@diagrammo/dgmo 0.34.0 → 0.35.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/.claude/commands/dgmo.md +17 -32
- package/.github/copilot-instructions.md +1 -1
- package/README.md +7 -1
- package/SKILL.md +1 -1
- package/dist/advanced.cjs +462 -465
- package/dist/advanced.d.cts +2 -51
- package/dist/advanced.d.ts +2 -51
- package/dist/advanced.js +462 -466
- package/dist/auto.cjs +463 -142
- package/dist/auto.js +91 -91
- package/dist/auto.mjs +463 -142
- package/dist/cli.cjs +143 -326
- package/dist/index.cjs +462 -141
- package/dist/index.js +462 -141
- package/docs/ai-integration.md +46 -26
- package/docs/language-reference.md +2 -2
- package/package.json +2 -2
- package/src/advanced.ts +0 -12
- package/src/c4/parser.ts +15 -6
- package/src/chart.ts +1 -1
- package/src/class/parser.ts +6 -2
- package/src/cli-banner.ts +2 -3
- package/src/cli.ts +539 -1223
- package/src/cycle/parser.ts +4 -1
- package/src/dgmo-router.ts +16 -2
- package/src/diagnostics.ts +0 -0
- package/src/echarts.ts +5 -1
- package/src/er/parser.ts +5 -1
- package/src/gantt/parser.ts +13 -4
- package/src/graph/flowchart-parser.ts +5 -1
- package/src/graph/state-parser.ts +5 -1
- package/src/infra/parser.ts +10 -6
- package/src/journey-map/parser.ts +5 -2
- package/src/kanban/parser.ts +6 -2
- package/src/map/context-labels.ts +29 -19
- package/src/map/layout.ts +403 -108
- package/src/map/legend-band.ts +28 -0
- package/src/map/parser.ts +13 -4
- package/src/map/renderer.ts +74 -23
- package/src/map/resolver.ts +2 -2
- package/src/org/parser.ts +8 -2
- package/src/pyramid/parser.ts +4 -1
- package/src/raci/parser.ts +4 -1
- package/src/ring/parser.ts +4 -1
- package/src/sequence/parser.ts +6 -3
- package/src/sitemap/parser.ts +12 -3
- package/src/tech-radar/parser.ts +6 -3
- package/src/utils/parsing.ts +2 -2
- package/src/utils/tag-groups.ts +3 -3
- package/src/visualizations/parse.ts +9 -3
- package/src/migrate/data-comma.ts +0 -117
- package/src/migrate/embedded.ts +0 -238
- package/src/migrate/index.ts +0 -295
- package/src/migrate/line-classifier.ts +0 -128
- package/src/migrate/line-transformer.ts +0 -218
package/dist/advanced.cjs
CHANGED
|
@@ -37,6 +37,17 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
37
37
|
function makeDgmoError(line11, message, severity = "error", code) {
|
|
38
38
|
return code !== void 0 ? { line: line11, message, severity, code } : { line: line11, message, severity };
|
|
39
39
|
}
|
|
40
|
+
function dedupeDiagnostics(diagnostics) {
|
|
41
|
+
const seen = /* @__PURE__ */ new Set();
|
|
42
|
+
const out = [];
|
|
43
|
+
for (const d of diagnostics) {
|
|
44
|
+
const key = `${d.line}\0${d.column ?? ""}\0${d.severity}\0${d.code ?? ""}\0${d.message}`;
|
|
45
|
+
if (seen.has(key)) continue;
|
|
46
|
+
seen.add(key);
|
|
47
|
+
out.push(d);
|
|
48
|
+
}
|
|
49
|
+
return out;
|
|
50
|
+
}
|
|
40
51
|
function formatDgmoError(err) {
|
|
41
52
|
return err.line > 0 ? `Line ${err.line}: ${err.message}` : err.message;
|
|
42
53
|
}
|
|
@@ -94,7 +105,7 @@ function vennAliasKeywordRemovedMessage(args) {
|
|
|
94
105
|
return `Venn 'alias' keyword was removed. Use 'as' instead \u2014 '${args.name} as ${args.alias}'.`;
|
|
95
106
|
}
|
|
96
107
|
function pipeOperatorRemovedMessage() {
|
|
97
|
-
return `'|' removed \u2014 'Node | c: red' \u2192 'Node c: red'
|
|
108
|
+
return `'|' removed \u2014 'Node | c: red' \u2192 'Node c: red'`;
|
|
98
109
|
}
|
|
99
110
|
function ganttBarePercentRemovedMessage(percent) {
|
|
100
111
|
return `Bare-percent progress shorthand '| ${percent}' was removed. Use 'progress: ${percent.replace(/%$/, "")}' (integer 0\u2013100, no '%').`;
|
|
@@ -1247,7 +1258,7 @@ var init_parsing = __esm({
|
|
|
1247
1258
|
"no-title",
|
|
1248
1259
|
"no-notes"
|
|
1249
1260
|
]);
|
|
1250
|
-
MULTIPLE_PIPE_ERROR = '
|
|
1261
|
+
MULTIPLE_PIPE_ERROR = "'|' is no longer metadata syntax \u2014 put metadata on the same line as 'key: value, key2: value2' (no pipes), per \xA71.4.";
|
|
1251
1262
|
RESERVED_KEY_RE = /^[A-Za-z][A-Za-z0-9_-]*$/;
|
|
1252
1263
|
AS_ALIAS_RE = /\s+as\s+([A-Za-z][A-Za-z0-9_]{0,11})$/;
|
|
1253
1264
|
POTENTIAL_META_RE = /\b([\w-]+)\s*:/;
|
|
@@ -1428,12 +1439,10 @@ function validateTagValues(entities, tagGroups, pushWarning, suggestFn) {
|
|
|
1428
1439
|
);
|
|
1429
1440
|
if (!isPrefix) {
|
|
1430
1441
|
const defined = group.entries.map((e) => e.value);
|
|
1431
|
-
let msg = `Unknown value '${value}' for tag group '${group.name}'`;
|
|
1442
|
+
let msg = `Unknown value '${value}' for tag group '${group.name}' \u2014 use one of: ${defined.join(", ")}`;
|
|
1432
1443
|
const hint = suggestFn?.(value, defined);
|
|
1433
1444
|
if (hint) {
|
|
1434
1445
|
msg += `. ${hint}`;
|
|
1435
|
-
} else {
|
|
1436
|
-
msg += ` \u2014 defined values: ${defined.join(", ")}`;
|
|
1437
1446
|
}
|
|
1438
1447
|
pushWarning(entity.lineNumber, msg);
|
|
1439
1448
|
}
|
|
@@ -2209,7 +2218,10 @@ function parseVisualizationFull(content, palette) {
|
|
|
2209
2218
|
lineNumber
|
|
2210
2219
|
});
|
|
2211
2220
|
} else {
|
|
2212
|
-
warn(
|
|
2221
|
+
warn(
|
|
2222
|
+
lineNumber,
|
|
2223
|
+
`Unrecognized era entry: "${line11}" \u2014 use '<start> -> <end> Label [color]' (e.g. '1716 -> 1717 Reign').`
|
|
2224
|
+
);
|
|
2213
2225
|
}
|
|
2214
2226
|
continue;
|
|
2215
2227
|
}
|
|
@@ -2237,7 +2249,10 @@ function parseVisualizationFull(content, palette) {
|
|
|
2237
2249
|
lineNumber
|
|
2238
2250
|
});
|
|
2239
2251
|
} else {
|
|
2240
|
-
warn(
|
|
2252
|
+
warn(
|
|
2253
|
+
lineNumber,
|
|
2254
|
+
`Unrecognized marker entry: "${line11}" \u2014 use '<date> Label [color]' (e.g. '1776 Independence').`
|
|
2255
|
+
);
|
|
2241
2256
|
}
|
|
2242
2257
|
continue;
|
|
2243
2258
|
}
|
|
@@ -2915,7 +2930,7 @@ function parseVisualizationFull(content, palette) {
|
|
|
2915
2930
|
result.diagnostics.push(
|
|
2916
2931
|
makeDgmoError(
|
|
2917
2932
|
ov.lineNumber,
|
|
2918
|
-
`Intersection references unknown set or alias "${ref}"`
|
|
2933
|
+
`Intersection references unknown set or alias "${ref}" \u2014 declare the set first on its own line ('Name [as <alias>] [color]', e.g. 'Navigation as nav blue'), then reference it by that name or alias. (\xA716.4)`
|
|
2919
2934
|
)
|
|
2920
2935
|
);
|
|
2921
2936
|
if (!result.error)
|
|
@@ -6298,10 +6313,10 @@ function parseSequenceDgmo(content, palette) {
|
|
|
6298
6313
|
const rawInside = fallbackMatch[1];
|
|
6299
6314
|
const pipeIdx = rawInside.indexOf("|");
|
|
6300
6315
|
const cleanName = rawInside.substring(0, pipeIdx).trim().replace(/\([^)]*\)$/, "").trim();
|
|
6301
|
-
const metaPart = rawInside.substring(pipeIdx).trim();
|
|
6316
|
+
const metaPart = rawInside.substring(pipeIdx).replace(/^\|\s*/, "").trim();
|
|
6302
6317
|
pushError(
|
|
6303
6318
|
lineNumber,
|
|
6304
|
-
`
|
|
6319
|
+
`Metadata goes after the bracket with no pipe \u2014 use '[${cleanName}] ${metaPart}' (e.g. '[Backend] t: Product'), not '[${rawInside.trim()}]'`
|
|
6305
6320
|
);
|
|
6306
6321
|
continue;
|
|
6307
6322
|
}
|
|
@@ -6911,7 +6926,7 @@ function parseSequenceDgmo(content, palette) {
|
|
|
6911
6926
|
}
|
|
6912
6927
|
pushWarning(
|
|
6913
6928
|
lineNumber,
|
|
6914
|
-
`Unexpected line: '${trimmed}'. Expected a message (A -> B), participant, section (== Name ==), or block
|
|
6929
|
+
`Unexpected line: '${trimmed}'. Expected a message ('A -> B' or 'A -label-> B'), participant ('Name' or 'Name is a actor'), note ('note right of A Text'), section ('== Name =='), or block ('if/loop/parallel <label>').`
|
|
6915
6930
|
);
|
|
6916
6931
|
}
|
|
6917
6932
|
if (!hasExplicitChart && result.messages.length === 0) {
|
|
@@ -8073,7 +8088,11 @@ function parseFlowchart(content, palette) {
|
|
|
8073
8088
|
const value = optMatch[2].trim();
|
|
8074
8089
|
if (key === "no-color") {
|
|
8075
8090
|
result.diagnostics.push(
|
|
8076
|
-
makeDgmoError(
|
|
8091
|
+
makeDgmoError(
|
|
8092
|
+
lineNumber,
|
|
8093
|
+
'"no-color" was removed \u2014 node colors are assigned automatically by shape; delete this line.',
|
|
8094
|
+
"warning"
|
|
8095
|
+
)
|
|
8077
8096
|
);
|
|
8078
8097
|
continue;
|
|
8079
8098
|
}
|
|
@@ -8402,7 +8421,11 @@ function parseState(content, palette) {
|
|
|
8402
8421
|
const value = optMatch[2].trim();
|
|
8403
8422
|
if (key === "no-color") {
|
|
8404
8423
|
result.diagnostics.push(
|
|
8405
|
-
makeDgmoError(
|
|
8424
|
+
makeDgmoError(
|
|
8425
|
+
lineNumber,
|
|
8426
|
+
'"no-color" was removed \u2014 state colors are assigned automatically; delete this line.',
|
|
8427
|
+
"warning"
|
|
8428
|
+
)
|
|
8406
8429
|
);
|
|
8407
8430
|
continue;
|
|
8408
8431
|
}
|
|
@@ -8717,7 +8740,7 @@ function parseClassDiagram(content, palette) {
|
|
|
8717
8740
|
result.diagnostics.push(
|
|
8718
8741
|
makeDgmoError(
|
|
8719
8742
|
lineNumber,
|
|
8720
|
-
'"no-auto-color"
|
|
8743
|
+
'"no-auto-color" was removed \u2014 colors are always auto-assigned from the palette; delete this line.',
|
|
8721
8744
|
"warning"
|
|
8722
8745
|
)
|
|
8723
8746
|
);
|
|
@@ -8832,7 +8855,11 @@ function parseClassDiagram(content, palette) {
|
|
|
8832
8855
|
continue;
|
|
8833
8856
|
}
|
|
8834
8857
|
result.diagnostics.push(
|
|
8835
|
-
makeDgmoError(
|
|
8858
|
+
makeDgmoError(
|
|
8859
|
+
lineNumber,
|
|
8860
|
+
`Unexpected line: '${trimmed}'. Classes start uppercase at indent 0 ('Ship'); members are indented and colon-typed ('+ name: string', '+ sail(): void'); relationships are indented arrows ('--|> Vessel'). (\xA710)`,
|
|
8861
|
+
"warning"
|
|
8862
|
+
)
|
|
8836
8863
|
);
|
|
8837
8864
|
}
|
|
8838
8865
|
if (notes.length > 0) {
|
|
@@ -9310,7 +9337,11 @@ function parseERDiagram(content, palette) {
|
|
|
9310
9337
|
continue;
|
|
9311
9338
|
}
|
|
9312
9339
|
result.diagnostics.push(
|
|
9313
|
-
makeDgmoError(
|
|
9340
|
+
makeDgmoError(
|
|
9341
|
+
lineNumber,
|
|
9342
|
+
`Unexpected line: '${trimmed}'. A table is a bare name at indent 0 ('users'); columns are indented and SPACE-separated, no colon ('id int pk'); relationships are indented ('1--* orders'). (\xA79)`,
|
|
9343
|
+
"warning"
|
|
9344
|
+
)
|
|
9314
9345
|
);
|
|
9315
9346
|
}
|
|
9316
9347
|
if (result.tables.length === 0 && !result.error) {
|
|
@@ -9654,7 +9685,10 @@ function parseOrg(content, palette) {
|
|
|
9654
9685
|
const value = metadataMatch[2].trim();
|
|
9655
9686
|
const parent = findMetadataParent(indent, indentStack);
|
|
9656
9687
|
if (!parent) {
|
|
9657
|
-
pushError(
|
|
9688
|
+
pushError(
|
|
9689
|
+
lineNumber,
|
|
9690
|
+
"Metadata 'key: value' must be indented under a node \u2014 no node precedes it."
|
|
9691
|
+
);
|
|
9658
9692
|
} else {
|
|
9659
9693
|
parent.metadata = { ...parent.metadata, [key]: value };
|
|
9660
9694
|
}
|
|
@@ -9672,7 +9706,10 @@ function parseOrg(content, palette) {
|
|
|
9672
9706
|
);
|
|
9673
9707
|
attachNode(node, indent, indentStack, result);
|
|
9674
9708
|
} else {
|
|
9675
|
-
pushError(
|
|
9709
|
+
pushError(
|
|
9710
|
+
lineNumber,
|
|
9711
|
+
"Metadata 'key: value' must be indented under a node \u2014 no node precedes it."
|
|
9712
|
+
);
|
|
9676
9713
|
}
|
|
9677
9714
|
} else {
|
|
9678
9715
|
const node = parseNodeLabel(
|
|
@@ -10021,7 +10058,10 @@ function parseSitemap(content, palette) {
|
|
|
10021
10058
|
if (arrowInfo) {
|
|
10022
10059
|
const source = findParentNode(indent, indentStack);
|
|
10023
10060
|
if (!source) {
|
|
10024
|
-
pushError(
|
|
10061
|
+
pushError(
|
|
10062
|
+
lineNumber,
|
|
10063
|
+
"Arrow '-> target' must be indented under its source page \u2014 no page precedes it."
|
|
10064
|
+
);
|
|
10025
10065
|
} else {
|
|
10026
10066
|
deferredArrows.push({
|
|
10027
10067
|
sourceNode: source,
|
|
@@ -10091,7 +10131,10 @@ function parseSitemap(content, palette) {
|
|
|
10091
10131
|
const value = metadataMatch[2].trim();
|
|
10092
10132
|
const parent = findParentNode(indent, indentStack);
|
|
10093
10133
|
if (!parent) {
|
|
10094
|
-
pushError(
|
|
10134
|
+
pushError(
|
|
10135
|
+
lineNumber,
|
|
10136
|
+
"Metadata 'key: value' must be indented under a page \u2014 no page precedes it."
|
|
10137
|
+
);
|
|
10095
10138
|
} else {
|
|
10096
10139
|
parent.metadata = { ...parent.metadata, [key]: value };
|
|
10097
10140
|
}
|
|
@@ -10111,7 +10154,10 @@ function parseSitemap(content, palette) {
|
|
|
10111
10154
|
const key = normalizeName(node.label);
|
|
10112
10155
|
labelToNode.set(key, node);
|
|
10113
10156
|
} else {
|
|
10114
|
-
pushError(
|
|
10157
|
+
pushError(
|
|
10158
|
+
lineNumber,
|
|
10159
|
+
"Metadata 'key: value' must be indented under a page \u2014 no page precedes it."
|
|
10160
|
+
);
|
|
10115
10161
|
}
|
|
10116
10162
|
} else {
|
|
10117
10163
|
const descResult = tryStripDescriptionKeyword(trimmed);
|
|
@@ -11929,7 +11975,7 @@ function parseChart(content, palette) {
|
|
|
11929
11975
|
result.diagnostics.push(
|
|
11930
11976
|
makeDgmoError(
|
|
11931
11977
|
lineNumber,
|
|
11932
|
-
`'${trimmed}' \u2014 ##
|
|
11978
|
+
`'${trimmed}' removed \u2014 use a bracket container '[${trimmed.replace(/^#+\s*/, "")}]' instead (## headers are no longer supported).`
|
|
11933
11979
|
)
|
|
11934
11980
|
);
|
|
11935
11981
|
continue;
|
|
@@ -12899,7 +12945,11 @@ function parseExtendedChartFull(content, palette) {
|
|
|
12899
12945
|
continue;
|
|
12900
12946
|
}
|
|
12901
12947
|
result.diagnostics.push(
|
|
12902
|
-
makeDgmoError(
|
|
12948
|
+
makeDgmoError(
|
|
12949
|
+
lineNumber,
|
|
12950
|
+
`Unexpected line: '${trimmed}'. Expected a data row ('Label value', space-separated) or a known option.`,
|
|
12951
|
+
"warning"
|
|
12952
|
+
)
|
|
12903
12953
|
);
|
|
12904
12954
|
}
|
|
12905
12955
|
const warn = (line11, message) => {
|
|
@@ -15261,7 +15311,10 @@ function parseKanban(content, palette) {
|
|
|
15261
15311
|
continue;
|
|
15262
15312
|
}
|
|
15263
15313
|
if (!currentColumn) {
|
|
15264
|
-
warn(
|
|
15314
|
+
warn(
|
|
15315
|
+
lineNumber,
|
|
15316
|
+
"Card line found before any column. Declare a column first with '[Column Name]', then indent cards beneath it. (\xA711)"
|
|
15317
|
+
);
|
|
15265
15318
|
continue;
|
|
15266
15319
|
}
|
|
15267
15320
|
if (currentCard && indent > cardBaseIndent) {
|
|
@@ -15400,7 +15453,7 @@ var init_parser13 = __esm({
|
|
|
15400
15453
|
KNOWN_OPTIONS4 = /* @__PURE__ */ new Set(["hide", "active-tag"]);
|
|
15401
15454
|
KNOWN_BOOLEANS3 = /* @__PURE__ */ new Set(["solid-fill", "no-title"]);
|
|
15402
15455
|
REMOVED_BOOLEANS = {
|
|
15403
|
-
"no-auto-color": '"no-auto-color"
|
|
15456
|
+
"no-auto-color": '"no-auto-color" was removed \u2014 colors are always auto-assigned from the palette; delete this line.'
|
|
15404
15457
|
};
|
|
15405
15458
|
}
|
|
15406
15459
|
});
|
|
@@ -15637,7 +15690,7 @@ function parseC4(content, palette) {
|
|
|
15637
15690
|
} else {
|
|
15638
15691
|
pushError(
|
|
15639
15692
|
lineNumber,
|
|
15640
|
-
`"container ${refName}" must be
|
|
15693
|
+
`"container ${refName}" must be indented under a deployment node (e.g. under 'Prod is a deployment-node')`
|
|
15641
15694
|
);
|
|
15642
15695
|
}
|
|
15643
15696
|
continue;
|
|
@@ -15692,7 +15745,10 @@ function parseC4(content, palette) {
|
|
|
15692
15745
|
indent
|
|
15693
15746
|
});
|
|
15694
15747
|
} else {
|
|
15695
|
-
pushError(
|
|
15748
|
+
pushError(
|
|
15749
|
+
lineNumber,
|
|
15750
|
+
`"${sectionType}" must be indented under an element (e.g. under 'Web App is a container')`
|
|
15751
|
+
);
|
|
15696
15752
|
}
|
|
15697
15753
|
continue;
|
|
15698
15754
|
}
|
|
@@ -15719,7 +15775,10 @@ function parseC4(content, palette) {
|
|
|
15719
15775
|
indent
|
|
15720
15776
|
});
|
|
15721
15777
|
} else {
|
|
15722
|
-
pushError(
|
|
15778
|
+
pushError(
|
|
15779
|
+
lineNumber,
|
|
15780
|
+
`Group [${groupName}] must be indented under an element (e.g. under 'Web App is a container')`
|
|
15781
|
+
);
|
|
15723
15782
|
}
|
|
15724
15783
|
continue;
|
|
15725
15784
|
}
|
|
@@ -16049,7 +16108,10 @@ function parseC4(content, palette) {
|
|
|
16049
16108
|
}
|
|
16050
16109
|
desc.push(descResult.text);
|
|
16051
16110
|
} else {
|
|
16052
|
-
pushError(
|
|
16111
|
+
pushError(
|
|
16112
|
+
lineNumber,
|
|
16113
|
+
`Unexpected content: "${trimmed}". Expected an element ('Web App is a container'), a relationship ('-Uses-> Database'), indented metadata ('tech: React'), or a group ('[Backend]'). (\xA78)`
|
|
16114
|
+
);
|
|
16053
16115
|
}
|
|
16054
16116
|
}
|
|
16055
16117
|
finalizeAutoTagColors(result.tagGroups, palette);
|
|
@@ -16111,7 +16173,7 @@ function validateRelationshipTargets(result, knownNames, pushWarning) {
|
|
|
16111
16173
|
for (const el of elements) {
|
|
16112
16174
|
for (const rel of el.relationships) {
|
|
16113
16175
|
if (!knownNames.has(normalizeName(rel.target))) {
|
|
16114
|
-
let msg = `Relationship target "${rel.target}" not found`;
|
|
16176
|
+
let msg = `Relationship target "${rel.target}" not found \u2014 declare it first (e.g. '${rel.target} is a container'), then reference it in the arrow`;
|
|
16115
16177
|
const hint = suggest(normalizeName(rel.target), allNames);
|
|
16116
16178
|
if (hint) msg += `. ${hint}`;
|
|
16117
16179
|
pushWarning(rel.lineNumber, msg, "warning");
|
|
@@ -16139,7 +16201,7 @@ function validateDeploymentRefs(result, knownNames, pushWarning) {
|
|
|
16139
16201
|
for (const node of nodes) {
|
|
16140
16202
|
for (const ref of node.containerRefs) {
|
|
16141
16203
|
if (!knownNames.has(normalizeName(ref))) {
|
|
16142
|
-
let msg = `Deployment reference "container ${ref}" not found`;
|
|
16204
|
+
let msg = `Deployment reference "container ${ref}" not found \u2014 declare the container element first, then reference it under the deployment node`;
|
|
16143
16205
|
const hint = suggest(normalizeName(ref), allNames);
|
|
16144
16206
|
if (hint) msg += `. ${hint}`;
|
|
16145
16207
|
pushWarning(node.lineNumber, msg, "warning");
|
|
@@ -16858,7 +16920,7 @@ function parseInfra(content) {
|
|
|
16858
16920
|
}
|
|
16859
16921
|
warn(
|
|
16860
16922
|
lineNumber,
|
|
16861
|
-
`Invalid tag value '${trimmed}' in tag group '${currentTagGroup.name}'.`
|
|
16923
|
+
`Invalid tag value '${trimmed}' in tag group '${currentTagGroup.name}' \u2014 a value is a bare word with an optional trailing color (e.g. 'Production red'); no ':' or '|'.`
|
|
16862
16924
|
);
|
|
16863
16925
|
continue;
|
|
16864
16926
|
}
|
|
@@ -16931,7 +16993,7 @@ function parseInfra(content) {
|
|
|
16931
16993
|
const n = deprecatedFanout[1];
|
|
16932
16994
|
setError(
|
|
16933
16995
|
lineNumber,
|
|
16934
|
-
`'x${n}' fanout syntax is no longer supported \u2014 use '
|
|
16996
|
+
`'x${n}' fanout syntax is no longer supported \u2014 use 'fanout: ${n}' instead`
|
|
16935
16997
|
);
|
|
16936
16998
|
continue;
|
|
16937
16999
|
}
|
|
@@ -17105,8 +17167,10 @@ function parseInfra(content) {
|
|
|
17105
17167
|
const hint = suggest(key, allKeys);
|
|
17106
17168
|
const valueLooksNumeric = /^[\d.]+%?$/.test(rawVal);
|
|
17107
17169
|
if (hint || valueLooksNumeric) {
|
|
17108
|
-
let msg = `Unknown property '${key}'.`;
|
|
17170
|
+
let msg = `Unknown infra property '${key}'.`;
|
|
17109
17171
|
if (hint) msg += ` ${hint}`;
|
|
17172
|
+
else
|
|
17173
|
+
msg += ` Properties are colon-keyed 'key: value' from the known schema (e.g. latency-ms, max-rps, cache-hit, instances, concurrency).`;
|
|
17110
17174
|
warn(lineNumber, msg);
|
|
17111
17175
|
} else if (!currentNode.isEdge) {
|
|
17112
17176
|
pushDescription(currentNode, trimmed);
|
|
@@ -17117,7 +17181,7 @@ function parseInfra(content) {
|
|
|
17117
17181
|
if (EDGE_ONLY_KEYS.has(key) && !currentNode.isEdge) {
|
|
17118
17182
|
warn(
|
|
17119
17183
|
lineNumber,
|
|
17120
|
-
`Property '${key}'
|
|
17184
|
+
`Property '${key}' belongs on the entry point \u2014 declare it indented under an 'internet' or 'edge' node, not on '${currentNode.label}'.`
|
|
17121
17185
|
);
|
|
17122
17186
|
}
|
|
17123
17187
|
const value = parsePropertyValue(rawVal);
|
|
@@ -17224,7 +17288,7 @@ function parseInfra(content) {
|
|
|
17224
17288
|
}
|
|
17225
17289
|
warn(
|
|
17226
17290
|
lineNumber,
|
|
17227
|
-
currentGroup ? `Unexpected line: '${trimmed}'.
|
|
17291
|
+
currentGroup ? `Unexpected line: '${trimmed}'. Inside a group, indent a component name under the '[Group]'.` : `Unexpected line: '${trimmed}'. Expected a node ('Api Gateway'), a group ('[Backend]'), a tag group ('tag Tier as t'), or an option ('default-rps 100'); node properties go indented under a node as 'key: value'.`
|
|
17228
17292
|
);
|
|
17229
17293
|
}
|
|
17230
17294
|
finishCurrentNode();
|
|
@@ -17600,7 +17664,10 @@ function parseGantt(content, palette) {
|
|
|
17600
17664
|
continue;
|
|
17601
17665
|
}
|
|
17602
17666
|
if (COMMENT_RE.test(line11)) continue;
|
|
17603
|
-
warn(
|
|
17667
|
+
warn(
|
|
17668
|
+
lineNumber,
|
|
17669
|
+
`Unrecognized holiday entry: "${line11}". Use a date '2024-02-19 Presidents Day' or a range '2024-05-27 -> 2024-05-29 Memorial Weekend'. (\xA713.3)`
|
|
17670
|
+
);
|
|
17604
17671
|
continue;
|
|
17605
17672
|
}
|
|
17606
17673
|
}
|
|
@@ -17626,7 +17693,10 @@ function parseGantt(content, palette) {
|
|
|
17626
17693
|
lineNumber
|
|
17627
17694
|
});
|
|
17628
17695
|
} else {
|
|
17629
|
-
warn(
|
|
17696
|
+
warn(
|
|
17697
|
+
lineNumber,
|
|
17698
|
+
`Unrecognized era entry: "${line11}". Use 'YYYY-MM-DD -> YYYY-MM-DD Label [color]' (e.g. '2026-04-06 -> 2026-04-10 Conference purple'). (\xA713.5)`
|
|
17699
|
+
);
|
|
17630
17700
|
}
|
|
17631
17701
|
continue;
|
|
17632
17702
|
}
|
|
@@ -17652,7 +17722,10 @@ function parseGantt(content, palette) {
|
|
|
17652
17722
|
lineNumber
|
|
17653
17723
|
});
|
|
17654
17724
|
} else {
|
|
17655
|
-
warn(
|
|
17725
|
+
warn(
|
|
17726
|
+
lineNumber,
|
|
17727
|
+
`Unrecognized marker entry: "${line11}". Use 'YYYY-MM-DD Label [color]' (e.g. '2026-03-27 Board Review' or '2026-06-15 Release green'). (\xA713.6)`
|
|
17728
|
+
);
|
|
17656
17729
|
}
|
|
17657
17730
|
continue;
|
|
17658
17731
|
}
|
|
@@ -17818,7 +17891,7 @@ function parseGantt(content, palette) {
|
|
|
17818
17891
|
} else {
|
|
17819
17892
|
softError(
|
|
17820
17893
|
lineNumber,
|
|
17821
|
-
`Arrow
|
|
17894
|
+
`Arrow '-> ${content2.name}' has no source task \u2014 indent it under the task it follows (e.g. 'Design 5bd' then indented '-> ${content2.name} 3bd'). (\xA713)`
|
|
17822
17895
|
);
|
|
17823
17896
|
}
|
|
17824
17897
|
}
|
|
@@ -19038,7 +19111,10 @@ function parseMap(content, palette) {
|
|
|
19038
19111
|
function handleTag(trimmed, line11) {
|
|
19039
19112
|
const m = matchTagBlockHeading(trimmed);
|
|
19040
19113
|
if (!m) {
|
|
19041
|
-
pushError(
|
|
19114
|
+
pushError(
|
|
19115
|
+
line11,
|
|
19116
|
+
`Malformed tag declaration: "${trimmed}" \u2014 write 'tag <Group>' (optionally 'tag <Group> as <alias>'), e.g. 'tag Market as m', with indented 'Value color' entries below.`
|
|
19117
|
+
);
|
|
19042
19118
|
return;
|
|
19043
19119
|
}
|
|
19044
19120
|
emitTagLegacyDiagnostic(m, line11, diagnostics);
|
|
@@ -19150,7 +19226,7 @@ function parseMap(content, palette) {
|
|
|
19150
19226
|
if (!pos || pos.kind === "name" && !pos.name) {
|
|
19151
19227
|
pushError(
|
|
19152
19228
|
line11,
|
|
19153
|
-
"route
|
|
19229
|
+
"route needs an origin place \u2014 `route <origin>` then indented legs (`-> dest`); origin may be a city name, IATA code, or `<lat> <lon>`. (\xA724B)"
|
|
19154
19230
|
);
|
|
19155
19231
|
return;
|
|
19156
19232
|
}
|
|
@@ -19213,7 +19289,10 @@ function parseMap(content, palette) {
|
|
|
19213
19289
|
function handleEdges(trimmed, line11) {
|
|
19214
19290
|
const parts = trimmed.split(ARROW_SPLIT);
|
|
19215
19291
|
if (parts.length < 3) {
|
|
19216
|
-
pushError(
|
|
19292
|
+
pushError(
|
|
19293
|
+
line11,
|
|
19294
|
+
`Malformed edge: "${trimmed}" \u2014 an edge is 'A -> B' (or 'A -label-> B', '~>' for arc, '--' undirected), both endpoints non-empty. (\xA724B)`
|
|
19295
|
+
);
|
|
19217
19296
|
return;
|
|
19218
19297
|
}
|
|
19219
19298
|
const endpoints = [];
|
|
@@ -19236,7 +19315,10 @@ function parseMap(content, palette) {
|
|
|
19236
19315
|
const from = endpoints[k];
|
|
19237
19316
|
const to = endpoints[k + 1];
|
|
19238
19317
|
if (!from || !to) {
|
|
19239
|
-
pushError(
|
|
19318
|
+
pushError(
|
|
19319
|
+
line11,
|
|
19320
|
+
`Edge has an empty endpoint: "${trimmed}" \u2014 both sides of the arrow need a place, e.g. 'Paris -> Berlin'. (\xA724B)`
|
|
19321
|
+
);
|
|
19240
19322
|
continue;
|
|
19241
19323
|
}
|
|
19242
19324
|
const isLast = k === links.length - 1;
|
|
@@ -21355,7 +21437,10 @@ function parseTechRadar(content) {
|
|
|
21355
21437
|
}
|
|
21356
21438
|
if (indent === 0 && trimmed.toLowerCase() === "rings") {
|
|
21357
21439
|
if (result.rings.length > 0) {
|
|
21358
|
-
warn(
|
|
21440
|
+
warn(
|
|
21441
|
+
lineNumber,
|
|
21442
|
+
'Duplicate "rings" block \u2014 only the last is kept; merge all ring names into one "rings" block.'
|
|
21443
|
+
);
|
|
21359
21444
|
result.rings = [];
|
|
21360
21445
|
}
|
|
21361
21446
|
inRingsBlock = true;
|
|
@@ -21574,7 +21659,7 @@ function parseTechRadar(content) {
|
|
|
21574
21659
|
result.diagnostics.push(
|
|
21575
21660
|
makeDgmoError(
|
|
21576
21661
|
lineNumber,
|
|
21577
|
-
`Blip "${trimmed}" has no ring
|
|
21662
|
+
`Blip "${trimmed}" has no ring. Put it under a ring section header, or add a colon-keyed ring \u2014 '${trimmed} ring: RingName' (per \xA720).`
|
|
21578
21663
|
)
|
|
21579
21664
|
);
|
|
21580
21665
|
continue;
|
|
@@ -21583,7 +21668,7 @@ function parseTechRadar(content) {
|
|
|
21583
21668
|
if (!trimmed.includes("|") && headerParsed && result.rings.length > 0) {
|
|
21584
21669
|
warn(
|
|
21585
21670
|
lineNumber,
|
|
21586
|
-
`Unrecognized line "${trimmed}".
|
|
21671
|
+
`Unrecognized line "${trimmed}". A quadrant header is 'Name quadrant: <top-left|top-right|bottom-left|bottom-right>' (per \xA720).`
|
|
21587
21672
|
);
|
|
21588
21673
|
}
|
|
21589
21674
|
}
|
|
@@ -21876,7 +21961,10 @@ function parseCycle(content) {
|
|
|
21876
21961
|
currentNode.description.push(descLine);
|
|
21877
21962
|
continue;
|
|
21878
21963
|
}
|
|
21879
|
-
warn(
|
|
21964
|
+
warn(
|
|
21965
|
+
lineNum,
|
|
21966
|
+
`Indented line "${trimmed}" has no step above it \u2014 add a step on a non-indented line first, then indent its details. (\xA721)`
|
|
21967
|
+
);
|
|
21880
21968
|
continue;
|
|
21881
21969
|
}
|
|
21882
21970
|
}
|
|
@@ -22179,7 +22267,7 @@ function parseJourneyMap(content, palette) {
|
|
|
22179
22267
|
if (trimmed.includes("|") || !PHASE_RE.test(trimmed)) {
|
|
22180
22268
|
warn(
|
|
22181
22269
|
lineNumber,
|
|
22182
|
-
"
|
|
22270
|
+
`Step "${trimmed}" sits outside any phase and is ignored \u2014 indent it under a '[Phase]' header (per \xA722).`
|
|
22183
22271
|
);
|
|
22184
22272
|
continue;
|
|
22185
22273
|
}
|
|
@@ -22236,7 +22324,10 @@ function parseJourneyMap(content, palette) {
|
|
|
22236
22324
|
continue;
|
|
22237
22325
|
}
|
|
22238
22326
|
if (indent > 0 && !currentPhase && hasPhases) {
|
|
22239
|
-
warn(
|
|
22327
|
+
warn(
|
|
22328
|
+
lineNumber,
|
|
22329
|
+
`Indented line outside any phase \u2014 add a '[Phase]' header above it, or unindent it to a top-level step. (\xA722)`
|
|
22330
|
+
);
|
|
22240
22331
|
}
|
|
22241
22332
|
}
|
|
22242
22333
|
if (currentStep) {
|
|
@@ -22582,7 +22673,10 @@ function parsePyramid(content) {
|
|
|
22582
22673
|
continue;
|
|
22583
22674
|
}
|
|
22584
22675
|
if (!currentLayer) {
|
|
22585
|
-
warn(
|
|
22676
|
+
warn(
|
|
22677
|
+
lineNum,
|
|
22678
|
+
`Indented description "${trimmed}" has no layer above it \u2014 add a layer name on a non-indented line first. (\xA723)`
|
|
22679
|
+
);
|
|
22586
22680
|
continue;
|
|
22587
22681
|
}
|
|
22588
22682
|
const descLine = trimmed.startsWith("- ") ? `\u2022 ${trimmed.substring(2)}` : trimmed;
|
|
@@ -22756,7 +22850,10 @@ function parseRing(content) {
|
|
|
22756
22850
|
continue;
|
|
22757
22851
|
}
|
|
22758
22852
|
if (!currentLayer) {
|
|
22759
|
-
warn(
|
|
22853
|
+
warn(
|
|
22854
|
+
lineNum,
|
|
22855
|
+
`Indented description "${trimmed}" has no layer above it \u2014 add a layer name on a non-indented line first. (\xA724)`
|
|
22856
|
+
);
|
|
22760
22857
|
continue;
|
|
22761
22858
|
}
|
|
22762
22859
|
const descLine = trimmed.startsWith("- ") ? `\u2022 ${trimmed.substring(2)}` : trimmed;
|
|
@@ -23482,7 +23579,10 @@ function parseRaci(content, palette) {
|
|
|
23482
23579
|
continue;
|
|
23483
23580
|
}
|
|
23484
23581
|
if (bodyStarted) {
|
|
23485
|
-
errorAt(
|
|
23582
|
+
errorAt(
|
|
23583
|
+
lineNumber,
|
|
23584
|
+
`Unexpected line: '${trimmed}'. In the body expect a '[Phase]' header, an indented task name, or an assignment 'Role: A R C I' under a task. (\xA724A)`
|
|
23585
|
+
);
|
|
23486
23586
|
} else {
|
|
23487
23587
|
warn(lineNumber, `Unrecognized directive: '${trimmed}'.`);
|
|
23488
23588
|
}
|
|
@@ -24029,6 +24129,13 @@ function getAllChartTypes() {
|
|
|
24029
24129
|
return chartTypes.map((c) => c.id);
|
|
24030
24130
|
}
|
|
24031
24131
|
function parseDgmo(content) {
|
|
24132
|
+
const result = parseDgmoUndeduped(content);
|
|
24133
|
+
return {
|
|
24134
|
+
diagnostics: dedupeDiagnostics(result.diagnostics),
|
|
24135
|
+
chartType: result.chartType
|
|
24136
|
+
};
|
|
24137
|
+
}
|
|
24138
|
+
function parseDgmoUndeduped(content) {
|
|
24032
24139
|
const chartType = parseDgmoChartType(content);
|
|
24033
24140
|
if (!chartType) {
|
|
24034
24141
|
const colonDiag = detectColonChartType(content);
|
|
@@ -51669,7 +51776,7 @@ function resolveMap(parsed, data) {
|
|
|
51669
51776
|
const hint = suggest(r.name, allNames);
|
|
51670
51777
|
err(
|
|
51671
51778
|
r.lineNumber,
|
|
51672
|
-
`Unknown
|
|
51779
|
+
`Unknown region "${r.name}" \u2014 not a known country or US state.${hint ? " " + hint : ""} Search the exact token with \`dgmo map-search "${r.name}"\` (or the lookup_map_location tool), use an ISO code (e.g. FR, US-CA), or coordinates.`,
|
|
51673
51780
|
"E_MAP_UNKNOWN_SUBDIVISION"
|
|
51674
51781
|
);
|
|
51675
51782
|
continue;
|
|
@@ -51749,7 +51856,7 @@ function resolveMap(parsed, data) {
|
|
|
51749
51856
|
const hint = suggest(name, cityNames);
|
|
51750
51857
|
err(
|
|
51751
51858
|
line11,
|
|
51752
|
-
`Unknown place "${name}"
|
|
51859
|
+
`Unknown place "${name}" \u2014 not in the gazetteer.${hint ? " " + hint : ""} Search the exact token with \`dgmo map-search "${name}"\` (or the lookup_map_location tool), or use coordinates \`poi <lat> <lon>\`.`,
|
|
51753
51860
|
"E_MAP_UNKNOWN_PLACE"
|
|
51754
51861
|
);
|
|
51755
51862
|
return { kind: "miss" };
|
|
@@ -52291,6 +52398,21 @@ function mapLegendBand(legend, opts) {
|
|
|
52291
52398
|
if (height <= 0) return 0;
|
|
52292
52399
|
return mapLegendTop(opts.hasTitle, opts.hasSubtitle) + height + LEGEND_BOTTOM_GAP2;
|
|
52293
52400
|
}
|
|
52401
|
+
function mapLegendBox(legend, opts) {
|
|
52402
|
+
if (!legend) return null;
|
|
52403
|
+
const groups = mapLegendGroups(legend);
|
|
52404
|
+
if (groups.length === 0) return null;
|
|
52405
|
+
const config = mapLegendConfig(groups, opts.mode);
|
|
52406
|
+
const state = { activeGroup: legend.activeGroup };
|
|
52407
|
+
const { width, height } = computeLegendLayout(config, state, opts.width);
|
|
52408
|
+
if (height <= 0 || width <= 0) return null;
|
|
52409
|
+
return {
|
|
52410
|
+
x: (opts.width - width) / 2,
|
|
52411
|
+
y: mapLegendTop(opts.hasTitle, opts.hasSubtitle),
|
|
52412
|
+
width,
|
|
52413
|
+
height
|
|
52414
|
+
};
|
|
52415
|
+
}
|
|
52294
52416
|
var LEGEND_TOP_GAP2, LEGEND_BOTTOM_GAP2;
|
|
52295
52417
|
var init_legend_band = __esm({
|
|
52296
52418
|
"src/map/legend-band.ts"() {
|
|
@@ -52415,6 +52537,8 @@ function placeContextLabels(args) {
|
|
|
52415
52537
|
waterBodies,
|
|
52416
52538
|
countries,
|
|
52417
52539
|
palette,
|
|
52540
|
+
countryTone,
|
|
52541
|
+
waterTone,
|
|
52418
52542
|
project,
|
|
52419
52543
|
collides,
|
|
52420
52544
|
contentPoints,
|
|
@@ -52424,8 +52548,8 @@ function placeContextLabels(args) {
|
|
|
52424
52548
|
const band = tierBand(Math.max(dLonSpan, dLatSpan));
|
|
52425
52549
|
const budget = labelBudget(width, height, band);
|
|
52426
52550
|
if (budget <= 0) return [];
|
|
52427
|
-
const waterColor = mix(palette.colors.blue, palette.textMuted, 50);
|
|
52428
|
-
const countryColor = palette.textMuted;
|
|
52551
|
+
const waterColor = waterTone ?? mix(palette.colors.blue, palette.textMuted, 50);
|
|
52552
|
+
const countryColor = countryTone ?? palette.textMuted;
|
|
52429
52553
|
const haloColor = palette.bg;
|
|
52430
52554
|
const candidates = [];
|
|
52431
52555
|
const center = [width / 2, height / 2];
|
|
@@ -52514,8 +52638,7 @@ function placeContextLabels(args) {
|
|
|
52514
52638
|
)
|
|
52515
52639
|
);
|
|
52516
52640
|
const fontSize = Math.round(FONT + t * (COUNTRY_FONT_MAX - FONT));
|
|
52517
|
-
const
|
|
52518
|
-
const color = fade > 0 ? mix(countryColor, palette.bg, 100 - fade) : countryColor;
|
|
52641
|
+
const color = countryColor;
|
|
52519
52642
|
const text = c.name;
|
|
52520
52643
|
const tw = labelWidth(text, 0, fontSize);
|
|
52521
52644
|
if (tw > w || fontSize + 2 * PADY > h) continue;
|
|
@@ -52609,7 +52732,7 @@ function placeContextLabels(args) {
|
|
|
52609
52732
|
}
|
|
52610
52733
|
return placed;
|
|
52611
52734
|
}
|
|
52612
|
-
var FONT, LINE_HEIGHT, PADX, PADY, WATER_LETTER_SPACING, CONTEXT_PAD, EDGE_CLAMP_MARGIN, EDGE_CLAMP_OVERSHOOT, COUNTRY_FONT_MAX, COUNTRY_SIZE_FRAC_MIN, COUNTRY_SIZE_FRAC_MAX,
|
|
52735
|
+
var FONT, LINE_HEIGHT, PADX, PADY, WATER_LETTER_SPACING, CONTEXT_PAD, EDGE_CLAMP_MARGIN, EDGE_CLAMP_OVERSHOOT, COUNTRY_FONT_MAX, COUNTRY_SIZE_FRAC_MIN, COUNTRY_SIZE_FRAC_MAX, MAX_COUNTRY_POSITIONS, COUNTRY_POS_GRID, COUNTRY_POS_TOPN_MARGIN, KIND_ORDER;
|
|
52613
52736
|
var init_context_labels = __esm({
|
|
52614
52737
|
"src/map/context-labels.ts"() {
|
|
52615
52738
|
"use strict";
|
|
@@ -52626,7 +52749,6 @@ var init_context_labels = __esm({
|
|
|
52626
52749
|
COUNTRY_FONT_MAX = 22;
|
|
52627
52750
|
COUNTRY_SIZE_FRAC_MIN = 0.06;
|
|
52628
52751
|
COUNTRY_SIZE_FRAC_MAX = 0.32;
|
|
52629
|
-
COUNTRY_FADE_MAX = 45;
|
|
52630
52752
|
MAX_COUNTRY_POSITIONS = 4;
|
|
52631
52753
|
COUNTRY_POS_GRID = 5;
|
|
52632
52754
|
COUNTRY_POS_TOPN_MARGIN = 3;
|
|
@@ -52753,36 +52875,23 @@ function countryLabelPositions(args) {
|
|
|
52753
52875
|
return n;
|
|
52754
52876
|
};
|
|
52755
52877
|
const dist2ToCentre = (c) => (c.sx - cx) ** 2 + (c.sy - cy) ** 2;
|
|
52756
|
-
const
|
|
52757
|
-
|
|
52758
|
-
|
|
52759
|
-
|
|
52760
|
-
|
|
52761
|
-
|
|
52762
|
-
|
|
52763
|
-
let bestIdx = 0;
|
|
52764
|
-
let bestMin = -1;
|
|
52765
|
-
for (let k = 0; k < pool.length; k++) {
|
|
52766
|
-
const c = pool[k];
|
|
52767
|
-
let minD = Infinity;
|
|
52768
|
-
for (const o of ordered) {
|
|
52769
|
-
const d = (c.sx - o.sx) ** 2 + (c.sy - o.sy) ** 2;
|
|
52770
|
-
if (d < minD) minD = d;
|
|
52771
|
-
}
|
|
52772
|
-
if (minD > bestMin) {
|
|
52773
|
-
bestMin = minD;
|
|
52774
|
-
bestIdx = k;
|
|
52775
|
-
}
|
|
52878
|
+
const centreLon = kept.reduce((s, c) => s + c.lon, 0) / kept.length;
|
|
52879
|
+
const centreLat = kept.reduce((s, c) => s + c.lat, 0) / kept.length;
|
|
52880
|
+
const centreScreen = project(centreLon, centreLat);
|
|
52881
|
+
const lead = pointInGeometry(geometry, centreLon, centreLat) && centreScreen && Number.isFinite(centreScreen[0]) && Number.isFinite(centreScreen[1]) && centreScreen[0] >= 0 && centreScreen[0] <= width && centreScreen[1] >= 0 && centreScreen[1] <= height ? [
|
|
52882
|
+
{
|
|
52883
|
+
lonLat: [centreLon, centreLat],
|
|
52884
|
+
screen: [centreScreen[0], centreScreen[1]]
|
|
52776
52885
|
}
|
|
52777
|
-
|
|
52778
|
-
|
|
52779
|
-
|
|
52886
|
+
] : [];
|
|
52887
|
+
const grid = [...kept].sort(
|
|
52888
|
+
(a, b) => interiorness(b) - interiorness(a) || dist2ToCentre(a) - dist2ToCentre(b)
|
|
52889
|
+
).map((c) => ({
|
|
52780
52890
|
lonLat: [c.lon, c.lat],
|
|
52781
52891
|
screen: [c.sx, c.sy]
|
|
52782
52892
|
}));
|
|
52783
52893
|
const curatedPos = curated ? mkCurated(curated, project) : [];
|
|
52784
|
-
|
|
52785
|
-
return out;
|
|
52894
|
+
return [...curatedPos, ...lead, ...grid].slice(0, MAX_COUNTRY_POSITIONS);
|
|
52786
52895
|
}
|
|
52787
52896
|
function mkCurated(curated, project) {
|
|
52788
52897
|
if (!curated) return [];
|
|
@@ -53048,6 +53157,25 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
53048
53157
|
palette.bg,
|
|
53049
53158
|
mutedBasemap ? isDark ? MUTED_FOREIGN_DARK : MUTED_FOREIGN_LIGHT : isDark ? FOREIGN_TINT_DARK : FOREIGN_TINT_LIGHT
|
|
53050
53159
|
);
|
|
53160
|
+
const contrastFloorTone = (tone, ...substrates) => {
|
|
53161
|
+
const clears = (t) => substrates.every((s) => contrastRatio(t, s) >= REGION_LABEL_HALO_RATIO);
|
|
53162
|
+
if (clears(tone)) return tone;
|
|
53163
|
+
for (let s = 10; s <= 100; s += 10) {
|
|
53164
|
+
const t = mix(palette.text, tone, s);
|
|
53165
|
+
if (clears(t)) return t;
|
|
53166
|
+
}
|
|
53167
|
+
return palette.text;
|
|
53168
|
+
};
|
|
53169
|
+
const backdropLandTone = contrastFloorTone(
|
|
53170
|
+
palette.textMuted,
|
|
53171
|
+
neutralFill,
|
|
53172
|
+
water
|
|
53173
|
+
);
|
|
53174
|
+
const backdropWaterTone = contrastFloorTone(
|
|
53175
|
+
mix(palette.colors.blue, palette.textMuted, 50),
|
|
53176
|
+
water,
|
|
53177
|
+
neutralFill
|
|
53178
|
+
);
|
|
53051
53179
|
const hasDirectColor = resolved.regions.some((r) => r.color !== void 0);
|
|
53052
53180
|
const colorizeActive = resolved.directives.noColorize !== true && !hasRamp && !hasDirectColor && fillGroupNames.size === 0;
|
|
53053
53181
|
const colorByIso = /* @__PURE__ */ new Map();
|
|
@@ -53162,6 +53290,33 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
53162
53290
|
hasSubtitle: Boolean(resolved.subtitle)
|
|
53163
53291
|
});
|
|
53164
53292
|
if (legendBand > topPad) topPad = legendBand;
|
|
53293
|
+
const topReserved = [];
|
|
53294
|
+
if (shownTitle) {
|
|
53295
|
+
const lines = resolved.subtitle ? 2 : 1;
|
|
53296
|
+
const tw = Math.max(
|
|
53297
|
+
measureLegendText(shownTitle, TITLE_FONT_SIZE),
|
|
53298
|
+
resolved.subtitle ? measureLegendText(resolved.subtitle, TITLE_FONT_SIZE) : 0
|
|
53299
|
+
) + 2 * TITLE_FONT_SIZE;
|
|
53300
|
+
topReserved.push({
|
|
53301
|
+
x: width / 2 - tw / 2,
|
|
53302
|
+
y: TITLE_Y - TITLE_FONT_SIZE,
|
|
53303
|
+
w: tw,
|
|
53304
|
+
h: TITLE_FONT_SIZE * (lines + 0.5)
|
|
53305
|
+
});
|
|
53306
|
+
}
|
|
53307
|
+
const legendBox = mapLegendBox(legend, {
|
|
53308
|
+
width,
|
|
53309
|
+
mode: opts.legendMode ?? "preview",
|
|
53310
|
+
hasTitle: Boolean(shownTitle),
|
|
53311
|
+
hasSubtitle: Boolean(resolved.subtitle)
|
|
53312
|
+
});
|
|
53313
|
+
if (legendBox)
|
|
53314
|
+
topReserved.push({
|
|
53315
|
+
x: legendBox.x,
|
|
53316
|
+
y: legendBox.y,
|
|
53317
|
+
w: legendBox.width,
|
|
53318
|
+
h: legendBox.height
|
|
53319
|
+
});
|
|
53165
53320
|
const reserve = opts._calloutReserve;
|
|
53166
53321
|
const fitLeft = FIT_PAD + (reserve?.left ?? 0);
|
|
53167
53322
|
const fitRight = width - FIT_PAD - (reserve?.right ?? 0);
|
|
@@ -53891,6 +54046,19 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
53891
54046
|
const by = b.cy - (b.cy - py) / tb * trimB;
|
|
53892
54047
|
return `M${ax},${ay}Q${px},${py} ${bx},${by}`;
|
|
53893
54048
|
};
|
|
54049
|
+
const legLabelPoint = (a, b, curved, offset) => {
|
|
54050
|
+
const mx = (a.cx + b.cx) / 2;
|
|
54051
|
+
const my = (a.cy + b.cy) / 2;
|
|
54052
|
+
if (!curved && offset === 0) return { x: mx, y: my - 4 };
|
|
54053
|
+
const dx = b.cx - a.cx;
|
|
54054
|
+
const dy = b.cy - a.cy;
|
|
54055
|
+
const len = Math.hypot(dx, dy) || 1;
|
|
54056
|
+
const nx = -dy / len;
|
|
54057
|
+
const ny = dx / len;
|
|
54058
|
+
const bow = offset !== 0 ? offset : len * ARC_CURVE_FRAC;
|
|
54059
|
+
const off = bow * 0.5 + Math.sign(bow || 1) * 8;
|
|
54060
|
+
return { x: mx + nx * off, y: my + ny * off };
|
|
54061
|
+
};
|
|
53894
54062
|
const routeLegVals = resolved.routes.flatMap((rt) => rt.legs).map((l) => Number(l.value)).filter((n) => Number.isFinite(n) && n > 0);
|
|
53895
54063
|
const rlMin = routeLegVals.length ? Math.min(...routeLegVals) : 0;
|
|
53896
54064
|
const rlMax = routeLegVals.length ? Math.max(...routeLegVals) : 0;
|
|
@@ -53904,13 +54072,12 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
53904
54072
|
const a = poiScreen.get(leg.fromId);
|
|
53905
54073
|
const b = poiScreen.get(leg.toId);
|
|
53906
54074
|
if (!a || !b) continue;
|
|
53907
|
-
const
|
|
53908
|
-
const my = (a.cy + b.cy) / 2;
|
|
54075
|
+
const lp = legLabelPoint(a, b, leg.style === "arc", 0);
|
|
53909
54076
|
const bow = {
|
|
53910
54077
|
curved: leg.style === "arc",
|
|
53911
54078
|
offset: 0,
|
|
53912
|
-
labelX:
|
|
53913
|
-
labelY:
|
|
54079
|
+
labelX: lp.x,
|
|
54080
|
+
labelY: lp.y
|
|
53914
54081
|
};
|
|
53915
54082
|
const routeLabelStyle = leg.label !== void 0 ? labelOnFill(fillAt(bow.labelX, bow.labelY)) : void 0;
|
|
53916
54083
|
legs.push({
|
|
@@ -53957,13 +54124,13 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
53957
54124
|
const b = poiScreen.get(e.toId);
|
|
53958
54125
|
if (!a || !b) return;
|
|
53959
54126
|
const fanOffset = n > 1 ? (i - (n - 1) / 2) * FAN_STEP : 0;
|
|
53960
|
-
const
|
|
53961
|
-
const
|
|
54127
|
+
const curved = e.style === "arc" || n > 1;
|
|
54128
|
+
const lp = legLabelPoint(a, b, curved, fanOffset);
|
|
53962
54129
|
const bow = {
|
|
53963
|
-
curved
|
|
54130
|
+
curved,
|
|
53964
54131
|
offset: fanOffset,
|
|
53965
|
-
labelX:
|
|
53966
|
-
labelY:
|
|
54132
|
+
labelX: lp.x,
|
|
54133
|
+
labelY: lp.y
|
|
53967
54134
|
};
|
|
53968
54135
|
const edgeLabelStyle = e.label !== void 0 ? labelOnFill(fillAt(bow.labelX, bow.labelY)) : void 0;
|
|
53969
54136
|
legs.push({
|
|
@@ -53987,7 +54154,7 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
53987
54154
|
});
|
|
53988
54155
|
}
|
|
53989
54156
|
const labels = [];
|
|
53990
|
-
const obstacles = [];
|
|
54157
|
+
const obstacles = [...topReserved];
|
|
53991
54158
|
const regionLabelGuards = [];
|
|
53992
54159
|
const markers = pois.map((p) => ({
|
|
53993
54160
|
cx: p.cx,
|
|
@@ -54025,6 +54192,7 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
54025
54192
|
}
|
|
54026
54193
|
const collides = (rect) => markers.some((m) => rectCircleOverlap(rect, m)) || obstacles.some((o) => rectsOverlap(rect, o)) || legSegments.some((s) => segmentRectOverlap(s[0], s[1], s[2], s[3], rect));
|
|
54027
54194
|
const showRegionLabels = resolved.directives.noRegionLabels !== true;
|
|
54195
|
+
const labeledRegionIds = /* @__PURE__ */ new Set();
|
|
54028
54196
|
const showRegionValues = resolved.directives.noRegionValue !== true && activeIsScore;
|
|
54029
54197
|
const regionValueStr = (value) => showRegionValues && value !== void 0 ? compactNumber(value) : void 0;
|
|
54030
54198
|
const isCompact = width < COMPACT_WIDTH_PX;
|
|
@@ -54045,7 +54213,9 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
54045
54213
|
const REGION_FONT_MAX_ORIENT = 22;
|
|
54046
54214
|
const REGION_SIZE_FRAC_MIN = 0.06;
|
|
54047
54215
|
const REGION_SIZE_FRAC_MAX = 0.32;
|
|
54048
|
-
const
|
|
54216
|
+
const SUBJECT_FONT_MAX = 18;
|
|
54217
|
+
const SUBJECT_MIN_PROMINENCE = 13;
|
|
54218
|
+
const SUBJECT_LEADER_FONT = 15;
|
|
54049
54219
|
const canvasLinear = Math.sqrt(Math.max(1, width * height));
|
|
54050
54220
|
const sizeT = (boxW, boxH) => {
|
|
54051
54221
|
const frac = Math.sqrt(Math.max(0, boxW * boxH)) / canvasLinear;
|
|
@@ -54057,9 +54227,9 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
54057
54227
|
)
|
|
54058
54228
|
);
|
|
54059
54229
|
};
|
|
54060
|
-
const pushRegionLabel = (x, y, text, fill2, lineNumber, valueLine, fontSize = FONT2,
|
|
54230
|
+
const pushRegionLabel = (x, y, text, fill2, lineNumber, valueLine, fontSize = FONT2, colorOverride) => {
|
|
54061
54231
|
const { color: baseColor, haloColor } = labelOnFill(fill2);
|
|
54062
|
-
const color =
|
|
54232
|
+
const color = colorOverride ?? baseColor;
|
|
54063
54233
|
const vf = Math.round(fontSize * 0.82);
|
|
54064
54234
|
const halfW = Math.max(
|
|
54065
54235
|
measureLegendText(text, fontSize),
|
|
@@ -54074,7 +54244,11 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
54074
54244
|
text,
|
|
54075
54245
|
anchor: "middle",
|
|
54076
54246
|
color,
|
|
54077
|
-
|
|
54247
|
+
// A backdrop label (colorOverride) NEVER haloes: the placement gate above
|
|
54248
|
+
// guarantees it sits on a floored-readable substrate (own fill, neutral
|
|
54249
|
+
// land, foreign land, or water), so a halo is pure noise. Data labels keep
|
|
54250
|
+
// the containment-gated halo until the role-tier pass (Phase 3).
|
|
54251
|
+
halo: colorOverride ? false : overflows,
|
|
54078
54252
|
haloColor,
|
|
54079
54253
|
...fontSize !== FONT2 && { fontSize },
|
|
54080
54254
|
...valueLine !== void 0 && { valueLine },
|
|
@@ -54110,7 +54284,7 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
54110
54284
|
if (!c || !Number.isFinite(c[0])) return null;
|
|
54111
54285
|
return { r, c, boxW, boxH, area: boxW * boxH, candidates };
|
|
54112
54286
|
}).filter((e) => e !== null).sort((a, b) => b.area - a.area || a.r.lineNumber - b.r.lineNumber);
|
|
54113
|
-
const placedRegionRects = [];
|
|
54287
|
+
const placedRegionRects = [...topReserved];
|
|
54114
54288
|
const placedLeaders = [];
|
|
54115
54289
|
const isEmptyFill = (f) => f === water || f === neutralFill || f === foreignFill;
|
|
54116
54290
|
const POI_LABEL_PAD = 14;
|
|
@@ -54123,9 +54297,9 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
54123
54297
|
const SHORT_HOP_MAX = Math.max(46, Math.min(width, height) * 0.11);
|
|
54124
54298
|
const STEP = 4;
|
|
54125
54299
|
const HOP_GAP = 9;
|
|
54126
|
-
const tryShortHopCallout = (cx, cy, fill2, name, value) => {
|
|
54127
|
-
const chipW = stackW(name, value);
|
|
54128
|
-
const chipH = stackH(value !== void 0);
|
|
54300
|
+
const tryShortHopCallout = (cx, cy, fill2, name, value, font = FONT2, gap = HOP_GAP, maxLen = SHORT_HOP_MAX) => {
|
|
54301
|
+
const chipW = stackW(name, value, font);
|
|
54302
|
+
const chipH = stackH(value !== void 0, font);
|
|
54129
54303
|
const dirs = [
|
|
54130
54304
|
[0, -1],
|
|
54131
54305
|
// north (over Canada)
|
|
@@ -54141,7 +54315,7 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
54141
54315
|
let ex = cx;
|
|
54142
54316
|
let ey = cy;
|
|
54143
54317
|
let steps = 0;
|
|
54144
|
-
const maxSteps = Math.ceil(
|
|
54318
|
+
const maxSteps = Math.ceil(maxLen / STEP) + 1;
|
|
54145
54319
|
while (steps < maxSteps && fillAt(ex, ey) === fill2) {
|
|
54146
54320
|
ex += dx * STEP;
|
|
54147
54321
|
ey += dy * STEP;
|
|
@@ -54149,8 +54323,8 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
54149
54323
|
}
|
|
54150
54324
|
if (fillAt(ex, ey) === fill2) continue;
|
|
54151
54325
|
const halfAlong = (Math.abs(dx) * chipW + Math.abs(dy) * chipH) / 2;
|
|
54152
|
-
const ccx = ex + dx * (
|
|
54153
|
-
const ccy = ey + dy * (
|
|
54326
|
+
const ccx = ex + dx * (gap + halfAlong);
|
|
54327
|
+
const ccy = ey + dy * (gap + halfAlong);
|
|
54154
54328
|
const rect = {
|
|
54155
54329
|
x: ccx - chipW / 2,
|
|
54156
54330
|
y: ccy - chipH / 2,
|
|
@@ -54175,7 +54349,7 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
54175
54349
|
const innerX = ccx - dx * (chipW / 2);
|
|
54176
54350
|
const innerY = ccy - dy * (chipH / 2);
|
|
54177
54351
|
const len = Math.hypot(innerX - cx, innerY - cy);
|
|
54178
|
-
if (len >
|
|
54352
|
+
if (len > maxLen) continue;
|
|
54179
54353
|
if (placedLeaders.some(
|
|
54180
54354
|
(l) => segmentsCross(cx, cy, innerX, innerY, l[0], l[1], l[2], l[3])
|
|
54181
54355
|
))
|
|
@@ -54199,6 +54373,78 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
54199
54373
|
const valStr = regionValueStr(r.value);
|
|
54200
54374
|
const fitsRegions = (rect) => !placedRegionRects.some((p) => rectsOverlap(rect, p));
|
|
54201
54375
|
const fitsPois = (rect) => !poiObstacles.some((o) => rectsOverlap(rect, o));
|
|
54376
|
+
const isSubject = regionById.has(r.id);
|
|
54377
|
+
const extremesOnFill = (ax, ay, text) => {
|
|
54378
|
+
const halfW = measureLegendText(text, FONT2) / 2;
|
|
54379
|
+
return fillAt(ax - halfW, ay) === r.fill && fillAt(ax + halfW, ay) === r.fill;
|
|
54380
|
+
};
|
|
54381
|
+
if (isSubject && valStr === void 0 && r.label !== void 0) {
|
|
54382
|
+
const name = candidates[0];
|
|
54383
|
+
let best = -1;
|
|
54384
|
+
for (let f = SUBJECT_FONT_MAX; f >= FONT2; f--) {
|
|
54385
|
+
if (measureLegendText(name, f) > boxW || f + 2 * LABEL_PADY > boxH)
|
|
54386
|
+
continue;
|
|
54387
|
+
const rect = regionLabelRect(c[0], c[1], name, void 0, f);
|
|
54388
|
+
if (!fitsRegions(rect) || !fitsPois(rect) || collides(rect)) continue;
|
|
54389
|
+
const halfW = measureLegendText(name, f) / 2;
|
|
54390
|
+
if (fillAt(c[0] - halfW, c[1]) !== r.fill || fillAt(c[0] + halfW, c[1]) !== r.fill)
|
|
54391
|
+
continue;
|
|
54392
|
+
best = f;
|
|
54393
|
+
break;
|
|
54394
|
+
}
|
|
54395
|
+
if (best >= SUBJECT_MIN_PROMINENCE) {
|
|
54396
|
+
const rect = regionLabelRect(c[0], c[1], name, void 0, best);
|
|
54397
|
+
placedRegionRects.push(rect);
|
|
54398
|
+
pushRegionLabel(
|
|
54399
|
+
c[0],
|
|
54400
|
+
c[1],
|
|
54401
|
+
name,
|
|
54402
|
+
r.fill,
|
|
54403
|
+
r.lineNumber,
|
|
54404
|
+
void 0,
|
|
54405
|
+
best
|
|
54406
|
+
);
|
|
54407
|
+
labeledRegionIds.add(r.id);
|
|
54408
|
+
regionLabelGuards.push({ label: labels[labels.length - 1], rect });
|
|
54409
|
+
} else {
|
|
54410
|
+
const hop = tryShortHopCallout(
|
|
54411
|
+
c[0],
|
|
54412
|
+
c[1],
|
|
54413
|
+
r.fill,
|
|
54414
|
+
r.label,
|
|
54415
|
+
void 0,
|
|
54416
|
+
SUBJECT_LEADER_FONT,
|
|
54417
|
+
HOP_GAP + SUBJECT_LEADER_FONT,
|
|
54418
|
+
SHORT_HOP_MAX * 2.2
|
|
54419
|
+
);
|
|
54420
|
+
if (hop) {
|
|
54421
|
+
placedRegionRects.push(hop.rect);
|
|
54422
|
+
placedLeaders.push(hop.leader);
|
|
54423
|
+
const dark = mix(r.fill, palette.text, 60);
|
|
54424
|
+
labels.push({
|
|
54425
|
+
x: hop.x,
|
|
54426
|
+
y: hop.y,
|
|
54427
|
+
text: r.label,
|
|
54428
|
+
anchor: "middle",
|
|
54429
|
+
color: palette.text,
|
|
54430
|
+
halo: false,
|
|
54431
|
+
haloColor: palette.bg,
|
|
54432
|
+
fontSize: SUBJECT_LEADER_FONT,
|
|
54433
|
+
leader: {
|
|
54434
|
+
x1: hop.leader[0],
|
|
54435
|
+
y1: hop.leader[1],
|
|
54436
|
+
x2: hop.leader[2],
|
|
54437
|
+
y2: hop.leader[3]
|
|
54438
|
+
},
|
|
54439
|
+
leaderColor: dark,
|
|
54440
|
+
calloutDot: { x: c[0], y: c[1], color: dark },
|
|
54441
|
+
lineNumber: r.lineNumber
|
|
54442
|
+
});
|
|
54443
|
+
labeledRegionIds.add(r.id);
|
|
54444
|
+
}
|
|
54445
|
+
}
|
|
54446
|
+
continue;
|
|
54447
|
+
}
|
|
54202
54448
|
const seekAnchors = [
|
|
54203
54449
|
{ x: c[0], y: c[1], guard: false }
|
|
54204
54450
|
];
|
|
@@ -54221,13 +54467,13 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
54221
54467
|
const nameRect = regionLabelRect(a.x, a.y, t);
|
|
54222
54468
|
if (valStr && stackW(t, valStr) <= boxW && stackH(true) <= boxH) {
|
|
54223
54469
|
const stackRect = regionLabelRect(a.x, a.y, t, valStr);
|
|
54224
|
-
if (fitsRegions(stackRect) && fitsPois(nameRect)) {
|
|
54470
|
+
if (fitsRegions(stackRect) && fitsPois(nameRect) && extremesOnFill(a.x, a.y, t)) {
|
|
54225
54471
|
chosen = { text: t, valueLine: valStr, ax: a.x, ay: a.y };
|
|
54226
54472
|
break;
|
|
54227
54473
|
}
|
|
54228
54474
|
}
|
|
54229
54475
|
if (labelW(t) <= boxW && labelH <= boxH) {
|
|
54230
|
-
if (fitsRegions(nameRect) && fitsPois(nameRect)) {
|
|
54476
|
+
if (fitsRegions(nameRect) && fitsPois(nameRect) && (valStr === void 0 || extremesOnFill(a.x, a.y, t))) {
|
|
54231
54477
|
chosen = { text: t, ax: a.x, ay: a.y };
|
|
54232
54478
|
break;
|
|
54233
54479
|
}
|
|
@@ -54235,7 +54481,7 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
54235
54481
|
}
|
|
54236
54482
|
if (chosen) break;
|
|
54237
54483
|
}
|
|
54238
|
-
if (chosen === void 0 &&
|
|
54484
|
+
if (chosen === void 0 && r.label !== void 0 && isSubject) {
|
|
54239
54485
|
const hop = tryShortHopCallout(c[0], c[1], r.fill, r.label, valStr);
|
|
54240
54486
|
if (hop) {
|
|
54241
54487
|
placedRegionRects.push(hop.rect);
|
|
@@ -54247,9 +54493,9 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
54247
54493
|
text: r.label,
|
|
54248
54494
|
anchor: "middle",
|
|
54249
54495
|
color: palette.text,
|
|
54250
|
-
halo:
|
|
54496
|
+
halo: false,
|
|
54251
54497
|
haloColor: palette.bg,
|
|
54252
|
-
valueLine: valStr,
|
|
54498
|
+
...valStr !== void 0 && { valueLine: valStr },
|
|
54253
54499
|
leader: {
|
|
54254
54500
|
x1: hop.leader[0],
|
|
54255
54501
|
y1: hop.leader[1],
|
|
@@ -54260,20 +54506,28 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
54260
54506
|
calloutDot: { x: c[0], y: c[1], color: dark },
|
|
54261
54507
|
lineNumber: r.lineNumber
|
|
54262
54508
|
});
|
|
54509
|
+
labeledRegionIds.add(r.id);
|
|
54263
54510
|
}
|
|
54264
54511
|
continue;
|
|
54265
54512
|
}
|
|
54266
54513
|
if (chosen === void 0) continue;
|
|
54267
54514
|
const isOrient = r.value === void 0 && r.layer === "base";
|
|
54268
54515
|
let font = FONT2;
|
|
54269
|
-
let fade = 0;
|
|
54270
54516
|
if (isOrient) {
|
|
54271
54517
|
const growT = sizeT(boxW, boxH);
|
|
54272
54518
|
const desiredFont = Math.round(
|
|
54273
54519
|
FONT2 + growT * (REGION_FONT_MAX_ORIENT - FONT2)
|
|
54274
54520
|
);
|
|
54275
54521
|
const hasVal = chosen.valueLine !== void 0;
|
|
54276
|
-
|
|
54522
|
+
const extremesClean = (f) => {
|
|
54523
|
+
const halfW = measureLegendText(chosen.text, f) / 2;
|
|
54524
|
+
return [chosen.ax - halfW, chosen.ax + halfW].every((sx) => {
|
|
54525
|
+
const fAt = fillAt(sx, chosen.ay);
|
|
54526
|
+
return fAt === r.fill || isEmptyFill(fAt);
|
|
54527
|
+
});
|
|
54528
|
+
};
|
|
54529
|
+
let fit = -1;
|
|
54530
|
+
for (let f = desiredFont; f >= FONT2; f--) {
|
|
54277
54531
|
if (stackW(chosen.text, chosen.valueLine, f) > boxW || stackH(hasVal, f) > boxH)
|
|
54278
54532
|
continue;
|
|
54279
54533
|
const gRect = regionLabelRect(
|
|
@@ -54290,14 +54544,18 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
54290
54544
|
void 0,
|
|
54291
54545
|
f
|
|
54292
54546
|
);
|
|
54293
|
-
if (!fitsRegions(gRect) || !fitsPois(gName))
|
|
54294
|
-
const halfW = measureLegendText(chosen.text, f) / 2;
|
|
54295
|
-
if (fillAt(chosen.ax - halfW, chosen.ay) !== r.fill || fillAt(chosen.ax + halfW, chosen.ay) !== r.fill)
|
|
54547
|
+
if (!fitsRegions(gRect) || !fitsPois(gName) || collides(gName))
|
|
54296
54548
|
continue;
|
|
54297
|
-
|
|
54549
|
+
if (!extremesClean(f)) continue;
|
|
54550
|
+
fit = f;
|
|
54298
54551
|
break;
|
|
54299
54552
|
}
|
|
54300
|
-
|
|
54553
|
+
if (fit < 0) {
|
|
54554
|
+
if (!frameContainers.has(r.id)) continue;
|
|
54555
|
+
font = FONT2;
|
|
54556
|
+
} else {
|
|
54557
|
+
font = fit;
|
|
54558
|
+
}
|
|
54301
54559
|
}
|
|
54302
54560
|
const rRect = regionLabelRect(
|
|
54303
54561
|
chosen.ax,
|
|
@@ -54315,8 +54573,9 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
54315
54573
|
r.lineNumber,
|
|
54316
54574
|
chosen.valueLine,
|
|
54317
54575
|
font,
|
|
54318
|
-
|
|
54576
|
+
isOrient ? backdropLandTone : void 0
|
|
54319
54577
|
);
|
|
54578
|
+
labeledRegionIds.add(r.id);
|
|
54320
54579
|
regionLabelGuards.push({
|
|
54321
54580
|
label: labels[labels.length - 1],
|
|
54322
54581
|
rect: rRect
|
|
@@ -54334,6 +54593,7 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
54334
54593
|
seed.lineNumber,
|
|
54335
54594
|
valStr
|
|
54336
54595
|
);
|
|
54596
|
+
labeledRegionIds.add(seed.iso);
|
|
54337
54597
|
regionLabelGuards.push({
|
|
54338
54598
|
label: labels[labels.length - 1],
|
|
54339
54599
|
rect: regionLabelRect(seed.x, seed.y, text, valStr)
|
|
@@ -54765,13 +55025,30 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
54765
55025
|
const nx = -dy / len;
|
|
54766
55026
|
const ny = dx / len;
|
|
54767
55027
|
const perp = labelH + 2;
|
|
55028
|
+
const pm = /^M(-?[\d.]+),(-?[\d.]+)(?:L(-?[\d.]+),(-?[\d.]+)|Q(-?[\d.]+),(-?[\d.]+) (-?[\d.]+),(-?[\d.]+))$/.exec(
|
|
55029
|
+
lg.d
|
|
55030
|
+
);
|
|
55031
|
+
const pointAt = (t) => {
|
|
55032
|
+
if (pm?.[5] !== void 0) {
|
|
55033
|
+
const u = 1 - t;
|
|
55034
|
+
return [
|
|
55035
|
+
u * u * +pm[1] + 2 * u * t * +pm[5] + t * t * +pm[7],
|
|
55036
|
+
u * u * +pm[2] + 2 * u * t * +pm[6] + t * t * +pm[8]
|
|
55037
|
+
];
|
|
55038
|
+
}
|
|
55039
|
+
if (pm?.[3] !== void 0)
|
|
55040
|
+
return [
|
|
55041
|
+
+pm[1] + (+pm[3] - +pm[1]) * t,
|
|
55042
|
+
+pm[2] + (+pm[4] - +pm[2]) * t
|
|
55043
|
+
];
|
|
55044
|
+
return [a.cx + dx * t, a.cy + dy * t];
|
|
55045
|
+
};
|
|
54768
55046
|
const candidates = [];
|
|
54769
55047
|
for (const off of [0, perp, -perp, 2 * perp, -2 * perp])
|
|
54770
|
-
for (const t of T_LIST)
|
|
54771
|
-
|
|
54772
|
-
|
|
54773
|
-
|
|
54774
|
-
]);
|
|
55048
|
+
for (const t of T_LIST) {
|
|
55049
|
+
const [bx, by] = pointAt(t);
|
|
55050
|
+
candidates.push([bx + nx * off, by + ny * off - 4]);
|
|
55051
|
+
}
|
|
54775
55052
|
const clean = ([cx2, cy2]) => {
|
|
54776
55053
|
const rect2 = { x: cx2 - w / 2, y: cy2 - labelH / 2, w, h: labelH };
|
|
54777
55054
|
if (rect2.x < 0 || rect2.x + w > width || rect2.y < 0 || rect2.y + rect2.h > height)
|
|
@@ -54781,10 +55058,8 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
54781
55058
|
if (placedEdge.some((o) => rectsOverlap(o, rect2))) return false;
|
|
54782
55059
|
return true;
|
|
54783
55060
|
};
|
|
54784
|
-
const
|
|
54785
|
-
|
|
54786
|
-
a.cy + dy * 0.5 - 4
|
|
54787
|
-
];
|
|
55061
|
+
const mid = pointAt(0.5);
|
|
55062
|
+
const [cx, cy] = candidates.find(clean) ?? [mid[0], mid[1] - 4];
|
|
54788
55063
|
const style = labelOnFill(fillAt(cx, cy));
|
|
54789
55064
|
legs[i] = {
|
|
54790
55065
|
...lg,
|
|
@@ -54812,7 +55087,7 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
54812
55087
|
const rawCountries = [];
|
|
54813
55088
|
for (const f of worldLayer.values()) {
|
|
54814
55089
|
const iso = typeof f.id === "string" ? f.id : String(f.id ?? "");
|
|
54815
|
-
if (!iso || regionById.has(iso)) continue;
|
|
55090
|
+
if (!iso || regionById.has(iso) || labeledRegionIds.has(iso)) continue;
|
|
54816
55091
|
let hasReferencedSub = false;
|
|
54817
55092
|
for (const k of regionById.keys())
|
|
54818
55093
|
if (k.startsWith(iso + "-")) {
|
|
@@ -54886,7 +55161,7 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
54886
55161
|
);
|
|
54887
55162
|
if (usLayer && framedStateContainers) {
|
|
54888
55163
|
for (const [iso, f] of usLayer) {
|
|
54889
|
-
if (regionById.has(iso)) continue;
|
|
55164
|
+
if (regionById.has(iso) || labeledRegionIds.has(iso)) continue;
|
|
54890
55165
|
const viewF = cullFeatureToView(f);
|
|
54891
55166
|
if (!viewF) continue;
|
|
54892
55167
|
const b = path.bounds(viewF);
|
|
@@ -54910,6 +55185,11 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
54910
55185
|
waterBodies: data.waterBodies,
|
|
54911
55186
|
countries: countryCandidates,
|
|
54912
55187
|
palette,
|
|
55188
|
+
// One muted, contrast-floored tone shared with the orientation backdrop
|
|
55189
|
+
// (region pass) so a context country (Canada) and an orientation region
|
|
55190
|
+
// (Minnesota) read identically — never below the WCAG-AA floor, no fade.
|
|
55191
|
+
countryTone: backdropLandTone,
|
|
55192
|
+
waterTone: backdropWaterTone,
|
|
54913
55193
|
project,
|
|
54914
55194
|
collides,
|
|
54915
55195
|
contentPoints,
|
|
@@ -55464,19 +55744,60 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
55464
55744
|
sel.style("cursor", "pointer").on("click", () => onClickItem(lineNumber));
|
|
55465
55745
|
};
|
|
55466
55746
|
const gLegs = svg.append("g").attr("class", "dgmo-map-legs").attr("fill", "none");
|
|
55467
|
-
|
|
55468
|
-
const
|
|
55747
|
+
const legEnd = (d) => {
|
|
55748
|
+
const m = /^M(-?[\d.]+),(-?[\d.]+)(?:L(-?[\d.]+),(-?[\d.]+)|Q(-?[\d.]+),(-?[\d.]+) (-?[\d.]+),(-?[\d.]+))$/.exec(
|
|
55749
|
+
d
|
|
55750
|
+
);
|
|
55751
|
+
if (!m) return null;
|
|
55752
|
+
const x0 = +m[1];
|
|
55753
|
+
const y0 = +m[2];
|
|
55754
|
+
let ex;
|
|
55755
|
+
let ey;
|
|
55756
|
+
let fromX;
|
|
55757
|
+
let fromY;
|
|
55758
|
+
if (m[3] !== void 0) {
|
|
55759
|
+
ex = +m[3];
|
|
55760
|
+
ey = +m[4];
|
|
55761
|
+
fromX = x0;
|
|
55762
|
+
fromY = y0;
|
|
55763
|
+
} else {
|
|
55764
|
+
ex = +m[7];
|
|
55765
|
+
ey = +m[8];
|
|
55766
|
+
fromX = +m[5];
|
|
55767
|
+
fromY = +m[6];
|
|
55768
|
+
}
|
|
55769
|
+
const dx = ex - fromX;
|
|
55770
|
+
const dy = ey - fromY;
|
|
55771
|
+
const len = Math.hypot(dx, dy);
|
|
55772
|
+
if (!(len > 0)) return null;
|
|
55773
|
+
return { ex, ey, tx: dx / len, ty: dy / len };
|
|
55774
|
+
};
|
|
55775
|
+
layout.legs.forEach((leg) => {
|
|
55776
|
+
const end = leg.arrow ? legEnd(leg.d) : null;
|
|
55777
|
+
let drawD = leg.d;
|
|
55778
|
+
let arrowTri = null;
|
|
55779
|
+
if (end) {
|
|
55780
|
+
const aLen = arrowSize(leg.width);
|
|
55781
|
+
const aHalf = Math.max(aLen * 0.5, leg.width * 0.6 + 1);
|
|
55782
|
+
const bx = end.ex - end.tx * aLen;
|
|
55783
|
+
const by = end.ey - end.ty * aLen;
|
|
55784
|
+
const px = -end.ty;
|
|
55785
|
+
const py = end.tx;
|
|
55786
|
+
arrowTri = `M${bx + px * aHalf},${by + py * aHalf}L${end.ex},${end.ey}L${bx - px * aHalf},${by - py * aHalf}z`;
|
|
55787
|
+
drawD = leg.d.replace(
|
|
55788
|
+
/(-?[\d.]+),(-?[\d.]+)$/,
|
|
55789
|
+
`${bx.toFixed(2)},${by.toFixed(2)}`
|
|
55790
|
+
);
|
|
55791
|
+
}
|
|
55792
|
+
const p = gLegs.append("path").attr("d", drawD).attr("stroke", leg.color).attr("stroke-width", leg.width).attr("stroke-linecap", "round").attr("data-from-id", leg.fromId).attr("data-to-id", leg.toId);
|
|
55469
55793
|
if (leg.tags) {
|
|
55470
55794
|
for (const [group, value] of Object.entries(leg.tags)) {
|
|
55471
55795
|
p.attr(`data-tag-${group.toLowerCase()}`, value.toLowerCase());
|
|
55472
55796
|
}
|
|
55473
55797
|
}
|
|
55474
55798
|
wireSync(p, leg.lineNumber);
|
|
55475
|
-
if (
|
|
55476
|
-
|
|
55477
|
-
const s = arrowSize(leg.width);
|
|
55478
|
-
defs.append("marker").attr("id", id).attr("viewBox", "0 0 10 10").attr("refX", 10).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", s).attr("markerHeight", s).attr("orient", "auto-start-reverse").append("path").attr("d", "M0,0L10,5L0,10z").attr("fill", leg.color);
|
|
55479
|
-
p.attr("marker-end", `url(#${id})`);
|
|
55799
|
+
if (arrowTri) {
|
|
55800
|
+
gLegs.append("path").attr("d", arrowTri).attr("fill", leg.color).attr("stroke", leg.color).attr("stroke-width", 1).attr("stroke-linejoin", "round").attr("data-from-id", leg.fromId).attr("data-to-id", leg.toId);
|
|
55480
55801
|
}
|
|
55481
55802
|
if (leg.label !== void 0 && leg.labelX !== void 0) {
|
|
55482
55803
|
const lt = emitText(
|
|
@@ -59105,9 +59426,9 @@ var init_renderer20 = __esm({
|
|
|
59105
59426
|
}
|
|
59106
59427
|
});
|
|
59107
59428
|
|
|
59108
|
-
// node_modules/.pnpm/lz-string@1.5.0/node_modules/lz-string/libs/lz-string.js
|
|
59429
|
+
// ../../diagrammo/dgmo/node_modules/.pnpm/lz-string@1.5.0/node_modules/lz-string/libs/lz-string.js
|
|
59109
59430
|
var require_lz_string = __commonJS({
|
|
59110
|
-
"node_modules/.pnpm/lz-string@1.5.0/node_modules/lz-string/libs/lz-string.js"(exports2, module2) {
|
|
59431
|
+
"../../diagrammo/dgmo/node_modules/.pnpm/lz-string@1.5.0/node_modules/lz-string/libs/lz-string.js"(exports2, module2) {
|
|
59111
59432
|
"use strict";
|
|
59112
59433
|
var LZString = (function() {
|
|
59113
59434
|
var f = String.fromCharCode;
|
|
@@ -59632,12 +59953,10 @@ __export(advanced_exports, {
|
|
|
59632
59953
|
extractFlowchartSymbols: () => extractSymbols,
|
|
59633
59954
|
extractInfraSymbols: () => extractSymbols4,
|
|
59634
59955
|
extractPertSymbols: () => extractPertSymbols,
|
|
59635
|
-
findUnsafePipePositions: () => findUnsafePipePositions,
|
|
59636
59956
|
focusBoxesAndLines: () => focusBoxesAndLines,
|
|
59637
59957
|
focusOrgTree: () => focusOrgTree,
|
|
59638
59958
|
formatDateLabel: () => formatDateLabel,
|
|
59639
59959
|
formatDgmoError: () => formatDgmoError,
|
|
59640
|
-
formatLineDiff: () => formatLineDiff,
|
|
59641
59960
|
getAllChartTypes: () => getAllChartTypes,
|
|
59642
59961
|
getAvailablePalettes: () => getAvailablePalettes,
|
|
59643
59962
|
getExtendedChartLegendGroups: () => getExtendedChartLegendGroups,
|
|
@@ -59658,7 +59977,6 @@ __export(advanced_exports, {
|
|
|
59658
59977
|
isArchiveColumn: () => isArchiveColumn,
|
|
59659
59978
|
isExtendedChartType: () => isExtendedChartType,
|
|
59660
59979
|
isInvalidColorToken: () => isInvalidColorToken,
|
|
59661
|
-
isLegacyMetadataLine: () => isLegacyMetadataLine,
|
|
59662
59980
|
isRecognizedColorName: () => isRecognizedColorName,
|
|
59663
59981
|
isSequenceBlock: () => isSequenceBlock,
|
|
59664
59982
|
isSequenceNote: () => isSequenceNote,
|
|
@@ -59695,7 +60013,6 @@ __export(advanced_exports, {
|
|
|
59695
60013
|
mapExportDimensions: () => mapExportDimensions,
|
|
59696
60014
|
mapNeutralLandColor: () => mapNeutralLandColor,
|
|
59697
60015
|
measurePertAnalysisBlock: () => measurePertAnalysisBlock,
|
|
59698
|
-
migrateContent: () => migrateContent,
|
|
59699
60016
|
mix: () => mix,
|
|
59700
60017
|
mulberry32: () => mulberry32,
|
|
59701
60018
|
nearestNamedColor: () => nearestNamedColor,
|
|
@@ -59823,7 +60140,6 @@ __export(advanced_exports, {
|
|
|
59823
60140
|
tidewaterPalette: () => tidewaterPalette,
|
|
59824
60141
|
tint: () => tint,
|
|
59825
60142
|
tokyoNightPalette: () => tokyoNightPalette,
|
|
59826
|
-
transformLine: () => transformLine,
|
|
59827
60143
|
truncateBareUrl: () => truncateBareUrl,
|
|
59828
60144
|
validate: () => parseDgmo,
|
|
59829
60145
|
validateComputed: () => validateComputed,
|
|
@@ -65661,320 +65977,6 @@ var themes = {
|
|
|
65661
65977
|
|
|
65662
65978
|
// src/advanced.ts
|
|
65663
65979
|
init_dgmo_router();
|
|
65664
|
-
|
|
65665
|
-
// src/migrate/index.ts
|
|
65666
|
-
var import_node_fs = require("fs");
|
|
65667
|
-
var import_node_path = require("path");
|
|
65668
|
-
init_dgmo_router();
|
|
65669
|
-
|
|
65670
|
-
// src/migrate/line-classifier.ts
|
|
65671
|
-
function findUnsafePipePositions(line11) {
|
|
65672
|
-
const positions = [];
|
|
65673
|
-
let i = 0;
|
|
65674
|
-
let inDouble = false;
|
|
65675
|
-
let inSingle = false;
|
|
65676
|
-
let braceDepth = 0;
|
|
65677
|
-
let inArrow = false;
|
|
65678
|
-
let arrowOpenChar = null;
|
|
65679
|
-
while (i < line11.length) {
|
|
65680
|
-
const ch = line11[i];
|
|
65681
|
-
const ch2 = i + 1 < line11.length ? line11[i + 1] : "";
|
|
65682
|
-
if (inDouble) {
|
|
65683
|
-
if (ch === '"') inDouble = false;
|
|
65684
|
-
i++;
|
|
65685
|
-
continue;
|
|
65686
|
-
}
|
|
65687
|
-
if (inSingle) {
|
|
65688
|
-
if (ch === "'") inSingle = false;
|
|
65689
|
-
i++;
|
|
65690
|
-
continue;
|
|
65691
|
-
}
|
|
65692
|
-
if (inArrow) {
|
|
65693
|
-
if (arrowOpenChar === "-" && ch === "-" && ch2 === ">" || arrowOpenChar === "~" && ch === "~" && ch2 === ">") {
|
|
65694
|
-
inArrow = false;
|
|
65695
|
-
arrowOpenChar = null;
|
|
65696
|
-
i += 2;
|
|
65697
|
-
continue;
|
|
65698
|
-
}
|
|
65699
|
-
i++;
|
|
65700
|
-
continue;
|
|
65701
|
-
}
|
|
65702
|
-
if (ch === '"') {
|
|
65703
|
-
inDouble = true;
|
|
65704
|
-
i++;
|
|
65705
|
-
continue;
|
|
65706
|
-
}
|
|
65707
|
-
if (ch === "'") {
|
|
65708
|
-
inSingle = true;
|
|
65709
|
-
i++;
|
|
65710
|
-
continue;
|
|
65711
|
-
}
|
|
65712
|
-
if (ch === "{") {
|
|
65713
|
-
braceDepth++;
|
|
65714
|
-
i++;
|
|
65715
|
-
continue;
|
|
65716
|
-
}
|
|
65717
|
-
if (ch === "}") {
|
|
65718
|
-
if (braceDepth > 0) braceDepth--;
|
|
65719
|
-
i++;
|
|
65720
|
-
continue;
|
|
65721
|
-
}
|
|
65722
|
-
if ((ch === "-" || ch === "~") && i > 0) {
|
|
65723
|
-
const prev = line11[i - 1];
|
|
65724
|
-
const onBoundary = prev === " " || prev === " ";
|
|
65725
|
-
const nextIsLabelChar = ch2 !== "" && ch2 !== ch && ch2 !== ">" && ch2 !== " " && ch2 !== " ";
|
|
65726
|
-
if (onBoundary && nextIsLabelChar) {
|
|
65727
|
-
const closer = ch + ">";
|
|
65728
|
-
const closeIdx = line11.indexOf(closer, i + 1);
|
|
65729
|
-
if (closeIdx > i) {
|
|
65730
|
-
const labelRegion = line11.substring(i + 1, closeIdx);
|
|
65731
|
-
if (!labelRegion.includes("->") && !labelRegion.includes("~>")) {
|
|
65732
|
-
inArrow = true;
|
|
65733
|
-
arrowOpenChar = ch;
|
|
65734
|
-
i++;
|
|
65735
|
-
continue;
|
|
65736
|
-
}
|
|
65737
|
-
}
|
|
65738
|
-
}
|
|
65739
|
-
}
|
|
65740
|
-
if (ch === "|" && braceDepth === 0) {
|
|
65741
|
-
positions.push(i);
|
|
65742
|
-
}
|
|
65743
|
-
i++;
|
|
65744
|
-
}
|
|
65745
|
-
return positions;
|
|
65746
|
-
}
|
|
65747
|
-
function isLegacyMetadataLine(line11) {
|
|
65748
|
-
return findUnsafePipePositions(line11).length > 0;
|
|
65749
|
-
}
|
|
65750
|
-
|
|
65751
|
-
// src/migrate/line-transformer.ts
|
|
65752
|
-
function replaceUnsafePipesWithCommas(s) {
|
|
65753
|
-
const positions = findUnsafePipePositions(s);
|
|
65754
|
-
if (positions.length === 0) return s;
|
|
65755
|
-
const chars = s.split("");
|
|
65756
|
-
for (const pos of positions) {
|
|
65757
|
-
chars[pos] = ",";
|
|
65758
|
-
}
|
|
65759
|
-
return chars.join("");
|
|
65760
|
-
}
|
|
65761
|
-
var GANTT_PERCENT = {
|
|
65762
|
-
match: (t) => /^\d+(?:\.\d+)?\s*%$/.test(t.trim()),
|
|
65763
|
-
promote: (t) => `progress: ${t.trim().replace(/\s*%$/, "")}`
|
|
65764
|
-
};
|
|
65765
|
-
var JOURNEY_SCORE = {
|
|
65766
|
-
match: (t) => /^\d+(?:\s+[A-Za-z][A-Za-z0-9_-]*)?$/.test(t.trim()),
|
|
65767
|
-
promote: (t) => {
|
|
65768
|
-
const m = t.trim().match(/^(\d+)(?:\s+([A-Za-z][A-Za-z0-9_-]*))?$/);
|
|
65769
|
-
if (!m) return t;
|
|
65770
|
-
return m[2] ? `score: ${m[1]}, emotion: ${m[2]}` : `score: ${m[1]}`;
|
|
65771
|
-
}
|
|
65772
|
-
};
|
|
65773
|
-
var PROMOTIONS_BY_CHART = {
|
|
65774
|
-
gantt: [GANTT_PERCENT],
|
|
65775
|
-
"journey-map": [JOURNEY_SCORE]
|
|
65776
|
-
};
|
|
65777
|
-
var BARE_DESCRIPTION_CHARTS = /* @__PURE__ */ new Set(["pyramid", "ring"]);
|
|
65778
|
-
function tokenizeMetaRegion(region) {
|
|
65779
|
-
const tokens = [];
|
|
65780
|
-
let i = 0;
|
|
65781
|
-
let buf = "";
|
|
65782
|
-
let inQuote = null;
|
|
65783
|
-
while (i < region.length) {
|
|
65784
|
-
const ch = region[i];
|
|
65785
|
-
if (inQuote) {
|
|
65786
|
-
buf += ch;
|
|
65787
|
-
if (ch === inQuote) inQuote = null;
|
|
65788
|
-
i++;
|
|
65789
|
-
continue;
|
|
65790
|
-
}
|
|
65791
|
-
if (ch === '"' || ch === "'") {
|
|
65792
|
-
inQuote = ch;
|
|
65793
|
-
buf += ch;
|
|
65794
|
-
i++;
|
|
65795
|
-
continue;
|
|
65796
|
-
}
|
|
65797
|
-
if (ch === ",") {
|
|
65798
|
-
const t = buf.trim();
|
|
65799
|
-
if (t) tokens.push(t);
|
|
65800
|
-
buf = "";
|
|
65801
|
-
i++;
|
|
65802
|
-
continue;
|
|
65803
|
-
}
|
|
65804
|
-
buf += ch;
|
|
65805
|
-
i++;
|
|
65806
|
-
}
|
|
65807
|
-
const tail = buf.trim();
|
|
65808
|
-
if (tail) tokens.push(tail);
|
|
65809
|
-
return tokens;
|
|
65810
|
-
}
|
|
65811
|
-
function transformLine(line11, chartType) {
|
|
65812
|
-
const indentMatch = line11.match(/^[ \t]*/);
|
|
65813
|
-
const indent = indentMatch ? indentMatch[0] : "";
|
|
65814
|
-
const body = line11.substring(indent.length);
|
|
65815
|
-
const pipePositions = findUnsafePipePositions(body);
|
|
65816
|
-
if (pipePositions.length === 0) {
|
|
65817
|
-
return { line: line11, changed: false };
|
|
65818
|
-
}
|
|
65819
|
-
const cut = pipePositions[0];
|
|
65820
|
-
const nameRegion = body.substring(0, cut).trimEnd();
|
|
65821
|
-
let metaRegion = body.substring(cut + 1).trimStart();
|
|
65822
|
-
if (pipePositions.length > 1) {
|
|
65823
|
-
metaRegion = replaceUnsafePipesWithCommas(metaRegion);
|
|
65824
|
-
}
|
|
65825
|
-
if (chartType !== null && BARE_DESCRIPTION_CHARTS.has(chartType) && !metaRegion.includes(":")) {
|
|
65826
|
-
const text = metaRegion.trim();
|
|
65827
|
-
if (!text) {
|
|
65828
|
-
return {
|
|
65829
|
-
line: indent + nameRegion,
|
|
65830
|
-
changed: true
|
|
65831
|
-
};
|
|
65832
|
-
}
|
|
65833
|
-
const value = text.includes(",") ? `"${text}"` : text;
|
|
65834
|
-
return {
|
|
65835
|
-
line: `${indent}${nameRegion} description: ${value}`,
|
|
65836
|
-
changed: true
|
|
65837
|
-
};
|
|
65838
|
-
}
|
|
65839
|
-
const tokens = tokenizeMetaRegion(metaRegion);
|
|
65840
|
-
const promotions = chartType ? PROMOTIONS_BY_CHART[chartType] ?? [] : [];
|
|
65841
|
-
const emitted = [];
|
|
65842
|
-
for (const raw of tokens) {
|
|
65843
|
-
if (raw.includes(":")) {
|
|
65844
|
-
emitted.push(raw);
|
|
65845
|
-
continue;
|
|
65846
|
-
}
|
|
65847
|
-
const promo = promotions.find((p) => p.match(raw));
|
|
65848
|
-
if (promo) {
|
|
65849
|
-
emitted.push(promo.promote(raw));
|
|
65850
|
-
continue;
|
|
65851
|
-
}
|
|
65852
|
-
emitted.push(raw);
|
|
65853
|
-
}
|
|
65854
|
-
if (emitted.length === 0) {
|
|
65855
|
-
return {
|
|
65856
|
-
line: indent + nameRegion,
|
|
65857
|
-
changed: true
|
|
65858
|
-
};
|
|
65859
|
-
}
|
|
65860
|
-
return {
|
|
65861
|
-
line: `${indent}${nameRegion} ${emitted.join(", ")}`,
|
|
65862
|
-
changed: true
|
|
65863
|
-
};
|
|
65864
|
-
}
|
|
65865
|
-
|
|
65866
|
-
// src/migrate/data-comma.ts
|
|
65867
|
-
init_colors();
|
|
65868
|
-
var DATA_COMMA_CHART_TYPES = /* @__PURE__ */ new Set([
|
|
65869
|
-
// Simple charts (chart.ts)
|
|
65870
|
-
"bar",
|
|
65871
|
-
"line",
|
|
65872
|
-
"multi-line",
|
|
65873
|
-
"pie",
|
|
65874
|
-
"doughnut",
|
|
65875
|
-
"area",
|
|
65876
|
-
"polar-area",
|
|
65877
|
-
"radar",
|
|
65878
|
-
"bar-stacked",
|
|
65879
|
-
// Extended charts (echarts.ts)
|
|
65880
|
-
"scatter",
|
|
65881
|
-
"heatmap",
|
|
65882
|
-
"sankey",
|
|
65883
|
-
"chord",
|
|
65884
|
-
"funnel",
|
|
65885
|
-
// Visualizations (d3 / visualizations/parse.ts)
|
|
65886
|
-
"quadrant",
|
|
65887
|
-
"slope",
|
|
65888
|
-
"arc",
|
|
65889
|
-
"wordcloud"
|
|
65890
|
-
]);
|
|
65891
|
-
var COLOR_SET = new Set(RECOGNIZED_COLOR_NAMES);
|
|
65892
|
-
var NUMERIC_VALUE_RE = /^-?\d[\d,_]*(?:\.\d+)?,?$/;
|
|
65893
|
-
function isNumericValueToken(tok) {
|
|
65894
|
-
if (!NUMERIC_VALUE_RE.test(tok)) return false;
|
|
65895
|
-
return /\d/.test(tok);
|
|
65896
|
-
}
|
|
65897
|
-
function migrateDataRowCommaLine(line11) {
|
|
65898
|
-
const indentMatch = line11.match(/^[ \t]*/);
|
|
65899
|
-
const indent = indentMatch ? indentMatch[0] : "";
|
|
65900
|
-
const body = line11.substring(indent.length);
|
|
65901
|
-
if (!body || body.startsWith("//")) return { line: line11, changed: false };
|
|
65902
|
-
const tokens = body.split(/\s+/);
|
|
65903
|
-
if (tokens.length < 2) return { line: line11, changed: false };
|
|
65904
|
-
let i = tokens.length - 1;
|
|
65905
|
-
if (i >= 1 && COLOR_SET.has(tokens[i])) {
|
|
65906
|
-
i--;
|
|
65907
|
-
}
|
|
65908
|
-
const valueStart = (() => {
|
|
65909
|
-
let j = i;
|
|
65910
|
-
while (j >= 1 && isNumericValueToken(tokens[j])) j--;
|
|
65911
|
-
return j + 1;
|
|
65912
|
-
})();
|
|
65913
|
-
if (valueStart > i || valueStart < 1) return { line: line11, changed: false };
|
|
65914
|
-
const valueTokens = tokens.slice(valueStart, i + 1);
|
|
65915
|
-
const hasComma = valueTokens.some((t) => t.includes(","));
|
|
65916
|
-
if (!hasComma) return { line: line11, changed: false };
|
|
65917
|
-
const cleaned = valueTokens.map((t) => t.replace(/,/g, ""));
|
|
65918
|
-
const labelPart = tokens.slice(0, valueStart);
|
|
65919
|
-
const tail = tokens.slice(i + 1);
|
|
65920
|
-
const rebuiltBody = [...labelPart, ...cleaned, ...tail].join(" ");
|
|
65921
|
-
return { line: indent + rebuiltBody, changed: rebuiltBody !== body };
|
|
65922
|
-
}
|
|
65923
|
-
|
|
65924
|
-
// src/migrate/index.ts
|
|
65925
|
-
function migrateContent(source) {
|
|
65926
|
-
const chartType = parseDgmoChartType(source);
|
|
65927
|
-
const lines = source.split("\n");
|
|
65928
|
-
const out = [];
|
|
65929
|
-
const changedLines = [];
|
|
65930
|
-
let changed = false;
|
|
65931
|
-
const migrateDataCommas = chartType !== null && DATA_COMMA_CHART_TYPES.has(chartType);
|
|
65932
|
-
let firstContentSeen = false;
|
|
65933
|
-
for (let i = 0; i < lines.length; i++) {
|
|
65934
|
-
let line11 = lines[i];
|
|
65935
|
-
const trimmed = line11.trim();
|
|
65936
|
-
if (migrateDataCommas && firstContentSeen && trimmed && !trimmed.startsWith("//")) {
|
|
65937
|
-
const dc = migrateDataRowCommaLine(line11);
|
|
65938
|
-
if (dc.changed) {
|
|
65939
|
-
line11 = dc.line;
|
|
65940
|
-
changed = true;
|
|
65941
|
-
changedLines.push(i + 1);
|
|
65942
|
-
}
|
|
65943
|
-
}
|
|
65944
|
-
if (trimmed && !trimmed.startsWith("//")) firstContentSeen = true;
|
|
65945
|
-
if (!isLegacyMetadataLine(line11)) {
|
|
65946
|
-
out.push(line11);
|
|
65947
|
-
continue;
|
|
65948
|
-
}
|
|
65949
|
-
const result = transformLine(line11, chartType);
|
|
65950
|
-
if (result.changed) {
|
|
65951
|
-
changed = true;
|
|
65952
|
-
if (!changedLines.includes(i + 1)) changedLines.push(i + 1);
|
|
65953
|
-
}
|
|
65954
|
-
out.push(result.line);
|
|
65955
|
-
}
|
|
65956
|
-
return {
|
|
65957
|
-
migrated: out.join("\n"),
|
|
65958
|
-
changed,
|
|
65959
|
-
chartType,
|
|
65960
|
-
changedLines
|
|
65961
|
-
};
|
|
65962
|
-
}
|
|
65963
|
-
function formatLineDiff(path, original, migrated) {
|
|
65964
|
-
const origLines = original.split("\n");
|
|
65965
|
-
const newLines = migrated.split("\n");
|
|
65966
|
-
const lines = [`--- ${path}`, `+++ ${path}`];
|
|
65967
|
-
const max = Math.max(origLines.length, newLines.length);
|
|
65968
|
-
for (let i = 0; i < max; i++) {
|
|
65969
|
-
const a = origLines[i];
|
|
65970
|
-
const b = newLines[i];
|
|
65971
|
-
if (a === b) continue;
|
|
65972
|
-
if (a !== void 0) lines.push(`@@ line ${i + 1}
|
|
65973
|
-
- ${a}`);
|
|
65974
|
-
if (b !== void 0) lines.push(`+ ${b}`);
|
|
65975
|
-
}
|
|
65976
|
-
return lines.join("\n");
|
|
65977
|
-
}
|
|
65978
65980
|
// Annotate the CommonJS export names for ESM import in node:
|
|
65979
65981
|
0 && (module.exports = {
|
|
65980
65982
|
ALL_CHART_TYPES,
|
|
@@ -66044,12 +66046,10 @@ function formatLineDiff(path, original, migrated) {
|
|
|
66044
66046
|
extractFlowchartSymbols,
|
|
66045
66047
|
extractInfraSymbols,
|
|
66046
66048
|
extractPertSymbols,
|
|
66047
|
-
findUnsafePipePositions,
|
|
66048
66049
|
focusBoxesAndLines,
|
|
66049
66050
|
focusOrgTree,
|
|
66050
66051
|
formatDateLabel,
|
|
66051
66052
|
formatDgmoError,
|
|
66052
|
-
formatLineDiff,
|
|
66053
66053
|
getAllChartTypes,
|
|
66054
66054
|
getAvailablePalettes,
|
|
66055
66055
|
getExtendedChartLegendGroups,
|
|
@@ -66070,7 +66070,6 @@ function formatLineDiff(path, original, migrated) {
|
|
|
66070
66070
|
isArchiveColumn,
|
|
66071
66071
|
isExtendedChartType,
|
|
66072
66072
|
isInvalidColorToken,
|
|
66073
|
-
isLegacyMetadataLine,
|
|
66074
66073
|
isRecognizedColorName,
|
|
66075
66074
|
isSequenceBlock,
|
|
66076
66075
|
isSequenceNote,
|
|
@@ -66107,7 +66106,6 @@ function formatLineDiff(path, original, migrated) {
|
|
|
66107
66106
|
mapExportDimensions,
|
|
66108
66107
|
mapNeutralLandColor,
|
|
66109
66108
|
measurePertAnalysisBlock,
|
|
66110
|
-
migrateContent,
|
|
66111
66109
|
mix,
|
|
66112
66110
|
mulberry32,
|
|
66113
66111
|
nearestNamedColor,
|
|
@@ -66235,7 +66233,6 @@ function formatLineDiff(path, original, migrated) {
|
|
|
66235
66233
|
tidewaterPalette,
|
|
66236
66234
|
tint,
|
|
66237
66235
|
tokyoNightPalette,
|
|
66238
|
-
transformLine,
|
|
66239
66236
|
truncateBareUrl,
|
|
66240
66237
|
validate,
|
|
66241
66238
|
validateComputed,
|