flexdesk 0.18.0 → 0.18.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -0
- package/css/flexdesk.css +83 -5
- package/css/tokens.css +7 -0
- package/dist/charts.js +78 -12
- package/dist/charts.js.map +2 -2
- package/dist/{chunk-5W4EEKSK.js → chunk-3BLIVOFD.js} +3 -3
- package/dist/{chunk-P74F6I6P.js → chunk-4X4SY3CP.js} +4 -4
- package/dist/{chunk-P74F6I6P.js.map → chunk-4X4SY3CP.js.map} +2 -2
- package/dist/{chunk-ZL3VKINP.js → chunk-HL3IIHU3.js} +494 -3
- package/dist/{chunk-ZL3VKINP.js.map → chunk-HL3IIHU3.js.map} +4 -4
- package/dist/{chunk-RKVYIXDC.js → chunk-NFZJ6P42.js} +19 -500
- package/dist/chunk-NFZJ6P42.js.map +7 -0
- package/dist/{chunk-U5GKJUOC.js → chunk-QRBOIUU3.js} +5 -6
- package/dist/chunk-QRBOIUU3.js.map +7 -0
- package/dist/flexdesk.css +83 -5
- package/dist/flow.js +22 -10
- package/dist/flow.js.map +2 -2
- package/dist/git.js +3 -3
- package/dist/tiles.js +4 -4
- package/dist/tokens.css +7 -0
- package/dist/widgets.js +226 -58
- package/dist/widgets.js.map +2 -2
- package/dist/wm.js +2 -2
- package/docs/components/charts.md +40 -0
- package/docs/components/chat-shell.md +8 -2
- package/docs/components/filter-builder.md +52 -6
- package/docs/components/flow-editors.md +20 -0
- package/docs/components/forms-and-dialogs.md +8 -0
- package/docs/components/input-fields.md +24 -0
- package/docs/components/menus.md +4 -0
- package/docs/components/shell.md +4 -0
- package/docs/components/workspace-picker.md +46 -2
- package/package.json +1 -1
- package/src/charts/plot_config_editor.js +92 -6
- package/src/charts/plot_grid.js +6 -1
- package/src/flow/kit/settings_panel.js +24 -9
- package/src/ui/components/chat_shell.js +7 -1
- package/src/ui/components/context_menu.js +8 -2
- package/src/ui/components/filter_builder.js +53 -28
- package/src/ui/components/filter_model.js +86 -18
- package/src/ui/components/inline_renamer.js +10 -5
- package/src/ui/components/modal.js +25 -8
- package/src/ui/components/workspace_picker.js +125 -27
- package/src/ui/utils/tooltip_service.js +81 -14
- package/dist/chunk-RKVYIXDC.js.map +0 -7
- package/dist/chunk-U5GKJUOC.js.map +0 -7
- /package/dist/{chunk-5W4EEKSK.js.map → chunk-3BLIVOFD.js.map} +0 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/ui/components/autocomplete_field.js", "../src/ui/components/cell_editor_host.js", "../src/ui/components/cell_editors.js", "../src/ui/components/cell_selection.js", "../src/ui/utils/raf_resize_observer.js", "../src/ui/components/table_values.js", "../src/ui/components/table_filter_chips.js", "../src/ui/components/staged_history.js", "../src/ui/components/series.js", "../src/ui/components/tsv.js", "../src/ui/components/inline_renamer.js", "../src/ui/components/staged_edits.js", "../src/ui/components/fill_handle.js", "../src/ui/components/cell_paste.js", "../src/ui/components/cell_grid.js", "../src/ui/components/column_order.js", "../src/ui/components/header_actions.js", "../src/ui/components/column_groups.js", "../src/ui/components/crosstab.js", "../src/ui/components/table_structure.js", "../src/ui/components/data_table.js"],
|
|
4
|
+
"sourcesContent": ["/**\n * Autocomplete Field Component\n * Location: ui/components/autocomplete_field.js\n *\n * Purpose: Provide autocomplete dropdown for text input fields,\n * specifically designed for variable reference inputs.\n *\n * Usage:\n * const ac = new AutocompleteField({\n * fieldId: 'my-input',\n * field: { placeholder: '...', value: '...' },\n * provider: ({ value }) => [{ label: 'foo', type: 'variable' }, ...],\n * onChange: (value) => { ... }\n * });\n * container.appendChild(ac.render());\n */\n\nexport class AutocompleteField {\n constructor({\n fieldId,\n field = {},\n provider = null,\n onChange = null,\n logger = null,\n namespace = null,\n namespaceOptions = [],\n showNamespaceSelect = false,\n variant = null,\n showNamespaceChip = false,\n allowScopeToggle = false,\n namespaceLabel = null,\n scopeMode = 'current',\n skipNamespacePrefix = false,\n // Material symbol per completion type, merged over the generic set. The\n // framework's map used to include `sector: 'domain'` \u2014 an EcoAgent\n // completion type \u2014 so the widget knew one application's ontology.\n typeIcons = {},\n } = {}) {\n if (!fieldId) {\n throw new Error('AutocompleteField requires a fieldId');\n }\n this.fieldId = fieldId;\n this.field = field;\n this.provider = typeof provider === 'function' ? provider : () => [];\n this.onChange = typeof onChange === 'function' ? onChange : null;\n this.logger = logger;\n this.typeIcons = typeIcons ?? {};\n this.namespace = namespace;\n this.namespaceOptions = Array.isArray(namespaceOptions) ? [...namespaceOptions] : [];\n // Ensure the active namespace is always present as an option, even if\n // it was not provided (e.g., data manager not yet hydrated).\n if (this.namespace && !this.namespaceOptions.some((opt) => opt.value === this.namespace)) {\n const fallbackLabel = this.field.namespaceLabel || 'This Tab';\n this.namespaceOptions.push({ value: this.namespace, label: fallbackLabel, token: fallbackLabel });\n }\n this.showNamespaceSelect = Boolean(showNamespaceSelect);\n this.variant = variant;\n this.showNamespaceChip = Boolean(showNamespaceChip);\n this.allowScopeToggle = Boolean(allowScopeToggle);\n this.namespaceLabel = namespaceLabel;\n this.scope = scopeMode === 'all' ? 'all' : 'current';\n this.skipNamespacePrefix = Boolean(skipNamespacePrefix);\n this.disabled = Boolean(field.disabled);\n\n const parsed = this.#parseInitialNamespace(field.value ?? '');\n this.selectedNamespace = parsed.initialNamespace;\n this.initialFragment = parsed.initialFragment;\n\n this._lastDropdownRect = null;\n\n this.root = null;\n this.input = null;\n this.dropdown = null;\n this.helperEl = null;\n this.scopeControl = null;\n this.namespaceSelect = null;\n this.ghost = null;\n\n this._items = [];\n this._activeIndex = -1;\n this._isOpen = false;\n this._disposers = [];\n // Every call to the provider is numbered. See `#updateSuggestions`: a\n // provider that answers over the network answers out of order, and the\n // reply to \"No\" must not be allowed to overwrite the reply to \"North\".\n this._suggestSeq = 0;\n }\n\n getValue() {\n return this.#composeValue();\n }\n\n setComposedValue(value) {\n if (!this.input) return;\n const safeValue = typeof value === 'string' ? value : '';\n\n // When namespace prefixing is disabled, store the raw value\n if (this.skipNamespacePrefix) {\n this.input.value = safeValue;\n this.initialFragment = safeValue;\n this.#renderGhost();\n this.#close();\n return;\n }\n\n const parsed = this.#parseInitialNamespace(safeValue);\n this.selectedNamespace = parsed.initialNamespace;\n this.initialFragment = parsed.initialFragment;\n\n if (this.namespaceSelect) {\n this.namespaceSelect.value = this.selectedNamespace;\n }\n this.#updateNamespaceChip();\n this.input.value = parsed.initialFragment;\n this.#renderGhost();\n this.#close();\n }\n\n #parseInitialNamespace(rawValue) {\n const value = typeof rawValue === 'string' ? rawValue.trim() : '';\n const options = this.namespaceOptions;\n \n // Default to provided namespace when available; otherwise fall back to first option or '__ALL__'.\n const defaultNs = this.namespace \n ? (options.find((opt) => opt.value === this.namespace)?.value ?? this.namespace)\n : (options[0]?.value ?? '__ALL__');\n \n if (!options.length) {\n return { initialNamespace: defaultNs, initialFragment: value };\n }\n if (!value) {\n return { initialNamespace: defaultNs, initialFragment: '' };\n }\n \n // Check for namespace prefix (by value OR label)\n const dotIndex = value.indexOf('.');\n if (dotIndex > 0) {\n const nsCandidate = value.slice(0, dotIndex);\n const match = options.find((opt) => \n (opt.value || '').toLowerCase() === nsCandidate.toLowerCase() ||\n (opt.label || '').toLowerCase() === nsCandidate.toLowerCase()\n );\n if (match) {\n return { initialNamespace: match.value, initialFragment: value.slice(dotIndex + 1) };\n }\n }\n return { initialNamespace: defaultNs, initialFragment: value };\n }\n\n #resolveNamespaceLabel() {\n if (this.scope === 'all') {\n return 'All Namespaces';\n }\n if (typeof this.namespaceLabel === 'string' && this.namespaceLabel.trim()) {\n return this.namespaceLabel.trim();\n }\n if (typeof this.field.namespaceLabel === 'string' && this.field.namespaceLabel.trim()) {\n return this.field.namespaceLabel.trim();\n }\n if (typeof this.namespace === 'string' && this.namespace.trim()) {\n return this.namespace.trim();\n }\n return 'This Tab';\n }\n\n #toggleScope() {\n if (this.disabled) return;\n this.scope = this.scope === 'all' ? 'current' : 'all';\n this.root?.classList?.toggle('twm-autocomplete-field--scope-all', this.scope === 'all');\n this.#updateNamespaceChip();\n this.#updateSuggestions();\n }\n\n #updateNamespaceChip() {\n if (!this.scopeControl) return;\n this.scopeControl.textContent = this.#resolveNamespaceLabel();\n this.scopeControl.dataset.scope = this.scope;\n this.scopeControl.title = this.scope === 'all'\n ? 'Searching across all namespaces (click to limit to this tab)'\n : 'Searching this tab (click to search all namespaces)';\n }\n\n render() {\n if (this.root) {\n return this.root;\n }\n\n this.root = document.createElement('div');\n this.root.className = 'twm-autocomplete-field';\n if (this.variant) {\n this.root.classList.add(`twm-autocomplete-field--${this.variant}`);\n }\n this.root.classList.toggle('twm-autocomplete-field--scope-all', this.scope === 'all');\n\n const inputWrapper = document.createElement('div');\n inputWrapper.className = 'twm-autocomplete-field__input-wrapper';\n\n if (this.showNamespaceSelect && this.namespaceOptions.length) {\n const select = document.createElement('select');\n select.className = 'twm-autocomplete-field__namespace-select';\n this.namespaceOptions.forEach((opt) => {\n const option = document.createElement('option');\n option.value = opt.value;\n option.textContent = opt.label ?? opt.value;\n if (opt.value === this.selectedNamespace) {\n option.selected = true;\n }\n select.appendChild(option);\n });\n this.namespaceSelect = select;\n inputWrapper.appendChild(select);\n }\n\n if (this.showNamespaceChip) {\n const nsChip = document.createElement(this.allowScopeToggle ? 'button' : 'span');\n nsChip.className = 'twm-autocomplete-field__namespace';\n if (this.allowScopeToggle) {\n nsChip.setAttribute('type', 'button');\n }\n if (this.allowScopeToggle) {\n nsChip.classList.add('twm-autocomplete-field__namespace--toggle');\n nsChip.addEventListener('click', () => this.#toggleScope());\n }\n this.scopeControl = nsChip;\n this.#updateNamespaceChip();\n inputWrapper.appendChild(nsChip);\n }\n\n this.input = document.createElement('input');\n this.input.type = 'text';\n this.input.className = 'twm-autocomplete-field__input';\n this.input.id = this.fieldId;\n this.input.autocomplete = 'off';\n this.input.spellcheck = false;\n if (this.field.placeholder) {\n this.input.placeholder = this.field.placeholder;\n }\n if (this.field.value != null) {\n this.input.value = this.initialFragment;\n }\n if (this.disabled) {\n this.input.disabled = true;\n this.root.classList.add('twm-autocomplete-field--disabled');\n }\n inputWrapper.appendChild(this.input);\n\n // Ghost overlay disabled - namespace select provides visual context\n this.ghost = null;\n\n this.dropdown = document.createElement('div');\n this.dropdown.className = 'twm-autocomplete-field__dropdown';\n this.dropdown.setAttribute('role', 'listbox');\n // Append dropdown to body to escape stacking context limitations\n document.body.appendChild(this.dropdown);\n\n this.helperEl = document.createElement('div');\n this.helperEl.className = 'twm-autocomplete-field__helper twm-config-hint';\n if (this.field.helperText) {\n this.helperEl.textContent = this.field.helperText;\n }\n\n this.root.appendChild(inputWrapper);\n this.root.appendChild(this.helperEl);\n\n this.#wireEvents();\n this.#renderGhost();\n return this.root;\n }\n\n #wireEvents() {\n const onInput = () => {\n if (this.disabled) return;\n this.#syncNamespaceFromInput();\n this.#renderGhost();\n this.#updateSuggestions();\n };\n\n const onChange = () => {\n this.onChange?.(this.#composeValue(), { immediate: false, namespace: this.selectedNamespace });\n };\n\n const onPaste = () => {\n // No special paste handling needed\n };\n\n const onKeyDown = (e) => {\n if (this.disabled) return;\n this.#handleKeyDown(e);\n };\n\n const onFocus = () => {\n if (this.disabled) return;\n this.#updateSuggestions();\n };\n\n const onBlur = (e) => {\n // Delay close to allow click on dropdown items\n setTimeout(() => {\n if (!this.root?.contains(document.activeElement)) {\n this.#close();\n // Trigger save on blur (similar to change event)\n this.onChange?.(this.#composeValue(), { immediate: false, namespace: this.selectedNamespace });\n }\n }, 150);\n };\n\n const onDropdownMouseDown = (e) => {\n // Prevent blur when clicking dropdown\n e.preventDefault();\n };\n\n const onDropdownClick = (e) => {\n const item = e.target.closest('.twm-autocomplete-field__item');\n if (item) {\n const index = parseInt(item.dataset.index, 10);\n if (!isNaN(index)) {\n this.#selectItem(index);\n }\n }\n };\n\n this.input.addEventListener('input', onInput);\n this.input.addEventListener('change', onChange);\n this.input.addEventListener('paste', onPaste);\n this.input.addEventListener('keydown', onKeyDown);\n this.input.addEventListener('focus', onFocus);\n this.input.addEventListener('blur', onBlur);\n this.dropdown.addEventListener('mousedown', onDropdownMouseDown);\n this.dropdown.addEventListener('click', onDropdownClick);\n\n if (this.namespaceSelect) {\n const onSelectChange = () => {\n // Store the new namespace selection\n this.selectedNamespace = this.namespaceSelect.value;\n // Refresh suggestions and notify listener so selection can be persisted\n this.#updateSuggestions();\n this.onChange?.(this.#composeValue(), { \n immediate: false, \n namespace: this.selectedNamespace,\n viewNamespace: this.selectedNamespace\n });\n };\n this.namespaceSelect.addEventListener('change', onSelectChange);\n this._disposers.push(() => this.namespaceSelect.removeEventListener('change', onSelectChange));\n }\n\n const onWindowResize = () => {\n if (this._isOpen) {\n this.#positionDropdown();\n }\n };\n window.addEventListener('resize', onWindowResize);\n\n // Close dropdown when user scrolls (dropdown is position: fixed so doesn't move with content)\n const onScroll = (e) => {\n if (!this._isOpen) return;\n // Don't close if scrolling inside the dropdown itself\n if (this.dropdown?.contains(e.target)) return;\n this.#close();\n };\n document.addEventListener('scroll', onScroll, true); // capture phase catches all scroll events\n this._disposers.push(() => {\n document.removeEventListener('scroll', onScroll, true);\n });\n\n // Close dropdown when clicking outside (anywhere not in root or dropdown)\n const onDocumentClick = (e) => {\n if (!this._isOpen) return;\n const clickedInRoot = this.root?.contains(e.target);\n const clickedInDropdown = this.dropdown?.contains(e.target);\n if (!clickedInRoot && !clickedInDropdown) {\n this.#close();\n }\n };\n document.addEventListener('click', onDocumentClick, true);\n\n this._disposers.push(() => {\n window.removeEventListener('resize', onWindowResize);\n });\n this._disposers.push(() => {\n document.removeEventListener('click', onDocumentClick, true);\n });\n\n this._disposers.push(() => {\n this.input.removeEventListener('input', onInput);\n this.input.removeEventListener('change', onChange);\n this.input.removeEventListener('paste', onPaste);\n this.input.removeEventListener('keydown', onKeyDown);\n this.input.removeEventListener('focus', onFocus);\n this.input.removeEventListener('blur', onBlur);\n this.dropdown.removeEventListener('mousedown', onDropdownMouseDown);\n this.dropdown.removeEventListener('click', onDropdownClick);\n });\n }\n\n #handleKeyDown(e) {\n if (!this._isOpen) {\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {\n this.#updateSuggestions();\n e.preventDefault();\n }\n return;\n }\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n this.#moveSelection(1);\n break;\n case 'ArrowUp':\n e.preventDefault();\n this.#moveSelection(-1);\n break;\n case 'Enter':\n e.preventDefault();\n if (this._activeIndex >= 0) {\n this.#selectItem(this._activeIndex);\n }\n // Always blur on Enter to trigger save\n this.input?.blur();\n break;\n case 'Tab':\n if (this._activeIndex >= 0) {\n e.preventDefault();\n this.#selectItem(this._activeIndex);\n }\n break;\n case 'Escape':\n e.preventDefault();\n this.#close();\n break;\n }\n }\n\n #updateSuggestions() {\n // Pass the fragment (variable part) for filtering, not the full composed value\n const fragment = this.#getInputFragment();\n\n // A PROVIDER MAY ANSWER LATER THAN IT WAS ASKED.\n //\n // This used to require the answer synchronously \u2014 `provider(...) || []`\n // straight into `Array.isArray`, so a provider that returned a promise\n // produced an empty list and a dropdown that closed on every keystroke.\n // That ruled out the entire class of completion source that lives on a\n // server, which is most of them outside a single-page simulation: a\n // table's rows, a query's result set, an index's matches.\n //\n // A provider that answers synchronously still takes the synchronous\n // path, unchanged and untouched, so nothing that works today changes.\n // A provider that hands back a thenable is awaited, and the reply is\n // used only if it is the reply to the most recent question \u2014 typing\n // \"North\" fires five requests and the network is free to answer them in\n // any order, so without the sequence number the list can settle on the\n // matches for \"Nor\".\n const request = ++this._suggestSeq;\n let produced;\n try {\n produced = this.provider({\n value: fragment,\n scope: this.scope,\n namespace: this.selectedNamespace\n });\n } catch (err) {\n this.logger?.warn?.('autocomplete', 'Provider error', { err });\n this._items = [];\n this.#close();\n return;\n }\n\n if (produced && typeof produced.then === 'function') {\n produced.then(\n (items) => {\n if (request !== this._suggestSeq) return;\n this.#applySuggestions(items);\n },\n (err) => {\n this.logger?.warn?.('autocomplete', 'Provider error', { err });\n if (request !== this._suggestSeq) return;\n this._items = [];\n this.#close();\n }\n );\n return;\n }\n\n this.#applySuggestions(produced);\n }\n\n /** Draw whatever the provider produced. Split out of `#updateSuggestions`\n * so the synchronous and the awaited paths cannot drift apart. */\n #applySuggestions(produced) {\n const items = Array.isArray(produced) ? produced : [];\n this._items = items;\n this._activeIndex = items.length > 0 ? 0 : -1;\n this.#renderDropdown();\n if (items.length > 0) {\n this.#open();\n } else {\n this.#close();\n }\n }\n\n #renderDropdown() {\n this.dropdown.innerHTML = '';\n const showingAll = this.selectedNamespace === '__ALL__';\n \n this._items.forEach((item, index) => {\n const el = document.createElement('div');\n el.className = 'twm-autocomplete-field__item';\n el.setAttribute('role', 'option');\n el.dataset.index = index;\n el.dataset.type = item.type || item.iconType || 'variable';\n if (index === this._activeIndex) {\n el.classList.add('active');\n }\n\n // Icon based on type\n const icon = document.createElement('span');\n icon.className = 'twm-autocomplete-field__icon material-symbols-outlined';\n icon.textContent = this.#getIconForType(item.type || item.iconType);\n el.appendChild(icon);\n\n // Label\n const label = document.createElement('span');\n label.className = 'twm-autocomplete-field__label';\n label.textContent = item.label || item.insertText || '';\n el.appendChild(label);\n\n // Show namespace indicator when viewing all namespaces\n if (showingAll && item.metadata?.namespaceId) {\n const nsLabel = this.#resolveNamespaceToken(item.metadata.namespaceId);\n if (nsLabel) {\n const nsIndicator = document.createElement('span');\n nsIndicator.className = 'twm-autocomplete-field__namespace-indicator';\n nsIndicator.textContent = nsLabel;\n el.appendChild(nsIndicator);\n }\n }\n\n // Optional badge (type)\n if (item.type && !showingAll) {\n const badge = document.createElement('span');\n badge.className = 'twm-autocomplete-field__badge';\n badge.textContent = item.type;\n el.appendChild(badge);\n }\n\n this.dropdown.appendChild(el);\n });\n if (this._isOpen) {\n this.#positionDropdown();\n }\n }\n\n #resolveNamespaceToken(namespaceId) {\n if (!namespaceId) return null;\n const opt = this.namespaceOptions.find((o) => o.value === namespaceId);\n return opt?.token || opt?.label || null;\n }\n\n #getIconForType(type) {\n const icons = {\n variable: 'functions',\n 'variable-qualified': 'link',\n stock: 'account_balance',\n account: 'savings',\n function: 'code',\n constant: 'numbers',\n operator: 'calculate',\n snippet: 'content_paste',\n ...this.typeIcons,\n };\n return icons[type] || 'label';\n }\n\n #moveSelection(delta) {\n if (this._items.length === 0) return;\n let newIndex = this._activeIndex + delta;\n if (newIndex < 0) newIndex = this._items.length - 1;\n if (newIndex >= this._items.length) newIndex = 0;\n this._activeIndex = newIndex;\n this.#renderDropdown();\n this.#scrollToActive();\n }\n\n #scrollToActive() {\n const activeEl = this.dropdown.querySelector('.twm-autocomplete-field__item.active');\n if (activeEl) {\n activeEl.scrollIntoView({ block: 'nearest', behavior: 'smooth' });\n }\n }\n\n #selectItem(index) {\n const item = this._items[index];\n if (!item) return;\n \n // Extract namespace from the selected item's metadata\n const itemNamespace = item.metadata?.namespaceId || null;\n \n // Put just the variable name in the input (not qualified)\n const insertText = item.insertText || item.label || '';\n this.input.value = insertText;\n \n // When \"All\" is selected, do NOT change the dropdown - keep it at \"All\"\n // Instead, pass the item's namespace via the callback so it's saved correctly\n // This allows users to stay in \"All\" view while browsing/selecting variables\n const viewNamespace = this.selectedNamespace; // What the dropdown shows (\"__ALL__\" or specific)\n const resolvedNamespace = (viewNamespace === '__ALL__' && itemNamespace) \n ? itemNamespace \n : viewNamespace;\n \n this.#close();\n this.input.focus();\n // Emit composed value with both namespace values and item metadata\n this.onChange?.(this.#composeValue(), {\n immediate: true,\n namespace: resolvedNamespace,\n viewNamespace: viewNamespace,\n metadata: item.metadata || null,\n });\n }\n\n #open() {\n if (this._isOpen) {\n return;\n }\n this._isOpen = true;\n this.#positionDropdown();\n this.dropdown.classList.add('visible');\n }\n\n #close() {\n if (!this._isOpen) return;\n this._isOpen = false;\n this.dropdown.classList.remove('visible');\n this._activeIndex = -1;\n }\n\n #syncNamespaceFromInput() {\n // Auto-switch namespace dropdown when user types \"Namespace.\" prefix\n // But do NOT modify the input value - keep what user typed\n // Also do NOT switch away from \"__ALL__\" unless user explicitly types a namespace prefix\n if (!this.namespaceOptions.length) return;\n const value = this.input?.value || '';\n const dotIndex = value.indexOf('.');\n if (dotIndex > 0) {\n const nsCandidate = value.slice(0, dotIndex);\n // Match by value OR display label\n const match = this.namespaceOptions.find((opt) => \n opt.value !== '__ALL__' && (\n (opt.value || '').toLowerCase() === nsCandidate.toLowerCase() ||\n (opt.label || '').toLowerCase() === nsCandidate.toLowerCase() ||\n (opt.token || '').toLowerCase() === nsCandidate.toLowerCase()\n )\n );\n if (match && this.namespaceSelect && this.namespaceSelect.value !== match.value) {\n this.namespaceSelect.value = match.value;\n this.selectedNamespace = match.value;\n }\n }\n // Note: We no longer auto-reset to a namespace when typing without a dot\n // This allows \"All\" selection to remain stable\n }\n\n #getInputFragment() {\n // Get the variable name fragment from input (strip namespace prefix if present)\n const value = this.input?.value || '';\n const dotIndex = value.indexOf('.');\n if (dotIndex > 0) {\n const nsCandidate = value.slice(0, dotIndex);\n const match = this.namespaceOptions.find((opt) => \n opt.value !== '__ALL__' && (\n (opt.value || '').toLowerCase() === nsCandidate.toLowerCase() ||\n (opt.label || '').toLowerCase() === nsCandidate.toLowerCase()\n )\n );\n if (match) {\n return value.slice(dotIndex + 1);\n }\n }\n return value;\n }\n\n #composeValue() {\n // Compose the full reference value for saving\n // Use the raw input value - it may already contain namespace prefix\n const rawInput = this.input?.value || '';\n if (!rawInput) return '';\n \n // Skip namespace prefixing for simple value fields (e.g., sector, account name)\n if (this.skipNamespacePrefix) {\n return rawInput;\n }\n \n // If input already has a namespace prefix, return as-is\n const dotIndex = rawInput.indexOf('.');\n if (dotIndex > 0) {\n const nsCandidate = rawInput.slice(0, dotIndex);\n const match = this.namespaceOptions.find((opt) => \n opt.value !== '__ALL__' && (\n (opt.value || '').toLowerCase() === nsCandidate.toLowerCase() ||\n (opt.label || '').toLowerCase() === nsCandidate.toLowerCase()\n )\n );\n if (match) {\n // Input already has valid namespace prefix, return as-is\n return rawInput;\n }\n }\n \n // No namespace prefix in input - prepend from dropdown if not \"All\"\n const ns = this.selectedNamespace;\n if (!ns || ns === '__ALL__') {\n return rawInput;\n }\n \n // Find display label for the namespace (case-insensitive search)\n const nsOption = this.namespaceOptions.find((opt) => \n opt.value === ns || (opt.value || '').toLowerCase() === (ns || '').toLowerCase()\n );\n\n // Choose a human-friendly token; fall back to label. If we only have a UUID-looking\n // token, avoid prefixing to prevent UUIDs leaking into the input.\n const nsToken = nsOption?.token || nsOption?.label || '';\n const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n if (ns === '__ALL__' || (nsToken || '').toUpperCase() === '__ALL__') {\n return rawInput;\n }\n if (!nsToken || uuidPattern.test(nsToken)) {\n return rawInput;\n }\n\n return `${nsToken}.${rawInput}`;\n }\n\n #renderGhost() {\n // Ghost overlay is disabled - it interferes with the input\n // The namespace select already provides visual context\n if (this.ghost) {\n this.ghost.style.display = 'none';\n }\n }\n\n #positionDropdown() {\n if (!this.dropdown || !this.root) return;\n const wrapper = this.root.querySelector('.twm-autocomplete-field__input-wrapper');\n if (!wrapper) return;\n const rect = wrapper.getBoundingClientRect();\n this._lastDropdownRect = rect;\n const viewportWidth = document.documentElement.clientWidth || window.innerWidth;\n const viewportHeight = document.documentElement.clientHeight || window.innerHeight;\n const width = Math.min(rect.width, viewportWidth - rect.left - 8);\n const maxHeight = Math.max(120, viewportHeight - rect.bottom - 12);\n Object.assign(this.dropdown.style, {\n position: 'fixed',\n top: `${rect.bottom}px`,\n left: `${rect.left}px`,\n width: `${width}px`,\n maxWidth: `${width}px`,\n maxHeight: `${maxHeight}px`,\n });\n }\n\n dispose() {\n // Retire the outstanding question first. An awaited provider can answer\n // after the field is gone, and `#applySuggestions` would then paint into\n // a dropdown that has been removed and nulled.\n this._suggestSeq += 1;\n // Close dropdown before cleanup\n this.#close();\n this._disposers.forEach((fn) => {\n try { fn(); } catch (e) { /* ignore */ }\n });\n this._disposers = [];\n // Remove dropdown from body since we appended it there\n if (this.dropdown && this.dropdown.parentNode) {\n this.dropdown.parentNode.removeChild(this.dropdown);\n }\n this.root = null;\n this.input = null;\n this.dropdown = null;\n this.helperEl = null;\n }\n}\n", "/**\n * cell_editor_host.js \u2014 STORY-0003. ONE CELL BEING EDITED: open an editor in\n * it, and close it exactly once \u2014 by a commit or by a cancel.\n *\n * The editor itself comes from a FACTORY, so a consumer can bring any editor\n * it likes (DataTable's `editors` option); the plain text box below is the\n * default. A factory is called with\n *\n * { ...args, value, row, rowIdx, colIdx, column: {index, header, type},\n * initialText, commit(value, move?), cancel() }\n *\n * and returns either an element, or\n * `{ el, getValue?, parse?, multiline?, focus?, destroy? }`.\n * `initialText` is the character typed to open the editor (null when it was\n * opened by F2, Enter or a double-click): the editor starts with it in place\n * of the value, as a spreadsheet does.\n *\n * \u2550\u2550 THE KEYS, WHICH THE HOST OWNS \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\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 * Enter commit, and the table moves the cursor down (Shift: up)\n * Tab commit, and the cursor moves right (Shift: left)\n * Escape cancel: the cell is drawn as it was, and nothing is called\n * focus out commit, without moving \u2014 a click elsewhere keeps the edit\n *\n * Enter and Tab commit `getValue()` \u2014 an input, select or textarea's `value`\n * when the factory returned the field itself; any other editor without a\n * `getValue` calls `commit(value)` itself. Such an editor has no value the host\n * can read: Enter, Tab and the focus leaving do nothing, and `commit()` from\n * outside (its row leaving a virtual window) CANCELS it. Every key\n * pressed in the editor stops there: the table's own keys (the arrows, Ctrl+A,\n * Ctrl+C) are not the editor's.\n *\n * \u2550\u2550 A VALUE THAT DOES NOT PARSE (STORY-0087) \u2550\u2550\u2550\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 editor with a `parse()` \u2014 `() => {ok: true, value} | {ok: false, error}`\n * \u2014 commits what `parse()` reads, not `getValue()`. A refusal on Enter or Tab\n * keeps the editor open, and its cell carries the message\n * (`twm-dt-cell--error`, `title`, `data-error`) until the next keystroke in\n * it; nothing is committed. A refusal when the focus leaves, or on `commit()`\n * from outside, closes the editor and hands `onRefuse` the message and the\n * text (`getValue()`); still nothing is committed. A `multiline` editor\n * keeps Enter for a new line: Ctrl/Cmd+Enter commits it.\n *\n * `commit(value, move?)` takes an optional move ('down', 'up', 'right',\n * 'left'), for an editor that commits on a key of its own.\n *\n * \u2550\u2550 EXACTLY ONCE \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\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 session closes once. Escape's own repaint takes the focused input out of\n * the document, and a browser fires `focusout` for that \u2014 the commit listener.\n * The session is marked closed BEFORE anything is taken out, so that late\n * `focusout` (and a second Enter, and an editor that calls `commit` twice)\n * finds nothing to do.\n */\n\n/**\n * The default editor: a text box holding the value as text (or the character\n * that opened it). Left unchanged, it commits the value it was given \u2014 not\n * that value turned into a string \u2014 so opening and leaving a number cell is\n * no edit at all.\n */\nexport function createTextEditor({ value, initialText = null }) {\n const input = document.createElement('input');\n input.type = 'text';\n input.className = 'twm-dt-editor';\n input.spellcheck = false;\n input.setAttribute('autocomplete', 'off');\n const start = value == null ? '' : String(value);\n input.value = initialText != null ? String(initialText) : start;\n return {\n el: input,\n getValue: () => (initialText == null && input.value === start ? value : input.value),\n focus: () => {\n input.focus({ preventScroll: true });\n const end = input.value.length;\n try { input.setSelectionRange(end, end); } catch (_) { /* not a text type */ }\n },\n };\n}\n\n/** What a factory returned, as one shape \u2014 or null when it returned nothing. */\nfunction normalise(made) {\n if (!made) return null;\n const isNode = typeof Node !== 'undefined' && made instanceof Node;\n const el = isNode ? made : made.el;\n if (!el || (typeof Node !== 'undefined' && !(el instanceof Node))) return null;\n const own = isNode ? {} : made;\n let getValue = typeof own.getValue === 'function' ? own.getValue : null;\n // A form field's value is the editor's; any other element says for itself.\n if (!getValue && el.matches?.('input, select, textarea')) getValue = () => el.value;\n const parse = typeof own.parse === 'function' ? own.parse : null;\n // What a commit reads: the parse, else the value as it is.\n let read = null;\n if (parse) {\n read = () => {\n let r;\n try { r = parse(); } catch (err) { r = { ok: false, error: err?.message || String(err) }; }\n return r && r.ok === false ? { ok: false, error: String(r.error ?? 'Not valid') }\n : { ok: true, value: r ? r.value : undefined };\n };\n } else if (getValue) read = () => ({ ok: true, value: getValue() });\n return {\n el,\n getValue,\n read,\n multiline: !!own.multiline,\n focus: typeof own.focus === 'function' ? own.focus : null,\n destroy: typeof own.destroy === 'function' ? own.destroy : null,\n };\n}\n\nconst MOVES = new Set(['down', 'up', 'right', 'left']);\n\nexport class CellEditorHost {\n /**\n * @param {object} o\n * @param {(session, value, move, reason) => void} o.onCommit after the\n * cell is drawn as it was again; `move` is 'down', 'up', 'right', 'left'\n * or null; `reason` is 'key', 'blur', 'editor' or 'scroll'.\n * @param {(session, reason) => void} o.onCancel\n * @param {(session, error, text, reason) => void} [o.onRefuse] a value\n * that did not parse, when the editor closed with it (the focus left,\n * `commit()` from outside); without it such a close is a cancel.\n */\n constructor({ onCommit, onCancel, onRefuse = null }) {\n this._onCommit = onCommit;\n this._onCancel = onCancel;\n this._onRefuse = onRefuse;\n /** The open session, or null. */\n this.session = null;\n }\n\n /**\n * Open an editor in `td`; `args` go to the factory beside the cell's own\n * (DataTable's `locale`, `utc`, `messages`). Returns whether one opened (a factory that\n * throws or returns nothing opens none, and the cell is untouched).\n */\n open({ td, factory, value, row, rowIdx, colIdx, column, initialText = null, args = {}, ...extra }) {\n if (this.session) return false;\n const s = {\n ...extra, td, value, row, rowIdx, colIdx, column,\n previous: value, closed: false, offs: [], saved: null, editor: null,\n };\n let made = null;\n try {\n made = factory({\n ...args, value, row, rowIdx, colIdx, column, initialText,\n commit: (v, move = null) => this._finish(s, v, MOVES.has(move) ? move : null, 'editor'),\n cancel: () => this._cancel(s, 'editor'),\n });\n } catch (err) {\n console.error('[DataTable] cell editor factory threw', err);\n return false;\n }\n const editor = normalise(made);\n if (!editor) return false;\n s.editor = editor;\n s.saved = [...td.childNodes];\n s.savedTitle = td.getAttribute('title');\n s.savedError = {\n on: td.classList.contains('twm-dt-cell--error'),\n message: td.getAttribute('data-error'),\n };\n this.session = s;\n td.classList.add('twm-dt-cell--editing');\n td.replaceChildren(editor.el);\n\n const on = (type, fn) => {\n editor.el.addEventListener(type, fn);\n s.offs.push(() => editor.el.removeEventListener(type, fn));\n };\n on('keydown', (ev) => {\n if (ev.isComposing) return;\n ev.stopPropagation();\n if (ev.key === 'Escape') {\n ev.preventDefault();\n this._cancel(s, 'key');\n } else if (ev.key === 'Enter' && !ev.altKey && editor.read\n && (editor.multiline ? (ev.ctrlKey || ev.metaKey) : !(ev.ctrlKey || ev.metaKey))) {\n ev.preventDefault();\n this._tryKey(s, ev.shiftKey ? 'up' : 'down');\n } else if (ev.key === 'Tab' && !ev.altKey && !ev.ctrlKey && !ev.metaKey && editor.read) {\n ev.preventDefault();\n this._tryKey(s, ev.shiftKey ? 'left' : 'right');\n }\n });\n // A refusal's message stands until the text changes.\n on('input', () => this._unmark(s));\n // A press inside the editor is the editor's, not a click on the cell.\n for (const type of ['click', 'dblclick', 'mousedown', 'contextmenu']) {\n on(type, (ev) => ev.stopPropagation());\n }\n on('focusout', (ev) => {\n if (s.closed || !editor.read) return;\n const to = ev.relatedTarget;\n if (to && editor.el.contains(to)) return;\n // The window losing focus (another app) is not a click elsewhere.\n const doc = editor.el.ownerDocument;\n if (!to && doc && typeof doc.hasFocus === 'function' && !doc.hasFocus()) return;\n this._settle(s, null, 'blur');\n });\n\n try {\n if (editor.focus) editor.focus();\n else editor.el.focus?.({ preventScroll: true });\n } catch (_) { /* not focusable */ }\n return true;\n }\n\n /** Commit the open session with what its editor holds. */\n commit(move = null, reason = 'editor') {\n const s = this.session;\n if (!s) return false;\n if (!s.editor.read) { this._cancel(s, reason); return false; }\n return this._settle(s, move, reason);\n }\n\n /** Enter or Tab: commit what parses; a refusal keeps the editor open,\n * the message on its cell. */\n _tryKey(s, move) {\n const r = s.editor.read();\n if (r.ok) return this._finish(s, r.value, move, 'key');\n s.td.classList.add('twm-dt-cell--error');\n s.td.setAttribute('data-error', r.error);\n s.td.setAttribute('title', r.error);\n s.marked = true;\n return false;\n }\n\n _unmark(s) {\n if (!s.marked) return;\n s.marked = false;\n this._restoreMark(s);\n }\n\n _restoreMark(s) {\n const { on, message } = s.savedError;\n s.td.classList.toggle('twm-dt-cell--error', on);\n if (message == null) s.td.removeAttribute('data-error');\n else s.td.setAttribute('data-error', message);\n if (s.savedTitle == null) s.td.removeAttribute('title');\n else s.td.setAttribute('title', s.savedTitle);\n }\n\n /** The editor closing with what it holds (the focus left, `commit()`):\n * committed when it parses, else handed to `onRefuse`. */\n _settle(s, move, reason) {\n const r = s.editor.read();\n if (r.ok) return this._finish(s, r.value, move, reason);\n if (s.closed) return false;\n let text = '';\n try { text = s.editor.getValue ? s.editor.getValue() : ''; } catch (_) { /* gone */ }\n this._close(s);\n if (this._onRefuse) this._onRefuse(s, r.error, text, reason);\n else this._onCancel?.(s, reason);\n return true;\n }\n\n /** Cancel the open session: the cell is drawn as it was. */\n cancel(reason = 'editor') {\n const s = this.session;\n if (!s) return false;\n return this._cancel(s, reason);\n }\n\n /** Take the editor out and put the cell's own content back. */\n _close(s) {\n s.closed = true;\n if (this.session === s) this.session = null;\n for (const off of s.offs) { try { off(); } catch (_) { /* gone */ } }\n s.offs = [];\n try { s.editor.destroy?.(); } catch (err) {\n console.error('[DataTable] cell editor destroy threw', err);\n }\n s.td.classList.remove('twm-dt-cell--editing');\n s.td.replaceChildren(...s.saved);\n this._restoreMark(s);\n }\n\n _finish(s, value, move, reason) {\n if (s.closed) return false;\n this._close(s);\n this._onCommit?.(s, value, move, reason);\n return true;\n }\n\n _cancel(s, reason) {\n if (s.closed) return false;\n this._close(s);\n this._onCancel?.(s, reason);\n return true;\n }\n}\n", "/**\n * cell_editors.js \u2014 STORY-0087. THE SIX BUILT-IN CELL EDITORS, and the parse\n * each one reads its text with.\n *\n * text a text box commits the text\n * multitext a text area commits the text; Enter is a new\n * line, Ctrl/Cmd+Enter commits\n * number a text box commits a Number (or null)\n * bool a checkbox commits true or false\n * choice an AutocompleteField over commits one option's value (or\n * the column's `options` null; other text only with\n * `allowOther`)\n * datetime a text box commits a Date (or null)\n *\n * Each is `{create, parse}` in `CELL_EDITORS`. `create` is an editor factory\n * as `cell_editor_host.js` takes one; `parse(text, ctx)` is the same reading\n * as plain text, for anything that has text and not an editor (a paste):\n *\n * parse(text, { locale, utc, options, allowOther, messages })\n * \u2192 { ok: true, value } | { ok: false, error }\n *\n * An editor built here hands the host a `parse()` of its own (what it holds,\n * read the same way): Enter and Tab commit only what parses, and a refusal\n * keeps the editor open with the message on the cell.\n *\n * NUMBER. Read by the separators of `locale` (Intl's): '1.234,56' is\n * 1234.56 under 'de-DE' and '1,234.56' is under 'en-US'. A group separator\n * is accepted only between groups of three digits in the whole part, so\n * '1.234,56' under 'en-US' is refused rather than read as 1.23456. Spaces\n * around the text are ignored. A space inside it is accepted only as the\n * group separator of a locale that groups with a space (fr-FR, sv-SE, ...;\n * any space, a no-break one included), and only between groups of three\n * digits, so '1 234,5' is 1234.5 under 'fr-FR'; any other inner space is\n * refused ('1 234' under 'en-US' is refused, not read as 1234). A minus may\n * be '-' or '\u2212'.\n *\n * DATETIME. ISO 8601 ('2026-12-31', '2026-12-31T08:30', with 'Z' or an\n * offset an exact instant), or day, month and year in the order `locale`\n * writes them, separated by '/', '.' or '-', with a four-digit year and an\n * optional time ('31/12/2026 08:30'). When that order makes no date but the\n * day-month swap does ('31/12/2026' under 'en-US') the swap is read \u2014 there\n * is no other reading. A date without a zone is in the table's zone\n * (`utc`: UTC, else local).\n *\n * A value opened and left as it was commits the value the cell was given,\n * not its text read back, so opening and leaving a cell is no edit at all.\n */\n\nimport { AutocompleteField } from './autocomplete_field.js';\nimport { createTextEditor } from './cell_editor_host.js';\n\n/** The refusals' words. DataTable's `editorMessages` overrides any of them. */\nexport const EDITOR_MESSAGES = Object.freeze({\n number: 'Not a number',\n datetime: 'Not a date',\n bool: 'Not true or false',\n choice: 'Not one of the options',\n});\n\nconst ok = (value) => ({ ok: true, value });\nconst refuse = (ctx, type) => ({ ok: false, error: (ctx?.messages || {})[type] || EDITOR_MESSAGES[type] });\nconst isBlank = (text) => text == null || String(text).trim() === '';\n\n/** The type names of the table's columns that the built-in editors answer to. */\nconst ALIASES = { num: 'number', date: 'datetime' };\n\n/** The built-in editor's name for a column type: 'num' is 'number' and 'date'\n * is 'datetime'; any other name is itself. */\nexport function editorTypeOf(type) {\n const t = type == null ? 'text' : String(type);\n return ALIASES[t] || t;\n}\n\n// \u2500\u2500 number \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 safeLocale(locale) {\n if (!locale) return undefined;\n try { return Intl.NumberFormat.supportedLocalesOf(locale).length ? locale : undefined; }\n catch (_) { return undefined; }\n}\n\n/** `{group, decimal}`: the separators `locale` writes numbers with. */\nexport function numberSeparators(locale) {\n const parts = new Intl.NumberFormat(safeLocale(locale)).formatToParts(1234567.5);\n return {\n group: parts.find((p) => p.type === 'group')?.value ?? ',',\n decimal: parts.find((p) => p.type === 'decimal')?.value ?? '.',\n };\n}\n\nconst SPACES = /[\\s\\u00a0\\u202f]/g;\n\n/** Text to a Number by `locale`'s separators; blank is null. Spaces around\n * the text are ignored; inside it a space is a group separator only where\n * the locale groups with one (fr-FR, sv-SE, ...) and only between groups of\n * three digits; anywhere else it is refused. */\nexport function parseNumber(text, ctx = {}) {\n if (isBlank(text)) return ok(null);\n const { group, decimal } = numberSeparators(ctx.locale);\n let s = String(text).trim().replace(/\\u2212/g, '-');\n let sign = '';\n if (s[0] === '-' || s[0] === '+') { sign = s[0] === '-' ? '-' : ''; s = s.slice(1); }\n const halves = s.split(decimal);\n if (halves.length > 2) return refuse(ctx, 'number');\n let [whole, frac = null] = halves;\n let exp = '';\n const tail = frac ?? whole;\n const e = /[eE][+-]?\\d+$/.exec(tail);\n if (e) {\n exp = e[0];\n if (frac != null) frac = frac.slice(0, -exp.length);\n else whole = whole.slice(0, -exp.length);\n }\n const spaceGroup = group !== '' && group.replace(SPACES, '') === '';\n const g = spaceGroup ? ' ' : group;\n if (spaceGroup) whole = whole.replace(SPACES, ' ');\n if (g && whole.includes(g)) {\n const esc = g.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n if (!new RegExp(`^\\\\d{1,3}(${esc}\\\\d{3})+$`).test(whole)) return refuse(ctx, 'number');\n whole = whole.split(g).join('');\n }\n if (!/^\\d*$/.test(whole) || (frac != null && !/^\\d*$/.test(frac))) return refuse(ctx, 'number');\n if (!whole && !frac) return refuse(ctx, 'number');\n const n = Number(`${sign}${whole || '0'}.${frac || '0'}${exp}`);\n return Number.isFinite(n) ? ok(n) : refuse(ctx, 'number');\n}\n\n/** A number as the editor shows it: `locale`'s decimal separator, no groups,\n * every digit (so it reads back as itself). */\nexport function formatNumberForEdit(value, ctx = {}) {\n if (value == null) return '';\n if (typeof value !== 'number' || !Number.isFinite(value)) return String(value);\n const { decimal } = numberSeparators(ctx.locale);\n return String(value).replace('.', decimal);\n}\n\n// \u2500\u2500 bool \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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\nconst TRUE_WORDS = new Set(['true', 'yes', 'y', '1', 'on', 'x', '\u2713', '\u2714']);\nconst FALSE_WORDS = new Set(['false', 'no', 'n', '0', 'off', '']);\n\n/** 'true', 'yes', 'y', '1', 'on', 'x' are true; 'false', 'no', 'n', '0', 'off'\n * and blank are false (any case); anything else is refused. */\nexport function parseBool(text, ctx = {}) {\n if (typeof text === 'boolean') return ok(text);\n const t = String(text ?? '').trim().toLowerCase();\n if (TRUE_WORDS.has(t)) return ok(true);\n if (FALSE_WORDS.has(t)) return ok(false);\n return refuse(ctx, 'bool');\n}\n\nfunction truthy(value) {\n if (typeof value === 'boolean') return value;\n if (value == null) return false;\n const r = parseBool(String(value));\n return r.ok ? r.value : true;\n}\n\n// \u2500\u2500 datetime \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 order `locale` writes a date's parts in, e.g. ['day', 'month', 'year']. */\nexport function dateOrder(locale) {\n let loc;\n try { loc = Intl.DateTimeFormat.supportedLocalesOf(locale || []).length ? locale : undefined; }\n catch (_) { loc = undefined; }\n return new Intl.DateTimeFormat(loc, { year: 'numeric', month: '2-digit', day: '2-digit' })\n .formatToParts(new Date(2026, 11, 31))\n .map((p) => p.type)\n .filter((t) => t === 'day' || t === 'month' || t === 'year');\n}\n\nfunction daysIn(y, m) {\n return new Date(Date.UTC(y, m, 0)).getUTCDate();\n}\n\n/** A Date from its parts, checked, in the table's zone (or at `offsetMin`). */\nfunction makeDate({ y, mo, d, h = 0, mi = 0, s = 0, ms = 0 }, utc, offsetMin = null) {\n if (!(mo >= 1 && mo <= 12) || !(d >= 1 && d <= daysIn(y, mo))) return null;\n if (h > 23 || mi > 59 || s > 59) return null;\n if (offsetMin != null) return new Date(Date.UTC(y, mo - 1, d, h, mi, s, ms) - offsetMin * 60000);\n if (utc) return new Date(Date.UTC(y, mo - 1, d, h, mi, s, ms));\n const date = new Date(y, mo - 1, d, h, mi, s, ms);\n date.setFullYear(y); // years below 100 are not 19xx\n return date;\n}\n\nconst ISO = /^(\\d{4})-(\\d{2})-(\\d{2})(?:[T ](\\d{2}):(\\d{2})(?::(\\d{2})(?:[.,](\\d{1,3})\\d*)?)?\\s*(Z|[+-]\\d{2}:?\\d{2})?)?$/i;\nconst LOCAL = /^(\\d{1,4})[./-](\\d{1,2})[./-](\\d{1,4})\\.?(?:[,\\sT]+(\\d{1,2}):(\\d{2})(?::(\\d{2}))?\\s*([ap])?\\.?m?\\.?)?$/i;\n\n/** Text to a Date: ISO 8601, or `locale`'s day/month/year order; blank is null. */\nexport function parseDateTime(text, ctx = {}) {\n if (isBlank(text)) return ok(null);\n const t = String(text).trim();\n const iso = ISO.exec(t);\n if (iso) {\n const [, y, mo, d, h, mi, s, ms, zone] = iso;\n let offset = null;\n if (zone) {\n if (zone.toUpperCase() === 'Z') offset = 0;\n else {\n const z = zone.replace(':', '');\n offset = (z[0] === '-' ? -1 : 1) * (Number(z.slice(1, 3)) * 60 + Number(z.slice(3, 5)));\n }\n }\n const date = makeDate({\n y: +y, mo: +mo, d: +d, h: +(h || 0), mi: +(mi || 0), s: +(s || 0),\n ms: ms ? Number(ms.padEnd(3, '0')) : 0,\n }, !!ctx.utc, offset);\n return date ? ok(date) : refuse(ctx, 'datetime');\n }\n const m = LOCAL.exec(t);\n if (!m) return refuse(ctx, 'datetime');\n const [, a, b, c, hh, mi, ss, ap] = m;\n let h = hh == null ? 0 : +hh;\n if (ap) {\n if (h < 1 || h > 12) return refuse(ctx, 'datetime');\n h = (h % 12) + (ap.toLowerCase() === 'p' ? 12 : 0);\n }\n const time = { h, mi: +(mi || 0), s: +(ss || 0) };\n const order = dateOrder(ctx.locale);\n const nums = [a, b, c];\n const read = (ord) => {\n const at = {};\n ord.forEach((type, i) => { at[type] = nums[i]; });\n if (!at.year || at.year.length !== 4) return null;\n return makeDate({ y: +at.year, mo: +at.month, d: +at.day, ...time }, !!ctx.utc);\n };\n let date = read(order);\n if (!date) {\n // Day and month the other way round, when that is the only reading.\n const swapped = order.map((p) => (p === 'day' ? 'month' : p === 'month' ? 'day' : p));\n date = read(swapped);\n }\n return date ? ok(date) : refuse(ctx, 'datetime');\n}\n\nconst pad = (n, w = 2) => String(n).padStart(w, '0');\n\n/** A date as the editor shows it: ISO, 'YYYY-MM-DD', with ' HH:MM(:SS)' when\n * it has a time of day \u2014 in the table's zone. Anything else as text. */\nexport function formatDateTimeForEdit(value, ctx = {}) {\n if (value == null || value === '') return '';\n if (!(value instanceof Date)) return String(value);\n if (Number.isNaN(value.getTime())) return '';\n const u = !!ctx.utc;\n const y = u ? value.getUTCFullYear() : value.getFullYear();\n const mo = (u ? value.getUTCMonth() : value.getMonth()) + 1;\n const d = u ? value.getUTCDate() : value.getDate();\n const h = u ? value.getUTCHours() : value.getHours();\n const mi = u ? value.getUTCMinutes() : value.getMinutes();\n const s = u ? value.getUTCSeconds() : value.getSeconds();\n const day = `${pad(y, 4)}-${pad(mo)}-${pad(d)}`;\n if (!h && !mi && !s) return day;\n return `${day} ${pad(h)}:${pad(mi)}${s ? `:${pad(s)}` : ''}`;\n}\n\n// \u2500\u2500 choice \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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/** A column's `options` as `[{value, label}]`: a bare value is its own label. */\nexport function normalizeOptions(options) {\n if (!Array.isArray(options)) return [];\n return options.map((o) => (o && typeof o === 'object'\n ? { value: o.value, label: String(o.label ?? o.value ?? '') }\n : { value: o, label: String(o ?? '') }));\n}\n\n/** Text to one option's value \u2014 by its label or its value, ignoring case\n * and the spaces around it; blank is null. Other text is refused, unless\n * `allowOther`, when it is the value. */\nexport function parseChoice(text, ctx = {}) {\n if (isBlank(text)) return ok(null);\n const t = String(text).trim();\n const lower = t.toLowerCase();\n const opts = normalizeOptions(ctx.options);\n const hit = opts.find((o) => o.label.trim().toLowerCase() === lower)\n || opts.find((o) => String(o.value ?? '').trim().toLowerCase() === lower);\n if (hit) return ok(hit.value);\n return ctx.allowOther ? ok(t) : refuse(ctx, 'choice');\n}\n\nfunction labelOf(value, ctx) {\n if (value == null) return '';\n const hit = normalizeOptions(ctx.options).find((o) => Object.is(o.value, value) || String(o.value) === String(value));\n return hit ? hit.label : String(value);\n}\n\n// \u2500\u2500 the editors \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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/** What a factory is told, as a parse's `ctx`. */\nfunction contextOf(args) {\n const col = args.column || {};\n return {\n locale: args.locale, utc: !!args.utc, messages: args.messages,\n options: col.options, allowOther: !!col.allowOther,\n };\n}\n\n/** A text field whose text a parse reads; left as it opened, it is the value\n * it was given. */\nfunction parsedField(el, args, start, parse) {\n const { value, initialText = null } = args;\n el.value = initialText != null ? String(initialText) : start;\n const ctx = contextOf(args);\n return {\n el,\n getValue: () => el.value,\n parse: () => (initialText == null && el.value === start ? ok(value) : parse(el.value, ctx)),\n focus: () => {\n el.focus({ preventScroll: true });\n const end = el.value.length;\n try { el.setSelectionRange(end, end); } catch (_) { /* not a text type */ }\n },\n };\n}\n\nfunction textInput(kind) {\n const input = document.createElement('input');\n input.type = 'text';\n input.className = `twm-dt-editor twm-dt-editor--${kind}`;\n input.spellcheck = false;\n input.setAttribute('autocomplete', 'off');\n return input;\n}\n\n/** number: a text box (not type=number, which throws '1.234,56' away as it is\n * typed) read by `locale`. */\nexport function createNumberEditor(args) {\n const input = textInput('number');\n input.inputMode = 'decimal';\n return parsedField(input, args, formatNumberForEdit(args.value, contextOf(args)), parseNumber);\n}\n\n/** datetime: a text box (not type=date, which takes no '31/12/2026') read as\n * ISO or by `locale`'s order. */\nexport function createDateTimeEditor(args) {\n const input = textInput('datetime');\n return parsedField(input, args, formatDateTimeForEdit(args.value, contextOf(args)), parseDateTime);\n}\n\n/** multitext: a text area. Enter is a new line; Ctrl/Cmd+Enter commits. */\nexport function createMultiTextEditor(args) {\n const area = document.createElement('textarea');\n area.className = 'twm-dt-editor twm-dt-editor--multitext';\n area.spellcheck = false;\n area.rows = Number(args.column?.rows) > 0 ? Number(args.column.rows) : 3;\n const start = args.value == null ? '' : String(args.value);\n const field = parsedField(area, args, start, (text) => ok(text));\n return { ...field, multiline: true };\n}\n\n/** bool: a checkbox. Ticking or unticking it commits; Enter and Tab commit it\n * as it is. A space that opened it ticks it over; a word that reads as true\n * or false sets it. */\nexport function createBoolEditor(args) {\n const { value, initialText = null, commit } = args;\n const box = document.createElement('input');\n box.type = 'checkbox';\n box.className = 'twm-dt-editor twm-dt-editor--bool';\n const start = truthy(value);\n box.checked = start;\n if (initialText === ' ') box.checked = !start;\n else if (initialText != null) {\n const r = parseBool(initialText);\n if (r.ok) box.checked = r.value;\n }\n box.addEventListener('change', () => commit(box.checked));\n const read = () => (box.checked === start && initialText == null ? ok(value) : ok(box.checked));\n return {\n el: box,\n getValue: () => box.checked,\n parse: read,\n focus: () => box.focus({ preventScroll: true }),\n };\n}\n\nlet uid = 0;\n\n/**\n * choice: an AutocompleteField offering the column's `options`, filtered by\n * what is typed. Picking one (a click, or Enter or Tab on the list) commits\n * its value; Enter and Tab with the list shut commit the text read by\n * `parseChoice`, and on an emptied box (no arrow having chosen an option)\n * commit null. Escape with the list open closes the list only.\n */\nexport function createChoiceEditor(args) {\n const { value, initialText = null, commit } = args;\n const ctx = contextOf(args);\n const opts = normalizeOptions(ctx.options);\n const start = labelOf(value, ctx);\n const shown = initialText != null ? String(initialText) : start;\n let picked = null; // {label, value}: the last option picked\n let keying = null; // the key being handled, while it is\n let done = false;\n\n const ac = new AutocompleteField({\n fieldId: `twm-dt-choice-${++uid}`,\n field: { value: shown },\n skipNamespacePrefix: true,\n typeIcons: { option: 'list' },\n provider: ({ value: term }) => {\n const q = String(term ?? '').trim().toLowerCase();\n const all = !q || (initialText == null && term === start);\n return opts\n .filter((o) => all || o.label.toLowerCase().includes(q))\n .map((o) => ({ label: o.label, insertText: o.label, iconType: 'option', metadata: { value: o.value } }));\n },\n onChange: (text, meta) => {\n if (done || !meta?.immediate || !meta.metadata) return;\n picked = { label: String(text ?? ''), value: meta.metadata.value };\n // A pick by Enter or Tab moves the cursor as those keys do.\n const move = keying\n ? (keying.key === 'Tab' ? (keying.shift ? 'left' : 'right') : (keying.shift ? 'up' : 'down'))\n : null;\n commit(picked.value, move);\n },\n });\n const root = ac.render();\n root.classList.add('twm-dt-editor--choice');\n const input = ac.input;\n input.classList.add('twm-dt-editor');\n\n let browsed = false; // an arrow moved through the list since the last keystroke\n const onCapture = (ev) => {\n const commitKey = (ev.key === 'Enter' || ev.key === 'Tab') && !ev.ctrlKey && !ev.metaKey && !ev.altKey;\n keying = commitKey ? { key: ev.key, shift: ev.shiftKey } : null;\n if (ev.key === 'ArrowDown' || ev.key === 'ArrowUp') browsed = true;\n // An emptied box is no option, even with the list open on all of\n // them: Enter and Tab commit null \u2014 unless an arrow chose one.\n if (commitKey && !browsed && !String(input.value).trim() && !ev.isComposing) {\n ev.preventDefault();\n ev.stopPropagation();\n const move = ev.key === 'Tab' ? (ev.shiftKey ? 'left' : 'right') : (ev.shiftKey ? 'up' : 'down');\n commit(null, move);\n }\n };\n const onInput = () => { browsed = false; };\n const onAfter = (ev) => {\n keying = null;\n // Escape with the list open was the list's (it closed it).\n if (ev.key === 'Escape' && ev.defaultPrevented) ev.stopPropagation();\n };\n root.addEventListener('keydown', onCapture, true);\n input.addEventListener('keydown', onAfter);\n input.addEventListener('input', onInput);\n\n return {\n el: root,\n getValue: () => ac.input?.value ?? '',\n parse: () => {\n const text = ac.input?.value ?? '';\n if (initialText == null && text === start) return ok(value);\n if (picked && text === picked.label) return ok(picked.value);\n return parseChoice(text, ctx);\n },\n focus: () => {\n ac.input?.focus({ preventScroll: true });\n const end = ac.input?.value.length ?? 0;\n try { ac.input?.setSelectionRange(end, end); } catch (_) { /* gone */ }\n },\n destroy: () => {\n done = true;\n root.removeEventListener('keydown', onCapture, true);\n input.removeEventListener('keydown', onAfter);\n input.removeEventListener('input', onInput);\n ac.dispose();\n },\n };\n}\n\nconst identity = (text) => ok(text == null ? '' : String(text));\n\n/** The six, by type: `{create, parse}` each. */\nexport const CELL_EDITORS = Object.freeze({\n text: Object.freeze({ create: createTextEditor, parse: identity }),\n multitext: Object.freeze({ create: createMultiTextEditor, parse: identity }),\n number: Object.freeze({ create: createNumberEditor, parse: parseNumber }),\n bool: Object.freeze({ create: createBoolEditor, parse: parseBool }),\n choice: Object.freeze({ create: createChoiceEditor, parse: parseChoice }),\n datetime: Object.freeze({ create: createDateTimeEditor, parse: parseDateTime }),\n});\n", "/**\n * cell_selection.js \u2014 STORY-0003. The model under DataTable's CELL MODE\n * (`selectionMode: 'cells'`): a cursor cell, a range from an anchor to that\n * cursor, and every move the keys make over them. No DOM, so the rules can be\n * tested \u2014 or drive another grid \u2014 without a table. DataTable's own half (the\n * painting, the pointer, the keys, the editor) is `cell_grid.js`, which is\n * internal to the table.\n *\n * \u2550\u2550 COORDINATES \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\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 cell is `{row, col}`. `row` is the row's POSITION in the order shown \u2014 the\n * index into `getDisplayedRows()`, after the sort and the filters \u2014 because a\n * range is a rectangle on the screen, not in the data. `col` is the DATA column\n * index (the one `headers`, `renderCell` and `hiddenColumns` use); a range\n * spans the columns SHOWN between its two edges, so a hidden column inside it\n * is not part of it. The cursor moves only over the rows of the page drawn.\n */\n\n/**\n * The selection model. Rows are positions `first..last`; columns are the data\n * indices in `cols`, in the order they are shown. Both are handed in on every\n * move (`setBounds`), because a filter, a page or a hidden column changes them\n * under a selection that has to survive.\n */\nexport class CellSelection {\n constructor() {\n /** @type {{row:number, col:number}|null} */\n this.anchor = null;\n /** @type {{row:number, col:number}|null} the cursor */\n this.focus = null;\n this.first = 0;\n this.last = -1;\n this.cols = [];\n }\n\n /** The rows (positions, inclusive) and columns (data indices, shown order)\n * the cursor may stand on. A selection outside them is pulled in. */\n setBounds(first, last, cols) {\n this.first = first;\n this.last = last;\n this.cols = Array.isArray(cols) ? cols.slice() : [];\n if (this.isEmptyGrid()) {\n this.anchor = null;\n this.focus = null;\n return;\n }\n if (this.focus) this.focus = this._clamp(this.focus);\n if (this.anchor) this.anchor = this._clamp(this.anchor);\n }\n\n isEmptyGrid() {\n return this.last < this.first || this.cols.length === 0;\n }\n\n _ord(col) {\n const i = this.cols.indexOf(col);\n return i >= 0 ? i : 0;\n }\n\n _clamp({ row, col }) {\n const r = Math.max(this.first, Math.min(this.last, row));\n const c = this.cols.includes(col) ? col\n : this.cols[Math.max(0, Math.min(this.cols.length - 1, this._nearestOrd(col)))];\n return { row: r, col: c };\n }\n\n /** A column that is not shown any more: the shown one nearest its index. */\n _nearestOrd(col) {\n let best = 0;\n for (let i = 0; i < this.cols.length; i++) if (this.cols[i] <= col) best = i;\n return best;\n }\n\n _inside(row, ord) {\n return row >= this.first && row <= this.last && ord >= 0 && ord < this.cols.length;\n }\n\n /** Put the cursor on one cell and collapse the range onto it. */\n setCursor(row, col) {\n if (this.isEmptyGrid()) return false;\n this.focus = this._clamp({ row, col });\n this.anchor = { ...this.focus };\n return true;\n }\n\n /** Move the cursor to a cell and keep the anchor: the range grows. */\n extendTo(row, col) {\n if (!this.anchor) return this.setCursor(row, col);\n if (this.isEmptyGrid()) return false;\n this.focus = this._clamp({ row, col });\n return true;\n }\n\n _go(cell, extend) {\n return extend ? this.extendTo(cell.row, cell.col) : this.setCursor(cell.row, cell.col);\n }\n\n /** One step: the arrows. At an edge the cursor stays put. */\n move(dRow, dCol, { extend = false } = {}) {\n if (!this.focus) return this.setCursor(this.first, this.cols[0]);\n const ord = Math.max(0, Math.min(this.cols.length - 1, this._ord(this.focus.col) + dCol));\n const row = Math.max(this.first, Math.min(this.last, this.focus.row + dRow));\n return this._go({ row, col: this.cols[ord] }, extend);\n }\n\n /**\n * Ctrl+arrow: to the edge of the block of filled cells, as a spreadsheet\n * does. From a filled cell whose neighbour is filled, to the last filled\n * cell of that run; otherwise to the next filled cell along the line, or\n * the edge of the grid when there is none.\n *\n * @param {number} dRow -1, 0 or 1\n * @param {number} dCol -1, 0 or 1\n * @param {(row:number, col:number) => boolean} filled\n */\n jump(dRow, dCol, filled, { extend = false } = {}) {\n if (!this.focus) return this.setCursor(this.first, this.cols[0]);\n let r = this.focus.row;\n let o = this._ord(this.focus.col);\n const isFilled = (row, ord) => !!filled(row, this.cols[ord]);\n if (this._inside(r + dRow, o + dCol)) {\n if (isFilled(r, o) && isFilled(r + dRow, o + dCol)) {\n while (this._inside(r + dRow, o + dCol) && isFilled(r + dRow, o + dCol)) {\n r += dRow; o += dCol;\n }\n } else {\n r += dRow; o += dCol;\n while (!isFilled(r, o) && this._inside(r + dRow, o + dCol)) {\n r += dRow; o += dCol;\n }\n }\n }\n return this._go({ row: r, col: this.cols[o] }, extend);\n }\n\n /** Home / End: the first or last column of the cursor's row; with\n * `corner` (Ctrl), the first or last cell of the grid. */\n lineEnd(toEnd, { extend = false, corner = false } = {}) {\n if (!this.focus) return this.setCursor(this.first, this.cols[0]);\n const col = toEnd ? this.cols[this.cols.length - 1] : this.cols[0];\n const row = corner ? (toEnd ? this.last : this.first) : this.focus.row;\n return this._go({ row, col }, extend);\n }\n\n /** Tab: one cell right, wrapping to the first cell of the next row (Shift:\n * left, wrapping to the last cell of the row before). The last cell of\n * the grid (the first, going back) stays put. */\n tab(back = false) {\n if (!this.focus) return this.setCursor(this.first, this.cols[0]);\n let row = this.focus.row;\n let ord = this._ord(this.focus.col) + (back ? -1 : 1);\n if (ord >= this.cols.length) {\n if (row >= this.last) return this.setCursor(row, this.focus.col);\n row += 1; ord = 0;\n } else if (ord < 0) {\n if (row <= this.first) return this.setCursor(row, this.focus.col);\n row -= 1; ord = this.cols.length - 1;\n }\n return this.setCursor(row, this.cols[ord]);\n }\n\n /** Whether Tab (Shift+Tab with `back`) has nowhere to go: the cursor is\n * on the grid's last cell (its first, going back). The grid then lets\n * the key move focus on, out of the table. */\n tabEnds(back = false) {\n if (!this.focus || this.isEmptyGrid()) return false;\n const col = back ? this.cols[0] : this.cols[this.cols.length - 1];\n const row = back ? this.first : this.last;\n return this.focus.row === row && this.focus.col === col;\n }\n\n /** Every cell of the grid: from its first cell to its last, which is\n * where the cursor goes. */\n selectAll() {\n if (this.isEmptyGrid()) return false;\n this.anchor = { row: this.first, col: this.cols[0] };\n this.focus = { row: this.last, col: this.cols[this.cols.length - 1] };\n return true;\n }\n\n /** The range collapses onto the cursor. */\n collapse() {\n if (!this.focus) return false;\n const was = this.anchor && (this.anchor.row !== this.focus.row || this.anchor.col !== this.focus.col);\n this.anchor = { ...this.focus };\n return !!was;\n }\n\n clear() {\n this.anchor = null;\n this.focus = null;\n }\n\n /** `{top, bottom, left, right, columns}` \u2014 rows as positions, `left` and\n * `right` and `columns` as data indices \u2014 or null with nothing selected. */\n range() {\n if (!this.focus || !this.anchor) return null;\n const a = this._ord(this.anchor.col);\n const b = this._ord(this.focus.col);\n const lo = Math.min(a, b);\n const hi = Math.max(a, b);\n return {\n top: Math.min(this.anchor.row, this.focus.row),\n bottom: Math.max(this.anchor.row, this.focus.row),\n left: this.cols[lo],\n right: this.cols[hi],\n columns: this.cols.slice(lo, hi + 1),\n };\n }\n\n contains(row, col) {\n const r = this.range();\n if (!r || row < r.top || row > r.bottom) return false;\n return r.columns.includes(col);\n }\n\n isCursor(row, col) {\n return !!this.focus && this.focus.row === row && this.focus.col === col;\n }\n}\n", "/**\n * rAF-coalesced ResizeObserver.\n *\n * Running layout-mutating work \u2014 `Plotly.Plots.resize()`, Monaco's\n * `editor.layout()`, a canvas resize, or a re-render \u2014 *synchronously* inside a\n * ResizeObserver callback makes the engine emit the (spec-defined, benign but\n * console-error-level) \"ResizeObserver loop completed with undelivered\n * notifications\" warning: the callback mutates layout, which produces more\n * resize notifications it can't deliver in the same dispatch.\n *\n * Deferring the work to the next animation frame is the root-cause fix \u2014 the\n * engine delivers all pending notifications first, so there's nothing left\n * \"undelivered\" \u2014 and coalescing collapses a burst of resize events into a\n * single render.\n *\n * @param {(entries: ResizeObserverEntry[]) => void} callback\n * @returns {ResizeObserver}\n */\nexport function createRafResizeObserver(callback) {\n let scheduled = false;\n let latestEntries = [];\n return new ResizeObserver((entries) => {\n latestEntries = entries;\n if (scheduled) return;\n scheduled = true;\n requestAnimationFrame(() => {\n scheduled = false;\n callback(latestEntries);\n });\n });\n}\n", "/**\n * table_values.js \u2014 the REAL VALUE behind a date, a timestamp or a duration\n * cell, and the words a reader sees for it.\n *\n * A list that hands DataTable already-formatted text sorts that text: \"10/5/2026\"\n * before \"9/30/2026\", \"3.2 s\" before \"850 ms\", \"5 Oct\" before \"30 Sep\". The\n * cure is to hand the table the VALUE (an ISO string, a `Date`, epoch\n * milliseconds, a duration in milliseconds) and let it format for the eye while\n * it sorts and filters by the value. That is what a column typed `date`,\n * `datetime` or `duration` does (0.5.0), and these are the functions it uses.\n *\n * They are exported (through `data_table.js`) so a consumer that draws a value\n * somewhere else \u2014 a detail pane, a tooltip \u2014 writes the same words the table\n * writes, rather than an eighth private formatter.\n *\n * \u2550\u2550 THE DEFAULT IS ISO \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\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 * `YYYY-MM-DD` for a date and `YYYY-MM-DD HH:mm` for a timestamp. It sorts as\n * text, it reads the same in every locale, and it is what the product owner of\n * the first consumer asked for: *\"Flexdesk default should be the ISO date\"*. A\n * consumer that wants something else passes a pattern (below) or a function.\n *\n * \u2550\u2550 PATTERNS \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\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 * YYYY 2026 YY 26 MMMM October MMM Oct MM 10 M 10\n * DD 05 D 5 dddd Monday ddd Mon\n * HH 14 H 14 hh 02 h 2 mm 05 m 5\n * ss 09 s 9 SSS 042 A PM a pm\n * [literal] anything in square brackets is copied verbatim\n *\n * Month and weekday NAMES are English. A consumer that needs another language\n * passes a function, which can use `Intl.DateTimeFormat` with whatever locale it\n * likes; this module has no locale data and wants none.\n *\n * \u2550\u2550 TIME ZONES \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\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 value WITH a zone (`\u2026Z`, `\u2026+02:00`, a `Date`, epoch ms) is an instant, and\n * it is drawn in the reader's local zone unless `utc` is asked for. A value\n * WITHOUT one (`2026-10-05`, `2026-10-05 14:30`) is a wall-clock reading, and\n * it is taken in the zone it will be drawn in \u2014 so `2026-10-05` is drawn as\n * `2026-10-05` everywhere. (`Date.parse('2026-10-05')` reads it as UTC\n * midnight, which west of Greenwich is the evening of the 4th: a calendar date\n * that moves a day depending on where it is read.)\n *\n * \u2550\u2550 WHAT IS READ AS A DATE: ISO 8601, A `Date`, EPOCH MS \u2014 NOTHING ELSE \u2550\u2550\n *\n * Text that is not ISO 8601 is NOT handed to `Date.parse`. Its other forms are\n * implementation-defined, and V8's reads almost anything: `'2'`, `'12'`,\n * `'1/2'` and `'5 Oct'` are all dates in 2001 there. A cell holding `'12'` was\n * drawn `2001-12-01`, and a date filter being typed \u2014 `2`, `20`, `202`,\n * `2026-` \u2014 emptied the table at every other keystroke, because each half was\n * read as an instant nothing equalled. So: an ISO string, a `Date` or a\n * number, or it is text \u2014 drawn as it came, sorted last, and matched by a\n * filter's words. An impossible calendar date (`2026-02-31`) is text too, not\n * the 3rd of March it would roll over to.\n */\n\nconst MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July',\n 'August', 'September', 'October', 'November', 'December'];\nconst WEEKDAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday',\n 'Friday', 'Saturday'];\n\n/** The ISO default for a `date` column. */\nexport const ISO_DATE = 'YYYY-MM-DD';\n/** The ISO default for a `datetime` column. */\nexport const ISO_DATETIME = 'YYYY-MM-DD HH:mm';\n\n// An ISO 8601 date, optionally with a time (`T` or a space) and a zone.\nconst ISO_RE = /^(\\d{4})-(\\d{2})-(\\d{2})(?:[T ](\\d{2}):(\\d{2})(?::(\\d{2})(?:[.,](\\d{1,9}))?)?)?\\s*(Z|[+-]\\d{2}(?::?\\d{2})?)?$/i;\n\nconst pad = (n, w = 2) => String(Math.trunc(Math.abs(n))).padStart(w, '0');\n\n/** Days in a month (0-based), proleptic Gregorian \u2014 as `Date` counts them. */\nfunction daysInMonth(y, mo) {\n if (mo !== 1) return [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][mo];\n return (y % 4 === 0 && y % 100 !== 0) || y % 400 === 0 ? 29 : 28;\n}\n\n/**\n * Epoch ms for calendar parts (month 0-based), in UTC or the local zone. Not\n * `new Date(y, \u2026)` or `Date.UTC(y, \u2026)`: both read a year below 100 as 19xx, so\n * `0001-01-01` \u2014 a common \"no date\" sentinel \u2014 would be drawn `1901-01-01`.\n * Parts past their range roll over, which is what a period's END wants; a\n * VALUE is checked before it gets here.\n */\nfunction partsToTime(utc, y, mo, d = 1, h = 0, mi = 0, s = 0, ms = 0) {\n const date = new Date(0);\n if (utc) {\n date.setUTCFullYear(y, mo, d);\n date.setUTCHours(h, mi, s, ms);\n } else {\n date.setFullYear(y, mo, d);\n date.setHours(h, mi, s, ms);\n }\n return date.getTime();\n}\n\n/**\n * Epoch milliseconds for a date-like value, or `NaN` when it is not one.\n *\n * @param {Date|number|string|null|undefined} value a `Date`, epoch ms, or an\n * ISO 8601 string. Any other text is `NaN` \u2014 see \"What is read as a date\"\n * in the header \u2014 and so is a calendar date that does not exist\n * (`2026-02-31`, `2026-02-29`).\n * @param {{utc?: boolean}} [o] read a zone-less string as UTC rather than local\n * @returns {number}\n */\nexport function parseDateValue(value, { utc = false } = {}) {\n if (value == null || value === '') return NaN;\n if (value instanceof Date) return value.getTime();\n if (typeof value === 'number') return Number.isFinite(value) ? value : NaN;\n const text = String(value).trim();\n if (!text) return NaN;\n const m = ISO_RE.exec(text);\n if (!m) return NaN;\n const y = Number(m[1]);\n const mo = Number(m[2]);\n const d = Number(m[3]);\n if (mo < 1 || mo > 12 || d < 1 || d > daysInMonth(y, mo - 1)) return NaN;\n const h = m[4] ? Number(m[4]) : 0;\n const mi = m[5] ? Number(m[5]) : 0;\n const s = m[6] ? Number(m[6]) : 0;\n const ms = m[7] ? Math.round(Number(`0.${m[7]}`) * 1000) : 0;\n // 24:00 is the end of the day (ISO 8601); 24:01 is nothing. A leap second\n // (:60) is the next minute's first.\n if (h > 24 || mi > 59 || s > 60 || (h === 24 && (mi || s || ms))) return NaN;\n const zone = m[8];\n if (zone) {\n let offset = 0;\n if (zone.toUpperCase() !== 'Z') {\n const sign = zone[0] === '-' ? -1 : 1;\n const digits = zone.slice(1).replace(':', '');\n offset = sign * (Number(digits.slice(0, 2)) * 60 + Number(digits.slice(2, 4) || 0));\n }\n return partsToTime(true, y, mo - 1, d, h, mi, s, ms) - offset * 60000;\n }\n return partsToTime(utc, y, mo - 1, d, h, mi, s, ms);\n}\n\n/**\n * Draw a date-like value with a pattern (see the header). An unreadable value\n * is drawn AS IT CAME rather than as nothing: a blank cell would hide that the\n * data held something unexpected.\n *\n * @param {Date|number|string|null|undefined} value\n * @param {string|Function} [pattern='YYYY-MM-DD'] a pattern, or\n * `(date: Date) => string`\n * @param {{utc?: boolean}} [o] draw in UTC rather than the local zone\n * @returns {string}\n */\nexport function formatDate(value, pattern = ISO_DATE, { utc = false } = {}) {\n if (value == null || value === '') return '';\n const t = parseDateValue(value, { utc });\n if (!Number.isFinite(t)) return String(value);\n const date = new Date(t);\n if (typeof pattern === 'function') return String(pattern(date) ?? '');\n const get = utc\n ? {\n y: date.getUTCFullYear(), mo: date.getUTCMonth(), d: date.getUTCDate(),\n wd: date.getUTCDay(), h: date.getUTCHours(), mi: date.getUTCMinutes(),\n s: date.getUTCSeconds(), ms: date.getUTCMilliseconds(),\n }\n : {\n y: date.getFullYear(), mo: date.getMonth(), d: date.getDate(),\n wd: date.getDay(), h: date.getHours(), mi: date.getMinutes(),\n s: date.getSeconds(), ms: date.getMilliseconds(),\n };\n const h12 = get.h % 12 === 0 ? 12 : get.h % 12;\n return String(pattern || ISO_DATE).replace(\n /\\[([^\\]]*)\\]|YYYY|YY|MMMM|MMM|MM|M|dddd|ddd|DD|D|HH|H|hh|h|mm|m|ss|s|SSS|A|a/g,\n (tok, literal) => {\n if (literal !== undefined) return literal;\n switch (tok) {\n case 'YYYY': return pad(get.y, 4);\n case 'YY': return pad(get.y % 100);\n case 'MMMM': return MONTHS[get.mo];\n case 'MMM': return MONTHS[get.mo].slice(0, 3);\n case 'MM': return pad(get.mo + 1);\n case 'M': return String(get.mo + 1);\n case 'dddd': return WEEKDAYS[get.wd];\n case 'ddd': return WEEKDAYS[get.wd].slice(0, 3);\n case 'DD': return pad(get.d);\n case 'D': return String(get.d);\n case 'HH': return pad(get.h);\n case 'H': return String(get.h);\n case 'hh': return pad(h12);\n case 'h': return String(h12);\n case 'mm': return pad(get.mi);\n case 'm': return String(get.mi);\n case 'ss': return pad(get.s);\n case 's': return String(get.s);\n case 'SSS': return pad(get.ms, 3);\n case 'A': return get.h < 12 ? 'AM' : 'PM';\n case 'a': return get.h < 12 ? 'am' : 'pm';\n default: return tok;\n }\n });\n}\n\n/**\n * The PERIOD an ISO prefix names, as `[start, end)` in epoch ms \u2014 `2026` is the\n * year, `2026-10` the month, `2026-10-05` the day, `2026-10-05 14` the hour,\n * `2026-10-05 14:30` the minute \u2014 ISO's own two-digit parts, nothing looser. A\n * full ISO instant (with a zone, say) is the one millisecond it names. `null`\n * for anything else: half typed (`2`, `202`, `2026-`, `2026-1`), a date that\n * does not exist (`2026-02-31`), or words (`5 Oct`). That is how a half-typed\n * operand (`>20`) filters nothing yet, and how text with no operator falls\n * through to the drawn words (`matchDateFilter`).\n *\n * @param {string} text\n * @param {{utc?: boolean}} [o]\n * @returns {{start: number, end: number}|null}\n */\nexport function parseDatePeriod(text, { utc = false } = {}) {\n const t = String(text ?? '').trim();\n const m = /^(\\d{4})(?:-(\\d{2})(?:-(\\d{2})(?:[T ](\\d{2})(?::(\\d{2})(?::(\\d{2}))?)?)?)?)?$/i.exec(t);\n if (m) {\n const parts = [Number(m[1]),\n m[2] ? Number(m[2]) - 1 : 0,\n m[3] ? Number(m[3]) : 1,\n m[4] ? Number(m[4]) : 0,\n m[5] ? Number(m[5]) : 0,\n m[6] ? Number(m[6]) : 0];\n if (parts[1] < 0 || parts[1] > 11 || parts[2] < 1 || parts[2] > daysInMonth(parts[0], parts[1])\n || parts[3] > 23 || parts[4] > 59 || parts[5] > 59) return null;\n // The least significant part that was GIVEN is the one the period spans.\n const unit = m[6] ? 5 : m[5] ? 4 : m[4] ? 3 : m[3] ? 2 : m[2] ? 1 : 0;\n const next = parts.slice();\n next[unit] += 1;\n return { start: partsToTime(utc, ...parts), end: partsToTime(utc, ...next) };\n }\n // Not a prefix: a full ISO instant or nothing (`parseDateValue` reads no\n // other text).\n const instant = parseDateValue(t, { utc });\n return Number.isFinite(instant) ? { start: instant, end: instant + 1 } : null;\n}\n\nconst DURATION_UNITS = {\n ms: 1, msec: 1, msecs: 1, millisecond: 1, milliseconds: 1,\n s: 1000, sec: 1000, secs: 1000, second: 1000, seconds: 1000,\n m: 60000, min: 60000, mins: 60000, minute: 60000, minutes: 60000,\n h: 3600000, hr: 3600000, hrs: 3600000, hour: 3600000, hours: 3600000,\n d: 86400000, day: 86400000, days: 86400000,\n};\n\n/**\n * Milliseconds for a duration: a number (taken as ms), or text \u2014 `850 ms`,\n * `3.2 s`, `2m 5s`, `1h 30m`, `2 days`, or a clock `1:02:05` (`h:mm:ss`, with\n * an optional `d.` in front). `NaN` when it is none of those.\n *\n * @param {number|string|null|undefined} value\n * @returns {number}\n */\nexport function parseDuration(value) {\n if (value == null || value === '') return NaN;\n if (typeof value === 'number') return Number.isFinite(value) ? value : NaN;\n let text = String(value).trim().toLowerCase();\n if (!text) return NaN;\n let sign = 1;\n if (text[0] === '-') { sign = -1; text = text.slice(1).trim(); }\n if (/^\\d+(?:\\.\\d+)?$/.test(text)) return sign * Number(text);\n const clock = /^(?:(\\d+)\\.)?(\\d+):(\\d{1,2})(?::(\\d{1,2}(?:\\.\\d+)?))?$/.exec(text);\n if (clock) {\n const [, d, a, b, c] = clock;\n // h:mm:ss, or h:mm when there is no third part.\n const ms = (Number(d || 0) * 86400 + Number(a) * 3600 + Number(b) * 60\n + Number(c || 0)) * 1000;\n return sign * ms;\n }\n const re = /(\\d+(?:\\.\\d+)?)\\s*([a-z]+)\\s*/g;\n let total = 0;\n let consumed = 0;\n let m;\n while ((m = re.exec(text)) !== null) {\n if (m.index !== consumed) return NaN;\n const unit = DURATION_UNITS[m[2]];\n if (unit === undefined) return NaN;\n total += Number(m[1]) * unit;\n consumed = re.lastIndex;\n }\n return consumed === text.length && consumed > 0 ? sign * total : NaN;\n}\n\n/**\n * Draw a duration in milliseconds.\n *\n * 'auto' (default) `850 ms`, `3.2 s`, `2m 5s`, `1h 2m`, `3d 4h` \u2014 the two\n * largest units that matter, which is what a list of run times or\n * query times wants\n * 'clock' `0:00:03`, `1:02:05`, `2.04:00:00` (`d.h:mm:ss`)\n * a function `(ms) => string`\n *\n * Text that is not a duration is drawn as it came, like `formatDate`.\n *\n * @param {number|string|null|undefined} value\n * @param {'auto'|'clock'|Function} [pattern='auto']\n * @returns {string}\n */\nexport function formatDuration(value, pattern = 'auto') {\n if (value == null || value === '') return '';\n const ms = parseDuration(value);\n if (!Number.isFinite(ms)) return String(value);\n if (typeof pattern === 'function') return String(pattern(ms) ?? '');\n const neg = ms < 0;\n const a = Math.abs(ms);\n let out;\n if (pattern === 'clock') {\n const total = Math.round(a / 1000);\n const d = Math.floor(total / 86400);\n const h = Math.floor((total % 86400) / 3600);\n const mi = Math.floor((total % 3600) / 60);\n const s = total % 60;\n out = `${d ? `${d}.${pad(h)}` : h}:${pad(mi)}:${pad(s)}`;\n } else if (a < 1000) {\n out = `${Math.round(a)} ms`;\n } else if (a < 59950) {\n out = `${(a / 1000).toFixed(1)} s`;\n } else if (a < 3600000) {\n let mi = Math.floor(a / 60000);\n let s = Math.round((a % 60000) / 1000);\n if (s === 60) { mi += 1; s = 0; }\n out = `${mi}m ${s}s`;\n } else if (a < 86400000) {\n let h = Math.floor(a / 3600000);\n let mi = Math.round((a % 3600000) / 60000);\n if (mi === 60) { h += 1; mi = 0; }\n out = `${h}h ${mi}m`;\n } else {\n let d = Math.floor(a / 86400000);\n let h = Math.round((a % 86400000) / 3600000);\n if (h === 24) { d += 1; h = 0; }\n out = `${d}d ${h}h`;\n }\n return neg ? `-${out}` : out;\n}\n\n/**\n * Does a time `t` (epoch ms) pass a date filter's text?\n *\n * >2026-10 after October 2026 >=2026-10 from the 1st of October\n * <2026-10-05 before the 5th <=2026-10-05 up to the end of the 5th\n * =2026-10 in October !=2026-10 not in October\n * 2026-01..2026-03 January to the end of March\n * 2026-10 (no operator) in October\n *\n * An operand that is not a date yet (`>20`, half typed) filters nothing. Text\n * with no operator that names no period is matched against the cell's DRAWN\n * words, so `Oct` finds October under an `MMM` pattern, `5 Oct` the 5th under\n * `D MMM YYYY`, and `2026-1` (on the way to `2026-10`) whatever is drawn with\n * it under the ISO default.\n *\n * @param {number} t the cell's time, or NaN\n * @param {string} filterText\n * @param {string} shown the cell as drawn\n * @param {{utc?: boolean}} [o]\n * @returns {boolean}\n */\nexport function matchDateFilter(t, filterText, shown, { utc = false } = {}) {\n const text = String(filterText ?? '').trim();\n if (!text) return true;\n const range = /^(.+?)\\s*\\.\\.\\s*(.+)$/.exec(text);\n if (range) {\n const lo = parseDatePeriod(range[1], { utc });\n const hi = parseDatePeriod(range[2], { utc });\n if (!lo || !hi) return true;\n return Number.isFinite(t) && t >= lo.start && t < hi.end;\n }\n const op = /^(>=|<=|!=|>|<|=)\\s*(.+)$/.exec(text);\n if (op) {\n const p = parseDatePeriod(op[2], { utc });\n if (!p) return true;\n if (!Number.isFinite(t)) return false;\n switch (op[1]) {\n case '>': return t >= p.end;\n case '>=': return t >= p.start;\n case '<': return t < p.start;\n case '<=': return t < p.end;\n case '=': return t >= p.start && t < p.end;\n case '!=': return !(t >= p.start && t < p.end);\n }\n }\n const p = parseDatePeriod(text, { utc });\n if (p) return Number.isFinite(t) && t >= p.start && t < p.end;\n return String(shown ?? '').toLowerCase().includes(text.toLowerCase());\n}\n\n/**\n * Does a duration `ms` pass a duration filter's text? The operators are the\n * numeric ones, and an operand carries its unit (`>1s`, `<500ms`, `2m..5m`); a\n * bare number is milliseconds. Text with no operator is matched against the\n * cell's drawn words.\n *\n * @param {number} ms\n * @param {string} filterText\n * @param {string} shown\n * @returns {boolean}\n */\nexport function matchDurationFilter(ms, filterText, shown) {\n const text = String(filterText ?? '').trim();\n if (!text) return true;\n const range = /^(.+?)\\s*\\.\\.\\s*(.+)$/.exec(text);\n if (range) {\n const lo = parseDuration(range[1]);\n const hi = parseDuration(range[2]);\n if (!Number.isFinite(lo) || !Number.isFinite(hi)) return true;\n return Number.isFinite(ms) && ms >= lo && ms <= hi;\n }\n const op = /^(>=|<=|!=|>|<|=)\\s*(.+)$/.exec(text);\n if (op) {\n const target = parseDuration(op[2]);\n if (!Number.isFinite(target)) return true;\n if (!Number.isFinite(ms)) return false;\n switch (op[1]) {\n case '>': return ms > target;\n case '>=': return ms >= target;\n case '<': return ms < target;\n case '<=': return ms <= target;\n case '=': return ms === target;\n case '!=': return ms !== target;\n }\n }\n return String(shown ?? '').toLowerCase().includes(text.toLowerCase());\n}\n", "/**\n * table_filter_chips.js \u2014 0.7.0\n *\n * ONE-OF-N CHIPS WITH COUNTS, as a column filter control: the built-in kind\n * behind `DataTable`'s `filterKinds: {[col]: {kind: 'chips', options}}`, and\n * usable on its own.\n *\n * Each option is a chip \u2014 an optional glyph, its label, and a count badge that\n * reads `\u2013` until `setCounts` says otherwise. A chip whose count is 0 is\n * DIMMED, never hidden: a chip that disappears at nought takes the information\n * \"there are none of these\" with it, which is often the most reassuring thing\n * on the screen.\n *\n * - An option whose value is `''` or `null` stands for NO FILTER (\"All\"); it\n * is pressed exactly when nothing is chosen, and its count is the total.\n * - One-of-N (the default): pressing a chip chooses it; pressing the chosen\n * chip again clears the filter.\n * - `multiple: true`: each chip toggles its value in or out of a list.\n *\n * What the values MEAN \u2014 which levels exist, their words, their glyphs, what a\n * count counts \u2014 is the consumer's. This file is only the control.\n *\n * const chips = createChipsFilter({ header: 'Level', setValue: (v) => \u2026, value: null },\n * { options: [{ value: '', label: 'All', icon: 'list_alt' },\n * { value: 'warn', label: 'Warn', icon: 'warning' }] });\n * host.appendChild(chips.el);\n * chips.setCounts({ '': 120, warn: 3 });\n */\n\nconst isAll = (v) => v === '' || v == null;\n\n/**\n * @param {object} [ctx] `{header, value, counts, setValue(v)}` \u2014 what a\n * `DataTable` hands a filter control. Without `setValue` the control keeps\n * its own value and reports it through `spec.onChange`.\n * @param {object} spec `{options: [{value, label, icon?, title?}], multiple?,\n * label?, counts? (false: no badges), onChange?}`\n * @returns {{el: HTMLElement, setValue(v): void, setCounts(c): void,\n * getValue(): *, destroy(): void}}\n */\nexport function createChipsFilter(ctx = {}, spec = {}) {\n const options = Array.isArray(spec.options) ? spec.options : [];\n const multiple = !!spec.multiple;\n const showCounts = spec.counts !== false;\n const el = document.createElement('div');\n el.className = 'twm-dt-filter-chips' + (multiple ? ' twm-dt-filter-chips--multiple' : '');\n el.setAttribute('role', 'group');\n const name = spec.label || ctx.header;\n if (name) el.setAttribute('aria-label', String(name));\n\n /** Chip key (text) -> the option's own value. */\n const valueOf = new Map();\n const chips = new Map();\n let value = null;\n\n const keyOf = (v) => String(v ?? '');\n const normalise = (v) => {\n if (multiple) {\n const list = Array.isArray(v) ? v : (isAll(v) ? [] : [v]);\n return list.filter((x) => !isAll(x)).map(keyOf);\n }\n if (Array.isArray(v)) v = v[0];\n return isAll(v) ? null : keyOf(v);\n };\n const chosen = () => (multiple ? value.length === 0 : value === null);\n\n for (const opt of options) {\n const key = keyOf(opt.value);\n valueOf.set(key, opt.value);\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = 'twm-dt-filter-chip';\n btn.dataset.value = key;\n if (opt.title) btn.title = String(opt.title);\n if (opt.icon) {\n const icon = document.createElement('span');\n icon.className = 'material-symbols-outlined twm-dt-filter-chip__icon';\n icon.setAttribute('aria-hidden', 'true');\n icon.textContent = String(opt.icon);\n btn.appendChild(icon);\n }\n const label = document.createElement('span');\n label.className = 'twm-dt-filter-chip__label';\n label.textContent = String(opt.label ?? key);\n btn.appendChild(label);\n let count = null;\n if (showCounts) {\n count = document.createElement('span');\n count.className = 'twm-dt-filter-chip__count';\n count.textContent = '\u2013';\n btn.appendChild(count);\n }\n btn.addEventListener('click', (ev) => {\n ev.stopPropagation();\n pick(key);\n });\n chips.set(key, { btn, count });\n el.appendChild(btn);\n }\n\n function outward() {\n if (multiple) return value.length ? value.map((k) => valueOf.get(k)) : null;\n return value === null ? null : valueOf.get(value);\n }\n\n function pick(key) {\n if (isAll(key)) value = multiple ? [] : null;\n else if (multiple) {\n value = value.includes(key) ? value.filter((k) => k !== key) : [...value, key];\n } else {\n value = value === key ? null : key;\n }\n paint();\n const out = outward();\n if (typeof ctx.setValue === 'function') ctx.setValue(out);\n try { spec.onChange?.(out); } catch (err) { console.error('[chips filter] onChange threw', err); }\n }\n\n function paint() {\n for (const [key, { btn }] of chips) {\n const on = isAll(key) ? chosen() : (multiple ? value.includes(key) : value === key);\n btn.classList.toggle('twm-dt-filter-chip--on', on);\n btn.setAttribute('aria-pressed', on ? 'true' : 'false');\n }\n }\n\n function setValue(v) {\n value = normalise(v);\n paint();\n }\n\n function setCounts(counts) {\n for (const [key, { btn, count }] of chips) {\n const n = counts == null ? undefined : counts[key];\n const known = typeof n === 'number' && Number.isFinite(n);\n if (count) count.textContent = known ? n.toLocaleString() : '\u2013';\n btn.classList.toggle('twm-dt-filter-chip--empty', known && n === 0);\n }\n }\n\n setValue(ctx.value);\n if (ctx.counts) setCounts(ctx.counts);\n\n return {\n el,\n setValue,\n setCounts,\n getValue: outward,\n destroy() { /* nothing outside its own element */ },\n };\n}\n\nexport default createChipsFilter;\n", "/**\n * staged_history.js \u2014 STORY-0088. Ctrl+Z and Ctrl+Y over a grid's STAGED\n * edits, and over nothing else. No DOM: the ring decides WHAT to reverse, and\n * the grid that owns the staged cells decides HOW (`apply`).\n *\n * \u2550\u2550 STAGED, NEVER COMMITTED \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\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 * Ctrl+Z takes back what was typed and not yet committed. It never reaches a\n * commit: once a batch has gone to the consumer, `reset()` empties the ring,\n * so an undo or a redo after a commit does nothing. `ACTIONS` lists the only\n * thing the ring knows how to reverse, and `record()` refuses anything else \u2014\n * an undoable action that writes somewhere cannot be added by accident.\n *\n * \u2550\u2550 A DELTA, NOT A SNAPSHOT \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\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 entry is the change itself: one cell's `before` and `after`. A paste of\n * 20,000 cells is one group of 20,000 deltas, held once \u2014 not 20,000 entries'\n * worth of copies of the staged set. `limit` counts ENTRIES (a group is one).\n *\n * Each side is `{has, value}`, not just a value, because a staged cell has\n * three states: absent (no change), staged as null, staged as something. A\n * side that held only the value could not tell the first two apart, and undoing\n * a cell staged as null would leave a staged null behind instead of no change.\n */\n\n/** The only action that exists: one cell's staged state changed.\n * `{action: 'cell:stage', row, col, before: {has, value}, after: {has, value}}`. */\nexport const ACTIONS = Object.freeze(['cell:stage']);\n\n/** Entries kept when no `limit` is given. */\nexport const DEFAULT_HISTORY_LIMIT = 100;\n\nexport class StagedHistory {\n /**\n * @param {object} cfg\n * @param {(entry, direction: 'undo'|'redo') => void} cfg.apply writes one\n * leaf entry's `before` (undo) or `after` (redo) into the staged cells.\n * Called once per leaf; the ring holds no reference to those cells.\n * @param {({canUndo, canRedo, depth}) => void} [cfg.onState] after every\n * change of the stacks.\n * @param {number} [cfg.limit=100] entries kept; the oldest fall off.\n */\n constructor({ apply, onState = null, limit = DEFAULT_HISTORY_LIMIT } = {}) {\n if (typeof apply !== 'function') {\n throw new Error('StagedHistory needs an `apply(entry, direction)`: a ring with no '\n + 'writer would report every undo as done and change nothing.');\n }\n this.apply = apply;\n this.onState = onState;\n this.limit = Number.isFinite(limit) && limit >= 1 ? Math.floor(limit) : DEFAULT_HISTORY_LIMIT;\n this.undoStack = [];\n this.redoStack = [];\n this.group = null;\n /** Groups nest; only the outermost `endGroup` closes one. */\n this.depthOpen = 0;\n /** Set while `apply` runs: a record from inside it is ignored, so an\n * undo that writes through the grid's own staging cannot record its\n * own inverse. */\n this.applying = false;\n }\n\n get canUndo() { return this.undoStack.length > 0; }\n get canRedo() { return this.redoStack.length > 0; }\n get depth() { return this.undoStack.length; }\n\n /** Open a group: everything recorded until the matching `endGroup` is one\n * undo (a fill, a paste). */\n beginGroup(label = '') {\n this.depthOpen += 1;\n if (this.depthOpen === 1) this.group = { action: 'batch', label, entries: [] };\n }\n\n /** Close a group. An empty one is dropped, so it costs no undo step; one\n * holding a single entry is that entry. */\n endGroup() {\n if (!this.depthOpen) return;\n this.depthOpen -= 1;\n if (this.depthOpen) return;\n const group = this.group;\n this.group = null;\n if (!group) return;\n if (group.entries.length === 1) this._push(group.entries[0]);\n else if (group.entries.length) this._push(group);\n }\n\n /** Record one delta. Returns whether it was recorded (false while an\n * entry is being applied). Throws on an action that is not in `ACTIONS`. */\n record(entry) {\n if (this.applying) return false;\n if (!entry || !ACTIONS.includes(entry.action)) {\n throw new Error(`${entry?.action} is not an undoable action: the ring reverses `\n + 'staged cells only, never a commit.');\n }\n if (this.group) { this.group.entries.push(entry); return true; }\n this._push(entry);\n return true;\n }\n\n undo() {\n this._closeOpenGroup();\n const entry = this.undoStack.pop();\n if (!entry) return false;\n this._run(entry, 'undo');\n this.redoStack.push(entry);\n this._publish();\n return true;\n }\n\n redo() {\n this._closeOpenGroup();\n const entry = this.redoStack.pop();\n if (!entry) return false;\n this._run(entry, 'redo');\n this.undoStack.push(entry);\n this._publish();\n return true;\n }\n\n /** Forget everything \u2014 after a commit or a discard, whose cells the\n * entries no longer describe. An open group is closed with it. */\n reset() {\n this.undoStack = [];\n this.redoStack = [];\n this.group = null;\n this.depthOpen = 0;\n this._publish();\n }\n\n /** A group left open (a caller that threw) is closed before an undo, so it\n * cannot swallow every later entry. */\n _closeOpenGroup() {\n if (!this.depthOpen) return;\n this.depthOpen = 1;\n this.endGroup();\n }\n\n _push(entry) {\n this.undoStack.push(entry);\n // A new edit after an undo ends the redo branch.\n this.redoStack = [];\n if (this.undoStack.length > this.limit) this.undoStack.splice(0, this.undoStack.length - this.limit);\n this._publish();\n }\n\n _publish() {\n try {\n this.onState?.({ canUndo: this.canUndo, canRedo: this.canRedo, depth: this.undoStack.length });\n } catch (err) {\n console.error('[StagedHistory] onState threw', err);\n }\n }\n\n _run(entry, direction) {\n this.applying = true;\n try {\n this._applyOne(entry, direction);\n } finally {\n this.applying = false;\n }\n }\n\n /** A group replays in REVERSE on the way back (two writes to one cell must\n * unwind last first) and in order on the way forward. */\n _applyOne(entry, direction) {\n if (entry.action === 'batch') {\n const entries = direction === 'undo' ? [...entry.entries].reverse() : entry.entries;\n for (const child of entries) this._applyOne(child, direction);\n return;\n }\n this.apply(entry, direction);\n }\n}\n", "/**\n * series.js \u2014 STORY-0089. What a FILL HANDLE writes: `detectSeries` reads the\n * block a fill starts from, and `projectSeries` continues it. Pure functions,\n * no DOM, so the rules are tested on their own (tests/series.test.mjs) and a\n * consumer that builds its own grid fills the way DataTable does.\n *\n * The rules, as a spreadsheet has them:\n * - one value -> repeat it\n * - two or more numbers a constant\n * step apart -> continue the arithmetic series\n * - two or more dates (`YYYY-MM-DD`\n * or `Date`) a constant number of\n * days apart -> continue them that many days apart\n * - two or more texts with one shared\n * prefix and suffix around a number\n * a constant step apart (\"Item 1\") -> continue the number, zero-padded\n * as the first is\n * - anything else (equal values\n * included) -> repeat the block, in a cycle\n * - `forceCopy` (Ctrl held) -> repeat the block, in a cycle\n *\n * `values` is the seed IN FILL ORDER: a fill up or left hands the block in\n * reverse, so the value next to the gap comes last and the series runs away\n * from the block.\n */\n\nconst ISO_DATE = /^\\d{4}-\\d{2}-\\d{2}$/;\nconst TRAILING_NUMBER = /^(.*?)(\\d+)(\\D*)$/;\nconst NUMERIC_TEXT = /^[-+]?(\\d+\\.?\\d*|\\.\\d+)$/;\nconst DAY_MS = 86400000;\n\nconst isBlank = (v) => v === null || v === undefined || v === '';\n\n/**\n * What the seed is: `{kind, step}` with `kind` one of 'copy', 'number',\n * 'date' (step in days), 'text-number' (also `prefix`, `suffix`, `pad`) or\n * 'cycle' \u2014 or null for an empty seed or one of blanks only.\n *\n * @param {any[]} values\n * @returns {{kind: string, step: number, prefix?: string, suffix?: string, pad?: number}|null}\n */\nexport function detectSeries(values) {\n if (!Array.isArray(values) || values.length === 0) return null;\n if (values.every(isBlank)) return null;\n if (values.length === 1) return { kind: 'copy', step: 0 };\n\n const numbers = values.map(toNumber);\n if (numbers.every((n) => n !== null)) {\n const step = numbers[1] - numbers[0];\n const constant = numbers.every((n, i) => i === 0 || nearlyEqual(n - numbers[i - 1], step));\n if (constant && step !== 0) return { kind: 'number', step };\n if (constant) return { kind: 'copy', step: 0 };\n return { kind: 'cycle', step: 0 };\n }\n\n const days = values.map(toDayMs);\n if (days.every((d) => d !== null)) {\n const step = Math.round((days[1] - days[0]) / DAY_MS);\n const constant = days.every((d, i) => i === 0 || Math.round((d - days[i - 1]) / DAY_MS) === step);\n if (constant && step !== 0) return { kind: 'date', step };\n if (constant) return { kind: 'copy', step: 0 };\n return { kind: 'cycle', step: 0 };\n }\n\n // \"Item 1\", \"Item 2\": one prefix and suffix around a number.\n const parts = values.map((v) => (typeof v === 'string' ? TRAILING_NUMBER.exec(v) : null));\n if (parts.every(Boolean)) {\n const prefix = parts[0][1];\n const suffix = parts[0][3];\n if (parts.every((p) => p[1] === prefix && p[3] === suffix)) {\n const nums = parts.map((p) => Number(p[2]));\n const step = nums[1] - nums[0];\n const constant = nums.every((n, i) => i === 0 || n - nums[i - 1] === step);\n if (constant && step !== 0) {\n return { kind: 'text-number', step, prefix, suffix, pad: parts[0][2].length };\n }\n }\n }\n\n return { kind: 'cycle', step: 0 };\n}\n\n/**\n * The `count` values a fill writes after `values` (the seed, in fill order).\n * A series keeps its seed's type: number seeds give numbers, text seeds text\n * (with the seed's decimals), `Date` seeds `Date`s and `YYYY-MM-DD` seeds\n * `YYYY-MM-DD`. A repeat hands back the seed's own values.\n *\n * @param {any[]} values\n * @param {number} count\n * @param {{forceCopy?: boolean}} [options] `forceCopy`: repeat the block\n * even when it is a series (Ctrl held).\n * @returns {any[]}\n */\nexport function projectSeries(values, count, { forceCopy = false } = {}) {\n const out = [];\n const n = Math.max(0, Math.floor(Number(count) || 0));\n if (!Array.isArray(values) || values.length === 0 || n === 0) return out;\n const series = forceCopy ? null : detectSeries(values);\n const last = values[values.length - 1];\n if (series?.kind === 'number') {\n const base = toNumber(last);\n const decimals = Math.min(15, Math.max(...values.map(decimalsOf)));\n const allNumbers = values.every((v) => typeof v === 'number');\n for (let i = 1; i <= n; i++) {\n const next = base + series.step * i;\n out.push(allNumbers ? Number(next.toFixed(decimals)) : next.toFixed(decimals));\n }\n return out;\n }\n if (series?.kind === 'date') {\n // Calendar days, not 24-hour blocks: a `Date` keeps its wall-clock\n // time across a daylight-saving change (local calendar), and a\n // YYYY-MM-DD text stays on the UTC calendar it was parsed on.\n const asDate = last instanceof Date;\n for (let i = 1; i <= n; i++) {\n if (asDate) {\n const next = new Date(last.getTime());\n next.setDate(next.getDate() + series.step * i);\n out.push(next);\n } else {\n const next = new Date(toDayMs(last));\n next.setUTCDate(next.getUTCDate() + series.step * i);\n out.push(next.toISOString().slice(0, 10));\n }\n }\n return out;\n }\n if (series?.kind === 'text-number') {\n const base = Number(TRAILING_NUMBER.exec(last)[2]);\n for (let i = 1; i <= n; i++) {\n const next = base + series.step * i;\n const digits = String(Math.abs(next)).padStart(series.pad, '0');\n out.push(`${series.prefix}${next < 0 ? '-' : ''}${digits}${series.suffix}`);\n }\n return out;\n }\n for (let i = 0; i < n; i++) out.push(values[i % values.length]);\n return out;\n}\n\n/** A number, or a text that is exactly one; never NaN. */\nfunction toNumber(value) {\n if (typeof value === 'number') return Number.isFinite(value) ? value : null;\n if (typeof value !== 'string') return null;\n const text = value.trim();\n return NUMERIC_TEXT.test(text) ? Number(text) : null;\n}\n\n/** A `Date`, or a `YYYY-MM-DD` text (read as UTC midnight), in ms. */\nfunction toDayMs(value) {\n if (value instanceof Date) {\n const t = value.getTime();\n return Number.isNaN(t) ? null : t;\n }\n if (typeof value !== 'string' || !ISO_DATE.test(value.trim())) return null;\n const text = value.trim();\n const t = new Date(`${text}T00:00:00Z`).getTime();\n // 2026-02-30 parses to March 2nd in some engines: not a date.\n if (Number.isNaN(t) || new Date(t).toISOString().slice(0, 10) !== text) return null;\n return t;\n}\n\n/** The decimals a seed value is written with (\"2.50\" \u2192 2, 0.1 \u2192 1). */\nfunction decimalsOf(value) {\n const text = typeof value === 'number' ? String(value) : String(value).trim();\n if (/e/i.test(text)) return 15;\n return (text.split('.')[1] || '').length;\n}\n\nfunction nearlyEqual(a, b) {\n return Math.abs(a - b) < 1e-9;\n}\n", "/**\n * tsv.js \u2014 STORY-0085 (writing), STORY-0090 (reading). Tab-separated text,\n * the format Excel and Google Sheets put on the clipboard as `text/plain` and\n * read back from it. DataTable's cell mode copies a range with `toTSV` and\n * pastes a block read with `fromTSV`.\n *\n * QUOTING. Excel quotes a cell that holds a tab, a newline (LF or CR) or a\n * double quote, and doubles every quote inside it: `say \"hi\"` is written\n * `\"say \"\"hi\"\"\"`. Any other cell is written as it is, so a plain grid stays\n * plain text. A writer that does not quote turns a cell holding a tab into two\n * cells, and every column after it lands one to the right when pasted.\n *\n * LINES. Rows are joined with `\\n` and there is no newline after the last\n * row: one cell copied is that cell's text alone.\n *\n * READING. Character by character, never by splitting: a quoted cell may hold\n * tabs and newlines, and a split that cannot know it shifts every column after\n * such a cell into the wrong place, silently. A quote opens a quoted cell only\n * at the start of a cell; inside one a doubled quote is a quote. A CR outside\n * a quoted cell is dropped, so CRLF lines read as LF ones. Excel ends its text\n * with a newline: the empty line that leaves (and any further empty lines at\n * the end) is dropped, so a paste never carries a row nobody copied.\n */\n\n/** One cell's text: `null` and `undefined` are empty, anything else is\n * `String(value)`, quoted the way Excel quotes it when it has to be. */\nexport function tsvCell(value) {\n const text = value === null || value === undefined ? '' : String(value);\n if (/[\\t\\n\\r\"]/.test(text)) return `\"${text.replace(/\"/g, '\"\"')}\"`;\n return text;\n}\n\n/** A matrix (an array of rows, each an array of cells) as TSV. */\nexport function toTSV(matrix) {\n if (!Array.isArray(matrix)) return '';\n return matrix\n .map((row) => (Array.isArray(row) ? row : [row]).map(tsvCell).join('\\t'))\n .join('\\n');\n}\n\n/**\n * Tab-separated text as a matrix of strings, one array per line. Empty text\n * is `[]`; a line with no tab is one cell; empty cells are kept (`'a\\t\\tb'`\n * is three cells). Lines may differ in length: each is as long as it is.\n */\nexport function fromTSV(text) {\n if (text === null || text === undefined || text === '') return [];\n const src = String(text);\n const rows = [];\n let row = [];\n let cell = '';\n let quoted = false;\n for (let i = 0; i < src.length; i++) {\n const ch = src[i];\n if (quoted) {\n if (ch === '\"' && src[i + 1] === '\"') { cell += '\"'; i++; }\n else if (ch === '\"') quoted = false;\n else cell += ch;\n } else if (ch === '\"' && cell === '') quoted = true;\n else if (ch === '\\t') { row.push(cell); cell = ''; }\n else if (ch === '\\r') { /* CRLF reads as LF */ }\n else if (ch === '\\n') { row.push(cell); rows.push(row); row = []; cell = ''; }\n else cell += ch;\n }\n row.push(cell);\n rows.push(row);\n // Excel's closing newline leaves an empty line behind: it is no row.\n while (rows.length > 1) {\n const last = rows[rows.length - 1];\n if (last.length === 1 && last[0] === '') rows.pop();\n else break;\n }\n return rows;\n}\n", "/**\n * InlineRenamer (js_new)\n * Minimal inline editing helper used by node labels and scenario titles.\n * Attaches an input on demand, commits through provided callback, and cleans up deterministically.\n */\n\nfunction assertLabel(label) {\n if (!label || typeof label.appendChild !== 'function') {\n throw new Error('[InlineRenamer] options.label must be an HTMLElement');\n }\n}\n\nfunction buildInput(label, options) {\n const input = document.createElement('input');\n input.type = 'text';\n input.className = ['twm-node-edit-input', options?.inputClass || ''].join(' ').trim();\n input.placeholder = options?.placeholder || label.textContent || 'Name';\n input.value = options?.initialValue ?? label.textContent ?? '';\n input.spellcheck = false;\n input.autocomplete = 'off';\n input.setAttribute('aria-label', 'Edit name');\n return input;\n}\n\nexport function attachInlineRenamer(options = {}) {\n const label = options.label;\n assertLabel(label);\n\n let input = null;\n let editing = false;\n let destroyed = false;\n let originalText = label.textContent || '';\n\n const cleanup = () => {\n // `input` goes first: taking a focused field off the page fires its blur,\n // and a blur with the field still held would commit an edit that just ended.\n const gone = input;\n input = null;\n editing = false;\n if (gone && gone.parentNode === label) gone.remove();\n };\n\n const cancel = () => {\n if (destroyed) return;\n cleanup();\n label.textContent = originalText;\n options.onCancel?.({ value: originalText });\n };\n\n const commit = async (reason = 'commit') => {\n if (destroyed || !input) return;\n const raw = input.value;\n let next = raw;\n try {\n next = options.transformInput ? options.transformInput(raw, { reason }) : raw;\n } catch (err) {\n window.logger?.warn('inline-renamer', 'transformInput failed', err);\n }\n\n try {\n const result = (await options.onCommit?.(next, { reason })) || {};\n if (result.success === false) {\n if (result.keepEditing) {\n input.focus();\n input.select();\n return;\n }\n cancel();\n return;\n }\n const finalValue = result.newValue ?? next ?? '';\n cleanup();\n label.textContent = finalValue;\n options.onFinish?.({ value: finalValue });\n } catch (err) {\n window.logger?.warn('inline-renamer', 'onCommit failed', err);\n cancel();\n }\n };\n\n const start = (triggerEvent = null) => {\n if (destroyed || editing) return;\n editing = true;\n originalText = label.textContent || '';\n label.textContent = '';\n input = buildInput(label, { ...options, initialValue: originalText });\n label.appendChild(input);\n\n const stopEvents = (ev) => ev.stopPropagation();\n input.addEventListener('mousedown', stopEvents);\n input.addEventListener('click', stopEvents);\n\n // Before the renamer's own keys, so that what it attaches to the input\n // hears them first: `attachInputOptions` takes Enter on a highlighted row\n // and Esc with its list open, and the renamer never sees either.\n options.onStart?.({ value: originalText, triggerEvent, input });\n\n input.addEventListener('keydown', (ev) => {\n if (ev.key === 'Enter') {\n ev.preventDefault();\n commit('enter');\n } else if (ev.key === 'Escape') {\n ev.preventDefault();\n cancel();\n }\n });\n\n input.addEventListener('blur', () => commit('blur'));\n\n setTimeout(() => {\n input?.focus();\n input?.select?.();\n }, 0);\n };\n\n const destroy = () => {\n destroyed = true;\n cleanup();\n };\n\n return { start, cancel, commit, destroy };\n}\n\n// `window.InlineRenamer` used to be installed here, at module scope, \"for existing\n// callers\". There are none: every caller in the tree \u2014 EcoAgent's and the\n// library's \u2014 uses the `attachInlineRenamer` named export. It was a global that\n// nothing read.\n//\n// It also made this module UNIMPORTABLE outside a browser, because the assignment\n// ran on import. That is how it was found: a node test that does nothing but\n// `import '@flexdesk/widgets'` died with `ReferenceError: window is not defined`. A\n// library whose entry point cannot be imported without a DOM is a library that\n// cannot be unit-tested, server-rendered, or loaded in a worker \u2014 and\n// package.json's `\"sideEffects\": [\"*.css\"]` was a lie while this line existed.\n", "/**\n * staged_edits.js \u2014 STORY-0088. DataTable's STAGED edits (`staged: true`).\n * INTERNAL to the table, like `cell_grid.js`: built by the cell grid, and\n * reading the table's private fields.\n *\n * With `staged`, an editor's commit does not go to `onCellCommit`: the value\n * is STAGED here, drawn `twm-dt-cell--staged`, and recorded in the undo ring\n * (`staged_history.js`) as a before/after delta. `commit()` hands every staged\n * cell to the consumer's `onCommit({edits})` in one call; `discard()` drops\n * them. While any cell is staged the table's sort, filters and pages are\n * FROZEN \u2014 each such control is disabled with the reason on it\n * (`data-refusal`), and the methods behind them refuse \u2014 because a new order\n * or page would move the rows being edited out from under the person editing.\n *\n * A cell has three states: absent (no change), staged as null, staged as a\n * value. Staging the value its row already holds makes it absent again.\n */\n\nimport { StagedHistory, DEFAULT_HISTORY_LIMIT } from './staged_history.js';\n\nconst key = (rowIdx, colIdx) => `${rowIdx}:${colIdx}`;\n\n/** The controls a freeze holds, under the table's wrapper. The export button\n * moves no rows and is left alone. */\nconst FROZEN_SELECTORS = [\n 'th.sortable',\n '.data-table__filter-cell:not(.data-table__filter-cell--empty)',\n '.data-table__filter-cell:not(.data-table__filter-cell--empty) input',\n '.data-table__filter-cell:not(.data-table__filter-cell--empty) button',\n '.data-table__filter-cell:not(.data-table__filter-cell--empty) select',\n '.data-table__filter-cell:not(.data-table__filter-cell--empty) textarea',\n '.twm-pagination-controls button:not(.twm-pagination-btn--export)',\n '.twm-pagination-controls input',\n '.twm-dt-paging button',\n '.twm-dt-paging input',\n].join(', ');\n\n/** The attributes a freeze writes, put back as they were when it lifts. */\nconst SAVED_ATTRS = ['title', 'data-refusal', 'data-tooltip', 'aria-disabled'];\n\nexport class StagedEdits {\n /** @param {import('./cell_grid.js').CellGrid} grid */\n constructor(grid) {\n this.grid = grid;\n this.table = grid.table;\n /** `rowIdx:colIdx` \u2192 {rowIdx, colIdx, value}: what is staged. */\n this.cells = new Map();\n /** `rowIdx:colIdx` \u2192 message: a cell the last commit refused. */\n this.errors = new Map();\n /** The commit out, or null. */\n this.committing = null;\n /** Bumped by new rows: a commit that outlived its rows marks nothing. */\n this.generation = 0;\n /** Rows touched while the ring applies an entry, drawn after it. */\n this._touched = null;\n /** Element \u2192 the attributes it had before the freeze. */\n this._frozen = new Map();\n const limit = this.table.config.historyLimit;\n this.history = new StagedHistory({\n apply: (entry, direction) => this._apply(entry, direction),\n limit: limit == null ? DEFAULT_HISTORY_LIMIT : limit,\n });\n }\n\n // \u2500\u2500 what is staged \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 has(k) { return this.cells.has(k); }\n\n value(k) { return this.cells.get(k)?.value; }\n\n /** The value the row holds for a cell: what \"no change\" means. */\n original(rowIdx, colIdx) {\n const row = this.grid.currentRow(rowIdx);\n return row ? row[colIdx] : undefined;\n }\n\n /** Every staged cell as `{rowIdx, colIdx, value, previous}`, by row then\n * column; `previous` is the value the row holds. */\n edits() {\n return [...this.cells.values()]\n .sort((a, b) => a.rowIdx - b.rowIdx || a.colIdx - b.colIdx)\n .map(({ rowIdx, colIdx, value }) => ({\n rowIdx, colIdx, value, previous: this.original(rowIdx, colIdx),\n }));\n }\n\n _side(k) {\n return this.cells.has(k) ? { has: true, value: this.cells.get(k).value } : { has: false, value: null };\n }\n\n /** Write one side of a delta: stage the value, or take the cell out. */\n _write(rowIdx, colIdx, side) {\n const k = key(rowIdx, colIdx);\n if (side.has) this.cells.set(k, { rowIdx, colIdx, value: side.value });\n else this.cells.delete(k);\n // A cell staged again (or taken back) is no longer what a commit refused.\n this.errors.delete(k);\n }\n\n /**\n * Stage a value in a cell, as one undo entry (inside an open group, part\n * of it). The value its row holds takes the cell back to no change.\n * Returns whether anything changed.\n */\n stage(rowIdx, colIdx, value) {\n if (this.committing) return false;\n const refusal = this._dropRefusal(rowIdx, colIdx);\n if (!this._stageOne(rowIdx, colIdx, value)) {\n if (refusal) this.grid._redraw(rowIdx, colIdx);\n return false;\n }\n this.grid._redraw(rowIdx, colIdx);\n this._changed();\n return true;\n }\n\n /**\n * STORY-0089. Stage many cells (`[{rowIdx, colIdx, value}]`) as ONE undo\n * entry \u2014 a fill, a paste \u2014 each as `stage` would; the rows are drawn and\n * the listeners told once, at the end. Returns how many cells changed.\n */\n stageMany(cells, label = '') {\n if (this.committing) return 0;\n const rows = new Set();\n let changed = 0;\n this.history.beginGroup(label);\n try {\n for (const { rowIdx, colIdx, value } of cells) {\n const refusal = this._dropRefusal(rowIdx, colIdx);\n if (this._stageOne(rowIdx, colIdx, value)) { changed++; rows.add(rowIdx); }\n else if (refusal) rows.add(rowIdx);\n }\n } finally {\n this.history.endGroup();\n }\n for (const rowIdx of rows) this.grid._redraw(rowIdx);\n if (changed) this._changed();\n return changed;\n }\n\n /** STORY-0087. A text that did not parse stays in its cell, marked, in\n * the grid's own marks; anything staged into the cell ends that refusal,\n * the value its row holds included. Whether there was one. */\n _dropRefusal(rowIdx, colIdx) {\n const k = key(rowIdx, colIdx);\n if (!this.grid.errors.has(k)) return false;\n this.grid.errors.delete(k);\n this.grid.latest.delete(k);\n return true;\n }\n\n /** One cell's new state and its delta in the ring; whether it changed. */\n _stageOne(rowIdx, colIdx, value) {\n const k = key(rowIdx, colIdx);\n const before = this._side(k);\n const after = Object.is(value, this.original(rowIdx, colIdx))\n ? { has: false, value: null } : { has: true, value };\n if (before.has === after.has && Object.is(before.value, after.value)) return false;\n this._write(rowIdx, colIdx, after);\n this.history.record({ action: 'cell:stage', row: rowIdx, col: colIdx, before, after });\n return true;\n }\n\n _apply(entry, direction) {\n this._write(entry.row, entry.col, direction === 'undo' ? entry.before : entry.after);\n this._touched?.add(entry.row);\n }\n\n _walk(step) {\n if (this.committing) return false;\n this._touched = new Set();\n let moved = false;\n try {\n moved = step();\n } finally {\n const rows = this._touched;\n this._touched = null;\n for (const rowIdx of rows) this.grid._redraw(rowIdx);\n }\n if (moved) this._changed();\n return moved;\n }\n\n undo() { return this._walk(() => this.history.undo()); }\n\n redo() { return this._walk(() => this.history.redo()); }\n\n /** Drop every staged cell, its marks and the ring. */\n discard() {\n if (this.committing) return false;\n const rows = this._rows();\n const had = this.cells.size > 0 || this.errors.size > 0;\n this.cells.clear();\n this.errors.clear();\n this.history.reset();\n for (const rowIdx of rows) this.grid._redraw(rowIdx);\n if (had) this._changed();\n return had;\n }\n\n /** New rows (`setData({rows})`): the cells named rows that are gone. */\n clear() {\n this.generation++;\n this.committing = null;\n const had = this.cells.size > 0 || this.errors.size > 0;\n this.cells.clear();\n this.errors.clear();\n this.history.reset();\n if (had) this._changed();\n }\n\n _rows() {\n const rows = new Set();\n for (const c of this.cells.values()) rows.add(c.rowIdx);\n for (const k of this.errors.keys()) rows.add(Number(k.split(':')[0]));\n return rows;\n }\n\n // \u2500\u2500 the commit \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 * Hand every staged cell to `onCommit({edits})`, once. Resolves\n * `{ok: true, committed}` when it succeeded \u2014 the values are written into\n * the rows the table holds, and the staged cells and the ring are gone \u2014\n * or `{ok: false, errors}` when it refused: per-cell errors mark their\n * cells, a refusal with none marks every staged cell, and every staged\n * value stays.\n */\n commit() {\n if (this.committing) return this.committing;\n // An open editor's value is staged first: it is part of the batch.\n if (this.grid.isEditing()) this.grid.editor.commit(null, 'commit');\n const fn = this.table.config.onCommit;\n const edits = this.edits();\n if (!edits.length) return Promise.resolve({ ok: true, committed: 0 });\n if (typeof fn !== 'function') {\n console.warn('[DataTable] commit() needs an `onCommit`; nothing was committed.');\n return Promise.resolve({ ok: false, errors: [] });\n }\n const generation = this.generation;\n const refused = (err) => ({ ok: false, error: err?.message || String(err ?? 'Not saved') });\n let result;\n try {\n result = fn({ edits: edits.map((e) => ({ ...e })) });\n } catch (err) {\n result = refused(err);\n }\n const out = Promise.resolve(result)\n .then((r) => r, refused)\n .then((r) => {\n if (generation !== this.generation) return { ok: false, errors: [] };\n this.committing = null;\n return this._settle(edits, r);\n });\n this.committing = out;\n this._changed();\n return out;\n }\n\n _settle(edits, result) {\n const listed = Array.isArray(result?.errors) ? result.errors : [];\n if (listed.length || result?.ok === false) {\n const errors = [];\n const mark = (rowIdx, colIdx, message) => {\n const k = key(rowIdx, colIdx);\n if (!this.cells.has(k)) return;\n const text = String(message ?? 'Not saved');\n this.errors.set(k, text);\n errors.push({ rowIdx, colIdx, error: text });\n };\n if (listed.length) {\n for (const e of listed) mark(e?.rowIdx, e?.colIdx, e?.error ?? e?.message);\n } else {\n for (const e of edits) mark(e.rowIdx, e.colIdx, result.error);\n }\n for (const rowIdx of this._rows()) this.grid._redraw(rowIdx);\n this._changed();\n return { ok: false, errors };\n }\n const rows = this._rows();\n for (const e of edits) {\n const row = this.grid.currentRow(e.rowIdx);\n if (Array.isArray(row)) row[e.colIdx] = e.value;\n }\n this.cells.clear();\n this.errors.clear();\n this.history.reset();\n for (const rowIdx of rows) this.grid._redraw(rowIdx);\n this._changed();\n return { ok: true, committed: edits.length };\n }\n\n // \u2500\u2500 the freeze \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 /** Why sort, filters and pages are held, or null when nothing is staged. */\n freezeReason() {\n const n = this.cells.size;\n if (!n) return null;\n const own = this.table.config.stagedRefusal;\n if (typeof own === 'function') {\n try { return String(own(n)); } catch (err) {\n console.error('[DataTable] stagedRefusal threw', err);\n }\n } else if (typeof own === 'string' && own) return own;\n return `Sorting, filtering and paging are held while ${n} change${n === 1 ? ' is' : 's are'} `\n + 'not committed. Commit or discard them first.';\n }\n\n /** Disable every control the freeze holds with the reason on it, or put\n * back the ones it held. Run after every render and every change. */\n paintFreeze() {\n const root = this.table._wrapperEl;\n const reason = this.freezeReason();\n root?.classList.toggle('twm-dt--frozen', !!reason);\n if (!reason) {\n for (const [el, saved] of this._frozen) this._thaw(el, saved);\n this._frozen.clear();\n return;\n }\n for (const el of this._frozen.keys()) if (!el.isConnected) this._frozen.delete(el);\n if (!root) return;\n for (const el of root.querySelectorAll(FROZEN_SELECTORS)) {\n if (!this._frozen.has(el)) {\n const saved = {};\n for (const a of SAVED_ATTRS) saved[a] = el.getAttribute(a);\n saved.disabled = 'disabled' in el ? el.disabled : null;\n this._frozen.set(el, saved);\n }\n el.setAttribute('data-refusal', reason);\n el.setAttribute('title', reason);\n if (el.hasAttribute('data-tooltip')) el.setAttribute('data-tooltip', reason);\n el.setAttribute('aria-disabled', 'true');\n if ('disabled' in el) el.disabled = true;\n }\n }\n\n _thaw(el, saved) {\n for (const a of SAVED_ATTRS) {\n if (saved[a] == null) el.removeAttribute(a);\n else el.setAttribute(a, saved[a]);\n }\n if (saved.disabled !== null) el.disabled = saved.disabled;\n }\n\n /** After every change: the freeze, and whoever listens. */\n _changed() {\n this.paintFreeze();\n const fn = this.table.config.onStagedChange;\n if (typeof fn !== 'function') return;\n try {\n fn({\n count: this.cells.size,\n canUndo: this.history.canUndo,\n canRedo: this.history.canRedo,\n committing: !!this.committing,\n });\n } catch (err) {\n console.error('[DataTable] onStagedChange threw', err);\n }\n }\n}\n", "/**\n * fill_handle.js \u2014 STORY-0089. DataTable's FILL HANDLE (`fillHandle: true`).\n * INTERNAL to the table, like `cell_grid.js`: built by the cell grid, and\n * reading the table through it.\n *\n * A small square on the bottom-right corner of the cell range. Dragging it\n * up, down, left or right over the cells beyond the range previews the cells\n * it covers (`twm-dt-cell--fill-preview`) and, on release, STAGES their new\n * values (`staged_edits.js`) as ONE undo entry. What the values are is\n * `series.js`'s: each line of the range \u2014 a column for a fill up or down, a\n * row for a fill left or right \u2014 is a seed, continued as a series or repeated\n * in a cycle; Ctrl (Cmd) held at release repeats it.\n *\n * A target cell that `editable` refuses is SKIPPED: nothing is staged in it,\n * and it is drawn `twm-dt-cell--fill-skipped` until the selection moves, the\n * next fill, or new rows.\n */\n\nimport { projectSeries } from './series.js';\n\nconst key = (rowIdx, colIdx) => `${rowIdx}:${colIdx}`;\n\nexport class FillHandle {\n /** @param {import('./cell_grid.js').CellGrid} grid */\n constructor(grid) {\n this.grid = grid;\n /** The handle element; made on first use, moved into the corner cell. */\n this.el = null;\n /** The `<td>` holding the handle, or null. */\n this.corner = null;\n /** `rowIdx:colIdx` of the cells the last fill skipped. */\n this.skipped = new Set();\n /** `pos:colIdx` of the cells a drag covers now. */\n this.preview = new Set();\n /** The drag in progress: `{range, plan, unbind}`, or null. */\n this.drag = null;\n /** Takes the click guard of the last press on the handle off, or null. */\n this._unguard = null;\n }\n\n // \u2500\u2500 painting (called by the grid for every cell it paints) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** One cell: its preview and skipped marks, and the handle when it is\n * the range's corner. */\n paintCell(td, pos, col) {\n const rowIdx = td.parentNode?.__rowIndex;\n td.classList.toggle('twm-dt-cell--fill-preview', this.preview.has(`${pos}:${col}`));\n td.classList.toggle('twm-dt-cell--fill-skipped', this.skipped.has(key(rowIdx, col)));\n const r = this.grid.sel.range();\n if (r && r.bottom === pos && r.right === col) this._place(td);\n else if (td === this.corner) this._unplace();\n }\n\n _handle() {\n if (this.el) return this.el;\n const el = document.createElement('div');\n el.className = 'twm-dt-fill-handle';\n el.setAttribute('aria-hidden', 'true');\n el.title = 'Drag to fill; hold Ctrl to repeat instead of continuing a series';\n el.addEventListener('pointerdown', (ev) => this._begin(ev));\n this.el = el;\n return el;\n }\n\n _place(td) {\n if (this.grid.isEditing() || this.grid.staged.committing) { this._unplace(); return; }\n if (this.corner && this.corner !== td) this.corner.classList.remove('twm-dt-cell--fill-corner');\n this.corner = td;\n td.classList.add('twm-dt-cell--fill-corner');\n const el = this._handle();\n if (el.parentNode !== td) td.appendChild(el);\n }\n\n _unplace() {\n this.corner?.classList.remove('twm-dt-cell--fill-corner');\n this.corner = null;\n this.el?.remove();\n }\n\n // \u2500\u2500 what a fill covers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 * The fill that reaching cell `to` (`{row, col}`, position and data\n * column) from `range` makes: `{direction, count}`, or null when `to` is\n * inside the range's rows and columns. The direction is the one the cell\n * lies furthest out in; up and down win a tie. Clamped to the page drawn.\n */\n plan(range, to) {\n if (!range || !to) return null;\n const cols = this.grid.columns();\n const [first, last] = this.grid.span();\n const row = Math.max(first, Math.min(last, Number(to.row)));\n const ordL = cols.indexOf(range.left);\n const ordR = cols.indexOf(range.right);\n const ordTo = cols.indexOf(to.col);\n const out = [\n ['down', row - range.bottom],\n ['up', range.top - row],\n ['right', ordTo < 0 ? 0 : ordTo - ordR],\n ['left', ordTo < 0 ? 0 : ordL - ordTo],\n ];\n let best = null;\n for (const [direction, count] of out) {\n if (count > 0 && (!best || count > best.count)) best = { direction, count };\n }\n return best;\n }\n\n /** The cells a plan covers, as `{pos, col}`, line by line in fill order:\n * `[{seed: [{pos, col}], targets: [{pos, col}]}]`. */\n _lines(range, { direction, count }) {\n const cols = this.grid.columns();\n const ordL = cols.indexOf(range.left);\n const ordR = cols.indexOf(range.right);\n const lines = [];\n if (direction === 'down' || direction === 'up') {\n const down = direction === 'down';\n for (let o = ordL; o <= ordR; o++) {\n const col = cols[o];\n const seed = [];\n for (let p = range.top; p <= range.bottom; p++) seed.push({ pos: p, col });\n if (!down) seed.reverse();\n const targets = [];\n for (let i = 1; i <= count; i++) {\n targets.push({ pos: down ? range.bottom + i : range.top - i, col });\n }\n lines.push({ seed, targets });\n }\n } else {\n const right = direction === 'right';\n for (let p = range.top; p <= range.bottom; p++) {\n const seed = [];\n for (let o = ordL; o <= ordR; o++) seed.push({ pos: p, col: cols[o] });\n if (!right) seed.reverse();\n const targets = [];\n for (let i = 1; i <= count; i++) {\n const o = right ? ordR + i : ordL - i;\n if (o >= 0 && o < cols.length) targets.push({ pos: p, col: cols[o] });\n }\n lines.push({ seed, targets });\n }\n }\n return lines;\n }\n\n // \u2500\u2500 the fill \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 * Fill from the range to cell `to`, staging the values as ONE undo\n * entry. Returns `{direction, count, staged, skipped}` (`skipped` the\n * cells `editable` refused, `{row, col, rowIdx}`), or null when nothing\n * was filled: no range, `to` inside it, an editor open or a commit out.\n */\n fill(to, { forceCopy = false } = {}) {\n const g = this.grid;\n g._sync();\n const range = g.sel.range();\n const plan = this.plan(range, to);\n if (!plan || g.staged.committing || g.isEditing()) return null;\n const cells = [];\n const skipped = [];\n for (const { seed, targets } of this._lines(range, plan)) {\n const values = projectSeries(\n seed.map(({ pos, col }) => g.shownValue(g.rowIndexAt(pos), col)),\n targets.length, { forceCopy });\n targets.forEach(({ pos, col }, i) => {\n const rowIdx = g.rowIndexAt(pos);\n if (g.canEdit(pos, col)) cells.push({ rowIdx, colIdx: col, value: values[i] });\n else skipped.push({ row: pos, col, rowIdx });\n });\n }\n const staged = g.staged.stageMany(cells, `fill ${cells.length} cell(s)`);\n // The range grows over what was filled, the cursor at its far end.\n const cols = g.columns();\n const ordL = cols.indexOf(range.left);\n const ordR = cols.indexOf(range.right);\n const { direction, count } = plan;\n if (direction === 'down') g.set({ row: range.bottom + count, col: range.right }, { row: range.top, col: range.left });\n else if (direction === 'up') g.set({ row: range.top - count, col: range.left }, { row: range.bottom, col: range.right });\n else if (direction === 'right') g.set({ row: range.bottom, col: cols[Math.min(cols.length - 1, ordR + count)] }, { row: range.top, col: range.left });\n else g.set({ row: range.top, col: cols[Math.max(0, ordL - count)] }, { row: range.bottom, col: range.right });\n // Marked after the selection moved, which clears the last fill's marks.\n for (const s of skipped) this.skipped.add(key(s.rowIdx, s.col));\n if (skipped.length) g.paint();\n return { direction, count, staged, skipped };\n }\n\n /** The selection moved, or new rows came: the skipped marks are over. */\n clearMarks() {\n this.skipped.clear();\n }\n\n // \u2500\u2500 the drag \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 _begin(ev) {\n if (ev.button != null && ev.button !== 0) return;\n ev.preventDefault();\n ev.stopPropagation();\n const g = this.grid;\n g._sync();\n const range = g.sel.range();\n if (!range || this.drag || g.isEditing() || g.staged.committing) return;\n const doc = this.el.ownerDocument;\n this._guardClick(doc);\n const onMove = (move) => this._move(move);\n const onUp = (up) => {\n const plan = this.drag?.plan;\n this._end();\n if (plan) this.fill(this._reach(range, plan), { forceCopy: !!(up.ctrlKey || up.metaKey) });\n try { g.table._tableEl?.focus({ preventScroll: true }); } catch (_) { /* detached */ }\n };\n const onCancel = () => this._end();\n const onKey = (k) => { if (k.key === 'Escape') { k.preventDefault(); k.stopPropagation(); this._end(); } };\n doc.addEventListener('pointermove', onMove);\n doc.addEventListener('pointerup', onUp);\n doc.addEventListener('pointercancel', onCancel);\n doc.addEventListener('keydown', onKey, true);\n this.drag = {\n range,\n plan: null,\n unbind: () => {\n doc.removeEventListener('pointermove', onMove);\n doc.removeEventListener('pointerup', onUp);\n doc.removeEventListener('pointercancel', onCancel);\n doc.removeEventListener('keydown', onKey, true);\n },\n };\n }\n\n /**\n * A press on the handle and its release make, in a browser, a click (and\n * on a second press a dblclick) of their own, on the element under both:\n * the corner cell, the row, the body. Filled, cancelled by Escape or\n * released where it began, a drag is no click on the table: from the\n * press, the next click in the document is swallowed in the capture\n * phase, and so is every dblclick until the task the release is handled\n * in is over. A cancelled pointer makes no click; the guard ends with it.\n */\n _guardClick(doc) {\n this._unguard?.();\n const view = doc.defaultView;\n let timer = null;\n const swallow = (c) => { c.stopPropagation(); c.preventDefault(); };\n const swallowOnce = (c) => { swallow(c); doc.removeEventListener('click', swallowOnce, true); };\n const released = () => {\n doc.removeEventListener('pointerup', released, true);\n doc.removeEventListener('pointercancel', unguard, true);\n timer = view.setTimeout(unguard, 0);\n };\n const unguard = () => {\n if (timer !== null) view.clearTimeout(timer);\n doc.removeEventListener('click', swallowOnce, true);\n doc.removeEventListener('dblclick', swallow, true);\n doc.removeEventListener('pointerup', released, true);\n doc.removeEventListener('pointercancel', unguard, true);\n if (this._unguard === unguard) this._unguard = null;\n };\n doc.addEventListener('click', swallowOnce, true);\n doc.addEventListener('dblclick', swallow, true);\n doc.addEventListener('pointerup', released, true);\n doc.addEventListener('pointercancel', unguard, true);\n this._unguard = unguard;\n }\n\n /** The cell a plan reaches, as `fill` takes it. */\n _reach(range, { direction, count }) {\n const cols = this.grid.columns();\n if (direction === 'down') return { row: range.bottom + count, col: range.right };\n if (direction === 'up') return { row: range.top - count, col: range.left };\n if (direction === 'right') return { row: range.bottom, col: cols[cols.indexOf(range.right) + count] };\n return { row: range.top, col: cols[cols.indexOf(range.left) - count] };\n }\n\n /** The data cell under the pointer: the event's target, or (a touch,\n * whose events stay on the handle) the element at its point. */\n _cellUnder(ev) {\n const tbody = this.grid.table._tbodyEl;\n const hit = (el) => {\n const td = el?.closest?.('td');\n if (!td || td.__colIdx === undefined || !tbody?.contains(td)) return null;\n const pos = td.parentNode?.__cellPos;\n return pos === undefined ? null : { row: pos, col: td.__colIdx };\n };\n let cell = ev.target === this.el ? null : hit(ev.target);\n const doc = this.el.ownerDocument;\n if (!cell && typeof doc.elementFromPoint === 'function') {\n cell = hit(doc.elementFromPoint(ev.clientX, ev.clientY));\n }\n return cell;\n }\n\n _move(ev) {\n const d = this.drag;\n if (!d) return;\n const cell = this._cellUnder(ev);\n if (!cell) return;\n d.plan = this.plan(d.range, cell);\n this.preview.clear();\n if (d.plan) {\n for (const { targets } of this._lines(d.range, d.plan)) {\n for (const t of targets) this.preview.add(`${t.pos}:${t.col}`);\n }\n }\n this.grid.paint();\n }\n\n _end() {\n const d = this.drag;\n if (!d) return;\n this.drag = null;\n d.unbind();\n this.preview.clear();\n this.grid.paint();\n }\n\n dispose() {\n this._end();\n this._unguard?.();\n this._unplace();\n this.skipped.clear();\n }\n}\n", "/**\n * cell_paste.js \u2014 STORY-0090. DataTable's PASTE (`pasteable: true`, with\n * `staged`). INTERNAL to the table, like `cell_grid.js` and `fill_handle.js`:\n * built by the cell grid, and reading the table through it.\n *\n * A block of tab-separated text (`tsv.js` `fromTSV`, what Excel and Google\n * Sheets put on the clipboard) lands at the CURSOR cell and fills right, over\n * the columns shown, and down, over the rows in the order shown. Each value is\n * read by its column's editor's parse (`cell_editors.js`, or an injected\n * editor's own `parse`), and every cell that reads is STAGED\n * (`staged_edits.js`) as ONE undo entry.\n *\n * - Columns past the last one shown are dropped, with a warning naming how\n * many.\n * - Rows past the last loaded row ask `onPasteOverrun({rows: n})` first:\n * anything but `true` (or a Promise of it) stages nothing; `true` stages\n * the rows that fit and hands the extra ones to `onRowsAppend`.\n * - A value that does not parse marks its cell (`twm-dt-cell--error`, the\n * message as `title` and `data-error`, the text kept in the cell, as an\n * editor's refusal is) and the rest of the block still stages.\n * - A cell `editable` refuses is skipped \u2014 nothing is staged in it \u2014 and\n * drawn `twm-dt-cell--paste-skipped` until the selection moves, the next\n * paste or fill, or new rows.\n */\n\nimport { fromTSV } from './tsv.js';\nimport { CELL_EDITORS } from './cell_editors.js';\n\nconst key = (rowIdx, colIdx) => `${rowIdx}:${colIdx}`;\n\nexport class CellPaste {\n /** @param {import('./cell_grid.js').CellGrid} grid */\n constructor(grid) {\n this.grid = grid;\n /** `rowIdx:colIdx` of the cells the last paste skipped. */\n this.skipped = new Set();\n /** True while a paste waits for `onPasteOverrun` or `onRowsAppend`. */\n this.busy = false;\n }\n\n // \u2500\u2500 painting (called by the grid for every cell it paints) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n paintCell(td, col) {\n const rowIdx = td.parentNode?.__rowIndex;\n td.classList.toggle('twm-dt-cell--paste-skipped', this.skipped.has(key(rowIdx, col)));\n }\n\n /** The selection moved, or new rows came: the skipped marks are over. */\n clearMarks() {\n this.skipped.clear();\n }\n\n // \u2500\u2500 reading a value \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 * The parse a column's pasted text is read with: an injected editor's\n * own (`editors[k].parse`, looked up as the editor is), else the built-in\n * editor's for the column's type, else the text as it is.\n */\n _parserFor(col) {\n const g = this.grid;\n const editors = g._cfg().editors;\n if (editors && typeof editors === 'object') {\n for (const k of [col, g._rawType(col), g._typeOf(col)]) {\n const f = editors[k];\n if (typeof f === 'function') {\n if (typeof f.parse === 'function') return f.parse;\n break;\n }\n }\n }\n const type = g._typeOf(col);\n return Object.prototype.hasOwnProperty.call(CELL_EDITORS, type)\n ? CELL_EDITORS[type].parse : CELL_EDITORS.text.parse;\n }\n\n /** One column's reader: `(text) => {ok: true, value} | {ok: false, error}`. */\n _reader(col) {\n const g = this.grid;\n const cfg = g._cfg();\n const spec = g._editSpec(col) || {};\n const parse = this._parserFor(col);\n const ctx = {\n locale: cfg.locale ?? undefined,\n utc: g.table._utc(),\n messages: cfg.editorMessages ?? undefined,\n options: spec.options,\n allowOther: !!spec.allowOther,\n };\n return (text) => {\n let r;\n try { r = parse(text, ctx); } catch (err) {\n return { ok: false, error: err?.message || String(err ?? 'Not pasted') };\n }\n if (r && r.ok === true) return { ok: true, value: r.value };\n if (r && r.ok === false) return { ok: false, error: String(r.error ?? 'Not pasted') };\n return { ok: false, error: 'Not pasted' };\n };\n }\n\n /** The position of the last loaded row: the rows held in the order shown\n * (all of them filtered and sorted; a server's page, the rows it sent). */\n _lastLoaded() {\n const t = this.grid.table;\n if (t._isServerSide()) return this.grid.span()[1];\n return t._getProcessedRows().length - 1;\n }\n\n _warn(message) {\n console.warn(`[DataTable] paste: ${message}`);\n this.grid.table._notify('Paste', message, 'warn');\n }\n\n // \u2500\u2500 the paste \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 * Paste tab-separated `text` at the cursor. Resolves `{rows, cols, staged,\n * skipped, refused, droppedColumns, appended}` \u2014 `staged` the NUMBER of\n * cells that changed, `skipped` the cells `editable` refused and `refused`\n * the ones whose text did not parse (`{row, col, rowIdx}`, `refused` with\n * its `text` and `error`), `droppedColumns` the columns past the last one,\n * `appended` the rows handed to `onRowsAppend` \u2014 or null when nothing was\n * pasted: empty text, no cursor, an editor open, a commit or another paste\n * out, an overrun declined, or new rows while `onPasteOverrun` was asked.\n */\n async paste(text) {\n const g = this.grid;\n const matrix = fromTSV(text);\n if (!matrix.length || this.busy) return null;\n g._sync();\n const at = g.sel.focus ? { ...g.sel.focus } : null;\n if (!at || g.isEditing() || g.staged.committing) return null;\n const cfg = g._cfg();\n const cols = g.columns();\n const width = Math.max(...matrix.map((line) => line.length));\n const targetCols = cols.slice(cols.indexOf(at.col), cols.indexOf(at.col) + width);\n const droppedColumns = width - targetCols.length;\n const last = this._lastLoaded();\n const fit = Math.max(0, Math.min(matrix.length, last - at.row + 1));\n const extra = matrix.length - fit;\n const generation = g.generation;\n\n if (extra > 0) {\n const ask = cfg.onPasteOverrun;\n let answer = false;\n if (typeof ask === 'function') {\n this.busy = true;\n try { answer = await ask({ rows: extra }); } catch (err) {\n console.error('[DataTable] onPasteOverrun threw', err);\n answer = false;\n } finally {\n this.busy = false;\n }\n } else {\n console.warn(`[DataTable] paste: ${extra} row(s) past the last loaded row and no \\`onPasteOverrun\\`; nothing pasted.`);\n }\n if (answer !== true) return null;\n if (generation !== g.generation || g.isEditing() || g.staged.committing) return null;\n }\n\n // What lands in the loaded rows: each cell read, or skipped.\n const cells = [];\n const skipped = [];\n const refused = [];\n const readers = new Map(targetCols.map((col) => [col, this._reader(col)]));\n for (let r = 0; r < fit; r++) {\n const pos = at.row + r;\n const rowIdx = g.rowIndexAt(pos);\n targetCols.forEach((col, c) => {\n if (c >= matrix[r].length) return; // a short line: nothing there\n if (!g.canEdit(pos, col)) { skipped.push({ row: pos, col, rowIdx }); return; }\n const text = matrix[r][c];\n const read = readers.get(col)(text);\n if (read.ok) cells.push({ rowIdx, colIdx: col, value: read.value });\n else refused.push({ row: pos, col, rowIdx, text, error: read.error });\n });\n }\n\n // The rows past the last loaded one, as data rows: every pasted\n // column read; one that does not read is null, and listed.\n let appended = 0;\n if (extra > 0) {\n const n = (cfg.headers || []).length;\n const rows = [];\n const errors = [];\n for (let r = fit; r < matrix.length; r++) {\n const row = new Array(n).fill(null);\n targetCols.forEach((col, c) => {\n if (c >= matrix[r].length) return;\n const text = matrix[r][c];\n const read = readers.get(col)(text);\n if (read.ok) row[col] = read.value;\n else errors.push({ row: rows.length, colIdx: col, text, error: read.error });\n });\n rows.push(row);\n }\n const append = cfg.onRowsAppend;\n if (typeof append === 'function') {\n appended = rows.length;\n this.busy = true;\n try { await append({ rows, errors }); } catch (err) {\n console.error('[DataTable] onRowsAppend threw', err);\n } finally {\n this.busy = false;\n }\n } else {\n this._warn(`${rows.length} row(s) past the last loaded row were not pasted (no \\`onRowsAppend\\`).`);\n }\n }\n\n const staged = g.staged.stageMany(cells, `paste ${cells.length} cell(s)`);\n\n // The range covers the block that landed, the cursor where it began.\n const lastCol = targetCols[targetCols.length - 1] ?? at.col;\n const lastRow = at.row + Math.max(0, fit - 1);\n g.set({ row: at.row, col: at.col }, { row: lastRow, col: lastCol });\n\n // Marked after the selection moved, which clears the last marks.\n for (const s of skipped) this.skipped.add(key(s.rowIdx, s.col));\n const redraw = new Set();\n for (const f of refused) {\n const k = key(f.rowIdx, f.col);\n g.errors.set(k, { value: f.text, message: f.error });\n // Any older commit of the cell still out no longer owns its marks.\n g.latest.set(k, {});\n g.pending.delete(k);\n redraw.add(f.rowIdx);\n }\n for (const rowIdx of redraw) g._redraw(rowIdx);\n if (skipped.length) g.paint();\n\n if (droppedColumns > 0) {\n this._warn(`${droppedColumns} column(s) past the last column were not pasted.`);\n }\n return {\n rows: matrix.length, cols: width, staged, skipped, refused, droppedColumns, appended,\n };\n }\n\n dispose() {\n this.skipped.clear();\n }\n}\n", "/**\n * cell_grid.js \u2014 STORY-0003. DataTable's half of the CELL MODE\n * (`selectionMode: 'cells'`). INTERNAL to the table: imported by\n * `data_table.js` only, and not part of the widgets barrel \u2014 it reads the\n * table's private fields.\n *\n * It reads the table's rows and columns, paints the cells, listens to the\n * pointer and the keys, moves the selection model (`cell_selection.js`\n * `CellSelection`) and drives the editor (`cell_editor_host.js`).\n *\n * A table without `selectionMode: 'cells'` never builds it.\n */\n\nimport { CellSelection } from './cell_selection.js';\nimport { CellEditorHost, createTextEditor } from './cell_editor_host.js';\nimport { CELL_EDITORS, editorTypeOf } from './cell_editors.js';\nimport { StagedEdits } from './staged_edits.js';\nimport { FillHandle } from './fill_handle.js';\nimport { CellPaste } from './cell_paste.js';\nimport { ISO_DATE, formatDate } from './table_values.js';\n\n/** Is this a cell somebody filled? What Ctrl+arrow stops at. */\nexport function isFilledValue(value) {\n if (value == null) return false;\n if (typeof value === 'string') return value !== '';\n if (typeof value === 'number') return !Number.isNaN(value);\n return true;\n}\n\n/** The keys a printable character is: one character, no Ctrl, Cmd or Alt. */\nfunction isPrintable(ev) {\n return typeof ev.key === 'string' && [...ev.key].length === 1\n && !ev.ctrlKey && !ev.metaKey && !ev.altKey;\n}\n\n/** The arrows, as steps. */\nconst ARROWS = {\n ArrowUp: [-1, 0], ArrowDown: [1, 0], ArrowLeft: [0, -1], ArrowRight: [0, 1],\n};\n\n/**\n * STORY-0085. A cell's raw value as the text a copy carries \u2014 never the text\n * it is drawn as (no `formatValue`, typed-column format, rounding or\n * `nullDisplay`): `null`/`undefined` (and an invalid Date) are empty, a\n * number is `String(n)` (1234.5, not \"1,234.50\"). Dates are ISO 8601: a\n * `Date` is `toISOString()`, except in a column declared `'date'`, where it is\n * the calendar day `YYYY-MM-DD` in the table's zone (`dateTimeZone`); a number\n * in a column declared `'date'` or `'datetime'` is read as epoch ms the same\n * way. Text is copied as it is.\n */\nfunction copyText(value, { kind, utc }) {\n if (value === null || value === undefined) return '';\n const dated = kind === 'date' || kind === 'datetime';\n if (value instanceof Date || (dated && typeof value === 'number')) {\n const t = value instanceof Date ? value.getTime() : value;\n if (!Number.isFinite(t)) return '';\n return kind === 'date' ? formatDate(t, ISO_DATE, { utc }) : new Date(t).toISOString();\n }\n return String(value);\n}\n\n/**\n * DataTable's cell mode. Built by the table when `selectionMode` is 'cells';\n * it reads the table, never the other way round, except through the few hooks\n * the table calls (`decorateRow`, `install`, `rowLeaving`, `isEditing`).\n */\nexport class CellGrid {\n /** @param {import('./data_table.js').DataTable} table */\n constructor(table) {\n this.table = table;\n this.sel = new CellSelection();\n /** `rowIdx:colIdx` \u2192 value typed, while its commit is out. */\n this.pending = new Map();\n /** `rowIdx:colIdx` \u2192 {value, message}: a commit that was refused. */\n this.errors = new Map();\n /** A `render()` asked for while an editor was open. */\n this.renderWaiting = false;\n /** `rowIdx`s whose redraw waits for the editor open in the row to\n * close: a settled commit's, or the consumer's `updateRow`. The row\n * is read when it is drawn, so the newest data is what shows. */\n this.rowsWaiting = new Set();\n /** `rowIdx:colIdx` \u2192 the token of the cell's newest commit, so an\n * older commit settling late does not take the newer one's marks. */\n this.latest = new Map();\n /** Bumped by every new set of rows, so a commit that outlived its rows\n * marks nothing in the new ones. */\n this.generation = 0;\n this.editor = new CellEditorHost({\n onCommit: (s, value, move, reason) => this._committed(s, value, move, reason),\n onCancel: (s, reason) => this._closed(s, reason),\n onRefuse: (s, error, text, reason) => this._refused(s, error, text, reason),\n });\n /** STORY-0088 `staged`: commits are staged here instead of sent. */\n this.staged = null;\n if (this._cfg().staged) {\n if (this._cfg().editable) this.staged = new StagedEdits(this);\n else console.warn('[DataTable] `staged` needs `editable`; ignored.');\n }\n /** STORY-0089 `fillHandle`: the handle on the range's corner. */\n this.fill = null;\n if (this._cfg().fillHandle) {\n if (this.staged) this.fill = new FillHandle(this);\n else console.warn('[DataTable] `fillHandle` needs `staged`; ignored.');\n }\n /** STORY-0090 `pasteable`: a tab-separated block pasted at the cursor. */\n this.paste = null;\n if (this._cfg().pasteable) {\n if (this.staged) this.paste = new CellPaste(this);\n else console.warn('[DataTable] `pasteable` needs `staged`; ignored.');\n }\n }\n\n // \u2500\u2500 what the table is, read through its own helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n _cfg() { return this.table.config; }\n\n /** The data columns shown, in the order shown. */\n columns() {\n return this.table._shownColumns();\n }\n\n /** The positions of the rows on the page drawn, `[first, last]`. */\n span() {\n const s = this.table._pageSpan || { start: 0, count: 0 };\n return [s.start, s.start + s.count - 1];\n }\n\n _sync() {\n const [first, last] = this.span();\n this.sel.setBounds(first, last, this.columns());\n }\n\n /** A position's original row index (the `__rowIndex` space). */\n rowIndexAt(pos) {\n const t = this.table;\n if (t._isServerSide()) return (t.config.dataSource ? 0 : (t.config.offset || 0)) + pos;\n t._getProcessedRows();\n return t._processedIndexMap?.[pos] ?? pos;\n }\n\n rowAt(pos) {\n return this.table._getProcessedRows()[pos] ?? null;\n }\n\n /**\n * The row the table holds NOW for an original row index \u2014 the window's\n * row list, else `config.rows` at the place the table draws it from \u2014\n * the one `updateRow` writes. Never a row captured earlier.\n */\n currentRow(rowIdx) {\n const t = this.table;\n const local = t._virtLocalOf(rowIdx);\n if (local >= 0) return t._virt.rows[local] ?? null;\n const rows = t.config.rows;\n if (!Array.isArray(rows)) return null;\n const at = t._isServerSide() ? rowIdx - (t.config.dataSource ? 0 : (t.config.offset || 0)) : rowIdx;\n return rows[at] ?? null;\n }\n\n /** What a cell shows: a refused or pending commit's value, else the row's. */\n shownValue(rowIdx, col) {\n const key = `${rowIdx}:${col}`;\n const err = this.errors.get(key);\n if (err) return err.value;\n if (this.pending.has(key)) return this.pending.get(key);\n if (this.staged?.has(key)) return this.staged.value(key);\n const row = this.currentRow(rowIdx);\n return row ? row[col] : undefined;\n }\n\n /** Whether the open editor sits in this row element. */\n _holds(tr) {\n const s = this.editor.session;\n return !!s && !!tr && tr.contains(s.td);\n }\n\n /**\n * `updateRow` on a drawn row: the table has stored the data already. When\n * the row holds the open editor the rebuild \u2014 which would take the editor\n * out of the document \u2014 waits for that editor to close, the editor's cell\n * left as it is. Returns whether it waits.\n */\n holdRow(tr, rowIdx) {\n if (!this._holds(tr)) return false;\n this.rowsWaiting.add(rowIdx);\n return true;\n }\n\n valueAt(pos, col) {\n const row = this.rowAt(pos);\n return row ? row[col] : undefined;\n }\n\n /** The `<td>` drawing a cell, or null when it is not drawn. */\n cellEl(pos, col) {\n const tr = this.table.getRowElement(this.rowIndexAt(pos));\n if (!tr) return null;\n for (const td of tr.children) if (td.__colIdx === col) return td;\n return null;\n }\n\n // \u2500\u2500 the public face (DataTable delegates) \u2500\u2500\u2500\u2500\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 /** `{anchor, focus, range}`; each cell is `{row, col, rowIdx}`, and the\n * range also lists its `rows` (original indices) and `columns`. */\n get() {\n this._sync();\n const cell = (c) => (c ? { row: c.row, col: c.col, rowIdx: this.rowIndexAt(c.row) } : null);\n const r = this.sel.range();\n let range = null;\n if (r) {\n const rows = [];\n for (let p = r.top; p <= r.bottom; p++) rows.push(this.rowIndexAt(p));\n range = { ...r, rows };\n }\n return { anchor: cell(this.sel.anchor), focus: cell(this.sel.focus), range };\n }\n\n /** Rows (original indices) the range touches, ascending. */\n rowIndices() {\n const r = this.sel.range();\n if (!r) return [];\n const out = [];\n for (let p = r.top; p <= r.bottom; p++) out.push(this.rowIndexAt(p));\n return out.sort((a, b) => a - b);\n }\n\n /** Select from `anchor` to `focus` (`{row, col}`, positions and data\n * indices), or put the cursor on `focus` alone. */\n set(focus, anchor = null) {\n this._sync();\n if (!focus) { this.sel.clear(); this._changed(); return; }\n this.sel.setCursor(anchor ? anchor.row : focus.row, anchor ? anchor.col : focus.col);\n if (anchor) this.sel.extendTo(focus.row, focus.col);\n this._changed({ reveal: true });\n }\n\n /** `setSelection(indices)` in cell mode: whole rows, the first to the last\n * of them as shown. */\n selectRows(indices) {\n this._sync();\n const t = this.table;\n t._getProcessedRows();\n const map = t._processedIndexMap || [];\n const positions = indices.map((i) => (t._isServerSide()\n ? i - (t.config.dataSource ? 0 : (t.config.offset || 0)) : map.indexOf(i)))\n .filter((p) => p >= 0);\n const cols = this.sel.cols;\n if (!positions.length || !cols.length) { this.sel.clear(); this._changed(); return; }\n this.sel.setCursor(Math.min(...positions), cols[0]);\n this.sel.extendTo(Math.max(...positions), cols[cols.length - 1]);\n this._changed();\n }\n\n clear() {\n this.sel.clear();\n this._changed();\n }\n\n /**\n * STORY-0085. What a copy of the selection puts on the clipboard: the\n * range's cells as text, one array per row in the order SHOWN (after the\n * sort and the filters), its shown columns left to right (a hidden column\n * inside it is not one of them). With no range beyond the cursor, the\n * cursor cell alone. A cell is its RAW value as text (`copyText`), not\n * the text it is drawn as: the value the cell holds now, a staged,\n * pending or refused one included. Null with nothing selected.\n */\n copyMatrix() {\n this._sync();\n const r = this.sel.range();\n if (!r) return null;\n const t = this.table;\n const utc = t._utc();\n const out = [];\n for (let p = r.top; p <= r.bottom; p++) {\n const rowIdx = this.rowIndexAt(p);\n out.push(r.columns.map((col) =>\n copyText(this.shownValue(rowIdx, col), { kind: t._valueKind(col), utc })));\n }\n return out;\n }\n\n /** New rows (`setData({rows})`): the marks were about the old ones. */\n newRows() {\n this.generation++;\n this.pending.clear();\n this.errors.clear();\n this.latest.clear();\n this.rowsWaiting.clear();\n this.staged?.clear();\n this.fill?.clearMarks();\n this.paste?.clearMarks();\n }\n\n isEditing() {\n return !!this.editor.session;\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 /** Called for every row drawn \u2014 on render, on a scroll, on `updateRow` \u2014\n * so a row that arrives later is painted like the rest. */\n decorateRow(tr) {\n const pos = tr.__cellPos;\n if (pos === undefined) return;\n for (const td of tr.children) {\n if (td.__colIdx !== undefined) this._decorateCell(td, pos, tr.__rowIndex, td.__colIdx);\n }\n }\n\n /** One cell: the selection, its commit's pending or refused mark, and\n * (STORY-0088) its staged value and a refused batch's mark. */\n _decorateCell(td, pos, rowIdx, col) {\n this._paintCell(td, pos, col);\n const key = `${rowIdx}:${col}`;\n const err = this.errors.get(key);\n const waiting = this.pending.has(key);\n const staged = !!this.staged?.has(key);\n if (err || waiting) {\n td.textContent = this.table._formatValue(err ? err.value : this.pending.get(key), col);\n } else if (staged) {\n td.textContent = this.table._formatValue(this.staged.value(key), col);\n }\n const message = err ? err.message : this.staged?.errors.get(key);\n td.classList.toggle('twm-dt-cell--pending', waiting);\n td.classList.toggle('twm-dt-cell--staged', staged);\n td.classList.toggle('twm-dt-cell--error', message != null);\n if (message != null) {\n td.title = message;\n td.setAttribute('data-error', message);\n } else td.removeAttribute('data-error');\n this.fill?.paintCell(td, pos, col); // STORY-0089, after the text\n }\n\n _paintCell(td, pos, col) {\n td.classList.toggle('twm-dt-cell--selected', this.sel.contains(pos, col));\n const cursor = this.sel.isCursor(pos, col);\n td.classList.toggle('twm-dt-cell--cursor', cursor);\n if (cursor) td.setAttribute('aria-selected', 'true');\n else td.removeAttribute('aria-selected');\n this.fill?.paintCell(td, pos, col); // STORY-0089\n this.paste?.paintCell(td, col); // STORY-0090\n }\n\n paint() {\n const tbody = this.table._tbodyEl;\n if (!tbody) return;\n for (const tr of tbody.children) {\n const pos = tr.__cellPos;\n if (pos === undefined) continue;\n for (const td of tr.children) {\n if (td.__colIdx !== undefined) this._paintCell(td, pos, td.__colIdx);\n }\n }\n }\n\n /** The selection moved: the cells, the rows `getSelection()` answers, and\n * whoever listens. */\n _changed({ reveal = false } = {}) {\n const t = this.table;\n this.fill?.clearMarks(); // STORY-0089: a skipped mark lasts until the selection moves\n this.paste?.clearMarks(); // STORY-0090: and so does a paste's\n if (reveal && this.sel.focus) t.scrollToRow(this.rowIndexAt(this.sel.focus.row));\n this.paint();\n const before = t.getSelection().join();\n const rows = this.rowIndices();\n t._state.selected.clear();\n for (const i of rows) t._state.selected.add(i);\n t._state.anchorIndex = this.sel.anchor ? this.rowIndexAt(this.sel.anchor.row) : null;\n if (rows.join() !== before) t._notifySelectionChange();\n try { t.config.onCellSelectionChange?.(this.get()); } catch (err) {\n console.error('[DataTable] onCellSelectionChange threw', err);\n }\n }\n\n // \u2500\u2500 the pointer and the keys \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 /** Bound by `_installInteractions` on every render, BEFORE the table's own\n * activation, detail and copy listeners, so a key the cell mode takes\n * goes no further. Listeners go on the table's disposers. */\n install(tbody, table) {\n const t = this.table;\n const on = (el, type, fn) => {\n el.addEventListener(type, fn);\n t._disposers.push(() => el.removeEventListener(type, fn));\n };\n this._sync();\n const cellOf = (target) => {\n const td = target?.closest?.('td');\n if (!td || td.__colIdx === undefined || !tbody.contains(td)) return null;\n const tr = td.parentNode;\n if (tr?.__cellPos === undefined) return null;\n return { td, row: tr.__cellPos, col: td.__colIdx };\n };\n const inEditor = (target) => !!this.editor.session && this.editor.session.td.contains(target);\n\n on(tbody, 'click', (ev) => {\n if (ev.button != null && ev.button !== 0) return;\n if (inEditor(ev.target)) return;\n const hit = cellOf(ev.target);\n if (!hit) return;\n this._sync();\n if (ev.shiftKey && this.sel.anchor) this.sel.extendTo(hit.row, hit.col);\n else this.sel.setCursor(hit.row, hit.col);\n this._changed();\n try { table.focus({ preventScroll: true }); } catch (_) { /* detached */ }\n });\n on(tbody, 'dblclick', (ev) => {\n if (inEditor(ev.target)) return;\n const hit = cellOf(ev.target);\n if (!hit || !this.canEdit(hit.row, hit.col)) return;\n this._sync();\n this.sel.setCursor(hit.row, hit.col);\n this._changed();\n if (this.open(hit.row, hit.col)) ev.stopImmediatePropagation();\n });\n // A right-click outside the range moves the cursor there first, so the\n // table's own menu (bound after this) finds its row already selected.\n on(tbody, 'contextmenu', (ev) => {\n if (inEditor(ev.target)) return;\n const hit = cellOf(ev.target);\n if (!hit || this.sel.contains(hit.row, hit.col)) return;\n this._sync();\n this.sel.setCursor(hit.row, hit.col);\n this._changed();\n });\n on(table, 'keydown', (ev) => {\n if (ev.isComposing || inEditor(ev.target)) return;\n if (ev.target !== table && ev.target?.closest?.('input, select, textarea, button, [contenteditable=\"true\"]')) return;\n if (this._onKey(ev)) {\n ev.preventDefault();\n ev.stopImmediatePropagation();\n }\n });\n // STORY-0090. Ctrl+V on the focused table: the browser's paste event\n // carries the clipboard's text, with no permission to ask for. In an\n // editor (or any field) the paste is the field's.\n if (this.paste) {\n on(table, 'paste', (ev) => {\n if (inEditor(ev.target)) return;\n if (ev.target !== table && ev.target?.closest?.('input, select, textarea, [contenteditable=\"true\"]')) return;\n const text = ev.clipboardData?.getData?.('text/plain');\n if (typeof text !== 'string') return;\n ev.preventDefault();\n this.paste.paste(text);\n });\n }\n // An editor that was open across a render of its row (an `updateRow`)\n // is still the editor; the paint follows the model.\n this.paint();\n // STORY-0088. The new controls are held while cells are staged.\n this.staged?.paintFreeze();\n }\n\n /** One key on the focused table. Returns whether the cell mode took it. */\n _onKey(ev) {\n this._sync();\n const ctrl = ev.ctrlKey || ev.metaKey;\n const k = ev.key;\n // STORY-0088. Ctrl+Z takes a staged edit back; Ctrl+Y (Ctrl+Shift+Z)\n // puts it back. Taken even with nothing to undo: the browser's own\n // undo has nothing to do on a table either.\n if (this.staged && ctrl && !ev.altKey) {\n const lower = String(k).toLowerCase();\n if (lower === 'z' && !ev.shiftKey) { this.staged.undo(); return true; }\n if (lower === 'y' || (lower === 'z' && ev.shiftKey)) { this.staged.redo(); return true; }\n }\n if (ARROWS[k] && !ev.altKey) {\n const [dr, dc] = ARROWS[k];\n if (ctrl) {\n this.sel.jump(dr, dc, (r, c) => isFilledValue(this.valueAt(r, c)), { extend: ev.shiftKey });\n } else this.sel.move(dr, dc, { extend: ev.shiftKey });\n this._changed({ reveal: true });\n return true;\n }\n if ((k === 'Home' || k === 'End') && !ev.altKey) {\n this.sel.lineEnd(k === 'End', { extend: ev.shiftKey, corner: ctrl });\n this._changed({ reveal: true });\n return true;\n }\n if (k === 'Tab' && !ctrl && !ev.altKey) {\n // On the last cell (the first, going back) Tab is not taken:\n // focus moves on out of the table, as Tab says.\n if (this.sel.tabEnds(ev.shiftKey)) return false;\n this.sel.tab(ev.shiftKey);\n this._changed({ reveal: true });\n return true;\n }\n if (ctrl && !ev.altKey && String(k).toLowerCase() === 'a') {\n this.sel.selectAll();\n this._changed();\n return true;\n }\n if (k === 'Escape') {\n this.sel.collapse();\n this._changed();\n this.table._hideContextMenu();\n return true;\n }\n const f = this.sel.focus;\n if (!f) return false;\n if ((k === 'F2' || (k === 'Enter' && !ctrl && !ev.altKey && !ev.shiftKey)) && this.canEdit(f.row, f.col)) {\n return this.open(f.row, f.col);\n }\n if (isPrintable(ev) && this.canEdit(f.row, f.col)) {\n return this.open(f.row, f.col, { initialText: ev.key });\n }\n return false;\n }\n\n // \u2500\u2500 editing \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** Whether a cell opens an editor: `editable` says so for its column. */\n canEdit(pos, col) {\n const spec = this._cfg().editable;\n if (!spec) return false;\n // STORY-0088. While a staged batch is out, nothing new is typed into it.\n if (this.staged?.committing) return false;\n if (spec === true) return true;\n if (Array.isArray(spec)) return spec.includes(col);\n if (typeof spec === 'function') {\n try { return !!spec(col, this.rowAt(pos), this.rowIndexAt(pos)); } catch (err) {\n console.error('[DataTable] editable threw', err);\n return false;\n }\n }\n return false;\n }\n\n /** STORY-0087. The column's `editTypes` entry, as `{type, ...}`, or null. */\n _editSpec(col) {\n const all = this._cfg().editTypes;\n let spec = all && typeof all === 'object' ? all[col] : null;\n if (typeof spec === 'string') spec = { type: spec };\n return spec && typeof spec === 'object' ? spec : null;\n }\n\n /** The column's type as it is named: `editTypes`', else the declared one\n * (`columnTypes`), else the detected one. */\n _rawType(col) {\n const spec = this._editSpec(col);\n if (spec?.type) return String(spec.type);\n const declared = this._cfg().columnTypes?.[col];\n return declared || this.table._columnTypes?.[col] || 'text';\n }\n\n /** The column's type as `editors` and the built-in editors know it:\n * 'num' is 'number', 'date' is 'datetime'. */\n _typeOf(col) {\n return editorTypeOf(this._rawType(col));\n }\n\n /** By column index, then by type (as named, then as the built-ins name\n * it), then the built-in editor for the type, else the text box. */\n _factoryFor(col) {\n const editors = this._cfg().editors;\n if (editors && typeof editors === 'object') {\n for (const k of [col, this._rawType(col), this._typeOf(col)]) {\n if (typeof editors[k] === 'function') return editors[k];\n }\n }\n const builtIn = Object.prototype.hasOwnProperty.call(CELL_EDITORS, this._typeOf(col))\n ? CELL_EDITORS[this._typeOf(col)] : null;\n return builtIn ? builtIn.create : createTextEditor;\n }\n\n /**\n * Open the editor on a cell (position, data column). Brings the row into\n * view first. Returns whether an editor opened.\n */\n open(pos, col, { initialText = null } = {}) {\n if (this.editor.session || !this.canEdit(pos, col)) return false;\n this.table.scrollToRow(this.rowIndexAt(pos));\n const td = this.cellEl(pos, col);\n if (!td) return false;\n const rowIdx = this.rowIndexAt(pos);\n const row = this.currentRow(rowIdx);\n const headers = this._cfg().headers || [];\n // The editor holds what the cell SHOWS \u2014 a refused or pending value,\n // not the row's \u2014 so it is what the person sees that they edit.\n return this.editor.open({\n td,\n factory: this._factoryFor(col),\n pos, colIdx: col, rowIdx, row,\n generation: this.generation,\n value: this.shownValue(rowIdx, col),\n column: { ...this._editSpec(col), index: col, header: headers[col], type: this._typeOf(col) },\n args: {\n locale: this._cfg().locale ?? undefined,\n utc: this.table._utc(),\n messages: this._cfg().editorMessages ?? undefined,\n },\n initialText,\n });\n }\n\n /** The virtual window is taking a row out: an editor in it commits, as a\n * click elsewhere would \u2014 what was typed is not thrown away. An editor\n * with no `getValue` has nothing to commit, and is cancelled. */\n rowLeaving(tr) {\n const s = this.editor.session;\n if (s && tr.contains(s.td)) this.editor.commit(null, 'scroll');\n }\n\n dispose() {\n this.fill?.dispose();\n this.paste?.dispose();\n this.editor.cancel('dispose');\n this.renderWaiting = false;\n this.rowsWaiting.clear();\n }\n\n /** After every close: focus back on the table when the keyboard closed it,\n * and the render that waited for the editor. */\n _closed(s, reason) {\n const t = this.table;\n if (reason === 'dispose') return;\n if (reason === 'key' || reason === 'editor') {\n try { t._tableEl?.focus({ preventScroll: true }); } catch (_) { /* detached */ }\n }\n if (this.renderWaiting) {\n this.renderWaiting = false;\n this.rowsWaiting.clear(); // the render draws every row\n // A commit made by the virtual window taking the row out is made\n // in the middle of the window's own redraw, which a render would\n // pull out from under it: that one waits for the redraw to end.\n if (reason === 'scroll') queueMicrotask(() => { if (t._wrapperEl) t.render(); });\n else t.render();\n return;\n }\n if (this.rowsWaiting.size) {\n const flush = () => {\n const waiting = [...this.rowsWaiting];\n this.rowsWaiting.clear();\n for (const rowIdx of waiting) this._redraw(rowIdx);\n };\n if (reason === 'scroll') queueMicrotask(() => { if (t._wrapperEl) flush(); });\n else flush();\n }\n }\n\n /**\n * Draw a row again after a commit, from the row the table holds now\n * (`currentRow`). `updateRow` rebuilds EVERY cell of the row, so while an\n * editor is open in it (save, Tab, type \u2014 the commit settles under the\n * next editor) the row waits for that editor to close (`_closed`), and\n * only the committed cell's marks are painted now.\n */\n _redraw(rowIdx, col = null) {\n const t = this.table;\n const tr = t.getRowElement(rowIdx);\n const row = this.currentRow(rowIdx);\n if (!tr || !row) return;\n if (this._holds(tr)) {\n this.rowsWaiting.add(rowIdx);\n if (col === null || tr.__cellPos === undefined) return;\n const s = this.editor.session;\n for (const td of tr.children) {\n if (td.__colIdx === col && td !== s.td) this._decorateCell(td, tr.__cellPos, rowIdx, col);\n }\n return;\n }\n this.rowsWaiting.delete(rowIdx);\n t.updateRow(rowIdx, row);\n }\n\n /** STORY-0087. The editor closed holding text that does not parse (the\n * focus left it, or its row left the window): nothing is committed, and\n * the cell keeps the text, marked with the message, as a refused commit's\n * would be. */\n _refused(s, error, text, reason) {\n if (s.generation === this.generation) {\n const key = `${s.rowIdx}:${s.colIdx}`;\n this.errors.set(key, { value: text, message: error });\n // Any older commit of the cell still out no longer owns its marks.\n this.latest.set(key, {});\n this.pending.delete(key);\n this._redraw(s.rowIdx, s.colIdx);\n }\n this._closed(s, reason);\n }\n\n _committed(s, value, move, reason) {\n if (move) {\n this._sync();\n if (move === 'down' || move === 'up') this.sel.move(move === 'down' ? 1 : -1, 0);\n else this.sel.tab(move === 'left');\n this._changed({ reveal: true });\n }\n const live = s.generation === this.generation;\n const key = `${s.rowIdx}:${s.colIdx}`;\n // Left as it was shown: no edit at all.\n if (Object.is(value, s.previous)) {\n this._closed(s, reason);\n return;\n }\n // STORY-0088 `staged`: the value is staged, not sent.\n if (this.staged) {\n if (live) this.staged.stage(s.rowIdx, s.colIdx, value);\n this._closed(s, reason);\n return;\n }\n // What the row holds: the table's row now, or \u2014 for a commit that\n // outlived its rows \u2014 the row it was opened on.\n const held = live ? this.currentRow(s.rowIdx) : s.row;\n const stored = held ? held[s.colIdx] : undefined;\n // A refused cell given back the value its row holds: nothing to save,\n // the refusal is over.\n if (live && this.errors.has(key) && !this.pending.has(key) && Object.is(value, stored)) {\n this.errors.delete(key);\n this.latest.delete(key);\n this._redraw(s.rowIdx, s.colIdx);\n this._closed(s, reason);\n return;\n }\n const fn = this._cfg().onCellCommit;\n const token = {};\n if (live) this.latest.set(key, token);\n const finish = (result) => {\n if (!live || s.generation !== this.generation) return;\n const newest = this.latest.get(key) === token;\n const good = !(result && result.ok === false);\n // The value goes into the row the table holds NOW, so a newer row\n // the consumer put in meanwhile (`updateRow`) keeps its other cells.\n if (good) {\n const row = this.currentRow(s.rowIdx);\n if (Array.isArray(row)) row[s.colIdx] = value;\n }\n // A newer commit of the cell is still out: its marks are its own.\n if (newest) {\n this.latest.delete(key);\n this.pending.delete(key);\n if (good) this.errors.delete(key);\n else this.errors.set(key, { value, message: String(result.error ?? 'Not saved') });\n }\n this._redraw(s.rowIdx, s.colIdx);\n };\n const refused = (err) => ({ ok: false, error: err?.message || String(err ?? 'Not saved') });\n let result;\n if (typeof fn === 'function') {\n try {\n result = fn({ rowIdx: s.rowIdx, colIdx: s.colIdx, value, previous: stored });\n } catch (err) {\n result = refused(err);\n }\n }\n if (result && typeof result.then === 'function') {\n if (live) {\n this.pending.set(key, value);\n this.errors.delete(key);\n this._redraw(s.rowIdx, s.colIdx);\n }\n this._closed(s, reason);\n result.then(finish, (err) => finish(refused(err)));\n return;\n }\n finish(result);\n this._closed(s, reason);\n }\n}\n", "/**\n * column_order.js \u2014 STORY-0086. The order DataTable draws its data columns in\n * (`reorderable`, `columnOrder`, `moveColumn`, `getColumnOrder`), and the drag\n * on the header that changes it. Internal to the table, like `cell_grid.js`.\n *\n * \u2550\u2550 AN ORDER IS A LIST OF DATA INDICES \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\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 * The order is every data column's index (hidden ones included), in the order\n * shown: `[0, 3, 1, 2]` draws column 3 second. Everything else the table keeps\n * by column \u2014 `hiddenColumns`, the sort, the filters, `renderCell`'s `colIdx`,\n * the cell mode's `col` \u2014 stays a data index and so stays on its column. Only\n * what is BY DRAWN POSITION (the cells of a row, the widths) follows the order.\n *\n * A table with no order asked for (`null`) draws 0, 1, 2, \u2026 as in 0.16. An\n * order that is not a permutation of today's columns \u2014 a saved one from when\n * the table had a different number of columns \u2014 is no order: the natural one\n * is drawn.\n */\n\n/** Whether `order` is a permutation of `0..n-1`. */\nexport function isColumnOrder(order, n) {\n if (!Array.isArray(order) || order.length !== n) return false;\n const seen = new Set();\n for (const c of order) {\n if (!Number.isInteger(c) || c < 0 || c >= n || seen.has(c)) return false;\n seen.add(c);\n }\n return true;\n}\n\n/** `0..n-1`. */\nexport function naturalOrder(n) {\n return Array.from({ length: Math.max(0, n) }, (_, i) => i);\n}\n\n/**\n * The data indices of a row of `count` cells in the order drawn: `order`\n * where it holds, and any cell past the headers (a row longer than them) after\n * it, as 0.16 drew them.\n */\nexport function cellOrder(order, count) {\n if (!order) return naturalOrder(count);\n const out = order.filter((c) => c < count);\n for (let c = order.length; c < count; c++) out.push(c);\n return out;\n}\n\n/** `order` with the column at position `from` taken out and put back at\n * position `to` (positions in `order`). A copy; `order` is not changed. */\nexport function moveInOrder(order, from, to) {\n const next = order.slice();\n const [moved] = next.splice(from, 1);\n next.splice(to, 0, moved);\n return next;\n}\n\n/**\n * The header drag. Every data column's header cell is draggable; dropping one\n * on another data column's header moves it to that column's place. A press\n * that starts on a resize grip is the resize's, never a drag. The row-number\n * and select columns are no data columns: they do not drag and take no drop,\n * so nothing lands in front of them.\n */\nexport class ColumnReorder {\n /** @param {import('./data_table.js').DataTable} table */\n constructor(table) {\n this.table = table;\n /** The data column being dragged, or null. */\n this.dragging = null;\n /** Whether the last press on a header cell was on its resize grip. */\n this.onGrip = false;\n }\n\n /** Wire the header row of a fresh render. Its cells are new each render,\n * so nothing needs taking off. */\n install(headRow) {\n if (!headRow) return;\n [...headRow.children].forEach((th, domIdx) => {\n const col = this.table._dataIdxOfDom(domIdx);\n if (col === null) return;\n th.draggable = true;\n th.classList.add('twm-dt-col--movable');\n // Capture: the grip stops its own mousedown, so a listener on the\n // way up would never hear it.\n th.addEventListener('mousedown', (ev) => {\n this.onGrip = !!ev.target?.closest?.('.twm-dt-col-resizer');\n }, true);\n th.addEventListener('dragstart', (ev) => {\n if (this.onGrip || ev.target?.closest?.('.twm-dt-col-resizer')) {\n ev.preventDefault();\n return;\n }\n this.dragging = col;\n try {\n ev.dataTransfer?.setData('text/plain', String(col));\n if (ev.dataTransfer) ev.dataTransfer.effectAllowed = 'move';\n } catch (_) { /* a drag with no data transfer */ }\n th.classList.add('twm-dt-col--dragging');\n });\n th.addEventListener('dragover', (ev) => {\n if (this.dragging === null || this.dragging === col) return;\n ev.preventDefault(); // a drop is welcome here\n if (ev.dataTransfer) ev.dataTransfer.dropEffect = 'move';\n // Moved right it lands AFTER the column it is dropped on.\n const order = this.table.getColumnOrder();\n th.classList.add('twm-dt-col--drop');\n th.classList.toggle('twm-dt-col--drop-after', order.indexOf(col) > order.indexOf(this.dragging));\n });\n th.addEventListener('dragleave', () => th.classList.remove('twm-dt-col--drop', 'twm-dt-col--drop-after'));\n th.addEventListener('drop', (ev) => {\n th.classList.remove('twm-dt-col--drop', 'twm-dt-col--drop-after');\n const from = this.dragging;\n this.dragging = null;\n if (from === null || from === col) return;\n ev.preventDefault();\n const order = this.table.getColumnOrder();\n this.table.moveColumn(order.indexOf(from), order.indexOf(col));\n });\n th.addEventListener('dragend', () => {\n th.classList.remove('twm-dt-col--dragging');\n this.dragging = null;\n });\n });\n }\n\n /** \"Move left\" / \"Move right\" for the header menu of data column `col`:\n * past the shown column next to it. */\n menuItems(col) {\n const shown = this.table._shownColumns();\n const at = shown.indexOf(col);\n if (at < 0) return [];\n const order = this.table.getColumnOrder();\n const step = (to) => () => this.table.moveColumn(order.indexOf(col), order.indexOf(to));\n return [\n { label: 'Move left', icon: 'arrow_back', action: 'move-left', disabled: at === 0,\n onChoose: at === 0 ? undefined : step(shown[at - 1]) },\n { label: 'Move right', icon: 'arrow_forward', action: 'move-right',\n disabled: at === shown.length - 1,\n onChoose: at === shown.length - 1 ? undefined : step(shown[at + 1]) },\n ];\n }\n}\n", "/**\n * header_actions.js \u2014 STORY-0066. The pieces DataTable's column groups\n * (column_groups.js) and structural edits (table_structure.js) share: the\n * consumer callback called behind a guard, and the action button drawn in a\n * header cell. INTERNAL to the table, and not part of the widgets barrel.\n */\n\n/** Call the table option `name` (a function on `config`) with `args`. An\n * option that is not a function answers undefined; one that throws is\n * logged and answers undefined too, so a consumer's bug never breaks a\n * render or a click. */\nexport function callOption(config, name, ...args) {\n const fn = config?.[name];\n if (typeof fn !== 'function') return undefined;\n try {\n return fn.apply(config, args);\n } catch (err) {\n console.error(`[DataTable] ${name} threw`, err);\n return undefined;\n }\n}\n\n/**\n * A button in a header cell for the item `{icon?, label?, title?, disabled?}`:\n * the material-symbols icon, or the label when there is no icon; the title\n * and aria-label from `title ?? label`; disabled when `disabled`. Its press\n * is its own: neither the mousedown nor the click reaches the header (no\n * sort, no drag under it).\n */\nexport function headerActionButton(className, { icon, label, title, disabled } = {}, onClick) {\n const b = document.createElement('button');\n b.type = 'button';\n b.className = className;\n if (icon) {\n const span = document.createElement('span');\n span.className = 'material-symbols-outlined';\n span.textContent = String(icon);\n b.appendChild(span);\n } else if (label != null) {\n b.appendChild(document.createTextNode(String(label)));\n }\n const name = title ?? label;\n if (name != null) {\n b.title = String(name);\n b.setAttribute('aria-label', String(name));\n }\n if (disabled) b.disabled = true;\n b.addEventListener('mousedown', (ev) => ev.stopPropagation());\n b.addEventListener('click', (ev) => {\n ev.preventDefault();\n ev.stopPropagation();\n onClick(ev);\n });\n return b;\n}\n", "/**\n * column_groups.js \u2014 STORY-0066. DataTable's COLUMN GROUPS (`columnGroups`).\n * INTERNAL to the table: imported by `data_table.js` (and its span helpers by\n * `crosstab.js`) only, and not part of the widgets barrel \u2014 it reads the\n * table's private fields.\n *\n * A group is `{key, label?, columns: number[]}` (data column indices). The\n * groups draw a second header row above the column headers, one cell a run of\n * shown columns of the same group spanning them, a blank cell over the row\n * number / select column and over any run of columns in no group.\n *\n * \u2500\u2500 WHY A TABLE OF ITS OWN \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 group row is a separate `<table class=\"twm-dt-groups\">` in the header\n * wrap, above the header table, rather than a first row of the header's\n * `<thead>`. Every width pass of the table (`_measureNaturalWidths`,\n * `_syncHeaderWidths`, the resize drag, `_applyTableWidth`) reads and writes\n * the header rows CELL BY CELL at the column's index, and under\n * `table-layout: fixed` the first row decides the track \u2014 a row of spanning\n * cells in either place would misalign every column. So the group table has a\n * `<colgroup>` of its own, one `<col>` a drawn column, and `align()` copies the\n * header's widths, table width, layout and sideways scroll onto it after every\n * pass that changes them (DataTable `_syncHeaderScroll`). The header wrap\n * scrolls both tables together.\n *\n * \u2500\u2500 AN EMPTY GROUP KEEPS A PLACEHOLDER COLUMN \u2500\u2500\u2500\u2500\u2500\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 * A group with no columns would have no cell to draw, so it gets one drawn\n * column of its own: a header cell `th.twm-dt-col--placeholder` (holding the\n * group's add control under `onColumnAdd`), an empty filter cell, and an\n * empty `td.twm-dt-cell--placeholder` in every body row. It is NO DATA\n * column: `_dataIdxOfDom` answers null for it, it is not in a copy, the CSV,\n * `ctx.colIdx` or the cell mode. It stands after the shown columns of the\n * groups listed before it.\n *\n * A table without `columnGroups` never builds this.\n */\n\nimport { callOption, headerActionButton } from './header_actions.js';\n\n/**\n * A row of spanning cells, cleaned (shared with STORY-0091's crosstab header\n * rows): the data columns that exist, each column in the first cell that lists\n * it, `key`, a label, and `index`, the cell's place in `spec` (the consumer's\n * object is looked up there when drawing, never kept). Under `requireKey` a\n * cell without a key is dropped; a cell without a label is labelled\n * `defaultLabel(cell)`.\n */\nexport function normalizeSpans(spec, n, { requireKey = false, defaultLabel = () => '' } = {}) {\n const taken = new Set();\n const out = [];\n (Array.isArray(spec) ? spec : []).forEach((g, index) => {\n if (!g || (requireKey && g.key == null)) return;\n const columns = [];\n for (const c of Array.isArray(g.columns) ? g.columns : []) {\n const i = Number(c);\n if (!Number.isInteger(i) || i < 0 || i >= n || taken.has(i)) continue;\n taken.add(i);\n columns.push(i);\n }\n out.push({ key: g.key, label: g.label == null ? defaultLabel(g) : String(g.label), columns, index });\n });\n return out;\n}\n\n/** The groups the table was given, cleaned: a key each, the key as the label\n * when none is given. */\nfunction normalize(spec, n) {\n return normalizeSpans(spec, n, { requireKey: true, defaultLabel: (g) => String(g.key) });\n}\n\n/** A spanning header cell over a run of columns in no group (or no cell). */\nexport function blankSpanCell(span) {\n const th = document.createElement('th');\n th.className = 'twm-dt-group twm-dt-group--none';\n th.colSpan = span;\n return th;\n}\n\n/** A spanning header cell holding a label, its tooltip `title`. */\nexport function labelSpanCell(span, label, title = label) {\n const th = document.createElement('th');\n th.className = 'twm-dt-group';\n th.colSpan = span;\n th.title = title;\n const el = document.createElement('span');\n el.className = 'twm-dt-group__label';\n el.textContent = label;\n th.appendChild(el);\n return th;\n}\n\nexport class ColumnGroups {\n /** @param {import('./data_table.js').DataTable} table */\n constructor(table) {\n this.table = table;\n this._memoKey = null;\n this._memo = null;\n this._el = null;\n }\n\n _cfg() {\n return this.table.config;\n }\n\n /**\n * The drawn columns after the lead, in order: `{col, group}` for a shown\n * data column (`group` the index in `groups`, or null) and\n * `{placeholder: true, group}` for an empty group's column. The data\n * columns come in the order the table draws them (STORY-0086's\n * `columnOrder`, hidden ones left out). Memoised on the groups' content,\n * the column count and the drawn columns.\n */\n layout() {\n const cfg = this._cfg();\n const n = cfg.headers?.length || 0;\n const shown = this.table._shownColumns();\n const spec = Array.isArray(cfg.columnGroups) ? cfg.columnGroups : [];\n const key = `${n}|${shown.join(',')}|${spec.map((g) => (g ? `${g.key}\\x01${g.label}\\x01${(g.columns || []).join(',')}` : '')).join('\\x02')}`;\n if (key === this._memoKey) return this._memo;\n\n const groups = normalize(spec, n);\n const groupOf = new Array(n).fill(null);\n groups.forEach((g, gi) => { for (const c of g.columns) groupOf[c] = gi; });\n const empty = groups.map((g) => g.columns.length === 0);\n const placed = new Set();\n const slots = [];\n const placeEmptyBefore = (gi) => {\n for (let e = 0; e < gi; e++) {\n if (empty[e] && !placed.has(e)) { placed.add(e); slots.push({ placeholder: true, group: e }); }\n }\n };\n for (const c of shown) {\n const gi = groupOf[c];\n if (gi !== null) placeEmptyBefore(gi);\n slots.push({ col: c, group: gi });\n }\n placeEmptyBefore(groups.length);\n\n const slotOfCol = new Map();\n slots.forEach((s, i) => { if (!s.placeholder) slotOfCol.set(s.col, i); });\n const placeholders = slots.filter((s) => s.placeholder).length;\n this._memoKey = key;\n this._memo = { groups, slots, slotOfCol, placeholders };\n return this._memo;\n }\n\n /** How many placeholder columns are drawn. */\n placeholderCount() {\n return this.layout().placeholders;\n }\n\n /** A shown data column's place after the lead, or -1 when the layout\n * has no placeholder (the table's own arithmetic then holds). */\n slotOf(colIdx) {\n const l = this.layout();\n if (!l.placeholders) return -1;\n return l.slotOfCol.has(colIdx) ? l.slotOfCol.get(colIdx) : -1;\n }\n\n /** What the drawn column `i` after the lead is: the data column, null for\n * a placeholder or past the end, `undefined` when the layout has no\n * placeholder (the table's own arithmetic then holds). */\n slotAt(i) {\n const l = this.layout();\n if (!l.placeholders) return undefined;\n const s = l.slots[i];\n return s && !s.placeholder ? s.col : null;\n }\n\n /** Part of the table's column signature: where the placeholders stand. */\n sig() {\n const l = this.layout();\n if (!l.placeholders) return '';\n return `|g${l.slots.map((s, i) => (s.placeholder ? i : '')).filter((x) => x !== '').join(',')}`;\n }\n\n /** The drawn positions (after the lead) of the placeholders, ascending,\n * with their groups. */\n _placeholderSlots() {\n const out = [];\n this.layout().slots.forEach((s, i) => { if (s.placeholder) out.push({ at: i, group: s.group }); });\n return out;\n }\n\n /** Put the placeholders' cells into a drawn row whose cells are the lead\n * and the shown data columns, in order. */\n _insert(tr, make) {\n const lead = this.table._lead().all;\n for (const { at, group } of this._placeholderSlots()) {\n const ref = tr.children[lead + at] || null;\n tr.insertBefore(make(this.layout().groups[group]), ref);\n }\n }\n\n /** STORY-0066. A body row gets an empty cell under each placeholder. */\n fillRow(tr) {\n if (!this.placeholderCount()) return;\n this._insert(tr, () => {\n const td = document.createElement('td');\n td.className = 'twm-dt-cell--placeholder';\n return td;\n });\n }\n\n /**\n * After the header is built and in the header table: the placeholders'\n * header and filter cells, and the group table above the header table.\n */\n decorate(headerWrap, headerTable) {\n this._el = null;\n if (!headerWrap || !headerTable) return;\n const thead = headerTable.querySelector('thead');\n const labelRow = thead?.querySelector('tr');\n if (!labelRow) return;\n if (this.placeholderCount()) {\n this._insert(labelRow, (g) => this._placeholderHead(g));\n for (const tr of thead.querySelectorAll('tr.twm-data-table__filter-row')) {\n this._insert(tr, () => {\n const th = document.createElement('th');\n th.className = 'data-table__filter-cell data-table__filter-cell--empty twm-dt-col--placeholder';\n return th;\n });\n }\n }\n const groupTable = this._buildGroupTable(headerTable);\n headerWrap.insertBefore(groupTable, headerTable);\n this._el = groupTable;\n this.align();\n }\n\n _placeholderHead(group) {\n const th = document.createElement('th');\n th.className = 'text twm-dt-col--placeholder';\n if (typeof this._cfg().onColumnAdd === 'function') {\n th.appendChild(this._addButton(group));\n }\n return th;\n }\n\n _addButton(group) {\n return headerActionButton('twm-dt-group__add', { icon: 'add', title: `Add column to ${group.label}` },\n () => callOption(this._cfg(), 'onColumnAdd', group.key));\n }\n\n _buildGroupTable(headerTable) {\n const { groups, slots } = this.layout();\n const lead = this.table._lead().all;\n const table = document.createElement('table');\n table.className = `${headerTable.className} twm-dt-groups`;\n const colgroup = document.createElement('colgroup');\n for (let i = 0; i < lead + slots.length; i++) colgroup.appendChild(document.createElement('col'));\n table.appendChild(colgroup);\n const thead = document.createElement('thead');\n const tr = document.createElement('tr');\n tr.className = 'twm-dt-group-row';\n if (lead) {\n const th = document.createElement('th');\n th.className = 'twm-dt-group twm-dt-group--lead';\n th.colSpan = lead;\n tr.appendChild(th);\n }\n // Runs of the same group (or of no group) are one cell.\n let i = 0;\n while (i < slots.length) {\n const gi = slots[i].group;\n let j = i + 1;\n while (j < slots.length && slots[j].group === gi) j++;\n tr.appendChild(gi === null ? blankSpanCell(j - i) : this._groupCell(groups[gi], j - i, slots[i].placeholder));\n i = j;\n }\n thead.appendChild(tr);\n table.appendChild(thead);\n return table;\n }\n\n _groupCell(group, span, empty) {\n const th = labelSpanCell(span, group.label);\n if (empty) th.classList.add('twm-dt-group--empty');\n\n const actions = document.createElement('span');\n actions.className = 'twm-dt-group__actions';\n const cfg = this._cfg();\n // The consumer's group object from the live config: the layout is\n // memoised on key, label and columns, so a group whose other fields\n // changed is still asked about with its current object.\n const items = callOption(cfg, 'groupActions', cfg.columnGroups[group.index], { key: group.key, columns: group.columns.slice(), table: this.table });\n for (const item of Array.isArray(items) ? items.filter(Boolean) : []) {\n actions.appendChild(headerActionButton('twm-dt-group__action', item,\n () => callOption(cfg, 'onGroupAction', item.action, group.key)));\n }\n if (typeof cfg.onColumnAdd === 'function') actions.appendChild(this._addButton(group));\n if (actions.childNodes.length) th.appendChild(actions);\n return th;\n }\n\n /** The group table follows the header table: the same column widths,\n * table width, layout and sideways offset. */\n align() {\n const groupTable = this._el;\n const headerTable = this.table._headerTableEl;\n if (!groupTable || !headerTable) return;\n const labelRow = headerTable.querySelector('thead > tr');\n const cols = groupTable.querySelector('colgroup')?.children || [];\n for (let i = 0; i < cols.length; i++) {\n const th = labelRow?.children[i];\n const w = th ? parseFloat(th.style.width) : NaN;\n cols[i].style.width = Number.isFinite(w) ? `${w}px` : '';\n }\n groupTable.style.width = headerTable.style.width;\n groupTable.style.tableLayout = headerTable.style.tableLayout;\n groupTable.style.transform = headerTable.style.transform;\n }\n}\n", "/**\n * crosstab.js \u2014 STORY-0091. DataTable's CROSSTAB LAYOUT (`crosstab`).\n * INTERNAL to the table: imported by `data_table.js` only, and not part of the\n * widgets barrel \u2014 it reads the table's private fields.\n *\n * `crosstab: {labelColumns, headerRows, emptyLabel}` draws the table as a\n * matrix: k rows of spanned headers over the body columns, the leading\n * `labelColumns` drawn data columns as row labels, and the whole of it in ONE\n * `<table>` in ONE scroller. The consumer hands over every value and every\n * label \u2014 rows and columns that add others up, their words and their classes\n * (`rowClass`, `cellClass`, a header cell's `className`) are the consumer's;\n * this module only lays the cells out and pins them.\n *\n * \u2500\u2500 ONE TABLE, ONE SCROLLER \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 ordinary DataTable lifts its `<thead>` into a header table of its own\n * above the body's scroll box and copies the body's widths onto it. A header\n * of spans breaks that copy (every width pass reads the header CELL BY CELL at\n * the column's index), and two scrollers cannot pin a label column in both the\n * header and the body. So here the `<thead>` stays in the body table and\n * pinning is `position: sticky` against the body's scroll box (`_tableWrapEl`),\n * the only box that scrolls: the header rows to the top, the label columns\n * (with the row number and select columns in front of them) to the left, and\n * the corner \u2014 the header cells over the label columns \u2014 to both. No header\n * table is built, so no width pass, resize grip, header menu or group row of\n * the split layout runs.\n *\n * \u2500\u2500 OFFSETS ARE MEASURED, NOT ASSUMED \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 * A sticky header row needs its own `top`: the height of every header row\n * above it. A sticky label column needs its own `left`: the width of every\n * pinned column before it. Both are read after layout (`pin()`, on the frame\n * after a render) and again whenever a header row or a pinned header cell\n * changes size (a label that wraps, a font, a zoom) through a ResizeObserver.\n * They are read with `getBoundingClientRect`, which keeps the fraction\n * `offsetHeight` rounds away, and scaled back out of any CSS zoom, because\n * `style.top`/`style.left` are written in the unzoomed space inside it.\n *\n * \u2500\u2500 AN EMPTY AXIS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 * With no body column at all the table still draws: one column headed\n * `emptyLabel` ('(none)'), an empty cell under it in every row, and no spanned\n * header rows. It is no data column (`_dataIdxOfDom` answers null for it).\n *\n * A table without `crosstab` never builds this.\n */\n\nimport { createRafResizeObserver } from '../utils/raf_resize_observer.js';\nimport { normalizeSpans, blankSpanCell, labelSpanCell } from './column_groups.js';\n\nconst DEFAULT_EMPTY_LABEL = '(none)';\n\n/** The CSS zoom an element is drawn in, as the factor that takes a measured\n * (zoomed) length back to the space `style` lengths are written in. */\nfunction unzoom(el) {\n return 1 / (el?.currentCSSZoom || 1);\n}\n\nexport class Crosstab {\n /** @param {import('./data_table.js').DataTable} table */\n constructor(table) {\n this.table = table;\n /** The pinned columns' `left`, by drawn index, as last measured. */\n this._lefts = [];\n this._leafRow = null;\n }\n\n _spec() {\n const s = this.table.config.crosstab;\n return s && typeof s === 'object' ? s : {};\n }\n\n /** How many of the drawn data columns are row labels: the leading ones. */\n labelCount() {\n const k = Math.floor(Number(this._spec().labelColumns) || 0);\n return Math.max(0, Math.min(k, this.table._shownColumns().length));\n }\n\n /** The drawn columns that pin to the left: the select and row-number\n * columns, and the label columns. */\n pinnedCount() {\n return this.table._lead().all + this.labelCount();\n }\n\n /** The drawn data columns after the label columns, in order. */\n bodyColumns() {\n return this.table._shownColumns().slice(this.labelCount());\n }\n\n /** Columns drawn that are no data column: the empty axis's one. */\n extraColumns() {\n return this.bodyColumns().length ? 0 : 1;\n }\n\n /** The header rows as drawn: per row, `{cell, span}` runs over the body\n * columns (`cell` null for a run in no cell of that row). None for an\n * empty axis. */\n headerRuns() {\n const body = this.bodyColumns();\n if (!body.length) return [];\n const spec = this._spec().headerRows;\n const n = this.table.config.headers?.length || 0;\n return (Array.isArray(spec) ? spec : []).map((rowSpec) => {\n const cells = normalizeSpans(rowSpec, n);\n const cellOf = new Map();\n cells.forEach((c) => { for (const col of c.columns) cellOf.set(col, c); });\n const runs = [];\n for (const col of body) {\n const cell = cellOf.get(col) || null;\n const last = runs[runs.length - 1];\n if (last && last.cell === cell) last.span++;\n else runs.push({ cell, span: 1, rowSpec });\n }\n return runs;\n });\n }\n\n /** STORY-0091. A body row: its pinned cells marked and put at the measured\n * offsets (a row the virtual window draws later lines up at once), and\n * the empty axis's cell. */\n fillRow(tr) {\n if (this.extraColumns()) {\n const td = document.createElement('td');\n td.className = 'twm-dt-crosstab__none';\n tr.appendChild(td);\n }\n this._pinRowCells(tr);\n }\n\n _pinRowCells(tr) {\n const p = this.pinnedCount();\n for (let j = 0; j < p && j < tr.children.length; j++) {\n const cell = tr.children[j];\n cell.classList.add('twm-dt-pin');\n if (j === p - 1) cell.classList.add('twm-dt-pin--last');\n cell.__pinCol = j;\n if (this._lefts[j] != null) cell.style.left = `${this._lefts[j]}px`;\n }\n }\n\n /**\n * After `_createTable`: the header rows above the column headers, the\n * corner, the pinned header cells and the empty axis's header \u2014 all in the\n * body table's own `<thead>`.\n */\n decorate(tableEl) {\n this._leafRow = null;\n const thead = tableEl?.querySelector('thead');\n const leaf = thead?.querySelector('tr');\n if (!leaf) return;\n tableEl.classList.add('twm-dt-crosstab');\n this._leafRow = leaf;\n leaf.classList.add('twm-dt-crosstab__leaf');\n const filters = [...thead.querySelectorAll('tr.twm-data-table__filter-row')];\n if (this.extraColumns()) {\n const th = document.createElement('th');\n th.className = 'text twm-dt-crosstab__none';\n const label = this._spec().emptyLabel;\n th.textContent = label == null ? DEFAULT_EMPTY_LABEL : String(label);\n leaf.appendChild(th);\n for (const tr of filters) {\n const cell = document.createElement('th');\n cell.className = 'data-table__filter-cell data-table__filter-cell--empty twm-dt-crosstab__none';\n tr.appendChild(cell);\n }\n }\n for (const tr of [leaf, ...filters]) this._pinRowCells(tr);\n\n const levels = this.headerRuns();\n const p = this.pinnedCount();\n levels.forEach((runs, r) => {\n const tr = document.createElement('tr');\n tr.className = 'twm-dt-crosstab__band';\n // THE CORNER: one cell per pinned column, spanning every header\n // row down to the column headers, so each pins at its own `left`.\n if (r === 0) {\n for (let j = 0; j < p; j++) {\n const th = document.createElement('th');\n th.className = 'twm-dt-crosstab__corner twm-dt-pin';\n if (j === p - 1) th.classList.add('twm-dt-pin--last');\n th.rowSpan = levels.length;\n th.__pinCol = j;\n tr.appendChild(th);\n }\n }\n for (const run of runs) tr.appendChild(this._bandCell(run));\n thead.insertBefore(tr, leaf);\n });\n }\n\n /** A header row's cell: STORY-0066's spanning cells, the consumer's\n * `className` and `title` on a labelled one. */\n _bandCell({ cell, span, rowSpec }) {\n if (!cell) return blankSpanCell(span);\n const own = rowSpec[cell.index];\n const th = labelSpanCell(span, cell.label, own?.title == null ? cell.label : String(own.title));\n if (own?.className) this.table._addClasses(th, own.className);\n return th;\n }\n\n /**\n * Once the table is in the document: pin now (a layout already there is\n * used at once), on the next frame (when it has settled), and whenever a\n * header row, a pinned header cell or the table's box changes size. The\n * observer goes with the render (`_disposers`).\n *\n * The split layout's own resize observer and settle frame hang off its\n * header table, which a crosstab has none of; so the virtual window's\n * re-measure and resize (`_virtRemeasure`, `_virtUpdate`) run from here.\n */\n install() {\n const table = this.table;\n const tableEl = table._tableEl;\n if (!tableEl || !this._leafRow) return;\n this.pin();\n requestAnimationFrame(() => {\n if (table._tableEl !== tableEl) return;\n this.pin();\n table._virtRemeasure();\n });\n if (typeof ResizeObserver === 'undefined') return;\n const observer = createRafResizeObserver(() => {\n if (table._tableEl !== tableEl) return;\n this.pin();\n table._virtUpdate();\n });\n if (table._wrapperEl) observer.observe(table._wrapperEl);\n const thead = tableEl.querySelector('thead');\n for (const tr of thead.querySelectorAll('tr')) observer.observe(tr);\n for (let j = 0; j < this.pinnedCount(); j++) {\n const cell = this._leafRow.children[j];\n if (cell) observer.observe(cell);\n }\n table._disposers.push(() => {\n try { observer.disconnect(); } catch (_) { /* gone */ }\n });\n }\n\n /** Measure and write every offset: each header row's `top`, each pinned\n * column's `left`. */\n pin() {\n const tableEl = this.table._tableEl;\n const thead = tableEl?.querySelector('thead');\n if (!thead || !this._leafRow) return;\n const rows = [...thead.rows];\n const scale = unzoom(thead);\n const origin = rows[0].getBoundingClientRect().top;\n for (const tr of rows) {\n const top = Math.max(0, (tr.getBoundingClientRect().top - origin) * scale);\n const css = `${+top.toFixed(2)}px`;\n for (const th of tr.cells) th.style.top = css;\n }\n\n const p = this.pinnedCount();\n const lefts = [0];\n for (let j = 1; j < p; j++) {\n const cell = this._leafRow.children[j - 1];\n const w = cell ? cell.getBoundingClientRect().width * scale : 0;\n lefts[j] = +(lefts[j - 1] + w).toFixed(2);\n }\n this._lefts = p ? lefts : [];\n for (const cell of tableEl.querySelectorAll('.twm-dt-pin')) {\n const left = this._lefts[cell.__pinCol];\n if (left != null) cell.style.left = `${left}px`;\n }\n this._lockColumns(scale);\n }\n\n /**\n * Under `virtualize` the rows drawn change with every scroll, and with\n * them the widths an automatic layout gives the columns. The first pass\n * that sees a layout writes the widths it measured on the column headers\n * into the `<colgroup>` and fixes the layout, so the columns hold still.\n * No layout (every width 0) is no measurement, and nothing is written.\n */\n _lockColumns(scale) {\n const cols = this.table._cols();\n const tableEl = this.table._tableEl;\n if (!cols || !tableEl || tableEl.__crosstabLocked) return;\n const cells = this._leafRow.children;\n if (cells.length !== cols.length) return;\n const widths = [...cells].map((c) => c.getBoundingClientRect().width * scale);\n if (!widths.every((w) => w > 0)) return;\n widths.forEach((w, i) => { cols[i].style.width = `${+w.toFixed(2)}px`; });\n tableEl.style.tableLayout = 'fixed';\n tableEl.style.width = `${+widths.reduce((a, b) => a + b, 0).toFixed(2)}px`;\n tableEl.__crosstabLocked = true;\n }\n}\n", "/**\n * table_structure.js \u2014 STORY-0066. DataTable's STRUCTURAL EDITS: the\n * consumer's action buttons on the column headers (`columnActions`), renaming\n * a column in place (`onColumnRename`, through `attachInlineRenamer`), and the\n * menu items that add and delete columns and rows (`onColumnDelete`,\n * `onRowAdd`, `onRowDelete`). INTERNAL to the table: imported by\n * `data_table.js` only, and not part of the widgets barrel.\n *\n * THE CONSUMER OWNS THE DATA. Nothing here changes `headers` or `rows`: each\n * edit is a call, and the consumer answers it with `setData`. A rename shows\n * the new name in the header until then.\n *\n * Where the items go: the header's right-click menu (the STORY-0003\n * `headerMenu` path) gets \"Rename column\", \"Delete column\" and \"Add row\" after\n * the consumer's `headerMenu` items, and the body's right-click menu (the\n * STORY-0010 `contextMenuItems` path) \"Insert row below\" and \"Delete row\"\n * after the consumer's `contextMenuItems`. \"Add row\" is in the header's menu\n * so a table with no rows can still get its first.\n *\n * A table without any of these options never builds this.\n */\n\nimport { callOption, headerActionButton } from './header_actions.js';\nimport { attachInlineRenamer } from './inline_renamer.js';\n\n/** The options that build this module. */\nexport const STRUCTURE_OPTIONS = ['columnActions', 'onColumnRename', 'onColumnDelete', 'onRowAdd', 'onRowDelete'];\n\nexport class TableStructure {\n /** @param {import('./data_table.js').DataTable} table */\n constructor(table) {\n this.table = table;\n this._renamer = null;\n }\n\n _cfg() {\n return this.table.config;\n }\n\n _has(name) {\n return typeof this._cfg()[name] === 'function';\n }\n\n _call(name, ...args) {\n return callOption(this._cfg(), name, ...args);\n }\n\n /** Whether the header's right-click has items of this module's. */\n hasHeaderItems() {\n return this._has('onColumnRename') || this._has('onColumnDelete') || this._has('onRowAdd');\n }\n\n /** Whether a row's right-click has items of this module's. */\n hasRowItems() {\n return this._has('onRowAdd') || this._has('onRowDelete');\n }\n\n /** The header menu's items for the data column `colIdx` (null off one). */\n headerItems(colIdx) {\n const items = [];\n if (colIdx !== null && this._has('onColumnRename')) {\n items.push({ label: 'Rename column', icon: 'edit', onChoose: () => this.rename(colIdx) });\n }\n if (colIdx !== null && this._has('onColumnDelete')) {\n items.push({ label: 'Delete column', icon: 'delete', danger: true,\n onChoose: () => this._call('onColumnDelete', colIdx) });\n }\n if (this._has('onRowAdd')) {\n items.push({ label: 'Add row', icon: 'add', onChoose: () => this._call('onRowAdd', null) });\n }\n return items;\n }\n\n /** The body menu's items for the row `rowIdx` (its original index). */\n rowItems(rowIdx) {\n const items = [];\n if (this._has('onRowAdd')) {\n items.push({ label: 'Insert row below', icon: 'add', onChoose: () => this._call('onRowAdd', rowIdx) });\n }\n if (this._has('onRowDelete')) {\n items.push({ label: 'Delete row', icon: 'delete', danger: true,\n onChoose: () => this._call('onRowDelete', rowIdx) });\n }\n return items;\n }\n\n /**\n * After the header is built: each data column's label in a span the\n * renamer can take over, and the consumer's action buttons.\n */\n decorate(headerTable) {\n this._renamer?.destroy();\n this._renamer = null;\n const labelRow = headerTable?.querySelector('thead > tr');\n if (!labelRow) return;\n const headers = this._cfg().headers || [];\n const rename = this._has('onColumnRename');\n const actions = this._has('columnActions');\n if (!rename && !actions) return;\n for (let colIdx = 0; colIdx < headers.length; colIdx++) {\n const th = labelRow.children[this.table._domIdxOf(colIdx)];\n if (!th) continue;\n if (rename) this._wrapLabel(th, colIdx);\n if (actions) this._addActions(th, colIdx, headers[colIdx]);\n }\n }\n\n _wrapLabel(th, colIdx) {\n const text = [...th.childNodes].find((n) => n.nodeType === 3);\n if (!text) return;\n const label = document.createElement('span');\n label.className = 'twm-dt-col-label';\n th.insertBefore(label, text);\n label.appendChild(text);\n // The renamer's keys stay its own: no Escape or Enter it handles\n // reaches the table or the page. (On the label, not added per rename:\n // the renamer's Escape removes its input before the key bubbles here.)\n label.addEventListener('keydown', (ev) => ev.stopPropagation());\n // A double-click on the label renames \u2014 on a table whose header click\n // does not sort (there, the first click redraws the header).\n if (!this._cfg().sortable) {\n label.addEventListener('dblclick', (ev) => {\n ev.preventDefault();\n ev.stopPropagation();\n this.rename(colIdx);\n });\n }\n }\n\n _addActions(th, colIdx, header) {\n const items = this._call('columnActions', colIdx, { colIdx, header, table: this.table });\n const list = Array.isArray(items) ? items.filter(Boolean) : [];\n if (!list.length) return;\n const box = document.createElement('span');\n box.className = 'twm-dt-col-actions';\n for (const item of list) {\n box.appendChild(headerActionButton('twm-dt-col-action', item,\n () => this._call('onColumnAction', item.action, colIdx)));\n }\n th.appendChild(box);\n }\n\n /**\n * Open the renamer on the data column's header. Enter (or the focus\n * leaving) with a different, non-empty name calls\n * `onColumnRename(colIdx, name)`; Escape, or the name left as it was,\n * restores the header and calls nothing. Returns whether it opened.\n */\n rename(colIdx) {\n if (!this._has('onColumnRename')) return false;\n const labelRow = this.table._headerTableEl?.querySelector('thead > tr');\n const dom = this.table._domIdxOf(colIdx);\n const label = dom < 0 ? null : labelRow?.children[dom]?.querySelector('.twm-dt-col-label');\n if (!label) return false;\n this._renamer?.cancel();\n const before = label.textContent || '';\n const done = () => {\n if (this._renamer === renamer) this._renamer = null;\n };\n const renamer = attachInlineRenamer({\n label,\n inputClass: 'twm-dt-col-rename',\n onCommit: async (raw) => {\n const name = String(raw ?? '').trim();\n if (!name || name === before) return { success: false };\n const answer = await this._call('onColumnRename', colIdx, name);\n if (answer === false || (answer && answer.ok === false)) return { success: false };\n return { newValue: name };\n },\n onCancel: done,\n onFinish: done,\n });\n this._renamer = renamer;\n renamer.start();\n return true;\n }\n\n dispose() {\n this._renamer?.destroy();\n this._renamer = null;\n }\n}\n", "/**\n * data_table.js\n *\n * Unified, reusable data table component with support for:\n * - Pagination (first/prev/next/last/jump to row)\n * - Row selection (single, range with Shift, toggle with Ctrl/Cmd)\n * - Keyboard shortcuts (Ctrl+A, Ctrl+C, Shift+Ctrl+C outside cell mode, Esc)\n * - Context menu (copy as TSV/CSV)\n * - Column sorting (internal or external via callback)\n * - Column drag-to-resize, and double-click-to-auto-size on the same grip\n * - Column drag-to-reorder (`reorderable`, `columnOrder`; column_order.js)\n * - Per-column filtering (numeric operators, text substring)\n * - Column type detection (numeric/text alignment)\n * - Header icons\n * - Read-only mode\n * - CSV download through the host port (native save dialog), with a\n * Blob + <a download> fallback when no host is supplied\n *\n * Used by: DataPage, PlotPopoutWindow, StatisticsTable, Import Wizard\n */\n\nimport { createRafResizeObserver } from '../utils/raf_resize_observer.js';\nimport { placeMenuInViewport, moveMenuFocus, focusMenuItem } from '../utils/menu_viewport.js';\nimport {\n ISO_DATE, ISO_DATETIME, formatDate, formatDuration, matchDateFilter,\n matchDurationFilter, parseDateValue, parseDuration,\n} from './table_values.js';\nimport { isRowActivation, isRowControl } from './row_activation.js';\nimport { createChipsFilter } from './table_filter_chips.js';\nimport { CellGrid } from './cell_grid.js';\nimport { toTSV } from './tsv.js';\nimport { ColumnReorder, cellOrder, isColumnOrder, moveInOrder, naturalOrder } from './column_order.js';\nimport { ColumnGroups } from './column_groups.js';\nimport { Crosstab } from './crosstab.js';\nimport { STRUCTURE_OPTIONS, TableStructure } from './table_structure.js';\n\n// 0.7.0: the built-in chips filter control, for a consumer that wants to build\n// one outside a table (the same control `filterKinds: {kind: 'chips'}` draws).\nexport { createChipsFilter } from './table_filter_chips.js';\n\n// 0.5.0: the value helpers a typed column uses, and the one row-activation rule,\n// re-exported so a consumer reaches them where it reaches DataTable.\nexport {\n ISO_DATE, ISO_DATETIME, formatDate, formatDuration, parseDateValue,\n parseDatePeriod, parseDuration, matchDateFilter, matchDurationFilter,\n} from './table_values.js';\nexport {\n ROW_CONTROL_SELECTOR, endsTextSelection, isRowActivation, isRowControl,\n} from './row_activation.js';\n\nconst DEFAULT_PAGE_SIZE = 100;\n\n/** 0.6.1 \u2014 the row statuses `diff` draws. */\nconst DIFF_STATUSES = new Set(['added', 'removed', 'changed', 'same', 'gap']);\n\n// \u2500\u2500 `paging`: a server's rows, in pages or as one scrolling list \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// THE TWO LIMITS. A table that scrolls holds every row it has loaded, in one\n// array and (through `virtualize`) one scroll range, so how many rows it may\n// hold is a decision rather than an accident of how far somebody scrolled.\n// The SOFT limit is the consumer's (a person's preference, say): a source\n// with more rows than that is shown in pages, whatever was asked for. The HARD\n// limit is the ceiling no soft limit may exceed, and no scrolling table ever\n// holds more rows than it.\n\n/** The most rows a scrolling table holds, and the ceiling of every soft limit. */\nexport const PAGING_HARD_LIMIT = 100_000;\n/** The soft limit when the consumer names none. */\nexport const PAGING_SOFT_LIMIT = 10_000;\n\n/**\n * WHICH WAY A TABLE IS SHOWN \u2014 pure, so a consumer deciding how to FETCH and\n * the table deciding how to DRAW get the same answer from the same facts.\n *\n * Scroll is allowed only while the source is known to hold no more rows than\n * the soft limit. What is known is the exact `total` when there is one, and\n * otherwise the most the facts prove: a lower bound (`atLeast`, a capped\n * count) or the rows already held plus one when the source says it has more.\n * An unknown total therefore does not force pages until the rows themselves\n * prove the source is larger than the limit.\n *\n * @param {object} [o]\n * @param {'pages'|'scroll'} [o.mode='scroll'] what was asked for\n * @param {number|null} [o.total] the source's exact row count, if known\n * @param {number} [o.atLeast=0] a lower bound on it (a capped count)\n * @param {number} [o.held=0] rows the table holds now\n * @param {boolean} [o.hasMore=false] the source has rows past those held\n * @param {number} [o.softLimit=PAGING_SOFT_LIMIT]\n * @param {number} [o.hardLimit=PAGING_HARD_LIMIT]\n * @returns {{mode: 'pages'|'scroll', requested: 'pages'|'scroll', forced: boolean,\n * softLimit: number, hardLimit: number, known: number, exact: boolean}}\n */\nexport function resolvePaging({\n mode = 'scroll', total = null, atLeast = 0, held = 0, hasMore = false,\n softLimit = PAGING_SOFT_LIMIT, hardLimit = PAGING_HARD_LIMIT,\n} = {}) {\n const requested = mode === 'pages' ? 'pages' : 'scroll';\n const hard = Number.isFinite(hardLimit) && hardLimit >= 1\n ? Math.floor(hardLimit) : PAGING_HARD_LIMIT;\n // A soft limit above the hard one is the hard one: nothing the consumer\n // names can let a table hold more than the ceiling.\n const soft = Math.min(hard, Number.isFinite(softLimit) && softLimit >= 1\n ? Math.floor(softLimit) : PAGING_SOFT_LIMIT);\n const exact = Number.isFinite(total) && total >= 0;\n const known = exact ? total\n : Math.max(Number.isFinite(atLeast) ? atLeast : 0, (held || 0) + (hasMore ? 1 : 0));\n const forced = requested === 'scroll' && known > soft;\n return {\n mode: forced ? 'pages' : requested, requested, forced,\n softLimit: soft, hardLimit: hard, known, exact,\n };\n}\n\n/** How near the bottom (px) a scrolling table asks for its next rows. */\nconst PAGING_LOAD_MORE_PX = 400;\n\n/** 0.5.0 \u2014 the column types that sort and filter by a value rather than by\n * the text drawn for it. */\nconst TYPED_COLUMNS = new Set(['date', 'datetime', 'duration']);\n\n/** 0.5.0. The clicks with which a `selectable: 'single'` table took its row\n * back OFF the selection (Ctrl on the chosen row). `onRowActivate` does not\n * open a row on such a click. Marked on the EVENT, not read back from the\n * selection, because a selection callback that re-draws with new rows clears\n * the selection before the activation listener runs. */\nconst DESELECTING_CLICKS = new WeakSet();\n\n// \u2500\u2500 0.5.0 `autoDispose` \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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// ONE MutationObserver per document, shared by every table that asked, rather\n// than one per table: a page with forty lists would otherwise run forty\n// callbacks on every mutation anywhere in it. Each callback asks each table one\n// question (`isConnected`), and the observer disconnects itself when the last\n// table is gone.\n//\n// The tables are held WEAKLY. A table rendered into a host that never reaches\n// the page is never \"taken out\" of it, so it is never disposed \u2014 and a strong\n// set here would then keep it, its rows and its DOM alive for the life of the\n// page: the very leak the option exists to stop.\nconst AUTO_DISPOSE = new Map(); // Document -> { observer, tables: Set<{deref()}> }\nconst AUTO_REFS = new WeakMap(); // DataTable -> its entry in that set\nconst weakRef = (table) => (typeof WeakRef === 'function'\n ? new WeakRef(table) : { deref: () => table });\n\nfunction autoDisposeSweep(entry) {\n for (const ref of entry.tables) {\n const table = ref.deref();\n if (!table) { entry.tables.delete(ref); continue; }\n const el = table._wrapperEl;\n if (!el) continue;\n if (el.isConnected) {\n table._autoSeen = true;\n // 0.7.0. BACK IN: whatever grace was running for the last time it\n // went out is over. Without this, a table taken out, put back and\n // taken out again was judged by the FIRST departure's clock, and\n // disposed while it had been out for less than its grace.\n if (table._autoPending) {\n clearTimeout(table._autoTimer);\n table._autoTimer = null;\n table._autoPending = false;\n }\n continue;\n }\n if (!table._autoSeen || table._autoPending) continue;\n // 0.7.0 `keepWhileDetached: true`: out is not gone. Nothing is\n // scheduled; the table waits to be put back (or for `dispose()`).\n const grace = table._detachGrace();\n if (grace === Infinity) continue;\n // NOT AT ONCE. A renderer that takes a subtree out and puts it back in\n // the same task (FlexDesk's own tile renderer re-appends every leaf in\n // tree order) has put it back by the time this microtask runs \u2014 and one\n // that takes a turn longer still gets one task's grace (or, 0.7.0, the\n // `keepWhileDetached` grace). Only a table that is STILL out after that\n // has been removed from the page.\n table._autoPending = true;\n table._autoTimer = setTimeout(() => {\n table._autoPending = false;\n table._autoTimer = null;\n if (!entry.tables.has(ref)) return;\n const now = table._wrapperEl;\n // `_disposeOwn`, NOT `dispose()`: by now the host may hold\n // something else \u2014 the next list mounted into it, or the pane's\n // own message \u2014 and `dispose()` empties the host.\n if (now && !now.isConnected) table._disposeOwn();\n }, grace);\n }\n if (entry.tables.size === 0) autoDisposeRelease(entry);\n}\n\nfunction autoDisposeRelease(entry) {\n for (const [doc, e] of AUTO_DISPOSE) {\n if (e !== entry) continue;\n try { e.observer.disconnect(); } catch (_) { /* gone */ }\n AUTO_DISPOSE.delete(doc);\n }\n}\n\nfunction autoDisposeWatch(table) {\n const doc = table.container?.ownerDocument;\n const MO = doc?.defaultView?.MutationObserver || globalThis.MutationObserver;\n if (!doc || typeof MO !== 'function') return;\n let entry = AUTO_DISPOSE.get(doc);\n if (!entry) {\n entry = { observer: null, tables: new Set() };\n entry.observer = new MO(() => autoDisposeSweep(entry));\n entry.observer.observe(doc, { childList: true, subtree: true });\n AUTO_DISPOSE.set(doc, entry);\n }\n let ref = AUTO_REFS.get(table);\n if (!ref) { ref = weakRef(table); AUTO_REFS.set(table, ref); }\n entry.tables.add(ref);\n if (table._wrapperEl?.isConnected) table._autoSeen = true;\n}\n\nfunction autoDisposeUnwatch(table) {\n const ref = AUTO_REFS.get(table);\n if (!ref) return;\n for (const entry of [...AUTO_DISPOSE.values()]) {\n if (entry.tables.delete(ref) && entry.tables.size === 0) autoDisposeRelease(entry);\n }\n}\n\n/** A per-column option: one value for every column, or an array / object\n * keyed by column index. `null` and `undefined` mean \"not set\". */\nfunction perColumn(option, colIdx) {\n if (option == null) return null;\n if (Array.isArray(option)) return option[colIdx] ?? null;\n if (typeof option === 'object') return option[colIdx] ?? null;\n return option;\n}\n\n/** 0.7.0. Ids for the detail regions a row's toggle controls. */\nconst DETAIL_SEQ = { n: 0 };\n\n/** 0.7.0. How a filter control's value matches a cell when its control says\n * nothing (`match`): a list is \"one of these\", a `{from, to}` is a range\n * (inclusive; dates and numbers compared as such), text is \"contains\", and\n * anything else is equality as text. */\nfunction defaultControlMatch(cell, value) {\n if (Array.isArray(value)) return value.some((v) => String(v ?? '') === String(cell ?? ''));\n if (value && typeof value === 'object' && !(value instanceof Date)\n && ('from' in value || 'to' in value)) {\n const asNumber = (x) => {\n if (x == null || x === '') return null;\n if (x instanceof Date) return x.getTime();\n if (typeof x === 'number') return x;\n const t = parseDateValue(x);\n if (Number.isFinite(t)) return t;\n const n = parseFloat(x);\n return Number.isFinite(n) ? n : null;\n };\n const c = asNumber(cell);\n if (c === null) return false;\n const lo = asNumber(value.from);\n const hi = asNumber(value.to);\n if (lo !== null && c < lo) return false;\n if (hi !== null && c > hi) return false;\n return true;\n }\n if (typeof value === 'string') {\n return String(cell ?? '').toLowerCase().includes(value.toLowerCase());\n }\n return String(value) === String(cell ?? '');\n}\n\n/** 0.7.0. The chips' rule: the cell IS the chosen value (one of them, for\n * `multiple`). */\nfunction chipsMatch(spec) {\n return (cell, value) => {\n const want = Array.isArray(value) ? value : [value];\n return want.some((v) => String(v ?? '') === String(cell ?? ''));\n };\n}\n\n/** One sort key, comparable with `compareSortKeys`. */\nfunction normaliseSortKey(k) {\n if (k == null) return null;\n if (k instanceof Date) k = k.getTime();\n if (typeof k === 'boolean') return k ? 1 : 0;\n if (typeof k === 'number') return Number.isFinite(k) ? k : null;\n if (typeof k === 'bigint') return Number(k);\n return String(k).toLowerCase();\n}\n\n/** Nulls (and NaN) last in either direction \u2014 as the 0.4 comparator put them \u2014\n * numbers before text, numbers numerically, text as lower-cased text. */\nfunction compareSortKeys(a, b, asc) {\n if (a === null && b === null) return 0;\n if (a === null) return 1;\n if (b === null) return -1;\n const na = typeof a === 'number';\n const nb = typeof b === 'number';\n let cmp;\n if (na !== nb) cmp = na ? -1 : 1;\n else cmp = a < b ? -1 : a > b ? 1 : 0;\n return asc ? cmp : -cmp;\n}\n\n/** How wide auto-sizing a column is allowed to make it.\n *\n * 520px, which is `_fitColumnWidths`' FIRST_CAP \u2014 the most generous ceiling\n * this file already sanctions for a single column. Auto-size is an explicit\n * gesture asking to see a column's content, so it is not held to the tighter\n * 360px the automatic fit pass applies to the columns it is squeezing; but it\n * is held to SOMETHING, because one 4,000-character note in one cell would\n * otherwise produce a column nobody can scroll past. */\nconst AUTOSIZE_MAX_PX = 520;\n\n/**\n * Configuration options for DataTable\n * @typedef {Object} DataTableConfig\n * @property {string[]} headers - Column headers\n * @property {Array<Array>} rows - Row data (array of arrays)\n * @property {number} [pageSize=100] - Rows per page\n * @property {boolean} [pagination=true] - Enable pagination controls\n * @property {boolean|'single'} [selectable=true] - Enable row selection. 'single' (0.5.0): a click selects exactly one row, Shift and Ctrl do not extend it, Ctrl+A selects nothing, and `setSelection` keeps the last index it is given.\n * @property {boolean} [copyable=true] - Enable copy shortcuts and context menu\n * @property {boolean} [sortable=false] - Enable column sorting\n * @property {boolean} [filterable=false] - Enable per-column filter inputs\n * @property {boolean} [readonly=false] - Read-only mode (no selection/hover effects)\n * @property {boolean|'position'} [showRowNumbers=false] - Show row number column. `true` numbers a row by its ORIGINAL index (2, 3, 4, 1 after a sort); 'position' (0.5.0) numbers the rows as SHOWN \u2014 1, 2, 3 after a sort, a filter, or on any page.\n * @property {string} [emptyMessage='No data'] - Message when no data\n * @property {Function} [onSort] - Callback when sort changes: (column, ascending) => void\n * @property {boolean} [resetPageOnSort=false] - A client-paged table goes back to its first page on every `sortBy()` (a header click included), the way a new filter already does: on page 3, a new order otherwise draws rows 201\u2013300 OF THE NEW ORDER under \"Page 3 of 3\", which reads as \"it only sorted this page\". OFF by default: before this key existed a sort kept the page, and a table that does not ask keeps that. Server-side paging is untouched either way \u2014 its page is the consumer's `offset`, which `sortBy` never reads or writes.\n * @property {Function} [onSelectionChange] - Callback when selection changes: (selectedIndices) => void\n * @property {Function} [formatValue] - Custom value formatter: (value, colIndex) => string\n * @property {Function} [getHeaderIcon] - Get icon for header: (header, colIndex) => {icon, title}\n * @property {Function} [getColumnType] - Get column type: (colIndex, rows) => 'num'|'text'. What it returns is the cells' class name, and 'num' also sorts and filters as a number \u2014 exactly as in 0.4. A date, datetime or duration column is declared through `columnTypes` (0.5.0): returned from here, those names are class names only.\n * @property {Object} [services] - App services { eventBus, logger } for notifications\n * @property {number} [totalCount] - Total row count for server-side pagination (when rows only contains current page)\n * @property {number} [offset=0] - Current offset for server-side pagination\n * @property {Function} [onPageChange] - Callback for server-side pagination: (offset, limit) => void\n * @property {Function} [onJumpToRow] - Callback for jump to row: (rowIndex) => void\n * @property {Function} [renderCell] - Custom cell renderer: (td, value, colIdx, rowIdx, row) => boolean (return true if handled)\n * @property {'normal'|'compact'} [mode='normal'] - Rendering density. 'compact' adds `data-table-component--compact` to the wrapper (tighter padding + smaller font for the bottom-panel use case).\n * @property {Function} [onRowClick] - Row click handler: (rowIdx, row, ev) => void. Receives the original (unfiltered) row index.\n * @property {Function} [onRowContextMenu] - Row right-click handler: (rowIdx, row, ev) => void. Fires before the default context menu; call ev.preventDefault() to suppress the default.\n * @property {Function} [onCellContextMenu] - Cell right-click handler: (colIdx, rowIdx, value, td, ev) => void. Fires before onRowContextMenu; same suppression semantics.\n * @property {boolean} [showExportButton=false] - Adds a \"CSV\" download button to the pagination strip that invokes `downloadCSV()`. The strip is drawn for it even when the table fits on one page (0.14.1).\n * @property {string|function(DataTable): string} [exportFilename='data.csv'] - The file the export button saves (0.14.1); in a desktop host, the name the Save dialog suggests.\n * @property {Object} [host] - A Host (see ui/js/host/host.js). Its `dialogs` capability backs `downloadCSV()`'s native save dialog; without it CSV export falls back to a Blob download.\n * @property {Object} [stateStore] - `{ ready(), get(key), set(key, state) }` \u2014 REQUIRED when `persistKey` is set. Built by `createTableStateStore()`.\n * @property {'container'|'content'} [columnFit='container'] - How the automatic fit pass sizes a column the user has NOT dragged. 'container' squeezes every column into the wrap: a 360px cap, a more generous one for the first column, and water-fill-shrink toward the 40px floor when they do not fit. 'content' sizes each column to its own content through the same `_autoWidth` a grip double-click uses (520px cap) and lets the body scroll sideways rather than squeezing. A pinned column is honoured verbatim under both.\n * @property {boolean|{overscan?: number, rowHeight?: number}} [virtualize=false] - C10. Draw only the rows near the viewport, between a top and a bottom spacer row, and give the body table a `<colgroup>` so its column widths no longer come from whichever row happens to be first. OFF by default: nothing about a table that does not ask changes. `overscan` (rows drawn beyond each edge, default 20) and `rowHeight` (the estimate used until a real row has been measured, default 24) tune it. See `_virtUpdate` for the whole contract.\n * @property {Function} [virtualRowHeight] - `(rowIndex, baseHeight) => number`. Under `virtualize`, the height a row occupies, including anything the embedder injects in front of it (a group header) \u2014 and 0 for a row the embedder hides, which is then not drawn at all. Absent: every row is `baseHeight`, which is measured from a real row.\n * @property {Function} [onRowsRendered] - `({ rows, removed }) => void`. Under `virtualize`, called whenever the window changes after `render()` returned: `rows` are the `<tr>`s the virtualiser ADDED \u2014 the rows an embedder that decorates rows after a render would otherwise never see \u2014 and `removed` the ones it took OUT, already detached (an embedder that injected rows of its own beside them, or holds an editor in one, has to hear that they went). The rows present when `render()` returns are not reported: they are the render's, exactly as without `virtualize`.\n *\n * \u2500\u2500 0.5.0, every one of them off unless asked for \u2500\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 * @property {boolean} [fitContent=false] - The table is as tall as its rows: the wrapper is `height:auto` instead of `height:100%`, and the body grows with its rows instead of filling the box. For a list in a flowing page, whose parent has no height \u2014 where the default draws a header and NO rows.\n * @property {number|string} [maxHeight] - Implies `fitContent`, and caps the whole table at this height (a number is px); past it the body scrolls under its header.\n * @property {boolean} [autoDispose=false] - Dispose by itself once the table has been taken out of the document (and is still out a task later). Unlike `dispose()`, it removes only the table's own elements and never empties the host, which by then may hold the next list or the pane's own message. Do NOT set it on a table you take out and put back later \u2014 a cached tab \u2014 since a disposed table comes back empty.\n * @property {'time'|'plain'} [firstColumn='time'] - 'plain' draws the first column like every other column: no 120\u2013150px pin, no grey, no weight. The default keeps the time-series styling the component was built around.\n * @property {boolean} [clickable] - Draw body rows as things to press (`twm-dt--clickable`: a pointer and a hover, readonly tables included). Defaults to on exactly when `onRowActivate` is set.\n * @property {Function} [onRowActivate] - `(rowIdx, row, ev) => void`. The row OPENS. Fired after the selection has been updated, on the gestures `activateOn` names, and never on a press on a control inside the row, a click that ends a text selection in the table, the second click of a double-click, or (`selectable: 'single'`) the Ctrl click that took the row off the selection. `ev.type` says which gesture ('click', 'dblclick' or 'keydown'). `rowIdx` is the original index, as for `onRowClick`. A press whose `onSelectionChange` or `onRowClick` re-draws the table still opens the row pressed; `row` is that row as it was drawn.\n * @property {'click'|'dblclick'|'enter'|Array<'click'|'dblclick'|'enter'>} [activateOn='click'] - Which gestures open a row. A list of things to open: 'click'. A pick list, where one click selects: ['dblclick', 'enter']. Enter opens the selected row (the one row selected, or the selection's anchor) \u2014 the row a double-click on it would open; with nothing selected, the active row (`activeRow`).\n * @property {Function} [getRowKey] - `(row, rowIdx) => key`. A row's identity, which `activeRow` is matched by. Compared as text.\n * @property {*} [activeRow] - The key of the row that is OPEN (the master of a master-detail): drawn `twm-dt-row--active` with `aria-current=\"true\"`. It survives `setData`, a sort, a filter and a page, and a right-click does not move it. Without `getRowKey` the key is the row's original index. See `setActiveRow`.\n * @property {Function} [rowClass] - `(row, rowIdx) => string|string[]|null`. Classes for the row's `<tr>`.\n * @property {Function} [rowAttrs] - `(row, rowIdx) => {name: value}`. Attributes for the row's `<tr>` (`null`/`false` leaves one off, `true` sets it empty).\n * @property {Function} [cellClass] - `(value, colIdx, row, rowIdx) => string|string[]|null`. Classes for a cell, after its type class.\n * @property {Function} [diff] - 0.6.1. `(row, rowIdx) => {status, cells?}|null`. One side of a COMPARISON: `status` is 'added', 'removed', 'changed', 'same' or 'gap' and draws the row `twm-dt-diff twm-dt-diff--<status>`; `cells` (an array or Set of column indices) marks the cells that differ `twm-dt-diff__cell--changed`. A 'gap' row is the place a row holds on the OTHER side: its cells are drawn empty, whatever its values and `renderCell`, so two tables drawn from one aligned row list keep their rows level. `null` (or an unknown status) draws the row as without `diff`.\n * @property {object} [scrollLock] - 0.6.1. A group from `createScrollLock()`: the table's body box joins it on every render and leaves it on the next render and on dispose, so tables in the same group scroll as one.\n * @property {Function} [rowIcon] - `(row, rowIdx) => string|{icon, title?, tone?}|null`. A Material Symbols icon at the start of the row's first cell; `tone` adds `twm-dt-row-icon--<tone>`. Drawn by CSS, so it is in neither the cell's text, its tooltip nor a copy.\n * @property {string|Node|Function} [emptyState] - What the box says when there are no rows: text, a node, or a function returning either (called on each render). Replaces `emptyMessage`, and is hidden while `setLoading(true)` \u2014 an empty table that is still loading is not empty.\n * @property {string} [nullDisplay] - Draw `null`/`undefined` as this text (and copy it so), with `twm-dt-cell--null` on the cell, instead of '-'.\n * @property {Array<string|null>} [columnTypes] - Each column's type by position ('num', 'text', 'date', 'datetime', 'duration'); `null` leaves a column to `getColumnType` and detection. Only a type declared HERE makes a column a date, datetime or duration column \u2014 drawn, sorted and filtered by its value; `setData({columnTypes})` applies a new list at once.\n * @property {Function|Object|Array} [sortValue] - `(value, colIdx, row) => comparable` \u2014 what a column sorts by, for every column or (as an object or array keyed by column index) for some. `undefined` falls back to the column's own rule. A `Date` sorts by its time, numbers numerically, text as lower-cased text, `null` last.\n * @property {string|Function|Object|Array} [dateFormat='YYYY-MM-DD'] - How a 'date' column is drawn: a pattern (see `formatDate`) or `(date) => string`, for every date column or per column index.\n * @property {string|Function|Object|Array} [dateTimeFormat='YYYY-MM-DD HH:mm'] - The same for a 'datetime' column.\n * @property {'auto'|'clock'|Function|Object|Array} [durationFormat='auto'] - How a 'duration' column (milliseconds) is drawn: '850 ms', '3.2 s', '2m 5s' (auto) or '0:02:05' (clock).\n * @property {'local'|'UTC'} [dateTimeZone='local'] - The zone typed date columns are read and drawn in.\n *\n * \u2500\u2500 `paging`, off unless asked for \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 * @property {Object} [paging] - A server's rows shown IN PAGES or as ONE SCROLLING LIST, and a strip under the body that says which and lets the reader change it. The consumer holds the rows and fetches them; the table decides which way they are shown (`resolvePaging`), asks for more, and draws the strip. Set it and the old pager (`pagination`) is not drawn. Its keys:\n * `mode` ('pages'|'scroll', default 'scroll') \u2014 what was asked for. Scroll is refused, and pages shown, while the source holds more than `softLimit` rows.\n * `pageSize` \u2014 rows per page, and per load while scrolling (default `pageSize`).\n * `softLimit` (default 10,000) and `hardLimit` (default 100,000) \u2014 see `resolvePaging`; the soft one is clamped to the hard one, and a scrolling table never asks for rows past the hard one.\n * `total` \u2014 the source's exact row count, or null. `atLeast` \u2014 a lower bound when the exact count is not known (a capped count). `hasMore` \u2014 the source has rows past those held.\n * `offset` \u2014 in pages, where the first row held stands in the source: the strip's \"Rows 1,001\u20132,000\" and `showRowNumbers: 'position'` read it. The rows' indexes (`__rowIndex`, selection, `onRowClick`) stay those of `rows`.\n * `onPage(offset, limit)` \u2014 pages: show the page at `offset`. `onLoadMore()` \u2014 scroll: called when the body is scrolled within 400px of its end (`loadMorePx`), or does not fill its box, while `hasMore`. `onLoadAll()` \u2014 scroll: the strip's *Load all rows* button. `onModeChange(mode)` \u2014 the strip's Pages / Scroll switch; without it there is no switch. Each may return a Promise; until it settles no second call is made and its button shows the table is busy.\n * 0.7.0: WITH `dataSource` the table fetches, and is its own `paging` consumer \u2014 `offset`, `total`, `atLeast`, `hasMore` and `held` are read from the source's answers, `onPage`/`onLoadMore`/`onLoadAll` are the table's own questions (`reason` 'page', 'more', 'all'; more rows are drawn under those held), and `onModeChange` is told after the table has switched and asked again (`reason` 'mode'). The 0.7.0 pager is not drawn; `pagerLabels` and `maxJumpOffset` apply to the strip.\n *\n * \u2500\u2500 0.7.0, every one of them off unless asked for \u2500\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 * @property {Function} [rowDetail] - `(row, rowIdx, {host, key, table}) => Node|string|null|void`. A row's DETAIL, folded open under it: each row (or each row `hasRowDetail` admits) gets a toggle at the start of its first cell, and opening it draws a full-width row under the row \u2014 the function fills `host` or returns what to put in it. It is drawn when opened and dropped when closed. Keyboard: the toggle is a button (Enter/Space), and on the focused table ArrowRight opens and ArrowLeft closes the current row's detail. Which rows are open is kept by KEY (`getRowKey`, else the row's index), so it survives a sort, a filter, a page and a `setData`; under `virtualize` an open detail is part of its row's height.\n * @property {Function} [hasRowDetail] - `(row, rowIdx) => boolean`. Whether a row has a detail at all; a row without one gets no toggle. Absent: every row has one.\n * @property {Array} [expandedRows] - The keys of the rows open at first.\n * @property {Function} [onRowDetailToggle] - `(rowIdx, row, expanded, key) => void`, after a detail opened or closed by a gesture or by `setRowExpanded`.\n * @property {string} [rowDetailLabel='Details'] - The toggle's accessible name (its state is `aria-expanded`).\n * @property {Function} [dataSource] - `(query, {signal}) => Promise<{rows, total?, hasMore?, filterCounts?} | rows>`. ROWS FROM A SERVER. The table asks for a page whenever its sort, its column filters or its page change (and on `reload()`/`refresh()`), and draws the answer AS GIVEN \u2014 no client sort, filter or slice. `query` is `{offset, limit, sort: {column, header, ascending}|null, filters: [{column, header, value}], reason}`. With `paging` the rows may be shown as one scrolling list as well as in pages \u2014 see `paging`. Only the NEWEST request paints: an older answer arriving later is dropped, and its `signal` is aborted. A failure keeps the rows on screen under `setError`'s banner. `total` is the count under these filters \u2014 a number, or null when it is not known (see `hasMore`). `rowIdx` everywhere is the row's index in the page drawn.\n * @property {Function} [onLoad] - `(result, query) => void`, after the newest answer has been drawn.\n * @property {Function} [onLoadError] - `(error, query) => void`, when the newest request failed (an aborted one is not a failure).\n * @property {boolean} [hasMore] - Server-side paging (`onPageChange`) with NO total: with `totalCount` null and this a boolean, the pager offers Next exactly while it is true and has no last page. Under `dataSource` the answer's `hasMore` (or, absent, a full page) says it.\n * @property {Object} [pagerLabels] - The pager's words: `{first, prev, next, last, noLast, tooDeep}`. The four buttons are drawn with their word beside the icon, never narrower than it (`{first: 'Newest', prev: 'Newer', next: 'Older', last: 'Oldest'}` for a log read newest first); `noLast` is the refusal on Last when the total is unknown, `tooDeep` (`(max) => string`) the one past `maxJumpOffset`.\n * @property {'top'|'bottom'} [pagerPosition='top'] - Where the pager strip sits.\n * @property {number} [maxJumpOffset] - The deepest offset Last and Go-to-row will jump to. Past it the control is REFUSED, disabled with the reason on it (`data-refusal`), rather than slow.\n * @property {boolean|{interval?: number}} [follow=false] - Under `dataSource`: re-read the first page every `interval` ms (default 10000) while the table is on it and in the page, keeping the scroll position, the selection and the active row; rows not there before are drawn `twm-dt-row--new`. A tick waits while text in the table is selected or the focus is inside an open detail. Paging away turns following OFF (`onFollowChange(false)`); coming back does not turn it on again. See `setFollow`, `refresh`.\n * @property {Function} [onFollowChange] - `(following) => void`.\n * @property {boolean|number} [keepWhileDetached=false] - With `autoDispose`: how long a table taken out of the page may stay out and still come back drawn. A number is a grace in ms; `true` keeps it for as long as it is out (it is disposed only by `dispose()`, and what it holds meanwhile is its own DOM \u2014 nothing on the document, and a follow timer that holds it weakly). A table put back within its grace is not disposed, however many tasks it was out.\n * @property {Object|Array|Function} [filterKinds] - FILTER CONTROLS THAT ARE NOT TEXT BOXES, per column (an object or array keyed by column index, or `(colIdx, header) => spec`). A spec is `'text'` (the 0.4 box), `{kind: 'chips', options: [{value, label, icon?, title?}], multiple?}` (one-of-N chips with counts \u2014 an option whose value is `''` or null means \"no filter\"), or `{create(ctx)}` / a function `create(ctx)` for the consumer's own control (a date range, a person): `ctx` is `{column, header, value, counts, setValue(v), table}`, and it returns `{el, setValue?(v), setCounts?(c), destroy?(), match?(cellValue, filterValue, row)}`. A filter's value may then be anything (an array, an object): `query.filters` forwards it as it is, and on the client the control's `match` decides (chips: equality, or membership for `multiple`). The control is built once and kept across renders, and is in the column-width measure: a column is never narrower than its control at its narrowest (the widest chip), and the cell wraps the rest.\n * @property {Function} [onFilterChange] - `(filters) => void` with `[{column, header, value}]`, whenever a column filter changes.\n *\n * \u2500\u2500 STORY-0010, every one of them off unless asked for \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * @property {Array|Function} [contextMenuItems] - The consumer's own items in the table's right-click menu: an array, or `(row, rowIdx, ctx) => items`, asked on every right-click of a body row so the items can follow the row and the live selection. An item is `{label, icon?, action, disabled?, danger?, title?}` or `{separator: true}`, drawn as the copy items are (`disabled` greys it, `danger` is `twm-delete-node`). `ctx` is `{rowIdx, row, colIdx, value, selection, selectedRows}`: the right-clicked row (already selected by then), the right-clicked cell (`colIdx` null off a data column, the row-number gutter included), and the selection's original indices with their rows, 1:1. The items come first; with `copyable` the copy items follow behind a separator. Set, it installs the menu without `copyable` too.\n * @property {Function} [onContextMenuAction] - `(action, rowIdx, row, ctx) => void`, when one of `contextMenuItems` is chosen; the menu is hidden first. The copy items never come here.\n * @property {Function} [onRender] - `(table) => void`, at the end of every `render()` \u2014 for a consumer that shows something the rows decide (a count) outside the table. See `getDisplayedRows`.\n * @property {boolean} [keyboardNav=false] - On the focused table, ArrowUp/ArrowDown move the selection one row through the rows of the page shown (in the order shown), Home/End to its first and last, and with Shift (a table that selects several rows) select the range from the anchor, as Shift-click does. The row moved to is scrolled into view (`scrollToRow`) and `onSelectionChange` is told. Needs `selectable`. Not on a key pressed in a control inside the table, nor with Ctrl, Cmd or Alt.\n * @property {Function} [onRowKeyDown] - `(rowIdx, row, ev) => boolean|void`, for every key pressed on the focused table (not in a control inside it) BEFORE the table's own keys: `rowIdx`/`row` are the row Enter would open (the one row selected, the selection's anchor, else the active row \u2014 see `activateOn`), or null when none is drawn. Return `true` and the key is the consumer's: the table does nothing more with it (default prevented, propagation stopped \u2014 the page's keymap does not see it either). For the keys `activateOn` does not take: Ctrl+Enter, Alt+T, a \"delete this row\".\n * @property {number[]} [hiddenColumns] - STORY-0012. Columns (data indices) NOT DRAWN: no header, no filter box, no cell, no width in the fit, not in a copy or the CSV. They stay in the row data \u2014 `renderCell`, `contextMenuItems`' `ctx.row`, sorting and filtering (`sortBy`, `setFilter`) all still see them. A column sorted on while hidden keeps the order and has no arrow to show it. The last column shown cannot be hidden. With `persistKey` the set shown is saved, and a saved set wins over this one. `setData({hiddenColumns})` applies a new set.\n * @property {boolean} [columnChooser=false] - STORY-0012. A right-click on the header lists every column with a check mark on those shown; choosing one shows or hides it (`setColumnVisible`).\n * @property {boolean} [selectToggle=false] - STORY-0016. The table offers a SELECT MODE: a narrow leading column whose header holds a toggle button. While the mode is on, every row shows a checkbox there and the header a select-all box; a plain click (or Space) ticks or unticks one row, Shift-click adds the range from the last row ticked, and no gesture opens a row (`onRowActivate` is not called; `onRowClick` still is \u2014 a consumer that opens rows from it asks `isSelectMode()`). The arrows move a cursor without changing what is ticked. A right-click keeps the ticks. Escape clears the ticks, then leaves the mode. Needs a multi-row `selectable` (ignored, with a warning, on `false` or 'single'). The column is not resizable, is no data column (not in a copy, a CSV, `ctx.colIdx` or `hiddenColumns`), and remembered widths stay on their columns.\n * @property {boolean} [selectMode=false] - STORY-0016. Start in select mode. Draws the select column even without `selectToggle` (then there is no toggle: the consumer turns the mode off with `setSelectMode(false)`).\n * @property {Function} [onSelectModeChange] - STORY-0016. `(on) => void`, after every change of the mode (the toggle, Escape, `setSelectMode`).\n * @property {Function} [onColumnsChange] - STORY-0012. `(hidden, {hidden, order}) => void` with the hidden columns' indices, ascending, after every change of the set (the chooser, `setColumnVisible`, `setData({hiddenColumns})`) \u2014 and (STORY-0086) of the order (a drag, `moveColumn`, `setData({columnOrder})`); `order` is `getColumnOrder()`.\n * @property {boolean} [reorderable=false] - STORY-0086. Data columns can be dragged into a new order by their headers (a press on a resize grip resizes instead), and the header's right-click offers Move left / Move right. The row-number and select columns stay first: they do not move and nothing is dropped in front of them. The order is kept by data index, so `hiddenColumns`, the sort and the filters stay on their columns; copies and the CSV follow the order shown. With `persistKey` it is saved, and a saved order wins over `columnOrder` \u2014 unless it is no order of today's columns (another column count), when it is ignored and `columnOrder` is drawn, or the natural order when there is none. The same holds when the saved order arrives before the headers do.\n * @property {number[]} [columnOrder] - STORY-0086. Every data index, in the order to draw them (`[0, 3, 1, 2]`). Not a permutation of the columns: ignored with a console warning, natural order (with no headers yet, checked and warned once when `setData` brings them). Works without `reorderable` (then only code moves columns). See `moveColumn`, `getColumnOrder`.\n * @property {boolean} [persistPage=false] - With `persistKey`: the client page is saved with the sort and the filters, and opened again on mount (on the last page, if the rows have shrunk since). OFF by default: a key shared by DIFFERENT row sets (ad-hoc filters, search results) must not reopen on a page of the last list. A sort under `resetPageOnSort` and a new filter save the first page, as they show it. A server's page (`onPageChange`, `dataSource`) is the consumer's and is not kept.\n *\n * \u2500\u2500 STORY-0003, every one of them off unless asked for \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * @property {'rows'|'cells'} [selectionMode='rows'] - 'cells': CELL MODE (cell_grid.js, over cell_selection.js). A click selects one cell and puts the CURSOR on it, Shift+click selects the range from the anchor to it; every cell of the range is drawn `twm-dt-cell--selected` and the cursor `twm-dt-cell--cursor` (rows are not lit). On the focused table the arrows move the cursor (Shift extends), Ctrl+arrow jumps to the edge of the block of filled cells, Home/End go to the row's ends (Ctrl: the page's corners), Tab moves right and wraps to the next row (Shift+Tab back), Ctrl+A selects every cell of the page and Escape collapses the range onto the cursor. The cursor stays on the page drawn and is scrolled into view (under `virtualize` its row is drawn). `getSelection()` still answers ROWS \u2014 the original indices the range touches \u2014 and Ctrl+C copies those rows as before. A cell is `{row, col}`: `row` the position in the order shown (`getDisplayedRows()`), `col` the data column. Fixed for the table's life; `selectToggle`, `selectMode` and `keyboardNav` beside it are ignored with a console warning. See `getCellSelection`, `setCellSelection`.\n * @property {boolean|number[]|Function} [editable=false] - Cell mode only (a warning, and ignored, without it). Which cells open an EDITOR: `true` every one, an array of data column indices, or `(colIdx, row, rowIdx) => boolean`. F2, Enter, a double-click or a printable key (which the editor starts with) opens it on the cursor cell; in it Enter commits and moves down, Tab commits and moves right, Escape restores the cell and calls nothing, and the focus leaving commits. While it is open a `render()` (a `setData` included) waits, and runs when it closes; its row leaving the virtual window commits it. An editor with no `getValue` (a factory's `{el}` around an element that is not an input, select or textarea) has no value to commit: Enter and Tab do nothing, the focus leaving does nothing, and its row leaving the window CANCELS it \u2014 it calls `commit(value)` itself.\n * @property {Object} [editors] - `{[colIdx|type]: factory}`, the editor for a column (by index first, then by its type: `editTypes`', else `columnTypes`', else the detected 'num'/'text' \u2014 as named, then as the built-in editors name it, 'num' being 'number' and 'date' 'datetime'). A factory is `({value, row, rowIdx, colIdx, column: {index, header, type, ...editTypes' entry}, locale, utc, messages, initialText, commit(value, move?), cancel()}) => Element | {el, getValue?, parse?, multiline?, focus?, destroy?}`; an input, select or textarea returned as it is commits its `value`. Absent: the built-in editor for the column's type (cell_editors.js `CELL_EDITORS`: text, multitext, number, bool, choice, datetime), else a text box (cell_editor_host.js `createTextEditor`). Every editor commits the value unchanged when left as it was. An injected editor replaces the built-in one for its type (or column) only.\n * @property {Array|Object} [editTypes] - STORY-0087. Each column's EDITOR type, by position (array) or by data column index (object): a name ('text', 'multitext', 'number', 'bool', 'choice', 'datetime', or any name `editors` is keyed by) or `{type, options?, allowOther?, rows?}`. Unset, a column's editor type is its `columnTypes` type, else the detected one. 'choice' offers `options` (values, or `{value, label}`) through an AutocompleteField and refuses other text unless `allowOther`; 'multitext' is a text area of `rows` lines (3). Only editing reads it: drawing, sorting and filtering are as without it.\n * @property {string} [locale] - STORY-0087. The locale the built-in number and datetime editors read and show their text in (Intl's; unset: the runtime's): '1.234,56' is 1234.56 under 'de-DE', '1,234.56' under 'en-US'; '31/12/2026' is a date under 'en-GB'. A datetime also takes ISO 8601 in any locale.\n * @property {Object} [editorMessages] - STORY-0087. Words for the built-in editors' refusals, over `EDITOR_MESSAGES`: `{number, datetime, bool, choice}`.\n * @property {Function} [onCellCommit] - `({rowIdx, colIdx, value, previous}) => void | {ok, error?} | Promise<\u2026>`, once per commit (not for a value left as the cell showed it; `previous` is the value the row holds). Resolving `{ok: false, error}`, rejecting or throwing leaves the typed value in the cell drawn `twm-dt-cell--error` with the message as its `title` and `data-error`; until it settles the cell is `twm-dt-cell--pending`. Otherwise the value is written into the row the table holds for `rowIdx` when it settles (`rows[rowIdx][colIdx]`) and drawn. Committing a refused cell back to the row's value clears the mark without a call. New rows (`setData({rows})`) drop the marks.\n * @property {Function} [onCellSelectionChange] - `(getCellSelection()) => void`, after every change of the cells selected.\n * @property {Function} [headerMenu] - `(colIdx, {colIdx, header, hiddenColumns, table}) => items`, asked on a right-click on a data column's header (or its filter cell). The items (`{label, action, icon?, disabled?, danger?, title?}` or `{separator: true}`) open the table's menu; with `columnChooser` the chooser's items follow behind a separator. `[]` or `null` shows what would show without the hook: the chooser, or the page's own menu.\n * @property {Function} [onHeaderMenuAction] - `(action, colIdx) => void`, when one of `headerMenu`'s items is chosen; the menu is hidden first.\n *\n * \u2500\u2500 STORY-0088, off unless asked for \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 * @property {boolean} [staged=false] - With `editable` (a warning, and ignored, without it): an editor's commit is STAGED instead of sent to `onCellCommit` (staged_edits.js). A staged cell shows its value drawn `twm-dt-cell--staged`; staging the value its row holds is no change. On the focused table Ctrl+Z takes the last staged edit back and Ctrl+Y (or Ctrl+Shift+Z) puts it back \u2014 a cell staged as `null` undoes to no change, not to a staged null. `commit()` sends every staged cell to `onCommit` at once; `discard()` drops them. While any cell is staged the sort, the filters and the pages are FROZEN: their controls are disabled with the reason on them (`data-refusal`, `title`), and `sortBy`, `setFilter`, `clearFilters`, `goToPage`, `goToRow` and the paging calls refuse with a console warning. New rows (`setData({rows})`) drop the staged cells and the ring.\n * @property {number} [historyLimit=100] - With `staged`: the undo ring keeps this many entries \u2014 the limit counts entries, not cells; an entry is one cell's before/after change or one fill (a group of cell changes, undone together); the oldest fall off.\n * @property {Function} [onCommit] - With `staged`: `({edits}) => void | {ok?, error?, errors?} | Promise<\u2026>`, called once by `commit()` with every staged cell as `{rowIdx, colIdx, value, previous}` (by row, then column; `previous` is the value the row holds). Resolving `{errors: [{rowIdx, colIdx, error}]}` (non-empty) marks each of those cells `twm-dt-cell--error` with the message as its `title` and `data-error`, and every staged value stays; `{ok: false, error}`, a rejection or a throw marks every staged cell with the message. Anything else is success: the values are written into the rows the table holds, and the staged cells and the ring are cleared. While it is out no editor opens and Ctrl+Z, Ctrl+Y and `discard()` do nothing.\n * @property {Function} [onStagedChange] - With `staged`: `({count, canUndo, canRedo, committing}) => void` after every change of the staged cells.\n * @property {boolean} [fillHandle=false] - STORY-0089. With `staged` (a warning, and ignored, without it): a FILL HANDLE (fill_handle.js) on the bottom-right corner of the cell range (`.twm-dt-fill-handle`, in the corner cell). Dragging it up, down, left or right over the cells beyond the range previews them `twm-dt-cell--fill-preview` and, on release, stages their values as ONE undo entry: each column of the range (each row, filling sideways) is continued by `projectSeries` (series.js) \u2014 one cell repeats, numbers, dates and \"Item 1\"-style texts a constant step apart continue, anything else repeats in a cycle \u2014 and Ctrl (Cmd) held at release repeats the block instead. A target cell `editable` refuses is skipped and drawn `twm-dt-cell--fill-skipped` until the selection moves. The range then covers what was filled. Escape during the drag cancels it. See `fill`.\n * @property {boolean} [pasteable=false] - STORY-0090. With `staged` (a warning, and ignored, without it): Ctrl+V on the focused table (the browser's `paste` event; `paste(text)` from code) pastes a tab-separated block \u2014 what Excel and Google Sheets copy, read by `fromTSV` (tsv.js) \u2014 at the CURSOR cell, filling right over the columns shown and down over the rows in the order shown (cell_paste.js). Each value is read by its column's editor's parse (the built-in editor's for its type, or an injected `editors` factory's own `parse` property), and every cell that reads is staged as ONE undo entry; the range then covers the block, the cursor where it began. Columns past the last shown one are dropped with a warning naming how many (a console warning and a 'warn' toast). A value that does not parse marks its cell `twm-dt-cell--error` (message as `title` and `data-error`, the text kept) and the rest still stages; a cell `editable` refuses is skipped and drawn `twm-dt-cell--paste-skipped` until the selection moves. Rows past the last loaded row ask `onPasteOverrun`.\n * @property {Function} [onPasteOverrun] - With `pasteable`: `({rows}) => boolean | Promise<boolean>`, asked when a paste runs `rows` rows past the last loaded row (the last row in the order shown; for a server's page, the last row it sent). Anything but `true` stages NOTHING; `true` stages the rows that fit and hands the extra ones to `onRowsAppend`. Without it, such a paste stages nothing, with a console warning.\n * @property {Function} [onRowsAppend] - With `pasteable`: `({rows, errors}) => void | Promise`, after `onPasteOverrun` said `true`: `rows` the extra rows as data rows (one array per row, as long as `headers`, every pasted column read by its parse, the others null) and `errors` the values that did not read (`{row, colIdx, text, error}`, `row` an index into `rows`; that cell is null). Adding them is the consumer's; the rows that fit are staged once it settles. Without it, the extra rows are dropped with a warning.\n * @property {string|Function} [stagedRefusal] - With `staged`: the reason a frozen control carries, or `(count) => string`. Absent: \"Sorting, filtering and paging are held while N changes are not committed. Commit or discard them first.\"\n *\n * \u2500\u2500 STORY-0066, every one of them off unless asked for. THE CONSUMER OWNS THE DATA: each edit is a call, answered with `setData` \u2500\u2500\n * @property {Array<{key: string|number, label?: string, columns: number[]}>} [columnGroups] - COLUMN GROUPS (column_groups.js). A second header row above the column headers: one cell per run of shown columns of a group, spanning them, and a blank cell over the row number / select column and over columns in no group. It is a table of its own in the header wrap (`table.twm-dt-groups`, cells `th.twm-dt-group`) that takes the header's column widths after every fit, auto-size and drag, and scrolls sideways with it. A column is in the first group that lists it. A group with NO columns keeps one PLACEHOLDER column (`th.twm-dt-col--placeholder`, `td.twm-dt-cell--placeholder` in every row), after the columns of the groups listed before it, so its add control is reachable; it is no data column (not in a copy, the CSV, `ctx.colIdx` or cell mode). `setData({columnGroups})` changes them.\n * @property {Function} [groupActions] - `(group, {key, columns, table}) => items`, buttons in a group's header cell (`{action, icon?, label?, title?, disabled?}`); a click calls `onGroupAction(action, groupKey)`.\n * @property {Function} [onGroupAction] - `(action, groupKey) => void`.\n * @property {Function} [onColumnAdd] - `(groupKey) => void`. Puts an add button (`.twm-dt-group__add`) in every group's header cell and in a placeholder column's header.\n * @property {Function} [columnActions] - `(colIdx, {colIdx, header, table}) => items`, buttons in a data column's header (`.twm-dt-col-action`, same items as `groupActions`); a click calls `onColumnAction(action, colIdx)` and does not sort.\n * @property {Function} [onColumnAction] - `(action, colIdx) => void`.\n * @property {Function} [onColumnRename] - `(colIdx, name) => void | false | {ok: false} | Promise<\u2026>`. RENAMING IN PLACE through `attachInlineRenamer`: \"Rename column\" in the header's right-click menu, `renameColumn(colIdx)`, or (on a table that is not `sortable`) a double-click on the header's label opens it. Enter, or the focus leaving, with a different non-empty name calls it once; Escape, or the name unchanged, restores the header and calls nothing. The new name shows until the next render; `false` or `{ok: false}` restores the old one.\n * @property {Function} [onColumnDelete] - `(colIdx) => void`, from \"Delete column\" in the header's right-click menu.\n * @property {Function} [onRowAdd] - `(afterRowIdx|null) => void`, from \"Insert row below\" in a row's right-click menu (its original index) and \"Add row\" in the header's (null), so a table with no rows can get its first.\n * @property {Function} [onRowDelete] - `(rowIdx) => void`, from \"Delete row\" in a row's right-click menu.\n *\n * \u2500\u2500 STORY-0091, off unless asked for \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 * @property {{labelColumns?: number, headerRows?: Array<Array<{label: string, columns: number[], className?: string|string[], title?: string}>>, emptyLabel?: string}} [crosstab] - A CROSSTAB (crosstab.js): one table in one scroller, the `thead` kept in the body table. `headerRows` draws rows of spans above the column headers (top first; a cell spans the run of drawn body columns it lists, a run in no cell is blank), the leading `labelColumns` drawn data columns are row labels, and header rows stick to the top and label columns (behind the select and row-number columns) to the left at offsets MEASURED after layout and again when a header row or pinned header cell changes size; the corner sticks to both. With no body column, one column headed `emptyLabel` ('(none)'). No header table is built, so the column fit, resize grips, header menu (and the header items of `table_structure`), `columnActions`, `reorderable` and `columnGroups` (ignored, with a warning) do not apply. A row's background is `--twm-dt-row-bg` on its `tr`, which the pinned cells lay over their surface, with every cell tint as a layer above it.\n */\n\n/** C10. When the scroll box has no layout \u2014 mounted hidden, or a DOM with no\n * layout engine \u2014 there is no viewport to measure, so the window is sized as if\n * it were this tall. A ResizeObserver corrects it the moment a real size exists. */\nconst VIRTUAL_FALLBACK_VIEWPORT_PX = 1000;\n\n/** The copy menu \u2014 the whole right-click menu of a table without\n * `contextMenuItems`, and its tail with them (STORY-0010). Row mode has two\n * items, \"Copy Row(s)\" and \"Copy as CSV\"; cell mode (STORY-0085) has one,\n * \"Copy Cells\", and no CSV copy. */\nconst COPY_CELLS_MENU_HTML = `\n <div class=\"twm-context-menu-item\" data-action=\"copy-tsv\">\n <span class=\"material-symbols-outlined\">content_copy</span>\n <span class=\"label\">Copy Cells</span>\n </div>`;\nconst copyMenuHtml = (cells) => cells ? COPY_CELLS_MENU_HTML : `\n <div class=\"twm-context-menu-item\" data-action=\"copy-tsv\">\n <span class=\"material-symbols-outlined\">content_copy</span>\n <span class=\"label\">Copy Row(s)</span>\n </div>\n <div class=\"twm-context-menu-item\" data-action=\"copy-csv\">\n <span class=\"material-symbols-outlined\">table</span>\n <span class=\"label\">Copy as CSV</span>\n </div>\n `;\n\nexport class DataTable {\n /**\n * Create a DataTable instance\n * @param {HTMLElement} container - Container element to render into\n * @param {DataTableConfig} config - Configuration options\n */\n constructor(container, config = {}) {\n this.container = container;\n this.config = {\n headers: [],\n rows: [],\n pageSize: DEFAULT_PAGE_SIZE,\n pagination: true,\n selectable: true,\n copyable: true,\n sortable: false,\n filterable: false,\n readonly: false,\n showRowNumbers: false,\n emptyMessage: 'No data',\n onSort: null,\n // OFF unless asked for, for `columnFit`'s reason below: a sort kept\n // the client-side page before this key existed, so turning the\n // reset on for everybody would change every paged table that never\n // asked. See the typedef.\n resetPageOnSort: false,\n onSelectionChange: null,\n formatValue: null,\n getHeaderIcon: null,\n getColumnType: null,\n services: null,\n // Server-side pagination\n totalCount: null,\n offset: 0,\n onPageChange: null,\n onJumpToRow: null,\n // Custom cell rendering\n renderCell: null,\n // Rendering density + bottom-panel hooks (P2)\n mode: 'normal',\n onRowClick: null,\n onRowContextMenu: null,\n onCellContextMenu: null,\n showExportButton: false,\n exportFilename: null,\n // The host port. TOP LEVEL, deliberately \u2014 NOT inside `services`,\n // which most call sites never pass. Supplies the native save\n // dialog for downloadCSV(); absent => Blob fallback.\n host: null,\n // Opt-in persistence: when set, this table's sort, filters, and\n // column widths survive teardown/reload, keyed by this string\n // inside the injected `stateStore`. Omit it and the table stays\n // ephemeral. WHERE the store persists is the embedder's business.\n persistKey: null,\n stateStore: null,\n // How the automatic fit pass sizes an undragged column \u2014 see the\n // typedef. 'container' is exactly what every consumer got before\n // this key existed, so the default is not a preference: it is the\n // promise that adding the key changed no existing layout by a\n // pixel. Only a consumer that asks for 'content' sees anything new.\n columnFit: 'container',\n // Off unless asked for \u2014 see the typedef. With it the old pager is\n // not drawn: the paging strip says the same and more.\n paging: null,\n // C10. Off unless asked for \u2014 see the typedef.\n virtualize: false,\n virtualRowHeight: null,\n onRowsRendered: null,\n // 0.5.0. Every key below is off \u2014 or exactly the 0.4 behaviour \u2014 until\n // a consumer sets it (D6: additive and back-compatible). The typedef\n // says what each does.\n fitContent: false,\n maxHeight: null,\n autoDispose: false,\n firstColumn: 'time',\n clickable: null,\n onRowActivate: null,\n activateOn: 'click',\n getRowKey: null,\n activeRow: null,\n rowClass: null,\n rowAttrs: null,\n cellClass: null,\n diff: null,\n scrollLock: null,\n rowIcon: null,\n emptyState: undefined,\n nullDisplay: null,\n columnTypes: null,\n sortValue: null,\n dateFormat: null,\n dateTimeFormat: null,\n durationFormat: null,\n dateTimeZone: 'local',\n // 0.7.0. Off \u2014 or exactly the 0.6 behaviour \u2014 until set. The\n // typedef says what each does.\n rowDetail: null,\n hasRowDetail: null,\n expandedRows: null,\n onRowDetailToggle: null,\n rowDetailLabel: 'Details',\n dataSource: null,\n onLoad: null,\n onLoadError: null,\n hasMore: undefined,\n pagerLabels: null,\n pagerPosition: 'top',\n maxJumpOffset: null,\n follow: false,\n onFollowChange: null,\n keepWhileDetached: false,\n filterKinds: null,\n onFilterChange: null,\n // STORY-0010. Off \u2014 or exactly the 0.9.1 behaviour \u2014 until set. The\n // typedef says what each does.\n contextMenuItems: null,\n onContextMenuAction: null,\n onRender: null,\n keyboardNav: false,\n onRowKeyDown: null,\n persistPage: false,\n // STORY-0012. Off \u2014 every column drawn, as in 0.9.1 \u2014 until set.\n hiddenColumns: null,\n columnChooser: false,\n onColumnsChange: null,\n // STORY-0086. Off \u2014 columns in their natural order, as in 0.16.\n reorderable: false,\n columnOrder: null,\n // STORY-0016. Off \u2014 no select column, as in 0.11 \u2014 until set.\n selectToggle: false,\n selectMode: false,\n onSelectModeChange: null,\n // STORY-0003. Off \u2014 rows selected as in 0.16, no editing \u2014 until\n // set. The typedef says what each does.\n selectionMode: 'rows',\n editable: false,\n editors: null,\n editTypes: null,\n locale: null,\n editorMessages: null,\n onCellCommit: null,\n onCellSelectionChange: null,\n headerMenu: null,\n onHeaderMenuAction: null,\n // STORY-0088. Off \u2014 commits go to onCellCommit \u2014 until set.\n staged: false,\n historyLimit: 100,\n onCommit: null,\n onStagedChange: null,\n stagedRefusal: null,\n // STORY-0066. Off \u2014 one header row, no structural edits \u2014 until\n // set. The typedef says what each does.\n columnGroups: null,\n groupActions: null,\n onGroupAction: null,\n onColumnAdd: null,\n columnActions: null,\n onColumnAction: null,\n onColumnRename: null,\n onColumnDelete: null,\n onRowAdd: null,\n onRowDelete: null,\n // STORY-0089. Off \u2014 no fill handle \u2014 until set.\n fillHandle: false,\n // STORY-0090. Off \u2014 Ctrl+V is not the table's \u2014 until set.\n pasteable: false,\n onPasteOverrun: null,\n onRowsAppend: null,\n ...config,\n };\n\n // STORY-0003. Cell mode is the table's for its whole life. The row\n // modes it replaces are ignored beside it, out loud.\n this._cellGrid = null;\n // STORY-0066. Built the first time their options are set (see\n // `_colGroups`, `_structure`); a table without them never builds either.\n this._columnGroups = null;\n this._tableStructure = null;\n // STORY-0091. Built the first time `crosstab` is read (`_crosstab`).\n this._crosstabLayout = null;\n if (this.config.selectionMode === 'cells') {\n const clash = ['selectToggle', 'selectMode', 'keyboardNav'].filter((k) => !!this.config[k]);\n if (clash.length) {\n console.warn(`[DataTable] ${clash.join('/')} cannot be combined with selectionMode: 'cells'; ignored.`);\n for (const k of clash) this.config[k] = false;\n }\n this._cellGrid = new CellGrid(this);\n } else if (this.config.editable) {\n console.warn(\"[DataTable] `editable` needs selectionMode: 'cells'; ignored.\");\n }\n if (this.config.staged && !this._cellGrid) {\n console.warn('[DataTable] `staged` needs `editable`; ignored.');\n }\n if (this.config.fillHandle && !this._cellGrid) {\n console.warn('[DataTable] `fillHandle` needs `staged`; ignored.');\n }\n if (this.config.pasteable && !this._cellGrid) {\n console.warn('[DataTable] `pasteable` needs `staged`; ignored.');\n }\n // STORY-0091. A crosstab has no group row: its spans are `headerRows`.\n if (Array.isArray(this.config.columnGroups) && this.config.columnGroups.length && this._crosstab()) {\n console.warn('[DataTable] `columnGroups` cannot be combined with `crosstab` (use crosstab.headerRows); ignored.');\n }\n\n // STORY-0016. The select column is drawn for the table's whole life or\n // not at all, so the drawn column indices (and the widths kept by them)\n // never move when the mode flips.\n {\n const sel = this.config.selectable;\n const asked = !!this.config.selectToggle || !!this.config.selectMode;\n this._gutter = asked && !!sel && sel !== 'single';\n if (asked && !this._gutter) {\n console.warn('[DataTable] selectToggle/selectMode need a multi-row `selectable`; ignored.');\n }\n this._selecting = this._gutter && !!this.config.selectMode;\n }\n\n // 0.7.0. Open details (by key), the server's half, follow, and the\n // filter controls that are not text boxes.\n this._expanded = new Set((this.config.expandedRows || []).map((k) => String(k)));\n this._detailHeights = new Map();\n this._source = null;\n this._following = !!this.config.follow && !!this.config.dataSource;\n this._followTimer = null;\n this._newKeys = null;\n this._filterControls = new Map();\n this._filterCounts = new Map();\n this._pendingFilter = null;\n\n // STORY-0012. The columns not drawn, by data index. Before the restore\n // below, which may replace them with the remembered set.\n this._hidden = new Set();\n this._setHidden(this.config.hiddenColumns);\n // STORY-0086. The order asked for (null: natural), before the restore\n // below, which may replace it with the remembered one.\n this._order = null;\n this._askedOrder = null;\n this._askedUnchecked = false;\n if (!this._setOrder(this.config.columnOrder, true)) {\n console.warn('[DataTable] columnOrder is not an order of the columns; ignored.');\n }\n this._reorder = this.config.reorderable ? new ColumnReorder(this) : null;\n\n // 0.5.0. The open row's key, and the failure on show (`setError`).\n this._activeKey = this.config.activeRow == null ? null : String(this.config.activeRow);\n this._error = null;\n\n // C10. The render window, or null when this table draws every row.\n this._virt = null;\n // The measured row height outlives a render, so a re-render does not\n // start again from the estimate and jump once it has re-measured.\n this._virtBase = null;\n\n // A persistKey with nowhere to persist is a wiring bug, not a\n // degraded mode. Fail loud at construction: a silent no-op here\n // reads as \"my filters randomly stopped sticking\" months later.\n if (this.config.persistKey && !this.config.stateStore) {\n throw new Error(`DataTable: persistKey \"${this.config.persistKey}\" requires { stateStore }`);\n }\n\n // State\n this._state = {\n offset: 0,\n selected: new Set(),\n anchorIndex: null,\n sortColumn: null,\n sortAscending: true,\n filters: new Map(),\n };\n\n // Column types cache\n this._columnTypes = [];\n\n // Processed rows cache (filtered + sorted)\n this._processedRows = null;\n this._processedIndexMap = null;\n this._filterDebounceTimer = null;\n\n // DOM references\n this._wrapperEl = null;\n this._paginationEl = null;\n this._tableEl = null;\n this._tbodyEl = null;\n this._contextMenuEl = null;\n // STORY-0010. The right-click the custom items on show were built for,\n // read again when one is chosen.\n this._contextMenuCtx = null;\n // BUG-0040. What had focus when the menu opened, given it back on close.\n this._contextMenuReturnFocus = null;\n // STORY-0010 `keyboardNav`: the row the arrows last moved to.\n this._navCursor = null;\n this._filterDropdownEl = null;\n this._filterDropdownCleanup = null;\n\n // User column-resize overrides, keyed by DOM column index (the\n // row-number column, when shown, is index 0). Persists across\n // re-renders; reset when the header signature changes.\n this._colWidths = {};\n this._colWidthsSig = null;\n\n // Event cleanup\n this._disposers = [];\n this._contextMenuGlobals = [];\n // 0.5.0. `onRowActivate`'s listeners are kept apart from `_disposers`:\n // a render does not remove them at once (see `_retireActivation`).\n this._activationOffs = [];\n\n // Persistence: seed from whatever's already cached, then \u2014 once\n // the on-disk blob has loaded \u2014 re-apply and re-render if state\n // arrived after this table first painted.\n if (this.config.persistKey) {\n const store = this.config.stateStore;\n this._restorePersisted(store.get(this.config.persistKey));\n store.ready().then(() => {\n const late = store.get(this.config.persistKey);\n if (late && this._restorePersisted(late) && this._wrapperEl) {\n this._invalidateProcessedCache?.();\n this.render();\n }\n });\n }\n }\n\n /**\n * 0.5.0. Construct AND DRAW, in one call. The constructor draws nothing\n * until `render()`, so every consumer that forgot the second line got an\n * empty box; this is the two lines, once.\n *\n * Called on a class made by `withDefaults`, it builds that class \u2014 so the\n * house defaults apply.\n *\n * @param {HTMLElement} container\n * @param {DataTableConfig} [config]\n * @returns {DataTable}\n */\n static mount(container, config = {}) {\n const table = new this(container, config);\n table.render();\n return table;\n }\n\n /**\n * 0.5.0. A DataTable class with house defaults: `defaults` sit under every\n * config it is constructed (or `mount`ed) with, and the config wins key by\n * key. It is a real subclass \u2014 `instanceof DataTable` holds \u2014 and it can be\n * narrowed again with its own `withDefaults`.\n *\n * const ListTable = DataTable.withDefaults({ mode: 'compact', sortable: true,\n * pagination: false, fitContent: true });\n * const table = ListTable.mount(host, { headers, rows });\n *\n * @param {DataTableConfig} defaults\n * @returns {typeof DataTable}\n */\n static withDefaults(defaults = {}) {\n const house = { ...defaults };\n return class extends this {\n constructor(container, config = {}) {\n super(container, { ...house, ...config });\n }\n };\n }\n\n /** Apply a persisted blob ({sort, asc, filters, widths}) onto this\n * table's live state. Returns true if anything was applied. */\n _restorePersisted(blob) {\n if (!blob) return false;\n let applied = false;\n if (typeof blob.sortColumn === 'number' || blob.sortColumn === null) {\n this._state.sortColumn = blob.sortColumn;\n this._state.sortAscending = blob.sortAscending !== false;\n applied = true;\n }\n if (Array.isArray(blob.filters)) {\n this._state.filters = new Map(blob.filters);\n applied = true;\n }\n // STORY-0012. The columns shown, before the widths: the widths are by\n // DRAWN column, and were saved for this set.\n if (Array.isArray(blob.hidden)) {\n this._setHidden(blob.hidden);\n applied = true;\n }\n // STORY-0086. The order, before the widths for the same reason. One\n // saved for a different number of columns is no order of these.\n if (Array.isArray(blob.order) && this._setOrder(blob.order)) {\n applied = true;\n }\n if (blob.colWidths && typeof blob.colWidths === 'object') {\n // Stored under string keys (JSON) \u2192 coerce back to ints.\n this._colWidths = {};\n // STORY-0016. Widths are by drawn column; a blob saved before this\n // table drew its select column (or a consumer's seed) has none.\n const shift = this._lead().select - (Number(blob.colWidthsLead) || 0);\n for (const [k, v] of Object.entries(blob.colWidths)) {\n const i = Number(k) + shift;\n if (i >= this._lead().select) this._colWidths[i] = v;\n }\n // Stamp the matching signature so the next render keeps these\n // widths instead of treating them as stale.\n this._colWidthsSig = this._colSig();\n applied = true;\n }\n // STORY-0010 `persistPage`. The page you were on \u2014 only when asked for:\n // page 3 of one search is not a place in the next. Clamped by the first\n // render that has rows, since they may have shrunk since it was saved.\n if (this.config.persistPage && Number.isInteger(blob.offset) && blob.offset >= 0) {\n this._state.offset = blob.offset;\n this._clampRestoredPage = true;\n applied = true;\n }\n return applied;\n }\n\n /** Identity of the current column set \u2014 restored widths/sort are\n * keyed by position, so a schema change invalidates them. */\n _colSig() {\n return (this.config.headers || []).join('\\x01')\n + (this.config.showRowNumbers ? '|#' : '')\n // STORY-0012. Widths are by drawn column, so a different set drawn\n // is a different schema \u2014 unless `setColumnVisible` carried them.\n + (this._hidden?.size ? `|-${this.getHiddenColumns().join(',')}` : '')\n // STORY-0086. And a different order \u2014 unless `moveColumn` carried them.\n + (this._columnOrder() ? `|>${this._columnOrder().join(',')}` : '')\n // STORY-0066. A placeholder column moves the drawn indices too.\n + (this._colGroups()?.sig() || '');\n }\n\n /** Snapshot the persistable slice of state to the project store.\n * No-op unless `persistKey` is set. Debounced inside the store. */\n _savePersisted() {\n if (!this.config.persistKey) return;\n this.config.stateStore.set(this.config.persistKey, {\n sortColumn: this._state.sortColumn,\n sortAscending: this._state.sortAscending,\n filters: [...this._state.filters.entries()],\n colWidths: { ...this._colWidths },\n // STORY-0016. Where the widths start, so a blob read by a table\n // with or without the select column lands on the same columns.\n ...(this._gutter ? { colWidthsLead: 1 } : {}),\n // STORY-0010. Only for a table that asked: one that did not writes\n // the 0.9.1 blob, key for key.\n ...(this.config.persistPage ? { offset: this._state.offset } : {}),\n // STORY-0012. Only for a table that hides columns or lets them be\n // hidden.\n ...(this._columnsOn() ? { hidden: this.getHiddenColumns() } : {}),\n // STORY-0086. Only for a table that orders its columns.\n ...(this._orderOn() ? { order: this.getColumnOrder() } : {}),\n });\n }\n\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 // STORY-0012 \u2014 columns shown and hidden\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** Whether this table hides columns at all (and so saves the set). */\n _columnsOn() {\n return Array.isArray(this.config.hiddenColumns) || !!this.config.columnChooser\n || !!this._columnsTouched;\n }\n\n /** Replace the hidden set: whole indices of existing columns, and never\n * every column \u2014 the first one stays when nothing else would. A table\n * with no headers yet keeps the set for the headers `setData` brings. */\n _setHidden(list) {\n const n = (this.config.headers || []).length;\n this._hidden = new Set((Array.isArray(list) ? list : [])\n .map(Number).filter((c) => Number.isInteger(c) && c >= 0 && (!n || c < n)));\n if (n && this._hidden.size >= n) this._hidden.delete(0);\n }\n\n _isHidden(colIdx) {\n return this._hidden.has(colIdx);\n }\n\n /** The cells a drawn row has: the shown columns, and the row number. */\n _domColCount() {\n const n = Math.max(0, (this.config.headers?.length || 0) - this._hidden.size);\n // STORY-0066: an empty group's placeholder column is drawn too.\n return n + this._lead().all + (this._colGroups()?.placeholderCount() || 0)\n // STORY-0091: an empty axis's one column.\n + (this._crosstab()?.extraColumns() || 0);\n }\n\n /** STORY-0066. The column groups (column_groups.js) while `columnGroups`\n * holds any; null otherwise. */\n _colGroups() {\n const spec = this.config.columnGroups;\n if (!Array.isArray(spec) || !spec.length) return null;\n // STORY-0091. A crosstab's spanned rows are its `headerRows`; the\n // split layout's group row has no header table to stand in.\n if (this._crosstab()) return null;\n return (this._columnGroups ||= new ColumnGroups(this));\n }\n\n /** STORY-0091. The crosstab layout (crosstab.js) while `crosstab` is an\n * object; null otherwise. */\n _crosstab() {\n const spec = this.config.crosstab;\n if (!spec || typeof spec !== 'object') return null;\n return (this._crosstabLayout ||= new Crosstab(this));\n }\n\n /** STORY-0066. The structural edits (table_structure.js) while any of\n * their options is set; null otherwise. */\n _structure() {\n if (!STRUCTURE_OPTIONS.some((k) => typeof this.config[k] === 'function')) return null;\n return (this._tableStructure ||= new TableStructure(this));\n }\n\n /** STORY-0016. The drawn columns in front of the data: the select column\n * (`select`, 0 or 1, always first) and the row number. */\n _lead() {\n const select = this._gutter ? 1 : 0;\n return { select, all: select + (this.config.showRowNumbers ? 1 : 0) };\n }\n\n /** The data columns drawn, in the order drawn (STORY-0086): the order\n * without the hidden ones. */\n _shownColumns() {\n return this._rowColumns(this.config.headers?.length || 0);\n }\n\n /** The data indices of a row of `count` cells to draw, in order: the\n * shown columns, and any cell past the headers after them. */\n _rowColumns(count) {\n return cellOrder(this._columnOrder(), count).filter((c) => !this._isHidden(c));\n }\n\n /** A data column's drawn index (row number included), or -1 when hidden. */\n _domIdxOf(colIdx) {\n // STORY-0066. With a placeholder drawn, the groups' layout says.\n const slot = this._colGroups()?.slotOf(colIdx) ?? -1;\n if (slot >= 0) return this._lead().all + slot;\n const at = this._shownColumns().indexOf(colIdx);\n return at < 0 ? -1 : this._lead().all + at;\n }\n\n /** A drawn cell's data column, or null for the row number. */\n _dataIdxOfDom(domIdx) {\n const i = domIdx - this._lead().all;\n if (i < 0) return null;\n // STORY-0066. With a placeholder drawn, the groups' layout says (and\n // a placeholder is no data column).\n const slot = this._colGroups()?.slotAt(i);\n if (slot !== undefined) return slot;\n return this._shownColumns()[i] ?? null;\n }\n\n /** The columns not drawn, by data index, ascending. */\n getHiddenColumns() {\n return [...(this._hidden || [])].sort((a, b) => a - b);\n }\n\n /**\n * Show (`on` true) or hide a column. The last column shown is not hidden.\n * The widths of the other columns stay as they were; a column shown again\n * is measured. Saved under `persistKey`, and `onColumnsChange` is told.\n *\n * @param {number} colIdx\n * @param {boolean} [on=true]\n * @returns {boolean} whether the set changed\n */\n setColumnVisible(colIdx, on = true) {\n const n = this.config.headers?.length || 0;\n if (!Number.isInteger(colIdx) || colIdx < 0 || colIdx >= n) return false;\n if (!!on === !this._isHidden(colIdx)) return false;\n if (!on && n - this._hidden.size <= 1) return false;\n this._columnsTouched = true;\n const next = new Set(this._hidden);\n if (on) next.delete(colIdx); else next.add(colIdx);\n this._applyHidden(next);\n return true;\n }\n\n /** Swap in a new hidden set, carrying the drawn widths of the columns\n * that stay drawn to their new places, and tell whoever listens. */\n _applyHidden(next) {\n const before = this.getHiddenColumns();\n this._carryWidths(() => this._setHidden([...next]));\n const after = this.getHiddenColumns();\n if (before.join() === after.join()) return;\n this._savePersisted();\n if (this._wrapperEl) this.render();\n this._columnsChanged();\n }\n\n /** STORY-0012/0086. Run `change` (a new hidden set or order), carrying\n * the drawn widths of the columns drawn before and after to their new\n * places. */\n _carryWidths(change) {\n const n = this.config.headers?.length || 0;\n const old = this._colWidths;\n const kept = this._colWidthsSig === this._colSig();\n const domBefore = [];\n for (let c = 0; c < n; c++) domBefore[c] = this._domIdxOf(c);\n change();\n if (kept) {\n const widths = {};\n for (let i = 0; i < this._lead().all; i++) if (old[i] != null) widths[i] = old[i];\n for (let c = 0; c < n; c++) {\n const from = domBefore[c];\n const to = this._domIdxOf(c);\n if (from >= 0 && to >= 0 && old[from] != null) widths[to] = old[from];\n }\n this._colWidths = widths;\n this._colWidthsSig = this._colSig();\n }\n }\n\n /** `onColumnsChange(hidden, {hidden, order})`, after a change of either. */\n _columnsChanged() {\n const hidden = this.getHiddenColumns();\n try { this.config.onColumnsChange?.(hidden, { hidden, order: this.getColumnOrder() }); } catch (err) {\n console.error('[DataTable] onColumnsChange threw', err);\n }\n }\n\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 // STORY-0086 \u2014 the order the columns are drawn in (column_order.js)\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** Whether this table orders its columns at all (and so saves the order). */\n _orderOn() {\n return !!this.config.reorderable || Array.isArray(this.config.columnOrder) || !!this._orderTouched;\n }\n\n /** Take `list` as the order (`asked`: it is `columnOrder`, kept apart as\n * the fallback). Refused (false, nothing changed) when it is no\n * permutation of the columns; a table with no headers yet keeps it for\n * the headers `setData` brings, and `_checkAskedOrder` checks it then. */\n _setOrder(list, asked = false) {\n const n = this.config.headers?.length || 0;\n if (list != null && (!Array.isArray(list) || (n && !isColumnOrder(list, n)))) return false;\n this._order = list == null ? null : list.map(Number);\n if (asked) {\n this._askedOrder = this._order;\n this._askedUnchecked = !!this._order && !n;\n }\n return true;\n }\n\n /** The first headers have come: a `columnOrder` taken before them, unchecked,\n * that is no order of them is dropped with the same warning a table with\n * headers gives at once \u2014 once, as the check is made once. */\n _checkAskedOrder() {\n const n = this.config.headers?.length || 0;\n if (!this._askedUnchecked || !n) return;\n this._askedUnchecked = false;\n if (isColumnOrder(this._askedOrder, n)) return;\n console.warn('[DataTable] columnOrder is not an order of the columns; ignored.');\n if (this._order === this._askedOrder) this._order = null;\n this._askedOrder = null;\n }\n\n /** The order in force, or null for the natural one. One rule, whether the\n * headers were known when an order came or not: the first of the live\n * order (dragged, moved or restored) and `columnOrder` that is an order\n * of today's columns \u2014 so a saved order of the wrong length never\n * displaces `columnOrder`. */\n _columnOrder() {\n const n = this.config.headers?.length || 0;\n for (const o of [this._order, this._askedOrder]) {\n if (o && isColumnOrder(o, n)) return o;\n }\n return null;\n }\n\n /**\n * Every data column's index, hidden ones included, in the order drawn.\n * @returns {number[]}\n */\n getColumnOrder() {\n return (this._columnOrder() || naturalOrder(this.config.headers?.length || 0)).slice();\n }\n\n /**\n * Move the column at position `from` of `getColumnOrder()` to position\n * `to`, the others closing up behind it: from the natural order,\n * `moveColumn(3, 1)` draws 0, 3, 1, 2. The widths stay with their columns.\n * Saved under `persistKey`, and `onColumnsChange` is told.\n *\n * @param {number} from\n * @param {number} to\n * @returns {boolean} whether the order changed\n */\n moveColumn(from, to) {\n const order = this.getColumnOrder();\n const n = order.length;\n if (![from, to].every((i) => Number.isInteger(i) && i >= 0 && i < n) || from === to) return false;\n this._applyOrder(moveInOrder(order, from, to));\n return true;\n }\n\n /** Swap in a new order (a permutation, or null), widths carried, and\n * tell whoever listens. */\n _applyOrder(next) {\n const before = this.getColumnOrder().join();\n this._orderTouched = true;\n this._carryWidths(() => this._setOrder(next));\n if (this.getColumnOrder().join() === before) return;\n this._savePersisted();\n if (this._wrapperEl) this.render();\n this._columnsChanged();\n }\n\n /** `columnChooser`'s items: one checkable item a column. */\n _columnChooserItems() {\n const headers = this.config.headers || [];\n const lastShown = headers.length - this._hidden.size <= 1;\n return headers.map((h, c) => {\n const shown = !this._isHidden(c);\n return {\n label: String(h ?? ''),\n icon: shown ? 'check' : '',\n checked: shown,\n disabled: shown && lastShown,\n title: shown && lastShown ? 'The last column shown cannot be hidden' : '',\n onChoose: () => this.setColumnVisible(c, !shown),\n };\n });\n }\n\n /**\n * STORY-0003. The header's right-click menu for a press on `target`: the\n * consumer's `headerMenu` items for the data column under it, then \u2014 with\n * `columnChooser` \u2014 the chooser's items behind a separator. Empty when\n * there is nothing to show.\n */\n _headerMenuItems(target) {\n const items = [];\n const hook = this.config.headerMenu;\n const colIdx = this._headerColumnAt(target);\n if (typeof hook === 'function' && colIdx !== null) {\n let asked = null;\n try {\n asked = hook(colIdx, {\n colIdx,\n header: this.config.headers?.[colIdx],\n hiddenColumns: this.getHiddenColumns(),\n table: this,\n });\n } catch (err) {\n console.error('[DataTable] headerMenu threw', err);\n }\n for (const item of Array.isArray(asked) ? asked.filter(Boolean) : []) {\n if (item.separator) { items.push({ separator: true }); continue; }\n items.push({\n ...item,\n onChoose: () => {\n try { this.config.onHeaderMenuAction?.(item.action, colIdx); } catch (err) {\n console.error('[DataTable] onHeaderMenuAction threw', err);\n }\n },\n });\n }\n }\n // STORY-0086. Move left / Move right, for the data column under it.\n if (this._reorder && colIdx !== null) {\n const moves = this._reorder.menuItems(colIdx);\n if (moves.length && items.length) items.push({ separator: true });\n items.push(...moves);\n }\n // STORY-0066. Rename, delete, add a row.\n const structural = this._structure()?.headerItems(colIdx) || [];\n if (structural.length) {\n if (items.length) items.push({ separator: true });\n items.push(...structural);\n }\n if (this.config.columnChooser) {\n if (items.length) items.push({ separator: true });\n items.push(...this._columnChooserItems());\n }\n return items;\n }\n\n /** The data column of a header cell (the header row, or the filter row\n * under it), or null off one \u2014 the row number, the select column. */\n _headerColumnAt(target) {\n const cell = target?.closest?.('th, td');\n const tr = cell?.parentNode;\n if (!tr || tr.parentNode?.tagName !== 'THEAD') return null;\n if (tr.children.length !== this._domColCount()) return null;\n return this._dataIdxOfDom(Array.prototype.indexOf.call(tr.children, cell));\n }\n\n /** STORY-0010 `persistPage`: the client page changed, so save it. */\n _savePage() {\n if (this.config.persistPage) this._savePersisted();\n }\n\n /**\n * Update data and re-render\n * @param {Object} updates - Partial config updates (headers, rows, etc.)\n */\n setData(updates) {\n // STORY-0016. In select mode, ticks are kept by `getRowKey` across new\n // rows (read before they are replaced): a list refreshed under somebody halfway through ticking twenty\n // rows must not throw them away. Only in the mode; elsewhere new rows\n // are an answer, as before.\n const keepTicks = updates.rows && this._selecting && typeof this.config.getRowKey === 'function'\n && this._state.selected.size\n ? new Set(this.getSelection().map((i) => this._rowKey(this.config.rows[i], i)).filter((k) => k !== null))\n : null;\n // Clear filters if headers changed\n if (updates.headers && this._state.filters.size > 0) {\n const oldHeaders = this.config.headers;\n const newHeaders = updates.headers;\n if (oldHeaders.length !== newHeaders.length ||\n oldHeaders.some((h, i) => h !== newHeaders[i])) {\n this._state.filters.clear();\n }\n }\n // 0.7.0. A filter control belongs to a column; new columns, new\n // controls (and no counts carried onto a column they did not count).\n if (updates.headers && (this._filterControls.size || this._filterCounts.size)) {\n const oldHeaders = this.config.headers;\n const newHeaders = updates.headers;\n if (oldHeaders.length !== newHeaders.length\n || oldHeaders.some((h, i) => h !== newHeaders[i])) {\n this._destroyFilterControls();\n this._filterCounts.clear();\n }\n }\n if (Object.prototype.hasOwnProperty.call(updates, 'filterKinds')) {\n this._destroyFilterControls();\n }\n\n Object.assign(this.config, updates);\n\n // STORY-0012. A new set asked for applies at once; new columns keep\n // the set by position, minus any column that is gone.\n if (Object.prototype.hasOwnProperty.call(updates, 'hiddenColumns')) {\n const before = this.getHiddenColumns().join();\n this._setHidden(updates.hiddenColumns);\n if (this.getHiddenColumns().join() !== before) {\n this._savePersisted();\n this._columnsChanged();\n }\n } else if (updates.headers && this._hidden.size) {\n this._setHidden([...this._hidden]);\n }\n // STORY-0086. A new order asked for applies at once (refused, with a\n // warning, when it is no order of the columns); new headers keep the\n // order while it still fits them.\n if (Object.prototype.hasOwnProperty.call(updates, 'columnOrder')) {\n const before = this.getColumnOrder().join();\n if (!this._setOrder(updates.columnOrder, true)) {\n console.warn('[DataTable] columnOrder is not an order of the columns; ignored.');\n } else if (this.getColumnOrder().join() !== before) {\n this._savePersisted();\n this._columnsChanged();\n }\n } else if (updates.headers) {\n this._checkAskedOrder();\n }\n\n // Reset state if rows changed\n if (updates.rows) {\n this._state.selected.clear();\n this._state.anchorIndex = null;\n this._cellGrid?.newRows();\n if (this._state.offset >= updates.rows.length) {\n this._state.offset = 0;\n }\n this._columnTypes = this._detectColumnTypes();\n // 0.5.0. New rows are an ANSWER, so a failure on show is over. The\n // open row is not reset: it is a key, and is found again in these\n // rows (or stays unmarked until it comes back).\n this._error = null;\n }\n if (Object.prototype.hasOwnProperty.call(updates, 'activeRow')) {\n this._activeKey = updates.activeRow == null ? null : String(updates.activeRow);\n }\n // 0.5.0. A new `columnTypes` list (null included) applies at once. A new\n // `getColumnType` alone does NOT re-detect: in 0.4 it took effect with\n // the next rows, and a table that asks for nothing new keeps that.\n if (Object.prototype.hasOwnProperty.call(updates, 'columnTypes') && !updates.rows) {\n this._columnTypes = this._detectColumnTypes();\n }\n\n // STORY-0016. The ticks, found again in the new rows by key.\n if (keepTicks) {\n (this.config.rows || []).forEach((r, i) => {\n if (keepTicks.has(this._rowKey(r, i))) this._state.selected.add(i);\n });\n }\n\n // Invalidate processed cache\n this._processedRows = null;\n this._processedIndexMap = null;\n\n this.render();\n if (keepTicks) this._notifySelectionChange();\n }\n\n /**\n * Show / hide a translucent loading overlay over the table body.\n * Used by server-side consumers between firing a fetch and\n * receiving the new rows so the UI doesn't appear frozen.\n * Callers either:\n * - call `setLoading(true)` before their fetch, `setLoading(false)` after, OR\n * - return a Promise from `onPageChange` / `onSort` callbacks\n * \u2014 the overlay auto-shows during the await.\n * @param {boolean} on\n */\n setLoading(on) {\n this._loading = !!on;\n if (!this._wrapperEl) return;\n // 0.5.0. A wrapper class as well as the overlay, so an `emptyState` can\n // stay quiet while there is nothing YET (see the CSS) \u2014 and ONLY for a\n // table with an `emptyState`, the one thing that reads it: a table that\n // asks for nothing new keeps 0.4's wrapper to the attribute.\n this._wrapperEl.classList.toggle('twm-data-table-component--loading',\n !!on && (this.config.emptyState !== undefined\n || !!this.config.dataSource));\n let overlay = this._wrapperEl.querySelector('.twm-data-table__loading');\n if (on) {\n if (!overlay) {\n overlay = document.createElement('div');\n overlay.className = 'twm-data-table__loading';\n overlay.innerHTML =\n '<div class=\"twm-data-table__spinner\"></div>';\n // Ensure positioning context.\n if (!this._wrapperEl.style.position) {\n this._wrapperEl.style.position = 'relative';\n }\n this._wrapperEl.appendChild(overlay);\n }\n } else if (overlay) {\n overlay.remove();\n }\n }\n\n /**\n * Get current selection indices\n * @returns {number[]} Array of selected row indices\n */\n getSelection() {\n return Array.from(this._state.selected).sort((a, b) => a - b);\n }\n\n /**\n * Set selection programmatically\n * @param {number[]} indices - Row indices to select\n */\n setSelection(indices) {\n // STORY-0003. In cell mode, the cells of those rows: one range from the\n // first of them to the last, as shown, across every column shown.\n if (this._cellGrid) {\n this._cellGrid.selectRows(indices);\n return;\n }\n this._state.selected.clear();\n for (const idx of indices) {\n if (idx >= 0 && idx < this.config.rows.length) {\n // 0.5.0. A single-selection table keeps the LAST index it is\n // given \u2014 the most recent choice \u2014 never several.\n if (this.config.selectable === 'single') this._state.selected.clear();\n this._state.selected.add(idx);\n }\n }\n if (this.config.selectable === 'single') {\n this._state.anchorIndex = this._state.selected.size\n ? [...this._state.selected][0] : null;\n }\n this._updateRowSelection();\n this._notifySelectionChange();\n }\n\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 // 0.5.0 \u2014 the open row, the failure state, column widths\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 * Mark the row that is OPEN \u2014 the master of a master-detail \u2014 by its key\n * (`getRowKey`; without it, the row's original index). `null` clears it.\n *\n * The mark is NOT the selection: `setData` keeps it (the key is looked for\n * in the new rows), a right-click does not move it, and a sort, a filter or\n * a page change finds it where the row went. Drawn as `twm-dt-row--active`\n * and `aria-current=\"true\"` on the row, in place \u2014 no re-render.\n *\n * @param {*} key\n */\n setActiveRow(key) {\n this._activeKey = key == null ? null : String(key);\n this.config.activeRow = key ?? null;\n const tbody = this._tbodyEl;\n if (!tbody) return;\n for (const tr of tbody.children) {\n if (tr.__rowIndex === undefined) continue;\n this._paintActive(tr);\n }\n }\n\n /** The open row's key, as text, or null. */\n getActiveRow() {\n return this._activeKey;\n }\n\n /**\n * Show a FAILURE inside the table's own box: text, a node, or an `Error`\n * (its message). The rows already drawn STAY \u2014 a failed refresh does not\n * blank a list a person was reading \u2014 under a banner saying what failed;\n * with no rows, the failure takes the empty row's place. `setError(null)`\n * clears it, and so does `setData({rows})`: new rows are an answer. A\n * failure also ends `setLoading`.\n *\n * @param {string|Node|Error|null} error\n */\n setError(error) {\n this._error = error == null || error === false ? null : error;\n if (this._error) this.setLoading(false);\n if (this._wrapperEl) this.render();\n }\n\n /** What `setError` was last given, or null. */\n getError() {\n return this._error;\n }\n\n /**\n * Forget every column width a person dragged, a double-click fitted or the\n * store restored, and measure the columns again from what is on screen \u2014\n * for an embedder whose content has just changed size under them (a zoom,\n * a font). Persisted widths are cleared too.\n *\n * @returns {boolean} whether there was a table to measure\n */\n resetColumnWidths() {\n this._colWidths = {};\n this._colWidthsSig = this._colSig();\n this._savePersisted();\n if (!this._headerTableEl || !this._tableEl) return false;\n this._syncHeaderWidths();\n return true;\n }\n\n /**\n * Clear selection\n */\n clearSelection() {\n if (this._cellGrid) {\n this._cellGrid.clear();\n return;\n }\n this._state.selected.clear();\n this._state.anchorIndex = null;\n this._updateRowSelection();\n this._notifySelectionChange();\n }\n\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 // STORY-0003 \u2014 cell mode (`selectionMode: 'cells'`), see cell_grid.js\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 * The cell selection: `{anchor, focus, range}`. `anchor` and `focus` (the\n * cursor) are `{row, col, rowIdx}` \u2014 `row` the position in the order\n * shown, `col` the data column, `rowIdx` the original row index \u2014 and\n * `range` is `{top, bottom, left, right, rows, columns}`: positions,\n * data columns at its edges, and the original row indices and data\n * columns it covers. All null with nothing selected. Null outside cell\n * mode.\n */\n getCellSelection() {\n return this._cellGrid ? this._cellGrid.get() : null;\n }\n\n /**\n * Put the cursor on a cell (`row` a position in the order shown, `col` a\n * data column) \u2014 with `anchor`, select the range from there. `null`\n * clears. The row is brought into view. A no-op outside cell mode.\n *\n * @param {{row:number, col:number}|null} focus\n * @param {{row:number, col:number}} [anchor]\n */\n setCellSelection(focus, anchor = null) {\n this._cellGrid?.set(focus, anchor);\n }\n\n /** Open the editor on a cell (position, data column), as F2 would.\n * Returns whether one opened. */\n editCell(row, col) {\n return !!this._cellGrid?.open(row, col);\n }\n\n /** Whether a cell editor is open. */\n isEditing() {\n return !!this._cellGrid?.isEditing();\n }\n\n // \u2500\u2500 STORY-0088 `staged` \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 * Send every staged cell to `onCommit({edits})`, in one call. Resolves\n * `{ok: true, committed}` (the staged cells and the undo ring are\n * cleared), or `{ok: false, errors}` (the cells refused are marked and\n * every staged value stays). An open editor's value is staged first.\n * Without `staged`, resolves `{ok: false, errors: []}`.\n *\n * @returns {Promise<{ok: boolean, committed?: number, errors?: Array<{rowIdx:number, colIdx:number, error:string}>}>}\n */\n commit() {\n const st = this._cellGrid?.staged;\n return st ? st.commit() : Promise.resolve({ ok: false, errors: [] });\n }\n\n /** Drop every staged cell, its marks and the undo ring. Returns whether\n * there was anything to drop. */\n discard() {\n return !!this._cellGrid?.staged?.discard();\n }\n\n /** Take the last staged edit back (Ctrl+Z). Returns whether it moved. */\n undo() {\n return !!this._cellGrid?.staged?.undo();\n }\n\n /** Put the last edit taken back back again (Ctrl+Y). */\n redo() {\n return !!this._cellGrid?.staged?.redo();\n }\n\n /** Every staged cell, `{rowIdx, colIdx, value, previous}`, by row then\n * column. Empty without `staged`. */\n getStagedEdits() {\n return this._cellGrid?.staged ? this._cellGrid.staged.edits() : [];\n }\n\n /**\n * STORY-0089. Fill from the cell range to the cell `to` (`{row, col}`:\n * position in the order shown, data column), as dragging the fill handle\n * there does: staged as ONE undo entry, Ctrl's repeat as `forceCopy`.\n * Returns `{direction, count, staged, skipped}` \u2014\n * `staged` the NUMBER of cells that changed, `skipped` the cells `editable` refused\n * (`{row, col, rowIdx}`) \u2014 or null when nothing was filled (no\n * `fillHandle`, no range, `to` inside it, an editor open, a commit out).\n */\n fill(to, { forceCopy = false } = {}) {\n return this._cellGrid?.fill ? this._cellGrid.fill.fill(to, { forceCopy }) : null;\n }\n\n /**\n * STORY-0090. Paste tab-separated `text` at the cursor cell, as Ctrl+V\n * does: each value read by its column's parse, staged as ONE undo entry.\n * Resolves `{rows, cols, staged, skipped, refused, droppedColumns,\n * appended}` \u2014 `staged` the NUMBER of cells that changed, `skipped` the\n * cells `editable` refused (`{row, col, rowIdx}`), `refused` the values\n * that did not parse (`{row, col, rowIdx, text, error}`),\n * `droppedColumns` the columns past the last one, `appended` the rows\n * handed to `onRowsAppend` \u2014 or null when nothing was pasted (no\n * `pasteable`, empty text, no cursor, an editor open, a commit or another\n * paste out, an overrun `onPasteOverrun` did not accept).\n *\n * @param {string} text\n * @returns {Promise<object|null>}\n */\n paste(text) {\n return this._cellGrid?.paste ? this._cellGrid.paste.paste(text) : Promise.resolve(null);\n }\n\n /** Why sort, filters and pages are held \u2014 a staged edit \u2014 or null; with\n * a reason, `what` is refused out loud. */\n _stagedRefusal(what) {\n const why = this._cellGrid?.staged?.freezeReason() || null;\n if (why) console.warn(`[DataTable] ${what} refused: ${why}`);\n return why;\n }\n\n /** STORY-0066. Open the inline renamer on a data column's header (needs\n * `onColumnRename`). Returns whether it opened. */\n renameColumn(colIdx) {\n return !!this._structure()?.rename(colIdx);\n }\n\n /**\n * Go to specific page\n * @param {number} page - Page number (0-indexed)\n */\n goToPage(page) {\n if (this._stagedRefusal('goToPage')) return;\n // 0.7.0 `dataSource`: the page is the SOURCE's \u2014 asked for, and drawn\n // when it answers (the promise). Past a known total, the last page.\n // (The release review: this set an offset nothing under a data source\n // reads, and drew the same page again.)\n if (this.config.dataSource) {\n const size = this._sourcePageSize();\n let p = Math.max(0, Math.floor(Number(page)) || 0);\n const total = this._source?.total;\n if (typeof total === 'number') p = Math.min(p, Math.max(0, Math.ceil(total / size) - 1));\n return this._sourceGoTo(p * size);\n }\n const rowCount = this._getProcessedRows().length;\n const maxPage = Math.ceil(rowCount / this.config.pageSize) - 1;\n this._state.offset = Math.max(0, Math.min(page, maxPage)) * this.config.pageSize;\n this._savePage();\n this.render();\n }\n\n /**\n * Go to specific row\n * @param {number} rowIndex - Row index\n */\n goToRow(rowIndex) {\n if (this._stagedRefusal('goToRow')) return;\n // 0.7.0 `dataSource`: the page that holds the row, from the source.\n if (this.config.dataSource) {\n const size = this._sourcePageSize();\n return this.goToPage(Math.floor(Math.max(0, Math.floor(Number(rowIndex)) || 0) / size));\n }\n const rowCount = this._getProcessedRows().length;\n const idx = Math.max(0, Math.min(rowIndex, rowCount - 1));\n this._state.offset = Math.floor(idx / this.config.pageSize) * this.config.pageSize;\n this._savePage();\n this.render();\n }\n\n /**\n * Sort by column\n * @param {number} colIndex - Column index\n * @param {boolean} [ascending] - Sort direction (toggles if same column)\n */\n sortBy(colIndex, ascending) {\n if (this._stagedRefusal('sortBy')) return;\n if (this._state.sortColumn === colIndex && ascending === undefined) {\n this._state.sortAscending = !this._state.sortAscending;\n } else {\n this._state.sortColumn = colIndex;\n this._state.sortAscending = ascending ?? true;\n }\n\n // Invalidate processed cache\n this._processedRows = null;\n this._processedIndexMap = null;\n // A new order starts at its first page \u2014 when the table asked for it.\n // Staying on page 3 shows rows 201\u2013300 of the NEW order, which reads as\n // \"it only sorted this page\"; but that IS what a sort did before\n // `resetPageOnSort` existed, so a table that does not ask keeps it (D6:\n // additive and back-compatible). `render()` keeps the scroll position\n // only on the same page, so the reset also starts the body at its top.\n if (this.config.resetPageOnSort) this._state.offset = 0;\n\n // Auto-spinner: if the sort handler returns a Promise (i.e.\n // it does a server-side refetch), show the loading overlay\n // until it resolves so the user gets visible feedback.\n const ret = this.config.onSort?.(colIndex, this._state.sortAscending);\n this._awaitWithSpinner(ret);\n this._savePersisted();\n this.render();\n // 0.7.0 `dataSource`: a new order is a new question, from its first\n // page. Drawn first (the arrow moves at once), asked after.\n if (this.config.dataSource) this._sourceLoad({ offset: 0, reason: 'sort' });\n }\n\n /** Internal: if `maybePromise` is a Promise (or thenable),\n * toggle the loading overlay around it. No-op otherwise. */\n _awaitWithSpinner(maybePromise) {\n if (!maybePromise || typeof maybePromise.then !== 'function') return;\n this.setLoading(true);\n Promise.resolve(maybePromise).finally(() => this.setLoading(false));\n }\n\n /**\n * Clear all column filters\n */\n clearFilters() {\n if (this._stagedRefusal('clearFilters')) return;\n this._state.filters.clear();\n this._processedRows = null;\n this._processedIndexMap = null;\n this._state.offset = 0;\n this._pendingFilter = null;\n this._savePersisted();\n // 0.7.0. Each control shows \"no filter\", and whoever listens hears it.\n for (const { control } of this._filterControls.values()) {\n try { control.setValue?.(null); } catch (err) { console.error('[DataTable] filter control setValue threw', err); }\n }\n this._notifyFilterChange();\n if (this.config.dataSource) {\n if (this._wrapperEl) this.render();\n this._sourceLoad({ offset: 0, reason: 'filter' });\n return;\n }\n this.render();\n }\n\n /**\n * Get the number of rows after filtering\n * @returns {number}\n */\n getFilteredRowCount() {\n return this._getProcessedRows().length;\n }\n\n /**\n * STORY-0010. Give the table the keyboard focus (the body, where the arrow\n * keys and `onRowKeyDown` listen) without scrolling the page. False when\n * there is nothing drawn to focus.\n * @returns {boolean}\n */\n focus() {\n if (!this._tableEl) return false;\n try { this._tableEl.focus({ preventScroll: true }); } catch (_) { return false; }\n return true;\n }\n\n /** STORY-0010 `keyboardNav`: the original indices of the page shown, in\n * the order shown \u2014 every row held, when the page is a server's or there\n * are no pages. */\n _pageOrder() {\n this._getProcessedRows();\n const order = this._processedIndexMap || [];\n if (this._isServerSide() || !this.config.pagination || this._pagingConfig()) return order;\n return order.slice(this._state.offset, this._state.offset + this.config.pageSize);\n }\n\n /**\n * STORY-0010. The rows the table shows, as row arrays, in the order shown:\n * filtered and sorted, across EVERY page \u2014 not only the one on screen. With\n * server-side paging (`onPageChange`, `dataSource`) they are the page the\n * consumer or the source gave, which is all the table holds. A copy:\n * changing it changes nothing in the table.\n * @returns {Array<Array>}\n */\n getDisplayedRows() {\n return this._getProcessedRows().slice();\n }\n\n /**\n * Render the table\n */\n render() {\n // STORY-0003. An open cell editor is not torn down by a redraw: the\n // render waits for its commit or cancel, and runs then.\n if (this._cellGrid?.isEditing()) {\n this._cellGrid.renderWaiting = true;\n return;\n }\n // Capture active filter input before re-render\n const activeFilterColIdx = this._getActiveFilterColIdx();\n // KEYBOARD FOCUS SURVIVES A RE-RENDER. Rendering replaces the table\n // element, and a focused element that is removed hands focus to the\n // page body, where the arrow keys reach nobody. A data refresh does\n // exactly that (a record changed on disk, a live reload), so keyboard\n // navigation silently died the first time the store moved.\n const doc = this.container.ownerDocument;\n const hadTableFocus = !!this._tableEl && doc?.activeElement === this._tableEl;\n // 0.7.0. Focus inside a filter control (it is kept and re-appended,\n // which a move would blur) or on a row's detail toggle (rebuilt): put\n // back after the render. And a filter still being typed under\n // `dataSource` \u2014 an answer arriving mid-word re-renders the row.\n const focus070 = this._captureFocus070(doc);\n const pendingFilter = this.config.dataSource ? this._pendingFilter : null;\n // SCROLL POSITION SURVIVES A RE-RENDER, for the same reason: the scroll\n // box is rebuilt too, and a new one starts at the top. Folding a tree\n // row, or any refresh, threw a reader scrolled halfway down back to row\n // one. Only on the SAME page \u2014 turning the page should start at its top.\n const prevWrap = this._tableWrapEl;\n const prevScroll = prevWrap?.isConnected && this._renderedOffset === this._state.offset\n ? { top: prevWrap.scrollTop, left: prevWrap.scrollLeft } : null;\n\n this._cleanup();\n this._retireActivation();\n this.container.innerHTML = '';\n // C10. A window belongs to one tbody; `_createTable` builds a new one.\n this._virt = null;\n\n const { rows, pagination, emptyMessage } = this.config;\n\n // Drop stale column-resize overrides when the columns change \u2014\n // widths are keyed by position, so a different schema must start\n // from natural widths rather than inherit the old ones. (Restore\n // stamps the matching signature so persisted widths survive the\n // first render.)\n const colSig = this._colSig();\n if (this._colWidthsSig !== colSig) {\n this._colWidths = {};\n this._colWidthsSig = colSig;\n }\n\n // Detect column types if not cached\n if (this._columnTypes.length === 0) {\n this._columnTypes = this._detectColumnTypes();\n }\n\n // STORY-0010 `persistPage`. A restored page is put on a page boundary,\n // and past the rows (they shrank since it was saved, or a restored\n // filter narrowed them) it is the last page \u2014 by the first render that\n // has rows to count, which for a board that sets its rows after it\n // mounts is not the first render.\n if (this._clampRestoredPage && rows.length > 0) {\n this._clampRestoredPage = false;\n if (!this._isServerSide() && !this._pagingConfig()) {\n const size = this.config.pageSize;\n const last = Math.max(0, Math.ceil(this._getProcessedRows().length / size) - 1) * size;\n this._state.offset = Math.min(Math.floor(this._state.offset / size) * size, last);\n }\n }\n\n // Create wrapper. Compact mode adds a modifier class that the\n // CSS uses to tighten padding + drop font size \u2014 opt-in so\n // existing landing/tab use sites stay identical.\n this._wrapperEl = document.createElement('div');\n this._wrapperEl.className = 'twm-data-table-component'\n + (this.config.mode === 'compact' ? ' twm-data-table-component--compact' : '');\n // 0.5.0 `fitContent` / `maxHeight`. THE DEFAULT IS `height:100%`, which\n // is right for a pane that already has a height and wrong for a list in\n // a flowing page: against an `auto` parent it resolves to nothing, and\n // the body (`flex:1 1 0`) gets ZERO \u2014 a header, a filter row, and every\n // `<tr>` in the DOM with no box to draw in. A fitted table is as tall as\n // its rows instead, up to `maxHeight`, past which its body scrolls.\n const fit = this._fitsContent();\n if (fit) {\n this._wrapperEl.classList.add('twm-data-table-component--fit');\n const max = this._maxHeightCss();\n this._wrapperEl.style.cssText = 'display:flex; flex-direction:column; height:auto; min-height:0;'\n + (max ? ` max-height:${max};` : '');\n } else {\n this._wrapperEl.style.cssText = 'display:flex; flex-direction:column; height:100%; min-height:0;';\n }\n // A render ends a `setLoading` (the overlay goes with the old wrapper,\n // as it always has).\n this._loading = false;\n\n // Pagination (top). `_createPagination` returns null when the\n // strip would be uninformative (single page, no active filter). Not\n // with `paging`, whose own strip (under the body) replaces it.\n // 0.7.0: under `dataSource` an empty page that is not the first still\n // needs it \u2014 it is the way back.\n this._paginationEl = null;\n if (pagination && (rows.length > 0 || (this._source?.offset || 0) > 0) && !this._pagingConfig()) {\n this._paginationEl = this._createPagination();\n if (this._paginationEl && this.config.pagerPosition !== 'bottom') {\n this._wrapperEl.appendChild(this._paginationEl);\n }\n }\n\n // \u2500\u2500 Structural split: thead and tbody live in separate\n // containers so the scrollbar appears only over the body,\n // never over the header / filter row. Column widths are\n // measured from the body after layout and applied to the\n // header via `table-layout: fixed` + explicit cell widths.\n const tableWrap = document.createElement('div');\n tableWrap.className = this.config.readonly\n ? 'twm-preview-table-wrap twm-preview-table-wrap--wizard'\n : 'twm-preview-table-wrap';\n tableWrap.style.cssText = fit\n // As tall as its content, and the one thing that gives way under a\n // `maxHeight`: the header and the pager keep their height.\n ? 'flex:0 1 auto; min-height:0; min-width:0; overflow:auto;'\n : 'flex:1 1 0; min-height:0; min-width:0; overflow:auto;';\n\n // 0.5.0 `setError` with rows on screen: the rows STAY, under a banner.\n if (this._error && rows.length > 0) {\n this._wrapperEl.appendChild(this._createErrorBanner());\n }\n\n // 0.7.0. Under `dataSource` the rows ARE the filtered answer, so an\n // empty one must keep the filter row \u2014 or a filter that matched nothing\n // could never be cleared. It goes through `_createTable` and gets its\n // empty row there.\n // STORY-0091: a crosstab keeps its header rows and its corner too.\n const keepFilterRow = rows.length === 0\n && ((!!this.config.dataSource && this.config.filterable) || !!this._crosstab());\n if (rows.length === 0 && !keepFilterRow) {\n // Empty state \u2014 render the same chrome as the data table\n // (header row in its own non-scrolling wrap) followed by a\n // single virtual row spanning every column with the empty\n // message in italics. NO filter row: there's nothing to\n // filter, so it'd only mislead the user.\n const { headers, showRowNumbers } = this.config;\n const headerWrap = document.createElement('div');\n headerWrap.className = 'twm-preview-table-header-wrap';\n headerWrap.style.cssText\n = 'flex:0 0 auto; overflow:hidden; min-width:0;';\n const headerTable = document.createElement('table');\n headerTable.className = this._tableClassName();\n const thead = document.createElement('thead');\n const tr = document.createElement('tr');\n if (this._gutter) tr.appendChild(this._buildSelectHead());\n if (showRowNumbers) {\n const th = document.createElement('th');\n th.className = 'num';\n th.textContent = '#';\n tr.appendChild(th);\n }\n for (const colIdx of this._shownColumns()) {\n const th = document.createElement('th');\n th.className = this._columnTypes[colIdx] || 'text';\n th.textContent = headers[colIdx];\n tr.appendChild(th);\n }\n thead.appendChild(tr);\n headerTable.appendChild(thead);\n headerWrap.appendChild(headerTable);\n this._wrapperEl.appendChild(headerWrap);\n this._headerWrapEl = headerWrap;\n this._headerTableEl = headerTable;\n\n // Body: one virtual row across every column with the empty\n // message in italics. Wraps in the standard scroll container\n // so the placeholder sits where data rows would.\n const bodyTable = document.createElement('table');\n bodyTable.className = headerTable.className;\n const tbody = document.createElement('tbody');\n tbody.appendChild(this._buildEmptyRow(this._domColCount(), emptyMessage));\n bodyTable.appendChild(tbody);\n tableWrap.appendChild(bodyTable);\n this._wrapperEl.appendChild(tableWrap);\n this._tableEl = bodyTable;\n this._tableWrapEl = tableWrap;\n // No column-width sync needed \u2014 the body row has colspan=N\n // so there's nothing per-column to align against.\n } else {\n const fullTable = this._createTable();\n this._tableEl = fullTable;\n // Extract thead \u2192 header table in its own non-scrolling\n // container. The body table keeps tbody only.\n // STORY-0091. A crosstab keeps its `thead` in the body table: one\n // table in one scroller, pinned by `position: sticky`.\n const crosstab = this._crosstab();\n const thead = crosstab ? null : fullTable.querySelector('thead');\n if (crosstab) {\n crosstab.decorate(fullTable);\n this._headerTableEl = null;\n this._headerWrapEl = null;\n }\n if (thead) {\n const headerWrap = document.createElement('div');\n headerWrap.className = 'twm-preview-table-header-wrap';\n headerWrap.style.cssText\n = 'flex:0 0 auto; overflow:hidden; min-width:0;';\n const headerTable = document.createElement('table');\n headerTable.className = fullTable.className;\n headerTable.appendChild(thead);\n headerWrap.appendChild(headerTable);\n this._wrapperEl.appendChild(headerWrap);\n this._headerTableEl = headerTable;\n this._headerWrapEl = headerWrap;\n } else {\n this._headerTableEl = null;\n }\n // 0.7.0 `keepFilterRow`: the header and its filters, then the\n // empty (or failed) row the other branch would have drawn.\n if (keepFilterRow && this._tbodyEl) {\n this._tbodyEl.appendChild(this._buildEmptyRow(this._domColCount(), emptyMessage));\n }\n tableWrap.appendChild(fullTable);\n this._wrapperEl.appendChild(tableWrap);\n }\n\n this._tableWrapEl = tableWrap;\n // STORY-0012 `columnChooser` and STORY-0003 `headerMenu`: the header's\n // right-click. With neither item to show, the page's own menu.\n // STORY-0066: the groups' row and placeholder columns, the renamer's\n // labels and the consumer's column actions, on the header just built.\n this._colGroups()?.decorate(this._headerWrapEl, this._headerTableEl);\n this._structure()?.decorate(this._headerTableEl);\n if ((this.config.columnChooser || typeof this.config.headerMenu === 'function' || this._reorder\n || this._structure()?.hasHeaderItems()) && this._headerTableEl) {\n const head = this._headerTableEl;\n const onHeadMenu = (ev) => {\n const items = this._headerMenuItems(ev.target);\n if (!items.length) return;\n ev.preventDefault();\n ev.stopPropagation();\n setTimeout(() => this._showContextMenu(ev.clientX, ev.clientY,\n { ctx: null, items, copy: false }), 0);\n };\n head.addEventListener('contextmenu', onHeadMenu);\n this._disposers.push(() => head.removeEventListener('contextmenu', onHeadMenu));\n }\n // STORY-0086 `reorderable`: the header's drag.\n if (this._reorder && this._headerTableEl) {\n this._reorder.install(this._headerTableEl.querySelector('thead > tr'));\n }\n // 0.7.0 `pagerPosition: 'bottom'`: under the rows.\n if (this._paginationEl && this.config.pagerPosition === 'bottom') {\n this._paginationEl.classList.add('twm-pagination-controls--bottom');\n this._paginationEl.style.borderBottom = '0';\n this._paginationEl.style.borderTop = '1px solid #2a2a2a';\n this._wrapperEl.appendChild(this._paginationEl);\n }\n // `paging`: the strip goes UNDER the body, where the reader's eye is\n // when they reach the end of what is held.\n this._pagingEl = null;\n if (this._pagingConfig()) {\n this._pagingEl = this._createPagingStrip();\n if (this._pagingEl) this._wrapperEl.appendChild(this._pagingEl);\n }\n this.container.appendChild(this._wrapperEl);\n // STORY-0091. The crosstab's offsets, measured now the table is in.\n this._crosstab()?.install();\n // 0.6.1 `scrollLock`: THIS render's body box joins the group, and leaves\n // it with the next render's cleanup or the dispose.\n if (this.config.scrollLock && typeof this.config.scrollLock.attach === 'function') {\n this._disposers.push(this.config.scrollLock.attach(tableWrap));\n }\n // 0.5.0. Watched from here, so a table rendered again after an automatic\n // dispose (a `setData` into a re-attached host) is watched again.\n if (this.config.autoDispose) autoDisposeWatch(this);\n if (prevScroll && this._state.offset === this._renderedOffset) {\n tableWrap.scrollTop = prevScroll.top;\n tableWrap.scrollLeft = prevScroll.left;\n }\n this._renderedOffset = this._state.offset;\n\n // C10. NOW THERE IS A VIEWPORT. `_createTable` drew a window sized from\n // an estimate, before the scroll box existed; measure a real row, and\n // redraw the window for the real height and the restored scroll offset.\n // Synchronously, and not reported through `onRowsRendered`: a row present\n // when `render()` returns is the render's, as it is without `virtualize`.\n if (this._virt) {\n const onScroll = () => this._virtUpdate();\n tableWrap.addEventListener('scroll', onScroll, { passive: true });\n this._disposers.push(() => tableWrap.removeEventListener('scroll', onScroll));\n this._virtMeasure();\n this._virtUpdate({ force: true, notify: false });\n }\n\n // `paging`, scrolling: ask for the next rows near the end \u2014 and once\n // the layout has settled, when the rows held do not fill the box at all,\n // since then nothing can ever be scrolled to ask for them.\n if (this._pagingConfig()) {\n const onScroll = () => this._pagingMaybeLoadMore();\n tableWrap.addEventListener('scroll', onScroll, { passive: true });\n this._disposers.push(() => tableWrap.removeEventListener('scroll', onScroll));\n requestAnimationFrame(() => {\n if (this._tableWrapEl === tableWrap) this._pagingMaybeLoadMore();\n });\n }\n\n // Sync header column widths to body after layout. Two-pass: the\n // first frame lets the browser settle natural widths from the\n // body's auto layout, then we lock both tables to those widths\n // via table-layout:fixed + explicit cell widths.\n if (this._headerTableEl && this._tableEl) {\n // 0.6.3: and once the widths are fixed the rows may be another\n // height than they were measured at \u2014 so the window measures again.\n requestAnimationFrame(() => {\n this._syncHeaderWidths();\n this._virtRemeasure();\n });\n // Re-sync on container resize so columns stay aligned when\n // the parent flex / grid layout changes (window resize,\n // splitter drag, etc.).\n if (this._resizeObserver) {\n try { this._resizeObserver.disconnect(); } catch (_) {}\n }\n if (typeof ResizeObserver !== 'undefined') {\n // C10: a new height is a new window, as well as new widths.\n this._resizeObserver = createRafResizeObserver(() => {\n this._syncHeaderWidths();\n this._virtUpdate();\n });\n this._resizeObserver.observe(this._wrapperEl);\n }\n // The header lives in its own non-scrolling wrap (so it can't\n // escape vertically), but that means it also won't follow the\n // body's HORIZONTAL scroll on its own \u2014 translate it to match.\n this._installHeaderScrollSync();\n // Drag-to-resize handles on each header cell. Only meaningful\n // when there are body rows to size against.\n if (rows.length > 0) this._installColumnResizers();\n }\n\n // Install interactions (readonly only prevents editing, not selection/copy)\n if (rows.length > 0 && (this.config.selectable || this.config.copyable || !this.config.readonly\n || typeof this.config.onRowActivate === 'function'\n || typeof this.config.rowDetail === 'function'\n || typeof this.config.onRowKeyDown === 'function'\n || this._cellGrid)) {\n this._installInteractions();\n }\n\n // Restore focus to filter input if it was active\n if (activeFilterColIdx !== null) {\n this._restoreFilterFocus(activeFilterColIdx);\n }\n else if (hadTableFocus && this._tableEl) {\n try { this._tableEl.focus({ preventScroll: true }); } catch (_) { /* detached */ }\n }\n else if (focus070) {\n this._restoreFocus070(focus070);\n }\n // 0.7.0. The words still being typed, and their debounce, which\n // `_cleanup` cleared.\n if (pendingFilter) this._resumePendingFilter(pendingFilter);\n\n // 0.7.0 `dataSource`: the first render asks for the first page; a\n // render while a request is out keeps the overlay up; following\n // resumes on a table drawn again.\n if (this.config.dataSource) {\n if (!this._source?.started) {\n this._sourceState().started = true;\n Promise.resolve().then(() => this._sourceLoad({ offset: 0, reason: 'initial' }));\n } else if (this._source.inFlight && !this._source.pendingAppend) {\n this.setLoading(true);\n }\n if (this._following && !this._followTimer) this._armFollow();\n }\n\n // STORY-0010. Last, so the hook reads the table as drawn.\n if (typeof this.config.onRender === 'function') {\n try { this.config.onRender(this); } catch (err) {\n console.error('[DataTable] onRender threw', err);\n }\n }\n }\n\n /**\n * Copy selected rows to clipboard \u2014 in cell mode (STORY-0085) the cells\n * selected, or the cursor cell alone, as tab-separated raw values with no\n * header line; cell mode has no CSV copy\n * @param {'tsv'|'csv'} [format='tsv'] - Output format\n */\n async copyToClipboard(format = 'tsv') {\n // STORY-0085. Cell mode copies the cells selected, not their rows,\n // and only as TSV.\n if (this._cellGrid) {\n if (format === 'csv') {\n console.warn('[DataTable] copyToClipboard: cell mode has no CSV copy; nothing copied');\n return;\n }\n return this._copyCells();\n }\n const indices = this.getSelection();\n if (indices.length === 0) {\n this._notify('Copy', 'No rows selected.', 'warn');\n return;\n }\n\n const { headers, rows } = this.config;\n // STORY-0012. The columns shown \u2014 all of them, unless some are hidden \u2014\n // and (STORY-0086) in the order shown.\n const matrix = [this._rowColumns(headers.length).map((c) => headers[c])];\n\n for (const idx of indices) {\n const row = rows[idx];\n if (row) {\n matrix.push(this._rowColumns(row.length).map((c) => this._formatValue(row[c], c)));\n }\n }\n\n const separator = format === 'csv' ? ',' : '\\t';\n const text = format === 'csv'\n ? matrix.map(row => row.map(cell => this._csvEscape(cell)).join(separator)).join('\\n')\n : matrix.map(row => row.join(separator)).join('\\n');\n\n let ok = false;\n try {\n await navigator.clipboard.writeText(text);\n ok = true;\n } catch (_) {\n ok = this._fallbackCopy(text);\n }\n\n if (ok) {\n const desc = indices.length === 1 ? 'row' : 'rows';\n const suffix = format === 'csv' ? ' as CSV' : '';\n this._notify('Copy', `Copied ${indices.length} ${desc}${suffix}.`, 'info');\n } else {\n this._notify('Copy', 'Clipboard unavailable.', 'warn');\n }\n\n this._hideContextMenu();\n }\n\n /**\n * STORY-0085. Cell mode's copy: the range (or the cursor cell alone), its\n * raw values as TSV \u2014 Excel's quoting, `tsv.js` \u2014 with no header line.\n */\n async _copyCells() {\n const matrix = this._cellGrid.copyMatrix();\n if (!matrix || !matrix.length) {\n this._notify('Copy', 'No cells selected.', 'warn');\n this._hideContextMenu();\n return;\n }\n const text = toTSV(matrix);\n let ok = false;\n try {\n await navigator.clipboard.writeText(text);\n ok = true;\n } catch (_) {\n ok = this._fallbackCopy(text);\n }\n if (ok) {\n const n = matrix.length;\n const m = matrix[0].length;\n const what = n * m === 1 ? '1 cell' : `${n} \u00D7 ${m} cells`;\n this._notify('Copy', `Copied ${what}.`, 'info');\n } else {\n this._notify('Copy', 'Clipboard unavailable.', 'warn');\n }\n this._hideContextMenu();\n }\n\n /**\n * Download all data as CSV\n * @param {string} [filename='data.csv'] - Filename for download\n */\n async downloadCSV(filename = 'data.csv') {\n const { headers, rows } = this.config;\n if (rows.length === 0) {\n this._notify('Download', 'No data to download.', 'warn');\n return;\n }\n\n const lines = [this._rowColumns(headers.length).map((c) => headers[c]).join(',')];\n for (const row of rows) {\n lines.push(this._rowColumns(row.length).map((c) =>\n this._csvEscape(this._formatValue(row[c], c))\n ).join(','));\n }\n\n const csv = lines.join('\\n');\n\n // Native save dialog when the embedder supplies one.\n //\n // `saveFile` resolves to null when a host advertises `dialogs` but its\n // transport has no save dialog behind it (host.js: null <=> unavailable).\n // That is NOT a failed save \u2014 it means \"I can't do this, use your own\n // way\", so it must reach the Blob fallback below, not the error toast.\n const dialogs = this.config.host?.dialogs;\n let result = null;\n if (dialogs) {\n try {\n // Send plain text CSV - Python handles text files directly (no base64)\n result = await dialogs.saveFile({ data: csv, filename, kind: 'csv' });\n } catch (err) {\n console.error('[DataTable] CSV download failed:', err);\n this._notify('Download', 'Failed to save file', 'error');\n return;\n }\n }\n if (result) {\n if (result.ok) {\n this._notify('Download', `Saved ${rows.length} rows to ${result.path}`, 'success');\n } else if (!result.cancelled) {\n this._notify('Download', result.error || 'Failed to save file', 'error');\n }\n return;\n }\n\n // Fallback: no `dialogs` capability at all, or a host that has one but\n // cannot actually save. Both mean \"download it yourself\".\n const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = filename;\n link.click();\n URL.revokeObjectURL(url);\n this._notify('Download', 'Download started', 'info');\n }\n\n /**\n * Dispose and cleanup. Empties the host, as it always has.\n */\n dispose() {\n this._teardown(true);\n }\n\n /**\n * 0.5.0 `autoDispose`'s dispose: everything `dispose()` lets go of \u2014 but of\n * the host, only the table's OWN wrapper. A table that has been taken out\n * of the page no longer owns its host: in the task before this runs, the\n * consumer may have mounted the next list into it, or written its own\n * message there, and emptying the host would wipe that.\n */\n _disposeOwn() {\n this._teardown(false);\n }\n\n _teardown(emptyHost) {\n // STORY-0003. An open editor goes, committing nothing.\n this._cellGrid?.dispose();\n // STORY-0066. And an open column renamer.\n this._tableStructure?.dispose();\n autoDisposeUnwatch(this);\n this._autoSeen = false;\n // 0.7.0. A grace still running, the follow timer, a request still out\n // (its answer must not draw into a disposed table), and the filter\n // controls (a picker may hang a menu on the body).\n if (this._autoTimer) { clearTimeout(this._autoTimer); this._autoTimer = null; }\n this._autoPending = false;\n this._disarmFollow();\n if (this._source) {\n this._source.ticket++;\n try { this._source.controller?.abort(); } catch (_) { /* gone */ }\n this._source.controller = null;\n this._source.inFlight = false;\n }\n this._destroyFilterControls();\n this._runOffs(this._activationOffs);\n this._activationOffs = [];\n this._cleanup();\n this._closeFilterDropdown();\n this._teardownContextMenu();\n if (this._resizeObserver) {\n try { this._resizeObserver.disconnect(); } catch (_) {}\n this._resizeObserver = null;\n }\n if (this._onBodyScroll && this._scrollSyncEl) {\n try {\n this._scrollSyncEl.removeEventListener('scroll', this._onBodyScroll);\n } catch (_) {}\n this._onBodyScroll = null;\n this._scrollSyncEl = null;\n }\n if (emptyHost) this.container.innerHTML = '';\n else this._wrapperEl?.remove();\n this._wrapperEl = null;\n this._paginationEl = null;\n this._tableEl = null;\n this._tbodyEl = null;\n this._headerTableEl = null;\n this._headerWrapEl = null;\n this._tableWrapEl = null;\n this._processedRows = null;\n this._processedIndexMap = null;\n this._virt = null;\n this._colgroupEl = null;\n }\n\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 // Processed rows pipeline (filter \u2192 sort \u2192 cache)\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 _getProcessedRows() {\n if (this._processedRows !== null) return this._processedRows;\n\n const isServerSide = this._isServerSide();\n let rows = this.config.rows;\n let indexMap = rows.map((_, i) => i);\n\n // Apply filters (client-side only)\n if (!isServerSide && this._state.filters.size > 0) {\n const result = this._applyFilters(rows, indexMap);\n rows = result.rows;\n indexMap = result.indexMap;\n }\n\n // Apply sort (client-side, only when no external onSort handler)\n if (!isServerSide && this.config.sortable && this._state.sortColumn !== null && !this.config.onSort) {\n const result = this._applySorting(rows, indexMap);\n rows = result.rows;\n indexMap = result.indexMap;\n }\n\n this._processedRows = rows;\n this._processedIndexMap = indexMap;\n return rows;\n }\n\n _applyFilters(rows, indexMap) {\n const filters = this._state.filters;\n const filteredRows = [];\n const filteredMap = [];\n // 0.7.0: each column's control rule, asked once rather than per row.\n const matchers = new Map();\n for (const colIdx of filters.keys()) matchers.set(colIdx, this._filterMatcher(colIdx));\n\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i];\n let pass = true;\n\n for (const [colIdx, filterText] of filters) {\n if (!filterText) continue;\n const value = row[colIdx];\n // 0.7.0 `filterKinds`: a control that is not a text box decides\n // by its own rule, over a value that need not be text.\n const kindMatch = matchers.get(colIdx);\n if (kindMatch) {\n if (this._isEmptyFilterValue(filterText)) continue;\n if (!kindMatch(value, filterText, row)) { pass = false; break; }\n continue;\n }\n const colType = this._valueKind(colIdx);\n\n if (colType === 'num') {\n if (!this._matchNumericFilter(value, filterText)) { pass = false; break; }\n } else if (colType === 'date' || colType === 'datetime') {\n // 0.5.0. By the TIME, with the drawn words as the fallback\n // for text that names no period.\n const utc = this._utc();\n if (!matchDateFilter(parseDateValue(value, { utc }), filterText,\n this._formatValue(value, colIdx), { utc })) {\n pass = false; break;\n }\n } else if (colType === 'duration') {\n if (!matchDurationFilter(parseDuration(value), filterText,\n this._formatValue(value, colIdx))) {\n pass = false; break;\n }\n } else {\n if (!this._matchTextFilter(value, filterText)) { pass = false; break; }\n }\n }\n\n if (pass) {\n filteredRows.push(row);\n filteredMap.push(indexMap[i]);\n }\n }\n\n return { rows: filteredRows, indexMap: filteredMap };\n }\n\n _applySorting(rows, indexMap) {\n const colIdx = this._state.sortColumn;\n const asc = this._state.sortAscending;\n\n // 0.5.0. A `sortValue` hook, or a column typed by its VALUE, sorts by a\n // key computed ONCE per row (a date is parsed once, not once per\n // comparison). Every other column takes the 0.4 comparator below,\n // untouched.\n const hook = this._sortValueFor(colIdx);\n const kind = this._valueKind(colIdx);\n if (hook || TYPED_COLUMNS.has(kind)) {\n const utc = this._utc();\n const keyOf = (row) => {\n const value = row[colIdx];\n if (hook) {\n const k = hook(value, colIdx, row);\n if (k !== undefined) return normaliseSortKey(k);\n }\n if (kind === 'date' || kind === 'datetime') {\n return normaliseSortKey(parseDateValue(value, { utc }));\n }\n if (kind === 'duration') return normaliseSortKey(parseDuration(value));\n if (kind === 'num') {\n return normaliseSortKey(typeof value === 'number' ? value : parseFloat(value));\n }\n return value == null ? null : String(value).toLowerCase();\n };\n const keyed = rows.map((row, i) => ({ row, origIdx: indexMap[i], key: keyOf(row) }));\n keyed.sort((a, b) => compareSortKeys(a.key, b.key, asc));\n return {\n rows: keyed.map((p) => p.row),\n indexMap: keyed.map((p) => p.origIdx),\n };\n }\n\n // Build paired array for stable sort with index tracking\n const paired = rows.map((row, i) => ({ row, origIdx: indexMap[i] }));\n const isNumeric = this._columnTypes[colIdx] === 'num';\n\n paired.sort((a, b) => {\n let valA = a.row[colIdx];\n let valB = b.row[colIdx];\n\n if (valA == null && valB == null) return 0;\n if (valA == null) return 1;\n if (valB == null) return -1;\n\n if (isNumeric) {\n valA = typeof valA === 'number' ? valA : parseFloat(valA);\n valB = typeof valB === 'number' ? valB : parseFloat(valB);\n if (!Number.isFinite(valA)) return 1;\n if (!Number.isFinite(valB)) return -1;\n } else {\n valA = String(valA).toLowerCase();\n valB = String(valB).toLowerCase();\n }\n\n let cmp = 0;\n if (valA < valB) cmp = -1;\n else if (valA > valB) cmp = 1;\n\n return asc ? cmp : -cmp;\n });\n\n return {\n rows: paired.map(p => p.row),\n indexMap: paired.map(p => p.origIdx),\n };\n }\n\n _matchNumericFilter(value, filterText) {\n const text = filterText.trim();\n if (!text) return true;\n\n const numVal = (typeof value === 'number') ? value : parseFloat(value);\n if (!Number.isFinite(numVal)) return false;\n\n // Range: \"10..100\"\n const rangeMatch = text.match(/^(-?[\\d.]+)\\.\\.(-?[\\d.]+)$/);\n if (rangeMatch) {\n const lo = parseFloat(rangeMatch[1]);\n const hi = parseFloat(rangeMatch[2]);\n return numVal >= lo && numVal <= hi;\n }\n\n // Operator prefix: >=, <=, !=, >, <, =\n const opMatch = text.match(/^(>=|<=|!=|>|<|=)\\s*(-?[\\d.]+)$/);\n if (opMatch) {\n const op = opMatch[1];\n const target = parseFloat(opMatch[2]);\n if (!Number.isFinite(target)) return true;\n switch (op) {\n case '>': return numVal > target;\n case '<': return numVal < target;\n case '>=': return numVal >= target;\n case '<=': return numVal <= target;\n case '!=': return Math.abs(numVal - target) > 1e-9;\n case '=': return Math.abs(numVal - target) <= 1e-9;\n }\n }\n\n // Plain number: equality\n const plain = parseFloat(text);\n if (Number.isFinite(plain)) {\n return Math.abs(numVal - plain) <= 1e-9;\n }\n\n return true;\n }\n\n _matchTextFilter(value, filterText) {\n if (!filterText) return true;\n const haystack = (value == null ? '' : String(value)).toLowerCase();\n const text = filterText.trim();\n\n // Exact match: =\"value\"\n if (text.startsWith('=\"') && text.endsWith('\"')) {\n return haystack === text.slice(2, -1).toLowerCase();\n }\n // Not contains: !value\n if (text.startsWith('!')) {\n return !haystack.includes(text.slice(1).toLowerCase());\n }\n // Starts with: ^value\n if (text.startsWith('^')) {\n return haystack.startsWith(text.slice(1).toLowerCase());\n }\n // Ends with: value$\n if (text.endsWith('$')) {\n return haystack.endsWith(text.slice(0, -1).toLowerCase());\n }\n // Contains (default)\n return haystack.includes(text.toLowerCase());\n }\n\n _invalidateProcessedCache() {\n this._processedRows = null;\n this._processedIndexMap = null;\n }\n\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 // Filter row\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 _createFilterRow(headers) {\n const { showRowNumbers } = this.config;\n const tr = document.createElement('tr');\n tr.className = 'twm-data-table__filter-row';\n\n if (this._gutter) {\n const th = document.createElement('th');\n th.className = 'data-table__filter-cell data-table__filter-cell--empty twm-dt-select-cell';\n tr.appendChild(th);\n }\n if (showRowNumbers) {\n const th = document.createElement('th');\n th.className = 'data-table__filter-cell data-table__filter-cell--empty';\n tr.appendChild(th);\n }\n\n this._shownColumns().forEach((colIdx) => {\n const header = headers[colIdx];\n const th = document.createElement('th');\n th.className = 'data-table__filter-cell';\n\n // 0.7.0 `filterKinds`: the consumer's (or the built-in chips')\n // control in place of the text box \u2014 the SAME element every render.\n const control = this._filterControlFor(colIdx, header);\n if (control) {\n th.classList.add('data-table__filter-cell--control');\n // The measuring pass keeps a row holding a control (its text\n // boxes stay out): see `_measureNaturalWidths`.\n tr.classList.add('twm-data-table__filter-row--controls');\n th.addEventListener('click', (e) => e.stopPropagation());\n if (control.el) th.appendChild(control.el);\n tr.appendChild(th);\n return;\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'twm-data-table__filter-wrapper';\n\n const input = document.createElement('input');\n input.type = 'text';\n input.className = 'twm-data-table__filter-input';\n const kind = this._valueKind(colIdx);\n input.placeholder = kind === 'num' ? 'e.g. >100'\n : kind === 'date' || kind === 'datetime' ? 'e.g. >2026-01-01'\n : kind === 'duration' ? 'e.g. >1s'\n : 'Filter...';\n\n // Restore existing filter value\n const existingFilter = this._state.filters.get(colIdx);\n if (existingFilter) {\n input.value = existingFilter;\n }\n\n // Dropdown trigger button\n const dropdownBtn = document.createElement('button');\n dropdownBtn.type = 'button';\n dropdownBtn.className = 'twm-data-table__filter-dropdown-btn';\n dropdownBtn.innerHTML = '<span class=\"material-symbols-outlined\" style=\"font-size:14px;\">tune</span>';\n dropdownBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this._openFilterDropdown(colIdx, th, input);\n });\n\n // Clear button\n const clearBtn = document.createElement('button');\n clearBtn.type = 'button';\n clearBtn.className = 'twm-data-table__filter-clear';\n clearBtn.innerHTML = '<span class=\"material-symbols-outlined\" style=\"font-size:12px;\">close</span>';\n clearBtn.style.display = existingFilter ? '' : 'none';\n clearBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n input.value = '';\n this._onFilterInput(colIdx, '');\n clearBtn.style.display = 'none';\n input.focus();\n });\n\n input.addEventListener('input', () => {\n clearBtn.style.display = input.value ? '' : 'none';\n this._onFilterInputDebounced(colIdx, input.value);\n });\n\n // Prevent sort from triggering when clicking in filter cell\n th.addEventListener('click', (e) => e.stopPropagation());\n\n wrapper.appendChild(input);\n wrapper.appendChild(dropdownBtn);\n wrapper.appendChild(clearBtn);\n th.appendChild(wrapper);\n tr.appendChild(th);\n });\n\n return tr;\n }\n\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 // Filter dropdown\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 _openFilterDropdown(colIdx, anchorEl, filterInput) {\n // Close any existing dropdown\n this._closeFilterDropdown();\n\n const kind = this._valueKind(colIdx);\n const isNumeric = kind === 'num';\n // 0.5.0. A date or a duration takes the numeric OPERATORS \u2014 before,\n // after, between \u2014 over operands typed as text (`2026-10`, `1.5s`).\n const isDate = kind === 'date' || kind === 'datetime';\n const isOrdered = isNumeric || isDate || kind === 'duration';\n const currentFilter = this._state.filters.get(colIdx) || '';\n const parsed = this._parseFilterForDropdown(currentFilter, isOrdered ? (isNumeric ? true : kind) : false);\n\n // Build dropdown panel\n const panel = document.createElement('div');\n panel.className = 'twm-data-table__filter-dropdown';\n\n // Operator/mode select\n const selectLabel = document.createElement('label');\n selectLabel.className = 'twm-data-table__filter-dropdown-label';\n selectLabel.textContent = isOrdered ? 'Operator' : 'Mode';\n\n const select = document.createElement('select');\n select.className = 'twm-data-table__filter-dropdown-select';\n\n const options = isDate\n ? [\n { value: '=', label: 'On / in' },\n { value: '!=', label: 'Not on / in' },\n { value: '>', label: 'After' },\n { value: '>=', label: 'On or after' },\n { value: '<', label: 'Before' },\n { value: '<=', label: 'On or before' },\n { value: '..', label: 'Between' },\n ]\n : isOrdered\n ? [\n { value: '=', label: 'Equals' },\n { value: '!=', label: 'Not equals' },\n { value: '>', label: 'Greater than' },\n { value: '>=', label: 'Greater or equal' },\n { value: '<', label: 'Less than' },\n { value: '<=', label: 'Less or equal' },\n { value: '..', label: 'Between' },\n ]\n : [\n { value: 'contains', label: 'Contains' },\n { value: 'equals', label: 'Equals' },\n { value: 'starts', label: 'Starts with' },\n { value: 'ends', label: 'Ends with' },\n { value: 'not', label: 'Not contains' },\n ];\n\n for (const opt of options) {\n const optEl = document.createElement('option');\n optEl.value = opt.value;\n optEl.textContent = opt.label;\n if (opt.value === parsed.operator) optEl.selected = true;\n select.appendChild(optEl);\n }\n\n // Value input\n const valueLabel = document.createElement('label');\n valueLabel.className = 'twm-data-table__filter-dropdown-label';\n valueLabel.textContent = 'Value';\n\n const operandPlaceholder = isNumeric ? 'Number...'\n : isDate ? 'YYYY-MM-DD' : isOrdered ? 'e.g. 1.5s' : 'Text...';\n const valueInput = document.createElement('input');\n valueInput.type = isNumeric ? 'number' : 'text';\n valueInput.className = 'twm-data-table__filter-dropdown-input';\n valueInput.placeholder = operandPlaceholder;\n valueInput.value = parsed.value;\n\n // Second value input (for \"between\")\n const value2Label = document.createElement('label');\n value2Label.className = 'twm-data-table__filter-dropdown-label';\n value2Label.textContent = 'And';\n\n const value2Input = document.createElement('input');\n value2Input.type = isOrdered && !isNumeric ? 'text' : 'number';\n value2Input.className = 'twm-data-table__filter-dropdown-input';\n value2Input.placeholder = isOrdered && !isNumeric ? operandPlaceholder : 'Number...';\n value2Input.value = parsed.value2;\n\n const value2Container = document.createElement('div');\n value2Container.className = 'twm-data-table__filter-dropdown-between';\n value2Container.style.display = (isOrdered && parsed.operator === '..') ? '' : 'none';\n value2Container.appendChild(value2Label);\n value2Container.appendChild(value2Input);\n\n // Toggle between fields when operator changes\n select.addEventListener('change', () => {\n value2Container.style.display = (isOrdered && select.value === '..') ? '' : 'none';\n });\n // What `_composeFilterString` is told: true for a number (0.4), the\n // kind for a date or a duration, false for text.\n const composeMode = isNumeric ? true : isOrdered ? kind : false;\n\n // Actions\n const actions = document.createElement('div');\n actions.className = 'twm-data-table__filter-dropdown-actions';\n\n const clearBtn = document.createElement('button');\n clearBtn.type = 'button';\n clearBtn.className = 'twm-data-table__filter-dropdown-btn-action twm-data-table__filter-dropdown-btn-action--clear';\n clearBtn.textContent = 'Clear';\n clearBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n filterInput.value = '';\n this._onFilterInput(colIdx, '');\n this._closeFilterDropdown();\n });\n\n const applyBtn = document.createElement('button');\n applyBtn.type = 'button';\n applyBtn.className = 'twm-data-table__filter-dropdown-btn-action twm-data-table__filter-dropdown-btn-action--apply';\n applyBtn.textContent = 'Apply';\n applyBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n const composed = this._composeFilterString(select.value, valueInput.value, value2Input.value, composeMode);\n filterInput.value = composed;\n this._onFilterInput(colIdx, composed);\n this._closeFilterDropdown();\n });\n\n actions.appendChild(clearBtn);\n actions.appendChild(applyBtn);\n\n // Assemble panel\n panel.appendChild(selectLabel);\n panel.appendChild(select);\n panel.appendChild(valueLabel);\n panel.appendChild(valueInput);\n panel.appendChild(value2Container);\n panel.appendChild(actions);\n\n // Add to document and position\n document.body.appendChild(panel);\n\n const anchorRect = anchorEl.getBoundingClientRect();\n let left = anchorRect.left;\n let top = anchorRect.bottom + 4;\n\n // Viewport boundary check\n const panelRect = panel.getBoundingClientRect();\n if (left + panelRect.width > window.innerWidth) {\n left = window.innerWidth - panelRect.width - 8;\n }\n if (top + panelRect.height > window.innerHeight) {\n top = anchorRect.top - panelRect.height - 4;\n }\n\n panel.style.left = `${left}px`;\n panel.style.top = `${top}px`;\n\n // Focus the value input\n requestAnimationFrame(() => valueInput.focus());\n\n // Close on outside click (capture phase)\n const handleOutsideClick = (e) => {\n if (!panel.contains(e.target)) {\n this._closeFilterDropdown();\n }\n };\n const handleEscape = (e) => {\n if (e.key === 'Escape') {\n this._closeFilterDropdown();\n }\n };\n // Enter key applies the filter\n const handleEnter = (e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n const composed = this._composeFilterString(select.value, valueInput.value, value2Input.value, composeMode);\n filterInput.value = composed;\n this._onFilterInput(colIdx, composed);\n this._closeFilterDropdown();\n }\n };\n\n // Delay attaching outside-click to avoid catching the trigger click\n setTimeout(() => {\n document.addEventListener('click', handleOutsideClick, true);\n }, 0);\n document.addEventListener('keydown', handleEscape);\n panel.addEventListener('keydown', handleEnter);\n\n this._filterDropdownEl = panel;\n this._filterDropdownCleanup = () => {\n document.removeEventListener('click', handleOutsideClick, true);\n document.removeEventListener('keydown', handleEscape);\n };\n }\n\n _closeFilterDropdown() {\n if (this._filterDropdownEl?.parentNode) {\n this._filterDropdownEl.parentNode.removeChild(this._filterDropdownEl);\n }\n this._filterDropdownCleanup?.();\n this._filterDropdownEl = null;\n this._filterDropdownCleanup = null;\n }\n\n _parseFilterForDropdown(filterText, isNumeric) {\n const text = (filterText || '').trim();\n if (!text) {\n return { operator: isNumeric ? '=' : 'contains', value: '', value2: '' };\n }\n\n // 0.5.0. A date or a duration (`isNumeric` is then the kind): the\n // numeric operators, over operands that are text.\n if (typeof isNumeric === 'string') {\n const range = text.match(/^(.+?)\\s*\\.\\.\\s*(.+)$/);\n if (range) return { operator: '..', value: range[1], value2: range[2] };\n const op = text.match(/^(>=|<=|!=|>|<|=)\\s*(.+)$/);\n if (op) return { operator: op[1], value: op[2], value2: '' };\n return { operator: '=', value: text, value2: '' };\n }\n\n if (isNumeric) {\n // Range: \"10..100\"\n const rangeMatch = text.match(/^(-?[\\d.]+)\\.\\.(-?[\\d.]+)$/);\n if (rangeMatch) {\n return { operator: '..', value: rangeMatch[1], value2: rangeMatch[2] };\n }\n // Operator prefix: >=, <=, !=, >, <, =\n const opMatch = text.match(/^(>=|<=|!=|>|<|=)\\s*(-?[\\d.]+)$/);\n if (opMatch) {\n return { operator: opMatch[1], value: opMatch[2], value2: '' };\n }\n // Plain number\n return { operator: '=', value: text, value2: '' };\n }\n\n // Text modes\n if (text.startsWith('=\"') && text.endsWith('\"')) {\n return { operator: 'equals', value: text.slice(2, -1), value2: '' };\n }\n if (text.startsWith('!')) {\n return { operator: 'not', value: text.slice(1), value2: '' };\n }\n if (text.startsWith('^')) {\n return { operator: 'starts', value: text.slice(1), value2: '' };\n }\n if (text.endsWith('$')) {\n return { operator: 'ends', value: text.slice(0, -1), value2: '' };\n }\n return { operator: 'contains', value: text, value2: '' };\n }\n\n _composeFilterString(operator, value, value2, isNumeric) {\n if (!value && operator !== '..') return '';\n\n // 0.5.0. A date or a duration keeps its `=`: an operand with no\n // operator is matched against the drawn words, not compared.\n if (typeof isNumeric === 'string') {\n if (operator === '..') return (value && value2) ? `${value}..${value2}` : '';\n return `${operator}${value}`;\n }\n\n if (isNumeric) {\n if (operator === '..') {\n return (value && value2) ? `${value}..${value2}` : '';\n }\n if (operator === '=') return value;\n return `${operator}${value}`;\n }\n\n // Text modes\n switch (operator) {\n case 'contains': return value;\n case 'equals': return value ? `=\"${value}\"` : '';\n case 'starts': return value ? `^${value}` : '';\n case 'ends': return value ? `${value}$` : '';\n case 'not': return value ? `!${value}` : '';\n default: return value;\n }\n }\n\n _onFilterInputDebounced(colIdx, value) {\n if (this._filterDebounceTimer) {\n clearTimeout(this._filterDebounceTimer);\n }\n // 0.7.0. What is waiting, so a render under `dataSource` (an answer\n // arriving mid-word) can put it back \u2014 see `_resumePendingFilter`.\n this._pendingFilter = { colIdx, value };\n this._filterDebounceTimer = setTimeout(() => {\n this._pendingFilter = null;\n this._onFilterInput(colIdx, value);\n }, 200);\n }\n\n _onFilterInput(colIdx, value) {\n if (this._stagedRefusal('A filter')) return;\n // 0.7.0. A filter value need not be text (a control's array, a range),\n // and an empty one of those is no filter. Text is judged as in 0.4.\n const empty = typeof value === 'string' ? !value : this._isEmptyFilterValue(value);\n if (!empty) {\n this._state.filters.set(colIdx, value);\n } else {\n this._state.filters.delete(colIdx);\n }\n this._pendingFilter = null;\n\n this._invalidateProcessedCache();\n this._state.offset = 0;\n this._state.selected.clear();\n this._state.anchorIndex = null;\n\n this._savePersisted();\n // 0.7.0. The column's control shows the value, and listeners hear it.\n const entry = this._filterControls.get(colIdx);\n if (entry) {\n try { entry.control.setValue?.(empty ? null : value); } catch (err) {\n console.error('[DataTable] filter control setValue threw', err);\n }\n }\n this._notifyFilterChange();\n // 0.7.0 `dataSource`: the server filters. Nothing to redraw until it\n // answers (the box shows what was typed); a control's own state\n // changed, so it repaints itself.\n if (this.config.dataSource) {\n this._sourceLoad({ offset: 0, reason: 'filter' });\n return;\n }\n this.render();\n }\n\n /** 0.7.0. Put back a filter that was still being typed when a render\n * rebuilt its box: the words, and the debounce that will apply them. */\n _resumePendingFilter({ colIdx, value }) {\n const filterRow = this._wrapperEl?.querySelector('.twm-data-table__filter-row');\n const cell = filterRow?.children[this._domIdxOf(colIdx)];\n const input = cell?.querySelector('.twm-data-table__filter-input');\n if (input && input.value !== value) {\n const focused = input.ownerDocument?.activeElement === input;\n input.value = value;\n const clear = cell.querySelector('.twm-data-table__filter-clear');\n if (clear) clear.style.display = value ? '' : 'none';\n if (focused) input.setSelectionRange(value.length, value.length);\n }\n this._onFilterInputDebounced(colIdx, value);\n }\n\n _getActiveFilterColIdx() {\n const active = document.activeElement;\n if (!active || !active.classList.contains('twm-data-table__filter-input')) return null;\n const cell = active.closest('.data-table__filter-cell');\n if (!cell) return null;\n const row = cell.parentElement;\n if (!row) return null;\n const cells = Array.from(row.children);\n const idx = cells.indexOf(cell);\n return this._dataIdxOfDom(idx);\n }\n\n _restoreFilterFocus(colIdx) {\n const filterRow = this._wrapperEl?.querySelector('.twm-data-table__filter-row');\n if (!filterRow) return;\n const cellIdx = this._domIdxOf(colIdx);\n const cell = filterRow.children[cellIdx];\n const input = cell?.querySelector('.twm-data-table__filter-input');\n if (input) {\n input.focus();\n input.setSelectionRange(input.value.length, input.value.length);\n }\n }\n\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 // Private methods\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 /** Run (and forget) a list of removers. */\n _runOffs(offs) {\n for (const off of offs || []) {\n try { off?.(); } catch (_) { /* already gone */ }\n }\n }\n\n /**\n * 0.5.0. A render takes `onRowActivate`'s listeners off the body it is\n * replacing ONE TASK LATER, not now. The render may be running INSIDE the\n * very click that is about to open a row \u2014 an `onSelectionChange` that calls\n * `setData`, an `onRowClick` that calls `render` \u2014 and a listener removed\n * during its own event's dispatch is skipped: the row silently did not\n * open. The event's path was fixed when it was dispatched, so it still\n * reaches the old body, whose listener opens the row that was pressed. The\n * old body is out of the page, so nothing else can reach it meanwhile.\n */\n _retireActivation() {\n const offs = this._activationOffs;\n this._activationOffs = [];\n if (offs.length) setTimeout(() => this._runOffs(offs), 0);\n }\n\n _cleanup() {\n this._disposers.forEach(dispose => {\n try { dispose?.(); } catch (_) {}\n });\n this._disposers = [];\n this._closeFilterDropdown();\n if (this._filterDebounceTimer) {\n clearTimeout(this._filterDebounceTimer);\n this._filterDebounceTimer = null;\n }\n }\n\n _detectColumnTypes() {\n const { headers, rows, getColumnType, columnTypes } = this.config;\n const types = [];\n\n for (let colIdx = 0; colIdx < headers.length; colIdx++) {\n // 0.5.0. A type declared by position wins over the callback and\n // over detection \u2014 which never guesses a date: typing one is a\n // decision about how it is drawn.\n const declared = Array.isArray(columnTypes) ? columnTypes[colIdx] : null;\n if (declared) {\n types.push(declared);\n continue;\n }\n if (getColumnType) {\n types.push(getColumnType(colIdx, rows));\n continue;\n }\n\n // Auto-detect by sampling first 10 rows\n let numericCount = 0;\n let sampleCount = 0;\n const maxSamples = Math.min(10, rows.length);\n\n for (let i = 0; i < maxSamples; i++) {\n const value = rows[i]?.[colIdx];\n if (value != null && value !== '') {\n sampleCount++;\n if (typeof value === 'number' || /^-?[\\d,.]+%?$/.test(String(value).trim())) {\n numericCount++;\n }\n }\n }\n\n types.push(sampleCount > 0 && numericCount / sampleCount > 0.5 ? 'num' : 'text');\n }\n\n return types;\n }\n\n _createPagination() {\n // 0.7.0. Any of the new pager's options takes the new pager, which\n // draws the 0.6 strip's words for a known total and something honest\n // for an unknown one. Without them, the 0.6 strip below, untouched.\n if (this._usesPager070()) return this._createPager070();\n const { rows, pageSize, totalCount: configTotalCount, offset: configOffset, onPageChange, onJumpToRow } = this.config;\n\n // Server-side pagination uses config offset, client-side uses state offset\n const isServerSide = typeof onPageChange === 'function';\n const offset = isServerSide ? (configOffset || 0) : this._state.offset;\n\n // For client-side, use processed (filtered+sorted) row count\n const processedRows = isServerSide ? rows : this._getProcessedRows();\n const effectiveTotal = isServerSide ? (configTotalCount || rows.length) : processedRows.length;\n const unfilteredTotal = isServerSide ? (configTotalCount || rows.length) : rows.length;\n const isFiltered = !isServerSide && this._state.filters.size > 0;\n\n const displayedRows = isServerSide ? rows.length : Math.min(pageSize, effectiveTotal - offset);\n const endRow = Math.min(offset + displayedRows, effectiveTotal);\n const totalPages = Math.max(1, Math.ceil(effectiveTotal / pageSize));\n // Don't render the strip when there's only one page \u2014 the row\n // count is uninformative (the table itself shows every row) and\n // the nav buttons would all be disabled.\n if (totalPages <= 1 && !isFiltered) return this._createExportOnlyStrip();\n const currentPage = Math.floor(offset / pageSize) + 1;\n const hasPrev = offset > 0;\n const hasNext = offset + pageSize < effectiveTotal;\n\n const el = document.createElement('div');\n el.className = 'twm-pagination-controls';\n el.style.cssText = 'display:flex; align-items:center; gap:6px; padding:2px 8px; border-bottom:1px solid #2a2a2a; font-size:11px;';\n\n // Info\n const info = document.createElement('span');\n info.style.cssText = 'color:#aaa; white-space:nowrap;';\n if (effectiveTotal === 0) {\n info.textContent = isFiltered\n ? `0 of ${unfilteredTotal.toLocaleString()} rows match`\n : 'No rows';\n } else if (isFiltered) {\n info.textContent = `Rows ${offset + 1}\\u2013${endRow} of ${effectiveTotal.toLocaleString()} (${unfilteredTotal.toLocaleString()} total)`;\n } else {\n info.textContent = `Rows ${offset + 1}\\u2013${endRow} of ${effectiveTotal.toLocaleString()}`;\n }\n\n // Spacer\n const spacer = document.createElement('div');\n spacer.style.flex = '1';\n\n // Page change handler - supports both client-side and server-side pagination\n const handlePageChange = (newOffset) => {\n if (this._stagedRefusal('Turning the page')) return;\n if (isServerSide) {\n // Auto-spinner if the consumer returns a Promise.\n this._awaitWithSpinner(onPageChange(newOffset, pageSize));\n } else {\n this._state.offset = newOffset;\n this._savePage();\n this.render();\n }\n };\n\n // Navigation buttons\n const firstBtn = this._createPaginationBtn('first_page', 'First page', !hasPrev, () => {\n handlePageChange(0);\n });\n\n const prevBtn = this._createPaginationBtn('chevron_left', 'Previous page', !hasPrev, () => {\n handlePageChange(Math.max(0, offset - pageSize));\n });\n\n const pageInfo = document.createElement('span');\n pageInfo.style.cssText = 'color:#aaa; font-size:10px; min-width:72px; text-align:center;';\n pageInfo.textContent = `Page ${currentPage} of ${totalPages}`;\n\n const nextBtn = this._createPaginationBtn('chevron_right', 'Next page', !hasNext, () => {\n handlePageChange(offset + pageSize);\n });\n\n const lastBtn = this._createPaginationBtn('last_page', 'Last page', !hasNext, () => {\n handlePageChange(Math.floor((effectiveTotal - 1) / pageSize) * pageSize);\n });\n\n // Jump to row\n const jumpInput = document.createElement('input');\n jumpInput.type = 'number';\n jumpInput.className = 'twm-pagination-input';\n jumpInput.style.cssText = 'width:54px; padding:1px 4px; border:1px solid #444; background:#2a2a2a; color:#ccc; font-size:10px;';\n jumpInput.min = '1';\n jumpInput.max = String(effectiveTotal);\n jumpInput.placeholder = 'Row #';\n\n const jumpBtn = this._createPaginationBtn(null, 'Go to row', false, () => {\n const target = Number(jumpInput.value);\n if (Number.isFinite(target) && target >= 1) {\n if (isServerSide && onJumpToRow) {\n onJumpToRow(target - 1);\n } else if (isServerSide) {\n // Default: calculate page offset for the target row\n const newOffset = Math.floor((target - 1) / pageSize) * pageSize;\n handlePageChange(newOffset);\n } else {\n this.goToRow(target - 1);\n }\n }\n }, 'Go');\n\n el.appendChild(info);\n el.appendChild(spacer);\n el.appendChild(firstBtn);\n el.appendChild(prevBtn);\n el.appendChild(pageInfo);\n el.appendChild(nextBtn);\n el.appendChild(lastBtn);\n el.appendChild(jumpInput);\n el.appendChild(jumpBtn);\n\n // CSV export button (opt-in). Re-uses the existing downloadCSV\n // method which already handles the host save dialog + browser\n // fallback.\n if (this.config.showExportButton) el.appendChild(this._createExportBtn());\n\n return el;\n }\n\n /** The export button: downloadCSV() under the configured file name. */\n _createExportBtn() {\n const name = this.config.exportFilename;\n const filename = (typeof name === 'function' ? name(this) : name) || 'data.csv';\n const btn = this._createPaginationBtn('download', 'Download visible rows as CSV', false,\n () => this.downloadCSV(filename));\n // STORY-0088. Moves no rows, so a staged edit's freeze leaves it be.\n btn.classList.add('twm-pagination-btn--export');\n return btn;\n }\n\n /**\n * The strip on a table with one page: nothing, as always, unless the export\n * button needs somewhere to be. Then the button alone, with no page\n * buttons (0.14.1).\n */\n _createExportOnlyStrip() {\n if (!this.config.showExportButton) return null;\n const el = document.createElement('div');\n el.className = 'twm-pagination-controls twm-pagination-controls--export-only';\n el.style.cssText = 'display:flex; align-items:center; gap:6px; padding:2px 8px; border-bottom:1px solid #2a2a2a; font-size:11px;';\n const spacer = document.createElement('div');\n spacer.style.flex = '1';\n el.append(spacer, this._createExportBtn());\n return el;\n }\n\n _createPaginationBtn(icon, tooltip, disabled, onClick, textLabel = null) {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = 'hoverbutton twm-pagination-btn twm-has-tooltip';\n btn.setAttribute('data-tooltip', tooltip);\n btn.disabled = disabled;\n btn.style.cssText = 'padding:1px 3px; background:transparent; border:1px solid #444; color:#aaa; cursor:pointer; display:flex; align-items:center; justify-content:center; line-height:1;';\n\n if (disabled) {\n btn.style.opacity = '0.4';\n btn.style.cursor = 'not-allowed';\n }\n\n if (icon) {\n const iconEl = document.createElement('span');\n iconEl.className = 'material-symbols-outlined';\n iconEl.style.fontSize = '14px';\n iconEl.textContent = icon;\n btn.appendChild(iconEl);\n } else if (textLabel) {\n btn.textContent = textLabel;\n btn.style.fontSize = '10px';\n btn.style.padding = '1px 6px';\n }\n\n btn.addEventListener('click', onClick);\n return btn;\n }\n\n // \u2500\u2500 `paging` \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 `paging` config with its defaults, or null when it is not set. */\n _pagingConfig() {\n const p = this.config.paging;\n if (!p || typeof p !== 'object') return null;\n const size = Number.isFinite(p.pageSize) && p.pageSize >= 1\n ? Math.floor(p.pageSize) : this.config.pageSize;\n // 0.7.0 \u2014 `paging` OVER A `dataSource`. ONE STRIP, ONE SET OF RULES:\n // the facts the 0.6.2 consumer hands in (`offset`, `total`, `hasMore`,\n // the rows held) are the source's last answer here, and the four\n // callbacks the consumer would write are the table's own \u2014 a page turn,\n // the next rows, all of them, the other mode \u2014 so the strip, the soft\n // and hard limits, the busy state and the load-near-the-end trigger are\n // the same code with or without a server the table asks itself.\n if (this.config.dataSource) {\n const src = this._source || { offset: 0, total: null, atLeast: 0, hasMore: false };\n return {\n ...p,\n pageSize: size,\n offset: src.offset || 0,\n held: this.config.rows?.length || 0,\n total: src.total,\n atLeast: src.atLeast || 0,\n hasMore: !!src.hasMore,\n loadMorePx: Number.isFinite(p.loadMorePx) ? p.loadMorePx : PAGING_LOAD_MORE_PX,\n onPage: (offset) => this._sourceGoTo(offset),\n onLoadMore: () => this._sourceLoadMore(),\n onLoadAll: () => this._sourceLoadAll(),\n // The switch is drawn, as in 0.6.2, only for a consumer that\n // listens; the table switches and then tells it.\n onModeChange: typeof p.onModeChange === 'function'\n ? (mode) => this._sourceSetMode(mode) : undefined,\n };\n }\n return {\n ...p,\n pageSize: size,\n offset: Number.isFinite(p.offset) && p.offset > 0 ? Math.floor(p.offset) : 0,\n // What the table holds of the source. A consumer whose `rows` carry\n // a row the source does not (a blank line to type into) says so.\n held: Number.isFinite(p.held) ? p.held : (this.config.rows?.length || 0),\n hasMore: !!p.hasMore,\n loadMorePx: Number.isFinite(p.loadMorePx) ? p.loadMorePx : PAGING_LOAD_MORE_PX,\n };\n }\n\n /**\n * Which way the rows are shown, and why \u2014 `resolvePaging` over this\n * table's facts. `null` without `paging`.\n */\n get pagingState() {\n const p = this._pagingConfig();\n if (!p) return null;\n // A page's rows prove the source holds every row before them too, so\n // what is PROVEN is the offset plus the rows held.\n return resolvePaging({\n mode: p.mode, total: p.total, atLeast: p.atLeast, held: p.offset + p.held,\n hasMore: p.hasMore, softLimit: p.softLimit, hardLimit: p.hardLimit,\n });\n }\n\n /**\n * Change some `paging` facts \u2014 a count that arrived, a mode \u2014 and redraw\n * the STRIP only. The rows are not touched: a consumer with new rows\n * renders the table as it always has.\n */\n setPaging(patch = {}) {\n if (!this.config.paging) return;\n const before = this.config.dataSource ? this.pagingState?.mode : null;\n this.config.paging = { ...this.config.paging, ...patch };\n // 0.7.0: over a `dataSource` the rows held are the table's, so a patch\n // that changes which way they are shown asks again from the start \u2014\n // a list scrolled to 3,000 rows is not page 1.\n if (before && this.pagingState?.mode !== before) {\n this._sourceLoad({ offset: 0, reason: 'mode' });\n return;\n }\n this._refreshPagingStrip();\n this._pagingMaybeLoadMore();\n }\n\n _refreshPagingStrip() {\n if (!this._wrapperEl) return;\n const next = this._pagingConfig() ? this._createPagingStrip() : null;\n const prev = this._pagingEl;\n if (prev && prev.parentNode === this._wrapperEl) {\n if (next) prev.replaceWith(next); else prev.remove();\n } else if (next) {\n this._wrapperEl.appendChild(next);\n }\n this._pagingEl = next;\n this._cellGrid?.staged?.paintFreeze(); // STORY-0088\n }\n\n /**\n * Call one of the consumer's paging callbacks. A Promise holds every other\n * paging call back until it settles, and the strip shows the table busy \u2014\n * a second `onLoadMore` fired by the next scroll event would fetch the same\n * page twice.\n */\n _pagingCall(kind, fn, ...args) {\n if (typeof fn !== 'function' || this._pagingBusy) return;\n if (this._stagedRefusal(`paging ${kind}`)) return;\n let result;\n try {\n result = fn(...args);\n } catch (err) {\n console.error(`[DataTable] paging ${kind} threw`, err);\n return;\n }\n if (result && typeof result.then === 'function') {\n this._pagingBusy = kind;\n this._refreshPagingStrip();\n const settle = () => {\n if (this._pagingBusy !== kind) return;\n this._pagingBusy = null;\n if (this._pagingEl?.isConnected) this._refreshPagingStrip();\n };\n result.then(settle, (err) => {\n console.error(`[DataTable] paging ${kind} failed`, err);\n settle();\n });\n }\n }\n\n /**\n * Scrolling: ask for the next rows when the body is near its end \u2014 or does\n * not fill its box, which no scroll can ever change. Never past the hard\n * limit, never in pages, never with no layout (a hidden table's box is 0px\n * tall, and \"0 \u2264 0\" would ask for the whole source).\n */\n _pagingMaybeLoadMore() {\n const p = this._pagingConfig();\n if (!p || !p.hasMore || this._pagingBusy) return;\n // STORY-0088. Paging is held while cells are staged \u2014 quietly here:\n // a scroll is not a click on a control that could say why.\n if (this._cellGrid?.staged?.freezeReason()) return;\n // 0.7.0: not while the source is answering another question (a sort, a\n // filter, a refresh) \u2014 those rows are about to be replaced.\n if (this.config.dataSource && this._source?.inFlight) return;\n const state = this.pagingState;\n if (state.mode !== 'scroll' || p.held >= state.hardLimit) return;\n const wrap = this._tableWrapEl;\n if (!wrap?.isConnected || !(wrap.clientHeight > 0)) return;\n const remaining = wrap.scrollHeight - wrap.scrollTop - wrap.clientHeight;\n if (remaining >= p.loadMorePx) return;\n this._pagingCall('more', p.onLoadMore);\n }\n\n /** The strip under the body, or null when it would say nothing. */\n _createPagingStrip() {\n const p = this._pagingConfig();\n const state = this.pagingState;\n const { mode, forced, exact, known } = state;\n const busy = this._pagingBusy;\n const n = (x) => Number(x).toLocaleString();\n const pageSize = p.pageSize;\n const held = p.held;\n const total = exact ? p.total : null;\n\n const morePages = p.offset > 0 || p.hasMore || (exact && total > held);\n if (!forced && mode === 'scroll' && !p.hasMore && held <= pageSize) return null;\n if (!forced && mode === 'pages' && !morePages) return null;\n\n const el = document.createElement('div');\n el.className = `twm-dt-paging twm-dt-paging--${mode}`;\n el.setAttribute('role', 'navigation');\n el.setAttribute('aria-label', 'Rows');\n if (busy) el.classList.add('twm-dt-paging--busy');\n\n const info = document.createElement('span');\n info.className = 'twm-dt-paging__info';\n el.appendChild(info);\n\n if (mode === 'pages') {\n const from = held ? p.offset + 1 : p.offset;\n const to = p.offset + held;\n let of = '';\n if (exact) of = ` of ${n(total)}`;\n else if (known > to) of = ` of more than ${n(known - 1)}`;\n info.textContent = held ? `Rows ${n(from)}\u2013${n(to)}${of}` : 'No rows on this page';\n\n // The same page arithmetic as the pager above the rows (`_pageNav`).\n const pn = this._pageNav({ offset: p.offset, held, total, hasMore: p.hasMore, pageSize });\n const { hasPrev, hasNext } = pn;\n const lastOffset = exact && total > 0 ? pn.lastOffset : null;\n // A disabled button's click is ignored here too: a browser sends none,\n // but a synthetic one (a test, a script) still reaches the listener.\n const go = (offset) => (ev) => {\n if (!ev?.currentTarget?.disabled) this._pagingCall('page', p.onPage, offset, pageSize);\n };\n const nav = document.createElement('span');\n nav.className = 'twm-dt-paging__nav';\n const off = !!busy || typeof p.onPage !== 'function';\n // 0.7.0: with the new pager's options (`pagerLabels`,\n // `maxJumpOffset`, or a `dataSource`) the strip's buttons are the\n // new pager's \u2014 words beside the icons, and a refusal said on the\n // control. Without them, exactly the 0.6.2 buttons.\n const words = this._usesPager070();\n const button = (icon, name, tip, disabled, onClick, refusal = null) => (words\n ? this._pagerButton(icon, name, tip, disabled, onClick, refusal)\n : this._createPaginationBtn(icon, tip, disabled, onClick));\n nav.append(\n button('first_page', 'first', 'First page', off || !hasPrev, go(0)),\n button('chevron_left', 'prev', 'Previous page', off || !hasPrev,\n go(Math.max(0, p.offset - pageSize))),\n );\n const page = document.createElement('span');\n page.className = 'twm-dt-paging__page';\n page.textContent = exact\n ? `Page ${n(pn.page)} of ${n(pn.pages)}`\n : `Page ${n(pn.page)}`;\n nav.append(\n page,\n button('chevron_right', 'next', 'Next page', off || !hasNext,\n go(p.offset + pageSize)),\n // The last page needs the exact count: without it there is no\n // offset to go to, and the button says so by being off.\n words\n ? button('last_page', 'last', 'Last page', off || !hasNext || lastOffset === null,\n go(lastOffset), pn.lastRefusal)\n : button('last_page', 'last',\n lastOffset === null ? 'Last page (the total is not known)' : 'Last page',\n off || !hasNext || lastOffset === null, go(lastOffset)),\n );\n el.appendChild(nav);\n } else {\n if (exact && total > held) info.textContent = `${n(held)} of ${n(total)} rows`;\n else if (p.hasMore) info.textContent = `${n(held)} rows, more to come`;\n else info.textContent = `${n(held)} rows`;\n if (p.hasMore && typeof p.onLoadAll === 'function') {\n const all = document.createElement('button');\n all.type = 'button';\n all.className = 'twm-dt-paging__all';\n all.textContent = busy === 'all' ? 'Loading\u2026'\n : exact ? `Load all ${n(total)} rows` : 'Load all rows';\n all.disabled = !!busy;\n all.addEventListener('click', () => {\n if (!all.disabled) this._pagingCall('all', p.onLoadAll);\n });\n el.appendChild(all);\n }\n }\n\n const spacer = document.createElement('span');\n spacer.className = 'twm-dt-paging__spacer';\n el.appendChild(spacer);\n\n // WHY IT IS PAGED, said on the strip \u2014 a disabled Scroll alone reads as\n // a switch that does not work.\n const why = forced\n ? `More than ${n(state.softLimit)} rows, so they are shown in pages.` : null;\n if (why) {\n const note = document.createElement('span');\n note.className = 'twm-dt-paging__note';\n note.textContent = why;\n el.appendChild(note);\n }\n\n if (typeof p.onModeChange === 'function') {\n const group = document.createElement('span');\n group.className = 'twm-dt-paging__modes';\n group.setAttribute('role', 'group');\n group.setAttribute('aria-label', 'Show rows');\n for (const [value, label] of [['pages', 'Pages'], ['scroll', 'Scroll']]) {\n const b = document.createElement('button');\n b.type = 'button';\n b.className = 'twm-dt-paging__mode';\n b.dataset.mode = value;\n b.textContent = label;\n const pressed = mode === value;\n b.setAttribute('aria-pressed', String(pressed));\n b.disabled = !!busy || (value === 'scroll' && forced);\n if (value === 'scroll' && forced) b.title = why;\n b.addEventListener('click', () => {\n if (!b.disabled && mode !== value) this._pagingCall('mode', p.onModeChange, value);\n });\n group.appendChild(b);\n }\n el.appendChild(group);\n }\n return el;\n }\n\n _createTable() {\n const { headers, rows, pageSize, sortable, filterable, showRowNumbers, readonly, getHeaderIcon } = this.config;\n const { sortColumn, sortAscending } = this._state;\n // 0.7.0 `dataSource`: a row's index is its place in the page drawn\n // (`config.rows`), so every lookup by index \u2014 selection, copy,\n // `updateRow` \u2014 reads the row it means on any page. The page's offset\n // is the server's, and only numbers the rows.\n const configOffset = this.config.dataSource ? 0 : this.config.offset;\n\n // Server-side pagination: rows already represent current page, use config offset for row numbering\n // Client-side pagination: use processed (filtered+sorted) rows, then slice for current page\n const isServerSide = this._isServerSide();\n const processedRows = isServerSide ? rows : this._getProcessedRows();\n const offset = isServerSide ? (configOffset || 0) : this._state.offset;\n // NO PAGINATION MEANS NO PAGES. This used to slice to `pageSize` either\n // way, so a table built with `pagination: false` silently showed its\n // first hundred rows and offered no control to reach the rest.\n // And `paging` rows ARE the page (or everything scrolled to so far):\n // the consumer fetched them, and slicing them again would draw a\n // hundred of a thousand.\n const pageRows = isServerSide || !this.config.pagination || this._pagingConfig()\n ? processedRows : processedRows.slice(offset, offset + pageSize);\n // STORY-0003. Where the rows drawn stand in the order shown.\n this._pageSpan = {\n start: pageRows === processedRows ? 0 : offset,\n count: pageRows.length,\n };\n\n const table = document.createElement('table');\n table.className = this._tableClassName();\n table.tabIndex = 0;\n\n // Header\n const thead = document.createElement('thead');\n const headerRow = document.createElement('tr');\n\n if (this._gutter) headerRow.appendChild(this._buildSelectHead());\n if (showRowNumbers) {\n const th = document.createElement('th');\n th.className = 'num';\n th.textContent = '#';\n headerRow.appendChild(th);\n }\n\n this._shownColumns().forEach((colIdx) => {\n const header = headers[colIdx];\n const th = document.createElement('th');\n th.className = this._columnTypes[colIdx] || 'text';\n\n if (sortable) {\n th.classList.add('sortable');\n th.style.cursor = 'pointer';\n }\n\n // Header icon\n if (getHeaderIcon) {\n const iconInfo = getHeaderIcon(header, colIdx);\n if (iconInfo) {\n const iconSpan = document.createElement('span');\n iconSpan.className = 'material-symbols-outlined twm-header-icon twm-has-tooltip';\n iconSpan.setAttribute('data-tooltip', iconInfo.title || '');\n iconSpan.style.cssText = 'font-size:16px; vertical-align:middle; margin-right:4px; opacity:0.7;';\n iconSpan.textContent = iconInfo.icon;\n th.appendChild(iconSpan);\n }\n }\n\n th.appendChild(document.createTextNode(header));\n\n // Sort indicator\n if (sortable) {\n const sortIcon = document.createElement('span');\n sortIcon.className = 'material-symbols-outlined twm-sort-icon';\n sortIcon.style.cssText = 'font-size:14px; margin-left:4px; opacity:0.5;';\n if (sortColumn === colIdx) {\n sortIcon.textContent = sortAscending ? 'arrow_upward' : 'arrow_downward';\n sortIcon.style.opacity = '1';\n } else {\n sortIcon.textContent = 'unfold_more';\n }\n th.appendChild(sortIcon);\n\n th.addEventListener('click', () => this.sortBy(colIdx));\n }\n\n th.title = header;\n headerRow.appendChild(th);\n });\n\n thead.appendChild(headerRow);\n\n // Filter row (below header)\n if (filterable) {\n const filterRow = this._createFilterRow(headers);\n thead.appendChild(filterRow);\n }\n\n // C10. THE COLUMN TRACK IS A `<colgroup>`, NOT THE FIRST ROW. Under\n // `table-layout: fixed` a `<col>` with a width decides its column, and a\n // first-row cell only decides one whose `<col>` is `auto` \u2014 so once the\n // widths live here, it stops mattering which row is first. A recycling\n // window changes that row on every scroll; without this the columns\n // would jitter each time it did. Before the `thead`, where the content\n // model puts it; the `thead` leaves for the header table in `render()`\n // and the colgroup stays with the body.\n const virtual = this._isVirtual();\n if (virtual) {\n table.classList.add('twm-dt--virtual');\n table.appendChild(this._createColgroup());\n }\n\n table.appendChild(thead);\n\n // Map back to original config.rows index for selection tracking\n const globalOf = (localIdx) => {\n const processedIdx = offset + localIdx;\n return isServerSide\n ? (configOffset || 0) + localIdx\n : (this._processedIndexMap?.[processedIdx] ?? processedIdx);\n };\n\n // 0.5.0 `showRowNumbers: 'position'`: where the first row drawn here\n // stands in the order SHOWN (the page's first row on a later page).\n this._positionBase = this.config.dataSource ? (this._source?.offset || 0)\n : isServerSide ? (configOffset || 0)\n : (this.config.pagination ? offset : 0);\n // `paging`: a page's rows stand at its offset in the SOURCE, which only\n // the numbering reads \u2014 their indexes stay those of `rows`. Over a\n // `dataSource` that offset IS the source's, counted above once.\n const paged = this.config.dataSource ? null : this._pagingConfig();\n if (paged && Number.isFinite(paged.offset)) this._positionBase += paged.offset;\n\n // Body\n const tbody = document.createElement('tbody');\n table.appendChild(tbody);\n this._tbodyEl = tbody;\n\n if (virtual) {\n this._virtInit(tbody, pageRows, globalOf, {\n serverSide: isServerSide, offset, configOffset: configOffset || 0,\n });\n } else {\n pageRows.forEach((row, localIdx) => {\n const tr = this._buildBodyRow(row, globalOf(localIdx), localIdx);\n tbody.appendChild(tr);\n // 0.7.0 `rowDetail`: an open detail goes in right under its row.\n if (this._detailOn()) this._appendDetailIfOpen(tr, null);\n });\n }\n\n return table;\n }\n\n /** One body row, fully built. The ONE place a `<tr>` for a row is made, so\n * the full render and the virtual window cannot drift apart: a row drawn\n * on scroll is the same row a render would have drawn. */\n _buildBodyRow(row, globalIdx, localIdx) {\n const { showRowNumbers } = this.config;\n const tr = document.createElement('tr');\n tr.__rowIndex = globalIdx;\n // 0.5.0. The row's place in the order shown (for 'position' numbers).\n tr.__position = (this._positionBase || 0) + localIdx;\n tr.className = 'data-preview-row';\n // STORY-0003. The row's position in the order shown, for cell mode.\n if (this._cellGrid) tr.__cellPos = (this._pageSpan?.start || 0) + localIdx;\n\n // STORY-0003. In cell mode the CELLS are lit, not the rows.\n if (this._state.selected.has(globalIdx) && !this._cellGrid) {\n tr.classList.add('selected');\n }\n // 0.5.0. The consumer's row classes and attributes, and the open mark.\n this._decorateRow(tr, row, globalIdx);\n // C10. The stripe is `tr:nth-child(even)`, which is a question about a\n // row's POSITION among its siblings \u2014 and a window that drops rows off\n // its top changes every answer. `_virtSpacers` keeps the position's\n // parity equal to the row's own, so the stripe needs nothing here; the\n // class is for an embedder that wants to ask about the row itself.\n if (this._virt) tr.classList.toggle('twm-dt-row--alt', localIdx % 2 === 1);\n\n this._fillRowCells(tr, row, globalIdx, showRowNumbers);\n\n // Row-level click + right-click hooks (P2). Bound after\n // cells so per-cell handlers run first.\n if (this.config.onRowClick) {\n tr.addEventListener('click', (ev) => {\n this.config.onRowClick(globalIdx, row, ev);\n });\n }\n if (this.config.onRowContextMenu) {\n tr.addEventListener('contextmenu', (ev) => {\n this.config.onRowContextMenu(globalIdx, row, ev);\n });\n }\n return tr;\n }\n\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 // C10 \u2014 the virtual window\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 // \u2550\u2550 WHAT IT IS \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\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 // Only the rows near the viewport are in the DOM: a TOP SPACER row whose\n // height is every row above the window, the window's rows, and a BOTTOM\n // SPACER for everything below it. The scrollbar is therefore sized to the\n // whole table and every row is reachable, while the DOM stays bounded by\n // the viewport \u2014 a thousand-row page (or fifty of them) costs the same\n // few dozen `<tr>`s as one screenful.\n //\n // \u2550\u2550 WHAT IT PROMISES \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\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 row that stays in the window is NEVER MOVED OR REBUILT when the\n // window slides. Rows leave from the edges and arrive at the edges; the\n // ones in the middle are the same nodes. An open editor, a focused\n // cell, a hover \u2014 anything living in a row that is still on screen \u2014\n // survives a scroll. (Moving a node that holds focus blurs it, which in\n // an editable grid is a commit nobody asked for.)\n // - Column widths come from a `<colgroup>`, so the first row changing\n // moves nothing (see `_createTable`).\n // - A spacer is in the DOM only while it has a height. A table that fits\n // in its window has exactly the DOM it had without `virtualize`.\n // - `onRowsRendered` hears about every row added after `render()`, and\n // every row taken out.\n //\n // \u2550\u2550 WHAT IT ASSUMES \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\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 // That a row's height is knowable without drawing it: `baseHeight`,\n // measured from a real row, or what `virtualRowHeight` says. A row that\n // wraps to two lines is drawn correctly and is simply mis-counted in the\n // spacer arithmetic by the difference \u2014 the overscan absorbs that.\n\n _isVirtual() {\n return !!this.config.virtualize;\n }\n\n _virtOptions() {\n const v = this.config.virtualize;\n const o = v && typeof v === 'object' ? v : {};\n return {\n overscan: Number.isFinite(o.overscan) && o.overscan >= 0 ? Math.floor(o.overscan) : 20,\n rowHeight: Number.isFinite(o.rowHeight) && o.rowHeight > 0 ? o.rowHeight : 24,\n };\n }\n\n /** One `<col>` per DOM column (the row-number column included), carrying\n * any width already pinned for it, so a re-render starts at the widths it\n * had rather than at a content-sized frame that then snaps. */\n _createColgroup() {\n const n = this._domColCount();\n const colgroup = document.createElement('colgroup');\n for (let i = 0; i < n; i++) {\n const col = document.createElement('col');\n const w = i < this._lead().select ? this._selectColWidth() : this._colWidths?.[i];\n if (w != null && this._colWidthsSig === this._colSig()) col.style.width = `${w}px`;\n colgroup.appendChild(col);\n }\n this._colgroupEl = colgroup;\n return colgroup;\n }\n\n /** The `<col>`s, when this table has them. */\n _cols() {\n return this._virt && this._colgroupEl ? this._colgroupEl.children : null;\n }\n\n _virtInit(tbody, rows, globalOf, { serverSide, offset, configOffset }) {\n const { overscan, rowHeight } = this._virtOptions();\n const spacer = (edge) => {\n const tr = document.createElement('tr');\n tr.className = `twm-dt-spacer twm-dt-spacer--${edge}`;\n tr.setAttribute('aria-hidden', 'true');\n const td = document.createElement('td');\n td.colSpan = Math.max(1, this._domColCount());\n // INLINE, because it must beat every consumer's cell padding and\n // border at any specificity: a spacer that is 1px taller than its\n // arithmetic moves every row below it by that pixel.\n td.style.cssText = 'padding:0;border:0;height:0;min-width:0;max-width:none;';\n tr.appendChild(td);\n return tr;\n };\n // The parity filler: see `_virtSpacers`.\n const filler = document.createElement('tr');\n filler.className = 'twm-dt-spacer twm-dt-spacer--parity';\n filler.setAttribute('aria-hidden', 'true');\n filler.hidden = true;\n this._virt = {\n tbody, rows, globalOf, serverSide, offset, configOffset,\n overscan,\n base: this._virtBase || rowHeight,\n heights: null, offsets: null,\n start: 0, end: 0,\n map: new Map(),\n top: spacer('top'), bottom: spacer('bottom'), filler,\n };\n this._virtComputeOffsets();\n // A first window from an ESTIMATED viewport: the scroll box does not\n // exist yet. `render()` redraws it for the real one once it does.\n const guess = this.container?.clientHeight || 0;\n this._virtUpdate({ force: true, notify: false, viewport: guess || undefined, top: 0 });\n }\n\n /** Heights and their running sum. `offsets[i]` is where row `i` starts;\n * `offsets[n]` is the whole table. O(n), and rerun only when a height can\n * have changed \u2014 a new measurement, or `refreshVirtualLayout()`. */\n _virtComputeOffsets() {\n const v = this._virt;\n if (!v) return;\n const n = v.rows.length;\n const heights = new Float64Array(n);\n const offsets = new Float64Array(n + 1);\n const fn = typeof this.config.virtualRowHeight === 'function'\n ? this.config.virtualRowHeight : null;\n // 0.7.0 `rowDetail`: an open detail is part of its row's height \u2014\n // measured once drawn, estimated until then.\n const details = this._detailOn() && this._expanded.size > 0;\n let y = 0;\n for (let i = 0; i < n; i++) {\n let h = v.base;\n if (fn) {\n const asked = fn(v.globalOf(i), v.base);\n h = Number.isFinite(asked) && asked > 0 ? asked : 0;\n }\n if (details && h > 0) h += this._detailHeightOf(v.rows[i], v.globalOf(i), v.base);\n heights[i] = h;\n offsets[i] = y;\n y += h;\n }\n offsets[n] = y;\n v.heights = heights;\n v.offsets = offsets;\n }\n\n /** The row whose span contains `y`: the LAST `i` with `offsets[i] <= y`,\n * which steps over rows of zero height at the same offset. */\n _virtIndexAt(y) {\n const v = this._virt;\n const n = v.rows.length;\n if (n === 0) return 0;\n let lo = 0;\n let hi = n - 1;\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1;\n if (v.offsets[mid] <= y) lo = mid; else hi = mid - 1;\n }\n return lo;\n }\n\n /**\n * Measure the rows that are DRAWN \u2014 the median of up to 64 of them. Client\n * pixels, so the zoom is divided back out (`_measureNaturalWidths` explains\n * why), and NOT `offsetHeight`, which is rounded: 21 for a 21.19px row is a\n * 1,100px error over 6,000 rows.\n *\n * 0.6.3: IT USED TO MEASURE ONE ROW, ONCE, AT RENDER, and trust it for the\n * life of the table. A row measured at a bad moment \u2014 a box not yet laid\n * out at its width, a font not yet loaded \u2014 set every row's height: a\n * Tables grid drawing 22.8px rows was found holding a 134px estimate, so the\n * window took a 650px viewport for five rows, drew rows 1\u201335 and left the\n * rest of the box blank spacer while the reader scrolled. Now it is asked\n * again on every window update (`_virtUpdate`), on a resize and once the\n * column widths are fixed, and corrects itself the first time real rows\n * are on screen. The first measure is exact; after that a change has to be\n * larger than half a pixel, so rows of mixed heights cannot make the\n * offsets move under the reader on every scroll.\n *\n * 0.7.0 `rowDetail`: AN OPEN DETAIL IS PART OF ITS ROW'S HEIGHT, and is\n * measured at the same moments. It is never one of the rows the median is\n * taken from (the window's map holds the rows, not their details), so a\n * tall detail cannot pass for a row; it is read on its own, into the\n * row's height \u2014 and read again here, because a detail's height moves for\n * the same reasons a row's does (the column widths fixed, a font), and\n * more: it wraps across the whole table's width.\n *\n * @returns {boolean} whether the heights changed (the offsets are recomputed).\n */\n _virtMeasure() {\n const v = this._virt;\n if (!v) return false;\n const zoom = this._tableEl?.currentCSSZoom || 1;\n const heights = [];\n for (const tr of v.map.values()) {\n if (!tr.isConnected || tr.hidden) continue;\n const h = tr.getBoundingClientRect().height / zoom;\n if (h > 0) heights.push(h);\n if (heights.length >= 64) break;\n }\n const details = this._detailOn() && this._expanded.size > 0\n && this._virtReadDetailHeights(v.map.values());\n let base = false;\n if (heights.length) {\n heights.sort((a, b) => a - b);\n const h = heights[heights.length >> 1];\n const tolerance = v.measured ? 0.5 : 0.01;\n v.measured = true;\n if (Math.abs(h - v.base) > tolerance) {\n v.base = h;\n this._virtBase = h;\n base = true;\n }\n }\n if (!base && !details) return false;\n this._virtComputeOffsets();\n return true;\n }\n\n /** Measure again, and redraw the window when the heights moved. */\n _virtRemeasure() {\n if (this._virtMeasure()) this._virtUpdate({ force: true });\n }\n\n /**\n * Slide the window to wherever the scroll box now is.\n *\n * HYSTERESIS, so a scroll of one pixel does not rebuild anything: the\n * window is redrawn only when the visible rows come within a quarter of the\n * overscan of either end of what is drawn, and it is then redrawn with the\n * full overscan on both sides.\n *\n * @param {object} [o]\n * @param {boolean} [o.force] redraw even inside the hysteresis band.\n * @param {boolean} [o.notify] report added and removed rows to `onRowsRendered`.\n * @param {number} [o.top] the scroll offset to draw for, instead of\n * reading one back \u2014 `scrollToRow` passes the offset it has just set,\n * which a DOM with no layout would read back as 0.\n * @param {number} [o.viewport] the viewport height, likewise.\n * @returns {HTMLElement[]} the rows added.\n */\n _virtUpdate({ force = false, notify = true, top = null, viewport = null, measure = true } = {}) {\n const v = this._virt;\n if (!v || !v.offsets) return [];\n // The rows on screen say how tall a row is \u2014 before the window is\n // placed, so a stale estimate is not used to place it (`_virtMeasure`).\n if (measure && this._virtMeasure()) force = true;\n const n = v.rows.length;\n const wrap = this._tableWrapEl;\n const view = viewport || wrap?.clientHeight || VIRTUAL_FALLBACK_VIEWPORT_PX;\n const scrollTop = top ?? (wrap?.scrollTop || 0);\n const vs = this._virtIndexAt(scrollTop);\n const ve = Math.min(n, this._virtIndexAt(scrollTop + view) + 1);\n if (!force && v.end > v.start) {\n const margin = Math.max(1, Math.floor(v.overscan / 4));\n const lowOk = v.start === 0 || vs >= v.start + margin;\n const highOk = v.end === n || ve <= v.end - margin;\n if (lowOk && highOk) return [];\n }\n const start = Math.max(0, vs - v.overscan);\n const end = Math.min(n, ve + v.overscan);\n const removed = [];\n const added = this._virtRender(start, end, removed);\n if (added.length || removed.length) {\n // Only once the columns are fixed: before that the first sync has\n // not run, and it tooltips every cell itself.\n if (added[0]?.isConnected && this._tableEl?.style.tableLayout === 'fixed') {\n this._updateCellTooltips(added);\n }\n if (notify) {\n try { this.config.onRowsRendered?.({ rows: added, removed }); } catch (err) {\n console.error('[DataTable] onRowsRendered threw', err);\n }\n }\n // And the rows just drawn: if they disagree with the estimate the\n // window was placed by, place it once more by what they say.\n if (measure && added.length && this._virtMeasure()) {\n return added.concat(this._virtUpdate({\n force: true, notify, top, viewport, measure: false,\n }));\n }\n }\n return added;\n }\n\n /** Make the DOM hold exactly the drawable rows of `[start, end)`, without\n * moving a row that is already there. See the promises above. */\n _virtRender(start, end, removed = null) {\n const v = this._virt;\n const tbody = v.tbody;\n const want = [];\n for (let i = start; i < end; i++) if (v.heights[i] > 0) want.push(i);\n const wanted = new Set(want);\n for (const [i, tr] of v.map) {\n if (!wanted.has(i)) {\n this._cellGrid?.rowLeaving(tr); // STORY-0003: an open editor commits\n tr.remove();\n this._removeDetailPieces(tr); // 0.7.0: its detail goes with it\n v.map.delete(i);\n removed?.push(tr);\n }\n }\n v.start = start;\n v.end = end;\n this._virtSpacers();\n const added = [];\n // Right to left, so each new row goes in front of the one after it \u2014\n // which is either a row that stayed (and is not moved) or the bottom\n // spacer (or the end of the body).\n let ref = v.bottom.isConnected ? v.bottom : null;\n for (let k = want.length - 1; k >= 0; k--) {\n const i = want[k];\n const have = v.map.get(i);\n if (have) { ref = have; continue; }\n const tr = this._buildBodyRow(v.rows[i], v.globalOf(i), i);\n v.map.set(i, tr);\n tbody.insertBefore(tr, ref);\n // 0.7.0: an open detail between the row and the one after it.\n if (this._detailOn()) this._appendDetailIfOpen(tr, ref);\n ref = tr;\n added.push(tr);\n }\n added.reverse();\n // 0.7.0: the details just drawn have a real height now.\n if (this._detailOn() && added.length) this._virtMeasureDetails(added);\n return added;\n }\n\n /**\n * Size the two spacers, and put each in the DOM only while it has a height.\n *\n * AND KEEP THE STRIPE. `tr:nth-child(even)` stripes by POSITION, and in a\n * full render row `i` is child `i + 1`. Here the first drawn row is preceded\n * by the top spacer, so its position is off by one \u2014 and by a different one\n * each time the window's start changes parity, which strobes every stripe\n * on the screen as you scroll. A hidden filler row after the spacer, present\n * exactly when `start` is even, puts the parity back: a `display: none` row\n * is still a child, and so still counted by `nth-child`.\n */\n _virtSpacers() {\n const v = this._virt;\n const n = v.rows.length;\n const above = v.offsets[v.start];\n const below = v.offsets[n] - v.offsets[v.end];\n const tbody = v.tbody;\n if (above > 0) {\n v.top.firstChild.style.height = `${above}px`;\n if (tbody.firstChild !== v.top) tbody.insertBefore(v.top, tbody.firstChild);\n const needFiller = v.start % 2 === 0;\n if (needFiller && v.top.nextSibling !== v.filler) v.top.after(v.filler);\n else if (!needFiller) v.filler.remove();\n } else {\n v.top.remove();\n v.filler.remove();\n }\n if (below > 0) {\n v.bottom.firstChild.style.height = `${below}px`;\n if (tbody.lastChild !== v.bottom) tbody.appendChild(v.bottom);\n } else {\n v.bottom.remove();\n }\n }\n\n /**\n * Recompute every row's height and redraw the window. For an embedder whose\n * `virtualRowHeight` answer has changed \u2014 a group folded, a header added.\n * A no-op on a table that is not virtual.\n */\n refreshVirtualLayout() {\n if (!this._virt) return;\n this._virtMeasure();\n this._virtComputeOffsets();\n this._virtUpdate({ force: true });\n }\n\n /** The element that scrolls the body. Read-only; the table owns it. */\n get scrollElement() {\n return this._tableWrapEl || null;\n }\n\n /** The `<tr>` drawing row `rowIndex` (the `__rowIndex` space), or null when\n * it is not in the DOM \u2014 outside the window, on another page, or hidden. */\n getRowElement(rowIndex) {\n const v = this._virt;\n if (v) {\n const local = this._virtLocalOf(rowIndex);\n return local < 0 ? null : (v.map.get(local) || null);\n }\n const tbody = this._tbodyEl;\n if (!tbody) return null;\n for (const tr of tbody.children) if (tr.__rowIndex === rowIndex) return tr;\n return null;\n }\n\n /** Keep the window's row list and `config.rows` in step for one row. They\n * are the same array in server-side mode; in client mode the window reads\n * the filtered-and-sorted copy, which holds its own reference. */\n _virtSetRow(rowIndex, row) {\n const v = this._virt;\n if (!v) return;\n if (Array.isArray(this.config.rows) && rowIndex >= 0\n && rowIndex < this.config.rows.length) {\n this.config.rows[rowIndex] = row;\n }\n const local = this._virtLocalOf(rowIndex);\n if (local >= 0) v.rows[local] = row;\n }\n\n /** `__rowIndex` \u2192 position in the window's row list, or -1. */\n _virtLocalOf(rowIndex) {\n const v = this._virt;\n if (!v) return -1;\n let local;\n if (v.serverSide) local = rowIndex - v.configOffset;\n else {\n const map = this._processedIndexMap;\n const processed = map ? map.indexOf(rowIndex) : rowIndex;\n local = processed < 0 ? -1 : processed - v.offset;\n }\n return local >= 0 && local < v.rows.length ? local : -1;\n }\n\n /**\n * Scroll the body so row `rowIndex` is on screen, drawing it if it was not,\n * and return its `<tr>` (null when it cannot be shown: another page, or a\n * row the embedder hides). Works with or without `virtualize`.\n *\n * @param {number} rowIndex in the `__rowIndex` space.\n * @param {{block?: 'nearest'|'center'|'start'}} [opts]\n */\n scrollToRow(rowIndex, { block = 'nearest' } = {}) {\n const wrap = this._tableWrapEl;\n const v = this._virt;\n if (!v) {\n const tr = this.getRowElement(rowIndex);\n if (!tr || !wrap) return tr;\n const zoom = this._tableEl?.currentCSSZoom || 1;\n const box = wrap.getBoundingClientRect();\n const r = tr.getBoundingClientRect();\n const rowTop = (r.top - box.top) / zoom + wrap.scrollTop;\n const rowH = r.height / zoom;\n const target = this._scrollTarget(rowTop, rowH, wrap.scrollTop,\n wrap.clientHeight, block);\n if (target !== wrap.scrollTop) wrap.scrollTop = target;\n return tr;\n }\n const local = this._virtLocalOf(rowIndex);\n if (local < 0 || !(v.heights[local] > 0)) return null;\n const view = wrap?.clientHeight || VIRTUAL_FALLBACK_VIEWPORT_PX;\n const current = wrap?.scrollTop || 0;\n let target = this._scrollTarget(v.offsets[local], v.heights[local],\n current, view, block);\n target = Math.max(0, Math.min(target, Math.max(0, v.offsets[v.rows.length] - view)));\n if (wrap && Math.abs(target - current) >= 1) wrap.scrollTop = target;\n this._virtUpdate({ top: Math.abs(target - current) >= 1 ? target : current });\n return v.map.get(local) || null;\n }\n\n _scrollTarget(rowTop, rowH, current, view, block) {\n if (block === 'start') return rowTop;\n if (block === 'center') return rowTop - Math.max(0, (view - rowH) / 2);\n if (rowTop < current) return rowTop;\n if (rowTop + rowH > current + view) return rowTop + rowH - view;\n return current;\n }\n\n /** The first body row that draws a row of data \u2014 never a spacer, and never\n * a row an embedder injected (a group header spans every column with ONE\n * cell, so measuring it would report one column). */\n _firstBodyRow() {\n const tbody = this._tableEl?.querySelector?.('tbody');\n if (!tbody) return null;\n for (const tr of tbody.children) {\n if (tr.__rowIndex !== undefined) return tr;\n }\n return null;\n }\n\n /** Build (or rebuild) one row's cells in place.\n *\n * Extracted from the body loop so that `updateRow` and the initial\n * render share ONE cell-building path. Two paths would drift, and the\n * drift would show as a cell that renders differently after a live\n * update than it did on load. */\n _fillRowCells(tr, row, globalIdx, showRowNumbers) {\n tr.replaceChildren();\n\n // STORY-0016. The select column: a checkbox, shown in select mode. It\n // takes no focus and no click of its own \u2014 the row's click ticks it.\n if (this._gutter) {\n const td = document.createElement('td');\n td.className = 'twm-dt-select-cell';\n const box = document.createElement('input');\n box.type = 'checkbox';\n box.className = 'twm-dt-select-box';\n box.tabIndex = -1;\n box.checked = this._state.selected.has(globalIdx);\n box.setAttribute('aria-label', 'Select row');\n // Its click is the row's: the box flips, the row's handler ticks\n // and sets it to the tick. (Prevented, the browser would flip it\n // back AFTER the handler.)\n td.appendChild(box);\n tr.appendChild(td);\n }\n\n if (showRowNumbers) {\n const td = document.createElement('td');\n td.className = 'num';\n // 0.5.0. 'position' counts the rows as SHOWN; `true` keeps the 0.4\n // number, the row's original index.\n const byPosition = this.config.showRowNumbers === 'position'\n && Number.isInteger(tr.__position);\n td.textContent = String((byPosition ? tr.__position : globalIdx) + 1);\n tr.appendChild(td);\n }\n\n const { cellClass, nullDisplay } = this.config;\n // 0.6.1 `diff`.\n const diff = this._diffOf(row, globalIdx);\n const gap = diff?.status === 'gap';\n const changedCells = diff?.cells\n ? (diff.cells instanceof Set ? diff.cells : new Set(diff.cells))\n : null;\n for (const colIdx of this._rowColumns(row.length)) {\n const td = document.createElement('td');\n td.className = this._columnTypes[colIdx] || 'text';\n if (this._cellGrid) td.__colIdx = colIdx; // STORY-0003\n\n // Use custom cell renderer if provided\n const value = row[colIdx];\n let handled = false;\n if (gap) {\n // The other side's row: a place, not a value.\n td.classList.add('twm-dt-diff__gap');\n tr.appendChild(td);\n continue;\n }\n if (changedCells?.has(colIdx)) td.classList.add('twm-dt-diff__cell--changed');\n if (this.config.renderCell) {\n handled = !!this.config.renderCell(td, value, colIdx, globalIdx, row);\n if (!handled) {\n td.textContent = this._formatValue(value, colIdx);\n }\n } else {\n td.textContent = this._formatValue(value, colIdx);\n }\n // 0.5.0 `nullDisplay`: a NULL is marked as one, so it can be drawn\n // unlike the text \"NULL\" \u2014 unless `renderCell` drew the cell.\n if (!handled && value == null && nullDisplay != null) {\n td.classList.add('twm-dt-cell--null');\n }\n // 0.5.0 `cellClass`.\n if (typeof cellClass === 'function') {\n this._addClasses(td, cellClass(value, colIdx, row, globalIdx));\n }\n // 0.5.0 `rowIcon`, at the start of the first data cell.\n if (colIdx === 0 && typeof this.config.rowIcon === 'function') {\n this._prependRowIcon(td, this.config.rowIcon(row, globalIdx));\n }\n // 0.7.0 `rowDetail`: the toggle, in front of everything in the\n // first data cell.\n if (colIdx === 0 && this._detailOn()) this._prependDetailToggle(td, tr, row, globalIdx);\n\n // Cell-level right-click hook (P2). Fires before the row-level\n // hook and the built-in context menu \u2014 the caller can\n // ev.preventDefault() to suppress the default copy menu on this\n // cell only.\n if (this.config.onCellContextMenu) {\n const cellColIdx = colIdx;\n td.addEventListener('contextmenu', (ev) => {\n this.config.onCellContextMenu(\n cellColIdx, globalIdx, value, td, ev);\n });\n }\n\n tr.appendChild(td);\n }\n // STORY-0066. An empty group's placeholder column.\n this._colGroups()?.fillRow(tr);\n // STORY-0091. The crosstab's pinned cells, and an empty axis's cell.\n this._crosstab()?.fillRow(tr);\n // STORY-0003. The selection, and a commit's pending or refused mark.\n this._cellGrid?.decorateRow(tr);\n }\n\n /** Re-render ONE row in place, preserving everything around it.\n *\n * `render()` rebuilds the entire `<tbody>`, which takes the scroll\n * position, any open editor, the keyboard focus and the measured column\n * widths with it. That is fine for a sort or a page change and wrong for\n * a single-cell commit or a live update arriving over a socket \u2014 the\n * common case in an editable grid, where a full rebuild once per keystroke\n * is both visible and destructive.\n *\n * What survives, by construction:\n * - scroll position, because the tbody is not replaced;\n * - the separately-rendered thead/tbody column widths, because the\n * explicit widths live on the header cells and on the FIRST body row,\n * and all three of the properties `_setCellWidth` writes are re-applied\n * here when that first row is the one being replaced;\n * - selection, because the `selected` class is recomputed from the\n * selection set rather than carried on the old element;\n * - keyboard focus, because the focused element's position is recorded\n * before the replace and restored after.\n *\n * STORY-0003: on the row an open cell editor is in, the data is stored\n * now and the row is drawn when the editor closes (true is returned).\n *\n * @param {number} index row index as tracked by `tr.__rowIndex`\n * @param {any[]} row the new cell values\n * @returns {boolean} false when the row is not currently rendered\n * (it is on another page, or outside the render\n * window) \u2014 which is NOT an error: the caller has\n * nothing to update on screen.\n */\n updateRow(index, row) {\n const tbody = this._tbodyEl;\n if (!tbody) return false;\n\n let tr = null;\n for (const candidate of tbody.children) {\n if (candidate.__rowIndex === index) { tr = candidate; break; }\n }\n // C10. OUTSIDE THE WINDOW IS NOT OFF THE PAGE. The row will be drawn the\n // moment it scrolls back in, from the window's own row list \u2014 so the\n // data has to change now, or it comes back showing the value it had\n // before this update. Without `virtualize` a row that is not in the DOM\n // is on another page, and that path is unchanged.\n if (!tr) {\n if (this._virt) this._virtSetRow(index, row);\n return false;\n }\n\n // Keep the caller's data in step, so a later full render agrees with\n // what is on screen. Server-side paging means config.rows may hold only\n // the current page; the index map is what resolves that.\n if (Array.isArray(this.config.rows) && this.config.rows[index]) {\n this.config.rows[index] = row;\n }\n if (this._virt) this._virtSetRow(index, row);\n // STORY-0003. The row holds an open cell editor: the rebuild would take\n // it out of the document, so the row is drawn when the editor closes.\n if (this._cellGrid?.holdRow(tr, index)) return true;\n\n // Record focus BEFORE the replace: `replaceChildren` detaches the\n // focused cell and the browser moves focus to <body>.\n const active = document.activeElement;\n let focusedCol = -1;\n if (active && tr.contains(active)) {\n focusedCol = Array.prototype.indexOf.call(tr.children, active.closest('td'));\n }\n\n // ALL THREE PROPERTIES, not just `width`. `_setCellWidth` writes\n // `width` together with `min-width: 0` and `max-width: none`, precisely\n // to escape the CSS floors on these cells (flexdesk.css pins the first\n // column at 120px/min 100px and gives every other column a 80px min).\n // Carrying the width across the rebuild and leaving the other two behind\n // let those floors back in \u2014 so a column measured narrower than its\n // floor SNAPPED WIDER the moment one of its cells was repainted, and\n // under `table-layout: fixed` this row is the column track, so the whole\n // column moved. In an editable grid that is one visible jump per saved\n // cell, which is what it looked like to the person doing the saving.\n const isFirstRow = tr === tbody.firstElementChild;\n const widths = isFirstRow\n ? Array.prototype.map.call(tr.children, (td) => ({\n width: td.style.width,\n minWidth: td.style.minWidth,\n maxWidth: td.style.maxWidth,\n }))\n : null;\n\n const showRowNumbers = this.config.showRowNumbers !== false\n && !!tr.querySelector(':scope > td.num');\n this._fillRowCells(tr, row, index, showRowNumbers);\n\n // `_syncHeaderWidths` derives column widths from the FIRST body row.\n // Under a recycling virtualiser that row changes on every scroll \u2014 and\n // here it changes on every update \u2014 so the explicit widths have to be\n // carried across the rebuild or the columns jitter.\n if (widths) {\n widths.forEach((saved, i) => {\n const cell = tr.children[i];\n if (!saved.width || !cell) return;\n cell.style.width = saved.width;\n cell.style.minWidth = saved.minWidth;\n cell.style.maxWidth = saved.maxWidth;\n });\n }\n\n tr.classList.toggle('selected', this._state?.selected?.has(index) === true && !this._cellGrid);\n // 0.5.0. The row's data changed, so its classes, attributes, key and\n // open mark are asked again (a key paused, a delivery that died).\n this._decorateRow(tr, row, index);\n // 0.7.0. An open detail is of the row's data, so it is drawn again.\n if (this._detailOn()) this._redrawDetail(tr);\n\n if (focusedCol >= 0 && tr.children[focusedCol]) {\n tr.children[focusedCol].focus?.();\n }\n return true;\n }\n\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 // 0.7.0 \u2014 a row's detail (#26)\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 // A detail is TWO rows after its row: the detail itself (one cell across\n // every column) and a hidden filler. The filler is the stripe: rows are\n // striped by `tr:nth-child(even)`, a question about POSITION, and one extra\n // row would flip the stripe of every row below an open detail. Two keep\n // the parity \u2014 the trick `_virtSpacers` already plays for the window.\n //\n // Neither row has a `__rowIndex`, so everything that walks the body for\n // rows of data (selection, the open mark, `_firstBodyRow`, `getRowElement`,\n // the activation and the copy menu) steps over them as it steps over a\n // spacer.\n\n _detailOn() {\n return typeof this.config.rowDetail === 'function';\n }\n\n _rowHasDetail(row, rowIdx) {\n const fn = this.config.hasRowDetail;\n if (typeof fn !== 'function') return true;\n try { return !!fn(row, rowIdx); } catch (err) {\n console.error('[DataTable] hasRowDetail threw', err);\n return false;\n }\n }\n\n /** The toggle: a real `<button>` (so Enter and Space work on it, and it is\n * a control `onRowActivate` leaves alone), its glyph drawn by CSS so the\n * cell's text, its tooltip and a copy stay the cell's own. */\n _prependDetailToggle(td, tr, row, rowIdx) {\n if (!this._rowHasDetail(row, rowIdx)) {\n // A row with no detail keeps the toggle's room, so its first cell's\n // text lines up with the rows that have one.\n const gap = document.createElement('span');\n gap.className = 'twm-dt-detail-toggle-gap';\n gap.setAttribute('aria-hidden', 'true');\n td.insertBefore(gap, td.firstChild);\n return;\n }\n const key = this._rowKey(row, rowIdx);\n const open = key !== null && this._expanded.has(key);\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = 'material-symbols-outlined twm-dt-detail-toggle';\n btn.setAttribute('aria-expanded', open ? 'true' : 'false');\n btn.setAttribute('aria-label', String(this.config.rowDetailLabel || 'Details'));\n btn.title = String(this.config.rowDetailLabel || 'Details');\n btn.addEventListener('click', (ev) => {\n // Its own gesture: it neither selects nor opens the row.\n ev.preventDefault();\n ev.stopPropagation();\n this._setRowElExpanded(tr, btn.getAttribute('aria-expanded') !== 'true', ev);\n });\n td.insertBefore(btn, td.firstChild);\n td.classList.add('twm-dt-cell--has-detail-toggle');\n tr.classList.add('twm-dt-row--has-detail');\n }\n\n /** After `tr` has been placed: its open detail, in front of `ref` (the row\n * after it, or null for the end of the body). */\n _appendDetailIfOpen(tr, ref) {\n const row = tr.__row;\n const idx = tr.__rowIndex;\n if (!this._rowHasDetail(row, idx)) return;\n const key = this._rowKey(row, idx);\n if (key === null || !this._expanded.has(key)) return;\n const pieces = this._buildDetailPieces(tr, key);\n const parent = tr.parentNode;\n if (!parent) return;\n for (const p of pieces) parent.insertBefore(p, ref);\n }\n\n _buildDetailPieces(tr, key) {\n const n = this._domColCount();\n const detailTr = document.createElement('tr');\n detailTr.className = 'twm-dt-detail-row';\n const td = document.createElement('td');\n td.className = 'twm-dt-detail-cell';\n td.colSpan = Math.max(1, n);\n const host = document.createElement('div');\n host.className = 'twm-dt-detail';\n DETAIL_SEQ.n += 1;\n host.id = `twm-dt-detail-${DETAIL_SEQ.n}`;\n td.appendChild(host);\n detailTr.appendChild(td);\n const filler = document.createElement('tr');\n filler.className = 'twm-dt-detail-filler';\n filler.hidden = true;\n filler.setAttribute('aria-hidden', 'true');\n detailTr.__detailOf = tr;\n tr.__detail = [detailTr, filler];\n this._drawDetail(tr, host, key);\n const btn = tr.querySelector(':scope > td > .twm-dt-detail-toggle');\n if (btn) btn.setAttribute('aria-controls', host.id);\n return tr.__detail;\n }\n\n _drawDetail(tr, host, key) {\n host.replaceChildren();\n let out;\n try {\n out = this.config.rowDetail(tr.__row, tr.__rowIndex, { host, key, table: this });\n } catch (err) {\n console.error('[DataTable] rowDetail threw', err);\n out = err?.message || String(err);\n }\n if (out == null || out === false || out === host) return;\n if (typeof Node !== 'undefined' && out instanceof Node) host.appendChild(out);\n else host.textContent = String(out);\n }\n\n _removeDetailPieces(tr) {\n const pieces = tr.__detail;\n if (!pieces) return;\n for (const p of pieces) p.remove();\n tr.__detail = null;\n const btn = tr.querySelector(':scope > td > .twm-dt-detail-toggle');\n if (btn) btn.removeAttribute('aria-controls');\n }\n\n /** `updateRow`'s half: the detail follows the row's new data. */\n _redrawDetail(tr) {\n const key = this._rowKey(tr.__row, tr.__rowIndex);\n const want = this._rowHasDetail(tr.__row, tr.__rowIndex) && key !== null && this._expanded.has(key);\n const pieces = tr.__detail;\n if (!want) { if (pieces) this._removeDetailPieces(tr); return; }\n if (pieces) {\n const host = pieces[0].querySelector('.twm-dt-detail');\n if (host) {\n this._drawDetail(tr, host, key);\n const btn = tr.querySelector(':scope > td > .twm-dt-detail-toggle');\n if (btn) btn.setAttribute('aria-controls', host.id);\n }\n return;\n }\n if (tr.parentNode) this._appendDetailIfOpen(tr, tr.nextSibling);\n }\n\n /** Open or close the detail of the row `tr` draws. Returns whether\n * anything changed. */\n _setRowElExpanded(tr, open, ev = null) {\n if (!this._detailOn() || tr.__rowIndex === undefined) return false;\n if (!this._rowHasDetail(tr.__row, tr.__rowIndex)) return false;\n const key = this._rowKey(tr.__row, tr.__rowIndex);\n if (key === null || this._expanded.has(key) === !!open) return false;\n if (open) this._expanded.add(key); else this._expanded.delete(key);\n this._syncDetailOnScreen(tr, key);\n this._afterDetailChange();\n try { this.config.onRowDetailToggle?.(tr.__rowIndex, tr.__row, !!open, key, ev); } catch (err) {\n console.error('[DataTable] onRowDetailToggle threw', err);\n }\n return true;\n }\n\n /** Make the row on screen agree with `_expanded` for its key. */\n _syncDetailOnScreen(tr, key) {\n const open = this._expanded.has(key);\n const btn = tr.querySelector(':scope > td > .twm-dt-detail-toggle');\n if (btn) btn.setAttribute('aria-expanded', open ? 'true' : 'false');\n if (open && !tr.__detail && tr.parentNode) {\n const ref = tr.nextSibling;\n for (const p of this._buildDetailPieces(tr, key)) tr.parentNode.insertBefore(p, ref);\n } else if (!open && tr.__detail) {\n this._removeDetailPieces(tr);\n }\n }\n\n /** Under `virtualize` an open detail is part of its row's height. */\n _afterDetailChange() {\n if (!this._virt) return;\n this._virtMeasureDetails([...this._virt.map.values()], { force: true });\n }\n\n /** The detail's height for row `i` of the window's list: 0 closed, the\n * measured height open, three rows until it has been measured. */\n _detailHeightOf(row, rowIdx, base) {\n if (!this._rowHasDetail(row, rowIdx)) return 0;\n const key = this._rowKey(row, rowIdx);\n if (key === null || !this._expanded.has(key)) return 0;\n const h = this._detailHeights.get(key);\n return h > 0 ? h : base * 3;\n }\n\n /** Measure the open details among `trs` (client pixels, the zoom divided\n * out, as `_virtMeasure` does), and re-lay the window if one changed. */\n _virtMeasureDetails(trs, { force = false } = {}) {\n const v = this._virt;\n if (!v) return;\n const changed = this._virtReadDetailHeights(trs) || force;\n if (!changed) return;\n this._virtComputeOffsets();\n this._virtSpacers();\n }\n\n /** Read the open details drawn under `trs` into `_detailHeights`; true\n * when one moved by more than half a pixel. Recomputes nothing. */\n _virtReadDetailHeights(trs) {\n let changed = false;\n const zoom = this._tableEl?.currentCSSZoom || 1;\n for (const tr of trs) {\n const d = tr?.__detail?.[0];\n if (!d || !d.isConnected) continue;\n const h = d.getBoundingClientRect().height / zoom;\n if (!(h > 0)) continue;\n const key = this._rowKey(tr.__row, tr.__rowIndex);\n if (Math.abs((this._detailHeights.get(key) || 0) - h) > 0.5) {\n this._detailHeights.set(key, h);\n changed = true;\n }\n }\n return changed;\n }\n\n /**\n * Open (or close) the detail of the row whose key is `key` (`getRowKey`,\n * else the row's index). A row not on screen \u2014 another page, outside the\n * window, filtered out \u2014 opens when it is drawn.\n *\n * @param {*} key\n * @param {boolean} [open=true]\n * @returns {boolean} whether anything changed\n */\n setRowExpanded(key, open = true) {\n if (key == null) return false;\n const k = String(key);\n if (this._expanded.has(k) === !!open) return false;\n if (open) this._expanded.add(k); else this._expanded.delete(k);\n const tr = this._rowElByKey(k);\n if (tr) {\n this._syncDetailOnScreen(tr, k);\n try { this.config.onRowDetailToggle?.(tr.__rowIndex, tr.__row, !!open, k, null); } catch (err) {\n console.error('[DataTable] onRowDetailToggle threw', err);\n }\n }\n if (this._virt) {\n this._virtComputeOffsets();\n this._virtSpacers();\n this._afterDetailChange();\n }\n return true;\n }\n\n /** Whether the row whose key is `key` has its detail open. */\n isRowExpanded(key) {\n return key != null && this._expanded.has(String(key));\n }\n\n /** The keys of the rows whose detail is open, as text. */\n getExpandedRows() {\n return [...this._expanded];\n }\n\n /** Close every detail. */\n collapseAllRows() {\n for (const k of [...this._expanded]) this.setRowExpanded(k, false);\n }\n\n /** The `<tr>` on screen for a key, or null. */\n _rowElByKey(key) {\n const tbody = this._tbodyEl;\n if (!tbody) return null;\n for (const tr of tbody.children) {\n if (tr.__rowIndex === undefined) continue;\n if (this._rowKey(tr.__row, tr.__rowIndex) === key) return tr;\n }\n return null;\n }\n\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 // 0.7.0 \u2014 rows from a server (#33), the pager for an unknown total\n // (#35), refresh and follow (#36)\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 // ONE QUESTION AT A TIME, AND ONLY THE NEWEST ANSWER. Every request takes\n // a ticket; an answer whose ticket is not the latest is dropped, and the\n // request it answered is aborted the moment a newer one is sent. Two\n // requests in flight from a fast typist otherwise race, and the loser\n // painting last is a list that does not match the box above it.\n\n /** Rows that are the current page of something larger (`onPageChange`,\n * or 0.7.0's `dataSource`): drawn as given, never filtered, sorted or\n * sliced here. */\n _isServerSide() {\n return typeof this.config.onPageChange === 'function' || !!this.config.dataSource;\n }\n\n /** `autoDispose`'s grace in ms: one task, `keepWhileDetached`'s number,\n * or Infinity for `true`. */\n _detachGrace() {\n const k = this.config.keepWhileDetached;\n if (k === true) return Infinity;\n if (typeof k === 'number' && Number.isFinite(k) && k > 0) return k;\n if (k === Infinity) return Infinity;\n return 0;\n }\n\n _sourceState() {\n if (!this._source) {\n this._source = {\n started: false, ticket: 0, controller: null, inFlight: false,\n offset: 0, pendingOffset: 0, total: null, atLeast: 0, hasMore: false,\n query: null, loaded: false, pendingAppend: false,\n };\n }\n return this._source;\n }\n\n /** The column filters, as a query and `onFilterChange` carry them. */\n _filterList() {\n const headers = this.config.headers || [];\n const out = [];\n for (const [column, value] of this._state.filters) {\n if (typeof value === 'string' ? !value : this._isEmptyFilterValue(value)) continue;\n out.push({ column, header: headers[column], value });\n }\n return out.sort((a, b) => a.column - b.column);\n }\n\n /** Rows per question: `paging.pageSize` when the source is paged, else\n * `pageSize` \u2014 one number for the query, `goToPage` and the pager. */\n _sourcePageSize() {\n const size = this._pagingConfig()?.pageSize ?? this.config.pageSize;\n return Math.max(1, size | 0);\n }\n\n _buildQuery(offset, reason, limit = null) {\n const col = this._state.sortColumn;\n return {\n offset,\n limit: Number.isFinite(limit) && limit >= 1 ? Math.floor(limit) : this._sourcePageSize(),\n sort: col == null ? null : {\n column: col, header: (this.config.headers || [])[col], ascending: this._state.sortAscending,\n },\n filters: this._filterList(),\n reason,\n };\n }\n\n /**\n * Ask the source for the page at `offset`, and draw the answer if it is\n * still the newest by then. Resolves with the answer drawn, or undefined\n * when it was dropped (superseded, failed, or the table was disposed).\n */\n async _sourceLoad({ offset = 0, reason = 'reload', keep = false, append = false, limit = null } = {}) {\n const fetch = this.config.dataSource;\n if (typeof fetch !== 'function') return undefined;\n const src = this._sourceState();\n src.started = true;\n const ticket = ++src.ticket;\n try { src.controller?.abort(); } catch (_) { /* gone */ }\n const controller = typeof AbortController === 'function' ? new AbortController() : null;\n src.controller = controller;\n const query = this._buildQuery(Math.max(0, offset | 0), reason, limit);\n src.query = query;\n src.inFlight = true;\n src.pendingOffset = query.offset;\n src.pendingAppend = append;\n // More rows under a scrolling list are said on the paging strip (busy),\n // not by covering the rows being read.\n if (!append) this.setLoading(true);\n let result;\n try {\n result = await fetch(query, { signal: controller?.signal });\n } catch (err) {\n if (ticket !== src.ticket) return undefined; // superseded or disposed\n src.inFlight = false;\n src.controller = null;\n src.pendingAppend = false;\n if (err?.name === 'AbortError' || controller?.signal?.aborted) {\n this.setLoading(false);\n return undefined;\n }\n // THE ROWS ON SCREEN STAY: a failed refresh does not blank a list a\n // person was reading. `setError` keeps them under its banner.\n this.setError(err);\n try { this.config.onLoadError?.(err, query); } catch (e) { console.error('[DataTable] onLoadError threw', e); }\n return undefined;\n }\n if (ticket !== src.ticket) return undefined; // a newer question is out\n src.inFlight = false;\n src.controller = null;\n src.pendingAppend = false;\n this._applySourceResult(result, query, { keep, append });\n try { this.config.onLoad?.(result, query); } catch (e) { console.error('[DataTable] onLoad threw', e); }\n return result;\n }\n\n _applySourceResult(result, query, { keep = false, append = false } = {}) {\n const src = this._sourceState();\n const r = Array.isArray(result) ? { rows: result } : (result || {});\n const answered = Array.isArray(r.rows) ? r.rows : [];\n const totalRaw = r.total ?? r.totalCount;\n const total = typeof totalRaw === 'number' && Number.isFinite(totalRaw) ? totalRaw : null;\n const hasMore = typeof r.hasMore === 'boolean' ? r.hasMore\n : total !== null ? query.offset + answered.length < total\n : answered.length >= query.limit;\n // `paging`, scrolling: the next rows go UNDER the ones held, and the\n // page held still starts where it started.\n let rows = append ? (this.config.rows || []).concat(answered) : answered;\n let rowsOffset = append ? (src.offset || 0) : query.offset;\n // \u2026until the source proves it holds more than the soft limit: from then\n // on it is shown in PAGES (`resolvePaging`), and the rows the reader had\n // just reached ARE that page \u2014 nothing is asked again, and the reader\n // goes on from where they were reading.\n const pc = append ? this._pagingConfig() : null;\n if (pc && resolvePaging({\n mode: pc.mode, total, atLeast: r.atLeast, held: rowsOffset + rows.length, hasMore,\n softLimit: pc.softLimit, hardLimit: pc.hardLimit,\n }).mode === 'pages') {\n rows = answered;\n rowsOffset = query.offset;\n append = false;\n }\n // WITHOUT `getRowKey`, A DETAIL IS OPEN AT A PLACE, and a place in one\n // answer says nothing about which row stands there in the next: page 2's\n // first row is not page 1's, and a sort or a new arrival moves every\n // row. So an index-keyed detail stays open only where the new answer\n // has the SAME row (equal values) at its place; `expandedRows` applies\n // to the first answer as given. (The release review: a detail opened on\n // page 1 opened the same place on page 2, under another row.)\n if (src.loaded && this._detailOn() && this._expanded.size\n && typeof this.config.getRowKey !== 'function') {\n const before = this.config.rows || [];\n const same = (a, b) => {\n if (a === b) return true;\n try { return JSON.stringify(a) === JSON.stringify(b); } catch (_) { return false; }\n };\n for (const k of [...this._expanded]) {\n const i = Number(k);\n if (!Number.isInteger(i) || i < 0 || i >= rows.length || !same(before[i], rows[i])) {\n this._expanded.delete(k);\n this._detailHeights.delete(k);\n }\n }\n }\n // The page drawn \u2014 so the pager says where these rows ARE.\n src.offset = rowsOffset;\n src.total = total;\n src.atLeast = Number.isFinite(r.atLeast) ? r.atLeast : 0;\n src.hasMore = hasMore;\n src.loaded = true;\n if (r.filterCounts && typeof r.filterCounts === 'object') this.setFilterCounts(r.filterCounts);\n\n const snap = keep ? this._snapshotView() : null;\n const kept = append ? this._tableWrapEl?.scrollTop || 0 : null;\n // Rows the last answer did not hold \u2014 marked as new (only by key: an\n // index says nothing about which row is which across two answers).\n if (snap && snap.keys && snap.keys.size && typeof this.config.getRowKey === 'function') {\n const fresh = new Set();\n rows.forEach((row, i) => {\n const k = this._rowKey(row, i);\n if (k !== null && !snap.keys.has(k)) fresh.add(k);\n });\n this._newKeys = fresh.size ? fresh : null;\n } else {\n this._newKeys = null;\n }\n // More rows under the same ones: the rows a person chose stay chosen.\n const chosen = append && this._state.selected.size\n ? { sel: [...this._state.selected], anchor: this._state.anchorIndex } : null;\n this.setData({ rows });\n this._newKeys = null;\n if (chosen) {\n for (const i of chosen.sel) this._state.selected.add(i);\n this._state.anchorIndex = chosen.anchor;\n this._updateRowSelection();\n }\n if (snap) this._restoreView(snap);\n else if (kept !== null) this._scrollBodyTo(kept); // more rows: the reader stays put\n else this._scrollBodyTo(0); // a new question starts at the top of its answer\n }\n\n /** What a refresh must put back: the keys on screen, the selection by\n * key, and the first row a reader can see with where it stood. */\n _snapshotView() {\n const rows = this.config.rows || [];\n const keyed = typeof this.config.getRowKey === 'function';\n const keys = keyed ? new Set(rows.map((row, i) => this._rowKey(row, i))) : null;\n const selectedKeys = keyed\n ? this.getSelection().map((i) => this._rowKey(rows[i], i)).filter((k) => k !== null)\n : null;\n const wrap = this._tableWrapEl;\n let anchor = null;\n const scrollTop = wrap?.scrollTop || 0;\n if (wrap && scrollTop > 0 && this._tbodyEl) {\n const zoom = this._tableEl?.currentCSSZoom || 1;\n const top = wrap.getBoundingClientRect().top;\n for (const tr of this._tbodyEl.children) {\n if (tr.__rowIndex === undefined) continue;\n const box = tr.getBoundingClientRect();\n if (box.bottom > top + 0.5) {\n anchor = { key: this._rowKey(tr.__row, tr.__rowIndex), delta: (box.top - top) / zoom };\n break;\n }\n }\n }\n return { keys, selectedKeys, anchor, scrollTop };\n }\n\n _restoreView(snap) {\n // The selection, by key: the rows a person chose are still chosen\n // wherever the new answer put them.\n if (snap.selectedKeys && snap.selectedKeys.length) {\n const want = new Set(snap.selectedKeys);\n const sel = this._state.selected;\n (this.config.rows || []).forEach((row, i) => {\n if (want.has(this._rowKey(row, i))) sel.add(i);\n });\n if (sel.size) {\n this._state.anchorIndex = [...sel][0];\n this._updateRowSelection();\n this._notifySelectionChange();\n }\n }\n // THE SCROLL POSITION: a reader at the top sees what arrived (that is\n // following); a reader scrolled down keeps the rows they were reading\n // where they were \u2014 new rows above push the scroll, not the rows.\n const wrap = this._tableWrapEl;\n if (!wrap || !snap.anchor || snap.anchor.key === null) return;\n const rows = this.config.rows || [];\n const idx = rows.findIndex((row, i) => this._rowKey(row, i) === snap.anchor.key);\n if (idx < 0) return;\n const zoom = this._tableEl?.currentCSSZoom || 1;\n if (this._virt) {\n const local = this._virtLocalOf(idx);\n if (local < 0) return;\n this._scrollBodyTo(Math.max(0, this._virt.offsets[local] - snap.anchor.delta));\n return;\n }\n const tr = this.getRowElement(idx);\n if (!tr) return;\n const now = (tr.getBoundingClientRect().top - wrap.getBoundingClientRect().top) / zoom;\n const shift = now - snap.anchor.delta;\n if (Math.abs(shift) >= 0.5) this._scrollBodyTo(wrap.scrollTop + shift);\n }\n\n _scrollBodyTo(top) {\n const wrap = this._tableWrapEl;\n if (!wrap) return;\n if (Math.abs((wrap.scrollTop || 0) - top) >= 0.5) wrap.scrollTop = top;\n if (this._virt) this._virtUpdate({ force: true, top });\n }\n\n /** Go to the page at `offset` (paging back stops following). */\n _sourceGoTo(offset) {\n if (this._stagedRefusal('Turning the page')) return undefined;\n const next = Math.max(0, offset | 0);\n // PAGING AWAY TURNS FOLLOWING OFF, and coming back does not turn it on\n // again by itself: a reader who left the tail to read an old page is\n // never pulled back to it by the next tick.\n if (this._following && next > 0) this.setFollow(false);\n return this._sourceLoad({ offset: next, reason: 'page' });\n }\n\n /**\n * `paging` over a `dataSource`, scrolling: the rows after those held, under\n * them \u2014 never past the hard limit. Scrolling down to ask for them is\n * paging away, so it turns following off as a page turn does; rows asked\n * for because the ones held do not fill the box are not (the reader is\n * still at the top).\n */\n _sourceLoadMore() {\n const held = this.config.rows?.length || 0;\n const hard = this.pagingState?.hardLimit ?? PAGING_HARD_LIMIT;\n const limit = Math.min(this._sourcePageSize(), hard - held);\n if (limit < 1) return Promise.resolve(undefined);\n if (this._following && (this._tableWrapEl?.scrollTop || 0) > 0) this.setFollow(false);\n const offset = (this._source?.offset || 0) + held;\n return this._sourceLoad({ offset, limit, reason: 'more', append: true });\n }\n\n /** The strip's *Load all rows*: ONE question for every row left under the\n * hard limit (`reason: 'all'`); the source answers as many as it will, and\n * says with `hasMore` whether there are still more. */\n _sourceLoadAll() {\n const held = this.config.rows?.length || 0;\n const hard = this.pagingState?.hardLimit ?? PAGING_HARD_LIMIT;\n if (hard - held < 1) return Promise.resolve(undefined);\n if (this._following) this.setFollow(false);\n const offset = (this._source?.offset || 0) + held;\n return this._sourceLoad({ offset, limit: hard - held, reason: 'all', append: true });\n }\n\n /** The strip's Pages / Scroll switch: the table switches, tells the\n * consumer (`paging.onModeChange`), and asks again from the start. */\n _sourceSetMode(mode) {\n const next = mode === 'pages' ? 'pages' : 'scroll';\n const p = this.config.paging;\n this.config.paging = { ...p, mode: next };\n try { p.onModeChange?.(next); } catch (err) { console.error('[DataTable] onModeChange threw', err); }\n return this._sourceLoad({ offset: 0, reason: 'mode' });\n }\n\n /**\n * Ask the source again from its FIRST page \u2014 for a consumer whose own\n * filters (outside the table) changed. Under `dataSource` only; resolves\n * with the answer drawn (undefined when it was superseded or failed).\n */\n reload() {\n if (!this.config.dataSource) return Promise.resolve(undefined);\n return this._sourceLoad({ offset: 0, reason: 'reload' });\n }\n\n /**\n * Read the CURRENT page again, in place: the scroll position (a reader at\n * the top sees what arrived; one scrolled down keeps the rows they were\n * reading where they were), the selection by key, the open row and the\n * open details all stay; rows the last answer did not hold are drawn\n * `twm-dt-row--new` (needs `getRowKey`). What `follow` calls on its tick.\n * Without `dataSource`, it only draws again.\n */\n refresh() {\n if (!this.config.dataSource) {\n if (this._wrapperEl) this.render();\n return Promise.resolve(undefined);\n }\n const src = this._sourceState();\n // `paging`, scrolling: the rows HELD are read again, in one question\n // from where they start \u2014 a list scrolled to row 300 is still 300 rows\n // after the tick. (Following stops once the reader scrolls down for\n // more, so a following list stays short.)\n if (this.pagingState?.mode === 'scroll') {\n const held = this.config.rows?.length || 0;\n return this._sourceLoad({\n offset: src.offset || 0, limit: Math.max(this._sourcePageSize(), held),\n reason: 'refresh', keep: true,\n });\n }\n const offset = src.inFlight && !src.pendingAppend ? src.pendingOffset : src.offset;\n return this._sourceLoad({ offset, reason: 'refresh', keep: true });\n }\n\n /** The last query sent to `dataSource`, or null. */\n getQuery() {\n return this._source?.query || null;\n }\n\n /** What the last answer said about the whole: `{offset, total, hasMore}`. */\n getPageInfo() {\n const s = this._source;\n return s ? { offset: s.offset, total: s.total, hasMore: s.hasMore } : null;\n }\n\n /**\n * Turn following on or off (`follow`). On, the first page is read again\n * every `follow.interval` ms while the table is on it and in the page.\n */\n setFollow(on) {\n const next = !!on;\n if (next === this._following) return;\n this._following = next;\n if (next) this._armFollow(); else this._disarmFollow();\n try { this.config.onFollowChange?.(next); } catch (err) { console.error('[DataTable] onFollowChange threw', err); }\n }\n\n isFollowing() {\n return this._following;\n }\n\n _followInterval() {\n const f = this.config.follow;\n const ms = f && typeof f === 'object' ? Number(f.interval) : NaN;\n return Number.isFinite(ms) && ms > 0 ? ms : 10_000;\n }\n\n /** The tick holds the table WEAKLY: a follow timer must never be what keeps\n * a table nobody holds alive (`keepWhileDetached: true`). */\n _armFollow() {\n this._disarmFollow();\n if (!this._following || !this.config.dataSource || !this._wrapperEl) return;\n const ref = weakRef(this);\n const id = setInterval(() => {\n const t = ref.deref();\n if (!t || t._followTimer !== id) { clearInterval(id); return; }\n const src = t._source;\n if (!t._following || !src || src.inFlight) return;\n if ((src.offset || 0) !== 0) return; // only on the first page\n if (!t._wrapperEl?.isConnected) return; // not while out of the page\n if (t._readerIsBusy()) return; // not under a reader (below)\n t.refresh();\n }, this._followInterval());\n this._followTimer = id;\n }\n\n _disarmFollow() {\n if (this._followTimer) clearInterval(this._followTimer);\n this._followTimer = null;\n }\n\n /** A TICK WAITS FOR A READER. A refresh redraws every row and every open\n * detail, so a tick that came while somebody was selecting text in the\n * table (a stack trace to copy) or working inside an open detail took the\n * text out from under the selection and the focus out of the detail \u2014\n * every interval, for as long as they stayed. The tick is skipped\n * instead, and following resumes on the next one after (the release\n * review). `refresh()` called by the consumer is not a tick and does not\n * wait. */\n _readerIsBusy() {\n const wrap = this._tableWrapEl;\n const doc = wrap?.ownerDocument;\n if (!wrap || !doc) return false;\n const active = doc.activeElement;\n if (active && active !== wrap && wrap.contains(active)\n && active.closest?.('.twm-dt-detail')) return true;\n try {\n const sel = doc.defaultView?.getSelection?.();\n if (sel && !sel.isCollapsed && sel.rangeCount > 0) {\n for (let i = 0; i < sel.rangeCount; i++) {\n const r = sel.getRangeAt(i);\n if (wrap.contains(r.startContainer) || wrap.contains(r.endContainer)) return true;\n }\n }\n } catch (_) { /* no selection API */ }\n return false;\n }\n\n // \u2500\u2500 the pager (#35) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 _usesPager070() {\n const c = this.config;\n return !!c.dataSource || !!c.pagerLabels || c.maxJumpOffset != null\n || (typeof c.onPageChange === 'function' && c.totalCount == null && typeof c.hasMore === 'boolean');\n }\n\n _pagerLabel(name) {\n const labels = this.config.pagerLabels || {};\n return labels[name];\n }\n\n _pagerRefusalTooDeep() {\n const max = this.config.maxJumpOffset;\n const fn = this._pagerLabel('tooDeep');\n if (typeof fn === 'function') return String(fn(max));\n if (typeof fn === 'string') return fn;\n return `Past ${Number(max).toLocaleString()} rows. Narrow the filters first.`;\n }\n\n _pagerButton(icon, name, tip, disabled, onClick, refusal = null) {\n const label = this._pagerLabel(name);\n const btn = this._createPaginationBtn(icon, typeof label === 'string' ? label : tip,\n disabled || !!refusal, onClick);\n btn.dataset.pager = name;\n if (typeof label === 'string' && label) {\n const span = document.createElement('span');\n span.className = 'twm-pagination-btn__label';\n span.textContent = label;\n btn.appendChild(span);\n btn.classList.add('twm-pagination-btn--labelled');\n btn.style.padding = '1px 6px 1px 3px';\n // NEVER NARROWER THAN ITS WORD. The pager's buttons carry a\n // `min-width` sized for a glyph (22px, `!important` in the compact\n // skin), and in a narrow tile the flex row shrank a labelled one\n // to it and clipped its word. Inline and `important`, because it\n // is the one declaration that must beat both skins.\n btn.style.setProperty('min-width', 'max-content', 'important');\n btn.style.flexShrink = '0';\n }\n if (refusal) {\n // The reason is ON the control, where a person looks and a test can\n // read it \u2014 not only in a tooltip.\n btn.dataset.refusal = refusal;\n btn.setAttribute('data-tooltip', refusal);\n btn.title = refusal;\n }\n return btn;\n }\n\n /**\n * THE PAGE ARITHMETIC, ONCE \u2014 read by the pager above the rows (0.7.0) and\n * by the `paging` strip under them (0.6.2), which each worked it out for\n * themselves. `held` is the rows drawn on this page; `total` a number or\n * null (unknown, when `hasMore` says whether there is a next page).\n *\n * @returns {{known: boolean, hasPrev: boolean, hasNext: boolean, page: number,\n * pages: number|null, lastOffset: number|null, lastRefusal: string|null}}\n */\n _pageNav({ offset = 0, held = 0, total = null, hasMore = false, pageSize }) {\n const size = Math.max(1, pageSize | 0);\n const known = typeof total === 'number' && Number.isFinite(total);\n const lastOffset = known ? Math.floor(Math.max(0, total - 1) / size) * size : null;\n const maxJump = Number.isFinite(this.config.maxJumpOffset) ? this.config.maxJumpOffset : null;\n let lastRefusal = null;\n if (!known) {\n const words = this._pagerLabel('noLast');\n lastRefusal = typeof words === 'string' ? words : 'The total is not known, so there is no last page.';\n } else if (maxJump !== null && lastOffset > maxJump) {\n lastRefusal = this._pagerRefusalTooDeep();\n }\n return {\n known,\n hasPrev: offset > 0,\n hasNext: known ? offset + held < total : !!hasMore,\n page: Math.floor(offset / size) + 1,\n pages: known ? Math.max(1, Math.ceil(total / size)) : null,\n lastOffset,\n lastRefusal,\n };\n }\n\n /**\n * The pager for any mode, with the two things the 0.6 strip could not do:\n * an UNKNOWN total (no \"of N\", no last page, Next until a short page) and\n * a REFUSED deep jump (`maxJumpOffset`). For a known total its words are\n * the 0.6 strip's.\n */\n _createPager070() {\n const c = this.config;\n const { rows, pageSize } = c;\n const source = !!c.dataSource;\n const server = !source && typeof c.onPageChange === 'function';\n const src = this._source || { offset: 0, total: null, hasMore: false };\n const offset = source ? src.offset : server ? (c.offset || 0) : this._state.offset;\n let total;\n let hasMoreKnown;\n if (source) {\n total = src.total;\n hasMoreKnown = src.hasMore;\n } else if (server) {\n const unknown = c.totalCount == null && typeof c.hasMore === 'boolean';\n total = unknown ? null : (c.totalCount || rows.length);\n hasMoreKnown = unknown ? c.hasMore : null;\n } else {\n total = this._getProcessedRows().length;\n hasMoreKnown = null;\n }\n const known = typeof total === 'number' && Number.isFinite(total);\n const isFiltered = !source && !server && this._state.filters.size > 0;\n const unfilteredTotal = !source && !server ? rows.length : total;\n const drawn = source || server ? rows.length : Math.max(0, Math.min(pageSize, total - offset));\n const pn = this._pageNav({ offset, held: drawn, total, hasMore: hasMoreKnown, pageSize });\n const { hasPrev, hasNext, page } = pn;\n const totalPages = pn.pages;\n if (known && totalPages <= 1 && !isFiltered && !hasPrev) return this._createExportOnlyStrip();\n if (!known && !hasPrev && !hasNext) return this._createExportOnlyStrip();\n const maxJump = Number.isFinite(c.maxJumpOffset) ? c.maxJumpOffset : null;\n\n const go = (newOffset) => {\n if (this._stagedRefusal('Turning the page')) return;\n if (source) { this._sourceGoTo(newOffset); return; }\n if (server) { this._awaitWithSpinner(c.onPageChange(newOffset, pageSize)); return; }\n this._state.offset = newOffset;\n this._savePage();\n this.render();\n };\n\n const el = document.createElement('div');\n el.className = 'twm-pagination-controls';\n if (!known) el.classList.add('twm-pagination-controls--unknown-total');\n el.style.cssText = 'display:flex; align-items:center; gap:6px; padding:2px 8px; border-bottom:1px solid #2a2a2a; font-size:11px;';\n\n const info = document.createElement('span');\n info.className = 'twm-pagination-info';\n info.style.cssText = 'color:#aaa; white-space:nowrap;';\n const from = (offset + 1).toLocaleString();\n const to = (offset + drawn).toLocaleString();\n if (drawn === 0) {\n info.textContent = hasPrev ? `Page ${page} \u00B7 no rows`\n : isFiltered ? `0 of ${unfilteredTotal.toLocaleString()} rows match` : 'No rows';\n } else if (!known) {\n info.textContent = `Rows ${from}\u2013${to}`;\n } else if (isFiltered) {\n info.textContent = `Rows ${from}\u2013${to} of ${total.toLocaleString()} (${unfilteredTotal.toLocaleString()} total)`;\n } else {\n info.textContent = `Rows ${from}\u2013${to} of ${total.toLocaleString()}`;\n }\n\n const spacer = document.createElement('div');\n spacer.style.flex = '1';\n\n const firstBtn = this._pagerButton('first_page', 'first', 'First page', !hasPrev, () => go(0));\n const prevBtn = this._pagerButton('chevron_left', 'prev', 'Previous page', !hasPrev,\n () => go(Math.max(0, offset - pageSize)));\n const pageInfo = document.createElement('span');\n pageInfo.className = 'twm-pagination-page';\n pageInfo.style.cssText = 'color:#aaa; font-size:10px; min-width:72px; text-align:center;';\n pageInfo.textContent = known ? `Page ${page} of ${totalPages.toLocaleString()}` : `Page ${page}`;\n const nextBtn = this._pagerButton('chevron_right', 'next', 'Next page', !hasNext,\n () => go(offset + pageSize));\n const { lastOffset, lastRefusal } = pn;\n const lastBtn = this._pagerButton('last_page', 'last', 'Last page',\n !hasNext || lastOffset === offset, () => {\n if (lastOffset !== null) go(lastOffset);\n }, lastRefusal);\n\n const jumpInput = document.createElement('input');\n jumpInput.type = 'number';\n jumpInput.className = 'twm-pagination-input';\n jumpInput.style.cssText = 'width:54px; padding:1px 4px; border:1px solid #444; background:#2a2a2a; color:#ccc; font-size:10px;';\n jumpInput.min = '1';\n if (known) jumpInput.max = String(total);\n jumpInput.placeholder = 'Row #';\n const jumpBtn = this._createPaginationBtn(null, 'Go to row', false, () => {\n const target = Math.floor(Number(jumpInput.value));\n if (!Number.isFinite(target) || target < 1) return;\n const row = known ? Math.min(target, Math.max(1, total)) : target;\n const newOffset = Math.floor((row - 1) / pageSize) * pageSize;\n if (maxJump !== null && newOffset > maxJump) {\n // Refused, and says so where the person is looking.\n const why = this._pagerRefusalTooDeep();\n jumpInput.setAttribute('aria-invalid', 'true');\n jumpInput.title = why;\n jumpInput.dataset.refusal = why;\n return;\n }\n jumpInput.removeAttribute('aria-invalid');\n delete jumpInput.dataset.refusal;\n if (server && typeof c.onJumpToRow === 'function') { c.onJumpToRow(row - 1); return; }\n go(newOffset);\n }, 'Go');\n jumpBtn.dataset.pager = 'go';\n\n el.append(info, spacer, firstBtn, prevBtn, pageInfo, nextBtn, lastBtn, jumpInput, jumpBtn);\n if (c.showExportButton) el.appendChild(this._createExportBtn());\n return el;\n }\n\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 // 0.7.0 \u2014 filter controls that are not text boxes (#37)\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 spec for a column, normalised: null for the 0.4 text box. */\n _filterKindFor(colIdx, header) {\n const fk = this.config.filterKinds;\n if (fk == null) return null;\n let spec;\n if (typeof fk === 'function') {\n try { spec = fk(colIdx, header); } catch (err) {\n console.error('[DataTable] filterKinds threw', err);\n spec = null;\n }\n } else {\n spec = perColumn(fk, colIdx);\n }\n if (spec == null || spec === 'text' || spec === false) return null;\n if (typeof spec === 'function') return { kind: 'custom', create: spec };\n if (typeof spec === 'object') {\n if (spec.kind === 'text') return null;\n if (spec.kind === 'chips') return spec;\n if (typeof spec.create === 'function') return { ...spec, kind: spec.kind || 'custom' };\n }\n if (spec === 'chips') return null; // chips need options\n return null;\n }\n\n /** The column's control \u2014 built once, then the same element every render. */\n _filterControlFor(colIdx, header) {\n const spec = this._filterKindFor(colIdx, header);\n if (!spec) return null;\n const have = this._filterControls.get(colIdx);\n if (have && have.kind === spec.kind && have.specKey === (spec.options || spec.create)) {\n return have.control;\n }\n if (have) this._destroyOneControl(have.control);\n const value = this._state.filters.get(colIdx) ?? null;\n const ctx = {\n column: colIdx,\n header,\n value,\n counts: this._filterCounts.get(colIdx) ?? null,\n table: this,\n setValue: (v) => this.setFilter(colIdx, v),\n };\n let control = null;\n try {\n control = spec.kind === 'chips' ? createChipsFilter(ctx, spec) : spec.create(ctx);\n } catch (err) {\n console.error('[DataTable] filter control threw while being built', err);\n control = null;\n }\n if (typeof Node !== 'undefined' && control instanceof Node) control = { el: control };\n if (!control || !control.el) return null;\n control.el.classList?.add('twm-dt-filter-control');\n this._filterControls.set(colIdx, {\n kind: spec.kind, specKey: spec.options || spec.create, control,\n match: typeof control.match === 'function' ? control.match\n : spec.kind === 'chips' ? chipsMatch(spec) : null,\n });\n return control;\n }\n\n /** The client-side rule for a column with a control, or null. */\n _filterMatcher(colIdx) {\n if (!this._filterControls.size && this.config.filterKinds == null) return null;\n const entry = this._filterControls.get(colIdx);\n if (entry) return entry.match || defaultControlMatch;\n // A control not yet built (no render yet, a restore): the spec decides.\n const spec = this._filterKindFor(colIdx, (this.config.headers || [])[colIdx]);\n if (!spec) return null;\n return spec.kind === 'chips' ? chipsMatch(spec) : (spec.match || defaultControlMatch);\n }\n\n _isEmptyFilterValue(v) {\n if (v == null || v === '' || v === false) return true;\n if (Array.isArray(v)) return v.length === 0;\n if (typeof v === 'object' && !(v instanceof Date)) {\n return Object.values(v).every((x) => x == null || x === '');\n }\n return false;\n }\n\n _destroyOneControl(control) {\n try { control?.destroy?.(); } catch (err) { console.error('[DataTable] filter control destroy threw', err); }\n control?.el?.remove?.();\n }\n\n _destroyFilterControls() {\n for (const { control } of this._filterControls.values()) this._destroyOneControl(control);\n this._filterControls.clear();\n }\n\n _notifyFilterChange() {\n if (typeof this.config.onFilterChange !== 'function') return;\n try { this.config.onFilterChange(this._filterList()); } catch (err) {\n console.error('[DataTable] onFilterChange threw', err);\n }\n }\n\n /** The column filters in force: `[{column, header, value}]`. */\n getFilters() {\n return this._filterList();\n }\n\n /**\n * Set one column's filter (`null`, `''` or an empty array clears it). The\n * value is whatever the column's control works in \u2014 text for the 0.4 box.\n */\n setFilter(colIdx, value) {\n if (this._stagedRefusal('setFilter')) return;\n const textBox = !this._filterKindFor(colIdx, (this.config.headers || [])[colIdx]);\n const v = textBox && value != null && typeof value !== 'string' ? String(value) : value;\n if (textBox) {\n const filterRow = this._wrapperEl?.querySelector('.twm-data-table__filter-row');\n const cell = filterRow?.children[this._domIdxOf(colIdx)];\n const input = cell?.querySelector('.twm-data-table__filter-input');\n if (input) input.value = v || '';\n }\n this._onFilterInput(colIdx, v ?? '');\n }\n\n /**\n * Counts for a column's filter control \u2014 chips draw them beside each\n * option (keyed by the option's value; `''` is \"no filter\"), a dimmed\n * chip at zero. `setFilterCounts(colIdx, counts)`, or\n * `setFilterCounts({[colIdx]: counts})` for several. They are kept, so a\n * control built later starts with them.\n */\n setFilterCounts(colIdx, counts) {\n if (colIdx && typeof colIdx === 'object' && counts === undefined) {\n for (const [k, c] of Object.entries(colIdx)) this.setFilterCounts(Number(k), c);\n return;\n }\n const col = Number(colIdx);\n if (!Number.isInteger(col)) return;\n if (counts == null) this._filterCounts.delete(col); else this._filterCounts.set(col, counts);\n const entry = this._filterControls.get(col);\n if (entry) {\n try { entry.control.setCounts?.(counts ?? null); } catch (err) {\n console.error('[DataTable] filter control setCounts threw', err);\n }\n }\n }\n\n /** What `setFilterCounts` last gave a column, or null. */\n getFilterCounts(colIdx) {\n return this._filterCounts.get(Number(colIdx)) ?? null;\n }\n\n // \u2500\u2500 focus across a render \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 _captureFocus070(doc) {\n const active = doc?.activeElement;\n if (!active || active === doc.body) return null;\n for (const [colIdx, { control }] of this._filterControls) {\n if (control.el?.contains?.(active)) {\n let sel = null;\n try {\n if (typeof active.selectionStart === 'number') sel = [active.selectionStart, active.selectionEnd];\n } catch (_) { /* not a text field */ }\n return { kind: 'control', colIdx, el: active, sel };\n }\n }\n // Inside an open detail (a button in it, a field): the detail is drawn\n // again by the render, so the same place in it \u2014 by its path under the\n // detail's host \u2014 gets the focus back (the release review).\n const detailHost = active.closest?.('.twm-dt-detail');\n if (detailHost && this._tbodyEl?.contains(detailHost)) {\n const tr = detailHost.closest('tr')?.__detailOf;\n if (tr && tr.__rowIndex !== undefined) {\n const path = [];\n for (let n = active; n && n !== detailHost; n = n.parentElement) {\n path.unshift(Array.prototype.indexOf.call(n.parentElement.children, n));\n }\n let sel = null;\n try {\n if (typeof active.selectionStart === 'number') sel = [active.selectionStart, active.selectionEnd];\n } catch (_) { /* not a text field */ }\n return { kind: 'detail', key: this._rowKey(tr.__row, tr.__rowIndex), path, tag: active.tagName, sel };\n }\n }\n const toggle = active.closest?.('.twm-dt-detail-toggle');\n if (toggle && this._tbodyEl?.contains(toggle)) {\n const tr = toggle.closest('tr');\n if (tr && tr.__rowIndex !== undefined) {\n return { kind: 'toggle', key: this._rowKey(tr.__row, tr.__rowIndex) };\n }\n }\n return null;\n }\n\n _restoreFocus070(f) {\n try {\n if (f.kind === 'control') {\n if (!f.el.isConnected) return;\n f.el.focus({ preventScroll: true });\n if (f.sel) f.el.setSelectionRange?.(f.sel[0], f.sel[1]);\n } else if (f.kind === 'detail' && f.key !== null) {\n let n = this._rowElByKey(f.key)?.__detail?.[0]?.querySelector('.twm-dt-detail');\n for (const i of f.path) n = n?.children[i];\n if (n && n.tagName === f.tag) {\n n.focus({ preventScroll: true });\n if (f.sel) n.setSelectionRange?.(f.sel[0], f.sel[1]);\n }\n } else if (f.kind === 'toggle' && f.key !== null) {\n const tr = this._rowElByKey(f.key);\n tr?.querySelector(':scope > td > .twm-dt-detail-toggle')?.focus({ preventScroll: true });\n }\n } catch (_) { /* detached */ }\n }\n\n /** The one row spanning every column that says there are no rows (or why\n * they could not be read). Under `dataSource` the plain message is drawn\n * by class, so it is quiet while the first answer is on its way. */\n _buildEmptyRow(colCount, emptyMessage) {\n const emptyTr = document.createElement('tr');\n emptyTr.className = 'data-preview-row data-table__empty-row';\n const emptyTd = document.createElement('td');\n emptyTd.colSpan = colCount;\n if (this._error) {\n // 0.5.0. Nothing to keep: the failure takes the empty row.\n emptyTd.className = 'twm-data-table__empty-cell twm-data-table__empty-cell--error';\n emptyTd.setAttribute('role', 'alert');\n this._appendStateContent(emptyTd, this._errorContent());\n } else if (this.config.emptyState !== undefined) {\n // 0.5.0. The consumer's own words (or node), styled by class\n // rather than inline, and quiet while the table is loading.\n emptyTd.className = 'twm-data-table__empty-cell twm-data-table__empty-cell--state';\n const state = typeof this.config.emptyState === 'function'\n ? this.config.emptyState() : this.config.emptyState;\n this._appendStateContent(emptyTd, state);\n } else if (this.config.dataSource) {\n emptyTd.className = 'twm-data-table__empty-cell twm-data-table__empty-cell--state';\n emptyTd.textContent = emptyMessage;\n } else {\n emptyTd.style.cssText\n = 'text-align:center; font-style:italic; color:#888; padding:16px;';\n emptyTd.textContent = emptyMessage;\n }\n emptyTr.appendChild(emptyTd);\n return emptyTr;\n }\n\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 // 0.5.0 \u2014 decoration, states and the typed columns\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 class list both halves of the table carry: the 0.4 pair, plus the\n * 0.5.0 modifiers a consumer asked for. */\n _tableClassName() {\n const names = this.config.readonly\n ? ['twm-preview-table', 'twm-preview-table--readonly']\n : ['twm-preview-table'];\n if (this.config.firstColumn === 'plain') names.push('twm-dt--first-plain');\n if (this._isClickable()) names.push('twm-dt--clickable');\n // STORY-0016. The select column, and whether the mode is on.\n if (this._gutter) names.push('twm-dt--select');\n if (this._selecting) names.push('twm-dt--selecting');\n // STORY-0003.\n if (this._cellGrid) names.push('twm-dt--cells');\n return names.join(' ');\n }\n\n /** `clickable` when it is said; otherwise exactly when rows open. */\n _isClickable() {\n const c = this.config.clickable;\n if (c === true || c === false) return c;\n return typeof this.config.onRowActivate === 'function';\n }\n\n _fitsContent() {\n return !!this.config.fitContent || this._maxHeightCss() !== null;\n }\n\n _maxHeightCss() {\n const m = this.config.maxHeight;\n if (m == null || m === '' || m === false) return null;\n if (typeof m === 'number') return Number.isFinite(m) && m > 0 ? `${m}px` : null;\n return String(m);\n }\n\n _utc() {\n return String(this.config.dateTimeZone || '').toUpperCase() === 'UTC';\n }\n\n /**\n * What a column is drawn, sorted and filtered BY: its type, except that a\n * 'date', 'datetime' or 'duration' counts only when it was DECLARED through\n * `columnTypes`. In 0.4, whatever `getColumnType` returned was the cells'\n * class name and nothing more (only 'num' changed the sort and the\n * filter), so a consumer that returned 'date' there to style its cells gets\n * exactly 0.4 \u2014 its `formatValue`, its text sort, its text filter \u2014 and\n * the class name it asked for.\n */\n _valueKind(colIdx) {\n const t = this._columnTypes?.[colIdx];\n if (!TYPED_COLUMNS.has(t)) return t;\n const declared = Array.isArray(this.config.columnTypes) ? this.config.columnTypes[colIdx] : null;\n return declared === t ? t : 'text';\n }\n\n /** `classList.add` for whatever a hook returned: a string (space-separated\n * names allowed), an array of them, or nothing. */\n _addClasses(el, names) {\n if (!names) return [];\n const list = (Array.isArray(names) ? names : String(names).split(/\\s+/))\n .map((n) => String(n || '').trim()).filter(Boolean);\n if (list.length) el.classList.add(...list);\n return list;\n }\n\n /** A row's key, as text, or null: `getRowKey`, else its original index. */\n _rowKey(row, rowIdx) {\n const fn = this.config.getRowKey;\n let key;\n if (typeof fn === 'function') {\n try { key = fn(row, rowIdx); } catch (err) {\n console.error('[DataTable] getRowKey threw', err);\n key = null;\n }\n } else {\n key = rowIdx;\n }\n return key == null ? null : String(key);\n }\n\n /** The gestures `activateOn` names, as a set. */\n _activateOn() {\n const a = this.config.activateOn;\n const list = Array.isArray(a) ? a : [a || 'click'];\n return new Set(list.map((g) => String(g).toLowerCase()));\n }\n\n /**\n * Open a row on the gestures `activateOn` names, by the one rule in\n * `row_activation.js` (a control is its own gesture, a drag that selects\n * text is not a click, the second click of a double-click opens nothing).\n * Delegated on the body, bound after the selection handler.\n *\n * The listeners go in `_activationOffs`, not `_disposers`, and a render\n * retires them a task late (`_retireActivation`): a press whose selection\n * callback re-draws the table still opens the row it pressed \u2014 the row\n * as it was drawn (`tr.__row`), with its original index.\n */\n _installActivation(tbody, table) {\n const on = this._activateOn();\n const scope = this._wrapperEl;\n // A table that selects several rows reads Shift and Ctrl as SELECTION\n // gestures; one that does not leaves them to the consumer (ev.ctrlKey:\n // \"open it somewhere else\").\n const sel = this.config.selectable;\n const multi = !!sel && sel !== 'single';\n const fire = (tr, ev) => {\n // A table disposed by the press (its selection callback threw the\n // list away) opens nothing.\n if (!this._wrapperEl || typeof this.config.onRowActivate !== 'function') return;\n // STORY-0016. In select mode a gesture ticks; nothing opens.\n if (this._selecting) return;\n try { this.config.onRowActivate(tr.__rowIndex, tr.__row, ev); } catch (err) {\n console.error('[DataTable] onRowActivate threw', err);\n }\n };\n const rowFor = (ev) => {\n const tr = ev.target?.closest?.('tr');\n return tr && tr.__rowIndex !== undefined && tbody.contains(tr) ? tr : null;\n };\n const listen = (el, type, fn) => {\n el.addEventListener(type, fn);\n this._activationOffs.push(() => el.removeEventListener(type, fn));\n };\n if (on.has('click')) {\n listen(tbody, 'click', (ev) => {\n if (ev.button != null && ev.button !== 0) return;\n const tr = rowFor(ev);\n if (!tr || !isRowActivation(ev, 'click', { scope })) return;\n if (multi && (ev.shiftKey || ev.ctrlKey || ev.metaKey)) return;\n // 'single': a Ctrl click that took the row back OFF the\n // selection does not also open it (the selection handler, bound\n // first, said so on the event).\n if (DESELECTING_CLICKS.has(ev)) return;\n fire(tr, ev);\n });\n }\n if (on.has('dblclick')) {\n listen(tbody, 'dblclick', (ev) => {\n const tr = rowFor(ev);\n if (!tr || !isRowActivation(ev, 'dblclick', { scope })) return;\n fire(tr, ev);\n });\n }\n if (on.has('enter')) {\n listen(table, 'keydown', (ev) => {\n if (ev.key !== 'Enter' || ev.isComposing) return;\n if (ev.ctrlKey || ev.metaKey || ev.altKey || ev.shiftKey) return;\n if (isRowControl(ev.target, table)) return;\n const tr = this._currentRowEl();\n if (!tr) return;\n ev.preventDefault();\n fire(tr, ev);\n });\n }\n }\n\n /**\n * The row Enter opens: the SELECTED one \u2014 the one row selected, or the\n * selection's anchor \u2014 because that is the row a person just chose (a\n * double-click opens the row it lands on, and Enter must agree with it);\n * the open row (`activeRow`) only when nothing is selected. A selected row\n * that is not drawn (another page) opens nothing rather than a different\n * row.\n */\n _currentRowEl() {\n const tbody = this._tbodyEl;\n if (!tbody) return null;\n const selected = this._state.selected;\n let idx = null;\n if (selected.size === 1) idx = [...selected][0];\n else if (this._state.anchorIndex != null && selected.has(this._state.anchorIndex)) {\n idx = this._state.anchorIndex;\n }\n if (idx != null) return this.getRowElement(idx);\n if (this._activeKey !== null) {\n for (const tr of tbody.children) {\n if (tr.__rowIndex !== undefined && tr.classList.contains('twm-dt-row--active')) return tr;\n }\n }\n return null;\n }\n\n /** 0.6.1. The `diff` answer for one row, or `null` when there is none or\n * its status is not one this component draws. */\n _diffOf(row, rowIdx) {\n if (typeof this.config.diff !== 'function') return null;\n const answer = this.config.diff(row, rowIdx);\n if (!answer || !DIFF_STATUSES.has(answer.status)) return null;\n return answer;\n }\n\n /** Everything `rowClass`, `rowAttrs` and the open mark put on a `<tr>`,\n * taken off again first \u2014 so `updateRow` cannot leave last state's class\n * behind. */\n _decorateRow(tr, row, rowIdx) {\n // The row's data, for a delegated handler (`onRowActivate`).\n tr.__row = row;\n const { rowClass, rowAttrs } = this.config;\n if (tr.__twmClasses) {\n for (const c of tr.__twmClasses) tr.classList.remove(c);\n tr.__twmClasses = null;\n }\n if (typeof rowClass === 'function') {\n const added = this._addClasses(tr, rowClass(row, rowIdx));\n // Never take away a class this component owns.\n tr.__twmClasses = added.filter((c) => c !== 'data-preview-row' && c !== 'selected');\n }\n // 0.6.1 `diff`: the row's status, taken off again first like `rowClass`.\n for (const c of [...tr.classList]) {\n if (c === 'twm-dt-diff' || c.startsWith('twm-dt-diff--')) tr.classList.remove(c);\n }\n const diff = this._diffOf(row, rowIdx);\n if (diff) tr.classList.add('twm-dt-diff', `twm-dt-diff--${diff.status}`);\n if (tr.__twmAttrs) {\n for (const name of tr.__twmAttrs) tr.removeAttribute(name);\n tr.__twmAttrs = null;\n }\n if (typeof rowAttrs === 'function') {\n const attrs = rowAttrs(row, rowIdx) || {};\n const set = [];\n for (const [name, value] of Object.entries(attrs)) {\n if (value == null || value === false) continue;\n try {\n tr.setAttribute(name, value === true ? '' : String(value));\n set.push(name);\n } catch (err) {\n console.error(`[DataTable] rowAttrs: bad attribute \"${name}\"`, err);\n }\n }\n tr.__twmAttrs = set;\n }\n if (typeof this.config.getRowKey === 'function' || this._activeKey !== null) {\n tr.__rowKey = this._rowKey(row, rowIdx);\n }\n this._paintActive(tr);\n // 0.7.0 `follow`/`refresh`: a row the last answer did not have.\n if (this._newKeys) {\n tr.classList.toggle('twm-dt-row--new', this._newKeys.has(this._rowKey(row, rowIdx)));\n }\n }\n\n /** The open mark on one row, from `_activeKey`. */\n _paintActive(tr) {\n if (tr.__rowKey === undefined && this._activeKey !== null && tr.__rowIndex !== undefined) {\n // A row drawn before a key was asked for (setActiveRow after render).\n const rows = this.config.rows;\n const local = this._virt ? this._virtLocalOf(tr.__rowIndex) : -1;\n const row = local >= 0 ? this._virt.rows[local] : rows?.[tr.__rowIndex];\n tr.__rowKey = this._rowKey(row, tr.__rowIndex);\n }\n const on = this._activeKey !== null && tr.__rowKey === this._activeKey;\n tr.classList.toggle('twm-dt-row--active', on);\n // `aria-current` is taken off only where THIS component wrote it. A\n // consumer that marks its open row itself (0.4 had no mark of its own,\n // and `updateRow` re-decorates a row) keeps the attribute it set.\n if (on) {\n if (tr.getAttribute('aria-current') !== 'true') {\n tr.setAttribute('aria-current', 'true');\n tr.__twmAriaCurrent = true;\n }\n } else if (tr.__twmAriaCurrent) {\n tr.__twmAriaCurrent = false;\n if (!(tr.__twmAttrs || []).includes('aria-current')) tr.removeAttribute('aria-current');\n }\n }\n\n /** The row icon, drawn by CSS from `data-twm-icon` so that its name is in\n * neither `textContent`, the clipped-cell tooltip nor a copy. */\n _prependRowIcon(td, spec) {\n if (!spec) return;\n const s = typeof spec === 'string' ? { icon: spec } : spec;\n if (!s.icon) return;\n const icon = document.createElement('span');\n icon.className = 'material-symbols-outlined twm-dt-row-icon'\n + (s.tone ? ` twm-dt-row-icon--${String(s.tone).replace(/[^\\w-]/g, '')}` : '');\n icon.dataset.twmIcon = String(s.icon);\n if (s.title) {\n icon.title = String(s.title);\n icon.setAttribute('role', 'img');\n icon.setAttribute('aria-label', String(s.title));\n } else {\n icon.setAttribute('aria-hidden', 'true');\n }\n td.insertBefore(icon, td.firstChild);\n td.classList.add('twm-dt-cell--has-icon');\n }\n\n /** Text, a node, or nothing, into an empty-state cell. */\n _appendStateContent(td, content) {\n if (content == null || content === false) return;\n if (typeof Node !== 'undefined' && content instanceof Node) td.appendChild(content);\n else td.textContent = String(content);\n }\n\n /** What `setError` holds, as something `_appendStateContent` can draw. */\n _errorContent() {\n const e = this._error;\n if (e == null) return null;\n if (typeof Node !== 'undefined' && e instanceof Node) return e;\n if (e instanceof Error) return e.message || String(e);\n if (typeof e === 'object' && e.message) return String(e.message);\n return String(e);\n }\n\n /** The failure banner over rows that are kept. */\n _createErrorBanner() {\n const banner = document.createElement('div');\n banner.className = 'twm-data-table__error';\n banner.setAttribute('role', 'alert');\n const icon = document.createElement('span');\n icon.className = 'material-symbols-outlined twm-data-table__error-icon';\n icon.setAttribute('aria-hidden', 'true');\n icon.textContent = 'error';\n const text = document.createElement('span');\n text.className = 'twm-data-table__error-text';\n const content = this._errorContent();\n // A node is the consumer's (and is MOVED here); a copy would lose its\n // listeners.\n if (typeof Node !== 'undefined' && content instanceof Node) text.appendChild(content);\n else text.textContent = String(content ?? '');\n banner.append(icon, text);\n return banner;\n }\n\n /** The `sortValue` hook for one column, or null. */\n _sortValueFor(colIdx) {\n const sv = this.config.sortValue;\n if (typeof sv === 'function') return sv;\n const fn = perColumn(sv, colIdx);\n return typeof fn === 'function' ? fn : null;\n }\n\n /** The words for a value in a typed column, or `undefined` when the\n * column is not typed (or the value is empty). */\n _formatTyped(value, colIdx) {\n const kind = this._valueKind(colIdx);\n if (!TYPED_COLUMNS.has(kind) || value == null || value === '') return undefined;\n if (kind === 'duration') {\n return formatDuration(value, perColumn(this.config.durationFormat, colIdx) || 'auto');\n }\n const pattern = kind === 'datetime'\n ? perColumn(this.config.dateTimeFormat, colIdx) || ISO_DATETIME\n : perColumn(this.config.dateFormat, colIdx) || ISO_DATE;\n if (typeof pattern === 'function') {\n const t = parseDateValue(value, { utc: this._utc() });\n return Number.isFinite(t) ? String(pattern(new Date(t), colIdx, value) ?? '') : String(value);\n }\n return formatDate(value, pattern, { utc: this._utc() });\n }\n\n /** Sync the (separate) header table's column widths to the body\n * table's measured widths. Without this, the two tables compute\n * widths independently and the columns drift apart. Locks both\n * tables to `table-layout: fixed` and writes explicit width onto\n * each header cell of every header row (header + filter row). */\n /**\n * Measure every column's NATURAL content width, in one transient reflow.\n *\n * Extracted from `_syncHeaderWidths` so that auto-size can ask the same\n * question the fit pass asks, and get the same answer. Two measurement\n * passes would drift, and the drift would show as a double-click that\n * sized a column differently from the render that follows it.\n *\n * The pass ignores the CSS caps (the 150px-pinned first column, the 80px\n * min on the rest) and the filter-row inputs: `twm-dt-measuring` flips both\n * tables to `table-layout:auto; width:max-content` with those caps off (via\n * `!important`) for a single reflow, then reverts before paint \u2014 it is\n * never visible. Clearing inline widths first stops the last sync's forced\n * widths from constraining the measure.\n *\n * C10 \u2014 UNDER `virtualize` ONLY THE WINDOW IS IN THE DOM, so `max-content`\n * spans the eighty-odd rows drawn rather than every row loaded. The fit\n * pass that runs on every render is content with that (it is fitting what\n * is on screen). An EXPLICIT auto-size is not: it is a promise to fit the\n * column's content, and the longest value in a 6,000-row table is usually\n * not in the window. So `sample` adds, for the length of this one reflow,\n * the row holding each column's longest value \u2014 see `_virtSampleRows`.\n *\n * @param {{sample?: boolean}} [o]\n * @returns {number[]|null} width per DOM column index, or null when there\n * is nothing laid out to measure.\n */\n _measureNaturalWidths({ sample = false } = {}) {\n const headerTable = this._headerTableEl;\n const bodyTable = this._tableEl;\n if (!headerTable || !bodyTable) return null;\n // A ROW OF DATA, not merely the first `<tr>`: under C10 that is a\n // spacer, and an embedder may inject rows of its own (a group header is\n // one cell spanning every column, which would measure as ONE column).\n const firstRow = this._firstBodyRow();\n if (!firstRow) return null;\n const bodyCells = firstRow.children;\n if (!bodyCells.length) return null;\n\n headerTable.querySelectorAll('thead > tr').forEach((tr) => {\n for (const th of tr.children) this._clearCellWidth(th);\n });\n for (const td of bodyCells) this._clearCellWidth(td);\n // C10: the `<col>`s are what hold the widths, so they are what has to\n // let go for the measure (`.twm-dt-measuring col` also overrides them).\n for (const col of this._cols() || []) col.style.width = '';\n headerTable.style.width = '';\n bodyTable.style.width = '';\n headerTable.classList.add('twm-dt-measuring');\n bodyTable.classList.add('twm-dt-measuring');\n // Appended at the end, where they move no drawn row, and taken out\n // again below before anything paints.\n const sampled = sample ? this._virtSampleRows() : [];\n for (const tr of sampled) this._virt.tbody.appendChild(tr);\n // Force layout flush so measurements are current.\n // eslint-disable-next-line no-unused-expressions\n bodyTable.offsetWidth;\n\n // Natural width per column = the wider of its header label and its\n // body content. `max-content` already spans every rendered body\n // row, so the body cell of the first row reports the whole column.\n const labelRow = headerTable.querySelector('thead > tr');\n const cols = bodyCells.length;\n const natural = new Array(cols);\n // \u2500\u2500 AND CSS `zoom` IS DIVIDED BACK OUT \u2500\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 // `getBoundingClientRect()` reports CLIENT pixels, so under a `zoom`\n // anywhere above this table every width read here comes back multiplied\n // by that zoom \u2014 while `_setCellWidth` writes a plain `width` in the\n // cell's OWN pixels, which the same zoom then multiplies again. The two\n // halves of one measure-and-apply loop would be in different units:\n // measured at 200% a column is pinned twice as wide as its text needs,\n // and at 50% it is pinned half as wide and every value ellipsises. The\n // fit pass has the same split, because its `avail` is `clientWidth`,\n // which is NOT zoom-adjusted.\n //\n // `currentCSSZoom` is the effective zoom on this element \u2014 1 when\n // nothing above it zooms, and `undefined` in an engine that predates\n // the property \u2014 so this is exactly a no-op for every consumer that\n // does not zoom, which is all of them but the Tables grid.\n const zoom = bodyTable.currentCSSZoom || 1;\n for (let i = 0; i < cols; i++) {\n const body = bodyCells[i].getBoundingClientRect().width / zoom;\n const head = labelRow && labelRow.children[i]\n ? labelRow.children[i].getBoundingClientRect().width / zoom\n : 0;\n natural[i] = Math.max(body, head);\n }\n // 0.7.0 `filterKinds`: A FILTER CONTROL IS IN THE MEASURE. The text\n // boxes stay out (an `<input>`'s default width would set every\n // column), but a control \u2014 the Level chips with their counts \u2014 is\n // drawn at its NARROWEST (`min-content`: the widest chip) for this\n // reflow, so the label row's width above already spans it, and that\n // narrowest width is kept as the column's FLOOR for the fit pass,\n // which would otherwise squeeze the column under one chip in a narrow\n // tile and cut it off. Above the floor the cell wraps its chips.\n const floors = new Array(cols).fill(0);\n const filterRow = headerTable.querySelector('thead > tr.twm-data-table__filter-row--controls');\n if (filterRow) {\n for (let i = 0; i < cols && i < filterRow.children.length; i++) {\n const th = filterRow.children[i];\n if (!th.classList.contains('data-table__filter-cell--control')) continue;\n const el = th.firstElementChild;\n if (!el) continue;\n const cs = getComputedStyle(th);\n const pad = (parseFloat(cs.paddingLeft) || 0) + (parseFloat(cs.paddingRight) || 0)\n + (parseFloat(cs.borderLeftWidth) || 0) + (parseFloat(cs.borderRightWidth) || 0);\n floors[i] = Math.ceil(el.getBoundingClientRect().width / zoom + pad);\n natural[i] = Math.max(natural[i], floors[i]);\n }\n }\n this._filterFloors = floors;\n\n for (const tr of sampled) tr.remove();\n headerTable.classList.remove('twm-dt-measuring');\n bodyTable.classList.remove('twm-dt-measuring');\n return natural;\n }\n\n /**\n * The rows an explicit auto-size must measure that the window has not\n * drawn: for each column, the drawable row whose value is LONGEST as a\n * string, plus the last row (the widest row number). Built with\n * `_buildBodyRow` \u2014 so a consumer's `renderCell` draws them exactly as it\n * would on screen \u2014 and handed back detached, for `_measureNaturalWidths`\n * to put in and take out around its one reflow.\n *\n * The string length is a proxy, not a measurement: in a proportional font\n * forty `i`s are narrower than thirty `W`s. It is the proxy a spreadsheet's\n * own autofit falls short by, and it is right about the case that matters\n * here \u2014 a value five times longer than anything in the window. One pass\n * over the loaded rows, on a click and never on a scroll or a resize.\n *\n * @returns {HTMLTableRowElement[]}\n */\n _virtSampleRows() {\n const v = this._virt;\n if (!v || !v.rows.length) return [];\n const longest = [];\n const at = [];\n let last = -1;\n for (let i = 0; i < v.rows.length; i++) {\n if (!(v.heights[i] > 0)) continue; // hidden: not drawn, not fitted\n last = i;\n const row = v.rows[i];\n if (!Array.isArray(row)) continue;\n for (let c = 0; c < row.length; c++) {\n const value = row[c];\n const len = value == null ? 0 : String(value).length;\n if (len > (longest[c] ?? -1)) { longest[c] = len; at[c] = i; }\n }\n }\n const want = new Set(at.filter((i) => i !== undefined));\n if (last >= 0) want.add(last);\n const rows = [];\n for (const i of want) {\n if (v.map.has(i)) continue; // drawn already; measured anyway\n const tr = this._buildBodyRow(v.rows[i], v.globalOf(i), i);\n tr.setAttribute('aria-hidden', 'true');\n rows.push(tr);\n }\n return rows;\n }\n\n /**\n * Fit one column to its widest value and pin it there \u2014 every loaded\n * row's, under `virtualize` (see `_virtSampleRows`), not only the window's.\n *\n * The gesture is a double-click on the column's resize grip, which is where\n * every spreadsheet has put it \u2014 and the grip is this component's, which is\n * why the behaviour is too. A consumer that wanted this had no hook to hang\n * it on: `_installColumnResizers` bound `mousedown` and a `click` that only\n * suppressed the sort, and the measurement, the pin, the table-width\n * invariant and the write-through to `stateStore` are all private here.\n *\n * @param {number} domIdx column index INCLUDING the row-number column when\n * `showRowNumbers` is on \u2014 the same index space as `_colWidths`.\n * @param {{maxWidth?: number}} [opts] ceiling; defaults to AUTOSIZE_MAX_PX.\n * @returns {boolean} whether it had a layout to measure.\n */\n autoSizeColumn(domIdx, opts = {}) {\n const natural = this._measureNaturalWidths({ sample: true });\n if (!natural || domIdx < this._lead().select || domIdx >= natural.length) return false;\n this._colWidths[domIdx] = this._autoWidth(natural[domIdx], opts);\n this._colWidthsSig = this._colSig();\n this._savePersisted();\n this._syncHeaderWidths();\n return true;\n }\n\n /**\n * The same for every column at once.\n *\n * It REPLACES existing drag overrides rather than sizing around them: \"fit\n * every column to its content\" that quietly excepted the three columns you\n * had dragged would be a button whose result depends on history nobody can\n * see.\n *\n * The result may well be wider than the container \u2014 forty columns of real\n * content usually are \u2014 and that is the intended answer, not a failure:\n * `_syncHeaderWidths` honours overrides verbatim, sizes both tables to their\n * total and the body wrap scrolls sideways with the header following it.\n * Squeezing them to fit is what the automatic fit pass does on every render\n * already, so a button that did that would be a button that does nothing.\n */\n autoSizeColumns(opts = {}) {\n const natural = this._measureNaturalWidths({ sample: true });\n if (!natural) return false;\n this._colWidths = {};\n for (let i = this._lead().select; i < natural.length; i++) {\n this._colWidths[i] = this._autoWidth(natural[i], opts);\n }\n this._colWidthsSig = this._colSig();\n this._savePersisted();\n this._syncHeaderWidths();\n return true;\n }\n\n /** One measured width, floored at the drag-resize minimum and capped, with\n * the same sub-pixel pad `_fitColumnWidths` adds against ellipsis. */\n _autoWidth(natural, opts = {}) {\n const max = opts.maxWidth ?? AUTOSIZE_MAX_PX;\n return Math.min(max, Math.max(40, Math.ceil((natural || 0) + 2)));\n }\n\n /**\n * Does every one of the `n` DOM columns already carry an override taken\n * against the column set that is on screen right now?\n *\n * The signature half is not belt-and-braces. `render()` drops `_colWidths`\n * when `_colSig` changes, but `_syncHeaderWidths` is also reached straight\n * from the ResizeObserver, which never goes through `render()` \u2014 so a set\n * of overrides measured against the PREVIOUS headers can still be sitting\n * in `_colWidths` when this is asked. Answering \"pinned\" then would skip\n * the measure and hand `_fitColumnWidths` widths keyed to columns that are\n * no longer there, each one landing on its neighbour.\n *\n * `== null` rather than a falsy test, to match `_fitColumnWidths`' own\n * `overrides[i] != null`: a legitimately-stored 0 must be read the same way\n * in both places or the two disagree about which columns are flexible.\n */\n _allColumnsPinned(n) {\n if (!n || this._colWidthsSig !== this._colSig()) return false;\n for (let i = this._lead().select; i < n; i++) {\n if (this._colWidths[i] == null) return false;\n }\n return true;\n }\n\n /** Sync the (separate) header table's column widths to the body\n * table's measured widths. Without this, the two tables compute\n * widths independently and the columns drift apart. Locks both\n * tables to `table-layout: fixed` and writes explicit width onto\n * each header cell of every header row (header + filter row). */\n _syncHeaderWidths() {\n const headerTable = this._headerTableEl;\n const bodyTable = this._tableEl;\n if (!headerTable || !bodyTable) return;\n // C10. UNDER `virtualize` THE COLUMN TRACK IS THE `<colgroup>`, and the\n // column count is ITS length \u2014 not the first row's, which is whatever\n // row the window happens to start at (or a spacer). Without it, the\n // first ROW OF DATA; see `_firstBodyRow` for why not merely the first `<tr>`.\n const cols = this._cols();\n const firstRow = this._firstBodyRow();\n const bodyCells = cols ? [] : firstRow?.children;\n const n = cols ? cols.length : (bodyCells?.length || 0);\n if (!n) return;\n\n const headerRows = headerTable.querySelectorAll('thead > tr');\n // DO NOT MEASURE WHAT NOTHING WILL READ.\n //\n // `_measureNaturalWidths` flips BOTH tables to\n // `table-layout:auto; width:max-content` with the CSS caps lifted, for\n // a full synchronous reflow (`.twm-dt-measuring`, css/flexdesk.css). This\n // method is the ResizeObserver's callback, so that reflow fires once\n // per animation frame for the whole of a splitter drag \u2014 and an\n // embedder that pages a thousand rows at a time across twenty columns\n // re-lays-out ~20,000 cells per frame for it.\n //\n // When every column is pinned, `_fitColumnWidths` reads `natural[i]`\n // for no `i` at all: each column takes its override verbatim, and the\n // only thing left that the array supplies is `n`, which is its length.\n // So zeroes of the right length are not an approximation of the\n // measurement, they are indistinguishable from it.\n const natural = this._allColumnsPinned(n)\n ? new Array(n).fill(0)\n : this._measureNaturalWidths();\n if (!natural) return;\n\n // \u2500\u2500 Fit pass: turn natural widths into final widths that respect\n // the available space, favour the first column, and cap runaways.\n // User-dragged columns (`_colWidths`) are honored as-is inside.\n const wrap = this._tableWrapEl;\n const headerWrap = this._headerWrapEl;\n const avail = wrap ? wrap.clientWidth : 0;\n const lead = this._lead().all;\n const firstIdx = lead && n > lead ? lead : 0;\n const widths = this._fitColumnWidths(natural, avail, {\n firstIdx,\n // STORY-0016. The select column is as wide as its controls, always.\n overrides: this._gutter ? { ...this._colWidths, 0: this._selectColWidth() } : this._colWidths,\n fit: this.config.columnFit,\n floors: this._filterFloors,\n });\n const total = widths.reduce((a, b) => a + b, 0);\n\n // Apply measured widths to every header row at the matching\n // column index AND the body's first row, so both tables compute\n // the SAME column track. `_setCellWidth` also clears any CSS\n // min/max-width (e.g. the 150px-pinned first \"time\" column) so\n // the explicit width is actually honored.\n headerRows.forEach((tr) => {\n for (let i = 0; i < tr.children.length && i < widths.length; i++) {\n this._setCellWidth(tr.children[i], widths[i]);\n }\n });\n if (cols) {\n for (let i = 0; i < cols.length && i < widths.length; i++) {\n cols[i].style.width = `${widths[i]}px`;\n }\n } else {\n for (let i = 0; i < bodyCells.length && i < widths.length; i++) {\n this._setCellWidth(bodyCells[i], widths[i]);\n }\n }\n\n // Lock both tables so the widths stick even when content changes.\n headerTable.style.tableLayout = 'fixed';\n bodyTable.style.tableLayout = 'fixed';\n\n // Size both tables to the explicit column TOTAL (not the CSS\n // `width: 100%`) so a widened column GROWS the table and the\n // body wrap scrolls horizontally, instead of squeezing into a\n // fixed budget and stealing from its neighbours. When the\n // columns fit and the user hasn't dragged, stay at 100% to fill\n // the container exactly with no phantom scrollbar.\n const hasOverride = Object.keys(this._colWidths).length > 0;\n if (hasOverride || total > avail + 1) {\n headerTable.style.width = `${total}px`;\n bodyTable.style.width = `${total}px`;\n } else {\n headerTable.style.width = '';\n bodyTable.style.width = '';\n }\n\n // Scrollbar gutter: when the body shows a vertical scrollbar, its\n // content is narrower than the wrap by `scrollbarW`. The header\n // wrap has no scrollbar, so pad it on the right to match.\n //\n // C29b. AND THE SAME NUMBER IS PUBLISHED AS A CUSTOM PROPERTY, because\n // padding does not help the one thing C29 was for. A `position: sticky`\n // cell pins to its scroll container's SCROLLPORT, and the scrollport of\n // a box with a classic scrollbar excludes that scrollbar while padding\n // is inside it \u2014 so `right: 0` in the body pins `sbw` px to the LEFT of\n // `right: 0` in the header, and a pinned trailing column would sit\n // visibly out of line with its own heading. There is nothing a\n // stylesheet can measure this from: it is the platform's scrollbar\n // width, known here and nowhere else. Written on the WRAPPER rather\n // than either box so a consumer's rule can read it from whichever of\n // the two it is styling, and written on every sync because a scrollbar\n // appears and disappears with the row count.\n if (wrap && headerWrap) {\n const sbw = Math.max(0, wrap.offsetWidth - wrap.clientWidth);\n headerWrap.style.paddingRight = sbw ? `${sbw}px` : '';\n this._wrapperEl?.style?.setProperty('--twm-dt-gutter', `${sbw}px`);\n }\n\n // Keep the header aligned with the body's current horizontal\n // scroll (a resize can clamp scrollLeft).\n this._syncHeaderScroll();\n\n // Columns are now fixed-width: any cell whose text was clipped\n // gets a hover tooltip carrying the full value.\n this._updateCellTooltips();\n }\n\n /**\n * Convert measured natural content widths into final column widths.\n *\n * Goals (the \"intelligent\" sizing):\n * - every column wants its content width (+a hair), clamped to a\n * sane [floor, cap]; the FIRST content column gets a more generous\n * cap so it shows its full value;\n * - user-dragged columns (`overrides`) are pinned, never grown/shrunk;\n * - if everything fits, grow the flexible columns evenly to fill the\n * width (no dead gap on the right);\n * - if it doesn't fit, protect the first column and water-fill-shrink\n * the rest (trim the widest first) until it fits; only if even the\n * floors overflow do we give up and let the body scroll sideways.\n *\n * Under `fit: 'content'` the first and last of those goals invert: each\n * unpinned column asks for its own content width through the same\n * `_autoWidth` the grip double-click uses, and an overflow is the answer\n * rather than a problem \u2014 the caller wanted a table that scrolls sideways,\n * not one squeezed toward the floor. The grow-to-fill branch is shared by\n * both, because a table narrower than its container leaves a dead gap on\n * the right under either reading.\n *\n * @param {number[]} natural measured content width per column (px)\n * @param {number} avail usable width of the body wrap (px)\n * @param {{firstIdx?:number, overrides?:Object, fit?:'container'|'content'}} [opts]\n * @returns {number[]} final width per column (px)\n */\n _fitColumnWidths(natural, avail, opts = {}) {\n const FLOOR = 40; // matches the drag-resize minimum\n const CAP = 360; // general per-column ceiling\n const FIRST_CAP = 520; // the first column may run wider\n const PAD = 2; // sub-pixel safety against ellipsis\n\n const n = natural.length;\n const firstIdx = opts.firstIdx ?? 0;\n const overrides = opts.overrides || {};\n // 0.7.0: a column's own floor (its filter control's narrowest width,\n // `_measureNaturalWidths`) \u2014 never squeezed below it, even when the\n // table then scrolls sideways.\n const floors = Array.isArray(opts.floors) ? opts.floors : [];\n const floorOf = (i) => Math.max(FLOOR, Math.ceil(floors[i] || 0));\n // Anything that is not the literal opt-in is the historical behaviour.\n // Read once, so an embedder that passes a typo gets the old layout\n // rather than half of each.\n const toContent = opts.fit === 'content';\n\n // Desired (pre-fit) width per column. Pinned columns take their\n // override verbatim and sit out the grow/shrink redistribution.\n const desired = new Array(n);\n const pinned = new Array(n).fill(false);\n for (let i = 0; i < n; i++) {\n if (overrides[i] != null) {\n desired[i] = Math.max(FLOOR, Math.round(overrides[i]));\n pinned[i] = true;\n continue;\n }\n if (toContent) {\n // THE SAME CALL THE GRIP DOUBLE-CLICK MAKES \u2014 `autoSizeColumn`\n // \u2192 `_autoWidth` \u2014 and deliberately not a second arithmetic\n // that happens to agree with it today. Two width formulas\n // drift, and the drift shows up as a column that jumps the\n // first time anyone double-clicks its grip.\n //\n // FIRST_CAP has nothing to say here. It exists to favour one\n // column while the others are being squeezed; under a content\n // fit nothing is being squeezed, so there is no column to\n // favour and every one of them is held to the same ceiling.\n desired[i] = this._autoWidth(natural[i]);\n continue;\n }\n const cap = i === firstIdx ? FIRST_CAP : CAP;\n desired[i] = Math.min(cap, Math.max(FLOOR, Math.ceil(natural[i] + PAD)));\n }\n\n const widths = desired.slice();\n const sum = widths.reduce((a, b) => a + b, 0);\n\n // Not laid out yet (or content already exactly fits): hand back the\n // desired widths; the caller decides fill vs horizontal scroll.\n if (avail <= 1) return widths;\n\n if (sum <= avail) {\n // Grow flexible columns evenly to fill the remaining space so\n // the table doesn't leave a dead gap on the right. When EVERY\n // column is pinned (e.g. after the user has dragged a column \u2014\n // the resize freezes all columns as overrides), fall back to\n // the last column so the table still spans the full container:\n // the width invariant \u2014 a table never renders narrower than\n // 100% of its wrap.\n const flex = [];\n for (let i = 0; i < n; i++) if (!pinned[i]) flex.push(i);\n const slack = avail - sum;\n if (slack > 0) {\n const targets = flex.length ? flex : [n - 1];\n const per = Math.floor(slack / targets.length);\n for (const i of targets) widths[i] += per;\n widths[targets[targets.length - 1]] += slack - per * targets.length;\n }\n return widths;\n }\n\n // OVERFLOW IS THE ANSWER UNDER A CONTENT FIT, not a case to recover\n // from. Everything below squeezes the unprotected columns toward the\n // 40px floor so that forty columns can be made to fit a pane \u2014 which is\n // precisely the outcome `columnFit: 'content'` opted out of. Handing\n // back the content widths lets the caller's `total > avail + 1` test\n // size both tables to the total, and the body wrap then scrolls\n // sideways with the header following it.\n if (toContent) return widths;\n\n // Overflow: protect the first column + pinned columns, water-fill\n // the rest down toward the floor.\n let protectedSum = 0;\n const shrinkable = [];\n for (let i = 0; i < n; i++) {\n if (pinned[i] || i === firstIdx) protectedSum += widths[i];\n else shrinkable.push(i);\n }\n const budget = avail - protectedSum;\n if (budget < shrinkable.length * FLOOR) {\n // Even at the floor we overflow \u2192 let the body scroll sideways.\n for (const i of shrinkable) widths[i] = floorOf(i);\n return widths;\n }\n // Max-min fair allocation: the narrow columns keep their content,\n // the widest share the remaining budget equally.\n shrinkable.sort((a, b) => desired[a] - desired[b]);\n let remaining = budget;\n for (let k = 0; k < shrinkable.length; k++) {\n const colsLeft = shrinkable.length - k;\n const fair = Math.floor(remaining / colsLeft);\n const i = shrinkable[k];\n if (desired[i] <= fair) {\n widths[i] = desired[i];\n remaining -= desired[i];\n } else {\n const level = Math.max(FLOOR, fair);\n for (let j = k; j < shrinkable.length; j++) {\n widths[shrinkable[j]] = Math.max(level, floorOf(shrinkable[j]));\n }\n // Dump any rounding remainder onto the widest column.\n const leftover = remaining - colsLeft * level;\n if (leftover > 0) widths[shrinkable[shrinkable.length - 1]] += leftover;\n break;\n }\n }\n return widths;\n }\n\n /** Set an explicit width on a table cell, clearing any CSS min/max\n * width constraint so the width is honored exactly. The first\n * (\"time\") column is pinned to 150px by `min/max-width` in CSS;\n * without this, dragging it does nothing and the slack leaks to the\n * other columns. */\n _setCellWidth(cell, w) {\n cell.style.width = `${w}px`;\n cell.style.minWidth = '0';\n cell.style.maxWidth = 'none';\n }\n\n /** Undo `_setCellWidth` so a re-measure sees the cell's natural,\n * CSS-constrained width again. */\n _clearCellWidth(cell) {\n cell.style.width = '';\n cell.style.minWidth = '';\n cell.style.maxWidth = '';\n }\n\n /** Wire the body wrap's horizontal scroll to the header. The header\n * sits in an overflow:hidden wrap, so it can't scroll sideways on\n * its own \u2014 `_syncHeaderScroll` scrolls it programmatically to the\n * body's `scrollLeft`. Re-installed each render against the freshly-built\n * wrap. */\n _installHeaderScrollSync() {\n const wrap = this._tableWrapEl;\n if (!wrap) return;\n if (this._onBodyScroll && this._scrollSyncEl) {\n this._scrollSyncEl.removeEventListener('scroll', this._onBodyScroll);\n }\n this._onBodyScroll = () => this._syncHeaderScroll();\n this._scrollSyncEl = wrap;\n wrap.addEventListener('scroll', this._onBodyScroll, { passive: true });\n this._syncHeaderScroll();\n }\n\n /**\n * Scroll the header wrap to match the body's horizontal scroll so the\n * columns stay aligned when the table overflows sideways.\n *\n * \u2550\u2550 C29. A TRANSFORM IS WHAT MAKES A STICKY COLUMN IMPOSSIBLE \u2550\u2550\u2550\u2550\u2550\u2550\u2550\n *\n * This wrote `headerTable.style.transform = translateX(-scrollLeft)`. It\n * aligns the two tables perfectly and it forecloses `position: sticky`\n * entirely, because the two halves of the table then pin against different\n * things: a sticky cell in the BODY pins to the body wrap's scrollport,\n * while its header counterpart is moved by a transform inside a box that\n * never scrolls at all. Scroll sideways and the pinned body column stands\n * still while its header slides away with everything else \u2014 so a table\n * with a trailing verb column (the row-actions column Tables needs pinned\n * to the right edge) can have a sticky body or an aligned header, never\n * both. A transform also establishes a containing block for fixed/sticky\n * descendants, which breaks the header cell independently of the offset.\n *\n * AN `overflow: hidden` BOX IS STILL A SCROLL CONTAINER. It has no\n * scrollbar and no user affordance, and `scrollLeft` moves it exactly like\n * any other. Scrolling the wrap rather than transforming its child gives\n * the header a real scrollport at the same offset as the body's, which is\n * the one arrangement in which a sticky cell on each side pins to the same\n * place. Identical for ordinary content: same pixels, no transform, no new\n * containing block.\n *\n * THE CLAMP IS ALREADY PAID FOR. A scroll container clamps `scrollLeft` to\n * `scrollWidth - clientWidth`, and the body wrap carries a vertical\n * scrollbar the header wrap does not \u2014 so the header would clamp short by\n * the scrollbar width and desync at the far right. `_syncHeaderWidths`\n * already pads the header wrap by exactly that gutter (`paddingRight`,\n * :1905), and end padding counts toward `scrollWidth`, so the two maxima\n * coincide. The residual below is the honest belt for the day some engine\n * disagrees about that: it is zero in the ordinary case, so the transform\n * is not set and sticky keeps working, and it is the difference rather\n * than the whole offset if it is ever not.\n */\n _syncHeaderScroll() {\n const wrap = this._tableWrapEl;\n const headerTable = this._headerTableEl;\n if (!wrap || !headerTable) return;\n const x = wrap.scrollLeft;\n const headerWrap = this._headerWrapEl;\n if (!headerWrap) {\n // No wrap to scroll \u2014 a consumer that built the header some other\n // way still gets the behaviour it always had.\n headerTable.style.transform = x ? `translateX(${-x}px)` : '';\n return;\n }\n headerWrap.scrollLeft = x;\n const residual = x - headerWrap.scrollLeft;\n headerTable.style.transform = residual ? `translateX(${-residual}px)` : '';\n // STORY-0066. The group row follows the header: every width pass and\n // drag ends here, and so does every sideways scroll.\n this._colGroups()?.align();\n }\n\n /** Drag-to-resize: hang a thin grab handle off the right edge of\n * every header cell. Dragging it writes a per-column width override\n * (keyed by DOM index) that `_syncHeaderWidths` then honors. */\n _installColumnResizers() {\n const headerTable = this._headerTableEl;\n if (!headerTable) return;\n const headRow = headerTable.querySelector('thead > tr');\n if (!headRow) return;\n [...headRow.children].forEach((th, domIdx) => {\n if (th.querySelector('.twm-dt-col-resizer')) return;\n if (th.classList.contains('twm-dt-select-cell')) return; // STORY-0016: fixed\n th.classList.add('twm-dt-col');\n const grip = document.createElement('div');\n grip.className = 'twm-dt-col-resizer';\n grip.addEventListener('mousedown',\n (ev) => this._beginColResize(ev, domIdx));\n // Keep a resize gesture from registering as a sort click.\n grip.addEventListener('click', (ev) => ev.stopPropagation());\n // Double-click the grip: fit the column to its content. The gesture\n // every spreadsheet has, on the affordance it has always been on.\n // Stopped as well as prevented, or a consumer that opens a column\n // menu from the header (Tables does) opens it on the way past.\n grip.addEventListener('dblclick', (ev) => {\n ev.preventDefault();\n ev.stopPropagation();\n this.autoSizeColumn(domIdx);\n });\n th.appendChild(grip);\n });\n }\n\n /**\n * CSS px per screen px. Content inside a zoomed tile reports rects and\n * pointer coordinates in screen pixels, while `style.width` is CSS pixels;\n * mixing them widened every column by the zoom factor on a mere click.\n */\n _zoomFactor() {\n const el = this._tableWrapEl || this._tableEl;\n const css = el?.offsetWidth || 0;\n const screen = el?.getBoundingClientRect?.().width || 0;\n return css > 0 && screen > 0 ? screen / css : 1;\n }\n\n _beginColResize(ev, domIdx) {\n if (ev.button != null && ev.button !== 0) return;\n ev.preventDefault();\n ev.stopPropagation();\n const headerTable = this._headerTableEl;\n const bodyTable = this._tableEl;\n const headRow = headerTable && headerTable.querySelector('thead > tr');\n if (!headRow) return;\n\n // NOTHING HAPPENS UNTIL THE POINTER MOVES. Freezing on mousedown pinned\n // every column on a plain click, and the first click of a double-click,\n // so a click on a grip was already a resize and switched auto-fit off\n // for every column for good.\n //\n // Once the drag is real: freeze EVERY column at its current width on\n // BOTH tables and lock fixed layout, so the drag moves only the grabbed\n // column and a neighbour can never absorb it. Widths come from the\n // header row (the column source of truth), in CSS pixels.\n const startX = ev.clientX;\n const THRESHOLD = 3;\n const MIN = 40;\n let startWidths = null;\n const begin = () => {\n const z = this._zoomFactor();\n startWidths = [...headRow.children].map((c) => {\n const set = parseFloat(c.style.width);\n return Number.isFinite(set) ? set : c.getBoundingClientRect().width / z;\n });\n headerTable.style.tableLayout = 'fixed';\n if (bodyTable) bodyTable.style.tableLayout = 'fixed';\n startWidths.forEach((w, i) => this._pinColumnWidth(i, w));\n this._applyTableWidth();\n document.body.classList.add('twm-dt-col-resizing');\n };\n const onMove = (mv) => {\n const dx = mv.clientX - startX;\n if (!startWidths) {\n if (Math.abs(dx) < THRESHOLD) return;\n begin();\n }\n const w = Math.max(MIN, Math.round(startWidths[domIdx] + dx / this._zoomFactor()));\n this._pinColumnWidth(domIdx, w);\n // Pass the dragged column so the fill invariant reclaims any\n // freed width into a DIFFERENT (flexible/last) column, never\n // shrinking the table below the container.\n this._applyTableWidth(domIdx);\n this._syncHeaderScroll();\n };\n const onUp = () => {\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n if (!startWidths) return; // a click: nothing changed\n document.body.classList.remove('twm-dt-col-resizing');\n this._updateCellTooltips();\n this._savePersisted();\n };\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n }\n\n /** Pin one column to an explicit width across BOTH tables (every\n * header row + the body's first row) and record it as a user\n * override so `_syncHeaderWidths` honors it on later renders. The\n * single place that writes a column width during a drag / fill. */\n _pinColumnWidth(i, w) {\n const headerTable = this._headerTableEl;\n const bodyTable = this._tableEl;\n if (!headerTable) return;\n this._colWidths[i] = w;\n headerTable.querySelectorAll('thead > tr').forEach((tr) => {\n if (tr.children[i]) this._setCellWidth(tr.children[i], w);\n });\n // C10: the `<col>` is the track; without one, the first row of data.\n const cols = this._cols();\n if (cols) {\n if (cols[i]) cols[i].style.width = `${w}px`;\n return;\n }\n const bodyRow = bodyTable && this._firstBodyRow();\n if (bodyRow && bodyRow.children[i]) this._setCellWidth(bodyRow.children[i], w);\n }\n\n /** Size both tables so a widened column grows the table (\u2192 horizontal\n * scroll) rather than stealing from its neighbours \u2014 while enforcing\n * the TABLE WIDTH INVARIANT: the table is never narrower than its\n * container. Any width freed by dragging a column in stretches a\n * flexible column (the last one, stepping off the column being\n * dragged) so the table always spans \u2265100% of the wrap.\n *\n * @param {number|null} dragIdx column the user is actively dragging,\n * so the fill lands on a DIFFERENT column and doesn't fight the\n * drag. Null (non-drag callers) lets the last column flex. */\n _applyTableWidth(dragIdx = null) {\n const headerTable = this._headerTableEl;\n const bodyTable = this._tableEl;\n const headRow = headerTable && headerTable.querySelector('thead > tr');\n if (!headRow) return;\n const cells = [...headRow.children];\n const cols = cells.length;\n if (cols === 0) return;\n\n const FLOOR = 40; // matches the drag-resize minimum\n const widthOf = (th) => {\n const px = parseFloat(th.style.width);\n return Number.isFinite(px) ? px : th.getBoundingClientRect().width;\n };\n const cur = cells.map(widthOf);\n\n // Fill invariant: pick a flexible column and stretch it to soak up\n // any freed width so the summed total is never below the container.\n const wrap = this._tableWrapEl;\n const avail = wrap ? wrap.clientWidth : 0;\n let flexIdx = cols - 1;\n if (dragIdx != null && flexIdx === dragIdx) flexIdx -= 1; // step off the dragged col\n if (avail > 1 && flexIdx >= 0 && flexIdx !== dragIdx) {\n let rest = 0;\n for (let i = 0; i < cols; i++) if (i !== flexIdx) rest += cur[i];\n const fill = Math.max(FLOOR, Math.round(avail - rest));\n if (Math.round(fill) !== Math.round(cur[flexIdx])) {\n this._pinColumnWidth(flexIdx, fill);\n cur[flexIdx] = fill;\n }\n }\n\n let total = 0;\n for (const w of cur) total += w;\n total = Math.ceil(total);\n headerTable.style.width = `${total}px`;\n if (bodyTable) bodyTable.style.width = `${total}px`;\n }\n\n /** Add a native `title` tooltip to any body cell whose text is\n * clipped by its column width; remove ours once it fits again.\n * Leaves caller-supplied titles (e.g. from renderCell) untouched. */\n _updateCellTooltips(rows = null) {\n const bodyTable = this._tableEl;\n if (!bodyTable) return;\n // `rows`: only these (C10 \u2014 the rows a window slide just added).\n const cells = rows\n ? rows.flatMap((tr) => [...tr.children])\n : bodyTable.querySelectorAll('tbody td');\n cells.forEach((td) => {\n if (td.parentElement?.classList.contains('twm-dt-spacer')) return;\n // 0.7.0: a row's detail \u2014 and anything drawn inside it \u2014 is not a\n // clipped cell of the table.\n if (td.closest?.('.twm-dt-detail-row')) return;\n const clipped = td.scrollWidth > td.clientWidth + 1;\n if (clipped) {\n if (!td.title) td.title = td.textContent;\n } else if (td.title && td.title === td.textContent) {\n td.removeAttribute('title');\n }\n });\n }\n\n _installInteractions() {\n if (!this._tbodyEl || !this._tableEl) return;\n\n const { selectable, copyable } = this.config;\n // STORY-0010. The consumer's own items install the menu by themselves.\n // STORY-0066: the structural row items make a menu of their own.\n const customMenu = this.config.contextMenuItems != null || !!this._structure()?.hasRowItems();\n const tbody = this._tbodyEl;\n const table = this._tableEl;\n\n // STORY-0003. Cell mode: the cells' own pointer and keys, bound before\n // the activation, detail and copy listeners so a key it takes stops.\n // The row click below is not cell mode's.\n if (this._cellGrid) this._cellGrid.install(tbody, table);\n\n if (selectable && !this._cellGrid) {\n const handleRowClick = (event) => {\n const rowEl = event.target.closest('tr');\n if (!rowEl || rowEl.__rowIndex === undefined) return;\n\n const idx = rowEl.__rowIndex;\n const selected = this._state.selected;\n\n if (selectable === 'single') {\n // 0.5.0. One row, whatever the modifiers say: Ctrl takes\n // the one row back off, nothing extends it.\n const was = selected.has(idx);\n selected.clear();\n if (!(was && (event.metaKey || event.ctrlKey))) selected.add(idx);\n else DESELECTING_CLICKS.add(event); // so it does not ALSO open it\n this._state.anchorIndex = selected.size ? idx : null;\n } else if (this._selecting) {\n // STORY-0016. A plain click ticks one row; Shift adds the\n // range from the last row ticked, as SHOWN.\n if (event.shiftKey && this._state.anchorIndex != null) {\n const order = this._processedIndexMap || this.config.rows.map((_, i) => i);\n const a = order.indexOf(this._state.anchorIndex);\n const b = order.indexOf(idx);\n if (a >= 0 && b >= 0) {\n for (let i = Math.min(a, b); i <= Math.max(a, b); i++) selected.add(order[i]);\n } else selected.add(idx);\n } else if (selected.has(idx)) selected.delete(idx);\n else selected.add(idx);\n this._state.anchorIndex = idx;\n this._navCursor = idx;\n this._markCursor();\n } else if (event.shiftKey && this._state.anchorIndex != null) {\n const start = Math.min(this._state.anchorIndex, idx);\n const end = Math.max(this._state.anchorIndex, idx);\n selected.clear();\n for (let i = start; i <= end; i++) selected.add(i);\n } else if (event.metaKey || event.ctrlKey) {\n if (selected.has(idx)) selected.delete(idx);\n else selected.add(idx);\n this._state.anchorIndex = idx;\n } else {\n selected.clear();\n selected.add(idx);\n this._state.anchorIndex = idx;\n }\n\n this._updateRowSelection();\n this._notifySelectionChange();\n try { table.focus({ preventScroll: true }); } catch (_) {}\n };\n\n tbody.addEventListener('click', handleRowClick);\n this._disposers.push(() => tbody.removeEventListener('click', handleRowClick));\n }\n\n // STORY-0010 `onRowKeyDown`. Bound BEFORE every keydown listener of the\n // table's own (Enter's activation, the detail keys, copy, `keyboardNav`),\n // so a key the consumer takes stops here.\n if (typeof this.config.onRowKeyDown === 'function') {\n const onRowKey = (ev) => {\n if (ev.isComposing || isRowControl(ev.target, table)) return;\n const tr = this._currentRowEl();\n let handled = false;\n try {\n handled = this.config.onRowKeyDown(tr ? tr.__rowIndex : null, tr ? tr.__row : null, ev) === true;\n } catch (err) {\n console.error('[DataTable] onRowKeyDown threw', err);\n }\n if (handled) {\n ev.preventDefault();\n ev.stopImmediatePropagation();\n }\n };\n table.addEventListener('keydown', onRowKey);\n this._disposers.push(() => table.removeEventListener('keydown', onRowKey));\n }\n\n // STORY-0010 `keyboardNav`: the arrows move the selection through the\n // rows of the page, in the order shown.\n if (this.config.keyboardNav && selectable) {\n const NAV_KEYS = ['ArrowDown', 'ArrowUp', 'Home', 'End'];\n const onNavKey = (ev) => {\n if (!NAV_KEYS.includes(ev.key) || ev.ctrlKey || ev.metaKey || ev.altKey) return;\n if (isRowControl(ev.target, table)) return;\n const order = this._pageOrder();\n if (!order.length) return;\n ev.preventDefault();\n const selected = this._state.selected;\n // Where the arrows left off, while that row is still selected;\n // else the anchor (a click since moved it).\n const cur = this._navCursor != null && (this._selecting || selected.has(this._navCursor))\n ? this._navCursor : this._state.anchorIndex;\n let pos = order.indexOf(cur);\n if (ev.key === 'Home') pos = 0;\n else if (ev.key === 'End') pos = order.length - 1;\n else if (pos === -1) pos = ev.key === 'ArrowDown' ? 0 : order.length - 1;\n else pos = Math.max(0, Math.min(order.length - 1, pos + (ev.key === 'ArrowDown' ? 1 : -1)));\n const idx = order[pos];\n this._navCursor = idx;\n const anchorPos = order.indexOf(this._state.anchorIndex);\n if (this._selecting) {\n // STORY-0016. The arrows move the cursor; the ticks stay.\n // Shift ticks the rows passed over.\n if (ev.shiftKey) {\n const from = order.indexOf(cur);\n if (from >= 0) {\n for (let i = Math.min(from, pos); i <= Math.max(from, pos); i++) selected.add(order[i]);\n } else selected.add(idx);\n this._updateRowSelection();\n this._notifySelectionChange();\n }\n this._state.anchorIndex = idx;\n this._markCursor();\n this.scrollToRow(idx);\n return;\n }\n if (ev.shiftKey && selectable !== 'single' && anchorPos !== -1) {\n // Shift: the range between the fixed anchor and the moving\n // row, as Shift-click selects it.\n const [a, b] = anchorPos <= pos ? [anchorPos, pos] : [pos, anchorPos];\n selected.clear();\n for (let i = a; i <= b; i++) selected.add(order[i]);\n } else {\n selected.clear();\n selected.add(idx);\n this._state.anchorIndex = idx;\n }\n this._updateRowSelection();\n this._notifySelectionChange();\n this.scrollToRow(idx);\n };\n table.addEventListener('keydown', onNavKey);\n this._disposers.push(() => table.removeEventListener('keydown', onNavKey));\n }\n\n // STORY-0016. Space ticks the keyboard's row in select mode.\n if (this._gutter) {\n const onSpace = (ev) => {\n if (!this._selecting || ev.key !== ' ' || ev.ctrlKey || ev.metaKey || ev.altKey) return;\n if (isRowControl(ev.target, table)) return;\n const idx = this._navCursor ?? this._state.anchorIndex;\n if (idx == null || !this.config.rows[idx]) return;\n ev.preventDefault();\n const selected = this._state.selected;\n if (selected.has(idx)) selected.delete(idx); else selected.add(idx);\n this._state.anchorIndex = idx;\n this._updateRowSelection();\n this._notifySelectionChange();\n };\n table.addEventListener('keydown', onSpace);\n this._disposers.push(() => table.removeEventListener('keydown', onSpace));\n this._paintSelectHead();\n this._markCursor();\n }\n\n // 0.5.0 `onRowActivate`. Bound AFTER the selection handler on the same\n // element, so a row is selected before it is opened \u2014 the listener\n // order is the guarantee. `onRowClick` stays exactly where it was (on\n // the `<tr>`, before the selection), for whoever already relies on that.\n if (typeof this.config.onRowActivate === 'function') {\n this._installActivation(tbody, table);\n }\n\n // 0.7.0 `rowDetail` from the keyboard: on the focused table (or a row's\n // toggle), ArrowRight opens the current row's detail and ArrowLeft\n // closes it \u2014 the tree-grid keys. The toggle itself is a button, so\n // Enter and Space work on it as on any button.\n if (this._detailOn()) {\n const onDetailKey = (ev) => {\n if (ev.key !== 'ArrowRight' && ev.key !== 'ArrowLeft') return;\n if (ev.ctrlKey || ev.metaKey || ev.altKey || ev.shiftKey) return;\n const toggle = ev.target?.closest?.('.twm-dt-detail-toggle');\n let tr = null;\n if (toggle && table.contains(toggle)) tr = toggle.closest('tr');\n else if (ev.target === table) tr = this._currentRowEl();\n if (!tr || tr.__rowIndex === undefined) return;\n if (this._setRowElExpanded(tr, ev.key === 'ArrowRight', ev)) ev.preventDefault();\n };\n table.addEventListener('keydown', onDetailKey);\n this._disposers.push(() => table.removeEventListener('keydown', onDetailKey));\n }\n\n if (copyable || customMenu) {\n const handleContextMenu = (event) => {\n const rowEl = event.target.closest('tr');\n if (!rowEl) {\n this._hideContextMenu();\n return;\n }\n // 0.7.0: inside a row's detail, the page's own menu (copy the\n // text a person selected there), not the table's.\n if (rowEl.closest('.twm-dt-detail-row')) {\n this._hideContextMenu();\n return;\n }\n\n // STORY-0010. The consumer's items, asked with the selection the\n // right-click is about to make, so `ctx` describes the rows the\n // person will act on. None, and no copy items: the page's menu.\n const idx = rowEl.__rowIndex;\n let custom = null;\n if (customMenu) {\n // STORY-0016. In select mode the menu is about the ticked\n // rows when the row is one of them, else about that row\n // alone \u2014 and the ticks stay as they were.\n const selection = idx !== undefined && !this._state.selected.has(idx)\n ? [idx] : this.getSelection();\n const ctx = this._contextMenuCtxFor(rowEl, event.target, selection);\n custom = { ctx, items: this._customMenuItems(ctx) };\n }\n if (!copyable && !custom.items.length) {\n this._hideContextMenu();\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n if (idx !== undefined && !this._state.selected.has(idx) && !this._selecting) {\n this._state.selected.clear();\n this._state.selected.add(idx);\n this._state.anchorIndex = idx;\n this._updateRowSelection();\n this._notifySelectionChange();\n }\n\n try { table.focus({ preventScroll: true }); } catch (_) {}\n setTimeout(() => this._showContextMenu(event.clientX, event.clientY, custom), 0);\n };\n\n tbody.addEventListener('contextmenu', handleContextMenu);\n this._disposers.push(() => tbody.removeEventListener('contextmenu', handleContextMenu));\n }\n\n if (copyable) {\n\n const handleKeyDown = (event) => {\n const ctrlLike = event.ctrlKey || event.metaKey;\n if (ctrlLike && !event.altKey) {\n const key = String(event.key || '').toLowerCase();\n if (key === 'a' && selectable === 'single') {\n // 0.5.0. Nothing to select all of \u2014 and not the page's\n // text either.\n event.preventDefault();\n } else if (key === 'a' && selectable) {\n event.preventDefault();\n this._selectAllShown();\n } else if (key === 'c' && !(event.shiftKey && this._cellGrid)) {\n // STORY-0085. Cell mode binds Ctrl+C only: it has no\n // CSV copy, so Ctrl+Shift+C is left to the page.\n event.preventDefault();\n this.copyToClipboard(event.shiftKey ? 'csv' : 'tsv');\n }\n } else if (event.key === 'Escape') {\n if (this._state.selected.size) {\n this.clearSelection();\n } else if (this._selecting && this.config.selectToggle) {\n this.setSelectMode(false); // STORY-0016\n }\n this._hideContextMenu();\n }\n };\n\n table.addEventListener('keydown', handleKeyDown);\n this._disposers.push(() => table.removeEventListener('keydown', handleKeyDown));\n }\n }\n\n _updateRowSelection() {\n if (!this._tbodyEl) return;\n this._tbodyEl.querySelectorAll('tr').forEach(tr => {\n const idx = tr.__rowIndex;\n if (idx !== undefined) {\n const on = this._state.selected.has(idx);\n tr.classList.toggle('selected', on && !this._cellGrid);\n // STORY-0016.\n const box = this._gutter ? tr.querySelector(':scope > td.twm-dt-select-cell > input') : null;\n if (box) box.checked = on;\n }\n });\n this._paintSelectHead();\n }\n\n /* \u2500\u2500 STORY-0016: select mode \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n /** Whether the table is in select mode. */\n isSelectMode() {\n return !!this._selecting;\n }\n\n /**\n * Turn select mode on or off. The ticks are kept either way (a selection\n * is a selection); the consumer clears it if leaving means \"never mind\".\n * Does nothing on a table without the select column.\n *\n * @param {boolean} on\n * @returns {boolean} whether the mode changed\n */\n setSelectMode(on) {\n if (!this._gutter || !!on === this._selecting) return false;\n this._selecting = !!on;\n this._navCursor = this._selecting ? this._state.anchorIndex : null;\n if (this._wrapperEl) this.render();\n try { this.config.onSelectModeChange?.(this._selecting); } catch (err) {\n console.error('[DataTable] onSelectModeChange threw', err);\n }\n return true;\n }\n\n /** The rows the filters let through, on every page, by original index. */\n _shownIndices() {\n if (this._isServerSide()) return this.config.rows.map((_, i) => i);\n this._getProcessedRows();\n return this._processedIndexMap ? [...this._processedIndexMap] : this.config.rows.map((_, i) => i);\n }\n\n /** Ctrl+A and the select-all box: every row the filters let through. */\n _selectAllShown() {\n this._state.selected.clear();\n for (const i of this._shownIndices()) this._state.selected.add(i);\n this._state.anchorIndex = this.config.rows.length - 1;\n this._updateRowSelection();\n this._notifySelectionChange();\n }\n\n /** The select column's width: its controls, never a drag. */\n _selectColWidth() {\n return this._selecting ? (this.config.selectToggle ? 56 : 32) : 32;\n }\n\n /** The select column's header: the toggle and, in the mode, select-all. */\n _buildSelectHead() {\n const th = document.createElement('th');\n th.className = 'twm-dt-select-cell twm-dt-select-head';\n if (this._selecting) {\n const all = document.createElement('input');\n all.type = 'checkbox';\n all.className = 'twm-dt-select-all';\n all.setAttribute('aria-label', 'Select all rows');\n all.title = 'Select all rows';\n all.addEventListener('click', (ev) => {\n // Not prevented: the browser would undo the state set here.\n ev.stopPropagation();\n const shown = this._shownIndices();\n const every = shown.length > 0 && shown.every((i) => this._state.selected.has(i));\n if (every) this.clearSelection(); else this._selectAllShown();\n });\n th.appendChild(all);\n }\n if (this.config.selectToggle) {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = 'material-symbols-outlined twm-dt-select-toggle';\n btn.textContent = this._selecting ? 'close' : 'checklist';\n btn.setAttribute('aria-pressed', this._selecting ? 'true' : 'false');\n const label = this._selecting ? 'Stop selecting' : 'Select multiple';\n btn.setAttribute('aria-label', label);\n btn.title = label;\n btn.addEventListener('click', (ev) => {\n ev.stopPropagation();\n this.setSelectMode(!this._selecting);\n });\n th.appendChild(btn);\n }\n th.classList.toggle('twm-dt-select-head--on', this._selecting);\n return th;\n }\n\n /** The select-all box: checked, mixed or clear, as the ticks are. */\n _paintSelectHead() {\n if (!this._gutter || !this._wrapperEl) return;\n const all = this._wrapperEl.querySelector('.twm-dt-select-all');\n if (!all) return;\n const shown = this._shownIndices();\n const n = shown.filter((i) => this._state.selected.has(i)).length;\n all.checked = n > 0 && n === shown.length;\n all.indeterminate = n > 0 && n < shown.length;\n }\n\n /** The keyboard's row in select mode, marked so it can be seen. */\n _markCursor() {\n if (!this._tbodyEl) return;\n for (const tr of this._tbodyEl.children) {\n if (tr.__rowIndex === undefined) continue;\n tr.classList.toggle('twm-dt-row--cursor', this._selecting && tr.__rowIndex === this._navCursor);\n }\n }\n\n _notifySelectionChange() {\n this.config.onSelectionChange?.(this.getSelection());\n }\n\n _ensureContextMenu() {\n if (this._contextMenuEl) return this._contextMenuEl;\n\n const menu = document.createElement('div');\n menu.className = 'twm-context-menu data-context-menu';\n menu.setAttribute('role', 'menu');\n menu.style.display = 'none';\n menu.style.position = 'fixed';\n menu.style.zIndex = '10001';\n menu.innerHTML = copyMenuHtml(!!this._cellGrid);\n document.body.appendChild(menu);\n\n menu.addEventListener('click', (event) => {\n const item = event.target.closest('.twm-context-menu-item');\n if (!item || item.classList.contains('disabled')) return;\n // STORY-0010. One of the consumer's items: dispatched off the item\n // itself, not `data-action`, so an action is free to be called\n // 'copy-tsv'. The menu goes first \u2014 the action may open a dialog.\n if (item.__cmItem) {\n event.stopPropagation();\n event.preventDefault();\n const ctx = this._contextMenuCtx;\n this._hideContextMenu();\n // STORY-0012. The column chooser's own items.\n if (typeof item.__cmItem.onChoose === 'function') { item.__cmItem.onChoose(); return; }\n if (!ctx || typeof this.config.onContextMenuAction !== 'function') return;\n try { this.config.onContextMenuAction(item.__cmItem.action, ctx.rowIdx, ctx.row, ctx); } catch (err) {\n console.error('[DataTable] onContextMenuAction threw', err);\n }\n return;\n }\n const action = item.getAttribute('data-action');\n if (action === 'copy-tsv') this.copyToClipboard('tsv');\n else if (action === 'copy-csv') this.copyToClipboard('csv');\n event.stopPropagation();\n event.preventDefault();\n }, { capture: true });\n\n menu.addEventListener('contextmenu', (e) => {\n e.preventDefault();\n e.stopPropagation();\n });\n\n this._contextMenuEl = menu;\n return menu;\n }\n\n /**\n * The document-level listeners that close the copy menu \u2014 a click\n * elsewhere, a scroll, Escape, a resize \u2014 held ONLY WHILE IT IS OPEN\n * (0.5.0). They were installed the first time the menu was built and kept\n * until `dispose()`, so every table anybody had ever right-clicked kept four\n * listeners on the document for as long as the instance lived, and an\n * instance whose host was thrown away without a `dispose()` kept them for\n * the life of the page. A closed menu has nothing for them to do.\n */\n _armContextMenuGlobals() {\n if (this._contextMenuGlobals.length) return;\n const menu = this._contextMenuEl;\n const hideOnGlobal = (event) => {\n if (event?.target && menu?.contains(event.target)) return;\n this._hideContextMenu();\n };\n // BUG-0040. The keyboard reaches every item: Up/Down/Home/End move\n // focus (and scroll the item into view in a menu taller than the\n // window), Enter and Space choose, Escape closes.\n const onMenuKey = (event) => {\n if (event.key === 'Escape') { this._hideContextMenu(); return; }\n if (!menu || menu.style.display === 'none') return;\n const focused = document.activeElement;\n if ((event.key === 'Enter' || event.key === ' ')\n && focused?.classList?.contains('twm-context-menu-item') && menu.contains(focused)) {\n event.preventDefault();\n focused.click();\n return;\n }\n moveMenuFocus(event, this._contextMenuEnabledItems());\n };\n const hideOnResize = () => this._hideContextMenu();\n\n document.addEventListener('click', hideOnGlobal, true);\n document.addEventListener('scroll', hideOnGlobal, true);\n window.addEventListener('resize', hideOnResize);\n document.addEventListener('keydown', onMenuKey);\n\n this._contextMenuGlobals.push(() => document.removeEventListener('click', hideOnGlobal, true));\n this._contextMenuGlobals.push(() => document.removeEventListener('scroll', hideOnGlobal, true));\n this._contextMenuGlobals.push(() => document.removeEventListener('keydown', onMenuKey));\n this._contextMenuGlobals.push(() => window.removeEventListener('resize', hideOnResize));\n }\n\n _disarmContextMenuGlobals() {\n this._contextMenuGlobals.forEach((off) => {\n try { off?.(); } catch (_) { /* already gone */ }\n });\n this._contextMenuGlobals = [];\n }\n\n _hideContextMenu() {\n const menu = this._contextMenuEl;\n const returnTo = this._contextMenuReturnFocus;\n this._contextMenuReturnFocus = null;\n const held = !!menu && menu.style.display !== 'none' && menu.contains(document.activeElement);\n if (menu) {\n menu.style.display = 'none';\n }\n this._disarmContextMenuGlobals();\n // BUG-0040. Focus goes back where it was, but only if the menu still\n // had it: a click elsewhere has moved it deliberately.\n if (held && returnTo?.isConnected) returnTo.focus?.({ preventScroll: true });\n }\n\n /** BUG-0040. The items the keyboard can land on. */\n _contextMenuEnabledItems() {\n const menu = this._contextMenuEl;\n return menu ? [...menu.querySelectorAll('.twm-context-menu-item:not(.disabled)')] : [];\n }\n\n _showContextMenu(clientX, clientY, custom = null) {\n const menu = this._ensureContextMenu();\n this._drawContextMenuItems(menu, custom);\n this._armContextMenuGlobals();\n const hasSelection = this._state.selected.size > 0;\n\n // The copy items need a selection; a consumer's item says for itself.\n menu.querySelectorAll('.twm-context-menu-item').forEach(item => {\n if (item.__cmItem) return;\n item.classList.toggle('disabled', !hasSelection);\n item.style.pointerEvents = hasSelection ? '' : 'none';\n });\n\n // BUG-0040. Every item is a menu item the keyboard can focus.\n menu.querySelectorAll('.twm-context-menu-item').forEach((item) => {\n item.tabIndex = -1;\n if (!item.hasAttribute('role')) item.setAttribute('role', 'menuitem');\n });\n if (!menu.contains(document.activeElement)) this._contextMenuReturnFocus = document.activeElement;\n\n // BUG-0040. Inside the window, at most its height, scrolling when longer.\n menu.style.display = 'block';\n placeMenuInViewport(menu, clientX, clientY);\n focusMenuItem(this._contextMenuEnabledItems()[0]);\n }\n\n /**\n * STORY-0010. The `ctx` handed to `contextMenuItems` and, later, to\n * `onContextMenuAction`: the right-clicked row and cell, and `selection`\n * (original indices, ascending) with its rows 1:1.\n */\n _contextMenuCtxFor(rowEl, target, selection) {\n const rows = this.config.rows || [];\n const rowIdx = rowEl.__rowIndex === undefined ? null : rowEl.__rowIndex;\n const row = rowIdx === null ? null : (rows[rowIdx] ?? null);\n // The DATA column under the pointer. Only a cell of THIS row counts (a\n // `renderCell` may plant a table of its own), and the row-number gutter\n // is no data column.\n let colIdx = null;\n const cellEl = target?.closest?.('td');\n if (cellEl && cellEl.parentNode === rowEl) {\n const domIdx = Array.prototype.indexOf.call(rowEl.children, cellEl);\n const dataIdx = this._dataIdxOfDom(domIdx);\n if (dataIdx !== null) colIdx = dataIdx;\n }\n const sel = [...selection].sort((a, b) => a - b);\n return {\n rowIdx,\n row,\n colIdx,\n value: colIdx !== null && row ? row[colIdx] : null,\n selection: sel,\n selectedRows: sel.map((i) => rows[i]),\n };\n }\n\n /** STORY-0010. `contextMenuItems` for one right-click: none off a data row\n * (the empty row), and none from a function that threw. */\n _customMenuItems(ctx) {\n if (ctx.rowIdx === null) return [];\n const spec = this.config.contextMenuItems;\n let items = spec;\n if (typeof spec === 'function') {\n try { items = spec(ctx.row, ctx.rowIdx, ctx); } catch (err) {\n console.error('[DataTable] contextMenuItems threw', err);\n items = null;\n }\n }\n const list = Array.isArray(items) ? items.filter(Boolean) : [];\n // STORY-0066. Insert and delete a row, after the consumer's items.\n const structural = this._structure()?.rowItems(ctx.rowIdx) || [];\n if (structural.length && list.length) list.push({ separator: true });\n return list.concat(structural);\n }\n\n /**\n * STORY-0010. Fill the menu for this right-click: the consumer's items,\n * then (with `copyable`) a separator and the copy items. Without custom\n * items the menu is the 0.9.1 copy menu, and is only rebuilt when the last\n * right-click drew custom ones into it. Built with DOM calls, not markup:\n * the labels are the consumer's text.\n */\n _drawContextMenuItems(menu, custom) {\n this._contextMenuCtx = custom ? custom.ctx : null;\n if (!custom) {\n if (this._contextMenuCustom) {\n menu.innerHTML = copyMenuHtml(!!this._cellGrid);\n this._contextMenuCustom = false;\n }\n return;\n }\n this._contextMenuCustom = true;\n menu.textContent = '';\n for (const item of custom.items) {\n if (item.separator) {\n const sep = document.createElement('div');\n sep.className = 'twm-context-menu__separator';\n menu.appendChild(sep);\n continue;\n }\n const el = document.createElement('div');\n el.className = 'twm-context-menu-item';\n if (item.action != null) el.setAttribute('data-action', String(item.action));\n if (item.danger) el.classList.add('twm-delete-node');\n if (item.disabled) {\n el.classList.add('disabled');\n el.style.pointerEvents = 'none';\n el.setAttribute('aria-disabled', 'true');\n }\n if (item.title) el.title = String(item.title);\n // STORY-0012. The column chooser's items say whether they are on.\n if (typeof item.checked === 'boolean') {\n el.setAttribute('role', 'menuitemcheckbox');\n el.setAttribute('aria-checked', String(item.checked));\n }\n const icon = document.createElement('span');\n icon.className = 'material-symbols-outlined';\n icon.textContent = item.icon == null ? '' : String(item.icon);\n const label = document.createElement('span');\n label.className = 'label';\n label.textContent = item.label == null ? '' : String(item.label);\n el.append(icon, label);\n el.__cmItem = item;\n menu.appendChild(el);\n }\n if (this.config.copyable && custom.copy !== false) {\n if (custom.items.length) {\n const sep = document.createElement('div');\n sep.className = 'twm-context-menu__separator';\n menu.appendChild(sep);\n }\n menu.insertAdjacentHTML('beforeend', copyMenuHtml(!!this._cellGrid));\n }\n }\n\n _teardownContextMenu() {\n this._contextMenuGlobals.forEach(dispose => {\n try { dispose?.(); } catch (_) {}\n });\n this._contextMenuGlobals = [];\n if (this._contextMenuEl?.parentNode) {\n this._contextMenuEl.parentNode.removeChild(this._contextMenuEl);\n }\n this._contextMenuEl = null;\n }\n\n _formatValue(value, colIndex) {\n // 0.5.0 `nullDisplay`, then a typed column's own words \u2014 each only when\n // asked for, so a table without them formats exactly as 0.4 did.\n if (value == null && this.config.nullDisplay != null) {\n return String(this.config.nullDisplay);\n }\n const typed = this._formatTyped(value, colIndex);\n if (typed !== undefined) return typed;\n if (this.config.formatValue) {\n return this.config.formatValue(value, colIndex);\n }\n if (value === undefined || value === null) return '-';\n if (typeof value === 'number') {\n if (!Number.isFinite(value)) return '-';\n return Number(value.toFixed(4)).toString();\n }\n return String(value);\n }\n\n _csvEscape(value) {\n if (value == null) return '';\n const str = String(value);\n if (/[\",\\n]/.test(str)) {\n return `\"${str.replace(/\"/g, '\"\"')}\"`;\n }\n return str;\n }\n\n _fallbackCopy(text) {\n try {\n const textarea = document.createElement('textarea');\n textarea.value = text;\n textarea.setAttribute('readonly', '');\n textarea.style.position = 'absolute';\n textarea.style.left = '-9999px';\n document.body.appendChild(textarea);\n textarea.select();\n const ok = document.execCommand('copy');\n document.body.removeChild(textarea);\n return ok;\n } catch (_) {\n return false;\n }\n }\n\n _notify(title, message, type = 'info') {\n this.config.services?.eventBus?.emit?.('toast:show', { title, message, type });\n }\n}\n\nexport default DataTable;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["h", "mi", "date", "pad", "p", "normalise", "key", "ISO_DATE", "isBlank", "t", "key", "key", "text", "key", "result", "key", "i", "key", "ok", "target", "pad"]
|
|
7
|
+
}
|