@cardenelabs/cdl 0.106.0 → 0.108.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.cjs CHANGED
@@ -839,6 +839,11 @@ function isHalfwidthKana(code) {
839
839
  }
840
840
  var EMOJI_ADVANCE_EM = 1.05;
841
841
  var MONO_EMOJI_ADVANCE_EM = 1.16;
842
+ var DRAWN_CJK_RATIO = 1.08;
843
+ var DRAWN_ASCII_RATIO = 1.16;
844
+ function isAscii(code) {
845
+ return code < 128;
846
+ }
842
847
  var WIDE_SYMBOL_ADVANCE_EM = 0.95;
843
848
  function isEmoji(code) {
844
849
  return code >= 126976 && code <= 129791 || // 絵文字の主要面
@@ -877,29 +882,31 @@ function measureTextWidth(text, opts = {}) {
877
882
  const fontSize = opts.fontSize ?? 22;
878
883
  const letterSpacing = opts.letterSpacing ?? 0;
879
884
  const fontFamily = opts.fontFamily ?? "sans";
885
+ const bound = opts.bound ?? "layout";
880
886
  let advanceEmSum = 0;
881
887
  let charCount = 0;
882
888
  const \u6587\u5B57\u5217 = CLUSTER_JOINER_RE.test(text) ? segmentGraphemes(text) : [...text];
883
889
  for (const ch of \u6587\u5B57\u5217) {
884
890
  charCount++;
885
891
  const code = ch.codePointAt(0) ?? 0;
892
+ const \u5272\u308A\u623B\u3057 = bound === "drawn" && !isEmojiGrapheme(ch, code) ? isAscii(code) ? DRAWN_ASCII_RATIO : isCJK(code) ? DRAWN_CJK_RATIO : 1 : 1;
886
893
  if (isEmojiGrapheme(ch, code)) {
887
894
  advanceEmSum += fontFamily === "mono" ? MONO_EMOJI_ADVANCE_EM : EMOJI_ADVANCE_EM;
888
895
  continue;
889
896
  }
890
897
  if (fontFamily === "mono") {
891
- advanceEmSum += isCJK(code) ? 1.08 : JETBRAINS_MONO_ADVANCE_EM;
898
+ advanceEmSum += (isCJK(code) ? 1.08 : JETBRAINS_MONO_ADVANCE_EM) / \u5272\u308A\u623B\u3057;
892
899
  continue;
893
900
  }
894
901
  if (isCJK(code)) {
895
- advanceEmSum += 1.08;
902
+ advanceEmSum += 1.08 / \u5272\u308A\u623B\u3057;
896
903
  continue;
897
904
  }
898
905
  const table = ch.length === 1 ? INTER_BOLD_ADVANCE_EM[ch] : void 0;
899
- advanceEmSum += table !== void 0 ? table : defaultAdvanceEm(ch, code);
906
+ advanceEmSum += (table !== void 0 ? table : defaultAdvanceEm(ch, code)) / \u5272\u308A\u623B\u3057;
900
907
  }
901
908
  const w = advanceEmSum * fontSize + letterSpacing * charCount;
902
- return Math.max(w, fontSize * 1.2);
909
+ return bound === "drawn" ? w : Math.max(w, fontSize * 1.2);
903
910
  }
904
911
  function \u53CE\u3081\u308B\u500D\u7387(text, opts, \u5E45) {
905
912
  if (!(\u5E45 > 0) || !(opts.fontSize > 0)) return 1;
@@ -1040,6 +1047,51 @@ function titleFontSize(kind) {
1040
1047
  return TITLE_FONT_SIZE.get(kind ?? "") ?? TITLE_FONT_SIZE_DEFAULT;
1041
1048
  }
1042
1049
  var TITLE_BOX_PADDING = 52;
1050
+ var KINDS_SCALING_TITLE_WHEN_LOW = /* @__PURE__ */ new Set(["actor", "event", "function", "storage"]);
1051
+ var KINDS_SCALING_TITLE_ALWAYS = /* @__PURE__ */ new Set([
1052
+ "card",
1053
+ "shape-file",
1054
+ "shape-folder",
1055
+ "shape-cloud",
1056
+ "shape-cylinder",
1057
+ "shape-hexagon",
1058
+ "shape-diamond",
1059
+ "shape-stack",
1060
+ "shape-person",
1061
+ "shape-server-rack",
1062
+ "shape-network-node",
1063
+ "shape-mobile-device",
1064
+ "shape-satellite",
1065
+ "shape-smart-contract",
1066
+ "shape-rpc-node",
1067
+ "shape-wallet",
1068
+ "shape-nft",
1069
+ "shape-token",
1070
+ "shape-blockchain",
1071
+ "shape-bitcoin-chain",
1072
+ "shape-ethereum-chain",
1073
+ "shape-blockchain-node",
1074
+ "shape-bank",
1075
+ "shape-trust-bank",
1076
+ "shape-payment-provider",
1077
+ "shape-credit-card",
1078
+ "shape-brokerage",
1079
+ "shape-exchange",
1080
+ "shape-atm",
1081
+ "shape-website",
1082
+ "shape-storefront",
1083
+ "shape-warehouse",
1084
+ "shape-online-shop",
1085
+ "shape-cdn-edge",
1086
+ "shape-api-gateway"
1087
+ ]);
1088
+ var COMPACT_TITLE_MAX_H = 100;
1089
+ function titleScalesToFit(kind, h) {
1090
+ const k = kind ?? "";
1091
+ if (KINDS_SCALING_TITLE_ALWAYS.has(k)) return true;
1092
+ return KINDS_SCALING_TITLE_WHEN_LOW.has(k) && h < COMPACT_TITLE_MAX_H;
1093
+ }
1094
+ var MIN_TITLE_FONT_SIZE = 11;
1043
1095
  var KINDS_DRAWN_BY_GENERIC = [
1044
1096
  "person",
1045
1097
  "user-group",
@@ -3142,6 +3194,111 @@ function requiredRowsWidth(rows, kind) {
3142
3194
  if (kind === void 0) return Math.ceil(Math.max(storage, generic));
3143
3195
  return Math.ceil(kind === "storage" ? storage : generic);
3144
3196
  }
3197
+
3198
+ // src/kinds/compact-title.ts
3199
+ function estimateTextWidth(text, fontSize) {
3200
+ let w = 0;
3201
+ for (const ch of text) {
3202
+ const isFullWidth = /[\u3000-\u9FFF\uFF00-\uFFEF]/.test(ch);
3203
+ w += fontSize * (isFullWidth ? 1.05 : 0.62);
3204
+ }
3205
+ return w;
3206
+ }
3207
+ function fitTextSize(text, maxWidth, targetSize, minSize) {
3208
+ let size = targetSize;
3209
+ while (size > minSize && estimateTextWidth(text, size) > maxWidth) {
3210
+ size -= 1;
3211
+ }
3212
+ return size;
3213
+ }
3214
+ var COMPACT_MAX_H = 100;
3215
+ var COMPACT_PADDING_X = 16;
3216
+ var MIN_TEXT_SIZE = 11;
3217
+ var ASCENT = 0.72;
3218
+ var DESCENT = 0.25;
3219
+ var MIN_BAND_H = MIN_TEXT_SIZE * (ASCENT + DESCENT);
3220
+ var EYEBROW_BASELINE = 38;
3221
+ var EYEBROW_SIZE = 18;
3222
+ var EYEBROW_GAP = 8;
3223
+ var BOTTOM_INSET = 4;
3224
+ var eyebrowBottom = () => EYEBROW_BASELINE + EYEBROW_SIZE * DESCENT;
3225
+ var titleBandTop = (hasEyebrow) => eyebrowBottom() + EYEBROW_GAP ;
3226
+ var isCompactBox = (h) => h < COMPACT_MAX_H;
3227
+ function titlePlacement(node, \u901A\u5E38, opts = {}) {
3228
+ if (!isCompactBox(node.h)) {
3229
+ return { x: \u901A\u5E38.x, y: \u901A\u5E38.y, size: \u901A\u5E38.size, anchor: "start" };
3230
+ }
3231
+ const \u9AD8\u3055 = Math.max(0, node.h);
3232
+ const \u76EE\u5370\u3042\u308A = opts.hasEyebrow === true;
3233
+ const \u4E0A = \u76EE\u5370\u3042\u308A && \u9AD8\u3055 >= eyebrowBottom() ? titleBandTop() : 0;
3234
+ const \u751F\u306E\u5E2F = Math.max(0, \u9AD8\u3055 - \u4E0A);
3235
+ const \u4E0B\u4F59\u767D = \u751F\u306E\u5E2F >= MIN_BAND_H + BOTTOM_INSET ? BOTTOM_INSET : 0;
3236
+ const \u5E2F = \u751F\u306E\u5E2F - \u4E0B\u4F59\u767D;
3237
+ const \u5E45\u3067 = fitTextSize(
3238
+ node.title,
3239
+ Math.max(0, node.w - COMPACT_PADDING_X),
3240
+ \u901A\u5E38.size,
3241
+ MIN_TEXT_SIZE
3242
+ );
3243
+ const \u5E2F\u3067 = Math.floor(\u5E2F / (ASCENT + DESCENT));
3244
+ const size = Math.max(MIN_TEXT_SIZE, Math.min(\u5E45\u3067, \u5E2F\u3067));
3245
+ const \u5B57\u9AD8 = size * (ASCENT + DESCENT);
3246
+ const y = \u5B57\u9AD8 <= \u5E2F ? \u4E0A + \u5E2F / 2 + size * (ASCENT - DESCENT) / 2 : \u4E0A > 0 ? \u4E0A + size * ASCENT : (\u9AD8\u3055 - \u5B57\u9AD8) / 2 + size * ASCENT;
3247
+ return { x: node.w / 2, y, size, anchor: "middle" };
3248
+ }
3249
+
3250
+ // src/kinds/box-lines.ts
3251
+ var \u884C\u9001\u308A\u306E\u6BD4 = 1.15;
3252
+ var \u5B57\u306E\u9AD8\u3055\u306E\u6BD4 = 0.72;
3253
+ var \u4E0A\u4E0B\u306E\u4F59\u767D = 2;
3254
+ var \u5DE6\u53F3\u306E\u4F59\u767D = 8;
3255
+ function \u4F7F\u3048\u308B\u5E45(\u7BB1\u306E\u5E45) {
3256
+ return \u7BB1\u306E\u5E45 - \u5DE6\u53F3\u306E\u4F59\u767D * 2;
3257
+ }
3258
+ function \u5E45\u3067\u5207\u308B(text, fontSize, \u4F7F\u3048\u308B\u5E452, \u6E2C\u308B = textWidth) {
3259
+ if (\u4F7F\u3048\u308B\u5E452 <= 0) return "";
3260
+ if (\u6E2C\u308B(text, fontSize) <= \u4F7F\u3048\u308B\u5E452) return text;
3261
+ const \u7701\u7565 = "\u2026";
3262
+ const \u7701\u7565\u306E\u5E45 = \u6E2C\u308B(\u7701\u7565, fontSize);
3263
+ if (\u7701\u7565\u306E\u5E45 > \u4F7F\u3048\u308B\u5E452) return "";
3264
+ let \u51FA = "";
3265
+ let \u5E45 = 0;
3266
+ for (const c of \u66F8\u8A18\u7D20\u306B\u5206\u3051\u308B(text)) {
3267
+ const \u5B57\u306E\u5E452 = \u6E2C\u308B(c, fontSize);
3268
+ if (\u5E45 + \u5B57\u306E\u5E452 + \u7701\u7565\u306E\u5E45 > \u4F7F\u3048\u308B\u5E452) break;
3269
+ \u5E45 += \u5B57\u306E\u5E452;
3270
+ \u51FA += c;
3271
+ }
3272
+ return `${\u51FA}${\u7701\u7565}`;
3273
+ }
3274
+ var \u7E2E\u3081\u306E\u4E0B\u9650 = MIN_TEXT_SIZE;
3275
+ function \u5E45\u306B\u53CE\u3081\u308B(text, fontSize, \u4F7F\u3048\u308B\u5E452, \u6E2C\u308B = textWidth) {
3276
+ let size = fontSize;
3277
+ while (size > \u7E2E\u3081\u306E\u4E0B\u9650 && \u6E2C\u308B(text, size) > \u4F7F\u3048\u308B\u5E452) size -= 1;
3278
+ return { text: \u5E45\u3067\u5207\u308B(text, size, \u4F7F\u3048\u308B\u5E452, \u6E2C\u308B), fontSize: size };
3279
+ }
3280
+ function \u66F8\u8A18\u7D20\u306B\u5206\u3051\u308B(text) {
3281
+ const \u533A\u5207\u308A = Intl.Segmenter;
3282
+ if (typeof \u533A\u5207\u308A !== "function") return [...text];
3283
+ return [...new \u533A\u5207\u308A(void 0, { granularity: "grapheme" }).segment(text)].map((g) => g.segment);
3284
+ }
3285
+ function \u7BB1\u306B\u7A4D\u3080(\u884C, \u7BB1\u306E\u5E45, \u7BB1\u306E\u9AD8\u30553) {
3286
+ const \u5019\u88DC = \u884C.filter((r, i) => i === 0 || r.text.trim() !== "");
3287
+ if (\u5019\u88DC.length === 0) return [];
3288
+ const \u4F7F\u3048\u308B\u9AD8\u3055 = \u7BB1\u306E\u9AD8\u30553 - \u4E0A\u4E0B\u306E\u4F59\u767D * 2;
3289
+ const \u9AD8\u3055 = (rs) => rs.reduce((a, r) => a + r.fontSize * \u884C\u9001\u308A\u306E\u6BD4, 0);
3290
+ const \u6B8B\u3059 = [...\u5019\u88DC];
3291
+ while (\u6B8B\u3059.length > 1 && \u9AD8\u3055(\u6B8B\u3059) > \u4F7F\u3048\u308B\u9AD8\u3055) \u6B8B\u3059.pop();
3292
+ const \u5E45 = \u4F7F\u3048\u308B\u5E45(\u7BB1\u306E\u5E45);
3293
+ const \u53CE\u3081\u305F = \u6B8B\u3059.map((r) => ({ ...r, ...\u5E45\u306B\u53CE\u3081\u308B(r.text, r.fontSize, \u5E45) }));
3294
+ const \u7DCF\u9AD8 = \u9AD8\u3055(\u53CE\u3081\u305F);
3295
+ let \u7A4D\u307F = -\u7DCF\u9AD8 / 2;
3296
+ return \u53CE\u3081\u305F.map((r) => {
3297
+ const dy = \u7A4D\u307F + (\u884C\u9001\u308A\u306E\u6BD4 + \u5B57\u306E\u9AD8\u3055\u306E\u6BD4) / 2 * r.fontSize;
3298
+ \u7A4D\u307F += r.fontSize * \u884C\u9001\u308A\u306E\u6BD4;
3299
+ return { ...r, dy };
3300
+ });
3301
+ }
3145
3302
  function \u66F8\u3044\u305F\u5024\u304B\u63A7\u3048(\u66F8\u3044\u305F, \u63A7\u3048) {
3146
3303
  const v = (\u66F8\u3044\u305F ?? "").trim();
3147
3304
  return v === "" ? \u63A7\u3048 : v;
@@ -3151,14 +3308,22 @@ function \u5E45\u306E\u500D\u7387(text, size, letterSpacing, \u5E45) {
3151
3308
  const \u5B9F\u5E45 = textWidth(text, size, letterSpacing);
3152
3309
  return \u5B9F\u5E45 > \u5E45 ? \u5E45 / \u5B9F\u5E45 : 1;
3153
3310
  }
3311
+ function \u8AAD\u3081\u308B\u4E0B\u9650\u306E\u500D\u7387(\u5927\u304D\u3055) {
3312
+ return \u5927\u304D\u3055 > MIN_TITLE_FONT_SIZE ? MIN_TITLE_FONT_SIZE / \u5927\u304D\u3055 : 0;
3313
+ }
3314
+ function \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(\u984C, \u5927\u304D\u3055, \u5B57\u9593, \u5E45\u4E0A\u9650, \u6E2C\u308B) {
3315
+ const \u4E0B\u9650 = \u8AAD\u3081\u308B\u4E0B\u9650\u306E\u500D\u7387(\u5927\u304D\u3055);
3316
+ if (!(\u4E0B\u9650 > 0) || !(\u5E45\u4E0A\u9650 > 0)) return 0;
3317
+ return \u5E45\u3067\u5207\u308B(\u984C, \u5927\u304D\u3055 * \u4E0B\u9650, \u5E45\u4E0A\u9650, (u, f) => \u6E2C\u308B(u, f, \u5B57\u9593 * \u4E0B\u9650)) === "" ? 0 : \u4E0B\u9650;
3318
+ }
3154
3319
  var TITLE_MAX = 18;
3155
3320
  var TITLE_MIN = 9;
3156
3321
  var TITLE_RATIO = 0.17;
3157
3322
  var SUB_RATIO = 0.72;
3158
3323
  var LINE_GAP = 3;
3159
3324
  var BOTTOM_PAD = 4;
3160
- var ASCENT = 0.72;
3161
- var DESCENT = 0.25;
3325
+ var ASCENT2 = 0.72;
3326
+ var DESCENT2 = 0.25;
3162
3327
  var ART_GAP = 4;
3163
3328
  var ART_MIN_BAND = 45;
3164
3329
  var \u843D\u3068\u3057\u3066\u3082\u63CF\u304F\u7A2E\u5225 = {
@@ -3223,9 +3388,9 @@ function labelPlan(node) {
3223
3388
  y -= \u540D\u524D\u5927 + LINE_GAP;
3224
3389
  const \u80A9\u66F8 = \u80A9\u66F8\u3042\u308A2 ? { y, size: \u5C0F\u3055\u3044\u5B57 } : null;
3225
3390
  const \u4E0A\u306E\u884C = \u80A9\u66F8 ?? \u540D\u524D;
3226
- return { \u540D\u524D, \u8AAC\u660E, \u80A9\u66F8, \u4E0A\u7AEF: \u4E0A\u306E\u884C.y - \u4E0A\u306E\u884C.size * ASCENT };
3391
+ return { \u540D\u524D, \u8AAC\u660E, \u80A9\u66F8, \u4E0A\u7AEF: \u4E0A\u306E\u884C.y - \u4E0A\u306E\u884C.size * ASCENT2 };
3227
3392
  };
3228
- const \u5165\u308B = (\u8AAC\u660E\u3042\u308A2, \u80A9\u66F8\u3042\u308A2) => \u7A4D\u3080(1, \u8AAC\u660E\u3042\u308A2, \u80A9\u66F8\u3042\u308A2, 1 * DESCENT).\u4E0A\u7AEF >= \u5929;
3393
+ const \u5165\u308B = (\u8AAC\u660E\u3042\u308A2, \u80A9\u66F8\u3042\u308A2) => \u7A4D\u3080(1, \u8AAC\u660E\u3042\u308A2, \u80A9\u66F8\u3042\u308A2, 1 * DESCENT2).\u4E0A\u7AEF >= \u5929;
3229
3394
  let \u8AAC\u660E\u3042\u308A = Boolean(node.subtitle);
3230
3395
  let \u80A9\u66F8\u3042\u308A = Boolean(node.eyebrow);
3231
3396
  const \u843D\u3068\u3057\u305F = [];
@@ -3243,14 +3408,14 @@ function labelPlan(node) {
3243
3408
  for (let size = \u4E0A\u9650; size >= 1; size--) {
3244
3409
  const \u5C0F\u3055\u3044\u5B572 = Math.max(1, Math.round(size * SUB_RATIO));
3245
3410
  const \u4E0B\u306E\u884C\u5927 = \u8AAC\u660E\u3042\u308A2 ? \u5C0F\u3055\u3044\u5B572 : size;
3246
- if (\u7A4D\u3080(size, \u8AAC\u660E\u3042\u308A2, \u80A9\u66F8\u3042\u308A2, \u4E0B\u306E\u884C\u5927 * DESCENT).\u4E0A\u7AEF >= \u5929) {
3411
+ if (\u7A4D\u3080(size, \u8AAC\u660E\u3042\u308A2, \u80A9\u66F8\u3042\u308A2, \u4E0B\u306E\u884C\u5927 * DESCENT2).\u4E0A\u7AEF >= \u5929) {
3247
3412
  \u540D\u524D\u5927 = size;
3248
3413
  break;
3249
3414
  }
3250
3415
  }
3251
- if (\u540D\u524D\u5927 === 0) \u540D\u524D\u5927 = \u9AD8\u3055 / (ASCENT + DESCENT);
3416
+ if (\u540D\u524D\u5927 === 0) \u540D\u524D\u5927 = \u9AD8\u3055 / (ASCENT2 + DESCENT2);
3252
3417
  const \u5C0F\u3055\u3044\u5B57 = Math.max(1, Math.round(\u540D\u524D\u5927 * SUB_RATIO));
3253
- const \u5F35\u308A\u51FA\u3057 = (\u8AAC\u660E\u3042\u308A2 ? \u5C0F\u3055\u3044\u5B57 : \u540D\u524D\u5927) * DESCENT;
3418
+ const \u5F35\u308A\u51FA\u3057 = (\u8AAC\u660E\u3042\u308A2 ? \u5C0F\u3055\u3044\u5B57 : \u540D\u524D\u5927) * DESCENT2;
3254
3419
  const \u4F59\u308A = Math.max(0, \u7A4D\u3080(\u540D\u524D\u5927, \u8AAC\u660E\u3042\u308A2, \u80A9\u66F8\u3042\u308A2, \u5F35\u308A\u51FA\u3057).\u4E0A\u7AEF - \u5929);
3255
3420
  const \u4E0B\u4F59\u767D = Math.min(Math.max(BOTTOM_PAD, \u5F35\u308A\u51FA\u3057), \u5F35\u308A\u51FA\u3057 + \u4F59\u308A);
3256
3421
  return \u7A4D\u3080(\u540D\u524D\u5927, \u8AAC\u660E\u3042\u308A2, \u80A9\u66F8\u3042\u308A2, \u4E0B\u4F59\u767D);
@@ -3310,16 +3475,19 @@ function bodyBand(node, opt) {
3310
3475
  const h = Math.max(0, \u7BB1h - \u7E26\u4F59\u767D * ky);
3311
3476
  return { x, y, w, h, cx: x + w / 2, cy: y + h / 2, \u53F3: x + w, \u5E95: y + h };
3312
3477
  }
3313
- function fitLabel(band, block, pos) {
3478
+ function fitLabel(band, block, pos, \u6A2A\u306E\u4E0B\u9650 = 0) {
3314
3479
  const \u7E26 = block.\u4E0A + block.\u4E0B;
3315
3480
  const \u6A2A = Math.max(0, block.\u5E45);
3316
3481
  if (!(\u7E26 > 0)) return { k: 1, x: pos.x, y: pos.y };
3317
3482
  if (!(band.h > 0) || !(band.w > 0)) return { k: 0, x: band.x + band.w / 2, y: band.y };
3318
- const k = Math.min(1, band.h / \u7E26, \u6A2A > 0 ? band.w / \u6A2A : 1);
3483
+ const \u6A2A\u3067 = \u6A2A > 0 ? Math.max(band.w / \u6A2A, \u6A2A\u306E\u4E0B\u9650) : 1;
3484
+ const k = Math.min(1, band.h / \u7E26, \u6A2A\u3067);
3319
3485
  const \u534A = \u6A2A * k / 2;
3320
3486
  return {
3321
3487
  k,
3322
- x: Math.max(band.x + \u534A, Math.min(pos.x, band.x + band.w - \u534A)),
3488
+ // 下限で止めた塊は帯より広い。 その時は帯の中央に置いて左右へ均等に出す =
3489
+ // 寄せの式をそのまま当てると片側だけに出る (`compact-title.ts` と同じ判断)
3490
+ x: \u534A * 2 > band.w ? band.x + band.w / 2 : Math.max(band.x + \u534A, Math.min(pos.x, band.x + band.w - \u534A)),
3323
3491
  y: Math.max(band.y + block.\u4E0A * k, Math.min(pos.y, band.y + band.h - block.\u4E0B * k))
3324
3492
  };
3325
3493
  }
@@ -3372,111 +3540,6 @@ function \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u5B57\u3089)
3372
3540
  return Math.max(1, Math.min(\u623B\u3057, \u4E0A\u9650));
3373
3541
  }
3374
3542
 
3375
- // src/kinds/compact-title.ts
3376
- function estimateTextWidth(text, fontSize) {
3377
- let w = 0;
3378
- for (const ch of text) {
3379
- const isFullWidth = /[\u3000-\u9FFF\uFF00-\uFFEF]/.test(ch);
3380
- w += fontSize * (isFullWidth ? 1.05 : 0.62);
3381
- }
3382
- return w;
3383
- }
3384
- function fitTextSize(text, maxWidth, targetSize, minSize) {
3385
- let size = targetSize;
3386
- while (size > minSize && estimateTextWidth(text, size) > maxWidth) {
3387
- size -= 1;
3388
- }
3389
- return size;
3390
- }
3391
- var COMPACT_MAX_H = 100;
3392
- var COMPACT_PADDING_X = 16;
3393
- var MIN_TEXT_SIZE = 11;
3394
- var ASCENT2 = 0.72;
3395
- var DESCENT2 = 0.25;
3396
- var MIN_BAND_H = MIN_TEXT_SIZE * (ASCENT2 + DESCENT2);
3397
- var EYEBROW_BASELINE = 38;
3398
- var EYEBROW_SIZE = 18;
3399
- var EYEBROW_GAP = 8;
3400
- var BOTTOM_INSET = 4;
3401
- var eyebrowBottom = () => EYEBROW_BASELINE + EYEBROW_SIZE * DESCENT2;
3402
- var titleBandTop = (hasEyebrow) => eyebrowBottom() + EYEBROW_GAP ;
3403
- var isCompactBox = (h) => h < COMPACT_MAX_H;
3404
- function titlePlacement(node, \u901A\u5E38, opts = {}) {
3405
- if (!isCompactBox(node.h)) {
3406
- return { x: \u901A\u5E38.x, y: \u901A\u5E38.y, size: \u901A\u5E38.size, anchor: "start" };
3407
- }
3408
- const \u9AD8\u3055 = Math.max(0, node.h);
3409
- const \u76EE\u5370\u3042\u308A = opts.hasEyebrow === true;
3410
- const \u4E0A = \u76EE\u5370\u3042\u308A && \u9AD8\u3055 >= eyebrowBottom() ? titleBandTop() : 0;
3411
- const \u751F\u306E\u5E2F = Math.max(0, \u9AD8\u3055 - \u4E0A);
3412
- const \u4E0B\u4F59\u767D = \u751F\u306E\u5E2F >= MIN_BAND_H + BOTTOM_INSET ? BOTTOM_INSET : 0;
3413
- const \u5E2F = \u751F\u306E\u5E2F - \u4E0B\u4F59\u767D;
3414
- const \u5E45\u3067 = fitTextSize(
3415
- node.title,
3416
- Math.max(0, node.w - COMPACT_PADDING_X),
3417
- \u901A\u5E38.size,
3418
- MIN_TEXT_SIZE
3419
- );
3420
- const \u5E2F\u3067 = Math.floor(\u5E2F / (ASCENT2 + DESCENT2));
3421
- const size = Math.max(MIN_TEXT_SIZE, Math.min(\u5E45\u3067, \u5E2F\u3067));
3422
- const \u5B57\u9AD8 = size * (ASCENT2 + DESCENT2);
3423
- const y = \u5B57\u9AD8 <= \u5E2F ? \u4E0A + \u5E2F / 2 + size * (ASCENT2 - DESCENT2) / 2 : \u4E0A > 0 ? \u4E0A + size * ASCENT2 : (\u9AD8\u3055 - \u5B57\u9AD8) / 2 + size * ASCENT2;
3424
- return { x: node.w / 2, y, size, anchor: "middle" };
3425
- }
3426
-
3427
- // src/kinds/box-lines.ts
3428
- var \u884C\u9001\u308A\u306E\u6BD4 = 1.15;
3429
- var \u5B57\u306E\u9AD8\u3055\u306E\u6BD4 = 0.72;
3430
- var \u4E0A\u4E0B\u306E\u4F59\u767D = 2;
3431
- var \u5DE6\u53F3\u306E\u4F59\u767D = 8;
3432
- function \u4F7F\u3048\u308B\u5E45(\u7BB1\u306E\u5E45) {
3433
- return \u7BB1\u306E\u5E45 - \u5DE6\u53F3\u306E\u4F59\u767D * 2;
3434
- }
3435
- function \u5E45\u3067\u5207\u308B(text, fontSize, \u4F7F\u3048\u308B\u5E452, \u6E2C\u308B = textWidth) {
3436
- if (\u4F7F\u3048\u308B\u5E452 <= 0) return "";
3437
- if (\u6E2C\u308B(text, fontSize) <= \u4F7F\u3048\u308B\u5E452) return text;
3438
- const \u7701\u7565 = "\u2026";
3439
- const \u7701\u7565\u306E\u5E45 = \u6E2C\u308B(\u7701\u7565, fontSize);
3440
- if (\u7701\u7565\u306E\u5E45 > \u4F7F\u3048\u308B\u5E452) return "";
3441
- let \u51FA = "";
3442
- let \u5E45 = 0;
3443
- for (const c of \u66F8\u8A18\u7D20\u306B\u5206\u3051\u308B(text)) {
3444
- const \u5B57\u306E\u5E452 = \u6E2C\u308B(c, fontSize);
3445
- if (\u5E45 + \u5B57\u306E\u5E452 + \u7701\u7565\u306E\u5E45 > \u4F7F\u3048\u308B\u5E452) break;
3446
- \u5E45 += \u5B57\u306E\u5E452;
3447
- \u51FA += c;
3448
- }
3449
- return `${\u51FA}${\u7701\u7565}`;
3450
- }
3451
- var \u7E2E\u3081\u306E\u4E0B\u9650 = MIN_TEXT_SIZE;
3452
- function \u5E45\u306B\u53CE\u3081\u308B(text, fontSize, \u4F7F\u3048\u308B\u5E452, \u6E2C\u308B = textWidth) {
3453
- let size = fontSize;
3454
- while (size > \u7E2E\u3081\u306E\u4E0B\u9650 && \u6E2C\u308B(text, size) > \u4F7F\u3048\u308B\u5E452) size -= 1;
3455
- return { text: \u5E45\u3067\u5207\u308B(text, size, \u4F7F\u3048\u308B\u5E452, \u6E2C\u308B), fontSize: size };
3456
- }
3457
- function \u66F8\u8A18\u7D20\u306B\u5206\u3051\u308B(text) {
3458
- const \u533A\u5207\u308A = Intl.Segmenter;
3459
- if (typeof \u533A\u5207\u308A !== "function") return [...text];
3460
- return [...new \u533A\u5207\u308A(void 0, { granularity: "grapheme" }).segment(text)].map((g) => g.segment);
3461
- }
3462
- function \u7BB1\u306B\u7A4D\u3080(\u884C, \u7BB1\u306E\u5E45, \u7BB1\u306E\u9AD8\u30553) {
3463
- const \u5019\u88DC = \u884C.filter((r, i) => i === 0 || r.text.trim() !== "");
3464
- if (\u5019\u88DC.length === 0) return [];
3465
- const \u4F7F\u3048\u308B\u9AD8\u3055 = \u7BB1\u306E\u9AD8\u30553 - \u4E0A\u4E0B\u306E\u4F59\u767D * 2;
3466
- const \u9AD8\u3055 = (rs) => rs.reduce((a, r) => a + r.fontSize * \u884C\u9001\u308A\u306E\u6BD4, 0);
3467
- const \u6B8B\u3059 = [...\u5019\u88DC];
3468
- while (\u6B8B\u3059.length > 1 && \u9AD8\u3055(\u6B8B\u3059) > \u4F7F\u3048\u308B\u9AD8\u3055) \u6B8B\u3059.pop();
3469
- const \u5E45 = \u4F7F\u3048\u308B\u5E45(\u7BB1\u306E\u5E45);
3470
- const \u53CE\u3081\u305F = \u6B8B\u3059.map((r) => ({ ...r, ...\u5E45\u306B\u53CE\u3081\u308B(r.text, r.fontSize, \u5E45) }));
3471
- const \u7DCF\u9AD8 = \u9AD8\u3055(\u53CE\u3081\u305F);
3472
- let \u7A4D\u307F = -\u7DCF\u9AD8 / 2;
3473
- return \u53CE\u3081\u305F.map((r) => {
3474
- const dy = \u7A4D\u307F + (\u884C\u9001\u308A\u306E\u6BD4 + \u5B57\u306E\u9AD8\u3055\u306E\u6BD4) / 2 * r.fontSize;
3475
- \u7A4D\u307F += r.fontSize * \u884C\u9001\u308A\u306E\u6BD4;
3476
- return { ...r, dy };
3477
- });
3478
- }
3479
-
3480
3543
  // src/render/tone.ts
3481
3544
  var TONE = {
3482
3545
  accent: "var(--cdl-tone-accent, #2d6a8f)",
@@ -6133,12 +6196,23 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5
6133
6196
  if (!isRenderedNode(n)) continue;
6134
6197
  const titleTrimmed = n.title?.trim() ?? "";
6135
6198
  if (!titleTrimmed) continue;
6136
- const expectedW = measureTextWidth(titleTrimmed, { fontSize: titleFontSize(n.kind) }) + (drawsTitleOutsideBox(n.kind) ? 0 : TITLE_BOX_PADDING);
6137
- if (expectedW > n.w + 8) {
6199
+ const \u4F59\u767D = drawsTitleOutsideBox(n.kind) ? 0 : TITLE_BOX_PADDING;
6200
+ const \u4F7F\u3048\u308B\u5E452 = n.w - \u4F59\u767D;
6201
+ const \u5B9F\u5E45 = measureTextWidth(titleTrimmed, { fontSize: titleFontSize(n.kind), bound: "drawn" });
6202
+ if (titleScalesToFit(n.kind, n.h)) {
6203
+ 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);
6204
+ if (\u7E2E\u3081\u305F\u5927\u304D\u3055 < MIN_TITLE_FONT_SIZE) {
6205
+ push(
6206
+ "text-readability",
6207
+ `node "${n.id}" title "${n.title}" \u304C node \u5E45 ${n.w}px \u306B\u53CE\u307E\u3089\u305A\u3001\u8AAD\u3081\u308B\u4E0B\u9650 ${MIN_TITLE_FONT_SIZE}px \u3092\u5272\u308B (\u7E2E\u3081\u3066 ${\u7E2E\u3081\u305F\u5927\u304D\u3055.toFixed(1)}px)`,
6208
+ "warn"
6209
+ );
6210
+ }
6211
+ } else if (\u5B9F\u5E45 > \u4F7F\u3048\u308B\u5E452 + 8) {
6138
6212
  push(
6139
6213
  "text-readability",
6140
6214
  // 字ごとの実幅は小数になるので、読む人に出す時だけ丸める (判定は丸めない)
6141
- `node "${n.id}" title "${n.title}" \u304C node \u5E45 ${n.w}px \u3092\u8D85\u904E\u3059\u308B\u53EF\u80FD\u6027 (\u671F\u5F85 ${Math.round(expectedW)}px)`,
6215
+ `node "${n.id}" title "${n.title}" \u304C node \u5E45 ${n.w}px \u3092\u8D85\u904E\u3059\u308B\u53EF\u80FD\u6027 (\u671F\u5F85 ${Math.round(\u5B9F\u5E45 + \u4F59\u767D)}px)`,
6142
6216
  "warn"
6143
6217
  );
6144
6218
  }
@@ -11778,7 +11852,7 @@ function CardNode({ node, active }) {
11778
11852
  const textAnchor = compact ? "middle" : "start";
11779
11853
  const subtitleY = 124 - \u305A\u3089\u3057;
11780
11854
  const \u6700\u5927\u306E\u884C\u9001\u308A = SUBTITLE_SIZE * \u884C\u9001\u308A\u306E\u500D\u7387;
11781
- const \u4E8C\u884C\u304C\u5165\u308B = !compact && subtitleY - \u6700\u5927\u306E\u884C\u9001\u308A / 2 - SUBTITLE_SIZE * ASCENT2 > titleY + titleSize * DESCENT2 && subtitleY + \u6700\u5927\u306E\u884C\u9001\u308A / 2 + SUBTITLE_SIZE * DESCENT2 <= node.h - 4;
11855
+ const \u4E8C\u884C\u304C\u5165\u308B = !compact && subtitleY - \u6700\u5927\u306E\u884C\u9001\u308A / 2 - SUBTITLE_SIZE * ASCENT > titleY + titleSize * DESCENT && subtitleY + \u6700\u5927\u306E\u884C\u9001\u308A / 2 + SUBTITLE_SIZE * DESCENT <= node.h - 4;
11782
11856
  const \u8AAC\u660E = node.subtitle ? \u8AAC\u660E\u6587\u3092\u5272\u308A\u4ED8\u3051\u308B(node.subtitle, availableW, { \u4E8C\u884C\u307E\u3067: \u4E8C\u884C\u304C\u5165\u308B }) : void 0;
11783
11857
  const subtitleSize = \u8AAC\u660E?.size ?? 21;
11784
11858
  const \u884C\u9001\u308A = subtitleSize * \u884C\u9001\u308A\u306E\u500D\u7387;
@@ -16075,20 +16149,22 @@ var EYEBROW_TRACKING = 2;
16075
16149
  var SUB_SIZE = 11;
16076
16150
  var SUB_GAP = 4;
16077
16151
  function labelBlock(node, pos, size, band) {
16078
- const \u4E0A = node.eyebrow ? size + EYEBROW_GAP2 + EYEBROW_SIZE2 * ASCENT : size * ASCENT;
16079
- const \u4E0B = node.subtitle ? size + SUB_GAP + SUB_SIZE * DESCENT : size * DESCENT;
16152
+ const \u4E0A = node.eyebrow ? size + EYEBROW_GAP2 + EYEBROW_SIZE2 * ASCENT2 : size * ASCENT2;
16153
+ const \u4E0B = node.subtitle ? size + SUB_GAP + SUB_SIZE * DESCENT2 : size * DESCENT2;
16080
16154
  const \u5E45 = Math.max(
16081
16155
  textWidth(node.title ?? "", size),
16082
16156
  node.eyebrow ? textWidth(node.eyebrow, EYEBROW_SIZE2, EYEBROW_TRACKING) : 0,
16083
16157
  node.subtitle ? textWidth(node.subtitle, SUB_SIZE) : 0
16084
16158
  );
16085
- const { k, x, y: baseline } = fitLabel(band, { \u4E0A, \u4E0B, \u5E45 }, pos);
16159
+ const \u4E0B\u9650 = \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(node.title ?? "", size, 0, band.w, textWidth);
16160
+ const { k, x, y: baseline } = fitLabel(band, { \u4E0A, \u4E0B, \u5E45 }, pos, \u4E0B\u9650);
16086
16161
  return { k, x, baseline, \u4E0A\u7AEF: baseline - \u4E0A * k, \u4E0B\u7AEF: baseline + \u4E0B * k };
16087
16162
  }
16088
16163
  function commonLabel(node, pos, size, band) {
16089
16164
  const \u584A = labelBlock(node, pos, size, band);
16090
16165
  const k = \u584A.k;
16091
16166
  const x = \u584A.x;
16167
+ const \u5207\u308B = (t, \u5927\u304D\u3055, \u5B57\u9593 = 0) => \u5E45\u3067\u5207\u308B(t, \u5927\u304D\u3055 * k, band.w, (u, f) => textWidth(u, f, \u5B57\u9593 * k));
16092
16168
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
16093
16169
  node.eyebrow && /* @__PURE__ */ jsxRuntime.jsx(
16094
16170
  "text",
@@ -16100,7 +16176,7 @@ function commonLabel(node, pos, size, band) {
16100
16176
  letterSpacing: EYEBROW_TRACKING * k,
16101
16177
  textAnchor: "middle",
16102
16178
  fill: "var(--cdl-tone-accent, #2d6a8f)",
16103
- children: node.eyebrow
16179
+ children: \u5207\u308B(node.eyebrow, EYEBROW_SIZE2, EYEBROW_TRACKING)
16104
16180
  }
16105
16181
  ),
16106
16182
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -16113,7 +16189,7 @@ function commonLabel(node, pos, size, band) {
16113
16189
  fontWeight: 700,
16114
16190
  textAnchor: "middle",
16115
16191
  fill: "var(--cdl-text, #1a1f2a)",
16116
- children: node.title
16192
+ children: \u5207\u308B(node.title ?? "", size)
16117
16193
  }
16118
16194
  ),
16119
16195
  node.subtitle && /* @__PURE__ */ jsxRuntime.jsx(
@@ -16124,7 +16200,7 @@ function commonLabel(node, pos, size, band) {
16124
16200
  fontSize: SUB_SIZE * k,
16125
16201
  textAnchor: "middle",
16126
16202
  fill: "var(--cdl-text-dim, #5a6270)",
16127
- children: node.subtitle
16203
+ children: \u5207\u308B(node.subtitle, SUB_SIZE)
16128
16204
  }
16129
16205
  )
16130
16206
  ] });
@@ -16459,7 +16535,9 @@ function planLabel(node, cx, \u5E45\u4E0A\u9650, plan) {
16459
16535
  node.eyebrow && plan.\u80A9\u66F8 ? textWidth(node.eyebrow, plan.\u80A9\u66F8.size, EYEBROW_TRACKING) : 0,
16460
16536
  node.subtitle && plan.\u8AAC\u660E ? textWidth(node.subtitle, plan.\u8AAC\u660E.size) : 0
16461
16537
  );
16462
- const k = \u5E45 > 0 && \u5E45\u4E0A\u9650 > 0 ? Math.min(1, \u5E45\u4E0A\u9650 / \u5E45) : 1;
16538
+ const \u4E0B\u9650 = \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(node.title ?? "", plan.\u540D\u524D.size, 0, \u5E45\u4E0A\u9650, textWidth);
16539
+ const k = \u5E45 > 0 && \u5E45\u4E0A\u9650 > 0 ? Math.min(1, Math.max(\u5E45\u4E0A\u9650 / \u5E45, \u4E0B\u9650)) : 1;
16540
+ const \u5207\u308B = (t, \u5927\u304D\u3055, \u5B57\u9593 = 0) => \u5E45\u3067\u5207\u308B(t, \u5927\u304D\u3055 * k, \u5E45\u4E0A\u9650, (u, f) => textWidth(u, f, \u5B57\u9593 * k));
16463
16541
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
16464
16542
  node.eyebrow && plan.\u80A9\u66F8 && /* @__PURE__ */ jsxRuntime.jsx(
16465
16543
  "text",
@@ -16471,7 +16549,7 @@ function planLabel(node, cx, \u5E45\u4E0A\u9650, plan) {
16471
16549
  letterSpacing: EYEBROW_TRACKING * k,
16472
16550
  textAnchor: "middle",
16473
16551
  fill: "var(--cdl-tone-accent, #2d6a8f)",
16474
- children: node.eyebrow
16552
+ children: \u5207\u308B(node.eyebrow, plan.\u80A9\u66F8.size, EYEBROW_TRACKING)
16475
16553
  }
16476
16554
  ),
16477
16555
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -16484,7 +16562,7 @@ function planLabel(node, cx, \u5E45\u4E0A\u9650, plan) {
16484
16562
  fontWeight: 700,
16485
16563
  textAnchor: "middle",
16486
16564
  fill: "var(--cdl-text, #1a1f2a)",
16487
- children: node.title
16565
+ children: \u5207\u308B(node.title ?? "", plan.\u540D\u524D.size)
16488
16566
  }
16489
16567
  ),
16490
16568
  node.subtitle && plan.\u8AAC\u660E && /* @__PURE__ */ jsxRuntime.jsx(
@@ -16495,7 +16573,7 @@ function planLabel(node, cx, \u5E45\u4E0A\u9650, plan) {
16495
16573
  fontSize: plan.\u8AAC\u660E.size * k,
16496
16574
  textAnchor: "middle",
16497
16575
  fill: "var(--cdl-text-dim, #5a6270)",
16498
- children: node.subtitle
16576
+ children: \u5207\u308B(node.subtitle, plan.\u8AAC\u660E.size)
16499
16577
  }
16500
16578
  )
16501
16579
  ] });
@@ -17418,17 +17496,19 @@ var externalLabel = (node, cx, bottomY) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRu
17418
17496
  var LABEL_EYEBROW_SPACING = 2;
17419
17497
  function \u5E45\u306B\u53CE\u3081\u308B2(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45) {
17420
17498
  const \u5E45 = textWidth(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593);
17421
- const \u500D\u7387 = \u5E45 > 0 && \u7BB1\u5E45 > 0 ? Math.min(1, \u7BB1\u5E45 / \u5E45) : 1;
17422
- return { size: \u5927\u304D\u3055 * \u500D\u7387, spacing: \u5B57\u9593 * \u500D\u7387 };
17499
+ const \u500D\u7387 = \u5E45 > 0 && \u7BB1\u5E45 > 0 ? Math.min(1, Math.max(\u7BB1\u5E45 / \u5E45, \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, textWidth))) : 1;
17500
+ const size = \u5927\u304D\u3055 * \u500D\u7387;
17501
+ const spacing = \u5B57\u9593 * \u500D\u7387;
17502
+ return { size, spacing, text: \u5E45\u3067\u5207\u308B(\u6587\u5B57\u5217, size, \u7BB1\u5E45, (u, f) => textWidth(u, f, spacing)) };
17423
17503
  }
17424
17504
  function bottomLabel(node, cx, plan) {
17425
17505
  const \u80A9 = \u5E45\u306B\u53CE\u3081\u308B2(node.eyebrow ?? "", plan.\u80A9\u66F8?.size ?? 0, LABEL_EYEBROW_SPACING, node.w);
17426
17506
  const \u540D = \u5E45\u306B\u53CE\u3081\u308B2(node.title ?? "", plan.\u540D\u524D.size, 0, node.w);
17427
17507
  const \u8AAC = \u5E45\u306B\u53CE\u3081\u308B2(node.subtitle ?? "", plan.\u8AAC\u660E?.size ?? 0, 0, node.w);
17428
17508
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
17429
- 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: node.eyebrow }),
17430
- /* @__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: node.title }),
17431
- node.subtitle && plan.\u8AAC\u660E && /* @__PURE__ */ jsxRuntime.jsx("text", { x: cx, y: plan.\u8AAC\u660E.y, fontSize: \u8AAC.size, textAnchor: "middle", fill: "var(--cdl-text-dim, #5a6270)", children: node.subtitle })
17509
+ 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 }),
17510
+ /* @__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 }),
17511
+ node.subtitle && plan.\u8AAC\u660E && /* @__PURE__ */ jsxRuntime.jsx("text", { x: cx, y: plan.\u8AAC\u660E.y, fontSize: \u8AAC.size, textAnchor: "middle", fill: "var(--cdl-text-dim, #5a6270)", children: \u8AAC.text })
17432
17512
  ] });
17433
17513
  }
17434
17514
  var RACK_SLOT_TOP = 20;
@@ -18223,13 +18303,22 @@ function blockchainNodeExtent(strokeWidth) {
18223
18303
  return { \u4E0A: \u7E26, \u4E0B: \u7E26, \u5DE6: \u6A2A, \u53F3: \u6A2A };
18224
18304
  }
18225
18305
  function bottomLabel2(node, cx, plan) {
18226
- const \u80A9\u66F8\u500D\u7387 = node.eyebrow && plan.\u80A9\u66F8 ? \u5E45\u306E\u500D\u7387(node.eyebrow, plan.\u80A9\u66F8.size, 2, node.w) : 1;
18227
- const \u540D\u524D\u500D\u7387 = \u5E45\u306E\u500D\u7387(node.title, plan.\u540D\u524D.size, 0, node.w);
18228
- const \u8AAC\u660E\u500D\u7387 = node.subtitle && plan.\u8AAC\u660E ? \u5E45\u306E\u500D\u7387(node.subtitle, plan.\u8AAC\u660E.size, 0, node.w) : 1;
18306
+ const \u53CE\u3081\u308B = (t, \u5927\u304D\u3055, \u5B57\u9593) => {
18307
+ const \u6E2C\u308B = (u, f, ls) => \u5B57\u306E\u5E45(u, f) + ls * [...u].length;
18308
+ const \u500D\u7387 = Math.max(\u5E45\u306E\u500D\u7387(t, \u5927\u304D\u3055, \u5B57\u9593, node.w), \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(t, \u5927\u304D\u3055, \u5B57\u9593, node.w, \u6E2C\u308B));
18309
+ const size = \u5927\u304D\u3055 * \u500D\u7387;
18310
+ return { \u500D\u7387, text: \u5E45\u3067\u5207\u308B(t, size, node.w, (u, f) => \u5B57\u306E\u5E45(u, f) + \u5B57\u9593 * \u500D\u7387 * [...u].length) };
18311
+ };
18312
+ const \u80A9 = node.eyebrow && plan.\u80A9\u66F8 ? \u53CE\u3081\u308B(node.eyebrow, plan.\u80A9\u66F8.size, 2) : { \u500D\u7387: 1, text: node.eyebrow ?? "" };
18313
+ const \u540D = \u53CE\u3081\u308B(node.title ?? "", plan.\u540D\u524D.size, 0);
18314
+ const \u8AAC = node.subtitle && plan.\u8AAC\u660E ? \u53CE\u3081\u308B(node.subtitle, plan.\u8AAC\u660E.size, 0) : { \u500D\u7387: 1, text: node.subtitle ?? "" };
18315
+ const \u80A9\u66F8\u500D\u7387 = \u80A9.\u500D\u7387;
18316
+ const \u540D\u524D\u500D\u7387 = \u540D.\u500D\u7387;
18317
+ const \u8AAC\u660E\u500D\u7387 = \u8AAC.\u500D\u7387;
18229
18318
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
18230
- node.eyebrow && plan.\u80A9\u66F8 && /* @__PURE__ */ jsxRuntime.jsx("text", { x: cx, y: plan.\u80A9\u66F8.y, fontSize: plan.\u80A9\u66F8.size * \u80A9\u66F8\u500D\u7387, fontWeight: 700, letterSpacing: 2 * \u80A9\u66F8\u500D\u7387, textAnchor: "middle", fill: "var(--cdl-tone-accent, #2d6a8f)", children: node.eyebrow }),
18231
- /* @__PURE__ */ jsxRuntime.jsx("text", { "data-cdl-role": "node-label", x: cx, y: plan.\u540D\u524D.y, fontSize: plan.\u540D\u524D.size * \u540D\u524D\u500D\u7387, fontWeight: 700, textAnchor: "middle", fill: "var(--cdl-text, #1a1f2a)", children: node.title }),
18232
- node.subtitle && plan.\u8AAC\u660E && /* @__PURE__ */ jsxRuntime.jsx("text", { x: cx, y: plan.\u8AAC\u660E.y, fontSize: plan.\u8AAC\u660E.size * \u8AAC\u660E\u500D\u7387, textAnchor: "middle", fill: "var(--cdl-text-dim, #5a6270)", children: node.subtitle })
18319
+ node.eyebrow && plan.\u80A9\u66F8 && /* @__PURE__ */ jsxRuntime.jsx("text", { x: cx, y: plan.\u80A9\u66F8.y, fontSize: plan.\u80A9\u66F8.size * \u80A9\u66F8\u500D\u7387, fontWeight: 700, letterSpacing: 2 * \u80A9\u66F8\u500D\u7387, textAnchor: "middle", fill: "var(--cdl-tone-accent, #2d6a8f)", children: \u80A9.text }),
18320
+ /* @__PURE__ */ jsxRuntime.jsx("text", { "data-cdl-role": "node-label", x: cx, y: plan.\u540D\u524D.y, fontSize: plan.\u540D\u524D.size * \u540D\u524D\u500D\u7387, fontWeight: 700, textAnchor: "middle", fill: "var(--cdl-text, #1a1f2a)", children: \u540D.text }),
18321
+ node.subtitle && plan.\u8AAC\u660E && /* @__PURE__ */ jsxRuntime.jsx("text", { x: cx, y: plan.\u8AAC\u660E.y, fontSize: plan.\u8AAC\u660E.size * \u8AAC\u660E\u500D\u7387, textAnchor: "middle", fill: "var(--cdl-text-dim, #5a6270)", children: \u8AAC.text })
18233
18322
  ] });
18234
18323
  }
18235
18324
  function EthereumDiamond({ cx, cy, h, colors }) {
@@ -18838,17 +18927,19 @@ function \u5B57\u5E45(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593) {
18838
18927
  }
18839
18928
  function \u5E45\u306B\u53CE\u3081\u308B3(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45) {
18840
18929
  const \u5E45 = \u5B57\u5E45(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593);
18841
- const \u500D\u7387 = \u5E45 > 0 && \u7BB1\u5E45 > 0 ? Math.min(1, \u7BB1\u5E45 / \u5E45) : 1;
18842
- return { size: \u5927\u304D\u3055 * \u500D\u7387, spacing: \u5B57\u9593 * \u500D\u7387 };
18930
+ const \u500D\u7387 = \u5E45 > 0 && \u7BB1\u5E45 > 0 ? Math.min(1, Math.max(\u7BB1\u5E45 / \u5E45, \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, \u5B57\u5E45))) : 1;
18931
+ const size = \u5927\u304D\u3055 * \u500D\u7387;
18932
+ const spacing = \u5B57\u9593 * \u500D\u7387;
18933
+ return { size, spacing, text: \u5E45\u3067\u5207\u308B(\u6587\u5B57\u5217, size, \u7BB1\u5E45, (u, f) => \u5B57\u5E45(u, f, spacing)) };
18843
18934
  }
18844
18935
  function bottomLabel3(node, cx, plan) {
18845
18936
  const \u80A9 = \u5E45\u306B\u53CE\u3081\u308B3(node.eyebrow ?? "", plan.\u80A9\u66F8?.size ?? 0, LABEL_EYEBROW_SPACING2, node.w);
18846
18937
  const \u540D = \u5E45\u306B\u53CE\u3081\u308B3(node.title ?? "", plan.\u540D\u524D.size, 0, node.w);
18847
18938
  const \u8AAC = \u5E45\u306B\u53CE\u3081\u308B3(node.subtitle ?? "", plan.\u8AAC\u660E?.size ?? 0, 0, node.w);
18848
18939
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
18849
- 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: node.eyebrow }),
18850
- /* @__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: node.title }),
18851
- node.subtitle && plan.\u8AAC\u660E && /* @__PURE__ */ jsxRuntime.jsx("text", { x: cx, y: plan.\u8AAC\u660E.y, fontSize: \u8AAC.size, textAnchor: "middle", fill: "var(--cdl-text-dim, #5a6270)", children: node.subtitle })
18940
+ 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 }),
18941
+ /* @__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 }),
18942
+ node.subtitle && plan.\u8AAC\u660E && /* @__PURE__ */ jsxRuntime.jsx("text", { x: cx, y: plan.\u8AAC\u660E.y, fontSize: \u8AAC.size, textAnchor: "middle", fill: "var(--cdl-text-dim, #5a6270)", children: \u8AAC.text })
18852
18943
  ] });
18853
18944
  }
18854
18945
  var BANK_PEDIMENT_H = 44;
@@ -19321,17 +19412,19 @@ function \u5B57\u5E452(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593) {
19321
19412
  }
19322
19413
  function \u5E45\u306B\u53CE\u3081\u308B4(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45) {
19323
19414
  const \u5E45 = \u5B57\u5E452(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593);
19324
- const \u500D\u7387 = \u5E45 > 0 && \u7BB1\u5E45 > 0 ? Math.min(1, \u7BB1\u5E45 / \u5E45) : 1;
19325
- return { size: \u5927\u304D\u3055 * \u500D\u7387, spacing: \u5B57\u9593 * \u500D\u7387 };
19415
+ const \u500D\u7387 = \u5E45 > 0 && \u7BB1\u5E45 > 0 ? Math.min(1, Math.max(\u7BB1\u5E45 / \u5E45, \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, \u5B57\u5E452))) : 1;
19416
+ const size = \u5927\u304D\u3055 * \u500D\u7387;
19417
+ const spacing = \u5B57\u9593 * \u500D\u7387;
19418
+ return { size, spacing, text: \u5E45\u3067\u5207\u308B(\u6587\u5B57\u5217, size, \u7BB1\u5E45, (u, f) => \u5B57\u5E452(u, f, spacing)) };
19326
19419
  }
19327
19420
  function bottomLabel4(node, cx, plan) {
19328
19421
  const \u80A9 = \u5E45\u306B\u53CE\u3081\u308B4(node.eyebrow ?? "", plan.\u80A9\u66F8?.size ?? 0, LABEL_EYEBROW_SPACING3, node.w);
19329
19422
  const \u540D = \u5E45\u306B\u53CE\u3081\u308B4(node.title ?? "", plan.\u540D\u524D.size, 0, node.w);
19330
19423
  const \u8AAC = \u5E45\u306B\u53CE\u3081\u308B4(node.subtitle ?? "", plan.\u8AAC\u660E?.size ?? 0, 0, node.w);
19331
19424
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
19332
- 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: node.eyebrow }),
19333
- /* @__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: node.title }),
19334
- node.subtitle && plan.\u8AAC\u660E && /* @__PURE__ */ jsxRuntime.jsx("text", { x: cx, y: plan.\u8AAC\u660E.y, fontSize: \u8AAC.size, textAnchor: "middle", fill: "var(--cdl-text-dim, #5a6270)", children: node.subtitle })
19425
+ 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 }),
19426
+ /* @__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 }),
19427
+ node.subtitle && plan.\u8AAC\u660E && /* @__PURE__ */ jsxRuntime.jsx("text", { x: cx, y: plan.\u8AAC\u660E.y, fontSize: \u8AAC.size, textAnchor: "middle", fill: "var(--cdl-text-dim, #5a6270)", children: \u8AAC.text })
19335
19428
  ] });
19336
19429
  }
19337
19430
  var DROP_SHADOW_D = 4;