@cardenelabs/cdl 0.83.0 → 0.102.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +851 -1
  2. package/dist/index.cjs +878 -186
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +17 -3
  5. package/dist/index.d.ts +17 -3
  6. package/dist/index.js +878 -186
  7. package/dist/index.js.map +1 -1
  8. package/dist/react.cjs +869 -178
  9. package/dist/react.cjs.map +1 -1
  10. package/dist/react.d.cts +1 -1
  11. package/dist/react.d.ts +1 -1
  12. package/dist/react.js +869 -178
  13. package/dist/react.js.map +1 -1
  14. package/dist/{render-DfXCs3Eh.d.cts → render-oEmwYN-q.d.cts} +21 -3
  15. package/dist/{render-DfXCs3Eh.d.ts → render-oEmwYN-q.d.ts} +21 -3
  16. package/package.json +1 -1
  17. package/src/kinds/chart-gauge.tsx +20 -3
  18. package/src/kinds/chart-legend-number.tsx +33 -0
  19. package/src/kinds/chart-number.ts +33 -0
  20. package/src/kinds/chart-radial.tsx +24 -7
  21. package/src/kinds/chart-stat.tsx +35 -5
  22. package/src/kinds/chart-waffle.tsx +25 -7
  23. package/src/kinds/dyn-shape.tsx +72 -12
  24. package/src/kinds/funnel.tsx +50 -2
  25. package/src/kinds/mind-map.tsx +206 -64
  26. package/src/kinds/quadrant.tsx +318 -45
  27. package/src/kinds/shape-blockchain.tsx +50 -18
  28. package/src/kinds/shape-commerce.tsx +27 -4
  29. package/src/kinds/shape-region.tsx +42 -1
  30. package/src/kinds/shape-software.tsx +51 -12
  31. package/src/kinds/storage.tsx +16 -8
  32. package/src/kinds/tree.tsx +46 -10
  33. package/src/lang.ts +5 -5
  34. package/src/layout/nodes.ts +3 -1
  35. package/src/layout/spec.ts +154 -25
  36. package/src/layout/text-width.ts +25 -0
  37. package/src/layout/viewbox.ts +32 -0
  38. package/src/presets.ts +21 -7
  39. package/src/render/nodes.tsx +77 -0
  40. package/src/render/payload-binding.ts +108 -25
  41. package/src/render/stage.tsx +24 -2
  42. package/src/types.ts +117 -38
  43. package/src/visual-validate.ts +61 -1
package/dist/react.js CHANGED
@@ -361,22 +361,22 @@ function resolveLang(value) {
361
361
  return value === "ja" ? "ja" : "en";
362
362
  }
363
363
  var en = {
364
- /** `shape-terminal` の 2 行目 (命令の出力) */
365
364
  /*
366
- * `shape-terminal` の出力の行。
365
+ * `shape-terminal` の出力の行を **書かない時** の控え (#927)。
367
366
  *
368
367
  * **いちばん長い行が絵の倍率を決める** (#891)。 端末の中身は自分の座標で組んでから箱へ
369
368
  * 収めるので、この行が長いほど全部の字が小さくなる。 120x110 の箱では 20 字の版で
370
- * 7.71 world まで落ちていた。
369
+ * 7.71 world まで落ちていた。 書いた説明を通すようになったので、長い説明を渡した図でも
370
+ * 同じことが起きる。
371
371
  */
372
372
  "terminal.output": "\u2192 12 chunks",
373
- /** `shape-code-block` の札の file 名 */
373
+ /** `shape-code-block` の札の file 名を **書かない時** の控え (#927) */
374
374
  "codeBlock.fileName": "utils.ts",
375
375
  /** `shape-kanban-card` の課題の番号 */
376
376
  "kanbanCard.id": "CAR-1111",
377
377
  /** `shape-kanban-card` の状態の札 */
378
378
  "kanbanCard.status": "IN PROG",
379
- /** `shape-kanban-card` の題の下の説明 */
379
+ /** `shape-kanban-card` の題の下の説明を **書かない時** の控え (#927) */
380
380
  "kanbanCard.task": "shape-driven kind \u5B9F\u88C5",
381
381
  /** `shape-kanban-card` の期日 */
382
382
  "kanbanCard.due": "Jul 10",
@@ -899,6 +899,11 @@ function measureTextWidth(text, opts = {}) {
899
899
  const w = advanceEmSum * fontSize + letterSpacing * charCount;
900
900
  return Math.max(w, fontSize * 1.2);
901
901
  }
902
+ function \u53CE\u3081\u308B\u500D\u7387(text, opts, \u5E45) {
903
+ if (!(\u5E45 > 0) || !(opts.fontSize > 0)) return 1;
904
+ const \u5B9F\u5E45 = measureTextWidth(text, { ...opts, letterSpacing: 0 });
905
+ return \u5B9F\u5E45 > \u5E45 ? \u5E45 / \u5B9F\u5E45 : 1;
906
+ }
902
907
 
903
908
  // src/label-text.ts
904
909
  var EDGE_LABEL_TEXT = {
@@ -933,17 +938,7 @@ var LABEL_PILL_PAD_X = 18;
933
938
  function hasRenderedLabel(e) {
934
939
  return Boolean(e.label?.trim() || e.sub?.trim());
935
940
  }
936
- var KINDS_WITHOUT_TITLE_TEXT = /* @__PURE__ */ new Set([
937
- // 時系列のやり取り (#578)。 図を丸ごと描く種別で、描くのは面々の名前と言づての語。
938
- // 箱の `title` は使わない
939
- "sequence-board",
940
- // 形だけを描く (DynShapeNode)
941
- "dyn-rect",
942
- "dyn-circle",
943
- "dyn-arc",
944
- "dyn-wave",
945
- "dyn-polygon",
946
- // payload を自前 layout して描く (label は payload 側が持つ)
941
+ var KINDS_DRAWING_OWN_PAYLOAD = /* @__PURE__ */ new Set([
947
942
  "chart-pie",
948
943
  "chart-line",
949
944
  "chart-bar",
@@ -958,22 +953,27 @@ var KINDS_WITHOUT_TITLE_TEXT = /* @__PURE__ */ new Set([
958
953
  "funnel-stages",
959
954
  "quadrant-matrix",
960
955
  "tree-hierarchy",
961
- "journey-map",
962
- // 印そのものが意味を持つ (#560)
956
+ "journey-map"
957
+ ]);
958
+ function drawsFigureTitle(kind) {
959
+ return KINDS_DRAWING_OWN_PAYLOAD.has(kind ?? "");
960
+ }
961
+ var KINDS_WITHOUT_TITLE_TEXT = /* @__PURE__ */ new Set([
962
+ "sequence-board",
963
963
  "mark-start",
964
964
  "mark-end"
965
965
  ]);
966
966
  function rendersTitleText(kind) {
967
967
  return !KINDS_WITHOUT_TITLE_TEXT.has(kind ?? "");
968
968
  }
969
- var KINDS_FITTING_OWN_TITLE = /* @__PURE__ */ new Set(["shape-blockchain-block"]);
969
+ var KINDS_FITTING_OWN_TITLE = /* @__PURE__ */ new Set([
970
+ "shape-blockchain-block",
971
+ ...KINDS_DRAWING_OWN_PAYLOAD
972
+ ]);
970
973
  function fitsOwnTitleWidth(kind) {
971
974
  return KINDS_FITTING_OWN_TITLE.has(kind ?? "");
972
975
  }
973
- var KINDS_WITH_ROW_TEXT = /* @__PURE__ */ new Set([
974
- // 専用の表組み (StorageNode)
975
- "storage",
976
- // 汎用描画 (GenericNode)
976
+ var KINDS_DRAWN_BY_GENERIC = [
977
977
  "person",
978
978
  "user-group",
979
979
  "admin",
@@ -995,10 +995,44 @@ var KINDS_WITH_ROW_TEXT = /* @__PURE__ */ new Set([
995
995
  "oracle",
996
996
  "merkle-tree",
997
997
  "decision"
998
+ ];
999
+ var KINDS_WITH_ROW_TEXT = /* @__PURE__ */ new Set([
1000
+ // 専用の表組み (StorageNode)
1001
+ "storage",
1002
+ ...KINDS_DRAWN_BY_GENERIC
998
1003
  ]);
999
1004
  function rendersRows(kind) {
1000
1005
  return KINDS_WITH_ROW_TEXT.has(kind ?? "");
1001
1006
  }
1007
+ var KINDS_DRAWING_ONLY_SHAPE = [
1008
+ "dyn-rect",
1009
+ "dyn-circle",
1010
+ "dyn-arc",
1011
+ "dyn-wave",
1012
+ "dyn-polygon"
1013
+ ];
1014
+ var KINDS_WITHOUT_EYEBROW_TEXT = /* @__PURE__ */ new Set([
1015
+ ...KINDS_DRAWING_ONLY_SHAPE,
1016
+ ...KINDS_WITHOUT_TITLE_TEXT
1017
+ ]);
1018
+ function rendersEyebrow(kind) {
1019
+ return !KINDS_WITHOUT_EYEBROW_TEXT.has(kind ?? "");
1020
+ }
1021
+ var KINDS_WITHOUT_SUBTITLE_TEXT = /* @__PURE__ */ new Set([
1022
+ ...KINDS_DRAWING_OWN_PAYLOAD,
1023
+ ...KINDS_WITHOUT_TITLE_TEXT
1024
+ ]);
1025
+ function rendersSubtitle(kind) {
1026
+ return !KINDS_WITHOUT_SUBTITLE_TEXT.has(kind ?? "");
1027
+ }
1028
+ var KINDS_WITH_VALUE_TEXT = /* @__PURE__ */ new Set([
1029
+ // 面々の絵 (ActorNode)
1030
+ "actor",
1031
+ ...KINDS_DRAWN_BY_GENERIC
1032
+ ]);
1033
+ function rendersValue(kind) {
1034
+ return KINDS_WITH_VALUE_TEXT.has(kind ?? "");
1035
+ }
1002
1036
  function rowBaselineY(kind, index) {
1003
1037
  if (!rendersRows(kind)) return null;
1004
1038
  return kind === "storage" ? ROW_TOP_STORAGE + index * ROW_PITCH_STORAGE : ROW_TOP_GENERIC + genericTextShift(kind) + index * ROW_PITCH_GENERIC;
@@ -3041,6 +3075,15 @@ function requiredRowsWidth(rows, kind) {
3041
3075
  if (kind === void 0) return Math.ceil(Math.max(storage, generic));
3042
3076
  return Math.ceil(kind === "storage" ? storage : generic);
3043
3077
  }
3078
+ function \u66F8\u3044\u305F\u5024\u304B\u63A7\u3048(\u66F8\u3044\u305F, \u63A7\u3048) {
3079
+ const v = (\u66F8\u3044\u305F ?? "").trim();
3080
+ return v === "" ? \u63A7\u3048 : v;
3081
+ }
3082
+ function \u5E45\u306E\u500D\u7387(text, size, letterSpacing, \u5E45) {
3083
+ if (!(\u5E45 > 0) || !(size > 0)) return 1;
3084
+ const \u5B9F\u5E45 = textWidth(text, size, letterSpacing);
3085
+ return \u5B9F\u5E45 > \u5E45 ? \u5E45 / \u5B9F\u5E45 : 1;
3086
+ }
3044
3087
  var TITLE_MAX = 18;
3045
3088
  var TITLE_MIN = 9;
3046
3089
  var TITLE_RATIO = 0.17;
@@ -3067,7 +3110,10 @@ var \u843D\u3068\u3057\u3066\u3082\u63CF\u304F\u7A2E\u5225 = {
3067
3110
  "shape-code-block",
3068
3111
  "shape-message-bubble",
3069
3112
  "shape-gear",
3070
- // hardware 系のうち固有 layout を持つもの
3113
+ // 絵の中の字の口に肩書を通す 2 種別 (#941)。 状態の札 / 見出しの帯の右 に描く
3114
+ "shape-kanban-card",
3115
+ "shape-blockchain-block",
3116
+ // hardware / blockchain 系のうち固有 layout を持つもの
3071
3117
  "shape-iot-sensor",
3072
3118
  "shape-robot-arm"
3073
3119
  ]),
@@ -3084,6 +3130,10 @@ var \u843D\u3068\u3057\u3066\u3082\u63CF\u304F\u7A2E\u5225 = {
3084
3130
  "shape-window",
3085
3131
  "shape-message-bubble",
3086
3132
  "shape-gear",
3133
+ // 絵の中の字の口に説明を通す 3 種別 (#927)。 札の file 名 / 出力の行 / 課題の 1 行 に描く
3134
+ "shape-terminal",
3135
+ "shape-code-block",
3136
+ "shape-kanban-card",
3087
3137
  // hardware / blockchain 系のうち固有 layout を持つもの
3088
3138
  "shape-iot-sensor",
3089
3139
  "shape-robot-arm",
@@ -4318,7 +4368,9 @@ function needsResolve(raw) {
4318
4368
  return typeof raw !== "number" || !Number.isFinite(raw);
4319
4369
  }
4320
4370
  function resolveChartData(data, values) {
4321
- if (!data.some((d) => needsResolve(d.value) || d.previous !== void 0 && needsResolve(d.previous)))
4371
+ if (!data.some(
4372
+ (d) => needsResolve(d.value) || d.previous !== void 0 && needsResolve(d.previous)
4373
+ ))
4322
4374
  return data;
4323
4375
  return data.map((d) => {
4324
4376
  const v = resolveBoundNumber(d.value, values, 0);
@@ -4329,14 +4381,24 @@ function resolveChartData(data, values) {
4329
4381
  });
4330
4382
  }
4331
4383
  function resolveFunnelData(stages, values) {
4332
- if (!stages.some((s) => needsResolve(s.count))) return stages;
4384
+ const \u8AAD\u3080 = stages.some(
4385
+ (s) => needsResolve(s.count) || (s.subtitle?.includes("{") ?? false)
4386
+ );
4387
+ if (!\u8AAD\u3080) return stages;
4333
4388
  return stages.map((s) => {
4334
4389
  const c = resolveBoundNumber(s.count, values, 0);
4335
- return c.ok ? { ...s, count: c.value } : { ...s, count: c.value, unresolved: true };
4390
+ const sub = s.subtitle === void 0 ? void 0 : resolveBoundText(s.subtitle, values);
4391
+ const \u7D20 = {
4392
+ ...s,
4393
+ count: c.value,
4394
+ ...sub ? { subtitle: sub.value } : {}
4395
+ };
4396
+ return c.ok && (sub?.ok ?? true) ? \u7D20 : { ...\u7D20, unresolved: true };
4336
4397
  });
4337
4398
  }
4338
4399
  function resolveGanttData(tasks, values) {
4339
- if (!tasks.some((t) => needsResolve(t.startIdx) || needsResolve(t.endIdx))) return tasks;
4400
+ if (!tasks.some((t) => needsResolve(t.startIdx) || needsResolve(t.endIdx)))
4401
+ return tasks;
4340
4402
  return tasks.map((t) => {
4341
4403
  const start = resolveBoundNumber(t.startIdx, values, 0);
4342
4404
  const end = resolveBoundNumber(t.endIdx, values, start.value);
@@ -4344,16 +4406,48 @@ function resolveGanttData(tasks, values) {
4344
4406
  return start.ok && end.ok ? next : { ...next, unresolved: true };
4345
4407
  });
4346
4408
  }
4409
+ function \u5EA7\u6A19\u306E\u8C61\u9650(x, y) {
4410
+ const \u53F3 = x >= 0.5;
4411
+ const \u4E0A = y >= 0.5;
4412
+ if (\u4E0A) return \u53F3 ? "topRight" : "topLeft";
4413
+ return \u53F3 ? "bottomRight" : "bottomLeft";
4414
+ }
4415
+ var \u57DF\u306B\u53CE\u3081\u308B = (v) => Math.min(1, Math.max(0, v));
4347
4416
  function resolveQuadrantData(data, values) {
4348
4417
  const items = data.items;
4349
- if (items.every((i) => QUADRANT_KEYS.includes(i.quadrant))) {
4350
- return data;
4351
- }
4418
+ const \u8FD1\u9053 = !items.some((i) => i.at !== void 0) && !items.some((i) => i.subtitle?.includes("{") ?? false) && items.every((i) => QUADRANT_KEYS.includes(i.quadrant ?? ""));
4419
+ if (\u8FD1\u9053) return data;
4352
4420
  return {
4353
4421
  ...data,
4354
4422
  items: items.map((i) => {
4355
- const q = resolveBoundEnum(i.quadrant, values, QUADRANT_KEYS, QUADRANT_FALLBACK);
4356
- return q.ok ? { ...i, quadrant: q.value } : { ...i, quadrant: q.value, unresolved: true };
4423
+ if (i.at !== void 0) {
4424
+ const x = resolveBoundNumber(i.at.x, values, 0.5);
4425
+ const y = resolveBoundNumber(i.at.y, values, 0.5);
4426
+ const \u7F6E\u304F = { x: \u57DF\u306B\u53CE\u3081\u308B(x.value), y: \u57DF\u306B\u53CE\u3081\u308B(y.value) };
4427
+ const sub2 = i.subtitle === void 0 ? void 0 : resolveBoundText(i.subtitle, values);
4428
+ const \u7D202 = {
4429
+ id: i.id,
4430
+ title: i.title,
4431
+ at: \u7F6E\u304F,
4432
+ quadrant: \u5EA7\u6A19\u306E\u8C61\u9650(\u7F6E\u304F.x, \u7F6E\u304F.y),
4433
+ ...sub2 ? { subtitle: sub2.value } : {}
4434
+ };
4435
+ return x.ok && y.ok && (sub2?.ok ?? true) ? \u7D202 : { ...\u7D202, unresolved: true };
4436
+ }
4437
+ const q = resolveBoundEnum(
4438
+ i.quadrant ?? "",
4439
+ values,
4440
+ QUADRANT_KEYS,
4441
+ QUADRANT_FALLBACK
4442
+ );
4443
+ const sub = i.subtitle === void 0 ? void 0 : resolveBoundText(i.subtitle, values);
4444
+ const \u7D20 = {
4445
+ id: i.id,
4446
+ title: i.title,
4447
+ quadrant: q.value,
4448
+ ...sub ? { subtitle: sub.value } : {}
4449
+ };
4450
+ return q.ok && (sub?.ok ?? true) ? \u7D20 : { ...\u7D20, unresolved: true };
4357
4451
  })
4358
4452
  };
4359
4453
  }
@@ -4473,13 +4567,10 @@ var PAD_TOP = 40;
4473
4567
  var PAD_RIGHT = 24;
4474
4568
  var PAD_BOTTOM = 40;
4475
4569
  var PAD_LEFT = 24;
4570
+ var \u6728\u306E\u679D\u306E\u592A\u3055 = (\u6BB5) => Math.max(1.1, 2.6 - \u6BB5 * 0.45);
4476
4571
  function \u6728\u306E\u4E2D\u8EAB(node, stateValues = {}) {
4477
4572
  const treeNodes = resolveTreeData(node.treeData ?? [], stateValues);
4478
- return computeTreeLayout(
4479
- treeNodes,
4480
- node.w - PAD_LEFT - PAD_RIGHT,
4481
- node.h - PAD_TOP - PAD_BOTTOM
4482
- );
4573
+ return computeTreeLayout(treeNodes, node.w - PAD_LEFT - PAD_RIGHT, node.h - PAD_TOP - PAD_BOTTOM);
4483
4574
  }
4484
4575
  function \u6728\u306E\u884C(n) {
4485
4576
  return [
@@ -4538,7 +4629,7 @@ function TreeNode({
4538
4629
  fill: "none",
4539
4630
  stroke: TONE.accent,
4540
4631
  strokeOpacity: 0.55,
4541
- strokeWidth: 1.5,
4632
+ strokeWidth: \u6728\u306E\u679D\u306E\u592A\u3055(e.depth),
4542
4633
  strokeLinejoin: "round",
4543
4634
  ...\u4F38\u3070\u3059dash(drawing, \u679D\u306E\u4F38\u3073)
4544
4635
  }
@@ -4673,11 +4764,20 @@ function computeTreeLayout(treeNodes, canvasW, canvasH) {
4673
4764
  if (kids.length === 0) return 1;
4674
4765
  return kids.reduce((sum, k) => sum + leafCount(k.id, seen), 0);
4675
4766
  };
4676
- const totalLeaves = Math.max(roots.reduce((sum, r) => sum + leafCount(r.id, /* @__PURE__ */ new Set()), 0), 1);
4767
+ const totalLeaves = Math.max(
4768
+ roots.reduce((sum, r) => sum + leafCount(r.id, /* @__PURE__ */ new Set()), 0),
4769
+ 1
4770
+ );
4677
4771
  const depthGap = canvasH / Math.max(maxDepth + 1, 1);
4678
4772
  const slotW = canvasW / totalLeaves;
4679
4773
  const nodeH = Math.min(38, depthGap * 0.7);
4680
4774
  const nodeW = Math.min(140, slotW * 0.85);
4775
+ const \u7BB1\u306E\u5E45 = (n, depth) => {
4776
+ const \u6750\u6599 = \u6728\u306E\u884C({ ...n, depth });
4777
+ const \u540D\u524D = \u6750\u6599[0];
4778
+ const \u8981\u308B = measureTextWidth(\u540D\u524D.text, { fontSize: \u540D\u524D.fontSize}) + (nodeW - \u4F7F\u3048\u308B\u5E45(nodeW));
4779
+ return Math.min(Math.max(\u8981\u308B, nodeW), slotW * 0.92);
4780
+ };
4681
4781
  const posOf = /* @__PURE__ */ new Map();
4682
4782
  const nodes = [];
4683
4783
  const placed = /* @__PURE__ */ new Set();
@@ -4701,7 +4801,7 @@ function computeTreeLayout(treeNodes, canvasW, canvasH) {
4701
4801
  ...n.subtitle !== void 0 ? { subtitle: n.subtitle } : {},
4702
4802
  x,
4703
4803
  y,
4704
- w: nodeW,
4804
+ w: \u7BB1\u306E\u5E45(n, depth),
4705
4805
  h: nodeH,
4706
4806
  depth,
4707
4807
  ...n.unresolved ? { unresolved: true } : {}
@@ -4752,6 +4852,10 @@ function computeTreeLayout(treeNodes, canvasW, canvasH) {
4752
4852
  }
4753
4853
  var MIND_TONES = ["accent", "teal", "success", "warning", "info", "error"];
4754
4854
  var MIND_BOX_GAP = 24;
4855
+ var \u679D\u306E\u592A\u3055 = (\u6BB5) => Math.max(1.2, 3.2 - \u6BB5 * 0.7);
4856
+ var BRANCH_BOX_H_MAX = 48;
4857
+ var SUB_BOX_H_MAX = 40;
4858
+ var ROW_GAP_MAX = 96;
4755
4859
  var MIND_PAD = 40;
4756
4860
  function \u653E\u5C04\u306E\u4E2D\u8EAB(node, stateValues = {}) {
4757
4861
  const mindData = node.mindData ? resolveMindData(node.mindData, stateValues) : void 0;
@@ -4808,7 +4912,7 @@ function MindMapNode({
4808
4912
  d: e.d,
4809
4913
  fill: "none",
4810
4914
  stroke: toneColor2(e.tone),
4811
- strokeWidth: 2.5,
4915
+ strokeWidth: \u679D\u306E\u592A\u3055(e.depth),
4812
4916
  strokeOpacity: 0.55,
4813
4917
  strokeLinecap: "round",
4814
4918
  ...\u4F38\u3070\u3059dash(drawing, \u679D\u306E\u4F38\u3073)
@@ -4819,13 +4923,19 @@ function MindMapNode({
4819
4923
  layout2.nodes.map((n) => {
4820
4924
  if (!\u7BB1\u304C\u51FA\u308B(n.depth)) return null;
4821
4925
  const \u6750\u6599 = \u653E\u5C04\u306E\u884C(n);
4822
- const \u884C = \u7BB1\u306B\u7A4D\u3080(\u6750\u6599, n.w, n.h);
4823
4926
  const \u88DC\u8DB3\u3042\u308A = (n.subtitle ?? "").trim() !== "";
4824
4927
  const \u540D\u524D = \u6750\u6599[0];
4825
- const \u53CE\u3081\u305F\u540D\u524D = \u88DC\u8DB3\u3042\u308A ? void 0 : \u5E45\u306B\u53CE\u3081\u308B(\u540D\u524D.text, \u540D\u524D.fontSize, \u4F7F\u3048\u308B\u5E45(n.w));
4928
+ const \u67A0\u306A\u3057 = !n.isRoot && n.isLeaf;
4929
+ const \u5916\u3078 = n.side === "right";
4930
+ const \u6587\u5B57\u306Ex = \u67A0\u306A\u3057 ? n.x + (\u5916\u3078 ? -n.w / 2 : n.w / 2) : n.x;
4931
+ const \u6587\u5B57\u306E\u5BC4\u305B = \u67A0\u306A\u3057 ? \u5916\u3078 ? "start" : "end" : "middle";
4932
+ const \u63CF\u753B\u57DF\u306E\u7AEF = \u5916\u3078 ? node.w - MIND_PAD : MIND_PAD;
4933
+ const \u4F7F\u3048\u308B = \u67A0\u306A\u3057 ? Math.abs(\u63CF\u753B\u57DF\u306E\u7AEF - \u6587\u5B57\u306Ex) : \u4F7F\u3048\u308B\u5E45(n.w);
4934
+ const \u53CE\u3081\u305F\u540D\u524D = \u88DC\u8DB3\u3042\u308A ? void 0 : \u5E45\u306B\u53CE\u3081\u308B(\u540D\u524D.text, \u540D\u524D.fontSize, \u4F7F\u3048\u308B);
4935
+ const \u884C = \u7BB1\u306B\u7A4D\u3080(\u6750\u6599, \u67A0\u306A\u3057 ? \u4F7F\u3048\u308B + (n.w - \u4F7F\u3048\u308B\u5E45(n.w)) : n.w, n.h);
4826
4936
  const \u6587\u5B57\u306E\u8272 = n.isRoot ? "var(--cdl-text-on-tone, #ffffff)" : "var(--cdl-chip-text, #1a1f2a)";
4827
4937
  return /* @__PURE__ */ jsxs("g", { "data-cdl-unresolved": n.unresolved ? "true" : void 0, children: [
4828
- /* @__PURE__ */ jsx(
4938
+ \u67A0\u306A\u3057 ? null : /* @__PURE__ */ jsx(
4829
4939
  "rect",
4830
4940
  {
4831
4941
  x: n.x - n.w / 2,
@@ -4842,11 +4952,11 @@ function MindMapNode({
4842
4952
  "text",
4843
4953
  {
4844
4954
  "data-cdl-role": r.\u5F79\u5272 === "subtitle" ? "mind-node-subtitle" : void 0,
4845
- x: n.x,
4955
+ x: \u6587\u5B57\u306Ex,
4846
4956
  y: n.y + r.dy,
4847
4957
  fontSize: r.fontSize,
4848
4958
  fontWeight: r.\u5F79\u5272 === "title" ? n.isRoot ? 700 : 600 : 500,
4849
- textAnchor: "middle",
4959
+ textAnchor: \u6587\u5B57\u306E\u5BC4\u305B,
4850
4960
  fill: \u6587\u5B57\u306E\u8272,
4851
4961
  opacity: r.\u5F79\u5272 === "subtitle" ? 0.85 : void 0,
4852
4962
  children: r.text
@@ -4860,11 +4970,11 @@ function MindMapNode({
4860
4970
  /* @__PURE__ */ jsx(
4861
4971
  "text",
4862
4972
  {
4863
- x: n.x,
4973
+ x: \u6587\u5B57\u306Ex,
4864
4974
  y: n.y + 5,
4865
4975
  fontSize: \u53CE\u3081\u305F\u540D\u524D.fontSize,
4866
4976
  fontWeight: n.isRoot ? 700 : 600,
4867
- textAnchor: "middle",
4977
+ textAnchor: \u6587\u5B57\u306E\u5BC4\u305B,
4868
4978
  fill: \u6587\u5B57\u306E\u8272,
4869
4979
  children: \u53CE\u3081\u305F\u540D\u524D.text
4870
4980
  }
@@ -4874,6 +4984,13 @@ function MindMapNode({
4874
4984
  })
4875
4985
  ] });
4876
4986
  }
4987
+ function \u63CF\u304F\u6A2A\u306E\u7AEF(n) {
4988
+ if (n.isRoot || !n.isLeaf) return [n.x - n.w / 2, n.x + n.w / 2];
4989
+ const \u8D77\u70B9 = n.x + (n.side === "right" ? -n.w / 2 : n.w / 2);
4990
+ const \u540D\u524D = \u653E\u5C04\u306E\u884C(n)[0];
4991
+ const \u5E45 = measureTextWidth(\u540D\u524D.text, { fontSize: \u540D\u524D.fontSize});
4992
+ return n.side === "right" ? [\u8D77\u70B9, \u8D77\u70B9 + \u5E45] : [\u8D77\u70B9 - \u5E45, \u8D77\u70B9];
4993
+ }
4877
4994
  function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
4878
4995
  const nodes = [];
4879
4996
  const edges = [];
@@ -4889,6 +5006,9 @@ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
4889
5006
  w: rootW,
4890
5007
  h: rootH,
4891
5008
  isRoot: true,
5009
+ // 中心は枝を持たなくても枠を描く = 図の起点なので、無いと何から広がるのかが読めない
5010
+ isLeaf: false,
5011
+ side: "right",
4892
5012
  // 中心は起点なので段数 0 (cdl#520)
4893
5013
  depth: 0,
4894
5014
  ...mindData.unresolved ? { unresolved: true } : {}
@@ -4925,7 +5045,6 @@ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
4925
5045
  const firstCount = firstLevel.length;
4926
5046
  const leftCount = Math.ceil(firstCount / 2);
4927
5047
  const branchW = 130;
4928
- const branchH = 38;
4929
5048
  const subBranchW = 100;
4930
5049
  const subBranchH = 30;
4931
5050
  const subDepthOf = (id, seen) => {
@@ -4959,22 +5078,27 @@ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
4959
5078
  const subOffset = (subDepth) => subDepth <= 0 ? 0 : step1 + (subDepth - 1) * stepN;
4960
5079
  const leftBranches = firstLevel.slice(0, leftCount);
4961
5080
  const rightBranches = firstLevel.slice(leftCount);
4962
- const leavesOfSide = (brs) => Math.max(1, brs.reduce((sum, br) => sum + leafCountOf(br.id, /* @__PURE__ */ new Set()), 0));
5081
+ const leavesOfSide = (brs) => Math.max(
5082
+ 1,
5083
+ brs.reduce((sum, br) => sum + leafCountOf(br.id, /* @__PURE__ */ new Set()), 0)
5084
+ );
4963
5085
  const sideLaneCount = Math.max(leavesOfSide(leftBranches), leavesOfSide(rightBranches));
4964
- const laneBandH = Math.min(canvasH * 0.9, sideLaneCount * (subBranchH + 14));
4965
- const rowGap = sideLaneCount > 1 ? laneBandH / (sideLaneCount - 1) : subBranchH + 14;
4966
- const effSubH = Math.min(subBranchH, rowGap * 0.7);
4967
- const effBranchH = Math.min(branchH, rowGap * 0.7);
4968
- const laneTop = cy - canvasH / 2 + effSubH / 2;
4969
- const laneBottom = cy + canvasH / 2 - effSubH / 2;
5086
+ const laneBandH = Math.max(0, canvasH - BRANCH_BOX_H_MAX);
5087
+ const rowGap = sideLaneCount > 1 ? Math.min(laneBandH / (sideLaneCount - 1), ROW_GAP_MAX) : subBranchH + 14;
5088
+ const effSubH = Math.min(SUB_BOX_H_MAX, rowGap * 0.7);
5089
+ const effBranchH = Math.min(BRANCH_BOX_H_MAX, rowGap * 0.7);
5090
+ const \u7AEF\u306E\u4F59\u308A = Math.max(effSubH, effBranchH) / 2;
5091
+ const laneTop = cy - canvasH / 2 + \u7AEF\u306E\u4F59\u308A;
5092
+ const laneBottom = cy + canvasH / 2 - \u7AEF\u306E\u4F59\u308A;
5093
+ const \u4F7F\u3046\u9AD8\u3055 = (sideLaneCount - 1) * rowGap;
4970
5094
  const laneY = (lane) => {
4971
5095
  if (sideLaneCount <= 1) return cy;
4972
- const y = cy - laneBandH / 2 + lane * rowGap;
5096
+ const y = cy - \u4F7F\u3046\u9AD8\u3055 / 2 + lane * rowGap;
4973
5097
  return Math.max(laneTop, Math.min(laneBottom, y));
4974
5098
  };
4975
- const rootEdgeXFor = (isLeft) => {
5099
+ const rootEdgeXFor = (isLeft, \u4E2D\u5FC3\u306Ex) => {
4976
5100
  const half = nodeHalfW.get(mindData.rootId) ?? rootW / 2;
4977
- return cx + (isLeft ? -half : half);
5101
+ return \u4E2D\u5FC3\u306Ex + (isLeft ? -half : half);
4978
5102
  };
4979
5103
  const placeSubtree = (node, subDepth, isLeft, tone, placed, laneRef) => {
4980
5104
  placed.add(node.id);
@@ -4990,7 +5114,14 @@ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
4990
5114
  laneRef.cursor += 1;
4991
5115
  } else {
4992
5116
  const ys = kids.map(
4993
- (k, i) => placeSubtree(k, subDepth + 1, isLeft, myTone ?? MIND_TONES[i % MIND_TONES.length], placed, laneRef)
5117
+ (k, i) => placeSubtree(
5118
+ k,
5119
+ subDepth + 1,
5120
+ isLeft,
5121
+ myTone ?? MIND_TONES[i % MIND_TONES.length],
5122
+ placed,
5123
+ laneRef
5124
+ )
4994
5125
  );
4995
5126
  y = (ys[0] + ys[ys.length - 1]) / 2;
4996
5127
  }
@@ -5006,6 +5137,8 @@ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
5006
5137
  depth: subDepth + 1,
5007
5138
  tone: myTone,
5008
5139
  isRoot: false,
5140
+ isLeaf: kids.length === 0,
5141
+ side: isLeft ? "left" : "right",
5009
5142
  ...node.unresolved ? { unresolved: true } : {}
5010
5143
  });
5011
5144
  nodePos.set(node.id, { x, y });
@@ -5015,7 +5148,8 @@ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
5015
5148
  return y;
5016
5149
  };
5017
5150
  const placeSide = (brs, isLeft, toneBase) => {
5018
- const laneRef = { cursor: 0 };
5151
+ const \u8449\u6570 = brs.reduce((sum, br) => sum + leafCountOf(br.id, /* @__PURE__ */ new Set()), 0);
5152
+ const laneRef = { cursor: Math.max(0, (sideLaneCount - \u8449\u6570) / 2) };
5019
5153
  const placed = /* @__PURE__ */ new Set();
5020
5154
  brs.forEach((br, i) => {
5021
5155
  const tone = br.tone ?? MIND_TONES[(toneBase + i) % MIND_TONES.length];
@@ -5045,6 +5179,23 @@ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
5045
5179
  }
5046
5180
  }
5047
5181
  }
5182
+ {
5183
+ let \u5DE6\u7AEF = Number.POSITIVE_INFINITY;
5184
+ let \u53F3\u7AEF = Number.NEGATIVE_INFINITY;
5185
+ for (const n of nodes) {
5186
+ const [l, r] = \u63CF\u304F\u6A2A\u306E\u7AEF(n);
5187
+ \u5DE6\u7AEF = Math.min(\u5DE6\u7AEF, l);
5188
+ \u53F3\u7AEF = Math.max(\u53F3\u7AEF, r);
5189
+ }
5190
+ const \u5BC4\u305B = Math.round((cx - \u5DE6\u7AEF - (\u53F3\u7AEF - cx)) / 2);
5191
+ if (Number.isFinite(\u5BC4\u305B) && \u5BC4\u305B !== 0) {
5192
+ for (const n of nodes) {
5193
+ n.x += \u5BC4\u305B;
5194
+ nodePos.set(n.id, { x: n.x, y: n.y });
5195
+ }
5196
+ }
5197
+ }
5198
+ const rootX = nodePos.get(mindData.rootId)?.x ?? cx;
5048
5199
  const \u6BB5\u6570 = new Map(nodes.map((n) => [n.id, n.depth]));
5049
5200
  for (const br of mindData.branches) {
5050
5201
  const childPos = nodePos.get(br.id);
@@ -5055,7 +5206,7 @@ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
5055
5206
  const childDepth = \u6BB5\u6570.get(br.id) ?? 1;
5056
5207
  const parentDepth = \u6BB5\u6570.get(br.parent) ?? 0;
5057
5208
  if (br.parent === mindData.rootId) {
5058
- const startX = rootEdgeXFor(isLeft);
5209
+ const startX = rootEdgeXFor(isLeft, rootX);
5059
5210
  const endX = childPos.x + (isLeft ? childHalfW : -childHalfW);
5060
5211
  edges.push({
5061
5212
  d: makeCurve(startX, cy, endX, childPos.y),
@@ -5235,6 +5386,7 @@ function emptyCounts() {
5235
5386
  "node-inside-lane": 0,
5236
5387
  "shape-label-dropped": 0,
5237
5388
  "box-line-dropped": 0,
5389
+ "node-field-unsupported": 0,
5238
5390
  "edge-inside-viewbox": 0,
5239
5391
  "lane-label-inside-viewbox": 0,
5240
5392
  "lane-label-overlap": 0,
@@ -6404,6 +6556,28 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5
6404
6556
  `node "${n.id}" (kind=${n.kind ?? "\u672A\u6307\u5B9A"}) \u304C rows ${n.rows.length} \u884C\u3092\u6301\u3064\u304C\u3001 \u3053\u306E\u7A2E\u5225\u306F\u884C\u3092\u63CF\u304B\u306A\u3044 (\u66F8\u3044\u305F\u5185\u5BB9\u304C\u753B\u9762\u306B\u51FA\u306A\u3044)`
6405
6557
  );
6406
6558
  }
6559
+ const \u6B04\u306E\u63CF\u304D\u5206\u3051 = [
6560
+ { \u6B04: "eyebrow", \u8A9E: "\u80A9\u66F8", \u63CF\u304F\u304B: rendersEyebrow },
6561
+ { \u6B04: "subtitle", \u8A9E: "\u8AAC\u660E", \u63CF\u304F\u304B: rendersSubtitle },
6562
+ { \u6B04: "value", \u8A9E: "\u5024", \u63CF\u304F\u304B: rendersValue }
6563
+ ];
6564
+ for (const n of diag.nodes) {
6565
+ if (!isRenderedNode(n)) continue;
6566
+ for (const { \u6B04, \u8A9E, \u63CF\u304F\u304B } of \u6B04\u306E\u63CF\u304D\u5206\u3051) {
6567
+ const \u66F8\u3044\u305F = (n[\u6B04] ?? "").trim();
6568
+ if (\u66F8\u3044\u305F === "") continue;
6569
+ if (\u63CF\u304F\u304B(n.kind)) continue;
6570
+ push(
6571
+ "node-field-unsupported",
6572
+ `node "${n.id}" (kind=${n.kind ?? "\u672A\u6307\u5B9A"}) \u304C ${\u6B04} (${\u8A9E}) \u306B "${\u66F8\u3044\u305F}" \u3092\u6301\u3064\u304C\u3001 \u3053\u306E\u7A2E\u5225\u306F\u305D\u306E\u6B04\u3092\u63CF\u304B\u306A\u3044 (\u66F8\u3044\u305F\u8A9E\u304C\u753B\u9762\u306B\u51FA\u306A\u3044)`,
6573
+ // 図そのものは正しく描かれており、効かない語が書かれているだけなので警告にする。
6574
+ // 誤り扱いにすると、既に書いている図が 1 枚も通らなくなる (実測 = engine の検査
6575
+ // だけで 8 file が落ちた)。 `rows-not-rendered` は誤り扱いだが、あちらは行が
6576
+ // 箱の主な中身になる種別を相手にしており、落ちた時の図の壊れ方が違う
6577
+ "warn"
6578
+ );
6579
+ }
6580
+ }
6407
6581
  for (const n of diag.nodes) {
6408
6582
  if (!n.rows || n.rows.length === 0) continue;
6409
6583
  if (!rendersRows(n.kind)) continue;
@@ -9893,7 +10067,7 @@ function autoStorageHeight(n, defaultH) {
9893
10067
  if (n.kind !== "storage") return n.h ?? defaultH;
9894
10068
  if (n.h != null) return n.h;
9895
10069
  const \u5370\u3042\u308A = n.rowMarks !== void 0;
9896
- const \u547C\u3073\u540D\u306E\u5206 = \u5370\u3042\u308A && n.subtitle ? SUBTITLE_ROW_SHIFT : 0;
10070
+ const \u547C\u3073\u540D\u306E\u5206 = n.subtitle ? SUBTITLE_ROW_SHIFT : 0;
9897
10071
  const \u7E70\u308A\u4E0A\u3052 = n.eyebrow ? 0 : \u76EE\u5370\u306A\u3057\u306E\u7E70\u308A\u4E0A\u3052("storage");
9898
10072
  if (!n.rows || n.rows.length === 0) return 115 + \u547C\u3073\u540D\u306E\u5206 - \u7E70\u308A\u4E0A\u3052;
9899
10073
  const \u5FC5\u8981 = requiredRowsHeight("storage", n.rows.length) ?? defaultH;
@@ -10020,22 +10194,33 @@ function layoutNodes(diag, lanes) {
10020
10194
  }
10021
10195
 
10022
10196
  // src/layout/viewbox.ts
10197
+ function \u7BB1\u3044\u3063\u3071\u3044\u306B\u63CF\u304F(lane) {
10198
+ return lane.contain === true || lane.lifeline === true;
10199
+ }
10023
10200
  function computeViewBox(lanes, nodes, edges, bboxes, viewport) {
10201
+ const \u5E38\u306B\u96A0\u308C\u308B\u7BC0 = new Set(nodes.filter((n) => !isRenderedNode(n)).map((n) => n.id));
10024
10202
  let maxX = 0;
10025
10203
  let maxY = 0;
10026
10204
  let minX = Number.POSITIVE_INFINITY;
10027
10205
  let minY = Number.POSITIVE_INFINITY;
10028
10206
  for (const bbox of bboxes) {
10207
+ if (bbox.kind === "node" && \u5E38\u306B\u96A0\u308C\u308B\u7BC0.has(bbox.id)) continue;
10029
10208
  maxX = Math.max(maxX, bbox.x + bbox.w);
10030
10209
  maxY = Math.max(maxY, bbox.y + bbox.h);
10031
10210
  minX = Math.min(minX, bbox.x);
10032
10211
  minY = Math.min(minY, bbox.y);
10033
10212
  }
10034
10213
  for (const lane of lanes) {
10214
+ if (!\u7BB1\u3044\u3063\u3071\u3044\u306B\u63CF\u304F(lane)) continue;
10215
+ minX = Math.min(minX, lane.x);
10216
+ minY = Math.min(minY, lane.y);
10035
10217
  maxX = Math.max(maxX, lane.x + lane.width);
10036
10218
  maxY = Math.max(maxY, lane.y + lane.height);
10037
10219
  }
10038
10220
  for (const n of nodes) {
10221
+ if (\u5E38\u306B\u96A0\u308C\u308B\u7BC0.has(n.id)) continue;
10222
+ minX = Math.min(minX, n.cx - n.w / 2);
10223
+ minY = Math.min(minY, n.cy - n.h / 2);
10039
10224
  maxX = Math.max(maxX, n.cx + n.w / 2);
10040
10225
  maxY = Math.max(maxY, n.cy + n.h / 2);
10041
10226
  }
@@ -11981,7 +12166,7 @@ function StorageNode({
11981
12166
  const columnDividerX = (leftEndDrawn + rightColX) / 2;
11982
12167
  const columnDividerFits = columnDividerX <= node.w - ROW_PAD_X_PX;
11983
12168
  const \u5370\u3067\u5206\u3051\u308B = node.rowMarks !== void 0;
11984
- const \u884C\u306E\u4E0B\u3052 = \u5370\u3067\u5206\u3051\u308B && node.subtitle ? SUBTITLE_ROW_SHIFT : 0;
12169
+ const \u884C\u306E\u4E0B\u3052 = node.subtitle ? SUBTITLE_ROW_SHIFT : 0;
11985
12170
  const lastRowBottom = Math.min(
11986
12171
  ROW_TOP_STORAGE + (rows.length - 1) * ROW_PITCH_STORAGE + (rowGlyphDepth("storage") ?? 0),
11987
12172
  node.h - ROW_PAD_X_PX
@@ -12021,8 +12206,7 @@ function StorageNode({
12021
12206
  );
12022
12207
  }),
12023
12208
  node.eyebrow && /* @__PURE__ */ jsx("text", { x: 26, y: 38, fontSize: 18, fontWeight: 700, letterSpacing: 2, fill: accent, children: node.eyebrow }),
12024
- \u5370\u3067\u5206\u3051\u308B && node.subtitle && // 呼び名は **印で分ける箱でだけ** 出す (#578)。 従来の箱は題の下に区切り線が来るので
12025
- // 置き場が無い
12209
+ node.subtitle && // 呼び名は書き方によらず出す (#937)。 区切り線を同じ分だけ下げて置き場を作る
12026
12210
  /* @__PURE__ */ jsx(
12027
12211
  "text",
12028
12212
  {
@@ -12053,9 +12237,9 @@ function StorageNode({
12053
12237
  {
12054
12238
  "data-cdl-role": "node-row-divider",
12055
12239
  x1: 26,
12056
- y1: STORAGE_ROW_DIVIDER_Y,
12240
+ y1: STORAGE_ROW_DIVIDER_Y + \u884C\u306E\u4E0B\u3052,
12057
12241
  x2: node.w - 26,
12058
- y2: STORAGE_ROW_DIVIDER_Y,
12242
+ y2: STORAGE_ROW_DIVIDER_Y + \u884C\u306E\u4E0B\u3052,
12059
12243
  stroke: "var(--cdl-row-divider, #7e848e)",
12060
12244
  strokeWidth: 1.25
12061
12245
  }
@@ -12065,7 +12249,7 @@ function StorageNode({
12065
12249
  {
12066
12250
  "data-cdl-role": "node-column-divider",
12067
12251
  x1: columnDividerX,
12068
- y1: STORAGE_ROW_DIVIDER_Y,
12252
+ y1: STORAGE_ROW_DIVIDER_Y + \u884C\u306E\u4E0B\u3052,
12069
12253
  x2: columnDividerX,
12070
12254
  y2: lastRowBottom,
12071
12255
  stroke: "var(--cdl-row-divider, #7e848e)",
@@ -12526,18 +12710,57 @@ function DynShapeNode({
12526
12710
  const strokeColor = shape.stroke ?? "var(--cdl-line, #a89d8f)";
12527
12711
  const fillColor = shape.fill ?? "var(--cdl-fill, #e0e6ef)";
12528
12712
  const activeOpacity = active ? 1 : 0.85;
12529
- switch (shape.kind) {
12530
- case "rect":
12531
- return renderRect(shape, x, y, w, h, stateValues, fillColor, strokeColor, activeOpacity, node);
12532
- case "circle":
12533
- return renderCircle(shape, cx, cy, w, h, stateValues, fillColor, strokeColor, activeOpacity);
12534
- case "arc":
12535
- return renderArc(shape, cx, cy, w, h, stateValues, fillColor, strokeColor, activeOpacity);
12536
- case "wave":
12537
- return /* @__PURE__ */ jsx(WaveShape, { shape, x, y, w, h, stateValues, fillColor, strokeColor, opacity: activeOpacity, node });
12538
- case "polygon":
12539
- return renderPolygon(shape, cx, cy, stateValues, fillColor, strokeColor, activeOpacity);
12540
- }
12713
+ const \u5F62 = (() => {
12714
+ switch (shape.kind) {
12715
+ case "rect":
12716
+ return renderRect(shape, x, y, w, h, stateValues, fillColor, strokeColor, activeOpacity, node);
12717
+ case "circle":
12718
+ return renderCircle(shape, cx, cy, w, h, stateValues, fillColor, strokeColor, activeOpacity);
12719
+ case "arc":
12720
+ return renderArc(shape, cx, cy, w, h, stateValues, fillColor, strokeColor, activeOpacity);
12721
+ case "wave":
12722
+ return /* @__PURE__ */ jsx(WaveShape, { shape, x, y, w, h, stateValues, fillColor, strokeColor, opacity: activeOpacity, node });
12723
+ case "polygon":
12724
+ return renderPolygon(shape, cx, cy, stateValues, fillColor, strokeColor, activeOpacity);
12725
+ }
12726
+ })();
12727
+ const \u540D\u524D = (node.title ?? "").trim();
12728
+ const \u5024 = (node.subtitle ?? "").trim();
12729
+ if (\u540D\u524D === "" && \u5024 === "") return \u5F62;
12730
+ const \u63C3\u3048 = \u7BB1\u3044\u3063\u3071\u3044\u306B\u63CF\u304F2(shape.kind) ? "start" : "middle";
12731
+ return /* @__PURE__ */ jsxs("g", { children: [
12732
+ \u5F62,
12733
+ \u540D\u524D !== "" && /* @__PURE__ */ jsx(
12734
+ "text",
12735
+ {
12736
+ "data-cdl-role": "shape-name",
12737
+ x: \u63C3\u3048 === "start" ? x : cx,
12738
+ y: y - NAME_GAP,
12739
+ textAnchor: \u63C3\u3048,
12740
+ fontSize: 13,
12741
+ fontWeight: 600,
12742
+ fill: "var(--cdl-text, #23201b)",
12743
+ children: \u540D\u524D
12744
+ }
12745
+ ),
12746
+ \u5024 !== "" && /* @__PURE__ */ jsx(
12747
+ "text",
12748
+ {
12749
+ "data-cdl-role": "shape-value",
12750
+ x: cx,
12751
+ y: y + h + VALUE_GAP,
12752
+ textAnchor: "middle",
12753
+ fontSize: 12,
12754
+ fill: "var(--cdl-text-dim, #5a6270)",
12755
+ children: \u5024
12756
+ }
12757
+ )
12758
+ ] });
12759
+ }
12760
+ var NAME_GAP = 6;
12761
+ var VALUE_GAP = 18;
12762
+ function \u7BB1\u3044\u3063\u3071\u3044\u306B\u63CF\u304F2(kind) {
12763
+ return kind === "rect" || kind === "wave";
12541
12764
  }
12542
12765
  function renderRect(shape, x, y, w, h, stateValues, fillColor, strokeColor, opacity, node) {
12543
12766
  const value = resolveNumericAttr(shape.source, stateValues, 0);
@@ -12825,6 +13048,13 @@ function \u5272\u5408\u8868\u8A18(frac) {
12825
13048
  const v = Math.round(frac * 1e3) / 10;
12826
13049
  return `${Number.isInteger(v) ? v : v.toFixed(1)}%`;
12827
13050
  }
13051
+ function \u5024\u3068\u5272\u5408\u306E\u7D44(\u5024, \u5272\u5408, \u5408\u8A08) {
13052
+ return Math.abs(\u5408\u8A08 - 100) < 1e-9 ? { \u5024: null, \u5272\u5408 } : { \u5024, \u5272\u5408 };
13053
+ }
13054
+ function \u5024\u3068\u5272\u5408\u306E\u6587\u5B57(\u5024, \u5272\u5408, \u5408\u8A08) {
13055
+ const \u7D44 = \u5024\u3068\u5272\u5408\u306E\u7D44(\u5024, \u5272\u5408, \u5408\u8A08);
13056
+ return \u7D44.\u5024 === null ? \u7D44.\u5272\u5408 : `${\u7D44.\u5024} ${\u7D44.\u5272\u5408}`;
13057
+ }
12828
13058
  var \u7A74\u306B\u5BFE\u3059\u308B\u4E0A\u9650 = 0.8;
12829
13059
  function \u4E2D\u592E\u306E\u5B57(\u6BD4\u4F8B\u3057\u305F\u5927\u304D\u3055, \u7A74\u306E\u534A\u5F84, \u6587) {
12830
13060
  const \u5165\u308B\u5927\u304D\u3055 = \u7A74\u306E\u534A\u5F84 * 2 * \u7A74\u306B\u5BFE\u3059\u308B\u4E0A\u9650 / Math.max(textWidth(\u6587, 1), 1e-6);
@@ -13301,6 +13531,18 @@ function sliceColor(tone, idx) {
13301
13531
  if (tone) return TONE[tone];
13302
13532
  return chartSeriesColor(idx);
13303
13533
  }
13534
+ function \u5024\u3068\u5272\u5408\u306E\u5B57({
13535
+ \u5024,
13536
+ \u5272\u5408,
13537
+ \u5408\u8A08
13538
+ }) {
13539
+ const \u7D44 = \u5024\u3068\u5272\u5408\u306E\u7D44(\u5024, \u5272\u5408, \u5408\u8A08);
13540
+ if (\u7D44.\u5024 === null) return /* @__PURE__ */ jsx("tspan", { "data-cdl-role": "chart-legend-share", children: \u7D44.\u5272\u5408 });
13541
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
13542
+ /* @__PURE__ */ jsx("tspan", { "data-cdl-role": "chart-legend-value", fill: "var(--cdl-text, #1a1f2a)", children: `${\u7D44.\u5024} ` }),
13543
+ /* @__PURE__ */ jsx("tspan", { "data-cdl-role": "chart-legend-share", children: \u7D44.\u5272\u5408 })
13544
+ ] });
13545
+ }
13304
13546
  function ChartGaugeNode({
13305
13547
  node,
13306
13548
  active,
@@ -13323,7 +13565,7 @@ function ChartGaugeNode({
13323
13565
  const \u5F27\u3068\u5185\u8A33\u306E\u9593 = 16;
13324
13566
  const \u5370\u306E\u5E452 = 30;
13325
13567
  const \u533A\u753B\u306E\u9593 = 12;
13326
- const \u6570\u5024\u306E\u884C = (d) => `${\u5B9F\u5024\u8868\u8A18(d.value)} ${\u5272\u5408\u8868\u8A18(d.value / total)}`;
13568
+ const \u6570\u5024\u306E\u884C = (d) => \u5024\u3068\u5272\u5408\u306E\u6587\u5B57(\u5B9F\u5024\u8868\u8A18(d.value), \u5272\u5408\u8868\u8A18(d.value / total), total);
13327
13569
  const \u5272\u308A\u4ED8\u3051\u308B = (\u4EF6\u305F\u3061) => {
13328
13570
  const \u5E45 = Math.max(\u5370\u306E\u5E452, ...\u4EF6\u305F\u3061.map((d) => textWidth(\u6570\u5024\u306E\u884C(d), \u6570\u5024\u306E\u7D1A))) + \u533A\u753B\u306E\u9593;
13329
13571
  const \u884C\u306E\u4EF6\u65702 = Math.min(
@@ -13492,6 +13734,8 @@ function ChartGaugeNode({
13492
13734
  const x = PAD_SIDE + \u5185\u8A33\u306E\u5E45 * \u5217;
13493
13735
  const y = \u5185\u8A33\u306Ey + \u6BB5\u306E\u9AD8\u3055 * \u6BB5;
13494
13736
  const \u53CE\u307E\u308B\u5E45 = \u5185\u8A33\u306E\u5E45 - \u533A\u753B\u306E\u9593;
13737
+ const \u6570\u306E\u884C = \u5185\u8A33\u306E\u6570\u5024[idx] ?? "";
13738
+ const \u5207\u3063\u305F\u6570\u306E\u884C = \u5207\u308A\u8A70\u3081\u308B(\u6570\u306E\u884C, \u53CE\u307E\u308B\u5E45, \u6570\u5024\u306E\u7D1A);
13495
13739
  return /* @__PURE__ */ jsxs("g", { "data-cdl-role": "chart-gauge-item", children: [
13496
13740
  /* @__PURE__ */ jsx(
13497
13741
  "rect",
@@ -13515,7 +13759,14 @@ function ChartGaugeNode({
13515
13759
  children: \u5207\u308A\u8A70\u3081\u308B(d.label ?? "", \u53CE\u307E\u308B\u5E45, \u540D\u524D\u306E\u7D1A)
13516
13760
  }
13517
13761
  ),
13518
- /* @__PURE__ */ jsx("text", { x, y: y + 46, fontSize: \u6570\u5024\u306E\u7D1A, fill: "var(--cdl-text-dim, #5a6270)", children: \u5207\u308A\u8A70\u3081\u308B(\u5185\u8A33\u306E\u6570\u5024[idx] ?? "", \u53CE\u307E\u308B\u5E45, \u6570\u5024\u306E\u7D1A) })
13762
+ /* @__PURE__ */ jsx("text", { x, y: y + 46, fontSize: \u6570\u5024\u306E\u7D1A, fill: "var(--cdl-text-dim, #5a6270)", children: \u5207\u3063\u305F\u6570\u306E\u884C === \u6570\u306E\u884C ? /* @__PURE__ */ jsx(
13763
+ \u5024\u3068\u5272\u5408\u306E\u5B57,
13764
+ {
13765
+ \u5024: \u5B9F\u5024\u8868\u8A18(d.value),
13766
+ \u5272\u5408: \u5272\u5408\u8868\u8A18(d.value / total),
13767
+ \u5408\u8A08: total
13768
+ }
13769
+ ) : \u5207\u3063\u305F\u6570\u306E\u884C })
13519
13770
  ] }, `legend-${idx}`);
13520
13771
  })
13521
13772
  ] });
@@ -13554,7 +13805,9 @@ function ChartRadialNode({
13554
13805
  const \u6570\u5024\u306E\u7D1A = 13;
13555
13806
  const \u884C\u306E\u9AD8\u3055 = 42;
13556
13807
  const \u4E00\u89A7\u3068\u5F27\u306E\u9593 = 28;
13557
- const \u6570\u5024\u306E\u6587\u5B57 = data.map((d) => `${\u5B9F\u5024\u8868\u8A18(d.value)} ${\u5272\u5408\u8868\u8A18(d.value / total)}`);
13808
+ const \u6570\u5024\u306E\u6587\u5B57 = data.map(
13809
+ (d) => \u5024\u3068\u5272\u5408\u306E\u6587\u5B57(\u5B9F\u5024\u8868\u8A18(d.value), \u5272\u5408\u8868\u8A18(d.value / total), total)
13810
+ );
13558
13811
  const \u4E00\u89A7\u306E\u5E45 = \u5370\u306E\u5E45 + Math.max(
13559
13812
  0,
13560
13813
  ...data.map(
@@ -13566,7 +13819,9 @@ function ChartRadialNode({
13566
13819
  const \u4F7F\u3048\u308B\u539A\u307F = \u5916\u534A\u5F84 * 0.7;
13567
13820
  const \u5E2F1\u672C = \u4F7F\u3048\u308B\u539A\u307F / Math.max(data.length, 1);
13568
13821
  const \u5E2F\u306E\u5E45 = \u5E2F1\u672C * 0.66;
13569
- const \u5F27\u306Ecx = PAD + \u4E00\u89A7\u306E\u5E45 + \u4E00\u89A7\u3068\u5F27\u306E\u9593 + \u5916\u534A\u5F84;
13822
+ const \u4E2D\u8EAB\u306E\u5E45 = \u4E00\u89A7\u306E\u5E45 + \u4E00\u89A7\u3068\u5F27\u306E\u9593 + \u5916\u534A\u5F84 * 2;
13823
+ const \u4E00\u89A7\u306E\u5DE6 = Math.max(PAD, (node.w - \u4E2D\u8EAB\u306E\u5E45) / 2);
13824
+ const \u5F27\u306Ecx = \u4E00\u89A7\u306E\u5DE6 + \u4E00\u89A7\u306E\u5E45 + \u4E00\u89A7\u3068\u5F27\u306E\u9593 + \u5916\u534A\u5F84;
13570
13825
  const cy = PAD + \u4F7F\u3048\u308B\u9AD8\u3055 / 2;
13571
13826
  const rings = data.map((d, idx) => {
13572
13827
  const frac = d.value / total;
@@ -13641,11 +13896,11 @@ function ChartRadialNode({
13641
13896
  data.map((d, idx) => {
13642
13897
  const y = \u4E00\u89A7\u306E\u59CB\u307E\u308A + \u884C\u306E\u9AD8\u3055 * idx;
13643
13898
  return /* @__PURE__ */ jsxs("g", { "data-cdl-role": "chart-radial-item", children: [
13644
- /* @__PURE__ */ jsx("rect", { x: PAD, y: y - 11, width: 4, height: 22, rx: 2, fill: arcColor2(d.tone, idx) }),
13899
+ /* @__PURE__ */ jsx("rect", { x: \u4E00\u89A7\u306E\u5DE6, y: y - 11, width: 4, height: 22, rx: 2, fill: arcColor2(d.tone, idx) }),
13645
13900
  /* @__PURE__ */ jsx(
13646
13901
  "text",
13647
13902
  {
13648
- x: PAD + \u5370\u306E\u5E45,
13903
+ x: \u4E00\u89A7\u306E\u5DE6 + \u5370\u306E\u5E45,
13649
13904
  y: y + 1,
13650
13905
  fontSize: \u540D\u524D\u306E\u7D1A,
13651
13906
  fontWeight: 700,
@@ -13656,11 +13911,18 @@ function ChartRadialNode({
13656
13911
  /* @__PURE__ */ jsx(
13657
13912
  "text",
13658
13913
  {
13659
- x: PAD + \u5370\u306E\u5E45,
13914
+ x: \u4E00\u89A7\u306E\u5DE6 + \u5370\u306E\u5E45,
13660
13915
  y: y + 20,
13661
13916
  fontSize: \u6570\u5024\u306E\u7D1A,
13662
13917
  fill: "var(--cdl-text-dim, #5a6270)",
13663
- children: \u6570\u5024\u306E\u6587\u5B57[idx]
13918
+ children: /* @__PURE__ */ jsx(
13919
+ \u5024\u3068\u5272\u5408\u306E\u5B57,
13920
+ {
13921
+ \u5024: \u5B9F\u5024\u8868\u8A18(d.value),
13922
+ \u5272\u5408: \u5272\u5408\u8868\u8A18(d.value / total),
13923
+ \u5408\u8A08: total
13924
+ }
13925
+ )
13664
13926
  }
13665
13927
  )
13666
13928
  ] }, `item-${idx}`);
@@ -13703,7 +13965,7 @@ function ChartStatNode({
13703
13965
  const data = resolveChartData(node.chartData ?? [], stateValues);
13704
13966
  const total = data.reduce((acc, d) => acc + d.value, 0) || 1;
13705
13967
  const \u524D\u3092\u51FA\u3059 = data.some((d) => d.previous !== void 0);
13706
- const \u533A\u753B = \u533A\u753B\u306E\u5272\u4ED8(node.w, node.h, data.length, \u524D\u3092\u51FA\u3059);
13968
+ const \u533A\u753B = \u533A\u753B\u306E\u5272\u4ED8(node.w, node.h, data.length, \u524D\u3092\u51FA\u3059, data.length > 1);
13707
13969
  const \u5272\u5408\u3092\u51FA\u3059 = data.length > 1;
13708
13970
  return /* @__PURE__ */ jsxs("g", { transform: `translate(${x0} ${y0})`, children: [
13709
13971
  /* @__PURE__ */ jsx(
@@ -13832,17 +14094,23 @@ function ChartStatNode({
13832
14094
  })
13833
14095
  ] });
13834
14096
  }
13835
- function \u533A\u753B\u306E\u5272\u4ED8(w, h, \u4EF6\u6570, \u524D\u3092\u51FA\u3059) {
14097
+ function \u533A\u753B\u306E\u5272\u4ED8(w, h, \u4EF6\u6570, \u524D\u3092\u51FA\u3059, \u5272\u5408\u3092\u51FA\u3059) {
13836
14098
  const \u4F59\u767D = 20;
13837
14099
  const \u5E45 = \u4EF6\u6570 > 0 ? w / \u4EF6\u6570 : w;
13838
14100
  const \u540D\u524D\u306E\u7D1A = 14;
13839
- const \u6570\u5024\u306E\u7D1A = 40;
13840
14101
  const \u524D\u306E\u7D1A = \u540D\u524D\u306E\u7D1A;
13841
14102
  const \u5272\u5408\u306E\u7D1A = 12;
13842
14103
  const \u5F27\u306E\u534A\u5F84 = 20;
13843
14104
  const \u5F27\u306E\u592A\u3055 = 4;
14105
+ const \u6570\u5024\u306E\u7D1A\u306E\u4E0B\u9650 = 40;
14106
+ const \u6570\u5024\u306E\u7D1A\u306E\u4E0A\u9650 = 112;
13844
14107
  const \u524D\u306E\u9AD8\u3055 = \u524D\u3092\u51FA\u3059 ? 8 + \u524D\u306E\u7D1A : 0;
13845
- const \u4E2D\u8EAB\u306E\u9AD8\u3055 = \u540D\u524D\u306E\u7D1A + 12 + \u6570\u5024\u306E\u7D1A + \u524D\u306E\u9AD8\u3055 + 16 + \u5F27\u306E\u534A\u5F84 * 2 + 8 + \u5272\u5408\u306E\u7D1A;
14108
+ const \u5F27\u3068\u5272\u5408\u306E\u9AD8\u3055 = \u5272\u5408\u3092\u51FA\u3059 ? 16 + \u5F27\u306E\u534A\u5F84 * 2 + 8 + \u5272\u5408\u306E\u7D1A : 0;
14109
+ const \u6570\u5024\u306E\u7D1A = \u5272\u5408\u3092\u51FA\u3059 ? \u6570\u5024\u306E\u7D1A\u306E\u4E0B\u9650 : Math.max(
14110
+ \u6570\u5024\u306E\u7D1A\u306E\u4E0B\u9650,
14111
+ Math.min(\u6570\u5024\u306E\u7D1A\u306E\u4E0A\u9650, Math.floor(h - \u4F59\u767D * 2 - \u540D\u524D\u306E\u7D1A - 12 - \u524D\u306E\u9AD8\u3055))
14112
+ );
14113
+ const \u4E2D\u8EAB\u306E\u9AD8\u3055 = \u540D\u524D\u306E\u7D1A + 12 + \u6570\u5024\u306E\u7D1A + \u524D\u306E\u9AD8\u3055 + \u5F27\u3068\u5272\u5408\u306E\u9AD8\u3055;
13846
14114
  const \u4E0A\u7AEF = Math.max(\u4F59\u767D, (h - \u4E2D\u8EAB\u306E\u9AD8\u3055) / 2);
13847
14115
  const \u540D\u524D\u306Ey = \u4E0A\u7AEF + \u540D\u524D\u306E\u7D1A;
13848
14116
  const \u6570\u5024\u306Ey = \u540D\u524D\u306Ey + 12 + \u6570\u5024\u306E\u7D1A * 0.78;
@@ -13914,7 +14182,10 @@ function ChartWaffleNode({
13914
14182
  const \u884C\u306E\u9AD8\u3055 = 40;
13915
14183
  const \u4E00\u89A7\u3068\u683C\u5B50\u306E\u9593 = 28;
13916
14184
  const \u5370\u306E\u5E452 = 18;
13917
- const \u6570\u5024\u306E\u6587\u5B57 = data.map((d, i) => `${\u5B9F\u5024\u8868\u8A18(d.value)} ${\u914D\u5206[i] ?? 0}%`);
14185
+ const \u5B9F\u5024\u306E\u5408\u8A08 = data.reduce((acc, d) => acc + d.value, 0);
14186
+ const \u6570\u5024\u306E\u6587\u5B57 = data.map(
14187
+ (d, i) => \u5024\u3068\u5272\u5408\u306E\u6587\u5B57(\u5B9F\u5024\u8868\u8A18(d.value), `${\u914D\u5206[i] ?? 0}%`, \u5B9F\u5024\u306E\u5408\u8A08)
14188
+ );
13918
14189
  const \u4E00\u89A7\u306E\u5E45 = \u5370\u306E\u5E452 + Math.max(
13919
14190
  0,
13920
14191
  ...data.map(
@@ -13925,7 +14196,9 @@ function ChartWaffleNode({
13925
14196
  const \u683C\u5B50\u306B\u4F7F\u3048\u308B\u5E45 = node.w - PAD * 2 - \u4E00\u89A7\u306E\u5E45 - \u4E00\u89A7\u3068\u683C\u5B50\u306E\u9593;
13926
14197
  const \u5347 = Math.max(4, Math.min(\u4F7F\u3048\u308B\u9AD8\u3055, \u683C\u5B50\u306B\u4F7F\u3048\u308B\u5E45) / WAFFLE_COLS);
13927
14198
  const \u5370 = \u5347 * 0.78;
13928
- const \u683C\u5B50\u306E\u5DE6 = PAD + \u4E00\u89A7\u306E\u5E45 + \u4E00\u89A7\u3068\u683C\u5B50\u306E\u9593;
14199
+ const \u4E2D\u8EAB\u306E\u5E45 = \u4E00\u89A7\u306E\u5E45 + \u4E00\u89A7\u3068\u683C\u5B50\u306E\u9593 + \u5347 * WAFFLE_COLS;
14200
+ const \u4E00\u89A7\u306E\u5DE6 = Math.max(PAD, (node.w - \u4E2D\u8EAB\u306E\u5E45) / 2);
14201
+ const \u683C\u5B50\u306E\u5DE6 = \u4E00\u89A7\u306E\u5DE6 + \u4E00\u89A7\u306E\u5E45 + \u4E00\u89A7\u3068\u683C\u5B50\u306E\u9593;
13929
14202
  const \u683C\u5B50\u306E\u4E0A = PAD + (\u4F7F\u3048\u308B\u9AD8\u3055 - \u5347 * WAFFLE_COLS) / 2;
13930
14203
  const \u6301\u3061\u4E3B = [];
13931
14204
  \u914D\u5206.forEach((n, idx) => {
@@ -13972,11 +14245,11 @@ function ChartWaffleNode({
13972
14245
  data.map((d, idx) => {
13973
14246
  const y = \u4E00\u89A7\u306E\u59CB\u307E\u308A + \u884C\u306E\u9AD8\u3055 * idx;
13974
14247
  return /* @__PURE__ */ jsxs("g", { "data-cdl-role": "chart-waffle-item", children: [
13975
- /* @__PURE__ */ jsx("rect", { x: PAD, y: y - 11, width: 4, height: 22, rx: 2, fill: \u5370\u306E\u82722(d.tone, idx) }),
14248
+ /* @__PURE__ */ jsx("rect", { x: \u4E00\u89A7\u306E\u5DE6, y: y - 11, width: 4, height: 22, rx: 2, fill: \u5370\u306E\u82722(d.tone, idx) }),
13976
14249
  /* @__PURE__ */ jsx(
13977
14250
  "text",
13978
14251
  {
13979
- x: PAD + \u5370\u306E\u5E452,
14252
+ x: \u4E00\u89A7\u306E\u5DE6 + \u5370\u306E\u5E452,
13980
14253
  y: y + 1,
13981
14254
  fontSize: \u540D\u524D\u306E\u7D1A,
13982
14255
  fontWeight: 700,
@@ -13989,11 +14262,18 @@ function ChartWaffleNode({
13989
14262
  {
13990
14263
  "data-cdl-role": "chart-waffle-count",
13991
14264
  "data-cdl-unresolved": d.unresolved ? "true" : void 0,
13992
- x: PAD + \u5370\u306E\u5E452,
14265
+ x: \u4E00\u89A7\u306E\u5DE6 + \u5370\u306E\u5E452,
13993
14266
  y: y + 20,
13994
14267
  fontSize: \u6570\u5024\u306E\u7D1A,
13995
14268
  fill: "var(--cdl-text-dim, #5a6270)",
13996
- children: \u6570\u5024\u306E\u6587\u5B57[idx]
14269
+ children: /* @__PURE__ */ jsx(
14270
+ \u5024\u3068\u5272\u5408\u306E\u5B57,
14271
+ {
14272
+ \u5024: \u5B9F\u5024\u8868\u8A18(d.value),
14273
+ \u5272\u5408: `${\u914D\u5206[idx] ?? 0}%`,
14274
+ \u5408\u8A08: \u5B9F\u5024\u306E\u5408\u8A08
14275
+ }
14276
+ )
13997
14277
  }
13998
14278
  )
13999
14279
  ] }, `item-${idx}`);
@@ -14899,6 +15179,8 @@ function FunnelNode({
14899
15179
  const t = step / stageCount;
14900
15180
  return canvasW * (topRatio + (bottomRatio - topRatio) * t);
14901
15181
  };
15182
+ const \u540D\u524D\u306E\u5B57 = 14;
15183
+ const \u88DC\u8DB3\u306E\u5B57 = 10.5;
14902
15184
  const \u6BB5 = stages.map((s, idx) => {
14903
15185
  const prev = idx > 0 ? stages[idx - 1] : null;
14904
15186
  const dropRate = prev && prev.count > 0 ? (prev.count - s.count) / prev.count * 100 : 0;
@@ -14911,6 +15193,17 @@ function FunnelNode({
14911
15193
  const points = `${topX},${y} ${topX + topW},${y} ${bottomX + bottomW},${y + stageH} ${bottomX},${y + stageH}`;
14912
15194
  const tone = toneByIndex(idx);
14913
15195
  const legendX = PAD_LEFT2 + canvasW + 24;
15196
+ const \u88DC\u8DB3 = (s.subtitle ?? "").trim();
15197
+ const \u88DC\u8DB3\u3042\u308A = \u88DC\u8DB3 !== "";
15198
+ const \u4E8C\u884C\u306E\u9AD8\u3055 = \u540D\u524D\u306E\u5B57 * 1.2 + \u88DC\u8DB3\u306E\u5B57 * 1.25;
15199
+ const \u7E26\u500D = \u88DC\u8DB3\u3042\u308A ? Math.min(1, Math.max(0, stageH - 8) / \u4E8C\u884C\u306E\u9AD8\u3055) : 1;
15200
+ const \u540D\u524D\u306E\u5B9F\u5B57 = \u540D\u524D\u306E\u5B57 * \u7E26\u500D;
15201
+ const \u88DC\u8DB3\u306E\u67A0\u5B57 = \u88DC\u8DB3\u306E\u5B57 * \u7E26\u500D;
15202
+ const \u53CE\u307E\u308B\u5E45 = Math.max(0, bottomW - 16);
15203
+ const \u88DC\u8DB3\u306E\u5B9F\u5B57 = \u88DC\u8DB3\u306E\u67A0\u5B57 * \u53CE\u3081\u308B\u500D\u7387(\u88DC\u8DB3, { fontSize: \u88DC\u8DB3\u306E\u67A0\u5B57, fontWeight: 500 }, \u53CE\u307E\u308B\u5E45);
15204
+ const \u584A\u306E\u4E0A = y + stageH / 2 - (\u540D\u524D\u306E\u5B9F\u5B57 * 1.2 + \u88DC\u8DB3\u306E\u67A0\u5B57 * 1.25) / 2;
15205
+ const \u540D\u524D\u306Ey = \u88DC\u8DB3\u3042\u308A ? \u584A\u306E\u4E0A + \u540D\u524D\u306E\u5B9F\u5B57 * 0.95 : y + stageH / 2 + 5;
15206
+ const \u88DC\u8DB3\u306Ey = \u584A\u306E\u4E0A + \u540D\u524D\u306E\u5B9F\u5B57 * 1.2 + \u88DC\u8DB3\u306E\u67A0\u5B57 * 0.95;
14914
15207
  return /* @__PURE__ */ jsxs("g", { children: [
14915
15208
  /* @__PURE__ */ jsx(
14916
15209
  "polygon",
@@ -14928,14 +15221,29 @@ function FunnelNode({
14928
15221
  "text",
14929
15222
  {
14930
15223
  x: cx,
14931
- y: y + stageH / 2 + 5,
14932
- fontSize: 14,
15224
+ y: \u540D\u524D\u306Ey,
15225
+ fontSize: \u540D\u524D\u306E\u5B9F\u5B57,
14933
15226
  fontWeight: 700,
14934
15227
  textAnchor: "middle",
14935
15228
  fill: "var(--cdl-node-fill, #ffffff)",
14936
15229
  children: s.title
14937
15230
  }
14938
15231
  ),
15232
+ \u88DC\u8DB3\u3042\u308A && /* @__PURE__ */ jsx(
15233
+ "text",
15234
+ {
15235
+ "data-cdl-role": "funnel-stage-subtitle",
15236
+ x: cx,
15237
+ y: \u88DC\u8DB3\u306Ey,
15238
+ fontSize: \u88DC\u8DB3\u306E\u5B9F\u5B57,
15239
+ fontWeight: 500,
15240
+ letterSpacing: 0,
15241
+ textAnchor: "middle",
15242
+ fill: "var(--cdl-node-fill, #ffffff)",
15243
+ fillOpacity: 0.82,
15244
+ children: \u88DC\u8DB3
15245
+ }
15246
+ ),
14939
15247
  \u6BB5\u304C\u51FA\u5207\u3063\u305F(idx) && /* @__PURE__ */ jsx(
14940
15248
  "text",
14941
15249
  {
@@ -14989,6 +15297,9 @@ var TONE_ORDER = [
14989
15297
  function toneByIndex(idx) {
14990
15298
  return TONE_ORDER[idx % TONE_ORDER.length];
14991
15299
  }
15300
+ function \u7573\u3093\u3060\u6587(\u4EF6\u6570) {
15301
+ return `\u307B\u304B ${\u4EF6\u6570} \u4EF6`;
15302
+ }
14992
15303
  function QuadrantNode({
14993
15304
  node,
14994
15305
  active,
@@ -15006,7 +15317,13 @@ function QuadrantNode({
15006
15317
  const ITEM_FONT = 13;
15007
15318
  const ITEM_PAD_X = 12;
15008
15319
  const ITEM_MIN_W = 48;
15009
- const axisLabelPad = (text) => Math.max(PAD_MIN, measureTextWidth(`\u2190 ${text}`, { fontSize: AXIS_LABEL_FONT}) + 12);
15320
+ const POINT_R = 5;
15321
+ const POINT_GAP = 6;
15322
+ const SUB_FONT = 10;
15323
+ const axisLabelPad = (text) => Math.max(
15324
+ PAD_MIN,
15325
+ measureTextWidth(`\u2190 ${text}`, { fontSize: AXIS_LABEL_FONT}) + 12
15326
+ );
15010
15327
  const padBudget = Math.max(0, node.w * 0.5 - PAD_MIN * 2);
15011
15328
  const wantLeft = axisLabelPad(data.xAxis.left) - PAD_MIN;
15012
15329
  const wantRight = axisLabelPad(data.xAxis.right) - PAD_MIN;
@@ -15020,11 +15337,13 @@ function QuadrantNode({
15020
15337
  const cy = PAD_TOP2 + canvasH / 2;
15021
15338
  const halfW = canvasW / 2;
15022
15339
  const halfH = canvasH / 2;
15340
+ const \u70B9\u3067\u7F6E\u304F = data.items.filter((i) => i.at !== void 0);
15341
+ const \u7A4D\u3080 = data.items.filter((i) => i.at === void 0);
15023
15342
  const itemsBy = {
15024
- topLeft: data.items.filter((i) => i.quadrant === "topLeft"),
15025
- topRight: data.items.filter((i) => i.quadrant === "topRight"),
15026
- bottomLeft: data.items.filter((i) => i.quadrant === "bottomLeft"),
15027
- bottomRight: data.items.filter((i) => i.quadrant === "bottomRight")
15343
+ topLeft: \u7A4D\u3080.filter((i) => i.quadrant === "topLeft"),
15344
+ topRight: \u7A4D\u3080.filter((i) => i.quadrant === "topRight"),
15345
+ bottomLeft: \u7A4D\u3080.filter((i) => i.quadrant === "bottomLeft"),
15346
+ bottomRight: \u7A4D\u3080.filter((i) => i.quadrant === "bottomRight")
15028
15347
  };
15029
15348
  const quadrantColor = {
15030
15349
  topLeft: toneFill("success", 0.06),
@@ -15053,10 +15372,50 @@ function QuadrantNode({
15053
15372
  strokeWidth: active ? 3 : 1.25
15054
15373
  }
15055
15374
  ),
15056
- /* @__PURE__ */ jsx("rect", { "data-cdl-role": "quadrant-bg", x: PAD_LEFT2, y: PAD_TOP2, width: halfW, height: halfH, ...quadrantColor.topLeft }),
15057
- /* @__PURE__ */ jsx("rect", { "data-cdl-role": "quadrant-bg", x: cx, y: PAD_TOP2, width: halfW, height: halfH, ...quadrantColor.topRight }),
15058
- /* @__PURE__ */ jsx("rect", { "data-cdl-role": "quadrant-bg", x: PAD_LEFT2, y: cy, width: halfW, height: halfH, ...quadrantColor.bottomLeft }),
15059
- /* @__PURE__ */ jsx("rect", { "data-cdl-role": "quadrant-bg", x: cx, y: cy, width: halfW, height: halfH, ...quadrantColor.bottomRight }),
15375
+ /* @__PURE__ */ jsx(
15376
+ "rect",
15377
+ {
15378
+ "data-cdl-role": "quadrant-bg",
15379
+ x: PAD_LEFT2,
15380
+ y: PAD_TOP2,
15381
+ width: halfW,
15382
+ height: halfH,
15383
+ ...quadrantColor.topLeft
15384
+ }
15385
+ ),
15386
+ /* @__PURE__ */ jsx(
15387
+ "rect",
15388
+ {
15389
+ "data-cdl-role": "quadrant-bg",
15390
+ x: cx,
15391
+ y: PAD_TOP2,
15392
+ width: halfW,
15393
+ height: halfH,
15394
+ ...quadrantColor.topRight
15395
+ }
15396
+ ),
15397
+ /* @__PURE__ */ jsx(
15398
+ "rect",
15399
+ {
15400
+ "data-cdl-role": "quadrant-bg",
15401
+ x: PAD_LEFT2,
15402
+ y: cy,
15403
+ width: halfW,
15404
+ height: halfH,
15405
+ ...quadrantColor.bottomLeft
15406
+ }
15407
+ ),
15408
+ /* @__PURE__ */ jsx(
15409
+ "rect",
15410
+ {
15411
+ "data-cdl-role": "quadrant-bg",
15412
+ x: cx,
15413
+ y: cy,
15414
+ width: halfW,
15415
+ height: halfH,
15416
+ ...quadrantColor.bottomRight
15417
+ }
15418
+ ),
15060
15419
  /* @__PURE__ */ jsx(
15061
15420
  "rect",
15062
15421
  {
@@ -15071,28 +15430,136 @@ function QuadrantNode({
15071
15430
  rx: 8
15072
15431
  }
15073
15432
  ),
15074
- /* @__PURE__ */ jsx("line", { x1: cx, y1: PAD_TOP2, x2: cx, y2: PAD_TOP2 + canvasH, stroke: "var(--cdl-text-mute, #8a8678)", strokeWidth: 1.5 }),
15075
- /* @__PURE__ */ jsx("line", { x1: PAD_LEFT2, y1: cy, x2: PAD_LEFT2 + canvasW, y2: cy, stroke: "var(--cdl-text-mute, #8a8678)", strokeWidth: 1.5 }),
15076
- /* @__PURE__ */ jsx("text", { x: PAD_LEFT2 + halfW / 2, y: PAD_TOP2 + 22, fontSize: 13, fontWeight: 700, textAnchor: "middle", fill: quadrantAccent.topLeft, children: data.quadrantLabels.topLeft }),
15077
- /* @__PURE__ */ jsx("text", { x: cx + halfW / 2, y: PAD_TOP2 + 22, fontSize: 13, fontWeight: 700, textAnchor: "middle", fill: quadrantAccent.topRight, children: data.quadrantLabels.topRight }),
15078
- /* @__PURE__ */ jsx("text", { x: PAD_LEFT2 + halfW / 2, y: PAD_TOP2 + canvasH - 12, fontSize: 13, fontWeight: 700, textAnchor: "middle", fill: quadrantAccent.bottomLeft, children: data.quadrantLabels.bottomLeft }),
15079
- /* @__PURE__ */ jsx("text", { x: cx + halfW / 2, y: PAD_TOP2 + canvasH - 12, fontSize: 13, fontWeight: 700, textAnchor: "middle", fill: quadrantAccent.bottomRight, children: data.quadrantLabels.bottomRight }),
15080
- /* @__PURE__ */ jsxs("text", { x: cx, y: PAD_TOP2 - 12, fontSize: 12, fontWeight: 700, textAnchor: "middle", fill: "var(--cdl-text-dim, #5a6270)", children: [
15081
- "\u2191 ",
15082
- data.yAxis.top
15083
- ] }),
15084
- /* @__PURE__ */ jsxs("text", { x: cx, y: PAD_TOP2 + canvasH + 24, fontSize: 12, fontWeight: 700, textAnchor: "middle", fill: "var(--cdl-text-dim, #5a6270)", children: [
15085
- "\u2193 ",
15086
- data.yAxis.bottom
15087
- ] }),
15088
- /* @__PURE__ */ jsxs("text", { x: PAD_LEFT2 - 12, y: cy + 4, fontSize: AXIS_LABEL_FONT, fontWeight: 700, textAnchor: "end", fill: "var(--cdl-text-dim, #5a6270)", children: [
15089
- "\u2190 ",
15090
- data.xAxis.left
15091
- ] }),
15092
- /* @__PURE__ */ jsxs("text", { x: PAD_LEFT2 + canvasW + 12, y: cy + 4, fontSize: AXIS_LABEL_FONT, fontWeight: 700, textAnchor: "start", fill: "var(--cdl-text-dim, #5a6270)", children: [
15093
- data.xAxis.right,
15094
- " \u2192"
15095
- ] }),
15433
+ /* @__PURE__ */ jsx(
15434
+ "line",
15435
+ {
15436
+ x1: cx,
15437
+ y1: PAD_TOP2,
15438
+ x2: cx,
15439
+ y2: PAD_TOP2 + canvasH,
15440
+ stroke: "var(--cdl-text-mute, #8a8678)",
15441
+ strokeWidth: 1.5
15442
+ }
15443
+ ),
15444
+ /* @__PURE__ */ jsx(
15445
+ "line",
15446
+ {
15447
+ x1: PAD_LEFT2,
15448
+ y1: cy,
15449
+ x2: PAD_LEFT2 + canvasW,
15450
+ y2: cy,
15451
+ stroke: "var(--cdl-text-mute, #8a8678)",
15452
+ strokeWidth: 1.5
15453
+ }
15454
+ ),
15455
+ /* @__PURE__ */ jsx(
15456
+ "text",
15457
+ {
15458
+ x: PAD_LEFT2 + halfW / 2,
15459
+ y: PAD_TOP2 + 22,
15460
+ fontSize: 13,
15461
+ fontWeight: 700,
15462
+ textAnchor: "middle",
15463
+ fill: quadrantAccent.topLeft,
15464
+ children: data.quadrantLabels.topLeft
15465
+ }
15466
+ ),
15467
+ /* @__PURE__ */ jsx(
15468
+ "text",
15469
+ {
15470
+ x: cx + halfW / 2,
15471
+ y: PAD_TOP2 + 22,
15472
+ fontSize: 13,
15473
+ fontWeight: 700,
15474
+ textAnchor: "middle",
15475
+ fill: quadrantAccent.topRight,
15476
+ children: data.quadrantLabels.topRight
15477
+ }
15478
+ ),
15479
+ /* @__PURE__ */ jsx(
15480
+ "text",
15481
+ {
15482
+ x: PAD_LEFT2 + halfW / 2,
15483
+ y: PAD_TOP2 + canvasH - 12,
15484
+ fontSize: 13,
15485
+ fontWeight: 700,
15486
+ textAnchor: "middle",
15487
+ fill: quadrantAccent.bottomLeft,
15488
+ children: data.quadrantLabels.bottomLeft
15489
+ }
15490
+ ),
15491
+ /* @__PURE__ */ jsx(
15492
+ "text",
15493
+ {
15494
+ x: cx + halfW / 2,
15495
+ y: PAD_TOP2 + canvasH - 12,
15496
+ fontSize: 13,
15497
+ fontWeight: 700,
15498
+ textAnchor: "middle",
15499
+ fill: quadrantAccent.bottomRight,
15500
+ children: data.quadrantLabels.bottomRight
15501
+ }
15502
+ ),
15503
+ /* @__PURE__ */ jsxs(
15504
+ "text",
15505
+ {
15506
+ x: cx,
15507
+ y: PAD_TOP2 - 12,
15508
+ fontSize: 12,
15509
+ fontWeight: 700,
15510
+ textAnchor: "middle",
15511
+ fill: "var(--cdl-text-dim, #5a6270)",
15512
+ children: [
15513
+ "\u2191 ",
15514
+ data.yAxis.top
15515
+ ]
15516
+ }
15517
+ ),
15518
+ /* @__PURE__ */ jsxs(
15519
+ "text",
15520
+ {
15521
+ x: cx,
15522
+ y: PAD_TOP2 + canvasH + 24,
15523
+ fontSize: 12,
15524
+ fontWeight: 700,
15525
+ textAnchor: "middle",
15526
+ fill: "var(--cdl-text-dim, #5a6270)",
15527
+ children: [
15528
+ "\u2193 ",
15529
+ data.yAxis.bottom
15530
+ ]
15531
+ }
15532
+ ),
15533
+ /* @__PURE__ */ jsxs(
15534
+ "text",
15535
+ {
15536
+ x: PAD_LEFT2 - 12,
15537
+ y: cy + 4,
15538
+ fontSize: AXIS_LABEL_FONT,
15539
+ fontWeight: 700,
15540
+ textAnchor: "end",
15541
+ fill: "var(--cdl-text-dim, #5a6270)",
15542
+ children: [
15543
+ "\u2190 ",
15544
+ data.xAxis.left
15545
+ ]
15546
+ }
15547
+ ),
15548
+ /* @__PURE__ */ jsxs(
15549
+ "text",
15550
+ {
15551
+ x: PAD_LEFT2 + canvasW + 12,
15552
+ y: cy + 4,
15553
+ fontSize: AXIS_LABEL_FONT,
15554
+ fontWeight: 700,
15555
+ textAnchor: "start",
15556
+ fill: "var(--cdl-text-dim, #5a6270)",
15557
+ children: [
15558
+ data.xAxis.right,
15559
+ " \u2192"
15560
+ ]
15561
+ }
15562
+ ),
15096
15563
  Object.keys(itemsBy).map((q) => {
15097
15564
  const items = itemsBy[q];
15098
15565
  if (items.length === 0) return null;
@@ -15103,35 +15570,169 @@ function QuadrantNode({
15103
15570
  const qHalfW = halfW - 36;
15104
15571
  const \u67A0\u306E\u4F59\u5730 = qHalfW;
15105
15572
  if (\u67A0\u306E\u4F59\u5730 <= 0) return null;
15106
- const \u67A0\u306E\u5E45 = (title) => Math.min(
15573
+ const \u67A0\u306E\u5E45 = (\u884C\u30892) => Math.min(
15107
15574
  \u67A0\u306E\u4F59\u5730,
15108
- Math.max(ITEM_MIN_W, measureTextWidth(title, { fontSize: ITEM_FONT}) + ITEM_PAD_X * 2)
15575
+ Math.max(
15576
+ ITEM_MIN_W,
15577
+ Math.max(
15578
+ ...\u884C\u30892.map(
15579
+ (r) => measureTextWidth(r.text, { fontSize: r.size, fontWeight: r.weight })
15580
+ )
15581
+ ) + ITEM_PAD_X * 2
15582
+ )
15109
15583
  );
15584
+ const \u884C\u3089 = (it) => {
15585
+ const \u88DC\u8DB3 = (it.subtitle ?? "").trim();
15586
+ return [
15587
+ { text: it.title, size: ITEM_FONT, weight: 600 },
15588
+ ...\u88DC\u8DB3 === "" ? [] : [{ text: \u88DC\u8DB3, size: SUB_FONT, weight: 500 }]
15589
+ ];
15590
+ };
15110
15591
  const qHalfH = halfH - 60;
15111
15592
  const gap = 10;
15112
15593
  const rowH = 34;
15113
15594
  const maxRows = Math.max(1, Math.floor(qHalfH / (rowH + gap)));
15114
- return items.slice(0, maxRows).map((it, idx) => {
15115
- const py = qyStart + idx * (rowH + gap);
15116
- return /* @__PURE__ */ jsxs("g", { children: [
15117
- /* @__PURE__ */ jsx(
15118
- "rect",
15119
- {
15120
- "data-cdl-role": "quadrant-item",
15121
- "data-cdl-unresolved": it.unresolved ? "true" : void 0,
15122
- x: qxStart,
15123
- y: py,
15124
- width: \u67A0\u306E\u5E45(it.title),
15125
- height: rowH,
15126
- rx: 6,
15127
- fill: "var(--cdl-node-fill, #ffffff)",
15128
- stroke: quadrantAccent[q],
15129
- strokeWidth: 1.5
15130
- }
15131
- ),
15132
- /* @__PURE__ */ jsx("text", { x: qxStart + ITEM_PAD_X, y: py + rowH / 2 + 5, fontSize: ITEM_FONT, fontWeight: 600, letterSpacing: 0, fill: "var(--cdl-text, #1a1f2a)", children: it.title })
15133
- ] }, `item-${it.id}`);
15134
- });
15595
+ const \u7573\u3080 = items.length > maxRows;
15596
+ const \u540D\u524D\u3092\u51FA\u3059 = \u7573\u3080 ? items.slice(0, maxRows - 1) : items;
15597
+ const \u7573\u3093\u3060\u4EF6\u6570 = items.length - \u540D\u524D\u3092\u51FA\u3059.length;
15598
+ return /* @__PURE__ */ jsxs("g", { children: [
15599
+ \u540D\u524D\u3092\u51FA\u3059.map((it, idx) => {
15600
+ const py = qyStart + idx * (rowH + gap);
15601
+ const \u5E45 = \u67A0\u306E\u5E45(\u884C\u3089(it));
15602
+ const \u88DC\u8DB3 = (it.subtitle ?? "").trim();
15603
+ const \u88DC\u8DB3\u306E\u5B57 = SUB_FONT * \u53CE\u3081\u308B\u500D\u7387(
15604
+ \u88DC\u8DB3,
15605
+ { fontSize: SUB_FONT, fontWeight: 500 },
15606
+ Math.max(0, \u5E45 - ITEM_PAD_X * 2)
15607
+ );
15608
+ return /* @__PURE__ */ jsxs("g", { children: [
15609
+ /* @__PURE__ */ jsx(
15610
+ "rect",
15611
+ {
15612
+ "data-cdl-role": "quadrant-item",
15613
+ "data-cdl-unresolved": it.unresolved ? "true" : void 0,
15614
+ x: qxStart,
15615
+ y: py,
15616
+ width: \u5E45,
15617
+ height: rowH,
15618
+ rx: 6,
15619
+ fill: "var(--cdl-node-fill, #ffffff)",
15620
+ stroke: quadrantAccent[q],
15621
+ strokeWidth: 1.5
15622
+ }
15623
+ ),
15624
+ /* @__PURE__ */ jsx(
15625
+ "text",
15626
+ {
15627
+ x: qxStart + ITEM_PAD_X,
15628
+ y: \u88DC\u8DB3 === "" ? py + rowH / 2 + 5 : py + rowH / 2 - 2,
15629
+ fontSize: ITEM_FONT,
15630
+ fontWeight: 600,
15631
+ letterSpacing: 0,
15632
+ fill: "var(--cdl-text, #1a1f2a)",
15633
+ children: it.title
15634
+ }
15635
+ ),
15636
+ \u88DC\u8DB3 !== "" && /* @__PURE__ */ jsx(
15637
+ "text",
15638
+ {
15639
+ "data-cdl-role": "quadrant-item-subtitle",
15640
+ x: qxStart + ITEM_PAD_X,
15641
+ y: py + rowH / 2 + 11,
15642
+ fontSize: \u88DC\u8DB3\u306E\u5B57,
15643
+ fontWeight: 500,
15644
+ letterSpacing: 0,
15645
+ fill: "var(--cdl-text-dim, #5a6270)",
15646
+ children: \u88DC\u8DB3
15647
+ }
15648
+ )
15649
+ ] }, `item-${it.id}`);
15650
+ }),
15651
+ \u7573\u3080 ? (
15652
+ /*
15653
+ 畳んだ段は名前の段と見た目を分ける。 同じにすると「ほか 3 件」 という名前の
15654
+ 項目があるように読める。 枠を持たず、点線の下線と薄い字で「続きがある」 ことを表す。
15655
+ */
15656
+ /* @__PURE__ */ jsxs("g", { children: [
15657
+ /* @__PURE__ */ jsx(
15658
+ "line",
15659
+ {
15660
+ "data-cdl-role": "quadrant-more-rule",
15661
+ x1: qxStart,
15662
+ y1: qyStart + \u540D\u524D\u3092\u51FA\u3059.length * (rowH + gap) + rowH / 2 + 9,
15663
+ x2: qxStart + \u67A0\u306E\u5E45([{ text: \u7573\u3093\u3060\u6587(\u7573\u3093\u3060\u4EF6\u6570), size: ITEM_FONT, weight: 600 }]),
15664
+ y2: qyStart + \u540D\u524D\u3092\u51FA\u3059.length * (rowH + gap) + rowH / 2 + 9,
15665
+ stroke: quadrantAccent[q],
15666
+ strokeWidth: 1,
15667
+ strokeDasharray: "3 3",
15668
+ strokeOpacity: 0.6
15669
+ }
15670
+ ),
15671
+ /* @__PURE__ */ jsx(
15672
+ "text",
15673
+ {
15674
+ "data-cdl-role": "quadrant-more",
15675
+ x: qxStart + ITEM_PAD_X,
15676
+ y: qyStart + \u540D\u524D\u3092\u51FA\u3059.length * (rowH + gap) + rowH / 2 + 5,
15677
+ fontSize: ITEM_FONT,
15678
+ fontWeight: 600,
15679
+ letterSpacing: 0,
15680
+ fill: quadrantAccent[q],
15681
+ children: \u7573\u3093\u3060\u6587(\u7573\u3093\u3060\u4EF6\u6570)
15682
+ }
15683
+ )
15684
+ ] }, `more-${q}`)
15685
+ ) : null
15686
+ ] }, `q-${q}`);
15687
+ }),
15688
+ \u70B9\u3067\u7F6E\u304F.map((it) => {
15689
+ const at = it.at;
15690
+ const px = PAD_LEFT2 + at.x * canvasW;
15691
+ const py = PAD_TOP2 + (1 - at.y) * canvasH;
15692
+ const \u53F3\u5BC4\u308A = at.x >= 0.5;
15693
+ const \u540D\u524D\u306Ex = px + (\u53F3\u5BC4\u308A ? -11 : POINT_R + POINT_GAP);
15694
+ const \u5BC4\u305B = \u53F3\u5BC4\u308A ? "end" : "start";
15695
+ const \u88DC\u8DB3 = (it.subtitle ?? "").trim();
15696
+ return /* @__PURE__ */ jsxs("g", { "data-cdl-unresolved": it.unresolved ? "true" : void 0, children: [
15697
+ /* @__PURE__ */ jsx(
15698
+ "circle",
15699
+ {
15700
+ "data-cdl-role": "quadrant-point",
15701
+ cx: px,
15702
+ cy: py,
15703
+ r: POINT_R,
15704
+ fill: quadrantAccent[it.quadrant]
15705
+ }
15706
+ ),
15707
+ /* @__PURE__ */ jsx(
15708
+ "text",
15709
+ {
15710
+ "data-cdl-role": "quadrant-point-label",
15711
+ x: \u540D\u524D\u306Ex,
15712
+ y: \u88DC\u8DB3 === "" ? py + 4 : py - 1,
15713
+ fontSize: ITEM_FONT,
15714
+ fontWeight: 600,
15715
+ letterSpacing: 0,
15716
+ textAnchor: \u5BC4\u305B,
15717
+ fill: "var(--cdl-text, #1a1f2a)",
15718
+ children: it.title
15719
+ }
15720
+ ),
15721
+ \u88DC\u8DB3 !== "" && /* @__PURE__ */ jsx(
15722
+ "text",
15723
+ {
15724
+ "data-cdl-role": "quadrant-point-subtitle",
15725
+ x: \u540D\u524D\u306Ex,
15726
+ y: py + 11,
15727
+ fontSize: SUB_FONT,
15728
+ fontWeight: 500,
15729
+ letterSpacing: 0,
15730
+ textAnchor: \u5BC4\u305B,
15731
+ fill: "var(--cdl-text-dim, #5a6270)",
15732
+ children: \u88DC\u8DB3
15733
+ }
15734
+ )
15735
+ ] }, `at-${it.id}`);
15135
15736
  })
15136
15737
  ] });
15137
15738
  }
@@ -16024,12 +16625,13 @@ function ShapeTerminalNode({ node, active, lang }) {
16024
16625
  const \u5148\u982D = 26;
16025
16626
  const \u884C\u9593 = 22;
16026
16627
  const \u30AB\u30FC\u30BD\u30EB = { \u5DE6: 30, \u5E45: 9, \u9AD8: 14, \u4E0A: 11, \u4E0B: 3 };
16628
+ const \u51FA\u529B = \u66F8\u3044\u305F\u5024\u304B\u63A7\u3048(node.subtitle, \u5B57\u5F15("terminal.output"));
16027
16629
  const \u884C = [
16028
16630
  [
16029
16631
  { \u5DE6: 16, \u5B57: 12.5, \u8272: "#7cd88f", \u6587: "$" },
16030
16632
  { \u5DE6: 30, \u5B57: 12.5, \u8272: "#e6edf3", \u6587: "pnpm build" }
16031
16633
  ],
16032
- [{ \u5DE6: 16, \u5B57: 12.5, \u8272: "#8b95a5", \u6587: \u5B57\u5F15("terminal.output") }],
16634
+ [{ \u5DE6: 16, \u5B57: 12.5, \u8272: "#8b95a5", \u6587: \u51FA\u529B }],
16033
16635
  [{ \u5DE6: 16, \u5B57: 12.5, \u8272: "#7cd88f", \u6587: "$" }]
16034
16636
  ];
16035
16637
  const \u81EA\u7136\u5E45 = Math.max(...\u884C.flat().map((c) => c.\u5DE6 + \u7B49\u5E45\u306E\u6841(c.\u6587) * MONO_ADVANCE * c.\u5B57)) + \u4F59\u767D;
@@ -16151,7 +16753,9 @@ function ShapeCodeBlockNode({ node, active, lang }) {
16151
16753
  const w = Math.max(0, node.w - \u7DDA * 2);
16152
16754
  const bodyH = Math.max(0, node.h - 42 - \u7DDA * 2);
16153
16755
  const lineFont = "ui-monospace, SFMono-Regular, Menlo, monospace";
16154
- const \u30BF\u30D6\u5E45 = 100;
16756
+ const \u672D = \u66F8\u3044\u305F\u5024\u304B\u63A7\u3048(node.subtitle, \u5B57\u5F15("codeBlock.fileName"));
16757
+ const \u672D\u306E\u5B57 = 11;
16758
+ const \u30BF\u30D6\u5E45 = Math.min(Math.max(100, textWidth(\u672D, \u672D\u306E\u5B57, 0) + 24), Math.max(0, w));
16155
16759
  const \u30BF\u30D6\u9AD8 = 24;
16156
16760
  const \u89D2 = 10;
16157
16761
  const \u6E9D = 32;
@@ -16188,7 +16792,7 @@ function ShapeCodeBlockNode({ node, active, lang }) {
16188
16792
  const \u81EA\u7136\u9AD8 = \u30BF\u30D6\u9AD8 + \u884C\u982D + \u884C\u9593 * (lines.length - 1) + Math.max(\u592A\u3055 - \u6301\u3061\u4E0A\u3052, \u884C\u756A\u53F7\u306E\u5B57 * DESCENT3);
16189
16793
  const \u500D = Math.min(1, bodyH / \u81EA\u7136\u9AD8);
16190
16794
  const \u6253\u3061\u6D88\u3059\u5B57\u3089 = [
16191
- { text: \u5B57\u5F15("codeBlock.fileName"), size: 11, \u5E2F: { \u5E45: \u30BF\u30D6\u5E45, \u9AD8\u3055: \u30BF\u30D6\u9AD8 } },
16795
+ { text: \u672D, size: \u672D\u306E\u5B57, \u5E2F: { \u5E45: \u30BF\u30D6\u5E45, \u9AD8\u3055: \u30BF\u30D6\u9AD8 } },
16192
16796
  { text: "1", size: \u884C\u756A\u53F7\u306E\u5B57, \u5E2F: { \u5E45: \u6E9D - \u6301\u3061\u4E0A\u3052, \u9AD8\u3055: \u884C\u9593 } }
16193
16797
  ];
16194
16798
  const \u500D\u8FD4\u3057 = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D, \u6253\u3061\u6D88\u3059\u5B57\u3089);
@@ -16230,11 +16834,11 @@ function ShapeCodeBlockNode({ node, active, lang }) {
16230
16834
  "data-cdl-counter-scaled": "1",
16231
16835
  x: x + tabW / 2,
16232
16836
  y: y + tabH / 2 + 4 * \u500D,
16233
- fontSize: 11 * \u500D * \u500D\u8FD4\u3057,
16837
+ fontSize: \u672D\u306E\u5B57 * \u500D * \u500D\u8FD4\u3057 * \u5E45\u306E\u500D\u7387(\u672D, \u672D\u306E\u5B57 * \u500D * \u500D\u8FD4\u3057, 0, tabW),
16234
16838
  fontFamily: lineFont,
16235
16839
  textAnchor: "middle",
16236
16840
  fill: "#e6edf3",
16237
- children: \u5B57\u5F15("codeBlock.fileName")
16841
+ children: \u672D
16238
16842
  }
16239
16843
  ),
16240
16844
  /* @__PURE__ */ jsx("circle", { cx: x + tabW - \u4E38, cy: y + tabH / 2, r: 3 * \u500D, fill: "#7cd88f", stroke: "none" }),
@@ -16334,6 +16938,7 @@ function ShapeKanbanCardNode({ node, active, lang }) {
16334
16938
  const PILL\u9AD8 = 16;
16335
16939
  const PILL\u5B57 = 11;
16336
16940
  const PILL\u5B57\u9593 = 0;
16941
+ const PILL\u5B57\u5E45 = PILL\u5E45 - 6;
16337
16942
  const FOOTER\u4E0B = 22;
16338
16943
  const AVATAR\u4E2D\u5FC3Y = 4;
16339
16944
  const AVATAR\u534A\u5F84 = 9;
@@ -16363,6 +16968,11 @@ function ShapeKanbanCardNode({ node, active, lang }) {
16363
16968
  \u4E0B: size * \u8AAC\u660E\u57FA\u6E96\u6BD4 + size * \u8AAC\u660E\u5B57\u6BD4 * DESCENT3
16364
16969
  })
16365
16970
  );
16971
+ const \u8AAC\u660E = \u66F8\u3044\u305F\u5024\u304B\u63A7\u3048(node.subtitle, \u5B57\u5F15("kanbanCard.task"));
16972
+ const \u72B6\u614B = \u66F8\u3044\u305F\u5024\u304B\u63A7\u3048(node.eyebrow, \u5B57\u5F15("kanbanCard.status"));
16973
+ const \u72B6\u614B\u306E\u500D\u7387 = \u5E45\u306E\u500D\u7387(\u72B6\u614B, PILL\u5B57, PILL\u5B57\u9593, PILL\u5B57\u5E45);
16974
+ const \u8AAC\u660E\u306E\u5B57 = \u540D\u524D.size * \u8AAC\u660E\u5B57\u6BD4;
16975
+ const \u4F7F\u3048\u308B\u5E452 = Math.max(0, w - \u5DE6\u53F3\u4F59\u767D * \u500D * 2);
16366
16976
  return /* @__PURE__ */ jsxs("g", { children: [
16367
16977
  /* @__PURE__ */ jsx(
16368
16978
  "rect",
@@ -16417,15 +17027,16 @@ function ShapeKanbanCardNode({ node, active, lang }) {
16417
17027
  /* @__PURE__ */ jsx(
16418
17028
  "text",
16419
17029
  {
17030
+ "data-cdl-role": "kanban-status",
16420
17031
  x: x + w - (\u5DE6\u53F3\u4F59\u767D + PILL\u5E45 / 2) * \u500D,
16421
17032
  y: pillY + 12 * \u500D,
16422
- fontSize: PILL\u5B57 * \u500D,
17033
+ fontSize: PILL\u5B57 * \u500D * \u72B6\u614B\u306E\u500D\u7387,
16423
17034
  fontWeight: 700,
16424
- letterSpacing: PILL\u5B57\u9593 * \u500D,
17035
+ letterSpacing: PILL\u5B57\u9593 * \u500D * \u72B6\u614B\u306E\u500D\u7387,
16425
17036
  textAnchor: "middle",
16426
17037
  fill: "#5a4a1a",
16427
17038
  fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
16428
- children: \u5B57\u5F15("kanbanCard.status")
17039
+ children: \u72B6\u614B
16429
17040
  }
16430
17041
  ),
16431
17042
  /* @__PURE__ */ jsx(
@@ -16446,10 +17057,10 @@ function ShapeKanbanCardNode({ node, active, lang }) {
16446
17057
  {
16447
17058
  x: x + w / 2,
16448
17059
  y: \u540D\u524D.y + \u540D\u524D.size * \u8AAC\u660E\u57FA\u6E96\u6BD4,
16449
- fontSize: \u540D\u524D.size * \u8AAC\u660E\u5B57\u6BD4,
17060
+ fontSize: \u8AAC\u660E\u306E\u5B57 * \u5E45\u306E\u500D\u7387(\u8AAC\u660E, \u8AAC\u660E\u306E\u5B57, 0, \u4F7F\u3048\u308B\u5E452),
16450
17061
  textAnchor: "middle",
16451
17062
  fill: "var(--cdl-text-dim, #5a6270)",
16452
- children: \u5B57\u5F15("kanbanCard.task")
17063
+ children: \u8AAC\u660E
16453
17064
  }
16454
17065
  ),
16455
17066
  /* @__PURE__ */ jsxs("g", { transform: `translate(${x + \u5DE6\u53F3\u4F59\u767D * \u500D}, ${footY})`, children: [
@@ -17467,6 +18078,7 @@ var SMART_CONTRACT_H = 220;
17467
18078
  var BLOCK_W = 240;
17468
18079
  var BLOCK_H = 220;
17469
18080
  var \u898B\u51FA\u3057\u306E\u5B57 = 13;
18081
+ var \u80A9\u66F8\u306E\u5B57 = 10;
17470
18082
  var \u540D\u306E\u5B57 = 11;
17471
18083
  var \u5024\u306E\u5B57 = 11;
17472
18084
  var \u884C\u306E\u9593\u9694 = 22;
@@ -17542,11 +18154,6 @@ function blockchainNodeExtent(strokeWidth) {
17542
18154
  const \u6A2A = (NODE_PEER_DIST + NODE_PEER_R) * Math.cos(Math.PI / 6) + \u7DDA;
17543
18155
  return { \u4E0A: \u7E26, \u4E0B: \u7E26, \u5DE6: \u6A2A, \u53F3: \u6A2A };
17544
18156
  }
17545
- function \u5E45\u306E\u500D\u7387(text, size, letterSpacing, \u5E45) {
17546
- if (!(\u5E45 > 0) || !(size > 0)) return 1;
17547
- const \u5B9F\u5E45 = textWidth(text, size, letterSpacing);
17548
- return \u5B9F\u5E45 > \u5E45 ? \u5E45 / \u5B9F\u5E45 : 1;
17549
- }
17550
18157
  function bottomLabel2(node, cx, plan) {
17551
18158
  const \u80A9\u66F8\u500D\u7387 = node.eyebrow && plan.\u80A9\u66F8 ? \u5E45\u306E\u500D\u7387(node.eyebrow, plan.\u80A9\u66F8.size, 2, node.w) : 1;
17552
18159
  const \u540D\u524D\u500D\u7387 = \u5E45\u306E\u500D\u7387(node.title, plan.\u540D\u524D.size, 0, node.w);
@@ -17664,9 +18271,18 @@ function ShapeBlockchainBlockNode({ node, active, lang }) {
17664
18271
  value: f.key === "hash" ? \u6E21\u3055\u308C\u305F(node.subtitle) || \u65E2\u5B9A\u5024 : \u65E2\u5B9A\u5024
17665
18272
  };
17666
18273
  });
17667
- const \u898B\u51FA\u3057\u306E\u5E45 = bw - 14 - 30;
18274
+ const \u80A9\u66F8 = \u6E21\u3055\u308C\u305F(node.eyebrow);
18275
+ const \u5E2F\u306E\u6B8B\u308A = bw - 14 - 30;
18276
+ const \u80A9\u66F8\u306E\u9699\u9593 = 8;
18277
+ const \u80A9\u66F8\u306E\u4E0A\u9650 = (\u5E2F\u306E\u6B8B\u308A - \u80A9\u66F8\u306E\u9699\u9593) / 2;
18278
+ const \u80A9\u66F8\u306E\u500D\u7387 = \u80A9\u66F8 === "" ? 1 : \u5E45\u306E\u500D\u7387(\u80A9\u66F8, \u80A9\u66F8\u306E\u5B57, 0, \u80A9\u66F8\u306E\u4E0A\u9650);
18279
+ const \u80A9\u66F8\u306E\u6307\u5B9A = \u80A9\u66F8\u306E\u5B57 * \u80A9\u66F8\u306E\u500D\u7387;
18280
+ const \u80A9\u66F8\u306E\u5E45 = \u80A9\u66F8 === "" ? 0 : \u5B57\u306E\u5E45(\u80A9\u66F8, \u80A9\u66F8\u306E\u6307\u5B9A);
18281
+ const \u898B\u51FA\u3057\u306E\u5E45 = \u5E2F\u306E\u6B8B\u308A - (\u80A9\u66F8 === "" ? 0 : \u80A9\u66F8\u306E\u5E45 + \u80A9\u66F8\u306E\u9699\u9593);
17668
18282
  const \u6253\u3061\u6D88\u3059\u5B57\u3089 = [
17669
18283
  { text: \u898B\u51FA\u3057, size: \u898B\u51FA\u3057\u306E\u5B57, \u5E2F: { \u5E45: \u898B\u51FA\u3057\u306E\u5E45, \u9AD8\u3055: \u898B\u51FA\u3057\u306E\u5E2F } },
18284
+ // 肩書も帯に入れる = 入れないと打ち消しの倍率が肩書を見ずに決まり、帯から横へ出る
18285
+ ...\u80A9\u66F8 === "" ? [] : [{ text: \u80A9\u66F8, size: \u80A9\u66F8\u306E\u6307\u5B9A, \u5E2F: { \u5E45: \u80A9\u66F8\u306E\u5E45, \u9AD8\u3055: \u898B\u51FA\u3057\u306E\u5E2F } }],
17670
18286
  ...fields.flatMap((f) => [
17671
18287
  { text: f.label, size: \u540D\u306E\u5B57, \u5E2F: { \u5E45: bw - 28, \u9AD8\u3055: \u884C\u306E\u9593\u9694 } },
17672
18288
  {
@@ -17679,6 +18295,7 @@ function ShapeBlockchainBlockNode({ node, active, lang }) {
17679
18295
  const art = (\u500D\u7387) => {
17680
18296
  const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089);
17681
18297
  const \u984C\u306E\u5927\u304D\u3055 = \u898B\u51FA\u3057\u306E\u5B57 * \u500D;
18298
+ const \u80A9\u66F8\u306E\u5927\u304D\u3055 = \u80A9\u66F8\u306E\u6307\u5B9A * \u500D;
17682
18299
  const \u540D\u306E\u5927\u304D\u3055 = \u540D\u306E\u5B57 * \u500D;
17683
18300
  const \u5024\u306E\u5927\u304D\u3055 = \u5024\u306E\u5B57 * \u500D;
17684
18301
  return /* @__PURE__ */ jsxs("g", { children: [
@@ -17686,6 +18303,22 @@ function ShapeBlockchainBlockNode({ node, active, lang }) {
17686
18303
  /* @__PURE__ */ jsx("rect", { "data-cdl-role": "node-body", x, y, width: bw, height: bh, rx: 8, ...frame }),
17687
18304
  /* @__PURE__ */ jsx("path", { d: `M ${x} ${y + 32} L ${x} ${y + 8} Q ${x} ${y}, ${x + 8} ${y} L ${x + bw - 8} ${y} Q ${x + bw} ${y}, ${x + bw} ${y + 8} L ${x + bw} ${y + 32} Z`, fill: "var(--cdl-tone-accent, #2d6a8f)", fillOpacity: 0.9, stroke: "none" }),
17688
18305
  /* @__PURE__ */ jsx("text", { "data-cdl-role": "blockchain-block-title", "data-cdl-counter-scaled": "1", x: x + 14, y: y + 22, fontSize: \u984C\u306E\u5927\u304D\u3055, fontWeight: 700, fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace", fill: "#ffffff", children: \u5E45\u3067\u5207\u308B(\u898B\u51FA\u3057, \u984C\u306E\u5927\u304D\u3055, \u898B\u51FA\u3057\u306E\u5E45, \u5B57\u306E\u5E45) }),
18306
+ \u80A9\u66F8 !== "" && /* @__PURE__ */ jsx(
18307
+ "text",
18308
+ {
18309
+ "data-cdl-role": "blockchain-block-eyebrow",
18310
+ "data-cdl-counter-scaled": "1",
18311
+ x: x + bw - 30,
18312
+ y: y + 21,
18313
+ fontSize: \u80A9\u66F8\u306E\u5927\u304D\u3055,
18314
+ fontWeight: 600,
18315
+ textAnchor: "end",
18316
+ fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
18317
+ fill: "#ffffff",
18318
+ fillOpacity: 0.78,
18319
+ children: \u80A9\u66F8
18320
+ }
18321
+ ),
17689
18322
  /* @__PURE__ */ jsx("circle", { cx: x + bw - 16, cy: y + 16, r: 5.5, fill: "#7cd88f", stroke: "#ffffff", strokeWidth: 1.5 }),
17690
18323
  fields.map((f, i) => /* @__PURE__ */ jsxs("g", { children: [
17691
18324
  /* @__PURE__ */ jsx("text", { "data-cdl-counter-scaled": "1", x: x + 14, y: y + 54 + i * \u884C\u306E\u9593\u9694, fontSize: \u540D\u306E\u5927\u304D\u3055, fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace", fill: "var(--cdl-text-dim, #5a6270)", children: f.label }),
@@ -17747,7 +18380,7 @@ function ShapeBlockchainNode({ node, active }) {
17747
18380
  420 + i
17748
18381
  ] }),
17749
18382
  /* @__PURE__ */ jsx("text", { "data-cdl-counter-scaled": "0", x: bx + blockW / 2, y: cy + 8, fontSize: 14, fontWeight: 700, textAnchor: "middle", fill: isCurrent ? "#ffffff" : "var(--cdl-tone-accent, #2d6a8f)", fontFamily: "Georgia, serif", children: "#" }),
17750
- /* @__PURE__ */ jsx("text", { "data-cdl-counter-scaled": "1", x: bx + blockW / 2, y: cy + 22, fontSize: CHAIN_HASH_SIZE * \u500D, fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace", textAnchor: "middle", fill: isCurrent ? "#ffffff" : "var(--cdl-text-dim, #5a6270)", opacity: 0.9, children: "0x\u2026" })
18383
+ /* @__PURE__ */ jsx("text", { "data-cdl-ellipsis": "written", "data-cdl-counter-scaled": "1", x: bx + blockW / 2, y: cy + 22, fontSize: CHAIN_HASH_SIZE * \u500D, fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace", textAnchor: "middle", fill: isCurrent ? "#ffffff" : "var(--cdl-text-dim, #5a6270)", opacity: 0.9, children: "0x\u2026" })
17751
18384
  ] }, i);
17752
18385
  }) });
17753
18386
  };
@@ -18782,13 +19415,18 @@ function ShapeWarehouseNode({ node, active, lang }) {
18782
19415
  bottomLabel4(node, r.cx, r.label)
18783
19416
  ] });
18784
19417
  }
19418
+ var HANDLE_GRIP_X = 118;
19419
+ var HANDLE_GRIP_R = 4;
19420
+ var CART_SHADOW_RX = 80;
18785
19421
  function ShapeOnlineShopNode({ node, active }) {
18786
19422
  const frame = commonFrame6(active);
18787
19423
  const r = shapeRegion(node);
18788
- const cx = r.cx;
18789
19424
  const cy = r.cy + 10;
18790
19425
  const scale = Math.min(r.availW / 260, r.availH / 320);
18791
19426
  const s = scale * 0.9;
19427
+ const \u5DE6\u3078\u51FA\u308B = HANDLE_GRIP_X + HANDLE_GRIP_R;
19428
+ const \u53F3\u3078\u51FA\u308B = CART_SHADOW_RX;
19429
+ const cx = r.cx + (\u5DE6\u3078\u51FA\u308B - \u53F3\u3078\u51FA\u308B) / 2 * s;
18792
19430
  const accent = "var(--cdl-tone-accent, #2d6a8f)";
18793
19431
  const accentDark = "#1a4a68";
18794
19432
  const accentDarker = "#0f3450";
@@ -18802,9 +19440,9 @@ function ShapeOnlineShopNode({ node, active }) {
18802
19440
  const wheelL = cx - 42 * s;
18803
19441
  const wheelR = cx + 42 * s;
18804
19442
  return /* @__PURE__ */ jsxs("g", { children: [
18805
- /* @__PURE__ */ jsx("ellipse", { cx, cy: wheelY + 22 * s, rx: 80 * s, ry: 5 * s, fill: frame.stroke, opacity: 0.25, stroke: "none" }),
18806
- /* @__PURE__ */ jsx("path", { d: `M ${cx - 118 * s} ${basketTopY - 60 * s} L ${cx - 90 * s} ${basketTopY - 60 * s} L ${cx - 80 * s} ${basketTopY - 30 * s} L ${basketTopL} ${basketTopY}`, fill: "none", stroke: accent, strokeWidth: 6 * s, strokeLinecap: "round", strokeLinejoin: "round" }),
18807
- /* @__PURE__ */ jsx("circle", { cx: cx - 118 * s, cy: basketTopY - 60 * s, r: 4 * s, fill: accent, stroke: accentDark, strokeWidth: 1.5 }),
19443
+ /* @__PURE__ */ jsx("ellipse", { cx, cy: wheelY + 22 * s, rx: CART_SHADOW_RX * s, ry: 5 * s, fill: frame.stroke, opacity: 0.25, stroke: "none" }),
19444
+ /* @__PURE__ */ jsx("path", { d: `M ${cx - HANDLE_GRIP_X * s} ${basketTopY - 60 * s} L ${cx - 90 * s} ${basketTopY - 60 * s} L ${cx - 80 * s} ${basketTopY - 30 * s} L ${basketTopL} ${basketTopY}`, fill: "none", stroke: accent, strokeWidth: 6 * s, strokeLinecap: "round", strokeLinejoin: "round" }),
19445
+ /* @__PURE__ */ jsx("circle", { cx: cx - HANDLE_GRIP_X * s, cy: basketTopY - 60 * s, r: HANDLE_GRIP_R * s, fill: accent, stroke: accentDark, strokeWidth: 1.5 }),
18808
19446
  /* @__PURE__ */ jsx(
18809
19447
  "path",
18810
19448
  {
@@ -19622,11 +20260,58 @@ function CdlNodeView({
19622
20260
  pointerEvents: "none"
19623
20261
  }
19624
20262
  ),
19625
- inner
20263
+ inner,
20264
+ \u7BB1\u306E\u4E0A\u306E\u8A9E(resolvedNode)
19626
20265
  ]
19627
20266
  }
19628
20267
  );
19629
20268
  }
20269
+ var FIGURE_TITLE_GAP = 10;
20270
+ var FIGURE_TITLE_SIZE = 15;
20271
+ var FIGURE_EYEBROW_SIZE = 11;
20272
+ var FIGURE_EYEBROW_LIFT = 1.1;
20273
+ function \u5E45\u306B\u53CE\u3081\u305F\u5927\u304D\u3055(\u8A9E, \u7D20\u306E\u5927\u304D\u3055, \u5E45) {
20274
+ const \u5B9F\u5E45 = textWidth(\u8A9E, \u7D20\u306E\u5927\u304D\u3055, 0);
20275
+ return \u5B9F\u5E45 > \u5E45 ? \u7D20\u306E\u5927\u304D\u3055 * \u5E45 / \u5B9F\u5E45 : \u7D20\u306E\u5927\u304D\u3055;
20276
+ }
20277
+ function \u7BB1\u306E\u4E0A\u306E\u8A9E(node) {
20278
+ if (!drawsFigureTitle(node.kind)) return null;
20279
+ const \u540D\u524D = (node.title ?? "").trim();
20280
+ const \u5C0F\u898B\u51FA\u3057 = (node.eyebrow ?? "").trim();
20281
+ if (\u540D\u524D === "" && \u5C0F\u898B\u51FA\u3057 === "") return null;
20282
+ const \u984C\u306Ey = node.cy - node.h / 2 - FIGURE_TITLE_GAP;
20283
+ const \u984C\u306E\u5927\u304D\u3055 = \u5E45\u306B\u53CE\u3081\u305F\u5927\u304D\u3055(\u540D\u524D, FIGURE_TITLE_SIZE, node.w);
20284
+ const \u5C0F\u898B\u51FA\u3057\u306Ey = \u540D\u524D === "" ? \u984C\u306Ey : \u984C\u306Ey - \u984C\u306E\u5927\u304D\u3055 * FIGURE_EYEBROW_LIFT;
20285
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
20286
+ \u5C0F\u898B\u51FA\u3057 !== "" && /* @__PURE__ */ jsx(
20287
+ "text",
20288
+ {
20289
+ "data-cdl-role": "figure-eyebrow",
20290
+ x: node.cx,
20291
+ y: \u5C0F\u898B\u51FA\u3057\u306Ey,
20292
+ textAnchor: "middle",
20293
+ fontSize: \u5E45\u306B\u53CE\u3081\u305F\u5927\u304D\u3055(\u5C0F\u898B\u51FA\u3057, FIGURE_EYEBROW_SIZE, node.w),
20294
+ fontWeight: 600,
20295
+ letterSpacing: 0.6,
20296
+ fill: "var(--cdl-text-dim, #5a6270)",
20297
+ children: \u5C0F\u898B\u51FA\u3057
20298
+ }
20299
+ ),
20300
+ \u540D\u524D !== "" && /* @__PURE__ */ jsx(
20301
+ "text",
20302
+ {
20303
+ "data-cdl-role": "figure-title",
20304
+ x: node.cx,
20305
+ y: \u984C\u306Ey,
20306
+ textAnchor: "middle",
20307
+ fontSize: \u984C\u306E\u5927\u304D\u3055,
20308
+ fontWeight: 600,
20309
+ fill: "var(--cdl-text, #23201b)",
20310
+ children: \u540D\u524D
20311
+ }
20312
+ )
20313
+ ] });
20314
+ }
19630
20315
 
19631
20316
  // src/render/relation-focus.ts
19632
20317
  function relatedFocusSet(edges, nodeId) {
@@ -19639,6 +20324,11 @@ function relatedFocusSet(edges, nodeId) {
19639
20324
  }
19640
20325
  return \u96C6\u5408;
19641
20326
  }
20327
+ function \u63CF\u304F\u3082\u306E\u304C\u3042\u308B(laid) {
20328
+ if (laid.edges.length > 0) return true;
20329
+ if (laid.nodes.some((n) => isRenderedNode(n))) return true;
20330
+ return laid.lanes.some((l) => l.contain === true || l.lifeline === true || Boolean(l.label));
20331
+ }
19642
20332
  function CdlStage({
19643
20333
  laid,
19644
20334
  currentPhase,
@@ -19797,6 +20487,7 @@ function CdlStage({
19797
20487
  );
19798
20488
  }, [laid]);
19799
20489
  const diagramScale = laid.diagramScale ?? 1;
20490
+ if (!\u63CF\u304F\u3082\u306E\u304C\u3042\u308B(laid)) return null;
19800
20491
  return /* @__PURE__ */ jsxs("div", { className: compact ? "px-3 py-3" : "px-6 py-6", style: compact ? void 0 : { minHeight: 460 }, children: [
19801
20492
  /* @__PURE__ */ jsxs(
19802
20493
  "svg",