circuit-json-to-lbrn 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.
Files changed (39) hide show
  1. package/README.md +39 -2
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.js +596 -122
  4. package/lib/ConvertContext.ts +4 -0
  5. package/lib/element-handlers/addPcbTrace/index.ts +7 -1
  6. package/lib/element-handlers/addPlatedHole/addCirclePlatedHole.ts +38 -4
  7. package/lib/element-handlers/addPlatedHole/addCircularHoleWithRectPad.ts +32 -11
  8. package/lib/element-handlers/addPlatedHole/addHoleWithPolygonPad.ts +31 -9
  9. package/lib/element-handlers/addPlatedHole/addOvalPlatedHole.ts +38 -4
  10. package/lib/element-handlers/addPlatedHole/addPillHoleWithRectPad.ts +31 -9
  11. package/lib/element-handlers/addPlatedHole/addPillPlatedHole.ts +38 -4
  12. package/lib/element-handlers/addPlatedHole/addRotatedPillHoleWithRectPad.ts +31 -9
  13. package/lib/element-handlers/addSmtPad/addCircleSmtPad.ts +62 -0
  14. package/lib/element-handlers/addSmtPad/addPillSmtPad.ts +58 -0
  15. package/lib/element-handlers/addSmtPad/addPolygonSmtPad.ts +57 -0
  16. package/lib/element-handlers/addSmtPad/addRectSmtPad.ts +80 -12
  17. package/lib/element-handlers/addSmtPad/addRotatedPillSmtPad.ts +64 -0
  18. package/lib/element-handlers/addSmtPad/addRotatedRectSmtPad.ts +68 -0
  19. package/lib/element-handlers/addSmtPad/index.ts +25 -7
  20. package/lib/helpers/pathToPolygon.ts +14 -0
  21. package/lib/index.ts +39 -32
  22. package/package.json +2 -2
  23. package/tests/examples/__snapshots__/lga-interconnect.snap.svg +1 -1
  24. package/tests/examples/addPlatedHole/__snapshots__/pcb-plated-hole-circle.snap.svg +1 -1
  25. package/tests/examples/addPlatedHole/__snapshots__/pcb-plated-hole-oval.snap.svg +1 -1
  26. package/tests/examples/addSmtPad/__snapshots__/circleSmtPad.snap.svg +8 -0
  27. package/tests/examples/addSmtPad/__snapshots__/pillSmtPad.snap.svg +8 -0
  28. package/tests/examples/addSmtPad/__snapshots__/polygonSmtPad.snap.svg +8 -0
  29. package/tests/examples/addSmtPad/__snapshots__/rotatedPillSmtPad.snap.svg +8 -0
  30. package/tests/examples/addSmtPad/__snapshots__/rotatedRectSmtPad.snap.svg +8 -0
  31. package/tests/examples/addSmtPad/circleSmtPad.test.ts +45 -0
  32. package/tests/examples/addSmtPad/pillSmtPad.test.ts +47 -0
  33. package/tests/examples/addSmtPad/polygonSmtPad.test.ts +51 -0
  34. package/tests/examples/addSmtPad/rotatedPillSmtPad.test.ts +48 -0
  35. package/tests/examples/addSmtPad/rotatedRectSmtPad.test.ts +59 -0
  36. package/tests/examples/soldermask/__snapshots__/copper-and-soldermask.snap.svg +8 -0
  37. package/tests/examples/soldermask/__snapshots__/soldermask-only.snap.svg +8 -0
  38. package/tests/examples/soldermask/copper-and-soldermask.test.ts +96 -0
  39. package/tests/examples/soldermask/soldermask-only.test.ts +96 -0
@@ -0,0 +1,45 @@
1
+ import { test, expect } from "bun:test"
2
+ import { convertCircuitJsonToPcbSvg } from "circuit-to-svg"
3
+ import { generateLightBurnSvg } from "lbrnts"
4
+ import { convertCircuitJsonToLbrn } from "../../../lib"
5
+ import { stackSvgsVertically } from "stack-svgs"
6
+ import type { CircuitJson } from "circuit-json"
7
+
8
+ const circuitJson: CircuitJson = [
9
+ {
10
+ type: "source_port",
11
+ name: "via1",
12
+ source_port_id: "source_port_1",
13
+ },
14
+ {
15
+ type: "pcb_board",
16
+ pcb_board_id: "board",
17
+ width: 10,
18
+ height: 10,
19
+ center: { x: 0, y: 0 },
20
+ thickness: 1.6,
21
+ num_layers: 2,
22
+ material: "fr4",
23
+ },
24
+ {
25
+ type: "pcb_smtpad",
26
+ x: 0,
27
+ y: 0,
28
+ layer: "top",
29
+ shape: "circle",
30
+ pcb_smtpad_id: "pcb_smt_pad_1",
31
+ radius: 1,
32
+ },
33
+ ]
34
+
35
+ test("renders a circle smt pad", async () => {
36
+ const pcbSvg = await convertCircuitJsonToPcbSvg(circuitJson)
37
+
38
+ const project = convertCircuitJsonToLbrn(circuitJson)
39
+
40
+ const lbrnSvg = await generateLightBurnSvg(project)
41
+
42
+ expect(stackSvgsVertically([pcbSvg, lbrnSvg])).toMatchSvgSnapshot(
43
+ import.meta.filename,
44
+ )
45
+ })
@@ -0,0 +1,47 @@
1
+ import { test, expect } from "bun:test"
2
+ import { convertCircuitJsonToPcbSvg } from "circuit-to-svg"
3
+ import { generateLightBurnSvg } from "lbrnts"
4
+ import { convertCircuitJsonToLbrn } from "../../../lib"
5
+ import { stackSvgsVertically } from "stack-svgs"
6
+ import type { CircuitJson } from "circuit-json"
7
+
8
+ const circuitJson: CircuitJson = [
9
+ {
10
+ type: "source_port",
11
+ name: "via1",
12
+ source_port_id: "source_port_1",
13
+ },
14
+ {
15
+ type: "pcb_board",
16
+ pcb_board_id: "board",
17
+ width: 10,
18
+ height: 10,
19
+ center: { x: 0, y: 0 },
20
+ thickness: 1.6,
21
+ num_layers: 2,
22
+ material: "fr4",
23
+ },
24
+ {
25
+ type: "pcb_smtpad",
26
+ x: 0,
27
+ y: 0,
28
+ layer: "top",
29
+ shape: "pill",
30
+ pcb_smtpad_id: "pcb_smt_pad_1",
31
+ width: 2,
32
+ height: 1,
33
+ radius: 0.5,
34
+ },
35
+ ]
36
+
37
+ test("renders a pill smt pad", async () => {
38
+ const pcbSvg = await convertCircuitJsonToPcbSvg(circuitJson)
39
+
40
+ const project = convertCircuitJsonToLbrn(circuitJson)
41
+
42
+ const lbrnSvg = await generateLightBurnSvg(project)
43
+
44
+ expect(stackSvgsVertically([pcbSvg, lbrnSvg])).toMatchSvgSnapshot(
45
+ import.meta.filename,
46
+ )
47
+ })
@@ -0,0 +1,51 @@
1
+ import { test, expect } from "bun:test"
2
+ import { convertCircuitJsonToPcbSvg } from "circuit-to-svg"
3
+ import { generateLightBurnSvg } from "lbrnts"
4
+ import { convertCircuitJsonToLbrn } from "../../../lib"
5
+ import { stackSvgsVertically } from "stack-svgs"
6
+ import type { CircuitJson } from "circuit-json"
7
+
8
+ const circuitJson: CircuitJson = [
9
+ {
10
+ type: "source_port",
11
+ name: "via1",
12
+ source_port_id: "source_port_1",
13
+ },
14
+ {
15
+ type: "pcb_board",
16
+ pcb_board_id: "board",
17
+ width: 10,
18
+ height: 10,
19
+ center: { x: 0, y: 0 },
20
+ thickness: 1.6,
21
+ num_layers: 2,
22
+ material: "fr4",
23
+ },
24
+ {
25
+ type: "pcb_smtpad",
26
+ layer: "top",
27
+ shape: "polygon",
28
+ pcb_smtpad_id: "pcb_smt_pad_1",
29
+ points: [
30
+ { x: 0, y: 0 },
31
+ { x: 2, y: 0 },
32
+ { x: 2, y: 1 },
33
+ { x: 1, y: 1 },
34
+ { x: 1, y: 2 },
35
+ { x: 0, y: 2 },
36
+ { x: 0, y: 1 },
37
+ ],
38
+ },
39
+ ]
40
+
41
+ test("renders a polygon smt pad", async () => {
42
+ const pcbSvg = await convertCircuitJsonToPcbSvg(circuitJson)
43
+
44
+ const project = convertCircuitJsonToLbrn(circuitJson)
45
+
46
+ const lbrnSvg = await generateLightBurnSvg(project)
47
+
48
+ expect(stackSvgsVertically([pcbSvg, lbrnSvg])).toMatchSvgSnapshot(
49
+ import.meta.filename,
50
+ )
51
+ })
@@ -0,0 +1,48 @@
1
+ import { test, expect } from "bun:test"
2
+ import { convertCircuitJsonToPcbSvg } from "circuit-to-svg"
3
+ import { generateLightBurnSvg } from "lbrnts"
4
+ import { convertCircuitJsonToLbrn } from "../../../lib"
5
+ import { stackSvgsVertically } from "stack-svgs"
6
+ import type { CircuitJson } from "circuit-json"
7
+
8
+ const circuitJson: CircuitJson = [
9
+ {
10
+ type: "source_port",
11
+ name: "via1",
12
+ source_port_id: "source_port_1",
13
+ },
14
+ {
15
+ type: "pcb_board",
16
+ pcb_board_id: "board",
17
+ width: 10,
18
+ height: 10,
19
+ center: { x: 0, y: 0 },
20
+ thickness: 1.6,
21
+ num_layers: 2,
22
+ material: "fr4",
23
+ },
24
+ {
25
+ type: "pcb_smtpad",
26
+ x: 0,
27
+ y: 0,
28
+ layer: "top",
29
+ shape: "rotated_pill",
30
+ pcb_smtpad_id: "pcb_smt_pad_1",
31
+ width: 2,
32
+ height: 1,
33
+ radius: 0.5,
34
+ ccw_rotation: 45,
35
+ },
36
+ ]
37
+
38
+ test("renders a rotated pill smt pad", async () => {
39
+ const pcbSvg = await convertCircuitJsonToPcbSvg(circuitJson)
40
+
41
+ const project = convertCircuitJsonToLbrn(circuitJson)
42
+
43
+ const lbrnSvg = await generateLightBurnSvg(project)
44
+
45
+ expect(stackSvgsVertically([pcbSvg, lbrnSvg])).toMatchSvgSnapshot(
46
+ import.meta.filename,
47
+ )
48
+ })
@@ -0,0 +1,59 @@
1
+ import { test, expect } from "bun:test"
2
+ import { convertCircuitJsonToPcbSvg } from "circuit-to-svg"
3
+ import { generateLightBurnSvg } from "lbrnts"
4
+ import { convertCircuitJsonToLbrn } from "../../../lib"
5
+ import { stackSvgsVertically } from "stack-svgs"
6
+ import type { CircuitJson } from "circuit-json"
7
+
8
+ const circuitJson: CircuitJson = [
9
+ {
10
+ type: "source_port",
11
+ name: "via1",
12
+ source_port_id: "source_port_1",
13
+ },
14
+ {
15
+ type: "pcb_board",
16
+ pcb_board_id: "board",
17
+ width: 10,
18
+ height: 10,
19
+ center: { x: 0, y: 0 },
20
+ thickness: 1.6,
21
+ num_layers: 2,
22
+ material: "fr4",
23
+ },
24
+ {
25
+ type: "pcb_smtpad",
26
+ x: -2,
27
+ y: 0,
28
+ layer: "top",
29
+ shape: "rotated_rect",
30
+ pcb_smtpad_id: "pcb_smt_pad_1",
31
+ width: 2,
32
+ height: 2,
33
+ ccw_rotation: 45,
34
+ rect_border_radius: 0.5,
35
+ },
36
+ {
37
+ type: "pcb_smtpad",
38
+ x: 2,
39
+ y: 0,
40
+ layer: "top",
41
+ shape: "rotated_rect",
42
+ pcb_smtpad_id: "pcb_smt_pad_1",
43
+ width: 2,
44
+ height: 2,
45
+ ccw_rotation: 0,
46
+ },
47
+ ]
48
+
49
+ test("renders a rotated rect smt pad", async () => {
50
+ const pcbSvg = await convertCircuitJsonToPcbSvg(circuitJson)
51
+
52
+ const project = convertCircuitJsonToLbrn(circuitJson)
53
+
54
+ const lbrnSvg = await generateLightBurnSvg(project)
55
+
56
+ expect(stackSvgsVertically([pcbSvg, lbrnSvg])).toMatchSvgSnapshot(
57
+ import.meta.filename,
58
+ )
59
+ })
@@ -0,0 +1,8 @@
1
+ <svg width="800" height="1400" viewBox="0 0 800 1400" xmlns="http://www.w3.org/2000/svg">
2
+ <g transform="translate(0, 0)">
3
+ <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"/><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"/><circle class="pcb-pad" fill="rgb(200, 52, 52)" cx="300" cy="300" r="25" data-type="pcb_smtpad" data-pcb-layer="top"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="475" y="275" width="50" height="50" data-type="pcb_smtpad" data-pcb-layer="top"/><path class="pcb-trace" stroke="rgb(200, 52, 52)" fill="none" d="M 300 300 L 500 300" stroke-width="10" stroke-linecap="round" stroke-linejoin="round" shape-rendering="crispEdges" data-type="pcb_trace" data-pcb-layer="top"/>
4
+ </g>
5
+ <g transform="translate(0, 600) scale(26.666666666666668, 26.666666666666668) translate(12.4, 14.4)">
6
+ <rect x="-12.4" y="-14.4" width="30" height="30" fill="white"/><g transform="matrix(1 0 0 -1 0 1.1999999999999993)"><g transform="matrix(1,0,0,1,0,0)"><path d="M 1.1 0.6 L 1.0975923633360987 0.6490085701647803 L 1.0903926402016153 0.6975451610080641 L 1.0784701678661044 0.7451423386272311 L 1.0619397662556436 0.7913417161825449 L 1.0409606321741776 0.8356983684129988 L 1.0157348061512728 0.8777851165098011 L 0.9865052266813685 0.9171966420818227 L 0.9535533905932738 0.9535533905932737 L 0.9171966420818228 0.9865052266813685 L 0.8777851165098012 1.0157348061512725 L 0.835698368412999 1.0409606321741776 L 0.791341716182545 1.0619397662556433 L 0.7451423386272312 1.0784701678661044 L 0.6975451610080643 1.0903926402016153 L 0.6490085701647805 1.0975923633360984 L 0.6000000000000001 1.1 L 0.5509914298352198 1.0975923633360984 L 0.502454838991936 1.0903926402016153 L 0.454857661372769 1.0784701678661044 L 0.4086582838174552 1.0619397662556433 L 0.36430163158700124 1.0409606321741776 L 0.3222148834901991 1.0157348061512725 L 0.2828033579181774 0.9865052266813685 L 0.24644660940672636 0.9535533905932738 L 0.2134947733186316 0.9171966420818227 L 0.18426519384872742 0.8777851165098011 L 0.15903936782582262 0.8356983684129989 L 0.13806023374435672 0.7913417161825449 L 0.12152983213389568 0.7451423386272311 L 0.10960735979838487 0.6975451610080643 L 0.10240763666390168 0.6490085701647804 L 0.10000000000000009 0.6000000000000001 L 0.10240763666390162 0.5509914298352196 L 0.10960735979838487 0.5024548389919358 L 0.12152983213389562 0.45485766137276895 L 0.13806023374435666 0.40865828381745517 L 0.15903936782582256 0.36430163158700113 L 0.18426519384872736 0.322214883490199 L 0.21349477331863154 0.28280335791817734 L 0.24644660940672625 0.24644660940672625 L 0.2828033579181772 0.21349477331863165 L 0.322214883490199 0.18426519384872736 L 0.36430163158700113 0.1590393678258225 L 0.40865828381745495 0.13806023374435672 L 0.45485766137276884 0.12152983213389557 L 0.5024548389919358 0.10960735979838482 L 0.5509914298352199 0.10240763666390151 L 0.6 0.09999999999999998 L 0.6490085701647801 0.10240763666390151 L 0.6975451610080643 0.10960735979838476 L 0.7451423386272311 0.12152983213389551 L 0.7913417161825451 0.13806023374435666 L 0.8356983684129988 0.15903936782582245 L 0.877785116509801 0.18426519384872725 L 0.9171966420818229 0.21349477331863154 L 0.9535533905932738 0.24644660940672614 L 0.9865052266813684 0.282803357918177 L 1.0157348061512728 0.3222148834901989 L 1.0409606321741776 0.364301631587001 L 1.0619397662556433 0.4086582838174548 L 1.0784701678661044 0.45485766137276873 L 1.0903926402016153 0.5024548389919357 L 1.0975923633360987 0.5509914298352198 L 1.1 0.6 L 1.1 0.6 Z" fill="none" stroke="#000000" stroke-width="0.1"/></g><g transform="matrix(1,0,0,1,0,0)"><path d="M 4.1 0.09999999999999998 L 5.1 0.09999999999999998 L 5.1 1.1 L 4.1 1.1 L 4.1 0.09999999999999998 L 4.1 0.09999999999999998 Z" fill="none" stroke="#000000" stroke-width="0.1"/></g><g transform="matrix(1,0,0,1,0,0)"><path d="M -2.4 -4.4 L 7.6 -4.4 L 7.6 5.6 L -2.4 5.6 L -2.4 -4.4 L -2.4 -4.4 Z" fill="none" stroke="#0000FF" stroke-width="0.1"/></g><g transform="matrix(1,0,0,1,0,0)"><path d="M 1.0896479729346218 0.7 L 1.0619397662556436 0.7913417161825449 L 1.0157348061512728 0.8777851165098011 L 0.9535533905932738 0.9535533905932737 L 0.8777851165098012 1.0157348061512725 L 0.791341716182545 1.0619397662556433 L 0.6975451610080643 1.0903926402016153 L 0.6000000000000001 1.1 L 0.502454838991936 1.0903926402016153 L 0.4086582838174552 1.0619397662556433 L 0.3222148834901991 1.0157348061512725 L 0.24644660940672636 0.9535533905932738 L 0.18426519384872742 0.8777851165098011 L 0.13806023374435672 0.7913417161825449 L 0.10960735979838487 0.6975451610080643 L 0.10000000000000009 0.6000000000000001 L 0.10960735979838487 0.5024548389919358 L 0.13806023374435666 0.40865828381745517 L 0.18426519384872736 0.322214883490199 L 0.24644660940672625 0.24644660940672625 L 0.322214883490199 0.18426519384872736 L 0.40865828381745495 0.13806023374435672 L 0.5024548389919358 0.10960735979838482 L 0.6 0.09999999999999998 L 0.6975451610080643 0.10960735979838476 L 0.7913417161825451 0.13806023374435666 L 0.877785116509801 0.18426519384872725 L 0.9535533905932738 0.24644660940672614 L 1.0157348061512728 0.3222148834901989 L 1.0619397662556433 0.4086582838174548 L 1.0896479729346216 0.5 L 4.1 0.5 L 4.1 0.09999999999999998 L 5.1 0.09999999999999998 L 5.1 1.1 L 4.1 1.1 L 4.1 0.7 L 1.0896479729346218 0.7 L 1.0896479729346218 0.7" fill="none" stroke="#000000" stroke-width="0.1"/></g></g>
7
+ </g>
8
+ </svg>
@@ -0,0 +1,8 @@
1
+ <svg width="800" height="1400" viewBox="0 0 800 1400" xmlns="http://www.w3.org/2000/svg">
2
+ <g transform="translate(0, 0)">
3
+ <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"/><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"/><circle class="pcb-pad" fill="rgb(200, 52, 52)" cx="300" cy="300" r="25" data-type="pcb_smtpad" data-pcb-layer="top"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="475" y="275" width="50" height="50" data-type="pcb_smtpad" data-pcb-layer="top"/><path class="pcb-trace" stroke="rgb(200, 52, 52)" fill="none" d="M 300 300 L 500 300" stroke-width="10" stroke-linecap="round" stroke-linejoin="round" shape-rendering="crispEdges" data-type="pcb_trace" data-pcb-layer="top"/>
4
+ </g>
5
+ <g transform="translate(0, 600) scale(26.666666666666668, 26.666666666666668) translate(12.4, 14.4)">
6
+ <rect x="-12.4" y="-14.4" width="30" height="30" fill="white"/><g transform="matrix(1 0 0 -1 0 1.1999999999999993)"><g transform="matrix(1,0,0,1,0,0)"><path d="M 1.1 0.6 L 1.0975923633360987 0.6490085701647803 L 1.0903926402016153 0.6975451610080641 L 1.0784701678661044 0.7451423386272311 L 1.0619397662556436 0.7913417161825449 L 1.0409606321741776 0.8356983684129988 L 1.0157348061512728 0.8777851165098011 L 0.9865052266813685 0.9171966420818227 L 0.9535533905932738 0.9535533905932737 L 0.9171966420818228 0.9865052266813685 L 0.8777851165098012 1.0157348061512725 L 0.835698368412999 1.0409606321741776 L 0.791341716182545 1.0619397662556433 L 0.7451423386272312 1.0784701678661044 L 0.6975451610080643 1.0903926402016153 L 0.6490085701647805 1.0975923633360984 L 0.6000000000000001 1.1 L 0.5509914298352198 1.0975923633360984 L 0.502454838991936 1.0903926402016153 L 0.454857661372769 1.0784701678661044 L 0.4086582838174552 1.0619397662556433 L 0.36430163158700124 1.0409606321741776 L 0.3222148834901991 1.0157348061512725 L 0.2828033579181774 0.9865052266813685 L 0.24644660940672636 0.9535533905932738 L 0.2134947733186316 0.9171966420818227 L 0.18426519384872742 0.8777851165098011 L 0.15903936782582262 0.8356983684129989 L 0.13806023374435672 0.7913417161825449 L 0.12152983213389568 0.7451423386272311 L 0.10960735979838487 0.6975451610080643 L 0.10240763666390168 0.6490085701647804 L 0.10000000000000009 0.6000000000000001 L 0.10240763666390162 0.5509914298352196 L 0.10960735979838487 0.5024548389919358 L 0.12152983213389562 0.45485766137276895 L 0.13806023374435666 0.40865828381745517 L 0.15903936782582256 0.36430163158700113 L 0.18426519384872736 0.322214883490199 L 0.21349477331863154 0.28280335791817734 L 0.24644660940672625 0.24644660940672625 L 0.2828033579181772 0.21349477331863165 L 0.322214883490199 0.18426519384872736 L 0.36430163158700113 0.1590393678258225 L 0.40865828381745495 0.13806023374435672 L 0.45485766137276884 0.12152983213389557 L 0.5024548389919358 0.10960735979838482 L 0.5509914298352199 0.10240763666390151 L 0.6 0.09999999999999998 L 0.6490085701647801 0.10240763666390151 L 0.6975451610080643 0.10960735979838476 L 0.7451423386272311 0.12152983213389551 L 0.7913417161825451 0.13806023374435666 L 0.8356983684129988 0.15903936782582245 L 0.877785116509801 0.18426519384872725 L 0.9171966420818229 0.21349477331863154 L 0.9535533905932738 0.24644660940672614 L 0.9865052266813684 0.282803357918177 L 1.0157348061512728 0.3222148834901989 L 1.0409606321741776 0.364301631587001 L 1.0619397662556433 0.4086582838174548 L 1.0784701678661044 0.45485766137276873 L 1.0903926402016153 0.5024548389919357 L 1.0975923633360987 0.5509914298352198 L 1.1 0.6 L 1.1 0.6 Z" fill="none" stroke="#000000" stroke-width="0.1"/></g><g transform="matrix(1,0,0,1,0,0)"><path d="M 4.1 0.09999999999999998 L 5.1 0.09999999999999998 L 5.1 1.1 L 4.1 1.1 L 4.1 0.09999999999999998 L 4.1 0.09999999999999998 Z" fill="none" stroke="#000000" stroke-width="0.1"/></g><g transform="matrix(1,0,0,1,0,0)"><path d="M -2.4 -4.4 L 7.6 -4.4 L 7.6 5.6 L -2.4 5.6 L -2.4 -4.4 L -2.4 -4.4 Z" fill="none" stroke="#0000FF" stroke-width="0.1"/></g></g>
7
+ </g>
8
+ </svg>
@@ -0,0 +1,96 @@
1
+ import { test, expect } from "bun:test"
2
+ import { convertCircuitJsonToPcbSvg } from "circuit-to-svg"
3
+ import { generateLightBurnSvg } from "lbrnts"
4
+ import { convertCircuitJsonToLbrn } from "../../../lib"
5
+ import { stackSvgsVertically } from "stack-svgs"
6
+ import type { CircuitJson } from "circuit-json"
7
+
8
+ const circuitJson: CircuitJson = [
9
+ {
10
+ type: "source_port",
11
+ name: "pad1",
12
+ source_port_id: "source_port_1",
13
+ },
14
+ {
15
+ type: "source_port",
16
+ name: "pad2",
17
+ source_port_id: "source_port_2",
18
+ },
19
+ {
20
+ type: "source_trace",
21
+ source_trace_id: "source_trace_1",
22
+ connected_source_port_ids: ["source_port_1", "source_port_2"],
23
+ connected_source_net_ids: [],
24
+ },
25
+ {
26
+ type: "pcb_board",
27
+ pcb_board_id: "board",
28
+ width: 10,
29
+ height: 10,
30
+ center: { x: 0, y: 0 },
31
+ thickness: 1.6,
32
+ num_layers: 2,
33
+ material: "fr4",
34
+ },
35
+ {
36
+ type: "pcb_smtpad",
37
+ x: -2,
38
+ y: 0,
39
+ layer: "top",
40
+ shape: "circle",
41
+ pcb_smtpad_id: "pcb_smt_pad_1",
42
+ pcb_port_id: "pcb_port_1",
43
+ radius: 0.5,
44
+ },
45
+ {
46
+ type: "pcb_port",
47
+ pcb_port_id: "pcb_port_1",
48
+ source_port_id: "source_port_1",
49
+ x: -2,
50
+ y: 0,
51
+ layers: ["top"],
52
+ },
53
+ {
54
+ type: "pcb_smtpad",
55
+ x: 2,
56
+ y: 0,
57
+ layer: "top",
58
+ shape: "rect",
59
+ pcb_smtpad_id: "pcb_smt_pad_2",
60
+ pcb_port_id: "pcb_port_2",
61
+ width: 1,
62
+ height: 1,
63
+ },
64
+ {
65
+ type: "pcb_port",
66
+ pcb_port_id: "pcb_port_2",
67
+ source_port_id: "source_port_2",
68
+ x: 2,
69
+ y: 0,
70
+ layers: ["top"],
71
+ },
72
+ {
73
+ type: "pcb_trace",
74
+ pcb_trace_id: "trace_1",
75
+ source_trace_id: "source_trace_1",
76
+ route: [
77
+ { x: -2, y: 0, width: 0.2, route_type: "wire", layer: "top" },
78
+ { x: 2, y: 0, width: 0.2, route_type: "wire", layer: "top" },
79
+ ],
80
+ },
81
+ ]
82
+
83
+ test("renders both copper and soldermask", async () => {
84
+ const pcbSvg = await convertCircuitJsonToPcbSvg(circuitJson)
85
+
86
+ const project = convertCircuitJsonToLbrn(circuitJson, {
87
+ includeCopper: true,
88
+ includeSoldermask: true,
89
+ })
90
+
91
+ const lbrnSvg = await generateLightBurnSvg(project)
92
+
93
+ expect(stackSvgsVertically([pcbSvg, lbrnSvg])).toMatchSvgSnapshot(
94
+ import.meta.filename,
95
+ )
96
+ })
@@ -0,0 +1,96 @@
1
+ import { test, expect } from "bun:test"
2
+ import { convertCircuitJsonToPcbSvg } from "circuit-to-svg"
3
+ import { generateLightBurnSvg } from "lbrnts"
4
+ import { convertCircuitJsonToLbrn } from "../../../lib"
5
+ import { stackSvgsVertically } from "stack-svgs"
6
+ import type { CircuitJson } from "circuit-json"
7
+
8
+ const circuitJson: CircuitJson = [
9
+ {
10
+ type: "source_port",
11
+ name: "pad1",
12
+ source_port_id: "source_port_1",
13
+ },
14
+ {
15
+ type: "source_port",
16
+ name: "pad2",
17
+ source_port_id: "source_port_2",
18
+ },
19
+ {
20
+ type: "source_trace",
21
+ source_trace_id: "source_trace_1",
22
+ connected_source_port_ids: ["source_port_1", "source_port_2"],
23
+ connected_source_net_ids: [],
24
+ },
25
+ {
26
+ type: "pcb_board",
27
+ pcb_board_id: "board",
28
+ width: 10,
29
+ height: 10,
30
+ center: { x: 0, y: 0 },
31
+ thickness: 1.6,
32
+ num_layers: 2,
33
+ material: "fr4",
34
+ },
35
+ {
36
+ type: "pcb_smtpad",
37
+ x: -2,
38
+ y: 0,
39
+ layer: "top",
40
+ shape: "circle",
41
+ pcb_smtpad_id: "pcb_smt_pad_1",
42
+ pcb_port_id: "pcb_port_1",
43
+ radius: 0.5,
44
+ },
45
+ {
46
+ type: "pcb_port",
47
+ pcb_port_id: "pcb_port_1",
48
+ source_port_id: "source_port_1",
49
+ x: -2,
50
+ y: 0,
51
+ layers: ["top"],
52
+ },
53
+ {
54
+ type: "pcb_smtpad",
55
+ x: 2,
56
+ y: 0,
57
+ layer: "top",
58
+ shape: "rect",
59
+ pcb_smtpad_id: "pcb_smt_pad_2",
60
+ pcb_port_id: "pcb_port_2",
61
+ width: 1,
62
+ height: 1,
63
+ },
64
+ {
65
+ type: "pcb_port",
66
+ pcb_port_id: "pcb_port_2",
67
+ source_port_id: "source_port_2",
68
+ x: 2,
69
+ y: 0,
70
+ layers: ["top"],
71
+ },
72
+ {
73
+ type: "pcb_trace",
74
+ pcb_trace_id: "trace_1",
75
+ source_trace_id: "source_trace_1",
76
+ route: [
77
+ { x: -2, y: 0, width: 0.2, route_type: "wire", layer: "top" },
78
+ { x: 2, y: 0, width: 0.2, route_type: "wire", layer: "top" },
79
+ ],
80
+ },
81
+ ]
82
+
83
+ test("renders soldermask only (no copper, no traces)", async () => {
84
+ const pcbSvg = await convertCircuitJsonToPcbSvg(circuitJson)
85
+
86
+ const project = convertCircuitJsonToLbrn(circuitJson, {
87
+ includeCopper: false,
88
+ includeSoldermask: true,
89
+ })
90
+
91
+ const lbrnSvg = await generateLightBurnSvg(project)
92
+
93
+ expect(stackSvgsVertically([pcbSvg, lbrnSvg])).toMatchSvgSnapshot(
94
+ import.meta.filename,
95
+ )
96
+ })