@cardenelabs/cdl 0.51.0 → 0.53.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/CHANGELOG.md +30 -1
- package/dist/index.cjs +108 -84
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -2
- package/dist/index.d.ts +8 -2
- package/dist/index.js +108 -84
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +105 -84
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +105 -84
- package/dist/react.js.map +1 -1
- package/dist/{render-BoBEyCu-.d.cts → render-C0PJ2weJ.d.cts} +6 -0
- package/dist/{render-BoBEyCu-.d.ts → render-C0PJ2weJ.d.ts} +6 -0
- package/package.json +1 -1
- package/src/builder.ts +6 -0
- package/src/layout/head-label.ts +80 -36
- package/src/layout/nodes.ts +7 -3
- package/src/presets.ts +3 -0
- package/src/render/edges.tsx +8 -5
- package/src/render/stage.tsx +13 -10
- package/src/types.ts +6 -0
package/dist/react.cjs
CHANGED
|
@@ -9226,6 +9226,87 @@ function requiredRowsWidth(rows, kind) {
|
|
|
9226
9226
|
return Math.ceil(kind === "storage" ? storage : generic);
|
|
9227
9227
|
}
|
|
9228
9228
|
|
|
9229
|
+
// src/layout/head-label.ts
|
|
9230
|
+
var \u7AEF\u306E\u5B57\u3092\u623B\u3059\u8DDD\u96E2 = 22;
|
|
9231
|
+
var \u7AEF\u306E\u5B57\u3068\u7DDA\u306E\u9699\u9593 = 8;
|
|
9232
|
+
var \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055 = EDGE_LABEL_TEXT.sub.fontSize;
|
|
9233
|
+
var \u7BB1\u306E\u9AD8\u3055 = Math.round(\u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055 * 1.2);
|
|
9234
|
+
var BASELINE_RATIO = 0.8;
|
|
9235
|
+
var \u4E21\u7AEF\u306E\u5B57\u306E\u9593 = \u7AEF\u306E\u5B57\u3092\u623B\u3059\u8DDD\u96E2 * 2;
|
|
9236
|
+
function \u7AEF\u306E\u5B57\u306B\u8981\u308B\u7DDA\u306E\u9577\u3055(edge) {
|
|
9237
|
+
const \u4E00\u3064\u5206 = \u7AEF\u306E\u5B57\u3092\u623B\u3059\u8DDD\u96E2 + \u7BB1\u306E\u9AD8\u3055;
|
|
9238
|
+
const \u6570 = [edge.headLabel, edge.tailLabel].filter((t) => t?.trim()).length;
|
|
9239
|
+
if (\u6570 === 0) return 0;
|
|
9240
|
+
if (\u6570 === 1) return \u4E00\u3064\u5206;
|
|
9241
|
+
return \u4E00\u3064\u5206 * 2 + \u4E21\u7AEF\u306E\u5B57\u306E\u9593;
|
|
9242
|
+
}
|
|
9243
|
+
function \u5411\u304D\u3092\u53D6\u308B(end, \u5019\u88DC) {
|
|
9244
|
+
for (const p of \u5019\u88DC) {
|
|
9245
|
+
if (!p) continue;
|
|
9246
|
+
const dx = end.x - p.x;
|
|
9247
|
+
const dy = end.y - p.y;
|
|
9248
|
+
const len = Math.hypot(dx, dy);
|
|
9249
|
+
if (len > 1e-6) return { end, ux: dx / len, uy: dy / len };
|
|
9250
|
+
}
|
|
9251
|
+
return null;
|
|
9252
|
+
}
|
|
9253
|
+
function \u7AEF\u3067\u306E\u5411\u304D(d, \u7AEF) {
|
|
9254
|
+
const segs = extractPathSegments(d);
|
|
9255
|
+
if (segs.length === 0) return null;
|
|
9256
|
+
if (\u7AEF === "head") {
|
|
9257
|
+
const last = segs[segs.length - 1];
|
|
9258
|
+
const end2 = { x: last.x2, y: last.y2 };
|
|
9259
|
+
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 }]);
|
|
9260
|
+
return \u5411\u304D\u3092\u53D6\u308B(end2, \u5019\u88DC2);
|
|
9261
|
+
}
|
|
9262
|
+
const first = segs[0];
|
|
9263
|
+
const end = { x: first.x1, y: first.y1 };
|
|
9264
|
+
const \u5019\u88DC = segs.flatMap((s) => [...s.ctrl ?? [], { x: s.x2, y: s.y2 }]);
|
|
9265
|
+
return \u5411\u304D\u3092\u53D6\u308B(end, \u5019\u88DC);
|
|
9266
|
+
}
|
|
9267
|
+
function \u7AEF\u306E\u5B57\u3092\u7F6E\u304F(edge, \u7AEF = "head") {
|
|
9268
|
+
const text = (\u7AEF === "head" ? edge.headLabel : edge.tailLabel)?.trim();
|
|
9269
|
+
if (!text) return null;
|
|
9270
|
+
const \u5411\u304D = \u7AEF\u3067\u306E\u5411\u304D(edge.d, \u7AEF);
|
|
9271
|
+
if (!\u5411\u304D) return null;
|
|
9272
|
+
const { end, ux, uy } = \u5411\u304D;
|
|
9273
|
+
const bx = end.x - ux * \u7AEF\u306E\u5B57\u3092\u623B\u3059\u8DDD\u96E2;
|
|
9274
|
+
const by = end.y - uy * \u7AEF\u306E\u5B57\u3092\u623B\u3059\u8DDD\u96E2;
|
|
9275
|
+
const w = measureTextWidth(text, {
|
|
9276
|
+
fontSize: \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055,
|
|
9277
|
+
fontWeight: EDGE_LABEL_TEXT.sub.fontWeight,
|
|
9278
|
+
fontFamily: "mono"
|
|
9279
|
+
});
|
|
9280
|
+
const h = \u7BB1\u306E\u9AD8\u3055;
|
|
9281
|
+
const \u672D = hasRenderedLabel(edge) && edge.labelX !== void 0 && edge.labelY !== void 0 ? { x: edge.labelX, y: edge.labelY } : null;
|
|
9282
|
+
let anchor;
|
|
9283
|
+
let box;
|
|
9284
|
+
if (Math.abs(ux) >= Math.abs(uy)) {
|
|
9285
|
+
const \u53F3\u3078\u9032\u3080 = ux > 0;
|
|
9286
|
+
const \u4E0A\u306B\u7F6E\u304F = \u672D !== null && \u672D.y > by;
|
|
9287
|
+
anchor = \u53F3\u3078\u9032\u3080 ? "end" : "start";
|
|
9288
|
+
box = {
|
|
9289
|
+
x: \u53F3\u3078\u9032\u3080 ? bx - w : bx,
|
|
9290
|
+
y: \u4E0A\u306B\u7F6E\u304F ? by - \u7AEF\u306E\u5B57\u3068\u7DDA\u306E\u9699\u9593 - h : by + \u7AEF\u306E\u5B57\u3068\u7DDA\u306E\u9699\u9593,
|
|
9291
|
+
w,
|
|
9292
|
+
h
|
|
9293
|
+
};
|
|
9294
|
+
} else {
|
|
9295
|
+
const \u4E0B\u3078\u9032\u3080 = uy > 0;
|
|
9296
|
+
const \u53F3\u306B\u7F6E\u304F = \u672D !== null && \u672D.x < bx;
|
|
9297
|
+
anchor = \u53F3\u306B\u7F6E\u304F ? "start" : "end";
|
|
9298
|
+
box = {
|
|
9299
|
+
x: \u53F3\u306B\u7F6E\u304F ? bx + \u7AEF\u306E\u5B57\u3068\u7DDA\u306E\u9699\u9593 : bx - \u7AEF\u306E\u5B57\u3068\u7DDA\u306E\u9699\u9593 - w,
|
|
9300
|
+
y: \u4E0B\u3078\u9032\u3080 ? by - h : by,
|
|
9301
|
+
w,
|
|
9302
|
+
h
|
|
9303
|
+
};
|
|
9304
|
+
}
|
|
9305
|
+
const x = anchor === "start" ? box.x : box.x + box.w;
|
|
9306
|
+
const y = box.y + (h - \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055) / 2 + \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055 * BASELINE_RATIO;
|
|
9307
|
+
return { x, y, anchor, box };
|
|
9308
|
+
}
|
|
9309
|
+
|
|
9229
9310
|
// src/layout/nodes.ts
|
|
9230
9311
|
function autoStorageHeight(n, defaultH) {
|
|
9231
9312
|
if (n.kind !== "storage") return n.h ?? defaultH;
|
|
@@ -9247,7 +9328,7 @@ function autoRowsWidth(n, defaultW) {
|
|
|
9247
9328
|
const required = requiredRowsWidth(n.rows, n.kind);
|
|
9248
9329
|
return Math.max(defaultW, required);
|
|
9249
9330
|
}
|
|
9250
|
-
function \u7BB1\u306E\u9AD8\
|
|
9331
|
+
function \u7BB1\u306E\u9AD8\u30552(n, \u65E2\u5B9Ah) {
|
|
9251
9332
|
if (n.h != null) return n.h;
|
|
9252
9333
|
if (n.kind === "storage") return autoStorageHeight(n, \u65E2\u5B9Ah);
|
|
9253
9334
|
return \u4E2D\u8EAB\u304B\u3089\u51FA\u3059\u9AD8\u3055(n.kind, \u65E2\u5B9Ah, {
|
|
@@ -9261,8 +9342,8 @@ function requiredStackGapForEdgeLabels(diag, allStacks) {
|
|
|
9261
9342
|
const byId = new Map(diag.nodes.map((n) => [n.id, n]));
|
|
9262
9343
|
const rankOf = new Map(allStacks.map((stack, i) => [stack, i]));
|
|
9263
9344
|
const pillHsByGap = /* @__PURE__ */ new Map();
|
|
9345
|
+
let \u7AEF\u306E\u5B57\u306E\u8981\u6C42 = 0;
|
|
9264
9346
|
for (const e of diag.edges) {
|
|
9265
|
-
if (!hasRenderedLabel(e)) continue;
|
|
9266
9347
|
const from = byId.get(e.from);
|
|
9267
9348
|
const to = byId.get(e.to);
|
|
9268
9349
|
if (!from || !to) continue;
|
|
@@ -9271,10 +9352,12 @@ function requiredStackGapForEdgeLabels(diag, allStacks) {
|
|
|
9271
9352
|
const toRank = rankOf.get(to.stack);
|
|
9272
9353
|
if (fromRank === void 0 || toRank === void 0) continue;
|
|
9273
9354
|
if (Math.abs(fromRank - toRank) !== 1) continue;
|
|
9355
|
+
\u7AEF\u306E\u5B57\u306E\u8981\u6C42 = Math.max(\u7AEF\u306E\u5B57\u306E\u8981\u6C42, \u7AEF\u306E\u5B57\u306B\u8981\u308B\u7DDA\u306E\u9577\u3055(e));
|
|
9356
|
+
if (!hasRenderedLabel(e)) continue;
|
|
9274
9357
|
const key = `${from.lane}::${Math.min(fromRank, toRank)}`;
|
|
9275
9358
|
pillHsByGap.set(key, [...pillHsByGap.get(key) ?? [], labelPillH(e.sub)]);
|
|
9276
9359
|
}
|
|
9277
|
-
let required =
|
|
9360
|
+
let required = \u7AEF\u306E\u5B57\u306E\u8981\u6C42;
|
|
9278
9361
|
for (const pillHs of pillHsByGap.values()) {
|
|
9279
9362
|
required = Math.max(required, requiredVerticalLabelGap(pillHs));
|
|
9280
9363
|
}
|
|
@@ -9286,7 +9369,7 @@ function layoutNodes(diag, lanes) {
|
|
|
9286
9369
|
const rowH = /* @__PURE__ */ new Map();
|
|
9287
9370
|
for (const stack of allStacks) {
|
|
9288
9371
|
const nodesAtStack = diag.nodes.filter((n) => n.stack === stack);
|
|
9289
|
-
const h = Math.max(...nodesAtStack.map((n) => \u7BB1\u306E\u9AD8\
|
|
9372
|
+
const h = Math.max(...nodesAtStack.map((n) => \u7BB1\u306E\u9AD8\u30552(n, NODE_SIZE[n.kind].h)));
|
|
9290
9373
|
rowH.set(stack, h);
|
|
9291
9374
|
}
|
|
9292
9375
|
const rowCy = /* @__PURE__ */ new Map();
|
|
@@ -9340,7 +9423,7 @@ function layoutNodes(diag, lanes) {
|
|
|
9340
9423
|
const \u6BB5\u306E\u82AF = rowCy.get(n.stack);
|
|
9341
9424
|
const \u6BB5\u306E\u9AD8\u3055 = rowH.get(n.stack);
|
|
9342
9425
|
const \u81EA\u524D\u306E\u9AD8\u3055 = n.rowMarks !== void 0;
|
|
9343
|
-
const h = n.h ?? (\u81EA\u524D\u306E\u9AD8\u3055 ? \u7BB1\u306E\u9AD8\
|
|
9426
|
+
const h = n.h ?? (\u81EA\u524D\u306E\u9AD8\u3055 ? \u7BB1\u306E\u9AD8\u30552(n, size.h) : \u6BB5\u306E\u9AD8\u3055);
|
|
9344
9427
|
const cy = \u6BB5\u306E\u82AF;
|
|
9345
9428
|
const w = autoRowsWidth(n, size.w);
|
|
9346
9429
|
out.push({
|
|
@@ -10414,73 +10497,6 @@ function \u7B49\u5E45\u306E\u5B57(text, fontSize) {
|
|
|
10414
10497
|
});
|
|
10415
10498
|
return out;
|
|
10416
10499
|
}
|
|
10417
|
-
|
|
10418
|
-
// src/layout/head-label.ts
|
|
10419
|
-
var \u7AEF\u306E\u5B57\u3092\u623B\u3059\u8DDD\u96E2 = 22;
|
|
10420
|
-
var \u7AEF\u306E\u5B57\u3068\u7DDA\u306E\u9699\u9593 = 8;
|
|
10421
|
-
var \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055 = EDGE_LABEL_TEXT.sub.fontSize;
|
|
10422
|
-
var \u7BB1\u306E\u9AD8\u30552 = Math.round(\u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055 * 1.2);
|
|
10423
|
-
var BASELINE_RATIO = 0.8;
|
|
10424
|
-
function \u6700\u5F8C\u306E\u5411\u304D(d) {
|
|
10425
|
-
const segs = extractPathSegments(d);
|
|
10426
|
-
const last = segs[segs.length - 1];
|
|
10427
|
-
if (!last) return null;
|
|
10428
|
-
const end = { x: last.x2, y: last.y2 };
|
|
10429
|
-
for (let i = segs.length - 1; i >= 0; i--) {
|
|
10430
|
-
const s = segs[i];
|
|
10431
|
-
const \u5236\u5FA1\u70B9 = s.cmd === "Q" ? s.ctrl?.[0] : s.cmd === "C" ? s.ctrl?.[1] : void 0;
|
|
10432
|
-
for (const p of [\u5236\u5FA1\u70B9, { x: s.x1, y: s.y1 }]) {
|
|
10433
|
-
if (!p) continue;
|
|
10434
|
-
const dx = end.x - p.x;
|
|
10435
|
-
const dy = end.y - p.y;
|
|
10436
|
-
const len = Math.hypot(dx, dy);
|
|
10437
|
-
if (len > 1e-6) return { end, ux: dx / len, uy: dy / len };
|
|
10438
|
-
}
|
|
10439
|
-
}
|
|
10440
|
-
return null;
|
|
10441
|
-
}
|
|
10442
|
-
function \u7AEF\u306E\u5B57\u3092\u7F6E\u304F(edge) {
|
|
10443
|
-
const text = edge.headLabel?.trim();
|
|
10444
|
-
if (!text) return null;
|
|
10445
|
-
const \u5411\u304D = \u6700\u5F8C\u306E\u5411\u304D(edge.d);
|
|
10446
|
-
if (!\u5411\u304D) return null;
|
|
10447
|
-
const { end, ux, uy } = \u5411\u304D;
|
|
10448
|
-
const bx = end.x - ux * \u7AEF\u306E\u5B57\u3092\u623B\u3059\u8DDD\u96E2;
|
|
10449
|
-
const by = end.y - uy * \u7AEF\u306E\u5B57\u3092\u623B\u3059\u8DDD\u96E2;
|
|
10450
|
-
const w = measureTextWidth(text, {
|
|
10451
|
-
fontSize: \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055,
|
|
10452
|
-
fontWeight: EDGE_LABEL_TEXT.sub.fontWeight,
|
|
10453
|
-
fontFamily: "mono"
|
|
10454
|
-
});
|
|
10455
|
-
const h = \u7BB1\u306E\u9AD8\u30552;
|
|
10456
|
-
const \u672D = hasRenderedLabel(edge) && edge.labelX !== void 0 && edge.labelY !== void 0 ? { x: edge.labelX, y: edge.labelY } : null;
|
|
10457
|
-
let anchor;
|
|
10458
|
-
let box;
|
|
10459
|
-
if (Math.abs(ux) >= Math.abs(uy)) {
|
|
10460
|
-
const \u53F3\u3078\u9032\u3080 = ux > 0;
|
|
10461
|
-
const \u4E0A\u306B\u7F6E\u304F = \u672D !== null && \u672D.y > by;
|
|
10462
|
-
anchor = \u53F3\u3078\u9032\u3080 ? "end" : "start";
|
|
10463
|
-
box = {
|
|
10464
|
-
x: \u53F3\u3078\u9032\u3080 ? bx - w : bx,
|
|
10465
|
-
y: \u4E0A\u306B\u7F6E\u304F ? by - \u7AEF\u306E\u5B57\u3068\u7DDA\u306E\u9699\u9593 - h : by + \u7AEF\u306E\u5B57\u3068\u7DDA\u306E\u9699\u9593,
|
|
10466
|
-
w,
|
|
10467
|
-
h
|
|
10468
|
-
};
|
|
10469
|
-
} else {
|
|
10470
|
-
const \u4E0B\u3078\u9032\u3080 = uy > 0;
|
|
10471
|
-
const \u53F3\u306B\u7F6E\u304F = \u672D !== null && \u672D.x < bx;
|
|
10472
|
-
anchor = \u53F3\u306B\u7F6E\u304F ? "start" : "end";
|
|
10473
|
-
box = {
|
|
10474
|
-
x: \u53F3\u306B\u7F6E\u304F ? bx + \u7AEF\u306E\u5B57\u3068\u7DDA\u306E\u9699\u9593 : bx - \u7AEF\u306E\u5B57\u3068\u7DDA\u306E\u9699\u9593 - w,
|
|
10475
|
-
y: \u4E0B\u3078\u9032\u3080 ? by - h : by,
|
|
10476
|
-
w,
|
|
10477
|
-
h
|
|
10478
|
-
};
|
|
10479
|
-
}
|
|
10480
|
-
const x = anchor === "start" ? box.x : box.x + box.w;
|
|
10481
|
-
const y = box.y + (h - \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055) / 2 + \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055 * BASELINE_RATIO;
|
|
10482
|
-
return { x, y, anchor, box };
|
|
10483
|
-
}
|
|
10484
10500
|
function defaultEdgeWidth(active) {
|
|
10485
10501
|
return active ? 2.5 : 1.25;
|
|
10486
10502
|
}
|
|
@@ -10743,11 +10759,12 @@ function CdlEdgeLabelView({
|
|
|
10743
10759
|
}
|
|
10744
10760
|
);
|
|
10745
10761
|
}
|
|
10746
|
-
function
|
|
10762
|
+
function CdlEdgeEndLabelView({
|
|
10747
10763
|
edge,
|
|
10748
|
-
active
|
|
10764
|
+
active,
|
|
10765
|
+
\u7AEF
|
|
10749
10766
|
}) {
|
|
10750
|
-
const \u7F6E\u304D\u5834\u6240 = \u7AEF\u306E\u5B57\u3092\u7F6E\u304F(edge);
|
|
10767
|
+
const \u7F6E\u304D\u5834\u6240 = \u7AEF\u306E\u5B57\u3092\u7F6E\u304F(edge, \u7AEF);
|
|
10751
10768
|
if (!\u7F6E\u304D\u5834\u6240) return null;
|
|
10752
10769
|
const color = edgeColor(edge);
|
|
10753
10770
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -10755,6 +10772,7 @@ function CdlEdgeHeadLabelView({
|
|
|
10755
10772
|
{
|
|
10756
10773
|
"data-cdl-role": "edge-end-label",
|
|
10757
10774
|
"data-cdl-edge-end-label-for": edge.id,
|
|
10775
|
+
"data-cdl-edge-end": \u7AEF,
|
|
10758
10776
|
x: \u7F6E\u304D\u5834\u6240.x,
|
|
10759
10777
|
y: \u7F6E\u304D\u5834\u6240.y,
|
|
10760
10778
|
fontSize: \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055,
|
|
@@ -10766,7 +10784,7 @@ function CdlEdgeHeadLabelView({
|
|
|
10766
10784
|
strokeLinejoin: "round",
|
|
10767
10785
|
paintOrder: "stroke",
|
|
10768
10786
|
style: { fontFamily: fontFamilyAttr("sub") },
|
|
10769
|
-
children: \u7B49\u5E45\u306E\u5B57(edge.headLabel, \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055)
|
|
10787
|
+
children: \u7B49\u5E45\u306E\u5B57(\u7AEF === "head" ? edge.headLabel : edge.tailLabel, \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055)
|
|
10770
10788
|
}
|
|
10771
10789
|
);
|
|
10772
10790
|
}
|
|
@@ -19051,14 +19069,17 @@ function CdlStage({
|
|
|
19051
19069
|
},
|
|
19052
19070
|
`label-${edge.id}`
|
|
19053
19071
|
)),
|
|
19054
|
-
laid.edges.filter((edge) => edge.headLabel && \u77E2\u5370\u306E\u51FA\u756A.\u51FA\u308B\u304B(edge.id)).
|
|
19055
|
-
|
|
19056
|
-
|
|
19057
|
-
|
|
19058
|
-
|
|
19059
|
-
|
|
19060
|
-
|
|
19061
|
-
|
|
19072
|
+
laid.edges.filter((edge) => (edge.headLabel || edge.tailLabel) && \u77E2\u5370\u306E\u51FA\u756A.\u51FA\u308B\u304B(edge.id)).flatMap(
|
|
19073
|
+
(edge) => ["head", "tail"].map((\u7AEF) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
19074
|
+
CdlEdgeEndLabelView,
|
|
19075
|
+
{
|
|
19076
|
+
edge,
|
|
19077
|
+
active: activeSet.has(edge.id),
|
|
19078
|
+
\u7AEF
|
|
19079
|
+
},
|
|
19080
|
+
`${\u7AEF}-label-${edge.id}`
|
|
19081
|
+
))
|
|
19082
|
+
),
|
|
19062
19083
|
debug && /* @__PURE__ */ jsxRuntime.jsxs("g", { pointerEvents: "none", children: [
|
|
19063
19084
|
laid.bboxes.map((bbox, idx) => {
|
|
19064
19085
|
const color = bbox.kind === "node" ? "#3b82f6" : bbox.kind === "lane-label" ? "#a855f7" : bbox.kind === "edge-label" ? "#10b981" : "#f59e0b";
|