flexdesk 0.17.18 → 0.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/CHANGELOG.md +91 -0
  2. package/README.md +1 -0
  3. package/css/flexdesk.css +7547 -5891
  4. package/css/reset.css +1 -1
  5. package/css/tokens.css +30 -1
  6. package/dist/charts.js +83 -13
  7. package/dist/charts.js.map +2 -2
  8. package/dist/chunk-3BLIVOFD.js +778 -0
  9. package/dist/chunk-3BLIVOFD.js.map +7 -0
  10. package/dist/{chunk-7OL6F2AM.js → chunk-4X4SY3CP.js} +7 -5
  11. package/dist/chunk-4X4SY3CP.js.map +7 -0
  12. package/dist/chunk-DNJ3N4T4.js +82 -0
  13. package/dist/chunk-DNJ3N4T4.js.map +7 -0
  14. package/dist/{chunk-PGZ4EHSE.js → chunk-HL3IIHU3.js} +501 -359
  15. package/dist/chunk-HL3IIHU3.js.map +7 -0
  16. package/dist/{chunk-REJ5HLIM.js → chunk-HYJYYEPK.js} +2 -2
  17. package/dist/{chunk-7U4IB65H.js → chunk-LLBJ2SJH.js} +5 -3
  18. package/dist/{chunk-7U4IB65H.js.map → chunk-LLBJ2SJH.js.map} +1 -1
  19. package/dist/{chunk-XJNADRGR.js → chunk-NFZJ6P42.js} +188 -96
  20. package/dist/chunk-NFZJ6P42.js.map +7 -0
  21. package/dist/chunk-PAI2ZUWV.js +260 -0
  22. package/dist/chunk-PAI2ZUWV.js.map +7 -0
  23. package/dist/chunk-Q7BALEPX.js +527 -0
  24. package/dist/chunk-Q7BALEPX.js.map +7 -0
  25. package/dist/{chunk-2Z2ENHR3.js → chunk-QRBOIUU3.js} +7 -8
  26. package/dist/chunk-QRBOIUU3.js.map +7 -0
  27. package/dist/chunk-QXAOTGCC.js +40 -0
  28. package/dist/chunk-QXAOTGCC.js.map +7 -0
  29. package/dist/chunk-UKP22RUG.js +219 -0
  30. package/dist/chunk-UKP22RUG.js.map +7 -0
  31. package/dist/chunk-VLOAI3HS.js +43 -0
  32. package/dist/chunk-VLOAI3HS.js.map +7 -0
  33. package/dist/{chunk-WUFLGETN.js → chunk-WVFGV5FT.js} +2 -39
  34. package/dist/{chunk-WUFLGETN.js.map → chunk-WVFGV5FT.js.map} +3 -3
  35. package/dist/editor.js +3 -2
  36. package/dist/editor.js.map +1 -1
  37. package/dist/flexdesk.css +7547 -5891
  38. package/dist/flow.js +29 -97
  39. package/dist/flow.js.map +3 -3
  40. package/dist/git.js +1356 -0
  41. package/dist/git.js.map +7 -0
  42. package/dist/reset.css +1 -1
  43. package/dist/tiles.js +20 -15
  44. package/dist/tiles.js.map +2 -2
  45. package/dist/tokens.css +30 -1
  46. package/dist/widgets.js +4146 -1199
  47. package/dist/widgets.js.map +4 -4
  48. package/dist/wm.js +120 -32
  49. package/dist/wm.js.map +2 -2
  50. package/docs/README.md +9 -4
  51. package/docs/best-practices.md +2 -2
  52. package/docs/components/charts.md +40 -0
  53. package/docs/components/chat-shell.md +204 -0
  54. package/docs/components/conversation.md +10 -0
  55. package/docs/components/filter-builder.md +292 -0
  56. package/docs/components/forms-and-dialogs.md +30 -0
  57. package/docs/components/git.md +355 -0
  58. package/docs/components/input-fields.md +191 -2
  59. package/docs/components/keymap.md +8 -0
  60. package/docs/components/menus.md +86 -2
  61. package/docs/components/panels-and-desktops.md +16 -5
  62. package/docs/components/shell.md +108 -1
  63. package/docs/components/workspace-picker.md +193 -0
  64. package/docs/concepts/building-and-packaging.md +2 -2
  65. package/docs/concepts/packages-and-entry-points.md +14 -13
  66. package/docs/concepts/state-guard.md +3 -3
  67. package/docs/quickstart.md +1 -1
  68. package/git.js +13 -0
  69. package/package.json +6 -1
  70. package/src/charts/plot_config_editor.js +92 -6
  71. package/src/charts/plot_grid.js +6 -1
  72. package/src/flow/kit/dom.js +28 -119
  73. package/src/flow/kit/step_picker.js +1 -1
  74. package/src/flow/kit/value_picker.js +1 -1
  75. package/src/flow/outline/menu.js +1 -1
  76. package/src/git/diff_viewer.js +212 -0
  77. package/src/git/diff_window.js +51 -0
  78. package/src/git/git_graph.js +401 -0
  79. package/src/git/git_ops.js +61 -0
  80. package/src/git/git_panel.js +755 -0
  81. package/src/git/index.js +9 -0
  82. package/src/git/line_diff.js +202 -0
  83. package/src/tiles/tile_base.js +5 -4
  84. package/src/tiling/desktops.js +10 -8
  85. package/src/tiling/keymap.js +6 -5
  86. package/src/tiling/kind_taxonomy.js +15 -2
  87. package/src/tiling/shell.js +124 -17
  88. package/src/tiling/tile_renderer.js +2 -3
  89. package/src/ui/components/action_dropdown.js +4 -78
  90. package/src/ui/components/anchored_layer.js +255 -0
  91. package/src/ui/components/chat_shell.js +926 -0
  92. package/src/ui/components/chat_state_machine.js +223 -0
  93. package/src/ui/components/choice_controls.js +45 -2
  94. package/src/ui/components/color_field.js +3 -2
  95. package/src/ui/components/color_list_field.js +3 -2
  96. package/src/ui/components/combobox.js +422 -0
  97. package/src/ui/components/context_menu.js +8 -2
  98. package/src/ui/components/conversation_view.js +17 -2
  99. package/src/ui/components/data_table.js +2 -2
  100. package/src/ui/components/filter_builder.js +791 -0
  101. package/src/ui/components/filter_model.js +682 -0
  102. package/src/ui/components/inline_renamer.js +10 -5
  103. package/src/ui/components/managed_window.js +24 -47
  104. package/src/ui/components/modal.js +104 -117
  105. package/src/ui/components/option_list.js +160 -0
  106. package/src/ui/components/popover.js +94 -0
  107. package/src/ui/components/recent_items.js +169 -0
  108. package/src/ui/components/select.js +322 -0
  109. package/src/ui/components/tag_input.js +77 -8
  110. package/src/ui/components/workspace_picker.js +1253 -0
  111. package/src/ui/utils/fire_event.js +17 -0
  112. package/src/ui/utils/focusable.js +25 -0
  113. package/src/ui/utils/modal_host.js +27 -0
  114. package/src/ui/utils/tooltip_service.js +81 -14
  115. package/widgets.js +12 -2
  116. package/css/base.css +0 -10547
  117. package/css/overrides.css +0 -2596
  118. package/dist/chunk-2Z2ENHR3.js.map +0 -7
  119. package/dist/chunk-7JI7HHSY.js +0 -107
  120. package/dist/chunk-7JI7HHSY.js.map +0 -7
  121. package/dist/chunk-7OL6F2AM.js.map +0 -7
  122. package/dist/chunk-MIW7D6WC.js +0 -526
  123. package/dist/chunk-MIW7D6WC.js.map +0 -7
  124. package/dist/chunk-PGZ4EHSE.js.map +0 -7
  125. package/dist/chunk-XJNADRGR.js.map +0 -7
  126. /package/dist/{chunk-REJ5HLIM.js.map → chunk-HYJYYEPK.js.map} +0 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/ui/components/managed_window.js", "../src/ui/components/toggle_field.js", "../src/ui/utils/fire_event.js", "../src/ui/components/color_field.js", "../src/ui/components/option_list.js", "../src/ui/components/combobox.js"],
4
+ "sourcesContent": ["/**\n * ManagedWindow - A reusable window component with drag, resize, minimize, and persistence.\n *\n * Usage:\n * const win = new ManagedWindow({\n * id: 'my-window',\n * title: 'My Window',\n * icon: 'folder_open', // Material Symbols icon name (optional)\n * content: myDomElement,\n * minWidth: 400,\n * minHeight: 300,\n * defaultWidth: 600,\n * defaultHeight: 400,\n * canMaximize: true,\n * onClose: () => { ... }\n * });\n * win.show();\n */\n\nimport { getSetting } from '../../core/settings.js';\nimport { isInAnchoredLayer } from './anchored_layer.js';\nimport { collectFocusable } from '../utils/focusable.js';\n\n/** Where window geometry lives when the embedder names no key. An embedder\n * that saved geometry under another key keeps it by passing that key to\n * `ManagedWindow.configure({ storageKey })` before the first window opens. */\nexport const DEFAULT_WINDOW_STORAGE_KEY = 'flexdesk.managedWindows.v1';\nlet _storageKey = DEFAULT_WINDOW_STORAGE_KEY;\n/** BUG-0053. How many window ids keep saved geometry. Every save stamps its\n * entry with a use counter; past the cap the least recently saved ids are\n * dropped, so ids minted per window (the window manager's `twm-mw-<time>-\u2026`)\n * no longer grow the entry for ever. */\nexport const DEFAULT_MAX_SAVED_WINDOWS = 50;\n/** The prefix of the ids the window manager mints per window\n * (`twm-mw-<time>-<rand>`). Such an id never opens again, so geometry saved\n * under it can never be restored: entries under it are purged on load. */\nconst MINTED_ID_PREFIX = 'twm-mw-';\nlet _maxSavedWindows = DEFAULT_MAX_SAVED_WINDOWS;\nconst BASE_Z_INDEX = 6000;\nconst MAX_Z_INDEX = 6999;\n\n// Bar heights for maximize bounds. Must match the tiling shell's\n// own constants (host.css locks `.global-bottom-bar` to 22 px) so a\n// maximized window stops above the bottom bar instead of slipping\n// under it.\nconst TOP_BAR_HEIGHT = 35;\nconst BOTTOM_BAR_HEIGHT = 22;\n\n/** STORY-0119. The space above a window on `document.body`: the top bar, and\n * under it a shell's menu row (`.twm-global-menu-bar`, a sibling of the top\n * bar in body.twm-body's column) when the page has one. The row is measured,\n * not assumed, because its height is its content's. Without a row this is\n * TOP_BAR_HEIGHT, exactly as before. */\nfunction _topInset() {\n const row = typeof document !== 'undefined'\n ? document.querySelector('body > .twm-global-menu-bar') : null;\n return TOP_BAR_HEIGHT + (row ? row.getBoundingClientRect().height : 0);\n}\n\n/** C11. How close to an edge the POINTER must come for a snap zone to arm.\n * Small enough that it takes intent, large enough to hit without aiming. */\nconst SNAP_EDGE = 12;\n\n// Default icon for windows\nconst DEFAULT_ICON = 'web_asset';\n\n// Global state for z-order management\nlet _zIndexCounter = 0;\nlet _activeWindows = new Map(); // id -> ManagedWindow instance\n/** BUG-0053. Esc events a window has already answered. Every visible window\n * listens on the document, and closing one can hand focus to another before\n * the same event reaches it \u2014 one Esc must close one window. */\nconst _escAnswered = new WeakSet();\n\n// Global state cache\nlet _stateCache = null;\n\nfunction _loadState() {\n if (_stateCache) return _stateCache;\n try {\n const raw = localStorage.getItem(_storageKey);\n const parsed = raw ? JSON.parse(raw) : {};\n _stateCache = parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : {};\n // BUG-0053. Before 0.17.16 every window-manager window saved an entry\n // under its minted id; they are junk, and leaving them in would let\n // them crowd stable ids out of the cap.\n for (const k of Object.keys(_stateCache)) {\n if (k.startsWith(MINTED_ID_PREFIX)) delete _stateCache[k];\n }\n } catch {\n _stateCache = {};\n }\n return _stateCache;\n}\n\nfunction _saveState(state) {\n _stateCache = state;\n try {\n localStorage.setItem(_storageKey, JSON.stringify(state));\n } catch (err) {\n console.warn('[ManagedWindow] Failed to save state:', err);\n }\n}\n\nfunction _getWindowState(id) {\n const state = _loadState();\n return state[id] || null;\n}\n\nfunction _setWindowState(id, windowState) {\n const state = _loadState();\n // `u` orders the entries by last save. A plain object's key order cannot\n // carry that (integer-like ids sort first). An entry written before the\n // stamp existed is a stable id the user has used (minted ids are purged\n // on load), so it is stamped here, in the order it was stored, AHEAD of\n // nothing newer: it ranks as older than any entry saved since, and the\n // cap reaches it only after the minted junk is gone and real ids crowd it.\n let latest = 0;\n for (const k of Object.keys(state)) latest = Math.max(latest, Number(state[k]?.u) || 0);\n for (const k of Object.keys(state)) {\n if (!(Number(state[k]?.u) > 0) && state[k] && typeof state[k] === 'object') {\n state[k] = { ...state[k], u: ++latest };\n }\n }\n state[id] = { ...windowState, u: latest + 1 };\n const ids = Object.keys(state);\n if (ids.length > _maxSavedWindows) {\n ids.sort((a, b) => (Number(state[a]?.u) || 0) - (Number(state[b]?.u) || 0));\n for (const k of ids.slice(0, ids.length - _maxSavedWindows)) delete state[k];\n }\n _saveState(state);\n}\n\n/** BUG-0053. The first element of `root` that actually takes focus. Tried in\n * DOM order rather than filtered by layout, because an element that is\n * `display: none` or `visibility: hidden` refuses `focus()` in a browser \u2014\n * so asking the element is exact where measuring it would guess. */\nfunction _focusFirstIn(root) {\n if (!root) return false;\n const sel = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled]):not([type=\"hidden\"])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[contenteditable=\"true\"]',\n '[tabindex]:not([tabindex=\"-1\"])',\n ].join(',');\n for (const el of root.querySelectorAll(sel)) {\n if (el.hidden || el.closest('[hidden]')) continue;\n try { el.focus({ preventScroll: true }); } catch { continue; }\n if (el.ownerDocument.activeElement === el) return true;\n }\n return false;\n}\n\n/** BUG-0053. Which window an Esc closes, or null.\n *\n * - A modal on top answers wherever focus is, as it always has.\n * - Otherwise the window holding focus answers, modal or not.\n * - Otherwise (focus in no window) the topmost modal answers.\n * A non-modal window that does not hold focus never answers: an Esc meant\n * for an editor beside it is not its. */\nfunction _escAnswerer() {\n const visible = Array.from(_activeWindows.values())\n .filter((w) => w.isVisible && !w.isMinimized && w.element)\n .sort((a, b) => b.zIndex - a.zIndex);\n if (visible[0]?.modal) return visible[0];\n const active = document.activeElement;\n const holder = active ? visible.find((w) => w.element.contains(active)) : null;\n return holder || visible.find((w) => w.modal) || null;\n}\n\nexport class ManagedWindow {\n /**\n * @param {Object} options\n * @param {string} options.id - Unique window ID for persistence\n * @param {string} options.title - Window title\n * @param {string} [options.icon] - Material Symbols icon name (default: 'web_asset')\n * @param {HTMLElement|Function} options.content - Content element or render function\n * @param {number} [options.minWidth=400] - Minimum width\n * @param {number} [options.minHeight=300] - Minimum height\n * @param {number} [options.defaultWidth=600] - Default width\n * @param {number} [options.defaultHeight=400] - Default height\n * @param {boolean} [options.canMinimize=true] - Whether minimize button is shown\n * @param {boolean} [options.canMaximize=true] - Whether maximize button is shown\n * @param {boolean} [options.canResize=true] - Whether window can be resized\n * @param {boolean} [options.canDrag=true] - Whether window can be dragged\n * @param {boolean} [options.modal=false] - Whether to show backdrop\n * @param {Function} [options.onClose] - Callback when window is closed\n * @param {Function} [options.beforeClose] - Guard called before close. Return false (or a Promise resolving to false) to prevent closing.\n * @param {Function} [options.onMinimize] - Callback when window is minimized\n * @param {HTMLElement} [options.container] - Mount point. Defaults to\n * `document.body` (every call site that exists today). When given, the\n * window is positioned and CLAMPED inside that element instead of the\n * viewport, and its taskbar events carry the container so a per-panel\n * taskbar can filter on them.\n *\n * The container MUST establish a containing block with\n * `position: relative` or `position: absolute` \u2014 and with NOTHING else.\n * `transform`, `filter`, `contain` and `will-change` also create a\n * containing block, and they additionally trap `position: fixed`\n * descendants. DataTable's filter dropdown (`position: fixed;\n * z-index: 10001`) and the autocomplete dropdown deliberately ESCAPE\n * their tile to the viewport; under a transformed ancestor they become\n * container-relative and get clipped by `overflow: hidden`. The symptom\n * is \"the filter dropdown is cut in half\" and the cause is three files\n * away.\n * @param {Array} [options.titlebarButtons] - Extra buttons left of\n * minimize: `{icon, title, onClick}`.\n * @param {boolean} [options.persistGeometry=true] - Save and restore this\n * window's position and size under its id. Pass false for a window whose\n * id is minted per opening, so it never writes an entry.\n * @param {boolean|'window'} [options.focusOnOpen=true] - When the window\n * opens, move focus to the first focusable element of its content (the\n * window itself when it has none; always the window itself with\n * `'window'`), and on close give focus back to the element that had it\n * before, if that element is still in the document and focus is still in\n * this window or nowhere.\n */\n constructor(options) {\n this.id = options.id;\n this.title = options.title || 'Window';\n this.icon = options.icon || DEFAULT_ICON;\n this.content = options.content;\n this.minWidth = options.minWidth || 400;\n this.minHeight = options.minHeight || 300;\n this.defaultWidth = options.defaultWidth || 600;\n this.defaultHeight = options.defaultHeight || 400;\n this.canMinimize = options.canMinimize ?? true;\n this.canMaximize = options.canMaximize ?? true;\n this.canResize = options.canResize ?? true;\n this.modal = options.modal ?? false;\n // Backdrop appearance (modal only). `undefined` \u2192 inherit the CSS\n // default (blur 2px over a 50% dim). Override per-modal when the\n // background should stay legible \u2014 e.g. a live-applied editor where\n // you want to watch the content behind update.\n // backdropBlur: blur radius in px; 0 disables the blur.\n // backdropOpacity: dim darkness, 0 (clear) \u2026 1 (opaque black).\n this.backdropBlur = options.backdropBlur;\n this.backdropOpacity = options.backdropOpacity;\n // Modals are non-draggable by default\n this.canDrag = options.canDrag ?? !this.modal;\n this.onClose = options.onClose;\n this.beforeClose = options.beforeClose || null;\n this.onMinimize = options.onMinimize;\n // C1. `document.body` is the default and the legacy path; every bounds\n // computation below reduces to today's expression by substitution when\n // it is in force. See `_bounds`.\n this.container = options.container || null;\n /** C11. AERO SNAP \u2014 drag to an edge, release, the window takes that\n * region. Opt-in and default OFF, so no existing consumer changes\n * behaviour by upgrading. Meaningful only for a draggable window that\n * is allowed to change size. */\n this.snap = (options.snap ?? false) && this.canDrag && this.canResize;\n /** C15. SNAP AS A DELEGATED DECISION.\n *\n * C11's snap answers \"which rectangle\" out of three it computes itself\n * from `_bounds()`. That is the whole and correct answer for a window\n * floating over a region nothing else owns, and only half of it under a\n * TILING window manager: there, dropping on an edge does not move a\n * window, it PROMOTES one \u2014 the window stops being a ManagedWindow and\n * becomes a leaf in a tree this component knows nothing about.\n *\n * So the decision is delegated. A `snapController` is:\n *\n * probe(pointerEvent, win) -> { key, rect } | null\n * `rect` is {left, top, width, height} in VIEWPORT pixels \u2014\n * the space a hit-test against other people's DOM naturally\n * produces. `key` is an opaque identity for the zone; the\n * preview only re-renders when it changes.\n * commit(probe, win) -> falsy | true | Promise\n * Called once on release. Falsy means \"not mine\" and the\n * window keeps the position the drag left it in. Anything\n * truthy means the controller took the window AND the preview:\n * a controller that opens a menu needs the preview to outlive\n * the pointer-up, so it clears it through `clearSnapPreview()`.\n *\n * Absent, every line below reduces to C11 exactly. */\n this.snapController = options.snapController || null;\n /** R1. DRAG ACROSS THE CONTAINER BOUNDARY.\n *\n * A contained window lives inside a box with `overflow: hidden` \u2014 for\n * the WM that box is a tile's leaf wrap \u2014 so at rest it cannot show a\n * single pixel outside it, and a drag that leaves it is a drag that\n * disappears. `dragHost` names the WIDER box the window is re-parented\n * into for the duration of a drag: an element or a `(win) => element`\n * callback, resolved on every pointer-down because the WM's root\n * outlives any particular tile and a captured tile does not.\n *\n * Absent \u2014 every consumer today \u2014 nothing re-parents and the drag is\n * clamped to the container exactly as before. The host must CONTAIN\n * the current container: escaping is meant to widen the box the window\n * may cross, not to move it somewhere it has no business being. */\n this.dragHost = options.dragHost || null;\n /** R12. THE BOX AN ESCAPED WINDOW MAY OCCUPY, in the drag host's own\n * coordinates: `() => {minX, minY, width, height}`.\n *\n * R1 widened the drag from one pane to the whole root, and the root is\n * not all tiles \u2014 the docked panels are inside it too. Without this a\n * window can be dragged down over the bottom panel and left there,\n * which is the one edge of the four that stopped feeling like an edge.\n * The host knows which of its children are panels and this component\n * never will, so it answers rather than guesses.\n *\n * Consulted only while a drag has escaped: at rest the container is\n * the box, exactly as before, and a window that never escapes never\n * reads this. */\n this.dragBounds = options.dragBounds || null;\n /** R7. MAXIMISE IS A GESTURE, NOT NECESSARILY A RECTANGLE.\n *\n * `(win) => truthy` claims the maximise gesture: `toggleMaximize`\n * returns without touching the geometry, and the consumer does\n * whatever it decided maximise means. The WM decides it means \"back\n * into the tree\", which is why the separate demote button it used to\n * inject into this chrome is gone. Falsy \u2014 and absent \u2014 leaves the\n * ordinary maximise, so no existing window changes behaviour. */\n this.onMaximize = options.onMaximize || null;\n /** A Material Symbol name replacing the maximize button's square, and\n * its tooltip. They exist because `onMaximize` can change what the\n * button DOES, and a button that does something else while drawing a\n * square is a lie the user only discovers by pressing it. */\n this.maximizeIcon = options.maximizeIcon || null;\n this.maximizeTitle = options.maximizeTitle || 'Maximize';\n this._snapZone = null;\n this._snapProbe = null;\n /** The container a drag escaped FROM, for as long as that drag lasts.\n * Null at every other moment, including for a window that never\n * escapes. Read by the consumer's snap controller (`dragOrigin`), which\n * needs to know which pane is \"home\" to stay silent inside it. */\n this._escapeOrigin = null;\n this._preSnapState = null;\n this._snapPreviewEl = null;\n // C27. THE TWO ANIMATION TIMERS, HELD SO THEY CAN BE CANCELLED.\n // Each of `minimize`/`_restore` ends in a `setTimeout` that finishes\n // its animation, and each finishes it by writing state the OTHER one\n // owns \u2014 `display`, and the three `--mw-target-*` properties. Fired\n // after the opposite gesture has already run, that write is not a late\n // tidy-up, it is a corruption. See `_restore` for the report.\n this._minimizeTimer = null;\n this._restoreTimer = null;\n this.titlebarButtons = Array.isArray(options.titlebarButtons)\n ? options.titlebarButtons : [];\n /** BUG-0053. See the constructor docs. */\n this.persistGeometry = options.persistGeometry ?? true;\n this.focusOnOpen = options.focusOnOpen ?? true;\n /** The element that had focus when the window opened. */\n this._returnFocusTo = null;\n /** True once the window has closed: a closed window is spent. */\n this._closed = false;\n\n this.element = null;\n this.backdropElement = null;\n this.contentContainer = null;\n this.isVisible = false;\n this.isMinimized = false;\n this.isMaximized = false;\n this.zIndex = BASE_Z_INDEX;\n\n // Position/size state - clamp to the bounds rectangle\n this.x = 0;\n this.y = 0;\n const initial = this._bounds();\n this.width = Math.min(this.defaultWidth, initial.width);\n this.height = Math.min(this.defaultHeight, initial.height);\n\n // State before maximize (for restore)\n this._preMaximizeState = null;\n\n // Drag state\n this._dragState = null;\n this._resizeState = null;\n\n // Bound handlers for cleanup\n this._boundOnPointerMove = this._onPointerMove.bind(this);\n this._boundOnPointerUp = this._onPointerUp.bind(this);\n this._boundOnKeyDown = this._onKeyDown.bind(this);\n\n // Register globally\n _activeWindows.set(this.id, this);\n }\n\n /**\n * Show the window.\n */\n show() {\n if (this._closed) {\n // BUG-0053. Close releases the content and every callback, so\n // there is nothing left to show. Build a new window for the id.\n console.warn(`[ManagedWindow] show() on closed window \"${this.id}\"; build a new ManagedWindow to reopen it`);\n return;\n }\n if (this.isVisible && !this.isMinimized) {\n // C27. `show()` IS THE REPAIR PATH, so it repairs. A window that is\n // visible by its own flags and hidden by an inline `display: none`\n // is the state the minimise/restore race used to leave behind, and\n // a consumer holding such a window had nothing to call: this branch\n // raised a window nobody could see. Clearing the property is a\n // no-op for every window that was not in that state \u2014 a shown\n // window's `display` is already `''`.\n if (this.element && this.element.style.display === 'none') {\n this.element.style.display = '';\n }\n this.bringToFront();\n return;\n }\n\n let opened = false;\n if (!this.element) {\n this._build();\n this._restoreState();\n }\n\n if (this.isMinimized) {\n this._restore();\n } else {\n // A window whose PERSISTED state was maximised is maximised before\n // anyone touches the button, so the modifier has to be written here\n // too and not only in `toggleMaximize`.\n this.element?.classList.toggle(\n 'twm-managed-window--maximized', this.isMaximized);\n this._applyPosition();\n const mount = this.container || document.body;\n // C3. `--contained` switches `position: fixed` to `absolute`; the\n // backdrop follows the same rule so a modal inside a panel dims the\n // panel rather than the page.\n this.element.classList.toggle('twm-managed-window--contained', !!this.container);\n mount.appendChild(this.element);\n if (this.modal && this.backdropElement) {\n this.backdropElement.classList.toggle(\n 'twm-managed-window__backdrop--contained', !!this.container);\n mount.appendChild(this.backdropElement);\n }\n this._installContainerResizeObserver();\n this.isVisible = true;\n opened = true;\n }\n\n this.bringToFront();\n document.addEventListener('keydown', this._boundOnKeyDown);\n if (opened && this.focusOnOpen) this._moveFocusIn();\n }\n\n /** BUG-0053. Focus into the content on open, remembering where it was. */\n _moveFocusIn() {\n const active = document.activeElement;\n this._returnFocusTo = active && active !== document.body\n && !this.element.contains(active) ? active : null;\n if (this.focusOnOpen !== 'window' && _focusFirstIn(this.contentContainer)) return;\n // Nothing focusable in the content (or the caller asked for the\n // window): the window takes focus itself, so Esc (which a non-modal\n // window answers only with focus inside) and Tab both start from here.\n try { this.element.focus({ preventScroll: true }); } catch { /* detached */ }\n }\n\n /** BUG-0053. Give focus back on close \u2014 only when it is still in this\n * window (or nowhere): a window closed while the user works elsewhere\n * must not pull focus away from where they are. */\n _returnFocus() {\n const back = this._returnFocusTo;\n this._returnFocusTo = null;\n if (!back || !back.isConnected) return;\n const active = document.activeElement;\n const held = !active || active === document.body\n || (this.element && this.element.contains(active));\n if (!held) return;\n try { back.focus({ preventScroll: true }); } catch { /* gone */ }\n }\n\n /**\n * Hide/close the window.\n * @param {{ force?: boolean }} [options] - Pass force:true to bypass the beforeClose guard.\n */\n close({ force = false } = {}) {\n if (!this.isVisible) return;\n\n if (!force && this.beforeClose) {\n const result = this.beforeClose();\n if (result && typeof result.then === 'function') {\n result.then(allowed => { if (allowed !== false) this._doClose(); });\n return;\n }\n if (result === false) return;\n }\n\n this._doClose();\n }\n\n /** Internal close \u2014 always executes, no guard. */\n _doClose() {\n if (!this.isVisible) return;\n\n this._saveCurrentState();\n\n // Call onClose BEFORE removing elements so content can still read its state\n // (e.g., expression modal needs to read the editor value before DOM is detached)\n if (this.onClose) {\n this.onClose();\n }\n\n // BUG-0053. Before the element leaves the document, while focus can\n // still be seen to be inside it.\n if (this.focusOnOpen) this._returnFocus();\n\n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n if (this.backdropElement && this.backdropElement.parentNode) {\n this.backdropElement.parentNode.removeChild(this.backdropElement);\n }\n\n this.isVisible = false;\n this.isMinimized = false;\n // C27. A window can be closed mid-animation \u2014 \"back to tile\" from the\n // taskbar's menu is exactly that, and it closes a MINIMISED window. The\n // pending timer would then write `display: none` and strip the target\n // properties from an element that has been detached, or, for a window\n // `show()` puts back inside the same 200ms, from a live one.\n this._cancelMinimizeAnimation();\n this._cancelRestoreAnimation();\n this._clearTargetProperties();\n document.removeEventListener('keydown', this._boundOnKeyDown);\n\n // Notify taskbar\n this._teardownContainerResizeObserver();\n // C5. `container` rides on all three window events so a NON-SINGLETON\n // taskbar can filter on receipt: an in-panel taskbar shows only the\n // windows mounted in its own panel, and the viewport taskbar shows only\n // the ones with no container.\n this._announce('managed-window-closed', { id: this.id, container: this.container });\n this._release();\n }\n\n /** Every window event goes out on the page's window, and a window takes only\n * an event built by its own `CustomEvent`: Node's global one is refused\n * under jsdom, in the middle of the close that fired it. */\n _announce(name, detail) {\n window.dispatchEvent(new window.CustomEvent(name, { detail }));\n }\n\n /** BUG-0053. A closed window leaves the registry and lets go of what it\n * held: its content, its DOM and every consumer callback (an `onClose`\n * typically captures its owner). Until now the registry kept all of it\n * alive until the same id opened again, and `get(id)` answered with the\n * dead window. */\n _release() {\n if (_activeWindows.get(this.id) === this) _activeWindows.delete(this.id);\n this._closed = true;\n // A close in the middle of a drag (a snap controller docking the\n // window from its own `commit`) still finishes in `_onPointerUp`,\n // which removes these; a programmatic close mid-drag has no pointer-up\n // coming that is its business.\n if (!this._dragState && !this._resizeState) {\n document.removeEventListener('pointermove', this._boundOnPointerMove);\n document.removeEventListener('pointerup', this._boundOnPointerUp);\n document.removeEventListener('pointercancel', this._boundOnPointerUp);\n }\n this.content = null;\n this.element = null;\n this.contentContainer = null;\n this.backdropElement = null;\n this.onClose = null;\n this.beforeClose = null;\n this.onMinimize = null;\n this.onMaximize = null;\n this.snapController = null;\n this.dragHost = null;\n this.dragBounds = null;\n this.titlebarButtons = [];\n }\n\n /** True once the window has closed. A closed window cannot be shown\n * again; `ManagedWindow.get(id)` no longer returns it. */\n get isClosed() { return this._closed; }\n\n /**\n * Minimize to taskbar with animation.\n */\n minimize() {\n if (!this.isVisible || this.isMinimized) return;\n\n this._saveCurrentState();\n this.isMinimized = true;\n\n if (this.onMinimize) {\n this.onMinimize();\n }\n\n if (this.backdropElement) {\n this.backdropElement.style.display = 'none';\n }\n\n // Dispatch event first so the taskbar button is created synchronously\n this._announce('managed-window-minimized', {\n id: this.id, title: this.title, icon: this.icon,\n container: this.container,\n });\n\n if (!this.element) return;\n\n // C27. The mirror of the cancellation in `_restore`. A restore in\n // flight owns `--restoring` and the target properties, and its timer\n // would strip both out from under the minimise that replaced it \u2014\n // leaving a window that shrinks toward the taskbar and then snaps back\n // to full size for the rest of the 200ms.\n this._cancelRestoreAnimation();\n\n if (!getSetting('window.animateMinimize', true)) {\n this.element.style.display = 'none';\n return;\n }\n\n // Calculate animation target toward the taskbar button\n this._setMinimizeTargetProperties();\n this.element.classList.add('twm-managed-window--minimizing');\n\n this._minimizeTimer = setTimeout(() => {\n this._minimizeTimer = null;\n if (this.element) {\n this.element.style.display = 'none';\n this.element.classList.remove('twm-managed-window--minimizing');\n this._clearTargetProperties();\n }\n }, 200);\n }\n\n /** C27. Abandon a minimise animation that has not landed yet.\n *\n * The timer is dropped AND the class is removed, because the class is half\n * the damage: `--minimizing` is `opacity: 0` plus a transform that parks\n * the window over the taskbar plus `pointer-events: none`, so a window\n * that keeps it is invisible and unclickable for the rest of the 200ms\n * even before the timer hides it outright. */\n _cancelMinimizeAnimation() {\n if (this._minimizeTimer !== null) {\n clearTimeout(this._minimizeTimer);\n this._minimizeTimer = null;\n }\n this.element?.classList.remove('twm-managed-window--minimizing');\n }\n\n /** C27. Abandon a restore animation that has not landed yet. */\n _cancelRestoreAnimation() {\n if (this._restoreTimer !== null) {\n clearTimeout(this._restoreTimer);\n this._restoreTimer = null;\n }\n this.element?.classList.remove('twm-managed-window--restoring');\n }\n\n /**\n * Restore from minimized state with animation.\n *\n * \u2550\u2550 C27. THE WINDOW THAT COULD NOT BE BROUGHT BACK \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n *\n * `minimize` hides the element inside a `setTimeout(..., 200)` so the\n * shrink-toward-the-taskbar animation has time to play, and this method\n * cleared the `display` IMMEDIATELY. Minimise a window and restore it from\n * the taskbar inside those 200ms \u2014 which is not a stress test, it is what\n * \"I clicked the wrong button\" looks like \u2014 and the sequence ran:\n *\n * minimize() isMinimized = true, timer armed for +200ms\n * _restore() display = '', isMinimized = FALSE, taskbar button gone\n * +200ms the timer fires and writes `display: none`\n *\n * leaving a window that is off screen with `isMinimized === false`. Every\n * route back is closed at once: `static restore` and `show` both funnel\n * through the `isMinimized` guard above and return without doing anything,\n * and a taskbar built from `ManagedWindow.all().filter(isMinimized)` \u2014\n * which is how `syncTaskbars` builds it \u2014 has no button for it either. The\n * window is live, holding its content and its staged edits, and there is no\n * gesture in the product that can reach it. Reported twice.\n *\n * The `--minimizing` CLASS is the same defect one layer up and it bites\n * even before the timer does: it is `opacity: 0` with a transform parking\n * the window over the taskbar and `pointer-events: none`, and it was left\n * on for the remainder of the animation, so the restored window was\n * invisible and unclickable for up to 200ms before disappearing outright.\n *\n * Both are cancelled here rather than worked around in a consumer. A\n * consumer cannot see either one: nothing throws, no state is inconsistent\n * at any moment a caller can observe, and the corruption is written by a\n * timer with no name.\n */\n _restore() {\n if (!this.isMinimized) return;\n\n // Capture taskbar item rect BEFORE dispatching the event (which removes it)\n const taskbarRect = this._getTaskbarItemRect();\n\n // C27. FIRST, before `display` is cleared: the pending timer would\n // otherwise undo this whole method 200ms from now.\n this._cancelMinimizeAnimation();\n\n if (this.element) {\n this.element.style.display = '';\n\n const animate = getSetting('window.animateMinimize', true);\n if (animate) {\n // A restore that interrupts a restore \u2014 two clicks on one\n // taskbar button \u2014 would otherwise have the first timer strip\n // the second one's class and properties at ITS deadline.\n this._cancelRestoreAnimation();\n this._setRestoreTargetProperties(taskbarRect);\n this.element.classList.add('twm-managed-window--restoring');\n this._restoreTimer = setTimeout(() => {\n this._restoreTimer = null;\n if (this.element) {\n this.element.classList.remove('twm-managed-window--restoring');\n this._clearTargetProperties();\n }\n }, 250);\n } else {\n // No animation means no timer to clear the properties, and a\n // minimise that was cancelled mid-flight left three of them\n // set. Harmless while no class reads them and wrong the moment\n // one does.\n this._clearTargetProperties();\n }\n }\n if (this.modal && this.backdropElement) {\n this.backdropElement.style.display = '';\n }\n\n this.isMinimized = false;\n this.bringToFront();\n\n // Notify taskbar (removes the taskbar button)\n this._announce('managed-window-restored', { id: this.id, container: this.container });\n }\n\n /**\n * Toggle maximize state.\n */\n /**\n * @param {{claimable?: boolean}} [opts] `claimable: false` performs the\n * GEOMETRIC maximise even when a consumer has claimed the gesture. NOTHING\n * INSIDE THE LIBRARY PASSES IT \u2014 this docstring used to say the topbar's\n * double-click did, and the binding at `:890` has never passed anything\n * (C26 settled the other way; see the note there). It has had two callers\n * outside it and it now has none: the window manager's aero-snap top edge\n * used it for R13's maximise-onto-the-layer, and Tables' window menu drew\n * a \"Maximize\" beside \"Back to tile\" and got its rectangle from here. R14\n * collapsed both into the dock \u2014 maximise means back to tile, everywhere\n * \u2014 so the escape hatch is now a LIBRARY API with no caller in this repo\n * rather than a shared secret between two.\n *\n * IT IS KEPT, and deliberately. A window that came out of a tile has a\n * tile to go back to; a window that never did has only the rectangle, and\n * `openModal`'s dialogs are exactly that case (`modal.js`, `maximizable`)\n * \u2014 they reach the same rectangle through the ordinary claimless path\n * because they set no `onMaximize` at all. Removing this would leave a\n * consumer that HAS claimed the gesture with no way to ask for the other\n * verb, which is the situation the flag was added to fix.\n *\n * A doc that names a caller that does not exist is worse than no doc \u2014 it\n * is the reason a reader concludes the double-click is already handled.\n */\n toggleMaximize({ claimable = true } = {}) {\n if (!this.canMaximize) return;\n\n // R7. THE CONSUMER MAY OWN THIS GESTURE, and under the window manager\n // it does: `adoptWindow` rewrites `onMaximize` to `bringBackWindow`, so\n // both doors \u2014 the button and the topbar's double-click \u2014 DOCK.\n //\n // C28. A CLAIM THAT DECLINES MUST FALL THROUGH, which is what makes\n // \"expand this window into a tile\" a gesture rather than a dead zone.\n // `bringBackWindow` returns false for a window the WM never adopted, so\n // this runs the geometric maximise for it \u2014 the answer every other\n // window manager gives a window with nowhere to go back to. When the\n // wrappers returned `true` regardless, the gesture was claimed, nothing\n // docked and nothing maximised: reported twice, as a title bar whose\n // double-click did nothing at all.\n //\n // Guarded like every other consumer callback here: an exception must not\n // leave the window in a half-maximised state \u2014 and a `throw` is a\n // DECLINE, not a claim, so it falls through to the rectangle too.\n if (claimable && this.onMaximize) {\n let handled = false;\n try { handled = this.onMaximize(this) ?? false; }\n catch (err) { console.error('[managed-window] onMaximize threw', err); }\n if (handled) return;\n }\n\n if (this.isMaximized) {\n // Restore\n if (this._preMaximizeState) {\n this.x = this._preMaximizeState.x;\n this.y = this._preMaximizeState.y;\n this.width = this._preMaximizeState.width;\n this.height = this._preMaximizeState.height;\n this._preMaximizeState = null;\n }\n this.isMaximized = false;\n } else {\n // Maximize - respect top and bottom bars\n this._preMaximizeState = { x: this.x, y: this.y, width: this.width, height: this.height };\n const bounds = this._bounds();\n this.x = bounds.minX;\n this.y = bounds.minY;\n this.width = bounds.width;\n this.height = bounds.height;\n this.isMaximized = true;\n }\n\n // A CLASS THE STYLESHEET HAS ALWAYS KNOWN AND NOTHING EVER SET.\n // `.twm-managed-window--maximized .twm-managed-window__resize\n // { display: none }` is in `css/flexdesk.css` \u2014 \"a maximised window is not\n // resized by dragging its edges\" \u2014 and it has never matched anything,\n // because no code path adds the modifier. So a maximised window keeps\n // eight live resize handles hanging 3px outside its edges. Exactly the\n // shape of the `.twm-collapsible-content.visible` and\n // `managed-window__resize--${dir}` bugs: a rule for a class that is\n // never written.\n this.element?.classList.toggle('twm-managed-window--maximized', this.isMaximized);\n this._applyPosition();\n this._saveCurrentState();\n // C16. Maximise is a STATE, and until now nothing outside this class\n // could see it change. A consumer that wants to say \"a maximised window\n // has no minimize\" \u2014 the WM does, for the windows it promotes out of\n // tiles \u2014 had no edge to hang the rule on and would have had to poll.\n // Same detail shape as the other three window events, `container`\n // included, so a per-region consumer can filter on receipt.\n this._announce('managed-window-maximized', { id: this.id, maximized: this.isMaximized, container: this.container });\n }\n\n /**\n * Find the taskbar button for this window.\n * @returns {DOMRect|null}\n */\n _getTaskbarItemRect() {\n const btn = document.querySelector(`.twm-bar-windows__item[data-window-id=\"${this.id}\"]`);\n return btn ? btn.getBoundingClientRect() : null;\n }\n\n /**\n * Set CSS custom properties to animate minimize toward the taskbar item.\n */\n _setMinimizeTargetProperties() {\n const targetRect = this._getTaskbarItemRect();\n if (!targetRect || !this.element) return;\n\n const winRect = this.element.getBoundingClientRect();\n const winCenterX = winRect.left + winRect.width / 2;\n const winCenterY = winRect.top + winRect.height / 2;\n const targetCenterX = targetRect.left + targetRect.width / 2;\n const targetCenterY = targetRect.top + targetRect.height / 2;\n\n const dx = targetCenterX - winCenterX;\n const dy = targetCenterY - winCenterY;\n const scale = Math.min(targetRect.width / winRect.width, targetRect.height / winRect.height, 0.15);\n\n this.element.style.setProperty('--mw-target-x', `${dx}px`);\n this.element.style.setProperty('--mw-target-y', `${dy}px`);\n this.element.style.setProperty('--mw-target-scale', scale);\n }\n\n /**\n * Set CSS custom properties to animate restore from the taskbar item position.\n * @param {DOMRect|null} taskbarRect\n */\n _setRestoreTargetProperties(taskbarRect) {\n if (!taskbarRect || !this.element) return;\n\n const winRect = this.element.getBoundingClientRect();\n const winCenterX = winRect.left + winRect.width / 2;\n const winCenterY = winRect.top + winRect.height / 2;\n const targetCenterX = taskbarRect.left + taskbarRect.width / 2;\n const targetCenterY = taskbarRect.top + taskbarRect.height / 2;\n\n const dx = targetCenterX - winCenterX;\n const dy = targetCenterY - winCenterY;\n const scale = Math.min(taskbarRect.width / winRect.width, taskbarRect.height / winRect.height, 0.15);\n\n this.element.style.setProperty('--mw-target-x', `${dx}px`);\n this.element.style.setProperty('--mw-target-y', `${dy}px`);\n this.element.style.setProperty('--mw-target-scale', scale);\n }\n\n /**\n * Clear animation CSS custom properties.\n */\n _clearTargetProperties() {\n if (!this.element) return;\n this.element.style.removeProperty('--mw-target-x');\n this.element.style.removeProperty('--mw-target-y');\n this.element.style.removeProperty('--mw-target-scale');\n }\n\n /**\n * Bring window to front of z-order.\n */\n bringToFront() {\n _zIndexCounter++;\n this.zIndex = Math.min(BASE_Z_INDEX + _zIndexCounter, MAX_Z_INDEX);\n if (this.element) {\n this.element.style.zIndex = this.zIndex.toString();\n }\n if (this.backdropElement) {\n this.backdropElement.style.zIndex = (this.zIndex - 1).toString();\n }\n }\n\n /**\n * Update window title.\n */\n setTitle(title) {\n this.title = title;\n if (this.element) {\n const titleEl = this.element.querySelector('.twm-managed-window__title');\n if (titleEl) titleEl.textContent = title;\n }\n }\n\n // ========== Private Methods ==========\n\n _build() {\n // Create backdrop for modal windows\n if (this.modal) {\n this.backdropElement = document.createElement('div');\n this.backdropElement.className = 'twm-managed-window__backdrop';\n // Apply backdrop overrides as inline styles only when the caller\n // set them; otherwise the CSS default governs (single source of\n // truth for the default look).\n if (this.backdropBlur !== undefined && this.backdropBlur !== null) {\n this.backdropElement.style.backdropFilter =\n this.backdropBlur > 0 ? `blur(${this.backdropBlur}px)` : 'none';\n }\n if (this.backdropOpacity !== undefined && this.backdropOpacity !== null) {\n this.backdropElement.style.background =\n `rgba(0, 0, 0, ${this.backdropOpacity})`;\n }\n }\n\n // Create window element\n this.element = document.createElement('div');\n this.element.className = 'twm-managed-window';\n if (!this.canDrag) {\n this.element.classList.add('twm-managed-window--no-drag');\n }\n if (this.modal) {\n this.element.classList.add('twm-managed-window--modal');\n }\n this.element.setAttribute('data-window-id', this.id);\n // BUG-0053. Focusable by script and by a press, never by Tab (the\n // modal trap's `collectFocusable` skips tabindex -1): a press on the\n // title bar or on empty content keeps focus in the window, where a\n // non-modal window's Esc looks for it.\n this.element.tabIndex = -1;\n\n // Top bar\n const topbar = document.createElement('div');\n topbar.className = 'twm-managed-window__topbar';\n\n // Icon\n const icon = document.createElement('span');\n icon.className = 'twm-managed-window__icon material-symbols-outlined';\n icon.textContent = this.icon;\n\n const title = document.createElement('div');\n title.className = 'twm-managed-window__title';\n title.textContent = this.title;\n\n const buttons = document.createElement('div');\n buttons.className = 'twm-managed-window__buttons';\n\n // C6. Extra titlebar buttons, immediately LEFT of minimize \u2014 which is\n // exactly where the concept asks for the table cogwheel. Added before\n // the built-in buttons so the ordering is positional rather than\n // something each caller has to get right.\n for (const spec of this.titlebarButtons) {\n const btn = document.createElement('button');\n btn.className = 'twm-managed-window__btn twm-managed-window__btn--custom';\n btn.type = 'button';\n btn.title = spec.title || '';\n if (spec.icon) {\n const glyph = document.createElement('span');\n glyph.className = 'material-symbols-outlined';\n glyph.textContent = spec.icon;\n btn.appendChild(glyph);\n } else {\n btn.textContent = spec.label || '';\n }\n btn.addEventListener('click', (e) => {\n e.stopPropagation();\n spec.onClick?.(this, e);\n });\n buttons.appendChild(btn);\n }\n\n // Minimize button (optional)\n if (this.canMinimize) {\n const minBtn = document.createElement('button');\n // BOTH SPELLINGS. The `twm-` prefix was missed on this modifier and\n // on `--maximize` when the component was vendored \u2014 the same slip\n // C13 found on the resize handles, where it meant no rule matched\n // either spelling. Nothing styles these two today, so nothing is\n // broken by it, but a consumer that wants to reach for one (the WM\n // hides minimize on a maximised window it promoted) should not have\n // to know which of the two conventions this particular button\n // landed on. The unprefixed name stays for whoever already queries\n // it; the prefixed one is the one to use.\n minBtn.className = 'twm-managed-window__btn '\n + 'twm-managed-window__btn--minimize managed-window__btn--minimize';\n minBtn.type = 'button';\n minBtn.innerHTML = '<svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\"><path d=\"M1 5h8\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\"/></svg>';\n minBtn.title = 'Minimize';\n minBtn.addEventListener('click', (e) => { e.stopPropagation(); this.minimize(); });\n buttons.appendChild(minBtn);\n }\n\n // Maximize button (optional)\n if (this.canMaximize) {\n const maxBtn = document.createElement('button');\n maxBtn.className = 'twm-managed-window__btn '\n + 'twm-managed-window__btn--maximize managed-window__btn--maximize';\n maxBtn.type = 'button';\n // R7. The square is the default and stays the default. A consumer\n // that redefined the gesture with `onMaximize` draws its own glyph\n // here rather than reaching into this markup afterwards \u2014 which is\n // what the WM used to do for its \"back to tile\" button, with four\n // internal class names and a silent failure if any of them moved.\n if (this.maximizeIcon) {\n const glyph = document.createElement('span');\n glyph.className = 'material-symbols-outlined';\n glyph.textContent = this.maximizeIcon;\n maxBtn.appendChild(glyph);\n } else {\n maxBtn.innerHTML = '<svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\"><rect x=\"1\" y=\"1\" width=\"8\" height=\"8\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\"/></svg>';\n }\n maxBtn.title = this.maximizeTitle;\n maxBtn.addEventListener('click', (e) => { e.stopPropagation(); this.toggleMaximize(); });\n buttons.appendChild(maxBtn);\n }\n\n // Close button\n const closeBtn = document.createElement('button');\n closeBtn.className = 'twm-managed-window__btn twm-managed-window__btn--close';\n closeBtn.type = 'button';\n closeBtn.innerHTML = '<svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\"><path d=\"M1 1l8 8M9 1l-8 8\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\"/></svg>';\n closeBtn.title = 'Close';\n closeBtn.addEventListener('click', (e) => { e.stopPropagation(); this.close(); });\n buttons.appendChild(closeBtn);\n\n topbar.appendChild(icon);\n topbar.appendChild(title);\n topbar.appendChild(buttons);\n\n // Content container\n this.contentContainer = document.createElement('div');\n this.contentContainer.className = 'twm-managed-window__content';\n\n if (this.content instanceof HTMLElement) {\n this.contentContainer.appendChild(this.content);\n } else if (typeof this.content === 'function') {\n const rendered = this.content();\n if (rendered instanceof HTMLElement) {\n this.contentContainer.appendChild(rendered);\n }\n }\n\n this.element.appendChild(topbar);\n this.element.appendChild(this.contentContainer);\n\n // Resize handles (only if resizable)\n if (this.canResize) {\n this._addResizeHandles();\n }\n\n // Event listeners\n topbar.addEventListener('pointerdown', (e) => this._onTopbarPointerDown(e));\n if (this.canMaximize) {\n // C26. THE CLAIMED VERB, which under the window manager is \"back to\n // tile\". This went the other way first, on a reading of *\"double\n // click ... always to maximize window\"* as the geometric maximise \u2014\n // the product owner then said *\"double click on a managed window\n // showing a table needs to maximize to tile\"*, which is the claim.\n // `claimable: false` stays on the method for a consumer that wants\n // the rectangle on a window whose maximise is claimed; nothing\n // INSIDE the library passes it, and this binding never has.\n //\n // C28 is what makes this safe for a window with no tile to go back\n // to: the claim may DECLINE \u2014 `bringBackWindow` returns false for a\n // window the WM never adopted \u2014 and `toggleMaximize` then falls\n // through to the geometric maximise. So the gesture always does\n // something, which is the whole complaint it was reported under.\n topbar.addEventListener('dblclick', () => this.toggleMaximize());\n }\n this.element.addEventListener('pointerdown', () => {\n this.bringToFront();\n // The title bar's pointerdown is default-prevented (it starts a\n // drag), which also stops the browser moving focus. A press inside\n // a window that does not hold focus gives it focus; a press on a\n // field then moves it on to the field as usual.\n if (this.element && !this.element.contains(document.activeElement)) {\n try { this.element.focus({ preventScroll: true }); } catch { /* detached */ }\n }\n });\n }\n\n _addResizeHandles() {\n const directions = ['n', 's', 'e', 'w', 'ne', 'nw', 'se', 'sw'];\n for (const dir of directions) {\n const handle = document.createElement('div');\n // BOTH classes carry the `twm-` prefix. The per-direction one was\n // left unprefixed when the framework was namespaced, and no rule for\n // either spelling exists \u2014 so all eight handles were\n // `position: absolute` with no size and no placement, and every\n // window in every consumer was unresizable. The legacy unprefixed\n // class is kept alongside for any embedder still selecting on it.\n handle.className = `twm-managed-window__resize `\n + `twm-managed-window__resize--${dir} managed-window__resize--${dir}`;\n handle.addEventListener('pointerdown', (e) => this._onResizePointerDown(e, dir));\n this.element.appendChild(handle);\n }\n }\n\n /** C2. The bounds rectangle this window is clamped inside.\n *\n * ONE computation replacing four inline copies. The `document.body` case \u2014\n * every call site that exists today \u2014 reduces to the previous expression\n * BY SUBSTITUTION, not by \"should be equivalent\":\n *\n * minX = 0\n * minY = TOP_BAR_HEIGHT\n * width = window.innerWidth\n * height = window.innerHeight - TOP_BAR_HEIGHT - BOTTOM_BAR_HEIGHT\n *\n * (STORY-0119: TOP_BAR_HEIGHT here is `_topInset()`, which is\n * TOP_BAR_HEIGHT on a page without a menu row and adds the row's height\n * on a page with one.)\n *\n * so, substituting into the clamps below:\n *\n * maxWidth = width = window.innerWidth \u2713\n * maxHeight = height = innerHeight - TOP - BOTTOM \u2713\n * maxX = max(minX, minX + width - w) = max(0, innerWidth - w) \u2713\n * maxY = max(minY, minY + height - h) = max(TOP, innerHeight - BOTTOM - h) \u2713\n * x = max(minX, min(x, maxX)) = max(0, min(x, maxX)) \u2713\n * y = max(minY, min(y, maxY)) = max(TOP, min(y, maxY)) \u2713\n *\n * Embedders' modals depend on that arithmetic; prove the\n * equivalence in review by substitution rather than by testing.\n */\n _bounds() {\n // R12. Mid-escape the container is the drag HOST \u2014 the root, which\n // contains the panels as well as the tiles. `dragBounds` narrows it to\n // the part a window belongs in; without it the bottom edge is the\n // root's, and the bottom panel is inside that.\n //\n // R13. AND FOR AS LONG AS THE WINDOW IS LEFT THERE. A drop the snap\n // controller CLAIMS ends the escape WITHOUT putting the window back\n // (`_endDragEscape({ taken: true })` returns before re-parenting), and\n // the window manager's aero-snap maximise is exactly that case: the\n // window stays a child of the host, filling the part of it\n // `dragBounds` describes. `_escapeOrigin` is null by then, so the test\n // as it stood stopped applying the moment the drag ended \u2014 and the next\n // re-clamp, which the container's ResizeObserver performs on any\n // splitter drag, would re-read the bounds as the WHOLE ROOT and grow\n // the window out over the docked panels.\n //\n // What the two cases share is not \"mid-drag\", it is THE CONTAINER IS\n // THE DRAG HOST \u2014 never true of a window sitting in its own pane, and\n // true of every window the host is currently holding. `dragHost` is\n // resolved rather than remembered for the same reason `_beginDragEscape`\n // resolves it: it is a function so that it can outlive any one tile.\n if (this.dragBounds) {\n const host = typeof this.dragHost === 'function'\n ? this.dragHost(this) : this.dragHost;\n if (this._escapeOrigin || (host && host === this.container)) {\n const b = this.dragBounds(this);\n if (b && b.width > 0 && b.height > 0) return b;\n }\n }\n if (this.container) {\n // Contained: coordinates are relative to the container, which is a\n // positioned ancestor, so the bars do not apply.\n return {\n minX: 0,\n minY: 0,\n width: this.container.clientWidth,\n height: this.container.clientHeight,\n };\n }\n const top = _topInset();\n return {\n minX: 0,\n minY: top,\n width: window.innerWidth,\n height: window.innerHeight - top - BOTTOM_BAR_HEIGHT,\n };\n }\n\n _applyPosition() {\n if (!this.element) return;\n\n const bounds = this._bounds();\n const maxWidth = bounds.width;\n const maxHeight = bounds.height;\n\n // Clamp width and height to the bounds (but respect minWidth/minHeight)\n this.width = Math.max(this.minWidth, Math.min(this.width, maxWidth));\n this.height = Math.max(this.minHeight, Math.min(this.height, maxHeight));\n\n // Ensure the window is within the bounds rectangle\n const maxX = Math.max(bounds.minX, bounds.minX + maxWidth - this.width);\n const maxY = Math.max(bounds.minY, bounds.minY + maxHeight - this.height);\n this.x = Math.max(bounds.minX, Math.min(this.x, maxX));\n this.y = Math.max(bounds.minY, Math.min(this.y, maxY));\n\n this.element.style.left = `${this.x}px`;\n this.element.style.top = `${this.y}px`;\n this.element.style.width = `${this.width}px`;\n this.element.style.height = `${this.height}px`;\n }\n\n /** C12. Re-clamp on demand.\n *\n * The ResizeObserver below covers a container that changes size on its\n * own. A container that changes size because a SIBLING did \u2014 a splitter\n * drag moves two panels at once \u2014 needs the caller to say so, and a\n * private `_applyPosition` is not something a caller may reach for. */\n reclamp() {\n this._applyPosition();\n }\n\n /** C12. Move this window into a different container.\n *\n * Re-parents the element and re-clamps against the new bounds, because a\n * window carried into a narrower region would otherwise keep coordinates\n * that put it outside and out of reach. The ResizeObserver follows the new\n * container, or the old one would keep driving the clamp.\n */\n moveTo(container) {\n if (!container || container === this.container) return false;\n this.container = container;\n if (this.element) {\n container.appendChild(this.element);\n this.element.classList.toggle('twm-managed-window--contained', true);\n if (this.backdropElement) container.appendChild(this.backdropElement);\n }\n this._resizeObserver?.disconnect();\n this._resizeObserver = null;\n this._installContainerResizeObserver();\n // A snapped window's rectangle belonged to the old container, so the\n // snap does not survive the move; its pre-snap size does.\n this._preSnapState = null;\n this.element?.classList.remove('twm-managed-window--snapped');\n if (this.isMaximized) {\n const bounds = this._bounds();\n this.x = bounds.minX; this.y = bounds.minY;\n this.width = bounds.width; this.height = bounds.height;\n }\n this._applyPosition();\n this._announce('managed-window-moved', { id: this.id, container });\n return true;\n }\n\n /** R1/R3. The container this drag started in, or null when the drag did\n * not have to escape one (an uncontained window, or no `dragHost`).\n *\n * Public because the decision that needs it is not this component's: a snap\n * controller has to know which pane is HOME so that moving a window around\n * inside the pane it already lives in arms nothing. That was the complaint\n * about the old behaviour \u2014 in-pane, virtually any movement was a dock. */\n get dragOrigin() { return this._escapeOrigin; }\n\n /** R1. Take the window out of its container for the duration of a drag.\n *\n * A contained window is clipped by its container (`.twm-leaf` is\n * `overflow: hidden`), so without this it cannot be dragged one pixel past\n * the pane it lives in \u2014 the gesture the tiling model is built on is not\n * merely awkward, it is invisible. The window is re-parented into the\n * wider `dragHost` and its coordinates are converted so the rectangle on\n * screen does not move: same viewport pixels, different reference frame.\n *\n * Deliberately NOT `moveTo` (C12), which is the same re-parent for a\n * different purpose. `moveTo` re-CLAMPS into the new container without\n * converting anything, which is right when a window is carried between\n * regions by a menu and wrong here \u2014 the window would jump out from under\n * the pointer at the first millimetre of every drag. It also drops the snap\n * and announces `managed-window-moved`, and an escape is neither a move the\n * user asked for nor one anybody should hear about: it is undone on\n * release, either by `_endDragEscape` or by the drop taking the window.\n */\n _beginDragEscape() {\n if (this._escapeOrigin || !this.container || !this.dragHost) return false;\n const host = typeof this.dragHost === 'function'\n ? this.dragHost(this) : this.dragHost;\n // CONTAINS, not merely \"different\". The host is meant to be the wider\n // box the window may now cross; anything else would teleport it.\n if (!host || host === this.container || !host.contains(this.container)) return false;\n const origin = this.container;\n this._escapeOrigin = origin;\n this._reparentPreservingPosition(host);\n return true;\n }\n\n /** R1. Put the window back into a container when the drag ends.\n *\n * `taken` means the drop was claimed by the snap controller: the window is\n * being docked into a tree and closed, so re-parenting it into a pane it is\n * about to leave would be work done for a frame nobody sees.\n *\n * Otherwise it goes back where the drag started \u2014 including when the drag\n * ended over nothing (the rail, the gap between two panes, off the edge).\n * A window that lives in a pane has to end every drag in SOME pane, and the\n * one it came from is the only answer that never surprises anyone. The one\n * case that cannot be honoured is an origin that stopped being in the\n * document mid-drag \u2014 a repaint rebuilt the leaf wrap \u2014 and there the\n * window stays on the host rather than being orphaned into a detached\n * node; the WM's own re-home pass adopts it on the next render.\n */\n _endDragEscape({ taken = false } = {}) {\n const origin = this._escapeOrigin;\n this._escapeOrigin = null;\n this.element?.classList.remove('twm-managed-window--detached');\n if (!origin || taken) return false;\n if (!origin.isConnected) return false;\n this._reparentPreservingPosition(origin);\n return true;\n }\n\n /** Move the element into `next` and rewrite `x`/`y` so it occupies the same\n * viewport rectangle it did a moment ago.\n *\n * `x`/`y` are written against the containing block, which for an absolutely\n * positioned child is the PADDING box \u2014 hence `clientLeft`/`clientTop`,\n * which are the border widths `getBoundingClientRect` includes and the\n * offset does not. `scrollLeft`/`scrollTop` are zero for every box either\n * side of this today (panes and the WM root both clip rather than scroll)\n * and are in the expression anyway: the day one of them scrolls, this is\n * the line that would be silently half a screen out.\n *\n * The container's ResizeObserver is deliberately NOT re-pointed. It exists\n * to re-clamp (C4), it re-clamps against whichever container is current\n * because `_applyPosition` reads `_bounds()` afresh, and an escape is\n * transient by construction \u2014 undone on release, or ended by the window\n * closing into a tree. `moveTo`, which is a permanent move, does re-point\n * it, and that difference is the reason these are two methods.\n */\n _reparentPreservingPosition(next) {\n const prev = this.container;\n if (!next || next === prev) return false;\n if (this.element && prev) {\n const from = prev.getBoundingClientRect();\n const to = next.getBoundingClientRect();\n this.x += (from.left + prev.clientLeft - prev.scrollLeft)\n - (to.left + next.clientLeft - next.scrollLeft);\n this.y += (from.top + prev.clientTop - prev.scrollTop)\n - (to.top + next.clientTop - next.scrollTop);\n }\n this.container = next;\n if (this.element) {\n next.appendChild(this.element);\n // Still contained \u2014 a drag host is another box on the page, not the\n // page \u2014 so the `position: absolute` modifier stays exactly as it\n // was. Toggled rather than assumed, because a window whose container\n // was null cannot reach here but a future caller might.\n this.element.classList.toggle('twm-managed-window--contained', !!next);\n if (this.backdropElement) next.appendChild(this.backdropElement);\n }\n this._applyPosition();\n return true;\n }\n\n /** R3. HALF TRANSPARENT THE MOMENT IT LEAVES THE TILE IT CAME FROM.\n *\n * The signal that releasing now will dock the window somewhere, and the\n * complement of the rule that keeps the origin pane silent: inside it, this\n * is just a window being moved and it stays opaque. Only for a window with\n * a snap controller \u2014 nothing else on the page can be docked, so nothing\n * else has anything to promise.\n *\n * A window that never had a pane (opened with Alt+N, floating over the\n * whole root) has no \"inside\" to be in, so it reads as detached for the\n * whole drag. That is not a special case being papered over: every pane\n * under it genuinely is foreign, and every drop on one genuinely docks.\n */\n _syncDragTransparency(e) {\n if (!this.snapController || !this.element) return;\n const origin = this._escapeOrigin;\n let outside = true;\n if (origin && origin.isConnected) {\n const r = origin.getBoundingClientRect();\n outside = e.clientX < r.left || e.clientX > r.right\n || e.clientY < r.top || e.clientY > r.bottom;\n }\n this.element.classList.toggle('twm-managed-window--detached', outside);\n }\n\n /** C4. Re-clamp when the container resizes.\n *\n * `managed_window.js` has NO resize listener at all today: a viewport\n * resize simply leaves windows where they were until the next pointer\n * move re-clamps them. That is survivable for the viewport, which resizes\n * rarely, and not for a panel, which resizes every time someone drags a\n * splitter \u2014 a window would end up outside its own panel and unreachable.\n */\n _installContainerResizeObserver() {\n if (!this.container || this._resizeObserver) return;\n this._resizeObserver = new ResizeObserver(() => {\n if (this.isMaximized) {\n const bounds = this._bounds();\n this.x = bounds.minX;\n this.y = bounds.minY;\n this.width = bounds.width;\n this.height = bounds.height;\n }\n this._applyPosition();\n });\n this._resizeObserver.observe(this.container);\n }\n\n _teardownContainerResizeObserver() {\n this._resizeObserver?.disconnect();\n this._resizeObserver = null;\n }\n\n _restoreState() {\n const bounds = this._bounds();\n const maxWidth = bounds.width;\n const maxHeight = bounds.height;\n\n // Modal windows always center on screen - never restore saved position\n const saved = this.modal || !this.persistGeometry ? null : _getWindowState(this.id);\n if (saved) {\n this.x = saved.x ?? this.x;\n this.y = saved.y ?? this.y;\n // Clamp restored dimensions to current viewport\n this.width = Math.min(saved.width ?? this.width, maxWidth);\n this.height = Math.min(saved.height ?? this.height, maxHeight);\n this.isMaximized = saved.maximized ?? false;\n\n if (this.isMaximized && this.canMaximize) {\n this._preMaximizeState = { x: saved.x, y: saved.y, width: saved.width, height: saved.height };\n this.x = bounds.minX;\n this.y = bounds.minY;\n this.width = maxWidth;\n this.height = maxHeight;\n }\n } else {\n // Center on screen (between top and bottom bars)\n this.x = Math.max(0, (maxWidth - this.width) / 2);\n const top = _topInset();\n this.y = Math.max(top, top + (maxHeight - this.height) / 2);\n }\n }\n\n _saveCurrentState() {\n // Modal windows always center - no need to persist position\n if (this.modal || !this.persistGeometry || this._closed) return;\n\n _setWindowState(this.id, {\n x: this._preMaximizeState?.x ?? this.x,\n y: this._preMaximizeState?.y ?? this.y,\n width: this._preMaximizeState?.width ?? this.width,\n height: this._preMaximizeState?.height ?? this.height,\n maximized: this.isMaximized,\n });\n }\n\n // ========== Drag Handling ==========\n\n _onTopbarPointerDown(e) {\n // Don't start drag if clicking on buttons\n if (e.target.closest('.twm-managed-window__buttons')) return;\n if (this.isMaximized) return;\n if (!this.canDrag) return;\n\n e.preventDefault();\n // Picking up a SNAPPED window restores the size it had before, centred\n // under the pointer \u2014 the same gesture Windows uses, and the reason a\n // snap does not have to be undone through a menu.\n if (this.snap && this._preSnapState) {\n const grabRatio = this.width ? (e.clientX - this.x) / this.width : 0.5;\n this.unsnap();\n this.x = Math.round(e.clientX - this.width * grabRatio);\n this._applyPosition();\n }\n // \u2550\u2550 C28. THE ESCAPE WAITS FOR MOVEMENT, AND THAT IS THE WHOLE OF\n // WHY DOUBLE-CLICKING A TITLE BAR DID NOTHING \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n //\n // R1 escaped the pane HERE, on pointerdown, before the pointer had\n // moved a pixel \u2014 so every press on a title bar tore the window element\n // out of `.tbl-canvas-pane`, appended it to the WM root, and put it\n // back on release. Two DOM removals per click, for a click.\n //\n // Blink and Gecko both drop the pending click when the element the\n // press landed on leaves the document between press and release:\n // `MouseEventManager::NodeWillBeRemoved` clears `mouse_down_element_`,\n // and `click` is dispatched to the common ancestor of that element and\n // the release target \u2014 with it null, no `click` is dispatched at all,\n // and `dblclick`, which counts clicks, never comes. So the `dblclick`\n // listener eleven lines below `_addResizeHandles` has never once fired\n // on a CONTAINED window in a real browser. Reported twice as *\"double\n // click does not maximize to tile\"*, and re-reading the listener could\n // not find it: the listener is correct, the gesture never reaches it.\n //\n // jsdom cannot see this \u2014 it has no click-count model and a test\n // dispatches `dblclick` directly \u2014 which is why every existing check\n // says the gesture works. The assertion that CAN see it is the one\n // about the mechanism: a press with no movement must leave the element\n // where it found it, and `web/js/shell/window_lifecycle.test.mjs`\n // asserts exactly that.\n //\n // Deferring costs nothing the escape was buying. R1 exists so a\n // contained window can be dragged past the pane that clips it, and\n // nothing is clipped until something moves; `_onPointerMove` performs\n // it on the first movement and corrects the drag origin by the same\n // delta `_reparentPreservingPosition` applied, so the window still\n // tracks the pointer exactly. `_onPointerUp` already tolerates a drag\n // that never escaped \u2014 `_endDragEscape` returns early with no origin.\n this._dragState = {\n startX: e.clientX,\n startY: e.clientY,\n startWinX: this.x,\n startWinY: this.y,\n };\n\n document.addEventListener('pointermove', this._boundOnPointerMove);\n document.addEventListener('pointerup', this._boundOnPointerUp);\n // A cancelled pointer never produces a `pointerup` \u2014 a touch turning\n // into a browser gesture, the tab losing the pointer, a device\n // disconnecting. Before C15 that left a window mid-drag, which the next\n // pointerdown corrected; now it can also leave a `position: fixed`\n // preview rectangle painted over the page with nothing to remove it.\n document.addEventListener('pointercancel', this._boundOnPointerUp);\n }\n\n _onPointerMove(e) {\n if (this._dragState) {\n // C28. THE ESCAPE, at the first movement rather than at the press \u2014\n // see `_onTopbarPointerDown` for the click it used to eat.\n //\n // `_reparentPreservingPosition` rewrites `this.x`/`this.y` into the\n // host's reference frame so the rectangle on screen does not move.\n // `_dragState.startWinX` was recorded in the PANE's frame a moment\n // ago and is the origin every subsequent delta is added to, so it\n // has to make the same journey \u2014 otherwise the window jumps by the\n // offset between the two boxes at the first millimetre of the drag,\n // which is the exact failure R1's \"out of the pane FIRST\" comment\n // was written to prevent. Same correction, applied where the escape\n // now happens.\n if (!this._escapeOrigin) {\n const fromX = this.x;\n const fromY = this.y;\n if (this._beginDragEscape()) {\n this._dragState.startWinX += this.x - fromX;\n this._dragState.startWinY += this.y - fromY;\n }\n }\n const dx = e.clientX - this._dragState.startX;\n const dy = e.clientY - this._dragState.startY;\n this.x = this._dragState.startWinX + dx;\n this.y = this._dragState.startWinY + dy;\n this._applyPosition();\n this._syncDragTransparency(e);\n if (this.snap) this._updateSnapZone(e);\n } else if (this._resizeState) {\n this._handleResize(e);\n }\n }\n\n _onPointerUp() {\n // The snap is applied BEFORE the state is saved, so what is persisted is\n // where the window ended up rather than where it was let go.\n let taken = false;\n if (this._dragState && this.snap && this._snapZone) {\n // C15. A controller answers instead of `_applySnap` when there is\n // one. It may answer asynchronously (a three-way choice is a menu),\n // which is why a truthy return also transfers ownership of the\n // preview \u2014 clearing it here would blank the affordance the menu is\n // still describing.\n if (this.snapController) {\n // Guarded, exactly as `probe` is. `commit` is not a leaf call \u2014\n // it reaches all the way into somebody else's tree mutation and\n // back out through a window close \u2014 and an exception escaping\n // here would leave the drag listeners attached and the window\n // following the pointer for ever.\n try {\n taken = this.snapController.commit?.(this._snapProbe, this) ?? false;\n } catch (err) {\n console.error('[managed-window] snap commit threw', err);\n taken = false;\n }\n } else {\n this._applySnap(this._snapZone);\n }\n }\n if (!taken) this.clearSnapPreview();\n this._snapZone = null;\n // R1. Back into a container before `_saveCurrentState`, or what is\n // persisted is a rectangle in the drag host's space that will be read\n // back as if it were the pane's.\n if (this._dragState) this._endDragEscape({ taken });\n if (this._dragState || this._resizeState) {\n this._saveCurrentState();\n }\n this._dragState = null;\n this._resizeState = null;\n document.removeEventListener('pointermove', this._boundOnPointerMove);\n document.removeEventListener('pointerup', this._boundOnPointerUp);\n document.removeEventListener('pointercancel', this._boundOnPointerUp);\n }\n\n // ========== C11. Aero Snap ==========\n\n /** The rectangle a zone would give this window, in the SAME coordinate\n * space `_applyPosition` writes \u2014 container-relative when contained,\n * viewport-relative otherwise. One source for the preview and the apply,\n * so the preview cannot promise a rectangle the drop does not deliver. */\n _snapRect(zone) {\n const b = this._bounds();\n const half = Math.round(b.width / 2);\n switch (zone) {\n case 'top': return { x: b.minX, y: b.minY, width: b.width, height: b.height };\n case 'left': return { x: b.minX, y: b.minY, width: half, height: b.height };\n case 'right': return { x: b.minX + b.width - half, y: b.minY,\n width: half, height: b.height };\n default: return null;\n }\n }\n\n /** Which zone the POINTER is in \u2014 not the window. Using the window's own\n * edge would make a wide window snap the moment it is picked up, because\n * it is already touching the edge it did not move towards. */\n _zoneFor(e) {\n const host = this.container || document.documentElement;\n const rect = this.container\n ? host.getBoundingClientRect()\n : { left: 0, top: 0, width: window.innerWidth, height: window.innerHeight };\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n // Outside the host entirely: no zone. Dragging a contained window over\n // the page chrome must not snap it to the container's edge.\n if (x < 0 || y < 0 || x > rect.width || y > rect.height) return null;\n if (y <= SNAP_EDGE) return 'top';\n if (x <= SNAP_EDGE) return 'left';\n if (x >= rect.width - SNAP_EDGE) return 'right';\n return null;\n }\n\n _updateSnapZone(e) {\n if (this.snapController) { this._updateControlledSnapZone(e); return; }\n const zone = this._zoneFor(e);\n if (zone === this._snapZone) return;\n this._snapZone = zone;\n if (!zone) { this.clearSnapPreview(); return; }\n this.showSnapPreview(this._snapRect(zone));\n }\n\n /** C15. The controller's half of `_updateSnapZone`. The probe runs on every\n * move because the rectangle can change while the KEY does not \u2014 a tile\n * resized underneath the pointer, a menu re-previewing the same zone \u2014 but\n * the DOM is only touched when something actually differs. */\n _updateControlledSnapZone(e) {\n let probe = null;\n try { probe = this.snapController.probe?.(e, this) ?? null; }\n catch (err) { console.warn('[managed-window] snap probe threw', err); }\n this._snapProbe = probe;\n this._snapZone = probe?.key ?? null;\n if (!probe?.rect) { this.clearSnapPreview(); return; }\n this.showSnapPreview(probe.rect, { viewport: true });\n }\n\n /** Paint the drag affordance. `rect` is container-relative by default \u2014\n * the same space `_applyPosition` writes \u2014 and viewport-relative for a\n * controller, whose rectangles come from hit-testing other people's DOM.\n * Public because a controller that survives the pointer-up owns it. */\n showSnapPreview(rect, { viewport = false } = {}) {\n if (!rect) { this.clearSnapPreview(); return; }\n const host = viewport ? document.body : (this.container || document.body);\n if (!this._snapPreviewEl) {\n this._snapPreviewEl = document.createElement('div');\n // `aria-hidden`: it is a drag affordance, not content.\n this._snapPreviewEl.setAttribute('aria-hidden', 'true');\n }\n this._snapPreviewEl.className =\n `twm-snap-preview${viewport ? ' twm-snap-preview--viewport' : ''}`;\n const left = rect.left ?? rect.x;\n const top = rect.top ?? rect.y;\n Object.assign(this._snapPreviewEl.style, {\n left: `${left}px`, top: `${top}px`,\n width: `${rect.width}px`, height: `${rect.height}px`,\n });\n if (this._snapPreviewEl.parentNode !== host) host.appendChild(this._snapPreviewEl);\n }\n\n clearSnapPreview() {\n this._snapPreviewEl?.remove();\n this._snapProbe = null;\n }\n\n /** @deprecated retained so nothing inside this file has to change spelling\n * in the same commit that adds the public one. */\n _clearSnapPreview() { this.clearSnapPreview(); }\n\n /** Applied on release. The pre-snap geometry is remembered so dragging the\n * window off an edge restores the size it had \u2014 a snap that eats the\n * original size makes the gesture one-way and people stop using it. */\n _applySnap(zone) {\n const rect = this._snapRect(zone);\n if (!rect) return;\n if (!this._preSnapState) {\n this._preSnapState = { x: this._dragState.startWinX, y: this._dragState.startWinY,\n width: this.width, height: this.height };\n }\n this.x = rect.x;\n this.y = rect.y;\n this.width = rect.width;\n this.height = rect.height;\n this._applyPosition();\n this.element?.classList.add('twm-managed-window--snapped');\n this._announce('managed-window-snapped', { id: this.id, zone, container: this.container });\n }\n\n /** Restore the geometry a snap replaced. Called when a snapped window is\n * picked up again, which is the gesture that means \"un-snap\". */\n unsnap() {\n if (!this._preSnapState) return false;\n const { x, y, width, height } = this._preSnapState;\n this._preSnapState = null;\n this.x = x; this.y = y; this.width = width; this.height = height;\n this._applyPosition();\n this.element?.classList.remove('twm-managed-window--snapped');\n return true;\n }\n\n // ========== Resize Handling ==========\n\n _onResizePointerDown(e, direction) {\n if (this.isMaximized) return;\n\n e.preventDefault();\n e.stopPropagation();\n\n this._resizeState = {\n direction,\n startX: e.clientX,\n startY: e.clientY,\n startWinX: this.x,\n startWinY: this.y,\n startWidth: this.width,\n startHeight: this.height,\n };\n\n document.addEventListener('pointermove', this._boundOnPointerMove);\n document.addEventListener('pointerup', this._boundOnPointerUp);\n }\n\n _handleResize(e) {\n const state = this._resizeState;\n if (!state) return;\n\n const dx = e.clientX - state.startX;\n const dy = e.clientY - state.startY;\n const dir = state.direction;\n\n // Calculate max available dimensions\n const maxWidth = window.innerWidth;\n const top = _topInset();\n const maxHeight = window.innerHeight - top - BOTTOM_BAR_HEIGHT;\n\n let newX = state.startWinX;\n let newY = state.startWinY;\n let newW = state.startWidth;\n let newH = state.startHeight;\n\n // Handle horizontal resize\n if (dir.includes('e')) {\n newW = Math.max(this.minWidth, Math.min(state.startWidth + dx, maxWidth - newX));\n }\n if (dir.includes('w')) {\n const maxDx = state.startWidth - this.minWidth;\n const actualDx = Math.min(dx, maxDx);\n newX = Math.max(0, state.startWinX + actualDx);\n newW = state.startWidth - (newX - state.startWinX);\n }\n\n // Handle vertical resize\n if (dir.includes('s')) {\n newH = Math.max(this.minHeight, Math.min(state.startHeight + dy, maxHeight - (newY - top)));\n }\n if (dir.includes('n')) {\n const maxDy = state.startHeight - this.minHeight;\n const actualDy = Math.min(dy, maxDy);\n newY = Math.max(top, state.startWinY + actualDy);\n newH = state.startHeight - (newY - state.startWinY);\n }\n\n this.x = newX;\n this.y = newY;\n this.width = newW;\n this.height = newH;\n this._applyPosition();\n }\n\n // ========== Keyboard Handling ==========\n\n _onKeyDown(e) {\n if (!this.isVisible || this.isMinimized) return;\n // Only the top-most window owns global keydowns \u2014 otherwise a\n // background window would steal focus from an open modal.\n const topWindow = Array.from(_activeWindows.values())\n .filter(w => w.isVisible && !w.isMinimized)\n .sort((a, b) => b.zIndex - a.zIndex)[0];\n if (e.key === 'Escape') {\n // BUG-0053. An Esc something inside already answered (an\n // autocomplete closing its list) or one that ends an IME\n // composition is not the window's.\n if (e.defaultPrevented || e.isComposing || _escAnswered.has(e)) return;\n if (_escAnswerer() === this) {\n _escAnswered.add(e);\n this.close();\n }\n return;\n }\n if (topWindow !== this) return;\n\n // Focus trap for modals: Tab and Shift+Tab cycle through the\n // focusable elements inside the modal's frame instead of\n // escaping to underlying tiles. Without this, Tab moves the\n // active element into the background \u2014 bad UX, and a\n // genuine WCAG focus-trap violation for accessibility tools.\n if (e.key === 'Tab' && this.modal && this.element) {\n // A popover opened from this modal is over it but outside its frame,\n // and sees to its own Tab.\n if (isInAnchoredLayer(document.activeElement)) return;\n const focusables = collectFocusable(this.element);\n if (focusables.length === 0) {\n e.preventDefault();\n return;\n }\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n const active = document.activeElement;\n if (e.shiftKey) {\n if (active === first || !this.element.contains(active)) {\n e.preventDefault();\n last.focus();\n }\n } else {\n if (active === last || !this.element.contains(active)) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n }\n\n // ========== Static Methods ==========\n\n /**\n * Choose where window geometry is saved and restored. Call once at boot,\n * before the first window opens; from then on windows read and write only\n * `storageKey`. The geometry already read from another key is dropped, so\n * a window shown afterwards restores what `storageKey` holds.\n *\n * @param {object} [opts]\n * @param {string} [opts.storageKey=DEFAULT_WINDOW_STORAGE_KEY]\n * @param {number} [opts.maxSavedWindows=DEFAULT_MAX_SAVED_WINDOWS] How many\n * ids keep saved geometry; the least recently saved go first.\n */\n static configure({ storageKey = DEFAULT_WINDOW_STORAGE_KEY,\n maxSavedWindows = DEFAULT_MAX_SAVED_WINDOWS } = {}) {\n _storageKey = storageKey;\n _maxSavedWindows = Math.max(1, Math.floor(maxSavedWindows) || DEFAULT_MAX_SAVED_WINDOWS);\n _stateCache = null;\n }\n\n /** @returns {string} The localStorage key window geometry uses. */\n static get storageKey() {\n return _storageKey;\n }\n\n /**\n * Get a window by ID.\n */\n static get(id) {\n return _activeWindows.get(id) || null;\n }\n\n /**\n * Every window this class currently holds, newest last.\n *\n * `get`/`restore` answer about a window whose id you already have, which is\n * enough for a consumer reacting to an EVENT \u2014 it carries the id. It is not\n * enough for one that has to repaint from scratch: a taskbar rebuilt with\n * its pane has missed every event that came before it existed, and the only\n * honest source for \"which windows are minimised right now\" is the registry\n * itself. Returned as an array rather than the live map, so a consumer\n * iterating it cannot mutate what it is iterating.\n */\n static all() {\n return [..._activeWindows.values()];\n }\n\n /**\n * Restore a minimized window by ID.\n */\n static restore(id) {\n const win = _activeWindows.get(id);\n if (win && win.isMinimized) {\n win._restore();\n win.bringToFront();\n }\n }\n}\n", "/**\n * ToggleField \u2014 an on/off switch: a track and a knob drawn over a REAL\n * checkbox, so the form, the label and assistive technology all see a native\n * control.\n *\n * const t = new ToggleField({ label: 'Autosave', onText: 'On', offText: 'Off',\n * checked: true, onChange: (on) => save(on) });\n * host.appendChild(t.render());\n * t.get(); // true\n * t.set(false); // no onChange: the caller already knows\n * t.setDisabled(true);\n * t.dispose();\n *\n * The input carries `role=\"switch\"` and an `aria-checked` that follows it.\n * Space toggles it (as it does any checkbox) and so does Enter, which a\n * checkbox ignores but a switch is expected to honour. Both go through the\n * input's own `click()`, so a disabled switch ignores them exactly as it\n * ignores the mouse, and a toggle fires the input's `input` and `change` like\n * any other control. The root is a `<label>`, so a click on the track, the\n * on/off text or the label toggles it too.\n *\n * Markup \u2014 every class is styled by `flexdesk.css` from tokens alone:\n *\n * label.twm-toggle[.twm-toggle--compact][.twm-toggle--disabled]\n * span.twm-toggle__control\n * input.twm-toggle__input[type=checkbox][role=switch]\n * span.twm-toggle__track > span.twm-toggle__knob\n * span.twm-toggle__state (onText / offText, when either is given)\n * span.twm-toggle__label (label, when given)\n */\nexport class ToggleField {\n /**\n * @param {object} o\n * @param {boolean} [o.checked=false]\n * @param {string?} [o.label] text beside the switch, and its accessible name\n * @param {string?} [o.ariaLabel] accessible name when there is no visible label\n * @param {string?} [o.onText] state text shown while on\n * @param {string?} [o.offText] state text shown while off\n * @param {boolean} [o.disabled=false]\n * @param {boolean} [o.compact=false] a smaller track, for dense rows\n * @param {string?} [o.name] the input's name, for a surrounding form\n * @param {string?} [o.id] the input's id\n * @param {Function?}[o.onChange] `(checked: boolean)` after a user toggle\n */\n constructor({\n checked = false, label = null, ariaLabel = null, onText = null, offText = null,\n disabled = false, compact = false, name = null, id = null, onChange = null,\n } = {}) {\n this._initial = !!checked;\n this._label = label == null ? null : String(label);\n this._ariaLabel = ariaLabel == null ? null : String(ariaLabel);\n this._onText = onText == null ? null : String(onText);\n this._offText = offText == null ? null : String(offText);\n this._disabled = !!disabled;\n this._compact = !!compact;\n this._name = name == null ? null : String(name);\n this._id = id == null ? null : String(id);\n this._onChange = typeof onChange === 'function' ? onChange : null;\n\n this.root = null;\n this.input = null;\n this._stateEl = null;\n this._disposers = [];\n }\n\n /** Build the switch once and hand back its root; later calls return it. */\n render() {\n if (this.root) return this.root;\n\n const root = document.createElement('label');\n root.className = 'twm-toggle';\n if (this._compact) root.classList.add('twm-toggle--compact');\n\n const control = document.createElement('span');\n control.className = 'twm-toggle__control';\n\n const input = document.createElement('input');\n input.type = 'checkbox';\n input.className = 'twm-toggle__input';\n input.setAttribute('role', 'switch');\n if (this._name) input.name = this._name;\n if (this._id) input.id = this._id;\n if (this._ariaLabel && !this._label) input.setAttribute('aria-label', this._ariaLabel);\n input.checked = this._initial;\n\n const track = document.createElement('span');\n track.className = 'twm-toggle__track';\n track.setAttribute('aria-hidden', 'true');\n const knob = document.createElement('span');\n knob.className = 'twm-toggle__knob';\n track.appendChild(knob);\n\n control.append(input, track);\n root.appendChild(control);\n\n if (this._onText != null || this._offText != null) {\n this._stateEl = document.createElement('span');\n this._stateEl.className = 'twm-toggle__state';\n // The switch already says on/off to a screen reader.\n this._stateEl.setAttribute('aria-hidden', 'true');\n root.appendChild(this._stateEl);\n }\n if (this._label != null) {\n const labelEl = document.createElement('span');\n labelEl.className = 'twm-toggle__label';\n labelEl.textContent = this._label;\n root.appendChild(labelEl);\n }\n\n this.root = root;\n this.input = input;\n this.setDisabled(this._disabled);\n this._sync();\n\n const onKeyDown = (e) => {\n if (e.key !== ' ' && e.key !== 'Enter') return;\n // Ours, not the browser's: Space would otherwise activate on keyup\n // as well, and Enter would submit the surrounding form.\n e.preventDefault();\n if (e.repeat) return;\n input.click();\n };\n const onKeyUp = (e) => { if (e.key === ' ') e.preventDefault(); };\n const onChange = () => {\n this._sync();\n this._onChange?.(input.checked);\n };\n input.addEventListener('keydown', onKeyDown);\n input.addEventListener('keyup', onKeyUp);\n input.addEventListener('change', onChange);\n this._disposers.push(\n () => input.removeEventListener('keydown', onKeyDown),\n () => input.removeEventListener('keyup', onKeyUp),\n () => input.removeEventListener('change', onChange),\n );\n return root;\n }\n\n /** Whether the switch is on. */\n get() {\n return this.input ? this.input.checked : this._initial;\n }\n\n /** Turn it on or off. Does NOT call `onChange`. */\n set(checked) {\n if (!this.input) { this._initial = !!checked; return; }\n this.input.checked = !!checked;\n this._sync();\n }\n\n /** A disabled switch ignores clicks and keys alike. */\n setDisabled(disabled) {\n this._disabled = !!disabled;\n if (!this.input) return;\n this.input.disabled = this._disabled;\n this.root.classList.toggle('twm-toggle--disabled', this._disabled);\n }\n\n dispose() {\n for (const d of this._disposers) {\n try { d(); } catch { /* the element is already gone */ }\n }\n this._disposers = [];\n this.root?.remove();\n this.root = null;\n this.input = null;\n this._stateEl = null;\n }\n\n _sync() {\n const on = this.input.checked;\n this.input.setAttribute('aria-checked', on ? 'true' : 'false');\n if (this._stateEl) this._stateEl.textContent = (on ? this._onText : this._offText) ?? '';\n }\n}\n", "/**\n * Fire a DOM event on `target`, built by `target`'s own window.\n *\n * `dispatchEvent` takes only an event from the target's realm. A bare\n * `new Event(...)` reads whatever global the running code sees, and that is a\n * different realm from the element's in an iframe, and under jsdom on any Node\n * with a global `Event` of its own: there it throws \"parameter 1 is not of type\n * 'Event'\" in the middle of whatever fired it.\n *\n * @param {EventTarget & Node} target an element\n * @param {string} type\n * @param {CustomEventInit} [init]\n */\nexport function fireEvent(target, type, init) {\n const view = target.ownerDocument.defaultView;\n target.dispatchEvent(new view.CustomEvent(type, init));\n}\n", "/**\n * ColorField \u2014 one colour: a swatch that opens the native picker, a hex text\n * box kept in step with it, and an optional row of preset swatches.\n *\n * const field = new ColorField({\n * value: 'rgb(31, 119, 180)', // shown as #1f77b4\n * presets: ['#1f77b4', '#ff7f0e', '#2ca02c'],\n * onChange: (hex, { commit }) => { ... },\n * });\n * host.appendChild(field.render());\n * field.getValue(); // '#1f77b4' | '' | null\n *\n * THE HEX BOX IS THE CONTROL. Picking in the swatch writes the box and fires\n * the box's own `input` (and, when the picker commits, `change`); a preset\n * does the same. So there is one path from any gesture to the value, and a\n * host listening on the box \u2014 `openForm` does, by its `name` \u2014 hears every\n * change whatever made it. Typing a valid hex moves the swatch; typing an\n * invalid one leaves the swatch on the last good colour and marks the field\n * `.twm-color-field--invalid`.\n *\n * VALUES. `getValue()` is the colour as lowercase `#rrggbb`, `''` when the box\n * is empty, and `null` when what is typed is not a hex colour (`#rgb` and\n * `#rrggbb` are). An `rgb()` / `rgba()` value handed IN \u2014 a default, a preset,\n * `setValue` \u2014 is converted to its hex equivalent first; alpha is dropped,\n * because the native picker has no alpha channel.\n *\n * `onChange(value, { commit })` runs on every edit with `commit: false` and on\n * the box's `change` (blur, Enter, a preset, the picker closing) with\n * `commit: true`.\n */\nimport { fireEvent } from '../utils/fire_event.js';\n\nconst HEX_RE = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i;\nconst RGB_RE = /^rgba?\\(\\s*([^)]*)\\)$/i;\n\n/** True for `#rgb` and `#rrggbb` (any case), and nothing else. */\nexport function isHexColor(value) {\n return typeof value === 'string' && HEX_RE.test(value.trim());\n}\n\n/**\n * A colour as lowercase `#rrggbb`, or null when `value` is not one.\n * Accepts `#rgb`, `#rrggbb` and `rgb()` / `rgba()` in comma or space syntax,\n * with channels as 0\u2013255 or percentages; an alpha channel is dropped.\n */\nexport function normalizeHex(value) {\n if (typeof value !== 'string') return null;\n const s = value.trim();\n if (HEX_RE.test(s)) {\n const h = s.slice(1).toLowerCase();\n return h.length === 3 ? `#${h[0]}${h[0]}${h[1]}${h[1]}${h[2]}${h[2]}` : `#${h}`;\n }\n const m = RGB_RE.exec(s);\n if (!m) return null;\n const parts = m[1].split(/\\s*[,/]\\s*|\\s+/).filter(Boolean);\n if (parts.length < 3 || parts.length > 4) return null;\n const channels = [];\n for (const p of parts.slice(0, 3)) {\n const pct = p.endsWith('%');\n const n = Number(pct ? p.slice(0, -1) : p);\n if (!Number.isFinite(n)) return null;\n const v = pct ? (n / 100) * 255 : n;\n if (v < 0 || v > 255) return null;\n channels.push(Math.round(v));\n }\n return `#${channels.map((c) => c.toString(16).padStart(2, '0')).join('')}`;\n}\n\n/** What the box shows for a value handed in: its hex if it is a colour, else as given. */\nfunction displayText(value) {\n if (value == null) return '';\n return normalizeHex(String(value)) ?? String(value);\n}\n\nexport class ColorField {\n /**\n * @param {Object} [o]\n * @param {string} [o.value] initial colour (hex or rgb()); '' for none\n * @param {string[]} [o.presets] preset colours drawn as buttons; ones that\n * are not colours are left out\n * @param {string} [o.name] `name` of the hex box, for a host form\n * @param {string} [o.label] accessible name of the swatch and the box\n * @param {Function} [o.onChange] `(value, { commit })`, value as `getValue()`\n */\n constructor({ value = '', presets = [], name = null, label = null, onChange = null } = {}) {\n this.initial = displayText(value);\n this.presets = (Array.isArray(presets) ? presets : []).map(normalizeHex).filter(Boolean);\n this.name = name;\n this.label = label;\n this.onChange = typeof onChange === 'function' ? onChange : null;\n\n this.root = null;\n this.swatch = null;\n this.hex = null;\n this._disposers = [];\n }\n\n render() {\n if (this.root) return this.root;\n const root = document.createElement('div');\n root.className = 'twm-color-field';\n\n const swatch = document.createElement('input');\n swatch.type = 'color';\n swatch.className = 'twm-color-field__swatch';\n swatch.value = normalizeHex(this.initial) ?? '#000000';\n if (this.label) swatch.title = this.label;\n\n const hex = document.createElement('input');\n hex.type = 'text';\n hex.className = 'twm-color-field__hex';\n hex.value = this.initial;\n hex.placeholder = '#rrggbb';\n hex.spellcheck = false;\n hex.autocomplete = 'off';\n hex.maxLength = 7;\n if (this.name) hex.name = this.name;\n if (this.label) hex.setAttribute('aria-label', this.label);\n\n root.append(swatch, hex);\n this.root = root;\n this.swatch = swatch;\n this.hex = hex;\n\n if (this.presets.length) {\n const strip = document.createElement('div');\n strip.className = 'twm-color-field__presets';\n for (const color of this.presets) {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = 'twm-color-field__preset';\n btn.style.backgroundColor = color;\n btn.title = color;\n btn.setAttribute('aria-label', color);\n this.#listen(btn, 'click', () => this.#writeBox(color, true));\n strip.appendChild(btn);\n }\n root.appendChild(strip);\n }\n\n // Every gesture lands on the box; the box's listeners do the rest.\n this.#listen(swatch, 'input', () => this.#writeBox(swatch.value, false));\n this.#listen(swatch, 'change', () => this.#writeBox(swatch.value, true));\n this.#listen(hex, 'input', () => this.#sync(false));\n this.#listen(hex, 'change', () => {\n const v = this.getValue();\n if (v) hex.value = v; // canonical form once committed\n this.#sync(true);\n });\n\n this.#sync(null);\n return root;\n }\n\n /** `#rrggbb`, `''` when empty, or `null` when the box holds no hex colour. */\n getValue() {\n const text = this.getText().trim();\n if (text === '') return '';\n return isHexColor(text) ? normalizeHex(text) : null;\n }\n\n /** The box as it stands. */\n getText() {\n return this.hex ? this.hex.value : this.initial;\n }\n\n isValid() {\n return this.getValue() !== null;\n }\n\n /** Write a colour (hex or rgb()) without firing `onChange`. */\n setValue(value) {\n const text = displayText(value);\n if (!this.hex) { this.initial = text; return; }\n this.hex.value = text;\n this.#sync(null);\n }\n\n focus() {\n this.hex?.focus();\n }\n\n dispose() {\n for (const d of this._disposers) {\n try { d(); } catch { /* listener already gone */ }\n }\n this._disposers = [];\n this.root = null;\n this.swatch = null;\n this.hex = null;\n }\n\n #listen(el, type, fn) {\n el.addEventListener(type, fn);\n this._disposers.push(() => el.removeEventListener(type, fn));\n }\n\n /** Put `text` in the box and fire the box's own events, as typing would. */\n #writeBox(text, commit) {\n this.hex.value = text;\n fireEvent(this.hex, 'input', { bubbles: true });\n if (commit) fireEvent(this.hex, 'change', { bubbles: true });\n }\n\n /** Swatch and invalid mark follow the box; `commit === null` is silent. */\n #sync(commit) {\n const v = this.getValue();\n if (v) this.swatch.value = v;\n this.root.classList.toggle('twm-color-field--invalid', v === null);\n if (commit !== null) this.onChange?.(v, { commit });\n }\n}\n", "/**\n * THE ROWS `createSelect`, `createCombobox` AND `createTagInput`'s SUGGESTIONS\n * DRAW: a `role=\"listbox\"` of options, each with a glyph, a label, a second line,\n * a hint at the end of the row and, when disabled, its reason; `{ group, options }`\n * sections under a heading; one active row that the arrow keys walk.\n *\n * Focus never comes here. The text box or trigger that holds it names the active\n * row with `aria-activedescendant` (`onActive`), and a press on a row is\n * prevented from taking focus, so that a list row can be chosen with the box\n * still holding the caret, and no blur closes the list under the pointer.\n *\n * `aria-selected` says which row IS the current value; the active row is a class.\n * They are different things in a select, where the highlight walks away from the\n * value and comes back. Every word is built with `textContent`: these lists carry\n * text users wrote.\n *\n * An internal part: not exported from `@flexdesk/widgets`.\n */\n\nlet SEQ = 0;\n\nfunction node(tag, className, text) {\n const n = document.createElement(tag);\n if (className) n.className = className;\n if (text !== undefined && text !== null) n.textContent = String(text);\n return n;\n}\n\n/** `text` with the first run of `needle` in a `<mark>`, so it is plain why a row is offered. */\nfunction marked(target, text, needle) {\n const at = needle ? text.toLowerCase().indexOf(needle.toLowerCase()) : -1;\n if (at < 0) { target.textContent = text; return; }\n target.append(text.slice(0, at), node('mark', 'twm-option-list__match', text.slice(at, at + needle.length)),\n text.slice(at + needle.length));\n}\n\n/**\n * @param {object} o\n * @param {(option: object) => void} o.onPick A row was clicked. Never a disabled one.\n * @param {(id: string|null) => void} [o.onActive] The active row's id changed.\n */\nexport function createOptionList({ onPick, onActive = null }) {\n const id = `twm-option-list-${++SEQ}`;\n const el = node('div', 'twm-option-list');\n el.id = id;\n el.setAttribute('role', 'listbox');\n\n /** Every row drawn: `{ option, row }`. */\n let rows = [];\n let active = -1;\n\n const paintActive = () => {\n rows.forEach(({ row }, i) => row.classList.toggle('twm-option-list__row--active', i === active));\n const row = rows[active]?.row;\n // jsdom does not implement it, and a test harness is no reason to drop it.\n row?.scrollIntoView?.({ block: 'nearest' });\n onActive?.(row ? row.id : null);\n };\n\n const rowFor = (option, { glyphs, mark, isCurrent }) => {\n const row = node('div', 'twm-option-list__row');\n row.id = `${id}-${rows.length}`;\n row.setAttribute('role', 'option');\n row.setAttribute('aria-selected', String(!!isCurrent?.(option)));\n if (option.disabled) row.setAttribute('aria-disabled', 'true');\n row.title = option.description ? `${option.label} \u2014 ${option.description}` : option.label;\n if (glyphs) {\n const glyph = node('span', 'twm-option-list__glyph material-symbols-outlined', option.icon || '');\n glyph.setAttribute('aria-hidden', 'true');\n row.appendChild(glyph);\n }\n const words = node('span', 'twm-option-list__words');\n const label = node('span', 'twm-option-list__label');\n marked(label, option.label, mark);\n words.appendChild(label);\n if (option.description) words.appendChild(node('span', 'twm-option-list__description', option.description));\n if (option.disabled && option.reason) words.appendChild(node('span', 'twm-choice__reason', option.reason));\n row.appendChild(words);\n if (option.hint) row.appendChild(node('span', 'twm-option-list__hint', option.hint));\n return row;\n };\n\n const enabled = () => rows.map((r, i) => (r.option.disabled ? -1 : i)).filter((i) => i >= 0);\n\n // A press on the list leaves focus where it is. See the header.\n el.addEventListener('mousedown', (ev) => ev.preventDefault());\n el.addEventListener('click', (ev) => {\n const row = ev.target.closest?.('[role=\"option\"]');\n const hit = rows.find((r) => r.row === row);\n if (hit && !hit.option.disabled) onPick(hit.option);\n });\n\n return {\n el,\n id,\n /**\n * Draw `sections` (`[{ heading, items }]`, as `choiceSections` gives them).\n * @param {object} [opts]\n * @param {string} [opts.mark] The text to mark in each label.\n * @param {(option: object) => boolean} [opts.isCurrent] Is this the current value?\n */\n setRows(sections, { mark = '', isCurrent = null } = {}) {\n rows = [];\n active = -1;\n el.replaceChildren();\n const glyphs = sections.some((s) => s.items.some((o) => o.icon));\n for (const { heading, items } of sections) {\n let parent = el;\n if (heading != null) {\n parent = node('div', 'twm-option-list__section');\n parent.setAttribute('role', 'group');\n parent.setAttribute('aria-label', heading);\n const title = node('div', 'twm-choice__group', heading);\n title.setAttribute('aria-hidden', 'true');\n parent.appendChild(title);\n el.appendChild(parent);\n }\n for (const option of items) {\n const row = rowFor(option, { glyphs, mark, isCurrent });\n rows.push({ option, row });\n parent.appendChild(row);\n }\n }\n paintActive();\n },\n /** One line of text in place of the rows: nothing matched, still loading, a failure. */\n setMessage(text) {\n rows = [];\n active = -1;\n el.replaceChildren(node('div', 'twm-option-list__message', text));\n paintActive();\n },\n /** How many rows are drawn. */\n get size() { return rows.length; },\n /** The drawn options, in order. */\n options: () => rows.map((r) => r.option),\n /** The active row's option, or null. */\n activeOption: () => rows[active]?.option ?? null,\n /** Make row `index` active; -1, or a row that is disabled, makes none active. */\n setActive(index) {\n active = rows[index] && !rows[index].option.disabled ? index : -1;\n paintActive();\n },\n /** The next row that may be chosen, by `step`, wrapping. From none: the first or the last. */\n move(step) {\n const stops = enabled();\n if (!stops.length) return;\n const at = stops.indexOf(active);\n const next = at < 0 ? (step > 0 ? 0 : stops.length - 1) : (at + step + stops.length) % stops.length;\n active = stops[next];\n paintActive();\n },\n /** The first (`step` 1) or last (`step` -1) row that may be chosen. */\n moveToEnd(step) {\n const stops = enabled();\n active = stops.length ? stops[step > 0 ? 0 : stops.length - 1] : -1;\n paintActive();\n },\n };\n}\n", "/**\n * createCombobox \u2014 A TEXT BOX THAT ALSO OFFERS A LIST. (0.18.0)\n *\n * `createSelect` picks from a list; a bare `<input>` has nothing to pick from. A\n * value that may be anything but usually is one of a few known ones (a code, a\n * unit, a name) needs both at once.\n *\n * THE BOX HOLDS THE VALUE. The text in the input is what the caller gets back. An\n * option's `label` is what the LIST shows for it, and choosing a row puts the row's\n * `value` in the box. A field whose value is an opaque id with a separate name is\n * `createSelect`'s job: free text into an id is not a feature.\n *\n * THE TYPED TEXT IS REPORTED ON EVERY KEYSTROKE. In a dialog, \"type a value, click\n * Save\" is the normal gesture, and a control that only reports on blur is one click\n * from saving the previous value. `normalise` is therefore applied to what is\n * reported every time but rewrites the BOX only when the text is settled (on a pick,\n * Enter, Tab or blur), because rewriting an input's value moves the caret. Once, at\n * construction, a value `normalise` changed is reported as well: otherwise the box\n * shows one thing and the caller's model holds another.\n *\n * WHICH ROW ENTER TAKES. `autoHighlight` makes the first surviving row active so\n * Enter completes what was typed, and the list searches the label, the description\n * and `keywords` too. Together those have a wrong answer in them: a well-formed code\n * typed in full can be a substring of another row's description, and Enter would\n * take that row. Whether the typed text is ITSELF a well-formed value separates the\n * two cases, and only the caller knows that shape: `isCandidate`.\n *\n * ESCAPE AND ENTER ARE SWALLOWED WHILE THE LIST IS OPEN, and only then, so they\n * close the list and not the dialog around it. Closed, both bubble untouched.\n *\n * `validate` WARNS, it does not refuse: what is wrong with the settled value is said\n * under the box and the value is still reported.\n */\nimport { openAnchoredLayer } from './anchored_layer.js';\nimport { fireEvent } from '../utils/fire_event.js';\nimport { choiceSections, filterSections, shownValue } from './choice_controls.js';\nimport { createOptionList } from './option_list.js';\n\n/** Ms between a keystroke and asking a function of options, by default. */\nconst DEBOUNCE_MS = 150;\n\nlet SEQ = 0;\n\n/**\n * The list under a text box of your own, and everything that makes it behave: the\n * panel, the filter, async answers, the keys, `aria-*` on the box. `createCombobox`\n * and `createTagInput`'s suggestions are this.\n *\n * `options` is an array (filtered here) or `(query, { signal }) => array | Promise`,\n * which does its own filtering: it is asked after `debounce` ms; an answer that is\n * no longer the latest is dropped, and `signal` aborts when a newer one is asked for.\n *\n * Attach it BEFORE your own `keydown` listeners on the box: with a row active,\n * Enter is taken here and yours do not see it.\n *\n * @param {HTMLInputElement} input\n * @param {object} o\n * @param {Array|Function} o.options\n * @param {(option: object) => void} o.onPick A row was chosen (normalised; the entry\n * as you gave it is `option.source`).\n * @param {HTMLElement} [o.anchor] What the list hangs from; else the box.\n * @param {(option: object) => boolean} [o.isCurrent] Is this row the current value?\n * @param {boolean} [o.autoHighlight] Make a row active as the reader types.\n * @param {(typed: string) => boolean} [o.isCandidate] See the file's header.\n * @param {(text: string) => string} [o.normalise] What a typed text and a row's value are compared as.\n * @param {boolean} [o.openOnFocus] Focus opens the list.\n * @param {boolean} [o.passEnter] Enter with no row active closes the list and is left to\n * your listeners; by default it is swallowed.\n * @param {string} [o.loadingText] While a function of options is answering, with no rows to show.\n * @param {string} [o.errorText] When it failed.\n * @param {number} [o.debounce]\n * @param {string} [o.panelClassName]\n * @param {() => void} [o.onSettle] Enter with no row active, or Tab: the text stays as typed.\n * @returns {{isOpen: boolean, open: Function, close: Function, takeActive: () => boolean,\n * setOptions: Function, destroy: Function}}\n * `takeActive` chooses the active row and says whether there was one, for a key of\n * your own that also means \"this one\" (the tag input's comma).\n */\nexport function attachInputOptions(input, {\n options = [], onPick, anchor = null, isCurrent = null, autoHighlight = false, isCandidate = null,\n normalise = (text) => text, openOnFocus = false, passEnter = false, loadingText = 'Loading\u2026',\n errorText = 'Could not load the options.', debounce = DEBOUNCE_MS, panelClassName = '', onSettle = null,\n} = {}) {\n let source = options;\n let layer = null;\n /** The reader wants the list open; a late answer must not open what they closed. */\n let wanted = false;\n /** `null`: opened without typing, which shows everything. A string filters. */\n let query = null;\n let asked = 0;\n let timer = null;\n let controller = null;\n /** A pick is settling: its `input.focus()` is not a reader asking for the list. */\n let picking = false;\n\n const list = createOptionList({\n onPick: (option) => take(option),\n onActive: (id) => {\n if (id) input.setAttribute('aria-activedescendant', id);\n else input.removeAttribute('aria-activedescendant');\n },\n });\n const panel = document.createElement('div');\n panel.className = `twm-option-panel${panelClassName ? ` ${panelClassName}` : ''}`;\n panel.appendChild(list.el);\n\n // Not the browser's own autofill list on top of ours.\n input.setAttribute('autocomplete', 'off');\n input.setAttribute('role', 'combobox');\n input.setAttribute('aria-autocomplete', 'list');\n input.setAttribute('aria-expanded', 'false');\n input.setAttribute('aria-controls', list.id);\n\n const show = () => {\n if (layer) { layer.place(); return; }\n layer = openAnchoredLayer({\n anchor: anchor || input, el: panel, gap: 4, matchWidth: true, returnFocus: false,\n onClose() {\n layer = null;\n wanted = false;\n input.setAttribute('aria-expanded', 'false');\n input.removeAttribute('aria-activedescendant');\n },\n });\n // The box is not on the page: there is no list, and nothing to come back to.\n if (!layer) { wanted = false; return; }\n input.setAttribute('aria-expanded', 'true');\n };\n\n /** Whatever is being asked is no longer wanted. */\n function forget() {\n clearTimeout(timer);\n asked += 1;\n controller?.abort();\n controller = null;\n }\n\n function close(reason = 'closed') {\n wanted = false;\n forget();\n layer?.close(reason);\n }\n\n /** Which row Enter would take, when `autoHighlight` is on. See the file's header. */\n function highlight(typed) {\n const text = normalise(typed.trim());\n if (!autoHighlight || !text) { list.setActive(-1); return; }\n const exact = list.options().findIndex((o) => normalise(shownValue(o.value)) === text);\n if (exact >= 0) list.setActive(exact);\n else if (isCandidate?.(text)) list.setActive(-1);\n else list.moveToEnd(1);\n }\n\n function drawRows(sections) {\n if (!wanted) return;\n // NOTHING TO SUGGEST, NOTHING TO SHOW. An empty panel under the box reads as a\n // broken control; an unlisted value is fine. Still wanted: the next answer may have rows.\n if (!sections.length) {\n layer?.close('empty');\n wanted = true;\n return;\n }\n const text = query ?? '';\n list.setRows(sections, { mark: normalise(text.trim()), isCurrent });\n show();\n highlight(text);\n }\n\n function ask(text) {\n controller = new AbortController();\n const token = asked;\n const failed = (err) => {\n if (token !== asked) return;\n console.warn('[createCombobox] options failed', err);\n if (!wanted) return;\n list.setMessage(errorText);\n show();\n };\n let answer;\n try { answer = source(text, { signal: controller.signal }); }\n catch (err) { failed(err); return; }\n if (typeof answer?.then !== 'function') { drawRows(choiceSections(answer)); return; }\n // Rows already drawn stay until the answer, so the list does not flicker per keystroke.\n if (!list.size && wanted) { list.setMessage(loadingText); show(); }\n answer.then((rows) => { if (token === asked) drawRows(choiceSections(rows)); }, failed);\n }\n\n /** The list, for the current query. */\n function refresh() {\n forget();\n if (typeof source !== 'function') {\n const all = choiceSections(source);\n drawRows(query === null ? all : filterSections(all, query));\n return;\n }\n const text = query ?? '';\n if (query === null || debounce <= 0) { ask(text); return; }\n const token = asked;\n timer = setTimeout(() => { if (token === asked) ask(text); }, debounce);\n }\n\n function take(option) {\n close('pick');\n picking = true;\n onPick?.(option);\n picking = false;\n }\n\n /** The active row is chosen, if the list is open and has one. */\n function takeActive() {\n const option = layer && list.activeOption();\n if (!option) return false;\n take(option);\n return true;\n }\n\n const openFor = (text) => { query = text; wanted = true; refresh(); };\n\n const onInput = () => openFor(input.value);\n const onClick = () => openFor(null);\n const onFocus = () => { if (openOnFocus && !layer && !picking) openFor(input.value || null); };\n const onBlur = () => close('blur');\n const onKey = (ev) => {\n if (ev.isComposing) return;\n if (ev.key === 'ArrowDown' || ev.key === 'ArrowUp') {\n ev.preventDefault();\n ev.stopPropagation();\n if (!layer) openFor(null);\n list.move(ev.key === 'ArrowDown' ? 1 : -1);\n return;\n }\n if (ev.key === 'Enter') {\n if (!layer) return; // the dialog's Enter, untouched\n if (takeActive()) {\n ev.preventDefault();\n ev.stopImmediatePropagation();\n return;\n }\n close();\n if (passEnter) return;\n ev.preventDefault();\n ev.stopPropagation();\n onSettle?.();\n return;\n }\n if (ev.key === 'Tab') {\n close('blur');\n onSettle?.();\n }\n };\n\n input.addEventListener('input', onInput);\n input.addEventListener('click', onClick);\n input.addEventListener('focus', onFocus);\n input.addEventListener('blur', onBlur);\n input.addEventListener('keydown', onKey);\n\n return {\n get isOpen() { return !!layer; },\n /** Open it showing everything, or for `text`. */\n open(text = null) { openFor(text); },\n close,\n takeActive,\n /** Replace the options; an open list redraws. */\n setOptions(next) {\n source = next;\n if (wanted) refresh();\n },\n destroy() {\n close();\n input.removeEventListener('input', onInput);\n input.removeEventListener('click', onClick);\n input.removeEventListener('focus', onFocus);\n input.removeEventListener('blur', onBlur);\n input.removeEventListener('keydown', onKey);\n },\n };\n}\n\n/**\n * @param {object} config\n * @param {Array|Function} [config.options] What `createSelect` takes: the list is a\n * SUGGESTION, never a constraint. Or `(query, { signal }) => array | Promise` for\n * options found as the reader types: it filters them itself, and is asked with `''`\n * when the list opens without typing.\n * @param {string} [config.value]\n * @param {(value: string, option: object|null) => void} [config.onChange] On every\n * keystroke and pick, and once at construction when `normalise` changed the value it\n * was handed. `option` is the entry as you gave it when one was picked, else `null`.\n * @param {string} [config.className] Extra classes on the root.\n * @param {string} [config.panelClassName]\n * @param {string} [config.placeholder]\n * @param {string} [config.title] The input's tooltip.\n * @param {string} [config.ariaLabel] When no `<label>` names the control.\n * @param {string} [config.name] The input's name.\n * @param {boolean} [config.disabled]\n * @param {(text: string) => string} [config.normalise] Upper-casing a code, say.\n * @param {boolean} [config.autoHighlight=true] See the file's header.\n * @param {(typed: string) => boolean} [config.isCandidate] See the file's header.\n * @param {(value: string) => string|null} [config.validate] What is wrong with the settled value.\n * @param {string} [config.loadingText]\n * @param {string} [config.errorText]\n * @param {number} [config.debounce=150] Ms before a function of options is asked.\n * @returns {{el: HTMLElement, input: HTMLInputElement, value: string, error: string|null,\n * isOpen: boolean, setOptions: Function, open: Function, close: Function,\n * focus: Function, destroy: Function}}\n */\nexport function createCombobox({\n options = [], value = '', onChange = null, className = '', panelClassName = '', placeholder = '', title = '',\n ariaLabel = '', name = null, disabled = false, normalise = (text) => text, autoHighlight = true, isCandidate = null,\n validate = null, loadingText, errorText, debounce,\n} = {}) {\n const handed = String(value ?? '');\n let current = normalise(handed);\n\n const el = document.createElement('div');\n el.className = `twm-combobox${className ? ` ${className}` : ''}`;\n\n const input = document.createElement('input');\n input.type = 'text';\n input.className = 'twm-combobox__input';\n input.spellcheck = false;\n input.value = current;\n input.disabled = !!disabled;\n if (name) input.name = name;\n if (placeholder) input.placeholder = placeholder;\n if (title) input.title = title;\n if (ariaLabel) input.setAttribute('aria-label', ariaLabel);\n\n const error = document.createElement('p');\n error.className = 'twm-combobox__error';\n error.hidden = true;\n error.id = `twm-combobox-error-${++SEQ}`;\n el.append(input, error);\n\n function report(next, option) {\n const settled = normalise(String(next ?? ''));\n if (settled === current) return;\n current = settled;\n onChange?.(current, option ?? null);\n }\n\n const clearValidity = () => {\n error.hidden = true;\n error.textContent = '';\n input.removeAttribute('aria-invalid');\n input.removeAttribute('aria-describedby');\n };\n\n /** The complaint appears when the text is settled: \"too short\" is noise mid-word. */\n function paintValidity() {\n const message = validate && current ? (validate(current) || null) : null;\n if (!message) { clearValidity(); return; }\n error.textContent = message;\n error.hidden = false;\n input.setAttribute('aria-invalid', 'true');\n input.setAttribute('aria-describedby', error.id);\n }\n\n /** Put the canonical text in the box. Only when it is settled: see the file's header. */\n function settle() {\n report(input.value, null);\n if (input.value !== current) input.value = current;\n paintValidity();\n }\n\n // Before the list's own listener: it marks the current value in the rows it draws.\n input.addEventListener('input', () => {\n // EVERY KEYSTROKE REACHES THE CALLER. See the file's header.\n report(input.value, null);\n clearValidity();\n });\n\n const menu = attachInputOptions(input, {\n options,\n autoHighlight,\n isCandidate,\n normalise,\n panelClassName,\n loadingText,\n errorText,\n debounce,\n isCurrent: (o) => normalise(shownValue(o.value)) === current,\n onSettle: settle,\n onPick(option) {\n input.value = shownValue(option.value);\n report(option.value, option.source);\n settle();\n input.focus();\n // A value set by script fires nothing; a surrounding form listens for this.\n fireEvent(input, 'change', { bubbles: true });\n },\n });\n\n input.addEventListener('blur', settle);\n\n paintValidity();\n if (onChange && current !== handed) onChange(current, null);\n\n return {\n el,\n input,\n get value() { return current; },\n set value(next) {\n current = normalise(String(next ?? ''));\n input.value = current;\n paintValidity();\n },\n /** The complaint on screen, or `null`. A caller that wants to refuse Save has this. */\n get error() { return error.hidden ? null : error.textContent; },\n get isOpen() { return menu.isOpen; },\n setOptions: menu.setOptions,\n /** Open the list showing everything, or for `text`. */\n open: menu.open,\n close: () => menu.close(),\n focus() { input.focus(); },\n destroy() {\n menu.destroy();\n el.remove();\n },\n };\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["row", "SEQ"]
7
+ }
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-N7HC3ADV.js";
5
5
  import {
6
6
  DragReorder
7
- } from "./chunk-WUFLGETN.js";
7
+ } from "./chunk-WVFGV5FT.js";
8
8
 
9
9
  // src/ui/components/tabs.js
10
10
  var TAB_LEVELS = Object.freeze(["info", "warning", "alert"]);
@@ -372,4 +372,4 @@ export {
372
372
  TAB_LEVELS,
373
373
  createTabs
374
374
  };
375
- //# sourceMappingURL=chunk-REJ5HLIM.js.map
375
+ //# sourceMappingURL=chunk-HYJYYEPK.js.map
@@ -3,11 +3,13 @@ import {
3
3
  wheelStripSideways
4
4
  } from "./chunk-N7HC3ADV.js";
5
5
  import {
6
- DragReorder,
6
+ DragReorder
7
+ } from "./chunk-WVFGV5FT.js";
8
+ import {
7
9
  focusMenuItem,
8
10
  moveMenuFocus,
9
11
  placeMenuInViewport
10
- } from "./chunk-WUFLGETN.js";
12
+ } from "./chunk-QXAOTGCC.js";
11
13
 
12
14
  // src/editor/notebook_tab_bar.js
13
15
  var DEFAULT_TAB_DRAG_MIME = "application/x-flexdesk-tab";
@@ -474,4 +476,4 @@ export {
474
476
  getTabDragMime,
475
477
  NotebookTabBar
476
478
  };
477
- //# sourceMappingURL=chunk-7U4IB65H.js.map
479
+ //# sourceMappingURL=chunk-LLBJ2SJH.js.map