flexdesk 0.4.7 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +1036 -301
  2. package/css/base.css +2958 -2
  3. package/css/flexdesk.css +2962 -4
  4. package/css/overrides.css +4 -2
  5. package/css/tokens.css +86 -0
  6. package/dist/canvas.js +390 -0
  7. package/dist/canvas.js.map +7 -0
  8. package/dist/charts.js +782 -782
  9. package/dist/{chunk-LH5TSOZW.js → chunk-6JSOVNID.js} +42 -2
  10. package/dist/{chunk-LH5TSOZW.js.map → chunk-6JSOVNID.js.map} +3 -3
  11. package/dist/{chunk-ELXVW542.js → chunk-6NG7YVBG.js} +3 -471
  12. package/dist/chunk-6NG7YVBG.js.map +7 -0
  13. package/dist/{chunk-F5FYDCOA.js → chunk-CNXP3SIN.js} +2373 -2373
  14. package/dist/{chunk-F5FYDCOA.js.map → chunk-CNXP3SIN.js.map} +7 -7
  15. package/dist/chunk-H4LT43RS.js +475 -0
  16. package/dist/chunk-H4LT43RS.js.map +7 -0
  17. package/dist/{chunk-WMGOJ3I6.js → chunk-KH2GJTKR.js} +3702 -2628
  18. package/dist/chunk-KH2GJTKR.js.map +7 -0
  19. package/dist/chunk-SN4LSOAR.js +532 -0
  20. package/dist/chunk-SN4LSOAR.js.map +7 -0
  21. package/dist/flexdesk.css +2962 -4
  22. package/dist/flow.js +10030 -0
  23. package/dist/flow.js.map +7 -0
  24. package/dist/tiles.js +2195 -2195
  25. package/dist/tokens.css +86 -0
  26. package/dist/widgets.js +5824 -5796
  27. package/dist/widgets.js.map +1 -1
  28. package/dist/wm.js +8077 -8074
  29. package/dist/wm.js.map +7 -7
  30. package/package.json +89 -81
  31. package/src/canvas/canvas_adapter.js +523 -0
  32. package/src/canvas/edge_router.js +392 -0
  33. package/src/canvas/graph/connector_router.js +189 -0
  34. package/src/canvas/graph/history_service.js +170 -0
  35. package/src/canvas/graph/node_platform.js +116 -0
  36. package/src/canvas/index.js +16 -0
  37. package/src/flow/canvas_editor/editor.js +1081 -0
  38. package/src/flow/canvas_editor/index.js +16 -0
  39. package/src/flow/canvas_editor/layout.js +118 -0
  40. package/src/flow/canvas_editor/strings.js +37 -0
  41. package/src/flow/kit/always_before.js +325 -0
  42. package/src/flow/kit/catalogue.js +170 -0
  43. package/src/flow/kit/chip_input.js +461 -0
  44. package/src/flow/kit/dom.js +205 -0
  45. package/src/flow/kit/findings.js +129 -0
  46. package/src/flow/kit/history.js +173 -0
  47. package/src/flow/kit/index.js +38 -0
  48. package/src/flow/kit/keys.js +127 -0
  49. package/src/flow/kit/logic_graph.js +210 -0
  50. package/src/flow/kit/references.js +199 -0
  51. package/src/flow/kit/settings_panel.js +357 -0
  52. package/src/flow/kit/settings_schema.js +175 -0
  53. package/src/flow/kit/step_picker.js +209 -0
  54. package/src/flow/kit/strings.js +102 -0
  55. package/src/flow/kit/value_picker.js +238 -0
  56. package/src/flow/kit/widgets.js +763 -0
  57. package/src/flow/lanes/editor.js +1469 -0
  58. package/src/flow/lanes/index.js +26 -0
  59. package/src/flow/lanes/layout.js +525 -0
  60. package/src/flow/lanes/pipeline.js +327 -0
  61. package/src/flow/lanes/preview.js +109 -0
  62. package/src/flow/lanes/strings.js +98 -0
  63. package/src/flow/outline/editor.js +1511 -0
  64. package/src/flow/outline/index.js +20 -0
  65. package/src/flow/outline/mapping.js +286 -0
  66. package/src/flow/outline/menu.js +154 -0
  67. package/src/flow/outline/operations.js +738 -0
  68. package/src/flow/outline/recognise.js +755 -0
  69. package/src/flow/outline/strings.js +135 -0
  70. package/src/tiling/landing_table.js +13 -5
  71. package/src/tiling/wm.js +3916 -3916
  72. package/src/ui/components/data_table.js +4205 -3294
  73. package/src/ui/components/row_activation.js +70 -0
  74. package/src/ui/components/table_values.js +423 -0
  75. package/dist/chunk-ELXVW542.js.map +0 -7
  76. package/dist/chunk-WMGOJ3I6.js.map +0 -7
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/canvas/canvas_adapter.js", "../src/canvas/edge_router.js"],
4
+ "sourcesContent": ["/**\n * The canvas kernel \u2014 BASE LAYER (36 \u00A74.2).\n *\n * Pan, zoom, rubber-band selection, grid snap, viewport events and\n * `clientToCanvas`. Nothing here knows what a node IS: a schema diagram, a\n * flow editor and a forms designer can all stand on it, and a forms designer\n * would use ONLY this layer, with no ports and no edges. That is the test of\n * whether the split is real.\n *\n * Moved into FlexDesk with its behaviour intact; only the class names changed\n * (`twm-canvas`, `twm-canvas__surface`, `__edges`, `__nodes`, `__marquee`), and\n * the one question it asks about the embedder's elements \u2014 \"is this press on a\n * node?\" \u2014 no longer names the embedder's class: a node is anything the\n * embedder put in `nodeLayer` (or what `nodeSelector` names, when given).\n *\n * KNOWN GAP, recorded rather than discovered in an accessibility review:\n * everything here is `mousedown`/`pointerdown` with button checks. There is no\n * touch support and no keyboard navigation of the graph; an editor on top of\n * it supplies its own (the canvas editor's nodes are focusable).\n */\n\nconst MIN_SCALE = 0.15;\nconst MAX_SCALE = 4;\n\n/** A brighter rule every N cells, so distance across the surface is readable\n * without counting identical lines. */\nconst COARSE_GRID_EVERY = 5;\n\n/**\n * Below this many screen pixels, `bringIntoView` does not move at all.\n *\n * A pan nobody can see is not a pan, and this method's contract is that it\n * moves only when it must \u2014 so half a pixel is on the \"must not\" side of it by\n * definition, not by rounding policy.\n *\n * It is also insurance on the one arithmetic that could break that contract:\n * the shift lands the near edge ON the padding, and `edge * scale + translate`\n * recomputed from the new translate need not come back exactly equal to it. An\n * ulp the wrong way would make the next identical request pan again \u2014 moving\n * the diagram by a ten-thousandth of a pixel and scheduling a layout save for\n * it. Excluded because excluding it costs one comparison.\n */\nconst SUB_PIXEL = 0.5;\n\nexport class CanvasAdapter {\n /**\n * @param {object} o\n * @param {HTMLElement} o.container the box the canvas fills (it needs a height)\n * @param {number} [o.gridSize] the snap grid, in canvas pixels; 0 = no snap\n * @param {(viewport) => void} [o.onViewportChange] after every pan and zoom \u2014 and once,\n * synchronously, from this constructor\n * @param {(event: MouseEvent) => void} [o.onBackgroundMenu] a right-CLICK on the empty surface\n * @param {string|null} [o.nodeSelector] what a node is, when it is not simply \"an element of\n * `nodeLayer`\"; a press inside one is the embedder's, never a pan or a marquee\n */\n constructor({ container, gridSize = 16, onViewportChange, onBackgroundMenu, nodeSelector = null } = {}) {\n this.container = container;\n this.gridSize = gridSize;\n this.onViewportChange = onViewportChange;\n /**\n * A RIGHT-CLICK ON THE EMPTY SURFACE, handed on rather than swallowed.\n *\n * The listener below has always suppressed the browser's menu on the\n * background, and the argument for that is written where it happens:\n * the background is where this class claims the right button, so a\n * press there is a gesture and a gesture does not open a menu. What it\n * could not do was let the embedder put something in its place \u2014\n * `contextmenu` never left this class, so an embedder wanting a canvas\n * menu had to bind its own listener and then race this one for the\n * right-drag flag, which `consumeRightDrag` clears as it reads. Whoever\n * lost the race opened a menu at the end of a pan.\n *\n * So the decision stays here, where the flag is, and the CONTENT of the\n * menu goes to the embedder. Omitted, nothing changes: the event is\n * suppressed and no menu appears. The kernel still knows nothing about\n * what a node or a command is.\n */\n this.onBackgroundMenu = onBackgroundMenu;\n this.nodeSelector = nodeSelector;\n this.scale = 1;\n this.tx = 0;\n this.ty = 0;\n this.selection = new Set();\n\n this.root = document.createElement('div');\n this.root.className = 'twm-canvas';\n this.root.tabIndex = 0;\n\n this.surface = document.createElement('div');\n this.surface.className = 'twm-canvas__surface';\n\n this.edgeLayer = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n this.edgeLayer.setAttribute('class', 'twm-canvas__edges');\n this.edgeLayer.setAttribute('overflow', 'visible');\n\n this.nodeLayer = document.createElement('div');\n this.nodeLayer.className = 'twm-canvas__nodes';\n\n this.marquee = document.createElement('div');\n this.marquee.className = 'twm-canvas__marquee';\n this.marquee.hidden = true;\n\n this.surface.append(this.edgeLayer, this.nodeLayer);\n this.root.append(this.surface, this.marquee);\n container.appendChild(this.root);\n\n this._bind();\n this._apply();\n }\n\n // \u2500\u2500 coordinates \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** Client (screen) point -> canvas point. */\n clientToCanvas(clientX, clientY) {\n const box = this.root.getBoundingClientRect();\n return {\n x: (clientX - box.left - this.tx) / this.scale,\n y: (clientY - box.top - this.ty) / this.scale,\n };\n }\n\n canvasToClient(x, y) {\n const box = this.root.getBoundingClientRect();\n return {\n x: x * this.scale + this.tx + box.left,\n y: y * this.scale + this.ty + box.top,\n };\n }\n\n snap(value) {\n return this.gridSize ? Math.round(value / this.gridSize) * this.gridSize : value;\n }\n\n // \u2500\u2500 viewport \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n setViewport({ scale, tx, ty }) {\n if (scale !== undefined) this.scale = clamp(scale, MIN_SCALE, MAX_SCALE);\n if (tx !== undefined) this.tx = tx;\n if (ty !== undefined) this.ty = ty;\n this._apply();\n }\n\n viewport() {\n return { scale: this.scale, tx: this.tx, ty: this.ty };\n }\n\n /**\n * Did the right button just PAN rather than click \u2014 and clear the answer.\n *\n * Right-drag pans (see `_bind`), so the `contextmenu` that arrives when the\n * button comes back up is the tail of a gesture, not a request for a menu.\n * The kernel's own root listener has always known this. Nothing else could\n * ask, and everything else needs to: a `contextmenu` handler on a node or an\n * edge is on the TARGET, and target-phase listeners run before the root's,\n * so an embedder that opens a menu opens it at the end of every pan that\n * happens to finish over one of its elements.\n *\n * CONSUMING, not peeking, and that is the whole design. An embedder's\n * element handler will often call `stopPropagation()` \u2014 deliberately, so one\n * press never opens two menus \u2014 which means the root listener below may\n * never run to do the clearing. A plain getter would therefore leave the\n * flag `true` and suppress the NEXT right-click, turning one wrong menu into\n * a menu that has stopped working. Whoever reads it first clears it; nobody\n * sees it twice; there is no ordering left to get wrong.\n *\n * An embedder that consumes a `true` should still `preventDefault()` and\n * show nothing \u2014 suppressing the browser's menu is the root listener's job\n * and it has just been cut out of the loop.\n */\n consumeRightDrag() {\n const dragged = this._rightDragged;\n this._rightDragged = false;\n return dragged;\n }\n\n zoomAt(clientX, clientY, factor) {\n const before = this.clientToCanvas(clientX, clientY);\n this.scale = clamp(this.scale * factor, MIN_SCALE, MAX_SCALE);\n const after = this.clientToCanvas(clientX, clientY);\n // Keep the point under the cursor fixed: pan by the difference the zoom\n // introduced. Zooming to the centre instead makes a large graph\n // impossible to navigate.\n this.tx += (after.x - before.x) * this.scale;\n this.ty += (after.y - before.y) * this.scale;\n this._apply();\n }\n\n fit(bounds, { padding = 60 } = {}) {\n if (!bounds || bounds.width <= 0 || bounds.height <= 0) return;\n const box = this.root.getBoundingClientRect();\n const scale = clamp(\n Math.min((box.width - padding * 2) / bounds.width,\n (box.height - padding * 2) / bounds.height),\n MIN_SCALE, MAX_SCALE);\n this.scale = scale;\n this.tx = (box.width - bounds.width * scale) / 2 - bounds.x * scale;\n this.ty = (box.height - bounds.height * scale) / 2 - bounds.y * scale;\n this._apply();\n }\n\n /** What is on screen, in CANVAS coordinates. The inverse of the transform\n * `_apply` writes, and the only honest way for an embedder to ask \"is this\n * already visible\" without duplicating the arithmetic. */\n visibleBox() {\n const view = this.root.getBoundingClientRect();\n return {\n x: -this.tx / this.scale,\n y: -this.ty / this.scale,\n width: view.width / this.scale,\n height: view.height / this.scale,\n };\n }\n\n /** Is all of `box` (canvas coordinates) inside the viewport, with `padding`\n * screen pixels to spare on every side? */\n contains(box, { padding = 0 } = {}) {\n if (!box) return false;\n const view = this.root.getBoundingClientRect();\n // The same tolerance `bringIntoView` refuses to move for: a box it has\n // just brought in must not then be reported as still outside.\n return box.x * this.scale + this.tx >= padding - SUB_PIXEL\n && box.y * this.scale + this.ty >= padding - SUB_PIXEL\n && (box.x + box.width) * this.scale + this.tx <= view.width - padding + SUB_PIXEL\n && (box.y + box.height) * this.scale + this.ty <= view.height - padding + SUB_PIXEL;\n }\n\n /**\n * PAN \u2014 AND ONLY PAN \u2014 UNTIL `box` IS IN VIEW. `this.scale` is never read\n * for a decision and never written.\n *\n * `fit` is the other way to put something on screen and it is a DIFFERENT\n * gesture: it derives a scale from the box and applies it, up to the 4\u00D7\n * ceiling. So \"take me to this node\" arrived as a zoom in until one node\n * filled the pane, and \"take me to this line\" as whatever scale happened to\n * frame two boxes \u2014 in either direction. The reader's complaint was *\"do not\n * zoom in, just move viewport if required\"*, and it is two complaints, not\n * one:\n *\n * * THE SCALE IS THE USER'S. They set it by scrolling; nothing that is\n * merely navigation may overwrite it. Zooming OUT \"to help\" fit a wide\n * pair breaks the same rule as zooming in.\n * * ALREADY VISIBLE MEANS NOTHING HAPPENS. `fit` centres unconditionally,\n * so asking for a node you are already looking at slid the whole drawing\n * under the cursor. A pan that was not required is not a smaller version\n * of the right behaviour; it is the wrong one. Hence the first branch of\n * `_panShift`, and hence `_apply()` below is not called at all when both\n * deltas are zero \u2014 no transform is rewritten, no `onViewportChange`\n * fires, and so no layout save is scheduled.\n *\n * Otherwise the move is the MINIMUM that brings the box inside: the near\n * edge lands on the padding and the far edge is left wherever it falls.\n * Centring would travel further for no gain.\n *\n * \u2500\u2500 WHEN THE BOX IS BIGGER THAN THE WINDOW AT THIS SCALE \u2500\u2500\n *\n * It cannot be brought in, and zooming out is exactly what the rule\n * forbids, so `fallback` names a smaller box worth preferring \u2014 for a line,\n * the end nearest what is already on screen. Per axis and independently,\n * because two nodes side by side are usually too wide and perfectly fine\n * vertically. With no fallback (or one that is itself oversized) the rule is\n * \"fill the window with as much of it as possible\": if the window already\n * lies entirely within the box, nothing can be gained by moving and nothing\n * moves; otherwise the box is pulled across until the dead space on one\n * side is gone.\n *\n * @param {{x, y, width, height}} box \u2014 canvas coordinates.\n * @param {{padding?: number, fallback?: object}} [options]\n * @returns {{moved: boolean, contained: boolean}} `contained` reports\n * whether ALL of `box` ended up on screen, so a caller can say why\n * half of what it named is still not visible rather than leaving\n * the user to conclude the click failed.\n */\n bringIntoView(box, { padding = 40, fallback = null } = {}) {\n if (!box || box.width < 0 || box.height < 0) {\n return { moved: false, contained: false };\n }\n const view = this.root.getBoundingClientRect();\n const dx = ignoreSubPixel(\n this._panShift(box.x, box.width, view.width, this.tx, padding,\n fallback && { start: fallback.x, size: fallback.width }));\n const dy = ignoreSubPixel(\n this._panShift(box.y, box.height, view.height, this.ty, padding,\n fallback && { start: fallback.y, size: fallback.height }));\n const moved = dx !== 0 || dy !== 0;\n if (moved) {\n this.tx += dx;\n this.ty += dy;\n this._apply();\n }\n return { moved, contained: this.contains(box) };\n }\n\n /**\n * One axis of `bringIntoView`, in SCREEN pixels: how far the translate has\n * to move. Positive is right/down. Returns 0 for \"already in view\", which is\n * the branch the whole method exists for.\n */\n _panShift(start, size, viewportSize, translate, padding, fallback) {\n // A padding wider than half the window would put the two limits the\n // wrong way round and turn every case below into nonsense. A pane can be\n // that narrow while it is being dragged.\n const pad = Math.min(padding, Math.max(0, (viewportSize - 1) / 2));\n const low = pad;\n const high = viewportSize - pad;\n const near = start * this.scale + translate;\n const far = (start + size) * this.scale + translate;\n if (near >= low && far <= high) return 0; // nothing to do\n if (far - near <= high - low) { // it fits: minimum move\n return near < low ? low - near : high - far;\n }\n if (fallback) {\n return this._panShift(fallback.start, fallback.size, viewportSize,\n translate, padding, null);\n }\n if (near <= low && far >= high) return 0; // the window is full of it\n return near > low ? low - near : high - far;\n }\n\n _apply() {\n this.surface.style.transform =\n `translate(${this.tx}px, ${this.ty}px) scale(${this.scale})`;\n // SEVEN background layers, in the order `.twm-canvas` declares them:\n // grain, lighting, coarse grid \u00D72, fine grid \u00D72, ground. Only the four\n // GRID layers follow the pan and the zoom \u2014 the grain is a material and\n // the lighting belongs to the window, and zooming either makes the\n // surface swim under the content instead of sitting behind it.\n //\n // The list length MUST match the stylesheet. A short list makes the\n // browser cycle it, so layer 5 silently takes layer 1's size. An\n // embedder that restyles the ground keeps seven layers, in this order.\n const fine = this.gridSize * this.scale;\n const coarse = fine * COARSE_GRID_EVERY;\n this.root.style.backgroundSize = [\n '160px 160px', // grain \u2014 its own fixed scale\n 'auto', // lighting \u2014 fills the element\n `${coarse}px ${coarse}px`,\n `${coarse}px ${coarse}px`,\n `${fine}px ${fine}px`,\n `${fine}px ${fine}px`,\n 'auto', // the ground\n ].join(', ');\n const offset = `${this.tx}px ${this.ty}px`;\n this.root.style.backgroundPosition =\n ['0 0', '0 0', offset, offset, offset, offset, '0 0'].join(', ');\n this.onViewportChange?.(this.viewport());\n }\n\n /**\n * Is `target` inside one of the embedder's nodes? A node is whatever the\n * embedder put in the node layer \u2014 or, with `nodeSelector`, what that\n * selector names. A press there belongs to the embedder: it starts no pan\n * and no marquee, and its right-click keeps whatever menu the embedder (or,\n * failing that, the browser) gives it.\n */\n _onNode(target) {\n if (!target || typeof target.closest !== 'function') return false;\n if (this.nodeSelector) return Boolean(target.closest(this.nodeSelector));\n return target !== this.nodeLayer && this.nodeLayer.contains(target);\n }\n\n // \u2500\u2500 input \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n _bind() {\n this.root.addEventListener('wheel', (event) => {\n event.preventDefault();\n if (event.ctrlKey || event.metaKey) {\n this.zoomAt(event.clientX, event.clientY, event.deltaY < 0 ? 1.12 : 1 / 1.12);\n } else {\n this.tx -= event.deltaX;\n this.ty -= event.deltaY;\n this._apply();\n }\n }, { passive: false });\n\n // RIGHT-DRAG PANS, and the browser menu gets out of the way for it.\n //\n // Middle-drag is the canonical pan and most mice have the button; a\n // laptop trackpad does not, and Shift+drag is a chord you have to be\n // told about. Right-drag is what every map and every node editor does,\n // and it costs one `contextmenu` handler.\n //\n // \u2500\u2500 AND THE BACKGROUND EATS THE MENU WHETHER OR NOT IT MOVED \u2500\u2500\n //\n // \"Right-click on the canvas if nothing is behind should be blocked.\"\n // It was not: nothing on the empty surface calls `preventDefault`, so a\n // right-click there produced the BROWSER's menu \u2014 Back, Reload, Save as,\n // Inspect \u2014 over the drawing. Suppressing only after a drag made that\n // worse rather than better, because whether you got a browser menu at\n // the end of a pan then depended on having moved more than three pixels.\n //\n // THE RULE IS \"SUPPRESS EXACTLY WHERE THIS CLASS CLAIMS THE RIGHT\n // BUTTON\", and that is the same test `pointerdown` below already makes:\n // it bails out inside a node and pans everywhere else. So the background\n // is ours \u2014 right-press there is a gesture, and a gesture does not hand\n // the browser a menu \u2014 while a node is the embedder's, and one that has\n // no menu of its own KEEPS THE BROWSER'S. Taking a working menu away to\n // put nothing in its place is a loss, unless the press was already\n // spoken for.\n //\n // `rightDragged` still has to be consulted first. A pan that ends over a\n // node dispatches `contextmenu` with that node as the target on the\n // platforms that fire it on release, and the menu must not come back\n // just because the pointer finished somewhere else.\n //\n // Nothing is shown in the menu's place. An empty menu is worse than\n // none: it reads as a feature that has broken rather than as a surface\n // that has no commands.\n //\n // \u2500\u2500 AND THE GUARD HAS TO BE REACHABLE FROM AN ELEMENT HANDLER \u2500\u2500\n //\n // A `contextmenu` listener bound to a NODE or an EDGE is on the target,\n // and target-phase listeners run BEFORE the ones bubbling to the root.\n // So an embedder's menu is already on screen by the time root gets to\n // consult the flag \u2014 and if that handler calls `stopPropagation()` root\n // never runs AT ALL, which leaves the flag stuck `true` and poisons the\n // NEXT right-click as well. Hence instance state with a CONSUMING reader\n // (`consumeRightDrag`): whichever handler reaches it first gets the\n // answer, and no second handler can see a stale `true`.\n this._rightDragged = false;\n this.root.addEventListener('contextmenu', (event) => {\n const afterDrag = this.consumeRightDrag();\n if (!afterDrag && this._onNode(event.target)) return;\n event.preventDefault();\n event.stopPropagation();\n // ONLY A CLICK, NEVER THE TAIL OF A PAN \u2014 the same test the two\n // lines above make, read once.\n if (!afterDrag) this.onBackgroundMenu?.(event);\n });\n\n this.root.addEventListener('pointerdown', (event) => {\n // \u2500\u2500 THE RESET IS ABOVE THE NODE BAIL, AND THAT ORDER IS THE FIX \u2500\u2500\n //\n // A NEW PRESS MEANS THE LAST GESTURE IS OVER, wherever it landed.\n // Below the bail, a press inside a node would return before reaching\n // it \u2014 and once the flag is readable from a target handler, that\n // turns a dead bit into a swallowed menu. Two gestures reach it:\n //\n // THE MENU IS NOT ALWAYS OURS TO CONSUME. An embedder's toolbar\n // and side panels are siblings of the canvas, not descendants of\n // `root`. Right-press the background, drag, release over one:\n // `contextmenu` fires there, no listener of ours runs, and the\n // flag stays armed.\n //\n // AND ON WINDOWS/X11 `contextmenu` FIRES AT THE PRESS, not the\n // release. So the only menu event of a right-drag pan has already\n // been and gone \u2014 with the flag still false \u2014 by the time the drag\n // sets it. Every pan on those platforms ends armed.\n //\n // Either way the next right-click on a node was eaten: its handler\n // consumed a `true` left over from a gesture that ended somewhere\n // else, suppressed the browser's menu and showed nothing.\n //\n // Clearing in `onUp` instead would be wrong, and quietly: on the\n // release-order platforms `contextmenu` arrives AFTER `pointerup`,\n // so the guard would be gone before the event it exists for.\n this._rightDragged = false;\n if (this._onNode(event.target)) return;\n // Middle button, right button or Shift-drag pans; left button\n // rubber-bands.\n const panning = event.button === 1 || event.button === 2 || event.shiftKey;\n const start = { x: event.clientX, y: event.clientY, tx: this.tx, ty: this.ty };\n const origin = this.clientToCanvas(event.clientX, event.clientY);\n\n if (!panning) {\n this.marquee.hidden = false;\n this.selection.clear();\n this.onSelectionChange?.(this.selection);\n }\n\n const onMove = (move) => {\n if (panning) {\n // A few pixels of slop, so a right-click with a shaky hand\n // is still a click and still gets its menu.\n if (event.button === 2\n && (Math.abs(move.clientX - start.x) > 3\n || Math.abs(move.clientY - start.y) > 3)) {\n this._rightDragged = true;\n }\n this.tx = start.tx + (move.clientX - start.x);\n this.ty = start.ty + (move.clientY - start.y);\n this._apply();\n return;\n }\n const current = this.clientToCanvas(move.clientX, move.clientY);\n const box = {\n x: Math.min(origin.x, current.x),\n y: Math.min(origin.y, current.y),\n width: Math.abs(current.x - origin.x),\n height: Math.abs(current.y - origin.y),\n };\n const topLeft = this.canvasToClient(box.x, box.y);\n const root = this.root.getBoundingClientRect();\n this.marquee.style.left = `${topLeft.x - root.left}px`;\n this.marquee.style.top = `${topLeft.y - root.top}px`;\n this.marquee.style.width = `${box.width * this.scale}px`;\n this.marquee.style.height = `${box.height * this.scale}px`;\n this.onMarquee?.(box);\n };\n const onUp = () => {\n window.removeEventListener('pointermove', onMove);\n window.removeEventListener('pointerup', onUp);\n this.marquee.hidden = true;\n };\n window.addEventListener('pointermove', onMove);\n window.addEventListener('pointerup', onUp);\n });\n }\n\n clear() {\n this.nodeLayer.replaceChildren();\n this.edgeLayer.replaceChildren();\n }\n\n destroy() {\n this.root.remove();\n }\n}\n\nfunction clamp(value, low, high) {\n return Math.max(low, Math.min(value, high));\n}\n\n/** A pan nobody could see is not a pan. See `SUB_PIXEL`. */\nfunction ignoreSubPixel(shift) {\n return Math.abs(shift) < SUB_PIXEL ? 0 : shift;\n}\n", "/**\n * The canvas kernel \u2014 edge routing, crow's-foot decoration, a loop's return\n * line and a layered \"Arrange\" (36 \u00A74.2). Every export is a pure function of\n * points and boxes; only `crowsFoot` builds DOM (an SVG group), so the rest\n * runs under plain node.\n *\n * The router is an obstacle-avoiding multi-strategy model reduced to the two\n * strategies that hold up at a dense diagram's scale \u2014 40 nodes averaging 12\n * ports each, 480 ports \u2014 with the node count at which it degrades made\n * explicit rather than discovered.\n *\n * Crow's-foot notation is general diagram vocabulary (an entity-relationship\n * drawing's ends), and it moved with the rest; the cardinality decoration was\n * written rather than lifted, because the router it descends from drew a\n * plain path with no markers at all.\n */\n\n/** Above this, routing time becomes visible; fall back to direct curves. */\nexport const OBSTACLE_ROUTING_NODE_LIMIT = 60;\n\nconst SVG = 'http://www.w3.org/2000/svg';\n\n/**\n * A line between two port anchors `{x, y, side: 'left'|'right'}`, as an SVG\n * path `d`. `simple` (or more than `OBSTACLE_ROUTING_NODE_LIMIT` obstacles)\n * draws the direct curve and never looks at an obstacle.\n */\nexport function routeEdge(from, to, { obstacles = [], simple = false } = {}) {\n // Orthogonal-ish routing with a horizontal lead-out, which is what makes a\n // dense diagram readable: edges leave a port sideways and meet the target\n // sideways, so parallel lines stack instead of crossing.\n const dx = to.x - from.x;\n const lead = Math.max(28, Math.min(Math.abs(dx) / 2, 90));\n const outX = from.side === 'right' ? from.x + lead : from.x - lead;\n const inX = to.side === 'right' ? to.x + lead : to.x - lead;\n\n if (simple || obstacles.length > OBSTACLE_ROUTING_NODE_LIMIT) {\n return `M ${from.x} ${from.y} C ${outX} ${from.y}, ${inX} ${to.y}, ${to.x} ${to.y}`;\n }\n\n // Try the direct cubic first; if it crosses a node box, step the midpoint\n // out of the way and try again. Two strategies, not five \u2014 at 480 ports the\n // extra strategies cost more than they buy.\n const direct = `M ${from.x} ${from.y} C ${outX} ${from.y}, ${inX} ${to.y}, ${to.x} ${to.y}`;\n if (!crossesAny(from, to, obstacles)) return direct;\n\n const midY = midpointClear(from, to, obstacles);\n return `M ${from.x} ${from.y} C ${outX} ${from.y}, ${outX} ${midY}, `\n + `${(from.x + to.x) / 2} ${midY} S ${inX} ${to.y}, ${to.x} ${to.y}`;\n}\n\nfunction crossesAny(from, to, obstacles) {\n for (const box of obstacles) {\n if (segmentIntersectsBox(from, to, box)) return true;\n }\n return false;\n}\n\nfunction midpointClear(from, to, obstacles) {\n const base = (from.y + to.y) / 2;\n for (let offset = 0; offset < 400; offset += 40) {\n for (const candidate of [base - offset, base + offset]) {\n const point = { x: (from.x + to.x) / 2, y: candidate };\n if (!obstacles.some((box) => pointInBox(point, box))) return candidate;\n }\n }\n return base;\n}\n\nfunction pointInBox(point, box) {\n return point.x >= box.x && point.x <= box.x + box.width\n && point.y >= box.y && point.y <= box.y + box.height;\n}\n\nfunction segmentIntersectsBox(a, b, box) {\n // Cheap AABB rejection first; the exact test is not worth it at this scale.\n const left = Math.min(a.x, b.x), right = Math.max(a.x, b.x);\n const top = Math.min(a.y, b.y), bottom = Math.max(a.y, b.y);\n if (right < box.x || left > box.x + box.width) return false;\n if (bottom < box.y || top > box.y + box.height) return false;\n return true;\n}\n\n/**\n * The six crow's-foot ends, and what each one asserts.\n *\n * `maximum` is the symbol nearest the box; `minimum` is the one further out\n * along the line. `null` means \"do not draw one\", which is the pre-cardinality\n * behaviour and is kept only so the two legacy kinds below still render.\n */\nconst FOOT_ENDS = {\n // The two a diagram draws when it does not know optionality. Kept because a\n // caller that knows only the maximum should draw only the maximum rather\n // than guessing at a minimum it has no evidence for.\n many: { maximum: 'many', minimum: null },\n one: { maximum: 'one', minimum: null },\n // The four a diagram can actually derive from a foreign key.\n 'zero-or-many': { maximum: 'many', minimum: 'zero' },\n 'one-or-many': { maximum: 'many', minimum: 'one' },\n 'zero-or-one': { maximum: 'one', minimum: 'zero' },\n 'exactly-one': { maximum: 'one', minimum: 'one' },\n};\n\n/**\n * THE NOTATION'S ONE NUMBER. Everything below is a multiple of it, so a mark\n * that has to grow grows in proportion instead of drifting apart.\n */\nconst FOOT_SIZE = 9;\n/**\n * Where each symbol lives, measured OUTWARD FROM THE BOX in multiples of\n * `FOOT_SIZE`, and the reason the line can now be told where to stop.\n *\n * `MAXIMUM_ENDS_AT` is the far side of the symbol touching the box: the crow's\n * foot's toes start ON the box and converge one unit out, so its far side is 1;\n * the bar is a single stroke standing 0.45 out, clear of the node's own border\n * without reading as a second border.\n *\n * `MINIMUM_SITS_AT`, keyed by the maximum it stands behind, is where the ring or\n * the second bar is CENTRED \u2014 far enough out to clear the foot's apex, which is\n * why the two entries differ.\n */\nconst MAXIMUM_ENDS_AT = { many: 1, one: 0.45 };\nconst MINIMUM_SITS_AT = { many: 1.5, one: 0.95 };\nconst RING_RADIUS = 0.33;\n\n/**\n * WHERE THE LINE STARTS, which is where the mark ENDS.\n *\n * \"The line routing should have the line connector after the cardinality\n * indicator. Currently the line connects directly to the box and the\n * cardinality indicator is on top.\" It did: `crowsFoot` draws at the box edge\n * and `routeEdge` was handed the same point, so the connector ran the whole\n * depth of the mark underneath it \u2014 three toes with a line through their middle\n * read as an arrowhead somebody had drawn over, not as one symbol.\n *\n * The offset is the MAXIMUM's depth and deliberately not the whole end's. IE\n * notation is read outward from the box \u2014 maximum first, then minimum \u2014 and the\n * minimum is a mark ON the line, not before it: a ring is a bead on a string and\n * a second bar is a tick across it. Stopping the line beyond the ring instead\n * would leave the ring hanging off the tip with a gap behind it, which is the\n * same defect in the other direction.\n *\n * Takes and returns the `{x, y, side}` shape `routeEdge` and `selfLoop` consume,\n * so a caller offsets an endpoint by wrapping it rather than by doing this\n * arithmetic itself \u2014 which is how a diagram and a dialog's preview of one of\n * its lines stay in step. `side` is the direction the line LEAVES the box, exactly\n * as `crowsFoot` means it.\n */\nexport function footAnchor(point, side, kind) {\n const { maximum } = FOOT_ENDS[kind] || FOOT_ENDS.one;\n const direction = side === 'right' ? 1 : -1;\n return { ...point, side, x: point.x + direction * FOOT_SIZE * MAXIMUM_ENDS_AT[maximum] };\n}\n\n/**\n * Crow's-foot decoration.\n *\n * A foreign key is many-to-one from child to parent, so the child end gets the\n * foot and the parent end gets the bar. Getting these the right way round is the\n * whole information content of the notation.\n *\n * \u2500\u2500 AN END IS TWO SYMBOLS, NOT ONE \u2500\u2500\n *\n * IE/Barker notation is read OUTWARD FROM THE BOX: the symbol touching the box\n * is the *maximum* (a foot for many, a bar for one) and the symbol further along\n * the line is the *minimum* (a ring for zero, a bar for one). \"Zero or many\" is\n * therefore a foot with a ring behind it. Drawing only the maximum \u2014 which is all\n * this function could do before \u2014 says how many children a parent may have and\n * stays silent on whether a child must have a parent, which is the half of a\n * schema diagram people actually argue about.\n *\n * The one place this stops short of the textbook is \"exactly one\", which the\n * books draw as two bars and this draws as one. The argument is at the bar\n * itself, below; the short version is that at 9px the second bar is not a second\n * symbol, and the ring already carries the whole of the minimum.\n *\n * `side` is the direction the LINE LEAVES THE BOX, so both symbols are laid out\n * away from it. Passing the opposite side draws the whole end underneath the\n * node, which is opaque and painted above the edge layer, so it disappears\n * without a trace.\n *\n * The group is `twm-edge__marker twm-edge__marker--<kind>`; its strokes take the\n * stylesheet's `.twm-edge__marker line` and `circle` rules.\n *\n * @param {string} kind one of the keys of `FOOT_ENDS`.\n */\nexport function crowsFoot(point, side, kind) {\n const group = document.createElementNS(SVG, 'g');\n group.setAttribute('class', `twm-edge__marker twm-edge__marker--${kind}`);\n const direction = side === 'right' ? 1 : -1;\n // Unknown kinds fall back to the bar rather than throwing: a diagram that\n // draws one end slightly wrong is recoverable, one that throws out of\n // `draw()` renders no edges at all.\n const { maximum, minimum } = FOOT_ENDS[kind] || FOOT_ENDS.one;\n\n const bar = (offset) => {\n const line = document.createElementNS(SVG, 'line');\n line.setAttribute('x1', point.x + direction * FOOT_SIZE * offset);\n line.setAttribute('y1', point.y - FOOT_SIZE * 0.7);\n line.setAttribute('x2', point.x + direction * FOOT_SIZE * offset);\n line.setAttribute('y2', point.y + FOOT_SIZE * 0.7);\n group.appendChild(line);\n };\n\n if (maximum === 'many') {\n // The toes touch the box and the three lines converge on the connector,\n // which is the way round every ERD tool draws it \u2014 and the way round\n // that leaves the minimum symbol room to sit behind the foot rather\n // than floating in the middle of the line belonging to nothing.\n for (const dy of [-FOOT_SIZE * 0.8, 0, FOOT_SIZE * 0.8]) {\n const line = document.createElementNS(SVG, 'line');\n line.setAttribute('x1', point.x + direction * FOOT_SIZE * MAXIMUM_ENDS_AT.many);\n line.setAttribute('y1', point.y);\n line.setAttribute('x2', point.x);\n line.setAttribute('y2', point.y + dy);\n group.appendChild(line);\n }\n } else {\n bar(MAXIMUM_ENDS_AT.one);\n }\n\n if (minimum === 'zero') {\n const ring = document.createElementNS(SVG, 'circle');\n ring.setAttribute('cx', point.x + direction * FOOT_SIZE * MINIMUM_SITS_AT[maximum]);\n ring.setAttribute('cy', point.y);\n ring.setAttribute('r', FOOT_SIZE * RING_RADIUS);\n group.appendChild(ring);\n } else if (minimum === 'one' && maximum === 'many') {\n // \u2500\u2500 \"TO ONE\" IS ONE BAR, NOT TWO \u2500\u2500\n //\n // Textbook IE draws mandatory-one as two bars, the outer one asserting\n // the minimum. At this size it cannot: the two strokes land 4px apart,\n // which at 9px and 1.4px of stroke is not a pair of bars but a thick\n // one \u2014 and a thick bar is what \"many\" reads as when the foot is small.\n // The report was \"on a `to one` cardinality I would expect a single\n // vertical bar, not two\", and that is the eye reading the drawing\n // correctly.\n //\n // OF THE TWO RULES THE SECOND BAR WAS EXPRESSING, THE MAXIMUM WINS. It\n // is the symbol nearest the box, it is the one the notation is read\n // from, and it is the one that cannot be inferred from anything else.\n // The minimum is not lost with it: optionality is carried by the RING,\n // whose presence means zero and whose absence means one, so `exactly-one`\n // is a bar with nothing behind it and `zero-or-one` is a bar with a ring\n // on the line behind it. Every one of the six ends stays distinguishable\n // and each is now one legible mark.\n //\n // `one-or-many` keeps its bar, because there it stands behind a FOOT and\n // the two shapes cannot be confused for one another.\n bar(MINIMUM_SITS_AT[maximum]);\n }\n return group;\n}\n\n/**\n * The two ends a foreign key implies, named in the vocabulary `crowsFoot` takes.\n *\n * ONE PLACE, because a diagram and any preview of one of its lines have to\n * agree: a preview drawn with this function and `crowsFoot` cannot disagree\n * with the canvas \u2014 it is not expressible rather than merely unlikely.\n *\n * Both facts come off the physical constraint and nothing else, which is why\n * only these two are derivable:\n *\n * * **the parent end** \u2014 how many parents one child row has \u2014 is settled by the\n * child column's NULLABILITY. `NOT NULL` is exactly one; nullable is zero or\n * one. The caller passes it as `optional`.\n * * **the child end** \u2014 how many children one parent row has \u2014 is settled by\n * the child column's UNIQUENESS. A single-column `UNIQUE` makes it zero or\n * one (`kind: '1:1'`); without it, zero or many (`kind: '1:N'`).\n *\n * \"One or many\" is deliberately never returned. No foreign key can require a\n * parent to have at least one child \u2014 that is a business rule living in a\n * trigger or nowhere \u2014 and inventing it on a schema diagram would be worse than\n * saying less.\n *\n * @param {{kind?: string, optional?: boolean}} edge\n * @returns {{child: string, parent: string}}\n */\nexport function cardinality({ kind, optional } = {}) {\n // `N:M` is a junction drawn as ONE line between its two ends rather than as\n // a three-box picture. Many at both ends is what that line means; the\n // parent end's `optional` describes a column the junction has not got yet.\n if (kind === 'N:M') return { child: 'zero-or-many', parent: 'zero-or-many' };\n return {\n child: kind === '1:1' ? 'zero-or-one' : 'zero-or-many',\n parent: optional ? 'zero-or-one' : 'exactly-one',\n };\n}\n\n/**\n * A SELF-REFERENCING edge: `employee.manager_id \u2192 employee`.\n *\n * A first-class thing a user creates on day one \u2014 a manager, a parent category,\n * a predecessor task. `routeEdge` cannot draw it: source and target are on the\n * same node, so a cubic between them is a line of zero visible length hidden\n * behind the node body.\n *\n * The shape is a loop out of the right edge and back into it, bulging by an\n * amount that grows with the vertical distance between the two ports so a node\n * with several self-references does not stack them on top of each other.\n */\nexport function selfLoop(from, to, { nodeRight, gap = 46 } = {}) {\n const right = Math.max(nodeRight ?? from.x, from.x, to.x);\n const span = Math.abs(to.y - from.y);\n const bulge = right + gap + Math.min(span / 2, 60);\n return `M ${from.x} ${from.y} C ${bulge} ${from.y}, ${bulge} ${to.y}, ${to.x} ${to.y}`;\n}\n\n/**\n * A RETURN edge: a loop's body handing control back to one of the loop step's\n * own inputs, for its next pass.\n *\n * The body sits RIGHT of its loop and that input is on the loop's LEFT edge, so\n * `routeEdge` draws the line doubling back across both nodes, where it reads\n * as one more forward step. This one leaves the body step rightwards, drops to\n * `floor` (the caller passes a line below both nodes), runs back left under\n * them, and rises into the port from its left side \u2014 the shape a reader\n * recognises as \"and round again\". It is never higher than the lower of the\n * two ends, whatever `floor` is.\n */\nexport function returnEdge(from, to, { floor = null, lead = 36 } = {}) {\n const bottom = Math.max(Number.isFinite(floor) ? floor : -Infinity, from.y, to.y);\n const outX = from.x + lead;\n const inX = to.x - lead;\n return `M ${from.x} ${from.y} C ${outX} ${from.y}, ${outX} ${bottom}, ${from.x} ${bottom} `\n + `L ${to.x} ${bottom} C ${inX} ${bottom}, ${inX} ${to.y}, ${to.x} ${to.y}`;\n}\n\n/**\n * Dagre-free layered auto-layout \u2014 \"Arrange\".\n *\n * Rank by dependency depth, then pack within a rank. `nodes` are\n * `{id, label, height?}` and `edges` `{from, to}`; returns a Map of id \u2192\n * `{x, y}` from (0, 0).\n *\n * \u2500\u2500 ITS TWO QUIRKS, KEPT AND STATED, because callers rely on both \u2500\u2500\n *\n * * **AN EDGE POINTS FROM CHILD TO PARENT.** A node with no outgoing edge is\n * at rank 0, and each node sits one rank RIGHT of its deepest `to` \u2014 which\n * lays a schema out the way people draw one, a foreign key pointing\n * leftwards at what it references. A flow, whose lines point at what runs\n * NEXT, hands its connections over REVERSED (`{from: target, to: source}`).\n * * **EVERY NODE NEEDS A `label`.** Each column is sorted with\n * `a.label.localeCompare(b.label)`, which throws on a missing one. A caller\n * that wants another order within a column passes an order key as the label\n * (the canvas editor passes a zero-padded breadth-first index).\n *\n * A cycle is broken (its back edge read as rank 0) rather than hung on.\n */\nexport function arrange(nodes, edges, { columnGap = 340, rowGap = 40 } = {}) {\n const byId = new Map(nodes.map((n) => [n.id, n]));\n const parents = new Map(nodes.map((n) => [n.id, []]));\n for (const edge of edges) {\n if (byId.has(edge.from) && byId.has(edge.to) && edge.from !== edge.to) {\n parents.get(edge.from).push(edge.to);\n }\n }\n\n const rank = new Map();\n const visiting = new Set();\n const rankOf = (id) => {\n if (rank.has(id)) return rank.get(id);\n if (visiting.has(id)) return 0; // a cycle: break it rather than hang\n visiting.add(id);\n const value = parents.get(id).length\n ? Math.max(...parents.get(id).map(rankOf)) + 1\n : 0;\n visiting.delete(id);\n rank.set(id, value);\n return value;\n };\n for (const node of nodes) rankOf(node.id);\n\n const columns = new Map();\n for (const node of nodes) {\n const column = rank.get(node.id) ?? 0;\n if (!columns.has(column)) columns.set(column, []);\n columns.get(column).push(node);\n }\n\n const positions = new Map();\n for (const [column, members] of [...columns].sort((a, b) => a[0] - b[0])) {\n members.sort((a, b) => a.label.localeCompare(b.label));\n let y = 0;\n for (const node of members) {\n positions.set(node.id, { x: column * columnGap, y });\n y += (node.height || 120) + rowGap;\n }\n }\n return positions;\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }