@cardenelabs/cdl 0.28.0 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as CdlDiagram, S as Signal, a as CdlInput, b as CdlLane, c as CdlNode, T as Tone, d as Side, E as EdgeStyle, e as EdgeRole, f as EdgeHead, g as EdgeHeadFill, h as CdlState, i as CdlEventTarget, j as Computed, k as CdlDerivedValue, l as CdlScrollTrigger, L as LaidDiagram, m as CdlDiagramViewProps, n as LaidEdge, o as LaidNode, p as CdlEdge, B as BBox, R as RowMark, N as NodeKind, J as JourneyEmotion, Q as QuadrantKey } from './render-ViWKnlu1.cjs';
2
- export { q as CdlDiagramView, r as CdlEventBinding, s as CdlEventKind, t as CdlFormula, u as CdlPhase, v as EDGE_HEADS, w as EDGE_HEAD_DEFAULT, x as EDGE_HEAD_FILLS, y as EDGE_HEAD_FILL_DEFAULT, z as EDGE_REVEALS, A as EDGE_REVEAL_DEFAULT, D as EDGE_STYLES, F as EdgeReveal, I as InteractiveHandlerMap, G as InteractiveSignalsAccessor, H as LaidLane, K as NODE_KINDS, M as ScrollProgressHandle, O as TONES, P as computeEventBindingKey, U as computeFormulaKey, V as computeInputSignalKey, W as computeScrollTriggerKey, X as computed, Y as createInteractiveSignalsAccessor, Z as createScrollProgressHandle, _ as createScrollProgressSignals, $ as hasInteractivePrimitives, a0 as sequenceBoardMetrics, a1 as sequenceStepId, a2 as signal } from './render-ViWKnlu1.cjs';
1
+ import { C as CdlDiagram, S as Signal, a as CdlInput, b as CdlLane, c as CdlNode, T as Tone, d as Side, E as EdgeStyle, e as EdgeRole, f as EdgeHead, g as EdgeHeadFill, h as CdlState, i as CdlEventTarget, j as Computed, k as CdlDerivedValue, l as CdlScrollTrigger, L as LaidDiagram, m as CdlDiagramViewProps, n as LaidEdge, o as LaidNode, p as CdlEdge, B as BBox, R as RowMark, N as NodeKind, J as JourneyEmotion, Q as QuadrantKey } from './render-CabTMeao.cjs';
2
+ export { q as CdlDiagramView, r as CdlEventBinding, s as CdlEventKind, t as CdlFormula, u as CdlPhase, v as EDGE_HEADS, w as EDGE_HEAD_DEFAULT, x as EDGE_HEAD_FILLS, y as EDGE_HEAD_FILL_DEFAULT, z as EDGE_REVEALS, A as EDGE_REVEAL_DEFAULT, D as EDGE_STYLES, F as EdgeReveal, I as InteractiveHandlerMap, G as InteractiveSignalsAccessor, H as LaidLane, K as NODE_KINDS, M as ScrollProgressHandle, O as TONES, P as computeEventBindingKey, U as computeFormulaKey, V as computeInputSignalKey, W as computeScrollTriggerKey, X as computed, Y as createInteractiveSignalsAccessor, Z as createScrollProgressHandle, _ as createScrollProgressSignals, $ as hasInteractivePrimitives, a0 as sequenceBoardMetrics, a1 as sequenceStepId, a2 as signal } from './render-CabTMeao.cjs';
3
3
  import { JSX } from 'react';
4
4
 
5
5
  declare function effect(fn: () => void | (() => void)): () => void;
@@ -1210,6 +1210,10 @@ declare function diagram(id: string, options: {
1210
1210
  * この図をどの配色で描くか (#1553)。 詳細は `CdlDiagram.palette` の doc 参照。
1211
1211
  */
1212
1212
  palette?: string;
1213
+ /**
1214
+ * この図がどの種類か (#645)。 詳しくは `CdlDiagram.type` の説明を参照。
1215
+ */
1216
+ type?: string;
1213
1217
  }): DiagramBuilder;
1214
1218
 
1215
1219
  /**
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as CdlDiagram, S as Signal, a as CdlInput, b as CdlLane, c as CdlNode, T as Tone, d as Side, E as EdgeStyle, e as EdgeRole, f as EdgeHead, g as EdgeHeadFill, h as CdlState, i as CdlEventTarget, j as Computed, k as CdlDerivedValue, l as CdlScrollTrigger, L as LaidDiagram, m as CdlDiagramViewProps, n as LaidEdge, o as LaidNode, p as CdlEdge, B as BBox, R as RowMark, N as NodeKind, J as JourneyEmotion, Q as QuadrantKey } from './render-ViWKnlu1.js';
2
- export { q as CdlDiagramView, r as CdlEventBinding, s as CdlEventKind, t as CdlFormula, u as CdlPhase, v as EDGE_HEADS, w as EDGE_HEAD_DEFAULT, x as EDGE_HEAD_FILLS, y as EDGE_HEAD_FILL_DEFAULT, z as EDGE_REVEALS, A as EDGE_REVEAL_DEFAULT, D as EDGE_STYLES, F as EdgeReveal, I as InteractiveHandlerMap, G as InteractiveSignalsAccessor, H as LaidLane, K as NODE_KINDS, M as ScrollProgressHandle, O as TONES, P as computeEventBindingKey, U as computeFormulaKey, V as computeInputSignalKey, W as computeScrollTriggerKey, X as computed, Y as createInteractiveSignalsAccessor, Z as createScrollProgressHandle, _ as createScrollProgressSignals, $ as hasInteractivePrimitives, a0 as sequenceBoardMetrics, a1 as sequenceStepId, a2 as signal } from './render-ViWKnlu1.js';
1
+ import { C as CdlDiagram, S as Signal, a as CdlInput, b as CdlLane, c as CdlNode, T as Tone, d as Side, E as EdgeStyle, e as EdgeRole, f as EdgeHead, g as EdgeHeadFill, h as CdlState, i as CdlEventTarget, j as Computed, k as CdlDerivedValue, l as CdlScrollTrigger, L as LaidDiagram, m as CdlDiagramViewProps, n as LaidEdge, o as LaidNode, p as CdlEdge, B as BBox, R as RowMark, N as NodeKind, J as JourneyEmotion, Q as QuadrantKey } from './render-CabTMeao.js';
2
+ export { q as CdlDiagramView, r as CdlEventBinding, s as CdlEventKind, t as CdlFormula, u as CdlPhase, v as EDGE_HEADS, w as EDGE_HEAD_DEFAULT, x as EDGE_HEAD_FILLS, y as EDGE_HEAD_FILL_DEFAULT, z as EDGE_REVEALS, A as EDGE_REVEAL_DEFAULT, D as EDGE_STYLES, F as EdgeReveal, I as InteractiveHandlerMap, G as InteractiveSignalsAccessor, H as LaidLane, K as NODE_KINDS, M as ScrollProgressHandle, O as TONES, P as computeEventBindingKey, U as computeFormulaKey, V as computeInputSignalKey, W as computeScrollTriggerKey, X as computed, Y as createInteractiveSignalsAccessor, Z as createScrollProgressHandle, _ as createScrollProgressSignals, $ as hasInteractivePrimitives, a0 as sequenceBoardMetrics, a1 as sequenceStepId, a2 as signal } from './render-CabTMeao.js';
3
3
  import { JSX } from 'react';
4
4
 
5
5
  declare function effect(fn: () => void | (() => void)): () => void;
@@ -1210,6 +1210,10 @@ declare function diagram(id: string, options: {
1210
1210
  * この図をどの配色で描くか (#1553)。 詳細は `CdlDiagram.palette` の doc 参照。
1211
1211
  */
1212
1212
  palette?: string;
1213
+ /**
1214
+ * この図がどの種類か (#645)。 詳しくは `CdlDiagram.type` の説明を参照。
1215
+ */
1216
+ type?: string;
1213
1217
  }): DiagramBuilder;
1214
1218
 
1215
1219
  /**
package/dist/index.js CHANGED
@@ -11484,6 +11484,8 @@ function diagram(id, options) {
11484
11484
  ...options.structuredData === "exclude" ? { structuredData: "exclude" } : {},
11485
11485
  // 配色の名前は素通しする。 空文字の遮断は `layout` が持つ (後段が必ず通るため)
11486
11486
  ...options.palette !== void 0 ? { palette: options.palette } : {},
11487
+ // 種類の名前も同じ経路で渡し、空文字の扱いを `layout` の 1 箇所に揃える
11488
+ ...options.type !== void 0 ? { type: options.type } : {},
11487
11489
  // inputs / formulas / scrollTriggers / eventBindings は空なら省略 (static diagram の JSON 形状維持)
11488
11490
  ...inputs.length > 0 ? { inputs: [...inputs] } : {},
11489
11491
  ...formulas.length > 0 ? { formulas: [...formulas] } : {},
@@ -19671,16 +19673,112 @@ function separateSharedStraightRuns(edges, nodes) {
19671
19673
  e.d = verticesToPath(verts.get(e.id));
19672
19674
  }
19673
19675
  }
19676
+ function pullOutgoingFirstCorner(edges, nodes) {
19677
+ if (edges.length < 2) return;
19678
+ const \u675F = /* @__PURE__ */ new Map();
19679
+ const \u540C\u3058\u7D44\u306E\u6570 = /* @__PURE__ */ new Map();
19680
+ for (const e of edges) {
19681
+ const key = `${e.from}::${e.fromSide}`;
19682
+ const list = \u675F.get(key) ?? [];
19683
+ list.push(e);
19684
+ \u675F.set(key, list);
19685
+ const pair = `${e.from}->${e.to}`;
19686
+ \u540C\u3058\u7D44\u306E\u6570.set(pair, (\u540C\u3058\u7D44\u306E\u6570.get(pair) ?? 0) + 1);
19687
+ }
19688
+ let \u672D\u3092\u65E7\u7D4C\u8DEF\u3078\u8FFD\u5F93\u6E08\u307F = false;
19689
+ for (const list of \u675F.values()) {
19690
+ if (list.length < 2) continue;
19691
+ const \u4E26\u3073 = list.flatMap((e) => {
19692
+ const pts = pathVertices(e.d);
19693
+ if (!pts || pts.length < 2) return [];
19694
+ return [{ e, pts, \u6700\u521D\u306E\u9577\u3055: Math.hypot(pts[1].x - pts[0].x, pts[1].y - pts[0].y) }];
19695
+ }).sort((a, b) => b.\u6700\u521D\u306E\u9577\u3055 - a.\u6700\u521D\u306E\u9577\u3055);
19696
+ for (const { e, pts, \u6700\u521D\u306E\u9577\u3055 } of \u4E26\u3073.slice(1)) {
19697
+ if ((\u540C\u3058\u7D44\u306E\u6570.get(`${e.from}->${e.to}`) ?? 0) > 1) continue;
19698
+ if (pts.length < 3 || \u6700\u521D\u306E\u9577\u3055 <= EDGE_STUB_OUT + VERTICAL_DETOUR_CORNER) continue;
19699
+ const \u6A2A = e.fromSide === "left" || e.fromSide === "right";
19700
+ if (!runIsAligned(pts, 0, \u6A2A ? 1 : 0)) continue;
19701
+ const \u79FB\u52D5\u91CF = \u6700\u521D\u306E\u9577\u3055 - (EDGE_STUB_OUT + VERTICAL_DETOUR_CORNER);
19702
+ const ux = (pts[1].x - pts[0].x) / \u6700\u521D\u306E\u9577\u3055;
19703
+ const uy = (pts[1].y - pts[0].y) / \u6700\u521D\u306E\u9577\u3055;
19704
+ const \u8A66\u3057 = pts.map(
19705
+ (p, i) => i === 1 || i === 2 ? { x: p.x - ux * \u79FB\u52D5\u91CF, y: p.y - uy * \u79FB\u52D5\u91CF } : p
19706
+ );
19707
+ const \u8A66\u3057D = verticesToPath(\u8A66\u3057);
19708
+ const \u8A66\u3057\u533A\u9593 = flattenPathSegments(extractPathSegments(\u8A66\u3057D));
19709
+ if (nodes.some(
19710
+ (n) => n.id !== e.from && n.id !== e.to && segmentsCrossRect(\u8A66\u3057\u533A\u9593, nodeRect(n))
19711
+ )) {
19712
+ continue;
19713
+ }
19714
+ const \u524D = e.d;
19715
+ const \u524D\u306E\u4EA4\u5DEE = countEdgeCrossings(edges).count;
19716
+ e.d = \u8A66\u3057D;
19717
+ if (countEdgeCrossings(edges).count > \u524D\u306E\u4EA4\u5DEE) {
19718
+ e.d = \u524D;
19719
+ continue;
19720
+ }
19721
+ e.d = \u524D;
19722
+ if (!\u672D\u3092\u65E7\u7D4C\u8DEF\u3078\u8FFD\u5F93\u6E08\u307F) {
19723
+ slideLabelsAlongOwnPath(edges, nodes);
19724
+ \u672D\u3092\u65E7\u7D4C\u8DEF\u3078\u8FFD\u5F93\u6E08\u307F = true;
19725
+ }
19726
+ const labelBox = computeLabelBBoxWorld(e);
19727
+ const label = { x: labelBox.x + labelBox.w / 2, y: labelBox.y + labelBox.h / 2 };
19728
+ const \u7DDA\u5206\u307E\u3067\u306E\u8DDD\u96E22 = (a, b) => {
19729
+ const dx = b.x - a.x;
19730
+ const dy = b.y - a.y;
19731
+ const len2 = dx * dx + dy * dy;
19732
+ const t = len2 === 0 ? 0 : Math.max(0, Math.min(1, ((label.x - a.x) * dx + (label.y - a.y) * dy) / len2));
19733
+ return (label.x - (a.x + dx * t)) ** 2 + (label.y - (a.y + dy * t)) ** 2;
19734
+ };
19735
+ const \u52D5\u304F\u533A\u9593\u3078\u306E\u8DDD\u96E2 = \u7DDA\u5206\u307E\u3067\u306E\u8DDD\u96E22(pts[1], pts[2]);
19736
+ const label\u3082\u52D5\u304B\u3059 = pts.slice(0, -1).every((p, i) => \u7DDA\u5206\u307E\u3067\u306E\u8DDD\u96E22(p, pts[i + 1]) >= \u52D5\u304F\u533A\u9593\u3078\u306E\u8DDD\u96E2 - 1e-6);
19737
+ e.d = \u8A66\u3057D;
19738
+ if (label\u3082\u52D5\u304B\u3059) {
19739
+ e.labelX -= ux * \u79FB\u52D5\u91CF;
19740
+ e.labelY -= uy * \u79FB\u52D5\u91CF;
19741
+ }
19742
+ }
19743
+ }
19744
+ }
19674
19745
  var ENDPOINT_FAN_STEP = 56;
19675
19746
  var ENDPOINT_FAN_MIN = 20;
19676
19747
  var ENDPOINT_FAN_RUNUP = 40;
19748
+ var MIXED_ROOT_OVERLAP_MIN = 24;
19677
19749
  function fanIncomingEndpoints(edges, nodes) {
19678
19750
  if (edges.length < 2) return;
19679
19751
  const nmap = new Map(nodes.map((n) => [n.id, n]));
19752
+ const \u5E73\u5766\u306A\u533A\u9593 = new Map(edges.map((e) => [e.id, flattenPathSegments(extractPathSegments(e.d))]));
19753
+ const \u8EF8\u306B\u5E73\u884C\u306A\u91CD\u306A\u308A\u9577\u3055 = (\u4E00\u65B9, \u4ED6\u65B9) => {
19754
+ let \u5408\u8A08 = 0;
19755
+ for (const a of \u5E73\u5766\u306A\u533A\u9593.get(\u4E00\u65B9.id) ?? []) {
19756
+ const a\u306F\u6C34\u5E73 = Math.abs(a.y2 - a.y1) <= 1;
19757
+ const a\u306F\u5782\u76F4 = Math.abs(a.x2 - a.x1) <= 1;
19758
+ for (const b of \u5E73\u5766\u306A\u533A\u9593.get(\u4ED6\u65B9.id) ?? []) {
19759
+ const b\u306F\u6C34\u5E73 = Math.abs(b.y2 - b.y1) <= 1;
19760
+ const b\u306F\u5782\u76F4 = Math.abs(b.x2 - b.x1) <= 1;
19761
+ if (a\u306F\u6C34\u5E73 && b\u306F\u6C34\u5E73 && Math.abs(a.y1 - b.y1) <= 1) {
19762
+ \u5408\u8A08 += Math.max(0, Math.min(Math.max(a.x1, a.x2), Math.max(b.x1, b.x2)) - Math.max(Math.min(a.x1, a.x2), Math.min(b.x1, b.x2)));
19763
+ }
19764
+ if (a\u306F\u5782\u76F4 && b\u306F\u5782\u76F4 && Math.abs(a.x1 - b.x1) <= 1) {
19765
+ \u5408\u8A08 += Math.max(0, Math.min(Math.max(a.y1, a.y2), Math.max(b.y1, b.y2)) - Math.max(Math.min(a.y1, a.y2), Math.min(b.y1, b.y2)));
19766
+ }
19767
+ }
19768
+ }
19769
+ return \u5408\u8A08;
19770
+ };
19680
19771
  const \u540C\u3058\u7D44\u306E\u6570 = /* @__PURE__ */ new Map();
19681
19772
  for (const e of edges) \u540C\u3058\u7D44\u306E\u6570.set(`${e.from}->${e.to}`, (\u540C\u3058\u7D44\u306E\u6570.get(`${e.from}->${e.to}`) ?? 0) + 1);
19682
19773
  const \u675F = /* @__PURE__ */ new Map();
19774
+ const \u51FA\u308B\u7DDA = /* @__PURE__ */ new Map();
19683
19775
  for (const e of edges) {
19776
+ if (nmap.has(e.from)) {
19777
+ const key2 = `${e.from}::${e.fromSide}`;
19778
+ const list2 = \u51FA\u308B\u7DDA.get(key2) ?? [];
19779
+ list2.push(e);
19780
+ \u51FA\u308B\u7DDA.set(key2, list2);
19781
+ }
19684
19782
  if (!nmap.has(e.to)) continue;
19685
19783
  if ((\u540C\u3058\u7D44\u306E\u6570.get(`${e.from}->${e.to}`) ?? 0) > 1) continue;
19686
19784
  const key = `${e.to}::${e.toSide}`;
@@ -19688,27 +19786,48 @@ function fanIncomingEndpoints(edges, nodes) {
19688
19786
  list.push(e);
19689
19787
  \u675F.set(key, list);
19690
19788
  }
19691
- for (const [, list] of \u675F) {
19692
- if (list.length < 2) continue;
19789
+ for (const [key, list] of \u675F) {
19790
+ const \u4E2D\u592E\u304C\u585E\u304C\u3063\u3066\u3044\u308B = (\u51FA\u308B\u7DDA.get(key) ?? []).some(
19791
+ (\u51FA\u7DDA) => list.some(
19792
+ (\u5165\u7DDA) => !(\u5165\u7DDA.from === \u51FA\u7DDA.to && \u5165\u7DDA.to === \u51FA\u7DDA.from) && \u8EF8\u306B\u5E73\u884C\u306A\u91CD\u306A\u308A\u9577\u3055(\u5165\u7DDA, \u51FA\u7DDA) >= MIXED_ROOT_OVERLAP_MIN
19793
+ )
19794
+ );
19795
+ if (list.length < 2 && !\u4E2D\u592E\u304C\u585E\u304C\u3063\u3066\u3044\u308B) continue;
19693
19796
  const n = nmap.get(list[0].to);
19694
19797
  const \u6A2A = list[0].toSide === "left" || list[0].toSide === "right";
19695
19798
  const \u8FBA\u306E\u9577\u3055 = \u6A2A ? n.h : n.w;
19696
19799
  const \u4F7F\u3048\u308B\u5E452 = \u8FBA\u306E\u9577\u3055 - 2 * ARROW_ENDPOINT_CENTER_TOL;
19697
19800
  if (\u4F7F\u3048\u308B\u5E452 <= 0) continue;
19698
- const \u9593\u9694 = Math.min(ENDPOINT_FAN_STEP, \u4F7F\u3048\u308B\u5E452 / (list.length - 1));
19801
+ const \u5E2D\u306E\u9593 = \u4E2D\u592E\u304C\u585E\u304C\u3063\u3066\u3044\u308B ? list.length : list.length - 1;
19802
+ const \u9593\u9694 = Math.min(ENDPOINT_FAN_STEP, \u4F7F\u3048\u308B\u5E452 / \u5E2D\u306E\u9593);
19699
19803
  if (\u9593\u9694 < ENDPOINT_FAN_MIN) continue;
19700
- const \u4E26\u3073 = list.map((e) => ({ e, \u6DF1\u3055: \u8FBA\u304B\u3089\u96E2\u308C\u305F\u5074\u306E\u4F4D\u7F6E(e, \u6A2A) ?? 0 })).sort((a, b) => a.\u6DF1\u3055 - b.\u6DF1\u3055 || (a.e.id < b.e.id ? -1 : 1));
19804
+ const \u8FBA\u306E\u4E2D\u5FC3 = \u6A2A ? n.cy : n.cx;
19805
+ const \u4E26\u3073 = list.map((e) => {
19806
+ const \u533A\u9593 = extractPathSegments(e.d);
19807
+ const last = \u533A\u9593[\u533A\u9593.length - 1];
19808
+ const \u9577\u3044\u52A9\u8D70 = last === void 0 ? 0 : Math.hypot(last.x2 - last.x1, last.y2 - last.y1);
19809
+ const \u4E2D\u5FC3\u3092\u88DC\u3046 = \u4E2D\u592E\u304C\u585E\u304C\u3063\u3066\u3044\u308B || list.length === 2;
19810
+ const \u6DF1\u3055 = \u8FBA\u304B\u3089\u96E2\u308C\u305F\u5074\u306E\u4F4D\u7F6E(e, \u6A2A) ?? (\u4E2D\u5FC3\u3092\u88DC\u3046 ? \u8FBA\u306E\u4E2D\u5FC3 : 0);
19811
+ return { e, \u9577\u3044\u52A9\u8D70, \u6DF1\u3055 };
19812
+ }).sort((a, b) => a.\u6DF1\u3055 - b.\u6DF1\u3055 || (a.e.id < b.e.id ? -1 : 1));
19701
19813
  const \u4E2D\u5FC3 = (\u4E26\u3073.length - 1) * \u9593\u9694 / 2;
19814
+ let \u8CA0\u5074\u306E\u5E2D = 0;
19815
+ let \u6B63\u5074\u306E\u5E2D = 0;
19702
19816
  for (let k = 0; k < \u4E26\u3073.length; k++) {
19703
- const d = k * \u9593\u9694 - \u4E2D\u5FC3;
19817
+ const d = \u4E2D\u592E\u304C\u585E\u304C\u3063\u3066\u3044\u308B ? \u4E26\u3073[k].\u6DF1\u3055 < \u8FBA\u306E\u4E2D\u5FC3 ? -(++\u8CA0\u5074\u306E\u5E2D * \u9593\u9694) : ++\u6B63\u5074\u306E\u5E2D * \u9593\u9694 : k * \u9593\u9694 - \u4E2D\u5FC3;
19704
19818
  if (Math.abs(d) < 1e-3) continue;
19705
19819
  const e = \u4E26\u3073[k].e;
19706
- const \u5DEE\u66FF = \u672B\u5C3E\u3092\u8FBA\u306B\u6CBF\u3063\u3066\u305A\u3089\u3059(e, \u6A2A, d, nodes);
19707
- if (\u5DEE\u66FF === null) continue;
19708
19820
  const \u524D = e.d;
19709
19821
  const \u524D\u306E\u4EA4\u5DEE = countEdgeCrossings(edges).count;
19710
- e.d = \u5DEE\u66FF;
19711
- if (countEdgeCrossings(edges).count > \u524D\u306E\u4EA4\u5DEE) e.d = \u524D;
19822
+ const \u9577\u3044\u52A9\u8D70 = \u4E26\u3073[k].\u9577\u3044\u52A9\u8D70;
19823
+ for (const \u52A9\u8D70 of [\u9577\u3044\u52A9\u8D70, ENDPOINT_FAN_RUNUP]) {
19824
+ e.d = \u524D;
19825
+ const \u5DEE\u66FF = \u672B\u5C3E\u3092\u8FBA\u306B\u6CBF\u3063\u3066\u305A\u3089\u3059(e, \u6A2A, d, \u52A9\u8D70, nodes);
19826
+ if (\u5DEE\u66FF === null) continue;
19827
+ e.d = \u5DEE\u66FF;
19828
+ if (countEdgeCrossings(edges).count <= \u524D\u306E\u4EA4\u5DEE) break;
19829
+ e.d = \u524D;
19830
+ }
19712
19831
  }
19713
19832
  }
19714
19833
  }
@@ -19721,7 +19840,7 @@ function \u8FBA\u304B\u3089\u96E2\u308C\u305F\u5074\u306E\u4F4D\u7F6E(e, \u6A2A)
19721
19840
  }
19722
19841
  return null;
19723
19842
  }
19724
- function \u672B\u5C3E\u3092\u8FBA\u306B\u6CBF\u3063\u3066\u305A\u3089\u3059(e, \u6A2A, d, nodes) {
19843
+ function \u672B\u5C3E\u3092\u8FBA\u306B\u6CBF\u3063\u3066\u305A\u3089\u3059(e, \u6A2A, d, \u52A9\u8D70, nodes) {
19725
19844
  if ((e.d.match(/M/g) ?? []).length !== 1) return null;
19726
19845
  const segs = extractPathSegments(e.d);
19727
19846
  if (segs.length === 0) return null;
@@ -19734,7 +19853,8 @@ function \u672B\u5C3E\u3092\u8FBA\u306B\u6CBF\u3063\u3066\u305A\u3089\u3059(e, \
19734
19853
  if (\u9577\u3055 < ENDPOINT_FAN_RUNUP + 1) return null;
19735
19854
  const ux = (last.x1 - last.x2) / \u9577\u3055;
19736
19855
  const uy = (last.y1 - last.y2) / \u9577\u3055;
19737
- const \u6298\u308C1 = { x: last.x2 + ux * ENDPOINT_FAN_RUNUP, y: last.y2 + uy * ENDPOINT_FAN_RUNUP };
19856
+ const \u4E38\u3081\u305F\u52A9\u8D70 = Math.min(\u52A9\u8D70, \u9577\u3055);
19857
+ const \u6298\u308C1 = { x: last.x2 + ux * \u4E38\u3081\u305F\u52A9\u8D70, y: last.y2 + uy * \u4E38\u3081\u305F\u52A9\u8D70 };
19738
19858
  const \u6298\u308C2 = \u6A2A ? { x: \u6298\u308C1.x, y: \u6298\u308C1.y + d } : { x: \u6298\u308C1.x + d, y: \u6298\u308C1.y };
19739
19859
  const \u7D42\u70B9 = \u6A2A ? { x: last.x2, y: last.y2 + d } : { x: last.x2 + d, y: last.y2 };
19740
19860
  const \u65B0\u533A\u9593 = [
@@ -19756,7 +19876,8 @@ function \u672B\u5C3E\u3092\u8FBA\u306B\u6CBF\u3063\u3066\u305A\u3089\u3059(e, \
19756
19876
  }
19757
19877
  parts.push(`L ${s.x2} ${s.y2}`);
19758
19878
  }
19759
- parts.push(`L ${round1(\u6298\u308C1.x)} ${round1(\u6298\u308C1.y)}`);
19879
+ const \u6298\u308C1\u306F\u76F4\u524D\u306E\u6298\u308C = Math.abs(\u6298\u308C1.x - last.x1) <= 0.5 && Math.abs(\u6298\u308C1.y - last.y1) <= 0.5;
19880
+ if (!\u6298\u308C1\u306F\u76F4\u524D\u306E\u6298\u308C) parts.push(`L ${round1(\u6298\u308C1.x)} ${round1(\u6298\u308C1.y)}`);
19760
19881
  parts.push(`L ${round1(\u6298\u308C2.x)} ${round1(\u6298\u308C2.y)}`);
19761
19882
  parts.push(`L ${round1(\u7D42\u70B9.x)} ${round1(\u7D42\u70B9.y)}`);
19762
19883
  return parts.join(" ");
@@ -20239,6 +20360,7 @@ function layout(diag) {
20239
20360
  diag.edges.filter((e) => e.posX1 !== void 0 && e.posY1 !== void 0 && e.posX2 !== void 0 && e.posY2 !== void 0).map((e) => e.id)
20240
20361
  );
20241
20362
  bowSharedStraightPaths(edges, nodesFinal, positionedEdgeIds);
20363
+ pullOutgoingFirstCorner(edges, nodesFinal);
20242
20364
  fanIncomingEndpoints(edges, nodesFinal);
20243
20365
  separateSharedStraightRuns(edges, nodesFinal);
20244
20366
  hopEdgeCrossings(edges);
@@ -20280,6 +20402,8 @@ function layout(diag) {
20280
20402
  // **遮断はここだけに置く**。 描画は必ず組み立てを通り、組み立て API も `er` も
20281
20403
  // 素通しにしてある。 上流にも置くと、どの入力でも通らない分岐が残る
20282
20404
  ...diag.palette ? { palette: diag.palette } : {},
20405
+ // 種類も配色と同じく空の目印を出さない。 遮断をここに揃えると手書きの図にも効く
20406
+ ...diag.type ? { type: diag.type } : {},
20283
20407
  bboxes,
20284
20408
  collisions,
20285
20409
  nearCollisions,
@@ -29699,6 +29823,7 @@ function CdlStage({
29699
29823
  "data-cdl-stage": "",
29700
29824
  "data-cdl-scale": diagramScale === 1 ? void 0 : diagramScale,
29701
29825
  "data-cdl-palette": laid.palette,
29826
+ "data-cdl-type": laid.type,
29702
29827
  children: [
29703
29828
  /* @__PURE__ */ jsxs("defs", { children: [
29704
29829
  Object.entries(TONE).flatMap(
@@ -30368,7 +30493,7 @@ function fitRowsWidth(boxW, rows) {
30368
30493
  }
30369
30494
  function swimlane(preset) {
30370
30495
  const w = preset.laneWidth ?? 400;
30371
- const b = diagram(preset.id, { topic: preset.topic });
30496
+ const b = diagram(preset.id, { topic: preset.topic, type: "swimlane" });
30372
30497
  const labelToId = /* @__PURE__ */ new Map();
30373
30498
  const idsInOrder = [];
30374
30499
  for (const label of preset.lanes) {
@@ -30388,7 +30513,7 @@ function swimlane(preset) {
30388
30513
  }
30389
30514
  function flow(preset) {
30390
30515
  const w = preset.laneWidth ?? 400;
30391
- const b = diagram(preset.id, { topic: preset.topic });
30516
+ const b = diagram(preset.id, { topic: preset.topic, type: "flow" });
30392
30517
  b.lane("flow", { width: w, ...preset.laneLabel ? { label: preset.laneLabel } : {} });
30393
30518
  const tone = preset.defaultTone ?? "accent";
30394
30519
  const style = preset.defaultStyle ?? "dotted-flow";
@@ -30449,7 +30574,7 @@ var SEQUENCE_MESSAGE_LOOK = {
30449
30574
  };
30450
30575
  function sequence(preset) {
30451
30576
  const tone = preset.defaultTone ?? "accent";
30452
- const b = diagram(preset.id, { topic: preset.topic });
30577
+ const b = diagram(preset.id, { topic: preset.topic, type: "sequence" });
30453
30578
  const \u9762\u3005 = preset.actors.map(
30454
30579
  (a) => typeof a === "string" ? { name: a } : { name: a.name, ...a.subtitle ? { subtitle: a.subtitle } : {} }
30455
30580
  );
@@ -30504,7 +30629,7 @@ function topology(preset) {
30504
30629
  const groupW = preset.groupWidth ?? 460;
30505
30630
  const tone = preset.defaultTone ?? "accent";
30506
30631
  const style = preset.defaultStyle ?? "solid";
30507
- const b = diagram(preset.id, { topic: preset.topic });
30632
+ const b = diagram(preset.id, { topic: preset.topic, type: "topology" });
30508
30633
  const groupOrder = [];
30509
30634
  const groupStackCount = /* @__PURE__ */ new Map();
30510
30635
  const phaseActivate = [];
@@ -30573,7 +30698,7 @@ function er(preset) {
30573
30698
  const entityW = resolveStorageBoxW(preset.entityWidth, "er", "entityWidth");
30574
30699
  const tone = preset.defaultTone ?? "info";
30575
30700
  const \u7E1E\u3092\u6577\u304F = preset.rowStripe ?? true;
30576
- const b = diagram(preset.id, { topic: preset.topic, palette: preset.palette });
30701
+ const b = diagram(preset.id, { topic: preset.topic, palette: preset.palette, type: "er" });
30577
30702
  const entities = [];
30578
30703
  const phaseActivate = [];
30579
30704
  let relIdx = 0;
@@ -30659,7 +30784,7 @@ var FSM_ACTION_MARK = {
30659
30784
  function stateMachine(preset) {
30660
30785
  const stateW = resolveStateW(preset.stateWidth, "stateMachine");
30661
30786
  const tone = preset.defaultTone ?? "accent";
30662
- const b = diagram(preset.id, { topic: preset.topic });
30787
+ const b = diagram(preset.id, { topic: preset.topic, type: "state" });
30663
30788
  const phaseActivate = [];
30664
30789
  const stateOrder = /* @__PURE__ */ new Map();
30665
30790
  const \u72B6\u614B = [];
@@ -30771,7 +30896,7 @@ function infrastructure(preset) {
30771
30896
  const laneW = preset.laneWidth ?? 380;
30772
30897
  const tone = preset.defaultTone ?? "accent";
30773
30898
  const style = preset.defaultStyle ?? "solid";
30774
- const b = diagram(preset.id, { topic: preset.topic });
30899
+ const b = diagram(preset.id, { topic: preset.topic, type: "infrastructure" });
30775
30900
  const colLaneIds = /* @__PURE__ */ new Map();
30776
30901
  const phaseActivate = [];
30777
30902
  let connIdx = 0;
@@ -30852,7 +30977,7 @@ function classDiagram(preset) {
30852
30977
  const classW = resolveStorageBoxW(preset.classWidth, "classDiagram", "classWidth");
30853
30978
  const \u56F3\u306E\u65E2\u5B9A = preset.defaultTone;
30854
30979
  const \u7E1E\u3092\u6577\u304F = preset.rowStripe ?? true;
30855
- const b = diagram(preset.id, { topic: preset.topic, palette: preset.palette });
30980
+ const b = diagram(preset.id, { topic: preset.topic, palette: preset.palette, type: "class" });
30856
30981
  const classes = [];
30857
30982
  const phaseActivate = [];
30858
30983
  const \u7BB1 = [];
@@ -30939,7 +31064,7 @@ function classDiagram(preset) {
30939
31064
  function tree(preset) {
30940
31065
  const canvasW = preset.nodeWidth ? preset.nodeWidth * 2 : 720;
30941
31066
  const canvasH = 480;
30942
- const b = diagram(preset.id, { topic: preset.topic });
31067
+ const b = diagram(preset.id, { topic: preset.topic, type: "tree" });
30943
31068
  const treeNodes = [];
30944
31069
  const api = {
30945
31070
  node(n) {
@@ -30977,7 +31102,7 @@ function tree(preset) {
30977
31102
  function userJourney(preset) {
30978
31103
  const canvasW = preset.stepWidth ? preset.stepWidth * 2 : 720;
30979
31104
  const canvasH = 480;
30980
- const b = diagram(preset.id, { topic: preset.topic });
31105
+ const b = diagram(preset.id, { topic: preset.topic, type: "journey" });
30981
31106
  const steps = [];
30982
31107
  const api = {
30983
31108
  step(s) {
@@ -31016,7 +31141,7 @@ function userJourney(preset) {
31016
31141
  function mindMap(preset) {
31017
31142
  const canvasW = preset.branchWidth ? preset.branchWidth * 2 : 720;
31018
31143
  const canvasH = 480;
31019
- const b = diagram(preset.id, { topic: preset.topic });
31144
+ const b = diagram(preset.id, { topic: preset.topic, type: "mindmap" });
31020
31145
  const branches = [];
31021
31146
  const api = {
31022
31147
  branch(br) {
@@ -31060,7 +31185,7 @@ function mindMap(preset) {
31060
31185
  function funnel(preset) {
31061
31186
  const canvasW = toGridSize(preset.stageWidth ?? 560);
31062
31187
  const canvasH = 480;
31063
- const b = diagram(preset.id, { topic: preset.topic });
31188
+ const b = diagram(preset.id, { topic: preset.topic, type: "funnel" });
31064
31189
  const stages = [];
31065
31190
  const api = {
31066
31191
  stage(s) {
@@ -31098,7 +31223,7 @@ function funnel(preset) {
31098
31223
  function quadrant(preset) {
31099
31224
  const canvasW = 640;
31100
31225
  const canvasH = 480;
31101
- const b = diagram(preset.id, { topic: preset.topic });
31226
+ const b = diagram(preset.id, { topic: preset.topic, type: "quadrant" });
31102
31227
  const items = [];
31103
31228
  const api = {
31104
31229
  item(it) {
@@ -31149,7 +31274,7 @@ function chart(preset) {
31149
31274
  const canvasH = toGridSize(
31150
31275
  preset.type === "pie" || preset.type === "gauge" || preset.type === "radial" || preset.type === "stat" || preset.type === "waffle" || preset.type === "stacked-bar" ? 320 : 360
31151
31276
  );
31152
- const b = diagram(preset.id, { topic: preset.topic });
31277
+ const b = diagram(preset.id, { topic: preset.topic, type: "chart" });
31153
31278
  const data = [];
31154
31279
  const kindMap = {
31155
31280
  line: "chart-line",
@@ -31198,7 +31323,7 @@ function gantt(preset) {
31198
31323
  const canvasW = preset.laneWidth ? preset.laneWidth * 2 : 720;
31199
31324
  const canvasH = 360;
31200
31325
  const tone = preset.defaultTone ?? "teal";
31201
- const b = diagram(preset.id, { topic: preset.topic });
31326
+ const b = diagram(preset.id, { topic: preset.topic, type: "gantt" });
31202
31327
  const tasks = [];
31203
31328
  const api = {
31204
31329
  task(t) {
@@ -31264,7 +31389,7 @@ var SHAPE_EYEBROW = {
31264
31389
  function flowchart(preset) {
31265
31390
  const laneW = preset.laneWidth ?? 380;
31266
31391
  const tone = preset.defaultTone ?? "accent";
31267
- const b = diagram(preset.id, { topic: preset.topic });
31392
+ const b = diagram(preset.id, { topic: preset.topic, type: "flowchart" });
31268
31393
  const laneToId = /* @__PURE__ */ new Map();
31269
31394
  const laneStackCount = /* @__PURE__ */ new Map();
31270
31395
  for (const label of preset.lanes) {
@@ -31325,7 +31450,7 @@ var NET_KIND_MAP = {
31325
31450
  function network(preset) {
31326
31451
  const laneW = preset.laneWidth ?? 320;
31327
31452
  const tone = preset.defaultTone ?? "info";
31328
- const b = diagram(preset.id, { topic: preset.topic });
31453
+ const b = diagram(preset.id, { topic: preset.topic, type: "network" });
31329
31454
  const colLaneIds = /* @__PURE__ */ new Map();
31330
31455
  const phaseActivate = [];
31331
31456
  let edgeIdx = 0;
@@ -31375,7 +31500,7 @@ function stateMachine2(preset) {
31375
31500
  const stateW = resolveStateW(preset.stateWidth, "stateMachine2");
31376
31501
  const laneW = boxLaneW(stateW);
31377
31502
  const tone = preset.defaultTone ?? "accent";
31378
- const b = diagram(preset.id, { topic: preset.topic });
31503
+ const b = diagram(preset.id, { topic: preset.topic, type: "state" });
31379
31504
  const stateOrder = /* @__PURE__ */ new Map();
31380
31505
  const phaseActivate = [];
31381
31506
  let transIdx = 0;