easyeda 0.0.126 → 0.0.128

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.
@@ -0,0 +1,3154 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
7
+ // lib/schemas/easy-eda-json-schema.ts
8
+ import { z as z3 } from "zod";
9
+
10
+ // lib/schemas/package-detail-shape-schema.ts
11
+ import { z } from "zod";
12
+ var tenthmil = z.union([z.number(), z.string()]).optional().transform(
13
+ (n) => typeof n === "string" && n.endsWith("mil") ? n : `${Number.parseFloat(n) * 10}mil`
14
+ ).pipe(z.string());
15
+ var PointSchema = z.any().transform((p) => {
16
+ if (Array.isArray(p)) {
17
+ const [x, y] = p;
18
+ return { x, y };
19
+ } else if (typeof p === "object") {
20
+ return p;
21
+ }
22
+ throw new Error(`Invalid point: ${p}`);
23
+ }).pipe(
24
+ z.object({
25
+ x: z.number(),
26
+ y: z.number()
27
+ })
28
+ );
29
+ var BaseShapeSchema = z.object({
30
+ type: z.string(),
31
+ id: z.string().optional(),
32
+ layer: z.coerce.number().optional()
33
+ });
34
+ var TrackSchema = BaseShapeSchema.extend({
35
+ type: z.literal("TRACK"),
36
+ width: z.coerce.number(),
37
+ points: z.array(PointSchema)
38
+ });
39
+ var PadSchema = BaseShapeSchema.extend({
40
+ type: z.literal("PAD"),
41
+ shape: z.enum(["RECT", "ELLIPSE", "OVAL"]),
42
+ center: z.object({
43
+ x: tenthmil,
44
+ y: tenthmil
45
+ }),
46
+ width: tenthmil,
47
+ height: tenthmil,
48
+ layermask: z.number(),
49
+ net: z.union([z.string(), z.number()]).optional(),
50
+ number: z.union([z.string(), z.number()]),
51
+ holeRadius: tenthmil,
52
+ points: z.array(PointSchema).optional(),
53
+ rotation: z.number().optional(),
54
+ plated: z.boolean()
55
+ });
56
+ var ArcSchema = BaseShapeSchema.extend({
57
+ type: z.literal("ARC"),
58
+ width: z.number(),
59
+ start: PointSchema,
60
+ end: PointSchema,
61
+ radiusX: z.number(),
62
+ radiusY: z.number(),
63
+ largeArc: z.boolean(),
64
+ sweepDirection: z.enum(["CW", "CCW"])
65
+ });
66
+ var CircleSchema = BaseShapeSchema.extend({
67
+ type: z.literal("CIRCLE"),
68
+ center: PointSchema,
69
+ radius: z.number(),
70
+ width: z.number()
71
+ });
72
+ var SolidRegionSchema = BaseShapeSchema.extend({
73
+ type: z.literal("SOLIDREGION"),
74
+ layermask: z.number(),
75
+ points: z.array(PointSchema),
76
+ fillStyle: z.string()
77
+ });
78
+ var SVGNodeSchema = BaseShapeSchema.extend({
79
+ type: z.literal("SVGNODE"),
80
+ svgData: z.object({
81
+ gId: z.string(),
82
+ nodeName: z.string(),
83
+ nodeType: z.number(),
84
+ layerid: z.string(),
85
+ attrs: z.record(z.string(), z.string()),
86
+ childNodes: z.array(z.unknown())
87
+ })
88
+ });
89
+ var HoleSchema = BaseShapeSchema.extend({
90
+ type: z.literal("HOLE"),
91
+ center: PointSchema,
92
+ radius: z.number()
93
+ });
94
+ var RectSchema = BaseShapeSchema.extend({
95
+ type: z.literal("RECT"),
96
+ x: tenthmil,
97
+ y: tenthmil,
98
+ width: tenthmil,
99
+ height: tenthmil,
100
+ lineWidth: z.number(),
101
+ fillStyle: z.string(),
102
+ rotation: z.number().optional()
103
+ });
104
+ var TextSchema = BaseShapeSchema.extend({
105
+ type: z.literal("TEXT"),
106
+ text: z.string(),
107
+ x: tenthmil,
108
+ y: tenthmil,
109
+ size_mm: z.number(),
110
+ rotation: z.number().optional(),
111
+ layer: z.number().optional(),
112
+ textAnchor: z.enum(["L", "C", "R", ""]).optional().transform((val) => val === "" ? void 0 : val),
113
+ font: z.string().optional()
114
+ });
115
+ var PackageDetailShapeSchema = z.discriminatedUnion("type", [
116
+ TrackSchema,
117
+ PadSchema,
118
+ ArcSchema,
119
+ CircleSchema,
120
+ SolidRegionSchema,
121
+ SVGNodeSchema,
122
+ HoleSchema,
123
+ RectSchema,
124
+ TextSchema
125
+ ]);
126
+ var pairs = (arr) => {
127
+ const pairs2 = [];
128
+ for (let i = 0; i < arr.length; i += 2) {
129
+ pairs2.push([arr[i], arr[i + 1]]);
130
+ }
131
+ return pairs2;
132
+ };
133
+ var parsePoints = (pointsStr) => pairs(
134
+ pointsStr.trim().split(" ").map((n) => Number(n))
135
+ );
136
+ var ShapeItemSchema = z.object({
137
+ type: z.string(),
138
+ data: z.string()
139
+ }).transform((shape) => {
140
+ const [firstParam, ...restParams] = shape.data.split("~");
141
+ const lastParam = restParams.pop();
142
+ switch (shape.type) {
143
+ case "TRACK": {
144
+ const [width, layer, _, pointsStr, id, _n] = shape.data.split("~");
145
+ const points = parsePoints(pointsStr);
146
+ return TrackSchema.parse({ type: "TRACK", width, layer, points, id });
147
+ }
148
+ case "PAD": {
149
+ const [padShape, ...params] = shape.data.split("~");
150
+ const [
151
+ centerX,
152
+ centerY,
153
+ width,
154
+ height,
155
+ layermask,
156
+ net,
157
+ number,
158
+ holeRadius,
159
+ ...rest
160
+ ] = params.map((p) => isNaN(Number(p)) ? p : Number(p));
161
+ const center = { x: centerX, y: centerY };
162
+ let points, rotation2;
163
+ if (padShape === "RECT") {
164
+ points = parsePoints(rest[0]);
165
+ rotation2 = Number(rest[1]);
166
+ }
167
+ const padInputParams = {
168
+ type: "PAD",
169
+ shape: padShape,
170
+ center,
171
+ width,
172
+ height,
173
+ layermask,
174
+ net,
175
+ number,
176
+ holeRadius,
177
+ points,
178
+ rotation: rotation2,
179
+ plated: rest.includes("Y")
180
+ };
181
+ const pad = PadSchema.parse(padInputParams);
182
+ return pad;
183
+ }
184
+ case "ARC": {
185
+ const [width, layer, , arcData] = shape.data.split("~");
186
+ const match = arcData.match(
187
+ /M\s*([\d.-]+)(?:\s*,\s*|\s+)([\d.-]+)\s*A\s*([\d.-]+)(?:\s*,\s*|\s+)([\d.-]+)\s*([\d.-]+)\s*([\d.-]+)\s*([\d.-]+)\s*([\d.-]+)(?:\s*,\s*|\s+)([\d.-]+)/
188
+ );
189
+ if (!match) {
190
+ throw new Error(`Invalid arc data: ${arcData}`);
191
+ }
192
+ const [
193
+ ,
194
+ startX,
195
+ startY,
196
+ radiusX,
197
+ radiusY,
198
+ xAxisRotation,
199
+ largeArcFlag,
200
+ sweepFlag,
201
+ endX,
202
+ endY
203
+ ] = match;
204
+ const start = [Number(startX), Number(startY)];
205
+ const end = [Number(endX), Number(endY)];
206
+ return ArcSchema.parse({
207
+ type: "ARC",
208
+ width: Number(width),
209
+ layer: Number(layer),
210
+ start,
211
+ end,
212
+ radiusX: Number(radiusX),
213
+ radiusY: Number(radiusY),
214
+ largeArc: largeArcFlag === "1",
215
+ sweepDirection: sweepFlag === "1" ? "CW" : "CCW"
216
+ });
217
+ }
218
+ case "CIRCLE": {
219
+ const [centerX, centerY, radius, width, layer, id] = shape.data.split("~");
220
+ const center = [Number(centerX), Number(centerY)];
221
+ return CircleSchema.parse({
222
+ type: "CIRCLE",
223
+ center,
224
+ radius: Number(radius),
225
+ width: Number(width),
226
+ layer: Number(layer),
227
+ id
228
+ });
229
+ }
230
+ case "HOLE": {
231
+ const [centerX, centerY, radius, id] = shape.data.split("~");
232
+ const center = [Number(centerX), Number(centerY)];
233
+ return HoleSchema.parse({
234
+ type: "HOLE",
235
+ center,
236
+ radius: Number(radius),
237
+ id
238
+ });
239
+ }
240
+ case "SOLIDREGION": {
241
+ const [layermask, , pathData, fillStyle, id] = shape.data.split("~");
242
+ const points = pathData.match(/[ML] ?(-?[\d.]+)[ ,](-?[\d.]+)/g)?.map((point2) => {
243
+ const [, x, y] = point2.match(/[ML]? ?(-?[\d.]+)[ ,](-?[\d.]+)/) || [];
244
+ return [Number(x), Number(y)];
245
+ }) || [];
246
+ return SolidRegionSchema.parse({
247
+ type: "SOLIDREGION",
248
+ layermask: Number(layermask),
249
+ points,
250
+ fillStyle,
251
+ id
252
+ });
253
+ }
254
+ case "SVGNODE": {
255
+ const svgData = JSON.parse(shape.data);
256
+ return SVGNodeSchema.parse({ type: "SVGNODE", svgData });
257
+ }
258
+ case "RECT": {
259
+ const [x, y, width, height, lineWidth, id, rotation2, layer, fillStyle] = shape.data.split("~");
260
+ return RectSchema.parse({
261
+ type: "RECT",
262
+ x,
263
+ y,
264
+ width,
265
+ height,
266
+ lineWidth: Number(lineWidth),
267
+ id,
268
+ rotation: rotation2 ? Number(rotation2) : void 0,
269
+ layer: layer ? Number(layer) : void 0,
270
+ fillStyle: fillStyle || void 0
271
+ });
272
+ }
273
+ case "TEXT": {
274
+ const [textAnchor, x, y, size2, layer, id, rotation2, , font, text] = shape.data.split("~");
275
+ return TextSchema.parse({
276
+ type: "TEXT",
277
+ text,
278
+ x,
279
+ y,
280
+ size_mm: Number(size2) * 2.54,
281
+ // empirically this seems to match, C5248081 is a good test case
282
+ layer: layer ? Number(layer) : void 0,
283
+ id,
284
+ rotation: rotation2 ? Number(rotation2) : void 0,
285
+ textAnchor,
286
+ font: font || void 0
287
+ });
288
+ }
289
+ default:
290
+ throw new Error(`Unknown shape type: ${shape.type}`);
291
+ return BaseShapeSchema.parse({ type: shape.type });
292
+ }
293
+ }).pipe(PackageDetailShapeSchema);
294
+ var ShapesArraySchema = z.array(ShapeItemSchema);
295
+
296
+ // lib/schemas/single-letter-shape-schema.ts
297
+ import { z as z2 } from "zod";
298
+ import "@tscircuit/mm";
299
+
300
+ // lib/utils/easyeda-unit-to-mm.ts
301
+ var mil10ToMm = (value) => value * 10 * 0.0254;
302
+
303
+ // lib/schemas/single-letter-shape-schema.ts
304
+ var PointSchema2 = z2.object({
305
+ x: z2.number(),
306
+ y: z2.number()
307
+ });
308
+ var RectangleShapeOutputSchema = z2.object({
309
+ type: z2.literal("RECTANGLE"),
310
+ position: PointSchema2,
311
+ width: z2.number(),
312
+ height: z2.number(),
313
+ color: z2.string(),
314
+ lineWidth: z2.number(),
315
+ id: z2.string()
316
+ });
317
+ var parseRectangle = (str) => {
318
+ const [, x, y, , , width, height, color, lineWidth, , , id] = str.split("~");
319
+ return {
320
+ type: "RECTANGLE",
321
+ position: { x: Number(x), y: Number(y) },
322
+ width: Number(width),
323
+ height: Number(height),
324
+ color,
325
+ lineWidth: Number(lineWidth),
326
+ id
327
+ };
328
+ };
329
+ var RectangleShapeSchema = z2.string().startsWith("R~").transform(parseRectangle).pipe(RectangleShapeOutputSchema);
330
+ var EllipseShapeOutputSchema = z2.object({
331
+ type: z2.literal("ELLIPSE"),
332
+ center: PointSchema2,
333
+ radiusX: z2.number(),
334
+ radiusY: z2.number(),
335
+ color: z2.string(),
336
+ lineWidth: z2.number(),
337
+ id: z2.string()
338
+ });
339
+ var parseEllipse = (str) => {
340
+ const [, x, y, radiusX, radiusY, color, lineWidth, , , id] = str.split("~");
341
+ return {
342
+ type: "ELLIPSE",
343
+ center: { x: Number(x), y: Number(y) },
344
+ radiusX: Number(radiusX),
345
+ radiusY: Number(radiusY),
346
+ color,
347
+ lineWidth: Number(lineWidth),
348
+ id
349
+ };
350
+ };
351
+ var EllipseShapeSchema = z2.string().startsWith("E~").transform(parseEllipse).pipe(EllipseShapeOutputSchema);
352
+ var PinShapeOutputSchema = z2.object({
353
+ type: z2.literal("PIN"),
354
+ visibility: z2.enum(["show", "hide"]),
355
+ pinNumber: z2.union([z2.string(), z2.number()]),
356
+ x: z2.number(),
357
+ y: z2.number(),
358
+ rotation: z2.number(),
359
+ id: z2.string(),
360
+ label: z2.string(),
361
+ labelColor: z2.string(),
362
+ path: z2.string(),
363
+ arrow: z2.string()
364
+ });
365
+ var parsePin = (pinString) => {
366
+ const parts = pinString.split("~");
367
+ const [, visibility, , pinNumber, x, y, rotation2, id] = parts;
368
+ const nameMatch = pinString.match(/~(\w+)~(start|end)~/);
369
+ const label = nameMatch ? nameMatch[1] : "";
370
+ const colorMatch = pinString.match(/#[0-9A-F]{6}/);
371
+ const labelColor = colorMatch ? colorMatch[0] : "";
372
+ const pathMatch = pinString.match(/\^\^([^~]+)/);
373
+ const path = pathMatch ? pathMatch[1] : "";
374
+ const arrowMatch = pinString.match(/\^\^0~(.+)$/);
375
+ const arrow = arrowMatch ? arrowMatch[1] : "";
376
+ return {
377
+ type: "PIN",
378
+ visibility,
379
+ id,
380
+ pinNumber: isNaN(Number(pinNumber)) ? pinNumber : Number(pinNumber),
381
+ x: parseFloat(x),
382
+ y: parseFloat(y),
383
+ rotation: parseFloat(rotation2),
384
+ label,
385
+ labelColor,
386
+ path,
387
+ arrow
388
+ };
389
+ };
390
+ var PinShapeSchema = z2.string().startsWith("P~").transform(parsePin).pipe(PinShapeOutputSchema);
391
+ var PolylineShapeOutputSchema = z2.object({
392
+ type: z2.literal("POLYLINE"),
393
+ points: z2.array(PointSchema2),
394
+ color: z2.string(),
395
+ lineWidth: z2.number(),
396
+ id: z2.string()
397
+ });
398
+ var parsePoints2 = (pointsStr) => {
399
+ return pointsStr.split(" ").reduce((acc, value, index) => {
400
+ if (index % 2 === 0) {
401
+ acc.push({ x: Number(value), y: 0 });
402
+ } else {
403
+ acc[acc.length - 1].y = Number(value);
404
+ }
405
+ return acc;
406
+ }, []);
407
+ };
408
+ var parsePolyline = (str) => {
409
+ const [, ...rest] = str.split("~");
410
+ const [pointsStr, color, lineWidth, , , id] = rest;
411
+ return {
412
+ type: "POLYLINE",
413
+ points: parsePoints2(pointsStr),
414
+ color,
415
+ lineWidth: Number(lineWidth),
416
+ id
417
+ };
418
+ };
419
+ var PolylineShapeSchema = z2.string().startsWith("PL~").transform(parsePolyline).pipe(PolylineShapeOutputSchema);
420
+ var PolygonShapeOutputSchema = z2.object({
421
+ type: z2.literal("POLYGON"),
422
+ points: z2.array(PointSchema2),
423
+ fillColor: z2.string(),
424
+ lineWidth: z2.number(),
425
+ lineColor: z2.string(),
426
+ id: z2.string()
427
+ });
428
+ var parsePolygon = (str) => {
429
+ const [, ...rest] = str.split("~");
430
+ const [pointsStr, fillColor, lineWidth, lineColor, , id] = rest;
431
+ return {
432
+ type: "POLYGON",
433
+ points: parsePoints2(pointsStr),
434
+ fillColor,
435
+ lineWidth: Number(lineWidth),
436
+ lineColor,
437
+ id
438
+ };
439
+ };
440
+ var PolygonShapeSchema = z2.string().startsWith("PG~").transform(parsePolygon).pipe(PolygonShapeOutputSchema);
441
+ var PathShapeOutputSchema = z2.object({
442
+ type: z2.literal("PATH"),
443
+ pathData: z2.string(),
444
+ fillColor: z2.string(),
445
+ strokeWidth: z2.number(),
446
+ strokeColor: z2.string(),
447
+ id: z2.string()
448
+ });
449
+ var parsePath = (str) => {
450
+ const [, pathData, fillColor, strokeWidth, strokeColor, , id] = str.split("~");
451
+ return {
452
+ type: "PATH",
453
+ pathData,
454
+ fillColor,
455
+ strokeWidth: mil10ToMm(Number(strokeWidth)),
456
+ strokeColor,
457
+ id
458
+ };
459
+ };
460
+ var PathShapeSchema = z2.string().startsWith("PT~").transform(parsePath).pipe(PathShapeOutputSchema);
461
+ var TextShapeOutputSchema = z2.object({
462
+ type: z2.literal("TEXT"),
463
+ alignment: z2.enum(["L", "C", "R"]),
464
+ x: z2.number(),
465
+ y: z2.number(),
466
+ rotation: z2.number(),
467
+ fontColor: z2.string(),
468
+ backgroundColor: z2.string().optional(),
469
+ fontSize: z2.string(),
470
+ fontWeight: z2.enum(["normal", "bold"]).optional().default("normal"),
471
+ fontStyle: z2.enum(["normal", "italic"]).optional().default("normal"),
472
+ fontDecoration: z2.enum(["", "underline"]),
473
+ content: z2.string(),
474
+ textType: z2.string(),
475
+ visibility: z2.enum(["0", "1"]),
476
+ mirror: z2.string(),
477
+ id: z2.string()
478
+ });
479
+ var parseText = (str) => {
480
+ const [
481
+ ,
482
+ alignment,
483
+ x,
484
+ y,
485
+ rotation2,
486
+ fontColor,
487
+ backgroundColor,
488
+ fontSize,
489
+ fontWeight,
490
+ fontStyle,
491
+ fontDecoration,
492
+ content,
493
+ textType,
494
+ visibility,
495
+ mirror,
496
+ id
497
+ ] = str.split("~");
498
+ return {
499
+ type: "TEXT",
500
+ alignment,
501
+ x: Number(x),
502
+ y: Number(y),
503
+ rotation: Number(rotation2),
504
+ fontColor,
505
+ backgroundColor: backgroundColor || void 0,
506
+ fontSize,
507
+ fontWeight: fontWeight || "normal",
508
+ fontStyle: fontStyle || "normal",
509
+ fontDecoration,
510
+ content,
511
+ textType,
512
+ visibility,
513
+ mirror,
514
+ id
515
+ };
516
+ };
517
+ var TextShapeSchema = z2.string().startsWith("T~").transform(parseText).pipe(TextShapeOutputSchema);
518
+ var SingleLetterShapeSchema = z2.string().transform((x) => {
519
+ if (x.startsWith("R~")) return RectangleShapeSchema.parse(x);
520
+ if (x.startsWith("E~")) return EllipseShapeSchema.parse(x);
521
+ if (x.startsWith("P~")) return PinShapeSchema.parse(x);
522
+ if (x.startsWith("PL~")) return PolylineShapeSchema.parse(x);
523
+ if (x.startsWith("PG~")) return PolygonShapeSchema.parse(x);
524
+ if (x.startsWith("PT~")) return PathShapeSchema.parse(x);
525
+ if (x.startsWith("T~")) return TextShapeSchema.parse(x);
526
+ throw new Error(`Invalid shape type: ${x}`);
527
+ }).pipe(
528
+ z2.union([
529
+ RectangleShapeOutputSchema,
530
+ EllipseShapeOutputSchema,
531
+ PinShapeOutputSchema,
532
+ PolylineShapeOutputSchema,
533
+ PolygonShapeOutputSchema,
534
+ PathShapeOutputSchema,
535
+ TextShapeOutputSchema
536
+ ])
537
+ );
538
+
539
+ // lib/schemas/easy-eda-json-schema.ts
540
+ var maybeNumber = z3.any().transform((k) => k === "nan" || Number.isNaN(k) ? null : k).pipe(z3.number().nullable().optional());
541
+ var SzlcscSchema = z3.object({
542
+ id: z3.number(),
543
+ number: z3.string(),
544
+ step: z3.number().optional(),
545
+ min: z3.number().optional(),
546
+ price: z3.number().optional(),
547
+ stock: z3.number().optional(),
548
+ url: z3.string().url().optional(),
549
+ image: z3.string().optional().optional()
550
+ });
551
+ var LcscSchema = z3.object({
552
+ id: z3.number(),
553
+ number: z3.string(),
554
+ step: z3.number().optional(),
555
+ min: z3.number().optional(),
556
+ price: z3.number().optional(),
557
+ stock: z3.number().optional(),
558
+ url: z3.string().url().optional()
559
+ });
560
+ var OwnerSchema = z3.object({
561
+ uuid: z3.string(),
562
+ username: z3.string(),
563
+ nickname: z3.string(),
564
+ avatar: z3.string()
565
+ });
566
+ var HeadSchema = z3.object({
567
+ docType: z3.string(),
568
+ editorVersion: z3.string(),
569
+ c_para: z3.record(z3.string(), z3.string()),
570
+ x: z3.number(),
571
+ y: z3.number(),
572
+ puuid: z3.string().optional(),
573
+ uuid: z3.string(),
574
+ utime: z3.number(),
575
+ importFlag: z3.number().optional(),
576
+ c_spiceCmd: z3.any().optional(),
577
+ hasIdFlag: z3.boolean()
578
+ });
579
+ var BBoxSchema = z3.object({
580
+ x: z3.number(),
581
+ y: z3.number(),
582
+ width: z3.number(),
583
+ height: z3.number()
584
+ });
585
+ var LayerItemSchema = z3.object({
586
+ name: z3.string(),
587
+ color: z3.string(),
588
+ visible: z3.boolean(),
589
+ active: z3.boolean(),
590
+ config: z3.boolean(),
591
+ transparency: z3.boolean()
592
+ });
593
+ var ObjectItemSchema = z3.object({
594
+ name: z3.string(),
595
+ visible: z3.boolean(),
596
+ locked: z3.boolean()
597
+ });
598
+ var DataStrSchema = z3.object({
599
+ head: HeadSchema,
600
+ canvas: z3.string(),
601
+ shape: z3.array(SingleLetterShapeSchema),
602
+ BBox: BBoxSchema,
603
+ colors: z3.array(z3.unknown())
604
+ });
605
+ var PackageDetailDataStrSchema = z3.object({
606
+ head: HeadSchema,
607
+ canvas: z3.string(),
608
+ shape: z3.array(z3.string()).transform(
609
+ (shapes) => shapes.map((shape) => {
610
+ const [type, ...data] = shape.split("~");
611
+ return ShapeItemSchema.parse({ type, data: data.join("~") });
612
+ })
613
+ ).pipe(z3.array(PackageDetailShapeSchema)),
614
+ layers: z3.array(z3.string()).transform(
615
+ (layers) => layers.map((layer) => {
616
+ const [name, color, visible, active, config, transparency] = layer.split("~");
617
+ return LayerItemSchema.parse({
618
+ name,
619
+ color,
620
+ visible: visible === "true",
621
+ active: active === "true",
622
+ config: config === "true",
623
+ transparency: transparency === "true"
624
+ });
625
+ })
626
+ ),
627
+ objects: z3.array(z3.string()).transform(
628
+ (objects) => objects.map((obj) => {
629
+ const [name, visible, locked] = obj.split("~");
630
+ return ObjectItemSchema.parse({
631
+ name,
632
+ visible: visible === "true",
633
+ locked: locked === "true"
634
+ });
635
+ })
636
+ ),
637
+ BBox: BBoxSchema,
638
+ netColors: z3.array(z3.unknown()).optional()
639
+ });
640
+ var PackageDetailSchema = z3.object({
641
+ uuid: z3.string(),
642
+ title: z3.string(),
643
+ docType: z3.number(),
644
+ updateTime: z3.number(),
645
+ owner: OwnerSchema,
646
+ datastrid: z3.string(),
647
+ writable: z3.boolean(),
648
+ dataStr: PackageDetailDataStrSchema
649
+ });
650
+ var EasyEdaJsonSchema = z3.object({
651
+ uuid: z3.string(),
652
+ title: z3.string(),
653
+ description: z3.string(),
654
+ docType: z3.number(),
655
+ type: z3.number(),
656
+ szlcsc: SzlcscSchema,
657
+ lcsc: LcscSchema,
658
+ owner: OwnerSchema,
659
+ tags: z3.array(z3.string()),
660
+ updateTime: z3.number(),
661
+ updated_at: z3.string(),
662
+ dataStr: DataStrSchema,
663
+ verify: z3.boolean(),
664
+ SMT: z3.boolean().optional(),
665
+ datastrid: z3.string(),
666
+ jlcOnSale: z3.number().optional(),
667
+ writable: z3.boolean(),
668
+ isFavorite: z3.boolean(),
669
+ packageDetail: PackageDetailSchema
670
+ });
671
+
672
+ // node_modules/circuit-json/dist/index.mjs
673
+ var dist_exports = {};
674
+ __export(dist_exports, {
675
+ all_layers: () => all_layers,
676
+ any_circuit_element: () => any_circuit_element,
677
+ any_soup_element: () => any_soup_element,
678
+ any_source_component: () => any_source_component,
679
+ battery_capacity: () => battery_capacity,
680
+ cad_component: () => cad_component,
681
+ capacitance: () => capacitance,
682
+ current: () => current,
683
+ distance: () => distance,
684
+ frequency: () => frequency,
685
+ getZodPrefixedIdWithDefault: () => getZodPrefixedIdWithDefault,
686
+ inductance: () => inductance,
687
+ layer_ref: () => layer_ref,
688
+ layer_string: () => layer_string,
689
+ length: () => length,
690
+ pcb_autorouting_error: () => pcb_autorouting_error,
691
+ pcb_board: () => pcb_board,
692
+ pcb_component: () => pcb_component,
693
+ pcb_fabrication_note_path: () => pcb_fabrication_note_path,
694
+ pcb_fabrication_note_text: () => pcb_fabrication_note_text,
695
+ pcb_group: () => pcb_group,
696
+ pcb_hole: () => pcb_hole,
697
+ pcb_hole_circle_or_square_shape: () => pcb_hole_circle_or_square_shape,
698
+ pcb_hole_oval_shape: () => pcb_hole_oval_shape,
699
+ pcb_keepout: () => pcb_keepout,
700
+ pcb_manual_edit_conflict_error: () => pcb_manual_edit_conflict_error,
701
+ pcb_missing_footprint_error: () => pcb_missing_footprint_error,
702
+ pcb_placement_error: () => pcb_placement_error,
703
+ pcb_plated_hole: () => pcb_plated_hole,
704
+ pcb_port: () => pcb_port,
705
+ pcb_port_not_matched_error: () => pcb_port_not_matched_error,
706
+ pcb_route_hint: () => pcb_route_hint,
707
+ pcb_route_hints: () => pcb_route_hints,
708
+ pcb_silkscreen_circle: () => pcb_silkscreen_circle,
709
+ pcb_silkscreen_line: () => pcb_silkscreen_line,
710
+ pcb_silkscreen_oval: () => pcb_silkscreen_oval,
711
+ pcb_silkscreen_path: () => pcb_silkscreen_path,
712
+ pcb_silkscreen_rect: () => pcb_silkscreen_rect,
713
+ pcb_silkscreen_text: () => pcb_silkscreen_text,
714
+ pcb_smtpad: () => pcb_smtpad,
715
+ pcb_smtpad_pill: () => pcb_smtpad_pill,
716
+ pcb_solder_paste: () => pcb_solder_paste,
717
+ pcb_text: () => pcb_text,
718
+ pcb_trace: () => pcb_trace,
719
+ pcb_trace_error: () => pcb_trace_error,
720
+ pcb_trace_hint: () => pcb_trace_hint,
721
+ pcb_trace_route_point: () => pcb_trace_route_point,
722
+ pcb_trace_route_point_via: () => pcb_trace_route_point_via,
723
+ pcb_trace_route_point_wire: () => pcb_trace_route_point_wire,
724
+ pcb_via: () => pcb_via,
725
+ point: () => point,
726
+ point3: () => point3,
727
+ port_arrangement: () => port_arrangement,
728
+ position: () => position,
729
+ position3: () => position3,
730
+ resistance: () => resistance,
731
+ rotation: () => rotation,
732
+ route_hint_point: () => route_hint_point,
733
+ schematic_box: () => schematic_box,
734
+ schematic_component: () => schematic_component,
735
+ schematic_component_port_arrangement_by_sides: () => schematic_component_port_arrangement_by_sides,
736
+ schematic_component_port_arrangement_by_size: () => schematic_component_port_arrangement_by_size,
737
+ schematic_debug_line: () => schematic_debug_line,
738
+ schematic_debug_object: () => schematic_debug_object,
739
+ schematic_debug_object_base: () => schematic_debug_object_base,
740
+ schematic_debug_point: () => schematic_debug_point,
741
+ schematic_debug_rect: () => schematic_debug_rect,
742
+ schematic_error: () => schematic_error,
743
+ schematic_line: () => schematic_line,
744
+ schematic_net_label: () => schematic_net_label,
745
+ schematic_path: () => schematic_path,
746
+ schematic_pin_styles: () => schematic_pin_styles,
747
+ schematic_port: () => schematic_port,
748
+ schematic_text: () => schematic_text,
749
+ schematic_trace: () => schematic_trace,
750
+ schematic_voltage_probe: () => schematic_voltage_probe,
751
+ size: () => size,
752
+ source_component_base: () => source_component_base,
753
+ source_group: () => source_group,
754
+ source_led: () => source_led,
755
+ source_net: () => source_net,
756
+ source_port: () => source_port,
757
+ source_project_metadata: () => source_project_metadata,
758
+ source_simple_battery: () => source_simple_battery,
759
+ source_simple_bug: () => source_simple_bug,
760
+ source_simple_capacitor: () => source_simple_capacitor,
761
+ source_simple_chip: () => source_simple_chip,
762
+ source_simple_crystal: () => source_simple_crystal,
763
+ source_simple_diode: () => source_simple_diode,
764
+ source_simple_ground: () => source_simple_ground,
765
+ source_simple_inductor: () => source_simple_inductor,
766
+ source_simple_mosfet: () => source_simple_mosfet,
767
+ source_simple_pin_header: () => source_simple_pin_header,
768
+ source_simple_potentiometer: () => source_simple_potentiometer,
769
+ source_simple_power_source: () => source_simple_power_source,
770
+ source_simple_push_button: () => source_simple_push_button,
771
+ source_simple_resistor: () => source_simple_resistor,
772
+ source_simple_resonator: () => source_simple_resonator,
773
+ source_simple_switch: () => source_simple_switch,
774
+ source_simple_transistor: () => source_simple_transistor,
775
+ source_trace: () => source_trace,
776
+ supplier_name: () => supplier_name,
777
+ time: () => time,
778
+ visible_layer: () => visible_layer,
779
+ voltage: () => voltage
780
+ });
781
+ import { z as z4 } from "zod";
782
+ import { z as z22 } from "zod";
783
+ import { z as z32 } from "zod";
784
+ import { z as z42 } from "zod";
785
+ import { z as z5 } from "zod";
786
+
787
+ // node_modules/nanoid/url-alphabet/index.js
788
+ var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
789
+
790
+ // node_modules/nanoid/index.browser.js
791
+ var nanoid = (size2 = 21) => {
792
+ let id = "";
793
+ let bytes = crypto.getRandomValues(new Uint8Array(size2));
794
+ while (size2--) {
795
+ id += urlAlphabet[bytes[size2] & 63];
796
+ }
797
+ return id;
798
+ };
799
+
800
+ // node_modules/circuit-json/dist/index.mjs
801
+ import { z as z8 } from "zod";
802
+ import { z as z6 } from "zod";
803
+ import { z as z7 } from "zod";
804
+ import { z as z9 } from "zod";
805
+ import { z as z10 } from "zod";
806
+ import { z as z11 } from "zod";
807
+ import { z as z12 } from "zod";
808
+ import { z as z13 } from "zod";
809
+ import { z as z14 } from "zod";
810
+ import { z as z15 } from "zod";
811
+ import { z as z27 } from "zod";
812
+ import { z as z16 } from "zod";
813
+ import { z as z17 } from "zod";
814
+ import { z as z18 } from "zod";
815
+ import { z as z19 } from "zod";
816
+ import { z as z20 } from "zod";
817
+ import { z as z21 } from "zod";
818
+ import { z as z222 } from "zod";
819
+ import { z as z23 } from "zod";
820
+ import { z as z24 } from "zod";
821
+ import { z as z25 } from "zod";
822
+ import { z as z26 } from "zod";
823
+ import { z as z28 } from "zod";
824
+ import { z as z29 } from "zod";
825
+ import { z as z30 } from "zod";
826
+ import { z as z31 } from "zod";
827
+ import { z as z322 } from "zod";
828
+ import { z as z33 } from "zod";
829
+ import { z as z34 } from "zod";
830
+ import { z as z35 } from "zod";
831
+ import { z as z36 } from "zod";
832
+ import { z as z37 } from "zod";
833
+ import { z as z38 } from "zod";
834
+ import { z as z39 } from "zod";
835
+ import { z as z40 } from "zod";
836
+ import { z as z41 } from "zod";
837
+ import { z as z422 } from "zod";
838
+ import { z as z43 } from "zod";
839
+ import { z as z44 } from "zod";
840
+ import { z as z45 } from "zod";
841
+ import { z as z46 } from "zod";
842
+ import { z as z47 } from "zod";
843
+ import { z as z48 } from "zod";
844
+ import { z as z49 } from "zod";
845
+ import { z as z50 } from "zod";
846
+ import { z as z51 } from "zod";
847
+ import { z as z52 } from "zod";
848
+ import { z as z53 } from "zod";
849
+ import { z as z54 } from "zod";
850
+ import { z as z55 } from "zod";
851
+ import { z as z56 } from "zod";
852
+ import { z as z57 } from "zod";
853
+ import { z as z58 } from "zod";
854
+ import { z as z59 } from "zod";
855
+ import { z as z60 } from "zod";
856
+ import { z as z61 } from "zod";
857
+ import { z as z62 } from "zod";
858
+ import { z as z63 } from "zod";
859
+ import { z as z64 } from "zod";
860
+ import { z as z65 } from "zod";
861
+ import { z as z66 } from "zod";
862
+ import { z as z67 } from "zod";
863
+ import { z as z68 } from "zod";
864
+ import { z as z69 } from "zod";
865
+ import { z as z70 } from "zod";
866
+ import { z as z71 } from "zod";
867
+ import { z as z72 } from "zod";
868
+ import { z as z73 } from "zod";
869
+ import { z as z74 } from "zod";
870
+ var unitMappings = {
871
+ Hz: {
872
+ baseUnit: "Hz",
873
+ variants: {
874
+ MHz: 1e6,
875
+ kHz: 1e3,
876
+ Hz: 1
877
+ }
878
+ },
879
+ g: {
880
+ baseUnit: "g",
881
+ variants: {
882
+ kg: 1e3,
883
+ g: 1
884
+ }
885
+ },
886
+ \u03A9: {
887
+ baseUnit: "\u03A9",
888
+ variants: {
889
+ m\u03A9: 1e-3,
890
+ \u03A9: 1,
891
+ k\u03A9: 1e3,
892
+ K\u03A9: 1e3,
893
+ kohm: 1e3,
894
+ M\u03A9: 1e6,
895
+ G\u03A9: 1e9,
896
+ T\u03A9: 1e12
897
+ }
898
+ },
899
+ V: {
900
+ baseUnit: "V",
901
+ variants: {
902
+ mV: 1e-3,
903
+ V: 1,
904
+ kV: 1e3,
905
+ KV: 1e3,
906
+ MV: 1e6,
907
+ GV: 1e9,
908
+ TV: 1e12
909
+ }
910
+ },
911
+ A: {
912
+ baseUnit: "A",
913
+ variants: {
914
+ \u00B5A: 1e-6,
915
+ mA: 1e-3,
916
+ ma: 1e-3,
917
+ A: 1,
918
+ kA: 1e3,
919
+ MA: 1e6
920
+ }
921
+ },
922
+ F: {
923
+ baseUnit: "F",
924
+ variants: {
925
+ pF: 1e-12,
926
+ nF: 1e-9,
927
+ \u00B5F: 1e-6,
928
+ uF: 1e-6,
929
+ mF: 1e-3,
930
+ F: 1
931
+ }
932
+ },
933
+ ml: {
934
+ baseUnit: "ml",
935
+ variants: {
936
+ ml: 1,
937
+ mL: 1,
938
+ l: 1e3,
939
+ L: 1e3
940
+ }
941
+ },
942
+ deg: {
943
+ baseUnit: "deg",
944
+ variants: {
945
+ rad: 180 / Math.PI
946
+ }
947
+ },
948
+ ms: {
949
+ baseUnit: "ms",
950
+ variants: {
951
+ s: 1e3
952
+ }
953
+ },
954
+ mm: {
955
+ baseUnit: "mm",
956
+ variants: {
957
+ nm: 1e-6,
958
+ \u00B5m: 1e-3,
959
+ um: 1e-3,
960
+ mm: 1,
961
+ cm: 10,
962
+ dm: 100,
963
+ m: 1e3,
964
+ km: 1e6,
965
+ in: 25.4,
966
+ ft: 304.8,
967
+ IN: 25.4,
968
+ FT: 304.8,
969
+ yd: 914.4,
970
+ mi: 1609344,
971
+ mil: 0.0254
972
+ }
973
+ }
974
+ };
975
+ var unitMappingAndVariantSuffixes = /* @__PURE__ */ new Set();
976
+ for (const [baseUnit, info] of Object.entries(unitMappings)) {
977
+ unitMappingAndVariantSuffixes.add(baseUnit);
978
+ for (const variant of Object.keys(info.variants)) {
979
+ unitMappingAndVariantSuffixes.add(variant);
980
+ }
981
+ }
982
+ function getBaseTscircuitUnit(unit) {
983
+ for (const [baseUnit, info] of Object.entries(unitMappings)) {
984
+ if (unit in info.variants) {
985
+ return {
986
+ baseUnit: info.baseUnit,
987
+ conversionFactor: info.variants[unit]
988
+ };
989
+ }
990
+ }
991
+ return {
992
+ baseUnit: unit,
993
+ conversionFactor: 1
994
+ };
995
+ }
996
+ var si_prefix_multiplier = {
997
+ tera: 1e12,
998
+ T: 1e12,
999
+ giga: 1e9,
1000
+ G: 1e9,
1001
+ mega: 1e6,
1002
+ M: 1e6,
1003
+ kilo: 1e3,
1004
+ k: 1e3,
1005
+ deci: 0.1,
1006
+ d: 0.1,
1007
+ centi: 0.01,
1008
+ c: 0.01,
1009
+ milli: 1e-3,
1010
+ m: 1e-3,
1011
+ micro: 1e-6,
1012
+ u: 1e-6,
1013
+ \u00B5: 1e-6,
1014
+ nano: 1e-9,
1015
+ n: 1e-9,
1016
+ pico: 1e-12,
1017
+ p: 1e-12
1018
+ };
1019
+ var parseAndConvertSiUnit = (v) => {
1020
+ if (typeof v === "undefined")
1021
+ return { parsedUnit: null, unitOfValue: null, value: null };
1022
+ if (typeof v === "string" && v.match(/^-?[\d\.]+$/))
1023
+ return {
1024
+ value: Number.parseFloat(v),
1025
+ parsedUnit: null,
1026
+ unitOfValue: null
1027
+ };
1028
+ if (typeof v === "number")
1029
+ return { value: v, parsedUnit: null, unitOfValue: null };
1030
+ if (typeof v === "object" && "x" in v && "y" in v) {
1031
+ const { parsedUnit, unitOfValue } = parseAndConvertSiUnit(v.x);
1032
+ return {
1033
+ parsedUnit,
1034
+ unitOfValue,
1035
+ value: {
1036
+ x: parseAndConvertSiUnit(v.x).value,
1037
+ y: parseAndConvertSiUnit(v.y).value
1038
+ }
1039
+ };
1040
+ }
1041
+ const reversed_input_string = v.toString().split("").reverse().join("");
1042
+ const unit_reversed = reversed_input_string.match(/[^\d\s]+/)?.[0];
1043
+ if (!unit_reversed) {
1044
+ throw new Error(`Could not determine unit: "${v}"`);
1045
+ }
1046
+ const unit = unit_reversed.split("").reverse().join("");
1047
+ const numberPart = v.slice(0, -unit.length);
1048
+ if (unit in si_prefix_multiplier && !unitMappingAndVariantSuffixes.has(unit)) {
1049
+ const siMultiplier = si_prefix_multiplier[unit];
1050
+ return {
1051
+ parsedUnit: null,
1052
+ unitOfValue: null,
1053
+ value: Number.parseFloat(numberPart) * siMultiplier
1054
+ };
1055
+ }
1056
+ const { baseUnit, conversionFactor } = getBaseTscircuitUnit(unit);
1057
+ return {
1058
+ parsedUnit: unit,
1059
+ unitOfValue: baseUnit,
1060
+ value: conversionFactor * Number.parseFloat(numberPart)
1061
+ };
1062
+ };
1063
+ var resistance = z4.string().or(z4.number()).transform((v) => parseAndConvertSiUnit(v).value);
1064
+ var capacitance = z4.string().or(z4.number()).transform((v) => parseAndConvertSiUnit(v).value).transform((value) => {
1065
+ return Number.parseFloat(value.toPrecision(12));
1066
+ });
1067
+ var inductance = z4.string().or(z4.number()).transform((v) => parseAndConvertSiUnit(v).value);
1068
+ var voltage = z4.string().or(z4.number()).transform((v) => parseAndConvertSiUnit(v).value);
1069
+ var length = z4.string().or(z4.number()).transform((v) => parseAndConvertSiUnit(v).value);
1070
+ var frequency = z4.string().or(z4.number()).transform((v) => parseAndConvertSiUnit(v).value);
1071
+ var distance = length;
1072
+ var current = z4.string().or(z4.number()).transform((v) => parseAndConvertSiUnit(v).value);
1073
+ var time = z4.string().or(z4.number()).transform((v) => parseAndConvertSiUnit(v).value);
1074
+ var rotation = z4.string().or(z4.number()).transform((arg) => {
1075
+ if (typeof arg === "number") return arg;
1076
+ if (arg.endsWith("deg")) {
1077
+ return Number.parseFloat(arg.split("deg")[0]);
1078
+ }
1079
+ if (arg.endsWith("rad")) {
1080
+ return Number.parseFloat(arg.split("rad")[0]) * 180 / Math.PI;
1081
+ }
1082
+ return Number.parseFloat(arg);
1083
+ });
1084
+ var battery_capacity = z4.number().or(z4.string().endsWith("mAh")).transform((v) => {
1085
+ if (typeof v === "string") {
1086
+ const valString = v.replace("mAh", "");
1087
+ const num = Number.parseFloat(valString);
1088
+ if (Number.isNaN(num)) {
1089
+ throw new Error("Invalid capacity");
1090
+ }
1091
+ return num;
1092
+ }
1093
+ return v;
1094
+ }).describe("Battery capacity in mAh");
1095
+ var point = z22.object({
1096
+ x: distance,
1097
+ y: distance
1098
+ });
1099
+ var position = point;
1100
+ var point3 = z32.object({
1101
+ x: distance,
1102
+ y: distance,
1103
+ z: distance
1104
+ });
1105
+ var position3 = point3;
1106
+ var size = z42.object({
1107
+ width: z42.number(),
1108
+ height: z42.number()
1109
+ });
1110
+ var getZodPrefixedIdWithDefault = (prefix) => {
1111
+ return z5.string().optional().default(() => `${prefix}_${nanoid(10)}`);
1112
+ };
1113
+ var supplier_name = z6.enum([
1114
+ "jlcpcb",
1115
+ "macrofab",
1116
+ "pcbway",
1117
+ "digikey",
1118
+ "mouser",
1119
+ "lcsc"
1120
+ ]);
1121
+ var expectTypesMatch = (shouldBe) => {
1122
+ };
1123
+ expectTypesMatch("extra props b");
1124
+ expectTypesMatch("missing props b");
1125
+ expectTypesMatch(true);
1126
+ expectTypesMatch("mismatched prop types: a");
1127
+ var source_component_base = z7.object({
1128
+ type: z7.literal("source_component"),
1129
+ ftype: z7.string().optional(),
1130
+ source_component_id: z7.string(),
1131
+ name: z7.string(),
1132
+ manufacturer_part_number: z7.string().optional(),
1133
+ supplier_part_numbers: z7.record(supplier_name, z7.array(z7.string())).optional(),
1134
+ display_value: z7.string().optional()
1135
+ });
1136
+ expectTypesMatch(true);
1137
+ var source_simple_capacitor = source_component_base.extend({
1138
+ ftype: z8.literal("simple_capacitor"),
1139
+ capacitance,
1140
+ max_voltage_rating: voltage.optional(),
1141
+ display_capacitance: z8.string().optional(),
1142
+ max_decoupling_trace_length: distance.optional()
1143
+ });
1144
+ expectTypesMatch(true);
1145
+ var source_simple_resistor = source_component_base.extend({
1146
+ ftype: z9.literal("simple_resistor"),
1147
+ resistance,
1148
+ display_resistance: z9.string().optional()
1149
+ });
1150
+ expectTypesMatch(true);
1151
+ var source_simple_diode = source_component_base.extend({
1152
+ ftype: z10.literal("simple_diode")
1153
+ });
1154
+ expectTypesMatch(true);
1155
+ var source_simple_ground = source_component_base.extend({
1156
+ ftype: z11.literal("simple_ground")
1157
+ });
1158
+ expectTypesMatch(true);
1159
+ var source_simple_bug = source_component_base.extend({
1160
+ ftype: z12.literal("simple_bug")
1161
+ }).describe("@deprecated");
1162
+ var source_simple_chip = source_component_base.extend({
1163
+ ftype: z13.literal("simple_chip")
1164
+ });
1165
+ expectTypesMatch(true);
1166
+ var source_led = source_simple_diode.extend({
1167
+ ftype: z14.literal("led")
1168
+ });
1169
+ expectTypesMatch(true);
1170
+ var source_simple_power_source = source_component_base.extend({
1171
+ ftype: z15.literal("simple_power_source"),
1172
+ voltage
1173
+ });
1174
+ expectTypesMatch(true);
1175
+ var source_simple_battery = source_component_base.extend({
1176
+ ftype: z16.literal("simple_battery"),
1177
+ capacity: battery_capacity
1178
+ });
1179
+ expectTypesMatch(true);
1180
+ var source_simple_inductor = source_component_base.extend({
1181
+ ftype: z17.literal("simple_inductor"),
1182
+ inductance
1183
+ });
1184
+ expectTypesMatch(true);
1185
+ var source_simple_push_button = source_component_base.extend({
1186
+ ftype: z18.literal("simple_push_button")
1187
+ });
1188
+ expectTypesMatch(true);
1189
+ var source_simple_potentiometer = source_component_base.extend({
1190
+ ftype: z19.literal("simple_potentiometer"),
1191
+ max_resistance: resistance
1192
+ });
1193
+ var source_simple_crystal = source_component_base.extend({
1194
+ ftype: z20.literal("simple_crystal"),
1195
+ frequency: z20.number().describe("Frequency in Hz"),
1196
+ load_capacitance: z20.number().optional().describe("Load capacitance in pF")
1197
+ });
1198
+ expectTypesMatch(true);
1199
+ var source_simple_pin_header = source_component_base.extend({
1200
+ ftype: z21.literal("simple_pin_header"),
1201
+ pin_count: z21.number(),
1202
+ gender: z21.enum(["male", "female"]).optional().default("male")
1203
+ });
1204
+ var source_simple_resonator = source_component_base.extend({
1205
+ ftype: z222.literal("simple_resonator"),
1206
+ load_capacitance: capacitance,
1207
+ equivalent_series_resistance: resistance.optional(),
1208
+ frequency
1209
+ });
1210
+ expectTypesMatch(true);
1211
+ var source_simple_transistor = source_component_base.extend({
1212
+ ftype: z23.literal("simple_transistor"),
1213
+ transistor_type: z23.enum(["npn", "pnp"])
1214
+ });
1215
+ expectTypesMatch(true);
1216
+ var source_simple_mosfet = source_component_base.extend({
1217
+ ftype: z24.literal("simple_mosfet"),
1218
+ channel_type: z24.enum(["n", "p"]),
1219
+ mosfet_mode: z24.enum(["enhancement", "depletion"])
1220
+ });
1221
+ expectTypesMatch(true);
1222
+ var source_simple_switch = source_component_base.extend({
1223
+ ftype: z25.literal("simple_switch")
1224
+ });
1225
+ expectTypesMatch(true);
1226
+ var source_project_metadata = z26.object({
1227
+ type: z26.literal("source_project_metadata"),
1228
+ name: z26.string().optional(),
1229
+ software_used_string: z26.string().optional(),
1230
+ created_at: z26.string().datetime().optional()
1231
+ });
1232
+ expectTypesMatch(true);
1233
+ var any_source_component = z27.union([
1234
+ source_simple_resistor,
1235
+ source_simple_capacitor,
1236
+ source_simple_diode,
1237
+ source_simple_ground,
1238
+ source_simple_chip,
1239
+ source_simple_bug,
1240
+ source_led,
1241
+ source_simple_power_source,
1242
+ source_simple_battery,
1243
+ source_simple_inductor,
1244
+ source_simple_push_button,
1245
+ source_simple_potentiometer,
1246
+ source_simple_crystal,
1247
+ source_simple_pin_header,
1248
+ source_simple_resonator,
1249
+ source_simple_switch,
1250
+ source_simple_transistor,
1251
+ source_simple_mosfet,
1252
+ source_project_metadata
1253
+ ]);
1254
+ var source_port = z28.object({
1255
+ type: z28.literal("source_port"),
1256
+ pin_number: z28.number().optional(),
1257
+ port_hints: z28.array(z28.string()).optional(),
1258
+ name: z28.string(),
1259
+ source_port_id: z28.string(),
1260
+ source_component_id: z28.string(),
1261
+ subcircuit_id: z28.string().optional()
1262
+ });
1263
+ expectTypesMatch(true);
1264
+ var source_trace = z29.object({
1265
+ type: z29.literal("source_trace"),
1266
+ source_trace_id: z29.string(),
1267
+ connected_source_port_ids: z29.array(z29.string()),
1268
+ connected_source_net_ids: z29.array(z29.string()),
1269
+ subcircuit_id: z29.string().optional(),
1270
+ subcircuit_connectivity_map_key: z29.string().optional(),
1271
+ max_length: z29.number().optional(),
1272
+ min_trace_thickness: z29.number().optional(),
1273
+ display_name: z29.string().optional()
1274
+ });
1275
+ expectTypesMatch(true);
1276
+ var source_group = z30.object({
1277
+ type: z30.literal("source_group"),
1278
+ source_group_id: z30.string(),
1279
+ subcircuit_id: z30.string().optional(),
1280
+ parent_subcircuit_id: z30.string().optional(),
1281
+ is_subcircuit: z30.boolean().optional(),
1282
+ name: z30.string().optional()
1283
+ });
1284
+ var source_net = z31.object({
1285
+ type: z31.literal("source_net"),
1286
+ source_net_id: z31.string(),
1287
+ name: z31.string(),
1288
+ member_source_group_ids: z31.array(z31.string()),
1289
+ is_power: z31.boolean().optional(),
1290
+ is_ground: z31.boolean().optional(),
1291
+ is_digital_signal: z31.boolean().optional(),
1292
+ is_analog_signal: z31.boolean().optional(),
1293
+ trace_width: z31.number().optional(),
1294
+ subcircuit_id: z31.string().optional()
1295
+ });
1296
+ var schematic_box = z322.object({
1297
+ type: z322.literal("schematic_box"),
1298
+ schematic_component_id: z322.string(),
1299
+ width: distance,
1300
+ height: distance,
1301
+ x: distance,
1302
+ y: distance
1303
+ }).describe("Draws a box on the schematic");
1304
+ expectTypesMatch(true);
1305
+ var schematic_path = z33.object({
1306
+ type: z33.literal("schematic_path"),
1307
+ schematic_component_id: z33.string(),
1308
+ fill_color: z33.enum(["red", "blue"]).optional(),
1309
+ is_filled: z33.boolean().optional(),
1310
+ points: z33.array(point)
1311
+ });
1312
+ expectTypesMatch(true);
1313
+ var schematic_pin_styles = z34.record(
1314
+ z34.object({
1315
+ left_margin: length.optional(),
1316
+ right_margin: length.optional(),
1317
+ top_margin: length.optional(),
1318
+ bottom_margin: length.optional()
1319
+ })
1320
+ );
1321
+ var schematic_component_port_arrangement_by_size = z34.object({
1322
+ left_size: z34.number(),
1323
+ right_size: z34.number(),
1324
+ top_size: z34.number().optional(),
1325
+ bottom_size: z34.number().optional()
1326
+ });
1327
+ expectTypesMatch(true);
1328
+ var schematic_component_port_arrangement_by_sides = z34.object({
1329
+ left_side: z34.object({
1330
+ pins: z34.array(z34.number()),
1331
+ // @ts-ignore
1332
+ direction: z34.enum(["top-to-bottom", "bottom-to-top"]).optional()
1333
+ }).optional(),
1334
+ right_side: z34.object({
1335
+ pins: z34.array(z34.number()),
1336
+ // @ts-ignore
1337
+ direction: z34.enum(["top-to-bottom", "bottom-to-top"]).optional()
1338
+ }).optional(),
1339
+ top_side: z34.object({
1340
+ pins: z34.array(z34.number()),
1341
+ // @ts-ignore
1342
+ direction: z34.enum(["left-to-right", "right-to-left"]).optional()
1343
+ }).optional(),
1344
+ bottom_side: z34.object({
1345
+ pins: z34.array(z34.number()),
1346
+ // @ts-ignore
1347
+ direction: z34.enum(["left-to-right", "right-to-left"]).optional()
1348
+ }).optional()
1349
+ });
1350
+ expectTypesMatch(true);
1351
+ var port_arrangement = z34.union([
1352
+ schematic_component_port_arrangement_by_size,
1353
+ schematic_component_port_arrangement_by_sides
1354
+ ]);
1355
+ var schematic_component = z34.object({
1356
+ type: z34.literal("schematic_component"),
1357
+ size,
1358
+ center: point,
1359
+ source_component_id: z34.string(),
1360
+ schematic_component_id: z34.string(),
1361
+ pin_spacing: length.optional(),
1362
+ pin_styles: schematic_pin_styles.optional(),
1363
+ box_width: length.optional(),
1364
+ symbol_name: z34.string().optional(),
1365
+ port_arrangement: port_arrangement.optional(),
1366
+ port_labels: z34.record(z34.string()).optional(),
1367
+ symbol_display_value: z34.string().optional()
1368
+ });
1369
+ expectTypesMatch(true);
1370
+ var schematic_line = z35.object({
1371
+ type: z35.literal("schematic_line"),
1372
+ schematic_component_id: z35.string(),
1373
+ x1: distance,
1374
+ x2: distance,
1375
+ y1: distance,
1376
+ y2: distance
1377
+ });
1378
+ expectTypesMatch(true);
1379
+ var schematic_trace = z36.object({
1380
+ type: z36.literal("schematic_trace"),
1381
+ schematic_trace_id: z36.string(),
1382
+ source_trace_id: z36.string(),
1383
+ junctions: z36.array(
1384
+ z36.object({
1385
+ x: z36.number(),
1386
+ y: z36.number()
1387
+ })
1388
+ ),
1389
+ edges: z36.array(
1390
+ z36.object({
1391
+ from: z36.object({
1392
+ x: z36.number(),
1393
+ y: z36.number()
1394
+ }),
1395
+ to: z36.object({
1396
+ x: z36.number(),
1397
+ y: z36.number()
1398
+ }),
1399
+ is_crossing: z36.boolean().optional(),
1400
+ from_schematic_port_id: z36.string().optional(),
1401
+ to_schematic_port_id: z36.string().optional()
1402
+ })
1403
+ )
1404
+ });
1405
+ expectTypesMatch(true);
1406
+ var schematic_text = z37.object({
1407
+ type: z37.literal("schematic_text"),
1408
+ schematic_component_id: z37.string(),
1409
+ schematic_text_id: z37.string(),
1410
+ text: z37.string(),
1411
+ position: z37.object({
1412
+ x: distance,
1413
+ y: distance
1414
+ }),
1415
+ rotation: z37.number().default(0),
1416
+ anchor: z37.enum(["center", "left", "right", "top", "bottom"]).default("center"),
1417
+ color: z37.string().default("#000000")
1418
+ });
1419
+ expectTypesMatch(true);
1420
+ var schematic_port = z38.object({
1421
+ type: z38.literal("schematic_port"),
1422
+ schematic_port_id: z38.string(),
1423
+ source_port_id: z38.string(),
1424
+ schematic_component_id: z38.string().optional(),
1425
+ center: point,
1426
+ facing_direction: z38.enum(["up", "down", "left", "right"]).optional(),
1427
+ distance_from_component_edge: z38.number().optional(),
1428
+ side_of_component: z38.enum(["top", "bottom", "left", "right"]).optional(),
1429
+ true_ccw_index: z38.number().optional(),
1430
+ pin_number: z38.number().optional(),
1431
+ display_pin_label: z38.string().optional()
1432
+ }).describe("Defines a port on a schematic component");
1433
+ expectTypesMatch(true);
1434
+ var schematic_net_label = z39.object({
1435
+ type: z39.literal("schematic_net_label"),
1436
+ source_net_id: z39.string(),
1437
+ center: point,
1438
+ anchor_position: point.optional(),
1439
+ anchor_side: z39.enum(["top", "bottom", "left", "right"]),
1440
+ text: z39.string(),
1441
+ symbol_name: z39.string().optional()
1442
+ });
1443
+ var schematic_error = z40.object({
1444
+ type: z40.literal("schematic_error"),
1445
+ schematic_error_id: z40.string(),
1446
+ // eventually each error type should be broken out into a dir of files
1447
+ error_type: z40.literal("schematic_port_not_found"),
1448
+ message: z40.string()
1449
+ }).describe("Defines a schematic error on the schematic");
1450
+ expectTypesMatch(true);
1451
+ var schematic_debug_object_base = z41.object({
1452
+ type: z41.literal("schematic_debug_object"),
1453
+ label: z41.string().optional()
1454
+ });
1455
+ var schematic_debug_rect = schematic_debug_object_base.extend({
1456
+ shape: z41.literal("rect"),
1457
+ center: point,
1458
+ size
1459
+ });
1460
+ var schematic_debug_line = schematic_debug_object_base.extend({
1461
+ shape: z41.literal("line"),
1462
+ start: point,
1463
+ end: point
1464
+ });
1465
+ var schematic_debug_point = schematic_debug_object_base.extend({
1466
+ shape: z41.literal("point"),
1467
+ center: point
1468
+ });
1469
+ var schematic_debug_object = z41.discriminatedUnion("shape", [
1470
+ schematic_debug_rect,
1471
+ schematic_debug_line,
1472
+ schematic_debug_point
1473
+ ]);
1474
+ expectTypesMatch(true);
1475
+ var schematic_voltage_probe = z422.object({
1476
+ type: z422.literal("schematic_voltage_probe"),
1477
+ schematic_voltage_probe_id: z422.string(),
1478
+ position: point,
1479
+ schematic_trace_id: z422.string(),
1480
+ voltage: voltage.optional()
1481
+ }).describe("Defines a voltage probe measurement point on a schematic trace");
1482
+ expectTypesMatch(true);
1483
+ var all_layers = [
1484
+ "top",
1485
+ "bottom",
1486
+ "inner1",
1487
+ "inner2",
1488
+ "inner3",
1489
+ "inner4",
1490
+ "inner5",
1491
+ "inner6"
1492
+ ];
1493
+ var layer_string = z43.enum(all_layers);
1494
+ var layer_ref = layer_string.or(
1495
+ z43.object({
1496
+ name: layer_string
1497
+ })
1498
+ ).transform((layer) => {
1499
+ if (typeof layer === "string") {
1500
+ return layer;
1501
+ }
1502
+ return layer.name;
1503
+ });
1504
+ var visible_layer = z43.enum(["top", "bottom"]);
1505
+ var pcb_route_hint = z44.object({
1506
+ x: distance,
1507
+ y: distance,
1508
+ via: z44.boolean().optional(),
1509
+ via_to_layer: layer_ref.optional()
1510
+ });
1511
+ var pcb_route_hints = z44.array(pcb_route_hint);
1512
+ var route_hint_point = z45.object({
1513
+ x: distance,
1514
+ y: distance,
1515
+ via: z45.boolean().optional(),
1516
+ to_layer: layer_ref.optional(),
1517
+ trace_width: distance.optional()
1518
+ });
1519
+ var pcb_component = z46.object({
1520
+ type: z46.literal("pcb_component"),
1521
+ pcb_component_id: getZodPrefixedIdWithDefault("pcb_component"),
1522
+ source_component_id: z46.string(),
1523
+ center: point,
1524
+ layer: layer_ref,
1525
+ rotation,
1526
+ width: length,
1527
+ height: length,
1528
+ subcircuit_id: z46.string().optional()
1529
+ }).describe("Defines a component on the PCB");
1530
+ expectTypesMatch(true);
1531
+ var pcb_hole_circle_or_square = z47.object({
1532
+ type: z47.literal("pcb_hole"),
1533
+ pcb_hole_id: getZodPrefixedIdWithDefault("pcb_hole"),
1534
+ pcb_group_id: z47.string().optional(),
1535
+ subcircuit_id: z47.string().optional(),
1536
+ hole_shape: z47.enum(["circle", "square"]),
1537
+ hole_diameter: z47.number(),
1538
+ x: distance,
1539
+ y: distance
1540
+ });
1541
+ var pcb_hole_circle_or_square_shape = pcb_hole_circle_or_square.describe(
1542
+ "Defines a circular or square hole on the PCB"
1543
+ );
1544
+ expectTypesMatch(true);
1545
+ var pcb_hole_oval = z47.object({
1546
+ type: z47.literal("pcb_hole"),
1547
+ pcb_hole_id: getZodPrefixedIdWithDefault("pcb_hole"),
1548
+ pcb_group_id: z47.string().optional(),
1549
+ subcircuit_id: z47.string().optional(),
1550
+ hole_shape: z47.literal("oval"),
1551
+ hole_width: z47.number(),
1552
+ hole_height: z47.number(),
1553
+ x: distance,
1554
+ y: distance
1555
+ });
1556
+ var pcb_hole_oval_shape = pcb_hole_oval.describe(
1557
+ "Defines an oval hole on the PCB"
1558
+ );
1559
+ expectTypesMatch(true);
1560
+ var pcb_hole = pcb_hole_circle_or_square.or(pcb_hole_oval);
1561
+ var pcb_plated_hole_circle = z48.object({
1562
+ type: z48.literal("pcb_plated_hole"),
1563
+ shape: z48.literal("circle"),
1564
+ pcb_group_id: z48.string().optional(),
1565
+ subcircuit_id: z48.string().optional(),
1566
+ outer_diameter: z48.number(),
1567
+ hole_diameter: z48.number(),
1568
+ x: distance,
1569
+ y: distance,
1570
+ layers: z48.array(layer_ref),
1571
+ port_hints: z48.array(z48.string()).optional(),
1572
+ pcb_component_id: z48.string().optional(),
1573
+ pcb_port_id: z48.string().optional(),
1574
+ pcb_plated_hole_id: getZodPrefixedIdWithDefault("pcb_plated_hole")
1575
+ });
1576
+ var pcb_plated_hole_oval = z48.object({
1577
+ type: z48.literal("pcb_plated_hole"),
1578
+ shape: z48.enum(["oval", "pill"]),
1579
+ pcb_group_id: z48.string().optional(),
1580
+ subcircuit_id: z48.string().optional(),
1581
+ outer_width: z48.number(),
1582
+ outer_height: z48.number(),
1583
+ hole_width: z48.number(),
1584
+ hole_height: z48.number(),
1585
+ x: distance,
1586
+ y: distance,
1587
+ layers: z48.array(layer_ref),
1588
+ port_hints: z48.array(z48.string()).optional(),
1589
+ pcb_component_id: z48.string().optional(),
1590
+ pcb_port_id: z48.string().optional(),
1591
+ pcb_plated_hole_id: getZodPrefixedIdWithDefault("pcb_plated_hole")
1592
+ });
1593
+ var pcb_circular_hole_with_rect_pad = z48.object({
1594
+ type: z48.literal("pcb_plated_hole"),
1595
+ shape: z48.literal("circular_hole_with_rect_pad"),
1596
+ pcb_group_id: z48.string().optional(),
1597
+ subcircuit_id: z48.string().optional(),
1598
+ hole_shape: z48.literal("circle"),
1599
+ pad_shape: z48.literal("rect"),
1600
+ hole_diameter: z48.number(),
1601
+ rect_pad_width: z48.number(),
1602
+ rect_pad_height: z48.number(),
1603
+ x: distance,
1604
+ y: distance,
1605
+ layers: z48.array(layer_ref),
1606
+ port_hints: z48.array(z48.string()).optional(),
1607
+ pcb_component_id: z48.string().optional(),
1608
+ pcb_port_id: z48.string().optional(),
1609
+ pcb_plated_hole_id: getZodPrefixedIdWithDefault("pcb_plated_hole")
1610
+ });
1611
+ var pcb_pill_hole_with_rect_pad = z48.object({
1612
+ type: z48.literal("pcb_plated_hole"),
1613
+ shape: z48.literal("pill_hole_with_rect_pad"),
1614
+ pcb_group_id: z48.string().optional(),
1615
+ subcircuit_id: z48.string().optional(),
1616
+ hole_shape: z48.literal("pill"),
1617
+ pad_shape: z48.literal("rect"),
1618
+ hole_width: z48.number(),
1619
+ hole_height: z48.number(),
1620
+ rect_pad_width: z48.number(),
1621
+ rect_pad_height: z48.number(),
1622
+ x: distance,
1623
+ y: distance,
1624
+ layers: z48.array(layer_ref),
1625
+ port_hints: z48.array(z48.string()).optional(),
1626
+ pcb_component_id: z48.string().optional(),
1627
+ pcb_port_id: z48.string().optional(),
1628
+ pcb_plated_hole_id: getZodPrefixedIdWithDefault("pcb_plated_hole")
1629
+ });
1630
+ var pcb_plated_hole = z48.union([
1631
+ pcb_plated_hole_circle,
1632
+ pcb_plated_hole_oval,
1633
+ pcb_circular_hole_with_rect_pad
1634
+ ]);
1635
+ expectTypesMatch(
1636
+ true
1637
+ );
1638
+ expectTypesMatch(true);
1639
+ expectTypesMatch(true);
1640
+ var pcb_port = z49.object({
1641
+ type: z49.literal("pcb_port"),
1642
+ pcb_port_id: getZodPrefixedIdWithDefault("pcb_port"),
1643
+ pcb_group_id: z49.string().optional(),
1644
+ subcircuit_id: z49.string().optional(),
1645
+ source_port_id: z49.string(),
1646
+ pcb_component_id: z49.string(),
1647
+ x: distance,
1648
+ y: distance,
1649
+ layers: z49.array(layer_ref)
1650
+ }).describe("Defines a port on the PCB");
1651
+ expectTypesMatch(true);
1652
+ var pcb_smtpad_circle = z50.object({
1653
+ type: z50.literal("pcb_smtpad"),
1654
+ shape: z50.literal("circle"),
1655
+ pcb_smtpad_id: getZodPrefixedIdWithDefault("pcb_smtpad"),
1656
+ pcb_group_id: z50.string().optional(),
1657
+ subcircuit_id: z50.string().optional(),
1658
+ x: distance,
1659
+ y: distance,
1660
+ radius: z50.number(),
1661
+ layer: layer_ref,
1662
+ port_hints: z50.array(z50.string()).optional(),
1663
+ pcb_component_id: z50.string().optional(),
1664
+ pcb_port_id: z50.string().optional()
1665
+ });
1666
+ var pcb_smtpad_rect = z50.object({
1667
+ type: z50.literal("pcb_smtpad"),
1668
+ shape: z50.literal("rect"),
1669
+ pcb_smtpad_id: getZodPrefixedIdWithDefault("pcb_smtpad"),
1670
+ pcb_group_id: z50.string().optional(),
1671
+ subcircuit_id: z50.string().optional(),
1672
+ x: distance,
1673
+ y: distance,
1674
+ width: z50.number(),
1675
+ height: z50.number(),
1676
+ layer: layer_ref,
1677
+ port_hints: z50.array(z50.string()).optional(),
1678
+ pcb_component_id: z50.string().optional(),
1679
+ pcb_port_id: z50.string().optional()
1680
+ });
1681
+ var pcb_smtpad_rotated_rect = z50.object({
1682
+ type: z50.literal("pcb_smtpad"),
1683
+ shape: z50.literal("rotated_rect"),
1684
+ pcb_smtpad_id: getZodPrefixedIdWithDefault("pcb_smtpad"),
1685
+ pcb_group_id: z50.string().optional(),
1686
+ subcircuit_id: z50.string().optional(),
1687
+ x: distance,
1688
+ y: distance,
1689
+ width: z50.number(),
1690
+ height: z50.number(),
1691
+ ccw_rotation: rotation,
1692
+ layer: layer_ref,
1693
+ port_hints: z50.array(z50.string()).optional(),
1694
+ pcb_component_id: z50.string().optional(),
1695
+ pcb_port_id: z50.string().optional()
1696
+ });
1697
+ var pcb_smtpad_pill = z50.object({
1698
+ type: z50.literal("pcb_smtpad"),
1699
+ shape: z50.literal("pill"),
1700
+ pcb_smtpad_id: getZodPrefixedIdWithDefault("pcb_smtpad"),
1701
+ pcb_group_id: z50.string().optional(),
1702
+ subcircuit_id: z50.string().optional(),
1703
+ x: distance,
1704
+ y: distance,
1705
+ width: z50.number(),
1706
+ height: z50.number(),
1707
+ radius: z50.number(),
1708
+ layer: layer_ref,
1709
+ port_hints: z50.array(z50.string()).optional(),
1710
+ pcb_component_id: z50.string().optional(),
1711
+ pcb_port_id: z50.string().optional()
1712
+ });
1713
+ var pcb_smtpad = z50.union([
1714
+ pcb_smtpad_circle,
1715
+ pcb_smtpad_rect,
1716
+ pcb_smtpad_rotated_rect,
1717
+ pcb_smtpad_pill
1718
+ ]).describe("Defines an SMT pad on the PCB");
1719
+ expectTypesMatch(true);
1720
+ expectTypesMatch(true);
1721
+ expectTypesMatch(true);
1722
+ expectTypesMatch(true);
1723
+ var pcb_solder_paste_circle = z51.object({
1724
+ type: z51.literal("pcb_solder_paste"),
1725
+ shape: z51.literal("circle"),
1726
+ pcb_solder_paste_id: getZodPrefixedIdWithDefault("pcb_solder_paste"),
1727
+ pcb_group_id: z51.string().optional(),
1728
+ subcircuit_id: z51.string().optional(),
1729
+ x: distance,
1730
+ y: distance,
1731
+ radius: z51.number(),
1732
+ layer: layer_ref,
1733
+ pcb_component_id: z51.string().optional(),
1734
+ pcb_smtpad_id: z51.string().optional()
1735
+ });
1736
+ var pcb_solder_paste_rect = z51.object({
1737
+ type: z51.literal("pcb_solder_paste"),
1738
+ shape: z51.literal("rect"),
1739
+ pcb_solder_paste_id: getZodPrefixedIdWithDefault("pcb_solder_paste"),
1740
+ pcb_group_id: z51.string().optional(),
1741
+ subcircuit_id: z51.string().optional(),
1742
+ x: distance,
1743
+ y: distance,
1744
+ width: z51.number(),
1745
+ height: z51.number(),
1746
+ layer: layer_ref,
1747
+ pcb_component_id: z51.string().optional(),
1748
+ pcb_smtpad_id: z51.string().optional()
1749
+ });
1750
+ var pcb_solder_paste = z51.union([pcb_solder_paste_circle, pcb_solder_paste_rect]).describe("Defines solderpaste on the PCB");
1751
+ expectTypesMatch(true);
1752
+ expectTypesMatch(true);
1753
+ var pcb_text = z52.object({
1754
+ type: z52.literal("pcb_text"),
1755
+ pcb_text_id: getZodPrefixedIdWithDefault("pcb_text"),
1756
+ pcb_group_id: z52.string().optional(),
1757
+ subcircuit_id: z52.string().optional(),
1758
+ text: z52.string(),
1759
+ center: point,
1760
+ layer: layer_ref,
1761
+ width: length,
1762
+ height: length,
1763
+ lines: z52.number(),
1764
+ // @ts-ignore
1765
+ align: z52.enum(["bottom-left"])
1766
+ }).describe("Defines text on the PCB");
1767
+ expectTypesMatch(true);
1768
+ var pcb_trace_route_point_wire = z53.object({
1769
+ route_type: z53.literal("wire"),
1770
+ x: distance,
1771
+ y: distance,
1772
+ width: distance,
1773
+ start_pcb_port_id: z53.string().optional(),
1774
+ end_pcb_port_id: z53.string().optional(),
1775
+ layer: layer_ref
1776
+ });
1777
+ var pcb_trace_route_point_via = z53.object({
1778
+ route_type: z53.literal("via"),
1779
+ x: distance,
1780
+ y: distance,
1781
+ from_layer: z53.string(),
1782
+ to_layer: z53.string()
1783
+ });
1784
+ var pcb_trace_route_point = z53.union([
1785
+ pcb_trace_route_point_wire,
1786
+ pcb_trace_route_point_via
1787
+ ]);
1788
+ var pcb_trace = z53.object({
1789
+ type: z53.literal("pcb_trace"),
1790
+ source_trace_id: z53.string().optional(),
1791
+ pcb_component_id: z53.string().optional(),
1792
+ pcb_trace_id: getZodPrefixedIdWithDefault("pcb_trace"),
1793
+ pcb_group_id: z53.string().optional(),
1794
+ subcircuit_id: z53.string().optional(),
1795
+ route_thickness_mode: z53.enum(["constant", "interpolated"]).default("constant").optional(),
1796
+ route_order_index: z53.number().optional(),
1797
+ should_round_corners: z53.boolean().optional(),
1798
+ trace_length: z53.number().optional(),
1799
+ route: z53.array(
1800
+ z53.union([
1801
+ z53.object({
1802
+ route_type: z53.literal("wire"),
1803
+ x: distance,
1804
+ y: distance,
1805
+ width: distance,
1806
+ start_pcb_port_id: z53.string().optional(),
1807
+ end_pcb_port_id: z53.string().optional(),
1808
+ layer: layer_ref
1809
+ }),
1810
+ z53.object({
1811
+ route_type: z53.literal("via"),
1812
+ x: distance,
1813
+ y: distance,
1814
+ from_layer: z53.string(),
1815
+ to_layer: z53.string()
1816
+ })
1817
+ ])
1818
+ )
1819
+ }).describe("Defines a trace on the PCB");
1820
+ expectTypesMatch(true);
1821
+ expectTypesMatch(true);
1822
+ var pcb_trace_error = z54.object({
1823
+ type: z54.literal("pcb_trace_error"),
1824
+ pcb_trace_error_id: getZodPrefixedIdWithDefault("pcb_trace_error"),
1825
+ error_type: z54.literal("pcb_trace_error"),
1826
+ message: z54.string(),
1827
+ center: point.optional(),
1828
+ pcb_trace_id: z54.string(),
1829
+ source_trace_id: z54.string(),
1830
+ pcb_component_ids: z54.array(z54.string()),
1831
+ pcb_port_ids: z54.array(z54.string())
1832
+ }).describe("Defines a trace error on the PCB");
1833
+ expectTypesMatch(true);
1834
+ var pcb_port_not_matched_error = z55.object({
1835
+ type: z55.literal("pcb_port_not_matched_error"),
1836
+ pcb_error_id: getZodPrefixedIdWithDefault("pcb_error"),
1837
+ message: z55.string(),
1838
+ pcb_component_ids: z55.array(z55.string())
1839
+ }).describe("Defines a trace error on the PCB where a port is not matched");
1840
+ expectTypesMatch(true);
1841
+ var pcb_via = z56.object({
1842
+ type: z56.literal("pcb_via"),
1843
+ pcb_via_id: getZodPrefixedIdWithDefault("pcb_via"),
1844
+ pcb_group_id: z56.string().optional(),
1845
+ subcircuit_id: z56.string().optional(),
1846
+ x: distance,
1847
+ y: distance,
1848
+ outer_diameter: distance.default("0.6mm"),
1849
+ hole_diameter: distance.default("0.25mm"),
1850
+ /** @deprecated */
1851
+ from_layer: layer_ref.optional(),
1852
+ /** @deprecated */
1853
+ to_layer: layer_ref.optional(),
1854
+ layers: z56.array(layer_ref),
1855
+ pcb_trace_id: z56.string().optional()
1856
+ }).describe("Defines a via on the PCB");
1857
+ expectTypesMatch(true);
1858
+ var pcb_board = z57.object({
1859
+ type: z57.literal("pcb_board"),
1860
+ pcb_board_id: getZodPrefixedIdWithDefault("pcb_board"),
1861
+ is_subcircuit: z57.boolean().optional(),
1862
+ subcircuit_id: z57.string().optional(),
1863
+ width: length,
1864
+ height: length,
1865
+ center: point,
1866
+ thickness: length.optional().default(1.4),
1867
+ num_layers: z57.number().optional().default(4),
1868
+ outline: z57.array(point).optional()
1869
+ }).describe("Defines the board outline of the PCB");
1870
+ expectTypesMatch(true);
1871
+ var pcb_placement_error = z58.object({
1872
+ type: z58.literal("pcb_placement_error"),
1873
+ pcb_placement_error_id: getZodPrefixedIdWithDefault("pcb_placement_error"),
1874
+ message: z58.string()
1875
+ }).describe("Defines a placement error on the PCB");
1876
+ expectTypesMatch(true);
1877
+ var pcb_trace_hint = z59.object({
1878
+ type: z59.literal("pcb_trace_hint"),
1879
+ pcb_trace_hint_id: getZodPrefixedIdWithDefault("pcb_trace_hint"),
1880
+ pcb_port_id: z59.string(),
1881
+ pcb_component_id: z59.string(),
1882
+ route: z59.array(route_hint_point)
1883
+ }).describe("A hint that can be used during generation of a PCB trace");
1884
+ expectTypesMatch(true);
1885
+ var pcb_silkscreen_line = z60.object({
1886
+ type: z60.literal("pcb_silkscreen_line"),
1887
+ pcb_silkscreen_line_id: getZodPrefixedIdWithDefault("pcb_silkscreen_line"),
1888
+ pcb_component_id: z60.string(),
1889
+ pcb_group_id: z60.string().optional(),
1890
+ subcircuit_id: z60.string().optional(),
1891
+ stroke_width: distance.default("0.1mm"),
1892
+ x1: distance,
1893
+ y1: distance,
1894
+ x2: distance,
1895
+ y2: distance,
1896
+ layer: visible_layer
1897
+ }).describe("Defines a silkscreen line on the PCB");
1898
+ expectTypesMatch(true);
1899
+ var pcb_silkscreen_path = z61.object({
1900
+ type: z61.literal("pcb_silkscreen_path"),
1901
+ pcb_silkscreen_path_id: getZodPrefixedIdWithDefault("pcb_silkscreen_path"),
1902
+ pcb_component_id: z61.string(),
1903
+ pcb_group_id: z61.string().optional(),
1904
+ subcircuit_id: z61.string().optional(),
1905
+ layer: visible_layer,
1906
+ route: z61.array(point),
1907
+ stroke_width: length
1908
+ }).describe("Defines a silkscreen path on the PCB");
1909
+ expectTypesMatch(true);
1910
+ var pcb_silkscreen_text = z62.object({
1911
+ type: z62.literal("pcb_silkscreen_text"),
1912
+ pcb_silkscreen_text_id: getZodPrefixedIdWithDefault("pcb_silkscreen_text"),
1913
+ pcb_group_id: z62.string().optional(),
1914
+ subcircuit_id: z62.string().optional(),
1915
+ font: z62.literal("tscircuit2024").default("tscircuit2024"),
1916
+ font_size: distance.default("0.2mm"),
1917
+ pcb_component_id: z62.string(),
1918
+ text: z62.string(),
1919
+ ccw_rotation: z62.number().optional(),
1920
+ layer: layer_ref,
1921
+ is_mirrored: z62.boolean().default(false).optional(),
1922
+ anchor_position: point.default({ x: 0, y: 0 }),
1923
+ anchor_alignment: z62.enum(["center", "top_left", "top_right", "bottom_left", "bottom_right"]).default("center")
1924
+ }).describe("Defines silkscreen text on the PCB");
1925
+ expectTypesMatch(true);
1926
+ var pcb_silkscreen_rect = z63.object({
1927
+ type: z63.literal("pcb_silkscreen_rect"),
1928
+ pcb_silkscreen_rect_id: getZodPrefixedIdWithDefault("pcb_silkscreen_rect"),
1929
+ pcb_component_id: z63.string(),
1930
+ pcb_group_id: z63.string().optional(),
1931
+ subcircuit_id: z63.string().optional(),
1932
+ center: point,
1933
+ width: length,
1934
+ height: length,
1935
+ layer: layer_ref,
1936
+ stroke_width: length.default("1mm")
1937
+ }).describe("Defines a silkscreen rect on the PCB");
1938
+ expectTypesMatch(true);
1939
+ var pcb_silkscreen_circle = z64.object({
1940
+ type: z64.literal("pcb_silkscreen_circle"),
1941
+ pcb_silkscreen_circle_id: getZodPrefixedIdWithDefault(
1942
+ "pcb_silkscreen_circle"
1943
+ ),
1944
+ pcb_component_id: z64.string(),
1945
+ pcb_group_id: z64.string().optional(),
1946
+ subcircuit_id: z64.string().optional(),
1947
+ center: point,
1948
+ radius: length,
1949
+ layer: visible_layer,
1950
+ stroke_width: length.default("1mm")
1951
+ }).describe("Defines a silkscreen circle on the PCB");
1952
+ expectTypesMatch(true);
1953
+ var pcb_silkscreen_oval = z65.object({
1954
+ type: z65.literal("pcb_silkscreen_oval"),
1955
+ pcb_silkscreen_oval_id: getZodPrefixedIdWithDefault("pcb_silkscreen_oval"),
1956
+ pcb_component_id: z65.string(),
1957
+ pcb_group_id: z65.string().optional(),
1958
+ subcircuit_id: z65.string().optional(),
1959
+ center: point,
1960
+ radius_x: distance,
1961
+ radius_y: distance,
1962
+ layer: visible_layer
1963
+ }).describe("Defines a silkscreen oval on the PCB");
1964
+ expectTypesMatch(true);
1965
+ var pcb_fabrication_note_text = z66.object({
1966
+ type: z66.literal("pcb_fabrication_note_text"),
1967
+ pcb_fabrication_note_text_id: getZodPrefixedIdWithDefault(
1968
+ "pcb_fabrication_note_text"
1969
+ ),
1970
+ subcircuit_id: z66.string().optional(),
1971
+ pcb_group_id: z66.string().optional(),
1972
+ font: z66.literal("tscircuit2024").default("tscircuit2024"),
1973
+ font_size: distance.default("1mm"),
1974
+ pcb_component_id: z66.string(),
1975
+ text: z66.string(),
1976
+ layer: visible_layer,
1977
+ anchor_position: point.default({ x: 0, y: 0 }),
1978
+ anchor_alignment: z66.enum(["center", "top_left", "top_right", "bottom_left", "bottom_right"]).default("center"),
1979
+ color: z66.string().optional()
1980
+ }).describe(
1981
+ "Defines a fabrication note in text on the PCB, useful for leaving notes for assemblers or fabricators"
1982
+ );
1983
+ expectTypesMatch(true);
1984
+ var pcb_fabrication_note_path = z67.object({
1985
+ type: z67.literal("pcb_fabrication_note_path"),
1986
+ pcb_fabrication_note_path_id: getZodPrefixedIdWithDefault(
1987
+ "pcb_fabrication_note_path"
1988
+ ),
1989
+ pcb_component_id: z67.string(),
1990
+ subcircuit_id: z67.string().optional(),
1991
+ layer: layer_ref,
1992
+ route: z67.array(point),
1993
+ stroke_width: length,
1994
+ color: z67.string().optional()
1995
+ }).describe(
1996
+ "Defines a fabrication path on the PCB for fabricators or assemblers"
1997
+ );
1998
+ expectTypesMatch(true);
1999
+ var pcb_keepout = z68.object({
2000
+ type: z68.literal("pcb_keepout"),
2001
+ shape: z68.literal("rect"),
2002
+ pcb_group_id: z68.string().optional(),
2003
+ subcircuit_id: z68.string().optional(),
2004
+ center: point,
2005
+ width: distance,
2006
+ height: distance,
2007
+ pcb_keepout_id: z68.string(),
2008
+ layers: z68.array(z68.string()),
2009
+ // Specify layers where the keepout applies
2010
+ description: z68.string().optional()
2011
+ // Optional description of the keepout
2012
+ }).or(
2013
+ z68.object({
2014
+ type: z68.literal("pcb_keepout"),
2015
+ shape: z68.literal("circle"),
2016
+ pcb_group_id: z68.string().optional(),
2017
+ subcircuit_id: z68.string().optional(),
2018
+ center: point,
2019
+ radius: distance,
2020
+ pcb_keepout_id: z68.string(),
2021
+ layers: z68.array(z68.string()),
2022
+ // Specify layers where the keepout applies
2023
+ description: z68.string().optional()
2024
+ // Optional description of the keepout
2025
+ })
2026
+ );
2027
+ var pcb_missing_footprint_error = z69.object({
2028
+ type: z69.literal("pcb_missing_footprint_error"),
2029
+ pcb_missing_footprint_error_id: getZodPrefixedIdWithDefault(
2030
+ "pcb_missing_footprint_error"
2031
+ ),
2032
+ pcb_group_id: z69.string().optional(),
2033
+ subcircuit_id: z69.string().optional(),
2034
+ error_type: z69.literal("pcb_missing_footprint_error"),
2035
+ source_component_id: z69.string(),
2036
+ message: z69.string()
2037
+ }).describe("Defines a missing footprint error on the PCB");
2038
+ expectTypesMatch(
2039
+ true
2040
+ );
2041
+ var pcb_manual_edit_conflict_error = z70.object({
2042
+ type: z70.literal("pcb_manual_edit_conflict_error"),
2043
+ pcb_error_id: getZodPrefixedIdWithDefault("pcb_manual_edit_conflict_error"),
2044
+ message: z70.string(),
2045
+ pcb_component_id: z70.string(),
2046
+ pcb_group_id: z70.string().optional(),
2047
+ subcircuit_id: z70.string().optional(),
2048
+ source_component_id: z70.string()
2049
+ }).describe(
2050
+ "Error emitted when a component has both manual placement and explicit pcbX/pcbY coordinates"
2051
+ );
2052
+ expectTypesMatch(true);
2053
+ var pcb_group = z71.object({
2054
+ type: z71.literal("pcb_group"),
2055
+ pcb_group_id: getZodPrefixedIdWithDefault("pcb_group"),
2056
+ source_group_id: z71.string(),
2057
+ is_subcircuit: z71.boolean().optional(),
2058
+ subcircuit_id: z71.string().optional(),
2059
+ width: length,
2060
+ height: length,
2061
+ center: point,
2062
+ pcb_component_ids: z71.array(z71.string()),
2063
+ name: z71.string().optional(),
2064
+ description: z71.string().optional()
2065
+ }).describe("Defines a group of components on the PCB");
2066
+ expectTypesMatch(true);
2067
+ var pcb_autorouting_error = z72.object({
2068
+ type: z72.literal("pcb_autorouting_error"),
2069
+ pcb_error_id: getZodPrefixedIdWithDefault("pcb_autorouting_error"),
2070
+ message: z72.string()
2071
+ }).describe("The autorouting has failed to route a portion of the board");
2072
+ expectTypesMatch(true);
2073
+ var cad_component = z73.object({
2074
+ type: z73.literal("cad_component"),
2075
+ cad_component_id: z73.string(),
2076
+ pcb_component_id: z73.string(),
2077
+ source_component_id: z73.string(),
2078
+ position: point3,
2079
+ rotation: point3.optional(),
2080
+ size: point3.optional(),
2081
+ layer: layer_ref.optional(),
2082
+ // These are all ways to generate/load the 3d model
2083
+ footprinter_string: z73.string().optional(),
2084
+ model_obj_url: z73.string().optional(),
2085
+ model_stl_url: z73.string().optional(),
2086
+ model_3mf_url: z73.string().optional(),
2087
+ model_jscad: z73.any().optional()
2088
+ }).describe("Defines a component on the PCB");
2089
+ var any_circuit_element = z74.union([
2090
+ source_trace,
2091
+ source_port,
2092
+ any_source_component,
2093
+ source_led,
2094
+ source_net,
2095
+ source_group,
2096
+ source_simple_bug,
2097
+ source_simple_chip,
2098
+ source_simple_capacitor,
2099
+ source_simple_diode,
2100
+ source_simple_resistor,
2101
+ source_simple_power_source,
2102
+ source_simple_battery,
2103
+ source_simple_inductor,
2104
+ source_simple_pin_header,
2105
+ source_simple_resonator,
2106
+ source_simple_switch,
2107
+ source_simple_transistor,
2108
+ source_simple_mosfet,
2109
+ source_simple_potentiometer,
2110
+ source_simple_push_button,
2111
+ source_project_metadata,
2112
+ pcb_component,
2113
+ pcb_hole,
2114
+ pcb_missing_footprint_error,
2115
+ pcb_manual_edit_conflict_error,
2116
+ pcb_plated_hole,
2117
+ pcb_keepout,
2118
+ pcb_port,
2119
+ pcb_text,
2120
+ pcb_trace,
2121
+ pcb_via,
2122
+ pcb_smtpad,
2123
+ pcb_solder_paste,
2124
+ pcb_board,
2125
+ pcb_group,
2126
+ pcb_trace_hint,
2127
+ pcb_silkscreen_line,
2128
+ pcb_silkscreen_path,
2129
+ pcb_silkscreen_text,
2130
+ pcb_silkscreen_rect,
2131
+ pcb_silkscreen_circle,
2132
+ pcb_silkscreen_oval,
2133
+ pcb_trace_error,
2134
+ pcb_placement_error,
2135
+ pcb_port_not_matched_error,
2136
+ pcb_fabrication_note_path,
2137
+ pcb_fabrication_note_text,
2138
+ pcb_autorouting_error,
2139
+ schematic_box,
2140
+ schematic_text,
2141
+ schematic_line,
2142
+ schematic_component,
2143
+ schematic_port,
2144
+ schematic_trace,
2145
+ schematic_path,
2146
+ schematic_error,
2147
+ schematic_net_label,
2148
+ schematic_debug_object,
2149
+ schematic_voltage_probe,
2150
+ cad_component
2151
+ ]);
2152
+ var any_soup_element = any_circuit_element;
2153
+
2154
+ // node_modules/@tscircuit/soup-util/dist/index.js
2155
+ import { applyToPoint, decomposeTSR } from "transformation-matrix";
2156
+ var su = (soup, options = {}) => {
2157
+ let internalStore = soup._internal_store;
2158
+ if (!internalStore) {
2159
+ internalStore = {
2160
+ counts: {}
2161
+ };
2162
+ soup._internal_store = internalStore;
2163
+ for (const elm of soup) {
2164
+ const type = elm.type;
2165
+ const idVal = elm[`${type}_id`];
2166
+ if (!idVal)
2167
+ continue;
2168
+ const idNum = Number.parseInt(idVal.split("_").pop());
2169
+ if (!Number.isNaN(idNum)) {
2170
+ internalStore.counts[type] = Math.max(
2171
+ internalStore.counts[type] ?? 0,
2172
+ idNum
2173
+ );
2174
+ }
2175
+ }
2176
+ }
2177
+ const su2 = new Proxy(
2178
+ {},
2179
+ {
2180
+ get: (proxy_target, component_type) => {
2181
+ if (component_type === "toArray") {
2182
+ return () => soup;
2183
+ }
2184
+ return {
2185
+ get: (id) => soup.find(
2186
+ (e) => e.type === component_type && e[`${component_type}_id`] === id
2187
+ ),
2188
+ getUsing: (using) => {
2189
+ const keys = Object.keys(using);
2190
+ if (keys.length !== 1) {
2191
+ throw new Error(
2192
+ "getUsing requires exactly one key, e.g. { pcb_component_id }"
2193
+ );
2194
+ }
2195
+ const join_key = keys[0];
2196
+ const join_type = join_key.replace("_id", "");
2197
+ const joiner = soup.find(
2198
+ (e) => e.type === join_type && e[join_key] === using[join_key]
2199
+ );
2200
+ if (!joiner)
2201
+ return null;
2202
+ return soup.find(
2203
+ (e) => e.type === component_type && e[`${component_type}_id`] === joiner[`${component_type}_id`]
2204
+ );
2205
+ },
2206
+ getWhere: (where) => {
2207
+ const keys = Object.keys(where);
2208
+ return soup.find(
2209
+ (e) => e.type === component_type && keys.every((key) => e[key] === where[key])
2210
+ );
2211
+ },
2212
+ list: (where) => {
2213
+ const keys = !where ? [] : Object.keys(where);
2214
+ return soup.filter(
2215
+ (e) => e.type === component_type && keys.every((key) => e[key] === where[key])
2216
+ );
2217
+ },
2218
+ insert: (elm) => {
2219
+ internalStore.counts[component_type] ??= -1;
2220
+ internalStore.counts[component_type]++;
2221
+ const index = internalStore.counts[component_type];
2222
+ const newElm = {
2223
+ type: component_type,
2224
+ [`${component_type}_id`]: `${component_type}_${index}`,
2225
+ ...elm
2226
+ };
2227
+ if (options.validateInserts) {
2228
+ const parser = dist_exports[component_type] ?? any_soup_element;
2229
+ parser.parse(newElm);
2230
+ }
2231
+ soup.push(newElm);
2232
+ return newElm;
2233
+ },
2234
+ delete: (id) => {
2235
+ const elm = soup.find(
2236
+ (e) => e[`${component_type}_id`] === id
2237
+ );
2238
+ if (!elm)
2239
+ return;
2240
+ soup.splice(soup.indexOf(elm), 1);
2241
+ },
2242
+ update: (id, newProps) => {
2243
+ const elm = soup.find(
2244
+ (e) => e.type === component_type && e[`${component_type}_id`] === id
2245
+ );
2246
+ if (!elm)
2247
+ return;
2248
+ Object.assign(elm, newProps);
2249
+ return elm;
2250
+ },
2251
+ select: (selector) => {
2252
+ if (component_type === "source_component") {
2253
+ return soup.find(
2254
+ (e) => e.type === "source_component" && e.name === selector.replace(/\./g, "")
2255
+ );
2256
+ } else if (component_type === "pcb_port" || component_type === "source_port" || component_type === "schematic_port") {
2257
+ const [component_name, port_selector] = selector.replace(/\./g, "").split(/[\s\>]+/);
2258
+ const source_component = soup.find(
2259
+ (e) => e.type === "source_component" && e.name === component_name
2260
+ );
2261
+ if (!source_component)
2262
+ return null;
2263
+ const source_port2 = soup.find(
2264
+ (e) => e.type === "source_port" && e.source_component_id === source_component.source_component_id && (e.name === port_selector || (e.port_hints ?? []).includes(port_selector))
2265
+ );
2266
+ if (!source_port2)
2267
+ return null;
2268
+ if (component_type === "source_port")
2269
+ return source_port2;
2270
+ if (component_type === "pcb_port") {
2271
+ return soup.find(
2272
+ (e) => e.type === "pcb_port" && e.source_port_id === source_port2.source_port_id
2273
+ );
2274
+ } else if (component_type === "schematic_port") {
2275
+ return soup.find(
2276
+ (e) => e.type === "schematic_port" && e.source_port_id === source_port2.source_port_id
2277
+ );
2278
+ }
2279
+ }
2280
+ }
2281
+ };
2282
+ }
2283
+ }
2284
+ );
2285
+ return su2;
2286
+ };
2287
+ su.unparsed = su;
2288
+ var su_default = su;
2289
+ var transformPCBElement = (elm, matrix) => {
2290
+ if (elm.type === "pcb_plated_hole" || elm.type === "pcb_hole" || elm.type === "pcb_via" || elm.type === "pcb_smtpad" || elm.type === "pcb_port") {
2291
+ const { x, y } = applyToPoint(matrix, { x: elm.x, y: elm.y });
2292
+ elm.x = x;
2293
+ elm.y = y;
2294
+ } else if (elm.type === "pcb_keepout" || elm.type === "pcb_board") {
2295
+ elm.center = applyToPoint(matrix, elm.center);
2296
+ } else if (elm.type === "pcb_silkscreen_text" || elm.type === "pcb_fabrication_note_text") {
2297
+ elm.anchor_position = applyToPoint(matrix, elm.anchor_position);
2298
+ } else if (elm.type === "pcb_silkscreen_circle" || elm.type === "pcb_silkscreen_rect" || elm.type === "pcb_component") {
2299
+ elm.center = applyToPoint(matrix, elm.center);
2300
+ } else if (elm.type === "pcb_silkscreen_path" || elm.type === "pcb_trace" || elm.type === "pcb_fabrication_note_path") {
2301
+ elm.route = elm.route.map((rp) => {
2302
+ const tp = applyToPoint(matrix, rp);
2303
+ rp.x = tp.x;
2304
+ rp.y = tp.y;
2305
+ return rp;
2306
+ });
2307
+ } else if (elm.type === "pcb_silkscreen_line") {
2308
+ const p1 = { x: elm.x1, y: elm.y1 };
2309
+ const p2 = { x: elm.x2, y: elm.y2 };
2310
+ const p1t = applyToPoint(matrix, p1);
2311
+ const p2t = applyToPoint(matrix, p2);
2312
+ elm.x1 = p1t.x;
2313
+ elm.y1 = p1t.y;
2314
+ elm.x2 = p2t.x;
2315
+ elm.y2 = p2t.y;
2316
+ } else if (elm.type === "cad_component") {
2317
+ const newPos = applyToPoint(matrix, {
2318
+ x: elm.position.x,
2319
+ y: elm.position.y
2320
+ });
2321
+ elm.position.x = newPos.x;
2322
+ elm.position.y = newPos.y;
2323
+ }
2324
+ return elm;
2325
+ };
2326
+ var transformPCBElements = (elms, matrix) => {
2327
+ const tsr = decomposeTSR(matrix);
2328
+ const flipPadWidthHeight = Math.round(tsr.rotation.angle / (Math.PI / 2)) % 2 === 1;
2329
+ let transformedElms = elms.map((elm) => transformPCBElement(elm, matrix));
2330
+ if (flipPadWidthHeight) {
2331
+ transformedElms = transformedElms.map((elm) => {
2332
+ if (elm.type === "pcb_smtpad" && elm.shape === "rect") {
2333
+ ;
2334
+ [elm.width, elm.height] = [elm.height, elm.width];
2335
+ }
2336
+ return elm;
2337
+ });
2338
+ }
2339
+ return transformedElms;
2340
+ };
2341
+ function stringHash(str) {
2342
+ let hash = 0;
2343
+ if (str.length == 0)
2344
+ return hash;
2345
+ for (var i = 0; i < str.length; i++) {
2346
+ var char = str.charCodeAt(i);
2347
+ hash = (hash << 5) - hash + char;
2348
+ hash = hash & hash;
2349
+ }
2350
+ return Math.abs(hash);
2351
+ }
2352
+ var nice_color_palettes = [
2353
+ ["#69d2e7", "#a7dbd8", "#e0e4cc", "#f38630", "#fa6900"],
2354
+ ["#fe4365", "#fc9d9a", "#f9cdad", "#c8c8a9", "#83af9b"],
2355
+ ["#ecd078", "#d95b43", "#c02942", "#542437", "#53777a"],
2356
+ ["#556270", "#4ecdc4", "#c7f464", "#ff6b6b", "#c44d58"],
2357
+ ["#774f38", "#e08e79", "#f1d4af", "#ece5ce", "#c5e0dc"],
2358
+ ["#e8ddcb", "#cdb380", "#036564", "#033649", "#031634"],
2359
+ ["#490a3d", "#bd1550", "#e97f02", "#f8ca00", "#8a9b0f"],
2360
+ ["#594f4f", "#547980", "#45ada8", "#9de0ad", "#e5fcc2"],
2361
+ ["#00a0b0", "#6a4a3c", "#cc333f", "#eb6841", "#edc951"],
2362
+ ["#e94e77", "#d68189", "#c6a49a", "#c6e5d9", "#f4ead5"],
2363
+ ["#3fb8af", "#7fc7af", "#dad8a7", "#ff9e9d", "#ff3d7f"],
2364
+ ["#d9ceb2", "#948c75", "#d5ded9", "#7a6a53", "#99b2b7"],
2365
+ ["#ffffff", "#cbe86b", "#f2e9e1", "#1c140d", "#cbe86b"],
2366
+ ["#efffcd", "#dce9be", "#555152", "#2e2633", "#99173c"],
2367
+ ["#343838", "#005f6b", "#008c9e", "#00b4cc", "#00dffc"],
2368
+ ["#413e4a", "#73626e", "#b38184", "#f0b49e", "#f7e4be"],
2369
+ ["#ff4e50", "#fc913a", "#f9d423", "#ede574", "#e1f5c4"],
2370
+ ["#99b898", "#fecea8", "#ff847c", "#e84a5f", "#2a363b"],
2371
+ ["#655643", "#80bca3", "#f6f7bd", "#e6ac27", "#bf4d28"],
2372
+ ["#00a8c6", "#40c0cb", "#f9f2e7", "#aee239", "#8fbe00"],
2373
+ ["#351330", "#424254", "#64908a", "#e8caa4", "#cc2a41"],
2374
+ ["#554236", "#f77825", "#d3ce3d", "#f1efa5", "#60b99a"],
2375
+ ["#5d4157", "#838689", "#a8caba", "#cad7b2", "#ebe3aa"],
2376
+ ["#8c2318", "#5e8c6a", "#88a65e", "#bfb35a", "#f2c45a"],
2377
+ ["#fad089", "#ff9c5b", "#f5634a", "#ed303c", "#3b8183"],
2378
+ ["#ff4242", "#f4fad2", "#d4ee5e", "#e1edb9", "#f0f2eb"],
2379
+ ["#f8b195", "#f67280", "#c06c84", "#6c5b7b", "#355c7d"],
2380
+ ["#d1e751", "#ffffff", "#000000", "#4dbce9", "#26ade4"],
2381
+ ["#1b676b", "#519548", "#88c425", "#bef202", "#eafde6"],
2382
+ ["#5e412f", "#fcebb6", "#78c0a8", "#f07818", "#f0a830"],
2383
+ ["#bcbdac", "#cfbe27", "#f27435", "#f02475", "#3b2d38"],
2384
+ ["#452632", "#91204d", "#e4844a", "#e8bf56", "#e2f7ce"],
2385
+ ["#eee6ab", "#c5bc8e", "#696758", "#45484b", "#36393b"],
2386
+ ["#f0d8a8", "#3d1c00", "#86b8b1", "#f2d694", "#fa2a00"],
2387
+ ["#2a044a", "#0b2e59", "#0d6759", "#7ab317", "#a0c55f"],
2388
+ ["#f04155", "#ff823a", "#f2f26f", "#fff7bd", "#95cfb7"],
2389
+ ["#b9d7d9", "#668284", "#2a2829", "#493736", "#7b3b3b"],
2390
+ ["#bbbb88", "#ccc68d", "#eedd99", "#eec290", "#eeaa88"],
2391
+ ["#b3cc57", "#ecf081", "#ffbe40", "#ef746f", "#ab3e5b"],
2392
+ ["#a3a948", "#edb92e", "#f85931", "#ce1836", "#009989"],
2393
+ ["#300030", "#480048", "#601848", "#c04848", "#f07241"],
2394
+ ["#67917a", "#170409", "#b8af03", "#ccbf82", "#e33258"],
2395
+ ["#aab3ab", "#c4cbb7", "#ebefc9", "#eee0b7", "#e8caaf"],
2396
+ ["#e8d5b7", "#0e2430", "#fc3a51", "#f5b349", "#e8d5b9"],
2397
+ ["#ab526b", "#bca297", "#c5ceae", "#f0e2a4", "#f4ebc3"],
2398
+ ["#607848", "#789048", "#c0d860", "#f0f0d8", "#604848"],
2399
+ ["#b6d8c0", "#c8d9bf", "#dadabd", "#ecdbbc", "#fedcba"],
2400
+ ["#a8e6ce", "#dcedc2", "#ffd3b5", "#ffaaa6", "#ff8c94"],
2401
+ ["#3e4147", "#fffedf", "#dfba69", "#5a2e2e", "#2a2c31"],
2402
+ ["#fc354c", "#29221f", "#13747d", "#0abfbc", "#fcf7c5"],
2403
+ ["#cc0c39", "#e6781e", "#c8cf02", "#f8fcc1", "#1693a7"],
2404
+ ["#1c2130", "#028f76", "#b3e099", "#ffeaad", "#d14334"],
2405
+ ["#a7c5bd", "#e5ddcb", "#eb7b59", "#cf4647", "#524656"],
2406
+ ["#dad6ca", "#1bb0ce", "#4f8699", "#6a5e72", "#563444"],
2407
+ ["#5c323e", "#a82743", "#e15e32", "#c0d23e", "#e5f04c"],
2408
+ ["#edebe6", "#d6e1c7", "#94c7b6", "#403b33", "#d3643b"],
2409
+ ["#fdf1cc", "#c6d6b8", "#987f69", "#e3ad40", "#fcd036"],
2410
+ ["#230f2b", "#f21d41", "#ebebbc", "#bce3c5", "#82b3ae"],
2411
+ ["#b9d3b0", "#81bda4", "#b28774", "#f88f79", "#f6aa93"],
2412
+ ["#3a111c", "#574951", "#83988e", "#bcdea5", "#e6f9bc"],
2413
+ ["#5e3929", "#cd8c52", "#b7d1a3", "#dee8be", "#fcf7d3"],
2414
+ ["#1c0113", "#6b0103", "#a30006", "#c21a01", "#f03c02"],
2415
+ ["#000000", "#9f111b", "#b11623", "#292c37", "#cccccc"],
2416
+ ["#382f32", "#ffeaf2", "#fcd9e5", "#fbc5d8", "#f1396d"],
2417
+ ["#e3dfba", "#c8d6bf", "#93ccc6", "#6cbdb5", "#1a1f1e"],
2418
+ ["#f6f6f6", "#e8e8e8", "#333333", "#990100", "#b90504"],
2419
+ ["#1b325f", "#9cc4e4", "#e9f2f9", "#3a89c9", "#f26c4f"],
2420
+ ["#a1dbb2", "#fee5ad", "#faca66", "#f7a541", "#f45d4c"],
2421
+ ["#c1b398", "#605951", "#fbeec2", "#61a6ab", "#accec0"],
2422
+ ["#5e9fa3", "#dcd1b4", "#fab87f", "#f87e7b", "#b05574"],
2423
+ ["#951f2b", "#f5f4d7", "#e0dfb1", "#a5a36c", "#535233"],
2424
+ ["#8dccad", "#988864", "#fea6a2", "#f9d6ac", "#ffe9af"],
2425
+ ["#2d2d29", "#215a6d", "#3ca2a2", "#92c7a3", "#dfece6"],
2426
+ ["#413d3d", "#040004", "#c8ff00", "#fa023c", "#4b000f"],
2427
+ ["#eff3cd", "#b2d5ba", "#61ada0", "#248f8d", "#605063"],
2428
+ ["#ffefd3", "#fffee4", "#d0ecea", "#9fd6d2", "#8b7a5e"],
2429
+ ["#cfffdd", "#b4dec1", "#5c5863", "#a85163", "#ff1f4c"],
2430
+ ["#9dc9ac", "#fffec7", "#f56218", "#ff9d2e", "#919167"],
2431
+ ["#4e395d", "#827085", "#8ebe94", "#ccfc8e", "#dc5b3e"],
2432
+ ["#a8a7a7", "#cc527a", "#e8175d", "#474747", "#363636"],
2433
+ ["#f8edd1", "#d88a8a", "#474843", "#9d9d93", "#c5cfc6"],
2434
+ ["#046d8b", "#309292", "#2fb8ac", "#93a42a", "#ecbe13"],
2435
+ ["#f38a8a", "#55443d", "#a0cab5", "#cde9ca", "#f1edd0"],
2436
+ ["#a70267", "#f10c49", "#fb6b41", "#f6d86b", "#339194"],
2437
+ ["#ff003c", "#ff8a00", "#fabe28", "#88c100", "#00c176"],
2438
+ ["#ffedbf", "#f7803c", "#f54828", "#2e0d23", "#f8e4c1"],
2439
+ ["#4e4d4a", "#353432", "#94ba65", "#2790b0", "#2b4e72"],
2440
+ ["#0ca5b0", "#4e3f30", "#fefeeb", "#f8f4e4", "#a5b3aa"],
2441
+ ["#4d3b3b", "#de6262", "#ffb88c", "#ffd0b3", "#f5e0d3"],
2442
+ ["#fffbb7", "#a6f6af", "#66b6ab", "#5b7c8d", "#4f2958"],
2443
+ ["#edf6ee", "#d1c089", "#b3204d", "#412e28", "#151101"],
2444
+ ["#9d7e79", "#ccac95", "#9a947c", "#748b83", "#5b756c"],
2445
+ ["#fcfef5", "#e9ffe1", "#cdcfb7", "#d6e6c3", "#fafbe3"],
2446
+ ["#9cddc8", "#bfd8ad", "#ddd9ab", "#f7af63", "#633d2e"],
2447
+ ["#30261c", "#403831", "#36544f", "#1f5f61", "#0b8185"],
2448
+ ["#aaff00", "#ffaa00", "#ff00aa", "#aa00ff", "#00aaff"],
2449
+ ["#d1313d", "#e5625c", "#f9bf76", "#8eb2c5", "#615375"],
2450
+ ["#ffe181", "#eee9e5", "#fad3b2", "#ffba7f", "#ff9c97"],
2451
+ ["#73c8a9", "#dee1b6", "#e1b866", "#bd5532", "#373b44"],
2452
+ ["#805841", "#dcf7f3", "#fffcdd", "#ffd8d8", "#f5a2a2"]
2453
+ ];
2454
+ var getDebugLayoutObject = (lo) => {
2455
+ let {
2456
+ x,
2457
+ y,
2458
+ width,
2459
+ height
2460
+ } = {
2461
+ ...lo,
2462
+ ...lo.size,
2463
+ ...lo.center,
2464
+ ...lo.position
2465
+ };
2466
+ if (lo.x1 !== void 0 && lo.x2 !== void 0 && lo.y1 !== void 0 && lo.y2 !== void 0) {
2467
+ x = (lo.x1 + lo.x2) / 2;
2468
+ y = (lo.y1 + lo.y2) / 2;
2469
+ width = Math.abs(lo.x1 - lo.x2);
2470
+ height = Math.abs(lo.y1 - lo.y2);
2471
+ }
2472
+ const title = lo.text || lo.name || lo.source?.text || lo.source?.name || "?";
2473
+ const content = lo;
2474
+ if (x === void 0 || y === void 0)
2475
+ return null;
2476
+ if (width === void 0) {
2477
+ if ("outer_diameter" in lo) {
2478
+ width = lo.outer_diameter;
2479
+ height = lo.outer_diameter;
2480
+ }
2481
+ }
2482
+ if (width === void 0 || height === void 0) {
2483
+ width = 0.1;
2484
+ height = 0.1;
2485
+ }
2486
+ return {
2487
+ x,
2488
+ y,
2489
+ width,
2490
+ height,
2491
+ title,
2492
+ content,
2493
+ bg_color: nice_color_palettes[stringHash(lo.type || title) % nice_color_palettes.length]?.[4] ?? "#f00"
2494
+ };
2495
+ };
2496
+ var isTruthy = (value) => Boolean(value);
2497
+ var findBoundsAndCenter = (elements) => {
2498
+ const debugObjects = elements.filter((elm) => elm.type.startsWith("pcb_")).concat(
2499
+ elements.filter((elm) => elm.type === "pcb_trace").flatMap((elm) => elm.route)
2500
+ ).map((elm) => getDebugLayoutObject(elm)).filter(isTruthy);
2501
+ if (debugObjects.length === 0)
2502
+ return { center: { x: 0, y: 0 }, width: 0, height: 0 };
2503
+ let minX = debugObjects[0].x - debugObjects[0].width / 2;
2504
+ let maxX = debugObjects[0].x + debugObjects[0].width / 2;
2505
+ let minY = debugObjects[0].y - debugObjects[0].height / 2;
2506
+ let maxY = debugObjects[0].y + debugObjects[0].height / 2;
2507
+ for (const obj of debugObjects.slice(1)) {
2508
+ minX = Math.min(minX, obj.x - obj.width / 2);
2509
+ maxX = Math.max(maxX, obj.x + obj.width / 2);
2510
+ minY = Math.min(minY, obj.y - obj.height / 2);
2511
+ maxY = Math.max(maxY, obj.y + obj.height / 2);
2512
+ }
2513
+ const width = maxX - minX;
2514
+ const height = maxY - minY;
2515
+ const center = { x: minX + width / 2, y: minY + height / 2 };
2516
+ return { center, width, height };
2517
+ };
2518
+
2519
+ // lib/websafe/generate-footprint-tsx.ts
2520
+ import { mmStr } from "@tscircuit/mm";
2521
+ var generateFootprintTsx = (circuitJson) => {
2522
+ const holes = su_default(circuitJson).pcb_hole.list();
2523
+ const platedHoles = su_default(circuitJson).pcb_plated_hole.list();
2524
+ const smtPads = su_default(circuitJson).pcb_smtpad.list();
2525
+ const silkscreenPaths = su_default(circuitJson).pcb_silkscreen_path.list();
2526
+ const silkscreenTexts = su_default(circuitJson).pcb_silkscreen_text.list();
2527
+ const elementStrings = [];
2528
+ for (const hole of holes) {
2529
+ if (hole.hole_shape === "circle") {
2530
+ elementStrings.push(
2531
+ `<hole pcbX="${mmStr(hole.x)}" pcbY="${mmStr(hole.y)}" diameter="${mmStr(hole.hole_diameter)}" />`
2532
+ );
2533
+ } else if (hole.hole_shape === "oval") {
2534
+ console.warn("Unhandled oval hole in conversion (needs implementation)");
2535
+ }
2536
+ }
2537
+ for (const platedHole of platedHoles) {
2538
+ if (platedHole.shape === "oval" || platedHole.shape === "pill") {
2539
+ elementStrings.push(
2540
+ `<platedhole portHints={${JSON.stringify(platedHole.port_hints)}} pcbX="${mmStr(platedHole.x)}" pcbY="${mmStr(platedHole.y)}" outerHeight="${mmStr(platedHole.outer_height)}" outerWidth="${mmStr(platedHole.outer_width)}" holeHeight="${mmStr(platedHole.hole_height)}" holeWidth="${mmStr(platedHole.hole_width)}" shape="${platedHole.shape}" />`
2541
+ );
2542
+ } else if (platedHole.shape === "circle") {
2543
+ elementStrings.push(
2544
+ `<platedhole portHints={${JSON.stringify(platedHole.port_hints)}} pcbX="${mmStr(platedHole.x)}" pcbY="${mmStr(platedHole.y)}" outerDiameter="${mmStr(platedHole.outer_diameter)}" holeDiameter="${mmStr(platedHole.hole_diameter)}" shape="circle" />`
2545
+ );
2546
+ }
2547
+ }
2548
+ for (const smtPad of smtPads) {
2549
+ if (smtPad.shape === "circle") {
2550
+ elementStrings.push(
2551
+ `<smtpad portHints={${JSON.stringify(smtPad.port_hints)}} pcbX="${mmStr(smtPad.x)}" pcbY="${mmStr(smtPad.y)}" radius="${mmStr(smtPad.radius)}" shape="circle" />`
2552
+ );
2553
+ } else if (smtPad.shape === "rect") {
2554
+ elementStrings.push(
2555
+ `<smtpad portHints={${JSON.stringify(smtPad.port_hints)}} pcbX="${mmStr(smtPad.x)}" pcbY="${mmStr(smtPad.y)}" width="${mmStr(smtPad.width)}" height="${mmStr(smtPad.height)}" shape="rect" />`
2556
+ );
2557
+ }
2558
+ }
2559
+ for (const silkscreenPath of silkscreenPaths) {
2560
+ elementStrings.push(
2561
+ `<silkscreenpath route={${JSON.stringify(silkscreenPath.route)}} />`
2562
+ );
2563
+ }
2564
+ for (const silkscreenText of silkscreenTexts) {
2565
+ elementStrings.push(
2566
+ `<silkscreentext text="${silkscreenText.text}" pcbX="${mmStr(silkscreenText.anchor_position.x)}" pcbY="${mmStr(silkscreenText.anchor_position.y)}" anchorAlignment="${silkscreenText.anchor_alignment}" ${silkscreenText.font_size ? `fontSize="${mmStr(silkscreenText.font_size)}"` : ""} />`
2567
+ );
2568
+ }
2569
+ return `
2570
+ <footprint>
2571
+ ${elementStrings.join("\n")}
2572
+ </footprint>
2573
+ `.trim();
2574
+ };
2575
+
2576
+ // lib/websafe/convert-to-typescript-component/generate-typescript-component.ts
2577
+ var generateTypescriptComponent = ({
2578
+ pinLabels,
2579
+ componentName,
2580
+ objUrl,
2581
+ circuitJson,
2582
+ supplierPartNumbers,
2583
+ manufacturerPartNumber
2584
+ }) => {
2585
+ const safePinLabels = pinLabels ?? {};
2586
+ const footprintTsx = generateFootprintTsx(circuitJson);
2587
+ const simplifiedPinLabels = Object.fromEntries(
2588
+ Object.entries(safePinLabels).map(([pin, labels]) => {
2589
+ if (Array.isArray(labels) && labels.length > 1) {
2590
+ return [pin, [labels[1]]];
2591
+ }
2592
+ return [pin, labels];
2593
+ })
2594
+ );
2595
+ const pinLabelsString = Object.entries(simplifiedPinLabels).map(([pin, labels]) => ` ${pin}: ${JSON.stringify(labels)}`).join(",\n");
2596
+ return `
2597
+ import type { ChipProps } from "@tscircuit/props"
2598
+
2599
+ const pinLabels = {
2600
+ ${pinLabelsString}
2601
+ } as const
2602
+
2603
+ export const ${componentName} = (props: ChipProps<typeof pinLabels>) => {
2604
+ return (
2605
+ <chip
2606
+ pinLabels={pinLabels}
2607
+ supplierPartNumbers={${JSON.stringify(supplierPartNumbers, null, " ")}}
2608
+ manufacturerPartNumber="${manufacturerPartNumber}"
2609
+ footprint={${footprintTsx}}
2610
+ ${objUrl ? `cadModel={{
2611
+ objUrl: "${objUrl}",
2612
+ rotationOffset: { x: 0, y: 0, z: 0 },
2613
+ positionOffset: { x: 0, y: 0, z: 0 },
2614
+ }}` : ""}
2615
+ {...props}
2616
+ />
2617
+ )
2618
+ }
2619
+ `.trim();
2620
+ };
2621
+
2622
+ // lib/math/arc-utils.ts
2623
+ function generateArcFromSweep(startX, startY, endX, endY, radius, largeArcFlag, sweepFlag) {
2624
+ const start = { x: startX, y: startY };
2625
+ const end = { x: endX, y: endY };
2626
+ const midX = (startX + endX) / 2;
2627
+ const midY = (startY + endY) / 2;
2628
+ const dx = endX - startX;
2629
+ const dy = endY - startY;
2630
+ const distance2 = Math.sqrt(dx * dx + dy * dy);
2631
+ if (distance2 === 0 || radius < distance2 / 2) {
2632
+ return [start, end];
2633
+ }
2634
+ const h = Math.sqrt(radius * radius - distance2 * distance2 / 4);
2635
+ const angle = Math.atan2(dy, dx);
2636
+ const centerX = midX + h * Math.sin(angle) * (sweepFlag ? 1 : -1);
2637
+ const centerY = midY - h * Math.cos(angle) * (sweepFlag ? 1 : -1);
2638
+ const startAngle = Math.atan2(startY - centerY, startX - centerX);
2639
+ let endAngle = Math.atan2(endY - centerY, endX - centerX);
2640
+ if (!sweepFlag && endAngle > startAngle) {
2641
+ endAngle -= 2 * Math.PI;
2642
+ } else if (sweepFlag && endAngle < startAngle) {
2643
+ endAngle += 2 * Math.PI;
2644
+ }
2645
+ if (!largeArcFlag && Math.abs(endAngle - startAngle) > Math.PI || largeArcFlag && Math.abs(endAngle - startAngle) < Math.PI) {
2646
+ if (endAngle > startAngle) {
2647
+ endAngle -= 2 * Math.PI;
2648
+ } else {
2649
+ endAngle += 2 * Math.PI;
2650
+ }
2651
+ }
2652
+ const numPoints = Math.max(
2653
+ 2,
2654
+ Math.ceil(Math.abs(endAngle - startAngle) * radius)
2655
+ );
2656
+ const path = [];
2657
+ for (let i = 0; i <= numPoints; i++) {
2658
+ const t = i / numPoints;
2659
+ const angle2 = startAngle + t * (endAngle - startAngle);
2660
+ const x = centerX + radius * Math.cos(angle2);
2661
+ const y = centerY + radius * Math.sin(angle2);
2662
+ path.push({ x, y });
2663
+ }
2664
+ return path;
2665
+ }
2666
+
2667
+ // lib/convert-easyeda-json-to-tscircuit-soup-json.ts
2668
+ import { compose, scale, translate } from "transformation-matrix";
2669
+
2670
+ // lib/compute-center-offset.ts
2671
+ import { mm as mm2 } from "@tscircuit/mm";
2672
+ var computeCenterOffset = (easyeda) => {
2673
+ const pads = easyeda.packageDetail.dataStr.shape.filter(
2674
+ (shape) => shape.type === "PAD"
2675
+ );
2676
+ const minX = Math.min(...pads.map((pad) => mm2(pad.center.x)));
2677
+ const maxX = Math.max(...pads.map((pad) => mm2(pad.center.x)));
2678
+ const minY = Math.min(...pads.map((pad) => mm2(pad.center.y)));
2679
+ const maxY = Math.max(...pads.map((pad) => mm2(pad.center.y)));
2680
+ const centerX = (minX + maxX) / 2;
2681
+ const centerY = (minY + maxY) / 2;
2682
+ return {
2683
+ x: centerX,
2684
+ y: centerY
2685
+ };
2686
+ };
2687
+
2688
+ // lib/convert-easyeda-json-to-tscircuit-soup-json.ts
2689
+ import { mm as mm3 } from "@tscircuit/mm";
2690
+
2691
+ // lib/websafe/normalize-pin-labels.ts
2692
+ var normalizePinLabels = (inputPinLabels) => {
2693
+ const unqInputPinLabels = inputPinLabels.map((labels) => [...new Set(labels)]);
2694
+ const result = unqInputPinLabels.map(() => []);
2695
+ const desiredNumbers = unqInputPinLabels.map(() => null);
2696
+ for (let i = 0; i < unqInputPinLabels.length; i++) {
2697
+ for (const label of unqInputPinLabels[i]) {
2698
+ if (/^\d+$/.test(label)) {
2699
+ desiredNumbers[i] = Number.parseInt(label);
2700
+ break;
2701
+ }
2702
+ }
2703
+ }
2704
+ let highestPinNumber = 0;
2705
+ const alreadyAcceptedDesiredNumbers = /* @__PURE__ */ new Set();
2706
+ for (let i = 0; i < desiredNumbers.length; i++) {
2707
+ const desiredNumber = desiredNumbers[i];
2708
+ if (desiredNumber === null || desiredNumber < 1) {
2709
+ continue;
2710
+ }
2711
+ if (!alreadyAcceptedDesiredNumbers.has(desiredNumber)) {
2712
+ alreadyAcceptedDesiredNumbers.add(desiredNumber);
2713
+ result[i].push(`pin${desiredNumber}`);
2714
+ highestPinNumber = Math.max(highestPinNumber, desiredNumber);
2715
+ continue;
2716
+ }
2717
+ let existingAltsForPin = 0;
2718
+ for (const label of result[i]) {
2719
+ if (label.startsWith(`pin${desiredNumber}_alt`)) {
2720
+ existingAltsForPin++;
2721
+ }
2722
+ }
2723
+ result[i].push(`pin${desiredNumber}_alt${existingAltsForPin + 1}`);
2724
+ }
2725
+ for (let i = 0; i < result.length; i++) {
2726
+ const firstLabel = result[i][0];
2727
+ if (firstLabel?.includes("_alt")) {
2728
+ highestPinNumber++;
2729
+ result[i].unshift(`pin${highestPinNumber}`);
2730
+ }
2731
+ }
2732
+ for (let i = 0; i < result.length; i++) {
2733
+ if (result[i].length === 0) {
2734
+ highestPinNumber++;
2735
+ result[i].push(`pin${highestPinNumber}`);
2736
+ }
2737
+ }
2738
+ const totalLabelCounts = {};
2739
+ for (const inputLabels of unqInputPinLabels) {
2740
+ for (const label of inputLabels) {
2741
+ if (/^\d+$/.test(label)) {
2742
+ continue;
2743
+ }
2744
+ totalLabelCounts[label] = (totalLabelCounts[label] ?? 0) + 1;
2745
+ }
2746
+ }
2747
+ const incrementalLabelCounts = {};
2748
+ for (let i = 0; i < unqInputPinLabels.length; i++) {
2749
+ const inputLabels = unqInputPinLabels[i];
2750
+ for (const label of inputLabels) {
2751
+ if (/^\d+$/.test(label)) {
2752
+ continue;
2753
+ }
2754
+ if (totalLabelCounts[label] === 1) {
2755
+ result[i].push(label);
2756
+ } else {
2757
+ incrementalLabelCounts[label] = (incrementalLabelCounts[label] ?? 0) + 1;
2758
+ result[i].push(`${label}${incrementalLabelCounts[label]}`);
2759
+ }
2760
+ }
2761
+ }
2762
+ return result;
2763
+ };
2764
+
2765
+ // lib/convert-easyeda-json-to-tscircuit-soup-json.ts
2766
+ var mil2mm = (mil) => {
2767
+ if (typeof mil === "number") return mm3(`${mil}mil`);
2768
+ if (mil.match(/^\d+$/)) return mm3(`${mil}mil`);
2769
+ return mm3(mil);
2770
+ };
2771
+ var milx10 = (mil10) => {
2772
+ if (typeof mil10 === "number") return mil2mm(mil10) * 10;
2773
+ if (mil10.match(/^\d+$/)) return mil2mm(mil10) * 10;
2774
+ return mil2mm(mil10);
2775
+ };
2776
+ var handleSilkscreenPath = (track, index) => {
2777
+ return pcb_silkscreen_path.parse({
2778
+ type: "pcb_silkscreen_path",
2779
+ pcb_silkscreen_path_id: `pcb_silkscreen_path_${index + 1}`,
2780
+ pcb_component_id: "pcb_component_1",
2781
+ layer: "top",
2782
+ // Assuming all silkscreen is on top layer
2783
+ route: track.points.map((point2) => ({
2784
+ x: milx10(point2.x),
2785
+ y: milx10(point2.y)
2786
+ })),
2787
+ stroke_width: mil10ToMm(track.width)
2788
+ });
2789
+ };
2790
+ var handleSilkscreenArc = (arc, index) => {
2791
+ const arcPath = generateArcFromSweep(
2792
+ arc.start.x,
2793
+ arc.start.y,
2794
+ arc.end.x,
2795
+ arc.end.y,
2796
+ arc.radiusX,
2797
+ arc.largeArc,
2798
+ arc.sweepDirection === "CW"
2799
+ );
2800
+ return pcb_silkscreen_path.parse({
2801
+ type: "pcb_silkscreen_path",
2802
+ pcb_silkscreen_path_id: `pcb_silkscreen_arc_${index + 1}`,
2803
+ pcb_component_id: "pcb_component_1",
2804
+ layer: "top",
2805
+ // Assuming all silkscreen is on top layer
2806
+ route: arcPath.map((p) => ({
2807
+ x: milx10(p.x),
2808
+ y: milx10(p.y)
2809
+ })),
2810
+ stroke_width: mil10ToMm(arc.width)
2811
+ });
2812
+ };
2813
+ var handleHole = (hole, index) => {
2814
+ return pcb_hole.parse({
2815
+ type: "pcb_hole",
2816
+ x: milx10(hole.center.x),
2817
+ y: milx10(hole.center.y),
2818
+ hole_diameter: milx10(hole.radius) * 2,
2819
+ hole_shape: "circle",
2820
+ pcb_hole_id: `pcb_hole_${index + 1}`
2821
+ });
2822
+ };
2823
+ var convertEasyEdaJsonToCircuitJson = (easyEdaJson, { useModelCdn, shouldRecenter = true } = {}) => {
2824
+ const soupElements = [];
2825
+ const centerOffset = computeCenterOffset(easyEdaJson);
2826
+ const source_component = any_source_component.parse({
2827
+ type: "source_component",
2828
+ source_component_id: "source_component_1",
2829
+ name: "U1",
2830
+ ftype: "simple_bug"
2831
+ });
2832
+ const pcb_component2 = pcb_component.parse({
2833
+ type: "pcb_component",
2834
+ pcb_component_id: "pcb_component_1",
2835
+ source_component_id: "source_component_1",
2836
+ name: "U1",
2837
+ ftype: "simple_bug",
2838
+ width: 0,
2839
+ // we update this at the end
2840
+ height: 0,
2841
+ // we update this at the end
2842
+ rotation: 0,
2843
+ center: { x: 0, y: 0 },
2844
+ layer: "top"
2845
+ });
2846
+ soupElements.push(source_component, pcb_component2);
2847
+ const pads = easyEdaJson.packageDetail.dataStr.shape.filter(
2848
+ (shape) => shape.type === "PAD"
2849
+ );
2850
+ const pins = easyEdaJson.dataStr.shape.filter((shape) => shape.type === "PIN");
2851
+ const pinLabelSets = pads.map((pad) => {
2852
+ const labels = [];
2853
+ if (pad.number) labels.push(pad.number.toString());
2854
+ const pin = pins.find((p) => p.pinNumber === pad.number);
2855
+ if (pin) labels.push(pin.label);
2856
+ return labels;
2857
+ });
2858
+ const normalizedPinLabels = normalizePinLabels(pinLabelSets);
2859
+ pads.forEach((pad, index) => {
2860
+ const portHints = normalizedPinLabels[index];
2861
+ const pinNumber = Number.parseInt(
2862
+ portHints.find((hint) => hint.match(/pin\d+/)).replace("pin", "")
2863
+ );
2864
+ soupElements.push({
2865
+ type: "source_port",
2866
+ source_port_id: `source_port_${index + 1}`,
2867
+ source_component_id: "source_component_1",
2868
+ name: `pin${pinNumber}`,
2869
+ pin_number: pinNumber,
2870
+ port_hints: portHints.filter((hint) => hint !== `pin${pinNumber}`)
2871
+ });
2872
+ if (pad.holeRadius !== void 0 && mil2mm(pad.holeRadius) !== 0) {
2873
+ const commonPlatedHoleProps = {
2874
+ type: "pcb_plated_hole",
2875
+ pcb_plated_hole_id: `pcb_plated_hole_${index + 1}`,
2876
+ x: mil2mm(pad.center.x),
2877
+ y: mil2mm(pad.center.y),
2878
+ layers: ["top"],
2879
+ port_hints: [`pin${pinNumber}`],
2880
+ pcb_component_id: "pcb_component_1",
2881
+ pcb_port_id: `pcb_port_${index + 1}`
2882
+ };
2883
+ let additionalPlatedHoleProps;
2884
+ if (pad.shape === "OVAL") {
2885
+ const largestOuterDimensionName = mil2mm(pad.width) > mil2mm(pad.height) ? "width" : "height";
2886
+ const smallestOuterDimension = Math.min(
2887
+ mil2mm(pad.width),
2888
+ mil2mm(pad.height)
2889
+ );
2890
+ const largestOuterDimension = Math.max(
2891
+ mil2mm(pad.width),
2892
+ mil2mm(pad.height)
2893
+ );
2894
+ const distanceFromOuterPlatingToHole = smallestOuterDimension / 2 - mil2mm(pad.holeRadius);
2895
+ const largestInnerDimension = largestOuterDimension - distanceFromOuterPlatingToHole * 2;
2896
+ const smallestInnerDimension = mil2mm(pad.holeRadius) * 2;
2897
+ const innerWidth = largestOuterDimensionName === "width" ? largestInnerDimension : smallestInnerDimension;
2898
+ const innerHeight = largestOuterDimensionName === "height" ? largestInnerDimension : smallestInnerDimension;
2899
+ additionalPlatedHoleProps = {
2900
+ shape: "pill",
2901
+ outer_width: mil2mm(pad.width),
2902
+ outer_height: mil2mm(pad.height),
2903
+ hole_width: innerWidth,
2904
+ hole_height: innerHeight
2905
+ };
2906
+ } else {
2907
+ additionalPlatedHoleProps = {
2908
+ shape: "circle",
2909
+ hole_diameter: mil2mm(pad.holeRadius) * 2,
2910
+ outer_diameter: mil2mm(pad.width),
2911
+ radius: mil2mm(pad.holeRadius)
2912
+ };
2913
+ }
2914
+ soupElements.push(
2915
+ pcb_plated_hole.parse({
2916
+ ...commonPlatedHoleProps,
2917
+ ...additionalPlatedHoleProps
2918
+ })
2919
+ );
2920
+ } else {
2921
+ let soupShape;
2922
+ if (pad.shape === "RECT") {
2923
+ soupShape = "rect";
2924
+ } else if (pad.shape === "ELLIPSE") {
2925
+ soupShape = "rect";
2926
+ } else if (pad.shape === "OVAL") {
2927
+ soupShape = "rect";
2928
+ }
2929
+ if (!soupShape) {
2930
+ throw new Error(`unknown pad.shape: "${pad.shape}"`);
2931
+ }
2932
+ const rectSize = { width: mil2mm(pad.width), height: mil2mm(pad.height) };
2933
+ if (pad.rotation === 90 || pad.rotation === 270) {
2934
+ rectSize.width = mil2mm(pad.height);
2935
+ rectSize.height = mil2mm(pad.width);
2936
+ }
2937
+ const parsedPcbSmtpad = pcb_smtpad.parse({
2938
+ type: "pcb_smtpad",
2939
+ pcb_smtpad_id: `pcb_smtpad_${index + 1}`,
2940
+ shape: soupShape,
2941
+ x: mil2mm(pad.center.x),
2942
+ y: mil2mm(pad.center.y),
2943
+ ...soupShape === "rect" ? rectSize : { radius: Math.min(mil2mm(pad.width), mil2mm(pad.height)) / 2 },
2944
+ layer: "top",
2945
+ port_hints: [`pin${pinNumber}`],
2946
+ pcb_component_id: "pcb_component_1",
2947
+ pcb_port_id: `pcb_port_${index + 1}`
2948
+ });
2949
+ soupElements.push(parsedPcbSmtpad);
2950
+ }
2951
+ });
2952
+ easyEdaJson.packageDetail.dataStr.shape.filter(
2953
+ (shape) => shape.type === "HOLE"
2954
+ ).forEach((h, index) => {
2955
+ soupElements.push(handleHole(h, index));
2956
+ });
2957
+ easyEdaJson.packageDetail.dataStr.shape.forEach((shape, index) => {
2958
+ if (shape.type === "TRACK") {
2959
+ soupElements.push(handleSilkscreenPath(shape, index));
2960
+ } else if (shape.type === "ARC") {
2961
+ soupElements.push(handleSilkscreenArc(shape, index));
2962
+ } else if (shape.type === "TEXT") {
2963
+ soupElements.push(
2964
+ pcb_silkscreen_text.parse({
2965
+ type: "pcb_silkscreen_text",
2966
+ pcb_silkscreen_text_id: `pcb_silkscreen_text_${index + 1}`,
2967
+ pcb_component_id: "pcb_component_1",
2968
+ text: shape.text,
2969
+ anchor_position: {
2970
+ x: mil2mm(shape.x),
2971
+ y: mil2mm(shape.y)
2972
+ },
2973
+ anchor_alignment: {
2974
+ L: "bottom_left",
2975
+ C: "center",
2976
+ R: "bottom_right"
2977
+ }[shape.textAnchor ?? "L"],
2978
+ font_size: shape.size_mm ? shape.size_mm : void 0,
2979
+ layer: "top"
2980
+ })
2981
+ );
2982
+ }
2983
+ });
2984
+ const svgNode = easyEdaJson.packageDetail.dataStr.shape.find(
2985
+ (a) => Boolean(a.type === "SVGNODE" && a.svgData.attrs?.uuid)
2986
+ );
2987
+ const objFileUuid = svgNode?.svgData?.attrs?.uuid;
2988
+ const objFileUrl = objFileUuid ? useModelCdn ? `https://modelcdn.tscircuit.com/easyeda_models/download?uuid=${objFileUuid}&pn=${easyEdaJson.lcsc.number}` : `https://modules.easyeda.com/3dmodel/${objFileUuid}` : void 0;
2989
+ if (objFileUrl !== void 0) {
2990
+ const [rx, ry, rz] = (svgNode?.svgData.attrs?.c_rotation ?? "0,0,0").split(",").map(Number);
2991
+ soupElements.push(
2992
+ cad_component.parse({
2993
+ type: "cad_component",
2994
+ cad_component_id: "cad_component_1",
2995
+ source_component_id: "source_component_1",
2996
+ pcb_component_id: "pcb_component_1",
2997
+ position: { x: 0, y: 0, z: 0 },
2998
+ rotation: { x: rx, y: ry, z: rz },
2999
+ model_obj_url: objFileUrl
3000
+ })
3001
+ );
3002
+ }
3003
+ if (shouldRecenter) {
3004
+ const bounds = findBoundsAndCenter(
3005
+ // exclude the pcb_component because it's center is currently incorrect,
3006
+ // we set it to (0,0)
3007
+ soupElements.filter((e) => e.type !== "pcb_component")
3008
+ );
3009
+ transformPCBElements(
3010
+ soupElements,
3011
+ compose(translate(-bounds.center.x, bounds.center.y), scale(1, -1))
3012
+ );
3013
+ pcb_component2.center = { x: 0, y: 0 };
3014
+ }
3015
+ return soupElements;
3016
+ };
3017
+
3018
+ // lib/utils/normalize-manufacturer-part-number.ts
3019
+ function normalizeManufacturerPartNumber(partNumber) {
3020
+ let normalized = partNumber.replace(/[-]/g, "_").replace(/[^a-zA-Z0-9_$]/g, "_");
3021
+ if (/^\d/.test(normalized)) {
3022
+ normalized = "A_" + normalized;
3023
+ }
3024
+ return normalized;
3025
+ }
3026
+
3027
+ // lib/websafe/convert-to-typescript-component/index.tsx
3028
+ var convertRawEasyToTsx = async (rawEasy) => {
3029
+ const betterEasy = EasyEdaJsonSchema.parse(rawEasy);
3030
+ const result = await convertBetterEasyToTsx({
3031
+ betterEasy
3032
+ });
3033
+ return result;
3034
+ };
3035
+ var convertBetterEasyToTsx = async ({
3036
+ betterEasy
3037
+ }) => {
3038
+ const circuitJson = convertEasyEdaJsonToCircuitJson(betterEasy, {
3039
+ useModelCdn: true,
3040
+ shouldRecenter: true
3041
+ });
3042
+ const rawPn = betterEasy.dataStr.head.c_para["Manufacturer Part"];
3043
+ const pn = normalizeManufacturerPartNumber(rawPn);
3044
+ const sourcePorts = su_default(circuitJson).source_port.list();
3045
+ const pinLabels = {};
3046
+ const sortedPorts = sourcePorts.sort((a, b) => {
3047
+ const aNum = parseInt(a.name.replace("pin", ""));
3048
+ const bNum = parseInt(b.name.replace("pin", ""));
3049
+ return aNum - bNum;
3050
+ });
3051
+ for (const sourcePort of sortedPorts) {
3052
+ pinLabels[sourcePort.name] = [
3053
+ sourcePort.name,
3054
+ ...sourcePort.port_hints ?? []
3055
+ ];
3056
+ }
3057
+ const [cadComponent] = su_default(circuitJson).cad_component.list();
3058
+ let modelObjUrl;
3059
+ if (cadComponent?.model_obj_url) {
3060
+ const isValidUrl = await checkModelObjUrlValidity(
3061
+ cadComponent.model_obj_url
3062
+ );
3063
+ if (isValidUrl) {
3064
+ modelObjUrl = cadComponent.model_obj_url;
3065
+ }
3066
+ }
3067
+ const supplierPartNumbers = {
3068
+ jlcpcb: [betterEasy.lcsc.number]
3069
+ };
3070
+ return generateTypescriptComponent({
3071
+ componentName: pn,
3072
+ manufacturerPartNumber: pn,
3073
+ pinLabels,
3074
+ objUrl: modelObjUrl,
3075
+ circuitJson,
3076
+ supplierPartNumbers
3077
+ });
3078
+ };
3079
+ var checkModelObjUrlValidity = async (url) => {
3080
+ try {
3081
+ const response = await fetch(url, { method: "HEAD" });
3082
+ return response.status === 200;
3083
+ } catch (error) {
3084
+ console.error(`Error checking model object URL ${url}:`, error);
3085
+ return false;
3086
+ }
3087
+ };
3088
+
3089
+ // lib/websafe/fetch-easyeda-json.ts
3090
+ async function fetchEasyEDAComponent(jlcpcbPartNumber, { fetch: fetch2 = globalThis.fetch } = {}) {
3091
+ const searchUrl = "https://easyeda.com/api/components/search";
3092
+ const componentUrl = (uuid) => `https://easyeda.com/api/components/${uuid}?version=6.4.7&uuid=${uuid}&datastrid=`;
3093
+ const searchHeaders = {
3094
+ authority: "easyeda.com",
3095
+ pragma: "no-cache",
3096
+ "cache-control": "no-cache",
3097
+ accept: "application/json, text/javascript, */*; q=0.01",
3098
+ "x-requested-with": "XMLHttpRequest",
3099
+ "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36",
3100
+ "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
3101
+ origin: "https://easyeda.com",
3102
+ "sec-fetch-site": "same-origin",
3103
+ "sec-fetch-mode": "cors",
3104
+ "sec-fetch-dest": "empty",
3105
+ referer: "https://easyeda.com/editor",
3106
+ "accept-language": "cs,en;q=0.9,sk;q=0.8,en-GB;q=0.7",
3107
+ cookie: "<PUT your cookies here>"
3108
+ };
3109
+ const searchData = `type=3&doctype%5B%5D=2&uid=0819f05c4eef4c71ace90d822a990e87&returnListStyle=classifyarr&wd=${jlcpcbPartNumber}&version=6.4.7`;
3110
+ const searchResponse = await fetch2(searchUrl, {
3111
+ method: "POST",
3112
+ headers: searchHeaders,
3113
+ body: searchData
3114
+ });
3115
+ if (!searchResponse.ok) {
3116
+ throw new Error("Failed to search for the component");
3117
+ }
3118
+ const searchResult = await searchResponse.json();
3119
+ if (!searchResult.success || !searchResult.result.lists.lcsc.length) {
3120
+ throw new Error("Component not found");
3121
+ }
3122
+ const bestMatchComponent = searchResult.result.lists.lcsc.find(
3123
+ (component) => component.dataStr.head.c_para["Supplier Part"] === jlcpcbPartNumber
3124
+ ) ?? searchResult.result.lists.lcsc[0];
3125
+ const componentUUID = bestMatchComponent.uuid;
3126
+ const componentResponse = await fetch2(componentUrl(componentUUID), {
3127
+ method: "GET",
3128
+ headers: {
3129
+ ...searchHeaders,
3130
+ referer: `https://easyeda.com/editor?uuid=${componentUUID}`
3131
+ }
3132
+ });
3133
+ if (!componentResponse.ok) {
3134
+ throw new Error("Failed to fetch the component details");
3135
+ }
3136
+ const componentResult = await componentResponse.json();
3137
+ return componentResult.result;
3138
+ }
3139
+
3140
+ // lib/websafe/get-model-cdn-url.ts
3141
+ var getModelCdnUrl = ({
3142
+ easyedaModelUuid,
3143
+ easyedaPartNumber
3144
+ }) => {
3145
+ return `https://modelcdn.tscircuit.com/easyeda_models/download?uuid=${easyedaModelUuid}&pn=${easyedaPartNumber}`;
3146
+ };
3147
+ export {
3148
+ convertBetterEasyToTsx,
3149
+ convertRawEasyToTsx,
3150
+ fetchEasyEDAComponent,
3151
+ generateFootprintTsx,
3152
+ getModelCdnUrl
3153
+ };
3154
+ //# sourceMappingURL=index.js.map