@cardenelabs/cdl 0.121.0 → 0.123.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 (69) hide show
  1. package/CHANGELOG.md +51 -1
  2. package/README.md +137 -0
  3. package/SPEC.md +1 -1
  4. package/dist/index.cjs +1513 -667
  5. package/dist/index.cjs.map +1 -1
  6. package/dist/index.d.cts +51 -33
  7. package/dist/index.d.ts +51 -33
  8. package/dist/index.js +1513 -668
  9. package/dist/index.js.map +1 -1
  10. package/dist/react.cjs +1271 -444
  11. package/dist/react.cjs.map +1 -1
  12. package/dist/react.d.cts +1 -1
  13. package/dist/react.d.ts +1 -1
  14. package/dist/react.js +1271 -444
  15. package/dist/react.js.map +1 -1
  16. package/dist/{render-A5AKjNuy.d.cts → render-CVczwfRb.d.cts} +40 -7
  17. package/dist/{render-A5AKjNuy.d.ts → render-CVczwfRb.d.ts} +40 -7
  18. package/package.json +9 -12
  19. package/src/builder.ts +8 -2
  20. package/src/index.ts +3 -0
  21. package/src/kinds/box-lines.ts +17 -4
  22. package/src/kinds/chart-bar.tsx +4 -0
  23. package/src/kinds/chart-gauge.tsx +20 -9
  24. package/src/kinds/chart-pie.tsx +67 -17
  25. package/src/kinds/chart-radial.tsx +7 -2
  26. package/src/kinds/chart-slope.tsx +26 -7
  27. package/src/kinds/chart-stacked-bar.tsx +8 -4
  28. package/src/kinds/chart-stat.tsx +19 -4
  29. package/src/kinds/chart-waffle.tsx +7 -2
  30. package/src/kinds/dyn-shape.tsx +22 -9
  31. package/src/kinds/funnel.tsx +9 -2
  32. package/src/kinds/generic.tsx +5 -2
  33. package/src/kinds/mind-map.tsx +26 -10
  34. package/src/kinds/quadrant.tsx +14 -4
  35. package/src/kinds/row-align.ts +19 -7
  36. package/src/kinds/sequence-board-metrics.ts +13 -3
  37. package/src/kinds/sequence-board.tsx +4 -2
  38. package/src/kinds/shape-basement.tsx +57 -32
  39. package/src/kinds/shape-blockchain.tsx +83 -34
  40. package/src/kinds/shape-commerce.tsx +65 -24
  41. package/src/kinds/shape-finance.tsx +90 -26
  42. package/src/kinds/shape-hardware.tsx +48 -17
  43. package/src/kinds/shape-region.tsx +16 -6
  44. package/src/kinds/shape-software.tsx +30 -8
  45. package/src/kinds/station.tsx +29 -0
  46. package/src/kinds/text-width.ts +17 -3
  47. package/src/kinds/tree.tsx +25 -7
  48. package/src/layout/collisions.ts +50 -28
  49. package/src/layout/curve-path.ts +126 -0
  50. package/src/layout/edges.ts +271 -58
  51. package/src/layout/head-label.ts +11 -5
  52. package/src/layout/lanes.ts +3 -2
  53. package/src/layout/metro-path.ts +185 -0
  54. package/src/layout/nodes.ts +14 -6
  55. package/src/layout/predict-bbox.ts +6 -3
  56. package/src/layout/self-loop.ts +10 -4
  57. package/src/layout/spec.ts +36 -7
  58. package/src/layout/text-width.ts +25 -8
  59. package/src/layout/tokens.ts +2 -0
  60. package/src/layout-with-validation.ts +10 -5
  61. package/src/layout.ts +55 -21
  62. package/src/presets.ts +69 -43
  63. package/src/render/edges.tsx +19 -3
  64. package/src/render/interactive-panel.tsx +34 -7
  65. package/src/render/nodes.tsx +100 -48
  66. package/src/render/stage.tsx +3 -0
  67. package/src/text-metrics.ts +9 -0
  68. package/src/types.ts +41 -4
  69. package/src/visual-validate.ts +91 -21
package/dist/index.cjs CHANGED
@@ -712,6 +712,11 @@ function \u5B57\u3092\u5DEE\u3057\u8FBC\u3080(template, values) {
712
712
  return template.replace(/\{(\w+)\}/g, (whole, name) => name in values ? String(values[name]) : whole);
713
713
  }
714
714
 
715
+ // src/text-metrics.ts
716
+ function resolveTextMetrics(value) {
717
+ return value === "monospace" ? "monospace" : "proportional";
718
+ }
719
+
715
720
  // src/formula/ast.ts
716
721
  var ALLOWED_MATH_FNS = /* @__PURE__ */ new Set([
717
722
  "min",
@@ -1650,13 +1655,215 @@ function \u5024\u3092\u540D\u524D\u3067\u8AAD\u3080(\u5165\u529B\u6B04, \u5024)
1650
1655
  return \u5024.split(",").map((v) => \u5165\u529B\u6B04.\u540D\u524D.get(v) ?? v).join(",");
1651
1656
  }
1652
1657
 
1658
+ // src/layout/text-width.ts
1659
+ var INTER_BOLD_ADVANCE_EM = {
1660
+ // uppercase (実測係数化、 Inter Bold 仕様 × 1.20)
1661
+ A: 0.86,
1662
+ B: 0.86,
1663
+ C: 0.88,
1664
+ D: 0.93,
1665
+ E: 0.82,
1666
+ F: 0.79,
1667
+ G: 0.94,
1668
+ H: 0.92,
1669
+ I: 0.44,
1670
+ J: 0.66,
1671
+ K: 0.86,
1672
+ L: 0.74,
1673
+ M: 1.12,
1674
+ N: 0.94,
1675
+ O: 0.94,
1676
+ P: 0.85,
1677
+ Q: 0.94,
1678
+ R: 0.87,
1679
+ S: 0.79,
1680
+ T: 0.82,
1681
+ U: 0.91,
1682
+ V: 0.85,
1683
+ W: 1.22,
1684
+ X: 0.85,
1685
+ Y: 0.82,
1686
+ Z: 0.82,
1687
+ // lowercase (実測係数化、 Inter Bold 仕様 × 1.22)
1688
+ a: 0.73,
1689
+ b: 0.77,
1690
+ c: 0.68,
1691
+ d: 0.77,
1692
+ e: 0.73,
1693
+ f: 0.51,
1694
+ g: 0.76,
1695
+ h: 0.77,
1696
+ i: 0.39,
1697
+ j: 0.41,
1698
+ k: 0.73,
1699
+ l: 0.39,
1700
+ m: 1.15,
1701
+ n: 0.77,
1702
+ o: 0.76,
1703
+ p: 0.77,
1704
+ q: 0.77,
1705
+ r: 0.54,
1706
+ s: 0.65,
1707
+ t: 0.54,
1708
+ u: 0.77,
1709
+ v: 0.71,
1710
+ w: 1.05,
1711
+ x: 0.71,
1712
+ y: 0.71,
1713
+ z: 0.66,
1714
+ // digits (Inter Bold tabular-nums、 実測係数化 × 1.20)
1715
+ "0": 0.72,
1716
+ "1": 0.72,
1717
+ "2": 0.72,
1718
+ "3": 0.72,
1719
+ "4": 0.72,
1720
+ "5": 0.72,
1721
+ "6": 0.72,
1722
+ "7": 0.72,
1723
+ "8": 0.72,
1724
+ "9": 0.72,
1725
+ // ascii symbols (実測係数化 × 1.15、 punct 系は kerning が広く効くため 1.20)
1726
+ " ": 0.35,
1727
+ "!": 0.44,
1728
+ '"': 0.59,
1729
+ "#": 0.78,
1730
+ "$": 0.72,
1731
+ "%": 1,
1732
+ "&": 0.86,
1733
+ "'": 0.32,
1734
+ "(": 0.46,
1735
+ ")": 0.46,
1736
+ "*": 0.63,
1737
+ "+": 0.78,
1738
+ ",": 0.36,
1739
+ "-": 0.5,
1740
+ ".": 0.36,
1741
+ "/": 0.51,
1742
+ ":": 0.36,
1743
+ ";": 0.36,
1744
+ "<": 0.78,
1745
+ "=": 0.78,
1746
+ ">": 0.78,
1747
+ "?": 0.63,
1748
+ "@": 1.17,
1749
+ "[": 0.48,
1750
+ "\\": 0.51,
1751
+ "]": 0.48,
1752
+ "^": 0.63,
1753
+ "_": 0.63,
1754
+ "`": 0.48,
1755
+ "{": 0.52,
1756
+ "|": 0.37,
1757
+ "}": 0.52,
1758
+ "~": 0.78
1759
+ };
1760
+ var JETBRAINS_MONO_ADVANCE_EM = 0.63;
1761
+ function isCJK(code) {
1762
+ return code >= 12288 && code <= 12543 || // CJK symbols / hiragana / katakana
1763
+ code >= 13312 && code <= 40959 || // CJK ideographs
1764
+ code >= 63744 && code <= 64255 || // CJK compat ideographs
1765
+ code >= 65281 && code <= 65376 || // fullwidth ASCII
1766
+ code >= 65504 && code <= 65510;
1767
+ }
1768
+ function isHalfwidthKana(code) {
1769
+ return code >= 65377 && code <= 65500;
1770
+ }
1771
+ var EMOJI_ADVANCE_EM = 1.05;
1772
+ var MONO_EMOJI_ADVANCE_EM = 1.16;
1773
+ var DRAWN_CJK_RATIO = 1.08;
1774
+ var DRAWN_ASCII_RATIO = 1.16;
1775
+ function isAscii(code) {
1776
+ return code < 128;
1777
+ }
1778
+ var WIDE_SYMBOL_ADVANCE_EM = 0.95;
1779
+ function isEmoji(code) {
1780
+ return code >= 126976 && code <= 129791 || // 絵文字の主要面
1781
+ code >= 9728 && code <= 10175 || // 記号と絵文字 (♻ ✅ ❤ 等)
1782
+ code >= 127462 && code <= 127487;
1783
+ }
1784
+ function isEmojiGrapheme(grapheme, firstCode) {
1785
+ return isEmoji(firstCode) || grapheme.includes("\uFE0F");
1786
+ }
1787
+ function isWideSymbol(code) {
1788
+ return code >= 8592 && code <= 8703 || // 矢印
1789
+ code >= 9472 && code <= 9599 || // 罫線
1790
+ code >= 9632 && code <= 9727 || // 幾何図形
1791
+ code >= 11008 && code <= 11263;
1792
+ }
1793
+ var CLUSTER_JOINER_RE = /\u200d|\ufe0f|[\u{1f000}-\u{1faff}]|[\u{2600}-\u{27bf}]/u;
1794
+ var \u66F8\u8A18\u7D20\u3067\u5206\u3051\u308B;
1795
+ function segmentGraphemes(text) {
1796
+ if (typeof Intl === "undefined" || typeof Intl.Segmenter !== "function") {
1797
+ return [...text];
1798
+ }
1799
+ \u66F8\u8A18\u7D20\u3067\u5206\u3051\u308B ??= new Intl.Segmenter(void 0, { granularity: "grapheme" });
1800
+ return [...\u66F8\u8A18\u7D20\u3067\u5206\u3051\u308B.segment(text)].map((s) => s.segment);
1801
+ }
1802
+ function defaultAdvanceEm(ch, code) {
1803
+ if (isEmoji(code)) return EMOJI_ADVANCE_EM;
1804
+ if (isWideSymbol(code)) return WIDE_SYMBOL_ADVANCE_EM;
1805
+ if (isCJK(code)) return 1.08;
1806
+ if (isHalfwidthKana(code)) return 0.72;
1807
+ if (ch >= "a" && ch <= "z") return 0.73;
1808
+ if (ch >= "A" && ch <= "Z") return 0.86;
1809
+ if (ch >= "0" && ch <= "9") return 0.72;
1810
+ return 0.65;
1811
+ }
1812
+ function measureAdvanceWidth(text, opts = {}) {
1813
+ const fontSize = opts.fontSize ?? 22;
1814
+ const letterSpacing = opts.letterSpacing ?? 0;
1815
+ const fontFamily = opts.textMetrics === "monospace" ? "mono" : opts.fontFamily ?? "sans";
1816
+ const bound = opts.bound ?? "layout";
1817
+ let advanceEmSum = 0;
1818
+ let charCount = 0;
1819
+ const \u6587\u5B57\u5217 = CLUSTER_JOINER_RE.test(text) ? segmentGraphemes(text) : [...text];
1820
+ for (const ch of \u6587\u5B57\u5217) {
1821
+ charCount++;
1822
+ const code = ch.codePointAt(0) ?? 0;
1823
+ const \u5272\u308A\u623B\u3057 = bound === "drawn" && !isEmojiGrapheme(ch, code) ? isAscii(code) && fontFamily !== "mono" ? DRAWN_ASCII_RATIO : isCJK(code) ? DRAWN_CJK_RATIO : 1 : 1;
1824
+ if (isEmojiGrapheme(ch, code)) {
1825
+ advanceEmSum += fontFamily === "mono" ? MONO_EMOJI_ADVANCE_EM : EMOJI_ADVANCE_EM;
1826
+ continue;
1827
+ }
1828
+ if (fontFamily === "mono") {
1829
+ advanceEmSum += (isCJK(code) ? 1.08 : JETBRAINS_MONO_ADVANCE_EM) / \u5272\u308A\u623B\u3057;
1830
+ continue;
1831
+ }
1832
+ if (isCJK(code)) {
1833
+ advanceEmSum += 1.08 / \u5272\u308A\u623B\u3057;
1834
+ continue;
1835
+ }
1836
+ const table = ch.length === 1 ? INTER_BOLD_ADVANCE_EM[ch] : void 0;
1837
+ advanceEmSum += (table !== void 0 ? table : defaultAdvanceEm(ch, code)) / \u5272\u308A\u623B\u3057;
1838
+ }
1839
+ return advanceEmSum * fontSize + letterSpacing * charCount;
1840
+ }
1841
+ function measureTextWidth(text, opts = {}) {
1842
+ const fontSize = opts.fontSize ?? 22;
1843
+ const bound = opts.bound ?? "layout";
1844
+ const w = measureAdvanceWidth(text, opts);
1845
+ return bound === "drawn" ? w : Math.max(w, fontSize * 1.2);
1846
+ }
1847
+ function \u53CE\u3081\u308B\u500D\u7387(text, opts, \u5E45) {
1848
+ if (!(\u5E45 > 0) || !(opts.fontSize > 0)) return 1;
1849
+ const \u5B9F\u5E45 = measureTextWidth(text, { ...opts, letterSpacing: 0 });
1850
+ return \u5B9F\u5E45 > \u5E45 ? \u5E45 / \u5B9F\u5E45 : 1;
1851
+ }
1852
+
1653
1853
  // src/kinds/text-width.ts
1654
1854
  var WIDE_RATIO = 1.04;
1655
1855
  var NARROW_RATIO = 0.37;
1656
1856
  var ASCII_RATIO = 0.86;
1657
1857
  var WIDE_CHARS = "W@%Mm";
1658
1858
  var NARROW_CHARS = "ijlI.,:;'! ";
1659
- function textWidth(s, size, \u5B57\u9001\u308A = 0) {
1859
+ function textWidth(s, size, \u5B57\u9001\u308A = 0, textMetrics = "proportional") {
1860
+ if (textMetrics === "monospace") {
1861
+ return measureAdvanceWidth(s, {
1862
+ fontSize: size,
1863
+ letterSpacing: \u5B57\u9001\u308A,
1864
+ fontFamily: "mono"
1865
+ });
1866
+ }
1660
1867
  let \u5E45 = 0;
1661
1868
  let \u5B57\u6570 = 0;
1662
1869
  for (const c of s) {
@@ -1693,8 +1900,8 @@ function splitRow(row) {
1693
1900
  }
1694
1901
  return { left: row.trim(), right: "", split: false };
1695
1902
  }
1696
- function rowColumnWidth(text, size, mono) {
1697
- return mono ? displayWidth(text) * size * MONO_ADVANCE_RATIO : textWidth(text, size);
1903
+ function rowColumnWidth(text, size, mono, textMetrics = "proportional") {
1904
+ return mono ? displayWidth(text) * size * MONO_ADVANCE_RATIO : textWidth(text, size, 0, textMetrics);
1698
1905
  }
1699
1906
  function displayWidth(text) {
1700
1907
  let w = 0;
@@ -1720,12 +1927,12 @@ function \u6841\u3067\u7701\u304F(text, \u4E0A\u9650) {
1720
1927
  if (displayWidth(text) <= \u4E0A\u9650) return text;
1721
1928
  return `${\u6841\u3067\u5272\u308B(text, \u4E0A\u9650 - 1)[0]}\u2026`;
1722
1929
  }
1723
- function requiredRowsWidth(rows, kind) {
1930
+ function requiredRowsWidth(rows, kind, textMetrics = "proportional") {
1724
1931
  if (!rows || rows.length === 0) return 0;
1725
1932
  const splits = rows.map(splitRow);
1726
1933
  const \u4E00\u756A\u5E83\u3044 = (\u53D6\u308B) => splits.reduce((m, s) => Math.max(m, \u53D6\u308B(s)), 0);
1727
- const storage = ROW_PAD_X_PX + \u4E00\u756A\u5E83\u3044((s) => rowColumnWidth(s.left, 26, true)) + STORAGE_COL_GAP_PX + \u4E00\u756A\u5E83\u3044((s) => rowColumnWidth(s.right, 26, true)) + ROW_RIGHT_PAD_PX;
1728
- const generic = ROW_PAD_X_PX + \u4E00\u756A\u5E83\u3044((s) => rowColumnWidth(s.left, GENERIC_ROW_LEFT_SIZE_PX, false)) + ROW_COL_GAP_PX + \u4E00\u756A\u5E83\u3044((s) => rowColumnWidth(s.right, GENERIC_ROW_RIGHT_SIZE_PX, true)) + ROW_RIGHT_PAD_PX;
1934
+ const storage = ROW_PAD_X_PX + \u4E00\u756A\u5E83\u3044((s) => rowColumnWidth(s.left, 26, true, textMetrics)) + STORAGE_COL_GAP_PX + \u4E00\u756A\u5E83\u3044((s) => rowColumnWidth(s.right, 26, true, textMetrics)) + ROW_RIGHT_PAD_PX;
1935
+ const generic = ROW_PAD_X_PX + \u4E00\u756A\u5E83\u3044((s) => rowColumnWidth(s.left, GENERIC_ROW_LEFT_SIZE_PX, false, textMetrics)) + ROW_COL_GAP_PX + \u4E00\u756A\u5E83\u3044((s) => rowColumnWidth(s.right, GENERIC_ROW_RIGHT_SIZE_PX, true, textMetrics)) + ROW_RIGHT_PAD_PX;
1729
1936
  if (kind === void 0) return Math.ceil(Math.max(storage, generic));
1730
1937
  return Math.ceil(kind === "storage" ? storage : generic);
1731
1938
  }
@@ -1790,7 +1997,10 @@ var \u5DE6\u53F3\u306E\u4F59\u767D = 8;
1790
1997
  function \u4F7F\u3048\u308B\u5E45(\u7BB1\u306E\u5E45) {
1791
1998
  return \u7BB1\u306E\u5E45 - \u5DE6\u53F3\u306E\u4F59\u767D * 2;
1792
1999
  }
1793
- function \u5E45\u3067\u5207\u308B(text, fontSize, \u4F7F\u3048\u308B\u5E452, \u6E2C\u308B = textWidth) {
2000
+ function \u7BB1\u306E\u5B57\u3092\u6E2C\u308B(textMetrics = "proportional") {
2001
+ return (text, fontSize) => textWidth(text, fontSize, 0, textMetrics);
2002
+ }
2003
+ function \u5E45\u3067\u5207\u308B(text, fontSize, \u4F7F\u3048\u308B\u5E452, \u6E2C\u308B) {
1794
2004
  if (\u4F7F\u3048\u308B\u5E452 <= 0) return "";
1795
2005
  if (\u6E2C\u308B(text, fontSize) <= \u4F7F\u3048\u308B\u5E452) return text;
1796
2006
  const \u7701\u7565 = "\u2026";
@@ -1807,7 +2017,7 @@ function \u5E45\u3067\u5207\u308B(text, fontSize, \u4F7F\u3048\u308B\u5E452, \u6
1807
2017
  return `${\u51FA}${\u7701\u7565}`;
1808
2018
  }
1809
2019
  var \u7E2E\u3081\u306E\u4E0B\u9650 = MIN_TEXT_SIZE;
1810
- function \u5E45\u306B\u53CE\u3081\u308B(text, fontSize, \u4F7F\u3048\u308B\u5E452, \u6E2C\u308B = textWidth) {
2020
+ function \u5E45\u306B\u53CE\u3081\u308B(text, fontSize, \u4F7F\u3048\u308B\u5E452, \u6E2C\u308B) {
1811
2021
  let size = fontSize;
1812
2022
  while (size > \u7E2E\u3081\u306E\u4E0B\u9650 && \u6E2C\u308B(text, size) > \u4F7F\u3048\u308B\u5E452) size -= 1;
1813
2023
  return { text: \u5E45\u3067\u5207\u308B(text, size, \u4F7F\u3048\u308B\u5E452, \u6E2C\u308B), fontSize: size };
@@ -1817,7 +2027,7 @@ function \u66F8\u8A18\u7D20\u306B\u5206\u3051\u308B(text) {
1817
2027
  if (typeof \u533A\u5207\u308A !== "function") return [...text];
1818
2028
  return [...new \u533A\u5207\u308A(void 0, { granularity: "grapheme" }).segment(text)].map((g) => g.segment);
1819
2029
  }
1820
- function \u7BB1\u306B\u7A4D\u3080(\u884C, \u7BB1\u306E\u5E45, \u7BB1\u306E\u9AD8\u30553) {
2030
+ function \u7BB1\u306B\u7A4D\u3080(\u884C, \u7BB1\u306E\u5E45, \u7BB1\u306E\u9AD8\u30553, \u6E2C\u308B) {
1821
2031
  const \u5019\u88DC = \u884C.filter((r, i) => i === 0 || r.text.trim() !== "");
1822
2032
  if (\u5019\u88DC.length === 0) return [];
1823
2033
  const \u4F7F\u3048\u308B\u9AD8\u3055 = \u7BB1\u306E\u9AD8\u30553 - \u4E0A\u4E0B\u306E\u4F59\u767D * 2;
@@ -1825,7 +2035,7 @@ function \u7BB1\u306B\u7A4D\u3080(\u884C, \u7BB1\u306E\u5E45, \u7BB1\u306E\u9AD8
1825
2035
  const \u6B8B\u3059 = [...\u5019\u88DC];
1826
2036
  while (\u6B8B\u3059.length > 1 && \u9AD8\u3055(\u6B8B\u3059) > \u4F7F\u3048\u308B\u9AD8\u3055) \u6B8B\u3059.pop();
1827
2037
  const \u5E45 = \u4F7F\u3048\u308B\u5E45(\u7BB1\u306E\u5E45);
1828
- const \u53CE\u3081\u305F = \u6B8B\u3059.map((r) => ({ ...r, ...\u5E45\u306B\u53CE\u3081\u308B(r.text, r.fontSize, \u5E45) }));
2038
+ const \u53CE\u3081\u305F = \u6B8B\u3059.map((r) => ({ ...r, ...\u5E45\u306B\u53CE\u3081\u308B(r.text, r.fontSize, \u5E45, \u6E2C\u308B) }));
1829
2039
  const \u7DCF\u9AD8 = \u9AD8\u3055(\u53CE\u3081\u305F);
1830
2040
  let \u7A4D\u307F = -\u7DCF\u9AD8 / 2;
1831
2041
  return \u53CE\u3081\u305F.map((r) => {
@@ -2182,7 +2392,15 @@ function useInteractiveIntegration(diagram2, options = {}) {
2182
2392
  f.id
2183
2393
  )) }),
2184
2394
  scrolls.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cdl-ip-group", children: scrolls.map((s) => /* @__PURE__ */ jsxRuntime.jsx(ScrollReadout, { id: s.id, name: s.label || s.id, progress: stateOverrides[s.id] }, s.id)) }),
2185
- readouts.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cdl-ip-group", children: readouts.map((r) => /* @__PURE__ */ jsxRuntime.jsx(ReadoutWidget, { readout: r, stateOverrides: mergedStateValues }, r.id)) })
2395
+ readouts.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cdl-ip-group", children: readouts.map((r) => /* @__PURE__ */ jsxRuntime.jsx(
2396
+ ReadoutWidget,
2397
+ {
2398
+ readout: r,
2399
+ stateOverrides: mergedStateValues,
2400
+ textMetrics: resolveTextMetrics(diagram2.textMetrics)
2401
+ },
2402
+ r.id
2403
+ )) })
2186
2404
  ] }) })
2187
2405
  );
2188
2406
  }, [diagram2, signals, stateOverrides, mergedStateValues]);
@@ -2603,7 +2821,8 @@ function StepperWidget({
2603
2821
  }
2604
2822
  function ReadoutWidget({
2605
2823
  readout,
2606
- stateOverrides
2824
+ stateOverrides,
2825
+ textMetrics = "proportional"
2607
2826
  }) {
2608
2827
  const rawValue = "source" in readout ? stateOverrides[readout.source] : void 0;
2609
2828
  const numericValue = typeof rawValue === "number" ? rawValue : typeof rawValue === "string" ? Number(rawValue) : Number.NaN;
@@ -2851,7 +3070,8 @@ function ReadoutWidget({
2851
3070
  max: readout.max,
2852
3071
  viewW: readout.viewW ?? 280,
2853
3072
  viewH: readout.viewH ?? 60,
2854
- color: readout.color ?? "#2563eb"
3073
+ color: readout.color ?? "#2563eb",
3074
+ textMetrics
2855
3075
  }
2856
3076
  );
2857
3077
  case "radar": {
@@ -3667,7 +3887,8 @@ function ReadoutWidget({
3667
3887
  { status: "idle", color: "#94a3b8" },
3668
3888
  { status: "error", color: "#ef4444" }
3669
3889
  ],
3670
- max: readout.max ?? 10
3890
+ max: readout.max ?? 10,
3891
+ textMetrics
3671
3892
  }
3672
3893
  );
3673
3894
  case "calendar-week":
@@ -4811,8 +5032,8 @@ function ProgressGroupReadout({
4811
5032
  }) })
4812
5033
  ] });
4813
5034
  }
4814
- function sequenceLabelAnchor(x, name, fontSize, viewW) {
4815
- const half = textWidth(name, fontSize) / 2;
5035
+ function sequenceLabelAnchor(x, name, fontSize, viewW, textMetrics = "proportional") {
5036
+ const half = textWidth(name, fontSize, 0, textMetrics) / 2;
4816
5037
  if (x - half < 0) return "start";
4817
5038
  if (x + half > viewW) return "end";
4818
5039
  return "middle";
@@ -4825,7 +5046,8 @@ function SequenceTimelineReadout({
4825
5046
  max,
4826
5047
  viewW,
4827
5048
  viewH,
4828
- color
5049
+ color,
5050
+ textMetrics = "proportional"
4829
5051
  }) {
4830
5052
  const events = [];
4831
5053
  const trimmed = value.trim();
@@ -4868,7 +5090,17 @@ function SequenceTimelineReadout({
4868
5090
  const x = xFor(e.t);
4869
5091
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { "data-cdl-event-marker": e.name, children: [
4870
5092
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x, cy: trackY, r: 5, fill: color, stroke: "#fff", strokeWidth: 1.5, children: /* @__PURE__ */ jsxRuntime.jsx(\u5B57\u306E\u898B\u51FA\u3057, { k: "readout.sequenceTimeline.title", v: { name: e.name, t: e.t } }) }),
4871
- /* @__PURE__ */ jsxRuntime.jsx("text", { x, y: trackY - 12, textAnchor: sequenceLabelAnchor(x, e.name, 10, viewW), fontSize: 10, fill: "var(--v4-ink, #1a1f2a)", children: e.name }),
5093
+ /* @__PURE__ */ jsxRuntime.jsx(
5094
+ "text",
5095
+ {
5096
+ x,
5097
+ y: trackY - 12,
5098
+ textAnchor: sequenceLabelAnchor(x, e.name, 10, viewW, textMetrics),
5099
+ fontSize: 10,
5100
+ fill: "var(--v4-ink, #1a1f2a)",
5101
+ children: e.name
5102
+ }
5103
+ ),
4872
5104
  /* @__PURE__ */ jsxRuntime.jsx("text", { x, y: trackY + 18, textAnchor: "middle", fontSize: 9, fill: "var(--v4-mute, #64748b)", children: e.t })
4873
5105
  ] }, i);
4874
5106
  })
@@ -7945,7 +8177,8 @@ function StatusTimelineReadout({
7945
8177
  label,
7946
8178
  value,
7947
8179
  colorMap,
7948
- max
8180
+ max,
8181
+ textMetrics = "proportional"
7949
8182
  }) {
7950
8183
  const events = [];
7951
8184
  const trimmed = value.trim();
@@ -7970,6 +8203,7 @@ function StatusTimelineReadout({
7970
8203
  const cellW = shown.length > 0 ? (width - 20) / shown.length : 0;
7971
8204
  const height = stripHeight + 40;
7972
8205
  const \u533A\u9593\u306E\u5B57 = (status) => status === "active" || status === "idle" || status === "error" ? \u5F15\u304F(`readout.statusTimeline.${status}`) : status.toUpperCase();
8206
+ const \u6E2C\u308B = \u7BB1\u306E\u5B57\u3092\u6E2C\u308B(textMetrics);
7973
8207
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cdl-ip-item cdl-ip-readout-status-timeline", "data-cdl-readout": id, children: [
7974
8208
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cdl-ip-label", children: label }),
7975
8209
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -7983,7 +8217,7 @@ function StatusTimelineReadout({
7983
8217
  const x = 10 + i * cellW;
7984
8218
  const c = colorLookup.get(ev.status) ?? "#cbd5e1";
7985
8219
  const \u5B572 = \u533A\u9593\u306E\u5B57(ev.status);
7986
- const \u63CF\u304F\u5B57 = \u5E45\u3067\u5207\u308B(\u5B572, 10, cellW - 8);
8220
+ const \u63CF\u304F\u5B57 = \u5E45\u3067\u5207\u308B(\u5B572, 10, cellW - 8, \u6E2C\u308B);
7987
8221
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { "data-cdl-status-event": i, "data-cdl-status": ev.status, children: [
7988
8222
  /* @__PURE__ */ jsxRuntime.jsx("rect", { x, y: 10, width: cellW - 2, height: stripHeight, fill: c, rx: 2 }),
7989
8223
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -12094,6 +12328,8 @@ function diagram(id, options) {
12094
12328
  ...options.palette !== void 0 ? { palette: options.palette } : {},
12095
12329
  // 言語も素通しする。 型の外の値を既定に落とすのは `layout` の 1 箇所に置く
12096
12330
  ...options.lang !== void 0 ? { lang: options.lang } : {},
12331
+ // 字幅の測り方も素通しする。型の外の値を既定に落とすのは `layout` の 1 箇所に置く
12332
+ ...options.textMetrics !== void 0 ? { textMetrics: options.textMetrics } : {},
12097
12333
  // 種類の名前も同じ経路で渡し、空文字の扱いを `layout` の 1 箇所に揃える
12098
12334
  ...options.type !== void 0 ? { type: options.type } : {},
12099
12335
  // inputs / formulas / scrollTriggers / eventBindings は空なら省略 (static diagram の JSON 形状維持)
@@ -12126,196 +12362,6 @@ var ARROW_ANGLE_MAX_DEG = 100;
12126
12362
  var FAN_GAP = 120;
12127
12363
  var DETOUR_GAP = 94;
12128
12364
 
12129
- // src/layout/text-width.ts
12130
- var INTER_BOLD_ADVANCE_EM = {
12131
- // uppercase (実測係数化、 Inter Bold 仕様 × 1.20)
12132
- A: 0.86,
12133
- B: 0.86,
12134
- C: 0.88,
12135
- D: 0.93,
12136
- E: 0.82,
12137
- F: 0.79,
12138
- G: 0.94,
12139
- H: 0.92,
12140
- I: 0.44,
12141
- J: 0.66,
12142
- K: 0.86,
12143
- L: 0.74,
12144
- M: 1.12,
12145
- N: 0.94,
12146
- O: 0.94,
12147
- P: 0.85,
12148
- Q: 0.94,
12149
- R: 0.87,
12150
- S: 0.79,
12151
- T: 0.82,
12152
- U: 0.91,
12153
- V: 0.85,
12154
- W: 1.22,
12155
- X: 0.85,
12156
- Y: 0.82,
12157
- Z: 0.82,
12158
- // lowercase (実測係数化、 Inter Bold 仕様 × 1.22)
12159
- a: 0.73,
12160
- b: 0.77,
12161
- c: 0.68,
12162
- d: 0.77,
12163
- e: 0.73,
12164
- f: 0.51,
12165
- g: 0.76,
12166
- h: 0.77,
12167
- i: 0.39,
12168
- j: 0.41,
12169
- k: 0.73,
12170
- l: 0.39,
12171
- m: 1.15,
12172
- n: 0.77,
12173
- o: 0.76,
12174
- p: 0.77,
12175
- q: 0.77,
12176
- r: 0.54,
12177
- s: 0.65,
12178
- t: 0.54,
12179
- u: 0.77,
12180
- v: 0.71,
12181
- w: 1.05,
12182
- x: 0.71,
12183
- y: 0.71,
12184
- z: 0.66,
12185
- // digits (Inter Bold tabular-nums、 実測係数化 × 1.20)
12186
- "0": 0.72,
12187
- "1": 0.72,
12188
- "2": 0.72,
12189
- "3": 0.72,
12190
- "4": 0.72,
12191
- "5": 0.72,
12192
- "6": 0.72,
12193
- "7": 0.72,
12194
- "8": 0.72,
12195
- "9": 0.72,
12196
- // ascii symbols (実測係数化 × 1.15、 punct 系は kerning が広く効くため 1.20)
12197
- " ": 0.35,
12198
- "!": 0.44,
12199
- '"': 0.59,
12200
- "#": 0.78,
12201
- "$": 0.72,
12202
- "%": 1,
12203
- "&": 0.86,
12204
- "'": 0.32,
12205
- "(": 0.46,
12206
- ")": 0.46,
12207
- "*": 0.63,
12208
- "+": 0.78,
12209
- ",": 0.36,
12210
- "-": 0.5,
12211
- ".": 0.36,
12212
- "/": 0.51,
12213
- ":": 0.36,
12214
- ";": 0.36,
12215
- "<": 0.78,
12216
- "=": 0.78,
12217
- ">": 0.78,
12218
- "?": 0.63,
12219
- "@": 1.17,
12220
- "[": 0.48,
12221
- "\\": 0.51,
12222
- "]": 0.48,
12223
- "^": 0.63,
12224
- "_": 0.63,
12225
- "`": 0.48,
12226
- "{": 0.52,
12227
- "|": 0.37,
12228
- "}": 0.52,
12229
- "~": 0.78
12230
- };
12231
- var JETBRAINS_MONO_ADVANCE_EM = 0.63;
12232
- function isCJK(code) {
12233
- return code >= 12288 && code <= 12543 || // CJK symbols / hiragana / katakana
12234
- code >= 13312 && code <= 40959 || // CJK ideographs
12235
- code >= 63744 && code <= 64255 || // CJK compat ideographs
12236
- code >= 65281 && code <= 65376 || // fullwidth ASCII
12237
- code >= 65504 && code <= 65510;
12238
- }
12239
- function isHalfwidthKana(code) {
12240
- return code >= 65377 && code <= 65500;
12241
- }
12242
- var EMOJI_ADVANCE_EM = 1.05;
12243
- var MONO_EMOJI_ADVANCE_EM = 1.16;
12244
- var DRAWN_CJK_RATIO = 1.08;
12245
- var DRAWN_ASCII_RATIO = 1.16;
12246
- function isAscii(code) {
12247
- return code < 128;
12248
- }
12249
- var WIDE_SYMBOL_ADVANCE_EM = 0.95;
12250
- function isEmoji(code) {
12251
- return code >= 126976 && code <= 129791 || // 絵文字の主要面
12252
- code >= 9728 && code <= 10175 || // 記号と絵文字 (♻ ✅ ❤ 等)
12253
- code >= 127462 && code <= 127487;
12254
- }
12255
- function isEmojiGrapheme(grapheme, firstCode) {
12256
- return isEmoji(firstCode) || grapheme.includes("\uFE0F");
12257
- }
12258
- function isWideSymbol(code) {
12259
- return code >= 8592 && code <= 8703 || // 矢印
12260
- code >= 9472 && code <= 9599 || // 罫線
12261
- code >= 9632 && code <= 9727 || // 幾何図形
12262
- code >= 11008 && code <= 11263;
12263
- }
12264
- var CLUSTER_JOINER_RE = /\u200d|\ufe0f|[\u{1f000}-\u{1faff}]|[\u{2600}-\u{27bf}]/u;
12265
- var \u66F8\u8A18\u7D20\u3067\u5206\u3051\u308B;
12266
- function segmentGraphemes(text) {
12267
- if (typeof Intl === "undefined" || typeof Intl.Segmenter !== "function") {
12268
- return [...text];
12269
- }
12270
- \u66F8\u8A18\u7D20\u3067\u5206\u3051\u308B ??= new Intl.Segmenter(void 0, { granularity: "grapheme" });
12271
- return [...\u66F8\u8A18\u7D20\u3067\u5206\u3051\u308B.segment(text)].map((s) => s.segment);
12272
- }
12273
- function defaultAdvanceEm(ch, code) {
12274
- if (isEmoji(code)) return EMOJI_ADVANCE_EM;
12275
- if (isWideSymbol(code)) return WIDE_SYMBOL_ADVANCE_EM;
12276
- if (isCJK(code)) return 1.08;
12277
- if (isHalfwidthKana(code)) return 0.72;
12278
- if (ch >= "a" && ch <= "z") return 0.73;
12279
- if (ch >= "A" && ch <= "Z") return 0.86;
12280
- if (ch >= "0" && ch <= "9") return 0.72;
12281
- return 0.65;
12282
- }
12283
- function measureTextWidth(text, opts = {}) {
12284
- const fontSize = opts.fontSize ?? 22;
12285
- const letterSpacing = opts.letterSpacing ?? 0;
12286
- const fontFamily = opts.fontFamily ?? "sans";
12287
- const bound = opts.bound ?? "layout";
12288
- let advanceEmSum = 0;
12289
- let charCount = 0;
12290
- const \u6587\u5B57\u5217 = CLUSTER_JOINER_RE.test(text) ? segmentGraphemes(text) : [...text];
12291
- for (const ch of \u6587\u5B57\u5217) {
12292
- charCount++;
12293
- const code = ch.codePointAt(0) ?? 0;
12294
- const \u5272\u308A\u623B\u3057 = bound === "drawn" && !isEmojiGrapheme(ch, code) ? isAscii(code) ? DRAWN_ASCII_RATIO : isCJK(code) ? DRAWN_CJK_RATIO : 1 : 1;
12295
- if (isEmojiGrapheme(ch, code)) {
12296
- advanceEmSum += fontFamily === "mono" ? MONO_EMOJI_ADVANCE_EM : EMOJI_ADVANCE_EM;
12297
- continue;
12298
- }
12299
- if (fontFamily === "mono") {
12300
- advanceEmSum += (isCJK(code) ? 1.08 : JETBRAINS_MONO_ADVANCE_EM) / \u5272\u308A\u623B\u3057;
12301
- continue;
12302
- }
12303
- if (isCJK(code)) {
12304
- advanceEmSum += 1.08 / \u5272\u308A\u623B\u3057;
12305
- continue;
12306
- }
12307
- const table = ch.length === 1 ? INTER_BOLD_ADVANCE_EM[ch] : void 0;
12308
- advanceEmSum += (table !== void 0 ? table : defaultAdvanceEm(ch, code)) / \u5272\u308A\u623B\u3057;
12309
- }
12310
- const w = advanceEmSum * fontSize + letterSpacing * charCount;
12311
- return bound === "drawn" ? w : Math.max(w, fontSize * 1.2);
12312
- }
12313
- function \u53CE\u3081\u308B\u500D\u7387(text, opts, \u5E45) {
12314
- if (!(\u5E45 > 0) || !(opts.fontSize > 0)) return 1;
12315
- const \u5B9F\u5E45 = measureTextWidth(text, { ...opts, letterSpacing: 0 });
12316
- return \u5B9F\u5E45 > \u5E45 ? \u5E45 / \u5B9F\u5E45 : 1;
12317
- }
12318
-
12319
12365
  // src/label-text.ts
12320
12366
  var EDGE_LABEL_TEXT = {
12321
12367
  // main 行は family を指定せず、 host 側の指定を継承する。
@@ -12390,6 +12436,7 @@ var KINDS_DRAWING_TITLE_OUTSIDE = /* @__PURE__ */ new Set([
12390
12436
  "dyn-arc",
12391
12437
  "dyn-wave",
12392
12438
  "dyn-polygon",
12439
+ "station",
12393
12440
  ...KINDS_DRAWING_OWN_PAYLOAD
12394
12441
  ]);
12395
12442
  function drawsTitleOutsideBox(kind) {
@@ -12397,7 +12444,7 @@ function drawsTitleOutsideBox(kind) {
12397
12444
  }
12398
12445
  var TITLE_FONT_SIZE_DEFAULT = 18;
12399
12446
  var TITLE_FONT_SIZE = new Map([
12400
- ...["dyn-rect", "dyn-circle", "dyn-arc", "dyn-wave", "dyn-polygon"].map(
12447
+ ...["dyn-rect", "dyn-circle", "dyn-arc", "dyn-wave", "dyn-polygon", "station"].map(
12401
12448
  (k) => [k, 13]
12402
12449
  ),
12403
12450
  ...[
@@ -12448,6 +12495,10 @@ var TITLE_FONT_SIZE = new Map([
12448
12495
  function titleFontSize(kind) {
12449
12496
  return TITLE_FONT_SIZE.get(kind ?? "") ?? TITLE_FONT_SIZE_DEFAULT;
12450
12497
  }
12498
+ var KINDS_WITH_TITLE_WIDTH_OUTSIDE_NODE = /* @__PURE__ */ new Set(["station"]);
12499
+ function skipsNodeTitleWidthCheck(kind) {
12500
+ return KINDS_WITH_TITLE_WIDTH_OUTSIDE_NODE.has(kind ?? "");
12501
+ }
12451
12502
  var TITLE_BOX_PADDING = 52;
12452
12503
  var KINDS_SCALING_TITLE_WHEN_LOW = /* @__PURE__ */ new Set(["actor", "event", "function", "storage"]);
12453
12504
  var KINDS_SCALING_TITLE_ALWAYS = /* @__PURE__ */ new Set([
@@ -12530,7 +12581,8 @@ var KINDS_DRAWING_ONLY_SHAPE = [
12530
12581
  "dyn-circle",
12531
12582
  "dyn-arc",
12532
12583
  "dyn-wave",
12533
- "dyn-polygon"
12584
+ "dyn-polygon",
12585
+ "station"
12534
12586
  ];
12535
12587
  var KINDS_WITHOUT_EYEBROW_TEXT = /* @__PURE__ */ new Set([
12536
12588
  ...KINDS_DRAWING_ONLY_SHAPE,
@@ -12669,15 +12721,22 @@ function requiredVerticalLabelGap(pillHs) {
12669
12721
  const step = parallelLabelStepY(pillHs);
12670
12722
  return (pillHs.length - 1) * step + Math.max(first, last) + CLEARANCE_NODE_LABEL * 2;
12671
12723
  }
12672
- function computeLabelBoxW(label, sub) {
12673
- const mainW = measureTextWidth(label ?? "", { fontSize: EDGE_LABEL_TEXT.main.fontSize });
12674
- const subW = sub ? measureTextWidth(sub, { fontSize: EDGE_LABEL_TEXT.sub.fontSize, fontFamily: "mono" }) : 0;
12724
+ function computeLabelBoxW(label, sub, textMetrics = "proportional") {
12725
+ const mainW = measureTextWidth(label ?? "", {
12726
+ fontSize: EDGE_LABEL_TEXT.main.fontSize,
12727
+ textMetrics
12728
+ });
12729
+ const subW = sub ? measureTextWidth(sub, {
12730
+ fontSize: EDGE_LABEL_TEXT.sub.fontSize,
12731
+ fontFamily: "mono",
12732
+ textMetrics
12733
+ }) : 0;
12675
12734
  const raw = Math.max(mainW, subW) + LABEL_PILL_PAD_X * 2;
12676
12735
  const EPSILON = 1e-6;
12677
12736
  return Math.ceil((raw - EPSILON) / 2) * 2;
12678
12737
  }
12679
- function computeLabelBBoxWorld(edge) {
12680
- const boxW = computeLabelBoxW(edge.label, edge.sub);
12738
+ function computeLabelBBoxWorld(edge, textMetrics = "proportional") {
12739
+ const boxW = computeLabelBoxW(edge.label, edge.sub, textMetrics);
12681
12740
  const boxH = edge.sub ? LABEL_PILL_H_WITH_SUB : LABEL_PILL_H_MAIN_ONLY;
12682
12741
  const anchor = edge.labelAnchor;
12683
12742
  const boxLeftX = anchor === "start" ? 0 : anchor === "end" ? -boxW : -boxW / 2;
@@ -12916,7 +12975,7 @@ function footerShapeDrawTop(node) {
12916
12975
  // src/layout/collisions.ts
12917
12976
  var LANE_LABEL_CLEARANCE_MARGIN = 2;
12918
12977
  var NEAR_MISS_MARGIN = LANE_LABEL_CLEARANCE_MARGIN;
12919
- function collectBBoxes(lanes, nodes, edges) {
12978
+ function collectBBoxes(lanes, nodes, edges, textMetrics = "proportional") {
12920
12979
  const out = [];
12921
12980
  for (const lane of lanes) {
12922
12981
  if (!lane.label) continue;
@@ -12925,7 +12984,7 @@ function collectBBoxes(lanes, nodes, edges) {
12925
12984
  id: lane.id,
12926
12985
  x: lane.x + 16,
12927
12986
  y: lane.y + 8,
12928
- w: measureTextWidth(lane.label, { fontSize: 20, letterSpacing: 2 }) + 24,
12987
+ w: measureTextWidth(lane.label, { fontSize: 20, letterSpacing: 2, textMetrics }) + 24,
12929
12988
  h: 28
12930
12989
  });
12931
12990
  }
@@ -12943,7 +13002,7 @@ function collectBBoxes(lanes, nodes, edges) {
12943
13002
  }
12944
13003
  for (const e of edges) {
12945
13004
  if (!hasRenderedLabel(e)) continue;
12946
- const bbox = computeLabelBBoxWorld(e);
13005
+ const bbox = computeLabelBBoxWorld(e, textMetrics);
12947
13006
  out.push({
12948
13007
  kind: "edge-label",
12949
13008
  id: e.id,
@@ -13310,13 +13369,13 @@ function detectCollisions(bboxes, edges) {
13310
13369
  }
13311
13370
  function extractPathSegments(d) {
13312
13371
  const segs = [];
13313
- const commandRegex = /([MLCQZmlcqz])([^MLCQZmlcqz]*)/g;
13372
+ const commandRegex = /([MLCQAZmlcqaz])([^MLCQAZmlcqaz]*)/g;
13314
13373
  let cur = { x: 0, y: 0 };
13315
13374
  let m;
13316
13375
  while ((m = commandRegex.exec(d)) !== null) {
13317
13376
  const cmd = m[1];
13318
13377
  const args = (m[2] ?? "").trim().split(/[\s,]+/).filter(Boolean).map(parseFloat);
13319
- const need = cmd === "M" || cmd === "L" ? 2 : cmd === "Q" ? 4 : cmd === "C" ? 6 : 0;
13378
+ const need = cmd === "M" || cmd === "L" ? 2 : cmd === "Q" ? 4 : cmd === "C" ? 6 : cmd === "A" ? 7 : 0;
13320
13379
  if (need > 0 && (args.length < need || !args.slice(0, need).every(Number.isFinite))) continue;
13321
13380
  if (cmd === "M") {
13322
13381
  cur = { x: args[0], y: args[1] };
@@ -13346,6 +13405,10 @@ function extractPathSegments(d) {
13346
13405
  ctrl: [{ x: args[0], y: args[1] }, { x: args[2], y: args[3] }]
13347
13406
  });
13348
13407
  cur = next;
13408
+ } else if (cmd === "A") {
13409
+ const next = { x: args[5], y: args[6] };
13410
+ segs.push({ x1: cur.x, y1: cur.y, x2: next.x, y2: next.y, cmd: "A" });
13411
+ cur = next;
13349
13412
  }
13350
13413
  }
13351
13414
  return segs;
@@ -13637,10 +13700,10 @@ function forEachCandidatePair(bboxes, margin, visit) {
13637
13700
  }
13638
13701
  }
13639
13702
  }
13640
- function resolveEdgeLabelOverlapsWithChain(edges, fixedObstacles, minClearance = 16, maxIter = 20) {
13703
+ function resolveEdgeLabelOverlapsWithChain(edges, fixedObstacles, minClearance = 16, maxIter = 20, textMetrics = "proportional") {
13641
13704
  if (edges.length === 0) return edges;
13642
13705
  const labelBBox = (e, offsetX, offsetY) => {
13643
- const base = computeLabelBBoxWorld(e);
13706
+ const base = computeLabelBBoxWorld(e, textMetrics);
13644
13707
  return {
13645
13708
  kind: "edge-label",
13646
13709
  id: e.id,
@@ -13741,7 +13804,7 @@ function clampShiftMagnitude(shift, maxMagnitude) {
13741
13804
  };
13742
13805
  return { dx: clampAxis(shift.dx), dy: clampAxis(shift.dy) };
13743
13806
  }
13744
- function resolveEdgeLabelOverlapsWithChainAndPropagate(edges, obstacles, minClearance = 16, maxIter = 20, pathLabelClearance = LABEL_TO_PATH_CLEARANCE) {
13807
+ function resolveEdgeLabelOverlapsWithChainAndPropagate(edges, obstacles, minClearance = 16, maxIter = 20, pathLabelClearance = LABEL_TO_PATH_CLEARANCE, textMetrics = "proportional") {
13745
13808
  if (edges.length === 0) {
13746
13809
  return {
13747
13810
  edges,
@@ -13752,7 +13815,7 @@ function resolveEdgeLabelOverlapsWithChainAndPropagate(edges, obstacles, minClea
13752
13815
  }
13753
13816
  const MAX_ACCUMULATED_SHIFT = CHAIN_SHIFT_MAX_ACCUMULATED;
13754
13817
  const labelBBox = (e, offsetX, offsetY) => {
13755
- const base = computeLabelBBoxWorld(e);
13818
+ const base = computeLabelBBoxWorld(e, textMetrics);
13756
13819
  return {
13757
13820
  kind: "edge-label",
13758
13821
  id: e.id,
@@ -14353,11 +14416,15 @@ var \u5411\u304D\u306E\u9806 = [
14353
14416
  { axis: "x", sign: -1, \u540D\u524D: "\u5DE6" },
14354
14417
  { axis: "x", sign: 1, \u540D\u524D: "\u53F3" }
14355
14418
  ];
14356
- function \u672D\u304C\u52D5\u3051\u306A\u3044\u7406\u7531(labelId, \u76F8\u624B, edges, obstacles) {
14419
+ function \u672D\u304C\u52D5\u3051\u306A\u3044\u7406\u7531(labelId, \u76F8\u624B, edges, obstacles, textMetrics = "proportional") {
14357
14420
  const edgeById = new Map(edges.map((e) => [e.id, e]));
14358
14421
  const \u81EA\u5206 = edgeById.get(labelId);
14359
14422
  if (!\u81EA\u5206) return null;
14360
- const labels = edges.filter((e) => e.label?.trim() || e.sub?.trim()).map((e) => ({ kind: "edge-label", id: e.id, ...computeLabelBBoxWorld(e) }));
14423
+ const labels = edges.filter((e) => e.label?.trim() || e.sub?.trim()).map((e) => ({
14424
+ kind: "edge-label",
14425
+ id: e.id,
14426
+ ...computeLabelBBoxWorld(e, textMetrics)
14427
+ }));
14361
14428
  const label = labels.find((l) => l.id === labelId);
14362
14429
  if (!label) return null;
14363
14430
  const \u6E2C\u308A\u65B9 = \u7DDA\u306E\u6E2C\u308A\u65B9\u3092\u4F5C\u308B();
@@ -14399,7 +14466,7 @@ function \u672D\u304C\u52D5\u3051\u306A\u3044\u7406\u7531(labelId, \u76F8\u624B,
14399
14466
  }
14400
14467
  return `\u9003\u3052\u5834\u306A\u3057: ${\u7406\u7531.sort((a, b) => a.\u9806 - b.\u9806).map((r) => r.\u6587).join(" / ")}`;
14401
14468
  }
14402
- function resolveLabelClearanceAfterPathPasses(edges, obstacles, maxIter = 8) {
14469
+ function resolveLabelClearanceAfterPathPasses(edges, obstacles, maxIter = 8, textMetrics = "proportional") {
14403
14470
  if (edges.length === 0) return edges;
14404
14471
  const labeledIds = new Set(
14405
14472
  edges.filter((e) => e.label?.trim() || e.sub?.trim()).map((e) => e.id)
@@ -14417,7 +14484,7 @@ function resolveLabelClearanceAfterPathPasses(edges, obstacles, maxIter = 8) {
14417
14484
  const out = [];
14418
14485
  for (const e of edges) {
14419
14486
  if (!labeledIds.has(e.id)) continue;
14420
- const base = computeLabelBBoxWorld(e);
14487
+ const base = computeLabelBBoxWorld(e, textMetrics);
14421
14488
  const s = getShift(e.id);
14422
14489
  out.push({ kind: "edge-label", id: e.id, x: base.x + s.dx, y: base.y + s.dy, w: base.w, h: base.h });
14423
14490
  }
@@ -14548,6 +14615,232 @@ function applyEdgeLabelAndPathShifts(edges, labelShiftMap, edgePathShiftMap) {
14548
14615
  });
14549
14616
  }
14550
14617
 
14618
+ // src/layout/curve-path.ts
14619
+ var SAME_HEIGHT_THRESHOLD = 1;
14620
+ function curvePath(from, to, edge, labelMarginExtra = 0, textMetrics = "proportional") {
14621
+ const fromLeft = from.cx - from.w / 2;
14622
+ const fromRight = from.cx + from.w / 2;
14623
+ const toLeft = to.cx - to.w / 2;
14624
+ const toRight = to.cx + to.w / 2;
14625
+ let fromSide;
14626
+ let toSide;
14627
+ let x1;
14628
+ let x2;
14629
+ if (toLeft >= fromRight) {
14630
+ fromSide = "right";
14631
+ toSide = "left";
14632
+ x1 = fromRight;
14633
+ x2 = toLeft;
14634
+ } else if (toRight <= fromLeft) {
14635
+ fromSide = "left";
14636
+ toSide = "right";
14637
+ x1 = fromLeft;
14638
+ x2 = toRight;
14639
+ } else {
14640
+ fromSide = "right";
14641
+ toSide = "right";
14642
+ x1 = fromRight;
14643
+ x2 = toRight;
14644
+ }
14645
+ const y1 = from.cy;
14646
+ const y2 = to.cy;
14647
+ const sameHeight = Math.abs(y2 - y1) < SAME_HEIGHT_THRESHOLD;
14648
+ let d;
14649
+ let midX;
14650
+ let midY;
14651
+ let tangentX;
14652
+ let tangentY;
14653
+ if (sameHeight) {
14654
+ d = `M ${x1} ${y1} L ${x2} ${y2}`;
14655
+ midX = (x1 + x2) / 2;
14656
+ midY = (y1 + y2) / 2;
14657
+ tangentX = x2 - x1;
14658
+ tangentY = y2 - y1;
14659
+ } else {
14660
+ let c1x;
14661
+ let c2x;
14662
+ if (fromSide !== toSide) {
14663
+ const direction = x2 > x1 ? 1 : -1;
14664
+ const bulge = Math.max(Math.abs(x2 - x1) / 2, EDGE_STUB_OUT);
14665
+ c1x = x1 + direction * bulge;
14666
+ c2x = x2 - direction * bulge;
14667
+ } else {
14668
+ const bulgeX = Math.max(x1, x2) + EDGE_STUB_OUT;
14669
+ c1x = bulgeX;
14670
+ c2x = bulgeX;
14671
+ }
14672
+ d = `M ${x1} ${y1} C ${c1x} ${y1}, ${c2x} ${y2}, ${x2} ${y2}`;
14673
+ midX = (x1 + 3 * c1x + 3 * c2x + x2) / 8;
14674
+ midY = (y1 + 3 * y1 + 3 * y2 + y2) / 8;
14675
+ tangentX = x2 + c2x - c1x - x1;
14676
+ tangentY = y2 + y2 - y1 - y1;
14677
+ }
14678
+ if (edge?.overlay) {
14679
+ return { d, fromSide, toSide, labelX: midX, labelY: midY, labelAnchor: "middle" };
14680
+ }
14681
+ const tangentLength = Math.hypot(tangentX, tangentY);
14682
+ let normalX = tangentY / tangentLength;
14683
+ let normalY = -tangentX / tangentLength;
14684
+ if (normalY > Number.EPSILON || Math.abs(normalY) <= Number.EPSILON && normalX < 0) {
14685
+ normalX *= -1;
14686
+ normalY *= -1;
14687
+ }
14688
+ const labelW = computeLabelBoxW(edge?.label, edge?.sub, textMetrics);
14689
+ const labelH = labelPillH(edge?.sub);
14690
+ const distance = labelPathClearanceHorizontal(edge) + (Math.abs(normalX) * labelW + Math.abs(normalY) * labelH) / 2 + labelMarginExtra;
14691
+ return {
14692
+ d,
14693
+ fromSide,
14694
+ toSide,
14695
+ labelX: midX + normalX * distance,
14696
+ labelY: midY + normalY * distance,
14697
+ labelAnchor: "middle"
14698
+ };
14699
+ }
14700
+
14701
+ // src/layout/metro-path.ts
14702
+ var METRO_CORNER_RADIUS = 24;
14703
+ var T = Math.SQRT2 - 1;
14704
+ function round2(v) {
14705
+ return Math.round(v * 100) / 100;
14706
+ }
14707
+ function point(p) {
14708
+ return `${round2(p.x)} ${round2(p.y)}`;
14709
+ }
14710
+ function add(p, v, scale) {
14711
+ return { x: p.x + v.x * scale, y: p.y + v.y * scale };
14712
+ }
14713
+ function polyline(points) {
14714
+ const distinct = points.filter((p, i) => {
14715
+ const previous = points[i - 1];
14716
+ return previous === void 0 || p.x !== previous.x || p.y !== previous.y;
14717
+ });
14718
+ return distinct.map((p, i) => `${i === 0 ? "M" : "L"} ${point(p)}`).join(" ");
14719
+ }
14720
+ function metroPath(from, to, edge, labelMarginExtra = 0, textMetrics = "proportional") {
14721
+ const fromLeft = from.cx - from.w / 2;
14722
+ const fromRight = from.cx + from.w / 2;
14723
+ const toLeft = to.cx - to.w / 2;
14724
+ const toRight = to.cx + to.w / 2;
14725
+ let fromSide;
14726
+ let toSide;
14727
+ let x1;
14728
+ let x2;
14729
+ let dir;
14730
+ if (toLeft >= fromRight) {
14731
+ fromSide = "right";
14732
+ toSide = "left";
14733
+ x1 = fromRight;
14734
+ x2 = toLeft;
14735
+ dir = 1;
14736
+ } else if (toRight <= fromLeft) {
14737
+ fromSide = "left";
14738
+ toSide = "right";
14739
+ x1 = fromLeft;
14740
+ x2 = toRight;
14741
+ dir = -1;
14742
+ } else {
14743
+ fromSide = "right";
14744
+ toSide = "right";
14745
+ x1 = fromRight;
14746
+ x2 = toRight;
14747
+ dir = 1;
14748
+ }
14749
+ const y1 = from.cy;
14750
+ const y2 = to.cy;
14751
+ const dy = y2 - y1;
14752
+ const sgn = Math.sign(dy);
14753
+ let d;
14754
+ let mid;
14755
+ let tangent;
14756
+ if (Math.abs(dy) < SAME_HEIGHT_THRESHOLD) {
14757
+ d = `M ${point({ x: x1, y: y1 })} L ${point({ x: x2, y: y2 })}`;
14758
+ mid = { x: (x1 + x2) / 2, y: (y1 + y2) / 2 };
14759
+ tangent = { x: x2 - x1, y: y2 - y1 };
14760
+ } else if (fromSide !== toSide && Math.abs(x2 - x1) >= Math.abs(dy)) {
14761
+ const horizontal = Math.abs(x2 - x1);
14762
+ const s = (horizontal - Math.abs(dy)) / 2;
14763
+ const p0 = { x: x1, y: y1 };
14764
+ const p1 = { x: x1 + dir * s, y: y1 };
14765
+ const p2 = { x: x2 - dir * s, y: y2 };
14766
+ const p3 = { x: x2, y: y2 };
14767
+ const u = { x: dir, y: 0 };
14768
+ const w = { x: dir / Math.SQRT2, y: sgn / Math.SQRT2 };
14769
+ const r = Math.min(
14770
+ METRO_CORNER_RADIUS,
14771
+ s / T,
14772
+ Math.SQRT2 * Math.abs(dy) / (2 * T)
14773
+ );
14774
+ const t = r * T;
14775
+ if (r >= 0.5) {
14776
+ const f1 = dir * sgn > 0 ? 1 : 0;
14777
+ d = [
14778
+ `M ${point(p0)}`,
14779
+ `L ${point(add(p1, u, -t))}`,
14780
+ `A ${round2(r)} ${round2(r)} 0 0 ${f1} ${point(add(p1, w, t))}`,
14781
+ `L ${point(add(p2, w, -t))}`,
14782
+ `A ${round2(r)} ${round2(r)} 0 0 ${1 - f1} ${point(add(p2, u, t))}`,
14783
+ `L ${point(p3)}`
14784
+ ].join(" ");
14785
+ } else {
14786
+ d = polyline([p0, p1, p2, p3]);
14787
+ }
14788
+ mid = { x: (x1 + x2) / 2, y: (y1 + y2) / 2 };
14789
+ tangent = w;
14790
+ } else {
14791
+ fromSide = "right";
14792
+ toSide = "right";
14793
+ x1 = fromRight;
14794
+ x2 = toRight;
14795
+ const xa = Math.max(x1, x2) + EDGE_STUB_OUT;
14796
+ const h = Math.abs(dy) / 2;
14797
+ const p0 = { x: x1, y: y1 };
14798
+ const p1 = { x: xa, y: y1 };
14799
+ const p2 = { x: xa + h, y: y1 + sgn * h };
14800
+ const p3 = { x: xa, y: y2 };
14801
+ const p4 = { x: x2, y: y2 };
14802
+ const u = { x: 1, y: 0 };
14803
+ const w1 = { x: 1 / Math.SQRT2, y: sgn / Math.SQRT2 };
14804
+ const w2 = { x: -1 / Math.SQRT2, y: sgn / Math.SQRT2 };
14805
+ const r = Math.min(METRO_CORNER_RADIUS, h);
14806
+ const t = r * T;
14807
+ const sweep = sgn > 0 ? 1 : 0;
14808
+ d = [
14809
+ `M ${point(p0)}`,
14810
+ `L ${point(add(p1, u, -t))}`,
14811
+ `A ${round2(r)} ${round2(r)} 0 0 ${sweep} ${point(add(p1, w1, t))}`,
14812
+ `L ${point(add(p2, w1, -r))}`,
14813
+ `A ${round2(r)} ${round2(r)} 0 0 ${sweep} ${point(add(p2, w2, r))}`,
14814
+ `L ${point(add(p3, w2, -t))}`,
14815
+ `A ${round2(r)} ${round2(r)} 0 0 ${sweep} ${point(add(p3, u, -t))}`,
14816
+ `L ${point(p4)}`
14817
+ ].join(" ");
14818
+ mid = { x: p2.x - T * r, y: p2.y };
14819
+ tangent = { x: 0, y: sgn };
14820
+ }
14821
+ if (edge?.overlay) {
14822
+ return { d, fromSide, toSide, labelX: mid.x, labelY: mid.y, labelAnchor: "middle" };
14823
+ }
14824
+ const tangentLength = Math.hypot(tangent.x, tangent.y);
14825
+ let normalX = tangent.y / tangentLength;
14826
+ let normalY = -tangent.x / tangentLength;
14827
+ if (normalY > Number.EPSILON || Math.abs(normalY) <= Number.EPSILON && normalX < 0) {
14828
+ normalX *= -1;
14829
+ normalY *= -1;
14830
+ }
14831
+ const labelW = computeLabelBoxW(edge?.label, edge?.sub, textMetrics);
14832
+ const labelH = labelPillH(edge?.sub);
14833
+ const distance = labelPathClearanceHorizontal(edge) + (Math.abs(normalX) * labelW + Math.abs(normalY) * labelH) / 2 + labelMarginExtra;
14834
+ return {
14835
+ d,
14836
+ fromSide,
14837
+ toSide,
14838
+ labelX: mid.x + normalX * distance,
14839
+ labelY: mid.y + normalY * distance,
14840
+ labelAnchor: "middle"
14841
+ };
14842
+ }
14843
+
14551
14844
  // src/types.ts
14552
14845
  var TONES = ["accent", "teal", "success", "error", "warning", "info"];
14553
14846
  var NODE_KINDS = [
@@ -14675,6 +14968,8 @@ var NODE_KINDS = [
14675
14968
  // 状態遷移図が使う。 印そのものが意味を持つので文字は描かない
14676
14969
  "mark-start",
14677
14970
  "mark-end",
14971
+ // 路線図の駅 (#996) ... 線路上の点を小さな丸で示し、名前と説明は丸の外に置く
14972
+ "station",
14678
14973
  // 時系列のやり取り (#578) ... 1 つの箱が図を丸ごと描く。 縦が時間で、参加者は箱を持たない
14679
14974
  "sequence-board"
14680
14975
  ];
@@ -14702,9 +14997,9 @@ function \u66F8\u3044\u305F\u5024\u304B\u63A7\u3048(\u66F8\u3044\u305F, \u63A7\u
14702
14997
  const v = (\u66F8\u3044\u305F ?? "").trim();
14703
14998
  return v === "" ? \u63A7\u3048 : v;
14704
14999
  }
14705
- function \u5E45\u306E\u500D\u7387(text, size, letterSpacing, \u5E45) {
15000
+ function \u5E45\u306E\u500D\u7387(text, size, letterSpacing, \u5E45, textMetrics = "proportional") {
14706
15001
  if (!(\u5E45 > 0) || !(size > 0)) return 1;
14707
- const \u5B9F\u5E45 = textWidth(text, size, letterSpacing);
15002
+ const \u5B9F\u5E45 = textWidth(text, size, letterSpacing, textMetrics);
14708
15003
  return \u5B9F\u5E45 > \u5E45 ? \u5E45 / \u5B9F\u5E45 : 1;
14709
15004
  }
14710
15005
  function \u8AAD\u3081\u308B\u4E0B\u9650\u306E\u500D\u7387(\u5927\u304D\u3055) {
@@ -14919,13 +15214,13 @@ function fitArt(region, extent, art) {
14919
15214
  );
14920
15215
  }
14921
15216
  var \u5E2F\u306E\u9AD8\u3055\u306B\u5BFE\u3059\u308B\u4E0A\u9650 = 0.8;
14922
- function \u7D75\u306E\u4E2D\u306E\u5B57\u306E\u5E45(text, size, letterSpacing = 0) {
15217
+ function \u7D75\u306E\u4E2D\u306E\u5B57\u306E\u5E45(text, size, letterSpacing = 0, textMetrics = "proportional") {
14923
15218
  return Math.max(
14924
15219
  displayWidth(text) * size * MONO_ADVANCE_RATIO,
14925
- textWidth(text, size, letterSpacing)
15220
+ textWidth(text, size, letterSpacing, textMetrics)
14926
15221
  );
14927
15222
  }
14928
- function \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u5B57\u3089) {
15223
+ function \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u5B57\u3089, textMetrics = "proportional") {
14929
15224
  const \u623B\u3057 = Number.isFinite(\u500D\u7387) && \u500D\u7387 > 0 ? 1 / \u500D\u7387 : 1;
14930
15225
  let \u4E0A\u9650 = Number.POSITIVE_INFINITY;
14931
15226
  for (const \u5B572 of \u5B57\u3089) {
@@ -14934,7 +15229,7 @@ function \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u5B57\u3089)
14934
15229
  if (Number.isFinite(\u9AD8\u3055) && \u9AD8\u3055 > 0) {
14935
15230
  \u4E0A\u9650 = Math.min(\u4E0A\u9650, \u9AD8\u3055 * \u5E2F\u306E\u9AD8\u3055\u306B\u5BFE\u3059\u308B\u4E0A\u9650 / \u5B572.size);
14936
15231
  }
14937
- const \u5B9F\u5E45 = \u7D75\u306E\u4E2D\u306E\u5B57\u306E\u5E45(\u5B572.text, \u5B572.size, \u5B572.letterSpacing ?? 0);
15232
+ const \u5B9F\u5E45 = \u7D75\u306E\u4E2D\u306E\u5B57\u306E\u5E45(\u5B572.text, \u5B572.size, \u5B572.letterSpacing ?? 0, textMetrics);
14938
15233
  if (Number.isFinite(\u5E45) && \u5E45 > 0 && \u5B9F\u5E45 > 0) {
14939
15234
  \u4E0A\u9650 = Math.min(\u4E0A\u9650, \u5E45 / \u5B9F\u5E45);
14940
15235
  }
@@ -15790,9 +16085,14 @@ function \u6728\u306E\u5F62(treeNodes) {
15790
16085
  return { \u8449\u306E\u6570, \u6BB5\u6570 };
15791
16086
  }
15792
16087
  var \u6728\u306E\u679D\u306E\u592A\u3055 = (\u6BB5) => Math.max(1.1, 2.6 - \u6BB5 * 0.45);
15793
- function \u6728\u306E\u4E2D\u8EAB(node, stateValues = {}) {
16088
+ function \u6728\u306E\u4E2D\u8EAB(node, stateValues = {}, textMetrics = "proportional") {
15794
16089
  const treeNodes = resolveTreeData(node.treeData ?? [], stateValues);
15795
- return computeTreeLayout(treeNodes, node.w - PAD_LEFT - PAD_RIGHT, node.h - PAD_TOP - PAD_BOTTOM);
16090
+ return computeTreeLayout(
16091
+ treeNodes,
16092
+ node.w - PAD_LEFT - PAD_RIGHT,
16093
+ node.h - PAD_TOP - PAD_BOTTOM,
16094
+ textMetrics
16095
+ );
15796
16096
  }
15797
16097
  function \u6728\u306E\u884C(n) {
15798
16098
  return [
@@ -15805,12 +16105,14 @@ function TreeNode({
15805
16105
  active,
15806
16106
  stateValues = {},
15807
16107
  drawing = false,
15808
- progress = 1
16108
+ progress = 1,
16109
+ textMetrics = "proportional"
15809
16110
  }) {
15810
16111
  const x0 = node.cx - node.w / 2;
15811
16112
  const y0 = node.cy - node.h / 2;
15812
16113
  const gradientId = `tree-root-grad-${node.id}`;
15813
- const layout2 = \u6728\u306E\u4E2D\u8EAB(node, stateValues);
16114
+ const layout2 = \u6728\u306E\u4E2D\u8EAB(node, stateValues, textMetrics);
16115
+ const \u6E2C\u308B = \u7BB1\u306E\u5B57\u3092\u6E2C\u308B(textMetrics);
15814
16116
  const \u4F38\u3073 = \u9032\u307F\u3092\u7573\u3080(drawing, progress);
15815
16117
  const \u6700\u5927\u6DF1\u3055 = layout2.nodes.reduce((m, n) => Math.max(m, n.depth), 0);
15816
16118
  const \u7BB1\u304C\u51FA\u308B = (\u6DF1\u3055) => !drawing || \u6BB5\u306E\u4F38\u3073(\u4F38\u3073, \u6DF1\u3055, \u6700\u5927\u6DF1\u3055) >= 1;
@@ -15864,10 +16166,10 @@ function TreeNode({
15864
16166
  const accent = depthColors[Math.min(n.depth, depthColors.length - 1)] ?? depthColors[0];
15865
16167
  const isRoot = n.depth === 0;
15866
16168
  const \u6750\u6599 = \u6728\u306E\u884C(n);
15867
- const \u884C = \u7BB1\u306B\u7A4D\u3080(\u6750\u6599, n.w, n.h);
16169
+ const \u884C = \u7BB1\u306B\u7A4D\u3080(\u6750\u6599, n.w, n.h, \u6E2C\u308B);
15868
16170
  const \u88DC\u8DB3\u3042\u308A = (n.subtitle ?? "").trim() !== "";
15869
16171
  const \u540D\u524D = \u6750\u6599[0];
15870
- 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));
16172
+ 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), \u6E2C\u308B);
15871
16173
  return /* @__PURE__ */ jsxRuntime.jsx(
15872
16174
  "g",
15873
16175
  {
@@ -15949,7 +16251,7 @@ function TreeNode({
15949
16251
  })
15950
16252
  ] });
15951
16253
  }
15952
- function computeTreeLayout(treeNodes, canvasW, canvasH) {
16254
+ function computeTreeLayout(treeNodes, canvasW, canvasH, textMetrics = "proportional") {
15953
16255
  const ids = new Set(treeNodes.map((n) => n.id));
15954
16256
  const childrenOf = /* @__PURE__ */ new Map();
15955
16257
  for (const n of treeNodes) {
@@ -15997,7 +16299,7 @@ function computeTreeLayout(treeNodes, canvasW, canvasH) {
15997
16299
  const \u7BB1\u306E\u5E45 = (n, depth) => {
15998
16300
  const \u6750\u6599 = \u6728\u306E\u884C({ ...n, depth });
15999
16301
  const \u540D\u524D = \u6750\u6599[0];
16000
- const \u8981\u308B = measureTextWidth(\u540D\u524D.text, { fontSize: \u540D\u524D.fontSize}) + (nodeW - \u4F7F\u3048\u308B\u5E45(nodeW));
16302
+ const \u8981\u308B = measureTextWidth(\u540D\u524D.text, { fontSize: \u540D\u524D.fontSize, textMetrics }) + (nodeW - \u4F7F\u3048\u308B\u5E45(nodeW));
16001
16303
  return Math.min(Math.max(\u8981\u308B, nodeW), slotW * 0.92);
16002
16304
  };
16003
16305
  const \u8449\u306E\u4E26\u3073 = [];
@@ -16101,7 +16403,7 @@ var BRANCH_BOX_H_MAX = 48;
16101
16403
  var SUB_BOX_H_MAX = 40;
16102
16404
  var \u7E26\u306E\u9593\u9694\u306E\u4E0A\u9650 = (\u679D\u306E\u6A2A\u306E\u4F38\u3073) => \u679D\u306E\u6A2A\u306E\u4F38\u3073;
16103
16405
  var MIND_PAD = 40;
16104
- function \u653E\u5C04\u306E\u4E2D\u8EAB(node, stateValues = {}) {
16406
+ function \u653E\u5C04\u306E\u4E2D\u8EAB(node, stateValues = {}, textMetrics = "proportional") {
16105
16407
  const mindData = node.mindData ? resolveMindData(node.mindData, stateValues) : void 0;
16106
16408
  if (!mindData) return void 0;
16107
16409
  return computeMindMapLayout(
@@ -16109,7 +16411,8 @@ function \u653E\u5C04\u306E\u4E2D\u8EAB(node, stateValues = {}) {
16109
16411
  node.w / 2,
16110
16412
  node.h / 2,
16111
16413
  node.w - MIND_PAD * 2,
16112
- node.h - MIND_PAD * 2
16414
+ node.h - MIND_PAD * 2,
16415
+ textMetrics
16113
16416
  );
16114
16417
  }
16115
16418
  function \u653E\u5C04\u306E\u884C(n) {
@@ -16123,12 +16426,14 @@ function MindMapNode({
16123
16426
  active,
16124
16427
  stateValues = {},
16125
16428
  drawing = false,
16126
- progress = 1
16429
+ progress = 1,
16430
+ textMetrics = "proportional"
16127
16431
  }) {
16128
16432
  const x0 = node.cx - node.w / 2;
16129
16433
  const y0 = node.cy - node.h / 2;
16130
- const layout2 = \u653E\u5C04\u306E\u4E2D\u8EAB(node, stateValues);
16434
+ const layout2 = \u653E\u5C04\u306E\u4E2D\u8EAB(node, stateValues, textMetrics);
16131
16435
  if (!layout2) return /* @__PURE__ */ jsxRuntime.jsx("g", { transform: `translate(${x0} ${y0})` });
16436
+ const \u6E2C\u308B = \u7BB1\u306E\u5B57\u3092\u6E2C\u308B(textMetrics);
16132
16437
  const \u4F38\u3073 = \u9032\u307F\u3092\u7573\u3080(drawing, progress);
16133
16438
  const \u6700\u5927\u6DF1\u3055 = layout2.nodes.reduce((m, n) => Math.max(m, n.depth), 0);
16134
16439
  const \u7BB1\u304C\u51FA\u308B = (\u6DF1\u3055) => !drawing || \u6BB5\u306E\u4F38\u3073(\u4F38\u3073, \u6DF1\u3055, \u6700\u5927\u6DF1\u3055) >= 1;
@@ -16175,8 +16480,13 @@ function MindMapNode({
16175
16480
  const \u6587\u5B57\u306E\u5BC4\u305B = \u67A0\u306A\u3057 ? \u5916\u3078 ? "start" : "end" : "middle";
16176
16481
  const \u63CF\u753B\u57DF\u306E\u7AEF = \u5916\u3078 ? node.w - MIND_PAD : MIND_PAD;
16177
16482
  const \u4F7F\u3048\u308B = \u67A0\u306A\u3057 ? Math.abs(\u63CF\u753B\u57DF\u306E\u7AEF - \u6587\u5B57\u306Ex) : \u4F7F\u3048\u308B\u5E45(n.w);
16178
- 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);
16179
- 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);
16483
+ 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, \u6E2C\u308B);
16484
+ const \u884C = \u7BB1\u306B\u7A4D\u3080(
16485
+ \u6750\u6599,
16486
+ \u67A0\u306A\u3057 ? \u4F7F\u3048\u308B + (n.w - \u4F7F\u3048\u308B\u5E45(n.w)) : n.w,
16487
+ n.h,
16488
+ \u6E2C\u308B
16489
+ );
16180
16490
  const \u6587\u5B57\u306E\u8272 = n.isRoot ? "var(--cdl-text-on-tone, #ffffff)" : "var(--cdl-chip-text, #1a1f2a)";
16181
16491
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { "data-cdl-unresolved": n.unresolved ? "true" : void 0, children: [
16182
16492
  \u67A0\u306A\u3057 ? null : /* @__PURE__ */ jsxRuntime.jsx(
@@ -16228,14 +16538,14 @@ function MindMapNode({
16228
16538
  })
16229
16539
  ] });
16230
16540
  }
16231
- function \u63CF\u304F\u6A2A\u306E\u7AEF(n) {
16541
+ function \u63CF\u304F\u6A2A\u306E\u7AEF(n, textMetrics = "proportional") {
16232
16542
  if (n.isRoot || !n.isLeaf) return [n.x - n.w / 2, n.x + n.w / 2];
16233
16543
  const \u8D77\u70B9 = n.x + (n.side === "right" ? -n.w / 2 : n.w / 2);
16234
16544
  const \u540D\u524D = \u653E\u5C04\u306E\u884C(n)[0];
16235
- const \u5E45 = textWidth(\u540D\u524D.text, \u540D\u524D.fontSize);
16545
+ const \u5E45 = textWidth(\u540D\u524D.text, \u540D\u524D.fontSize, 0, textMetrics);
16236
16546
  return n.side === "right" ? [\u8D77\u70B9, \u8D77\u70B9 + \u5E45] : [\u8D77\u70B9 - \u5E45, \u8D77\u70B9];
16237
16547
  }
16238
- function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
16548
+ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH, textMetrics = "proportional") {
16239
16549
  const nodes = [];
16240
16550
  const edges = [];
16241
16551
  const rootW = 120;
@@ -16313,7 +16623,7 @@ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
16313
16623
  const PREFERRED_GAP = MIND_BOX_GAP;
16314
16624
  const \u679D\u306E\u540D\u524D\u306E\u5E45 = (title) => {
16315
16625
  const \u540D\u524D = \u653E\u5C04\u306E\u884C({ title, isRoot: false })[0];
16316
- return textWidth(\u540D\u524D.text, \u540D\u524D.fontSize);
16626
+ return textWidth(\u540D\u524D.text, \u540D\u524D.fontSize, 0, textMetrics);
16317
16627
  };
16318
16628
  const \u679D\u306E\u6A2A\u3092\u6C7A\u3081\u308B = (br) => {
16319
16629
  const maxSubDepth = subDepthOf(br.id, /* @__PURE__ */ new Set());
@@ -16431,7 +16741,7 @@ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
16431
16741
  let maxExtentX = rootW / 2;
16432
16742
  let maxExtentY = rootH / 2;
16433
16743
  for (const n of nodes) {
16434
- const [\u5DE6, \u53F3] = \u63CF\u304F\u6A2A\u306E\u7AEF(n);
16744
+ const [\u5DE6, \u53F3] = \u63CF\u304F\u6A2A\u306E\u7AEF(n, textMetrics);
16435
16745
  maxExtentX = Math.max(maxExtentX, Math.abs(\u5DE6 - cx), Math.abs(\u53F3 - cx));
16436
16746
  maxExtentY = Math.max(maxExtentY, Math.abs(n.y - cy) + n.h / 2);
16437
16747
  }
@@ -16451,7 +16761,7 @@ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
16451
16761
  let \u5DE6\u7AEF = Number.POSITIVE_INFINITY;
16452
16762
  let \u53F3\u7AEF = Number.NEGATIVE_INFINITY;
16453
16763
  for (const n of nodes) {
16454
- const [l, r] = \u63CF\u304F\u6A2A\u306E\u7AEF(n);
16764
+ const [l, r] = \u63CF\u304F\u6A2A\u306E\u7AEF(n, textMetrics);
16455
16765
  \u5DE6\u7AEF = Math.min(\u5DE6\u7AEF, l);
16456
16766
  \u53F3\u7AEF = Math.max(\u53F3\u7AEF, r);
16457
16767
  }
@@ -16694,10 +17004,16 @@ function emptyCounts() {
16694
17004
  "validation-interrupted": 0
16695
17005
  };
16696
17006
  }
16697
- function \u7A4D\u3080\u7BB1\u3092\u96C6\u3081\u308B(n) {
16698
- const \u7BB1 = (b, \u884C) => ({ \u884C, w: b.w, h: b.h });
16699
- if (n.kind === "tree-hierarchy") return \u6728\u306E\u4E2D\u8EAB(n).nodes.map((b) => \u7BB1(b, \u6728\u306E\u884C(b)));
16700
- if (n.kind === "mind-map") return (\u653E\u5C04\u306E\u4E2D\u8EAB(n)?.nodes ?? []).map((b) => \u7BB1(b, \u653E\u5C04\u306E\u884C(b)));
17007
+ function \u7A4D\u3080\u7BB1\u3092\u96C6\u3081\u308B(n, textMetrics = "proportional") {
17008
+ const \u7BB1 = (b, \u884C, \u6E2C\u308B) => ({ \u884C, w: b.w, h: b.h, \u6E2C\u308B });
17009
+ if (n.kind === "tree-hierarchy") {
17010
+ const \u6E2C\u308B = \u7BB1\u306E\u5B57\u3092\u6E2C\u308B(textMetrics);
17011
+ return \u6728\u306E\u4E2D\u8EAB(n, {}, textMetrics).nodes.map((b) => \u7BB1(b, \u6728\u306E\u884C(b), \u6E2C\u308B));
17012
+ }
17013
+ if (n.kind === "mind-map") {
17014
+ const \u6E2C\u308B = \u7BB1\u306E\u5B57\u3092\u6E2C\u308B(textMetrics);
17015
+ return (\u653E\u5C04\u306E\u4E2D\u8EAB(n, {}, textMetrics)?.nodes ?? []).map((b) => \u7BB1(b, \u653E\u5C04\u306E\u884C(b), \u6E2C\u308B));
17016
+ }
16701
17017
  return [];
16702
17018
  }
16703
17019
  function measureStubOut(segs) {
@@ -17383,9 +17699,11 @@ function \u4F4D\u7F6E\u3092\u624B\u3067\u66F8\u3044\u305F(n) {
17383
17699
  return n.posX !== void 0 && n.posY !== void 0;
17384
17700
  }
17385
17701
  function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5668) {
17702
+ const textMetrics = laid.textMetrics ?? "proportional";
17386
17703
  const LIFELINE_W_THRESHOLD = 8;
17387
17704
  for (const n of laid.nodes) {
17388
17705
  if (n.w < LIFELINE_W_THRESHOLD) continue;
17706
+ if (n.kind === "station") continue;
17389
17707
  if (n.w < MIN_NODE_W || n.h < MIN_NODE_H) {
17390
17708
  push(
17391
17709
  "node-visibility",
@@ -17393,7 +17711,7 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5
17393
17711
  );
17394
17712
  }
17395
17713
  }
17396
- const bboxes = collectBBoxes(laid.lanes, laid.nodes, laid.edges);
17714
+ const bboxes = collectBBoxes(laid.lanes, laid.nodes, laid.edges, textMetrics);
17397
17715
  const collisions = detectCollisions(bboxes, laid.edges);
17398
17716
  for (const c of collisions) {
17399
17717
  const involvesEdgeLabel = c.a.kind === "edge-label" || c.b.kind === "edge-label";
@@ -17407,12 +17725,17 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5
17407
17725
  if (n.id.endsWith("-spacer")) continue;
17408
17726
  if (!rendersTitleText(n.kind)) continue;
17409
17727
  if (fitsOwnTitleWidth(n.kind)) continue;
17728
+ if (skipsNodeTitleWidthCheck(n.kind)) continue;
17410
17729
  if (!isRenderedNode(n)) continue;
17411
17730
  const titleTrimmed = n.title?.trim() ?? "";
17412
17731
  if (!titleTrimmed) continue;
17413
17732
  const \u4F59\u767D = drawsTitleOutsideBox(n.kind) ? 0 : TITLE_BOX_PADDING;
17414
17733
  const \u4F7F\u3048\u308B\u5E452 = n.w - \u4F59\u767D;
17415
- const \u5B9F\u5E45 = measureTextWidth(titleTrimmed, { fontSize: titleFontSize(n.kind), bound: "drawn" });
17734
+ const \u5B9F\u5E45 = measureTextWidth(titleTrimmed, {
17735
+ fontSize: titleFontSize(n.kind),
17736
+ bound: "drawn",
17737
+ textMetrics
17738
+ });
17416
17739
  if (titleScalesToFit(n.kind, n.h)) {
17417
17740
  const \u7E2E\u3081\u305F\u5927\u304D\u3055 = \u5B9F\u5E45 > 0 ? titleFontSize(n.kind) * Math.min(1, \u4F7F\u3048\u308B\u5E452 / \u5B9F\u5E45) : titleFontSize(n.kind);
17418
17741
  if (\u7E2E\u3081\u305F\u5927\u304D\u3055 < MIN_TITLE_FONT_SIZE) {
@@ -17480,7 +17803,13 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5
17480
17803
  const b\u306F\u672D = n.b.kind === "edge-label";
17481
17804
  const \u52D5\u304B\u3059 = a\u306F\u672D && b\u306F\u672D ? (\u8FBA\u306E\u9806.get(n.a.id) ?? 0) > (\u8FBA\u306E\u9806.get(n.b.id) ?? 0) ? n.a : n.b : a\u306F\u672D ? n.a : b\u306F\u672D ? n.b : null;
17482
17805
  const \u76F8\u624B = \u52D5\u304B\u3059 === n.a ? n.b : n.a;
17483
- const reason = \u52D5\u304B\u3059 !== null ? \u672D\u304C\u52D5\u3051\u306A\u3044\u7406\u7531(\u52D5\u304B\u3059.id, \u76F8\u624B, laid.edges, \u672D\u306E\u969C\u5BB3\u7269) ?? void 0 : void 0;
17806
+ const reason = \u52D5\u304B\u3059 !== null ? \u672D\u304C\u52D5\u3051\u306A\u3044\u7406\u7531(
17807
+ \u52D5\u304B\u3059.id,
17808
+ \u76F8\u624B,
17809
+ laid.edges,
17810
+ \u672D\u306E\u969C\u5BB3\u7269,
17811
+ textMetrics
17812
+ ) ?? void 0 : void 0;
17484
17813
  push(
17485
17814
  "clearance",
17486
17815
  `${n.a.kind}:${n.a.id} \u2194 ${n.b.kind}:${n.b.id} gap=${n.gap.toFixed(1)}px (need ${n.required}px)`,
@@ -17494,7 +17823,10 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5
17494
17823
  if (!hasRenderedLabel(e)) continue;
17495
17824
  const segs = extractPathSegments(e.d);
17496
17825
  if (segs.length === 0) continue;
17497
- const minDist = measurePathLabelGapSegs(flattenPathSegments(segs), computeLabelBBoxWorld(e));
17826
+ const minDist = measurePathLabelGapSegs(
17827
+ flattenPathSegments(segs),
17828
+ computeLabelBBoxWorld(e, textMetrics)
17829
+ );
17498
17830
  if (!Number.isFinite(minDist)) continue;
17499
17831
  if (minDist > PROXIMITY_ERROR_THRESHOLD) {
17500
17832
  push(
@@ -17544,8 +17876,15 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5
17544
17876
  }
17545
17877
  for (const e of laid.edges) {
17546
17878
  if (!hasRenderedLabel(e)) continue;
17547
- const mainW = measureTextWidth(e.label ?? "", { fontSize: EDGE_LABEL_TEXT.main.fontSize });
17548
- const subW = e.sub ? measureTextWidth(e.sub, { fontSize: EDGE_LABEL_TEXT.sub.fontSize, fontFamily: "mono" }) : 0;
17879
+ const mainW = measureTextWidth(e.label ?? "", {
17880
+ fontSize: EDGE_LABEL_TEXT.main.fontSize,
17881
+ textMetrics
17882
+ });
17883
+ const subW = e.sub ? measureTextWidth(e.sub, {
17884
+ fontSize: EDGE_LABEL_TEXT.sub.fontSize,
17885
+ fontFamily: "mono",
17886
+ textMetrics
17887
+ }) : 0;
17549
17888
  const expectedBoxW = Math.max(mainW, subW) + LABEL_PILL_PAD_X * 2;
17550
17889
  const bbox = bboxes.find((b) => b.kind === "edge-label" && b.id === e.id);
17551
17890
  if (!bbox) continue;
@@ -17687,7 +18026,9 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5
17687
18026
  }
17688
18027
  }
17689
18028
  for (const n of laid.nodes) {
17690
- const \u843D\u3068\u3057\u305F = labelPlan(n).\u843D\u3068\u3057\u305F.filter((line) => droppedLineIsHidden(n.kind, line));
18029
+ const \u843D\u3068\u3057\u305F = labelPlan(n).\u843D\u3068\u3057\u305F.filter(
18030
+ (line) => droppedLineIsHidden(n.kind, line)
18031
+ );
17691
18032
  if (\u843D\u3068\u3057\u305F.length === 0) continue;
17692
18033
  push(
17693
18034
  "shape-label-dropped",
@@ -17696,7 +18037,7 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5
17696
18037
  );
17697
18038
  }
17698
18039
  for (const n of laid.nodes) {
17699
- const \u7BB1 = \u7A4D\u3080\u7BB1\u3092\u96C6\u3081\u308B(n);
18040
+ const \u7BB1 = \u7A4D\u3080\u7BB1\u3092\u96C6\u3081\u308B(n, textMetrics);
17700
18041
  if (\u7BB1.length === 0) continue;
17701
18042
  let \u5BFE\u8C61 = 0;
17702
18043
  const \u843D\u3061\u305F = [];
@@ -17704,7 +18045,7 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5
17704
18045
  const \u5BA3\u8A00 = b.\u884C.slice(1).filter((r) => r.text.trim() !== "");
17705
18046
  if (\u5BA3\u8A00.length === 0) continue;
17706
18047
  \u5BFE\u8C61 += 1;
17707
- const \u6B8B\u3063\u305F = new Set(\u7BB1\u306B\u7A4D\u3080(b.\u884C, b.w, b.h).map((r) => r.\u5F79\u5272));
18048
+ const \u6B8B\u3063\u305F = new Set(\u7BB1\u306B\u7A4D\u3080(b.\u884C, b.w, b.h, b.\u6E2C\u308B).map((r) => r.\u5F79\u5272));
17708
18049
  if (\u5BA3\u8A00.every((r) => \u6B8B\u3063\u305F.has(r.\u5F79\u5272))) continue;
17709
18050
  \u843D\u3061\u305F.push({ title: b.\u884C[0]?.text ?? "", h: b.h });
17710
18051
  }
@@ -18011,6 +18352,9 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5
18011
18352
  for (let i = 0; i + 1 < sorted.length; i++) {
18012
18353
  const upper = sorted[i];
18013
18354
  const lower = sorted[i + 1];
18355
+ if (upper.cx + upper.w / 2 <= lower.cx - lower.w / 2 || lower.cx + lower.w / 2 <= upper.cx - upper.w / 2) {
18356
+ continue;
18357
+ }
18014
18358
  const upperBottom = upper.cy + upper.h / 2;
18015
18359
  const lowerTop = lower.cy - lower.h / 2;
18016
18360
  const gap = lowerTop - upperBottom;
@@ -18642,11 +18986,18 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5
18642
18986
  {
18643
18987
  const crestSpans = (segs, peakY) => {
18644
18988
  const out = [];
18989
+ let \u5186\u5F27\u306E\u59CB\u70B9 = null;
18645
18990
  for (const s of segs) {
18646
- if (Math.abs(s.y1 - s.y2) > 1) continue;
18647
- if (Math.abs(s.y1 - peakY) > 1) continue;
18991
+ if (s.cmd === "A") {
18992
+ \u5186\u5F27\u306E\u59CB\u70B9 ??= { x: s.x1, y: s.y1 };
18993
+ continue;
18994
+ }
18995
+ const \u59CB\u70B9 = \u5186\u5F27\u306E\u59CB\u70B9 ?? { x: s.x1, y: s.y1 };
18996
+ \u5186\u5F27\u306E\u59CB\u70B9 = null;
18997
+ if (Math.abs(\u59CB\u70B9.y - s.y2) > 1) continue;
18998
+ if (Math.abs(\u59CB\u70B9.y - peakY) > 1) continue;
18648
18999
  if (s.cmd !== "L" && !(s.ctrl ?? []).every((c) => Math.abs(c.y - peakY) <= 1)) continue;
18649
- out.push({ minX: Math.min(s.x1, s.x2), maxX: Math.max(s.x1, s.x2) });
19000
+ out.push({ minX: Math.min(\u59CB\u70B9.x, s.x2), maxX: Math.max(\u59CB\u70B9.x, s.x2) });
18650
19001
  }
18651
19002
  return out;
18652
19003
  };
@@ -18757,7 +19108,7 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5
18757
19108
  const allowedLanes = /* @__PURE__ */ new Set();
18758
19109
  if (fromNode) allowedLanes.add(fromNode.lane);
18759
19110
  if (toNode) allowedLanes.add(toNode.lane);
18760
- const box = computeLabelBBoxWorld(e);
19111
+ const box = computeLabelBBoxWorld(e, textMetrics);
18761
19112
  for (const lane of laid.lanes) {
18762
19113
  if (allowedLanes.has(lane.id)) continue;
18763
19114
  const side = rectCrossesLaneBorder(box, lane, rangeByLane.get(lane.id));
@@ -19135,7 +19486,7 @@ function pickFreeSides(occupied, count) {
19135
19486
  const \u4F7F\u3046 = \u7A7A\u304D.length > 0 ? \u7A7A\u304D : [SELF_LOOP_SIDE_FALLBACK];
19136
19487
  return Array.from({ length: count }, (_, i) => \u4F7F\u3046[i % \u4F7F\u3046.length]);
19137
19488
  }
19138
- function routeSelfLoopGroup(edges, node, side) {
19489
+ function routeSelfLoopGroup(edges, node, side, textMetrics = "proportional") {
19139
19490
  const horizontal = side === "left" || side === "right";
19140
19491
  const g = sideGeometry(node, side);
19141
19492
  const span = fitSpan(horizontal ? node.h : node.w, SELF_LOOP_SPAN);
@@ -19144,7 +19495,7 @@ function routeSelfLoopGroup(edges, node, side) {
19144
19495
  const \u6700\u5916 = controlOffset(SELF_LOOP_OUT + (edges.length - 1) * SELF_LOOP_STAGGER);
19145
19496
  const \u8A9E\u307E\u3067 = \u6700\u5916 + LABEL_TO_PATH_CLEARANCE;
19146
19497
  const \u8A9E\u5E45 = edges.map(
19147
- (e) => horizontal ? labelPillH(e.sub) : computeLabelBoxW(e.label, e.sub)
19498
+ (e) => horizontal ? labelPillH(e.sub) : computeLabelBoxW(e.label, e.sub, textMetrics)
19148
19499
  );
19149
19500
  const \u4F4D\u7F6E = [];
19150
19501
  let \u7A4D = 0;
@@ -19174,7 +19525,7 @@ function routeSelfLoopGroup(edges, node, side) {
19174
19525
  function isSelfLoop(e) {
19175
19526
  return e.from === e.to;
19176
19527
  }
19177
- function layoutSelfLoops(edges, nodes, occupiedBySide) {
19528
+ function layoutSelfLoops(edges, nodes, occupiedBySide, textMetrics = "proportional") {
19178
19529
  const \u5272\u5F53 = /* @__PURE__ */ new Map();
19179
19530
  for (const edge of edges) {
19180
19531
  if (edge.side) continue;
@@ -19201,7 +19552,7 @@ function layoutSelfLoops(edges, nodes, occupiedBySide) {
19201
19552
  if (\u65E2) \u65E2.edges.push(edge);
19202
19553
  else \u675F.set(key, { node, side, edges: [edge] });
19203
19554
  }
19204
- return [...\u675F.values()].flatMap((b) => routeSelfLoopGroup(b.edges, b.node, b.side));
19555
+ return [...\u675F.values()].flatMap((b) => routeSelfLoopGroup(b.edges, b.node, b.side, textMetrics));
19205
19556
  }
19206
19557
 
19207
19558
  // src/layout/tokens.ts
@@ -19337,6 +19688,8 @@ var TOKENS = {
19337
19688
  // 箱としての最小 (80x40) より大きく、名前を持つ箱 (card 320x150) よりは明らかに小さい
19338
19689
  "mark-start": { w: 96, h: 96 },
19339
19690
  "mark-end": { w: 96, h: 96 },
19691
+ // 路線図の駅 (#996) ... 正方形にして小さな丸が縦横どちらにも歪まないようにする。
19692
+ station: { w: 24, h: 24 },
19340
19693
  // 時系列のやり取り (#578)。 実寸は中身から決まる (`sequenceBoardMetrics`) ので、
19341
19694
  // ここは書かなかった時の受け皿
19342
19695
  "sequence-board": { w: 960, h: 640 }
@@ -19361,6 +19714,7 @@ var LANE_PAD_MIN = 25;
19361
19714
  // src/layout/edges.ts
19362
19715
  var VERTICAL_DETOUR_GAP = 50;
19363
19716
  var VERTICAL_DETOUR_CORNER = 14;
19717
+ var OVERLAY_LABEL_ON_PATH_TOLERANCE = 1;
19364
19718
  function verticalCornerDir(from, to) {
19365
19719
  return to < from ? -1 : 1;
19366
19720
  }
@@ -19416,7 +19770,7 @@ function verticalDetourBlockers(A, B, obstacles) {
19416
19770
  function detourColumnFor(blockers, side) {
19417
19771
  return side === "left" ? Math.min(...blockers.map((n) => n.cx - n.w / 2)) - VERTICAL_DETOUR_GAP : Math.max(...blockers.map((n) => n.cx + n.w / 2)) + VERTICAL_DETOUR_GAP;
19418
19772
  }
19419
- function layoutEdges(diag, nodes, lanes = []) {
19773
+ function layoutEdges(diag, nodes, lanes = [], textMetrics = "proportional") {
19420
19774
  const labelMarginExtra = (diag.viewport?.labelMargin ?? diag.viewport?.gap ?? DEFAULT_LABEL_MARGIN) - DEFAULT_LABEL_MARGIN;
19421
19775
  const nmap = new Map(nodes.map((n) => [n.id, n]));
19422
19776
  const lmap = new Map(lanes.map((l) => [l.id, l]));
@@ -19444,6 +19798,36 @@ function layoutEdges(diag, nodes, lanes = []) {
19444
19798
  });
19445
19799
  } else if (isSelfLoop(e)) {
19446
19800
  selfLoopEdges.push(e);
19801
+ } else if (e.routing === "curve") {
19802
+ const from = nmap.get(e.from);
19803
+ const to = nmap.get(e.to);
19804
+ if (!from) throw new Error(`cdl layout: edge "${e.id}" \u306E from "${e.from}" \u304C node \u306B\u7121\u3044`);
19805
+ if (!to) throw new Error(`cdl layout: edge "${e.id}" \u306E to "${e.to}" \u304C node \u306B\u7121\u3044`);
19806
+ const c = curvePath(from, to, e, labelMarginExtra, textMetrics);
19807
+ positionedEdges.push({
19808
+ ...e,
19809
+ d: c.d,
19810
+ fromSide: c.fromSide,
19811
+ toSide: c.toSide,
19812
+ labelX: c.labelX + (e.labelOffsetX ?? 0),
19813
+ labelY: c.labelY + (e.labelOffsetY ?? 0),
19814
+ labelAnchor: c.labelAnchor
19815
+ });
19816
+ } else if (e.routing === "metro") {
19817
+ const from = nmap.get(e.from);
19818
+ const to = nmap.get(e.to);
19819
+ if (!from) throw new Error(`cdl layout: edge "${e.id}" \u306E from "${e.from}" \u304C node \u306B\u7121\u3044`);
19820
+ if (!to) throw new Error(`cdl layout: edge "${e.id}" \u306E to "${e.to}" \u304C node \u306B\u7121\u3044`);
19821
+ const m = metroPath(from, to, e, labelMarginExtra, textMetrics);
19822
+ positionedEdges.push({
19823
+ ...e,
19824
+ d: m.d,
19825
+ fromSide: m.fromSide,
19826
+ toSide: m.toSide,
19827
+ labelX: m.labelX + (e.labelOffsetX ?? 0),
19828
+ labelY: m.labelY + (e.labelOffsetY ?? 0),
19829
+ labelAnchor: m.labelAnchor
19830
+ });
19447
19831
  } else {
19448
19832
  autoEdges.push(e);
19449
19833
  }
@@ -19482,7 +19866,7 @@ function layoutEdges(diag, nodes, lanes = []) {
19482
19866
  \u4F7F\u3046(le.from, le.fromSide);
19483
19867
  \u4F7F\u3046(le.to, le.toSide);
19484
19868
  }
19485
- const loopEdges = layoutSelfLoops(selfLoopEdges, nmap, occupiedBySide);
19869
+ const loopEdges = layoutSelfLoops(selfLoopEdges, nmap, occupiedBySide, textMetrics);
19486
19870
  const labelOffsetsByEdgeId = /* @__PURE__ */ new Map();
19487
19871
  const parallelKey = (p) => p.e.from < p.e.to ? `${p.e.from}::${p.e.to}` : `${p.e.to}::${p.e.from}`;
19488
19872
  const byParallel = /* @__PURE__ */ new Map();
@@ -19636,7 +20020,7 @@ function layoutEdges(diag, nodes, lanes = []) {
19636
20020
  const others = nodes.filter((n) => n.id !== c.from && n.id !== c.to);
19637
20021
  if (others.some((n) => segmentsCrossRect(segs, nodeRect(n)))) return true;
19638
20022
  if (!hasRenderedLabel(c.e)) return false;
19639
- const boxW = computeLabelBoxW(c.e.label, c.e.sub);
20023
+ const boxW = computeLabelBoxW(c.e.label, c.e.sub, textMetrics);
19640
20024
  const boxH = labelPillH(c.e.sub);
19641
20025
  const centerX = columnX - (labelPathClearanceHorizontal(c.e) + boxW / 2);
19642
20026
  const pill = { x: centerX - boxW / 2, y: (exitY + returnY) / 2 - boxH / 2, w: boxW, h: boxH };
@@ -19751,7 +20135,8 @@ function layoutEdges(diag, nodes, lanes = []) {
19751
20135
  allOtherNodes,
19752
20136
  { x: endpointOffset.fromDx, y: endpointOffset.fromDy },
19753
20137
  { x: endpointOffset.toDx, y: endpointOffset.toDy },
19754
- avoidRects
20138
+ avoidRects,
20139
+ textMetrics
19755
20140
  );
19756
20141
  const routed1 = route([]);
19757
20142
  const { d, labelX, labelY, labelAnchor, labelAltX } = routed1;
@@ -19807,13 +20192,13 @@ function layoutEdges(diag, nodes, lanes = []) {
19807
20192
  const pillById = /* @__PURE__ */ new Map();
19808
20193
  for (const r of list) {
19809
20194
  if (!hasRenderedLabel(r.e)) continue;
19810
- const w = computeLabelBoxW(r.e.label, r.e.sub);
20195
+ const w = computeLabelBoxW(r.e.label, r.e.sub, textMetrics);
19811
20196
  const h = labelPillH(r.e.sub);
19812
20197
  pillById.set(r.e.id, { x: r.baseLabelX - w / 2, y: r.baseLabelY - h / 2, w, h });
19813
20198
  }
19814
20199
  for (const le of positionedEdges) {
19815
20200
  if (!hasRenderedLabel(le)) continue;
19816
- const w = computeLabelBoxW(le.label, le.sub);
20201
+ const w = computeLabelBoxW(le.label, le.sub, textMetrics);
19817
20202
  const h = labelPillH(le.sub);
19818
20203
  pillById.set(le.id, { x: le.labelX - w / 2, y: le.labelY - h / 2, w, h });
19819
20204
  }
@@ -19843,7 +20228,7 @@ function layoutEdges(diag, nodes, lanes = []) {
19843
20228
  const laneOfNode = new Map(nodes.map((n) => [n.id, n.lane]));
19844
20229
  for (const r of flippable) {
19845
20230
  const ownSegs = segsByEdgeId.get(r.e.id);
19846
- const boxW = computeLabelBoxW(r.e.label, r.e.sub);
20231
+ const boxW = computeLabelBoxW(r.e.label, r.e.sub, textMetrics);
19847
20232
  const boxH = labelPillH(r.e.sub);
19848
20233
  const pillAt = (centerX) => ({
19849
20234
  x: centerX - boxW / 2,
@@ -19888,7 +20273,7 @@ function layoutEdges(diag, nodes, lanes = []) {
19888
20273
  if (list.length < 2) continue;
19889
20274
  const boxes = list.map((r) => ({
19890
20275
  cx: r.baseLabelX,
19891
- halfW: computeLabelBoxW(r.e.label, r.e.sub) / 2
20276
+ halfW: computeLabelBoxW(r.e.label, r.e.sub, textMetrics) / 2
19892
20277
  }));
19893
20278
  const overlapsX = (i, j) => Math.abs(boxes[i].cx - boxes[j].cx) < boxes[i].halfW + boxes[j].halfW + CLEARANCE_LABEL_LABEL;
19894
20279
  const componentOf = list.map((_, i) => i);
@@ -19938,7 +20323,7 @@ function layoutEdges(diag, nodes, lanes = []) {
19938
20323
  r,
19939
20324
  baseX: r.baseLabelX,
19940
20325
  baseY: r.baseLabelY,
19941
- w: computeLabelBoxW(r.e.label, r.e.sub),
20326
+ w: computeLabelBoxW(r.e.label, r.e.sub, textMetrics),
19942
20327
  h: labelPillH(r.e.sub)
19943
20328
  }));
19944
20329
  items.sort((a, b) => a.baseX - b.baseX);
@@ -20050,7 +20435,7 @@ function singleStraightSegment(d) {
20050
20435
  if (x1 === x2 && y1 === y2) return null;
20051
20436
  return { x1, y1, x2, y2 };
20052
20437
  }
20053
- function bowSharedStraightPaths(edges, nodes, skipIds) {
20438
+ function bowSharedStraightPaths(edges, nodes, skipIds, textMetrics = "proportional") {
20054
20439
  const groups = /* @__PURE__ */ new Map();
20055
20440
  for (const e of edges) {
20056
20441
  if (skipIds.has(e.id)) continue;
@@ -20086,7 +20471,7 @@ function bowSharedStraightPaths(edges, nodes, skipIds) {
20086
20471
  )
20087
20472
  );
20088
20473
  const groupIds = new Set(group.map((g) => g.e.id));
20089
- const labelRects = edges.filter((x) => hasRenderedLabel(x) && !groupIds.has(x.id)).map((x) => computeLabelBBoxWorld(x));
20474
+ const labelRects = edges.filter((x) => hasRenderedLabel(x) && !groupIds.has(x.id)).map((x) => computeLabelBBoxWorld(x, textMetrics));
20090
20475
  const nodeRects = nodes.map((n) => ({ x: n.cx - n.w / 2, y: n.cy - n.h / 2, w: n.w, h: n.h }));
20091
20476
  const build = (seg, offset) => {
20092
20477
  const cx = midX + nx * offset * 2;
@@ -20206,8 +20591,8 @@ function sidePoint(n, side) {
20206
20591
  return { x: n.cx + n.w / 2, y: n.cy };
20207
20592
  }
20208
20593
  }
20209
- function routePath(from, to, fromSide, toSide, obstacles = [], detourSide, _fromLane, _toLane, edge, labelObstacles = obstacles, fromOffset = { x: 0, y: 0 }, toOffset = { x: 0, y: 0 }, avoidRects = []) {
20210
- const labelBoxW = edge ? computeLabelBoxW(edge.label, edge.sub) : 0;
20594
+ function routePath(from, to, fromSide, toSide, obstacles = [], detourSide, _fromLane, _toLane, edge, labelObstacles = obstacles, fromOffset = { x: 0, y: 0 }, toOffset = { x: 0, y: 0 }, avoidRects = [], textMetrics = "proportional") {
20595
+ const labelBoxW = edge ? computeLabelBoxW(edge.label, edge.sub, textMetrics) : 0;
20211
20596
  const labelHalfW = labelBoxW / 2;
20212
20597
  const labelInit = labelInitClearance(edge);
20213
20598
  const verticalPair = fromSide === "bottom" && toSide === "top" || fromSide === "top" && toSide === "bottom";
@@ -20606,7 +20991,7 @@ function routePath(from, to, fromSide, toSide, obstacles = [], detourSide, _from
20606
20991
  labelAnchor: "middle"
20607
20992
  };
20608
20993
  }
20609
- function repositionParallelLabels(edges, nodes) {
20994
+ function repositionParallelLabels(edges, nodes, textMetrics = "proportional") {
20610
20995
  const allSegs = new Map(
20611
20996
  edges.map((e) => [e.id, flattenPathSegments(extractPathSegments(e.d))])
20612
20997
  );
@@ -20631,7 +21016,7 @@ function repositionParallelLabels(edges, nodes) {
20631
21016
  for (const pair of byPair.values()) {
20632
21017
  if (pair.length < 2) continue;
20633
21018
  const pairOrder = [...pair].sort(compareSharedPairOrder);
20634
- const boxes = pair.map((e) => computeLabelBBoxWorld(e));
21019
+ const boxes = pair.map((e) => computeLabelBBoxWorld(e, textMetrics));
20635
21020
  const componentOf = pair.map((_, i) => i);
20636
21021
  for (let i = 0; i < pair.length; i++) {
20637
21022
  for (let j = i + 1; j < pair.length; j++) {
@@ -20656,17 +21041,27 @@ function repositionParallelLabels(edges, nodes) {
20656
21041
  nodes,
20657
21042
  allEdges: edges,
20658
21043
  allSegs,
20659
- xRange
21044
+ xRange,
21045
+ textMetrics
20660
21046
  });
20661
21047
  for (let i = 0; i < members.length; i++) members[i].labelY = placed[i];
20662
21048
  }
20663
21049
  }
20664
21050
  }
20665
21051
  function placeAvoidingSiblingPaths(args) {
20666
- const { members, pair, pairOrder, nodes, allEdges, allSegs, xRange } = args;
21052
+ const {
21053
+ members,
21054
+ pair,
21055
+ pairOrder,
21056
+ nodes,
21057
+ allEdges,
21058
+ allSegs,
21059
+ xRange,
21060
+ textMetrics = "proportional"
21061
+ } = args;
20667
21062
  const sizes = members.map((e) => labelPillH(e.sub));
20668
21063
  const wants = members.map((e) => e.labelY);
20669
- const boxes = members.map((e) => computeLabelBBoxWorld(e));
21064
+ const boxes = members.map((e) => computeLabelBBoxWorld(e, textMetrics));
20670
21065
  const all = members.map((_, i) => i);
20671
21066
  const spread = (idx) => spreadWithMinimalShift(
20672
21067
  idx.map((i) => ({ want: wants[i], size: sizes[i] })),
@@ -20857,14 +21252,14 @@ function labelRectAt(cx, cy, w, h) {
20857
21252
  function inflate(r, pad) {
20858
21253
  return { x: r.x - pad, y: r.y - pad, w: r.w + pad * 2, h: r.h + pad * 2 };
20859
21254
  }
20860
- function slideLabelsAlongOwnPath(edges, nodes) {
21255
+ function slideLabelsAlongOwnPath(edges, nodes, textMetrics = "proportional") {
20861
21256
  const withLabel = edges.filter((e) => hasRenderedLabel(e));
20862
21257
  if (withLabel.length === 0) return;
20863
21258
  const segsById = /* @__PURE__ */ new Map();
20864
21259
  for (const e of edges) segsById.set(e.id, flattenPathSegments(extractPathSegments(e.d)));
20865
21260
  const nodeRects = nodes.map(nodeRect);
20866
21261
  for (const e of withLabel) {
20867
- const w = computeLabelBoxW(e.label, e.sub);
21262
+ const w = computeLabelBoxW(e.label, e.sub, textMetrics);
20868
21263
  const h = labelPillH(e.sub);
20869
21264
  if (w === 0 || h === 0) continue;
20870
21265
  const own = segsById.get(e.id) ?? [];
@@ -20948,9 +21343,11 @@ function hopEdgeCrossings(edges) {
20948
21343
  ends.set(e.id, pathEnds(segs));
20949
21344
  }
20950
21345
  for (const e of edges) {
21346
+ if (e.routing === "metro") continue;
20951
21347
  if ((e.d.match(/M/g) ?? []).length !== 1) continue;
20952
21348
  const own = extractPathSegments(e.d);
20953
21349
  if (own.length === 0) continue;
21350
+ if (own.some((s) => s.cmd === "A")) continue;
20954
21351
  const myEnds = ends.get(e.id) ?? [];
20955
21352
  const hops = /* @__PURE__ */ new Map();
20956
21353
  for (let i = 0; i < own.length; i++) {
@@ -21038,7 +21435,7 @@ function pathVertices(d) {
21038
21435
  const out = [{ x: first.x1, y: first.y1 }];
21039
21436
  for (let i = 0; i < segs.length; i++) {
21040
21437
  const s = segs[i];
21041
- if (s.cmd === "C") return null;
21438
+ if (s.cmd === "C" || s.cmd === "A") return null;
21042
21439
  if (s.cmd === "Q") {
21043
21440
  const c = s.ctrl?.[0];
21044
21441
  if (!c) return null;
@@ -21101,7 +21498,7 @@ function separateSharedStraightRuns(edges, nodes) {
21101
21498
  const v = pathVertices(e.d);
21102
21499
  if (v && v.length >= 2) verts.set(e.id, v);
21103
21500
  }
21104
- if (verts.size < 2) return;
21501
+ if (verts.size === 0) return;
21105
21502
  const moved = /* @__PURE__ */ new Set();
21106
21503
  const fits = (e, pts, k, ax, delta) => {
21107
21504
  const \u8A66\u3057 = pts.map(
@@ -21119,33 +21516,40 @@ function separateSharedStraightRuns(edges, nodes) {
21119
21516
  for (let j = i + 1; j < edges.length; j++) {
21120
21517
  const \u524D = edges[i];
21121
21518
  const \u5F8C = edges[j];
21122
- const A = verts.get(\u524D.id);
21123
- const B = verts.get(\u5F8C.id);
21124
- if (!A || !B) continue;
21125
- if (\u524D.from === \u5F8C.from) continue;
21519
+ if (\u524D.routing === "metro" && \u5F8C.routing === "metro") continue;
21520
+ const \u56FA\u5B9A = \u5F8C.routing === "metro" ? \u5F8C : \u524D;
21521
+ const \u52D5\u304B\u3059 = \u5F8C.routing === "metro" ? \u524D : \u5F8C;
21522
+ const B = verts.get(\u52D5\u304B\u3059.id);
21523
+ if (!B) continue;
21524
+ const \u56FA\u5B9A\u306E\u89D2 = verts.get(\u56FA\u5B9A.id);
21525
+ const \u56FA\u5B9A\u306E\u7D4C\u8DEF = \u56FA\u5B9A\u306E\u89D2 ? [\u56FA\u5B9A\u306E\u89D2] : \u56FA\u5B9A.routing === "metro" ? extractPathSegments(\u56FA\u5B9A.d).filter((s) => s.cmd === "L").map((s) => [{ x: s.x1, y: s.y1 }, { x: s.x2, y: s.y2 }]) : [];
21526
+ if (\u56FA\u5B9A\u306E\u7D4C\u8DEF.length === 0) continue;
21527
+ if (\u56FA\u5B9A.from === \u52D5\u304B\u3059.from) continue;
21126
21528
  for (const ax of [0, 1]) {
21127
- for (let ka = 0; ka + 1 < A.length; ka++) {
21128
- if (!runIsAligned(A, ka, ax)) continue;
21129
- for (let kb = 0; kb + 1 < B.length; kb++) {
21130
- if (!runIsAligned(B, kb, ax)) continue;
21131
- if (kb === 0 || kb + 1 === B.length - 1) continue;
21132
- const \u5EA7\u6A19A = ax === 0 ? A[ka].x : A[ka].y;
21133
- const \u5EA7\u6A19B = ax === 0 ? B[kb].x : B[kb].y;
21134
- if (Math.abs(\u5EA7\u6A19A - \u5EA7\u6A19B) > SHARED_RUN_EPS) continue;
21135
- const sa = runSpan(A, ka, ax);
21136
- const sb = runSpan(B, kb, ax);
21137
- if (Math.min(sa.hi, sb.hi) - Math.max(sa.lo, sb.lo) < SHARED_RUN_MIN) continue;
21138
- for (const delta of [SHARED_RUN_SEPARATION, -SHARED_RUN_SEPARATION]) {
21139
- if (!fits(\u5F8C, B, kb, ax, delta)) continue;
21140
- if (ax === 0) {
21141
- B[kb].x += delta;
21142
- B[kb + 1].x += delta;
21143
- } else {
21144
- B[kb].y += delta;
21145
- B[kb + 1].y += delta;
21529
+ for (const A of \u56FA\u5B9A\u306E\u7D4C\u8DEF) {
21530
+ for (let ka = 0; ka + 1 < A.length; ka++) {
21531
+ if (!runIsAligned(A, ka, ax)) continue;
21532
+ for (let kb = 0; kb + 1 < B.length; kb++) {
21533
+ if (!runIsAligned(B, kb, ax)) continue;
21534
+ if (kb === 0 || kb + 1 === B.length - 1) continue;
21535
+ const \u5EA7\u6A19A = ax === 0 ? A[ka].x : A[ka].y;
21536
+ const \u5EA7\u6A19B = ax === 0 ? B[kb].x : B[kb].y;
21537
+ if (Math.abs(\u5EA7\u6A19A - \u5EA7\u6A19B) > SHARED_RUN_EPS) continue;
21538
+ const sa = runSpan(A, ka, ax);
21539
+ const sb = runSpan(B, kb, ax);
21540
+ if (Math.min(sa.hi, sb.hi) - Math.max(sa.lo, sb.lo) < SHARED_RUN_MIN) continue;
21541
+ for (const delta of [SHARED_RUN_SEPARATION, -SHARED_RUN_SEPARATION]) {
21542
+ if (!fits(\u52D5\u304B\u3059, B, kb, ax, delta)) continue;
21543
+ if (ax === 0) {
21544
+ B[kb].x += delta;
21545
+ B[kb + 1].x += delta;
21546
+ } else {
21547
+ B[kb].y += delta;
21548
+ B[kb + 1].y += delta;
21549
+ }
21550
+ moved.add(\u52D5\u304B\u3059.id);
21551
+ break;
21146
21552
  }
21147
- moved.add(\u5F8C.id);
21148
- break;
21149
21553
  }
21150
21554
  }
21151
21555
  }
@@ -21157,7 +21561,7 @@ function separateSharedStraightRuns(edges, nodes) {
21157
21561
  e.d = verticesToPath(verts.get(e.id));
21158
21562
  }
21159
21563
  }
21160
- function pullOutgoingFirstCorner(edges, nodes) {
21564
+ function pullOutgoingFirstCorner(edges, nodes, textMetrics = "proportional") {
21161
21565
  if (edges.length < 2) return;
21162
21566
  const \u675F = /* @__PURE__ */ new Map();
21163
21567
  const \u540C\u3058\u7D44\u306E\u6570 = /* @__PURE__ */ new Map();
@@ -21172,12 +21576,19 @@ function pullOutgoingFirstCorner(edges, nodes) {
21172
21576
  let \u672D\u3092\u65E7\u7D4C\u8DEF\u3078\u8FFD\u5F93\u6E08\u307F = false;
21173
21577
  for (const list of \u675F.values()) {
21174
21578
  if (list.length < 2) continue;
21175
- const \u4E26\u3073 = list.flatMap((e) => {
21579
+ const \u4E26\u3073 = list.map((e) => {
21176
21580
  const pts = pathVertices(e.d);
21177
- if (!pts || pts.length < 2) return [];
21178
- return [{ e, pts, \u6700\u521D\u306E\u9577\u3055: Math.hypot(pts[1].x - pts[0].x, pts[1].y - pts[0].y) }];
21179
- }).sort((a, b) => b.\u6700\u521D\u306E\u9577\u3055 - a.\u6700\u521D\u306E\u9577\u3055);
21581
+ if (pts && pts.length >= 2) {
21582
+ return { e, pts, \u6700\u521D\u306E\u9577\u3055: Math.hypot(pts[1].x - pts[0].x, pts[1].y - pts[0].y) };
21583
+ }
21584
+ if (e.routing !== "metro") return null;
21585
+ const first = extractPathSegments(e.d)[0];
21586
+ if (!first) return null;
21587
+ return { e, pts: null, \u6700\u521D\u306E\u9577\u3055: Math.hypot(first.x2 - first.x1, first.y2 - first.y1) };
21588
+ }).filter((x) => x !== null).sort((a, b) => b.\u6700\u521D\u306E\u9577\u3055 - a.\u6700\u521D\u306E\u9577\u3055);
21180
21589
  for (const { e, pts, \u6700\u521D\u306E\u9577\u3055 } of \u4E26\u3073.slice(1)) {
21590
+ if (e.routing === "metro") continue;
21591
+ if (!pts) continue;
21181
21592
  if ((\u540C\u3058\u7D44\u306E\u6570.get(`${e.from}->${e.to}`) ?? 0) > 1) continue;
21182
21593
  if (pts.length < 3 || \u6700\u521D\u306E\u9577\u3055 <= EDGE_STUB_OUT + VERTICAL_DETOUR_CORNER) continue;
21183
21594
  const \u6A2A = e.fromSide === "left" || e.fromSide === "right";
@@ -21204,10 +21615,10 @@ function pullOutgoingFirstCorner(edges, nodes) {
21204
21615
  }
21205
21616
  e.d = \u524D;
21206
21617
  if (!\u672D\u3092\u65E7\u7D4C\u8DEF\u3078\u8FFD\u5F93\u6E08\u307F) {
21207
- slideLabelsAlongOwnPath(edges, nodes);
21618
+ slideLabelsAlongOwnPath(edges, nodes, textMetrics);
21208
21619
  \u672D\u3092\u65E7\u7D4C\u8DEF\u3078\u8FFD\u5F93\u6E08\u307F = true;
21209
21620
  }
21210
- const labelBox = computeLabelBBoxWorld(e);
21621
+ const labelBox = computeLabelBBoxWorld(e, textMetrics);
21211
21622
  const label = { x: labelBox.x + labelBox.w / 2, y: labelBox.y + labelBox.h / 2 };
21212
21623
  const \u7DDA\u5206\u307E\u3067\u306E\u8DDD\u96E22 = (a, b) => {
21213
21624
  const dx = b.x - a.x;
@@ -21231,7 +21642,8 @@ var ENDPOINT_FAN_MIN = 20;
21231
21642
  var ENDPOINT_FAN_RUNUP = 40;
21232
21643
  var MIXED_ROOT_OVERLAP_MIN = 24;
21233
21644
  function fanIncomingEndpoints(edges, nodes) {
21234
- if (edges.length < 2) return;
21645
+ const \u7D42\u70B9\u306E\u79FB\u52D5 = /* @__PURE__ */ new Map();
21646
+ if (edges.length < 2) return \u7D42\u70B9\u306E\u79FB\u52D5;
21235
21647
  const nmap = new Map(nodes.map((n) => [n.id, n]));
21236
21648
  const \u5E73\u5766\u306A\u533A\u9593 = new Map(edges.map((e) => [e.id, flattenPathSegments(extractPathSegments(e.d))]));
21237
21649
  const \u8EF8\u306B\u5E73\u884C\u306A\u91CD\u306A\u308A\u9577\u3055 = (\u4E00\u65B9, \u4ED6\u65B9) => {
@@ -21301,6 +21713,7 @@ function fanIncomingEndpoints(edges, nodes) {
21301
21713
  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;
21302
21714
  if (Math.abs(d) < 1e-3) continue;
21303
21715
  const e = \u4E26\u3073[k].e;
21716
+ if (e.routing === "metro") continue;
21304
21717
  const \u524D = e.d;
21305
21718
  const \u524D\u306E\u4EA4\u5DEE = countEdgeCrossings(edges).count;
21306
21719
  const \u9577\u3044\u52A9\u8D70 = \u4E26\u3073[k].\u9577\u3044\u52A9\u8D70;
@@ -21312,6 +21725,72 @@ function fanIncomingEndpoints(edges, nodes) {
21312
21725
  if (countEdgeCrossings(edges).count <= \u524D\u306E\u4EA4\u5DEE) break;
21313
21726
  e.d = \u524D;
21314
21727
  }
21728
+ if (e.d !== \u524D) \u7D42\u70B9\u306E\u79FB\u52D5.set(e.id, \u6A2A ? { dx: 0, dy: d } : { dx: d, dy: 0 });
21729
+ }
21730
+ }
21731
+ return \u7D42\u70B9\u306E\u79FB\u52D5;
21732
+ }
21733
+ function followLabelsToFannedTails(edges, obstacles, shifts, textMetrics = "proportional") {
21734
+ if (shifts.size === 0) return;
21735
+ const \u6E2C\u308A\u65B9 = \u7DDA\u306E\u6E2C\u308A\u65B9\u3092\u4F5C\u308B();
21736
+ const labels = edges.filter(hasRenderedLabel).map((e) => ({
21737
+ kind: "edge-label",
21738
+ id: e.id,
21739
+ ...computeLabelBBoxWorld(e, textMetrics)
21740
+ }));
21741
+ const labelIndexByEdgeId = new Map(labels.map((label, index) => [label.id, index]));
21742
+ const edgeById = new Map(edges.map((e) => [e.id, e]));
21743
+ const \u5468\u308A = {
21744
+ \u7BB1\u305F\u3061: obstacles.filter((o) => o.kind === "node" || o.kind === "lane-label"),
21745
+ labels,
21746
+ edges,
21747
+ edgeById,
21748
+ \u6E2C\u308A\u65B9
21749
+ };
21750
+ for (const e of edges) {
21751
+ const \u79FB\u52D5 = shifts.get(e.id);
21752
+ if (!\u79FB\u52D5 || !hasRenderedLabel(e)) continue;
21753
+ const labelIndex = labelIndexByEdgeId.get(e.id);
21754
+ if (labelIndex === void 0) continue;
21755
+ const \u5143\u306E\u672D = labels[labelIndex];
21756
+ const \u81EA\u5206\u306E\u533A\u9593 = \u6E2C\u308A\u65B9.\u533A\u9593(e.id, e.d);
21757
+ if (e.overlay && measurePathLabelGapSegs(\u81EA\u5206\u306E\u533A\u9593, {
21758
+ x: \u5143\u306E\u672D.x + \u5143\u306E\u672D.w / 2,
21759
+ y: \u5143\u306E\u672D.y + \u5143\u306E\u672D.h / 2,
21760
+ w: 0,
21761
+ h: 0
21762
+ }) <= OVERLAY_LABEL_ON_PATH_TOLERANCE) continue;
21763
+ const \u6700\u5F8C = \u81EA\u5206\u306E\u533A\u9593.at(-1);
21764
+ if (!\u6700\u5F8C) continue;
21765
+ if (!segmentsCrossRect([\u6700\u5F8C], \u5143\u306E\u672D)) continue;
21766
+ const \u5019\u88DCa = {
21767
+ labelX: e.labelX + \u79FB\u52D5.dx,
21768
+ labelY: e.labelY + \u79FB\u52D5.dy,
21769
+ labelAnchor: e.labelAnchor
21770
+ };
21771
+ const \u5019\u88DCa\u306E\u7BB1 = computeLabelBBoxWorld({ ...e, ...\u5019\u88DCa }, textMetrics);
21772
+ const \u6700\u5F8C\u306F\u7E26 = Math.abs(\u6700\u5F8C.x2 - \u6700\u5F8C.x1) <= Math.abs(\u6700\u5F8C.y2 - \u6700\u5F8C.y1);
21773
+ const \u5019\u88DC = [
21774
+ \u5019\u88DCa,
21775
+ {
21776
+ labelX: \u6700\u5F8C\u306F\u7E26 ? \u6700\u5F8C.x1 * 2 - (\u5019\u88DCa\u306E\u7BB1.x + \u5019\u88DCa\u306E\u7BB1.w / 2) : \u5019\u88DCa\u306E\u7BB1.x + \u5019\u88DCa\u306E\u7BB1.w / 2,
21777
+ labelY: \u6700\u5F8C\u306F\u7E26 ? \u5019\u88DCa\u306E\u7BB1.y + \u5019\u88DCa\u306E\u7BB1.h / 2 : \u6700\u5F8C.y1 * 2 - (\u5019\u88DCa\u306E\u7BB1.y + \u5019\u88DCa\u306E\u7BB1.h / 2),
21778
+ labelAnchor: "middle"
21779
+ }
21780
+ ];
21781
+ for (const c of \u5019\u88DC) {
21782
+ const \u672D = {
21783
+ kind: "edge-label",
21784
+ id: e.id,
21785
+ ...computeLabelBBoxWorld({ ...e, ...c }, textMetrics)
21786
+ };
21787
+ if (segmentsCrossRect([\u6700\u5F8C], \u672D)) continue;
21788
+ if (\u672D\u306E\u79FB\u52D5\u3092\u585E\u3050\u76F8\u624B\u3092\u63A2\u3059(\u5468\u308A, \u5143\u306E\u672D, \u672D) !== null) continue;
21789
+ e.labelX = c.labelX;
21790
+ e.labelY = c.labelY;
21791
+ e.labelAnchor = c.labelAnchor;
21792
+ labels[labelIndex] = \u672D;
21793
+ break;
21315
21794
  }
21316
21795
  }
21317
21796
  }
@@ -21328,7 +21807,7 @@ function \u672B\u5C3E\u3092\u8FBA\u306B\u6CBF\u3063\u3066\u305A\u3089\u3059(e, \
21328
21807
  if ((e.d.match(/M/g) ?? []).length !== 1) return null;
21329
21808
  const segs = extractPathSegments(e.d);
21330
21809
  if (segs.length === 0) return null;
21331
- if (segs.some((s) => s.cmd === "C")) return null;
21810
+ if (segs.some((s) => s.cmd === "C" || s.cmd === "A")) return null;
21332
21811
  const last = segs[segs.length - 1];
21333
21812
  if (last.cmd !== "L") return null;
21334
21813
  const \u5782\u76F4\u306B\u5165\u308B = \u6A2A ? Math.abs(last.y2 - last.y1) < 0.5 && Math.abs(last.x2 - last.x1) > 0.5 : Math.abs(last.x2 - last.x1) < 0.5 && Math.abs(last.y2 - last.y1) > 0.5;
@@ -21498,7 +21977,7 @@ function expandLanesForNodes(lanes, nodes) {
21498
21977
  };
21499
21978
  });
21500
21979
  }
21501
- function expandLaneGapsForEdgeLabels(lanes, nodes, edges) {
21980
+ function expandLaneGapsForEdgeLabels(lanes, nodes, edges, textMetrics = "proportional") {
21502
21981
  if (lanes.length < 2) return lanes;
21503
21982
  const layoutedLanes = lanes.filter((l) => !(l.posX !== void 0 && l.posY !== void 0));
21504
21983
  if (layoutedLanes.length < 2) return lanes;
@@ -21514,7 +21993,7 @@ function expandLaneGapsForEdgeLabels(lanes, nodes, edges) {
21514
21993
  const fi = laneIndexById.get(fromLane);
21515
21994
  const ti = laneIndexById.get(toLane);
21516
21995
  if (fi === void 0 || ti === void 0 || fi === ti) continue;
21517
- const labelBoxW = computeLabelBoxW(edge.label, edge.sub);
21996
+ const labelBoxW = computeLabelBoxW(edge.label, edge.sub, textMetrics);
21518
21997
  if (labelBoxW === 0) continue;
21519
21998
  const lo = Math.min(fi, ti);
21520
21999
  const hi = Math.max(fi, ti);
@@ -21619,13 +22098,16 @@ function \u5411\u304D\u3092\u53D6\u308B(end, \u5019\u88DC) {
21619
22098
  }
21620
22099
  return null;
21621
22100
  }
21622
- function \u7AEF\u3067\u306E\u5411\u304D(d, \u7AEF) {
22101
+ function \u7DDA\u306E\u7AEF\u306E\u5411\u304D(d, \u7AEF) {
21623
22102
  const segs = extractPathSegments(d);
21624
22103
  if (segs.length === 0) return null;
21625
22104
  if (\u7AEF === "head") {
21626
22105
  const last = segs[segs.length - 1];
21627
22106
  const end2 = { x: last.x2, y: last.y2 };
21628
- const \u5019\u88DC2 = segs.slice().reverse().flatMap((s) => [s.cmd === "Q" ? s.ctrl?.[0] : s.cmd === "C" ? s.ctrl?.[1] : void 0, { x: s.x1, y: s.y1 }]);
22107
+ const \u5019\u88DC2 = segs.slice().reverse().flatMap((s) => {
22108
+ const \u5236\u5FA1\u70B9 = s.cmd === "C" ? [s.ctrl?.[1], s.ctrl?.[0]] : s.cmd === "Q" ? [s.ctrl?.[0]] : [];
22109
+ return [...\u5236\u5FA1\u70B9, { x: s.x1, y: s.y1 }];
22110
+ });
21629
22111
  return \u5411\u304D\u3092\u53D6\u308B(end2, \u5019\u88DC2);
21630
22112
  }
21631
22113
  const first = segs[0];
@@ -21633,10 +22115,10 @@ function \u7AEF\u3067\u306E\u5411\u304D(d, \u7AEF) {
21633
22115
  const \u5019\u88DC = segs.flatMap((s) => [...s.ctrl ?? [], { x: s.x2, y: s.y2 }]);
21634
22116
  return \u5411\u304D\u3092\u53D6\u308B(end, \u5019\u88DC);
21635
22117
  }
21636
- function \u7AEF\u306E\u5B57\u3092\u7F6E\u304F(edge, \u7AEF = "head") {
22118
+ function \u7AEF\u306E\u5B57\u3092\u7F6E\u304F(edge, \u7AEF = "head", textMetrics = "proportional") {
21637
22119
  const text = (\u7AEF === "head" ? edge.headLabel : edge.tailLabel)?.trim();
21638
22120
  if (!text) return null;
21639
- const \u5411\u304D = \u7AEF\u3067\u306E\u5411\u304D(edge.d, \u7AEF);
22121
+ const \u5411\u304D = \u7DDA\u306E\u7AEF\u306E\u5411\u304D(edge.d, \u7AEF);
21640
22122
  if (!\u5411\u304D) return null;
21641
22123
  const { end, ux, uy } = \u5411\u304D;
21642
22124
  const bx = end.x - ux * \u7AEF\u306E\u5B57\u3092\u623B\u3059\u8DDD\u96E2;
@@ -21644,7 +22126,8 @@ function \u7AEF\u306E\u5B57\u3092\u7F6E\u304F(edge, \u7AEF = "head") {
21644
22126
  const w = measureTextWidth(text, {
21645
22127
  fontSize: \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055,
21646
22128
  fontWeight: EDGE_LABEL_TEXT.sub.fontWeight,
21647
- fontFamily: "mono"
22129
+ fontFamily: "mono",
22130
+ textMetrics
21648
22131
  });
21649
22132
  const h = \u7BB1\u306E\u9AD8\u3055;
21650
22133
  const \u672D = hasRenderedLabel(edge) && edge.labelX !== void 0 && edge.labelY !== void 0 ? { x: edge.labelX, y: edge.labelY } : null;
@@ -21693,10 +22176,10 @@ function autoStorageHeight(n, defaultH) {
21693
22176
  }
21694
22177
  return Math.max(defaultH, \u5FC5\u8981);
21695
22178
  }
21696
- function autoRowsWidth(n, defaultW) {
22179
+ function autoRowsWidth(n, defaultW, textMetrics = "proportional") {
21697
22180
  if (n.w != null) return n.w;
21698
22181
  if (!n.rows || n.rows.length === 0) return defaultW;
21699
- const required = requiredRowsWidth(n.rows, n.kind);
22182
+ const required = requiredRowsWidth(n.rows, n.kind, textMetrics);
21700
22183
  return Math.max(defaultW, required);
21701
22184
  }
21702
22185
  function \u7BB1\u306E\u9AD8\u30552(n, \u65E2\u5B9Ah) {
@@ -21734,7 +22217,7 @@ function requiredStackGapForEdgeLabels(diag, allStacks) {
21734
22217
  }
21735
22218
  return required;
21736
22219
  }
21737
- function layoutNodes(diag, lanes) {
22220
+ function layoutNodes(diag, lanes, textMetrics) {
21738
22221
  const laneMap = new Map(lanes.map((l) => [l.id, l]));
21739
22222
  const allStacks = Array.from(new Set(diag.nodes.map((n) => n.stack))).sort((a, b) => a - b);
21740
22223
  const rowH = /* @__PURE__ */ new Map();
@@ -21778,7 +22261,7 @@ function layoutNodes(diag, lanes) {
21778
22261
  }
21779
22262
  const size = NODE_SIZE[n.kind];
21780
22263
  if (n.posX !== void 0 && n.posY !== void 0) {
21781
- const w2 = n.posW ?? n.w ?? autoRowsWidth(n, size.w);
22264
+ const w2 = n.posW ?? n.w ?? autoRowsWidth(n, size.w, textMetrics);
21782
22265
  const h2 = n.posH ?? n.h ?? rowH.get(n.stack) ?? size.h;
21783
22266
  out.push({
21784
22267
  ...n,
@@ -21796,7 +22279,7 @@ function layoutNodes(diag, lanes) {
21796
22279
  const \u81EA\u524D\u306E\u9AD8\u3055 = n.rowMarks !== void 0;
21797
22280
  const h = n.h ?? (\u81EA\u524D\u306E\u9AD8\u3055 ? \u7BB1\u306E\u9AD8\u30552(n, size.h) : \u6BB5\u306E\u9AD8\u3055);
21798
22281
  const cy = \u6BB5\u306E\u82AF;
21799
- const w = autoRowsWidth(n, size.w);
22282
+ const w = autoRowsWidth(n, size.w, textMetrics);
21800
22283
  out.push({
21801
22284
  ...n,
21802
22285
  cx,
@@ -21916,10 +22399,16 @@ function applyRowLevelNodeShifts(nodes, lanes, nodeShifts) {
21916
22399
  return moved ? { nodes: outNodes, lanes: outLanes } : null;
21917
22400
  }
21918
22401
  function layout(diag) {
22402
+ const textMetrics = resolveTextMetrics(diag.textMetrics);
21919
22403
  const lanes = layoutLanes(diag);
21920
- const rawNodes = applyFooterShapeDrops(lanes, layoutNodes(diag, lanes));
22404
+ const rawNodes = applyFooterShapeDrops(lanes, layoutNodes(diag, lanes, textMetrics));
21921
22405
  const expandedLanes = expandLanesForNodes(lanes, rawNodes);
21922
- const gapExpandedLanes = expandLaneGapsForEdgeLabels(expandedLanes, rawNodes, diag.edges);
22406
+ const gapExpandedLanes = expandLaneGapsForEdgeLabels(
22407
+ expandedLanes,
22408
+ rawNodes,
22409
+ diag.edges,
22410
+ textMetrics
22411
+ );
21923
22412
  const nodes = rawNodes.map((n) => {
21924
22413
  if (n.posX !== void 0 && n.posY !== void 0) return n;
21925
22414
  const oldLane = lanes.find((l) => l.id === n.lane);
@@ -21928,13 +22417,13 @@ function layout(diag) {
21928
22417
  return { ...n, cx: newLane.x + newLane.width / 2 };
21929
22418
  });
21930
22419
  const containedLanesPre = recomputeContainedLanes(gapExpandedLanes, nodes);
21931
- const edgesPre = layoutEdges(diag, nodes, containedLanesPre);
21932
- const bboxesPre = collectBBoxes(containedLanesPre, nodes, edgesPre);
22420
+ const edgesPre = layoutEdges(diag, nodes, containedLanesPre, textMetrics);
22421
+ const bboxesPre = collectBBoxes(containedLanesPre, nodes, edgesPre, textMetrics);
21933
22422
  const collisionsPre = detectCollisions(bboxesPre, edgesPre);
21934
22423
  const nodesResolved = resolveOverlaps(nodes, collisionsPre);
21935
22424
  const moved = nodesResolved !== nodes;
21936
22425
  const containedLanes = moved ? recomputeContainedLanes(gapExpandedLanes, nodesResolved) : containedLanesPre;
21937
- const edgesAfterMove = moved ? layoutEdges(diag, nodesResolved, containedLanes) : edgesPre;
22426
+ const edgesAfterMove = moved ? layoutEdges(diag, nodesResolved, containedLanes, textMetrics) : edgesPre;
21938
22427
  const chainShiftClearance = Math.max(CLEARANCE_LABEL_LABEL, CLEARANCE_NODE_LABEL);
21939
22428
  let edges;
21940
22429
  let nodesFinal = nodesResolved;
@@ -21945,10 +22434,13 @@ function layout(diag) {
21945
22434
  } else {
21946
22435
  const propagateResult = resolveEdgeLabelOverlapsWithChainAndPropagate(
21947
22436
  edgesAfterMove,
21948
- collectBBoxes(containedLanes, nodesResolved, []).filter(
22437
+ collectBBoxes(containedLanes, nodesResolved, [], textMetrics).filter(
21949
22438
  (b) => b.kind === "node" || b.kind === "lane-label"
21950
22439
  ),
21951
- chainShiftClearance
22440
+ chainShiftClearance,
22441
+ void 0,
22442
+ void 0,
22443
+ textMetrics
21952
22444
  );
21953
22445
  edges = propagateResult.edges;
21954
22446
  if (propagateResult.nodeShifts.size > 0) {
@@ -21960,28 +22452,39 @@ function layout(diag) {
21960
22452
  }
21961
22453
  if (nodesFinal !== nodesResolved) {
21962
22454
  containedLanesFinal = recomputeContainedLanes(laneShiftedBase, nodesFinal);
21963
- edges = layoutEdges(diag, nodesFinal, containedLanesFinal);
22455
+ edges = layoutEdges(diag, nodesFinal, containedLanesFinal, textMetrics);
21964
22456
  }
21965
22457
  }
21966
22458
  const positionedEdgeIds = new Set(
21967
- diag.edges.filter((e) => e.posX1 !== void 0 && e.posY1 !== void 0 && e.posX2 !== void 0 && e.posY2 !== void 0).map((e) => e.id)
22459
+ diag.edges.filter(
22460
+ (e) => e.routing === "curve" || e.routing === "metro" || e.posX1 !== void 0 && e.posY1 !== void 0 && e.posX2 !== void 0 && e.posY2 !== void 0
22461
+ ).map((e) => e.id)
21968
22462
  );
21969
- bowSharedStraightPaths(edges, nodesFinal, positionedEdgeIds);
21970
- pullOutgoingFirstCorner(edges, nodesFinal);
21971
- fanIncomingEndpoints(edges, nodesFinal);
22463
+ bowSharedStraightPaths(edges, nodesFinal, positionedEdgeIds, textMetrics);
22464
+ pullOutgoingFirstCorner(edges, nodesFinal, textMetrics);
22465
+ const fannedTailShifts = fanIncomingEndpoints(edges, nodesFinal);
21972
22466
  separateSharedStraightRuns(edges, nodesFinal);
21973
22467
  hopEdgeCrossings(edges);
21974
- repositionParallelLabels(edges, nodesFinal);
21975
- slideLabelsAlongOwnPath(edges, nodesFinal);
22468
+ const labelClearanceObstacles = collectBBoxes(
22469
+ containedLanesFinal,
22470
+ nodesFinal,
22471
+ [],
22472
+ textMetrics
22473
+ ).filter(
22474
+ (b) => b.kind === "node" || b.kind === "lane-label"
22475
+ );
22476
+ followLabelsToFannedTails(edges, labelClearanceObstacles, fannedTailShifts, textMetrics);
22477
+ repositionParallelLabels(edges, nodesFinal, textMetrics);
22478
+ slideLabelsAlongOwnPath(edges, nodesFinal, textMetrics);
21976
22479
  if (!isChainEdgeLabelDisabled()) {
21977
22480
  edges = resolveLabelClearanceAfterPathPasses(
21978
22481
  edges,
21979
- collectBBoxes(containedLanesFinal, nodesFinal, []).filter(
21980
- (b) => b.kind === "node" || b.kind === "lane-label"
21981
- )
22482
+ labelClearanceObstacles,
22483
+ void 0,
22484
+ textMetrics
21982
22485
  );
21983
22486
  }
21984
- const bboxes = collectBBoxes(containedLanesFinal, nodesFinal, edges);
22487
+ const bboxes = collectBBoxes(containedLanesFinal, nodesFinal, edges, textMetrics);
21985
22488
  const collisions = detectCollisions(bboxes, edges);
21986
22489
  const nearCollisions = detectNearCollisions(bboxes, edges);
21987
22490
  if (collisions.length > 0) {
@@ -22021,6 +22524,8 @@ function layout(diag) {
22021
22524
  // 描画側の固定の字の言語 (#847)。 既定 (`en`) と型の外の値は持たせない = 配置の結果の形を
22022
22525
  // 変更前と揃え、記法の書き損じで一部の字だけ日本語になる形を作らない
22023
22526
  ...resolveLang(diag.lang) === "ja" ? { lang: "ja" } : {},
22527
+ // 既定は持ち越さない。既存の LaidDiagram の形を変えず、等幅の図だけ描画へ伝える
22528
+ ...textMetrics === "monospace" ? { textMetrics: "monospace" } : {},
22024
22529
  // 種類も配色と同じく空の目印を出さない。 遮断をここに揃えると手書きの図にも効く
22025
22530
  ...diag.type ? { type: diag.type } : {},
22026
22531
  bboxes,
@@ -22588,11 +23093,13 @@ function applyHeuristics(diag, laid, violations, applied) {
22588
23093
  violations.filter((v) => v.axis === "edge-node-cross").map((v) => extractEdgeId(v.detail)).filter((id) => id !== null)
22589
23094
  );
22590
23095
  if (h3Edges.size > 0) {
22591
- const originalEdges = edges;
22592
- edges = edges.map(
22593
- (e) => h3Edges.has(e.id) && e.routing !== "back-detour" ? { ...e, routing: "back-detour" } : e
23096
+ const eligibleEdges = new Set(
23097
+ edges.filter((e) => h3Edges.has(e.id) && (e.routing === void 0 || e.routing === "default")).map((e) => e.id)
22594
23098
  );
22595
- if (edges !== originalEdges) {
23099
+ if (eligibleEdges.size > 0) {
23100
+ edges = edges.map(
23101
+ (e) => eligibleEdges.has(e.id) ? { ...e, routing: "back-detour" } : e
23102
+ );
22596
23103
  applied.push("h3-edge-back-detour");
22597
23104
  mutated = true;
22598
23105
  }
@@ -22912,15 +23419,15 @@ function extractPathEndpoints(d) {
22912
23419
  if (!start || !end) return null;
22913
23420
  return { start, end };
22914
23421
  }
22915
- function isPointOnNodeBoundary(point, node, tol) {
23422
+ function isPointOnNodeBoundary(point2, node, tol) {
22916
23423
  const left = node.cx - node.w / 2;
22917
23424
  const right = node.cx + node.w / 2;
22918
23425
  const top = node.cy - node.h / 2;
22919
23426
  const bot = node.cy + node.h / 2;
22920
- if (Math.abs(point.x - left) <= tol && point.y >= top - tol && point.y <= bot + tol) return true;
22921
- if (Math.abs(point.x - right) <= tol && point.y >= top - tol && point.y <= bot + tol) return true;
22922
- if (Math.abs(point.y - top) <= tol && point.x >= left - tol && point.x <= right + tol) return true;
22923
- if (Math.abs(point.y - bot) <= tol && point.x >= left - tol && point.x <= right + tol) return true;
23427
+ if (Math.abs(point2.x - left) <= tol && point2.y >= top - tol && point2.y <= bot + tol) return true;
23428
+ if (Math.abs(point2.x - right) <= tol && point2.y >= top - tol && point2.y <= bot + tol) return true;
23429
+ if (Math.abs(point2.y - top) <= tol && point2.x >= left - tol && point2.x <= right + tol) return true;
23430
+ if (Math.abs(point2.y - bot) <= tol && point2.x >= left - tol && point2.x <= right + tol) return true;
22924
23431
  return false;
22925
23432
  }
22926
23433
  async function verifyBoundingBoxes(page, laid, options) {
@@ -24132,6 +24639,7 @@ function CdlEdgeView({
24132
24639
  "g",
24133
24640
  {
24134
24641
  "data-cdl-edge": edge.id,
24642
+ "data-cdl-routing": edge.routing === "metro" ? "metro" : void 0,
24135
24643
  "data-cdl-from": edge.from,
24136
24644
  "data-cdl-to": edge.to,
24137
24645
  "data-cdl-active": active ? "true" : "false",
@@ -24143,6 +24651,7 @@ function CdlEdgeView({
24143
24651
  "data-cdl-edge-label": edge.label,
24144
24652
  "data-cdl-edge-sub": edge.sub ?? "",
24145
24653
  "data-cdl-tone": edge.tone,
24654
+ "data-cdl-edge-role": edge.role,
24146
24655
  children: [
24147
24656
  isDotted ? /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
24148
24657
  /* @__PURE__ */ jsxRuntime.jsx("path", { id: glowPathId, d: glowPathD, fill: "none", stroke: "none" }),
@@ -24294,11 +24803,12 @@ function CdlEdgeGlowView({
24294
24803
  }
24295
24804
  function CdlEdgeLabelView({
24296
24805
  edge,
24297
- active
24806
+ active,
24807
+ textMetrics = "proportional"
24298
24808
  }) {
24299
24809
  if (!hasRenderedLabel(edge)) return null;
24300
24810
  const color = edgeColor(edge);
24301
- const bbox = computeLabelBBoxWorld(edge);
24811
+ const bbox = computeLabelBBoxWorld(edge, textMetrics);
24302
24812
  const boxW = bbox.w;
24303
24813
  const boxH = bbox.h;
24304
24814
  const boxLeftX = bbox.x - edge.labelX;
@@ -24314,6 +24824,8 @@ function CdlEdgeLabelView({
24314
24824
  "data-cdl-edge-label-for": edge.id,
24315
24825
  "data-cdl-edge-label-text": edge.label,
24316
24826
  "data-cdl-edge-sub-text": edge.sub ?? "",
24827
+ "data-cdl-tone": edge.tone,
24828
+ "data-cdl-edge-role": edge.role,
24317
24829
  children: [
24318
24830
  edge.labelPlate !== false && /* @__PURE__ */ jsxRuntime.jsx(
24319
24831
  "rect",
@@ -24367,9 +24879,10 @@ function CdlEdgeLabelView({
24367
24879
  function CdlEdgeEndLabelView({
24368
24880
  edge,
24369
24881
  active,
24370
- \u7AEF
24882
+ \u7AEF,
24883
+ textMetrics = "proportional"
24371
24884
  }) {
24372
- const \u7F6E\u304D\u5834\u6240 = \u7AEF\u306E\u5B57\u3092\u7F6E\u304F(edge, \u7AEF);
24885
+ const \u7F6E\u304D\u5834\u6240 = \u7AEF\u306E\u5B57\u3092\u7F6E\u304F(edge, \u7AEF, textMetrics);
24373
24886
  if (!\u7F6E\u304D\u5834\u6240) return null;
24374
24887
  const color = edgeColor(edge);
24375
24888
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -24378,6 +24891,8 @@ function CdlEdgeEndLabelView({
24378
24891
  "data-cdl-role": "edge-end-label",
24379
24892
  "data-cdl-edge-end-label-for": edge.id,
24380
24893
  "data-cdl-edge-end": \u7AEF,
24894
+ "data-cdl-tone": edge.tone,
24895
+ "data-cdl-edge-role": edge.role,
24381
24896
  x: \u7F6E\u304D\u5834\u6240.x,
24382
24897
  y: \u7F6E\u304D\u5834\u6240.y,
24383
24898
  fontSize: \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055,
@@ -24625,12 +25140,18 @@ var g4 = (v) => Math.round(v / 4) * 4;
24625
25140
  function sequenceStepId() {
24626
25141
  return "seq_step";
24627
25142
  }
24628
- function sequenceBoardMetrics(data) {
25143
+ function sequenceBoardMetrics(data, textMetrics = "proportional") {
24629
25144
  const \u540D\u5E45 = data.actors.map(
24630
- (a) => Math.max(textWidth(a.name, SEQ_NAME), a.subtitle ? textWidth(a.subtitle, SEQ_SUB) : 0)
25145
+ (a) => Math.max(
25146
+ textWidth(a.name, SEQ_NAME, 0, textMetrics),
25147
+ a.subtitle ? textWidth(a.subtitle, SEQ_SUB, 0, textMetrics) : 0
25148
+ )
24631
25149
  );
24632
25150
  const colW = g4(Math.max(SEQ_COL_MIN, Math.max(0, ...\u540D\u5E45) + SEQ_COL_PAD));
24633
- const \u8A9E\u5E45 = Math.max(0, ...data.messages.map((m) => textWidth(m.label, SEQ_LABEL)));
25151
+ const \u8A9E\u5E45 = Math.max(
25152
+ 0,
25153
+ ...data.messages.map((m) => textWidth(m.label, SEQ_LABEL, 0, textMetrics))
25154
+ );
24634
25155
  const gutter = g4(SEQ_EDGE + SEQ_GUTTER_PAD + \u8A9E\u5E45 + SEQ_GUTTER_GAP);
24635
25156
  const headY = SEQ_EDGE + SEQ_HEAD;
24636
25157
  const rowY = (i) => headY + SEQ_ROW_PAD + i * SEQ_ROW;
@@ -24643,11 +25164,12 @@ function sequenceBoardMetrics(data) {
24643
25164
  }
24644
25165
  function SequenceBoardNode({
24645
25166
  node,
24646
- stateValues
25167
+ stateValues,
25168
+ textMetrics = "proportional"
24647
25169
  }) {
24648
25170
  const data = node.sequenceData;
24649
25171
  if (!data) return /* @__PURE__ */ jsxRuntime.jsx("g", { "data-cdl-role": "sequence-board" });
24650
- const m = sequenceBoardMetrics(data);
25172
+ const m = sequenceBoardMetrics(data, textMetrics);
24651
25173
  const x = node.cx - node.w / 2;
24652
25174
  const y = node.cy - node.h / 2;
24653
25175
  const \u73FE\u5728 = (() => {
@@ -25298,7 +25820,8 @@ function GenericNode({
25298
25820
  active,
25299
25821
  value,
25300
25822
  stateValues,
25301
- \u5024\u306E\u540D\u524D
25823
+ \u5024\u306E\u540D\u524D,
25824
+ textMetrics = "proportional"
25302
25825
  }) {
25303
25826
  const base = STYLES[node.kind] ?? FALLBACK;
25304
25827
  const toned = toneColor3(node.tone);
@@ -25437,7 +25960,7 @@ function GenericNode({
25437
25960
  const resolved = node.rows.map((row) => interpolate(row, stateValues, \u5024\u306E\u540D\u524D));
25438
25961
  const splits = resolved.map(splitRow);
25439
25962
  const leftMaxWidth = splits.reduce(
25440
- (m, s) => Math.max(m, rowColumnWidth(s.left, GENERIC_ROW_LEFT_SIZE_PX, false)),
25963
+ (m, s) => Math.max(m, rowColumnWidth(s.left, GENERIC_ROW_LEFT_SIZE_PX, false, textMetrics)),
25441
25964
  0
25442
25965
  );
25443
25966
  const rightColX = ROW_PAD_X_PX + leftMaxWidth + ROW_COL_GAP_PX;
@@ -25563,17 +26086,22 @@ function DynShapeNode({
25563
26086
  return renderPolygon(shape, cx, cy, stateValues, fillColor, strokeColor, activeOpacity);
25564
26087
  }
25565
26088
  })();
26089
+ const \u63C3\u3048 = \u7BB1\u3044\u3063\u3071\u3044\u306B\u63CF\u304F2(shape.kind) ? "start" : "middle";
26090
+ return renderShapeWithOutsideLabels(\u5F62, node, \u63C3\u3048);
26091
+ }
26092
+ function renderShapeWithOutsideLabels(\u5F62, node, \u63C3\u3048) {
26093
+ const cx = node.cx;
26094
+ const y = node.cy - node.h / 2;
25566
26095
  const \u540D\u524D = (node.title ?? "").trim();
25567
26096
  const \u5024 = (node.subtitle ?? "").trim();
25568
26097
  if (\u540D\u524D === "" && \u5024 === "") return \u5F62;
25569
- const \u63C3\u3048 = \u7BB1\u3044\u3063\u3071\u3044\u306B\u63CF\u304F2(shape.kind) ? "start" : "middle";
25570
26098
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
25571
26099
  \u5F62,
25572
26100
  \u540D\u524D !== "" && /* @__PURE__ */ jsxRuntime.jsx(
25573
26101
  "text",
25574
26102
  {
25575
26103
  "data-cdl-role": "shape-name",
25576
- x: \u63C3\u3048 === "start" ? x : cx,
26104
+ x: \u63C3\u3048 === "start" ? node.cx - node.w / 2 : cx,
25577
26105
  y: y - NAME_GAP,
25578
26106
  textAnchor: \u63C3\u3048,
25579
26107
  fontSize: 13,
@@ -25587,7 +26115,7 @@ function DynShapeNode({
25587
26115
  {
25588
26116
  "data-cdl-role": "shape-value",
25589
26117
  x: cx,
25590
- y: y + h + VALUE_GAP,
26118
+ y: y + node.h + VALUE_GAP,
25591
26119
  textAnchor: "middle",
25592
26120
  fontSize: 12,
25593
26121
  fill: "var(--cdl-text-dim, #5a6270)",
@@ -25837,6 +26365,27 @@ function interpolateColor(template, stateValues, fallback) {
25837
26365
  if (!template) return fallback;
25838
26366
  return interpolate(template, stateValues);
25839
26367
  }
26368
+ var STATION_STROKE_ACTIVE = 4;
26369
+ var STATION_STROKE_IDLE = 3;
26370
+ var STATION_DEFAULT = "var(--cdl-tone-accent, #2d6a8f)";
26371
+ function StationNode({ node, active }) {
26372
+ const strokeWidth = active ? STATION_STROKE_ACTIVE : STATION_STROKE_IDLE;
26373
+ const radius = Math.max(0, Math.min(node.w, node.h) / 2 - strokeWidth / 2);
26374
+ const \u5F62 = /* @__PURE__ */ jsxRuntime.jsx(
26375
+ "circle",
26376
+ {
26377
+ "data-cdl-role": "node-body",
26378
+ "data-cdl-mark": "station",
26379
+ cx: node.cx,
26380
+ cy: node.cy,
26381
+ r: radius,
26382
+ fill: "var(--cdl-node-fill, #ffffff)",
26383
+ stroke: nodeAccent(node, STATION_DEFAULT),
26384
+ strokeWidth
26385
+ }
26386
+ );
26387
+ return renderShapeWithOutsideLabels(\u5F62, node, "middle");
26388
+ }
25840
26389
 
25841
26390
  // src/kinds/label-stack.ts
25842
26391
  function \u540D\u672D\u306E\u6BB5\u3092\u307B\u3069\u304F(\u771F\u306Ey, \u9593\u9694, \u4E0A\u9650, \u4E0B\u9650) {
@@ -25895,8 +26444,8 @@ function \u5024\u3068\u5272\u5408\u306E\u6587\u5B57(\u5024, \u5272\u5408, \u5408
25895
26444
  return \u7D44.\u5024 === null ? \u7D44.\u5272\u5408 : `${\u7D44.\u5024} ${\u7D44.\u5272\u5408}`;
25896
26445
  }
25897
26446
  var \u7A74\u306B\u5BFE\u3059\u308B\u4E0A\u9650 = 0.8;
25898
- function \u4E2D\u592E\u306E\u5B57(\u6BD4\u4F8B\u3057\u305F\u5927\u304D\u3055, \u7A74\u306E\u534A\u5F84, \u6587) {
25899
- 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);
26447
+ function \u4E2D\u592E\u306E\u5B57(\u6BD4\u4F8B\u3057\u305F\u5927\u304D\u3055, \u7A74\u306E\u534A\u5F84, \u6587, textMetrics = "proportional") {
26448
+ const \u5165\u308B\u5927\u304D\u3055 = \u7A74\u306E\u534A\u5F84 * 2 * \u7A74\u306B\u5BFE\u3059\u308B\u4E0A\u9650 / Math.max(textWidth(\u6587, 1, 0, textMetrics), 1e-6);
25900
26449
  return Math.min(Math.max(\u6BD4\u4F8B\u3057\u305F\u5927\u304D\u3055, \u7E2E\u3093\u3060\u7D75\u306E\u5B57\u306E\u4E0B\u9650), \u5165\u308B\u5927\u304D\u3055);
25901
26450
  }
25902
26451
  function ChartPieNode({
@@ -25904,7 +26453,8 @@ function ChartPieNode({
25904
26453
  active,
25905
26454
  stateValues = {},
25906
26455
  drawing = false,
25907
- progress = 1
26456
+ progress = 1,
26457
+ textMetrics = "proportional"
25908
26458
  }) {
25909
26459
  const instanceId = react.useId().replace(/[^A-Za-z0-9_-]/g, "");
25910
26460
  const x0 = node.cx - node.w / 2;
@@ -25935,15 +26485,26 @@ function ChartPieNode({
25935
26485
  return `${\u5B9F\u5024\u8868\u8A18(d.value)}%` === \u5272\u5408\u306E\u6587\u5B57[i] ? \u540D : `${\u540D} ${\u5B9F\u5024\u8868\u8A18(d.value)}`;
25936
26486
  });
25937
26487
  if (\u5F62 !== "ring") {
25938
- const \u5171\u901A = { node, active, data, \u5272\u5408: \u4ECA\u306E\u5272\u5408, x0, y0, drawing, progress, instanceId };
26488
+ const \u5171\u901A = {
26489
+ node,
26490
+ active,
26491
+ data,
26492
+ \u5272\u5408: \u4ECA\u306E\u5272\u5408,
26493
+ x0,
26494
+ y0,
26495
+ drawing,
26496
+ progress,
26497
+ instanceId,
26498
+ textMetrics
26499
+ };
25939
26500
  return \u5F62 === "arcs" ? \u5F27\u306E\u5F62(\u5171\u901A) : \u8868\u306E\u5F62(\u5171\u901A);
25940
26501
  }
25941
26502
  const \u540D\u672D\u5E45 = Math.max(
25942
26503
  0,
25943
26504
  ...data.map(
25944
26505
  (_d, i) => Math.max(
25945
- textWidth(\u5272\u5408\u306E\u6587\u5B57[i] ?? "", \u5272\u5408\u306E\u7D1A),
25946
- textWidth(\u540D\u524D\u306E\u6587\u5B57[i] ?? "", \u540D\u524D\u306E\u7D1A)
26506
+ textWidth(\u5272\u5408\u306E\u6587\u5B57[i] ?? "", \u5272\u5408\u306E\u7D1A, 0, textMetrics),
26507
+ textWidth(\u540D\u524D\u306E\u6587\u5B57[i] ?? "", \u540D\u524D\u306E\u7D1A, 0, textMetrics)
25947
26508
  )
25948
26509
  )
25949
26510
  );
@@ -25958,8 +26519,8 @@ function ChartPieNode({
25958
26519
  const \u524D\u306Eslices = \u524D\u3042\u308A ? \u8F2A\u3092\u7D44\u3080(data, cx, cy, \u524D\u306E\u5916\u534A\u5F84, \u524D\u306E\u5185\u534A\u5F84, \u524D\u306E\u5272\u5408) : [];
25959
26520
  const \u7A74 = \u524D\u3042\u308A ? \u524D\u306E\u5185\u534A\u5F84 : \u5916\u306E\u5185\u534A\u5F84;
25960
26521
  const \u5408\u8A08\u306E\u6587 = \u5B9F\u5024\u8868\u8A18(Math.round(\u524D\u3042\u308A ? \u4ECA\u306E\u5408\u8A08 : total));
25961
- const \u5408\u8A08\u306E\u5B57 = \u4E2D\u592E\u306E\u5B57(Math.round(radius * 0.26), \u7A74, \u5408\u8A08\u306E\u6587);
25962
- const \u898B\u51FA\u3057\u306E\u5B572 = \u4E2D\u592E\u306E\u5B57(Math.round(radius * 0.12), \u7A74, "\u5408\u8A08");
26522
+ const \u5408\u8A08\u306E\u5B57 = \u4E2D\u592E\u306E\u5B57(Math.round(radius * 0.26), \u7A74, \u5408\u8A08\u306E\u6587, textMetrics);
26523
+ const \u898B\u51FA\u3057\u306E\u5B572 = \u4E2D\u592E\u306E\u5B57(Math.round(radius * 0.12), \u7A74, "\u5408\u8A08", textMetrics);
25963
26524
  const \u5408\u8A08\u306E\u4E0B = Math.max(Math.round(radius * 0.2), \u5408\u8A08\u306E\u5B57 * 0.25 + \u898B\u51FA\u3057\u306E\u5B572 * 0.8);
25964
26525
  const slices = \u8F2A\u3092\u7D44\u3080(data, cx, cy, radius, \u5916\u306E\u5185\u534A\u5F84, \u4ECA\u306E\u5272\u5408);
25965
26526
  const \u958B\u304D = \u9032\u307F\u3092\u7573\u3080(drawing, progress);
@@ -26142,14 +26703,24 @@ function \u67A0(node, active) {
26142
26703
  }
26143
26704
  );
26144
26705
  }
26145
- function \u5F27\u306E\u5F62({ node, active, data, \u5272\u5408, x0, y0, drawing, progress }) {
26706
+ function \u5F27\u306E\u5F62({
26707
+ node,
26708
+ active,
26709
+ data,
26710
+ \u5272\u5408,
26711
+ x0,
26712
+ y0,
26713
+ drawing,
26714
+ progress,
26715
+ textMetrics
26716
+ }) {
26146
26717
  const PAD = 20;
26147
26718
  const \u540D\u524D\u306E\u7D1A = 14;
26148
26719
  const \u5272\u5408\u306E\u7D1A = 24;
26149
26720
  const \u5370\u304B\u3089\u540D\u524D\u307E\u30672 = 18;
26150
26721
  const \u540D\u524D\u304B\u3089\u5272\u5408\u307E\u3067 = 24;
26151
26722
  const \u5272\u5408\u306E\u6587\u5B57 = \u5272\u5408.map(\u5272\u5408\u8868\u8A18);
26152
- const \u4E00\u89A7\u5E45 = 10 + \u5370\u304B\u3089\u540D\u524D\u307E\u30672 + Math.max(0, ...data.map((d) => textWidth(d.label ?? "", \u540D\u524D\u306E\u7D1A))) + \u540D\u524D\u304B\u3089\u5272\u5408\u307E\u3067 + Math.max(0, ...\u5272\u5408\u306E\u6587\u5B57.map((t) => textWidth(t, \u5272\u5408\u306E\u7D1A)));
26723
+ const \u4E00\u89A7\u5E45 = 10 + \u5370\u304B\u3089\u540D\u524D\u307E\u30672 + Math.max(0, ...data.map((d) => textWidth(d.label ?? "", \u540D\u524D\u306E\u7D1A, 0, textMetrics))) + \u540D\u524D\u304B\u3089\u5272\u5408\u307E\u3067 + Math.max(0, ...\u5272\u5408\u306E\u6587\u5B57.map((t) => textWidth(t, \u5272\u5408\u306E\u7D1A, 0, textMetrics)));
26153
26724
  const \u7E26\u304B\u3089 = (node.h - PAD * 2) / 2;
26154
26725
  const \u6A2A\u304B\u3089 = (node.w - PAD * 2 - \u4E00\u89A7\u5E45 - 28) / 2;
26155
26726
  const R = Math.max(24, Math.min(\u7E26\u304B\u3089, \u6A2A\u304B\u3089));
@@ -26235,7 +26806,18 @@ function \u5F27\u306E\u5F62({ node, active, data, \u5272\u5408, x0, y0, drawing,
26235
26806
  })
26236
26807
  ] });
26237
26808
  }
26238
- function \u8868\u306E\u5F62({ node, active, data, \u5272\u5408, x0, y0, drawing, progress, instanceId }) {
26809
+ function \u8868\u306E\u5F62({
26810
+ node,
26811
+ active,
26812
+ data,
26813
+ \u5272\u5408,
26814
+ x0,
26815
+ y0,
26816
+ drawing,
26817
+ progress,
26818
+ instanceId,
26819
+ textMetrics
26820
+ }) {
26239
26821
  const PAD = 20;
26240
26822
  const \u898B\u51FA\u3057\u306E\u7D1A = 11;
26241
26823
  const \u540D\u524D\u306E\u7D1A = 15;
@@ -26244,9 +26826,18 @@ function \u8868\u306E\u5F62({ node, active, data, \u5272\u5408, x0, y0, drawing,
26244
26826
  const \u5370\u304B\u3089\u540D\u524D\u307E\u30672 = 18;
26245
26827
  const \u5272\u5408\u306E\u6587\u5B57 = \u5272\u5408.map(\u5272\u5408\u8868\u8A18);
26246
26828
  const \u5B9F\u6570\u306E\u6587\u5B57 = data.map((d) => \u5B9F\u5024\u8868\u8A18(d.value));
26247
- const \u540D\u524D\u5E45 = Math.max(0, ...data.map((d) => textWidth(d.label ?? "", \u540D\u524D\u306E\u7D1A)));
26248
- const \u5272\u5408\u5E45 = Math.max(textWidth("\u5272\u5408", \u898B\u51FA\u3057\u306E\u7D1A), ...\u5272\u5408\u306E\u6587\u5B57.map((t) => textWidth(t, \u5272\u5408\u306E\u7D1A)));
26249
- const \u5B9F\u6570\u5E45 = Math.max(textWidth("\u5024", \u898B\u51FA\u3057\u306E\u7D1A), ...\u5B9F\u6570\u306E\u6587\u5B57.map((t) => textWidth(t, \u5B9F\u6570\u306E\u7D1A)));
26829
+ const \u540D\u524D\u5E45 = Math.max(
26830
+ 0,
26831
+ ...data.map((d) => textWidth(d.label ?? "", \u540D\u524D\u306E\u7D1A, 0, textMetrics))
26832
+ );
26833
+ const \u5272\u5408\u5E45 = Math.max(
26834
+ textWidth("\u5272\u5408", \u898B\u51FA\u3057\u306E\u7D1A, 0, textMetrics),
26835
+ ...\u5272\u5408\u306E\u6587\u5B57.map((t) => textWidth(t, \u5272\u5408\u306E\u7D1A, 0, textMetrics))
26836
+ );
26837
+ const \u5B9F\u6570\u5E45 = Math.max(
26838
+ textWidth("\u5024", \u898B\u51FA\u3057\u306E\u7D1A, 0, textMetrics),
26839
+ ...\u5B9F\u6570\u306E\u6587\u5B57.map((t) => textWidth(t, \u5B9F\u6570\u306E\u7D1A, 0, textMetrics))
26840
+ );
26250
26841
  const \u8868\u5E45 = 10 + \u5370\u304B\u3089\u540D\u524D\u307E\u30672 + \u540D\u524D\u5E45 + 28 + \u5272\u5408\u5E45 + 24 + \u5B9F\u6570\u5E45;
26251
26842
  const \u7E26\u304B\u3089 = (node.h - PAD * 2) / 2;
26252
26843
  const \u6A2A\u304B\u3089 = (node.w - PAD * 2 - \u8868\u5E45 - 28) / 2;
@@ -26255,8 +26846,8 @@ function \u8868\u306E\u5F62({ node, active, data, \u5272\u5408, x0, y0, drawing,
26255
26846
  const cx = PAD + R;
26256
26847
  const cy = node.h / 2;
26257
26848
  const \u5408\u8A08\u306E\u6587 = \u5B9F\u5024\u8868\u8A18(Math.round(data.reduce((acc, d) => acc + d.value, 0)));
26258
- const \u5408\u8A08\u306E\u5B57 = \u4E2D\u592E\u306E\u5B57(Math.round(R * 0.26), \u5185\u534A\u5F84, \u5408\u8A08\u306E\u6587);
26259
- const \u898B\u51FA\u3057\u306E\u5B572 = \u4E2D\u592E\u306E\u5B57(Math.round(R * 0.12), \u5185\u534A\u5F84, "\u5408\u8A08");
26849
+ const \u5408\u8A08\u306E\u5B57 = \u4E2D\u592E\u306E\u5B57(Math.round(R * 0.26), \u5185\u534A\u5F84, \u5408\u8A08\u306E\u6587, textMetrics);
26850
+ const \u898B\u51FA\u3057\u306E\u5B572 = \u4E2D\u592E\u306E\u5B57(Math.round(R * 0.12), \u5185\u534A\u5F84, "\u5408\u8A08", textMetrics);
26260
26851
  const \u5408\u8A08\u306E\u4E0B = Math.max(Math.round(R * 0.2), \u5408\u8A08\u306E\u5B57 * 0.25 + \u898B\u51FA\u3057\u306E\u5B572 * 0.8);
26261
26852
  const \u8868\u5DE6 = node.w - PAD - \u8868\u5E45;
26262
26853
  const \u53F3\u7AEF = node.w - PAD;
@@ -26387,7 +26978,8 @@ function ChartGaugeNode({
26387
26978
  active,
26388
26979
  stateValues = {},
26389
26980
  drawing = false,
26390
- progress = 1
26981
+ progress = 1,
26982
+ textMetrics = "proportional"
26391
26983
  }) {
26392
26984
  const x0 = node.cx - node.w / 2;
26393
26985
  const y0 = node.cy - node.h / 2;
@@ -26406,7 +26998,10 @@ function ChartGaugeNode({
26406
26998
  const \u533A\u753B\u306E\u9593 = 12;
26407
26999
  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);
26408
27000
  const \u5272\u308A\u4ED8\u3051\u308B = (\u4EF6\u305F\u3061) => {
26409
- 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;
27001
+ const \u5E45 = Math.max(
27002
+ \u5370\u306E\u5E452,
27003
+ ...\u4EF6\u305F\u3061.map((d) => textWidth(\u6570\u5024\u306E\u884C(d), \u6570\u5024\u306E\u7D1A, 0, textMetrics))
27004
+ ) + \u533A\u753B\u306E\u9593;
26410
27005
  const \u884C\u306E\u4EF6\u65702 = Math.min(
26411
27006
  Math.max(1, Math.floor(\u4F7F\u3048\u308B\u5E452 / Math.max(\u5E45, 1))),
26412
27007
  Math.max(\u4EF6\u305F\u3061.length, 1)
@@ -26481,7 +27076,7 @@ function ChartGaugeNode({
26481
27076
  return { d, frac, path: \u6247\u306E\u9053(a0, a1, \u524D\u306E\u5185\u534A\u5F84, \u524D\u306E\u5916\u534A\u5F84) };
26482
27077
  });
26483
27078
  const \u5408\u8A08\u306E\u6587\u5B57 = \u5B9F\u5024\u8868\u8A18(Math.round(total));
26484
- const \u5358\u4F4D\u5E45 = Math.max(textWidth(\u5408\u8A08\u306E\u6587\u5B57, 100), 1) / 100;
27079
+ const \u5358\u4F4D\u5E45 = Math.max(textWidth(\u5408\u8A08\u306E\u6587\u5B57, 100, 0, textMetrics), 1) / 100;
26485
27080
  const \u7D1A\u306E\u5019\u88DC = Math.min(
26486
27081
  // 横 = 字の上の角が内側の円に入る大きさ
26487
27082
  \u5185\u534A\u5F84 / Math.sqrt((\u5358\u4F4D\u5E45 / 2) ** 2 + 1.25 ** 2),
@@ -26574,7 +27169,7 @@ function ChartGaugeNode({
26574
27169
  const y = \u5185\u8A33\u306Ey + \u6BB5\u306E\u9AD8\u3055 * \u6BB5;
26575
27170
  const \u53CE\u307E\u308B\u5E45 = \u5185\u8A33\u306E\u5E45 - \u533A\u753B\u306E\u9593;
26576
27171
  const \u6570\u306E\u884C = \u5185\u8A33\u306E\u6570\u5024[idx] ?? "";
26577
- const \u5207\u3063\u305F\u6570\u306E\u884C = \u5207\u308A\u8A70\u3081\u308B(\u6570\u306E\u884C, \u53CE\u307E\u308B\u5E45, \u6570\u5024\u306E\u7D1A);
27172
+ const \u5207\u3063\u305F\u6570\u306E\u884C = \u5207\u308A\u8A70\u3081\u308B(\u6570\u306E\u884C, \u53CE\u307E\u308B\u5E45, \u6570\u5024\u306E\u7D1A, textMetrics);
26578
27173
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { "data-cdl-role": "chart-gauge-item", children: [
26579
27174
  /* @__PURE__ */ jsxRuntime.jsx(
26580
27175
  "rect",
@@ -26595,7 +27190,7 @@ function ChartGaugeNode({
26595
27190
  fontSize: \u540D\u524D\u306E\u7D1A,
26596
27191
  fontWeight: 700,
26597
27192
  fill: "var(--cdl-text, #1a1f2a)",
26598
- children: \u5207\u308A\u8A70\u3081\u308B(d.label ?? "", \u53CE\u307E\u308B\u5E45, \u540D\u524D\u306E\u7D1A)
27193
+ children: \u5207\u308A\u8A70\u3081\u308B(d.label ?? "", \u53CE\u307E\u308B\u5E45, \u540D\u524D\u306E\u7D1A, textMetrics)
26599
27194
  }
26600
27195
  ),
26601
27196
  /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx(
@@ -26613,12 +27208,12 @@ function ChartGaugeNode({
26613
27208
  function \u6975(cx, cy, r, a) {
26614
27209
  return { x: cx + r * Math.cos(a), y: cy + r * Math.sin(a) };
26615
27210
  }
26616
- function \u5207\u308A\u8A70\u3081\u308B(s, \u4E0A\u9650, \u7D1A) {
26617
- if (\u4E0A\u9650 <= 0 || textWidth(s, \u7D1A) <= \u4E0A\u9650) return s;
26618
- const \u8A18\u53F7\u5E45 = textWidth("\u2026", \u7D1A);
27211
+ function \u5207\u308A\u8A70\u3081\u308B(s, \u4E0A\u9650, \u7D1A, textMetrics = "proportional") {
27212
+ if (\u4E0A\u9650 <= 0 || textWidth(s, \u7D1A, 0, textMetrics) <= \u4E0A\u9650) return s;
27213
+ const \u8A18\u53F7\u5E45 = textWidth("\u2026", \u7D1A, 0, textMetrics);
26619
27214
  let out = "";
26620
27215
  for (const c of s) {
26621
- if (textWidth(out + c, \u7D1A) + \u8A18\u53F7\u5E45 > \u4E0A\u9650) break;
27216
+ if (textWidth(out + c, \u7D1A, 0, textMetrics) + \u8A18\u53F7\u5E45 > \u4E0A\u9650) break;
26622
27217
  out += c;
26623
27218
  }
26624
27219
  return `${out}\u2026`;
@@ -26632,7 +27227,8 @@ function ChartRadialNode({
26632
27227
  active,
26633
27228
  stateValues = {},
26634
27229
  drawing = false,
26635
- progress = 1
27230
+ progress = 1,
27231
+ textMetrics = "proportional"
26636
27232
  }) {
26637
27233
  const x0 = node.cx - node.w / 2;
26638
27234
  const y0 = node.cy - node.h / 2;
@@ -26650,7 +27246,10 @@ function ChartRadialNode({
26650
27246
  const \u4E00\u89A7\u306E\u5E45 = \u5370\u306E\u5E45 + Math.max(
26651
27247
  0,
26652
27248
  ...data.map(
26653
- (d, i) => Math.max(textWidth(d.label ?? "", \u540D\u524D\u306E\u7D1A), textWidth(\u6570\u5024\u306E\u6587\u5B57[i] ?? "", \u6570\u5024\u306E\u7D1A))
27249
+ (d, i) => Math.max(
27250
+ textWidth(d.label ?? "", \u540D\u524D\u306E\u7D1A, 0, textMetrics),
27251
+ textWidth(\u6570\u5024\u306E\u6587\u5B57[i] ?? "", \u6570\u5024\u306E\u7D1A, 0, textMetrics)
27252
+ )
26654
27253
  )
26655
27254
  );
26656
27255
  const \u5F27\u306B\u4F7F\u3048\u308B\u5E45 = node.w - PAD * 2 - \u4E00\u89A7\u306E\u5E45 - \u4E00\u89A7\u3068\u5F27\u306E\u9593;
@@ -26797,7 +27396,8 @@ function arcColor2(tone, idx) {
26797
27396
  function ChartStatNode({
26798
27397
  node,
26799
27398
  active,
26800
- stateValues = {}
27399
+ stateValues = {},
27400
+ textMetrics = "proportional"
26801
27401
  }) {
26802
27402
  const x0 = node.cx - node.w / 2;
26803
27403
  const y0 = node.cy - node.h / 2;
@@ -26826,7 +27426,13 @@ function ChartStatNode({
26826
27426
  const frac = total > 0 ? d.value / total : 0;
26827
27427
  const \u8272 = \u5370\u306E\u8272(d.tone, idx);
26828
27428
  const \u6570\u5024 = \u5B9F\u5024\u8868\u8A18(d.value);
26829
- const \u6570\u5024\u306E\u7D1A = \u53CE\u3081\u308B\u7D1A(\u6570\u5024, \u67A02.w - \u533A\u753B.\u4F59\u767D * 2, \u533A\u753B.\u6570\u5024\u306E\u7D1A, \u533A\u753B.\u540D\u524D\u306E\u7D1A + 1);
27429
+ const \u6570\u5024\u306E\u7D1A = \u53CE\u3081\u308B\u7D1A(
27430
+ \u6570\u5024,
27431
+ \u67A02.w - \u533A\u753B.\u4F59\u767D * 2,
27432
+ \u533A\u753B.\u6570\u5024\u306E\u7D1A,
27433
+ \u533A\u753B.\u540D\u524D\u306E\u7D1A + 1,
27434
+ textMetrics
27435
+ );
26830
27436
  return /* @__PURE__ */ jsxRuntime.jsxs(
26831
27437
  "g",
26832
27438
  {
@@ -26883,7 +27489,8 @@ function ChartStatNode({
26883
27489
  `\u524D ${\u5B9F\u5024\u8868\u8A18(d.previous)}`,
26884
27490
  \u67A02.w - \u533A\u753B.\u4F59\u767D * 2,
26885
27491
  \u533A\u753B.\u524D\u306E\u7D1A,
26886
- 8
27492
+ 8,
27493
+ textMetrics
26887
27494
  ),
26888
27495
  textAnchor: "middle",
26889
27496
  fill: "var(--cdl-text-dim, #5a6270)",
@@ -26972,9 +27579,9 @@ function \u533A\u753B\u306E\u5272\u4ED8(w, h, \u4EF6\u6570, \u524D\u3092\u51FA\u
26972
27579
  \u67A0: (idx) => ({ x: \u5E45 * idx, y: 0, w: \u5E45, h })
26973
27580
  };
26974
27581
  }
26975
- function \u53CE\u3081\u308B\u7D1A(\u5B572, \u4F7F\u3048\u308B\u5E452, \u521D\u671F, \u4E0B\u9650) {
27582
+ function \u53CE\u3081\u308B\u7D1A(\u5B572, \u4F7F\u3048\u308B\u5E452, \u521D\u671F, \u4E0B\u9650, textMetrics = "proportional") {
26976
27583
  let \u7D1A = \u521D\u671F;
26977
- while (\u7D1A > \u4E0B\u9650 && textWidth(\u5B572, \u7D1A) > \u4F7F\u3048\u308B\u5E452) \u7D1A -= 1;
27584
+ while (\u7D1A > \u4E0B\u9650 && textWidth(\u5B572, \u7D1A, 0, textMetrics) > \u4F7F\u3048\u308B\u5E452) \u7D1A -= 1;
26978
27585
  return \u7D1A;
26979
27586
  }
26980
27587
  function \u5F27\u306E\u90533(cx, cy, r, \u5272\u5408) {
@@ -27009,7 +27616,8 @@ function ChartWaffleNode({
27009
27616
  active,
27010
27617
  stateValues = {},
27011
27618
  drawing = false,
27012
- progress = 1
27619
+ progress = 1,
27620
+ textMetrics = "proportional"
27013
27621
  }) {
27014
27622
  const x0 = node.cx - node.w / 2;
27015
27623
  const y0 = node.cy - node.h / 2;
@@ -27028,7 +27636,10 @@ function ChartWaffleNode({
27028
27636
  const \u4E00\u89A7\u306E\u5E45 = \u5370\u306E\u5E452 + Math.max(
27029
27637
  0,
27030
27638
  ...data.map(
27031
- (d, i) => Math.max(textWidth(d.label ?? "", \u540D\u524D\u306E\u7D1A), textWidth(\u6570\u5024\u306E\u6587\u5B57[i] ?? "", \u6570\u5024\u306E\u7D1A))
27639
+ (d, i) => Math.max(
27640
+ textWidth(d.label ?? "", \u540D\u524D\u306E\u7D1A, 0, textMetrics),
27641
+ textWidth(\u6570\u5024\u306E\u6587\u5B57[i] ?? "", \u6570\u5024\u306E\u7D1A, 0, textMetrics)
27642
+ )
27032
27643
  )
27033
27644
  );
27034
27645
  const \u4F7F\u3048\u308B\u9AD8\u3055 = node.h - PAD * 2;
@@ -27130,7 +27741,8 @@ function ChartStackedBarNode({
27130
27741
  active,
27131
27742
  stateValues = {},
27132
27743
  drawing = false,
27133
- progress = 1
27744
+ progress = 1,
27745
+ textMetrics = "proportional"
27134
27746
  }) {
27135
27747
  const x0 = node.cx - node.w / 2;
27136
27748
  const y0 = node.cy - node.h / 2;
@@ -27140,7 +27752,7 @@ function ChartStackedBarNode({
27140
27752
  const \u540D\u524D\u306E\u7D1A = 13;
27141
27753
  const \u533A\u753B\u306E\u7D1A = 12;
27142
27754
  const \u6642\u70B9\u306E\u7D1A = 13;
27143
- const \u6642\u70B9\u306E\u5E45 = Math.max(0, ...\u5E2F\u305F\u3061.map((b) => textWidth(b.\u540D\u524D, \u6642\u70B9\u306E\u7D1A))) + (\u5E2F\u305F\u3061.length > 1 ? 16 : 0);
27755
+ const \u6642\u70B9\u306E\u5E45 = Math.max(0, ...\u5E2F\u305F\u3061.map((b) => textWidth(b.\u540D\u524D, \u6642\u70B9\u306E\u7D1A, 0, textMetrics))) + (\u5E2F\u305F\u3061.length > 1 ? 16 : 0);
27144
27756
  const \u5E2F\u306E\u5DE6 = PAD + \u6642\u70B9\u306E\u5E45;
27145
27757
  const \u5E2F\u306E\u5E45 = Math.max(40, node.w - \u5E2F\u306E\u5DE6 - PAD);
27146
27758
  const \u5E2F\u306E\u9AD8\u3055 = 44;
@@ -27233,7 +27845,7 @@ function ChartStackedBarNode({
27233
27845
  })()
27234
27846
  ] }, `bar-${\u6BB5}`);
27235
27847
  }),
27236
- \u4E00\u89A7\u306E\u4E26\u3073(data, \u5E2F\u306E\u5DE6, node.w - PAD, \u540D\u524D\u306E\u7D1A).map(({ d, idx, x, \u884C }) => {
27848
+ \u4E00\u89A7\u306E\u4E26\u3073(data, \u5E2F\u306E\u5DE6, node.w - PAD, \u540D\u524D\u306E\u7D1A, textMetrics).map(({ d, idx, x, \u884C }) => {
27237
27849
  const y = \u4E0A\u7AEF + \u5E2F\u305F\u3061.length * (\u5E2F\u306E\u9AD8\u3055 + \u5E2F\u306E\u9593) - \u5E2F\u306E\u9593 + 16 + \u4E00\u89A7\u306E\u9AD8\u3055 / 2 + \u884C * \u4E00\u89A7\u306E\u9AD8\u3055;
27238
27850
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { "data-cdl-role": "chart-stacked-bar-legend", children: [
27239
27851
  /* @__PURE__ */ jsxRuntime.jsx("rect", { x, y: y - 5, width: 10, height: 10, rx: 2, fill: \u5370\u306E\u82723(d.tone, idx) }),
@@ -27268,12 +27880,12 @@ function \u5370\u306E\u82723(tone, idx) {
27268
27880
  }
27269
27881
  var \u5370\u304B\u3089\u540D\u524D\u307E\u3067 = 16;
27270
27882
  var \u4EF6\u306E\u9593 = 10;
27271
- function \u4E00\u89A7\u306E\u4E26\u3073(data, \u5DE6, \u53F3\u7AEF, \u7D1A) {
27883
+ function \u4E00\u89A7\u306E\u4E26\u3073(data, \u5DE6, \u53F3\u7AEF, \u7D1A, textMetrics = "proportional") {
27272
27884
  const out = [];
27273
27885
  let x = \u5DE6;
27274
27886
  let \u884C = 0;
27275
27887
  data.forEach((d, idx) => {
27276
- const \u5E45 = \u5370\u304B\u3089\u540D\u524D\u307E\u3067 + textWidth(d.label ?? "", \u7D1A);
27888
+ const \u5E45 = \u5370\u304B\u3089\u540D\u524D\u307E\u3067 + textWidth(d.label ?? "", \u7D1A, 0, textMetrics);
27277
27889
  if (x > \u5DE6 && x + \u5E45 > \u53F3\u7AEF) {
27278
27890
  \u884C += 1;
27279
27891
  x = \u5DE6;
@@ -27289,7 +27901,8 @@ function ChartSlopeNode({
27289
27901
  active,
27290
27902
  stateValues = {},
27291
27903
  drawing = false,
27292
- progress = 1
27904
+ progress = 1,
27905
+ textMetrics = "proportional"
27293
27906
  }) {
27294
27907
  const x0 = node.cx - node.w / 2;
27295
27908
  const y0 = node.cy - node.h / 2;
@@ -27332,16 +27945,22 @@ function ChartSlopeNode({
27332
27945
  const \u53F3\u306E\u5B57 = \u7CFB\u5217\u305F\u3061.map(
27333
27946
  (s) => \u5F62 === "delta" ? \u5897\u6E1B\u8868\u8A18(s.\u524D, s.\u4ECA) : \u5B9F\u5024\u8868\u8A18(s.\u4ECA)
27334
27947
  );
27335
- const \u5DE6\u5024\u5E45 = Math.max(0, ...\u5DE6\u306E\u5B57.map((t) => textWidth(t, \u5024\u306E\u7D1A)));
27336
- const \u53F3\u5024\u5E45 = Math.max(0, ...\u53F3\u306E\u5B57.map((t) => textWidth(t, \u5024\u306E\u7D1A)));
27948
+ const \u5DE6\u5024\u5E45 = Math.max(0, ...\u5DE6\u306E\u5B57.map((t) => textWidth(t, \u5024\u306E\u7D1A, 0, textMetrics)));
27949
+ const \u53F3\u5024\u5E45 = Math.max(0, ...\u53F3\u306E\u5B57.map((t) => textWidth(t, \u5024\u306E\u7D1A, 0, textMetrics)));
27337
27950
  const \u540D\u524D\u306B\u4F7F\u3048\u308B = Math.max(
27338
27951
  0,
27339
27952
  (node.w - PAD * 2 - \u7DDA\u306E\u6700\u5C0F\u5E45 - (\u5DE6\u5024\u5E45 + \u8EF8\u304B\u3089\u5024\u307E\u3067 + \u5024\u304B\u3089\u540D\u524D\u307E\u3067) - (\u53F3\u5024\u5E45 + \u8EF8\u304B\u3089\u5024\u307E\u3067 + \u5024\u304B\u3089\u540D\u524D\u307E\u3067)) / 2
27340
27953
  );
27341
- const \u540D\u524D\u306E\u7D1A = \u53CE\u3081\u308B\u7D1A2(\u7CFB\u5217\u305F\u3061.map((s) => s.\u540D\u524D), \u540D\u524D\u306B\u4F7F\u3048\u308B, \u540D\u524D\u306E\u4E0A\u9650\u7D1A, \u540D\u524D\u306E\u4E0B\u9650\u7D1A);
27954
+ const \u540D\u524D\u306E\u7D1A = \u53CE\u3081\u308B\u7D1A2(
27955
+ \u7CFB\u5217\u305F\u3061.map((s) => s.\u540D\u524D),
27956
+ \u540D\u524D\u306B\u4F7F\u3048\u308B,
27957
+ \u540D\u524D\u306E\u4E0A\u9650\u7D1A,
27958
+ \u540D\u524D\u306E\u4E0B\u9650\u7D1A,
27959
+ textMetrics
27960
+ );
27342
27961
  const \u540D\u524D\u5E45 = Math.min(
27343
27962
  \u540D\u524D\u306B\u4F7F\u3048\u308B,
27344
- Math.max(0, ...\u7CFB\u5217\u305F\u3061.map((s) => textWidth(s.\u540D\u524D, \u540D\u524D\u306E\u7D1A)))
27963
+ Math.max(0, ...\u7CFB\u5217\u305F\u3061.map((s) => textWidth(s.\u540D\u524D, \u540D\u524D\u306E\u7D1A, 0, textMetrics)))
27345
27964
  );
27346
27965
  const \u5DE6\u306E\u4F59\u767D = \u540D\u524D\u5E45 + \u5024\u304B\u3089\u540D\u524D\u307E\u3067 + \u5DE6\u5024\u5E45 + \u8EF8\u304B\u3089\u5024\u307E\u3067;
27347
27966
  const \u53F3\u306E\u4F59\u767D = \u8EF8\u304B\u3089\u5024\u307E\u3067 + \u53F3\u5024\u5E45 + \u5024\u304B\u3089\u540D\u524D\u307E\u3067 + \u540D\u524D\u5E45;
@@ -27527,10 +28146,12 @@ function \u5370\u306E\u82724(tone, idx) {
27527
28146
  if (tone) return TONE[tone];
27528
28147
  return chartSeriesColor(idx);
27529
28148
  }
27530
- function \u53CE\u3081\u308B\u7D1A2(\u540D\u524D\u305F\u3061, \u5E45, \u4E0A\u9650, \u4E0B\u9650) {
28149
+ function \u53CE\u3081\u308B\u7D1A2(\u540D\u524D\u305F\u3061, \u5E45, \u4E0A\u9650, \u4E0B\u9650, textMetrics = "proportional") {
27531
28150
  if (\u540D\u524D\u305F\u3061.length === 0) return \u4E0A\u9650;
27532
28151
  let \u7D1A = \u4E0A\u9650;
27533
- while (\u7D1A > \u4E0B\u9650 && Math.max(...\u540D\u524D\u305F\u3061.map((n) => textWidth(n, \u7D1A))) > \u5E45) \u7D1A -= 1;
28152
+ while (\u7D1A > \u4E0B\u9650 && Math.max(...\u540D\u524D\u305F\u3061.map((n) => textWidth(n, \u7D1A, 0, textMetrics))) > \u5E45) {
28153
+ \u7D1A -= 1;
28154
+ }
27534
28155
  return \u7D1A;
27535
28156
  }
27536
28157
  function \u5C0F\u6570\u306E\u6841(n) {
@@ -27578,6 +28199,7 @@ function ChartBarNode({
27578
28199
  return { y: yAt(v), value: v };
27579
28200
  });
27580
28201
  const \u6FC3\u3055 = (v) => vMax > 0 ? v >= vMax ? 1 : 0.45 : 0.9;
28202
+ const \u4E3B\u5F79\u306E\u68D2\u304B = (v) => vMax > 0 && v >= vMax;
27581
28203
  const \u89D2\u4E38 = Math.min(barW * 0.06, 8);
27582
28204
  const \u4F38\u3073 = \u9032\u307F\u3092\u7573\u3080(drawing, progress);
27583
28205
  const \u6A2A\u8EF8\u306Ey = PAD_TOP2 + canvasH;
@@ -27644,6 +28266,7 @@ function ChartBarNode({
27644
28266
  {
27645
28267
  "data-cdl-role": "chart-bar",
27646
28268
  "data-cdl-unresolved": d.unresolved ? "true" : void 0,
28269
+ "data-cdl-emphasis": \u4E3B\u5F79\u306E\u68D2\u304B(d.value) ? "primary" : void 0,
27647
28270
  x: bx,
27648
28271
  y: by,
27649
28272
  width: barW,
@@ -27990,7 +28613,8 @@ function FunnelNode({
27990
28613
  active,
27991
28614
  stateValues = {},
27992
28615
  drawing = false,
27993
- progress = 1
28616
+ progress = 1,
28617
+ textMetrics = "proportional"
27994
28618
  }) {
27995
28619
  const x0 = node.cx - node.w / 2;
27996
28620
  const y0 = node.cy - node.h / 2;
@@ -28039,7 +28663,11 @@ function FunnelNode({
28039
28663
  const \u540D\u524D\u306E\u5B9F\u5B57 = \u540D\u524D\u306E\u5B57 * \u7E26\u500D;
28040
28664
  const \u88DC\u8DB3\u306E\u67A0\u5B57 = \u88DC\u8DB3\u306E\u5B57 * \u7E26\u500D;
28041
28665
  const \u53CE\u307E\u308B\u5E45 = Math.max(0, bottomW - 16);
28042
- 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);
28666
+ const \u88DC\u8DB3\u306E\u5B9F\u5B57 = \u88DC\u8DB3\u306E\u67A0\u5B57 * \u53CE\u3081\u308B\u500D\u7387(
28667
+ \u88DC\u8DB3,
28668
+ { fontSize: \u88DC\u8DB3\u306E\u67A0\u5B57, fontWeight: 500, textMetrics },
28669
+ \u53CE\u307E\u308B\u5E45
28670
+ );
28043
28671
  const \u584A\u306E\u4E0A = y + stageH / 2 - (\u540D\u524D\u306E\u5B9F\u5B57 * 1.2 + \u88DC\u8DB3\u306E\u67A0\u5B57 * 1.25) / 2;
28044
28672
  const \u540D\u524D\u306Ey = \u88DC\u8DB3\u3042\u308A ? \u584A\u306E\u4E0A + \u540D\u524D\u306E\u5B9F\u5B57 * 0.95 : y + stageH / 2 + 5;
28045
28673
  const \u88DC\u8DB3\u306Ey = \u584A\u306E\u4E0A + \u540D\u524D\u306E\u5B9F\u5B57 * 1.2 + \u88DC\u8DB3\u306E\u67A0\u5B57 * 0.95;
@@ -28142,7 +28770,8 @@ function \u7573\u3093\u3060\u6587(\u4EF6\u6570) {
28142
28770
  function QuadrantNode({
28143
28771
  node,
28144
28772
  active,
28145
- stateValues = {}
28773
+ stateValues = {},
28774
+ textMetrics = "proportional"
28146
28775
  }) {
28147
28776
  const x0 = node.cx - node.w / 2;
28148
28777
  const y0 = node.cy - node.h / 2;
@@ -28161,7 +28790,10 @@ function QuadrantNode({
28161
28790
  const SUB_FONT = 10;
28162
28791
  const axisLabelPad = (text) => Math.max(
28163
28792
  PAD_MIN,
28164
- measureTextWidth(`\u2190 ${text}`, { fontSize: AXIS_LABEL_FONT}) + 12
28793
+ measureTextWidth(`\u2190 ${text}`, {
28794
+ fontSize: AXIS_LABEL_FONT,
28795
+ textMetrics
28796
+ }) + 12
28165
28797
  );
28166
28798
  const padBudget = Math.max(0, node.w * 0.5 - PAD_MIN * 2);
28167
28799
  const wantLeft = axisLabelPad(data.xAxis.left) - PAD_MIN;
@@ -28415,7 +29047,11 @@ function QuadrantNode({
28415
29047
  ITEM_MIN_W,
28416
29048
  Math.max(
28417
29049
  ...\u884C\u30892.map(
28418
- (r) => measureTextWidth(r.text, { fontSize: r.size, fontWeight: r.weight })
29050
+ (r) => measureTextWidth(r.text, {
29051
+ fontSize: r.size,
29052
+ fontWeight: r.weight,
29053
+ textMetrics
29054
+ })
28419
29055
  )
28420
29056
  ) + ITEM_PAD_X * 2
28421
29057
  )
@@ -28441,7 +29077,7 @@ function QuadrantNode({
28441
29077
  const \u88DC\u8DB3 = (it.subtitle ?? "").trim();
28442
29078
  const \u88DC\u8DB3\u306E\u5B57 = SUB_FONT * \u53CE\u3081\u308B\u500D\u7387(
28443
29079
  \u88DC\u8DB3,
28444
- { fontSize: SUB_FONT, fontWeight: 500 },
29080
+ { fontSize: SUB_FONT, fontWeight: 500, textMetrics },
28445
29081
  Math.max(0, \u5E45 - ITEM_PAD_X * 2)
28446
29082
  );
28447
29083
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
@@ -28845,24 +29481,30 @@ var EYEBROW_GAP2 = 8;
28845
29481
  var EYEBROW_TRACKING = 2;
28846
29482
  var SUB_SIZE = 11;
28847
29483
  var SUB_GAP = 4;
28848
- function labelBlock(node, pos, size, band) {
29484
+ function labelBlock(node, pos, size, band, textMetrics = "proportional") {
28849
29485
  const \u4E0A = node.eyebrow ? size + EYEBROW_GAP2 + EYEBROW_SIZE2 * ASCENT2 : size * ASCENT2;
28850
29486
  const \u4E0B = node.subtitle ? size + SUB_GAP + SUB_SIZE * DESCENT2 : size * DESCENT2;
28851
29487
  const \u5E45 = Math.max(
28852
- textWidth(node.title ?? "", size),
28853
- node.eyebrow ? textWidth(node.eyebrow, EYEBROW_SIZE2, EYEBROW_TRACKING) : 0,
28854
- node.subtitle ? textWidth(node.subtitle, SUB_SIZE) : 0
29488
+ textWidth(node.title ?? "", size, 0, textMetrics),
29489
+ node.eyebrow ? textWidth(node.eyebrow, EYEBROW_SIZE2, EYEBROW_TRACKING, textMetrics) : 0,
29490
+ node.subtitle ? textWidth(node.subtitle, SUB_SIZE, 0, textMetrics) : 0
28855
29491
  );
28856
- const \u984C\u5E45 = textWidth(node.title ?? "", size);
28857
- const \u4E0B\u9650 = \u984C\u5E45 >= \u5E45 ? \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(node.title ?? "", size, 0, band.w, textWidth) : 0;
29492
+ const \u984C\u5E45 = textWidth(node.title ?? "", size, 0, textMetrics);
29493
+ const \u6E2C\u308B = (t, s, ls) => textWidth(t, s, ls, textMetrics);
29494
+ const \u4E0B\u9650 = \u984C\u5E45 >= \u5E45 ? \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(node.title ?? "", size, 0, band.w, \u6E2C\u308B) : 0;
28858
29495
  const { k, x, y: baseline } = fitLabel(band, { \u4E0A, \u4E0B, \u5E45 }, pos, \u4E0B\u9650);
28859
29496
  return { k, x, baseline, \u4E0A\u7AEF: baseline - \u4E0A * k, \u4E0B\u7AEF: baseline + \u4E0B * k };
28860
29497
  }
28861
- function commonLabel(node, pos, size, band) {
28862
- const \u584A = labelBlock(node, pos, size, band);
29498
+ function commonLabel(node, pos, size, band, textMetrics = "proportional") {
29499
+ const \u584A = labelBlock(node, pos, size, band, textMetrics);
28863
29500
  const k = \u584A.k;
28864
29501
  const x = \u584A.x;
28865
- const \u5207\u308B = (t, \u5927\u304D\u3055, \u5B57\u9593 = 0) => \u5E2F\u3067\u5207\u308B(t, \u5927\u304D\u3055 * k, band.w, (u, f) => textWidth(u, f, \u5B57\u9593 * k));
29502
+ const \u5207\u308B = (t, \u5927\u304D\u3055, \u5B57\u9593 = 0) => \u5E2F\u3067\u5207\u308B(
29503
+ t,
29504
+ \u5927\u304D\u3055 * k,
29505
+ band.w,
29506
+ (u, f) => textWidth(u, f, \u5B57\u9593 * k, textMetrics)
29507
+ );
28866
29508
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
28867
29509
  node.eyebrow && /* @__PURE__ */ jsxRuntime.jsx(
28868
29510
  "text",
@@ -28913,7 +29555,7 @@ var RULE_GAP_RATIO = 0.1;
28913
29555
  var RULE_PAD_MAX = 20;
28914
29556
  var RULE_PAD_RATIO = 0.14;
28915
29557
  var RULE_SHRINK_RATIO = 0.055;
28916
- function ShapeFileNode({ node, active }) {
29558
+ function ShapeFileNode({ node, active, textMetrics = "proportional" }) {
28917
29559
  const \u5E2F = bodyBand(node, { \u5F71ry: SHADOW_RY });
28918
29560
  const \u7D19h = \u5E2F.h;
28919
29561
  const \u7D19w = Math.min(\u5E2F.w, \u7D19h * 0.72);
@@ -28933,7 +29575,7 @@ function ShapeFileNode({ node, active }) {
28933
29575
  const foldTriangle = `M ${x + \u7D19w - fold} ${y} L ${x + \u7D19w} ${y + fold} L ${x + \u7D19w - fold} ${y + fold} Z`;
28934
29576
  const \u540D\u524D\u5E2F = { x, y, w: \u7D19w, h: \u7D19h };
28935
29577
  const \u540D\u524D\u4F4D\u7F6E = { x: \u5E2F.cx, y: node.cy + node.h * 0.12 };
28936
- const \u540D\u524D = labelBlock(node, \u540D\u524D\u4F4D\u7F6E, 16, \u540D\u524D\u5E2F);
29578
+ const \u540D\u524D = labelBlock(node, \u540D\u524D\u4F4D\u7F6E, 16, \u540D\u524D\u5E2F, textMetrics);
28937
29579
  const \u9593\u9694 = Math.min(RULE_GAP_MAX, \u7D19h * RULE_GAP_RATIO);
28938
29580
  const \u7DDA\u4F59\u767D = Math.min(RULE_PAD_MAX, \u7D19w * RULE_PAD_RATIO);
28939
29581
  const textLines = [0, 1, 2].map((i) => ({ i, ly: y + fold + \u9593\u9694 * (i + 1) })).filter(({ ly }) => ly < \u540D\u524D.\u4E0A\u7AEF);
@@ -28965,12 +29607,12 @@ function ShapeFileNode({ node, active }) {
28965
29607
  i
28966
29608
  );
28967
29609
  }),
28968
- commonLabel(node, \u540D\u524D\u4F4D\u7F6E, 16, \u540D\u524D\u5E2F)
29610
+ commonLabel(node, \u540D\u524D\u4F4D\u7F6E, 16, \u540D\u524D\u5E2F, textMetrics)
28969
29611
  ] });
28970
29612
  }
28971
29613
  var TAB_H_MAX = 22;
28972
29614
  var TAB_H_RATIO = 0.3;
28973
- function ShapeFolderNode({ node, active }) {
29615
+ function ShapeFolderNode({ node, active, textMetrics = "proportional" }) {
28974
29616
  const \u5E2F = bodyBand(node, { \u5F71ry: SHADOW_RY });
28975
29617
  const x = \u5E2F.x;
28976
29618
  const y = \u5E2F.y;
@@ -28991,7 +29633,7 @@ function ShapeFolderNode({ node, active }) {
28991
29633
  const \u5883\u754Cy = y + tabH + Math.min(8, (\u5E2F.h - tabH) * 0.2);
28992
29634
  const \u7AEF = Math.min(6, \u5E2F.w * 0.1);
28993
29635
  const \u540D\u524D\u4F4D\u7F6E = { x: \u5E2F.cx, y: node.cy + 18 };
28994
- const \u540D\u524D = labelBlock(node, \u540D\u524D\u4F4D\u7F6E, 16, \u5E2F);
29636
+ const \u540D\u524D = labelBlock(node, \u540D\u524D\u4F4D\u7F6E, 16, \u5E2F, textMetrics);
28995
29637
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
28996
29638
  dropShadow(\u5E2F.cx, \u5E2F.\u5E95, \u5E2F.w * 0.44),
28997
29639
  /* @__PURE__ */ jsxRuntime.jsx("path", { "data-cdl-role": "node-body", d: bodyPath, ...frame, strokeLinejoin: "round" }),
@@ -29007,13 +29649,13 @@ function ShapeFolderNode({ node, active }) {
29007
29649
  opacity: 0.35
29008
29650
  }
29009
29651
  ),
29010
- commonLabel(node, \u540D\u524D\u4F4D\u7F6E, 16, \u5E2F)
29652
+ commonLabel(node, \u540D\u524D\u4F4D\u7F6E, 16, \u5E2F, textMetrics)
29011
29653
  ] });
29012
29654
  }
29013
29655
  var CLOUD_VB_W = 640;
29014
29656
  var CLOUD_VB_H = 512;
29015
29657
  var CLOUD_W_RATIO = 0.9;
29016
- function ShapeCloudNode({ node, active }) {
29658
+ function ShapeCloudNode({ node, active, textMetrics = "proportional" }) {
29017
29659
  const \u5E2F = bodyBand(node, { \u5F71ry: SHADOW_RY });
29018
29660
  const frame = commonFrame(active);
29019
29661
  const \u7D20\u306E\u500D\u7387 = Math.min(\u5E2F.h / CLOUD_VB_H, \u5E2F.w * CLOUD_W_RATIO / CLOUD_VB_W);
@@ -29036,13 +29678,13 @@ function ShapeCloudNode({ node, active }) {
29036
29678
  strokeLinejoin: "round"
29037
29679
  }
29038
29680
  ) }),
29039
- commonLabel(node, { x: \u5E2F.cx, y: node.cy + node.h * 0.05 }, 16, \u5E2F)
29681
+ commonLabel(node, { x: \u5E2F.cx, y: node.cy + node.h * 0.05 }, 16, \u5E2F, textMetrics)
29040
29682
  ] });
29041
29683
  }
29042
29684
  var CYLINDER_RY_MAX = 18;
29043
29685
  var CYLINDER_RY_RATIO = 0.1;
29044
29686
  var CYLINDER_DISKS = [0.3, 0.55, 0.8];
29045
- function ShapeCylinderNode({ node, active }) {
29687
+ function ShapeCylinderNode({ node, active, textMetrics = "proportional" }) {
29046
29688
  const \u5E2F = bodyBand(node, { \u5F71ry: CYLINDER_SHADOW_RY });
29047
29689
  const x = \u5E2F.x;
29048
29690
  const y = \u5E2F.y;
@@ -29059,7 +29701,7 @@ function ShapeCylinderNode({ node, active }) {
29059
29701
  const \u84CB\u5E95 = y + ry * 2;
29060
29702
  const \u540D\u524D\u4F4D\u7F6E = { x: \u5E2F.cx, y: node.cy + 6 };
29061
29703
  const \u540D\u524D\u5E2F = { x: \u5E2F.x, y: \u84CB\u5E95, w: \u5E2F.w, h: Math.max(0, \u5E2F.\u5E95 - \u84CB\u5E95) };
29062
- const \u540D\u524D = labelBlock(node, \u540D\u524D\u4F4D\u7F6E, 15, \u540D\u524D\u5E2F);
29704
+ const \u540D\u524D = labelBlock(node, \u540D\u524D\u4F4D\u7F6E, 15, \u540D\u524D\u5E2F, textMetrics);
29063
29705
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
29064
29706
  dropShadow(\u5E2F.cx, \u5E2F.\u5E95, rx * 0.85, CYLINDER_SHADOW_RY),
29065
29707
  /* @__PURE__ */ jsxRuntime.jsx("path", { "data-cdl-role": "node-body", d: bodyPath, ...frame, strokeLinejoin: "round" }),
@@ -29083,11 +29725,11 @@ function ShapeCylinderNode({ node, active }) {
29083
29725
  },
29084
29726
  i
29085
29727
  )),
29086
- commonLabel(node, \u540D\u524D\u4F4D\u7F6E, 15, \u540D\u524D\u5E2F)
29728
+ commonLabel(node, \u540D\u524D\u4F4D\u7F6E, 15, \u540D\u524D\u5E2F, textMetrics)
29087
29729
  ] });
29088
29730
  }
29089
29731
  var HEX_DOT_R = 2.5;
29090
- function ShapeHexagonNode({ node, active }) {
29732
+ function ShapeHexagonNode({ node, active, textMetrics = "proportional" }) {
29091
29733
  const \u5E2F = bodyBand(node, { \u5F71ry: SHADOW_RY, \u5916: Math.max(HEX_DOT_R, FRAME_HALF) });
29092
29734
  const cx = \u5E2F.cx;
29093
29735
  const cy = \u5E2F.cy;
@@ -29110,11 +29752,12 @@ function ShapeHexagonNode({ node, active }) {
29110
29752
  node,
29111
29753
  { x: cx, y: node.cy + 6 },
29112
29754
  16,
29113
- { x: \u5E2F.x + cut, y: \u5E2F.y, w: Math.max(0, \u5E2F.w - cut * 2), h: \u5E2F.h }
29755
+ { x: \u5E2F.x + cut, y: \u5E2F.y, w: Math.max(0, \u5E2F.w - cut * 2), h: \u5E2F.h },
29756
+ textMetrics
29114
29757
  )
29115
29758
  ] });
29116
29759
  }
29117
- function ShapeDiamondNode({ node, active }) {
29760
+ function ShapeDiamondNode({ node, active, textMetrics = "proportional" }) {
29118
29761
  const \u5E2F = bodyBand(node, { \u5F71ry: SHADOW_RY });
29119
29762
  const cx = \u5E2F.cx;
29120
29763
  const cy = \u5E2F.cy;
@@ -29155,13 +29798,14 @@ function ShapeDiamondNode({ node, active }) {
29155
29798
  y: cy - \u5E2F.h * innerScale / 4,
29156
29799
  w: \u5E2F.w * innerScale / 2,
29157
29800
  h: \u5E2F.h * innerScale / 2
29158
- }
29801
+ },
29802
+ textMetrics
29159
29803
  )
29160
29804
  ] });
29161
29805
  }
29162
29806
  var STACK_OFFSET_MAX = 12;
29163
29807
  var STACK_OFFSET_RATIO = 0.15;
29164
- function ShapeStackNode({ node, active }) {
29808
+ function ShapeStackNode({ node, active, textMetrics = "proportional" }) {
29165
29809
  const \u5E2F = bodyBand(node, { \u5F71ry: SHADOW_RY });
29166
29810
  const x = \u5E2F.x;
29167
29811
  const y = \u5E2F.y;
@@ -29215,7 +29859,8 @@ function ShapeStackNode({ node, active }) {
29215
29859
  node,
29216
29860
  { x: \u624B\u524Dcx, y: node.cy + \u305A\u308C + 6 },
29217
29861
  15,
29218
- { x, y: y + \u305A\u308C * 2, w: cardW, h: cardH }
29862
+ { x, y: y + \u305A\u308C * 2, w: cardW, h: cardH },
29863
+ textMetrics
29219
29864
  )
29220
29865
  ] });
29221
29866
  }
@@ -29227,16 +29872,22 @@ var PERSON_BODY_LEN = 90;
29227
29872
  var PERSON_SHADOW_DY = 20;
29228
29873
  var PERSON_SHADOW_RY = 4;
29229
29874
  var PERSON_SHADOW_RX = 55;
29230
- function planLabel(node, cx, \u5E45\u4E0A\u9650, plan) {
29875
+ function planLabel(node, cx, \u5E45\u4E0A\u9650, plan, textMetrics = "proportional") {
29231
29876
  const \u5E45 = Math.max(
29232
- textWidth(node.title ?? "", plan.\u540D\u524D.size),
29233
- node.eyebrow && plan.\u80A9\u66F8 ? textWidth(node.eyebrow, plan.\u80A9\u66F8.size, EYEBROW_TRACKING) : 0,
29234
- node.subtitle && plan.\u8AAC\u660E ? textWidth(node.subtitle, plan.\u8AAC\u660E.size) : 0
29877
+ textWidth(node.title ?? "", plan.\u540D\u524D.size, 0, textMetrics),
29878
+ node.eyebrow && plan.\u80A9\u66F8 ? textWidth(node.eyebrow, plan.\u80A9\u66F8.size, EYEBROW_TRACKING, textMetrics) : 0,
29879
+ node.subtitle && plan.\u8AAC\u660E ? textWidth(node.subtitle, plan.\u8AAC\u660E.size, 0, textMetrics) : 0
29235
29880
  );
29236
- const \u984C\u5E45 = textWidth(node.title ?? "", plan.\u540D\u524D.size);
29237
- const \u4E0B\u9650 = \u984C\u5E45 >= \u5E45 ? \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(node.title ?? "", plan.\u540D\u524D.size, 0, \u5E45\u4E0A\u9650, textWidth) : 0;
29881
+ const \u984C\u5E45 = textWidth(node.title ?? "", plan.\u540D\u524D.size, 0, textMetrics);
29882
+ const \u6E2C\u308B = (t, s, ls) => textWidth(t, s, ls, textMetrics);
29883
+ const \u4E0B\u9650 = \u984C\u5E45 >= \u5E45 ? \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(node.title ?? "", plan.\u540D\u524D.size, 0, \u5E45\u4E0A\u9650, \u6E2C\u308B) : 0;
29238
29884
  const k = \u5E45 > 0 && \u5E45\u4E0A\u9650 > 0 ? Math.min(1, Math.max(\u5E45\u4E0A\u9650 / \u5E45, \u4E0B\u9650)) : 1;
29239
- const \u5207\u308B = (t, \u5927\u304D\u3055, \u5B57\u9593 = 0) => \u5E2F\u3067\u5207\u308B(t, \u5927\u304D\u3055 * k, \u5E45\u4E0A\u9650, (u, f) => textWidth(u, f, \u5B57\u9593 * k));
29885
+ const \u5207\u308B = (t, \u5927\u304D\u3055, \u5B57\u9593 = 0) => \u5E2F\u3067\u5207\u308B(
29886
+ t,
29887
+ \u5927\u304D\u3055 * k,
29888
+ \u5E45\u4E0A\u9650,
29889
+ (u, f) => textWidth(u, f, \u5B57\u9593 * k, textMetrics)
29890
+ );
29240
29891
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
29241
29892
  node.eyebrow && plan.\u80A9\u66F8 && /* @__PURE__ */ jsxRuntime.jsx(
29242
29893
  "text",
@@ -29277,7 +29928,7 @@ function planLabel(node, cx, \u5E45\u4E0A\u9650, plan) {
29277
29928
  )
29278
29929
  ] });
29279
29930
  }
29280
- function ShapePersonNode({ node, active }) {
29931
+ function ShapePersonNode({ node, active, textMetrics = "proportional" }) {
29281
29932
  const r = shapeRegion(node);
29282
29933
  const cx = r.cx;
29283
29934
  const strokeColor = active ? "var(--cdl-tone-accent, #2d6a8f)" : "var(--cdl-divider, #d4d4d8)";
@@ -29339,7 +29990,7 @@ function ShapePersonNode({ node, active }) {
29339
29990
  )
29340
29991
  ] })
29341
29992
  ),
29342
- planLabel(node, r.cx, Math.max(0, node.w), r.label)
29993
+ planLabel(node, r.cx, Math.max(0, node.w), r.label, textMetrics)
29343
29994
  ] });
29344
29995
  }
29345
29996
  var commonFrame2 = (active) => ({
@@ -29589,7 +30240,12 @@ function ShapeTerminalNode({ node, active, lang }) {
29589
30240
  )
29590
30241
  ] });
29591
30242
  }
29592
- function ShapeCodeBlockNode({ node, active, lang }) {
30243
+ function ShapeCodeBlockNode({
30244
+ node,
30245
+ active,
30246
+ lang,
30247
+ textMetrics = "proportional"
30248
+ }) {
29593
30249
  const \u5B57\u5F15 = \u5B57\u5F15\u304D\u3092\u4F5C\u308B(lang);
29594
30250
  const frame = commonFrame2(active);
29595
30251
  const \u7DDA = frame.strokeWidth / 2;
@@ -29600,7 +30256,10 @@ function ShapeCodeBlockNode({ node, active, lang }) {
29600
30256
  const lineFont = "ui-monospace, SFMono-Regular, Menlo, monospace";
29601
30257
  const \u672D = \u66F8\u3044\u305F\u5024\u304B\u63A7\u3048(node.subtitle, \u5B57\u5F15("codeBlock.fileName"));
29602
30258
  const \u672D\u306E\u5B57 = 11;
29603
- const \u30BF\u30D6\u5E45 = Math.min(Math.max(100, textWidth(\u672D, \u672D\u306E\u5B57, 0) + 24), Math.max(0, w));
30259
+ const \u30BF\u30D6\u5E45 = Math.min(
30260
+ Math.max(100, textWidth(\u672D, \u672D\u306E\u5B57, 0, textMetrics) + 24),
30261
+ Math.max(0, w)
30262
+ );
29604
30263
  const \u30BF\u30D6\u9AD8 = 24;
29605
30264
  const \u89D2 = 10;
29606
30265
  const \u6E9D = 32;
@@ -29640,7 +30299,7 @@ function ShapeCodeBlockNode({ node, active, lang }) {
29640
30299
  { text: \u672D, size: \u672D\u306E\u5B57, \u5E2F: { \u5E45: \u30BF\u30D6\u5E45, \u9AD8\u3055: \u30BF\u30D6\u9AD8 } },
29641
30300
  { text: "1", size: \u884C\u756A\u53F7\u306E\u5B57, \u5E2F: { \u5E45: \u6E9D - \u6301\u3061\u4E0A\u3052, \u9AD8\u3055: \u884C\u9593 } }
29642
30301
  ];
29643
- const \u500D\u8FD4\u3057 = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D, \u6253\u3061\u6D88\u3059\u5B57\u3089);
30302
+ const \u500D\u8FD4\u3057 = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D, \u6253\u3061\u6D88\u3059\u5B57\u3089, textMetrics);
29644
30303
  const tabW = \u30BF\u30D6\u5E45 * \u500D;
29645
30304
  const tabH = \u30BF\u30D6\u9AD8 * \u500D;
29646
30305
  const \u4E38 = \u89D2 * \u500D;
@@ -29679,7 +30338,7 @@ function ShapeCodeBlockNode({ node, active, lang }) {
29679
30338
  "data-cdl-counter-scaled": "1",
29680
30339
  x: x + tabW / 2,
29681
30340
  y: y + tabH / 2 + 4 * \u500D,
29682
- fontSize: \u672D\u306E\u5B57 * \u500D * \u500D\u8FD4\u3057 * \u5E45\u306E\u500D\u7387(\u672D, \u672D\u306E\u5B57 * \u500D * \u500D\u8FD4\u3057, 0, tabW),
30341
+ fontSize: \u672D\u306E\u5B57 * \u500D * \u500D\u8FD4\u3057 * \u5E45\u306E\u500D\u7387(\u672D, \u672D\u306E\u5B57 * \u500D * \u500D\u8FD4\u3057, 0, tabW, textMetrics),
29683
30342
  fontFamily: lineFont,
29684
30343
  textAnchor: "middle",
29685
30344
  fill: "#e6edf3",
@@ -29761,7 +30420,12 @@ function ShapeCodeBlockNode({ node, active, lang }) {
29761
30420
  )
29762
30421
  ] });
29763
30422
  }
29764
- function ShapeKanbanCardNode({ node, active, lang }) {
30423
+ function ShapeKanbanCardNode({
30424
+ node,
30425
+ active,
30426
+ lang,
30427
+ textMetrics = "proportional"
30428
+ }) {
29765
30429
  const \u5B57\u5F15 = \u5B57\u5F15\u304D\u3092\u4F5C\u308B(lang);
29766
30430
  const frame = commonFrame2(active);
29767
30431
  const \u7DDA = frame.strokeWidth / 2;
@@ -29815,7 +30479,7 @@ function ShapeKanbanCardNode({ node, active, lang }) {
29815
30479
  );
29816
30480
  const \u8AAC\u660E = \u66F8\u3044\u305F\u5024\u304B\u63A7\u3048(node.subtitle, \u5B57\u5F15("kanbanCard.task"));
29817
30481
  const \u72B6\u614B = \u66F8\u3044\u305F\u5024\u304B\u63A7\u3048(node.eyebrow, \u5B57\u5F15("kanbanCard.status"));
29818
- const \u72B6\u614B\u306E\u500D\u7387 = \u5E45\u306E\u500D\u7387(\u72B6\u614B, PILL\u5B57, PILL\u5B57\u9593, PILL\u5B57\u5E45);
30482
+ const \u72B6\u614B\u306E\u500D\u7387 = \u5E45\u306E\u500D\u7387(\u72B6\u614B, PILL\u5B57, PILL\u5B57\u9593, PILL\u5B57\u5E45, textMetrics);
29819
30483
  const \u8AAC\u660E\u306E\u5B57 = \u540D\u524D.size * \u8AAC\u660E\u5B57\u6BD4;
29820
30484
  const \u4F7F\u3048\u308B\u5E452 = Math.max(0, w - \u5DE6\u53F3\u4F59\u767D * \u500D * 2);
29821
30485
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
@@ -29902,7 +30566,7 @@ function ShapeKanbanCardNode({ node, active, lang }) {
29902
30566
  {
29903
30567
  x: x + w / 2,
29904
30568
  y: \u540D\u524D.y + \u540D\u524D.size * \u8AAC\u660E\u57FA\u6E96\u6BD4,
29905
- fontSize: \u8AAC\u660E\u306E\u5B57 * \u5E45\u306E\u500D\u7387(\u8AAC\u660E, \u8AAC\u660E\u306E\u5B57, 0, \u4F7F\u3048\u308B\u5E452),
30569
+ fontSize: \u8AAC\u660E\u306E\u5B57 * \u5E45\u306E\u500D\u7387(\u8AAC\u660E, \u8AAC\u660E\u306E\u5B57, 0, \u4F7F\u3048\u308B\u5E452, textMetrics),
29906
30570
  textAnchor: "middle",
29907
30571
  fill: "var(--cdl-text-dim, #5a6270)",
29908
30572
  children: \u8AAC\u660E
@@ -30193,18 +30857,33 @@ var externalLabel = (node, cx, bottomY) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRu
30193
30857
  )
30194
30858
  ] });
30195
30859
  var LABEL_EYEBROW_SPACING = 2;
30196
- function \u5E45\u306B\u53CE\u3081\u308B2(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, \u984C\u304B = false) {
30197
- const \u5E45 = textWidth(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593);
30198
- const \u4E0B\u9650 = \u984C\u304B ? \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, textWidth) : 0;
30860
+ function \u5E45\u306B\u53CE\u3081\u308B2(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, \u984C\u304B = false, textMetrics = "proportional") {
30861
+ const \u6E2C\u308B = (t, s, ls) => textWidth(t, s, ls, textMetrics);
30862
+ const \u5E45 = \u6E2C\u308B(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593);
30863
+ const \u4E0B\u9650 = \u984C\u304B ? \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, \u6E2C\u308B) : 0;
30199
30864
  const \u500D\u7387 = \u5E45 > 0 && \u7BB1\u5E45 > 0 ? Math.min(1, Math.max(\u7BB1\u5E45 / \u5E45, \u4E0B\u9650)) : 1;
30200
30865
  const size = \u5927\u304D\u3055 * \u500D\u7387;
30201
30866
  const spacing = \u5B57\u9593 * \u500D\u7387;
30202
- return { size, spacing, text: \u5E2F\u3067\u5207\u308B(\u6587\u5B57\u5217, size, \u7BB1\u5E45, (u, f) => textWidth(u, f, spacing)) };
30203
- }
30204
- function bottomLabel(node, cx, plan) {
30205
- const \u80A9 = \u5E45\u306B\u53CE\u3081\u308B2(node.eyebrow ?? "", plan.\u80A9\u66F8?.size ?? 0, LABEL_EYEBROW_SPACING, node.w);
30206
- const \u540D = \u5E45\u306B\u53CE\u3081\u308B2(node.title ?? "", plan.\u540D\u524D.size, 0, node.w, true);
30207
- const \u8AAC = \u5E45\u306B\u53CE\u3081\u308B2(node.subtitle ?? "", plan.\u8AAC\u660E?.size ?? 0, 0, node.w);
30867
+ return { size, spacing, text: \u5E2F\u3067\u5207\u308B(\u6587\u5B57\u5217, size, \u7BB1\u5E45, (u, f) => \u6E2C\u308B(u, f, spacing)) };
30868
+ }
30869
+ function bottomLabel(node, cx, plan, textMetrics = "proportional") {
30870
+ const \u80A9 = \u5E45\u306B\u53CE\u3081\u308B2(
30871
+ node.eyebrow ?? "",
30872
+ plan.\u80A9\u66F8?.size ?? 0,
30873
+ LABEL_EYEBROW_SPACING,
30874
+ node.w,
30875
+ false,
30876
+ textMetrics
30877
+ );
30878
+ const \u540D = \u5E45\u306B\u53CE\u3081\u308B2(node.title ?? "", plan.\u540D\u524D.size, 0, node.w, true, textMetrics);
30879
+ const \u8AAC = \u5E45\u306B\u53CE\u3081\u308B2(
30880
+ node.subtitle ?? "",
30881
+ plan.\u8AAC\u660E?.size ?? 0,
30882
+ 0,
30883
+ node.w,
30884
+ false,
30885
+ textMetrics
30886
+ );
30208
30887
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
30209
30888
  node.eyebrow && plan.\u80A9\u66F8 && /* @__PURE__ */ jsxRuntime.jsx("text", { x: cx, y: plan.\u80A9\u66F8.y, fontSize: \u80A9.size, fontWeight: 700, letterSpacing: \u80A9.spacing, textAnchor: "middle", fill: "var(--cdl-tone-accent, #2d6a8f)", children: \u80A9.text }),
30210
30889
  /* @__PURE__ */ jsxRuntime.jsx("text", { "data-cdl-role": "node-label", x: cx, y: plan.\u540D\u524D.y, fontSize: \u540D.size, fontWeight: 700, textAnchor: "middle", fill: "var(--cdl-text, #1a1f2a)", children: \u540D.text }),
@@ -30218,7 +30897,7 @@ var RACK_SLOT_N = 4;
30218
30897
  var RACK_BOTTOM = 8;
30219
30898
  var RACK_H = RACK_SLOT_TOP + RACK_SLOT_N * RACK_SLOT_H + (RACK_SLOT_N - 1) * RACK_SLOT_GAP + RACK_BOTTOM;
30220
30899
  var RACK_W_MIN = 120;
30221
- function ShapeServerRackNode({ node, active }) {
30900
+ function ShapeServerRackNode({ node, active, textMetrics = "proportional" }) {
30222
30901
  const r = shapeRegion(node);
30223
30902
  const frame = commonFrame3(active);
30224
30903
  const \u7DDA = frame.strokeWidth / 2;
@@ -30300,7 +30979,7 @@ function ShapeServerRackNode({ node, active }) {
30300
30979
  ] }, i);
30301
30980
  })
30302
30981
  ] })),
30303
- bottomLabel(node, r.cx, r.label)
30982
+ bottomLabel(node, r.cx, r.label, textMetrics)
30304
30983
  ] });
30305
30984
  }
30306
30985
  var HUB_R = 30;
@@ -30308,7 +30987,7 @@ var ARM_LEN = 68;
30308
30987
  var END_R = 7;
30309
30988
  var WIFI_ARC_R = [10, 16, 22];
30310
30989
  var WIFI_BASE_Y = 5;
30311
- function ShapeNetworkNodeNode({ node, active }) {
30990
+ function ShapeNetworkNodeNode({ node, active, textMetrics = "proportional" }) {
30312
30991
  const r = shapeRegion(node);
30313
30992
  const cx = r.cx;
30314
30993
  const cy = r.cy;
@@ -30384,12 +31063,12 @@ function ShapeNetworkNodeNode({ node, active }) {
30384
31063
  )),
30385
31064
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx, cy: cy + WIFI_BASE_Y + 3, r: 2.5, fill: "var(--cdl-tone-accent, #2d6a8f)", stroke: "none" })
30386
31065
  ] })),
30387
- bottomLabel(node, r.cx, r.label)
31066
+ bottomLabel(node, r.cx, r.label, textMetrics)
30388
31067
  ] });
30389
31068
  }
30390
31069
  var PHONE_H = 240;
30391
31070
  var PHONE_W = 110;
30392
- function ShapeMobileDeviceNode({ node, active }) {
31071
+ function ShapeMobileDeviceNode({ node, active, textMetrics = "proportional" }) {
30393
31072
  const r = shapeRegion(node);
30394
31073
  const frame = commonFrame3(active);
30395
31074
  const \u7DDA = frame.strokeWidth / 2;
@@ -30456,7 +31135,7 @@ function ShapeMobileDeviceNode({ node, active }) {
30456
31135
  }
30457
31136
  )
30458
31137
  ] })),
30459
- bottomLabel(node, r.cx, r.label)
31138
+ bottomLabel(node, r.cx, r.label, textMetrics)
30460
31139
  ] });
30461
31140
  }
30462
31141
  function ShapeIotSensorNode({ node, active }) {
@@ -30727,7 +31406,7 @@ var SAT_DISH_R = 12;
30727
31406
  var SAT_DISH_STEM = 12;
30728
31407
  var SAT_MAST_LEN = 22;
30729
31408
  var SAT_MAST_TIP_R = 4;
30730
- function ShapeSatelliteNode({ node, active }) {
31409
+ function ShapeSatelliteNode({ node, active, textMetrics = "proportional" }) {
30731
31410
  const r = shapeRegion(node);
30732
31411
  const cx = r.cx;
30733
31412
  const cy = r.cy;
@@ -30916,7 +31595,7 @@ function ShapeSatelliteNode({ node, active }) {
30916
31595
  ),
30917
31596
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx, cy: cy - bodyH / 2 - SAT_MAST_LEN, r: 2, fill: "#ff5f56", stroke: "none", children: /* @__PURE__ */ jsxRuntime.jsx("animate", { attributeName: "opacity", values: "0.4;1;0.4", dur: "1.4s", repeatCount: "indefinite" }) })
30918
31597
  ] })),
30919
- bottomLabel(node, r.cx, r.label)
31598
+ bottomLabel(node, r.cx, r.label, textMetrics)
30920
31599
  ] });
30921
31600
  }
30922
31601
  var FRAME_SW_ACTIVE = 3;
@@ -31002,9 +31681,9 @@ function blockchainNodeExtent(strokeWidth) {
31002
31681
  const \u6A2A = (NODE_PEER_DIST + NODE_PEER_R) * Math.cos(Math.PI / 6) + \u7DDA;
31003
31682
  return { \u4E0A: \u7E26, \u4E0B: \u7E26, \u5DE6: \u6A2A, \u53F3: \u6A2A };
31004
31683
  }
31005
- function bottomLabel2(node, cx, plan) {
31684
+ function bottomLabel2(node, cx, plan, textMetrics = "proportional") {
31006
31685
  const \u53CE\u3081\u308B = (t, \u5927\u304D\u3055, \u5B57\u9593, \u984C\u304B = false) => {
31007
- const \u6E2C\u308B = (u, f, ls) => \u5B57\u306E\u5E45(u, f) + ls * [...u].length;
31686
+ const \u6E2C\u308B = (u, f, ls) => \u5B57\u306E\u5E45(u, f, textMetrics) + ls * [...u].length;
31008
31687
  const \u7D20\u306E\u5E45 = \u6E2C\u308B(t, \u5927\u304D\u3055, \u5B57\u9593);
31009
31688
  const \u53CE\u307E\u308B = \u7D20\u306E\u5E45 > node.w && node.w > 0 ? node.w / \u7D20\u306E\u5E45 : 1;
31010
31689
  const \u4E0B\u9650 = \u984C\u304B ? \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(t, \u5927\u304D\u3055, \u5B57\u9593, node.w, \u6E2C\u308B) : 0;
@@ -31037,7 +31716,12 @@ function EthereumDiamond({ cx, cy, h, colors }) {
31037
31716
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: `M ${cx} ${midY} L ${cx + w} ${cy + h * 0.05} L ${cx} ${lowerBotY} Z`, fill: c.dark, stroke: c.stroke, strokeWidth: 0.6, strokeLinejoin: "round" })
31038
31717
  ] });
31039
31718
  }
31040
- function ShapeSmartContractNode({ node, active, lang }) {
31719
+ function ShapeSmartContractNode({
31720
+ node,
31721
+ active,
31722
+ lang,
31723
+ textMetrics = "proportional"
31724
+ }) {
31041
31725
  const \u5B57\u5F15 = \u5B57\u5F15\u304D\u3092\u4F5C\u308B(lang);
31042
31726
  const frame = commonFrame4(active);
31043
31727
  const r = shapeRegion(node);
@@ -31078,7 +31762,7 @@ function ShapeSmartContractNode({ node, active, lang }) {
31078
31762
  }
31079
31763
  ];
31080
31764
  const art = (\u500D\u7387) => {
31081
- const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089);
31765
+ const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089, textMetrics);
31082
31766
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
31083
31767
  /* @__PURE__ */ jsxRuntime.jsx("path", { "data-cdl-role": "node-body", d: path, ...frame, strokeLinejoin: "round" }),
31084
31768
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: foldPath, fill: "none", stroke: frame.stroke, strokeWidth: frame.strokeWidth, strokeLinejoin: "round" }),
@@ -31100,10 +31784,10 @@ function ShapeSmartContractNode({ node, active, lang }) {
31100
31784
  };
31101
31785
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
31102
31786
  fitArt(r, smartContractExtent(frame.strokeWidth), art),
31103
- bottomLabel2(node, r.cx, r.label)
31787
+ bottomLabel2(node, r.cx, r.label, textMetrics)
31104
31788
  ] });
31105
31789
  }
31106
- var \u5B57\u306E\u5E45 = (text, size) => \u7D75\u306E\u4E2D\u306E\u5B57\u306E\u5E45(text, size);
31790
+ var \u5B57\u306E\u5E45 = (text, size, textMetrics = "proportional") => \u7D75\u306E\u4E2D\u306E\u5B57\u306E\u5E45(text, size, 0, textMetrics);
31107
31791
  var BLOCK_DEFAULT_FIELDS = [
31108
31792
  { key: "hash", label: "blockchainBlock.hash", value: { text: "0xaf31..." } },
31109
31793
  { key: "prev", label: "blockchainBlock.prev", value: { text: "0x7b3f..." } },
@@ -31111,10 +31795,16 @@ var BLOCK_DEFAULT_FIELDS = [
31111
31795
  { key: "nonce", label: "blockchainBlock.nonce", value: { text: "82,914" } },
31112
31796
  { key: "tx", label: "blockchainBlock.tx", value: { \u8F9E\u66F8: "blockchainBlock.txCount" } }
31113
31797
  ];
31114
- function ShapeBlockchainBlockNode({ node, active, lang }) {
31798
+ function ShapeBlockchainBlockNode({
31799
+ node,
31800
+ active,
31801
+ lang,
31802
+ textMetrics = "proportional"
31803
+ }) {
31115
31804
  const \u5B57\u5F15 = \u5B57\u5F15\u304D\u3092\u4F5C\u308B(lang);
31116
31805
  const frame = commonFrame4(active);
31117
31806
  const r = shapeRegion(node);
31807
+ const \u6E2C\u308B\u5B57 = (text, size) => \u5B57\u306E\u5E45(text, size, textMetrics);
31118
31808
  const bw = BLOCK_W;
31119
31809
  const bh = BLOCK_H;
31120
31810
  const cx = r.cx;
@@ -31135,9 +31825,9 @@ function ShapeBlockchainBlockNode({ node, active, lang }) {
31135
31825
  const \u5E2F\u306E\u6B8B\u308A = bw - 14 - 30;
31136
31826
  const \u80A9\u66F8\u306E\u9699\u9593 = 8;
31137
31827
  const \u80A9\u66F8\u306E\u4E0A\u9650 = (\u5E2F\u306E\u6B8B\u308A - \u80A9\u66F8\u306E\u9699\u9593) / 2;
31138
- 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);
31828
+ 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, textMetrics);
31139
31829
  const \u80A9\u66F8\u306E\u6307\u5B9A = \u80A9\u66F8\u306E\u5B57 * \u80A9\u66F8\u306E\u500D\u7387;
31140
- const \u80A9\u66F8\u306E\u5E45 = \u80A9\u66F8 === "" ? 0 : \u5B57\u306E\u5E45(\u80A9\u66F8, \u80A9\u66F8\u306E\u6307\u5B9A);
31830
+ const \u80A9\u66F8\u306E\u5E45 = \u80A9\u66F8 === "" ? 0 : \u6E2C\u308B\u5B57(\u80A9\u66F8, \u80A9\u66F8\u306E\u6307\u5B9A);
31141
31831
  const \u898B\u51FA\u3057\u306E\u5E45 = \u5E2F\u306E\u6B8B\u308A - (\u80A9\u66F8 === "" ? 0 : \u80A9\u66F8\u306E\u5E45 + \u80A9\u66F8\u306E\u9699\u9593);
31142
31832
  const \u6253\u3061\u6D88\u3059\u5B57\u3089 = [
31143
31833
  { text: \u898B\u51FA\u3057, size: \u898B\u51FA\u3057\u306E\u5B57, \u5E2F: { \u5E45: \u898B\u51FA\u3057\u306E\u5E45, \u9AD8\u3055: \u898B\u51FA\u3057\u306E\u5E2F } },
@@ -31148,12 +31838,12 @@ function ShapeBlockchainBlockNode({ node, active, lang }) {
31148
31838
  {
31149
31839
  text: f.value,
31150
31840
  size: \u5024\u306E\u5B57,
31151
- \u5E2F: { \u5E45: bw - 28 - \u5B57\u306E\u5E45(f.label, \u540D\u306E\u5B57) - 8, \u9AD8\u3055: \u884C\u306E\u9593\u9694 }
31841
+ \u5E2F: { \u5E45: bw - 28 - \u6E2C\u308B\u5B57(f.label, \u540D\u306E\u5B57) - 8, \u9AD8\u3055: \u884C\u306E\u9593\u9694 }
31152
31842
  }
31153
31843
  ])
31154
31844
  ];
31155
31845
  const art = (\u500D\u7387) => {
31156
- const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089);
31846
+ const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089, textMetrics);
31157
31847
  const \u984C\u306E\u5927\u304D\u3055 = \u898B\u51FA\u3057\u306E\u5B57 * \u500D;
31158
31848
  const \u80A9\u66F8\u306E\u5927\u304D\u3055 = \u80A9\u66F8\u306E\u6307\u5B9A * \u500D;
31159
31849
  const \u540D\u306E\u5927\u304D\u3055 = \u540D\u306E\u5B57 * \u500D;
@@ -31162,7 +31852,7 @@ function ShapeBlockchainBlockNode({ node, active, lang }) {
31162
31852
  /* @__PURE__ */ jsxRuntime.jsx("rect", { x: x + 6, y: y + 6, width: bw, height: bh, rx: 8, fill: frame.stroke, opacity: 0.2, stroke: "none" }),
31163
31853
  /* @__PURE__ */ jsxRuntime.jsx("rect", { "data-cdl-role": "node-body", x, y, width: bw, height: bh, rx: 8, ...frame }),
31164
31854
  /* @__PURE__ */ jsxRuntime.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" }),
31165
- /* @__PURE__ */ jsxRuntime.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) }),
31855
+ /* @__PURE__ */ jsxRuntime.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, \u6E2C\u308B\u5B57) }),
31166
31856
  \u80A9\u66F8 !== "" && /* @__PURE__ */ jsxRuntime.jsx(
31167
31857
  "text",
31168
31858
  {
@@ -31182,7 +31872,12 @@ function ShapeBlockchainBlockNode({ node, active, lang }) {
31182
31872
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x + bw - 16, cy: y + 16, r: 5.5, fill: "#7cd88f", stroke: "#ffffff", strokeWidth: 1.5 }),
31183
31873
  fields.map((f, i) => /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
31184
31874
  /* @__PURE__ */ jsxRuntime.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 }),
31185
- /* @__PURE__ */ jsxRuntime.jsx("text", { "data-cdl-role": `blockchain-block-${f.key}`, "data-cdl-counter-scaled": "1", x: x + bw - 14, y: y + 54 + i * \u884C\u306E\u9593\u9694, fontSize: \u5024\u306E\u5927\u304D\u3055, fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace", fontWeight: 600, textAnchor: "end", fill: "var(--cdl-text, #1a1f2a)", children: \u5E45\u3067\u5207\u308B(f.value, \u5024\u306E\u5927\u304D\u3055, bw - 28 - \u5B57\u306E\u5E45(f.label, \u540D\u306E\u5927\u304D\u3055) - 8, \u5B57\u306E\u5E45) }),
31875
+ /* @__PURE__ */ jsxRuntime.jsx("text", { "data-cdl-role": `blockchain-block-${f.key}`, "data-cdl-counter-scaled": "1", x: x + bw - 14, y: y + 54 + i * \u884C\u306E\u9593\u9694, fontSize: \u5024\u306E\u5927\u304D\u3055, fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace", fontWeight: 600, textAnchor: "end", fill: "var(--cdl-text, #1a1f2a)", children: \u5E45\u3067\u5207\u308B(
31876
+ f.value,
31877
+ \u5024\u306E\u5927\u304D\u3055,
31878
+ bw - 28 - \u6E2C\u308B\u5B57(f.label, \u540D\u306E\u5927\u304D\u3055) - 8,
31879
+ \u6E2C\u308B\u5B57
31880
+ ) }),
31186
31881
  /* @__PURE__ */ jsxRuntime.jsx("line", { x1: x + 14, y1: y + 60 + i * \u884C\u306E\u9593\u9694, x2: x + bw - 14, y2: y + 60 + i * \u884C\u306E\u9593\u9694, stroke: "var(--cdl-divider, #d4d4d8)", strokeWidth: 0.5, opacity: 0.5 })
31187
31882
  ] }, i)),
31188
31883
  /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${cx - 32}, ${y + bh - 26})`, children: [
@@ -31194,7 +31889,11 @@ function ShapeBlockchainBlockNode({ node, active, lang }) {
31194
31889
  };
31195
31890
  return /* @__PURE__ */ jsxRuntime.jsx("g", { children: fitArt(r, blockchainBlockExtent(frame.strokeWidth), art) });
31196
31891
  }
31197
- function ShapeBlockchainNode({ node, active }) {
31892
+ function ShapeBlockchainNode({
31893
+ node,
31894
+ active,
31895
+ textMetrics = "proportional"
31896
+ }) {
31198
31897
  const frame = commonFrame4(active);
31199
31898
  const r = shapeRegion(node);
31200
31899
  const cx = r.cx;
@@ -31210,7 +31909,7 @@ function ShapeBlockchainNode({ node, active }) {
31210
31909
  { text: "0x\u2026", size: CHAIN_HASH_SIZE, \u5E2F: { \u5E45: CHAIN_TEXT_W, \u9AD8\u3055: CHAIN_ROW_GAP } }
31211
31910
  ];
31212
31911
  const art = (\u500D\u7387) => {
31213
- const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089);
31912
+ const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089, textMetrics);
31214
31913
  return /* @__PURE__ */ jsxRuntime.jsx("g", { children: Array.from({ length: blockCount }, (_, i) => i).map((i) => {
31215
31914
  const bx = startX + i * (blockW + linkW);
31216
31915
  const isCurrent = i === blockCount - 1;
@@ -31246,10 +31945,14 @@ function ShapeBlockchainNode({ node, active }) {
31246
31945
  };
31247
31946
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
31248
31947
  fitArt(r, chainExtent(), art),
31249
- bottomLabel2(node, r.cx, r.label)
31948
+ bottomLabel2(node, r.cx, r.label, textMetrics)
31250
31949
  ] });
31251
31950
  }
31252
- function ShapeBitcoinChainNode({ node, active }) {
31951
+ function ShapeBitcoinChainNode({
31952
+ node,
31953
+ active,
31954
+ textMetrics = "proportional"
31955
+ }) {
31253
31956
  const frame = commonFrame4(active);
31254
31957
  const r = shapeRegion(node);
31255
31958
  const cx = r.cx;
@@ -31265,7 +31968,7 @@ function ShapeBitcoinChainNode({ node, active }) {
31265
31968
  { text: "#820", size: BTC_NO_SIZE, \u5E2F: { \u5E45: CHAIN_TEXT_W, \u9AD8\u3055: 20 } }
31266
31969
  ];
31267
31970
  const art = (\u500D\u7387) => {
31268
- const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089);
31971
+ const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089, textMetrics);
31269
31972
  return /* @__PURE__ */ jsxRuntime.jsx("g", { children: Array.from({ length: blockCount }, (_, i) => i).map((i) => {
31270
31973
  const bx = startX + i * (blockW + linkW);
31271
31974
  const isCurrent = i === blockCount - 1;
@@ -31296,10 +31999,14 @@ function ShapeBitcoinChainNode({ node, active }) {
31296
31999
  };
31297
32000
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
31298
32001
  fitArt(r, chainExtent(), art),
31299
- bottomLabel2(node, r.cx, r.label)
32002
+ bottomLabel2(node, r.cx, r.label, textMetrics)
31300
32003
  ] });
31301
32004
  }
31302
- function ShapeEthereumChainNode({ node, active }) {
32005
+ function ShapeEthereumChainNode({
32006
+ node,
32007
+ active,
32008
+ textMetrics = "proportional"
32009
+ }) {
31303
32010
  const frame = commonFrame4(active);
31304
32011
  const r = shapeRegion(node);
31305
32012
  const cx = r.cx;
@@ -31315,7 +32022,7 @@ function ShapeEthereumChainNode({ node, active }) {
31315
32022
  { text: "#214", size: ETH_NO_SIZE, \u5E2F: { \u5E45: CHAIN_TEXT_W, \u9AD8\u3055: 20 } }
31316
32023
  ];
31317
32024
  const art = (\u500D\u7387) => {
31318
- const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089);
32025
+ const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089, textMetrics);
31319
32026
  return /* @__PURE__ */ jsxRuntime.jsx("g", { children: Array.from({ length: blockCount }, (_, i) => i).map((i) => {
31320
32027
  const bx = startX + i * (blockW + linkW);
31321
32028
  const isCurrent = i === blockCount - 1;
@@ -31347,10 +32054,14 @@ function ShapeEthereumChainNode({ node, active }) {
31347
32054
  };
31348
32055
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
31349
32056
  fitArt(r, chainExtent(), art),
31350
- bottomLabel2(node, r.cx, r.label)
32057
+ bottomLabel2(node, r.cx, r.label, textMetrics)
31351
32058
  ] });
31352
32059
  }
31353
- function ShapeBlockchainNodeNode({ node, active }) {
32060
+ function ShapeBlockchainNodeNode({
32061
+ node,
32062
+ active,
32063
+ textMetrics = "proportional"
32064
+ }) {
31354
32065
  const frame = commonFrame4(active);
31355
32066
  const r = shapeRegion(node);
31356
32067
  const cx = r.cx;
@@ -31404,10 +32115,15 @@ function ShapeBlockchainNodeNode({ node, active }) {
31404
32115
  ] });
31405
32116
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
31406
32117
  fitArt(r, blockchainNodeExtent(frame.strokeWidth), art),
31407
- bottomLabel2(node, r.cx, r.label)
32118
+ bottomLabel2(node, r.cx, r.label, textMetrics)
31408
32119
  ] });
31409
32120
  }
31410
- function ShapeRpcNodeNode({ node, active, lang }) {
32121
+ function ShapeRpcNodeNode({
32122
+ node,
32123
+ active,
32124
+ lang,
32125
+ textMetrics = "proportional"
32126
+ }) {
31411
32127
  const \u5B57\u5F15 = \u5B57\u5F15\u304D\u3092\u4F5C\u308B(lang);
31412
32128
  const frame = commonFrame4(active);
31413
32129
  const r = shapeRegion(node);
@@ -31426,10 +32142,10 @@ function ShapeRpcNodeNode({ node, active, lang }) {
31426
32142
  /* @__PURE__ */ jsxRuntime.jsx("text", { x: cx, y: cy + 26, fontSize: 11, textAnchor: "middle", fill: "#7a8290", fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace", children: "JSON-RPC 2.0" }),
31427
32143
  /* @__PURE__ */ jsxRuntime.jsx("rect", { x: x + 16, y: y + bh - 24, width: bw - 32, height: 8, rx: 4, fill: "#0f1419", stroke: "none" }),
31428
32144
  /* @__PURE__ */ jsxRuntime.jsx("rect", { x: x + 16, y: y + bh - 24, width: (bw - 32) * 0.92, height: 8, rx: 4, fill: "#27c93f", stroke: "none", children: /* @__PURE__ */ jsxRuntime.jsx("animate", { attributeName: "width", values: `${(bw - 32) * 0.86};${(bw - 32) * 0.96};${(bw - 32) * 0.86}`, dur: "3s", repeatCount: "indefinite" }) }),
31429
- bottomLabel2(node, r.cx, r.label)
32145
+ bottomLabel2(node, r.cx, r.label, textMetrics)
31430
32146
  ] });
31431
32147
  }
31432
- function ShapeWalletNode({ node, active }) {
32148
+ function ShapeWalletNode({ node, active, textMetrics = "proportional" }) {
31433
32149
  const frame = commonFrame4(active);
31434
32150
  const r = shapeRegion(node);
31435
32151
  const cx = r.cx;
@@ -31503,10 +32219,10 @@ function ShapeWalletNode({ node, active }) {
31503
32219
  /* @__PURE__ */ jsxRuntime.jsx("text", { x: cx, y: foldY + 3, fontSize: 9, fontWeight: 700, fill: "#5a3a10", textAnchor: "middle", opacity: 0.8, children: "\u039E" }),
31504
32220
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: `M ${x + 2} ${y + 6} L ${x + w - 2} ${y + 6}`, fill: "none", stroke: "#ffffff", strokeWidth: 1, opacity: 0.4 })
31505
32221
  ] }),
31506
- bottomLabel2(node, r.cx, r.label)
32222
+ bottomLabel2(node, r.cx, r.label, textMetrics)
31507
32223
  ] });
31508
32224
  }
31509
- function ShapeNftNode({ node, active }) {
32225
+ function ShapeNftNode({ node, active, textMetrics = "proportional" }) {
31510
32226
  const frame = commonFrame4(active);
31511
32227
  const r = shapeRegion(node);
31512
32228
  const cx = r.cx;
@@ -31522,7 +32238,7 @@ function ShapeNftNode({ node, active }) {
31522
32238
  { text: "#1024", size: NFT_ID_SIZE, \u5E2F: { \u5E45: cardW - 16 - 34, \u9AD8\u3055: cardH - artH } }
31523
32239
  ];
31524
32240
  const art = (\u500D\u7387) => {
31525
- const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089);
32241
+ const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089, textMetrics);
31526
32242
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
31527
32243
  /* @__PURE__ */ jsxRuntime.jsx("rect", { x: x + 4, y: y + 4, width: cardW, height: cardH, rx: 14, fill: frame.stroke, opacity: 0.2, stroke: "none" }),
31528
32244
  /* @__PURE__ */ jsxRuntime.jsx("rect", { "data-cdl-role": "node-body", x, y, width: cardW, height: cardH, rx: 14, ...frame }),
@@ -31560,10 +32276,10 @@ function ShapeNftNode({ node, active }) {
31560
32276
  };
31561
32277
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
31562
32278
  fitArt(r, nftExtent(frame.strokeWidth), art),
31563
- bottomLabel2(node, r.cx, r.label)
32279
+ bottomLabel2(node, r.cx, r.label, textMetrics)
31564
32280
  ] });
31565
32281
  }
31566
- function ShapeTokenNode({ node, active }) {
32282
+ function ShapeTokenNode({ node, active, textMetrics = "proportional" }) {
31567
32283
  const frame = commonFrame4(active);
31568
32284
  const r = shapeRegion(node);
31569
32285
  const cx = r.cx;
@@ -31600,7 +32316,7 @@ function ShapeTokenNode({ node, active }) {
31600
32316
  }
31601
32317
  }
31602
32318
  ),
31603
- bottomLabel2(node, r.cx, r.label)
32319
+ bottomLabel2(node, r.cx, r.label, textMetrics)
31604
32320
  ] });
31605
32321
  }
31606
32322
  var commonFrame5 = (active) => ({
@@ -31619,7 +32335,8 @@ function \u5B57\u306E\u6BD4(c) {
31619
32335
  if (\u5E83\u5B57.has(c)) return \u5E83\u5B57\u6BD4;
31620
32336
  return (c.codePointAt(0) ?? 0) < 128 ? \u4E26\u5B57\u6BD4 : \u5E83\u5B57\u6BD4;
31621
32337
  }
31622
- function \u5B57\u5E45(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593) {
32338
+ function \u5B57\u5E45(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, textMetrics = "proportional") {
32339
+ if (textMetrics === "monospace") return textWidth(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, textMetrics);
31623
32340
  let \u5E45 = 0;
31624
32341
  let \u5B57\u6570 = 0;
31625
32342
  for (const c of \u6587\u5B57\u5217) {
@@ -31628,18 +32345,33 @@ function \u5B57\u5E45(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593) {
31628
32345
  }
31629
32346
  return \u5E45 + \u5B57\u9593 * \u5B57\u6570;
31630
32347
  }
31631
- function \u5E45\u306B\u53CE\u3081\u308B3(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, \u984C\u304B = false) {
31632
- const \u5E45 = \u5B57\u5E45(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593);
31633
- const \u4E0B\u9650 = \u984C\u304B ? \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, \u5B57\u5E45) : 0;
32348
+ function \u5E45\u306B\u53CE\u3081\u308B3(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, \u984C\u304B = false, textMetrics = "proportional") {
32349
+ const \u6E2C\u308B = (t, s, ls) => \u5B57\u5E45(t, s, ls, textMetrics);
32350
+ const \u5E45 = \u6E2C\u308B(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593);
32351
+ const \u4E0B\u9650 = \u984C\u304B ? \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, \u6E2C\u308B) : 0;
31634
32352
  const \u500D\u7387 = \u5E45 > 0 && \u7BB1\u5E45 > 0 ? Math.min(1, Math.max(\u7BB1\u5E45 / \u5E45, \u4E0B\u9650)) : 1;
31635
32353
  const size = \u5927\u304D\u3055 * \u500D\u7387;
31636
32354
  const spacing = \u5B57\u9593 * \u500D\u7387;
31637
- return { size, spacing, text: \u5E2F\u3067\u5207\u308B(\u6587\u5B57\u5217, size, \u7BB1\u5E45, (u, f) => \u5B57\u5E45(u, f, spacing)) };
31638
- }
31639
- function bottomLabel3(node, cx, plan) {
31640
- const \u80A9 = \u5E45\u306B\u53CE\u3081\u308B3(node.eyebrow ?? "", plan.\u80A9\u66F8?.size ?? 0, LABEL_EYEBROW_SPACING2, node.w);
31641
- const \u540D = \u5E45\u306B\u53CE\u3081\u308B3(node.title ?? "", plan.\u540D\u524D.size, 0, node.w, true);
31642
- const \u8AAC = \u5E45\u306B\u53CE\u3081\u308B3(node.subtitle ?? "", plan.\u8AAC\u660E?.size ?? 0, 0, node.w);
32355
+ return { size, spacing, text: \u5E2F\u3067\u5207\u308B(\u6587\u5B57\u5217, size, \u7BB1\u5E45, (u, f) => \u6E2C\u308B(u, f, spacing)) };
32356
+ }
32357
+ function bottomLabel3(node, cx, plan, textMetrics = "proportional") {
32358
+ const \u80A9 = \u5E45\u306B\u53CE\u3081\u308B3(
32359
+ node.eyebrow ?? "",
32360
+ plan.\u80A9\u66F8?.size ?? 0,
32361
+ LABEL_EYEBROW_SPACING2,
32362
+ node.w,
32363
+ false,
32364
+ textMetrics
32365
+ );
32366
+ const \u540D = \u5E45\u306B\u53CE\u3081\u308B3(node.title ?? "", plan.\u540D\u524D.size, 0, node.w, true, textMetrics);
32367
+ const \u8AAC = \u5E45\u306B\u53CE\u3081\u308B3(
32368
+ node.subtitle ?? "",
32369
+ plan.\u8AAC\u660E?.size ?? 0,
32370
+ 0,
32371
+ node.w,
32372
+ false,
32373
+ textMetrics
32374
+ );
31643
32375
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
31644
32376
  node.eyebrow && plan.\u80A9\u66F8 && /* @__PURE__ */ jsxRuntime.jsx("text", { x: cx, y: plan.\u80A9\u66F8.y, fontSize: \u80A9.size, fontWeight: 700, letterSpacing: \u80A9.spacing, textAnchor: "middle", fill: "var(--cdl-tone-accent, #2d6a8f)", children: \u80A9.text }),
31645
32377
  /* @__PURE__ */ jsxRuntime.jsx("text", { "data-cdl-role": "node-label", x: cx, y: plan.\u540D\u524D.y, fontSize: \u540D.size, fontWeight: 700, textAnchor: "middle", fill: "var(--cdl-text, #1a1f2a)", children: \u540D.text }),
@@ -31658,7 +32390,7 @@ var BANK_STEP_SW = 1;
31658
32390
  var BANK_COLUMN_MIN = 24;
31659
32391
  var BANK_BLD_W_MIN = 120;
31660
32392
  var BANK_BLD_W_MAX = 280;
31661
- function ShapeBankNode({ node, active }) {
32393
+ function ShapeBankNode({ node, active, textMetrics = "proportional" }) {
31662
32394
  const frame = commonFrame5(active);
31663
32395
  const r = shapeRegion(node);
31664
32396
  const \u7DDA = frame.strokeWidth / 2;
@@ -31705,7 +32437,7 @@ function ShapeBankNode({ node, active }) {
31705
32437
  ] });
31706
32438
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
31707
32439
  fitArt(r, \u5E83\u304C\u308A, \u7D75),
31708
- bottomLabel3(node, r.cx, r.label)
32440
+ bottomLabel3(node, r.cx, r.label, textMetrics)
31709
32441
  ] });
31710
32442
  }
31711
32443
  var TRUST_CROWN_RISE = 4;
@@ -31717,7 +32449,12 @@ var TRUST_BASE_H = 14;
31717
32449
  var TRUST_BODY_OUT = 8;
31718
32450
  var TRUST_BLD_W_MIN = 140;
31719
32451
  var TRUST_BLD_W_MAX = 280;
31720
- function ShapeTrustBankNode({ node, active, lang }) {
32452
+ function ShapeTrustBankNode({
32453
+ node,
32454
+ active,
32455
+ lang,
32456
+ textMetrics = "proportional"
32457
+ }) {
31721
32458
  const \u5B57\u5F15 = \u5B57\u5F15\u304D\u3092\u4F5C\u308B(lang);
31722
32459
  const frame = commonFrame5(active);
31723
32460
  const r = shapeRegion(node);
@@ -31771,10 +32508,15 @@ function ShapeTrustBankNode({ node, active, lang }) {
31771
32508
  ] });
31772
32509
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
31773
32510
  fitArt(r, \u5E83\u304C\u308A, \u7D75),
31774
- bottomLabel3(node, r.cx, r.label)
32511
+ bottomLabel3(node, r.cx, r.label, textMetrics)
31775
32512
  ] });
31776
32513
  }
31777
- function ShapePaymentProviderNode({ node, active, lang }) {
32514
+ function ShapePaymentProviderNode({
32515
+ node,
32516
+ active,
32517
+ lang,
32518
+ textMetrics = "proportional"
32519
+ }) {
31778
32520
  const \u5B57\u5F15 = \u5B57\u5F15\u304D\u3092\u4F5C\u308B(lang);
31779
32521
  const frame = commonFrame5(active);
31780
32522
  const r = shapeRegion(node);
@@ -31799,10 +32541,14 @@ function ShapePaymentProviderNode({ node, active, lang }) {
31799
32541
  /* @__PURE__ */ jsxRuntime.jsx("text", { x: cx, y: cy + 9, fontSize: 13, fontWeight: 700, textAnchor: "middle", fill: accentDarker, fontFamily: "Georgia, serif", children: "$" })
31800
32542
  ] }),
31801
32543
  /* @__PURE__ */ jsxRuntime.jsx("text", { x: cx, y: y + boxH - 16, fontSize: 11, fontWeight: 700, letterSpacing: 2, textAnchor: "middle", fill: "#a4b5f2", children: \u5B57\u5F15("paymentProvider.status") }),
31802
- bottomLabel3(node, r.cx, r.label)
32544
+ bottomLabel3(node, r.cx, r.label, textMetrics)
31803
32545
  ] });
31804
32546
  }
31805
- function ShapeCreditCardNode({ node, active }) {
32547
+ function ShapeCreditCardNode({
32548
+ node,
32549
+ active,
32550
+ textMetrics = "proportional"
32551
+ }) {
31806
32552
  const frame = commonFrame5(active);
31807
32553
  const r = shapeRegion(node);
31808
32554
  const cardW = Math.min(r.availW - 30, 260);
@@ -31824,7 +32570,7 @@ function ShapeCreditCardNode({ node, active }) {
31824
32570
  [0, 1, 2, 3].map((block) => /* @__PURE__ */ jsxRuntime.jsx("g", { children: [0, 1, 2, 3].map((dot) => /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x + 32 + block * (cardW - 64) / 4 + dot * 8, cy: y + cardH - 40, r: 2.8, fill: "#ffffff", stroke: "none" }, dot)) }, block)),
31825
32571
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x + cardW - 48, cy: y + cardH - 24, r: 15, fill: "#c9302c", opacity: 0.9, stroke: "none" }),
31826
32572
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x + cardW - 30, cy: y + cardH - 24, r: 15, fill: "#e5c07b", opacity: 0.9, stroke: "none" }),
31827
- bottomLabel3(node, r.cx, r.label)
32573
+ bottomLabel3(node, r.cx, r.label, textMetrics)
31828
32574
  ] });
31829
32575
  }
31830
32576
  var BROKERAGE_TICK_H = 18;
@@ -31849,7 +32595,12 @@ var BROKERAGE_SHADE_OUT = 2;
31849
32595
  var BROKERAGE_W_MIN = BROKERAGE_COLS * BROKERAGE_CELL_W + (BROKERAGE_COLS - 1) * BROKERAGE_GAP_X + 6;
31850
32596
  var BROKERAGE_W_MAX = 140;
31851
32597
  var BROKERAGE_H_MIN = BROKERAGE_TICK_H + BROKERAGE_LOGO_H + BROKERAGE_BASE_H;
31852
- function ShapeBrokerageNode({ node, active, lang }) {
32598
+ function ShapeBrokerageNode({
32599
+ node,
32600
+ active,
32601
+ lang,
32602
+ textMetrics = "proportional"
32603
+ }) {
31853
32604
  const \u5B57\u5F15 = \u5B57\u5F15\u304D\u3092\u4F5C\u308B(lang);
31854
32605
  const frame = commonFrame5(active);
31855
32606
  const r = shapeRegion(node);
@@ -31888,7 +32639,7 @@ function ShapeBrokerageNode({ node, active, lang }) {
31888
32639
  }
31889
32640
  ];
31890
32641
  const \u7D75 = (\u500D\u7387) => {
31891
- const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089);
32642
+ const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089, textMetrics);
31892
32643
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
31893
32644
  /* @__PURE__ */ jsxRuntime.jsx("ellipse", { cx, cy: y + h + BROKERAGE_SHADOW_DY, rx: w * BROKERAGE_SHADOW_RX_RATIO, ry: BROKERAGE_SHADOW_RY, fill: frame.stroke, opacity: 0.2, stroke: "none" }),
31894
32645
  /* @__PURE__ */ jsxRuntime.jsx("rect", { "data-cdl-role": "node-body", x, y, width: w, height: h, fill: "#255a7a", stroke: accentDarker, strokeWidth: frame.strokeWidth }),
@@ -31916,12 +32667,17 @@ function ShapeBrokerageNode({ node, active, lang }) {
31916
32667
  };
31917
32668
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
31918
32669
  fitArt(r, \u5E83\u304C\u308A, \u7D75),
31919
- bottomLabel3(node, r.cx, r.label)
32670
+ bottomLabel3(node, r.cx, r.label, textMetrics)
31920
32671
  ] });
31921
32672
  }
31922
32673
  var EXCHANGE_SUB_SIZE = 11;
31923
32674
  var EXCHANGE_HEX_R = 52;
31924
- function ShapeExchangeNode({ node, active, lang }) {
32675
+ function ShapeExchangeNode({
32676
+ node,
32677
+ active,
32678
+ lang,
32679
+ textMetrics = "proportional"
32680
+ }) {
31925
32681
  const \u5B57\u5F15 = \u5B57\u5F15\u304D\u3092\u4F5C\u308B(lang);
31926
32682
  const frame = commonFrame5(active);
31927
32683
  const r = shapeRegion(node);
@@ -31966,7 +32722,7 @@ function ShapeExchangeNode({ node, active, lang }) {
31966
32722
  }
31967
32723
  ];
31968
32724
  const \u7D75 = (\u500D\u7387) => {
31969
- const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089);
32725
+ const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089, textMetrics);
31970
32726
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
31971
32727
  nodes.map((n, i) => /* @__PURE__ */ jsxRuntime.jsx("line", { x1: cx, y1: cy, x2: n.cx, y2: n.cy, stroke: accentDarker, strokeWidth: 1.5, strokeDasharray: "3 2" }, `l${i}`)),
31972
32728
  nodes.map((n, i) => {
@@ -31985,7 +32741,7 @@ function ShapeExchangeNode({ node, active, lang }) {
31985
32741
  };
31986
32742
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
31987
32743
  fitArt(r, \u5E83\u304C\u308A, \u7D75),
31988
- bottomLabel3(node, r.cx, r.label)
32744
+ bottomLabel3(node, r.cx, r.label, textMetrics)
31989
32745
  ] });
31990
32746
  }
31991
32747
  var ATM_SIGN_H = 26;
@@ -32002,7 +32758,12 @@ var ATM_PANEL_H = 146;
32002
32758
  var ATM_W_MIN = 100;
32003
32759
  var ATM_W_MAX = ATM_PANEL_W;
32004
32760
  var ATM_H_MIN = ATM_SIGN_H + ATM_SIGN_GAP + 30 + ATM_FLOOR_RESERVE;
32005
- function ShapeAtmNode({ node, active, lang }) {
32761
+ function ShapeAtmNode({
32762
+ node,
32763
+ active,
32764
+ lang,
32765
+ textMetrics = "proportional"
32766
+ }) {
32006
32767
  const \u5B57\u5F15 = \u5B57\u5F15\u304D\u3092\u4F5C\u308B(lang);
32007
32768
  const frame = commonFrame5(active);
32008
32769
  const r = shapeRegion(node);
@@ -32086,7 +32847,7 @@ function ShapeAtmNode({ node, active, lang }) {
32086
32847
  ] });
32087
32848
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
32088
32849
  fitArt(r, \u5E83\u304C\u308A, \u7D75),
32089
- bottomLabel3(node, r.cx, r.label)
32850
+ bottomLabel3(node, r.cx, r.label, textMetrics)
32090
32851
  ] });
32091
32852
  }
32092
32853
  var commonFrame6 = (active) => ({
@@ -32105,7 +32866,8 @@ function \u5B57\u306E\u6BD42(c) {
32105
32866
  if (\u5E83\u5B572.has(c)) return \u5E83\u5B57\u6BD42;
32106
32867
  return (c.codePointAt(0) ?? 0) < 128 ? \u4E26\u5B57\u6BD42 : \u5E83\u5B57\u6BD42;
32107
32868
  }
32108
- function \u5B57\u5E452(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593) {
32869
+ function \u5B57\u5E452(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, textMetrics = "proportional") {
32870
+ if (textMetrics === "monospace") return textWidth(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, textMetrics);
32109
32871
  let \u5E45 = 0;
32110
32872
  let \u5B57\u6570 = 0;
32111
32873
  for (const c of \u6587\u5B57\u5217) {
@@ -32114,18 +32876,33 @@ function \u5B57\u5E452(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593) {
32114
32876
  }
32115
32877
  return \u5E45 + \u5B57\u9593 * \u5B57\u6570;
32116
32878
  }
32117
- function \u5E45\u306B\u53CE\u3081\u308B4(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, \u984C\u304B = false) {
32118
- const \u5E45 = \u5B57\u5E452(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593);
32119
- const \u4E0B\u9650 = \u984C\u304B ? \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, \u5B57\u5E452) : 0;
32879
+ function \u5E45\u306B\u53CE\u3081\u308B4(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, \u984C\u304B = false, textMetrics = "proportional") {
32880
+ const \u6E2C\u308B = (t, s, ls) => \u5B57\u5E452(t, s, ls, textMetrics);
32881
+ const \u5E45 = \u6E2C\u308B(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593);
32882
+ const \u4E0B\u9650 = \u984C\u304B ? \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, \u6E2C\u308B) : 0;
32120
32883
  const \u500D\u7387 = \u5E45 > 0 && \u7BB1\u5E45 > 0 ? Math.min(1, Math.max(\u7BB1\u5E45 / \u5E45, \u4E0B\u9650)) : 1;
32121
32884
  const size = \u5927\u304D\u3055 * \u500D\u7387;
32122
32885
  const spacing = \u5B57\u9593 * \u500D\u7387;
32123
- return { size, spacing, text: \u5E2F\u3067\u5207\u308B(\u6587\u5B57\u5217, size, \u7BB1\u5E45, (u, f) => \u5B57\u5E452(u, f, spacing)) };
32124
- }
32125
- function bottomLabel4(node, cx, plan) {
32126
- const \u80A9 = \u5E45\u306B\u53CE\u3081\u308B4(node.eyebrow ?? "", plan.\u80A9\u66F8?.size ?? 0, LABEL_EYEBROW_SPACING3, node.w);
32127
- const \u540D = \u5E45\u306B\u53CE\u3081\u308B4(node.title ?? "", plan.\u540D\u524D.size, 0, node.w, true);
32128
- const \u8AAC = \u5E45\u306B\u53CE\u3081\u308B4(node.subtitle ?? "", plan.\u8AAC\u660E?.size ?? 0, 0, node.w);
32886
+ return { size, spacing, text: \u5E2F\u3067\u5207\u308B(\u6587\u5B57\u5217, size, \u7BB1\u5E45, (u, f) => \u6E2C\u308B(u, f, spacing)) };
32887
+ }
32888
+ function bottomLabel4(node, cx, plan, textMetrics = "proportional") {
32889
+ const \u80A9 = \u5E45\u306B\u53CE\u3081\u308B4(
32890
+ node.eyebrow ?? "",
32891
+ plan.\u80A9\u66F8?.size ?? 0,
32892
+ LABEL_EYEBROW_SPACING3,
32893
+ node.w,
32894
+ false,
32895
+ textMetrics
32896
+ );
32897
+ const \u540D = \u5E45\u306B\u53CE\u3081\u308B4(node.title ?? "", plan.\u540D\u524D.size, 0, node.w, true, textMetrics);
32898
+ const \u8AAC = \u5E45\u306B\u53CE\u3081\u308B4(
32899
+ node.subtitle ?? "",
32900
+ plan.\u8AAC\u660E?.size ?? 0,
32901
+ 0,
32902
+ node.w,
32903
+ false,
32904
+ textMetrics
32905
+ );
32129
32906
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
32130
32907
  node.eyebrow && plan.\u80A9\u66F8 && /* @__PURE__ */ jsxRuntime.jsx("text", { x: cx, y: plan.\u80A9\u66F8.y, fontSize: \u80A9.size, fontWeight: 700, letterSpacing: \u80A9.spacing, textAnchor: "middle", fill: "var(--cdl-tone-accent, #2d6a8f)", children: \u80A9.text }),
32131
32908
  /* @__PURE__ */ jsxRuntime.jsx("text", { "data-cdl-role": "node-label", x: cx, y: plan.\u540D\u524D.y, fontSize: \u540D.size, fontWeight: 700, textAnchor: "middle", fill: "var(--cdl-text, #1a1f2a)", children: \u540D.text }),
@@ -32137,7 +32914,7 @@ var WEBSITE_BAR_H = 32;
32137
32914
  var WEBSITE_H_MIN = WEBSITE_BAR_H + 98;
32138
32915
  var WEBSITE_W_MIN = 160;
32139
32916
  var WEBSITE_W_MAX = 280;
32140
- function ShapeWebsiteNode({ node, active }) {
32917
+ function ShapeWebsiteNode({ node, active, textMetrics = "proportional" }) {
32141
32918
  const frame = commonFrame6(active);
32142
32919
  const r = shapeRegion(node);
32143
32920
  const cx = r.cx;
@@ -32163,10 +32940,10 @@ function ShapeWebsiteNode({ node, active }) {
32163
32940
  ] });
32164
32941
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
32165
32942
  fitArt(r, \u5E83\u304C\u308A, \u7D75),
32166
- bottomLabel4(node, r.cx, r.label)
32943
+ bottomLabel4(node, r.cx, r.label, textMetrics)
32167
32944
  ] });
32168
32945
  }
32169
- function ShapeStorefrontNode({ node, active, lang }) {
32946
+ function ShapeStorefrontNode({ node, active, lang, textMetrics = "proportional" }) {
32170
32947
  const \u5B57\u5F15 = \u5B57\u5F15\u304D\u3092\u4F5C\u308B(lang);
32171
32948
  const frame = commonFrame6(active);
32172
32949
  const r = shapeRegion(node);
@@ -32211,7 +32988,7 @@ function ShapeStorefrontNode({ node, active, lang }) {
32211
32988
  /* @__PURE__ */ jsxRuntime.jsx("text", { x: doorX + doorW / 2, y: doorY + doorH * 0.85 + 11, fontSize: 11, fontWeight: 700, letterSpacing: 1, textAnchor: "middle", fill: "#5a3a10", children: \u5B57\u5F15("storefront.open") }),
32212
32989
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: doorX + 6, cy: doorY + doorH * 0.55, r: 1.5, fill: "#c15a4a" }),
32213
32990
  /* @__PURE__ */ jsxRuntime.jsx("rect", { x: x - 6, y: y + bh - 6, width: bw + 12, height: 8, fill: "#5a6270", stroke: "none" }),
32214
- bottomLabel4(node, r.cx, r.label)
32991
+ bottomLabel4(node, r.cx, r.label, textMetrics)
32215
32992
  ] });
32216
32993
  }
32217
32994
  var WAREHOUSE_ROOF_H = 18;
@@ -32225,7 +33002,7 @@ var WAREHOUSE_SHADOW_RX_RATIO = 0.5;
32225
33002
  var WAREHOUSE_H_MIN = WAREHOUSE_ROOF_H + WAREHOUSE_SIGN_H + 68;
32226
33003
  var WAREHOUSE_W_MIN = 160;
32227
33004
  var WAREHOUSE_W_MAX = 240;
32228
- function ShapeWarehouseNode({ node, active, lang }) {
33005
+ function ShapeWarehouseNode({ node, active, lang, textMetrics = "proportional" }) {
32229
33006
  const \u5B57\u5F15 = \u5B57\u5F15\u304D\u3092\u4F5C\u308B(lang);
32230
33007
  const frame = commonFrame6(active);
32231
33008
  const r = shapeRegion(node);
@@ -32278,13 +33055,13 @@ function ShapeWarehouseNode({ node, active, lang }) {
32278
33055
  ] });
32279
33056
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
32280
33057
  fitArt(r, \u5E83\u304C\u308A, \u7D75),
32281
- bottomLabel4(node, r.cx, r.label)
33058
+ bottomLabel4(node, r.cx, r.label, textMetrics)
32282
33059
  ] });
32283
33060
  }
32284
33061
  var HANDLE_GRIP_X = 118;
32285
33062
  var HANDLE_GRIP_R = 4;
32286
33063
  var CART_SHADOW_RX = 80;
32287
- function ShapeOnlineShopNode({ node, active }) {
33064
+ function ShapeOnlineShopNode({ node, active, textMetrics = "proportional" }) {
32288
33065
  const frame = commonFrame6(active);
32289
33066
  const r = shapeRegion(node);
32290
33067
  const cy = r.cy + 10;
@@ -32340,10 +33117,10 @@ function ShapeOnlineShopNode({ node, active }) {
32340
33117
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: wheelR, cy: wheelY, r: 16 * s, fill: "#0f1830", stroke: "#000", strokeWidth: 2 * s }),
32341
33118
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: wheelR, cy: wheelY, r: 8 * s, fill: "#5a6270", stroke: "#0f1830", strokeWidth: 1.5 * s }),
32342
33119
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: wheelR, cy: wheelY, r: 2 * s, fill: "#0f1830" }),
32343
- bottomLabel4(node, r.cx, r.label)
33120
+ bottomLabel4(node, r.cx, r.label, textMetrics)
32344
33121
  ] });
32345
33122
  }
32346
- function ShapeCdnEdgeNode({ node, active }) {
33123
+ function ShapeCdnEdgeNode({ node, active, textMetrics = "proportional" }) {
32347
33124
  const frame = commonFrame6(active);
32348
33125
  const r = shapeRegion(node);
32349
33126
  const cx = r.cx;
@@ -32406,7 +33183,7 @@ function ShapeCdnEdgeNode({ node, active }) {
32406
33183
  ] });
32407
33184
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
32408
33185
  fitArt(r, { \u4E0A: \u5E83\u304C\u308A, \u4E0B: \u5E83\u304C\u308A, \u5DE6: \u5E83\u304C\u308A, \u53F3: \u5E83\u304C\u308A }, \u7D75),
32409
- bottomLabel4(node, r.cx, r.label)
33186
+ bottomLabel4(node, r.cx, r.label, textMetrics)
32410
33187
  ] });
32411
33188
  }
32412
33189
  var API_ROW_TOP = 52;
@@ -32421,7 +33198,7 @@ var API_METHOD_BOX_W = 54;
32421
33198
  var API_METHOD_TEXT_W = 48;
32422
33199
  var API_W_MIN = 200;
32423
33200
  var API_W_MAX = 300;
32424
- function ShapeApiGatewayNode({ node, active, lang }) {
33201
+ function ShapeApiGatewayNode({ node, active, lang, textMetrics = "proportional" }) {
32425
33202
  const \u5B57\u5F15 = \u5B57\u5F15\u304D\u3092\u4F5C\u308B(lang);
32426
33203
  const frame = commonFrame6(active);
32427
33204
  const r = shapeRegion(node);
@@ -32433,7 +33210,13 @@ function ShapeApiGatewayNode({ node, active, lang }) {
32433
33210
  const x = cx - bw / 2;
32434
33211
  const y = r.cy - \u7E26 / 2 + \u4F59\u767D;
32435
33212
  const \u5E83\u304C\u308A = { \u4E0A: \u7E26 / 2, \u4E0B: \u7E26 / 2, \u5DE6: bw / 2 + \u4F59\u767D, \u53F3: bw / 2 + \u4F59\u767D };
32436
- const \u7A2E\u985E\u306E\u5B57 = (s) => Math.min(11, 11 * API_METHOD_TEXT_W / Math.max(displayWidth(s) * 11 * MONO_ADVANCE_RATIO, textWidth(s, 11)));
33213
+ const \u7A2E\u985E\u306E\u5B57 = (s) => Math.min(
33214
+ 11,
33215
+ 11 * API_METHOD_TEXT_W / Math.max(
33216
+ displayWidth(s) * 11 * MONO_ADVANCE_RATIO,
33217
+ textWidth(s, 11, 0, textMetrics)
33218
+ )
33219
+ );
32437
33220
  const rowPitch = Math.max(
32438
33221
  API_ROW_PITCH_MIN,
32439
33222
  (bh - API_ROW_TOP - API_ROW_H - API_ROW_BOTTOM_PAD) / (API_ROWS - 1)
@@ -32449,7 +33232,7 @@ function ShapeApiGatewayNode({ node, active, lang }) {
32449
33232
  \u5E2F: { \u5E45: bw - 32 - 64 - 16, \u9AD8\u3055: API_ROW_H }
32450
33233
  }));
32451
33234
  const \u7D75 = (\u500D\u7387) => {
32452
- const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089);
33235
+ const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089, textMetrics);
32453
33236
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
32454
33237
  /* @__PURE__ */ jsxRuntime.jsx("rect", { x: x + DROP_SHADOW_D, y: y + DROP_SHADOW_D, width: bw, height: bh, rx: 10, fill: frame.stroke, opacity: 0.2, stroke: "none" }),
32455
33238
  /* @__PURE__ */ jsxRuntime.jsx("rect", { "data-cdl-role": "node-body", x, y, width: bw, height: bh, rx: 10, fill: "#1a2332", stroke: frame.stroke, strokeWidth: frame.strokeWidth }),
@@ -32466,7 +33249,7 @@ function ShapeApiGatewayNode({ node, active, lang }) {
32466
33249
  };
32467
33250
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
32468
33251
  fitArt(r, \u5E83\u304C\u308A, \u7D75),
32469
- bottomLabel4(node, r.cx, r.label)
33252
+ bottomLabel4(node, r.cx, r.label, textMetrics)
32470
33253
  ] });
32471
33254
  }
32472
33255
  function bottomLabel5(node, cx, plan) {
@@ -32766,6 +33549,7 @@ function CdlNodeView({
32766
33549
  chartLineScale,
32767
33550
  \u95A2\u4FC2\u306E\u53D7\u3051\u53E3,
32768
33551
  lang,
33552
+ textMetrics,
32769
33553
  \u5024\u306E\u540D\u524D
32770
33554
  }) {
32771
33555
  const value = node.value ? interpolate(node.value, stateValues, \u5024\u306E\u540D\u524D) : void 0;
@@ -32810,7 +33594,14 @@ function CdlNodeView({
32810
33594
  return /* @__PURE__ */ jsxRuntime.jsx(CardNode, { node: resolvedNode, active });
32811
33595
  // 時系列のやり取り (#578)。 1 つの箱が図を丸ごと描く = 縦が時間で、参加者は箱を持たない
32812
33596
  case "sequence-board":
32813
- return /* @__PURE__ */ jsxRuntime.jsx(SequenceBoardNode, { node: resolvedNode, stateValues });
33597
+ return /* @__PURE__ */ jsxRuntime.jsx(
33598
+ SequenceBoardNode,
33599
+ {
33600
+ node: resolvedNode,
33601
+ stateValues,
33602
+ textMetrics
33603
+ }
33604
+ );
32814
33605
  // 図表 9 種は payload が `{signal}` を取れるので stateValues を渡す
32815
33606
  // (`render/payload-binding.ts` が描画直前に解決する)。 取れる欄は種別で違い、
32816
33607
  // 数と語を取る 7 種に対し、mind-map / tree-hierarchy は **名前だけ** を取る (#467)。
@@ -32835,7 +33626,8 @@ function CdlNodeView({
32835
33626
  active,
32836
33627
  stateValues,
32837
33628
  drawing,
32838
- progress
33629
+ progress,
33630
+ textMetrics
32839
33631
  }
32840
33632
  );
32841
33633
  case "chart-gauge":
@@ -32846,7 +33638,8 @@ function CdlNodeView({
32846
33638
  active,
32847
33639
  stateValues,
32848
33640
  drawing,
32849
- progress
33641
+ progress,
33642
+ textMetrics
32850
33643
  }
32851
33644
  );
32852
33645
  case "chart-stacked-bar":
@@ -32857,7 +33650,8 @@ function CdlNodeView({
32857
33650
  active,
32858
33651
  stateValues,
32859
33652
  drawing,
32860
- progress
33653
+ progress,
33654
+ textMetrics
32861
33655
  }
32862
33656
  );
32863
33657
  case "chart-slope":
@@ -32868,7 +33662,8 @@ function CdlNodeView({
32868
33662
  active,
32869
33663
  stateValues,
32870
33664
  drawing,
32871
- progress
33665
+ progress,
33666
+ textMetrics
32872
33667
  }
32873
33668
  );
32874
33669
  case "chart-waffle":
@@ -32879,11 +33674,20 @@ function CdlNodeView({
32879
33674
  active,
32880
33675
  stateValues,
32881
33676
  drawing,
32882
- progress
33677
+ progress,
33678
+ textMetrics
32883
33679
  }
32884
33680
  );
32885
33681
  case "chart-stat":
32886
- return /* @__PURE__ */ jsxRuntime.jsx(ChartStatNode, { node: resolvedNode, active, stateValues });
33682
+ return /* @__PURE__ */ jsxRuntime.jsx(
33683
+ ChartStatNode,
33684
+ {
33685
+ node: resolvedNode,
33686
+ active,
33687
+ stateValues,
33688
+ textMetrics
33689
+ }
33690
+ );
32887
33691
  case "chart-radial":
32888
33692
  return /* @__PURE__ */ jsxRuntime.jsx(
32889
33693
  ChartRadialNode,
@@ -32892,7 +33696,8 @@ function CdlNodeView({
32892
33696
  active,
32893
33697
  stateValues,
32894
33698
  drawing,
32895
- progress
33699
+ progress,
33700
+ textMetrics
32896
33701
  }
32897
33702
  );
32898
33703
  case "chart-bar":
@@ -32925,7 +33730,8 @@ function CdlNodeView({
32925
33730
  active,
32926
33731
  stateValues,
32927
33732
  drawing,
32928
- progress
33733
+ progress,
33734
+ textMetrics
32929
33735
  }
32930
33736
  );
32931
33737
  case "funnel-stages":
@@ -32936,11 +33742,20 @@ function CdlNodeView({
32936
33742
  active,
32937
33743
  stateValues,
32938
33744
  drawing,
32939
- progress
33745
+ progress,
33746
+ textMetrics
32940
33747
  }
32941
33748
  );
32942
33749
  case "quadrant-matrix":
32943
- return /* @__PURE__ */ jsxRuntime.jsx(QuadrantNode, { node: resolvedNode, active, stateValues });
33750
+ return /* @__PURE__ */ jsxRuntime.jsx(
33751
+ QuadrantNode,
33752
+ {
33753
+ node: resolvedNode,
33754
+ active,
33755
+ stateValues,
33756
+ textMetrics
33757
+ }
33758
+ );
32944
33759
  case "tree-hierarchy":
32945
33760
  return /* @__PURE__ */ jsxRuntime.jsx(
32946
33761
  TreeNode,
@@ -32949,7 +33764,8 @@ function CdlNodeView({
32949
33764
  active,
32950
33765
  stateValues,
32951
33766
  drawing,
32952
- progress
33767
+ progress,
33768
+ textMetrics
32953
33769
  }
32954
33770
  );
32955
33771
  case "journey-map":
@@ -32964,91 +33780,91 @@ function CdlNodeView({
32964
33780
  }
32965
33781
  );
32966
33782
  case "shape-file":
32967
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeFileNode, { node: resolvedNode, active });
33783
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeFileNode, { node: resolvedNode, active, textMetrics });
32968
33784
  case "shape-folder":
32969
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeFolderNode, { node: resolvedNode, active });
33785
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeFolderNode, { node: resolvedNode, active, textMetrics });
32970
33786
  case "shape-cloud":
32971
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeCloudNode, { node: resolvedNode, active });
33787
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeCloudNode, { node: resolvedNode, active, textMetrics });
32972
33788
  case "shape-cylinder":
32973
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeCylinderNode, { node: resolvedNode, active });
33789
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeCylinderNode, { node: resolvedNode, active, textMetrics });
32974
33790
  case "shape-hexagon":
32975
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeHexagonNode, { node: resolvedNode, active });
33791
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeHexagonNode, { node: resolvedNode, active, textMetrics });
32976
33792
  case "shape-diamond":
32977
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeDiamondNode, { node: resolvedNode, active });
33793
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeDiamondNode, { node: resolvedNode, active, textMetrics });
32978
33794
  case "shape-stack":
32979
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeStackNode, { node: resolvedNode, active });
33795
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeStackNode, { node: resolvedNode, active, textMetrics });
32980
33796
  case "shape-person":
32981
- return /* @__PURE__ */ jsxRuntime.jsx(ShapePersonNode, { node: resolvedNode, active });
33797
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapePersonNode, { node: resolvedNode, active, textMetrics });
32982
33798
  case "shape-window":
32983
33799
  return /* @__PURE__ */ jsxRuntime.jsx(ShapeWindowNode, { node: resolvedNode, active });
32984
33800
  case "shape-terminal":
32985
33801
  return /* @__PURE__ */ jsxRuntime.jsx(ShapeTerminalNode, { node: resolvedNode, active, lang });
32986
33802
  case "shape-code-block":
32987
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeCodeBlockNode, { node: resolvedNode, active, lang });
33803
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeCodeBlockNode, { node: resolvedNode, active, lang, textMetrics });
32988
33804
  case "shape-kanban-card":
32989
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeKanbanCardNode, { node: resolvedNode, active, lang });
33805
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeKanbanCardNode, { node: resolvedNode, active, lang, textMetrics });
32990
33806
  case "shape-message-bubble":
32991
33807
  return /* @__PURE__ */ jsxRuntime.jsx(ShapeMessageBubbleNode, { node: resolvedNode, active });
32992
33808
  case "shape-gear":
32993
33809
  return /* @__PURE__ */ jsxRuntime.jsx(ShapeGearNode, { node: resolvedNode, active });
32994
33810
  case "shape-server-rack":
32995
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeServerRackNode, { node: resolvedNode, active });
33811
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeServerRackNode, { node: resolvedNode, active, textMetrics });
32996
33812
  case "shape-network-node":
32997
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeNetworkNodeNode, { node: resolvedNode, active });
33813
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeNetworkNodeNode, { node: resolvedNode, active, textMetrics });
32998
33814
  case "shape-mobile-device":
32999
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeMobileDeviceNode, { node: resolvedNode, active });
33815
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeMobileDeviceNode, { node: resolvedNode, active, textMetrics });
33000
33816
  case "shape-iot-sensor":
33001
33817
  return /* @__PURE__ */ jsxRuntime.jsx(ShapeIotSensorNode, { node: resolvedNode, active });
33002
33818
  case "shape-robot-arm":
33003
33819
  return /* @__PURE__ */ jsxRuntime.jsx(ShapeRobotArmNode, { node: resolvedNode, active });
33004
33820
  case "shape-satellite":
33005
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeSatelliteNode, { node: resolvedNode, active });
33821
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeSatelliteNode, { node: resolvedNode, active, textMetrics });
33006
33822
  case "shape-smart-contract":
33007
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeSmartContractNode, { node: resolvedNode, active, lang });
33823
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeSmartContractNode, { node: resolvedNode, active, lang, textMetrics });
33008
33824
  case "shape-blockchain-block":
33009
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeBlockchainBlockNode, { node: resolvedNode, active, lang });
33825
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeBlockchainBlockNode, { node: resolvedNode, active, lang, textMetrics });
33010
33826
  case "shape-rpc-node":
33011
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeRpcNodeNode, { node: resolvedNode, active, lang });
33827
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeRpcNodeNode, { node: resolvedNode, active, lang, textMetrics });
33012
33828
  case "shape-wallet":
33013
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeWalletNode, { node: resolvedNode, active });
33829
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeWalletNode, { node: resolvedNode, active, textMetrics });
33014
33830
  case "shape-nft":
33015
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeNftNode, { node: resolvedNode, active });
33831
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeNftNode, { node: resolvedNode, active, textMetrics });
33016
33832
  case "shape-token":
33017
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeTokenNode, { node: resolvedNode, active });
33833
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeTokenNode, { node: resolvedNode, active, textMetrics });
33018
33834
  case "shape-blockchain":
33019
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeBlockchainNode, { node: resolvedNode, active });
33835
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeBlockchainNode, { node: resolvedNode, active, textMetrics });
33020
33836
  case "shape-bitcoin-chain":
33021
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeBitcoinChainNode, { node: resolvedNode, active });
33837
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeBitcoinChainNode, { node: resolvedNode, active, textMetrics });
33022
33838
  case "shape-ethereum-chain":
33023
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeEthereumChainNode, { node: resolvedNode, active });
33839
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeEthereumChainNode, { node: resolvedNode, active, textMetrics });
33024
33840
  case "shape-blockchain-node":
33025
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeBlockchainNodeNode, { node: resolvedNode, active });
33841
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeBlockchainNodeNode, { node: resolvedNode, active, textMetrics });
33026
33842
  case "shape-bank":
33027
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeBankNode, { node: resolvedNode, active });
33843
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeBankNode, { node: resolvedNode, active, textMetrics });
33028
33844
  case "shape-trust-bank":
33029
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeTrustBankNode, { node: resolvedNode, active, lang });
33845
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeTrustBankNode, { node: resolvedNode, active, lang, textMetrics });
33030
33846
  case "shape-payment-provider":
33031
- return /* @__PURE__ */ jsxRuntime.jsx(ShapePaymentProviderNode, { node: resolvedNode, active, lang });
33847
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapePaymentProviderNode, { node: resolvedNode, active, lang, textMetrics });
33032
33848
  case "shape-credit-card":
33033
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeCreditCardNode, { node: resolvedNode, active });
33849
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeCreditCardNode, { node: resolvedNode, active, textMetrics });
33034
33850
  case "shape-brokerage":
33035
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeBrokerageNode, { node: resolvedNode, active, lang });
33851
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeBrokerageNode, { node: resolvedNode, active, lang, textMetrics });
33036
33852
  case "shape-exchange":
33037
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeExchangeNode, { node: resolvedNode, active, lang });
33853
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeExchangeNode, { node: resolvedNode, active, lang, textMetrics });
33038
33854
  case "shape-atm":
33039
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeAtmNode, { node: resolvedNode, active, lang });
33855
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeAtmNode, { node: resolvedNode, active, lang, textMetrics });
33040
33856
  case "shape-website":
33041
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeWebsiteNode, { node: resolvedNode, active });
33857
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeWebsiteNode, { node: resolvedNode, active, textMetrics });
33042
33858
  case "shape-storefront":
33043
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeStorefrontNode, { node: resolvedNode, active, lang });
33859
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeStorefrontNode, { node: resolvedNode, active, lang, textMetrics });
33044
33860
  case "shape-warehouse":
33045
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeWarehouseNode, { node: resolvedNode, active, lang });
33861
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeWarehouseNode, { node: resolvedNode, active, lang, textMetrics });
33046
33862
  case "shape-online-shop":
33047
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeOnlineShopNode, { node: resolvedNode, active });
33863
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeOnlineShopNode, { node: resolvedNode, active, textMetrics });
33048
33864
  case "shape-cdn-edge":
33049
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeCdnEdgeNode, { node: resolvedNode, active });
33865
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeCdnEdgeNode, { node: resolvedNode, active, textMetrics });
33050
33866
  case "shape-api-gateway":
33051
- return /* @__PURE__ */ jsxRuntime.jsx(ShapeApiGatewayNode, { node: resolvedNode, active, lang });
33867
+ return /* @__PURE__ */ jsxRuntime.jsx(ShapeApiGatewayNode, { node: resolvedNode, active, lang, textMetrics });
33052
33868
  case "shape-auditor":
33053
33869
  return /* @__PURE__ */ jsxRuntime.jsx(ShapeAuditorNode, { node: resolvedNode, active });
33054
33870
  case "shape-regulator":
@@ -33065,8 +33881,20 @@ function CdlNodeView({
33065
33881
  return /* @__PURE__ */ jsxRuntime.jsx(MarkStartNode, { node: resolvedNode, active });
33066
33882
  case "mark-end":
33067
33883
  return /* @__PURE__ */ jsxRuntime.jsx(MarkEndNode, { node: resolvedNode, active });
33884
+ case "station":
33885
+ return /* @__PURE__ */ jsxRuntime.jsx(StationNode, { node: resolvedNode, active });
33068
33886
  default:
33069
- return /* @__PURE__ */ jsxRuntime.jsx(GenericNode, { node: resolvedNode, active, value: node.value, stateValues, \u5024\u306E\u540D\u524D });
33887
+ return /* @__PURE__ */ jsxRuntime.jsx(
33888
+ GenericNode,
33889
+ {
33890
+ node: resolvedNode,
33891
+ active,
33892
+ value: node.value,
33893
+ stateValues,
33894
+ \u5024\u306E\u540D\u524D,
33895
+ textMetrics
33896
+ }
33897
+ );
33070
33898
  }
33071
33899
  })();
33072
33900
  const offsetX = node.renderOffsetX !== void 0 ? resolveNumericAttr(node.renderOffsetX, stateValues, 0) : 0;
@@ -33127,7 +33955,7 @@ function CdlNodeView({
33127
33955
  }
33128
33956
  ),
33129
33957
  inner,
33130
- \u7BB1\u306E\u4E0A\u306E\u8A9E(resolvedNode)
33958
+ \u7BB1\u306E\u4E0A\u306E\u8A9E(resolvedNode, textMetrics ?? "proportional")
33131
33959
  ]
33132
33960
  }
33133
33961
  );
@@ -33136,17 +33964,17 @@ var FIGURE_TITLE_GAP = 10;
33136
33964
  var FIGURE_TITLE_SIZE = 15;
33137
33965
  var FIGURE_EYEBROW_SIZE = 11;
33138
33966
  var FIGURE_EYEBROW_LIFT = 1.1;
33139
- function \u5E45\u306B\u53CE\u3081\u305F\u5927\u304D\u3055(\u8A9E, \u7D20\u306E\u5927\u304D\u3055, \u5E45) {
33140
- const \u5B9F\u5E45 = textWidth(\u8A9E, \u7D20\u306E\u5927\u304D\u3055, 0);
33967
+ function \u5E45\u306B\u53CE\u3081\u305F\u5927\u304D\u3055(\u8A9E, \u7D20\u306E\u5927\u304D\u3055, \u5E45, textMetrics = "proportional") {
33968
+ const \u5B9F\u5E45 = textWidth(\u8A9E, \u7D20\u306E\u5927\u304D\u3055, 0, textMetrics);
33141
33969
  return \u5B9F\u5E45 > \u5E45 ? \u7D20\u306E\u5927\u304D\u3055 * \u5E45 / \u5B9F\u5E45 : \u7D20\u306E\u5927\u304D\u3055;
33142
33970
  }
33143
- function \u7BB1\u306E\u4E0A\u306E\u8A9E(node) {
33971
+ function \u7BB1\u306E\u4E0A\u306E\u8A9E(node, textMetrics = "proportional") {
33144
33972
  if (!drawsFigureTitle(node.kind)) return null;
33145
33973
  const \u540D\u524D = (node.title ?? "").trim();
33146
33974
  const \u5C0F\u898B\u51FA\u3057 = (node.eyebrow ?? "").trim();
33147
33975
  if (\u540D\u524D === "" && \u5C0F\u898B\u51FA\u3057 === "") return null;
33148
33976
  const \u984C\u306Ey = node.cy - node.h / 2 - FIGURE_TITLE_GAP;
33149
- const \u984C\u306E\u5927\u304D\u3055 = \u5E45\u306B\u53CE\u3081\u305F\u5927\u304D\u3055(\u540D\u524D, FIGURE_TITLE_SIZE, node.w);
33977
+ const \u984C\u306E\u5927\u304D\u3055 = \u5E45\u306B\u53CE\u3081\u305F\u5927\u304D\u3055(\u540D\u524D, FIGURE_TITLE_SIZE, node.w, textMetrics);
33150
33978
  const \u5C0F\u898B\u51FA\u3057\u306Ey = \u540D\u524D === "" ? \u984C\u306Ey : \u984C\u306Ey - \u984C\u306E\u5927\u304D\u3055 * FIGURE_EYEBROW_LIFT;
33151
33979
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
33152
33980
  \u5C0F\u898B\u51FA\u3057 !== "" && /* @__PURE__ */ jsxRuntime.jsx(
@@ -33156,7 +33984,7 @@ function \u7BB1\u306E\u4E0A\u306E\u8A9E(node) {
33156
33984
  x: node.cx,
33157
33985
  y: \u5C0F\u898B\u51FA\u3057\u306Ey,
33158
33986
  textAnchor: "middle",
33159
- fontSize: \u5E45\u306B\u53CE\u3081\u305F\u5927\u304D\u3055(\u5C0F\u898B\u51FA\u3057, FIGURE_EYEBROW_SIZE, node.w),
33987
+ fontSize: \u5E45\u306B\u53CE\u3081\u305F\u5927\u304D\u3055(\u5C0F\u898B\u51FA\u3057, FIGURE_EYEBROW_SIZE, node.w, textMetrics),
33160
33988
  fontWeight: 600,
33161
33989
  letterSpacing: 0.6,
33162
33990
  fill: "var(--cdl-text-dim, #5a6270)",
@@ -33297,15 +34125,15 @@ function CdlStage({
33297
34125
  }, [laid]);
33298
34126
  const edgeHeadMarkers = react.useMemo(() => {
33299
34127
  const referenced = /* @__PURE__ */ new Set();
33300
- const add = (tone, head, fill) => {
34128
+ const add2 = (tone, head, fill) => {
33301
34129
  for (const small of [false, true]) {
33302
34130
  const id = edgeHeadMarkerName(tone, head, small, fill);
33303
34131
  if (id !== void 0) referenced.add(id);
33304
34132
  }
33305
34133
  };
33306
34134
  for (const edge of laid.edges) {
33307
- add(edge.tone, edge.head, edge.headFill);
33308
- if (edge.tailHead !== void 0) add(edge.tone, edge.tailHead, edge.tailHeadFill);
34135
+ add2(edge.tone, edge.head, edge.headFill);
34136
+ if (edge.tailHead !== void 0) add2(edge.tone, edge.tailHead, edge.tailHeadFill);
33309
34137
  }
33310
34138
  return Object.entries(TONE).flatMap(
33311
34139
  ([tone, color]) => [
@@ -33481,6 +34309,7 @@ function CdlStage({
33481
34309
  node,
33482
34310
  active: activeSet.has(node.id),
33483
34311
  lang: laid.lang,
34312
+ textMetrics: laid.textMetrics,
33484
34313
  \u95A2\u4FC2\u306E\u53D7\u3051\u53E3: \u7BB1\u306E\u53D7\u3051\u53E3,
33485
34314
  drawing: \u63CF\u304F,
33486
34315
  progress: \u63CF\u304F ? \u63CF\u304F\u9032\u307F : progress,
@@ -33497,7 +34326,8 @@ function CdlStage({
33497
34326
  CdlEdgeLabelView,
33498
34327
  {
33499
34328
  edge,
33500
- active: activeSet.has(edge.id)
34329
+ active: activeSet.has(edge.id),
34330
+ textMetrics: laid.textMetrics
33501
34331
  },
33502
34332
  `label-${edge.id}`
33503
34333
  )),
@@ -33507,7 +34337,8 @@ function CdlStage({
33507
34337
  {
33508
34338
  edge,
33509
34339
  active: activeSet.has(edge.id),
33510
- \u7AEF
34340
+ \u7AEF,
34341
+ textMetrics: laid.textMetrics
33511
34342
  },
33512
34343
  `${\u7AEF}-label-${edge.id}`
33513
34344
  ))
@@ -33952,8 +34783,8 @@ function pointToSegmentDistance2(px, py, seg) {
33952
34783
  }
33953
34784
 
33954
34785
  // src/layout/predict-bbox.ts
33955
- function predictLabelBBoxWorld(edge) {
33956
- return computeLabelBBoxWorld(edge);
34786
+ function predictLabelBBoxWorld(edge, textMetrics = "proportional") {
34787
+ return computeLabelBBoxWorld(edge, textMetrics);
33957
34788
  }
33958
34789
  function predictNodeBBoxWorld(n) {
33959
34790
  return {
@@ -34013,12 +34844,12 @@ function resolveStorageBoxW(width, presetName, optionName) {
34013
34844
  }
34014
34845
  return width;
34015
34846
  }
34016
- function fitRowsWidth(boxW, rows) {
34017
- return Math.max(boxW, requiredRowsWidth(rows ? [...rows] : void 0, "storage"));
34847
+ function fitRowsWidth(boxW, rows, textMetrics = "proportional") {
34848
+ return Math.max(boxW, requiredRowsWidth(rows ? [...rows] : void 0, "storage", textMetrics));
34018
34849
  }
34019
34850
  function swimlane(preset) {
34020
34851
  const w = preset.laneWidth ?? 400;
34021
- const b = diagram(preset.id, { topic: preset.topic, type: "swimlane" });
34852
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "swimlane" });
34022
34853
  const labelToId = /* @__PURE__ */ new Map();
34023
34854
  const idsInOrder = [];
34024
34855
  for (const label of preset.lanes) {
@@ -34038,7 +34869,7 @@ function swimlane(preset) {
34038
34869
  }
34039
34870
  function flow(preset) {
34040
34871
  const w = preset.laneWidth ?? 400;
34041
- const b = diagram(preset.id, { topic: preset.topic, type: "flow" });
34872
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "flow" });
34042
34873
  b.lane("flow", { width: w, ...preset.laneLabel ? { label: preset.laneLabel } : {} });
34043
34874
  const tone = preset.defaultTone ?? "accent";
34044
34875
  const style = preset.defaultStyle ?? "dotted-flow";
@@ -34099,7 +34930,7 @@ var SEQUENCE_MESSAGE_LOOK = {
34099
34930
  };
34100
34931
  function sequence(preset) {
34101
34932
  const tone = preset.defaultTone ?? "accent";
34102
- const b = diagram(preset.id, { topic: preset.topic, type: "sequence" });
34933
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "sequence" });
34103
34934
  const \u9762\u3005 = preset.actors.map(
34104
34935
  (a) => typeof a === "string" ? { name: a } : { name: a.name, ...a.subtitle ? { subtitle: a.subtitle } : {} }
34105
34936
  );
@@ -34125,7 +34956,7 @@ function sequence(preset) {
34125
34956
  return \u51FA\u756A.length > 0 ? { actor: i, from: \u51FA\u756A[0], to: \u51FA\u756A[\u51FA\u756A.length - 1] } : null;
34126
34957
  }).filter((x) => x !== null);
34127
34958
  const data = { actors: \u9762\u3005, messages: \u8A00\u3065\u3066, bands: \u5E2F };
34128
- const m = sequenceBoardMetrics(data);
34959
+ const m = sequenceBoardMetrics(data, resolveTextMetrics(preset.textMetrics));
34129
34960
  const laneId = "seq";
34130
34961
  b.lane(laneId, { width: m.w + LANE_PAD_MIN * 2 });
34131
34962
  b.node(preset.id, {
@@ -34154,7 +34985,7 @@ function topology(preset) {
34154
34985
  const groupW = preset.groupWidth ?? 460;
34155
34986
  const tone = preset.defaultTone ?? "accent";
34156
34987
  const style = preset.defaultStyle ?? "solid";
34157
- const b = diagram(preset.id, { topic: preset.topic, type: "topology" });
34988
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "topology" });
34158
34989
  const groupOrder = [];
34159
34990
  const groupStackCount = /* @__PURE__ */ new Map();
34160
34991
  const phaseActivate = [];
@@ -34223,7 +35054,12 @@ function er(preset) {
34223
35054
  const entityW = resolveStorageBoxW(preset.entityWidth, "er", "entityWidth");
34224
35055
  const tone = preset.defaultTone ?? "info";
34225
35056
  const \u7E1E\u3092\u6577\u304F = preset.rowStripe ?? true;
34226
- const b = diagram(preset.id, { topic: preset.topic, palette: preset.palette, type: "er" });
35057
+ const b = diagram(preset.id, {
35058
+ topic: preset.topic,
35059
+ palette: preset.palette,
35060
+ textMetrics: preset.textMetrics,
35061
+ type: "er"
35062
+ });
34227
35063
  const entities = [];
34228
35064
  const phaseActivate = [];
34229
35065
  let relIdx = 0;
@@ -34246,7 +35082,7 @@ function er(preset) {
34246
35082
  \u5024.forEach(\u8DB3\u3059);
34247
35083
  const \u8A2D\u8A08\u306E\u5F62 = \u884C.length > 0;
34248
35084
  const rows = \u8A2D\u8A08\u306E\u5F62 ? \u884C : e.rows ?? [];
34249
- const boxW = fitRowsWidth(entityW, rows);
35085
+ const boxW = fitRowsWidth(entityW, rows, resolveTextMetrics(preset.textMetrics));
34250
35086
  b.lane(laneId, { width: boxLaneW(boxW) });
34251
35087
  b.node(e.id, {
34252
35088
  lane: laneId,
@@ -34310,7 +35146,7 @@ function stateMachine(preset) {
34310
35146
  const stateW = resolveStateW(preset.stateWidth, "stateMachine");
34311
35147
  const tone = preset.defaultTone ?? "accent";
34312
35148
  const diagramType = "state";
34313
- const b = diagram(preset.id, { topic: preset.topic, type: diagramType });
35149
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: diagramType });
34314
35150
  const phaseActivate = [];
34315
35151
  const stateOrder = /* @__PURE__ */ new Map();
34316
35152
  const \u72B6\u614B = [];
@@ -34341,7 +35177,7 @@ function stateMachine(preset) {
34341
35177
  const \u884C = (s.actions ?? []).map((a) => a.note ? `${a.label}: ${a.note}` : a.label);
34342
35178
  const \u5370 = (s.actions ?? []).map((a) => FSM_ACTION_MARK[a.when]);
34343
35179
  const laneId = \u683C\u5B50 && s.col !== void 0 ? `col-${s.col}` : `lane-${s.id}`;
34344
- const boxW = \u8A2D\u8A08\u306E\u5F62 ? fitRowsWidth(stateW, \u884C) : stateW;
35180
+ const boxW = \u8A2D\u8A08\u306E\u5F62 ? fitRowsWidth(stateW, \u884C, resolveTextMetrics(preset.textMetrics)) : stateW;
34345
35181
  return { s, \u884C, \u5370, laneId, boxW, stack: \u683C\u5B50 ? s.row ?? 0 : 0 };
34346
35182
  });
34347
35183
  const \u7BC0\u70B9\u306E\u4E2D\u8EAB = \u7BC0\u70B9.map((m) => ({
@@ -34422,7 +35258,11 @@ function infrastructure(preset) {
34422
35258
  const laneW = preset.laneWidth ?? 380;
34423
35259
  const tone = preset.defaultTone ?? "accent";
34424
35260
  const style = preset.defaultStyle ?? "solid";
34425
- const b = diagram(preset.id, { topic: preset.topic, type: "infrastructure" });
35261
+ const b = diagram(preset.id, {
35262
+ topic: preset.topic,
35263
+ textMetrics: preset.textMetrics,
35264
+ type: "infrastructure"
35265
+ });
34426
35266
  const colLaneIds = /* @__PURE__ */ new Map();
34427
35267
  const phaseActivate = [];
34428
35268
  let connIdx = 0;
@@ -34503,7 +35343,12 @@ function classDiagram(preset) {
34503
35343
  const classW = resolveStorageBoxW(preset.classWidth, "classDiagram", "classWidth");
34504
35344
  const \u56F3\u306E\u65E2\u5B9A = preset.defaultTone;
34505
35345
  const \u7E1E\u3092\u6577\u304F = preset.rowStripe ?? true;
34506
- const b = diagram(preset.id, { topic: preset.topic, palette: preset.palette, type: "class" });
35346
+ const b = diagram(preset.id, {
35347
+ topic: preset.topic,
35348
+ palette: preset.palette,
35349
+ textMetrics: preset.textMetrics,
35350
+ type: "class"
35351
+ });
34507
35352
  const classes = [];
34508
35353
  const phaseActivate = [];
34509
35354
  const \u7BB1 = [];
@@ -34529,7 +35374,7 @@ function classDiagram(preset) {
34529
35374
  rows.push(stripAccess(m));
34530
35375
  rowMarks.push({ shape: "chevron", filled: isPublic(m) });
34531
35376
  }
34532
- const boxW = fitRowsWidth(classW, rows);
35377
+ const boxW = fitRowsWidth(classW, rows, resolveTextMetrics(preset.textMetrics));
34533
35378
  const laneId = c.col !== void 0 ? `col-${c.col}` : `lane-${c.id}`;
34534
35379
  return { c, rows, rowMarks, boxW, laneId, stack: c.col !== void 0 ? c.row ?? 0 : 0 };
34535
35380
  });
@@ -34592,7 +35437,7 @@ function classDiagram(preset) {
34592
35437
  }
34593
35438
  function tree(preset) {
34594
35439
  const canvasH = 480;
34595
- const b = diagram(preset.id, { topic: preset.topic, type: "tree" });
35440
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "tree" });
34596
35441
  const treeNodes = [];
34597
35442
  const api = {
34598
35443
  node(n) {
@@ -34631,7 +35476,7 @@ function tree(preset) {
34631
35476
  function userJourney(preset) {
34632
35477
  const canvasW = preset.stepWidth ? preset.stepWidth * 2 : 720;
34633
35478
  const canvasH = 480;
34634
- const b = diagram(preset.id, { topic: preset.topic, type: "journey" });
35479
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "journey" });
34635
35480
  const steps = [];
34636
35481
  const api = {
34637
35482
  step(s) {
@@ -34671,7 +35516,7 @@ function mindMap(preset) {
34671
35516
  const canvasW = preset.branchWidth ? preset.branchWidth * 2 : 720;
34672
35517
  const canvasH = 480;
34673
35518
  const diagramType = "mind";
34674
- const b = diagram(preset.id, { topic: preset.topic, type: diagramType });
35519
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: diagramType });
34675
35520
  const branches = [];
34676
35521
  const api = {
34677
35522
  branch(br) {
@@ -34715,7 +35560,7 @@ function mindMap(preset) {
34715
35560
  function funnel(preset) {
34716
35561
  const canvasW = toGridSize(preset.stageWidth ?? 560);
34717
35562
  const canvasH = 480;
34718
- const b = diagram(preset.id, { topic: preset.topic, type: "funnel" });
35563
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "funnel" });
34719
35564
  const stages = [];
34720
35565
  const api = {
34721
35566
  stage(s) {
@@ -34753,7 +35598,7 @@ function funnel(preset) {
34753
35598
  function quadrant(preset) {
34754
35599
  const canvasW = 640;
34755
35600
  const canvasH = 480;
34756
- const b = diagram(preset.id, { topic: preset.topic, type: "quadrant" });
35601
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "quadrant" });
34757
35602
  const items = [];
34758
35603
  const api = {
34759
35604
  item(it) {
@@ -34804,7 +35649,7 @@ function chart(preset) {
34804
35649
  const canvasH = toGridSize(
34805
35650
  preset.type === "pie" || preset.type === "gauge" || preset.type === "radial" || preset.type === "stat" || preset.type === "waffle" || preset.type === "stacked-bar" ? 320 : 360
34806
35651
  );
34807
- const b = diagram(preset.id, { topic: preset.topic, type: "chart" });
35652
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "chart" });
34808
35653
  const data = [];
34809
35654
  const kindMap = {
34810
35655
  line: "chart-line",
@@ -34854,7 +35699,7 @@ function gantt(preset) {
34854
35699
  const canvasW = preset.laneWidth ? preset.laneWidth * 2 : 720;
34855
35700
  const canvasH = 360;
34856
35701
  const tone = preset.defaultTone ?? "teal";
34857
- const b = diagram(preset.id, { topic: preset.topic, type: "gantt" });
35702
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "gantt" });
34858
35703
  const tasks = [];
34859
35704
  const api = {
34860
35705
  task(t) {
@@ -34922,7 +35767,7 @@ function flowchart(preset) {
34922
35767
  const laneW = preset.laneWidth ?? 380;
34923
35768
  const tone = preset.defaultTone ?? "accent";
34924
35769
  const \u7E26\u306B\u7A4D\u3080 = (preset.direction ?? "horizontal") === "vertical";
34925
- const b = diagram(preset.id, { topic: preset.topic, type: "flowchart" });
35770
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "flowchart" });
34926
35771
  const laneToId = /* @__PURE__ */ new Map();
34927
35772
  const laneStackCount = /* @__PURE__ */ new Map();
34928
35773
  if (\u7E26\u306B\u7A4D\u3080) {
@@ -34997,7 +35842,7 @@ var NET_KIND_LABEL = {
34997
35842
  function network(preset) {
34998
35843
  const laneW = preset.laneWidth ?? 320;
34999
35844
  const tone = preset.defaultTone ?? "info";
35000
- const b = diagram(preset.id, { topic: preset.topic, type: "network" });
35845
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "network" });
35001
35846
  const colLaneIds = /* @__PURE__ */ new Map();
35002
35847
  const phaseActivate = [];
35003
35848
  let edgeIdx = 0;
@@ -35048,7 +35893,7 @@ function stateMachine2(preset) {
35048
35893
  const laneW = boxLaneW(stateW);
35049
35894
  const tone = preset.defaultTone ?? "accent";
35050
35895
  const diagramType = "state";
35051
- const b = diagram(preset.id, { topic: preset.topic, type: diagramType });
35896
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: diagramType });
35052
35897
  const stateOrder = /* @__PURE__ */ new Map();
35053
35898
  const phaseActivate = [];
35054
35899
  let transIdx = 0;
@@ -35253,6 +36098,7 @@ exports.resolveLang = resolveLang;
35253
36098
  exports.resolveOverlapsWithChain = resolveOverlapsWithChain;
35254
36099
  exports.resolveTarget = resolveTarget;
35255
36100
  exports.resolveTargetAll = resolveTargetAll;
36101
+ exports.resolveTextMetrics = resolveTextMetrics;
35256
36102
  exports.segmentsIntersect = segmentsIntersect2;
35257
36103
  exports.sequence = sequence;
35258
36104
  exports.sequenceBoardMetrics = sequenceBoardMetrics;