@tscircuit/copper-pour-solver 0.0.8 → 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.
@@ -47,12 +47,12 @@ jobs:
47
47
  committer: tscircuitbot <githubbot@tscircuit.com>
48
48
  author: tscircuitbot <githubbot@tscircuit.com>
49
49
 
50
- # - name: Enable auto-merge
51
- # if: steps.create-pr.outputs.pull-request-number != ''
52
- # run: |
53
- # gh pr merge ${{ steps.create-pr.outputs.pull-request-number }} --auto --squash --delete-branch
54
- # env:
55
- # GH_TOKEN: ${{ secrets.TSCIRCUIT_BOT_GITHUB_TOKEN }}
50
+ - name: Enable auto-merge
51
+ if: steps.create-pr.outputs.pull-request-number != ''
52
+ run: |
53
+ gh pr merge ${{ steps.create-pr.outputs.pull-request-number }} --auto --squash --delete-branch
54
+ env:
55
+ GH_TOKEN: ${{ secrets.TSCIRCUIT_BOT_GITHUB_TOKEN }}
56
56
 
57
57
  # - name: Trigger upstream repo updates
58
58
  # if: env.UPSTREAM_REPOS && env.UPSTREAM_PACKAGES_TO_UPDATE
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.8",
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
+ })