@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,1057 @@
1
+ import {
2
+ collectIndentedValues,
3
+ extractColor,
4
+ measureIndent,
5
+ normalizeNumericToken,
6
+ parseFirstLine,
7
+ parseSeriesNames
8
+ } from "./chunk-Y3J7VR52.js";
9
+ import {
10
+ RECOGNIZED_COLOR_NAMES,
11
+ resolveColorWithDiagnostic
12
+ } from "./chunk-TLVIHFRO.js";
13
+ import {
14
+ formatDgmoError,
15
+ makeDgmoError,
16
+ suggest
17
+ } from "./chunk-CXK4DZH3.js";
18
+
19
+ // src/chart.ts
20
+ var VALID_TYPES = /* @__PURE__ */ new Set([
21
+ "bar",
22
+ "line",
23
+ "pie",
24
+ "polar-area",
25
+ "radar"
26
+ ]);
27
+ var KNOWN_OPTIONS = /* @__PURE__ */ new Set([
28
+ "chart",
29
+ "title",
30
+ "series",
31
+ "stack",
32
+ "group",
33
+ "hole",
34
+ "x-label",
35
+ "y-label",
36
+ "y-right-label",
37
+ "label",
38
+ "no-name",
39
+ "no-value",
40
+ "no-percent",
41
+ "color"
42
+ ]);
43
+ var DEFAULT_HOLE = 0.6;
44
+ var KNOWN_BOOLEANS = /* @__PURE__ */ new Set([
45
+ "orientation-horizontal",
46
+ "solid-fill",
47
+ "no-title",
48
+ "fill",
49
+ "hole"
50
+ ]);
51
+ function rejectSeriesHeader(result, keyword, lineNumber) {
52
+ if (result.type === "bar" && keyword === "series") {
53
+ const diag = makeDgmoError(
54
+ lineNumber,
55
+ "On bar charts, declare multiple series with a 'stack' or 'group' block header, not 'series'."
56
+ );
57
+ result.diagnostics.push(diag);
58
+ result.error = formatDgmoError(diag);
59
+ return true;
60
+ }
61
+ if ((keyword === "stack" || keyword === "group") && result.type !== "bar") {
62
+ result.diagnostics.push(
63
+ makeDgmoError(
64
+ lineNumber,
65
+ `'${keyword}' is a bar layout header; ${result.type} charts use a 'series' block.`,
66
+ "warning"
67
+ )
68
+ );
69
+ }
70
+ return false;
71
+ }
72
+ function applySeriesAxes(result, parsed, lineNumber) {
73
+ if (parsed.leftLabel !== void 0) {
74
+ result.ylabel = parsed.leftLabel;
75
+ result.ylabelLineNumber = lineNumber;
76
+ }
77
+ if (parsed.rightLabel !== void 0) {
78
+ result.yrlabel = parsed.rightLabel;
79
+ result.yrlabelLineNumber = lineNumber;
80
+ }
81
+ if (parsed.axes?.includes("right")) {
82
+ result.seriesAxes = parsed.axes;
83
+ }
84
+ }
85
+ function parseChart(content, palette) {
86
+ const lines = content.split("\n");
87
+ const parsedEras = [];
88
+ const rawEras = [];
89
+ const result = {
90
+ type: "bar",
91
+ data: [],
92
+ eras: parsedEras,
93
+ diagnostics: [],
94
+ error: null
95
+ };
96
+ const fail = (line, message) => {
97
+ const diag = makeDgmoError(line, message);
98
+ result.diagnostics.push(diag);
99
+ result.error = formatDgmoError(diag);
100
+ return result;
101
+ };
102
+ let firstLineParsed = false;
103
+ for (let i = 0; i < lines.length; i++) {
104
+ const trimmed = lines[i].trim();
105
+ const lineNumber = i + 1;
106
+ if (!trimmed) continue;
107
+ if (/^#{2,}\s+/.test(trimmed)) {
108
+ result.diagnostics.push(
109
+ makeDgmoError(
110
+ lineNumber,
111
+ `'${trimmed}' removed \u2014 use a bracket container '[${trimmed.replace(/^#+\s*/, "")}]' instead (## headers are no longer supported).`
112
+ )
113
+ );
114
+ continue;
115
+ }
116
+ if (trimmed.startsWith("//")) continue;
117
+ if (!firstLineParsed) {
118
+ firstLineParsed = true;
119
+ const firstLine = parseFirstLine(trimmed);
120
+ if (firstLine) {
121
+ const raw = firstLine.chartType.toLowerCase();
122
+ const chartType = raw;
123
+ if (VALID_TYPES.has(chartType)) {
124
+ result.type = chartType;
125
+ if (firstLine.title) {
126
+ result.title = firstLine.title;
127
+ result.titleLineNumber = lineNumber;
128
+ }
129
+ continue;
130
+ } else {
131
+ let msg2 = `Unsupported chart type: ${firstLine.chartType}. Supported types: ${[...VALID_TYPES].join(", ")}.`;
132
+ const hint2 = suggest(raw, [...VALID_TYPES]);
133
+ if (hint2) msg2 += ` ${hint2}`;
134
+ return fail(lineNumber, msg2);
135
+ }
136
+ }
137
+ if (!trimmed.includes(" ") && !trimmed.includes(":") && !/\d/.test(trimmed)) {
138
+ let msg2 = `Unsupported chart type: ${trimmed}. Supported types: ${[...VALID_TYPES].join(", ")}.`;
139
+ const hint2 = suggest(trimmed.toLowerCase(), [...VALID_TYPES]);
140
+ if (hint2) msg2 += ` ${hint2}`;
141
+ return fail(lineNumber, msg2);
142
+ }
143
+ }
144
+ const eraMatch = trimmed.match(/^era\s+(.+?)\s*->\s*(.+?)\s*$/);
145
+ if (eraMatch) {
146
+ const afterArrow = eraMatch[2].trim();
147
+ const spaceIdx2 = afterArrow.indexOf(" ");
148
+ if (spaceIdx2 >= 0) {
149
+ const lastSpaceIdx = afterArrow.lastIndexOf(" ");
150
+ const trailing = afterArrow.substring(lastSpaceIdx + 1);
151
+ const hasColor = RECOGNIZED_COLOR_NAMES.includes(
152
+ trailing
153
+ );
154
+ const labelPart = hasColor ? afterArrow.substring(0, lastSpaceIdx).trimEnd() : afterArrow;
155
+ rawEras.push({
156
+ // Capture group 1 guaranteed present after regex match.
157
+ start: eraMatch[1].trim(),
158
+ afterArrow: labelPart,
159
+ color: hasColor ? resolveColorWithDiagnostic(
160
+ trailing,
161
+ lineNumber,
162
+ result.diagnostics,
163
+ palette
164
+ ) ?? null : null,
165
+ lineNumber
166
+ });
167
+ }
168
+ continue;
169
+ }
170
+ const spaceIdx = trimmed.indexOf(" ");
171
+ const firstToken = (spaceIdx >= 0 ? trimmed.substring(0, spaceIdx) : trimmed).toLowerCase();
172
+ if (KNOWN_BOOLEANS.has(firstToken) && spaceIdx < 0) {
173
+ if (firstToken === "orientation-horizontal") {
174
+ result.orientation = "horizontal";
175
+ } else if (firstToken === "solid-fill") {
176
+ result.solidFill = true;
177
+ } else if (firstToken === "no-title") {
178
+ result.noTitle = true;
179
+ } else if (firstToken === "fill") {
180
+ result.fill = true;
181
+ } else if (firstToken === "hole") {
182
+ result.hole = DEFAULT_HOLE;
183
+ }
184
+ continue;
185
+ }
186
+ if (KNOWN_OPTIONS.has(firstToken) && spaceIdx >= 0) {
187
+ const value = trimmed.substring(spaceIdx + 1).trim();
188
+ if (firstToken === "chart") {
189
+ const raw = value.toLowerCase();
190
+ const chartType = raw;
191
+ if (VALID_TYPES.has(chartType)) {
192
+ result.type = chartType;
193
+ } else {
194
+ let msg2 = `Unsupported chart type: ${value}. Supported types: ${[...VALID_TYPES].join(", ")}.`;
195
+ const hint2 = suggest(raw, [...VALID_TYPES]);
196
+ if (hint2) msg2 += ` ${hint2}`;
197
+ return fail(lineNumber, msg2);
198
+ }
199
+ continue;
200
+ }
201
+ if (firstToken === "title") {
202
+ result.title = value;
203
+ result.titleLineNumber = lineNumber;
204
+ continue;
205
+ }
206
+ if (firstToken === "x-label") {
207
+ result.xlabel = value;
208
+ result.xlabelLineNumber = lineNumber;
209
+ continue;
210
+ }
211
+ if (firstToken === "y-label") {
212
+ result.ylabel = value;
213
+ result.ylabelLineNumber = lineNumber;
214
+ continue;
215
+ }
216
+ if (firstToken === "y-right-label") {
217
+ result.yrlabel = value;
218
+ result.yrlabelLineNumber = lineNumber;
219
+ continue;
220
+ }
221
+ if (firstToken === "label") {
222
+ result.label = value;
223
+ continue;
224
+ }
225
+ if (firstToken === "hole") {
226
+ const ratio = parseFloat(value);
227
+ if (Number.isFinite(ratio) && ratio >= 0 && ratio < 1) {
228
+ result.hole = ratio;
229
+ } else {
230
+ result.diagnostics.push(
231
+ makeDgmoError(
232
+ lineNumber,
233
+ 'hole must be a ratio between 0 and 0.9 (e.g. "hole 0.6"). Using the default.',
234
+ "warning"
235
+ )
236
+ );
237
+ result.hole = DEFAULT_HOLE;
238
+ }
239
+ continue;
240
+ }
241
+ if (firstToken === "color") {
242
+ const resolvedColor = resolveColorWithDiagnostic(
243
+ value.trim(),
244
+ lineNumber,
245
+ result.diagnostics,
246
+ palette
247
+ );
248
+ if (resolvedColor !== void 0) result.color = resolvedColor;
249
+ continue;
250
+ }
251
+ if (firstToken === "series" || firstToken === "stack" || firstToken === "group") {
252
+ const rejected = rejectSeriesHeader(result, firstToken, lineNumber);
253
+ const parsed = parseSeriesNames(
254
+ value,
255
+ lines,
256
+ i,
257
+ palette,
258
+ rejected ? void 0 : result.diagnostics
259
+ );
260
+ i = parsed.newIndex;
261
+ if (rejected) continue;
262
+ result.series = parsed.series;
263
+ result.seriesLineNumber = lineNumber;
264
+ if (parsed.names.length > 1) {
265
+ result.seriesNames = parsed.names;
266
+ result.seriesNameLineNumbers = parsed.nameLineNumbers;
267
+ }
268
+ if (parsed.nameColors.some(Boolean))
269
+ result.seriesNameColors = parsed.nameColors;
270
+ applySeriesAxes(result, parsed, lineNumber);
271
+ if (firstToken === "stack" || firstToken === "group")
272
+ result.barLayout = firstToken;
273
+ continue;
274
+ }
275
+ }
276
+ if (firstToken === "no-name") {
277
+ result.noName = true;
278
+ continue;
279
+ }
280
+ if (firstToken === "no-value") {
281
+ result.noValue = true;
282
+ continue;
283
+ }
284
+ if (firstToken === "no-percent") {
285
+ result.noPercent = true;
286
+ continue;
287
+ }
288
+ if (firstToken === "no-center-total") {
289
+ result.noCenterTotal = true;
290
+ continue;
291
+ }
292
+ if (firstToken.startsWith("no-") && spaceIdx < 0) {
293
+ continue;
294
+ }
295
+ if ((firstToken === "series" || firstToken === "stack" || firstToken === "group") && spaceIdx === -1) {
296
+ const rejected = rejectSeriesHeader(result, firstToken, lineNumber);
297
+ const parsed = parseSeriesNames("", lines, i, palette);
298
+ i = parsed.newIndex;
299
+ if (rejected) continue;
300
+ result.series = parsed.series;
301
+ result.seriesLineNumber = lineNumber;
302
+ if (parsed.names.length > 1) {
303
+ result.seriesNames = parsed.names;
304
+ result.seriesNameLineNumbers = parsed.nameLineNumbers;
305
+ }
306
+ if (parsed.nameColors.some(Boolean))
307
+ result.seriesNameColors = parsed.nameColors;
308
+ applySeriesAxes(result, parsed, lineNumber);
309
+ if (firstToken === "stack" || firstToken === "group")
310
+ result.barLayout = firstToken;
311
+ continue;
312
+ }
313
+ const seriesCount = result.seriesNames?.length ?? 0;
314
+ const multiValue = seriesCount >= 2;
315
+ const dataValues = parseDataRowValues(trimmed, {
316
+ multiValue,
317
+ ...multiValue && { expectedValues: seriesCount }
318
+ });
319
+ if (dataValues) {
320
+ const { label: rawLabel, color: pointColor } = extractColor(
321
+ dataValues.label,
322
+ palette,
323
+ result.diagnostics,
324
+ lineNumber
325
+ );
326
+ const [first, ...rest] = dataValues.values;
327
+ result.data.push({
328
+ label: rawLabel,
329
+ // parseDataRowValues guarantees values.length >= 1.
330
+ value: first,
331
+ ...rest.length > 0 && { extraValues: rest },
332
+ ...pointColor && { color: pointColor },
333
+ lineNumber
334
+ });
335
+ continue;
336
+ }
337
+ let msg = `Unexpected line: '${trimmed}'.`;
338
+ const hint = suggest(firstToken, [...KNOWN_OPTIONS, ...KNOWN_BOOLEANS]);
339
+ if (hint) msg += ` ${hint}`;
340
+ result.diagnostics.push(makeDgmoError(lineNumber, msg, "warning"));
341
+ }
342
+ const knownLabels = new Set(result.data.map((d) => d.label));
343
+ for (const raw of rawEras) {
344
+ const words = raw.afterArrow.split(" ");
345
+ let end = "";
346
+ let label = "";
347
+ let matched = false;
348
+ for (let w = words.length - 1; w >= 1; w--) {
349
+ const candidateEnd = words.slice(0, w).join(" ");
350
+ if (knownLabels.has(candidateEnd)) {
351
+ end = candidateEnd;
352
+ label = words.slice(w).join(" ");
353
+ matched = true;
354
+ break;
355
+ }
356
+ }
357
+ if (!matched) {
358
+ end = words[0];
359
+ label = words.slice(1).join(" ");
360
+ }
361
+ parsedEras.push({
362
+ start: raw.start,
363
+ end,
364
+ label,
365
+ color: raw.color,
366
+ lineNumber: raw.lineNumber
367
+ });
368
+ }
369
+ if (result.type !== "line") {
370
+ result.eras = [];
371
+ }
372
+ const warn = (line, message) => {
373
+ result.diagnostics.push(makeDgmoError(line, message, "warning"));
374
+ };
375
+ if (!result.error && result.data.length === 0) {
376
+ warn(1, "No data points found. Add data in format: Label 123");
377
+ }
378
+ if (!result.error && result.seriesNames) {
379
+ const expectedCount = result.seriesNames.length;
380
+ for (const dp of result.data) {
381
+ const actualCount = 1 + (dp.extraValues?.length ?? 0);
382
+ if (actualCount !== expectedCount) {
383
+ warn(
384
+ dp.lineNumber,
385
+ `Data point "${dp.label}" has ${actualCount} value(s), but ${expectedCount} series defined. Each row must have ${expectedCount} values.`
386
+ );
387
+ }
388
+ }
389
+ result.data = result.data.filter((dp) => {
390
+ const actualCount = 1 + (dp.extraValues?.length ?? 0);
391
+ return actualCount === expectedCount;
392
+ });
393
+ }
394
+ if (!result.error && result.seriesAxes && result.type !== "line") {
395
+ warn(
396
+ result.seriesLineNumber ?? 1,
397
+ `Dual y-axes (y-right-label) are only supported on line / multi-line charts; ignoring the secondary axis for "${result.type}".`
398
+ );
399
+ delete result.seriesAxes;
400
+ delete result.yrlabel;
401
+ }
402
+ if (!result.error && result.yrlabel && !result.seriesAxes?.includes("right")) {
403
+ warn(
404
+ result.yrlabelLineNumber ?? 1,
405
+ `y-right-label is set but no series is assigned to the right axis. Group the series under a "y-right-label" header (see \xA715.1).`
406
+ );
407
+ }
408
+ return result;
409
+ }
410
+ function parseDataRowValues(line, options) {
411
+ const tokens = line.split(/\s+/);
412
+ if (tokens.length < 2) return null;
413
+ if (options?.multiValue) {
414
+ const limit = options.expectedValues ?? Infinity;
415
+ const values = [];
416
+ let idx = tokens.length - 1;
417
+ while (idx >= 1 && values.length < limit) {
418
+ const tok = tokens[idx];
419
+ const normTok = normalizeNumericToken(tok) ?? tok;
420
+ const num2 = parseFloat(normTok);
421
+ if (isNaN(num2) || !isFinite(Number(normTok))) break;
422
+ values.unshift(num2);
423
+ idx--;
424
+ }
425
+ if (values.length === 0) return null;
426
+ const label2 = tokens.slice(0, idx + 1).join(" ");
427
+ if (!label2) return null;
428
+ return { label: label2, values };
429
+ }
430
+ const lastToken = tokens[tokens.length - 1];
431
+ const normalizedLast = normalizeNumericToken(lastToken) ?? lastToken;
432
+ const num = parseFloat(normalizedLast);
433
+ if (isNaN(num) || !isFinite(Number(normalizedLast))) return null;
434
+ const label = tokens.slice(0, -1).join(" ");
435
+ if (!label) return null;
436
+ return { label, values: [num] };
437
+ }
438
+
439
+ // src/data-chart-parser.ts
440
+ var VALID_EXTENDED_TYPES = /* @__PURE__ */ new Set([
441
+ "sankey",
442
+ "chord",
443
+ "function",
444
+ "scatter",
445
+ "heatmap",
446
+ "funnel"
447
+ ]);
448
+ var KNOWN_EXTENDED_OPTIONS = /* @__PURE__ */ new Set([
449
+ "chart",
450
+ "title",
451
+ "series",
452
+ "x-label",
453
+ "y-label",
454
+ "size-label",
455
+ "layout",
456
+ "no-name",
457
+ "no-value",
458
+ "no-percent",
459
+ "columns",
460
+ "rows",
461
+ "x"
462
+ ]);
463
+ function parseScatterRow(line, palette, currentCategory, lineNumber, diagnostics) {
464
+ const dataRow = parseDataRowValues(line, { multiValue: true });
465
+ if (!dataRow || dataRow.values.length < 2) return null;
466
+ const { label: rawLabel, color: pointColor } = extractColor(
467
+ dataRow.label,
468
+ palette,
469
+ diagnostics,
470
+ lineNumber
471
+ );
472
+ return {
473
+ name: rawLabel,
474
+ // In-bounds by length >= 2 guard above.
475
+ x: dataRow.values[0],
476
+ y: dataRow.values[1],
477
+ ...dataRow.values[2] !== void 0 && { size: dataRow.values[2] },
478
+ ...pointColor && { color: pointColor },
479
+ ...currentCategory !== "Default" && { category: currentCategory },
480
+ lineNumber
481
+ };
482
+ }
483
+ function parseExtendedChart(content, palette) {
484
+ return parseExtendedChartFull(content, palette);
485
+ }
486
+ function parseSankey(content, palette) {
487
+ return parseExtendedChart(content, palette);
488
+ }
489
+ function parseChord(content, palette) {
490
+ return parseExtendedChart(content, palette);
491
+ }
492
+ function parseFunctionChart(content, palette) {
493
+ return parseExtendedChart(content, palette);
494
+ }
495
+ function parseScatter(content, palette) {
496
+ return parseExtendedChart(content, palette);
497
+ }
498
+ function parseHeatmap(content, palette) {
499
+ return parseExtendedChart(content, palette);
500
+ }
501
+ function parseFunnel(content, palette) {
502
+ return parseExtendedChart(content, palette);
503
+ }
504
+ var EXTENDED_CHART_DOORS = /* @__PURE__ */ new Set([
505
+ parseSankey,
506
+ parseChord,
507
+ parseFunctionChart,
508
+ parseScatter,
509
+ parseHeatmap,
510
+ parseFunnel
511
+ ]);
512
+ function parseExtendedChartFull(content, palette) {
513
+ const lines = content.split("\n");
514
+ const result = {
515
+ type: "scatter",
516
+ data: [],
517
+ diagnostics: [],
518
+ error: null
519
+ };
520
+ let currentCategory = "Default";
521
+ const sankeyStack = [];
522
+ let firstLineParsed = false;
523
+ const nameAliasMap = /* @__PURE__ */ new Map();
524
+ function resolveSlot(raw) {
525
+ const trimmed = raw.trim();
526
+ const m = trimmed.match(/^(.*?)\s+as\s+([A-Za-z][A-Za-z0-9_]{0,11})\s*$/);
527
+ if (m) {
528
+ const canonical = m[1].trim();
529
+ nameAliasMap.set(m[2], canonical);
530
+ return canonical;
531
+ }
532
+ const aliased = nameAliasMap.get(trimmed);
533
+ return aliased !== void 0 ? aliased : trimmed;
534
+ }
535
+ for (let i = 0; i < lines.length; i++) {
536
+ const trimmed = lines[i].trim();
537
+ const lineNumber = i + 1;
538
+ if (!trimmed) continue;
539
+ if (/^#{2,}\s+/.test(trimmed)) {
540
+ const name = trimmed.replace(/^#{2,}\s+/, "").replace(/\s*\([^)]*\)\s*$/, "").trim();
541
+ result.diagnostics.push(
542
+ makeDgmoError(
543
+ lineNumber,
544
+ `'## ${name}' is no longer supported. Use '[${name}]' instead`
545
+ )
546
+ );
547
+ continue;
548
+ }
549
+ if (trimmed.startsWith("//")) continue;
550
+ if (!firstLineParsed) {
551
+ firstLineParsed = true;
552
+ const firstLine = parseFirstLine(trimmed);
553
+ if (!firstLine) {
554
+ const rawType = trimmed.split(/\s+/)[0].toLowerCase();
555
+ if (VALID_EXTENDED_TYPES.has(rawType)) {
556
+ result.type = rawType;
557
+ const rest = trimmed.slice(rawType.length).trim();
558
+ if (rest) {
559
+ result.title = rest;
560
+ result.titleLineNumber = lineNumber;
561
+ }
562
+ continue;
563
+ }
564
+ }
565
+ if (firstLine) {
566
+ const chartType = firstLine.chartType.toLowerCase();
567
+ if (VALID_EXTENDED_TYPES.has(chartType)) {
568
+ result.type = chartType;
569
+ if (firstLine.title) {
570
+ result.title = firstLine.title;
571
+ result.titleLineNumber = lineNumber;
572
+ }
573
+ continue;
574
+ } else {
575
+ const validTypes = [...VALID_EXTENDED_TYPES];
576
+ let msg = `Unsupported chart type: ${firstLine.chartType}. Supported types: ${validTypes.join(", ")}.`;
577
+ const hint = suggest(chartType, validTypes);
578
+ if (hint) msg += ` ${hint}`;
579
+ const diag = makeDgmoError(lineNumber, msg);
580
+ result.diagnostics.push(diag);
581
+ result.error = formatDgmoError(diag);
582
+ return result;
583
+ }
584
+ }
585
+ if (!trimmed.includes(" ") && !trimmed.includes(":") && !/\d/.test(trimmed)) {
586
+ const validTypes = [...VALID_EXTENDED_TYPES];
587
+ let msg = `Unsupported chart type: ${trimmed}. Supported types: ${validTypes.join(", ")}.`;
588
+ const hint = suggest(trimmed.toLowerCase(), validTypes);
589
+ if (hint) msg += ` ${hint}`;
590
+ const diag = makeDgmoError(lineNumber, msg);
591
+ result.diagnostics.push(diag);
592
+ result.error = formatDgmoError(diag);
593
+ return result;
594
+ }
595
+ }
596
+ const categoryMatch = trimmed.match(/^\[(.+?)\](?:\s+(\S+))?\s*$/);
597
+ if (categoryMatch) {
598
+ const catName = categoryMatch[1].trim();
599
+ const rawCatColor = categoryMatch[2]?.trim();
600
+ const catColor = rawCatColor ? resolveColorWithDiagnostic(
601
+ rawCatColor,
602
+ lineNumber,
603
+ result.diagnostics,
604
+ palette
605
+ ) ?? null : null;
606
+ if (catColor) {
607
+ if (!result.categoryColors) result.categoryColors = {};
608
+ result.categoryColors[catName] = catColor;
609
+ }
610
+ if (!result.categoryLineNumbers) result.categoryLineNumbers = {};
611
+ result.categoryLineNumbers[catName] = lineNumber;
612
+ currentCategory = catName;
613
+ continue;
614
+ }
615
+ const arrowMatch = trimmed.match(
616
+ /^(.+?)\s*(->|--)\s*(.+?)\s+(-?[\d_]+(?:\.[\d]+)?)(?:\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white))?\s*$/
617
+ );
618
+ if (arrowMatch) {
619
+ const [, rawSource, arrow, rawTarget, rawVal, rawLinkColor] = arrowMatch;
620
+ const val = normalizeNumericToken(rawVal) ?? rawVal;
621
+ const sourceResolved = resolveSlot(rawSource);
622
+ const targetResolved = resolveSlot(rawTarget);
623
+ const { label: source, color: sourceColor } = extractColor(
624
+ sourceResolved,
625
+ palette,
626
+ result.diagnostics,
627
+ lineNumber
628
+ );
629
+ const { label: target, color: targetColor } = extractColor(
630
+ targetResolved,
631
+ palette,
632
+ result.diagnostics,
633
+ lineNumber
634
+ );
635
+ if (sourceColor || targetColor) {
636
+ if (!result.nodeColors) result.nodeColors = {};
637
+ if (sourceColor) result.nodeColors[source] = sourceColor;
638
+ if (targetColor) result.nodeColors[target] = targetColor;
639
+ }
640
+ const linkColor = rawLinkColor ? resolveColorWithDiagnostic(
641
+ rawLinkColor.trim(),
642
+ lineNumber,
643
+ result.diagnostics,
644
+ palette
645
+ ) : void 0;
646
+ if (!result.links) result.links = [];
647
+ result.links.push({
648
+ source,
649
+ target,
650
+ value: parseFloat(val),
651
+ ...linkColor && { color: linkColor },
652
+ directed: arrow === "->",
653
+ lineNumber
654
+ });
655
+ continue;
656
+ }
657
+ if (result.type === "sankey") {
658
+ const indent = measureIndent(lines[i]);
659
+ if (indent > 0 && sankeyStack.length > 0) {
660
+ while (sankeyStack.length && sankeyStack.at(-1).indent >= indent) {
661
+ sankeyStack.pop();
662
+ }
663
+ if (sankeyStack.length > 0) {
664
+ const valColorMatch = trimmed.match(
665
+ /(-?[\d_]+(?:\.[\d]+)?)\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white)\s*$/
666
+ );
667
+ const strippedLine = valColorMatch ? trimmed.replace(
668
+ /\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white)\s*$/,
669
+ ""
670
+ ) : trimmed;
671
+ const dataRow2 = parseDataRowValues(strippedLine);
672
+ if (dataRow2?.values.length === 1) {
673
+ const source = sankeyStack.at(-1).name;
674
+ const linkColor = valColorMatch?.[2] ? resolveColorWithDiagnostic(
675
+ valColorMatch[2].trim(),
676
+ lineNumber,
677
+ result.diagnostics,
678
+ palette
679
+ ) : void 0;
680
+ const targetResolved = resolveSlot(dataRow2.label);
681
+ const { label: target, color: targetColor } = extractColor(
682
+ targetResolved,
683
+ palette,
684
+ result.diagnostics,
685
+ lineNumber
686
+ );
687
+ if (targetColor) {
688
+ if (!result.nodeColors) result.nodeColors = {};
689
+ result.nodeColors[target] = targetColor;
690
+ }
691
+ if (!result.links) result.links = [];
692
+ result.links.push({
693
+ source,
694
+ target,
695
+ // In-bounds by values.length === 1 guard above.
696
+ value: dataRow2.values[0],
697
+ ...linkColor && { color: linkColor },
698
+ lineNumber
699
+ });
700
+ sankeyStack.push({ name: target, indent });
701
+ continue;
702
+ }
703
+ }
704
+ }
705
+ const spaceIdx2 = trimmed.indexOf(" ");
706
+ const lastTok = trimmed.substring(trimmed.lastIndexOf(" ") + 1);
707
+ const hasNumericSuffix = spaceIdx2 >= 0 && !isNaN(parseFloat(normalizeNumericToken(lastTok) ?? lastTok));
708
+ const isBareKeywordOption = spaceIdx2 < 0 && /^(solid-fill|no-name|no-value|no-percent|shade|no-title)$/i.test(
709
+ trimmed
710
+ );
711
+ const isLayoutDirective = spaceIdx2 >= 0 && trimmed.substring(0, spaceIdx2).toLowerCase() === "layout";
712
+ if (!hasNumericSuffix && !isBareKeywordOption && !isLayoutDirective) {
713
+ while (sankeyStack.length && sankeyStack.at(-1).indent >= indent) {
714
+ sankeyStack.pop();
715
+ }
716
+ const trimmedResolved = resolveSlot(trimmed);
717
+ const { label: nodeName, color: nodeColor } = extractColor(
718
+ trimmedResolved,
719
+ palette,
720
+ result.diagnostics,
721
+ lineNumber
722
+ );
723
+ if (nodeColor) {
724
+ if (!result.nodeColors) result.nodeColors = {};
725
+ result.nodeColors[nodeName] = nodeColor;
726
+ }
727
+ sankeyStack.push({ name: nodeName, indent });
728
+ continue;
729
+ }
730
+ }
731
+ const spaceIdx = trimmed.indexOf(" ");
732
+ const firstToken = (spaceIdx >= 0 ? trimmed.substring(0, spaceIdx) : trimmed).toLowerCase();
733
+ if (KNOWN_EXTENDED_OPTIONS.has(firstToken) && spaceIdx >= 0) {
734
+ const value = trimmed.substring(spaceIdx + 1).trim();
735
+ if (firstToken === "chart") {
736
+ const chartType = value.toLowerCase();
737
+ if (VALID_EXTENDED_TYPES.has(chartType)) {
738
+ result.type = chartType;
739
+ } else {
740
+ const validTypes = [...VALID_EXTENDED_TYPES];
741
+ let msg = `Unsupported chart type: ${value}. Supported types: ${validTypes.join(", ")}.`;
742
+ const hint = suggest(chartType, validTypes);
743
+ if (hint) msg += ` ${hint}`;
744
+ const diag = makeDgmoError(lineNumber, msg);
745
+ result.diagnostics.push(diag);
746
+ result.error = formatDgmoError(diag);
747
+ return result;
748
+ }
749
+ continue;
750
+ }
751
+ if (firstToken === "title") {
752
+ result.title = value;
753
+ result.titleLineNumber = lineNumber;
754
+ continue;
755
+ }
756
+ if (firstToken === "series") {
757
+ const parsed = parseSeriesNames(value, lines, i, palette);
758
+ i = parsed.newIndex;
759
+ result.series = parsed.series;
760
+ result.seriesLineNumber = lineNumber;
761
+ if (parsed.names.length > 1) {
762
+ result.seriesNames = parsed.names;
763
+ result.seriesNameLineNumbers = parsed.nameLineNumbers;
764
+ }
765
+ if (parsed.nameColors.some(Boolean))
766
+ result.seriesNameColors = parsed.nameColors;
767
+ continue;
768
+ }
769
+ if (firstToken === "x-label") {
770
+ result.xlabel = value;
771
+ result.xlabelLineNumber = lineNumber;
772
+ continue;
773
+ }
774
+ if (firstToken === "y-label") {
775
+ result.ylabel = value;
776
+ result.ylabelLineNumber = lineNumber;
777
+ continue;
778
+ }
779
+ if (firstToken === "size-label") {
780
+ result.sizelabel = value;
781
+ continue;
782
+ }
783
+ if (firstToken === "layout") {
784
+ const v = value.toLowerCase();
785
+ if (v === "arc" || v === "chord") result.layout = v;
786
+ continue;
787
+ }
788
+ if (firstToken === "columns") {
789
+ if (value) {
790
+ result.columns = value.includes(",") ? value.split(",").map((s) => s.trim()) : value.split(/\s+/);
791
+ } else {
792
+ const collected = collectIndentedValues(lines, i);
793
+ i = collected.newIndex;
794
+ result.columns = collected.values;
795
+ }
796
+ continue;
797
+ }
798
+ if (firstToken === "rows") {
799
+ if (value) {
800
+ result.rows = value.includes(",") ? value.split(",").map((s) => s.trim()) : value.split(/\s+/);
801
+ } else {
802
+ const collected = collectIndentedValues(lines, i);
803
+ i = collected.newIndex;
804
+ result.rows = collected.values;
805
+ }
806
+ continue;
807
+ }
808
+ if (firstToken === "x") {
809
+ const rangeMatch = value.match(/^(-?[\d.]+)\s+to\s+(-?[\d.]+)$/);
810
+ if (rangeMatch) {
811
+ result.xRange = {
812
+ // Regex capture groups [1] and [2] are non-optional in the pattern.
813
+ min: parseFloat(rangeMatch[1]),
814
+ max: parseFloat(rangeMatch[2])
815
+ };
816
+ continue;
817
+ }
818
+ if (!(result.type === "function" && trimmed.includes(":"))) {
819
+ continue;
820
+ }
821
+ }
822
+ }
823
+ if (firstToken === "no-name") {
824
+ result.noName = true;
825
+ continue;
826
+ }
827
+ if (firstToken === "no-value") {
828
+ result.noValue = true;
829
+ continue;
830
+ }
831
+ if (firstToken === "no-percent") {
832
+ result.noPercent = true;
833
+ continue;
834
+ }
835
+ if (firstToken === "shade") {
836
+ result.shade = true;
837
+ continue;
838
+ }
839
+ if (firstToken === "solid-fill") {
840
+ result.solidFill = true;
841
+ continue;
842
+ }
843
+ if (firstToken === "no-title" && spaceIdx < 0) {
844
+ result.noTitle = true;
845
+ continue;
846
+ }
847
+ if (firstToken.startsWith("no-") && spaceIdx < 0) {
848
+ continue;
849
+ }
850
+ if (firstToken === "series" && spaceIdx === -1) {
851
+ const parsed = parseSeriesNames("", lines, i, palette);
852
+ i = parsed.newIndex;
853
+ result.series = parsed.series;
854
+ result.seriesLineNumber = lineNumber;
855
+ if (parsed.names.length > 1) {
856
+ result.seriesNames = parsed.names;
857
+ result.seriesNameLineNumbers = parsed.nameLineNumbers;
858
+ }
859
+ if (parsed.nameColors.some(Boolean))
860
+ result.seriesNameColors = parsed.nameColors;
861
+ continue;
862
+ }
863
+ if (firstToken === "columns" && spaceIdx === -1) {
864
+ const collected = collectIndentedValues(lines, i);
865
+ i = collected.newIndex;
866
+ result.columns = collected.values;
867
+ continue;
868
+ }
869
+ if (firstToken === "rows" && spaceIdx === -1) {
870
+ const collected = collectIndentedValues(lines, i);
871
+ i = collected.newIndex;
872
+ result.rows = collected.values;
873
+ continue;
874
+ }
875
+ if (result.type === "function") {
876
+ const colonIndex = trimmed.indexOf(":");
877
+ if (colonIndex >= 0) {
878
+ const { label: fnName, color: fnColor } = extractColor(
879
+ trimmed.substring(0, colonIndex).trim(),
880
+ palette,
881
+ result.diagnostics,
882
+ lineNumber
883
+ );
884
+ const fnValue = trimmed.substring(colonIndex + 1).trim();
885
+ if (!result.functions) result.functions = [];
886
+ result.functions.push({
887
+ name: fnName,
888
+ expression: fnValue,
889
+ ...fnColor && { color: fnColor },
890
+ lineNumber
891
+ });
892
+ continue;
893
+ }
894
+ }
895
+ if (result.type === "scatter") {
896
+ const scatterData = parseScatterRow(
897
+ trimmed,
898
+ palette,
899
+ currentCategory,
900
+ lineNumber,
901
+ result.diagnostics
902
+ );
903
+ if (scatterData) {
904
+ if (!result.scatterPoints) result.scatterPoints = [];
905
+ result.scatterPoints.push(scatterData);
906
+ continue;
907
+ }
908
+ }
909
+ if (result.type === "heatmap") {
910
+ const dataRow2 = parseDataRowValues(trimmed, { multiValue: true });
911
+ if (dataRow2 && dataRow2.values.length > 0) {
912
+ if (!result.heatmapRows) result.heatmapRows = [];
913
+ result.heatmapRows.push({
914
+ label: dataRow2.label,
915
+ values: dataRow2.values,
916
+ lineNumber
917
+ });
918
+ continue;
919
+ }
920
+ }
921
+ const dataRow = parseDataRowValues(trimmed);
922
+ if (dataRow?.values.length === 1) {
923
+ const { label: rawLabel, color: pointColor } = extractColor(
924
+ dataRow.label,
925
+ palette,
926
+ result.diagnostics,
927
+ lineNumber
928
+ );
929
+ result.data.push({
930
+ label: rawLabel,
931
+ // In-bounds by values.length === 1 guard above.
932
+ value: dataRow.values[0],
933
+ ...pointColor && { color: pointColor },
934
+ lineNumber
935
+ });
936
+ continue;
937
+ }
938
+ result.diagnostics.push(
939
+ makeDgmoError(
940
+ lineNumber,
941
+ `Unexpected line: '${trimmed}'. Expected a data row ('Label value', space-separated) or a known option.`,
942
+ "warning"
943
+ )
944
+ );
945
+ }
946
+ const warn = (line, message) => {
947
+ result.diagnostics.push(makeDgmoError(line, message, "warning"));
948
+ };
949
+ if (!result.error) {
950
+ if (result.type === "sankey") {
951
+ if (!result.links || result.links.length === 0) {
952
+ warn(1, "No links found. Add links in format: Source -> Target 123");
953
+ }
954
+ } else if (result.type === "chord") {
955
+ if (!result.links || result.links.length === 0) {
956
+ warn(1, "No links found. Add links in format: Source -> Target 123");
957
+ }
958
+ } else if (result.type === "function") {
959
+ if (!result.functions || result.functions.length === 0) {
960
+ warn(
961
+ 1,
962
+ "No functions found. Add functions in format: Name: expression"
963
+ );
964
+ }
965
+ if (!result.xRange) {
966
+ result.xRange = { min: -10, max: 10 };
967
+ }
968
+ } else if (result.type === "scatter") {
969
+ if (!result.scatterPoints || result.scatterPoints.length === 0) {
970
+ warn(
971
+ 1,
972
+ "No scatter points found. Add points in format: Name: x, y or Name: x, y, size"
973
+ );
974
+ }
975
+ } else if (result.type === "heatmap") {
976
+ if (!result.heatmapRows || result.heatmapRows.length === 0) {
977
+ warn(
978
+ 1,
979
+ "No heatmap data found. Add data in format: RowLabel: val1, val2, val3"
980
+ );
981
+ }
982
+ if (!result.columns || result.columns.length === 0) {
983
+ warn(
984
+ 1,
985
+ "No columns defined. Add columns in format: columns: Col1, Col2, Col3"
986
+ );
987
+ }
988
+ } else if (result.type === "funnel") {
989
+ if (result.data.length === 0) {
990
+ warn(1, "No data found. Add data in format: Label: value");
991
+ }
992
+ }
993
+ }
994
+ return result;
995
+ }
996
+ function getSimpleChartLegendGroups(parsed, colors) {
997
+ if (!parsed.seriesNames || parsed.seriesNames.length <= 1) return [];
998
+ return [
999
+ {
1000
+ name: "Series",
1001
+ entries: parsed.seriesNames.map((name, i) => ({
1002
+ value: name,
1003
+ // colors is a non-empty palette array; modulo index is always in-bounds.
1004
+ color: parsed.seriesNameColors?.[i] ?? colors[i % colors.length]
1005
+ }))
1006
+ }
1007
+ ];
1008
+ }
1009
+ function getExtendedChartLegendGroups(parsed, colors) {
1010
+ if (parsed.type === "scatter") {
1011
+ const points = parsed.scatterPoints ?? [];
1012
+ const categories = [
1013
+ ...new Set(points.map((p) => p.category).filter(Boolean))
1014
+ ];
1015
+ if (categories.length === 0) return [];
1016
+ return [
1017
+ {
1018
+ name: "Group",
1019
+ entries: categories.map((cat, i) => ({
1020
+ value: cat,
1021
+ // colors is a non-empty palette array; modulo index is always in-bounds.
1022
+ color: parsed.categoryColors?.[cat] ?? colors[i % colors.length]
1023
+ }))
1024
+ }
1025
+ ];
1026
+ }
1027
+ if (parsed.type === "function") {
1028
+ const fns = parsed.functions ?? [];
1029
+ if (fns.length === 0) return [];
1030
+ return [
1031
+ {
1032
+ name: "Function",
1033
+ entries: fns.map((fn, i) => ({
1034
+ value: fn.name,
1035
+ // colors is a non-empty palette array; modulo index is always in-bounds.
1036
+ color: fn.color ?? colors[i % colors.length]
1037
+ }))
1038
+ }
1039
+ ];
1040
+ }
1041
+ return [];
1042
+ }
1043
+
1044
+ export {
1045
+ parseChart,
1046
+ parseDataRowValues,
1047
+ parseExtendedChart,
1048
+ parseSankey,
1049
+ parseFunctionChart,
1050
+ parseScatter,
1051
+ parseHeatmap,
1052
+ parseFunnel,
1053
+ EXTENDED_CHART_DOORS,
1054
+ getSimpleChartLegendGroups,
1055
+ getExtendedChartLegendGroups
1056
+ };
1057
+ //# sourceMappingURL=chunk-P235SVAH.js.map