@tscircuit/copper-pour-solver 0.0.9 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -294,6 +294,9 @@ var convertCircuitJsonToInputProblem = (circuitJson, options) => {
294
294
  const source_traces = circuitJson.filter(
295
295
  (e) => e.type === "source_trace"
296
296
  );
297
+ const pcb_traces = circuitJson.filter(
298
+ (e) => e.type === "pcb_trace"
299
+ );
297
300
  const source_nets = circuitJson.filter(
298
301
  (e) => e.type === "source_net"
299
302
  );
@@ -333,6 +336,14 @@ var convertCircuitJsonToInputProblem = (circuitJson, options) => {
333
336
  ...sourceTraceIdToConnectivityKey,
334
337
  ...sourceNetIdToConnectivityKey
335
338
  };
339
+ const pcbTraceIdToConnectivityKey = Object.fromEntries(
340
+ pcb_traces.map(
341
+ (trace) => [
342
+ trace.pcb_trace_id,
343
+ trace.source_trace_id ? idToConnectivityKey[trace.source_trace_id] : void 0
344
+ ]
345
+ ).filter((entry) => Boolean(entry[1]))
346
+ );
336
347
  const pads = [];
337
348
  for (const elm of circuitJson) {
338
349
  if (elm.type === "pcb_smtpad") {
@@ -399,25 +410,57 @@ var convertCircuitJsonToInputProblem = (circuitJson, options) => {
399
410
  y: hole.y,
400
411
  radius: hole.hole_diameter / 2
401
412
  });
413
+ } else if (elm.type === "pcb_via") {
414
+ const via = elm;
415
+ if (!via.layers.includes(options.layer)) continue;
416
+ let connectivityKey;
417
+ if (via.pcb_trace_id) {
418
+ connectivityKey = pcbTraceIdToConnectivityKey[via.pcb_trace_id];
419
+ }
420
+ if (!connectivityKey) {
421
+ connectivityKey = `unconnected-via:${via.pcb_via_id}`;
422
+ }
423
+ pads.push({
424
+ shape: "circle",
425
+ padId: via.pcb_via_id,
426
+ layer: options.layer,
427
+ connectivityKey,
428
+ x: via.x,
429
+ y: via.y,
430
+ radius: via.outer_diameter / 2
431
+ });
402
432
  } else if (elm.type === "pcb_trace") {
403
433
  const trace = elm;
404
- const first_wire = trace.route.find(
405
- (r) => r.route_type === "wire" && r.layer
406
- );
407
- if (!first_wire) continue;
408
- if (first_wire.route_type === "via") continue;
409
- if (first_wire.layer !== options.layer) continue;
410
434
  if (!trace.source_trace_id) continue;
411
435
  const connectivityKey = idToConnectivityKey[trace.source_trace_id];
412
436
  if (!connectivityKey) continue;
413
- pads.push({
414
- shape: "trace",
415
- padId: trace.pcb_trace_id,
416
- layer: first_wire.layer,
417
- connectivityKey,
418
- segments: trace.route.map((r) => ({ x: r.x, y: r.y })),
419
- width: first_wire.width
420
- });
437
+ let currentSegmentGroup = [];
438
+ let currentWidth = null;
439
+ const commitGroup = () => {
440
+ if (currentSegmentGroup.length > 1) {
441
+ pads.push({
442
+ shape: "trace",
443
+ padId: `${trace.pcb_trace_id}-${pads.length}`,
444
+ layer: options.layer,
445
+ connectivityKey,
446
+ segments: currentSegmentGroup,
447
+ width: currentWidth
448
+ });
449
+ }
450
+ currentSegmentGroup = [];
451
+ currentWidth = null;
452
+ };
453
+ for (const r of trace.route) {
454
+ const ri = r;
455
+ const isWireOnLayer = ri.route_type === "wire" && ri.layer === options.layer;
456
+ if (isWireOnLayer) {
457
+ if (currentWidth === null) currentWidth = ri.width;
458
+ currentSegmentGroup.push({ x: ri.x, y: ri.y });
459
+ } else {
460
+ commitGroup();
461
+ }
462
+ }
463
+ commitGroup();
421
464
  }
422
465
  }
423
466
  const { width, height } = pcb_board;
@@ -7,6 +7,8 @@ import type {
7
7
  PcbPort,
8
8
  PcbSmtPad,
9
9
  PcbTrace,
10
+ PcbVia,
11
+ Point,
10
12
  SourceNet,
11
13
  SourcePort,
12
14
  SourceTrace,
@@ -38,6 +40,9 @@ export const convertCircuitJsonToInputProblem = (
38
40
  const source_traces = circuitJson.filter(
39
41
  (e) => e.type === "source_trace",
40
42
  ) as SourceTrace[]
43
+ const pcb_traces = circuitJson.filter(
44
+ (e) => e.type === "pcb_trace",
45
+ ) as PcbTrace[]
41
46
  const source_nets = circuitJson.filter(
42
47
  (e) => e.type === "source_net",
43
48
  ) as SourceNet[]
@@ -87,6 +92,21 @@ export const convertCircuitJsonToInputProblem = (
87
92
  ...sourceNetIdToConnectivityKey,
88
93
  }
89
94
 
95
+ const pcbTraceIdToConnectivityKey: Record<string, string> =
96
+ Object.fromEntries(
97
+ pcb_traces
98
+ .map(
99
+ (trace) =>
100
+ [
101
+ trace.pcb_trace_id,
102
+ trace.source_trace_id
103
+ ? idToConnectivityKey[trace.source_trace_id]
104
+ : undefined,
105
+ ] as const,
106
+ )
107
+ .filter((entry): entry is [string, string] => Boolean(entry[1])),
108
+ )
109
+
90
110
  const pads: InputPad[] = []
91
111
 
92
112
  for (const elm of circuitJson) {
@@ -160,27 +180,64 @@ export const convertCircuitJsonToInputProblem = (
160
180
  y: hole.y,
161
181
  radius: hole.hole_diameter / 2,
162
182
  } as InputCircularPad)
183
+ } else if (elm.type === "pcb_via") {
184
+ const via = elm as PcbVia
185
+ if (!via.layers.includes(options.layer)) continue
186
+
187
+ let connectivityKey: string | undefined
188
+ if (via.pcb_trace_id) {
189
+ connectivityKey = pcbTraceIdToConnectivityKey[via.pcb_trace_id]
190
+ }
191
+
192
+ if (!connectivityKey) {
193
+ connectivityKey = `unconnected-via:${via.pcb_via_id}`
194
+ }
195
+
196
+ pads.push({
197
+ shape: "circle",
198
+ padId: via.pcb_via_id,
199
+ layer: options.layer,
200
+ connectivityKey,
201
+ x: via.x,
202
+ y: via.y,
203
+ radius: via.outer_diameter / 2,
204
+ } as InputCircularPad)
163
205
  } else if (elm.type === "pcb_trace") {
164
206
  const trace = elm as PcbTrace
165
- const first_wire = trace.route.find(
166
- (r: any) => r.route_type === "wire" && r.layer,
167
- )
168
- if (!first_wire) continue
169
- if (first_wire.route_type === "via") continue
170
- if (first_wire.layer !== options.layer) continue
171
-
172
207
  if (!trace.source_trace_id) continue
173
208
  const connectivityKey = idToConnectivityKey[trace.source_trace_id]
174
209
  if (!connectivityKey) continue
175
210
 
176
- pads.push({
177
- shape: "trace",
178
- padId: trace.pcb_trace_id,
179
- layer: first_wire.layer!,
180
- connectivityKey,
181
- segments: trace.route.map((r: any) => ({ x: r.x, y: r.y })),
182
- width: first_wire.width,
183
- } as InputTracePad)
211
+ let currentSegmentGroup: Point[] = []
212
+ let currentWidth: number | null = null
213
+
214
+ const commitGroup = () => {
215
+ if (currentSegmentGroup.length > 1) {
216
+ pads.push({
217
+ shape: "trace",
218
+ padId: `${trace.pcb_trace_id}-${pads.length}`,
219
+ layer: options.layer,
220
+ connectivityKey,
221
+ segments: currentSegmentGroup,
222
+ width: currentWidth!,
223
+ } as InputTracePad)
224
+ }
225
+ currentSegmentGroup = []
226
+ currentWidth = null
227
+ }
228
+
229
+ for (const r of trace.route) {
230
+ const ri = r as any
231
+ const isWireOnLayer =
232
+ ri.route_type === "wire" && ri.layer === options.layer
233
+ if (isWireOnLayer) {
234
+ if (currentWidth === null) currentWidth = ri.width
235
+ currentSegmentGroup.push({ x: ri.x, y: ri.y })
236
+ } else {
237
+ commitGroup()
238
+ }
239
+ }
240
+ commitGroup()
184
241
  }
185
242
  }
186
243
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/copper-pour-solver",
3
3
  "main": "dist/index.js",
4
- "version": "0.0.9",
4
+ "version": "0.0.10",
5
5
  "scripts": {
6
6
  "format": "biome format . --write",
7
7
  "format:check": "biome format .",
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="800" height="600" data-software-used-string="@tscircuit/core@0.0.849"><style></style><rect class="boundary" x="0" y="0" fill="#000" width="800" height="600" data-type="pcb_background" data-pcb-layer="global"/><rect class="pcb-boundary" fill="none" stroke="#fff" stroke-width="0.3" x="150" y="50" width="500" height="500" data-type="pcb_boundary" data-pcb-layer="global"/><rect class="pcb-pad" fill="rgb(77, 127, 196)" x="284" y="284" width="27" height="32" data-type="pcb_smtpad" data-pcb-layer="bottom"/><rect class="pcb-pad" fill="rgb(77, 127, 196)" x="233" y="284" width="27" height="32" data-type="pcb_smtpad" data-pcb-layer="bottom"/><path class="pcb-trace" stroke="rgb(77, 127, 196)" fill="none" d="M 297.5 300 L 297.5 379.512341162088" stroke-width="7.5" stroke-linecap="round" stroke-linejoin="round" shape-rendering="crispEdges" data-type="pcb_trace" data-pcb-layer="bottom"/><path class="pcb-trace" stroke="rgb(77, 127, 196)" fill="none" d="M 297.5 379.512341162088 L 303.1454224777405 385.1577636398285" stroke-width="7.5" stroke-linecap="round" stroke-linejoin="round" shape-rendering="crispEdges" data-type="pcb_trace" data-pcb-layer="bottom"/><path class="pcb-trace" stroke="rgb(77, 127, 196)" fill="none" d="M 303.1454224777405 385.1577636398285 L 306.25 393.75" stroke-width="7.5" stroke-linecap="round" stroke-linejoin="round" shape-rendering="crispEdges" data-type="pcb_trace" data-pcb-layer="bottom"/><path class="pcb-trace" stroke="rgb(77, 127, 196)" fill="none" d="M 306.25 393.75 L 306.25 393.75" stroke-width="7.5" stroke-linecap="round" stroke-linejoin="round" shape-rendering="crispEdges" data-type="pcb_trace" data-pcb-layer="bottom"/><path class="pcb-silkscreen pcb-silkscreen-bottom" d="M 246.5 264 L 321 264 L 321 336 L 246.5 336" fill="none" stroke="#5da9e9" stroke-width="5" stroke-linecap="round" stroke-linejoin="round" data-pcb-component-id="pcb_component_1" data-pcb-silkscreen-path-id="pcb_silkscreen_path_1" data-type="pcb_silkscreen_path" data-pcb-layer="bottom"/><text x="0" y="0" dx="0" dy="0" fill="#5da9e9" font-family="Arial, sans-serif" font-size="20" text-anchor="middle" dominant-baseline="central" transform="matrix(-1,0,0,1,272,239)" class="pcb-silkscreen-text pcb-silkscreen-bottom" data-pcb-silkscreen-text-id="pcb_component_1" stroke="none" data-type="pcb_silkscreen_text" data-pcb-layer="bottom">C1</text><path class="pcb-board" d="M 150 550 L 650 550 L 650 50 L 150 50 Z" fill="none" stroke="rgba(255, 255, 255, 0.5)" stroke-width="5" data-type="pcb_board" data-pcb-layer="board"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="361" y="284" width="27" height="32" data-type="pcb_smtpad" data-pcb-layer="top"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="412" y="284" width="27" height="32" data-type="pcb_smtpad" data-pcb-layer="top"/><path class="pcb-trace" stroke="rgb(200, 52, 52)" fill="none" d="M 306.25 393.75 L 306.25 393.75" stroke-width="7.5" stroke-linecap="round" stroke-linejoin="round" shape-rendering="crispEdges" data-type="pcb_trace" data-pcb-layer="top"/><path class="pcb-trace" stroke="rgb(200, 52, 52)" fill="none" d="M 306.25 393.75 L 306.25 368.25" stroke-width="7.5" stroke-linecap="round" stroke-linejoin="round" shape-rendering="crispEdges" data-type="pcb_trace" data-pcb-layer="top"/><path class="pcb-trace" stroke="rgb(200, 52, 52)" fill="none" d="M 306.25 368.25 L 374.5 300" stroke-width="7.5" stroke-linecap="round" stroke-linejoin="round" shape-rendering="crispEdges" data-type="pcb_trace" data-pcb-layer="top"/><path class="pcb-copper-pour pcb-copper-pour-brep" d="M 150 550 L 150 50 L 650 50 L 650 550 L 150 550 Z M 316.0805385563561 370.7938301144085 L 360.87436867076457 326 L 398 326 L 398 274 L 351 274 L 351 311.12563132923543 L 300.0628156646177 362.0628156646177 L 298.97464089235274 363.3887604610785 L 298.16605409052625 364.9015199668055 L 297.6681287964717 366.54295968235886 L 297.5 368.25 L 297.5 370.40515141679646 L 296.6829141908728 370.6530116872178 L 292.36074417450993 372.9632596924364 L 288.5723304703363 376.0723304703363 L 285.4632596924364 379.86074417450993 L 283.1530116872178 384.18291419087274 L 281.7303679899193 388.8727419495968 L 281.25 393.75 L 281.7303679899193 398.6272580504032 L 283.1530116872178 403.3170858091272 L 285.46325969243634 407.63925582549007 L 288.5723304703363 411.4276695296637 L 292.36074417450993 414.5367403075636 L 296.68291419087274 416.8469883127822 L 301.3727419495968 418.2696320100807 L 306.25 418.75 L 311.1272580504032 418.2696320100807 L 315.81708580912726 416.8469883127822 L 320.13925582549007 414.53674030756366 L 323.9276695296637 411.4276695296637 L 327.0367403075636 407.63925582549007 L 329.3469883127822 403.31708580912726 L 330.7696320100807 398.6272580504032 L 331.25 393.75 L 330.7696320100807 388.8727419495968 L 329.3469883127822 384.1829141908728 L 327.0367403075636 379.86074417450993 L 323.9276695296637 376.0723304703363 L 320.13925582549007 372.9632596924364 L 316.0805385563561 370.7938301144085 Z" fill="rgb(200, 52, 52)" fill-rule="evenodd" fill-opacity="0.5" data-type="pcb_copper_pour" data-pcb-layer="top"/><path class="pcb-silkscreen pcb-silkscreen-top" d="M 425.5 264 L 351 264 L 351 336 L 425.5 336" fill="none" stroke="#f2eda1" stroke-width="5" stroke-linecap="round" stroke-linejoin="round" data-pcb-component-id="pcb_component_0" data-pcb-silkscreen-path-id="pcb_silkscreen_path_0" data-type="pcb_silkscreen_path" data-pcb-layer="top"/><text x="0" y="0" dx="0" dy="0" fill="#f2eda1" font-family="Arial, sans-serif" font-size="20" text-anchor="middle" dominant-baseline="central" transform="matrix(1,0,0,1,400,239)" class="pcb-silkscreen-text pcb-silkscreen-top" data-pcb-silkscreen-text-id="pcb_component_0" stroke="none" data-type="pcb_silkscreen_text" data-pcb-layer="top">R1</text><g data-type="pcb_via" data-pcb-layer="through"><circle class="pcb-hole-outer" fill="rgb(200, 52, 52)" cx="306.25" cy="393.75" r="15" data-type="pcb_via" data-pcb-layer="top"/><circle class="pcb-hole-inner" fill="#FF26E2" cx="306.25" cy="393.75" r="7.5" data-type="pcb_via" data-pcb-layer="drill"/></g></svg>
@@ -0,0 +1,716 @@
1
+ [
2
+ {
3
+ "type": "source_project_metadata",
4
+ "source_project_metadata_id": "source_project_metadata_0",
5
+ "software_used_string": "@tscircuit/core@0.0.849"
6
+ },
7
+ {
8
+ "type": "source_group",
9
+ "source_group_id": "source_group_0",
10
+ "is_subcircuit": true,
11
+ "was_automatically_named": true,
12
+ "subcircuit_id": "subcircuit_source_group_0"
13
+ },
14
+ {
15
+ "type": "source_net",
16
+ "source_net_id": "source_net_0",
17
+ "name": "GND",
18
+ "member_source_group_ids": [],
19
+ "is_ground": true,
20
+ "is_power": false,
21
+ "is_positive_voltage_source": false,
22
+ "subcircuit_id": "subcircuit_source_group_0",
23
+ "subcircuit_connectivity_map_key": "unnamedsubcircuit410_connectivity_net0"
24
+ },
25
+ {
26
+ "type": "source_port",
27
+ "source_port_id": "source_port_0",
28
+ "name": "pin1",
29
+ "pin_number": 1,
30
+ "port_hints": ["pin1", "anode", "pos", "left", "1"],
31
+ "source_component_id": "source_component_0",
32
+ "subcircuit_id": "subcircuit_source_group_0",
33
+ "subcircuit_connectivity_map_key": "unnamedsubcircuit410_connectivity_net1"
34
+ },
35
+ {
36
+ "type": "source_port",
37
+ "source_port_id": "source_port_1",
38
+ "name": "pin2",
39
+ "pin_number": 2,
40
+ "port_hints": ["pin2", "cathode", "neg", "right", "2"],
41
+ "source_component_id": "source_component_0",
42
+ "subcircuit_id": "subcircuit_source_group_0",
43
+ "subcircuit_connectivity_map_key": "unnamedsubcircuit410_connectivity_net0"
44
+ },
45
+ {
46
+ "type": "source_component",
47
+ "source_component_id": "source_component_0",
48
+ "ftype": "simple_resistor",
49
+ "name": "R1",
50
+ "supplier_part_numbers": {
51
+ "jlcpcb": ["C11702", "C25543", "C2906864"]
52
+ },
53
+ "resistance": 1000,
54
+ "display_resistance": "1kΩ",
55
+ "are_pins_interchangeable": true,
56
+ "source_group_id": "source_group_0"
57
+ },
58
+ {
59
+ "type": "source_port",
60
+ "source_port_id": "source_port_2",
61
+ "name": "pin1",
62
+ "pin_number": 1,
63
+ "port_hints": ["pin1", "pos", "anode", "1"],
64
+ "source_component_id": "source_component_1",
65
+ "subcircuit_id": "subcircuit_source_group_0",
66
+ "subcircuit_connectivity_map_key": "unnamedsubcircuit410_connectivity_net1"
67
+ },
68
+ {
69
+ "type": "source_port",
70
+ "source_port_id": "source_port_3",
71
+ "name": "pin2",
72
+ "pin_number": 2,
73
+ "port_hints": ["pin2", "neg", "cathode", "2"],
74
+ "source_component_id": "source_component_1",
75
+ "subcircuit_id": "subcircuit_source_group_0"
76
+ },
77
+ {
78
+ "type": "source_component",
79
+ "source_component_id": "source_component_1",
80
+ "ftype": "simple_capacitor",
81
+ "name": "C1",
82
+ "supplier_part_numbers": {
83
+ "jlcpcb": ["C1523", "C696907", "C5137470"]
84
+ },
85
+ "capacitance": 1e-9,
86
+ "display_capacitance": "1000pF",
87
+ "are_pins_interchangeable": true,
88
+ "source_group_id": "source_group_0"
89
+ },
90
+ {
91
+ "type": "source_net",
92
+ "source_net_id": "source_net_1",
93
+ "name": "VCC",
94
+ "member_source_group_ids": [],
95
+ "is_ground": false,
96
+ "is_power": true,
97
+ "is_positive_voltage_source": true,
98
+ "subcircuit_id": "subcircuit_source_group_0",
99
+ "subcircuit_connectivity_map_key": "unnamedsubcircuit410_connectivity_net1"
100
+ },
101
+ {
102
+ "type": "source_board",
103
+ "source_board_id": "source_board_0",
104
+ "source_group_id": "source_group_0"
105
+ },
106
+ {
107
+ "type": "source_trace",
108
+ "source_trace_id": "source_trace_0",
109
+ "connected_source_port_ids": ["source_port_1"],
110
+ "connected_source_net_ids": ["source_net_0"],
111
+ "subcircuit_id": "subcircuit_source_group_0",
112
+ "display_name": ".R1 > .pin2 to net.GND",
113
+ "subcircuit_connectivity_map_key": "unnamedsubcircuit410_connectivity_net0"
114
+ },
115
+ {
116
+ "type": "source_trace",
117
+ "source_trace_id": "source_trace_1",
118
+ "connected_source_port_ids": ["source_port_0"],
119
+ "connected_source_net_ids": ["source_net_1"],
120
+ "subcircuit_id": "subcircuit_source_group_0",
121
+ "display_name": ".R1 > .pin1 to net.VCC",
122
+ "subcircuit_connectivity_map_key": "unnamedsubcircuit410_connectivity_net1"
123
+ },
124
+ {
125
+ "type": "source_trace",
126
+ "source_trace_id": "source_trace_2",
127
+ "connected_source_port_ids": ["source_port_2"],
128
+ "connected_source_net_ids": ["source_net_1"],
129
+ "subcircuit_id": "subcircuit_source_group_0",
130
+ "max_length": null,
131
+ "display_name": ".C1 > .pin1 to net.VCC",
132
+ "subcircuit_connectivity_map_key": "unnamedsubcircuit410_connectivity_net1"
133
+ },
134
+ {
135
+ "type": "source_pin_missing_trace_warning",
136
+ "source_pin_missing_trace_warning_id": "source_pin_missing_trace_warning_0",
137
+ "message": "Port pin2 on C1 is missing a trace",
138
+ "source_component_id": "source_component_1",
139
+ "source_port_id": "source_port_3",
140
+ "subcircuit_id": "subcircuit_source_group_0",
141
+ "warning_type": "source_pin_missing_trace_warning"
142
+ },
143
+ {
144
+ "type": "schematic_component",
145
+ "schematic_component_id": "schematic_component_0",
146
+ "center": {
147
+ "x": 0,
148
+ "y": 0
149
+ },
150
+ "size": {
151
+ "width": 1.1,
152
+ "height": 0.388910699999999
153
+ },
154
+ "source_component_id": "source_component_0",
155
+ "is_box_with_pins": true,
156
+ "symbol_name": "boxresistor_right",
157
+ "symbol_display_value": "1kΩ",
158
+ "schematic_group_id": "schematic_group_0"
159
+ },
160
+ {
161
+ "type": "schematic_component",
162
+ "schematic_component_id": "schematic_component_1",
163
+ "center": {
164
+ "x": 0,
165
+ "y": -1.8144553499999994
166
+ },
167
+ "size": {
168
+ "width": 1.1,
169
+ "height": 0.84
170
+ },
171
+ "source_component_id": "source_component_1",
172
+ "is_box_with_pins": true,
173
+ "symbol_name": "capacitor_right",
174
+ "symbol_display_value": "1000pF",
175
+ "schematic_group_id": "schematic_group_0"
176
+ },
177
+ {
178
+ "type": "schematic_group",
179
+ "schematic_group_id": "schematic_group_0",
180
+ "is_subcircuit": true,
181
+ "subcircuit_id": "subcircuit_source_group_0",
182
+ "name": "unnamed_board1",
183
+ "center": {
184
+ "x": 0,
185
+ "y": 0
186
+ },
187
+ "width": 0,
188
+ "height": 0,
189
+ "schematic_component_ids": [],
190
+ "source_group_id": "source_group_0"
191
+ },
192
+ {
193
+ "type": "schematic_port",
194
+ "schematic_port_id": "schematic_port_0",
195
+ "schematic_component_id": "schematic_component_0",
196
+ "center": {
197
+ "x": -0.55,
198
+ "y": 0
199
+ },
200
+ "source_port_id": "source_port_0",
201
+ "facing_direction": "left",
202
+ "distance_from_component_edge": 0.4,
203
+ "pin_number": 1,
204
+ "display_pin_label": "anode",
205
+ "is_connected": true
206
+ },
207
+ {
208
+ "type": "schematic_port",
209
+ "schematic_port_id": "schematic_port_1",
210
+ "schematic_component_id": "schematic_component_0",
211
+ "center": {
212
+ "x": 0.55,
213
+ "y": 0
214
+ },
215
+ "source_port_id": "source_port_1",
216
+ "facing_direction": "right",
217
+ "distance_from_component_edge": 0.4,
218
+ "pin_number": 2,
219
+ "display_pin_label": "cathode",
220
+ "is_connected": false
221
+ },
222
+ {
223
+ "type": "schematic_port",
224
+ "schematic_port_id": "schematic_port_2",
225
+ "schematic_component_id": "schematic_component_1",
226
+ "center": {
227
+ "x": -0.55,
228
+ "y": -1.8144553499999994
229
+ },
230
+ "source_port_id": "source_port_2",
231
+ "facing_direction": "left",
232
+ "distance_from_component_edge": 0.4,
233
+ "pin_number": 1,
234
+ "display_pin_label": "pos",
235
+ "is_connected": true
236
+ },
237
+ {
238
+ "type": "schematic_port",
239
+ "schematic_port_id": "schematic_port_3",
240
+ "schematic_component_id": "schematic_component_1",
241
+ "center": {
242
+ "x": 0.55,
243
+ "y": -1.8144553499999994
244
+ },
245
+ "source_port_id": "source_port_3",
246
+ "facing_direction": "right",
247
+ "distance_from_component_edge": 0.4,
248
+ "pin_number": 2,
249
+ "display_pin_label": "neg",
250
+ "is_connected": false
251
+ },
252
+ {
253
+ "type": "schematic_trace",
254
+ "schematic_trace_id": "schematic_trace_0",
255
+ "source_trace_id": "solver_R1.1-C1.1",
256
+ "edges": [
257
+ {
258
+ "from": {
259
+ "x": -0.55,
260
+ "y": 0
261
+ },
262
+ "to": {
263
+ "x": -0.75,
264
+ "y": 0
265
+ }
266
+ },
267
+ {
268
+ "from": {
269
+ "x": -0.75,
270
+ "y": 0
271
+ },
272
+ "to": {
273
+ "x": -0.75,
274
+ "y": -1.8144553499999994
275
+ }
276
+ },
277
+ {
278
+ "from": {
279
+ "x": -0.75,
280
+ "y": -1.8144553499999994
281
+ },
282
+ "to": {
283
+ "x": -0.55,
284
+ "y": -1.8144553499999994
285
+ }
286
+ }
287
+ ],
288
+ "junctions": [],
289
+ "subcircuit_connectivity_map_key": "unnamedsubcircuit410_connectivity_net1"
290
+ },
291
+ {
292
+ "type": "schematic_net_label",
293
+ "schematic_net_label_id": "schematic_net_label_0",
294
+ "text": "VCC",
295
+ "anchor_position": {
296
+ "x": -0.75,
297
+ "y": 0
298
+ },
299
+ "center": {
300
+ "x": -0.75,
301
+ "y": 0.09
302
+ },
303
+ "anchor_side": "bottom",
304
+ "source_net_id": "source_net_1",
305
+ "symbol_name": "rail_up"
306
+ },
307
+ {
308
+ "type": "schematic_net_label",
309
+ "schematic_net_label_id": "schematic_net_label_1",
310
+ "text": "GND",
311
+ "anchor_position": {
312
+ "x": 0.55,
313
+ "y": 0
314
+ },
315
+ "center": {
316
+ "x": 0.7000000000000001,
317
+ "y": 0
318
+ },
319
+ "anchor_side": "left",
320
+ "source_net_id": "source_net_0"
321
+ },
322
+ {
323
+ "type": "pcb_component",
324
+ "pcb_component_id": "pcb_component_0",
325
+ "center": {
326
+ "x": 0,
327
+ "y": 0
328
+ },
329
+ "width": 1.56,
330
+ "height": 0.64,
331
+ "layer": "top",
332
+ "rotation": 0,
333
+ "source_component_id": "source_component_0",
334
+ "subcircuit_id": "subcircuit_source_group_0",
335
+ "do_not_place": false,
336
+ "obstructs_within_bounds": true
337
+ },
338
+ {
339
+ "type": "pcb_component",
340
+ "pcb_component_id": "pcb_component_1",
341
+ "center": {
342
+ "x": -2.5600000000000005,
343
+ "y": 0
344
+ },
345
+ "width": 1.56,
346
+ "height": 0.64,
347
+ "layer": "bottom",
348
+ "rotation": 0,
349
+ "source_component_id": "source_component_1",
350
+ "subcircuit_id": "subcircuit_source_group_0",
351
+ "do_not_place": false,
352
+ "obstructs_within_bounds": true
353
+ },
354
+ {
355
+ "type": "pcb_board",
356
+ "pcb_board_id": "pcb_board_0",
357
+ "center": {
358
+ "x": 0,
359
+ "y": 0
360
+ },
361
+ "thickness": 1.4,
362
+ "num_layers": 2,
363
+ "width": 10,
364
+ "height": 10,
365
+ "material": "fr4"
366
+ },
367
+ {
368
+ "type": "pcb_smtpad",
369
+ "pcb_smtpad_id": "pcb_smtpad_0",
370
+ "pcb_component_id": "pcb_component_0",
371
+ "pcb_port_id": "pcb_port_0",
372
+ "layer": "top",
373
+ "shape": "rect",
374
+ "width": 0.54,
375
+ "height": 0.64,
376
+ "port_hints": ["1", "left"],
377
+ "is_covered_with_solder_mask": false,
378
+ "x": -0.51,
379
+ "y": 0,
380
+ "subcircuit_id": "subcircuit_source_group_0"
381
+ },
382
+ {
383
+ "type": "pcb_solder_paste",
384
+ "pcb_solder_paste_id": "pcb_solder_paste_0",
385
+ "layer": "top",
386
+ "shape": "rect",
387
+ "width": 0.378,
388
+ "height": 0.44799999999999995,
389
+ "x": -0.51,
390
+ "y": 0,
391
+ "pcb_component_id": "pcb_component_0",
392
+ "pcb_smtpad_id": "pcb_smtpad_0",
393
+ "subcircuit_id": "subcircuit_source_group_0"
394
+ },
395
+ {
396
+ "type": "pcb_smtpad",
397
+ "pcb_smtpad_id": "pcb_smtpad_1",
398
+ "pcb_component_id": "pcb_component_0",
399
+ "pcb_port_id": "pcb_port_1",
400
+ "layer": "top",
401
+ "shape": "rect",
402
+ "width": 0.54,
403
+ "height": 0.64,
404
+ "port_hints": ["2", "right"],
405
+ "is_covered_with_solder_mask": false,
406
+ "x": 0.51,
407
+ "y": 0,
408
+ "subcircuit_id": "subcircuit_source_group_0"
409
+ },
410
+ {
411
+ "type": "pcb_solder_paste",
412
+ "pcb_solder_paste_id": "pcb_solder_paste_1",
413
+ "layer": "top",
414
+ "shape": "rect",
415
+ "width": 0.378,
416
+ "height": 0.44799999999999995,
417
+ "x": 0.51,
418
+ "y": 0,
419
+ "pcb_component_id": "pcb_component_0",
420
+ "pcb_smtpad_id": "pcb_smtpad_1",
421
+ "subcircuit_id": "subcircuit_source_group_0"
422
+ },
423
+ {
424
+ "type": "pcb_silkscreen_path",
425
+ "pcb_silkscreen_path_id": "pcb_silkscreen_path_0",
426
+ "pcb_component_id": "pcb_component_0",
427
+ "layer": "top",
428
+ "route": [
429
+ {
430
+ "x": 0.51,
431
+ "y": 0.72
432
+ },
433
+ {
434
+ "x": -0.98,
435
+ "y": 0.72
436
+ },
437
+ {
438
+ "x": -0.98,
439
+ "y": -0.72
440
+ },
441
+ {
442
+ "x": 0.51,
443
+ "y": -0.72
444
+ }
445
+ ],
446
+ "stroke_width": 0.1,
447
+ "subcircuit_id": "subcircuit_source_group_0"
448
+ },
449
+ {
450
+ "type": "pcb_silkscreen_text",
451
+ "pcb_silkscreen_text_id": "pcb_silkscreen_text_0",
452
+ "anchor_alignment": "center",
453
+ "anchor_position": {
454
+ "x": 0,
455
+ "y": 1.22
456
+ },
457
+ "font": "tscircuit2024",
458
+ "font_size": 0.4,
459
+ "layer": "top",
460
+ "text": "R1",
461
+ "ccw_rotation": 0,
462
+ "pcb_component_id": "pcb_component_0",
463
+ "subcircuit_id": "subcircuit_source_group_0"
464
+ },
465
+ {
466
+ "type": "pcb_smtpad",
467
+ "pcb_smtpad_id": "pcb_smtpad_2",
468
+ "pcb_component_id": "pcb_component_1",
469
+ "pcb_port_id": "pcb_port_2",
470
+ "layer": "bottom",
471
+ "shape": "rect",
472
+ "width": 0.54,
473
+ "height": 0.64,
474
+ "port_hints": ["1", "left"],
475
+ "is_covered_with_solder_mask": false,
476
+ "x": -2.0500000000000007,
477
+ "y": 0,
478
+ "subcircuit_id": "subcircuit_source_group_0"
479
+ },
480
+ {
481
+ "type": "pcb_solder_paste",
482
+ "pcb_solder_paste_id": "pcb_solder_paste_2",
483
+ "layer": "bottom",
484
+ "shape": "rect",
485
+ "width": 0.378,
486
+ "height": 0.44799999999999995,
487
+ "x": 0.51,
488
+ "y": 0,
489
+ "pcb_component_id": "pcb_component_1",
490
+ "pcb_smtpad_id": "pcb_smtpad_2",
491
+ "subcircuit_id": "subcircuit_source_group_0"
492
+ },
493
+ {
494
+ "type": "pcb_smtpad",
495
+ "pcb_smtpad_id": "pcb_smtpad_3",
496
+ "pcb_component_id": "pcb_component_1",
497
+ "pcb_port_id": "pcb_port_3",
498
+ "layer": "bottom",
499
+ "shape": "rect",
500
+ "width": 0.54,
501
+ "height": 0.64,
502
+ "port_hints": ["2", "right"],
503
+ "is_covered_with_solder_mask": false,
504
+ "x": -3.0700000000000003,
505
+ "y": 0,
506
+ "subcircuit_id": "subcircuit_source_group_0"
507
+ },
508
+ {
509
+ "type": "pcb_solder_paste",
510
+ "pcb_solder_paste_id": "pcb_solder_paste_3",
511
+ "layer": "bottom",
512
+ "shape": "rect",
513
+ "width": 0.378,
514
+ "height": 0.44799999999999995,
515
+ "x": -0.51,
516
+ "y": 0,
517
+ "pcb_component_id": "pcb_component_1",
518
+ "pcb_smtpad_id": "pcb_smtpad_3",
519
+ "subcircuit_id": "subcircuit_source_group_0"
520
+ },
521
+ {
522
+ "type": "pcb_silkscreen_path",
523
+ "pcb_silkscreen_path_id": "pcb_silkscreen_path_1",
524
+ "pcb_component_id": "pcb_component_1",
525
+ "layer": "bottom",
526
+ "route": [
527
+ {
528
+ "x": -3.0700000000000003,
529
+ "y": 0.72
530
+ },
531
+ {
532
+ "x": -1.5800000000000005,
533
+ "y": 0.72
534
+ },
535
+ {
536
+ "x": -1.5800000000000005,
537
+ "y": -0.72
538
+ },
539
+ {
540
+ "x": -3.0700000000000003,
541
+ "y": -0.72
542
+ }
543
+ ],
544
+ "stroke_width": 0.1,
545
+ "subcircuit_id": "subcircuit_source_group_0"
546
+ },
547
+ {
548
+ "type": "pcb_silkscreen_text",
549
+ "pcb_silkscreen_text_id": "pcb_silkscreen_text_1",
550
+ "anchor_alignment": "center",
551
+ "anchor_position": {
552
+ "x": -2.5600000000000005,
553
+ "y": 1.22
554
+ },
555
+ "font": "tscircuit2024",
556
+ "font_size": 0.4,
557
+ "layer": "bottom",
558
+ "text": "C1",
559
+ "ccw_rotation": 0,
560
+ "pcb_component_id": "pcb_component_1",
561
+ "subcircuit_id": "subcircuit_source_group_0"
562
+ },
563
+ {
564
+ "type": "pcb_port",
565
+ "pcb_port_id": "pcb_port_0",
566
+ "pcb_component_id": "pcb_component_0",
567
+ "layers": ["top"],
568
+ "subcircuit_id": "subcircuit_source_group_0",
569
+ "x": -0.51,
570
+ "y": 0,
571
+ "source_port_id": "source_port_0"
572
+ },
573
+ {
574
+ "type": "pcb_port",
575
+ "pcb_port_id": "pcb_port_1",
576
+ "pcb_component_id": "pcb_component_0",
577
+ "layers": ["top"],
578
+ "subcircuit_id": "subcircuit_source_group_0",
579
+ "x": 0.51,
580
+ "y": 0,
581
+ "source_port_id": "source_port_1"
582
+ },
583
+ {
584
+ "type": "pcb_port",
585
+ "pcb_port_id": "pcb_port_2",
586
+ "pcb_component_id": "pcb_component_1",
587
+ "layers": ["bottom"],
588
+ "subcircuit_id": "subcircuit_source_group_0",
589
+ "x": -2.0500000000000007,
590
+ "y": 0,
591
+ "source_port_id": "source_port_2"
592
+ },
593
+ {
594
+ "type": "pcb_port",
595
+ "pcb_port_id": "pcb_port_3",
596
+ "pcb_component_id": "pcb_component_1",
597
+ "layers": ["bottom"],
598
+ "subcircuit_id": "subcircuit_source_group_0",
599
+ "x": -3.0700000000000003,
600
+ "y": 0,
601
+ "source_port_id": "source_port_3"
602
+ },
603
+ {
604
+ "type": "cad_component",
605
+ "cad_component_id": "cad_component_0",
606
+ "position": {
607
+ "x": 0,
608
+ "y": 0,
609
+ "z": 0.7
610
+ },
611
+ "rotation": {
612
+ "x": 0,
613
+ "y": 0,
614
+ "z": 0
615
+ },
616
+ "pcb_component_id": "pcb_component_0",
617
+ "source_component_id": "source_component_0",
618
+ "footprinter_string": "0402"
619
+ },
620
+ {
621
+ "type": "cad_component",
622
+ "cad_component_id": "cad_component_1",
623
+ "position": {
624
+ "x": -2.5600000000000005,
625
+ "y": 0,
626
+ "z": -0.7
627
+ },
628
+ "rotation": {
629
+ "x": 0,
630
+ "y": 180,
631
+ "z": 0
632
+ },
633
+ "pcb_component_id": "pcb_component_1",
634
+ "source_component_id": "source_component_1",
635
+ "footprinter_string": "0402"
636
+ },
637
+ {
638
+ "type": "pcb_trace",
639
+ "pcb_trace_id": "source_net_1_0",
640
+ "connection_name": "source_net_1",
641
+ "route": [
642
+ {
643
+ "route_type": "wire",
644
+ "x": -2.0500000000000007,
645
+ "y": 0,
646
+ "width": 0.15,
647
+ "layer": "bottom",
648
+ "start_pcb_port_id": "pcb_port_2"
649
+ },
650
+ {
651
+ "route_type": "wire",
652
+ "x": -2.0500000000000007,
653
+ "y": -1.5902468232417593,
654
+ "width": 0.15,
655
+ "layer": "bottom"
656
+ },
657
+ {
658
+ "route_type": "wire",
659
+ "x": -1.93709155044519,
660
+ "y": -1.70315527279657,
661
+ "width": 0.15,
662
+ "layer": "bottom"
663
+ },
664
+ {
665
+ "route_type": "wire",
666
+ "x": -1.875,
667
+ "y": -1.875,
668
+ "width": 0.15,
669
+ "layer": "bottom"
670
+ },
671
+ {
672
+ "route_type": "via",
673
+ "x": -1.875,
674
+ "y": -1.875,
675
+ "from_layer": "bottom",
676
+ "to_layer": "top"
677
+ },
678
+ {
679
+ "route_type": "wire",
680
+ "x": -1.875,
681
+ "y": -1.875,
682
+ "width": 0.15,
683
+ "layer": "top"
684
+ },
685
+ {
686
+ "route_type": "wire",
687
+ "x": -1.875,
688
+ "y": -1.365,
689
+ "width": 0.15,
690
+ "layer": "top"
691
+ },
692
+ {
693
+ "route_type": "wire",
694
+ "x": -0.51,
695
+ "y": 0,
696
+ "width": 0.15,
697
+ "layer": "top",
698
+ "end_pcb_port_id": "pcb_port_0"
699
+ }
700
+ ],
701
+ "subcircuit_id": "subcircuit_source_group_0",
702
+ "source_trace_id": "source_net_1"
703
+ },
704
+ {
705
+ "type": "pcb_via",
706
+ "pcb_via_id": "pcb_via_0",
707
+ "pcb_trace_id": "source_net_1_0",
708
+ "x": -1.875,
709
+ "y": -1.875,
710
+ "hole_diameter": 0.3,
711
+ "outer_diameter": 0.6,
712
+ "layers": ["bottom", "top"],
713
+ "from_layer": "bottom",
714
+ "to_layer": "top"
715
+ }
716
+ ]
@@ -0,0 +1,15 @@
1
+ import { expect, test } from "bun:test"
2
+ import circuitJson from "./assets/via.json"
3
+ import { runSolverAndRenderToSvg } from "./utils/run-solver-and-render-to-svg"
4
+ import type { AnyCircuitElement } from "circuit-json"
5
+
6
+ test("via", async () => {
7
+ const svg = runSolverAndRenderToSvg(circuitJson as AnyCircuitElement[], {
8
+ layer: "top",
9
+ net_name: "GND",
10
+ pad_margin: 0.2,
11
+ trace_margin: 0.1,
12
+ })
13
+
14
+ await expect(svg).toMatchSvgSnapshot(import.meta.path, "via")
15
+ })