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,874 @@
1
+ 'use strict';
2
+
3
+ var chunkN7KOXOMX_cjs = require('./chunk-N7KOXOMX.cjs');
4
+ var chunkHDKDQAEQ_cjs = require('./chunk-HDKDQAEQ.cjs');
5
+
6
+ // src/diagrams/logic/parser.ts
7
+ var LogicParseError = class extends Error {
8
+ constructor(message) {
9
+ super(message);
10
+ this.name = "LogicParseError";
11
+ }
12
+ };
13
+ var GATE_TYPES = /* @__PURE__ */ new Set([
14
+ "AND",
15
+ "OR",
16
+ "NOT",
17
+ "NAND",
18
+ "NOR",
19
+ "XOR",
20
+ "XNOR",
21
+ "BUF",
22
+ "TRISTATE_BUF",
23
+ "TRISTATE_INV",
24
+ "OPEN_DRAIN",
25
+ "SCHMITT",
26
+ "DFF",
27
+ "JKFF",
28
+ "SRFF",
29
+ "TFF",
30
+ "LATCH_SR",
31
+ "LATCH_D",
32
+ "MUX",
33
+ "DEMUX",
34
+ "DECODER",
35
+ "ENCODER",
36
+ "COUNTER",
37
+ "SHIFT_REG"
38
+ ]);
39
+ function splitIds(s) {
40
+ return s.split(",").map((x) => x.trim()).filter(Boolean);
41
+ }
42
+ function parseInputList(s) {
43
+ return s.split(",").map((x) => x.trim()).filter(Boolean).map((tok) => {
44
+ const eq = tok.indexOf("=");
45
+ return eq >= 0 ? tok.slice(eq + 1).trim() : tok;
46
+ });
47
+ }
48
+ function parseLogic(text2) {
49
+ const lines = text2.split("\n").map((l) => l.replace(/\r$/, "").trim());
50
+ let title2;
51
+ let style;
52
+ const inputs = [];
53
+ const outputs = [];
54
+ const gates = [];
55
+ const modules = [];
56
+ const moduleStack = [];
57
+ let moduleCounter = 0;
58
+ const explicitOutputFrom = /* @__PURE__ */ new Map();
59
+ for (const rawLine of lines) {
60
+ const line = rawLine.replace(/#.*$/, "").replace(/--.*$/, "").trim();
61
+ if (!line) continue;
62
+ const modOpen = line.match(/^module\s+(?:"([^"]+)"|([a-zA-Z_][\w]*))\s*\{$/);
63
+ if (modOpen) {
64
+ const label = modOpen[1] ?? modOpen[2];
65
+ const id = `mod_${moduleCounter++}`;
66
+ modules.push({ id, label });
67
+ moduleStack.push(id);
68
+ continue;
69
+ }
70
+ if (line === "}") {
71
+ if (moduleStack.length === 0) {
72
+ throw new LogicParseError("Unmatched `}` \u2014 no open module");
73
+ }
74
+ moduleStack.pop();
75
+ continue;
76
+ }
77
+ if (/^logic\b/i.test(line)) {
78
+ const t = line.match(/"([^"]*)"/);
79
+ if (t) title2 = t[1];
80
+ const s = line.match(/style\s*:\s*(ansi|iec)/i);
81
+ if (s) style = s[1].toLowerCase();
82
+ continue;
83
+ }
84
+ const inputMatch = line.match(/^input\s+(.+)$/i);
85
+ if (inputMatch) {
86
+ for (const id of splitIds(inputMatch[1])) {
87
+ const isLow = id.startsWith("~");
88
+ const clean = isLow ? id.slice(1) : id;
89
+ inputs.push({ id: clean, label: clean, isActiveLow: isLow || void 0 });
90
+ }
91
+ continue;
92
+ }
93
+ const outputMatch = line.match(/^output\s+(.+)$/i);
94
+ if (outputMatch) {
95
+ for (const id of splitIds(outputMatch[1])) {
96
+ outputs.push({ id, label: id, from: id });
97
+ }
98
+ continue;
99
+ }
100
+ const assignMatch = line.match(/^([a-zA-Z_][\w]*)\s*<-\s*([a-zA-Z_][\w]*)$/);
101
+ if (assignMatch) {
102
+ explicitOutputFrom.set(assignMatch[1], assignMatch[2]);
103
+ continue;
104
+ }
105
+ const gateMatch = line.match(/^([a-zA-Z_][\w]*)\s*=\s*([A-Za-z_][\w]*)\s*\(([^)]*)\)$/);
106
+ if (gateMatch) {
107
+ const id = gateMatch[1];
108
+ const rawType = gateMatch[2].toUpperCase();
109
+ if (!GATE_TYPES.has(rawType)) {
110
+ throw new LogicParseError(`Unknown gate type: ${rawType}`);
111
+ }
112
+ const gInputs = parseInputList(gateMatch[3]);
113
+ const moduleId = moduleStack[moduleStack.length - 1];
114
+ gates.push({ id, gateType: rawType, inputs: gInputs, moduleId });
115
+ continue;
116
+ }
117
+ }
118
+ if (moduleStack.length > 0) {
119
+ throw new LogicParseError(`Unclosed module (${moduleStack.length} open)`);
120
+ }
121
+ for (const out of outputs) {
122
+ const mapped = explicitOutputFrom.get(out.id);
123
+ if (mapped) out.from = mapped;
124
+ else if (gates.some((g) => g.id === out.id)) out.from = out.id;
125
+ }
126
+ const known = /* @__PURE__ */ new Set([
127
+ ...inputs.map((i) => i.id),
128
+ ...gates.map((g) => g.id)
129
+ ]);
130
+ for (const g of gates) {
131
+ for (const inp of g.inputs) {
132
+ const clean = inp.startsWith("~") ? inp.slice(1) : inp;
133
+ if (!known.has(clean)) {
134
+ throw new LogicParseError(`Unknown signal "${clean}" in gate ${g.id}`);
135
+ }
136
+ }
137
+ }
138
+ return {
139
+ type: "logic",
140
+ title: title2,
141
+ style: style ?? "ansi",
142
+ inputs,
143
+ outputs,
144
+ gates,
145
+ modules: modules.length > 0 ? modules : void 0
146
+ };
147
+ }
148
+
149
+ // src/diagrams/logic/symbols.ts
150
+ function combPins(nInputs, _width, leftX) {
151
+ const pins = [];
152
+ if (nInputs === 1) {
153
+ pins.push({ id: "in1", x: leftX, y: 30 });
154
+ } else if (nInputs === 2) {
155
+ pins.push({ id: "in1", x: leftX, y: 15 });
156
+ pins.push({ id: "in2", x: leftX, y: 45 });
157
+ } else {
158
+ const step = 50 / (nInputs - 1);
159
+ for (let i = 0; i < nInputs; i++) {
160
+ pins.push({ id: `in${i + 1}`, x: leftX, y: 5 + step * i });
161
+ }
162
+ }
163
+ return pins;
164
+ }
165
+ function getGateGeometry(gateType, inputCount) {
166
+ switch (gateType) {
167
+ case "AND":
168
+ case "NAND": {
169
+ const bubble = gateType === "NAND";
170
+ return {
171
+ width: bubble ? 90 : 80,
172
+ height: 60,
173
+ inputPins: combPins(inputCount, 80, 20).map((p) => ({ ...p, x: 20 })),
174
+ outputPins: [{ id: "out", x: bubble ? 90 : 80, y: 30, bubble }],
175
+ ansiPath: "M 20,60 L 20,0 Q 80,0 80,30 Q 80,60 20,60 Z",
176
+ outputBubble: bubble,
177
+ iecLabel: "&"
178
+ };
179
+ }
180
+ case "OR":
181
+ case "NOR": {
182
+ const bubble = gateType === "NOR";
183
+ return {
184
+ width: bubble ? 80 : 70,
185
+ height: 60,
186
+ inputPins: combPins(inputCount, 80, 18).map((p) => ({ ...p, x: 18 })),
187
+ outputPins: [{ id: "out", x: bubble ? 80 : 70, y: 30, bubble }],
188
+ ansiPath: "M 15,60 Q 10,30 15,0 Q 30,15 70,30 Q 30,45 15,60 Z",
189
+ outputBubble: bubble,
190
+ iecLabel: "\u22651"
191
+ };
192
+ }
193
+ case "XOR":
194
+ case "XNOR": {
195
+ const bubble = gateType === "XNOR";
196
+ return {
197
+ width: bubble ? 80 : 70,
198
+ height: 60,
199
+ inputPins: combPins(inputCount, 80, 12).map((p) => ({ ...p, x: 12 })),
200
+ outputPins: [{ id: "out", x: bubble ? 80 : 70, y: 30, bubble }],
201
+ ansiPath: "M 15,60 Q 10,30 15,0 Q 30,15 70,30 Q 30,45 15,60 Z M 8,60 Q 3,30 8,0",
202
+ outputBubble: bubble,
203
+ iecLabel: "=1"
204
+ };
205
+ }
206
+ case "NOT": {
207
+ return {
208
+ width: 70,
209
+ height: 60,
210
+ inputPins: [{ id: "in1", x: 10, y: 30 }],
211
+ outputPins: [{ id: "out", x: 70, y: 30, bubble: true }],
212
+ ansiPath: "M 10,55 L 60,30 L 10,5 Z",
213
+ outputBubble: true,
214
+ iecLabel: "1"
215
+ };
216
+ }
217
+ case "BUF":
218
+ case "SCHMITT": {
219
+ return {
220
+ width: 60,
221
+ height: 60,
222
+ inputPins: [{ id: "in1", x: 10, y: 30 }],
223
+ outputPins: [{ id: "out", x: 60, y: 30 }],
224
+ ansiPath: "M 10,55 L 60,30 L 10,5 Z",
225
+ iecLabel: "1"
226
+ };
227
+ }
228
+ case "TRISTATE_BUF":
229
+ case "TRISTATE_INV":
230
+ case "OPEN_DRAIN": {
231
+ const bubble = gateType === "TRISTATE_INV";
232
+ return {
233
+ width: bubble ? 70 : 60,
234
+ height: 70,
235
+ inputPins: [
236
+ { id: "in1", x: 10, y: 30 },
237
+ { id: "en", x: 35, y: 65, label: "EN" }
238
+ ],
239
+ outputPins: [{ id: "out", x: bubble ? 70 : 60, y: 30, bubble }],
240
+ ansiPath: "M 10,55 L 60,30 L 10,5 Z",
241
+ outputBubble: bubble,
242
+ iecLabel: "1"
243
+ };
244
+ }
245
+ case "DFF": {
246
+ return {
247
+ width: 60,
248
+ height: 80,
249
+ inputPins: [
250
+ { id: "D", x: 0, y: 20, label: "D" },
251
+ { id: "CLK", x: 0, y: 50, label: "" }
252
+ ],
253
+ outputPins: [
254
+ { id: "Q", x: 60, y: 20, label: "Q" },
255
+ { id: "Qn", x: 60, y: 60, label: "Q\u0304", bubble: true }
256
+ ],
257
+ ansiPath: "M 0,0 H 60 V 80 H 0 Z",
258
+ clockPin: "CLK",
259
+ iecLabel: "DFF"
260
+ };
261
+ }
262
+ case "JKFF": {
263
+ return {
264
+ width: 60,
265
+ height: 80,
266
+ inputPins: [
267
+ { id: "J", x: 0, y: 15, label: "J" },
268
+ { id: "CLK", x: 0, y: 40 },
269
+ { id: "K", x: 0, y: 65, label: "K" }
270
+ ],
271
+ outputPins: [
272
+ { id: "Q", x: 60, y: 20, label: "Q" },
273
+ { id: "Qn", x: 60, y: 60, label: "Q\u0304", bubble: true }
274
+ ],
275
+ ansiPath: "M 0,0 H 60 V 80 H 0 Z",
276
+ clockPin: "CLK",
277
+ iecLabel: "JK"
278
+ };
279
+ }
280
+ case "SRFF":
281
+ case "LATCH_SR": {
282
+ return {
283
+ width: 60,
284
+ height: 80,
285
+ inputPins: [
286
+ { id: "S", x: 0, y: 20, label: "S" },
287
+ { id: "R", x: 0, y: 60, label: "R" }
288
+ ],
289
+ outputPins: [
290
+ { id: "Q", x: 60, y: 20, label: "Q" },
291
+ { id: "Qn", x: 60, y: 60, label: "Q\u0304", bubble: true }
292
+ ],
293
+ ansiPath: "M 0,0 H 60 V 80 H 0 Z",
294
+ iecLabel: "SR"
295
+ };
296
+ }
297
+ case "TFF": {
298
+ return {
299
+ width: 60,
300
+ height: 80,
301
+ inputPins: [
302
+ { id: "T", x: 0, y: 20, label: "T" },
303
+ { id: "CLK", x: 0, y: 50 }
304
+ ],
305
+ outputPins: [
306
+ { id: "Q", x: 60, y: 20, label: "Q" },
307
+ { id: "Qn", x: 60, y: 60, label: "Q\u0304", bubble: true }
308
+ ],
309
+ ansiPath: "M 0,0 H 60 V 80 H 0 Z",
310
+ clockPin: "CLK",
311
+ iecLabel: "T"
312
+ };
313
+ }
314
+ case "LATCH_D": {
315
+ return {
316
+ width: 60,
317
+ height: 80,
318
+ inputPins: [
319
+ { id: "D", x: 0, y: 20, label: "D" },
320
+ { id: "E", x: 0, y: 60, label: "E" }
321
+ ],
322
+ outputPins: [
323
+ { id: "Q", x: 60, y: 20, label: "Q" },
324
+ { id: "Qn", x: 60, y: 60, label: "Q\u0304", bubble: true }
325
+ ],
326
+ ansiPath: "M 0,0 H 60 V 80 H 0 Z",
327
+ iecLabel: "D"
328
+ };
329
+ }
330
+ default: {
331
+ const ins = Math.max(inputCount, 2);
332
+ const inputPins = combPins(ins, 100, 0).map((p, i) => ({
333
+ ...p,
334
+ x: 0,
335
+ label: `I${i}`
336
+ }));
337
+ return {
338
+ width: 100,
339
+ height: 80,
340
+ inputPins,
341
+ outputPins: [{ id: "out", x: 100, y: 40 }],
342
+ ansiPath: "M 0,0 H 100 V 80 H 0 Z",
343
+ iecLabel: gateType
344
+ };
345
+ }
346
+ }
347
+ }
348
+
349
+ // src/diagrams/logic/layout.ts
350
+ var LAYER_GAP = 80;
351
+ var ROW_GAP = 40;
352
+ var PORT_SIZE = 40;
353
+ var PORT_H = 30;
354
+ function layoutLogic(ast) {
355
+ const layerOf = /* @__PURE__ */ new Map();
356
+ for (const inp of ast.inputs) layerOf.set(inp.id, 0);
357
+ const pending = new Set(ast.gates.map((g) => g.id));
358
+ let safety = 0;
359
+ while (pending.size > 0 && safety++ < 1e3) {
360
+ for (const g of ast.gates) {
361
+ if (!pending.has(g.id)) continue;
362
+ let maxDep = -1;
363
+ let ready = true;
364
+ for (const inp of g.inputs) {
365
+ const clean = inp.startsWith("~") ? inp.slice(1) : inp;
366
+ const l = layerOf.get(clean);
367
+ if (l === void 0) {
368
+ ready = false;
369
+ break;
370
+ }
371
+ if (l > maxDep) maxDep = l;
372
+ }
373
+ if (ready) {
374
+ layerOf.set(g.id, maxDep + 1);
375
+ pending.delete(g.id);
376
+ }
377
+ }
378
+ }
379
+ if (pending.size > 0) {
380
+ for (const id of pending) layerOf.set(id, 1);
381
+ }
382
+ const outputLayer = Math.max(0, ...Array.from(layerOf.values())) + 1;
383
+ const outTermId = (o) => `$out$${o.id}`;
384
+ const portOutputs = ast.outputs.map((o) => ({
385
+ ...o,
386
+ termId: outTermId(o),
387
+ source: o.from
388
+ }));
389
+ for (const o of portOutputs) layerOf.set(o.termId, outputLayer);
390
+ const layers = /* @__PURE__ */ new Map();
391
+ const addToLayer = (id, layer) => {
392
+ if (!layers.has(layer)) layers.set(layer, []);
393
+ layers.get(layer).push(id);
394
+ };
395
+ for (const i of ast.inputs) addToLayer(i.id, 0);
396
+ for (const g of ast.gates) addToLayer(g.id, layerOf.get(g.id));
397
+ for (const o of portOutputs) addToLayer(o.termId, outputLayer);
398
+ const gateGeoms = /* @__PURE__ */ new Map();
399
+ for (const g of ast.gates) {
400
+ gateGeoms.set(g.id, getGateGeometry(g.gateType, g.inputs.length));
401
+ }
402
+ const nodes = [];
403
+ const sortedLayers = Array.from(layers.keys()).sort((a, b) => a - b);
404
+ const layerWidth = /* @__PURE__ */ new Map();
405
+ for (const [layerIdx, ids] of layers) {
406
+ let maxW = 60;
407
+ for (const id of ids) {
408
+ const g = gateGeoms.get(id);
409
+ if (g && g.width > maxW) maxW = g.width;
410
+ if (!g && layerIdx === 0) maxW = Math.max(maxW, PORT_SIZE);
411
+ if (!g && layerIdx === outputLayer) maxW = Math.max(maxW, PORT_SIZE);
412
+ }
413
+ layerWidth.set(layerIdx, maxW);
414
+ }
415
+ let cursorX = 20;
416
+ const layerStartMap = /* @__PURE__ */ new Map();
417
+ for (const layerIdx of sortedLayers) {
418
+ layerStartMap.set(layerIdx, cursorX);
419
+ cursorX += (layerWidth.get(layerIdx) ?? 60) + LAYER_GAP;
420
+ }
421
+ const totalW = cursorX;
422
+ const heightOf = (id) => {
423
+ const g = gateGeoms.get(id);
424
+ if (g) return g.height;
425
+ return PORT_H;
426
+ };
427
+ let maxColH = 0;
428
+ for (const ids of layers.values()) {
429
+ const total = ids.reduce((s, id) => s + heightOf(id), 0) + (ids.length - 1) * ROW_GAP;
430
+ if (total > maxColH) maxColH = total;
431
+ }
432
+ const totalH = maxColH + 80;
433
+ const nodeInfo = /* @__PURE__ */ new Map();
434
+ for (const [layerIdx, ids] of layers) {
435
+ const xStart = layerStartMap.get(layerIdx);
436
+ const total = ids.reduce((s, id) => s + heightOf(id), 0) + (ids.length - 1) * ROW_GAP;
437
+ let y = 40 + (maxColH - total) / 2;
438
+ for (const id of ids) {
439
+ const h = heightOf(id);
440
+ const g = gateGeoms.get(id);
441
+ let node;
442
+ if (layerIdx === 0) {
443
+ const inp = ast.inputs.find((i) => i.id === id);
444
+ node = {
445
+ id,
446
+ kind: "input",
447
+ x: xStart,
448
+ y,
449
+ layer: 0,
450
+ label: inp.label,
451
+ isActiveLow: inp.isActiveLow
452
+ };
453
+ } else if (layerIdx === outputLayer && !g && id.startsWith("$out$")) {
454
+ const out = portOutputs.find((o) => o.termId === id);
455
+ node = {
456
+ id,
457
+ kind: "output",
458
+ x: xStart,
459
+ y,
460
+ layer: outputLayer,
461
+ label: out.label,
462
+ isActiveLow: out.isActiveLow
463
+ };
464
+ } else {
465
+ node = {
466
+ id,
467
+ kind: "gate",
468
+ x: xStart,
469
+ y,
470
+ layer: layerIdx,
471
+ geometry: g,
472
+ gateType: ast.gates.find((gg) => gg.id === id).gateType,
473
+ label: id
474
+ };
475
+ }
476
+ nodes.push(node);
477
+ nodeInfo.set(id, node);
478
+ y += h + ROW_GAP;
479
+ }
480
+ }
481
+ const wires = [];
482
+ const getSourcePoint = (id) => {
483
+ const n = nodeInfo.get(id);
484
+ if (!n) return null;
485
+ if (n.kind === "input") return { x: n.x + PORT_SIZE, y: n.y + PORT_H / 2 };
486
+ if (n.kind === "gate" && n.geometry) {
487
+ const out = n.geometry.outputPins[0];
488
+ return { x: n.x + out.x, y: n.y + out.y };
489
+ }
490
+ return null;
491
+ };
492
+ for (const g of ast.gates) {
493
+ const target = nodeInfo.get(g.id);
494
+ if (!target || !target.geometry) continue;
495
+ g.inputs.forEach((rawInp, idx) => {
496
+ const isLow = rawInp.startsWith("~");
497
+ const srcId = isLow ? rawInp.slice(1) : rawInp;
498
+ const src = getSourcePoint(srcId);
499
+ if (!src) return;
500
+ const pin = target.geometry.inputPins[idx];
501
+ if (!pin) return;
502
+ const toX = target.x + pin.x;
503
+ const toY = target.y + pin.y;
504
+ const midX = (src.x + toX) / 2;
505
+ const path2 = `M ${src.x},${src.y} L ${midX},${src.y} L ${midX},${toY} L ${toX},${toY}`;
506
+ wires.push({
507
+ fromNode: srcId,
508
+ fromX: src.x,
509
+ fromY: src.y,
510
+ toNode: g.id,
511
+ toX,
512
+ toY,
513
+ isActiveLow: isLow,
514
+ path: path2
515
+ });
516
+ });
517
+ }
518
+ for (const o of portOutputs) {
519
+ const src = getSourcePoint(o.source);
520
+ const target = nodeInfo.get(o.termId);
521
+ if (!src || !target || target.kind !== "output") continue;
522
+ const toX = target.x;
523
+ const toY = target.y + PORT_H / 2;
524
+ let path2;
525
+ if (Math.abs(src.y - toY) < 0.5) {
526
+ path2 = `M ${src.x},${src.y} L ${toX},${toY}`;
527
+ } else {
528
+ const midX = (src.x + toX) / 2;
529
+ path2 = `M ${src.x},${src.y} L ${midX},${src.y} L ${midX},${toY} L ${toX},${toY}`;
530
+ }
531
+ wires.push({
532
+ fromNode: o.source,
533
+ fromX: src.x,
534
+ fromY: src.y,
535
+ toNode: o.termId,
536
+ toX,
537
+ toY,
538
+ path: path2
539
+ });
540
+ }
541
+ const modules = [];
542
+ if (ast.modules && ast.modules.length > 0) {
543
+ const PAD = 14;
544
+ for (const mod of ast.modules) {
545
+ const memberIds = new Set(
546
+ ast.gates.filter((g) => g.moduleId === mod.id).map((g) => g.id)
547
+ );
548
+ if (memberIds.size === 0) continue;
549
+ let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
550
+ for (const n of nodes) {
551
+ if (!memberIds.has(n.id)) continue;
552
+ const w = n.geometry?.width ?? 60;
553
+ const h = n.geometry?.height ?? 60;
554
+ if (n.x < minX) minX = n.x;
555
+ if (n.y < minY) minY = n.y;
556
+ if (n.x + w > maxX) maxX = n.x + w;
557
+ if (n.y + h > maxY) maxY = n.y + h;
558
+ }
559
+ if (!isFinite(minX)) continue;
560
+ modules.push({
561
+ id: mod.id,
562
+ label: mod.label,
563
+ x: minX - PAD,
564
+ y: minY - PAD - 4,
565
+ width: maxX - minX + PAD * 2,
566
+ height: maxY - minY + PAD * 2 + 4
567
+ });
568
+ }
569
+ }
570
+ return { width: totalW, height: totalH, nodes, wires, modules };
571
+ }
572
+
573
+ // src/diagrams/logic/renderer.ts
574
+ var PORT_SIZE2 = 40;
575
+ var PORT_H2 = 30;
576
+ function renderGateBody(n, style) {
577
+ const out = [];
578
+ if (!n.geometry) return out;
579
+ const g = n.geometry;
580
+ if (style === "iec") {
581
+ out.push(
582
+ chunkHDKDQAEQ_cjs.el("rect", {
583
+ x: 0,
584
+ y: 0,
585
+ width: g.width,
586
+ height: g.height,
587
+ class: "schematex-logic-gate-body"
588
+ })
589
+ );
590
+ if (g.iecLabel) {
591
+ out.push(
592
+ chunkHDKDQAEQ_cjs.text(
593
+ {
594
+ x: g.width / 2,
595
+ y: g.height / 2 + 4,
596
+ class: "schematex-logic-gate-iec-label",
597
+ "text-anchor": "middle"
598
+ },
599
+ g.iecLabel
600
+ )
601
+ );
602
+ }
603
+ } else {
604
+ out.push(
605
+ chunkHDKDQAEQ_cjs.el("path", { d: g.ansiPath, class: "schematex-logic-gate-body" })
606
+ );
607
+ }
608
+ if (g.outputBubble) {
609
+ const op = g.outputPins[0];
610
+ out.push(
611
+ chunkHDKDQAEQ_cjs.circle({
612
+ cx: op.x - 4,
613
+ cy: op.y,
614
+ r: 4,
615
+ class: "schematex-logic-bubble"
616
+ })
617
+ );
618
+ }
619
+ if (g.clockPin) {
620
+ const cp = g.inputPins.find((p) => p.id === g.clockPin);
621
+ if (cp) {
622
+ out.push(
623
+ chunkHDKDQAEQ_cjs.polygon({
624
+ points: `${cp.x},${cp.y - 5} ${cp.x + 8},${cp.y} ${cp.x},${cp.y + 5}`,
625
+ class: "schematex-logic-clock-tri"
626
+ })
627
+ );
628
+ }
629
+ }
630
+ for (const op of g.outputPins) {
631
+ if (op.bubble && op.id !== "out") {
632
+ out.push(
633
+ chunkHDKDQAEQ_cjs.circle({
634
+ cx: op.x + 4,
635
+ cy: op.y,
636
+ r: 4,
637
+ class: "schematex-logic-bubble"
638
+ })
639
+ );
640
+ }
641
+ }
642
+ for (const pin of g.inputPins) {
643
+ if (pin.label && pin.id !== g.clockPin) {
644
+ out.push(
645
+ chunkHDKDQAEQ_cjs.text(
646
+ {
647
+ x: pin.x + 5,
648
+ y: pin.y + 3,
649
+ class: "schematex-logic-pin-label"
650
+ },
651
+ pin.label
652
+ )
653
+ );
654
+ }
655
+ }
656
+ for (const pin of g.outputPins) {
657
+ if (pin.label) {
658
+ out.push(
659
+ chunkHDKDQAEQ_cjs.text(
660
+ {
661
+ x: pin.x - 6,
662
+ y: pin.y + 3,
663
+ class: "schematex-logic-pin-label",
664
+ "text-anchor": "end"
665
+ },
666
+ pin.label
667
+ )
668
+ );
669
+ }
670
+ }
671
+ if (style === "ansi" && g.iecLabel && g.height >= 60) {
672
+ const labelX = g.width / 2;
673
+ const labelY = g.height + 14;
674
+ out.push(
675
+ chunkHDKDQAEQ_cjs.text(
676
+ {
677
+ x: labelX,
678
+ y: labelY,
679
+ class: "schematex-logic-gate-type",
680
+ "text-anchor": "middle"
681
+ },
682
+ n.gateType ?? ""
683
+ )
684
+ );
685
+ }
686
+ return out;
687
+ }
688
+ function renderLogic(ast, config) {
689
+ const style = ast.style ?? "ansi";
690
+ const layout = layoutLogic(ast);
691
+ const { width, height } = layout;
692
+ const t = chunkN7KOXOMX_cjs.resolveIndustrialTheme(config?.theme ?? "default");
693
+ const gateSvgs = [];
694
+ const portSvgs = [];
695
+ const moduleSvgs = [];
696
+ for (const m of layout.modules) {
697
+ moduleSvgs.push(
698
+ chunkHDKDQAEQ_cjs.group({ "data-module-id": m.id }, [
699
+ chunkHDKDQAEQ_cjs.el("rect", {
700
+ x: m.x,
701
+ y: m.y,
702
+ width: m.width,
703
+ height: m.height,
704
+ rx: 6,
705
+ class: "schematex-logic-module"
706
+ }),
707
+ chunkHDKDQAEQ_cjs.text(
708
+ {
709
+ x: m.x + 10,
710
+ y: m.y + 14,
711
+ class: "schematex-logic-module-label"
712
+ },
713
+ m.label
714
+ )
715
+ ])
716
+ );
717
+ }
718
+ for (const n of layout.nodes) {
719
+ if (n.kind === "gate") {
720
+ gateSvgs.push(
721
+ chunkHDKDQAEQ_cjs.group(
722
+ {
723
+ transform: `translate(${n.x}, ${n.y})`,
724
+ "data-gate-id": n.id,
725
+ "data-gate-type": n.gateType ?? ""
726
+ },
727
+ renderGateBody(n, style)
728
+ )
729
+ );
730
+ } else if (n.kind === "input") {
731
+ const cy = PORT_H2 / 2;
732
+ portSvgs.push(
733
+ chunkHDKDQAEQ_cjs.group({ transform: `translate(${n.x}, ${n.y})`, "data-port": "input" }, [
734
+ chunkHDKDQAEQ_cjs.text(
735
+ {
736
+ x: 0,
737
+ y: cy + 4,
738
+ "text-anchor": "start",
739
+ class: "schematex-logic-port-label"
740
+ },
741
+ n.label
742
+ ),
743
+ chunkHDKDQAEQ_cjs.el("line", {
744
+ x1: PORT_SIZE2 - 12,
745
+ y1: cy,
746
+ x2: n.isActiveLow ? PORT_SIZE2 - 8 : PORT_SIZE2,
747
+ y2: cy,
748
+ class: "schematex-logic-wire"
749
+ }),
750
+ n.isActiveLow ? chunkHDKDQAEQ_cjs.circle({
751
+ cx: PORT_SIZE2 - 4,
752
+ cy,
753
+ r: 4,
754
+ class: "schematex-logic-bubble"
755
+ }) : ""
756
+ ])
757
+ );
758
+ } else if (n.kind === "output") {
759
+ const cy = PORT_H2 / 2;
760
+ portSvgs.push(
761
+ chunkHDKDQAEQ_cjs.group({ transform: `translate(${n.x}, ${n.y})`, "data-port": "output" }, [
762
+ chunkHDKDQAEQ_cjs.el("line", {
763
+ x1: 0,
764
+ y1: cy,
765
+ x2: 12,
766
+ y2: cy,
767
+ class: "schematex-logic-wire"
768
+ }),
769
+ chunkHDKDQAEQ_cjs.text(
770
+ {
771
+ x: 16,
772
+ y: cy + 4,
773
+ "text-anchor": "start",
774
+ class: "schematex-logic-port-label"
775
+ },
776
+ n.label
777
+ )
778
+ ])
779
+ );
780
+ }
781
+ }
782
+ const wireSvgs = layout.wires.map((w) => {
783
+ const extras = [];
784
+ if (w.isActiveLow) {
785
+ extras.push(
786
+ chunkHDKDQAEQ_cjs.circle({
787
+ cx: w.toX - 4,
788
+ cy: w.toY,
789
+ r: 4,
790
+ class: "schematex-logic-bubble"
791
+ })
792
+ );
793
+ }
794
+ return [
795
+ chunkHDKDQAEQ_cjs.path({
796
+ d: w.path,
797
+ class: "schematex-logic-wire",
798
+ "data-from": w.fromNode,
799
+ "data-to": w.toNode
800
+ }),
801
+ ...extras
802
+ ].join("");
803
+ });
804
+ const css = `
805
+ .schematex-logic { background: ${t.bg}; font-family: system-ui, -apple-system, sans-serif; }
806
+ .schematex-logic-gate-body { fill: none; stroke: ${t.strokeHeavy}; stroke-width: 1.75; stroke-linejoin: round; }
807
+ .schematex-logic-bubble { fill: ${t.bg}; stroke: ${t.strokeHeavy}; stroke-width: 1.5; }
808
+ .schematex-logic-clock-tri { fill: none; stroke: ${t.strokeHeavy}; stroke-width: 1.5; stroke-linejoin: round; }
809
+ .schematex-logic-wire { stroke: ${t.strokeHeavy}; stroke-width: 1.5; fill: none; stroke-linecap: square; }
810
+ .schematex-logic-port-label { font: 13px system-ui, sans-serif; fill: ${t.text}; }
811
+ .schematex-logic-pin-label { font: 9px sans-serif; fill: ${t.stroke}; }
812
+ .schematex-logic-gate-type { font: 10px sans-serif; fill: ${t.textMuted}; }
813
+ .schematex-logic-gate-iec-label { font: bold 13px sans-serif; fill: ${t.text}; }
814
+ .schematex-logic-title { font: bold 14px sans-serif; fill: ${t.text}; }
815
+ .schematex-logic-module { fill: none; stroke: ${t.textMuted}; stroke-width: 1.25; stroke-dasharray: 6 4; }
816
+ .schematex-logic-module-label { font: 11px sans-serif; fill: ${t.textMuted}; font-style: italic; }
817
+ `.trim();
818
+ const titleSvg = ast.title ? chunkHDKDQAEQ_cjs.text(
819
+ {
820
+ x: width / 2,
821
+ y: 18,
822
+ "text-anchor": "middle",
823
+ class: "schematex-logic-title"
824
+ },
825
+ ast.title
826
+ ) : "";
827
+ return chunkHDKDQAEQ_cjs.svgRoot(
828
+ {
829
+ class: "schematex-logic",
830
+ viewBox: `0 0 ${width} ${height + (ast.title ? 20 : 0)}`,
831
+ width,
832
+ height: height + (ast.title ? 20 : 0),
833
+ role: "img",
834
+ "data-diagram-type": "logic"
835
+ },
836
+ [
837
+ chunkHDKDQAEQ_cjs.title(ast.title ?? "Logic Gate Diagram"),
838
+ chunkHDKDQAEQ_cjs.desc(
839
+ `Logic gate diagram with ${ast.gates.length} gates, ${ast.inputs.length} inputs, ${ast.outputs.length} outputs`
840
+ ),
841
+ chunkHDKDQAEQ_cjs.defs([chunkHDKDQAEQ_cjs.el("style", {}, css)]),
842
+ chunkHDKDQAEQ_cjs.group(
843
+ { transform: `translate(0, ${ast.title ? 20 : 0})` },
844
+ [
845
+ chunkHDKDQAEQ_cjs.group({ class: "schematex-logic-modules" }, moduleSvgs),
846
+ chunkHDKDQAEQ_cjs.group({ class: "schematex-logic-wires" }, wireSvgs),
847
+ chunkHDKDQAEQ_cjs.group({ class: "schematex-logic-gates" }, gateSvgs),
848
+ chunkHDKDQAEQ_cjs.group({ class: "schematex-logic-ports" }, portSvgs)
849
+ ]
850
+ ),
851
+ titleSvg
852
+ ]
853
+ );
854
+ }
855
+
856
+ // src/diagrams/logic/index.ts
857
+ var logic = {
858
+ type: "logic",
859
+ detect(text2) {
860
+ const first = text2.trim().split("\n")[0]?.trim().toLowerCase() ?? "";
861
+ return first.startsWith("logic");
862
+ },
863
+ render(text2, config) {
864
+ const ast = parseLogic(text2);
865
+ return renderLogic(ast, config);
866
+ }
867
+ };
868
+
869
+ exports.layoutLogic = layoutLogic;
870
+ exports.logic = logic;
871
+ exports.parseLogic = parseLogic;
872
+ exports.renderLogic = renderLogic;
873
+ //# sourceMappingURL=chunk-BE5HNDA5.cjs.map
874
+ //# sourceMappingURL=chunk-BE5HNDA5.cjs.map