@weasel-js/diagram 1.15.0 → 1.15.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 (34) hide show
  1. package/README.md +114 -5
  2. package/dist/{chunk-GR2DK4S2.js → chunk-EIHPPOAM.js} +1480 -229
  3. package/dist/chunk-EIHPPOAM.js.map +1 -0
  4. package/dist/{chunk-AXL4JQBM.js → chunk-EIT4BFDK.js} +3 -3
  5. package/dist/{chunk-AXL4JQBM.js.map → chunk-EIT4BFDK.js.map} +1 -1
  6. package/dist/{chunk-DE7UILJA.js → chunk-NEX4QKQQ.js} +183 -23
  7. package/dist/chunk-NEX4QKQQ.js.map +1 -0
  8. package/dist/{chunk-FDCODMFW.js → chunk-UOFQBGJY.js} +904 -599
  9. package/dist/chunk-UOFQBGJY.js.map +1 -0
  10. package/dist/{chunk-IYUU5KUY.js → chunk-UUMLQEMR.js} +8 -96
  11. package/dist/chunk-UUMLQEMR.js.map +1 -0
  12. package/dist/{dataTypes-BIkhAOc4.d.ts → dataTypes-1ch6cMtq.d.ts} +12 -3
  13. package/dist/effect-audio.d.ts +2 -2
  14. package/dist/effect-audio.js +3 -3
  15. package/dist/effect.d.ts +5 -5
  16. package/dist/effect.js +7 -7
  17. package/dist/effect.js.map +1 -1
  18. package/dist/icons.table.js +44 -0
  19. package/dist/icons.table.js.map +1 -1
  20. package/dist/icons.table.json +44 -0
  21. package/dist/index.d.ts +938 -37
  22. package/dist/index.js +708 -34
  23. package/dist/index.js.map +1 -1
  24. package/dist/{labelTrait-BBjRgxbz.d.ts → labelTrait-moIciyXr.d.ts} +4 -0
  25. package/dist/layout.d.ts +3 -3
  26. package/dist/{layout.entry-CbmGuqE-.d.ts → layout.entry-zstuljAl.d.ts} +2 -2
  27. package/dist/layout.js +2 -2
  28. package/dist/{stageTypes-UiO25hcn.d.ts → stageTypes-B7oF8Lww.d.ts} +1 -1
  29. package/dist/{types-B0n2CNTW.d.ts → types-D5ybp8Xh.d.ts} +32 -1
  30. package/package.json +11 -11
  31. package/dist/chunk-DE7UILJA.js.map +0 -1
  32. package/dist/chunk-FDCODMFW.js.map +0 -1
  33. package/dist/chunk-GR2DK4S2.js.map +0 -1
  34. package/dist/chunk-IYUU5KUY.js.map +0 -1
@@ -1,11 +1,11 @@
1
- import { createAvoidRouter, placeLabels, edgeHops, radial, DEFAULT_HOP_SIZE, HOPS_DOC_KEY, simplifyStops } from './chunk-IYUU5KUY.js';
2
- import { edgeRouter, registerMarkShape, withDiagramRegistry, diagramLabelOf, editEdgeLabelBinding, editEdgeLabelAction, diagramGroupOf, diagramContainerOf, headerBox, labelFollowsLayout, buildGraph, LABEL_DRAG_AFFORDANCE_KIND, EDIT_EDGE_LABEL_ACTION_ID, labelDragLayer, laneOutlineOf, recordedRows, keyedIndex, boxIndex, boxesMeeting, routerOf, labelScratchOf, ROUTERS, avoid, LABEL_PLACEMENT, editableLabels, titleIdOf, orthogonal, diagramAnchorOf, MIN_LANE_SIZE, EDGE_DERIVE_PATH, titleInFrame, regionSpecs, DIAGRAM_THEME_KEY, diagramThemeOf, endAims, resolveEnd, themeLabelFamily, bodyBox, boxCenter, roleEdgeStyle, roleStyle, themeLabelFont, firstLanes, DEFAULT_LANE_SIZE } from './chunk-DE7UILJA.js';
3
- import { diagramEdgeOf, isPromise, diagramNodeOf, portsOf, portSitesOf, outlinePath, outlineDetail, samePoints, layoutWritesRoute, plannerPlan, planOf, layered, dataKeyReader, layoutBody, forceRelaxation, center, layoutOwnsPort, chain, force, tree, portOf, labelCenter, labelSpotAt, isPinned, layoutOwnsRoute } from './chunk-FDCODMFW.js';
4
- import { bodyPredicate, dragPanContribution, WeaselProvider, useScene, useSelection, useLatest, SceneCanvas, useDepSource, RIGID_POSE_COMPOSITION, registerNodeShape, reconcileSpecs, pagesBounds, pagesLayer, AUTO_POSE_DESCRIPTOR, usePoseRun, drawnBoundsScene, pointAlongPath, scenePoseAdapter, drawnAABBOf, composeWorldPose, worldPosesOf, RECT_POSE_DESCRIPTOR, resolveFill, resolveStroke, commandFill, commandStroke, nodeGates, scenePoseFrame, fitViewToBounds, clampView, rebaseLocalPose, translatePoseViaDescriptor, carriedDescendants, sceneCarrySource, composeAffordanceLayer, createResizeAction, createDeleteAction, effectivePose, polylineFromPoints, SNAP_ROLES, ActionDisabledReason, refusalOf, snapMods, documentDepOf, definesFrame, paintsLayer, viewToTransform, ellipsePath, derivedDepOf, localizeWorldPoses, PathBuilder, startCarry, createInsertOp, createSetDataOp, documentPose } from '@weasel-js/core';
1
+ import { createAvoidRouter, placeLabels, edgeHops, DEFAULT_HOP_SIZE, HOPS_DOC_KEY, simplifyStops } from './chunk-UUMLQEMR.js';
2
+ import { edgeRouter, registerMarkShape, withDiagramRegistry, diagramLabelOf, routesOf, layoutPoses, routeWrites, editEdgeLabelBinding, editEdgeLabelAction, diagramGroupOf, diagramContainerOf, headerBox, buildGraph, LAYOUTS, LABEL_DRAG_AFFORDANCE_KIND, EDIT_EDGE_LABEL_ACTION_ID, labelDragLayer, laneOutlineOf, recordedRows, keyedIndex, boxIndex, boxesMeeting, routerOf, labelScratchOf, ROUTERS, avoid, LABEL_PLACEMENT, editableLabels, titleIdOf, orthogonal, diagramAnchorOf, MIN_LANE_SIZE, EDGE_DERIVE_PATH, titleInFrame, regionSpecs, DIAGRAM_THEME_KEY, diagramThemeOf, endAims, resolveEnd, themeLabelFamily, diagramThemeFrom, themeFont, bodyBox, boxCenter, roleEdgeStyle, DEFAULT_FONT, withColors, roleStyle, GLYPH, themeLabelFont, firstLanes, DEFAULT_LANE_SIZE } from './chunk-NEX4QKQQ.js';
3
+ import { diagramEdgeOf, isPromise, diagramNodeOf, portsOf, portSitesOf, outlinePath, outlineDetail, outlineSolid, samePoints, layoutWritesRoute, plannerPlan, planOf, layered, dataKeyReader, layoutBody, forceRelaxation, center, portOf, labelCenter, labelSpotAt, contentBox, boxForContent, grid, chain, tree, isPinned, layoutOwnsRoute } from './chunk-UOFQBGJY.js';
4
+ import { bodyPredicate, dragPanContribution, WeaselProvider, useScene, useSelection, useLatest, SceneCanvas, useDepSource, RIGID_POSE_COMPOSITION, registerNodeShape, reconcileSpecs, pagesBounds, pagesLayer, usePoseRun, drawnBoundsScene, pointAlongPath, scenePoseAdapter, drawnAABBOf, composeWorldPose, worldPosesOf, RECT_POSE_DESCRIPTOR, resolveFill, resolveStroke, commandFill, commandStroke, nodeGates, scenePoseFrame, fitViewToBounds, clampView, AUTO_POSE_DESCRIPTOR, composeAffordanceLayer, createResizeAction, createDeleteAction, isTextData, effectivePose, polylineFromPoints, SNAP_ROLES, ActionDisabledReason, commitDeleteToScene, refusalOf, snapMods, documentDepOf, translatePoseViaDescriptor, definesFrame, paintsLayer, viewToTransform, ellipsePath, carriedDescendants, sceneCarrySource, derivedDepOf, localizeWorldPoses, PathBuilder, startCarry, createInsertOp, createSetDataOp, documentPose } from '@weasel-js/core';
5
5
  import { createSettledCache } from '@weasel-js/geom/nd';
6
6
  import { AUTO_POSE_DESCRIPTOR as AUTO_POSE_DESCRIPTOR$1, rotatePoint } from '@weasel-js/core/math';
7
7
  import { clampRectWithin, placeRect, pathContainsPoint } from '@weasel-js/geom';
8
- import { nudgeGap, moveItems, nearestGap, isNoopDrop } from '@weasel-js/headless';
8
+ import { nudgeGap, moveItems, nearestGap, isNoopDrop } from '@weasel-js/ui-logic';
9
9
  import { forwardRef, useMemo, useEffect, useState, useRef, useCallback, useImperativeHandle, useLayoutEffect } from 'react';
10
10
  import { useLatest as useLatest$1, adoptCssOnce } from '@weasel-js/react';
11
11
  import '@weasel-js/animator';
@@ -109,10 +109,10 @@ function createPortAffordance(participants, opts = {}) {
109
109
  const built = index();
110
110
  const rx = hitRadiusPx / Math.abs(view.scale.x);
111
111
  const ry = hitRadiusPx / Math.abs(view.scale.y);
112
- const near2 = built && boxesMeeting(built.boxes, wx - rx, wy - ry, wx + rx, wy + ry);
113
- if (!built || !near2) return regions(state);
112
+ const near = built && boxesMeeting(built.boxes, wx - rx, wy - ry, wx + rx, wy + ry);
113
+ if (!built || !near) return regions(state);
114
114
  const out = [];
115
- for (const i of near2) {
115
+ for (const i of near) {
116
116
  const entry = built.at[i];
117
117
  if (shown(entry.participant, state) && showsPort(entry.port)) out.push(regionAt(entry));
118
118
  }
@@ -507,8 +507,8 @@ function createReorderAction(opts) {
507
507
  if (slots === null || picked === null) return {};
508
508
  const held = { slots, ...picked };
509
509
  const { axis } = slots;
510
- const region = opts.region?.(ctx.deps, held.item) ?? null;
511
- const leaves = (at) => region !== null && !inside(at, region);
510
+ const region2 = opts.region?.(ctx.deps, held.item) ?? null;
511
+ const leaves = (at) => region2 !== null && !inside(at, region2);
512
512
  let by = ctx.world[axis] - start[axis];
513
513
  let open = true;
514
514
  const verdicts = /* @__PURE__ */ new Map();
@@ -920,6 +920,7 @@ function themeWrites(scene, theme, ids, from) {
920
920
  const data = node.data;
921
921
  if (data === null || typeof data !== "object") continue;
922
922
  const trait = traitOf(data);
923
+ if (trait !== null && ("seq" in trait || "sequence" in trait)) continue;
923
924
  if (trait !== null && "from" in trait && "to" in trait) {
924
925
  if (ids !== void 0 && !ids.has(node.id)) continue;
925
926
  const look2 = edgeLook(trait, theme);
@@ -980,7 +981,7 @@ function containerBuild(stencil, bounds, opts) {
980
981
  const id = opts.newId();
981
982
  const axis = stencil.axis ?? "y";
982
983
  const at = placedBounds(stencil, bounds);
983
- const title = stencil.role === "pool" ? "Pool" : stencil.label;
984
+ const title = stencil.title ?? (stencil.role === "pool" ? "Pool" : stencil.label);
984
985
  const style = stencil.role === "pool" && opts.laneStyles ? opts.laneStyles.header : opts.style;
985
986
  const specs = [
986
987
  ...regionSpecs(stencil.role, axis, at, title, {
@@ -989,7 +990,7 @@ function containerBuild(stencil, bounds, opts) {
989
990
  parent: opts.parent ?? null,
990
991
  ...style ? { style } : {}
991
992
  }),
992
- ...stencil.role === "pool" ? firstLanes(id, axis, at, opts) : []
993
+ ...stencil.role === "pool" ? firstLanes(id, axis, at, opts, stencil.lanes) : []
993
994
  ];
994
995
  const label = `Insert ${stencil.label}`;
995
996
  const stored = localizeWorldPoses(specs, RIGID_POSE_COMPOSITION);
@@ -1442,19 +1443,19 @@ function createLabelDragAction(opts = {}) {
1442
1443
  if (p === null) return {};
1443
1444
  let spot = null;
1444
1445
  let open = true;
1445
- const proposed = () => open ? spot : null;
1446
+ const proposed2 = () => open ? spot : null;
1446
1447
  return {
1447
1448
  kind: "diagram-move-label",
1448
1449
  onMove(moveCtx) {
1449
1450
  spot = spotAt(p, moveCtx);
1450
1451
  },
1451
- previewIds: () => proposed() === null ? null : [p.labelId],
1452
+ previewIds: () => proposed2() === null ? null : [p.labelId],
1452
1453
  previewPose: (id) => {
1453
- const next = proposed();
1454
+ const next = proposed2();
1454
1455
  return id === p.labelId && next !== null ? poseAt(p, next) : null;
1455
1456
  },
1456
1457
  previewData: (id) => {
1457
- const next = proposed();
1458
+ const next = proposed2();
1458
1459
  return id === p.labelId && next !== null ? movedLabelData(p.data, next) : null;
1459
1460
  },
1460
1461
  onEnd(endCtx, reason) {
@@ -1928,16 +1929,16 @@ function createRouteEditAction(opts) {
1928
1929
  const session = beginSnap(ctx, p, snapPx);
1929
1930
  let waypoints = null;
1930
1931
  let open = true;
1931
- const proposed = () => open ? waypoints : null;
1932
+ const proposed2 = () => open ? waypoints : null;
1932
1933
  return {
1933
1934
  kind: "diagram-edit-route",
1934
1935
  onMove(moveCtx) {
1935
1936
  waypoints = waypointsAt(p, moveOf2(p, session, moveCtx));
1936
1937
  },
1937
- previewIds: () => proposed() === null ? null : [p.edgeId],
1938
- previewPose: (id) => id === p.edgeId && proposed() !== null ? p.pose : null,
1938
+ previewIds: () => proposed2() === null ? null : [p.edgeId],
1939
+ previewPose: (id) => id === p.edgeId && proposed2() !== null ? p.pose : null,
1939
1940
  previewData: (id) => {
1940
- const next = proposed();
1941
+ const next = proposed2();
1941
1942
  return id === p.edgeId && next !== null ? routedData(p.data, p.trait, next) : null;
1942
1943
  },
1943
1944
  onEnd(endCtx, reason) {
@@ -2255,8 +2256,8 @@ function avoidSceneInput(scene, opts = {}, poseOf) {
2255
2256
  const header = container === null ? null : headerBox(box, container.header);
2256
2257
  if (header !== null) obstacles.push({ id: headerIdOf(node.id), kind: "shape", box: header });
2257
2258
  if (container?.role === "lane") continue;
2258
- const region = container !== null || diagramGroupOf(node) !== null;
2259
- obstacles.push(region ? { id: node.id, kind: "region", box, members: members(sc, node, /* @__PURE__ */ new Set()) } : { id: node.id, kind: "shape", box });
2259
+ const region2 = container !== null || diagramGroupOf(node) !== null;
2260
+ obstacles.push(region2 ? { id: node.id, kind: "region", box, members: members(sc, node, /* @__PURE__ */ new Set()) } : { id: node.id, kind: "shape", box });
2260
2261
  }
2261
2262
  for (const id of split) {
2262
2263
  const node = labelNodes.get(id);
@@ -2315,13 +2316,13 @@ function obstaclesOf(specs, world) {
2315
2316
  for (const spec of specs) {
2316
2317
  const node = { id: spec.id, kind: spec.kind, data: spec.data };
2317
2318
  if (spec.derivePose !== void 0 || diagramEdgeOf(spec) !== null) continue;
2318
- const region = diagramContainerOf(spec);
2319
- if (diagramNodeOf(node) === null && region?.role !== "lane") continue;
2319
+ const region2 = diagramContainerOf(spec);
2320
+ if (diagramNodeOf(node) === null && region2?.role !== "lane") continue;
2320
2321
  const box = world.get(node.id) ?? spec.pose;
2321
- const header = region === null ? null : headerBox(box, region.header);
2322
+ const header = region2 === null ? null : headerBox(box, region2.header);
2322
2323
  if (header !== null) out.push({ id: headerIdOf(node.id), kind: "shape", box: header });
2323
- if (region?.role === "lane") continue;
2324
- out.push(region === null ? { id: node.id, kind: "shape", box } : { id: node.id, kind: "region", box, members: inside2(node.id, /* @__PURE__ */ new Set()) });
2324
+ if (region2?.role === "lane") continue;
2325
+ out.push(region2 === null ? { id: node.id, kind: "shape", box } : { id: node.id, kind: "region", box, members: inside2(node.id, /* @__PURE__ */ new Set()) });
2325
2326
  }
2326
2327
  return out;
2327
2328
  }
@@ -2684,168 +2685,27 @@ function createSpecLabelPlacer(opts = {}) {
2684
2685
  };
2685
2686
  }
2686
2687
 
2688
+ // src/sequence/trait.ts
2689
+ var traitOf2 = (node) => {
2690
+ const data = node.data;
2691
+ if (data === null || typeof data !== "object") return null;
2692
+ const trait = data.diagram;
2693
+ return trait !== null && typeof trait === "object" ? trait : null;
2694
+ };
2695
+ function sequenceRootOf(node) {
2696
+ const trait = traitOf2(node);
2697
+ return trait !== null && "sequence" in trait && "geometry" in trait ? trait : null;
2698
+ }
2699
+ function sequencePartOf(node) {
2700
+ const seq = traitOf2(node)?.seq;
2701
+ return seq !== null && typeof seq === "object" && typeof seq.root === "string" ? seq : null;
2702
+ }
2703
+
2687
2704
  // src/resizable.ts
2688
2705
  function diagramResizable(scene) {
2689
2706
  return (id) => {
2690
2707
  const node = scene.get(id);
2691
- return node === void 0 || diagramEdgeOf(node) === null && diagramLabelOf(node) === null && diagramGroupOf(node) === null && diagramContainerOf(node)?.role !== "lane";
2692
- };
2693
- }
2694
-
2695
- // src/routeWrites.ts
2696
- var ROUTE_TOLERANCE = 1e-3;
2697
- function routesOf(graph, plan) {
2698
- return {
2699
- edges: new Set(graph.edges.map((e) => e.origin?.id ?? e.id)),
2700
- waypoints: plan.waypoints ?? /* @__PURE__ */ new Map(),
2701
- ...plan.labels !== void 0 ? { labels: plan.labels } : {},
2702
- ...plan.ports !== void 0 ? { ports: plan.ports } : {}
2703
- };
2704
- }
2705
- function routeWrites(scene, routes) {
2706
- const out = /* @__PURE__ */ new Map();
2707
- const owned = /* @__PURE__ */ new Set();
2708
- for (const id of routes.edges) {
2709
- const node = scene.get(id);
2710
- const edge = node === void 0 ? null : diagramEdgeOf(node);
2711
- if (node === void 0 || edge === null || scene.isLocked(id)) {
2712
- if (edge !== null && layoutWritesRoute(edge)) owned.add(id);
2713
- continue;
2714
- }
2715
- let next = edge;
2716
- if (layoutWritesRoute(edge)) {
2717
- owned.add(id);
2718
- next = rerouted(edge, routes.waypoints.get(id));
2719
- }
2720
- const ports = routes.ports?.get(id);
2721
- const from = renamed(edge.from, ports?.from);
2722
- const to = renamed(edge.to, ports?.to);
2723
- if (from !== edge.from || to !== edge.to) next = { ...next, from, to };
2724
- if (next !== edge) out.set(id, withTrait(node.data, next));
2725
- }
2726
- const stationed = /* @__PURE__ */ new Set();
2727
- for (const node of scene.renderOrderNodes()) {
2728
- const label = diagramLabelOf(node);
2729
- const deps = node.dependsOn;
2730
- if (label === null || !Array.isArray(deps) || deps.length !== 1 || !owned.has(deps[0])) continue;
2731
- if (!labelFollowsLayout(label.at) || stationed.has(deps[0])) continue;
2732
- stationed.add(deps[0]);
2733
- const near2 = routes.labels?.get(deps[0]);
2734
- const at = near2 === void 0 ? "mid" : { near: near2 };
2735
- if (sameAt(label.at, at) || scene.isLocked(node.id)) continue;
2736
- out.set(node.id, withTrait(node.data, { ...label, at }, "label"));
2737
- }
2738
- return out;
2739
- }
2740
- function rerouted(edge, route) {
2741
- if (route === void 0 || route.length === 0) {
2742
- if ((edge.waypoints ?? []).length === 0 && edge.laidOut === void 0) return edge;
2743
- const { waypoints: _w, laidOut: _l, ...rest } = edge;
2744
- return rest;
2745
- }
2746
- if (edge.waypoints !== void 0 && near(edge.waypoints, route)) return edge;
2747
- return { ...edge, waypoints: route, laidOut: route };
2748
- }
2749
- function renamed(end, port) {
2750
- if (!layoutOwnsPort(end) || end.port === port && (port === void 0 || end.laidOut === port)) return end;
2751
- const { port: _p, laidOut: _l, ...rest } = end;
2752
- return port === void 0 ? rest : { ...rest, port, laidOut: port };
2753
- }
2754
- function near(a, b) {
2755
- return a.length === b.length && a.every((p, i) => Math.abs(p.x - b[i].x) <= ROUTE_TOLERANCE && Math.abs(p.y - b[i].y) <= ROUTE_TOLERANCE);
2756
- }
2757
- function sameAt(a, b) {
2758
- if (typeof a === "object" && typeof b === "object") return near([a.near], [b.near]);
2759
- return a === b;
2760
- }
2761
- function withTrait(data, value, key) {
2762
- const own = data;
2763
- const diagram = key === void 0 ? value : { ...own.diagram, [key]: value };
2764
- return { ...own, diagram };
2765
- }
2766
- var LAYOUTS = Object.freeze({
2767
- layered,
2768
- tree,
2769
- force,
2770
- chain,
2771
- radial
2772
- });
2773
- function applyLayout(scene, result, opts = {}) {
2774
- const poses = layoutPoses(scene, result, opts.geometry);
2775
- const data = opts.routes === void 0 ? /* @__PURE__ */ new Map() : routeWrites(scene, opts.routes);
2776
- if (poses.size === 0 && data.size === 0) return 0;
2777
- const open = [...poses].filter(([id]) => !scene.isLocked(id));
2778
- if (open.length === 0 && data.size === 0) return 0;
2779
- scene.batch(opts.label ?? "Layout", () => {
2780
- for (const [id, pose] of open) scene.setPose(id, pose);
2781
- for (const [id, d] of data) scene.update(id, { data: d });
2782
- });
2783
- const wrote = new Set(open.map(([id]) => id));
2784
- let moved = 0;
2785
- for (const id of result.keys()) if (wrote.has(id)) moved++;
2786
- return moved;
2787
- }
2788
- function layoutPoses(scene, result, geometry = AUTO_POSE_DESCRIPTOR) {
2789
- const sc = scene;
2790
- const { compose, decompose } = sc.composition;
2791
- const stored = scenePoseAdapter(sc);
2792
- const out = /* @__PURE__ */ new Map();
2793
- const decided = { ...stored, getPose: (id) => out.has(id) ? out.get(id) : stored.getPose(id) };
2794
- const depth = (id) => {
2795
- let d = 0;
2796
- for (let at = scene.get(id)?.parent; at != null; at = scene.get(at)?.parent) d++;
2797
- return d;
2798
- };
2799
- const ids = [...result.keys()].filter((id) => scene.get(id) !== void 0).sort((a, b) => depth(a) - depth(b));
2800
- for (const id of ids) {
2801
- const at = result.get(id);
2802
- const world = composeWorldPose(stored, id, compose);
2803
- const bounds = geometry.getBounds(world);
2804
- const dx = at.x - bounds.x;
2805
- const dy = at.y - bounds.y;
2806
- if (dx === 0 && dy === 0) continue;
2807
- const parent = scene.get(id).parent;
2808
- out.set(id, rebaseLocalPose(decided, translatePoseViaDescriptor(world, dx, dy, geometry), parent, compose, decompose));
2809
- const carried = carriedDescendants(sceneCarrySource(sc), id, (w) => translatePoseViaDescriptor(w, dx, dy, geometry));
2810
- for (const [d, pose] of carried) out.set(d, pose);
2811
- }
2812
- return out;
2813
- }
2814
- var LAYOUT_ACTION_ID = "diagram.layout";
2815
- function layoutDiagram(scene, source, algorithm, opts = {}) {
2816
- const fn = typeof algorithm === "function" ? algorithm : LAYOUTS[algorithm] ?? layered;
2817
- const graph = buildGraph(source, {
2818
- ...opts.read ? { read: opts.read } : {},
2819
- ...opts.geometry ? { geometry: opts.geometry } : {}
2820
- });
2821
- const plan = planOf(fn, graph, opts.layout);
2822
- return applyLayout(scene, plan.moves, {
2823
- ...opts.geometry ? { geometry: opts.geometry } : {},
2824
- ...opts.label ? { label: opts.label } : {},
2825
- routes: routesOf(graph, plan)
2826
- });
2827
- }
2828
- function createLayoutAction(opts) {
2829
- const { read, geometry, layout, label } = opts;
2830
- const options = {
2831
- ...read ? { read } : {},
2832
- ...geometry ? { geometry } : {},
2833
- ...layout ? { layout } : {},
2834
- ...label ? { label } : {}
2835
- };
2836
- return {
2837
- id: opts.id ?? LAYOUT_ACTION_ID,
2838
- label: opts.label ?? "Lay out diagram",
2839
- group: opts.group ?? "diagram",
2840
- requires: ["scene"],
2841
- invoker: {
2842
- timing: "immediate",
2843
- run: (deps) => {
2844
- const scene = deps["scene"];
2845
- if (scene !== void 0) layoutDiagram(scene, opts.source, opts.algorithm ?? "layered", options);
2846
- }
2847
- },
2848
- enabled: () => true
2708
+ return node === void 0 || diagramEdgeOf(node) === null && diagramLabelOf(node) === null && diagramGroupOf(node) === null && diagramContainerOf(node)?.role !== "lane" && sequencePartOf(node) === null;
2849
2709
  };
2850
2710
  }
2851
2711
  var EASE_FRAMES = 24;
@@ -2880,14 +2740,14 @@ function forceProducer(graph, opts = {}) {
2880
2740
  }
2881
2741
  relaxation.sim.alphaTarget(pinned.size > 0 ? dragAlpha : 0);
2882
2742
  relaxation.sim.tick();
2883
- let moved = 0;
2743
+ let moved2 = 0;
2884
2744
  relaxation.bodies.forEach((body, i) => {
2885
2745
  const at = was[i];
2886
- moved = Math.max(moved, Math.hypot(body.x - at.x, body.y - at.y));
2746
+ moved2 = Math.max(moved2, Math.hypot(body.x - at.x, body.y - at.y));
2887
2747
  at.x = body.x;
2888
2748
  at.y = body.y;
2889
2749
  });
2890
- still = pinned.size === 0 && moved < restDistance ? still + 1 : 0;
2750
+ still = pinned.size === 0 && moved2 < restDistance ? still + 1 : 0;
2891
2751
  const done = still >= restTicks || relaxation.sim.isSettled();
2892
2752
  return { result: relaxation.placed(), done };
2893
2753
  };
@@ -3143,7 +3003,7 @@ function useLiveLayout(opts) {
3143
3003
  const o = optsRef.current;
3144
3004
  producerFrame.current = 0;
3145
3005
  held.current = false;
3146
- routes.current = routesOf(graph, plan ?? { });
3006
+ routes.current = routesOf(graph, plan ?? { moves: /* @__PURE__ */ new Map() });
3147
3007
  eased.set(routeEasings(o.scene, graph, routes.current));
3148
3008
  producer.current = producerFor(graph, plan, o);
3149
3009
  }, [optsRef, eased]);
@@ -3168,9 +3028,9 @@ function useLiveLayout(opts) {
3168
3028
  scene: opts.scene,
3169
3029
  step,
3170
3030
  // Eased routes go once the routes are in the document, so no frame shows the old ones.
3171
- onCommit: (moved) => {
3031
+ onCommit: (moved2) => {
3172
3032
  eased.drop();
3173
- optsRef.current.onSettle?.(moved);
3033
+ optsRef.current.onSettle?.(moved2);
3174
3034
  },
3175
3035
  // Routes match where the layout was going, so only a run that got there
3176
3036
  // with nothing held along the way writes them.
@@ -3237,7 +3097,8 @@ function useLiveLayout(opts) {
3237
3097
  var EASED_LAYOUTS = Object.freeze({
3238
3098
  layered,
3239
3099
  tree,
3240
- chain
3100
+ chain,
3101
+ grid
3241
3102
  });
3242
3103
  function bodyRules(trait, box) {
3243
3104
  const layout = trait.body;
@@ -3254,7 +3115,7 @@ function bodyRules(trait, box) {
3254
3115
  // src/shape.ts
3255
3116
  function diagramShape(opts = {}) {
3256
3117
  const geometry = opts.geometry ?? RECT_POSE_DESCRIPTOR;
3257
- const outlineOf2 = (node) => diagramNodeOf(node, opts.read)?.outline ?? laneOutlineOf(node);
3118
+ const outlineOf2 = (node) => diagramNodeOf(node, opts.read)?.outline ?? laneOutlineOf(node) ?? sequenceOutlineOf(node);
3258
3119
  return {
3259
3120
  id: opts.id ?? "diagram:outline",
3260
3121
  matches: (node) => outlineOf2(node) !== void 0,
@@ -3271,6 +3132,9 @@ function diagramShape(opts = {}) {
3271
3132
  const divider = header === null || !stroke ? [] : [{ kind: "path", path: dividerPath(box, header), stroke }];
3272
3133
  const detailPath = stroke ? outlineDetail(outline, box) : null;
3273
3134
  const detail = stroke && detailPath ? [{ kind: "path", path: detailPath, stroke }] : [];
3135
+ const solidPath = declaredStroke ? outlineSolid(outline, box) : null;
3136
+ const solidFill = declaredStroke && solidPath ? commandFill({ paint: declaredStroke.paint }, box) : null;
3137
+ const solid = solidPath && solidFill ? [{ kind: "path", path: solidPath, fill: solidFill }] : [];
3274
3138
  const trait = diagramNodeOf(node, opts.read);
3275
3139
  const rules = stroke && trait !== null ? bodyRules(trait, box).map((path) => ({ kind: "path", path, stroke })) : [];
3276
3140
  return [{
@@ -3278,7 +3142,7 @@ function diagramShape(opts = {}) {
3278
3142
  path: outlinePath(outline, box),
3279
3143
  ...fill ? { fill } : {},
3280
3144
  ...stroke ? { stroke } : {}
3281
- }, ...detail, ...rules, ...divider];
3145
+ }, ...solid, ...detail, ...rules, ...divider];
3282
3146
  },
3283
3147
  // The drawn boundary, so picking and clipping follow the diamond rather
3284
3148
  // than its bounding box.
@@ -3288,6 +3152,10 @@ function diagramShape(opts = {}) {
3288
3152
  }
3289
3153
  };
3290
3154
  }
3155
+ function sequenceOutlineOf(node) {
3156
+ if (sequencePartOf(node) === null) return void 0;
3157
+ return node.data.diagram?.outline;
3158
+ }
3291
3159
  function dividerPath(box, header) {
3292
3160
  return header.width < box.width ? polylineFromPoints([{ x: header.x + header.width, y: box.y }, { x: header.x + header.width, y: box.y + box.height }]) : polylineFromPoints([{ x: box.x, y: header.y + header.height }, { x: box.x + box.width, y: header.y + header.height }]);
3293
3161
  }
@@ -3298,6 +3166,1348 @@ function registerDiagramShape(opts = {}) {
3298
3166
  // src/bodyNode.ts
3299
3167
  var isDiagramBody = (node) => diagramContainerOf(node) === null && diagramGroupOf(node) === null && dataKeyReader(node) !== null;
3300
3168
  var isBodyOrRegion = (node) => diagramContainerOf(node) !== null || isDiagramBody(node);
3169
+
3170
+ // src/sequence/edit.ts
3171
+ var hasId = (s) => "id" in s;
3172
+ function stepListOf(steps, parent) {
3173
+ if (parent === null) return steps;
3174
+ const frag = findStep(steps, parent.fragment);
3175
+ return frag?.kind === "fragment" ? frag.sections[parent.section]?.steps ?? null : null;
3176
+ }
3177
+ function findStep(steps, id) {
3178
+ for (const s of steps) {
3179
+ if (hasId(s) && s.id === id) return s;
3180
+ if (s.kind === "fragment") {
3181
+ for (const section of s.sections) {
3182
+ const found = findStep(section.steps, id);
3183
+ if (found !== null) return found;
3184
+ }
3185
+ }
3186
+ }
3187
+ return null;
3188
+ }
3189
+ function placeOf(steps, id, parent = null) {
3190
+ for (const [index, s] of steps.entries()) {
3191
+ if (hasId(s) && s.id === id) return { parent, index };
3192
+ if (s.kind === "fragment") {
3193
+ for (const [k, section] of s.sections.entries()) {
3194
+ const found = placeOf(section.steps, id, { fragment: s.id, section: k });
3195
+ if (found !== null) return found;
3196
+ }
3197
+ }
3198
+ }
3199
+ return null;
3200
+ }
3201
+ function mapSteps(steps, fn) {
3202
+ let changed = false;
3203
+ const out = steps.map((s) => {
3204
+ let next = fn(s);
3205
+ if (next.kind === "fragment") {
3206
+ const frag = next;
3207
+ const sections = frag.sections.map((section) => {
3208
+ const inner = mapSteps(section.steps, fn);
3209
+ return inner === section.steps ? section : { ...section, steps: inner };
3210
+ });
3211
+ if (sections.some((sec, k) => sec !== frag.sections[k])) next = { ...frag, sections };
3212
+ }
3213
+ if (next !== s) changed = true;
3214
+ return next;
3215
+ });
3216
+ return changed ? out : steps;
3217
+ }
3218
+ function pruneSteps(steps, fn) {
3219
+ let changed = false;
3220
+ const out = [];
3221
+ for (const s of steps) {
3222
+ let step = s;
3223
+ if (s.kind === "fragment") {
3224
+ const sections = s.sections.map((sec) => {
3225
+ const inner = pruneSteps(sec.steps, fn);
3226
+ return inner === sec.steps ? sec : { ...sec, steps: inner };
3227
+ });
3228
+ if (sections.some((sec, k) => sec !== s.sections[k])) step = { ...s, sections };
3229
+ }
3230
+ const next = fn(step);
3231
+ if (next !== s) changed = true;
3232
+ if (next !== null) out.push(next);
3233
+ }
3234
+ return changed ? out : steps;
3235
+ }
3236
+ function withList(steps, parent, fn) {
3237
+ if (parent === null) return fn(steps);
3238
+ return mapSteps(steps, (s) => {
3239
+ if (s.kind !== "fragment" || s.id !== parent.fragment) return s;
3240
+ const sections = s.sections.map((sec, k) => k === parent.section ? { ...sec, steps: fn(sec.steps) } : sec);
3241
+ return { ...s, sections };
3242
+ });
3243
+ }
3244
+ var contains = (step, id) => step.kind === "fragment" && step.sections.some((sec) => sec.steps.some((s) => hasId(s) && s.id === id || contains(s, id)));
3245
+ function moveStep(data, id, to) {
3246
+ const from = placeOf(data.steps, id);
3247
+ const step = findStep(data.steps, id);
3248
+ if (from === null || step === null) return data;
3249
+ if (to.parent !== null && (to.parent.fragment === id || contains(step, to.parent.fragment))) return data;
3250
+ if (stepListOf(data.steps, to.parent) === null) return data;
3251
+ const sameList = JSON.stringify(from.parent) === JSON.stringify(to.parent);
3252
+ if (sameList && (to.index === from.index || to.index === from.index + 1)) return data;
3253
+ const removed = withList(data.steps, from.parent, (list) => list.filter((_, i) => i !== from.index));
3254
+ const index = sameList && to.index > from.index ? to.index - 1 : to.index;
3255
+ const steps = withList(removed, to.parent, (list) => [...list.slice(0, index), step, ...list.slice(index)]);
3256
+ return { ...data, steps };
3257
+ }
3258
+ function moveParticipant(data, id, index) {
3259
+ const from = data.participants.findIndex((p2) => p2.id === id);
3260
+ if (from < 0 || index === from || index === from + 1) return data;
3261
+ const p = data.participants[from];
3262
+ const rest = data.participants.filter((_, i) => i !== from);
3263
+ const at = index > from ? index - 1 : index;
3264
+ return { ...data, participants: [...rest.slice(0, at), p, ...rest.slice(at)] };
3265
+ }
3266
+ function reconnectMessage(data, id, end, participant) {
3267
+ const step = findStep(data.steps, id);
3268
+ if (step?.kind !== "message" || step[end] === participant || !data.participants.some((p) => p.id === participant)) return data;
3269
+ return { ...data, steps: mapSteps(data.steps, (s) => s === step ? { ...step, [end]: participant } : s) };
3270
+ }
3271
+ function setSequenceText(data, target, text) {
3272
+ if ("participant" in target) {
3273
+ const at = data.participants.findIndex((p2) => p2.id === target.participant);
3274
+ const p = data.participants[at];
3275
+ if (p === void 0 || (p.label ?? p.id) === text) return data;
3276
+ const { label: _label, ...rest } = p;
3277
+ const next = text === "" || text === p.id ? rest : { ...rest, label: text };
3278
+ return { ...data, participants: data.participants.map((q, i) => i === at ? next : q) };
3279
+ }
3280
+ if ("box" in target) {
3281
+ const boxes = data.boxes?.map((b) => {
3282
+ if (b.id !== target.box || (b.label ?? "") === text) return b;
3283
+ const { label: _label, ...rest } = b;
3284
+ return text === "" ? rest : { ...rest, label: text };
3285
+ });
3286
+ return boxes === void 0 || boxes.every((b, i) => b === data.boxes[i]) ? data : { ...data, boxes };
3287
+ }
3288
+ if ("fragment" in target) {
3289
+ const steps2 = mapSteps(data.steps, (s) => {
3290
+ if (s.kind !== "fragment" || s.id !== target.fragment) return s;
3291
+ const section = s.sections[target.section];
3292
+ if (section === void 0 || (section.label ?? "") === text) return s;
3293
+ const { label: _label, ...rest } = section;
3294
+ const next = text === "" ? rest : { ...rest, label: text };
3295
+ return { ...s, sections: s.sections.map((sec, k) => k === target.section ? next : sec) };
3296
+ });
3297
+ return steps2 === data.steps ? data : { ...data, steps: steps2 };
3298
+ }
3299
+ const steps = mapSteps(data.steps, (s) => {
3300
+ if (s.kind === "note" && s.id === target.step && s.text !== text) return { ...s, text };
3301
+ if (s.kind !== "message" || s.id !== target.step || (s.text ?? "") === text) return s;
3302
+ const { text: _text, ...rest } = s;
3303
+ return text === "" ? rest : { ...rest, text };
3304
+ });
3305
+ return steps === data.steps ? data : { ...data, steps };
3306
+ }
3307
+ function sequenceTextOf(data, target) {
3308
+ if ("participant" in target) {
3309
+ const p = data.participants.find((q) => q.id === target.participant);
3310
+ return p === void 0 ? null : p.label ?? p.id;
3311
+ }
3312
+ if ("box" in target) {
3313
+ const b = data.boxes?.find((q) => q.id === target.box);
3314
+ return b === void 0 ? null : b.label ?? "";
3315
+ }
3316
+ if ("fragment" in target) {
3317
+ const f = findStep(data.steps, target.fragment);
3318
+ const section = f?.kind === "fragment" ? f.sections[target.section] : void 0;
3319
+ return section === void 0 ? null : section.label ?? "";
3320
+ }
3321
+ const s = findStep(data.steps, target.step);
3322
+ return s?.kind === "message" ? s.text ?? "" : s?.kind === "note" ? s.text : null;
3323
+ }
3324
+
3325
+ // src/sequence/metrics.ts
3326
+ var SEQ = {
3327
+ /** Around the whole diagram. */
3328
+ margin: 12,
3329
+ /** Between a head's outline and its text. */
3330
+ headPad: 10,
3331
+ headMinWidth: 80,
3332
+ headMinHeight: 36,
3333
+ /** The least room between two heads. */
3334
+ columnGap: 32,
3335
+ /** Either side of a message's text along its line. */
3336
+ textPad: 10,
3337
+ /** Above every row. */
3338
+ rowGap: 14,
3339
+ /** Between a message's text and its line. */
3340
+ textGap: 3,
3341
+ /** A self-message's loop: how far it reaches right, and how tall it is. */
3342
+ loopWidth: 32,
3343
+ loopHeight: 20,
3344
+ /** An activation bar's width, and how far each nested one steps right. */
3345
+ barWidth: 10,
3346
+ barStep: 5,
3347
+ notePad: 6,
3348
+ noteMinWidth: 60,
3349
+ /** Between a lifeline and a note beside it. */
3350
+ noteGap: 10,
3351
+ /** How far a note over two lifelines reaches past them. */
3352
+ noteOverhang: 16,
3353
+ /** Between a fragment's box and the lifelines it holds, and between nested boxes. */
3354
+ fragmentPad: 14,
3355
+ fragmentNest: 8,
3356
+ /** Around a fragment's type label in its tab. */
3357
+ tabPad: 6,
3358
+ /** Between a box's border and the heads it holds. */
3359
+ boxPad: 10,
3360
+ /** Below the last row. */
3361
+ footer: 16,
3362
+ /** The X at a destroyed lifeline's end. */
3363
+ cross: 12
3364
+ };
3365
+ function seqMeasure(measure, font = DEFAULT_FONT) {
3366
+ const line = measure ?? ((text, s) => {
3367
+ const size = s.fontSize ?? font.fontSize;
3368
+ return { width: text.length * GLYPH * size, height: Math.ceil(1.4 * size) };
3369
+ });
3370
+ return {
3371
+ font,
3372
+ text: (text, style = {}) => {
3373
+ const s = { ...style, fontFamily: style.fontFamily ?? font.fontFamily, fontSize: style.fontSize ?? font.fontSize };
3374
+ const sizes = text.split("\n").map((l) => line(l, s));
3375
+ return { width: Math.max(0, ...sizes.map((z) => z.width)), height: sizes.reduce((h, z) => h + z.height, 0) };
3376
+ }
3377
+ };
3378
+ }
3379
+ function headSize(p, m) {
3380
+ const t = m.text(p.label ?? p.id);
3381
+ const outline = p.outline ?? "rect";
3382
+ const box = boxForContent(outline, { width: t.width + SEQ.headPad * 2, height: t.height + SEQ.headPad * 2 });
3383
+ return { width: Math.max(SEQ.headMinWidth, Math.ceil(box.width)), height: Math.max(SEQ.headMinHeight, Math.ceil(box.height)) };
3384
+ }
3385
+
3386
+ // src/sequence/columns.ts
3387
+ function* flatSteps(steps) {
3388
+ for (const s of steps) {
3389
+ yield s;
3390
+ if (s.kind === "fragment") for (const section of s.sections) yield* flatSteps(section.steps);
3391
+ }
3392
+ }
3393
+ function noteNeeds(over, side, width, half) {
3394
+ const [a, b] = [Math.min(...over), Math.max(...over)];
3395
+ const room = width + SEQ.noteGap * 2;
3396
+ if (side === "right") return [{ a, b: a + 1, room: room + half(a + 1) }];
3397
+ if (side === "left") return [{ a: a - 1, b: a, room: room + half(a - 1) }];
3398
+ if (a === b) return [{ a: a - 1, b: a, room: width / 2 + half(a - 1) + SEQ.noteGap }, { a, b: a + 1, room: width / 2 + half(a + 1) + SEQ.noteGap }];
3399
+ return [{ a, b, room: width - SEQ.noteOverhang * 2 }];
3400
+ }
3401
+ function needsOf(data, m, index, half) {
3402
+ const out = [];
3403
+ const numbered = data.autonumber !== void 0;
3404
+ for (const s of flatSteps(data.steps)) {
3405
+ if (s.kind === "message") {
3406
+ const a = index.get(s.from);
3407
+ const b = index.get(s.to);
3408
+ if (a === void 0 || b === void 0) continue;
3409
+ const text = (s.text ?? "") === "" ? 0 : m.text(s.text).width;
3410
+ const room = text + SEQ.textPad * 2 + SEQ.barWidth * 2 + (numbered ? SEQ.textPad * 2 : 0);
3411
+ if (a === b) out.push({ a, b: a + 1, room: SEQ.loopWidth + room + half(a + 1) });
3412
+ else out.push({ a: Math.min(a, b), b: Math.max(a, b), room });
3413
+ } else if (s.kind === "note") {
3414
+ const over = s.over.map((id) => index.get(id)).filter((i) => i !== void 0);
3415
+ if (over.length > 0) out.push(...noteNeeds(over, s.side, Math.max(SEQ.noteMinWidth, m.text(s.text).width + SEQ.notePad * 2), half));
3416
+ }
3417
+ }
3418
+ return out;
3419
+ }
3420
+ function columnsOf(data, m, left) {
3421
+ const ps = data.participants;
3422
+ const heads = ps.map((p) => headSize(p, m));
3423
+ const index = new Map(ps.map((p, i) => [p.id, i]));
3424
+ const boxOf = /* @__PURE__ */ new Map();
3425
+ for (const b of data.boxes ?? []) for (const id of b.members) if (!boxOf.has(id)) boxOf.set(id, b.id);
3426
+ const half = (i) => (heads[i]?.width ?? 0) / 2;
3427
+ const boxPad = (i) => i >= 0 && i < ps.length && boxOf.has(ps[i].id) ? SEQ.boxPad : 0;
3428
+ const gaps = Array.from({ length: ps.length + 1 }, (_, i) => {
3429
+ if (i === 0) return half(0) + boxPad(0);
3430
+ if (i === ps.length) return half(i - 1) + boxPad(i - 1);
3431
+ const split = boxOf.get(ps[i - 1].id) !== boxOf.get(ps[i].id);
3432
+ return half(i - 1) + half(i) + SEQ.columnGap + (split ? boxPad(i - 1) + boxPad(i) : 0);
3433
+ });
3434
+ const needs = needsOf(data, m, index, half).sort((p, q) => p.b - p.a - (q.b - q.a));
3435
+ for (const { a, b, room } of needs) {
3436
+ const lo = Math.max(a, -1) + 1;
3437
+ const hi = Math.min(b, ps.length) + 1;
3438
+ let have = 0;
3439
+ for (let i = lo; i < hi; i++) have += gaps[i];
3440
+ const lack = room - have;
3441
+ if (lack > 0) for (let i = lo; i < hi; i++) gaps[i] += lack / (hi - lo);
3442
+ }
3443
+ const x = [];
3444
+ let at = left;
3445
+ for (let i = 0; i < ps.length; i++) {
3446
+ at += gaps[i];
3447
+ x.push(at);
3448
+ }
3449
+ return { x, heads, right: at + gaps[ps.length] };
3450
+ }
3451
+
3452
+ // src/sequence/rows.ts
3453
+ var spanOf = (rects) => {
3454
+ const x0 = Math.min(...rects.map((r) => r.x));
3455
+ return { x0, x1: Math.max(...rects.map((r) => r.x + r.width)) };
3456
+ };
3457
+ var RowWalk = class {
3458
+ constructor(data, m, cols, top) {
3459
+ this.data = data;
3460
+ this.m = m;
3461
+ this.cols = cols;
3462
+ this.index = new Map(data.participants.map((p, i) => [p.id, i]));
3463
+ this.created = new Set(flatMarks(data.steps, "create"));
3464
+ this.number = data.autonumber;
3465
+ const shown = data.participants.filter((p) => !this.created.has(p.id));
3466
+ const tall = Math.max(SEQ.headMinHeight, ...shown.map((p) => cols.heads[this.index.get(p.id)].height));
3467
+ for (const p of shown) this.placeHead(p.id, top + tall - cols.heads[this.index.get(p.id)].height, false);
3468
+ for (const l of this.lifeline.values()) l.y0 = top + tall;
3469
+ this.y = top + tall;
3470
+ }
3471
+ data;
3472
+ m;
3473
+ cols;
3474
+ out = { heads: [], lifelines: [], messages: [], activations: [], notes: [], fragments: [], slots: [], bottom: 0 };
3475
+ index;
3476
+ created;
3477
+ lifeline = /* @__PURE__ */ new Map();
3478
+ bars = /* @__PURE__ */ new Map();
3479
+ /** Lifelines a `destroy` ends at the next message to them, each with where it ends if none comes. */
3480
+ destroying = /* @__PURE__ */ new Map();
3481
+ frames = [];
3482
+ last = null;
3483
+ number;
3484
+ y;
3485
+ cx(id) {
3486
+ return this.cols.x[this.index.get(id)];
3487
+ }
3488
+ headRect(id) {
3489
+ const size = this.cols.heads[this.index.get(id)];
3490
+ return { x: this.cx(id) - size.width / 2, y: 0, width: size.width, height: 0 };
3491
+ }
3492
+ placeHead(id, y, created) {
3493
+ const size = this.cols.heads[this.index.get(id)];
3494
+ this.out.heads.push({ id, box: { x: this.cx(id) - size.width / 2, y, width: size.width, height: size.height }, created });
3495
+ const line = { id, x: this.cx(id), y0: y + size.height, y1: null };
3496
+ this.lifeline.set(id, line);
3497
+ this.out.lifelines.push(line);
3498
+ return y + size.height;
3499
+ }
3500
+ /** Into every open fragment's reach. */
3501
+ touch(rect) {
3502
+ for (const f of this.frames) f.push(rect);
3503
+ }
3504
+ /** Where a line meets `id`'s lifeline from `side`: the edge of its innermost open activation. */
3505
+ endX(id, side) {
3506
+ const depth = this.bars.get(id)?.length ?? 0;
3507
+ if (depth === 0) return this.cx(id);
3508
+ return this.cx(id) + side * (SEQ.barWidth / 2) + (depth - 1) * SEQ.barStep;
3509
+ }
3510
+ open(id, y, opener) {
3511
+ const stack = this.bars.get(id) ?? [];
3512
+ stack.push({ y, opener });
3513
+ this.bars.set(id, stack);
3514
+ }
3515
+ close(id, y, closer) {
3516
+ const stack = this.bars.get(id);
3517
+ const bar = stack?.pop();
3518
+ if (bar === void 0) return;
3519
+ const start = bar.y;
3520
+ const depth = stack.length;
3521
+ const x = this.cx(id) - SEQ.barWidth / 2 + depth * SEQ.barStep;
3522
+ const box = { x, y: start, width: SEQ.barWidth, height: Math.max(y, start + 8) - start };
3523
+ this.out.activations.push({ participant: id, depth, box, opener: bar.opener, ...closer ? { closer } : {} });
3524
+ }
3525
+ steps(list, parent) {
3526
+ list.forEach((step, index) => {
3527
+ this.out.slots.push({ y: this.y, place: { parent, index } });
3528
+ if (step.kind === "message") this.message(step);
3529
+ else if (step.kind === "note") this.note(step);
3530
+ else if (step.kind === "fragment") this.fragment(step);
3531
+ else this.mark(step, { parent, index });
3532
+ });
3533
+ this.out.slots.push({ y: this.y, place: { parent, index: list.length } });
3534
+ }
3535
+ message(s) {
3536
+ if (!this.index.has(s.from) || !this.index.has(s.to)) return;
3537
+ this.y += SEQ.rowGap;
3538
+ const text = (s.text ?? "") === "" ? null : this.m.text(s.text);
3539
+ const lineY = this.y + Math.max(text === null ? 0 : text.height + SEQ.textGap, 6);
3540
+ if (s.activate !== void 0) this.open(s[s.activate], lineY, { message: s.id, flag: "activate" });
3541
+ const self = s.from === s.to;
3542
+ const dir = self ? 1 : Math.sign(this.cx(s.to) - this.cx(s.from));
3543
+ const x1 = this.endX(s.from, dir);
3544
+ const x2 = self ? x1 : this.endX(s.to, -dir);
3545
+ const place2 = { id: s.id, y: lineY, x1, x2 };
3546
+ if (self) place2.loopY = lineY + SEQ.loopHeight;
3547
+ if (text !== null) {
3548
+ const x = self ? x1 + SEQ.textGap + 2 : (x1 + x2) / 2 - text.width / 2;
3549
+ place2.text = { x, y: lineY - SEQ.textGap - text.height, ...text };
3550
+ this.touch(place2.text);
3551
+ }
3552
+ if (this.number !== void 0) {
3553
+ const n = this.m.text(String(this.number), { fontSize: Math.max(8, this.m.font.fontSize - 2) });
3554
+ const d = Math.max(16, n.width + 6);
3555
+ place2.number = { n: this.number++, box: { x: x1 - d / 2, y: lineY - d / 2, width: d, height: d } };
3556
+ }
3557
+ this.out.messages.push(place2);
3558
+ this.touch(this.headRect(s.from));
3559
+ this.touch(this.headRect(s.to));
3560
+ if (self) this.touch({ x: x1, y: lineY, width: SEQ.loopWidth, height: 0 });
3561
+ if (s.deactivate !== void 0) this.close(s[s.deactivate], self ? place2.loopY : lineY, { message: s.id, flag: "deactivate" });
3562
+ for (const id of /* @__PURE__ */ new Set([s.from, s.to])) {
3563
+ if (!this.destroying.delete(id)) continue;
3564
+ const line = this.lifeline.get(id);
3565
+ if (line !== void 0) line.y1 = self ? place2.loopY : lineY;
3566
+ }
3567
+ this.y = place2.loopY ?? lineY;
3568
+ this.last = { y: this.y, ends: [s.from, s.to] };
3569
+ }
3570
+ note(s) {
3571
+ const over = s.over.filter((id) => this.index.has(id));
3572
+ if (over.length === 0) return;
3573
+ this.y += SEQ.rowGap;
3574
+ const t = this.m.text(s.text);
3575
+ const width = Math.max(SEQ.noteMinWidth, t.width + SEQ.notePad * 2);
3576
+ const height = t.height + SEQ.notePad * 2;
3577
+ const xs = over.map((id) => this.cx(id));
3578
+ const [lo, hi] = [Math.min(...xs), Math.max(...xs)];
3579
+ const x = s.side === "right" ? lo + SEQ.barWidth / 2 + SEQ.noteGap : s.side === "left" ? lo - SEQ.barWidth / 2 - SEQ.noteGap - width : lo === hi ? lo - width / 2 : Math.min(lo - SEQ.noteOverhang, (lo + hi) / 2 - width / 2);
3580
+ const box = { x, y: this.y, width: s.side === void 0 && lo !== hi ? Math.max(width, hi - lo + SEQ.noteOverhang * 2) : width, height };
3581
+ this.out.notes.push({ id: s.id, box });
3582
+ this.touch(box);
3583
+ for (const id of over) this.touch(this.headRect(id));
3584
+ this.y += height;
3585
+ this.last = null;
3586
+ }
3587
+ mark(s, at) {
3588
+ if (!this.index.has(s.participant)) return;
3589
+ this.touch(this.headRect(s.participant));
3590
+ const y = this.last?.ends.includes(s.participant) ? this.last.y : this.y + SEQ.rowGap / 2;
3591
+ if (s.kind === "activate") this.open(s.participant, y, { place: at });
3592
+ else if (s.kind === "deactivate") this.close(s.participant, y, { place: at });
3593
+ else if (s.kind === "destroy") {
3594
+ this.destroying.set(s.participant, this.last?.ends.includes(s.participant) ? this.last.y : null);
3595
+ const line = this.lifeline.get(s.participant);
3596
+ if (line !== void 0) line.destroyedBy = at;
3597
+ } else if (this.out.heads.every((h) => h.id !== s.participant)) {
3598
+ this.y = this.placeHead(s.participant, this.y + SEQ.rowGap, true);
3599
+ this.last = null;
3600
+ }
3601
+ }
3602
+ fragment(s) {
3603
+ this.y += SEQ.rowGap;
3604
+ const top = this.y;
3605
+ const tabText = s.type === "region" ? null : this.m.text(s.type, { bold: true });
3606
+ const tab = tabText === null ? null : { width: tabText.width + SEQ.tabPad * 2, height: tabText.height + SEQ.tabPad };
3607
+ const labels = s.sections.map((sec) => (sec.label ?? "") === "" ? null : this.m.text(sec.label));
3608
+ this.y += Math.max(tab?.height ?? 0, (labels[0]?.height ?? 0) + 4, 8);
3609
+ const frame = [];
3610
+ this.frames.push(frame);
3611
+ const sections = [];
3612
+ s.sections.forEach((sec, k) => {
3613
+ if (k > 0) {
3614
+ this.y += SEQ.rowGap / 2;
3615
+ sections.push({ y: this.y, height: 0 });
3616
+ this.y += (labels[k]?.height ?? 0) + 4;
3617
+ } else sections.push({ y: top, height: 0 });
3618
+ this.steps(sec.steps, { fragment: s.id, section: k });
3619
+ this.last = null;
3620
+ });
3621
+ this.frames.pop();
3622
+ this.y += SEQ.rowGap / 2;
3623
+ const reach = frame.length > 0 ? spanOf(frame) : { x0: this.cols.x[0] ?? 0, x1: this.cols.x.at(-1) ?? 0 };
3624
+ const minWidth = (tab?.width ?? 0) + (labels[0]?.width ?? 0) + SEQ.tabPad * 4;
3625
+ const x0 = reach.x0 - SEQ.fragmentPad / 2;
3626
+ const width = Math.max(reach.x1 - reach.x0 + SEQ.fragmentPad, minWidth);
3627
+ const box = { x: x0, y: top, width, height: this.y - top };
3628
+ const place2 = {
3629
+ id: s.id,
3630
+ type: s.type,
3631
+ box,
3632
+ sections: sections.map((sec, k) => {
3633
+ const l = labels[k];
3634
+ if (l === null || l === void 0) return { y: sec.y };
3635
+ const label = k === 0 ? { x: x0 + (tab?.width ?? 0) + SEQ.tabPad * 2, y: top + 2, ...l } : { x: x0 + width / 2 - l.width / 2, y: sec.y + 2, ...l };
3636
+ return { y: sec.y, label };
3637
+ })
3638
+ };
3639
+ if (tab !== null) place2.tab = { x: x0, y: top, ...tab };
3640
+ this.out.fragments.push(place2);
3641
+ this.touch({ x: box.x - SEQ.fragmentNest, y: top, width: box.width + SEQ.fragmentNest * 2, height: 0 });
3642
+ }
3643
+ };
3644
+ function flatMarks(steps, kind) {
3645
+ const out = [];
3646
+ for (const s of steps) {
3647
+ if (s.kind === kind) out.push(s.participant);
3648
+ if (s.kind === "fragment") for (const sec of s.sections) out.push(...flatMarks(sec.steps, kind));
3649
+ }
3650
+ return out;
3651
+ }
3652
+ function walkRows(data, m, cols, top) {
3653
+ const walk = new RowWalk(data, m, cols, top);
3654
+ walk.steps(data.steps, null);
3655
+ const bottom = walk.y + SEQ.rowGap;
3656
+ for (const [id, fallback] of walk.destroying) {
3657
+ const line = walk.lifeline.get(id);
3658
+ if (line !== void 0) line.y1 = fallback ?? bottom;
3659
+ }
3660
+ for (const [id, stack] of walk.bars) while (stack.length > 0) walk.close(id, bottom + SEQ.footer);
3661
+ walk.out.bottom = bottom;
3662
+ return walk.out;
3663
+ }
3664
+
3665
+ // src/sequence/layout.ts
3666
+ function unionRect(rects) {
3667
+ if (rects.length === 0) return null;
3668
+ const x = Math.min(...rects.map((r) => r.x));
3669
+ const y = Math.min(...rects.map((r) => r.y));
3670
+ return {
3671
+ x,
3672
+ y,
3673
+ width: Math.max(...rects.map((r) => r.x + r.width)) - x,
3674
+ height: Math.max(...rects.map((r) => r.y + r.height)) - y
3675
+ };
3676
+ }
3677
+ function sequenceLayout(data, opts = {}) {
3678
+ const m = seqMeasure(opts.measure, opts.font);
3679
+ const boxLabelHeight = Math.max(0, ...(data.boxes ?? []).map((b) => (b.label ?? "") === "" ? 0 : m.text(b.label).height + 4));
3680
+ const cols = columnsOf(data, m, SEQ.margin);
3681
+ const top = SEQ.margin + (data.boxes?.length ? SEQ.boxPad : 0) + boxLabelHeight;
3682
+ const rows = walkRows(data, m, cols, top);
3683
+ const columns = data.participants.map((p, i) => ({ id: p.id, x: cols.x[i] }));
3684
+ const foot = rows.bottom + SEQ.footer;
3685
+ const lifelines = rows.lifelines.map((l) => ({ ...l, y1: l.y1 ?? foot, destroyed: l.y1 !== null }));
3686
+ const boxes = (data.boxes ?? []).flatMap((b) => {
3687
+ const heads = rows.heads.filter((h) => b.members.includes(h.id)).map((h) => h.box);
3688
+ const around = unionRect(heads);
3689
+ if (around === null) return [];
3690
+ const label = (b.label ?? "") === "" ? null : m.text(b.label);
3691
+ const x = around.x - SEQ.boxPad;
3692
+ const width = around.width + SEQ.boxPad * 2;
3693
+ const y = SEQ.margin;
3694
+ const box = { x, y, width, height: foot + SEQ.boxPad - y };
3695
+ return [{ id: b.id, box, ...label ? { label: { x: x + (width - label.width) / 2, y: y + 2, ...label } } : {} }];
3696
+ });
3697
+ const all = unionRect([
3698
+ ...rows.heads.map((h) => h.box),
3699
+ ...rows.notes.map((n) => n.box),
3700
+ ...rows.fragments.map((f) => f.box),
3701
+ ...boxes.map((b) => b.box),
3702
+ ...rows.messages.flatMap((msg) => msg.text ? [msg.text] : []),
3703
+ { x: 0, y: 0, width: cols.right, height: foot }
3704
+ ]);
3705
+ return {
3706
+ width: Math.ceil(all.x + all.width + SEQ.margin),
3707
+ height: Math.ceil(Math.max(foot, all.y + all.height) + SEQ.margin),
3708
+ columns,
3709
+ heads: rows.heads,
3710
+ lifelines,
3711
+ messages: rows.messages,
3712
+ activations: rows.activations,
3713
+ notes: rows.notes,
3714
+ fragments: rows.fragments,
3715
+ boxes,
3716
+ slots: rows.slots
3717
+ };
3718
+ }
3719
+ var SEQUENCE_ROLES = { note: "warning", number: "accent" };
3720
+ var DASH = [6, 4];
3721
+ var LIFELINE_DASH = [4, 4];
3722
+ var MARKERS = { arrow: "arrow", open: "arrow-open", cross: null, none: null };
3723
+ var PartSpecs = class {
3724
+ constructor(root, at, font) {
3725
+ this.root = root;
3726
+ this.at = at;
3727
+ this.font = font;
3728
+ }
3729
+ root;
3730
+ at;
3731
+ font;
3732
+ specs = [];
3733
+ place(r) {
3734
+ return { x: this.at.x + r.x, y: this.at.y + r.y, width: r.width, height: r.height };
3735
+ }
3736
+ push(id, seq, r, data) {
3737
+ this.specs.push({
3738
+ id: `${this.root}/${id}`,
3739
+ kind: "mark",
3740
+ layer: "main",
3741
+ parent: this.root,
3742
+ pickable: false,
3743
+ pose: this.place(r),
3744
+ data: { ...data, diagram: { ...data.diagram, seq: { root: this.root, ...seq } } }
3745
+ });
3746
+ }
3747
+ body(id, part, of, r, outline, style, dash) {
3748
+ const lines = dash ?? style.dash;
3749
+ this.push(id, { part, ...of !== void 0 ? { id: of } : {} }, r, {
3750
+ diagram: { outline },
3751
+ fill: { paint: { color: style.fill } },
3752
+ stroke: { paint: { color: style.stroke }, width: style.strokeWidth ?? 1.5, ...lines !== void 0 && lines.length > 0 ? { dash: lines } : {} }
3753
+ });
3754
+ }
3755
+ line(id, part, of, r, d, stroke, fill) {
3756
+ this.push(id, { part, ...of !== void 0 ? { id: of } : {} }, r, {
3757
+ diagram: { mark: { d } },
3758
+ stroke,
3759
+ ...fill !== void 0 ? { fill: { paint: { color: fill } } } : {}
3760
+ });
3761
+ }
3762
+ /** The marks the part just pushed draws, onto its trait. */
3763
+ marks(refs) {
3764
+ const seq = this.specs.at(-1).data.diagram.seq;
3765
+ seq.marks = refs;
3766
+ }
3767
+ text(id, r, text, color, target, face = {}, centered = true) {
3768
+ const box = { ...r, x: r.x - 1, width: r.width + 2 };
3769
+ this.push(id, { part: "text", ...target ? { target } : {} }, box, {
3770
+ text,
3771
+ style: { ...this.font, ...centered ? { align: "center" } : {}, ...face },
3772
+ verticalAlign: "center",
3773
+ fill: { paint: { color } }
3774
+ });
3775
+ }
3776
+ };
3777
+ function participantSpecs(out, data, layout, theme) {
3778
+ for (const l of layout.lifelines) {
3779
+ const p = data.participants.find((q) => q.id === l.id);
3780
+ const style = withColors(roleStyle(theme, p.style), p.colors);
3781
+ out.line(
3782
+ `life:${l.id}`,
3783
+ "lifeline",
3784
+ l.id,
3785
+ { x: l.x - 1, y: l.y0, width: 2, height: Math.max(l.y1 - l.y0, 0) },
3786
+ "M0.5 0V1",
3787
+ { paint: { color: style.stroke }, width: 1, dash: LIFELINE_DASH }
3788
+ );
3789
+ if (l.destroyed) {
3790
+ const c = SEQ.cross;
3791
+ out.line(
3792
+ `destroy:${l.id}`,
3793
+ "destroy",
3794
+ l.id,
3795
+ { x: l.x - c / 2, y: l.y1 - c / 2, width: c, height: c },
3796
+ "M0 0L1 1M1 0L0 1",
3797
+ { paint: { color: style.stroke }, width: 2 }
3798
+ );
3799
+ if (l.destroyedBy) out.marks([{ place: l.destroyedBy }]);
3800
+ }
3801
+ }
3802
+ for (const [i, a] of layout.activations.entries()) {
3803
+ const p = data.participants.find((q) => q.id === a.participant);
3804
+ out.body(`act:${i}`, "activation", a.participant, a.box, "rect", withColors(roleStyle(theme, p.style), p.colors));
3805
+ out.marks(a.closer ? [a.opener, a.closer] : [a.opener]);
3806
+ }
3807
+ }
3808
+ function headSpecs(out, data, layout, theme) {
3809
+ for (const h of layout.heads) {
3810
+ const p = data.participants.find((q) => q.id === h.id);
3811
+ const style = withColors(roleStyle(theme, p.style), p.colors);
3812
+ const outline = p.outline ?? "rect";
3813
+ out.body(`head:${p.id}`, "head", p.id, h.box, outline, style);
3814
+ out.text(`head:${p.id}/text`, contentBox(outline, h.box), p.label ?? p.id, style.text, { participant: p.id });
3815
+ }
3816
+ }
3817
+ function messageSpecs(out, steps, layout, theme) {
3818
+ const byId = new Map(layout.messages.map((m) => [m.id, m]));
3819
+ const edge = roleEdgeStyle(theme);
3820
+ const width = edge.width ?? 1.5;
3821
+ for (const msg of flatSteps(steps)) {
3822
+ const at = msg.kind === "message" ? byId.get(msg.id) : void 0;
3823
+ if (at === void 0 || msg.kind !== "message") continue;
3824
+ const s = msg;
3825
+ const marker = MARKERS[msg.head];
3826
+ const stroke = {
3827
+ paint: { color: edge.stroke },
3828
+ width,
3829
+ ...msg.line === "dashed" ? { dash: DASH } : {},
3830
+ ...marker !== null ? { markerEnd: marker } : {},
3831
+ ...marker !== null && msg.both ? { markerStart: marker } : {}
3832
+ };
3833
+ if (at.loopY !== void 0) {
3834
+ out.line(`msg:${s.id}`, "message", s.id, { x: at.x1, y: at.y, width: SEQ.loopWidth, height: at.loopY - at.y }, "M0 0H1V1H0", stroke);
3835
+ } else {
3836
+ const d = at.x2 >= at.x1 ? "M0 0H1" : "M1 0H0";
3837
+ out.line(`msg:${s.id}`, "message", s.id, { x: Math.min(at.x1, at.x2), y: at.y, width: Math.abs(at.x2 - at.x1), height: 0 }, d, stroke);
3838
+ }
3839
+ if (msg.head === "cross") {
3840
+ const c = SEQ.cross * 0.8;
3841
+ const end = { x: at.x2, y: at.loopY ?? at.y };
3842
+ out.line(
3843
+ `msg:${s.id}/cross`,
3844
+ "message",
3845
+ s.id,
3846
+ { x: end.x - c / 2, y: end.y - c / 2, width: c, height: c },
3847
+ "M0 0L1 1M1 0L0 1",
3848
+ { paint: { color: edge.stroke }, width }
3849
+ );
3850
+ }
3851
+ if (at.text) out.text(`msg:${s.id}/text`, at.text, msg.text ?? "", edge.label ?? edge.stroke, { step: s.id }, {}, msg.from !== msg.to);
3852
+ if (at.number) {
3853
+ const style = roleStyle(theme, SEQUENCE_ROLES.number);
3854
+ out.body(`msg:${s.id}/number`, "number", s.id, at.number.box, "ellipse", style);
3855
+ out.text(`msg:${s.id}/number/text`, at.number.box, String(at.number.n), style.text, void 0, { fontSize: Math.max(8, out.font.fontSize - 2) });
3856
+ }
3857
+ }
3858
+ }
3859
+ function noteSpecs(out, steps, layout, theme) {
3860
+ const byId = new Map(layout.notes.map((n) => [n.id, n]));
3861
+ const style = roleStyle(theme, SEQUENCE_ROLES.note);
3862
+ for (const s of flatSteps(steps)) {
3863
+ const at = s.kind === "note" ? byId.get(s.id) : void 0;
3864
+ if (at === void 0 || s.kind !== "note") continue;
3865
+ out.body(`note:${s.id}`, "note", s.id, at.box, "note", style);
3866
+ out.text(`note:${s.id}/text`, contentBox("note", at.box), s.text, style.text, { step: s.id });
3867
+ }
3868
+ }
3869
+ function fragmentSpecs(out, steps, layout, theme, boxesOnly) {
3870
+ const byId = new Map(layout.fragments.map((f) => [f.id, f]));
3871
+ for (const s of flatSteps(steps)) {
3872
+ const at = s.kind === "fragment" ? byId.get(s.id) : void 0;
3873
+ if (at === void 0 || s.kind !== "fragment") continue;
3874
+ const style = withColors({ ...theme.container, ...s.type === "region" ? {} : { fill: "transparent" } }, s.colors);
3875
+ if (boxesOnly) {
3876
+ out.body(`frag:${s.id}`, "fragment", s.id, at.box, "rect", { ...style, strokeWidth: 1 }, []);
3877
+ continue;
3878
+ }
3879
+ at.sections.forEach((sec, k) => {
3880
+ if (k > 0) {
3881
+ out.line(
3882
+ `frag:${s.id}/divider:${k}`,
3883
+ "divider",
3884
+ s.id,
3885
+ { x: at.box.x, y: sec.y, width: at.box.width, height: 0 },
3886
+ "M0 0H1",
3887
+ { paint: { color: style.stroke }, width: 1, dash: DASH }
3888
+ );
3889
+ }
3890
+ if (sec.label) out.text(`frag:${s.id}/label:${k}`, sec.label, s.sections[k].label ?? "", style.text, { fragment: s.id, section: k });
3891
+ });
3892
+ if (at.tab) {
3893
+ out.line(`frag:${s.id}/tab`, "fragment", s.id, at.tab, "M0 0H1V0.6L0.85 1H0Z", { paint: { color: style.stroke }, width: 1 }, theme.container.fill);
3894
+ out.text(`frag:${s.id}/type`, at.tab, s.type, style.text, void 0, { fontWeight: 700 });
3895
+ }
3896
+ }
3897
+ }
3898
+ function boxSpecs(out, data, layout, theme) {
3899
+ for (const b of layout.boxes) {
3900
+ const own = data.boxes?.find((q) => q.id === b.id);
3901
+ const style = withColors(theme.container, own?.colors);
3902
+ out.body(`box:${b.id}`, "box", b.id, b.box, "rect", { ...style, strokeWidth: 1 }, []);
3903
+ if (b.label) out.text(`box:${b.id}/text`, b.label, own?.label ?? "", style.text, { box: b.id });
3904
+ }
3905
+ }
3906
+ var geometryOf = (layout) => ({
3907
+ columns: layout.columns,
3908
+ slots: layout.slots,
3909
+ messages: layout.messages,
3910
+ notes: layout.notes,
3911
+ heads: layout.heads.map(({ id, box }) => ({ id, box })),
3912
+ fragments: layout.fragments.map(({ id, box, tab }) => ({ id, grip: tab ?? { ...box, height: Math.min(box.height, SEQ.rowGap) } })),
3913
+ boxes: layout.boxes.map(({ id, box, label }) => ({ id, grip: { ...box, height: (label?.height ?? 0) + SEQ.boxPad } })),
3914
+ marks: [
3915
+ ...layout.activations.map((a, i) => ({ id: `act:${i}`, grip: a.box })),
3916
+ ...layout.lifelines.flatMap((l) => l.destroyedBy === void 0 ? [] : [{ id: `destroy:${l.id}`, grip: crossGrip(l.x, l.y1) }])
3917
+ ]
3918
+ });
3919
+ var crossGrip = (x, y) => {
3920
+ const c = Math.max(SEQ.cross, 12);
3921
+ return { x: x - c / 2, y: y - c / 2, width: c, height: c };
3922
+ };
3923
+ function sequenceSpecs(data, opts) {
3924
+ const theme = opts.theme ?? diagramThemeFrom(void 0);
3925
+ const font = opts.font ?? themeFont(theme);
3926
+ const layout = sequenceLayout(data, { font, ...opts.measure ? { measure: opts.measure } : {} });
3927
+ const at = opts.at ?? { x: 0, y: 0 };
3928
+ const out = new PartSpecs(opts.id, at, font);
3929
+ out.specs.push({
3930
+ id: opts.id,
3931
+ kind: "mark",
3932
+ layer: "main",
3933
+ pose: out.place({ x: 0, y: 0, width: layout.width, height: layout.height }),
3934
+ data: { diagram: { sequence: data, geometry: geometryOf(layout) } }
3935
+ });
3936
+ boxSpecs(out, data, layout, theme);
3937
+ fragmentSpecs(out, data.steps, layout, theme, true);
3938
+ participantSpecs(out, data, layout, theme);
3939
+ messageSpecs(out, data.steps, layout, theme);
3940
+ noteSpecs(out, data.steps, layout, theme);
3941
+ headSpecs(out, data, layout, theme);
3942
+ fragmentSpecs(out, data.steps, layout, theme, false);
3943
+ const layer = opts.layer ?? "main";
3944
+ return localizeWorldPoses(out.specs, opts.composition ?? RIGID_POSE_COMPOSITION).map((s) => ({ ...s, layer }));
3945
+ }
3946
+ var worldPose = (scene, id) => composeWorldPose(scenePoseAdapter(scene), id, scene.composition.compose);
3947
+ function rebuild(scene, id, data, opts) {
3948
+ const root = scene.get(id);
3949
+ const at = worldPose(scene, id);
3950
+ const [own, ...parts] = sequenceSpecs(data, {
3951
+ id,
3952
+ at,
3953
+ theme: opts.theme ?? diagramThemeOf(scene),
3954
+ layer: root.layer,
3955
+ composition: scene.composition,
3956
+ ...opts.measure ? { measure: opts.measure } : {}
3957
+ });
3958
+ const selected = scene.getSelection();
3959
+ scene.removeMany([...scene.childrenOf(id)]);
3960
+ const pose = root.pose;
3961
+ scene.update(id, { data: own.data });
3962
+ scene.setPose(id, { ...pose, width: own.pose.width, height: own.pose.height });
3963
+ for (const part of parts) scene.add(part);
3964
+ const kept = selected.filter((s) => scene.get(s) !== void 0);
3965
+ if (kept.length !== scene.getSelection().length) scene.setSelection(kept);
3966
+ }
3967
+ function commitSequence(scene, id, data, label, opts = {}) {
3968
+ const node = scene.get(id);
3969
+ if (node === void 0 || sequenceRootOf(node) === null) return;
3970
+ scene.batch(label, () => rebuild(scene, id, data, opts));
3971
+ }
3972
+ function startSequence(scene, at, data, label, opts = {}) {
3973
+ const id = scene.mintId();
3974
+ const layer = opts.layer ?? scene.layers[0]?.id ?? "main";
3975
+ const specs = sequenceSpecs(data, {
3976
+ id,
3977
+ at,
3978
+ theme: opts.theme ?? diagramThemeOf(scene),
3979
+ layer,
3980
+ composition: scene.composition,
3981
+ ...opts.measure ? { measure: opts.measure } : {}
3982
+ });
3983
+ scene.batch(label, () => {
3984
+ for (const spec of specs) scene.add(spec);
3985
+ });
3986
+ return id;
3987
+ }
3988
+ function redrawSequences(scene, opts = {}) {
3989
+ for (const node of scene.renderOrderNodes()) {
3990
+ const root = sequenceRootOf(node);
3991
+ if (root !== null) rebuild(scene, node.id, root.sequence, opts);
3992
+ }
3993
+ }
3994
+ function foldSequenceText(scene, textId, commit) {
3995
+ const node = scene.get(textId);
3996
+ const part = node === void 0 ? null : sequencePartOf(node);
3997
+ const root = part === null ? void 0 : scene.get(part.root);
3998
+ const held = root === void 0 ? null : sequenceRootOf(root);
3999
+ if (part === null || held === null || part.target === void 0) return;
4000
+ const text = node.data.text;
4001
+ if (typeof text !== "string") return;
4002
+ const next = setSequenceText(held.sequence, part.target, text);
4003
+ if (next === held.sequence) return;
4004
+ scene.undo();
4005
+ commit({ id: part.root, data: next, label: "Edit text" });
4006
+ }
4007
+ function sequenceCommitOf(opts) {
4008
+ return opts.commit ?? ((edit, ctx) => {
4009
+ const scene = ctx.deps.scene;
4010
+ if (scene !== void 0) commitSequence(scene, edit.id, edit.data, edit.label, opts);
4011
+ });
4012
+ }
4013
+
4014
+ // src/sequence/author.ts
4015
+ function idsOf(data) {
4016
+ const ids = new Set(data.participants.map((p) => p.id));
4017
+ for (const s of flatSteps(data.steps)) if (hasId(s)) ids.add(s.id);
4018
+ for (const b of data.boxes ?? []) ids.add(b.id);
4019
+ return ids;
4020
+ }
4021
+ var seqIdTaken = (data, id) => idsOf(data).has(id);
4022
+ function freshSeqId(data, prefix) {
4023
+ const ids = idsOf(data);
4024
+ let n = 1;
4025
+ while (ids.has(`${prefix}${n}`)) n++;
4026
+ return `${prefix}${n}`;
4027
+ }
4028
+ function newParticipant(data, kind = "participant") {
4029
+ const id = freshSeqId(data, kind === "actor" ? "A" : "P");
4030
+ const label = `${kind === "actor" ? "Actor" : "Participant"} ${id.slice(1)}`;
4031
+ return { id, label, ...kind === "actor" ? { outline: "actor" } : {} };
4032
+ }
4033
+ function addParticipant(data, p, index = data.participants.length) {
4034
+ if (seqIdTaken(data, p.id)) return data;
4035
+ const at = Math.max(0, Math.min(index, data.participants.length));
4036
+ return { ...data, participants: [...data.participants.slice(0, at), p, ...data.participants.slice(at)] };
4037
+ }
4038
+ function removeParticipant(data, id) {
4039
+ if (!data.participants.some((p) => p.id === id)) return data;
4040
+ const steps = pruneSteps(data.steps, (s) => {
4041
+ if (s.kind === "message") return s.from === id || s.to === id ? null : s;
4042
+ if (s.kind === "note") {
4043
+ if (!s.over.includes(id)) return s;
4044
+ const over = s.over.filter((q) => q !== id);
4045
+ return over.length === 0 ? null : { ...s, over };
4046
+ }
4047
+ if (s.kind === "fragment") return s;
4048
+ return s.participant === id ? null : s;
4049
+ });
4050
+ const boxes = data.boxes?.flatMap((b) => {
4051
+ if (!b.members.includes(id)) return [b];
4052
+ const members2 = b.members.filter((m) => m !== id);
4053
+ return members2.length === 0 ? [] : [{ ...b, members: members2 }];
4054
+ });
4055
+ const { boxes: _boxes, ...rest } = data;
4056
+ return {
4057
+ ...rest,
4058
+ participants: data.participants.filter((p) => p.id !== id),
4059
+ steps,
4060
+ ...boxes !== void 0 && boxes.length > 0 ? { boxes } : {}
4061
+ };
4062
+ }
4063
+ function setParticipantOutline(data, id, outline) {
4064
+ const at = data.participants.findIndex((p2) => p2.id === id);
4065
+ const p = data.participants[at];
4066
+ const next = outline === "rect" ? void 0 : outline;
4067
+ if (p === void 0 || p.outline === next) return data;
4068
+ const { outline: _outline, ...rest } = p;
4069
+ const q = next === void 0 ? rest : { ...rest, outline: next };
4070
+ return { ...data, participants: data.participants.map((r, i) => i === at ? q : r) };
4071
+ }
4072
+ function addBox(data, box) {
4073
+ const members2 = data.participants.filter((p) => box.members.includes(p.id));
4074
+ if (members2.length === 0 || seqIdTaken(data, box.id)) return data;
4075
+ const taken = new Set(members2.map((p) => p.id));
4076
+ const first = data.participants.findIndex((p) => taken.has(p.id));
4077
+ const before = data.participants.slice(0, first).filter((p) => !taken.has(p.id));
4078
+ const after = data.participants.slice(first).filter((p) => !taken.has(p.id));
4079
+ const others = (data.boxes ?? []).flatMap((b) => {
4080
+ const left = b.members.filter((m) => !taken.has(m));
4081
+ return left.length === 0 ? [] : [left.length === b.members.length ? b : { ...b, members: left }];
4082
+ });
4083
+ return {
4084
+ ...data,
4085
+ participants: [...before, ...members2, ...after],
4086
+ boxes: [...others, { ...box, members: members2.map((p) => p.id) }]
4087
+ };
4088
+ }
4089
+ function removeBox(data, id) {
4090
+ if (!data.boxes?.some((b) => b.id === id)) return data;
4091
+ const boxes = data.boxes.filter((b) => b.id !== id);
4092
+ const { boxes: _boxes, ...rest } = data;
4093
+ return boxes.length === 0 ? rest : { ...rest, boxes };
4094
+ }
4095
+ function setAutonumber(data, from) {
4096
+ if (data.autonumber === from) return data;
4097
+ const { autonumber: _n, ...rest } = data;
4098
+ return from === void 0 ? rest : { ...rest, autonumber: from };
4099
+ }
4100
+
4101
+ // src/sequence/authorSteps.ts
4102
+ var SEQ_ARROWS = {
4103
+ /** A call: a solid line, a filled head. */
4104
+ sync: { line: "solid", head: "arrow" },
4105
+ /** An answer: a dashed line, a filled head. */
4106
+ reply: { line: "dashed", head: "arrow" },
4107
+ /** Sent without waiting: a solid line, an open head. */
4108
+ async: { line: "solid", head: "open", async: true },
4109
+ /** Lost or refused: a solid line ending in a cross. */
4110
+ lost: { line: "solid", head: "cross" },
4111
+ /** A plain solid line. */
4112
+ line: { line: "solid", head: "none" },
4113
+ /** A plain dashed line. */
4114
+ dashed: { line: "dashed", head: "none" },
4115
+ /** Both ways: a solid line, filled heads at both ends. */
4116
+ both: { line: "solid", head: "arrow", both: true }
4117
+ };
4118
+ var SEQ_MULTI_SECTION = /* @__PURE__ */ new Set(["alt", "par", "critical"]);
4119
+ function insertStep(data, step, at) {
4120
+ const list = stepListOf(data.steps, at.parent);
4121
+ if (list === null || hasId(step) && seqIdTaken(data, step.id)) return data;
4122
+ const index = Math.max(0, Math.min(at.index, list.length));
4123
+ return { ...data, steps: withList(data.steps, at.parent, (l) => [...l.slice(0, index), step, ...l.slice(index)]) };
4124
+ }
4125
+ var known = (data, ...ids) => ids.every((id) => data.participants.some((p) => p.id === id));
4126
+ function insertMessage(data, m) {
4127
+ if (!known(data, m.from, m.to)) return data;
4128
+ const arrow = typeof m.arrow === "object" ? m.arrow : SEQ_ARROWS[m.arrow ?? "sync"];
4129
+ const step = {
4130
+ kind: "message",
4131
+ id: m.id ?? freshSeqId(data, "m"),
4132
+ from: m.from,
4133
+ to: m.to,
4134
+ ...arrow,
4135
+ ...m.text ? { text: m.text } : {}
4136
+ };
4137
+ return insertStep(data, step, m.at);
4138
+ }
4139
+ function insertNote(data, n) {
4140
+ if (n.over.length === 0 || !known(data, ...n.over)) return data;
4141
+ const step = {
4142
+ kind: "note",
4143
+ id: n.id ?? freshSeqId(data, "n"),
4144
+ over: n.side === void 0 ? [...n.over] : [n.over[0]],
4145
+ ...n.side ? { side: n.side } : {},
4146
+ text: n.text ?? "Note"
4147
+ };
4148
+ return insertStep(data, step, n.at);
4149
+ }
4150
+ function insertMark(data, mark, at) {
4151
+ if (!known(data, mark.participant)) return data;
4152
+ if (mark.kind === "create" && hasMark(data.steps, "create", mark.participant)) return data;
4153
+ return insertStep(data, { kind: mark.kind, participant: mark.participant }, at);
4154
+ }
4155
+ function hasMark(steps, kind, participant) {
4156
+ return steps.some((s) => s.kind === kind && s.participant === participant || s.kind === "fragment" && s.sections.some((sec) => hasMark(sec.steps, kind, participant)));
4157
+ }
4158
+ function removeStep(data, id) {
4159
+ if (findStep(data.steps, id) === null) return data;
4160
+ return { ...data, steps: pruneSteps(data.steps, (s) => hasId(s) && s.id === id ? null : s) };
4161
+ }
4162
+ function removeStepAt(data, at) {
4163
+ const list = stepListOf(data.steps, at.parent);
4164
+ if (list === null || at.index < 0 || at.index >= list.length) return data;
4165
+ return { ...data, steps: withList(data.steps, at.parent, (l) => l.filter((_, i) => i !== at.index)) };
4166
+ }
4167
+ function removeMarks(data, refs) {
4168
+ const key = (p) => p === null ? "" : `${p.fragment}/${p.section}`;
4169
+ const places = refs.flatMap((r) => "place" in r ? [r.place] : []).filter((p) => {
4170
+ const s = stepListOf(data.steps, p.parent)?.[p.index];
4171
+ return s !== void 0 && !hasId(s);
4172
+ }).sort((a, b) => key(a.parent) === key(b.parent) ? b.index - a.index : key(a.parent) < key(b.parent) ? -1 : 1);
4173
+ let next = places.reduce((d, p) => removeStepAt(d, p), data);
4174
+ for (const r of refs) if ("message" in r) next = setMessageActivation(next, r.message, { [r.flag]: void 0 });
4175
+ return next;
4176
+ }
4177
+ function removeMarksOf(data, kind, participant) {
4178
+ const steps = pruneSteps(data.steps, (s) => s.kind === kind && s.participant === participant ? null : s);
4179
+ return steps === data.steps ? data : { ...data, steps };
4180
+ }
4181
+ function wrapSteps(data, parent, start, end, f) {
4182
+ const list = stepListOf(data.steps, parent);
4183
+ const id = f.id ?? freshSeqId(data, "f");
4184
+ if (list === null || seqIdTaken(data, id)) return data;
4185
+ const lo = Math.max(0, Math.min(start, end, list.length));
4186
+ const hi = Math.max(lo, Math.min(Math.max(start, end), list.length));
4187
+ const frag = {
4188
+ kind: "fragment",
4189
+ id,
4190
+ type: f.type,
4191
+ sections: [{ ...f.label ? { label: f.label } : {}, steps: list.slice(lo, hi) }]
4192
+ };
4193
+ return { ...data, steps: withList(data.steps, parent, (l) => [...l.slice(0, lo), frag, ...l.slice(hi)]) };
4194
+ }
4195
+ function unwrapFragment(data, id) {
4196
+ const place2 = placeOf(data.steps, id);
4197
+ const frag = findStep(data.steps, id);
4198
+ if (place2 === null || frag?.kind !== "fragment") return data;
4199
+ const inner = frag.sections.flatMap((sec) => sec.steps);
4200
+ return { ...data, steps: withList(data.steps, place2.parent, (l) => [...l.slice(0, place2.index), ...inner, ...l.slice(place2.index + 1)]) };
4201
+ }
4202
+ function withFragment(data, id, fn) {
4203
+ const steps = mapSteps(data.steps, (s) => s.kind === "fragment" && s.id === id ? fn(s) : s);
4204
+ return steps === data.steps ? data : { ...data, steps };
4205
+ }
4206
+ function addSection(data, id, label, index) {
4207
+ return withFragment(data, id, (f) => {
4208
+ if (!SEQ_MULTI_SECTION.has(f.type)) return f;
4209
+ const at = Math.max(1, Math.min(index ?? f.sections.length, f.sections.length));
4210
+ const section = { ...label ? { label } : {}, steps: [] };
4211
+ return { ...f, sections: [...f.sections.slice(0, at), section, ...f.sections.slice(at)] };
4212
+ });
4213
+ }
4214
+ function removeSection(data, id, index) {
4215
+ return withFragment(data, id, (f) => f.sections.length < 2 || f.sections[index] === void 0 ? f : { ...f, sections: f.sections.filter((_, k) => k !== index) });
4216
+ }
4217
+ function setFragmentType(data, id, type) {
4218
+ return withFragment(data, id, (f) => f.type === type || f.sections.length > 1 && !SEQ_MULTI_SECTION.has(type) ? f : { ...f, type });
4219
+ }
4220
+ function withMessage(data, id, fn) {
4221
+ const steps = mapSteps(data.steps, (s) => s.kind === "message" && s.id === id ? fn(s) : s);
4222
+ return steps === data.steps ? data : { ...data, steps };
4223
+ }
4224
+ function setMessageArrow(data, id, arrow) {
4225
+ const next = typeof arrow === "object" ? arrow : SEQ_ARROWS[arrow];
4226
+ return withMessage(data, id, (m) => {
4227
+ if (m.line === next.line && m.head === next.head && m.both === next.both && m.async === next.async) return m;
4228
+ const { both: _both, async: _async, ...rest } = m;
4229
+ return { ...rest, line: next.line, head: next.head, ...next.both ? { both: true } : {}, ...next.async ? { async: true } : {} };
4230
+ });
4231
+ }
4232
+ function setMessageActivation(data, id, flags) {
4233
+ return withMessage(data, id, (m) => {
4234
+ const activate = "activate" in flags ? flags.activate : m.activate;
4235
+ const deactivate = "deactivate" in flags ? flags.deactivate : m.deactivate;
4236
+ if (activate === m.activate && deactivate === m.deactivate) return m;
4237
+ const { activate: _a, deactivate: _d, ...rest } = m;
4238
+ return { ...rest, ...activate ? { activate } : {}, ...deactivate ? { deactivate } : {} };
4239
+ });
4240
+ }
4241
+ var SEQUENCE_LAYER_ID = "diagram-sequence";
4242
+ var SEQUENCE_AFFORDANCE_KIND = `layer:${SEQUENCE_LAYER_ID}`;
4243
+ function sequenceScratchOf(hit) {
4244
+ const p = hit?.payload;
4245
+ return p !== void 0 && typeof p.root === "string" && typeof p.id === "string" && typeof p.part === "string" ? p : null;
4246
+ }
4247
+ function placedSequences(scene) {
4248
+ const out = [];
4249
+ const poses = scenePoseAdapter(scene);
4250
+ for (const node of scene.renderOrderNodes()) {
4251
+ const root = sequenceRootOf(node);
4252
+ if (root === null || scene.isLocked(node.id) || scene.isHidden(node.id)) continue;
4253
+ const at = composeWorldPose(poses, node.id, scene.composition.compose);
4254
+ out.push({ id: node.id, origin: { x: at.x, y: at.y }, width: at.width, height: at.height, geometry: root.geometry });
4255
+ }
4256
+ return out;
4257
+ }
4258
+ var REACH = 6;
4259
+ var END = 7;
4260
+ var moved = (r, o) => ({ x: r.x + o.x, y: r.y + o.y, width: r.width, height: r.height });
4261
+ function messageReach(m) {
4262
+ const x0 = Math.min(m.x1, m.x2);
4263
+ const x1 = m.loopY !== void 0 ? m.x1 + 32 : Math.max(m.x1, m.x2);
4264
+ const y1 = (m.loopY ?? m.y) + REACH;
4265
+ const top = Math.min(m.y - REACH, m.text?.y ?? Infinity);
4266
+ const left = Math.min(x0, m.text?.x ?? Infinity);
4267
+ const right = Math.max(x1, m.text ? m.text.x + m.text.width : -Infinity);
4268
+ return { x: left, y: top, width: right - left, height: y1 - top };
4269
+ }
4270
+ function region(id, r, scratch, cursor) {
4271
+ return {
4272
+ id,
4273
+ targetId: null,
4274
+ shape: { kind: "rect", x: r.x, y: r.y, width: r.width, height: r.height },
4275
+ cursor,
4276
+ strength: "exclusive",
4277
+ claimedKinds: ["pointer"],
4278
+ bind: () => ({ initialScratch: scratch })
4279
+ };
4280
+ }
4281
+ function regionsOf(all) {
4282
+ const parts = [];
4283
+ const ends = [];
4284
+ for (const { id: root, origin, geometry } of all) {
4285
+ const base = { targetId: root, root };
4286
+ for (const h of geometry.heads) parts.push(region(`${root}/head:${h.id}`, moved(h.box, origin), { ...base, part: "head", id: h.id }, "ew-resize"));
4287
+ for (const m of geometry.marks ?? []) parts.push(region(`${root}/${m.id}`, moved(m.grip, origin), { ...base, part: "mark", id: m.id }, "default"));
4288
+ for (const b of geometry.boxes ?? []) parts.push(region(`${root}/box:${b.id}`, moved(b.grip, origin), { ...base, part: "box", id: b.id }, "default"));
4289
+ for (const f of geometry.fragments ?? []) parts.push(region(`${root}/frag:${f.id}`, moved(f.grip, origin), { ...base, part: "step", id: f.id }, "ns-resize"));
4290
+ for (const n of geometry.notes) parts.push(region(`${root}/note:${n.id}`, moved(n.box, origin), { ...base, part: "step", id: n.id }, "ns-resize"));
4291
+ for (const m of geometry.messages) {
4292
+ parts.push(region(`${root}/msg:${m.id}`, moved(messageReach(m), origin), { ...base, part: "step", id: m.id }, "ns-resize"));
4293
+ const at = [["from", m.x1, m.y], ["to", m.x2, m.loopY ?? m.y]];
4294
+ for (const [end, x, y] of at) {
4295
+ const r = { x: x - END + origin.x, y: y - END + origin.y, width: END * 2, height: END * 2 };
4296
+ ends.push(region(`${root}/msg:${m.id}/${end}`, r, { ...base, part: "end", id: m.id, end }, "crosshair"));
4297
+ }
4298
+ }
4299
+ }
4300
+ return { parts, ends };
4301
+ }
4302
+ var INDEXES = /* @__PURE__ */ new WeakMap();
4303
+ function regionsIn(scene) {
4304
+ let index = INDEXES.get(scene);
4305
+ if (index === void 0) {
4306
+ index = keyedIndex(
4307
+ () => typeof scene.getVersion === "function" ? [scene.getVersion()] : void 0,
4308
+ () => regionsOf(placedSequences(scene))
4309
+ );
4310
+ INDEXES.set(scene, index);
4311
+ }
4312
+ return index() ?? regionsOf(placedSequences(scene));
4313
+ }
4314
+ function sequenceLayer(scene) {
4315
+ const parts = { id: SEQUENCE_LAYER_ID, regions: () => regionsIn(scene).parts };
4316
+ const ends = { id: `${SEQUENCE_LAYER_ID}-ends`, regions: () => regionsIn(scene).ends };
4317
+ return composeAffordanceLayer(SEQUENCE_LAYER_ID, "Sequence diagram parts", [parts, ends]);
4318
+ }
4319
+ var SELECT_SEQUENCE_PART_ACTION_ID = "diagram.sequence.select";
4320
+ function sequencePartNodeOf(scene, s) {
4321
+ if (s.part === "mark") return scene.get(`${s.root}/${s.id}`) === void 0 ? null : `${s.root}/${s.id}`;
4322
+ const names = s.part === "head" ? [`head:${s.id}`] : s.part === "box" ? [`box:${s.id}`] : s.part === "end" ? [`msg:${s.id}`] : [`msg:${s.id}`, `note:${s.id}`, `frag:${s.id}`];
4323
+ return names.map((n) => `${s.root}/${n}`).find((id) => scene.get(id) !== void 0) ?? null;
4324
+ }
4325
+ var selectSequencePartAction = {
4326
+ id: SELECT_SEQUENCE_PART_ACTION_ID,
4327
+ label: "Select sequence part",
4328
+ group: "diagram",
4329
+ requires: ["scene", "selection"],
4330
+ invoker: {
4331
+ timing: "immediate",
4332
+ run(deps, params) {
4333
+ const scene = deps.scene;
4334
+ const selection = deps.selection;
4335
+ const scratch = sequenceScratchOf(params?.affordance);
4336
+ const id = scene === void 0 || scratch === null ? null : sequencePartNodeOf(scene, scratch);
4337
+ if (id === null || selection === void 0) return;
4338
+ const held = selection.get();
4339
+ const shift = params?.mods?.shift === true;
4340
+ selection.set(!shift ? [id] : held.includes(id) ? held.filter((h) => h !== id) : [...held, id]);
4341
+ }
4342
+ },
4343
+ enabled: () => true
4344
+ };
4345
+ function removing(data, part) {
4346
+ if (part.part === "head" || part.part === "lifeline") return removeParticipant(data, part.id);
4347
+ if (part.part === "box") return removeBox(data, part.id);
4348
+ if (part.part === "message" || part.part === "note" || part.part === "fragment" || part.part === "divider") return removeStep(data, part.id);
4349
+ return data;
4350
+ }
4351
+ function sequenceDeletes(scene, ids) {
4352
+ const byRoot = /* @__PURE__ */ new Map();
4353
+ const rest = [];
4354
+ for (const id of ids) {
4355
+ const node = scene.get(id);
4356
+ const part = node === void 0 ? null : sequencePartOf(node);
4357
+ if (part === null) {
4358
+ rest.push(id);
4359
+ continue;
4360
+ }
4361
+ const root = scene.get(part.root);
4362
+ const held = root === void 0 ? null : sequenceRootOf(root);
4363
+ if (held === null) continue;
4364
+ const at = byRoot.get(part.root) ?? { was: held.sequence, marks: [], parts: [] };
4365
+ byRoot.set(part.root, at);
4366
+ if (part.marks !== void 0) at.marks.push(...part.marks);
4367
+ else if (part.id !== void 0) at.parts.push({ part: part.part, id: part.id });
4368
+ }
4369
+ const edits = [...byRoot].flatMap(([id, { was, marks, parts }]) => {
4370
+ const data = parts.reduce(removing, removeMarks(was, marks));
4371
+ return data === was ? [] : [{ id, data }];
4372
+ });
4373
+ return { edits, rest };
4374
+ }
4375
+ function createSequenceDeleteAction(opts = {}) {
4376
+ const commit = sequenceCommitOf(opts);
4377
+ const others = opts.others ?? commitDeleteToScene;
4378
+ return createDeleteAction({
4379
+ commit: (ids, deps) => {
4380
+ const scene = deps.scene;
4381
+ if (scene === void 0) return;
4382
+ const { edits, rest } = sequenceDeletes(scene, ids);
4383
+ for (const edit of edits) commit({ ...edit, label: "Delete" }, { deps });
4384
+ if (rest.length > 0) others(rest, deps);
4385
+ else deps.selection?.set([]);
4386
+ }
4387
+ });
4388
+ }
4389
+
4390
+ // src/sequence/actions.ts
4391
+ var SEQUENCE_DRAG_ACTION_ID = "diagram.sequence.drag";
4392
+ var GRAB_SEQUENCE_ACTION_ID = "diagram.sequence.grab";
4393
+ function carries(s, part) {
4394
+ if (s.part === "head") {
4395
+ if (part.target !== void 0) return "participant" in part.target && part.target.participant === s.id;
4396
+ return part.id === s.id && ["head", "lifeline", "destroy", "activation"].includes(part.part);
4397
+ }
4398
+ if (s.part === "step") {
4399
+ return part.id === s.id || part.target !== void 0 && ("step" in part.target && part.target.step === s.id || "fragment" in part.target && part.target.fragment === s.id);
4400
+ }
4401
+ return s.part === "end" && part.part === "message" && part.id === s.id;
4402
+ }
4403
+ function pressOf2(ctx) {
4404
+ const scratch = sequenceScratchOf(ctx.drag?.affordance);
4405
+ const scene = ctx.deps.scene;
4406
+ const node = scratch === null ? void 0 : scene?.get(scratch.root);
4407
+ const held = node === void 0 ? null : sequenceRootOf(node);
4408
+ const root = scene === void 0 || held === null ? void 0 : placedSequences(scene).find((p) => p.id === scratch.root);
4409
+ if (scratch === null || scene === void 0 || held === null || root === void 0) return null;
4410
+ const carried = /* @__PURE__ */ new Map();
4411
+ for (const id of scene.childrenOf(scratch.root)) {
4412
+ const child = scene.get(id);
4413
+ const part = sequencePartOf(child);
4414
+ if (part !== null && carries(scratch, part)) carried.set(id, child.pose);
4415
+ }
4416
+ return { scratch, scene, root, data: held.sequence, start: ctx.drag?.start ?? { x: ctx.world.x, y: ctx.world.y }, carried };
4417
+ }
4418
+ var nearest = (xs, x) => xs.reduce((best, v, i) => Math.abs(v - x) < Math.abs(xs[best] - x) ? i : best, 0);
4419
+ function proposed(p, at) {
4420
+ const { geometry, origin } = p.root;
4421
+ const local = { x: at.x - origin.x, y: at.y - origin.y };
4422
+ const { scratch } = p;
4423
+ if (scratch.part === "box" || scratch.part === "mark") return { data: p.data, label: "" };
4424
+ if (scratch.part === "head") {
4425
+ const index = geometry.columns.filter((c) => c.x < local.x).length;
4426
+ return { data: moveParticipant(p.data, scratch.id, index), label: "Move participant" };
4427
+ }
4428
+ if (scratch.part === "end") {
4429
+ const column = geometry.columns[nearest(geometry.columns.map((c) => c.x), local.x)];
4430
+ if (column === void 0) return { data: p.data, label: "" };
4431
+ return { data: reconnectMessage(p.data, scratch.id, scratch.end, column.id), label: "Reconnect message" };
4432
+ }
4433
+ const slot = geometry.slots[nearest(geometry.slots.map((s) => s.y), local.y)];
4434
+ if (slot === void 0) return { data: p.data, label: "" };
4435
+ return { data: moveStep(p.data, scratch.id, slot.place), label: "Move step" };
4436
+ }
4437
+ function previewOf(p, id, pose, at) {
4438
+ const dx = at.x - p.start.x;
4439
+ const dy = at.y - p.start.y;
4440
+ if (p.scratch.part === "head") return { ...pose, x: pose.x + dx };
4441
+ if (p.scratch.part === "step") return { ...pose, y: pose.y + dy };
4442
+ const m = p.root.geometry.messages.find((q) => q.id === p.scratch.id);
4443
+ if (m === void 0 || id !== `${p.scratch.root}/msg:${p.scratch.id}` || m.loopY !== void 0) return pose;
4444
+ const shift = pose.x - Math.min(m.x1, m.x2);
4445
+ const still = (p.scratch.end === "from" ? m.x2 : m.x1) + shift;
4446
+ const moving = (p.scratch.end === "from" ? m.x1 : m.x2) + shift + dx;
4447
+ return { ...pose, x: Math.min(still, moving), width: Math.abs(moving - still) };
4448
+ }
4449
+ function createSequenceDragAction(opts = {}) {
4450
+ const commit = sequenceCommitOf(opts);
4451
+ return {
4452
+ id: opts.id ?? SEQUENCE_DRAG_ACTION_ID,
4453
+ label: "Move sequence part",
4454
+ group: "diagram",
4455
+ requires: ["scene"],
4456
+ eligible: { mode: "normal" },
4457
+ invoker: {
4458
+ timing: "ongoing",
4459
+ start(ctx) {
4460
+ const p = pressOf2(ctx);
4461
+ if (p === null) return {};
4462
+ let at = null;
4463
+ let open = true;
4464
+ return {
4465
+ kind: "diagram-sequence-drag",
4466
+ onMove(move) {
4467
+ at = { x: move.world.x, y: move.world.y };
4468
+ },
4469
+ previewIds: () => open && at !== null ? [...p.carried.keys()] : null,
4470
+ previewPose: (id) => {
4471
+ const pose = p.carried.get(id);
4472
+ return open && at !== null && pose !== void 0 ? previewOf(p, id, pose, at) : null;
4473
+ },
4474
+ onEnd(end, reason) {
4475
+ open = false;
4476
+ if (reason !== "commit" || at === null) return;
4477
+ const next = proposed(p, { x: end.world.x, y: end.world.y });
4478
+ if (next.data !== p.data) commit({ id: p.scratch.root, data: next.data, label: next.label }, { ...end, deps: { ...end.deps, scene: p.scene } });
4479
+ }
4480
+ };
4481
+ }
4482
+ },
4483
+ enabled: () => true
4484
+ };
4485
+ }
4486
+ var grab = {
4487
+ id: GRAB_SEQUENCE_ACTION_ID,
4488
+ label: "Grab sequence part",
4489
+ group: "diagram",
4490
+ invoker: { timing: "immediate", run: () => {
4491
+ } },
4492
+ enabled: () => true
4493
+ };
4494
+ function diagramSequence(opts) {
4495
+ const actionId = opts.id ?? SEQUENCE_DRAG_ACTION_ID;
4496
+ const target = `affordance:${SEQUENCE_AFFORDANCE_KIND}`;
4497
+ return {
4498
+ layer: sequenceLayer(opts.scene),
4499
+ contribution: {
4500
+ id: "weasel-diagram-sequence",
4501
+ eligibility: { claimed: true },
4502
+ actions: [createSequenceDragAction({ ...opts, id: actionId }), grab, selectSequencePartAction],
4503
+ bindings: [
4504
+ { spec: { kind: "drag", target }, actionId, opts: { id: "weasel-diagram-sequence.drag" } },
4505
+ { spec: { kind: "pointerDown", target }, actionId: GRAB_SEQUENCE_ACTION_ID, opts: { id: "weasel-diagram-sequence.pointerDown" } },
4506
+ { spec: { kind: "click", target, mods: { shift: "optional" } }, actionId: SELECT_SEQUENCE_PART_ACTION_ID, opts: { id: "weasel-diagram-sequence.click" } }
4507
+ ]
4508
+ }
4509
+ };
4510
+ }
3301
4511
  function agrees(selection, want) {
3302
4512
  if (typeof want === "string" || want === null) return (selection.at(-1) ?? null) === want;
3303
4513
  return selection.length === want.length && want.every((id) => selection.includes(id));
@@ -3407,11 +4617,11 @@ function diagramLayoutOf(specs) {
3407
4617
  const id = s.id;
3408
4618
  if (id === void 0) continue;
3409
4619
  if (isBodyOrRegion(s)) {
3410
- const region = diagramContainerOf(s);
4620
+ const region2 = diagramContainerOf(s);
3411
4621
  const pinned = isPinned({ id, kind: s.kind, data: s.data });
3412
4622
  const { x, y, width, height } = world.get(id);
3413
- if (region !== null) {
3414
- if (!pinned && region.role !== "lane" && region.fitted !== true) {
4623
+ if (region2 !== null) {
4624
+ if (!pinned && region2.role !== "lane" && region2.fitted !== true) {
3415
4625
  containers.push({ kind: "box", id, box: { x, y, width, height } });
3416
4626
  }
3417
4627
  } else if (!pinned) moves.push({ id, x, y });
@@ -3439,8 +4649,8 @@ function changes(was, now) {
3439
4649
  for (const [id, after] of now.routes) {
3440
4650
  const before = was.routes.get(id);
3441
4651
  if (before === void 0) continue;
3442
- const moved = before.waypoints !== after.waypoints && !samePoints(before.waypoints, after.waypoints);
3443
- if (moved || !samePorts(before.ports, after.ports)) routes.push({ id, ...after });
4652
+ const moved2 = before.waypoints !== after.waypoints && !samePoints(before.waypoints, after.waypoints);
4653
+ if (moved2 || !samePorts(before.ports, after.ports)) routes.push({ id, ...after });
3444
4654
  }
3445
4655
  return { moves, routes, containers: regionChanges(was.regions, now.regions) };
3446
4656
  }
@@ -3449,11 +4659,11 @@ function useSceneSync(scene, specs, reports) {
3449
4659
  const syncing = useRef(false);
3450
4660
  const applied = useRef(specs);
3451
4661
  useEffect(() => {
3452
- let known = readScene(scene);
4662
+ let known2 = readScene(scene);
3453
4663
  return scene.subscribe(() => {
3454
4664
  const now = readScene(scene);
3455
- const found = syncing.current ? null : changes(known, now);
3456
- known = now;
4665
+ const found = syncing.current ? null : changes(known2, now);
4666
+ known2 = now;
3457
4667
  if (found === null) return;
3458
4668
  if (found.moves.length > 0 || found.routes.length > 0) reportsRef.current.onMove?.(found.moves, found.routes);
3459
4669
  for (const edit of found.containers) reportsRef.current.onEditContainer?.(edit);
@@ -3470,6 +4680,15 @@ function useSceneSync(scene, specs, reports) {
3470
4680
  applied.current = specs;
3471
4681
  }, [scene, specs]);
3472
4682
  }
4683
+ var isSequenceText = (data) => isTextData(data) && sequencePartOf({ data })?.target !== void 0;
4684
+ function useSequenceTextEdit(scene, report) {
4685
+ const latest = useLatest(report);
4686
+ const on = report !== void 0;
4687
+ return useMemo(() => on ? {
4688
+ isText: isSequenceText,
4689
+ onEnd: (id) => foldSequenceText(scene, id, (edit) => latest.current?.(edit))
4690
+ } : void 0, [on, scene, latest]);
4691
+ }
3473
4692
 
3474
4693
  // src/regionEditing.ts
3475
4694
  function laneResizeReports(scene, resize) {
@@ -3488,9 +4707,9 @@ function laneResizeReports(scene, resize) {
3488
4707
  const { x, y, width, height } = after(id);
3489
4708
  const was = before(id);
3490
4709
  if (x === was.x && y === was.y) continue;
3491
- const region = diagramContainerOf(node);
3492
- if (region !== null) {
3493
- if (region.role === "container" && region.fitted !== true) boxes.push({ kind: "box", id, box: { x, y, width, height } });
4710
+ const region2 = diagramContainerOf(node);
4711
+ if (region2 !== null) {
4712
+ if (region2.role === "container" && region2.fitted !== true) boxes.push({ kind: "box", id, box: { x, y, width, height } });
3494
4713
  } else if (isDiagramBody(node)) moves.push({ id, x, y });
3495
4714
  }
3496
4715
  }
@@ -3565,7 +4784,16 @@ function reportDeleteAction(report) {
3565
4784
  }
3566
4785
  });
3567
4786
  }
3568
- function reportResizeAction(report, region) {
4787
+ function sequenceDeleteAction(scene, edit, report) {
4788
+ return createSequenceDeleteAction({
4789
+ commit: edit,
4790
+ others: (ids) => {
4791
+ const removed = removedData(scene, ids);
4792
+ if (report !== null && (removed.nodes.length > 0 || removed.edges.length > 0)) report(removed);
4793
+ }
4794
+ });
4795
+ }
4796
+ function reportResizeAction(report, region2) {
3569
4797
  return createResizeAction({
3570
4798
  commit: (poses, deps) => {
3571
4799
  const picked = new Set(deps.selection?.get() ?? []);
@@ -3574,7 +4802,7 @@ function reportResizeAction(report, region) {
3574
4802
  if (!picked.has(id)) continue;
3575
4803
  const { x, y, width, height } = pose;
3576
4804
  const node = deps.scene?.get(id);
3577
- if (node !== void 0 && diagramContainerOf(node) !== null) region?.({ kind: "box", id, box: { x, y, width, height } });
4805
+ if (node !== void 0 && diagramContainerOf(node) !== null) region2?.({ kind: "box", id, box: { x, y, width, height } });
3578
4806
  else resizes.push({ id, x, y, width, height });
3579
4807
  }
3580
4808
  if (resizes.length > 0) report?.(resizes);
@@ -3601,6 +4829,7 @@ function useDiagramEditing(props) {
3601
4829
  const reorders = props.onReorder !== void 0;
3602
4830
  const resizes = props.onResize !== void 0;
3603
4831
  const regionEdits = props.onEditContainer !== void 0;
4832
+ const sequences = props.onEditSequence !== void 0;
3604
4833
  const ports = useMemo(() => mode === "connect" ? diagramPorts({
3605
4834
  ...portOptions,
3606
4835
  participants: source,
@@ -3648,24 +4877,28 @@ function useDiagramEditing(props) {
3648
4877
  [reorders, report]
3649
4878
  );
3650
4879
  const regions = useMemo(() => regionEdits ? regionEditing(scene, selected, report) : null, [regionEdits, scene, selected, report]);
4880
+ const sequence = useMemo(
4881
+ () => sequences ? diagramSequence({ scene, commit: (edit) => report.current.onEditSequence?.(edit) }) : null,
4882
+ [sequences, scene, report]
4883
+ );
3651
4884
  const actions = useMemo(() => ({
3652
4885
  ...NO_MARQUEE,
3653
- ...deletes ? { delete: reportDeleteAction((r) => report.current.onDelete?.(r)) } : {},
4886
+ ...sequences ? { delete: sequenceDeleteAction(scene, (edit) => report.current.onEditSequence?.(edit), deletes ? (r) => report.current.onDelete?.(r) : null) } : deletes ? { delete: reportDeleteAction((r) => report.current.onDelete?.(r)) } : {},
3654
4887
  ...resizes || regionEdits ? { resize: reportResizeAction((r) => report.current.onResize?.(r), (e) => report.current.onEditContainer?.(e)) } : {}
3655
- }), [deletes, resizes, regionEdits, report]);
4888
+ }), [deletes, sequences, scene, resizes, regionEdits, report]);
3656
4889
  const portsLayer = ports?.layer ?? shown;
3657
4890
  const layers = useMemo(
3658
- // Edge ends last: an edge's end sits on a port and beside a route handle, and the last layer is hit first.
3659
- () => [regions?.layer, labelDrag?.layer, portsLayer, route?.layer, ends?.layer].filter((l) => l != null),
3660
- [regions, labelDrag, portsLayer, route, ends]
4891
+ // Edge ends after ports and routes: an edge's end sits on a port and beside a route handle, and the last layer is hit first.
4892
+ () => [regions?.layer, labelDrag?.layer, portsLayer, route?.layer, ends?.layer, sequence?.layer].filter((l) => l != null),
4893
+ [regions, labelDrag, portsLayer, route, ends, sequence]
3661
4894
  );
3662
4895
  const extra = props.ambient;
3663
4896
  const ambient = useMemo(() => [
3664
4897
  ...AMBIENT,
3665
- ...[ports?.contribution, route?.contribution, ends?.contribution, labelDrag?.contribution, label, reorder].filter((c) => c != null),
4898
+ ...[ports?.contribution, route?.contribution, ends?.contribution, labelDrag?.contribution, label, reorder, sequence?.contribution].filter((c) => c != null),
3666
4899
  ...regions?.contributions ?? [],
3667
4900
  ...extra ?? []
3668
- ], [ports, route, ends, labelDrag, label, reorder, regions, extra]);
4901
+ ], [ports, route, ends, labelDrag, label, reorder, sequence, regions, extra]);
3669
4902
  return { layers, ambient, actions };
3670
4903
  }
3671
4904
  function usePagesView(pages) {
@@ -3801,6 +5034,7 @@ function Inner({
3801
5034
  onDelete,
3802
5035
  onEditLabel,
3803
5036
  onMoveLabel,
5037
+ onEditSequence,
3804
5038
  onReorder,
3805
5039
  onEditContainer,
3806
5040
  connectBodies,
@@ -3810,6 +5044,8 @@ function Inner({
3810
5044
  pickEdges,
3811
5045
  overlays = NO_OVERLAYS,
3812
5046
  ambient: extraAmbient,
5047
+ tools,
5048
+ onToolsCreated,
3813
5049
  enableKeybindings,
3814
5050
  canConnect,
3815
5051
  portOptions,
@@ -3873,16 +5109,16 @@ function Inner({
3873
5109
  ...refit ? { refit } : {}
3874
5110
  });
3875
5111
  const { defaultView } = fitting;
3876
- const settled = useLatest((moved) => {
3877
- liveOpts?.onSettle?.(moved);
3878
- if (moved !== 0) fitting.settle();
5112
+ const settled = useLatest((moved2) => {
5113
+ liveOpts?.onSettle?.(moved2);
5114
+ if (moved2 !== 0) fitting.settle();
3879
5115
  });
3880
5116
  const live = useLiveLayout({
3881
5117
  ...liveOpts,
3882
5118
  scene,
3883
5119
  source,
3884
5120
  algorithm: run?.algorithm ?? "force",
3885
- onSettle: (moved) => settled.current(moved)
5121
+ onSettle: (moved2) => settled.current(moved2)
3886
5122
  });
3887
5123
  useEffect(() => {
3888
5124
  if (run !== null) live.restart();
@@ -3904,6 +5140,7 @@ function Inner({
3904
5140
  onResize,
3905
5141
  onEditContainer,
3906
5142
  onMove,
5143
+ onEditSequence,
3907
5144
  connectBodies,
3908
5145
  canConnect,
3909
5146
  portOptions,
@@ -3911,16 +5148,19 @@ function Inner({
3911
5148
  });
3912
5149
  const itemDrop = useItemDrop(source, { onDropItem, canDropItem });
3913
5150
  const ambient = useMemo(() => itemDrop === null ? editing.ambient : [...editing.ambient, itemDrop], [editing.ambient, itemDrop]);
3914
- useEffect(() => {
3915
- const canvas = canvasRef.current;
3916
- if (canvas === null) return;
3917
- const disposers = editing.layers.map((layer) => canvas.registerLayer(layer));
3918
- return () => disposers.forEach((dispose) => dispose());
3919
- }, [editing.layers]);
5151
+ useRegisteredLayers(canvasRef, editing.layers);
3920
5152
  const moves = onMove !== void 0 || onEditContainer !== void 0;
3921
5153
  const resizes = onResize !== void 0 || onEditContainer !== void 0;
3922
- const edits = moves || onConnect !== void 0 || onReorder !== void 0 || resizes || edgesPick;
3923
- const features = useMemo(() => ["view", "pick", ...moves ? ["move"] : [], ...resizes ? ["resize"] : []], [moves, resizes]);
5154
+ const sequences = onEditSequence !== void 0;
5155
+ const edits = moves || onConnect !== void 0 || onReorder !== void 0 || resizes || edgesPick || sequences;
5156
+ const features = useMemo(() => [
5157
+ "view",
5158
+ "pick",
5159
+ ...moves ? ["move"] : [],
5160
+ ...resizes ? ["resize"] : [],
5161
+ ...sequences ? ["edit"] : []
5162
+ ], [moves, resizes, sequences]);
5163
+ const textEditor = useSequenceTextEdit(scene, onEditSequence);
3924
5164
  const selectTool = useMemo(() => ({ resize: { resizable: diagramResizable(scene) } }), [scene]);
3925
5165
  const overlayRef = useOverlayPlacement(canvasRef, scene, overlays);
3926
5166
  const fillsOn = [width === void 0 ? "fill-x" : "", height === void 0 ? "fill-y" : ""].join(" ").trim();
@@ -3933,9 +5173,12 @@ function Inner({
3933
5173
  selection,
3934
5174
  features,
3935
5175
  ...resizes ? { selectTool } : {},
5176
+ ...textEditor ? { textEditor } : {},
3936
5177
  enableKeybindings: enableKeybindings ?? edits,
3937
5178
  ambient,
3938
5179
  actions: editing.actions,
5180
+ ...tools ? { tools } : {},
5181
+ ...onToolsCreated ? { onToolsCreated } : {},
3939
5182
  onClick,
3940
5183
  ...onHover ? { onHover } : {},
3941
5184
  width,
@@ -3957,6 +5200,14 @@ function Inner({
3957
5200
  ] });
3958
5201
  }
3959
5202
  var NO_OVERLAYS = [];
5203
+ function useRegisteredLayers(canvasRef, layers) {
5204
+ useEffect(() => {
5205
+ const canvas = canvasRef.current;
5206
+ if (canvas === null) return;
5207
+ const disposers = layers.map((layer) => canvas.registerLayer(layer));
5208
+ return () => disposers.forEach((dispose) => dispose());
5209
+ }, [canvasRef, layers]);
5210
+ }
3960
5211
  function DropRules({ scene, canReparent }) {
3961
5212
  const latest = useLatest(canReparent);
3962
5213
  const asks = canReparent !== void 0;
@@ -3997,6 +5248,6 @@ function useDiagramApi(apiRef, canvasRef, scene, live, setRun, fitNow) {
3997
5248
  }), [canvasRef, live, scene, setRun, fitNow]);
3998
5249
  }
3999
5250
 
4000
- export { ADD_LANE_ACTION_ID, ANYWHERE, CONNECT_ACTION_ID, CONTAINERS_GROUP, CONTAINER_STENCILS, DEFAULT_EDGE_STROKE, DIAGRAM_ITEM_CARRY, DiagramView, EASED_LAYOUTS, EDGE_END_AFFORDANCE_KIND, EDGE_END_LAYER_ID, EDIT_CONTAINER_TITLE_ACTION_ID, GRAB_EDGE_END_ACTION_ID, GRAB_LABEL_ACTION_ID, GRAB_PORT_ACTION_ID, GRAB_WAYPOINT_ACTION_ID, ITEM_DROP_ACTION_ID, LANE_AFFORDANCE_KIND, LANE_LAYER_ID, LANE_RESIZE_ACTION_ID, LAYOUTS, LAYOUT_ACTION_ID, MOVE_LABEL_ACTION_ID, PORT_AFFORDANCE_KIND, PORT_LAYER_ID, RECONNECT_ACTION_ID, RELEASE_MEMBERS_ACTION_ID, REMOVE_WAYPOINT_ACTION_ID, REORDER_ACTION_ID, RESET_LABEL_ACTION_ID, RESET_ROUTE_ACTION_ID, ROUTER_LABELS, ROUTE_EDIT_ACTION_ID, SELECT_LABEL_EDGE_ACTION_ID, SET_HOPS_ACTION_ID, SET_ROUTER_ACTION_IDS, STEP_REORDER_ACTION_ID, WAYPOINT_AFFORDANCE_KIND, WAYPOINT_HIT_PX, WAYPOINT_LAYER_ID, addLane, applyLayout, avoidSceneInput, bodyAt, commitEdgeToScene, commitLabelToScene, commitLaneResizeToScene, commitReconnectToScene, commitRouteToScene, commitRouterToScene, connectBinding, containerBuild, createAddLaneAction, createConnectAction, createDiagramContribution, createEdgeEndAffordance, createItemDropAction, createLabelDragAction, createLaneAffordance, createLaneResizeAction, createLayoutAction, createPortAffordance, createReconnectAction, createReleaseMembersAction, createRemoveWaypointAction, createReorderAction, createResetLabelAction, createResetRouteAction, createRouteEditAction, createSetHopsAction, createSetRouterAction, createSpecHops, createSpecLabelPlacer, createSpecRouter, createStepReorderAction, createWaypointAffordance, defaultCanConnect, diagramCanDropInto, diagramContainers, diagramDropParentAt, diagramEdgeEnds, diagramLabelDrag, diagramLayoutOf, diagramPorts, diagramResizable, diagramShape, diagramWaypoints, dragItemProps, dragSegment, dragVertex, easedProducer, edgeEndLayer, edgeEndScratchOf, edgePolylines, editContainerTitleAction, editContainerTitleBinding, forceProducer, grabPortAction, grabPortBindings, groupReorderContribution, groupReorderSlots, headerIdOf, hopDataOps, inOrUnder, insertWaypoint, isBodyEnd, isBodyOrRegion, isDiagramBody, itemDropContribution, laneLayer, laneResizeFrame, laneScratchOf, lanesOf, layoutDiagram, layoutPoses, movedLabelData, pinSegment, poolAxisOf, poolsOf, portLayer, portScratchOf, reconnectBinding, regionHeaderAt, registerDiagramShape, releaseMembers, removeSegment, removeWaypoint, reorderBinding, reorderContribution, routeHandles, routeStateOf, routeWrites, routedData, routerActions, routesOf, sceneEdges, sceneParticipants, segmentAxis, sequenceSlots, startItemDrag, themeWrites, unpinSegment, useLiveLayout, useMirroredSelection, waypointLayer, waypointScratchOf, withHopsData, withRouter, worldWith };
4001
- //# sourceMappingURL=chunk-GR2DK4S2.js.map
4002
- //# sourceMappingURL=chunk-GR2DK4S2.js.map
5251
+ export { ADD_LANE_ACTION_ID, ANYWHERE, CONNECT_ACTION_ID, CONTAINERS_GROUP, CONTAINER_STENCILS, DEFAULT_EDGE_STROKE, DIAGRAM_ITEM_CARRY, DiagramView, EASED_LAYOUTS, EDGE_END_AFFORDANCE_KIND, EDGE_END_LAYER_ID, EDIT_CONTAINER_TITLE_ACTION_ID, GRAB_EDGE_END_ACTION_ID, GRAB_LABEL_ACTION_ID, GRAB_PORT_ACTION_ID, GRAB_SEQUENCE_ACTION_ID, GRAB_WAYPOINT_ACTION_ID, ITEM_DROP_ACTION_ID, LANE_AFFORDANCE_KIND, LANE_LAYER_ID, LANE_RESIZE_ACTION_ID, MOVE_LABEL_ACTION_ID, PORT_AFFORDANCE_KIND, PORT_LAYER_ID, RECONNECT_ACTION_ID, RELEASE_MEMBERS_ACTION_ID, REMOVE_WAYPOINT_ACTION_ID, REORDER_ACTION_ID, RESET_LABEL_ACTION_ID, RESET_ROUTE_ACTION_ID, ROUTER_LABELS, ROUTE_EDIT_ACTION_ID, SELECT_LABEL_EDGE_ACTION_ID, SELECT_SEQUENCE_PART_ACTION_ID, SEQ, SEQUENCE_AFFORDANCE_KIND, SEQUENCE_DRAG_ACTION_ID, SEQUENCE_LAYER_ID, SEQUENCE_ROLES, SEQ_ARROWS, SEQ_MULTI_SECTION, SET_HOPS_ACTION_ID, SET_ROUTER_ACTION_IDS, STEP_REORDER_ACTION_ID, WAYPOINT_AFFORDANCE_KIND, WAYPOINT_HIT_PX, WAYPOINT_LAYER_ID, addBox, addLane, addParticipant, addSection, avoidSceneInput, bodyAt, commitEdgeToScene, commitLabelToScene, commitLaneResizeToScene, commitReconnectToScene, commitRouteToScene, commitRouterToScene, commitSequence, connectBinding, containerBuild, createAddLaneAction, createConnectAction, createDiagramContribution, createEdgeEndAffordance, createItemDropAction, createLabelDragAction, createLaneAffordance, createLaneResizeAction, createPortAffordance, createReconnectAction, createReleaseMembersAction, createRemoveWaypointAction, createReorderAction, createResetLabelAction, createResetRouteAction, createRouteEditAction, createSequenceDeleteAction, createSequenceDragAction, createSetHopsAction, createSetRouterAction, createSpecHops, createSpecLabelPlacer, createSpecRouter, createStepReorderAction, createWaypointAffordance, defaultCanConnect, diagramCanDropInto, diagramContainers, diagramDropParentAt, diagramEdgeEnds, diagramLabelDrag, diagramLayoutOf, diagramPorts, diagramResizable, diagramSequence, diagramShape, diagramWaypoints, dragItemProps, dragSegment, dragVertex, easedProducer, edgeEndLayer, edgeEndScratchOf, edgePolylines, editContainerTitleAction, editContainerTitleBinding, findStep, foldSequenceText, forceProducer, freshSeqId, grabPortAction, grabPortBindings, groupReorderContribution, groupReorderSlots, headerIdOf, hopDataOps, inOrUnder, insertMark, insertMessage, insertNote, insertStep, insertWaypoint, isBodyEnd, isBodyOrRegion, isDiagramBody, isSequenceText, itemDropContribution, laneLayer, laneResizeFrame, laneScratchOf, lanesOf, moveParticipant, moveStep, movedLabelData, newParticipant, pinSegment, placeOf, placedSequences, poolAxisOf, poolsOf, portLayer, portScratchOf, reconnectBinding, reconnectMessage, redrawSequences, regionHeaderAt, registerDiagramShape, releaseMembers, removeBox, removeMarks, removeMarksOf, removeParticipant, removeSection, removeSegment, removeStep, removeStepAt, removeWaypoint, reorderBinding, reorderContribution, routeHandles, routeStateOf, routedData, routerActions, sceneEdges, sceneParticipants, segmentAxis, selectSequencePartAction, seqIdTaken, sequenceCommitOf, sequenceDeletes, sequenceLayout, sequencePartNodeOf, sequencePartOf, sequenceRootOf, sequenceScratchOf, sequenceSlots, sequenceSpecs, sequenceTextOf, setAutonumber, setFragmentType, setMessageActivation, setMessageArrow, setParticipantOutline, setSequenceText, startItemDrag, startSequence, stepListOf, themeWrites, unpinSegment, unwrapFragment, useLiveLayout, useMirroredSelection, useSequenceTextEdit, waypointLayer, waypointScratchOf, withHopsData, withRouter, worldWith, wrapSteps };
5252
+ //# sourceMappingURL=chunk-EIHPPOAM.js.map
5253
+ //# sourceMappingURL=chunk-EIHPPOAM.js.map