@tscircuit/core 0.0.1297 → 0.0.1298

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 (2) hide show
  1. package/dist/index.js +158 -69
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -13769,7 +13769,7 @@ import {
13769
13769
  groupProps
13770
13770
  } from "@tscircuit/props";
13771
13771
  import {
13772
- distance as distance10
13772
+ distance as distance11
13773
13773
  } from "circuit-json";
13774
13774
  import Debug14 from "debug";
13775
13775
 
@@ -14476,6 +14476,56 @@ var getUnbrokenCopperPourObstacles = ({
14476
14476
  return obstacles;
14477
14477
  };
14478
14478
 
14479
+ // lib/utils/autorouting/trimRouteEndsAtBreakoutPoints.ts
14480
+ import {
14481
+ distance as distance9,
14482
+ getUnitVectorFromPointAToB as getUnitVectorFromPointAToB2
14483
+ } from "@tscircuit/math-utils";
14484
+ var DEFAULT_BREAKOUT_HANDOFF_TRIM_MM = 0.6;
14485
+ var getPointXY = (routePoint) => {
14486
+ const { x, y } = routePoint;
14487
+ return typeof x === "number" && typeof y === "number" ? { x, y } : null;
14488
+ };
14489
+ var trimRouteEndsAtBreakoutPoints = ({
14490
+ route,
14491
+ breakoutPointPositions,
14492
+ trimMm = DEFAULT_BREAKOUT_HANDOFF_TRIM_MM
14493
+ }) => {
14494
+ if (breakoutPointPositions.length === 0 || route.length < 2) return route;
14495
+ const isAtBreakoutPoint = (point6) => breakoutPointPositions.some((bp) => distance9(bp, point6) < 0.05);
14496
+ const trimFront = (points) => {
14497
+ const out = [...points];
14498
+ let remaining = trimMm;
14499
+ while (out.length >= 2 && remaining > 1e-9) {
14500
+ const a = getPointXY(out[0]);
14501
+ const b = getPointXY(out[1]);
14502
+ if (!a || !b) break;
14503
+ const segmentLength = distance9(a, b);
14504
+ if (segmentLength <= remaining + 1e-9) {
14505
+ out.shift();
14506
+ remaining -= segmentLength;
14507
+ } else {
14508
+ const unit = getUnitVectorFromPointAToB2(a, b);
14509
+ out[0] = {
14510
+ ...out[0],
14511
+ x: a.x + unit.x * remaining,
14512
+ y: a.y + unit.y * remaining
14513
+ };
14514
+ remaining = 0;
14515
+ }
14516
+ }
14517
+ return out;
14518
+ };
14519
+ let trimmed = route;
14520
+ const first = getPointXY(trimmed[0]);
14521
+ if (first && isAtBreakoutPoint(first)) trimmed = trimFront(trimmed);
14522
+ const last = getPointXY(trimmed[trimmed.length - 1]);
14523
+ if (last && trimmed.length >= 2 && isAtBreakoutPoint(last)) {
14524
+ trimmed = trimFront([...trimmed].reverse()).reverse();
14525
+ }
14526
+ return trimmed;
14527
+ };
14528
+
14479
14529
  // lib/utils/autorouting/getSimpleRouteJsonFromCircuitJson.ts
14480
14530
  var getSimpleRouteJsonFromCircuitJson = ({
14481
14531
  db,
@@ -14514,6 +14564,7 @@ var getSimpleRouteJsonFromCircuitJson = ({
14514
14564
  (e) => !subcircuit_id || "subcircuit_id" in e && relevantSubcircuitIds.has(e.subcircuit_id)
14515
14565
  );
14516
14566
  let board = null;
14567
+ let subcircuitIsBoard = false;
14517
14568
  if (subcircuit_id) {
14518
14569
  const source_group_id = subcircuit_id.replace(/^subcircuit_/, "");
14519
14570
  const source_board = db.source_board.getWhere({ source_group_id });
@@ -14521,6 +14572,7 @@ var getSimpleRouteJsonFromCircuitJson = ({
14521
14572
  board = db.pcb_board.getWhere({
14522
14573
  source_board_id: source_board.source_board_id
14523
14574
  });
14575
+ if (board) subcircuitIsBoard = true;
14524
14576
  }
14525
14577
  }
14526
14578
  if (!board) {
@@ -14554,13 +14606,24 @@ var getSimpleRouteJsonFromCircuitJson = ({
14554
14606
  group: pcbGroup
14555
14607
  })
14556
14608
  );
14609
+ const breakoutPointPositions = breakoutPoints.map((bp) => ({
14610
+ x: bp.x,
14611
+ y: bp.y
14612
+ }));
14613
+ const breakoutHandoffTrimMm = (minViaPadDiameter ?? board?.min_via_pad_diameter ?? 0.3) + 2 * (minTraceWidth ?? board?.min_trace_width ?? 0.15) + (minTraceToPadEdgeClearance ?? board?.min_trace_to_pad_edge_clearance ?? 0.1);
14557
14614
  const descendantTraces = subcircuit_id ? db.pcb_trace.list().filter(
14558
14615
  (t) => t.subcircuit_id && t.subcircuit_id !== subcircuit_id && relevantSubcircuitIds.has(t.subcircuit_id)
14559
14616
  ).map((t) => ({
14560
14617
  type: "pcb_trace",
14561
14618
  pcb_trace_id: t.pcb_trace_id,
14562
- route: t.route
14563
- })) : [];
14619
+ source_trace_id: t.source_trace_id,
14620
+ connection_name: t.source_trace_id ?? t.connection_name ?? t.pcb_trace_id,
14621
+ route: trimRouteEndsAtBreakoutPoints({
14622
+ route: t.route,
14623
+ breakoutPointPositions,
14624
+ trimMm: breakoutHandoffTrimMm
14625
+ })
14626
+ })).filter((t) => t.route.length >= 2) : [];
14564
14627
  for (const obstacle of obstacles) {
14565
14628
  const additionalIds = obstacle.connectedTo.flatMap(
14566
14629
  (id) => connMap.getIdsConnectedToNet(id)
@@ -14624,7 +14687,15 @@ var getSimpleRouteJsonFromCircuitJson = ({
14624
14687
  }
14625
14688
  ]).concat(board?.outline ?? []);
14626
14689
  let bounds;
14627
- if (board && !board.outline) {
14690
+ const useGroupBoundsAsSrjBounds = !!(pcbGroup?.width && pcbGroup.height && subcircuit_id && !subcircuitIsBoard);
14691
+ if (useGroupBoundsAsSrjBounds) {
14692
+ bounds = {
14693
+ minX: pcbGroup.center.x - pcbGroup.width / 2,
14694
+ maxX: pcbGroup.center.x + pcbGroup.width / 2,
14695
+ minY: pcbGroup.center.y - pcbGroup.height / 2,
14696
+ maxY: pcbGroup.center.y + pcbGroup.height / 2
14697
+ };
14698
+ } else if (board && !board.outline) {
14628
14699
  bounds = {
14629
14700
  minX: board.center.x - board.width / 2,
14630
14701
  maxX: board.center.x + board.width / 2,
@@ -14639,7 +14710,7 @@ var getSimpleRouteJsonFromCircuitJson = ({
14639
14710
  maxY: Math.max(...allPoints.map((p) => p.y)) + 1
14640
14711
  };
14641
14712
  }
14642
- if (pcbGroup?.width && pcbGroup.height) {
14713
+ if (pcbGroup?.width && pcbGroup.height && !useGroupBoundsAsSrjBounds) {
14643
14714
  const groupBounds = {
14644
14715
  minX: pcbGroup.center.x - pcbGroup.width / 2,
14645
14716
  maxX: pcbGroup.center.x + pcbGroup.width / 2,
@@ -19688,7 +19759,7 @@ function addPortIdsToTracesAtJumperPads(segments, db) {
19688
19759
  }
19689
19760
 
19690
19761
  // lib/components/primitive-components/Group/get-source-trace-id-for-routed-trace.ts
19691
- import { distance as distance9, pointToSegmentDistance } from "@tscircuit/math-utils";
19762
+ import { distance as distance10, pointToSegmentDistance } from "@tscircuit/math-utils";
19692
19763
  import { ConnectivityMap as ConnectivityMap3 } from "circuit-json-to-connectivity-map";
19693
19764
  var POINT_EPSILON = 1e-6;
19694
19765
  function isPointOnWireSegment({
@@ -19710,7 +19781,7 @@ function isPointInSmtPad({
19710
19781
  return Math.abs(point6.x - pad.x) <= pad.width / 2 + traceWidth / 2 && Math.abs(point6.y - pad.y) <= pad.height / 2 + traceWidth / 2;
19711
19782
  }
19712
19783
  if (pad.shape === "circle") {
19713
- return distance9(point6, pad) <= pad.radius + traceWidth / 2;
19784
+ return distance10(point6, pad) <= pad.radius + traceWidth / 2;
19714
19785
  }
19715
19786
  return false;
19716
19787
  }
@@ -19719,7 +19790,7 @@ function isPointInPlatedHole({
19719
19790
  hole,
19720
19791
  traceWidth = 0
19721
19792
  }) {
19722
- return distance9(point6, hole) <= (hole.outer_diameter ?? hole.hole_diameter ?? 0) / 2 + traceWidth / 2;
19793
+ return distance10(point6, hole) <= (hole.outer_diameter ?? hole.hole_diameter ?? 0) / 2 + traceWidth / 2;
19723
19794
  }
19724
19795
  function getEndpointSourcePortIdsFromGeometry(db, trace) {
19725
19796
  const sourcePortIds = /* @__PURE__ */ new Set();
@@ -19730,7 +19801,7 @@ function getEndpointSourcePortIdsFromGeometry(db, trace) {
19730
19801
  for (const endpoint of endpoints) {
19731
19802
  for (const pcbPort of db.pcb_port.list()) {
19732
19803
  if (!pcbPort.source_port_id) continue;
19733
- if (distance9(endpoint, pcbPort) <= 0.01) {
19804
+ if (distance10(endpoint, pcbPort) <= 0.01) {
19734
19805
  sourcePortIds.add(pcbPort.source_port_id);
19735
19806
  }
19736
19807
  }
@@ -20356,8 +20427,8 @@ var Group5 = class extends NormalComponent3 {
20356
20427
  const groupProps2 = props;
20357
20428
  const hasOutline = groupProps2.outline && groupProps2.outline.length > 0;
20358
20429
  const numericOutline = hasOutline ? groupProps2.outline.map((point6) => ({
20359
- x: distance10.parse(point6.x),
20360
- y: distance10.parse(point6.y)
20430
+ x: distance11.parse(point6.x),
20431
+ y: distance11.parse(point6.y)
20361
20432
  })) : void 0;
20362
20433
  const ctx = this.props;
20363
20434
  const anchorPosition = this._getGlobalPcbPositionBeforeLayout();
@@ -20395,8 +20466,8 @@ var Group5 = class extends NormalComponent3 {
20395
20466
  const hasExplicitPositioning = this._parsedProps.pcbX !== void 0 || this._parsedProps.pcbY !== void 0;
20396
20467
  if (hasOutline) {
20397
20468
  const numericOutline = props.outline.map((point6) => ({
20398
- x: distance10.parse(point6.x),
20399
- y: distance10.parse(point6.y)
20469
+ x: distance11.parse(point6.x),
20470
+ y: distance11.parse(point6.y)
20400
20471
  }));
20401
20472
  const outlineBounds = getBoundsFromPoints4(numericOutline);
20402
20473
  if (!outlineBounds) return;
@@ -22430,7 +22501,7 @@ import { identity as identity5 } from "transformation-matrix";
22430
22501
  var package_default = {
22431
22502
  name: "@tscircuit/core",
22432
22503
  type: "module",
22433
- version: "0.0.1296",
22504
+ version: "0.0.1297",
22434
22505
  types: "dist/index.d.ts",
22435
22506
  main: "dist/index.js",
22436
22507
  module: "dist/index.js",
@@ -23612,11 +23683,11 @@ var MountedBoard = class extends Subcircuit {
23612
23683
 
23613
23684
  // lib/components/normal-components/Panel.ts
23614
23685
  import { panelProps } from "@tscircuit/props";
23615
- import { distance as distance14 } from "circuit-json";
23686
+ import { distance as distance15 } from "circuit-json";
23616
23687
 
23617
23688
  // lib/components/normal-components/Subpanel.ts
23618
23689
  import { subpanelProps } from "@tscircuit/props";
23619
- import { distance as distance13 } from "circuit-json";
23690
+ import { distance as distance14 } from "circuit-json";
23620
23691
  import { compose as compose7, identity as identity6, translate as translate7 } from "transformation-matrix";
23621
23692
 
23622
23693
  // lib/utils/panels/generate-panel-tabs-and-mouse-bites.ts
@@ -23829,15 +23900,15 @@ function generatePanelTabsAndMouseBites(boards, options) {
23829
23900
  }
23830
23901
 
23831
23902
  // lib/utils/panels/pack-into-grid.ts
23832
- import { distance as distance12 } from "circuit-json";
23903
+ import { distance as distance13 } from "circuit-json";
23833
23904
 
23834
23905
  // lib/utils/panels/get-board-dimensions-from-props.ts
23835
23906
  import { getBoundsFromPoints as getBoundsFromPoints6 } from "@tscircuit/math-utils";
23836
- import { distance as distance11 } from "circuit-json";
23907
+ import { distance as distance12 } from "circuit-json";
23837
23908
  var getBoardDimensionsFromProps = (board) => {
23838
23909
  const props = board._parsedProps;
23839
- let width = props.width != null ? distance11.parse(props.width) : void 0;
23840
- let height = props.height != null ? distance11.parse(props.height) : void 0;
23910
+ let width = props.width != null ? distance12.parse(props.width) : void 0;
23911
+ let height = props.height != null ? distance12.parse(props.height) : void 0;
23841
23912
  if ((width === void 0 || height === void 0) && props.outline?.length) {
23842
23913
  const outlineBounds = getBoundsFromPoints6(props.outline);
23843
23914
  if (outlineBounds) {
@@ -23881,8 +23952,8 @@ function packIntoGrid({
23881
23952
  }
23882
23953
  let cols;
23883
23954
  let rows;
23884
- const minCellWidth = cellWidth ? distance12.parse(cellWidth) : 0;
23885
- const minCellHeight = cellHeight ? distance12.parse(cellHeight) : 0;
23955
+ const minCellWidth = cellWidth ? distance13.parse(cellWidth) : 0;
23956
+ const minCellHeight = cellHeight ? distance13.parse(cellHeight) : 0;
23886
23957
  if (col !== void 0) {
23887
23958
  cols = col;
23888
23959
  rows = row ?? Math.ceil(itemsWithDims.length / cols);
@@ -23981,8 +24052,8 @@ function getItemDimensions(item, db) {
23981
24052
  const props = subpanel._parsedProps;
23982
24053
  if (props.width !== void 0 && props.height !== void 0) {
23983
24054
  return {
23984
- width: distance12.parse(props.width),
23985
- height: distance12.parse(props.height)
24055
+ width: distance13.parse(props.width),
24056
+ height: distance13.parse(props.height)
23986
24057
  };
23987
24058
  }
23988
24059
  const directBoards = subpanel._getDirectBoardChildren();
@@ -24009,7 +24080,7 @@ function getItemDimensions(item, db) {
24009
24080
  return getBoardDimensionsFromProps(directBoards[0]);
24010
24081
  }
24011
24082
  if (subpanel._cachedGridWidth > 0 && subpanel._cachedGridHeight > 0) {
24012
- const edgePadding = distance12.parse(props.edgePadding ?? 5);
24083
+ const edgePadding = distance13.parse(props.edgePadding ?? 5);
24013
24084
  return {
24014
24085
  width: subpanel._cachedGridWidth + edgePadding * 2,
24015
24086
  height: subpanel._cachedGridHeight + edgePadding * 2
@@ -24167,17 +24238,17 @@ var Subpanel = class _Subpanel extends Group5 {
24167
24238
  edgePaddingTop: edgePaddingTopProp,
24168
24239
  edgePaddingBottom: edgePaddingBottomProp
24169
24240
  } = this._parsedProps;
24170
- const edgePadding = distance13.parse(edgePaddingProp ?? 5);
24171
- const edgePaddingLeft = distance13.parse(edgePaddingLeftProp ?? edgePadding);
24172
- const edgePaddingRight = distance13.parse(
24241
+ const edgePadding = distance14.parse(edgePaddingProp ?? 5);
24242
+ const edgePaddingLeft = distance14.parse(edgePaddingLeftProp ?? edgePadding);
24243
+ const edgePaddingRight = distance14.parse(
24173
24244
  edgePaddingRightProp ?? edgePadding
24174
24245
  );
24175
- const edgePaddingTop = distance13.parse(edgePaddingTopProp ?? edgePadding);
24176
- const edgePaddingBottom = distance13.parse(
24246
+ const edgePaddingTop = distance14.parse(edgePaddingTopProp ?? edgePadding);
24247
+ const edgePaddingBottom = distance14.parse(
24177
24248
  edgePaddingBottomProp ?? edgePadding
24178
24249
  );
24179
- const panelWidth = distance13.parse(this._parsedProps.width);
24180
- const panelHeight = distance13.parse(this._parsedProps.height);
24250
+ const panelWidth = distance14.parse(this._parsedProps.width);
24251
+ const panelHeight = distance14.parse(this._parsedProps.height);
24181
24252
  availablePanelWidth = panelWidth - edgePaddingLeft - edgePaddingRight;
24182
24253
  availablePanelHeight = panelHeight - edgePaddingTop - edgePaddingBottom;
24183
24254
  }
@@ -24252,8 +24323,8 @@ var Subpanel = class _Subpanel extends Group5 {
24252
24323
  if (!this.pcb_group_id) return;
24253
24324
  if (hasExplicitWidth && hasExplicitHeight) {
24254
24325
  db.pcb_group.update(this.pcb_group_id, {
24255
- width: distance13.parse(this._parsedProps.width),
24256
- height: distance13.parse(this._parsedProps.height)
24326
+ width: distance14.parse(this._parsedProps.width),
24327
+ height: distance14.parse(this._parsedProps.height)
24257
24328
  });
24258
24329
  } else if (gridWidth > 0 || gridHeight > 0) {
24259
24330
  const {
@@ -24263,18 +24334,18 @@ var Subpanel = class _Subpanel extends Group5 {
24263
24334
  edgePaddingTop: edgePaddingTopProp,
24264
24335
  edgePaddingBottom: edgePaddingBottomProp
24265
24336
  } = this._parsedProps;
24266
- const edgePadding = distance13.parse(edgePaddingProp ?? 5);
24267
- const edgePaddingLeft = distance13.parse(edgePaddingLeftProp ?? edgePadding);
24268
- const edgePaddingRight = distance13.parse(
24337
+ const edgePadding = distance14.parse(edgePaddingProp ?? 5);
24338
+ const edgePaddingLeft = distance14.parse(edgePaddingLeftProp ?? edgePadding);
24339
+ const edgePaddingRight = distance14.parse(
24269
24340
  edgePaddingRightProp ?? edgePadding
24270
24341
  );
24271
- const edgePaddingTop = distance13.parse(edgePaddingTopProp ?? edgePadding);
24272
- const edgePaddingBottom = distance13.parse(
24342
+ const edgePaddingTop = distance14.parse(edgePaddingTopProp ?? edgePadding);
24343
+ const edgePaddingBottom = distance14.parse(
24273
24344
  edgePaddingBottomProp ?? edgePadding
24274
24345
  );
24275
24346
  db.pcb_group.update(this.pcb_group_id, {
24276
- width: hasExplicitWidth ? distance13.parse(this._parsedProps.width) : gridWidth + edgePaddingLeft + edgePaddingRight,
24277
- height: hasExplicitHeight ? distance13.parse(this._parsedProps.height) : gridHeight + edgePaddingTop + edgePaddingBottom
24347
+ width: hasExplicitWidth ? distance14.parse(this._parsedProps.width) : gridWidth + edgePaddingLeft + edgePaddingRight,
24348
+ height: hasExplicitHeight ? distance14.parse(this._parsedProps.height) : gridHeight + edgePaddingTop + edgePaddingBottom
24278
24349
  });
24279
24350
  }
24280
24351
  }
@@ -24348,8 +24419,8 @@ var Panel = class extends Subpanel {
24348
24419
  const { db } = this.root;
24349
24420
  const props = this._parsedProps;
24350
24421
  const inserted = db.pcb_panel.insert({
24351
- width: props.width !== void 0 ? distance14.parse(props.width) : 0,
24352
- height: props.height !== void 0 ? distance14.parse(props.height) : 0,
24422
+ width: props.width !== void 0 ? distance15.parse(props.width) : 0,
24423
+ height: props.height !== void 0 ? distance15.parse(props.height) : 0,
24353
24424
  thickness: 1.6,
24354
24425
  center: this._getGlobalPcbPositionBeforeLayout(),
24355
24426
  covered_with_solder_mask: !(props.noSolderMask ?? false)
@@ -24368,8 +24439,8 @@ var Panel = class extends Subpanel {
24368
24439
  if (!this.pcb_panel_id) return;
24369
24440
  if (hasExplicitWidth && hasExplicitHeight) {
24370
24441
  db.pcb_panel.update(this.pcb_panel_id, {
24371
- width: distance14.parse(this._parsedProps.width),
24372
- height: distance14.parse(this._parsedProps.height)
24442
+ width: distance15.parse(this._parsedProps.width),
24443
+ height: distance15.parse(this._parsedProps.height)
24373
24444
  });
24374
24445
  } else if (gridWidth > 0 || gridHeight > 0) {
24375
24446
  const {
@@ -24379,18 +24450,18 @@ var Panel = class extends Subpanel {
24379
24450
  edgePaddingTop: edgePaddingTopProp,
24380
24451
  edgePaddingBottom: edgePaddingBottomProp
24381
24452
  } = this._parsedProps;
24382
- const edgePadding = distance14.parse(edgePaddingProp ?? 5);
24383
- const edgePaddingLeft = distance14.parse(edgePaddingLeftProp ?? edgePadding);
24384
- const edgePaddingRight = distance14.parse(
24453
+ const edgePadding = distance15.parse(edgePaddingProp ?? 5);
24454
+ const edgePaddingLeft = distance15.parse(edgePaddingLeftProp ?? edgePadding);
24455
+ const edgePaddingRight = distance15.parse(
24385
24456
  edgePaddingRightProp ?? edgePadding
24386
24457
  );
24387
- const edgePaddingTop = distance14.parse(edgePaddingTopProp ?? edgePadding);
24388
- const edgePaddingBottom = distance14.parse(
24458
+ const edgePaddingTop = distance15.parse(edgePaddingTopProp ?? edgePadding);
24459
+ const edgePaddingBottom = distance15.parse(
24389
24460
  edgePaddingBottomProp ?? edgePadding
24390
24461
  );
24391
24462
  db.pcb_panel.update(this.pcb_panel_id, {
24392
- width: hasExplicitWidth ? distance14.parse(this._parsedProps.width) : gridWidth + edgePaddingLeft + edgePaddingRight,
24393
- height: hasExplicitHeight ? distance14.parse(this._parsedProps.height) : gridHeight + edgePaddingTop + edgePaddingBottom
24463
+ width: hasExplicitWidth ? distance15.parse(this._parsedProps.width) : gridWidth + edgePaddingLeft + edgePaddingRight,
24464
+ height: hasExplicitHeight ? distance15.parse(this._parsedProps.height) : gridHeight + edgePaddingTop + edgePaddingBottom
24394
24465
  });
24395
24466
  }
24396
24467
  }
@@ -24401,8 +24472,8 @@ var Panel = class extends Subpanel {
24401
24472
  const props = this._parsedProps;
24402
24473
  const currentPanel = db.pcb_panel.get(this.pcb_panel_id);
24403
24474
  db.pcb_panel.update(this.pcb_panel_id, {
24404
- width: props.width !== void 0 ? distance14.parse(props.width) : currentPanel?.width,
24405
- height: props.height !== void 0 ? distance14.parse(props.height) : currentPanel?.height,
24475
+ width: props.width !== void 0 ? distance15.parse(props.width) : currentPanel?.width,
24476
+ height: props.height !== void 0 ? distance15.parse(props.height) : currentPanel?.height,
24406
24477
  center: this._getGlobalPcbPositionBeforeLayout(),
24407
24478
  covered_with_solder_mask: !(props.noSolderMask ?? false)
24408
24479
  });
@@ -25495,7 +25566,7 @@ import { BaseSolver } from "@tscircuit/solver-utils";
25495
25566
 
25496
25567
  // node_modules/@tscircuit/breakout-point-solver/lib/boundary/get-breakout-boundary-intersection.ts
25497
25568
  import {
25498
- distance as distance15,
25569
+ distance as distance16,
25499
25570
  getSegmentIntersection
25500
25571
  } from "@tscircuit/math-utils";
25501
25572
  var getBreakoutBoundaryIntersection = ({
@@ -25523,12 +25594,12 @@ var getBreakoutBoundaryIntersection = ({
25523
25594
  ]
25524
25595
  ];
25525
25596
  const candidates = boundarySegments.map(([start, end]) => getSegmentIntersection(from, to, start, end)).filter((point6) => point6 !== null);
25526
- candidates.sort((a, b) => distance15(from, a) - distance15(from, b));
25597
+ candidates.sort((a, b) => distance16(from, a) - distance16(from, b));
25527
25598
  return candidates[0] ?? null;
25528
25599
  };
25529
25600
 
25530
25601
  // node_modules/@tscircuit/breakout-point-solver/lib/boundary/get-available-breakout-boundary-point.ts
25531
- import { distance as distance16 } from "@tscircuit/math-utils";
25602
+ import { distance as distance17 } from "@tscircuit/math-utils";
25532
25603
 
25533
25604
  // node_modules/@tscircuit/breakout-point-solver/lib/pad/breakout-pad-collisions.ts
25534
25605
  import {
@@ -25630,7 +25701,7 @@ var isInsideRequiredSpacing = ({
25630
25701
  candidate,
25631
25702
  usedPoint,
25632
25703
  boundaryPointSpacing
25633
- }) => distance16(usedPoint, candidate) < boundaryPointSpacing - BOUNDARY_POINT_DISTANCE_TOLERANCE;
25704
+ }) => distance17(usedPoint, candidate) < boundaryPointSpacing - BOUNDARY_POINT_DISTANCE_TOLERANCE;
25634
25705
  var getBoundsEdge = (point6, bounds) => {
25635
25706
  if (Math.abs(point6.x - bounds.minX) < BOUNDARY_POINT_DISTANCE_TOLERANCE)
25636
25707
  return "left";
@@ -25821,7 +25892,7 @@ var getAvailableBreakoutBoundaryPoint = ({
25821
25892
  step
25822
25893
  });
25823
25894
  edgeCandidates.sort(
25824
- (a, b) => distance16(a, idealPoint) - distance16(b, idealPoint)
25895
+ (a, b) => distance17(a, idealPoint) - distance17(b, idealPoint)
25825
25896
  );
25826
25897
  for (const candidate of edgeCandidates) {
25827
25898
  if (isCandidateAvailable({
@@ -25837,7 +25908,7 @@ var getAvailableBreakoutBoundaryPoint = ({
25837
25908
  }
25838
25909
  }
25839
25910
  const candidates = getAllBoundsCandidates({ bounds, step });
25840
- candidates.sort((a, b) => distance16(a, idealPoint) - distance16(b, idealPoint));
25911
+ candidates.sort((a, b) => distance17(a, idealPoint) - distance17(b, idealPoint));
25841
25912
  for (const candidate of candidates) {
25842
25913
  if (isCandidateAvailable({
25843
25914
  candidate,
@@ -25887,7 +25958,7 @@ var getAvailableBreakoutBoundaryPointForOutsidePorts = ({
25887
25958
  if (!edge) continue;
25888
25959
  const edgeCandidates = getBoundsEdgeCandidates({ edge, bounds, step });
25889
25960
  edgeCandidates.sort(
25890
- (a, b) => distance16(a, idealPoint) - distance16(b, idealPoint)
25961
+ (a, b) => distance17(a, idealPoint) - distance17(b, idealPoint)
25891
25962
  );
25892
25963
  for (const candidate of edgeCandidates) {
25893
25964
  if (isCandidateAvailableForOutsidePorts({
@@ -25907,7 +25978,7 @@ var getAvailableBreakoutBoundaryPointForOutsidePorts = ({
25907
25978
  }
25908
25979
  for (const idealPoint of idealPoints) {
25909
25980
  const candidates = getAllBoundsCandidates({ bounds, step });
25910
- candidates.sort((a, b) => distance16(a, idealPoint) - distance16(b, idealPoint));
25981
+ candidates.sort((a, b) => distance17(a, idealPoint) - distance17(b, idealPoint));
25911
25982
  for (const candidate of candidates) {
25912
25983
  if (isCandidateAvailableForOutsidePorts({
25913
25984
  candidate,
@@ -26427,6 +26498,11 @@ var createBreakoutPointSolverInput = (breakout) => {
26427
26498
  label: component.pcb_component_id
26428
26499
  }));
26429
26500
  const usedBoundaryPoints = db.pcb_breakout_point.list().filter((point6) => point6.pcb_group_id === breakout.pcb_group_id).map((point6) => ({ x: point6.x, y: point6.y }));
26501
+ const board = db.pcb_board.list()[0];
26502
+ const traceWidth = board?.min_trace_width ?? 0.15;
26503
+ const clearance = board?.min_trace_to_pad_edge_clearance ?? 0.2;
26504
+ const viaPadDiameter = board?.min_via_pad_diameter ?? 0.3;
26505
+ const boundaryPointSpacing = viaPadDiameter + 2 * (traceWidth + clearance);
26430
26506
  return {
26431
26507
  bounds: {
26432
26508
  minX: boundsMinX,
@@ -26434,7 +26510,7 @@ var createBreakoutPointSolverInput = (breakout) => {
26434
26510
  minY: boundsMinY,
26435
26511
  maxY: boundsMaxY
26436
26512
  },
26437
- boundaryPointSpacing: 0.5,
26513
+ boundaryPointSpacing,
26438
26514
  traces,
26439
26515
  pads,
26440
26516
  components,
@@ -26502,15 +26578,28 @@ var Breakout = class extends Group5 {
26502
26578
  const autoBreakoutPoints = this.children.filter(
26503
26579
  (c) => c instanceof AutoplacedBreakoutPoint
26504
26580
  );
26581
+ const BOUNDARY_INSET_MM = 1e-4;
26582
+ const { bounds } = solverInput;
26583
+ const insetWithinBounds = (x, y) => ({
26584
+ x: Math.max(
26585
+ bounds.minX + BOUNDARY_INSET_MM,
26586
+ Math.min(bounds.maxX - BOUNDARY_INSET_MM, x)
26587
+ ),
26588
+ y: Math.max(
26589
+ bounds.minY + BOUNDARY_INSET_MM,
26590
+ Math.min(bounds.maxY - BOUNDARY_INSET_MM, y)
26591
+ )
26592
+ });
26505
26593
  for (const solvedPoint of output.breakoutPoints) {
26506
26594
  const matchingBreakoutPoint = autoBreakoutPoints.find(
26507
26595
  (child) => child.matchedPort?.source_port_id === solvedPoint.sourcePortId
26508
26596
  );
26509
26597
  if (matchingBreakoutPoint) {
26510
26598
  matchingBreakoutPoint.matchedSourceTraceId = solvedPoint.sourceTraceId;
26599
+ const insetPoint = insetWithinBounds(solvedPoint.x, solvedPoint.y);
26511
26600
  matchingBreakoutPoint._setPositionFromLayout({
26512
- x: solvedPoint.x,
26513
- y: solvedPoint.y
26601
+ x: insetPoint.x,
26602
+ y: insetPoint.y
26514
26603
  });
26515
26604
  }
26516
26605
  }
@@ -26736,7 +26825,7 @@ var NetLabel = class extends PrimitiveComponent2 {
26736
26825
 
26737
26826
  // lib/components/primitive-components/Fiducial.ts
26738
26827
  import "zod";
26739
- import { distance as distance17 } from "circuit-json";
26828
+ import { distance as distance18 } from "circuit-json";
26740
26829
  import { fiducialProps } from "@tscircuit/props";
26741
26830
  var Fiducial = class extends PrimitiveComponent2 {
26742
26831
  pcb_smtpad_id = null;
@@ -26761,15 +26850,15 @@ var Fiducial = class extends PrimitiveComponent2 {
26761
26850
  shape: "circle",
26762
26851
  x: position.x,
26763
26852
  y: position.y,
26764
- radius: distance17.parse(props.padDiameter) / 2,
26765
- soldermask_margin: props.soldermaskPullback ? distance17.parse(props.soldermaskPullback) : distance17.parse(props.padDiameter) / 2,
26853
+ radius: distance18.parse(props.padDiameter) / 2,
26854
+ soldermask_margin: props.soldermaskPullback ? distance18.parse(props.soldermaskPullback) : distance18.parse(props.padDiameter) / 2,
26766
26855
  is_covered_with_solder_mask: true
26767
26856
  });
26768
26857
  this.pcb_smtpad_id = pcb_smtpad.pcb_smtpad_id;
26769
26858
  }
26770
26859
  getPcbSize() {
26771
26860
  const { _parsedProps: props } = this;
26772
- const d = distance17.parse(props.padDiameter);
26861
+ const d = distance18.parse(props.padDiameter);
26773
26862
  return { width: d, height: d };
26774
26863
  }
26775
26864
  _setPositionFromLayout(newCenter) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/core",
3
3
  "type": "module",
4
- "version": "0.0.1297",
4
+ "version": "0.0.1298",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",