@diagrammo/dgmo 0.46.0 → 0.47.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.d.cts +3 -855
- package/dist/advanced.d.ts +3 -855
- package/dist/advanced.js +541 -70107
- package/dist/analyzer-UYKBXAKR.js +15 -0
- package/dist/auto.cjs +1 -1
- package/dist/auto.js +1 -1
- package/dist/auto.mjs +1 -1
- package/dist/block.js +83 -69417
- package/dist/calculator-LDYQCDDY.js +11 -0
- package/dist/charts-d3-QOZHKTCT.js +25 -0
- package/dist/chunk-2DXMZRWJ.js +800 -0
- package/dist/chunk-2LACINWN.js +786 -0
- package/dist/chunk-33LCUH4H.js +893 -0
- package/dist/chunk-3CIOJ5YJ.js +35 -0
- package/dist/chunk-3HDBAXF5.js +86 -0
- package/dist/chunk-3JLKYGBQ.js +290 -0
- package/dist/chunk-3MQQNXPD.js +415 -0
- package/dist/chunk-3R5POCTZ.js +967 -0
- package/dist/chunk-3SMGIJDD.js +112 -0
- package/dist/chunk-44CM72SQ.js +409 -0
- package/dist/chunk-4GRI7MEB.js +1604 -0
- package/dist/chunk-4OHACBGX.js +606 -0
- package/dist/chunk-5DH3KYFH.js +21 -0
- package/dist/chunk-5MLYVTYM.js +76 -0
- package/dist/chunk-5QXL4NYS.js +553 -0
- package/dist/chunk-5WRI5ZAA.js +31 -0
- package/dist/chunk-6EK55ART.js +117 -0
- package/dist/chunk-6FZYCKXB.js +2065 -0
- package/dist/chunk-6HO5ZTXK.js +277 -0
- package/dist/chunk-6KFWC4CO.js +7 -0
- package/dist/chunk-6MTWIQVO.js +121 -0
- package/dist/chunk-6NYWYNBI.js +329 -0
- package/dist/chunk-6SM5NJQH.js +620 -0
- package/dist/chunk-725LDASD.js +422 -0
- package/dist/chunk-76OWZ3BA.js +130 -0
- package/dist/chunk-7JEGTRLD.js +338 -0
- package/dist/chunk-A44USUV7.js +923 -0
- package/dist/chunk-A4GOY3PE.js +25 -0
- package/dist/chunk-A4VFQH5G.js +251 -0
- package/dist/chunk-AELOBFW5.js +375 -0
- package/dist/chunk-AN2MOO5T.js +522 -0
- package/dist/chunk-BMR4CIEO.js +41 -0
- package/dist/chunk-BS7SV7C3.js +51 -0
- package/dist/chunk-BUPDIHML.js +613 -0
- package/dist/chunk-BUVJFRPY.js +887 -0
- package/dist/chunk-C3Z4DX3V.js +112 -0
- package/dist/chunk-CI2G3OEB.js +1818 -0
- package/dist/chunk-CKNVO24D.js +54 -0
- package/dist/chunk-CUVHQHZ7.js +391 -0
- package/dist/chunk-CXK4DZH3.js +114 -0
- package/dist/chunk-DKEPS5LH.js +315 -0
- package/dist/chunk-DU7W62N5.js +487 -0
- package/dist/chunk-DZAQBW35.js +751 -0
- package/dist/chunk-EB6FPQUP.js +316 -0
- package/dist/chunk-EMS2SK26.js +376 -0
- package/dist/chunk-ERLBPDGU.js +510 -0
- package/dist/chunk-EVCVDTXE.js +732 -0
- package/dist/chunk-FCIIHT24.js +384 -0
- package/dist/chunk-FFUN5D66.js +97 -0
- package/dist/chunk-FITOLXSX.js +714 -0
- package/dist/chunk-FMDSF3OV.js +68 -0
- package/dist/chunk-FNB3PNGF.js +410 -0
- package/dist/chunk-G2H74XJZ.js +2104 -0
- package/dist/chunk-GMR5MFHJ.js +339 -0
- package/dist/chunk-H6PI3KJT.js +305 -0
- package/dist/chunk-I46X5VUA.js +59 -0
- package/dist/chunk-I5IGB56C.js +255 -0
- package/dist/chunk-IH6ZMVQ5.js +3950 -0
- package/dist/chunk-IJZFN3HM.js +463 -0
- package/dist/chunk-IPWPWM6R.js +3079 -0
- package/dist/chunk-IYULMRBE.js +23 -0
- package/dist/chunk-IZMRON6C.js +167 -0
- package/dist/chunk-J5FIXQRT.js +813 -0
- package/dist/chunk-JED6ZDEE.js +73 -0
- package/dist/chunk-JEUJOX5X.js +136 -0
- package/dist/chunk-JM4LEPY3.js +436 -0
- package/dist/chunk-L3UHP6TD.js +101 -0
- package/dist/chunk-L66GEFB6.js +524 -0
- package/dist/chunk-LIOHW36Z.js +469 -0
- package/dist/chunk-LP7EC4MI.js +16 -0
- package/dist/chunk-MITI6NOL.js +548 -0
- package/dist/chunk-MO5YHHMQ.js +168 -0
- package/dist/chunk-MZSBFAPJ.js +885 -0
- package/dist/chunk-NNAAJVBU.js +9 -0
- package/dist/chunk-NOTA6TEI.js +47 -0
- package/dist/chunk-NURGB5Z4.js +335 -0
- package/dist/chunk-NX4EQS3U.js +1062 -0
- package/dist/chunk-NXMESY4J.js +1 -0
- package/dist/chunk-OJR3MQYV.js +1458 -0
- package/dist/chunk-OURHMODR.js +454 -0
- package/dist/chunk-P235SVAH.js +1057 -0
- package/dist/chunk-P4RH4OSP.js +1038 -0
- package/dist/chunk-P6T66CCZ.js +226 -0
- package/dist/chunk-PBAHEPLQ.js +223 -0
- package/dist/chunk-PBHE5UG6.js +1530 -0
- package/dist/chunk-PDKUANDZ.js +35 -0
- package/dist/chunk-PWIHZ6NJ.js +296 -0
- package/dist/chunk-QEBUY5NY.js +1685 -0
- package/dist/chunk-QLCCJEJI.js +253 -0
- package/dist/chunk-QOOUC2J5.js +52 -0
- package/dist/chunk-QYTPPDAO.js +402 -0
- package/dist/chunk-R3XI2VC7.js +801 -0
- package/dist/chunk-RCERWOJR.js +154 -0
- package/dist/chunk-RJE5JTVK.js +362 -0
- package/dist/chunk-RTLBSQ3G.js +1155 -0
- package/dist/chunk-RUNNI6VE.js +448 -0
- package/dist/chunk-RVMRZAPB.js +354 -0
- package/dist/chunk-RYEGFMUO.js +955 -0
- package/dist/chunk-RZCF2VVM.js +528 -0
- package/dist/chunk-SML67VPV.js +1025 -0
- package/dist/chunk-SQ7IY53Q.js +44 -0
- package/dist/chunk-SQAG3UXH.js +161 -0
- package/dist/chunk-SRTU6HMQ.js +1851 -0
- package/dist/chunk-T2OE3YQB.js +550 -0
- package/dist/chunk-T3UBLACL.js +299 -0
- package/dist/chunk-TLVIHFRO.js +296 -0
- package/dist/chunk-TYS6CSS5.js +52 -0
- package/dist/chunk-U6EQI3U6.js +130 -0
- package/dist/chunk-UJ4FJLBF.js +86 -0
- package/dist/chunk-ULOEATBZ.js +347 -0
- package/dist/chunk-UNCCZ3NU.js +127 -0
- package/dist/chunk-USZW2HHU.js +197 -0
- package/dist/chunk-UWN33VNX.js +1610 -0
- package/dist/chunk-UZ7EZW3B.js +40 -0
- package/dist/chunk-VOKGH627.js +37 -0
- package/dist/chunk-WBRZJOEC.js +204 -0
- package/dist/chunk-WCSOJFU3.js +380 -0
- package/dist/chunk-WCT3NYCV.js +160 -0
- package/dist/chunk-WVAJFAIA.js +529 -0
- package/dist/chunk-X5LCYCL5.js +394 -0
- package/dist/chunk-XAKEUMEJ.js +1256 -0
- package/dist/chunk-Y2ZE3MSG.js +590 -0
- package/dist/chunk-Y3J7VR52.js +646 -0
- package/dist/chunk-Y5QGVTVC.js +33 -0
- package/dist/chunk-YAA6IID3.js +548 -0
- package/dist/chunk-YGJTDXVR.js +692 -0
- package/dist/chunk-YRYKTYMQ.js +186 -0
- package/dist/chunk-YYVTBZZC.js +61 -0
- package/dist/chunk-Z5CGSFJB.js +647 -0
- package/dist/chunk-Z72XRXD4.js +787 -0
- package/dist/chunk-ZGR7ULFJ.js +978 -0
- package/dist/chunk-ZJEL4H2R.js +851 -0
- package/dist/chunk-ZO27FGJS.js +554 -0
- package/dist/collapse-CLPJD2RL.js +11 -0
- package/dist/collapse-SLINJQW6.js +9 -0
- package/dist/collapse-ZWUFFCK2.js +9 -0
- package/dist/compute-G55RG53N.js +8 -0
- package/dist/dgmo-router-DZCIDUO5.js +73 -0
- package/dist/dimensions-J3FHIMJ6.js +22 -0
- package/dist/element.cjs +1 -1
- package/dist/element.js +1 -1
- package/dist/element.mjs +1 -1
- package/dist/flowchart-parser-ZNSKIBVR.js +21 -0
- package/dist/flowchart-renderer-ZAEOL4DX.js +35 -0
- package/dist/index.cjs +3 -3
- package/dist/index.d.cts +3 -469
- package/dist/index.d.ts +3 -469
- package/dist/index.js +137 -69685
- package/dist/layout-46N4JJYK.js +17 -0
- package/dist/layout-5RA6QWR6.js +26 -0
- package/dist/layout-5T6RH5M6.js +14 -0
- package/dist/layout-7QXCNOVS.js +13 -0
- package/dist/layout-EE6GE46Y.js +17 -0
- package/dist/layout-G23F7LDH.js +9 -0
- package/dist/layout-HRBZPFCN.js +23 -0
- package/dist/layout-HWDSRX5E.js +20 -0
- package/dist/layout-HYZPWAK5.js +18 -0
- package/dist/layout-N76NR4ZO.js +19 -0
- package/dist/layout-OB3RI63S.js +14 -0
- package/dist/layout-S2QBYSK2.js +15 -0
- package/dist/layout-UM5F4DJB.js +15 -0
- package/dist/layout-search-OYV77HHS.js +1655 -0
- package/dist/load-data-EHDDZ5ZS.js +8 -0
- package/dist/palettes-PRJ2RI6D.js +56 -0
- package/dist/parser-2MFP2H2E.js +11 -0
- package/dist/parser-3STE62GB.js +21 -0
- package/dist/parser-4FL2CMDG.js +18 -0
- package/dist/parser-4OGOBJJ4.js +13 -0
- package/dist/parser-6BTRLKRZ.js +15 -0
- package/dist/parser-AQETEVRW.js +21 -0
- package/dist/parser-CFZD5IBL.js +12 -0
- package/dist/parser-FUSKFGZN.js +16 -0
- package/dist/parser-I6KXEYFK.js +13 -0
- package/dist/parser-IXSZZQHY.js +18 -0
- package/dist/parser-JAL2HD4I.js +13 -0
- package/dist/parser-KNSQSKQO.js +20 -0
- package/dist/parser-N5O4IHUN.js +13 -0
- package/dist/parser-NGU3ETO6.js +16 -0
- package/dist/parser-NRAI6O25.js +19 -0
- package/dist/parser-O5J4VBII.js +11 -0
- package/dist/parser-OV7NOBW6.js +21 -0
- package/dist/parser-PQ3POX45.js +23 -0
- package/dist/parser-TFZFBVWN.js +11 -0
- package/dist/parser-TRTHDFPP.js +18 -0
- package/dist/parser-VQP2UJ6W.js +11 -0
- package/dist/parser-XDVELHRK.js +13 -0
- package/dist/parser-XKRP7QKP.js +11 -0
- package/dist/parser-Y6WTBU76.js +14 -0
- package/dist/parser-ZSDPZYQP.js +12 -0
- package/dist/renderer-2XQQQ6QR.js +28 -0
- package/dist/renderer-5NDVNDAZ.js +26 -0
- package/dist/renderer-6EEZHMH4.js +26 -0
- package/dist/renderer-6W5462RB.js +43 -0
- package/dist/renderer-7MVLWWQD.js +22 -0
- package/dist/renderer-AWWAF6XD.js +33 -0
- package/dist/renderer-BYCNMBF7.js +34 -0
- package/dist/renderer-CLJHQPBJ.js +29 -0
- package/dist/renderer-GHPZMFU2.js +15 -0
- package/dist/renderer-JGBKUCZD.js +16 -0
- package/dist/renderer-KQB7UGDS.js +19 -0
- package/dist/renderer-PGX2TKVS.js +24 -0
- package/dist/renderer-QIWVHWZO.js +15 -0
- package/dist/renderer-RPOA5YPZ.js +35 -0
- package/dist/renderer-SMIBCRVB.js +24 -0
- package/dist/renderer-T7YKC5VP.js +28 -0
- package/dist/renderer-TOCOVLHS.js +37 -0
- package/dist/renderer-UWA5XS74.js +39 -0
- package/dist/renderer-VACVQYML.js +25 -0
- package/dist/renderer-W4M6QLIJ.js +37 -0
- package/dist/renderer-WZRREQ2P.js +23 -0
- package/dist/renderer-YY2OSF6E.js +27 -0
- package/dist/renderer-Z7I3W2PP.js +24 -0
- package/dist/renderer-ZGNTUWC4.js +22 -0
- package/dist/renderer-ZTR3DER3.js +19 -0
- package/dist/renderer-radial-C32GPJQ7.js +21 -0
- package/dist/resolver-NOAA7ID7.js +13 -0
- package/dist/state-collapse-HCGD6IVJ.js +8 -0
- package/dist/state-parser-Z2V23ATR.js +18 -0
- package/dist/state-renderer-RFYHSP4K.js +34 -0
- package/dist/themes-1-CuKpeH.d.cts +908 -0
- package/dist/themes-1-CuKpeH.d.ts +908 -0
- package/package.json +1 -1
|
@@ -0,0 +1,613 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MAP_DIRECTIVE_KEY_SET
|
|
3
|
+
} from "./chunk-DKEPS5LH.js";
|
|
4
|
+
import {
|
|
5
|
+
AUTO_TAG_COLOR_SENTINEL,
|
|
6
|
+
finalizeAutoTagColors,
|
|
7
|
+
matchTagBlockHeading,
|
|
8
|
+
stripDefaultModifier,
|
|
9
|
+
tagAttrKey,
|
|
10
|
+
validateTagGroupNames
|
|
11
|
+
} from "./chunk-QLCCJEJI.js";
|
|
12
|
+
import {
|
|
13
|
+
parseInArrowLabel
|
|
14
|
+
} from "./chunk-FFUN5D66.js";
|
|
15
|
+
import {
|
|
16
|
+
MAP_REGISTRY,
|
|
17
|
+
extractColor,
|
|
18
|
+
measureIndent,
|
|
19
|
+
peelRampColors,
|
|
20
|
+
splitNameAndMeta,
|
|
21
|
+
withTagAliases
|
|
22
|
+
} from "./chunk-Y3J7VR52.js";
|
|
23
|
+
import {
|
|
24
|
+
formatDgmoError,
|
|
25
|
+
makeDgmoError
|
|
26
|
+
} from "./chunk-CXK4DZH3.js";
|
|
27
|
+
|
|
28
|
+
// src/map/parser.ts
|
|
29
|
+
var COORD_RE = /^[+-]?\d+(?:\.\d+)?\s+[+-]?\d+(?:\.\d+)?$/;
|
|
30
|
+
var NUMERIC_LEAD_RE = /^[+-]?\d/;
|
|
31
|
+
var SCOPE_RE = /^[A-Z]{2}(?:-[A-Z0-9]{1,3})?$/;
|
|
32
|
+
var ARROW_TOKENS = "-[^>]*?->|->|~[^>]*?~>|~>|-[^>]*?-|~[^>]*?~";
|
|
33
|
+
var ARROW_SPLIT = new RegExp(`\\s+(${ARROW_TOKENS})\\s+`);
|
|
34
|
+
var HUB_RE = new RegExp(`^(${ARROW_TOKENS})\\s+(.+)$`);
|
|
35
|
+
var LEG_ARROW_RE = new RegExp(`^(${ARROW_TOKENS})\\s+(.+)$`);
|
|
36
|
+
var AT_RE = /(^|[\s,])at\s*:/i;
|
|
37
|
+
var CHANNEL_FOREIGN = {
|
|
38
|
+
heat: ["size", "width"],
|
|
39
|
+
size: ["heat", "width"],
|
|
40
|
+
width: ["heat", "size"]
|
|
41
|
+
};
|
|
42
|
+
var CHANNEL_HINT = {
|
|
43
|
+
heat: "regions take `heat:`",
|
|
44
|
+
size: "points take `size:`",
|
|
45
|
+
width: "edges take `width:`"
|
|
46
|
+
};
|
|
47
|
+
var MAP_DIRECTIVE_SET = MAP_DIRECTIVE_KEY_SET;
|
|
48
|
+
var DIRECTIVE_SET = MAP_DIRECTIVE_SET;
|
|
49
|
+
function looksLikeMap(content) {
|
|
50
|
+
for (const raw of content.split("\n")) {
|
|
51
|
+
const t = stripInlineComment(raw).trim();
|
|
52
|
+
if (!t || t.startsWith("//")) continue;
|
|
53
|
+
return /^map(\s|$)/.test(t);
|
|
54
|
+
}
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
function stripInlineComment(line) {
|
|
58
|
+
return line.replace(/(^|\s)\/\/.*$/, (_m, p1) => p1).replace(/\s+$/, "");
|
|
59
|
+
}
|
|
60
|
+
function parseMap(content, palette) {
|
|
61
|
+
const result = {
|
|
62
|
+
title: null,
|
|
63
|
+
titleLineNumber: null,
|
|
64
|
+
directives: {},
|
|
65
|
+
tagGroups: [],
|
|
66
|
+
regions: [],
|
|
67
|
+
pois: [],
|
|
68
|
+
routes: [],
|
|
69
|
+
edges: [],
|
|
70
|
+
options: {},
|
|
71
|
+
diagnostics: [],
|
|
72
|
+
error: null
|
|
73
|
+
};
|
|
74
|
+
const diagnostics = result.diagnostics;
|
|
75
|
+
const pushError = (line, message, code) => {
|
|
76
|
+
diagnostics.push(makeDgmoError(line, message, "error", code));
|
|
77
|
+
result.error ??= formatDgmoError(diagnostics[diagnostics.length - 1]);
|
|
78
|
+
};
|
|
79
|
+
const fail = (line, message) => {
|
|
80
|
+
pushError(line, message);
|
|
81
|
+
return result;
|
|
82
|
+
};
|
|
83
|
+
const pushWarning = (line, message) => {
|
|
84
|
+
diagnostics.push(makeDgmoError(line, message, "warning"));
|
|
85
|
+
};
|
|
86
|
+
const lines = content.split("\n");
|
|
87
|
+
let firstIdx = 0;
|
|
88
|
+
while (firstIdx < lines.length) {
|
|
89
|
+
const t = stripInlineComment(lines[firstIdx]).trim();
|
|
90
|
+
if (t && !t.startsWith("//")) break;
|
|
91
|
+
firstIdx++;
|
|
92
|
+
}
|
|
93
|
+
const firstLine = stripInlineComment(lines[firstIdx] ?? "").trim();
|
|
94
|
+
const firstTok = firstLine.split(/\s+/)[0] ?? "";
|
|
95
|
+
if (firstTok !== "map") {
|
|
96
|
+
return fail(
|
|
97
|
+
firstIdx + 1,
|
|
98
|
+
`Expected chart type "map" on the first line, got "${firstTok || "(empty)"}"`
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
const titleText = firstLine.slice(3).trim();
|
|
102
|
+
if (titleText) {
|
|
103
|
+
result.title = titleText;
|
|
104
|
+
result.titleLineNumber = firstIdx + 1;
|
|
105
|
+
}
|
|
106
|
+
const tagGroups = result.tagGroups;
|
|
107
|
+
const regions = result.regions;
|
|
108
|
+
const pois = result.pois;
|
|
109
|
+
const routes = result.routes;
|
|
110
|
+
const edges = result.edges;
|
|
111
|
+
const aliasMap = /* @__PURE__ */ new Map();
|
|
112
|
+
const open = { tag: null, route: null, poi: null };
|
|
113
|
+
const registry = () => withTagAliases(MAP_REGISTRY, new Set(aliasMap.keys()));
|
|
114
|
+
const tagGroupNames = () => new Set(tagGroups.map((g) => tagAttrKey(g.name)));
|
|
115
|
+
const closeBlocks = () => {
|
|
116
|
+
open.tag = null;
|
|
117
|
+
open.route = null;
|
|
118
|
+
open.poi = null;
|
|
119
|
+
};
|
|
120
|
+
for (let i = firstIdx + 1; i < lines.length; i++) {
|
|
121
|
+
const raw = lines[i];
|
|
122
|
+
const lineNumber = i + 1;
|
|
123
|
+
const cleaned = stripInlineComment(raw);
|
|
124
|
+
const trimmed = cleaned.trim();
|
|
125
|
+
const indent = measureIndent(raw);
|
|
126
|
+
if (!trimmed || trimmed.startsWith("//")) continue;
|
|
127
|
+
if (open.tag && indent > 0) {
|
|
128
|
+
addTagEntry(open.tag, trimmed, lineNumber);
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (open.route && indent > open.route.indent) {
|
|
132
|
+
const leg = parseLeg(trimmed, lineNumber);
|
|
133
|
+
if (leg) open.route.route.legs.push(leg);
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
if (open.poi && indent > open.poi.indent) {
|
|
137
|
+
const hub = trimmed.match(HUB_RE);
|
|
138
|
+
if (hub) {
|
|
139
|
+
const src = open.poi.poi.alias ?? poiName(open.poi.poi.pos);
|
|
140
|
+
if (src) {
|
|
141
|
+
const arr = classifyArrow(hub[1], lineNumber);
|
|
142
|
+
const hubSplit = splitNameAndMeta(hub[2], registry(), aliasMap);
|
|
143
|
+
const { tags, meta } = partitionMeta(hubSplit.meta, tagGroupNames());
|
|
144
|
+
edges.push({
|
|
145
|
+
from: src,
|
|
146
|
+
to: hubSplit.name.trim(),
|
|
147
|
+
...arr.label !== void 0 && { label: arr.label },
|
|
148
|
+
directed: arr.directed,
|
|
149
|
+
style: arr.style,
|
|
150
|
+
meta,
|
|
151
|
+
tags,
|
|
152
|
+
lineNumber
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
const split = splitNameAndMeta(trimmed, registry(), aliasMap);
|
|
158
|
+
if (Object.keys(split.meta).length && !split.name) {
|
|
159
|
+
Object.assign(open.poi.poi.meta, split.meta);
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
if (split.name) {
|
|
163
|
+
const src = open.poi.poi.alias ?? poiName(open.poi.poi.pos) ?? "the poi";
|
|
164
|
+
pushError(
|
|
165
|
+
lineNumber,
|
|
166
|
+
`Malformed hub edge: "${trimmed}" \u2014 an indented line under a poi is an edge from "${src}" and needs an arrow glyph (\`-> dest\`, \`~> dest\`, or labeled \`-label-> dest\`). For a standalone place, declare it at the top level. (\xA724B.5)`
|
|
167
|
+
);
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
closeBlocks();
|
|
172
|
+
const firstWord = trimmed.split(/\s+/)[0];
|
|
173
|
+
if (firstWord === "tag") {
|
|
174
|
+
handleTag(trimmed, lineNumber);
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
if (DIRECTIVE_SET.has(firstWord) && !trimmed.slice(firstWord.length).trimStart().startsWith(":")) {
|
|
178
|
+
handleDirective(
|
|
179
|
+
firstWord,
|
|
180
|
+
trimmed.slice(firstWord.length).trim(),
|
|
181
|
+
lineNumber
|
|
182
|
+
);
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
if (firstWord === "poi") {
|
|
186
|
+
handlePoi(trimmed.slice(3).trim(), lineNumber, indent);
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
if (firstWord === "route") {
|
|
190
|
+
handleRoute(trimmed.slice(5).trim(), lineNumber, indent);
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
if (ARROW_SPLIT.test(" " + trimmed + " ") || ARROW_SPLIT.test(trimmed)) {
|
|
194
|
+
handleEdges(trimmed, lineNumber);
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
handleRegion(trimmed, lineNumber);
|
|
198
|
+
}
|
|
199
|
+
finalizeAutoTagColors(tagGroups, palette);
|
|
200
|
+
validateTagGroupNames(
|
|
201
|
+
tagGroups,
|
|
202
|
+
pushWarning,
|
|
203
|
+
(line, m) => pushError(line, m)
|
|
204
|
+
);
|
|
205
|
+
const at = result.directives.activeTag;
|
|
206
|
+
if (at && at.toLowerCase() !== "none") {
|
|
207
|
+
const names = tagGroupNames();
|
|
208
|
+
if (!names.has(at.toLowerCase())) {
|
|
209
|
+
const hint = tagGroups.length ? ` Declared groups: ${tagGroups.map((g) => g.name).join(", ")}.` : " No tag groups are declared.";
|
|
210
|
+
pushWarning(
|
|
211
|
+
0,
|
|
212
|
+
`active-tag "${at}" does not match a declared tag group.${hint}`
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return result;
|
|
217
|
+
function rejectForeignChannels(meta, own, line) {
|
|
218
|
+
for (const k of CHANNEL_FOREIGN[own]) {
|
|
219
|
+
if (meta[k] !== void 0) {
|
|
220
|
+
pushError(
|
|
221
|
+
line,
|
|
222
|
+
`\`${k}:\` is not a valid channel here \u2014 ${CHANNEL_HINT[own]} (\xA724B).`
|
|
223
|
+
);
|
|
224
|
+
delete meta[k];
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
function handleDirective(key, value, line) {
|
|
229
|
+
const d = result.directives;
|
|
230
|
+
const dup = (have) => {
|
|
231
|
+
if (have !== void 0)
|
|
232
|
+
pushWarning(line, `Duplicate directive "${key}" \u2014 last value wins.`);
|
|
233
|
+
};
|
|
234
|
+
switch (key) {
|
|
235
|
+
case "region-heat": {
|
|
236
|
+
dup(d.regionMetric);
|
|
237
|
+
const {
|
|
238
|
+
label: rmLabel,
|
|
239
|
+
low: rmLow,
|
|
240
|
+
high: rmHigh
|
|
241
|
+
} = peelRampColors(value);
|
|
242
|
+
d.regionMetric = rmLabel;
|
|
243
|
+
if (rmHigh) d.regionMetricColor = rmHigh;
|
|
244
|
+
if (rmLow) d.regionMetricLowColor = rmLow;
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
case "poi-size":
|
|
248
|
+
dup(d.poiMetric);
|
|
249
|
+
d.poiMetric = value;
|
|
250
|
+
break;
|
|
251
|
+
case "flow-width":
|
|
252
|
+
dup(d.flowMetric);
|
|
253
|
+
d.flowMetric = value;
|
|
254
|
+
break;
|
|
255
|
+
case "locale":
|
|
256
|
+
dup(d.locale);
|
|
257
|
+
d.locale = value;
|
|
258
|
+
break;
|
|
259
|
+
case "active-tag":
|
|
260
|
+
dup(d.activeTag);
|
|
261
|
+
d.activeTag = value;
|
|
262
|
+
break;
|
|
263
|
+
case "caption":
|
|
264
|
+
dup(d.caption);
|
|
265
|
+
d.caption = value;
|
|
266
|
+
break;
|
|
267
|
+
// ── Cosmetic `no-*` opt-outs: bare flags, idempotent (mirror `no-legend`,
|
|
268
|
+
// no dup warning); each defaults the feature ON when absent. ──
|
|
269
|
+
case "no-title":
|
|
270
|
+
d.noTitle = true;
|
|
271
|
+
break;
|
|
272
|
+
case "no-legend":
|
|
273
|
+
d.noLegend = true;
|
|
274
|
+
break;
|
|
275
|
+
case "no-coastline":
|
|
276
|
+
d.noCoastline = true;
|
|
277
|
+
break;
|
|
278
|
+
case "no-relief":
|
|
279
|
+
d.noRelief = true;
|
|
280
|
+
break;
|
|
281
|
+
case "no-context-labels":
|
|
282
|
+
d.noContextLabels = true;
|
|
283
|
+
break;
|
|
284
|
+
case "no-region-labels":
|
|
285
|
+
d.noRegionLabels = true;
|
|
286
|
+
break;
|
|
287
|
+
case "no-region-heat-value":
|
|
288
|
+
d.noRegionValue = true;
|
|
289
|
+
break;
|
|
290
|
+
case "no-poi-labels":
|
|
291
|
+
d.noPoiLabels = true;
|
|
292
|
+
break;
|
|
293
|
+
case "no-colorize":
|
|
294
|
+
d.noColorize = true;
|
|
295
|
+
break;
|
|
296
|
+
case "no-cities":
|
|
297
|
+
d.noCities = true;
|
|
298
|
+
break;
|
|
299
|
+
case "no-cluster-pois":
|
|
300
|
+
d.noClusterPois = true;
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
function handleTag(trimmed, line) {
|
|
305
|
+
const m = matchTagBlockHeading(trimmed);
|
|
306
|
+
if (!m) {
|
|
307
|
+
pushError(
|
|
308
|
+
line,
|
|
309
|
+
`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.`
|
|
310
|
+
);
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
const group = {
|
|
314
|
+
name: m.name,
|
|
315
|
+
...m.alias !== void 0 && { alias: m.alias },
|
|
316
|
+
entries: [],
|
|
317
|
+
lineNumber: line
|
|
318
|
+
};
|
|
319
|
+
if (m.alias) aliasMap.set(m.alias.toLowerCase(), tagAttrKey(m.name));
|
|
320
|
+
tagGroups.push(group);
|
|
321
|
+
open.tag = group;
|
|
322
|
+
if (m.inlineValues?.length) {
|
|
323
|
+
for (const seg of m.inlineValues) addTagEntry(group, seg.trim(), line);
|
|
324
|
+
open.tag = null;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
function addTagEntry(group, text, line) {
|
|
328
|
+
const { text: clean, isDefault } = stripDefaultModifier(text);
|
|
329
|
+
const { label, color } = extractColor(clean, palette, diagnostics, line);
|
|
330
|
+
const entries = group.entries;
|
|
331
|
+
if (isDefault || entries.length === 0) group.defaultValue = label;
|
|
332
|
+
entries.push({
|
|
333
|
+
value: label,
|
|
334
|
+
color: color ?? AUTO_TAG_COLOR_SENTINEL,
|
|
335
|
+
lineNumber: line
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
function handleRegion(trimmed, line) {
|
|
339
|
+
if (AT_RE.test(trimmed))
|
|
340
|
+
pushError(
|
|
341
|
+
line,
|
|
342
|
+
"Coordinates are positional, not `at:` \u2014 write region names bare and POIs as `poi <lat> <lon>`."
|
|
343
|
+
);
|
|
344
|
+
const split = splitNameAndMeta(
|
|
345
|
+
trimmed,
|
|
346
|
+
registry(),
|
|
347
|
+
aliasMap,
|
|
348
|
+
void 0,
|
|
349
|
+
diagnostics,
|
|
350
|
+
line
|
|
351
|
+
);
|
|
352
|
+
const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
|
|
353
|
+
rejectForeignChannels(meta, "heat", line);
|
|
354
|
+
let valueNum;
|
|
355
|
+
const value = meta["heat"];
|
|
356
|
+
if (value !== void 0) {
|
|
357
|
+
delete meta["heat"];
|
|
358
|
+
valueNum = Number(value);
|
|
359
|
+
if (!Number.isFinite(valueNum)) {
|
|
360
|
+
pushError(line, `heat must be a number (got "${value}").`);
|
|
361
|
+
valueNum = void 0;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
let regionName = split.name;
|
|
365
|
+
let regionScope;
|
|
366
|
+
const rToks = regionName.split(/\s+/);
|
|
367
|
+
const rLast = rToks[rToks.length - 1];
|
|
368
|
+
if (rToks.length > 1 && SCOPE_RE.test(rLast)) {
|
|
369
|
+
regionName = rToks.slice(0, -1).join(" ");
|
|
370
|
+
regionScope = rLast;
|
|
371
|
+
}
|
|
372
|
+
const region = {
|
|
373
|
+
name: regionName,
|
|
374
|
+
tags,
|
|
375
|
+
meta,
|
|
376
|
+
lineNumber: line
|
|
377
|
+
};
|
|
378
|
+
if (regionScope !== void 0) region.scope = regionScope;
|
|
379
|
+
if (valueNum !== void 0) region.value = valueNum;
|
|
380
|
+
if (split.color) region.color = split.color;
|
|
381
|
+
regions.push(region);
|
|
382
|
+
}
|
|
383
|
+
function handlePoi(rest, line, indent) {
|
|
384
|
+
if (AT_RE.test(rest))
|
|
385
|
+
pushError(
|
|
386
|
+
line,
|
|
387
|
+
"Coordinates are positional, not `at:` \u2014 write `poi <lat> <lon>`."
|
|
388
|
+
);
|
|
389
|
+
const split = splitNameAndMeta(
|
|
390
|
+
rest,
|
|
391
|
+
registry(),
|
|
392
|
+
aliasMap,
|
|
393
|
+
void 0,
|
|
394
|
+
diagnostics,
|
|
395
|
+
line
|
|
396
|
+
);
|
|
397
|
+
const pos = parsePos(split.name, line);
|
|
398
|
+
if (!pos) return;
|
|
399
|
+
const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
|
|
400
|
+
rejectForeignChannels(meta, "size", line);
|
|
401
|
+
const label = meta["label"];
|
|
402
|
+
if (label !== void 0) delete meta["label"];
|
|
403
|
+
const poi = { pos, tags, meta, lineNumber: line };
|
|
404
|
+
if (split.alias) poi.alias = split.alias;
|
|
405
|
+
if (label !== void 0) poi.label = label;
|
|
406
|
+
if (split.color) poi.color = split.color;
|
|
407
|
+
pois.push(poi);
|
|
408
|
+
open.poi = { poi, indent };
|
|
409
|
+
}
|
|
410
|
+
function handleRoute(rest, line, indent) {
|
|
411
|
+
const split = rest ? splitNameAndMeta(
|
|
412
|
+
rest,
|
|
413
|
+
registry(),
|
|
414
|
+
aliasMap,
|
|
415
|
+
void 0,
|
|
416
|
+
diagnostics,
|
|
417
|
+
line
|
|
418
|
+
) : { name: "", meta: {}, alias: void 0 };
|
|
419
|
+
const pos = parsePos(split.name, line);
|
|
420
|
+
if (!pos || pos.kind === "name" && !pos.name) {
|
|
421
|
+
pushError(
|
|
422
|
+
line,
|
|
423
|
+
"route needs an origin place \u2014 `route <origin>` then indented legs (`-> dest`); origin may be a city name, IATA code, or `<lat> <lon>`. (\xA724B)"
|
|
424
|
+
);
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
|
|
428
|
+
rejectForeignChannels(meta, "size", line);
|
|
429
|
+
const originLabel = meta["label"];
|
|
430
|
+
const originValue = meta["size"];
|
|
431
|
+
if (meta["style"] !== void 0) {
|
|
432
|
+
pushError(
|
|
433
|
+
line,
|
|
434
|
+
"route header no longer takes `style:` \u2014 set leg shape with the arrow glyph instead (`~\u2026~>` for an arc leg, `-\u2026->` for a straight one). (\xA724B.6)"
|
|
435
|
+
);
|
|
436
|
+
}
|
|
437
|
+
const route = {
|
|
438
|
+
origin: pos,
|
|
439
|
+
...split.alias !== void 0 && { originAlias: split.alias },
|
|
440
|
+
...originLabel !== void 0 && { originLabel },
|
|
441
|
+
...originValue !== void 0 && { originValue },
|
|
442
|
+
originTags: tags,
|
|
443
|
+
legs: [],
|
|
444
|
+
lineNumber: line
|
|
445
|
+
};
|
|
446
|
+
routes.push(route);
|
|
447
|
+
open.route = { route, indent };
|
|
448
|
+
}
|
|
449
|
+
function parseLeg(trimmed, line) {
|
|
450
|
+
const m = trimmed.match(LEG_ARROW_RE);
|
|
451
|
+
if (!m) {
|
|
452
|
+
pushError(
|
|
453
|
+
line,
|
|
454
|
+
`Malformed route leg: "${trimmed}" \u2014 a leg needs an arrow glyph (\`-> dest\`, \`~> dest\`, or labeled \`-label-> dest\` / \`~label~> dest\`). (\xA724B.6)`
|
|
455
|
+
);
|
|
456
|
+
return null;
|
|
457
|
+
}
|
|
458
|
+
const arr = classifyArrow(m[1], line);
|
|
459
|
+
if (!arr.directed) {
|
|
460
|
+
pushError(
|
|
461
|
+
line,
|
|
462
|
+
`A route leg is directional \u2014 "${trimmed}" uses an undirected glyph; use \`-> \` (straight) or \`~> \` (arc). (\xA724B.6)`
|
|
463
|
+
);
|
|
464
|
+
return null;
|
|
465
|
+
}
|
|
466
|
+
const arrowStyle = arr.style;
|
|
467
|
+
const label = arr.label;
|
|
468
|
+
const rest = m[2];
|
|
469
|
+
const split = splitNameAndMeta(
|
|
470
|
+
rest,
|
|
471
|
+
registry(),
|
|
472
|
+
aliasMap,
|
|
473
|
+
void 0,
|
|
474
|
+
diagnostics,
|
|
475
|
+
line
|
|
476
|
+
);
|
|
477
|
+
const pos = parsePos(split.name, line) ?? {
|
|
478
|
+
kind: "name",
|
|
479
|
+
name: split.name
|
|
480
|
+
};
|
|
481
|
+
const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
|
|
482
|
+
rejectForeignChannels(meta, "width", line);
|
|
483
|
+
const value = meta["width"];
|
|
484
|
+
const destLabel = meta["label"];
|
|
485
|
+
return {
|
|
486
|
+
...label !== void 0 && { label },
|
|
487
|
+
style: arrowStyle,
|
|
488
|
+
...value !== void 0 && { value },
|
|
489
|
+
dest: pos,
|
|
490
|
+
...split.alias !== void 0 && { destAlias: split.alias },
|
|
491
|
+
...destLabel !== void 0 && { destLabel },
|
|
492
|
+
tags,
|
|
493
|
+
// colour the LINE (§24B.6); stop tags go on the poi line
|
|
494
|
+
lineNumber: line
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
function handleEdges(trimmed, line) {
|
|
498
|
+
const parts = trimmed.split(ARROW_SPLIT);
|
|
499
|
+
if (parts.length < 3) {
|
|
500
|
+
pushError(
|
|
501
|
+
line,
|
|
502
|
+
`Malformed edge: "${trimmed}" \u2014 an edge is 'A -> B' (or 'A -label-> B', '~>' for arc, '--' undirected), both endpoints non-empty. (\xA724B)`
|
|
503
|
+
);
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
const endpoints = [];
|
|
507
|
+
const links = [];
|
|
508
|
+
for (let k = 0; k < parts.length; k++) {
|
|
509
|
+
if (k % 2 === 0) endpoints.push(parts[k].trim());
|
|
510
|
+
else links.push(classifyArrow(parts[k], line));
|
|
511
|
+
}
|
|
512
|
+
const lastSplit = splitNameAndMeta(
|
|
513
|
+
endpoints[endpoints.length - 1],
|
|
514
|
+
registry(),
|
|
515
|
+
aliasMap
|
|
516
|
+
);
|
|
517
|
+
endpoints[endpoints.length - 1] = lastSplit.name;
|
|
518
|
+
const { tags: lastTags, meta: lastMeta } = partitionMeta(
|
|
519
|
+
lastSplit.meta,
|
|
520
|
+
tagGroupNames()
|
|
521
|
+
);
|
|
522
|
+
rejectForeignChannels(lastMeta, "width", line);
|
|
523
|
+
for (let k = 0; k < links.length; k++) {
|
|
524
|
+
const from = endpoints[k];
|
|
525
|
+
const to = endpoints[k + 1];
|
|
526
|
+
if (!from || !to) {
|
|
527
|
+
pushError(
|
|
528
|
+
line,
|
|
529
|
+
`Edge has an empty endpoint: "${trimmed}" \u2014 both sides of the arrow need a place, e.g. 'Paris -> Berlin'. (\xA724B)`
|
|
530
|
+
);
|
|
531
|
+
continue;
|
|
532
|
+
}
|
|
533
|
+
const isLast = k === links.length - 1;
|
|
534
|
+
const meta = isLast ? lastMeta : {};
|
|
535
|
+
const tags = isLast ? lastTags : {};
|
|
536
|
+
const style = links[k].style === "arc" ? "arc" : "straight";
|
|
537
|
+
edges.push({
|
|
538
|
+
from,
|
|
539
|
+
to,
|
|
540
|
+
...links[k].label !== void 0 && { label: links[k].label },
|
|
541
|
+
directed: links[k].directed,
|
|
542
|
+
style,
|
|
543
|
+
meta,
|
|
544
|
+
tags,
|
|
545
|
+
lineNumber: line
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
function classifyArrow(tok, line) {
|
|
550
|
+
if (tok === "--") return { directed: false, style: "straight" };
|
|
551
|
+
if (tok === "~~") return { directed: false, style: "arc" };
|
|
552
|
+
if (tok === "->") return { directed: true, style: "straight" };
|
|
553
|
+
if (tok === "~>") return { directed: true, style: "arc" };
|
|
554
|
+
const directed = tok.endsWith(">");
|
|
555
|
+
const style = tok.startsWith("~") ? "arc" : "straight";
|
|
556
|
+
const inner = directed ? tok.slice(1, -2) : tok.slice(1, -1);
|
|
557
|
+
const lbl = parseInArrowLabel(inner, line);
|
|
558
|
+
lbl.diagnostics.forEach((d) => diagnostics.push(d));
|
|
559
|
+
return {
|
|
560
|
+
...lbl.label !== void 0 && { label: lbl.label },
|
|
561
|
+
directed,
|
|
562
|
+
style
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
function parsePos(nameRegion, line) {
|
|
566
|
+
const n = nameRegion.trim();
|
|
567
|
+
if (COORD_RE.test(n)) {
|
|
568
|
+
const [latS, lonS] = n.split(/\s+/);
|
|
569
|
+
const lat = Number(latS);
|
|
570
|
+
const lon = Number(lonS);
|
|
571
|
+
if (lat < -90 || lat > 90 || lon < -180 || lon > 180) {
|
|
572
|
+
pushError(
|
|
573
|
+
line,
|
|
574
|
+
`Coordinates out of range: lat ${lat}, lon ${lon} (lat \u2208 [-90,90], lon \u2208 [-180,180]).`
|
|
575
|
+
);
|
|
576
|
+
return null;
|
|
577
|
+
}
|
|
578
|
+
return { kind: "coords", lat, lon };
|
|
579
|
+
}
|
|
580
|
+
if (NUMERIC_LEAD_RE.test(n)) {
|
|
581
|
+
pushError(
|
|
582
|
+
line,
|
|
583
|
+
`Malformed coordinates "${n}" \u2014 expected "<lat> <lon>" (two signed numbers).`
|
|
584
|
+
);
|
|
585
|
+
return null;
|
|
586
|
+
}
|
|
587
|
+
const toks = n.split(/\s+/);
|
|
588
|
+
const last = toks[toks.length - 1];
|
|
589
|
+
if (toks.length > 1 && SCOPE_RE.test(last)) {
|
|
590
|
+
return { kind: "name", name: toks.slice(0, -1).join(" "), scope: last };
|
|
591
|
+
}
|
|
592
|
+
return { kind: "name", name: n };
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
function partitionMeta(meta, tagGroupNames) {
|
|
596
|
+
const tags = {};
|
|
597
|
+
const inert = {};
|
|
598
|
+
for (const [k, v] of Object.entries(meta)) {
|
|
599
|
+
if (tagGroupNames.has(k)) tags[k] = v;
|
|
600
|
+
else inert[k] = v;
|
|
601
|
+
}
|
|
602
|
+
return { tags, meta: inert };
|
|
603
|
+
}
|
|
604
|
+
function poiName(pos) {
|
|
605
|
+
return pos.kind === "name" ? pos.name : void 0;
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
export {
|
|
609
|
+
MAP_DIRECTIVE_SET,
|
|
610
|
+
looksLikeMap,
|
|
611
|
+
parseMap
|
|
612
|
+
};
|
|
613
|
+
//# sourceMappingURL=chunk-BUPDIHML.js.map
|