@tscircuit/schematic-trace-solver 0.0.153 → 0.0.154

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
@@ -12139,6 +12139,7 @@ var pathEntersAnyNetLabel = ({
12139
12139
  // lib/solvers/SameNetJunctionAlignmentSolver/alignSameNetJunctions.ts
12140
12140
  var MAX_ALIGNED_LOAD_PIN_OFFSET = 0.2;
12141
12141
  var MAX_SAME_NET_LABEL_BOUNDARY_RAIL_OFFSET = 0.2;
12142
+ var MAX_SHARED_PIN_RAIL_OFFSET = 0.05;
12142
12143
  var getSharedPin = ({
12143
12144
  donorTrace,
12144
12145
  branchTrace
@@ -12178,6 +12179,28 @@ var railIsOnFacingSide = ({
12178
12179
  if (pin._facingDirection === "y+") return railY > pin.y;
12179
12180
  return false;
12180
12181
  };
12182
+ var railIsOnSharedPinFacingSide = ({
12183
+ railY,
12184
+ pin
12185
+ }) => {
12186
+ if (pin._facingDirection === "y+") return railY > pin.y;
12187
+ if (pin._facingDirection === "y-") return railY < pin.y;
12188
+ return false;
12189
+ };
12190
+ var getHorizontalPinApproachPoint = ({
12191
+ branchTrace,
12192
+ sharedPin,
12193
+ otherPin
12194
+ }) => {
12195
+ if (otherPin._facingDirection !== "x-" && otherPin._facingDirection !== "x+") {
12196
+ return null;
12197
+ }
12198
+ const sharedToOtherPath = branchTrace.pins[0].pinId === sharedPin.pinId ? branchTrace.tracePath : [...branchTrace.tracePath].reverse();
12199
+ const approachPoint = sharedToOtherPath.at(-2);
12200
+ if (!approachPoint || !nearlyEqual(approachPoint.y, otherPin.y)) return null;
12201
+ const approachesFromFacingSide = otherPin._facingDirection === "x-" ? approachPoint.x < otherPin.x : approachPoint.x > otherPin.x;
12202
+ return approachesFromFacingSide ? approachPoint : null;
12203
+ };
12181
12204
  var getAttachedLabelIndexes = (trace, netLabelPlacements) => netLabelPlacements.flatMap((label, index) => {
12182
12205
  const labelOwnsTrace = label.mspConnectionPairIds.includes(trace.mspPairId) || label.mspConnectionPairIds.length === 0 && label.globalConnNetId === trace.globalConnNetId;
12183
12206
  return labelOwnsTrace && tracePathContainsPoint(trace.tracePath, label.anchorPoint) ? [index] : [];
@@ -12226,19 +12249,45 @@ var getAlignedBranchPath = ({
12226
12249
  if (branchRail && nearlyEqual(branchRail.start.y, donorRail.start.y)) {
12227
12250
  return null;
12228
12251
  }
12229
- if (!railIsOnFacingSide({ railY: donorRail.start.y, pin: otherPin })) {
12252
+ const railFacesOtherPin = railIsOnFacingSide({
12253
+ railY: donorRail.start.y,
12254
+ pin: otherPin
12255
+ });
12256
+ const railFacesSharedPin = railIsOnSharedPinFacingSide({
12257
+ railY: donorRail.start.y,
12258
+ pin: sharedPin
12259
+ }) && Math.abs(donorRail.start.y - sharedPin.y) <= MAX_SHARED_PIN_RAIL_OFFSET;
12260
+ if (!railFacesOtherPin && !railFacesSharedPin) {
12230
12261
  return null;
12231
12262
  }
12232
12263
  const junction = getJunctionPoint({ segment: donorRail, sharedPin });
12233
12264
  const extendsDonorRail = donorOtherPin.x < junction.x && otherPin.x > junction.x || donorOtherPin.x > junction.x && otherPin.x < junction.x;
12234
12265
  if (!extendsDonorRail) return null;
12235
- const sharedToOther = simplifyPath([
12236
- { x: sharedPin.x, y: sharedPin.y },
12237
- { x: junction.x, y: sharedPin.y },
12238
- { x: junction.x, y: junction.y },
12239
- { x: otherPin.x, y: junction.y },
12240
- { x: otherPin.x, y: otherPin.y }
12241
- ]);
12266
+ let sharedToOther;
12267
+ if (!railFacesOtherPin && railFacesSharedPin) {
12268
+ const approachPoint = getHorizontalPinApproachPoint({
12269
+ branchTrace,
12270
+ sharedPin,
12271
+ otherPin
12272
+ });
12273
+ if (!approachPoint) return null;
12274
+ sharedToOther = simplifyPath([
12275
+ { x: sharedPin.x, y: sharedPin.y },
12276
+ { x: junction.x, y: sharedPin.y },
12277
+ { x: junction.x, y: junction.y },
12278
+ { x: approachPoint.x, y: junction.y },
12279
+ { x: approachPoint.x, y: otherPin.y },
12280
+ { x: otherPin.x, y: otherPin.y }
12281
+ ]);
12282
+ } else {
12283
+ sharedToOther = simplifyPath([
12284
+ { x: sharedPin.x, y: sharedPin.y },
12285
+ { x: junction.x, y: sharedPin.y },
12286
+ { x: junction.x, y: junction.y },
12287
+ { x: otherPin.x, y: junction.y },
12288
+ { x: otherPin.x, y: otherPin.y }
12289
+ ]);
12290
+ }
12242
12291
  if (branchTrace.pins[0].pinId === sharedPin.pinId) return sharedToOther;
12243
12292
  return [...sharedToOther].reverse();
12244
12293
  };
@@ -34,6 +34,9 @@ interface HorizontalSegment {
34
34
  const MAX_ALIGNED_LOAD_PIN_OFFSET = 0.2
35
35
  // Limit label-boundary alignment to small corrections that cannot create spikes.
36
36
  const MAX_SAME_NET_LABEL_BOUNDARY_RAIL_OFFSET = 0.2
37
+ // A shared vertical pin can anchor an existing rail when the rail is only a
38
+ // symbol-stem correction away from the pin itself.
39
+ const MAX_SHARED_PIN_RAIL_OFFSET = 0.05
37
40
 
38
41
  const getSharedPin = ({
39
42
  donorTrace,
@@ -96,6 +99,48 @@ const railIsOnFacingSide = ({
96
99
  return false
97
100
  }
98
101
 
102
+ const railIsOnSharedPinFacingSide = ({
103
+ railY,
104
+ pin,
105
+ }: {
106
+ railY: number
107
+ pin: InputPin
108
+ }) => {
109
+ if (pin._facingDirection === "y+") return railY > pin.y
110
+ if (pin._facingDirection === "y-") return railY < pin.y
111
+ return false
112
+ }
113
+
114
+ const getHorizontalPinApproachPoint = ({
115
+ branchTrace,
116
+ sharedPin,
117
+ otherPin,
118
+ }: {
119
+ branchTrace: SolvedTracePath
120
+ sharedPin: InputPin
121
+ otherPin: InputPin
122
+ }): Point | null => {
123
+ if (
124
+ otherPin._facingDirection !== "x-" &&
125
+ otherPin._facingDirection !== "x+"
126
+ ) {
127
+ return null
128
+ }
129
+
130
+ const sharedToOtherPath =
131
+ branchTrace.pins[0].pinId === sharedPin.pinId
132
+ ? branchTrace.tracePath
133
+ : [...branchTrace.tracePath].reverse()
134
+ const approachPoint = sharedToOtherPath.at(-2)
135
+ if (!approachPoint || !nearlyEqual(approachPoint.y, otherPin.y)) return null
136
+
137
+ const approachesFromFacingSide =
138
+ otherPin._facingDirection === "x-"
139
+ ? approachPoint.x < otherPin.x
140
+ : approachPoint.x > otherPin.x
141
+ return approachesFromFacingSide ? approachPoint : null
142
+ }
143
+
99
144
  const getAttachedLabelIndexes = (
100
145
  trace: SolvedTracePath,
101
146
  netLabelPlacements: NetLabelPlacement[],
@@ -165,7 +210,17 @@ const getAlignedBranchPath = ({
165
210
  if (branchRail && nearlyEqual(branchRail.start.y, donorRail.start.y)) {
166
211
  return null
167
212
  }
168
- if (!railIsOnFacingSide({ railY: donorRail.start.y, pin: otherPin })) {
213
+ const railFacesOtherPin = railIsOnFacingSide({
214
+ railY: donorRail.start.y,
215
+ pin: otherPin,
216
+ })
217
+ const railFacesSharedPin =
218
+ railIsOnSharedPinFacingSide({
219
+ railY: donorRail.start.y,
220
+ pin: sharedPin,
221
+ }) &&
222
+ Math.abs(donorRail.start.y - sharedPin.y) <= MAX_SHARED_PIN_RAIL_OFFSET
223
+ if (!railFacesOtherPin && !railFacesSharedPin) {
169
224
  return null
170
225
  }
171
226
 
@@ -175,13 +230,31 @@ const getAlignedBranchPath = ({
175
230
  (donorOtherPin.x > junction.x && otherPin.x < junction.x)
176
231
  if (!extendsDonorRail) return null
177
232
 
178
- const sharedToOther = simplifyPath([
179
- { x: sharedPin.x, y: sharedPin.y },
180
- { x: junction.x, y: sharedPin.y },
181
- { x: junction.x, y: junction.y },
182
- { x: otherPin.x, y: junction.y },
183
- { x: otherPin.x, y: otherPin.y },
184
- ])
233
+ let sharedToOther: Point[]
234
+ if (!railFacesOtherPin && railFacesSharedPin) {
235
+ const approachPoint = getHorizontalPinApproachPoint({
236
+ branchTrace,
237
+ sharedPin,
238
+ otherPin,
239
+ })
240
+ if (!approachPoint) return null
241
+ sharedToOther = simplifyPath([
242
+ { x: sharedPin.x, y: sharedPin.y },
243
+ { x: junction.x, y: sharedPin.y },
244
+ { x: junction.x, y: junction.y },
245
+ { x: approachPoint.x, y: junction.y },
246
+ { x: approachPoint.x, y: otherPin.y },
247
+ { x: otherPin.x, y: otherPin.y },
248
+ ])
249
+ } else {
250
+ sharedToOther = simplifyPath([
251
+ { x: sharedPin.x, y: sharedPin.y },
252
+ { x: junction.x, y: sharedPin.y },
253
+ { x: junction.x, y: junction.y },
254
+ { x: otherPin.x, y: junction.y },
255
+ { x: otherPin.x, y: otherPin.y },
256
+ ])
257
+ }
185
258
 
186
259
  if (branchTrace.pins[0].pinId === sharedPin.pinId) return sharedToOther
187
260
  return [...sharedToOther].reverse()
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "url": "https://github.com/tscircuit/schematic-trace-solver.git"
6
6
  },
7
7
  "main": "dist/index.js",
8
- "version": "0.0.153",
8
+ "version": "0.0.154",
9
9
  "type": "module",
10
10
  "scripts": {
11
11
  "start": "cosmos",
@@ -0,0 +1,4 @@
1
+ import { PipelineDebugger } from "site/components/PipelineDebugger"
2
+ import inputProblem from "../../tests/bug-reports/bug-report-20260825T103621Z/bug-report-20260825T103621Z.json"
3
+
4
+ export default () => <PipelineDebugger inputProblem={inputProblem as any} />