kicad-to-circuit-json 0.0.78 → 0.0.80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +130 -2
- package/dist/index.js +665 -40
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,92 @@
|
|
|
1
|
+
import { AnyCircuitElement } from 'circuit-json';
|
|
1
2
|
import { CircuitJsonUtilObjects } from '@tscircuit/circuit-json-util';
|
|
2
3
|
import { KicadPcb, KicadSch } from 'kicadts';
|
|
3
4
|
import { Matrix } from 'transformation-matrix';
|
|
4
5
|
|
|
6
|
+
interface KicadSymbolLibPinAlternate {
|
|
7
|
+
name: string;
|
|
8
|
+
electricalType?: string;
|
|
9
|
+
graphicStyle?: string;
|
|
10
|
+
}
|
|
11
|
+
interface KicadSymbolLibPin {
|
|
12
|
+
name: string;
|
|
13
|
+
number: string;
|
|
14
|
+
electricalType?: string;
|
|
15
|
+
graphicStyle?: string;
|
|
16
|
+
at?: {
|
|
17
|
+
x: number;
|
|
18
|
+
y: number;
|
|
19
|
+
angle: number;
|
|
20
|
+
};
|
|
21
|
+
length?: number;
|
|
22
|
+
hidden?: boolean;
|
|
23
|
+
alternates?: KicadSymbolLibPinAlternate[];
|
|
24
|
+
}
|
|
25
|
+
interface KicadSymbolLibPoint {
|
|
26
|
+
x: number;
|
|
27
|
+
y: number;
|
|
28
|
+
}
|
|
29
|
+
interface KicadSymbolLibStroke {
|
|
30
|
+
width?: number;
|
|
31
|
+
type?: string;
|
|
32
|
+
}
|
|
33
|
+
interface KicadSymbolLibFill {
|
|
34
|
+
type?: string;
|
|
35
|
+
}
|
|
36
|
+
interface KicadSymbolLibPolyline {
|
|
37
|
+
points: KicadSymbolLibPoint[];
|
|
38
|
+
stroke?: KicadSymbolLibStroke;
|
|
39
|
+
fill?: KicadSymbolLibFill;
|
|
40
|
+
}
|
|
41
|
+
interface KicadSymbolLibRectangle {
|
|
42
|
+
start: KicadSymbolLibPoint;
|
|
43
|
+
end: KicadSymbolLibPoint;
|
|
44
|
+
stroke?: KicadSymbolLibStroke;
|
|
45
|
+
fill?: KicadSymbolLibFill;
|
|
46
|
+
}
|
|
47
|
+
interface KicadSymbolLibCircle {
|
|
48
|
+
center: KicadSymbolLibPoint;
|
|
49
|
+
radius: number;
|
|
50
|
+
stroke?: KicadSymbolLibStroke;
|
|
51
|
+
fill?: KicadSymbolLibFill;
|
|
52
|
+
}
|
|
53
|
+
interface KicadSymbolLibArc {
|
|
54
|
+
start: KicadSymbolLibPoint;
|
|
55
|
+
mid: KicadSymbolLibPoint;
|
|
56
|
+
end: KicadSymbolLibPoint;
|
|
57
|
+
stroke?: KicadSymbolLibStroke;
|
|
58
|
+
}
|
|
59
|
+
interface KicadSymbolLibText {
|
|
60
|
+
text: string;
|
|
61
|
+
at: {
|
|
62
|
+
x: number;
|
|
63
|
+
y: number;
|
|
64
|
+
angle: number;
|
|
65
|
+
};
|
|
66
|
+
fontSize?: number;
|
|
67
|
+
}
|
|
68
|
+
interface KicadSymbolLibSymbol {
|
|
69
|
+
name: string;
|
|
70
|
+
properties: Record<string, string>;
|
|
71
|
+
pins: KicadSymbolLibPin[];
|
|
72
|
+
polylines: KicadSymbolLibPolyline[];
|
|
73
|
+
rectangles: KicadSymbolLibRectangle[];
|
|
74
|
+
circles: KicadSymbolLibCircle[];
|
|
75
|
+
arcs: KicadSymbolLibArc[];
|
|
76
|
+
texts: KicadSymbolLibText[];
|
|
77
|
+
subSymbols: KicadSymbolLibSymbol[];
|
|
78
|
+
}
|
|
79
|
+
interface KicadSymbolLib {
|
|
80
|
+
version?: string;
|
|
81
|
+
generator?: string;
|
|
82
|
+
generatorVersion?: string;
|
|
83
|
+
symbols: KicadSymbolLibSymbol[];
|
|
84
|
+
}
|
|
5
85
|
interface ConverterContext {
|
|
6
86
|
db: CircuitJsonUtilObjects;
|
|
7
87
|
kicadPcb?: KicadPcb;
|
|
8
88
|
kicadSch?: KicadSch;
|
|
89
|
+
kicadSymbolLib?: KicadSymbolLib;
|
|
9
90
|
k2cMatSch?: Matrix;
|
|
10
91
|
k2cMatPcb?: Matrix;
|
|
11
92
|
netNumToName?: Map<number, string>;
|
|
@@ -56,7 +137,7 @@ declare class KicadToCircuitJsonConverter {
|
|
|
56
137
|
initializePipeline(): void;
|
|
57
138
|
step(): boolean;
|
|
58
139
|
runUntilFinished(): void;
|
|
59
|
-
getOutput():
|
|
140
|
+
getOutput(): AnyCircuitElement[];
|
|
60
141
|
getOutputString(): string;
|
|
61
142
|
getWarnings(): string[];
|
|
62
143
|
getStats(): {
|
|
@@ -265,4 +346,51 @@ declare class CollectSourceTracesStage extends ConverterStage {
|
|
|
265
346
|
private createSourceNet;
|
|
266
347
|
}
|
|
267
348
|
|
|
268
|
-
|
|
349
|
+
/**
|
|
350
|
+
* InitializeSymbolLibraryContextStage prepares shared state for .kicad_sym
|
|
351
|
+
* conversion. Symbol libraries have no schematic placements, so this branch
|
|
352
|
+
* emits source-level Circuit JSON only.
|
|
353
|
+
*/
|
|
354
|
+
declare class InitializeSymbolLibraryContextStage extends ConverterStage {
|
|
355
|
+
step(): boolean;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* CollectSymbolLibrarySymbolsStage converts KiCad symbol-library definitions
|
|
360
|
+
* into source-level Circuit JSON:
|
|
361
|
+
* - source_component for each top-level library symbol
|
|
362
|
+
* - source_port for each physical pin in the symbol definition
|
|
363
|
+
* - schematic_component and schematic_port preview geometry for snapshots
|
|
364
|
+
*/
|
|
365
|
+
declare class CollectSymbolLibrarySymbolsStage extends ConverterStage {
|
|
366
|
+
private processedSymbols;
|
|
367
|
+
private previewIndex;
|
|
368
|
+
step(): boolean;
|
|
369
|
+
private processSymbol;
|
|
370
|
+
private getKicadSymbolExportFileName;
|
|
371
|
+
private collectPins;
|
|
372
|
+
private collectPolylines;
|
|
373
|
+
private collectRectangles;
|
|
374
|
+
private collectCircles;
|
|
375
|
+
private collectArcs;
|
|
376
|
+
private collectTexts;
|
|
377
|
+
private createSchematicPreview;
|
|
378
|
+
private getPreviewCenter;
|
|
379
|
+
private getPinBounds;
|
|
380
|
+
private getPreviewScale;
|
|
381
|
+
private createSchematicPrimitives;
|
|
382
|
+
private createPolylinePrimitives;
|
|
383
|
+
private toSchematicPoint;
|
|
384
|
+
private toStrokeWidth;
|
|
385
|
+
private isFilled;
|
|
386
|
+
private getArcGeometry;
|
|
387
|
+
private getAngleDegrees;
|
|
388
|
+
private getManufacturerPartNumber;
|
|
389
|
+
private createSourceComponentData;
|
|
390
|
+
private inferFtype;
|
|
391
|
+
private getPortName;
|
|
392
|
+
private getSourcePortPinMetadata;
|
|
393
|
+
private getSchematicPortPinMetadata;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
export { CollectFootprintsStage, CollectGraphicsStage, CollectLibrarySymbolsStage, CollectNetsStage, CollectSchematicTracesStage, CollectSourceTracesStage, CollectSymbolLibrarySymbolsStage, CollectTracesStage, CollectViasStage, CollectZonesStage, type ConverterContext, ConverterStage, InitializePcbContextStage, InitializeSchematicContextStage, InitializeSymbolLibraryContextStage, KicadToCircuitJsonConverter };
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,255 @@
|
|
|
2
2
|
import { cju } from "@tscircuit/circuit-json-util";
|
|
3
3
|
import { parseKicadPcb, parseKicadSch } from "kicadts";
|
|
4
4
|
|
|
5
|
+
// lib/parseKicadSymbolLib.ts
|
|
6
|
+
function parseKicadSymbolLib(content) {
|
|
7
|
+
const expressions = parseSExpr(content);
|
|
8
|
+
const root = expressions.find(
|
|
9
|
+
(expr) => isList(expr) && expr[0] === "kicad_symbol_lib"
|
|
10
|
+
);
|
|
11
|
+
if (!root) {
|
|
12
|
+
throw new Error("Expected kicad_symbol_lib root in .kicad_sym file");
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
version: getChildScalar(root, "version"),
|
|
16
|
+
generator: getChildScalar(root, "generator"),
|
|
17
|
+
generatorVersion: getChildScalar(root, "generator_version"),
|
|
18
|
+
symbols: getChildLists(root, "symbol").map(parseSymbol)
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function parseSExpr(content) {
|
|
22
|
+
const tokens = tokenize(content);
|
|
23
|
+
const expressions = [];
|
|
24
|
+
let index = 0;
|
|
25
|
+
function parseList() {
|
|
26
|
+
const list = [];
|
|
27
|
+
index++;
|
|
28
|
+
while (index < tokens.length && tokens[index] !== ")") {
|
|
29
|
+
if (tokens[index] === "(") {
|
|
30
|
+
list.push(parseList());
|
|
31
|
+
} else {
|
|
32
|
+
list.push(tokens[index]);
|
|
33
|
+
index++;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (tokens[index] !== ")") {
|
|
37
|
+
throw new Error("Unterminated S-expression list");
|
|
38
|
+
}
|
|
39
|
+
index++;
|
|
40
|
+
return list;
|
|
41
|
+
}
|
|
42
|
+
while (index < tokens.length) {
|
|
43
|
+
const token = tokens[index];
|
|
44
|
+
if (token === "(") {
|
|
45
|
+
expressions.push(parseList());
|
|
46
|
+
} else if (token === ")") {
|
|
47
|
+
throw new Error("Unexpected ')' in S-expression");
|
|
48
|
+
} else if (token !== void 0) {
|
|
49
|
+
expressions.push(token);
|
|
50
|
+
index++;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return expressions;
|
|
54
|
+
}
|
|
55
|
+
function tokenize(content) {
|
|
56
|
+
const tokens = [];
|
|
57
|
+
let index = 0;
|
|
58
|
+
while (index < content.length) {
|
|
59
|
+
const char = content[index];
|
|
60
|
+
if (/\s/.test(char)) {
|
|
61
|
+
index++;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (char === ";") {
|
|
65
|
+
while (index < content.length && content[index] !== "\n") index++;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (char === "(" || char === ")") {
|
|
69
|
+
tokens.push(char);
|
|
70
|
+
index++;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (char === '"') {
|
|
74
|
+
let value2 = "";
|
|
75
|
+
index++;
|
|
76
|
+
while (index < content.length) {
|
|
77
|
+
const current = content[index];
|
|
78
|
+
if (current === "\\") {
|
|
79
|
+
const next = content[index + 1];
|
|
80
|
+
if (next === void 0) {
|
|
81
|
+
throw new Error("Unterminated escape sequence in quoted string");
|
|
82
|
+
}
|
|
83
|
+
value2 += next;
|
|
84
|
+
index += 2;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (current === '"') {
|
|
88
|
+
index++;
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
value2 += current;
|
|
92
|
+
index++;
|
|
93
|
+
}
|
|
94
|
+
tokens.push(value2);
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
let value = "";
|
|
98
|
+
while (index < content.length && !/\s/.test(content[index]) && content[index] !== "(" && content[index] !== ")") {
|
|
99
|
+
value += content[index];
|
|
100
|
+
index++;
|
|
101
|
+
}
|
|
102
|
+
tokens.push(value);
|
|
103
|
+
}
|
|
104
|
+
return tokens;
|
|
105
|
+
}
|
|
106
|
+
function parseSymbol(expr) {
|
|
107
|
+
const name = getAtom(expr[1]) ?? "";
|
|
108
|
+
const subSymbols = getChildLists(expr, "symbol").map(parseSymbol);
|
|
109
|
+
const directPins = getChildLists(expr, "pin").map(parsePin);
|
|
110
|
+
return {
|
|
111
|
+
name,
|
|
112
|
+
properties: Object.fromEntries(
|
|
113
|
+
getChildLists(expr, "property").flatMap((property) => {
|
|
114
|
+
const key = getAtom(property[1]);
|
|
115
|
+
const value = getAtom(property[2]);
|
|
116
|
+
return key ? [[key, value ?? ""]] : [];
|
|
117
|
+
})
|
|
118
|
+
),
|
|
119
|
+
pins: directPins,
|
|
120
|
+
polylines: getChildLists(expr, "polyline").map(parsePolyline),
|
|
121
|
+
rectangles: getChildLists(expr, "rectangle").map(parseRectangle),
|
|
122
|
+
circles: getChildLists(expr, "circle").map(parseCircle),
|
|
123
|
+
arcs: getChildLists(expr, "arc").map(parseArc),
|
|
124
|
+
texts: getChildLists(expr, "text").map(parseText),
|
|
125
|
+
subSymbols
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function parsePin(expr) {
|
|
129
|
+
const at = getChildList(expr, "at");
|
|
130
|
+
const length = getChildScalar(expr, "length");
|
|
131
|
+
return {
|
|
132
|
+
electricalType: getAtom(expr[1]),
|
|
133
|
+
graphicStyle: getAtom(expr[2]),
|
|
134
|
+
at: at ? {
|
|
135
|
+
x: parseNumber(getAtom(at[1])),
|
|
136
|
+
y: parseNumber(getAtom(at[2])),
|
|
137
|
+
angle: parseNumber(getAtom(at[3]))
|
|
138
|
+
} : void 0,
|
|
139
|
+
length: length !== void 0 ? parseNumber(length) : void 0,
|
|
140
|
+
hidden: getChildScalar(expr, "hide") === "yes",
|
|
141
|
+
name: getChildScalar(expr, "name") ?? "",
|
|
142
|
+
number: getChildScalar(expr, "number") ?? "",
|
|
143
|
+
alternates: getChildLists(expr, "alternate").map(parseAlternate)
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
function parseAlternate(expr) {
|
|
147
|
+
return {
|
|
148
|
+
name: getAtom(expr[1]) ?? "",
|
|
149
|
+
electricalType: getAtom(expr[2]),
|
|
150
|
+
graphicStyle: getAtom(expr[3])
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function parsePolyline(expr) {
|
|
154
|
+
const pts = getChildList(expr, "pts");
|
|
155
|
+
return {
|
|
156
|
+
points: pts ? getChildLists(pts, "xy").map(parseXy) : [],
|
|
157
|
+
stroke: parseStroke(getChildList(expr, "stroke")),
|
|
158
|
+
fill: parseFill(getChildList(expr, "fill"))
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
function parseRectangle(expr) {
|
|
162
|
+
return {
|
|
163
|
+
start: parsePoint(getChildList(expr, "start")),
|
|
164
|
+
end: parsePoint(getChildList(expr, "end")),
|
|
165
|
+
stroke: parseStroke(getChildList(expr, "stroke")),
|
|
166
|
+
fill: parseFill(getChildList(expr, "fill"))
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
function parseCircle(expr) {
|
|
170
|
+
return {
|
|
171
|
+
center: parsePoint(getChildList(expr, "center")),
|
|
172
|
+
radius: parseNumber(getChildScalar(expr, "radius")),
|
|
173
|
+
stroke: parseStroke(getChildList(expr, "stroke")),
|
|
174
|
+
fill: parseFill(getChildList(expr, "fill"))
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
function parseArc(expr) {
|
|
178
|
+
return {
|
|
179
|
+
start: parsePoint(getChildList(expr, "start")),
|
|
180
|
+
mid: parsePoint(getChildList(expr, "mid")),
|
|
181
|
+
end: parsePoint(getChildList(expr, "end")),
|
|
182
|
+
stroke: parseStroke(getChildList(expr, "stroke"))
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function parseText(expr) {
|
|
186
|
+
const at = getChildList(expr, "at");
|
|
187
|
+
const effects = getChildList(expr, "effects");
|
|
188
|
+
const font = effects ? getChildList(effects, "font") : void 0;
|
|
189
|
+
const fontSize = font ? getChildList(font, "size") : void 0;
|
|
190
|
+
return {
|
|
191
|
+
text: getAtom(expr[1]) ?? "",
|
|
192
|
+
at: at ? {
|
|
193
|
+
x: parseNumber(getAtom(at[1])),
|
|
194
|
+
y: parseNumber(getAtom(at[2])),
|
|
195
|
+
angle: parseNumber(getAtom(at[3]))
|
|
196
|
+
} : { x: 0, y: 0, angle: 0 },
|
|
197
|
+
fontSize: fontSize ? Math.max(
|
|
198
|
+
parseNumber(getAtom(fontSize[1])),
|
|
199
|
+
parseNumber(getAtom(fontSize[2]))
|
|
200
|
+
) : void 0
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
function parseStroke(expr) {
|
|
204
|
+
if (!expr) return {};
|
|
205
|
+
return {
|
|
206
|
+
width: parseNumber(getChildScalar(expr, "width")),
|
|
207
|
+
type: getChildScalar(expr, "type")
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
function parseFill(expr) {
|
|
211
|
+
if (!expr) return {};
|
|
212
|
+
return {
|
|
213
|
+
type: getChildScalar(expr, "type")
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
function parseXy(expr) {
|
|
217
|
+
return {
|
|
218
|
+
x: parseNumber(getAtom(expr[1])),
|
|
219
|
+
y: parseNumber(getAtom(expr[2]))
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
function parsePoint(expr) {
|
|
223
|
+
if (!expr) return { x: 0, y: 0 };
|
|
224
|
+
return {
|
|
225
|
+
x: parseNumber(getAtom(expr[1])),
|
|
226
|
+
y: parseNumber(getAtom(expr[2]))
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function getChildScalar(expr, token) {
|
|
230
|
+
const child = getChildList(expr, token);
|
|
231
|
+
if (!child) return void 0;
|
|
232
|
+
return getAtom(child[1]);
|
|
233
|
+
}
|
|
234
|
+
function getChildList(expr, token) {
|
|
235
|
+
return getChildLists(expr, token)[0];
|
|
236
|
+
}
|
|
237
|
+
function getChildLists(expr, token) {
|
|
238
|
+
return expr.filter(
|
|
239
|
+
(child) => isList(child) && child[0] === token
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
function getAtom(expr) {
|
|
243
|
+
return typeof expr === "string" ? expr : void 0;
|
|
244
|
+
}
|
|
245
|
+
function isList(expr) {
|
|
246
|
+
return Array.isArray(expr);
|
|
247
|
+
}
|
|
248
|
+
function parseNumber(value) {
|
|
249
|
+
if (value === void 0) return 0;
|
|
250
|
+
const parsed = Number(value);
|
|
251
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
252
|
+
}
|
|
253
|
+
|
|
5
254
|
// lib/types.ts
|
|
6
255
|
var ConverterStage = class {
|
|
7
256
|
constructor(ctx) {
|
|
@@ -3671,6 +3920,411 @@ var InitializeSchematicContextStage = class extends ConverterStage {
|
|
|
3671
3920
|
}
|
|
3672
3921
|
};
|
|
3673
3922
|
|
|
3923
|
+
// lib/stages/symbol-library/CollectSymbolLibrarySymbolsStage.ts
|
|
3924
|
+
var MAX_KICAD_SYMBOL_UNIT_TO_CJ = 1;
|
|
3925
|
+
var PREVIEW_COLUMNS = 6;
|
|
3926
|
+
var PREVIEW_CELL_WIDTH = 10;
|
|
3927
|
+
var PREVIEW_CELL_HEIGHT = 9.5;
|
|
3928
|
+
var PREVIEW_CELL_FILL_RATIO = 0.95;
|
|
3929
|
+
var DEFAULT_STROKE_COLOR = "rgb(132, 0, 0)";
|
|
3930
|
+
var DEFAULT_FILL_COLOR = "rgb(255, 255, 194)";
|
|
3931
|
+
var CollectSymbolLibrarySymbolsStage = class extends ConverterStage {
|
|
3932
|
+
processedSymbols = /* @__PURE__ */ new Set();
|
|
3933
|
+
previewIndex = 0;
|
|
3934
|
+
step() {
|
|
3935
|
+
if (!this.ctx.kicadSymbolLib) {
|
|
3936
|
+
this.finished = true;
|
|
3937
|
+
return false;
|
|
3938
|
+
}
|
|
3939
|
+
const symbols = [...this.ctx.kicadSymbolLib.symbols].sort((a, b) => {
|
|
3940
|
+
const aFileName = this.getKicadSymbolExportFileName(a);
|
|
3941
|
+
const bFileName = this.getKicadSymbolExportFileName(b);
|
|
3942
|
+
return aFileName < bFileName ? -1 : aFileName > bFileName ? 1 : 0;
|
|
3943
|
+
});
|
|
3944
|
+
for (const symbol of symbols) {
|
|
3945
|
+
if (!symbol.name || this.processedSymbols.has(symbol.name)) continue;
|
|
3946
|
+
this.processSymbol(symbol);
|
|
3947
|
+
this.processedSymbols.add(symbol.name);
|
|
3948
|
+
}
|
|
3949
|
+
this.finished = true;
|
|
3950
|
+
return false;
|
|
3951
|
+
}
|
|
3952
|
+
processSymbol(symbol) {
|
|
3953
|
+
const sourceComponentData = this.createSourceComponentData(symbol);
|
|
3954
|
+
const sourceComponent = this.ctx.db.source_component.insert(sourceComponentData);
|
|
3955
|
+
const pins = this.collectPins(symbol);
|
|
3956
|
+
const seenPinNumbers = /* @__PURE__ */ new Set();
|
|
3957
|
+
let unnamedPinIndex = 0;
|
|
3958
|
+
const sourcePortIdByPinNumber = /* @__PURE__ */ new Map();
|
|
3959
|
+
for (const pin of pins) {
|
|
3960
|
+
const pinNumber = pin.number || `unnamed_${unnamedPinIndex++}`;
|
|
3961
|
+
if (seenPinNumbers.has(pinNumber)) continue;
|
|
3962
|
+
seenPinNumbers.add(pinNumber);
|
|
3963
|
+
const sourcePortData = {
|
|
3964
|
+
source_component_id: sourceComponent.source_component_id,
|
|
3965
|
+
name: this.getPortName(pin, pinNumber),
|
|
3966
|
+
...this.getSourcePortPinMetadata(pinNumber)
|
|
3967
|
+
};
|
|
3968
|
+
const sourcePort = this.ctx.db.source_port.insert(sourcePortData);
|
|
3969
|
+
sourcePortIdByPinNumber.set(pinNumber, sourcePort.source_port_id);
|
|
3970
|
+
}
|
|
3971
|
+
this.createSchematicPreview({
|
|
3972
|
+
symbol,
|
|
3973
|
+
pins,
|
|
3974
|
+
sourceComponentId: sourceComponent.source_component_id,
|
|
3975
|
+
sourcePortIdByPinNumber
|
|
3976
|
+
});
|
|
3977
|
+
if (this.ctx.stats) {
|
|
3978
|
+
this.ctx.stats.components = (this.ctx.stats.components || 0) + 1;
|
|
3979
|
+
this.ctx.stats.pads = (this.ctx.stats.pads || 0) + seenPinNumbers.size;
|
|
3980
|
+
}
|
|
3981
|
+
}
|
|
3982
|
+
getKicadSymbolExportFileName(symbol) {
|
|
3983
|
+
return `${symbol.name}_unit1.svg`;
|
|
3984
|
+
}
|
|
3985
|
+
collectPins(symbol) {
|
|
3986
|
+
return [
|
|
3987
|
+
...symbol.pins,
|
|
3988
|
+
...symbol.subSymbols.flatMap((subSymbol) => this.collectPins(subSymbol))
|
|
3989
|
+
];
|
|
3990
|
+
}
|
|
3991
|
+
collectPolylines(symbol) {
|
|
3992
|
+
return [
|
|
3993
|
+
...symbol.polylines,
|
|
3994
|
+
...symbol.subSymbols.flatMap(
|
|
3995
|
+
(subSymbol) => this.collectPolylines(subSymbol)
|
|
3996
|
+
)
|
|
3997
|
+
];
|
|
3998
|
+
}
|
|
3999
|
+
collectRectangles(symbol) {
|
|
4000
|
+
return [
|
|
4001
|
+
...symbol.rectangles,
|
|
4002
|
+
...symbol.subSymbols.flatMap(
|
|
4003
|
+
(subSymbol) => this.collectRectangles(subSymbol)
|
|
4004
|
+
)
|
|
4005
|
+
];
|
|
4006
|
+
}
|
|
4007
|
+
collectCircles(symbol) {
|
|
4008
|
+
return [
|
|
4009
|
+
...symbol.circles,
|
|
4010
|
+
...symbol.subSymbols.flatMap(
|
|
4011
|
+
(subSymbol) => this.collectCircles(subSymbol)
|
|
4012
|
+
)
|
|
4013
|
+
];
|
|
4014
|
+
}
|
|
4015
|
+
collectArcs(symbol) {
|
|
4016
|
+
return [
|
|
4017
|
+
...symbol.arcs,
|
|
4018
|
+
...symbol.subSymbols.flatMap((subSymbol) => this.collectArcs(subSymbol))
|
|
4019
|
+
];
|
|
4020
|
+
}
|
|
4021
|
+
collectTexts(symbol) {
|
|
4022
|
+
return [
|
|
4023
|
+
...symbol.texts,
|
|
4024
|
+
...symbol.subSymbols.flatMap((subSymbol) => this.collectTexts(subSymbol))
|
|
4025
|
+
];
|
|
4026
|
+
}
|
|
4027
|
+
createSchematicPreview(params) {
|
|
4028
|
+
const { symbol, pins, sourceComponentId, sourcePortIdByPinNumber } = params;
|
|
4029
|
+
const bounds = this.getPinBounds(pins);
|
|
4030
|
+
const scale3 = this.getPreviewScale(bounds);
|
|
4031
|
+
const size = {
|
|
4032
|
+
width: Math.max(1, bounds.width * scale3),
|
|
4033
|
+
height: Math.max(1, bounds.height * scale3)
|
|
4034
|
+
};
|
|
4035
|
+
const center = this.getPreviewCenter();
|
|
4036
|
+
const schematicComponentData = {
|
|
4037
|
+
source_component_id: sourceComponentId,
|
|
4038
|
+
center,
|
|
4039
|
+
size,
|
|
4040
|
+
is_box_with_pins: false
|
|
4041
|
+
};
|
|
4042
|
+
const schematicComponent = this.ctx.db.schematic_component.insert(
|
|
4043
|
+
schematicComponentData
|
|
4044
|
+
);
|
|
4045
|
+
for (const pin of pins) {
|
|
4046
|
+
if (!pin.at) continue;
|
|
4047
|
+
const pinNumber = pin.number || "";
|
|
4048
|
+
const sourcePortId = sourcePortIdByPinNumber.get(pinNumber);
|
|
4049
|
+
if (!sourcePortId) continue;
|
|
4050
|
+
const schematicPortData = {
|
|
4051
|
+
schematic_component_id: schematicComponent.schematic_component_id,
|
|
4052
|
+
source_port_id: sourcePortId,
|
|
4053
|
+
center: this.toSchematicPoint(pin.at, center, scale3),
|
|
4054
|
+
facing_direction: rotationToDirection(pin.at.angle),
|
|
4055
|
+
...this.getSchematicPortPinMetadata(pinNumber)
|
|
4056
|
+
};
|
|
4057
|
+
this.ctx.db.schematic_port.insert(schematicPortData);
|
|
4058
|
+
}
|
|
4059
|
+
this.createSchematicPrimitives({
|
|
4060
|
+
symbol,
|
|
4061
|
+
schematicComponentId: schematicComponent.schematic_component_id,
|
|
4062
|
+
origin: center,
|
|
4063
|
+
scale: scale3
|
|
4064
|
+
});
|
|
4065
|
+
}
|
|
4066
|
+
getPreviewCenter() {
|
|
4067
|
+
const index = this.previewIndex++;
|
|
4068
|
+
const column = index % PREVIEW_COLUMNS;
|
|
4069
|
+
const row = Math.floor(index / PREVIEW_COLUMNS);
|
|
4070
|
+
return {
|
|
4071
|
+
x: (column - (PREVIEW_COLUMNS - 1) / 2) * PREVIEW_CELL_WIDTH,
|
|
4072
|
+
y: -row * PREVIEW_CELL_HEIGHT
|
|
4073
|
+
};
|
|
4074
|
+
}
|
|
4075
|
+
getPinBounds(pins) {
|
|
4076
|
+
const pinsWithPositions = pins.filter((pin) => pin.at);
|
|
4077
|
+
if (pinsWithPositions.length === 0) {
|
|
4078
|
+
return { width: 15, height: 15 };
|
|
4079
|
+
}
|
|
4080
|
+
const xs = pinsWithPositions.map((pin) => pin.at.x);
|
|
4081
|
+
const ys = pinsWithPositions.map((pin) => pin.at.y);
|
|
4082
|
+
return {
|
|
4083
|
+
width: Math.max(...xs) - Math.min(...xs) + 7.5,
|
|
4084
|
+
height: Math.max(...ys) - Math.min(...ys) + 7.5
|
|
4085
|
+
};
|
|
4086
|
+
}
|
|
4087
|
+
getPreviewScale(bounds) {
|
|
4088
|
+
const scaleX = PREVIEW_CELL_WIDTH * PREVIEW_CELL_FILL_RATIO / Math.max(1, bounds.width);
|
|
4089
|
+
const scaleY = PREVIEW_CELL_HEIGHT * PREVIEW_CELL_FILL_RATIO / Math.max(1, bounds.height);
|
|
4090
|
+
return Math.min(MAX_KICAD_SYMBOL_UNIT_TO_CJ, scaleX, scaleY);
|
|
4091
|
+
}
|
|
4092
|
+
createSchematicPrimitives(params) {
|
|
4093
|
+
const { symbol, schematicComponentId, origin, scale: scale3 } = params;
|
|
4094
|
+
for (const polyline of this.collectPolylines(symbol)) {
|
|
4095
|
+
this.createPolylinePrimitives(
|
|
4096
|
+
polyline,
|
|
4097
|
+
schematicComponentId,
|
|
4098
|
+
origin,
|
|
4099
|
+
scale3
|
|
4100
|
+
);
|
|
4101
|
+
}
|
|
4102
|
+
for (const rectangle of this.collectRectangles(symbol)) {
|
|
4103
|
+
const start = this.toSchematicPoint(rectangle.start, origin, scale3);
|
|
4104
|
+
const end = this.toSchematicPoint(rectangle.end, origin, scale3);
|
|
4105
|
+
const rectData = {
|
|
4106
|
+
schematic_component_id: schematicComponentId,
|
|
4107
|
+
center: {
|
|
4108
|
+
x: (start.x + end.x) / 2,
|
|
4109
|
+
y: (start.y + end.y) / 2
|
|
4110
|
+
},
|
|
4111
|
+
width: Math.abs(end.x - start.x),
|
|
4112
|
+
height: Math.abs(end.y - start.y),
|
|
4113
|
+
rotation: 0,
|
|
4114
|
+
stroke_width: this.toStrokeWidth(rectangle.stroke?.width, scale3),
|
|
4115
|
+
color: DEFAULT_STROKE_COLOR,
|
|
4116
|
+
is_filled: this.isFilled(rectangle.fill?.type),
|
|
4117
|
+
fill_color: this.isFilled(rectangle.fill?.type) ? DEFAULT_FILL_COLOR : void 0,
|
|
4118
|
+
is_dashed: rectangle.stroke?.type === "dash"
|
|
4119
|
+
};
|
|
4120
|
+
this.ctx.db.schematic_rect.insert(rectData);
|
|
4121
|
+
}
|
|
4122
|
+
for (const circle of this.collectCircles(symbol)) {
|
|
4123
|
+
const circleData = {
|
|
4124
|
+
schematic_component_id: schematicComponentId,
|
|
4125
|
+
center: this.toSchematicPoint(circle.center, origin, scale3),
|
|
4126
|
+
radius: circle.radius * scale3,
|
|
4127
|
+
stroke_width: this.toStrokeWidth(circle.stroke?.width, scale3),
|
|
4128
|
+
color: DEFAULT_STROKE_COLOR,
|
|
4129
|
+
is_filled: this.isFilled(circle.fill?.type),
|
|
4130
|
+
fill_color: this.isFilled(circle.fill?.type) ? DEFAULT_FILL_COLOR : void 0,
|
|
4131
|
+
is_dashed: circle.stroke?.type === "dash"
|
|
4132
|
+
};
|
|
4133
|
+
this.ctx.db.schematic_circle.insert(circleData);
|
|
4134
|
+
}
|
|
4135
|
+
for (const arc of this.collectArcs(symbol)) {
|
|
4136
|
+
const arcGeometry = this.getArcGeometry(arc, origin, scale3);
|
|
4137
|
+
if (!arcGeometry) {
|
|
4138
|
+
const pathData = {
|
|
4139
|
+
schematic_component_id: schematicComponentId,
|
|
4140
|
+
points: [arc.start, arc.mid, arc.end].map(
|
|
4141
|
+
(point) => this.toSchematicPoint(point, origin, scale3)
|
|
4142
|
+
),
|
|
4143
|
+
stroke_width: this.toStrokeWidth(arc.stroke?.width, scale3),
|
|
4144
|
+
stroke_color: DEFAULT_STROKE_COLOR
|
|
4145
|
+
};
|
|
4146
|
+
this.ctx.db.schematic_path.insert(pathData);
|
|
4147
|
+
continue;
|
|
4148
|
+
}
|
|
4149
|
+
const arcData = {
|
|
4150
|
+
schematic_component_id: schematicComponentId,
|
|
4151
|
+
...arcGeometry,
|
|
4152
|
+
stroke_width: this.toStrokeWidth(arc.stroke?.width, scale3),
|
|
4153
|
+
color: DEFAULT_STROKE_COLOR,
|
|
4154
|
+
is_dashed: arc.stroke?.type === "dash"
|
|
4155
|
+
};
|
|
4156
|
+
this.ctx.db.schematic_arc.insert(arcData);
|
|
4157
|
+
}
|
|
4158
|
+
for (const text of this.collectTexts(symbol)) {
|
|
4159
|
+
if (!text.text) continue;
|
|
4160
|
+
const textData = {
|
|
4161
|
+
schematic_component_id: schematicComponentId,
|
|
4162
|
+
text: text.text,
|
|
4163
|
+
font_size: Math.max(0.1, (text.fontSize ?? 1.27) * scale3),
|
|
4164
|
+
position: this.toSchematicPoint(text.at, origin, scale3),
|
|
4165
|
+
rotation: -text.at.angle,
|
|
4166
|
+
anchor: "center",
|
|
4167
|
+
color: DEFAULT_STROKE_COLOR
|
|
4168
|
+
};
|
|
4169
|
+
this.ctx.db.schematic_text.insert(textData);
|
|
4170
|
+
}
|
|
4171
|
+
}
|
|
4172
|
+
createPolylinePrimitives(polyline, schematicComponentId, origin, scale3) {
|
|
4173
|
+
if (polyline.points.length < 2) return;
|
|
4174
|
+
if (this.isFilled(polyline.fill?.type) && polyline.points.length >= 3) {
|
|
4175
|
+
const pathData = {
|
|
4176
|
+
schematic_component_id: schematicComponentId,
|
|
4177
|
+
points: polyline.points.map(
|
|
4178
|
+
(point) => this.toSchematicPoint(point, origin, scale3)
|
|
4179
|
+
),
|
|
4180
|
+
stroke_width: this.toStrokeWidth(polyline.stroke?.width, scale3),
|
|
4181
|
+
stroke_color: DEFAULT_STROKE_COLOR,
|
|
4182
|
+
is_filled: true,
|
|
4183
|
+
fill_color: DEFAULT_FILL_COLOR
|
|
4184
|
+
};
|
|
4185
|
+
this.ctx.db.schematic_path.insert(pathData);
|
|
4186
|
+
}
|
|
4187
|
+
for (let index = 1; index < polyline.points.length; index++) {
|
|
4188
|
+
const start = this.toSchematicPoint(
|
|
4189
|
+
polyline.points[index - 1],
|
|
4190
|
+
origin,
|
|
4191
|
+
scale3
|
|
4192
|
+
);
|
|
4193
|
+
const end = this.toSchematicPoint(polyline.points[index], origin, scale3);
|
|
4194
|
+
const lineData = {
|
|
4195
|
+
schematic_component_id: schematicComponentId,
|
|
4196
|
+
x1: start.x,
|
|
4197
|
+
y1: start.y,
|
|
4198
|
+
x2: end.x,
|
|
4199
|
+
y2: end.y,
|
|
4200
|
+
stroke_width: this.toStrokeWidth(polyline.stroke?.width, scale3),
|
|
4201
|
+
color: DEFAULT_STROKE_COLOR,
|
|
4202
|
+
is_dashed: polyline.stroke?.type === "dash"
|
|
4203
|
+
};
|
|
4204
|
+
this.ctx.db.schematic_line.insert(lineData);
|
|
4205
|
+
}
|
|
4206
|
+
}
|
|
4207
|
+
toSchematicPoint(point, origin = { x: 0, y: 0 }, scale3 = MAX_KICAD_SYMBOL_UNIT_TO_CJ) {
|
|
4208
|
+
return {
|
|
4209
|
+
x: origin.x + point.x * scale3,
|
|
4210
|
+
y: origin.y + point.y * scale3
|
|
4211
|
+
};
|
|
4212
|
+
}
|
|
4213
|
+
toStrokeWidth(width, scale3) {
|
|
4214
|
+
if (!width) return null;
|
|
4215
|
+
return Math.max(0.01, width * scale3);
|
|
4216
|
+
}
|
|
4217
|
+
isFilled(fillType) {
|
|
4218
|
+
return fillType !== void 0 && fillType !== "none";
|
|
4219
|
+
}
|
|
4220
|
+
getArcGeometry(arc, origin, scale3) {
|
|
4221
|
+
const start = this.toSchematicPoint(arc.start, origin, scale3);
|
|
4222
|
+
const mid = this.toSchematicPoint(arc.mid, origin, scale3);
|
|
4223
|
+
const end = this.toSchematicPoint(arc.end, origin, scale3);
|
|
4224
|
+
const denominator = 2 * (start.x * (mid.y - end.y) + mid.x * (end.y - start.y) + end.x * (start.y - mid.y));
|
|
4225
|
+
if (Math.abs(denominator) < 1e-9) return null;
|
|
4226
|
+
const startLen = start.x ** 2 + start.y ** 2;
|
|
4227
|
+
const midLen = mid.x ** 2 + mid.y ** 2;
|
|
4228
|
+
const endLen = end.x ** 2 + end.y ** 2;
|
|
4229
|
+
const center = {
|
|
4230
|
+
x: (startLen * (mid.y - end.y) + midLen * (end.y - start.y) + endLen * (start.y - mid.y)) / denominator,
|
|
4231
|
+
y: (startLen * (end.x - mid.x) + midLen * (start.x - end.x) + endLen * (mid.x - start.x)) / denominator
|
|
4232
|
+
};
|
|
4233
|
+
const radius = Math.hypot(start.x - center.x, start.y - center.y);
|
|
4234
|
+
const startAngleDegrees = this.getAngleDegrees(start, center);
|
|
4235
|
+
const endAngleDegrees = this.getAngleDegrees(end, center);
|
|
4236
|
+
const cross = (mid.x - start.x) * (end.y - mid.y) - (mid.y - start.y) * (end.x - mid.x);
|
|
4237
|
+
return {
|
|
4238
|
+
center,
|
|
4239
|
+
radius,
|
|
4240
|
+
start_angle_degrees: startAngleDegrees,
|
|
4241
|
+
end_angle_degrees: endAngleDegrees,
|
|
4242
|
+
direction: cross >= 0 ? "counterclockwise" : "clockwise"
|
|
4243
|
+
};
|
|
4244
|
+
}
|
|
4245
|
+
getAngleDegrees(point, center) {
|
|
4246
|
+
return Math.atan2(point.y - center.y, point.x - center.x) * 180 / Math.PI;
|
|
4247
|
+
}
|
|
4248
|
+
getManufacturerPartNumber(symbol) {
|
|
4249
|
+
return symbol.properties["Manufacturer Part Number"] || symbol.properties["MPN"] || symbol.properties["P/N"] || symbol.properties.Value || void 0;
|
|
4250
|
+
}
|
|
4251
|
+
createSourceComponentData(symbol) {
|
|
4252
|
+
const base = {
|
|
4253
|
+
name: symbol.name,
|
|
4254
|
+
manufacturer_part_number: this.getManufacturerPartNumber(symbol)
|
|
4255
|
+
};
|
|
4256
|
+
const ftype = this.inferFtype(symbol);
|
|
4257
|
+
switch (ftype) {
|
|
4258
|
+
case "simple_resistor":
|
|
4259
|
+
return { ...base, ftype, resistance: 0 };
|
|
4260
|
+
case "simple_capacitor":
|
|
4261
|
+
return { ...base, ftype, capacitance: 0 };
|
|
4262
|
+
case "simple_inductor":
|
|
4263
|
+
return { ...base, ftype, inductance: 0 };
|
|
4264
|
+
case "simple_transistor":
|
|
4265
|
+
return { ...base, ftype, transistor_type: "npn" };
|
|
4266
|
+
case "simple_led":
|
|
4267
|
+
case "simple_diode":
|
|
4268
|
+
case "simple_chip":
|
|
4269
|
+
return { ...base, ftype };
|
|
4270
|
+
}
|
|
4271
|
+
}
|
|
4272
|
+
inferFtype(symbol) {
|
|
4273
|
+
const name = symbol.name.toLowerCase();
|
|
4274
|
+
const reference = symbol.properties.Reference ?? "";
|
|
4275
|
+
if (name === "r" || name.startsWith("r_") || reference.startsWith("R")) {
|
|
4276
|
+
return "simple_resistor";
|
|
4277
|
+
}
|
|
4278
|
+
if (name === "c" || name.startsWith("c_") || reference.startsWith("C")) {
|
|
4279
|
+
return "simple_capacitor";
|
|
4280
|
+
}
|
|
4281
|
+
if (name === "l" || name.startsWith("l_") || reference.startsWith("L")) {
|
|
4282
|
+
return "simple_inductor";
|
|
4283
|
+
}
|
|
4284
|
+
if (name.includes("led") || reference.startsWith("LED")) {
|
|
4285
|
+
return "simple_led";
|
|
4286
|
+
}
|
|
4287
|
+
if (name.startsWith("d_") || reference.startsWith("D")) {
|
|
4288
|
+
return "simple_diode";
|
|
4289
|
+
}
|
|
4290
|
+
if (name.startsWith("q_") || reference.startsWith("Q")) {
|
|
4291
|
+
return "simple_transistor";
|
|
4292
|
+
}
|
|
4293
|
+
return "simple_chip";
|
|
4294
|
+
}
|
|
4295
|
+
getPortName(pin, pinNumber) {
|
|
4296
|
+
if (pin.name) return pin.name;
|
|
4297
|
+
if (/^\d+$/.test(pinNumber)) return `pin${Number(pinNumber)}`;
|
|
4298
|
+
return pinNumber;
|
|
4299
|
+
}
|
|
4300
|
+
getSourcePortPinMetadata(pinNumber) {
|
|
4301
|
+
if (/^\d+$/.test(pinNumber)) {
|
|
4302
|
+
return { pin_number: Number(pinNumber) };
|
|
4303
|
+
}
|
|
4304
|
+
return { port_hints: [pinNumber] };
|
|
4305
|
+
}
|
|
4306
|
+
getSchematicPortPinMetadata(pinNumber) {
|
|
4307
|
+
if (/^\d+$/.test(pinNumber)) {
|
|
4308
|
+
return { pin_number: Number(pinNumber) };
|
|
4309
|
+
}
|
|
4310
|
+
return { display_pin_label: pinNumber };
|
|
4311
|
+
}
|
|
4312
|
+
};
|
|
4313
|
+
|
|
4314
|
+
// lib/stages/symbol-library/InitializeSymbolLibraryContextStage.ts
|
|
4315
|
+
var InitializeSymbolLibraryContextStage = class extends ConverterStage {
|
|
4316
|
+
step() {
|
|
4317
|
+
if (!this.ctx.kicadSymbolLib) {
|
|
4318
|
+
this.finished = true;
|
|
4319
|
+
return false;
|
|
4320
|
+
}
|
|
4321
|
+
this.ctx.warnings = this.ctx.warnings || [];
|
|
4322
|
+
this.ctx.stats = this.ctx.stats || {};
|
|
4323
|
+
this.finished = true;
|
|
4324
|
+
return false;
|
|
4325
|
+
}
|
|
4326
|
+
};
|
|
4327
|
+
|
|
3674
4328
|
// lib/KicadToCircuitJsonConverter.ts
|
|
3675
4329
|
var KicadToCircuitJsonConverter = class {
|
|
3676
4330
|
fsMap = {};
|
|
@@ -3697,14 +4351,22 @@ var KicadToCircuitJsonConverter = class {
|
|
|
3697
4351
|
initializePipeline() {
|
|
3698
4352
|
const pcbFile = this._findFileWithExtension(".kicad_pcb");
|
|
3699
4353
|
const schFile = this._findFileWithExtension(".kicad_sch");
|
|
4354
|
+
const symbolLibFile = this._findFileWithExtension(".kicad_sym");
|
|
3700
4355
|
this.ctx = {
|
|
3701
4356
|
db: cju([]),
|
|
3702
4357
|
kicadPcb: pcbFile ? parseKicadPcb(this.fsMap[pcbFile]) : void 0,
|
|
3703
4358
|
kicadSch: schFile ? parseKicadSch(this.fsMap[schFile]) : void 0,
|
|
4359
|
+
kicadSymbolLib: symbolLibFile ? parseKicadSymbolLib(this.fsMap[symbolLibFile]) : void 0,
|
|
3704
4360
|
warnings: [],
|
|
3705
4361
|
stats: {}
|
|
3706
4362
|
};
|
|
3707
4363
|
this.pipeline = [];
|
|
4364
|
+
if (this.ctx.kicadSymbolLib) {
|
|
4365
|
+
this.pipeline.push(
|
|
4366
|
+
new InitializeSymbolLibraryContextStage(this.ctx),
|
|
4367
|
+
new CollectSymbolLibrarySymbolsStage(this.ctx)
|
|
4368
|
+
);
|
|
4369
|
+
}
|
|
3708
4370
|
if (this.ctx.kicadSch) {
|
|
3709
4371
|
this.pipeline.push(
|
|
3710
4372
|
new InitializeSchematicContextStage(this.ctx),
|
|
@@ -3751,46 +4413,7 @@ var KicadToCircuitJsonConverter = class {
|
|
|
3751
4413
|
this.initializePipeline();
|
|
3752
4414
|
this.runUntilFinished();
|
|
3753
4415
|
}
|
|
3754
|
-
|
|
3755
|
-
const tableNames = [
|
|
3756
|
-
"source_component",
|
|
3757
|
-
"source_port",
|
|
3758
|
-
"source_net",
|
|
3759
|
-
"source_trace",
|
|
3760
|
-
"schematic_component",
|
|
3761
|
-
"schematic_port",
|
|
3762
|
-
"schematic_trace",
|
|
3763
|
-
"schematic_net_label",
|
|
3764
|
-
"pcb_component",
|
|
3765
|
-
"pcb_port",
|
|
3766
|
-
"pcb_smtpad",
|
|
3767
|
-
"pcb_plated_hole",
|
|
3768
|
-
"pcb_hole",
|
|
3769
|
-
"pcb_trace",
|
|
3770
|
-
"pcb_via",
|
|
3771
|
-
"pcb_copper_pour",
|
|
3772
|
-
"pcb_board",
|
|
3773
|
-
"pcb_cutout",
|
|
3774
|
-
"pcb_copper_text",
|
|
3775
|
-
"pcb_silkscreen_text",
|
|
3776
|
-
"pcb_silkscreen_path",
|
|
3777
|
-
"pcb_fabrication_note_text",
|
|
3778
|
-
"pcb_fabrication_note_path",
|
|
3779
|
-
"pcb_fabrication_note_rect",
|
|
3780
|
-
"pcb_courtyard_rect",
|
|
3781
|
-
"pcb_courtyard_outline",
|
|
3782
|
-
"pcb_courtyard_circle"
|
|
3783
|
-
];
|
|
3784
|
-
for (const tableName of tableNames) {
|
|
3785
|
-
const table = this.ctx.db[tableName];
|
|
3786
|
-
if (table && typeof table.list === "function") {
|
|
3787
|
-
const items = table.list();
|
|
3788
|
-
if (items && Array.isArray(items)) {
|
|
3789
|
-
elements.push(...items);
|
|
3790
|
-
}
|
|
3791
|
-
}
|
|
3792
|
-
}
|
|
3793
|
-
return elements;
|
|
4416
|
+
return this.ctx.db.toArray();
|
|
3794
4417
|
}
|
|
3795
4418
|
getOutputString() {
|
|
3796
4419
|
return JSON.stringify(this.getOutput(), null, 2);
|
|
@@ -3809,11 +4432,13 @@ export {
|
|
|
3809
4432
|
CollectNetsStage,
|
|
3810
4433
|
CollectSchematicTracesStage,
|
|
3811
4434
|
CollectSourceTracesStage,
|
|
4435
|
+
CollectSymbolLibrarySymbolsStage,
|
|
3812
4436
|
CollectTracesStage,
|
|
3813
4437
|
CollectViasStage,
|
|
3814
4438
|
CollectZonesStage,
|
|
3815
4439
|
ConverterStage,
|
|
3816
4440
|
InitializePcbContextStage,
|
|
3817
4441
|
InitializeSchematicContextStage,
|
|
4442
|
+
InitializeSymbolLibraryContextStage,
|
|
3818
4443
|
KicadToCircuitJsonConverter
|
|
3819
4444
|
};
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "kicad-to-circuit-json",
|
|
3
3
|
"main": "dist/index.js",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.80",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist"
|
|
8
8
|
],
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"kicadts": "^0.0.43",
|
|
36
36
|
"react": "^19.2.0",
|
|
37
37
|
"react-dom": "^19.2.5",
|
|
38
|
-
"tscircuit": "^0.0.
|
|
38
|
+
"tscircuit": "^0.0.1825",
|
|
39
39
|
"tsup": "^8.5.0",
|
|
40
40
|
"vercel": "^50.42.0",
|
|
41
41
|
"vite": "^8.0.8"
|