@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.
Files changed (232) hide show
  1. package/dist/advanced.d.cts +3 -855
  2. package/dist/advanced.d.ts +3 -855
  3. package/dist/advanced.js +541 -70107
  4. package/dist/analyzer-UYKBXAKR.js +15 -0
  5. package/dist/auto.cjs +1 -1
  6. package/dist/auto.js +1 -1
  7. package/dist/auto.mjs +1 -1
  8. package/dist/block.js +83 -69417
  9. package/dist/calculator-LDYQCDDY.js +11 -0
  10. package/dist/charts-d3-QOZHKTCT.js +25 -0
  11. package/dist/chunk-2DXMZRWJ.js +800 -0
  12. package/dist/chunk-2LACINWN.js +786 -0
  13. package/dist/chunk-33LCUH4H.js +893 -0
  14. package/dist/chunk-3CIOJ5YJ.js +35 -0
  15. package/dist/chunk-3HDBAXF5.js +86 -0
  16. package/dist/chunk-3JLKYGBQ.js +290 -0
  17. package/dist/chunk-3MQQNXPD.js +415 -0
  18. package/dist/chunk-3R5POCTZ.js +967 -0
  19. package/dist/chunk-3SMGIJDD.js +112 -0
  20. package/dist/chunk-44CM72SQ.js +409 -0
  21. package/dist/chunk-4GRI7MEB.js +1604 -0
  22. package/dist/chunk-4OHACBGX.js +606 -0
  23. package/dist/chunk-5DH3KYFH.js +21 -0
  24. package/dist/chunk-5MLYVTYM.js +76 -0
  25. package/dist/chunk-5QXL4NYS.js +553 -0
  26. package/dist/chunk-5WRI5ZAA.js +31 -0
  27. package/dist/chunk-6EK55ART.js +117 -0
  28. package/dist/chunk-6FZYCKXB.js +2065 -0
  29. package/dist/chunk-6HO5ZTXK.js +277 -0
  30. package/dist/chunk-6KFWC4CO.js +7 -0
  31. package/dist/chunk-6MTWIQVO.js +121 -0
  32. package/dist/chunk-6NYWYNBI.js +329 -0
  33. package/dist/chunk-6SM5NJQH.js +620 -0
  34. package/dist/chunk-725LDASD.js +422 -0
  35. package/dist/chunk-76OWZ3BA.js +130 -0
  36. package/dist/chunk-7JEGTRLD.js +338 -0
  37. package/dist/chunk-A44USUV7.js +923 -0
  38. package/dist/chunk-A4GOY3PE.js +25 -0
  39. package/dist/chunk-A4VFQH5G.js +251 -0
  40. package/dist/chunk-AELOBFW5.js +375 -0
  41. package/dist/chunk-AN2MOO5T.js +522 -0
  42. package/dist/chunk-BMR4CIEO.js +41 -0
  43. package/dist/chunk-BS7SV7C3.js +51 -0
  44. package/dist/chunk-BUPDIHML.js +613 -0
  45. package/dist/chunk-BUVJFRPY.js +887 -0
  46. package/dist/chunk-C3Z4DX3V.js +112 -0
  47. package/dist/chunk-CI2G3OEB.js +1818 -0
  48. package/dist/chunk-CKNVO24D.js +54 -0
  49. package/dist/chunk-CUVHQHZ7.js +391 -0
  50. package/dist/chunk-CXK4DZH3.js +114 -0
  51. package/dist/chunk-DKEPS5LH.js +315 -0
  52. package/dist/chunk-DU7W62N5.js +487 -0
  53. package/dist/chunk-DZAQBW35.js +751 -0
  54. package/dist/chunk-EB6FPQUP.js +316 -0
  55. package/dist/chunk-EMS2SK26.js +376 -0
  56. package/dist/chunk-ERLBPDGU.js +510 -0
  57. package/dist/chunk-EVCVDTXE.js +732 -0
  58. package/dist/chunk-FCIIHT24.js +384 -0
  59. package/dist/chunk-FFUN5D66.js +97 -0
  60. package/dist/chunk-FITOLXSX.js +714 -0
  61. package/dist/chunk-FMDSF3OV.js +68 -0
  62. package/dist/chunk-FNB3PNGF.js +410 -0
  63. package/dist/chunk-G2H74XJZ.js +2104 -0
  64. package/dist/chunk-GMR5MFHJ.js +339 -0
  65. package/dist/chunk-H6PI3KJT.js +305 -0
  66. package/dist/chunk-I46X5VUA.js +59 -0
  67. package/dist/chunk-I5IGB56C.js +255 -0
  68. package/dist/chunk-IH6ZMVQ5.js +3950 -0
  69. package/dist/chunk-IJZFN3HM.js +463 -0
  70. package/dist/chunk-IPWPWM6R.js +3079 -0
  71. package/dist/chunk-IYULMRBE.js +23 -0
  72. package/dist/chunk-IZMRON6C.js +167 -0
  73. package/dist/chunk-J5FIXQRT.js +813 -0
  74. package/dist/chunk-JED6ZDEE.js +73 -0
  75. package/dist/chunk-JEUJOX5X.js +136 -0
  76. package/dist/chunk-JM4LEPY3.js +436 -0
  77. package/dist/chunk-L3UHP6TD.js +101 -0
  78. package/dist/chunk-L66GEFB6.js +524 -0
  79. package/dist/chunk-LIOHW36Z.js +469 -0
  80. package/dist/chunk-LP7EC4MI.js +16 -0
  81. package/dist/chunk-MITI6NOL.js +548 -0
  82. package/dist/chunk-MO5YHHMQ.js +168 -0
  83. package/dist/chunk-MZSBFAPJ.js +885 -0
  84. package/dist/chunk-NNAAJVBU.js +9 -0
  85. package/dist/chunk-NOTA6TEI.js +47 -0
  86. package/dist/chunk-NURGB5Z4.js +335 -0
  87. package/dist/chunk-NX4EQS3U.js +1062 -0
  88. package/dist/chunk-NXMESY4J.js +1 -0
  89. package/dist/chunk-OJR3MQYV.js +1458 -0
  90. package/dist/chunk-OURHMODR.js +454 -0
  91. package/dist/chunk-P235SVAH.js +1057 -0
  92. package/dist/chunk-P4RH4OSP.js +1038 -0
  93. package/dist/chunk-P6T66CCZ.js +226 -0
  94. package/dist/chunk-PBAHEPLQ.js +223 -0
  95. package/dist/chunk-PBHE5UG6.js +1530 -0
  96. package/dist/chunk-PDKUANDZ.js +35 -0
  97. package/dist/chunk-PWIHZ6NJ.js +296 -0
  98. package/dist/chunk-QEBUY5NY.js +1685 -0
  99. package/dist/chunk-QLCCJEJI.js +253 -0
  100. package/dist/chunk-QOOUC2J5.js +52 -0
  101. package/dist/chunk-QYTPPDAO.js +402 -0
  102. package/dist/chunk-R3XI2VC7.js +801 -0
  103. package/dist/chunk-RCERWOJR.js +154 -0
  104. package/dist/chunk-RJE5JTVK.js +362 -0
  105. package/dist/chunk-RTLBSQ3G.js +1155 -0
  106. package/dist/chunk-RUNNI6VE.js +448 -0
  107. package/dist/chunk-RVMRZAPB.js +354 -0
  108. package/dist/chunk-RYEGFMUO.js +955 -0
  109. package/dist/chunk-RZCF2VVM.js +528 -0
  110. package/dist/chunk-SML67VPV.js +1025 -0
  111. package/dist/chunk-SQ7IY53Q.js +44 -0
  112. package/dist/chunk-SQAG3UXH.js +161 -0
  113. package/dist/chunk-SRTU6HMQ.js +1851 -0
  114. package/dist/chunk-T2OE3YQB.js +550 -0
  115. package/dist/chunk-T3UBLACL.js +299 -0
  116. package/dist/chunk-TLVIHFRO.js +296 -0
  117. package/dist/chunk-TYS6CSS5.js +52 -0
  118. package/dist/chunk-U6EQI3U6.js +130 -0
  119. package/dist/chunk-UJ4FJLBF.js +86 -0
  120. package/dist/chunk-ULOEATBZ.js +347 -0
  121. package/dist/chunk-UNCCZ3NU.js +127 -0
  122. package/dist/chunk-USZW2HHU.js +197 -0
  123. package/dist/chunk-UWN33VNX.js +1610 -0
  124. package/dist/chunk-UZ7EZW3B.js +40 -0
  125. package/dist/chunk-VOKGH627.js +37 -0
  126. package/dist/chunk-WBRZJOEC.js +204 -0
  127. package/dist/chunk-WCSOJFU3.js +380 -0
  128. package/dist/chunk-WCT3NYCV.js +160 -0
  129. package/dist/chunk-WVAJFAIA.js +529 -0
  130. package/dist/chunk-X5LCYCL5.js +394 -0
  131. package/dist/chunk-XAKEUMEJ.js +1256 -0
  132. package/dist/chunk-Y2ZE3MSG.js +590 -0
  133. package/dist/chunk-Y3J7VR52.js +646 -0
  134. package/dist/chunk-Y5QGVTVC.js +33 -0
  135. package/dist/chunk-YAA6IID3.js +548 -0
  136. package/dist/chunk-YGJTDXVR.js +692 -0
  137. package/dist/chunk-YRYKTYMQ.js +186 -0
  138. package/dist/chunk-YYVTBZZC.js +61 -0
  139. package/dist/chunk-Z5CGSFJB.js +647 -0
  140. package/dist/chunk-Z72XRXD4.js +787 -0
  141. package/dist/chunk-ZGR7ULFJ.js +978 -0
  142. package/dist/chunk-ZJEL4H2R.js +851 -0
  143. package/dist/chunk-ZO27FGJS.js +554 -0
  144. package/dist/collapse-CLPJD2RL.js +11 -0
  145. package/dist/collapse-SLINJQW6.js +9 -0
  146. package/dist/collapse-ZWUFFCK2.js +9 -0
  147. package/dist/compute-G55RG53N.js +8 -0
  148. package/dist/dgmo-router-DZCIDUO5.js +73 -0
  149. package/dist/dimensions-J3FHIMJ6.js +22 -0
  150. package/dist/element.cjs +1 -1
  151. package/dist/element.js +1 -1
  152. package/dist/element.mjs +1 -1
  153. package/dist/flowchart-parser-ZNSKIBVR.js +21 -0
  154. package/dist/flowchart-renderer-ZAEOL4DX.js +35 -0
  155. package/dist/index.cjs +3 -3
  156. package/dist/index.d.cts +3 -469
  157. package/dist/index.d.ts +3 -469
  158. package/dist/index.js +137 -69685
  159. package/dist/layout-46N4JJYK.js +17 -0
  160. package/dist/layout-5RA6QWR6.js +26 -0
  161. package/dist/layout-5T6RH5M6.js +14 -0
  162. package/dist/layout-7QXCNOVS.js +13 -0
  163. package/dist/layout-EE6GE46Y.js +17 -0
  164. package/dist/layout-G23F7LDH.js +9 -0
  165. package/dist/layout-HRBZPFCN.js +23 -0
  166. package/dist/layout-HWDSRX5E.js +20 -0
  167. package/dist/layout-HYZPWAK5.js +18 -0
  168. package/dist/layout-N76NR4ZO.js +19 -0
  169. package/dist/layout-OB3RI63S.js +14 -0
  170. package/dist/layout-S2QBYSK2.js +15 -0
  171. package/dist/layout-UM5F4DJB.js +15 -0
  172. package/dist/layout-search-OYV77HHS.js +1655 -0
  173. package/dist/load-data-EHDDZ5ZS.js +8 -0
  174. package/dist/palettes-PRJ2RI6D.js +56 -0
  175. package/dist/parser-2MFP2H2E.js +11 -0
  176. package/dist/parser-3STE62GB.js +21 -0
  177. package/dist/parser-4FL2CMDG.js +18 -0
  178. package/dist/parser-4OGOBJJ4.js +13 -0
  179. package/dist/parser-6BTRLKRZ.js +15 -0
  180. package/dist/parser-AQETEVRW.js +21 -0
  181. package/dist/parser-CFZD5IBL.js +12 -0
  182. package/dist/parser-FUSKFGZN.js +16 -0
  183. package/dist/parser-I6KXEYFK.js +13 -0
  184. package/dist/parser-IXSZZQHY.js +18 -0
  185. package/dist/parser-JAL2HD4I.js +13 -0
  186. package/dist/parser-KNSQSKQO.js +20 -0
  187. package/dist/parser-N5O4IHUN.js +13 -0
  188. package/dist/parser-NGU3ETO6.js +16 -0
  189. package/dist/parser-NRAI6O25.js +19 -0
  190. package/dist/parser-O5J4VBII.js +11 -0
  191. package/dist/parser-OV7NOBW6.js +21 -0
  192. package/dist/parser-PQ3POX45.js +23 -0
  193. package/dist/parser-TFZFBVWN.js +11 -0
  194. package/dist/parser-TRTHDFPP.js +18 -0
  195. package/dist/parser-VQP2UJ6W.js +11 -0
  196. package/dist/parser-XDVELHRK.js +13 -0
  197. package/dist/parser-XKRP7QKP.js +11 -0
  198. package/dist/parser-Y6WTBU76.js +14 -0
  199. package/dist/parser-ZSDPZYQP.js +12 -0
  200. package/dist/renderer-2XQQQ6QR.js +28 -0
  201. package/dist/renderer-5NDVNDAZ.js +26 -0
  202. package/dist/renderer-6EEZHMH4.js +26 -0
  203. package/dist/renderer-6W5462RB.js +43 -0
  204. package/dist/renderer-7MVLWWQD.js +22 -0
  205. package/dist/renderer-AWWAF6XD.js +33 -0
  206. package/dist/renderer-BYCNMBF7.js +34 -0
  207. package/dist/renderer-CLJHQPBJ.js +29 -0
  208. package/dist/renderer-GHPZMFU2.js +15 -0
  209. package/dist/renderer-JGBKUCZD.js +16 -0
  210. package/dist/renderer-KQB7UGDS.js +19 -0
  211. package/dist/renderer-PGX2TKVS.js +24 -0
  212. package/dist/renderer-QIWVHWZO.js +15 -0
  213. package/dist/renderer-RPOA5YPZ.js +35 -0
  214. package/dist/renderer-SMIBCRVB.js +24 -0
  215. package/dist/renderer-T7YKC5VP.js +28 -0
  216. package/dist/renderer-TOCOVLHS.js +37 -0
  217. package/dist/renderer-UWA5XS74.js +39 -0
  218. package/dist/renderer-VACVQYML.js +25 -0
  219. package/dist/renderer-W4M6QLIJ.js +37 -0
  220. package/dist/renderer-WZRREQ2P.js +23 -0
  221. package/dist/renderer-YY2OSF6E.js +27 -0
  222. package/dist/renderer-Z7I3W2PP.js +24 -0
  223. package/dist/renderer-ZGNTUWC4.js +22 -0
  224. package/dist/renderer-ZTR3DER3.js +19 -0
  225. package/dist/renderer-radial-C32GPJQ7.js +21 -0
  226. package/dist/resolver-NOAA7ID7.js +13 -0
  227. package/dist/state-collapse-HCGD6IVJ.js +8 -0
  228. package/dist/state-parser-Z2V23ATR.js +18 -0
  229. package/dist/state-renderer-RFYHSP4K.js +34 -0
  230. package/dist/themes-1-CuKpeH.d.cts +908 -0
  231. package/dist/themes-1-CuKpeH.d.ts +908 -0
  232. package/package.json +1 -1
@@ -0,0 +1,887 @@
1
+ import {
2
+ AUTO_TAG_COLOR_SENTINEL,
3
+ finalizeAutoTagColors,
4
+ injectDefaultTagMetadata,
5
+ matchTagBlockHeading,
6
+ stripDefaultModifier,
7
+ tagAttrKey,
8
+ validateTagGroupNames,
9
+ validateTagValues
10
+ } from "./chunk-QLCCJEJI.js";
11
+ import {
12
+ tryCollectNote
13
+ } from "./chunk-5MLYVTYM.js";
14
+ import {
15
+ resolveNotes
16
+ } from "./chunk-FMDSF3OV.js";
17
+ import {
18
+ parseInArrowLabel
19
+ } from "./chunk-FFUN5D66.js";
20
+ import {
21
+ normalizeName
22
+ } from "./chunk-NOTA6TEI.js";
23
+ import {
24
+ BOXES_AND_LINES_REGISTRY,
25
+ OPTION_NOCOLON_RE,
26
+ extractColor,
27
+ parseFirstLine,
28
+ peelRampColors,
29
+ splitNameAndMeta,
30
+ tryParseSharedOption,
31
+ warnUnknownMetaKeys,
32
+ withTagAliases
33
+ } from "./chunk-Y3J7VR52.js";
34
+ import {
35
+ makeDgmoError,
36
+ suggest
37
+ } from "./chunk-CXK4DZH3.js";
38
+
39
+ // src/boxes-and-lines/parser.ts
40
+ var MAX_GROUP_DEPTH = 2;
41
+ function looksLikeBoxesAndLines(_content) {
42
+ return false;
43
+ }
44
+ function measureIndent(line) {
45
+ let count = 0;
46
+ for (const ch of line) {
47
+ if (ch === " ") count++;
48
+ else if (ch === " ") count += 4;
49
+ else break;
50
+ }
51
+ return count;
52
+ }
53
+ function parseTailMeta(rawTail, metaAliasMap) {
54
+ const segment = rawTail.trim();
55
+ if (!segment) return { metadata: {} };
56
+ const metadata = {};
57
+ let description;
58
+ for (const item of segment.split(",")) {
59
+ const trimmed = item.trim();
60
+ if (!trimmed) continue;
61
+ const colonIdx = trimmed.indexOf(":");
62
+ if (colonIdx >= 0) {
63
+ const rawKey = trimmed.slice(0, colonIdx).trim().toLowerCase();
64
+ const value = trimmed.slice(colonIdx + 1).trim();
65
+ if (rawKey === "description") {
66
+ description = [value];
67
+ } else {
68
+ const resolvedKey = metaAliasMap.get(rawKey) ?? rawKey;
69
+ metadata[resolvedKey] = value;
70
+ }
71
+ }
72
+ }
73
+ return { metadata, ...description !== void 0 && { description } };
74
+ }
75
+ function groupId(label) {
76
+ return `__group_${label}`;
77
+ }
78
+ function parseBoxesAndLines(content, palette) {
79
+ const options = {};
80
+ const notes = [];
81
+ const initialHiddenTagValues = /* @__PURE__ */ new Map();
82
+ const nodes = [];
83
+ const edges = [];
84
+ const groups = [];
85
+ const nodePositions = /* @__PURE__ */ new Map();
86
+ const result = {
87
+ type: "boxes-and-lines",
88
+ title: null,
89
+ titleLineNumber: null,
90
+ nodes,
91
+ edges,
92
+ groups,
93
+ tagGroups: [],
94
+ options,
95
+ initialHiddenTagValues,
96
+ direction: "LR",
97
+ diagnostics: [],
98
+ error: null
99
+ };
100
+ const lines = content.split("\n");
101
+ const nodeLabels = /* @__PURE__ */ new Set();
102
+ const groupLabels = /* @__PURE__ */ new Set();
103
+ let lastNodeLabel = null;
104
+ let lastSourceIsGroup = false;
105
+ let lastNodeIndent = 0;
106
+ let descState = null;
107
+ function flushDescription() {
108
+ if (descState && descState.lines.length > 0) {
109
+ const node = nodes.find((n) => n.label === descState.nodeLabel);
110
+ if (node) {
111
+ const existing = node.description ?? [];
112
+ node.description = [...existing, ...descState.lines];
113
+ }
114
+ }
115
+ descState = null;
116
+ }
117
+ const groupStack = [];
118
+ let contentStarted = false;
119
+ let inLayoutBlock = false;
120
+ const LAYOUT_ENTRY_RE = /^(.+?):\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*$/;
121
+ let currentTagGroup = null;
122
+ const metaAliasMap = /* @__PURE__ */ new Map();
123
+ const nameAliasMap = /* @__PURE__ */ new Map();
124
+ function peelAlias(label) {
125
+ const trimmed = label.trim();
126
+ const m = trimmed.match(/^(.*?)\s+as\s+([A-Za-z][A-Za-z0-9_]{0,11})\s*$/);
127
+ if (!m) return { label: trimmed };
128
+ return { label: m[1].trim(), alias: m[2] };
129
+ }
130
+ const pushWarning = (lineNumber, message) => {
131
+ result.diagnostics.push(makeDgmoError(lineNumber, message, "warning"));
132
+ };
133
+ function currentGroupState() {
134
+ return groupStack.length > 0 ? groupStack[groupStack.length - 1] : null;
135
+ }
136
+ function closeGroupsToIndent(indent) {
137
+ while (groupStack.length > 0 && // In-bounds by length guard.
138
+ groupStack[groupStack.length - 1].indent >= indent) {
139
+ const gs = groupStack.pop();
140
+ result.groups.push(gs.group);
141
+ }
142
+ }
143
+ function ensureNode(label, lineNum) {
144
+ const key = normalizeName(label);
145
+ if (!nodeLabels.has(key)) {
146
+ result.nodes.push({
147
+ label,
148
+ lineNumber: lineNum,
149
+ metadata: {}
150
+ });
151
+ nodeLabels.add(key);
152
+ }
153
+ }
154
+ for (let i = 0; i < lines.length; i++) {
155
+ const lineNum = i + 1;
156
+ const raw = lines[i];
157
+ const trimmed = raw.trim();
158
+ const indent = measureIndent(raw);
159
+ if (!trimmed || trimmed.startsWith("//")) continue;
160
+ const firstLineResult = parseFirstLine(trimmed);
161
+ if (firstLineResult && !contentStarted && i < 5) {
162
+ if (firstLineResult.chartType !== "boxes-and-lines") {
163
+ const diag = makeDgmoError(
164
+ lineNum,
165
+ `Expected chart type "boxes-and-lines", got "${firstLineResult.chartType}"`
166
+ );
167
+ result.diagnostics.push(diag);
168
+ result.error = diag.message;
169
+ return result;
170
+ }
171
+ if (firstLineResult.title) {
172
+ result.title = firstLineResult.title;
173
+ result.titleLineNumber = lineNum;
174
+ }
175
+ continue;
176
+ }
177
+ if (indent === 0) {
178
+ const dirMatch = trimmed.match(/^direction\s+(TB|LR)$/i);
179
+ if (dirMatch) {
180
+ result.direction = dirMatch[1].toUpperCase();
181
+ continue;
182
+ }
183
+ const hideMatch = trimmed.match(/^hide\s+(.+)/i);
184
+ if (hideMatch && !trimmed.match(/^hide\s*\|/)) {
185
+ const pairs = hideMatch[1].split(",");
186
+ for (const pair of pairs) {
187
+ const colonIdx = pair.indexOf(":");
188
+ if (colonIdx > 0) {
189
+ const groupKey = pair.substring(0, colonIdx).trim().toLowerCase();
190
+ const value = pair.substring(colonIdx + 1).trim().toLowerCase();
191
+ if (groupKey && value) {
192
+ if (!initialHiddenTagValues.has(groupKey)) {
193
+ initialHiddenTagValues.set(groupKey, /* @__PURE__ */ new Set());
194
+ }
195
+ initialHiddenTagValues.get(groupKey).add(value);
196
+ }
197
+ }
198
+ }
199
+ continue;
200
+ }
201
+ if (!contentStarted) {
202
+ const metricMatch = trimmed.match(/^heat\s+(.+)$/i);
203
+ if (metricMatch) {
204
+ const { label, low, high } = peelRampColors(metricMatch[1].trim());
205
+ result.boxMetric = label;
206
+ if (high !== void 0) result.boxMetricColor = high;
207
+ if (low !== void 0) result.boxMetricLowColor = low;
208
+ continue;
209
+ }
210
+ if (/^show-values$/i.test(trimmed)) {
211
+ result.showValues = true;
212
+ continue;
213
+ }
214
+ }
215
+ if (!contentStarted) {
216
+ const optMatch = trimmed.match(OPTION_NOCOLON_RE);
217
+ if (optMatch) {
218
+ const key2 = optMatch[1].toLowerCase();
219
+ const value = optMatch[2].trim();
220
+ if (key2 === "active-tag") {
221
+ options[key2] = value;
222
+ continue;
223
+ }
224
+ }
225
+ if (tryParseSharedOption(trimmed, options)) {
226
+ continue;
227
+ }
228
+ }
229
+ }
230
+ if (indent === 0) {
231
+ const noteResult = tryCollectNote(
232
+ lines,
233
+ i,
234
+ indent,
235
+ palette,
236
+ result.diagnostics
237
+ );
238
+ if (noteResult) {
239
+ if (noteResult.note) notes.push(noteResult.note);
240
+ i = noteResult.lastIndex;
241
+ continue;
242
+ }
243
+ }
244
+ const tagBlockMatch = matchTagBlockHeading(trimmed);
245
+ if (tagBlockMatch && indent === 0) {
246
+ if (contentStarted) {
247
+ result.diagnostics.push(
248
+ makeDgmoError(
249
+ lineNum,
250
+ "Tag groups must appear before diagram content",
251
+ "error"
252
+ )
253
+ );
254
+ continue;
255
+ }
256
+ const newTagGroup = {
257
+ name: tagBlockMatch.name,
258
+ ...tagBlockMatch.alias !== void 0 && {
259
+ alias: tagBlockMatch.alias
260
+ },
261
+ entries: [],
262
+ lineNumber: lineNum
263
+ };
264
+ currentTagGroup = newTagGroup;
265
+ if (tagBlockMatch.alias) {
266
+ metaAliasMap.set(
267
+ normalizeName(tagBlockMatch.alias),
268
+ tagAttrKey(tagBlockMatch.name)
269
+ );
270
+ }
271
+ metaAliasMap.set(
272
+ normalizeName(tagBlockMatch.name),
273
+ tagAttrKey(tagBlockMatch.name)
274
+ );
275
+ if (tagBlockMatch.inlineValues) {
276
+ for (const rawVal of tagBlockMatch.inlineValues) {
277
+ const { text: cleanVal, isDefault } = stripDefaultModifier(rawVal);
278
+ const { label, color } = extractColor(
279
+ cleanVal,
280
+ palette,
281
+ result.diagnostics,
282
+ lineNum
283
+ );
284
+ newTagGroup.entries.push({
285
+ value: label,
286
+ color: color ?? AUTO_TAG_COLOR_SENTINEL,
287
+ lineNumber: lineNum
288
+ });
289
+ if (isDefault) newTagGroup.defaultValue = label;
290
+ }
291
+ if (!newTagGroup.defaultValue && newTagGroup.entries.length > 0) {
292
+ newTagGroup.defaultValue = newTagGroup.entries[0].value;
293
+ }
294
+ }
295
+ result.tagGroups.push(newTagGroup);
296
+ continue;
297
+ }
298
+ if (currentTagGroup && !contentStarted && indent > 0) {
299
+ const { text: cleanEntry, isDefault } = stripDefaultModifier(trimmed);
300
+ const { label, color } = extractColor(
301
+ cleanEntry,
302
+ palette,
303
+ result.diagnostics,
304
+ lineNum
305
+ );
306
+ currentTagGroup.entries.push({
307
+ value: label,
308
+ color: color ?? AUTO_TAG_COLOR_SENTINEL,
309
+ lineNumber: lineNum
310
+ });
311
+ if (isDefault) {
312
+ currentTagGroup.defaultValue = label;
313
+ } else if (currentTagGroup.entries.length === 1) {
314
+ currentTagGroup.defaultValue = label;
315
+ }
316
+ continue;
317
+ }
318
+ if (currentTagGroup && indent === 0) {
319
+ currentTagGroup = null;
320
+ }
321
+ if (!inLayoutBlock && indent === 0 && trimmed === "layout") {
322
+ let isBlock = false;
323
+ for (let j = i + 1; j < lines.length; j++) {
324
+ const peek = lines[j];
325
+ if (!peek.trim()) continue;
326
+ isBlock = measureIndent(peek) > 0 && LAYOUT_ENTRY_RE.test(peek.trim());
327
+ break;
328
+ }
329
+ if (isBlock) {
330
+ flushDescription();
331
+ closeGroupsToIndent(0);
332
+ inLayoutBlock = true;
333
+ continue;
334
+ }
335
+ }
336
+ if (inLayoutBlock) {
337
+ if (indent > 0) {
338
+ const lm = trimmed.match(LAYOUT_ENTRY_RE);
339
+ if (lm) {
340
+ nodePositions.set(lm[1].trim(), {
341
+ x: Number(lm[2]),
342
+ y: Number(lm[3])
343
+ });
344
+ } else {
345
+ result.diagnostics.push(
346
+ makeDgmoError(
347
+ lineNum,
348
+ `Invalid layout entry "${trimmed}" \u2014 expected "<node-id>: <x>, <y>"`,
349
+ "warning"
350
+ )
351
+ );
352
+ }
353
+ continue;
354
+ }
355
+ inLayoutBlock = false;
356
+ }
357
+ if (descState !== null) {
358
+ if (indent > descState.indent) {
359
+ if (trimmed.includes("->") || trimmed.includes("<->")) {
360
+ descState.edgeSeen = true;
361
+ } else if (descState.edgeSeen) {
362
+ result.diagnostics.push(
363
+ makeDgmoError(
364
+ lineNum,
365
+ `Move description lines above edges for '${descState.nodeLabel}' \u2014 descriptions must come before -> lines`,
366
+ "warning"
367
+ )
368
+ );
369
+ continue;
370
+ } else if (/^-\s*\w/.test(trimmed) && !trimmed.startsWith("- ") && !trimmed.includes("->") && !trimmed.includes("<->")) {
371
+ result.diagnostics.push(
372
+ makeDgmoError(
373
+ lineNum,
374
+ `Looks like an incomplete edge \u2014 did you mean "-> ${trimmed.slice(1).trim()}"?`,
375
+ "warning"
376
+ )
377
+ );
378
+ descState.lines.push(trimmed);
379
+ continue;
380
+ } else {
381
+ descState.lines.push(trimmed);
382
+ continue;
383
+ }
384
+ } else {
385
+ flushDescription();
386
+ }
387
+ }
388
+ if (indent === 0) {
389
+ closeGroupsToIndent(0);
390
+ } else if (groupStack.length > 0) {
391
+ closeGroupsToIndent(indent);
392
+ }
393
+ const groupEdgeMatch = trimmed.match(
394
+ /^\[(.+?)\]\s*(<->|->)\s*\[(.+?)\](.*)$/
395
+ );
396
+ if (groupEdgeMatch) {
397
+ contentStarted = true;
398
+ currentTagGroup = null;
399
+ const sourceLabel = groupEdgeMatch[1];
400
+ const arrow = groupEdgeMatch[2];
401
+ const targetLabel = groupEdgeMatch[3];
402
+ const rawTail = groupEdgeMatch[4] ?? "";
403
+ const edgeMeta = parseTailMeta(rawTail, metaAliasMap).metadata;
404
+ result.edges.push({
405
+ // Regex capture groups present after successful match.
406
+ source: groupId(sourceLabel),
407
+ target: groupId(targetLabel),
408
+ bidirectional: arrow === "<->",
409
+ lineNumber: lineNum,
410
+ metadata: edgeMeta
411
+ });
412
+ continue;
413
+ }
414
+ const labeledGroupEdgeMatch = trimmed.match(
415
+ /^\[(.+?)\]\s*(?:<-(.+)->|-(.+)->)\s*\[(.+?)\](.*)$/
416
+ );
417
+ if (labeledGroupEdgeMatch) {
418
+ contentStarted = true;
419
+ currentTagGroup = null;
420
+ const sourceLabel = labeledGroupEdgeMatch[1];
421
+ const biLabel = labeledGroupEdgeMatch[2];
422
+ const uniLabel = labeledGroupEdgeMatch[3];
423
+ const targetLabel = labeledGroupEdgeMatch[4];
424
+ const rawTail = labeledGroupEdgeMatch[5] ?? "";
425
+ const edgeMeta = parseTailMeta(rawTail, metaAliasMap).metadata;
426
+ const labeledEdgeLabel = (biLabel ?? uniLabel)?.trim();
427
+ result.edges.push({
428
+ // Regex capture groups present after successful match.
429
+ source: groupId(sourceLabel),
430
+ target: groupId(targetLabel),
431
+ ...labeledEdgeLabel !== void 0 && { label: labeledEdgeLabel },
432
+ bidirectional: !!biLabel,
433
+ lineNumber: lineNum,
434
+ metadata: edgeMeta
435
+ });
436
+ continue;
437
+ }
438
+ const groupMatch = trimmed.match(/^\[(.+?)\](.*)$/);
439
+ if (groupMatch && !trimmed.includes("->") && !trimmed.includes("<->")) {
440
+ contentStarted = true;
441
+ currentTagGroup = null;
442
+ flushDescription();
443
+ const groupPeeled = peelAlias(groupMatch[1]);
444
+ const label = groupPeeled.label;
445
+ if (groupPeeled.alias)
446
+ nameAliasMap.set(groupPeeled.alias, groupId(label));
447
+ const currentDepth = groupStack.length + 1;
448
+ if (currentDepth > MAX_GROUP_DEPTH) {
449
+ result.diagnostics.push(
450
+ makeDgmoError(
451
+ lineNum,
452
+ `Group nesting exceeds maximum depth of ${MAX_GROUP_DEPTH}`,
453
+ "warning"
454
+ )
455
+ );
456
+ continue;
457
+ }
458
+ const groupMeta = parseTailMeta(
459
+ groupMatch[2] ?? "",
460
+ metaAliasMap
461
+ ).metadata;
462
+ const parentGs = currentGroupState();
463
+ const group = {
464
+ label,
465
+ children: [],
466
+ lineNumber: lineNum,
467
+ metadata: groupMeta,
468
+ ...parentGs ? { parentGroup: parentGs.group.label } : {}
469
+ };
470
+ if (parentGs && indent > parentGs.indent) {
471
+ parentGs.group.children.push(label);
472
+ }
473
+ groupLabels.add(normalizeName(label));
474
+ groupStack.push({ group, indent, depth: currentDepth });
475
+ lastNodeLabel = label;
476
+ lastSourceIsGroup = true;
477
+ continue;
478
+ }
479
+ if (trimmed.includes("->") || trimmed.includes("<->")) {
480
+ contentStarted = true;
481
+ currentTagGroup = null;
482
+ let edgeText = trimmed;
483
+ if (trimmed.startsWith("->") || /^-[^>].*->/.test(trimmed)) {
484
+ const gs2 = currentGroupState();
485
+ const inGroup = gs2 && indent > gs2.indent;
486
+ const indentedUnderNode = lastNodeLabel && !lastSourceIsGroup && indent > lastNodeIndent;
487
+ if (inGroup && !indentedUnderNode) {
488
+ const sourcePrefix = `[${gs2.group.label}]`;
489
+ edgeText = `${sourcePrefix} ${trimmed}`;
490
+ } else if (lastNodeLabel) {
491
+ const sourcePrefix = lastSourceIsGroup ? `[${lastNodeLabel}]` : lastNodeLabel;
492
+ edgeText = `${sourcePrefix} ${trimmed}`;
493
+ } else {
494
+ result.diagnostics.push(
495
+ makeDgmoError(
496
+ lineNum,
497
+ "Indented edge has no preceding node to use as source",
498
+ "warning"
499
+ )
500
+ );
501
+ continue;
502
+ }
503
+ }
504
+ const edge = parseEdgeLine(
505
+ edgeText,
506
+ lineNum,
507
+ metaAliasMap,
508
+ result.diagnostics,
509
+ nameAliasMap
510
+ );
511
+ if (edge) {
512
+ result.edges.push(edge);
513
+ }
514
+ continue;
515
+ }
516
+ contentStarted = true;
517
+ currentTagGroup = null;
518
+ flushDescription();
519
+ const node = parseNodeLine(
520
+ trimmed,
521
+ lineNum,
522
+ metaAliasMap,
523
+ result.diagnostics,
524
+ nameAliasMap
525
+ );
526
+ if (!node) {
527
+ result.diagnostics.push(
528
+ makeDgmoError(lineNum, `Unexpected line: '${trimmed}'.`, "warning")
529
+ );
530
+ continue;
531
+ }
532
+ lastNodeLabel = node.label;
533
+ lastSourceIsGroup = false;
534
+ lastNodeIndent = indent;
535
+ const gs = currentGroupState();
536
+ const isGroupChild = gs && indent > gs.indent;
537
+ const key = normalizeName(node.label);
538
+ if (nodeLabels.has(key)) {
539
+ if (isGroupChild) {
540
+ gs.group.children.push(node.label);
541
+ continue;
542
+ }
543
+ result.diagnostics.push(
544
+ makeDgmoError(lineNum, `Duplicate node "${node.label}"`, "warning")
545
+ );
546
+ } else {
547
+ nodeLabels.add(key);
548
+ }
549
+ if (isGroupChild) {
550
+ for (const [key2, val] of Object.entries(gs.group.metadata)) {
551
+ if (!(key2 in node.metadata)) {
552
+ node.metadata[key2] = val;
553
+ }
554
+ }
555
+ gs.group.children.push(node.label);
556
+ }
557
+ result.nodes.push(node);
558
+ descState = { nodeLabel: node.label, indent, lines: [], edgeSeen: false };
559
+ }
560
+ flushDescription();
561
+ while (groupStack.length > 0) {
562
+ const gs = groupStack.pop();
563
+ result.groups.push(gs.group);
564
+ }
565
+ const validEdges = [];
566
+ for (const edge of result.edges) {
567
+ let valid = true;
568
+ const allGroups = Array.from(groupLabels);
569
+ if (edge.source.startsWith("__group_")) {
570
+ const label = edge.source.slice("__group_".length);
571
+ const found = groupLabels.has(normalizeName(label));
572
+ if (!found) {
573
+ let msg = `Group '[${label}]' not found`;
574
+ const hint = suggest(normalizeName(label), allGroups);
575
+ if (hint) msg += `. ${hint}`;
576
+ result.diagnostics.push(makeDgmoError(edge.lineNumber, msg));
577
+ valid = false;
578
+ }
579
+ } else {
580
+ ensureNode(edge.source, edge.lineNumber);
581
+ }
582
+ if (edge.target.startsWith("__group_")) {
583
+ const label = edge.target.slice("__group_".length);
584
+ const found = groupLabels.has(normalizeName(label));
585
+ if (!found) {
586
+ let msg = `Group '[${label}]' not found`;
587
+ const hint = suggest(normalizeName(label), allGroups);
588
+ if (hint) msg += `. ${hint}`;
589
+ result.diagnostics.push(makeDgmoError(edge.lineNumber, msg));
590
+ valid = false;
591
+ }
592
+ } else {
593
+ ensureNode(edge.target, edge.lineNumber);
594
+ }
595
+ if (valid) {
596
+ validEdges.push(edge);
597
+ }
598
+ }
599
+ result.edges = validEdges;
600
+ if (notes.length > 0) {
601
+ result.notes = notes;
602
+ resolveNotes(
603
+ notes,
604
+ result.nodes.map((n) => ({ id: n.label, label: n.label })),
605
+ result.diagnostics
606
+ );
607
+ }
608
+ finalizeAutoTagColors(result.tagGroups);
609
+ if (nodePositions.size > 0) {
610
+ const nodeLabelSet = new Set(result.nodes.map((n) => n.label));
611
+ for (const id of nodePositions.keys()) {
612
+ if (!nodeLabelSet.has(id)) {
613
+ pushWarning(0, `layout entry for unknown node "${id}" (ignored)`);
614
+ }
615
+ }
616
+ const unpositioned = result.nodes.filter((n) => !nodePositions.has(n.label)).map((n) => n.label);
617
+ if (unpositioned.length > 0) {
618
+ pushWarning(
619
+ 0,
620
+ `layout block is partial \u2014 ${unpositioned.length} node(s) without coordinates (${unpositioned.slice(0, 5).join(", ")}${unpositioned.length > 5 ? "\u2026" : ""}); ignoring the block and auto-laying-out`
621
+ );
622
+ }
623
+ result.nodePositions = nodePositions;
624
+ }
625
+ if (result.tagGroups.length > 0) {
626
+ injectDefaultTagMetadata(result.nodes, result.tagGroups);
627
+ validateTagValues(result.nodes, result.tagGroups, pushWarning, suggest);
628
+ validateTagGroupNames(result.tagGroups, pushWarning, (line, msg) => {
629
+ const diag = makeDgmoError(line, msg);
630
+ result.diagnostics.push(diag);
631
+ if (!result.error) result.error = diag.message;
632
+ });
633
+ }
634
+ return result;
635
+ }
636
+ function parseNodeLine(trimmed, lineNum, metaAliasMap, diagnostics, nameAliasMap) {
637
+ const registry = withTagAliases(
638
+ BOXES_AND_LINES_REGISTRY,
639
+ new Set(metaAliasMap.keys())
640
+ );
641
+ const split = splitNameAndMeta(
642
+ trimmed,
643
+ registry,
644
+ metaAliasMap,
645
+ void 0,
646
+ diagnostics,
647
+ lineNum
648
+ );
649
+ warnUnknownMetaKeys(
650
+ split.meta,
651
+ registry,
652
+ (msg) => diagnostics.push(makeDgmoError(lineNum, msg, "warning")),
653
+ split.name
654
+ );
655
+ let label = split.name;
656
+ const metadata = { ...split.meta };
657
+ let description;
658
+ if (split.color !== void 0) {
659
+ label = `${label} ${split.color}`;
660
+ }
661
+ if (metadata["description"] !== void 0) {
662
+ description = [metadata["description"]];
663
+ delete metadata["description"];
664
+ }
665
+ let value;
666
+ if (metadata["heat"] !== void 0) {
667
+ const raw = metadata["heat"];
668
+ const num = Number(raw);
669
+ if (Number.isFinite(num)) {
670
+ value = num;
671
+ } else {
672
+ diagnostics.push(
673
+ makeDgmoError(lineNum, `heat must be a number (got "${raw}")`, "error")
674
+ );
675
+ }
676
+ delete metadata["heat"];
677
+ }
678
+ if (split.alias) {
679
+ nameAliasMap?.set(normalizeName(split.alias), label);
680
+ }
681
+ if (!label) return null;
682
+ return {
683
+ label,
684
+ lineNumber: lineNum,
685
+ metadata,
686
+ ...description !== void 0 && { description },
687
+ ...value !== void 0 && { value }
688
+ };
689
+ }
690
+ function splitTargetAndMeta(rest, metaAliasMap) {
691
+ const registry = withTagAliases(
692
+ BOXES_AND_LINES_REGISTRY,
693
+ new Set(metaAliasMap.keys())
694
+ );
695
+ const split = splitNameAndMeta(rest, registry, metaAliasMap);
696
+ let target = split.name;
697
+ if (split.color !== void 0) {
698
+ target = `${target} ${split.color}`;
699
+ }
700
+ return { target, metadata: split.meta };
701
+ }
702
+ function resolveEndpoint(name, nameAliasMap) {
703
+ const m = name.match(/^\[(.+)\]$/);
704
+ if (m) return groupId(m[1].trim());
705
+ if (nameAliasMap) {
706
+ const aliased = nameAliasMap.get(name.trim());
707
+ if (aliased !== void 0) return aliased;
708
+ }
709
+ return name;
710
+ }
711
+ function parseEdgeLine(trimmed, lineNum, metaAliasMap, diagnostics, nameAliasMap) {
712
+ const edgeRegistry = withTagAliases(
713
+ BOXES_AND_LINES_REGISTRY,
714
+ new Set(metaAliasMap.keys())
715
+ );
716
+ const biLabeledMatch = trimmed.match(/^(.+?)\s*<-(.+)->\s*(.+)$/);
717
+ if (biLabeledMatch) {
718
+ const rawSource2 = biLabeledMatch[1].trim();
719
+ const source2 = resolveEndpoint(rawSource2, nameAliasMap);
720
+ const labelResult = parseInArrowLabel(biLabeledMatch[2], lineNum);
721
+ diagnostics.push(...labelResult.diagnostics);
722
+ const label = labelResult.label;
723
+ let rest2 = biLabeledMatch[3].trim();
724
+ const { target: biTarget, metadata: metadata2 } = splitTargetAndMeta(
725
+ rest2,
726
+ metaAliasMap
727
+ );
728
+ warnUnknownMetaKeys(
729
+ metadata2,
730
+ edgeRegistry,
731
+ (msg) => diagnostics.push(makeDgmoError(lineNum, msg, "warning"))
732
+ );
733
+ rest2 = biTarget;
734
+ if (!source2 || !rest2) {
735
+ diagnostics.push(
736
+ makeDgmoError(lineNum, "Edge is missing source or target")
737
+ );
738
+ return null;
739
+ }
740
+ if (rawSource2.endsWith(":") || rest2.endsWith(":")) {
741
+ diagnostics.push(
742
+ makeDgmoError(
743
+ lineNum,
744
+ `Trailing colon is not valid \u2014 write '${rawSource2.replace(/:$/, "")} <-> ${rest2.replace(/:$/, "")}' instead`
745
+ )
746
+ );
747
+ return null;
748
+ }
749
+ return {
750
+ source: source2,
751
+ target: resolveEndpoint(rest2, nameAliasMap),
752
+ ...label !== void 0 && { label },
753
+ bidirectional: true,
754
+ lineNumber: lineNum,
755
+ metadata: metadata2
756
+ };
757
+ }
758
+ const biIdx = trimmed.indexOf("<->");
759
+ if (biIdx >= 0) {
760
+ const rawSource2 = trimmed.slice(0, biIdx).trim();
761
+ const source2 = resolveEndpoint(rawSource2, nameAliasMap);
762
+ let rest2 = trimmed.slice(biIdx + 3).trim();
763
+ const { target: plainTarget2, metadata: metadata2 } = splitTargetAndMeta(
764
+ rest2,
765
+ metaAliasMap
766
+ );
767
+ warnUnknownMetaKeys(
768
+ metadata2,
769
+ edgeRegistry,
770
+ (msg) => diagnostics.push(makeDgmoError(lineNum, msg, "warning"))
771
+ );
772
+ rest2 = plainTarget2;
773
+ if (!source2 || !rest2) {
774
+ diagnostics.push(
775
+ makeDgmoError(lineNum, "Edge is missing source or target")
776
+ );
777
+ return null;
778
+ }
779
+ if (rawSource2.endsWith(":") || rest2.endsWith(":")) {
780
+ diagnostics.push(
781
+ makeDgmoError(
782
+ lineNum,
783
+ `Trailing colon is not valid \u2014 write '${rawSource2.replace(/:$/, "")} <-> ${rest2.replace(/:$/, "")}' instead`
784
+ )
785
+ );
786
+ return null;
787
+ }
788
+ return {
789
+ source: source2,
790
+ target: resolveEndpoint(rest2, nameAliasMap),
791
+ bidirectional: true,
792
+ lineNumber: lineNum,
793
+ metadata: metadata2
794
+ };
795
+ }
796
+ const labeledMatch = trimmed.match(/^(.+?)\s+-(.+?)->\s*(.+)$/);
797
+ if (labeledMatch) {
798
+ const rawSource2 = labeledMatch[1].trim();
799
+ const source2 = resolveEndpoint(rawSource2, nameAliasMap);
800
+ const labelResult = parseInArrowLabel(labeledMatch[2], lineNum);
801
+ diagnostics.push(...labelResult.diagnostics);
802
+ const label = labelResult.label;
803
+ let rest2 = labeledMatch[3].trim();
804
+ if (label) {
805
+ const { target: labeledTarget, metadata: metadata2 } = splitTargetAndMeta(
806
+ rest2,
807
+ metaAliasMap
808
+ );
809
+ warnUnknownMetaKeys(
810
+ metadata2,
811
+ edgeRegistry,
812
+ (msg) => diagnostics.push(makeDgmoError(lineNum, msg, "warning"))
813
+ );
814
+ rest2 = labeledTarget;
815
+ if (!source2 || !rest2) {
816
+ diagnostics.push(
817
+ makeDgmoError(lineNum, "Edge is missing source or target")
818
+ );
819
+ return null;
820
+ }
821
+ if (rawSource2.endsWith(":") || rest2.endsWith(":")) {
822
+ diagnostics.push(
823
+ makeDgmoError(
824
+ lineNum,
825
+ `Trailing colon is not valid \u2014 write '${rawSource2.replace(/:$/, "")} -> ${rest2.replace(/:$/, "")}' instead`
826
+ )
827
+ );
828
+ return null;
829
+ }
830
+ return {
831
+ source: source2,
832
+ target: resolveEndpoint(rest2, nameAliasMap),
833
+ label,
834
+ bidirectional: false,
835
+ lineNumber: lineNum,
836
+ metadata: metadata2
837
+ };
838
+ }
839
+ }
840
+ const arrowIdx = trimmed.indexOf("->");
841
+ if (arrowIdx < 0) return null;
842
+ const rawSource = trimmed.slice(0, arrowIdx).trim();
843
+ const source = resolveEndpoint(rawSource, nameAliasMap);
844
+ let rest = trimmed.slice(arrowIdx + 2).trim();
845
+ if (!source || !rest) {
846
+ diagnostics.push(
847
+ makeDgmoError(lineNum, "Edge is missing source or target")
848
+ );
849
+ return null;
850
+ }
851
+ const { target: plainTarget, metadata } = splitTargetAndMeta(
852
+ rest,
853
+ metaAliasMap
854
+ );
855
+ warnUnknownMetaKeys(
856
+ metadata,
857
+ edgeRegistry,
858
+ (msg) => diagnostics.push(makeDgmoError(lineNum, msg, "warning"))
859
+ );
860
+ rest = plainTarget;
861
+ if (!rest) {
862
+ diagnostics.push(makeDgmoError(lineNum, "Edge is missing target"));
863
+ return null;
864
+ }
865
+ if (rawSource.endsWith(":") || rest.endsWith(":")) {
866
+ diagnostics.push(
867
+ makeDgmoError(
868
+ lineNum,
869
+ `Trailing colon is not valid \u2014 write '${rawSource.replace(/:$/, "")} -> ${rest.replace(/:$/, "")}' instead`
870
+ )
871
+ );
872
+ return null;
873
+ }
874
+ return {
875
+ source,
876
+ target: resolveEndpoint(rest, nameAliasMap),
877
+ bidirectional: false,
878
+ lineNumber: lineNum,
879
+ metadata
880
+ };
881
+ }
882
+
883
+ export {
884
+ looksLikeBoxesAndLines,
885
+ parseBoxesAndLines
886
+ };
887
+ //# sourceMappingURL=chunk-BUVJFRPY.js.map