schematex 0.1.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 (181) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +379 -0
  3. package/dist/chunk-2MQWZ2XY.cjs +453 -0
  4. package/dist/chunk-2MQWZ2XY.cjs.map +1 -0
  5. package/dist/chunk-2UKC6ZCY.cjs +1803 -0
  6. package/dist/chunk-2UKC6ZCY.cjs.map +1 -0
  7. package/dist/chunk-34X3ZJ6E.cjs +783 -0
  8. package/dist/chunk-34X3ZJ6E.cjs.map +1 -0
  9. package/dist/chunk-3FTUWAXK.cjs +1220 -0
  10. package/dist/chunk-3FTUWAXK.cjs.map +1 -0
  11. package/dist/chunk-3J7TFUOC.js +745 -0
  12. package/dist/chunk-3J7TFUOC.js.map +1 -0
  13. package/dist/chunk-47ZC6EMJ.js +1009 -0
  14. package/dist/chunk-47ZC6EMJ.js.map +1 -0
  15. package/dist/chunk-4DBRNOPA.cjs +750 -0
  16. package/dist/chunk-4DBRNOPA.cjs.map +1 -0
  17. package/dist/chunk-4G7ZIBHN.js +778 -0
  18. package/dist/chunk-4G7ZIBHN.js.map +1 -0
  19. package/dist/chunk-5C7DPDHQ.js +1321 -0
  20. package/dist/chunk-5C7DPDHQ.js.map +1 -0
  21. package/dist/chunk-ADOXGKAK.js +1251 -0
  22. package/dist/chunk-ADOXGKAK.js.map +1 -0
  23. package/dist/chunk-BE5HNDA5.cjs +874 -0
  24. package/dist/chunk-BE5HNDA5.cjs.map +1 -0
  25. package/dist/chunk-CZRM7LT7.js +889 -0
  26. package/dist/chunk-CZRM7LT7.js.map +1 -0
  27. package/dist/chunk-D4JTSPOL.js +1795 -0
  28. package/dist/chunk-D4JTSPOL.js.map +1 -0
  29. package/dist/chunk-DS47NTWZ.cjs +1034 -0
  30. package/dist/chunk-DS47NTWZ.cjs.map +1 -0
  31. package/dist/chunk-FDLZEKEB.js +449 -0
  32. package/dist/chunk-FDLZEKEB.js.map +1 -0
  33. package/dist/chunk-FGPTCDUT.cjs +1851 -0
  34. package/dist/chunk-FGPTCDUT.cjs.map +1 -0
  35. package/dist/chunk-HDKDQAEQ.cjs +86 -0
  36. package/dist/chunk-HDKDQAEQ.cjs.map +1 -0
  37. package/dist/chunk-IX554O5K.js +346 -0
  38. package/dist/chunk-IX554O5K.js.map +1 -0
  39. package/dist/chunk-KLJEK547.js +71 -0
  40. package/dist/chunk-KLJEK547.js.map +1 -0
  41. package/dist/chunk-LMFSHK45.js +1028 -0
  42. package/dist/chunk-LMFSHK45.js.map +1 -0
  43. package/dist/chunk-MDICUK6F.cjs +1258 -0
  44. package/dist/chunk-MDICUK6F.cjs.map +1 -0
  45. package/dist/chunk-N7KOXOMX.cjs +363 -0
  46. package/dist/chunk-N7KOXOMX.cjs.map +1 -0
  47. package/dist/chunk-NYCIK4SU.cjs +775 -0
  48. package/dist/chunk-NYCIK4SU.cjs.map +1 -0
  49. package/dist/chunk-PDPHRZZT.js +770 -0
  50. package/dist/chunk-PDPHRZZT.js.map +1 -0
  51. package/dist/chunk-ROFLJ74T.js +1212 -0
  52. package/dist/chunk-ROFLJ74T.js.map +1 -0
  53. package/dist/chunk-S6BK5DB6.cjs +845 -0
  54. package/dist/chunk-S6BK5DB6.cjs.map +1 -0
  55. package/dist/chunk-U4I37IBN.js +874 -0
  56. package/dist/chunk-U4I37IBN.js.map +1 -0
  57. package/dist/chunk-U5GGE6PJ.js +839 -0
  58. package/dist/chunk-U5GGE6PJ.js.map +1 -0
  59. package/dist/chunk-UHLYS3W5.cjs +1015 -0
  60. package/dist/chunk-UHLYS3W5.cjs.map +1 -0
  61. package/dist/chunk-URSKIHSY.cjs +881 -0
  62. package/dist/chunk-URSKIHSY.cjs.map +1 -0
  63. package/dist/chunk-V6WO7RK7.cjs +1056 -0
  64. package/dist/chunk-V6WO7RK7.cjs.map +1 -0
  65. package/dist/chunk-VFQCTXOX.js +869 -0
  66. package/dist/chunk-VFQCTXOX.js.map +1 -0
  67. package/dist/chunk-XQ52ICHU.cjs +895 -0
  68. package/dist/chunk-XQ52ICHU.cjs.map +1 -0
  69. package/dist/chunk-XX4BKS7Y.js +1051 -0
  70. package/dist/chunk-XX4BKS7Y.js.map +1 -0
  71. package/dist/chunk-XXU36667.js +1844 -0
  72. package/dist/chunk-XXU36667.js.map +1 -0
  73. package/dist/chunk-ZX7QKZK2.cjs +1326 -0
  74. package/dist/chunk-ZX7QKZK2.cjs.map +1 -0
  75. package/dist/diagrams/blockdiagram/index.cjs +25 -0
  76. package/dist/diagrams/blockdiagram/index.cjs.map +1 -0
  77. package/dist/diagrams/blockdiagram/index.d.cts +67 -0
  78. package/dist/diagrams/blockdiagram/index.d.ts +67 -0
  79. package/dist/diagrams/blockdiagram/index.js +4 -0
  80. package/dist/diagrams/blockdiagram/index.js.map +1 -0
  81. package/dist/diagrams/circuit/index.cjs +34 -0
  82. package/dist/diagrams/circuit/index.cjs.map +1 -0
  83. package/dist/diagrams/circuit/index.d.cts +138 -0
  84. package/dist/diagrams/circuit/index.d.ts +138 -0
  85. package/dist/diagrams/circuit/index.js +5 -0
  86. package/dist/diagrams/circuit/index.js.map +1 -0
  87. package/dist/diagrams/ecomap/index.cjs +30 -0
  88. package/dist/diagrams/ecomap/index.cjs.map +1 -0
  89. package/dist/diagrams/ecomap/index.d.cts +15 -0
  90. package/dist/diagrams/ecomap/index.d.ts +15 -0
  91. package/dist/diagrams/ecomap/index.js +5 -0
  92. package/dist/diagrams/ecomap/index.js.map +1 -0
  93. package/dist/diagrams/entity/index.cjs +26 -0
  94. package/dist/diagrams/entity/index.cjs.map +1 -0
  95. package/dist/diagrams/entity/index.d.cts +54 -0
  96. package/dist/diagrams/entity/index.d.ts +54 -0
  97. package/dist/diagrams/entity/index.js +5 -0
  98. package/dist/diagrams/entity/index.js.map +1 -0
  99. package/dist/diagrams/fishbone/index.cjs +34 -0
  100. package/dist/diagrams/fishbone/index.cjs.map +1 -0
  101. package/dist/diagrams/fishbone/index.d.cts +185 -0
  102. package/dist/diagrams/fishbone/index.d.ts +185 -0
  103. package/dist/diagrams/fishbone/index.js +5 -0
  104. package/dist/diagrams/fishbone/index.js.map +1 -0
  105. package/dist/diagrams/flowchart/index.cjs +34 -0
  106. package/dist/diagrams/flowchart/index.cjs.map +1 -0
  107. package/dist/diagrams/flowchart/index.d.cts +2 -0
  108. package/dist/diagrams/flowchart/index.d.ts +2 -0
  109. package/dist/diagrams/flowchart/index.js +5 -0
  110. package/dist/diagrams/flowchart/index.js.map +1 -0
  111. package/dist/diagrams/genogram/index.cjs +38 -0
  112. package/dist/diagrams/genogram/index.cjs.map +1 -0
  113. package/dist/diagrams/genogram/index.d.cts +20 -0
  114. package/dist/diagrams/genogram/index.d.ts +20 -0
  115. package/dist/diagrams/genogram/index.js +5 -0
  116. package/dist/diagrams/genogram/index.js.map +1 -0
  117. package/dist/diagrams/ladder/index.cjs +26 -0
  118. package/dist/diagrams/ladder/index.cjs.map +1 -0
  119. package/dist/diagrams/ladder/index.d.cts +49 -0
  120. package/dist/diagrams/ladder/index.d.ts +49 -0
  121. package/dist/diagrams/ladder/index.js +5 -0
  122. package/dist/diagrams/ladder/index.js.map +1 -0
  123. package/dist/diagrams/logic/index.cjs +26 -0
  124. package/dist/diagrams/logic/index.cjs.map +1 -0
  125. package/dist/diagrams/logic/index.d.cts +73 -0
  126. package/dist/diagrams/logic/index.d.ts +73 -0
  127. package/dist/diagrams/logic/index.js +5 -0
  128. package/dist/diagrams/logic/index.js.map +1 -0
  129. package/dist/diagrams/orgchart/index.cjs +30 -0
  130. package/dist/diagrams/orgchart/index.cjs.map +1 -0
  131. package/dist/diagrams/orgchart/index.d.cts +100 -0
  132. package/dist/diagrams/orgchart/index.d.ts +100 -0
  133. package/dist/diagrams/orgchart/index.js +5 -0
  134. package/dist/diagrams/orgchart/index.js.map +1 -0
  135. package/dist/diagrams/pedigree/index.cjs +30 -0
  136. package/dist/diagrams/pedigree/index.cjs.map +1 -0
  137. package/dist/diagrams/pedigree/index.d.cts +15 -0
  138. package/dist/diagrams/pedigree/index.d.ts +15 -0
  139. package/dist/diagrams/pedigree/index.js +5 -0
  140. package/dist/diagrams/pedigree/index.js.map +1 -0
  141. package/dist/diagrams/phylo/index.cjs +30 -0
  142. package/dist/diagrams/phylo/index.cjs.map +1 -0
  143. package/dist/diagrams/phylo/index.d.cts +32 -0
  144. package/dist/diagrams/phylo/index.d.ts +32 -0
  145. package/dist/diagrams/phylo/index.js +5 -0
  146. package/dist/diagrams/phylo/index.js.map +1 -0
  147. package/dist/diagrams/sld/index.cjs +26 -0
  148. package/dist/diagrams/sld/index.cjs.map +1 -0
  149. package/dist/diagrams/sld/index.d.cts +58 -0
  150. package/dist/diagrams/sld/index.d.ts +58 -0
  151. package/dist/diagrams/sld/index.js +5 -0
  152. package/dist/diagrams/sld/index.js.map +1 -0
  153. package/dist/diagrams/sociogram/index.cjs +26 -0
  154. package/dist/diagrams/sociogram/index.cjs.map +1 -0
  155. package/dist/diagrams/sociogram/index.d.cts +76 -0
  156. package/dist/diagrams/sociogram/index.d.ts +76 -0
  157. package/dist/diagrams/sociogram/index.js +5 -0
  158. package/dist/diagrams/sociogram/index.js.map +1 -0
  159. package/dist/diagrams/timing/index.cjs +21 -0
  160. package/dist/diagrams/timing/index.cjs.map +1 -0
  161. package/dist/diagrams/timing/index.d.cts +9 -0
  162. package/dist/diagrams/timing/index.d.ts +9 -0
  163. package/dist/diagrams/timing/index.js +4 -0
  164. package/dist/diagrams/timing/index.js.map +1 -0
  165. package/dist/diagrams/venn/index.cjs +38 -0
  166. package/dist/diagrams/venn/index.cjs.map +1 -0
  167. package/dist/diagrams/venn/index.d.cts +69 -0
  168. package/dist/diagrams/venn/index.d.ts +69 -0
  169. package/dist/diagrams/venn/index.js +5 -0
  170. package/dist/diagrams/venn/index.js.map +1 -0
  171. package/dist/index-BSlza1YY.d.ts +150 -0
  172. package/dist/index-BXefHVce.d.cts +150 -0
  173. package/dist/index.cjs +2033 -0
  174. package/dist/index.cjs.map +1 -0
  175. package/dist/index.d.cts +29 -0
  176. package/dist/index.d.ts +29 -0
  177. package/dist/index.js +1944 -0
  178. package/dist/index.js.map +1 -0
  179. package/dist/types-DqfcYkcY.d.cts +741 -0
  180. package/dist/types-DqfcYkcY.d.ts +741 -0
  181. package/package.json +163 -0
@@ -0,0 +1,1326 @@
1
+ 'use strict';
2
+
3
+ var chunkN7KOXOMX_cjs = require('./chunk-N7KOXOMX.cjs');
4
+ var chunkHDKDQAEQ_cjs = require('./chunk-HDKDQAEQ.cjs');
5
+
6
+ // src/diagrams/sld/parser.ts
7
+ var SLDParseError = class extends Error {
8
+ constructor(message) {
9
+ super(message);
10
+ this.name = "SLDParseError";
11
+ }
12
+ };
13
+ var NODE_TYPES = /* @__PURE__ */ new Set([
14
+ "utility",
15
+ "generator",
16
+ "solar",
17
+ "wind",
18
+ "ups",
19
+ "transformer",
20
+ "transformer_dy",
21
+ "transformer_yd",
22
+ "transformer_yy",
23
+ "transformer_dd",
24
+ "autotransformer",
25
+ "transformer_3winding",
26
+ "bus",
27
+ "bus_tie",
28
+ "hub",
29
+ "breaker",
30
+ "breaker_vacuum",
31
+ "switch",
32
+ "switch_load",
33
+ "ground_switch",
34
+ "ats",
35
+ "recloser",
36
+ "sectionalizer",
37
+ "fuse",
38
+ "fuse_cl",
39
+ "ct",
40
+ "pt",
41
+ "relay",
42
+ "surge_arrester",
43
+ "ground_fault",
44
+ "motor",
45
+ "load",
46
+ "capacitor_bank",
47
+ "harmonic_filter",
48
+ "vfd",
49
+ "watthour_meter",
50
+ "demand_meter"
51
+ ]);
52
+ function stripComment(s) {
53
+ let out = "";
54
+ let inQuote = false;
55
+ for (const ch of s) {
56
+ if (ch === '"') inQuote = !inQuote;
57
+ if (ch === "#" && !inQuote) break;
58
+ out += ch;
59
+ }
60
+ return out;
61
+ }
62
+ function stripQuotes(v) {
63
+ const t = v.trim();
64
+ if (t.length >= 2 && t.startsWith('"') && t.endsWith('"')) {
65
+ return t.slice(1, -1);
66
+ }
67
+ return t;
68
+ }
69
+ function splitAttrs(inside) {
70
+ const parts = [];
71
+ let cur = "";
72
+ let inQuote = false;
73
+ for (const ch of inside) {
74
+ if (ch === '"') inQuote = !inQuote;
75
+ if (ch === "," && !inQuote) {
76
+ parts.push(cur);
77
+ cur = "";
78
+ } else {
79
+ cur += ch;
80
+ }
81
+ }
82
+ if (cur.trim()) parts.push(cur);
83
+ const out = [];
84
+ for (const p of parts) {
85
+ const s = p.trim();
86
+ if (!s) continue;
87
+ const colon = s.indexOf(":");
88
+ if (colon < 0) {
89
+ throw new SLDParseError(`Invalid attribute "${s}" (missing ":")`);
90
+ }
91
+ const k = s.slice(0, colon).trim();
92
+ const v = stripQuotes(s.slice(colon + 1));
93
+ out.push([k, v]);
94
+ }
95
+ return out;
96
+ }
97
+ function applyAttrs(node, attrs) {
98
+ for (const [k, v] of attrs) {
99
+ const key = k.toLowerCase();
100
+ if (key === "label") node.label = v;
101
+ else if (key === "voltage") node.voltage = v;
102
+ else if (key === "rating") node.rating = v;
103
+ else if (key === "device") node.deviceNumber = v;
104
+ else {
105
+ if (!node.nameplate) node.nameplate = {};
106
+ node.nameplate[k] = v;
107
+ }
108
+ }
109
+ }
110
+ function joinBrackets(lines) {
111
+ const out = [];
112
+ let buf = "";
113
+ let depth = 0;
114
+ for (const raw of lines) {
115
+ const line = stripComment(raw);
116
+ if (!line.trim() && depth === 0) {
117
+ if (buf) {
118
+ out.push(buf);
119
+ buf = "";
120
+ }
121
+ out.push("");
122
+ continue;
123
+ }
124
+ for (const ch of line) {
125
+ if (ch === "[") depth++;
126
+ else if (ch === "]") depth = Math.max(0, depth - 1);
127
+ }
128
+ buf = buf ? buf + " " + line.trim() : line;
129
+ if (depth === 0) {
130
+ out.push(buf);
131
+ buf = "";
132
+ }
133
+ }
134
+ if (buf) out.push(buf);
135
+ return out;
136
+ }
137
+ function parseSLDDSL(text2) {
138
+ const rawLines = text2.split("\n").map((l) => l.replace(/\r$/, ""));
139
+ const lines = joinBrackets(rawLines);
140
+ let title2;
141
+ const nodes = [];
142
+ const nodeMap = /* @__PURE__ */ new Map();
143
+ const connections = [];
144
+ for (let i = 0; i < lines.length; i++) {
145
+ const raw = lines[i];
146
+ const line = raw.trim();
147
+ if (!line) continue;
148
+ if (/^sld\b/i.test(line)) {
149
+ const m = line.match(/"([^"]*)"/);
150
+ if (m) title2 = m[1];
151
+ continue;
152
+ }
153
+ const connMatch = line.match(
154
+ /^([A-Za-z][A-Za-z0-9_\-]*)\s*->\s*([A-Za-z][A-Za-z0-9_\-]*)(?:\s*\[([^\]]*)\])?\s*$/
155
+ );
156
+ if (connMatch) {
157
+ const from = connMatch[1];
158
+ const to = connMatch[2];
159
+ const c = { from, to };
160
+ if (connMatch[3]) {
161
+ for (const [k, v] of splitAttrs(connMatch[3])) {
162
+ const key = k.toLowerCase();
163
+ if (key === "cable") c.cable = v;
164
+ else if (key === "label") c.label = v;
165
+ }
166
+ }
167
+ connections.push(c);
168
+ continue;
169
+ }
170
+ const nodeMatch = line.match(
171
+ /^([A-Za-z][A-Za-z0-9_\-]*)\s*=\s*([a-zA-Z_][a-zA-Z0-9_]*)(?:\s*\[([^\]]*)\])?\s*$/
172
+ );
173
+ if (nodeMatch) {
174
+ const id = nodeMatch[1];
175
+ const nodeType = nodeMatch[2];
176
+ if (!NODE_TYPES.has(nodeType)) {
177
+ throw new SLDParseError(
178
+ `Unknown node type "${nodeType}" for "${id}" (line: ${line})`
179
+ );
180
+ }
181
+ if (nodeMap.has(id)) {
182
+ throw new SLDParseError(`Duplicate node id "${id}"`);
183
+ }
184
+ const node = { id, nodeType };
185
+ if (nodeMatch[3]) {
186
+ applyAttrs(node, splitAttrs(nodeMatch[3]));
187
+ }
188
+ nodes.push(node);
189
+ nodeMap.set(id, node);
190
+ continue;
191
+ }
192
+ throw new SLDParseError(`Cannot parse line: ${line}`);
193
+ }
194
+ for (const c of connections) {
195
+ if (!nodeMap.has(c.from)) {
196
+ throw new SLDParseError(`Connection references unknown node "${c.from}"`);
197
+ }
198
+ if (!nodeMap.has(c.to)) {
199
+ throw new SLDParseError(`Connection references unknown node "${c.to}"`);
200
+ }
201
+ }
202
+ if (nodes.length === 0) {
203
+ throw new SLDParseError("SLD diagram has no nodes");
204
+ }
205
+ return { type: "sld", title: title2, nodes, connections };
206
+ }
207
+
208
+ // src/diagrams/sld/symbols.ts
209
+ var DEFAULT_GEOMETRY = {
210
+ halfWidth: 20,
211
+ topY: -20,
212
+ bottomY: 20
213
+ };
214
+ function geometryFor(type) {
215
+ switch (type) {
216
+ case "utility":
217
+ case "generator":
218
+ case "solar":
219
+ case "wind":
220
+ return { halfWidth: 18, topY: -24, bottomY: 18 };
221
+ case "transformer":
222
+ case "transformer_dy":
223
+ case "transformer_yd":
224
+ case "transformer_yy":
225
+ case "transformer_dd":
226
+ case "autotransformer":
227
+ case "transformer_3winding":
228
+ return { halfWidth: 22, topY: -24, bottomY: 24 };
229
+ case "breaker":
230
+ case "breaker_vacuum":
231
+ case "recloser":
232
+ case "switch":
233
+ case "switch_load":
234
+ case "ground_switch":
235
+ case "sectionalizer":
236
+ return { halfWidth: 18, topY: -18, bottomY: 18 };
237
+ case "fuse":
238
+ case "fuse_cl":
239
+ return { halfWidth: 14, topY: -18, bottomY: 18 };
240
+ case "motor":
241
+ return { halfWidth: 16, topY: -16, bottomY: 22 };
242
+ case "load":
243
+ case "capacitor_bank":
244
+ case "harmonic_filter":
245
+ return { halfWidth: 20, topY: -14, bottomY: 14 };
246
+ case "vfd":
247
+ case "ups":
248
+ return { halfWidth: 24, topY: -18, bottomY: 18 };
249
+ case "ats":
250
+ return { halfWidth: 22, topY: -18, bottomY: 18 };
251
+ case "ct":
252
+ case "pt":
253
+ return { halfWidth: 10, topY: -16, bottomY: 16 };
254
+ case "relay":
255
+ return { halfWidth: 12, topY: -12, bottomY: 12 };
256
+ case "surge_arrester":
257
+ return { halfWidth: 12, topY: -16, bottomY: 26 };
258
+ case "watthour_meter":
259
+ case "demand_meter":
260
+ case "ground_fault":
261
+ return { halfWidth: 14, topY: -14, bottomY: 14 };
262
+ case "bus":
263
+ return DEFAULT_GEOMETRY;
264
+ case "hub":
265
+ return { halfWidth: 52, topY: -20, bottomY: 20 };
266
+ case "bus_tie":
267
+ return { halfWidth: 16, topY: -10, bottomY: 10 };
268
+ default:
269
+ return DEFAULT_GEOMETRY;
270
+ }
271
+ }
272
+ function lineEl(x1, y1, x2, y2, cls = "lt-sld-stroke") {
273
+ return chunkHDKDQAEQ_cjs.el("line", { x1, y1, x2, y2, class: cls });
274
+ }
275
+ function utilitySymbol() {
276
+ return chunkHDKDQAEQ_cjs.group({}, [
277
+ chunkHDKDQAEQ_cjs.el("circle", { cx: 0, cy: 0, r: 16, class: "lt-sld-fill" }),
278
+ chunkHDKDQAEQ_cjs.path({ d: "M -8 0 Q -4 -8 0 0 Q 4 8 8 0", class: "lt-sld-stroke", fill: "none" }),
279
+ // lead wires in/out
280
+ lineEl(0, -24, 0, -16),
281
+ lineEl(0, 16, 0, 18)
282
+ ]);
283
+ }
284
+ function generatorSymbol() {
285
+ return chunkHDKDQAEQ_cjs.group({}, [
286
+ chunkHDKDQAEQ_cjs.el("circle", { cx: 0, cy: 0, r: 16, class: "lt-sld-fill" }),
287
+ chunkHDKDQAEQ_cjs.text({ x: 0, y: -2, class: "lt-sld-symbol-text", "text-anchor": "middle", "font-weight": "bold", "font-size": "14" }, "G"),
288
+ chunkHDKDQAEQ_cjs.path({ d: "M -6 6 Q -3 1 0 6 Q 3 11 6 6", class: "lt-sld-stroke", fill: "none" }),
289
+ lineEl(0, -24, 0, -16),
290
+ lineEl(0, 16, 0, 18)
291
+ ]);
292
+ }
293
+ function solarSymbol() {
294
+ return chunkHDKDQAEQ_cjs.group({}, [
295
+ chunkHDKDQAEQ_cjs.el("rect", { x: -18, y: -12, width: 36, height: 24, class: "lt-sld-fill" }),
296
+ lineEl(-18, -4, 18, -4),
297
+ lineEl(-18, 4, 18, 4),
298
+ lineEl(-6, -12, -6, 12),
299
+ lineEl(6, -12, 6, 12),
300
+ lineEl(0, 12, 0, 18)
301
+ ]);
302
+ }
303
+ function windSymbol() {
304
+ return chunkHDKDQAEQ_cjs.group({}, [
305
+ chunkHDKDQAEQ_cjs.el("circle", { cx: 0, cy: 0, r: 6, class: "lt-sld-fill" }),
306
+ lineEl(0, -6, 0, -22),
307
+ chunkHDKDQAEQ_cjs.path({ d: "M 0 -6 L 14 -2 L 0 0 Z", class: "lt-sld-fill-dark" }),
308
+ chunkHDKDQAEQ_cjs.path({ d: "M 0 -6 L -10 8 L 0 2 Z", class: "lt-sld-fill-dark" }),
309
+ chunkHDKDQAEQ_cjs.path({ d: "M 0 -6 L -6 -18 L 2 -6 Z", class: "lt-sld-fill-dark" }),
310
+ lineEl(0, 6, 0, 18)
311
+ ]);
312
+ }
313
+ function upsSymbol() {
314
+ return chunkHDKDQAEQ_cjs.group({}, [
315
+ chunkHDKDQAEQ_cjs.el("rect", { x: -22, y: -16, width: 44, height: 32, class: "lt-sld-fill" }),
316
+ chunkHDKDQAEQ_cjs.text({ x: 0, y: 4, class: "lt-sld-symbol-text", "text-anchor": "middle", "font-weight": "bold", "font-size": "11" }, "UPS")
317
+ ]);
318
+ }
319
+ function transformerSymbol(type) {
320
+ const pieces = [];
321
+ pieces.push(
322
+ chunkHDKDQAEQ_cjs.path({
323
+ d: "M -12 -18 A 4 4 0 0 1 -4 -18 A 4 4 0 0 1 4 -18 A 4 4 0 0 1 12 -18",
324
+ class: "lt-sld-stroke",
325
+ fill: "none"
326
+ })
327
+ );
328
+ pieces.push(lineEl(-14, -8, 14, -8));
329
+ pieces.push(lineEl(-14, -4, 14, -4));
330
+ pieces.push(
331
+ chunkHDKDQAEQ_cjs.path({
332
+ d: "M -12 18 A 4 4 0 0 0 -4 18 A 4 4 0 0 0 4 18 A 4 4 0 0 0 12 18",
333
+ class: "lt-sld-stroke",
334
+ fill: "none"
335
+ })
336
+ );
337
+ pieces.push(chunkHDKDQAEQ_cjs.el("circle", { cx: -10, cy: -14, r: 2, class: "lt-sld-dot" }));
338
+ pieces.push(chunkHDKDQAEQ_cjs.el("circle", { cx: 10, cy: 14, r: 2, class: "lt-sld-dot" }));
339
+ pieces.push(lineEl(0, -24, 0, -22));
340
+ pieces.push(lineEl(0, 22, 0, 24));
341
+ const { primary, secondary } = windingGlyphs(type);
342
+ if (primary) pieces.push(chunkHDKDQAEQ_cjs.text({ x: 20, y: -14, class: "lt-sld-wdg", "text-anchor": "start" }, primary));
343
+ if (secondary) pieces.push(chunkHDKDQAEQ_cjs.text({ x: 20, y: 18, class: "lt-sld-wdg", "text-anchor": "start" }, secondary));
344
+ return chunkHDKDQAEQ_cjs.group({}, pieces);
345
+ }
346
+ function windingGlyphs(type) {
347
+ switch (type) {
348
+ case "transformer_dy":
349
+ return { primary: "\u0394", secondary: "Y" };
350
+ case "transformer_yd":
351
+ return { primary: "Y", secondary: "\u0394" };
352
+ case "transformer_yy":
353
+ return { primary: "Y", secondary: "Y" };
354
+ case "transformer_dd":
355
+ return { primary: "\u0394", secondary: "\u0394" };
356
+ default:
357
+ return {};
358
+ }
359
+ }
360
+ function autotransformerSymbol() {
361
+ return chunkHDKDQAEQ_cjs.group({}, [
362
+ chunkHDKDQAEQ_cjs.path({
363
+ d: "M 0 -20 A 6 6 0 0 1 0 -10 A 6 6 0 0 1 0 0 A 6 6 0 0 1 0 10 A 6 6 0 0 1 0 20",
364
+ class: "lt-sld-stroke",
365
+ fill: "none"
366
+ }),
367
+ lineEl(6, 0, 14, 0),
368
+ lineEl(0, -24, 0, -20),
369
+ lineEl(0, 20, 0, 24)
370
+ ]);
371
+ }
372
+ function threeWindingSymbol() {
373
+ return chunkHDKDQAEQ_cjs.group({}, [
374
+ // top coil
375
+ chunkHDKDQAEQ_cjs.path({ d: "M -10 -18 A 3 3 0 0 1 -4 -18 A 3 3 0 0 1 2 -18 A 3 3 0 0 1 8 -18", class: "lt-sld-stroke", fill: "none" }),
376
+ // left-bottom coil
377
+ chunkHDKDQAEQ_cjs.path({ d: "M -18 6 A 3 3 0 0 1 -12 6 A 3 3 0 0 1 -6 6 A 3 3 0 0 1 0 6", class: "lt-sld-stroke", fill: "none" }),
378
+ // right-bottom coil
379
+ chunkHDKDQAEQ_cjs.path({ d: "M 0 6 A 3 3 0 0 1 6 6 A 3 3 0 0 1 12 6 A 3 3 0 0 1 18 6", class: "lt-sld-stroke", fill: "none" }),
380
+ lineEl(-14, -8, 14, -8),
381
+ lineEl(0, -24, 0, -18),
382
+ lineEl(-9, 10, -9, 24),
383
+ lineEl(9, 10, 9, 24)
384
+ ]);
385
+ }
386
+ function breakerSymbol() {
387
+ return chunkHDKDQAEQ_cjs.group({}, [
388
+ lineEl(0, -14, 0, -10, "lt-sld-stroke"),
389
+ lineEl(0, 10, 0, 14, "lt-sld-stroke"),
390
+ chunkHDKDQAEQ_cjs.el("line", { x1: -6, y1: 10, x2: 8, y2: -10, class: "lt-sld-stroke-thick" }),
391
+ chunkHDKDQAEQ_cjs.path({ d: "M 8 -10 Q 14 -12 12 -18", class: "lt-sld-stroke", fill: "none" }),
392
+ lineEl(0, -18, 0, -14),
393
+ lineEl(0, 14, 0, 18)
394
+ ]);
395
+ }
396
+ function vacuumBreakerSymbol() {
397
+ return chunkHDKDQAEQ_cjs.group({}, [
398
+ chunkHDKDQAEQ_cjs.el("ellipse", { cx: 0, cy: 0, rx: 10, ry: 14, class: "lt-sld-fill" }),
399
+ chunkHDKDQAEQ_cjs.el("line", { x1: -6, y1: 10, x2: 8, y2: -10, class: "lt-sld-stroke-thick" }),
400
+ chunkHDKDQAEQ_cjs.text({ x: -2, y: -4, class: "lt-sld-symbol-text", "text-anchor": "middle", "font-size": "8" }, "V"),
401
+ lineEl(0, -18, 0, -14),
402
+ lineEl(0, 14, 0, 18)
403
+ ]);
404
+ }
405
+ function recloserSymbol() {
406
+ return chunkHDKDQAEQ_cjs.group({}, [
407
+ chunkHDKDQAEQ_cjs.el("line", { x1: -6, y1: 10, x2: 8, y2: -10, class: "lt-sld-stroke-thick" }),
408
+ chunkHDKDQAEQ_cjs.path({ d: "M 8 -10 Q 14 -12 12 -18", class: "lt-sld-stroke", fill: "none" }),
409
+ chunkHDKDQAEQ_cjs.path({ d: "M 14 -6 A 5 5 0 1 1 18 -4", class: "lt-sld-stroke", fill: "none" }),
410
+ chunkHDKDQAEQ_cjs.el("polygon", { points: "18,-4 20,-8 15,-7", class: "lt-sld-dot" }),
411
+ lineEl(0, -18, 0, -14),
412
+ lineEl(0, 14, 0, 18)
413
+ ]);
414
+ }
415
+ function switchSymbol(open = false) {
416
+ const pieces = [];
417
+ if (open) {
418
+ pieces.push(chunkHDKDQAEQ_cjs.el("line", { x1: -6, y1: 10, x2: 10, y2: -8, class: "lt-sld-stroke-thick" }));
419
+ pieces.push(chunkHDKDQAEQ_cjs.el("circle", { cx: 10, cy: -8, r: 2, class: "lt-sld-fill" }));
420
+ } else {
421
+ pieces.push(chunkHDKDQAEQ_cjs.el("line", { x1: -6, y1: 10, x2: 8, y2: -10, class: "lt-sld-stroke-thick" }));
422
+ }
423
+ pieces.push(lineEl(0, -18, 0, -10));
424
+ pieces.push(lineEl(0, 10, 0, 18));
425
+ return chunkHDKDQAEQ_cjs.group({}, pieces);
426
+ }
427
+ function loadSwitchSymbol() {
428
+ return chunkHDKDQAEQ_cjs.group({}, [
429
+ chunkHDKDQAEQ_cjs.el("line", { x1: -6, y1: 10, x2: 8, y2: -10, class: "lt-sld-stroke-thick" }),
430
+ chunkHDKDQAEQ_cjs.el("rect", { x: 6, y: -14, width: 6, height: 6, class: "lt-sld-fill" }),
431
+ lineEl(0, -18, 0, -10),
432
+ lineEl(0, 10, 0, 18)
433
+ ]);
434
+ }
435
+ function groundSwitchSymbol() {
436
+ return chunkHDKDQAEQ_cjs.group({}, [
437
+ chunkHDKDQAEQ_cjs.el("line", { x1: -6, y1: 0, x2: 8, y2: -14, class: "lt-sld-stroke-thick" }),
438
+ lineEl(0, -18, 0, -4),
439
+ // ground symbol
440
+ lineEl(-8, 6, 8, 6),
441
+ lineEl(-5, 10, 5, 10),
442
+ lineEl(-2, 14, 2, 14),
443
+ lineEl(0, 0, 0, 6)
444
+ ]);
445
+ }
446
+ function sectionalizerSymbol() {
447
+ return chunkHDKDQAEQ_cjs.group({}, [
448
+ chunkHDKDQAEQ_cjs.el("line", { x1: -6, y1: 10, x2: 10, y2: -8, class: "lt-sld-stroke-thick" }),
449
+ chunkHDKDQAEQ_cjs.el("circle", { cx: 10, cy: -8, r: 2, class: "lt-sld-fill" }),
450
+ chunkHDKDQAEQ_cjs.text({ x: 14, y: -4, class: "lt-sld-wdg", "text-anchor": "start" }, "S"),
451
+ lineEl(0, -18, 0, -10),
452
+ lineEl(0, 10, 0, 18)
453
+ ]);
454
+ }
455
+ function fuseSymbol() {
456
+ return chunkHDKDQAEQ_cjs.group({}, [
457
+ chunkHDKDQAEQ_cjs.el("rect", { x: -5, y: -10, width: 10, height: 20, class: "lt-sld-fill" }),
458
+ lineEl(0, -18, 0, -10),
459
+ lineEl(0, 10, 0, 18)
460
+ ]);
461
+ }
462
+ function fuseCLSymbol() {
463
+ return chunkHDKDQAEQ_cjs.group({}, [
464
+ chunkHDKDQAEQ_cjs.el("rect", { x: -6, y: -12, width: 12, height: 24, class: "lt-sld-fill" }),
465
+ lineEl(-6, 0, 6, 0),
466
+ lineEl(0, -18, 0, -12),
467
+ lineEl(0, 12, 0, 18)
468
+ ]);
469
+ }
470
+ function motorSymbol() {
471
+ return chunkHDKDQAEQ_cjs.group({}, [
472
+ chunkHDKDQAEQ_cjs.el("circle", { cx: 0, cy: 0, r: 14, class: "lt-sld-fill" }),
473
+ chunkHDKDQAEQ_cjs.text({ x: 0, y: 5, class: "lt-sld-symbol-text", "text-anchor": "middle", "font-weight": "bold", "font-size": "13" }, "M"),
474
+ lineEl(0, -16, 0, -14),
475
+ // 3-phase dots at bottom
476
+ chunkHDKDQAEQ_cjs.el("circle", { cx: -6, cy: 12, r: 1.5, class: "lt-sld-dot" }),
477
+ chunkHDKDQAEQ_cjs.el("circle", { cx: 0, cy: 14, r: 1.5, class: "lt-sld-dot" }),
478
+ chunkHDKDQAEQ_cjs.el("circle", { cx: 6, cy: 12, r: 1.5, class: "lt-sld-dot" })
479
+ ]);
480
+ }
481
+ function loadSymbol() {
482
+ return chunkHDKDQAEQ_cjs.group({}, [
483
+ chunkHDKDQAEQ_cjs.el("rect", { x: -16, y: -12, width: 32, height: 24, class: "lt-sld-fill" })
484
+ ]);
485
+ }
486
+ function capacitorBankSymbol() {
487
+ return chunkHDKDQAEQ_cjs.group({}, [
488
+ lineEl(-10, -6, 10, -6, "lt-sld-stroke-thick"),
489
+ lineEl(-10, -2, 10, -2, "lt-sld-stroke-thick"),
490
+ lineEl(-10, 4, 10, 4, "lt-sld-stroke-thick"),
491
+ lineEl(-10, 8, 10, 8, "lt-sld-stroke-thick"),
492
+ lineEl(0, -14, 0, -6),
493
+ lineEl(0, 8, 0, 14)
494
+ ]);
495
+ }
496
+ function harmonicFilterSymbol() {
497
+ return chunkHDKDQAEQ_cjs.group({}, [
498
+ // L + C chained
499
+ chunkHDKDQAEQ_cjs.path({ d: "M -14 -4 A 3 3 0 0 1 -8 -4 A 3 3 0 0 1 -2 -4 A 3 3 0 0 1 4 -4", class: "lt-sld-stroke", fill: "none" }),
500
+ lineEl(4, -8, 14, -8),
501
+ lineEl(4, 0, 14, 0),
502
+ lineEl(0, -14, 0, -4),
503
+ lineEl(0, 4, 0, 14)
504
+ ]);
505
+ }
506
+ function vfdSymbol() {
507
+ return chunkHDKDQAEQ_cjs.group({}, [
508
+ chunkHDKDQAEQ_cjs.el("rect", { x: -22, y: -16, width: 44, height: 32, class: "lt-sld-fill" }),
509
+ chunkHDKDQAEQ_cjs.text({ x: 0, y: -2, class: "lt-sld-symbol-text", "text-anchor": "middle", "font-weight": "bold", "font-size": "11" }, "VFD"),
510
+ chunkHDKDQAEQ_cjs.path({ d: "M -10 8 Q -5 2 0 8 Q 5 14 10 8", class: "lt-sld-stroke", fill: "none" }),
511
+ lineEl(0, -18, 0, -16),
512
+ lineEl(0, 16, 0, 18)
513
+ ]);
514
+ }
515
+ function atsSymbol() {
516
+ return chunkHDKDQAEQ_cjs.group({}, [
517
+ chunkHDKDQAEQ_cjs.el("rect", { x: -22, y: -16, width: 44, height: 32, class: "lt-sld-fill" }),
518
+ chunkHDKDQAEQ_cjs.el("line", { x1: -14, y1: -8, x2: -2, y2: 6, class: "lt-sld-stroke-thick" }),
519
+ chunkHDKDQAEQ_cjs.el("line", { x1: 14, y1: -8, x2: 2, y2: 6, class: "lt-sld-stroke-thick" }),
520
+ chunkHDKDQAEQ_cjs.text({ x: 0, y: 14, class: "lt-sld-symbol-text", "text-anchor": "middle", "font-weight": "bold", "font-size": "9" }, "ATS"),
521
+ lineEl(-12, -18, -12, -16),
522
+ lineEl(12, -18, 12, -16),
523
+ lineEl(0, 16, 0, 18)
524
+ ]);
525
+ }
526
+ function ctSymbol() {
527
+ return chunkHDKDQAEQ_cjs.group({}, [
528
+ chunkHDKDQAEQ_cjs.el("circle", { cx: 0, cy: 0, r: 7, class: "lt-sld-fill" }),
529
+ chunkHDKDQAEQ_cjs.text({ x: 0, y: 3, class: "lt-sld-wdg", "text-anchor": "middle", "font-size": "7" }, "CT"),
530
+ lineEl(0, -16, 0, -7),
531
+ lineEl(0, 7, 0, 16)
532
+ ]);
533
+ }
534
+ function ptSymbol() {
535
+ return chunkHDKDQAEQ_cjs.group({}, [
536
+ chunkHDKDQAEQ_cjs.el("circle", { cx: 0, cy: 0, r: 7, class: "lt-sld-fill" }),
537
+ chunkHDKDQAEQ_cjs.text({ x: 0, y: 3, class: "lt-sld-wdg", "text-anchor": "middle", "font-size": "7" }, "PT"),
538
+ lineEl(0, -16, 0, -7),
539
+ lineEl(0, 7, 0, 16)
540
+ ]);
541
+ }
542
+ function relaySymbol(deviceNumber) {
543
+ return chunkHDKDQAEQ_cjs.group({}, [
544
+ chunkHDKDQAEQ_cjs.el("circle", { cx: 0, cy: 0, r: 11, class: "lt-sld-fill" }),
545
+ chunkHDKDQAEQ_cjs.text({ x: 0, y: 4, class: "lt-sld-wdg", "text-anchor": "middle", "font-size": "10" }, deviceNumber ?? "R")
546
+ ]);
547
+ }
548
+ function surgeArresterSymbol() {
549
+ return chunkHDKDQAEQ_cjs.group({}, [
550
+ chunkHDKDQAEQ_cjs.el("rect", { x: -7, y: -6, width: 14, height: 14, class: "lt-sld-fill" }),
551
+ chunkHDKDQAEQ_cjs.path({ d: "M -4 2 Q 0 -4 4 2", class: "lt-sld-stroke", fill: "none" }),
552
+ lineEl(0, -16, 0, -6),
553
+ lineEl(0, 8, 0, 14),
554
+ lineEl(-8, 14, 8, 14),
555
+ lineEl(-5, 18, 5, 18),
556
+ lineEl(-2, 22, 2, 22)
557
+ ]);
558
+ }
559
+ function groundFaultSymbol() {
560
+ return chunkHDKDQAEQ_cjs.group({}, [
561
+ chunkHDKDQAEQ_cjs.el("circle", { cx: 0, cy: 0, r: 12, class: "lt-sld-fill" }),
562
+ chunkHDKDQAEQ_cjs.text({ x: 0, y: 4, class: "lt-sld-wdg", "text-anchor": "middle", "font-size": "9" }, "GFI"),
563
+ lineEl(0, -14, 0, -12),
564
+ lineEl(0, 12, 0, 14)
565
+ ]);
566
+ }
567
+ function hubSymbol(label) {
568
+ return chunkHDKDQAEQ_cjs.group({}, [
569
+ chunkHDKDQAEQ_cjs.el("rect", {
570
+ x: -50,
571
+ y: -18,
572
+ width: 100,
573
+ height: 36,
574
+ rx: 4,
575
+ ry: 4,
576
+ class: "lt-sld-fill",
577
+ "stroke-width": 2
578
+ }),
579
+ chunkHDKDQAEQ_cjs.text(
580
+ { x: 0, y: 4, class: "lt-sld-wdg", "text-anchor": "middle", "font-size": "11" },
581
+ label ?? "HUB"
582
+ ),
583
+ lineEl(0, -20, 0, -18),
584
+ lineEl(0, 18, 0, 20),
585
+ // left/right lead stubs for lateral ports
586
+ lineEl(-50, 0, -54, 0),
587
+ lineEl(50, 0, 54, 0)
588
+ ]);
589
+ }
590
+ function busTieSymbol() {
591
+ return chunkHDKDQAEQ_cjs.group({}, [
592
+ lineEl(-16, 0, -4, 0),
593
+ lineEl(4, 0, 16, 0),
594
+ chunkHDKDQAEQ_cjs.path({ d: "M -4 0 L 4 -6", class: "lt-sld-stroke-thick" }),
595
+ chunkHDKDQAEQ_cjs.path({ d: "M -4 -6 Q 0 -10 4 -6", class: "lt-sld-stroke", fill: "none" })
596
+ ]);
597
+ }
598
+ function meterSymbol(label) {
599
+ return chunkHDKDQAEQ_cjs.group({}, [
600
+ chunkHDKDQAEQ_cjs.el("circle", { cx: 0, cy: 0, r: 12, class: "lt-sld-fill" }),
601
+ chunkHDKDQAEQ_cjs.text({ x: 0, y: 4, class: "lt-sld-wdg", "text-anchor": "middle", "font-size": "9" }, label),
602
+ lineEl(0, -14, 0, -12),
603
+ lineEl(0, 12, 0, 14)
604
+ ]);
605
+ }
606
+ function renderSymbol(type, detail) {
607
+ switch (type) {
608
+ case "utility":
609
+ return utilitySymbol();
610
+ case "generator":
611
+ return generatorSymbol();
612
+ case "solar":
613
+ return solarSymbol();
614
+ case "wind":
615
+ return windSymbol();
616
+ case "ups":
617
+ return upsSymbol();
618
+ case "transformer":
619
+ case "transformer_dy":
620
+ case "transformer_yd":
621
+ case "transformer_yy":
622
+ case "transformer_dd":
623
+ return transformerSymbol(type);
624
+ case "autotransformer":
625
+ return autotransformerSymbol();
626
+ case "transformer_3winding":
627
+ return threeWindingSymbol();
628
+ case "breaker":
629
+ return breakerSymbol();
630
+ case "breaker_vacuum":
631
+ return vacuumBreakerSymbol();
632
+ case "recloser":
633
+ return recloserSymbol();
634
+ case "switch":
635
+ return switchSymbol(true);
636
+ case "switch_load":
637
+ return loadSwitchSymbol();
638
+ case "ground_switch":
639
+ return groundSwitchSymbol();
640
+ case "sectionalizer":
641
+ return sectionalizerSymbol();
642
+ case "fuse":
643
+ return fuseSymbol();
644
+ case "fuse_cl":
645
+ return fuseCLSymbol();
646
+ case "motor":
647
+ return motorSymbol();
648
+ case "load":
649
+ return loadSymbol();
650
+ case "capacitor_bank":
651
+ return capacitorBankSymbol();
652
+ case "harmonic_filter":
653
+ return harmonicFilterSymbol();
654
+ case "vfd":
655
+ return vfdSymbol();
656
+ case "ats":
657
+ return atsSymbol();
658
+ case "ct":
659
+ return ctSymbol();
660
+ case "pt":
661
+ return ptSymbol();
662
+ case "relay":
663
+ return relaySymbol(detail);
664
+ case "surge_arrester":
665
+ return surgeArresterSymbol();
666
+ case "ground_fault":
667
+ return groundFaultSymbol();
668
+ case "watthour_meter":
669
+ return meterSymbol("Wh");
670
+ case "demand_meter":
671
+ return meterSymbol("D");
672
+ case "bus":
673
+ return "";
674
+ case "hub":
675
+ return hubSymbol(detail);
676
+ case "bus_tie":
677
+ return busTieSymbol();
678
+ default:
679
+ return loadSymbol();
680
+ }
681
+ }
682
+
683
+ // src/diagrams/sld/layout.ts
684
+ var LEVEL_SPACING = 100;
685
+ var H_SPACING = 90;
686
+ var LEFT_PADDING = 80;
687
+ var TOP_PADDING = 40;
688
+ var BUS_OVERHANG = 20;
689
+ function computeLevels(ast) {
690
+ const levels = /* @__PURE__ */ new Map();
691
+ const inEdges = /* @__PURE__ */ new Map();
692
+ const outEdges = /* @__PURE__ */ new Map();
693
+ for (const n of ast.nodes) {
694
+ inEdges.set(n.id, []);
695
+ outEdges.set(n.id, []);
696
+ }
697
+ for (const c of ast.connections) {
698
+ inEdges.get(c.to)?.push(c);
699
+ outEdges.get(c.from)?.push(c);
700
+ }
701
+ const roots = ast.nodes.filter((n) => (inEdges.get(n.id) ?? []).length === 0);
702
+ for (const r of roots) levels.set(r.id, 0);
703
+ const typeById = /* @__PURE__ */ new Map();
704
+ for (const n of ast.nodes) typeById.set(n.id, n.nodeType);
705
+ const isTieEdge = (c) => typeById.get(c.from) === "bus_tie" || typeById.get(c.to) === "bus_tie";
706
+ const maxIter = ast.nodes.length + 2;
707
+ for (let iter = 0; iter < maxIter; iter++) {
708
+ let changed = false;
709
+ for (const c of ast.connections) {
710
+ if (isTieEdge(c)) continue;
711
+ const fromLvl = levels.get(c.from);
712
+ if (fromLvl === void 0) continue;
713
+ const want = fromLvl + 1;
714
+ const curr = levels.get(c.to);
715
+ if (curr === void 0 || want > curr) {
716
+ levels.set(c.to, want);
717
+ changed = true;
718
+ }
719
+ }
720
+ if (!changed) break;
721
+ }
722
+ for (let iter = 0; iter < maxIter; iter++) {
723
+ let changed = false;
724
+ for (const c of ast.connections) {
725
+ if (!isTieEdge(c)) continue;
726
+ const fromLvl = levels.get(c.from);
727
+ const toLvl = levels.get(c.to);
728
+ const shared = fromLvl ?? toLvl;
729
+ if (shared === void 0) continue;
730
+ if (fromLvl === void 0 || fromLvl !== shared) {
731
+ levels.set(c.from, shared);
732
+ changed = true;
733
+ }
734
+ if (toLvl === void 0 || toLvl !== shared) {
735
+ levels.set(c.to, shared);
736
+ changed = true;
737
+ }
738
+ }
739
+ if (!changed) break;
740
+ }
741
+ for (const n of ast.nodes) {
742
+ if (!levels.has(n.id)) levels.set(n.id, 0);
743
+ }
744
+ return levels;
745
+ }
746
+ function orderWithinLevel(ast, levels) {
747
+ const byLevel = /* @__PURE__ */ new Map();
748
+ for (const n of ast.nodes) {
749
+ const lvl = levels.get(n.id) ?? 0;
750
+ if (!byLevel.has(lvl)) byLevel.set(lvl, []);
751
+ byLevel.get(lvl).push(n.id);
752
+ }
753
+ const visited = /* @__PURE__ */ new Set();
754
+ const order = /* @__PURE__ */ new Map();
755
+ let idx = 0;
756
+ const adj = /* @__PURE__ */ new Map();
757
+ for (const n of ast.nodes) adj.set(n.id, []);
758
+ for (const c of ast.connections) adj.get(c.from)?.push(c.to);
759
+ function dfs(id) {
760
+ if (visited.has(id)) return;
761
+ visited.add(id);
762
+ order.set(id, idx++);
763
+ for (const child of adj.get(id) ?? []) dfs(child);
764
+ }
765
+ const inEdgeCount = /* @__PURE__ */ new Map();
766
+ for (const n of ast.nodes) inEdgeCount.set(n.id, 0);
767
+ for (const c of ast.connections) {
768
+ inEdgeCount.set(c.to, (inEdgeCount.get(c.to) ?? 0) + 1);
769
+ }
770
+ for (const n of ast.nodes) {
771
+ if ((inEdgeCount.get(n.id) ?? 0) === 0) dfs(n.id);
772
+ }
773
+ for (const n of ast.nodes) dfs(n.id);
774
+ for (const [lvl, ids] of byLevel.entries()) {
775
+ ids.sort((a, b) => (order.get(a) ?? 0) - (order.get(b) ?? 0));
776
+ byLevel.set(lvl, ids);
777
+ }
778
+ return byLevel;
779
+ }
780
+ function layoutSLD(ast) {
781
+ const levels = computeLevels(ast);
782
+ const byLevel = orderWithinLevel(ast, levels);
783
+ const nodeMap = /* @__PURE__ */ new Map();
784
+ for (const n of ast.nodes) nodeMap.set(n.id, n);
785
+ const layoutNodes = [];
786
+ const byIdLayout = /* @__PURE__ */ new Map();
787
+ const parents = /* @__PURE__ */ new Map();
788
+ const children = /* @__PURE__ */ new Map();
789
+ for (const n of ast.nodes) {
790
+ parents.set(n.id, []);
791
+ children.set(n.id, []);
792
+ }
793
+ for (const c of ast.connections) {
794
+ parents.get(c.to)?.push(c.from);
795
+ children.get(c.from)?.push(c.to);
796
+ }
797
+ const sortedLevels = Array.from(byLevel.keys()).sort((a, b) => a - b);
798
+ const maxLevel = sortedLevels.length ? sortedLevels[sortedLevels.length - 1] : 0;
799
+ let nextX = LEFT_PADDING;
800
+ function placeNode(id) {
801
+ const existing = byIdLayout.get(id);
802
+ if (existing) return existing;
803
+ const node = nodeMap.get(id);
804
+ const lvl = levels.get(id) ?? 0;
805
+ const geom = geometryFor(node.nodeType);
806
+ const y = TOP_PADDING + lvl * LEVEL_SPACING;
807
+ const ln = {
808
+ node,
809
+ nodeType: node.nodeType,
810
+ x: 0,
811
+ y,
812
+ topY: y + geom.topY,
813
+ bottomY: y + geom.bottomY,
814
+ level: lvl,
815
+ halfWidth: geom.halfWidth
816
+ };
817
+ byIdLayout.set(id, ln);
818
+ layoutNodes.push(ln);
819
+ return ln;
820
+ }
821
+ for (const lvl of sortedLevels) {
822
+ for (const id of byLevel.get(lvl)) {
823
+ const ln = placeNode(id);
824
+ if (ln.nodeType === "bus") {
825
+ ln.x = nextX;
826
+ } else {
827
+ ln.x = nextX;
828
+ nextX += H_SPACING;
829
+ }
830
+ }
831
+ }
832
+ for (let iter = 0; iter < 4; iter++) {
833
+ for (const lvl of sortedLevels) {
834
+ for (const id of byLevel.get(lvl)) {
835
+ const ln = byIdLayout.get(id);
836
+ if (ln.nodeType !== "bus") continue;
837
+ const childrenIds = children.get(id) ?? [];
838
+ const parentIds = parents.get(id) ?? [];
839
+ const relatedXs = [];
840
+ for (const cid of childrenIds) {
841
+ const c = byIdLayout.get(cid);
842
+ if (c && c.nodeType !== "bus_tie") relatedXs.push(c.x);
843
+ }
844
+ if (relatedXs.length === 0) {
845
+ for (const pid of parentIds) {
846
+ const p = byIdLayout.get(pid);
847
+ if (p && p.nodeType !== "bus_tie") relatedXs.push(p.x);
848
+ }
849
+ }
850
+ if (relatedXs.length > 0) {
851
+ const minX = Math.min(...relatedXs);
852
+ const maxX2 = Math.max(...relatedXs);
853
+ ln.x = (minX + maxX2) / 2;
854
+ ln.busLeft = minX - BUS_OVERHANG;
855
+ ln.busRight = maxX2 + BUS_OVERHANG;
856
+ } else {
857
+ ln.busLeft = ln.x - 40;
858
+ ln.busRight = ln.x + 40;
859
+ }
860
+ }
861
+ }
862
+ }
863
+ const CONVERGENCE_SPREAD = Math.max(H_SPACING, 110);
864
+ for (let iter = 0; iter < 4; iter++) {
865
+ for (const lvl of [...sortedLevels].reverse()) {
866
+ for (const id of byLevel.get(lvl)) {
867
+ const ln = byIdLayout.get(id);
868
+ if (ln.nodeType === "bus" || ln.nodeType === "bus_tie") continue;
869
+ const childIds = children.get(id) ?? [];
870
+ if (childIds.length === 1) {
871
+ const child = byIdLayout.get(childIds[0]);
872
+ if (!child) continue;
873
+ const siblingParents = (parents.get(child.node.id) ?? []).map((pid) => byIdLayout.get(pid)).filter((p) => !!p && p.level === lvl && p.nodeType !== "bus");
874
+ if (siblingParents.length > 1) {
875
+ siblingParents.sort((a, b) => a.x - b.x);
876
+ const n = siblingParents.length;
877
+ const spread = Math.max(
878
+ CONVERGENCE_SPREAD,
879
+ (child.halfWidth * 2 + 40) / Math.max(1, n - 1)
880
+ );
881
+ const idx = siblingParents.indexOf(ln);
882
+ ln.x = child.x + (idx - (n - 1) / 2) * spread;
883
+ } else {
884
+ ln.x = child.x;
885
+ }
886
+ } else if (childIds.length > 1) {
887
+ const xs = childIds.map((c) => byIdLayout.get(c)?.x).filter((v) => v !== void 0);
888
+ if (xs.length > 0) {
889
+ ln.x = (Math.min(...xs) + Math.max(...xs)) / 2;
890
+ }
891
+ }
892
+ }
893
+ }
894
+ }
895
+ for (const ln of layoutNodes) {
896
+ if (ln.nodeType !== "bus_tie") continue;
897
+ const inIds = parents.get(ln.node.id) ?? [];
898
+ const outIds = children.get(ln.node.id) ?? [];
899
+ const busA = inIds.map((id) => byIdLayout.get(id)).find((n) => n?.nodeType === "bus");
900
+ const busB = outIds.map((id) => byIdLayout.get(id)).find((n) => n?.nodeType === "bus");
901
+ if (!busA || !busB) continue;
902
+ const busAChildren = (children.get(busA.node.id) ?? []).map((id) => byIdLayout.get(id)).filter((c) => !!c && c.nodeType !== "bus_tie");
903
+ const busAMaxX = busAChildren.length ? Math.max(...busAChildren.map((c) => c.x)) : busA.x;
904
+ ln.y = busA.y;
905
+ ln.x = busAMaxX + 60;
906
+ const cluster = /* @__PURE__ */ new Set([busB.node.id]);
907
+ const queue = [busB.node.id];
908
+ const excluded = /* @__PURE__ */ new Set([busA.node.id, ln.node.id]);
909
+ while (queue.length) {
910
+ const cur = queue.shift();
911
+ const neighbors = [...children.get(cur) ?? [], ...parents.get(cur) ?? []];
912
+ for (const nb of neighbors) {
913
+ if (cluster.has(nb) || excluded.has(nb)) continue;
914
+ cluster.add(nb);
915
+ queue.push(nb);
916
+ }
917
+ }
918
+ let minClusterX = Infinity;
919
+ for (const id of cluster) {
920
+ const n = byIdLayout.get(id);
921
+ if (!n) continue;
922
+ const left = n.nodeType === "bus" ? n.busLeft ?? n.x : n.x - n.halfWidth;
923
+ if (left < minClusterX) minClusterX = left;
924
+ }
925
+ const desiredLeft = ln.x + 30;
926
+ const shift = desiredLeft - minClusterX;
927
+ if (shift > 0) {
928
+ for (const id of cluster) {
929
+ const n = byIdLayout.get(id);
930
+ if (!n) continue;
931
+ n.x += shift;
932
+ if (n.busLeft !== void 0) n.busLeft += shift;
933
+ if (n.busRight !== void 0) n.busRight += shift;
934
+ }
935
+ }
936
+ }
937
+ const labelHalfWidth = (ln) => {
938
+ if (ln.nodeType === "bus" || ln.nodeType === "bus_tie") return 0;
939
+ const node = ln.node;
940
+ const txtParts = [node.label ?? node.id];
941
+ if (node.rating) txtParts.push(node.rating);
942
+ const longest = txtParts.reduce((m, s) => Math.max(m, s.length), 0);
943
+ return longest * 6.2 / 2 + 4;
944
+ };
945
+ for (const lvl of sortedLevels) {
946
+ const ids = byLevel.get(lvl);
947
+ const sorted = ids.map((id) => byIdLayout.get(id)).sort((a, b) => a.x - b.x);
948
+ for (let i = 1; i < sorted.length; i++) {
949
+ const prev = sorted[i - 1];
950
+ const cur = sorted[i];
951
+ if (prev.nodeType === "bus" && cur.nodeType !== "bus") continue;
952
+ if (cur.nodeType === "bus" && prev.nodeType !== "bus") continue;
953
+ const symGap = (prev.nodeType === "bus" ? 0 : prev.halfWidth) + (cur.nodeType === "bus" ? 0 : cur.halfWidth) + 16;
954
+ const labelGap = labelHalfWidth(prev) + labelHalfWidth(cur) + 8;
955
+ const minGap = Math.max(symGap, labelGap);
956
+ if (cur.x - prev.x < minGap) {
957
+ cur.x = prev.x + minGap;
958
+ }
959
+ }
960
+ }
961
+ for (const ln of layoutNodes) {
962
+ if (ln.nodeType !== "bus") continue;
963
+ const childrenIds = children.get(ln.node.id) ?? [];
964
+ const parentIds = parents.get(ln.node.id) ?? [];
965
+ const xs = [];
966
+ for (const cid of [...childrenIds, ...parentIds]) {
967
+ const rel = byIdLayout.get(cid);
968
+ if (rel && rel.nodeType !== "bus_tie") xs.push(rel.x);
969
+ }
970
+ const tieXs = [];
971
+ for (const cid of [...childrenIds, ...parentIds]) {
972
+ const rel = byIdLayout.get(cid);
973
+ if (rel && rel.nodeType === "bus_tie") tieXs.push(rel.x);
974
+ }
975
+ if (xs.length > 0) {
976
+ let left = Math.min(...xs) - BUS_OVERHANG;
977
+ let right = Math.max(...xs) + BUS_OVERHANG;
978
+ for (const tx of tieXs) {
979
+ if (tx < left) left = tx;
980
+ if (tx > right) right = tx;
981
+ }
982
+ ln.busLeft = left;
983
+ ln.busRight = right;
984
+ ln.x = (Math.min(...xs) + Math.max(...xs)) / 2;
985
+ }
986
+ }
987
+ for (const ln of layoutNodes) {
988
+ const geom = geometryFor(ln.nodeType);
989
+ ln.topY = ln.y + geom.topY;
990
+ ln.bottomY = ln.y + geom.bottomY;
991
+ }
992
+ const edges = [];
993
+ for (const c of ast.connections) {
994
+ const from = byIdLayout.get(c.from);
995
+ const to = byIdLayout.get(c.to);
996
+ if (!from || !to) continue;
997
+ const fx = from.x;
998
+ const tx = to.x;
999
+ const lateralTie = from.nodeType === "bus_tie" || to.nodeType === "bus_tie" || from.level === to.level && (from.nodeType === "bus" || to.nodeType === "bus");
1000
+ let startY;
1001
+ let endY;
1002
+ if (lateralTie) {
1003
+ startY = from.y;
1004
+ endY = to.y;
1005
+ } else {
1006
+ startY = from.nodeType === "bus" ? from.y : from.bottomY;
1007
+ endY = to.nodeType === "bus" ? to.y : to.topY;
1008
+ }
1009
+ let pathD;
1010
+ if (lateralTie) {
1011
+ pathD = `M ${fx} ${startY} L ${tx} ${endY}`;
1012
+ } else if (Math.abs(fx - tx) < 0.5) {
1013
+ pathD = `M ${fx} ${startY} L ${tx} ${endY}`;
1014
+ } else {
1015
+ const midY = (startY + endY) / 2;
1016
+ pathD = `M ${fx} ${startY} L ${fx} ${midY} L ${tx} ${midY} L ${tx} ${endY}`;
1017
+ }
1018
+ edges.push({
1019
+ from: c.from,
1020
+ to: c.to,
1021
+ path: pathD,
1022
+ cable: c.cable,
1023
+ label: c.label,
1024
+ midX: (fx + tx) / 2,
1025
+ midY: (startY + endY) / 2
1026
+ });
1027
+ }
1028
+ const bands = [];
1029
+ for (const lvl of sortedLevels) {
1030
+ let voltage;
1031
+ for (const id of byLevel.get(lvl)) {
1032
+ const n = nodeMap.get(id);
1033
+ if (n.voltage) {
1034
+ voltage = n.voltage;
1035
+ break;
1036
+ }
1037
+ }
1038
+ bands.push({
1039
+ level: lvl,
1040
+ voltage,
1041
+ y: TOP_PADDING + lvl * LEVEL_SPACING - LEVEL_SPACING / 2 + 10,
1042
+ height: LEVEL_SPACING
1043
+ });
1044
+ }
1045
+ let contentMinX = Infinity;
1046
+ for (const ln of layoutNodes) {
1047
+ const left = ln.nodeType === "bus" ? ln.busLeft ?? ln.x : ln.x - ln.halfWidth;
1048
+ if (left < contentMinX) contentMinX = left;
1049
+ }
1050
+ if (!Number.isFinite(contentMinX)) contentMinX = 0;
1051
+ const xShift = LEFT_PADDING - contentMinX;
1052
+ if (Math.abs(xShift) > 0.5) {
1053
+ for (const ln of layoutNodes) {
1054
+ ln.x += xShift;
1055
+ if (ln.busLeft !== void 0) ln.busLeft += xShift;
1056
+ if (ln.busRight !== void 0) ln.busRight += xShift;
1057
+ }
1058
+ for (const e of edges) {
1059
+ e.midX += xShift;
1060
+ e.path = e.path.replace(
1061
+ /([ML])\s+(-?[\d.]+)\s+(-?[\d.]+)/g,
1062
+ (_m, cmd, x, y) => `${cmd} ${Number(x) + xShift} ${y}`
1063
+ );
1064
+ }
1065
+ }
1066
+ let maxX = 0;
1067
+ for (const ln of layoutNodes) {
1068
+ const right = (ln.busRight ?? ln.x + ln.halfWidth) + 60;
1069
+ if (right > maxX) maxX = right;
1070
+ }
1071
+ const width = Math.max(400, maxX + 40);
1072
+ const height = TOP_PADDING + maxLevel * LEVEL_SPACING + 120;
1073
+ return {
1074
+ width,
1075
+ height,
1076
+ nodes: layoutNodes,
1077
+ edges,
1078
+ bands,
1079
+ nodeById: byIdLayout
1080
+ };
1081
+ }
1082
+
1083
+ // src/diagrams/sld/renderer.ts
1084
+ var BAND_ODD_LIGHT = "#f7f7f7";
1085
+ var BAND_EVEN_LIGHT = "#fbfbfb";
1086
+ var BAND_ODD_DARK = "#2a2b3c";
1087
+ var BAND_EVEN_DARK = "#313244";
1088
+ function buildCss(t) {
1089
+ const isDark = t.bg !== "#ffffff";
1090
+ const bandOdd = isDark ? BAND_ODD_DARK : BAND_ODD_LIGHT;
1091
+ const bandEven = isDark ? BAND_EVEN_DARK : BAND_EVEN_LIGHT;
1092
+ return `
1093
+ .lt-sld { background: ${t.bg}; font-family: system-ui, -apple-system, sans-serif; }
1094
+ .lt-sld-stroke { stroke: ${t.stroke}; stroke-width: 1.8; fill: none; }
1095
+ .lt-sld-stroke-thick { stroke: ${t.stroke}; stroke-width: 2.4; fill: none; stroke-linecap: round; }
1096
+ .lt-sld-fill { fill: ${t.bg}; stroke: ${t.stroke}; stroke-width: 2; }
1097
+ .lt-sld-fill-dark { fill: ${t.stroke}; stroke: ${t.stroke}; stroke-width: 1; }
1098
+ .lt-sld-dot { fill: ${t.stroke}; stroke: none; }
1099
+ .lt-sld-wire { stroke: ${t.stroke}; stroke-width: 2; fill: none; }
1100
+ .lt-sld-bus { stroke: ${t.strokeHeavy}; stroke-width: 6; stroke-linecap: square; }
1101
+ .lt-sld-band-odd { fill: ${bandOdd}; stroke: none; }
1102
+ .lt-sld-band-even { fill: ${bandEven}; stroke: none; }
1103
+ .lt-sld-band-label { font: bold 11px sans-serif; fill: ${t.textMuted}; }
1104
+ .lt-sld-title { font: bold 16px sans-serif; fill: ${t.text}; }
1105
+ .lt-sld-id { font: bold 11px sans-serif; fill: ${t.text}; text-anchor: middle; }
1106
+ .lt-sld-rating { font: 9px sans-serif; fill: ${t.textMuted}; text-anchor: middle; }
1107
+ .lt-sld-voltage { font: bold 10px sans-serif; fill: ${t.textMuted}; }
1108
+ .lt-sld-nameplate { font: 9px sans-serif; fill: ${t.textMuted}; }
1109
+ .lt-sld-cable { font: 9px ui-monospace, SFMono-Regular, Menlo, monospace; fill: ${t.textMuted}; }
1110
+ .lt-sld-symbol-text { font: 11px sans-serif; fill: ${t.text}; dominant-baseline: middle; }
1111
+ .lt-sld-wdg { font: bold 10px sans-serif; fill: ${t.stroke}; dominant-baseline: middle; }
1112
+ .lt-sld-bus-label { font: bold 11px sans-serif; fill: ${t.accent}; }
1113
+ `.trim();
1114
+ }
1115
+ function renderLabels(ln) {
1116
+ const pieces = [];
1117
+ const { node } = ln;
1118
+ if (ln.nodeType === "bus") {
1119
+ const label = node.label ?? node.id;
1120
+ pieces.push(
1121
+ chunkHDKDQAEQ_cjs.text(
1122
+ { x: (ln.busLeft ?? ln.x - 40) + 4, y: ln.y - 8, class: "lt-sld-bus-label" },
1123
+ node.voltage ? `${node.voltage} \xB7 ${label}` : label
1124
+ )
1125
+ );
1126
+ return pieces;
1127
+ }
1128
+ if (ln.nodeType === "hub") {
1129
+ if (node.rating || node.voltage) {
1130
+ const lines2 = [];
1131
+ if (node.rating) lines2.push(node.rating);
1132
+ if (node.voltage) lines2.push(node.voltage);
1133
+ lines2.forEach((l, i) => {
1134
+ pieces.push(
1135
+ chunkHDKDQAEQ_cjs.text(
1136
+ { x: ln.x, y: ln.bottomY + 14 + i * 11, class: "lt-sld-rating" },
1137
+ l
1138
+ )
1139
+ );
1140
+ });
1141
+ }
1142
+ return pieces;
1143
+ }
1144
+ if (ln.nodeType === "bus_tie") {
1145
+ pieces.push(
1146
+ chunkHDKDQAEQ_cjs.text(
1147
+ { x: ln.x, y: ln.topY - 6, class: "lt-sld-rating" },
1148
+ node.label ?? node.id
1149
+ )
1150
+ );
1151
+ return pieces;
1152
+ }
1153
+ const idY = ln.topY - 22;
1154
+ pieces.push(
1155
+ chunkHDKDQAEQ_cjs.text({ x: ln.x, y: idY, class: "lt-sld-id" }, node.label ?? node.id)
1156
+ );
1157
+ const lines = [];
1158
+ if (node.rating) lines.push(node.rating);
1159
+ if (node.voltage) lines.push(node.voltage);
1160
+ if (node.deviceNumber && ln.nodeType === "relay") ;
1161
+ lines.forEach((l, i) => {
1162
+ pieces.push(
1163
+ chunkHDKDQAEQ_cjs.text(
1164
+ { x: ln.x, y: ln.bottomY + 14 + i * 11, class: "lt-sld-rating" },
1165
+ l
1166
+ )
1167
+ );
1168
+ });
1169
+ if ((ln.nodeType === "transformer" || ln.nodeType === "transformer_dy" || ln.nodeType === "transformer_yd" || ln.nodeType === "transformer_yy" || ln.nodeType === "transformer_dd" || ln.nodeType === "autotransformer" || ln.nodeType === "transformer_3winding") && node.nameplate) {
1170
+ const np = node.nameplate;
1171
+ const keys = Object.keys(np);
1172
+ let offset = -12;
1173
+ const x = ln.x + ln.halfWidth + 28;
1174
+ for (const k of keys) {
1175
+ pieces.push(
1176
+ chunkHDKDQAEQ_cjs.text(
1177
+ { x, y: ln.y + offset, class: "lt-sld-nameplate" },
1178
+ `${k}: ${np[k]}`
1179
+ )
1180
+ );
1181
+ offset += 11;
1182
+ }
1183
+ }
1184
+ return pieces;
1185
+ }
1186
+ function renderSLD(ast, config) {
1187
+ const layout = layoutSLD(ast);
1188
+ const t = chunkN7KOXOMX_cjs.resolveIndustrialTheme(config?.theme ?? "default");
1189
+ const titleOffset = ast.title ? 34 : 12;
1190
+ const width = Math.ceil(layout.width);
1191
+ const height = Math.ceil(layout.height + titleOffset);
1192
+ const children = [];
1193
+ children.push(chunkHDKDQAEQ_cjs.title(ast.title ?? "Single-Line Diagram"));
1194
+ children.push(
1195
+ chunkHDKDQAEQ_cjs.desc(
1196
+ `Single-line diagram with ${ast.nodes.length} nodes and ${ast.connections.length} connections`
1197
+ )
1198
+ );
1199
+ children.push(chunkHDKDQAEQ_cjs.el("style", {}, buildCss(t)));
1200
+ children.push(
1201
+ chunkHDKDQAEQ_cjs.defs([
1202
+ chunkHDKDQAEQ_cjs.el(
1203
+ "marker",
1204
+ {
1205
+ id: "lt-sld-arrow",
1206
+ markerWidth: 8,
1207
+ markerHeight: 8,
1208
+ refX: 6,
1209
+ refY: 3,
1210
+ orient: "auto",
1211
+ markerUnits: "strokeWidth"
1212
+ },
1213
+ [chunkHDKDQAEQ_cjs.el("path", { d: "M 0 0 L 6 3 L 0 6 z", fill: t.textMuted })]
1214
+ )
1215
+ ])
1216
+ );
1217
+ if (ast.title) {
1218
+ children.push(
1219
+ chunkHDKDQAEQ_cjs.text({ x: 20, y: 22, class: "lt-sld-title" }, ast.title)
1220
+ );
1221
+ }
1222
+ const inner = [];
1223
+ layout.bands.forEach((b, i) => {
1224
+ inner.push(
1225
+ chunkHDKDQAEQ_cjs.el("rect", {
1226
+ x: 0,
1227
+ y: b.y,
1228
+ width: layout.width,
1229
+ height: b.height,
1230
+ class: i % 2 === 0 ? "lt-sld-band-odd" : "lt-sld-band-even"
1231
+ })
1232
+ );
1233
+ if (b.voltage) {
1234
+ inner.push(
1235
+ chunkHDKDQAEQ_cjs.text(
1236
+ { x: 14, y: b.y + 18, class: "lt-sld-band-label" },
1237
+ b.voltage
1238
+ )
1239
+ );
1240
+ }
1241
+ });
1242
+ for (const e of layout.edges) {
1243
+ inner.push(chunkHDKDQAEQ_cjs.path({ d: e.path, class: "lt-sld-wire" }));
1244
+ if (e.cable) {
1245
+ inner.push(
1246
+ chunkHDKDQAEQ_cjs.text(
1247
+ { x: e.midX + 6, y: e.midY - 2, class: "lt-sld-cable" },
1248
+ e.cable
1249
+ )
1250
+ );
1251
+ }
1252
+ if (e.label) {
1253
+ inner.push(
1254
+ chunkHDKDQAEQ_cjs.text(
1255
+ { x: e.midX + 6, y: e.midY + 10, class: "lt-sld-cable" },
1256
+ e.label
1257
+ )
1258
+ );
1259
+ }
1260
+ }
1261
+ for (const ln of layout.nodes) {
1262
+ if (ln.nodeType === "bus") {
1263
+ const left = ln.busLeft ?? ln.x - 40;
1264
+ const right = ln.busRight ?? ln.x + 40;
1265
+ inner.push(
1266
+ chunkHDKDQAEQ_cjs.el("line", {
1267
+ x1: left,
1268
+ y1: ln.y,
1269
+ x2: right,
1270
+ y2: ln.y,
1271
+ class: "lt-sld-bus",
1272
+ "data-id": ln.node.id
1273
+ })
1274
+ );
1275
+ for (const piece of renderLabels(ln)) inner.push(piece);
1276
+ continue;
1277
+ }
1278
+ const attrs = {
1279
+ transform: `translate(${ln.x}, ${ln.y})`,
1280
+ "data-type": ln.nodeType,
1281
+ "data-id": ln.node.id
1282
+ };
1283
+ inner.push(
1284
+ chunkHDKDQAEQ_cjs.group(attrs, [
1285
+ renderSymbol(
1286
+ ln.nodeType,
1287
+ ln.nodeType === "hub" ? ln.node.label ?? ln.node.id : ln.node.deviceNumber
1288
+ )
1289
+ ])
1290
+ );
1291
+ for (const piece of renderLabels(ln)) inner.push(piece);
1292
+ }
1293
+ const wrap = chunkHDKDQAEQ_cjs.group({ transform: `translate(0, ${titleOffset})` }, inner);
1294
+ children.push(wrap);
1295
+ return chunkHDKDQAEQ_cjs.svgRoot(
1296
+ {
1297
+ class: "lt-sld",
1298
+ role: "img",
1299
+ "aria-labelledby": "lt-sld-title lt-sld-desc",
1300
+ width,
1301
+ height,
1302
+ viewBox: `0 0 ${width} ${height}`
1303
+ },
1304
+ children
1305
+ );
1306
+ }
1307
+
1308
+ // src/diagrams/sld/index.ts
1309
+ var sld = {
1310
+ type: "sld",
1311
+ detect(text2) {
1312
+ const first = text2.trim().split("\n")[0]?.trim().toLowerCase() ?? "";
1313
+ return first.startsWith("sld");
1314
+ },
1315
+ render(text2, config) {
1316
+ const ast = parseSLDDSL(text2);
1317
+ return renderSLD(ast, config);
1318
+ }
1319
+ };
1320
+
1321
+ exports.layoutSLD = layoutSLD;
1322
+ exports.parseSLDDSL = parseSLDDSL;
1323
+ exports.renderSLD = renderSLD;
1324
+ exports.sld = sld;
1325
+ //# sourceMappingURL=chunk-ZX7QKZK2.cjs.map
1326
+ //# sourceMappingURL=chunk-ZX7QKZK2.cjs.map