@tscircuit/schematic-trace-solver 0.0.146 → 0.0.148

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,69 @@
1
+ <svg width="640" height="640" viewBox="0 0 640 640" xmlns="http://www.w3.org/2000/svg"><rect width="100%" height="100%" fill="white"/><g><polyline data-points="5.575,1.4 2.045,2.6" data-type="line" data-label="" points="447.56446991404016,256.8863419293219 258.75835721107927,192.70296084049664" fill="none" stroke="hsl(193, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="5.575,1.2 2.045,2.4" data-type="line" data-label="" points="447.56446991404016,267.5835721107927 258.75835721107927,203.40019102196752" fill="none" stroke="hsl(191, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="5.575,1 2.045,2.2" data-type="line" data-label="" points="447.56446991404016,278.2808022922636 258.75835721107927,214.0974212034384" fill="none" stroke="hsl(72, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="5.575,0.8 2.045,2" data-type="line" data-label="" points="447.56446991404016,288.97803247373446 258.75835721107927,224.79465138490926" fill="none" stroke="hsl(74, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="5.575,0.6 2.045,0.7" data-type="line" data-label="" points="447.56446991404016,299.67526265520536 258.75835721107927,294.3266475644699" fill="none" stroke="hsl(184, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="5.575,1.4 5.375,1.4 5.375,2.6 2.045,2.6" data-type="line" data-label="" points="447.56446991404016,256.8863419293219 436.86723973256926,256.8863419293219 436.86723973256926,192.70296084049664 258.75835721107927,192.70296084049664" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="5.575,1.2 3.81,1.2 3.81,2.4 2.045,2.4" data-type="line" data-label="" points="447.56446991404016,267.5835721107927 353.1614135625597,267.5835721107927 353.1614135625597,203.40019102196752 258.75835721107927,203.40019102196752" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="5.575,1 3.71,1 3.71,2.2 2.045,2.2" data-type="line" data-label="" points="447.56446991404016,278.2808022922636 347.81279847182424,278.2808022922636 347.81279847182424,214.0974212034384 258.75835721107927,214.0974212034384" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="5.575,0.8 2.245,0.8 2.245,2 2.045,2" data-type="line" data-label="" points="447.56446991404016,288.97803247373446 269.4555873925501,288.97803247373446 269.4555873925501,224.79465138490926 258.75835721107927,224.79465138490926" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="5.575,0.6 3.81,0.6 3.81,0.7 2.045,0.7" data-type="line" data-label="" points="447.56446991404016,299.67526265520536 353.1614135625597,299.67526265520536 353.1614135625597,294.3266475644699 258.75835721107927,294.3266475644699" fill="none" stroke="purple" stroke-width="1px"/></g><g><rect data-type="rect" data-label="U1" data-x="0" data-y="0" x="40" y="161.9484240687679" width="218.75835721107927" height="339.6370582617001" fill="hsl(164, 100%, 50%, 0.8)" stroke="black" stroke-width="0.018696428571428572"/></g><g><rect data-type="rect" data-label="J4" data-x="7" data-y="-0.4" x="447.5644699140401" y="246.189111747851" width="152.43553008595984" height="213.94460362941737" fill="hsl(186, 100%, 50%, 0.8)" stroke="black" stroke-width="0.018696428571428572"/></g><g><rect data-type="rect" data-label="TB67S579FTG" data-x="2.405" data-y="3.525" x="242.71251193887292" y="138.41451766953202" width="70.60171919770775" height="9.627507163323742" fill="rgba(160, 0, 220, 0.14)" stroke="black" stroke-width="0.018696428571428572"/></g><g><rect data-type="rect" data-label="U1" data-x="1.865" data-y="3.29" x="239.50334288443167" y="149.11174785100286" width="19.25501432664757" height="13.371537726838596" fill="rgba(160, 0, 220, 0.14)" stroke="black" stroke-width="0.018696428571428572"/></g><g><rect data-type="rect" data-label="J4" data-x="6.095" data-y="1.715" x="465.74976122254054" y="233.35243553008593" width="19.255014326647597" height="13.371537726838568" fill="rgba(160, 0, 220, 0.14)" stroke="black" stroke-width="0.018696428571428572"/></g><g><rect data-type="rect" data-label="INLINE netId: OUT_A_P
2
+ axis: x
3
+ side: y+" data-x="3.71" data-y="2.71" x="330.69723018147084" y="183.6103151862464" width="34.23113658070679" height="6.418338108882523" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.018696428571428572"/></g><g><rect data-type="rect" data-label="INLINE netId: OUT_A_N
4
+ axis: x
5
+ side: y+" data-x="4.6925" data-y="1.31" x="383.24737344794653" y="258.4909264565425" width="34.231136580706846" height="6.418338108882551" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.018696428571428572"/></g><g><rect data-type="rect" data-label="INLINE netId: OUT_B_N
6
+ axis: x
7
+ side: y+" data-x="4.6425" data-y="1.11" x="380.5730659025787" y="269.18815663801337" width="34.231136580706846" height="6.4183381088824945" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.018696428571428572"/></g><g><rect data-type="rect" data-label="INLINE netId: OUT_B_P
8
+ axis: x
9
+ side: y+" data-x="3.91" data-y="0.91" x="341.39446036294174" y="279.8853868194842" width="34.23113658070679" height="6.418338108882551" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.018696428571428572"/></g><g><rect data-type="rect" data-label="INLINE netId: SERIAL_IN
10
+ axis: x
11
+ side: y+" data-x="4.6925" data-y="0.71" x="378.9684813753582" y="290.5826170009551" width="42.788920725883486" height="6.4183381088824945" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.018696428571428572"/></g><text data-type="text" data-label="OUT_A_P" data-x="3.71" data-y="2.71" x="347.81279847182424" y="186.81948424068767" fill="green" font-size="6.418338108882521" font-family="sans-serif" text-anchor="middle" dominant-baseline="central">OUT_A_P</text><text data-type="text" data-label="OUT_A_N" data-x="4.6925" data-y="1.31" x="400.3629417382999" y="261.7000955109838" fill="green" font-size="6.418338108882521" font-family="sans-serif" text-anchor="middle" dominant-baseline="central">OUT_A_N</text><text data-type="text" data-label="OUT_B_N" data-x="4.6425" data-y="1.11" x="397.68863419293217" y="272.3973256924546" fill="green" font-size="6.418338108882521" font-family="sans-serif" text-anchor="middle" dominant-baseline="central">OUT_B_N</text><text data-type="text" data-label="OUT_B_P" data-x="3.91" data-y="0.91" x="358.51002865329514" y="283.0945558739255" fill="green" font-size="6.418338108882521" font-family="sans-serif" text-anchor="middle" dominant-baseline="central">OUT_B_P</text><text data-type="text" data-label="SERIAL_IN" data-x="4.6925" data-y="0.71" x="400.3629417382999" y="293.79178605539636" fill="green" font-size="6.418338108882521" font-family="sans-serif" text-anchor="middle" dominant-baseline="central">SERIAL_IN</text><g><circle data-type="point" data-label="U1.4
12
+ x+" data-x="2.045" data-y="2.6" cx="258.75835721107927" cy="192.70296084049664" r="3" fill="hsl(322, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.6
13
+ x+" data-x="2.045" data-y="2.4" cx="258.75835721107927" cy="203.40019102196752" r="3" fill="hsl(324, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.7
14
+ x+" data-x="2.045" data-y="2.2" cx="258.75835721107927" cy="214.0974212034384" r="3" fill="hsl(325, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.9
15
+ x+" data-x="2.045" data-y="2" cx="258.75835721107927" cy="224.79465138490926" r="3" fill="hsl(327, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.48
16
+ x+" data-x="2.045" data-y="0.7" cx="258.75835721107927" cy="294.3266475644699" r="3" fill="hsl(318, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="J4.1
17
+ x-" data-x="5.575" data-y="1.4" cx="447.56446991404016" cy="256.8863419293219" r="3" fill="hsl(221, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="J4.2
18
+ x-" data-x="5.575" data-y="1.2" cx="447.56446991404016" cy="267.5835721107927" r="3" fill="hsl(222, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="J4.3
19
+ x-" data-x="5.575" data-y="1" cx="447.56446991404016" cy="278.2808022922636" r="3" fill="hsl(223, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="J4.4
20
+ x-" data-x="5.575" data-y="0.8" cx="447.56446991404016" cy="288.97803247373446" r="3" fill="hsl(224, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="J4.5
21
+ x-" data-x="5.575" data-y="0.6" cx="447.56446991404016" cy="299.67526265520536" r="3" fill="hsl(225, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="inline anchor
22
+ OUT_A_P" data-x="3.71" data-y="2.6" cx="347.81279847182424" cy="192.70296084049664" r="3" fill="green"/></g><g><circle data-type="point" data-label="inline anchor
23
+ OUT_A_N" data-x="4.6925" data-y="1.2" cx="400.3629417382999" cy="267.5835721107927" r="3" fill="green"/></g><g><circle data-type="point" data-label="inline anchor
24
+ OUT_B_N" data-x="4.6425" data-y="1" cx="397.68863419293217" cy="278.2808022922636" r="3" fill="green"/></g><g><circle data-type="point" data-label="inline anchor
25
+ OUT_B_P" data-x="3.91" data-y="0.8" cx="358.51002865329514" cy="288.97803247373446" r="3" fill="green"/></g><g><circle data-type="point" data-label="inline anchor
26
+ SERIAL_IN" data-x="4.6925" data-y="0.6" cx="400.3629417382999" cy="299.67526265520536" r="3" fill="green"/></g><g id="crosshair" style="display: none"><line id="crosshair-h" y1="0" y2="640" stroke="#666" stroke-width="0.5"/><line id="crosshair-v" x1="0" x2="640" stroke="#666" stroke-width="0.5"/><text id="coordinates" font-family="monospace" font-size="12" fill="#666"></text></g><script><![CDATA[
27
+ document.currentScript.parentElement.addEventListener('mousemove', (e) => {
28
+ const svg = e.currentTarget;
29
+ const rect = svg.getBoundingClientRect();
30
+ const x = e.clientX - rect.left;
31
+ const y = e.clientY - rect.top;
32
+ const crosshair = svg.getElementById('crosshair');
33
+ const h = svg.getElementById('crosshair-h');
34
+ const v = svg.getElementById('crosshair-v');
35
+ const coords = svg.getElementById('coordinates');
36
+
37
+ crosshair.style.display = 'block';
38
+ h.setAttribute('x1', '0');
39
+ h.setAttribute('x2', '640');
40
+ h.setAttribute('y1', y);
41
+ h.setAttribute('y2', y);
42
+ v.setAttribute('x1', x);
43
+ v.setAttribute('x2', x);
44
+ v.setAttribute('y1', '0');
45
+ v.setAttribute('y2', '640');
46
+
47
+ // Calculate real coordinates using inverse transformation
48
+ const matrix = {"a":53.48615090735434,"c":0,"e":149.37917860553964,"b":0,"d":-53.48615090735434,"f":331.76695319961794};
49
+ // Manually invert and apply the affine transform
50
+ // Since we only use translate and scale, we can directly compute:
51
+ // x' = (x - tx) / sx
52
+ // y' = (y - ty) / sy
53
+ const sx = matrix.a;
54
+ const sy = matrix.d;
55
+ const tx = matrix.e;
56
+ const ty = matrix.f;
57
+ const realPoint = {
58
+ x: (x - tx) / sx,
59
+ y: (y - ty) / sy // Flip y back since we used negative scale
60
+ }
61
+
62
+ coords.textContent = `(${realPoint.x.toFixed(2)}, ${realPoint.y.toFixed(2)})`;
63
+ coords.setAttribute('x', (x + 5).toString());
64
+ coords.setAttribute('y', (y - 5).toString());
65
+ });
66
+ document.currentScript.parentElement.addEventListener('mouseleave', () => {
67
+ document.currentScript.parentElement.getElementById('crosshair').style.display = 'none';
68
+ });
69
+ ]]></script></svg>
@@ -0,0 +1,152 @@
1
+ import { expect, test } from "bun:test"
2
+ import { SchematicTracePipelineSolver } from "lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver"
3
+ import type {
4
+ InputDirectConnection,
5
+ InputProblem,
6
+ } from "lib/types/InputProblem"
7
+ import "tests/fixtures/matcher"
8
+
9
+ const inlineConnection = (
10
+ netId: string,
11
+ pinIds: [string, string],
12
+ fallbackNetLabelWidth: number,
13
+ inlineNetLabelWidth: number,
14
+ ): InputDirectConnection => ({
15
+ netId,
16
+ pinIds,
17
+ allowInlineNetLabel: true,
18
+ fallbackNetLabelWidth,
19
+ inlineNetLabelWidth,
20
+ inlineNetLabelHeight: 0.12,
21
+ })
22
+
23
+ const routedInputProblem: InputProblem = {
24
+ chips: [
25
+ {
26
+ chipId: "U1",
27
+ center: { x: 0, y: 0 },
28
+ width: 3.29,
29
+ height: 6.35,
30
+ sectionId: "driver",
31
+ pins: [
32
+ { pinId: "U1.4", x: 2.045, y: 2.6, _facingDirection: "x+" },
33
+ { pinId: "U1.6", x: 2.045, y: 2.4, _facingDirection: "x+" },
34
+ { pinId: "U1.7", x: 2.045, y: 2.2, _facingDirection: "x+" },
35
+ { pinId: "U1.9", x: 2.045, y: 2, _facingDirection: "x+" },
36
+ { pinId: "U1.48", x: 2.045, y: 0.7, _facingDirection: "x+" },
37
+ ],
38
+ },
39
+ {
40
+ chipId: "J4",
41
+ center: { x: 7, y: -0.4 },
42
+ width: 2.05,
43
+ height: 4,
44
+ sectionId: "driver",
45
+ pins: [
46
+ { pinId: "J4.1", x: 5.575, y: 1.4, _facingDirection: "x-" },
47
+ { pinId: "J4.2", x: 5.575, y: 1.2, _facingDirection: "x-" },
48
+ { pinId: "J4.3", x: 5.575, y: 1, _facingDirection: "x-" },
49
+ { pinId: "J4.4", x: 5.575, y: 0.8, _facingDirection: "x-" },
50
+ { pinId: "J4.5", x: 5.575, y: 0.6, _facingDirection: "x-" },
51
+ ],
52
+ },
53
+ ],
54
+ directConnections: [
55
+ inlineConnection("OUT_A_P", ["J4.1", "U1.4"], 0.96, 0.64),
56
+ inlineConnection("OUT_A_N", ["J4.2", "U1.6"], 0.96, 0.64),
57
+ inlineConnection("OUT_B_N", ["J4.3", "U1.7"], 0.96, 0.64),
58
+ inlineConnection("OUT_B_P", ["J4.4", "U1.9"], 0.96, 0.64),
59
+ inlineConnection("SERIAL_IN", ["J4.5", "U1.48"], 1.2, 0.8),
60
+ ],
61
+ netConnections: [],
62
+ textBoxes: [
63
+ {
64
+ chipId: "U1",
65
+ center: { x: 2.405, y: 3.525 },
66
+ width: 1.32,
67
+ height: 0.18,
68
+ text: "TB67S579FTG",
69
+ },
70
+ {
71
+ chipId: "U1",
72
+ center: { x: 1.865, y: 3.29 },
73
+ width: 0.36,
74
+ height: 0.25,
75
+ text: "U1",
76
+ },
77
+ {
78
+ chipId: "J4",
79
+ center: { x: 6.095, y: 1.715 },
80
+ width: 0.36,
81
+ height: 0.25,
82
+ text: "J4",
83
+ },
84
+ ],
85
+ availableNetLabelOrientations: {},
86
+ maxMspPairDistance: 20,
87
+ }
88
+
89
+ test("fallback label width does not split routable inline connections", () => {
90
+ const solver = new SchematicTracePipelineSolver(routedInputProblem)
91
+
92
+ solver.solve()
93
+
94
+ expect(solver.schematicTraceLinesSolver!.solvedTracePaths).toHaveLength(5)
95
+ expect(solver.schematicTraceLinesSolver!.failedConnectionPairs).toHaveLength(
96
+ 0,
97
+ )
98
+
99
+ const output = solver.inlineNetLabelSolver!.getOutput()
100
+ expect(output.traces).toHaveLength(5)
101
+ expect(output.inlineNetLabelPlacements).toHaveLength(5)
102
+ expect(
103
+ output.inlineNetLabelPlacements.every(
104
+ (placement) => placement.stubTracePath === undefined,
105
+ ),
106
+ ).toBe(true)
107
+
108
+ expect(solver).toMatchSolverSnapshot(import.meta.path)
109
+ })
110
+
111
+ test("fallback label width sizes anchored labels when routing is skipped", () => {
112
+ const inputProblem: InputProblem = {
113
+ chips: [
114
+ {
115
+ chipId: "U1",
116
+ center: { x: -3, y: 0 },
117
+ width: 1,
118
+ height: 1,
119
+ pins: [{ pinId: "U1.1", x: -2.5, y: 0, _facingDirection: "x+" }],
120
+ },
121
+ {
122
+ chipId: "U2",
123
+ center: { x: 3, y: 0 },
124
+ width: 1,
125
+ height: 1,
126
+ pins: [{ pinId: "U2.1", x: 2.5, y: 0, _facingDirection: "x-" }],
127
+ },
128
+ ],
129
+ directConnections: [
130
+ {
131
+ netId: "SIGNAL",
132
+ pinIds: ["U1.1", "U2.1"],
133
+ allowInlineNetLabel: true,
134
+ fallbackNetLabelWidth: 0.96,
135
+ inlineNetLabelWidth: 0.64,
136
+ inlineNetLabelHeight: 0.12,
137
+ },
138
+ ],
139
+ netConnections: [],
140
+ availableNetLabelOrientations: {},
141
+ maxMspPairDistance: 1,
142
+ }
143
+
144
+ const solver = new SchematicTracePipelineSolver(inputProblem)
145
+ solver.solve()
146
+
147
+ const [fallbackPlacement] = solver.netLabelPlacementSolver!.netLabelPlacements
148
+ expect(fallbackPlacement).toBeDefined()
149
+ expect(Math.max(fallbackPlacement!.width, fallbackPlacement!.height)).toBe(
150
+ 0.96,
151
+ )
152
+ })