@diagrammo/dgmo 0.39.0 → 0.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/advanced.cjs +324 -116
- package/dist/advanced.js +324 -116
- package/dist/auto.cjs +325 -117
- package/dist/auto.js +92 -92
- package/dist/auto.mjs +325 -117
- package/dist/cli.cjs +115 -115
- package/dist/index.cjs +502 -171
- package/dist/index.js +502 -171
- package/gallery/fixtures/block.dgmo +16 -0
- package/gallery/fixtures/event-line.dgmo +26 -0
- package/package.json +1 -1
- package/src/diagnostics.ts +0 -0
- package/src/echarts.ts +5 -0
- package/src/error-card.ts +200 -0
- package/src/event-line/parser.ts +91 -1
- package/src/event-line/renderer.ts +350 -139
- package/src/index.ts +7 -30
- package/src/journey-map/renderer.ts +50 -18
package/dist/index.cjs
CHANGED
|
@@ -105,7 +105,7 @@ function vennAliasKeywordRemovedMessage(args) {
|
|
|
105
105
|
return `Venn 'alias' keyword was removed. Use 'as' instead \u2014 '${args.name} as ${args.alias}'.`;
|
|
106
106
|
}
|
|
107
107
|
function pipeOperatorRemovedMessage() {
|
|
108
|
-
return `'|'
|
|
108
|
+
return `'|' is no longer metadata syntax \u2014 write metadata inline as 'key: value' (e.g. "Name color: red"), or remove the '|'.`;
|
|
109
109
|
}
|
|
110
110
|
function ganttBarePercentRemovedMessage(percent) {
|
|
111
111
|
return `Bare-percent progress shorthand '| ${percent}' was removed. Use 'progress: ${percent.replace(/%$/, "")}' (integer 0\u2013100, no '%').`;
|
|
@@ -13609,7 +13609,8 @@ function buildScatterOption(parsed, palette, isDark, textColor, axisLineColor, g
|
|
|
13609
13609
|
solid: parsed.solidFill === true
|
|
13610
13610
|
}),
|
|
13611
13611
|
borderColor: catColor,
|
|
13612
|
-
borderWidth: CHART_BORDER_WIDTH
|
|
13612
|
+
borderWidth: CHART_BORDER_WIDTH,
|
|
13613
|
+
opacity: SCATTER_FILL_OPACITY
|
|
13613
13614
|
},
|
|
13614
13615
|
label: labelConfig,
|
|
13615
13616
|
emphasis: emphasisConfig,
|
|
@@ -13636,6 +13637,7 @@ function buildScatterOption(parsed, palette, isDark, textColor, axisLineColor, g
|
|
|
13636
13637
|
{
|
|
13637
13638
|
type: "scatter",
|
|
13638
13639
|
data,
|
|
13640
|
+
itemStyle: { opacity: SCATTER_FILL_OPACITY },
|
|
13639
13641
|
label: labelConfig,
|
|
13640
13642
|
emphasis: emphasisConfig,
|
|
13641
13643
|
blur: blurConfig
|
|
@@ -14941,7 +14943,7 @@ async function renderExtendedChartForExport(content, theme, palette) {
|
|
|
14941
14943
|
chart.dispose();
|
|
14942
14944
|
}
|
|
14943
14945
|
}
|
|
14944
|
-
var echarts, import_charts, import_components, import_renderers, EMPHASIS_SELF, EMPHASIS_SERIES, BLUR_DIM, EMPHASIS_LINE, CHART_BASE, CHART_BORDER_WIDTH, VALID_EXTENDED_TYPES, KNOWN_EXTENDED_OPTIONS, EXTENDED_CHART_DOORS, FIT_PADDING, OFFSCREEN, fitStackedLabelToSegment, ECHART_EXPORT_WIDTH, ECHART_EXPORT_HEIGHT, STANDARD_CHART_TYPES;
|
|
14946
|
+
var echarts, import_charts, import_components, import_renderers, EMPHASIS_SELF, EMPHASIS_SERIES, BLUR_DIM, EMPHASIS_LINE, CHART_BASE, CHART_BORDER_WIDTH, SCATTER_FILL_OPACITY, VALID_EXTENDED_TYPES, KNOWN_EXTENDED_OPTIONS, EXTENDED_CHART_DOORS, FIT_PADDING, OFFSCREEN, fitStackedLabelToSegment, ECHART_EXPORT_WIDTH, ECHART_EXPORT_HEIGHT, STANDARD_CHART_TYPES;
|
|
14945
14947
|
var init_echarts = __esm({
|
|
14946
14948
|
"src/echarts.ts"() {
|
|
14947
14949
|
"use strict";
|
|
@@ -14999,6 +15001,7 @@ var init_echarts = __esm({
|
|
|
14999
15001
|
tooltip: { show: false }
|
|
15000
15002
|
};
|
|
15001
15003
|
CHART_BORDER_WIDTH = 2;
|
|
15004
|
+
SCATTER_FILL_OPACITY = 0.65;
|
|
15002
15005
|
VALID_EXTENDED_TYPES = /* @__PURE__ */ new Set([
|
|
15003
15006
|
"sankey",
|
|
15004
15007
|
"chord",
|
|
@@ -15274,8 +15277,61 @@ function parseEventLine(content, palette) {
|
|
|
15274
15277
|
EVENT_LINE_DIAGNOSTIC_CODES.NO_EVENTS
|
|
15275
15278
|
);
|
|
15276
15279
|
}
|
|
15280
|
+
if (options.scale) {
|
|
15281
|
+
validateEraDateOrder(result.events, result.eras, pushWarning);
|
|
15282
|
+
}
|
|
15277
15283
|
return result;
|
|
15278
15284
|
}
|
|
15285
|
+
function validateEraDateOrder(events, eras, pushWarning) {
|
|
15286
|
+
if (eras.length < 2) return;
|
|
15287
|
+
const order = new Map(eras.map((e, i) => [e.name, i]));
|
|
15288
|
+
const dated = events.filter(
|
|
15289
|
+
(e) => e.dateValue !== null && e.era !== null && order.has(e.era)
|
|
15290
|
+
);
|
|
15291
|
+
if (dated.length === 0) return;
|
|
15292
|
+
const perEra = /* @__PURE__ */ new Map();
|
|
15293
|
+
for (const ev of dated) {
|
|
15294
|
+
const idx = order.get(ev.era);
|
|
15295
|
+
const cur = perEra.get(idx);
|
|
15296
|
+
if (!cur) {
|
|
15297
|
+
perEra.set(idx, { min: ev, max: ev });
|
|
15298
|
+
} else {
|
|
15299
|
+
if (ev.dateValue < cur.min.dateValue) cur.min = ev;
|
|
15300
|
+
if (ev.dateValue > cur.max.dateValue) cur.max = ev;
|
|
15301
|
+
}
|
|
15302
|
+
}
|
|
15303
|
+
const n = eras.length;
|
|
15304
|
+
const prefixMax = new Array(n).fill(null);
|
|
15305
|
+
const suffixMin = new Array(n).fill(null);
|
|
15306
|
+
for (let k = 1; k < n; k++) {
|
|
15307
|
+
const prev = perEra.get(k - 1)?.max ?? null;
|
|
15308
|
+
const carried = prefixMax[k - 1] ?? null;
|
|
15309
|
+
prefixMax[k] = prev && (!carried || prev.dateValue > carried.dateValue) ? prev : carried;
|
|
15310
|
+
}
|
|
15311
|
+
for (let k = n - 2; k >= 0; k--) {
|
|
15312
|
+
const next = perEra.get(k + 1)?.min ?? null;
|
|
15313
|
+
const carried = suffixMin[k + 1] ?? null;
|
|
15314
|
+
suffixMin[k] = next && (!carried || next.dateValue < carried.dateValue) ? next : carried;
|
|
15315
|
+
}
|
|
15316
|
+
for (const ev of dated) {
|
|
15317
|
+
const k = order.get(ev.era);
|
|
15318
|
+
const ahead = suffixMin[k];
|
|
15319
|
+
const behind = prefixMax[k];
|
|
15320
|
+
if (ahead && ev.dateValue > ahead.dateValue) {
|
|
15321
|
+
pushWarning(
|
|
15322
|
+
ev.lineNumber,
|
|
15323
|
+
`"${ev.label}" (${ev.date}) is in era "${ev.era}" but dated after era "${ahead.era}" begins (${ahead.date}). event-line eras run left-to-right by date \u2014 fix the date or move it to the right era, or their brackets will overlap.`,
|
|
15324
|
+
EVENT_LINE_DIAGNOSTIC_CODES.ERA_DATE_ORDER
|
|
15325
|
+
);
|
|
15326
|
+
} else if (behind && ev.dateValue < behind.dateValue) {
|
|
15327
|
+
pushWarning(
|
|
15328
|
+
ev.lineNumber,
|
|
15329
|
+
`"${ev.label}" (${ev.date}) is in era "${ev.era}" but dated before era "${behind.era}" ends (${behind.date}). event-line eras run left-to-right by date \u2014 fix the date or move it to the right era, or their brackets will overlap.`,
|
|
15330
|
+
EVENT_LINE_DIAGNOSTIC_CODES.ERA_DATE_ORDER
|
|
15331
|
+
);
|
|
15332
|
+
}
|
|
15333
|
+
}
|
|
15334
|
+
}
|
|
15279
15335
|
function parseEventHeader(trimmed, lineNumber, era, aliasMap, diagnostics, pushWarning) {
|
|
15280
15336
|
let date = null;
|
|
15281
15337
|
let dateValue = null;
|
|
@@ -15342,7 +15398,8 @@ var init_parser13 = __esm({
|
|
|
15342
15398
|
EVENT_LINE_DIAGNOSTIC_CODES = {
|
|
15343
15399
|
NO_EVENTS: "E_EVENT_LINE_NO_EVENTS",
|
|
15344
15400
|
BAD_DATE: "E_EVENT_LINE_BAD_DATE",
|
|
15345
|
-
UNSUPPORTED: "E_EVENT_LINE_UNSUPPORTED"
|
|
15401
|
+
UNSUPPORTED: "E_EVENT_LINE_UNSUPPORTED",
|
|
15402
|
+
ERA_DATE_ORDER: "E_EVENT_LINE_ERA_DATE_ORDER"
|
|
15346
15403
|
};
|
|
15347
15404
|
NON_ISO_DATE_RE = /^\d{1,4}[/.]\d/;
|
|
15348
15405
|
SIDE_RE = /^side\s+(above|below|alternate)\b/i;
|
|
@@ -26278,9 +26335,6 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26278
26335
|
const hasExpandedEra = parsed.events.some(
|
|
26279
26336
|
(e) => e.era && eraByName.has(e.era) && !collapsedSet.has(e.era)
|
|
26280
26337
|
);
|
|
26281
|
-
const anyCollapsed = parsed.events.some(
|
|
26282
|
-
(e) => e.era && collapsedSet.has(e.era)
|
|
26283
|
-
);
|
|
26284
26338
|
const sideOpt = parsed.options.side;
|
|
26285
26339
|
const alternate = sideOpt === "alternate";
|
|
26286
26340
|
const eraSide = alternate ? "below" : sideOpt === "above" ? "below" : "above";
|
|
@@ -26347,7 +26401,8 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26347
26401
|
x: 0,
|
|
26348
26402
|
side,
|
|
26349
26403
|
lane: 0,
|
|
26350
|
-
left: 0
|
|
26404
|
+
left: 0,
|
|
26405
|
+
spanHalf: 0
|
|
26351
26406
|
};
|
|
26352
26407
|
}
|
|
26353
26408
|
const era = slot.era;
|
|
@@ -26360,19 +26415,19 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26360
26415
|
palette.textOnFillLight,
|
|
26361
26416
|
palette.textOnFillDark
|
|
26362
26417
|
);
|
|
26363
|
-
|
|
26364
|
-
|
|
26365
|
-
const
|
|
26418
|
+
let spanLo = null;
|
|
26419
|
+
let spanHi = null;
|
|
26420
|
+
for (const m of slot.members) {
|
|
26421
|
+
if (m.dateValue === null) continue;
|
|
26422
|
+
if (spanLo === null || m.dateValue < spanLo) spanLo = m.dateValue;
|
|
26423
|
+
if (spanHi === null || m.dateValue > spanHi) spanHi = m.dateValue;
|
|
26424
|
+
}
|
|
26425
|
+
const repDateValue = spanLo !== null && spanHi !== null ? (spanLo + spanHi) / 2 : null;
|
|
26426
|
+
const memberStrs = slot.members.map(
|
|
26366
26427
|
(m) => `\u2022 ${m.date ? `${m.date} ` : ""}${m.label}`
|
|
26367
26428
|
);
|
|
26368
|
-
const bulletColors =
|
|
26429
|
+
const bulletColors = slot.members.map(eventColor);
|
|
26369
26430
|
const lines = wrapDescription(memberStrs, charsPerLine);
|
|
26370
|
-
if (overflow) {
|
|
26371
|
-
lines.push({
|
|
26372
|
-
text: `+${slot.members.length - (ERA_MEMBER_MAX - 1)} more`,
|
|
26373
|
-
kind: "plain"
|
|
26374
|
-
});
|
|
26375
|
-
}
|
|
26376
26431
|
return {
|
|
26377
26432
|
kind: "era",
|
|
26378
26433
|
event: null,
|
|
@@ -26380,7 +26435,7 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26380
26435
|
members: slot.members,
|
|
26381
26436
|
label: era.name,
|
|
26382
26437
|
date: null,
|
|
26383
|
-
dateValue:
|
|
26438
|
+
dateValue: repDateValue,
|
|
26384
26439
|
lineNumber: era.lineNumber,
|
|
26385
26440
|
eraName: era.name,
|
|
26386
26441
|
color: solid,
|
|
@@ -26392,87 +26447,189 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26392
26447
|
x: 0,
|
|
26393
26448
|
side,
|
|
26394
26449
|
lane: 0,
|
|
26395
|
-
left: 0
|
|
26450
|
+
left: 0,
|
|
26451
|
+
spanHalf: 0
|
|
26396
26452
|
};
|
|
26397
26453
|
});
|
|
26398
|
-
const scaled = parsed.options.scale &&
|
|
26454
|
+
const scaled = parsed.options.scale && placed.every((p) => p.dateValue !== null);
|
|
26399
26455
|
const innerW = width - H_MARGIN * 2;
|
|
26400
|
-
|
|
26401
|
-
|
|
26402
|
-
|
|
26403
|
-
|
|
26404
|
-
|
|
26405
|
-
|
|
26456
|
+
const MIN_DOT_GAP = 16;
|
|
26457
|
+
const STRETCH_CAP = 8;
|
|
26458
|
+
const COLLAPSE_W = 64;
|
|
26459
|
+
const SEG_GAP = 16;
|
|
26460
|
+
const segments = [];
|
|
26461
|
+
let run = [];
|
|
26462
|
+
const flushRun = () => {
|
|
26463
|
+
if (!run.length) return;
|
|
26464
|
+
const ds = run.map((e) => e.dateValue);
|
|
26465
|
+
segments.push({
|
|
26466
|
+
kind: "run",
|
|
26467
|
+
events: run,
|
|
26468
|
+
lo: Math.min(...ds),
|
|
26469
|
+
hi: Math.max(...ds)
|
|
26406
26470
|
});
|
|
26407
|
-
|
|
26408
|
-
|
|
26409
|
-
|
|
26410
|
-
|
|
26411
|
-
|
|
26412
|
-
|
|
26413
|
-
|
|
26471
|
+
run = [];
|
|
26472
|
+
};
|
|
26473
|
+
for (const p of placed) {
|
|
26474
|
+
if (p.kind === "era") {
|
|
26475
|
+
flushRun();
|
|
26476
|
+
segments.push({ kind: "capsule", p });
|
|
26477
|
+
} else {
|
|
26478
|
+
run.push(p);
|
|
26479
|
+
}
|
|
26480
|
+
}
|
|
26481
|
+
flushRun();
|
|
26482
|
+
const totalRunTime = segments.reduce(
|
|
26483
|
+
(s, seg) => s + (seg.kind === "run" ? seg.hi - seg.lo : 0),
|
|
26484
|
+
0
|
|
26485
|
+
);
|
|
26486
|
+
const place = (stretch) => {
|
|
26487
|
+
if (scaled) {
|
|
26488
|
+
const pxPerUnit = totalRunTime > 0 ? innerW * stretch / totalRunTime : 0;
|
|
26489
|
+
let cursor = H_MARGIN;
|
|
26490
|
+
for (const seg of segments) {
|
|
26491
|
+
if (seg.kind === "capsule") {
|
|
26492
|
+
seg.p.x = cursor + COLLAPSE_W / 2;
|
|
26493
|
+
seg.p.spanHalf = COLLAPSE_W / 2;
|
|
26494
|
+
cursor += COLLAPSE_W + SEG_GAP;
|
|
26495
|
+
} else {
|
|
26496
|
+
for (const e of seg.events) {
|
|
26497
|
+
e.x = cursor + (e.dateValue - seg.lo) * pxPerUnit;
|
|
26498
|
+
e.spanHalf = 0;
|
|
26499
|
+
}
|
|
26500
|
+
cursor += (seg.hi - seg.lo) * pxPerUnit + SEG_GAP;
|
|
26501
|
+
}
|
|
26502
|
+
}
|
|
26503
|
+
let prevX = -Infinity;
|
|
26504
|
+
let prevVal = null;
|
|
26505
|
+
for (const p of [...placed].sort((a, b) => a.x - b.x)) {
|
|
26506
|
+
if (p.kind === "era") {
|
|
26507
|
+
prevX = p.x + p.spanHalf;
|
|
26508
|
+
prevVal = null;
|
|
26509
|
+
continue;
|
|
26510
|
+
}
|
|
26511
|
+
if (p.dateValue === prevVal) {
|
|
26512
|
+
p.x = prevX;
|
|
26513
|
+
continue;
|
|
26514
|
+
}
|
|
26515
|
+
if (p.x < prevX + MIN_DOT_GAP) p.x = prevX + MIN_DOT_GAP;
|
|
26516
|
+
prevX = p.x;
|
|
26517
|
+
prevVal = p.dateValue;
|
|
26518
|
+
}
|
|
26519
|
+
} else {
|
|
26520
|
+
placed.forEach((p) => {
|
|
26521
|
+
p.spanHalf = 0;
|
|
26522
|
+
});
|
|
26523
|
+
const n = placed.length;
|
|
26524
|
+
const spacing = n > 1 ? Math.max(MIN_SPACING, innerW / (n - 1)) : 0;
|
|
26525
|
+
placed.forEach((p, i) => {
|
|
26526
|
+
p.x = H_MARGIN + i * spacing;
|
|
26527
|
+
});
|
|
26528
|
+
}
|
|
26529
|
+
for (const side of ["above", "below"]) {
|
|
26530
|
+
const arr = placed.filter((p) => p.side === side).sort((a, b) => a.x - b.x);
|
|
26531
|
+
const laneRight = [];
|
|
26532
|
+
for (let i = 0; i < arr.length; i++) {
|
|
26533
|
+
const p = arr[i];
|
|
26534
|
+
const next = arr[i + 1];
|
|
26535
|
+
const crowdedRight = !!next && next.x - p.x < CARD_W + FAN_GAP;
|
|
26536
|
+
const preferred = crowdedRight ? p.x - CARD_W + CARD_INSET : p.x - CARD_W / 2;
|
|
26537
|
+
const maxLeft = p.x - CARD_INSET;
|
|
26538
|
+
const minLeft = p.x - CARD_W + CARD_INSET;
|
|
26539
|
+
let lane = laneRight.length;
|
|
26540
|
+
let left = Math.max(preferred, minLeft);
|
|
26541
|
+
for (let l = 0; l < laneRight.length; l++) {
|
|
26542
|
+
const want = Math.max(preferred, laneRight[l] + FAN_GAP, minLeft);
|
|
26543
|
+
if (want <= maxLeft) {
|
|
26544
|
+
lane = l;
|
|
26545
|
+
left = want;
|
|
26546
|
+
break;
|
|
26547
|
+
}
|
|
26548
|
+
}
|
|
26549
|
+
p.lane = lane;
|
|
26550
|
+
p.left = Math.max(6, left);
|
|
26551
|
+
laneRight[lane] = p.left + CARD_W;
|
|
26552
|
+
}
|
|
26553
|
+
}
|
|
26554
|
+
};
|
|
26555
|
+
const derive = () => {
|
|
26556
|
+
const contentW2 = Math.max(
|
|
26557
|
+
width,
|
|
26558
|
+
Math.max(...placed.map((p) => p.x + p.spanHalf)) + H_MARGIN,
|
|
26559
|
+
Math.max(...placed.map((p) => p.left + CARD_W)) + 6
|
|
26560
|
+
);
|
|
26561
|
+
const laneOffset = { above: [], below: [] };
|
|
26562
|
+
for (const side of ["above", "below"]) {
|
|
26563
|
+
const laneH = [];
|
|
26564
|
+
for (const p of placed) {
|
|
26565
|
+
if (p.side !== side) continue;
|
|
26566
|
+
laneH[p.lane] = Math.max(laneH[p.lane] ?? 0, p.cardH);
|
|
26567
|
+
}
|
|
26568
|
+
const off = [];
|
|
26569
|
+
let acc = 0;
|
|
26570
|
+
for (let l = 0; l < laneH.length; l++) {
|
|
26571
|
+
off[l] = acc;
|
|
26572
|
+
acc += (laneH[l] ?? 0) + LANE_GAP;
|
|
26414
26573
|
}
|
|
26415
|
-
|
|
26416
|
-
prevX = p.x;
|
|
26417
|
-
prevVal = p.dateValue;
|
|
26574
|
+
laneOffset[side] = off;
|
|
26418
26575
|
}
|
|
26576
|
+
const laneNear2 = (p) => (p.side === "above" ? LEADER_ABOVE : LEADER_BELOW) + (laneOffset[p.side][p.lane] ?? 0);
|
|
26577
|
+
const ext = (side) => Math.max(
|
|
26578
|
+
0,
|
|
26579
|
+
...placed.filter((p) => p.side === side).map((p) => laneNear2(p) + p.cardH)
|
|
26580
|
+
);
|
|
26581
|
+
const dateAbove = placed.some((p) => p.side === "below" && p.date);
|
|
26582
|
+
const dateBelow = placed.some((p) => p.side === "above" && p.date);
|
|
26583
|
+
const contentAbove = Math.max(
|
|
26584
|
+
ext("above"),
|
|
26585
|
+
dateAbove ? DATE_OFFSET + 10 : 0
|
|
26586
|
+
);
|
|
26587
|
+
const contentBelow = Math.max(
|
|
26588
|
+
ext("below"),
|
|
26589
|
+
dateBelow ? DATE_OFFSET + 10 : 0
|
|
26590
|
+
);
|
|
26591
|
+
const aboveExt = contentAbove + (hasExpandedEra && eraSide === "above" ? ERA_BLOCK : 0);
|
|
26592
|
+
const belowExt = contentBelow + (hasExpandedEra && eraSide === "below" ? ERA_BLOCK : 0);
|
|
26593
|
+
const TOP_PAD = 14;
|
|
26594
|
+
const BOT_PAD = 14;
|
|
26595
|
+
const spineY2 = topUsed + TOP_PAD + aboveExt;
|
|
26596
|
+
const eraBaseY2 = eraSide === "above" ? spineY2 - (contentAbove + 14) : spineY2 + (contentBelow + 14);
|
|
26597
|
+
const contentH = spineY2 + belowExt + BOT_PAD;
|
|
26598
|
+
const totalH2 = Math.max(heightHint, contentH);
|
|
26599
|
+
return { contentW: contentW2, contentH, totalH: totalH2, spineY: spineY2, eraBaseY: eraBaseY2, laneNear: laneNear2 };
|
|
26600
|
+
};
|
|
26601
|
+
const envStretch = Number(
|
|
26602
|
+
globalThis.process?.env?.["DGMO_EVT_STRETCH"]
|
|
26603
|
+
);
|
|
26604
|
+
let layout;
|
|
26605
|
+
if (Number.isFinite(envStretch) && envStretch > 0) {
|
|
26606
|
+
place(envStretch);
|
|
26607
|
+
layout = derive();
|
|
26419
26608
|
} else {
|
|
26420
|
-
|
|
26421
|
-
|
|
26422
|
-
|
|
26423
|
-
|
|
26424
|
-
|
|
26425
|
-
|
|
26426
|
-
|
|
26427
|
-
|
|
26428
|
-
|
|
26429
|
-
|
|
26430
|
-
|
|
26431
|
-
|
|
26432
|
-
|
|
26433
|
-
|
|
26434
|
-
|
|
26435
|
-
|
|
26436
|
-
|
|
26437
|
-
let left = Math.max(preferred, minLeft);
|
|
26438
|
-
for (let l = 0; l < laneRight.length; l++) {
|
|
26439
|
-
const want = Math.max(preferred, laneRight[l] + FAN_GAP, minLeft);
|
|
26440
|
-
if (want <= maxLeft) {
|
|
26441
|
-
lane = l;
|
|
26442
|
-
left = want;
|
|
26443
|
-
break;
|
|
26609
|
+
place(1);
|
|
26610
|
+
layout = derive();
|
|
26611
|
+
const panelAspect = width / heightHint;
|
|
26612
|
+
const aspectOf = (l) => l.contentW / l.contentH;
|
|
26613
|
+
if (scaled && layout.contentH > heightHint && aspectOf(layout) < panelAspect) {
|
|
26614
|
+
place(STRETCH_CAP);
|
|
26615
|
+
const capped = derive();
|
|
26616
|
+
if (aspectOf(capped) <= panelAspect) {
|
|
26617
|
+
layout = capped;
|
|
26618
|
+
} else {
|
|
26619
|
+
let loF = 1;
|
|
26620
|
+
let hiF = STRETCH_CAP;
|
|
26621
|
+
for (let it = 0; it < 8; it++) {
|
|
26622
|
+
const mid = (loF + hiF) / 2;
|
|
26623
|
+
place(mid);
|
|
26624
|
+
if (aspectOf(derive()) >= panelAspect) hiF = mid;
|
|
26625
|
+
else loF = mid;
|
|
26444
26626
|
}
|
|
26627
|
+
place(hiF);
|
|
26628
|
+
layout = derive();
|
|
26445
26629
|
}
|
|
26446
|
-
p.lane = lane;
|
|
26447
|
-
p.left = Math.max(6, left);
|
|
26448
|
-
laneRight[lane] = p.left + CARD_W;
|
|
26449
26630
|
}
|
|
26450
26631
|
}
|
|
26451
|
-
const contentW =
|
|
26452
|
-
width,
|
|
26453
|
-
Math.max(...placed.map((p) => p.x)) + H_MARGIN,
|
|
26454
|
-
Math.max(...placed.map((p) => p.left + CARD_W)) + 6
|
|
26455
|
-
);
|
|
26456
|
-
const rowGap = (side) => Math.max(0, ...placed.filter((p) => p.side === side).map((p) => p.cardH)) + LANE_GAP;
|
|
26457
|
-
const rowGapA = rowGap("above");
|
|
26458
|
-
const rowGapB = rowGap("below");
|
|
26459
|
-
const ext = (side) => Math.max(
|
|
26460
|
-
0,
|
|
26461
|
-
...placed.filter((p) => p.side === side).map(
|
|
26462
|
-
(p) => (side === "above" ? LEADER_ABOVE : LEADER_BELOW) + p.lane * (side === "above" ? rowGapA : rowGapB) + p.cardH
|
|
26463
|
-
)
|
|
26464
|
-
);
|
|
26465
|
-
const dateAbove = placed.some((p) => p.side === "below" && p.date);
|
|
26466
|
-
const dateBelow = placed.some((p) => p.side === "above" && p.date);
|
|
26467
|
-
const contentAbove = Math.max(ext("above"), dateAbove ? DATE_OFFSET + 10 : 0);
|
|
26468
|
-
const contentBelow = Math.max(ext("below"), dateBelow ? DATE_OFFSET + 10 : 0);
|
|
26469
|
-
const aboveExt = contentAbove + (hasExpandedEra && eraSide === "above" ? ERA_BLOCK : 0);
|
|
26470
|
-
const belowExt = contentBelow + (hasExpandedEra && eraSide === "below" ? ERA_BLOCK : 0);
|
|
26471
|
-
const TOP_PAD = 14;
|
|
26472
|
-
const BOT_PAD = 14;
|
|
26473
|
-
const spineY = topUsed + TOP_PAD + aboveExt;
|
|
26474
|
-
const eraBaseY = eraSide === "above" ? spineY - (contentAbove + 14) : spineY + (contentBelow + 14);
|
|
26475
|
-
const totalH = Math.max(heightHint, spineY + belowExt + BOT_PAD);
|
|
26632
|
+
const { contentW, totalH, spineY, eraBaseY, laneNear } = layout;
|
|
26476
26633
|
const svg = d3Selection6.select(container).append("svg").attr("width", contentW).attr("height", totalH).attr("viewBox", `0 0 ${contentW} ${totalH}`).attr("preserveAspectRatio", "xMidYMin meet").attr("xmlns", "http://www.w3.org/2000/svg").style("font-family", FONT_FAMILY);
|
|
26477
26634
|
svg.append("rect").attr("width", contentW).attr("height", totalH).attr("fill", palette.bg);
|
|
26478
26635
|
if (showTitle) {
|
|
@@ -26500,12 +26657,11 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26500
26657
|
activeGroup
|
|
26501
26658
|
});
|
|
26502
26659
|
}
|
|
26503
|
-
const
|
|
26504
|
-
const
|
|
26505
|
-
const x1 = Math.max(...xs);
|
|
26660
|
+
const x0 = Math.min(...placed.map((p) => p.x - p.spanHalf));
|
|
26661
|
+
const x1 = Math.max(...placed.map((p) => p.x + p.spanHalf));
|
|
26506
26662
|
svg.append("line").attr("x1", x0 - 20).attr("y1", spineY).attr("x2", x1 + 20).attr("y2", spineY).attr("stroke", palette.text).attr("stroke-width", 2.5).attr("stroke-linecap", "round");
|
|
26507
26663
|
const geo = placed.map((p) => {
|
|
26508
|
-
const near = p.side === "above" ? spineY -
|
|
26664
|
+
const near = p.side === "above" ? spineY - laneNear(p) : spineY + laneNear(p);
|
|
26509
26665
|
const top = p.side === "above" ? near - p.cardH : near;
|
|
26510
26666
|
return { p, near, top };
|
|
26511
26667
|
});
|
|
@@ -26617,7 +26773,7 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26617
26773
|
for (const p of placed) {
|
|
26618
26774
|
if (p.kind === "era") {
|
|
26619
26775
|
const col = p.color;
|
|
26620
|
-
const half = Math.
|
|
26776
|
+
const half = Math.max(16, p.spanHalf);
|
|
26621
26777
|
const spineLeft = x0 - 20;
|
|
26622
26778
|
const spineRight = x1 + 20;
|
|
26623
26779
|
const bx0 = Math.max(spineLeft, p.x - half);
|
|
@@ -26628,6 +26784,11 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26628
26784
|
"d",
|
|
26629
26785
|
`M${bx0},${spineY} L${bx0},${barY} L${bx1},${barY} L${bx1},${spineY}`
|
|
26630
26786
|
).attr("fill", "none").attr("stroke", col).attr("stroke-width", 1.5).attr("stroke-linecap", "round").attr("stroke-linejoin", "round");
|
|
26787
|
+
const breakCx = (bx0 + bx1) / 2;
|
|
26788
|
+
eg.append("line").attr("x1", breakCx - BREAK_GAP / 2).attr("y1", spineY).attr("x2", breakCx + BREAK_GAP / 2).attr("y2", spineY).attr("stroke", palette.bg).attr("stroke-width", 4).attr("stroke-linecap", "butt");
|
|
26789
|
+
for (const d of axisBreakPaths(breakCx, spineY)) {
|
|
26790
|
+
eg.append("path").attr("d", d).attr("fill", "none").attr("stroke", col).attr("stroke-width", 1.25).attr("stroke-linecap", "round").attr("stroke-linejoin", "round").attr("stroke-opacity", 0.85);
|
|
26791
|
+
}
|
|
26631
26792
|
if (onClickItem) {
|
|
26632
26793
|
const ln = p.lineNumber;
|
|
26633
26794
|
eg.style("cursor", "pointer").on("click", () => onClickItem(ln));
|
|
@@ -26661,13 +26822,23 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26661
26822
|
}
|
|
26662
26823
|
const clampX = (v) => Math.max(4, Math.min(contentW - 4, v));
|
|
26663
26824
|
const cap = eraSide === "above" ? 1 : -1;
|
|
26664
|
-
|
|
26665
|
-
|
|
26825
|
+
const drawn = runs.filter((r) => !r.collapsed).map((r) => ({
|
|
26826
|
+
run: r,
|
|
26827
|
+
x0: clampX(r.firstX - ERA_BRACKET_PAD),
|
|
26828
|
+
x1: clampX(r.lastX + ERA_BRACKET_PAD)
|
|
26829
|
+
})).sort((a, b) => a.run.firstX - b.run.firstX);
|
|
26830
|
+
for (let i = 1; i < drawn.length; i++) {
|
|
26831
|
+
const prev = drawn[i - 1];
|
|
26832
|
+
const cur = drawn[i];
|
|
26833
|
+
if (prev.x1 <= cur.x0) continue;
|
|
26834
|
+
const mid = (prev.run.lastX + cur.run.firstX) / 2;
|
|
26835
|
+
prev.x1 = Math.max(prev.run.lastX, Math.min(prev.x1, mid - ERA_SEAM_GAP));
|
|
26836
|
+
cur.x0 = Math.min(cur.run.firstX, Math.max(cur.x0, mid + ERA_SEAM_GAP));
|
|
26837
|
+
}
|
|
26838
|
+
for (const { run: r, x0: x02, x1: x12 } of drawn) {
|
|
26666
26839
|
const neutral = !r.era.color;
|
|
26667
26840
|
const col = neutral ? palette.text : resolveColor(r.era.color, palette) ?? palette.text;
|
|
26668
26841
|
const op = neutral ? 0.5 : 0.85;
|
|
26669
|
-
const x02 = clampX(r.firstX - 14);
|
|
26670
|
-
const x12 = clampX(r.lastX + 14);
|
|
26671
26842
|
const y = eraBaseY;
|
|
26672
26843
|
const eg = svg.append("g").attr("data-era", r.era.name).attr("data-era-collapsed", String(r.collapsed)).attr("data-line-number", r.era.lineNumber);
|
|
26673
26844
|
eg.append("path").attr(
|
|
@@ -26693,6 +26864,22 @@ function renderEventLineForExport(container, parsed, palette, isDark, exportDims
|
|
|
26693
26864
|
tagOverride
|
|
26694
26865
|
);
|
|
26695
26866
|
}
|
|
26867
|
+
function axisBreakPaths(cx, cy) {
|
|
26868
|
+
const HUMPS = 2;
|
|
26869
|
+
const STEPS = 14;
|
|
26870
|
+
const wave = (x0) => {
|
|
26871
|
+
let d = "";
|
|
26872
|
+
for (let i = 0; i <= STEPS; i++) {
|
|
26873
|
+
const t = i / STEPS;
|
|
26874
|
+
const y = cy - BREAK_HALF_H + t * 2 * BREAK_HALF_H;
|
|
26875
|
+
const x = x0 + BREAK_AMP * Math.sin(t * Math.PI * HUMPS);
|
|
26876
|
+
d += `${i === 0 ? "M" : "L"}${x.toFixed(2)},${y.toFixed(2)}`;
|
|
26877
|
+
if (i < STEPS) d += " ";
|
|
26878
|
+
}
|
|
26879
|
+
return d;
|
|
26880
|
+
};
|
|
26881
|
+
return [wave(cx - BREAK_GAP / 2), wave(cx + BREAK_GAP / 2)];
|
|
26882
|
+
}
|
|
26696
26883
|
function wrapDescription(lines, charsPerLine) {
|
|
26697
26884
|
const out = [];
|
|
26698
26885
|
for (const line11 of lines) {
|
|
@@ -26722,7 +26909,7 @@ function renderBody(cardG, lines, bodyColor, palette, startBaseline = CARD_BODY_
|
|
|
26722
26909
|
y += DESC_LINE_H;
|
|
26723
26910
|
}
|
|
26724
26911
|
}
|
|
26725
|
-
var d3Selection6, CARD_W, H_MARGIN, TITLE_AREA, LEGEND_BAND, LEADER_ABOVE, LEADER_BELOW, DESC_FONT, DESC_LINE_H, CARD_PAD, CARD_BODY_TOP, DOT_R, MIN_SPACING, LANE_GAP, NEUTRAL_TAG, CARD_INSET, FAN_GAP, DATE_OFFSET, ERA_BLOCK, ERA_BRACKET_CAP, ERA_LEG, ERA_LABEL_FONT
|
|
26912
|
+
var d3Selection6, CARD_W, H_MARGIN, TITLE_AREA, LEGEND_BAND, LEADER_ABOVE, LEADER_BELOW, DESC_FONT, DESC_LINE_H, CARD_PAD, CARD_BODY_TOP, DOT_R, MIN_SPACING, LANE_GAP, NEUTRAL_TAG, CARD_INSET, FAN_GAP, DATE_OFFSET, ERA_BLOCK, ERA_BRACKET_CAP, ERA_BRACKET_PAD, ERA_SEAM_GAP, BREAK_HALF_H, BREAK_AMP, BREAK_GAP, ERA_LEG, ERA_LABEL_FONT;
|
|
26726
26913
|
var init_renderer = __esm({
|
|
26727
26914
|
"src/event-line/renderer.ts"() {
|
|
26728
26915
|
"use strict";
|
|
@@ -26757,9 +26944,13 @@ var init_renderer = __esm({
|
|
|
26757
26944
|
DATE_OFFSET = 28;
|
|
26758
26945
|
ERA_BLOCK = 30;
|
|
26759
26946
|
ERA_BRACKET_CAP = 8;
|
|
26947
|
+
ERA_BRACKET_PAD = 14;
|
|
26948
|
+
ERA_SEAM_GAP = 3;
|
|
26949
|
+
BREAK_HALF_H = 6;
|
|
26950
|
+
BREAK_AMP = 2.2;
|
|
26951
|
+
BREAK_GAP = 5;
|
|
26760
26952
|
ERA_LEG = 13;
|
|
26761
26953
|
ERA_LABEL_FONT = 11.5;
|
|
26762
|
-
ERA_MEMBER_MAX = 6;
|
|
26763
26954
|
}
|
|
26764
26955
|
});
|
|
26765
26956
|
|
|
@@ -26901,13 +27092,13 @@ function renderVersionControl(container, parsed, palette, isDark, onClickItem, e
|
|
|
26901
27092
|
}
|
|
26902
27093
|
const showTitle = !!parsed.title;
|
|
26903
27094
|
const titleH = showTitle ? TITLE_AREA2 : 0;
|
|
26904
|
-
const
|
|
27095
|
+
const W3 = Math.round(contentW);
|
|
26905
27096
|
const H2 = Math.round(contentH + titleH);
|
|
26906
27097
|
const exportMode = !!exportDims;
|
|
26907
|
-
const svg = d3Selection7.select(container).append("svg").attr("width",
|
|
26908
|
-
svg.append("rect").attr("width",
|
|
27098
|
+
const svg = d3Selection7.select(container).append("svg").attr("width", W3).attr("height", H2).attr("viewBox", `0 0 ${W3} ${H2}`).attr("preserveAspectRatio", "xMidYMin meet").attr("xmlns", "http://www.w3.org/2000/svg").style("font-family", FONT_FAMILY);
|
|
27099
|
+
svg.append("rect").attr("width", W3).attr("height", H2).attr("fill", palette.bg);
|
|
26909
27100
|
if (showTitle) {
|
|
26910
|
-
const t = svg.append("text").attr("class", "chart-title").attr("x",
|
|
27101
|
+
const t = svg.append("text").attr("class", "chart-title").attr("x", W3 / 2).attr("y", TITLE_Y).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-family", FONT_FAMILY).attr("font-size", TITLE_FONT_SIZE).attr("font-weight", TITLE_FONT_WEIGHT).attr("data-line-number", parsed.titleLineNumber ?? 1).text(parsed.title);
|
|
26911
27102
|
if (onClickItem && parsed.titleLineNumber && !exportMode) {
|
|
26912
27103
|
const ln = parsed.titleLineNumber;
|
|
26913
27104
|
t.style("cursor", "pointer").on("click", () => onClickItem(ln));
|
|
@@ -32689,7 +32880,7 @@ function findClearPosition(w, h, points, obstacles) {
|
|
|
32689
32880
|
}
|
|
32690
32881
|
function resolveLabelOverlaps(boxes) {
|
|
32691
32882
|
const MAX_PASSES = 8;
|
|
32692
|
-
const
|
|
32883
|
+
const PAD2 = 4;
|
|
32693
32884
|
for (let pass = 0; pass < MAX_PASSES; pass++) {
|
|
32694
32885
|
let moved = false;
|
|
32695
32886
|
for (let i = 0; i < boxes.length; i++) {
|
|
@@ -32698,8 +32889,8 @@ function resolveLabelOverlaps(boxes) {
|
|
|
32698
32889
|
const b = boxes[j];
|
|
32699
32890
|
const dx = Math.abs(a.cx - b.cx);
|
|
32700
32891
|
const dy = Math.abs(a.cy - b.cy);
|
|
32701
|
-
const overlapX = (a.w + b.w) / 2 +
|
|
32702
|
-
const overlapY = (a.h + b.h) / 2 +
|
|
32892
|
+
const overlapX = (a.w + b.w) / 2 + PAD2 - dx;
|
|
32893
|
+
const overlapY = (a.h + b.h) / 2 + PAD2 - dy;
|
|
32703
32894
|
if (overlapX > 0 && overlapY > 0) {
|
|
32704
32895
|
const shift = overlapY / 2 + 1;
|
|
32705
32896
|
if (a.cy < b.cy) {
|
|
@@ -43078,7 +43269,7 @@ function buildPathD(pts, direction) {
|
|
|
43078
43269
|
function computePortPts(edges, nodeMap, direction) {
|
|
43079
43270
|
const srcPts = /* @__PURE__ */ new Map();
|
|
43080
43271
|
const tgtPts = /* @__PURE__ */ new Map();
|
|
43081
|
-
const
|
|
43272
|
+
const PAD2 = 0.1;
|
|
43082
43273
|
const activeEdges = edges.filter((e) => e.points.length > 0);
|
|
43083
43274
|
const bySource = /* @__PURE__ */ new Map();
|
|
43084
43275
|
for (const e of activeEdges) {
|
|
@@ -43094,7 +43285,7 @@ function computePortPts(edges, nodeMap, direction) {
|
|
|
43094
43285
|
).sort((a, b) => direction === "LR" ? a.t.y - b.t.y : a.t.x - b.t.x);
|
|
43095
43286
|
const n = sorted.length;
|
|
43096
43287
|
for (let i = 0; i < n; i++) {
|
|
43097
|
-
const frac = n === 1 ? 0.5 :
|
|
43288
|
+
const frac = n === 1 ? 0.5 : PAD2 + (1 - 2 * PAD2) * i / (n - 1);
|
|
43098
43289
|
const { e, t } = sorted[i];
|
|
43099
43290
|
const isBackward = direction === "LR" ? t.x < source.x : t.y < source.y;
|
|
43100
43291
|
if (direction === "LR") {
|
|
@@ -43124,7 +43315,7 @@ function computePortPts(edges, nodeMap, direction) {
|
|
|
43124
43315
|
).sort((a, b) => direction === "LR" ? a.s.y - b.s.y : a.s.x - b.s.x);
|
|
43125
43316
|
const n = sorted.length;
|
|
43126
43317
|
for (let i = 0; i < n; i++) {
|
|
43127
|
-
const frac = n === 1 ? 0.5 :
|
|
43318
|
+
const frac = n === 1 ? 0.5 : PAD2 + (1 - 2 * PAD2) * i / (n - 1);
|
|
43128
43319
|
const { e, s } = sorted[i];
|
|
43129
43320
|
const isBackward = direction === "LR" ? target.x < s.x : target.y < s.y;
|
|
43130
43321
|
if (direction === "LR") {
|
|
@@ -52917,6 +53108,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
52917
53108
|
y,
|
|
52918
53109
|
score,
|
|
52919
53110
|
palette,
|
|
53111
|
+
isDark,
|
|
52920
53112
|
SCORE_LABEL_R
|
|
52921
53113
|
);
|
|
52922
53114
|
if (!exportDims) {
|
|
@@ -52948,7 +53140,14 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
52948
53140
|
const allSteps = parsed.phases.length > 0 ? parsed.phases.flatMap((p) => p.steps) : parsed.steps;
|
|
52949
53141
|
for (const pt of layout.curvePoints) {
|
|
52950
53142
|
const step = allSteps[pt.stepIndex];
|
|
52951
|
-
const faceG = renderScoreFace(
|
|
53143
|
+
const faceG = renderScoreFace(
|
|
53144
|
+
curveG,
|
|
53145
|
+
pt.x,
|
|
53146
|
+
pt.y,
|
|
53147
|
+
pt.score,
|
|
53148
|
+
palette,
|
|
53149
|
+
isDark
|
|
53150
|
+
);
|
|
52952
53151
|
addEmotionLabel(faceG, pt, palette);
|
|
52953
53152
|
if (step) {
|
|
52954
53153
|
faceG.attr("data-line-number", step.lineNumber);
|
|
@@ -52974,7 +53173,14 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
52974
53173
|
const pt = layout.curvePoints[0];
|
|
52975
53174
|
const allSteps = parsed.phases.length > 0 ? parsed.phases.flatMap((p) => p.steps) : parsed.steps;
|
|
52976
53175
|
const step = allSteps[pt.stepIndex];
|
|
52977
|
-
const faceG = renderScoreFace(
|
|
53176
|
+
const faceG = renderScoreFace(
|
|
53177
|
+
curveG,
|
|
53178
|
+
pt.x,
|
|
53179
|
+
pt.y,
|
|
53180
|
+
pt.score,
|
|
53181
|
+
palette,
|
|
53182
|
+
isDark
|
|
53183
|
+
);
|
|
52978
53184
|
addEmotionLabel(faceG, pt, palette);
|
|
52979
53185
|
if (step) {
|
|
52980
53186
|
faceG.attr("data-line-number", step.lineNumber);
|
|
@@ -53071,6 +53277,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
53071
53277
|
faceCy,
|
|
53072
53278
|
step.score,
|
|
53073
53279
|
palette,
|
|
53280
|
+
isDark,
|
|
53074
53281
|
COLLAPSED_FACE_R
|
|
53075
53282
|
);
|
|
53076
53283
|
faceG.attr("data-line-number", step.lineNumber);
|
|
@@ -53174,7 +53381,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
53174
53381
|
const fcy = parseFloat(el.attr("data-cy") ?? "0");
|
|
53175
53382
|
el.attr(
|
|
53176
53383
|
"transform",
|
|
53177
|
-
`translate(${fcx},${fcy}) scale(
|
|
53384
|
+
`translate(${fcx},${fcy}) scale(${FACE_HOVER_SCALE}) translate(${-fcx},${-fcy})`
|
|
53178
53385
|
);
|
|
53179
53386
|
} else {
|
|
53180
53387
|
el.attr("transform", null);
|
|
@@ -53220,12 +53427,12 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
53220
53427
|
PADDING2,
|
|
53221
53428
|
Math.min(fcx - bw / 2, layout.totalWidth - PADDING2 - bw)
|
|
53222
53429
|
);
|
|
53223
|
-
const by = Math.max(PADDING2, fcy -
|
|
53430
|
+
const by = Math.max(PADDING2, fcy - FACE_HOVER_R - THOUGHT_GAP - bh);
|
|
53224
53431
|
const scoreColor = scoreToColor(score, palette);
|
|
53225
53432
|
const tintedBg = mix(scoreColor, palette.surface, 20);
|
|
53226
53433
|
const g = overlayG.append("g").attr("class", "journey-thought-hover");
|
|
53227
53434
|
g.append("rect").attr("x", bx).attr("y", by).attr("width", bw).attr("height", bh).attr("rx", CARD_RADIUS).attr("fill", tintedBg).attr("stroke", scoreColor).attr("stroke-width", CARD_STROKE_WIDTH2);
|
|
53228
|
-
g.append("line").attr("x1", fcx).attr("y1", by + bh).attr("x2", fcx).attr("y2", fcy -
|
|
53435
|
+
g.append("line").attr("x1", fcx).attr("y1", by + bh).attr("x2", fcx).attr("y2", fcy - FACE_HOVER_R - 1).attr("stroke", scoreColor).attr("stroke-width", CARD_STROKE_WIDTH2);
|
|
53229
53436
|
const centerX = bx + bw / 2;
|
|
53230
53437
|
for (let i = 0; i < lines.length; i++) {
|
|
53231
53438
|
g.append("text").attr("x", centerX).attr("y", by + THOUGHT_PAD_Y + (i + 1) * THOUGHT_LINE_H - 2).attr("text-anchor", "middle").attr("font-size", THOUGHT_FONT).attr("font-style", "italic").attr("fill", palette.textMuted).text(lines[i]);
|
|
@@ -53468,24 +53675,23 @@ function renderPersonaSilhouette(parent, cx, cy, color, palette, scale = 1) {
|
|
|
53468
53675
|
`M ${cx} ${cy - 12 * s} C ${cx + 10 * s} ${cy - 12 * s}, ${cx + 9 * s} ${cy + 2 * s}, ${cx + 6 * s} ${cy + 6 * s} Q ${cx} ${cy + 9 * s}, ${cx - 6 * s} ${cy + 6 * s} C ${cx - 9 * s} ${cy + 2 * s}, ${cx - 10 * s} ${cy - 12 * s}, ${cx} ${cy - 12 * s} Z`
|
|
53469
53676
|
).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", 1.2);
|
|
53470
53677
|
}
|
|
53471
|
-
function renderScoreFace(parent, cx, cy, score, palette, radius) {
|
|
53678
|
+
function renderScoreFace(parent, cx, cy, score, palette, isDark, radius) {
|
|
53472
53679
|
const r = radius ?? FACE_RADIUS;
|
|
53473
53680
|
const color = scoreToColor(score, palette);
|
|
53474
53681
|
const g = parent.append("g").attr("class", "journey-face").attr("data-cx", cx).attr("data-cy", cy);
|
|
53475
|
-
|
|
53476
|
-
|
|
53477
|
-
|
|
53478
|
-
|
|
53479
|
-
palette.textOnFillDark
|
|
53480
|
-
);
|
|
53682
|
+
const faceFill = shapeFill(palette, color, isDark);
|
|
53683
|
+
g.append("circle").attr("cx", cx).attr("cy", cy).attr("r", r + 1).attr("fill", palette.bg);
|
|
53684
|
+
g.append("circle").attr("cx", cx).attr("cy", cy).attr("r", r).attr("fill", faceFill).attr("stroke", color).attr("stroke-width", 2);
|
|
53685
|
+
const eyeColor = color;
|
|
53481
53686
|
const eyeY = cy - r * 0.15;
|
|
53482
53687
|
const eyeSpacing = r * 0.32;
|
|
53483
53688
|
const eyeR = r * 0.12;
|
|
53484
53689
|
g.append("circle").attr("cx", cx - eyeSpacing).attr("cy", eyeY).attr("r", eyeR).attr("fill", eyeColor);
|
|
53485
53690
|
g.append("circle").attr("cx", cx + eyeSpacing).attr("cy", eyeY).attr("r", eyeR).attr("fill", eyeColor);
|
|
53486
|
-
const
|
|
53487
|
-
const
|
|
53488
|
-
const
|
|
53691
|
+
const mouthW = r * 0.46;
|
|
53692
|
+
const curve = (score - 3) / 2 * r * 0.42;
|
|
53693
|
+
const apexY = cy + r * 0.32;
|
|
53694
|
+
const mouthY = apexY - curve / 2;
|
|
53489
53695
|
g.append("path").attr(
|
|
53490
53696
|
"d",
|
|
53491
53697
|
`M ${cx - mouthW} ${mouthY} Q ${cx} ${mouthY + curve} ${cx + mouthW} ${mouthY}`
|
|
@@ -53556,7 +53762,7 @@ function renderJourneyMapForExport(content, theme, palette) {
|
|
|
53556
53762
|
}
|
|
53557
53763
|
return svgEl.outerHTML;
|
|
53558
53764
|
}
|
|
53559
|
-
var d3, d3Shape10, DIAGRAM_PADDING13, PADDING2, CARD_PADDING_X3, CARD_PADDING_Y3, CARD_HEADER_HEIGHT3, CARD_STROKE_WIDTH2, CARD_META_LINE_HEIGHT3, CARD_GAP_INTERNAL, COLUMN_RADIUS2, COLUMN_HEADER_HEIGHT2, COLUMN_PADDING3, FONT_SIZE_TITLE, FONT_SIZE_PHASE, FONT_SIZE_STEP, FONT_SIZE_META, GRID_LINE_OPACITY, CURVE_STROKE_WIDTH, FACE_RADIUS, DIM_HOVER, TITLE_LINE_HEIGHT, EMOTION_LABEL_MAX_WIDTH, EMOTION_LABEL_FONT_SIZE, ICON_THUMBS_DOWN, ICON_THUMBS_UP, ICON_THOUGHT;
|
|
53765
|
+
var d3, d3Shape10, DIAGRAM_PADDING13, PADDING2, CARD_PADDING_X3, CARD_PADDING_Y3, CARD_HEADER_HEIGHT3, CARD_STROKE_WIDTH2, CARD_META_LINE_HEIGHT3, CARD_GAP_INTERNAL, COLUMN_RADIUS2, COLUMN_HEADER_HEIGHT2, COLUMN_PADDING3, FONT_SIZE_TITLE, FONT_SIZE_PHASE, FONT_SIZE_STEP, FONT_SIZE_META, GRID_LINE_OPACITY, CURVE_STROKE_WIDTH, FACE_RADIUS, FACE_HOVER_SCALE, FACE_HOVER_R, DIM_HOVER, TITLE_LINE_HEIGHT, EMOTION_LABEL_MAX_WIDTH, EMOTION_LABEL_FONT_SIZE, ICON_THUMBS_DOWN, ICON_THUMBS_UP, ICON_THOUGHT;
|
|
53560
53766
|
var init_renderer17 = __esm({
|
|
53561
53767
|
"src/journey-map/renderer.ts"() {
|
|
53562
53768
|
"use strict";
|
|
@@ -53592,6 +53798,8 @@ var init_renderer17 = __esm({
|
|
|
53592
53798
|
GRID_LINE_OPACITY = 0.15;
|
|
53593
53799
|
CURVE_STROKE_WIDTH = 2.5;
|
|
53594
53800
|
FACE_RADIUS = 14;
|
|
53801
|
+
FACE_HOVER_SCALE = 1.5;
|
|
53802
|
+
FACE_HOVER_R = (FACE_RADIUS + 1) * FACE_HOVER_SCALE;
|
|
53595
53803
|
DIM_HOVER = 0.25;
|
|
53596
53804
|
TITLE_LINE_HEIGHT = 16;
|
|
53597
53805
|
EMOTION_LABEL_MAX_WIDTH = 180;
|
|
@@ -56630,7 +56838,7 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
56630
56838
|
const akRef = resolved.regions.some((r) => r.iso === "US-AK") || resolved.pois.some((p) => inAlaska(p.lon, p.lat));
|
|
56631
56839
|
const hiRef = resolved.regions.some((r) => r.iso === "US-HI") || resolved.pois.some((p) => inHawaii(p.lon, p.lat));
|
|
56632
56840
|
if (resolved.projection === "albers-usa" && usLayer && (akRef || hiRef)) {
|
|
56633
|
-
const
|
|
56841
|
+
const PAD2 = 8;
|
|
56634
56842
|
const GAP = 12;
|
|
56635
56843
|
const yB = height - FIT_PAD;
|
|
56636
56844
|
const BW = 8;
|
|
@@ -56673,22 +56881,22 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
56673
56881
|
const f = usLayer.get(iso);
|
|
56674
56882
|
if (!f) return boxX;
|
|
56675
56883
|
const x0 = boxX;
|
|
56676
|
-
const iw = Math.min(iwReq, width - FIT_PAD - x0 - 2 *
|
|
56884
|
+
const iw = Math.min(iwReq, width - FIT_PAD - x0 - 2 * PAD2);
|
|
56677
56885
|
if (iw < 24) return boxX;
|
|
56678
|
-
const xr = x0 + iw + 2 *
|
|
56886
|
+
const xr = x0 + iw + 2 * PAD2;
|
|
56679
56887
|
const floor = coastFloor(x0, xr);
|
|
56680
56888
|
const topGuess = floor > -Infinity ? floor + GAP : yB - height * 0.42;
|
|
56681
56889
|
proj.fitWidth(iw, f);
|
|
56682
56890
|
const bb = (0, import_d3_geo2.geoPath)(proj).bounds(f);
|
|
56683
56891
|
const sh = Number.isFinite(bb[0][0]) ? bb[1][1] - bb[0][1] : iw;
|
|
56684
|
-
const needH = sh + 2 *
|
|
56892
|
+
const needH = sh + 2 * PAD2;
|
|
56685
56893
|
let topFit = topGuess;
|
|
56686
56894
|
const bottom = Math.min(topFit + needH, yB);
|
|
56687
56895
|
if (bottom - topFit < needH) topFit = bottom - needH;
|
|
56688
56896
|
proj.fitExtent(
|
|
56689
56897
|
[
|
|
56690
|
-
[x0 +
|
|
56691
|
-
[xr -
|
|
56898
|
+
[x0 + PAD2, topFit + PAD2],
|
|
56899
|
+
[xr - PAD2, bottom - PAD2]
|
|
56692
56900
|
],
|
|
56693
56901
|
f
|
|
56694
56902
|
);
|
|
@@ -58212,15 +58420,15 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
58212
58420
|
}
|
|
58213
58421
|
}
|
|
58214
58422
|
if (regionLabelGuards.length > 0) {
|
|
58215
|
-
const
|
|
58423
|
+
const PAD2 = 2;
|
|
58216
58424
|
const poiRects = labels.filter((l) => l.poiId !== void 0 && l.hidden !== true).map((l) => {
|
|
58217
58425
|
const w = measureLegendText(l.text, FONT2);
|
|
58218
58426
|
const x = l.anchor === "start" ? l.x : l.anchor === "end" ? l.x - w : l.x - w / 2;
|
|
58219
58427
|
return {
|
|
58220
|
-
x: x -
|
|
58428
|
+
x: x - PAD2,
|
|
58221
58429
|
y: l.y - FONT2,
|
|
58222
|
-
w: w + 2 *
|
|
58223
|
-
h: FONT2 * 1.4 + 2 *
|
|
58430
|
+
w: w + 2 * PAD2,
|
|
58431
|
+
h: FONT2 * 1.4 + 2 * PAD2
|
|
58224
58432
|
};
|
|
58225
58433
|
});
|
|
58226
58434
|
for (const g of regionLabelGuards) {
|
|
@@ -58845,7 +59053,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
58845
59053
|
if (poiLabels.length) {
|
|
58846
59054
|
const patchBlurId = nid("dgmo-map-label-patch-blur");
|
|
58847
59055
|
defs.append("filter").attr("id", patchBlurId).attr("x", "-50%").attr("y", "-50%").attr("width", "200%").attr("height", "200%").append("feGaussianBlur").attr("in", "SourceGraphic").attr("stdDeviation", 2.5);
|
|
58848
|
-
const
|
|
59056
|
+
const PAD2 = 8;
|
|
58849
59057
|
const buildPatch = (labels, maskId, decoCluster) => {
|
|
58850
59058
|
if (!labels.length) return;
|
|
58851
59059
|
const patchMask = defs.append("mask").attr("id", maskId).attr("maskUnits", "userSpaceOnUse").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height);
|
|
@@ -58861,10 +59069,10 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
58861
59069
|
const h = th + 6;
|
|
58862
59070
|
blobs.append("rect").attr("x", cx - w / 2).attr("y", cy - h / 2).attr("width", w).attr("height", h).attr("rx", h / 2).attr("fill", "white");
|
|
58863
59071
|
blobRects.push({
|
|
58864
|
-
x0: cx - w / 2 -
|
|
58865
|
-
y0: cy - h / 2 -
|
|
58866
|
-
x1: cx + w / 2 +
|
|
58867
|
-
y1: cy + h / 2 +
|
|
59072
|
+
x0: cx - w / 2 - PAD2,
|
|
59073
|
+
y0: cy - h / 2 - PAD2,
|
|
59074
|
+
x1: cx + w / 2 + PAD2,
|
|
59075
|
+
y1: cy + h / 2 + PAD2
|
|
58868
59076
|
});
|
|
58869
59077
|
}
|
|
58870
59078
|
const gPatch = svg.append("g").attr("class", "dgmo-map-label-patch").attr("mask", `url(#${maskId})`).style("pointer-events", "none");
|
|
@@ -60282,13 +60490,13 @@ function renderTreemap(container, parsed, palette, isDark, exportDims, options =
|
|
|
60282
60490
|
g.append("text").attr("class", "dgmo-treemap-header-value").attr("x", w - ICON_RESERVE - 4).attr("y", 13).attr("text-anchor", "end").attr("font-size", 10.5).attr("fill", ink).attr("opacity", 0.75).text(valStr);
|
|
60283
60491
|
}
|
|
60284
60492
|
}
|
|
60285
|
-
const
|
|
60493
|
+
const PAD2 = Math.max(4, Math.min(14, Math.floor(Math.min(w, h) / 5)));
|
|
60286
60494
|
const MIN_FS = 7;
|
|
60287
|
-
if (!cell.isContainer && w >= 2 *
|
|
60288
|
-
const maxW = w - 2 *
|
|
60495
|
+
if (!cell.isContainer && w >= 2 * PAD2 + 8 && h >= 2 * PAD2 + 8) {
|
|
60496
|
+
const maxW = w - 2 * PAD2;
|
|
60289
60497
|
const horizMinW = measureText(cell.label, MIN_FS) * 1.06;
|
|
60290
|
-
if (horizMinW > maxW && h > w * 1.25 && h - 2 *
|
|
60291
|
-
drawVerticalLabel(g, cell.label, w, h,
|
|
60498
|
+
if (horizMinW > maxW && h > w * 1.25 && h - 2 * PAD2 > maxW) {
|
|
60499
|
+
drawVerticalLabel(g, cell.label, w, h, PAD2, ink);
|
|
60292
60500
|
if (drillable && w > 30 && h > 22) drawFocusIcon(g, w, ink, 9);
|
|
60293
60501
|
continue;
|
|
60294
60502
|
}
|
|
@@ -60299,8 +60507,8 @@ function renderTreemap(container, parsed, palette, isDark, exportDims, options =
|
|
|
60299
60507
|
const nameOpacity = 0.95 - tg * 0.5;
|
|
60300
60508
|
const vfs = clamp3(Math.round(fs * 0.42), 11, 28);
|
|
60301
60509
|
const valOpacity = Math.max(0.45, nameOpacity - 0.1);
|
|
60302
|
-
let y =
|
|
60303
|
-
g.append("text").attr("class", "dgmo-treemap-label").attr("x",
|
|
60510
|
+
let y = PAD2 + Math.round(fs * 0.78);
|
|
60511
|
+
g.append("text").attr("class", "dgmo-treemap-label").attr("x", PAD2).attr("y", y).attr("font-size", fs).attr("font-weight", 600).attr("fill", ink).attr("opacity", nameOpacity).text(clipLabel(cell.label, maxW, fs));
|
|
60304
60512
|
const valParts = [
|
|
60305
60513
|
opts.noValues ? "" : compactNumber2(cell.value),
|
|
60306
60514
|
opts.noPercent ? "" : formatPct(cell.pctOfRoot)
|
|
@@ -60308,12 +60516,12 @@ function renderTreemap(container, parsed, palette, isDark, exportDims, options =
|
|
|
60308
60516
|
const combined = valParts.join(" \xB7 ");
|
|
60309
60517
|
const nameBaseY = y;
|
|
60310
60518
|
const addLineAt = (text, yy, size, opacity) => {
|
|
60311
|
-
g.append("text").attr("class", "dgmo-treemap-value").attr("x",
|
|
60519
|
+
g.append("text").attr("class", "dgmo-treemap-value").attr("x", PAD2).attr("y", yy).attr("font-size", size).attr("fill", ink).attr("opacity", opacity).text(text);
|
|
60312
60520
|
};
|
|
60313
60521
|
if (combined) {
|
|
60314
60522
|
const fitsW = measureText(combined, vfs) <= maxW;
|
|
60315
60523
|
const valY = y + lineDrop(fs, vfs);
|
|
60316
|
-
const roomBelow = valY + descent(vfs) <= h -
|
|
60524
|
+
const roomBelow = valY + descent(vfs) <= h - PAD2;
|
|
60317
60525
|
if (fitsW && roomBelow) {
|
|
60318
60526
|
addLineAt(combined, valY, vfs, valOpacity);
|
|
60319
60527
|
} else if (fitsW) {
|
|
@@ -60321,24 +60529,24 @@ function renderTreemap(container, parsed, palette, isDark, exportDims, options =
|
|
|
60321
60529
|
const rendered = clipLabel(cell.label, maxW, fs);
|
|
60322
60530
|
const nW = measureText(rendered, fs) * 1.12;
|
|
60323
60531
|
const gap = Math.max(12, Math.round(fs * 0.25));
|
|
60324
|
-
if (
|
|
60325
|
-
g.append("text").attr("class", "dgmo-treemap-value").attr("x",
|
|
60532
|
+
if (PAD2 + nW + gap + measureText(combined, ivfs) <= w - PAD2) {
|
|
60533
|
+
g.append("text").attr("class", "dgmo-treemap-value").attr("x", PAD2 + nW + gap).attr("y", nameBaseY).attr("font-size", ivfs).attr("fill", ink).attr("opacity", valOpacity).text(combined);
|
|
60326
60534
|
}
|
|
60327
60535
|
} else if (valParts.length === 2) {
|
|
60328
60536
|
const d1 = lineDrop(fs, vfs);
|
|
60329
|
-
if (y + d1 + descent(vfs) <= h -
|
|
60537
|
+
if (y + d1 + descent(vfs) <= h - PAD2) {
|
|
60330
60538
|
y += d1;
|
|
60331
60539
|
addLineAt(valParts[0], y, vfs, valOpacity);
|
|
60332
60540
|
}
|
|
60333
60541
|
const pfs = Math.max(10, Math.round(vfs * 0.9));
|
|
60334
60542
|
const d2 = lineDrop(vfs, pfs);
|
|
60335
|
-
if (y + d2 + descent(pfs) <= h -
|
|
60543
|
+
if (y + d2 + descent(pfs) <= h - PAD2) {
|
|
60336
60544
|
y += d2;
|
|
60337
60545
|
addLineAt(valParts[1], y, pfs, valOpacity);
|
|
60338
60546
|
}
|
|
60339
60547
|
} else {
|
|
60340
60548
|
const onlyY = y + lineDrop(fs, vfs);
|
|
60341
|
-
if (onlyY + descent(vfs) <= h -
|
|
60549
|
+
if (onlyY + descent(vfs) <= h - PAD2) {
|
|
60342
60550
|
addLineAt(combined, onlyY, vfs, valOpacity);
|
|
60343
60551
|
}
|
|
60344
60552
|
}
|
|
@@ -68485,6 +68693,144 @@ function decodeDiagramUrl(hash) {
|
|
|
68485
68693
|
init_dgmo_router();
|
|
68486
68694
|
init_palettes();
|
|
68487
68695
|
init_diagnostics();
|
|
68696
|
+
|
|
68697
|
+
// src/error-card.ts
|
|
68698
|
+
init_text_measure();
|
|
68699
|
+
init_fonts();
|
|
68700
|
+
var MONO_FAMILY = "ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace";
|
|
68701
|
+
var W2 = 660;
|
|
68702
|
+
var PAD = 24;
|
|
68703
|
+
var CONTENT_W = W2 - PAD * 2;
|
|
68704
|
+
var MAX_ERRORS = 4;
|
|
68705
|
+
var MONO_CH = 0.6;
|
|
68706
|
+
var CODE_FS = 12.5;
|
|
68707
|
+
function renderErrorCard(errors, source, palette, theme) {
|
|
68708
|
+
const c = palette[theme === "dark" ? "dark" : "light"];
|
|
68709
|
+
const isTransparent = theme === "transparent";
|
|
68710
|
+
const card = c.surface;
|
|
68711
|
+
const codeBg = c.bg;
|
|
68712
|
+
const border = c.border;
|
|
68713
|
+
const danger = c.destructive ?? c.colors.red;
|
|
68714
|
+
const text = c.text;
|
|
68715
|
+
const muted = c.textMuted;
|
|
68716
|
+
const srcLines = source.split("\n");
|
|
68717
|
+
const shown = errors.slice(0, MAX_ERRORS);
|
|
68718
|
+
const overflow = errors.length - shown.length;
|
|
68719
|
+
const parts = [];
|
|
68720
|
+
let y = PAD + 8;
|
|
68721
|
+
parts.push(frownMark(PAD + 14, y + 12, danger));
|
|
68722
|
+
parts.push(
|
|
68723
|
+
`<text x="${PAD + 38}" y="${y + 11}" fill="${text}" font-family="${FONT_FAMILY}" font-size="16" font-weight="700">Couldn't render this diagram</text>`,
|
|
68724
|
+
`<text x="${W2 - PAD}" y="${y + 10}" text-anchor="end" fill="${muted}" font-family="${FONT_FAMILY}" font-size="12" font-weight="600" letter-spacing="0.5">dgmo</text>`
|
|
68725
|
+
);
|
|
68726
|
+
y += 24;
|
|
68727
|
+
const errLabel = errors.length === 1 ? "1 error" : `${errors.length} errors`;
|
|
68728
|
+
parts.push(
|
|
68729
|
+
`<text x="${PAD + 38}" y="${y + 4}" fill="${muted}" font-family="${FONT_FAMILY}" font-size="12.5">${errLabel} \u2014 fix the lines below and re-render</text>`
|
|
68730
|
+
);
|
|
68731
|
+
y += 22;
|
|
68732
|
+
parts.push(
|
|
68733
|
+
`<line x1="${PAD}" y1="${y}" x2="${W2 - PAD}" y2="${y}" stroke="${border}" stroke-width="1"/>`
|
|
68734
|
+
);
|
|
68735
|
+
y += 24;
|
|
68736
|
+
for (const e of shown) {
|
|
68737
|
+
const hasLine = e.line > 0;
|
|
68738
|
+
let msgX = PAD;
|
|
68739
|
+
if (hasLine) {
|
|
68740
|
+
const label = e.column ? `Line ${e.line}:${e.column}` : `Line ${e.line}`;
|
|
68741
|
+
const badgeW = 14 + label.length * 7;
|
|
68742
|
+
parts.push(
|
|
68743
|
+
`<rect x="${PAD}" y="${y - 13}" width="${badgeW}" height="19" rx="4" fill="${danger}"/>`,
|
|
68744
|
+
`<text x="${PAD + badgeW / 2}" y="${y + 1}" text-anchor="middle" fill="${c.bg}" font-family="${FONT_FAMILY}" font-size="11.5" font-weight="700">${escapeXml(label)}</text>`
|
|
68745
|
+
);
|
|
68746
|
+
msgX = PAD + badgeW + 12;
|
|
68747
|
+
}
|
|
68748
|
+
const lines = wrapMessage(e.message, CONTENT_W - (msgX - PAD), CONTENT_W);
|
|
68749
|
+
lines.forEach((line11, i) => {
|
|
68750
|
+
parts.push(
|
|
68751
|
+
`<text x="${i === 0 ? msgX : PAD}" y="${y + 1}" fill="${text}" font-family="${FONT_FAMILY}" font-size="13">${escapeXml(line11)}</text>`
|
|
68752
|
+
);
|
|
68753
|
+
if (i < lines.length - 1) y += 18;
|
|
68754
|
+
});
|
|
68755
|
+
y += 24;
|
|
68756
|
+
const raw = hasLine ? srcLines[e.line - 1] : void 0;
|
|
68757
|
+
if (raw !== void 0 && raw.trim().length > 0) {
|
|
68758
|
+
const gutter = `${e.line}`;
|
|
68759
|
+
const gutterW = gutter.length * CODE_FS * MONO_CH + 16;
|
|
68760
|
+
const codeX = PAD + gutterW;
|
|
68761
|
+
const codeMaxW = CONTENT_W - gutterW - 12;
|
|
68762
|
+
const codeText = truncateText(
|
|
68763
|
+
raw.replace(/\t/g, " "),
|
|
68764
|
+
CODE_FS,
|
|
68765
|
+
codeMaxW
|
|
68766
|
+
);
|
|
68767
|
+
const hasCaret = e.column !== void 0 && e.column > 0;
|
|
68768
|
+
const blockH = hasCaret ? 40 : 26;
|
|
68769
|
+
parts.push(
|
|
68770
|
+
`<rect x="${PAD}" y="${y - 14}" width="${CONTENT_W}" height="${blockH}" rx="5" fill="${codeBg}" stroke="${border}" stroke-width="1"/>`,
|
|
68771
|
+
`<line x1="${codeX - 8}" y1="${y - 14}" x2="${codeX - 8}" y2="${y - 14 + blockH}" stroke="${border}" stroke-width="1"/>`,
|
|
68772
|
+
`<text x="${PAD + 8}" y="${y + 3}" fill="${muted}" font-family="${MONO_FAMILY}" font-size="${CODE_FS}">${escapeXml(gutter)}</text>`,
|
|
68773
|
+
`<text x="${codeX}" y="${y + 3}" fill="${text}" font-family="${MONO_FAMILY}" font-size="${CODE_FS}" xml:space="preserve">${escapeXml(codeText)}</text>`
|
|
68774
|
+
);
|
|
68775
|
+
if (hasCaret) {
|
|
68776
|
+
const caretX = codeX + (e.column - 1) * CODE_FS * MONO_CH;
|
|
68777
|
+
parts.push(
|
|
68778
|
+
`<text x="${caretX}" y="${y + 17}" fill="${danger}" font-family="${MONO_FAMILY}" font-size="${CODE_FS}" font-weight="700">^</text>`
|
|
68779
|
+
);
|
|
68780
|
+
y += 14;
|
|
68781
|
+
}
|
|
68782
|
+
y += 24;
|
|
68783
|
+
}
|
|
68784
|
+
y += 14;
|
|
68785
|
+
}
|
|
68786
|
+
if (overflow > 0) {
|
|
68787
|
+
parts.push(
|
|
68788
|
+
`<text x="${PAD}" y="${y}" fill="${muted}" font-family="${FONT_FAMILY}" font-size="12.5" font-style="italic">+ ${overflow} more error${overflow === 1 ? "" : "s"}</text>`
|
|
68789
|
+
);
|
|
68790
|
+
y += 22;
|
|
68791
|
+
}
|
|
68792
|
+
const height = Math.round(y + PAD - 14);
|
|
68793
|
+
const pageBg = isTransparent ? "" : `<rect width="100%" height="100%" fill="${c.bg}"/>`;
|
|
68794
|
+
return [
|
|
68795
|
+
`<svg xmlns="http://www.w3.org/2000/svg" width="${W2}" height="${height}" viewBox="0 0 ${W2} ${height}" font-family="${FONT_FAMILY}">`,
|
|
68796
|
+
pageBg,
|
|
68797
|
+
`<rect x="0.5" y="0.5" width="${W2 - 1}" height="${height - 1}" rx="10" fill="${card}" stroke="${border}" stroke-width="1"/>`,
|
|
68798
|
+
parts.join(""),
|
|
68799
|
+
`</svg>`
|
|
68800
|
+
].join("");
|
|
68801
|
+
}
|
|
68802
|
+
function wrapMessage(message, firstWidth, fullWidth) {
|
|
68803
|
+
const words = message.split(/\s+/).filter(Boolean);
|
|
68804
|
+
if (words.length === 0) return [""];
|
|
68805
|
+
const lines = [];
|
|
68806
|
+
let cur = "";
|
|
68807
|
+
for (const word of words) {
|
|
68808
|
+
const limit = lines.length === 0 ? firstWidth : fullWidth;
|
|
68809
|
+
const test = cur ? `${cur} ${word}` : word;
|
|
68810
|
+
if (measureText(test, 13) <= limit || !cur) {
|
|
68811
|
+
cur = test;
|
|
68812
|
+
} else {
|
|
68813
|
+
lines.push(cur);
|
|
68814
|
+
cur = word;
|
|
68815
|
+
}
|
|
68816
|
+
}
|
|
68817
|
+
if (cur) lines.push(cur);
|
|
68818
|
+
return lines;
|
|
68819
|
+
}
|
|
68820
|
+
function frownMark(cx, cy, color) {
|
|
68821
|
+
const r = 12;
|
|
68822
|
+
return [
|
|
68823
|
+
`<circle cx="${cx}" cy="${cy}" r="${r}" fill="none" stroke="${color}" stroke-width="2"/>`,
|
|
68824
|
+
`<circle cx="${cx - 4.5}" cy="${cy - 3}" r="1.6" fill="${color}"/>`,
|
|
68825
|
+
`<circle cx="${cx + 4.5}" cy="${cy - 3}" r="1.6" fill="${color}"/>`,
|
|
68826
|
+
`<path d="M ${cx - 5} ${cy + 6} Q ${cx} ${cy + 1} ${cx + 5} ${cy + 6}" fill="none" stroke="${color}" stroke-width="2" stroke-linecap="round"/>`
|
|
68827
|
+
].join("");
|
|
68828
|
+
}
|
|
68829
|
+
function escapeXml(s) {
|
|
68830
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
68831
|
+
}
|
|
68832
|
+
|
|
68833
|
+
// src/index.ts
|
|
68488
68834
|
init_palettes();
|
|
68489
68835
|
|
|
68490
68836
|
// src/themes.ts
|
|
@@ -68824,25 +69170,10 @@ async function render2(text, options) {
|
|
|
68824
69170
|
return result;
|
|
68825
69171
|
}
|
|
68826
69172
|
return {
|
|
68827
|
-
svg:
|
|
69173
|
+
svg: renderErrorCard(errors, text, palette, options?.theme),
|
|
68828
69174
|
diagnostics: result.diagnostics
|
|
68829
69175
|
};
|
|
68830
69176
|
}
|
|
68831
|
-
function renderErrorSvg(errors, palette, theme) {
|
|
68832
|
-
const colors = palette[theme === "dark" ? "dark" : "light"];
|
|
68833
|
-
const bg = theme === "transparent" ? "transparent" : colors.bg;
|
|
68834
|
-
const fg = colors.destructive ?? colors.text;
|
|
68835
|
-
const muted = colors.textMuted ?? colors.text;
|
|
68836
|
-
const lines = errors.slice(0, 5).map((e) => formatDgmoError(e));
|
|
68837
|
-
const height = 60 + lines.length * 20;
|
|
68838
|
-
const body = lines.map(
|
|
68839
|
-
(line11, i) => `<text x="20" y="${60 + i * 20}" fill="${fg}" font-family="ui-monospace, monospace" font-size="12">${escapeXml(line11)}</text>`
|
|
68840
|
-
).join("");
|
|
68841
|
-
return `<svg xmlns="http://www.w3.org/2000/svg" width="640" height="${height}" viewBox="0 0 640 ${height}"><rect width="100%" height="100%" fill="${bg}"/><text x="20" y="34" fill="${muted}" font-family="system-ui, sans-serif" font-size="13" font-weight="600">DGMO parse error</text>${body}</svg>`;
|
|
68842
|
-
}
|
|
68843
|
-
function escapeXml(s) {
|
|
68844
|
-
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
68845
|
-
}
|
|
68846
69177
|
function encodeDiagramUrl2(text, options) {
|
|
68847
69178
|
const internalTheme = options?.theme === "light" || options?.theme === "dark" ? options.theme : void 0;
|
|
68848
69179
|
const result = encodeDiagramUrl(text, {
|