flexdesk 0.17.2 → 0.17.4

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 (49) hide show
  1. package/CHANGELOG.md +100 -63
  2. package/README.md +27 -4517
  3. package/css/base.css +18 -1
  4. package/css/flexdesk.css +18 -1
  5. package/dist/{chunk-4A7SJC3T.js → chunk-RKNFBX5K.js} +15 -4
  6. package/dist/{chunk-4A7SJC3T.js.map → chunk-RKNFBX5K.js.map} +2 -2
  7. package/dist/flexdesk.css +18 -1
  8. package/dist/tiles.js +1 -1
  9. package/dist/widgets.js +59 -26
  10. package/dist/widgets.js.map +2 -2
  11. package/docs/README.md +97 -0
  12. package/docs/best-practices.md +45 -0
  13. package/docs/components/charts.md +211 -0
  14. package/docs/components/command-palette.md +102 -0
  15. package/docs/components/conversation.md +72 -0
  16. package/docs/components/data-table-grid.md +328 -0
  17. package/docs/components/data-table.md +596 -0
  18. package/docs/components/editor.md +22 -0
  19. package/docs/components/flow-canvas-editor.md +482 -0
  20. package/docs/components/flow-editors.md +176 -0
  21. package/docs/components/flow-lane-editor.md +165 -0
  22. package/docs/components/flow-outline-editor.md +176 -0
  23. package/docs/components/forms-and-dialogs.md +294 -0
  24. package/docs/components/input-fields.md +72 -0
  25. package/docs/components/keymap.md +143 -0
  26. package/docs/components/layout-widgets.md +163 -0
  27. package/docs/components/markdown-and-outline.md +106 -0
  28. package/docs/components/menus.md +86 -0
  29. package/docs/components/notifications.md +194 -0
  30. package/docs/components/panels-and-desktops.md +127 -0
  31. package/docs/components/record-list-and-fact-table.md +128 -0
  32. package/docs/components/settings-view.md +112 -0
  33. package/docs/components/shell.md +189 -0
  34. package/docs/components/slide-out-panel.md +68 -0
  35. package/docs/components/tiles.md +210 -0
  36. package/docs/components/wizard.md +54 -0
  37. package/docs/concepts/building-and-packaging.md +33 -0
  38. package/docs/concepts/domain-neutrality.md +110 -0
  39. package/docs/concepts/host-port.md +137 -0
  40. package/docs/concepts/packages-and-entry-points.md +32 -0
  41. package/docs/concepts/peer-dependencies.md +42 -0
  42. package/docs/concepts/state-guard.md +58 -0
  43. package/docs/concepts/styling.md +47 -0
  44. package/docs/quickstart.md +179 -0
  45. package/package.json +2 -1
  46. package/src/ui/components/notification_history.js +17 -24
  47. package/src/ui/components/slide_out_panel.js +14 -3
  48. package/src/ui/notification_center.js +41 -3
  49. package/src/ui/utils/auto_scrollbars.js +16 -2
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/ui/base/controller_base.js", "../src/ui/base/page_base.js", "../src/ui/components/about_dialog.js", "../src/ui/components/alert_log.js", "../src/ui/components/alerts_pane.js", "../src/ui/components/attribute_list_editor.js", "../src/ui/components/column_fit.js", "../src/ui/components/progress.js", "../src/ui/components/job_progress.js", "../src/ui/components/computing_status_window.js", "../src/ui/components/confirm_dialog.js", "../src/ui/components/conversation_view.js", "../src/ui/components/detail_header.js", "../src/ui/components/fact_table.js", "../src/ui/components/gallery_picker.js", "../src/ui/components/notification_history.js", "../src/ui/components/record_list.js", "../src/ui/components/section_stack.js", "../src/ui/components/settings_view.js", "../src/ui/components/slider_field.js", "../src/ui/components/table_state_store.js", "../src/ui/components/tag_input.js", "../src/ui/components/toast.js", "../src/ui/components/tree_view.js", "../src/ui/components/window_taskbar.js", "../src/ui/components/wizard.js", "../src/ui/controllers/window_chrome_controller.js", "../src/ui/notification_center.js", "../src/ui/utils/auto_scrollbars.js", "../src/ui/utils/native_context_menu.js", "../src/ui/utils/overlay_scrollbar.js", "../src/ui/utils/scroll_lock.js", "../src/ui/utils/tooltip_service.js"],
4
- "sourcesContent": ["/**\r\n * ControllerBase (js_new)\r\n *\r\n * Shared superclass for UI controllers (tab, panel, layout, etc.). Provides\r\n * deterministic teardown, scoped event subscriptions, and dependency injection.\r\n */\r\nexport class ControllerBase {\r\n constructor({ eventBus, dataManager, logger } = {}) {\r\n if (new.target === ControllerBase) {\r\n throw new Error('ControllerBase is abstract \u2013 extend it instead');\r\n }\r\n\r\n this.eventBus = eventBus;\r\n this.dataManager = dataManager;\r\n this.logger = logger;\r\n this._disposers = new Set();\r\n }\r\n\r\n /**\r\n * Register a disposer callback to guarantee teardown.\r\n */\r\n trackDisposer(disposer) {\r\n if (typeof disposer === 'function') {\r\n this._disposers.add(disposer);\r\n }\r\n }\r\n\r\n /**\r\n * Attach controller-specific DOM/event wiring. Subclasses implement this.\r\n */\r\n initialize(/* options */) {\r\n throw new Error('ControllerBase.initialize must be implemented by subclasses');\r\n }\r\n\r\n /**\r\n * Dispose all tracked resources.\r\n */\r\n dispose() {\r\n for (const disposer of this._disposers) {\r\n try {\r\n disposer();\r\n } catch (err) {\r\n this.logger?.error?.('ui', 'Controller disposer failed', err);\r\n }\r\n }\r\n this._disposers.clear();\r\n }\r\n}\r\n", "/**\r\n * PageBase (js_new)\r\n *\r\n * Abstract shell for every top-level UI page (node workspace, simulation, data).\r\n * Handles dependency injection + shared lifecycle hooks so individual pages only\r\n * focus on domain logic.\r\n *\r\n * ## Async Initialization Pattern\r\n * Pages with async initialization should:\r\n * 1. Store the init promise: `this._initPromise = this.init();` in mount()\r\n * 2. Use `await this.waitForReady()` in show()/hydrate() to wait for init\r\n * 3. Mark completion by resolving the promise (init() returns)\r\n *\r\n * Example:\r\n * ```javascript\r\n * mount(container) {\r\n * this.container = container;\r\n * this._initPromise = this.init(); // Store promise\r\n * this._mounted = true;\r\n * }\r\n *\r\n * async show() {\r\n * await this.waitForReady(); // Wait for init if still running\r\n * this.refresh();\r\n * }\r\n * ```\r\n */\r\nexport class PageBase {\r\n constructor({ eventBus, dataManager, notificationCenter, logger } = {}) {\r\n if (new.target === PageBase) {\r\n throw new Error('PageBase is abstract \u2013 extend it instead');\r\n }\r\n\r\n this.eventBus = eventBus;\r\n this.dataManager = dataManager;\r\n this.notificationCenter = notificationCenter;\r\n this.logger = logger;\r\n this._mounted = false;\r\n\r\n /**\r\n * Promise that resolves when async initialization completes.\r\n * Pages with async init should set this in mount().\r\n * @type {Promise<void>|null}\r\n */\r\n this._initPromise = null;\r\n }\r\n\r\n /**\r\n * Mount the page into a DOM container. Concrete pages must override this.\r\n * For pages with async initialization, store the init promise:\r\n * `this._initPromise = this.init();`\r\n */\r\n mount(/* container */) {\r\n throw new Error('PageBase.mount must be implemented by subclasses');\r\n }\r\n\r\n /**\r\n * Wait for the page to complete initialization.\r\n * Returns immediately if no async init or if already complete.\r\n * @returns {Promise<void>}\r\n */\r\n async waitForReady() {\r\n if (this._initPromise) {\r\n try {\r\n await this._initPromise;\r\n } catch (err) {\r\n this.logger?.warn?.('page', 'Init promise rejected', err);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Optional hook invoked after the initial mount to hydrate data/state.\r\n * For pages with async init, this should await waitForReady().\r\n */\r\n async hydrate(/* options */) {\r\n // default: wait for init to complete\r\n await this.waitForReady();\r\n }\r\n\r\n /**\r\n * Optional hook for when the page becomes active (tab switched, etc.).\r\n */\r\n onActivated(/* context */) {\r\n // default no-op\r\n }\r\n\r\n /**\r\n * Optional hook for when the page is hidden/unmounted but not disposed.\r\n */\r\n onDeactivated(/* context */) {\r\n // default no-op\r\n }\r\n\r\n /**\r\n * Dispose resources/event subscriptions.\r\n */\r\n dispose() {\r\n this._mounted = false;\r\n this._initPromise = null;\r\n }\r\n}\r\n", "/**\n * About Dialog Component\n *\n * A modal that shows a product's name, version, license, homepage and\n * third-party credits. It knows NOTHING about which product \u2014 the caller\n * supplies all of it.\n *\n * It used to hardcode EcoAgent's: PRODUCT_NAME, the GitHub URL, the tagline\n * (\"Heterogeneous-agent, stock-flow-consistent macroeconomic simulation\") and\n * two dependency lists. A library that ships an About box for somebody else's\n * application is not a library.\n *\n * EcoAgent's values now live in ui/js/ecoagent/about.js and are pushed in.\n *\n * @typedef {{name: string, license: string, url: string}} Dep\n * @typedef {{title: string, deps: Dep[]}} DepSection\n */\n\nimport { ManagedWindow } from './managed_window.js';\n\nfunction createExternalLink(text, url, className) {\n const a = document.createElement('a');\n a.className = className;\n a.textContent = text;\n a.href = url;\n a.title = url;\n a.addEventListener('click', (e) => {\n e.preventDefault();\n window.open(url, '_blank');\n });\n return a;\n}\n\nfunction buildDepSection(title, deps) {\n const section = document.createElement('div');\n section.className = 'twm-about-dialog__section';\n\n const heading = document.createElement('div');\n heading.className = 'twm-about-dialog__section-title';\n heading.textContent = title;\n section.appendChild(heading);\n\n const list = document.createElement('div');\n list.className = 'twm-about-dialog__dep-list';\n\n for (const dep of deps) {\n const row = document.createElement('div');\n row.className = 'twm-about-dialog__dep';\n\n const link = createExternalLink(dep.name, dep.url, 'twm-about-dialog__dep-name');\n row.appendChild(link);\n\n const lic = document.createElement('span');\n lic.className = 'twm-about-dialog__dep-license';\n lic.textContent = dep.license;\n row.appendChild(lic);\n\n list.appendChild(row);\n }\n\n section.appendChild(list);\n return section;\n}\n\n/**\n * Show the About dialog for whatever product the caller names.\n *\n * @param {Object} product\n * @param {string} product.name Product name \u2014 the title and the heading.\n * @param {string} [product.version]\n * @param {string} [product.tagline]\n * @param {string} [product.license] Shown as \"License: <x>\"; omitted if absent.\n * @param {string} [product.url] Homepage; omitted if absent.\n * @param {string} [product.urlLabel='Homepage']\n * @param {string} [product.logo='info'] Material symbol shown beside the title.\n * @param {DepSection[]} [product.credits=[]] Third-party credit sections.\n * @returns {Promise<void>} Resolves when the dialog is closed.\n */\nexport function showAboutDialog(product = {}) {\n const {\n name = 'Application',\n version = '',\n tagline = '',\n license = '',\n url = '',\n urlLabel = 'Homepage',\n logo = 'info',\n credits = [],\n } = product;\n\n return new Promise((resolve) => {\n let resolved = false;\n\n const finish = () => {\n if (resolved) return;\n resolved = true;\n dialogWindow.close();\n resolve();\n };\n\n // --- Content ---\n const contentEl = document.createElement('div');\n contentEl.className = 'twm-about-dialog__content';\n\n // Header\n const header = document.createElement('div');\n header.className = 'twm-about-dialog__header';\n\n const logoEl = document.createElement('span');\n logoEl.className = 'twm-about-dialog__logo material-symbols-outlined';\n logoEl.textContent = logo;\n header.appendChild(logoEl);\n\n const title = document.createElement('h2');\n title.className = 'twm-about-dialog__title';\n title.textContent = name;\n header.appendChild(title);\n\n if (version) {\n const versionEl = document.createElement('div');\n versionEl.className = 'twm-about-dialog__version';\n versionEl.textContent = `Version ${version}`;\n header.appendChild(versionEl);\n }\n\n if (tagline) {\n const taglineEl = document.createElement('div');\n taglineEl.className = 'twm-about-dialog__tagline';\n taglineEl.textContent = tagline;\n header.appendChild(taglineEl);\n }\n\n contentEl.appendChild(header);\n\n // Body (scrollable)\n const body = document.createElement('div');\n body.className = 'twm-about-dialog__body';\n\n // Project section \u2014 only if there is something to put in it.\n if (url || license) {\n const projectSection = document.createElement('div');\n projectSection.className = 'twm-about-dialog__section';\n\n const projectTitle = document.createElement('div');\n projectTitle.className = 'twm-about-dialog__section-title';\n projectTitle.textContent = 'Project';\n projectSection.appendChild(projectTitle);\n\n const links = document.createElement('div');\n links.className = 'twm-about-dialog__links';\n\n if (url) {\n const link = createExternalLink(urlLabel, url, 'twm-about-dialog__link');\n const icon = document.createElement('span');\n icon.className = 'material-symbols-outlined';\n icon.textContent = 'open_in_new';\n link.prepend(icon);\n links.appendChild(link);\n }\n\n if (license) {\n const licenseSpan = document.createElement('span');\n licenseSpan.className = 'twm-about-dialog__license-text';\n const licIcon = document.createElement('span');\n licIcon.className = 'material-symbols-outlined';\n licIcon.textContent = 'license';\n licenseSpan.appendChild(licIcon);\n licenseSpan.appendChild(document.createTextNode(`License: ${license}`));\n links.appendChild(licenseSpan);\n }\n\n projectSection.appendChild(links);\n body.appendChild(projectSection);\n }\n\n for (const section of credits) {\n body.appendChild(buildDepSection(section.title, section.deps ?? []));\n }\n\n contentEl.appendChild(body);\n\n // Footer\n const footer = document.createElement('div');\n footer.className = 'twm-about-dialog__footer';\n\n const closeBtn = document.createElement('button');\n closeBtn.type = 'button';\n closeBtn.className = 'twm-about-dialog__btn twm-about-dialog__btn--close';\n closeBtn.textContent = 'Close';\n closeBtn.addEventListener('click', finish);\n footer.appendChild(closeBtn);\n\n contentEl.appendChild(footer);\n\n // --- Window ---\n const dialogWindow = new ManagedWindow({\n id: 'about-dialog',\n title: `About ${name}`,\n icon: 'info',\n content: contentEl,\n minWidth: 420,\n minHeight: 400,\n defaultWidth: 460,\n defaultHeight: 540,\n canMinimize: false,\n canMaximize: false,\n canResize: false,\n canDrag: false,\n modal: true,\n onClose: () => {\n if (!resolved) {\n resolved = true;\n resolve();\n }\n },\n });\n\n dialogWindow.show();\n\n requestAnimationFrame(() => {\n closeBtn.focus();\n });\n });\n}\n", "/**\n * \u2550\u2550 THE ALERT LOG \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\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 * What an application told its user, kept: every entry, newest first, read or\n * not, until it is dismissed or falls off the end (FlexDesk STORY-0019, from\n * bugdesk's `alerts.js`). NotificationCenter's toasts are the moment; this is\n * the history the Alerts pane (`alerts_pane.js`) and the bell\n * (NotificationHistory's `alertLog` option) read.\n *\n * An ENTRY is `{ id, at, level, title, body?, ref?, read, ruleId?, rule? }`.\n * `at` is a Date; `level` is one of `info`, `warning`, `alert` (`normalizeLevel`\n * maps the toast's `warn`/`error` and the server's `danger` onto them).\n *\n * WHERE ENTRIES LIVE IS THE EMBEDDER'S \u2014 a pluggable SOURCE:\n *\n * load({ offset, limit }) \u2192 { entries, more?, unread? } a page, newest first\n * markRead(ids | null) \u2192 null is \"all\"\n * dismiss(ids | null) \u2192 optional; without it nothing can be dismissed\n *\n * bugdesk keeps the whole log in its workspace state (`localSource`: one\n * blob, read once, written on every change); Tables pages its server's\n * notifications and has no dismiss. A source's `unread` is the count beyond\n * the loaded page \u2014 the server knows it, the page does not.\n *\n * CHANGES ARE APPLIED HERE FIRST and the source told after, so a click marks\n * read at once; a source that refuses is logged and the log re-read, rather\n * than the click being made to wait on a round trip.\n */\n\n/** The three levels, worst last; `icon` is a Material Symbols name. */\nexport const ALERT_LEVELS = Object.freeze({\n info: Object.freeze({ label: 'Info', icon: 'info' }),\n warning: Object.freeze({ label: 'Warning', icon: 'warning' }),\n alert: Object.freeze({ label: 'Alert', icon: 'notifications_active' }),\n});\n\nconst LEVEL_ALIASES = { warn: 'warning', error: 'alert', danger: 'alert', critical: 'alert', success: 'info' };\n\n/** One of `info`, `warning`, `alert`, whatever the caller spelt. */\nexport function normalizeLevel(level) {\n const l = String(level ?? '').toLowerCase();\n if (ALERT_LEVELS[l]) return l;\n return LEVEL_ALIASES[l] ?? 'info';\n}\n\n/** The worst level among these entries \u2014 a badge's colour \u2014 or null for none. */\nexport function worstLevel(entries) {\n let worst = null;\n for (const e of entries || []) {\n const l = normalizeLevel(e?.level);\n if (l === 'alert') return 'alert';\n if (l === 'warning') worst = 'warning';\n else if (!worst) worst = 'info';\n }\n return worst;\n}\n\n/** \"just now\", \"5 min ago\", \"3 h ago\"; older than a day, the clock time (the day header has the date). */\nexport function ago(at, now = new Date()) {\n const s = Math.max(0, (now - at) / 1000);\n if (s < 60) return 'just now';\n if (s < 3600) return `${Math.floor(s / 60)} min ago`;\n if (s < 86400) return `${Math.floor(s / 3600)} h ago`;\n return at.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });\n}\n\n/** TODAY, YESTERDAY, or the date \u2014 the Alerts pane's day header. */\nexport function dayLabel(at, now = new Date()) {\n const d = new Date(at.getFullYear(), at.getMonth(), at.getDate());\n const t = new Date(now.getFullYear(), now.getMonth(), now.getDate());\n const days = Math.round((t - d) / 86400000);\n if (days === 0) return 'TODAY';\n if (days === 1) return 'YESTERDAY';\n return at.toLocaleDateString([], { weekday: 'short', day: 'numeric', month: 'short', year: 'numeric' })\n .toUpperCase();\n}\n\nlet _seq = 0;\n\n/** An entry in the shape the log keeps, from whatever a source or a caller handed in. */\nfunction normalizeEntry(raw) {\n const at = raw.at instanceof Date ? raw.at : new Date(raw.at ?? Date.now());\n return {\n ...raw,\n id: String(raw.id ?? `${Date.now().toString(36)}-${(_seq++).toString(36)}`),\n at: Number.isNaN(at.getTime()) ? new Date() : at,\n level: normalizeLevel(raw.level),\n title: String(raw.title ?? ''),\n read: !!raw.read,\n };\n}\n\n/**\n * A source that keeps the whole log in one stored value \u2014 bugdesk's workspace\n * state, or localStorage. `read()` answers the saved array (or a promise of\n * it); `write(array)` stores one. Dates are written as ISO strings.\n */\nexport function localSource({ read, write, limit = 300 } = {}) {\n let all = null;\n const save = () => {\n try {\n write?.(all.map((e) => ({ ...e, at: e.at.toISOString() })));\n } catch (err) { console.warn('[alert-log] the log could not be saved', err); }\n };\n const ensure = async () => {\n if (all) return all;\n let saved = [];\n try { saved = (await read?.()) ?? []; } catch (err) {\n console.warn('[alert-log] the log could not be read', err);\n }\n all = (Array.isArray(saved) ? saved : []).filter((e) => e && typeof e === 'object')\n .map(normalizeEntry).sort((a, b) => b.at - a.at).slice(0, limit);\n return all;\n };\n return {\n local: true,\n async load({ offset = 0, limit: n = limit } = {}) {\n const list = await ensure();\n return { entries: list.slice(offset, offset + n), more: offset + n < list.length };\n },\n async add(entry) {\n const list = await ensure();\n list.unshift(entry);\n if (list.length > limit) list.length = limit;\n save();\n },\n async markRead(ids) {\n const want = ids ? new Set(ids) : null;\n for (const e of await ensure()) if (!want || want.has(e.id)) e.read = true;\n save();\n },\n async dismiss(ids) {\n const want = ids ? new Set(ids) : null;\n all = (await ensure()).filter((e) => want && !want.has(e.id));\n save();\n },\n };\n}\n\n/**\n * @param {object} [opts]\n * @param {object} [opts.source] where entries live; none keeps them in memory only\n * @param {number} [opts.limit] most entries held, and a page's size\n * @returns the log\n */\nexport function createAlertLog({ source = null, limit = 300 } = {}) {\n let entries = [];\n let more = false;\n let remoteUnread = null;\n let loaded = false;\n let loading = null;\n const listeners = new Set();\n\n const changed = () => {\n for (const fn of [...listeners]) {\n try { fn(log); } catch (err) { console.warn('[alert-log] listener failed', err); }\n }\n };\n const tell = (verb, ...args) => {\n const fn = source?.[verb];\n if (typeof fn !== 'function') return;\n Promise.resolve().then(() => fn.apply(source, args)).catch((err) => {\n console.warn(`[alert-log] the source refused ${verb}`, err);\n log.refresh();\n });\n };\n const page = async (offset) => {\n const res = (await source?.load?.({ offset, limit })) ?? {};\n const got = (res.entries ?? []).map(normalizeEntry);\n return { got, more: !!res.more, unread: Number.isFinite(res.unread) ? res.unread : null };\n };\n\n const log = {\n /** Loaded entries, newest first. */\n entries: () => entries,\n loaded: () => loaded,\n /** Whether the source has older entries than those loaded. */\n hasMore: () => more,\n /** Whether entries can be dismissed: a log with no source, or a source that can. */\n canDismiss: () => !source || typeof source.dismiss === 'function',\n /** Unread entries: the source's count when it knows one, else the loaded ones. */\n unreadCount() {\n const here = entries.filter((e) => !e.read).length;\n return remoteUnread === null ? here : Math.max(remoteUnread, here);\n },\n /** The worst level among unread entries, or null. */\n worstUnread: () => worstLevel(entries.filter((e) => !e.read)),\n get: (id) => entries.find((e) => e.id === String(id)) ?? null,\n\n /** `fn(log)` after every change; answers the unsubscribe. */\n subscribe(fn) {\n listeners.add(fn);\n return () => listeners.delete(fn);\n },\n\n /** The first page, again. */\n refresh() {\n if (!source?.load) { loaded = true; changed(); return Promise.resolve(log); }\n loading = page(0).then(({ got, more: m, unread }) => {\n entries = got;\n more = m;\n remoteUnread = unread;\n loaded = true;\n changed();\n return log;\n }).catch((err) => {\n console.warn('[alert-log] the log could not be loaded', err);\n loaded = true;\n changed();\n return log;\n }).finally(() => { loading = null; });\n return loading;\n },\n /** Load once; later calls answer the same promise or nothing. */\n load() { return loading ?? (loaded ? Promise.resolve(log) : log.refresh()); },\n /** The next page, after the loaded ones. */\n async loadMore() {\n if (!more || !source?.load) return log;\n const { got, more: m, unread } = await page(entries.length);\n const seen = new Set(entries.map((e) => e.id));\n entries = [...entries, ...got.filter((e) => !seen.has(e.id))];\n more = m;\n if (unread !== null) remoteUnread = unread;\n changed();\n return log;\n },\n\n /** A new entry raised HERE (bugdesk's rules): kept, and handed to the source to save. */\n add(raw) {\n const entry = normalizeEntry(raw);\n entries = [entry, ...entries.filter((e) => e.id !== entry.id)];\n if (entries.length > limit) entries.length = limit;\n if (remoteUnread !== null && !entry.read) remoteUnread += 1;\n tell('add', entry);\n changed();\n return entry;\n },\n /** Entries that arrived from the source's side (a push): shown, not saved back. */\n receive(raws) {\n const got = (Array.isArray(raws) ? raws : [raws]).map(normalizeEntry);\n const ids = new Set(got.map((e) => e.id));\n const fresh = got.filter((e) => !entries.some((x) => x.id === e.id));\n entries = [...got, ...entries.filter((e) => !ids.has(e.id))]\n .sort((a, b) => b.at - a.at).slice(0, limit);\n if (remoteUnread !== null) remoteUnread += fresh.filter((e) => !e.read).length;\n changed();\n },\n /** Mark these read \u2014 all of them when `ids` is omitted. */\n markRead(ids = null) {\n const want = ids ? new Set(ids.map(String)) : null;\n let n = 0;\n for (const e of entries) if (!e.read && (!want || want.has(e.id))) { e.read = true; n++; }\n if (remoteUnread !== null) remoteUnread = want ? Math.max(0, remoteUnread - n) : 0;\n if (!n && want) return;\n tell('markRead', want ? [...want] : null);\n changed();\n },\n /** Remove these \u2014 all of them when `ids` is omitted. Nothing, when the source cannot. */\n dismiss(ids = null) {\n if (!log.canDismiss()) return;\n const want = ids ? new Set(ids.map(String)) : null;\n const gone = entries.filter((e) => !want || want.has(e.id));\n if (!gone.length) return;\n entries = want ? entries.filter((e) => !want.has(e.id)) : [];\n if (remoteUnread !== null) {\n remoteUnread = want ? Math.max(0, remoteUnread - gone.filter((e) => !e.read).length) : 0;\n }\n tell('dismiss', want ? [...want] : null);\n changed();\n },\n };\n if (!source?.load) loaded = true;\n return log;\n}\n", "/**\n * \u2550\u2550 THE ALERTS PANE \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\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 * An alert log (`alert_log.js`) drawn as the bottom panel's Alerts tab: level\n * chips with counts, a text filter, entries grouped by day with relative\n * times, an unread mark, Open and Dismiss on each row, Mark all read and Clear\n * for the lot (FlexDesk STORY-0019, from bugdesk's `alerts.js`). The same\n * layout whether the log is local or pages a server: *Load older* appears\n * when the source has more.\n *\n * mountAlertsPane(el, { log, onOpen: (entry) => \u2026, onBadge: ({ unread, level }) => \u2026 })\n *\n * OPTIONAL, for an embedder with rules of its own (bugdesk): `rules` is\n * `{ list() \u2192 [{ id, name, level, meta?, off? }], onEdit?, foot? }` \u2014 a column\n * of them on the left that narrows the log to one rule (entries carry\n * `ruleId`) \u2014 and `stillMatches(entry)` \u2192 true / false / null, drawn as \"still\n * matches\" or \"no longer matches\" on each row.\n *\n * NEVER REBUILT UNDER THE POINTER. A log changes on its own \u2014 a push from the\n * server, a rule firing, the minute tick \u2014 and a row repainted between a\n * mousedown and its click loses the click (Tables' recorded trap). While a\n * button is down inside the pane a repaint waits, and runs once it is up.\n * The bar (chips, the filter, the buttons) is built once and updated in\n * place, so typing in the filter never loses the caret either.\n *\n * OLDER ENTRIES LOAD AS YOU SCROLL (Tables STORY-0293): when the list is\n * scrolled to within :data:`MORE_WITHIN_PX` of its end and the source has\n * more, the next page is asked for \u2014 once at a time. *Load older* stays at the\n * end, for a list too short to scroll and for the keyboard.\n */\n\nimport { ALERT_LEVELS, ago, dayLabel, normalizeLevel } from './alert_log.js';\n\nconst CHIPS = [['all', 'All'], ['alert', 'Alert'], ['warning', 'Warning'], ['info', 'Info']];\n\n/** How near the end of the list a scroll asks for the next page. */\nexport const MORE_WITHIN_PX = 48;\n\n/**\n * @param {HTMLElement} host\n * @param {object} opts\n * @param {object} opts.log `createAlertLog(\u2026)`\n * @param {Function}[opts.onOpen] `(entry)` \u2014 Open; the entry is marked read first\n * @param {Function}[opts.onBadge] `({ unread, level })` after every change \u2014 a tab's badge\n * @param {object} [opts.rules] `{ list, onEdit?, foot? }`\n * @param {Function}[opts.stillMatches] `(entry) \u2192 boolean | null`\n * @param {Function}[opts.describe] `(entry) \u2192 string` \u2014 a small chip on the row (bugdesk: the store)\n * @param {string} [opts.status] the footer line\n * @param {object} [opts.empty] `{ none, filtered }` \u2014 the two empty texts\n * @returns {{ refresh, destroy, root }}\n */\nexport function mountAlertsPane(host, {\n log, onOpen = null, onBadge = null, rules = null, stillMatches = null, describe = null,\n status = '', empty = {},\n} = {}) {\n const doc = host.ownerDocument;\n const el = (tag, cls, text) => {\n const n = doc.createElement(tag);\n if (cls) n.className = cls;\n if (text !== undefined) n.textContent = text;\n return n;\n };\n const icon = (name) => el('span', 'material-symbols-outlined', name);\n\n let level = 'all';\n let rule = null;\n let q = '';\n let pointerDown = false;\n let pending = false;\n let destroyed = false;\n\n // \u2500\u2500 the frame, built once \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 const root = el('div', 'twm-alerts');\n let ruleList = null;\n if (rules) {\n const side = el('div', 'twm-alerts__rules');\n const head = el('div', 'twm-alerts__head');\n head.append(el('span', 'twm-alerts__caps', 'RULES'), el('span', 'twm-alerts__spacer'));\n if (rules.onEdit) {\n const edit = el('button', 'twm-alerts__link', 'Edit rules');\n edit.type = 'button';\n edit.dataset.act = 'edit-rules';\n head.append(edit);\n }\n ruleList = el('div', 'twm-alerts__rulelist');\n side.append(head, ruleList);\n if (rules.foot) side.append(el('div', 'twm-alerts__foot', rules.foot));\n root.append(side);\n }\n const main = el('div', 'twm-alerts__main');\n const bar = el('div', 'twm-alerts__bar');\n const chips = el('div', 'twm-alerts__chips');\n chips.setAttribute('role', 'group');\n chips.setAttribute('aria-label', 'Level');\n const chipEls = new Map();\n for (const [key, label] of CHIPS) {\n const chip = el('button', 'twm-alerts__chip');\n chip.type = 'button';\n chip.dataset.level = key;\n chip.append(doc.createTextNode(`${label} `), el('span', 'twm-alerts__count', '0'));\n chips.append(chip);\n chipEls.set(key, chip);\n }\n const input = el('input', 'twm-alerts__q');\n input.type = 'text';\n input.autocomplete = 'off';\n input.spellcheck = false;\n input.placeholder = 'Filter';\n input.setAttribute('aria-label', 'Filter alerts');\n const readAll = el('button', 'twm-btn twm-alerts__btn', 'Mark all read');\n readAll.type = 'button';\n readAll.dataset.act = 'read-all';\n const clear = el('button', 'twm-btn twm-alerts__btn', 'Clear');\n clear.type = 'button';\n clear.dataset.act = 'clear';\n bar.append(chips, input, el('span', 'twm-alerts__spacer'), readAll, clear);\n const list = el('div', 'twm-alerts__log');\n const foot = el('div', 'twm-alerts__status', status);\n foot.hidden = !status;\n main.append(bar, list, foot);\n root.append(main);\n host.append(root);\n\n // \u2500\u2500 what is shown \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 const byRule = () => (rule ? log.entries().filter((e) => String(e.ruleId) === rule) : log.entries());\n const shown = () => {\n const needle = q.trim().toLowerCase();\n return byRule()\n .filter((e) => level === 'all' || e.level === level)\n .filter((e) => !needle || `${e.ref ?? ''} ${e.title} ${e.body ?? ''} ${e.rule ?? ''}`\n .toLowerCase().includes(needle));\n };\n\n function row(entry, now) {\n const lv = ALERT_LEVELS[normalizeLevel(entry.level)];\n const r = el('div', `twm-alerts__row twm-alerts__row--${entry.level}${entry.read ? '' : ' twm-alerts__row--unread'}`);\n r.dataset.id = entry.id;\n const mark = el('span', 'twm-alerts__unread');\n mark.setAttribute('aria-label', entry.read ? 'Read' : 'Unread');\n const ic = icon(lv.icon);\n ic.classList.add('twm-alerts__icon');\n ic.title = lv.label;\n const time = el('span', 'twm-alerts__time', ago(entry.at, now));\n time.title = entry.at.toLocaleString();\n const text = el('span', 'twm-alerts__text');\n text.append(el('span', 'twm-alerts__title', entry.title));\n if (entry.body) text.append(el('span', 'twm-alerts__body', entry.body));\n const cells = [mark, ic, time];\n if (rules) cells.push(el('span', 'twm-alerts__rule', entry.rule ?? ''));\n const tag = describe?.(entry);\n cells.push(el('span', tag ? 'twm-alerts__tag' : 'twm-alerts__tag twm-alerts__tag--none', tag ?? ''));\n const ref = el(entry.ref && onOpen ? 'button' : 'span', 'twm-alerts__ref', entry.ref ?? '');\n if (ref.tagName === 'BUTTON') { ref.type = 'button'; ref.dataset.open = entry.id; }\n cells.push(ref, text);\n if (stillMatches) {\n const still = stillMatches(entry);\n cells.push(el('span', `twm-alerts__state${still === false ? ' twm-alerts__state--gone' : ''}`,\n still === true ? 'still matches' : still === false ? 'no longer matches' : ''));\n }\n const acts = el('span', 'twm-alerts__acts');\n if (onOpen) {\n const open = el('button', 'twm-alerts__icon-btn');\n open.type = 'button';\n open.dataset.open = entry.id;\n open.title = 'Open';\n open.setAttribute('aria-label', 'Open');\n open.append(icon('open_in_new'));\n acts.append(open);\n }\n if (log.canDismiss()) {\n const dis = el('button', 'twm-alerts__icon-btn');\n dis.type = 'button';\n dis.dataset.dismiss = entry.id;\n dis.title = 'Dismiss';\n dis.setAttribute('aria-label', 'Dismiss');\n dis.append(icon('close'));\n acts.append(dis);\n }\n cells.push(acts);\n r.append(...cells);\n return r;\n }\n\n function paint() {\n if (destroyed) return;\n if (pointerDown) { pending = true; return; }\n pending = false;\n const now = new Date();\n const all = log.entries();\n const scoped = byRule();\n\n for (const [key, chip] of chipEls) {\n const on = level === key;\n chip.classList.toggle('twm-alerts__chip--on', on);\n chip.setAttribute('aria-pressed', String(on));\n chip.querySelector('.twm-alerts__count').textContent =\n String(scoped.filter((e) => key === 'all' || e.level === key).length);\n }\n readAll.disabled = !all.some((e) => !e.read) && log.unreadCount() === 0;\n clear.hidden = !log.canDismiss();\n clear.disabled = !all.length;\n\n if (ruleList) {\n const items = [{ id: null, name: 'All alerts', meta: String(all.length) }, ...(rules.list?.() ?? [])];\n ruleList.replaceChildren(...items.map((r) => {\n const key = r.id === null ? null : String(r.id);\n const b = el('button', `twm-alerts__rulebtn${rule === key ? ' twm-alerts__rulebtn--on' : ''}${r.off ? ' twm-alerts__rulebtn--off' : ''}`);\n b.type = 'button';\n b.dataset.rule = key ?? '';\n b.setAttribute('aria-pressed', String(rule === key));\n b.append(el('span', `twm-alerts__dot${r.level ? ` twm-alerts__dot--${normalizeLevel(r.level)}` : ''}`),\n el('span', 'twm-alerts__rulename', r.name || 'Unnamed rule'),\n el('span', 'twm-alerts__meta', r.meta ?? ''));\n return b;\n }));\n }\n\n const rows = [];\n let lastDay = '';\n for (const entry of shown()) {\n const day = dayLabel(entry.at, now);\n if (day !== lastDay) rows.push(el('div', 'twm-alerts__day', day));\n lastDay = day;\n rows.push(row(entry, now));\n }\n if (!rows.length) {\n rows.push(el('div', 'twm-alerts__none', !log.loaded() ? 'Loading\u2026'\n : all.length ? (empty.filtered ?? 'No alerts match.') : (empty.none ?? 'Nothing yet.')));\n }\n if (log.hasMore()) {\n const older = el('button', 'twm-btn twm-alerts__more', 'Load older');\n older.type = 'button';\n older.dataset.act = 'more';\n rows.push(older);\n }\n const scroll = list.scrollTop;\n list.replaceChildren(...rows);\n list.scrollTop = scroll;\n onBadge?.({ unread: log.unreadCount(), level: log.worstUnread() });\n }\n\n // \u2500\u2500 input \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 const onDown = () => { pointerDown = true; };\n const onUp = () => {\n if (!pointerDown) return;\n // After the click this mouseup belongs to has been dispatched.\n setTimeout(() => {\n pointerDown = false;\n if (pending) paint();\n }, 0);\n };\n root.addEventListener('mousedown', onDown, true);\n root.addEventListener('pointerdown', onDown, true);\n doc.addEventListener('mouseup', onUp, true);\n doc.addEventListener('pointerup', onUp, true);\n doc.addEventListener('pointercancel', onUp, true);\n\n root.addEventListener('click', (event) => {\n const t = event.target;\n const chip = t.closest('[data-level]');\n if (chip) { level = chip.dataset.level; paint(); return; }\n const r = t.closest('[data-rule]');\n if (r) { rule = r.dataset.rule || null; paint(); return; }\n const open = t.closest('[data-open]');\n if (open) {\n const entry = log.get(open.dataset.open);\n if (!entry) return;\n log.markRead([entry.id]);\n onOpen?.(entry);\n return;\n }\n const dis = t.closest('[data-dismiss]');\n if (dis) { log.dismiss([dis.dataset.dismiss]); return; }\n const act = t.closest('[data-act]')?.dataset.act;\n if (act === 'read-all') log.markRead();\n else if (act === 'clear') log.dismiss();\n else if (act === 'more') log.loadMore();\n else if (act === 'edit-rules') rules?.onEdit?.();\n });\n input.addEventListener('input', () => { q = input.value; paint(); });\n\n let loadingMore = false;\n list.addEventListener('scroll', () => {\n if (loadingMore || !log.hasMore()) return;\n if (list.scrollTop + list.clientHeight < list.scrollHeight - MORE_WITHIN_PX) return;\n loadingMore = true;\n Promise.resolve(log.loadMore()).catch(() => {}).finally(() => { loadingMore = false; });\n });\n\n const unsubscribe = log.subscribe(() => paint());\n // \"5 min ago\" moves on its own.\n const timer = setInterval(paint, 60000);\n paint();\n log.load?.();\n\n return {\n root,\n refresh: paint,\n destroy() {\n if (destroyed) return;\n destroyed = true;\n clearInterval(timer);\n unsubscribe();\n doc.removeEventListener('mouseup', onUp, true);\n doc.removeEventListener('pointerup', onUp, true);\n doc.removeEventListener('pointercancel', onUp, true);\n root.remove();\n },\n };\n}\n", "/**\n * attribute_list_editor.js \u2014 generic AttributeSpec list editor.\n *\n * One reusable component for every entity that declares a typed-slot\n * list: Asset.attributes, Archetype.attributes, SectorKind.requires,\n * MarketKind.requires, Flow.params, KPI.params. Mounts a SortableList\n * (drag-reorder + add + remove + empty-state) with typed cells:\n *\n * - scalar (number / integer / string / boolean): typed `<input>`\n * - expression: free-text input \u2014 engine evaluates each tick\n * - ref:<target>: typeahead-ish `<select>` populated by a caller-\n * supplied resolver returning {id, label} lists\n * - list[ref:<target>]: comma-separated input (UI primitive \u2014 chip\n * editor can land later without changing the data shape)\n * - select: dropdown of options (auto when `options[]` is set)\n *\n * Each row exposes the columns in `showColumns` (defaults to the full\n * set); callers narrow it (e.g. SectorKind.requires only needs name +\n * type + description, not default/value). Layout follows the column\n * spec \u2014 header strip aligned via CSS grid using --cols.\n *\n * Usage:\n *\n * import { mountAttributeListEditor } from\n * '../../ui/components/attribute_list_editor.js';\n *\n * const editor = mountAttributeListEditor(hostEl, {\n * items: kind.attributes,\n * showColumns: ['name', 'type', 'default', 'value', 'description'],\n * refResolvers: {\n * 'ref:asset': () => api.assets_list(),\n * },\n * onChange: (next) => { kind.attributes = next; save(); },\n * });\n * editor.refresh(); // call after `items` changes externally\n * editor.dispose(); // teardown\n */\n\nimport { SortableList } from './sortable_list.js';\n\n// The types a generic attribute editor knows about, with no application loaded.\n//\n// This used to also list nine EcoAgent entity kinds \u2014 asset_kind, market,\n// sub_sector, currency, sector, market_kind, asset_kind_template, archetype,\n// kpi \u2014 and derive `ref:<kind>` and `list[ref:<kind>]` from them. `types` was\n// ALREADY an injectable option; it simply had EcoAgent's ontology as its\n// default, which meant every consumer who didn't override it inherited a type\n// dropdown full of macroeconomics.\n//\n// Callers who want reference types build them with refTypesFor() and pass them\n// in, alongside the `refResolvers` that make them resolvable.\nconst SCALAR_TYPES = ['number', 'integer', 'string', 'boolean'];\n\nconst DEFAULT_TYPES = [...SCALAR_TYPES, 'expression'];\n\n/** `['agent']` -> `['ref:agent', 'list[ref:agent]']`. */\nexport function refTypesFor(kinds = []) {\n return [\n ...kinds.map((k) => `ref:${k}`),\n ...kinds.map((k) => `list[ref:${k}]`),\n ];\n}\n\nexport { SCALAR_TYPES, DEFAULT_TYPES };\n\nconst DEFAULT_COLUMNS = ['name', 'type', 'default', 'value', 'description'];\n\nconst COLUMN_TEMPLATES = {\n name: { label: 'name', width: 'minmax(140px, 1.2fr)' },\n type: { label: 'type', width: '140px' },\n default: { label: 'default', width: 'minmax(110px, 1fr)' },\n value: { label: 'value', width: 'minmax(110px, 1fr)' },\n description: { label: 'description', width: 'minmax(160px, 2fr)' },\n required: { label: 'req', width: '60px' },\n readonly: { label: 'r/o', width: '60px' },\n expression: { label: 'expression', width: 'minmax(160px, 2fr)' },\n // Layer N3 \u2014 extended AttributeSpec fields. Opt-in via showColumns\n // so existing single-table layouts (asset_kind editor) stay tight;\n // the agent params surface includes them.\n min: { label: 'min', width: '90px' },\n max: { label: 'max', width: '90px' },\n step: { label: 'step', width: '70px' },\n unit: { label: 'unit', width: '80px' },\n distribution: { label: 'dist', width: '110px' },\n // Distribution and \"selection set\" are two different concepts \u2014\n // numeric params sample from a continuous distribution (uniform /\n // normal / lognormal / \u2026), choice params pick from a discrete\n // option set. Keep them in separate columns so the user can tell\n // which is which at a glance.\n choices: { label: 'choices', width: '130px' },\n // Variation-override flags \u2014 R7 in\n // docs/ARCHETYPE_RETHINK_REQUIREMENTS.md. Tight columns so they\n // stay readable next to the scalar fields.\n enabled: { label: 'on', width: '50px' },\n force: { label: 'lock', width: '50px' },\n optional: { label: 'opt', width: '50px' },\n};\n\nconst DISTRIBUTION_OPTIONS = [\n '', 'constant', 'uniform', 'normal', 'lognormal', 'choice',\n];\n\n\n/** Classify one attribute against its parent-archetype counterpart.\n * Layer 8.J1 inheritance display:\n *\n * - 'inherited' \u2014 entity's effective value matches the archetype's\n * default for the same attribute name. UI paints the row blue.\n * - 'overridden' \u2014 entity's value is set AND differs from the\n * archetype's default. UI paints the row solarized orange + shows\n * a revert button.\n * - 'neutral' \u2014 neither side declares a value (or there's no parent).\n * UI paints the row in default style.\n */\nfunction _classifyRow(row, parentByName) {\n if (!parentByName) return 'neutral';\n const p = parentByName.get(row.name);\n if (!p) return 'neutral';\n const ourValue = (row.value !== undefined && row.value !== null)\n ? row.value : row.default;\n const parentValue = (p.value !== undefined && p.value !== null)\n ? p.value : p.default;\n if (ourValue === undefined || ourValue === null) return 'neutral';\n if (parentValue === undefined || parentValue === null) return 'overridden';\n // Loose equality: handles number vs numeric-string from form inputs.\n if (String(ourValue) === String(parentValue)) return 'inherited';\n return 'overridden';\n}\n\n\nexport function mountAttributeListEditor(hostEl, options = {}) {\n const {\n items = [],\n types = DEFAULT_TYPES,\n showColumns = DEFAULT_COLUMNS,\n refResolvers = {},\n onChange = () => {},\n onFlush = () => {},\n addButtonText = '',\n emptyMessage = 'No entries yet.',\n containerId = `attrs-${Math.random().toString(36).slice(2, 8)}`,\n allowReorder = true,\n allowRemove = true,\n // Layer 8.J1: parent-archetype attributes (the inherited baseline).\n // The editor uses this to classify each row as inherited / overridden /\n // neutral and to provide a revert action. Pass [] when no archetype\n // applies; the editor degrades gracefully (all rows render neutral).\n parentAttributes = null,\n createItem = () => ({\n name: '', type: 'string', default: null,\n value: null, description: '',\n }),\n // Layer N3 \u2014 per-column renderer overrides. Callers can supply\n // `cellOverrides: {column_name: (item, callbacks, ctx) => HTMLElement | null}`\n // to swap in a custom cell. Returning `null` falls through to\n // the default renderer. The `ctx` object exposes:\n // refreshRow() \u2014 force a re-render (the wider list refreshes\n // when the row's items change, e.g. type swap).\n // Use cases: agent params' distribution-dict button cell;\n // structured-type modal openers on the default cell.\n cellOverrides = null,\n // R7 \u2014 when true, this editor is mounted as a *variation* of the\n // parent archetype (not on the archetype itself). Rows where\n // the parent has `force=true` lock their editable cells; the\n // `enabled/force/optional` flag columns themselves stay\n // read-only (variations don't author flags, only the\n // archetype does).\n variationMode = false,\n } = options;\n\n // Lookup map for inheritance classification.\n const parentByName = parentAttributes\n ? new Map(parentAttributes.map((p) => [p.name, p]))\n : null;\n\n if (!hostEl) {\n return { refresh() {}, addItem() {}, dispose() {} };\n }\n\n hostEl.classList.add('twm-attr-editor');\n hostEl.style.setProperty('--cols',\n showColumns.map((c) => COLUMN_TEMPLATES[c]?.width || '1fr').join(' '));\n\n const refsCache = new Map();\n const resolveRefOptions = async (target) => {\n if (refsCache.has(target)) return refsCache.get(target);\n const resolver = refResolvers[`ref:${target}`]\n || refResolvers[`list[ref:${target}]`];\n let list = [];\n if (typeof resolver === 'function') {\n try { list = await resolver() || []; }\n catch (e) { console.warn('ref resolver failed', target, e); }\n }\n const normalised = (list || []).map((o) => {\n if (typeof o === 'string') return { id: o, label: o };\n return { id: o.id ?? o.value ?? '', label: o.label ?? o.id ?? '' };\n }).filter((o) => o.id);\n refsCache.set(target, normalised);\n return normalised;\n };\n\n // Header strip \u2014 mimics the SortableList row layout exactly so\n // header cells align with body cells. Row shape is:\n // [drag-handle] [content-with-cols-grid] [remove-button]\n // The header reuses `.sortable-list__row` chrome with placeholder\n // spans for the handle / remove gutters, then the inner content\n // div carries the same `--cols` grid as each row's content div.\n const header = document.createElement('div');\n header.className = 'twm-sortable-list__row twm-attr-editor__header-row';\n if (allowReorder) {\n const handlePh = document.createElement('span');\n handlePh.className = 'twm-sortable-list__handle twm-attr-editor__header-placeholder';\n header.appendChild(handlePh);\n }\n const headerContent = document.createElement('div');\n headerContent.className = 'twm-sortable-list__content twm-attr-editor__headers';\n for (const col of showColumns) {\n const span = document.createElement('span');\n span.textContent = COLUMN_TEMPLATES[col]?.label ?? col;\n headerContent.appendChild(span);\n }\n header.appendChild(headerContent);\n if (allowRemove) {\n const removePh = document.createElement('span');\n removePh.className = 'twm-sortable-list__remove twm-attr-editor__header-placeholder';\n header.appendChild(removePh);\n }\n hostEl.appendChild(header);\n\n const listHost = document.createElement('div');\n listHost.className = 'ea-attr-editor__rows';\n hostEl.appendChild(listHost);\n\n let list = null;\n\n const renderRow = (contentEl, item, _idx, callbacks) => {\n contentEl.classList.add('twm-attr-editor__row');\n // Layer 8.J1 \u2014 paint inheritance state.\n const cls = _classifyRow(item, parentByName);\n contentEl.classList.remove(\n 'twm-attr-editor__row--inherited',\n 'twm-attr-editor__row--overridden',\n 'twm-attr-editor__row--neutral',\n );\n contentEl.classList.add(`twm-attr-editor__row--${cls}`);\n\n // R7 variation-override flags. `enabled` defaults true, so the\n // disabled treatment only applies when explicitly false.\n // `force` locks the row (variations can't override). `optional`\n // signals the value is a suggestion \u2014 green border, no fill.\n // The flag rules are applied additively so the inheritance\n // classification's background still shows where applicable.\n // In variation mode the relevant flags are the parent's; in\n // archetype mode they're the row's own. (A variation row only\n // has the flags it inherited; it doesn't author its own.)\n const parentRow = parentByName?.get(item.name);\n const flagSource = variationMode && parentRow ? parentRow : item;\n contentEl.classList.toggle(\n 'twm-attr-editor__row--disabled', flagSource.enabled === false);\n contentEl.classList.toggle(\n 'twm-attr-editor__row--forced', flagSource.force === true);\n contentEl.classList.toggle(\n 'twm-attr-editor__row--optional', flagSource.optional === true);\n\n // Attention indicator on overridden rows + revert button.\n if (cls === 'overridden') {\n const attention = document.createElement('span');\n attention.className = 'twm-attr-editor__attention material-symbols-outlined';\n attention.textContent = 'fiber_manual_record';\n attention.title = 'Value overrides the parent default';\n contentEl.appendChild(attention);\n }\n\n for (const col of showColumns) {\n const cell = renderCell(col, item, callbacks);\n contentEl.appendChild(cell);\n }\n // R7 \u2014 lock the row's editable inputs when the parent forced it.\n // The flag columns themselves stay enabled on the archetype\n // (where the author sets them); in variation mode they're\n // read-only because variations don't author flags.\n const FLAG_COLS = new Set(['enabled', 'force', 'optional']);\n if (variationMode && flagSource.force === true) {\n contentEl.querySelectorAll(\n 'input:not([type=\"checkbox\"]), select, textarea'\n ).forEach((el) => { el.disabled = true; });\n }\n if (variationMode) {\n contentEl.querySelectorAll(\n 'input[type=\"checkbox\"].ea-attr-editor__cell--flag'\n ).forEach((el) => { el.disabled = true; });\n }\n void FLAG_COLS; // referenced by future per-column handling\n\n // Revert button \u2014 only rendered for overridden rows. Resets\n // `value` back to the archetype's inherited default. The row\n // re-classifies as 'inherited' on the next render pass.\n if (cls === 'overridden' && parentByName) {\n const p = parentByName.get(item.name);\n const parentDefault = (p?.value !== undefined && p?.value !== null)\n ? p.value : p?.default;\n const revert = document.createElement('button');\n revert.type = 'button';\n revert.className = 'twm-attr-editor__revert material-symbols-outlined';\n revert.textContent = 'undo';\n revert.title =\n `Revert to inherited default (${parentDefault ?? '\u2014'})`;\n revert.addEventListener('click', (e) => {\n e.stopPropagation();\n callbacks.update({ value: parentDefault });\n onFlush();\n // Force a re-render so the row re-classifies.\n list?.setItems(currentItems());\n });\n contentEl.appendChild(revert);\n }\n };\n\n const renderCell = (col, item, callbacks) => {\n // Caller override wins \u2014 used by agent_tab to inject the\n // distribution-dict button + structured-type modal openers.\n if (cellOverrides && typeof cellOverrides[col] === 'function') {\n const ctx = { refreshRow: () => list?.setItems(currentItems()) };\n const custom = cellOverrides[col](item, callbacks, ctx);\n if (custom) return custom;\n }\n if (col === 'name') return renderTextCell(item, 'name', callbacks, 'attr_name');\n if (col === 'type') return renderTypeCell(item, callbacks);\n if (col === 'description') return renderTextCell(item, 'description', callbacks, 'optional');\n if (col === 'required') return renderBoolCell(item, 'required', callbacks);\n if (col === 'readonly') return renderBoolCell(item, 'readonly', callbacks);\n // R7 \u2014 three variation-override flags. `enabled` defaults true,\n // so the checkbox renders checked when the field is undefined;\n // the others default false.\n if (col === 'enabled') return renderFlagCell(item, 'enabled', callbacks, true);\n if (col === 'force') return renderFlagCell(item, 'force', callbacks, false);\n if (col === 'optional') return renderFlagCell(item, 'optional', callbacks, false);\n if (col === 'expression') return renderTextCell(item, 'expression', callbacks, 'expr');\n if (col === 'min') return renderNumericCell(item, 'min', callbacks);\n if (col === 'max') return renderNumericCell(item, 'max', callbacks);\n if (col === 'step') return renderTextCell(item, 'step', callbacks, 'any');\n if (col === 'unit') return renderTextCell(item, 'unit', callbacks, 'USD/%/\u2026');\n if (col === 'distribution') return renderDistributionCell(item, callbacks);\n if (col === 'default' || col === 'value') return renderTypedValueCell(col, item, callbacks);\n // Unknown column \u2014 render a stub.\n const stub = document.createElement('span');\n stub.textContent = '';\n return stub;\n };\n\n const renderNumericCell = (item, field, callbacks) => {\n const el = document.createElement('input');\n el.type = 'number';\n el.className = 'twm-sortable-list__input twm-attr-editor__cell';\n el.step = 'any';\n el.value = (item[field] === null || item[field] === undefined)\n ? '' : String(item[field]);\n el.placeholder = '\u2014';\n el.addEventListener('input', () => {\n const v = el.value === '' ? null : Number(el.value);\n callbacks.update({ [field]: v });\n });\n el.addEventListener('blur', () => onFlush());\n return el;\n };\n\n const renderDistributionCell = (item, callbacks) => {\n const el = document.createElement('select');\n el.className = 'twm-attr-editor__cell';\n for (const d of DISTRIBUTION_OPTIONS) {\n const o = document.createElement('option');\n o.value = d; o.textContent = d || '(none)';\n if ((item.distribution || '') === d) o.selected = true;\n el.appendChild(o);\n }\n el.addEventListener('change', () => {\n callbacks.update({ distribution: el.value || null });\n onFlush();\n });\n return el;\n };\n\n const renderTextCell = (item, field, callbacks, placeholder) => {\n const el = document.createElement('input');\n el.type = 'text';\n el.className = 'twm-sortable-list__input twm-attr-editor__cell';\n el.value = item[field] ?? '';\n el.placeholder = placeholder;\n el.addEventListener('input', () => {\n callbacks.update({ [field]: el.value });\n });\n el.addEventListener('blur', () => onFlush());\n return el;\n };\n\n const renderBoolCell = (item, field, callbacks) => {\n const el = document.createElement('input');\n el.type = 'checkbox';\n el.className = 'twm-attr-editor__cell';\n el.checked = !!item[field];\n el.addEventListener('change', () => {\n callbacks.update({ [field]: el.checked });\n onFlush();\n });\n return el;\n };\n\n /** Boolean cell for R7 flags. Same as renderBoolCell but treats an\n * undefined value as `defaultIfMissing`, so `enabled` (default\n * true) renders checked on legacy rows that predate the flag. */\n const renderFlagCell = (item, field, callbacks, defaultIfMissing) => {\n const el = document.createElement('input');\n el.type = 'checkbox';\n el.className = 'twm-attr-editor__cell ea-attr-editor__cell--flag';\n const cur = item[field];\n el.checked = (cur === undefined || cur === null)\n ? !!defaultIfMissing : !!cur;\n el.addEventListener('change', () => {\n callbacks.update({ [field]: el.checked });\n onFlush();\n });\n return el;\n };\n\n const renderTypeCell = (item, callbacks) => {\n const el = document.createElement('select');\n el.className = 'twm-attr-editor__cell';\n // Group scalar, expression, ref, list[ref] for readability.\n // Any type the caller hands us that doesn't fit one of those\n // buckets lands in `other` \u2014 that's how param-mode types\n // (float / int / str / bool / choice / map / schedule /\n // string_list) appear without breaking the dispatch.\n const seen = new Set();\n const addOpts = (label, optList) => {\n if (optList.length === 0) return;\n const grp = document.createElement('optgroup');\n grp.label = label;\n for (const t of optList) {\n const o = document.createElement('option');\n o.value = t; o.textContent = t;\n if (t === item.type) o.selected = true;\n grp.appendChild(o);\n seen.add(t);\n }\n el.appendChild(grp);\n };\n addOpts('scalar', types.filter((t) => SCALAR_TYPES.includes(t)));\n addOpts('expression', types.filter((t) => t === 'expression'));\n addOpts('typed reference', types.filter((t) => t.startsWith('ref:')));\n addOpts('list of references',\n types.filter((t) => t.startsWith('list[ref:')));\n addOpts('other', types.filter((t) => !seen.has(t)));\n el.addEventListener('change', () => {\n // On type change, leave default/value as-is \u2014 the user\n // may want to keep e.g. a numeric value when switching\n // from number to integer. The typed value cell renderer\n // coerces on display.\n callbacks.update({ type: el.value });\n onFlush();\n // Force re-render so the value cell picks up the new\n // input type (number \u2192 select, etc.).\n list?.setItems(currentItems());\n });\n return el;\n };\n\n const renderTypedValueCell = (field, item, callbacks) => {\n const t = item.type || 'string';\n if (t === 'boolean') {\n return renderBoolCell(item, field, callbacks);\n }\n if (t === 'integer' || t === 'number') {\n const el = document.createElement('input');\n el.type = 'number';\n el.className = 'twm-sortable-list__input twm-attr-editor__cell';\n el.step = (t === 'integer') ? '1' : 'any';\n el.value = (item[field] === null || item[field] === undefined)\n ? '' : item[field];\n el.placeholder = field;\n el.addEventListener('input', () => {\n const v = el.value === '' ? null\n : (t === 'integer' ? parseInt(el.value, 10)\n : Number(el.value));\n callbacks.update({ [field]: v });\n });\n el.addEventListener('blur', () => onFlush());\n return el;\n }\n if (t === 'expression') {\n // For an expression-typed attribute, the value cell shows\n // the expression itself (read-only by convention \u2014 the\n // engine fills it). Stub: render the expression string;\n // the actual expression authoring lives in the\n // `expression` column when shown.\n const el = document.createElement('span');\n el.className = 'twm-attr-editor__cell twm-attr-editor__cell--readonly';\n el.textContent = item.expression\n ? `\u2192 ${item.expression}` : '\u2014 (engine-evaluated)';\n return el;\n }\n if (t.startsWith('ref:')) {\n return renderRefCell(t.slice(4), field, item, callbacks);\n }\n if (t.startsWith('list[ref:') && t.endsWith(']')) {\n return renderListRefCell(t.slice(9, -1), field, item, callbacks);\n }\n if (Array.isArray(item.options) && item.options.length > 0) {\n return renderEnumCell(item.options, field, item, callbacks);\n }\n // String fallback.\n const el = document.createElement('input');\n el.type = 'text';\n el.className = 'twm-sortable-list__input twm-attr-editor__cell';\n el.value = item[field] ?? '';\n el.placeholder = field;\n el.addEventListener('input', () => {\n callbacks.update({ [field]: el.value });\n });\n el.addEventListener('blur', () => onFlush());\n return el;\n };\n\n const renderRefCell = (target, field, item, callbacks) => {\n const el = document.createElement('select');\n el.className = 'twm-attr-editor__cell';\n const placeholder = document.createElement('option');\n placeholder.value = '';\n placeholder.textContent = `\u2014 pick ${target} \u2014`;\n el.appendChild(placeholder);\n // Render once with the cached options if we have them; resolve\n // async otherwise and patch.\n const populate = (opts) => {\n // Clear everything except the placeholder.\n while (el.childNodes.length > 1) el.removeChild(el.lastChild);\n for (const o of opts) {\n const node = document.createElement('option');\n node.value = o.id;\n node.textContent = o.label;\n if (o.id === item[field]) node.selected = true;\n el.appendChild(node);\n }\n };\n if (refsCache.has(target)) {\n populate(refsCache.get(target));\n } else {\n resolveRefOptions(target).then(populate);\n }\n el.addEventListener('change', () => {\n callbacks.update({ [field]: el.value || null });\n onFlush();\n });\n return el;\n };\n\n const renderListRefCell = (target, field, item, callbacks) => {\n // MVP: comma-separated text input over the underlying string-\n // list. The chip-style picker can replace this without\n // changing the on-disk shape.\n const el = document.createElement('input');\n el.type = 'text';\n el.className = 'twm-sortable-list__input twm-attr-editor__cell';\n const arr = Array.isArray(item[field]) ? item[field] : [];\n el.value = arr.join(', ');\n el.placeholder = `${target}, ${target}, \u2026`;\n el.addEventListener('input', () => {\n const next = el.value.split(',')\n .map((s) => s.trim()).filter(Boolean);\n callbacks.update({ [field]: next });\n });\n el.addEventListener('blur', () => onFlush());\n return el;\n };\n\n const renderEnumCell = (options, field, item, callbacks) => {\n // `options` may be either a flat list of strings (legacy:\n // `['fx', 'commodity', \u2026]`) or a list of `{value, label}`\n // pairs (newer callers that want display labels distinct from\n // the stored value, e.g. market-rules ref fields where the\n // value is a currency id and the label is the currency name).\n const el = document.createElement('select');\n el.className = 'twm-attr-editor__cell';\n // Empty placeholder so the user can clear the selection.\n const blank = document.createElement('option');\n blank.value = '';\n blank.textContent = '\u2014';\n if (item[field] === null || item[field] === undefined || item[field] === '') {\n blank.selected = true;\n }\n el.appendChild(blank);\n for (const opt of options) {\n const o = document.createElement('option');\n if (opt !== null && typeof opt === 'object') {\n o.value = String(opt.value ?? opt.id ?? '');\n o.textContent = String(opt.label ?? opt.value ?? opt.id ?? '');\n } else {\n o.value = String(opt);\n o.textContent = String(opt);\n }\n if (o.value === String(item[field] ?? '')) o.selected = true;\n el.appendChild(o);\n }\n el.addEventListener('change', () => {\n callbacks.update({ [field]: el.value === '' ? null : el.value });\n onFlush();\n });\n return el;\n };\n\n // \u2500\u2500\u2500 SortableList wiring \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 const itemsCopy = (src) => (src || []).map((it) => ({ ...it }));\n const currentItems = () => list?.getItems?.() || itemsCopy(items);\n\n const buildList = (current) => {\n try { list?.dispose?.(); } catch {}\n listHost.innerHTML = '';\n list = new SortableList({\n containerId,\n items: itemsCopy(current),\n allowReorder,\n allowRemove,\n minItems: 0,\n emptyMessage,\n addButtonText,\n createItem,\n renderItem: renderRow,\n onChange: (next) => onChange(next.map((it) => ({ ...it }))),\n });\n listHost.appendChild(list.render());\n };\n\n buildList(items);\n\n return {\n addItem() { list?.addItem(); },\n refresh(nextItems) {\n // External update: rebuild to pick up new type-cell shapes.\n // Cheaper than setItems when types changed; setItems\n // wouldn't re-render the row controls.\n buildList(nextItems !== undefined ? nextItems : currentItems());\n },\n items() {\n return currentItems();\n },\n dispose() {\n try { list?.dispose?.(); } catch {}\n list = null;\n hostEl.innerHTML = '';\n hostEl.classList.remove('twm-attr-editor');\n },\n };\n}\n", "/**\n * column_fit.js \u2014 how wide each column of a table should be.\n *\n * A pure function over measurements, so the policy can be read and tested\n * without a DOM. A table measures its columns, hands them here, and applies\n * the widths it gets back.\n *\n * \u2500\u2500 The policy \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 * Columns are not all alike, and treating them alike is what went wrong\n * before. An id, a date, a status, a person: SHORT columns, whose values are\n * all about as wide as each other, and which are useless the moment they are\n * cut (\"2026-09-\u2026\", \"review-q\u2026\"). A summary or a title: TEXT columns, whose\n * values run as long as people write them, and which are readable cut.\n *\n * The old fit spread spare room EVENLY, so a 40px \"BUG\" chip got 90px while\n * the summary beside it was clipped in nine rows out of ten, and it shrank the\n * WIDEST column first, so a narrow tile crushed the title to 85px while every\n * short column kept its width.\n *\n * 1. Short columns get their full content width. Text columns start at a\n * readable width.\n * 2. Room to spare goes to the text columns, in proportion to what each\n * still needs, and past their content so the table fills its box. With no\n * text column it goes to the last column, so no column in the middle\n * opens a gap.\n * 3. Too little room: shrink in order of harm. Short columns first give up\n * only their rare longest values (down to `typical`, what most values\n * fit). Then text columns go down to a floor. Then short columns go down\n * to theirs, and text columns once more. What still does not fit scrolls\n * sideways rather than being crushed further.\n *\n * Within each step the widest columns give way first and the narrow ones keep\n * their width (a water level), so one long column never forces every other\n * column down with it.\n *\n * Columns the user dragged are PINNED: they keep their width and sit out every\n * step.\n */\n\nexport const COLUMN_FIT = Object.freeze({\n /** Absolute floor, and the drag-resize minimum. */\n FLOOR: 40,\n /** Sub-pixel safety against an ellipsis on content that exactly fits. */\n PAD: 2,\n /** A column whose full width reaches this is free text. */\n TEXT_AT: 240,\n /** A text column's starting share when room allows it. */\n TEXT_MIN: 200,\n /** How far a text column shrinks before short columns go below `typical`. */\n TEXT_FLOOR: 120,\n /** How far a short column shrinks before the table scrolls. */\n SHORT_FLOOR: 56,\n});\n\n/**\n * @typedef {object} ColumnMeasure\n * @property {number} natural widest cell, padding included (px)\n * @property {number} [typical] width most cells fit, e.g. the 95th percentile (px);\n * defaults to `natural`\n * @property {number} [header] the header label's width (px)\n * @property {number} [pinned] a user-dragged width, honoured exactly\n * @property {boolean} [text] force (true) or forbid (false) text treatment;\n * omitted, it is decided from the width\n */\n\n/**\n * @param {ColumnMeasure[]} columns\n * @param {number} avail the width the table has (px); 0 or less means \"not laid out\"\n * @returns {number[]} a width per column (px, possibly fractional). The sum\n * equals `avail` whenever the floors fit, and exceeds it only when they do\n * not, in which case the table should scroll.\n */\nexport function fitColumns(columns, avail) {\n const { FLOOR, PAD, TEXT_AT, TEXT_MIN, TEXT_FLOOR, SHORT_FLOOR } = COLUMN_FIT;\n const n = columns.length;\n const cols = columns.map((c) => {\n const header = Math.max(0, Number(c.header) || 0);\n const natural = Math.max(0, Number(c.natural) || 0);\n const full = Math.max(FLOOR, Math.ceil(Math.max(natural, header) + PAD));\n const typical = Math.min(full, Math.max(FLOOR, Math.ceil(Math.max(\n Number.isFinite(c.typical) ? c.typical : natural, header) + PAD)));\n const pinned = Number.isFinite(c.pinned) ? Math.max(FLOOR, Math.round(c.pinned)) : null;\n const text = pinned == null && (typeof c.text === 'boolean' ? c.text : full >= TEXT_AT);\n return { full, typical, pinned, text };\n });\n\n const text = [];\n const short = [];\n cols.forEach((c, i) => { if (c.pinned == null) (c.text ? text : short).push(i); });\n if (!(avail > 1)) return cols.map((c) => (c.pinned != null ? c.pinned : c.full));\n\n // 1. The starting point: short columns at their full content width, text\n // columns at a readable width (or their content, if shorter).\n const widths = cols.map((c) => {\n if (c.pinned != null) return c.pinned;\n return c.text ? Math.min(c.full, TEXT_MIN) : c.full;\n });\n const total = () => widths.reduce((a, b) => a + b, 0);\n let slack = avail - total();\n\n // 2. Room to spare goes to the text columns, in proportion to what each\n // still needs, then beyond their content so the table fills its box.\n // Widths are not rounded: CSS takes fractional pixels, and rounding is\n // what made the total miss the box by a pixel and a column jitter by one\n // as its tile was resized.\n if (slack >= 0) {\n slack = raise(widths, text, (i) => cols[i].full, slack);\n if (slack > 0) {\n if (text.length) text.forEach((i) => { widths[i] += slack / text.length; });\n else widths[short.length ? short[short.length - 1] : n - 1] += slack;\n }\n return widths;\n }\n\n // 3. Not enough room: shrink in order of harm until it fits.\n const steps = [\n [short, (i) => cols[i].typical],\n [text, () => TEXT_FLOOR],\n [short, (i) => Math.min(cols[i].typical, SHORT_FLOOR)],\n [text, () => FLOOR * 2],\n ];\n for (const [idxs, low] of steps) {\n const over = total() - avail;\n if (over <= 1e-6) break;\n lowerTo(widths, idxs, low, over);\n }\n return widths;\n}\n\n/**\n * Give up to `slack` px to the columns in `idxs`, each toward `target(i)`, in\n * proportion to how far each still is from it. Returns what is left.\n */\nfunction raise(widths, idxs, target, slack) {\n if (!(slack > 0)) return slack;\n const wants = idxs.map((i) => Math.max(0, target(i) - widths[i]));\n const need = wants.reduce((a, b) => a + b, 0);\n if (!(need > 0)) return slack;\n const give = Math.min(slack, need);\n idxs.forEach((i, k) => { widths[i] += give * wants[k] / need; });\n return slack - give;\n}\n\n/**\n * Take up to `over` px off the columns in `idxs`, widest first, none below\n * `low(i)`. A water level: every column above the level is cut down to it, and\n * the level is solved so the total cut is exactly `over`, or everything the\n * lows allow when that is less. Solved on real numbers: the result is exact,\n * and a wider box can never make any column narrower.\n */\nfunction lowerTo(widths, idxs, low, over) {\n const floorOf = (i) => Math.min(widths[i], Math.max(0, low(i)));\n const cand = idxs.filter((i) => widths[i] > floorOf(i));\n if (!cand.length || over <= 0) return;\n const floors = new Map(cand.map((i) => [i, floorOf(i)]));\n const capacity = cand.reduce((a, i) => a + widths[i] - floors.get(i), 0);\n if (capacity <= over) {\n for (const i of cand) widths[i] = floors.get(i);\n return;\n }\n const cutAt = (level) => cand.reduce((a, i) => a + Math.max(0, widths[i] - Math.max(floors.get(i), level)), 0);\n let lo = 0;\n let hi = Math.max(...cand.map((i) => widths[i]));\n for (let k = 0; k < 64; k++) {\n const mid = (lo + hi) / 2;\n if (cutAt(mid) > over) lo = mid; else hi = mid;\n }\n for (const i of cand) widths[i] = Math.min(widths[i], Math.max(floors.get(i), hi));\n}\n", "/**\n * Determinate progress: a bar, a keyed list of bars, and a row of phases.\n * Location: ui/components/progress.js\n *\n * Three primitives for long-running jobs, each a class that owns its own DOM\n * and changes it IN PLACE \u2014 a caller that reports progress twenty times a\n * second gets the same elements back every time, so a row it is hovering, a\n * tooltip anchored to it and a CSS transition on the fill all survive.\n *\n * ProgressBar value/max or a 0..1 fraction, indeterminate, a label, a\n * percent and a count readout, elapsed time, a cancel button,\n * and a final state (done / error / cancelled).\n * ProgressList keyed rows `{ key, name, completed, total?, state }`;\n * `setItems` reconciles by key. A row without `total` is\n * drawn against the largest item in the list.\n * StepProgress ordered phases, each done / active / pending / error, the\n * active one optionally reading \"pass n of m\".\n *\n * Nothing here knows what is being computed: names, labels and the stats line\n * are the caller's text, always set with `textContent`. State lives on the\n * instances; the DOM carries only classes and ARIA.\n */\n\n/** The states a ProgressBar can end in, besides `running`. */\nexport const PROGRESS_STATES = Object.freeze(['running', 'done', 'error', 'cancelled']);\n\n/** The states a ProgressList row can be in. */\nexport const PROGRESS_ITEM_STATES = Object.freeze(['pending', 'running', 'done', 'failed']);\n\n/** The states a StepProgress phase can be in. */\nexport const STEP_STATES = Object.freeze(['pending', 'active', 'done', 'error']);\n\nconst clamp01 = (x) => (x < 0 ? 0 : x > 1 ? 1 : x);\nconst isNum = (x) => typeof x === 'number' && Number.isFinite(x);\n\n/** `m:ss`, or `h:mm:ss` from an hour on. */\nexport function formatElapsed(ms) {\n const s = Math.max(0, Math.floor((ms || 0) / 1000));\n const h = Math.floor(s / 3600);\n const m = Math.floor((s % 3600) / 60);\n const ss = String(s % 60).padStart(2, '0');\n return h ? `${h}:${String(m).padStart(2, '0')}:${ss}` : `${m}:${ss}`;\n}\n\nfunction el(tag, className, text) {\n const n = document.createElement(tag);\n if (className) n.className = className;\n if (text !== undefined) n.textContent = text;\n return n;\n}\n\n/** Set text only when it changed, so an unchanged readout is not a mutation. */\nfunction setText(node, text) {\n const t = text == null ? '' : String(text);\n if (node.textContent !== t) node.textContent = t;\n}\n\nfunction setWidth(node, fraction) {\n const w = `${(clamp01(fraction) * 100).toFixed(2).replace(/\\.?0+$/, '')}%`;\n if (node.style.width !== w) node.style.width = w;\n}\n\n// \u2500\u2500\u2500 ProgressBar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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/**\n * @typedef {Object} ProgressBarOptions\n * @property {number} [value=0] - A count when `max` is given, else a 0..1 fraction.\n * @property {number|null} [max=null] - The count `value` runs to.\n * @property {boolean} [indeterminate=false] - Busy, with no known end.\n * @property {string} [label=''] - Text before the readout.\n * @property {boolean} [showPercent=true] - \"42%\".\n * @property {boolean|null} [showCount=null] - \"21 / 50\"; defaults to on when `max` is given.\n * @property {boolean} [showElapsed=false] - A running \"m:ss\" from construction until a final state.\n * @property {Function|null} [onCancel=null] - Shows a Cancel button; called once when clicked.\n * @property {string} [cancelLabel='Cancel']\n * @property {Function} [now=Date.now] - The clock, for the elapsed readout.\n * @property {string} [className] - Added to the root.\n */\n\nexport class ProgressBar {\n /**\n * @param {HTMLElement|null} host appended to, if given\n * @param {ProgressBarOptions} [options]\n */\n constructor(host, options = {}) {\n const {\n value = 0, max = null, indeterminate = false, label = '',\n showPercent = true, showCount = null, showElapsed = false,\n onCancel = null, cancelLabel = 'Cancel', now = Date.now, className = '',\n } = options;\n this._value = isNum(value) ? value : 0;\n this._max = isNum(max) && max > 0 ? max : null;\n this._indeterminate = !!indeterminate;\n this._label = label || '';\n this._showPercent = showPercent !== false;\n this._showCount = showCount;\n this._showElapsed = !!showElapsed;\n this._state = 'running';\n this._now = typeof now === 'function' ? now : Date.now;\n this._started = this._now();\n this._stopped = null;\n this._timer = null;\n this._onCancel = typeof onCancel === 'function' ? onCancel : null;\n\n const root = el('div', `twm-progress${className ? ` ${className}` : ''}`);\n const head = el('div', 'twm-progress__head');\n this._labelEl = el('span', 'twm-progress__label');\n this._readoutEl = el('span', 'twm-progress__readout');\n head.append(this._labelEl, this._readoutEl);\n if (this._showElapsed) {\n this._elapsedEl = el('span', 'twm-progress__elapsed');\n head.appendChild(this._elapsedEl);\n this._startTimer();\n } else {\n this._elapsedEl = null;\n }\n if (this._onCancel) {\n const btn = el('button', 'twm-progress__cancel', cancelLabel);\n btn.type = 'button';\n btn.addEventListener('click', () => {\n if (btn.disabled || this._state !== 'running') return;\n btn.disabled = true;\n this._onCancel();\n });\n this._cancelBtn = btn;\n head.appendChild(btn);\n } else {\n this._cancelBtn = null;\n }\n this._track = el('div', 'twm-progress__track');\n this._track.setAttribute('role', 'progressbar');\n this._fill = el('div', 'twm-progress__fill');\n this._track.appendChild(this._fill);\n root.append(head, this._track);\n this.element = root;\n this._draw();\n if (host) host.appendChild(root);\n }\n\n /** The bar's fraction 0..1, or null while indeterminate. */\n get fraction() {\n if (this._indeterminate) return null;\n return clamp01(this._max ? this._value / this._max : this._value);\n }\n\n /** `running`, `done`, `error` or `cancelled`. */\n get state() { return this._state; }\n\n /** Milliseconds since construction, frozen at the final state. */\n get elapsed() { return (this._stopped ?? this._now()) - this._started; }\n\n /**\n * Change the bar in place. A number is the new value (a count with `max`,\n * else a fraction); an object may carry `value`, `max`, `label` and\n * `indeterminate`. Ignored once the bar is in a final state.\n */\n update(next) {\n if (this._state !== 'running') return this;\n const o = isNum(next) ? { value: next } : (next || {});\n if ('max' in o) this._max = isNum(o.max) && o.max > 0 ? o.max : null;\n if (isNum(o.value)) { this._value = o.value; if (!('indeterminate' in o)) this._indeterminate = false; }\n if ('indeterminate' in o) this._indeterminate = !!o.indeterminate;\n if ('label' in o) this._label = o.label || '';\n this._draw();\n return this;\n }\n\n /**\n * Put the bar in a final state (`done`, `error`, `cancelled`) or back to\n * `running`. `done` fills it. A final state stops the elapsed clock and\n * disables Cancel; `running` restarts the clock (still counting from\n * construction) and enables Cancel again. `label` replaces the label when\n * given.\n */\n setState(state, { label } = {}) {\n if (!PROGRESS_STATES.includes(state)) throw new Error(`ProgressBar: unknown state \"${state}\"`);\n this._state = state;\n if (label !== undefined) this._label = label || '';\n if (state === 'done') { this._indeterminate = false; this._value = this._max ?? 1; }\n if (state === 'running') {\n this._stopped = null;\n if (this._showElapsed) this._startTimer();\n } else {\n this._stopped = this._now();\n if (this._timer) { clearInterval(this._timer); this._timer = null; }\n }\n if (this._cancelBtn) this._cancelBtn.disabled = state !== 'running';\n this._draw();\n this._drawElapsed();\n return this;\n }\n\n /** Tick the elapsed readout once a second, unless it already ticks. */\n _startTimer() {\n if (!this._timer) this._timer = setInterval(() => this._drawElapsed(), 1000);\n }\n\n /** Stop the elapsed clock and detach. */\n dispose() {\n this._showElapsed = false;\n if (this._timer) { clearInterval(this._timer); this._timer = null; }\n this.element.remove();\n }\n\n _draw() {\n const root = this.element;\n for (const s of PROGRESS_STATES) {\n root.classList.toggle(`twm-progress--${s}`, this._state === s);\n }\n root.classList.toggle('twm-progress--indeterminate', this._indeterminate);\n setText(this._labelEl, this._label);\n const f = this.fraction;\n const parts = [];\n if (f !== null) {\n if (this._showPercent) parts.push(`${Math.floor(f * 100)}%`);\n const count = this._showCount ?? !!this._max;\n if (count && this._max) parts.push(`${fmtCount(this._value)} / ${fmtCount(this._max)}`);\n }\n setText(this._readoutEl, parts.join(' \u00B7 '));\n if (f === null) {\n if (this._fill.style.width) this._fill.style.width = '';\n this._track.removeAttribute('aria-valuenow');\n } else {\n setWidth(this._fill, f);\n this._track.setAttribute('aria-valuenow', String(Math.round(f * 100)));\n }\n this._track.setAttribute('aria-valuemin', '0');\n this._track.setAttribute('aria-valuemax', '100');\n if (this._label) this._track.setAttribute('aria-label', this._label);\n this._drawElapsed();\n }\n\n _drawElapsed() {\n if (this._elapsedEl) setText(this._elapsedEl, formatElapsed(this.elapsed));\n }\n}\n\nfunction fmtCount(n) {\n return Number.isInteger(n) ? String(n) : String(Math.round(n * 100) / 100);\n}\n\n// \u2500\u2500\u2500 ProgressList \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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/**\n * @typedef {Object} ProgressItem\n * @property {string|number} key - Identity across `setItems` calls.\n * @property {string} [name] - Shown as the row's label; defaults to the key.\n * @property {number} [completed=0]\n * @property {number} [total] - Absent: the row is drawn against the largest item.\n * @property {'pending'|'running'|'done'|'failed'} [state='pending']\n * @property {string} [detail] - Extra text after the count.\n */\n\n/**\n * @typedef {Object} ProgressListOptions\n * @property {ProgressItem[]} [items=[]]\n * @property {boolean|Function} [stats=true] - The line under the rows: `true`\n * for the default summary, `false` for none, or `(items) => string`.\n * @property {boolean} [pulse=true] - Running rows pulse.\n * @property {string} [emptyText=''] - Shown when there are no items.\n * @property {string} [className] - Added to the root.\n */\n\nexport class ProgressList {\n /**\n * @param {HTMLElement|null} host appended to, if given\n * @param {ProgressListOptions} [options]\n */\n constructor(host, options = {}) {\n const { items = [], stats = true, pulse = true, emptyText = '', className = '' } = options;\n this._stats = stats;\n this._emptyText = emptyText;\n /** @type {Map<string, {item: ProgressItem, row: HTMLElement, name: HTMLElement, fill: HTMLElement, count: HTMLElement, state: HTMLElement}>} */\n this._rows = new Map();\n this._items = [];\n const root = el('div', `twm-progress-list${pulse ? ' twm-progress-list--pulse' : ''}${className ? ` ${className}` : ''}`);\n this._listEl = el('div', 'twm-progress-list__rows');\n this._listEl.setAttribute('role', 'list');\n this._emptyEl = el('div', 'twm-progress-list__empty');\n this._statsEl = el('div', 'twm-progress-list__stats');\n root.append(this._listEl, this._emptyEl, this._statsEl);\n this.element = root;\n this.setItems(items);\n if (host) host.appendChild(root);\n }\n\n /** The items last given, in order. */\n get items() { return this._items.slice(); }\n\n /**\n * Reconcile the rows with `items` by key: a known key keeps its row and\n * has its text, width and state changed in place; a new key gets a row; a\n * key that is gone loses its row. Rows follow the order given, and a row\n * already in its place is not moved.\n */\n setItems(items) {\n const list = Array.isArray(items) ? items : [];\n const seen = new Set();\n this._items = [];\n for (const it of list) {\n if (!it || it.key == null) continue;\n const k = String(it.key);\n if (seen.has(k)) continue;\n seen.add(k);\n this._items.push(it);\n }\n for (const [k, r] of this._rows) {\n if (!seen.has(k)) { r.row.remove(); this._rows.delete(k); }\n }\n const scale = this._items.reduce((m, it) => {\n const d = isNum(it.total) && it.total > 0 ? it.total : (isNum(it.completed) ? it.completed : 0);\n return d > m ? d : m;\n }, 0);\n let prev = null;\n for (const it of this._items) {\n const k = String(it.key);\n let r = this._rows.get(k);\n if (!r) { r = this._makeRow(); this._rows.set(k, r); }\n this._drawRow(r, it, scale);\n const want = prev ? prev.nextSibling : this._listEl.firstChild;\n if (want !== r.row) this._listEl.insertBefore(r.row, want);\n prev = r.row;\n }\n this._emptyEl.hidden = this._items.length > 0 || !this._emptyText;\n setText(this._emptyEl, this._emptyText);\n const line = this._statsLine();\n this._statsEl.hidden = !line;\n setText(this._statsEl, line);\n return this;\n }\n\n /** The row element for `key`, or null. */\n rowFor(key) { return this._rows.get(String(key))?.row ?? null; }\n\n dispose() { this.element.remove(); this._rows.clear(); }\n\n _makeRow() {\n const row = el('div', 'twm-progress-list__row');\n row.setAttribute('role', 'listitem');\n const name = el('span', 'twm-progress-list__name');\n const track = el('div', 'twm-progress-list__track');\n const fill = el('div', 'twm-progress-list__fill');\n track.appendChild(fill);\n const count = el('span', 'twm-progress-list__count');\n const state = el('span', 'twm-progress-list__state');\n row.append(state, name, track, count);\n return { row, name, fill, count, state };\n }\n\n _drawRow(r, it, scale) {\n const state = PROGRESS_ITEM_STATES.includes(it.state) ? it.state : 'pending';\n for (const s of PROGRESS_ITEM_STATES) {\n r.row.classList.toggle(`twm-progress-list__row--${s}`, s === state);\n }\n const done = isNum(it.completed) ? it.completed : 0;\n const hasTotal = isNum(it.total) && it.total > 0;\n const denom = hasTotal ? it.total : scale;\n setWidth(r.fill, denom > 0 ? done / denom : 0);\n setText(r.name, it.name ?? String(it.key));\n const count = hasTotal ? `${fmtCount(done)} / ${fmtCount(it.total)}` : fmtCount(done);\n setText(r.count, it.detail ? `${count} \u00B7 ${it.detail}` : count);\n if (r.state.title !== state) r.state.title = state;\n }\n\n _statsLine() {\n if (this._stats === false) return '';\n if (typeof this._stats === 'function') return String(this._stats(this.items) ?? '');\n if (!this._items.length) return '';\n const n = { done: 0, running: 0, failed: 0, pending: 0 };\n let completed = 0;\n for (const it of this._items) {\n n[PROGRESS_ITEM_STATES.includes(it.state) ? it.state : 'pending'] += 1;\n if (isNum(it.completed)) completed += it.completed;\n }\n const parts = [`${n.done} / ${this._items.length} done`];\n if (n.running) parts.push(`${n.running} running`);\n if (n.failed) parts.push(`${n.failed} failed`);\n if (n.pending) parts.push(`${n.pending} pending`);\n parts.push(`${fmtCount(completed)} completed`);\n return parts.join(' \u00B7 ');\n }\n}\n\n// \u2500\u2500\u2500 StepProgress \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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/**\n * @typedef {Object} StepDef\n * @property {string} [key] - How `setStep` names it; defaults to its index.\n * @property {string} label\n */\n\nexport class StepProgress {\n /**\n * @param {HTMLElement|null} host appended to, if given\n * @param {{ steps?: Array<StepDef|string>, className?: string }} [options]\n */\n constructor(host, options = {}) {\n const { steps = [], className = '' } = options;\n const root = el('ol', `twm-steps${className ? ` ${className}` : ''}`);\n this.element = root;\n this._steps = steps.map((s, i) => {\n const def = typeof s === 'string' ? { label: s } : (s || {});\n const li = el('li', 'twm-steps__step');\n const marker = el('span', 'twm-steps__marker');\n const label = el('span', 'twm-steps__label', def.label ?? '');\n const pass = el('span', 'twm-steps__pass');\n pass.hidden = true;\n li.append(marker, label, pass);\n root.appendChild(li);\n return { key: def.key != null ? String(def.key) : String(i), label: def.label ?? '', state: 'pending', pass: null, li, passEl: pass };\n });\n this._draw();\n if (host) host.appendChild(root);\n }\n\n /** `[{ key, label, state, pass }]`, in order. */\n get steps() {\n return this._steps.map(({ key, label, state, pass }) => ({ key, label, state, pass }));\n }\n\n /** The index of the active phase, or -1. */\n get activeIndex() { return this._steps.findIndex((s) => s.state === 'active'); }\n\n /**\n * Make one phase active: every phase before it is done, every phase after\n * it pending. `pass` and `passes` read \"pass n of m\" on it.\n * @param {string|number} which - A key, or an index.\n * @param {{ pass?: number, passes?: number }} [opts]\n */\n setStep(which, { pass, passes } = {}) {\n const i = this._index(which);\n this._steps.forEach((s, j) => {\n s.state = j < i ? 'done' : j === i ? 'active' : 'pending';\n s.pass = j === i && isNum(pass) ? { n: pass, of: isNum(passes) ? passes : null } : null;\n });\n this._draw();\n return this;\n }\n\n /** Mark a phase (the active one by default) as failed; phases after it stay pending. */\n fail(which) {\n const i = which === undefined ? this.activeIndex : this._index(which);\n if (i < 0) return this;\n this._steps.forEach((s, j) => {\n if (j < i) s.state = 'done';\n else if (j === i) s.state = 'error';\n else s.state = 'pending';\n if (j !== i) s.pass = null;\n });\n this._draw();\n return this;\n }\n\n /** Every phase done. */\n complete() {\n for (const s of this._steps) { s.state = 'done'; s.pass = null; }\n this._draw();\n return this;\n }\n\n dispose() { this.element.remove(); }\n\n _index(which) {\n const i = typeof which === 'number'\n ? which\n : this._steps.findIndex((s) => s.key === String(which));\n if (!Number.isInteger(i) || i < 0 || i >= this._steps.length) {\n throw new Error(`StepProgress: no step \"${which}\"`);\n }\n return i;\n }\n\n _draw() {\n for (const s of this._steps) {\n for (const st of STEP_STATES) s.li.classList.toggle(`twm-steps__step--${st}`, s.state === st);\n if (s.state === 'active') s.li.setAttribute('aria-current', 'step');\n else s.li.removeAttribute('aria-current');\n const text = s.pass ? (s.pass.of ? `pass ${s.pass.n} of ${s.pass.of}` : `pass ${s.pass.n}`) : '';\n s.passEl.hidden = !text;\n setText(s.passEl, text);\n }\n }\n}\n", "/**\n * The progress block both job dialogs share \u2014 `showRunProgressDialog` and\n * `showComputingWindow` \u2014 so a bar and a row of phases behave the same in\n * either. Internal: not in the `widgets` barrel.\n */\n\nimport { ProgressBar, StepProgress } from './progress.js';\n\n/**\n * Mount the optional phases and bar into `parent`, phases first.\n *\n * @param {HTMLElement} parent\n * @param {{ progress?: boolean|Object, steps?: Array, spinner?: HTMLElement|null }} options\n * `progress`: `true`, or ProgressBar options (its `onCancel` is ignored: the\n * dialog owns cancelling). `steps`: StepProgress steps. `spinner`: hidden\n * while a bar is shown. Both are fixed at mount: `setProgress` throws\n * without `progress` and `setStep` without `steps`, so the window is sized\n * for what it holds from the start.\n */\nexport function mountJobProgress(parent, { progress = null, steps = null, spinner = null } = {}) {\n const stepper = Array.isArray(steps) && steps.length\n ? new StepProgress(parent, { steps, className: 'twm-job-progress__steps' })\n : null;\n let bar = null;\n if (progress) {\n const { onCancel: _ignored, ...rest } = typeof progress === 'object' ? progress : {};\n bar = new ProgressBar(parent, { ...rest, className: 'twm-job-progress__bar' });\n if (spinner) spinner.hidden = true;\n }\n\n return {\n get bar() { return bar; },\n get steps() { return stepper; },\n /** `bar.update(next)`. */\n setProgress(next) {\n if (!bar) throw new Error('setProgress: this dialog was opened without `progress`');\n bar.update(next);\n },\n /** `steps.setStep(which, opts)`. */\n setStep(which, opts) {\n if (!stepper) throw new Error('setStep: this dialog was opened without `steps`');\n stepper.setStep(which, opts);\n },\n /** Put the bar and the phases in their final state. */\n finish(status) {\n if (status === 'done') { bar?.setState('done'); stepper?.complete(); }\n else if (status === 'error') { bar?.setState('error'); stepper?.fail(); }\n else bar?.setState('cancelled');\n },\n };\n}\n", "/**\n * Computing Status Window\n *\n * Lightweight ManagedWindow that shows a spinner (or a progress bar) and a\n * status message while a long-running computation is in progress. Returns a\n * handle with update(), setProgress(), setStep(), complete(), cancelled(),\n * close() and a `result` promise.\n *\n * Optionally shows a Cancel button when an onCancel callback is provided.\n * Only one is open at a time: opening another closes the first, which then\n * settles as cancelled (its onCancel is not called).\n */\n\nimport { ManagedWindow } from './managed_window.js';\nimport { mountJobProgress } from './job_progress.js';\n\nlet _activeWindow = null;\n\n/**\n * Show a computing status window.\n *\n * `result` settles once: `complete({ok, message})` gives `done` or `error`\n * (the window stays, with a Close button, until closed), `cancelled()` gives\n * `cancelled`, and so does closing the window while it runs (by its \u00D7,\n * Escape, `close()` or opening another). Closing never calls `onCancel`: only\n * the Cancel button does. `progress` and `steps` are fixed when the window\n * opens: `setProgress` throws if it was opened without `progress`, and\n * `setStep` if it was opened without `steps`.\n *\n * @param {Object} options\n * @param {string} [options.title='Computing...'] - Window title\n * @param {string} [options.message=''] - Status message below spinner (markup; `update` takes text)\n * @param {string} [options.icon='hourglass_top'] - Material icon name\n * @param {Function} [options.onCancel] - If provided, shows a Cancel button. Called once when clicked.\n * @param {boolean|Object} [options.progress] - A ProgressBar in place of the spinner: `true` or its options.\n * @param {Array} [options.steps] - StepProgress steps, shown above the message.\n * @returns {{ update(msg: string): void, setProgress(next: number|Object): void,\n * setStep(which: string|number, opts?: {pass?: number, passes?: number}): void,\n * complete(result: {ok: boolean, message?: string}): void, cancelled(msg?: string): void,\n * close(): void, result: Promise<{status: 'done'|'error'|'cancelled', message: string}> }}\n */\nexport function showComputingWindow({\n title = 'Computing...', message = '', icon = 'hourglass_top', onCancel,\n progress = null, steps = null,\n} = {}) {\n if (_activeWindow) {\n _activeWindow.close();\n _activeWindow = null;\n }\n\n let finished = false;\n let settle;\n const result = new Promise((resolve) => { settle = resolve; });\n\n const content = document.createElement('div');\n content.className = 'twm-computing-status';\n const spinnerEl = document.createElement('div');\n spinnerEl.className = 'twm-computing-status__spinner';\n const msgEl = document.createElement('div');\n msgEl.className = 'twm-computing-status__message';\n // The opening message is markup, as it always was; every later one is text.\n msgEl.innerHTML = message;\n content.appendChild(spinnerEl);\n const job = mountJobProgress(content, { progress, steps, spinner: spinnerEl });\n content.appendChild(msgEl);\n\n let cancelBtn = null;\n if (typeof onCancel === 'function') {\n cancelBtn = document.createElement('button');\n cancelBtn.className = 'twm-computing-status__cancel-btn';\n cancelBtn.textContent = 'Cancel';\n cancelBtn.addEventListener('click', () => {\n cancelBtn.disabled = true;\n msgEl.textContent = 'Cancelling...';\n onCancel();\n }, { once: true });\n content.appendChild(cancelBtn);\n }\n\n const closeBtn = document.createElement('button');\n closeBtn.type = 'button';\n closeBtn.className = 'twm-computing-status__cancel-btn twm-computing-status__close-btn';\n closeBtn.textContent = 'Close';\n closeBtn.hidden = true;\n content.appendChild(closeBtn);\n\n const finish = (status, text) => {\n finished = true;\n spinnerEl.hidden = true;\n if (cancelBtn) cancelBtn.hidden = true;\n msgEl.textContent = text;\n msgEl.classList.toggle('is-ok', status === 'done');\n msgEl.classList.toggle('is-err', status === 'error');\n msgEl.classList.toggle('is-cancelled', status === 'cancelled');\n job.finish(status);\n settle({ status, message: text });\n };\n\n const win = new ManagedWindow({\n id: 'computing-status-window',\n title,\n icon,\n content,\n minWidth: 320,\n minHeight: 140,\n defaultWidth: 380,\n defaultHeight: (onCancel ? 190 : 160) + (job.bar ? 30 : 0) + (job.steps ? 40 : 0),\n canMinimize: true,\n canMaximize: false,\n canResize: false,\n canDrag: true,\n modal: false,\n onClose: () => {\n if (_activeWindow === win) _activeWindow = null;\n if (finished) return;\n finish('cancelled', 'Cancelled.');\n },\n });\n closeBtn.addEventListener('click', () => win.close());\n _activeWindow = win;\n win.show();\n\n return {\n result,\n update(msg) {\n if (finished) return;\n msgEl.textContent = msg;\n },\n setProgress(next) {\n if (finished) return;\n job.setProgress(next);\n },\n setStep(which, opts) {\n if (finished) return;\n job.setStep(which, opts);\n },\n complete(res) {\n if (finished) return;\n finish(res?.ok ? 'done' : 'error', res?.message || '');\n closeBtn.hidden = false;\n },\n cancelled(msg) {\n if (finished) return;\n finish('cancelled', msg || 'Cancelled.');\n closeBtn.hidden = false;\n },\n close() {\n if (_activeWindow) {\n _activeWindow.close();\n _activeWindow = null;\n }\n },\n };\n}\n", "/**\n * Confirm Dialog Component\n * Location: ui/components/confirm_dialog.js\n *\n * Thin delegator over the canonical modal helpers in\n * `ecoagent/ui/modal.js`. Every dialog signature here is preserved so\n * the 10+ call sites across notebook/data/results/ai pages keep\n * working unchanged; under the hood, all four standard dialogs now\n * flow through `openConfirm` / `openForm` / `openModal` so they\n * inherit the TUI styling (`\u25B8 TITLE` strip, accent-blue primary\n * action, square frame, Tab focus trap).\n *\n * The one custom case is `showRunProgressDialog`, which exposes an\n * imperative `update / setProgress / setStep / complete / cancelled /\n * close` API and a `result` promise, and so\n * stays as a direct `ManagedWindow` build \u2014 but it still benefits\n * from the focus trap + chrome by virtue of `modal: true`.\n */\n\nimport { ManagedWindow } from './managed_window.js';\nimport { mountJobProgress } from './job_progress.js';\nimport {\n openConfirm, openForm, openModal,\n} from './modal.js';\n\n// Counter \u2014 used only by showRunProgressDialog which still builds its\n// own ManagedWindow. The migrated helpers don't need it.\nlet dialogIdCounter = 0;\n\n/**\n * Show a confirmation dialog. Delegates to `openConfirm`.\n * @param {Object} options\n * @param {string} options.title\n * @param {string} options.message\n * @param {string} [options.icon='warning']\n * @param {string} [options.okLabel='OK']\n * @param {string} [options.cancelLabel='Cancel']\n * @param {string} [options.okVariant='primary'] - 'primary' or 'danger'\n * @returns {Promise<boolean>}\n */\nexport async function showConfirmDialog(options = {}) {\n const {\n title = 'Confirm',\n message = 'Are you sure?',\n icon = 'warning',\n okLabel = 'OK',\n cancelLabel = 'Cancel',\n okVariant = 'primary',\n } = options;\n return openConfirm({\n title,\n message,\n icon,\n confirmLabel: okLabel,\n cancelLabel,\n danger: okVariant === 'danger',\n });\n}\n\n/**\n * Show a delete-confirmation dialog. Always danger-styled.\n * @returns {Promise<boolean>}\n */\nexport async function showDeleteConfirmDialog(options = {}) {\n const {\n itemName = '',\n itemType = 'item',\n additionalMessage = '',\n } = options;\n // `openConfirm` renders the message as text, so a user-named item\n // (`<b>x</b>`, an unclosed `<`) is shown exactly as it was typed.\n let message = `Delete ${itemType}`;\n if (itemName) message += ` \"${itemName}\"`;\n message += '?';\n if (additionalMessage) message += `\\n\\n${additionalMessage}`;\n return openConfirm({\n title: `Delete ${capitalize(itemType)}`,\n message,\n icon: 'delete',\n confirmLabel: 'Delete',\n cancelLabel: 'Cancel',\n danger: true,\n });\n}\n\n/**\n * Show a close-confirmation dialog.\n * @returns {Promise<boolean>}\n */\nexport async function showCloseConfirmDialog(options = {}) {\n const {\n itemName = '',\n itemType = 'tab',\n } = options;\n let message = `Close ${itemType}`;\n if (itemName) message += ` \"${itemName}\"`;\n message += '?';\n return openConfirm({\n title: `Close ${capitalize(itemType)}`,\n message,\n icon: 'close',\n confirmLabel: 'Close',\n cancelLabel: 'Cancel',\n });\n}\n\n/**\n * Show a dialog with multiple action buttons. Delegates to `openModal`\n * so each action maps to a button in the canonical footer.\n * @returns {Promise<string|null>}\n */\nexport async function showChoiceDialog(options = {}) {\n const {\n title = 'Choose',\n message = '',\n icon = 'warning',\n actions = [],\n } = options;\n const content = document.createElement('div');\n content.className = 'twm-confirm-dialog__body';\n content.innerHTML = `\n <span class=\"twm-confirm-dialog__icon material-symbols-outlined\">${escapeHtml(icon)}</span>\n <div class=\"twm-confirm-dialog__message\">${escapeHtml(message)}</div>\n `;\n return openModal({\n title,\n icon,\n content,\n width: 480,\n height: 220,\n actions: actions.map((a) => ({\n label: a.label,\n value: a.value,\n primary: a.variant === 'primary',\n danger: a.variant === 'danger',\n })),\n });\n}\n\n/**\n * Show a dialog with a dropdown select + OK/Cancel. Delegates to\n * `openForm` with a single select field.\n * @returns {Promise<string|null>}\n */\nexport async function showSelectDialog(options = {}) {\n const {\n title = 'Select',\n message = '',\n items = [],\n okLabel = 'OK',\n cancelLabel = 'Cancel',\n } = options;\n const fields = [];\n if (message) {\n fields.push({ section: message });\n }\n fields.push({\n name: '_choice',\n label: 'Choice',\n type: 'select',\n default: items[0]?.value || '',\n options: items.map((i) => ({ value: i.value, label: i.label })),\n });\n // NB: cancelLabel is currently hardcoded as \"Cancel\" on openForm.\n // openConfirm has cancelLabel; if a caller really needs custom\n // cancel text on openForm, we'd extend openForm there. The\n // explicit no-op suppresses the unused-arg lint.\n void cancelLabel;\n const data = await openForm({\n title,\n submitLabel: okLabel,\n fields,\n });\n if (!data) return null;\n return data._choice;\n}\n\n\n// \u2500\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\n\nfunction escapeHtml(str) {\n if (!str) return '';\n return String(str)\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\nfunction capitalize(str) {\n if (!str) return '';\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\n\n// \u2500\u2500\u2500 showRunProgressDialog (custom build) \u2500\u2500\u2500\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// This one exposes an imperative API (`update`, `setProgress`, `setStep`,\n// `complete`, `cancelled`, `close`) that the openModal/openForm/openConfirm\n// helpers don't model \u2014 they're one-shot promise-returning. Keep the direct\n// ManagedWindow build, but it still gets the TUI chrome + focus trap for free\n// via `modal: true`.\n\n/**\n * @typedef {Object} RunProgressResult\n * @property {'done'|'error'|'cancelled'} status\n * @property {string} message\n */\n\n/**\n * Show a run progress dialog with a spinner (or a bar), live message\n * updates, optional phases, and a final status.\n *\n * `progress` (`true` or ProgressBar options) shows a determinate bar in place\n * of the spinner; `steps` (StepProgress steps) shows the phases above it.\n * Both are fixed when the dialog opens: `setProgress` throws if it was opened\n * without `progress`, and `setStep` if it was opened without `steps`.\n * `result` settles once, with the final state: `complete({ok})` gives `done`\n * or `error`, `cancelled()` gives `cancelled`, and so does closing the dialog\n * while it runs (by its \u00D7, Escape or `close()`). Closing never calls\n * `onCancel`: only the Stop button does.\n *\n * @param {Object} [options]\n * @param {string} [options.title='Running Pipeline']\n * @param {string} [options.message='Starting\u2026']\n * @param {Function} [options.onCancel] - Shows a Stop button.\n * @param {boolean|Object} [options.progress] - A ProgressBar, `true` or its options.\n * @param {Array} [options.steps] - StepProgress steps.\n * @returns {{ update(msg: string): void, setProgress(next: number|Object): void,\n * setStep(which: string|number, opts?: {pass?: number, passes?: number}): void,\n * complete(result: {ok: boolean, message: string}): void, cancelled(msg?: string): void,\n * close(): void, result: Promise<RunProgressResult> }}\n */\nexport function showRunProgressDialog(options = {}) {\n const {\n title = 'Running Pipeline',\n message = 'Starting\u2026',\n onCancel,\n progress = null,\n steps = null,\n } = options;\n\n const dialogId = `run-progress-${++dialogIdCounter}`;\n let finished = false;\n let settle;\n const result = new Promise((resolve) => { settle = resolve; });\n\n const contentEl = document.createElement('div');\n contentEl.className = 'twm-confirm-dialog__content run-progress';\n\n const bodyEl = document.createElement('div');\n bodyEl.className = 'twm-run-progress__body';\n const spinnerEl = document.createElement('div');\n spinnerEl.className = 'twm-run-progress__spinner';\n const messageEl = document.createElement('div');\n messageEl.className = 'twm-run-progress__message';\n messageEl.textContent = message;\n bodyEl.append(spinnerEl, messageEl);\n contentEl.appendChild(bodyEl);\n\n const job = mountJobProgress(contentEl, { progress, steps, spinner: spinnerEl });\n\n let stopBtn = null;\n if (typeof onCancel === 'function') {\n const stopActionsEl = document.createElement('div');\n stopActionsEl.className = 'twm-confirm-dialog__actions twm-run-progress__stop-actions';\n stopBtn = document.createElement('button');\n stopBtn.type = 'button';\n stopBtn.className = 'twm-confirm-dialog__btn twm-run-progress__stop-btn';\n stopBtn.innerHTML = '<span class=\"material-symbols-outlined\">stop</span> Stop';\n stopBtn.addEventListener('click', () => {\n stopBtn.disabled = true;\n stopBtn.innerHTML = '<span class=\"material-symbols-outlined\">hourglass_top</span> Stopping\u2026';\n onCancel();\n });\n stopActionsEl.appendChild(stopBtn);\n contentEl.appendChild(stopActionsEl);\n }\n\n const actionsEl = document.createElement('div');\n actionsEl.className = 'twm-confirm-dialog__actions';\n actionsEl.style.display = 'none';\n\n const closeBtn = document.createElement('button');\n closeBtn.type = 'button';\n closeBtn.className = 'twm-confirm-dialog__btn twm-confirm-dialog__btn--primary';\n closeBtn.textContent = 'Close';\n closeBtn.addEventListener('click', () => dialogWindow.close());\n actionsEl.appendChild(closeBtn);\n contentEl.appendChild(actionsEl);\n\n const finish = (status, text, cls) => {\n finished = true;\n spinnerEl.style.display = 'none';\n if (stopBtn) stopBtn.parentElement.style.display = 'none';\n messageEl.textContent = text;\n messageEl.className = `twm-run-progress__message ${cls}`;\n job.finish(status);\n actionsEl.style.display = '';\n settle({ status, message: text });\n };\n\n const dialogWindow = new ManagedWindow({\n id: dialogId,\n title,\n icon: 'play_arrow',\n content: contentEl,\n minWidth: 320,\n minHeight: 120,\n defaultWidth: 420,\n defaultHeight: 200 + (job.bar ? 40 : 0) + (job.steps ? 40 : 0),\n canMinimize: false,\n canMaximize: false,\n canResize: false,\n canDrag: false,\n modal: true,\n onClose: () => {\n if (finished) return;\n finish('cancelled', 'Cancelled.', 'is-cancelled');\n },\n });\n dialogWindow.show();\n\n return {\n result,\n update(msg) {\n if (finished) return;\n messageEl.textContent = msg;\n },\n setProgress(next) {\n if (finished) return;\n job.setProgress(next);\n },\n setStep(which, opts) {\n if (finished) return;\n job.setStep(which, opts);\n },\n complete(res) {\n if (finished) return;\n finish(res?.ok ? 'done' : 'error', res?.message || '', res?.ok ? 'is-ok' : 'is-err');\n },\n cancelled(msg) {\n if (finished) return;\n finish('cancelled', msg || 'Cancelled.', 'is-cancelled');\n },\n close() {\n try { dialogWindow.close(); } catch { /* already closed */ }\n },\n };\n}\n", "/**\n * \u2550\u2550 THE CONVERSATION VIEW \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\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 transcript of role-tagged messages above a composer (FlexDesk STORY-0057).\n * It knows nothing about what a message says or where it came from: no\n * markdown, no model, no provider. The caller draws a message's body (or\n * leaves it as plain text) and is told when the user submits or cancels.\n *\n * const view = mountConversationView(el, {\n * render: (message, bodyEl, { streaming }) => { bodyEl.innerHTML = toHtml(message.text); },\n * onSubmit: (text) => send(text),\n * onCancel: () => stop(),\n * });\n * view.append({ role: 'user', text: 'Hello' });\n * view.beginStream({ role: 'assistant' });\n * view.appendChunk('Hi'); // re-renders ONLY the streaming message\n * view.endStream();\n *\n * MESSAGES are `{ id?, role, text, meta? }`. `id` is assigned when absent;\n * `role` becomes a modifier class (`twm-chat__msg--<role>`); `meta` is the\n * caller's and is handed back untouched. `append`, `replaceAll` and `clear`\n * change the list; `messages()` reads it. An id already in the transcript (or\n * repeated within one `replaceAll`) is refused with a throw, and a refused\n * call changes nothing. Each message has an EXTRA SLOT\n * (`slot(id)`), an element below the body the caller fills with whatever\n * belongs to that message \u2014 tool output, buttons, a diff \u2014 and which a\n * re-render of the body never touches.\n *\n * THE RENDER CALLBACK draws one body: `render(message, bodyEl, { streaming })`.\n * The body is emptied before every call. One that throws leaves the message\n * as its plain text (`twm-chat__body--plain`) and the view carries on; the\n * error goes to `onRenderError(error, message)` when given.\n *\n * STREAMING: `beginStream(message?)` appends a message marked streaming,\n * `appendChunk(text)` adds to its text and re-renders that message's body\n * alone, `endStream()` renders it a last time, unmarked. Nothing is deferred to\n * a frame: every call has drawn by the time it returns.\n *\n * PINNED TO THE BOTTOM: the view starts out following new content. Any\n * scroll UP \u2014 even a few px from the end, and whichever frame of a smooth\n * wheel or key scroll reports it \u2014 stops the following and shows *Jump to\n * latest*, and no later chunk moves the reader back. Following resumes only\n * on a scroll down (or a move that is not up) that ends within\n * `pinThreshold` px of the end, a click on *Jump to latest*,\n * `scrollToBottom()`, `replaceAll()` / `clear()`, or a `setScrollTop(px)`\n * that lands within the threshold. Content growing below a pinned view\n * never unpins it, nor does content shrinking under it (the browser clamps\n * `scrollTop` to the new end, which is not a move up). A wheel over\n * a nested scroller (a `<pre>` in a body, say) scrolls that, not the view;\n * nor does a wheel a handler inside the transcript cancelled, a Ctrl+wheel\n * (zoom, or a trackpad pinch), or a wheel up over a transcript already at its\n * top. `scrollTop` is\n * readable and settable (`getScrollTop` / `setScrollTop`) so an embedder can\n * keep it across a remount.\n *\n * THE COMPOSER is a textarea that grows with its text up to\n * `composerMaxHeight`. Enter submits (the trimmed-empty text is ignored) and\n * clears it; Shift+Enter is left to the browser, which inserts the newline\n * (native undo, `input` events). `setBusy(true)` turns Send into Cancel: Enter\n * then submits nothing, and Esc \u2014 wherever focus is inside the view \u2014 or a\n * click on Cancel calls `onCancel`, once per busy period, however often it is\n * pressed. That Esc stops there: it never reaches a window or panel around\n * the view that would close on Escape. An Esc a handler inside the view has\n * already consumed (`preventDefault`, say an inline popup or editor in the\n * transcript closing itself) is left alone: it neither cancels nor is stopped.\n *\n * `destroy()` removes the view. Every listener sits on an element the view\n * created, so they go with it; none is on the host or the document.\n */\n\n/** How near the end of the transcript still counts as \"at the bottom\". */\nexport const CONVERSATION_PIN_WITHIN_PX = 32;\n\n/**\n * A drop in `scrollTop` that still leaves the view this close to its end is\n * the browser clamping it after the content shrank (or sub-pixel rounding),\n * not the reader scrolling up.\n */\nconst AT_END_PX = 1;\n\n/** The tallest the composer grows before it scrolls instead. */\nexport const CONVERSATION_COMPOSER_MAX_PX = 200;\n\n/**\n * @param {HTMLElement} host\n * @param {object} [opts]\n * @param {Function} [opts.render] `(message, bodyEl, { streaming })` \u2014 draws a body; plain text without it\n * @param {Function} [opts.onSubmit] `(text)` \u2014 Enter or Send\n * @param {Function} [opts.onCancel] `()` \u2014 Esc or Cancel while busy\n * @param {Function} [opts.onRenderError] `(error, message)` \u2014 a render that threw\n * @param {number} [opts.pinThreshold] px from the end that still follows new content\n * @param {number} [opts.composerMaxHeight] px the composer grows to\n * @param {string} [opts.placeholder] the composer's placeholder\n * @param {object} [opts.labels] `{ send, cancel, jump, input }` \u2014 button and field texts\n * @returns {object} the view (see the methods below)\n */\nexport function mountConversationView(host, {\n render = null, onSubmit = null, onCancel = null, onRenderError = null,\n pinThreshold = CONVERSATION_PIN_WITHIN_PX, composerMaxHeight = CONVERSATION_COMPOSER_MAX_PX,\n placeholder = '', labels = {},\n} = {}) {\n const text = {\n send: 'Send', cancel: 'Cancel', jump: 'Jump to latest', input: 'Message', ...labels,\n };\n const doc = host.ownerDocument;\n const el = (tag, cls, content) => {\n const n = doc.createElement(tag);\n if (cls) n.className = cls;\n if (content !== undefined) n.textContent = content;\n return n;\n };\n const icon = (name) => {\n const i = el('span', 'material-symbols-outlined', name);\n i.setAttribute('aria-hidden', 'true');\n return i;\n };\n\n /** id \u2192 { message, row, body, extra } in transcript order. */\n const entries = new Map();\n let nextId = 1;\n let streamId = null;\n let pinned = true;\n let lastScrollTop = 0;\n let busy = false;\n let cancelled = false;\n let destroyed = false;\n\n // \u2500\u2500 the frame \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 const root = el('div', 'twm-chat');\n const viewport = el('div', 'twm-chat__viewport');\n const log = el('div', 'twm-chat__log');\n log.setAttribute('role', 'log');\n log.setAttribute('aria-live', 'polite');\n const jump = el('button', 'twm-chat__jump');\n jump.type = 'button';\n jump.append(icon('arrow_downward'), doc.createTextNode(` ${text.jump}`));\n jump.hidden = true;\n viewport.append(log, jump);\n\n const composer = el('div', 'twm-chat__composer');\n const input = el('textarea', 'twm-chat__input');\n input.rows = 1;\n input.placeholder = placeholder;\n input.setAttribute('aria-label', text.input);\n const send = el('button', 'twm-chat__send');\n send.type = 'button';\n composer.append(input, send);\n root.append(viewport, composer);\n host.append(root);\n\n // \u2500\u2500 scrolling \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 const distanceFromEnd = () => log.scrollHeight - log.scrollTop - log.clientHeight;\n const toBottom = () => {\n log.scrollTop = log.scrollHeight;\n lastScrollTop = log.scrollTop;\n };\n const setPinned = (value) => {\n pinned = value;\n jump.hidden = pinned;\n };\n /**\n * Reads the position the reader left: any move up stops following, however\n * near the end it stops (a smooth wheel or key scroll reports its first\n * frame only a few px up). Returns whether the move may follow again: it\n * was not up and ends within `pinThreshold` of the end. Shared by the\n * `scroll` event and by settle(), because a scrollbar drag, a key or a\n * touch moves `scrollTop` before its `scroll` event is dispatched, and a\n * change arriving in between must not snap the reader back.\n */\n function noticeMove() {\n const top = log.scrollTop;\n const distance = distanceFromEnd();\n const movedUp = top < lastScrollTop && distance > AT_END_PX;\n lastScrollTop = top;\n if (movedUp && pinned) setPinned(false);\n return !movedUp && distance <= pinThreshold;\n }\n /** After every change to the transcript: follow it, or leave the reader where they are. */\n const settle = () => {\n noticeMove();\n if (pinned) toBottom();\n };\n\n function onScroll() { if (noticeMove() && !pinned) setPinned(true); }\n /**\n * Whether a wheel up over `target` is kept by something nested inside the\n * transcript \u2014 a scrollable block in a body or an extra slot that is not\n * at its own top, or one at its top whose `overscroll-behavior` keeps the\n * scroll from chaining out \u2014 rather than moving the transcript itself.\n */\n function innerTakesWheelUp(target) {\n const view = doc.defaultView;\n for (let n = target; n && n !== log; n = n.parentElement) {\n if (n.nodeType !== 1 || n.scrollHeight <= n.clientHeight) continue;\n const style = view?.getComputedStyle(n);\n const overflow = style?.overflowY;\n if (overflow !== 'auto' && overflow !== 'scroll' && overflow !== 'overlay') continue;\n if (n.scrollTop > 0) return true;\n const chain = style.getPropertyValue('overscroll-behavior-y');\n if (chain === 'contain' || chain === 'none') return true;\n }\n return false;\n }\n /**\n * A wheel up that will move the transcript stops following at once, before\n * the scroll it causes is reported. One that a nested scroller keeps, or\n * one a handler inside the transcript cancelled (a zoomable chart in a\n * slot, say), leaves the transcript where it is, so it changes nothing.\n * Nor does a Ctrl+wheel (page zoom; a trackpad pinch arrives as one), or\n * a wheel up over a transcript already at its top, which cannot go up.\n */\n function onWheel(e) {\n if (e.deltaY < 0 && pinned && !e.ctrlKey && !e.defaultPrevented && log.scrollTop > 0\n && !innerTakesWheelUp(e.target)) setPinned(false);\n }\n function onJump() { setPinned(true); toBottom(); }\n log.addEventListener('scroll', onScroll);\n log.addEventListener('wheel', onWheel, { passive: true });\n jump.addEventListener('click', onJump);\n\n // \u2500\u2500 messages \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 fresh id, never one `taken` holds. */\n const newId = (taken = (id) => entries.has(id)) => {\n let id;\n do id = `m${nextId++}`; while (taken(id));\n return id;\n };\n const duplicate = (id) => new Error(`conversation view: duplicate message id \"${id}\"`);\n const roleClass = (role) => String(role ?? '').toLowerCase().replace(/[^a-z0-9-]+/g, '-') || 'none';\n const snapshot = (message) => ({ ...message });\n\n function drawBody(entry, streaming = entry.message.id === streamId) {\n const { message, body } = entry;\n body.replaceChildren();\n body.classList.remove('twm-chat__body--plain');\n if (render) {\n try {\n render(snapshot(message), body, { streaming });\n return;\n } catch (error) {\n body.replaceChildren();\n if (onRenderError) {\n try { onRenderError(error, snapshot(message)); } catch { /* the view keeps working */ }\n }\n }\n }\n body.classList.add('twm-chat__body--plain');\n body.textContent = message.text;\n }\n\n /**\n * One entry, drawn, and added to `into` (the transcript unless a\n * replaceAll is building its own). Throws on an id `into` already holds,\n * before anything is changed.\n */\n function build(spec, { into = entries, taken, streaming = false } = {}) {\n const message = {\n ...spec,\n id: spec?.id ?? newId(taken ?? ((id) => into.has(id))),\n role: spec?.role ?? 'assistant',\n text: String(spec?.text ?? ''),\n };\n if (into.has(message.id)) throw duplicate(message.id);\n const row = el('div', `twm-chat__msg twm-chat__msg--${roleClass(message.role)}`);\n if (streaming) row.classList.add('twm-chat__msg--streaming');\n const body = el('div', 'twm-chat__body');\n const extra = el('div', 'twm-chat__extra');\n row.append(body, extra);\n const entry = { message, row, body, extra };\n into.set(message.id, entry);\n drawBody(entry, streaming);\n return entry;\n }\n\n function append(message) {\n const entry = build(message);\n log.append(entry.row);\n settle();\n return entry.message.id;\n }\n\n /** All or nothing: a repeated id throws before the transcript is touched. No list (undefined or null) empties it. */\n function replaceAll(messages) {\n const list = [...(messages ?? [])];\n const given = new Set();\n for (const m of list) {\n if (m?.id == null) continue;\n if (given.has(m.id)) throw duplicate(m.id);\n given.add(m.id);\n }\n const next = new Map();\n const taken = (id) => given.has(id) || next.has(id);\n const frag = doc.createDocumentFragment();\n for (const m of list) frag.append(build(m, { into: next, taken }).row);\n streamId = null;\n entries.clear();\n for (const [id, entry] of next) entries.set(id, entry);\n log.replaceChildren(frag);\n setPinned(true);\n toBottom();\n }\n\n function clear() { replaceAll([]); }\n\n // \u2500\u2500 streaming \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 * Refused (a throw, nothing changed, an open stream left open) on an id\n * already present. No message (undefined or null) streams an empty\n * assistant message, as `append` treats them.\n */\n function beginStream(message) {\n if (message?.id != null && entries.has(message.id)) throw duplicate(message.id);\n if (streamId !== null) endStream();\n const entry = build({ role: 'assistant', text: '', ...(message ?? {}) }, { streaming: true });\n streamId = entry.message.id;\n log.append(entry.row);\n settle();\n return streamId;\n }\n\n function appendChunk(chunk) {\n const entry = streamId !== null ? entries.get(streamId) : null;\n if (!entry) return;\n entry.message.text += String(chunk ?? '');\n drawBody(entry);\n settle();\n }\n\n function endStream() {\n const entry = streamId !== null ? entries.get(streamId) : null;\n streamId = null;\n if (!entry) return null;\n entry.row.classList.remove('twm-chat__msg--streaming');\n drawBody(entry);\n settle();\n return entry.message.id;\n }\n\n // \u2500\u2500 the composer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 function grow() {\n input.style.height = 'auto';\n input.style.height = `${Math.min(input.scrollHeight, composerMaxHeight)}px`;\n input.style.overflowY = input.scrollHeight > composerMaxHeight ? 'auto' : 'hidden';\n }\n\n function drawSend() {\n send.replaceChildren(icon(busy ? 'stop' : 'send'));\n send.setAttribute('aria-label', busy ? text.cancel : text.send);\n send.title = busy ? text.cancel : text.send;\n send.classList.toggle('twm-chat__send--cancel', busy);\n root.classList.toggle('twm-chat--busy', busy);\n }\n\n function submit() {\n if (busy) return;\n const value = input.value;\n if (!value.trim()) return;\n input.value = '';\n grow();\n onSubmit?.(value);\n }\n\n function cancel() {\n if (!busy || cancelled) return;\n cancelled = true;\n onCancel?.();\n }\n\n /** Enter submits; Shift+Enter (and Ctrl/Meta/Alt+Enter) is the browser's to handle. */\n function onInputKey(e) {\n if (e.isComposing || e.key !== 'Enter') return;\n if (e.shiftKey || e.ctrlKey || e.metaKey || e.altKey) return;\n e.preventDefault();\n submit();\n }\n /**\n * Esc while busy cancels wherever focus is inside the view, and it is the\n * view's alone: it goes no further, so a window or panel holding the view\n * that closes on Escape stays open \u2014 on the cancelling Esc and on any\n * repeat in the same busy period. An Esc a handler inside the view\n * already consumed (defaultPrevented) is that handler's: it neither\n * cancels nor is stopped.\n */\n function onRootKey(e) {\n if (e.isComposing || e.key !== 'Escape' || !busy || e.defaultPrevented) return;\n e.preventDefault();\n e.stopPropagation();\n cancel();\n }\n input.addEventListener('keydown', onInputKey);\n input.addEventListener('input', grow);\n root.addEventListener('keydown', onRootKey);\n send.addEventListener('click', () => (busy ? cancel() : submit()));\n drawSend();\n\n return {\n root,\n append,\n replaceAll,\n clear,\n beginStream,\n appendChunk,\n endStream,\n /** A copy of every message, in order. */\n messages: () => [...entries.values()].map((e) => snapshot(e.message)),\n /** The extra slot below a message's body, or null for an unknown id. */\n slot: (id) => entries.get(id)?.extra ?? null,\n /** The id of the message being streamed, or null. */\n streamingId: () => streamId,\n isPinned: () => pinned,\n getScrollTop: () => log.scrollTop,\n /** Scrolls the transcript; pinned again only when that lands at the end. */\n setScrollTop(px) {\n log.scrollTop = px;\n lastScrollTop = log.scrollTop;\n setPinned(distanceFromEnd() <= pinThreshold);\n },\n scrollToBottom: onJump,\n /** `true` turns Send into Cancel; every busy period may cancel once. */\n setBusy(value) {\n if (busy === !!value) return;\n busy = !!value;\n cancelled = false;\n drawSend();\n },\n isBusy: () => busy,\n getText: () => input.value,\n setText(value) { input.value = String(value ?? ''); grow(); },\n focus: () => input.focus(),\n destroy() {\n if (destroyed) return;\n destroyed = true;\n streamId = null;\n busy = false;\n cancelled = false;\n entries.clear();\n root.remove();\n },\n };\n}\n", "/**\n * DetailHeader \u2014 shared header bar for detail views.\n *\n * Usage:\n * import { createDetailHeader, updateDetailHeader } from '../ui/components/detail_header.js';\n *\n * const header = createDetailHeader({\n * title: 'My Scenario',\n * badges: [{ text: 'Static' }],\n * renameable: true,\n * onRename: async (name) => ({ success: true }),\n * actions: [\n * { key: 'run', label: 'Run', icon: 'play_arrow', variant: 'primary', handler: () => {} },\n * { key: 'delete', label: 'Delete', icon: 'delete', variant: 'danger', handler: () => {} },\n * ],\n * });\n * container.appendChild(header);\n *\n * To update in place (e.g., running state changed):\n * updateDetailHeader(header, { ...newConfig });\n */\n\nimport { attachInlineRenamer } from './inline_renamer.js';\n\nconst ESC = (s) => String(s ?? '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n\n/**\n * @typedef {Object} DetailHeaderBadge\n * @property {string} text\n * @property {string} [className] - Extra class(es) of your own (e.g., 'my-badge--live'); the\n * pill itself is `.twm-detail-header__badge`\n * @property {string} [icon] - Material Symbols icon name\n */\n\n/**\n * @typedef {Object} DetailHeaderAction\n * @property {string} key - data-action value\n * @property {string} label - Button text\n * @property {string} [icon] - Material Symbols icon name (none: label only)\n * @property {'primary'|'secondary'|'danger'} [variant='secondary'] - The button is a `.twm-btn`;\n * 'primary' and 'danger' add `.twm-btn--primary` / `.twm-btn--danger`, and every\n * variant is also named `.twm-detail-header__btn--<variant>`\n * @property {boolean} [disabled=false]\n * @property {string} [title] - Tooltip\n * @property {Function} handler - Click callback\n */\n\n/**\n * @typedef {Object} DetailHeaderConfig\n * @property {string} title\n * @property {string} [subtitle]\n * @property {string} [icon] - Material icon before title\n * @property {DetailHeaderBadge[]} [badges]\n * @property {DetailHeaderAction[]} [actions]\n * @property {HTMLElement[]} [extraElements] - Custom elements appended to actions area\n * @property {boolean} [renameable=false]\n * @property {Function} [onRename] - (newName) => Promise<{success, newValue?}>\n */\n\n/**\n * Create a detail header element.\n * @param {DetailHeaderConfig} config\n * @returns {HTMLElement}\n */\nexport function createDetailHeader(config) {\n const header = document.createElement('header');\n header.className = 'twm-detail-header';\n _populate(header, config);\n return header;\n}\n\n/**\n * Update an existing detail header in place.\n * Destroys previous inline renamer and rebuilds inner DOM.\n * @param {HTMLElement} headerEl\n * @param {DetailHeaderConfig} config\n */\nexport function updateDetailHeader(headerEl, config) {\n // Destroy previous renamer if any\n headerEl._renamer?.destroy();\n headerEl._renamer = null;\n headerEl.innerHTML = '';\n _populate(headerEl, config);\n}\n\n// \u2500\u2500\u2500 Internal \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 _populate(header, config) {\n const { title, subtitle, icon, badges = [], actions = [], extraElements = [], renameable = false, onRename } = config;\n\n // Title row\n const titleRow = document.createElement('div');\n titleRow.className = 'twm-detail-header__title-row';\n\n if (icon) {\n const iconEl = document.createElement('span');\n iconEl.className = 'twm-detail-header__icon material-symbols-outlined';\n iconEl.textContent = icon;\n titleRow.appendChild(iconEl);\n }\n\n const nameEl = document.createElement('h2');\n nameEl.className = 'twm-detail-header__name';\n nameEl.textContent = title || '';\n if (renameable) {\n nameEl.dataset.renameable = '';\n nameEl.title = 'Double-click to rename';\n }\n titleRow.appendChild(nameEl);\n\n for (const badge of badges) {\n const badgeEl = document.createElement('span');\n badgeEl.className = `twm-detail-header__badge${badge.className ? ` ${badge.className}` : ''}`;\n if (badge.icon) {\n const bi = document.createElement('span');\n bi.className = 'twm-detail-header__badge-icon material-symbols-outlined';\n bi.textContent = badge.icon;\n badgeEl.appendChild(bi);\n }\n badgeEl.appendChild(document.createTextNode(badge.text));\n titleRow.appendChild(badgeEl);\n }\n\n header.appendChild(titleRow);\n\n // Subtitle\n if (subtitle) {\n const sub = document.createElement('div');\n sub.className = 'twm-detail-header__subtitle';\n sub.innerHTML = subtitle; // may contain <strong> etc.\n header.appendChild(sub);\n }\n\n // Actions\n if (actions.length > 0 || extraElements.length > 0) {\n const actionsEl = document.createElement('div');\n actionsEl.className = 'twm-detail-header__actions';\n\n for (const extra of extraElements) {\n actionsEl.appendChild(extra);\n }\n\n for (const action of actions) {\n const btn = document.createElement('button');\n btn.type = 'button';\n const variant = action.variant || 'secondary';\n // The shared `.twm-btn` look (BUG-0015): 'primary' and 'danger'\n // wear its colour variants; 'secondary' is the plain button.\n const look = variant === 'secondary' ? '' : ` twm-btn--${variant}`;\n btn.className = `twm-btn${look} twm-detail-header__btn twm-detail-header__btn--${variant}`;\n btn.dataset.action = action.key;\n if (action.disabled) btn.disabled = true;\n if (action.title) btn.title = action.title;\n\n if (action.icon) {\n const iconSpan = document.createElement('span');\n iconSpan.className = 'material-symbols-outlined twm-btn__glyph';\n iconSpan.textContent = action.icon;\n btn.appendChild(iconSpan);\n }\n const labelSpan = document.createElement('span');\n labelSpan.className = 'twm-btn__label';\n labelSpan.textContent = action.label ?? '';\n btn.appendChild(labelSpan);\n\n btn.addEventListener('click', () => action.handler?.());\n actionsEl.appendChild(btn);\n }\n\n header.appendChild(actionsEl);\n }\n\n // Inline rename\n if (renameable && onRename) {\n const renamer = attachInlineRenamer({\n label: nameEl,\n onCommit: async (newName) => {\n if (!newName?.trim()) return { success: false };\n return await onRename(newName.trim());\n },\n });\n nameEl.addEventListener('dblclick', (e) => {\n e.stopPropagation();\n renamer.start(e);\n });\n header._renamer = renamer;\n }\n}\n", "/**\n * fact_table.js \u2014 A SHEET OF FACTS: a name and its value, row after row, with\n * no header row, nothing truncated and no height to give it. (0.7.0)\n *\n * Server db-main-01.internal\n * Version 16.4\n * Connection postgresql://tables@db-main-01.internal:5432/tables_control\n * ?application_name=tables-api&sslmode=verify-full\n *\n * A DataTable is the wrong tool for this, for three reasons that are its\n * design rather than its defects: it draws a header row, it clips a cell to\n * one line (a long value becomes an ellipsis), and it fills a box with a\n * height (in a box without one it draws its header and no rows). A fact\n * sheet is the opposite on all three: the names are the header, every value\n * is read whole, and the sheet is exactly as tall as its rows.\n *\n * So this is a plain `<table class=\"twm-facts\">`:\n *\n * - the first column is the LABEL \u2014 muted, and kept on one line (pass\n * `wrapLabels: true` to let a long one wrap, `labelColumn: false` for a\n * sheet whose first column is ordinary data);\n * - every value WRAPS \u2014 at spaces, and inside a long word or URL when it must\n * (`overflow-wrap: anywhere`) \u2014 and keeps its own line breaks, so a\n * pretty-printed JSON value reads as one; `wrap: 'words'` wraps at spaces\n * only and keeps a long word whole (the sheet grows wider, for a sideways\n * scroller around it), and `wrap: 'none'` keeps only the value's own breaks;\n * - a value is text, a number or a NODE (a pill, a link, a button); an\n * object or array is drawn as indented JSON; `null` is an empty cell, or\n * `nullDisplay`;\n * - `mono` draws values in the monospace face, for the whole sheet or one row;\n * - `compare: true` gives each row a BEFORE and an AFTER, with an arrow\n * between: a row whose two sides differ is `--changed`, one that has only\n * an after is `--added`, only a before `--removed`, and the same on both\n * sides `--same`. A row with a plain `value` spans both sides;\n * - `headers` adds a header row after all, for the sheets that have several\n * columns of facts (a list of schemas, a list of pools); rows are then\n * arrays of cells, and `numeric` names the columns of figures.\n *\n * A row may be an OBJECT \u2014 `{label, value}` or `{label, before, after}`, with\n * `mono`, `numeric`, `labelTitle`, `key` and `status` \u2014 or an ARRAY of cells,\n * `[label, value, \u2026]`, which is the positional form a multi-column sheet uses.\n */\n\nlet SEQ = 0;\nconst isNode = (v) => typeof Node !== 'undefined' && v instanceof Node;\n\n/**\n * @typedef {Object} FactRow\n * @property {string|Node} label\n * @property {*} [value]\n * @property {*} [before] - With `compare`: the value before.\n * @property {*} [after] - With `compare`: the value after.\n * @property {boolean} [mono] - This row's values in the monospace face.\n * @property {boolean} [numeric] - This row's values in tabular numerals.\n * @property {string} [labelTitle] - A tooltip on the label.\n * @property {*} [key] - `data-key` on the row.\n * @property {'changed'|'same'|'added'|'removed'} [status] - With `compare`:\n * overrides the status worked out from the two sides.\n */\n\n/**\n * @typedef {Object} FactTableConfig\n * @property {Array<FactRow|Array>} [rows=[]]\n * @property {string[]|null} [headers=null] - A header row. Off by default.\n * @property {boolean} [compare=false] - A before and an after column.\n * @property {boolean} [labelColumn=true] - The first column is a label.\n * @property {boolean} [wrapLabels=false] - Let a long label wrap.\n * @property {'anywhere'|'words'|'none'} [wrap='anywhere'] - How a value wraps:\n * at spaces and inside a long word when it must (the default), at spaces\n * only (`'words'`: a long word stays whole and the sheet grows wider \u2014 for a\n * sheet inside a sideways scroller), or not at all beyond its own line\n * breaks (`'none'`).\n * @property {boolean} [mono=false] - Every value in the monospace face.\n * @property {number[]} [numeric=[]] - Column indices drawn in tabular numerals.\n * @property {string} [nullDisplay=''] - What `null`/`undefined` reads as.\n * @property {string} [missing='\u2014'] - With `compare`: an absent side.\n * @property {Function} [rowClass] - `(row, idx) => string|string[]|null`.\n * @property {Function} [rowAttrs] - `(row, idx) => {name: value}`.\n * @property {string|Node|Function} [emptyState] - Shown when there are no rows.\n * @property {string} [label] - The table's accessible name (`aria-label`).\n * @property {string} [className] - Added to the `<table>`.\n */\n\nexport class FactTable {\n /**\n * @param {HTMLElement|null} host appended to, if given\n * @param {FactTableConfig} [config]\n */\n constructor(host, config = {}) {\n this.config = {\n rows: [],\n headers: null,\n compare: false,\n labelColumn: true,\n wrapLabels: false,\n wrap: 'anywhere',\n mono: false,\n numeric: [],\n nullDisplay: '',\n missing: '\u2014',\n rowClass: null,\n rowAttrs: null,\n emptyState: null,\n label: null,\n className: null,\n ...config,\n };\n this._rows = Array.isArray(this.config.rows) ? this.config.rows.slice() : [];\n this._id = ++SEQ;\n const table = document.createElement('table');\n table.className = 'twm-facts'\n + (this.config.compare ? ' twm-facts--compare' : '')\n + (this.config.labelColumn ? '' : ' twm-facts--no-label')\n + (this.config.wrapLabels ? ' twm-facts--wrap-labels' : '')\n + (this.config.wrap === 'words' ? ' twm-facts--wrap-words'\n : this.config.wrap === 'none' ? ' twm-facts--wrap-none' : '')\n + (this.config.mono ? ' twm-facts--mono' : '')\n + (this.config.className ? ` ${this.config.className}` : '');\n if (this.config.label) table.setAttribute('aria-label', this.config.label);\n this.element = table;\n this._draw();\n if (host) host.appendChild(table);\n }\n\n /** Replace the rows and draw them. */\n setRows(rows) {\n this._rows = Array.isArray(rows) ? rows.slice() : [];\n this._draw();\n }\n\n getRows() {\n return this._rows.slice();\n }\n\n /** The `<tr>` drawn for row `idx`, or null. */\n getRow(idx) {\n return this.element.tBodies[0]?.rows[idx]?.__factIndex === idx\n ? this.element.tBodies[0].rows[idx] : null;\n }\n\n dispose() {\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 /** How many columns the sheet has. */\n _width() {\n const { compare, headers } = this.config;\n if (compare) return 4;\n let n = 2;\n if (Array.isArray(headers)) n = Math.max(n, headers.length);\n for (const r of this._rows) if (Array.isArray(r)) n = Math.max(n, r.length);\n return n;\n }\n\n _draw() {\n const table = this.element;\n table.replaceChildren();\n const width = this._width();\n const { headers, compare } = this.config;\n\n if (Array.isArray(headers) && headers.length) {\n const thead = document.createElement('thead');\n const tr = document.createElement('tr');\n // With `compare`, three names stand over label, before and after;\n // the arrow column gets an empty one.\n const names = compare && headers.length === 3\n ? [headers[0], headers[1], '', headers[2]] : headers;\n for (let i = 0; i < width; i++) {\n const th = document.createElement('th');\n th.scope = 'col';\n appendContent(th, names[i] ?? '');\n if (this._numeric(i)) th.classList.add('twm-facts__num');\n tr.appendChild(th);\n }\n thead.appendChild(tr);\n table.appendChild(thead);\n }\n\n const tbody = document.createElement('tbody');\n this._rows.forEach((row, idx) => tbody.appendChild(this._row(row, idx, width)));\n if (!this._rows.length) {\n let content = this.config.emptyState;\n if (typeof content === 'function') content = content();\n if (content != null && content !== false && content !== '') {\n const tr = document.createElement('tr');\n tr.className = 'twm-facts__empty-row';\n const td = document.createElement('td');\n td.className = 'twm-facts__empty';\n td.colSpan = width;\n appendContent(td, content);\n tr.appendChild(td);\n tbody.appendChild(tr);\n }\n }\n table.classList.toggle('twm-facts--empty', this._rows.length === 0);\n table.appendChild(tbody);\n }\n\n _numeric(col) {\n const n = this.config.numeric;\n return Array.isArray(n) && n.includes(col);\n }\n\n _row(row, idx, width) {\n const tr = document.createElement('tr');\n tr.className = 'twm-facts__row';\n tr.__factIndex = idx;\n tr.__fact = row;\n if (Array.isArray(row)) {\n for (let i = 0; i < width; i++) {\n const td = this._cell(i === 0 && this.config.labelColumn ? 'label' : 'value', row[i]);\n if (this._numeric(i)) td.classList.add('twm-facts__num');\n if (i === row.length - 1 && row.length < width) {\n td.colSpan = width - i;\n tr.appendChild(td);\n break;\n }\n tr.appendChild(td);\n }\n } else {\n const r = row && typeof row === 'object' ? row : { label: row };\n if (r.key !== undefined && r.key !== null) tr.dataset.key = String(r.key);\n const label = this._cell(this.config.labelColumn ? 'label' : 'value', r.label);\n if (r.labelTitle) label.title = String(r.labelTitle);\n tr.appendChild(label);\n const tune = (td) => {\n if (r.mono) td.classList.add('twm-facts__mono');\n if (r.numeric) td.classList.add('twm-facts__num');\n return td;\n };\n const hasBefore = Object.prototype.hasOwnProperty.call(r, 'before');\n const hasAfter = Object.prototype.hasOwnProperty.call(r, 'after');\n if (this.config.compare && (hasBefore || hasAfter)) {\n const status = r.status || statusOf(r, hasBefore, hasAfter);\n tr.classList.add(`twm-facts__row--${String(status).replace(/[^\\w-]/g, '')}`);\n tr.dataset.status = String(status);\n const before = tune(hasBefore ? this._cell('value', r.before) : this._missing());\n before.classList.add('twm-facts__before');\n const arrow = document.createElement('td');\n arrow.className = 'twm-facts__arrow';\n arrow.setAttribute('aria-hidden', 'true');\n arrow.textContent = '\u2192';\n const after = tune(hasAfter ? this._cell('value', r.after) : this._missing());\n after.classList.add('twm-facts__after');\n tr.append(before, arrow, after);\n } else {\n const value = tune(this._cell('value', r.value));\n if (width > 2) value.colSpan = width - 1;\n tr.appendChild(value);\n }\n }\n this._decorate(tr, row, idx);\n return tr;\n }\n\n _cell(kind, content) {\n const isLabel = kind === 'label';\n const td = document.createElement(isLabel ? 'th' : 'td');\n td.className = isLabel ? 'twm-facts__label' : 'twm-facts__value';\n if (isLabel) td.scope = 'row';\n if (content === null || content === undefined) {\n const said = isLabel ? '' : this.config.nullDisplay;\n if (said) {\n td.textContent = String(said);\n td.classList.add('twm-facts__null');\n }\n } else {\n appendContent(td, content);\n }\n return td;\n }\n\n _missing() {\n const td = document.createElement('td');\n td.className = 'twm-facts__value twm-facts__missing';\n td.textContent = String(this.config.missing ?? '');\n return td;\n }\n\n _decorate(tr, row, idx) {\n const { rowClass, rowAttrs } = this.config;\n if (typeof rowClass === 'function') {\n const c = rowClass(row, idx);\n const list = Array.isArray(c) ? c : String(c ?? '').split(/\\s+/);\n for (const name of list) if (name) tr.classList.add(String(name));\n }\n if (typeof rowAttrs === 'function') {\n for (const [name, value] of Object.entries(rowAttrs(row, idx) || {})) {\n if (value == null || value === false) continue;\n try {\n tr.setAttribute(name, value === true ? '' : String(value));\n } catch (err) {\n console.error(`[FactTable] rowAttrs: bad attribute \"${name}\"`, err);\n }\n }\n }\n }\n}\n\n/**\n * Build a fact sheet, append it to `host` (if given) and draw it.\n *\n * @param {HTMLElement|null} host\n * @param {FactTableConfig} [config]\n * @returns {FactTable}\n */\nexport function createFactTable(host, config = {}) {\n return new FactTable(host, config);\n}\n\n/** What a before/after row says, from its two sides. Nodes cannot be\n * compared, so a row that has one is `changed` unless it says otherwise;\n * objects compare by their JSON. */\nfunction statusOf(r, hasBefore, hasAfter) {\n if (!hasBefore) return 'added';\n if (!hasAfter) return 'removed';\n if (isNode(r.before) || isNode(r.after)) return 'changed';\n if (Object.is(r.before, r.after)) return 'same';\n if (r.before && r.after && typeof r.before === 'object' && typeof r.after === 'object') {\n try {\n return JSON.stringify(r.before) === JSON.stringify(r.after) ? 'same' : 'changed';\n } catch {\n return 'changed';\n }\n }\n return 'changed';\n}\n\n/** Text, a number, a node, or an object (drawn as indented JSON) into `el`. */\nfunction appendContent(el, content) {\n if (content === null || content === undefined) return;\n if (isNode(content)) { el.appendChild(content); return; }\n let text;\n if (typeof content === 'object') {\n try { text = JSON.stringify(content, null, 2); } catch { text = String(content); }\n } else {\n text = String(content);\n }\n el.appendChild(document.createTextNode(text));\n}\n", "/**\n * gallery_picker.js \u2014 single-select card grid for the starter catalog.\n *\n * G1.3 in docs/STARTER_GALLERY_REQUIREMENTS.md. Used by every\n * \"New X\" modal to let the user pick a starter shape (formerly\n * called a \"template\"). The picker is mounted into a host element\n * and fires `onChange(entry)` whenever the selection changes.\n *\n * The entries come from `opts.entries`, or else from the host's optional\n * `gallery` capability (`host.gallery.list(kind)`, see host.js). Each entry is\n *\n * { id, kind, label, description, fields }\n *\n * The picker shows label + description as a card. `fields` is\n * passed through to the caller untouched on select \u2014 the New-X\n * handler decides what to do with it.\n *\n * Usage:\n *\n * const picker = await mountGalleryPicker(hostEl, {\n * host, // or entries: [...]\n * kind: 'agent',\n * selectedId: 'blank',\n * onChange: (entry) => { \u2026 },\n * });\n *\n * // later \u2026\n * picker.getSelected(); // \u2192 { id, kind, label, description, fields }\n * picker.dispose();\n */\n\nfunction esc(s) {\n return String(s ?? '').replace(/[&<>\"']/g, (c) => ({\n '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;',\n }[c]));\n}\n\n\n/**\n * Mount a starter-gallery picker into `hostEl`.\n *\n * @param {HTMLElement} hostEl\n * @param {object} opts\n * @param {string} opts.kind \u2014 gallery entries to load (e.g. 'agent').\n * When undefined, every kind shows up.\n * @param {string} [opts.selectedId] \u2014 id to pre-select. If absent, the\n * first entry wins.\n * @param {function} [opts.onChange] \u2014 `(entry) => void` fired on selection\n * change AND on initial mount.\n * @param {object[]} [opts.entries] \u2014 explicit entries (the host is not asked).\n * @param {object} [opts.host] \u2014 a Host; its `gallery.list(kind)` supplies\n * the entries when `entries` is absent.\n * With neither, the picker shows\n * `emptyLabel` and warns once.\n * @param {string} [opts.emptyLabel] \u2014 copy shown when the catalog is empty\n * for that kind.\n * @returns {Promise<{getSelected, setSelectedById, dispose}>}\n */\nexport async function mountGalleryPicker(hostEl, opts = {}) {\n const {\n kind = null,\n selectedId = null,\n onChange = () => {},\n entries = null,\n host = null,\n emptyLabel = 'No starters available for this kind.',\n } = opts;\n if (!hostEl) throw new Error('mountGalleryPicker: hostEl is required');\n\n let catalog = entries;\n if (!catalog) {\n const list = host?.gallery?.list;\n if (typeof list !== 'function') {\n console.warn('[gallery-picker] no entries and no host gallery capability; showing the empty label');\n catalog = [];\n } else {\n try {\n catalog = (await list(kind)) || [];\n } catch (err) {\n console.warn('[gallery-picker] host.gallery.list failed', err);\n catalog = [];\n }\n }\n }\n catalog = Array.isArray(catalog) ? catalog : [];\n\n hostEl.classList.add('twm-gallery-picker');\n if (catalog.length === 0) {\n hostEl.innerHTML = `<div class=\"twm-gallery-picker__empty\">${esc(emptyLabel)}</div>`;\n return {\n getSelected: () => null,\n setSelectedById: () => false,\n dispose: () => { hostEl.classList.remove('twm-gallery-picker'); },\n };\n }\n\n let selected = catalog.find((e) => e?.id === selectedId)\n || catalog[0];\n\n const render = () => {\n hostEl.innerHTML = catalog.map((e, i) => {\n const isSel = e === selected;\n const desc = e?.description\n ? `<p class=\"twm-gallery-card__desc\">${esc(e.description)}</p>`\n : '';\n return `\n <button type=\"button\"\n class=\"twm-gallery-card ${isSel ? 'is-selected' : ''}\"\n data-idx=\"${i}\"\n title=\"${esc(e?.id || '')}\">\n <span class=\"twm-gallery-card__label\">${esc(e?.label || e?.id || '')}</span>\n ${desc}\n </button>\n `;\n }).join('');\n };\n render();\n\n const onClick = (ev) => {\n const card = ev.target.closest?.('.twm-gallery-card');\n if (!card || !hostEl.contains(card)) return;\n const idx = Number(card.dataset.idx);\n const next = catalog[idx];\n if (!next || next === selected) return;\n selected = next;\n render();\n try { onChange(selected); } catch (err) {\n console.warn('[gallery-picker] onChange threw', err);\n }\n };\n hostEl.addEventListener('click', onClick);\n\n // Fire the initial selection so the caller can prime any\n // downstream UI (preview pane, defaults, etc.) without a\n // special case for first-render.\n try { onChange(selected); } catch (err) {\n console.warn('[gallery-picker] initial onChange threw', err);\n }\n\n return {\n getSelected: () => (selected ? { ...selected } : null),\n setSelectedById: (id) => {\n const next = catalog.find((e) => e?.id === id);\n if (!next || next === selected) return false;\n selected = next;\n render();\n try { onChange(selected); } catch (err) {\n console.warn('[gallery-picker] onChange threw', err);\n }\n return true;\n },\n dispose: () => {\n hostEl.removeEventListener('click', onClick);\n hostEl.innerHTML = '';\n hostEl.classList.remove('twm-gallery-picker');\n },\n };\n}\n", "/**\n * NotificationHistory - Bottom bar notification history panel\n *\n * Bell icon in the global-bottom-bar that opens a popover listing past notifications.\n * Reads from NotificationCenter.history (no modifications to NotificationCenter needed).\n * Tracks unread count via lastSeenCount delta and updates a badge on the bell icon.\n *\n * THREE OPTIONS, all additive (FlexDesk STORY-0020); without them it is the bell\n * it always was:\n *\n * mountPoint the element the bell is appended to. Without it, the hard-coded\n * `.twm-global-bottom-bar .twm-bar-right`, which only FlexDesk's own\n * bottom bar has.\n * alertLog an alert log (`alert_log.js`). The badge is then the log's unread\n * count, in the worst unread level's colour, and nothing when all is\n * read \u2014 not a delta of a toast history the user may never have\n * opened. A click opens the bottom panel's Alerts tab instead of the\n * popover, and the toasts' \"+N more\" (`notification:summary`) does too.\n * alertsTab the tab a click asks for, `bottompanel:show { tab }`; 'alerts'.\n * onOpen a click, instead of the bus event \u2014 for an embedder with no bus,\n * or whose panel must be opened before a tab can be chosen.\n */\n\nexport class NotificationHistory {\n constructor({ notificationCenter, eventBus, logger, mountPoint = null, alertLog = null,\n alertsTab = 'alerts', onOpen = null } = {}) {\n this.notificationCenter = notificationCenter;\n this.eventBus = eventBus || null;\n this.logger = logger || console;\n this.mountPoint = mountPoint;\n this.alertLog = alertLog;\n this.alertsTab = alertsTab;\n this.onOpen = typeof onOpen === 'function' ? onOpen : null;\n\n this.triggerEl = null;\n this.badgeEl = null;\n this.lastSeenCount = 0;\n this._popoverCleanup = null;\n this._subscriptions = [];\n }\n\n mount() {\n const barRight = this.mountPoint\n || document.querySelector('.twm-global-bottom-bar .twm-bar-right');\n if (!barRight) {\n this.logger.warn?.('[NotificationHistory] .bar-right not found');\n return;\n }\n\n // Build trigger button\n this.triggerEl = document.createElement('button');\n this.triggerEl.className = 'twm-notification-history__trigger twm-has-tooltip';\n this.triggerEl.setAttribute('data-tooltip', 'Notification history');\n this.triggerEl.setAttribute('aria-label', 'Notification history');\n this.triggerEl.innerHTML =\n '<span class=\"material-symbols-outlined\">notifications</span>' +\n '<span class=\"twm-notification-history__badge\" style=\"display:none\">0</span>';\n\n this.badgeEl = this.triggerEl.querySelector('.twm-notification-history__badge');\n\n // Park the bell as the LAST child of .bar-right so it always\n // sits at the far-right edge of the status bar \u2014 past the\n // tick readout, streaming dot, and anything else that the\n // global actions cluster mounts before it.\n barRight.appendChild(this.triggerEl);\n\n this.triggerEl.addEventListener('click', (e) => {\n e.stopPropagation();\n if (this.alertLog) this.#openAlerts();\n else this.#togglePanel();\n });\n\n if (this.alertLog) {\n this.triggerEl.setAttribute('data-tooltip', 'Alerts');\n this.triggerEl.setAttribute('aria-label', 'Alerts');\n this._subscriptions.push(this.alertLog.subscribe(() => this.#updateBadge()));\n const summary = this.eventBus?.on?.('notification:summary', () => this.#openAlerts());\n if (summary) this._subscriptions.push(() => summary.dispose?.());\n this.#updateBadge();\n return;\n }\n\n // Sync initial count so existing history doesn't show as unread\n this.lastSeenCount = this.notificationCenter?.history?.length ?? 0;\n\n this.#subscribeEvents();\n }\n\n unmount() {\n this.#closePanel();\n this._subscriptions.forEach(unsub => {\n if (typeof unsub === 'function') unsub();\n });\n this._subscriptions = [];\n if (this.triggerEl?.parentNode) {\n this.triggerEl.parentNode.removeChild(this.triggerEl);\n }\n this.triggerEl = null;\n this.badgeEl = null;\n }\n\n #subscribeEvents() {\n if (!this.eventBus) return;\n\n // Update badge whenever a new notification comes in\n const badgeUpdate = () => queueMicrotask(() => this.#updateBadge());\n const events = ['toast:show', 'notification:show', 'log:entry',\n 'workspace:save:failed', 'workspace:import:failed'];\n\n events.forEach(name => {\n const handle = this.eventBus.on(name, badgeUpdate);\n this._subscriptions.push(() => handle?.dispose?.());\n });\n }\n\n /** The Alerts tab, asked for on the bus \u2014 or the embedder's own verb. */\n #openAlerts() {\n if (this.onOpen) {\n try { this.onOpen(); } catch (err) { this.logger.warn?.('[NotificationHistory] onOpen failed', err); }\n return;\n }\n this.eventBus?.emit?.('bottompanel:show', { tab: this.alertsTab });\n }\n\n #updateBadge() {\n const historyLen = this.notificationCenter?.history?.length ?? 0;\n const unread = this.alertLog\n ? this.alertLog.unreadCount()\n : Math.max(0, historyLen - this.lastSeenCount);\n\n if (!this.badgeEl) return;\n\n if (this.alertLog) {\n const level = unread > 0 ? this.alertLog.worstUnread() : null;\n this.badgeEl.className = 'twm-notification-history__badge'\n + (level ? ` twm-notification-history__badge--${level}` : '');\n this.triggerEl?.classList.toggle('twm-notification-history__trigger--unread', unread > 0);\n }\n\n if (unread > 0) {\n this.badgeEl.textContent = unread > 99 ? '99+' : String(unread);\n this.badgeEl.style.display = '';\n } else {\n this.badgeEl.style.display = 'none';\n }\n }\n\n #togglePanel() {\n if (this._popoverCleanup) {\n this.#closePanel();\n } else {\n this.#openPanel();\n }\n }\n\n #closePanel() {\n if (typeof this._popoverCleanup === 'function') {\n try { this._popoverCleanup(); } catch (_) { /* ignore */ }\n this._popoverCleanup = null;\n }\n }\n\n #openPanel() {\n this.#closePanel();\n\n // Mark all as seen\n this.lastSeenCount = this.notificationCenter?.history?.length ?? 0;\n this.#updateBadge();\n\n const panel = document.createElement('div');\n panel.className = 'twm-notification-history__panel';\n\n // Header\n const header = document.createElement('div');\n header.className = 'twm-notification-history__header';\n header.innerHTML =\n '<span class=\"twm-notification-history__title\">Notifications</span>' +\n '<button class=\"twm-notification-history__clear-btn twm-has-tooltip\" data-tooltip=\"Clear all\" aria-label=\"Clear all\">' +\n '<span class=\"material-symbols-outlined\">delete_sweep</span>' +\n '</button>' +\n '<button class=\"twm-notification-history__close-btn twm-has-tooltip\" data-tooltip=\"Close\" aria-label=\"Close\">' +\n '<span class=\"material-symbols-outlined\">close</span>' +\n '</button>';\n panel.appendChild(header);\n\n // List\n const list = document.createElement('div');\n list.className = 'twm-notification-history__list';\n panel.appendChild(list);\n\n this.#renderList(list);\n\n // Wire header buttons\n header.querySelector('.twm-notification-history__close-btn')\n .addEventListener('click', () => this.#closePanel());\n\n header.querySelector('.twm-notification-history__clear-btn')\n .addEventListener('click', () => {\n this.notificationCenter.history.splice(0);\n this.lastSeenCount = 0;\n this.#updateBadge();\n this.#renderList(list);\n });\n\n // Position and attach\n document.body.appendChild(panel);\n this.#positionPanel(panel);\n\n // Popover lifecycle (same pattern as ValidationStatus)\n const cleanup = () => {\n document.removeEventListener('mousedown', onDocDown, true);\n document.removeEventListener('keydown', onKey, true);\n window.removeEventListener('resize', onResize, true);\n try { panel.remove(); } catch (_) { /* ignore */ }\n this._popoverCleanup = null;\n };\n this._popoverCleanup = cleanup;\n\n const onDocDown = (ev) => {\n if (!panel.contains(ev.target) && !this.triggerEl.contains(ev.target)) cleanup();\n };\n const onKey = (ev) => { if (ev.key === 'Escape') cleanup(); };\n const onResize = () => cleanup();\n\n document.addEventListener('mousedown', onDocDown, true);\n document.addEventListener('keydown', onKey, true);\n window.addEventListener('resize', onResize, true);\n }\n\n #renderList(listEl) {\n listEl.innerHTML = '';\n const history = this.notificationCenter?.history ?? [];\n\n if (history.length === 0) {\n const empty = document.createElement('div');\n empty.className = 'twm-notification-history__empty';\n empty.textContent = 'No notifications';\n listEl.appendChild(empty);\n return;\n }\n\n // Reverse chronological\n const fragment = document.createDocumentFragment();\n for (let i = history.length - 1; i >= 0; i--) {\n const entry = history[i];\n const item = document.createElement('div');\n const severity = entry.severity || 'info';\n item.className = `twm-notification-history__item twm-notification-history__item--${severity}`;\n\n const itemHeader = document.createElement('div');\n itemHeader.className = 'twm-notification-history__item-header';\n\n if (entry.title) {\n const titleEl = document.createElement('span');\n titleEl.className = 'twm-notification-history__item-title';\n titleEl.textContent = entry.title;\n itemHeader.appendChild(titleEl);\n }\n\n const timeEl = document.createElement('span');\n timeEl.className = 'twm-notification-history__item-time';\n timeEl.textContent = this.#formatTime(entry.timestamp);\n itemHeader.appendChild(timeEl);\n\n item.appendChild(itemHeader);\n\n const body = document.createElement('div');\n body.className = 'twm-notification-history__item-body';\n body.textContent = entry.message || '';\n item.appendChild(body);\n\n fragment.appendChild(item);\n }\n listEl.appendChild(fragment);\n }\n\n #positionPanel(panel) {\n if (!this.triggerEl) return;\n\n const triggerRect = this.triggerEl.getBoundingClientRect();\n const panelWidth = panel.getBoundingClientRect().width;\n const gap = 8;\n\n let left = triggerRect.right - panelWidth;\n\n // Clamp horizontally to the viewport.\n const vw = window.innerWidth;\n left = Math.max(8, Math.min(left, vw - panelWidth - 8));\n\n // Anchor by the panel's BOTTOM edge, pinned just above the bell.\n // Anchoring by `top` leaves the box floating when its content shrinks\n // (notifications cleared/removed): the top stays put while the bottom\n // lifts away from the bell, stranding the panel in mid-air. Pinning\n // the bottom keeps it glued to the bottom bar and lets it grow/shrink\n // upward \u2014 no repositioning needed on re-render.\n const bottom = window.innerHeight - (triggerRect.top - gap);\n\n // Never let the panel run off the top of the viewport: cap its height\n // to the space above the bell (within the design max). The list\n // scrolls within whatever remains.\n const available = triggerRect.top - gap - 8;\n panel.style.maxHeight = `${Math.max(0, Math.min(420, Math.round(available)))}px`;\n\n panel.style.left = `${Math.round(left)}px`;\n panel.style.bottom = `${Math.round(bottom)}px`;\n panel.style.top = 'auto';\n }\n\n #formatTime(timestamp) {\n if (!timestamp) return '';\n const d = new Date(timestamp);\n return d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' });\n }\n}\n", "/**\n * record_list.js \u2014 A READ-ONLY LIST OF RECORDS, each drawn as two lines: a\n * name, and under it a quiet line of facts; beside them pills and verbs.\n * (0.7.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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 ETL loader [paused] Resume Revoke \u2502\n * \u2502 tblk_8f2 \u2014 acts with the account \u2014 last used 5 Oct \u2502\n * \u2502 Resume: This key is revoked, and revoking cannot be undone. \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 * It is the shape an administration screen reaches for when a table would\n * be wrong: few records, each with its own verbs, read top to bottom rather\n * than sorted and filtered. Before this component every consumer built it by\n * hand, row by row, and each copy grew its own post-build loop to put a key\n * or a state on the row afterwards. Here the record's key, its classes and\n * its attributes are declared, and the list owns the rest.\n *\n * WHAT A RECORD SAYS ABOUT ITSELF (`describe(record, idx)`, or the record\n * itself when there is no `describe`):\n *\n * {\n * name: 'ETL loader' | Node, the first line\n * mono: true, the name in the monospace face\n * facts: ['tblk_8f2', null, 'last used 5 Oct'] | 'text' | Node,\n * the quiet line; null/'' parts\n * are left out, the rest joined\n * with `factSeparator`\n * pills: ['paused', {text: 'URL', tone: 'danger', title: '\u2026'}],\n * verbs: [{label: 'Resume', onClick(record, ev), refusal: '\u2026' | null,\n * danger, primary, icon, title, name}],\n * state: 'paused' | 'off' | 'dead' | 'error' | 'active' | any word \u2014\n * `data-state` and `twm-record--state-<word>` on the row,\n * error: 'The last delivery failed: 503' | Node, a line in the error colour\n * key: 'k-1', overrides `getKey`\n * }\n *\n * A REFUSED VERB IS A DISABLED BUTTON AND A SENTENCE ON THE SCREEN. The\n * reason is on the button's `title` and `data-refusal` too, but a reason only\n * on a tooltip reads as \"the button does nothing\" \u2014 nobody hovers a button\n * they believe they have just pressed. So each distinct reason is a line of\n * its own under the facts, named by the verbs it refuses\n * (`data-refusal-for`), and the button is `aria-describedby` that line.\n *\n * OPENING A RECORD (`onActivate`) follows DataTable's `onRowActivate` rule,\n * from the same module (`row_activation.js`): a press on a control in the\n * row is that control's, a click that ends a drag selecting text opens\n * nothing, and neither does the second click of a double-click.\n *\n * THE KEYBOARD. With `onActivate` (or `keyboard: true`) the RECORDS are one\n * tab stop \u2014 the one last focused, else the open one, else the first \u2014 and\n * each enabled verb keeps its own, so every verb is reachable by Tab.\n * ArrowUp/ArrowDown move between records (from a record or from one of its\n * verbs), Home/End go to the ends, and Enter on a record opens it. Enter on a\n * verb is the verb's.\n */\nimport { isRowActivation, isRowControl } from './row_activation.js';\n\n/** A field, a select or editable text keeps its own arrow keys. */\nconst OWN_ARROWS = 'input, select, textarea, [contenteditable=\"\"], [contenteditable=\"true\"]';\n\n/** The words a tone may be, after sanitising (`[^\\w-]` dropped). */\nconst safeWord = (s) => String(s).replace(/[^\\w-]/g, '');\n\nlet SEQ = 0;\n\n/**\n * @typedef {Object} RecordVerb\n * @property {string} label - The button's words.\n * @property {Function} [onClick] - `(record, ev) => void`.\n * @property {string|null} [refusal] - Why it cannot be pressed. A disabled\n * button, and the sentence drawn under the record's facts.\n * @property {boolean} [danger]\n * @property {boolean} [primary]\n * @property {string} [icon] - A Material Symbols name, drawn before the label.\n * @property {string} [title] - A tooltip, for a verb that is NOT refused.\n * @property {string} [name] - A stable id: `data-verb`, and what focus is\n * restored to after a redraw. Defaults to the label.\n */\n\n/**\n * @typedef {Object} RecordListConfig\n * @property {Array} [records=[]]\n * @property {Function} [describe] - `(record, idx) => spec`. Without it the\n * record is its own spec.\n * @property {Function} [getKey] - `(record, idx) => string|number`. Defaults to\n * `spec.key`, then `record.key`, then `record.id`, then the index.\n * @property {Function} [onActivate] - `(record, idx, ev) => void`. Opens a record.\n * @property {string|string[]} [activateOn=['click','enter']] - `'click'`,\n * `'dblclick'`, `'enter'`, or several.\n * @property {boolean} [keyboard] - Arrow keys between records. Defaults to on\n * exactly when `onActivate` is set.\n * @property {*} [activeKey] - The record that is open: `twm-record--active`\n * and `aria-current=\"true\"`.\n * @property {Function} [rowClass] - `(record, idx) => string|string[]|null`.\n * @property {Function} [rowAttrs] - `(record, idx) => {name: value}`;\n * `null`/`false` leaves one off, `true` sets it empty.\n * @property {string|Node|Function} [emptyState] - Shown when there are no\n * records. A function is called with no arguments and may return either.\n * @property {string} [factSeparator=' \u2014 ']\n * @property {'wrap'|'ellipsis'} [facts='wrap'] - How a long fact line ends.\n * `'ellipsis'` keeps it to one line and puts the whole line on `title`.\n * @property {string|Function} [verbClass] - The verbs' class names, or\n * `(verb) => string`, for a consumer with its own buttons. Defaults to\n * FlexDesk's `twm-btn` with `--primary`/`--danger`.\n * @property {string} [label] - The list's accessible name (`aria-label`).\n * @property {string} [className] - Added to the root.\n */\n\nexport class RecordList {\n /**\n * @param {HTMLElement|null} host appended to, if given\n * @param {RecordListConfig} [config]\n */\n constructor(host, config = {}) {\n this.config = {\n records: [],\n describe: null,\n getKey: null,\n onActivate: null,\n activateOn: ['click', 'enter'],\n keyboard: undefined,\n activeKey: null,\n rowClass: null,\n rowAttrs: null,\n emptyState: null,\n factSeparator: ' \u2014 ',\n facts: 'wrap',\n verbClass: null,\n label: null,\n className: null,\n ...config,\n };\n this._records = Array.isArray(this.config.records) ? this.config.records.slice() : [];\n this._activeKey = this.config.activeKey ?? null;\n this._tabKey = null;\n this._items = new Map(); // key \u2192 <li>\n this._disposed = false;\n this._id = `twm-record-list-${++SEQ}`;\n\n const root = document.createElement('div');\n root.className = 'twm-record-list'\n + (this.config.facts === 'ellipsis' ? ' twm-record-list--clip' : '')\n + (this._activates() ? ' twm-record-list--clickable' : '')\n + (this.config.className ? ` ${this.config.className}` : '');\n const list = document.createElement('ul');\n list.className = 'twm-record-list__items';\n if (this.config.label) list.setAttribute('aria-label', this.config.label);\n root.appendChild(list);\n this.element = root;\n this.listElement = list;\n\n this._onClick = (ev) => this._gesture(ev, 'click');\n this._onDblClick = (ev) => this._gesture(ev, 'dblclick');\n this._onKeyDown = (ev) => this._key(ev);\n // Only focus ON a record moves the tab stop. Focus on one of its verbs\n // must not: Tab walks forward through the verbs of the records before\n // the stop, and moving the stop behind the focus would leave no record\n // ahead to Tab to (measured in Edge).\n this._onFocusIn = (ev) => {\n const li = this._itemOf(ev.target);\n if (li && ev.target === li) this._setTabStop(li.__recordKey);\n };\n list.addEventListener('click', this._onClick);\n list.addEventListener('dblclick', this._onDblClick);\n list.addEventListener('keydown', this._onKeyDown);\n list.addEventListener('focusin', this._onFocusIn);\n\n this._draw();\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 records and draw them. Focus inside the list is kept on\n * the same record, and on the same verb of it, when it is still there. */\n setRecords(records) {\n if (this._disposed) return;\n this._records = Array.isArray(records) ? records.slice() : [];\n this._draw();\n }\n\n /** The records, as last given. */\n getRecords() {\n return this._records.slice();\n }\n\n /** Draw ONE record again (`describe` asked afresh), or every one with no key. */\n refresh(key) {\n if (this._disposed) return;\n if (key === undefined) { this._draw(); return; }\n const old = this._items.get(this._norm(key));\n if (!old) return;\n const idx = old.__recordIndex;\n const focus = this._focusMemo();\n const fresh = this._item(this._records[idx], idx);\n old.replaceWith(fresh);\n this._items.set(fresh.__recordKey, fresh);\n this._paintTabStop();\n this._restoreFocus(focus);\n }\n\n /** Mark the record that is open (`null` for none). */\n setActiveKey(key) {\n this._activeKey = key ?? null;\n for (const li of this._items.values()) this._paintActive(li);\n if (this._activeKey !== null && this._items.has(this._norm(this._activeKey))) {\n this._setTabStop(this._norm(this._activeKey));\n }\n }\n\n getActiveKey() {\n return this._activeKey;\n }\n\n /** The `<li>` drawn for a key, or null. */\n getItem(key) {\n return this._items.get(this._norm(key)) || null;\n }\n\n /** Move the keyboard focus to a record. */\n focusRecord(key) {\n const li = this.getItem(key);\n if (!li) return false;\n this._setTabStop(li.__recordKey);\n li.focus();\n return true;\n }\n\n dispose() {\n if (this._disposed) return;\n this._disposed = true;\n const list = this.listElement;\n list.removeEventListener('click', this._onClick);\n list.removeEventListener('dblclick', this._onDblClick);\n list.removeEventListener('keydown', this._onKeyDown);\n list.removeEventListener('focusin', this._onFocusIn);\n this._items.clear();\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 _activates() {\n return typeof this.config.onActivate === 'function';\n }\n\n _keyboard() {\n return this.config.keyboard ?? this._activates();\n }\n\n _gestures() {\n const g = this.config.activateOn;\n return new Set(Array.isArray(g) ? g : [g]);\n }\n\n /** Keys compare as strings: a record keyed `7` and an `activeKey` of `'7'` are one. */\n _norm(key) {\n return key === null || key === undefined ? key : String(key);\n }\n\n _spec(record, idx) {\n const { describe } = this.config;\n const spec = typeof describe === 'function' ? describe(record, idx) : record;\n return spec && typeof spec === 'object' ? spec : { name: spec };\n }\n\n _keyOf(record, idx, spec) {\n const { getKey } = this.config;\n let key;\n if (spec.key !== undefined && spec.key !== null) key = spec.key;\n else if (typeof getKey === 'function') key = getKey(record, idx);\n else if (record && typeof record === 'object' && (record.key ?? record.id) != null) key = record.key ?? record.id;\n else key = idx;\n return String(key);\n }\n\n _draw() {\n const focus = this._focusMemo();\n const list = this.listElement;\n list.replaceChildren();\n this._items.clear();\n this.element.querySelector(':scope > .twm-record-list__empty')?.remove();\n\n this._records.forEach((record, idx) => {\n const li = this._item(record, idx);\n if (this._items.has(li.__recordKey)) {\n console.error(`[RecordList] two records share the key \"${li.__recordKey}\"`);\n }\n this._items.set(li.__recordKey, li);\n list.appendChild(li);\n });\n this.element.classList.toggle('twm-record-list--empty', this._records.length === 0);\n if (!this._records.length) this._drawEmpty();\n this._paintTabStop();\n this._restoreFocus(focus);\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-record-list__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 _item(record, idx) {\n const spec = this._spec(record, idx);\n const key = this._keyOf(record, idx, spec);\n const li = document.createElement('li');\n li.className = 'twm-record';\n li.__record = record;\n li.__recordIndex = idx;\n li.__recordKey = key;\n li.dataset.recordKey = key;\n if (this._keyboard()) li.tabIndex = -1;\n if (spec.state) {\n li.dataset.state = safeWord(spec.state);\n li.classList.add(`twm-record--state-${safeWord(spec.state)}`);\n }\n\n const main = document.createElement('div');\n main.className = 'twm-record__main';\n const name = document.createElement('div');\n name.className = 'twm-record__name' + (spec.mono ? ' twm-record__name--mono' : '');\n appendContent(name, spec.name);\n main.appendChild(name);\n\n const factsText = this._facts(spec.facts);\n if (factsText !== null) {\n const facts = document.createElement('div');\n facts.className = 'twm-record__facts';\n appendContent(facts, factsText);\n if (this.config.facts === 'ellipsis') facts.title = facts.textContent;\n main.appendChild(facts);\n }\n if (spec.error != null && spec.error !== false && spec.error !== '') {\n const err = document.createElement('div');\n err.className = 'twm-record__error';\n appendContent(err, spec.error);\n main.appendChild(err);\n }\n li.appendChild(main);\n\n const pills = (spec.pills || []).filter((p) => p != null && p !== false && p !== '');\n if (pills.length) {\n const box = document.createElement('div');\n box.className = 'twm-record__pills';\n for (const p of pills) box.appendChild(pill(p));\n li.appendChild(box);\n }\n\n const verbs = (spec.verbs || []).filter(Boolean);\n if (verbs.length) {\n const box = document.createElement('div');\n box.className = 'twm-record__verbs';\n const reasons = new Map(); // sentence \u2192 [labels]\n for (const v of verbs) {\n const b = this._verb(v, record);\n box.appendChild(b);\n if (v.refusal) {\n const said = String(v.refusal);\n if (!reasons.has(said)) reasons.set(said, { labels: [], buttons: [] });\n reasons.get(said).labels.push(v.label);\n reasons.get(said).buttons.push(b);\n }\n }\n li.appendChild(box);\n if (reasons.size) {\n const lines = document.createElement('div');\n lines.className = 'twm-record__refusals';\n let n = 0;\n for (const [said, { labels, buttons }] of reasons) {\n const line = document.createElement('div');\n line.className = 'twm-record__refusal';\n line.id = `${this._id}-r${idx}-${n++}`;\n line.dataset.refusalFor = labels.join(', ');\n line.textContent = labels.length === verbs.length && verbs.length > 1\n ? said : `${labels.join(', ')}: ${said}`;\n for (const b of buttons) b.setAttribute('aria-describedby', line.id);\n lines.appendChild(line);\n }\n main.appendChild(lines);\n }\n }\n\n this._decorate(li, record, idx);\n return li;\n }\n\n _facts(facts) {\n if (facts == null || facts === false) return null;\n if (typeof Node !== 'undefined' && facts instanceof Node) return facts;\n if (!Array.isArray(facts)) {\n const s = String(facts);\n return s === '' ? null : s;\n }\n const parts = facts.filter((f) => f != null && f !== false && f !== '');\n if (!parts.length) return null;\n if (parts.every((p) => !(typeof Node !== 'undefined' && p instanceof Node))) {\n return parts.map(String).join(this.config.factSeparator);\n }\n const frag = document.createDocumentFragment();\n parts.forEach((p, i) => {\n if (i) frag.appendChild(document.createTextNode(this.config.factSeparator));\n appendContent(frag, p);\n });\n return frag;\n }\n\n _verb(v, record) {\n const b = document.createElement('button');\n b.type = 'button';\n const { verbClass } = this.config;\n b.className = typeof verbClass === 'function' ? String(verbClass(v) || '')\n : typeof verbClass === 'string' ? verbClass\n : 'twm-btn' + (v.primary ? ' twm-btn--primary' : '') + (v.danger ? ' twm-btn--danger' : '');\n b.classList.add('twm-record__verb');\n b.dataset.verb = String(v.name ?? v.label);\n if (v.icon) {\n const glyph = document.createElement('span');\n glyph.className = 'material-symbols-outlined twm-record__verb-icon';\n glyph.setAttribute('aria-hidden', 'true');\n glyph.textContent = String(v.icon);\n b.appendChild(glyph);\n }\n const label = document.createElement('span');\n label.className = 'twm-record__verb-label';\n label.textContent = String(v.label ?? '');\n b.appendChild(label);\n if (v.refusal) {\n b.disabled = true;\n b.title = String(v.refusal);\n b.dataset.refusal = String(v.refusal);\n } else {\n if (v.title) b.title = String(v.title);\n if (typeof v.onClick === 'function') b.addEventListener('click', (ev) => v.onClick(record, ev));\n }\n return b;\n }\n\n _decorate(li, record, idx) {\n const { rowClass, rowAttrs } = this.config;\n if (typeof rowClass === 'function') {\n const c = rowClass(record, idx);\n const list = Array.isArray(c) ? c : String(c ?? '').split(/\\s+/);\n for (const name of list) if (name) li.classList.add(String(name));\n }\n if (typeof rowAttrs === 'function') {\n for (const [name, value] of Object.entries(rowAttrs(record, idx) || {})) {\n if (value == null || value === false) continue;\n try {\n li.setAttribute(name, value === true ? '' : String(value));\n } catch (err) {\n console.error(`[RecordList] rowAttrs: bad attribute \"${name}\"`, err);\n }\n }\n }\n this._paintActive(li);\n }\n\n _paintActive(li) {\n const on = this._activeKey !== null && li.__recordKey === this._norm(this._activeKey);\n li.classList.toggle('twm-record--active', on);\n if (on) {\n if (li.getAttribute('aria-current') !== 'true') {\n li.setAttribute('aria-current', 'true');\n li.__twmAriaCurrent = true;\n }\n } else if (li.__twmAriaCurrent) {\n li.__twmAriaCurrent = false;\n li.removeAttribute('aria-current');\n }\n }\n\n // \u2500\u2500 focus \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 ONE record that takes Tab: the one last focused, else the open\n * one, else the first. */\n _paintTabStop() {\n if (!this._keyboard()) return;\n let key = this._tabKey;\n if (key === null || !this._items.has(key)) {\n const active = this._norm(this._activeKey);\n key = active !== null && this._items.has(active) ? active : (this._items.keys().next().value ?? null);\n }\n this._setTabStop(key);\n }\n\n _setTabStop(key) {\n if (!this._keyboard()) return;\n this._tabKey = key ?? null;\n for (const [k, li] of this._items) li.tabIndex = k === this._tabKey ? 0 : -1;\n }\n\n _focusMemo() {\n const doc = this.element.ownerDocument;\n const active = doc?.activeElement;\n if (!active || !this.listElement.contains(active)) return null;\n const li = this._itemOf(active);\n if (!li) return null;\n return { key: li.__recordKey, verb: active.closest('.twm-record__verb')?.dataset.verb ?? null };\n }\n\n _restoreFocus(memo) {\n if (!memo) return;\n const li = this._items.get(memo.key);\n if (!li) return;\n if (memo.verb !== null) {\n const b = [...li.querySelectorAll('.twm-record__verb')].find((x) => x.dataset.verb === memo.verb);\n if (b && !b.disabled) { b.focus(); return; }\n }\n if (this._keyboard()) { this._setTabStop(li.__recordKey); li.focus(); }\n }\n\n _itemOf(target) {\n const li = target?.closest?.('.twm-record');\n return li && this.listElement.contains(li) && li.parentNode === this.listElement ? li : null;\n }\n\n // \u2500\u2500 gestures \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 _gesture(ev, gesture) {\n if (!this._activates() || !this._gestures().has(gesture)) return;\n const li = this._itemOf(ev.target);\n if (!li) return;\n if (!isRowActivation(ev, gesture, { scope: this.listElement })) return;\n this.config.onActivate(li.__record, li.__recordIndex, ev);\n }\n\n _key(ev) {\n if (ev.defaultPrevented) return;\n const li = this._itemOf(ev.target);\n if (!li) return;\n if (ev.key === 'Enter') {\n // Enter on a verb is the verb's; only Enter on the record itself opens it.\n if (ev.target !== li || !this._activates() || !this._gestures().has('enter')) return;\n if (ev.altKey || ev.ctrlKey || ev.metaKey || ev.shiftKey) return;\n ev.preventDefault();\n this.config.onActivate(li.__record, li.__recordIndex, ev);\n return;\n }\n if (!this._keyboard()) return;\n if (ev.target !== li && (ev.target.closest(OWN_ARROWS) || !isRowControl(ev.target, li))) return;\n const items = [...this._items.values()];\n const at = items.indexOf(li);\n let next = null;\n if (ev.key === 'ArrowDown') next = items[Math.min(items.length - 1, at + 1)];\n else if (ev.key === 'ArrowUp') next = items[Math.max(0, at - 1)];\n else if (ev.key === 'Home') next = items[0];\n else if (ev.key === 'End') next = items[items.length - 1];\n else return;\n ev.preventDefault();\n if (next) {\n this._setTabStop(next.__recordKey);\n next.focus();\n }\n }\n}\n\n/**\n * Build a record list, append it to `host` (if given) and draw it.\n *\n * @param {HTMLElement|null} host\n * @param {RecordListConfig} [config]\n * @returns {RecordList}\n */\nexport function createRecordList(host, config = {}) {\n return new RecordList(host, config);\n}\n\n/** One pill: a string, or `{text, tone, title}`. A tone is a word\n * (`muted`, `info`, `success`, `warn`, `danger` are drawn). */\nfunction pill(p) {\n const s = typeof p === 'object' && !(typeof Node !== 'undefined' && p instanceof Node) ? p : { text: p };\n const span = document.createElement('span');\n span.className = 'twm-record__pill' + (s.tone ? ` twm-record__pill--${safeWord(s.tone)}` : '');\n if (typeof Node !== 'undefined' && s.text instanceof Node) span.appendChild(s.text);\n else if (typeof Node !== 'undefined' && p instanceof Node) span.appendChild(p);\n else span.textContent = String(s.text ?? '');\n if (s.title) span.title = String(s.title);\n if (s.tone) span.dataset.tone = safeWord(s.tone);\n return span;\n}\n\n/** Text, a node or nothing, into `el`. */\nfunction appendContent(el, content) {\n if (content == null || content === false) return;\n if (typeof Node !== 'undefined' && content instanceof Node) el.appendChild(content);\n else el.appendChild(document.createTextNode(String(content)));\n}\n", "/**\n * \u2550\u2550 A STACK OF COLLAPSIBLE SECTIONS \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\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 * Inspector-style panel content: titled sections, one above the other, each\n * opened and closed from its header (FlexDesk STORY-0036). Until this, only a\n * tree's categories could collapse, and every embedder that wanted a panel of\n * \"Notes / Assistant / Parameters\" built the headers, the arrows and the\n * remembering itself.\n *\n * const stack = createSectionStack(panel, {\n * sections: [\n * { id: 'notes', title: 'Notes', content: notesEl },\n * { id: 'chat', title: 'Assistant', fill: true,\n * actions: [{ id: 'clear', icon: 'delete', label: 'Clear', onClick: clear }] },\n * { id: 'params', title: 'Parameters', defaultExpanded: false },\n * ],\n * key: 'inspector.sections',\n * stateStore: { read: (key) => saved[key], write: (key, map) => { saved[key] = map; } },\n * });\n * stack.body('chat').appendChild(chatEl);\n * const off = stack.on('toggled', ({ id, expanded }) => \u2026);\n *\n * A SECTION is `{ id, title, icon?, content?, actions?, defaultExpanded?, fill? }`.\n * `content` is a Node put into the section's body at mount; `body(id)` hands\n * the same element over for anything mounted later. `defaultExpanded` is true\n * unless it says otherwise.\n *\n * THE HEADER TOGGLES; ITS ACTIONS DO NOT. A click anywhere on the header opens\n * or closes the section and turns its arrow \u2014 except on one of its `actions`\n * (`{ id?, icon, label, title?, onClick(sectionId, event) }`), which runs its\n * own `onClick` and leaves the section as it was.\n *\n * A FILL SECTION (`fill: true`) takes the height the others leave, and its\n * body scrolls inside it (`min-height: 0`), so a long conversation scrolls in\n * its section instead of growing the panel past the window. Give the stack's\n * container a height \u2014 it is `height: 100%` of it.\n *\n * REMEMBERING is the embedder's: `stateStore` is `{ read(key), write(key, map) }`\n * and `map` is `{ [sectionId]: expanded }`, written whenever a section opens or\n * closes. `read` may answer a promise; until it does, sections show their\n * `defaultExpanded`, and a section somebody toggled meanwhile keeps their\n * choice. Such a toggle is written once the read has settled, merged over\n * the stored map, so the defaults on screen never overwrite it. A store that throws, rejects, or answers something that is not a map\n * leaves every section on its `defaultExpanded` \u2014 remembering is a convenience,\n * never a reason for a panel not to draw. `ready` resolves once the read has\n * been applied (at once without a store).\n *\n * `setVisible(id, false)` takes a section off the stack without forgetting it:\n * `setVisible(id, true)` brings it back open or closed exactly as it was.\n *\n * The `toggled` event carries `{ id, expanded, source }`, `source` being\n * `'user'` (a header click), `'api'` (expand / collapse / toggle) or\n * `'restore'` (a stored state that arrived after mount). It fires only on a\n * change. `on()` answers the function that stops listening.\n *\n * `dispose()` removes the one listener the stack adds and every node it made;\n * `content` the embedder handed in goes with its section.\n *\n * Styled by `.twm-collapsible-*` (the tree's primitive) plus `.twm-section-stack*`.\n */\n\n/**\n * @param {HTMLElement} container\n * @param {object} opts\n * @param {Array} opts.sections `{ id, title, icon?, content?, actions?, defaultExpanded?, fill? }`\n * @param {object} [opts.stateStore] `{ read(key): map|Promise<map>, write(key, map) }`\n * @param {string} [opts.key] the key the expanded states live under; required with a store\n */\nexport function createSectionStack(container, { sections = [], stateStore = null, key = null } = {}) {\n if (stateStore && !key) throw new Error('createSectionStack: a stateStore needs a { key }');\n const doc = container.ownerDocument;\n\n const root = doc.createElement('div');\n root.className = 'twm-section-stack';\n\n /** id -> { def, box, toggle, arrow, body, expanded, visible, touched } */\n const byId = new Map();\n /** action button -> { sectionId, action } */\n const actionOf = new Map();\n /** header -> section id */\n const headerOf = new Map();\n const listeners = new Set();\n let disposed = false;\n // While a promised read is out, the sections nobody touched still show\n // their defaults, not what the store holds: writing them then would\n // overwrite the stored states with defaults. A toggle meanwhile only marks\n // the map as owed; it is written once the read has settled.\n let readPending = false;\n let writeOwed = false;\n\n for (const def of sections) {\n if (!def || def.id == null || byId.has(def.id)) {\n throw new Error(`createSectionStack: every section needs a unique id (got ${def?.id})`);\n }\n const expanded = def.defaultExpanded !== false;\n\n const box = doc.createElement('section');\n box.className = 'twm-collapsible-box twm-section-stack__section'\n + (def.fill ? ' twm-section-stack__section--fill' : '');\n\n const header = doc.createElement('div');\n header.className = 'twm-collapsible-header twm-section-stack__header';\n\n const toggle = doc.createElement('button');\n toggle.type = 'button';\n toggle.className = 'twm-section-stack__toggle';\n const arrow = doc.createElement('span');\n arrow.className = 'twm-collapsible-arrow material-symbols-outlined';\n arrow.setAttribute('aria-hidden', 'true');\n arrow.textContent = 'expand_more';\n toggle.appendChild(arrow);\n if (def.icon) {\n const icon = doc.createElement('span');\n icon.className = 'twm-section-stack__icon material-symbols-outlined';\n icon.setAttribute('aria-hidden', 'true');\n icon.textContent = def.icon;\n toggle.appendChild(icon);\n }\n const title = doc.createElement('span');\n title.className = 'twm-section-stack__title';\n title.textContent = def.title ?? String(def.id);\n toggle.appendChild(title);\n header.appendChild(toggle);\n\n if (Array.isArray(def.actions) && def.actions.length) {\n const bar = doc.createElement('div');\n bar.className = 'twm-section-stack__actions';\n for (const action of def.actions) {\n const btn = doc.createElement('button');\n btn.type = 'button';\n btn.className = 'twm-section-stack__action';\n if (action.label) btn.setAttribute('aria-label', action.label);\n if (action.title ?? action.label) btn.setAttribute('title', action.title ?? action.label);\n const glyph = doc.createElement('span');\n glyph.className = 'material-symbols-outlined';\n glyph.setAttribute('aria-hidden', 'true');\n glyph.textContent = action.icon ?? '';\n btn.appendChild(glyph);\n bar.appendChild(btn);\n actionOf.set(btn, { sectionId: def.id, action });\n }\n header.appendChild(bar);\n }\n\n const body = doc.createElement('div');\n body.className = 'twm-collapsible-content twm-section-stack__body';\n if (def.content) body.appendChild(def.content);\n\n box.append(header, body);\n root.appendChild(box);\n headerOf.set(header, def.id);\n const entry = { def, box, toggle, arrow, body, expanded, visible: true, touched: false };\n byId.set(def.id, entry);\n paint(entry);\n }\n\n function paint(entry) {\n entry.box.classList.toggle('twm-section-stack__section--expanded', entry.expanded);\n entry.body.classList.toggle('visible', entry.expanded);\n entry.arrow.classList.toggle('collapsed', !entry.expanded);\n entry.toggle.setAttribute('aria-expanded', String(entry.expanded));\n entry.box.hidden = !entry.visible;\n }\n\n function emit(detail) {\n for (const fn of [...listeners]) {\n try { fn(detail); } catch (err) { console.error('[section-stack] toggled listener failed', err); }\n }\n }\n\n function persist() {\n if (!stateStore?.write) return;\n if (readPending) { writeOwed = true; return; }\n const map = {};\n for (const [id, entry] of byId) map[id] = entry.expanded;\n write(map);\n }\n\n function write(map) {\n try {\n const pending = stateStore.write(key, map);\n pending?.catch?.(() => { /* storage refused: not ours to fix */ });\n } catch { /* storage refused: not ours to fix */ }\n }\n\n /** Set one section's state; true when it changed. */\n function set(id, expanded, source) {\n const entry = byId.get(id);\n if (disposed || !entry || entry.expanded === expanded) return false;\n entry.expanded = expanded;\n if (source !== 'restore') entry.touched = true;\n paint(entry);\n if (source !== 'restore') persist();\n emit({ id, expanded, source });\n return true;\n }\n\n const isMap = (saved) => !!saved && typeof saved === 'object' && !Array.isArray(saved);\n\n function restore(saved, source) {\n if (disposed || !isMap(saved)) return;\n for (const [id, entry] of byId) {\n if (entry.touched || typeof saved[id] !== 'boolean') continue;\n if (source === 'restore') set(id, saved[id], 'restore');\n else { entry.expanded = saved[id]; paint(entry); }\n }\n }\n\n /** A promised read has settled (`saved` is null when it rejected). */\n function settle(saved) {\n restore(saved, 'restore');\n readPending = false;\n if (!writeOwed) return;\n writeOwed = false;\n // The touched sections over what the store holds \u2014 also after a\n // dispose, which must not lose a choice made before the read answered.\n const map = {};\n for (const [id, entry] of byId) {\n map[id] = !entry.touched && isMap(saved) && typeof saved[id] === 'boolean'\n ? saved[id] : entry.expanded;\n }\n write(map);\n }\n\n function onClick(event) {\n const target = event.target;\n const btn = target?.closest?.('.twm-section-stack__action');\n if (btn && actionOf.has(btn)) {\n const { sectionId, action } = actionOf.get(btn);\n event.stopPropagation();\n try { action.onClick?.(sectionId, event); } catch (err) {\n console.error(`[section-stack] action on \"${sectionId}\" failed`, err);\n }\n return;\n }\n const header = target?.closest?.('.twm-section-stack__header');\n if (!header || !headerOf.has(header)) return;\n const id = headerOf.get(header);\n set(id, !byId.get(id).expanded, 'user');\n }\n root.addEventListener('click', onClick);\n\n // Synchronous stored state is applied before the stack is on screen, so it\n // never flashes the defaults; a promise is applied when it answers.\n let ready = Promise.resolve();\n if (stateStore?.read) {\n let saved = null;\n try { saved = stateStore.read(key); } catch { saved = null; }\n if (saved && typeof saved.then === 'function') {\n readPending = true;\n ready = Promise.resolve(saved)\n .then((value) => settle(value), () => settle(null));\n } else {\n restore(saved, 'mount');\n }\n }\n\n container.appendChild(root);\n\n const need = (id) => {\n if (!byId.has(id)) throw new Error(`createSectionStack: no section \"${id}\"`);\n return byId.get(id);\n };\n\n return {\n root,\n ready,\n /** The section's body element, for content mounted after the stack. */\n body: (id) => need(id).body,\n expand(id) { need(id); set(id, true, 'api'); },\n collapse(id) { need(id); set(id, false, 'api'); },\n toggle(id) { set(id, !need(id).expanded, 'api'); },\n isExpanded: (id) => need(id).expanded,\n /** Off the stack, or back on it \u2014 its expanded state is kept either way. */\n setVisible(id, visible) {\n const entry = need(id);\n entry.visible = !!visible;\n paint(entry);\n },\n isVisible: (id) => need(id).visible,\n /** `on('toggled', fn)` \u2014 answers the function that stops listening. */\n on(event, fn) {\n if (event !== 'toggled') throw new Error(`createSectionStack: no \"${event}\" event`);\n if (disposed) return () => {};\n listeners.add(fn);\n return () => listeners.delete(fn);\n },\n dispose() {\n if (disposed) return;\n disposed = true;\n root.removeEventListener('click', onClick);\n listeners.clear();\n actionOf.clear();\n headerOf.clear();\n root.remove();\n },\n };\n}\n", "/**\n * SettingsView \u2014 the settings page, drawn from a settings store's schema.\n *\n * const view = new SettingsView({ store, eventBus }); // the bus the store emits on\n * view.mount(host);\n * view.selectCategory('window');\n * view.setQuery('shadow');\n * view.dispose();\n *\n * // or as tile content:\n * createShell({ content: { settings: settingsViewContent({ store, eventBus }) } });\n *\n * `store` is a `createSettingsStore()` handle, or the app-global binding's own\n * (`getSettingsStore()` in `@flexdesk/core`). The view knows no setting: every\n * category, group, label, description and control comes from the store's\n * `getCategories()` and `getSchema()`.\n *\n * THE LAYOUT. A sidebar with a filter box, the categories in their\n * `CategoryDef.order` and *Reset all*; beside it the chosen category's\n * settings under its title, description and *Reset category*, grouped by\n * `SettingDef.group` in schema order. Each row shows its label, a *Modified*\n * marker while its value differs from its default, its description, its path,\n * its control and a reset button. Text typed in the filter searches every\n * category's labels, descriptions and paths, and the matches are listed\n * under their category and group.\n *\n * THE CONTROLS, one per `SettingDef.type`:\n * boolean a ToggleField\n * select a select over `options`\n * number a number box with `min`, `max` and `step`; a value written is\n * snapped to the step (counted from `min`) and clamped to the range,\n * and a box left empty or unreadable goes back to the value\n * text a text box written `textDebounceMs` after the last keystroke,\n * or at once on Enter or blur; emptied, it writes `null` when the\n * default is `null`, else `''`\n * colorList a ColorListField, written on every committed edit while every\n * row holds a colour\n * A type the view does not know shows the value as text, read only.\n *\n * LIVE, BOTH WAYS. A control writes through `store.set()`. The view listens\n * on `eventBus` for `settings:<path>:changed` for every path in the schema,\n * for `settings:changed` with a null path (the resets) and for\n * `settings:registered` (a slice registered after mount: its categories join\n * the sidebar and its settings their category, without a remount). A value\n * changed elsewhere moves its control and its marker. An edit still being\n * typed (a text before its debounce, digits before 'change') is written\n * before the view redraws or syncs its rows, so it is never dropped.\n *\n * RESETS. A row's reset button resets that setting. *Reset category* and\n * *Reset all* ask `confirm(\u2026)` first (default `openConfirm`) and change\n * nothing unless it resolves true.\n *\n * THE SIDEBAR ELSEWHERE (0.17.2). `sidebar: false` leaves the sidebar out:\n * the view is the content alone. A `SettingsCategories` bound to it, mounted\n * anywhere, draws the filter box, the categories and *Reset all* instead:\n *\n * const view = new SettingsView({ store, eventBus, sidebar: false });\n * view.mount(pageHost);\n * const cats = new SettingsCategories({ view });\n * cats.mount(navigatorHost);\n *\n * Both draw from the view's state, so the filter text and the selected\n * category are the same in both, whichever moved them; `view.subscribe(fn)`\n * tells any other listener. *Reset all* there is `view.resetAll()`, so it asks\n * to confirm as before.\n *\n * Every word on screen that comes from the schema, the store or the user is\n * set as text, so a label or a query holding markup is shown as typed.\n *\n * Markup: `.twm-settings` > `.twm-settings__sidebar` (`__search` >\n * `__search-input`, `__nav` > `button.__cat` [`--active`], `__reset-all`)\n * + `.twm-settings__content` (`__header` > `__title`, `__description`,\n * `__reset-category`; `section.__group` > `__group-title` + `.__row`\n * [`--modified`] > `__info` (`__label`, `__marker`, `__description`,\n * `__path`) + `__control` + `__reset`; `__empty`). A `SettingsCategories` is\n * `.twm-settings-categories` > `.twm-settings__search`, `.twm-settings__nav`\n * and `.twm-settings__reset-all`, the same parts as the sidebar's.\n */\n\nimport { ComponentBase } from '../base/component_base.js';\nimport { ToggleField } from './toggle_field.js';\nimport { ColorListField } from './color_list_field.js';\nimport { selectBox, shownValue } from './choice_controls.js';\nimport { openConfirm } from './modal.js';\n\n/** Milliseconds between the last keystroke in a text setting and its write. */\nexport const SETTINGS_TEXT_DEBOUNCE_MS = 300;\n\nfunction el(tag, className, text) {\n const n = document.createElement(tag);\n if (className) n.className = className;\n if (text !== undefined && text !== null) n.textContent = String(text);\n return n;\n}\n\nfunction icon(name) {\n const n = el('span', 'material-symbols-outlined', name);\n n.setAttribute('aria-hidden', 'true');\n return n;\n}\n\nfunction same(a, b) {\n if (a === b) return true;\n if (a == null || b == null) return a == null && b == null;\n if (typeof a !== typeof b || typeof a !== 'object') return false;\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n const ka = Object.keys(a);\n const kb = Object.keys(b);\n return ka.length === kb.length && ka.every((k) => same(a[k], b[k]));\n}\n\n/**\n * A number written by a number row, always both in range and on the step grid\n * (`min + k * step`, or `k * step` with no `min`): snapped to the nearest grid\n * point, and a point outside [min, max] is moved inward to the nearest grid\n * point inside. `min` is itself a grid point, so the range holds none only\n * when `max < min`; the value is then `min`. With no step it is only clamped.\n */\nfunction fitNumber(n, { min, max, step }) {\n const lo = min != null && Number.isFinite(Number(min)) ? Number(min) : null;\n const hi = max != null && Number.isFinite(Number(max)) ? Number(max) : null;\n const s = Number(step);\n if (!(Number.isFinite(s) && s > 0)) {\n let v = n;\n if (hi != null) v = Math.min(hi, v);\n if (lo != null) v = Math.max(lo, v);\n return v;\n }\n const base = lo ?? 0;\n const places = (x) => (String(x).split('.')[1] || '').length;\n const decimals = Math.max(places(s), places(base));\n const at = (k) => Number((base + k * s).toFixed(decimals));\n const EPS = 1e-9;\n let k = Math.round((n - base) / s);\n if (hi != null && at(k) > hi) k = Math.floor((hi - base) / s + EPS);\n if (lo != null && at(k) < lo) k = Math.ceil((lo - base) / s - EPS);\n return at(k);\n}\n\n// \u2500\u2500 the sidebar's parts, drawn alike by SettingsView and SettingsCategories \u2500\u2500\n\n/** The filter box: `{ label, input }`; `onInput(text)` on every keystroke. */\nfunction filterBox(onInput) {\n const label = el('label', 'twm-settings__search');\n const input = el('input', 'twm-settings__search-input');\n input.type = 'search';\n input.placeholder = 'Filter settings\u2026';\n input.autocomplete = 'off';\n input.spellcheck = false;\n input.setAttribute('aria-label', 'Filter settings');\n input.addEventListener('input', () => onInput(input.value));\n label.append(icon('search'), input);\n return { label, input };\n}\n\n/** The category list; `onSelect(id)` when a category is clicked. */\nfunction categoryNav(onSelect) {\n const nav = el('nav', 'twm-settings__nav');\n nav.setAttribute('aria-label', 'Settings categories');\n nav.addEventListener('click', (e) => {\n const btn = e.target.closest?.('[data-category]');\n if (btn && nav.contains(btn)) onSelect(btn.dataset.category);\n });\n return nav;\n}\n\n/** Draw `categories` into `nav`, `active` (an id, or null) marked. */\nfunction paintCategories(nav, categories, active) {\n const buttons = categories.map((cat) => {\n const b = el('button', 'twm-settings__cat');\n b.type = 'button';\n b.dataset.category = cat.id;\n if (cat.id === active) {\n b.classList.add('twm-settings__cat--active');\n b.setAttribute('aria-current', 'page');\n }\n b.append(icon(cat.icon || 'tune'), el('span', 'twm-settings__cat-label', cat.label ?? cat.id));\n if (cat.description) b.title = String(cat.description);\n return b;\n });\n nav.replaceChildren(...buttons);\n}\n\n/** The *Reset all* button; `onClick()` when pressed. */\nfunction resetAllButton(onClick) {\n const b = el('button', 'twm-btn twm-settings__reset-all');\n b.type = 'button';\n b.append(icon('restart_alt'), el('span', '', 'Reset all'));\n b.addEventListener('click', () => { onClick(); });\n return b;\n}\n\nexport class SettingsView extends ComponentBase {\n /**\n * @param {object} o\n * @param {object} o.store a settings store (`createSettingsStore()` / `getSettingsStore()`)\n * @param {object} o.eventBus the bus the store emits on\n * @param {Function} [o.confirm] `({title, message, confirmLabel, danger}) -> Promise<boolean>`\n * @param {string} [o.category] the category shown first (default: the first)\n * @param {number} [o.textDebounceMs]\n * @param {string} [o.title='Settings'] the sidebar heading\n * @param {boolean} [o.sidebar=true] false leaves the sidebar (filter,\n * categories, *Reset all*) out, for a `SettingsCategories` elsewhere\n */\n constructor({\n store, eventBus, confirm = openConfirm, category = null,\n textDebounceMs = SETTINGS_TEXT_DEBOUNCE_MS, title = 'Settings', sidebar = true, logger,\n } = {}) {\n super({ eventBus, logger });\n if (!store || typeof store.getSchema !== 'function') {\n throw new TypeError('SettingsView: `store` must be a settings store');\n }\n if (!eventBus || typeof eventBus.on !== 'function') {\n throw new TypeError('SettingsView: `eventBus` must be the bus the store emits on');\n }\n this.store = store;\n this._confirm = confirm;\n this._category = category;\n this._query = '';\n this._debounceMs = textDebounceMs;\n this._title = title;\n this._sidebar = sidebar !== false;\n /** `fn({ category, query })` after the category, the filter or the categories change. */\n this._listeners = new Set();\n\n this.root = null;\n this._nav = null;\n this._content = null;\n this._search = null;\n /** path -> { sync(), flush(), dispose() } for the rows on screen. */\n this._rows = new Map();\n /** path -> the bus subscription handle, for every schema path. */\n this._pathSubs = new Map();\n /** Bus subscription handles for the whole-store events. */\n this._subs = [];\n this._disposed = false;\n }\n\n /** Build the view into `container` (once). */\n mount(container) {\n if (this.root) return this.root;\n const root = el('div', 'twm-settings');\n if (this._sidebar) {\n const side = el('aside', 'twm-settings__sidebar');\n const head = el('div', 'twm-settings__sidebar-title');\n head.append(icon('settings'), el('span', '', this._title));\n const search = filterBox((text) => this.setQuery(text));\n this._search = search.input;\n this._nav = categoryNav((id) => this.selectCategory(id));\n side.append(head, search.label, this._nav, resetAllButton(() => this.resetAll()));\n root.append(side);\n }\n\n const content = el('div', 'twm-settings__content');\n this._content = content;\n root.append(content);\n this.root = root;\n container.appendChild(root);\n this._mounted = true;\n\n for (const path of Object.keys(this.store.getSchema())) this.#watch(path);\n this._subs.push(this.eventBus.on('settings:changed', (p) => {\n if (p?.path == null) this.#syncAll();\n }));\n this._subs.push(this.eventBus.on('settings:registered', (p) => this.#onRegistered(p)));\n\n this.#paintNav();\n this.#paintContent();\n this.#notify();\n return root;\n }\n\n /** The category on screen (its id), or null. */\n getCategory() { return this.#activeCategory()?.id ?? null; }\n\n /** The filter text. */\n getQuery() { return this._query; }\n\n /** True while the filter is in effect (its trimmed text is not empty). */\n isFiltering() { return this.#searching(); }\n\n /**\n * `fn({ category, query })` after every change of the category, the filter\n * or the registered categories, until the view is disposed. Answers the\n * unsubscribe.\n */\n subscribe(fn) {\n this._listeners.add(fn);\n return () => this._listeners.delete(fn);\n }\n\n /** Show one category; clears the filter. */\n selectCategory(id) {\n if (!this.root) return;\n if (!this.store.getCategories().some((c) => c.id === id)) return;\n this._category = id;\n this._query = '';\n if (this._search) this._search.value = '';\n this.#paintNav();\n this.#paintContent();\n this.#notify();\n }\n\n /** Search every category; an empty query goes back to the category. */\n setQuery(query) {\n if (!this.root) return;\n const q = String(query ?? '');\n this._query = q;\n if (this._search && this._search.value !== q) this._search.value = q;\n this.#paintNav();\n this.#paintContent();\n this.#notify();\n }\n\n /** Reset one category after `confirm`; resolves true when it was reset. */\n async resetCategory(id = this.getCategory()) {\n const cat = this.store.getCategories().find((c) => c.id === id);\n if (!cat) return false;\n const ok = await this._confirm({\n title: 'Reset category',\n message: `Reset every setting in \u201C${cat.label ?? cat.id}\u201D to its default?`,\n confirmLabel: 'Reset',\n danger: true,\n });\n if (!ok || this._disposed) return false;\n this.#flushAll();\n this.store.resetCategory(id);\n this.#syncAll();\n return true;\n }\n\n /** Reset every setting after `confirm`; resolves true when they were reset. */\n async resetAll() {\n const ok = await this._confirm({\n title: 'Reset all settings',\n message: 'Reset every setting to its default?',\n confirmLabel: 'Reset all',\n danger: true,\n });\n if (!ok || this._disposed) return false;\n this.#flushAll();\n this.store.resetAll();\n this.#syncAll();\n return true;\n }\n\n dispose() {\n if (this._disposed) return;\n this._disposed = true;\n this.#flushAll();\n this.#dropRows();\n for (const sub of this._pathSubs.values()) sub.dispose();\n this._pathSubs.clear();\n for (const sub of this._subs) sub.dispose();\n this._subs = [];\n this.root?.remove();\n this.root = null;\n this._nav = null;\n this._content = null;\n this._search = null;\n this._listeners.clear();\n super.dispose();\n }\n\n // \u2500\u2500 store 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\n\n #watch(path) {\n if (this._pathSubs.has(path)) return;\n this._pathSubs.set(path, this.eventBus.on(`settings:${path}:changed`, () => {\n this._rows.get(path)?.sync();\n }));\n }\n\n #onRegistered({ paths = [] } = {}) {\n if (!this.root) return;\n const schema = this.store.getSchema();\n for (const path of Object.keys(schema)) this.#watch(path);\n this.#paintNav();\n const active = this.getCategory();\n const touches = this.#searching()\n || !this._rows.size\n || paths.some((p) => schema[p]?.category === active);\n if (touches) {\n this.#paintContent();\n } else {\n // The slice's defaults may have moved values on screen; an edit still\n // being typed is written first, so the sync shows it rather than drop it.\n this.#flushAll();\n this.#syncAll();\n }\n this.#notify();\n }\n\n /** True while a filter is in effect: the trimmed query is not empty. */\n #searching() {\n return this._query.trim() !== '';\n }\n\n #syncAll() {\n for (const row of this._rows.values()) row.sync();\n }\n\n #flushAll() {\n for (const row of this._rows.values()) row.flush();\n }\n\n #dropRows() {\n for (const row of this._rows.values()) row.dispose();\n this._rows.clear();\n }\n\n // \u2500\u2500 painting \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 #activeCategory() {\n const cats = this.store.getCategories();\n return cats.find((c) => c.id === this._category) ?? cats[0] ?? null;\n }\n\n #paintNav() {\n if (!this._nav) return;\n paintCategories(this._nav, this.store.getCategories(), this.#searching() ? null : this.getCategory());\n }\n\n /** Tell the listeners, after the content is drawn (it settles the category). */\n #notify() {\n const state = { category: this.getCategory(), query: this._query };\n for (const fn of [...this._listeners]) fn(state);\n }\n\n #paintContent() {\n this.#flushAll();\n this.#dropRows();\n const schema = this.store.getSchema();\n const content = this._content;\n content.replaceChildren();\n\n if (this.#searching()) {\n const q = this._query.trim().toLowerCase();\n const cats = this.store.getCategories();\n const labelOf = new Map(cats.map((c) => [c.id, c.label ?? c.id]));\n const rank = new Map(cats.map((c, i) => [c.id, i]));\n const matches = Object.entries(schema)\n .filter(([path, def]) => [def.label, def.description, path]\n .some((t) => t != null && String(t).toLowerCase().includes(q)))\n .map(([path, def]) => ({ path, ...def }));\n matches.sort((a, b) => (rank.get(a.category) ?? Infinity) - (rank.get(b.category) ?? Infinity));\n\n const header = el('header', 'twm-settings__header');\n const info = el('div', 'twm-settings__header-info');\n const n = matches.length;\n info.append(el('h2', 'twm-settings__title',\n `${n} result${n === 1 ? '' : 's'} for \u201C${this._query.trim()}\u201D`));\n header.append(info);\n content.append(header);\n if (!n) {\n content.append(el('div', 'twm-settings__empty', 'No setting matches the filter.'));\n return;\n }\n this.#paintGroups(matches, (def) =>\n `${labelOf.get(def.category) ?? def.category ?? ''} \u203A ${def.group || 'General'}`);\n return;\n }\n\n const cat = this.#activeCategory();\n if (!cat) {\n content.append(el('div', 'twm-settings__empty', 'No settings.'));\n return;\n }\n // The page drawn is the category: a slice registered later, ordered\n // before it, must not move the sidebar marker or getCategory() off it.\n this._category = cat.id;\n const header = el('header', 'twm-settings__header');\n const info = el('div', 'twm-settings__header-info');\n info.append(el('h2', 'twm-settings__title', cat.label ?? cat.id));\n if (cat.description) info.append(el('p', 'twm-settings__description', cat.description));\n const reset = el('button', 'twm-btn twm-settings__reset-category');\n reset.type = 'button';\n reset.append(icon('restart_alt'), el('span', '', 'Reset category'));\n reset.addEventListener('click', () => { this.resetCategory(cat.id); });\n header.append(info, reset);\n content.append(header);\n\n const defs = Object.entries(schema)\n .filter(([, def]) => def.category === cat.id)\n .map(([path, def]) => ({ path, ...def }));\n if (!defs.length) {\n content.append(el('div', 'twm-settings__empty', 'No settings in this category.'));\n return;\n }\n this.#paintGroups(defs, (def) => def.group || 'General');\n }\n\n #paintGroups(defs, groupTitle) {\n const groups = new Map();\n for (const def of defs) {\n const key = groupTitle(def);\n if (!groups.has(key)) groups.set(key, []);\n groups.get(key).push(def);\n }\n for (const [title, list] of groups) {\n const section = el('section', 'twm-settings__group');\n section.append(el('h3', 'twm-settings__group-title', title));\n for (const def of list) section.append(this.#row(def));\n this._content.append(section);\n }\n }\n\n // \u2500\u2500 rows \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 #row(def) {\n const { path } = def;\n const store = this.store;\n const row = el('div', 'twm-settings__row');\n row.dataset.path = path;\n\n const info = el('div', 'twm-settings__info');\n const labelLine = el('div', 'twm-settings__label-line');\n const label = el('span', 'twm-settings__label', def.label ?? path);\n const marker = el('span', 'twm-settings__marker', 'Modified');\n labelLine.append(label, marker);\n info.append(labelLine);\n if (def.description) info.append(el('div', 'twm-settings__description', def.description));\n info.append(el('code', 'twm-settings__path', path));\n\n const slot = el('div', 'twm-settings__control');\n const control = this.#control(def, (value) => store.set(path, value));\n slot.append(control.el);\n\n const reset = el('button', 'twm-settings__reset');\n reset.type = 'button';\n reset.title = 'Reset to default';\n reset.setAttribute('aria-label', `Reset ${def.label ?? path} to default`);\n reset.append(icon('restart_alt'));\n reset.addEventListener('click', () => {\n control.cancel?.();\n store.resetOne(path);\n });\n\n row.append(info, slot, reset);\n\n const sync = () => {\n const value = store.get(path);\n control.show(value);\n const modified = !same(value, store.getDefault(path));\n row.classList.toggle('twm-settings__row--modified', modified);\n marker.hidden = !modified;\n reset.hidden = !modified;\n };\n sync();\n this._rows.set(path, {\n sync,\n flush: () => control.flush?.(),\n dispose: () => control.dispose?.(),\n });\n return row;\n }\n\n /** `{ el, show(value), flush?(), cancel?(), dispose?() }` for one setting. */\n #control(def, write) {\n const name = def.label ?? def.path;\n switch (def.type) {\n case 'boolean': {\n const t = new ToggleField({\n checked: !!this.store.get(def.path), ariaLabel: name, compact: true,\n onChange: (on) => write(on),\n });\n return {\n el: t.render(),\n show: (v) => { if (t.get() !== !!v) t.set(!!v); },\n dispose: () => t.dispose(),\n };\n }\n case 'select': {\n const c = selectBox(def.options || [], this.store.get(def.path), {\n label: name, valueAttr: 'value', className: 'twm-settings__select',\n });\n c.box.addEventListener('change', () => {\n // Redrawn as a fresh mount draws the chosen value, so a stray\n // '(not found)' entry goes once an offered option is picked.\n const v = c.valueOf();\n c.setOptions(def.options || [], v);\n write(v);\n });\n return {\n el: c.box,\n // Redrawn with the new value, as a fresh mount draws it: a\n // value the options lack shows as its '(not found)' entry, and\n // a stray entry left from an earlier value goes.\n show: (v) => { if (!same(c.valueOf(), v)) c.setOptions(def.options || [], v); },\n };\n }\n case 'number': {\n const box = el('input', 'twm-settings__number');\n box.type = 'number';\n box.setAttribute('aria-label', name);\n if (def.min != null) box.min = String(def.min);\n if (def.max != null) box.max = String(def.max);\n if (def.step != null) box.step = String(def.step);\n // Digits typed but not yet committed by 'change'.\n let dirty = false;\n const show = (v) => {\n dirty = false;\n const text = v == null ? '' : String(v);\n if (box.value !== text) box.value = text;\n };\n const commit = () => {\n const current = this.store.get(def.path);\n const n = box.value.trim() === '' ? NaN : Number(box.value);\n if (!Number.isFinite(n)) { show(current); return; }\n const v = fitNumber(n, def);\n show(v);\n if (!same(v, current)) write(v);\n };\n box.addEventListener('input', () => { dirty = true; });\n box.addEventListener('change', commit);\n return {\n el: box,\n show,\n flush: () => { if (dirty) commit(); },\n };\n }\n case 'text': {\n const box = el('input', 'twm-settings__text');\n box.type = 'text';\n box.setAttribute('aria-label', name);\n if (def.placeholder != null) box.placeholder = String(def.placeholder);\n let timer = null;\n const valueOf = () => (box.value === '' && def.defaultValue === null ? null : box.value);\n const cancel = () => { if (timer !== null) { clearTimeout(timer); timer = null; } };\n const commit = () => {\n const v = valueOf();\n if (!same(v, this.store.get(def.path))) write(v);\n };\n const flush = () => {\n if (timer === null) return;\n cancel();\n commit();\n };\n box.addEventListener('input', () => {\n cancel();\n timer = setTimeout(() => { timer = null; commit(); }, this._debounceMs);\n });\n box.addEventListener('change', flush);\n box.addEventListener('keydown', (e) => { if (e.key === 'Enter') flush(); });\n return {\n el: box,\n show: (v) => {\n const text = v == null ? '' : String(v);\n if (box.value === text) return;\n cancel();\n box.value = text;\n },\n flush,\n cancel,\n dispose: cancel,\n };\n }\n case 'colorList': {\n const value = this.store.get(def.path);\n const f = new ColorListField({\n value: Array.isArray(value) ? value : [],\n onChange: (colors, { commit }) => { if (commit && colors) write(colors); },\n });\n return {\n el: f.render(),\n show: (v) => {\n const list = Array.isArray(v) ? v : [];\n if (!same(f.getValue(), list)) f.setValue(list);\n },\n dispose: () => f.dispose(),\n };\n }\n default: {\n const out = el('span', 'twm-settings__readonly');\n return {\n el: out,\n show: (v) => { out.textContent = shownValue(v); },\n };\n }\n }\n }\n}\n\n/**\n * SettingsCategories \u2014 a SettingsView's filter box, category list and\n * *Reset all*, mounted wherever the app wants them (0.17.2).\n *\n * const view = new SettingsView({ store, eventBus, sidebar: false });\n * view.mount(pageHost);\n * const cats = new SettingsCategories({ view });\n * cats.mount(navigatorHost);\n * cats.dispose(); // before or with the view\n *\n * It holds no state of its own: typing in its filter is `view.setQuery()`,\n * clicking a category `view.selectCategory()`, *Reset all* `view.resetAll()`\n * (which asks the view's `confirm` first), and it redraws from the view on\n * every `view.subscribe()` call. So the filter text and the selected category\n * are always the view's, however either side moved them, and a category\n * registered later joins the list. Its clicks and keystrokes act once the\n * view is mounted.\n *\n * Markup: `.twm-settings-categories` > `.twm-settings__search` (>\n * `__search-input`), `.twm-settings__nav` > `button.twm-settings__cat`\n * [`--active`], `.twm-settings__reset-all`.\n */\nexport class SettingsCategories extends ComponentBase {\n /**\n * @param {object} o\n * @param {SettingsView} o.view the view it lists the categories of\n */\n constructor({ view, logger } = {}) {\n if (!(view instanceof SettingsView)) {\n throw new TypeError('SettingsCategories: `view` must be a SettingsView');\n }\n super({ eventBus: view.eventBus, logger });\n this.view = view;\n this.root = null;\n this._search = null;\n this._nav = null;\n this._unsubscribe = null;\n }\n\n /** Build the list into `container` (once). */\n mount(container) {\n if (this.root) return this.root;\n const view = this.view;\n const root = el('div', 'twm-settings-categories');\n const search = filterBox((text) => view.setQuery(text));\n this._search = search.input;\n this._nav = categoryNav((id) => view.selectCategory(id));\n root.append(search.label, this._nav, resetAllButton(() => view.resetAll()));\n this.root = root;\n container.appendChild(root);\n this._mounted = true;\n this._unsubscribe = view.subscribe(() => this.#paint());\n this.#paint();\n return root;\n }\n\n dispose() {\n this._unsubscribe?.();\n this._unsubscribe = null;\n this.root?.remove();\n this.root = null;\n this._search = null;\n this._nav = null;\n super.dispose();\n }\n\n #paint() {\n const view = this.view;\n const q = view.getQuery();\n if (this._search.value !== q) this._search.value = q;\n paintCategories(this._nav, view.store.getCategories(), view.isFiltering() ? null : view.getCategory());\n }\n}\n\n/**\n * A content factory for the shell: `(hostEl, props, ctx) -> { title, destroy }`.\n * `props.category` picks the category shown first.\n *\n * @param {object} opts as `new SettingsView(opts)`\n * @returns {Function}\n */\nexport function settingsViewContent(opts = {}) {\n return (hostEl, props = {}) => {\n const view = new SettingsView({ ...opts, category: props?.category ?? opts.category ?? null });\n view.mount(hostEl);\n return {\n title: opts.title ?? 'Settings',\n view,\n destroy: () => view.dispose(),\n };\n };\n}\n", "/**\n * A range slider with optional companions: a linked number box, a readout, a\n * default with a modified state and a reset button, and an enable toggle.\n *\n * Every companion is opt-in through `field`; with none of them the DOM is the\n * range and the helper line, exactly as before.\n *\n * field.min / max / step / value the range (defaults 0 / 100 / 1 / min)\n * field.numberInput true: an editable number box, two-way synced\n * field.readout true, or (value: number) => string\n * field.defaultValue enables the modified state and a reset button\n * field.toggleable true: an enable checkbox before the slider\n * field.enabled the toggle's initial state (default true)\n * field.disabledValue what onChange reports while toggled off (default null)\n * field.emitOnInput also report every drag frame ({ immediate: true })\n * field.disabled / helperText as before\n *\n * onChange(value, { immediate }) receives the slider's value as a string \u2014 the\n * range input's own value, as it always has \u2014 or `disabledValue` while the\n * toggle is off. A commit that leaves the reported value where it was reports\n * nothing, so setValue/setRange/setEnabled cannot echo back into the caller\n * that drove them.\n */\nexport class SliderField {\n #min = 0;\n #max = 100;\n #step = 1;\n #value = 0;\n #enabled = true;\n #hasDefault = false;\n #defaultValue = 0;\n\n constructor({ fieldId, field = {}, onChange = null, logger = null } = {}) {\n if (!fieldId) {\n throw new Error('SliderField requires a fieldId');\n }\n this.fieldId = fieldId;\n this.field = field;\n this.logger = logger;\n this.onChange = typeof onChange === 'function' ? onChange : null;\n\n this.root = null;\n this.sliderInput = null;\n this.numberInput = null;\n this.readoutEl = null;\n this.resetButton = null;\n this.toggleInput = null;\n this.helperEl = null;\n this.emitOnInput = Boolean(field.emitOnInput ?? field.emitsOnInput);\n this._disposers = [];\n\n this.#min = this.#coerceNumber(field.min, 0);\n this.#max = Math.max(this.#min, this.#coerceNumber(field.max, 100));\n this.#step = this.#coercePositiveNumber(field.step, 1);\n this.#value = this.#fit(this.#coerceNumber(field.value, this.#min));\n this.#enabled = field.toggleable ? field.enabled !== false : true;\n this.#hasDefault = this.#isFiniteInput(field.defaultValue);\n if (this.#hasDefault) {\n this.#defaultValue = this.#fit(Number(field.defaultValue));\n }\n }\n\n render() {\n if (this.root) {\n return this.root;\n }\n this.root = document.createElement('div');\n this.root.className = 'twm-slider-field';\n\n this.sliderInput = document.createElement('input');\n this.sliderInput.type = 'range';\n this.sliderInput.className = 'twm-slider-field__input';\n this.#writeRangeAttributes();\n\n // Prevent parent interactions from interfering with slider dragging\n // Use stopImmediatePropagation to ensure no other handlers on this element run\n // DO NOT call preventDefault - allow native slider drag behavior\n const stopDrag = (evt) => {\n evt.stopPropagation();\n evt.stopImmediatePropagation();\n };\n // Use capture phase to intercept before any parent handlers\n this.#listen(this.sliderInput, 'mousedown', stopDrag, { capture: true });\n this.#listen(this.sliderInput, 'touchstart', stopDrag, { passive: false, capture: true });\n\n this.helperEl = document.createElement('div');\n this.helperEl.className = 'twm-slider-field__helper';\n if (this.field.helperText) {\n this.helperEl.textContent = this.field.helperText;\n }\n\n const companions = this.field.toggleable || this.field.numberInput\n || this.field.readout || this.#hasDefault;\n if (companions) {\n const row = document.createElement('div');\n row.className = 'twm-slider-field__row';\n if (this.field.toggleable) {\n row.appendChild(this.#buildToggle());\n }\n row.appendChild(this.sliderInput);\n if (this.field.readout) {\n this.readoutEl = document.createElement('span');\n this.readoutEl.className = 'twm-slider-field__readout';\n row.appendChild(this.readoutEl);\n }\n if (this.field.numberInput) {\n row.appendChild(this.#buildNumberInput());\n }\n if (this.#hasDefault) {\n row.appendChild(this.#buildResetButton());\n }\n this.root.appendChild(row);\n } else {\n this.root.appendChild(this.sliderInput);\n }\n this.root.appendChild(this.helperEl);\n\n // Throttle onInput to animation frames to avoid re-render stutter while dragging\n let rafToken = null;\n let pendingValue = null;\n const flushPending = () => {\n if (rafToken) {\n cancelAnimationFrame(rafToken);\n rafToken = null;\n }\n if (pendingValue === null) return;\n const valueToEmit = pendingValue;\n pendingValue = null;\n if (this.emitOnInput) {\n this.onChange?.(valueToEmit, { immediate: true });\n }\n };\n\n const handleInput = (event) => {\n // The companions follow the thumb on every frame; onChange waits for release.\n this.#value = this.#fit(Number(event.target.value));\n this.#syncCompanions();\n pendingValue = event.target.value;\n if (!rafToken) {\n rafToken = requestAnimationFrame(() => {\n rafToken = null;\n flushPending();\n });\n }\n };\n const handleChange = (event) => {\n flushPending();\n this.#value = this.#fit(Number(event.target.value));\n this.#syncCompanions();\n this.onChange?.(event.target.value, { immediate: false });\n };\n this.#listen(this.sliderInput, 'input', handleInput);\n this.#listen(this.sliderInput, 'change', handleChange);\n\n this.#syncCompanions();\n return this.root;\n }\n\n /** What onChange would report now: the value as a string, or disabledValue while toggled off. */\n getValue() {\n return this.#enabled ? String(this.#value) : this.#disabledValue();\n }\n\n isEnabled() {\n return this.#enabled;\n }\n\n /** True when a defaultValue was given and the value differs from it. */\n isModified() {\n return this.#hasDefault && this.#value !== this.#defaultValue;\n }\n\n /**\n * Clamp to the range and snap to the step. Reports once, unless `silent` or\n * the reported value did not move. A non-finite value is refused (false).\n */\n setValue(value, { silent = false } = {}) {\n if (!this.#isFiniteInput(value)) {\n return false;\n }\n const numeric = Number(value);\n return this.#commit(() => { this.#value = this.#fit(numeric); }, silent);\n }\n\n setEnabled(enabled, { silent = false } = {}) {\n return this.#commit(() => { this.#enabled = Boolean(enabled); }, silent);\n }\n\n /** Change any of min/max/step; the value and the default are refitted into the new range. */\n setRange({ min, max, step } = {}, { silent = false } = {}) {\n return this.#commit(() => {\n this.#min = this.#isFiniteInput(min) ? Number(min) : this.#min;\n this.#max = Math.max(this.#min, this.#isFiniteInput(max) ? Number(max) : this.#max);\n this.#step = this.#coercePositiveNumber(step, this.#step);\n this.#value = this.#fit(this.#value);\n if (this.#hasDefault) {\n this.#defaultValue = this.#fit(this.#defaultValue);\n }\n if (this.sliderInput) {\n this.#writeRangeAttributes();\n }\n }, silent);\n }\n\n /** Restore defaultValue and report it, a commit like a drag release. */\n reset({ silent = false } = {}) {\n if (!this.#hasDefault) {\n return false;\n }\n return this.#commit(() => { this.#value = this.#defaultValue; }, silent);\n }\n\n dispose() {\n this._disposers.forEach((dispose) => {\n try {\n dispose?.();\n } catch (error) {\n this.logger?.warn?.('twm-slider-field', 'Failed to dispose slider listener', { error });\n }\n });\n this._disposers = [];\n this.root = null;\n this.sliderInput = null;\n this.numberInput = null;\n this.readoutEl = null;\n this.resetButton = null;\n this.toggleInput = null;\n this.helperEl = null;\n }\n\n #buildToggle() {\n this.toggleInput = document.createElement('input');\n this.toggleInput.type = 'checkbox';\n this.toggleInput.className = 'twm-slider-field__toggle';\n this.toggleInput.setAttribute('aria-label', 'Enabled');\n if (this.field.disabled) {\n this.toggleInput.disabled = true;\n }\n this.#listen(this.toggleInput, 'change', () => this.setEnabled(this.toggleInput.checked));\n return this.toggleInput;\n }\n\n #buildNumberInput() {\n this.numberInput = document.createElement('input');\n this.numberInput.type = 'text';\n this.numberInput.inputMode = 'decimal';\n this.numberInput.className = 'twm-slider-field__number';\n this.numberInput.setAttribute('aria-label', 'Value');\n // A typed value that is not a finite number is refused and the box shows the value again.\n const commitTyped = () => {\n if (!this.setValue(this.numberInput.value.trim())) {\n this.#syncCompanions();\n }\n };\n this.#listen(this.numberInput, 'keydown', (event) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n commitTyped();\n } else if (event.key === 'Escape') {\n this.#syncCompanions();\n }\n });\n this.#listen(this.numberInput, 'change', commitTyped);\n return this.numberInput;\n }\n\n #buildResetButton() {\n this.resetButton = document.createElement('button');\n this.resetButton.type = 'button';\n this.resetButton.className = 'twm-slider-field__reset';\n this.resetButton.title = 'Reset to default';\n this.resetButton.setAttribute('aria-label', 'Reset to default');\n const icon = document.createElement('span');\n icon.className = 'material-symbols-outlined';\n icon.textContent = 'restart_alt';\n this.resetButton.appendChild(icon);\n this.#listen(this.resetButton, 'click', () => this.reset());\n return this.resetButton;\n }\n\n /** Apply a change, refresh the DOM, and report once if the reported value moved. */\n #commit(apply, silent) {\n const before = this.getValue();\n apply();\n this.#syncCompanions();\n const after = this.getValue();\n if (after === before) {\n return false;\n }\n if (!silent) {\n this.onChange?.(after, { immediate: false });\n }\n return true;\n }\n\n /** Write the model into every element: slider, box, readout, toggle, states. */\n #syncCompanions() {\n if (!this.root) return;\n const text = String(this.#value);\n if (this.sliderInput.value !== text) {\n this.sliderInput.value = text;\n }\n const off = !this.#enabled;\n const hardDisabled = Boolean(this.field.disabled);\n this.sliderInput.disabled = hardDisabled || off;\n if (this.numberInput) {\n this.numberInput.value = text;\n this.numberInput.disabled = hardDisabled || off;\n }\n if (this.readoutEl) {\n const format = typeof this.field.readout === 'function' ? this.field.readout : null;\n this.readoutEl.textContent = format ? String(format(this.#value)) : text;\n }\n if (this.toggleInput) {\n this.toggleInput.checked = this.#enabled;\n }\n const modified = this.isModified();\n if (this.resetButton) {\n this.resetButton.disabled = hardDisabled || off || !modified;\n }\n this.root.classList.toggle('twm-slider-field--modified', modified);\n this.root.classList.toggle('twm-slider-field--off', off);\n }\n\n #writeRangeAttributes() {\n this.sliderInput.min = String(this.#min);\n this.sliderInput.max = String(this.#max);\n this.sliderInput.step = String(this.#step);\n this.sliderInput.value = String(this.#value);\n }\n\n /** Clamp to [min, max] and snap to the step grid anchored at min, as a range input does. */\n #fit(value) {\n const clamped = Math.min(this.#max, Math.max(this.#min, value));\n let snapped = this.#min + Math.round((clamped - this.#min) / this.#step) * this.#step;\n if (snapped > this.#max) snapped -= this.#step;\n const decimals = Math.max(this.#decimals(this.#step), this.#decimals(this.#min));\n return Number(snapped.toFixed(Math.min(decimals, 12)));\n }\n\n #decimals(value) {\n const text = String(value);\n if (text.includes('e-')) return Number(text.split('e-')[1]);\n const dot = text.indexOf('.');\n return dot === -1 ? 0 : text.length - dot - 1;\n }\n\n #isFiniteInput(value) {\n if (value === null || value === undefined || typeof value === 'boolean') {\n return false;\n }\n if (typeof value === 'string' && value.trim() === '') {\n return false;\n }\n return Number.isFinite(Number(value));\n }\n\n #disabledValue() {\n return this.field.disabledValue === undefined ? null : this.field.disabledValue;\n }\n\n #listen(target, type, handler, options) {\n target.addEventListener(type, handler, options);\n this._disposers.push(() => target.removeEventListener(type, handler, options));\n }\n\n #coerceNumber(value, fallback) {\n const numeric = Number(value);\n return Number.isFinite(numeric) ? numeric : fallback;\n }\n\n #coercePositiveNumber(value, fallback) {\n const numeric = this.#coerceNumber(value, fallback);\n if (numeric <= 0) {\n return fallback;\n }\n return numeric;\n }\n}\n", "/**\n * table_state_store.js \u2014 persist DataTable view-state (sort, filters,\n * column widths), keyed by a caller-supplied `persistKey`.\n *\n * A FACTORY, not a singleton: the store reads and writes through a Host's\n * `state` capability (see ui/js/host/host.js) under one logical state key.\n * One blob holds a map of `{ [persistKey]: state }` for every persisted table.\n * Where that key lands on disk is the embedder's business, not ours \u2014 it is\n * decided by the host's `resolvePath`.\n *\n * A host without a `state` capability is legal: tables simply stay ephemeral.\n *\n * The in-memory cache must be dropped when the project changes (the app swaps\n * projects in-place without a page reload) \u2014 `reset()` is wired to the\n * `project:opened` event in app_bootstrap.\n */\n\n/**\n * @param {object} opts\n * @param {object} opts.host a Host. May lack `state` -> tables become ephemeral.\n * @param {string} opts.key logical state key, e.g. 'datatable_state'\n * @param {object} [opts.logger]\n * @param {number} [opts.debounceMs=500]\n */\nexport function createTableStateStore({ host, key, logger = console, debounceMs = 500 }) {\n if (!key) throw new Error('createTableStateStore requires { key }');\n const state = host?.state || null;\n\n let cache = null; // { [persistKey]: state } \u2014 null until first load\n let loadPromise = null;\n let saveTimer = null;\n\n const scheduleSave = () => {\n if (saveTimer) clearTimeout(saveTimer);\n saveTimer = setTimeout(async () => {\n saveTimer = null;\n if (!state || !cache) return;\n try { await state.write(key, cache); }\n catch (err) { logger.warn?.('[table-state] save failed', err); }\n }, debounceMs);\n };\n\n return {\n /** Resolve once the persisted blob has been read into the cache. Safe\n * to call repeatedly \u2014 the read happens at most once per project. */\n ready() {\n if (loadPromise) return loadPromise;\n loadPromise = (async () => {\n if (!state) { cache = {}; return cache; }\n try { cache = (await state.read(key)) || {}; }\n catch (err) { logger.warn?.('[table-state] load failed', err); cache = {}; }\n return cache;\n })();\n return loadPromise;\n },\n\n /** Synchronous read of a table's persisted state. Returns null until\n * the cache is loaded (await `ready()` first to be sure). */\n get(k) {\n if (!k || !cache) return null;\n return cache[k] || null;\n },\n\n /** Merge-and-persist a table's state (debounced). Pass null to forget\n * a key. Writes the whole map back atomically through the host. */\n set(k, s) {\n if (!k) return;\n if (!cache) cache = {};\n if (s == null) delete cache[k]; else cache[k] = s;\n scheduleSave();\n },\n\n /** Drop the cache + pending read so the next access reloads from the\n * newly-opened project. Cancels any in-flight save for the old one. */\n reset() {\n cache = null;\n loadPromise = null;\n if (saveTimer) { clearTimeout(saveTimer); saveTimer = null; }\n },\n };\n}\n", "/**\n * tag_input.js \u2014 A LIST OF SHORT STRINGS, drawn as removable chips followed by\n * a text box. (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\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 [baseline \u00D7] [stress \u00D7] [q3 \u00D7] Add a tag\u2026 \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\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 * The text box commits what was typed \u2014 trimmed, split at commas \u2014 on Enter,\n * on a comma and when it loses focus. Empty pieces are dropped, and so is a\n * piece already in the list unless `allowDuplicates`. Backspace in an empty\n * box removes the last chip. A paste that carries a comma is split into\n * chips at once; a paste without one is ordinary text in the box.\n *\n * Every chip has a remove button with an `aria-label` (`removeLabel(tag)`,\n * \"Remove <tag>\" by default). `readOnly` draws the chips alone: no remove\n * buttons and no text box.\n *\n * `onChange(list)` is called with a fresh copy of the list after every change\n * the reader makes \u2014 never for `setValue`, and never for a commit that added\n * nothing.\n *\n * const tags = createTagInput(host, {\n * value: ['baseline'],\n * placeholder: 'Add a tag\u2026',\n * onChange: (list) => save(list),\n * });\n * tags.getValue(); // ['baseline']\n * tags.setValue(['a', 'b']);\n * tags.dispose();\n */\n\n/** The list as strings, the empty ones left out. */\nconst normalise = (list) => (Array.isArray(list) ? list : [])\n .map((v) => (v == null ? '' : String(v).trim()))\n .filter((v) => v !== '');\n\n/**\n * @typedef {Object} TagInputOptions\n * @property {string[]} [value] - The tags it opens with.\n * @property {string} [placeholder] - The empty text box's placeholder.\n * @property {boolean} [readOnly] - Chips only: no remove buttons, no text box.\n * @property {boolean} [allowDuplicates] - Keep a tag that is already in the list.\n * @property {(list: string[]) => void} [onChange] - After each change the reader makes.\n * @property {string} [label] - The text box's accessible name.\n * @property {(tag: string) => string} [removeLabel] - A remove button's `aria-label`.\n * @property {string} [className] - Extra classes on the root.\n */\n\n/**\n * @param {HTMLElement} host\n * @param {TagInputOptions} [options]\n */\nexport function createTagInput(host, options = {}) {\n if (!host || typeof host.appendChild !== 'function') {\n throw new Error('[TagInput] host must be an HTMLElement');\n }\n const readOnly = !!options.readOnly;\n const allowDuplicates = !!options.allowDuplicates;\n const removeLabel = typeof options.removeLabel === 'function'\n ? options.removeLabel : (tag) => `Remove ${tag}`;\n\n let tags = normalise(options.value);\n let disposed = false;\n\n const root = document.createElement('div');\n root.className = ['twm-tag-input', readOnly ? 'twm-tag-input--readonly' : '', options.className || '']\n .join(' ').replace(/\\s+/g, ' ').trim();\n root.setAttribute('role', 'group');\n if (options.label) root.setAttribute('aria-label', options.label);\n\n const chips = document.createElement('ul');\n chips.className = 'twm-tag-input__chips';\n root.appendChild(chips);\n\n let input = null;\n if (!readOnly) {\n input = document.createElement('input');\n input.type = 'text';\n input.className = 'twm-tag-input__input';\n input.spellcheck = false;\n input.autocomplete = 'off';\n if (options.placeholder) input.placeholder = options.placeholder;\n if (options.label) input.setAttribute('aria-label', options.label);\n root.appendChild(input);\n }\n\n const changed = () => {\n if (typeof options.onChange === 'function') options.onChange([...tags]);\n };\n\n const chipFor = (tag, idx) => {\n const chip = document.createElement('li');\n chip.className = 'twm-tag-input__chip';\n const text = document.createElement('span');\n text.className = 'twm-tag-input__text';\n text.textContent = tag;\n text.title = tag;\n chip.appendChild(text);\n if (!readOnly) {\n const remove = document.createElement('button');\n remove.type = 'button';\n remove.className = 'twm-tag-input__remove';\n remove.setAttribute('aria-label', removeLabel(tag));\n remove.textContent = '\u00D7';\n // The text box keeps the focus: a blur would commit its text\n // and redraw the chips under the pointer before the click.\n remove.addEventListener('mousedown', (ev) => ev.preventDefault());\n remove.addEventListener('click', (ev) => {\n ev.preventDefault();\n ev.stopPropagation();\n removeAt(idx);\n input?.focus();\n });\n chip.appendChild(remove);\n }\n return chip;\n };\n\n /** Redraws every chip. */\n const paint = () => {\n chips.replaceChildren(...tags.map(chipFor));\n };\n\n function removeAt(idx) {\n if (disposed || readOnly || idx < 0 || idx >= tags.length) return;\n tags = tags.filter((_, i) => i !== idx);\n paint();\n changed();\n }\n\n /** Adds the comma-separated pieces of `text`; true when any was added. */\n const commitText = (text) => {\n if (disposed || readOnly) return false;\n const next = [...tags];\n for (const piece of String(text).split(',')) {\n const tag = piece.trim();\n if (tag === '') continue;\n if (!allowDuplicates && next.includes(tag)) continue;\n next.push(tag);\n }\n if (next.length === tags.length) return false;\n // Only the new chips are drawn: the ones already there stay in place,\n // so a remove button that the focus is moving to (Tab out of the box\n // commits its text) is still in the document when the focus lands.\n const added = next.slice(tags.length).map((tag, i) => chipFor(tag, tags.length + i));\n tags = next;\n chips.append(...added);\n changed();\n return true;\n };\n\n const commitInput = () => {\n if (!input) return;\n const text = input.value;\n input.value = '';\n commitText(text);\n };\n\n if (input) {\n input.addEventListener('keydown', (ev) => {\n if (ev.isComposing) return;\n if (ev.key === 'Enter' || ev.key === ',') {\n ev.preventDefault();\n commitInput();\n } else if (ev.key === 'Backspace' && input.value === '' && tags.length) {\n ev.preventDefault();\n removeAt(tags.length - 1);\n }\n });\n // A comma that arrives without its keydown (a soft keyboard, an IME,\n // a drop) commits all the same.\n input.addEventListener('input', () => {\n if (input.value.includes(',')) commitInput();\n });\n input.addEventListener('blur', commitInput);\n input.addEventListener('paste', (ev) => {\n const pasted = ev.clipboardData?.getData('text/plain') ?? '';\n if (!pasted.includes(',')) return;\n ev.preventDefault();\n const start = input.selectionStart ?? input.value.length;\n const end = input.selectionEnd ?? start;\n const text = input.value.slice(0, start) + pasted + input.value.slice(end);\n input.value = '';\n commitText(text);\n });\n root.addEventListener('mousedown', (ev) => {\n if (ev.target === root || ev.target === chips) {\n ev.preventDefault();\n input.focus();\n }\n });\n }\n\n paint();\n host.appendChild(root);\n\n return {\n element: root,\n input,\n getValue: () => [...tags],\n /** Replaces the list. Does not call `onChange`. */\n setValue(list) {\n if (disposed) return;\n tags = normalise(list);\n paint();\n },\n focus() { input?.focus(); },\n dispose() {\n if (disposed) return;\n disposed = true;\n root.remove();\n },\n };\n}\n", "/**\n * toast.js \u2014 thin wrapper around the mounted NotificationCenter for\n * callers that don't already hold an eventBus reference.\n *\n * The NotificationCenter (../notification_center.js) subscribes to\n * `toast:show` on its event bus; these helpers emit the same payload shape\n * on the bus they were given. They read no global: `NotificationCenter.mount()`\n * hands its bus to `setToastBus()`, and `dispose()` takes it back. An embedder\n * that wants toasts on some other bus calls `setToastBus(bus)` itself, and\n * `setToastBus(null)` to stop.\n *\n * Usage:\n * import { toastError, toastSuccess, toastWarn, toastInfo } from './toast.js';\n * toastError('Save failed', 'the server refused the change');\n *\n * The 1-arg form treats the string as the message (no title); the\n * 2-arg form is title + message. With no bus (no NotificationCenter mounted\n * yet, isolated test pages) the message goes to the console and nothing throws.\n */\n\nlet toastBus = null;\n\n/**\n * Route the toast helpers to `bus` (anything with `emit(name, payload)`), or\n * to the console with `null`. Returns the bus that was set before.\n */\nexport function setToastBus(bus) {\n const prev = toastBus;\n toastBus = bus && typeof bus.emit === 'function' ? bus : null;\n return prev;\n}\n\n/** The bus the toast helpers currently emit on, or null. */\nexport function getToastBus() {\n return toastBus;\n}\n\nfunction _emit(severity, persistent, titleOrMsg, msg) {\n const bus = toastBus;\n const title = (msg !== undefined) ? titleOrMsg : null;\n const message = (msg !== undefined) ? msg : titleOrMsg;\n if (!bus) {\n // Fall back to console so the message isn't lost if the bus is\n // unavailable (early bootstrap, isolated test pages).\n // eslint-disable-next-line no-console\n (severity === 'error' || severity === 'warn' ? console.warn : console.info)(\n `[toast/${severity}]`, title ? `${title}:` : '', message);\n return;\n }\n bus.emit('toast:show', {\n title, message, severity,\n persistent,\n durationMs: persistent ? 0 : 5000,\n });\n}\n\nexport function toastError(titleOrMsg, msg) { _emit('error', true, titleOrMsg, msg); }\nexport function toastWarn(titleOrMsg, msg) { _emit('warn', false, titleOrMsg, msg); }\nexport function toastInfo(titleOrMsg, msg) { _emit('info', false, titleOrMsg, msg); }\nexport function toastSuccess(titleOrMsg, msg) { _emit('success', false, titleOrMsg, msg); }\n\n/** Coerce a bridge-call result/exception into a user-facing error toast.\n * Drops the toast only if `res?.ok === false` *or* an exception was caught.\n * Returns true if the call succeeded (caller can continue), false otherwise. */\nexport function reportBridgeError(opName, resOrErr) {\n if (!resOrErr) return true;\n if (resOrErr instanceof Error) {\n toastError(opName, resOrErr.message || String(resOrErr));\n return false;\n }\n if (resOrErr && resOrErr.ok === false) {\n toastError(opName, resOrErr.error || 'operation refused');\n return false;\n }\n return true;\n}\n", "/**\n * Tree View Component\n *\n * A reusable hierarchical tree view component for displaying nested data.\n * Used by Functions Page (modules/functions) and Data Page (datasets/series).\n *\n * Structure:\n * - TreeView: Container for multiple categories\n * - TreeCategory: Top-level collapsible group (e.g., \"Built-in\", \"Project\")\n * - TreeNode: Expandable node with children (e.g., module, dataset)\n * - TreeItem: Leaf item (e.g., function, series)\n */\n\n/**\n * Labels, subtitles and badge text are TEXT, set with `textContent` after the\n * skeleton is built (BUG-0013): a dataset called 'A <b>B</b>' is shown as\n * those characters, and a name carrying `<img onerror>` runs nothing.\n */\nfunction setText(root, selector, value) {\n const el = root.querySelector(selector);\n if (el) el.textContent = value == null ? '' : String(value);\n}\n\n/**\n * An id as the value of a double-quoted attribute selector (BUG-0013).\n * NOT `CSS.escape`: jsdom does not provide it (see modal.js). Inside a quoted\n * attribute value `\"` and `\\` are escaped, and a line break, which would end\n * the string, becomes its hex escape.\n */\nfunction attrValue(value) {\n return String(value)\n .replace(/[\"\\\\]/g, '\\\\$&')\n .replace(/[\\n\\r\\f]/g, (c) => `\\\\${c.charCodeAt(0).toString(16)} `);\n}\n\n/**\n * Create a tree category (top-level collapsible section)\n * @param {Object} options - Category options\n * @param {string} options.id - Unique category ID\n * @param {string} options.label - Display label\n * @param {string} [options.icon] - Material icon name\n * @param {string} [options.iconClass] - Additional icon CSS class\n * @param {number} [options.count] - Item count to display\n * @param {boolean} [options.expanded=false] - Initial expanded state\n * @param {boolean} [options.readonly=false] - Whether items are readonly\n * @returns {HTMLElement} - Category element\n */\nexport function createTreeCategory(options) {\n const {\n id,\n label,\n icon = 'folder',\n iconClass = '',\n count = 0,\n expanded = false,\n readonly = false,\n } = options;\n\n const node = document.createElement('div');\n node.className = 'twm-collapsible-box twm-tree-category';\n node.dataset.categoryId = id;\n node.dataset.collapsibleId = `tree-category-${id}`;\n node.dataset.collapsibleDefault = expanded ? 'expanded' : 'collapsed';\n if (readonly) node.dataset.readonly = 'true';\n\n node.innerHTML = `\n <div class=\"twm-collapsible-header\" data-collapsible-header=\"true\">\n <button class=\"twm-arrow-toggle\" type=\"button\">\n <span class=\"twm-collapsible-arrow material-symbols-outlined${expanded ? '' : ' collapsed'}\">expand_more</span>\n </button>\n <span class=\"twm-tree-category__icon ${iconClass}\">\n <span class=\"material-symbols-outlined\">${icon}</span>\n </span>\n <span class=\"twm-tree-category__label\"></span>\n <span class=\"twm-tree-category__count\">(${count})</span>\n </div>\n <div class=\"twm-collapsible-content${expanded ? ' visible' : ''}\" data-collapsible-content=\"true\"></div>\n `;\n setText(node, '.twm-tree-category__label', label);\n\n return node;\n}\n\n/**\n * Create a tree node (expandable container with children)\n * @param {Object} options - Node options\n * @param {string} options.id - Unique node ID\n * @param {string} options.label - Display label\n * @param {string} [options.icon] - Material icon name (optional)\n * @param {number} [options.count] - Child count to display\n * @param {boolean} [options.expanded=false] - Initial expanded state\n * @param {boolean} [options.readonly=false] - Whether node is readonly\n * @param {Object} [options.actions] - Action buttons config\n * @returns {HTMLElement} - Node element\n */\nexport function createTreeNode(options) {\n const {\n id,\n label,\n icon = null,\n count = 0,\n expanded = false,\n readonly = false,\n actions = null,\n } = options;\n\n const node = document.createElement('div');\n node.className = `twm-tree-node${readonly ? ' readonly' : ''}`;\n node.dataset.nodeId = id;\n\n const iconHtml = icon\n ? `<span class=\"twm-tree-node__icon\"><span class=\"material-symbols-outlined\">${icon}</span></span>`\n : '';\n\n const actionsHtml = actions ? '<span class=\"twm-tree-node__actions\"></span>' : '';\n\n node.innerHTML = `\n <div class=\"twm-tree-node__header\">\n <span class=\"twm-tree-node__toggle\">\n <span class=\"material-symbols-outlined\">${expanded ? 'expand_more' : 'chevron_right'}</span>\n </span>\n ${iconHtml}\n <span class=\"twm-tree-node__label\"></span>\n <span class=\"twm-tree-node__count\">(${count})</span>\n ${actionsHtml}\n </div>\n <div class=\"twm-tree-node__children\" style=\"display: ${expanded ? 'block' : 'none'};\"></div>\n `;\n setText(node, '.twm-tree-node__label', label);\n\n // Add action buttons if specified\n if (actions) {\n const actionsEl = node.querySelector('.twm-tree-node__actions');\n Object.entries(actions).forEach(([actionId, actionConfig]) => {\n const btn = document.createElement('button');\n btn.className = 'twm-tree-node__action-btn';\n btn.dataset.action = actionId;\n btn.title = actionConfig.title || actionId;\n btn.innerHTML = `<span class=\"material-symbols-outlined\">${actionConfig.icon}</span>`;\n if (actionConfig.onClick) {\n btn.addEventListener('click', (e) => {\n e.stopPropagation();\n actionConfig.onClick(id, e);\n });\n }\n actionsEl.appendChild(btn);\n });\n }\n\n return node;\n}\n\n/**\n * Create a tree item (leaf node)\n * @param {Object} options - Item options\n * @param {string} options.id - Unique item ID\n * @param {string} options.label - Display label\n * @param {string} [options.icon] - Material icon or symbol (e.g., '\u0192', 'insights')\n * @param {boolean} [options.isMaterialIcon=true] - Whether icon is Material icon\n * @param {boolean} [options.readonly=false] - Whether item is readonly\n * @param {boolean} [options.selected=false] - Whether item is selected\n * @param {string} [options.subtitle] - Optional subtitle text\n * @param {Object} [options.data] - Additional data to attach\n * @param {Object} [options.badge] - Optional badge config\n * @param {string} [options.badge.text] - Badge text (if empty, renders as status dot)\n * @param {string} [options.badge.variant] - 'muted'|'pass'|'fail'|'error'\n * @returns {HTMLElement} - Item element\n */\nexport function createTreeItem(options) {\n const {\n id,\n label,\n icon = null,\n isMaterialIcon = true,\n readonly = false,\n selected = false,\n subtitle = null,\n data = null,\n badge = null,\n } = options;\n\n const item = document.createElement('div');\n item.className = `twm-tree-item${readonly ? ' readonly' : ''}${selected ? ' selected' : ''}`;\n item.dataset.itemId = id;\n\n // Attach custom data\n if (data) {\n Object.entries(data).forEach(([key, value]) => {\n item.dataset[key] = value;\n });\n }\n\n const iconHtml = icon\n ? isMaterialIcon\n ? `<span class=\"twm-tree-item__icon\"><span class=\"material-symbols-outlined\">${icon}</span></span>`\n : `<span class=\"twm-tree-item__icon twm-tree-item__icon--symbol\">${icon}</span>`\n : '';\n\n const subtitleHtml = subtitle\n ? '<span class=\"twm-tree-item__subtitle\"></span>'\n : '';\n\n let badgeHtml = '';\n if (badge) {\n const variant = badge.variant || 'muted';\n if (badge.text) {\n badgeHtml = `<span class=\"twm-tree-item__badge twm-tree-item__badge--${variant}\"></span>`;\n } else {\n badgeHtml = `<span class=\"twm-tree-item__status-dot twm-tree-item__status-dot--${variant}\"></span>`;\n }\n }\n\n item.innerHTML = `\n ${iconHtml}\n <span class=\"twm-tree-item__label\"></span>\n ${subtitleHtml}\n ${badgeHtml}\n `;\n setText(item, '.twm-tree-item__label', label);\n if (subtitle) setText(item, '.twm-tree-item__subtitle', subtitle);\n if (badge?.text) setText(item, '.twm-tree-item__badge', badge.text);\n\n return item;\n}\n\n/**\n * Toggle a collapsible category\n * @param {HTMLElement} categoryEl - Category element\n * @param {boolean} [force] - Force specific state (true = expand, false = collapse)\n */\nexport function toggleCategory(categoryEl, force) {\n if (!categoryEl) return;\n\n const arrow = categoryEl.querySelector(':scope > .twm-collapsible-header .twm-collapsible-arrow');\n const content = categoryEl.querySelector(':scope > .twm-collapsible-content');\n\n if (!content) return;\n\n // Determine whether we should expand\n // force=true means expand, force=false means collapse, undefined means toggle\n const isCurrentlyExpanded = content.classList.contains('visible');\n const shouldExpand = force !== undefined ? force : !isCurrentlyExpanded;\n\n if (shouldExpand) {\n // Expand\n if (arrow) {\n arrow.classList.remove('collapsed');\n }\n content.classList.add('visible');\n } else {\n // Collapse\n if (arrow) {\n arrow.classList.add('collapsed');\n }\n content.classList.remove('visible');\n }\n}\n\n/**\n * Toggle a tree node\n * @param {HTMLElement} nodeEl - Node element\n * @param {boolean} [force] - Force specific state\n */\nexport function toggleNode(nodeEl, force) {\n if (!nodeEl) return;\n\n const toggle = nodeEl.querySelector(':scope > .twm-tree-node__header .twm-tree-node__toggle .material-symbols-outlined');\n const children = nodeEl.querySelector(':scope > .twm-tree-node__children');\n\n if (!children) return;\n\n const isExpanded = force !== undefined\n ? force\n : children.style.display === 'none';\n\n if (isExpanded) {\n children.style.display = 'block';\n if (toggle) toggle.textContent = 'expand_more';\n } else {\n children.style.display = 'none';\n if (toggle) toggle.textContent = 'chevron_right';\n }\n}\n\n/**\n * Filter tree items by text match\n *\n * An item is shown when its label contains the filter. A node or a category is\n * shown when any tree item inside it is shown, whether the item sits directly\n * in it or deeper inside nodes. An empty filter shows everything, so clearing\n * the filter restores the whole tree, empty nodes and categories included.\n *\n * @param {HTMLElement} container - Tree container\n * @param {string} filter - Filter text (case-insensitive)\n * @param {Object} [options] - Filter options\n * @param {boolean} [options.expandMatches=true] - Auto-expand nodes with matches\n */\nexport function filterTree(container, filter, options = {}) {\n const { expandMatches = true } = options;\n const normalizedFilter = (filter || '').toLowerCase().trim();\n\n const visibleItems = new Set();\n container.querySelectorAll('.twm-tree-item').forEach((item) => {\n const label = item.querySelector('.twm-tree-item__label')?.textContent || '';\n const matches = !normalizedFilter || label.toLowerCase().includes(normalizedFilter);\n item.style.display = matches ? '' : 'none';\n item.classList.toggle('twm-filter-match', matches && !!normalizedFilter);\n if (matches) visibleItems.add(item);\n });\n\n const hasVisibleItem = (el) => !normalizedFilter\n || [...el.querySelectorAll('.twm-tree-item')].some((item) => visibleItems.has(item));\n\n container.querySelectorAll('.twm-tree-node').forEach((node) => {\n const visible = hasVisibleItem(node);\n node.style.display = visible ? '' : 'none';\n if (expandMatches && visible && normalizedFilter) toggleNode(node, true);\n });\n\n container.querySelectorAll('.twm-tree-category').forEach((category) => {\n const visible = hasVisibleItem(category);\n category.style.display = visible ? '' : 'none';\n if (expandMatches && visible && normalizedFilter) toggleCategory(category, true);\n });\n}\n\n/**\n * Select a tree item\n * @param {HTMLElement} container - Tree container\n * @param {string} itemId - Item ID to select\n * @param {Object} [options] - Selection options\n * @param {boolean} [options.scrollIntoView=true] - Scroll item into view\n * @param {boolean} [options.expandParents=true] - Expand parent nodes\n */\nexport function selectItem(container, itemId, options = {}) {\n const { scrollIntoView = true, expandParents = true } = options;\n\n // Deselect all\n container.querySelectorAll('.twm-tree-item.selected').forEach((el) => {\n el.classList.remove('selected');\n });\n\n // Find and select item\n const item = container.querySelector(`.twm-tree-item[data-item-id=\"${attrValue(itemId)}\"]`);\n if (!item) return null;\n\n item.classList.add('selected');\n\n // Expand parent nodes\n if (expandParents) {\n let parent = item.parentElement;\n while (parent && parent !== container) {\n if (parent.classList.contains('twm-tree-node__children')) {\n const node = parent.closest('.twm-tree-node');\n if (node) toggleNode(node, true);\n }\n if (parent.classList.contains('twm-collapsible-content')) {\n const category = parent.closest('.twm-tree-category');\n if (category) toggleCategory(category, true);\n }\n parent = parent.parentElement;\n }\n }\n\n // Scroll into view\n if (scrollIntoView) {\n item.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }\n\n return item;\n}\n\n/**\n * TreeView class for managing a complete tree structure\n */\nexport class TreeView {\n constructor(container, options = {}) {\n this.container = container;\n this.options = {\n onItemClick: null,\n onItemDoubleClick: null,\n onNodeToggle: null,\n onCategoryToggle: null,\n ...options,\n };\n\n this._boundHandleClick = this._handleClick.bind(this);\n this._boundHandleDblClick = this._handleDoubleClick.bind(this);\n\n if (container) {\n container.classList.add('twm-tree-view');\n container.addEventListener('click', this._boundHandleClick);\n container.addEventListener('dblclick', this._boundHandleDblClick);\n }\n }\n\n _handleClick(e) {\n // Handle category toggle\n const collapsibleHeader = e.target.closest('.twm-collapsible-header');\n if (collapsibleHeader) {\n const category = collapsibleHeader.closest('.twm-tree-category');\n if (category) {\n toggleCategory(category);\n this.options.onCategoryToggle?.(category.dataset.categoryId, category);\n }\n return;\n }\n\n // Handle node toggle\n const nodeHeader = e.target.closest('.twm-tree-node__header');\n if (nodeHeader) {\n const node = nodeHeader.closest('.twm-tree-node');\n if (node) {\n toggleNode(node);\n this.options.onNodeToggle?.(node.dataset.nodeId, node);\n }\n return;\n }\n\n // Handle item click\n const item = e.target.closest('.twm-tree-item');\n if (item) {\n this.select(item.dataset.itemId);\n this.options.onItemClick?.(item.dataset.itemId, item, e);\n }\n }\n\n _handleDoubleClick(e) {\n const item = e.target.closest('.twm-tree-item');\n if (item) {\n this.options.onItemDoubleClick?.(item.dataset.itemId, item, e);\n }\n }\n\n addCategory(options) {\n const category = createTreeCategory(options);\n this.container.appendChild(category);\n return category;\n }\n\n addNode(categoryId, options) {\n const category = this.container.querySelector(`.twm-tree-category[data-category-id=\"${attrValue(categoryId)}\"]`);\n const content = category?.querySelector('.twm-collapsible-content');\n if (!content) return null;\n\n const node = createTreeNode(options);\n content.appendChild(node);\n return node;\n }\n\n addItem(nodeId, options) {\n const node = this.container.querySelector(`.twm-tree-node[data-node-id=\"${attrValue(nodeId)}\"]`);\n const children = node?.querySelector('.twm-tree-node__children');\n if (!children) return null;\n\n const item = createTreeItem(options);\n children.appendChild(item);\n return item;\n }\n\n select(itemId) {\n return selectItem(this.container, itemId);\n }\n\n filter(text) {\n filterTree(this.container, text);\n }\n\n clear() {\n this.container.innerHTML = '';\n }\n\n dispose() {\n if (this.container) {\n this.container.removeEventListener('click', this._boundHandleClick);\n this.container.removeEventListener('dblclick', this._boundHandleDblClick);\n }\n }\n}\n\nexport default TreeView;\n", "/**\n * WindowTaskbar - Singleton component that manages minimized windows in the global bottom bar.\n *\n * Listens for window events and renders taskbar buttons for minimized windows.\n * Integrates with the existing global-bottom-bar element.\n */\n\nimport { ManagedWindow } from './managed_window.js';\n\nclass WindowTaskbarManager {\n constructor() {\n this._minimizedWindows = new Map(); // id -> { title, icon }\n this._containerEl = null;\n this._leftDivider = null;\n this._rightDivider = null;\n this._initialized = false;\n }\n\n /**\n * Initialize the taskbar. Call once after DOM is ready.\n */\n init() {\n if (this._initialized) return;\n\n // Find or create the container in the global bottom bar\n const bottomBar = document.querySelector('.twm-global-bottom-bar');\n if (!bottomBar) {\n console.warn('[WindowTaskbar] twm-global-bottom-bar not found');\n return;\n }\n\n // Create left divider (always present but hidden when no windows)\n this._leftDivider = document.createElement('div');\n this._leftDivider.className = 'twm-bar-windows__divider twm-bar-windows__divider--left';\n\n // Insert bar-windows container between bar-left and bar-center\n this._containerEl = document.createElement('div');\n this._containerEl.className = 'twm-bar-windows';\n\n // Create right divider (shown when there are windows)\n this._rightDivider = document.createElement('div');\n this._rightDivider.className = 'twm-bar-windows__divider twm-bar-windows__divider--right';\n\n const barCenter = bottomBar.querySelector('.twm-bar-center');\n if (barCenter) {\n bottomBar.insertBefore(this._rightDivider, barCenter);\n bottomBar.insertBefore(this._containerEl, this._rightDivider);\n bottomBar.insertBefore(this._leftDivider, this._containerEl);\n } else {\n bottomBar.appendChild(this._leftDivider);\n bottomBar.appendChild(this._containerEl);\n bottomBar.appendChild(this._rightDivider);\n }\n\n // Listen for window events\n window.addEventListener('managed-window-minimized', (e) => this._onWindowMinimized(e));\n window.addEventListener('managed-window-restored', (e) => this._onWindowRestored(e));\n window.addEventListener('managed-window-closed', (e) => this._onWindowClosed(e));\n\n this._initialized = true;\n this._updateDividers();\n }\n\n /**\n * Handle window minimized event.\n */\n _onWindowMinimized(e) {\n const { id, title, icon } = e.detail;\n this._minimizedWindows.set(id, { title, icon });\n this._render();\n }\n\n /**\n * Handle window restored event.\n */\n _onWindowRestored(e) {\n const { id } = e.detail;\n this._minimizedWindows.delete(id);\n this._render();\n }\n\n /**\n * Handle window closed event.\n */\n _onWindowClosed(e) {\n const { id } = e.detail;\n this._minimizedWindows.delete(id);\n this._render();\n }\n\n /**\n * Update divider visibility based on window count.\n */\n _updateDividers() {\n const hasWindows = this._minimizedWindows.size > 0;\n if (this._leftDivider) {\n this._leftDivider.style.display = hasWindows ? '' : 'none';\n }\n if (this._rightDivider) {\n this._rightDivider.style.display = hasWindows ? '' : 'none';\n }\n }\n\n /**\n * Render the taskbar buttons.\n */\n _render() {\n if (!this._containerEl) return;\n\n this._containerEl.innerHTML = '';\n\n for (const [id, { title, icon }] of this._minimizedWindows) {\n const btn = document.createElement('button');\n btn.className = 'twm-bar-windows__item';\n btn.setAttribute('data-window-id', id);\n btn.title = `Restore: ${title}`;\n\n // Add icon\n if (icon) {\n const iconEl = document.createElement('span');\n iconEl.className = 'twm-bar-windows__item-icon material-symbols-outlined';\n iconEl.textContent = icon;\n btn.appendChild(iconEl);\n }\n\n // Add title\n const titleEl = document.createElement('span');\n titleEl.className = 'twm-bar-windows__item-title';\n titleEl.textContent = title;\n btn.appendChild(titleEl);\n\n btn.addEventListener('click', () => {\n ManagedWindow.restore(id);\n });\n this._containerEl.appendChild(btn);\n }\n\n this._updateDividers();\n }\n}\n\n// Singleton instance\nexport const WindowTaskbar = new WindowTaskbarManager();\n", "/**\n * Wizard \u2014 a multi-step flow: a step indicator, a body slot and a footer with\n * Cancel, Back and Next/Finish, every step gated by its own `canAdvance`.\n *\n * Usage:\n * const wizard = new Wizard({\n * data: { file: null }, // yours; every hook sees it as ctx.data\n * steps: [\n * { id: 'source', label: 'Source', icon: 'upload_file',\n * render(bodyEl, ctx) { \u2026 ; return () => { \u2026 } }, // optional cleanup function\n * canAdvance: (ctx) => ctx.data.file\n * ? { ok: true } : { ok: false, hint: 'Choose a file first' } },\n * { id: 'review', label: 'Review', render(bodyEl, ctx) { \u2026 } },\n * ],\n * onFinish: async (ctx) => { \u2026 }, // rejects \u2192 the step shows the error\n * onCancel: (ctx) => { \u2026 },\n * });\n * wizard.mount(hostEl); // inline \u2026\n * wizard.openInWindow({ id: 'import', title: 'Import' }); // \u2026 or in a window\n *\n * Steps are drawn done / current / upcoming / error and joined by a connector.\n * A done (or errored) step BEFORE the current one is a button that jumps back;\n * a step after it is inert, so the only way forward is Next, through the gate.\n *\n * `canAdvance(ctx)` is asked whenever the footer is drawn, and `revalidate()`\n * draws it again \u2014 the body is rendered once per visit, never by a revalidate,\n * so an input the user is typing into keeps its focus and its value.\n *\n * Every move goes through a core StateMachine:\n *\n * step \u2500\u2500move\u2500\u2500\u25B6 step (guard: back to a visited step, or forward\n * \u2502 one step through the gate)\n * \u251C\u2500\u2500finish\u2500\u2500\u25B6 finishing \u2500\u2500resolve\u2500\u2500\u25B6 finished (closes)\n * \u2502 \u2502\n * \u2502 \u2514\u2500\u2500reject\u2500\u2500\u25B6 step (the step shows the error)\n * \u2514\u2500\u2500cancel\u2500\u2500\u25B6 cancelled (closes, calls onCancel)\n *\n * While `finishing`, every button is disabled and no move is accepted, so an\n * async finish cannot be raced by a click. `finished` and `cancelled` are final:\n * onCancel runs once however many times Cancel is pressed.\n *\n * State lives in this instance only; the DOM carries classes and ARIA, never a\n * data attribute.\n */\nimport { ComponentBase } from '../base/component_base.js';\nimport { StateMachine } from '../../core/state_machine.js';\nimport { ManagedWindow } from './managed_window.js';\n\nconst DEFAULT_LABELS = Object.freeze({\n back: 'Back',\n next: 'Next',\n finish: 'Finish',\n cancel: 'Cancel',\n});\n\nconst OPEN = 'step';\nconst FINISHING = 'finishing';\nconst FINISHED = 'finished';\nconst CANCELLED = 'cancelled';\n\n/** Steps own one override: an error and its message. Everything else about a\n * step's look follows from where it is relative to the current one. */\nconst STEP_STATES = Object.freeze(['error']);\n\nconst isFinal = (state) => state === FINISHED || state === CANCELLED;\n\n/** A step's render may hand back a cleanup function, run when the step is\n * left and on dispose(). */\nfunction runCleanup(cleanup) {\n if (typeof cleanup === 'function') cleanup();\n}\n\nfunction messageOf(err) {\n if (err && typeof err.message === 'string' && err.message) return err.message;\n return err == null ? 'Failed' : String(err);\n}\n\nexport class Wizard extends ComponentBase {\n\n /** @type {Array<object>} */ #steps;\n /** @type {object} */ #labels;\n /** @type {Function|null} */ #onFinish;\n /** @type {Function|null} */ #onCancel;\n /** @type {object} */ #ctx;\n /** @type {StateMachine} */ #machine;\n /** @type {number} */ #index = 0;\n /** @type {Map<string,{state:string,message:string}>} */ #overrides = new Map();\n /** @type {*} */ #cleanup = null;\n /** @type {Promise} */ #queue = Promise.resolve();\n /** @type {ManagedWindow|null} */ #window = null;\n /** @type {boolean} */ #disposed = false;\n\n /** @type {HTMLElement|null} */ #root = null;\n /** @type {HTMLElement[]} */ #stepItems = [];\n /** @type {HTMLButtonElement[]} */#stepButtons = [];\n /** @type {HTMLElement[]} */ #connectors = [];\n /** @type {HTMLElement|null} */ #body = null;\n /** @type {HTMLElement|null} */ #message = null;\n /** @type {HTMLButtonElement|null} */ #cancelBtn = null;\n /** @type {HTMLButtonElement|null} */ #backBtn = null;\n /** @type {HTMLButtonElement|null} */ #nextBtn = null;\n\n /**\n * @param {object} opts\n * @param {Array<{id:string,label:string,icon?:string,\n * render:(bodyEl:HTMLElement, ctx:object)=>(Function|void),\n * canAdvance?:(ctx:object)=>{ok:boolean,hint?:string}}>} opts.steps\n * @param {object} [opts.data={}] Your state; every hook reads it as `ctx.data`.\n * @param {Function} [opts.onFinish] `(ctx) => void|Promise`. A rejection marks the\n * current step as error with the rejection's message.\n * @param {Function} [opts.onCancel] `(ctx) => void`, called once when the wizard is cancelled.\n * @param {object} [opts.labels] `{back, next, finish, cancel}` button labels.\n * @param {object} [opts.eventBus] Passed to the StateMachine (its `fsm:*` events).\n * @param {object} [opts.logger] Passed to the StateMachine.\n */\n constructor({ steps, data = {}, onFinish = null, onCancel = null, labels = {},\n eventBus = null, logger = null } = {}) {\n super({ eventBus, logger });\n if (!Array.isArray(steps) || steps.length === 0) {\n throw new Error('Wizard requires at least one step');\n }\n const ids = new Set();\n for (const step of steps) {\n if (!step || typeof step.id !== 'string' || !step.id) {\n throw new Error('Wizard: every step needs a non-empty string id');\n }\n if (ids.has(step.id)) throw new Error(`Wizard: duplicate step id \"${step.id}\"`);\n if (typeof step.render !== 'function') {\n throw new Error(`Wizard: step \"${step.id}\" needs a render(bodyEl, ctx) function`);\n }\n ids.add(step.id);\n }\n this.#steps = steps.slice();\n this.#labels = { ...DEFAULT_LABELS, ...labels };\n this.#onFinish = onFinish;\n this.#onCancel = onCancel;\n\n const wizard = this;\n this.#ctx = Object.freeze({\n data,\n get step() { return wizard.currentStep; },\n get index() { return wizard.currentIndex; },\n revalidate: () => this.revalidate(),\n next: () => this.next(),\n back: () => this.back(),\n goTo: (target) => this.goTo(target),\n setStepState: (id, state, message) => this.setStepState(id, state, message),\n });\n\n this.#machine = new StateMachine({\n name: 'wizard',\n initialState: OPEN,\n eventBus,\n logger,\n states: {\n [OPEN]: {\n transitions: {\n move: {\n target: OPEN,\n guard: ({ payload }) => this.#canMoveTo(payload.to),\n action: ({ payload }) => this.#enterStep(payload.to),\n },\n finish: {\n target: FINISHING,\n guard: () => this.#isLast() && this.#gate().ok,\n action: () => { this.#overrides.delete(this.currentStep); },\n },\n cancel: { target: CANCELLED },\n },\n },\n [FINISHING]: {\n transitions: {\n resolve: { target: FINISHED },\n reject: {\n target: OPEN,\n action: ({ payload }) => {\n this.#overrides.set(this.currentStep,\n { state: 'error', message: messageOf(payload.error) });\n },\n },\n },\n },\n [FINISHED]: { onEnter: () => this.#close() },\n [CANCELLED]: {\n onEnter: () => {\n this.#close();\n this.#onCancel?.(this.#ctx);\n },\n },\n },\n });\n }\n\n // \u2500\u2500\u2500 Lifecycle \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 /**\n * Mount inline into `container` and render the first step.\n * @param {HTMLElement} container\n * @returns {Wizard}\n */\n mount(container) {\n if (this._mounted) return this;\n this.#build();\n container.appendChild(this.#root);\n this._mounted = true;\n this.#renderBody();\n this.#paint();\n return this;\n }\n\n /**\n * Mount in a ManagedWindow and show it. The window's close button and\n * Escape cancel the wizard (and are refused while a finish is running);\n * finishing or cancelling closes the window.\n * @param {object} [opts] ManagedWindow options: id, title, icon, defaultWidth,\n * defaultHeight, minWidth, minHeight, container, modal (default true).\n * @returns {ManagedWindow}\n */\n openInWindow({ id = 'twm-wizard', title = 'Wizard', icon, defaultWidth = 720,\n defaultHeight = 520, minWidth = 420, minHeight = 320,\n container, modal = true } = {}) {\n if (this._mounted) throw new Error('Wizard is already mounted');\n this.#build();\n this._mounted = true;\n this.#window = new ManagedWindow({\n id, title, icon, defaultWidth, defaultHeight, minWidth, minHeight,\n container, modal,\n content: this.#root,\n canMinimize: false,\n beforeClose: () => {\n if (isFinal(this.state)) return true;\n void this.cancel();\n return false;\n },\n });\n this.#window.show();\n this.#renderBody();\n this.#paint();\n return this.#window;\n }\n\n /** Tear down (and close the window, if any) without calling any callback.\n * Every later move, finish or cancel is refused. */\n dispose() {\n if (this.#disposed) return;\n this.#disposed = true;\n const win = this.#window;\n this.#teardown();\n win?.close({ force: true });\n super.dispose();\n }\n\n // \u2500\u2500\u2500 Public API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 wizard's root element (null before mount). */\n get element() { return this.#root; }\n\n /** The body slot the current step renders into. */\n get bodyElement() { return this.#body; }\n\n /** The ManagedWindow, when opened with `openInWindow`. */\n get window() { return this.#window; }\n\n /** The object every hook receives: `{data, step, index, revalidate, next, back, goTo, setStepState}`. */\n get context() { return this.#ctx; }\n\n /** The current step's id. */\n get currentStep() { return this.#steps[this.#index].id; }\n\n /** The current step's index. */\n get currentIndex() { return this.#index; }\n\n /** 'step' | 'finishing' | 'finished' | 'cancelled' (null for a moment after construction). */\n get state() { return this.#machine.getState(); }\n\n /** True while an async finish is running. */\n get busy() { return this.state === FINISHING; }\n\n /**\n * Ask the current step's `canAdvance` again and redraw the indicator and\n * the footer. The body is NOT re-rendered.\n */\n revalidate() {\n this.#paint();\n }\n\n /** Forward one step, if the current step's gate allows it. Resolves true when it moved. */\n next() {\n return this.#move(() => this.#index + 1);\n }\n\n /** Back one step. Resolves true when it moved. */\n back() {\n return this.#move(() => this.#index - 1);\n }\n\n /**\n * Move to a step by id or index: any step before the current one, or the\n * next one through the gate. Resolves true when it moved.\n * @param {string|number} target\n */\n goTo(target) {\n return this.#move(() => this.#resolveIndex(target));\n }\n\n /**\n * Mark a step as errored (`'error'`, with a message shown while it is the\n * current step), or clear the mark (`null`).\n * @param {string} id\n * @param {'error'|null} state\n * @param {string} [message]\n */\n setStepState(id, state, message = '') {\n const i = this.#resolveIndex(id);\n if (i < 0 || i >= this.#steps.length) throw new Error(`Wizard: no step \"${id}\"`);\n const key = this.#steps[i].id;\n if (state == null) this.#overrides.delete(key);\n else if (STEP_STATES.includes(state)) this.#overrides.set(key, { state, message: String(message ?? '') });\n else throw new Error(`Wizard: unknown step state \"${state}\" (expected 'error' or null)`);\n this.#paint();\n }\n\n /**\n * Run `onFinish` from the last step, if its gate allows. The buttons are\n * disabled until it settles; resolved, the wizard closes; rejected, the\n * step is marked as error with the message. Resolves true when it finished.\n */\n finish() {\n return this.#enqueue(async () => {\n if (this.state !== OPEN) return false;\n const { transitioned } = await this.#machine.transition('finish');\n if (!transitioned) return false;\n this.#paint();\n try {\n await this.#onFinish?.(this.#ctx);\n } catch (error) {\n await this.#machine.transition('reject', { error });\n this.#paint();\n return false;\n }\n await this.#machine.transition('resolve');\n return true;\n });\n }\n\n /**\n * Close the wizard and call `onCancel` \u2014 once. Refused while a finish is\n * running. Resolves true when it cancelled.\n */\n cancel() {\n return this.#enqueue(async () => {\n if (this.state !== OPEN) return false;\n const { transitioned } = await this.#machine.transition('cancel');\n return transitioned;\n });\n }\n\n // \u2500\u2500\u2500 Moves \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 /** Moves run one at a time, so a double click cannot start a transition\n * inside another. The target is computed when the move runs, not when it\n * was asked for. A request made while a finish is running (or after the\n * wizard closed) is refused there and then \u2014 it is not queued behind the\n * finish to run once it settles. */\n #enqueue(fn) {\n if (this.#disposed || this.busy || isFinal(this.state)) return Promise.resolve(false);\n const run = this.#queue.then(() => (this.#disposed ? false : fn()));\n this.#queue = run.catch(() => {});\n return run;\n }\n\n #move(targetOf) {\n return this.#enqueue(async () => {\n if (this.state !== OPEN) return false;\n const to = targetOf();\n if (!this.#canMoveTo(to)) return false;\n const { transitioned } = await this.#machine.transition('move', { to });\n this.#paint();\n return transitioned;\n });\n }\n\n #canMoveTo(to) {\n if (!Number.isInteger(to) || to < 0 || to >= this.#steps.length) return false;\n if (to < this.#index) return true;\n return to === this.#index + 1 && this.#gate().ok;\n }\n\n #enterStep(to) {\n this.#index = to;\n this.#renderBody();\n }\n\n #resolveIndex(target) {\n if (typeof target === 'number') return Number.isInteger(target) ? target : -1;\n return this.#steps.findIndex((s) => s.id === target);\n }\n\n #isLast() {\n return this.#index === this.#steps.length - 1;\n }\n\n /** The current step's gate, normalised to `{ok, hint}`. */\n #gate() {\n const step = this.#steps[this.#index];\n if (typeof step.canAdvance !== 'function') return { ok: true, hint: '' };\n const r = step.canAdvance(this.#ctx) ?? {};\n return { ok: r.ok === true, hint: typeof r.hint === 'string' ? r.hint : '' };\n }\n\n // \u2500\u2500\u2500 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\u2500\u2500\u2500\u2500\u2500\u2500\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 #build() {\n const root = document.createElement('div');\n root.className = 'twm-wizard';\n\n const steps = document.createElement('ol');\n steps.className = 'twm-wizard__steps';\n this.#steps.forEach((step, i) => {\n if (i > 0) {\n const connector = document.createElement('li');\n connector.className = 'twm-wizard__connector';\n connector.setAttribute('role', 'presentation');\n connector.setAttribute('aria-hidden', 'true');\n steps.appendChild(connector);\n this.#connectors.push(connector);\n }\n const item = document.createElement('li');\n item.className = 'twm-wizard__step';\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = 'twm-wizard__step-btn';\n const marker = document.createElement('span');\n marker.className = 'twm-wizard__step-marker';\n const label = document.createElement('span');\n label.className = 'twm-wizard__step-label';\n label.textContent = step.label ?? step.id;\n btn.append(marker, label);\n btn.addEventListener('click', () => this.#onStepClick(i));\n item.appendChild(btn);\n steps.appendChild(item);\n this.#stepItems.push(item);\n this.#stepButtons.push(btn);\n });\n\n this.#body = document.createElement('div');\n this.#body.className = 'twm-wizard__body';\n\n const footer = document.createElement('div');\n footer.className = 'twm-wizard__footer';\n this.#message = document.createElement('div');\n this.#message.className = 'twm-wizard__message';\n this.#message.setAttribute('aria-live', 'polite');\n\n const actions = document.createElement('div');\n actions.className = 'twm-wizard__actions';\n this.#cancelBtn = this.#button('twm-wizard__cancel', this.#labels.cancel, () => { void this.cancel(); });\n this.#backBtn = this.#button('twm-wizard__back', this.#labels.back, () => { void this.back(); });\n this.#nextBtn = this.#button('twm-wizard__next twm-btn--primary', this.#labels.next, () => {\n void (this.#isLast() ? this.finish() : this.next());\n });\n actions.append(this.#cancelBtn, this.#backBtn, this.#nextBtn);\n footer.append(this.#message, actions);\n\n root.append(steps, this.#body, footer);\n this.#root = root;\n }\n\n #button(cls, text, onClick) {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = `twm-btn ${cls}`;\n btn.textContent = text;\n btn.addEventListener('click', onClick);\n return btn;\n }\n\n #onStepClick(i) {\n if (i < this.#index) void this.goTo(i);\n }\n\n #renderBody() {\n runCleanup(this.#cleanup);\n this.#cleanup = null;\n this.#body.replaceChildren();\n const step = this.#steps[this.#index];\n this.#cleanup = step.render(this.#body, this.#ctx) ?? null;\n }\n\n /** The visual state of step `i`: an override, else its position. */\n #stepState(i) {\n const override = this.#overrides.get(this.#steps[i].id);\n if (override) return override.state;\n if (i < this.#index) return 'done';\n return i === this.#index ? 'current' : 'upcoming';\n }\n\n #paint() {\n if (!this.#root) return;\n const busy = this.busy;\n this.#root.classList.toggle('twm-wizard--busy', busy);\n this.#root.setAttribute('aria-busy', busy ? 'true' : 'false');\n\n this.#steps.forEach((step, i) => {\n const state = this.#stepState(i);\n const item = this.#stepItems[i];\n for (const s of ['done', 'current', 'upcoming', 'error']) {\n item.classList.toggle(`twm-wizard__step--${s}`, s === state);\n }\n item.classList.toggle('twm-wizard__step--active', i === this.#index);\n const btn = this.#stepButtons[i];\n btn.disabled = busy || i >= this.#index;\n if (i === this.#index) btn.setAttribute('aria-current', 'step');\n else btn.removeAttribute('aria-current');\n const override = this.#overrides.get(step.id);\n btn.title = override?.message || step.label || step.id;\n\n const marker = btn.firstChild;\n const glyph = state === 'done' ? 'check' : state === 'error' ? 'error' : (step.icon || '');\n marker.classList.toggle('material-symbols-outlined', Boolean(glyph));\n marker.textContent = glyph || String(i + 1);\n if (i > 0) {\n this.#connectors[i - 1].classList.toggle('twm-wizard__connector--done', i <= this.#index);\n }\n });\n\n const gate = this.#gate();\n const last = this.#isLast();\n this.#nextBtn.textContent = last ? this.#labels.finish : this.#labels.next;\n this.#nextBtn.disabled = busy || !gate.ok;\n this.#nextBtn.title = gate.ok ? '' : gate.hint;\n this.#backBtn.disabled = busy || this.#index === 0;\n this.#cancelBtn.disabled = busy;\n\n const error = this.#overrides.get(this.currentStep);\n const text = error ? error.message : (gate.ok ? '' : gate.hint);\n this.#message.textContent = text;\n this.#message.classList.toggle('twm-wizard__message--error', Boolean(error));\n this.#message.classList.toggle('twm-wizard__message--hint', !error && Boolean(text));\n if (error) this.#message.setAttribute('role', 'alert');\n else this.#message.removeAttribute('role');\n }\n\n #close() {\n const win = this.#window;\n this.#teardown();\n this._mounted = false;\n win?.close({ force: true });\n }\n\n #teardown() {\n runCleanup(this.#cleanup);\n this.#cleanup = null;\n this.#root?.remove();\n this.#root = null;\n this.#body = null;\n this.#message = null;\n this.#stepItems = [];\n this.#stepButtons = [];\n this.#connectors = [];\n this.#cancelBtn = this.#backBtn = this.#nextBtn = null;\n }\n}\n", "/**\n * WindowChromeController\n *\n * Handles frameless window management for the desktop application:\n * - Window minimize, maximize, close buttons\n * - Resize handles (edges and corners)\n * - Top bar dragging for window movement\n * - F11 fullscreen toggle\n *\n * Talks to the embedder ONLY through a Host's `window` capability\n * (see src/host/host.js). A host with no `window` capability \u2014 a browser\n * tab, a VS Code webview, the standalone demo \u2014 is legal: we simply don't\n * install custom chrome. That degraded path is also the production path on\n * Linux, macOS and `--browser`, where the OS/browser draws the title bar.\n *\n * THREE MODES, decided by `host.window.chrome()` (which may answer with a\n * promise: the Photino host asks its native side): a browser tab and a window\n * with native chrome get NOTHING from this class (no handles, no buttons, no\n * body class), and only a window that answers `custom` gets the chrome.\n *\n * NATIVE GESTURES. A host that offers `startNativeDrag()` and\n * `startNativeResize(edge)` gets drags on the top bar and presses on the\n * resize handles handed to the OS, which brings snapping and a resize that\n * keeps up with the pointer. A host without them gets the JS move and resize\n * over getBounds/setBounds.\n *\n * @param {object} [opts]\n * @param {object} [opts.host] a Host; only its `window` capability is used\n * @param {string|Element} [opts.topBar='.twm-global-top-bar'] the bar that drags the window\n * @param {string|Element} [opts.controls] where to draw minimise/maximise/close when\n * the page has no `#win-minimize`/`#win-maximize`/`#win-close` of its own\n * (default: the top bar's `.twm-bar-right`, else the top bar itself)\n * @param {string} [opts.noDrag] more selectors that never start a drag\n */\n\nconst SUPPORTS_POINTER = typeof window !== 'undefined' && 'onpointerdown' in window;\nconst MIN_WIDTH = 500;\nconst MIN_HEIGHT = 350;\nconst DRAG_THRESHOLD = 4;\n\nexport class WindowChromeController {\n constructor({ eventBus, logger, host, topBar = '.twm-global-top-bar', controls = null, noDrag = '' } = {}) {\n this.eventBus = eventBus;\n this.logger = logger || console;\n this._topBarOpt = topBar;\n this._controlsOpt = controls;\n this._noDrag = noDrag;\n this._createdControls = null;\n\n // The host's window capability, or null. Never throw on a missing\n // one \u2014 see the class comment.\n this.win = host?.window || null;\n\n this.resizingActive = false;\n this.lastDblClickTs = 0;\n this.handles = {};\n this.topBar = null;\n\n this._disposed = false;\n this._disposers = [];\n }\n\n /**\n * Initialize the window chrome controller\n */\n async initialize() {\n if (this._disposed) return false;\n\n let chrome = 'native';\n try { chrome = this.win ? await this.win.chrome() : 'native'; } catch (_) { chrome = 'native'; }\n if (this._disposed) return false;\n if (chrome !== 'custom') {\n // Native window decorations (Linux/macOS) or the browser already\n // provide a title bar + window controls; our custom chrome would be\n // a redundant second set. Skip it entirely.\n this.logger.info?.('[WindowChrome] Native/browser chrome detected \u2014 custom window chrome disabled');\n return false;\n }\n\n document.body.classList.add('twm-custom-chrome');\n this.#createWindowControls();\n this.#wireWindowButtons();\n this.#createResizeHandles();\n this.#wireTopBarDrag();\n this.#wireKeyboardShortcuts();\n this.#wireNativeStateSync();\n this.#initializeState();\n \n this.logger.info?.('[WindowChrome] Initialized');\n return true;\n }\n\n /** An element from a selector or an element; null when there is none. */\n #resolve(target, within = document) {\n if (!target) return null;\n if (typeof target !== 'string') return target;\n return within.querySelector(target);\n }\n\n /**\n * Draw minimise, maximise/restore and close, unless the page has its own\n * `#win-*` buttons (an embedder's own markup), which are then wired instead.\n */\n #createWindowControls() {\n if (document.getElementById('win-minimize') || document.getElementById('win-close')) return;\n const bar = this.#resolve(this._topBarOpt);\n const host = this.#resolve(this._controlsOpt)\n || bar?.querySelector('.twm-bar-right')\n || bar;\n if (!host) return;\n const box = document.createElement('div');\n box.className = 'twm-window-controls';\n const button = (id, icon, label, extra = '') => {\n const b = document.createElement('button');\n b.type = 'button';\n b.id = id;\n b.className = `twm-window-controls__btn${extra}`;\n b.setAttribute('aria-label', label);\n b.title = label;\n const i = document.createElement('span');\n i.className = 'material-symbols-outlined';\n i.textContent = icon;\n b.appendChild(i);\n box.appendChild(b);\n };\n button('win-minimize', 'remove', 'Minimize');\n button('win-maximize', 'check_box_outline_blank', 'Maximize');\n button('win-close', 'close', 'Close', ' twm-window-controls__btn--close');\n host.appendChild(box);\n this._createdControls = box;\n }\n\n /**\n * Wire minimize, maximize, close buttons\n */\n #wireWindowButtons() {\n const minBtn = document.getElementById('win-minimize');\n const maxBtn = document.getElementById('win-maximize');\n const closeBtn = document.getElementById('win-close');\n\n if (minBtn) {\n const handler = () => this.win.minimize();\n minBtn.addEventListener('click', handler);\n this._disposers.push(() => minBtn.removeEventListener('click', handler));\n }\n\n if (maxBtn) {\n const handler = async () => {\n try {\n const isMax = await this.win.setMaximized(!(await this.win.isMaximized()));\n this.#updateMaximizeIcon(isMax);\n this.#setResizeHandlesEnabled(!isMax);\n } catch (e) {\n this.logger.warn?.('[WindowChrome] Maximize toggle failed', e);\n }\n };\n maxBtn.addEventListener('click', handler);\n this._disposers.push(() => maxBtn.removeEventListener('click', handler));\n }\n\n if (closeBtn) {\n const handler = () => this.win.close();\n closeBtn.addEventListener('click', handler);\n this._disposers.push(() => closeBtn.removeEventListener('click', handler));\n }\n }\n\n /**\n * Update maximize button icon and body class\n */\n #updateMaximizeIcon(isMax) {\n const maxBtn = document.getElementById('win-maximize');\n if (!maxBtn) return;\n \n const icon = maxBtn.querySelector('.material-symbols-outlined');\n if (icon) {\n icon.textContent = isMax ? 'filter_none' : 'check_box_outline_blank';\n }\n const tooltipText = isMax ? 'Restore' : 'Maximize';\n window.LatexTooltip?.set(maxBtn, tooltipText);\n maxBtn.setAttribute('aria-label', tooltipText);\n maxBtn.title = tooltipText;\n \n document.body.classList.toggle('twm-window-maximized', isMax);\n }\n\n /**\n * Enable/disable resize handles\n */\n #setResizeHandlesEnabled(enabled) {\n Object.values(this.handles).forEach(handle => {\n if (handle) {\n handle.style.pointerEvents = enabled ? 'auto' : 'none';\n }\n });\n }\n\n /**\n * Set fullscreen body class\n */\n #setFullscreenClass(isFs) {\n document.body.classList.toggle('window-fullscreen', isFs);\n }\n\n /**\n * Create all resize handles\n */\n #createResizeHandles() {\n const positions = ['right', 'left', 'top', 'bottom'];\n const corners = ['br', 'bl', 'tr', 'tl'];\n\n positions.forEach(pos => {\n const handle = document.createElement('div');\n handle.className = `twm-resize-handle ${pos}`;\n document.body.appendChild(handle);\n this.handles[pos] = handle;\n this.#setupResize(handle, pos);\n });\n\n corners.forEach(corner => {\n const handle = document.createElement('div');\n handle.className = `twm-resize-handle corner ${corner}`;\n document.body.appendChild(handle);\n const mode = 'corner' + corner.toUpperCase();\n this.handles[mode] = handle;\n this.#setupResize(handle, mode);\n });\n }\n\n /**\n * Setup resize behavior for a handle\n */\n #setupResize(handle, mode) {\n let startX = 0, startY = 0, startScreenX = 0, startScreenY = 0;\n let startW = 0, startH = 0, startLeft = 0, startTop = 0;\n let pending = null;\n let rafScheduled = false;\n let lastSent = null;\n\n const boundsEqual = (a, b) => {\n return !!a && !!b && a.x === b.x && a.y === b.y && a.w === b.w && a.h === b.h;\n };\n\n const sendBounds = () => {\n rafScheduled = false;\n if (!pending) return;\n if (lastSent && boundsEqual(lastSent, pending)) return;\n this.win.setBounds({ x: pending.x, y: pending.y, width: pending.w, height: pending.h });\n lastSent = pending;\n };\n\n const scheduleSend = () => {\n if (!rafScheduled) {\n rafScheduled = true;\n requestAnimationFrame(sendBounds);\n }\n };\n\n let activePointerId = null;\n\n const EDGE = {\n right: 'e', left: 'w', top: 'n', bottom: 's',\n cornerBR: 'se', cornerBL: 'sw', cornerTR: 'ne', cornerTL: 'nw',\n };\n\n const startDrag = async (e) => {\n if (e.button != null && e.button !== 0) return;\n e.preventDefault();\n // \u2500\u2500 Native resize: the OS runs its own size loop (it blocks until\n // mouse-up), so the edge stays under the pointer. \u2500\u2500\n if (this.win.startNativeResize) {\n this.resizingActive = true;\n let handled = false;\n try { handled = await this.win.startNativeResize(EDGE[mode]); } catch (_) { handled = false; }\n this.resizingActive = false;\n if (handled) return;\n }\n this.resizingActive = true;\n startX = e.clientX;\n startY = e.clientY;\n startScreenX = e.screenX ?? startX;\n startScreenY = e.screenY ?? startY;\n\n try {\n const res = await this.win.getBounds();\n if (res) {\n startLeft = typeof res.x === 'number' ? res.x : 0;\n startTop = typeof res.y === 'number' ? res.y : 0;\n startW = res.width || document.documentElement.clientWidth;\n startH = res.height || document.documentElement.clientHeight;\n } else {\n startLeft = 0;\n startTop = 0;\n startW = document.documentElement.clientWidth;\n startH = document.documentElement.clientHeight;\n }\n } catch (e) {\n startLeft = 0;\n startTop = 0;\n startW = document.documentElement.clientWidth;\n startH = document.documentElement.clientHeight;\n }\n\n startLeft = Math.round(startLeft);\n startTop = Math.round(startTop);\n startW = Math.round(startW);\n startH = Math.round(startH);\n pending = null;\n lastSent = null;\n rafScheduled = false;\n\n // Capture pointer for smooth resize even when cursor escapes the handle\n if (SUPPORTS_POINTER && e.pointerId != null && handle.setPointerCapture) {\n try {\n handle.setPointerCapture(e.pointerId);\n activePointerId = e.pointerId;\n } catch (_) {}\n }\n\n if (SUPPORTS_POINTER) {\n window.addEventListener('pointermove', onMove, { passive: false });\n window.addEventListener('pointerup', endDrag, { once: true });\n } else {\n window.addEventListener('mousemove', onMove, { passive: false });\n window.addEventListener('mouseup', endDrag, { once: true });\n }\n };\n\n const onMove = (e) => {\n const sx = e.screenX ?? e.clientX ?? 0;\n const sy = e.screenY ?? e.clientY ?? 0;\n const dx = sx - startScreenX;\n const dy = sy - startScreenY;\n\n let newX = startLeft;\n let newY = startTop;\n let newW = startW;\n let newH = startH;\n\n const isLeft = mode === 'left' || mode === 'cornerBL' || mode === 'cornerTL';\n const isRight = mode === 'right' || mode === 'cornerBR' || mode === 'cornerTR';\n const isTop = mode === 'top' || mode === 'cornerTR' || mode === 'cornerTL';\n const isBottom = mode === 'bottom' || mode === 'cornerBR' || mode === 'cornerBL';\n\n if (isLeft) {\n const candidateWidth = startW - dx;\n newW = Math.max(MIN_WIDTH, candidateWidth);\n const shift = startW - newW;\n newX = startLeft + shift;\n } else if (isRight) {\n newW = Math.max(MIN_WIDTH, startW + dx);\n }\n\n if (isTop) {\n const candidateHeight = startH - dy;\n newH = Math.max(MIN_HEIGHT, candidateHeight);\n const shiftY = startH - newH;\n newY = startTop + shiftY;\n } else if (isBottom) {\n newH = Math.max(MIN_HEIGHT, startH + dy);\n }\n\n newX = Math.round(newX);\n newY = Math.round(newY);\n newW = Math.max(MIN_WIDTH, Math.round(newW));\n newH = Math.max(MIN_HEIGHT, Math.round(newH));\n\n pending = { x: newX, y: newY, w: newW, h: newH };\n scheduleSend();\n };\n\n const endDrag = () => {\n if (SUPPORTS_POINTER) {\n window.removeEventListener('pointermove', onMove);\n } else {\n window.removeEventListener('mousemove', onMove);\n }\n // Release pointer capture\n if (activePointerId != null && handle.releasePointerCapture) {\n try { handle.releasePointerCapture(activePointerId); } catch (_) {}\n activePointerId = null;\n }\n // Flush any pending bounds update that was waiting for rAF\n if (pending && (!lastSent || !boundsEqual(lastSent, pending))) {\n this.win.setBounds({ x: pending.x, y: pending.y, width: pending.w, height: pending.h });\n }\n pending = null;\n lastSent = null;\n this.resizingActive = false;\n };\n\n const event = SUPPORTS_POINTER ? 'pointerdown' : 'mousedown';\n handle.addEventListener(event, startDrag);\n this._disposers.push(() => handle.removeEventListener(event, startDrag));\n }\n\n /**\n * Setup top bar dragging for window movement\n */\n #wireTopBarDrag() {\n this.topBar = this.#resolve(this._topBarOpt);\n if (!this.topBar) return;\n\n // What never starts a drag: anything you can click or type into. An\n // embedder adds its own with `noDrag`. (`.window-controls` and\n // `.panel-toggles` are kept for embedders' own markup of that shape.)\n const NO_DRAG_SELECTOR = [\n '.no-drag', 'button', 'a', 'input', 'select', 'textarea', 'label',\n '[role=\"button\"]', '[role=\"menuitem\"]', '[role=\"tab\"]', '[contenteditable=\"true\"]',\n '.twm-window-controls', '.window-controls', '.panel-toggles',\n this._noDrag,\n ].filter(Boolean).join(', ');\n\n let dragging = false;\n let startSX = 0, startSY = 0, startX = null, startY = null, winW = 0, winH = 0;\n let wasMax = false;\n let didRestore = false;\n let grabRatio = 0.5;\n let raf = null;\n let lastSentX = null, lastSentY = null;\n let activePointerId = null;\n\n // Double-click detection (native drag swallows dblclick events)\n const DBL_CLICK_TIME = 500;\n const DBL_CLICK_DIST = 4;\n let lastDownTime = 0;\n let lastDownX = 0;\n let lastDownY = 0;\n\n const isInteractiveTarget = (t) => !!(t && t.closest && t.closest(NO_DRAG_SELECTOR));\n\n const onMove = (e) => {\n // IMPORTANT: This must NOT be async to avoid race conditions on first drag\n const sx = e.screenX ?? e.clientX ?? 0;\n const sy = e.screenY ?? e.clientY ?? 0;\n const dx = Math.abs(sx - startSX);\n const dy = Math.abs(sy - startSY);\n\n if (!dragging) {\n if (wasMax) {\n if ((dx + dy) <= 0) return;\n // Handle restore from maximized state\n if (!didRestore) {\n didRestore = true;\n // Fire-and-forget the restore, then reposition\n this.win.setMaximized(false).then(() => {\n this.#updateMaximizeIcon(false);\n this.#setResizeHandlesEnabled(true);\n return this.win.getBounds();\n }).then((bounds) => {\n if (bounds) {\n const rw = bounds.width || 800;\n const rh = bounds.height || 600;\n const targetX = Math.max(0, Math.round(startSX - (rw * grabRatio)));\n const targetY = Math.max(0, Math.round(sy - 10));\n this.win.setBounds({ x: targetX, y: targetY, width: rw, height: rh });\n startX = targetX;\n startY = targetY;\n winW = rw;\n winH = rh;\n startSX = sx;\n startSY = sy;\n }\n }).catch((err) => {\n this.logger.warn?.('[WindowChrome] Restore on drag failed', err);\n });\n }\n return; // Don't proceed with normal drag until restore completes\n } else {\n if ((dx + dy) < DRAG_THRESHOLD) return;\n // startX/startY should already be set by startDrag - if not, skip this move\n if (startX == null || startY == null) {\n return;\n }\n }\n dragging = true;\n }\n\n // Use the bounds fetched in startDrag (never default to 0)\n if (startX == null || startY == null) return;\n\n const nx = Math.round(startX + (sx - startSX));\n const ny = Math.round(startY + (sy - startSY));\n\n if (lastSentX === nx && lastSentY === ny) return;\n\n if (raf) cancelAnimationFrame(raf);\n raf = requestAnimationFrame(() => {\n lastSentX = nx;\n lastSentY = ny;\n this.win.setBounds({ x: nx, y: ny });\n });\n };\n\n const endDrag = () => {\n dragging = false;\n if (raf) {\n cancelAnimationFrame(raf);\n raf = null;\n }\n if (activePointerId != null && this.topBar.releasePointerCapture) {\n try {\n this.topBar.releasePointerCapture(activePointerId);\n } catch (e) {}\n }\n activePointerId = null;\n didRestore = false;\n\n if (SUPPORTS_POINTER) {\n window.removeEventListener('pointermove', onMove, true);\n window.removeEventListener('pointerup', endDrag, true);\n } else {\n window.removeEventListener('mousemove', onMove, true);\n window.removeEventListener('mouseup', endDrag, true);\n }\n };\n\n const startDrag = async (e) => {\n if (this.resizingActive) return;\n if (isInteractiveTarget(e.target)) return;\n if ((Date.now() - this.lastDblClickTs) < 300) return;\n\n // Detect double-click before entering native drag (which\n // blocks the message loop and prevents dblclick events).\n const now = Date.now();\n const cx = e.clientX ?? 0;\n const cy = e.clientY ?? 0;\n if ((now - lastDownTime) < DBL_CLICK_TIME\n && Math.abs(cx - lastDownX) < DBL_CLICK_DIST\n && Math.abs(cy - lastDownY) < DBL_CLICK_DIST) {\n lastDownTime = 0;\n this.lastDblClickTs = now;\n e.preventDefault();\n try {\n const isMax = await this.win.setMaximized(!(await this.win.isMaximized()));\n this.#updateMaximizeIcon(isMax);\n this.#setResizeHandlesEnabled(!isMax);\n } catch (err) {\n this.logger.warn?.('[WindowChrome] Double-click maximize failed', err);\n }\n return;\n }\n lastDownTime = now;\n lastDownX = cx;\n lastDownY = cy;\n\n try {\n if (!this.win) return;\n\n // \u2500\u2500 Native drag (enables Aero Snap) \u2500\u2500\n // The call blocks until the OS drag loop ends (mouse-up).\n // On return the window has already moved/snapped.\n if (this.win.startNativeDrag) {\n e.preventDefault();\n if (await this.win.startNativeDrag()) {\n // Sync UI state after native drag (may have snapped/maximized)\n try {\n const isMax = await this.win.isMaximized();\n this.#updateMaximizeIcon(isMax);\n this.#setResizeHandlesEnabled(!isMax);\n } catch (_) {}\n return;\n }\n // Native drag unavailable \u2014 fall through to JS drag\n }\n\n // \u2500\u2500 JS drag fallback (non-Windows) \u2500\u2500\n startSX = e.screenX ?? e.clientX ?? 0;\n startSY = e.screenY ?? e.clientY ?? 0;\n\n try {\n wasMax = await this.win.isMaximized();\n } catch (e) {\n wasMax = false;\n }\n\n const barWidth = Math.max(1, window.innerWidth || document.documentElement.clientWidth);\n grabRatio = Math.min(1, Math.max(0, (e.clientX || 0) / barWidth));\n\n if (!wasMax) {\n const bounds = await this.win.getBounds();\n if (bounds) {\n startX = typeof bounds.x === 'number' ? bounds.x : (window.screenX ?? 0);\n startY = typeof bounds.y === 'number' ? bounds.y : (window.screenY ?? 0);\n winW = bounds.width || document.documentElement.clientWidth;\n winH = bounds.height || document.documentElement.clientHeight;\n } else {\n startX = window.screenX ?? 0;\n startY = window.screenY ?? 0;\n winW = document.documentElement.clientWidth;\n winH = document.documentElement.clientHeight;\n }\n }\n\n e.preventDefault();\n\n if (SUPPORTS_POINTER && e.pointerId != null && this.topBar.setPointerCapture) {\n try {\n this.topBar.setPointerCapture(e.pointerId);\n activePointerId = e.pointerId;\n } catch (e) {}\n }\n\n if (SUPPORTS_POINTER) {\n window.addEventListener('pointermove', onMove, true);\n window.addEventListener('pointerup', endDrag, true);\n } else {\n window.addEventListener('mousemove', onMove, true);\n window.addEventListener('mouseup', endDrag, true);\n }\n } catch (err) {\n this.logger.warn?.('[WindowChrome] Start drag failed', err);\n }\n };\n\n // Block drag during resize\n const blocker = (e) => {\n if (this.resizingActive) {\n e.preventDefault();\n e.stopPropagation();\n }\n };\n this.topBar.addEventListener('mousedown', blocker, true);\n this.topBar.addEventListener('pointerdown', blocker, true);\n\n // Double-click to toggle maximize (only on blank surfaces)\n const dblClickHandler = async (e) => {\n // Skip maximize if double-click is on interactive elements\n if (isInteractiveTarget(e.target)) {\n return;\n }\n\n this.lastDblClickTs = Date.now();\n e.preventDefault();\n e.stopPropagation();\n if (this.resizingActive) return;\n\n try {\n const isMax = await this.win.setMaximized(!(await this.win.isMaximized()));\n this.#updateMaximizeIcon(isMax);\n this.#setResizeHandlesEnabled(!isMax);\n } catch (e) {\n this.logger.warn?.('[WindowChrome] Double-click maximize failed', e);\n }\n };\n this.topBar.addEventListener('dblclick', dblClickHandler);\n\n // Start drag\n const event = SUPPORTS_POINTER ? 'pointerdown' : 'mousedown';\n this.topBar.addEventListener(event, startDrag, false);\n\n this._disposers.push(() => {\n this.topBar.removeEventListener('mousedown', blocker, true);\n this.topBar.removeEventListener('pointerdown', blocker, true);\n this.topBar.removeEventListener('dblclick', dblClickHandler);\n this.topBar.removeEventListener(event, startDrag, false);\n });\n }\n\n /**\n * Listen for browser resize events to sync UI with native state changes\n * (e.g. Win+Arrow maximize/restore, Win+Down minimize).\n */\n #wireNativeStateSync() {\n let syncTimer = null;\n const syncState = async () => {\n if (this.resizingActive || this._disposed) return;\n try {\n if (!this.win) return;\n const isMax = await this.win.isMaximized();\n this.#updateMaximizeIcon(isMax);\n this.#setResizeHandlesEnabled(!isMax);\n } catch (_) {}\n };\n const handler = () => {\n // Debounce: native snap triggers multiple resize events\n clearTimeout(syncTimer);\n syncTimer = setTimeout(syncState, 80);\n };\n window.addEventListener('resize', handler);\n this._disposers.push(() => {\n window.removeEventListener('resize', handler);\n clearTimeout(syncTimer);\n });\n }\n\n /**\n * Wire F11 fullscreen toggle\n */\n #wireKeyboardShortcuts() {\n const handler = async (e) => {\n if (e.code === 'F11') {\n e.preventDefault();\n try {\n const isFs = await this.win.toggleFullscreen();\n this.#setFullscreenClass(isFs);\n const max = await this.win.isMaximized();\n this.#setResizeHandlesEnabled(!(isFs || max));\n } catch (e) {\n this.logger.warn?.('[WindowChrome] F11 toggle failed', e);\n }\n }\n };\n window.addEventListener('keydown', handler, true);\n this._disposers.push(() => window.removeEventListener('keydown', handler, true));\n }\n\n /**\n * Initialize window state on startup\n */\n async #initializeState() {\n try {\n if (!this.win) return;\n\n const isMax = await this.win.isMaximized();\n this.#updateMaximizeIcon(isMax);\n this.#setResizeHandlesEnabled(!isMax);\n\n const isFs = await this.win.isFullscreen();\n this.#setFullscreenClass(isFs);\n if (isFs) this.#setResizeHandlesEnabled(false);\n } catch (e) {\n this.logger.warn?.('[WindowChrome] Initial state check failed', e);\n }\n }\n\n /**\n * Dispose of the controller\n */\n dispose() {\n if (this._disposed) return;\n this._disposed = true;\n\n this._disposers.forEach(dispose => {\n try {\n dispose();\n } catch (e) {}\n });\n this._disposers = [];\n\n // Remove resize handles, and the buttons this drew\n Object.values(this.handles).forEach(handle => {\n if (handle && handle.parentNode) {\n handle.parentNode.removeChild(handle);\n }\n });\n this.handles = {};\n this._createdControls?.remove();\n this._createdControls = null;\n document.body.classList.remove('twm-custom-chrome', 'twm-window-maximized', 'window-fullscreen');\n\n this.logger.info?.('[WindowChrome] Disposed');\n }\n}\n", "/**\n * Notification Center (js_new)\n *\n * Purpose\n * -------\n * Unified notifications/toasts/status-line controller consuming events from the rest of the app.\n *\n * Responsibilities\n * - Render queued notifications with namespace context and severity.\n * - Ingest `log:*` and domain-specific events to present user-facing feedback.\n * - Replace scattered `window.notify` / `status_view.js` hooks.\n *\n * Source Material\n * - html/js/status_view.js and ui_manager.js toast helpers.\n * - html/js/ui_utilities.js notification utilities.\n *\n * Progress toasts (0.17.0)\n * ------------------------\n * `show({ progress })` makes a toast that tracks a job: `progress` is a 0..1\n * fraction, `{ value, total }`, or `null` for indeterminate; `status` is a line\n * under the message and `counts` a label beside the bar. Such a toast is\n * persistent and collapsible, and it RUNS until `update()` gives it an outcome\n * severity (success, error or fatal), which ends its bar (done or error) for\n * good and lets a `durationMs` in the same patch dismiss it. Every toast is\n * drawn once and then patched: `update()` touches only its own nodes, and a\n * toast arriving or leaving moves no other toast's element, so a bar, a\n * collapsed state and a hovered button survive. A running progress toast is\n * never held behind \"+N more\" (and never dropped by 'drop'); it counts toward\n * `maxVisible`, so it takes the place of the newest other toast.\n */\nimport { ComponentBase } from './base/component_base.js';\nimport { getSetting } from '../core/settings.js';\nimport { setToastBus, getToastBus } from './components/toast.js';\nimport { ProgressBar } from './components/progress.js';\n\nconst SEVERITIES = ['info', 'success', 'warn', 'error', 'fatal'];\n\n/** The severity a progress toast finishes with, and the state its bar ends in. */\nconst OUTCOME_BAR_STATE = Object.freeze({ success: 'done', error: 'error', fatal: 'error' });\nconst LOG_SEVERITY_MAP = {\n trace: 'info',\n debug: 'info',\n info: 'info',\n warn: 'warn',\n error: 'error',\n fatal: 'fatal',\n};\n\nconst DEFAULT_LOG_LEVELS = new Set(['warn', 'error', 'fatal']);\n\n// Internal namespace identifiers that should not be shown as toast titles.\n// Messages from these namespaces are self-descriptive and need no category header.\nconst SUPPRESSED_NAMESPACE_TITLES = new Set(['bootstrap', 'app']);\n\nexport class NotificationCenter extends ComponentBase {\n #items;\n #summaryEl;\n\n constructor({\n eventBus,\n logger,\n maxVisible = 3,\n historyLimit = 50,\n defaultDurationMs = 6000,\n logLevels = DEFAULT_LOG_LEVELS,\n // What happens past `maxVisible`. 'drop' (the default, as before 0.11):\n // the oldest toast leaves. 'collapse': the toasts on screen stay, the\n // rest wait behind one \"+N more\" toast, and each comes in as one closes\n // \u2014 a sticky alert nobody has read is never pushed off unseen.\n overflow = 'drop',\n // Called with the held-back toasts when the \"+N more\" toast is clicked.\n summaryAction = null,\n } = {}) {\n super({ eventBus, logger });\n\n this.maxVisible = maxVisible;\n this.overflow = overflow === 'collapse' ? 'collapse' : 'drop';\n this.summaryAction = typeof summaryAction === 'function' ? summaryAction : null;\n /** Toasts waiting behind the \"+N more\" summary ('collapse' only), oldest first. */\n this.held = [];\n this.historyLimit = historyLimit;\n this.defaultDurationMs = defaultDurationMs;\n this.logLevels = new Set(logLevels ?? DEFAULT_LOG_LEVELS);\n\n this.notifications = [];\n this.history = [];\n this.sequence = 0;\n this.activeTimers = new Map();\n this.eventDisposers = [];\n /** id -> the drawn toast's nodes, for the toasts on screen. */\n this.#items = new Map();\n this.#summaryEl = null;\n\n this.container = null;\n this.rootEl = null;\n this.listEl = null;\n this.liveRegionEl = null;\n }\n\n mount(container, props = {}) {\n // Always mount to document.body for reliable visibility\n // The passed container is ignored - we create our own fixed-position container\n const existingContainer = document.getElementById('notification-center-root');\n if (existingContainer) {\n this.container = existingContainer;\n this.rootEl = existingContainer.querySelector('.twm-notification-center');\n this.listEl = existingContainer.querySelector('.twm-notification-center__list');\n this.liveRegionEl = existingContainer.querySelector('.twm-notification-center__live-region');\n this._mounted = true;\n this.#subscribeEvents();\n this.#claimToastBus();\n return this;\n }\n\n // Create a new fixed-position container directly on body\n this.container = document.createElement('div');\n this.container.id = 'notification-center-root';\n this.container.style.cssText = 'position: fixed; right: 16px; bottom: 24px; z-index: 10000; pointer-events: none;';\n\n this.rootEl = document.createElement('div');\n this.rootEl.className = 'twm-notification-center';\n\n this.listEl = document.createElement('div');\n this.listEl.className = 'twm-notification-center__list';\n\n this.liveRegionEl = document.createElement('div');\n this.liveRegionEl.className = 'twm-notification-center__live-region';\n this.liveRegionEl.setAttribute('aria-live', 'polite');\n this.liveRegionEl.setAttribute('aria-atomic', 'true');\n this.liveRegionEl.style.position = 'absolute';\n this.liveRegionEl.style.width = '1px';\n this.liveRegionEl.style.height = '1px';\n this.liveRegionEl.style.overflow = 'hidden';\n this.liveRegionEl.style.clip = 'rect(1px, 1px, 1px, 1px)';\n\n this.rootEl.appendChild(this.listEl);\n this.rootEl.appendChild(this.liveRegionEl);\n this.container.appendChild(this.rootEl);\n document.body.appendChild(this.container);\n\n this._mounted = true;\n this.#subscribeEvents();\n this.#claimToastBus();\n\n if (Array.isArray(props.initialNotifications)) {\n props.initialNotifications.forEach((notification) => this.show(notification));\n }\n return this;\n }\n\n dispose() {\n this.#clearTimers();\n this.#unsubscribeEvents();\n // Give the toast helpers back to the console \u2014 unless someone has\n // pointed them at another bus since this centre mounted.\n if (this.eventBus && getToastBus() === this.eventBus) setToastBus(null);\n this.#items.forEach((entry) => entry.bar?.dispose());\n this.#items.clear();\n this.#summaryEl = null;\n if (this.rootEl?.parentNode) {\n this.rootEl.parentNode.removeChild(this.rootEl);\n }\n this.container = null;\n this.rootEl = null;\n this.listEl = null;\n this.liveRegionEl = null;\n super.dispose();\n }\n\n show(notification) {\n const normalized = this.#normalizeNotification(notification);\n this.#consoleLog(normalized);\n const running = NotificationCenter.#isRunning(normalized);\n if (this.overflow === 'collapse' && !running && this.notifications.length >= this.maxVisible) {\n // Held, not shown: its timer starts when it comes on screen.\n this.held.push(normalized);\n this.#recordHistory(normalized);\n this.#render();\n this.#announce(normalized);\n return normalized.id;\n }\n this.notifications.push(normalized);\n if (this.overflow === 'collapse') {\n // Only a running progress toast gets here past the limit: the\n // newest other toast steps back behind \"+N more\" to make room.\n this.#rebalance();\n } else if (this.notifications.length > this.maxVisible) {\n // The oldest leaves \u2014 but never a running progress toast.\n const idx = this.notifications.findIndex((item) => !NotificationCenter.#isRunning(item));\n if (idx !== -1) {\n const [removed] = this.notifications.splice(idx, 1);\n this.#stopTimer(removed.id);\n this.#recordHistory({ ...removed, dismissed: true, reason: 'overflow' });\n }\n }\n\n this.#recordHistory(normalized);\n this.#scheduleAutoDismiss(normalized);\n this.#render();\n this.#announce(normalized);\n return normalized.id;\n }\n\n dismiss(notificationId, reason = 'dismissed') {\n const idx = this.notifications.findIndex((item) => item.id === notificationId);\n if (idx === -1) {\n const h = this.held.findIndex((item) => item.id === notificationId);\n if (h === -1) return false;\n const [gone] = this.held.splice(h, 1);\n this.#recordHistory({ ...gone, dismissed: true, reason });\n this.#render();\n return true;\n }\n const [removed] = this.notifications.splice(idx, 1);\n this.#stopTimer(notificationId);\n this.#recordHistory({ ...removed, dismissed: true, reason });\n // A place on screen came free: the oldest held-back toast takes it.\n this.#rebalance();\n this.#render();\n return true;\n }\n\n /**\n * Change a notification in place: only its own nodes are touched, and no\n * other toast is redrawn. A held-back toast is changed too and shows the\n * change when it comes on screen.\n *\n * Fields: `message`, `title`, `description`, `severity`, `meta`, and for\n * progress toasts `progress` (fraction, `{ value, total }`, or `null` for\n * indeterminate), `status`, `counts` and `collapsed`; `progress` on a\n * plain toast turns it into a running progress toast (on screen, as with\n * show()). Giving a running progress toast an outcome severity (success,\n * error, fatal) finishes it, and its bar keeps the state it ended in: a\n * later severity only restyles the toast. A `durationMs` on a toast that\n * is not running (re)starts its auto-dismiss (0 keeps it until closed).\n *\n * @param {string} notificationId - The ID of the notification to update\n * @param {Object} updates - The fields to change\n * @returns {boolean} True if the notification was found and updated\n */\n update(notificationId, updates = {}) {\n const notification = this.notifications.find((item) => item.id === notificationId)\n ?? this.held.find((item) => item.id === notificationId);\n if (!notification) {\n return false;\n }\n const hadTitle = Boolean(notification.title);\n const hadDescription = Boolean(notification.description);\n const wasProgress = notification.progress !== undefined;\n const wasRunning = NotificationCenter.#isRunning(notification);\n\n if (updates.message !== undefined) notification.message = updates.message;\n if (updates.title !== undefined) notification.title = updates.title;\n if (updates.description !== undefined) notification.description = updates.description;\n if (updates.meta !== undefined) notification.meta = updates.meta;\n if (updates.status !== undefined) notification.status = updates.status ?? '';\n if (updates.counts !== undefined) notification.counts = updates.counts ?? '';\n if (updates.collapsed !== undefined) notification.collapsed = Boolean(updates.collapsed);\n if (updates.progress !== undefined) {\n if (wasProgress) {\n notification.progress = NotificationCenter.#normalizeProgress(updates.progress);\n } else {\n // A plain toast becomes a running progress toast, set up as show() would.\n Object.assign(notification, NotificationCenter.#progressFields({ ...notification, ...updates }));\n notification.persistent = true;\n this.#stopTimer(notification.id);\n }\n }\n if (updates.severity !== undefined) {\n notification.severity = this.#normalizeSeverity(updates.severity);\n const outcome = OUTCOME_BAR_STATE[notification.severity];\n if (NotificationCenter.#isRunning(notification) && outcome) notification.outcome = outcome;\n }\n const running = NotificationCenter.#isRunning(notification);\n const finished = wasRunning && !running;\n if (updates.durationMs !== undefined && !NotificationCenter.#isRunning(notification)) {\n notification.durationMs = this.#coerceDuration(updates.durationMs);\n notification.persistent = notification.durationMs === 0;\n if (this.notifications.includes(notification)) {\n this.#stopTimer(notification.id);\n this.#scheduleAutoDismiss(notification);\n }\n }\n\n const entry = this.#items.get(notification.id);\n if (entry) {\n const structural = hadTitle !== Boolean(notification.title)\n || hadDescription !== Boolean(notification.description)\n || wasProgress !== (notification.progress !== undefined);\n if (structural) {\n // A part appears or goes: rebuild this one toast, in its place.\n const next = this.#buildItem(notification);\n entry.el.replaceWith(next.el);\n entry.bar?.dispose();\n this.#items.set(notification.id, next);\n } else {\n this.#patchItem(entry, notification);\n }\n }\n if (finished) this.#announce(notification);\n // Started, it comes on screen whatever is held; finished, it folds\n // like any other toast.\n if (running !== wasRunning) this.#rebalance();\n this.#render();\n return true;\n }\n\n clearAll(reason = 'cleared') {\n [...this.notifications].forEach((notification) => this.dismiss(notification.id, reason));\n }\n\n ingestLogEntry(entry) {\n if (!entry || !this.logLevels.has(entry.level)) {\n return;\n }\n\n // Suppress state-guard warnings - these are internal and would cause a cascade\n // (NotificationCenter renders -> triggers state-guard -> logs warning -> creates notification -> repeat)\n if (entry.namespace === 'state-guard') {\n return;\n }\n\n const severity = LOG_SEVERITY_MAP[entry.level] ?? 'info';\n const suppressTitle = SUPPRESSED_NAMESPACE_TITLES.has(entry.namespace);\n const title = suppressTitle\n ? null\n : NotificationCenter.#formatNamespaceTitle(entry.namespace);\n // Info-level log entries from internal namespaces are noise in history\n const skipHistory = severity === 'info' && suppressTitle;\n this.show({\n title,\n message: entry.message,\n severity,\n namespace: entry.namespace,\n meta: entry.data,\n skipHistory,\n });\n }\n\n #consoleLog(notification) {\n if (notification.severity !== 'warn' && notification.severity !== 'error' && notification.severity !== 'fatal') {\n return;\n }\n const method = notification.severity === 'warn' ? console.warn : console.error; // eslint-disable-line no-console\n const prefix = notification.title ? `[${notification.title}]` : '[Notification]';\n const details = notification.meta ?? notification.description ?? '';\n method(`${prefix} ${notification.message}`, details); // eslint-disable-line no-console\n }\n\n #normalizeNotification(notification) {\n if (!notification) {\n throw new TypeError('Notification payload is required');\n }\n const id = notification.id ?? `notification-${++this.sequence}`;\n const severity = this.#normalizeSeverity(notification.severity ?? 'info');\n const isProgress = notification.progress !== undefined;\n return {\n ...(isProgress ? NotificationCenter.#progressFields(notification) : {}),\n id,\n title: notification.title ?? null,\n message: notification.message ?? '',\n description: notification.description ?? null,\n timestamp: notification.timestamp ?? Date.now(),\n severity,\n namespace: notification.namespace ?? null,\n durationMs: this.#coerceDuration(notification.durationMs),\n // A progress toast stays until it finishes (and then until its\n // finishing durationMs, or its \u00D7).\n persistent: isProgress || Boolean(notification.persistent),\n skipHistory: Boolean(notification.skipHistory),\n actions: this.#normalizeActions(notification.actions),\n meta: notification.meta ?? null,\n };\n }\n\n #normalizeSeverity(severity) {\n const value = typeof severity === 'string' ? severity.toLowerCase() : 'info';\n if (!SEVERITIES.includes(value)) {\n return 'info';\n }\n return value;\n }\n\n #coerceDuration(duration) {\n if (duration === null || duration === undefined) {\n return this.defaultDurationMs;\n }\n const value = Number(duration);\n if (!Number.isFinite(value) || value < 0) {\n return this.defaultDurationMs;\n }\n return value;\n }\n\n toast(title, message, type = 'info') {\n // Legacy compatibility method\n this.show({\n title,\n message,\n severity: type,\n persistent: type === 'error' || type === 'fatal',\n });\n }\n\n error(titleOrMessage, message) {\n const hasTitle = message !== undefined;\n return this.show({\n title: hasTitle ? titleOrMessage : null,\n message: hasTitle ? message : titleOrMessage,\n severity: 'error',\n persistent: true,\n });\n }\n\n warn(titleOrMessage, message) {\n const hasTitle = message !== undefined;\n return this.show({\n title: hasTitle ? titleOrMessage : null,\n message: hasTitle ? message : titleOrMessage,\n severity: 'warn',\n });\n }\n\n info(titleOrMessage, message) {\n const hasTitle = message !== undefined;\n return this.show({\n title: hasTitle ? titleOrMessage : null,\n message: hasTitle ? message : titleOrMessage,\n severity: 'info',\n });\n }\n\n success(titleOrMessage, message) {\n const hasTitle = message !== undefined;\n return this.show({\n title: hasTitle ? titleOrMessage : null,\n message: hasTitle ? message : titleOrMessage,\n severity: 'success',\n });\n }\n\n #normalizeActions(actions) {\n if (!Array.isArray(actions) || actions.length === 0) {\n return [];\n }\n return actions.map((action, idx) => ({\n id: action.id ?? `action-${idx}`,\n label: action.label ?? 'Action',\n handler: typeof action.handler === 'function' ? action.handler : null,\n eventName: action.eventName ?? null,\n payload: action.payload ?? null,\n }));\n }\n\n #scheduleAutoDismiss(notification) {\n if (notification.persistent || notification.durationMs === 0) {\n return;\n }\n const timer = setTimeout(() => {\n this.dismiss(notification.id, 'timeout');\n }, notification.durationMs);\n this.activeTimers.set(notification.id, timer);\n }\n\n #stopTimer(notificationId) {\n const timer = this.activeTimers.get(notificationId);\n if (timer) {\n clearTimeout(timer);\n this.activeTimers.delete(notificationId);\n }\n }\n\n #clearTimers() {\n this.activeTimers.forEach((timer) => clearTimeout(timer));\n this.activeTimers.clear();\n }\n\n #recordHistory(entry) {\n if (entry.skipHistory) return;\n this.history.push(entry);\n if (this.history.length > this.historyLimit) {\n this.history.shift();\n }\n }\n\n /** A progress toast that has not been given an outcome yet. */\n static #isRunning(notification) {\n return notification.progress !== undefined && !notification.outcome;\n }\n\n /**\n * The fields a progress toast carries, from a show() payload or an\n * update() that turns a plain toast into one. `outcome` is null while it\n * runs, then the state its bar ended in (done or error).\n */\n static #progressFields(source) {\n return {\n progress: NotificationCenter.#normalizeProgress(source.progress),\n status: source.status ?? '',\n counts: source.counts ?? '',\n collapsed: Boolean(source.collapsed),\n outcome: null,\n };\n }\n\n /** `null` (indeterminate), a 0..1 fraction, or `{ value, total }` -> ProgressBar input. */\n static #normalizeProgress(progress) {\n if (progress === null) return { indeterminate: true };\n if (typeof progress === 'number') {\n return { value: Number.isFinite(progress) ? progress : 0, max: null, indeterminate: false };\n }\n if (typeof progress === 'object') {\n const value = Number(progress.value);\n const total = Number(progress.total);\n return {\n value: Number.isFinite(value) ? value : 0,\n max: Number.isFinite(total) && total > 0 ? total : null,\n indeterminate: false,\n };\n }\n return { indeterminate: true };\n }\n\n /**\n * 'collapse' only: keep at most `maxVisible` on screen, counting running\n * progress toasts, which never leave and are never held (one that started\n * running while held comes on screen first). Past the limit the newest\n * other toast steps back to the front of the held queue (its timer\n * restarts when it returns); under it the oldest held toast comes in.\n */\n #rebalance() {\n if (this.overflow !== 'collapse') return;\n for (let i = 0; i < this.held.length;) {\n if (NotificationCenter.#isRunning(this.held[i])) this.notifications.push(...this.held.splice(i, 1));\n else i++;\n }\n while (this.notifications.length > this.maxVisible) {\n let idx = -1;\n for (let i = this.notifications.length - 1; i >= 0; i--) {\n if (!NotificationCenter.#isRunning(this.notifications[i])) { idx = i; break; }\n }\n if (idx === -1) break;\n const [back] = this.notifications.splice(idx, 1);\n this.#stopTimer(back.id);\n this.held.unshift(back);\n }\n while (this.held.length && this.notifications.length < this.maxVisible) {\n const next = this.held.shift();\n this.notifications.push(next);\n this.#scheduleAutoDismiss(next);\n }\n }\n\n /**\n * Draw the toasts on screen. Each toast's element is built once and kept:\n * a toast arriving or leaving only inserts or removes its own element, so\n * every other toast keeps its nodes (and its bar, collapsed state, hover).\n */\n #render() {\n if (!this._mounted || !this.listEl) {\n return;\n }\n const visible = new Set(this.notifications.map((n) => n.id));\n for (const [id, entry] of this.#items) {\n if (visible.has(id)) continue;\n entry.bar?.dispose();\n entry.el.remove();\n this.#items.delete(id);\n }\n const wanted = this.notifications.map((notification) => {\n let entry = this.#items.get(notification.id);\n if (!entry) {\n entry = this.#buildItem(notification);\n this.#items.set(notification.id, entry);\n }\n return entry.el;\n });\n const summary = this.#syncSummary();\n if (summary) wanted.push(summary);\n wanted.forEach((el, i) => {\n const at = this.listEl.children[i];\n if (at !== el) this.listEl.insertBefore(el, at ?? null);\n });\n // Anything after them is stale (another instance's toasts on a reused root).\n while (this.listEl.children.length > wanted.length) {\n this.listEl.lastElementChild.remove();\n }\n }\n\n // The held-back toasts, as one: \"+N more\". It is a button so the count is\n // reachable by keyboard; what it opens is the consumer's (summaryAction),\n // and it is also announced on the bus for a history panel to answer.\n #syncSummary() {\n if (!this.held.length) {\n this.#summaryEl?.remove();\n this.#summaryEl = null;\n return null;\n }\n if (!this.#summaryEl) {\n const more = document.createElement('button');\n more.type = 'button';\n more.className = 'twm-notification twm-notification--summary';\n more.addEventListener('click', () => {\n const held = [...this.held];\n try { this.summaryAction?.(held); } catch (err) { this.logger?.warn?.('summaryAction failed', err); }\n this.eventBus?.emit?.('notification:summary', { held });\n });\n this.#summaryEl = more;\n }\n const more = this.#summaryEl;\n const count = String(this.held.length);\n if (more.getAttribute('data-notification-summary') !== count) more.setAttribute('data-notification-summary', count);\n NotificationCenter.#setText(more, `+${count} more`);\n const tip = this.held.map((h) => h.title || h.message).join('\\n');\n if (more.title !== tip) more.title = tip;\n return more;\n }\n\n static #setText(node, text) {\n const t = text == null ? '' : String(text);\n if (node.textContent !== t) node.textContent = t;\n }\n\n /** Build one toast's element; `#patchItem` then fills what can change. */\n #buildItem(notification) {\n const isProgress = notification.progress !== undefined;\n const item = document.createElement('div');\n // Use setAttribute to avoid StateGuard blocking dataset mutations\n item.setAttribute('data-notification-id', notification.id);\n const entry = { el: item, severity: null, titleEl: null, bodyEl: null, descriptionEl: null,\n statusEl: null, bar: null, collapseBtn: null };\n\n const header = document.createElement('div');\n header.className = 'twm-notification__header';\n if (notification.title) {\n entry.titleEl = document.createElement('span');\n entry.titleEl.className = 'twm-notification__title';\n header.appendChild(entry.titleEl);\n }\n\n const timeEl = document.createElement('span');\n timeEl.className = 'twm-notification__timestamp';\n timeEl.textContent = this.#formatTimestamp(notification.timestamp);\n header.appendChild(timeEl);\n\n if (isProgress) {\n const toggle = document.createElement('button');\n toggle.className = 'twm-notification__collapse';\n toggle.type = 'button';\n toggle.innerHTML = '<span class=\"material-symbols-outlined\">expand_more</span>';\n toggle.addEventListener('click', () => {\n this.update(notification.id, { collapsed: !notification.collapsed });\n });\n entry.collapseBtn = toggle;\n header.appendChild(toggle);\n }\n\n const closeBtn = document.createElement('button');\n closeBtn.className = 'twm-notification__close';\n closeBtn.type = 'button';\n closeBtn.setAttribute('aria-label', 'Dismiss notification');\n closeBtn.innerHTML = '<span class=\"material-symbols-outlined\">close</span>';\n closeBtn.addEventListener('click', () => this.dismiss(notification.id, 'manual'));\n header.appendChild(closeBtn);\n item.appendChild(header);\n\n entry.bodyEl = document.createElement('div');\n entry.bodyEl.className = 'twm-notification__body';\n item.appendChild(entry.bodyEl);\n\n if (isProgress) {\n entry.bar = new ProgressBar(item, {\n ...notification.progress, showCount: false, className: 'twm-notification__progress',\n });\n entry.statusEl = document.createElement('div');\n entry.statusEl.className = 'twm-notification__status';\n item.appendChild(entry.statusEl);\n }\n\n if (notification.description) {\n entry.descriptionEl = document.createElement('div');\n entry.descriptionEl.className = 'twm-notification__description';\n item.appendChild(entry.descriptionEl);\n }\n\n if (notification.actions.length > 0) {\n const actionsEl = document.createElement('div');\n actionsEl.className = 'twm-notification__actions';\n notification.actions.forEach((action) => {\n const button = document.createElement('button');\n button.type = 'button';\n button.className = 'twm-notification__action-btn';\n button.textContent = action.label;\n button.addEventListener('click', () => {\n try {\n if (action.handler) {\n action.handler(notification, action);\n } else if (action.eventName && this.eventBus) {\n this.eventBus.emit(action.eventName, action.payload ?? { notificationId: notification.id });\n }\n } catch (err) {\n this.logger?.error?.('twm-notification-center', 'Notification action failed', { err });\n } finally {\n // Don't auto-dismiss error/fatal notifications, or a job\n // still running, after action clicks\n if (notification.severity !== 'error' && notification.severity !== 'fatal'\n && !NotificationCenter.#isRunning(notification)) {\n this.dismiss(notification.id, 'action');\n }\n }\n });\n actionsEl.appendChild(button);\n });\n item.appendChild(actionsEl);\n }\n\n item.addEventListener('click', (event) => {\n if (event.target.closest('button') || NotificationCenter.#isRunning(notification)) {\n return;\n }\n this.dismiss(notification.id, 'click');\n });\n\n this.#patchItem(entry, notification);\n return entry;\n }\n\n /** Bring a drawn toast's nodes in line with its data, touching only what changed. */\n #patchItem(entry, notification) {\n const item = entry.el;\n if (entry.severity !== notification.severity) {\n if (entry.severity) item.classList.remove(`twm-notification--${entry.severity}`);\n item.classList.add('twm-notification', `twm-notification--${notification.severity}`);\n entry.severity = notification.severity;\n }\n if (entry.titleEl) NotificationCenter.#setText(entry.titleEl, notification.title);\n NotificationCenter.#setText(entry.bodyEl, notification.message);\n if (entry.descriptionEl) NotificationCenter.#setText(entry.descriptionEl, notification.description);\n if (!entry.bar) return;\n\n item.classList.add('twm-notification--progress');\n item.classList.toggle('twm-notification--collapsed', Boolean(notification.collapsed));\n const expanded = String(!notification.collapsed);\n if (entry.collapseBtn.getAttribute('aria-expanded') !== expanded) {\n entry.collapseBtn.setAttribute('aria-expanded', expanded);\n entry.collapseBtn.setAttribute('aria-label', notification.collapsed ? 'Expand notification' : 'Collapse notification');\n }\n NotificationCenter.#setText(entry.statusEl, notification.status);\n entry.statusEl.hidden = !notification.status;\n entry.bar.update({ ...notification.progress, label: notification.counts });\n const end = notification.outcome ?? 'running';\n if (entry.bar.state !== end) entry.bar.setState(end);\n }\n\n #formatTimestamp(timestamp) {\n const date = new Date(timestamp);\n return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' });\n }\n\n #announce(notification) {\n if (!this.liveRegionEl) {\n return;\n }\n const parts = [notification.title, notification.message].filter(Boolean);\n this.liveRegionEl.textContent = parts.join(': ');\n }\n\n #handleToast(payload = {}) {\n const message = payload.text ?? payload.message ?? (typeof payload === 'string' ? payload : '');\n if (!message) {\n return;\n }\n\n const persistent = payload.persistent === true || payload.autoHide === false;\n const durationMs = persistent ? 0 : (payload.durationMs ?? payload.duration ?? payload.timeout);\n this.show({\n title: payload.title ?? null,\n message,\n severity: payload.type ?? payload.severity ?? 'info',\n durationMs,\n persistent,\n namespace: payload.namespace ?? null,\n actions: payload.actions,\n meta: payload.meta ?? null,\n });\n }\n\n #subscribeEvents() {\n if (!this.eventBus) {\n return;\n }\n this.eventDisposers.push(\n this.eventBus.on('toast:show', (payload) => this.#handleToast(payload)),\n this.eventBus.on('notification:show', (payload) => this.show(payload)),\n this.eventBus.on('notification:update', (payload) => {\n if (payload?.id) {\n this.update(payload.id, payload);\n }\n }),\n this.eventBus.on('log:entry', (entry) => this.ingestLogEntry(entry)),\n this.eventBus.on('workspace:save:failed', (payload) => {\n // Error toasts are shown by default unless explicitly disabled\n if (getSetting('workspace.save.showErrorToast', true)) {\n this.show({\n title: 'Workspace Save Failed',\n message: payload?.reason ? `Save failed: ${payload.reason}` : 'Workspace save failed',\n severity: 'error',\n meta: payload,\n persistent: true,\n });\n }\n }),\n this.eventBus.on('workspace:save:completed', (payload) => {\n // Only show toast if enabled in settings\n if (getSetting('workspace.save.showToast', false)) {\n this.show({\n title: 'Workspace Saved',\n message: 'Changes saved successfully',\n severity: 'success',\n durationMs: 3000,\n meta: payload,\n skipHistory: true,\n });\n }\n }),\n this.eventBus.on('workspace:import:failed', (payload) => {\n // Error toasts are shown by default unless explicitly disabled\n if (getSetting('workspace.import.showErrorToast', true)) {\n this.show({\n title: 'Workspace Import Failed',\n message: payload?.error?.message || 'Import failed',\n severity: 'error',\n meta: payload,\n persistent: true,\n });\n }\n }),\n this.eventBus.on('workspace:import:completed', (payload) => {\n // Show import completion toast if enabled in settings\n if (getSetting('workspace.import.showToast', true)) {\n this.show({\n title: 'Workspace Ready',\n message: 'Workspace import completed',\n severity: 'success',\n durationMs: 3000,\n meta: payload,\n skipHistory: true,\n });\n }\n }),\n );\n }\n\n /** The toast helpers (toast.js) emit on the bus of the centre mounted last. */\n #claimToastBus() {\n if (this.eventBus) setToastBus(this.eventBus);\n }\n\n #unsubscribeEvents() {\n this.eventDisposers.forEach((disposer) => {\n try {\n disposer?.dispose?.();\n } catch (err) {\n this.logger?.warn?.('twm-notification-center', 'Failed to remove event listener', { err });\n }\n });\n this.eventDisposers = [];\n }\n\n static #formatNamespaceTitle(namespace) {\n if (!namespace) return null;\n return namespace\n .split(/[-_]/)\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join(' ');\n }\n}\n\nNotificationCenter.SEVERITIES = SEVERITIES;\n", "/**\n * auto_scrollbars.js \u2014 the overlay scrollbar, on EVERY scrollable element.\n *\n * `installOverlayScrollbar` (overlay_scrollbar.js) gives one container a thin\n * bar that shows on hover and fades away. It is installed container by\n * container, it puts the bar INSIDE the container, and it holds a resize\n * observer, a subtree mutation observer and a window listener for each one.\n * That is fine for a handful of known panes and wrong for \"all of them\": a\n * page that redraws with `innerHTML = ''` deletes its bar for good, and a\n * table body, a dropdown, a textarea and a dialog each want one.\n *\n * So this is the same look, done once for a whole subtree:\n *\n * - Native scrollbars are hidden under `root`, so no element reserves\n * layout width for one and nothing reflows when a bar appears.\n * - Bars live in ONE fixed layer on `document.body`, positioned over the\n * element they belong to. Nothing is added to a scroll container, so a\n * redraw cannot remove a bar, and a textarea (which cannot hold children)\n * gets one too.\n * - An element gets its bars when the pointer is over it or it scrolls, if\n * it actually overflows. They fade out a moment after the pointer leaves\n * or the scrolling stops. Nested scroll areas each show their own.\n * - The thumb drags and the track pages, as a native bar does.\n * - The layer is above everything, so a bar would also draw over whatever\n * covers its element \u2014 a popover, a menu, a dialog. A bar whose track is\n * covered anywhere is not drawn; it comes back when it is uncovered.\n *\n * Discovery is lazy: the pointer and scroll events name the elements worth\n * measuring, so nothing walks the DOM looking for scroll areas.\n */\n\nconst LAYER_ID = 'twm-autoscroll-layer';\nconst ROOT_CLASS = 'twm-autoscroll';\nconst HIDE_AFTER_MS = 900;\nconst MIN_THUMB = 30;\nconst BAR = 6;\n\n/**\n * Where the thumb goes. Pure, so it can be tested without a layout engine.\n *\n * @param {number} scrollSize scrollHeight / scrollWidth\n * @param {number} clientSize clientHeight / clientWidth\n * @param {number} scrollPos scrollTop / scrollLeft\n * @param {number} trackLen the bar's length on screen (px)\n * @returns {{size:number, pos:number}|null} null when nothing overflows\n */\nexport function thumbGeometry(scrollSize, clientSize, scrollPos, trackLen) {\n const max = scrollSize - clientSize;\n if (!(max > 1) || !(trackLen > 0)) return null;\n const size = Math.min(trackLen, Math.max(MIN_THUMB, trackLen * clientSize / scrollSize));\n const pos = (trackLen - size) * Math.min(1, Math.max(0, scrollPos / max));\n return { size, pos };\n}\n\n/**\n * Whether something else covers `el` at any of the points a bar runs along.\n * Pure, so it can be tested without a layout engine.\n *\n * @param {Element} el\n * @param {Element[][]} stacks what `elementsFromPoint` gave at each point,\n * topmost first. The overlay layer's own bars are skipped.\n * @returns {boolean}\n */\nexport function barCovered(el, stacks) {\n return stacks.some((stack) => {\n const top = (stack || []).find((h) => !h.closest?.('.twm-autoscroll-layer'));\n return Boolean(top) && top !== el && !el.contains(top);\n });\n}\n\n/** Whether an element scrolls on an axis: its overflow allows it and its\n * content is larger than its box. */\nfunction scrollsOn(el, axis) {\n if (!(el instanceof Element)) return false;\n const cs = getComputedStyle(el);\n const overflow = axis === 'y' ? cs.overflowY : cs.overflowX;\n if (overflow !== 'auto' && overflow !== 'scroll' && !(el.tagName === 'TEXTAREA' && overflow !== 'hidden')) return false;\n return axis === 'y' ? el.scrollHeight - el.clientHeight > 1 : el.scrollWidth - el.clientWidth > 1;\n}\n\n/**\n * Give every scrollable element under `root` an auto-hiding overlay scrollbar.\n *\n * @param {HTMLElement} [root=document.body]\n * @param {{exclude?: (el: Element) => boolean}} [opts] elements to leave to\n * their own scrollbar. Containers that already carry an\n * `installOverlayScrollbar` bar are always left alone.\n * @returns {{dispose: () => void}}\n */\nexport function installAutoScrollbars(root = document.body, { exclude = null } = {}) {\n const doc = root.ownerDocument || document;\n const win = doc.defaultView || window;\n root.classList.add(ROOT_CLASS);\n\n let layer = doc.getElementById(LAYER_ID);\n if (!layer) {\n layer = doc.createElement('div');\n layer.id = LAYER_ID;\n layer.className = 'twm-autoscroll-layer';\n doc.body.appendChild(layer);\n }\n\n /** element -> { v, h, timer, hovered } */\n const managed = new Map();\n let hoverChain = new Set();\n\n const eligible = (el) => el instanceof Element\n && root.contains(el)\n && !el.__overlayScrollbarInstalled\n && !el.closest?.('.twm-autoscroll-layer')\n && !(exclude && exclude(el));\n\n const makeBar = (el, axis) => {\n const bar = doc.createElement('div');\n bar.className = `twm-autoscroll-bar twm-autoscroll-bar--${axis}`;\n const thumb = doc.createElement('div');\n thumb.className = 'twm-autoscroll-thumb';\n bar.appendChild(thumb);\n layer.appendChild(bar);\n\n // The track pages, like a native bar's.\n bar.addEventListener('mousedown', (e) => {\n if (e.target !== bar) return;\n e.preventDefault();\n const r = thumb.getBoundingClientRect();\n const before = axis === 'y' ? e.clientY < r.top : e.clientX < r.left;\n const page = (axis === 'y' ? el.clientHeight : el.clientWidth) * 0.9;\n if (axis === 'y') el.scrollTop += before ? -page : page;\n else el.scrollLeft += before ? -page : page;\n });\n // The thumb drags.\n thumb.addEventListener('mousedown', (e) => {\n e.preventDefault();\n e.stopPropagation();\n const rec = managed.get(el);\n if (rec) rec.dragging = true;\n const start = axis === 'y' ? e.clientY : e.clientX;\n const startScroll = axis === 'y' ? el.scrollTop : el.scrollLeft;\n const trackLen = axis === 'y' ? bar.getBoundingClientRect().height : bar.getBoundingClientRect().width;\n const thumbLen = axis === 'y' ? thumb.getBoundingClientRect().height : thumb.getBoundingClientRect().width;\n const max = axis === 'y' ? el.scrollHeight - el.clientHeight : el.scrollWidth - el.clientWidth;\n const perPx = trackLen > thumbLen ? max / (trackLen - thumbLen) : 0;\n bar.classList.add('twm-autoscroll-bar--active');\n const move = (mv) => {\n const d = (axis === 'y' ? mv.clientY : mv.clientX) - start;\n if (axis === 'y') el.scrollTop = startScroll + d * perPx;\n else el.scrollLeft = startScroll + d * perPx;\n };\n const up = () => {\n doc.removeEventListener('mousemove', move);\n doc.removeEventListener('mouseup', up);\n bar.classList.remove('twm-autoscroll-bar--active');\n if (rec) rec.dragging = false;\n hideLater(el);\n };\n doc.addEventListener('mousemove', move);\n doc.addEventListener('mouseup', up);\n });\n bar.addEventListener('mouseenter', () => { const rec = managed.get(el); if (rec) { rec.onBar = true; show(el); } });\n bar.addEventListener('mouseleave', () => { const rec = managed.get(el); if (rec) { rec.onBar = false; hideLater(el); } });\n return { bar, thumb };\n };\n\n const record = (el) => {\n let rec = managed.get(el);\n if (!rec) {\n rec = { v: null, h: null, timer: 0, dragging: false, onBar: false };\n managed.set(el, rec);\n }\n return rec;\n };\n\n const coveredAlong = (el, points) => typeof doc.elementsFromPoint === 'function'\n && barCovered(el, points.map(([x, y]) => doc.elementsFromPoint(x, y)));\n\n /** Place and size an element's bars; drop the element when it is gone. */\n const place = (el) => {\n const rec = managed.get(el);\n if (!rec) return;\n if (!el.isConnected) { drop(el); return; }\n const r = el.getBoundingClientRect();\n const vw = win.innerWidth;\n const vh = win.innerHeight;\n const top = Math.max(0, r.top);\n const left = Math.max(0, r.left);\n const bottom = Math.min(vh, r.bottom);\n const right = Math.min(vw, r.right);\n // Screen px per CSS px, for content inside a zoomed tile.\n const z = el.offsetHeight ? r.height / el.offsetHeight : 1;\n for (const axis of ['y', 'x']) {\n const key = axis === 'y' ? 'v' : 'h';\n const overflows = scrollsOn(el, axis);\n if (!overflows) { if (rec[key]) rec[key].bar.style.display = 'none'; continue; }\n if (!rec[key]) rec[key] = makeBar(el, axis);\n const { bar, thumb } = rec[key];\n bar.style.display = '';\n if (axis === 'y') {\n const len = bottom - top;\n Object.assign(bar.style, { top: `${top}px`, left: `${right - BAR - 1}px`, height: `${len}px`, width: `${BAR}px` });\n const g = thumbGeometry(el.scrollHeight * z, el.clientHeight * z, el.scrollTop * z, len);\n if (!g) { bar.style.display = 'none'; continue; }\n Object.assign(thumb.style, { top: `${g.pos}px`, height: `${g.size}px`, left: '0', width: '100%' });\n const x = right - BAR / 2 - 1;\n if (coveredAlong(el, [[x, top + 2], [x, top + len / 2], [x, bottom - 2]])) bar.style.display = 'none';\n } else {\n const len = right - left;\n Object.assign(bar.style, { left: `${left}px`, top: `${bottom - BAR - 1}px`, width: `${len}px`, height: `${BAR}px` });\n const g = thumbGeometry(el.scrollWidth * z, el.clientWidth * z, el.scrollLeft * z, len);\n if (!g) { bar.style.display = 'none'; continue; }\n Object.assign(thumb.style, { left: `${g.pos}px`, width: `${g.size}px`, top: '0', height: '100%' });\n const y = bottom - BAR / 2 - 1;\n if (coveredAlong(el, [[left + 2, y], [left + len / 2, y], [right - 2, y]])) bar.style.display = 'none';\n }\n }\n };\n\n const setVisible = (el, on) => {\n const rec = managed.get(el);\n if (!rec) return;\n for (const b of [rec.v, rec.h]) if (b) b.bar.classList.toggle('twm-autoscroll-bar--on', on);\n };\n const show = (el) => {\n const rec = record(el);\n clearTimeout(rec.timer);\n place(el);\n setVisible(el, true);\n };\n const hideLater = (el) => {\n const rec = managed.get(el);\n if (!rec) return;\n clearTimeout(rec.timer);\n rec.timer = setTimeout(() => {\n if (rec.dragging || rec.onBar || hoverChain.has(el)) return;\n setVisible(el, false);\n }, HIDE_AFTER_MS);\n };\n const drop = (el) => {\n const rec = managed.get(el);\n if (!rec) return;\n clearTimeout(rec.timer);\n rec.v?.bar.remove();\n rec.h?.bar.remove();\n managed.delete(el);\n };\n\n /** The scrollable elements from `target` up to `root`. */\n const scrollChain = (target) => {\n const out = new Set();\n for (let el = target instanceof Element ? target : target?.parentElement; el && el !== doc.documentElement; el = el.parentElement) {\n if (el.closest?.('.twm-autoscroll-layer')) return out;\n if (eligible(el) && (scrollsOn(el, 'y') || scrollsOn(el, 'x'))) out.add(el);\n if (el === root) break;\n }\n return out;\n };\n\n const onOver = (e) => {\n if (e.target?.closest?.('.twm-autoscroll-layer')) return;\n const next = scrollChain(e.target);\n for (const el of hoverChain) if (!next.has(el)) hideLater(el);\n for (const el of next) show(el);\n hoverChain = next;\n };\n const onLeaveWindow = (e) => {\n if (e.relatedTarget) return;\n for (const el of hoverChain) hideLater(el);\n hoverChain = new Set();\n };\n const onScroll = (e) => {\n const el = e.target === doc ? null : e.target;\n if (el && eligible(el)) { show(el); hideLater(el); }\n // A scrolling ancestor moves every bar inside it.\n for (const other of managed.keys()) if (other !== el) place(other);\n };\n let raf = 0;\n const onResize = () => {\n cancelAnimationFrame(raf);\n raf = requestAnimationFrame(() => { for (const el of managed.keys()) place(el); });\n };\n\n doc.addEventListener('mouseover', onOver, true);\n doc.addEventListener('mouseout', onLeaveWindow, true);\n doc.addEventListener('scroll', onScroll, true);\n win.addEventListener('resize', onResize);\n // A popover or dialog takes the focus as it opens, often over a bar that\n // is showing because the pointer has not moved: look again once it is drawn.\n doc.addEventListener('focusin', onResize, true);\n\n return {\n dispose() {\n doc.removeEventListener('mouseover', onOver, true);\n doc.removeEventListener('mouseout', onLeaveWindow, true);\n doc.removeEventListener('scroll', onScroll, true);\n win.removeEventListener('resize', onResize);\n doc.removeEventListener('focusin', onResize, true);\n for (const el of [...managed.keys()]) drop(el);\n root.classList.remove(ROOT_CLASS);\n },\n };\n}\n", "/**\n * native_context_menu.js \u2014 the browser's own right-click menu, only where it helps.\n *\n * A FlexDesk app draws its own context menus (DataTable rows and headers, tabs,\n * tiles, the top bar). Everywhere else a right-click shows the browser's or the\n * webview's menu: Back, Reload, Save as, Print, Inspect. In a desktop window\n * that makes the app look like a web page and offers moves that break it.\n *\n * This keeps the native menu where it is the useful one, editable text (Paste)\n * and selected text (Copy), and prevents it everywhere nobody else claimed the\n * right-click.\n */\n\n/** Input types that take typed text, where Paste belongs. */\nconst TEXT_INPUTS = new Set(['', 'text', 'search', 'url', 'tel', 'email', 'password', 'number',\n 'date', 'datetime-local', 'month', 'week', 'time']);\n\nfunction isEditable(el) {\n if (!el || el.nodeType !== 1) return false;\n const tag = el.tagName;\n if (tag === 'TEXTAREA' || tag === 'SELECT') return true;\n if (tag === 'INPUT') return TEXT_INPUTS.has(String(el.getAttribute('type') || '').toLowerCase());\n return !!el.closest?.('[contenteditable=\"\"],[contenteditable=\"true\"],[contenteditable=\"plaintext-only\"]');\n}\n\n/** A non-empty selection that the click landed inside. */\nfunction onSelection(target, doc) {\n const sel = doc?.getSelection?.();\n if (!sel || sel.isCollapsed || !String(sel).trim()) return false;\n for (let i = 0; i < sel.rangeCount; i += 1) {\n if (sel.getRangeAt(i).intersectsNode?.(target)) return true;\n }\n return false;\n}\n\n/**\n * Prevent the native context menu wherever no handler claimed the right-click.\n *\n * Listens in the bubble phase, so every element handler runs first: one that\n * shows its own menu calls `preventDefault()`, and this leaves it alone. A\n * handler that stops propagation never reaches here at all.\n *\n * @param {object} [opts]\n * @param {EventTarget} [opts.root=document]\n * @param {(e: MouseEvent) => boolean} [opts.allow] true keeps the native menu for that event\n * @returns {{ dispose: () => void }}\n */\nexport function suppressNativeContextMenu({ root, allow } = {}) {\n const r = root ?? (typeof document !== 'undefined' ? document : null);\n if (!r) return { dispose() {} };\n const onMenu = (e) => {\n if (e.defaultPrevented) return;\n const t = e.target;\n if (isEditable(t)) return;\n if (onSelection(t, t?.ownerDocument)) return;\n if (allow?.(e)) return;\n e.preventDefault();\n };\n r.addEventListener('contextmenu', onMenu);\n return { dispose() { r.removeEventListener('contextmenu', onMenu); } };\n}\n", "/**\n * Overlay scrollbar utilities for the js_new UI stack.\n * Ports the unified hover-only scrollbar system from the legacy UI manager.\n */\n\nimport { createRafResizeObserver } from './raf_resize_observer.js';\n\nfunction normalizeOrientation(value) {\n return String(value || 'horizontal').toLowerCase() === 'vertical' ? 'vertical' : 'horizontal';\n}\n\nfunction ensureInstallState(container) {\n if (!container.__overlayScrollbarInstalled) {\n Object.defineProperty(container, '__overlayScrollbarInstalled', {\n value: {},\n writable: true,\n configurable: true,\n });\n }\n}\n\nexport function installOverlayScrollbar(container, options = {}) {\n if (!container) return null;\n\n const orientation = normalizeOrientation(options.orientation);\n const className = options.className || 'overlay-scrollbar';\n const isHorizontal = orientation !== 'vertical';\n const orientationKey = isHorizontal ? 'horizontal' : 'vertical';\n\n ensureInstallState(container);\n if (container.__overlayScrollbarInstalled[orientationKey]) {\n return container.__overlayScrollbarInstalled[orientationKey];\n }\n\n if (options.setOverflow !== false) {\n container.style.overflow = options.overflow || 'auto';\n }\n if (options.setPosition !== false && getComputedStyle(container).position === 'static') {\n container.style.position = 'relative';\n }\n\n // When externalBar is true, place the bar on the parent element instead of\n // inside the scroll container. This avoids overflow clipping issues in certain\n // flex+overflow layouts (e.g. bottom-tabs-header .tabs).\n const externalBar = !!options.externalBar;\n const barHost = externalBar ? container.parentElement : container;\n if (externalBar && barHost && getComputedStyle(barHost).position === 'static') {\n barHost.style.position = 'relative';\n }\n\n const bar = document.createElement('div');\n bar.className = className;\n bar.classList.add(`overlay-scrollbar-${isHorizontal ? 'h' : 'v'}`);\n const track = document.createElement('div');\n track.className = 'track';\n const thumb = document.createElement('div');\n thumb.className = 'thumb';\n bar.appendChild(track);\n bar.appendChild(thumb);\n (barHost || container).appendChild(bar);\n\n const getScrollProps = () => ({\n scrollSize: isHorizontal ? container.scrollWidth : container.scrollHeight,\n clientSize: isHorizontal ? container.clientWidth : container.clientHeight,\n scrollPos: isHorizontal ? (container.scrollLeft || 0) : (container.scrollTop || 0),\n });\n\n // Dragging and hover state - must be declared early so event handlers can access it\n let dragging = false;\n let hovered = false;\n let startPos = 0;\n let thumbStartPos = 0;\n\n let previousHasOverflow = null;\n let previousClientSize = null;\n let isResettingScroll = false;\n\n const update = () => {\n if (isResettingScroll) return;\n\n const { scrollSize, clientSize, scrollPos } = getScrollProps();\n const scrollLeft = container.scrollLeft || 0;\n const scrollTop = container.scrollTop || 0;\n const maxScroll = scrollSize - clientSize;\n const hasOverflow = maxScroll > 2;\n\n if (previousClientSize !== null && clientSize > previousClientSize && hasOverflow && scrollPos > 0) {\n const delta = clientSize - previousClientSize;\n const targetScroll = Math.max(0, scrollPos - delta);\n if (targetScroll !== scrollPos) {\n isResettingScroll = true;\n if (isHorizontal) {\n container.scrollLeft = targetScroll;\n } else {\n container.scrollTop = targetScroll;\n }\n requestAnimationFrame(() => {\n isResettingScroll = false;\n update();\n });\n previousClientSize = clientSize;\n previousHasOverflow = hasOverflow;\n return;\n }\n }\n\n previousClientSize = clientSize;\n\n if (previousHasOverflow === true && !hasOverflow && scrollPos > 0) {\n isResettingScroll = true;\n if (isHorizontal) {\n container.scrollLeft = 0;\n } else {\n container.scrollTop = 0;\n }\n requestAnimationFrame(() => {\n isResettingScroll = false;\n update();\n });\n previousHasOverflow = hasOverflow;\n return;\n }\n\n const clampedMaxScroll = Math.max(0, maxScroll);\n if (hasOverflow && scrollPos > clampedMaxScroll) {\n isResettingScroll = true;\n if (isHorizontal) {\n container.scrollLeft = clampedMaxScroll;\n } else {\n container.scrollTop = clampedMaxScroll;\n }\n requestAnimationFrame(() => {\n isResettingScroll = false;\n update();\n });\n previousHasOverflow = hasOverflow;\n return;\n }\n previousHasOverflow = hasOverflow;\n\n container.dataset.scrollable = hasOverflow ? '1' : '0';\n\n // Position the bar at the scroll viewport edge.\n if (externalBar) {\n // Bar lives on the parent element \u2014 position using container's offset.\n // No scroll-offset compensation needed since bar is outside scroll context.\n if (isHorizontal) {\n bar.style.left = `${container.offsetLeft}px`;\n bar.style.bottom = 'auto';\n bar.style.top = `${container.offsetTop + container.offsetHeight - 6}px`;\n bar.style.width = `${container.clientWidth}px`;\n } else {\n bar.style.top = `${container.offsetTop}px`;\n bar.style.right = 'auto';\n bar.style.left = `${container.offsetLeft + container.offsetWidth - 6}px`;\n bar.style.height = `${container.clientHeight}px`;\n }\n } else {\n // Bar lives inside the container \u2014 compensate for scroll offset\n // on BOTH axes so the bar stays pinned to the viewport edge.\n if (isHorizontal) {\n bar.style.left = `${scrollLeft}px`;\n bar.style.top = `${scrollTop + container.clientHeight - bar.offsetHeight}px`;\n bar.style.bottom = 'auto';\n bar.style.width = `${clientSize}px`;\n } else {\n bar.style.top = `${scrollTop}px`;\n bar.style.left = `${scrollLeft + container.clientWidth - bar.offsetWidth}px`;\n bar.style.right = 'auto';\n bar.style.height = `${clientSize}px`;\n }\n }\n\n if (!hasOverflow) {\n bar.style.opacity = '0';\n bar.style.pointerEvents = 'none';\n thumb.style[isHorizontal ? 'width' : 'height'] = '0px';\n thumb.style[isHorizontal ? 'left' : 'top'] = '0px';\n return;\n }\n\n // Don't hide while dragging or hovering\n if (!dragging && !hovered) {\n bar.style.opacity = '0'; // hidden until hover\n bar.style.pointerEvents = 'none';\n }\n\n const ratio = clientSize / scrollSize;\n const thumbSize = Math.max(30, Math.floor(ratio * clientSize));\n const maxThumbPos = clientSize - thumbSize;\n const scrollRatio = maxScroll > 0 ? scrollPos / maxScroll : 0;\n const thumbPos = Math.round(maxThumbPos * scrollRatio);\n\n if (isHorizontal) {\n thumb.style.width = `${thumbSize}px`;\n thumb.style.left = `${thumbPos}px`;\n } else {\n thumb.style.height = `${thumbSize}px`;\n thumb.style.top = `${thumbPos}px`;\n }\n };\n\n const onScroll = () => update();\n container.addEventListener('scroll', onScroll, { passive: true });\n \n // Manage hover visibility entirely in JS to avoid CSS specificity issues.\n // Show bar on mouseenter if scrollable, hide on mouseleave.\n const onMouseEnter = () => {\n hovered = true;\n update();\n if (container.dataset.scrollable === '1') {\n bar.style.opacity = '1';\n bar.style.pointerEvents = '';\n }\n };\n const onMouseLeave = () => {\n hovered = false;\n // Don't hide while dragging\n if (dragging) return;\n bar.style.opacity = '0';\n bar.style.pointerEvents = 'none';\n };\n container.addEventListener('mouseenter', onMouseEnter, { passive: true });\n container.addEventListener('mouseleave', onMouseLeave, { passive: true });\n // When bar is external (sibling of container), also listen for hover on the bar\n // itself so moving the mouse to the thumb doesn't trigger a hide.\n if (externalBar) {\n bar.addEventListener('mouseenter', onMouseEnter, { passive: true });\n bar.addEventListener('mouseleave', onMouseLeave, { passive: true });\n }\n\n // Also handle focus-within for keyboard accessibility\n container.addEventListener('focusin', onMouseEnter, { passive: true });\n container.addEventListener('focusout', onMouseLeave, { passive: true });\n\n const resizeObserver = createRafResizeObserver(update);\n try { resizeObserver.observe(container); } catch (_) {}\n\n const mo = new MutationObserver(update);\n try { mo.observe(container, { childList: true, subtree: options.watchSubtree !== false }); } catch (_) {}\n\n let resizeTimeout;\n const onWindowResize = () => {\n update();\n clearTimeout(resizeTimeout);\n resizeTimeout = setTimeout(update, 150);\n };\n window.addEventListener('resize', onWindowResize, { passive: true });\n\n const onMouseDown = (e) => {\n dragging = true;\n startPos = isHorizontal ? e.clientX : e.clientY;\n thumbStartPos = parseFloat(thumb.style[isHorizontal ? 'left' : 'top']) || 0;\n // Keep bar visible while dragging\n bar.style.opacity = '1';\n bar.style.pointerEvents = '';\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp, { once: true });\n e.preventDefault();\n e.stopPropagation();\n };\n\n const onMouseMove = (e) => {\n if (!dragging) return;\n e.preventDefault();\n\n const { scrollSize, clientSize } = getScrollProps();\n const maxScroll = scrollSize - clientSize;\n if (maxScroll <= 0) return;\n\n const thumbSize = parseFloat(thumb.style[isHorizontal ? 'width' : 'height']) || 30;\n const maxThumbPos = clientSize - thumbSize;\n\n const delta = (isHorizontal ? e.clientX : e.clientY) - startPos;\n let newThumbPos = thumbStartPos + delta;\n newThumbPos = Math.max(0, Math.min(maxThumbPos, newThumbPos));\n\n const thumbRatio = maxThumbPos > 0 ? newThumbPos / maxThumbPos : 0;\n if (isHorizontal) {\n container.scrollLeft = thumbRatio * maxScroll;\n } else {\n container.scrollTop = thumbRatio * maxScroll;\n }\n };\n\n const onMouseUp = () => {\n dragging = false;\n document.removeEventListener('mousemove', onMouseMove);\n // Check if mouse is still over container - if not, hide the bar\n const rect = container.getBoundingClientRect();\n const isMouseOver = document.elementsFromPoint(\n (rect.left + rect.right) / 2,\n (rect.top + rect.bottom) / 2\n ).includes(container);\n if (!isMouseOver) {\n bar.style.opacity = '0';\n bar.style.pointerEvents = 'none';\n }\n };\n\n thumb.addEventListener('mousedown', onMouseDown);\n\n // Wheel-to-horizontal: convert vertical wheel into horizontal scroll,\n // but only when the container has no vertical overflow (otherwise let\n // the browser handle normal vertical scrolling).\n let onWheel = null;\n if (isHorizontal) {\n onWheel = (e) => {\n const { scrollSize, clientSize } = getScrollProps();\n if (scrollSize <= clientSize) return;\n if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) return;\n // If the container also scrolls vertically, don't hijack the wheel\n if (container.scrollHeight > container.clientHeight) return;\n e.preventDefault();\n container.scrollLeft += e.deltaY;\n };\n container.addEventListener('wheel', onWheel, { passive: false });\n }\n\n requestAnimationFrame(() => {\n requestAnimationFrame(update);\n });\n setTimeout(update, 50);\n\n const cleanup = () => {\n container.removeEventListener('scroll', onScroll);\n container.removeEventListener('mouseenter', onMouseEnter);\n container.removeEventListener('mouseleave', onMouseLeave);\n container.removeEventListener('focusin', onMouseEnter);\n container.removeEventListener('focusout', onMouseLeave);\n if (externalBar) {\n bar.removeEventListener('mouseenter', onMouseEnter);\n bar.removeEventListener('mouseleave', onMouseLeave);\n }\n if (onWheel) container.removeEventListener('wheel', onWheel);\n window.removeEventListener('resize', onWindowResize);\n try { resizeObserver.disconnect(); } catch (_) {}\n try { mo.disconnect(); } catch (_) {}\n bar.remove();\n };\n\n const handle = { update, cleanup, bar, thumb };\n container.__overlayScrollbarInstalled[orientationKey] = handle;\n return handle;\n}\n\nexport function installWorkspaceScrollbars(workspace, options = {}) {\n if (!workspace) return null;\n if (workspace.__workspaceOverlayScrollbarsInstalled) return workspace.__workspaceOverlayScrollbarsUpdate;\n\n installOverlayScrollbar(workspace, {\n orientation: 'vertical',\n className: options.verticalClass || 'panel-scrollbar',\n watchSubtree: options.watchSubtree ?? true,\n });\n installOverlayScrollbar(workspace, {\n orientation: 'horizontal',\n className: options.horizontalClass || 'tabs-scrollbar',\n watchSubtree: options.watchSubtree ?? true,\n });\n\n const update = () => {\n const maxX = Math.max(0, workspace.scrollWidth - workspace.clientWidth);\n const maxY = Math.max(0, workspace.scrollHeight - workspace.clientHeight);\n workspace.dataset.scrollableX = maxX > 1 ? '1' : '0';\n workspace.dataset.scrollableY = maxY > 1 ? '1' : '0';\n };\n\n workspace.__workspaceOverlayScrollbarsInstalled = true;\n workspace.__workspaceOverlayScrollbarsUpdate = update;\n workspace.addEventListener('scroll', update, { passive: true });\n const ro = createRafResizeObserver(update);\n try { ro.observe(workspace); } catch (_) {}\n const mo = new MutationObserver(update);\n try { mo.observe(workspace, { childList: true, subtree: true }); } catch (_) {}\n requestAnimationFrame(update);\n return update;\n}\n\n/**\n * Auto-discover and install vertical overlay scrollbars on\n * `.twm-collapsible-content.visible` elements under `root`. Sections already\n * visible when this is called get a bar at once; a MutationObserver on `root`\n * handles content mounted later (pages mount lazily) and class toggles\n * (expand/collapse). Only class changes under `root` are watched.\n *\n * This used to look up a hard-coded `#twm-fixed-200` that nothing in FlexDesk\n * creates, so the first pass never ran and the observer fell back to the whole\n * document (BUG-0006). The caller names its own root now.\n *\n * Only adds the visual overlay bar \u2014 does NOT change overflow. Elements that are already\n * scrollable via CSS (e.g. accordion `.twm-collapsible-content.visible { overflow-y: auto }`)\n * get the bar; non-scrollable elements get a no-op bar that stays hidden.\n *\n * @param {Element} [root=document.body] The subtree to scan and watch.\n * @returns {Function} disconnect \u2014 stops watching\n */\nexport function installCollapsibleScrollbars(root = document.body) {\n const installOnElement = (el) => {\n installOverlayScrollbar(el, {\n orientation: 'vertical',\n setOverflow: false,\n watchSubtree: true,\n });\n };\n\n if (root.matches?.('.twm-collapsible-content.visible')) installOnElement(root);\n root.querySelectorAll('.twm-collapsible-content.visible').forEach(installOnElement);\n\n // Watch for new elements AND class changes (visible toggled by toggleCategory)\n const observer = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n // Class change \u2014 check if .twm-collapsible-content just gained .visible\n if (mutation.type === 'attributes' && mutation.attributeName === 'class') {\n const el = mutation.target;\n if (el.classList.contains('twm-collapsible-content') && el.classList.contains('visible')) {\n installOnElement(el);\n }\n continue;\n }\n // New subtrees added (lazy page mount)\n for (const node of mutation.addedNodes) {\n if (node.nodeType !== 1) continue;\n if (node.classList?.contains('twm-collapsible-content') && node.classList?.contains('visible')) {\n installOnElement(node);\n }\n node.querySelectorAll?.('.twm-collapsible-content.visible')?.forEach(installOnElement);\n }\n }\n });\n\n observer.observe(root, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['class'],\n });\n return () => observer.disconnect();\n}\n\n/**\n * Auto-discover and install horizontal overlay scrollbars on tab strips.\n *\n * Uses a MutationObserver so dynamically created tab strips are picked up\n * without per-page manual setup.\n *\n * The selector list used to be hardcoded as `.tabs, .scenario-detail-tabs`, so\n * a generic scrollbar utility carried the name of one EcoAgent page's tab bar.\n * The caller names its own strips now.\n *\n * @param {string[]} [selectors=['.tabs']] Which elements count as a tab strip.\n * @returns {Function} disconnect \u2014 stops watching for new tabs\n */\nexport function installTabsScrollbars(selectors = ['.tabs']) {\n const selector = selectors.join(', ');\n const classes = selectors\n .filter((s) => s.startsWith('.'))\n .map((s) => s.slice(1));\n const installOnElement = (el) => {\n installOverlayScrollbar(el, {\n orientation: 'horizontal',\n className: 'tabs-scrollbar',\n setOverflow: false,\n externalBar: true,\n watchSubtree: true,\n });\n };\n\n const cleanupElement = (el) => {\n el.__overlayScrollbarInstalled?.horizontal?.cleanup?.();\n delete el.__overlayScrollbarInstalled;\n };\n\n const matches = (el) => classes.some((c) => el.classList?.contains(c));\n\n document.querySelectorAll(selector).forEach(installOnElement);\n\n // Watch for dynamically added/removed elements\n const observer = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n for (const node of mutation.addedNodes) {\n if (node.nodeType !== 1) continue;\n if (matches(node)) installOnElement(node);\n node.querySelectorAll?.(selector)?.forEach(installOnElement);\n }\n for (const node of mutation.removedNodes) {\n if (node.nodeType !== 1) continue;\n if (matches(node)) cleanupElement(node);\n node.querySelectorAll?.(selector)?.forEach(cleanupElement);\n }\n }\n });\n\n observer.observe(document.body, { childList: true, subtree: true });\n return () => observer.disconnect();\n}\n", "/**\n * scroll_lock.js \u2014 0.6.1. Several scroll boxes that move as one.\n *\n * A side-by-side comparison (two DataTables in two tiles, \"now\" and \"then\") is\n * only readable if row 40 on the left stays beside row 40 on the right. A lock\n * is a GROUP: every box attached to it copies the scroll position of whichever\n * member the person scrolled, on the axes the lock names.\n *\n * const lock = createScrollLock({ axis: 'y' });\n * new DataTable(left, { \u2026, scrollLock: lock });\n * new DataTable(right, { \u2026, scrollLock: lock });\n * lock.setEnabled(false); // the two scroll freely; true locks them again\n *\n * Any element can join with `lock.attach(el)`, which returns its detach. A\n * DataTable given `scrollLock` attaches its own body box on every render and\n * detaches it on the next render and on dispose, so a re-render (a sort, new\n * data) never strands a dead box in the group.\n *\n * THE ECHO. Setting `scrollTop` on a member fires that member's own `scroll`\n * event a frame later, and a naive group would then copy it back to the first\n * box, which by then may have moved on \u2014 the two fight and the wheel stutters.\n * So a position this lock WROTE is remembered per box, and the scroll event that\n * reports exactly that position is the echo and is ignored.\n *\n * A box that joins is moved to the group's last position, so a pane opened\n * beside a scrolled one starts level with it. Positions are copied as pixels:\n * the lock aligns rows only when the members draw rows of the same height,\n * which is the comparison's own contract (both sides drawn from one aligned\n * row list, a gap row where a side has none).\n */\n\n/**\n * @param {object} [options]\n * @param {'x'|'y'|'both'} [options.axis='y'] which positions are copied\n * @param {boolean} [options.enabled=true]\n */\nexport function createScrollLock({ axis = 'y', enabled = true } = {}) {\n const doY = axis === 'y' || axis === 'both';\n const doX = axis === 'x' || axis === 'both';\n const members = new Map(); // element -> { wrote: {top, left} | null, off }\n let last = { top: 0, left: 0 };\n let on = !!enabled;\n\n function copyFrom(source) {\n last = { top: source.scrollTop, left: source.scrollLeft };\n if (!on) return;\n for (const [el, state] of members) {\n if (el === source) continue;\n const top = doY ? last.top : el.scrollTop;\n const left = doX ? last.left : el.scrollLeft;\n if (el.scrollTop === top && el.scrollLeft === left) continue;\n state.wrote = { top, left };\n if (doY) el.scrollTop = top;\n if (doX) el.scrollLeft = left;\n }\n }\n\n function onScroll(event) {\n const el = event.currentTarget;\n const state = members.get(el);\n if (!state) return;\n const wrote = state.wrote;\n state.wrote = null;\n // THE ECHO of a position this lock set: not a person scrolling.\n if (wrote && Math.abs(el.scrollTop - wrote.top) < 1\n && Math.abs(el.scrollLeft - wrote.left) < 1) return;\n copyFrom(el);\n }\n\n const lock = {\n /** Join the group. Returns the function that leaves it. */\n attach(el) {\n if (!el || typeof el.addEventListener !== 'function') return () => {};\n if (members.has(el)) return () => lock.detach(el);\n const state = { wrote: null };\n members.set(el, state);\n el.addEventListener('scroll', onScroll, { passive: true });\n if (on && (last.top || last.left)) {\n state.wrote = { top: doY ? last.top : el.scrollTop,\n left: doX ? last.left : el.scrollLeft };\n if (doY) el.scrollTop = last.top;\n if (doX) el.scrollLeft = last.left;\n }\n return () => lock.detach(el);\n },\n detach(el) {\n if (!members.has(el)) return;\n members.delete(el);\n el.removeEventListener('scroll', onScroll);\n },\n /** Lock (true) or let the members scroll freely (false). Locking again\n * brings every member level with the one scrolled last. */\n setEnabled(value) {\n const was = on;\n on = !!value;\n if (on && !was) {\n const source = [...members.keys()].find(\n (el) => el.scrollTop === last.top && el.scrollLeft === last.left)\n || members.keys().next().value;\n if (source) copyFrom(source);\n }\n },\n get enabled() { return on; },\n /** How many boxes are in the group (for a consumer's own checks). */\n get size() { return members.size; },\n dispose() {\n for (const el of [...members.keys()]) lock.detach(el);\n },\n };\n return lock;\n}\n", "/**\n * tooltip_service.js\n *\n * JS-driven tooltip system for elements with `has-tooltip` class and `data-tooltip` attribute.\n * Also supports LaTeX tooltips with `has-latex-tooltip` and `data-latex-tooltip`.\n *\n * This replaces CSS-based ::after pseudo-element tooltips for better stacking context\n * and dynamic content support.\n */\n\nlet tooltipElement = null;\nlet currentTarget = null;\nlet listenersAttached = false;\nlet mouseCheckInterval = null;\nlet lastMousePosition = { x: 0, y: 0 };\n\n/**\n * Create or get the tooltip DOM element.\n * @returns {HTMLElement}\n */\nfunction createTooltipElement() {\n if (tooltipElement) return tooltipElement;\n\n tooltipElement = document.createElement('div');\n tooltipElement.className = 'twm-latex-tooltip';\n document.body.appendChild(tooltipElement);\n return tooltipElement;\n}\n\n/**\n * Position the tooltip relative to target element with smart auto-positioning.\n * Automatically flips placement if tooltip would extend outside viewport.\n * @param {HTMLElement} target - Element to position near\n * @param {HTMLElement} tooltip - Tooltip element\n */\nfunction positionTooltip(target, tooltip) {\n const rect = target.getBoundingClientRect();\n const tooltipRect = tooltip.getBoundingClientRect();\n const gap = 12;\n const margin = 10; // Minimum distance from viewport edge\n\n // Get requested placement from data attributes or context\n const requestedPlacement = (target.dataset?.tooltipPlacement || target.getAttribute('data-tooltip-placement') || '').toLowerCase() ||\n (target.dataset?.latexPlacement || target.getAttribute('data-latex-placement') || '').toLowerCase() ||\n (target.closest('.twm-global-top-bar') ? 'bottom' : (target.closest('.twm-fl-bar') ? 'right' : 'top'));\n\n // Auto-positioning: determine best placement based on available space\n let placement = requestedPlacement || 'top';\n\n // Check if explicit placement is set (not auto)\n const isExplicitPlacement = target.hasAttribute('data-tooltip-placement') ||\n target.hasAttribute('data-latex-placement');\n\n if (!isExplicitPlacement) {\n // Calculate available space in each direction\n const spaceAbove = rect.top - margin;\n const spaceBelow = window.innerHeight - rect.bottom - margin;\n const spaceLeft = rect.left - margin;\n const spaceRight = window.innerWidth - rect.right - margin;\n\n // Auto-select placement based on available space\n if (placement === 'top' && tooltipRect.height > spaceAbove && spaceBelow > spaceAbove) {\n placement = 'bottom';\n } else if (placement === 'bottom' && tooltipRect.height > spaceBelow && spaceAbove > spaceBelow) {\n placement = 'top';\n } else if (placement === 'left' && tooltipRect.width > spaceLeft && spaceRight > spaceLeft) {\n placement = 'right';\n } else if (placement === 'right' && tooltipRect.width > spaceRight && spaceLeft > spaceRight) {\n placement = 'left';\n }\n }\n\n // Calculate position based on final placement\n let left, top;\n\n if (placement === 'top') {\n left = rect.left + (rect.width / 2) - (tooltipRect.width / 2);\n top = rect.top - tooltipRect.height - gap;\n } else if (placement === 'bottom') {\n left = rect.left + (rect.width / 2) - (tooltipRect.width / 2);\n top = rect.bottom + gap;\n } else if (placement === 'left') {\n left = rect.left - tooltipRect.width - gap;\n top = rect.top + (rect.height / 2) - (tooltipRect.height / 2);\n } else if (placement === 'right') {\n left = rect.right + gap;\n top = rect.top + (rect.height / 2) - (tooltipRect.height / 2);\n }\n\n // Clamp to viewport\n const clampedLeft = Math.max(margin, Math.min(left, window.innerWidth - tooltipRect.width - margin));\n const clampedTop = Math.max(margin, Math.min(top, window.innerHeight - tooltipRect.height - margin));\n\n tooltip.style.left = `${clampedLeft}px`;\n tooltip.style.top = `${clampedTop}px`;\n\n // Calculate notch/arrow offset to point toward the target element center\n const targetCenterX = rect.left + rect.width / 2;\n const targetCenterY = rect.top + rect.height / 2;\n let notchOffset = 0;\n\n if (placement === 'top' || placement === 'bottom') {\n // Horizontal offset for notch\n const tooltipCenterX = clampedLeft + tooltipRect.width / 2;\n notchOffset = targetCenterX - tooltipCenterX;\n // Clamp notch offset to stay within tooltip bounds\n const maxOffset = (tooltipRect.width / 2) - 16; // 16px from edge minimum\n notchOffset = Math.max(-maxOffset, Math.min(notchOffset, maxOffset));\n } else {\n // Vertical offset for notch\n const tooltipCenterY = clampedTop + tooltipRect.height / 2;\n notchOffset = targetCenterY - tooltipCenterY;\n // Clamp notch offset\n const maxOffset = (tooltipRect.height / 2) - 16;\n notchOffset = Math.max(-maxOffset, Math.min(notchOffset, maxOffset));\n }\n\n // Set placement and notch offset attributes for CSS styling\n const setAttributes = () => {\n tooltip.setAttribute('data-placement', placement);\n tooltip.style.setProperty('--notch-offset', `${notchOffset}px`);\n };\n\n const guard = window.stateGuard;\n if (guard?.executeWithBypass) {\n guard.executeWithBypass('latex-tooltip:set-placement', setAttributes);\n } else {\n setAttributes();\n }\n}\n\n/**\n * Show tooltip for a target element.\n * @param {HTMLElement} target - Element with tooltip data\n */\nfunction showTooltip(target) {\n if (!target || !target.getAttribute) return;\n\n const hasLatex = target.classList && target.classList.contains('has-latex-tooltip');\n const hasPlain = target.classList && target.classList.contains('twm-has-tooltip');\n\n if (!hasLatex && !hasPlain) return;\n\n currentTarget = target;\n const tooltip = createTooltipElement();\n\n if (hasLatex) {\n // Render LaTeX using KaTeX\n const latex = target.getAttribute('data-latex-tooltip');\n if (!latex) return;\n\n try {\n if (typeof katex !== 'undefined') {\n katex.render(latex, tooltip, {\n displayMode: true,\n throwOnError: false,\n trust: false\n });\n } else {\n tooltip.textContent = latex;\n }\n } catch (err) {\n window.logger?.error('nodes', 'KaTeX rendering error:', err);\n tooltip.textContent = latex;\n }\n } else if (hasPlain) {\n // Plain text tooltip with line breaks preserved\n const text = target.getAttribute('data-tooltip');\n if (!text) return;\n\n // Replace &#10; with actual line breaks, preserve formatting\n const formattedText = text.replace(/&#10;/g, '\\n');\n const lines = formattedText.split('\\n');\n\n tooltip.innerHTML = '';\n lines.forEach((line, index) => {\n if (index === 0) {\n // First line is bold header\n const header = document.createElement('strong');\n header.textContent = line;\n tooltip.appendChild(header);\n } else {\n // Add line break and text\n tooltip.appendChild(document.createElement('br'));\n const textNode = document.createTextNode(line);\n tooltip.appendChild(textNode);\n }\n });\n }\n\n // Optional per-target width override (for long plain-text content like\n // widget documentation). Set data-tooltip-max-width on the target with a\n // CSS length (e.g. \"420px\"). Reset between shows so sticky values don't\n // leak across unrelated targets.\n const widthOverride = target.getAttribute('data-tooltip-max-width');\n tooltip.style.maxWidth = widthOverride || '';\n\n // Position and show\n requestAnimationFrame(() => {\n positionTooltip(target, tooltip);\n tooltip.classList.add('visible');\n\n // Start mouse position check for auto-hide\n startMouseCheck();\n });\n}\n\n/**\n * Hide the tooltip and clean up.\n */\nfunction hideTooltip() {\n if (tooltipElement) {\n tooltipElement.classList.remove('visible');\n }\n currentTarget = null;\n\n // Clear mouse check interval\n if (mouseCheckInterval) {\n clearInterval(mouseCheckInterval);\n mouseCheckInterval = null;\n }\n}\n\n/**\n * Start the mouse position check interval.\n * Hides tooltip if mouse is no longer over the target element.\n */\nfunction startMouseCheck() {\n // Clear any existing interval\n if (mouseCheckInterval) {\n clearInterval(mouseCheckInterval);\n }\n\n // Check every 3 seconds if mouse is still on the target element\n mouseCheckInterval = setInterval(() => {\n if (!currentTarget) {\n clearInterval(mouseCheckInterval);\n mouseCheckInterval = null;\n return;\n }\n\n // Get element under the last known mouse position\n const elementUnderMouse = document.elementFromPoint(lastMousePosition.x, lastMousePosition.y);\n\n // Check if the element under mouse is the target or a child of it\n if (elementUnderMouse) {\n const isStillOnTarget = elementUnderMouse === currentTarget ||\n currentTarget.contains(elementUnderMouse) ||\n elementUnderMouse.closest('.twm-has-tooltip, .has-latex-tooltip') === currentTarget;\n\n if (!isStillOnTarget) {\n hideTooltip();\n }\n } else {\n // Mouse is outside the document\n hideTooltip();\n }\n }, 3000);\n}\n\n/**\n * Attach global event listeners for tooltips.\n */\nfunction attachListeners() {\n if (listenersAttached) return;\n listenersAttached = true;\n\n // Remove all title attributes from elements with custom tooltips\n document.querySelectorAll('.twm-has-tooltip, .has-latex-tooltip').forEach(el => {\n el.removeAttribute('title');\n });\n\n // Track mouse position for the 3-second auto-hide check\n document.addEventListener('mousemove', (event) => {\n lastMousePosition.x = event.clientX;\n lastMousePosition.y = event.clientY;\n }, { passive: true });\n\n document.addEventListener('mouseenter', (event) => {\n const target = event.target;\n if (!(target instanceof Element)) return;\n const tooltipTarget = target.closest('.has-latex-tooltip, .twm-has-tooltip');\n if (!tooltipTarget) return;\n showTooltip(tooltipTarget);\n }, true);\n\n document.addEventListener('mouseleave', (event) => {\n const target = event.target;\n if (!(target instanceof Element)) return;\n const tooltipTarget = target.closest('.has-latex-tooltip, .twm-has-tooltip');\n if (!tooltipTarget) return;\n hideTooltip();\n }, true);\n\n // Hide on scroll\n document.addEventListener('scroll', hideTooltip, true);\n\n // ESC key hides all tooltips application-wide (does not stop propagation)\n document.addEventListener('keydown', (event) => {\n if (event.key === 'Escape') {\n hideTooltip();\n // Note: We intentionally do NOT call event.stopPropagation()\n // so other listeners can also respond to ESC\n }\n }, true);\n}\n\n/**\n * Initialize the tooltip system.\n */\nfunction initializeTooltips() {\n // Wait for KaTeX to load (optional, for latex tooltips)\n const initInterval = setInterval(() => {\n if (typeof katex !== 'undefined') {\n clearInterval(initInterval);\n if (!listenersAttached) {\n attachListeners();\n }\n }\n }, 100);\n\n // Timeout after 2 seconds - attach listeners anyway for plain tooltips\n setTimeout(() => {\n clearInterval(initInterval);\n if (!listenersAttached) {\n attachListeners();\n }\n }, 2000);\n}\n\n/**\n * Set a tooltip on an element programmatically.\n * @param {HTMLElement} element - Target element\n * @param {string} text - Tooltip text\n * @param {boolean} [isLatex=false] - Whether to render as LaTeX\n */\nfunction setTooltip(element, text, isLatex = false) {\n if (!element || !text) return;\n\n // Remove any existing title attribute\n element.removeAttribute('title');\n\n if (isLatex) {\n element.classList.add('has-latex-tooltip');\n element.classList.remove('twm-has-tooltip');\n element.setAttribute('data-latex-tooltip', text);\n } else {\n element.classList.add('twm-has-tooltip');\n element.classList.remove('has-latex-tooltip');\n element.setAttribute('data-tooltip', text);\n }\n}\n\n/**\n * Refresh tooltips for dynamically added content.\n * Removes title attributes that might cause native tooltips.\n * @param {HTMLElement} [container=document] - Container to search within\n */\nfunction refreshTooltips(container = document) {\n container.querySelectorAll('.twm-has-tooltip, .has-latex-tooltip').forEach(el => {\n el.removeAttribute('title');\n });\n}\n\n// ES module exports \u2014 the real interface.\nexport const TooltipService = {\n show: showTooltip,\n hide: hideTooltip,\n set: setTooltip,\n refresh: refreshTooltips,\n init: initializeTooltips\n};\n\nexport default TooltipService;\n\n// Everything below is a side effect of IMPORTING this file, and it is guarded.\n//\n// Unguarded, it touched `document` and `window` at module scope, which made\n// @flexdesk/widgets throw `ReferenceError: window is not defined` the moment anything\n// imported it outside a browser. The DOM check is not defensive programming; it\n// is the difference between a module and a script.\n//\n// `window.LatexTooltip` stays, because unlike `window.InlineRenamer` it is real:\n// roughly 25 call sites read it, all as `window.LatexTooltip?.set(...)`, and one\n// of them is INSIDE the library (window_chrome_controller.js). That last one is a\n// hidden dependency on a global and should import TooltipService instead \u2014 a small\n// piece of P6 cleanup, noted rather than smuggled in here.\nif (typeof document !== 'undefined') {\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', initializeTooltips);\n } else {\n initializeTooltips();\n }\n}\n\nif (typeof window !== 'undefined') {\n window.LatexTooltip = TooltipService;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\r\n * ControllerBase (js_new)\r\n *\r\n * Shared superclass for UI controllers (tab, panel, layout, etc.). Provides\r\n * deterministic teardown, scoped event subscriptions, and dependency injection.\r\n */\r\nexport class ControllerBase {\r\n constructor({ eventBus, dataManager, logger } = {}) {\r\n if (new.target === ControllerBase) {\r\n throw new Error('ControllerBase is abstract \u2013 extend it instead');\r\n }\r\n\r\n this.eventBus = eventBus;\r\n this.dataManager = dataManager;\r\n this.logger = logger;\r\n this._disposers = new Set();\r\n }\r\n\r\n /**\r\n * Register a disposer callback to guarantee teardown.\r\n */\r\n trackDisposer(disposer) {\r\n if (typeof disposer === 'function') {\r\n this._disposers.add(disposer);\r\n }\r\n }\r\n\r\n /**\r\n * Attach controller-specific DOM/event wiring. Subclasses implement this.\r\n */\r\n initialize(/* options */) {\r\n throw new Error('ControllerBase.initialize must be implemented by subclasses');\r\n }\r\n\r\n /**\r\n * Dispose all tracked resources.\r\n */\r\n dispose() {\r\n for (const disposer of this._disposers) {\r\n try {\r\n disposer();\r\n } catch (err) {\r\n this.logger?.error?.('ui', 'Controller disposer failed', err);\r\n }\r\n }\r\n this._disposers.clear();\r\n }\r\n}\r\n", "/**\r\n * PageBase (js_new)\r\n *\r\n * Abstract shell for every top-level UI page (node workspace, simulation, data).\r\n * Handles dependency injection + shared lifecycle hooks so individual pages only\r\n * focus on domain logic.\r\n *\r\n * ## Async Initialization Pattern\r\n * Pages with async initialization should:\r\n * 1. Store the init promise: `this._initPromise = this.init();` in mount()\r\n * 2. Use `await this.waitForReady()` in show()/hydrate() to wait for init\r\n * 3. Mark completion by resolving the promise (init() returns)\r\n *\r\n * Example:\r\n * ```javascript\r\n * mount(container) {\r\n * this.container = container;\r\n * this._initPromise = this.init(); // Store promise\r\n * this._mounted = true;\r\n * }\r\n *\r\n * async show() {\r\n * await this.waitForReady(); // Wait for init if still running\r\n * this.refresh();\r\n * }\r\n * ```\r\n */\r\nexport class PageBase {\r\n constructor({ eventBus, dataManager, notificationCenter, logger } = {}) {\r\n if (new.target === PageBase) {\r\n throw new Error('PageBase is abstract \u2013 extend it instead');\r\n }\r\n\r\n this.eventBus = eventBus;\r\n this.dataManager = dataManager;\r\n this.notificationCenter = notificationCenter;\r\n this.logger = logger;\r\n this._mounted = false;\r\n\r\n /**\r\n * Promise that resolves when async initialization completes.\r\n * Pages with async init should set this in mount().\r\n * @type {Promise<void>|null}\r\n */\r\n this._initPromise = null;\r\n }\r\n\r\n /**\r\n * Mount the page into a DOM container. Concrete pages must override this.\r\n * For pages with async initialization, store the init promise:\r\n * `this._initPromise = this.init();`\r\n */\r\n mount(/* container */) {\r\n throw new Error('PageBase.mount must be implemented by subclasses');\r\n }\r\n\r\n /**\r\n * Wait for the page to complete initialization.\r\n * Returns immediately if no async init or if already complete.\r\n * @returns {Promise<void>}\r\n */\r\n async waitForReady() {\r\n if (this._initPromise) {\r\n try {\r\n await this._initPromise;\r\n } catch (err) {\r\n this.logger?.warn?.('page', 'Init promise rejected', err);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Optional hook invoked after the initial mount to hydrate data/state.\r\n * For pages with async init, this should await waitForReady().\r\n */\r\n async hydrate(/* options */) {\r\n // default: wait for init to complete\r\n await this.waitForReady();\r\n }\r\n\r\n /**\r\n * Optional hook for when the page becomes active (tab switched, etc.).\r\n */\r\n onActivated(/* context */) {\r\n // default no-op\r\n }\r\n\r\n /**\r\n * Optional hook for when the page is hidden/unmounted but not disposed.\r\n */\r\n onDeactivated(/* context */) {\r\n // default no-op\r\n }\r\n\r\n /**\r\n * Dispose resources/event subscriptions.\r\n */\r\n dispose() {\r\n this._mounted = false;\r\n this._initPromise = null;\r\n }\r\n}\r\n", "/**\n * About Dialog Component\n *\n * A modal that shows a product's name, version, license, homepage and\n * third-party credits. It knows NOTHING about which product \u2014 the caller\n * supplies all of it.\n *\n * It used to hardcode EcoAgent's: PRODUCT_NAME, the GitHub URL, the tagline\n * (\"Heterogeneous-agent, stock-flow-consistent macroeconomic simulation\") and\n * two dependency lists. A library that ships an About box for somebody else's\n * application is not a library.\n *\n * EcoAgent's values now live in ui/js/ecoagent/about.js and are pushed in.\n *\n * @typedef {{name: string, license: string, url: string}} Dep\n * @typedef {{title: string, deps: Dep[]}} DepSection\n */\n\nimport { ManagedWindow } from './managed_window.js';\n\nfunction createExternalLink(text, url, className) {\n const a = document.createElement('a');\n a.className = className;\n a.textContent = text;\n a.href = url;\n a.title = url;\n a.addEventListener('click', (e) => {\n e.preventDefault();\n window.open(url, '_blank');\n });\n return a;\n}\n\nfunction buildDepSection(title, deps) {\n const section = document.createElement('div');\n section.className = 'twm-about-dialog__section';\n\n const heading = document.createElement('div');\n heading.className = 'twm-about-dialog__section-title';\n heading.textContent = title;\n section.appendChild(heading);\n\n const list = document.createElement('div');\n list.className = 'twm-about-dialog__dep-list';\n\n for (const dep of deps) {\n const row = document.createElement('div');\n row.className = 'twm-about-dialog__dep';\n\n const link = createExternalLink(dep.name, dep.url, 'twm-about-dialog__dep-name');\n row.appendChild(link);\n\n const lic = document.createElement('span');\n lic.className = 'twm-about-dialog__dep-license';\n lic.textContent = dep.license;\n row.appendChild(lic);\n\n list.appendChild(row);\n }\n\n section.appendChild(list);\n return section;\n}\n\n/**\n * Show the About dialog for whatever product the caller names.\n *\n * @param {Object} product\n * @param {string} product.name Product name \u2014 the title and the heading.\n * @param {string} [product.version]\n * @param {string} [product.tagline]\n * @param {string} [product.license] Shown as \"License: <x>\"; omitted if absent.\n * @param {string} [product.url] Homepage; omitted if absent.\n * @param {string} [product.urlLabel='Homepage']\n * @param {string} [product.logo='info'] Material symbol shown beside the title.\n * @param {DepSection[]} [product.credits=[]] Third-party credit sections.\n * @returns {Promise<void>} Resolves when the dialog is closed.\n */\nexport function showAboutDialog(product = {}) {\n const {\n name = 'Application',\n version = '',\n tagline = '',\n license = '',\n url = '',\n urlLabel = 'Homepage',\n logo = 'info',\n credits = [],\n } = product;\n\n return new Promise((resolve) => {\n let resolved = false;\n\n const finish = () => {\n if (resolved) return;\n resolved = true;\n dialogWindow.close();\n resolve();\n };\n\n // --- Content ---\n const contentEl = document.createElement('div');\n contentEl.className = 'twm-about-dialog__content';\n\n // Header\n const header = document.createElement('div');\n header.className = 'twm-about-dialog__header';\n\n const logoEl = document.createElement('span');\n logoEl.className = 'twm-about-dialog__logo material-symbols-outlined';\n logoEl.textContent = logo;\n header.appendChild(logoEl);\n\n const title = document.createElement('h2');\n title.className = 'twm-about-dialog__title';\n title.textContent = name;\n header.appendChild(title);\n\n if (version) {\n const versionEl = document.createElement('div');\n versionEl.className = 'twm-about-dialog__version';\n versionEl.textContent = `Version ${version}`;\n header.appendChild(versionEl);\n }\n\n if (tagline) {\n const taglineEl = document.createElement('div');\n taglineEl.className = 'twm-about-dialog__tagline';\n taglineEl.textContent = tagline;\n header.appendChild(taglineEl);\n }\n\n contentEl.appendChild(header);\n\n // Body (scrollable)\n const body = document.createElement('div');\n body.className = 'twm-about-dialog__body';\n\n // Project section \u2014 only if there is something to put in it.\n if (url || license) {\n const projectSection = document.createElement('div');\n projectSection.className = 'twm-about-dialog__section';\n\n const projectTitle = document.createElement('div');\n projectTitle.className = 'twm-about-dialog__section-title';\n projectTitle.textContent = 'Project';\n projectSection.appendChild(projectTitle);\n\n const links = document.createElement('div');\n links.className = 'twm-about-dialog__links';\n\n if (url) {\n const link = createExternalLink(urlLabel, url, 'twm-about-dialog__link');\n const icon = document.createElement('span');\n icon.className = 'material-symbols-outlined';\n icon.textContent = 'open_in_new';\n link.prepend(icon);\n links.appendChild(link);\n }\n\n if (license) {\n const licenseSpan = document.createElement('span');\n licenseSpan.className = 'twm-about-dialog__license-text';\n const licIcon = document.createElement('span');\n licIcon.className = 'material-symbols-outlined';\n licIcon.textContent = 'license';\n licenseSpan.appendChild(licIcon);\n licenseSpan.appendChild(document.createTextNode(`License: ${license}`));\n links.appendChild(licenseSpan);\n }\n\n projectSection.appendChild(links);\n body.appendChild(projectSection);\n }\n\n for (const section of credits) {\n body.appendChild(buildDepSection(section.title, section.deps ?? []));\n }\n\n contentEl.appendChild(body);\n\n // Footer\n const footer = document.createElement('div');\n footer.className = 'twm-about-dialog__footer';\n\n const closeBtn = document.createElement('button');\n closeBtn.type = 'button';\n closeBtn.className = 'twm-about-dialog__btn twm-about-dialog__btn--close';\n closeBtn.textContent = 'Close';\n closeBtn.addEventListener('click', finish);\n footer.appendChild(closeBtn);\n\n contentEl.appendChild(footer);\n\n // --- Window ---\n const dialogWindow = new ManagedWindow({\n id: 'about-dialog',\n title: `About ${name}`,\n icon: 'info',\n content: contentEl,\n minWidth: 420,\n minHeight: 400,\n defaultWidth: 460,\n defaultHeight: 540,\n canMinimize: false,\n canMaximize: false,\n canResize: false,\n canDrag: false,\n modal: true,\n onClose: () => {\n if (!resolved) {\n resolved = true;\n resolve();\n }\n },\n });\n\n dialogWindow.show();\n\n requestAnimationFrame(() => {\n closeBtn.focus();\n });\n });\n}\n", "/**\n * \u2550\u2550 THE ALERT LOG \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\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 * What an application told its user, kept: every entry, newest first, read or\n * not, until it is dismissed or falls off the end (FlexDesk STORY-0019, from\n * bugdesk's `alerts.js`). NotificationCenter's toasts are the moment; this is\n * the history the Alerts pane (`alerts_pane.js`) and the bell\n * (NotificationHistory's `alertLog` option) read.\n *\n * An ENTRY is `{ id, at, level, title, body?, ref?, read, ruleId?, rule? }`.\n * `at` is a Date; `level` is one of `info`, `warning`, `alert` (`normalizeLevel`\n * maps the toast's `warn`/`error` and the server's `danger` onto them).\n *\n * WHERE ENTRIES LIVE IS THE EMBEDDER'S \u2014 a pluggable SOURCE:\n *\n * load({ offset, limit }) \u2192 { entries, more?, unread? } a page, newest first\n * markRead(ids | null) \u2192 null is \"all\"\n * dismiss(ids | null) \u2192 optional; without it nothing can be dismissed\n *\n * bugdesk keeps the whole log in its workspace state (`localSource`: one\n * blob, read once, written on every change); Tables pages its server's\n * notifications and has no dismiss. A source's `unread` is the count beyond\n * the loaded page \u2014 the server knows it, the page does not.\n *\n * CHANGES ARE APPLIED HERE FIRST and the source told after, so a click marks\n * read at once; a source that refuses is logged and the log re-read, rather\n * than the click being made to wait on a round trip.\n */\n\n/** The three levels, worst last; `icon` is a Material Symbols name. */\nexport const ALERT_LEVELS = Object.freeze({\n info: Object.freeze({ label: 'Info', icon: 'info' }),\n warning: Object.freeze({ label: 'Warning', icon: 'warning' }),\n alert: Object.freeze({ label: 'Alert', icon: 'notifications_active' }),\n});\n\nconst LEVEL_ALIASES = { warn: 'warning', error: 'alert', danger: 'alert', critical: 'alert', success: 'info' };\n\n/** One of `info`, `warning`, `alert`, whatever the caller spelt. */\nexport function normalizeLevel(level) {\n const l = String(level ?? '').toLowerCase();\n if (ALERT_LEVELS[l]) return l;\n return LEVEL_ALIASES[l] ?? 'info';\n}\n\n/** The worst level among these entries \u2014 a badge's colour \u2014 or null for none. */\nexport function worstLevel(entries) {\n let worst = null;\n for (const e of entries || []) {\n const l = normalizeLevel(e?.level);\n if (l === 'alert') return 'alert';\n if (l === 'warning') worst = 'warning';\n else if (!worst) worst = 'info';\n }\n return worst;\n}\n\n/** \"just now\", \"5 min ago\", \"3 h ago\"; older than a day, the clock time (the day header has the date). */\nexport function ago(at, now = new Date()) {\n const s = Math.max(0, (now - at) / 1000);\n if (s < 60) return 'just now';\n if (s < 3600) return `${Math.floor(s / 60)} min ago`;\n if (s < 86400) return `${Math.floor(s / 3600)} h ago`;\n return at.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });\n}\n\n/** TODAY, YESTERDAY, or the date \u2014 the Alerts pane's day header. */\nexport function dayLabel(at, now = new Date()) {\n const d = new Date(at.getFullYear(), at.getMonth(), at.getDate());\n const t = new Date(now.getFullYear(), now.getMonth(), now.getDate());\n const days = Math.round((t - d) / 86400000);\n if (days === 0) return 'TODAY';\n if (days === 1) return 'YESTERDAY';\n return at.toLocaleDateString([], { weekday: 'short', day: 'numeric', month: 'short', year: 'numeric' })\n .toUpperCase();\n}\n\nlet _seq = 0;\n\n/** An entry in the shape the log keeps, from whatever a source or a caller handed in. */\nfunction normalizeEntry(raw) {\n const at = raw.at instanceof Date ? raw.at : new Date(raw.at ?? Date.now());\n return {\n ...raw,\n id: String(raw.id ?? `${Date.now().toString(36)}-${(_seq++).toString(36)}`),\n at: Number.isNaN(at.getTime()) ? new Date() : at,\n level: normalizeLevel(raw.level),\n title: String(raw.title ?? ''),\n read: !!raw.read,\n };\n}\n\n/**\n * A source that keeps the whole log in one stored value \u2014 bugdesk's workspace\n * state, or localStorage. `read()` answers the saved array (or a promise of\n * it); `write(array)` stores one. Dates are written as ISO strings.\n */\nexport function localSource({ read, write, limit = 300 } = {}) {\n let all = null;\n const save = () => {\n try {\n write?.(all.map((e) => ({ ...e, at: e.at.toISOString() })));\n } catch (err) { console.warn('[alert-log] the log could not be saved', err); }\n };\n const ensure = async () => {\n if (all) return all;\n let saved = [];\n try { saved = (await read?.()) ?? []; } catch (err) {\n console.warn('[alert-log] the log could not be read', err);\n }\n all = (Array.isArray(saved) ? saved : []).filter((e) => e && typeof e === 'object')\n .map(normalizeEntry).sort((a, b) => b.at - a.at).slice(0, limit);\n return all;\n };\n return {\n local: true,\n async load({ offset = 0, limit: n = limit } = {}) {\n const list = await ensure();\n return { entries: list.slice(offset, offset + n), more: offset + n < list.length };\n },\n async add(entry) {\n const list = await ensure();\n list.unshift(entry);\n if (list.length > limit) list.length = limit;\n save();\n },\n async markRead(ids) {\n const want = ids ? new Set(ids) : null;\n for (const e of await ensure()) if (!want || want.has(e.id)) e.read = true;\n save();\n },\n async dismiss(ids) {\n const want = ids ? new Set(ids) : null;\n all = (await ensure()).filter((e) => want && !want.has(e.id));\n save();\n },\n };\n}\n\n/**\n * @param {object} [opts]\n * @param {object} [opts.source] where entries live; none keeps them in memory only\n * @param {number} [opts.limit] most entries held, and a page's size\n * @returns the log\n */\nexport function createAlertLog({ source = null, limit = 300 } = {}) {\n let entries = [];\n let more = false;\n let remoteUnread = null;\n let loaded = false;\n let loading = null;\n const listeners = new Set();\n\n const changed = () => {\n for (const fn of [...listeners]) {\n try { fn(log); } catch (err) { console.warn('[alert-log] listener failed', err); }\n }\n };\n const tell = (verb, ...args) => {\n const fn = source?.[verb];\n if (typeof fn !== 'function') return;\n Promise.resolve().then(() => fn.apply(source, args)).catch((err) => {\n console.warn(`[alert-log] the source refused ${verb}`, err);\n log.refresh();\n });\n };\n const page = async (offset) => {\n const res = (await source?.load?.({ offset, limit })) ?? {};\n const got = (res.entries ?? []).map(normalizeEntry);\n return { got, more: !!res.more, unread: Number.isFinite(res.unread) ? res.unread : null };\n };\n\n const log = {\n /** Loaded entries, newest first. */\n entries: () => entries,\n loaded: () => loaded,\n /** Whether the source has older entries than those loaded. */\n hasMore: () => more,\n /** Whether entries can be dismissed: a log with no source, or a source that can. */\n canDismiss: () => !source || typeof source.dismiss === 'function',\n /** Unread entries: the source's count when it knows one, else the loaded ones. */\n unreadCount() {\n const here = entries.filter((e) => !e.read).length;\n return remoteUnread === null ? here : Math.max(remoteUnread, here);\n },\n /** The worst level among unread entries, or null. */\n worstUnread: () => worstLevel(entries.filter((e) => !e.read)),\n get: (id) => entries.find((e) => e.id === String(id)) ?? null,\n\n /** `fn(log)` after every change; answers the unsubscribe. */\n subscribe(fn) {\n listeners.add(fn);\n return () => listeners.delete(fn);\n },\n\n /** The first page, again. */\n refresh() {\n if (!source?.load) { loaded = true; changed(); return Promise.resolve(log); }\n loading = page(0).then(({ got, more: m, unread }) => {\n entries = got;\n more = m;\n remoteUnread = unread;\n loaded = true;\n changed();\n return log;\n }).catch((err) => {\n console.warn('[alert-log] the log could not be loaded', err);\n loaded = true;\n changed();\n return log;\n }).finally(() => { loading = null; });\n return loading;\n },\n /** Load once; later calls answer the same promise or nothing. */\n load() { return loading ?? (loaded ? Promise.resolve(log) : log.refresh()); },\n /** The next page, after the loaded ones. */\n async loadMore() {\n if (!more || !source?.load) return log;\n const { got, more: m, unread } = await page(entries.length);\n const seen = new Set(entries.map((e) => e.id));\n entries = [...entries, ...got.filter((e) => !seen.has(e.id))];\n more = m;\n if (unread !== null) remoteUnread = unread;\n changed();\n return log;\n },\n\n /** A new entry raised HERE (bugdesk's rules): kept, and handed to the source to save. */\n add(raw) {\n const entry = normalizeEntry(raw);\n entries = [entry, ...entries.filter((e) => e.id !== entry.id)];\n if (entries.length > limit) entries.length = limit;\n if (remoteUnread !== null && !entry.read) remoteUnread += 1;\n tell('add', entry);\n changed();\n return entry;\n },\n /** Entries that arrived from the source's side (a push): shown, not saved back. */\n receive(raws) {\n const got = (Array.isArray(raws) ? raws : [raws]).map(normalizeEntry);\n const ids = new Set(got.map((e) => e.id));\n const fresh = got.filter((e) => !entries.some((x) => x.id === e.id));\n entries = [...got, ...entries.filter((e) => !ids.has(e.id))]\n .sort((a, b) => b.at - a.at).slice(0, limit);\n if (remoteUnread !== null) remoteUnread += fresh.filter((e) => !e.read).length;\n changed();\n },\n /** Mark these read \u2014 all of them when `ids` is omitted. */\n markRead(ids = null) {\n const want = ids ? new Set(ids.map(String)) : null;\n let n = 0;\n for (const e of entries) if (!e.read && (!want || want.has(e.id))) { e.read = true; n++; }\n if (remoteUnread !== null) remoteUnread = want ? Math.max(0, remoteUnread - n) : 0;\n if (!n && want) return;\n tell('markRead', want ? [...want] : null);\n changed();\n },\n /** Remove these \u2014 all of them when `ids` is omitted. Nothing, when the source cannot. */\n dismiss(ids = null) {\n if (!log.canDismiss()) return;\n const want = ids ? new Set(ids.map(String)) : null;\n const gone = entries.filter((e) => !want || want.has(e.id));\n if (!gone.length) return;\n entries = want ? entries.filter((e) => !want.has(e.id)) : [];\n if (remoteUnread !== null) {\n remoteUnread = want ? Math.max(0, remoteUnread - gone.filter((e) => !e.read).length) : 0;\n }\n tell('dismiss', want ? [...want] : null);\n changed();\n },\n };\n if (!source?.load) loaded = true;\n return log;\n}\n", "/**\n * \u2550\u2550 THE ALERTS PANE \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\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 * An alert log (`alert_log.js`) drawn as the bottom panel's Alerts tab: level\n * chips with counts, a text filter, entries grouped by day with relative\n * times, an unread mark, Open and Dismiss on each row, Mark all read and Clear\n * for the lot (FlexDesk STORY-0019, from bugdesk's `alerts.js`). The same\n * layout whether the log is local or pages a server: *Load older* appears\n * when the source has more.\n *\n * mountAlertsPane(el, { log, onOpen: (entry) => \u2026, onBadge: ({ unread, level }) => \u2026 })\n *\n * OPTIONAL, for an embedder with rules of its own (bugdesk): `rules` is\n * `{ list() \u2192 [{ id, name, level, meta?, off? }], onEdit?, foot? }` \u2014 a column\n * of them on the left that narrows the log to one rule (entries carry\n * `ruleId`) \u2014 and `stillMatches(entry)` \u2192 true / false / null, drawn as \"still\n * matches\" or \"no longer matches\" on each row.\n *\n * NEVER REBUILT UNDER THE POINTER. A log changes on its own \u2014 a push from the\n * server, a rule firing, the minute tick \u2014 and a row repainted between a\n * mousedown and its click loses the click (Tables' recorded trap). While a\n * button is down inside the pane a repaint waits, and runs once it is up.\n * The bar (chips, the filter, the buttons) is built once and updated in\n * place, so typing in the filter never loses the caret either.\n *\n * OLDER ENTRIES LOAD AS YOU SCROLL (Tables STORY-0293): when the list is\n * scrolled to within :data:`MORE_WITHIN_PX` of its end and the source has\n * more, the next page is asked for \u2014 once at a time. *Load older* stays at the\n * end, for a list too short to scroll and for the keyboard.\n */\n\nimport { ALERT_LEVELS, ago, dayLabel, normalizeLevel } from './alert_log.js';\n\nconst CHIPS = [['all', 'All'], ['alert', 'Alert'], ['warning', 'Warning'], ['info', 'Info']];\n\n/** How near the end of the list a scroll asks for the next page. */\nexport const MORE_WITHIN_PX = 48;\n\n/**\n * @param {HTMLElement} host\n * @param {object} opts\n * @param {object} opts.log `createAlertLog(\u2026)`\n * @param {Function}[opts.onOpen] `(entry)` \u2014 Open; the entry is marked read first\n * @param {Function}[opts.onBadge] `({ unread, level })` after every change \u2014 a tab's badge\n * @param {object} [opts.rules] `{ list, onEdit?, foot? }`\n * @param {Function}[opts.stillMatches] `(entry) \u2192 boolean | null`\n * @param {Function}[opts.describe] `(entry) \u2192 string` \u2014 a small chip on the row (bugdesk: the store)\n * @param {string} [opts.status] the footer line\n * @param {object} [opts.empty] `{ none, filtered }` \u2014 the two empty texts\n * @returns {{ refresh, destroy, root }}\n */\nexport function mountAlertsPane(host, {\n log, onOpen = null, onBadge = null, rules = null, stillMatches = null, describe = null,\n status = '', empty = {},\n} = {}) {\n const doc = host.ownerDocument;\n const el = (tag, cls, text) => {\n const n = doc.createElement(tag);\n if (cls) n.className = cls;\n if (text !== undefined) n.textContent = text;\n return n;\n };\n const icon = (name) => el('span', 'material-symbols-outlined', name);\n\n let level = 'all';\n let rule = null;\n let q = '';\n let pointerDown = false;\n let pending = false;\n let destroyed = false;\n\n // \u2500\u2500 the frame, built once \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 const root = el('div', 'twm-alerts');\n let ruleList = null;\n if (rules) {\n const side = el('div', 'twm-alerts__rules');\n const head = el('div', 'twm-alerts__head');\n head.append(el('span', 'twm-alerts__caps', 'RULES'), el('span', 'twm-alerts__spacer'));\n if (rules.onEdit) {\n const edit = el('button', 'twm-alerts__link', 'Edit rules');\n edit.type = 'button';\n edit.dataset.act = 'edit-rules';\n head.append(edit);\n }\n ruleList = el('div', 'twm-alerts__rulelist');\n side.append(head, ruleList);\n if (rules.foot) side.append(el('div', 'twm-alerts__foot', rules.foot));\n root.append(side);\n }\n const main = el('div', 'twm-alerts__main');\n const bar = el('div', 'twm-alerts__bar');\n const chips = el('div', 'twm-alerts__chips');\n chips.setAttribute('role', 'group');\n chips.setAttribute('aria-label', 'Level');\n const chipEls = new Map();\n for (const [key, label] of CHIPS) {\n const chip = el('button', 'twm-alerts__chip');\n chip.type = 'button';\n chip.dataset.level = key;\n chip.append(doc.createTextNode(`${label} `), el('span', 'twm-alerts__count', '0'));\n chips.append(chip);\n chipEls.set(key, chip);\n }\n const input = el('input', 'twm-alerts__q');\n input.type = 'text';\n input.autocomplete = 'off';\n input.spellcheck = false;\n input.placeholder = 'Filter';\n input.setAttribute('aria-label', 'Filter alerts');\n const readAll = el('button', 'twm-btn twm-alerts__btn', 'Mark all read');\n readAll.type = 'button';\n readAll.dataset.act = 'read-all';\n const clear = el('button', 'twm-btn twm-alerts__btn', 'Clear');\n clear.type = 'button';\n clear.dataset.act = 'clear';\n bar.append(chips, input, el('span', 'twm-alerts__spacer'), readAll, clear);\n const list = el('div', 'twm-alerts__log');\n const foot = el('div', 'twm-alerts__status', status);\n foot.hidden = !status;\n main.append(bar, list, foot);\n root.append(main);\n host.append(root);\n\n // \u2500\u2500 what is shown \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 const byRule = () => (rule ? log.entries().filter((e) => String(e.ruleId) === rule) : log.entries());\n const shown = () => {\n const needle = q.trim().toLowerCase();\n return byRule()\n .filter((e) => level === 'all' || e.level === level)\n .filter((e) => !needle || `${e.ref ?? ''} ${e.title} ${e.body ?? ''} ${e.rule ?? ''}`\n .toLowerCase().includes(needle));\n };\n\n function row(entry, now) {\n const lv = ALERT_LEVELS[normalizeLevel(entry.level)];\n const r = el('div', `twm-alerts__row twm-alerts__row--${entry.level}${entry.read ? '' : ' twm-alerts__row--unread'}`);\n r.dataset.id = entry.id;\n const mark = el('span', 'twm-alerts__unread');\n mark.setAttribute('aria-label', entry.read ? 'Read' : 'Unread');\n const ic = icon(lv.icon);\n ic.classList.add('twm-alerts__icon');\n ic.title = lv.label;\n const time = el('span', 'twm-alerts__time', ago(entry.at, now));\n time.title = entry.at.toLocaleString();\n const text = el('span', 'twm-alerts__text');\n text.append(el('span', 'twm-alerts__title', entry.title));\n if (entry.body) text.append(el('span', 'twm-alerts__body', entry.body));\n const cells = [mark, ic, time];\n if (rules) cells.push(el('span', 'twm-alerts__rule', entry.rule ?? ''));\n const tag = describe?.(entry);\n cells.push(el('span', tag ? 'twm-alerts__tag' : 'twm-alerts__tag twm-alerts__tag--none', tag ?? ''));\n const ref = el(entry.ref && onOpen ? 'button' : 'span', 'twm-alerts__ref', entry.ref ?? '');\n if (ref.tagName === 'BUTTON') { ref.type = 'button'; ref.dataset.open = entry.id; }\n cells.push(ref, text);\n if (stillMatches) {\n const still = stillMatches(entry);\n cells.push(el('span', `twm-alerts__state${still === false ? ' twm-alerts__state--gone' : ''}`,\n still === true ? 'still matches' : still === false ? 'no longer matches' : ''));\n }\n const acts = el('span', 'twm-alerts__acts');\n if (onOpen) {\n const open = el('button', 'twm-alerts__icon-btn');\n open.type = 'button';\n open.dataset.open = entry.id;\n open.title = 'Open';\n open.setAttribute('aria-label', 'Open');\n open.append(icon('open_in_new'));\n acts.append(open);\n }\n if (log.canDismiss()) {\n const dis = el('button', 'twm-alerts__icon-btn');\n dis.type = 'button';\n dis.dataset.dismiss = entry.id;\n dis.title = 'Dismiss';\n dis.setAttribute('aria-label', 'Dismiss');\n dis.append(icon('close'));\n acts.append(dis);\n }\n cells.push(acts);\n r.append(...cells);\n return r;\n }\n\n function paint() {\n if (destroyed) return;\n if (pointerDown) { pending = true; return; }\n pending = false;\n const now = new Date();\n const all = log.entries();\n const scoped = byRule();\n\n for (const [key, chip] of chipEls) {\n const on = level === key;\n chip.classList.toggle('twm-alerts__chip--on', on);\n chip.setAttribute('aria-pressed', String(on));\n chip.querySelector('.twm-alerts__count').textContent =\n String(scoped.filter((e) => key === 'all' || e.level === key).length);\n }\n readAll.disabled = !all.some((e) => !e.read) && log.unreadCount() === 0;\n clear.hidden = !log.canDismiss();\n clear.disabled = !all.length;\n\n if (ruleList) {\n const items = [{ id: null, name: 'All alerts', meta: String(all.length) }, ...(rules.list?.() ?? [])];\n ruleList.replaceChildren(...items.map((r) => {\n const key = r.id === null ? null : String(r.id);\n const b = el('button', `twm-alerts__rulebtn${rule === key ? ' twm-alerts__rulebtn--on' : ''}${r.off ? ' twm-alerts__rulebtn--off' : ''}`);\n b.type = 'button';\n b.dataset.rule = key ?? '';\n b.setAttribute('aria-pressed', String(rule === key));\n b.append(el('span', `twm-alerts__dot${r.level ? ` twm-alerts__dot--${normalizeLevel(r.level)}` : ''}`),\n el('span', 'twm-alerts__rulename', r.name || 'Unnamed rule'),\n el('span', 'twm-alerts__meta', r.meta ?? ''));\n return b;\n }));\n }\n\n const rows = [];\n let lastDay = '';\n for (const entry of shown()) {\n const day = dayLabel(entry.at, now);\n if (day !== lastDay) rows.push(el('div', 'twm-alerts__day', day));\n lastDay = day;\n rows.push(row(entry, now));\n }\n if (!rows.length) {\n rows.push(el('div', 'twm-alerts__none', !log.loaded() ? 'Loading\u2026'\n : all.length ? (empty.filtered ?? 'No alerts match.') : (empty.none ?? 'Nothing yet.')));\n }\n if (log.hasMore()) {\n const older = el('button', 'twm-btn twm-alerts__more', 'Load older');\n older.type = 'button';\n older.dataset.act = 'more';\n rows.push(older);\n }\n const scroll = list.scrollTop;\n list.replaceChildren(...rows);\n list.scrollTop = scroll;\n onBadge?.({ unread: log.unreadCount(), level: log.worstUnread() });\n }\n\n // \u2500\u2500 input \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 const onDown = () => { pointerDown = true; };\n const onUp = () => {\n if (!pointerDown) return;\n // After the click this mouseup belongs to has been dispatched.\n setTimeout(() => {\n pointerDown = false;\n if (pending) paint();\n }, 0);\n };\n root.addEventListener('mousedown', onDown, true);\n root.addEventListener('pointerdown', onDown, true);\n doc.addEventListener('mouseup', onUp, true);\n doc.addEventListener('pointerup', onUp, true);\n doc.addEventListener('pointercancel', onUp, true);\n\n root.addEventListener('click', (event) => {\n const t = event.target;\n const chip = t.closest('[data-level]');\n if (chip) { level = chip.dataset.level; paint(); return; }\n const r = t.closest('[data-rule]');\n if (r) { rule = r.dataset.rule || null; paint(); return; }\n const open = t.closest('[data-open]');\n if (open) {\n const entry = log.get(open.dataset.open);\n if (!entry) return;\n log.markRead([entry.id]);\n onOpen?.(entry);\n return;\n }\n const dis = t.closest('[data-dismiss]');\n if (dis) { log.dismiss([dis.dataset.dismiss]); return; }\n const act = t.closest('[data-act]')?.dataset.act;\n if (act === 'read-all') log.markRead();\n else if (act === 'clear') log.dismiss();\n else if (act === 'more') log.loadMore();\n else if (act === 'edit-rules') rules?.onEdit?.();\n });\n input.addEventListener('input', () => { q = input.value; paint(); });\n\n let loadingMore = false;\n list.addEventListener('scroll', () => {\n if (loadingMore || !log.hasMore()) return;\n if (list.scrollTop + list.clientHeight < list.scrollHeight - MORE_WITHIN_PX) return;\n loadingMore = true;\n Promise.resolve(log.loadMore()).catch(() => {}).finally(() => { loadingMore = false; });\n });\n\n const unsubscribe = log.subscribe(() => paint());\n // \"5 min ago\" moves on its own.\n const timer = setInterval(paint, 60000);\n paint();\n log.load?.();\n\n return {\n root,\n refresh: paint,\n destroy() {\n if (destroyed) return;\n destroyed = true;\n clearInterval(timer);\n unsubscribe();\n doc.removeEventListener('mouseup', onUp, true);\n doc.removeEventListener('pointerup', onUp, true);\n doc.removeEventListener('pointercancel', onUp, true);\n root.remove();\n },\n };\n}\n", "/**\n * attribute_list_editor.js \u2014 generic AttributeSpec list editor.\n *\n * One reusable component for every entity that declares a typed-slot\n * list: Asset.attributes, Archetype.attributes, SectorKind.requires,\n * MarketKind.requires, Flow.params, KPI.params. Mounts a SortableList\n * (drag-reorder + add + remove + empty-state) with typed cells:\n *\n * - scalar (number / integer / string / boolean): typed `<input>`\n * - expression: free-text input \u2014 engine evaluates each tick\n * - ref:<target>: typeahead-ish `<select>` populated by a caller-\n * supplied resolver returning {id, label} lists\n * - list[ref:<target>]: comma-separated input (UI primitive \u2014 chip\n * editor can land later without changing the data shape)\n * - select: dropdown of options (auto when `options[]` is set)\n *\n * Each row exposes the columns in `showColumns` (defaults to the full\n * set); callers narrow it (e.g. SectorKind.requires only needs name +\n * type + description, not default/value). Layout follows the column\n * spec \u2014 header strip aligned via CSS grid using --cols.\n *\n * Usage:\n *\n * import { mountAttributeListEditor } from\n * '../../ui/components/attribute_list_editor.js';\n *\n * const editor = mountAttributeListEditor(hostEl, {\n * items: kind.attributes,\n * showColumns: ['name', 'type', 'default', 'value', 'description'],\n * refResolvers: {\n * 'ref:asset': () => api.assets_list(),\n * },\n * onChange: (next) => { kind.attributes = next; save(); },\n * });\n * editor.refresh(); // call after `items` changes externally\n * editor.dispose(); // teardown\n */\n\nimport { SortableList } from './sortable_list.js';\n\n// The types a generic attribute editor knows about, with no application loaded.\n//\n// This used to also list nine EcoAgent entity kinds \u2014 asset_kind, market,\n// sub_sector, currency, sector, market_kind, asset_kind_template, archetype,\n// kpi \u2014 and derive `ref:<kind>` and `list[ref:<kind>]` from them. `types` was\n// ALREADY an injectable option; it simply had EcoAgent's ontology as its\n// default, which meant every consumer who didn't override it inherited a type\n// dropdown full of macroeconomics.\n//\n// Callers who want reference types build them with refTypesFor() and pass them\n// in, alongside the `refResolvers` that make them resolvable.\nconst SCALAR_TYPES = ['number', 'integer', 'string', 'boolean'];\n\nconst DEFAULT_TYPES = [...SCALAR_TYPES, 'expression'];\n\n/** `['agent']` -> `['ref:agent', 'list[ref:agent]']`. */\nexport function refTypesFor(kinds = []) {\n return [\n ...kinds.map((k) => `ref:${k}`),\n ...kinds.map((k) => `list[ref:${k}]`),\n ];\n}\n\nexport { SCALAR_TYPES, DEFAULT_TYPES };\n\nconst DEFAULT_COLUMNS = ['name', 'type', 'default', 'value', 'description'];\n\nconst COLUMN_TEMPLATES = {\n name: { label: 'name', width: 'minmax(140px, 1.2fr)' },\n type: { label: 'type', width: '140px' },\n default: { label: 'default', width: 'minmax(110px, 1fr)' },\n value: { label: 'value', width: 'minmax(110px, 1fr)' },\n description: { label: 'description', width: 'minmax(160px, 2fr)' },\n required: { label: 'req', width: '60px' },\n readonly: { label: 'r/o', width: '60px' },\n expression: { label: 'expression', width: 'minmax(160px, 2fr)' },\n // Layer N3 \u2014 extended AttributeSpec fields. Opt-in via showColumns\n // so existing single-table layouts (asset_kind editor) stay tight;\n // the agent params surface includes them.\n min: { label: 'min', width: '90px' },\n max: { label: 'max', width: '90px' },\n step: { label: 'step', width: '70px' },\n unit: { label: 'unit', width: '80px' },\n distribution: { label: 'dist', width: '110px' },\n // Distribution and \"selection set\" are two different concepts \u2014\n // numeric params sample from a continuous distribution (uniform /\n // normal / lognormal / \u2026), choice params pick from a discrete\n // option set. Keep them in separate columns so the user can tell\n // which is which at a glance.\n choices: { label: 'choices', width: '130px' },\n // Variation-override flags \u2014 R7 in\n // docs/ARCHETYPE_RETHINK_REQUIREMENTS.md. Tight columns so they\n // stay readable next to the scalar fields.\n enabled: { label: 'on', width: '50px' },\n force: { label: 'lock', width: '50px' },\n optional: { label: 'opt', width: '50px' },\n};\n\nconst DISTRIBUTION_OPTIONS = [\n '', 'constant', 'uniform', 'normal', 'lognormal', 'choice',\n];\n\n\n/** Classify one attribute against its parent-archetype counterpart.\n * Layer 8.J1 inheritance display:\n *\n * - 'inherited' \u2014 entity's effective value matches the archetype's\n * default for the same attribute name. UI paints the row blue.\n * - 'overridden' \u2014 entity's value is set AND differs from the\n * archetype's default. UI paints the row solarized orange + shows\n * a revert button.\n * - 'neutral' \u2014 neither side declares a value (or there's no parent).\n * UI paints the row in default style.\n */\nfunction _classifyRow(row, parentByName) {\n if (!parentByName) return 'neutral';\n const p = parentByName.get(row.name);\n if (!p) return 'neutral';\n const ourValue = (row.value !== undefined && row.value !== null)\n ? row.value : row.default;\n const parentValue = (p.value !== undefined && p.value !== null)\n ? p.value : p.default;\n if (ourValue === undefined || ourValue === null) return 'neutral';\n if (parentValue === undefined || parentValue === null) return 'overridden';\n // Loose equality: handles number vs numeric-string from form inputs.\n if (String(ourValue) === String(parentValue)) return 'inherited';\n return 'overridden';\n}\n\n\nexport function mountAttributeListEditor(hostEl, options = {}) {\n const {\n items = [],\n types = DEFAULT_TYPES,\n showColumns = DEFAULT_COLUMNS,\n refResolvers = {},\n onChange = () => {},\n onFlush = () => {},\n addButtonText = '',\n emptyMessage = 'No entries yet.',\n containerId = `attrs-${Math.random().toString(36).slice(2, 8)}`,\n allowReorder = true,\n allowRemove = true,\n // Layer 8.J1: parent-archetype attributes (the inherited baseline).\n // The editor uses this to classify each row as inherited / overridden /\n // neutral and to provide a revert action. Pass [] when no archetype\n // applies; the editor degrades gracefully (all rows render neutral).\n parentAttributes = null,\n createItem = () => ({\n name: '', type: 'string', default: null,\n value: null, description: '',\n }),\n // Layer N3 \u2014 per-column renderer overrides. Callers can supply\n // `cellOverrides: {column_name: (item, callbacks, ctx) => HTMLElement | null}`\n // to swap in a custom cell. Returning `null` falls through to\n // the default renderer. The `ctx` object exposes:\n // refreshRow() \u2014 force a re-render (the wider list refreshes\n // when the row's items change, e.g. type swap).\n // Use cases: agent params' distribution-dict button cell;\n // structured-type modal openers on the default cell.\n cellOverrides = null,\n // R7 \u2014 when true, this editor is mounted as a *variation* of the\n // parent archetype (not on the archetype itself). Rows where\n // the parent has `force=true` lock their editable cells; the\n // `enabled/force/optional` flag columns themselves stay\n // read-only (variations don't author flags, only the\n // archetype does).\n variationMode = false,\n } = options;\n\n // Lookup map for inheritance classification.\n const parentByName = parentAttributes\n ? new Map(parentAttributes.map((p) => [p.name, p]))\n : null;\n\n if (!hostEl) {\n return { refresh() {}, addItem() {}, dispose() {} };\n }\n\n hostEl.classList.add('twm-attr-editor');\n hostEl.style.setProperty('--cols',\n showColumns.map((c) => COLUMN_TEMPLATES[c]?.width || '1fr').join(' '));\n\n const refsCache = new Map();\n const resolveRefOptions = async (target) => {\n if (refsCache.has(target)) return refsCache.get(target);\n const resolver = refResolvers[`ref:${target}`]\n || refResolvers[`list[ref:${target}]`];\n let list = [];\n if (typeof resolver === 'function') {\n try { list = await resolver() || []; }\n catch (e) { console.warn('ref resolver failed', target, e); }\n }\n const normalised = (list || []).map((o) => {\n if (typeof o === 'string') return { id: o, label: o };\n return { id: o.id ?? o.value ?? '', label: o.label ?? o.id ?? '' };\n }).filter((o) => o.id);\n refsCache.set(target, normalised);\n return normalised;\n };\n\n // Header strip \u2014 mimics the SortableList row layout exactly so\n // header cells align with body cells. Row shape is:\n // [drag-handle] [content-with-cols-grid] [remove-button]\n // The header reuses `.sortable-list__row` chrome with placeholder\n // spans for the handle / remove gutters, then the inner content\n // div carries the same `--cols` grid as each row's content div.\n const header = document.createElement('div');\n header.className = 'twm-sortable-list__row twm-attr-editor__header-row';\n if (allowReorder) {\n const handlePh = document.createElement('span');\n handlePh.className = 'twm-sortable-list__handle twm-attr-editor__header-placeholder';\n header.appendChild(handlePh);\n }\n const headerContent = document.createElement('div');\n headerContent.className = 'twm-sortable-list__content twm-attr-editor__headers';\n for (const col of showColumns) {\n const span = document.createElement('span');\n span.textContent = COLUMN_TEMPLATES[col]?.label ?? col;\n headerContent.appendChild(span);\n }\n header.appendChild(headerContent);\n if (allowRemove) {\n const removePh = document.createElement('span');\n removePh.className = 'twm-sortable-list__remove twm-attr-editor__header-placeholder';\n header.appendChild(removePh);\n }\n hostEl.appendChild(header);\n\n const listHost = document.createElement('div');\n listHost.className = 'ea-attr-editor__rows';\n hostEl.appendChild(listHost);\n\n let list = null;\n\n const renderRow = (contentEl, item, _idx, callbacks) => {\n contentEl.classList.add('twm-attr-editor__row');\n // Layer 8.J1 \u2014 paint inheritance state.\n const cls = _classifyRow(item, parentByName);\n contentEl.classList.remove(\n 'twm-attr-editor__row--inherited',\n 'twm-attr-editor__row--overridden',\n 'twm-attr-editor__row--neutral',\n );\n contentEl.classList.add(`twm-attr-editor__row--${cls}`);\n\n // R7 variation-override flags. `enabled` defaults true, so the\n // disabled treatment only applies when explicitly false.\n // `force` locks the row (variations can't override). `optional`\n // signals the value is a suggestion \u2014 green border, no fill.\n // The flag rules are applied additively so the inheritance\n // classification's background still shows where applicable.\n // In variation mode the relevant flags are the parent's; in\n // archetype mode they're the row's own. (A variation row only\n // has the flags it inherited; it doesn't author its own.)\n const parentRow = parentByName?.get(item.name);\n const flagSource = variationMode && parentRow ? parentRow : item;\n contentEl.classList.toggle(\n 'twm-attr-editor__row--disabled', flagSource.enabled === false);\n contentEl.classList.toggle(\n 'twm-attr-editor__row--forced', flagSource.force === true);\n contentEl.classList.toggle(\n 'twm-attr-editor__row--optional', flagSource.optional === true);\n\n // Attention indicator on overridden rows + revert button.\n if (cls === 'overridden') {\n const attention = document.createElement('span');\n attention.className = 'twm-attr-editor__attention material-symbols-outlined';\n attention.textContent = 'fiber_manual_record';\n attention.title = 'Value overrides the parent default';\n contentEl.appendChild(attention);\n }\n\n for (const col of showColumns) {\n const cell = renderCell(col, item, callbacks);\n contentEl.appendChild(cell);\n }\n // R7 \u2014 lock the row's editable inputs when the parent forced it.\n // The flag columns themselves stay enabled on the archetype\n // (where the author sets them); in variation mode they're\n // read-only because variations don't author flags.\n const FLAG_COLS = new Set(['enabled', 'force', 'optional']);\n if (variationMode && flagSource.force === true) {\n contentEl.querySelectorAll(\n 'input:not([type=\"checkbox\"]), select, textarea'\n ).forEach((el) => { el.disabled = true; });\n }\n if (variationMode) {\n contentEl.querySelectorAll(\n 'input[type=\"checkbox\"].ea-attr-editor__cell--flag'\n ).forEach((el) => { el.disabled = true; });\n }\n void FLAG_COLS; // referenced by future per-column handling\n\n // Revert button \u2014 only rendered for overridden rows. Resets\n // `value` back to the archetype's inherited default. The row\n // re-classifies as 'inherited' on the next render pass.\n if (cls === 'overridden' && parentByName) {\n const p = parentByName.get(item.name);\n const parentDefault = (p?.value !== undefined && p?.value !== null)\n ? p.value : p?.default;\n const revert = document.createElement('button');\n revert.type = 'button';\n revert.className = 'twm-attr-editor__revert material-symbols-outlined';\n revert.textContent = 'undo';\n revert.title =\n `Revert to inherited default (${parentDefault ?? '\u2014'})`;\n revert.addEventListener('click', (e) => {\n e.stopPropagation();\n callbacks.update({ value: parentDefault });\n onFlush();\n // Force a re-render so the row re-classifies.\n list?.setItems(currentItems());\n });\n contentEl.appendChild(revert);\n }\n };\n\n const renderCell = (col, item, callbacks) => {\n // Caller override wins \u2014 used by agent_tab to inject the\n // distribution-dict button + structured-type modal openers.\n if (cellOverrides && typeof cellOverrides[col] === 'function') {\n const ctx = { refreshRow: () => list?.setItems(currentItems()) };\n const custom = cellOverrides[col](item, callbacks, ctx);\n if (custom) return custom;\n }\n if (col === 'name') return renderTextCell(item, 'name', callbacks, 'attr_name');\n if (col === 'type') return renderTypeCell(item, callbacks);\n if (col === 'description') return renderTextCell(item, 'description', callbacks, 'optional');\n if (col === 'required') return renderBoolCell(item, 'required', callbacks);\n if (col === 'readonly') return renderBoolCell(item, 'readonly', callbacks);\n // R7 \u2014 three variation-override flags. `enabled` defaults true,\n // so the checkbox renders checked when the field is undefined;\n // the others default false.\n if (col === 'enabled') return renderFlagCell(item, 'enabled', callbacks, true);\n if (col === 'force') return renderFlagCell(item, 'force', callbacks, false);\n if (col === 'optional') return renderFlagCell(item, 'optional', callbacks, false);\n if (col === 'expression') return renderTextCell(item, 'expression', callbacks, 'expr');\n if (col === 'min') return renderNumericCell(item, 'min', callbacks);\n if (col === 'max') return renderNumericCell(item, 'max', callbacks);\n if (col === 'step') return renderTextCell(item, 'step', callbacks, 'any');\n if (col === 'unit') return renderTextCell(item, 'unit', callbacks, 'USD/%/\u2026');\n if (col === 'distribution') return renderDistributionCell(item, callbacks);\n if (col === 'default' || col === 'value') return renderTypedValueCell(col, item, callbacks);\n // Unknown column \u2014 render a stub.\n const stub = document.createElement('span');\n stub.textContent = '';\n return stub;\n };\n\n const renderNumericCell = (item, field, callbacks) => {\n const el = document.createElement('input');\n el.type = 'number';\n el.className = 'twm-sortable-list__input twm-attr-editor__cell';\n el.step = 'any';\n el.value = (item[field] === null || item[field] === undefined)\n ? '' : String(item[field]);\n el.placeholder = '\u2014';\n el.addEventListener('input', () => {\n const v = el.value === '' ? null : Number(el.value);\n callbacks.update({ [field]: v });\n });\n el.addEventListener('blur', () => onFlush());\n return el;\n };\n\n const renderDistributionCell = (item, callbacks) => {\n const el = document.createElement('select');\n el.className = 'twm-attr-editor__cell';\n for (const d of DISTRIBUTION_OPTIONS) {\n const o = document.createElement('option');\n o.value = d; o.textContent = d || '(none)';\n if ((item.distribution || '') === d) o.selected = true;\n el.appendChild(o);\n }\n el.addEventListener('change', () => {\n callbacks.update({ distribution: el.value || null });\n onFlush();\n });\n return el;\n };\n\n const renderTextCell = (item, field, callbacks, placeholder) => {\n const el = document.createElement('input');\n el.type = 'text';\n el.className = 'twm-sortable-list__input twm-attr-editor__cell';\n el.value = item[field] ?? '';\n el.placeholder = placeholder;\n el.addEventListener('input', () => {\n callbacks.update({ [field]: el.value });\n });\n el.addEventListener('blur', () => onFlush());\n return el;\n };\n\n const renderBoolCell = (item, field, callbacks) => {\n const el = document.createElement('input');\n el.type = 'checkbox';\n el.className = 'twm-attr-editor__cell';\n el.checked = !!item[field];\n el.addEventListener('change', () => {\n callbacks.update({ [field]: el.checked });\n onFlush();\n });\n return el;\n };\n\n /** Boolean cell for R7 flags. Same as renderBoolCell but treats an\n * undefined value as `defaultIfMissing`, so `enabled` (default\n * true) renders checked on legacy rows that predate the flag. */\n const renderFlagCell = (item, field, callbacks, defaultIfMissing) => {\n const el = document.createElement('input');\n el.type = 'checkbox';\n el.className = 'twm-attr-editor__cell ea-attr-editor__cell--flag';\n const cur = item[field];\n el.checked = (cur === undefined || cur === null)\n ? !!defaultIfMissing : !!cur;\n el.addEventListener('change', () => {\n callbacks.update({ [field]: el.checked });\n onFlush();\n });\n return el;\n };\n\n const renderTypeCell = (item, callbacks) => {\n const el = document.createElement('select');\n el.className = 'twm-attr-editor__cell';\n // Group scalar, expression, ref, list[ref] for readability.\n // Any type the caller hands us that doesn't fit one of those\n // buckets lands in `other` \u2014 that's how param-mode types\n // (float / int / str / bool / choice / map / schedule /\n // string_list) appear without breaking the dispatch.\n const seen = new Set();\n const addOpts = (label, optList) => {\n if (optList.length === 0) return;\n const grp = document.createElement('optgroup');\n grp.label = label;\n for (const t of optList) {\n const o = document.createElement('option');\n o.value = t; o.textContent = t;\n if (t === item.type) o.selected = true;\n grp.appendChild(o);\n seen.add(t);\n }\n el.appendChild(grp);\n };\n addOpts('scalar', types.filter((t) => SCALAR_TYPES.includes(t)));\n addOpts('expression', types.filter((t) => t === 'expression'));\n addOpts('typed reference', types.filter((t) => t.startsWith('ref:')));\n addOpts('list of references',\n types.filter((t) => t.startsWith('list[ref:')));\n addOpts('other', types.filter((t) => !seen.has(t)));\n el.addEventListener('change', () => {\n // On type change, leave default/value as-is \u2014 the user\n // may want to keep e.g. a numeric value when switching\n // from number to integer. The typed value cell renderer\n // coerces on display.\n callbacks.update({ type: el.value });\n onFlush();\n // Force re-render so the value cell picks up the new\n // input type (number \u2192 select, etc.).\n list?.setItems(currentItems());\n });\n return el;\n };\n\n const renderTypedValueCell = (field, item, callbacks) => {\n const t = item.type || 'string';\n if (t === 'boolean') {\n return renderBoolCell(item, field, callbacks);\n }\n if (t === 'integer' || t === 'number') {\n const el = document.createElement('input');\n el.type = 'number';\n el.className = 'twm-sortable-list__input twm-attr-editor__cell';\n el.step = (t === 'integer') ? '1' : 'any';\n el.value = (item[field] === null || item[field] === undefined)\n ? '' : item[field];\n el.placeholder = field;\n el.addEventListener('input', () => {\n const v = el.value === '' ? null\n : (t === 'integer' ? parseInt(el.value, 10)\n : Number(el.value));\n callbacks.update({ [field]: v });\n });\n el.addEventListener('blur', () => onFlush());\n return el;\n }\n if (t === 'expression') {\n // For an expression-typed attribute, the value cell shows\n // the expression itself (read-only by convention \u2014 the\n // engine fills it). Stub: render the expression string;\n // the actual expression authoring lives in the\n // `expression` column when shown.\n const el = document.createElement('span');\n el.className = 'twm-attr-editor__cell twm-attr-editor__cell--readonly';\n el.textContent = item.expression\n ? `\u2192 ${item.expression}` : '\u2014 (engine-evaluated)';\n return el;\n }\n if (t.startsWith('ref:')) {\n return renderRefCell(t.slice(4), field, item, callbacks);\n }\n if (t.startsWith('list[ref:') && t.endsWith(']')) {\n return renderListRefCell(t.slice(9, -1), field, item, callbacks);\n }\n if (Array.isArray(item.options) && item.options.length > 0) {\n return renderEnumCell(item.options, field, item, callbacks);\n }\n // String fallback.\n const el = document.createElement('input');\n el.type = 'text';\n el.className = 'twm-sortable-list__input twm-attr-editor__cell';\n el.value = item[field] ?? '';\n el.placeholder = field;\n el.addEventListener('input', () => {\n callbacks.update({ [field]: el.value });\n });\n el.addEventListener('blur', () => onFlush());\n return el;\n };\n\n const renderRefCell = (target, field, item, callbacks) => {\n const el = document.createElement('select');\n el.className = 'twm-attr-editor__cell';\n const placeholder = document.createElement('option');\n placeholder.value = '';\n placeholder.textContent = `\u2014 pick ${target} \u2014`;\n el.appendChild(placeholder);\n // Render once with the cached options if we have them; resolve\n // async otherwise and patch.\n const populate = (opts) => {\n // Clear everything except the placeholder.\n while (el.childNodes.length > 1) el.removeChild(el.lastChild);\n for (const o of opts) {\n const node = document.createElement('option');\n node.value = o.id;\n node.textContent = o.label;\n if (o.id === item[field]) node.selected = true;\n el.appendChild(node);\n }\n };\n if (refsCache.has(target)) {\n populate(refsCache.get(target));\n } else {\n resolveRefOptions(target).then(populate);\n }\n el.addEventListener('change', () => {\n callbacks.update({ [field]: el.value || null });\n onFlush();\n });\n return el;\n };\n\n const renderListRefCell = (target, field, item, callbacks) => {\n // MVP: comma-separated text input over the underlying string-\n // list. The chip-style picker can replace this without\n // changing the on-disk shape.\n const el = document.createElement('input');\n el.type = 'text';\n el.className = 'twm-sortable-list__input twm-attr-editor__cell';\n const arr = Array.isArray(item[field]) ? item[field] : [];\n el.value = arr.join(', ');\n el.placeholder = `${target}, ${target}, \u2026`;\n el.addEventListener('input', () => {\n const next = el.value.split(',')\n .map((s) => s.trim()).filter(Boolean);\n callbacks.update({ [field]: next });\n });\n el.addEventListener('blur', () => onFlush());\n return el;\n };\n\n const renderEnumCell = (options, field, item, callbacks) => {\n // `options` may be either a flat list of strings (legacy:\n // `['fx', 'commodity', \u2026]`) or a list of `{value, label}`\n // pairs (newer callers that want display labels distinct from\n // the stored value, e.g. market-rules ref fields where the\n // value is a currency id and the label is the currency name).\n const el = document.createElement('select');\n el.className = 'twm-attr-editor__cell';\n // Empty placeholder so the user can clear the selection.\n const blank = document.createElement('option');\n blank.value = '';\n blank.textContent = '\u2014';\n if (item[field] === null || item[field] === undefined || item[field] === '') {\n blank.selected = true;\n }\n el.appendChild(blank);\n for (const opt of options) {\n const o = document.createElement('option');\n if (opt !== null && typeof opt === 'object') {\n o.value = String(opt.value ?? opt.id ?? '');\n o.textContent = String(opt.label ?? opt.value ?? opt.id ?? '');\n } else {\n o.value = String(opt);\n o.textContent = String(opt);\n }\n if (o.value === String(item[field] ?? '')) o.selected = true;\n el.appendChild(o);\n }\n el.addEventListener('change', () => {\n callbacks.update({ [field]: el.value === '' ? null : el.value });\n onFlush();\n });\n return el;\n };\n\n // \u2500\u2500\u2500 SortableList wiring \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 const itemsCopy = (src) => (src || []).map((it) => ({ ...it }));\n const currentItems = () => list?.getItems?.() || itemsCopy(items);\n\n const buildList = (current) => {\n try { list?.dispose?.(); } catch {}\n listHost.innerHTML = '';\n list = new SortableList({\n containerId,\n items: itemsCopy(current),\n allowReorder,\n allowRemove,\n minItems: 0,\n emptyMessage,\n addButtonText,\n createItem,\n renderItem: renderRow,\n onChange: (next) => onChange(next.map((it) => ({ ...it }))),\n });\n listHost.appendChild(list.render());\n };\n\n buildList(items);\n\n return {\n addItem() { list?.addItem(); },\n refresh(nextItems) {\n // External update: rebuild to pick up new type-cell shapes.\n // Cheaper than setItems when types changed; setItems\n // wouldn't re-render the row controls.\n buildList(nextItems !== undefined ? nextItems : currentItems());\n },\n items() {\n return currentItems();\n },\n dispose() {\n try { list?.dispose?.(); } catch {}\n list = null;\n hostEl.innerHTML = '';\n hostEl.classList.remove('twm-attr-editor');\n },\n };\n}\n", "/**\n * column_fit.js \u2014 how wide each column of a table should be.\n *\n * A pure function over measurements, so the policy can be read and tested\n * without a DOM. A table measures its columns, hands them here, and applies\n * the widths it gets back.\n *\n * \u2500\u2500 The policy \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 * Columns are not all alike, and treating them alike is what went wrong\n * before. An id, a date, a status, a person: SHORT columns, whose values are\n * all about as wide as each other, and which are useless the moment they are\n * cut (\"2026-09-\u2026\", \"review-q\u2026\"). A summary or a title: TEXT columns, whose\n * values run as long as people write them, and which are readable cut.\n *\n * The old fit spread spare room EVENLY, so a 40px \"BUG\" chip got 90px while\n * the summary beside it was clipped in nine rows out of ten, and it shrank the\n * WIDEST column first, so a narrow tile crushed the title to 85px while every\n * short column kept its width.\n *\n * 1. Short columns get their full content width. Text columns start at a\n * readable width.\n * 2. Room to spare goes to the text columns, in proportion to what each\n * still needs, and past their content so the table fills its box. With no\n * text column it goes to the last column, so no column in the middle\n * opens a gap.\n * 3. Too little room: shrink in order of harm. Short columns first give up\n * only their rare longest values (down to `typical`, what most values\n * fit). Then text columns go down to a floor. Then short columns go down\n * to theirs, and text columns once more. What still does not fit scrolls\n * sideways rather than being crushed further.\n *\n * Within each step the widest columns give way first and the narrow ones keep\n * their width (a water level), so one long column never forces every other\n * column down with it.\n *\n * Columns the user dragged are PINNED: they keep their width and sit out every\n * step.\n */\n\nexport const COLUMN_FIT = Object.freeze({\n /** Absolute floor, and the drag-resize minimum. */\n FLOOR: 40,\n /** Sub-pixel safety against an ellipsis on content that exactly fits. */\n PAD: 2,\n /** A column whose full width reaches this is free text. */\n TEXT_AT: 240,\n /** A text column's starting share when room allows it. */\n TEXT_MIN: 200,\n /** How far a text column shrinks before short columns go below `typical`. */\n TEXT_FLOOR: 120,\n /** How far a short column shrinks before the table scrolls. */\n SHORT_FLOOR: 56,\n});\n\n/**\n * @typedef {object} ColumnMeasure\n * @property {number} natural widest cell, padding included (px)\n * @property {number} [typical] width most cells fit, e.g. the 95th percentile (px);\n * defaults to `natural`\n * @property {number} [header] the header label's width (px)\n * @property {number} [pinned] a user-dragged width, honoured exactly\n * @property {boolean} [text] force (true) or forbid (false) text treatment;\n * omitted, it is decided from the width\n */\n\n/**\n * @param {ColumnMeasure[]} columns\n * @param {number} avail the width the table has (px); 0 or less means \"not laid out\"\n * @returns {number[]} a width per column (px, possibly fractional). The sum\n * equals `avail` whenever the floors fit, and exceeds it only when they do\n * not, in which case the table should scroll.\n */\nexport function fitColumns(columns, avail) {\n const { FLOOR, PAD, TEXT_AT, TEXT_MIN, TEXT_FLOOR, SHORT_FLOOR } = COLUMN_FIT;\n const n = columns.length;\n const cols = columns.map((c) => {\n const header = Math.max(0, Number(c.header) || 0);\n const natural = Math.max(0, Number(c.natural) || 0);\n const full = Math.max(FLOOR, Math.ceil(Math.max(natural, header) + PAD));\n const typical = Math.min(full, Math.max(FLOOR, Math.ceil(Math.max(\n Number.isFinite(c.typical) ? c.typical : natural, header) + PAD)));\n const pinned = Number.isFinite(c.pinned) ? Math.max(FLOOR, Math.round(c.pinned)) : null;\n const text = pinned == null && (typeof c.text === 'boolean' ? c.text : full >= TEXT_AT);\n return { full, typical, pinned, text };\n });\n\n const text = [];\n const short = [];\n cols.forEach((c, i) => { if (c.pinned == null) (c.text ? text : short).push(i); });\n if (!(avail > 1)) return cols.map((c) => (c.pinned != null ? c.pinned : c.full));\n\n // 1. The starting point: short columns at their full content width, text\n // columns at a readable width (or their content, if shorter).\n const widths = cols.map((c) => {\n if (c.pinned != null) return c.pinned;\n return c.text ? Math.min(c.full, TEXT_MIN) : c.full;\n });\n const total = () => widths.reduce((a, b) => a + b, 0);\n let slack = avail - total();\n\n // 2. Room to spare goes to the text columns, in proportion to what each\n // still needs, then beyond their content so the table fills its box.\n // Widths are not rounded: CSS takes fractional pixels, and rounding is\n // what made the total miss the box by a pixel and a column jitter by one\n // as its tile was resized.\n if (slack >= 0) {\n slack = raise(widths, text, (i) => cols[i].full, slack);\n if (slack > 0) {\n if (text.length) text.forEach((i) => { widths[i] += slack / text.length; });\n else widths[short.length ? short[short.length - 1] : n - 1] += slack;\n }\n return widths;\n }\n\n // 3. Not enough room: shrink in order of harm until it fits.\n const steps = [\n [short, (i) => cols[i].typical],\n [text, () => TEXT_FLOOR],\n [short, (i) => Math.min(cols[i].typical, SHORT_FLOOR)],\n [text, () => FLOOR * 2],\n ];\n for (const [idxs, low] of steps) {\n const over = total() - avail;\n if (over <= 1e-6) break;\n lowerTo(widths, idxs, low, over);\n }\n return widths;\n}\n\n/**\n * Give up to `slack` px to the columns in `idxs`, each toward `target(i)`, in\n * proportion to how far each still is from it. Returns what is left.\n */\nfunction raise(widths, idxs, target, slack) {\n if (!(slack > 0)) return slack;\n const wants = idxs.map((i) => Math.max(0, target(i) - widths[i]));\n const need = wants.reduce((a, b) => a + b, 0);\n if (!(need > 0)) return slack;\n const give = Math.min(slack, need);\n idxs.forEach((i, k) => { widths[i] += give * wants[k] / need; });\n return slack - give;\n}\n\n/**\n * Take up to `over` px off the columns in `idxs`, widest first, none below\n * `low(i)`. A water level: every column above the level is cut down to it, and\n * the level is solved so the total cut is exactly `over`, or everything the\n * lows allow when that is less. Solved on real numbers: the result is exact,\n * and a wider box can never make any column narrower.\n */\nfunction lowerTo(widths, idxs, low, over) {\n const floorOf = (i) => Math.min(widths[i], Math.max(0, low(i)));\n const cand = idxs.filter((i) => widths[i] > floorOf(i));\n if (!cand.length || over <= 0) return;\n const floors = new Map(cand.map((i) => [i, floorOf(i)]));\n const capacity = cand.reduce((a, i) => a + widths[i] - floors.get(i), 0);\n if (capacity <= over) {\n for (const i of cand) widths[i] = floors.get(i);\n return;\n }\n const cutAt = (level) => cand.reduce((a, i) => a + Math.max(0, widths[i] - Math.max(floors.get(i), level)), 0);\n let lo = 0;\n let hi = Math.max(...cand.map((i) => widths[i]));\n for (let k = 0; k < 64; k++) {\n const mid = (lo + hi) / 2;\n if (cutAt(mid) > over) lo = mid; else hi = mid;\n }\n for (const i of cand) widths[i] = Math.min(widths[i], Math.max(floors.get(i), hi));\n}\n", "/**\n * Determinate progress: a bar, a keyed list of bars, and a row of phases.\n * Location: ui/components/progress.js\n *\n * Three primitives for long-running jobs, each a class that owns its own DOM\n * and changes it IN PLACE \u2014 a caller that reports progress twenty times a\n * second gets the same elements back every time, so a row it is hovering, a\n * tooltip anchored to it and a CSS transition on the fill all survive.\n *\n * ProgressBar value/max or a 0..1 fraction, indeterminate, a label, a\n * percent and a count readout, elapsed time, a cancel button,\n * and a final state (done / error / cancelled).\n * ProgressList keyed rows `{ key, name, completed, total?, state }`;\n * `setItems` reconciles by key. A row without `total` is\n * drawn against the largest item in the list.\n * StepProgress ordered phases, each done / active / pending / error, the\n * active one optionally reading \"pass n of m\".\n *\n * Nothing here knows what is being computed: names, labels and the stats line\n * are the caller's text, always set with `textContent`. State lives on the\n * instances; the DOM carries only classes and ARIA.\n */\n\n/** The states a ProgressBar can end in, besides `running`. */\nexport const PROGRESS_STATES = Object.freeze(['running', 'done', 'error', 'cancelled']);\n\n/** The states a ProgressList row can be in. */\nexport const PROGRESS_ITEM_STATES = Object.freeze(['pending', 'running', 'done', 'failed']);\n\n/** The states a StepProgress phase can be in. */\nexport const STEP_STATES = Object.freeze(['pending', 'active', 'done', 'error']);\n\nconst clamp01 = (x) => (x < 0 ? 0 : x > 1 ? 1 : x);\nconst isNum = (x) => typeof x === 'number' && Number.isFinite(x);\n\n/** `m:ss`, or `h:mm:ss` from an hour on. */\nexport function formatElapsed(ms) {\n const s = Math.max(0, Math.floor((ms || 0) / 1000));\n const h = Math.floor(s / 3600);\n const m = Math.floor((s % 3600) / 60);\n const ss = String(s % 60).padStart(2, '0');\n return h ? `${h}:${String(m).padStart(2, '0')}:${ss}` : `${m}:${ss}`;\n}\n\nfunction el(tag, className, text) {\n const n = document.createElement(tag);\n if (className) n.className = className;\n if (text !== undefined) n.textContent = text;\n return n;\n}\n\n/** Set text only when it changed, so an unchanged readout is not a mutation. */\nfunction setText(node, text) {\n const t = text == null ? '' : String(text);\n if (node.textContent !== t) node.textContent = t;\n}\n\nfunction setWidth(node, fraction) {\n const w = `${(clamp01(fraction) * 100).toFixed(2).replace(/\\.?0+$/, '')}%`;\n if (node.style.width !== w) node.style.width = w;\n}\n\n// \u2500\u2500\u2500 ProgressBar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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/**\n * @typedef {Object} ProgressBarOptions\n * @property {number} [value=0] - A count when `max` is given, else a 0..1 fraction.\n * @property {number|null} [max=null] - The count `value` runs to.\n * @property {boolean} [indeterminate=false] - Busy, with no known end.\n * @property {string} [label=''] - Text before the readout.\n * @property {boolean} [showPercent=true] - \"42%\".\n * @property {boolean|null} [showCount=null] - \"21 / 50\"; defaults to on when `max` is given.\n * @property {boolean} [showElapsed=false] - A running \"m:ss\" from construction until a final state.\n * @property {Function|null} [onCancel=null] - Shows a Cancel button; called once when clicked.\n * @property {string} [cancelLabel='Cancel']\n * @property {Function} [now=Date.now] - The clock, for the elapsed readout.\n * @property {string} [className] - Added to the root.\n */\n\nexport class ProgressBar {\n /**\n * @param {HTMLElement|null} host appended to, if given\n * @param {ProgressBarOptions} [options]\n */\n constructor(host, options = {}) {\n const {\n value = 0, max = null, indeterminate = false, label = '',\n showPercent = true, showCount = null, showElapsed = false,\n onCancel = null, cancelLabel = 'Cancel', now = Date.now, className = '',\n } = options;\n this._value = isNum(value) ? value : 0;\n this._max = isNum(max) && max > 0 ? max : null;\n this._indeterminate = !!indeterminate;\n this._label = label || '';\n this._showPercent = showPercent !== false;\n this._showCount = showCount;\n this._showElapsed = !!showElapsed;\n this._state = 'running';\n this._now = typeof now === 'function' ? now : Date.now;\n this._started = this._now();\n this._stopped = null;\n this._timer = null;\n this._onCancel = typeof onCancel === 'function' ? onCancel : null;\n\n const root = el('div', `twm-progress${className ? ` ${className}` : ''}`);\n const head = el('div', 'twm-progress__head');\n this._labelEl = el('span', 'twm-progress__label');\n this._readoutEl = el('span', 'twm-progress__readout');\n head.append(this._labelEl, this._readoutEl);\n if (this._showElapsed) {\n this._elapsedEl = el('span', 'twm-progress__elapsed');\n head.appendChild(this._elapsedEl);\n this._startTimer();\n } else {\n this._elapsedEl = null;\n }\n if (this._onCancel) {\n const btn = el('button', 'twm-progress__cancel', cancelLabel);\n btn.type = 'button';\n btn.addEventListener('click', () => {\n if (btn.disabled || this._state !== 'running') return;\n btn.disabled = true;\n this._onCancel();\n });\n this._cancelBtn = btn;\n head.appendChild(btn);\n } else {\n this._cancelBtn = null;\n }\n this._track = el('div', 'twm-progress__track');\n this._track.setAttribute('role', 'progressbar');\n this._fill = el('div', 'twm-progress__fill');\n this._track.appendChild(this._fill);\n root.append(head, this._track);\n this.element = root;\n this._draw();\n if (host) host.appendChild(root);\n }\n\n /** The bar's fraction 0..1, or null while indeterminate. */\n get fraction() {\n if (this._indeterminate) return null;\n return clamp01(this._max ? this._value / this._max : this._value);\n }\n\n /** `running`, `done`, `error` or `cancelled`. */\n get state() { return this._state; }\n\n /** Milliseconds since construction, frozen at the final state. */\n get elapsed() { return (this._stopped ?? this._now()) - this._started; }\n\n /**\n * Change the bar in place. A number is the new value (a count with `max`,\n * else a fraction); an object may carry `value`, `max`, `label` and\n * `indeterminate`. Ignored once the bar is in a final state.\n */\n update(next) {\n if (this._state !== 'running') return this;\n const o = isNum(next) ? { value: next } : (next || {});\n if ('max' in o) this._max = isNum(o.max) && o.max > 0 ? o.max : null;\n if (isNum(o.value)) { this._value = o.value; if (!('indeterminate' in o)) this._indeterminate = false; }\n if ('indeterminate' in o) this._indeterminate = !!o.indeterminate;\n if ('label' in o) this._label = o.label || '';\n this._draw();\n return this;\n }\n\n /**\n * Put the bar in a final state (`done`, `error`, `cancelled`) or back to\n * `running`. `done` fills it. A final state stops the elapsed clock and\n * disables Cancel; `running` restarts the clock (still counting from\n * construction) and enables Cancel again. `label` replaces the label when\n * given.\n */\n setState(state, { label } = {}) {\n if (!PROGRESS_STATES.includes(state)) throw new Error(`ProgressBar: unknown state \"${state}\"`);\n this._state = state;\n if (label !== undefined) this._label = label || '';\n if (state === 'done') { this._indeterminate = false; this._value = this._max ?? 1; }\n if (state === 'running') {\n this._stopped = null;\n if (this._showElapsed) this._startTimer();\n } else {\n this._stopped = this._now();\n if (this._timer) { clearInterval(this._timer); this._timer = null; }\n }\n if (this._cancelBtn) this._cancelBtn.disabled = state !== 'running';\n this._draw();\n this._drawElapsed();\n return this;\n }\n\n /** Tick the elapsed readout once a second, unless it already ticks. */\n _startTimer() {\n if (!this._timer) this._timer = setInterval(() => this._drawElapsed(), 1000);\n }\n\n /** Stop the elapsed clock and detach. */\n dispose() {\n this._showElapsed = false;\n if (this._timer) { clearInterval(this._timer); this._timer = null; }\n this.element.remove();\n }\n\n _draw() {\n const root = this.element;\n for (const s of PROGRESS_STATES) {\n root.classList.toggle(`twm-progress--${s}`, this._state === s);\n }\n root.classList.toggle('twm-progress--indeterminate', this._indeterminate);\n setText(this._labelEl, this._label);\n const f = this.fraction;\n const parts = [];\n if (f !== null) {\n if (this._showPercent) parts.push(`${Math.floor(f * 100)}%`);\n const count = this._showCount ?? !!this._max;\n if (count && this._max) parts.push(`${fmtCount(this._value)} / ${fmtCount(this._max)}`);\n }\n setText(this._readoutEl, parts.join(' \u00B7 '));\n if (f === null) {\n if (this._fill.style.width) this._fill.style.width = '';\n this._track.removeAttribute('aria-valuenow');\n } else {\n setWidth(this._fill, f);\n this._track.setAttribute('aria-valuenow', String(Math.round(f * 100)));\n }\n this._track.setAttribute('aria-valuemin', '0');\n this._track.setAttribute('aria-valuemax', '100');\n if (this._label) this._track.setAttribute('aria-label', this._label);\n this._drawElapsed();\n }\n\n _drawElapsed() {\n if (this._elapsedEl) setText(this._elapsedEl, formatElapsed(this.elapsed));\n }\n}\n\nfunction fmtCount(n) {\n return Number.isInteger(n) ? String(n) : String(Math.round(n * 100) / 100);\n}\n\n// \u2500\u2500\u2500 ProgressList \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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/**\n * @typedef {Object} ProgressItem\n * @property {string|number} key - Identity across `setItems` calls.\n * @property {string} [name] - Shown as the row's label; defaults to the key.\n * @property {number} [completed=0]\n * @property {number} [total] - Absent: the row is drawn against the largest item.\n * @property {'pending'|'running'|'done'|'failed'} [state='pending']\n * @property {string} [detail] - Extra text after the count.\n */\n\n/**\n * @typedef {Object} ProgressListOptions\n * @property {ProgressItem[]} [items=[]]\n * @property {boolean|Function} [stats=true] - The line under the rows: `true`\n * for the default summary, `false` for none, or `(items) => string`.\n * @property {boolean} [pulse=true] - Running rows pulse.\n * @property {string} [emptyText=''] - Shown when there are no items.\n * @property {string} [className] - Added to the root.\n */\n\nexport class ProgressList {\n /**\n * @param {HTMLElement|null} host appended to, if given\n * @param {ProgressListOptions} [options]\n */\n constructor(host, options = {}) {\n const { items = [], stats = true, pulse = true, emptyText = '', className = '' } = options;\n this._stats = stats;\n this._emptyText = emptyText;\n /** @type {Map<string, {item: ProgressItem, row: HTMLElement, name: HTMLElement, fill: HTMLElement, count: HTMLElement, state: HTMLElement}>} */\n this._rows = new Map();\n this._items = [];\n const root = el('div', `twm-progress-list${pulse ? ' twm-progress-list--pulse' : ''}${className ? ` ${className}` : ''}`);\n this._listEl = el('div', 'twm-progress-list__rows');\n this._listEl.setAttribute('role', 'list');\n this._emptyEl = el('div', 'twm-progress-list__empty');\n this._statsEl = el('div', 'twm-progress-list__stats');\n root.append(this._listEl, this._emptyEl, this._statsEl);\n this.element = root;\n this.setItems(items);\n if (host) host.appendChild(root);\n }\n\n /** The items last given, in order. */\n get items() { return this._items.slice(); }\n\n /**\n * Reconcile the rows with `items` by key: a known key keeps its row and\n * has its text, width and state changed in place; a new key gets a row; a\n * key that is gone loses its row. Rows follow the order given, and a row\n * already in its place is not moved.\n */\n setItems(items) {\n const list = Array.isArray(items) ? items : [];\n const seen = new Set();\n this._items = [];\n for (const it of list) {\n if (!it || it.key == null) continue;\n const k = String(it.key);\n if (seen.has(k)) continue;\n seen.add(k);\n this._items.push(it);\n }\n for (const [k, r] of this._rows) {\n if (!seen.has(k)) { r.row.remove(); this._rows.delete(k); }\n }\n const scale = this._items.reduce((m, it) => {\n const d = isNum(it.total) && it.total > 0 ? it.total : (isNum(it.completed) ? it.completed : 0);\n return d > m ? d : m;\n }, 0);\n let prev = null;\n for (const it of this._items) {\n const k = String(it.key);\n let r = this._rows.get(k);\n if (!r) { r = this._makeRow(); this._rows.set(k, r); }\n this._drawRow(r, it, scale);\n const want = prev ? prev.nextSibling : this._listEl.firstChild;\n if (want !== r.row) this._listEl.insertBefore(r.row, want);\n prev = r.row;\n }\n this._emptyEl.hidden = this._items.length > 0 || !this._emptyText;\n setText(this._emptyEl, this._emptyText);\n const line = this._statsLine();\n this._statsEl.hidden = !line;\n setText(this._statsEl, line);\n return this;\n }\n\n /** The row element for `key`, or null. */\n rowFor(key) { return this._rows.get(String(key))?.row ?? null; }\n\n dispose() { this.element.remove(); this._rows.clear(); }\n\n _makeRow() {\n const row = el('div', 'twm-progress-list__row');\n row.setAttribute('role', 'listitem');\n const name = el('span', 'twm-progress-list__name');\n const track = el('div', 'twm-progress-list__track');\n const fill = el('div', 'twm-progress-list__fill');\n track.appendChild(fill);\n const count = el('span', 'twm-progress-list__count');\n const state = el('span', 'twm-progress-list__state');\n row.append(state, name, track, count);\n return { row, name, fill, count, state };\n }\n\n _drawRow(r, it, scale) {\n const state = PROGRESS_ITEM_STATES.includes(it.state) ? it.state : 'pending';\n for (const s of PROGRESS_ITEM_STATES) {\n r.row.classList.toggle(`twm-progress-list__row--${s}`, s === state);\n }\n const done = isNum(it.completed) ? it.completed : 0;\n const hasTotal = isNum(it.total) && it.total > 0;\n const denom = hasTotal ? it.total : scale;\n setWidth(r.fill, denom > 0 ? done / denom : 0);\n setText(r.name, it.name ?? String(it.key));\n const count = hasTotal ? `${fmtCount(done)} / ${fmtCount(it.total)}` : fmtCount(done);\n setText(r.count, it.detail ? `${count} \u00B7 ${it.detail}` : count);\n if (r.state.title !== state) r.state.title = state;\n }\n\n _statsLine() {\n if (this._stats === false) return '';\n if (typeof this._stats === 'function') return String(this._stats(this.items) ?? '');\n if (!this._items.length) return '';\n const n = { done: 0, running: 0, failed: 0, pending: 0 };\n let completed = 0;\n for (const it of this._items) {\n n[PROGRESS_ITEM_STATES.includes(it.state) ? it.state : 'pending'] += 1;\n if (isNum(it.completed)) completed += it.completed;\n }\n const parts = [`${n.done} / ${this._items.length} done`];\n if (n.running) parts.push(`${n.running} running`);\n if (n.failed) parts.push(`${n.failed} failed`);\n if (n.pending) parts.push(`${n.pending} pending`);\n parts.push(`${fmtCount(completed)} completed`);\n return parts.join(' \u00B7 ');\n }\n}\n\n// \u2500\u2500\u2500 StepProgress \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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/**\n * @typedef {Object} StepDef\n * @property {string} [key] - How `setStep` names it; defaults to its index.\n * @property {string} label\n */\n\nexport class StepProgress {\n /**\n * @param {HTMLElement|null} host appended to, if given\n * @param {{ steps?: Array<StepDef|string>, className?: string }} [options]\n */\n constructor(host, options = {}) {\n const { steps = [], className = '' } = options;\n const root = el('ol', `twm-steps${className ? ` ${className}` : ''}`);\n this.element = root;\n this._steps = steps.map((s, i) => {\n const def = typeof s === 'string' ? { label: s } : (s || {});\n const li = el('li', 'twm-steps__step');\n const marker = el('span', 'twm-steps__marker');\n const label = el('span', 'twm-steps__label', def.label ?? '');\n const pass = el('span', 'twm-steps__pass');\n pass.hidden = true;\n li.append(marker, label, pass);\n root.appendChild(li);\n return { key: def.key != null ? String(def.key) : String(i), label: def.label ?? '', state: 'pending', pass: null, li, passEl: pass };\n });\n this._draw();\n if (host) host.appendChild(root);\n }\n\n /** `[{ key, label, state, pass }]`, in order. */\n get steps() {\n return this._steps.map(({ key, label, state, pass }) => ({ key, label, state, pass }));\n }\n\n /** The index of the active phase, or -1. */\n get activeIndex() { return this._steps.findIndex((s) => s.state === 'active'); }\n\n /**\n * Make one phase active: every phase before it is done, every phase after\n * it pending. `pass` and `passes` read \"pass n of m\" on it.\n * @param {string|number} which - A key, or an index.\n * @param {{ pass?: number, passes?: number }} [opts]\n */\n setStep(which, { pass, passes } = {}) {\n const i = this._index(which);\n this._steps.forEach((s, j) => {\n s.state = j < i ? 'done' : j === i ? 'active' : 'pending';\n s.pass = j === i && isNum(pass) ? { n: pass, of: isNum(passes) ? passes : null } : null;\n });\n this._draw();\n return this;\n }\n\n /** Mark a phase (the active one by default) as failed; phases after it stay pending. */\n fail(which) {\n const i = which === undefined ? this.activeIndex : this._index(which);\n if (i < 0) return this;\n this._steps.forEach((s, j) => {\n if (j < i) s.state = 'done';\n else if (j === i) s.state = 'error';\n else s.state = 'pending';\n if (j !== i) s.pass = null;\n });\n this._draw();\n return this;\n }\n\n /** Every phase done. */\n complete() {\n for (const s of this._steps) { s.state = 'done'; s.pass = null; }\n this._draw();\n return this;\n }\n\n dispose() { this.element.remove(); }\n\n _index(which) {\n const i = typeof which === 'number'\n ? which\n : this._steps.findIndex((s) => s.key === String(which));\n if (!Number.isInteger(i) || i < 0 || i >= this._steps.length) {\n throw new Error(`StepProgress: no step \"${which}\"`);\n }\n return i;\n }\n\n _draw() {\n for (const s of this._steps) {\n for (const st of STEP_STATES) s.li.classList.toggle(`twm-steps__step--${st}`, s.state === st);\n if (s.state === 'active') s.li.setAttribute('aria-current', 'step');\n else s.li.removeAttribute('aria-current');\n const text = s.pass ? (s.pass.of ? `pass ${s.pass.n} of ${s.pass.of}` : `pass ${s.pass.n}`) : '';\n s.passEl.hidden = !text;\n setText(s.passEl, text);\n }\n }\n}\n", "/**\n * The progress block both job dialogs share \u2014 `showRunProgressDialog` and\n * `showComputingWindow` \u2014 so a bar and a row of phases behave the same in\n * either. Internal: not in the `widgets` barrel.\n */\n\nimport { ProgressBar, StepProgress } from './progress.js';\n\n/**\n * Mount the optional phases and bar into `parent`, phases first.\n *\n * @param {HTMLElement} parent\n * @param {{ progress?: boolean|Object, steps?: Array, spinner?: HTMLElement|null }} options\n * `progress`: `true`, or ProgressBar options (its `onCancel` is ignored: the\n * dialog owns cancelling). `steps`: StepProgress steps. `spinner`: hidden\n * while a bar is shown. Both are fixed at mount: `setProgress` throws\n * without `progress` and `setStep` without `steps`, so the window is sized\n * for what it holds from the start.\n */\nexport function mountJobProgress(parent, { progress = null, steps = null, spinner = null } = {}) {\n const stepper = Array.isArray(steps) && steps.length\n ? new StepProgress(parent, { steps, className: 'twm-job-progress__steps' })\n : null;\n let bar = null;\n if (progress) {\n const { onCancel: _ignored, ...rest } = typeof progress === 'object' ? progress : {};\n bar = new ProgressBar(parent, { ...rest, className: 'twm-job-progress__bar' });\n if (spinner) spinner.hidden = true;\n }\n\n return {\n get bar() { return bar; },\n get steps() { return stepper; },\n /** `bar.update(next)`. */\n setProgress(next) {\n if (!bar) throw new Error('setProgress: this dialog was opened without `progress`');\n bar.update(next);\n },\n /** `steps.setStep(which, opts)`. */\n setStep(which, opts) {\n if (!stepper) throw new Error('setStep: this dialog was opened without `steps`');\n stepper.setStep(which, opts);\n },\n /** Put the bar and the phases in their final state. */\n finish(status) {\n if (status === 'done') { bar?.setState('done'); stepper?.complete(); }\n else if (status === 'error') { bar?.setState('error'); stepper?.fail(); }\n else bar?.setState('cancelled');\n },\n };\n}\n", "/**\n * Computing Status Window\n *\n * Lightweight ManagedWindow that shows a spinner (or a progress bar) and a\n * status message while a long-running computation is in progress. Returns a\n * handle with update(), setProgress(), setStep(), complete(), cancelled(),\n * close() and a `result` promise.\n *\n * Optionally shows a Cancel button when an onCancel callback is provided.\n * Only one is open at a time: opening another closes the first, which then\n * settles as cancelled (its onCancel is not called).\n */\n\nimport { ManagedWindow } from './managed_window.js';\nimport { mountJobProgress } from './job_progress.js';\n\nlet _activeWindow = null;\n\n/**\n * Show a computing status window.\n *\n * `result` settles once: `complete({ok, message})` gives `done` or `error`\n * (the window stays, with a Close button, until closed), `cancelled()` gives\n * `cancelled`, and so does closing the window while it runs (by its \u00D7,\n * Escape, `close()` or opening another). Closing never calls `onCancel`: only\n * the Cancel button does. `progress` and `steps` are fixed when the window\n * opens: `setProgress` throws if it was opened without `progress`, and\n * `setStep` if it was opened without `steps`.\n *\n * @param {Object} options\n * @param {string} [options.title='Computing...'] - Window title\n * @param {string} [options.message=''] - Status message below spinner (markup; `update` takes text)\n * @param {string} [options.icon='hourglass_top'] - Material icon name\n * @param {Function} [options.onCancel] - If provided, shows a Cancel button. Called once when clicked.\n * @param {boolean|Object} [options.progress] - A ProgressBar in place of the spinner: `true` or its options.\n * @param {Array} [options.steps] - StepProgress steps, shown above the message.\n * @returns {{ update(msg: string): void, setProgress(next: number|Object): void,\n * setStep(which: string|number, opts?: {pass?: number, passes?: number}): void,\n * complete(result: {ok: boolean, message?: string}): void, cancelled(msg?: string): void,\n * close(): void, result: Promise<{status: 'done'|'error'|'cancelled', message: string}> }}\n */\nexport function showComputingWindow({\n title = 'Computing...', message = '', icon = 'hourglass_top', onCancel,\n progress = null, steps = null,\n} = {}) {\n if (_activeWindow) {\n _activeWindow.close();\n _activeWindow = null;\n }\n\n let finished = false;\n let settle;\n const result = new Promise((resolve) => { settle = resolve; });\n\n const content = document.createElement('div');\n content.className = 'twm-computing-status';\n const spinnerEl = document.createElement('div');\n spinnerEl.className = 'twm-computing-status__spinner';\n const msgEl = document.createElement('div');\n msgEl.className = 'twm-computing-status__message';\n // The opening message is markup, as it always was; every later one is text.\n msgEl.innerHTML = message;\n content.appendChild(spinnerEl);\n const job = mountJobProgress(content, { progress, steps, spinner: spinnerEl });\n content.appendChild(msgEl);\n\n let cancelBtn = null;\n if (typeof onCancel === 'function') {\n cancelBtn = document.createElement('button');\n cancelBtn.className = 'twm-computing-status__cancel-btn';\n cancelBtn.textContent = 'Cancel';\n cancelBtn.addEventListener('click', () => {\n cancelBtn.disabled = true;\n msgEl.textContent = 'Cancelling...';\n onCancel();\n }, { once: true });\n content.appendChild(cancelBtn);\n }\n\n const closeBtn = document.createElement('button');\n closeBtn.type = 'button';\n closeBtn.className = 'twm-computing-status__cancel-btn twm-computing-status__close-btn';\n closeBtn.textContent = 'Close';\n closeBtn.hidden = true;\n content.appendChild(closeBtn);\n\n const finish = (status, text) => {\n finished = true;\n spinnerEl.hidden = true;\n if (cancelBtn) cancelBtn.hidden = true;\n msgEl.textContent = text;\n msgEl.classList.toggle('is-ok', status === 'done');\n msgEl.classList.toggle('is-err', status === 'error');\n msgEl.classList.toggle('is-cancelled', status === 'cancelled');\n job.finish(status);\n settle({ status, message: text });\n };\n\n const win = new ManagedWindow({\n id: 'computing-status-window',\n title,\n icon,\n content,\n minWidth: 320,\n minHeight: 140,\n defaultWidth: 380,\n defaultHeight: (onCancel ? 190 : 160) + (job.bar ? 30 : 0) + (job.steps ? 40 : 0),\n canMinimize: true,\n canMaximize: false,\n canResize: false,\n canDrag: true,\n modal: false,\n onClose: () => {\n if (_activeWindow === win) _activeWindow = null;\n if (finished) return;\n finish('cancelled', 'Cancelled.');\n },\n });\n closeBtn.addEventListener('click', () => win.close());\n _activeWindow = win;\n win.show();\n\n return {\n result,\n update(msg) {\n if (finished) return;\n msgEl.textContent = msg;\n },\n setProgress(next) {\n if (finished) return;\n job.setProgress(next);\n },\n setStep(which, opts) {\n if (finished) return;\n job.setStep(which, opts);\n },\n complete(res) {\n if (finished) return;\n finish(res?.ok ? 'done' : 'error', res?.message || '');\n closeBtn.hidden = false;\n },\n cancelled(msg) {\n if (finished) return;\n finish('cancelled', msg || 'Cancelled.');\n closeBtn.hidden = false;\n },\n close() {\n if (_activeWindow) {\n _activeWindow.close();\n _activeWindow = null;\n }\n },\n };\n}\n", "/**\n * Confirm Dialog Component\n * Location: ui/components/confirm_dialog.js\n *\n * Thin delegator over the canonical modal helpers in\n * `ecoagent/ui/modal.js`. Every dialog signature here is preserved so\n * the 10+ call sites across notebook/data/results/ai pages keep\n * working unchanged; under the hood, all four standard dialogs now\n * flow through `openConfirm` / `openForm` / `openModal` so they\n * inherit the TUI styling (`\u25B8 TITLE` strip, accent-blue primary\n * action, square frame, Tab focus trap).\n *\n * The one custom case is `showRunProgressDialog`, which exposes an\n * imperative `update / setProgress / setStep / complete / cancelled /\n * close` API and a `result` promise, and so\n * stays as a direct `ManagedWindow` build \u2014 but it still benefits\n * from the focus trap + chrome by virtue of `modal: true`.\n */\n\nimport { ManagedWindow } from './managed_window.js';\nimport { mountJobProgress } from './job_progress.js';\nimport {\n openConfirm, openForm, openModal,\n} from './modal.js';\n\n// Counter \u2014 used only by showRunProgressDialog which still builds its\n// own ManagedWindow. The migrated helpers don't need it.\nlet dialogIdCounter = 0;\n\n/**\n * Show a confirmation dialog. Delegates to `openConfirm`.\n * @param {Object} options\n * @param {string} options.title\n * @param {string} options.message\n * @param {string} [options.icon='warning']\n * @param {string} [options.okLabel='OK']\n * @param {string} [options.cancelLabel='Cancel']\n * @param {string} [options.okVariant='primary'] - 'primary' or 'danger'\n * @returns {Promise<boolean>}\n */\nexport async function showConfirmDialog(options = {}) {\n const {\n title = 'Confirm',\n message = 'Are you sure?',\n icon = 'warning',\n okLabel = 'OK',\n cancelLabel = 'Cancel',\n okVariant = 'primary',\n } = options;\n return openConfirm({\n title,\n message,\n icon,\n confirmLabel: okLabel,\n cancelLabel,\n danger: okVariant === 'danger',\n });\n}\n\n/**\n * Show a delete-confirmation dialog. Always danger-styled.\n * @returns {Promise<boolean>}\n */\nexport async function showDeleteConfirmDialog(options = {}) {\n const {\n itemName = '',\n itemType = 'item',\n additionalMessage = '',\n } = options;\n // `openConfirm` renders the message as text, so a user-named item\n // (`<b>x</b>`, an unclosed `<`) is shown exactly as it was typed.\n let message = `Delete ${itemType}`;\n if (itemName) message += ` \"${itemName}\"`;\n message += '?';\n if (additionalMessage) message += `\\n\\n${additionalMessage}`;\n return openConfirm({\n title: `Delete ${capitalize(itemType)}`,\n message,\n icon: 'delete',\n confirmLabel: 'Delete',\n cancelLabel: 'Cancel',\n danger: true,\n });\n}\n\n/**\n * Show a close-confirmation dialog.\n * @returns {Promise<boolean>}\n */\nexport async function showCloseConfirmDialog(options = {}) {\n const {\n itemName = '',\n itemType = 'tab',\n } = options;\n let message = `Close ${itemType}`;\n if (itemName) message += ` \"${itemName}\"`;\n message += '?';\n return openConfirm({\n title: `Close ${capitalize(itemType)}`,\n message,\n icon: 'close',\n confirmLabel: 'Close',\n cancelLabel: 'Cancel',\n });\n}\n\n/**\n * Show a dialog with multiple action buttons. Delegates to `openModal`\n * so each action maps to a button in the canonical footer.\n * @returns {Promise<string|null>}\n */\nexport async function showChoiceDialog(options = {}) {\n const {\n title = 'Choose',\n message = '',\n icon = 'warning',\n actions = [],\n } = options;\n const content = document.createElement('div');\n content.className = 'twm-confirm-dialog__body';\n content.innerHTML = `\n <span class=\"twm-confirm-dialog__icon material-symbols-outlined\">${escapeHtml(icon)}</span>\n <div class=\"twm-confirm-dialog__message\">${escapeHtml(message)}</div>\n `;\n return openModal({\n title,\n icon,\n content,\n width: 480,\n height: 220,\n actions: actions.map((a) => ({\n label: a.label,\n value: a.value,\n primary: a.variant === 'primary',\n danger: a.variant === 'danger',\n })),\n });\n}\n\n/**\n * Show a dialog with a dropdown select + OK/Cancel. Delegates to\n * `openForm` with a single select field.\n * @returns {Promise<string|null>}\n */\nexport async function showSelectDialog(options = {}) {\n const {\n title = 'Select',\n message = '',\n items = [],\n okLabel = 'OK',\n cancelLabel = 'Cancel',\n } = options;\n const fields = [];\n if (message) {\n fields.push({ section: message });\n }\n fields.push({\n name: '_choice',\n label: 'Choice',\n type: 'select',\n default: items[0]?.value || '',\n options: items.map((i) => ({ value: i.value, label: i.label })),\n });\n // NB: cancelLabel is currently hardcoded as \"Cancel\" on openForm.\n // openConfirm has cancelLabel; if a caller really needs custom\n // cancel text on openForm, we'd extend openForm there. The\n // explicit no-op suppresses the unused-arg lint.\n void cancelLabel;\n const data = await openForm({\n title,\n submitLabel: okLabel,\n fields,\n });\n if (!data) return null;\n return data._choice;\n}\n\n\n// \u2500\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\n\nfunction escapeHtml(str) {\n if (!str) return '';\n return String(str)\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\nfunction capitalize(str) {\n if (!str) return '';\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\n\n// \u2500\u2500\u2500 showRunProgressDialog (custom build) \u2500\u2500\u2500\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// This one exposes an imperative API (`update`, `setProgress`, `setStep`,\n// `complete`, `cancelled`, `close`) that the openModal/openForm/openConfirm\n// helpers don't model \u2014 they're one-shot promise-returning. Keep the direct\n// ManagedWindow build, but it still gets the TUI chrome + focus trap for free\n// via `modal: true`.\n\n/**\n * @typedef {Object} RunProgressResult\n * @property {'done'|'error'|'cancelled'} status\n * @property {string} message\n */\n\n/**\n * Show a run progress dialog with a spinner (or a bar), live message\n * updates, optional phases, and a final status.\n *\n * `progress` (`true` or ProgressBar options) shows a determinate bar in place\n * of the spinner; `steps` (StepProgress steps) shows the phases above it.\n * Both are fixed when the dialog opens: `setProgress` throws if it was opened\n * without `progress`, and `setStep` if it was opened without `steps`.\n * `result` settles once, with the final state: `complete({ok})` gives `done`\n * or `error`, `cancelled()` gives `cancelled`, and so does closing the dialog\n * while it runs (by its \u00D7, Escape or `close()`). Closing never calls\n * `onCancel`: only the Stop button does.\n *\n * @param {Object} [options]\n * @param {string} [options.title='Running Pipeline']\n * @param {string} [options.message='Starting\u2026']\n * @param {Function} [options.onCancel] - Shows a Stop button.\n * @param {boolean|Object} [options.progress] - A ProgressBar, `true` or its options.\n * @param {Array} [options.steps] - StepProgress steps.\n * @returns {{ update(msg: string): void, setProgress(next: number|Object): void,\n * setStep(which: string|number, opts?: {pass?: number, passes?: number}): void,\n * complete(result: {ok: boolean, message: string}): void, cancelled(msg?: string): void,\n * close(): void, result: Promise<RunProgressResult> }}\n */\nexport function showRunProgressDialog(options = {}) {\n const {\n title = 'Running Pipeline',\n message = 'Starting\u2026',\n onCancel,\n progress = null,\n steps = null,\n } = options;\n\n const dialogId = `run-progress-${++dialogIdCounter}`;\n let finished = false;\n let settle;\n const result = new Promise((resolve) => { settle = resolve; });\n\n const contentEl = document.createElement('div');\n contentEl.className = 'twm-confirm-dialog__content run-progress';\n\n const bodyEl = document.createElement('div');\n bodyEl.className = 'twm-run-progress__body';\n const spinnerEl = document.createElement('div');\n spinnerEl.className = 'twm-run-progress__spinner';\n const messageEl = document.createElement('div');\n messageEl.className = 'twm-run-progress__message';\n messageEl.textContent = message;\n bodyEl.append(spinnerEl, messageEl);\n contentEl.appendChild(bodyEl);\n\n const job = mountJobProgress(contentEl, { progress, steps, spinner: spinnerEl });\n\n let stopBtn = null;\n if (typeof onCancel === 'function') {\n const stopActionsEl = document.createElement('div');\n stopActionsEl.className = 'twm-confirm-dialog__actions twm-run-progress__stop-actions';\n stopBtn = document.createElement('button');\n stopBtn.type = 'button';\n stopBtn.className = 'twm-confirm-dialog__btn twm-run-progress__stop-btn';\n stopBtn.innerHTML = '<span class=\"material-symbols-outlined\">stop</span> Stop';\n stopBtn.addEventListener('click', () => {\n stopBtn.disabled = true;\n stopBtn.innerHTML = '<span class=\"material-symbols-outlined\">hourglass_top</span> Stopping\u2026';\n onCancel();\n });\n stopActionsEl.appendChild(stopBtn);\n contentEl.appendChild(stopActionsEl);\n }\n\n const actionsEl = document.createElement('div');\n actionsEl.className = 'twm-confirm-dialog__actions';\n actionsEl.style.display = 'none';\n\n const closeBtn = document.createElement('button');\n closeBtn.type = 'button';\n closeBtn.className = 'twm-confirm-dialog__btn twm-confirm-dialog__btn--primary';\n closeBtn.textContent = 'Close';\n closeBtn.addEventListener('click', () => dialogWindow.close());\n actionsEl.appendChild(closeBtn);\n contentEl.appendChild(actionsEl);\n\n const finish = (status, text, cls) => {\n finished = true;\n spinnerEl.style.display = 'none';\n if (stopBtn) stopBtn.parentElement.style.display = 'none';\n messageEl.textContent = text;\n messageEl.className = `twm-run-progress__message ${cls}`;\n job.finish(status);\n actionsEl.style.display = '';\n settle({ status, message: text });\n };\n\n const dialogWindow = new ManagedWindow({\n id: dialogId,\n title,\n icon: 'play_arrow',\n content: contentEl,\n minWidth: 320,\n minHeight: 120,\n defaultWidth: 420,\n defaultHeight: 200 + (job.bar ? 40 : 0) + (job.steps ? 40 : 0),\n canMinimize: false,\n canMaximize: false,\n canResize: false,\n canDrag: false,\n modal: true,\n onClose: () => {\n if (finished) return;\n finish('cancelled', 'Cancelled.', 'is-cancelled');\n },\n });\n dialogWindow.show();\n\n return {\n result,\n update(msg) {\n if (finished) return;\n messageEl.textContent = msg;\n },\n setProgress(next) {\n if (finished) return;\n job.setProgress(next);\n },\n setStep(which, opts) {\n if (finished) return;\n job.setStep(which, opts);\n },\n complete(res) {\n if (finished) return;\n finish(res?.ok ? 'done' : 'error', res?.message || '', res?.ok ? 'is-ok' : 'is-err');\n },\n cancelled(msg) {\n if (finished) return;\n finish('cancelled', msg || 'Cancelled.', 'is-cancelled');\n },\n close() {\n try { dialogWindow.close(); } catch { /* already closed */ }\n },\n };\n}\n", "/**\n * \u2550\u2550 THE CONVERSATION VIEW \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\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 transcript of role-tagged messages above a composer (FlexDesk STORY-0057).\n * It knows nothing about what a message says or where it came from: no\n * markdown, no model, no provider. The caller draws a message's body (or\n * leaves it as plain text) and is told when the user submits or cancels.\n *\n * const view = mountConversationView(el, {\n * render: (message, bodyEl, { streaming }) => { bodyEl.innerHTML = toHtml(message.text); },\n * onSubmit: (text) => send(text),\n * onCancel: () => stop(),\n * });\n * view.append({ role: 'user', text: 'Hello' });\n * view.beginStream({ role: 'assistant' });\n * view.appendChunk('Hi'); // re-renders ONLY the streaming message\n * view.endStream();\n *\n * MESSAGES are `{ id?, role, text, meta? }`. `id` is assigned when absent;\n * `role` becomes a modifier class (`twm-chat__msg--<role>`); `meta` is the\n * caller's and is handed back untouched. `append`, `replaceAll` and `clear`\n * change the list; `messages()` reads it. An id already in the transcript (or\n * repeated within one `replaceAll`) is refused with a throw, and a refused\n * call changes nothing. Each message has an EXTRA SLOT\n * (`slot(id)`), an element below the body the caller fills with whatever\n * belongs to that message \u2014 tool output, buttons, a diff \u2014 and which a\n * re-render of the body never touches.\n *\n * THE RENDER CALLBACK draws one body: `render(message, bodyEl, { streaming })`.\n * The body is emptied before every call. One that throws leaves the message\n * as its plain text (`twm-chat__body--plain`) and the view carries on; the\n * error goes to `onRenderError(error, message)` when given.\n *\n * STREAMING: `beginStream(message?)` appends a message marked streaming,\n * `appendChunk(text)` adds to its text and re-renders that message's body\n * alone, `endStream()` renders it a last time, unmarked. Nothing is deferred to\n * a frame: every call has drawn by the time it returns.\n *\n * PINNED TO THE BOTTOM: the view starts out following new content. Any\n * scroll UP \u2014 even a few px from the end, and whichever frame of a smooth\n * wheel or key scroll reports it \u2014 stops the following and shows *Jump to\n * latest*, and no later chunk moves the reader back. Following resumes only\n * on a scroll down (or a move that is not up) that ends within\n * `pinThreshold` px of the end, a click on *Jump to latest*,\n * `scrollToBottom()`, `replaceAll()` / `clear()`, or a `setScrollTop(px)`\n * that lands within the threshold. Content growing below a pinned view\n * never unpins it, nor does content shrinking under it (the browser clamps\n * `scrollTop` to the new end, which is not a move up). A wheel over\n * a nested scroller (a `<pre>` in a body, say) scrolls that, not the view;\n * nor does a wheel a handler inside the transcript cancelled, a Ctrl+wheel\n * (zoom, or a trackpad pinch), or a wheel up over a transcript already at its\n * top. `scrollTop` is\n * readable and settable (`getScrollTop` / `setScrollTop`) so an embedder can\n * keep it across a remount.\n *\n * THE COMPOSER is a textarea that grows with its text up to\n * `composerMaxHeight`. Enter submits (the trimmed-empty text is ignored) and\n * clears it; Shift+Enter is left to the browser, which inserts the newline\n * (native undo, `input` events). `setBusy(true)` turns Send into Cancel: Enter\n * then submits nothing, and Esc \u2014 wherever focus is inside the view \u2014 or a\n * click on Cancel calls `onCancel`, once per busy period, however often it is\n * pressed. That Esc stops there: it never reaches a window or panel around\n * the view that would close on Escape. An Esc a handler inside the view has\n * already consumed (`preventDefault`, say an inline popup or editor in the\n * transcript closing itself) is left alone: it neither cancels nor is stopped.\n *\n * `destroy()` removes the view. Every listener sits on an element the view\n * created, so they go with it; none is on the host or the document.\n */\n\n/** How near the end of the transcript still counts as \"at the bottom\". */\nexport const CONVERSATION_PIN_WITHIN_PX = 32;\n\n/**\n * A drop in `scrollTop` that still leaves the view this close to its end is\n * the browser clamping it after the content shrank (or sub-pixel rounding),\n * not the reader scrolling up.\n */\nconst AT_END_PX = 1;\n\n/** The tallest the composer grows before it scrolls instead. */\nexport const CONVERSATION_COMPOSER_MAX_PX = 200;\n\n/**\n * @param {HTMLElement} host\n * @param {object} [opts]\n * @param {Function} [opts.render] `(message, bodyEl, { streaming })` \u2014 draws a body; plain text without it\n * @param {Function} [opts.onSubmit] `(text)` \u2014 Enter or Send\n * @param {Function} [opts.onCancel] `()` \u2014 Esc or Cancel while busy\n * @param {Function} [opts.onRenderError] `(error, message)` \u2014 a render that threw\n * @param {number} [opts.pinThreshold] px from the end that still follows new content\n * @param {number} [opts.composerMaxHeight] px the composer grows to\n * @param {string} [opts.placeholder] the composer's placeholder\n * @param {object} [opts.labels] `{ send, cancel, jump, input }` \u2014 button and field texts\n * @returns {object} the view (see the methods below)\n */\nexport function mountConversationView(host, {\n render = null, onSubmit = null, onCancel = null, onRenderError = null,\n pinThreshold = CONVERSATION_PIN_WITHIN_PX, composerMaxHeight = CONVERSATION_COMPOSER_MAX_PX,\n placeholder = '', labels = {},\n} = {}) {\n const text = {\n send: 'Send', cancel: 'Cancel', jump: 'Jump to latest', input: 'Message', ...labels,\n };\n const doc = host.ownerDocument;\n const el = (tag, cls, content) => {\n const n = doc.createElement(tag);\n if (cls) n.className = cls;\n if (content !== undefined) n.textContent = content;\n return n;\n };\n const icon = (name) => {\n const i = el('span', 'material-symbols-outlined', name);\n i.setAttribute('aria-hidden', 'true');\n return i;\n };\n\n /** id \u2192 { message, row, body, extra } in transcript order. */\n const entries = new Map();\n let nextId = 1;\n let streamId = null;\n let pinned = true;\n let lastScrollTop = 0;\n let busy = false;\n let cancelled = false;\n let destroyed = false;\n\n // \u2500\u2500 the frame \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 const root = el('div', 'twm-chat');\n const viewport = el('div', 'twm-chat__viewport');\n const log = el('div', 'twm-chat__log');\n log.setAttribute('role', 'log');\n log.setAttribute('aria-live', 'polite');\n const jump = el('button', 'twm-chat__jump');\n jump.type = 'button';\n jump.append(icon('arrow_downward'), doc.createTextNode(` ${text.jump}`));\n jump.hidden = true;\n viewport.append(log, jump);\n\n const composer = el('div', 'twm-chat__composer');\n const input = el('textarea', 'twm-chat__input');\n input.rows = 1;\n input.placeholder = placeholder;\n input.setAttribute('aria-label', text.input);\n const send = el('button', 'twm-chat__send');\n send.type = 'button';\n composer.append(input, send);\n root.append(viewport, composer);\n host.append(root);\n\n // \u2500\u2500 scrolling \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 const distanceFromEnd = () => log.scrollHeight - log.scrollTop - log.clientHeight;\n const toBottom = () => {\n log.scrollTop = log.scrollHeight;\n lastScrollTop = log.scrollTop;\n };\n const setPinned = (value) => {\n pinned = value;\n jump.hidden = pinned;\n };\n /**\n * Reads the position the reader left: any move up stops following, however\n * near the end it stops (a smooth wheel or key scroll reports its first\n * frame only a few px up). Returns whether the move may follow again: it\n * was not up and ends within `pinThreshold` of the end. Shared by the\n * `scroll` event and by settle(), because a scrollbar drag, a key or a\n * touch moves `scrollTop` before its `scroll` event is dispatched, and a\n * change arriving in between must not snap the reader back.\n */\n function noticeMove() {\n const top = log.scrollTop;\n const distance = distanceFromEnd();\n const movedUp = top < lastScrollTop && distance > AT_END_PX;\n lastScrollTop = top;\n if (movedUp && pinned) setPinned(false);\n return !movedUp && distance <= pinThreshold;\n }\n /** After every change to the transcript: follow it, or leave the reader where they are. */\n const settle = () => {\n noticeMove();\n if (pinned) toBottom();\n };\n\n function onScroll() { if (noticeMove() && !pinned) setPinned(true); }\n /**\n * Whether a wheel up over `target` is kept by something nested inside the\n * transcript \u2014 a scrollable block in a body or an extra slot that is not\n * at its own top, or one at its top whose `overscroll-behavior` keeps the\n * scroll from chaining out \u2014 rather than moving the transcript itself.\n */\n function innerTakesWheelUp(target) {\n const view = doc.defaultView;\n for (let n = target; n && n !== log; n = n.parentElement) {\n if (n.nodeType !== 1 || n.scrollHeight <= n.clientHeight) continue;\n const style = view?.getComputedStyle(n);\n const overflow = style?.overflowY;\n if (overflow !== 'auto' && overflow !== 'scroll' && overflow !== 'overlay') continue;\n if (n.scrollTop > 0) return true;\n const chain = style.getPropertyValue('overscroll-behavior-y');\n if (chain === 'contain' || chain === 'none') return true;\n }\n return false;\n }\n /**\n * A wheel up that will move the transcript stops following at once, before\n * the scroll it causes is reported. One that a nested scroller keeps, or\n * one a handler inside the transcript cancelled (a zoomable chart in a\n * slot, say), leaves the transcript where it is, so it changes nothing.\n * Nor does a Ctrl+wheel (page zoom; a trackpad pinch arrives as one), or\n * a wheel up over a transcript already at its top, which cannot go up.\n */\n function onWheel(e) {\n if (e.deltaY < 0 && pinned && !e.ctrlKey && !e.defaultPrevented && log.scrollTop > 0\n && !innerTakesWheelUp(e.target)) setPinned(false);\n }\n function onJump() { setPinned(true); toBottom(); }\n log.addEventListener('scroll', onScroll);\n log.addEventListener('wheel', onWheel, { passive: true });\n jump.addEventListener('click', onJump);\n\n // \u2500\u2500 messages \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 fresh id, never one `taken` holds. */\n const newId = (taken = (id) => entries.has(id)) => {\n let id;\n do id = `m${nextId++}`; while (taken(id));\n return id;\n };\n const duplicate = (id) => new Error(`conversation view: duplicate message id \"${id}\"`);\n const roleClass = (role) => String(role ?? '').toLowerCase().replace(/[^a-z0-9-]+/g, '-') || 'none';\n const snapshot = (message) => ({ ...message });\n\n function drawBody(entry, streaming = entry.message.id === streamId) {\n const { message, body } = entry;\n body.replaceChildren();\n body.classList.remove('twm-chat__body--plain');\n if (render) {\n try {\n render(snapshot(message), body, { streaming });\n return;\n } catch (error) {\n body.replaceChildren();\n if (onRenderError) {\n try { onRenderError(error, snapshot(message)); } catch { /* the view keeps working */ }\n }\n }\n }\n body.classList.add('twm-chat__body--plain');\n body.textContent = message.text;\n }\n\n /**\n * One entry, drawn, and added to `into` (the transcript unless a\n * replaceAll is building its own). Throws on an id `into` already holds,\n * before anything is changed.\n */\n function build(spec, { into = entries, taken, streaming = false } = {}) {\n const message = {\n ...spec,\n id: spec?.id ?? newId(taken ?? ((id) => into.has(id))),\n role: spec?.role ?? 'assistant',\n text: String(spec?.text ?? ''),\n };\n if (into.has(message.id)) throw duplicate(message.id);\n const row = el('div', `twm-chat__msg twm-chat__msg--${roleClass(message.role)}`);\n if (streaming) row.classList.add('twm-chat__msg--streaming');\n const body = el('div', 'twm-chat__body');\n const extra = el('div', 'twm-chat__extra');\n row.append(body, extra);\n const entry = { message, row, body, extra };\n into.set(message.id, entry);\n drawBody(entry, streaming);\n return entry;\n }\n\n function append(message) {\n const entry = build(message);\n log.append(entry.row);\n settle();\n return entry.message.id;\n }\n\n /** All or nothing: a repeated id throws before the transcript is touched. No list (undefined or null) empties it. */\n function replaceAll(messages) {\n const list = [...(messages ?? [])];\n const given = new Set();\n for (const m of list) {\n if (m?.id == null) continue;\n if (given.has(m.id)) throw duplicate(m.id);\n given.add(m.id);\n }\n const next = new Map();\n const taken = (id) => given.has(id) || next.has(id);\n const frag = doc.createDocumentFragment();\n for (const m of list) frag.append(build(m, { into: next, taken }).row);\n streamId = null;\n entries.clear();\n for (const [id, entry] of next) entries.set(id, entry);\n log.replaceChildren(frag);\n setPinned(true);\n toBottom();\n }\n\n function clear() { replaceAll([]); }\n\n // \u2500\u2500 streaming \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 * Refused (a throw, nothing changed, an open stream left open) on an id\n * already present. No message (undefined or null) streams an empty\n * assistant message, as `append` treats them.\n */\n function beginStream(message) {\n if (message?.id != null && entries.has(message.id)) throw duplicate(message.id);\n if (streamId !== null) endStream();\n const entry = build({ role: 'assistant', text: '', ...(message ?? {}) }, { streaming: true });\n streamId = entry.message.id;\n log.append(entry.row);\n settle();\n return streamId;\n }\n\n function appendChunk(chunk) {\n const entry = streamId !== null ? entries.get(streamId) : null;\n if (!entry) return;\n entry.message.text += String(chunk ?? '');\n drawBody(entry);\n settle();\n }\n\n function endStream() {\n const entry = streamId !== null ? entries.get(streamId) : null;\n streamId = null;\n if (!entry) return null;\n entry.row.classList.remove('twm-chat__msg--streaming');\n drawBody(entry);\n settle();\n return entry.message.id;\n }\n\n // \u2500\u2500 the composer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 function grow() {\n input.style.height = 'auto';\n input.style.height = `${Math.min(input.scrollHeight, composerMaxHeight)}px`;\n input.style.overflowY = input.scrollHeight > composerMaxHeight ? 'auto' : 'hidden';\n }\n\n function drawSend() {\n send.replaceChildren(icon(busy ? 'stop' : 'send'));\n send.setAttribute('aria-label', busy ? text.cancel : text.send);\n send.title = busy ? text.cancel : text.send;\n send.classList.toggle('twm-chat__send--cancel', busy);\n root.classList.toggle('twm-chat--busy', busy);\n }\n\n function submit() {\n if (busy) return;\n const value = input.value;\n if (!value.trim()) return;\n input.value = '';\n grow();\n onSubmit?.(value);\n }\n\n function cancel() {\n if (!busy || cancelled) return;\n cancelled = true;\n onCancel?.();\n }\n\n /** Enter submits; Shift+Enter (and Ctrl/Meta/Alt+Enter) is the browser's to handle. */\n function onInputKey(e) {\n if (e.isComposing || e.key !== 'Enter') return;\n if (e.shiftKey || e.ctrlKey || e.metaKey || e.altKey) return;\n e.preventDefault();\n submit();\n }\n /**\n * Esc while busy cancels wherever focus is inside the view, and it is the\n * view's alone: it goes no further, so a window or panel holding the view\n * that closes on Escape stays open \u2014 on the cancelling Esc and on any\n * repeat in the same busy period. An Esc a handler inside the view\n * already consumed (defaultPrevented) is that handler's: it neither\n * cancels nor is stopped.\n */\n function onRootKey(e) {\n if (e.isComposing || e.key !== 'Escape' || !busy || e.defaultPrevented) return;\n e.preventDefault();\n e.stopPropagation();\n cancel();\n }\n input.addEventListener('keydown', onInputKey);\n input.addEventListener('input', grow);\n root.addEventListener('keydown', onRootKey);\n send.addEventListener('click', () => (busy ? cancel() : submit()));\n drawSend();\n\n return {\n root,\n append,\n replaceAll,\n clear,\n beginStream,\n appendChunk,\n endStream,\n /** A copy of every message, in order. */\n messages: () => [...entries.values()].map((e) => snapshot(e.message)),\n /** The extra slot below a message's body, or null for an unknown id. */\n slot: (id) => entries.get(id)?.extra ?? null,\n /** The id of the message being streamed, or null. */\n streamingId: () => streamId,\n isPinned: () => pinned,\n getScrollTop: () => log.scrollTop,\n /** Scrolls the transcript; pinned again only when that lands at the end. */\n setScrollTop(px) {\n log.scrollTop = px;\n lastScrollTop = log.scrollTop;\n setPinned(distanceFromEnd() <= pinThreshold);\n },\n scrollToBottom: onJump,\n /** `true` turns Send into Cancel; every busy period may cancel once. */\n setBusy(value) {\n if (busy === !!value) return;\n busy = !!value;\n cancelled = false;\n drawSend();\n },\n isBusy: () => busy,\n getText: () => input.value,\n setText(value) { input.value = String(value ?? ''); grow(); },\n focus: () => input.focus(),\n destroy() {\n if (destroyed) return;\n destroyed = true;\n streamId = null;\n busy = false;\n cancelled = false;\n entries.clear();\n root.remove();\n },\n };\n}\n", "/**\n * DetailHeader \u2014 shared header bar for detail views.\n *\n * Usage:\n * import { createDetailHeader, updateDetailHeader } from '../ui/components/detail_header.js';\n *\n * const header = createDetailHeader({\n * title: 'My Scenario',\n * badges: [{ text: 'Static' }],\n * renameable: true,\n * onRename: async (name) => ({ success: true }),\n * actions: [\n * { key: 'run', label: 'Run', icon: 'play_arrow', variant: 'primary', handler: () => {} },\n * { key: 'delete', label: 'Delete', icon: 'delete', variant: 'danger', handler: () => {} },\n * ],\n * });\n * container.appendChild(header);\n *\n * To update in place (e.g., running state changed):\n * updateDetailHeader(header, { ...newConfig });\n */\n\nimport { attachInlineRenamer } from './inline_renamer.js';\n\nconst ESC = (s) => String(s ?? '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n\n/**\n * @typedef {Object} DetailHeaderBadge\n * @property {string} text\n * @property {string} [className] - Extra class(es) of your own (e.g., 'my-badge--live'); the\n * pill itself is `.twm-detail-header__badge`\n * @property {string} [icon] - Material Symbols icon name\n */\n\n/**\n * @typedef {Object} DetailHeaderAction\n * @property {string} key - data-action value\n * @property {string} label - Button text\n * @property {string} [icon] - Material Symbols icon name (none: label only)\n * @property {'primary'|'secondary'|'danger'} [variant='secondary'] - The button is a `.twm-btn`;\n * 'primary' and 'danger' add `.twm-btn--primary` / `.twm-btn--danger`, and every\n * variant is also named `.twm-detail-header__btn--<variant>`\n * @property {boolean} [disabled=false]\n * @property {string} [title] - Tooltip\n * @property {Function} handler - Click callback\n */\n\n/**\n * @typedef {Object} DetailHeaderConfig\n * @property {string} title\n * @property {string} [subtitle]\n * @property {string} [icon] - Material icon before title\n * @property {DetailHeaderBadge[]} [badges]\n * @property {DetailHeaderAction[]} [actions]\n * @property {HTMLElement[]} [extraElements] - Custom elements appended to actions area\n * @property {boolean} [renameable=false]\n * @property {Function} [onRename] - (newName) => Promise<{success, newValue?}>\n */\n\n/**\n * Create a detail header element.\n * @param {DetailHeaderConfig} config\n * @returns {HTMLElement}\n */\nexport function createDetailHeader(config) {\n const header = document.createElement('header');\n header.className = 'twm-detail-header';\n _populate(header, config);\n return header;\n}\n\n/**\n * Update an existing detail header in place.\n * Destroys previous inline renamer and rebuilds inner DOM.\n * @param {HTMLElement} headerEl\n * @param {DetailHeaderConfig} config\n */\nexport function updateDetailHeader(headerEl, config) {\n // Destroy previous renamer if any\n headerEl._renamer?.destroy();\n headerEl._renamer = null;\n headerEl.innerHTML = '';\n _populate(headerEl, config);\n}\n\n// \u2500\u2500\u2500 Internal \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 _populate(header, config) {\n const { title, subtitle, icon, badges = [], actions = [], extraElements = [], renameable = false, onRename } = config;\n\n // Title row\n const titleRow = document.createElement('div');\n titleRow.className = 'twm-detail-header__title-row';\n\n if (icon) {\n const iconEl = document.createElement('span');\n iconEl.className = 'twm-detail-header__icon material-symbols-outlined';\n iconEl.textContent = icon;\n titleRow.appendChild(iconEl);\n }\n\n const nameEl = document.createElement('h2');\n nameEl.className = 'twm-detail-header__name';\n nameEl.textContent = title || '';\n if (renameable) {\n nameEl.dataset.renameable = '';\n nameEl.title = 'Double-click to rename';\n }\n titleRow.appendChild(nameEl);\n\n for (const badge of badges) {\n const badgeEl = document.createElement('span');\n badgeEl.className = `twm-detail-header__badge${badge.className ? ` ${badge.className}` : ''}`;\n if (badge.icon) {\n const bi = document.createElement('span');\n bi.className = 'twm-detail-header__badge-icon material-symbols-outlined';\n bi.textContent = badge.icon;\n badgeEl.appendChild(bi);\n }\n badgeEl.appendChild(document.createTextNode(badge.text));\n titleRow.appendChild(badgeEl);\n }\n\n header.appendChild(titleRow);\n\n // Subtitle\n if (subtitle) {\n const sub = document.createElement('div');\n sub.className = 'twm-detail-header__subtitle';\n sub.innerHTML = subtitle; // may contain <strong> etc.\n header.appendChild(sub);\n }\n\n // Actions\n if (actions.length > 0 || extraElements.length > 0) {\n const actionsEl = document.createElement('div');\n actionsEl.className = 'twm-detail-header__actions';\n\n for (const extra of extraElements) {\n actionsEl.appendChild(extra);\n }\n\n for (const action of actions) {\n const btn = document.createElement('button');\n btn.type = 'button';\n const variant = action.variant || 'secondary';\n // The shared `.twm-btn` look (BUG-0015): 'primary' and 'danger'\n // wear its colour variants; 'secondary' is the plain button.\n const look = variant === 'secondary' ? '' : ` twm-btn--${variant}`;\n btn.className = `twm-btn${look} twm-detail-header__btn twm-detail-header__btn--${variant}`;\n btn.dataset.action = action.key;\n if (action.disabled) btn.disabled = true;\n if (action.title) btn.title = action.title;\n\n if (action.icon) {\n const iconSpan = document.createElement('span');\n iconSpan.className = 'material-symbols-outlined twm-btn__glyph';\n iconSpan.textContent = action.icon;\n btn.appendChild(iconSpan);\n }\n const labelSpan = document.createElement('span');\n labelSpan.className = 'twm-btn__label';\n labelSpan.textContent = action.label ?? '';\n btn.appendChild(labelSpan);\n\n btn.addEventListener('click', () => action.handler?.());\n actionsEl.appendChild(btn);\n }\n\n header.appendChild(actionsEl);\n }\n\n // Inline rename\n if (renameable && onRename) {\n const renamer = attachInlineRenamer({\n label: nameEl,\n onCommit: async (newName) => {\n if (!newName?.trim()) return { success: false };\n return await onRename(newName.trim());\n },\n });\n nameEl.addEventListener('dblclick', (e) => {\n e.stopPropagation();\n renamer.start(e);\n });\n header._renamer = renamer;\n }\n}\n", "/**\n * fact_table.js \u2014 A SHEET OF FACTS: a name and its value, row after row, with\n * no header row, nothing truncated and no height to give it. (0.7.0)\n *\n * Server db-main-01.internal\n * Version 16.4\n * Connection postgresql://tables@db-main-01.internal:5432/tables_control\n * ?application_name=tables-api&sslmode=verify-full\n *\n * A DataTable is the wrong tool for this, for three reasons that are its\n * design rather than its defects: it draws a header row, it clips a cell to\n * one line (a long value becomes an ellipsis), and it fills a box with a\n * height (in a box without one it draws its header and no rows). A fact\n * sheet is the opposite on all three: the names are the header, every value\n * is read whole, and the sheet is exactly as tall as its rows.\n *\n * So this is a plain `<table class=\"twm-facts\">`:\n *\n * - the first column is the LABEL \u2014 muted, and kept on one line (pass\n * `wrapLabels: true` to let a long one wrap, `labelColumn: false` for a\n * sheet whose first column is ordinary data);\n * - every value WRAPS \u2014 at spaces, and inside a long word or URL when it must\n * (`overflow-wrap: anywhere`) \u2014 and keeps its own line breaks, so a\n * pretty-printed JSON value reads as one; `wrap: 'words'` wraps at spaces\n * only and keeps a long word whole (the sheet grows wider, for a sideways\n * scroller around it), and `wrap: 'none'` keeps only the value's own breaks;\n * - a value is text, a number or a NODE (a pill, a link, a button); an\n * object or array is drawn as indented JSON; `null` is an empty cell, or\n * `nullDisplay`;\n * - `mono` draws values in the monospace face, for the whole sheet or one row;\n * - `compare: true` gives each row a BEFORE and an AFTER, with an arrow\n * between: a row whose two sides differ is `--changed`, one that has only\n * an after is `--added`, only a before `--removed`, and the same on both\n * sides `--same`. A row with a plain `value` spans both sides;\n * - `headers` adds a header row after all, for the sheets that have several\n * columns of facts (a list of schemas, a list of pools); rows are then\n * arrays of cells, and `numeric` names the columns of figures.\n *\n * A row may be an OBJECT \u2014 `{label, value}` or `{label, before, after}`, with\n * `mono`, `numeric`, `labelTitle`, `key` and `status` \u2014 or an ARRAY of cells,\n * `[label, value, \u2026]`, which is the positional form a multi-column sheet uses.\n */\n\nlet SEQ = 0;\nconst isNode = (v) => typeof Node !== 'undefined' && v instanceof Node;\n\n/**\n * @typedef {Object} FactRow\n * @property {string|Node} label\n * @property {*} [value]\n * @property {*} [before] - With `compare`: the value before.\n * @property {*} [after] - With `compare`: the value after.\n * @property {boolean} [mono] - This row's values in the monospace face.\n * @property {boolean} [numeric] - This row's values in tabular numerals.\n * @property {string} [labelTitle] - A tooltip on the label.\n * @property {*} [key] - `data-key` on the row.\n * @property {'changed'|'same'|'added'|'removed'} [status] - With `compare`:\n * overrides the status worked out from the two sides.\n */\n\n/**\n * @typedef {Object} FactTableConfig\n * @property {Array<FactRow|Array>} [rows=[]]\n * @property {string[]|null} [headers=null] - A header row. Off by default.\n * @property {boolean} [compare=false] - A before and an after column.\n * @property {boolean} [labelColumn=true] - The first column is a label.\n * @property {boolean} [wrapLabels=false] - Let a long label wrap.\n * @property {'anywhere'|'words'|'none'} [wrap='anywhere'] - How a value wraps:\n * at spaces and inside a long word when it must (the default), at spaces\n * only (`'words'`: a long word stays whole and the sheet grows wider \u2014 for a\n * sheet inside a sideways scroller), or not at all beyond its own line\n * breaks (`'none'`).\n * @property {boolean} [mono=false] - Every value in the monospace face.\n * @property {number[]} [numeric=[]] - Column indices drawn in tabular numerals.\n * @property {string} [nullDisplay=''] - What `null`/`undefined` reads as.\n * @property {string} [missing='\u2014'] - With `compare`: an absent side.\n * @property {Function} [rowClass] - `(row, idx) => string|string[]|null`.\n * @property {Function} [rowAttrs] - `(row, idx) => {name: value}`.\n * @property {string|Node|Function} [emptyState] - Shown when there are no rows.\n * @property {string} [label] - The table's accessible name (`aria-label`).\n * @property {string} [className] - Added to the `<table>`.\n */\n\nexport class FactTable {\n /**\n * @param {HTMLElement|null} host appended to, if given\n * @param {FactTableConfig} [config]\n */\n constructor(host, config = {}) {\n this.config = {\n rows: [],\n headers: null,\n compare: false,\n labelColumn: true,\n wrapLabels: false,\n wrap: 'anywhere',\n mono: false,\n numeric: [],\n nullDisplay: '',\n missing: '\u2014',\n rowClass: null,\n rowAttrs: null,\n emptyState: null,\n label: null,\n className: null,\n ...config,\n };\n this._rows = Array.isArray(this.config.rows) ? this.config.rows.slice() : [];\n this._id = ++SEQ;\n const table = document.createElement('table');\n table.className = 'twm-facts'\n + (this.config.compare ? ' twm-facts--compare' : '')\n + (this.config.labelColumn ? '' : ' twm-facts--no-label')\n + (this.config.wrapLabels ? ' twm-facts--wrap-labels' : '')\n + (this.config.wrap === 'words' ? ' twm-facts--wrap-words'\n : this.config.wrap === 'none' ? ' twm-facts--wrap-none' : '')\n + (this.config.mono ? ' twm-facts--mono' : '')\n + (this.config.className ? ` ${this.config.className}` : '');\n if (this.config.label) table.setAttribute('aria-label', this.config.label);\n this.element = table;\n this._draw();\n if (host) host.appendChild(table);\n }\n\n /** Replace the rows and draw them. */\n setRows(rows) {\n this._rows = Array.isArray(rows) ? rows.slice() : [];\n this._draw();\n }\n\n getRows() {\n return this._rows.slice();\n }\n\n /** The `<tr>` drawn for row `idx`, or null. */\n getRow(idx) {\n return this.element.tBodies[0]?.rows[idx]?.__factIndex === idx\n ? this.element.tBodies[0].rows[idx] : null;\n }\n\n dispose() {\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 /** How many columns the sheet has. */\n _width() {\n const { compare, headers } = this.config;\n if (compare) return 4;\n let n = 2;\n if (Array.isArray(headers)) n = Math.max(n, headers.length);\n for (const r of this._rows) if (Array.isArray(r)) n = Math.max(n, r.length);\n return n;\n }\n\n _draw() {\n const table = this.element;\n table.replaceChildren();\n const width = this._width();\n const { headers, compare } = this.config;\n\n if (Array.isArray(headers) && headers.length) {\n const thead = document.createElement('thead');\n const tr = document.createElement('tr');\n // With `compare`, three names stand over label, before and after;\n // the arrow column gets an empty one.\n const names = compare && headers.length === 3\n ? [headers[0], headers[1], '', headers[2]] : headers;\n for (let i = 0; i < width; i++) {\n const th = document.createElement('th');\n th.scope = 'col';\n appendContent(th, names[i] ?? '');\n if (this._numeric(i)) th.classList.add('twm-facts__num');\n tr.appendChild(th);\n }\n thead.appendChild(tr);\n table.appendChild(thead);\n }\n\n const tbody = document.createElement('tbody');\n this._rows.forEach((row, idx) => tbody.appendChild(this._row(row, idx, width)));\n if (!this._rows.length) {\n let content = this.config.emptyState;\n if (typeof content === 'function') content = content();\n if (content != null && content !== false && content !== '') {\n const tr = document.createElement('tr');\n tr.className = 'twm-facts__empty-row';\n const td = document.createElement('td');\n td.className = 'twm-facts__empty';\n td.colSpan = width;\n appendContent(td, content);\n tr.appendChild(td);\n tbody.appendChild(tr);\n }\n }\n table.classList.toggle('twm-facts--empty', this._rows.length === 0);\n table.appendChild(tbody);\n }\n\n _numeric(col) {\n const n = this.config.numeric;\n return Array.isArray(n) && n.includes(col);\n }\n\n _row(row, idx, width) {\n const tr = document.createElement('tr');\n tr.className = 'twm-facts__row';\n tr.__factIndex = idx;\n tr.__fact = row;\n if (Array.isArray(row)) {\n for (let i = 0; i < width; i++) {\n const td = this._cell(i === 0 && this.config.labelColumn ? 'label' : 'value', row[i]);\n if (this._numeric(i)) td.classList.add('twm-facts__num');\n if (i === row.length - 1 && row.length < width) {\n td.colSpan = width - i;\n tr.appendChild(td);\n break;\n }\n tr.appendChild(td);\n }\n } else {\n const r = row && typeof row === 'object' ? row : { label: row };\n if (r.key !== undefined && r.key !== null) tr.dataset.key = String(r.key);\n const label = this._cell(this.config.labelColumn ? 'label' : 'value', r.label);\n if (r.labelTitle) label.title = String(r.labelTitle);\n tr.appendChild(label);\n const tune = (td) => {\n if (r.mono) td.classList.add('twm-facts__mono');\n if (r.numeric) td.classList.add('twm-facts__num');\n return td;\n };\n const hasBefore = Object.prototype.hasOwnProperty.call(r, 'before');\n const hasAfter = Object.prototype.hasOwnProperty.call(r, 'after');\n if (this.config.compare && (hasBefore || hasAfter)) {\n const status = r.status || statusOf(r, hasBefore, hasAfter);\n tr.classList.add(`twm-facts__row--${String(status).replace(/[^\\w-]/g, '')}`);\n tr.dataset.status = String(status);\n const before = tune(hasBefore ? this._cell('value', r.before) : this._missing());\n before.classList.add('twm-facts__before');\n const arrow = document.createElement('td');\n arrow.className = 'twm-facts__arrow';\n arrow.setAttribute('aria-hidden', 'true');\n arrow.textContent = '\u2192';\n const after = tune(hasAfter ? this._cell('value', r.after) : this._missing());\n after.classList.add('twm-facts__after');\n tr.append(before, arrow, after);\n } else {\n const value = tune(this._cell('value', r.value));\n if (width > 2) value.colSpan = width - 1;\n tr.appendChild(value);\n }\n }\n this._decorate(tr, row, idx);\n return tr;\n }\n\n _cell(kind, content) {\n const isLabel = kind === 'label';\n const td = document.createElement(isLabel ? 'th' : 'td');\n td.className = isLabel ? 'twm-facts__label' : 'twm-facts__value';\n if (isLabel) td.scope = 'row';\n if (content === null || content === undefined) {\n const said = isLabel ? '' : this.config.nullDisplay;\n if (said) {\n td.textContent = String(said);\n td.classList.add('twm-facts__null');\n }\n } else {\n appendContent(td, content);\n }\n return td;\n }\n\n _missing() {\n const td = document.createElement('td');\n td.className = 'twm-facts__value twm-facts__missing';\n td.textContent = String(this.config.missing ?? '');\n return td;\n }\n\n _decorate(tr, row, idx) {\n const { rowClass, rowAttrs } = this.config;\n if (typeof rowClass === 'function') {\n const c = rowClass(row, idx);\n const list = Array.isArray(c) ? c : String(c ?? '').split(/\\s+/);\n for (const name of list) if (name) tr.classList.add(String(name));\n }\n if (typeof rowAttrs === 'function') {\n for (const [name, value] of Object.entries(rowAttrs(row, idx) || {})) {\n if (value == null || value === false) continue;\n try {\n tr.setAttribute(name, value === true ? '' : String(value));\n } catch (err) {\n console.error(`[FactTable] rowAttrs: bad attribute \"${name}\"`, err);\n }\n }\n }\n }\n}\n\n/**\n * Build a fact sheet, append it to `host` (if given) and draw it.\n *\n * @param {HTMLElement|null} host\n * @param {FactTableConfig} [config]\n * @returns {FactTable}\n */\nexport function createFactTable(host, config = {}) {\n return new FactTable(host, config);\n}\n\n/** What a before/after row says, from its two sides. Nodes cannot be\n * compared, so a row that has one is `changed` unless it says otherwise;\n * objects compare by their JSON. */\nfunction statusOf(r, hasBefore, hasAfter) {\n if (!hasBefore) return 'added';\n if (!hasAfter) return 'removed';\n if (isNode(r.before) || isNode(r.after)) return 'changed';\n if (Object.is(r.before, r.after)) return 'same';\n if (r.before && r.after && typeof r.before === 'object' && typeof r.after === 'object') {\n try {\n return JSON.stringify(r.before) === JSON.stringify(r.after) ? 'same' : 'changed';\n } catch {\n return 'changed';\n }\n }\n return 'changed';\n}\n\n/** Text, a number, a node, or an object (drawn as indented JSON) into `el`. */\nfunction appendContent(el, content) {\n if (content === null || content === undefined) return;\n if (isNode(content)) { el.appendChild(content); return; }\n let text;\n if (typeof content === 'object') {\n try { text = JSON.stringify(content, null, 2); } catch { text = String(content); }\n } else {\n text = String(content);\n }\n el.appendChild(document.createTextNode(text));\n}\n", "/**\n * gallery_picker.js \u2014 single-select card grid for the starter catalog.\n *\n * G1.3 in docs/STARTER_GALLERY_REQUIREMENTS.md. Used by every\n * \"New X\" modal to let the user pick a starter shape (formerly\n * called a \"template\"). The picker is mounted into a host element\n * and fires `onChange(entry)` whenever the selection changes.\n *\n * The entries come from `opts.entries`, or else from the host's optional\n * `gallery` capability (`host.gallery.list(kind)`, see host.js). Each entry is\n *\n * { id, kind, label, description, fields }\n *\n * The picker shows label + description as a card. `fields` is\n * passed through to the caller untouched on select \u2014 the New-X\n * handler decides what to do with it.\n *\n * Usage:\n *\n * const picker = await mountGalleryPicker(hostEl, {\n * host, // or entries: [...]\n * kind: 'agent',\n * selectedId: 'blank',\n * onChange: (entry) => { \u2026 },\n * });\n *\n * // later \u2026\n * picker.getSelected(); // \u2192 { id, kind, label, description, fields }\n * picker.dispose();\n */\n\nfunction esc(s) {\n return String(s ?? '').replace(/[&<>\"']/g, (c) => ({\n '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;',\n }[c]));\n}\n\n\n/**\n * Mount a starter-gallery picker into `hostEl`.\n *\n * @param {HTMLElement} hostEl\n * @param {object} opts\n * @param {string} opts.kind \u2014 gallery entries to load (e.g. 'agent').\n * When undefined, every kind shows up.\n * @param {string} [opts.selectedId] \u2014 id to pre-select. If absent, the\n * first entry wins.\n * @param {function} [opts.onChange] \u2014 `(entry) => void` fired on selection\n * change AND on initial mount.\n * @param {object[]} [opts.entries] \u2014 explicit entries (the host is not asked).\n * @param {object} [opts.host] \u2014 a Host; its `gallery.list(kind)` supplies\n * the entries when `entries` is absent.\n * With neither, the picker shows\n * `emptyLabel` and warns once.\n * @param {string} [opts.emptyLabel] \u2014 copy shown when the catalog is empty\n * for that kind.\n * @returns {Promise<{getSelected, setSelectedById, dispose}>}\n */\nexport async function mountGalleryPicker(hostEl, opts = {}) {\n const {\n kind = null,\n selectedId = null,\n onChange = () => {},\n entries = null,\n host = null,\n emptyLabel = 'No starters available for this kind.',\n } = opts;\n if (!hostEl) throw new Error('mountGalleryPicker: hostEl is required');\n\n let catalog = entries;\n if (!catalog) {\n const list = host?.gallery?.list;\n if (typeof list !== 'function') {\n console.warn('[gallery-picker] no entries and no host gallery capability; showing the empty label');\n catalog = [];\n } else {\n try {\n catalog = (await list(kind)) || [];\n } catch (err) {\n console.warn('[gallery-picker] host.gallery.list failed', err);\n catalog = [];\n }\n }\n }\n catalog = Array.isArray(catalog) ? catalog : [];\n\n hostEl.classList.add('twm-gallery-picker');\n if (catalog.length === 0) {\n hostEl.innerHTML = `<div class=\"twm-gallery-picker__empty\">${esc(emptyLabel)}</div>`;\n return {\n getSelected: () => null,\n setSelectedById: () => false,\n dispose: () => { hostEl.classList.remove('twm-gallery-picker'); },\n };\n }\n\n let selected = catalog.find((e) => e?.id === selectedId)\n || catalog[0];\n\n const render = () => {\n hostEl.innerHTML = catalog.map((e, i) => {\n const isSel = e === selected;\n const desc = e?.description\n ? `<p class=\"twm-gallery-card__desc\">${esc(e.description)}</p>`\n : '';\n return `\n <button type=\"button\"\n class=\"twm-gallery-card ${isSel ? 'is-selected' : ''}\"\n data-idx=\"${i}\"\n title=\"${esc(e?.id || '')}\">\n <span class=\"twm-gallery-card__label\">${esc(e?.label || e?.id || '')}</span>\n ${desc}\n </button>\n `;\n }).join('');\n };\n render();\n\n const onClick = (ev) => {\n const card = ev.target.closest?.('.twm-gallery-card');\n if (!card || !hostEl.contains(card)) return;\n const idx = Number(card.dataset.idx);\n const next = catalog[idx];\n if (!next || next === selected) return;\n selected = next;\n render();\n try { onChange(selected); } catch (err) {\n console.warn('[gallery-picker] onChange threw', err);\n }\n };\n hostEl.addEventListener('click', onClick);\n\n // Fire the initial selection so the caller can prime any\n // downstream UI (preview pane, defaults, etc.) without a\n // special case for first-render.\n try { onChange(selected); } catch (err) {\n console.warn('[gallery-picker] initial onChange threw', err);\n }\n\n return {\n getSelected: () => (selected ? { ...selected } : null),\n setSelectedById: (id) => {\n const next = catalog.find((e) => e?.id === id);\n if (!next || next === selected) return false;\n selected = next;\n render();\n try { onChange(selected); } catch (err) {\n console.warn('[gallery-picker] onChange threw', err);\n }\n return true;\n },\n dispose: () => {\n hostEl.removeEventListener('click', onClick);\n hostEl.innerHTML = '';\n hostEl.classList.remove('twm-gallery-picker');\n },\n };\n}\n", "/**\n * NotificationHistory - Bottom bar notification history panel\n *\n * Bell icon in the global-bottom-bar that opens a popover listing past notifications.\n * Reads from NotificationCenter.history and follows it through\n * `notificationCenter.subscribe()` (0.17.3): every entry the centre records \u2014 a\n * toast from `show()`/`warn()`/... or from the bus \u2014 is one unread, until the\n * popover is opened. The bus is not watched for toasts.\n *\n * THREE OPTIONS, all additive (FlexDesk STORY-0020); without them it is the bell\n * it always was:\n *\n * mountPoint the element the bell is appended to. Without it, the hard-coded\n * `.twm-global-bottom-bar .twm-bar-right`, which only FlexDesk's own\n * bottom bar has.\n * alertLog an alert log (`alert_log.js`). The badge is then the log's unread\n * count, in the worst unread level's colour, and nothing when all is\n * read \u2014 not a delta of a toast history the user may never have\n * opened. A click opens the bottom panel's Alerts tab instead of the\n * popover, and the toasts' \"+N more\" (`notification:summary`) does too.\n * alertsTab the tab a click asks for, `bottompanel:show { tab }`; 'alerts'.\n * onOpen a click, instead of the bus event \u2014 for an embedder with no bus,\n * or whose panel must be opened before a tab can be chosen.\n */\n\nexport class NotificationHistory {\n constructor({ notificationCenter, eventBus, logger, mountPoint = null, alertLog = null,\n alertsTab = 'alerts', onOpen = null } = {}) {\n this.notificationCenter = notificationCenter;\n this.eventBus = eventBus || null;\n this.logger = logger || console;\n this.mountPoint = mountPoint;\n this.alertLog = alertLog;\n this.alertsTab = alertsTab;\n this.onOpen = typeof onOpen === 'function' ? onOpen : null;\n\n this.triggerEl = null;\n this.badgeEl = null;\n /** Entries recorded since the popover was last opened. */\n this.unreadCount = 0;\n this._popoverCleanup = null;\n this._subscriptions = [];\n }\n\n mount() {\n const barRight = this.mountPoint\n || document.querySelector('.twm-global-bottom-bar .twm-bar-right');\n if (!barRight) {\n this.logger.warn?.('[NotificationHistory] .bar-right not found');\n return;\n }\n\n // Build trigger button\n this.triggerEl = document.createElement('button');\n this.triggerEl.className = 'twm-notification-history__trigger twm-has-tooltip';\n this.triggerEl.setAttribute('data-tooltip', 'Notification history');\n this.triggerEl.setAttribute('aria-label', 'Notification history');\n this.triggerEl.innerHTML =\n '<span class=\"material-symbols-outlined\">notifications</span>' +\n '<span class=\"twm-notification-history__badge\" style=\"display:none\">0</span>';\n\n this.badgeEl = this.triggerEl.querySelector('.twm-notification-history__badge');\n\n // Park the bell as the LAST child of .bar-right so it always\n // sits at the far-right edge of the status bar \u2014 past the\n // tick readout, streaming dot, and anything else that the\n // global actions cluster mounts before it.\n barRight.appendChild(this.triggerEl);\n\n this.triggerEl.addEventListener('click', (e) => {\n e.stopPropagation();\n if (this.alertLog) this.#openAlerts();\n else this.#togglePanel();\n });\n\n if (this.alertLog) {\n this.triggerEl.setAttribute('data-tooltip', 'Alerts');\n this.triggerEl.setAttribute('aria-label', 'Alerts');\n this._subscriptions.push(this.alertLog.subscribe(() => this.#updateBadge()));\n const summary = this.eventBus?.on?.('notification:summary', () => this.#openAlerts());\n if (summary) this._subscriptions.push(() => summary.dispose?.());\n this.#updateBadge();\n return;\n }\n\n // What is in the history at mount is not unread.\n this.unreadCount = 0;\n const unsubscribe = this.notificationCenter?.subscribe?.(() => {\n this.unreadCount += 1;\n this.#updateBadge();\n });\n if (typeof unsubscribe === 'function') this._subscriptions.push(unsubscribe);\n this.#updateBadge();\n }\n\n unmount() {\n this.#closePanel();\n this._subscriptions.forEach(unsub => {\n if (typeof unsub === 'function') unsub();\n });\n this._subscriptions = [];\n if (this.triggerEl?.parentNode) {\n this.triggerEl.parentNode.removeChild(this.triggerEl);\n }\n this.triggerEl = null;\n this.badgeEl = null;\n }\n\n /** The Alerts tab, asked for on the bus \u2014 or the embedder's own verb. */\n #openAlerts() {\n if (this.onOpen) {\n try { this.onOpen(); } catch (err) { this.logger.warn?.('[NotificationHistory] onOpen failed', err); }\n return;\n }\n this.eventBus?.emit?.('bottompanel:show', { tab: this.alertsTab });\n }\n\n #updateBadge() {\n const historyLen = this.notificationCenter?.history?.length ?? 0;\n const unread = this.alertLog\n ? this.alertLog.unreadCount()\n : Math.min(this.unreadCount, historyLen);\n\n if (!this.badgeEl) return;\n\n if (this.alertLog) {\n const level = unread > 0 ? this.alertLog.worstUnread() : null;\n this.badgeEl.className = 'twm-notification-history__badge'\n + (level ? ` twm-notification-history__badge--${level}` : '');\n this.triggerEl?.classList.toggle('twm-notification-history__trigger--unread', unread > 0);\n }\n\n if (unread > 0) {\n this.badgeEl.textContent = unread > 99 ? '99+' : String(unread);\n this.badgeEl.style.display = '';\n } else {\n this.badgeEl.style.display = 'none';\n }\n }\n\n #togglePanel() {\n if (this._popoverCleanup) {\n this.#closePanel();\n } else {\n this.#openPanel();\n }\n }\n\n #closePanel() {\n if (typeof this._popoverCleanup === 'function') {\n try { this._popoverCleanup(); } catch (_) { /* ignore */ }\n this._popoverCleanup = null;\n }\n }\n\n #openPanel() {\n this.#closePanel();\n\n // Mark all as seen\n this.unreadCount = 0;\n this.#updateBadge();\n\n const panel = document.createElement('div');\n panel.className = 'twm-notification-history__panel';\n\n // Header\n const header = document.createElement('div');\n header.className = 'twm-notification-history__header';\n header.innerHTML =\n '<span class=\"twm-notification-history__title\">Notifications</span>' +\n '<button class=\"twm-notification-history__clear-btn twm-has-tooltip\" data-tooltip=\"Clear all\" aria-label=\"Clear all\">' +\n '<span class=\"material-symbols-outlined\">delete_sweep</span>' +\n '</button>' +\n '<button class=\"twm-notification-history__close-btn twm-has-tooltip\" data-tooltip=\"Close\" aria-label=\"Close\">' +\n '<span class=\"material-symbols-outlined\">close</span>' +\n '</button>';\n panel.appendChild(header);\n\n // List\n const list = document.createElement('div');\n list.className = 'twm-notification-history__list';\n panel.appendChild(list);\n\n this.#renderList(list);\n\n // Wire header buttons\n header.querySelector('.twm-notification-history__close-btn')\n .addEventListener('click', () => this.#closePanel());\n\n header.querySelector('.twm-notification-history__clear-btn')\n .addEventListener('click', () => {\n this.notificationCenter.history.splice(0);\n this.unreadCount = 0;\n this.#updateBadge();\n this.#renderList(list);\n });\n\n // Position and attach\n document.body.appendChild(panel);\n this.#positionPanel(panel);\n\n // Popover lifecycle (same pattern as ValidationStatus)\n const cleanup = () => {\n document.removeEventListener('mousedown', onDocDown, true);\n document.removeEventListener('keydown', onKey, true);\n window.removeEventListener('resize', onResize, true);\n try { panel.remove(); } catch (_) { /* ignore */ }\n this._popoverCleanup = null;\n };\n this._popoverCleanup = cleanup;\n\n const onDocDown = (ev) => {\n if (!panel.contains(ev.target) && !this.triggerEl.contains(ev.target)) cleanup();\n };\n const onKey = (ev) => { if (ev.key === 'Escape') cleanup(); };\n const onResize = () => cleanup();\n\n document.addEventListener('mousedown', onDocDown, true);\n document.addEventListener('keydown', onKey, true);\n window.addEventListener('resize', onResize, true);\n }\n\n #renderList(listEl) {\n listEl.innerHTML = '';\n const history = this.notificationCenter?.history ?? [];\n\n if (history.length === 0) {\n const empty = document.createElement('div');\n empty.className = 'twm-notification-history__empty';\n empty.textContent = 'No notifications';\n listEl.appendChild(empty);\n return;\n }\n\n // Reverse chronological\n const fragment = document.createDocumentFragment();\n for (let i = history.length - 1; i >= 0; i--) {\n const entry = history[i];\n const item = document.createElement('div');\n const severity = entry.severity || 'info';\n item.className = `twm-notification-history__item twm-notification-history__item--${severity}`;\n\n const itemHeader = document.createElement('div');\n itemHeader.className = 'twm-notification-history__item-header';\n\n if (entry.title) {\n const titleEl = document.createElement('span');\n titleEl.className = 'twm-notification-history__item-title';\n titleEl.textContent = entry.title;\n itemHeader.appendChild(titleEl);\n }\n\n const timeEl = document.createElement('span');\n timeEl.className = 'twm-notification-history__item-time';\n timeEl.textContent = this.#formatTime(entry.timestamp);\n itemHeader.appendChild(timeEl);\n\n item.appendChild(itemHeader);\n\n const body = document.createElement('div');\n body.className = 'twm-notification-history__item-body';\n body.textContent = entry.message || '';\n item.appendChild(body);\n\n fragment.appendChild(item);\n }\n listEl.appendChild(fragment);\n }\n\n #positionPanel(panel) {\n if (!this.triggerEl) return;\n\n const triggerRect = this.triggerEl.getBoundingClientRect();\n const panelWidth = panel.getBoundingClientRect().width;\n const gap = 8;\n\n let left = triggerRect.right - panelWidth;\n\n // Clamp horizontally to the viewport.\n const vw = window.innerWidth;\n left = Math.max(8, Math.min(left, vw - panelWidth - 8));\n\n // Anchor by the panel's BOTTOM edge, pinned just above the bell.\n // Anchoring by `top` leaves the box floating when its content shrinks\n // (notifications cleared/removed): the top stays put while the bottom\n // lifts away from the bell, stranding the panel in mid-air. Pinning\n // the bottom keeps it glued to the bottom bar and lets it grow/shrink\n // upward \u2014 no repositioning needed on re-render.\n const bottom = window.innerHeight - (triggerRect.top - gap);\n\n // Never let the panel run off the top of the viewport: cap its height\n // to the space above the bell (within the design max). The list\n // scrolls within whatever remains.\n const available = triggerRect.top - gap - 8;\n panel.style.maxHeight = `${Math.max(0, Math.min(420, Math.round(available)))}px`;\n\n panel.style.left = `${Math.round(left)}px`;\n panel.style.bottom = `${Math.round(bottom)}px`;\n panel.style.top = 'auto';\n }\n\n #formatTime(timestamp) {\n if (!timestamp) return '';\n const d = new Date(timestamp);\n return d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' });\n }\n}\n", "/**\n * record_list.js \u2014 A READ-ONLY LIST OF RECORDS, each drawn as two lines: a\n * name, and under it a quiet line of facts; beside them pills and verbs.\n * (0.7.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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 ETL loader [paused] Resume Revoke \u2502\n * \u2502 tblk_8f2 \u2014 acts with the account \u2014 last used 5 Oct \u2502\n * \u2502 Resume: This key is revoked, and revoking cannot be undone. \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 * It is the shape an administration screen reaches for when a table would\n * be wrong: few records, each with its own verbs, read top to bottom rather\n * than sorted and filtered. Before this component every consumer built it by\n * hand, row by row, and each copy grew its own post-build loop to put a key\n * or a state on the row afterwards. Here the record's key, its classes and\n * its attributes are declared, and the list owns the rest.\n *\n * WHAT A RECORD SAYS ABOUT ITSELF (`describe(record, idx)`, or the record\n * itself when there is no `describe`):\n *\n * {\n * name: 'ETL loader' | Node, the first line\n * mono: true, the name in the monospace face\n * facts: ['tblk_8f2', null, 'last used 5 Oct'] | 'text' | Node,\n * the quiet line; null/'' parts\n * are left out, the rest joined\n * with `factSeparator`\n * pills: ['paused', {text: 'URL', tone: 'danger', title: '\u2026'}],\n * verbs: [{label: 'Resume', onClick(record, ev), refusal: '\u2026' | null,\n * danger, primary, icon, title, name}],\n * state: 'paused' | 'off' | 'dead' | 'error' | 'active' | any word \u2014\n * `data-state` and `twm-record--state-<word>` on the row,\n * error: 'The last delivery failed: 503' | Node, a line in the error colour\n * key: 'k-1', overrides `getKey`\n * }\n *\n * A REFUSED VERB IS A DISABLED BUTTON AND A SENTENCE ON THE SCREEN. The\n * reason is on the button's `title` and `data-refusal` too, but a reason only\n * on a tooltip reads as \"the button does nothing\" \u2014 nobody hovers a button\n * they believe they have just pressed. So each distinct reason is a line of\n * its own under the facts, named by the verbs it refuses\n * (`data-refusal-for`), and the button is `aria-describedby` that line.\n *\n * OPENING A RECORD (`onActivate`) follows DataTable's `onRowActivate` rule,\n * from the same module (`row_activation.js`): a press on a control in the\n * row is that control's, a click that ends a drag selecting text opens\n * nothing, and neither does the second click of a double-click.\n *\n * THE KEYBOARD. With `onActivate` (or `keyboard: true`) the RECORDS are one\n * tab stop \u2014 the one last focused, else the open one, else the first \u2014 and\n * each enabled verb keeps its own, so every verb is reachable by Tab.\n * ArrowUp/ArrowDown move between records (from a record or from one of its\n * verbs), Home/End go to the ends, and Enter on a record opens it. Enter on a\n * verb is the verb's.\n */\nimport { isRowActivation, isRowControl } from './row_activation.js';\n\n/** A field, a select or editable text keeps its own arrow keys. */\nconst OWN_ARROWS = 'input, select, textarea, [contenteditable=\"\"], [contenteditable=\"true\"]';\n\n/** The words a tone may be, after sanitising (`[^\\w-]` dropped). */\nconst safeWord = (s) => String(s).replace(/[^\\w-]/g, '');\n\nlet SEQ = 0;\n\n/**\n * @typedef {Object} RecordVerb\n * @property {string} label - The button's words.\n * @property {Function} [onClick] - `(record, ev) => void`.\n * @property {string|null} [refusal] - Why it cannot be pressed. A disabled\n * button, and the sentence drawn under the record's facts.\n * @property {boolean} [danger]\n * @property {boolean} [primary]\n * @property {string} [icon] - A Material Symbols name, drawn before the label.\n * @property {string} [title] - A tooltip, for a verb that is NOT refused.\n * @property {string} [name] - A stable id: `data-verb`, and what focus is\n * restored to after a redraw. Defaults to the label.\n */\n\n/**\n * @typedef {Object} RecordListConfig\n * @property {Array} [records=[]]\n * @property {Function} [describe] - `(record, idx) => spec`. Without it the\n * record is its own spec.\n * @property {Function} [getKey] - `(record, idx) => string|number`. Defaults to\n * `spec.key`, then `record.key`, then `record.id`, then the index.\n * @property {Function} [onActivate] - `(record, idx, ev) => void`. Opens a record.\n * @property {string|string[]} [activateOn=['click','enter']] - `'click'`,\n * `'dblclick'`, `'enter'`, or several.\n * @property {boolean} [keyboard] - Arrow keys between records. Defaults to on\n * exactly when `onActivate` is set.\n * @property {*} [activeKey] - The record that is open: `twm-record--active`\n * and `aria-current=\"true\"`.\n * @property {Function} [rowClass] - `(record, idx) => string|string[]|null`.\n * @property {Function} [rowAttrs] - `(record, idx) => {name: value}`;\n * `null`/`false` leaves one off, `true` sets it empty.\n * @property {string|Node|Function} [emptyState] - Shown when there are no\n * records. A function is called with no arguments and may return either.\n * @property {string} [factSeparator=' \u2014 ']\n * @property {'wrap'|'ellipsis'} [facts='wrap'] - How a long fact line ends.\n * `'ellipsis'` keeps it to one line and puts the whole line on `title`.\n * @property {string|Function} [verbClass] - The verbs' class names, or\n * `(verb) => string`, for a consumer with its own buttons. Defaults to\n * FlexDesk's `twm-btn` with `--primary`/`--danger`.\n * @property {string} [label] - The list's accessible name (`aria-label`).\n * @property {string} [className] - Added to the root.\n */\n\nexport class RecordList {\n /**\n * @param {HTMLElement|null} host appended to, if given\n * @param {RecordListConfig} [config]\n */\n constructor(host, config = {}) {\n this.config = {\n records: [],\n describe: null,\n getKey: null,\n onActivate: null,\n activateOn: ['click', 'enter'],\n keyboard: undefined,\n activeKey: null,\n rowClass: null,\n rowAttrs: null,\n emptyState: null,\n factSeparator: ' \u2014 ',\n facts: 'wrap',\n verbClass: null,\n label: null,\n className: null,\n ...config,\n };\n this._records = Array.isArray(this.config.records) ? this.config.records.slice() : [];\n this._activeKey = this.config.activeKey ?? null;\n this._tabKey = null;\n this._items = new Map(); // key \u2192 <li>\n this._disposed = false;\n this._id = `twm-record-list-${++SEQ}`;\n\n const root = document.createElement('div');\n root.className = 'twm-record-list'\n + (this.config.facts === 'ellipsis' ? ' twm-record-list--clip' : '')\n + (this._activates() ? ' twm-record-list--clickable' : '')\n + (this.config.className ? ` ${this.config.className}` : '');\n const list = document.createElement('ul');\n list.className = 'twm-record-list__items';\n if (this.config.label) list.setAttribute('aria-label', this.config.label);\n root.appendChild(list);\n this.element = root;\n this.listElement = list;\n\n this._onClick = (ev) => this._gesture(ev, 'click');\n this._onDblClick = (ev) => this._gesture(ev, 'dblclick');\n this._onKeyDown = (ev) => this._key(ev);\n // Only focus ON a record moves the tab stop. Focus on one of its verbs\n // must not: Tab walks forward through the verbs of the records before\n // the stop, and moving the stop behind the focus would leave no record\n // ahead to Tab to (measured in Edge).\n this._onFocusIn = (ev) => {\n const li = this._itemOf(ev.target);\n if (li && ev.target === li) this._setTabStop(li.__recordKey);\n };\n list.addEventListener('click', this._onClick);\n list.addEventListener('dblclick', this._onDblClick);\n list.addEventListener('keydown', this._onKeyDown);\n list.addEventListener('focusin', this._onFocusIn);\n\n this._draw();\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 records and draw them. Focus inside the list is kept on\n * the same record, and on the same verb of it, when it is still there. */\n setRecords(records) {\n if (this._disposed) return;\n this._records = Array.isArray(records) ? records.slice() : [];\n this._draw();\n }\n\n /** The records, as last given. */\n getRecords() {\n return this._records.slice();\n }\n\n /** Draw ONE record again (`describe` asked afresh), or every one with no key. */\n refresh(key) {\n if (this._disposed) return;\n if (key === undefined) { this._draw(); return; }\n const old = this._items.get(this._norm(key));\n if (!old) return;\n const idx = old.__recordIndex;\n const focus = this._focusMemo();\n const fresh = this._item(this._records[idx], idx);\n old.replaceWith(fresh);\n this._items.set(fresh.__recordKey, fresh);\n this._paintTabStop();\n this._restoreFocus(focus);\n }\n\n /** Mark the record that is open (`null` for none). */\n setActiveKey(key) {\n this._activeKey = key ?? null;\n for (const li of this._items.values()) this._paintActive(li);\n if (this._activeKey !== null && this._items.has(this._norm(this._activeKey))) {\n this._setTabStop(this._norm(this._activeKey));\n }\n }\n\n getActiveKey() {\n return this._activeKey;\n }\n\n /** The `<li>` drawn for a key, or null. */\n getItem(key) {\n return this._items.get(this._norm(key)) || null;\n }\n\n /** Move the keyboard focus to a record. */\n focusRecord(key) {\n const li = this.getItem(key);\n if (!li) return false;\n this._setTabStop(li.__recordKey);\n li.focus();\n return true;\n }\n\n dispose() {\n if (this._disposed) return;\n this._disposed = true;\n const list = this.listElement;\n list.removeEventListener('click', this._onClick);\n list.removeEventListener('dblclick', this._onDblClick);\n list.removeEventListener('keydown', this._onKeyDown);\n list.removeEventListener('focusin', this._onFocusIn);\n this._items.clear();\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 _activates() {\n return typeof this.config.onActivate === 'function';\n }\n\n _keyboard() {\n return this.config.keyboard ?? this._activates();\n }\n\n _gestures() {\n const g = this.config.activateOn;\n return new Set(Array.isArray(g) ? g : [g]);\n }\n\n /** Keys compare as strings: a record keyed `7` and an `activeKey` of `'7'` are one. */\n _norm(key) {\n return key === null || key === undefined ? key : String(key);\n }\n\n _spec(record, idx) {\n const { describe } = this.config;\n const spec = typeof describe === 'function' ? describe(record, idx) : record;\n return spec && typeof spec === 'object' ? spec : { name: spec };\n }\n\n _keyOf(record, idx, spec) {\n const { getKey } = this.config;\n let key;\n if (spec.key !== undefined && spec.key !== null) key = spec.key;\n else if (typeof getKey === 'function') key = getKey(record, idx);\n else if (record && typeof record === 'object' && (record.key ?? record.id) != null) key = record.key ?? record.id;\n else key = idx;\n return String(key);\n }\n\n _draw() {\n const focus = this._focusMemo();\n const list = this.listElement;\n list.replaceChildren();\n this._items.clear();\n this.element.querySelector(':scope > .twm-record-list__empty')?.remove();\n\n this._records.forEach((record, idx) => {\n const li = this._item(record, idx);\n if (this._items.has(li.__recordKey)) {\n console.error(`[RecordList] two records share the key \"${li.__recordKey}\"`);\n }\n this._items.set(li.__recordKey, li);\n list.appendChild(li);\n });\n this.element.classList.toggle('twm-record-list--empty', this._records.length === 0);\n if (!this._records.length) this._drawEmpty();\n this._paintTabStop();\n this._restoreFocus(focus);\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-record-list__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 _item(record, idx) {\n const spec = this._spec(record, idx);\n const key = this._keyOf(record, idx, spec);\n const li = document.createElement('li');\n li.className = 'twm-record';\n li.__record = record;\n li.__recordIndex = idx;\n li.__recordKey = key;\n li.dataset.recordKey = key;\n if (this._keyboard()) li.tabIndex = -1;\n if (spec.state) {\n li.dataset.state = safeWord(spec.state);\n li.classList.add(`twm-record--state-${safeWord(spec.state)}`);\n }\n\n const main = document.createElement('div');\n main.className = 'twm-record__main';\n const name = document.createElement('div');\n name.className = 'twm-record__name' + (spec.mono ? ' twm-record__name--mono' : '');\n appendContent(name, spec.name);\n main.appendChild(name);\n\n const factsText = this._facts(spec.facts);\n if (factsText !== null) {\n const facts = document.createElement('div');\n facts.className = 'twm-record__facts';\n appendContent(facts, factsText);\n if (this.config.facts === 'ellipsis') facts.title = facts.textContent;\n main.appendChild(facts);\n }\n if (spec.error != null && spec.error !== false && spec.error !== '') {\n const err = document.createElement('div');\n err.className = 'twm-record__error';\n appendContent(err, spec.error);\n main.appendChild(err);\n }\n li.appendChild(main);\n\n const pills = (spec.pills || []).filter((p) => p != null && p !== false && p !== '');\n if (pills.length) {\n const box = document.createElement('div');\n box.className = 'twm-record__pills';\n for (const p of pills) box.appendChild(pill(p));\n li.appendChild(box);\n }\n\n const verbs = (spec.verbs || []).filter(Boolean);\n if (verbs.length) {\n const box = document.createElement('div');\n box.className = 'twm-record__verbs';\n const reasons = new Map(); // sentence \u2192 [labels]\n for (const v of verbs) {\n const b = this._verb(v, record);\n box.appendChild(b);\n if (v.refusal) {\n const said = String(v.refusal);\n if (!reasons.has(said)) reasons.set(said, { labels: [], buttons: [] });\n reasons.get(said).labels.push(v.label);\n reasons.get(said).buttons.push(b);\n }\n }\n li.appendChild(box);\n if (reasons.size) {\n const lines = document.createElement('div');\n lines.className = 'twm-record__refusals';\n let n = 0;\n for (const [said, { labels, buttons }] of reasons) {\n const line = document.createElement('div');\n line.className = 'twm-record__refusal';\n line.id = `${this._id}-r${idx}-${n++}`;\n line.dataset.refusalFor = labels.join(', ');\n line.textContent = labels.length === verbs.length && verbs.length > 1\n ? said : `${labels.join(', ')}: ${said}`;\n for (const b of buttons) b.setAttribute('aria-describedby', line.id);\n lines.appendChild(line);\n }\n main.appendChild(lines);\n }\n }\n\n this._decorate(li, record, idx);\n return li;\n }\n\n _facts(facts) {\n if (facts == null || facts === false) return null;\n if (typeof Node !== 'undefined' && facts instanceof Node) return facts;\n if (!Array.isArray(facts)) {\n const s = String(facts);\n return s === '' ? null : s;\n }\n const parts = facts.filter((f) => f != null && f !== false && f !== '');\n if (!parts.length) return null;\n if (parts.every((p) => !(typeof Node !== 'undefined' && p instanceof Node))) {\n return parts.map(String).join(this.config.factSeparator);\n }\n const frag = document.createDocumentFragment();\n parts.forEach((p, i) => {\n if (i) frag.appendChild(document.createTextNode(this.config.factSeparator));\n appendContent(frag, p);\n });\n return frag;\n }\n\n _verb(v, record) {\n const b = document.createElement('button');\n b.type = 'button';\n const { verbClass } = this.config;\n b.className = typeof verbClass === 'function' ? String(verbClass(v) || '')\n : typeof verbClass === 'string' ? verbClass\n : 'twm-btn' + (v.primary ? ' twm-btn--primary' : '') + (v.danger ? ' twm-btn--danger' : '');\n b.classList.add('twm-record__verb');\n b.dataset.verb = String(v.name ?? v.label);\n if (v.icon) {\n const glyph = document.createElement('span');\n glyph.className = 'material-symbols-outlined twm-record__verb-icon';\n glyph.setAttribute('aria-hidden', 'true');\n glyph.textContent = String(v.icon);\n b.appendChild(glyph);\n }\n const label = document.createElement('span');\n label.className = 'twm-record__verb-label';\n label.textContent = String(v.label ?? '');\n b.appendChild(label);\n if (v.refusal) {\n b.disabled = true;\n b.title = String(v.refusal);\n b.dataset.refusal = String(v.refusal);\n } else {\n if (v.title) b.title = String(v.title);\n if (typeof v.onClick === 'function') b.addEventListener('click', (ev) => v.onClick(record, ev));\n }\n return b;\n }\n\n _decorate(li, record, idx) {\n const { rowClass, rowAttrs } = this.config;\n if (typeof rowClass === 'function') {\n const c = rowClass(record, idx);\n const list = Array.isArray(c) ? c : String(c ?? '').split(/\\s+/);\n for (const name of list) if (name) li.classList.add(String(name));\n }\n if (typeof rowAttrs === 'function') {\n for (const [name, value] of Object.entries(rowAttrs(record, idx) || {})) {\n if (value == null || value === false) continue;\n try {\n li.setAttribute(name, value === true ? '' : String(value));\n } catch (err) {\n console.error(`[RecordList] rowAttrs: bad attribute \"${name}\"`, err);\n }\n }\n }\n this._paintActive(li);\n }\n\n _paintActive(li) {\n const on = this._activeKey !== null && li.__recordKey === this._norm(this._activeKey);\n li.classList.toggle('twm-record--active', on);\n if (on) {\n if (li.getAttribute('aria-current') !== 'true') {\n li.setAttribute('aria-current', 'true');\n li.__twmAriaCurrent = true;\n }\n } else if (li.__twmAriaCurrent) {\n li.__twmAriaCurrent = false;\n li.removeAttribute('aria-current');\n }\n }\n\n // \u2500\u2500 focus \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 ONE record that takes Tab: the one last focused, else the open\n * one, else the first. */\n _paintTabStop() {\n if (!this._keyboard()) return;\n let key = this._tabKey;\n if (key === null || !this._items.has(key)) {\n const active = this._norm(this._activeKey);\n key = active !== null && this._items.has(active) ? active : (this._items.keys().next().value ?? null);\n }\n this._setTabStop(key);\n }\n\n _setTabStop(key) {\n if (!this._keyboard()) return;\n this._tabKey = key ?? null;\n for (const [k, li] of this._items) li.tabIndex = k === this._tabKey ? 0 : -1;\n }\n\n _focusMemo() {\n const doc = this.element.ownerDocument;\n const active = doc?.activeElement;\n if (!active || !this.listElement.contains(active)) return null;\n const li = this._itemOf(active);\n if (!li) return null;\n return { key: li.__recordKey, verb: active.closest('.twm-record__verb')?.dataset.verb ?? null };\n }\n\n _restoreFocus(memo) {\n if (!memo) return;\n const li = this._items.get(memo.key);\n if (!li) return;\n if (memo.verb !== null) {\n const b = [...li.querySelectorAll('.twm-record__verb')].find((x) => x.dataset.verb === memo.verb);\n if (b && !b.disabled) { b.focus(); return; }\n }\n if (this._keyboard()) { this._setTabStop(li.__recordKey); li.focus(); }\n }\n\n _itemOf(target) {\n const li = target?.closest?.('.twm-record');\n return li && this.listElement.contains(li) && li.parentNode === this.listElement ? li : null;\n }\n\n // \u2500\u2500 gestures \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 _gesture(ev, gesture) {\n if (!this._activates() || !this._gestures().has(gesture)) return;\n const li = this._itemOf(ev.target);\n if (!li) return;\n if (!isRowActivation(ev, gesture, { scope: this.listElement })) return;\n this.config.onActivate(li.__record, li.__recordIndex, ev);\n }\n\n _key(ev) {\n if (ev.defaultPrevented) return;\n const li = this._itemOf(ev.target);\n if (!li) return;\n if (ev.key === 'Enter') {\n // Enter on a verb is the verb's; only Enter on the record itself opens it.\n if (ev.target !== li || !this._activates() || !this._gestures().has('enter')) return;\n if (ev.altKey || ev.ctrlKey || ev.metaKey || ev.shiftKey) return;\n ev.preventDefault();\n this.config.onActivate(li.__record, li.__recordIndex, ev);\n return;\n }\n if (!this._keyboard()) return;\n if (ev.target !== li && (ev.target.closest(OWN_ARROWS) || !isRowControl(ev.target, li))) return;\n const items = [...this._items.values()];\n const at = items.indexOf(li);\n let next = null;\n if (ev.key === 'ArrowDown') next = items[Math.min(items.length - 1, at + 1)];\n else if (ev.key === 'ArrowUp') next = items[Math.max(0, at - 1)];\n else if (ev.key === 'Home') next = items[0];\n else if (ev.key === 'End') next = items[items.length - 1];\n else return;\n ev.preventDefault();\n if (next) {\n this._setTabStop(next.__recordKey);\n next.focus();\n }\n }\n}\n\n/**\n * Build a record list, append it to `host` (if given) and draw it.\n *\n * @param {HTMLElement|null} host\n * @param {RecordListConfig} [config]\n * @returns {RecordList}\n */\nexport function createRecordList(host, config = {}) {\n return new RecordList(host, config);\n}\n\n/** One pill: a string, or `{text, tone, title}`. A tone is a word\n * (`muted`, `info`, `success`, `warn`, `danger` are drawn). */\nfunction pill(p) {\n const s = typeof p === 'object' && !(typeof Node !== 'undefined' && p instanceof Node) ? p : { text: p };\n const span = document.createElement('span');\n span.className = 'twm-record__pill' + (s.tone ? ` twm-record__pill--${safeWord(s.tone)}` : '');\n if (typeof Node !== 'undefined' && s.text instanceof Node) span.appendChild(s.text);\n else if (typeof Node !== 'undefined' && p instanceof Node) span.appendChild(p);\n else span.textContent = String(s.text ?? '');\n if (s.title) span.title = String(s.title);\n if (s.tone) span.dataset.tone = safeWord(s.tone);\n return span;\n}\n\n/** Text, a node or nothing, into `el`. */\nfunction appendContent(el, content) {\n if (content == null || content === false) return;\n if (typeof Node !== 'undefined' && content instanceof Node) el.appendChild(content);\n else el.appendChild(document.createTextNode(String(content)));\n}\n", "/**\n * \u2550\u2550 A STACK OF COLLAPSIBLE SECTIONS \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\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 * Inspector-style panel content: titled sections, one above the other, each\n * opened and closed from its header (FlexDesk STORY-0036). Until this, only a\n * tree's categories could collapse, and every embedder that wanted a panel of\n * \"Notes / Assistant / Parameters\" built the headers, the arrows and the\n * remembering itself.\n *\n * const stack = createSectionStack(panel, {\n * sections: [\n * { id: 'notes', title: 'Notes', content: notesEl },\n * { id: 'chat', title: 'Assistant', fill: true,\n * actions: [{ id: 'clear', icon: 'delete', label: 'Clear', onClick: clear }] },\n * { id: 'params', title: 'Parameters', defaultExpanded: false },\n * ],\n * key: 'inspector.sections',\n * stateStore: { read: (key) => saved[key], write: (key, map) => { saved[key] = map; } },\n * });\n * stack.body('chat').appendChild(chatEl);\n * const off = stack.on('toggled', ({ id, expanded }) => \u2026);\n *\n * A SECTION is `{ id, title, icon?, content?, actions?, defaultExpanded?, fill? }`.\n * `content` is a Node put into the section's body at mount; `body(id)` hands\n * the same element over for anything mounted later. `defaultExpanded` is true\n * unless it says otherwise.\n *\n * THE HEADER TOGGLES; ITS ACTIONS DO NOT. A click anywhere on the header opens\n * or closes the section and turns its arrow \u2014 except on one of its `actions`\n * (`{ id?, icon, label, title?, onClick(sectionId, event) }`), which runs its\n * own `onClick` and leaves the section as it was.\n *\n * A FILL SECTION (`fill: true`) takes the height the others leave, and its\n * body scrolls inside it (`min-height: 0`), so a long conversation scrolls in\n * its section instead of growing the panel past the window. Give the stack's\n * container a height \u2014 it is `height: 100%` of it.\n *\n * REMEMBERING is the embedder's: `stateStore` is `{ read(key), write(key, map) }`\n * and `map` is `{ [sectionId]: expanded }`, written whenever a section opens or\n * closes. `read` may answer a promise; until it does, sections show their\n * `defaultExpanded`, and a section somebody toggled meanwhile keeps their\n * choice. Such a toggle is written once the read has settled, merged over\n * the stored map, so the defaults on screen never overwrite it. A store that throws, rejects, or answers something that is not a map\n * leaves every section on its `defaultExpanded` \u2014 remembering is a convenience,\n * never a reason for a panel not to draw. `ready` resolves once the read has\n * been applied (at once without a store).\n *\n * `setVisible(id, false)` takes a section off the stack without forgetting it:\n * `setVisible(id, true)` brings it back open or closed exactly as it was.\n *\n * The `toggled` event carries `{ id, expanded, source }`, `source` being\n * `'user'` (a header click), `'api'` (expand / collapse / toggle) or\n * `'restore'` (a stored state that arrived after mount). It fires only on a\n * change. `on()` answers the function that stops listening.\n *\n * `dispose()` removes the one listener the stack adds and every node it made;\n * `content` the embedder handed in goes with its section.\n *\n * Styled by `.twm-collapsible-*` (the tree's primitive) plus `.twm-section-stack*`.\n */\n\n/**\n * @param {HTMLElement} container\n * @param {object} opts\n * @param {Array} opts.sections `{ id, title, icon?, content?, actions?, defaultExpanded?, fill? }`\n * @param {object} [opts.stateStore] `{ read(key): map|Promise<map>, write(key, map) }`\n * @param {string} [opts.key] the key the expanded states live under; required with a store\n */\nexport function createSectionStack(container, { sections = [], stateStore = null, key = null } = {}) {\n if (stateStore && !key) throw new Error('createSectionStack: a stateStore needs a { key }');\n const doc = container.ownerDocument;\n\n const root = doc.createElement('div');\n root.className = 'twm-section-stack';\n\n /** id -> { def, box, toggle, arrow, body, expanded, visible, touched } */\n const byId = new Map();\n /** action button -> { sectionId, action } */\n const actionOf = new Map();\n /** header -> section id */\n const headerOf = new Map();\n const listeners = new Set();\n let disposed = false;\n // While a promised read is out, the sections nobody touched still show\n // their defaults, not what the store holds: writing them then would\n // overwrite the stored states with defaults. A toggle meanwhile only marks\n // the map as owed; it is written once the read has settled.\n let readPending = false;\n let writeOwed = false;\n\n for (const def of sections) {\n if (!def || def.id == null || byId.has(def.id)) {\n throw new Error(`createSectionStack: every section needs a unique id (got ${def?.id})`);\n }\n const expanded = def.defaultExpanded !== false;\n\n const box = doc.createElement('section');\n box.className = 'twm-collapsible-box twm-section-stack__section'\n + (def.fill ? ' twm-section-stack__section--fill' : '');\n\n const header = doc.createElement('div');\n header.className = 'twm-collapsible-header twm-section-stack__header';\n\n const toggle = doc.createElement('button');\n toggle.type = 'button';\n toggle.className = 'twm-section-stack__toggle';\n const arrow = doc.createElement('span');\n arrow.className = 'twm-collapsible-arrow material-symbols-outlined';\n arrow.setAttribute('aria-hidden', 'true');\n arrow.textContent = 'expand_more';\n toggle.appendChild(arrow);\n if (def.icon) {\n const icon = doc.createElement('span');\n icon.className = 'twm-section-stack__icon material-symbols-outlined';\n icon.setAttribute('aria-hidden', 'true');\n icon.textContent = def.icon;\n toggle.appendChild(icon);\n }\n const title = doc.createElement('span');\n title.className = 'twm-section-stack__title';\n title.textContent = def.title ?? String(def.id);\n toggle.appendChild(title);\n header.appendChild(toggle);\n\n if (Array.isArray(def.actions) && def.actions.length) {\n const bar = doc.createElement('div');\n bar.className = 'twm-section-stack__actions';\n for (const action of def.actions) {\n const btn = doc.createElement('button');\n btn.type = 'button';\n btn.className = 'twm-section-stack__action';\n if (action.label) btn.setAttribute('aria-label', action.label);\n if (action.title ?? action.label) btn.setAttribute('title', action.title ?? action.label);\n const glyph = doc.createElement('span');\n glyph.className = 'material-symbols-outlined';\n glyph.setAttribute('aria-hidden', 'true');\n glyph.textContent = action.icon ?? '';\n btn.appendChild(glyph);\n bar.appendChild(btn);\n actionOf.set(btn, { sectionId: def.id, action });\n }\n header.appendChild(bar);\n }\n\n const body = doc.createElement('div');\n body.className = 'twm-collapsible-content twm-section-stack__body';\n if (def.content) body.appendChild(def.content);\n\n box.append(header, body);\n root.appendChild(box);\n headerOf.set(header, def.id);\n const entry = { def, box, toggle, arrow, body, expanded, visible: true, touched: false };\n byId.set(def.id, entry);\n paint(entry);\n }\n\n function paint(entry) {\n entry.box.classList.toggle('twm-section-stack__section--expanded', entry.expanded);\n entry.body.classList.toggle('visible', entry.expanded);\n entry.arrow.classList.toggle('collapsed', !entry.expanded);\n entry.toggle.setAttribute('aria-expanded', String(entry.expanded));\n entry.box.hidden = !entry.visible;\n }\n\n function emit(detail) {\n for (const fn of [...listeners]) {\n try { fn(detail); } catch (err) { console.error('[section-stack] toggled listener failed', err); }\n }\n }\n\n function persist() {\n if (!stateStore?.write) return;\n if (readPending) { writeOwed = true; return; }\n const map = {};\n for (const [id, entry] of byId) map[id] = entry.expanded;\n write(map);\n }\n\n function write(map) {\n try {\n const pending = stateStore.write(key, map);\n pending?.catch?.(() => { /* storage refused: not ours to fix */ });\n } catch { /* storage refused: not ours to fix */ }\n }\n\n /** Set one section's state; true when it changed. */\n function set(id, expanded, source) {\n const entry = byId.get(id);\n if (disposed || !entry || entry.expanded === expanded) return false;\n entry.expanded = expanded;\n if (source !== 'restore') entry.touched = true;\n paint(entry);\n if (source !== 'restore') persist();\n emit({ id, expanded, source });\n return true;\n }\n\n const isMap = (saved) => !!saved && typeof saved === 'object' && !Array.isArray(saved);\n\n function restore(saved, source) {\n if (disposed || !isMap(saved)) return;\n for (const [id, entry] of byId) {\n if (entry.touched || typeof saved[id] !== 'boolean') continue;\n if (source === 'restore') set(id, saved[id], 'restore');\n else { entry.expanded = saved[id]; paint(entry); }\n }\n }\n\n /** A promised read has settled (`saved` is null when it rejected). */\n function settle(saved) {\n restore(saved, 'restore');\n readPending = false;\n if (!writeOwed) return;\n writeOwed = false;\n // The touched sections over what the store holds \u2014 also after a\n // dispose, which must not lose a choice made before the read answered.\n const map = {};\n for (const [id, entry] of byId) {\n map[id] = !entry.touched && isMap(saved) && typeof saved[id] === 'boolean'\n ? saved[id] : entry.expanded;\n }\n write(map);\n }\n\n function onClick(event) {\n const target = event.target;\n const btn = target?.closest?.('.twm-section-stack__action');\n if (btn && actionOf.has(btn)) {\n const { sectionId, action } = actionOf.get(btn);\n event.stopPropagation();\n try { action.onClick?.(sectionId, event); } catch (err) {\n console.error(`[section-stack] action on \"${sectionId}\" failed`, err);\n }\n return;\n }\n const header = target?.closest?.('.twm-section-stack__header');\n if (!header || !headerOf.has(header)) return;\n const id = headerOf.get(header);\n set(id, !byId.get(id).expanded, 'user');\n }\n root.addEventListener('click', onClick);\n\n // Synchronous stored state is applied before the stack is on screen, so it\n // never flashes the defaults; a promise is applied when it answers.\n let ready = Promise.resolve();\n if (stateStore?.read) {\n let saved = null;\n try { saved = stateStore.read(key); } catch { saved = null; }\n if (saved && typeof saved.then === 'function') {\n readPending = true;\n ready = Promise.resolve(saved)\n .then((value) => settle(value), () => settle(null));\n } else {\n restore(saved, 'mount');\n }\n }\n\n container.appendChild(root);\n\n const need = (id) => {\n if (!byId.has(id)) throw new Error(`createSectionStack: no section \"${id}\"`);\n return byId.get(id);\n };\n\n return {\n root,\n ready,\n /** The section's body element, for content mounted after the stack. */\n body: (id) => need(id).body,\n expand(id) { need(id); set(id, true, 'api'); },\n collapse(id) { need(id); set(id, false, 'api'); },\n toggle(id) { set(id, !need(id).expanded, 'api'); },\n isExpanded: (id) => need(id).expanded,\n /** Off the stack, or back on it \u2014 its expanded state is kept either way. */\n setVisible(id, visible) {\n const entry = need(id);\n entry.visible = !!visible;\n paint(entry);\n },\n isVisible: (id) => need(id).visible,\n /** `on('toggled', fn)` \u2014 answers the function that stops listening. */\n on(event, fn) {\n if (event !== 'toggled') throw new Error(`createSectionStack: no \"${event}\" event`);\n if (disposed) return () => {};\n listeners.add(fn);\n return () => listeners.delete(fn);\n },\n dispose() {\n if (disposed) return;\n disposed = true;\n root.removeEventListener('click', onClick);\n listeners.clear();\n actionOf.clear();\n headerOf.clear();\n root.remove();\n },\n };\n}\n", "/**\n * SettingsView \u2014 the settings page, drawn from a settings store's schema.\n *\n * const view = new SettingsView({ store, eventBus }); // the bus the store emits on\n * view.mount(host);\n * view.selectCategory('window');\n * view.setQuery('shadow');\n * view.dispose();\n *\n * // or as tile content:\n * createShell({ content: { settings: settingsViewContent({ store, eventBus }) } });\n *\n * `store` is a `createSettingsStore()` handle, or the app-global binding's own\n * (`getSettingsStore()` in `@flexdesk/core`). The view knows no setting: every\n * category, group, label, description and control comes from the store's\n * `getCategories()` and `getSchema()`.\n *\n * THE LAYOUT. A sidebar with a filter box, the categories in their\n * `CategoryDef.order` and *Reset all*; beside it the chosen category's\n * settings under its title, description and *Reset category*, grouped by\n * `SettingDef.group` in schema order. Each row shows its label, a *Modified*\n * marker while its value differs from its default, its description, its path,\n * its control and a reset button. Text typed in the filter searches every\n * category's labels, descriptions and paths, and the matches are listed\n * under their category and group.\n *\n * THE CONTROLS, one per `SettingDef.type`:\n * boolean a ToggleField\n * select a select over `options`\n * number a number box with `min`, `max` and `step`; a value written is\n * snapped to the step (counted from `min`) and clamped to the range,\n * and a box left empty or unreadable goes back to the value\n * text a text box written `textDebounceMs` after the last keystroke,\n * or at once on Enter or blur; emptied, it writes `null` when the\n * default is `null`, else `''`\n * colorList a ColorListField, written on every committed edit while every\n * row holds a colour\n * A type the view does not know shows the value as text, read only.\n *\n * LIVE, BOTH WAYS. A control writes through `store.set()`. The view listens\n * on `eventBus` for `settings:<path>:changed` for every path in the schema,\n * for `settings:changed` with a null path (the resets) and for\n * `settings:registered` (a slice registered after mount: its categories join\n * the sidebar and its settings their category, without a remount). A value\n * changed elsewhere moves its control and its marker. An edit still being\n * typed (a text before its debounce, digits before 'change') is written\n * before the view redraws or syncs its rows, so it is never dropped.\n *\n * RESETS. A row's reset button resets that setting. *Reset category* and\n * *Reset all* ask `confirm(\u2026)` first (default `openConfirm`) and change\n * nothing unless it resolves true.\n *\n * THE SIDEBAR ELSEWHERE (0.17.2). `sidebar: false` leaves the sidebar out:\n * the view is the content alone. A `SettingsCategories` bound to it, mounted\n * anywhere, draws the filter box, the categories and *Reset all* instead:\n *\n * const view = new SettingsView({ store, eventBus, sidebar: false });\n * view.mount(pageHost);\n * const cats = new SettingsCategories({ view });\n * cats.mount(navigatorHost);\n *\n * Both draw from the view's state, so the filter text and the selected\n * category are the same in both, whichever moved them; `view.subscribe(fn)`\n * tells any other listener. *Reset all* there is `view.resetAll()`, so it asks\n * to confirm as before.\n *\n * Every word on screen that comes from the schema, the store or the user is\n * set as text, so a label or a query holding markup is shown as typed.\n *\n * Markup: `.twm-settings` > `.twm-settings__sidebar` (`__search` >\n * `__search-input`, `__nav` > `button.__cat` [`--active`], `__reset-all`)\n * + `.twm-settings__content` (`__header` > `__title`, `__description`,\n * `__reset-category`; `section.__group` > `__group-title` + `.__row`\n * [`--modified`] > `__info` (`__label`, `__marker`, `__description`,\n * `__path`) + `__control` + `__reset`; `__empty`). A `SettingsCategories` is\n * `.twm-settings-categories` > `.twm-settings__search`, `.twm-settings__nav`\n * and `.twm-settings__reset-all`, the same parts as the sidebar's.\n */\n\nimport { ComponentBase } from '../base/component_base.js';\nimport { ToggleField } from './toggle_field.js';\nimport { ColorListField } from './color_list_field.js';\nimport { selectBox, shownValue } from './choice_controls.js';\nimport { openConfirm } from './modal.js';\n\n/** Milliseconds between the last keystroke in a text setting and its write. */\nexport const SETTINGS_TEXT_DEBOUNCE_MS = 300;\n\nfunction el(tag, className, text) {\n const n = document.createElement(tag);\n if (className) n.className = className;\n if (text !== undefined && text !== null) n.textContent = String(text);\n return n;\n}\n\nfunction icon(name) {\n const n = el('span', 'material-symbols-outlined', name);\n n.setAttribute('aria-hidden', 'true');\n return n;\n}\n\nfunction same(a, b) {\n if (a === b) return true;\n if (a == null || b == null) return a == null && b == null;\n if (typeof a !== typeof b || typeof a !== 'object') return false;\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n const ka = Object.keys(a);\n const kb = Object.keys(b);\n return ka.length === kb.length && ka.every((k) => same(a[k], b[k]));\n}\n\n/**\n * A number written by a number row, always both in range and on the step grid\n * (`min + k * step`, or `k * step` with no `min`): snapped to the nearest grid\n * point, and a point outside [min, max] is moved inward to the nearest grid\n * point inside. `min` is itself a grid point, so the range holds none only\n * when `max < min`; the value is then `min`. With no step it is only clamped.\n */\nfunction fitNumber(n, { min, max, step }) {\n const lo = min != null && Number.isFinite(Number(min)) ? Number(min) : null;\n const hi = max != null && Number.isFinite(Number(max)) ? Number(max) : null;\n const s = Number(step);\n if (!(Number.isFinite(s) && s > 0)) {\n let v = n;\n if (hi != null) v = Math.min(hi, v);\n if (lo != null) v = Math.max(lo, v);\n return v;\n }\n const base = lo ?? 0;\n const places = (x) => (String(x).split('.')[1] || '').length;\n const decimals = Math.max(places(s), places(base));\n const at = (k) => Number((base + k * s).toFixed(decimals));\n const EPS = 1e-9;\n let k = Math.round((n - base) / s);\n if (hi != null && at(k) > hi) k = Math.floor((hi - base) / s + EPS);\n if (lo != null && at(k) < lo) k = Math.ceil((lo - base) / s - EPS);\n return at(k);\n}\n\n// \u2500\u2500 the sidebar's parts, drawn alike by SettingsView and SettingsCategories \u2500\u2500\n\n/** The filter box: `{ label, input }`; `onInput(text)` on every keystroke. */\nfunction filterBox(onInput) {\n const label = el('label', 'twm-settings__search');\n const input = el('input', 'twm-settings__search-input');\n input.type = 'search';\n input.placeholder = 'Filter settings\u2026';\n input.autocomplete = 'off';\n input.spellcheck = false;\n input.setAttribute('aria-label', 'Filter settings');\n input.addEventListener('input', () => onInput(input.value));\n label.append(icon('search'), input);\n return { label, input };\n}\n\n/** The category list; `onSelect(id)` when a category is clicked. */\nfunction categoryNav(onSelect) {\n const nav = el('nav', 'twm-settings__nav');\n nav.setAttribute('aria-label', 'Settings categories');\n nav.addEventListener('click', (e) => {\n const btn = e.target.closest?.('[data-category]');\n if (btn && nav.contains(btn)) onSelect(btn.dataset.category);\n });\n return nav;\n}\n\n/** Draw `categories` into `nav`, `active` (an id, or null) marked. */\nfunction paintCategories(nav, categories, active) {\n const buttons = categories.map((cat) => {\n const b = el('button', 'twm-settings__cat');\n b.type = 'button';\n b.dataset.category = cat.id;\n if (cat.id === active) {\n b.classList.add('twm-settings__cat--active');\n b.setAttribute('aria-current', 'page');\n }\n b.append(icon(cat.icon || 'tune'), el('span', 'twm-settings__cat-label', cat.label ?? cat.id));\n if (cat.description) b.title = String(cat.description);\n return b;\n });\n nav.replaceChildren(...buttons);\n}\n\n/** The *Reset all* button; `onClick()` when pressed. */\nfunction resetAllButton(onClick) {\n const b = el('button', 'twm-btn twm-settings__reset-all');\n b.type = 'button';\n b.append(icon('restart_alt'), el('span', '', 'Reset all'));\n b.addEventListener('click', () => { onClick(); });\n return b;\n}\n\nexport class SettingsView extends ComponentBase {\n /**\n * @param {object} o\n * @param {object} o.store a settings store (`createSettingsStore()` / `getSettingsStore()`)\n * @param {object} o.eventBus the bus the store emits on\n * @param {Function} [o.confirm] `({title, message, confirmLabel, danger}) -> Promise<boolean>`\n * @param {string} [o.category] the category shown first (default: the first)\n * @param {number} [o.textDebounceMs]\n * @param {string} [o.title='Settings'] the sidebar heading\n * @param {boolean} [o.sidebar=true] false leaves the sidebar (filter,\n * categories, *Reset all*) out, for a `SettingsCategories` elsewhere\n */\n constructor({\n store, eventBus, confirm = openConfirm, category = null,\n textDebounceMs = SETTINGS_TEXT_DEBOUNCE_MS, title = 'Settings', sidebar = true, logger,\n } = {}) {\n super({ eventBus, logger });\n if (!store || typeof store.getSchema !== 'function') {\n throw new TypeError('SettingsView: `store` must be a settings store');\n }\n if (!eventBus || typeof eventBus.on !== 'function') {\n throw new TypeError('SettingsView: `eventBus` must be the bus the store emits on');\n }\n this.store = store;\n this._confirm = confirm;\n this._category = category;\n this._query = '';\n this._debounceMs = textDebounceMs;\n this._title = title;\n this._sidebar = sidebar !== false;\n /** `fn({ category, query })` after the category, the filter or the categories change. */\n this._listeners = new Set();\n\n this.root = null;\n this._nav = null;\n this._content = null;\n this._search = null;\n /** path -> { sync(), flush(), dispose() } for the rows on screen. */\n this._rows = new Map();\n /** path -> the bus subscription handle, for every schema path. */\n this._pathSubs = new Map();\n /** Bus subscription handles for the whole-store events. */\n this._subs = [];\n this._disposed = false;\n }\n\n /** Build the view into `container` (once). */\n mount(container) {\n if (this.root) return this.root;\n const root = el('div', 'twm-settings');\n if (this._sidebar) {\n const side = el('aside', 'twm-settings__sidebar');\n const head = el('div', 'twm-settings__sidebar-title');\n head.append(icon('settings'), el('span', '', this._title));\n const search = filterBox((text) => this.setQuery(text));\n this._search = search.input;\n this._nav = categoryNav((id) => this.selectCategory(id));\n side.append(head, search.label, this._nav, resetAllButton(() => this.resetAll()));\n root.append(side);\n }\n\n const content = el('div', 'twm-settings__content');\n this._content = content;\n root.append(content);\n this.root = root;\n container.appendChild(root);\n this._mounted = true;\n\n for (const path of Object.keys(this.store.getSchema())) this.#watch(path);\n this._subs.push(this.eventBus.on('settings:changed', (p) => {\n if (p?.path == null) this.#syncAll();\n }));\n this._subs.push(this.eventBus.on('settings:registered', (p) => this.#onRegistered(p)));\n\n this.#paintNav();\n this.#paintContent();\n this.#notify();\n return root;\n }\n\n /** The category on screen (its id), or null. */\n getCategory() { return this.#activeCategory()?.id ?? null; }\n\n /** The filter text. */\n getQuery() { return this._query; }\n\n /** True while the filter is in effect (its trimmed text is not empty). */\n isFiltering() { return this.#searching(); }\n\n /**\n * `fn({ category, query })` after every change of the category, the filter\n * or the registered categories, until the view is disposed. Answers the\n * unsubscribe.\n */\n subscribe(fn) {\n this._listeners.add(fn);\n return () => this._listeners.delete(fn);\n }\n\n /** Show one category; clears the filter. */\n selectCategory(id) {\n if (!this.root) return;\n if (!this.store.getCategories().some((c) => c.id === id)) return;\n this._category = id;\n this._query = '';\n if (this._search) this._search.value = '';\n this.#paintNav();\n this.#paintContent();\n this.#notify();\n }\n\n /** Search every category; an empty query goes back to the category. */\n setQuery(query) {\n if (!this.root) return;\n const q = String(query ?? '');\n this._query = q;\n if (this._search && this._search.value !== q) this._search.value = q;\n this.#paintNav();\n this.#paintContent();\n this.#notify();\n }\n\n /** Reset one category after `confirm`; resolves true when it was reset. */\n async resetCategory(id = this.getCategory()) {\n const cat = this.store.getCategories().find((c) => c.id === id);\n if (!cat) return false;\n const ok = await this._confirm({\n title: 'Reset category',\n message: `Reset every setting in \u201C${cat.label ?? cat.id}\u201D to its default?`,\n confirmLabel: 'Reset',\n danger: true,\n });\n if (!ok || this._disposed) return false;\n this.#flushAll();\n this.store.resetCategory(id);\n this.#syncAll();\n return true;\n }\n\n /** Reset every setting after `confirm`; resolves true when they were reset. */\n async resetAll() {\n const ok = await this._confirm({\n title: 'Reset all settings',\n message: 'Reset every setting to its default?',\n confirmLabel: 'Reset all',\n danger: true,\n });\n if (!ok || this._disposed) return false;\n this.#flushAll();\n this.store.resetAll();\n this.#syncAll();\n return true;\n }\n\n dispose() {\n if (this._disposed) return;\n this._disposed = true;\n this.#flushAll();\n this.#dropRows();\n for (const sub of this._pathSubs.values()) sub.dispose();\n this._pathSubs.clear();\n for (const sub of this._subs) sub.dispose();\n this._subs = [];\n this.root?.remove();\n this.root = null;\n this._nav = null;\n this._content = null;\n this._search = null;\n this._listeners.clear();\n super.dispose();\n }\n\n // \u2500\u2500 store 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\n\n #watch(path) {\n if (this._pathSubs.has(path)) return;\n this._pathSubs.set(path, this.eventBus.on(`settings:${path}:changed`, () => {\n this._rows.get(path)?.sync();\n }));\n }\n\n #onRegistered({ paths = [] } = {}) {\n if (!this.root) return;\n const schema = this.store.getSchema();\n for (const path of Object.keys(schema)) this.#watch(path);\n this.#paintNav();\n const active = this.getCategory();\n const touches = this.#searching()\n || !this._rows.size\n || paths.some((p) => schema[p]?.category === active);\n if (touches) {\n this.#paintContent();\n } else {\n // The slice's defaults may have moved values on screen; an edit still\n // being typed is written first, so the sync shows it rather than drop it.\n this.#flushAll();\n this.#syncAll();\n }\n this.#notify();\n }\n\n /** True while a filter is in effect: the trimmed query is not empty. */\n #searching() {\n return this._query.trim() !== '';\n }\n\n #syncAll() {\n for (const row of this._rows.values()) row.sync();\n }\n\n #flushAll() {\n for (const row of this._rows.values()) row.flush();\n }\n\n #dropRows() {\n for (const row of this._rows.values()) row.dispose();\n this._rows.clear();\n }\n\n // \u2500\u2500 painting \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 #activeCategory() {\n const cats = this.store.getCategories();\n return cats.find((c) => c.id === this._category) ?? cats[0] ?? null;\n }\n\n #paintNav() {\n if (!this._nav) return;\n paintCategories(this._nav, this.store.getCategories(), this.#searching() ? null : this.getCategory());\n }\n\n /** Tell the listeners, after the content is drawn (it settles the category). */\n #notify() {\n const state = { category: this.getCategory(), query: this._query };\n for (const fn of [...this._listeners]) fn(state);\n }\n\n #paintContent() {\n this.#flushAll();\n this.#dropRows();\n const schema = this.store.getSchema();\n const content = this._content;\n content.replaceChildren();\n\n if (this.#searching()) {\n const q = this._query.trim().toLowerCase();\n const cats = this.store.getCategories();\n const labelOf = new Map(cats.map((c) => [c.id, c.label ?? c.id]));\n const rank = new Map(cats.map((c, i) => [c.id, i]));\n const matches = Object.entries(schema)\n .filter(([path, def]) => [def.label, def.description, path]\n .some((t) => t != null && String(t).toLowerCase().includes(q)))\n .map(([path, def]) => ({ path, ...def }));\n matches.sort((a, b) => (rank.get(a.category) ?? Infinity) - (rank.get(b.category) ?? Infinity));\n\n const header = el('header', 'twm-settings__header');\n const info = el('div', 'twm-settings__header-info');\n const n = matches.length;\n info.append(el('h2', 'twm-settings__title',\n `${n} result${n === 1 ? '' : 's'} for \u201C${this._query.trim()}\u201D`));\n header.append(info);\n content.append(header);\n if (!n) {\n content.append(el('div', 'twm-settings__empty', 'No setting matches the filter.'));\n return;\n }\n this.#paintGroups(matches, (def) =>\n `${labelOf.get(def.category) ?? def.category ?? ''} \u203A ${def.group || 'General'}`);\n return;\n }\n\n const cat = this.#activeCategory();\n if (!cat) {\n content.append(el('div', 'twm-settings__empty', 'No settings.'));\n return;\n }\n // The page drawn is the category: a slice registered later, ordered\n // before it, must not move the sidebar marker or getCategory() off it.\n this._category = cat.id;\n const header = el('header', 'twm-settings__header');\n const info = el('div', 'twm-settings__header-info');\n info.append(el('h2', 'twm-settings__title', cat.label ?? cat.id));\n if (cat.description) info.append(el('p', 'twm-settings__description', cat.description));\n const reset = el('button', 'twm-btn twm-settings__reset-category');\n reset.type = 'button';\n reset.append(icon('restart_alt'), el('span', '', 'Reset category'));\n reset.addEventListener('click', () => { this.resetCategory(cat.id); });\n header.append(info, reset);\n content.append(header);\n\n const defs = Object.entries(schema)\n .filter(([, def]) => def.category === cat.id)\n .map(([path, def]) => ({ path, ...def }));\n if (!defs.length) {\n content.append(el('div', 'twm-settings__empty', 'No settings in this category.'));\n return;\n }\n this.#paintGroups(defs, (def) => def.group || 'General');\n }\n\n #paintGroups(defs, groupTitle) {\n const groups = new Map();\n for (const def of defs) {\n const key = groupTitle(def);\n if (!groups.has(key)) groups.set(key, []);\n groups.get(key).push(def);\n }\n for (const [title, list] of groups) {\n const section = el('section', 'twm-settings__group');\n section.append(el('h3', 'twm-settings__group-title', title));\n for (const def of list) section.append(this.#row(def));\n this._content.append(section);\n }\n }\n\n // \u2500\u2500 rows \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 #row(def) {\n const { path } = def;\n const store = this.store;\n const row = el('div', 'twm-settings__row');\n row.dataset.path = path;\n\n const info = el('div', 'twm-settings__info');\n const labelLine = el('div', 'twm-settings__label-line');\n const label = el('span', 'twm-settings__label', def.label ?? path);\n const marker = el('span', 'twm-settings__marker', 'Modified');\n labelLine.append(label, marker);\n info.append(labelLine);\n if (def.description) info.append(el('div', 'twm-settings__description', def.description));\n info.append(el('code', 'twm-settings__path', path));\n\n const slot = el('div', 'twm-settings__control');\n const control = this.#control(def, (value) => store.set(path, value));\n slot.append(control.el);\n\n const reset = el('button', 'twm-settings__reset');\n reset.type = 'button';\n reset.title = 'Reset to default';\n reset.setAttribute('aria-label', `Reset ${def.label ?? path} to default`);\n reset.append(icon('restart_alt'));\n reset.addEventListener('click', () => {\n control.cancel?.();\n store.resetOne(path);\n });\n\n row.append(info, slot, reset);\n\n const sync = () => {\n const value = store.get(path);\n control.show(value);\n const modified = !same(value, store.getDefault(path));\n row.classList.toggle('twm-settings__row--modified', modified);\n marker.hidden = !modified;\n reset.hidden = !modified;\n };\n sync();\n this._rows.set(path, {\n sync,\n flush: () => control.flush?.(),\n dispose: () => control.dispose?.(),\n });\n return row;\n }\n\n /** `{ el, show(value), flush?(), cancel?(), dispose?() }` for one setting. */\n #control(def, write) {\n const name = def.label ?? def.path;\n switch (def.type) {\n case 'boolean': {\n const t = new ToggleField({\n checked: !!this.store.get(def.path), ariaLabel: name, compact: true,\n onChange: (on) => write(on),\n });\n return {\n el: t.render(),\n show: (v) => { if (t.get() !== !!v) t.set(!!v); },\n dispose: () => t.dispose(),\n };\n }\n case 'select': {\n const c = selectBox(def.options || [], this.store.get(def.path), {\n label: name, valueAttr: 'value', className: 'twm-settings__select',\n });\n c.box.addEventListener('change', () => {\n // Redrawn as a fresh mount draws the chosen value, so a stray\n // '(not found)' entry goes once an offered option is picked.\n const v = c.valueOf();\n c.setOptions(def.options || [], v);\n write(v);\n });\n return {\n el: c.box,\n // Redrawn with the new value, as a fresh mount draws it: a\n // value the options lack shows as its '(not found)' entry, and\n // a stray entry left from an earlier value goes.\n show: (v) => { if (!same(c.valueOf(), v)) c.setOptions(def.options || [], v); },\n };\n }\n case 'number': {\n const box = el('input', 'twm-settings__number');\n box.type = 'number';\n box.setAttribute('aria-label', name);\n if (def.min != null) box.min = String(def.min);\n if (def.max != null) box.max = String(def.max);\n if (def.step != null) box.step = String(def.step);\n // Digits typed but not yet committed by 'change'.\n let dirty = false;\n const show = (v) => {\n dirty = false;\n const text = v == null ? '' : String(v);\n if (box.value !== text) box.value = text;\n };\n const commit = () => {\n const current = this.store.get(def.path);\n const n = box.value.trim() === '' ? NaN : Number(box.value);\n if (!Number.isFinite(n)) { show(current); return; }\n const v = fitNumber(n, def);\n show(v);\n if (!same(v, current)) write(v);\n };\n box.addEventListener('input', () => { dirty = true; });\n box.addEventListener('change', commit);\n return {\n el: box,\n show,\n flush: () => { if (dirty) commit(); },\n };\n }\n case 'text': {\n const box = el('input', 'twm-settings__text');\n box.type = 'text';\n box.setAttribute('aria-label', name);\n if (def.placeholder != null) box.placeholder = String(def.placeholder);\n let timer = null;\n const valueOf = () => (box.value === '' && def.defaultValue === null ? null : box.value);\n const cancel = () => { if (timer !== null) { clearTimeout(timer); timer = null; } };\n const commit = () => {\n const v = valueOf();\n if (!same(v, this.store.get(def.path))) write(v);\n };\n const flush = () => {\n if (timer === null) return;\n cancel();\n commit();\n };\n box.addEventListener('input', () => {\n cancel();\n timer = setTimeout(() => { timer = null; commit(); }, this._debounceMs);\n });\n box.addEventListener('change', flush);\n box.addEventListener('keydown', (e) => { if (e.key === 'Enter') flush(); });\n return {\n el: box,\n show: (v) => {\n const text = v == null ? '' : String(v);\n if (box.value === text) return;\n cancel();\n box.value = text;\n },\n flush,\n cancel,\n dispose: cancel,\n };\n }\n case 'colorList': {\n const value = this.store.get(def.path);\n const f = new ColorListField({\n value: Array.isArray(value) ? value : [],\n onChange: (colors, { commit }) => { if (commit && colors) write(colors); },\n });\n return {\n el: f.render(),\n show: (v) => {\n const list = Array.isArray(v) ? v : [];\n if (!same(f.getValue(), list)) f.setValue(list);\n },\n dispose: () => f.dispose(),\n };\n }\n default: {\n const out = el('span', 'twm-settings__readonly');\n return {\n el: out,\n show: (v) => { out.textContent = shownValue(v); },\n };\n }\n }\n }\n}\n\n/**\n * SettingsCategories \u2014 a SettingsView's filter box, category list and\n * *Reset all*, mounted wherever the app wants them (0.17.2).\n *\n * const view = new SettingsView({ store, eventBus, sidebar: false });\n * view.mount(pageHost);\n * const cats = new SettingsCategories({ view });\n * cats.mount(navigatorHost);\n * cats.dispose(); // before or with the view\n *\n * It holds no state of its own: typing in its filter is `view.setQuery()`,\n * clicking a category `view.selectCategory()`, *Reset all* `view.resetAll()`\n * (which asks the view's `confirm` first), and it redraws from the view on\n * every `view.subscribe()` call. So the filter text and the selected category\n * are always the view's, however either side moved them, and a category\n * registered later joins the list. Its clicks and keystrokes act once the\n * view is mounted.\n *\n * Markup: `.twm-settings-categories` > `.twm-settings__search` (>\n * `__search-input`), `.twm-settings__nav` > `button.twm-settings__cat`\n * [`--active`], `.twm-settings__reset-all`.\n */\nexport class SettingsCategories extends ComponentBase {\n /**\n * @param {object} o\n * @param {SettingsView} o.view the view it lists the categories of\n */\n constructor({ view, logger } = {}) {\n if (!(view instanceof SettingsView)) {\n throw new TypeError('SettingsCategories: `view` must be a SettingsView');\n }\n super({ eventBus: view.eventBus, logger });\n this.view = view;\n this.root = null;\n this._search = null;\n this._nav = null;\n this._unsubscribe = null;\n }\n\n /** Build the list into `container` (once). */\n mount(container) {\n if (this.root) return this.root;\n const view = this.view;\n const root = el('div', 'twm-settings-categories');\n const search = filterBox((text) => view.setQuery(text));\n this._search = search.input;\n this._nav = categoryNav((id) => view.selectCategory(id));\n root.append(search.label, this._nav, resetAllButton(() => view.resetAll()));\n this.root = root;\n container.appendChild(root);\n this._mounted = true;\n this._unsubscribe = view.subscribe(() => this.#paint());\n this.#paint();\n return root;\n }\n\n dispose() {\n this._unsubscribe?.();\n this._unsubscribe = null;\n this.root?.remove();\n this.root = null;\n this._search = null;\n this._nav = null;\n super.dispose();\n }\n\n #paint() {\n const view = this.view;\n const q = view.getQuery();\n if (this._search.value !== q) this._search.value = q;\n paintCategories(this._nav, view.store.getCategories(), view.isFiltering() ? null : view.getCategory());\n }\n}\n\n/**\n * A content factory for the shell: `(hostEl, props, ctx) -> { title, destroy }`.\n * `props.category` picks the category shown first.\n *\n * @param {object} opts as `new SettingsView(opts)`\n * @returns {Function}\n */\nexport function settingsViewContent(opts = {}) {\n return (hostEl, props = {}) => {\n const view = new SettingsView({ ...opts, category: props?.category ?? opts.category ?? null });\n view.mount(hostEl);\n return {\n title: opts.title ?? 'Settings',\n view,\n destroy: () => view.dispose(),\n };\n };\n}\n", "/**\n * A range slider with optional companions: a linked number box, a readout, a\n * default with a modified state and a reset button, and an enable toggle.\n *\n * Every companion is opt-in through `field`; with none of them the DOM is the\n * range and the helper line, exactly as before.\n *\n * field.min / max / step / value the range (defaults 0 / 100 / 1 / min)\n * field.numberInput true: an editable number box, two-way synced\n * field.readout true, or (value: number) => string\n * field.defaultValue enables the modified state and a reset button\n * field.toggleable true: an enable checkbox before the slider\n * field.enabled the toggle's initial state (default true)\n * field.disabledValue what onChange reports while toggled off (default null)\n * field.emitOnInput also report every drag frame ({ immediate: true })\n * field.disabled / helperText as before\n *\n * onChange(value, { immediate }) receives the slider's value as a string \u2014 the\n * range input's own value, as it always has \u2014 or `disabledValue` while the\n * toggle is off. A commit that leaves the reported value where it was reports\n * nothing, so setValue/setRange/setEnabled cannot echo back into the caller\n * that drove them.\n */\nexport class SliderField {\n #min = 0;\n #max = 100;\n #step = 1;\n #value = 0;\n #enabled = true;\n #hasDefault = false;\n #defaultValue = 0;\n\n constructor({ fieldId, field = {}, onChange = null, logger = null } = {}) {\n if (!fieldId) {\n throw new Error('SliderField requires a fieldId');\n }\n this.fieldId = fieldId;\n this.field = field;\n this.logger = logger;\n this.onChange = typeof onChange === 'function' ? onChange : null;\n\n this.root = null;\n this.sliderInput = null;\n this.numberInput = null;\n this.readoutEl = null;\n this.resetButton = null;\n this.toggleInput = null;\n this.helperEl = null;\n this.emitOnInput = Boolean(field.emitOnInput ?? field.emitsOnInput);\n this._disposers = [];\n\n this.#min = this.#coerceNumber(field.min, 0);\n this.#max = Math.max(this.#min, this.#coerceNumber(field.max, 100));\n this.#step = this.#coercePositiveNumber(field.step, 1);\n this.#value = this.#fit(this.#coerceNumber(field.value, this.#min));\n this.#enabled = field.toggleable ? field.enabled !== false : true;\n this.#hasDefault = this.#isFiniteInput(field.defaultValue);\n if (this.#hasDefault) {\n this.#defaultValue = this.#fit(Number(field.defaultValue));\n }\n }\n\n render() {\n if (this.root) {\n return this.root;\n }\n this.root = document.createElement('div');\n this.root.className = 'twm-slider-field';\n\n this.sliderInput = document.createElement('input');\n this.sliderInput.type = 'range';\n this.sliderInput.className = 'twm-slider-field__input';\n this.#writeRangeAttributes();\n\n // Prevent parent interactions from interfering with slider dragging\n // Use stopImmediatePropagation to ensure no other handlers on this element run\n // DO NOT call preventDefault - allow native slider drag behavior\n const stopDrag = (evt) => {\n evt.stopPropagation();\n evt.stopImmediatePropagation();\n };\n // Use capture phase to intercept before any parent handlers\n this.#listen(this.sliderInput, 'mousedown', stopDrag, { capture: true });\n this.#listen(this.sliderInput, 'touchstart', stopDrag, { passive: false, capture: true });\n\n this.helperEl = document.createElement('div');\n this.helperEl.className = 'twm-slider-field__helper';\n if (this.field.helperText) {\n this.helperEl.textContent = this.field.helperText;\n }\n\n const companions = this.field.toggleable || this.field.numberInput\n || this.field.readout || this.#hasDefault;\n if (companions) {\n const row = document.createElement('div');\n row.className = 'twm-slider-field__row';\n if (this.field.toggleable) {\n row.appendChild(this.#buildToggle());\n }\n row.appendChild(this.sliderInput);\n if (this.field.readout) {\n this.readoutEl = document.createElement('span');\n this.readoutEl.className = 'twm-slider-field__readout';\n row.appendChild(this.readoutEl);\n }\n if (this.field.numberInput) {\n row.appendChild(this.#buildNumberInput());\n }\n if (this.#hasDefault) {\n row.appendChild(this.#buildResetButton());\n }\n this.root.appendChild(row);\n } else {\n this.root.appendChild(this.sliderInput);\n }\n this.root.appendChild(this.helperEl);\n\n // Throttle onInput to animation frames to avoid re-render stutter while dragging\n let rafToken = null;\n let pendingValue = null;\n const flushPending = () => {\n if (rafToken) {\n cancelAnimationFrame(rafToken);\n rafToken = null;\n }\n if (pendingValue === null) return;\n const valueToEmit = pendingValue;\n pendingValue = null;\n if (this.emitOnInput) {\n this.onChange?.(valueToEmit, { immediate: true });\n }\n };\n\n const handleInput = (event) => {\n // The companions follow the thumb on every frame; onChange waits for release.\n this.#value = this.#fit(Number(event.target.value));\n this.#syncCompanions();\n pendingValue = event.target.value;\n if (!rafToken) {\n rafToken = requestAnimationFrame(() => {\n rafToken = null;\n flushPending();\n });\n }\n };\n const handleChange = (event) => {\n flushPending();\n this.#value = this.#fit(Number(event.target.value));\n this.#syncCompanions();\n this.onChange?.(event.target.value, { immediate: false });\n };\n this.#listen(this.sliderInput, 'input', handleInput);\n this.#listen(this.sliderInput, 'change', handleChange);\n\n this.#syncCompanions();\n return this.root;\n }\n\n /** What onChange would report now: the value as a string, or disabledValue while toggled off. */\n getValue() {\n return this.#enabled ? String(this.#value) : this.#disabledValue();\n }\n\n isEnabled() {\n return this.#enabled;\n }\n\n /** True when a defaultValue was given and the value differs from it. */\n isModified() {\n return this.#hasDefault && this.#value !== this.#defaultValue;\n }\n\n /**\n * Clamp to the range and snap to the step. Reports once, unless `silent` or\n * the reported value did not move. A non-finite value is refused (false).\n */\n setValue(value, { silent = false } = {}) {\n if (!this.#isFiniteInput(value)) {\n return false;\n }\n const numeric = Number(value);\n return this.#commit(() => { this.#value = this.#fit(numeric); }, silent);\n }\n\n setEnabled(enabled, { silent = false } = {}) {\n return this.#commit(() => { this.#enabled = Boolean(enabled); }, silent);\n }\n\n /** Change any of min/max/step; the value and the default are refitted into the new range. */\n setRange({ min, max, step } = {}, { silent = false } = {}) {\n return this.#commit(() => {\n this.#min = this.#isFiniteInput(min) ? Number(min) : this.#min;\n this.#max = Math.max(this.#min, this.#isFiniteInput(max) ? Number(max) : this.#max);\n this.#step = this.#coercePositiveNumber(step, this.#step);\n this.#value = this.#fit(this.#value);\n if (this.#hasDefault) {\n this.#defaultValue = this.#fit(this.#defaultValue);\n }\n if (this.sliderInput) {\n this.#writeRangeAttributes();\n }\n }, silent);\n }\n\n /** Restore defaultValue and report it, a commit like a drag release. */\n reset({ silent = false } = {}) {\n if (!this.#hasDefault) {\n return false;\n }\n return this.#commit(() => { this.#value = this.#defaultValue; }, silent);\n }\n\n dispose() {\n this._disposers.forEach((dispose) => {\n try {\n dispose?.();\n } catch (error) {\n this.logger?.warn?.('twm-slider-field', 'Failed to dispose slider listener', { error });\n }\n });\n this._disposers = [];\n this.root = null;\n this.sliderInput = null;\n this.numberInput = null;\n this.readoutEl = null;\n this.resetButton = null;\n this.toggleInput = null;\n this.helperEl = null;\n }\n\n #buildToggle() {\n this.toggleInput = document.createElement('input');\n this.toggleInput.type = 'checkbox';\n this.toggleInput.className = 'twm-slider-field__toggle';\n this.toggleInput.setAttribute('aria-label', 'Enabled');\n if (this.field.disabled) {\n this.toggleInput.disabled = true;\n }\n this.#listen(this.toggleInput, 'change', () => this.setEnabled(this.toggleInput.checked));\n return this.toggleInput;\n }\n\n #buildNumberInput() {\n this.numberInput = document.createElement('input');\n this.numberInput.type = 'text';\n this.numberInput.inputMode = 'decimal';\n this.numberInput.className = 'twm-slider-field__number';\n this.numberInput.setAttribute('aria-label', 'Value');\n // A typed value that is not a finite number is refused and the box shows the value again.\n const commitTyped = () => {\n if (!this.setValue(this.numberInput.value.trim())) {\n this.#syncCompanions();\n }\n };\n this.#listen(this.numberInput, 'keydown', (event) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n commitTyped();\n } else if (event.key === 'Escape') {\n this.#syncCompanions();\n }\n });\n this.#listen(this.numberInput, 'change', commitTyped);\n return this.numberInput;\n }\n\n #buildResetButton() {\n this.resetButton = document.createElement('button');\n this.resetButton.type = 'button';\n this.resetButton.className = 'twm-slider-field__reset';\n this.resetButton.title = 'Reset to default';\n this.resetButton.setAttribute('aria-label', 'Reset to default');\n const icon = document.createElement('span');\n icon.className = 'material-symbols-outlined';\n icon.textContent = 'restart_alt';\n this.resetButton.appendChild(icon);\n this.#listen(this.resetButton, 'click', () => this.reset());\n return this.resetButton;\n }\n\n /** Apply a change, refresh the DOM, and report once if the reported value moved. */\n #commit(apply, silent) {\n const before = this.getValue();\n apply();\n this.#syncCompanions();\n const after = this.getValue();\n if (after === before) {\n return false;\n }\n if (!silent) {\n this.onChange?.(after, { immediate: false });\n }\n return true;\n }\n\n /** Write the model into every element: slider, box, readout, toggle, states. */\n #syncCompanions() {\n if (!this.root) return;\n const text = String(this.#value);\n if (this.sliderInput.value !== text) {\n this.sliderInput.value = text;\n }\n const off = !this.#enabled;\n const hardDisabled = Boolean(this.field.disabled);\n this.sliderInput.disabled = hardDisabled || off;\n if (this.numberInput) {\n this.numberInput.value = text;\n this.numberInput.disabled = hardDisabled || off;\n }\n if (this.readoutEl) {\n const format = typeof this.field.readout === 'function' ? this.field.readout : null;\n this.readoutEl.textContent = format ? String(format(this.#value)) : text;\n }\n if (this.toggleInput) {\n this.toggleInput.checked = this.#enabled;\n }\n const modified = this.isModified();\n if (this.resetButton) {\n this.resetButton.disabled = hardDisabled || off || !modified;\n }\n this.root.classList.toggle('twm-slider-field--modified', modified);\n this.root.classList.toggle('twm-slider-field--off', off);\n }\n\n #writeRangeAttributes() {\n this.sliderInput.min = String(this.#min);\n this.sliderInput.max = String(this.#max);\n this.sliderInput.step = String(this.#step);\n this.sliderInput.value = String(this.#value);\n }\n\n /** Clamp to [min, max] and snap to the step grid anchored at min, as a range input does. */\n #fit(value) {\n const clamped = Math.min(this.#max, Math.max(this.#min, value));\n let snapped = this.#min + Math.round((clamped - this.#min) / this.#step) * this.#step;\n if (snapped > this.#max) snapped -= this.#step;\n const decimals = Math.max(this.#decimals(this.#step), this.#decimals(this.#min));\n return Number(snapped.toFixed(Math.min(decimals, 12)));\n }\n\n #decimals(value) {\n const text = String(value);\n if (text.includes('e-')) return Number(text.split('e-')[1]);\n const dot = text.indexOf('.');\n return dot === -1 ? 0 : text.length - dot - 1;\n }\n\n #isFiniteInput(value) {\n if (value === null || value === undefined || typeof value === 'boolean') {\n return false;\n }\n if (typeof value === 'string' && value.trim() === '') {\n return false;\n }\n return Number.isFinite(Number(value));\n }\n\n #disabledValue() {\n return this.field.disabledValue === undefined ? null : this.field.disabledValue;\n }\n\n #listen(target, type, handler, options) {\n target.addEventListener(type, handler, options);\n this._disposers.push(() => target.removeEventListener(type, handler, options));\n }\n\n #coerceNumber(value, fallback) {\n const numeric = Number(value);\n return Number.isFinite(numeric) ? numeric : fallback;\n }\n\n #coercePositiveNumber(value, fallback) {\n const numeric = this.#coerceNumber(value, fallback);\n if (numeric <= 0) {\n return fallback;\n }\n return numeric;\n }\n}\n", "/**\n * table_state_store.js \u2014 persist DataTable view-state (sort, filters,\n * column widths), keyed by a caller-supplied `persistKey`.\n *\n * A FACTORY, not a singleton: the store reads and writes through a Host's\n * `state` capability (see ui/js/host/host.js) under one logical state key.\n * One blob holds a map of `{ [persistKey]: state }` for every persisted table.\n * Where that key lands on disk is the embedder's business, not ours \u2014 it is\n * decided by the host's `resolvePath`.\n *\n * A host without a `state` capability is legal: tables simply stay ephemeral.\n *\n * The in-memory cache must be dropped when the project changes (the app swaps\n * projects in-place without a page reload) \u2014 `reset()` is wired to the\n * `project:opened` event in app_bootstrap.\n */\n\n/**\n * @param {object} opts\n * @param {object} opts.host a Host. May lack `state` -> tables become ephemeral.\n * @param {string} opts.key logical state key, e.g. 'datatable_state'\n * @param {object} [opts.logger]\n * @param {number} [opts.debounceMs=500]\n */\nexport function createTableStateStore({ host, key, logger = console, debounceMs = 500 }) {\n if (!key) throw new Error('createTableStateStore requires { key }');\n const state = host?.state || null;\n\n let cache = null; // { [persistKey]: state } \u2014 null until first load\n let loadPromise = null;\n let saveTimer = null;\n\n const scheduleSave = () => {\n if (saveTimer) clearTimeout(saveTimer);\n saveTimer = setTimeout(async () => {\n saveTimer = null;\n if (!state || !cache) return;\n try { await state.write(key, cache); }\n catch (err) { logger.warn?.('[table-state] save failed', err); }\n }, debounceMs);\n };\n\n return {\n /** Resolve once the persisted blob has been read into the cache. Safe\n * to call repeatedly \u2014 the read happens at most once per project. */\n ready() {\n if (loadPromise) return loadPromise;\n loadPromise = (async () => {\n if (!state) { cache = {}; return cache; }\n try { cache = (await state.read(key)) || {}; }\n catch (err) { logger.warn?.('[table-state] load failed', err); cache = {}; }\n return cache;\n })();\n return loadPromise;\n },\n\n /** Synchronous read of a table's persisted state. Returns null until\n * the cache is loaded (await `ready()` first to be sure). */\n get(k) {\n if (!k || !cache) return null;\n return cache[k] || null;\n },\n\n /** Merge-and-persist a table's state (debounced). Pass null to forget\n * a key. Writes the whole map back atomically through the host. */\n set(k, s) {\n if (!k) return;\n if (!cache) cache = {};\n if (s == null) delete cache[k]; else cache[k] = s;\n scheduleSave();\n },\n\n /** Drop the cache + pending read so the next access reloads from the\n * newly-opened project. Cancels any in-flight save for the old one. */\n reset() {\n cache = null;\n loadPromise = null;\n if (saveTimer) { clearTimeout(saveTimer); saveTimer = null; }\n },\n };\n}\n", "/**\n * tag_input.js \u2014 A LIST OF SHORT STRINGS, drawn as removable chips followed by\n * a text box. (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\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 [baseline \u00D7] [stress \u00D7] [q3 \u00D7] Add a tag\u2026 \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\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 * The text box commits what was typed \u2014 trimmed, split at commas \u2014 on Enter,\n * on a comma and when it loses focus. Empty pieces are dropped, and so is a\n * piece already in the list unless `allowDuplicates`. Backspace in an empty\n * box removes the last chip. A paste that carries a comma is split into\n * chips at once; a paste without one is ordinary text in the box.\n *\n * Every chip has a remove button with an `aria-label` (`removeLabel(tag)`,\n * \"Remove <tag>\" by default). `readOnly` draws the chips alone: no remove\n * buttons and no text box.\n *\n * `onChange(list)` is called with a fresh copy of the list after every change\n * the reader makes \u2014 never for `setValue`, and never for a commit that added\n * nothing.\n *\n * const tags = createTagInput(host, {\n * value: ['baseline'],\n * placeholder: 'Add a tag\u2026',\n * onChange: (list) => save(list),\n * });\n * tags.getValue(); // ['baseline']\n * tags.setValue(['a', 'b']);\n * tags.dispose();\n */\n\n/** The list as strings, the empty ones left out. */\nconst normalise = (list) => (Array.isArray(list) ? list : [])\n .map((v) => (v == null ? '' : String(v).trim()))\n .filter((v) => v !== '');\n\n/**\n * @typedef {Object} TagInputOptions\n * @property {string[]} [value] - The tags it opens with.\n * @property {string} [placeholder] - The empty text box's placeholder.\n * @property {boolean} [readOnly] - Chips only: no remove buttons, no text box.\n * @property {boolean} [allowDuplicates] - Keep a tag that is already in the list.\n * @property {(list: string[]) => void} [onChange] - After each change the reader makes.\n * @property {string} [label] - The text box's accessible name.\n * @property {(tag: string) => string} [removeLabel] - A remove button's `aria-label`.\n * @property {string} [className] - Extra classes on the root.\n */\n\n/**\n * @param {HTMLElement} host\n * @param {TagInputOptions} [options]\n */\nexport function createTagInput(host, options = {}) {\n if (!host || typeof host.appendChild !== 'function') {\n throw new Error('[TagInput] host must be an HTMLElement');\n }\n const readOnly = !!options.readOnly;\n const allowDuplicates = !!options.allowDuplicates;\n const removeLabel = typeof options.removeLabel === 'function'\n ? options.removeLabel : (tag) => `Remove ${tag}`;\n\n let tags = normalise(options.value);\n let disposed = false;\n\n const root = document.createElement('div');\n root.className = ['twm-tag-input', readOnly ? 'twm-tag-input--readonly' : '', options.className || '']\n .join(' ').replace(/\\s+/g, ' ').trim();\n root.setAttribute('role', 'group');\n if (options.label) root.setAttribute('aria-label', options.label);\n\n const chips = document.createElement('ul');\n chips.className = 'twm-tag-input__chips';\n root.appendChild(chips);\n\n let input = null;\n if (!readOnly) {\n input = document.createElement('input');\n input.type = 'text';\n input.className = 'twm-tag-input__input';\n input.spellcheck = false;\n input.autocomplete = 'off';\n if (options.placeholder) input.placeholder = options.placeholder;\n if (options.label) input.setAttribute('aria-label', options.label);\n root.appendChild(input);\n }\n\n const changed = () => {\n if (typeof options.onChange === 'function') options.onChange([...tags]);\n };\n\n const chipFor = (tag, idx) => {\n const chip = document.createElement('li');\n chip.className = 'twm-tag-input__chip';\n const text = document.createElement('span');\n text.className = 'twm-tag-input__text';\n text.textContent = tag;\n text.title = tag;\n chip.appendChild(text);\n if (!readOnly) {\n const remove = document.createElement('button');\n remove.type = 'button';\n remove.className = 'twm-tag-input__remove';\n remove.setAttribute('aria-label', removeLabel(tag));\n remove.textContent = '\u00D7';\n // The text box keeps the focus: a blur would commit its text\n // and redraw the chips under the pointer before the click.\n remove.addEventListener('mousedown', (ev) => ev.preventDefault());\n remove.addEventListener('click', (ev) => {\n ev.preventDefault();\n ev.stopPropagation();\n removeAt(idx);\n input?.focus();\n });\n chip.appendChild(remove);\n }\n return chip;\n };\n\n /** Redraws every chip. */\n const paint = () => {\n chips.replaceChildren(...tags.map(chipFor));\n };\n\n function removeAt(idx) {\n if (disposed || readOnly || idx < 0 || idx >= tags.length) return;\n tags = tags.filter((_, i) => i !== idx);\n paint();\n changed();\n }\n\n /** Adds the comma-separated pieces of `text`; true when any was added. */\n const commitText = (text) => {\n if (disposed || readOnly) return false;\n const next = [...tags];\n for (const piece of String(text).split(',')) {\n const tag = piece.trim();\n if (tag === '') continue;\n if (!allowDuplicates && next.includes(tag)) continue;\n next.push(tag);\n }\n if (next.length === tags.length) return false;\n // Only the new chips are drawn: the ones already there stay in place,\n // so a remove button that the focus is moving to (Tab out of the box\n // commits its text) is still in the document when the focus lands.\n const added = next.slice(tags.length).map((tag, i) => chipFor(tag, tags.length + i));\n tags = next;\n chips.append(...added);\n changed();\n return true;\n };\n\n const commitInput = () => {\n if (!input) return;\n const text = input.value;\n input.value = '';\n commitText(text);\n };\n\n if (input) {\n input.addEventListener('keydown', (ev) => {\n if (ev.isComposing) return;\n if (ev.key === 'Enter' || ev.key === ',') {\n ev.preventDefault();\n commitInput();\n } else if (ev.key === 'Backspace' && input.value === '' && tags.length) {\n ev.preventDefault();\n removeAt(tags.length - 1);\n }\n });\n // A comma that arrives without its keydown (a soft keyboard, an IME,\n // a drop) commits all the same.\n input.addEventListener('input', () => {\n if (input.value.includes(',')) commitInput();\n });\n input.addEventListener('blur', commitInput);\n input.addEventListener('paste', (ev) => {\n const pasted = ev.clipboardData?.getData('text/plain') ?? '';\n if (!pasted.includes(',')) return;\n ev.preventDefault();\n const start = input.selectionStart ?? input.value.length;\n const end = input.selectionEnd ?? start;\n const text = input.value.slice(0, start) + pasted + input.value.slice(end);\n input.value = '';\n commitText(text);\n });\n root.addEventListener('mousedown', (ev) => {\n if (ev.target === root || ev.target === chips) {\n ev.preventDefault();\n input.focus();\n }\n });\n }\n\n paint();\n host.appendChild(root);\n\n return {\n element: root,\n input,\n getValue: () => [...tags],\n /** Replaces the list. Does not call `onChange`. */\n setValue(list) {\n if (disposed) return;\n tags = normalise(list);\n paint();\n },\n focus() { input?.focus(); },\n dispose() {\n if (disposed) return;\n disposed = true;\n root.remove();\n },\n };\n}\n", "/**\n * toast.js \u2014 thin wrapper around the mounted NotificationCenter for\n * callers that don't already hold an eventBus reference.\n *\n * The NotificationCenter (../notification_center.js) subscribes to\n * `toast:show` on its event bus; these helpers emit the same payload shape\n * on the bus they were given. They read no global: `NotificationCenter.mount()`\n * hands its bus to `setToastBus()`, and `dispose()` takes it back. An embedder\n * that wants toasts on some other bus calls `setToastBus(bus)` itself, and\n * `setToastBus(null)` to stop.\n *\n * Usage:\n * import { toastError, toastSuccess, toastWarn, toastInfo } from './toast.js';\n * toastError('Save failed', 'the server refused the change');\n *\n * The 1-arg form treats the string as the message (no title); the\n * 2-arg form is title + message. With no bus (no NotificationCenter mounted\n * yet, isolated test pages) the message goes to the console and nothing throws.\n */\n\nlet toastBus = null;\n\n/**\n * Route the toast helpers to `bus` (anything with `emit(name, payload)`), or\n * to the console with `null`. Returns the bus that was set before.\n */\nexport function setToastBus(bus) {\n const prev = toastBus;\n toastBus = bus && typeof bus.emit === 'function' ? bus : null;\n return prev;\n}\n\n/** The bus the toast helpers currently emit on, or null. */\nexport function getToastBus() {\n return toastBus;\n}\n\nfunction _emit(severity, persistent, titleOrMsg, msg) {\n const bus = toastBus;\n const title = (msg !== undefined) ? titleOrMsg : null;\n const message = (msg !== undefined) ? msg : titleOrMsg;\n if (!bus) {\n // Fall back to console so the message isn't lost if the bus is\n // unavailable (early bootstrap, isolated test pages).\n // eslint-disable-next-line no-console\n (severity === 'error' || severity === 'warn' ? console.warn : console.info)(\n `[toast/${severity}]`, title ? `${title}:` : '', message);\n return;\n }\n bus.emit('toast:show', {\n title, message, severity,\n persistent,\n durationMs: persistent ? 0 : 5000,\n });\n}\n\nexport function toastError(titleOrMsg, msg) { _emit('error', true, titleOrMsg, msg); }\nexport function toastWarn(titleOrMsg, msg) { _emit('warn', false, titleOrMsg, msg); }\nexport function toastInfo(titleOrMsg, msg) { _emit('info', false, titleOrMsg, msg); }\nexport function toastSuccess(titleOrMsg, msg) { _emit('success', false, titleOrMsg, msg); }\n\n/** Coerce a bridge-call result/exception into a user-facing error toast.\n * Drops the toast only if `res?.ok === false` *or* an exception was caught.\n * Returns true if the call succeeded (caller can continue), false otherwise. */\nexport function reportBridgeError(opName, resOrErr) {\n if (!resOrErr) return true;\n if (resOrErr instanceof Error) {\n toastError(opName, resOrErr.message || String(resOrErr));\n return false;\n }\n if (resOrErr && resOrErr.ok === false) {\n toastError(opName, resOrErr.error || 'operation refused');\n return false;\n }\n return true;\n}\n", "/**\n * Tree View Component\n *\n * A reusable hierarchical tree view component for displaying nested data.\n * Used by Functions Page (modules/functions) and Data Page (datasets/series).\n *\n * Structure:\n * - TreeView: Container for multiple categories\n * - TreeCategory: Top-level collapsible group (e.g., \"Built-in\", \"Project\")\n * - TreeNode: Expandable node with children (e.g., module, dataset)\n * - TreeItem: Leaf item (e.g., function, series)\n */\n\n/**\n * Labels, subtitles and badge text are TEXT, set with `textContent` after the\n * skeleton is built (BUG-0013): a dataset called 'A <b>B</b>' is shown as\n * those characters, and a name carrying `<img onerror>` runs nothing.\n */\nfunction setText(root, selector, value) {\n const el = root.querySelector(selector);\n if (el) el.textContent = value == null ? '' : String(value);\n}\n\n/**\n * An id as the value of a double-quoted attribute selector (BUG-0013).\n * NOT `CSS.escape`: jsdom does not provide it (see modal.js). Inside a quoted\n * attribute value `\"` and `\\` are escaped, and a line break, which would end\n * the string, becomes its hex escape.\n */\nfunction attrValue(value) {\n return String(value)\n .replace(/[\"\\\\]/g, '\\\\$&')\n .replace(/[\\n\\r\\f]/g, (c) => `\\\\${c.charCodeAt(0).toString(16)} `);\n}\n\n/**\n * Create a tree category (top-level collapsible section)\n * @param {Object} options - Category options\n * @param {string} options.id - Unique category ID\n * @param {string} options.label - Display label\n * @param {string} [options.icon] - Material icon name\n * @param {string} [options.iconClass] - Additional icon CSS class\n * @param {number} [options.count] - Item count to display\n * @param {boolean} [options.expanded=false] - Initial expanded state\n * @param {boolean} [options.readonly=false] - Whether items are readonly\n * @returns {HTMLElement} - Category element\n */\nexport function createTreeCategory(options) {\n const {\n id,\n label,\n icon = 'folder',\n iconClass = '',\n count = 0,\n expanded = false,\n readonly = false,\n } = options;\n\n const node = document.createElement('div');\n node.className = 'twm-collapsible-box twm-tree-category';\n node.dataset.categoryId = id;\n node.dataset.collapsibleId = `tree-category-${id}`;\n node.dataset.collapsibleDefault = expanded ? 'expanded' : 'collapsed';\n if (readonly) node.dataset.readonly = 'true';\n\n node.innerHTML = `\n <div class=\"twm-collapsible-header\" data-collapsible-header=\"true\">\n <button class=\"twm-arrow-toggle\" type=\"button\">\n <span class=\"twm-collapsible-arrow material-symbols-outlined${expanded ? '' : ' collapsed'}\">expand_more</span>\n </button>\n <span class=\"twm-tree-category__icon ${iconClass}\">\n <span class=\"material-symbols-outlined\">${icon}</span>\n </span>\n <span class=\"twm-tree-category__label\"></span>\n <span class=\"twm-tree-category__count\">(${count})</span>\n </div>\n <div class=\"twm-collapsible-content${expanded ? ' visible' : ''}\" data-collapsible-content=\"true\"></div>\n `;\n setText(node, '.twm-tree-category__label', label);\n\n return node;\n}\n\n/**\n * Create a tree node (expandable container with children)\n * @param {Object} options - Node options\n * @param {string} options.id - Unique node ID\n * @param {string} options.label - Display label\n * @param {string} [options.icon] - Material icon name (optional)\n * @param {number} [options.count] - Child count to display\n * @param {boolean} [options.expanded=false] - Initial expanded state\n * @param {boolean} [options.readonly=false] - Whether node is readonly\n * @param {Object} [options.actions] - Action buttons config\n * @returns {HTMLElement} - Node element\n */\nexport function createTreeNode(options) {\n const {\n id,\n label,\n icon = null,\n count = 0,\n expanded = false,\n readonly = false,\n actions = null,\n } = options;\n\n const node = document.createElement('div');\n node.className = `twm-tree-node${readonly ? ' readonly' : ''}`;\n node.dataset.nodeId = id;\n\n const iconHtml = icon\n ? `<span class=\"twm-tree-node__icon\"><span class=\"material-symbols-outlined\">${icon}</span></span>`\n : '';\n\n const actionsHtml = actions ? '<span class=\"twm-tree-node__actions\"></span>' : '';\n\n node.innerHTML = `\n <div class=\"twm-tree-node__header\">\n <span class=\"twm-tree-node__toggle\">\n <span class=\"material-symbols-outlined\">${expanded ? 'expand_more' : 'chevron_right'}</span>\n </span>\n ${iconHtml}\n <span class=\"twm-tree-node__label\"></span>\n <span class=\"twm-tree-node__count\">(${count})</span>\n ${actionsHtml}\n </div>\n <div class=\"twm-tree-node__children\" style=\"display: ${expanded ? 'block' : 'none'};\"></div>\n `;\n setText(node, '.twm-tree-node__label', label);\n\n // Add action buttons if specified\n if (actions) {\n const actionsEl = node.querySelector('.twm-tree-node__actions');\n Object.entries(actions).forEach(([actionId, actionConfig]) => {\n const btn = document.createElement('button');\n btn.className = 'twm-tree-node__action-btn';\n btn.dataset.action = actionId;\n btn.title = actionConfig.title || actionId;\n btn.innerHTML = `<span class=\"material-symbols-outlined\">${actionConfig.icon}</span>`;\n if (actionConfig.onClick) {\n btn.addEventListener('click', (e) => {\n e.stopPropagation();\n actionConfig.onClick(id, e);\n });\n }\n actionsEl.appendChild(btn);\n });\n }\n\n return node;\n}\n\n/**\n * Create a tree item (leaf node)\n * @param {Object} options - Item options\n * @param {string} options.id - Unique item ID\n * @param {string} options.label - Display label\n * @param {string} [options.icon] - Material icon or symbol (e.g., '\u0192', 'insights')\n * @param {boolean} [options.isMaterialIcon=true] - Whether icon is Material icon\n * @param {boolean} [options.readonly=false] - Whether item is readonly\n * @param {boolean} [options.selected=false] - Whether item is selected\n * @param {string} [options.subtitle] - Optional subtitle text\n * @param {Object} [options.data] - Additional data to attach\n * @param {Object} [options.badge] - Optional badge config\n * @param {string} [options.badge.text] - Badge text (if empty, renders as status dot)\n * @param {string} [options.badge.variant] - 'muted'|'pass'|'fail'|'error'\n * @returns {HTMLElement} - Item element\n */\nexport function createTreeItem(options) {\n const {\n id,\n label,\n icon = null,\n isMaterialIcon = true,\n readonly = false,\n selected = false,\n subtitle = null,\n data = null,\n badge = null,\n } = options;\n\n const item = document.createElement('div');\n item.className = `twm-tree-item${readonly ? ' readonly' : ''}${selected ? ' selected' : ''}`;\n item.dataset.itemId = id;\n\n // Attach custom data\n if (data) {\n Object.entries(data).forEach(([key, value]) => {\n item.dataset[key] = value;\n });\n }\n\n const iconHtml = icon\n ? isMaterialIcon\n ? `<span class=\"twm-tree-item__icon\"><span class=\"material-symbols-outlined\">${icon}</span></span>`\n : `<span class=\"twm-tree-item__icon twm-tree-item__icon--symbol\">${icon}</span>`\n : '';\n\n const subtitleHtml = subtitle\n ? '<span class=\"twm-tree-item__subtitle\"></span>'\n : '';\n\n let badgeHtml = '';\n if (badge) {\n const variant = badge.variant || 'muted';\n if (badge.text) {\n badgeHtml = `<span class=\"twm-tree-item__badge twm-tree-item__badge--${variant}\"></span>`;\n } else {\n badgeHtml = `<span class=\"twm-tree-item__status-dot twm-tree-item__status-dot--${variant}\"></span>`;\n }\n }\n\n item.innerHTML = `\n ${iconHtml}\n <span class=\"twm-tree-item__label\"></span>\n ${subtitleHtml}\n ${badgeHtml}\n `;\n setText(item, '.twm-tree-item__label', label);\n if (subtitle) setText(item, '.twm-tree-item__subtitle', subtitle);\n if (badge?.text) setText(item, '.twm-tree-item__badge', badge.text);\n\n return item;\n}\n\n/**\n * Toggle a collapsible category\n * @param {HTMLElement} categoryEl - Category element\n * @param {boolean} [force] - Force specific state (true = expand, false = collapse)\n */\nexport function toggleCategory(categoryEl, force) {\n if (!categoryEl) return;\n\n const arrow = categoryEl.querySelector(':scope > .twm-collapsible-header .twm-collapsible-arrow');\n const content = categoryEl.querySelector(':scope > .twm-collapsible-content');\n\n if (!content) return;\n\n // Determine whether we should expand\n // force=true means expand, force=false means collapse, undefined means toggle\n const isCurrentlyExpanded = content.classList.contains('visible');\n const shouldExpand = force !== undefined ? force : !isCurrentlyExpanded;\n\n if (shouldExpand) {\n // Expand\n if (arrow) {\n arrow.classList.remove('collapsed');\n }\n content.classList.add('visible');\n } else {\n // Collapse\n if (arrow) {\n arrow.classList.add('collapsed');\n }\n content.classList.remove('visible');\n }\n}\n\n/**\n * Toggle a tree node\n * @param {HTMLElement} nodeEl - Node element\n * @param {boolean} [force] - Force specific state\n */\nexport function toggleNode(nodeEl, force) {\n if (!nodeEl) return;\n\n const toggle = nodeEl.querySelector(':scope > .twm-tree-node__header .twm-tree-node__toggle .material-symbols-outlined');\n const children = nodeEl.querySelector(':scope > .twm-tree-node__children');\n\n if (!children) return;\n\n const isExpanded = force !== undefined\n ? force\n : children.style.display === 'none';\n\n if (isExpanded) {\n children.style.display = 'block';\n if (toggle) toggle.textContent = 'expand_more';\n } else {\n children.style.display = 'none';\n if (toggle) toggle.textContent = 'chevron_right';\n }\n}\n\n/**\n * Filter tree items by text match\n *\n * An item is shown when its label contains the filter. A node or a category is\n * shown when any tree item inside it is shown, whether the item sits directly\n * in it or deeper inside nodes. An empty filter shows everything, so clearing\n * the filter restores the whole tree, empty nodes and categories included.\n *\n * @param {HTMLElement} container - Tree container\n * @param {string} filter - Filter text (case-insensitive)\n * @param {Object} [options] - Filter options\n * @param {boolean} [options.expandMatches=true] - Auto-expand nodes with matches\n */\nexport function filterTree(container, filter, options = {}) {\n const { expandMatches = true } = options;\n const normalizedFilter = (filter || '').toLowerCase().trim();\n\n const visibleItems = new Set();\n container.querySelectorAll('.twm-tree-item').forEach((item) => {\n const label = item.querySelector('.twm-tree-item__label')?.textContent || '';\n const matches = !normalizedFilter || label.toLowerCase().includes(normalizedFilter);\n item.style.display = matches ? '' : 'none';\n item.classList.toggle('twm-filter-match', matches && !!normalizedFilter);\n if (matches) visibleItems.add(item);\n });\n\n const hasVisibleItem = (el) => !normalizedFilter\n || [...el.querySelectorAll('.twm-tree-item')].some((item) => visibleItems.has(item));\n\n container.querySelectorAll('.twm-tree-node').forEach((node) => {\n const visible = hasVisibleItem(node);\n node.style.display = visible ? '' : 'none';\n if (expandMatches && visible && normalizedFilter) toggleNode(node, true);\n });\n\n container.querySelectorAll('.twm-tree-category').forEach((category) => {\n const visible = hasVisibleItem(category);\n category.style.display = visible ? '' : 'none';\n if (expandMatches && visible && normalizedFilter) toggleCategory(category, true);\n });\n}\n\n/**\n * Select a tree item\n * @param {HTMLElement} container - Tree container\n * @param {string} itemId - Item ID to select\n * @param {Object} [options] - Selection options\n * @param {boolean} [options.scrollIntoView=true] - Scroll item into view\n * @param {boolean} [options.expandParents=true] - Expand parent nodes\n */\nexport function selectItem(container, itemId, options = {}) {\n const { scrollIntoView = true, expandParents = true } = options;\n\n // Deselect all\n container.querySelectorAll('.twm-tree-item.selected').forEach((el) => {\n el.classList.remove('selected');\n });\n\n // Find and select item\n const item = container.querySelector(`.twm-tree-item[data-item-id=\"${attrValue(itemId)}\"]`);\n if (!item) return null;\n\n item.classList.add('selected');\n\n // Expand parent nodes\n if (expandParents) {\n let parent = item.parentElement;\n while (parent && parent !== container) {\n if (parent.classList.contains('twm-tree-node__children')) {\n const node = parent.closest('.twm-tree-node');\n if (node) toggleNode(node, true);\n }\n if (parent.classList.contains('twm-collapsible-content')) {\n const category = parent.closest('.twm-tree-category');\n if (category) toggleCategory(category, true);\n }\n parent = parent.parentElement;\n }\n }\n\n // Scroll into view\n if (scrollIntoView) {\n item.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }\n\n return item;\n}\n\n/**\n * TreeView class for managing a complete tree structure\n */\nexport class TreeView {\n constructor(container, options = {}) {\n this.container = container;\n this.options = {\n onItemClick: null,\n onItemDoubleClick: null,\n onNodeToggle: null,\n onCategoryToggle: null,\n ...options,\n };\n\n this._boundHandleClick = this._handleClick.bind(this);\n this._boundHandleDblClick = this._handleDoubleClick.bind(this);\n\n if (container) {\n container.classList.add('twm-tree-view');\n container.addEventListener('click', this._boundHandleClick);\n container.addEventListener('dblclick', this._boundHandleDblClick);\n }\n }\n\n _handleClick(e) {\n // Handle category toggle\n const collapsibleHeader = e.target.closest('.twm-collapsible-header');\n if (collapsibleHeader) {\n const category = collapsibleHeader.closest('.twm-tree-category');\n if (category) {\n toggleCategory(category);\n this.options.onCategoryToggle?.(category.dataset.categoryId, category);\n }\n return;\n }\n\n // Handle node toggle\n const nodeHeader = e.target.closest('.twm-tree-node__header');\n if (nodeHeader) {\n const node = nodeHeader.closest('.twm-tree-node');\n if (node) {\n toggleNode(node);\n this.options.onNodeToggle?.(node.dataset.nodeId, node);\n }\n return;\n }\n\n // Handle item click\n const item = e.target.closest('.twm-tree-item');\n if (item) {\n this.select(item.dataset.itemId);\n this.options.onItemClick?.(item.dataset.itemId, item, e);\n }\n }\n\n _handleDoubleClick(e) {\n const item = e.target.closest('.twm-tree-item');\n if (item) {\n this.options.onItemDoubleClick?.(item.dataset.itemId, item, e);\n }\n }\n\n addCategory(options) {\n const category = createTreeCategory(options);\n this.container.appendChild(category);\n return category;\n }\n\n addNode(categoryId, options) {\n const category = this.container.querySelector(`.twm-tree-category[data-category-id=\"${attrValue(categoryId)}\"]`);\n const content = category?.querySelector('.twm-collapsible-content');\n if (!content) return null;\n\n const node = createTreeNode(options);\n content.appendChild(node);\n return node;\n }\n\n addItem(nodeId, options) {\n const node = this.container.querySelector(`.twm-tree-node[data-node-id=\"${attrValue(nodeId)}\"]`);\n const children = node?.querySelector('.twm-tree-node__children');\n if (!children) return null;\n\n const item = createTreeItem(options);\n children.appendChild(item);\n return item;\n }\n\n select(itemId) {\n return selectItem(this.container, itemId);\n }\n\n filter(text) {\n filterTree(this.container, text);\n }\n\n clear() {\n this.container.innerHTML = '';\n }\n\n dispose() {\n if (this.container) {\n this.container.removeEventListener('click', this._boundHandleClick);\n this.container.removeEventListener('dblclick', this._boundHandleDblClick);\n }\n }\n}\n\nexport default TreeView;\n", "/**\n * WindowTaskbar - Singleton component that manages minimized windows in the global bottom bar.\n *\n * Listens for window events and renders taskbar buttons for minimized windows.\n * Integrates with the existing global-bottom-bar element.\n */\n\nimport { ManagedWindow } from './managed_window.js';\n\nclass WindowTaskbarManager {\n constructor() {\n this._minimizedWindows = new Map(); // id -> { title, icon }\n this._containerEl = null;\n this._leftDivider = null;\n this._rightDivider = null;\n this._initialized = false;\n }\n\n /**\n * Initialize the taskbar. Call once after DOM is ready.\n */\n init() {\n if (this._initialized) return;\n\n // Find or create the container in the global bottom bar\n const bottomBar = document.querySelector('.twm-global-bottom-bar');\n if (!bottomBar) {\n console.warn('[WindowTaskbar] twm-global-bottom-bar not found');\n return;\n }\n\n // Create left divider (always present but hidden when no windows)\n this._leftDivider = document.createElement('div');\n this._leftDivider.className = 'twm-bar-windows__divider twm-bar-windows__divider--left';\n\n // Insert bar-windows container between bar-left and bar-center\n this._containerEl = document.createElement('div');\n this._containerEl.className = 'twm-bar-windows';\n\n // Create right divider (shown when there are windows)\n this._rightDivider = document.createElement('div');\n this._rightDivider.className = 'twm-bar-windows__divider twm-bar-windows__divider--right';\n\n const barCenter = bottomBar.querySelector('.twm-bar-center');\n if (barCenter) {\n bottomBar.insertBefore(this._rightDivider, barCenter);\n bottomBar.insertBefore(this._containerEl, this._rightDivider);\n bottomBar.insertBefore(this._leftDivider, this._containerEl);\n } else {\n bottomBar.appendChild(this._leftDivider);\n bottomBar.appendChild(this._containerEl);\n bottomBar.appendChild(this._rightDivider);\n }\n\n // Listen for window events\n window.addEventListener('managed-window-minimized', (e) => this._onWindowMinimized(e));\n window.addEventListener('managed-window-restored', (e) => this._onWindowRestored(e));\n window.addEventListener('managed-window-closed', (e) => this._onWindowClosed(e));\n\n this._initialized = true;\n this._updateDividers();\n }\n\n /**\n * Handle window minimized event.\n */\n _onWindowMinimized(e) {\n const { id, title, icon } = e.detail;\n this._minimizedWindows.set(id, { title, icon });\n this._render();\n }\n\n /**\n * Handle window restored event.\n */\n _onWindowRestored(e) {\n const { id } = e.detail;\n this._minimizedWindows.delete(id);\n this._render();\n }\n\n /**\n * Handle window closed event.\n */\n _onWindowClosed(e) {\n const { id } = e.detail;\n this._minimizedWindows.delete(id);\n this._render();\n }\n\n /**\n * Update divider visibility based on window count.\n */\n _updateDividers() {\n const hasWindows = this._minimizedWindows.size > 0;\n if (this._leftDivider) {\n this._leftDivider.style.display = hasWindows ? '' : 'none';\n }\n if (this._rightDivider) {\n this._rightDivider.style.display = hasWindows ? '' : 'none';\n }\n }\n\n /**\n * Render the taskbar buttons.\n */\n _render() {\n if (!this._containerEl) return;\n\n this._containerEl.innerHTML = '';\n\n for (const [id, { title, icon }] of this._minimizedWindows) {\n const btn = document.createElement('button');\n btn.className = 'twm-bar-windows__item';\n btn.setAttribute('data-window-id', id);\n btn.title = `Restore: ${title}`;\n\n // Add icon\n if (icon) {\n const iconEl = document.createElement('span');\n iconEl.className = 'twm-bar-windows__item-icon material-symbols-outlined';\n iconEl.textContent = icon;\n btn.appendChild(iconEl);\n }\n\n // Add title\n const titleEl = document.createElement('span');\n titleEl.className = 'twm-bar-windows__item-title';\n titleEl.textContent = title;\n btn.appendChild(titleEl);\n\n btn.addEventListener('click', () => {\n ManagedWindow.restore(id);\n });\n this._containerEl.appendChild(btn);\n }\n\n this._updateDividers();\n }\n}\n\n// Singleton instance\nexport const WindowTaskbar = new WindowTaskbarManager();\n", "/**\n * Wizard \u2014 a multi-step flow: a step indicator, a body slot and a footer with\n * Cancel, Back and Next/Finish, every step gated by its own `canAdvance`.\n *\n * Usage:\n * const wizard = new Wizard({\n * data: { file: null }, // yours; every hook sees it as ctx.data\n * steps: [\n * { id: 'source', label: 'Source', icon: 'upload_file',\n * render(bodyEl, ctx) { \u2026 ; return () => { \u2026 } }, // optional cleanup function\n * canAdvance: (ctx) => ctx.data.file\n * ? { ok: true } : { ok: false, hint: 'Choose a file first' } },\n * { id: 'review', label: 'Review', render(bodyEl, ctx) { \u2026 } },\n * ],\n * onFinish: async (ctx) => { \u2026 }, // rejects \u2192 the step shows the error\n * onCancel: (ctx) => { \u2026 },\n * });\n * wizard.mount(hostEl); // inline \u2026\n * wizard.openInWindow({ id: 'import', title: 'Import' }); // \u2026 or in a window\n *\n * Steps are drawn done / current / upcoming / error and joined by a connector.\n * A done (or errored) step BEFORE the current one is a button that jumps back;\n * a step after it is inert, so the only way forward is Next, through the gate.\n *\n * `canAdvance(ctx)` is asked whenever the footer is drawn, and `revalidate()`\n * draws it again \u2014 the body is rendered once per visit, never by a revalidate,\n * so an input the user is typing into keeps its focus and its value.\n *\n * Every move goes through a core StateMachine:\n *\n * step \u2500\u2500move\u2500\u2500\u25B6 step (guard: back to a visited step, or forward\n * \u2502 one step through the gate)\n * \u251C\u2500\u2500finish\u2500\u2500\u25B6 finishing \u2500\u2500resolve\u2500\u2500\u25B6 finished (closes)\n * \u2502 \u2502\n * \u2502 \u2514\u2500\u2500reject\u2500\u2500\u25B6 step (the step shows the error)\n * \u2514\u2500\u2500cancel\u2500\u2500\u25B6 cancelled (closes, calls onCancel)\n *\n * While `finishing`, every button is disabled and no move is accepted, so an\n * async finish cannot be raced by a click. `finished` and `cancelled` are final:\n * onCancel runs once however many times Cancel is pressed.\n *\n * State lives in this instance only; the DOM carries classes and ARIA, never a\n * data attribute.\n */\nimport { ComponentBase } from '../base/component_base.js';\nimport { StateMachine } from '../../core/state_machine.js';\nimport { ManagedWindow } from './managed_window.js';\n\nconst DEFAULT_LABELS = Object.freeze({\n back: 'Back',\n next: 'Next',\n finish: 'Finish',\n cancel: 'Cancel',\n});\n\nconst OPEN = 'step';\nconst FINISHING = 'finishing';\nconst FINISHED = 'finished';\nconst CANCELLED = 'cancelled';\n\n/** Steps own one override: an error and its message. Everything else about a\n * step's look follows from where it is relative to the current one. */\nconst STEP_STATES = Object.freeze(['error']);\n\nconst isFinal = (state) => state === FINISHED || state === CANCELLED;\n\n/** A step's render may hand back a cleanup function, run when the step is\n * left and on dispose(). */\nfunction runCleanup(cleanup) {\n if (typeof cleanup === 'function') cleanup();\n}\n\nfunction messageOf(err) {\n if (err && typeof err.message === 'string' && err.message) return err.message;\n return err == null ? 'Failed' : String(err);\n}\n\nexport class Wizard extends ComponentBase {\n\n /** @type {Array<object>} */ #steps;\n /** @type {object} */ #labels;\n /** @type {Function|null} */ #onFinish;\n /** @type {Function|null} */ #onCancel;\n /** @type {object} */ #ctx;\n /** @type {StateMachine} */ #machine;\n /** @type {number} */ #index = 0;\n /** @type {Map<string,{state:string,message:string}>} */ #overrides = new Map();\n /** @type {*} */ #cleanup = null;\n /** @type {Promise} */ #queue = Promise.resolve();\n /** @type {ManagedWindow|null} */ #window = null;\n /** @type {boolean} */ #disposed = false;\n\n /** @type {HTMLElement|null} */ #root = null;\n /** @type {HTMLElement[]} */ #stepItems = [];\n /** @type {HTMLButtonElement[]} */#stepButtons = [];\n /** @type {HTMLElement[]} */ #connectors = [];\n /** @type {HTMLElement|null} */ #body = null;\n /** @type {HTMLElement|null} */ #message = null;\n /** @type {HTMLButtonElement|null} */ #cancelBtn = null;\n /** @type {HTMLButtonElement|null} */ #backBtn = null;\n /** @type {HTMLButtonElement|null} */ #nextBtn = null;\n\n /**\n * @param {object} opts\n * @param {Array<{id:string,label:string,icon?:string,\n * render:(bodyEl:HTMLElement, ctx:object)=>(Function|void),\n * canAdvance?:(ctx:object)=>{ok:boolean,hint?:string}}>} opts.steps\n * @param {object} [opts.data={}] Your state; every hook reads it as `ctx.data`.\n * @param {Function} [opts.onFinish] `(ctx) => void|Promise`. A rejection marks the\n * current step as error with the rejection's message.\n * @param {Function} [opts.onCancel] `(ctx) => void`, called once when the wizard is cancelled.\n * @param {object} [opts.labels] `{back, next, finish, cancel}` button labels.\n * @param {object} [opts.eventBus] Passed to the StateMachine (its `fsm:*` events).\n * @param {object} [opts.logger] Passed to the StateMachine.\n */\n constructor({ steps, data = {}, onFinish = null, onCancel = null, labels = {},\n eventBus = null, logger = null } = {}) {\n super({ eventBus, logger });\n if (!Array.isArray(steps) || steps.length === 0) {\n throw new Error('Wizard requires at least one step');\n }\n const ids = new Set();\n for (const step of steps) {\n if (!step || typeof step.id !== 'string' || !step.id) {\n throw new Error('Wizard: every step needs a non-empty string id');\n }\n if (ids.has(step.id)) throw new Error(`Wizard: duplicate step id \"${step.id}\"`);\n if (typeof step.render !== 'function') {\n throw new Error(`Wizard: step \"${step.id}\" needs a render(bodyEl, ctx) function`);\n }\n ids.add(step.id);\n }\n this.#steps = steps.slice();\n this.#labels = { ...DEFAULT_LABELS, ...labels };\n this.#onFinish = onFinish;\n this.#onCancel = onCancel;\n\n const wizard = this;\n this.#ctx = Object.freeze({\n data,\n get step() { return wizard.currentStep; },\n get index() { return wizard.currentIndex; },\n revalidate: () => this.revalidate(),\n next: () => this.next(),\n back: () => this.back(),\n goTo: (target) => this.goTo(target),\n setStepState: (id, state, message) => this.setStepState(id, state, message),\n });\n\n this.#machine = new StateMachine({\n name: 'wizard',\n initialState: OPEN,\n eventBus,\n logger,\n states: {\n [OPEN]: {\n transitions: {\n move: {\n target: OPEN,\n guard: ({ payload }) => this.#canMoveTo(payload.to),\n action: ({ payload }) => this.#enterStep(payload.to),\n },\n finish: {\n target: FINISHING,\n guard: () => this.#isLast() && this.#gate().ok,\n action: () => { this.#overrides.delete(this.currentStep); },\n },\n cancel: { target: CANCELLED },\n },\n },\n [FINISHING]: {\n transitions: {\n resolve: { target: FINISHED },\n reject: {\n target: OPEN,\n action: ({ payload }) => {\n this.#overrides.set(this.currentStep,\n { state: 'error', message: messageOf(payload.error) });\n },\n },\n },\n },\n [FINISHED]: { onEnter: () => this.#close() },\n [CANCELLED]: {\n onEnter: () => {\n this.#close();\n this.#onCancel?.(this.#ctx);\n },\n },\n },\n });\n }\n\n // \u2500\u2500\u2500 Lifecycle \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 /**\n * Mount inline into `container` and render the first step.\n * @param {HTMLElement} container\n * @returns {Wizard}\n */\n mount(container) {\n if (this._mounted) return this;\n this.#build();\n container.appendChild(this.#root);\n this._mounted = true;\n this.#renderBody();\n this.#paint();\n return this;\n }\n\n /**\n * Mount in a ManagedWindow and show it. The window's close button and\n * Escape cancel the wizard (and are refused while a finish is running);\n * finishing or cancelling closes the window.\n * @param {object} [opts] ManagedWindow options: id, title, icon, defaultWidth,\n * defaultHeight, minWidth, minHeight, container, modal (default true).\n * @returns {ManagedWindow}\n */\n openInWindow({ id = 'twm-wizard', title = 'Wizard', icon, defaultWidth = 720,\n defaultHeight = 520, minWidth = 420, minHeight = 320,\n container, modal = true } = {}) {\n if (this._mounted) throw new Error('Wizard is already mounted');\n this.#build();\n this._mounted = true;\n this.#window = new ManagedWindow({\n id, title, icon, defaultWidth, defaultHeight, minWidth, minHeight,\n container, modal,\n content: this.#root,\n canMinimize: false,\n beforeClose: () => {\n if (isFinal(this.state)) return true;\n void this.cancel();\n return false;\n },\n });\n this.#window.show();\n this.#renderBody();\n this.#paint();\n return this.#window;\n }\n\n /** Tear down (and close the window, if any) without calling any callback.\n * Every later move, finish or cancel is refused. */\n dispose() {\n if (this.#disposed) return;\n this.#disposed = true;\n const win = this.#window;\n this.#teardown();\n win?.close({ force: true });\n super.dispose();\n }\n\n // \u2500\u2500\u2500 Public API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 wizard's root element (null before mount). */\n get element() { return this.#root; }\n\n /** The body slot the current step renders into. */\n get bodyElement() { return this.#body; }\n\n /** The ManagedWindow, when opened with `openInWindow`. */\n get window() { return this.#window; }\n\n /** The object every hook receives: `{data, step, index, revalidate, next, back, goTo, setStepState}`. */\n get context() { return this.#ctx; }\n\n /** The current step's id. */\n get currentStep() { return this.#steps[this.#index].id; }\n\n /** The current step's index. */\n get currentIndex() { return this.#index; }\n\n /** 'step' | 'finishing' | 'finished' | 'cancelled' (null for a moment after construction). */\n get state() { return this.#machine.getState(); }\n\n /** True while an async finish is running. */\n get busy() { return this.state === FINISHING; }\n\n /**\n * Ask the current step's `canAdvance` again and redraw the indicator and\n * the footer. The body is NOT re-rendered.\n */\n revalidate() {\n this.#paint();\n }\n\n /** Forward one step, if the current step's gate allows it. Resolves true when it moved. */\n next() {\n return this.#move(() => this.#index + 1);\n }\n\n /** Back one step. Resolves true when it moved. */\n back() {\n return this.#move(() => this.#index - 1);\n }\n\n /**\n * Move to a step by id or index: any step before the current one, or the\n * next one through the gate. Resolves true when it moved.\n * @param {string|number} target\n */\n goTo(target) {\n return this.#move(() => this.#resolveIndex(target));\n }\n\n /**\n * Mark a step as errored (`'error'`, with a message shown while it is the\n * current step), or clear the mark (`null`).\n * @param {string} id\n * @param {'error'|null} state\n * @param {string} [message]\n */\n setStepState(id, state, message = '') {\n const i = this.#resolveIndex(id);\n if (i < 0 || i >= this.#steps.length) throw new Error(`Wizard: no step \"${id}\"`);\n const key = this.#steps[i].id;\n if (state == null) this.#overrides.delete(key);\n else if (STEP_STATES.includes(state)) this.#overrides.set(key, { state, message: String(message ?? '') });\n else throw new Error(`Wizard: unknown step state \"${state}\" (expected 'error' or null)`);\n this.#paint();\n }\n\n /**\n * Run `onFinish` from the last step, if its gate allows. The buttons are\n * disabled until it settles; resolved, the wizard closes; rejected, the\n * step is marked as error with the message. Resolves true when it finished.\n */\n finish() {\n return this.#enqueue(async () => {\n if (this.state !== OPEN) return false;\n const { transitioned } = await this.#machine.transition('finish');\n if (!transitioned) return false;\n this.#paint();\n try {\n await this.#onFinish?.(this.#ctx);\n } catch (error) {\n await this.#machine.transition('reject', { error });\n this.#paint();\n return false;\n }\n await this.#machine.transition('resolve');\n return true;\n });\n }\n\n /**\n * Close the wizard and call `onCancel` \u2014 once. Refused while a finish is\n * running. Resolves true when it cancelled.\n */\n cancel() {\n return this.#enqueue(async () => {\n if (this.state !== OPEN) return false;\n const { transitioned } = await this.#machine.transition('cancel');\n return transitioned;\n });\n }\n\n // \u2500\u2500\u2500 Moves \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 /** Moves run one at a time, so a double click cannot start a transition\n * inside another. The target is computed when the move runs, not when it\n * was asked for. A request made while a finish is running (or after the\n * wizard closed) is refused there and then \u2014 it is not queued behind the\n * finish to run once it settles. */\n #enqueue(fn) {\n if (this.#disposed || this.busy || isFinal(this.state)) return Promise.resolve(false);\n const run = this.#queue.then(() => (this.#disposed ? false : fn()));\n this.#queue = run.catch(() => {});\n return run;\n }\n\n #move(targetOf) {\n return this.#enqueue(async () => {\n if (this.state !== OPEN) return false;\n const to = targetOf();\n if (!this.#canMoveTo(to)) return false;\n const { transitioned } = await this.#machine.transition('move', { to });\n this.#paint();\n return transitioned;\n });\n }\n\n #canMoveTo(to) {\n if (!Number.isInteger(to) || to < 0 || to >= this.#steps.length) return false;\n if (to < this.#index) return true;\n return to === this.#index + 1 && this.#gate().ok;\n }\n\n #enterStep(to) {\n this.#index = to;\n this.#renderBody();\n }\n\n #resolveIndex(target) {\n if (typeof target === 'number') return Number.isInteger(target) ? target : -1;\n return this.#steps.findIndex((s) => s.id === target);\n }\n\n #isLast() {\n return this.#index === this.#steps.length - 1;\n }\n\n /** The current step's gate, normalised to `{ok, hint}`. */\n #gate() {\n const step = this.#steps[this.#index];\n if (typeof step.canAdvance !== 'function') return { ok: true, hint: '' };\n const r = step.canAdvance(this.#ctx) ?? {};\n return { ok: r.ok === true, hint: typeof r.hint === 'string' ? r.hint : '' };\n }\n\n // \u2500\u2500\u2500 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\u2500\u2500\u2500\u2500\u2500\u2500\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 #build() {\n const root = document.createElement('div');\n root.className = 'twm-wizard';\n\n const steps = document.createElement('ol');\n steps.className = 'twm-wizard__steps';\n this.#steps.forEach((step, i) => {\n if (i > 0) {\n const connector = document.createElement('li');\n connector.className = 'twm-wizard__connector';\n connector.setAttribute('role', 'presentation');\n connector.setAttribute('aria-hidden', 'true');\n steps.appendChild(connector);\n this.#connectors.push(connector);\n }\n const item = document.createElement('li');\n item.className = 'twm-wizard__step';\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = 'twm-wizard__step-btn';\n const marker = document.createElement('span');\n marker.className = 'twm-wizard__step-marker';\n const label = document.createElement('span');\n label.className = 'twm-wizard__step-label';\n label.textContent = step.label ?? step.id;\n btn.append(marker, label);\n btn.addEventListener('click', () => this.#onStepClick(i));\n item.appendChild(btn);\n steps.appendChild(item);\n this.#stepItems.push(item);\n this.#stepButtons.push(btn);\n });\n\n this.#body = document.createElement('div');\n this.#body.className = 'twm-wizard__body';\n\n const footer = document.createElement('div');\n footer.className = 'twm-wizard__footer';\n this.#message = document.createElement('div');\n this.#message.className = 'twm-wizard__message';\n this.#message.setAttribute('aria-live', 'polite');\n\n const actions = document.createElement('div');\n actions.className = 'twm-wizard__actions';\n this.#cancelBtn = this.#button('twm-wizard__cancel', this.#labels.cancel, () => { void this.cancel(); });\n this.#backBtn = this.#button('twm-wizard__back', this.#labels.back, () => { void this.back(); });\n this.#nextBtn = this.#button('twm-wizard__next twm-btn--primary', this.#labels.next, () => {\n void (this.#isLast() ? this.finish() : this.next());\n });\n actions.append(this.#cancelBtn, this.#backBtn, this.#nextBtn);\n footer.append(this.#message, actions);\n\n root.append(steps, this.#body, footer);\n this.#root = root;\n }\n\n #button(cls, text, onClick) {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = `twm-btn ${cls}`;\n btn.textContent = text;\n btn.addEventListener('click', onClick);\n return btn;\n }\n\n #onStepClick(i) {\n if (i < this.#index) void this.goTo(i);\n }\n\n #renderBody() {\n runCleanup(this.#cleanup);\n this.#cleanup = null;\n this.#body.replaceChildren();\n const step = this.#steps[this.#index];\n this.#cleanup = step.render(this.#body, this.#ctx) ?? null;\n }\n\n /** The visual state of step `i`: an override, else its position. */\n #stepState(i) {\n const override = this.#overrides.get(this.#steps[i].id);\n if (override) return override.state;\n if (i < this.#index) return 'done';\n return i === this.#index ? 'current' : 'upcoming';\n }\n\n #paint() {\n if (!this.#root) return;\n const busy = this.busy;\n this.#root.classList.toggle('twm-wizard--busy', busy);\n this.#root.setAttribute('aria-busy', busy ? 'true' : 'false');\n\n this.#steps.forEach((step, i) => {\n const state = this.#stepState(i);\n const item = this.#stepItems[i];\n for (const s of ['done', 'current', 'upcoming', 'error']) {\n item.classList.toggle(`twm-wizard__step--${s}`, s === state);\n }\n item.classList.toggle('twm-wizard__step--active', i === this.#index);\n const btn = this.#stepButtons[i];\n btn.disabled = busy || i >= this.#index;\n if (i === this.#index) btn.setAttribute('aria-current', 'step');\n else btn.removeAttribute('aria-current');\n const override = this.#overrides.get(step.id);\n btn.title = override?.message || step.label || step.id;\n\n const marker = btn.firstChild;\n const glyph = state === 'done' ? 'check' : state === 'error' ? 'error' : (step.icon || '');\n marker.classList.toggle('material-symbols-outlined', Boolean(glyph));\n marker.textContent = glyph || String(i + 1);\n if (i > 0) {\n this.#connectors[i - 1].classList.toggle('twm-wizard__connector--done', i <= this.#index);\n }\n });\n\n const gate = this.#gate();\n const last = this.#isLast();\n this.#nextBtn.textContent = last ? this.#labels.finish : this.#labels.next;\n this.#nextBtn.disabled = busy || !gate.ok;\n this.#nextBtn.title = gate.ok ? '' : gate.hint;\n this.#backBtn.disabled = busy || this.#index === 0;\n this.#cancelBtn.disabled = busy;\n\n const error = this.#overrides.get(this.currentStep);\n const text = error ? error.message : (gate.ok ? '' : gate.hint);\n this.#message.textContent = text;\n this.#message.classList.toggle('twm-wizard__message--error', Boolean(error));\n this.#message.classList.toggle('twm-wizard__message--hint', !error && Boolean(text));\n if (error) this.#message.setAttribute('role', 'alert');\n else this.#message.removeAttribute('role');\n }\n\n #close() {\n const win = this.#window;\n this.#teardown();\n this._mounted = false;\n win?.close({ force: true });\n }\n\n #teardown() {\n runCleanup(this.#cleanup);\n this.#cleanup = null;\n this.#root?.remove();\n this.#root = null;\n this.#body = null;\n this.#message = null;\n this.#stepItems = [];\n this.#stepButtons = [];\n this.#connectors = [];\n this.#cancelBtn = this.#backBtn = this.#nextBtn = null;\n }\n}\n", "/**\n * WindowChromeController\n *\n * Handles frameless window management for the desktop application:\n * - Window minimize, maximize, close buttons\n * - Resize handles (edges and corners)\n * - Top bar dragging for window movement\n * - F11 fullscreen toggle\n *\n * Talks to the embedder ONLY through a Host's `window` capability\n * (see src/host/host.js). A host with no `window` capability \u2014 a browser\n * tab, a VS Code webview, the standalone demo \u2014 is legal: we simply don't\n * install custom chrome. That degraded path is also the production path on\n * Linux, macOS and `--browser`, where the OS/browser draws the title bar.\n *\n * THREE MODES, decided by `host.window.chrome()` (which may answer with a\n * promise: the Photino host asks its native side): a browser tab and a window\n * with native chrome get NOTHING from this class (no handles, no buttons, no\n * body class), and only a window that answers `custom` gets the chrome.\n *\n * NATIVE GESTURES. A host that offers `startNativeDrag()` and\n * `startNativeResize(edge)` gets drags on the top bar and presses on the\n * resize handles handed to the OS, which brings snapping and a resize that\n * keeps up with the pointer. A host without them gets the JS move and resize\n * over getBounds/setBounds.\n *\n * @param {object} [opts]\n * @param {object} [opts.host] a Host; only its `window` capability is used\n * @param {string|Element} [opts.topBar='.twm-global-top-bar'] the bar that drags the window\n * @param {string|Element} [opts.controls] where to draw minimise/maximise/close when\n * the page has no `#win-minimize`/`#win-maximize`/`#win-close` of its own\n * (default: the top bar's `.twm-bar-right`, else the top bar itself)\n * @param {string} [opts.noDrag] more selectors that never start a drag\n */\n\nconst SUPPORTS_POINTER = typeof window !== 'undefined' && 'onpointerdown' in window;\nconst MIN_WIDTH = 500;\nconst MIN_HEIGHT = 350;\nconst DRAG_THRESHOLD = 4;\n\nexport class WindowChromeController {\n constructor({ eventBus, logger, host, topBar = '.twm-global-top-bar', controls = null, noDrag = '' } = {}) {\n this.eventBus = eventBus;\n this.logger = logger || console;\n this._topBarOpt = topBar;\n this._controlsOpt = controls;\n this._noDrag = noDrag;\n this._createdControls = null;\n\n // The host's window capability, or null. Never throw on a missing\n // one \u2014 see the class comment.\n this.win = host?.window || null;\n\n this.resizingActive = false;\n this.lastDblClickTs = 0;\n this.handles = {};\n this.topBar = null;\n\n this._disposed = false;\n this._disposers = [];\n }\n\n /**\n * Initialize the window chrome controller\n */\n async initialize() {\n if (this._disposed) return false;\n\n let chrome = 'native';\n try { chrome = this.win ? await this.win.chrome() : 'native'; } catch (_) { chrome = 'native'; }\n if (this._disposed) return false;\n if (chrome !== 'custom') {\n // Native window decorations (Linux/macOS) or the browser already\n // provide a title bar + window controls; our custom chrome would be\n // a redundant second set. Skip it entirely.\n this.logger.info?.('[WindowChrome] Native/browser chrome detected \u2014 custom window chrome disabled');\n return false;\n }\n\n document.body.classList.add('twm-custom-chrome');\n this.#createWindowControls();\n this.#wireWindowButtons();\n this.#createResizeHandles();\n this.#wireTopBarDrag();\n this.#wireKeyboardShortcuts();\n this.#wireNativeStateSync();\n this.#initializeState();\n \n this.logger.info?.('[WindowChrome] Initialized');\n return true;\n }\n\n /** An element from a selector or an element; null when there is none. */\n #resolve(target, within = document) {\n if (!target) return null;\n if (typeof target !== 'string') return target;\n return within.querySelector(target);\n }\n\n /**\n * Draw minimise, maximise/restore and close, unless the page has its own\n * `#win-*` buttons (an embedder's own markup), which are then wired instead.\n */\n #createWindowControls() {\n if (document.getElementById('win-minimize') || document.getElementById('win-close')) return;\n const bar = this.#resolve(this._topBarOpt);\n const host = this.#resolve(this._controlsOpt)\n || bar?.querySelector('.twm-bar-right')\n || bar;\n if (!host) return;\n const box = document.createElement('div');\n box.className = 'twm-window-controls';\n const button = (id, icon, label, extra = '') => {\n const b = document.createElement('button');\n b.type = 'button';\n b.id = id;\n b.className = `twm-window-controls__btn${extra}`;\n b.setAttribute('aria-label', label);\n b.title = label;\n const i = document.createElement('span');\n i.className = 'material-symbols-outlined';\n i.textContent = icon;\n b.appendChild(i);\n box.appendChild(b);\n };\n button('win-minimize', 'remove', 'Minimize');\n button('win-maximize', 'check_box_outline_blank', 'Maximize');\n button('win-close', 'close', 'Close', ' twm-window-controls__btn--close');\n host.appendChild(box);\n this._createdControls = box;\n }\n\n /**\n * Wire minimize, maximize, close buttons\n */\n #wireWindowButtons() {\n const minBtn = document.getElementById('win-minimize');\n const maxBtn = document.getElementById('win-maximize');\n const closeBtn = document.getElementById('win-close');\n\n if (minBtn) {\n const handler = () => this.win.minimize();\n minBtn.addEventListener('click', handler);\n this._disposers.push(() => minBtn.removeEventListener('click', handler));\n }\n\n if (maxBtn) {\n const handler = async () => {\n try {\n const isMax = await this.win.setMaximized(!(await this.win.isMaximized()));\n this.#updateMaximizeIcon(isMax);\n this.#setResizeHandlesEnabled(!isMax);\n } catch (e) {\n this.logger.warn?.('[WindowChrome] Maximize toggle failed', e);\n }\n };\n maxBtn.addEventListener('click', handler);\n this._disposers.push(() => maxBtn.removeEventListener('click', handler));\n }\n\n if (closeBtn) {\n const handler = () => this.win.close();\n closeBtn.addEventListener('click', handler);\n this._disposers.push(() => closeBtn.removeEventListener('click', handler));\n }\n }\n\n /**\n * Update maximize button icon and body class\n */\n #updateMaximizeIcon(isMax) {\n const maxBtn = document.getElementById('win-maximize');\n if (!maxBtn) return;\n \n const icon = maxBtn.querySelector('.material-symbols-outlined');\n if (icon) {\n icon.textContent = isMax ? 'filter_none' : 'check_box_outline_blank';\n }\n const tooltipText = isMax ? 'Restore' : 'Maximize';\n window.LatexTooltip?.set(maxBtn, tooltipText);\n maxBtn.setAttribute('aria-label', tooltipText);\n maxBtn.title = tooltipText;\n \n document.body.classList.toggle('twm-window-maximized', isMax);\n }\n\n /**\n * Enable/disable resize handles\n */\n #setResizeHandlesEnabled(enabled) {\n Object.values(this.handles).forEach(handle => {\n if (handle) {\n handle.style.pointerEvents = enabled ? 'auto' : 'none';\n }\n });\n }\n\n /**\n * Set fullscreen body class\n */\n #setFullscreenClass(isFs) {\n document.body.classList.toggle('window-fullscreen', isFs);\n }\n\n /**\n * Create all resize handles\n */\n #createResizeHandles() {\n const positions = ['right', 'left', 'top', 'bottom'];\n const corners = ['br', 'bl', 'tr', 'tl'];\n\n positions.forEach(pos => {\n const handle = document.createElement('div');\n handle.className = `twm-resize-handle ${pos}`;\n document.body.appendChild(handle);\n this.handles[pos] = handle;\n this.#setupResize(handle, pos);\n });\n\n corners.forEach(corner => {\n const handle = document.createElement('div');\n handle.className = `twm-resize-handle corner ${corner}`;\n document.body.appendChild(handle);\n const mode = 'corner' + corner.toUpperCase();\n this.handles[mode] = handle;\n this.#setupResize(handle, mode);\n });\n }\n\n /**\n * Setup resize behavior for a handle\n */\n #setupResize(handle, mode) {\n let startX = 0, startY = 0, startScreenX = 0, startScreenY = 0;\n let startW = 0, startH = 0, startLeft = 0, startTop = 0;\n let pending = null;\n let rafScheduled = false;\n let lastSent = null;\n\n const boundsEqual = (a, b) => {\n return !!a && !!b && a.x === b.x && a.y === b.y && a.w === b.w && a.h === b.h;\n };\n\n const sendBounds = () => {\n rafScheduled = false;\n if (!pending) return;\n if (lastSent && boundsEqual(lastSent, pending)) return;\n this.win.setBounds({ x: pending.x, y: pending.y, width: pending.w, height: pending.h });\n lastSent = pending;\n };\n\n const scheduleSend = () => {\n if (!rafScheduled) {\n rafScheduled = true;\n requestAnimationFrame(sendBounds);\n }\n };\n\n let activePointerId = null;\n\n const EDGE = {\n right: 'e', left: 'w', top: 'n', bottom: 's',\n cornerBR: 'se', cornerBL: 'sw', cornerTR: 'ne', cornerTL: 'nw',\n };\n\n const startDrag = async (e) => {\n if (e.button != null && e.button !== 0) return;\n e.preventDefault();\n // \u2500\u2500 Native resize: the OS runs its own size loop (it blocks until\n // mouse-up), so the edge stays under the pointer. \u2500\u2500\n if (this.win.startNativeResize) {\n this.resizingActive = true;\n let handled = false;\n try { handled = await this.win.startNativeResize(EDGE[mode]); } catch (_) { handled = false; }\n this.resizingActive = false;\n if (handled) return;\n }\n this.resizingActive = true;\n startX = e.clientX;\n startY = e.clientY;\n startScreenX = e.screenX ?? startX;\n startScreenY = e.screenY ?? startY;\n\n try {\n const res = await this.win.getBounds();\n if (res) {\n startLeft = typeof res.x === 'number' ? res.x : 0;\n startTop = typeof res.y === 'number' ? res.y : 0;\n startW = res.width || document.documentElement.clientWidth;\n startH = res.height || document.documentElement.clientHeight;\n } else {\n startLeft = 0;\n startTop = 0;\n startW = document.documentElement.clientWidth;\n startH = document.documentElement.clientHeight;\n }\n } catch (e) {\n startLeft = 0;\n startTop = 0;\n startW = document.documentElement.clientWidth;\n startH = document.documentElement.clientHeight;\n }\n\n startLeft = Math.round(startLeft);\n startTop = Math.round(startTop);\n startW = Math.round(startW);\n startH = Math.round(startH);\n pending = null;\n lastSent = null;\n rafScheduled = false;\n\n // Capture pointer for smooth resize even when cursor escapes the handle\n if (SUPPORTS_POINTER && e.pointerId != null && handle.setPointerCapture) {\n try {\n handle.setPointerCapture(e.pointerId);\n activePointerId = e.pointerId;\n } catch (_) {}\n }\n\n if (SUPPORTS_POINTER) {\n window.addEventListener('pointermove', onMove, { passive: false });\n window.addEventListener('pointerup', endDrag, { once: true });\n } else {\n window.addEventListener('mousemove', onMove, { passive: false });\n window.addEventListener('mouseup', endDrag, { once: true });\n }\n };\n\n const onMove = (e) => {\n const sx = e.screenX ?? e.clientX ?? 0;\n const sy = e.screenY ?? e.clientY ?? 0;\n const dx = sx - startScreenX;\n const dy = sy - startScreenY;\n\n let newX = startLeft;\n let newY = startTop;\n let newW = startW;\n let newH = startH;\n\n const isLeft = mode === 'left' || mode === 'cornerBL' || mode === 'cornerTL';\n const isRight = mode === 'right' || mode === 'cornerBR' || mode === 'cornerTR';\n const isTop = mode === 'top' || mode === 'cornerTR' || mode === 'cornerTL';\n const isBottom = mode === 'bottom' || mode === 'cornerBR' || mode === 'cornerBL';\n\n if (isLeft) {\n const candidateWidth = startW - dx;\n newW = Math.max(MIN_WIDTH, candidateWidth);\n const shift = startW - newW;\n newX = startLeft + shift;\n } else if (isRight) {\n newW = Math.max(MIN_WIDTH, startW + dx);\n }\n\n if (isTop) {\n const candidateHeight = startH - dy;\n newH = Math.max(MIN_HEIGHT, candidateHeight);\n const shiftY = startH - newH;\n newY = startTop + shiftY;\n } else if (isBottom) {\n newH = Math.max(MIN_HEIGHT, startH + dy);\n }\n\n newX = Math.round(newX);\n newY = Math.round(newY);\n newW = Math.max(MIN_WIDTH, Math.round(newW));\n newH = Math.max(MIN_HEIGHT, Math.round(newH));\n\n pending = { x: newX, y: newY, w: newW, h: newH };\n scheduleSend();\n };\n\n const endDrag = () => {\n if (SUPPORTS_POINTER) {\n window.removeEventListener('pointermove', onMove);\n } else {\n window.removeEventListener('mousemove', onMove);\n }\n // Release pointer capture\n if (activePointerId != null && handle.releasePointerCapture) {\n try { handle.releasePointerCapture(activePointerId); } catch (_) {}\n activePointerId = null;\n }\n // Flush any pending bounds update that was waiting for rAF\n if (pending && (!lastSent || !boundsEqual(lastSent, pending))) {\n this.win.setBounds({ x: pending.x, y: pending.y, width: pending.w, height: pending.h });\n }\n pending = null;\n lastSent = null;\n this.resizingActive = false;\n };\n\n const event = SUPPORTS_POINTER ? 'pointerdown' : 'mousedown';\n handle.addEventListener(event, startDrag);\n this._disposers.push(() => handle.removeEventListener(event, startDrag));\n }\n\n /**\n * Setup top bar dragging for window movement\n */\n #wireTopBarDrag() {\n this.topBar = this.#resolve(this._topBarOpt);\n if (!this.topBar) return;\n\n // What never starts a drag: anything you can click or type into. An\n // embedder adds its own with `noDrag`. (`.window-controls` and\n // `.panel-toggles` are kept for embedders' own markup of that shape.)\n const NO_DRAG_SELECTOR = [\n '.no-drag', 'button', 'a', 'input', 'select', 'textarea', 'label',\n '[role=\"button\"]', '[role=\"menuitem\"]', '[role=\"tab\"]', '[contenteditable=\"true\"]',\n '.twm-window-controls', '.window-controls', '.panel-toggles',\n this._noDrag,\n ].filter(Boolean).join(', ');\n\n let dragging = false;\n let startSX = 0, startSY = 0, startX = null, startY = null, winW = 0, winH = 0;\n let wasMax = false;\n let didRestore = false;\n let grabRatio = 0.5;\n let raf = null;\n let lastSentX = null, lastSentY = null;\n let activePointerId = null;\n\n // Double-click detection (native drag swallows dblclick events)\n const DBL_CLICK_TIME = 500;\n const DBL_CLICK_DIST = 4;\n let lastDownTime = 0;\n let lastDownX = 0;\n let lastDownY = 0;\n\n const isInteractiveTarget = (t) => !!(t && t.closest && t.closest(NO_DRAG_SELECTOR));\n\n const onMove = (e) => {\n // IMPORTANT: This must NOT be async to avoid race conditions on first drag\n const sx = e.screenX ?? e.clientX ?? 0;\n const sy = e.screenY ?? e.clientY ?? 0;\n const dx = Math.abs(sx - startSX);\n const dy = Math.abs(sy - startSY);\n\n if (!dragging) {\n if (wasMax) {\n if ((dx + dy) <= 0) return;\n // Handle restore from maximized state\n if (!didRestore) {\n didRestore = true;\n // Fire-and-forget the restore, then reposition\n this.win.setMaximized(false).then(() => {\n this.#updateMaximizeIcon(false);\n this.#setResizeHandlesEnabled(true);\n return this.win.getBounds();\n }).then((bounds) => {\n if (bounds) {\n const rw = bounds.width || 800;\n const rh = bounds.height || 600;\n const targetX = Math.max(0, Math.round(startSX - (rw * grabRatio)));\n const targetY = Math.max(0, Math.round(sy - 10));\n this.win.setBounds({ x: targetX, y: targetY, width: rw, height: rh });\n startX = targetX;\n startY = targetY;\n winW = rw;\n winH = rh;\n startSX = sx;\n startSY = sy;\n }\n }).catch((err) => {\n this.logger.warn?.('[WindowChrome] Restore on drag failed', err);\n });\n }\n return; // Don't proceed with normal drag until restore completes\n } else {\n if ((dx + dy) < DRAG_THRESHOLD) return;\n // startX/startY should already be set by startDrag - if not, skip this move\n if (startX == null || startY == null) {\n return;\n }\n }\n dragging = true;\n }\n\n // Use the bounds fetched in startDrag (never default to 0)\n if (startX == null || startY == null) return;\n\n const nx = Math.round(startX + (sx - startSX));\n const ny = Math.round(startY + (sy - startSY));\n\n if (lastSentX === nx && lastSentY === ny) return;\n\n if (raf) cancelAnimationFrame(raf);\n raf = requestAnimationFrame(() => {\n lastSentX = nx;\n lastSentY = ny;\n this.win.setBounds({ x: nx, y: ny });\n });\n };\n\n const endDrag = () => {\n dragging = false;\n if (raf) {\n cancelAnimationFrame(raf);\n raf = null;\n }\n if (activePointerId != null && this.topBar.releasePointerCapture) {\n try {\n this.topBar.releasePointerCapture(activePointerId);\n } catch (e) {}\n }\n activePointerId = null;\n didRestore = false;\n\n if (SUPPORTS_POINTER) {\n window.removeEventListener('pointermove', onMove, true);\n window.removeEventListener('pointerup', endDrag, true);\n } else {\n window.removeEventListener('mousemove', onMove, true);\n window.removeEventListener('mouseup', endDrag, true);\n }\n };\n\n const startDrag = async (e) => {\n if (this.resizingActive) return;\n if (isInteractiveTarget(e.target)) return;\n if ((Date.now() - this.lastDblClickTs) < 300) return;\n\n // Detect double-click before entering native drag (which\n // blocks the message loop and prevents dblclick events).\n const now = Date.now();\n const cx = e.clientX ?? 0;\n const cy = e.clientY ?? 0;\n if ((now - lastDownTime) < DBL_CLICK_TIME\n && Math.abs(cx - lastDownX) < DBL_CLICK_DIST\n && Math.abs(cy - lastDownY) < DBL_CLICK_DIST) {\n lastDownTime = 0;\n this.lastDblClickTs = now;\n e.preventDefault();\n try {\n const isMax = await this.win.setMaximized(!(await this.win.isMaximized()));\n this.#updateMaximizeIcon(isMax);\n this.#setResizeHandlesEnabled(!isMax);\n } catch (err) {\n this.logger.warn?.('[WindowChrome] Double-click maximize failed', err);\n }\n return;\n }\n lastDownTime = now;\n lastDownX = cx;\n lastDownY = cy;\n\n try {\n if (!this.win) return;\n\n // \u2500\u2500 Native drag (enables Aero Snap) \u2500\u2500\n // The call blocks until the OS drag loop ends (mouse-up).\n // On return the window has already moved/snapped.\n if (this.win.startNativeDrag) {\n e.preventDefault();\n if (await this.win.startNativeDrag()) {\n // Sync UI state after native drag (may have snapped/maximized)\n try {\n const isMax = await this.win.isMaximized();\n this.#updateMaximizeIcon(isMax);\n this.#setResizeHandlesEnabled(!isMax);\n } catch (_) {}\n return;\n }\n // Native drag unavailable \u2014 fall through to JS drag\n }\n\n // \u2500\u2500 JS drag fallback (non-Windows) \u2500\u2500\n startSX = e.screenX ?? e.clientX ?? 0;\n startSY = e.screenY ?? e.clientY ?? 0;\n\n try {\n wasMax = await this.win.isMaximized();\n } catch (e) {\n wasMax = false;\n }\n\n const barWidth = Math.max(1, window.innerWidth || document.documentElement.clientWidth);\n grabRatio = Math.min(1, Math.max(0, (e.clientX || 0) / barWidth));\n\n if (!wasMax) {\n const bounds = await this.win.getBounds();\n if (bounds) {\n startX = typeof bounds.x === 'number' ? bounds.x : (window.screenX ?? 0);\n startY = typeof bounds.y === 'number' ? bounds.y : (window.screenY ?? 0);\n winW = bounds.width || document.documentElement.clientWidth;\n winH = bounds.height || document.documentElement.clientHeight;\n } else {\n startX = window.screenX ?? 0;\n startY = window.screenY ?? 0;\n winW = document.documentElement.clientWidth;\n winH = document.documentElement.clientHeight;\n }\n }\n\n e.preventDefault();\n\n if (SUPPORTS_POINTER && e.pointerId != null && this.topBar.setPointerCapture) {\n try {\n this.topBar.setPointerCapture(e.pointerId);\n activePointerId = e.pointerId;\n } catch (e) {}\n }\n\n if (SUPPORTS_POINTER) {\n window.addEventListener('pointermove', onMove, true);\n window.addEventListener('pointerup', endDrag, true);\n } else {\n window.addEventListener('mousemove', onMove, true);\n window.addEventListener('mouseup', endDrag, true);\n }\n } catch (err) {\n this.logger.warn?.('[WindowChrome] Start drag failed', err);\n }\n };\n\n // Block drag during resize\n const blocker = (e) => {\n if (this.resizingActive) {\n e.preventDefault();\n e.stopPropagation();\n }\n };\n this.topBar.addEventListener('mousedown', blocker, true);\n this.topBar.addEventListener('pointerdown', blocker, true);\n\n // Double-click to toggle maximize (only on blank surfaces)\n const dblClickHandler = async (e) => {\n // Skip maximize if double-click is on interactive elements\n if (isInteractiveTarget(e.target)) {\n return;\n }\n\n this.lastDblClickTs = Date.now();\n e.preventDefault();\n e.stopPropagation();\n if (this.resizingActive) return;\n\n try {\n const isMax = await this.win.setMaximized(!(await this.win.isMaximized()));\n this.#updateMaximizeIcon(isMax);\n this.#setResizeHandlesEnabled(!isMax);\n } catch (e) {\n this.logger.warn?.('[WindowChrome] Double-click maximize failed', e);\n }\n };\n this.topBar.addEventListener('dblclick', dblClickHandler);\n\n // Start drag\n const event = SUPPORTS_POINTER ? 'pointerdown' : 'mousedown';\n this.topBar.addEventListener(event, startDrag, false);\n\n this._disposers.push(() => {\n this.topBar.removeEventListener('mousedown', blocker, true);\n this.topBar.removeEventListener('pointerdown', blocker, true);\n this.topBar.removeEventListener('dblclick', dblClickHandler);\n this.topBar.removeEventListener(event, startDrag, false);\n });\n }\n\n /**\n * Listen for browser resize events to sync UI with native state changes\n * (e.g. Win+Arrow maximize/restore, Win+Down minimize).\n */\n #wireNativeStateSync() {\n let syncTimer = null;\n const syncState = async () => {\n if (this.resizingActive || this._disposed) return;\n try {\n if (!this.win) return;\n const isMax = await this.win.isMaximized();\n this.#updateMaximizeIcon(isMax);\n this.#setResizeHandlesEnabled(!isMax);\n } catch (_) {}\n };\n const handler = () => {\n // Debounce: native snap triggers multiple resize events\n clearTimeout(syncTimer);\n syncTimer = setTimeout(syncState, 80);\n };\n window.addEventListener('resize', handler);\n this._disposers.push(() => {\n window.removeEventListener('resize', handler);\n clearTimeout(syncTimer);\n });\n }\n\n /**\n * Wire F11 fullscreen toggle\n */\n #wireKeyboardShortcuts() {\n const handler = async (e) => {\n if (e.code === 'F11') {\n e.preventDefault();\n try {\n const isFs = await this.win.toggleFullscreen();\n this.#setFullscreenClass(isFs);\n const max = await this.win.isMaximized();\n this.#setResizeHandlesEnabled(!(isFs || max));\n } catch (e) {\n this.logger.warn?.('[WindowChrome] F11 toggle failed', e);\n }\n }\n };\n window.addEventListener('keydown', handler, true);\n this._disposers.push(() => window.removeEventListener('keydown', handler, true));\n }\n\n /**\n * Initialize window state on startup\n */\n async #initializeState() {\n try {\n if (!this.win) return;\n\n const isMax = await this.win.isMaximized();\n this.#updateMaximizeIcon(isMax);\n this.#setResizeHandlesEnabled(!isMax);\n\n const isFs = await this.win.isFullscreen();\n this.#setFullscreenClass(isFs);\n if (isFs) this.#setResizeHandlesEnabled(false);\n } catch (e) {\n this.logger.warn?.('[WindowChrome] Initial state check failed', e);\n }\n }\n\n /**\n * Dispose of the controller\n */\n dispose() {\n if (this._disposed) return;\n this._disposed = true;\n\n this._disposers.forEach(dispose => {\n try {\n dispose();\n } catch (e) {}\n });\n this._disposers = [];\n\n // Remove resize handles, and the buttons this drew\n Object.values(this.handles).forEach(handle => {\n if (handle && handle.parentNode) {\n handle.parentNode.removeChild(handle);\n }\n });\n this.handles = {};\n this._createdControls?.remove();\n this._createdControls = null;\n document.body.classList.remove('twm-custom-chrome', 'twm-window-maximized', 'window-fullscreen');\n\n this.logger.info?.('[WindowChrome] Disposed');\n }\n}\n", "/**\n * Notification Center (js_new)\n *\n * Purpose\n * -------\n * Unified notifications/toasts/status-line controller consuming events from the rest of the app.\n *\n * Responsibilities\n * - Render queued notifications with namespace context and severity.\n * - Ingest `log:*` and domain-specific events to present user-facing feedback.\n * - Replace scattered `window.notify` / `status_view.js` hooks.\n *\n * Source Material\n * - html/js/status_view.js and ui_manager.js toast helpers.\n * - html/js/ui_utilities.js notification utilities.\n *\n * Progress toasts (0.17.0)\n * ------------------------\n * `show({ progress })` makes a toast that tracks a job: `progress` is a 0..1\n * fraction, `{ value, total }`, or `null` for indeterminate; `status` is a line\n * under the message and `counts` a label beside the bar. Such a toast is\n * persistent and collapsible, and it RUNS until `update()` gives it an outcome\n * severity (success, error or fatal), which ends its bar (done or error) for\n * good and lets a `durationMs` in the same patch dismiss it. Every toast is\n * drawn once and then patched: `update()` touches only its own nodes, and a\n * toast arriving or leaving moves no other toast's element, so a bar, a\n * collapsed state and a hovered button survive. A running progress toast is\n * never held behind \"+N more\" (and never dropped by 'drop'); it counts toward\n * `maxVisible`, so it takes the place of the newest other toast.\n *\n * History subscribers (0.17.3)\n * ----------------------------\n * `history` holds one entry per toast, whichever way it came (`show()`, the\n * `warn()`/`error()`/... helpers, `toast:show`, `notification:show`,\n * `log:entry`). A toast that leaves marks its own entry `dismissed` with a\n * `reason`; it adds none. `subscribe(fn)` calls `fn(entry, center)` for each\n * entry added, so a history view follows the centre rather than the bus.\n */\nimport { ComponentBase } from './base/component_base.js';\nimport { getSetting } from '../core/settings.js';\nimport { setToastBus, getToastBus } from './components/toast.js';\nimport { ProgressBar } from './components/progress.js';\n\nconst SEVERITIES = ['info', 'success', 'warn', 'error', 'fatal'];\n\n/** The severity a progress toast finishes with, and the state its bar ends in. */\nconst OUTCOME_BAR_STATE = Object.freeze({ success: 'done', error: 'error', fatal: 'error' });\nconst LOG_SEVERITY_MAP = {\n trace: 'info',\n debug: 'info',\n info: 'info',\n warn: 'warn',\n error: 'error',\n fatal: 'fatal',\n};\n\nconst DEFAULT_LOG_LEVELS = new Set(['warn', 'error', 'fatal']);\n\n// Internal namespace identifiers that should not be shown as toast titles.\n// Messages from these namespaces are self-descriptive and need no category header.\nconst SUPPRESSED_NAMESPACE_TITLES = new Set(['bootstrap', 'app']);\n\nexport class NotificationCenter extends ComponentBase {\n #items;\n #summaryEl;\n #historyListeners;\n\n constructor({\n eventBus,\n logger,\n maxVisible = 3,\n historyLimit = 50,\n defaultDurationMs = 6000,\n logLevels = DEFAULT_LOG_LEVELS,\n // What happens past `maxVisible`. 'drop' (the default, as before 0.11):\n // the oldest toast leaves. 'collapse': the toasts on screen stay, the\n // rest wait behind one \"+N more\" toast, and each comes in as one closes\n // \u2014 a sticky alert nobody has read is never pushed off unseen.\n overflow = 'drop',\n // Called with the held-back toasts when the \"+N more\" toast is clicked.\n summaryAction = null,\n } = {}) {\n super({ eventBus, logger });\n\n this.maxVisible = maxVisible;\n this.overflow = overflow === 'collapse' ? 'collapse' : 'drop';\n this.summaryAction = typeof summaryAction === 'function' ? summaryAction : null;\n /** Toasts waiting behind the \"+N more\" summary ('collapse' only), oldest first. */\n this.held = [];\n this.historyLimit = historyLimit;\n this.defaultDurationMs = defaultDurationMs;\n this.logLevels = new Set(logLevels ?? DEFAULT_LOG_LEVELS);\n\n this.notifications = [];\n this.history = [];\n this.sequence = 0;\n this.activeTimers = new Map();\n this.eventDisposers = [];\n /** id -> the drawn toast's nodes, for the toasts on screen. */\n this.#items = new Map();\n this.#summaryEl = null;\n this.#historyListeners = new Set();\n\n this.container = null;\n this.rootEl = null;\n this.listEl = null;\n this.liveRegionEl = null;\n }\n\n mount(container, props = {}) {\n // Always mount to document.body for reliable visibility\n // The passed container is ignored - we create our own fixed-position container\n const existingContainer = document.getElementById('notification-center-root');\n if (existingContainer) {\n this.container = existingContainer;\n this.rootEl = existingContainer.querySelector('.twm-notification-center');\n this.listEl = existingContainer.querySelector('.twm-notification-center__list');\n this.liveRegionEl = existingContainer.querySelector('.twm-notification-center__live-region');\n this._mounted = true;\n this.#subscribeEvents();\n this.#claimToastBus();\n return this;\n }\n\n // Create a new fixed-position container directly on body\n this.container = document.createElement('div');\n this.container.id = 'notification-center-root';\n this.container.style.cssText = 'position: fixed; right: 16px; bottom: 24px; z-index: 10000; pointer-events: none;';\n\n this.rootEl = document.createElement('div');\n this.rootEl.className = 'twm-notification-center';\n\n this.listEl = document.createElement('div');\n this.listEl.className = 'twm-notification-center__list';\n\n this.liveRegionEl = document.createElement('div');\n this.liveRegionEl.className = 'twm-notification-center__live-region';\n this.liveRegionEl.setAttribute('aria-live', 'polite');\n this.liveRegionEl.setAttribute('aria-atomic', 'true');\n this.liveRegionEl.style.position = 'absolute';\n this.liveRegionEl.style.width = '1px';\n this.liveRegionEl.style.height = '1px';\n this.liveRegionEl.style.overflow = 'hidden';\n this.liveRegionEl.style.clip = 'rect(1px, 1px, 1px, 1px)';\n\n this.rootEl.appendChild(this.listEl);\n this.rootEl.appendChild(this.liveRegionEl);\n this.container.appendChild(this.rootEl);\n document.body.appendChild(this.container);\n\n this._mounted = true;\n this.#subscribeEvents();\n this.#claimToastBus();\n\n if (Array.isArray(props.initialNotifications)) {\n props.initialNotifications.forEach((notification) => this.show(notification));\n }\n return this;\n }\n\n dispose() {\n this.#clearTimers();\n this.#unsubscribeEvents();\n this.#historyListeners.clear();\n // Give the toast helpers back to the console \u2014 unless someone has\n // pointed them at another bus since this centre mounted.\n if (this.eventBus && getToastBus() === this.eventBus) setToastBus(null);\n this.#items.forEach((entry) => entry.bar?.dispose());\n this.#items.clear();\n this.#summaryEl = null;\n if (this.rootEl?.parentNode) {\n this.rootEl.parentNode.removeChild(this.rootEl);\n }\n this.container = null;\n this.rootEl = null;\n this.listEl = null;\n this.liveRegionEl = null;\n super.dispose();\n }\n\n show(notification) {\n const normalized = this.#normalizeNotification(notification);\n this.#consoleLog(normalized);\n const running = NotificationCenter.#isRunning(normalized);\n if (this.overflow === 'collapse' && !running && this.notifications.length >= this.maxVisible) {\n // Held, not shown: its timer starts when it comes on screen.\n this.held.push(normalized);\n this.#recordHistory(normalized);\n this.#render();\n this.#announce(normalized);\n return normalized.id;\n }\n this.notifications.push(normalized);\n if (this.overflow === 'collapse') {\n // Only a running progress toast gets here past the limit: the\n // newest other toast steps back behind \"+N more\" to make room.\n this.#rebalance();\n } else if (this.notifications.length > this.maxVisible) {\n // The oldest leaves \u2014 but never a running progress toast.\n const idx = this.notifications.findIndex((item) => !NotificationCenter.#isRunning(item));\n if (idx !== -1) {\n const [removed] = this.notifications.splice(idx, 1);\n this.#stopTimer(removed.id);\n this.#recordDismissal(removed, 'overflow');\n }\n }\n\n this.#recordHistory(normalized);\n this.#scheduleAutoDismiss(normalized);\n this.#render();\n this.#announce(normalized);\n return normalized.id;\n }\n\n dismiss(notificationId, reason = 'dismissed') {\n const idx = this.notifications.findIndex((item) => item.id === notificationId);\n if (idx === -1) {\n const h = this.held.findIndex((item) => item.id === notificationId);\n if (h === -1) return false;\n const [gone] = this.held.splice(h, 1);\n this.#recordDismissal(gone, reason);\n this.#render();\n return true;\n }\n const [removed] = this.notifications.splice(idx, 1);\n this.#stopTimer(notificationId);\n this.#recordDismissal(removed, reason);\n // A place on screen came free: the oldest held-back toast takes it.\n this.#rebalance();\n this.#render();\n return true;\n }\n\n /**\n * Change a notification in place: only its own nodes are touched, and no\n * other toast is redrawn. A held-back toast is changed too and shows the\n * change when it comes on screen.\n *\n * Fields: `message`, `title`, `description`, `severity`, `meta`, and for\n * progress toasts `progress` (fraction, `{ value, total }`, or `null` for\n * indeterminate), `status`, `counts` and `collapsed`; `progress` on a\n * plain toast turns it into a running progress toast (on screen, as with\n * show()). Giving a running progress toast an outcome severity (success,\n * error, fatal) finishes it, and its bar keeps the state it ended in: a\n * later severity only restyles the toast. A `durationMs` on a toast that\n * is not running (re)starts its auto-dismiss (0 keeps it until closed).\n *\n * @param {string} notificationId - The ID of the notification to update\n * @param {Object} updates - The fields to change\n * @returns {boolean} True if the notification was found and updated\n */\n update(notificationId, updates = {}) {\n const notification = this.notifications.find((item) => item.id === notificationId)\n ?? this.held.find((item) => item.id === notificationId);\n if (!notification) {\n return false;\n }\n const hadTitle = Boolean(notification.title);\n const hadDescription = Boolean(notification.description);\n const wasProgress = notification.progress !== undefined;\n const wasRunning = NotificationCenter.#isRunning(notification);\n\n if (updates.message !== undefined) notification.message = updates.message;\n if (updates.title !== undefined) notification.title = updates.title;\n if (updates.description !== undefined) notification.description = updates.description;\n if (updates.meta !== undefined) notification.meta = updates.meta;\n if (updates.status !== undefined) notification.status = updates.status ?? '';\n if (updates.counts !== undefined) notification.counts = updates.counts ?? '';\n if (updates.collapsed !== undefined) notification.collapsed = Boolean(updates.collapsed);\n if (updates.progress !== undefined) {\n if (wasProgress) {\n notification.progress = NotificationCenter.#normalizeProgress(updates.progress);\n } else {\n // A plain toast becomes a running progress toast, set up as show() would.\n Object.assign(notification, NotificationCenter.#progressFields({ ...notification, ...updates }));\n notification.persistent = true;\n this.#stopTimer(notification.id);\n }\n }\n if (updates.severity !== undefined) {\n notification.severity = this.#normalizeSeverity(updates.severity);\n const outcome = OUTCOME_BAR_STATE[notification.severity];\n if (NotificationCenter.#isRunning(notification) && outcome) notification.outcome = outcome;\n }\n const running = NotificationCenter.#isRunning(notification);\n const finished = wasRunning && !running;\n if (updates.durationMs !== undefined && !NotificationCenter.#isRunning(notification)) {\n notification.durationMs = this.#coerceDuration(updates.durationMs);\n notification.persistent = notification.durationMs === 0;\n if (this.notifications.includes(notification)) {\n this.#stopTimer(notification.id);\n this.#scheduleAutoDismiss(notification);\n }\n }\n\n const entry = this.#items.get(notification.id);\n if (entry) {\n const structural = hadTitle !== Boolean(notification.title)\n || hadDescription !== Boolean(notification.description)\n || wasProgress !== (notification.progress !== undefined);\n if (structural) {\n // A part appears or goes: rebuild this one toast, in its place.\n const next = this.#buildItem(notification);\n entry.el.replaceWith(next.el);\n entry.bar?.dispose();\n this.#items.set(notification.id, next);\n } else {\n this.#patchItem(entry, notification);\n }\n }\n if (finished) this.#announce(notification);\n // Started, it comes on screen whatever is held; finished, it folds\n // like any other toast.\n if (running !== wasRunning) this.#rebalance();\n this.#render();\n return true;\n }\n\n clearAll(reason = 'cleared') {\n [...this.notifications].forEach((notification) => this.dismiss(notification.id, reason));\n }\n\n ingestLogEntry(entry) {\n if (!entry || !this.logLevels.has(entry.level)) {\n return;\n }\n\n // Suppress state-guard warnings - these are internal and would cause a cascade\n // (NotificationCenter renders -> triggers state-guard -> logs warning -> creates notification -> repeat)\n if (entry.namespace === 'state-guard') {\n return;\n }\n\n const severity = LOG_SEVERITY_MAP[entry.level] ?? 'info';\n const suppressTitle = SUPPRESSED_NAMESPACE_TITLES.has(entry.namespace);\n const title = suppressTitle\n ? null\n : NotificationCenter.#formatNamespaceTitle(entry.namespace);\n // Info-level log entries from internal namespaces are noise in history\n const skipHistory = severity === 'info' && suppressTitle;\n this.show({\n title,\n message: entry.message,\n severity,\n namespace: entry.namespace,\n meta: entry.data,\n skipHistory,\n });\n }\n\n #consoleLog(notification) {\n if (notification.severity !== 'warn' && notification.severity !== 'error' && notification.severity !== 'fatal') {\n return;\n }\n const method = notification.severity === 'warn' ? console.warn : console.error; // eslint-disable-line no-console\n const prefix = notification.title ? `[${notification.title}]` : '[Notification]';\n const details = notification.meta ?? notification.description ?? '';\n method(`${prefix} ${notification.message}`, details); // eslint-disable-line no-console\n }\n\n #normalizeNotification(notification) {\n if (!notification) {\n throw new TypeError('Notification payload is required');\n }\n const id = notification.id ?? `notification-${++this.sequence}`;\n const severity = this.#normalizeSeverity(notification.severity ?? 'info');\n const isProgress = notification.progress !== undefined;\n return {\n ...(isProgress ? NotificationCenter.#progressFields(notification) : {}),\n id,\n title: notification.title ?? null,\n message: notification.message ?? '',\n description: notification.description ?? null,\n timestamp: notification.timestamp ?? Date.now(),\n severity,\n namespace: notification.namespace ?? null,\n durationMs: this.#coerceDuration(notification.durationMs),\n // A progress toast stays until it finishes (and then until its\n // finishing durationMs, or its \u00D7).\n persistent: isProgress || Boolean(notification.persistent),\n skipHistory: Boolean(notification.skipHistory),\n actions: this.#normalizeActions(notification.actions),\n meta: notification.meta ?? null,\n };\n }\n\n #normalizeSeverity(severity) {\n const value = typeof severity === 'string' ? severity.toLowerCase() : 'info';\n if (!SEVERITIES.includes(value)) {\n return 'info';\n }\n return value;\n }\n\n #coerceDuration(duration) {\n if (duration === null || duration === undefined) {\n return this.defaultDurationMs;\n }\n const value = Number(duration);\n if (!Number.isFinite(value) || value < 0) {\n return this.defaultDurationMs;\n }\n return value;\n }\n\n toast(title, message, type = 'info') {\n // Legacy compatibility method\n this.show({\n title,\n message,\n severity: type,\n persistent: type === 'error' || type === 'fatal',\n });\n }\n\n error(titleOrMessage, message) {\n const hasTitle = message !== undefined;\n return this.show({\n title: hasTitle ? titleOrMessage : null,\n message: hasTitle ? message : titleOrMessage,\n severity: 'error',\n persistent: true,\n });\n }\n\n warn(titleOrMessage, message) {\n const hasTitle = message !== undefined;\n return this.show({\n title: hasTitle ? titleOrMessage : null,\n message: hasTitle ? message : titleOrMessage,\n severity: 'warn',\n });\n }\n\n info(titleOrMessage, message) {\n const hasTitle = message !== undefined;\n return this.show({\n title: hasTitle ? titleOrMessage : null,\n message: hasTitle ? message : titleOrMessage,\n severity: 'info',\n });\n }\n\n success(titleOrMessage, message) {\n const hasTitle = message !== undefined;\n return this.show({\n title: hasTitle ? titleOrMessage : null,\n message: hasTitle ? message : titleOrMessage,\n severity: 'success',\n });\n }\n\n #normalizeActions(actions) {\n if (!Array.isArray(actions) || actions.length === 0) {\n return [];\n }\n return actions.map((action, idx) => ({\n id: action.id ?? `action-${idx}`,\n label: action.label ?? 'Action',\n handler: typeof action.handler === 'function' ? action.handler : null,\n eventName: action.eventName ?? null,\n payload: action.payload ?? null,\n }));\n }\n\n #scheduleAutoDismiss(notification) {\n if (notification.persistent || notification.durationMs === 0) {\n return;\n }\n const timer = setTimeout(() => {\n this.dismiss(notification.id, 'timeout');\n }, notification.durationMs);\n this.activeTimers.set(notification.id, timer);\n }\n\n #stopTimer(notificationId) {\n const timer = this.activeTimers.get(notificationId);\n if (timer) {\n clearTimeout(timer);\n this.activeTimers.delete(notificationId);\n }\n }\n\n #clearTimers() {\n this.activeTimers.forEach((timer) => clearTimeout(timer));\n this.activeTimers.clear();\n }\n\n /**\n * Hear of every entry added to `history`, by `show()`, `warn()`/`error()`/\n * `info()`/`success()` and the bus alike: `listener(entry, center)`, once\n * per toast, after the entry is in `history`. A dismissal changes the\n * toast's own entry and is not an entry of its own. Answers the unsubscribe.\n */\n subscribe(listener) {\n if (typeof listener !== 'function') return () => {};\n this.#historyListeners.add(listener);\n return () => { this.#historyListeners.delete(listener); };\n }\n\n #recordHistory(entry) {\n if (entry.skipHistory) return;\n this.history.push(entry);\n if (this.history.length > this.historyLimit) {\n this.history.shift();\n }\n [...this.#historyListeners].forEach((listener) => {\n try {\n listener(entry, this);\n } catch (err) {\n this.logger?.warn?.('twm-notification-center', 'History listener failed', { err });\n }\n });\n }\n\n /** A toast that left marks its own entry: one toast, one entry. */\n #recordDismissal(notification, reason) {\n if (notification.skipHistory) return;\n const at = this.history.findLastIndex((entry) => entry.id === notification.id);\n if (at === -1) return;\n this.history[at] = { ...notification, dismissed: true, reason };\n }\n\n /** A progress toast that has not been given an outcome yet. */\n static #isRunning(notification) {\n return notification.progress !== undefined && !notification.outcome;\n }\n\n /**\n * The fields a progress toast carries, from a show() payload or an\n * update() that turns a plain toast into one. `outcome` is null while it\n * runs, then the state its bar ended in (done or error).\n */\n static #progressFields(source) {\n return {\n progress: NotificationCenter.#normalizeProgress(source.progress),\n status: source.status ?? '',\n counts: source.counts ?? '',\n collapsed: Boolean(source.collapsed),\n outcome: null,\n };\n }\n\n /** `null` (indeterminate), a 0..1 fraction, or `{ value, total }` -> ProgressBar input. */\n static #normalizeProgress(progress) {\n if (progress === null) return { indeterminate: true };\n if (typeof progress === 'number') {\n return { value: Number.isFinite(progress) ? progress : 0, max: null, indeterminate: false };\n }\n if (typeof progress === 'object') {\n const value = Number(progress.value);\n const total = Number(progress.total);\n return {\n value: Number.isFinite(value) ? value : 0,\n max: Number.isFinite(total) && total > 0 ? total : null,\n indeterminate: false,\n };\n }\n return { indeterminate: true };\n }\n\n /**\n * 'collapse' only: keep at most `maxVisible` on screen, counting running\n * progress toasts, which never leave and are never held (one that started\n * running while held comes on screen first). Past the limit the newest\n * other toast steps back to the front of the held queue (its timer\n * restarts when it returns); under it the oldest held toast comes in.\n */\n #rebalance() {\n if (this.overflow !== 'collapse') return;\n for (let i = 0; i < this.held.length;) {\n if (NotificationCenter.#isRunning(this.held[i])) this.notifications.push(...this.held.splice(i, 1));\n else i++;\n }\n while (this.notifications.length > this.maxVisible) {\n let idx = -1;\n for (let i = this.notifications.length - 1; i >= 0; i--) {\n if (!NotificationCenter.#isRunning(this.notifications[i])) { idx = i; break; }\n }\n if (idx === -1) break;\n const [back] = this.notifications.splice(idx, 1);\n this.#stopTimer(back.id);\n this.held.unshift(back);\n }\n while (this.held.length && this.notifications.length < this.maxVisible) {\n const next = this.held.shift();\n this.notifications.push(next);\n this.#scheduleAutoDismiss(next);\n }\n }\n\n /**\n * Draw the toasts on screen. Each toast's element is built once and kept:\n * a toast arriving or leaving only inserts or removes its own element, so\n * every other toast keeps its nodes (and its bar, collapsed state, hover).\n */\n #render() {\n if (!this._mounted || !this.listEl) {\n return;\n }\n const visible = new Set(this.notifications.map((n) => n.id));\n for (const [id, entry] of this.#items) {\n if (visible.has(id)) continue;\n entry.bar?.dispose();\n entry.el.remove();\n this.#items.delete(id);\n }\n const wanted = this.notifications.map((notification) => {\n let entry = this.#items.get(notification.id);\n if (!entry) {\n entry = this.#buildItem(notification);\n this.#items.set(notification.id, entry);\n }\n return entry.el;\n });\n const summary = this.#syncSummary();\n if (summary) wanted.push(summary);\n wanted.forEach((el, i) => {\n const at = this.listEl.children[i];\n if (at !== el) this.listEl.insertBefore(el, at ?? null);\n });\n // Anything after them is stale (another instance's toasts on a reused root).\n while (this.listEl.children.length > wanted.length) {\n this.listEl.lastElementChild.remove();\n }\n }\n\n // The held-back toasts, as one: \"+N more\". It is a button so the count is\n // reachable by keyboard; what it opens is the consumer's (summaryAction),\n // and it is also announced on the bus for a history panel to answer.\n #syncSummary() {\n if (!this.held.length) {\n this.#summaryEl?.remove();\n this.#summaryEl = null;\n return null;\n }\n if (!this.#summaryEl) {\n const more = document.createElement('button');\n more.type = 'button';\n more.className = 'twm-notification twm-notification--summary';\n more.addEventListener('click', () => {\n const held = [...this.held];\n try { this.summaryAction?.(held); } catch (err) { this.logger?.warn?.('summaryAction failed', err); }\n this.eventBus?.emit?.('notification:summary', { held });\n });\n this.#summaryEl = more;\n }\n const more = this.#summaryEl;\n const count = String(this.held.length);\n if (more.getAttribute('data-notification-summary') !== count) more.setAttribute('data-notification-summary', count);\n NotificationCenter.#setText(more, `+${count} more`);\n const tip = this.held.map((h) => h.title || h.message).join('\\n');\n if (more.title !== tip) more.title = tip;\n return more;\n }\n\n static #setText(node, text) {\n const t = text == null ? '' : String(text);\n if (node.textContent !== t) node.textContent = t;\n }\n\n /** Build one toast's element; `#patchItem` then fills what can change. */\n #buildItem(notification) {\n const isProgress = notification.progress !== undefined;\n const item = document.createElement('div');\n // Use setAttribute to avoid StateGuard blocking dataset mutations\n item.setAttribute('data-notification-id', notification.id);\n const entry = { el: item, severity: null, titleEl: null, bodyEl: null, descriptionEl: null,\n statusEl: null, bar: null, collapseBtn: null };\n\n const header = document.createElement('div');\n header.className = 'twm-notification__header';\n if (notification.title) {\n entry.titleEl = document.createElement('span');\n entry.titleEl.className = 'twm-notification__title';\n header.appendChild(entry.titleEl);\n }\n\n const timeEl = document.createElement('span');\n timeEl.className = 'twm-notification__timestamp';\n timeEl.textContent = this.#formatTimestamp(notification.timestamp);\n header.appendChild(timeEl);\n\n if (isProgress) {\n const toggle = document.createElement('button');\n toggle.className = 'twm-notification__collapse';\n toggle.type = 'button';\n toggle.innerHTML = '<span class=\"material-symbols-outlined\">expand_more</span>';\n toggle.addEventListener('click', () => {\n this.update(notification.id, { collapsed: !notification.collapsed });\n });\n entry.collapseBtn = toggle;\n header.appendChild(toggle);\n }\n\n const closeBtn = document.createElement('button');\n closeBtn.className = 'twm-notification__close';\n closeBtn.type = 'button';\n closeBtn.setAttribute('aria-label', 'Dismiss notification');\n closeBtn.innerHTML = '<span class=\"material-symbols-outlined\">close</span>';\n closeBtn.addEventListener('click', () => this.dismiss(notification.id, 'manual'));\n header.appendChild(closeBtn);\n item.appendChild(header);\n\n entry.bodyEl = document.createElement('div');\n entry.bodyEl.className = 'twm-notification__body';\n item.appendChild(entry.bodyEl);\n\n if (isProgress) {\n entry.bar = new ProgressBar(item, {\n ...notification.progress, showCount: false, className: 'twm-notification__progress',\n });\n entry.statusEl = document.createElement('div');\n entry.statusEl.className = 'twm-notification__status';\n item.appendChild(entry.statusEl);\n }\n\n if (notification.description) {\n entry.descriptionEl = document.createElement('div');\n entry.descriptionEl.className = 'twm-notification__description';\n item.appendChild(entry.descriptionEl);\n }\n\n if (notification.actions.length > 0) {\n const actionsEl = document.createElement('div');\n actionsEl.className = 'twm-notification__actions';\n notification.actions.forEach((action) => {\n const button = document.createElement('button');\n button.type = 'button';\n button.className = 'twm-notification__action-btn';\n button.textContent = action.label;\n button.addEventListener('click', () => {\n try {\n if (action.handler) {\n action.handler(notification, action);\n } else if (action.eventName && this.eventBus) {\n this.eventBus.emit(action.eventName, action.payload ?? { notificationId: notification.id });\n }\n } catch (err) {\n this.logger?.error?.('twm-notification-center', 'Notification action failed', { err });\n } finally {\n // Don't auto-dismiss error/fatal notifications, or a job\n // still running, after action clicks\n if (notification.severity !== 'error' && notification.severity !== 'fatal'\n && !NotificationCenter.#isRunning(notification)) {\n this.dismiss(notification.id, 'action');\n }\n }\n });\n actionsEl.appendChild(button);\n });\n item.appendChild(actionsEl);\n }\n\n item.addEventListener('click', (event) => {\n if (event.target.closest('button') || NotificationCenter.#isRunning(notification)) {\n return;\n }\n this.dismiss(notification.id, 'click');\n });\n\n this.#patchItem(entry, notification);\n return entry;\n }\n\n /** Bring a drawn toast's nodes in line with its data, touching only what changed. */\n #patchItem(entry, notification) {\n const item = entry.el;\n if (entry.severity !== notification.severity) {\n if (entry.severity) item.classList.remove(`twm-notification--${entry.severity}`);\n item.classList.add('twm-notification', `twm-notification--${notification.severity}`);\n entry.severity = notification.severity;\n }\n if (entry.titleEl) NotificationCenter.#setText(entry.titleEl, notification.title);\n NotificationCenter.#setText(entry.bodyEl, notification.message);\n if (entry.descriptionEl) NotificationCenter.#setText(entry.descriptionEl, notification.description);\n if (!entry.bar) return;\n\n item.classList.add('twm-notification--progress');\n item.classList.toggle('twm-notification--collapsed', Boolean(notification.collapsed));\n const expanded = String(!notification.collapsed);\n if (entry.collapseBtn.getAttribute('aria-expanded') !== expanded) {\n entry.collapseBtn.setAttribute('aria-expanded', expanded);\n entry.collapseBtn.setAttribute('aria-label', notification.collapsed ? 'Expand notification' : 'Collapse notification');\n }\n NotificationCenter.#setText(entry.statusEl, notification.status);\n entry.statusEl.hidden = !notification.status;\n entry.bar.update({ ...notification.progress, label: notification.counts });\n const end = notification.outcome ?? 'running';\n if (entry.bar.state !== end) entry.bar.setState(end);\n }\n\n #formatTimestamp(timestamp) {\n const date = new Date(timestamp);\n return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' });\n }\n\n #announce(notification) {\n if (!this.liveRegionEl) {\n return;\n }\n const parts = [notification.title, notification.message].filter(Boolean);\n this.liveRegionEl.textContent = parts.join(': ');\n }\n\n #handleToast(payload = {}) {\n const message = payload.text ?? payload.message ?? (typeof payload === 'string' ? payload : '');\n if (!message) {\n return;\n }\n\n const persistent = payload.persistent === true || payload.autoHide === false;\n const durationMs = persistent ? 0 : (payload.durationMs ?? payload.duration ?? payload.timeout);\n this.show({\n title: payload.title ?? null,\n message,\n severity: payload.type ?? payload.severity ?? 'info',\n durationMs,\n persistent,\n namespace: payload.namespace ?? null,\n actions: payload.actions,\n meta: payload.meta ?? null,\n });\n }\n\n #subscribeEvents() {\n if (!this.eventBus) {\n return;\n }\n this.eventDisposers.push(\n this.eventBus.on('toast:show', (payload) => this.#handleToast(payload)),\n this.eventBus.on('notification:show', (payload) => this.show(payload)),\n this.eventBus.on('notification:update', (payload) => {\n if (payload?.id) {\n this.update(payload.id, payload);\n }\n }),\n this.eventBus.on('log:entry', (entry) => this.ingestLogEntry(entry)),\n this.eventBus.on('workspace:save:failed', (payload) => {\n // Error toasts are shown by default unless explicitly disabled\n if (getSetting('workspace.save.showErrorToast', true)) {\n this.show({\n title: 'Workspace Save Failed',\n message: payload?.reason ? `Save failed: ${payload.reason}` : 'Workspace save failed',\n severity: 'error',\n meta: payload,\n persistent: true,\n });\n }\n }),\n this.eventBus.on('workspace:save:completed', (payload) => {\n // Only show toast if enabled in settings\n if (getSetting('workspace.save.showToast', false)) {\n this.show({\n title: 'Workspace Saved',\n message: 'Changes saved successfully',\n severity: 'success',\n durationMs: 3000,\n meta: payload,\n skipHistory: true,\n });\n }\n }),\n this.eventBus.on('workspace:import:failed', (payload) => {\n // Error toasts are shown by default unless explicitly disabled\n if (getSetting('workspace.import.showErrorToast', true)) {\n this.show({\n title: 'Workspace Import Failed',\n message: payload?.error?.message || 'Import failed',\n severity: 'error',\n meta: payload,\n persistent: true,\n });\n }\n }),\n this.eventBus.on('workspace:import:completed', (payload) => {\n // Show import completion toast if enabled in settings\n if (getSetting('workspace.import.showToast', true)) {\n this.show({\n title: 'Workspace Ready',\n message: 'Workspace import completed',\n severity: 'success',\n durationMs: 3000,\n meta: payload,\n skipHistory: true,\n });\n }\n }),\n );\n }\n\n /** The toast helpers (toast.js) emit on the bus of the centre mounted last. */\n #claimToastBus() {\n if (this.eventBus) setToastBus(this.eventBus);\n }\n\n #unsubscribeEvents() {\n this.eventDisposers.forEach((disposer) => {\n try {\n disposer?.dispose?.();\n } catch (err) {\n this.logger?.warn?.('twm-notification-center', 'Failed to remove event listener', { err });\n }\n });\n this.eventDisposers = [];\n }\n\n static #formatNamespaceTitle(namespace) {\n if (!namespace) return null;\n return namespace\n .split(/[-_]/)\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join(' ');\n }\n}\n\nNotificationCenter.SEVERITIES = SEVERITIES;\n", "/**\n * auto_scrollbars.js \u2014 the overlay scrollbar, on EVERY scrollable element.\n *\n * `installOverlayScrollbar` (overlay_scrollbar.js) gives one container a thin\n * bar that shows on hover and fades away. It is installed container by\n * container, it puts the bar INSIDE the container, and it holds a resize\n * observer, a subtree mutation observer and a window listener for each one.\n * That is fine for a handful of known panes and wrong for \"all of them\": a\n * page that redraws with `innerHTML = ''` deletes its bar for good, and a\n * table body, a dropdown, a textarea and a dialog each want one.\n *\n * So this is the same look, done once for a whole subtree:\n *\n * - Native scrollbars are hidden under `root`, so no element reserves\n * layout width for one and nothing reflows when a bar appears.\n * - Bars live in ONE fixed layer on `document.body`, positioned over the\n * element they belong to. Nothing is added to a scroll container, so a\n * redraw cannot remove a bar, and a textarea (which cannot hold children)\n * gets one too.\n * - An element gets its bars when the pointer is over it or it scrolls, if\n * it actually overflows. They fade out a moment after the pointer leaves\n * or the scrolling stops. Nested scroll areas each show their own.\n * - The thumb drags and the track pages, as a native bar does.\n * - The layer is above everything, so a bar would also draw over whatever\n * covers its element \u2014 a popover, a menu, a dialog. A bar whose track is\n * covered anywhere is not drawn; it comes back when it is uncovered.\n *\n * Discovery is lazy: the pointer and scroll events name the elements worth\n * measuring, so nothing walks the DOM looking for scroll areas.\n */\n\nconst LAYER_ID = 'twm-autoscroll-layer';\nconst ROOT_CLASS = 'twm-autoscroll';\nconst HIDE_AFTER_MS = 900;\nconst MIN_THUMB = 30;\nconst BAR = 6;\n\n/**\n * Where the thumb goes. Pure, so it can be tested without a layout engine.\n *\n * @param {number} scrollSize scrollHeight / scrollWidth\n * @param {number} clientSize clientHeight / clientWidth\n * @param {number} scrollPos scrollTop / scrollLeft\n * @param {number} trackLen the bar's length on screen (px)\n * @returns {{size:number, pos:number}|null} null when nothing overflows\n */\nexport function thumbGeometry(scrollSize, clientSize, scrollPos, trackLen) {\n const max = scrollSize - clientSize;\n if (!(max > 1) || !(trackLen > 0)) return null;\n const size = Math.min(trackLen, Math.max(MIN_THUMB, trackLen * clientSize / scrollSize));\n const pos = (trackLen - size) * Math.min(1, Math.max(0, scrollPos / max));\n return { size, pos };\n}\n\n/**\n * Whether something else covers `el` at any of the points a bar runs along.\n * Pure, so it can be tested without a layout engine.\n *\n * @param {Element} el\n * @param {Element[][]} stacks what `elementsFromPoint` gave at each point,\n * topmost first. The overlay layer's own bars are skipped, and so are the\n * window's `.twm-resize-handle` edge strips (BUG-0036): they lie over every\n * pane flush against a window edge and are chrome, not cover.\n * @returns {boolean}\n */\nexport function barCovered(el, stacks) {\n const passThrough = (h) => h.closest?.('.twm-autoscroll-layer') || h.closest?.('.twm-resize-handle');\n return stacks.some((stack) => {\n const top = (stack || []).find((h) => !passThrough(h));\n return Boolean(top) && top !== el && !el.contains(top);\n });\n}\n\n/** Whether an element scrolls on an axis: its overflow allows it and its\n * content is larger than its box. */\nfunction scrollsOn(el, axis) {\n if (!(el instanceof Element)) return false;\n const cs = getComputedStyle(el);\n const overflow = axis === 'y' ? cs.overflowY : cs.overflowX;\n if (overflow !== 'auto' && overflow !== 'scroll' && !(el.tagName === 'TEXTAREA' && overflow !== 'hidden')) return false;\n return axis === 'y' ? el.scrollHeight - el.clientHeight > 1 : el.scrollWidth - el.clientWidth > 1;\n}\n\n/**\n * Give every scrollable element under `root` an auto-hiding overlay scrollbar.\n *\n * @param {HTMLElement} [root=document.body]\n * @param {{exclude?: (el: Element) => boolean}} [opts] elements to leave to\n * their own scrollbar. Containers that already carry an\n * `installOverlayScrollbar` bar are always left alone.\n * @returns {{dispose: () => void}}\n */\nexport function installAutoScrollbars(root = document.body, { exclude = null } = {}) {\n const doc = root.ownerDocument || document;\n const win = doc.defaultView || window;\n root.classList.add(ROOT_CLASS);\n\n let layer = doc.getElementById(LAYER_ID);\n if (!layer) {\n layer = doc.createElement('div');\n layer.id = LAYER_ID;\n layer.className = 'twm-autoscroll-layer';\n doc.body.appendChild(layer);\n }\n\n /** element -> { v, h, timer, hovered } */\n const managed = new Map();\n let hoverChain = new Set();\n\n const eligible = (el) => el instanceof Element\n && root.contains(el)\n && !el.__overlayScrollbarInstalled\n && !el.closest?.('.twm-autoscroll-layer')\n && !(exclude && exclude(el));\n\n const makeBar = (el, axis) => {\n const bar = doc.createElement('div');\n bar.className = `twm-autoscroll-bar twm-autoscroll-bar--${axis}`;\n const thumb = doc.createElement('div');\n thumb.className = 'twm-autoscroll-thumb';\n bar.appendChild(thumb);\n layer.appendChild(bar);\n\n // The track pages, like a native bar's.\n bar.addEventListener('mousedown', (e) => {\n if (e.target !== bar) return;\n e.preventDefault();\n const r = thumb.getBoundingClientRect();\n const before = axis === 'y' ? e.clientY < r.top : e.clientX < r.left;\n const page = (axis === 'y' ? el.clientHeight : el.clientWidth) * 0.9;\n if (axis === 'y') el.scrollTop += before ? -page : page;\n else el.scrollLeft += before ? -page : page;\n });\n // The thumb drags.\n thumb.addEventListener('mousedown', (e) => {\n e.preventDefault();\n e.stopPropagation();\n const rec = managed.get(el);\n if (rec) rec.dragging = true;\n const start = axis === 'y' ? e.clientY : e.clientX;\n const startScroll = axis === 'y' ? el.scrollTop : el.scrollLeft;\n const trackLen = axis === 'y' ? bar.getBoundingClientRect().height : bar.getBoundingClientRect().width;\n const thumbLen = axis === 'y' ? thumb.getBoundingClientRect().height : thumb.getBoundingClientRect().width;\n const max = axis === 'y' ? el.scrollHeight - el.clientHeight : el.scrollWidth - el.clientWidth;\n const perPx = trackLen > thumbLen ? max / (trackLen - thumbLen) : 0;\n bar.classList.add('twm-autoscroll-bar--active');\n const move = (mv) => {\n const d = (axis === 'y' ? mv.clientY : mv.clientX) - start;\n if (axis === 'y') el.scrollTop = startScroll + d * perPx;\n else el.scrollLeft = startScroll + d * perPx;\n };\n const up = () => {\n doc.removeEventListener('mousemove', move);\n doc.removeEventListener('mouseup', up);\n bar.classList.remove('twm-autoscroll-bar--active');\n if (rec) rec.dragging = false;\n hideLater(el);\n };\n doc.addEventListener('mousemove', move);\n doc.addEventListener('mouseup', up);\n });\n bar.addEventListener('mouseenter', () => { const rec = managed.get(el); if (rec) { rec.onBar = true; show(el); } });\n bar.addEventListener('mouseleave', () => { const rec = managed.get(el); if (rec) { rec.onBar = false; hideLater(el); } });\n return { bar, thumb };\n };\n\n const record = (el) => {\n let rec = managed.get(el);\n if (!rec) {\n rec = { v: null, h: null, timer: 0, dragging: false, onBar: false };\n managed.set(el, rec);\n }\n return rec;\n };\n\n const coveredAlong = (el, points) => typeof doc.elementsFromPoint === 'function'\n && barCovered(el, points.map(([x, y]) => doc.elementsFromPoint(x, y)));\n\n /** Place and size an element's bars; drop the element when it is gone. */\n const place = (el) => {\n const rec = managed.get(el);\n if (!rec) return;\n if (!el.isConnected) { drop(el); return; }\n const r = el.getBoundingClientRect();\n const vw = win.innerWidth;\n const vh = win.innerHeight;\n const top = Math.max(0, r.top);\n const left = Math.max(0, r.left);\n const bottom = Math.min(vh, r.bottom);\n const right = Math.min(vw, r.right);\n // Screen px per CSS px, for content inside a zoomed tile.\n const z = el.offsetHeight ? r.height / el.offsetHeight : 1;\n for (const axis of ['y', 'x']) {\n const key = axis === 'y' ? 'v' : 'h';\n const overflows = scrollsOn(el, axis);\n if (!overflows) { if (rec[key]) rec[key].bar.style.display = 'none'; continue; }\n if (!rec[key]) rec[key] = makeBar(el, axis);\n const { bar, thumb } = rec[key];\n bar.style.display = '';\n if (axis === 'y') {\n const len = bottom - top;\n Object.assign(bar.style, { top: `${top}px`, left: `${right - BAR - 1}px`, height: `${len}px`, width: `${BAR}px` });\n const g = thumbGeometry(el.scrollHeight * z, el.clientHeight * z, el.scrollTop * z, len);\n if (!g) { bar.style.display = 'none'; continue; }\n Object.assign(thumb.style, { top: `${g.pos}px`, height: `${g.size}px`, left: '0', width: '100%' });\n const x = right - BAR / 2 - 1;\n if (coveredAlong(el, [[x, top + 2], [x, top + len / 2], [x, bottom - 2]])) bar.style.display = 'none';\n } else {\n const len = right - left;\n Object.assign(bar.style, { left: `${left}px`, top: `${bottom - BAR - 1}px`, width: `${len}px`, height: `${BAR}px` });\n const g = thumbGeometry(el.scrollWidth * z, el.clientWidth * z, el.scrollLeft * z, len);\n if (!g) { bar.style.display = 'none'; continue; }\n Object.assign(thumb.style, { left: `${g.pos}px`, width: `${g.size}px`, top: '0', height: '100%' });\n const y = bottom - BAR / 2 - 1;\n if (coveredAlong(el, [[left + 2, y], [left + len / 2, y], [right - 2, y]])) bar.style.display = 'none';\n }\n }\n };\n\n const setVisible = (el, on) => {\n const rec = managed.get(el);\n if (!rec) return;\n for (const b of [rec.v, rec.h]) if (b) b.bar.classList.toggle('twm-autoscroll-bar--on', on);\n };\n const show = (el) => {\n const rec = record(el);\n clearTimeout(rec.timer);\n place(el);\n setVisible(el, true);\n };\n const hideLater = (el) => {\n const rec = managed.get(el);\n if (!rec) return;\n clearTimeout(rec.timer);\n rec.timer = setTimeout(() => {\n if (rec.dragging || rec.onBar || hoverChain.has(el)) return;\n setVisible(el, false);\n }, HIDE_AFTER_MS);\n };\n const drop = (el) => {\n const rec = managed.get(el);\n if (!rec) return;\n clearTimeout(rec.timer);\n rec.v?.bar.remove();\n rec.h?.bar.remove();\n managed.delete(el);\n };\n\n /** The scrollable elements from `target` up to `root`. */\n const scrollChain = (target) => {\n const out = new Set();\n for (let el = target instanceof Element ? target : target?.parentElement; el && el !== doc.documentElement; el = el.parentElement) {\n if (el.closest?.('.twm-autoscroll-layer')) return out;\n if (eligible(el) && (scrollsOn(el, 'y') || scrollsOn(el, 'x'))) out.add(el);\n if (el === root) break;\n }\n return out;\n };\n\n const onOver = (e) => {\n if (e.target?.closest?.('.twm-autoscroll-layer')) return;\n const next = scrollChain(e.target);\n for (const el of hoverChain) if (!next.has(el)) hideLater(el);\n for (const el of next) show(el);\n hoverChain = next;\n };\n const onLeaveWindow = (e) => {\n if (e.relatedTarget) return;\n for (const el of hoverChain) hideLater(el);\n hoverChain = new Set();\n };\n const onScroll = (e) => {\n const el = e.target === doc ? null : e.target;\n if (el && eligible(el)) { show(el); hideLater(el); }\n // A scrolling ancestor moves every bar inside it.\n for (const other of managed.keys()) if (other !== el) place(other);\n };\n let raf = 0;\n const onResize = () => {\n cancelAnimationFrame(raf);\n raf = requestAnimationFrame(() => { for (const el of managed.keys()) place(el); });\n };\n // An element taken out of the page (a managed window closed) takes its\n // bars with it at once. They live in the layer, not in the element, so\n // otherwise they would stay on screen through the hide delay and fade.\n const sweep = new MutationObserver((mutations) => {\n if (!managed.size || !mutations.some((m) => m.removedNodes.length)) return;\n for (const el of [...managed.keys()]) {\n if (!el.isConnected) { drop(el); hoverChain.delete(el); }\n }\n });\n sweep.observe(root, { childList: true, subtree: true });\n\n doc.addEventListener('mouseover', onOver, true);\n doc.addEventListener('mouseout', onLeaveWindow, true);\n doc.addEventListener('scroll', onScroll, true);\n win.addEventListener('resize', onResize);\n // A popover or dialog takes the focus as it opens, often over a bar that\n // is showing because the pointer has not moved: look again once it is drawn.\n doc.addEventListener('focusin', onResize, true);\n\n return {\n dispose() {\n doc.removeEventListener('mouseover', onOver, true);\n doc.removeEventListener('mouseout', onLeaveWindow, true);\n doc.removeEventListener('scroll', onScroll, true);\n win.removeEventListener('resize', onResize);\n doc.removeEventListener('focusin', onResize, true);\n sweep.disconnect();\n for (const el of [...managed.keys()]) drop(el);\n root.classList.remove(ROOT_CLASS);\n },\n };\n}\n", "/**\n * native_context_menu.js \u2014 the browser's own right-click menu, only where it helps.\n *\n * A FlexDesk app draws its own context menus (DataTable rows and headers, tabs,\n * tiles, the top bar). Everywhere else a right-click shows the browser's or the\n * webview's menu: Back, Reload, Save as, Print, Inspect. In a desktop window\n * that makes the app look like a web page and offers moves that break it.\n *\n * This keeps the native menu where it is the useful one, editable text (Paste)\n * and selected text (Copy), and prevents it everywhere nobody else claimed the\n * right-click.\n */\n\n/** Input types that take typed text, where Paste belongs. */\nconst TEXT_INPUTS = new Set(['', 'text', 'search', 'url', 'tel', 'email', 'password', 'number',\n 'date', 'datetime-local', 'month', 'week', 'time']);\n\nfunction isEditable(el) {\n if (!el || el.nodeType !== 1) return false;\n const tag = el.tagName;\n if (tag === 'TEXTAREA' || tag === 'SELECT') return true;\n if (tag === 'INPUT') return TEXT_INPUTS.has(String(el.getAttribute('type') || '').toLowerCase());\n return !!el.closest?.('[contenteditable=\"\"],[contenteditable=\"true\"],[contenteditable=\"plaintext-only\"]');\n}\n\n/** A non-empty selection that the click landed inside. */\nfunction onSelection(target, doc) {\n const sel = doc?.getSelection?.();\n if (!sel || sel.isCollapsed || !String(sel).trim()) return false;\n for (let i = 0; i < sel.rangeCount; i += 1) {\n if (sel.getRangeAt(i).intersectsNode?.(target)) return true;\n }\n return false;\n}\n\n/**\n * Prevent the native context menu wherever no handler claimed the right-click.\n *\n * Listens in the bubble phase, so every element handler runs first: one that\n * shows its own menu calls `preventDefault()`, and this leaves it alone. A\n * handler that stops propagation never reaches here at all.\n *\n * @param {object} [opts]\n * @param {EventTarget} [opts.root=document]\n * @param {(e: MouseEvent) => boolean} [opts.allow] true keeps the native menu for that event\n * @returns {{ dispose: () => void }}\n */\nexport function suppressNativeContextMenu({ root, allow } = {}) {\n const r = root ?? (typeof document !== 'undefined' ? document : null);\n if (!r) return { dispose() {} };\n const onMenu = (e) => {\n if (e.defaultPrevented) return;\n const t = e.target;\n if (isEditable(t)) return;\n if (onSelection(t, t?.ownerDocument)) return;\n if (allow?.(e)) return;\n e.preventDefault();\n };\n r.addEventListener('contextmenu', onMenu);\n return { dispose() { r.removeEventListener('contextmenu', onMenu); } };\n}\n", "/**\n * Overlay scrollbar utilities for the js_new UI stack.\n * Ports the unified hover-only scrollbar system from the legacy UI manager.\n */\n\nimport { createRafResizeObserver } from './raf_resize_observer.js';\n\nfunction normalizeOrientation(value) {\n return String(value || 'horizontal').toLowerCase() === 'vertical' ? 'vertical' : 'horizontal';\n}\n\nfunction ensureInstallState(container) {\n if (!container.__overlayScrollbarInstalled) {\n Object.defineProperty(container, '__overlayScrollbarInstalled', {\n value: {},\n writable: true,\n configurable: true,\n });\n }\n}\n\nexport function installOverlayScrollbar(container, options = {}) {\n if (!container) return null;\n\n const orientation = normalizeOrientation(options.orientation);\n const className = options.className || 'overlay-scrollbar';\n const isHorizontal = orientation !== 'vertical';\n const orientationKey = isHorizontal ? 'horizontal' : 'vertical';\n\n ensureInstallState(container);\n if (container.__overlayScrollbarInstalled[orientationKey]) {\n return container.__overlayScrollbarInstalled[orientationKey];\n }\n\n if (options.setOverflow !== false) {\n container.style.overflow = options.overflow || 'auto';\n }\n if (options.setPosition !== false && getComputedStyle(container).position === 'static') {\n container.style.position = 'relative';\n }\n\n // When externalBar is true, place the bar on the parent element instead of\n // inside the scroll container. This avoids overflow clipping issues in certain\n // flex+overflow layouts (e.g. bottom-tabs-header .tabs).\n const externalBar = !!options.externalBar;\n const barHost = externalBar ? container.parentElement : container;\n if (externalBar && barHost && getComputedStyle(barHost).position === 'static') {\n barHost.style.position = 'relative';\n }\n\n const bar = document.createElement('div');\n bar.className = className;\n bar.classList.add(`overlay-scrollbar-${isHorizontal ? 'h' : 'v'}`);\n const track = document.createElement('div');\n track.className = 'track';\n const thumb = document.createElement('div');\n thumb.className = 'thumb';\n bar.appendChild(track);\n bar.appendChild(thumb);\n (barHost || container).appendChild(bar);\n\n const getScrollProps = () => ({\n scrollSize: isHorizontal ? container.scrollWidth : container.scrollHeight,\n clientSize: isHorizontal ? container.clientWidth : container.clientHeight,\n scrollPos: isHorizontal ? (container.scrollLeft || 0) : (container.scrollTop || 0),\n });\n\n // Dragging and hover state - must be declared early so event handlers can access it\n let dragging = false;\n let hovered = false;\n let startPos = 0;\n let thumbStartPos = 0;\n\n let previousHasOverflow = null;\n let previousClientSize = null;\n let isResettingScroll = false;\n\n const update = () => {\n if (isResettingScroll) return;\n\n const { scrollSize, clientSize, scrollPos } = getScrollProps();\n const scrollLeft = container.scrollLeft || 0;\n const scrollTop = container.scrollTop || 0;\n const maxScroll = scrollSize - clientSize;\n const hasOverflow = maxScroll > 2;\n\n if (previousClientSize !== null && clientSize > previousClientSize && hasOverflow && scrollPos > 0) {\n const delta = clientSize - previousClientSize;\n const targetScroll = Math.max(0, scrollPos - delta);\n if (targetScroll !== scrollPos) {\n isResettingScroll = true;\n if (isHorizontal) {\n container.scrollLeft = targetScroll;\n } else {\n container.scrollTop = targetScroll;\n }\n requestAnimationFrame(() => {\n isResettingScroll = false;\n update();\n });\n previousClientSize = clientSize;\n previousHasOverflow = hasOverflow;\n return;\n }\n }\n\n previousClientSize = clientSize;\n\n if (previousHasOverflow === true && !hasOverflow && scrollPos > 0) {\n isResettingScroll = true;\n if (isHorizontal) {\n container.scrollLeft = 0;\n } else {\n container.scrollTop = 0;\n }\n requestAnimationFrame(() => {\n isResettingScroll = false;\n update();\n });\n previousHasOverflow = hasOverflow;\n return;\n }\n\n const clampedMaxScroll = Math.max(0, maxScroll);\n if (hasOverflow && scrollPos > clampedMaxScroll) {\n isResettingScroll = true;\n if (isHorizontal) {\n container.scrollLeft = clampedMaxScroll;\n } else {\n container.scrollTop = clampedMaxScroll;\n }\n requestAnimationFrame(() => {\n isResettingScroll = false;\n update();\n });\n previousHasOverflow = hasOverflow;\n return;\n }\n previousHasOverflow = hasOverflow;\n\n container.dataset.scrollable = hasOverflow ? '1' : '0';\n\n // Position the bar at the scroll viewport edge.\n if (externalBar) {\n // Bar lives on the parent element \u2014 position using container's offset.\n // No scroll-offset compensation needed since bar is outside scroll context.\n if (isHorizontal) {\n bar.style.left = `${container.offsetLeft}px`;\n bar.style.bottom = 'auto';\n bar.style.top = `${container.offsetTop + container.offsetHeight - 6}px`;\n bar.style.width = `${container.clientWidth}px`;\n } else {\n bar.style.top = `${container.offsetTop}px`;\n bar.style.right = 'auto';\n bar.style.left = `${container.offsetLeft + container.offsetWidth - 6}px`;\n bar.style.height = `${container.clientHeight}px`;\n }\n } else {\n // Bar lives inside the container \u2014 compensate for scroll offset\n // on BOTH axes so the bar stays pinned to the viewport edge.\n if (isHorizontal) {\n bar.style.left = `${scrollLeft}px`;\n bar.style.top = `${scrollTop + container.clientHeight - bar.offsetHeight}px`;\n bar.style.bottom = 'auto';\n bar.style.width = `${clientSize}px`;\n } else {\n bar.style.top = `${scrollTop}px`;\n bar.style.left = `${scrollLeft + container.clientWidth - bar.offsetWidth}px`;\n bar.style.right = 'auto';\n bar.style.height = `${clientSize}px`;\n }\n }\n\n if (!hasOverflow) {\n bar.style.opacity = '0';\n bar.style.pointerEvents = 'none';\n thumb.style[isHorizontal ? 'width' : 'height'] = '0px';\n thumb.style[isHorizontal ? 'left' : 'top'] = '0px';\n return;\n }\n\n // Don't hide while dragging or hovering\n if (!dragging && !hovered) {\n bar.style.opacity = '0'; // hidden until hover\n bar.style.pointerEvents = 'none';\n }\n\n const ratio = clientSize / scrollSize;\n const thumbSize = Math.max(30, Math.floor(ratio * clientSize));\n const maxThumbPos = clientSize - thumbSize;\n const scrollRatio = maxScroll > 0 ? scrollPos / maxScroll : 0;\n const thumbPos = Math.round(maxThumbPos * scrollRatio);\n\n if (isHorizontal) {\n thumb.style.width = `${thumbSize}px`;\n thumb.style.left = `${thumbPos}px`;\n } else {\n thumb.style.height = `${thumbSize}px`;\n thumb.style.top = `${thumbPos}px`;\n }\n };\n\n const onScroll = () => update();\n container.addEventListener('scroll', onScroll, { passive: true });\n \n // Manage hover visibility entirely in JS to avoid CSS specificity issues.\n // Show bar on mouseenter if scrollable, hide on mouseleave.\n const onMouseEnter = () => {\n hovered = true;\n update();\n if (container.dataset.scrollable === '1') {\n bar.style.opacity = '1';\n bar.style.pointerEvents = '';\n }\n };\n const onMouseLeave = () => {\n hovered = false;\n // Don't hide while dragging\n if (dragging) return;\n bar.style.opacity = '0';\n bar.style.pointerEvents = 'none';\n };\n container.addEventListener('mouseenter', onMouseEnter, { passive: true });\n container.addEventListener('mouseleave', onMouseLeave, { passive: true });\n // When bar is external (sibling of container), also listen for hover on the bar\n // itself so moving the mouse to the thumb doesn't trigger a hide.\n if (externalBar) {\n bar.addEventListener('mouseenter', onMouseEnter, { passive: true });\n bar.addEventListener('mouseleave', onMouseLeave, { passive: true });\n }\n\n // Also handle focus-within for keyboard accessibility\n container.addEventListener('focusin', onMouseEnter, { passive: true });\n container.addEventListener('focusout', onMouseLeave, { passive: true });\n\n const resizeObserver = createRafResizeObserver(update);\n try { resizeObserver.observe(container); } catch (_) {}\n\n const mo = new MutationObserver(update);\n try { mo.observe(container, { childList: true, subtree: options.watchSubtree !== false }); } catch (_) {}\n\n let resizeTimeout;\n const onWindowResize = () => {\n update();\n clearTimeout(resizeTimeout);\n resizeTimeout = setTimeout(update, 150);\n };\n window.addEventListener('resize', onWindowResize, { passive: true });\n\n const onMouseDown = (e) => {\n dragging = true;\n startPos = isHorizontal ? e.clientX : e.clientY;\n thumbStartPos = parseFloat(thumb.style[isHorizontal ? 'left' : 'top']) || 0;\n // Keep bar visible while dragging\n bar.style.opacity = '1';\n bar.style.pointerEvents = '';\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp, { once: true });\n e.preventDefault();\n e.stopPropagation();\n };\n\n const onMouseMove = (e) => {\n if (!dragging) return;\n e.preventDefault();\n\n const { scrollSize, clientSize } = getScrollProps();\n const maxScroll = scrollSize - clientSize;\n if (maxScroll <= 0) return;\n\n const thumbSize = parseFloat(thumb.style[isHorizontal ? 'width' : 'height']) || 30;\n const maxThumbPos = clientSize - thumbSize;\n\n const delta = (isHorizontal ? e.clientX : e.clientY) - startPos;\n let newThumbPos = thumbStartPos + delta;\n newThumbPos = Math.max(0, Math.min(maxThumbPos, newThumbPos));\n\n const thumbRatio = maxThumbPos > 0 ? newThumbPos / maxThumbPos : 0;\n if (isHorizontal) {\n container.scrollLeft = thumbRatio * maxScroll;\n } else {\n container.scrollTop = thumbRatio * maxScroll;\n }\n };\n\n const onMouseUp = () => {\n dragging = false;\n document.removeEventListener('mousemove', onMouseMove);\n // Check if mouse is still over container - if not, hide the bar\n const rect = container.getBoundingClientRect();\n const isMouseOver = document.elementsFromPoint(\n (rect.left + rect.right) / 2,\n (rect.top + rect.bottom) / 2\n ).includes(container);\n if (!isMouseOver) {\n bar.style.opacity = '0';\n bar.style.pointerEvents = 'none';\n }\n };\n\n thumb.addEventListener('mousedown', onMouseDown);\n\n // Wheel-to-horizontal: convert vertical wheel into horizontal scroll,\n // but only when the container has no vertical overflow (otherwise let\n // the browser handle normal vertical scrolling).\n let onWheel = null;\n if (isHorizontal) {\n onWheel = (e) => {\n const { scrollSize, clientSize } = getScrollProps();\n if (scrollSize <= clientSize) return;\n if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) return;\n // If the container also scrolls vertically, don't hijack the wheel\n if (container.scrollHeight > container.clientHeight) return;\n e.preventDefault();\n container.scrollLeft += e.deltaY;\n };\n container.addEventListener('wheel', onWheel, { passive: false });\n }\n\n requestAnimationFrame(() => {\n requestAnimationFrame(update);\n });\n setTimeout(update, 50);\n\n const cleanup = () => {\n container.removeEventListener('scroll', onScroll);\n container.removeEventListener('mouseenter', onMouseEnter);\n container.removeEventListener('mouseleave', onMouseLeave);\n container.removeEventListener('focusin', onMouseEnter);\n container.removeEventListener('focusout', onMouseLeave);\n if (externalBar) {\n bar.removeEventListener('mouseenter', onMouseEnter);\n bar.removeEventListener('mouseleave', onMouseLeave);\n }\n if (onWheel) container.removeEventListener('wheel', onWheel);\n window.removeEventListener('resize', onWindowResize);\n try { resizeObserver.disconnect(); } catch (_) {}\n try { mo.disconnect(); } catch (_) {}\n bar.remove();\n };\n\n const handle = { update, cleanup, bar, thumb };\n container.__overlayScrollbarInstalled[orientationKey] = handle;\n return handle;\n}\n\nexport function installWorkspaceScrollbars(workspace, options = {}) {\n if (!workspace) return null;\n if (workspace.__workspaceOverlayScrollbarsInstalled) return workspace.__workspaceOverlayScrollbarsUpdate;\n\n installOverlayScrollbar(workspace, {\n orientation: 'vertical',\n className: options.verticalClass || 'panel-scrollbar',\n watchSubtree: options.watchSubtree ?? true,\n });\n installOverlayScrollbar(workspace, {\n orientation: 'horizontal',\n className: options.horizontalClass || 'tabs-scrollbar',\n watchSubtree: options.watchSubtree ?? true,\n });\n\n const update = () => {\n const maxX = Math.max(0, workspace.scrollWidth - workspace.clientWidth);\n const maxY = Math.max(0, workspace.scrollHeight - workspace.clientHeight);\n workspace.dataset.scrollableX = maxX > 1 ? '1' : '0';\n workspace.dataset.scrollableY = maxY > 1 ? '1' : '0';\n };\n\n workspace.__workspaceOverlayScrollbarsInstalled = true;\n workspace.__workspaceOverlayScrollbarsUpdate = update;\n workspace.addEventListener('scroll', update, { passive: true });\n const ro = createRafResizeObserver(update);\n try { ro.observe(workspace); } catch (_) {}\n const mo = new MutationObserver(update);\n try { mo.observe(workspace, { childList: true, subtree: true }); } catch (_) {}\n requestAnimationFrame(update);\n return update;\n}\n\n/**\n * Auto-discover and install vertical overlay scrollbars on\n * `.twm-collapsible-content.visible` elements under `root`. Sections already\n * visible when this is called get a bar at once; a MutationObserver on `root`\n * handles content mounted later (pages mount lazily) and class toggles\n * (expand/collapse). Only class changes under `root` are watched.\n *\n * This used to look up a hard-coded `#twm-fixed-200` that nothing in FlexDesk\n * creates, so the first pass never ran and the observer fell back to the whole\n * document (BUG-0006). The caller names its own root now.\n *\n * Only adds the visual overlay bar \u2014 does NOT change overflow. Elements that are already\n * scrollable via CSS (e.g. accordion `.twm-collapsible-content.visible { overflow-y: auto }`)\n * get the bar; non-scrollable elements get a no-op bar that stays hidden.\n *\n * @param {Element} [root=document.body] The subtree to scan and watch.\n * @returns {Function} disconnect \u2014 stops watching\n */\nexport function installCollapsibleScrollbars(root = document.body) {\n const installOnElement = (el) => {\n installOverlayScrollbar(el, {\n orientation: 'vertical',\n setOverflow: false,\n watchSubtree: true,\n });\n };\n\n if (root.matches?.('.twm-collapsible-content.visible')) installOnElement(root);\n root.querySelectorAll('.twm-collapsible-content.visible').forEach(installOnElement);\n\n // Watch for new elements AND class changes (visible toggled by toggleCategory)\n const observer = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n // Class change \u2014 check if .twm-collapsible-content just gained .visible\n if (mutation.type === 'attributes' && mutation.attributeName === 'class') {\n const el = mutation.target;\n if (el.classList.contains('twm-collapsible-content') && el.classList.contains('visible')) {\n installOnElement(el);\n }\n continue;\n }\n // New subtrees added (lazy page mount)\n for (const node of mutation.addedNodes) {\n if (node.nodeType !== 1) continue;\n if (node.classList?.contains('twm-collapsible-content') && node.classList?.contains('visible')) {\n installOnElement(node);\n }\n node.querySelectorAll?.('.twm-collapsible-content.visible')?.forEach(installOnElement);\n }\n }\n });\n\n observer.observe(root, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['class'],\n });\n return () => observer.disconnect();\n}\n\n/**\n * Auto-discover and install horizontal overlay scrollbars on tab strips.\n *\n * Uses a MutationObserver so dynamically created tab strips are picked up\n * without per-page manual setup.\n *\n * The selector list used to be hardcoded as `.tabs, .scenario-detail-tabs`, so\n * a generic scrollbar utility carried the name of one EcoAgent page's tab bar.\n * The caller names its own strips now.\n *\n * @param {string[]} [selectors=['.tabs']] Which elements count as a tab strip.\n * @returns {Function} disconnect \u2014 stops watching for new tabs\n */\nexport function installTabsScrollbars(selectors = ['.tabs']) {\n const selector = selectors.join(', ');\n const classes = selectors\n .filter((s) => s.startsWith('.'))\n .map((s) => s.slice(1));\n const installOnElement = (el) => {\n installOverlayScrollbar(el, {\n orientation: 'horizontal',\n className: 'tabs-scrollbar',\n setOverflow: false,\n externalBar: true,\n watchSubtree: true,\n });\n };\n\n const cleanupElement = (el) => {\n el.__overlayScrollbarInstalled?.horizontal?.cleanup?.();\n delete el.__overlayScrollbarInstalled;\n };\n\n const matches = (el) => classes.some((c) => el.classList?.contains(c));\n\n document.querySelectorAll(selector).forEach(installOnElement);\n\n // Watch for dynamically added/removed elements\n const observer = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n for (const node of mutation.addedNodes) {\n if (node.nodeType !== 1) continue;\n if (matches(node)) installOnElement(node);\n node.querySelectorAll?.(selector)?.forEach(installOnElement);\n }\n for (const node of mutation.removedNodes) {\n if (node.nodeType !== 1) continue;\n if (matches(node)) cleanupElement(node);\n node.querySelectorAll?.(selector)?.forEach(cleanupElement);\n }\n }\n });\n\n observer.observe(document.body, { childList: true, subtree: true });\n return () => observer.disconnect();\n}\n", "/**\n * scroll_lock.js \u2014 0.6.1. Several scroll boxes that move as one.\n *\n * A side-by-side comparison (two DataTables in two tiles, \"now\" and \"then\") is\n * only readable if row 40 on the left stays beside row 40 on the right. A lock\n * is a GROUP: every box attached to it copies the scroll position of whichever\n * member the person scrolled, on the axes the lock names.\n *\n * const lock = createScrollLock({ axis: 'y' });\n * new DataTable(left, { \u2026, scrollLock: lock });\n * new DataTable(right, { \u2026, scrollLock: lock });\n * lock.setEnabled(false); // the two scroll freely; true locks them again\n *\n * Any element can join with `lock.attach(el)`, which returns its detach. A\n * DataTable given `scrollLock` attaches its own body box on every render and\n * detaches it on the next render and on dispose, so a re-render (a sort, new\n * data) never strands a dead box in the group.\n *\n * THE ECHO. Setting `scrollTop` on a member fires that member's own `scroll`\n * event a frame later, and a naive group would then copy it back to the first\n * box, which by then may have moved on \u2014 the two fight and the wheel stutters.\n * So a position this lock WROTE is remembered per box, and the scroll event that\n * reports exactly that position is the echo and is ignored.\n *\n * A box that joins is moved to the group's last position, so a pane opened\n * beside a scrolled one starts level with it. Positions are copied as pixels:\n * the lock aligns rows only when the members draw rows of the same height,\n * which is the comparison's own contract (both sides drawn from one aligned\n * row list, a gap row where a side has none).\n */\n\n/**\n * @param {object} [options]\n * @param {'x'|'y'|'both'} [options.axis='y'] which positions are copied\n * @param {boolean} [options.enabled=true]\n */\nexport function createScrollLock({ axis = 'y', enabled = true } = {}) {\n const doY = axis === 'y' || axis === 'both';\n const doX = axis === 'x' || axis === 'both';\n const members = new Map(); // element -> { wrote: {top, left} | null, off }\n let last = { top: 0, left: 0 };\n let on = !!enabled;\n\n function copyFrom(source) {\n last = { top: source.scrollTop, left: source.scrollLeft };\n if (!on) return;\n for (const [el, state] of members) {\n if (el === source) continue;\n const top = doY ? last.top : el.scrollTop;\n const left = doX ? last.left : el.scrollLeft;\n if (el.scrollTop === top && el.scrollLeft === left) continue;\n state.wrote = { top, left };\n if (doY) el.scrollTop = top;\n if (doX) el.scrollLeft = left;\n }\n }\n\n function onScroll(event) {\n const el = event.currentTarget;\n const state = members.get(el);\n if (!state) return;\n const wrote = state.wrote;\n state.wrote = null;\n // THE ECHO of a position this lock set: not a person scrolling.\n if (wrote && Math.abs(el.scrollTop - wrote.top) < 1\n && Math.abs(el.scrollLeft - wrote.left) < 1) return;\n copyFrom(el);\n }\n\n const lock = {\n /** Join the group. Returns the function that leaves it. */\n attach(el) {\n if (!el || typeof el.addEventListener !== 'function') return () => {};\n if (members.has(el)) return () => lock.detach(el);\n const state = { wrote: null };\n members.set(el, state);\n el.addEventListener('scroll', onScroll, { passive: true });\n if (on && (last.top || last.left)) {\n state.wrote = { top: doY ? last.top : el.scrollTop,\n left: doX ? last.left : el.scrollLeft };\n if (doY) el.scrollTop = last.top;\n if (doX) el.scrollLeft = last.left;\n }\n return () => lock.detach(el);\n },\n detach(el) {\n if (!members.has(el)) return;\n members.delete(el);\n el.removeEventListener('scroll', onScroll);\n },\n /** Lock (true) or let the members scroll freely (false). Locking again\n * brings every member level with the one scrolled last. */\n setEnabled(value) {\n const was = on;\n on = !!value;\n if (on && !was) {\n const source = [...members.keys()].find(\n (el) => el.scrollTop === last.top && el.scrollLeft === last.left)\n || members.keys().next().value;\n if (source) copyFrom(source);\n }\n },\n get enabled() { return on; },\n /** How many boxes are in the group (for a consumer's own checks). */\n get size() { return members.size; },\n dispose() {\n for (const el of [...members.keys()]) lock.detach(el);\n },\n };\n return lock;\n}\n", "/**\n * tooltip_service.js\n *\n * JS-driven tooltip system for elements with `has-tooltip` class and `data-tooltip` attribute.\n * Also supports LaTeX tooltips with `has-latex-tooltip` and `data-latex-tooltip`.\n *\n * This replaces CSS-based ::after pseudo-element tooltips for better stacking context\n * and dynamic content support.\n */\n\nlet tooltipElement = null;\nlet currentTarget = null;\nlet listenersAttached = false;\nlet mouseCheckInterval = null;\nlet lastMousePosition = { x: 0, y: 0 };\n\n/**\n * Create or get the tooltip DOM element.\n * @returns {HTMLElement}\n */\nfunction createTooltipElement() {\n if (tooltipElement) return tooltipElement;\n\n tooltipElement = document.createElement('div');\n tooltipElement.className = 'twm-latex-tooltip';\n document.body.appendChild(tooltipElement);\n return tooltipElement;\n}\n\n/**\n * Position the tooltip relative to target element with smart auto-positioning.\n * Automatically flips placement if tooltip would extend outside viewport.\n * @param {HTMLElement} target - Element to position near\n * @param {HTMLElement} tooltip - Tooltip element\n */\nfunction positionTooltip(target, tooltip) {\n const rect = target.getBoundingClientRect();\n const tooltipRect = tooltip.getBoundingClientRect();\n const gap = 12;\n const margin = 10; // Minimum distance from viewport edge\n\n // Get requested placement from data attributes or context\n const requestedPlacement = (target.dataset?.tooltipPlacement || target.getAttribute('data-tooltip-placement') || '').toLowerCase() ||\n (target.dataset?.latexPlacement || target.getAttribute('data-latex-placement') || '').toLowerCase() ||\n (target.closest('.twm-global-top-bar') ? 'bottom' : (target.closest('.twm-fl-bar') ? 'right' : 'top'));\n\n // Auto-positioning: determine best placement based on available space\n let placement = requestedPlacement || 'top';\n\n // Check if explicit placement is set (not auto)\n const isExplicitPlacement = target.hasAttribute('data-tooltip-placement') ||\n target.hasAttribute('data-latex-placement');\n\n if (!isExplicitPlacement) {\n // Calculate available space in each direction\n const spaceAbove = rect.top - margin;\n const spaceBelow = window.innerHeight - rect.bottom - margin;\n const spaceLeft = rect.left - margin;\n const spaceRight = window.innerWidth - rect.right - margin;\n\n // Auto-select placement based on available space\n if (placement === 'top' && tooltipRect.height > spaceAbove && spaceBelow > spaceAbove) {\n placement = 'bottom';\n } else if (placement === 'bottom' && tooltipRect.height > spaceBelow && spaceAbove > spaceBelow) {\n placement = 'top';\n } else if (placement === 'left' && tooltipRect.width > spaceLeft && spaceRight > spaceLeft) {\n placement = 'right';\n } else if (placement === 'right' && tooltipRect.width > spaceRight && spaceLeft > spaceRight) {\n placement = 'left';\n }\n }\n\n // Calculate position based on final placement\n let left, top;\n\n if (placement === 'top') {\n left = rect.left + (rect.width / 2) - (tooltipRect.width / 2);\n top = rect.top - tooltipRect.height - gap;\n } else if (placement === 'bottom') {\n left = rect.left + (rect.width / 2) - (tooltipRect.width / 2);\n top = rect.bottom + gap;\n } else if (placement === 'left') {\n left = rect.left - tooltipRect.width - gap;\n top = rect.top + (rect.height / 2) - (tooltipRect.height / 2);\n } else if (placement === 'right') {\n left = rect.right + gap;\n top = rect.top + (rect.height / 2) - (tooltipRect.height / 2);\n }\n\n // Clamp to viewport\n const clampedLeft = Math.max(margin, Math.min(left, window.innerWidth - tooltipRect.width - margin));\n const clampedTop = Math.max(margin, Math.min(top, window.innerHeight - tooltipRect.height - margin));\n\n tooltip.style.left = `${clampedLeft}px`;\n tooltip.style.top = `${clampedTop}px`;\n\n // Calculate notch/arrow offset to point toward the target element center\n const targetCenterX = rect.left + rect.width / 2;\n const targetCenterY = rect.top + rect.height / 2;\n let notchOffset = 0;\n\n if (placement === 'top' || placement === 'bottom') {\n // Horizontal offset for notch\n const tooltipCenterX = clampedLeft + tooltipRect.width / 2;\n notchOffset = targetCenterX - tooltipCenterX;\n // Clamp notch offset to stay within tooltip bounds\n const maxOffset = (tooltipRect.width / 2) - 16; // 16px from edge minimum\n notchOffset = Math.max(-maxOffset, Math.min(notchOffset, maxOffset));\n } else {\n // Vertical offset for notch\n const tooltipCenterY = clampedTop + tooltipRect.height / 2;\n notchOffset = targetCenterY - tooltipCenterY;\n // Clamp notch offset\n const maxOffset = (tooltipRect.height / 2) - 16;\n notchOffset = Math.max(-maxOffset, Math.min(notchOffset, maxOffset));\n }\n\n // Set placement and notch offset attributes for CSS styling\n const setAttributes = () => {\n tooltip.setAttribute('data-placement', placement);\n tooltip.style.setProperty('--notch-offset', `${notchOffset}px`);\n };\n\n const guard = window.stateGuard;\n if (guard?.executeWithBypass) {\n guard.executeWithBypass('latex-tooltip:set-placement', setAttributes);\n } else {\n setAttributes();\n }\n}\n\n/**\n * Show tooltip for a target element.\n * @param {HTMLElement} target - Element with tooltip data\n */\nfunction showTooltip(target) {\n if (!target || !target.getAttribute) return;\n\n const hasLatex = target.classList && target.classList.contains('has-latex-tooltip');\n const hasPlain = target.classList && target.classList.contains('twm-has-tooltip');\n\n if (!hasLatex && !hasPlain) return;\n\n currentTarget = target;\n const tooltip = createTooltipElement();\n\n if (hasLatex) {\n // Render LaTeX using KaTeX\n const latex = target.getAttribute('data-latex-tooltip');\n if (!latex) return;\n\n try {\n if (typeof katex !== 'undefined') {\n katex.render(latex, tooltip, {\n displayMode: true,\n throwOnError: false,\n trust: false\n });\n } else {\n tooltip.textContent = latex;\n }\n } catch (err) {\n window.logger?.error('nodes', 'KaTeX rendering error:', err);\n tooltip.textContent = latex;\n }\n } else if (hasPlain) {\n // Plain text tooltip with line breaks preserved\n const text = target.getAttribute('data-tooltip');\n if (!text) return;\n\n // Replace &#10; with actual line breaks, preserve formatting\n const formattedText = text.replace(/&#10;/g, '\\n');\n const lines = formattedText.split('\\n');\n\n tooltip.innerHTML = '';\n lines.forEach((line, index) => {\n if (index === 0) {\n // First line is bold header\n const header = document.createElement('strong');\n header.textContent = line;\n tooltip.appendChild(header);\n } else {\n // Add line break and text\n tooltip.appendChild(document.createElement('br'));\n const textNode = document.createTextNode(line);\n tooltip.appendChild(textNode);\n }\n });\n }\n\n // Optional per-target width override (for long plain-text content like\n // widget documentation). Set data-tooltip-max-width on the target with a\n // CSS length (e.g. \"420px\"). Reset between shows so sticky values don't\n // leak across unrelated targets.\n const widthOverride = target.getAttribute('data-tooltip-max-width');\n tooltip.style.maxWidth = widthOverride || '';\n\n // Position and show\n requestAnimationFrame(() => {\n positionTooltip(target, tooltip);\n tooltip.classList.add('visible');\n\n // Start mouse position check for auto-hide\n startMouseCheck();\n });\n}\n\n/**\n * Hide the tooltip and clean up.\n */\nfunction hideTooltip() {\n if (tooltipElement) {\n tooltipElement.classList.remove('visible');\n }\n currentTarget = null;\n\n // Clear mouse check interval\n if (mouseCheckInterval) {\n clearInterval(mouseCheckInterval);\n mouseCheckInterval = null;\n }\n}\n\n/**\n * Start the mouse position check interval.\n * Hides tooltip if mouse is no longer over the target element.\n */\nfunction startMouseCheck() {\n // Clear any existing interval\n if (mouseCheckInterval) {\n clearInterval(mouseCheckInterval);\n }\n\n // Check every 3 seconds if mouse is still on the target element\n mouseCheckInterval = setInterval(() => {\n if (!currentTarget) {\n clearInterval(mouseCheckInterval);\n mouseCheckInterval = null;\n return;\n }\n\n // Get element under the last known mouse position\n const elementUnderMouse = document.elementFromPoint(lastMousePosition.x, lastMousePosition.y);\n\n // Check if the element under mouse is the target or a child of it\n if (elementUnderMouse) {\n const isStillOnTarget = elementUnderMouse === currentTarget ||\n currentTarget.contains(elementUnderMouse) ||\n elementUnderMouse.closest('.twm-has-tooltip, .has-latex-tooltip') === currentTarget;\n\n if (!isStillOnTarget) {\n hideTooltip();\n }\n } else {\n // Mouse is outside the document\n hideTooltip();\n }\n }, 3000);\n}\n\n/**\n * Attach global event listeners for tooltips.\n */\nfunction attachListeners() {\n if (listenersAttached) return;\n listenersAttached = true;\n\n // Remove all title attributes from elements with custom tooltips\n document.querySelectorAll('.twm-has-tooltip, .has-latex-tooltip').forEach(el => {\n el.removeAttribute('title');\n });\n\n // Track mouse position for the 3-second auto-hide check\n document.addEventListener('mousemove', (event) => {\n lastMousePosition.x = event.clientX;\n lastMousePosition.y = event.clientY;\n }, { passive: true });\n\n document.addEventListener('mouseenter', (event) => {\n const target = event.target;\n if (!(target instanceof Element)) return;\n const tooltipTarget = target.closest('.has-latex-tooltip, .twm-has-tooltip');\n if (!tooltipTarget) return;\n showTooltip(tooltipTarget);\n }, true);\n\n document.addEventListener('mouseleave', (event) => {\n const target = event.target;\n if (!(target instanceof Element)) return;\n const tooltipTarget = target.closest('.has-latex-tooltip, .twm-has-tooltip');\n if (!tooltipTarget) return;\n hideTooltip();\n }, true);\n\n // Hide on scroll\n document.addEventListener('scroll', hideTooltip, true);\n\n // ESC key hides all tooltips application-wide (does not stop propagation)\n document.addEventListener('keydown', (event) => {\n if (event.key === 'Escape') {\n hideTooltip();\n // Note: We intentionally do NOT call event.stopPropagation()\n // so other listeners can also respond to ESC\n }\n }, true);\n}\n\n/**\n * Initialize the tooltip system.\n */\nfunction initializeTooltips() {\n // Wait for KaTeX to load (optional, for latex tooltips)\n const initInterval = setInterval(() => {\n if (typeof katex !== 'undefined') {\n clearInterval(initInterval);\n if (!listenersAttached) {\n attachListeners();\n }\n }\n }, 100);\n\n // Timeout after 2 seconds - attach listeners anyway for plain tooltips\n setTimeout(() => {\n clearInterval(initInterval);\n if (!listenersAttached) {\n attachListeners();\n }\n }, 2000);\n}\n\n/**\n * Set a tooltip on an element programmatically.\n * @param {HTMLElement} element - Target element\n * @param {string} text - Tooltip text\n * @param {boolean} [isLatex=false] - Whether to render as LaTeX\n */\nfunction setTooltip(element, text, isLatex = false) {\n if (!element || !text) return;\n\n // Remove any existing title attribute\n element.removeAttribute('title');\n\n if (isLatex) {\n element.classList.add('has-latex-tooltip');\n element.classList.remove('twm-has-tooltip');\n element.setAttribute('data-latex-tooltip', text);\n } else {\n element.classList.add('twm-has-tooltip');\n element.classList.remove('has-latex-tooltip');\n element.setAttribute('data-tooltip', text);\n }\n}\n\n/**\n * Refresh tooltips for dynamically added content.\n * Removes title attributes that might cause native tooltips.\n * @param {HTMLElement} [container=document] - Container to search within\n */\nfunction refreshTooltips(container = document) {\n container.querySelectorAll('.twm-has-tooltip, .has-latex-tooltip').forEach(el => {\n el.removeAttribute('title');\n });\n}\n\n// ES module exports \u2014 the real interface.\nexport const TooltipService = {\n show: showTooltip,\n hide: hideTooltip,\n set: setTooltip,\n refresh: refreshTooltips,\n init: initializeTooltips\n};\n\nexport default TooltipService;\n\n// Everything below is a side effect of IMPORTING this file, and it is guarded.\n//\n// Unguarded, it touched `document` and `window` at module scope, which made\n// @flexdesk/widgets throw `ReferenceError: window is not defined` the moment anything\n// imported it outside a browser. The DOM check is not defensive programming; it\n// is the difference between a module and a script.\n//\n// `window.LatexTooltip` stays, because unlike `window.InlineRenamer` it is real:\n// roughly 25 call sites read it, all as `window.LatexTooltip?.set(...)`, and one\n// of them is INSIDE the library (window_chrome_controller.js). That last one is a\n// hidden dependency on a global and should import TooltipService instead \u2014 a small\n// piece of P6 cleanup, noted rather than smuggled in here.\nif (typeof document !== 'undefined') {\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', initializeTooltips);\n } else {\n initializeTooltips();\n }\n}\n\nif (typeof window !== 'undefined') {\n window.LatexTooltip = TooltipService;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["icon", "el", "icon", "list", "el", "options", "text", "icon", "icon", "el", "icon", "icon", "el", "SEQ", "appendContent", "el", "icon", "el", "k", "header", "info", "icon", "setText", "el", "icon", "icon", "STEP_STATES", "icon", "icon", "e", "el", "more", "el", "el", "el", "el", "el"]
7
7
  }