@diagrammo/dgmo 0.5.2 → 0.5.4
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/README.md +16 -16
- package/dist/cli.cjs +159 -159
- package/dist/index.cjs +770 -322
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +37 -23
- package/dist/index.d.ts +37 -23
- package/dist/index.js +769 -322
- package/dist/index.js.map +1 -1
- package/docs/language-reference.md +20 -2
- package/package.json +1 -1
- package/src/d3.ts +254 -211
- package/src/index.ts +3 -0
- package/src/infra/compute.ts +88 -10
- package/src/infra/layout.ts +97 -12
- package/src/infra/parser.ts +47 -4
- package/src/infra/renderer.ts +216 -42
- package/src/infra/roles.ts +15 -0
- package/src/infra/types.ts +7 -0
- package/src/initiative-status/collapse.ts +76 -0
- package/src/initiative-status/layout.ts +193 -26
- package/src/initiative-status/renderer.ts +94 -46
- package/src/org/layout.ts +5 -2
- package/src/org/renderer.ts +65 -11
- package/src/org/resolver.ts +1 -1
- package/src/sharing.ts +12 -0
package/dist/index.cjs
CHANGED
|
@@ -6883,7 +6883,10 @@ var init_types2 = __esm({
|
|
|
6883
6883
|
"buffer",
|
|
6884
6884
|
"drain-rate",
|
|
6885
6885
|
"retention-hours",
|
|
6886
|
-
"partitions"
|
|
6886
|
+
"partitions",
|
|
6887
|
+
"slo-availability",
|
|
6888
|
+
"slo-p90-latency-ms",
|
|
6889
|
+
"slo-warning-margin"
|
|
6887
6890
|
]);
|
|
6888
6891
|
EDGE_ONLY_KEYS = /* @__PURE__ */ new Set(["rps"]);
|
|
6889
6892
|
}
|
|
@@ -7019,6 +7022,18 @@ function parseInfra(content) {
|
|
|
7019
7022
|
result.options["default-uptime"] = trimmed.replace(/^default-uptime\s*:\s*/i, "").trim();
|
|
7020
7023
|
continue;
|
|
7021
7024
|
}
|
|
7025
|
+
if (/^slo-availability\s*:/i.test(trimmed)) {
|
|
7026
|
+
result.options["slo-availability"] = trimmed.replace(/^slo-availability\s*:\s*/i, "").trim();
|
|
7027
|
+
continue;
|
|
7028
|
+
}
|
|
7029
|
+
if (/^slo-p90-latency-ms\s*:/i.test(trimmed)) {
|
|
7030
|
+
result.options["slo-p90-latency-ms"] = trimmed.replace(/^slo-p90-latency-ms\s*:\s*/i, "").trim();
|
|
7031
|
+
continue;
|
|
7032
|
+
}
|
|
7033
|
+
if (/^slo-warning-margin\s*:/i.test(trimmed)) {
|
|
7034
|
+
result.options["slo-warning-margin"] = trimmed.replace(/^slo-warning-margin\s*:\s*/i, "").trim();
|
|
7035
|
+
continue;
|
|
7036
|
+
}
|
|
7022
7037
|
if (/^scenario\s*:/i.test(trimmed)) {
|
|
7023
7038
|
finishCurrentNode();
|
|
7024
7039
|
finishCurrentTagGroup();
|
|
@@ -7163,12 +7178,19 @@ function parseInfra(content) {
|
|
|
7163
7178
|
if (simpleConn) {
|
|
7164
7179
|
const targetName = simpleConn[1].trim();
|
|
7165
7180
|
const splitStr = simpleConn[2];
|
|
7181
|
+
const fanoutStr = simpleConn[3];
|
|
7166
7182
|
const split = splitStr ? parseFloat(splitStr) : null;
|
|
7183
|
+
const fanoutRaw = fanoutStr ? parseInt(fanoutStr, 10) : null;
|
|
7184
|
+
if (fanoutRaw !== null && fanoutRaw < 1) {
|
|
7185
|
+
warn(lineNumber, `Fan-out multiplier must be at least 1 (got x${fanoutRaw}). Ignoring.`);
|
|
7186
|
+
}
|
|
7187
|
+
const fanout = fanoutRaw !== null && fanoutRaw >= 1 ? fanoutRaw : null;
|
|
7167
7188
|
result.edges.push({
|
|
7168
7189
|
sourceId: currentNode.id,
|
|
7169
7190
|
targetId: nodeId2(targetName),
|
|
7170
7191
|
label: "",
|
|
7171
7192
|
split,
|
|
7193
|
+
fanout,
|
|
7172
7194
|
lineNumber
|
|
7173
7195
|
});
|
|
7174
7196
|
continue;
|
|
@@ -7178,7 +7200,13 @@ function parseInfra(content) {
|
|
|
7178
7200
|
const label = connMatch[1]?.trim() || "";
|
|
7179
7201
|
const targetName = connMatch[2].trim();
|
|
7180
7202
|
const splitStr = connMatch[3];
|
|
7203
|
+
const fanoutStr = connMatch[4];
|
|
7181
7204
|
const split = splitStr ? parseFloat(splitStr) : null;
|
|
7205
|
+
const fanoutRaw = fanoutStr ? parseInt(fanoutStr, 10) : null;
|
|
7206
|
+
if (fanoutRaw !== null && fanoutRaw < 1) {
|
|
7207
|
+
warn(lineNumber, `Fan-out multiplier must be at least 1 (got x${fanoutRaw}). Ignoring.`);
|
|
7208
|
+
}
|
|
7209
|
+
const fanout = fanoutRaw !== null && fanoutRaw >= 1 ? fanoutRaw : null;
|
|
7182
7210
|
let targetId;
|
|
7183
7211
|
const targetGroupMatch = targetName.match(GROUP_RE);
|
|
7184
7212
|
if (targetGroupMatch) {
|
|
@@ -7191,14 +7219,20 @@ function parseInfra(content) {
|
|
|
7191
7219
|
targetId,
|
|
7192
7220
|
label,
|
|
7193
7221
|
split,
|
|
7222
|
+
fanout,
|
|
7194
7223
|
lineNumber
|
|
7195
7224
|
});
|
|
7196
7225
|
continue;
|
|
7197
7226
|
}
|
|
7227
|
+
if (/^description\s*:\s*$/i.test(trimmed)) continue;
|
|
7198
7228
|
const propMatch = trimmed.match(PROPERTY_RE);
|
|
7199
7229
|
if (propMatch) {
|
|
7200
7230
|
const key = propMatch[1].toLowerCase();
|
|
7201
7231
|
const rawVal = propMatch[2].trim();
|
|
7232
|
+
if (key === "description" && currentNode) {
|
|
7233
|
+
if (!currentNode.isEdge) currentNode.description = rawVal;
|
|
7234
|
+
continue;
|
|
7235
|
+
}
|
|
7202
7236
|
if (!INFRA_BEHAVIOR_KEYS.has(key) && !EDGE_ONLY_KEYS.has(key)) {
|
|
7203
7237
|
const allKeys = [...INFRA_BEHAVIOR_KEYS, ...EDGE_ONLY_KEYS];
|
|
7204
7238
|
let msg = `Unknown property '${key}'.`;
|
|
@@ -7300,12 +7334,12 @@ var init_parser9 = __esm({
|
|
|
7300
7334
|
init_diagnostics();
|
|
7301
7335
|
init_parsing();
|
|
7302
7336
|
init_types2();
|
|
7303
|
-
CONNECTION_RE = /^-(?:([^-].*?))?->\s+(.+?)(?:(?:\s*\|\s*|\s+)split\s*:?\s*(\d+)%)?\s*$/;
|
|
7304
|
-
SIMPLE_CONNECTION_RE = /^->\s+(.+?)(?:(?:\s*\|\s*|\s+)split\s*:?\s*(\d+)%)?\s*$/;
|
|
7337
|
+
CONNECTION_RE = /^-(?:([^-].*?))?->\s+(.+?)(?:(?:\s*\|\s*|\s+)split\s*:?\s*(\d+)%)?\s*(?:x(\d+))?\s*$/;
|
|
7338
|
+
SIMPLE_CONNECTION_RE = /^->\s+(.+?)(?:(?:\s*\|\s*|\s+)split\s*:?\s*(\d+)%)?\s*(?:x(\d+))?\s*$/;
|
|
7305
7339
|
GROUP_RE = /^\[([^\]]+)\]$/;
|
|
7306
7340
|
TAG_GROUP_RE = /^tag\s*:\s*(\w[\w\s]*?)(?:\s+alias\s+(\w+))?\s*$/;
|
|
7307
7341
|
TAG_VALUE_RE = /^(\w[\w\s]*?)(?:\(([^)]+)\))?(\s+default)?\s*$/;
|
|
7308
|
-
COMPONENT_RE = /^([a-zA-Z_][\w]*)(.*)$/;
|
|
7342
|
+
COMPONENT_RE = /^([a-zA-Z_][\w-]*)(.*)$/;
|
|
7309
7343
|
PIPE_META_RE = /[|,]\s*(\w+)\s*:\s*([^|,]+)/g;
|
|
7310
7344
|
PROPERTY_RE = /^([\w-]+)\s*:\s*(.+)$/;
|
|
7311
7345
|
PERCENT_RE = /^([\d.]+)%$/;
|
|
@@ -7539,7 +7573,7 @@ function centerHeavyChildren(node) {
|
|
|
7539
7573
|
}
|
|
7540
7574
|
node.children = result;
|
|
7541
7575
|
}
|
|
7542
|
-
function computeLegendGroups(tagGroups,
|
|
7576
|
+
function computeLegendGroups(tagGroups, showEyeIcons, usedValuesByGroup) {
|
|
7543
7577
|
const groups = [];
|
|
7544
7578
|
for (const group of tagGroups) {
|
|
7545
7579
|
if (group.entries.length === 0) continue;
|
|
@@ -7552,7 +7586,8 @@ function computeLegendGroups(tagGroups, _showEyeIcons, usedValuesByGroup) {
|
|
|
7552
7586
|
for (const entry of visibleEntries) {
|
|
7553
7587
|
entriesWidth += LEGEND_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP + entry.value.length * LEGEND_ENTRY_FONT_W + LEGEND_ENTRY_TRAIL;
|
|
7554
7588
|
}
|
|
7555
|
-
const
|
|
7589
|
+
const eyeSpace = showEyeIcons ? LEGEND_EYE_SIZE + LEGEND_EYE_GAP : 0;
|
|
7590
|
+
const capsuleWidth = LEGEND_CAPSULE_PAD * 2 + pillWidth + 4 + eyeSpace + entriesWidth;
|
|
7556
7591
|
groups.push({
|
|
7557
7592
|
name: group.name,
|
|
7558
7593
|
alias: group.alias,
|
|
@@ -8185,7 +8220,7 @@ function layoutOrg(parsed, hiddenCounts, activeTagGroup, hiddenAttributes, expan
|
|
|
8185
8220
|
height: finalHeight
|
|
8186
8221
|
};
|
|
8187
8222
|
}
|
|
8188
|
-
var import_d3_hierarchy, CHAR_WIDTH, META_LINE_HEIGHT, HEADER_HEIGHT, SEPARATOR_GAP, CARD_H_PAD, CARD_V_PAD, MIN_CARD_WIDTH, H_GAP, V_GAP, MARGIN, CONTAINER_PAD_X, CONTAINER_PAD_BOTTOM, CONTAINER_LABEL_HEIGHT, CONTAINER_META_LINE_HEIGHT, STACK_V_GAP, LEGEND_GAP, LEGEND_HEIGHT, LEGEND_PILL_PAD, LEGEND_PILL_FONT_W, LEGEND_CAPSULE_PAD, LEGEND_DOT_R, LEGEND_ENTRY_FONT_W, LEGEND_ENTRY_DOT_GAP, LEGEND_ENTRY_TRAIL, LEGEND_GROUP_GAP;
|
|
8223
|
+
var import_d3_hierarchy, CHAR_WIDTH, META_LINE_HEIGHT, HEADER_HEIGHT, SEPARATOR_GAP, CARD_H_PAD, CARD_V_PAD, MIN_CARD_WIDTH, H_GAP, V_GAP, MARGIN, CONTAINER_PAD_X, CONTAINER_PAD_BOTTOM, CONTAINER_LABEL_HEIGHT, CONTAINER_META_LINE_HEIGHT, STACK_V_GAP, LEGEND_GAP, LEGEND_HEIGHT, LEGEND_PILL_PAD, LEGEND_PILL_FONT_W, LEGEND_CAPSULE_PAD, LEGEND_DOT_R, LEGEND_ENTRY_FONT_W, LEGEND_ENTRY_DOT_GAP, LEGEND_ENTRY_TRAIL, LEGEND_GROUP_GAP, LEGEND_EYE_SIZE, LEGEND_EYE_GAP;
|
|
8189
8224
|
var init_layout = __esm({
|
|
8190
8225
|
"src/org/layout.ts"() {
|
|
8191
8226
|
"use strict";
|
|
@@ -8216,6 +8251,8 @@ var init_layout = __esm({
|
|
|
8216
8251
|
LEGEND_ENTRY_DOT_GAP = 4;
|
|
8217
8252
|
LEGEND_ENTRY_TRAIL = 8;
|
|
8218
8253
|
LEGEND_GROUP_GAP = 12;
|
|
8254
|
+
LEGEND_EYE_SIZE = 14;
|
|
8255
|
+
LEGEND_EYE_GAP = 6;
|
|
8219
8256
|
}
|
|
8220
8257
|
});
|
|
8221
8258
|
|
|
@@ -8317,22 +8354,27 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
|
|
|
8317
8354
|
const layoutLegendShift = LEGEND_HEIGHT2 + LEGEND_GROUP_GAP2;
|
|
8318
8355
|
const fixedLegend = !exportDims && hasLegend && !legendOnly;
|
|
8319
8356
|
const legendReserve = fixedLegend ? LEGEND_HEIGHT2 + LEGEND_FIXED_GAP : 0;
|
|
8357
|
+
const fixedTitle = !exportDims && !!parsed.title;
|
|
8358
|
+
const titleReserve = fixedTitle ? TITLE_HEIGHT : 0;
|
|
8320
8359
|
const diagramW = layout.width;
|
|
8321
|
-
let diagramH = layout.height + titleOffset;
|
|
8360
|
+
let diagramH = layout.height + (fixedTitle ? 0 : titleOffset);
|
|
8322
8361
|
if (fixedLegend) {
|
|
8323
8362
|
diagramH -= layoutLegendShift;
|
|
8324
8363
|
}
|
|
8325
|
-
const availH = height - DIAGRAM_PADDING * 2 - legendReserve;
|
|
8364
|
+
const availH = height - DIAGRAM_PADDING * 2 - legendReserve - titleReserve;
|
|
8326
8365
|
const scaleX = (width - DIAGRAM_PADDING * 2) / diagramW;
|
|
8327
8366
|
const scaleY = availH / diagramH;
|
|
8328
8367
|
const scale = Math.min(MAX_SCALE, scaleX, scaleY);
|
|
8329
8368
|
const scaledW = diagramW * scale;
|
|
8330
8369
|
const offsetX = (width - scaledW) / 2;
|
|
8331
|
-
const offsetY = legendPosition === "top" && fixedLegend ? DIAGRAM_PADDING + legendReserve : DIAGRAM_PADDING;
|
|
8370
|
+
const offsetY = legendPosition === "top" && fixedLegend ? DIAGRAM_PADDING + legendReserve + titleReserve : DIAGRAM_PADDING + titleReserve;
|
|
8332
8371
|
const svg = d3Selection.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
|
|
8333
8372
|
const mainG = svg.append("g").attr("transform", `translate(${offsetX}, ${offsetY}) scale(${scale})`);
|
|
8334
8373
|
if (parsed.title) {
|
|
8335
|
-
const
|
|
8374
|
+
const titleParent = fixedTitle ? svg : mainG;
|
|
8375
|
+
const titleX = fixedTitle ? width / 2 : diagramW / 2;
|
|
8376
|
+
const titleY = fixedTitle ? DIAGRAM_PADDING + TITLE_FONT_SIZE : TITLE_FONT_SIZE;
|
|
8377
|
+
const titleEl = titleParent.append("text").attr("x", titleX).attr("y", titleY).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-size", TITLE_FONT_SIZE).attr("font-weight", "bold").attr("class", "org-title chart-title").style(
|
|
8336
8378
|
"cursor",
|
|
8337
8379
|
onClickItem && parsed.titleLineNumber ? "pointer" : "default"
|
|
8338
8380
|
).text(parsed.title);
|
|
@@ -8347,7 +8389,7 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
|
|
|
8347
8389
|
}
|
|
8348
8390
|
}
|
|
8349
8391
|
}
|
|
8350
|
-
const contentG = mainG.append("g").attr("transform", `translate(0, ${titleOffset})`);
|
|
8392
|
+
const contentG = mainG.append("g").attr("transform", `translate(0, ${fixedTitle ? 0 : titleOffset})`);
|
|
8351
8393
|
const displayNames = /* @__PURE__ */ new Map();
|
|
8352
8394
|
for (const group of parsed.tagGroups) {
|
|
8353
8395
|
displayNames.set(group.name.toLowerCase(), group.name);
|
|
@@ -8475,7 +8517,7 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
|
|
|
8475
8517
|
}
|
|
8476
8518
|
const legendParent = fixedLegend ? svg.append("g").attr("class", "org-legend-fixed").attr(
|
|
8477
8519
|
"transform",
|
|
8478
|
-
legendPosition === "bottom" ? `translate(0, ${height - DIAGRAM_PADDING - LEGEND_HEIGHT2})` : `translate(0, ${DIAGRAM_PADDING})`
|
|
8520
|
+
legendPosition === "bottom" ? `translate(0, ${height - DIAGRAM_PADDING - LEGEND_HEIGHT2})` : `translate(0, ${DIAGRAM_PADDING + titleReserve})`
|
|
8479
8521
|
) : contentG;
|
|
8480
8522
|
for (const group of visibleGroups) {
|
|
8481
8523
|
const isActive = legendOnly || activeTagGroup != null && group.name.toLowerCase() === activeTagGroup.toLowerCase();
|
|
@@ -8496,8 +8538,19 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
|
|
|
8496
8538
|
gEl.append("rect").attr("x", pillXOff).attr("y", pillYOff).attr("width", pillWidth).attr("height", pillH).attr("rx", pillH / 2).attr("fill", "none").attr("stroke", mix(palette.textMuted, palette.bg, 50)).attr("stroke-width", 0.75);
|
|
8497
8539
|
}
|
|
8498
8540
|
gEl.append("text").attr("x", pillXOff + pillWidth / 2).attr("y", LEGEND_HEIGHT2 / 2 + LEGEND_PILL_FONT_SIZE / 2 - 2).attr("font-size", LEGEND_PILL_FONT_SIZE).attr("font-weight", "500").attr("fill", isActive ? palette.text : palette.textMuted).attr("text-anchor", "middle").text(pillLabel);
|
|
8541
|
+
if (isActive && fixedLegend) {
|
|
8542
|
+
const groupKey = group.name.toLowerCase();
|
|
8543
|
+
const isHidden = hiddenAttributes?.has(groupKey) ?? false;
|
|
8544
|
+
const eyeX = pillXOff + pillWidth + LEGEND_EYE_GAP2;
|
|
8545
|
+
const eyeY = (LEGEND_HEIGHT2 - LEGEND_EYE_SIZE2) / 2;
|
|
8546
|
+
const hitPad = 6;
|
|
8547
|
+
const eyeG = gEl.append("g").attr("class", "org-legend-eye").attr("data-legend-visibility", groupKey).style("cursor", "pointer").attr("opacity", isHidden ? 0.4 : 0.7);
|
|
8548
|
+
eyeG.append("rect").attr("x", eyeX - hitPad).attr("y", eyeY - hitPad).attr("width", LEGEND_EYE_SIZE2 + hitPad * 2).attr("height", LEGEND_EYE_SIZE2 + hitPad * 2).attr("fill", "transparent").attr("pointer-events", "all");
|
|
8549
|
+
eyeG.append("path").attr("d", isHidden ? EYE_CLOSED_PATH : EYE_OPEN_PATH).attr("transform", `translate(${eyeX}, ${eyeY})`).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", 1.2).attr("stroke-linecap", "round").attr("stroke-linejoin", "round");
|
|
8550
|
+
}
|
|
8499
8551
|
if (isActive) {
|
|
8500
|
-
|
|
8552
|
+
const eyeShift = fixedLegend ? LEGEND_EYE_SIZE2 + LEGEND_EYE_GAP2 : 0;
|
|
8553
|
+
let entryX = pillXOff + pillWidth + 4 + eyeShift;
|
|
8501
8554
|
for (const entry of group.entries) {
|
|
8502
8555
|
const entryG = gEl.append("g").attr("data-legend-entry", entry.value.toLowerCase()).style("cursor", "pointer");
|
|
8503
8556
|
entryG.append("circle").attr("cx", entryX + LEGEND_DOT_R2).attr("cy", LEGEND_HEIGHT2 / 2).attr("r", LEGEND_DOT_R2).attr("fill", entry.color);
|
|
@@ -8543,7 +8596,7 @@ function renderOrgForExport(content, theme, palette) {
|
|
|
8543
8596
|
document.body.removeChild(container);
|
|
8544
8597
|
}
|
|
8545
8598
|
}
|
|
8546
|
-
var d3Selection, DIAGRAM_PADDING, MAX_SCALE, TITLE_HEIGHT, TITLE_FONT_SIZE, LABEL_FONT_SIZE, META_FONT_SIZE, META_LINE_HEIGHT2, HEADER_HEIGHT2, SEPARATOR_GAP2, EDGE_STROKE_WIDTH, NODE_STROKE_WIDTH, CARD_RADIUS, CONTAINER_RADIUS, CONTAINER_LABEL_FONT_SIZE, CONTAINER_META_FONT_SIZE, CONTAINER_META_LINE_HEIGHT2, CONTAINER_HEADER_HEIGHT, COLLAPSE_BAR_HEIGHT, COLLAPSE_BAR_INSET, LEGEND_HEIGHT2, LEGEND_PILL_PAD2, LEGEND_PILL_FONT_SIZE, LEGEND_PILL_FONT_W2, LEGEND_CAPSULE_PAD2, LEGEND_DOT_R2, LEGEND_ENTRY_FONT_SIZE, LEGEND_ENTRY_FONT_W2, LEGEND_ENTRY_DOT_GAP2, LEGEND_ENTRY_TRAIL2, LEGEND_GROUP_GAP2, LEGEND_FIXED_GAP;
|
|
8599
|
+
var d3Selection, DIAGRAM_PADDING, MAX_SCALE, TITLE_HEIGHT, TITLE_FONT_SIZE, LABEL_FONT_SIZE, META_FONT_SIZE, META_LINE_HEIGHT2, HEADER_HEIGHT2, SEPARATOR_GAP2, EDGE_STROKE_WIDTH, NODE_STROKE_WIDTH, CARD_RADIUS, CONTAINER_RADIUS, CONTAINER_LABEL_FONT_SIZE, CONTAINER_META_FONT_SIZE, CONTAINER_META_LINE_HEIGHT2, CONTAINER_HEADER_HEIGHT, COLLAPSE_BAR_HEIGHT, COLLAPSE_BAR_INSET, LEGEND_HEIGHT2, LEGEND_PILL_PAD2, LEGEND_PILL_FONT_SIZE, LEGEND_PILL_FONT_W2, LEGEND_CAPSULE_PAD2, LEGEND_DOT_R2, LEGEND_ENTRY_FONT_SIZE, LEGEND_ENTRY_FONT_W2, LEGEND_ENTRY_DOT_GAP2, LEGEND_ENTRY_TRAIL2, LEGEND_GROUP_GAP2, LEGEND_EYE_SIZE2, LEGEND_EYE_GAP2, LEGEND_FIXED_GAP, EYE_OPEN_PATH, EYE_CLOSED_PATH;
|
|
8547
8600
|
var init_renderer = __esm({
|
|
8548
8601
|
"src/org/renderer.ts"() {
|
|
8549
8602
|
"use strict";
|
|
@@ -8582,7 +8635,11 @@ var init_renderer = __esm({
|
|
|
8582
8635
|
LEGEND_ENTRY_DOT_GAP2 = 4;
|
|
8583
8636
|
LEGEND_ENTRY_TRAIL2 = 8;
|
|
8584
8637
|
LEGEND_GROUP_GAP2 = 12;
|
|
8638
|
+
LEGEND_EYE_SIZE2 = 14;
|
|
8639
|
+
LEGEND_EYE_GAP2 = 6;
|
|
8585
8640
|
LEGEND_FIXED_GAP = 8;
|
|
8641
|
+
EYE_OPEN_PATH = "M1 7s2.5-5 6-5 6 5 6 5-2.5 5-6 5-6-5-6-5z M7 9.5a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z";
|
|
8642
|
+
EYE_CLOSED_PATH = "M2.5 2.5l9 9 M1.5 7s2.2-4 5.5-4c1.2 0 2.2.5 3 1.1 M12.5 7s-2.2 4-5.5 4c-1.2 0-2.2-.5-3-1.1";
|
|
8586
8643
|
}
|
|
8587
8644
|
});
|
|
8588
8645
|
|
|
@@ -8631,7 +8688,7 @@ function computeLegendGroups2(tagGroups, usedValuesByGroup) {
|
|
|
8631
8688
|
for (const entry of visibleEntries) {
|
|
8632
8689
|
entriesWidth += LEGEND_DOT_R3 * 2 + LEGEND_ENTRY_DOT_GAP3 + entry.value.length * LEGEND_ENTRY_FONT_W3 + LEGEND_ENTRY_TRAIL3;
|
|
8633
8690
|
}
|
|
8634
|
-
const eyeSpace =
|
|
8691
|
+
const eyeSpace = LEGEND_EYE_SIZE3 + LEGEND_EYE_GAP3;
|
|
8635
8692
|
const capsuleWidth = LEGEND_CAPSULE_PAD3 * 2 + pillWidth + 4 + eyeSpace + entriesWidth;
|
|
8636
8693
|
groups.push({
|
|
8637
8694
|
name: group.name,
|
|
@@ -9033,7 +9090,7 @@ function layoutSitemap(parsed, hiddenCounts, activeTagGroup, hiddenAttributes, e
|
|
|
9033
9090
|
height: totalHeight
|
|
9034
9091
|
};
|
|
9035
9092
|
}
|
|
9036
|
-
var import_dagre, CHAR_WIDTH2, META_LINE_HEIGHT3, HEADER_HEIGHT3, SEPARATOR_GAP3, CARD_H_PAD2, CARD_V_PAD2, MIN_CARD_WIDTH2, MARGIN2, CONTAINER_PAD_X2, CONTAINER_PAD_TOP, CONTAINER_PAD_BOTTOM2, CONTAINER_LABEL_HEIGHT2, CONTAINER_META_LINE_HEIGHT3, LEGEND_HEIGHT3, LEGEND_PILL_PAD3, LEGEND_PILL_FONT_W3, LEGEND_CAPSULE_PAD3, LEGEND_DOT_R3, LEGEND_ENTRY_FONT_W3, LEGEND_ENTRY_DOT_GAP3, LEGEND_ENTRY_TRAIL3, LEGEND_GROUP_GAP3,
|
|
9093
|
+
var import_dagre, CHAR_WIDTH2, META_LINE_HEIGHT3, HEADER_HEIGHT3, SEPARATOR_GAP3, CARD_H_PAD2, CARD_V_PAD2, MIN_CARD_WIDTH2, MARGIN2, CONTAINER_PAD_X2, CONTAINER_PAD_TOP, CONTAINER_PAD_BOTTOM2, CONTAINER_LABEL_HEIGHT2, CONTAINER_META_LINE_HEIGHT3, LEGEND_HEIGHT3, LEGEND_PILL_PAD3, LEGEND_PILL_FONT_W3, LEGEND_CAPSULE_PAD3, LEGEND_DOT_R3, LEGEND_ENTRY_FONT_W3, LEGEND_ENTRY_DOT_GAP3, LEGEND_ENTRY_TRAIL3, LEGEND_GROUP_GAP3, LEGEND_EYE_SIZE3, LEGEND_EYE_GAP3, OVERLAP_GAP;
|
|
9037
9094
|
var init_layout2 = __esm({
|
|
9038
9095
|
"src/sitemap/layout.ts"() {
|
|
9039
9096
|
"use strict";
|
|
@@ -9061,8 +9118,8 @@ var init_layout2 = __esm({
|
|
|
9061
9118
|
LEGEND_ENTRY_DOT_GAP3 = 4;
|
|
9062
9119
|
LEGEND_ENTRY_TRAIL3 = 8;
|
|
9063
9120
|
LEGEND_GROUP_GAP3 = 12;
|
|
9064
|
-
|
|
9065
|
-
|
|
9121
|
+
LEGEND_EYE_SIZE3 = 14;
|
|
9122
|
+
LEGEND_EYE_GAP3 = 6;
|
|
9066
9123
|
OVERLAP_GAP = 20;
|
|
9067
9124
|
}
|
|
9068
9125
|
});
|
|
@@ -9414,15 +9471,15 @@ function renderLegend(parent, legendGroups, palette, isDark, activeTagGroup, fix
|
|
|
9414
9471
|
if (isActive && fixedWidth != null) {
|
|
9415
9472
|
const groupKey = group.name.toLowerCase();
|
|
9416
9473
|
const isHidden = hiddenAttributes?.has(groupKey) ?? false;
|
|
9417
|
-
const eyeX = pillXOff + pillW +
|
|
9418
|
-
const eyeY = (LEGEND_HEIGHT4 -
|
|
9474
|
+
const eyeX = pillXOff + pillW + LEGEND_EYE_GAP4;
|
|
9475
|
+
const eyeY = (LEGEND_HEIGHT4 - LEGEND_EYE_SIZE4) / 2;
|
|
9419
9476
|
const hitPad = 6;
|
|
9420
9477
|
const eyeG = legendG.append("g").attr("class", "sitemap-legend-eye").attr("data-legend-visibility", groupKey).style("cursor", "pointer").attr("opacity", isHidden ? 0.4 : 0.7);
|
|
9421
|
-
eyeG.append("rect").attr("x", eyeX - hitPad).attr("y", eyeY - hitPad).attr("width",
|
|
9422
|
-
eyeG.append("path").attr("d", isHidden ?
|
|
9478
|
+
eyeG.append("rect").attr("x", eyeX - hitPad).attr("y", eyeY - hitPad).attr("width", LEGEND_EYE_SIZE4 + hitPad * 2).attr("height", LEGEND_EYE_SIZE4 + hitPad * 2).attr("fill", "transparent").attr("pointer-events", "all");
|
|
9479
|
+
eyeG.append("path").attr("d", isHidden ? EYE_CLOSED_PATH2 : EYE_OPEN_PATH2).attr("transform", `translate(${eyeX}, ${eyeY})`).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", 1.2).attr("stroke-linecap", "round").attr("stroke-linejoin", "round");
|
|
9423
9480
|
}
|
|
9424
9481
|
if (isActive) {
|
|
9425
|
-
const eyeShift = fixedWidth != null ?
|
|
9482
|
+
const eyeShift = fixedWidth != null ? LEGEND_EYE_SIZE4 + LEGEND_EYE_GAP4 : 0;
|
|
9426
9483
|
let entryX = pillXOff + pillW + 4 + eyeShift;
|
|
9427
9484
|
for (const entry of group.entries) {
|
|
9428
9485
|
const entryG = legendG.append("g").attr("data-legend-entry", entry.value.toLowerCase()).style("cursor", "pointer");
|
|
@@ -9475,7 +9532,7 @@ async function renderSitemapForExport(content, theme, palette) {
|
|
|
9475
9532
|
const brandColor = theme === "transparent" ? "#888" : effectivePalette.textMuted;
|
|
9476
9533
|
return injectBranding2(svgHtml, brandColor);
|
|
9477
9534
|
}
|
|
9478
|
-
var d3Selection2, d3Shape, DIAGRAM_PADDING2, MAX_SCALE2, TITLE_HEIGHT2, TITLE_FONT_SIZE2, LABEL_FONT_SIZE2, META_FONT_SIZE2, META_LINE_HEIGHT4, HEADER_HEIGHT4, SEPARATOR_GAP4, EDGE_STROKE_WIDTH2, NODE_STROKE_WIDTH2, CARD_RADIUS2, CONTAINER_RADIUS2, CONTAINER_LABEL_FONT_SIZE2, CONTAINER_META_FONT_SIZE2, CONTAINER_META_LINE_HEIGHT4, CONTAINER_HEADER_HEIGHT2, ARROWHEAD_W, ARROWHEAD_H, EDGE_LABEL_FONT_SIZE, COLLAPSE_BAR_HEIGHT2, LEGEND_HEIGHT4, LEGEND_FIXED_GAP2, LEGEND_PILL_PAD4, LEGEND_PILL_FONT_SIZE2, LEGEND_PILL_FONT_W4, LEGEND_CAPSULE_PAD4, LEGEND_DOT_R4, LEGEND_ENTRY_FONT_SIZE2, LEGEND_ENTRY_FONT_W4, LEGEND_ENTRY_DOT_GAP4, LEGEND_ENTRY_TRAIL4, LEGEND_GROUP_GAP4,
|
|
9535
|
+
var d3Selection2, d3Shape, DIAGRAM_PADDING2, MAX_SCALE2, TITLE_HEIGHT2, TITLE_FONT_SIZE2, LABEL_FONT_SIZE2, META_FONT_SIZE2, META_LINE_HEIGHT4, HEADER_HEIGHT4, SEPARATOR_GAP4, EDGE_STROKE_WIDTH2, NODE_STROKE_WIDTH2, CARD_RADIUS2, CONTAINER_RADIUS2, CONTAINER_LABEL_FONT_SIZE2, CONTAINER_META_FONT_SIZE2, CONTAINER_META_LINE_HEIGHT4, CONTAINER_HEADER_HEIGHT2, ARROWHEAD_W, ARROWHEAD_H, EDGE_LABEL_FONT_SIZE, COLLAPSE_BAR_HEIGHT2, LEGEND_HEIGHT4, LEGEND_FIXED_GAP2, LEGEND_PILL_PAD4, LEGEND_PILL_FONT_SIZE2, LEGEND_PILL_FONT_W4, LEGEND_CAPSULE_PAD4, LEGEND_DOT_R4, LEGEND_ENTRY_FONT_SIZE2, LEGEND_ENTRY_FONT_W4, LEGEND_ENTRY_DOT_GAP4, LEGEND_ENTRY_TRAIL4, LEGEND_GROUP_GAP4, LEGEND_EYE_SIZE4, LEGEND_EYE_GAP4, lineGenerator, EYE_OPEN_PATH2, EYE_CLOSED_PATH2;
|
|
9479
9536
|
var init_renderer2 = __esm({
|
|
9480
9537
|
"src/sitemap/renderer.ts"() {
|
|
9481
9538
|
"use strict";
|
|
@@ -9516,11 +9573,11 @@ var init_renderer2 = __esm({
|
|
|
9516
9573
|
LEGEND_ENTRY_DOT_GAP4 = 4;
|
|
9517
9574
|
LEGEND_ENTRY_TRAIL4 = 8;
|
|
9518
9575
|
LEGEND_GROUP_GAP4 = 12;
|
|
9519
|
-
|
|
9520
|
-
|
|
9576
|
+
LEGEND_EYE_SIZE4 = 14;
|
|
9577
|
+
LEGEND_EYE_GAP4 = 6;
|
|
9521
9578
|
lineGenerator = d3Shape.line().x((d) => d.x).y((d) => d.y).curve(d3Shape.curveBasis);
|
|
9522
|
-
|
|
9523
|
-
|
|
9579
|
+
EYE_OPEN_PATH2 = "M1 7s2.5-5 6-5 6 5 6 5-2.5 5-6 5-6-5-6-5z M7 9.5a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z";
|
|
9580
|
+
EYE_CLOSED_PATH2 = "M2.5 2.5l9 9 M1.5 7s2.2-4 5.5-4c1.2 0 2.2.5 3 1.1 M12.5 7s-2.2 4-5.5 4c-1.2 0-2.2-.5-3-1.1";
|
|
9524
9581
|
}
|
|
9525
9582
|
});
|
|
9526
9583
|
|
|
@@ -10756,7 +10813,8 @@ var init_renderer5 = __esm({
|
|
|
10756
10813
|
// src/initiative-status/layout.ts
|
|
10757
10814
|
var layout_exports5 = {};
|
|
10758
10815
|
__export(layout_exports5, {
|
|
10759
|
-
layoutInitiativeStatus: () => layoutInitiativeStatus
|
|
10816
|
+
layoutInitiativeStatus: () => layoutInitiativeStatus,
|
|
10817
|
+
rollUpStatus: () => rollUpStatus
|
|
10760
10818
|
});
|
|
10761
10819
|
function rollUpStatus(members) {
|
|
10762
10820
|
let worst = null;
|
|
@@ -10770,14 +10828,28 @@ function rollUpStatus(members) {
|
|
|
10770
10828
|
}
|
|
10771
10829
|
return worst;
|
|
10772
10830
|
}
|
|
10773
|
-
function layoutInitiativeStatus(parsed) {
|
|
10774
|
-
if (parsed.nodes.length === 0) {
|
|
10831
|
+
function layoutInitiativeStatus(parsed, collapseResult) {
|
|
10832
|
+
if (parsed.nodes.length === 0 && (!collapseResult || collapseResult.collapsedGroupStatuses.size === 0)) {
|
|
10775
10833
|
return { nodes: [], edges: [], groups: [], width: 0, height: 0 };
|
|
10776
10834
|
}
|
|
10777
|
-
const
|
|
10835
|
+
const originalGroups = collapseResult?.originalGroups ?? parsed.groups;
|
|
10836
|
+
const collapsedGroupStatuses = collapseResult?.collapsedGroupStatuses ?? /* @__PURE__ */ new Map();
|
|
10837
|
+
const collapsedGroupLabels = new Set(
|
|
10838
|
+
originalGroups.map((g2) => g2.label).filter((l) => !parsed.groups.some((g2) => g2.label === l))
|
|
10839
|
+
);
|
|
10840
|
+
const hasGroups = parsed.groups.length > 0 || collapsedGroupLabels.size > 0;
|
|
10778
10841
|
const g = new import_dagre4.default.graphlib.Graph({ multigraph: true, compound: hasGroups });
|
|
10779
10842
|
g.setGraph({ rankdir: "LR", nodesep: NODESEP, ranksep: RANKSEP });
|
|
10780
10843
|
g.setDefaultEdgeLabel(() => ({}));
|
|
10844
|
+
for (const group of originalGroups) {
|
|
10845
|
+
if (collapsedGroupLabels.has(group.label)) {
|
|
10846
|
+
const collapsedW = Math.max(
|
|
10847
|
+
NODE_WIDTH,
|
|
10848
|
+
Math.ceil(group.label.length * CHAR_WIDTH_RATIO * NODE_FONT_SIZE) + NODE_TEXT_PADDING * 2
|
|
10849
|
+
);
|
|
10850
|
+
g.setNode(group.label, { label: group.label, width: collapsedW, height: NODE_HEIGHT });
|
|
10851
|
+
}
|
|
10852
|
+
}
|
|
10781
10853
|
for (const group of parsed.groups) {
|
|
10782
10854
|
g.setNode(`__group_${group.label}`, { label: group.label, clusterLabelPos: "top" });
|
|
10783
10855
|
}
|
|
@@ -10808,38 +10880,130 @@ function layoutInitiativeStatus(parsed) {
|
|
|
10808
10880
|
height: pos.height
|
|
10809
10881
|
};
|
|
10810
10882
|
});
|
|
10811
|
-
const
|
|
10812
|
-
const
|
|
10813
|
-
|
|
10814
|
-
|
|
10815
|
-
|
|
10883
|
+
const posMap = new Map(layoutNodes.map((n) => [n.label, n]));
|
|
10884
|
+
for (const label of collapsedGroupLabels) {
|
|
10885
|
+
const pos = g.node(label);
|
|
10886
|
+
if (pos) posMap.set(label, { x: pos.x, y: pos.y, width: pos.width, height: pos.height });
|
|
10887
|
+
}
|
|
10888
|
+
const allNodeX = [...posMap.values()].map((n) => n.x);
|
|
10889
|
+
const avgNodeY = layoutNodes.length > 0 ? layoutNodes.reduce((s, n) => s + n.y, 0) / layoutNodes.length : 0;
|
|
10890
|
+
const avgNodeX = layoutNodes.length > 0 ? layoutNodes.reduce((s, n) => s + n.x, 0) / layoutNodes.length : 0;
|
|
10891
|
+
const edgeYOffsets = new Array(parsed.edges.length).fill(0);
|
|
10892
|
+
const edgeParallelCounts = new Array(parsed.edges.length).fill(1);
|
|
10893
|
+
const parallelGroups = /* @__PURE__ */ new Map();
|
|
10894
|
+
for (let i = 0; i < parsed.edges.length; i++) {
|
|
10895
|
+
const edge = parsed.edges[i];
|
|
10896
|
+
const key = `${edge.source}\0${edge.target}`;
|
|
10897
|
+
parallelGroups.set(key, parallelGroups.get(key) ?? []);
|
|
10898
|
+
parallelGroups.get(key).push(i);
|
|
10899
|
+
}
|
|
10900
|
+
for (const group of parallelGroups.values()) {
|
|
10901
|
+
const capped = group.slice(0, MAX_PARALLEL_EDGES);
|
|
10902
|
+
for (const idx of group.slice(MAX_PARALLEL_EDGES)) {
|
|
10903
|
+
edgeParallelCounts[idx] = 0;
|
|
10904
|
+
}
|
|
10905
|
+
if (capped.length < 2) continue;
|
|
10906
|
+
const effectiveSpacing = Math.min(PARALLEL_SPACING, (NODE_HEIGHT - PARALLEL_EDGE_MARGIN) / (capped.length - 1));
|
|
10907
|
+
for (let j = 0; j < capped.length; j++) {
|
|
10908
|
+
edgeYOffsets[capped[j]] = (j - (capped.length - 1) / 2) * effectiveSpacing;
|
|
10909
|
+
edgeParallelCounts[capped[j]] = capped.length;
|
|
10910
|
+
}
|
|
10911
|
+
}
|
|
10912
|
+
const layoutEdges = [];
|
|
10913
|
+
for (let i = 0; i < parsed.edges.length; i++) {
|
|
10914
|
+
const edge = parsed.edges[i];
|
|
10915
|
+
const src = posMap.get(edge.source);
|
|
10916
|
+
const tgt = posMap.get(edge.target);
|
|
10917
|
+
if (edgeParallelCounts[i] === 0) continue;
|
|
10918
|
+
if (!src || !tgt) continue;
|
|
10919
|
+
const yOffset = edgeYOffsets[i];
|
|
10920
|
+
const parallelCount = edgeParallelCounts[i];
|
|
10816
10921
|
const exitX = src.x + src.width / 2;
|
|
10817
10922
|
const enterX = tgt.x - tgt.width / 2;
|
|
10818
10923
|
const dagreEdge = g.edge(edge.source, edge.target, `e${i}`);
|
|
10819
10924
|
const dagrePoints = dagreEdge?.points ?? [];
|
|
10820
10925
|
const hasIntermediateRank = allNodeX.some((x) => x > src.x + 20 && x < tgt.x - 20);
|
|
10821
10926
|
const step = Math.min((enterX - exitX) * 0.15, 20);
|
|
10822
|
-
const
|
|
10823
|
-
|
|
10824
|
-
|
|
10825
|
-
|
|
10826
|
-
|
|
10827
|
-
|
|
10828
|
-
|
|
10829
|
-
|
|
10830
|
-
|
|
10831
|
-
|
|
10832
|
-
|
|
10833
|
-
|
|
10927
|
+
const isBackEdge = tgt.x < src.x - 5;
|
|
10928
|
+
const isYDisplaced = !isBackEdge && Math.abs(tgt.y - src.y) > NODESEP;
|
|
10929
|
+
let points;
|
|
10930
|
+
if (isBackEdge) {
|
|
10931
|
+
const routeAbove = Math.min(src.y, tgt.y) > avgNodeY;
|
|
10932
|
+
const srcHalfH = src.height / 2;
|
|
10933
|
+
const tgtHalfH = tgt.height / 2;
|
|
10934
|
+
const rawMidX = (src.x + tgt.x) / 2;
|
|
10935
|
+
const spreadDir = avgNodeX < rawMidX ? 1 : -1;
|
|
10936
|
+
const unclamped = Math.abs(src.x - tgt.x) < NODE_WIDTH ? rawMidX + spreadDir * BACK_EDGE_MIN_SPREAD : rawMidX;
|
|
10937
|
+
const midX = Math.min(src.x, Math.max(tgt.x, unclamped));
|
|
10938
|
+
if (routeAbove) {
|
|
10939
|
+
const arcY = Math.min(src.y - srcHalfH, tgt.y - tgtHalfH) - BACK_EDGE_MARGIN;
|
|
10940
|
+
points = [
|
|
10941
|
+
{ x: src.x, y: src.y - srcHalfH },
|
|
10942
|
+
{ x: midX, y: arcY },
|
|
10943
|
+
{ x: tgt.x, y: tgt.y - tgtHalfH }
|
|
10944
|
+
];
|
|
10945
|
+
} else {
|
|
10946
|
+
const arcY = Math.max(src.y + srcHalfH, tgt.y + tgtHalfH) + BACK_EDGE_MARGIN;
|
|
10947
|
+
points = [
|
|
10948
|
+
{ x: src.x, y: src.y + srcHalfH },
|
|
10949
|
+
{ x: midX, y: arcY },
|
|
10950
|
+
{ x: tgt.x, y: tgt.y + tgtHalfH }
|
|
10951
|
+
];
|
|
10952
|
+
}
|
|
10953
|
+
} else if (isYDisplaced) {
|
|
10954
|
+
const exitY = tgt.y > src.y + NODESEP ? src.y + src.height / 2 : src.y - src.height / 2;
|
|
10955
|
+
const midX = Math.max(src.x + 1, (src.x + enterX) / 2);
|
|
10956
|
+
const midY = (exitY + tgt.y) / 2;
|
|
10957
|
+
points = [
|
|
10958
|
+
{ x: src.x, y: exitY },
|
|
10959
|
+
{ x: midX, y: midY },
|
|
10960
|
+
{ x: enterX, y: tgt.y }
|
|
10961
|
+
];
|
|
10962
|
+
} else if (tgt.x > src.x && !hasIntermediateRank) {
|
|
10963
|
+
points = [
|
|
10964
|
+
{ x: exitX, y: src.y },
|
|
10965
|
+
// exits node center — stays pinned
|
|
10966
|
+
{ x: exitX + step, y: src.y + yOffset },
|
|
10967
|
+
// fans out
|
|
10968
|
+
{ x: enterX - step, y: tgt.y + yOffset },
|
|
10969
|
+
// still fanned
|
|
10970
|
+
{ x: enterX, y: tgt.y }
|
|
10971
|
+
// enters node center — stays pinned
|
|
10972
|
+
];
|
|
10973
|
+
} else {
|
|
10974
|
+
points = dagrePoints.length >= 2 ? [
|
|
10975
|
+
{ x: exitX, y: src.y + yOffset },
|
|
10976
|
+
...dagrePoints.slice(1, -1),
|
|
10977
|
+
{ x: enterX, y: tgt.y + yOffset }
|
|
10978
|
+
] : dagrePoints;
|
|
10979
|
+
}
|
|
10980
|
+
layoutEdges.push({
|
|
10834
10981
|
source: edge.source,
|
|
10835
10982
|
target: edge.target,
|
|
10836
10983
|
label: edge.label,
|
|
10837
10984
|
status: edge.status,
|
|
10838
10985
|
lineNumber: edge.lineNumber,
|
|
10839
|
-
points
|
|
10840
|
-
|
|
10841
|
-
|
|
10986
|
+
points,
|
|
10987
|
+
parallelCount
|
|
10988
|
+
});
|
|
10989
|
+
}
|
|
10842
10990
|
const layoutGroups = [];
|
|
10991
|
+
for (const group of originalGroups) {
|
|
10992
|
+
if (collapsedGroupLabels.has(group.label)) {
|
|
10993
|
+
const pos = g.node(group.label);
|
|
10994
|
+
if (!pos) continue;
|
|
10995
|
+
layoutGroups.push({
|
|
10996
|
+
label: group.label,
|
|
10997
|
+
status: collapsedGroupStatuses.get(group.label) ?? null,
|
|
10998
|
+
x: pos.x - pos.width / 2,
|
|
10999
|
+
y: pos.y - pos.height / 2,
|
|
11000
|
+
width: pos.width,
|
|
11001
|
+
height: pos.height,
|
|
11002
|
+
lineNumber: group.lineNumber,
|
|
11003
|
+
collapsed: true
|
|
11004
|
+
});
|
|
11005
|
+
}
|
|
11006
|
+
}
|
|
10843
11007
|
if (parsed.groups.length > 0) {
|
|
10844
11008
|
const nMap = new Map(layoutNodes.map((n) => [n.label, n]));
|
|
10845
11009
|
for (const group of parsed.groups) {
|
|
@@ -10863,7 +11027,8 @@ function layoutInitiativeStatus(parsed) {
|
|
|
10863
11027
|
y: minY - GROUP_PADDING,
|
|
10864
11028
|
width: maxX - minX + GROUP_PADDING * 2,
|
|
10865
11029
|
height: maxY - minY + GROUP_PADDING * 2,
|
|
10866
|
-
lineNumber: group.lineNumber
|
|
11030
|
+
lineNumber: group.lineNumber,
|
|
11031
|
+
collapsed: false
|
|
10867
11032
|
});
|
|
10868
11033
|
}
|
|
10869
11034
|
}
|
|
@@ -10889,7 +11054,7 @@ function layoutInitiativeStatus(parsed) {
|
|
|
10889
11054
|
totalHeight += 40;
|
|
10890
11055
|
return { nodes: layoutNodes, edges: layoutEdges, groups: layoutGroups, width: totalWidth, height: totalHeight };
|
|
10891
11056
|
}
|
|
10892
|
-
var import_dagre4, STATUS_PRIORITY, PHI, NODE_HEIGHT, NODE_WIDTH, GROUP_PADDING, NODESEP, RANKSEP;
|
|
11057
|
+
var import_dagre4, STATUS_PRIORITY, PHI, NODE_HEIGHT, NODE_WIDTH, GROUP_PADDING, NODESEP, RANKSEP, PARALLEL_SPACING, PARALLEL_EDGE_MARGIN, MAX_PARALLEL_EDGES, BACK_EDGE_MARGIN, BACK_EDGE_MIN_SPREAD, CHAR_WIDTH_RATIO, NODE_FONT_SIZE, NODE_TEXT_PADDING;
|
|
10893
11058
|
var init_layout5 = __esm({
|
|
10894
11059
|
"src/initiative-status/layout.ts"() {
|
|
10895
11060
|
"use strict";
|
|
@@ -10901,6 +11066,14 @@ var init_layout5 = __esm({
|
|
|
10901
11066
|
GROUP_PADDING = 20;
|
|
10902
11067
|
NODESEP = 80;
|
|
10903
11068
|
RANKSEP = 160;
|
|
11069
|
+
PARALLEL_SPACING = 16;
|
|
11070
|
+
PARALLEL_EDGE_MARGIN = 12;
|
|
11071
|
+
MAX_PARALLEL_EDGES = 5;
|
|
11072
|
+
BACK_EDGE_MARGIN = 40;
|
|
11073
|
+
BACK_EDGE_MIN_SPREAD = Math.round(NODE_WIDTH * 0.75);
|
|
11074
|
+
CHAR_WIDTH_RATIO = 0.6;
|
|
11075
|
+
NODE_FONT_SIZE = 13;
|
|
11076
|
+
NODE_TEXT_PADDING = 12;
|
|
10904
11077
|
}
|
|
10905
11078
|
});
|
|
10906
11079
|
|
|
@@ -10956,10 +11129,10 @@ function splitCamelCase(word) {
|
|
|
10956
11129
|
return parts.length > 1 ? parts : [word];
|
|
10957
11130
|
}
|
|
10958
11131
|
function fitTextToNode(label, nodeWidth, nodeHeight) {
|
|
10959
|
-
const maxTextWidth = nodeWidth -
|
|
11132
|
+
const maxTextWidth = nodeWidth - NODE_TEXT_PADDING2 * 2;
|
|
10960
11133
|
const lineHeight = 1.3;
|
|
10961
|
-
for (let fontSize =
|
|
10962
|
-
const charWidth2 = fontSize *
|
|
11134
|
+
for (let fontSize = NODE_FONT_SIZE2; fontSize >= MIN_NODE_FONT_SIZE; fontSize--) {
|
|
11135
|
+
const charWidth2 = fontSize * CHAR_WIDTH_RATIO2;
|
|
10963
11136
|
const maxCharsPerLine = Math.floor(maxTextWidth / charWidth2);
|
|
10964
11137
|
const maxLines = Math.floor((nodeHeight - 8) / (fontSize * lineHeight));
|
|
10965
11138
|
if (maxCharsPerLine < 2 || maxLines < 1) continue;
|
|
@@ -11020,8 +11193,8 @@ function fitTextToNode(label, nodeWidth, nodeHeight) {
|
|
|
11020
11193
|
return { lines: hardLines, fontSize };
|
|
11021
11194
|
}
|
|
11022
11195
|
}
|
|
11023
|
-
const charWidth = MIN_NODE_FONT_SIZE *
|
|
11024
|
-
const maxChars = Math.floor((nodeWidth -
|
|
11196
|
+
const charWidth = MIN_NODE_FONT_SIZE * CHAR_WIDTH_RATIO2;
|
|
11197
|
+
const maxChars = Math.floor((nodeWidth - NODE_TEXT_PADDING2 * 2) / charWidth);
|
|
11025
11198
|
const truncated = label.length > maxChars ? label.slice(0, maxChars - 1) + "\u2026" : label;
|
|
11026
11199
|
return { lines: [truncated], fontSize: MIN_NODE_FONT_SIZE };
|
|
11027
11200
|
}
|
|
@@ -11244,21 +11417,27 @@ function renderInitiativeStatus(container, parsed, layout, palette, isDark, onCl
|
|
|
11244
11417
|
const labelMap = /* @__PURE__ */ new Map();
|
|
11245
11418
|
for (const lp of labelPlacements) labelMap.set(lp.edgeIdx, lp);
|
|
11246
11419
|
for (const group of layout.groups) {
|
|
11247
|
-
if (group.
|
|
11248
|
-
|
|
11249
|
-
|
|
11250
|
-
|
|
11251
|
-
|
|
11252
|
-
|
|
11253
|
-
|
|
11254
|
-
|
|
11255
|
-
|
|
11256
|
-
|
|
11257
|
-
|
|
11258
|
-
|
|
11259
|
-
|
|
11260
|
-
|
|
11261
|
-
|
|
11420
|
+
if (group.collapsed) {
|
|
11421
|
+
const fillCol = nodeFill4(group.status, palette, isDark);
|
|
11422
|
+
const strokeCol = nodeStroke4(group.status, palette, isDark);
|
|
11423
|
+
const textCol = nodeTextColor(group.status, palette, isDark);
|
|
11424
|
+
const clipId = `clip-group-${group.lineNumber}`;
|
|
11425
|
+
const groupG = contentG.append("g").attr("class", "is-group is-group-collapsed").attr("data-line-number", String(group.lineNumber)).attr("data-group-toggle", group.label).style("cursor", "pointer");
|
|
11426
|
+
groupG.append("clipPath").attr("id", clipId).append("rect").attr("x", group.x).attr("y", group.y).attr("width", group.width).attr("height", group.height).attr("rx", NODE_RX);
|
|
11427
|
+
groupG.append("rect").attr("x", group.x).attr("y", group.y).attr("width", group.width).attr("height", group.height).attr("rx", NODE_RX).attr("fill", fillCol).attr("stroke", strokeCol).attr("stroke-width", NODE_STROKE_WIDTH5);
|
|
11428
|
+
groupG.append("rect").attr("x", group.x).attr("y", group.y + group.height - COLLAPSE_BAR_HEIGHT3).attr("width", group.width).attr("height", COLLAPSE_BAR_HEIGHT3).attr("fill", strokeCol).attr("clip-path", `url(#${clipId})`).attr("class", "is-collapse-bar");
|
|
11429
|
+
groupG.append("text").attr("x", group.x + group.width / 2).attr("y", group.y + group.height / 2 - COLLAPSE_BAR_HEIGHT3 / 2).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("fill", textCol).attr("font-size", NODE_FONT_SIZE2).attr("font-weight", "bold").attr("font-family", FONT_FAMILY).text(group.label);
|
|
11430
|
+
} else {
|
|
11431
|
+
if (group.width === 0 && group.height === 0) continue;
|
|
11432
|
+
const gx = group.x - GROUP_EXTRA_PADDING;
|
|
11433
|
+
const gy = group.y - GROUP_EXTRA_PADDING - GROUP_LABEL_FONT_SIZE - 4;
|
|
11434
|
+
const gw = group.width + GROUP_EXTRA_PADDING * 2;
|
|
11435
|
+
const gh = group.height + GROUP_EXTRA_PADDING * 2 + GROUP_LABEL_FONT_SIZE + 4;
|
|
11436
|
+
const fillColor = isDark ? palette.surface : palette.bg;
|
|
11437
|
+
const strokeColor = palette.textMuted;
|
|
11438
|
+
const groupG = contentG.append("g").attr("class", "is-group").attr("data-line-number", String(group.lineNumber)).attr("data-group-toggle", group.label).style("cursor", "pointer");
|
|
11439
|
+
groupG.append("rect").attr("x", gx).attr("y", gy).attr("width", gw).attr("height", gh).attr("rx", 6).attr("fill", fillColor).attr("stroke", strokeColor).attr("stroke-opacity", 0.5);
|
|
11440
|
+
groupG.append("text").attr("x", gx + 8).attr("y", gy + GROUP_LABEL_FONT_SIZE + 4).attr("fill", strokeColor).attr("font-size", GROUP_LABEL_FONT_SIZE).attr("font-weight", "bold").attr("opacity", 0.7).attr("class", "is-group-label").text(group.label);
|
|
11262
11441
|
}
|
|
11263
11442
|
}
|
|
11264
11443
|
for (let ei = 0; ei < layout.edges.length; ei++) {
|
|
@@ -11269,7 +11448,7 @@ function renderInitiativeStatus(container, parsed, layout, palette, isDark, onCl
|
|
|
11269
11448
|
const edgeG = contentG.append("g").attr("class", "is-edge-group").attr("data-line-number", String(edge.lineNumber));
|
|
11270
11449
|
const pathD = lineGenerator4(edge.points);
|
|
11271
11450
|
if (pathD) {
|
|
11272
|
-
edgeG.append("path").attr("d", pathD).attr("fill", "none").attr("stroke", "transparent").attr("stroke-width", 16);
|
|
11451
|
+
edgeG.append("path").attr("d", pathD).attr("fill", "none").attr("stroke", "transparent").attr("stroke-width", Math.max(6, Math.round(16 / (edge.parallelCount ?? 1))));
|
|
11273
11452
|
edgeG.append("path").attr("d", pathD).attr("fill", "none").attr("stroke", edgeColor2).attr("stroke-width", EDGE_STROKE_WIDTH5).attr("marker-end", `url(#${markerId})`).attr("class", "is-edge");
|
|
11274
11453
|
}
|
|
11275
11454
|
const lp = labelMap.get(ei);
|
|
@@ -11349,7 +11528,7 @@ function renderInitiativeStatusForExport(content, theme, palette) {
|
|
|
11349
11528
|
document.body.removeChild(container);
|
|
11350
11529
|
}
|
|
11351
11530
|
}
|
|
11352
|
-
var d3Selection6, d3Shape4, DIAGRAM_PADDING6, MAX_SCALE5,
|
|
11531
|
+
var d3Selection6, d3Shape4, DIAGRAM_PADDING6, MAX_SCALE5, NODE_FONT_SIZE2, MIN_NODE_FONT_SIZE, EDGE_LABEL_FONT_SIZE4, EDGE_STROKE_WIDTH5, NODE_STROKE_WIDTH5, NODE_RX, ARROWHEAD_W2, ARROWHEAD_H2, CHAR_WIDTH_RATIO2, NODE_TEXT_PADDING2, SERVICE_RX, GROUP_EXTRA_PADDING, GROUP_LABEL_FONT_SIZE, COLLAPSE_BAR_HEIGHT3, lineGenerator4;
|
|
11353
11532
|
var init_renderer6 = __esm({
|
|
11354
11533
|
"src/initiative-status/renderer.ts"() {
|
|
11355
11534
|
"use strict";
|
|
@@ -11361,19 +11540,20 @@ var init_renderer6 = __esm({
|
|
|
11361
11540
|
init_layout5();
|
|
11362
11541
|
DIAGRAM_PADDING6 = 20;
|
|
11363
11542
|
MAX_SCALE5 = 3;
|
|
11364
|
-
|
|
11543
|
+
NODE_FONT_SIZE2 = 13;
|
|
11365
11544
|
MIN_NODE_FONT_SIZE = 9;
|
|
11366
11545
|
EDGE_LABEL_FONT_SIZE4 = 11;
|
|
11367
11546
|
EDGE_STROKE_WIDTH5 = 2;
|
|
11368
11547
|
NODE_STROKE_WIDTH5 = 2;
|
|
11369
11548
|
NODE_RX = 8;
|
|
11370
|
-
ARROWHEAD_W2 =
|
|
11371
|
-
ARROWHEAD_H2 =
|
|
11372
|
-
|
|
11373
|
-
|
|
11549
|
+
ARROWHEAD_W2 = 5;
|
|
11550
|
+
ARROWHEAD_H2 = 4;
|
|
11551
|
+
CHAR_WIDTH_RATIO2 = 0.6;
|
|
11552
|
+
NODE_TEXT_PADDING2 = 12;
|
|
11374
11553
|
SERVICE_RX = 10;
|
|
11375
11554
|
GROUP_EXTRA_PADDING = 8;
|
|
11376
11555
|
GROUP_LABEL_FONT_SIZE = 11;
|
|
11556
|
+
COLLAPSE_BAR_HEIGHT3 = 6;
|
|
11377
11557
|
lineGenerator4 = d3Shape4.line().x((d) => d.x).y((d) => d.y).curve(d3Shape4.curveMonotoneX);
|
|
11378
11558
|
}
|
|
11379
11559
|
});
|
|
@@ -14149,7 +14329,7 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
|
|
|
14149
14329
|
});
|
|
14150
14330
|
}
|
|
14151
14331
|
renderNodeShape2(nodeG, node, palette, isDark, endTerminalIds, colorOff);
|
|
14152
|
-
nodeG.append("text").attr("x", 0).attr("y", 0).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("fill", palette.text).attr("font-size",
|
|
14332
|
+
nodeG.append("text").attr("x", 0).attr("y", 0).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("fill", palette.text).attr("font-size", NODE_FONT_SIZE3).text(node.label);
|
|
14153
14333
|
}
|
|
14154
14334
|
}
|
|
14155
14335
|
function renderFlowchartForExport(content, theme, palette) {
|
|
@@ -14187,7 +14367,7 @@ function renderFlowchartForExport(content, theme, palette) {
|
|
|
14187
14367
|
document.body.removeChild(container);
|
|
14188
14368
|
}
|
|
14189
14369
|
}
|
|
14190
|
-
var d3Selection8, d3Shape6, DIAGRAM_PADDING8, MAX_SCALE7,
|
|
14370
|
+
var d3Selection8, d3Shape6, DIAGRAM_PADDING8, MAX_SCALE7, NODE_FONT_SIZE3, EDGE_LABEL_FONT_SIZE6, EDGE_STROKE_WIDTH7, NODE_STROKE_WIDTH7, ARROWHEAD_W3, ARROWHEAD_H3, IO_SKEW, SUBROUTINE_INSET, DOC_WAVE_HEIGHT, lineGenerator6;
|
|
14191
14371
|
var init_flowchart_renderer = __esm({
|
|
14192
14372
|
"src/graph/flowchart-renderer.ts"() {
|
|
14193
14373
|
"use strict";
|
|
@@ -14199,7 +14379,7 @@ var init_flowchart_renderer = __esm({
|
|
|
14199
14379
|
init_layout7();
|
|
14200
14380
|
DIAGRAM_PADDING8 = 20;
|
|
14201
14381
|
MAX_SCALE7 = 3;
|
|
14202
|
-
|
|
14382
|
+
NODE_FONT_SIZE3 = 13;
|
|
14203
14383
|
EDGE_LABEL_FONT_SIZE6 = 11;
|
|
14204
14384
|
EDGE_STROKE_WIDTH7 = 1.5;
|
|
14205
14385
|
NODE_STROKE_WIDTH7 = 1.5;
|
|
@@ -14387,23 +14567,26 @@ function collapseGroups(parsed, collapsedIds, defaultLatencyMs = 0, defaultUptim
|
|
|
14387
14567
|
if (!collapsedIds.has(group.id)) continue;
|
|
14388
14568
|
const children = groupChildren.get(group.id) ?? [];
|
|
14389
14569
|
if (children.length === 0) continue;
|
|
14390
|
-
let totalLatency = 0;
|
|
14391
14570
|
let minEffectiveCapacity = Infinity;
|
|
14392
14571
|
let hasMaxRps = false;
|
|
14393
14572
|
let composedUptime = 1;
|
|
14394
14573
|
const behaviorProps = [];
|
|
14395
14574
|
const perChildCapacities = [];
|
|
14575
|
+
const childIdSet = new Set(children.map((c) => c.id));
|
|
14576
|
+
const childLatencies = /* @__PURE__ */ new Map();
|
|
14396
14577
|
for (const child of children) {
|
|
14397
14578
|
const latencyProp = child.properties.find((p) => p.key === "latency-ms");
|
|
14398
14579
|
const childIsServerless = child.properties.some((p) => p.key === "concurrency");
|
|
14580
|
+
let childLat;
|
|
14399
14581
|
if (childIsServerless) {
|
|
14400
14582
|
const durationProp = child.properties.find((p) => p.key === "duration-ms");
|
|
14401
|
-
|
|
14583
|
+
childLat = durationProp ? typeof durationProp.value === "number" ? durationProp.value : parseFloat(String(durationProp.value)) || 100 : 100;
|
|
14402
14584
|
} else if (latencyProp) {
|
|
14403
|
-
|
|
14585
|
+
childLat = typeof latencyProp.value === "number" ? latencyProp.value : parseFloat(String(latencyProp.value)) || 0;
|
|
14404
14586
|
} else {
|
|
14405
|
-
|
|
14587
|
+
childLat = defaultLatencyMs;
|
|
14406
14588
|
}
|
|
14589
|
+
childLatencies.set(child.id, childLat);
|
|
14407
14590
|
const maxRps = child.properties.find((p) => p.key === "max-rps");
|
|
14408
14591
|
if (maxRps) {
|
|
14409
14592
|
hasMaxRps = true;
|
|
@@ -14434,6 +14617,59 @@ function collapseGroups(parsed, collapsedIds, defaultLatencyMs = 0, defaultUptim
|
|
|
14434
14617
|
}
|
|
14435
14618
|
}
|
|
14436
14619
|
}
|
|
14620
|
+
const entryIds = /* @__PURE__ */ new Set();
|
|
14621
|
+
const exitIds = /* @__PURE__ */ new Set();
|
|
14622
|
+
for (const edge of inboundEdges) {
|
|
14623
|
+
if (childIdSet.has(edge.targetId)) entryIds.add(edge.targetId);
|
|
14624
|
+
}
|
|
14625
|
+
for (const edge of outboundEdges) {
|
|
14626
|
+
if (childIdSet.has(edge.sourceId)) exitIds.add(edge.sourceId);
|
|
14627
|
+
}
|
|
14628
|
+
for (const edge of crossGroupEdges) {
|
|
14629
|
+
if (childIdSet.has(edge.sourceId)) exitIds.add(edge.sourceId);
|
|
14630
|
+
if (childIdSet.has(edge.targetId)) entryIds.add(edge.targetId);
|
|
14631
|
+
}
|
|
14632
|
+
const fwdAdj = /* @__PURE__ */ new Map();
|
|
14633
|
+
for (const edge of internalEdges) {
|
|
14634
|
+
if (!childIdSet.has(edge.sourceId) || !childIdSet.has(edge.targetId)) continue;
|
|
14635
|
+
const list = fwdAdj.get(edge.sourceId) ?? [];
|
|
14636
|
+
list.push(edge.targetId);
|
|
14637
|
+
fwdAdj.set(edge.sourceId, list);
|
|
14638
|
+
}
|
|
14639
|
+
const topoOrder = [];
|
|
14640
|
+
const tsVisited = /* @__PURE__ */ new Set();
|
|
14641
|
+
const dfsTopoSort = (id) => {
|
|
14642
|
+
if (tsVisited.has(id)) return;
|
|
14643
|
+
tsVisited.add(id);
|
|
14644
|
+
for (const next of fwdAdj.get(id) ?? []) dfsTopoSort(next);
|
|
14645
|
+
topoOrder.unshift(id);
|
|
14646
|
+
};
|
|
14647
|
+
for (const child of children) dfsTopoSort(child.id);
|
|
14648
|
+
const dist = /* @__PURE__ */ new Map();
|
|
14649
|
+
for (const child of children) {
|
|
14650
|
+
dist.set(child.id, entryIds.has(child.id) ? childLatencies.get(child.id) ?? 0 : -Infinity);
|
|
14651
|
+
}
|
|
14652
|
+
for (const nodeId3 of topoOrder) {
|
|
14653
|
+
const curDist = dist.get(nodeId3) ?? -Infinity;
|
|
14654
|
+
if (curDist === -Infinity) continue;
|
|
14655
|
+
for (const nextId of fwdAdj.get(nodeId3) ?? []) {
|
|
14656
|
+
const newDist = curDist + (childLatencies.get(nextId) ?? 0);
|
|
14657
|
+
if (newDist > (dist.get(nextId) ?? -Infinity)) dist.set(nextId, newDist);
|
|
14658
|
+
}
|
|
14659
|
+
}
|
|
14660
|
+
let totalLatency = 0;
|
|
14661
|
+
if (exitIds.size > 0) {
|
|
14662
|
+
for (const id of exitIds) {
|
|
14663
|
+
const d = dist.get(id);
|
|
14664
|
+
if (d !== void 0 && d > -Infinity && d > totalLatency) totalLatency = d;
|
|
14665
|
+
}
|
|
14666
|
+
} else if (entryIds.size > 0) {
|
|
14667
|
+
for (const [, d] of dist) {
|
|
14668
|
+
if (d > 0 && d > totalLatency) totalLatency = d;
|
|
14669
|
+
}
|
|
14670
|
+
} else {
|
|
14671
|
+
for (const [, lat] of childLatencies) totalLatency += lat;
|
|
14672
|
+
}
|
|
14437
14673
|
const props = [];
|
|
14438
14674
|
if (totalLatency > 0) props.push({ key: "latency-ms", value: totalLatency, lineNumber: group.lineNumber });
|
|
14439
14675
|
const groupInstances = typeof group.instances === "number" ? group.instances : 1;
|
|
@@ -14666,8 +14902,10 @@ function computeInfra(parsed, params = {}) {
|
|
|
14666
14902
|
const resolved = resolveSplits(outbound, diagnostics);
|
|
14667
14903
|
for (const { edge, split } of resolved) {
|
|
14668
14904
|
const edgeRps = outboundRps * (split / 100);
|
|
14905
|
+
const fanout = edge.fanout != null && edge.fanout >= 1 ? edge.fanout : 1;
|
|
14906
|
+
const fanoutedRps = edgeRps * fanout;
|
|
14669
14907
|
const edgeKey = `${edge.sourceId}->${edge.targetId}`;
|
|
14670
|
-
computedEdgeRps.set(edgeKey,
|
|
14908
|
+
computedEdgeRps.set(edgeKey, fanoutedRps);
|
|
14671
14909
|
let targetIds;
|
|
14672
14910
|
const groupChildren = groupChildMap.get(edge.targetId);
|
|
14673
14911
|
if (groupChildren && groupChildren.length > 0) {
|
|
@@ -14676,7 +14914,7 @@ function computeInfra(parsed, params = {}) {
|
|
|
14676
14914
|
targetIds = [edge.targetId];
|
|
14677
14915
|
}
|
|
14678
14916
|
for (const targetId of targetIds) {
|
|
14679
|
-
const perTarget =
|
|
14917
|
+
const perTarget = fanoutedRps / targetIds.length;
|
|
14680
14918
|
const existing = computedRps.get(targetId) ?? 0;
|
|
14681
14919
|
computedRps.set(targetId, existing + perTarget);
|
|
14682
14920
|
const prevLatency = computedLatency.get(targetId) ?? 0;
|
|
@@ -14772,6 +15010,7 @@ function computeInfra(parsed, params = {}) {
|
|
|
14772
15010
|
const resolved = resolveSplits(outbound, []);
|
|
14773
15011
|
const paths = [];
|
|
14774
15012
|
for (const { edge, split } of resolved) {
|
|
15013
|
+
const fanout = edge.fanout != null && edge.fanout >= 1 ? edge.fanout : 1;
|
|
14775
15014
|
const groupChildren = groupChildMap.get(edge.targetId);
|
|
14776
15015
|
const targetIds = groupChildren && groupChildren.length > 0 ? groupChildren : [edge.targetId];
|
|
14777
15016
|
for (const targetId of targetIds) {
|
|
@@ -14782,20 +15021,20 @@ function computeInfra(parsed, params = {}) {
|
|
|
14782
15021
|
latency: nodeLatency + cp.latency,
|
|
14783
15022
|
uptime: nodeUptimeFrac * cp.uptime,
|
|
14784
15023
|
availability: nodeAvail * cp.availability,
|
|
14785
|
-
weight: cp.weight * (split / 100) / targetIds.length * 0.95
|
|
15024
|
+
weight: cp.weight * (split / 100) / targetIds.length * fanout * 0.95
|
|
14786
15025
|
});
|
|
14787
15026
|
paths.push({
|
|
14788
15027
|
latency: coldLatency + cp.latency,
|
|
14789
15028
|
uptime: nodeUptimeFrac * cp.uptime,
|
|
14790
15029
|
availability: nodeAvail * cp.availability,
|
|
14791
|
-
weight: cp.weight * (split / 100) / targetIds.length * 0.05
|
|
15030
|
+
weight: cp.weight * (split / 100) / targetIds.length * fanout * 0.05
|
|
14792
15031
|
});
|
|
14793
15032
|
} else {
|
|
14794
15033
|
paths.push({
|
|
14795
15034
|
latency: nodeLatency + cp.latency,
|
|
14796
15035
|
uptime: nodeUptimeFrac * cp.uptime,
|
|
14797
15036
|
availability: nodeAvail * cp.availability,
|
|
14798
|
-
weight: cp.weight * (split / 100) / targetIds.length
|
|
15037
|
+
weight: cp.weight * (split / 100) / targetIds.length * fanout
|
|
14799
15038
|
});
|
|
14800
15039
|
}
|
|
14801
15040
|
}
|
|
@@ -14950,6 +15189,7 @@ function computeInfra(parsed, params = {}) {
|
|
|
14950
15189
|
queueMetrics,
|
|
14951
15190
|
properties: node.properties,
|
|
14952
15191
|
tags: node.tags,
|
|
15192
|
+
description: node.description,
|
|
14953
15193
|
lineNumber: node.lineNumber
|
|
14954
15194
|
};
|
|
14955
15195
|
});
|
|
@@ -14974,6 +15214,7 @@ function computeInfra(parsed, params = {}) {
|
|
|
14974
15214
|
label: edge.label,
|
|
14975
15215
|
computedRps: rps,
|
|
14976
15216
|
split: resolvedSplit,
|
|
15217
|
+
fanout: edge.fanout,
|
|
14977
15218
|
lineNumber: edge.lineNumber
|
|
14978
15219
|
};
|
|
14979
15220
|
});
|
|
@@ -15000,7 +15241,8 @@ var init_compute = __esm({
|
|
|
15000
15241
|
// src/infra/layout.ts
|
|
15001
15242
|
var layout_exports8 = {};
|
|
15002
15243
|
__export(layout_exports8, {
|
|
15003
|
-
layoutInfra: () => layoutInfra
|
|
15244
|
+
layoutInfra: () => layoutInfra,
|
|
15245
|
+
separateGroups: () => separateGroups
|
|
15004
15246
|
});
|
|
15005
15247
|
function countDisplayProps(node, expanded, options) {
|
|
15006
15248
|
if (!expanded) return 0;
|
|
@@ -15066,7 +15308,7 @@ function computeNodeWidth2(node, expanded, options) {
|
|
|
15066
15308
|
if (expanded) {
|
|
15067
15309
|
allKeys.push("p50", "p90", "p99");
|
|
15068
15310
|
} else {
|
|
15069
|
-
allKeys.push("
|
|
15311
|
+
allKeys.push("p90");
|
|
15070
15312
|
}
|
|
15071
15313
|
}
|
|
15072
15314
|
if (node.computedUptime < 1) {
|
|
@@ -15108,13 +15350,21 @@ function computeNodeWidth2(node, expanded, options) {
|
|
|
15108
15350
|
}
|
|
15109
15351
|
if (computedRows > 0) {
|
|
15110
15352
|
const perc = node.computedLatencyPercentiles;
|
|
15111
|
-
const msValues = expanded ? [perc.p50, perc.p90, perc.p99] : [perc.
|
|
15353
|
+
const msValues = expanded ? [perc.p50, perc.p90, perc.p99] : [perc.p90];
|
|
15112
15354
|
for (const ms of msValues) {
|
|
15113
15355
|
if (ms > 0) {
|
|
15114
15356
|
const valLen = formatMs(ms).length;
|
|
15115
15357
|
maxRowWidth = Math.max(maxRowWidth, (maxKeyLen + 2 + valLen) * META_CHAR_WIDTH3);
|
|
15116
15358
|
}
|
|
15117
15359
|
}
|
|
15360
|
+
if (perc.p90 > 0) {
|
|
15361
|
+
const rawThreshold = node.properties.find((p) => p.key === "slo-p90-latency-ms")?.value ?? options?.["slo-p90-latency-ms"];
|
|
15362
|
+
const threshold = rawThreshold != null ? parseFloat(String(rawThreshold)) : NaN;
|
|
15363
|
+
if (!isNaN(threshold) && threshold > 0) {
|
|
15364
|
+
const combinedVal = `${formatMs(perc.p90)} / ${formatMs(threshold)}`;
|
|
15365
|
+
maxRowWidth = Math.max(maxRowWidth, (maxKeyLen + 2 + combinedVal.length) * META_CHAR_WIDTH3);
|
|
15366
|
+
}
|
|
15367
|
+
}
|
|
15118
15368
|
if (node.computedUptime < 1) {
|
|
15119
15369
|
const valLen = formatUptime(node.computedUptime).length;
|
|
15120
15370
|
maxRowWidth = Math.max(maxRowWidth, (maxKeyLen + 2 + valLen) * META_CHAR_WIDTH3);
|
|
@@ -15127,21 +15377,26 @@ function computeNodeWidth2(node, expanded, options) {
|
|
|
15127
15377
|
maxRowWidth = Math.max(maxRowWidth, "CB: OPEN".length * META_CHAR_WIDTH3 + 8);
|
|
15128
15378
|
}
|
|
15129
15379
|
}
|
|
15130
|
-
|
|
15380
|
+
const DESC_MAX_CHARS2 = 120;
|
|
15381
|
+
const descText = expanded && node.description && !node.isEdge ? node.description : "";
|
|
15382
|
+
const descTruncated = descText.length > DESC_MAX_CHARS2 ? descText.slice(0, DESC_MAX_CHARS2 - 1) + "\u2026" : descText;
|
|
15383
|
+
const descWidth = descTruncated.length > 0 ? descTruncated.length * META_CHAR_WIDTH3 + PADDING_X3 : 0;
|
|
15384
|
+
return Math.max(MIN_NODE_WIDTH2, labelWidth, maxRowWidth + 20, descWidth);
|
|
15131
15385
|
}
|
|
15132
15386
|
function computeNodeHeight2(node, expanded, options) {
|
|
15133
15387
|
const propCount = countDisplayProps(node, expanded, options);
|
|
15134
15388
|
const computedCount = countComputedRows(node, expanded);
|
|
15135
15389
|
const hasRps = node.computedRps > 0;
|
|
15136
|
-
|
|
15137
|
-
|
|
15390
|
+
const descH = expanded && node.description && !node.isEdge ? META_LINE_HEIGHT7 : 0;
|
|
15391
|
+
if (propCount === 0 && computedCount === 0 && !hasRps) return NODE_HEADER_HEIGHT + descH + NODE_PAD_BOTTOM;
|
|
15392
|
+
let h = NODE_HEADER_HEIGHT + descH + NODE_SEPARATOR_GAP;
|
|
15138
15393
|
const computedSectionCount = (hasRps ? 1 : 0) + computedCount;
|
|
15139
15394
|
h += computedSectionCount * META_LINE_HEIGHT7;
|
|
15140
15395
|
if (computedSectionCount > 0 && propCount > 0) h += NODE_SEPARATOR_GAP;
|
|
15141
15396
|
h += propCount * META_LINE_HEIGHT7;
|
|
15142
15397
|
if (hasRoles(node)) h += ROLE_DOT_ROW;
|
|
15143
15398
|
h += NODE_PAD_BOTTOM;
|
|
15144
|
-
if (node.id.startsWith("[")) h +=
|
|
15399
|
+
if (node.id.startsWith("[")) h += COLLAPSE_BAR_HEIGHT4;
|
|
15145
15400
|
return h;
|
|
15146
15401
|
}
|
|
15147
15402
|
function formatRps(rps) {
|
|
@@ -15168,7 +15423,36 @@ function formatUptime(fraction) {
|
|
|
15168
15423
|
if (pct >= 99) return `${pct.toFixed(1)}%`;
|
|
15169
15424
|
return `${pct.toFixed(1)}%`;
|
|
15170
15425
|
}
|
|
15171
|
-
function
|
|
15426
|
+
function separateGroups(groups, nodes, isLR, maxIterations = 20) {
|
|
15427
|
+
for (let iter = 0; iter < maxIterations; iter++) {
|
|
15428
|
+
let anyOverlap = false;
|
|
15429
|
+
for (let i = 0; i < groups.length; i++) {
|
|
15430
|
+
for (let j = i + 1; j < groups.length; j++) {
|
|
15431
|
+
const ga = groups[i];
|
|
15432
|
+
const gb = groups[j];
|
|
15433
|
+
const primaryOverlap = isLR ? Math.min(ga.y + ga.height, gb.y + gb.height) - Math.max(ga.y, gb.y) : Math.min(ga.x + ga.width, gb.x + gb.width) - Math.max(ga.x, gb.x);
|
|
15434
|
+
if (primaryOverlap <= 0) continue;
|
|
15435
|
+
const crossOverlap = isLR ? Math.min(ga.x + ga.width, gb.x + gb.width) - Math.max(ga.x, gb.x) : Math.min(ga.y + ga.height, gb.y + gb.height) - Math.max(ga.y, gb.y);
|
|
15436
|
+
if (crossOverlap <= 0) continue;
|
|
15437
|
+
anyOverlap = true;
|
|
15438
|
+
const shift = primaryOverlap + GROUP_GAP;
|
|
15439
|
+
const aCenter = isLR ? ga.y + ga.height / 2 : ga.x + ga.width / 2;
|
|
15440
|
+
const bCenter = isLR ? gb.y + gb.height / 2 : gb.x + gb.width / 2;
|
|
15441
|
+
const groupToShift = aCenter <= bCenter ? gb : ga;
|
|
15442
|
+
if (isLR) groupToShift.y += shift;
|
|
15443
|
+
else groupToShift.x += shift;
|
|
15444
|
+
for (const node of nodes) {
|
|
15445
|
+
if (node.groupId === groupToShift.id) {
|
|
15446
|
+
if (isLR) node.y += shift;
|
|
15447
|
+
else node.x += shift;
|
|
15448
|
+
}
|
|
15449
|
+
}
|
|
15450
|
+
}
|
|
15451
|
+
}
|
|
15452
|
+
if (!anyOverlap) break;
|
|
15453
|
+
}
|
|
15454
|
+
}
|
|
15455
|
+
function layoutInfra(computed, expandedNodeIds, collapsedNodes) {
|
|
15172
15456
|
if (computed.nodes.length === 0) {
|
|
15173
15457
|
return { nodes: [], edges: [], groups: [], options: {}, width: 0, height: 0 };
|
|
15174
15458
|
}
|
|
@@ -15190,7 +15474,7 @@ function layoutInfra(computed, selectedNodeId, collapsedNodes) {
|
|
|
15190
15474
|
const heightMap = /* @__PURE__ */ new Map();
|
|
15191
15475
|
for (const node of computed.nodes) {
|
|
15192
15476
|
const isNodeCollapsed = collapsedNodes?.has(node.id) ?? false;
|
|
15193
|
-
const expanded = !isNodeCollapsed && node.id
|
|
15477
|
+
const expanded = !isNodeCollapsed && (expandedNodeIds?.has(node.id) ?? false);
|
|
15194
15478
|
const width = computeNodeWidth2(node, expanded, computed.options);
|
|
15195
15479
|
const height = isNodeCollapsed ? NODE_HEADER_HEIGHT + NODE_PAD_BOTTOM : computeNodeHeight2(node, expanded, computed.options);
|
|
15196
15480
|
widthMap.set(node.id, width);
|
|
@@ -15251,6 +15535,7 @@ function layoutInfra(computed, selectedNodeId, collapsedNodes) {
|
|
|
15251
15535
|
queueMetrics: node.queueMetrics,
|
|
15252
15536
|
properties: node.properties,
|
|
15253
15537
|
tags: node.tags,
|
|
15538
|
+
description: node.description,
|
|
15254
15539
|
lineNumber: node.lineNumber
|
|
15255
15540
|
};
|
|
15256
15541
|
});
|
|
@@ -15265,6 +15550,7 @@ function layoutInfra(computed, selectedNodeId, collapsedNodes) {
|
|
|
15265
15550
|
label: edge.label,
|
|
15266
15551
|
computedRps: edge.computedRps,
|
|
15267
15552
|
split: edge.split,
|
|
15553
|
+
fanout: edge.fanout,
|
|
15268
15554
|
points: edgeData?.points ?? [],
|
|
15269
15555
|
lineNumber: edge.lineNumber
|
|
15270
15556
|
});
|
|
@@ -15276,6 +15562,7 @@ function layoutInfra(computed, selectedNodeId, collapsedNodes) {
|
|
|
15276
15562
|
label: edge.label,
|
|
15277
15563
|
computedRps: edge.computedRps,
|
|
15278
15564
|
split: edge.split,
|
|
15565
|
+
fanout: edge.fanout,
|
|
15279
15566
|
points: edgeData?.points ?? [],
|
|
15280
15567
|
lineNumber: edge.lineNumber
|
|
15281
15568
|
});
|
|
@@ -15317,6 +15604,7 @@ function layoutInfra(computed, selectedNodeId, collapsedNodes) {
|
|
|
15317
15604
|
lineNumber: group.lineNumber
|
|
15318
15605
|
};
|
|
15319
15606
|
});
|
|
15607
|
+
separateGroups(layoutGroups, layoutNodes, isLR);
|
|
15320
15608
|
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
15321
15609
|
for (const node of layoutNodes) {
|
|
15322
15610
|
const left = node.x - node.width / 2;
|
|
@@ -15378,7 +15666,7 @@ function layoutInfra(computed, selectedNodeId, collapsedNodes) {
|
|
|
15378
15666
|
height: totalHeight
|
|
15379
15667
|
};
|
|
15380
15668
|
}
|
|
15381
|
-
var import_dagre7, MIN_NODE_WIDTH2, NODE_HEADER_HEIGHT, META_LINE_HEIGHT7, NODE_SEPARATOR_GAP, NODE_PAD_BOTTOM, ROLE_DOT_ROW,
|
|
15669
|
+
var import_dagre7, MIN_NODE_WIDTH2, NODE_HEADER_HEIGHT, META_LINE_HEIGHT7, NODE_SEPARATOR_GAP, NODE_PAD_BOTTOM, ROLE_DOT_ROW, COLLAPSE_BAR_HEIGHT4, CHAR_WIDTH6, META_CHAR_WIDTH3, PADDING_X3, GROUP_PADDING3, GROUP_HEADER_HEIGHT, EDGE_MARGIN, DISPLAY_KEYS, DISPLAY_NAMES, GROUP_GAP;
|
|
15382
15670
|
var init_layout8 = __esm({
|
|
15383
15671
|
"src/infra/layout.ts"() {
|
|
15384
15672
|
"use strict";
|
|
@@ -15389,7 +15677,7 @@ var init_layout8 = __esm({
|
|
|
15389
15677
|
NODE_SEPARATOR_GAP = 4;
|
|
15390
15678
|
NODE_PAD_BOTTOM = 10;
|
|
15391
15679
|
ROLE_DOT_ROW = 12;
|
|
15392
|
-
|
|
15680
|
+
COLLAPSE_BAR_HEIGHT4 = 6;
|
|
15393
15681
|
CHAR_WIDTH6 = 7;
|
|
15394
15682
|
META_CHAR_WIDTH3 = 6;
|
|
15395
15683
|
PADDING_X3 = 24;
|
|
@@ -15417,11 +15705,11 @@ var init_layout8 = __esm({
|
|
|
15417
15705
|
DISPLAY_NAMES = {
|
|
15418
15706
|
"cache-hit": "cache hit",
|
|
15419
15707
|
"firewall-block": "fw block",
|
|
15420
|
-
"ratelimit-rps": "rate limit",
|
|
15708
|
+
"ratelimit-rps": "rate limit RPS",
|
|
15421
15709
|
"latency-ms": "latency",
|
|
15422
15710
|
"uptime": "uptime",
|
|
15423
15711
|
"instances": "instances",
|
|
15424
|
-
"max-rps": "
|
|
15712
|
+
"max-rps": "max RPS",
|
|
15425
15713
|
"cb-error-threshold": "CB error",
|
|
15426
15714
|
"cb-latency-threshold-ms": "CB latency",
|
|
15427
15715
|
"concurrency": "concurrency",
|
|
@@ -15432,6 +15720,7 @@ var init_layout8 = __esm({
|
|
|
15432
15720
|
"retention-hours": "retention",
|
|
15433
15721
|
"partitions": "partitions"
|
|
15434
15722
|
};
|
|
15723
|
+
GROUP_GAP = 24;
|
|
15435
15724
|
}
|
|
15436
15725
|
});
|
|
15437
15726
|
|
|
@@ -15446,6 +15735,13 @@ function inferRoles(properties) {
|
|
|
15446
15735
|
}
|
|
15447
15736
|
return roles;
|
|
15448
15737
|
}
|
|
15738
|
+
function collectFanoutSourceIds(edges) {
|
|
15739
|
+
const ids = /* @__PURE__ */ new Set();
|
|
15740
|
+
for (const e of edges) {
|
|
15741
|
+
if (e.fanout != null) ids.add(e.sourceId);
|
|
15742
|
+
}
|
|
15743
|
+
return ids;
|
|
15744
|
+
}
|
|
15449
15745
|
function collectDiagramRoles(allProperties) {
|
|
15450
15746
|
const seen = /* @__PURE__ */ new Set();
|
|
15451
15747
|
const roles = [];
|
|
@@ -15459,7 +15755,7 @@ function collectDiagramRoles(allProperties) {
|
|
|
15459
15755
|
}
|
|
15460
15756
|
return roles;
|
|
15461
15757
|
}
|
|
15462
|
-
var ROLE_RULES;
|
|
15758
|
+
var ROLE_RULES, FANOUT_ROLE;
|
|
15463
15759
|
var init_roles = __esm({
|
|
15464
15760
|
"src/infra/roles.ts"() {
|
|
15465
15761
|
"use strict";
|
|
@@ -15472,6 +15768,7 @@ var init_roles = __esm({
|
|
|
15472
15768
|
{ keys: ["concurrency"], role: { name: "Serverless", color: "#06b6d4" } },
|
|
15473
15769
|
{ keys: ["buffer"], role: { name: "Queue", color: "#8b5cf6" } }
|
|
15474
15770
|
];
|
|
15771
|
+
FANOUT_ROLE = { name: "Fan-Out", color: "#f97316" };
|
|
15475
15772
|
}
|
|
15476
15773
|
});
|
|
15477
15774
|
|
|
@@ -15482,6 +15779,20 @@ __export(renderer_exports8, {
|
|
|
15482
15779
|
parseAndLayoutInfra: () => parseAndLayoutInfra,
|
|
15483
15780
|
renderInfra: () => renderInfra
|
|
15484
15781
|
});
|
|
15782
|
+
function resolveNodeSlo(node, diagramOptions) {
|
|
15783
|
+
const nodeProp = (key) => node.properties.find((p) => p.key === key);
|
|
15784
|
+
const availRaw = nodeProp("slo-availability")?.value ?? diagramOptions["slo-availability"];
|
|
15785
|
+
const latencyRaw = nodeProp("slo-p90-latency-ms")?.value ?? diagramOptions["slo-p90-latency-ms"];
|
|
15786
|
+
const marginRaw = nodeProp("slo-warning-margin")?.value ?? diagramOptions["slo-warning-margin"];
|
|
15787
|
+
const availParsed = availRaw != null ? parseFloat(String(availRaw).replace("%", "")) / 100 : NaN;
|
|
15788
|
+
const availThreshold = !isNaN(availParsed) ? availParsed : null;
|
|
15789
|
+
const latencyParsed = latencyRaw != null ? parseFloat(String(latencyRaw)) : NaN;
|
|
15790
|
+
const latencyP90 = !isNaN(latencyParsed) ? latencyParsed : null;
|
|
15791
|
+
const marginParsed = marginRaw != null ? parseFloat(String(marginRaw).replace("%", "")) / 100 : NaN;
|
|
15792
|
+
const warningMargin = !isNaN(marginParsed) ? marginParsed : 0.05;
|
|
15793
|
+
if (availThreshold == null && latencyP90 == null) return null;
|
|
15794
|
+
return { availThreshold, latencyP90, warningMargin };
|
|
15795
|
+
}
|
|
15485
15796
|
function nodeBorderPoint(node, target) {
|
|
15486
15797
|
const hw = node.width / 2;
|
|
15487
15798
|
const hh = node.height / 2;
|
|
@@ -15518,7 +15829,17 @@ function isWarning(node) {
|
|
|
15518
15829
|
const cap = Number(maxRps.value) * node.computedInstances;
|
|
15519
15830
|
return cap > 0 && node.computedRps / cap > 0.7;
|
|
15520
15831
|
}
|
|
15521
|
-
function
|
|
15832
|
+
function truncateDesc(text) {
|
|
15833
|
+
if (text.length <= DESC_MAX_CHARS) return text;
|
|
15834
|
+
return text.slice(0, DESC_MAX_CHARS - 1) + "\u2026";
|
|
15835
|
+
}
|
|
15836
|
+
function sloLatencyColor(p90, slo) {
|
|
15837
|
+
const t = slo.latencyP90 ?? 0;
|
|
15838
|
+
if (t === 0) return COLOR_HEALTHY;
|
|
15839
|
+
const m = slo.warningMargin;
|
|
15840
|
+
return p90 > t ? COLOR_OVERLOADED : p90 > t * (1 - m) ? COLOR_WARNING : COLOR_HEALTHY;
|
|
15841
|
+
}
|
|
15842
|
+
function getComputedRows(node, expanded, slo) {
|
|
15522
15843
|
const rows = [];
|
|
15523
15844
|
if (node.computedConcurrentInvocations > 0) {
|
|
15524
15845
|
const concurrency = getNodeNumProp(node, "concurrency", 0);
|
|
@@ -15532,9 +15853,23 @@ function getComputedRows(node, expanded) {
|
|
|
15532
15853
|
if (p.p50 > 0 || p.p90 > 0 || p.p99 > 0) {
|
|
15533
15854
|
if (expanded) {
|
|
15534
15855
|
rows.push({ key: "p50", value: formatMsShort(p.p50) });
|
|
15535
|
-
|
|
15856
|
+
if (slo?.latencyP90 != null) {
|
|
15857
|
+
const color = sloLatencyColor(p.p90, slo);
|
|
15858
|
+
const p90Value = color !== COLOR_HEALTHY ? `${formatMsShort(p.p90)} / ${formatMsShort(slo.latencyP90)}` : formatMsShort(p.p90);
|
|
15859
|
+
rows.push({ key: "p90", value: p90Value, color, inverted: color !== COLOR_HEALTHY });
|
|
15860
|
+
} else {
|
|
15861
|
+
rows.push({ key: "p90", value: formatMsShort(p.p90) });
|
|
15862
|
+
}
|
|
15863
|
+
rows.push({ key: "p99", value: formatMsShort(p.p99) });
|
|
15864
|
+
} else if (p.p90 > 0) {
|
|
15865
|
+
if (slo?.latencyP90 != null) {
|
|
15866
|
+
const color = sloLatencyColor(p.p90, slo);
|
|
15867
|
+
const p90Value = color !== COLOR_HEALTHY ? `${formatMsShort(p.p90)} / ${formatMsShort(slo.latencyP90)}` : formatMsShort(p.p90);
|
|
15868
|
+
rows.push({ key: "p90", value: p90Value, color, inverted: color !== COLOR_HEALTHY });
|
|
15869
|
+
} else {
|
|
15870
|
+
rows.push({ key: "p90", value: formatMsShort(p.p90) });
|
|
15871
|
+
}
|
|
15536
15872
|
}
|
|
15537
|
-
rows.push({ key: "p99", value: formatMsShort(p.p99) });
|
|
15538
15873
|
}
|
|
15539
15874
|
if (node.computedUptime < 1) {
|
|
15540
15875
|
const declaredUptime = node.properties.find((p2) => p2.key === "uptime");
|
|
@@ -15545,8 +15880,17 @@ function getComputedRows(node, expanded) {
|
|
|
15545
15880
|
}
|
|
15546
15881
|
}
|
|
15547
15882
|
if (node.computedAvailability < 1) {
|
|
15548
|
-
|
|
15549
|
-
|
|
15883
|
+
let color;
|
|
15884
|
+
if (slo?.availThreshold != null) {
|
|
15885
|
+
const t = slo.availThreshold;
|
|
15886
|
+
const m = slo.warningMargin;
|
|
15887
|
+
if (node.computedAvailability < t) color = COLOR_OVERLOADED;
|
|
15888
|
+
else if (node.computedAvailability < Math.min(1, t + m)) color = COLOR_WARNING;
|
|
15889
|
+
else color = COLOR_HEALTHY;
|
|
15890
|
+
} else {
|
|
15891
|
+
color = node.computedAvailability < 0.95 ? COLOR_OVERLOADED : node.computedAvailability < 0.99 ? COLOR_WARNING : void 0;
|
|
15892
|
+
}
|
|
15893
|
+
rows.push({ key: "availability", value: formatUptimeShort(node.computedAvailability), color, inverted: color != null && color !== COLOR_HEALTHY });
|
|
15550
15894
|
}
|
|
15551
15895
|
if (node.computedCbState === "open") {
|
|
15552
15896
|
rows.push({ key: "CB", value: "OPEN", color: COLOR_OVERLOADED, inverted: true });
|
|
@@ -15634,7 +15978,7 @@ function formatRpsShort2(rps) {
|
|
|
15634
15978
|
if (rps >= 1e3) return `${(rps / 1e3).toFixed(1)}k`;
|
|
15635
15979
|
return `${Math.round(rps)}`;
|
|
15636
15980
|
}
|
|
15637
|
-
function worstNodeSeverity(node) {
|
|
15981
|
+
function worstNodeSeverity(node, slo) {
|
|
15638
15982
|
let worst = "normal";
|
|
15639
15983
|
const upgrade = (s) => {
|
|
15640
15984
|
if (s === "overloaded") worst = "overloaded";
|
|
@@ -15645,8 +15989,22 @@ function worstNodeSeverity(node) {
|
|
|
15645
15989
|
if (node.overloaded) upgrade("overloaded");
|
|
15646
15990
|
if (node.rateLimited) upgrade("warning");
|
|
15647
15991
|
if (isWarning(node)) upgrade("warning");
|
|
15648
|
-
if (
|
|
15649
|
-
|
|
15992
|
+
if (slo?.availThreshold != null) {
|
|
15993
|
+
const t = slo.availThreshold;
|
|
15994
|
+
const m = slo.warningMargin;
|
|
15995
|
+
if (node.computedAvailability < t) upgrade("overloaded");
|
|
15996
|
+
else if (node.computedAvailability < Math.min(1, t + m)) upgrade("warning");
|
|
15997
|
+
} else {
|
|
15998
|
+
if (node.computedAvailability < 0.95) upgrade("overloaded");
|
|
15999
|
+
else if (node.computedAvailability < 0.99) upgrade("warning");
|
|
16000
|
+
}
|
|
16001
|
+
if (slo?.latencyP90 != null) {
|
|
16002
|
+
const t = slo.latencyP90;
|
|
16003
|
+
const m = slo.warningMargin;
|
|
16004
|
+
const p90 = node.computedLatencyPercentiles.p90;
|
|
16005
|
+
if (p90 > t) upgrade("overloaded");
|
|
16006
|
+
else if (p90 > t * (1 - m)) upgrade("warning");
|
|
16007
|
+
}
|
|
15650
16008
|
if (node.computedCbState === "open") upgrade("overloaded");
|
|
15651
16009
|
if (node.queueMetrics && node.queueMetrics.fillRate > 0) {
|
|
15652
16010
|
if (node.queueMetrics.timeToOverflow < 60) upgrade("overloaded");
|
|
@@ -15664,10 +16022,14 @@ function worstNodeSeverity(node) {
|
|
|
15664
16022
|
else if (preRl > nodeRateLimit * 0.8) upgrade("warning");
|
|
15665
16023
|
}
|
|
15666
16024
|
}
|
|
16025
|
+
if (worst === "normal" && slo != null) {
|
|
16026
|
+
const availGreen = slo.availThreshold == null || node.computedAvailability >= Math.min(1, slo.availThreshold + slo.warningMargin);
|
|
16027
|
+
const latencyGreen = slo.latencyP90 == null || node.computedLatencyPercentiles.p90 <= slo.latencyP90 * (1 - slo.warningMargin);
|
|
16028
|
+
if (availGreen && latencyGreen) return "healthy";
|
|
16029
|
+
}
|
|
15667
16030
|
return worst;
|
|
15668
16031
|
}
|
|
15669
|
-
function nodeColor(
|
|
15670
|
-
const severity = worstNodeSeverity(node);
|
|
16032
|
+
function nodeColor(_node, palette, isDark, severity) {
|
|
15671
16033
|
if (severity === "overloaded") {
|
|
15672
16034
|
return {
|
|
15673
16035
|
fill: mix(palette.bg, COLOR_OVERLOADED, isDark ? 80 : 92),
|
|
@@ -15682,6 +16044,13 @@ function nodeColor(node, palette, isDark) {
|
|
|
15682
16044
|
textFill: palette.text
|
|
15683
16045
|
};
|
|
15684
16046
|
}
|
|
16047
|
+
if (severity === "healthy") {
|
|
16048
|
+
return {
|
|
16049
|
+
fill: mix(palette.bg, COLOR_HEALTHY, isDark ? 85 : 93),
|
|
16050
|
+
stroke: COLOR_HEALTHY,
|
|
16051
|
+
textFill: palette.text
|
|
16052
|
+
};
|
|
16053
|
+
}
|
|
15685
16054
|
return {
|
|
15686
16055
|
fill: isDark ? mix(palette.bg, palette.text, 90) : mix(palette.bg, palette.text, 95),
|
|
15687
16056
|
stroke: isDark ? mix(palette.text, palette.bg, 60) : mix(palette.text, palette.bg, 40),
|
|
@@ -15775,10 +16144,12 @@ function resolveActiveTagStroke(node, activeGroup, tagGroups, palette) {
|
|
|
15775
16144
|
if (!tv?.color) return null;
|
|
15776
16145
|
return resolveColor(tv.color, palette);
|
|
15777
16146
|
}
|
|
15778
|
-
function renderNodes(svg, nodes, palette, isDark, animate,
|
|
16147
|
+
function renderNodes(svg, nodes, palette, isDark, animate, expandedNodeIds, activeGroup, diagramOptions, collapsedNodes, tagGroups, fanoutSourceIds, scaledGroupIds) {
|
|
15779
16148
|
const mutedColor = palette.textMuted;
|
|
15780
16149
|
for (const node of nodes) {
|
|
15781
|
-
|
|
16150
|
+
const slo = !node.isEdge && diagramOptions ? resolveNodeSlo(node, diagramOptions) : null;
|
|
16151
|
+
const severity = worstNodeSeverity(node, slo);
|
|
16152
|
+
let { fill: fill2, stroke: stroke2, textFill } = nodeColor(node, palette, isDark, severity);
|
|
15782
16153
|
if (activeGroup && tagGroups && !node.isEdge) {
|
|
15783
16154
|
const tagStroke = resolveActiveTagStroke(node, activeGroup, tagGroups, palette);
|
|
15784
16155
|
if (tagStroke) {
|
|
@@ -15790,7 +16161,6 @@ function renderNodes(svg, nodes, palette, isDark, animate, selectedNodeId, activ
|
|
|
15790
16161
|
if (animate && node.isEdge) {
|
|
15791
16162
|
cls += " infra-node-edge-throb";
|
|
15792
16163
|
} else if (animate && !node.isEdge) {
|
|
15793
|
-
const severity = worstNodeSeverity(node);
|
|
15794
16164
|
if (node.computedCbState === "open") cls += " infra-node-cb-open";
|
|
15795
16165
|
else if (severity === "overloaded") cls += " infra-node-overload";
|
|
15796
16166
|
else if (severity === "warning") cls += " infra-node-warning";
|
|
@@ -15807,26 +16177,36 @@ function renderNodes(svg, nodes, palette, isDark, animate, selectedNodeId, activ
|
|
|
15807
16177
|
for (const role of roles) {
|
|
15808
16178
|
g.attr(`data-role-${role.name.toLowerCase().replace(/\s+/g, "-")}`, "true");
|
|
15809
16179
|
}
|
|
16180
|
+
if (fanoutSourceIds?.has(node.id)) {
|
|
16181
|
+
g.attr("data-role-fan-out", "true");
|
|
16182
|
+
}
|
|
15810
16183
|
}
|
|
15811
16184
|
const x = node.x - node.width / 2;
|
|
15812
16185
|
const y = node.y - node.height / 2;
|
|
15813
16186
|
const isCollapsedGroup = node.id.startsWith("[");
|
|
15814
|
-
const strokeWidth =
|
|
16187
|
+
const strokeWidth = severity !== "normal" ? OVERLOAD_STROKE_WIDTH : NODE_STROKE_WIDTH8;
|
|
15815
16188
|
g.append("rect").attr("x", x).attr("y", y).attr("width", node.width).attr("height", node.height).attr("rx", NODE_BORDER_RADIUS).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", strokeWidth);
|
|
15816
|
-
const headerCenterY = y + NODE_HEADER_HEIGHT2 / 2 +
|
|
15817
|
-
g.append("text").attr("x", node.x).attr("y", headerCenterY).attr("text-anchor", "middle").attr("font-family", FONT_FAMILY).attr("font-size",
|
|
16189
|
+
const headerCenterY = y + NODE_HEADER_HEIGHT2 / 2 + NODE_FONT_SIZE4 * 0.35;
|
|
16190
|
+
g.append("text").attr("x", node.x).attr("y", headerCenterY).attr("text-anchor", "middle").attr("font-family", FONT_FAMILY).attr("font-size", NODE_FONT_SIZE4).attr("font-weight", "600").attr("fill", textFill).text(node.label);
|
|
15818
16191
|
const isNodeCollapsed = collapsedNodes?.has(node.id) ?? false;
|
|
15819
16192
|
if (isNodeCollapsed) {
|
|
15820
16193
|
const chevronY = y + node.height - 6;
|
|
15821
16194
|
g.append("text").attr("x", node.x).attr("y", chevronY).attr("text-anchor", "middle").attr("font-family", FONT_FAMILY).attr("font-size", 8).attr("fill", textFill).attr("opacity", 0.5).text("\u25BC");
|
|
15822
16195
|
}
|
|
15823
16196
|
if (!isNodeCollapsed) {
|
|
15824
|
-
const expanded = node.id
|
|
16197
|
+
const expanded = expandedNodeIds?.has(node.id) ?? false;
|
|
16198
|
+
const descH = expanded && node.description && !node.isEdge ? META_LINE_HEIGHT8 : 0;
|
|
16199
|
+
if (descH > 0 && node.description) {
|
|
16200
|
+
const descTruncated = truncateDesc(node.description);
|
|
16201
|
+
const isTruncated = descTruncated !== node.description;
|
|
16202
|
+
const textEl = g.append("text").attr("x", node.x).attr("y", y + NODE_HEADER_HEIGHT2 + META_LINE_HEIGHT8 / 2 + META_FONT_SIZE4 * 0.35).attr("text-anchor", "middle").attr("font-family", FONT_FAMILY).attr("font-size", META_FONT_SIZE4).attr("fill", mutedColor).text(descTruncated);
|
|
16203
|
+
if (isTruncated) textEl.append("title").text(node.description);
|
|
16204
|
+
}
|
|
15825
16205
|
const displayProps = !node.isEdge && expanded ? getDisplayProps(node, expanded, diagramOptions) : [];
|
|
15826
|
-
const computedRows = getComputedRows(node, expanded);
|
|
16206
|
+
const computedRows = getComputedRows(node, expanded, slo);
|
|
15827
16207
|
const hasContent = displayProps.length > 0 || computedRows.length > 0 || node.computedRps > 0;
|
|
15828
16208
|
if (hasContent) {
|
|
15829
|
-
const sepY = y + NODE_HEADER_HEIGHT2;
|
|
16209
|
+
const sepY = y + NODE_HEADER_HEIGHT2 + descH;
|
|
15830
16210
|
g.append("line").attr("x1", x).attr("y1", sepY).attr("x2", x + node.width).attr("y2", sepY).attr("stroke", stroke2).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
|
|
15831
16211
|
const computedSection = [];
|
|
15832
16212
|
const declaredSection = [];
|
|
@@ -15922,14 +16302,15 @@ function renderNodes(svg, nodes, palette, isDark, animate, selectedNodeId, activ
|
|
|
15922
16302
|
rowIdx++;
|
|
15923
16303
|
}
|
|
15924
16304
|
}
|
|
15925
|
-
|
|
16305
|
+
const inScaledGroup = node.groupId != null && (scaledGroupIds?.has(node.groupId) ?? false);
|
|
16306
|
+
if (!node.isEdge && node.computedConcurrentInvocations === 0 && node.computedInstances > 1 && !inScaledGroup) {
|
|
15926
16307
|
const badgeText = `${node.computedInstances}x`;
|
|
15927
16308
|
g.append("text").attr("x", x + node.width - 6).attr("y", y + NODE_HEADER_HEIGHT2 / 2 + META_FONT_SIZE4 * 0.35).attr("text-anchor", "end").attr("font-family", FONT_FAMILY).attr("font-size", META_FONT_SIZE4).attr("fill", mutedColor).attr("data-instance-node", node.id).style("cursor", "pointer").text(badgeText);
|
|
15928
16309
|
}
|
|
15929
16310
|
const showDots = activeGroup != null && activeGroup.toLowerCase() === "capabilities";
|
|
15930
16311
|
const roles = showDots && !node.isEdge ? inferRoles(node.properties) : [];
|
|
15931
16312
|
if (roles.length > 0) {
|
|
15932
|
-
const dotY = isCollapsedGroup ? y + node.height -
|
|
16313
|
+
const dotY = isCollapsedGroup ? y + node.height - COLLAPSE_BAR_HEIGHT5 - NODE_PAD_BOTTOM2 / 2 : y + node.height - NODE_PAD_BOTTOM2 / 2;
|
|
15933
16314
|
const totalDotsWidth = roles.length * (ROLE_DOT_RADIUS * 2 + 2) - 2;
|
|
15934
16315
|
const startX = node.x - totalDotsWidth / 2 + ROLE_DOT_RADIUS;
|
|
15935
16316
|
for (let i = 0; i < roles.length; i++) {
|
|
@@ -15939,7 +16320,7 @@ function renderNodes(svg, nodes, palette, isDark, animate, selectedNodeId, activ
|
|
|
15939
16320
|
if (isCollapsedGroup) {
|
|
15940
16321
|
const clipId = `clip-${node.id.replace(/[[\]\s]/g, "")}`;
|
|
15941
16322
|
g.append("clipPath").attr("id", clipId).append("rect").attr("x", x).attr("y", y).attr("width", node.width).attr("height", node.height).attr("rx", NODE_BORDER_RADIUS);
|
|
15942
|
-
g.append("rect").attr("x", x + COLLAPSE_BAR_INSET2).attr("y", y + node.height -
|
|
16323
|
+
g.append("rect").attr("x", x + COLLAPSE_BAR_INSET2).attr("y", y + node.height - COLLAPSE_BAR_HEIGHT5).attr("width", node.width - COLLAPSE_BAR_INSET2 * 2).attr("height", COLLAPSE_BAR_HEIGHT5).attr("fill", stroke2).attr("clip-path", `url(#${clipId})`).attr("class", "infra-collapse-bar");
|
|
15943
16324
|
}
|
|
15944
16325
|
}
|
|
15945
16326
|
}
|
|
@@ -16008,9 +16389,12 @@ function renderRejectParticles(svg, nodes) {
|
|
|
16008
16389
|
}
|
|
16009
16390
|
}
|
|
16010
16391
|
}
|
|
16011
|
-
function computeInfraLegendGroups(nodes, tagGroups, palette) {
|
|
16392
|
+
function computeInfraLegendGroups(nodes, tagGroups, palette, edges) {
|
|
16012
16393
|
const groups = [];
|
|
16013
16394
|
const roles = collectDiagramRoles(nodes.filter((n) => !n.isEdge).map((n) => n.properties));
|
|
16395
|
+
if (edges && collectFanoutSourceIds(edges).size > 0) {
|
|
16396
|
+
roles.push(FANOUT_ROLE);
|
|
16397
|
+
}
|
|
16014
16398
|
if (roles.length > 0) {
|
|
16015
16399
|
const entries = roles.map((r) => ({
|
|
16016
16400
|
value: r.name,
|
|
@@ -16065,7 +16449,7 @@ function computePlaybackWidth(playback) {
|
|
|
16065
16449
|
let entriesW = 8;
|
|
16066
16450
|
entriesW += LEGEND_PILL_FONT_SIZE5 * 0.8 + 6;
|
|
16067
16451
|
for (const s of playback.speedOptions) {
|
|
16068
|
-
entriesW += `${s}x`.length * LEGEND_ENTRY_FONT_W7 +
|
|
16452
|
+
entriesW += `${s}x`.length * LEGEND_ENTRY_FONT_W7 + SPEED_BADGE_H_PAD * 2 + SPEED_BADGE_GAP;
|
|
16069
16453
|
}
|
|
16070
16454
|
return LEGEND_CAPSULE_PAD7 * 2 + pillWidth + entriesW;
|
|
16071
16455
|
}
|
|
@@ -16136,16 +16520,21 @@ function renderLegend3(rootSvg, legendGroups, totalWidth, legendY, palette, isDa
|
|
|
16136
16520
|
for (const s of playback.speedOptions) {
|
|
16137
16521
|
const label = `${s}x`;
|
|
16138
16522
|
const isActive = playback.speed === s;
|
|
16139
|
-
|
|
16140
|
-
|
|
16523
|
+
const slotW = label.length * LEGEND_ENTRY_FONT_W7 + SPEED_BADGE_H_PAD * 2;
|
|
16524
|
+
const badgeH = LEGEND_ENTRY_FONT_SIZE6 + SPEED_BADGE_V_PAD * 2;
|
|
16525
|
+
const badgeY = (LEGEND_HEIGHT8 - badgeH) / 2;
|
|
16526
|
+
const speedG = pbG.append("g").attr("data-playback-action", "set-speed").attr("data-playback-value", String(s)).style("cursor", "pointer");
|
|
16527
|
+
speedG.append("rect").attr("x", entryX).attr("y", badgeY).attr("width", slotW).attr("height", badgeH).attr("rx", badgeH / 2).attr("fill", isActive ? palette.primary : "transparent");
|
|
16528
|
+
speedG.append("text").attr("x", entryX + slotW / 2).attr("y", entryY).attr("font-family", FONT_FAMILY).attr("font-size", LEGEND_ENTRY_FONT_SIZE6).attr("font-weight", isActive ? "600" : "400").attr("fill", isActive ? palette.bg : palette.textMuted).attr("text-anchor", "middle").text(label);
|
|
16529
|
+
entryX += slotW + SPEED_BADGE_GAP;
|
|
16141
16530
|
}
|
|
16142
16531
|
}
|
|
16143
16532
|
cursorX += fullW + LEGEND_GROUP_GAP5;
|
|
16144
16533
|
}
|
|
16145
16534
|
}
|
|
16146
|
-
function renderInfra(container, layout, palette, isDark, title, titleLineNumber, tagGroups, activeGroup, animate, playback,
|
|
16535
|
+
function renderInfra(container, layout, palette, isDark, title, titleLineNumber, tagGroups, activeGroup, animate, playback, expandedNodeIds, exportMode, collapsedNodes) {
|
|
16147
16536
|
d3Selection9.select(container).selectAll(":not([data-d3-tooltip])").remove();
|
|
16148
|
-
const legendGroups = computeInfraLegendGroups(layout.nodes, tagGroups ?? [], palette);
|
|
16537
|
+
const legendGroups = computeInfraLegendGroups(layout.nodes, tagGroups ?? [], palette, layout.edges);
|
|
16149
16538
|
const hasLegend = legendGroups.length > 0 || !!playback;
|
|
16150
16539
|
const fixedLegend = !exportMode && hasLegend;
|
|
16151
16540
|
const legendOffset = hasLegend && !fixedLegend ? LEGEND_HEIGHT8 : 0;
|
|
@@ -16202,7 +16591,14 @@ function renderInfra(container, layout, palette, isDark, title, titleLineNumber,
|
|
|
16202
16591
|
}
|
|
16203
16592
|
renderGroups(svg, layout.groups, palette, isDark);
|
|
16204
16593
|
renderEdgePaths(svg, layout.edges, layout.nodes, palette, isDark, shouldAnimate);
|
|
16205
|
-
|
|
16594
|
+
const fanoutSourceIds = collectFanoutSourceIds(layout.edges);
|
|
16595
|
+
const scaledGroupIds = new Set(
|
|
16596
|
+
layout.groups.filter((g) => {
|
|
16597
|
+
const gi = typeof g.instances === "number" ? g.instances : typeof g.instances === "string" ? parseInt(String(g.instances), 10) || 0 : 0;
|
|
16598
|
+
return gi > 1;
|
|
16599
|
+
}).map((g) => g.id)
|
|
16600
|
+
);
|
|
16601
|
+
renderNodes(svg, layout.nodes, palette, isDark, shouldAnimate, expandedNodeIds, activeGroup, layout.options, collapsedNodes, tagGroups ?? [], fanoutSourceIds, scaledGroupIds);
|
|
16206
16602
|
if (shouldAnimate) {
|
|
16207
16603
|
renderRejectParticles(svg, layout.nodes);
|
|
16208
16604
|
}
|
|
@@ -16224,7 +16620,7 @@ function parseAndLayoutInfra(content) {
|
|
|
16224
16620
|
const layout = layoutInfra(computed);
|
|
16225
16621
|
return { parsed, computed, layout };
|
|
16226
16622
|
}
|
|
16227
|
-
var d3Selection9, d3Shape7,
|
|
16623
|
+
var d3Selection9, d3Shape7, NODE_FONT_SIZE4, META_FONT_SIZE4, META_LINE_HEIGHT8, EDGE_LABEL_FONT_SIZE7, GROUP_LABEL_FONT_SIZE2, NODE_BORDER_RADIUS, EDGE_STROKE_WIDTH8, NODE_STROKE_WIDTH8, OVERLOAD_STROKE_WIDTH, ROLE_DOT_RADIUS, NODE_HEADER_HEIGHT2, NODE_SEPARATOR_GAP2, NODE_PAD_BOTTOM2, COLLAPSE_BAR_HEIGHT5, COLLAPSE_BAR_INSET2, LEGEND_HEIGHT8, LEGEND_PILL_PAD7, LEGEND_PILL_FONT_SIZE5, LEGEND_PILL_FONT_W7, LEGEND_CAPSULE_PAD7, LEGEND_DOT_R8, LEGEND_ENTRY_FONT_SIZE6, LEGEND_ENTRY_FONT_W7, LEGEND_ENTRY_DOT_GAP7, LEGEND_ENTRY_TRAIL7, LEGEND_GROUP_GAP5, LEGEND_FIXED_GAP3, SPEED_BADGE_H_PAD, SPEED_BADGE_V_PAD, SPEED_BADGE_GAP, COLOR_HEALTHY, COLOR_WARNING, COLOR_OVERLOADED, FLOW_SPEED_MIN, FLOW_SPEED_MAX, PARTICLE_R, PARTICLE_COUNT_MIN, PARTICLE_COUNT_MAX, NODE_PULSE_SPEED, NODE_PULSE_OVERLOAD, REJECT_PARTICLE_R, REJECT_DROP_DISTANCE, REJECT_DURATION_MIN, REJECT_DURATION_MAX, REJECT_COUNT_MIN, REJECT_COUNT_MAX, lineGenerator7, PROP_DISPLAY, DESC_MAX_CHARS, RPS_FORMAT_KEYS, MS_FORMAT_KEYS, PCT_FORMAT_KEYS;
|
|
16228
16624
|
var init_renderer8 = __esm({
|
|
16229
16625
|
"src/infra/renderer.ts"() {
|
|
16230
16626
|
"use strict";
|
|
@@ -16237,7 +16633,7 @@ var init_renderer8 = __esm({
|
|
|
16237
16633
|
init_parser9();
|
|
16238
16634
|
init_compute();
|
|
16239
16635
|
init_layout8();
|
|
16240
|
-
|
|
16636
|
+
NODE_FONT_SIZE4 = 13;
|
|
16241
16637
|
META_FONT_SIZE4 = 10;
|
|
16242
16638
|
META_LINE_HEIGHT8 = 14;
|
|
16243
16639
|
EDGE_LABEL_FONT_SIZE7 = 11;
|
|
@@ -16250,7 +16646,7 @@ var init_renderer8 = __esm({
|
|
|
16250
16646
|
NODE_HEADER_HEIGHT2 = 28;
|
|
16251
16647
|
NODE_SEPARATOR_GAP2 = 4;
|
|
16252
16648
|
NODE_PAD_BOTTOM2 = 10;
|
|
16253
|
-
|
|
16649
|
+
COLLAPSE_BAR_HEIGHT5 = 6;
|
|
16254
16650
|
COLLAPSE_BAR_INSET2 = 0;
|
|
16255
16651
|
LEGEND_HEIGHT8 = 28;
|
|
16256
16652
|
LEGEND_PILL_PAD7 = 16;
|
|
@@ -16264,6 +16660,10 @@ var init_renderer8 = __esm({
|
|
|
16264
16660
|
LEGEND_ENTRY_TRAIL7 = 8;
|
|
16265
16661
|
LEGEND_GROUP_GAP5 = 12;
|
|
16266
16662
|
LEGEND_FIXED_GAP3 = 16;
|
|
16663
|
+
SPEED_BADGE_H_PAD = 5;
|
|
16664
|
+
SPEED_BADGE_V_PAD = 3;
|
|
16665
|
+
SPEED_BADGE_GAP = 6;
|
|
16666
|
+
COLOR_HEALTHY = "#22c55e";
|
|
16267
16667
|
COLOR_WARNING = "#eab308";
|
|
16268
16668
|
COLOR_OVERLOADED = "#ef4444";
|
|
16269
16669
|
FLOW_SPEED_MIN = 2.5;
|
|
@@ -16282,22 +16682,23 @@ var init_renderer8 = __esm({
|
|
|
16282
16682
|
lineGenerator7 = d3Shape7.line().x((d) => d.x).y((d) => d.y).curve(d3Shape7.curveBasis);
|
|
16283
16683
|
PROP_DISPLAY = {
|
|
16284
16684
|
"cache-hit": "cache hit",
|
|
16285
|
-
"firewall-block": "
|
|
16286
|
-
"ratelimit-rps": "rate limit",
|
|
16685
|
+
"firewall-block": "firewall block",
|
|
16686
|
+
"ratelimit-rps": "rate limit RPS",
|
|
16287
16687
|
"latency-ms": "latency",
|
|
16288
16688
|
"uptime": "uptime",
|
|
16289
16689
|
"instances": "instances",
|
|
16290
|
-
"max-rps": "
|
|
16291
|
-
"cb-error-threshold": "CB error",
|
|
16292
|
-
"cb-latency-threshold-ms": "CB latency",
|
|
16690
|
+
"max-rps": "max RPS",
|
|
16691
|
+
"cb-error-threshold": "CB error threshold",
|
|
16692
|
+
"cb-latency-threshold-ms": "CB latency threshold",
|
|
16293
16693
|
"concurrency": "concurrency",
|
|
16294
16694
|
"duration-ms": "duration",
|
|
16295
16695
|
"cold-start-ms": "cold start",
|
|
16296
16696
|
"buffer": "buffer",
|
|
16297
|
-
"drain-rate": "drain",
|
|
16697
|
+
"drain-rate": "drain rate",
|
|
16298
16698
|
"retention-hours": "retention",
|
|
16299
16699
|
"partitions": "partitions"
|
|
16300
16700
|
};
|
|
16701
|
+
DESC_MAX_CHARS = 120;
|
|
16301
16702
|
RPS_FORMAT_KEYS = /* @__PURE__ */ new Set(["max-rps", "ratelimit-rps"]);
|
|
16302
16703
|
MS_FORMAT_KEYS = /* @__PURE__ */ new Set(["latency-ms", "cb-latency-threshold-ms", "duration-ms", "cold-start-ms"]);
|
|
16303
16704
|
PCT_FORMAT_KEYS = /* @__PURE__ */ new Set(["cache-hit", "firewall-block", "uptime", "cb-error-threshold"]);
|
|
@@ -16486,7 +16887,7 @@ function renderState(container, graph, layout, palette, isDark, onClickItem, exp
|
|
|
16486
16887
|
const w = node.width;
|
|
16487
16888
|
const h = node.height;
|
|
16488
16889
|
nodeG.append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", STATE_CORNER_RADIUS).attr("ry", STATE_CORNER_RADIUS).attr("fill", stateFill(palette, isDark, node.color, colorOff)).attr("stroke", stateStroke(palette, node.color, colorOff)).attr("stroke-width", NODE_STROKE_WIDTH9);
|
|
16489
|
-
nodeG.append("text").attr("x", 0).attr("y", 0).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("fill", palette.text).attr("font-size",
|
|
16890
|
+
nodeG.append("text").attr("x", 0).attr("y", 0).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("fill", palette.text).attr("font-size", NODE_FONT_SIZE5).text(node.label);
|
|
16490
16891
|
}
|
|
16491
16892
|
}
|
|
16492
16893
|
}
|
|
@@ -16525,7 +16926,7 @@ function renderStateForExport(content, theme, palette) {
|
|
|
16525
16926
|
document.body.removeChild(container);
|
|
16526
16927
|
}
|
|
16527
16928
|
}
|
|
16528
|
-
var d3Selection10, d3Shape8, DIAGRAM_PADDING9, MAX_SCALE8,
|
|
16929
|
+
var d3Selection10, d3Shape8, DIAGRAM_PADDING9, MAX_SCALE8, NODE_FONT_SIZE5, EDGE_LABEL_FONT_SIZE8, GROUP_LABEL_FONT_SIZE3, EDGE_STROKE_WIDTH9, NODE_STROKE_WIDTH9, ARROWHEAD_W4, ARROWHEAD_H4, PSEUDOSTATE_RADIUS, STATE_CORNER_RADIUS, GROUP_EXTRA_PADDING2, lineGenerator8;
|
|
16529
16930
|
var init_state_renderer = __esm({
|
|
16530
16931
|
"src/graph/state-renderer.ts"() {
|
|
16531
16932
|
"use strict";
|
|
@@ -16537,7 +16938,7 @@ var init_state_renderer = __esm({
|
|
|
16537
16938
|
init_layout7();
|
|
16538
16939
|
DIAGRAM_PADDING9 = 20;
|
|
16539
16940
|
MAX_SCALE8 = 3;
|
|
16540
|
-
|
|
16941
|
+
NODE_FONT_SIZE5 = 13;
|
|
16541
16942
|
EDGE_LABEL_FONT_SIZE8 = 11;
|
|
16542
16943
|
GROUP_LABEL_FONT_SIZE3 = 11;
|
|
16543
16944
|
EDGE_STROKE_WIDTH9 = 1.5;
|
|
@@ -18144,7 +18545,6 @@ function parseD3(content, palette) {
|
|
|
18144
18545
|
timelineSwimlanes: false,
|
|
18145
18546
|
vennSets: [],
|
|
18146
18547
|
vennOverlaps: [],
|
|
18147
|
-
vennShowValues: false,
|
|
18148
18548
|
quadrantLabels: {
|
|
18149
18549
|
topRight: null,
|
|
18150
18550
|
topLeft: null,
|
|
@@ -18166,6 +18566,9 @@ function parseD3(content, palette) {
|
|
|
18166
18566
|
result.error = formatDgmoError(diag);
|
|
18167
18567
|
return result;
|
|
18168
18568
|
};
|
|
18569
|
+
const warn = (line10, message) => {
|
|
18570
|
+
result.diagnostics.push(makeDgmoError(line10, message, "warning"));
|
|
18571
|
+
};
|
|
18169
18572
|
if (!content || !content.trim()) {
|
|
18170
18573
|
return fail(0, "Empty content");
|
|
18171
18574
|
}
|
|
@@ -18361,25 +18764,38 @@ function parseD3(content, palette) {
|
|
|
18361
18764
|
}
|
|
18362
18765
|
}
|
|
18363
18766
|
if (result.type === "venn") {
|
|
18364
|
-
|
|
18365
|
-
|
|
18366
|
-
|
|
18367
|
-
|
|
18368
|
-
|
|
18369
|
-
|
|
18370
|
-
|
|
18371
|
-
|
|
18372
|
-
|
|
18767
|
+
if (/\+/.test(line10)) {
|
|
18768
|
+
const colonIdx = line10.indexOf(":");
|
|
18769
|
+
let setsPart;
|
|
18770
|
+
let label;
|
|
18771
|
+
if (colonIdx >= 0) {
|
|
18772
|
+
setsPart = line10.substring(0, colonIdx).trim();
|
|
18773
|
+
label = line10.substring(colonIdx + 1).trim() || null;
|
|
18774
|
+
} else {
|
|
18775
|
+
setsPart = line10.trim();
|
|
18776
|
+
label = null;
|
|
18777
|
+
}
|
|
18778
|
+
const rawSets = setsPart.split("+").map((s) => s.trim()).filter(Boolean);
|
|
18779
|
+
if (rawSets.length >= 2) {
|
|
18780
|
+
result.vennOverlaps.push({ sets: rawSets, label, lineNumber });
|
|
18781
|
+
continue;
|
|
18782
|
+
}
|
|
18373
18783
|
}
|
|
18374
|
-
const
|
|
18375
|
-
|
|
18376
|
-
|
|
18377
|
-
|
|
18378
|
-
|
|
18379
|
-
|
|
18380
|
-
|
|
18381
|
-
|
|
18382
|
-
|
|
18784
|
+
const setDeclMatch = line10.match(/^([^(:]+?)(?:\(([^)]+)\))?(?:\s+alias\s+(\S+))?\s*$/i);
|
|
18785
|
+
if (setDeclMatch) {
|
|
18786
|
+
const name = setDeclMatch[1].trim();
|
|
18787
|
+
const colorName = setDeclMatch[2]?.trim() ?? null;
|
|
18788
|
+
let color = null;
|
|
18789
|
+
if (colorName) {
|
|
18790
|
+
const resolved = resolveColor(colorName, palette);
|
|
18791
|
+
if (resolved.startsWith("#")) {
|
|
18792
|
+
color = resolved;
|
|
18793
|
+
} else {
|
|
18794
|
+
warn(lineNumber, `Unknown color "${colorName}" on set "${name}". Using auto-assigned color.`);
|
|
18795
|
+
}
|
|
18796
|
+
}
|
|
18797
|
+
const alias = setDeclMatch[3]?.trim() ?? null;
|
|
18798
|
+
result.vennSets.push({ name, alias, color, lineNumber });
|
|
18383
18799
|
continue;
|
|
18384
18800
|
}
|
|
18385
18801
|
}
|
|
@@ -18519,15 +18935,6 @@ function parseD3(content, palette) {
|
|
|
18519
18935
|
}
|
|
18520
18936
|
continue;
|
|
18521
18937
|
}
|
|
18522
|
-
if (key === "values") {
|
|
18523
|
-
const v = line10.substring(colonIndex + 1).trim().toLowerCase();
|
|
18524
|
-
if (v === "off") {
|
|
18525
|
-
result.vennShowValues = false;
|
|
18526
|
-
} else if (v === "on") {
|
|
18527
|
-
result.vennShowValues = true;
|
|
18528
|
-
}
|
|
18529
|
-
continue;
|
|
18530
|
-
}
|
|
18531
18938
|
if (key === "rotate") {
|
|
18532
18939
|
const v = line10.substring(colonIndex + 1).trim().toLowerCase();
|
|
18533
18940
|
if (v === "none" || v === "mixed" || v === "angled") {
|
|
@@ -18605,9 +19012,6 @@ function parseD3(content, palette) {
|
|
|
18605
19012
|
if (result.type === "sequence") {
|
|
18606
19013
|
return result;
|
|
18607
19014
|
}
|
|
18608
|
-
const warn = (line10, message) => {
|
|
18609
|
-
result.diagnostics.push(makeDgmoError(line10, message, "warning"));
|
|
18610
|
-
};
|
|
18611
19015
|
if (result.type === "wordcloud") {
|
|
18612
19016
|
if (result.words.length === 0 && freeformLines.length > 0) {
|
|
18613
19017
|
result.words = tokenizeFreeformText(freeformLines.join(" "));
|
|
@@ -18679,29 +19083,34 @@ function parseD3(content, palette) {
|
|
|
18679
19083
|
}
|
|
18680
19084
|
if (result.type === "venn") {
|
|
18681
19085
|
if (result.vennSets.length < 2) {
|
|
18682
|
-
return fail(1, 'At least 2 sets are required. Add
|
|
19086
|
+
return fail(1, 'At least 2 sets are required. Add set names (e.g., "Apples", "Oranges")');
|
|
18683
19087
|
}
|
|
18684
19088
|
if (result.vennSets.length > 3) {
|
|
18685
|
-
return fail(1, "
|
|
19089
|
+
return fail(1, "Venn diagrams support 2\u20133 sets");
|
|
19090
|
+
}
|
|
19091
|
+
const setNameLower = new Map(
|
|
19092
|
+
result.vennSets.map((s) => [s.name.toLowerCase(), s.name])
|
|
19093
|
+
);
|
|
19094
|
+
const aliasLower = /* @__PURE__ */ new Map();
|
|
19095
|
+
for (const s of result.vennSets) {
|
|
19096
|
+
if (s.alias) aliasLower.set(s.alias.toLowerCase(), s.name);
|
|
18686
19097
|
}
|
|
18687
|
-
const
|
|
19098
|
+
const resolveSetRef = (ref) => setNameLower.get(ref.toLowerCase()) ?? aliasLower.get(ref.toLowerCase()) ?? null;
|
|
18688
19099
|
const validOverlaps = [];
|
|
18689
19100
|
for (const ov of result.vennOverlaps) {
|
|
19101
|
+
const resolvedSets = [];
|
|
18690
19102
|
let valid = true;
|
|
18691
|
-
for (const
|
|
18692
|
-
|
|
18693
|
-
|
|
19103
|
+
for (const ref of ov.sets) {
|
|
19104
|
+
const resolved = resolveSetRef(ref);
|
|
19105
|
+
if (!resolved) {
|
|
19106
|
+
result.diagnostics.push(makeDgmoError(ov.lineNumber, `Intersection references unknown set or alias "${ref}"`));
|
|
18694
19107
|
if (!result.error) result.error = formatDgmoError(result.diagnostics[result.diagnostics.length - 1]);
|
|
18695
19108
|
valid = false;
|
|
18696
19109
|
break;
|
|
18697
19110
|
}
|
|
19111
|
+
resolvedSets.push(resolved);
|
|
18698
19112
|
}
|
|
18699
|
-
if (
|
|
18700
|
-
const minSetSize = Math.min(...ov.sets.map((s) => setMap.get(s)));
|
|
18701
|
-
if (ov.size > minSetSize) {
|
|
18702
|
-
warn(ov.lineNumber, `Overlap size ${ov.size} exceeds smallest constituent set size ${minSetSize}`);
|
|
18703
|
-
}
|
|
18704
|
-
validOverlaps.push(ov);
|
|
19113
|
+
if (valid) validOverlaps.push({ ...ov, sets: resolvedSets.sort() });
|
|
18705
19114
|
}
|
|
18706
19115
|
result.vennOverlaps = validOverlaps;
|
|
18707
19116
|
return result;
|
|
@@ -19855,7 +20264,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
19855
20264
|
return;
|
|
19856
20265
|
}
|
|
19857
20266
|
const BAR_H = 22;
|
|
19858
|
-
const
|
|
20267
|
+
const GROUP_GAP2 = 12;
|
|
19859
20268
|
const useGroupedHorizontal = tagLanes != null || timelineSort === "group" && timelineGroups.length > 0;
|
|
19860
20269
|
if (useGroupedHorizontal) {
|
|
19861
20270
|
let lanes;
|
|
@@ -19888,7 +20297,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
19888
20297
|
};
|
|
19889
20298
|
const innerWidth = width - margin.left - margin.right;
|
|
19890
20299
|
const innerHeight = height - margin.top - margin.bottom;
|
|
19891
|
-
const totalGaps = (lanes.length - 1) *
|
|
20300
|
+
const totalGaps = (lanes.length - 1) * GROUP_GAP2;
|
|
19892
20301
|
const rowH = Math.min(28, (innerHeight - totalGaps) / totalEventRows);
|
|
19893
20302
|
const xScale = d3Scale.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerWidth]);
|
|
19894
20303
|
const svg = d3Selection12.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
@@ -19938,8 +20347,8 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
19938
20347
|
lanes.forEach((lane, idx) => {
|
|
19939
20348
|
const laneSpan = lane.events.length * rowH;
|
|
19940
20349
|
const fillColor = idx % 2 === 0 ? textColor : "transparent";
|
|
19941
|
-
g.append("rect").attr("class", "tl-swimlane").attr("data-group", lane.name).attr("x", -margin.left).attr("y", swimY).attr("width", innerWidth + margin.left).attr("height", laneSpan + (idx < lanes.length - 1 ?
|
|
19942
|
-
swimY += laneSpan +
|
|
20350
|
+
g.append("rect").attr("class", "tl-swimlane").attr("data-group", lane.name).attr("x", -margin.left).attr("y", swimY).attr("width", innerWidth + margin.left).attr("height", laneSpan + (idx < lanes.length - 1 ? GROUP_GAP2 : 0)).attr("fill", fillColor).attr("opacity", 0.06);
|
|
20351
|
+
swimY += laneSpan + GROUP_GAP2;
|
|
19943
20352
|
});
|
|
19944
20353
|
}
|
|
19945
20354
|
for (const lane of lanes) {
|
|
@@ -20020,7 +20429,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
20020
20429
|
evG.append("text").attr("x", flipLeft ? x - 10 : x + 10).attr("y", y).attr("dy", "0.35em").attr("text-anchor", flipLeft ? "end" : "start").attr("fill", textColor).attr("font-size", "12px").text(ev.label);
|
|
20021
20430
|
}
|
|
20022
20431
|
});
|
|
20023
|
-
curY += laneSpan +
|
|
20432
|
+
curY += laneSpan + GROUP_GAP2;
|
|
20024
20433
|
}
|
|
20025
20434
|
} else {
|
|
20026
20435
|
const sorted = timelineEvents.slice().sort((a, b) => parseTimelineDate(a.date) - parseTimelineDate(b.date));
|
|
@@ -20203,18 +20612,19 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
20203
20612
|
);
|
|
20204
20613
|
}, drawLegend2 = function() {
|
|
20205
20614
|
mainSvg.selectAll(".tl-tag-legend-group").remove();
|
|
20615
|
+
const effectiveColorKey = (currentActiveGroup ?? currentSwimlaneGroup)?.toLowerCase() ?? null;
|
|
20206
20616
|
const visibleGroups = viewMode ? legendGroups.filter(
|
|
20207
|
-
(lg) =>
|
|
20617
|
+
(lg) => effectiveColorKey != null && lg.group.name.toLowerCase() === effectiveColorKey
|
|
20208
20618
|
) : legendGroups;
|
|
20209
20619
|
if (visibleGroups.length === 0) return;
|
|
20210
20620
|
const totalW = visibleGroups.reduce((s, lg) => {
|
|
20211
|
-
const isActive = currentActiveGroup != null && lg.group.name.toLowerCase() === currentActiveGroup.toLowerCase();
|
|
20621
|
+
const isActive = viewMode || currentActiveGroup != null && lg.group.name.toLowerCase() === currentActiveGroup.toLowerCase();
|
|
20212
20622
|
return s + (isActive ? lg.expandedWidth : lg.minifiedWidth);
|
|
20213
20623
|
}, 0) + (visibleGroups.length - 1) * LG_GROUP_GAP;
|
|
20214
20624
|
let cx = (width - totalW) / 2;
|
|
20215
20625
|
for (const lg of visibleGroups) {
|
|
20216
20626
|
const groupKey = lg.group.name.toLowerCase();
|
|
20217
|
-
const isActive = currentActiveGroup != null && currentActiveGroup.toLowerCase() === groupKey;
|
|
20627
|
+
const isActive = viewMode || currentActiveGroup != null && currentActiveGroup.toLowerCase() === groupKey;
|
|
20218
20628
|
const isSwimActive = currentSwimlaneGroup != null && currentSwimlaneGroup.toLowerCase() === groupKey;
|
|
20219
20629
|
const pillLabel = lg.group.name;
|
|
20220
20630
|
const pillWidth = pillLabel.length * LG_PILL_FONT_W + LG_PILL_PAD;
|
|
@@ -20422,49 +20832,6 @@ function renderWordCloudAsync(container, parsed, palette, _isDark, exportDims) {
|
|
|
20422
20832
|
}).start();
|
|
20423
20833
|
});
|
|
20424
20834
|
}
|
|
20425
|
-
function radiusFromArea(area) {
|
|
20426
|
-
return Math.sqrt(area / Math.PI);
|
|
20427
|
-
}
|
|
20428
|
-
function circleOverlapArea(r1, r2, d) {
|
|
20429
|
-
if (d >= r1 + r2) return 0;
|
|
20430
|
-
if (d + Math.min(r1, r2) <= Math.max(r1, r2)) {
|
|
20431
|
-
return Math.PI * Math.min(r1, r2) ** 2;
|
|
20432
|
-
}
|
|
20433
|
-
const part1 = r1 * r1 * Math.acos((d * d + r1 * r1 - r2 * r2) / (2 * d * r1));
|
|
20434
|
-
const part2 = r2 * r2 * Math.acos((d * d + r2 * r2 - r1 * r1) / (2 * d * r2));
|
|
20435
|
-
const part3 = 0.5 * Math.sqrt((-d + r1 + r2) * (d + r1 - r2) * (d - r1 + r2) * (d + r1 + r2));
|
|
20436
|
-
return part1 + part2 - part3;
|
|
20437
|
-
}
|
|
20438
|
-
function distanceForOverlap(r1, r2, targetArea) {
|
|
20439
|
-
if (targetArea <= 0) return r1 + r2;
|
|
20440
|
-
const minR = Math.min(r1, r2);
|
|
20441
|
-
if (targetArea >= Math.PI * minR * minR) return Math.abs(r1 - r2);
|
|
20442
|
-
let lo = Math.abs(r1 - r2);
|
|
20443
|
-
let hi = r1 + r2;
|
|
20444
|
-
for (let i = 0; i < 64; i++) {
|
|
20445
|
-
const mid = (lo + hi) / 2;
|
|
20446
|
-
if (circleOverlapArea(r1, r2, mid) > targetArea) {
|
|
20447
|
-
lo = mid;
|
|
20448
|
-
} else {
|
|
20449
|
-
hi = mid;
|
|
20450
|
-
}
|
|
20451
|
-
}
|
|
20452
|
-
return (lo + hi) / 2;
|
|
20453
|
-
}
|
|
20454
|
-
function thirdCirclePosition(ax, ay, dAC, bx, by, dBC) {
|
|
20455
|
-
const dx = bx - ax;
|
|
20456
|
-
const dy = by - ay;
|
|
20457
|
-
const dAB = Math.sqrt(dx * dx + dy * dy);
|
|
20458
|
-
if (dAB === 0) return { x: ax + dAC, y: ay };
|
|
20459
|
-
const cosA = (dAB * dAB + dAC * dAC - dBC * dBC) / (2 * dAB * dAC);
|
|
20460
|
-
const sinA = Math.sqrt(Math.max(0, 1 - cosA * cosA));
|
|
20461
|
-
const ux = dx / dAB;
|
|
20462
|
-
const uy = dy / dAB;
|
|
20463
|
-
return {
|
|
20464
|
-
x: ax + dAC * (cosA * ux - sinA * uy),
|
|
20465
|
-
y: ay + dAC * (cosA * uy + sinA * ux)
|
|
20466
|
-
};
|
|
20467
|
-
}
|
|
20468
20835
|
function fitCirclesToContainerAsymmetric(circles, w, h, mLeft, mRight, mTop, mBottom) {
|
|
20469
20836
|
if (circles.length === 0) return [];
|
|
20470
20837
|
let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
|
|
@@ -20539,54 +20906,28 @@ function regionCentroid(circles, inside) {
|
|
|
20539
20906
|
return { x: sx / count, y: sy / count };
|
|
20540
20907
|
}
|
|
20541
20908
|
function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims) {
|
|
20542
|
-
const { vennSets, vennOverlaps,
|
|
20909
|
+
const { vennSets, vennOverlaps, title } = parsed;
|
|
20543
20910
|
if (vennSets.length < 2) return;
|
|
20544
20911
|
const init2 = initD3Chart(container, palette, exportDims);
|
|
20545
20912
|
if (!init2) return;
|
|
20546
20913
|
const { svg, width, height, textColor, colors } = init2;
|
|
20547
20914
|
const titleHeight = title ? 40 : 0;
|
|
20548
|
-
const radii = vennSets.map((s) => radiusFromArea(s.size));
|
|
20549
|
-
const overlapMap = /* @__PURE__ */ new Map();
|
|
20550
|
-
for (const ov of vennOverlaps) {
|
|
20551
|
-
overlapMap.set(ov.sets.join("&"), ov.size);
|
|
20552
|
-
}
|
|
20553
|
-
let rawCircles;
|
|
20554
20915
|
const n = vennSets.length;
|
|
20916
|
+
const BASE_R = 100;
|
|
20917
|
+
const OVERLAP_DISTANCE = BASE_R * 1.4;
|
|
20918
|
+
let rawCircles;
|
|
20555
20919
|
if (n === 2) {
|
|
20556
|
-
const d = distanceForOverlap(
|
|
20557
|
-
radii[0],
|
|
20558
|
-
radii[1],
|
|
20559
|
-
overlapMap.get([vennSets[0].name, vennSets[1].name].sort().join("&")) ?? 0
|
|
20560
|
-
);
|
|
20561
20920
|
rawCircles = [
|
|
20562
|
-
{ x: -
|
|
20563
|
-
{ x:
|
|
20921
|
+
{ x: -OVERLAP_DISTANCE / 2, y: 0, r: BASE_R },
|
|
20922
|
+
{ x: OVERLAP_DISTANCE / 2, y: 0, r: BASE_R }
|
|
20564
20923
|
];
|
|
20565
20924
|
} else {
|
|
20566
|
-
const
|
|
20567
|
-
const
|
|
20568
|
-
const dAB = distanceForOverlap(
|
|
20569
|
-
radii[0],
|
|
20570
|
-
radii[1],
|
|
20571
|
-
overlapMap.get(pairKey(0, 1)) ?? 0
|
|
20572
|
-
);
|
|
20573
|
-
const dAC = distanceForOverlap(
|
|
20574
|
-
radii[0],
|
|
20575
|
-
radii[2],
|
|
20576
|
-
overlapMap.get(pairKey(0, 2)) ?? 0
|
|
20577
|
-
);
|
|
20578
|
-
const dBC = distanceForOverlap(
|
|
20579
|
-
radii[1],
|
|
20580
|
-
radii[2],
|
|
20581
|
-
overlapMap.get(pairKey(1, 2)) ?? 0
|
|
20582
|
-
);
|
|
20583
|
-
const ax = -dAB / 2;
|
|
20584
|
-
const bx = dAB / 2;
|
|
20585
|
-
const cPos = thirdCirclePosition(ax, 0, dAC, bx, 0, dBC);
|
|
20925
|
+
const s = OVERLAP_DISTANCE;
|
|
20926
|
+
const h = Math.sqrt(3) / 2 * s;
|
|
20586
20927
|
rawCircles = [
|
|
20587
|
-
{ x:
|
|
20588
|
-
{ x:
|
|
20589
|
-
{ x:
|
|
20928
|
+
{ x: -s / 2, y: h / 3, r: BASE_R },
|
|
20929
|
+
{ x: s / 2, y: h / 3, r: BASE_R },
|
|
20930
|
+
{ x: 0, y: -(2 * h) / 3, r: BASE_R }
|
|
20590
20931
|
];
|
|
20591
20932
|
}
|
|
20592
20933
|
const setColors = vennSets.map(
|
|
@@ -20599,8 +20940,7 @@ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims)
|
|
|
20599
20940
|
const edgePad = 8;
|
|
20600
20941
|
const labelTextPad = 4;
|
|
20601
20942
|
for (let i = 0; i < n; i++) {
|
|
20602
|
-
const
|
|
20603
|
-
const estimatedWidth = displayName.length * 8.5 + stubLen + edgePad + labelTextPad;
|
|
20943
|
+
const estimatedWidth = vennSets[i].name.length * 8.5 + stubLen + edgePad + labelTextPad;
|
|
20604
20944
|
const dx = rawCircles[i].x - clusterCx;
|
|
20605
20945
|
const dy = rawCircles[i].y - clusterCy;
|
|
20606
20946
|
if (Math.abs(dx) >= Math.abs(dy)) {
|
|
@@ -20622,25 +20962,71 @@ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims)
|
|
|
20622
20962
|
marginTop,
|
|
20623
20963
|
marginBottom
|
|
20624
20964
|
).map((c) => ({ ...c, y: c.y + titleHeight }));
|
|
20625
|
-
const
|
|
20965
|
+
const scaledR = circles[0].r;
|
|
20966
|
+
svg.append("style").text("circle:focus, circle:focus-visible { outline: none !important; }");
|
|
20626
20967
|
renderChartTitle(svg, title, parsed.titleLineNumber, width, textColor, onClickItem);
|
|
20627
20968
|
const circleEls = [];
|
|
20628
20969
|
const circleGroup = svg.append("g");
|
|
20629
20970
|
circles.forEach((c, i) => {
|
|
20630
|
-
const el = circleGroup.append("circle").attr("cx", c.x).attr("cy", c.y).attr("r", c.r).attr("fill", setColors[i]).attr("fill-opacity", 0.35).attr("stroke", setColors[i]).attr("stroke-width", 2).style("pointer-events", "none");
|
|
20971
|
+
const el = circleGroup.append("circle").attr("cx", c.x).attr("cy", c.y).attr("r", c.r).attr("fill", setColors[i]).attr("fill-opacity", 0.35).attr("stroke", setColors[i]).attr("stroke-width", 2).attr("class", "venn-fill-circle").attr("data-line-number", String(vennSets[i].lineNumber)).style("pointer-events", "none");
|
|
20631
20972
|
circleEls.push(el);
|
|
20632
20973
|
});
|
|
20974
|
+
const defs = svg.append("defs");
|
|
20975
|
+
circles.forEach((c, i) => {
|
|
20976
|
+
defs.append("clipPath").attr("id", `vcp-${i}`).append("circle").attr("cx", c.x).attr("cy", c.y).attr("r", c.r);
|
|
20977
|
+
});
|
|
20978
|
+
const regionIdxSets = circles.map((_, i) => [i]);
|
|
20979
|
+
if (n === 2) {
|
|
20980
|
+
regionIdxSets.push([0, 1]);
|
|
20981
|
+
} else {
|
|
20982
|
+
regionIdxSets.push([0, 1], [0, 2], [1, 2], [0, 1, 2]);
|
|
20983
|
+
}
|
|
20984
|
+
const overlayGroup = svg.append("g").style("pointer-events", "none");
|
|
20985
|
+
const overlayEls = /* @__PURE__ */ new Map();
|
|
20986
|
+
for (const idxs of regionIdxSets) {
|
|
20987
|
+
const key = idxs.join("-");
|
|
20988
|
+
const excluded = Array.from({ length: n }, (_, j) => j).filter((j) => !idxs.includes(j));
|
|
20989
|
+
let clipId = `vcp-${idxs[0]}`;
|
|
20990
|
+
for (let k = 1; k < idxs.length; k++) {
|
|
20991
|
+
const nestedId = `vcp-n-${idxs.slice(0, k + 1).join("-")}`;
|
|
20992
|
+
const ci = idxs[k];
|
|
20993
|
+
defs.append("clipPath").attr("id", nestedId).append("circle").attr("cx", circles[ci].x).attr("cy", circles[ci].y).attr("r", circles[ci].r).attr("clip-path", `url(#${clipId})`);
|
|
20994
|
+
clipId = nestedId;
|
|
20995
|
+
}
|
|
20996
|
+
let regionLineNumber = null;
|
|
20997
|
+
if (idxs.length === 1) {
|
|
20998
|
+
regionLineNumber = vennSets[idxs[0]].lineNumber;
|
|
20999
|
+
} else {
|
|
21000
|
+
const sortedNames = idxs.map((i) => vennSets[i].name).sort();
|
|
21001
|
+
const ov = vennOverlaps.find(
|
|
21002
|
+
(o) => o.sets.length === sortedNames.length && o.sets.every((s, k) => s === sortedNames[k])
|
|
21003
|
+
);
|
|
21004
|
+
regionLineNumber = ov?.lineNumber ?? null;
|
|
21005
|
+
}
|
|
21006
|
+
const el = overlayGroup.append("rect").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height).attr("fill", "white").attr("fill-opacity", 0).attr("class", "venn-region-overlay").attr("clip-path", `url(#${clipId})`);
|
|
21007
|
+
if (regionLineNumber != null) {
|
|
21008
|
+
el.attr("data-line-number", String(regionLineNumber));
|
|
21009
|
+
}
|
|
21010
|
+
if (excluded.length > 0) {
|
|
21011
|
+
const maskId = `vvm-${key}`;
|
|
21012
|
+
const mask = defs.append("mask").attr("id", maskId);
|
|
21013
|
+
mask.append("rect").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height).attr("fill", "white");
|
|
21014
|
+
for (const j of excluded) {
|
|
21015
|
+
mask.append("circle").attr("cx", circles[j].x).attr("cy", circles[j].y).attr("r", circles[j].r).attr("fill", "black");
|
|
21016
|
+
}
|
|
21017
|
+
el.attr("mask", `url(#${maskId})`);
|
|
21018
|
+
}
|
|
21019
|
+
overlayEls.set(key, el);
|
|
21020
|
+
}
|
|
21021
|
+
const showRegionOverlay = (idxs) => {
|
|
21022
|
+
const key = [...idxs].sort((a, b) => a - b).join("-");
|
|
21023
|
+
overlayEls.forEach((el, k) => el.attr("fill-opacity", k === key ? 0.3 : 0));
|
|
21024
|
+
};
|
|
21025
|
+
const hideAllOverlays = () => {
|
|
21026
|
+
overlayEls.forEach((el) => el.attr("fill-opacity", 0));
|
|
21027
|
+
};
|
|
20633
21028
|
const gcx = circles.reduce((s, c) => s + c.x, 0) / n;
|
|
20634
21029
|
const gcy = circles.reduce((s, c) => s + c.y, 0) / n;
|
|
20635
|
-
function rayCircleExit(ox, oy, dx, dy, c) {
|
|
20636
|
-
const lx = ox - c.x;
|
|
20637
|
-
const ly = oy - c.y;
|
|
20638
|
-
const b = lx * dx + ly * dy;
|
|
20639
|
-
const det = b * b - (lx * lx + ly * ly - c.r * c.r);
|
|
20640
|
-
if (det < 0) return 0;
|
|
20641
|
-
return -b + Math.sqrt(det);
|
|
20642
|
-
}
|
|
20643
|
-
const labelGroup = svg.append("g").style("pointer-events", "none");
|
|
20644
21030
|
function exclusiveHSpan(px, py, ci) {
|
|
20645
21031
|
const dy = py - circles[ci].y;
|
|
20646
21032
|
const halfChord = Math.sqrt(Math.max(0, circles[ci].r * circles[ci].r - dy * dy));
|
|
@@ -20663,8 +21049,9 @@ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims)
|
|
|
20663
21049
|
const MIN_FONT = 10;
|
|
20664
21050
|
const MAX_FONT = 22;
|
|
20665
21051
|
const INTERNAL_PAD = 12;
|
|
21052
|
+
const labelGroup = svg.append("g").style("pointer-events", "none");
|
|
20666
21053
|
circles.forEach((c, i) => {
|
|
20667
|
-
const text = vennSets[i].
|
|
21054
|
+
const text = vennSets[i].name;
|
|
20668
21055
|
const inside = circles.map((_, j) => j === i);
|
|
20669
21056
|
const centroid = regionCentroid(circles, inside);
|
|
20670
21057
|
const availW = exclusiveHSpan(centroid.x, centroid.y, i);
|
|
@@ -20699,11 +21086,8 @@ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims)
|
|
|
20699
21086
|
let textX = stubEndX + (isRight ? labelTextPad : -labelTextPad);
|
|
20700
21087
|
const textY = stubEndY;
|
|
20701
21088
|
const estW = text.length * 8.5;
|
|
20702
|
-
if (isRight)
|
|
20703
|
-
|
|
20704
|
-
} else {
|
|
20705
|
-
textX = Math.max(textX, estW + 4);
|
|
20706
|
-
}
|
|
21089
|
+
if (isRight) textX = Math.min(textX, width - estW - 4);
|
|
21090
|
+
else textX = Math.max(textX, estW + 4);
|
|
20707
21091
|
labelGroup.append("text").attr("x", textX).attr("y", Math.max(14, Math.min(height - 4, textY))).attr("text-anchor", textAnchor).attr("dominant-baseline", "central").attr("fill", textColor).attr("font-size", "14px").attr("font-weight", "bold").text(text);
|
|
20708
21092
|
}
|
|
20709
21093
|
});
|
|
@@ -20731,40 +21115,57 @@ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims)
|
|
|
20731
21115
|
return Math.max(0, right - left);
|
|
20732
21116
|
}
|
|
20733
21117
|
for (const ov of vennOverlaps) {
|
|
21118
|
+
if (!ov.label) continue;
|
|
20734
21119
|
const idxs = ov.sets.map((s) => vennSets.findIndex((vs) => vs.name === s));
|
|
20735
21120
|
if (idxs.some((idx) => idx < 0)) continue;
|
|
20736
|
-
if (!ov.label) continue;
|
|
20737
21121
|
const inside = circles.map((_, j) => idxs.includes(j));
|
|
20738
21122
|
const centroid = regionCentroid(circles, inside);
|
|
20739
|
-
const text = ov.label;
|
|
20740
21123
|
const availW = overlapHSpan(centroid.y, idxs);
|
|
20741
21124
|
const fitFont = Math.min(MAX_FONT, Math.max(
|
|
20742
21125
|
MIN_FONT,
|
|
20743
|
-
(availW - INTERNAL_PAD * 2) / (
|
|
21126
|
+
(availW - INTERNAL_PAD * 2) / (ov.label.length * CH_RATIO)
|
|
20744
21127
|
));
|
|
20745
|
-
labelGroup.append("text").attr("x", centroid.x).attr("y", centroid.y).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("fill", textColor).attr("font-size", `${Math.round(fitFont)}px`).attr("font-weight", "600").text(
|
|
21128
|
+
labelGroup.append("text").attr("x", centroid.x).attr("y", centroid.y).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("fill", textColor).attr("font-size", `${Math.round(fitFont)}px`).attr("font-weight", "600").text(ov.label);
|
|
20746
21129
|
}
|
|
20747
21130
|
const hoverGroup = svg.append("g");
|
|
20748
21131
|
circles.forEach((c, i) => {
|
|
20749
|
-
|
|
20750
|
-
|
|
20751
|
-
hoverGroup.append("circle").attr("cx", c.x).attr("cy", c.y).attr("r", c.r).attr("fill", "transparent").attr("data-line-number", String(vennSets[i].lineNumber)).style("cursor", onClickItem ? "pointer" : "default").on("mouseenter", (event) => {
|
|
20752
|
-
circleEls.forEach((el, ci) => {
|
|
20753
|
-
el.attr("fill-opacity", ci === i ? 0.5 : 0.1);
|
|
20754
|
-
});
|
|
20755
|
-
showTooltip(tooltip, tipHtml, event);
|
|
20756
|
-
}).on("mousemove", (event) => {
|
|
20757
|
-
showTooltip(tooltip, tipHtml, event);
|
|
21132
|
+
hoverGroup.append("circle").attr("cx", c.x).attr("cy", c.y).attr("r", c.r).attr("fill", "transparent").attr("stroke", "none").attr("class", "venn-hit-target").attr("data-line-number", String(vennSets[i].lineNumber)).style("cursor", onClickItem ? "pointer" : "default").style("outline", "none").on("mouseenter", () => {
|
|
21133
|
+
showRegionOverlay([i]);
|
|
20758
21134
|
}).on("mouseleave", () => {
|
|
20759
|
-
|
|
20760
|
-
|
|
20761
|
-
|
|
20762
|
-
|
|
20763
|
-
}).on("click", () => {
|
|
20764
|
-
if (onClickItem && vennSets[i].lineNumber)
|
|
20765
|
-
onClickItem(vennSets[i].lineNumber);
|
|
21135
|
+
hideAllOverlays();
|
|
21136
|
+
}).on("click", function() {
|
|
21137
|
+
this.blur?.();
|
|
21138
|
+
if (onClickItem && vennSets[i].lineNumber) onClickItem(vennSets[i].lineNumber);
|
|
20766
21139
|
});
|
|
20767
21140
|
});
|
|
21141
|
+
const overlayR = scaledR * 0.35;
|
|
21142
|
+
const subsets = [];
|
|
21143
|
+
if (n === 2) {
|
|
21144
|
+
subsets.push({ idxs: [0, 1], sets: [vennSets[0].name, vennSets[1].name].sort() });
|
|
21145
|
+
} else {
|
|
21146
|
+
for (let a = 0; a < n; a++) {
|
|
21147
|
+
for (let b = a + 1; b < n; b++) {
|
|
21148
|
+
subsets.push({ idxs: [a, b], sets: [vennSets[a].name, vennSets[b].name].sort() });
|
|
21149
|
+
}
|
|
21150
|
+
}
|
|
21151
|
+
subsets.push({ idxs: [0, 1, 2], sets: [vennSets[0].name, vennSets[1].name, vennSets[2].name].sort() });
|
|
21152
|
+
}
|
|
21153
|
+
for (const subset of subsets) {
|
|
21154
|
+
const { idxs, sets } = subset;
|
|
21155
|
+
const inside = circles.map((_, j) => idxs.includes(j));
|
|
21156
|
+
const centroid = regionCentroid(circles, inside);
|
|
21157
|
+
const declaredOv = vennOverlaps.find(
|
|
21158
|
+
(ov) => ov.sets.length === sets.length && ov.sets.every((s, k) => s === sets[k])
|
|
21159
|
+
);
|
|
21160
|
+
hoverGroup.append("circle").attr("cx", centroid.x).attr("cy", centroid.y).attr("r", overlayR).attr("fill", "transparent").attr("stroke", "none").attr("class", "venn-hit-target").attr("data-line-number", declaredOv ? String(declaredOv.lineNumber) : "").style("cursor", onClickItem && declaredOv ? "pointer" : "default").style("outline", "none").on("mouseenter", () => {
|
|
21161
|
+
showRegionOverlay(idxs);
|
|
21162
|
+
}).on("mouseleave", () => {
|
|
21163
|
+
hideAllOverlays();
|
|
21164
|
+
}).on("click", function() {
|
|
21165
|
+
this.blur?.();
|
|
21166
|
+
if (onClickItem && declaredOv) onClickItem(declaredOv.lineNumber);
|
|
21167
|
+
});
|
|
21168
|
+
}
|
|
20768
21169
|
}
|
|
20769
21170
|
function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportDims) {
|
|
20770
21171
|
const {
|
|
@@ -20872,8 +21273,8 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
20872
21273
|
const LABEL_MAX_FONT = 48;
|
|
20873
21274
|
const LABEL_MIN_FONT = 14;
|
|
20874
21275
|
const LABEL_PAD = 40;
|
|
20875
|
-
const
|
|
20876
|
-
const estTextWidth = (text, fontSize) => text.length * fontSize *
|
|
21276
|
+
const CHAR_WIDTH_RATIO3 = 0.6;
|
|
21277
|
+
const estTextWidth = (text, fontSize) => text.length * fontSize * CHAR_WIDTH_RATIO3;
|
|
20877
21278
|
const quadrantLabelLayout = (text, qw2, qh2) => {
|
|
20878
21279
|
const availW = qw2 - LABEL_PAD;
|
|
20879
21280
|
const availH = qh2 - LABEL_PAD;
|
|
@@ -21495,6 +21896,7 @@ __export(index_exports, {
|
|
|
21495
21896
|
buildRenderSequence: () => buildRenderSequence,
|
|
21496
21897
|
buildThemeCSS: () => buildThemeCSS,
|
|
21497
21898
|
catppuccinPalette: () => catppuccinPalette,
|
|
21899
|
+
collapseInitiativeStatus: () => collapseInitiativeStatus,
|
|
21498
21900
|
collapseOrgTree: () => collapseOrgTree,
|
|
21499
21901
|
collapseSitemapTree: () => collapseSitemapTree,
|
|
21500
21902
|
collectDiagramRoles: () => collectDiagramRoles,
|
|
@@ -21843,6 +22245,43 @@ init_renderer7();
|
|
|
21843
22245
|
init_parser7();
|
|
21844
22246
|
init_layout5();
|
|
21845
22247
|
init_renderer6();
|
|
22248
|
+
|
|
22249
|
+
// src/initiative-status/collapse.ts
|
|
22250
|
+
init_layout5();
|
|
22251
|
+
function collapseInitiativeStatus(parsed, collapsedGroups) {
|
|
22252
|
+
const originalGroups = parsed.groups;
|
|
22253
|
+
if (collapsedGroups.size === 0) {
|
|
22254
|
+
return { parsed, collapsedGroupStatuses: /* @__PURE__ */ new Map(), originalGroups };
|
|
22255
|
+
}
|
|
22256
|
+
const nodeToGroup = /* @__PURE__ */ new Map();
|
|
22257
|
+
const collapsedGroupStatuses = /* @__PURE__ */ new Map();
|
|
22258
|
+
for (const group of parsed.groups) {
|
|
22259
|
+
if (!collapsedGroups.has(group.label)) continue;
|
|
22260
|
+
const children = group.nodeLabels.map((l) => parsed.nodes.find((n) => n.label === l)).filter((n) => n !== void 0);
|
|
22261
|
+
for (const node of children) nodeToGroup.set(node.label, group.label);
|
|
22262
|
+
collapsedGroupStatuses.set(group.label, rollUpStatus(children));
|
|
22263
|
+
}
|
|
22264
|
+
const nodes = parsed.nodes.filter((n) => !nodeToGroup.has(n.label));
|
|
22265
|
+
const edgeKeys = /* @__PURE__ */ new Set();
|
|
22266
|
+
const edges = [];
|
|
22267
|
+
for (const edge of parsed.edges) {
|
|
22268
|
+
const src = nodeToGroup.get(edge.source) ?? edge.source;
|
|
22269
|
+
const tgt = nodeToGroup.get(edge.target) ?? edge.target;
|
|
22270
|
+
if (src === tgt) continue;
|
|
22271
|
+
const key = `${src}|${tgt}|${edge.label ?? ""}`;
|
|
22272
|
+
if (edgeKeys.has(key)) continue;
|
|
22273
|
+
edgeKeys.add(key);
|
|
22274
|
+
edges.push({ ...edge, source: src, target: tgt });
|
|
22275
|
+
}
|
|
22276
|
+
const groups = parsed.groups.filter((g) => !collapsedGroups.has(g.label));
|
|
22277
|
+
return {
|
|
22278
|
+
parsed: { ...parsed, nodes, edges, groups },
|
|
22279
|
+
collapsedGroupStatuses,
|
|
22280
|
+
originalGroups
|
|
22281
|
+
};
|
|
22282
|
+
}
|
|
22283
|
+
|
|
22284
|
+
// src/index.ts
|
|
21846
22285
|
init_parser8();
|
|
21847
22286
|
init_layout2();
|
|
21848
22287
|
init_renderer2();
|
|
@@ -22100,7 +22539,7 @@ async function resolveFile(content, filePath, readFileFn, diagnostics, ancestorC
|
|
|
22100
22539
|
continue;
|
|
22101
22540
|
}
|
|
22102
22541
|
if (isTagBlockHeading(trimmed)) continue;
|
|
22103
|
-
if (lines[i]
|
|
22542
|
+
if (/^\s/.test(lines[i])) continue;
|
|
22104
22543
|
const tagsMatch = trimmed.match(TAGS_RE);
|
|
22105
22544
|
if (tagsMatch) {
|
|
22106
22545
|
tagsDirective = tagsMatch[1].trim();
|
|
@@ -22339,6 +22778,12 @@ function encodeDiagramUrl(dsl, options) {
|
|
|
22339
22778
|
if (options?.viewState?.swimlaneTagGroup) {
|
|
22340
22779
|
hash += `&swim=${encodeURIComponent(options.viewState.swimlaneTagGroup)}`;
|
|
22341
22780
|
}
|
|
22781
|
+
if (options?.viewState?.palette && options.viewState.palette !== "nord") {
|
|
22782
|
+
hash += `&pal=${encodeURIComponent(options.viewState.palette)}`;
|
|
22783
|
+
}
|
|
22784
|
+
if (options?.viewState?.theme && options.viewState.theme !== "dark") {
|
|
22785
|
+
hash += `&th=${encodeURIComponent(options.viewState.theme)}`;
|
|
22786
|
+
}
|
|
22342
22787
|
return { url: `${baseUrl}?${hash}#${hash}` };
|
|
22343
22788
|
}
|
|
22344
22789
|
function decodeDiagramUrl(hash) {
|
|
@@ -22365,6 +22810,8 @@ function decodeDiagramUrl(hash) {
|
|
|
22365
22810
|
if (key === "swim" && val) {
|
|
22366
22811
|
viewState.swimlaneTagGroup = val;
|
|
22367
22812
|
}
|
|
22813
|
+
if (key === "pal" && val) viewState.palette = val;
|
|
22814
|
+
if (key === "th" && (val === "light" || val === "dark")) viewState.theme = val;
|
|
22368
22815
|
}
|
|
22369
22816
|
if (payload.startsWith("dgmo=")) {
|
|
22370
22817
|
payload = payload.slice(5);
|
|
@@ -22398,6 +22845,7 @@ init_branding();
|
|
|
22398
22845
|
buildRenderSequence,
|
|
22399
22846
|
buildThemeCSS,
|
|
22400
22847
|
catppuccinPalette,
|
|
22848
|
+
collapseInitiativeStatus,
|
|
22401
22849
|
collapseOrgTree,
|
|
22402
22850
|
collapseSitemapTree,
|
|
22403
22851
|
collectDiagramRoles,
|