@tscircuit/core 0.0.905 → 0.0.907
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 +280 -123
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -2335,10 +2335,10 @@ var SmtPad = class extends PrimitiveComponent2 {
|
|
|
2335
2335
|
pcb_group_id: this.getGroup()?.pcb_group_id ?? void 0
|
|
2336
2336
|
});
|
|
2337
2337
|
} else if (props.shape === "polygon") {
|
|
2338
|
-
const transformedPoints = props.points.map((
|
|
2338
|
+
const transformedPoints = props.points.map((point2) => {
|
|
2339
2339
|
const transformed = applyToPoint2(globalTransform, {
|
|
2340
|
-
x: distance.parse(
|
|
2341
|
-
y: distance.parse(
|
|
2340
|
+
x: distance.parse(point2.x),
|
|
2341
|
+
y: distance.parse(point2.y)
|
|
2342
2342
|
});
|
|
2343
2343
|
return {
|
|
2344
2344
|
x: transformed.x,
|
|
@@ -2546,18 +2546,18 @@ var SilkscreenPath = class extends PrimitiveComponent2 {
|
|
|
2546
2546
|
if (!currentPath) return;
|
|
2547
2547
|
let currentCenterX = 0;
|
|
2548
2548
|
let currentCenterY = 0;
|
|
2549
|
-
for (const
|
|
2550
|
-
currentCenterX +=
|
|
2551
|
-
currentCenterY +=
|
|
2549
|
+
for (const point2 of currentPath.route) {
|
|
2550
|
+
currentCenterX += point2.x;
|
|
2551
|
+
currentCenterY += point2.y;
|
|
2552
2552
|
}
|
|
2553
2553
|
currentCenterX /= currentPath.route.length;
|
|
2554
2554
|
currentCenterY /= currentPath.route.length;
|
|
2555
2555
|
const offsetX = newCenter.x - currentCenterX;
|
|
2556
2556
|
const offsetY = newCenter.y - currentCenterY;
|
|
2557
|
-
const newRoute = currentPath.route.map((
|
|
2558
|
-
...
|
|
2559
|
-
x:
|
|
2560
|
-
y:
|
|
2557
|
+
const newRoute = currentPath.route.map((point2) => ({
|
|
2558
|
+
...point2,
|
|
2559
|
+
x: point2.x + offsetX,
|
|
2560
|
+
y: point2.y + offsetY
|
|
2561
2561
|
}));
|
|
2562
2562
|
db.pcb_silkscreen_path.update(this.pcb_silkscreen_path_id, {
|
|
2563
2563
|
route: newRoute
|
|
@@ -2569,11 +2569,11 @@ var SilkscreenPath = class extends PrimitiveComponent2 {
|
|
|
2569
2569
|
return { width: 0, height: 0 };
|
|
2570
2570
|
}
|
|
2571
2571
|
let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
|
|
2572
|
-
for (const
|
|
2573
|
-
minX = Math.min(minX,
|
|
2574
|
-
maxX = Math.max(maxX,
|
|
2575
|
-
minY = Math.min(minY,
|
|
2576
|
-
maxY = Math.max(maxY,
|
|
2572
|
+
for (const point2 of props.route) {
|
|
2573
|
+
minX = Math.min(minX, point2.x);
|
|
2574
|
+
maxX = Math.max(maxX, point2.x);
|
|
2575
|
+
minY = Math.min(minY, point2.y);
|
|
2576
|
+
maxY = Math.max(maxY, point2.y);
|
|
2577
2577
|
}
|
|
2578
2578
|
return {
|
|
2579
2579
|
width: maxX - minX,
|
|
@@ -2609,14 +2609,14 @@ var PcbTrace = class extends PrimitiveComponent2 {
|
|
|
2609
2609
|
const subcircuit = this.getSubcircuit();
|
|
2610
2610
|
const { maybeFlipLayer } = this._getPcbPrimitiveFlippedHelpers();
|
|
2611
2611
|
const parentTransform = this._computePcbGlobalTransformBeforeLayout();
|
|
2612
|
-
const transformedRoute = props.route.map((
|
|
2613
|
-
const { x, y, ...restOfPoint } =
|
|
2612
|
+
const transformedRoute = props.route.map((point2) => {
|
|
2613
|
+
const { x, y, ...restOfPoint } = point2;
|
|
2614
2614
|
const transformedPoint = applyToPoint4(parentTransform, { x, y });
|
|
2615
|
-
if (
|
|
2615
|
+
if (point2.route_type === "wire" && point2.layer) {
|
|
2616
2616
|
return {
|
|
2617
2617
|
...transformedPoint,
|
|
2618
2618
|
...restOfPoint,
|
|
2619
|
-
layer: maybeFlipLayer(
|
|
2619
|
+
layer: maybeFlipLayer(point2.layer)
|
|
2620
2620
|
};
|
|
2621
2621
|
}
|
|
2622
2622
|
return { ...transformedPoint, ...restOfPoint };
|
|
@@ -2636,16 +2636,16 @@ var PcbTrace = class extends PrimitiveComponent2 {
|
|
|
2636
2636
|
return { width: 0, height: 0 };
|
|
2637
2637
|
}
|
|
2638
2638
|
let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
|
|
2639
|
-
for (const
|
|
2640
|
-
minX = Math.min(minX,
|
|
2641
|
-
maxX = Math.max(maxX,
|
|
2642
|
-
minY = Math.min(minY,
|
|
2643
|
-
maxY = Math.max(maxY,
|
|
2644
|
-
if (
|
|
2645
|
-
minX = Math.min(minX,
|
|
2646
|
-
maxX = Math.max(maxX,
|
|
2647
|
-
minY = Math.min(minY,
|
|
2648
|
-
maxY = Math.max(maxY,
|
|
2639
|
+
for (const point2 of props.route) {
|
|
2640
|
+
minX = Math.min(minX, point2.x);
|
|
2641
|
+
maxX = Math.max(maxX, point2.x);
|
|
2642
|
+
minY = Math.min(minY, point2.y);
|
|
2643
|
+
maxY = Math.max(maxY, point2.y);
|
|
2644
|
+
if (point2.route_type === "wire") {
|
|
2645
|
+
minX = Math.min(minX, point2.x - point2.width / 2);
|
|
2646
|
+
maxX = Math.max(maxX, point2.x + point2.width / 2);
|
|
2647
|
+
minY = Math.min(minY, point2.y - point2.width / 2);
|
|
2648
|
+
maxY = Math.max(maxY, point2.y + point2.width / 2);
|
|
2649
2649
|
}
|
|
2650
2650
|
}
|
|
2651
2651
|
if (minX === Infinity || maxX === -Infinity || minY === Infinity || maxY === -Infinity) {
|
|
@@ -2911,9 +2911,9 @@ var PlatedHole = class extends PrimitiveComponent2 {
|
|
|
2911
2911
|
});
|
|
2912
2912
|
this.pcb_plated_hole_id = pcb_plated_hole.pcb_plated_hole_id;
|
|
2913
2913
|
} else if (props.shape === "hole_with_polygon_pad") {
|
|
2914
|
-
const padOutline = (props.padOutline || []).map((
|
|
2915
|
-
const x = typeof
|
|
2916
|
-
const y = typeof
|
|
2914
|
+
const padOutline = (props.padOutline || []).map((point2) => {
|
|
2915
|
+
const x = typeof point2.x === "number" ? point2.x : parseFloat(String(point2.x));
|
|
2916
|
+
const y = typeof point2.y === "number" ? point2.y : parseFloat(String(point2.y));
|
|
2917
2917
|
return {
|
|
2918
2918
|
x,
|
|
2919
2919
|
y
|
|
@@ -3273,11 +3273,11 @@ var Cutout = class extends PrimitiveComponent2 {
|
|
|
3273
3273
|
if (props.shape === "polygon") {
|
|
3274
3274
|
if (props.points.length === 0) return { width: 0, height: 0 };
|
|
3275
3275
|
let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
|
|
3276
|
-
for (const
|
|
3277
|
-
minX = Math.min(minX,
|
|
3278
|
-
maxX = Math.max(maxX,
|
|
3279
|
-
minY = Math.min(minY,
|
|
3280
|
-
maxY = Math.max(maxY,
|
|
3276
|
+
for (const point2 of props.points) {
|
|
3277
|
+
minX = Math.min(minX, point2.x);
|
|
3278
|
+
maxX = Math.max(maxX, point2.x);
|
|
3279
|
+
minY = Math.min(minY, point2.y);
|
|
3280
|
+
maxY = Math.max(maxY, point2.y);
|
|
3281
3281
|
}
|
|
3282
3282
|
return { width: maxX - minX, height: maxY - minY };
|
|
3283
3283
|
}
|
|
@@ -3316,11 +3316,11 @@ var Cutout = class extends PrimitiveComponent2 {
|
|
|
3316
3316
|
} else if (cutout.shape === "polygon") {
|
|
3317
3317
|
if (cutout.points.length === 0) return super._getPcbCircuitJsonBounds();
|
|
3318
3318
|
let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
|
|
3319
|
-
for (const
|
|
3320
|
-
minX = Math.min(minX,
|
|
3321
|
-
maxX = Math.max(maxX,
|
|
3322
|
-
minY = Math.min(minY,
|
|
3323
|
-
maxY = Math.max(maxY,
|
|
3319
|
+
for (const point2 of cutout.points) {
|
|
3320
|
+
minX = Math.min(minX, point2.x);
|
|
3321
|
+
maxX = Math.max(maxX, point2.x);
|
|
3322
|
+
minY = Math.min(minY, point2.y);
|
|
3323
|
+
maxY = Math.max(maxY, point2.y);
|
|
3324
3324
|
}
|
|
3325
3325
|
return {
|
|
3326
3326
|
center: { x: (minX + maxX) / 2, y: (minY + maxY) / 2 },
|
|
@@ -5324,13 +5324,13 @@ var getDistance = (a, b) => {
|
|
|
5324
5324
|
const bPos = "_getGlobalPcbPositionBeforeLayout" in b ? b._getGlobalPcbPositionBeforeLayout() : b;
|
|
5325
5325
|
return Math.sqrt((aPos.x - bPos.x) ** 2 + (aPos.y - bPos.y) ** 2);
|
|
5326
5326
|
};
|
|
5327
|
-
function getClosest(
|
|
5327
|
+
function getClosest(point2, candidates) {
|
|
5328
5328
|
if (candidates.length === 0)
|
|
5329
5329
|
throw new Error("No candidates given to getClosest method");
|
|
5330
5330
|
let closest = candidates[0];
|
|
5331
5331
|
let closestDist = Infinity;
|
|
5332
5332
|
for (const candidate of candidates) {
|
|
5333
|
-
const dist = getDistance(
|
|
5333
|
+
const dist = getDistance(point2, candidate);
|
|
5334
5334
|
if (dist < closestDist) {
|
|
5335
5335
|
closest = candidate;
|
|
5336
5336
|
closestDist = dist;
|
|
@@ -5464,24 +5464,24 @@ var isRouteOutsideBoard = (mergedRoute, { db }) => {
|
|
|
5464
5464
|
const pcbBoard = db.pcb_board.list()[0];
|
|
5465
5465
|
if (pcbBoard.outline) {
|
|
5466
5466
|
const boardOutline = pcbBoard.outline;
|
|
5467
|
-
const isInsidePolygon = (
|
|
5467
|
+
const isInsidePolygon = (point2, polygon) => {
|
|
5468
5468
|
let inside = false;
|
|
5469
5469
|
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
|
|
5470
5470
|
const xi = polygon[i].x, yi = polygon[i].y;
|
|
5471
5471
|
const xj = polygon[j].x, yj = polygon[j].y;
|
|
5472
|
-
const intersect = yi >
|
|
5472
|
+
const intersect = yi > point2.y !== yj > point2.y && point2.x < (xj - xi) * (point2.y - yi) / (yj - yi) + xi;
|
|
5473
5473
|
if (intersect) inside = !inside;
|
|
5474
5474
|
}
|
|
5475
5475
|
return inside;
|
|
5476
5476
|
};
|
|
5477
|
-
return mergedRoute.some((
|
|
5477
|
+
return mergedRoute.some((point2) => !isInsidePolygon(point2, boardOutline));
|
|
5478
5478
|
}
|
|
5479
5479
|
const boardWidth = pcbBoard.width;
|
|
5480
5480
|
const boardHeight = pcbBoard.height;
|
|
5481
5481
|
const boardCenterX = pcbBoard.center.x;
|
|
5482
5482
|
const boardCenterY = pcbBoard.center.y;
|
|
5483
|
-
const outsideBoard = mergedRoute.some((
|
|
5484
|
-
return
|
|
5483
|
+
const outsideBoard = mergedRoute.some((point2) => {
|
|
5484
|
+
return point2.x < boardCenterX - boardWidth / 2 || point2.y < boardCenterY - boardHeight / 2 || point2.x > boardCenterX + boardWidth / 2 || point2.y > boardCenterY + boardHeight / 2;
|
|
5485
5485
|
});
|
|
5486
5486
|
return outsideBoard;
|
|
5487
5487
|
};
|
|
@@ -6063,12 +6063,12 @@ var createSchematicTraceCrossingSegments = ({
|
|
|
6063
6063
|
|
|
6064
6064
|
// lib/components/primitive-components/Trace/trace-utils/create-schematic-trace-junctions.ts
|
|
6065
6065
|
var TOLERANCE = 1e-3;
|
|
6066
|
-
var isPointWithinEdge = (
|
|
6066
|
+
var isPointWithinEdge = (point2, edge) => {
|
|
6067
6067
|
const minX = Math.min(edge.from.x, edge.to.x);
|
|
6068
6068
|
const maxX = Math.max(edge.from.x, edge.to.x);
|
|
6069
6069
|
const minY = Math.min(edge.from.y, edge.to.y);
|
|
6070
6070
|
const maxY = Math.max(edge.from.y, edge.to.y);
|
|
6071
|
-
return
|
|
6071
|
+
return point2.x >= minX && point2.x <= maxX && point2.y >= minY && point2.y <= maxY;
|
|
6072
6072
|
};
|
|
6073
6073
|
var getEdgeOrientation = (edge) => {
|
|
6074
6074
|
const isVertical = Math.abs(edge.from.x - edge.to.x) < TOLERANCE;
|
|
@@ -6673,15 +6673,15 @@ import { getFullConnectivityMapFromCircuitJson } from "circuit-json-to-connectiv
|
|
|
6673
6673
|
function getTraceLength(route) {
|
|
6674
6674
|
let totalLength = 0;
|
|
6675
6675
|
for (let i = 0; i < route.length; i++) {
|
|
6676
|
-
const
|
|
6677
|
-
if (
|
|
6676
|
+
const point2 = route[i];
|
|
6677
|
+
if (point2.route_type === "wire") {
|
|
6678
6678
|
const nextPoint = route[i + 1];
|
|
6679
6679
|
if (nextPoint) {
|
|
6680
|
-
const dx = nextPoint.x -
|
|
6681
|
-
const dy = nextPoint.y -
|
|
6680
|
+
const dx = nextPoint.x - point2.x;
|
|
6681
|
+
const dy = nextPoint.y - point2.y;
|
|
6682
6682
|
totalLength += Math.sqrt(dx * dx + dy * dy);
|
|
6683
6683
|
}
|
|
6684
|
-
} else if (
|
|
6684
|
+
} else if (point2.route_type === "via") {
|
|
6685
6685
|
totalLength += 1.6;
|
|
6686
6686
|
}
|
|
6687
6687
|
}
|
|
@@ -6991,17 +6991,17 @@ function Trace_doInitialPcbTraceRender(trace) {
|
|
|
6991
6991
|
});
|
|
6992
6992
|
trace._portsRoutedOnPcb = ports;
|
|
6993
6993
|
trace.pcb_trace_id = pcb_trace.pcb_trace_id;
|
|
6994
|
-
for (const
|
|
6995
|
-
if (
|
|
6994
|
+
for (const point2 of mergedRoute) {
|
|
6995
|
+
if (point2.route_type === "via") {
|
|
6996
6996
|
db.pcb_via.insert({
|
|
6997
6997
|
pcb_trace_id: pcb_trace.pcb_trace_id,
|
|
6998
|
-
x:
|
|
6999
|
-
y:
|
|
6998
|
+
x: point2.x,
|
|
6999
|
+
y: point2.y,
|
|
7000
7000
|
hole_diameter: holeDiameter,
|
|
7001
7001
|
outer_diameter: padDiameter,
|
|
7002
|
-
layers: [
|
|
7003
|
-
from_layer:
|
|
7004
|
-
to_layer:
|
|
7002
|
+
layers: [point2.from_layer, point2.to_layer],
|
|
7003
|
+
from_layer: point2.from_layer,
|
|
7004
|
+
to_layer: point2.to_layer
|
|
7005
7005
|
});
|
|
7006
7006
|
}
|
|
7007
7007
|
}
|
|
@@ -10247,7 +10247,7 @@ var getSimpleRouteJsonFromCircuitJson = ({
|
|
|
10247
10247
|
// subcircuit
|
|
10248
10248
|
layerCount: board?.num_layers ?? 2,
|
|
10249
10249
|
minTraceWidth,
|
|
10250
|
-
outline: board?.outline?.map((
|
|
10250
|
+
outline: board?.outline?.map((point2) => ({ ...point2 }))
|
|
10251
10251
|
},
|
|
10252
10252
|
connMap
|
|
10253
10253
|
};
|
|
@@ -13735,9 +13735,9 @@ var Group6 = class extends NormalComponent3 {
|
|
|
13735
13735
|
const { _parsedProps: props } = this;
|
|
13736
13736
|
const groupProps2 = props;
|
|
13737
13737
|
const hasOutline = groupProps2.outline && groupProps2.outline.length > 0;
|
|
13738
|
-
const numericOutline = hasOutline ? groupProps2.outline.map((
|
|
13739
|
-
x: distance8.parse(
|
|
13740
|
-
y: distance8.parse(
|
|
13738
|
+
const numericOutline = hasOutline ? groupProps2.outline.map((point2) => ({
|
|
13739
|
+
x: distance8.parse(point2.x),
|
|
13740
|
+
y: distance8.parse(point2.y)
|
|
13741
13741
|
})) : void 0;
|
|
13742
13742
|
const pcb_group = db.pcb_group.insert({
|
|
13743
13743
|
is_subcircuit: this.isSubcircuit,
|
|
@@ -13766,9 +13766,9 @@ var Group6 = class extends NormalComponent3 {
|
|
|
13766
13766
|
if (this.pcb_group_id) {
|
|
13767
13767
|
const hasExplicitPositioning = this._parsedProps.pcbX !== void 0 || this._parsedProps.pcbY !== void 0;
|
|
13768
13768
|
if (hasOutline) {
|
|
13769
|
-
const numericOutline = props.outline.map((
|
|
13770
|
-
x: distance8.parse(
|
|
13771
|
-
y: distance8.parse(
|
|
13769
|
+
const numericOutline = props.outline.map((point2) => ({
|
|
13770
|
+
x: distance8.parse(point2.x),
|
|
13771
|
+
y: distance8.parse(point2.y)
|
|
13772
13772
|
}));
|
|
13773
13773
|
const outlineBounds = getBoundsFromPoints3(numericOutline);
|
|
13774
13774
|
if (!outlineBounds) return;
|
|
@@ -14183,20 +14183,20 @@ var Group6 = class extends NormalComponent3 {
|
|
|
14183
14183
|
continue;
|
|
14184
14184
|
}
|
|
14185
14185
|
if (pcb_trace.type === "pcb_trace") {
|
|
14186
|
-
for (const
|
|
14187
|
-
if (
|
|
14186
|
+
for (const point2 of pcb_trace.route) {
|
|
14187
|
+
if (point2.route_type === "via") {
|
|
14188
14188
|
db.pcb_via.insert({
|
|
14189
14189
|
pcb_trace_id: pcb_trace.pcb_trace_id,
|
|
14190
|
-
x:
|
|
14191
|
-
y:
|
|
14190
|
+
x: point2.x,
|
|
14191
|
+
y: point2.y,
|
|
14192
14192
|
hole_diameter: holeDiameter,
|
|
14193
14193
|
outer_diameter: padDiameter,
|
|
14194
14194
|
layers: [
|
|
14195
|
-
|
|
14196
|
-
|
|
14195
|
+
point2.from_layer,
|
|
14196
|
+
point2.to_layer
|
|
14197
14197
|
],
|
|
14198
|
-
from_layer:
|
|
14199
|
-
to_layer:
|
|
14198
|
+
from_layer: point2.from_layer,
|
|
14199
|
+
to_layer: point2.to_layer
|
|
14200
14200
|
});
|
|
14201
14201
|
}
|
|
14202
14202
|
}
|
|
@@ -15047,7 +15047,8 @@ var Inductor = class extends NormalComponent3 {
|
|
|
15047
15047
|
const source_component = db.source_component.insert({
|
|
15048
15048
|
name: this.name,
|
|
15049
15049
|
ftype: FTYPE.simple_inductor,
|
|
15050
|
-
inductance: props.inductance,
|
|
15050
|
+
inductance: this.props.inductance,
|
|
15051
|
+
display_inductance: this._getSchematicSymbolDisplayValue(),
|
|
15051
15052
|
supplier_part_numbers: props.supplierPartNumbers,
|
|
15052
15053
|
are_pins_interchangeable: true
|
|
15053
15054
|
});
|
|
@@ -15635,9 +15636,9 @@ var Board = class extends Group6 {
|
|
|
15635
15636
|
center
|
|
15636
15637
|
};
|
|
15637
15638
|
if (outline) {
|
|
15638
|
-
update.outline = outline.map((
|
|
15639
|
-
x:
|
|
15640
|
-
y:
|
|
15639
|
+
update.outline = outline.map((point2) => ({
|
|
15640
|
+
x: point2.x + (props.outlineOffsetX ?? 0),
|
|
15641
|
+
y: point2.y + (props.outlineOffsetY ?? 0)
|
|
15641
15642
|
}));
|
|
15642
15643
|
}
|
|
15643
15644
|
db.pcb_board.update(this.pcb_board_id, update);
|
|
@@ -15716,8 +15717,8 @@ var Board = class extends Group6 {
|
|
|
15716
15717
|
});
|
|
15717
15718
|
}
|
|
15718
15719
|
if (props.outline) {
|
|
15719
|
-
const xValues = props.outline.map((
|
|
15720
|
-
const yValues = props.outline.map((
|
|
15720
|
+
const xValues = props.outline.map((point2) => point2.x);
|
|
15721
|
+
const yValues = props.outline.map((point2) => point2.y);
|
|
15721
15722
|
const minX = Math.min(...xValues);
|
|
15722
15723
|
const maxX = Math.max(...xValues);
|
|
15723
15724
|
const minY = Math.min(...yValues);
|
|
@@ -15743,9 +15744,9 @@ var Board = class extends Group6 {
|
|
|
15743
15744
|
num_layers: this.allLayers.length,
|
|
15744
15745
|
width: computedWidth,
|
|
15745
15746
|
height: computedHeight,
|
|
15746
|
-
outline: outline?.map((
|
|
15747
|
-
x:
|
|
15748
|
-
y:
|
|
15747
|
+
outline: outline?.map((point2) => ({
|
|
15748
|
+
x: point2.x + (props.outlineOffsetX ?? 0),
|
|
15749
|
+
y: point2.y + (props.outlineOffsetY ?? 0)
|
|
15749
15750
|
})),
|
|
15750
15751
|
material: props.material
|
|
15751
15752
|
});
|
|
@@ -15821,6 +15822,7 @@ import { panelProps } from "@tscircuit/props";
|
|
|
15821
15822
|
import { distance as distance9 } from "circuit-json";
|
|
15822
15823
|
|
|
15823
15824
|
// lib/utils/panels/generate-panel-tabs-and-mouse-bites.ts
|
|
15825
|
+
import * as Flatten from "@flatten-js/core";
|
|
15824
15826
|
var DEFAULT_PANEL_MARGIN = 5;
|
|
15825
15827
|
var DEFAULT_TAB_LENGTH = 5;
|
|
15826
15828
|
var DEFAULT_TAB_WIDTH = 2;
|
|
@@ -15835,15 +15837,15 @@ function rectanglesOverlap(rect1, rect2) {
|
|
|
15835
15837
|
const r2Top = rect2.center.y + rect2.height / 2;
|
|
15836
15838
|
return !(r1Right <= r2Left || r1Left >= r2Right || r1Top <= r2Bottom || r1Bottom >= r2Top);
|
|
15837
15839
|
}
|
|
15838
|
-
function pointOverlapsRectangle(
|
|
15840
|
+
function pointOverlapsRectangle(point2, radius, rect) {
|
|
15839
15841
|
const rectLeft = rect.center.x - rect.width / 2;
|
|
15840
15842
|
const rectRight = rect.center.x + rect.width / 2;
|
|
15841
15843
|
const rectBottom = rect.center.y - rect.height / 2;
|
|
15842
15844
|
const rectTop = rect.center.y + rect.height / 2;
|
|
15843
|
-
const closestX = Math.max(rectLeft, Math.min(
|
|
15844
|
-
const closestY = Math.max(rectBottom, Math.min(
|
|
15845
|
-
const distanceX =
|
|
15846
|
-
const distanceY =
|
|
15845
|
+
const closestX = Math.max(rectLeft, Math.min(point2.x, rectRight));
|
|
15846
|
+
const closestY = Math.max(rectBottom, Math.min(point2.y, rectTop));
|
|
15847
|
+
const distanceX = point2.x - closestX;
|
|
15848
|
+
const distanceY = point2.y - closestY;
|
|
15847
15849
|
return distanceX * distanceX + distanceY * distanceY <= radius * radius;
|
|
15848
15850
|
}
|
|
15849
15851
|
function generateTabsForEdge({
|
|
@@ -16019,44 +16021,199 @@ function generateMouseBitesForEdge({
|
|
|
16019
16021
|
}
|
|
16020
16022
|
return mouseBites;
|
|
16021
16023
|
}
|
|
16024
|
+
var generatePanelTabsAndMouseBitesForOutlines = (outline, otherBoards, options) => {
|
|
16025
|
+
const {
|
|
16026
|
+
boardGap,
|
|
16027
|
+
tabLength,
|
|
16028
|
+
// along edge
|
|
16029
|
+
tabWidth,
|
|
16030
|
+
// extrusion
|
|
16031
|
+
mouseBites,
|
|
16032
|
+
mouseBiteHoleDiameter,
|
|
16033
|
+
mouseBiteHoleSpacing
|
|
16034
|
+
} = options;
|
|
16035
|
+
const tabCutouts = [];
|
|
16036
|
+
const mouseBiteHoles = [];
|
|
16037
|
+
if (outline.length < 2) {
|
|
16038
|
+
return { tabCutouts, mouseBiteHoles };
|
|
16039
|
+
}
|
|
16040
|
+
const outlinePolygon = new Flatten.Polygon(
|
|
16041
|
+
outline.map((p) => Flatten.point(p.x, p.y))
|
|
16042
|
+
);
|
|
16043
|
+
const otherBoardGeometries = otherBoards.map(
|
|
16044
|
+
(b) => b.outline ? new Flatten.Polygon(b.outline.map((p) => Flatten.point(p.x, p.y))) : b.width && b.height ? new Flatten.Box(
|
|
16045
|
+
b.center.x - b.width / 2,
|
|
16046
|
+
b.center.y - b.height / 2,
|
|
16047
|
+
b.center.x + b.width / 2,
|
|
16048
|
+
b.center.y + b.height / 2
|
|
16049
|
+
) : null
|
|
16050
|
+
);
|
|
16051
|
+
for (let i = 0; i < outline.length; i++) {
|
|
16052
|
+
const p1 = outline[i];
|
|
16053
|
+
const p2 = outline[(i + 1) % outline.length];
|
|
16054
|
+
const segmentVector = Flatten.vector(p2.x - p1.x, p2.y - p1.y);
|
|
16055
|
+
const segmentLength = segmentVector.length;
|
|
16056
|
+
const physicalTabLength = boardGap;
|
|
16057
|
+
const cutoutLength = tabLength;
|
|
16058
|
+
if (segmentLength < physicalTabLength) continue;
|
|
16059
|
+
const segmentDirVec = segmentVector.normalize();
|
|
16060
|
+
const isHorizontal = Math.abs(segmentVector.y) < 1e-9;
|
|
16061
|
+
const isVertical = Math.abs(segmentVector.x) < 1e-9;
|
|
16062
|
+
const isAxisAligned = isHorizontal || isVertical;
|
|
16063
|
+
let normalVec = segmentDirVec.rotate(Math.PI / 2);
|
|
16064
|
+
const midPoint = Flatten.point(p1.x, p1.y).translate(
|
|
16065
|
+
segmentDirVec.multiply(segmentLength / 2)
|
|
16066
|
+
);
|
|
16067
|
+
const testPointInward = midPoint.translate(normalVec.multiply(0.01));
|
|
16068
|
+
if (outlinePolygon.contains(testPointInward)) {
|
|
16069
|
+
normalVec = normalVec.multiply(-1);
|
|
16070
|
+
}
|
|
16071
|
+
const testPointOutward = midPoint.translate(
|
|
16072
|
+
normalVec.multiply((tabWidth + physicalTabLength) / 2)
|
|
16073
|
+
);
|
|
16074
|
+
let isExterior = true;
|
|
16075
|
+
for (const geom of otherBoardGeometries) {
|
|
16076
|
+
if (geom?.contains(testPointOutward)) {
|
|
16077
|
+
isExterior = false;
|
|
16078
|
+
break;
|
|
16079
|
+
}
|
|
16080
|
+
}
|
|
16081
|
+
if (!isExterior) continue;
|
|
16082
|
+
const numTabs = Math.max(
|
|
16083
|
+
1,
|
|
16084
|
+
Math.floor(segmentLength / (physicalTabLength + cutoutLength))
|
|
16085
|
+
);
|
|
16086
|
+
const totalContentLength = numTabs * physicalTabLength;
|
|
16087
|
+
const totalGapLength = segmentLength - totalContentLength;
|
|
16088
|
+
const gapSize = totalGapLength / (numTabs + 1);
|
|
16089
|
+
if (gapSize < 0) continue;
|
|
16090
|
+
const tabsOnSegment = [];
|
|
16091
|
+
for (let j = 0; j < numTabs; j++) {
|
|
16092
|
+
const tabStartDist = gapSize * (j + 1) + physicalTabLength * j;
|
|
16093
|
+
tabsOnSegment.push({
|
|
16094
|
+
start: tabStartDist,
|
|
16095
|
+
end: tabStartDist + physicalTabLength
|
|
16096
|
+
});
|
|
16097
|
+
}
|
|
16098
|
+
const extrusion = normalVec.multiply(tabWidth);
|
|
16099
|
+
for (let j = 0; j <= numTabs; j++) {
|
|
16100
|
+
const gapStartDist = j === 0 ? 0 : tabsOnSegment[j - 1].end;
|
|
16101
|
+
const gapEndDist = j === numTabs ? segmentLength : tabsOnSegment[j].start;
|
|
16102
|
+
const gapLength = gapEndDist - gapStartDist;
|
|
16103
|
+
if (gapLength < 1e-6) continue;
|
|
16104
|
+
if (isAxisAligned) {
|
|
16105
|
+
const width = isHorizontal ? gapLength : tabWidth;
|
|
16106
|
+
const height = isHorizontal ? tabWidth : gapLength;
|
|
16107
|
+
const gapCenterAlongSegment = Flatten.point(p1.x, p1.y).translate(
|
|
16108
|
+
segmentDirVec.multiply(gapStartDist + gapLength / 2)
|
|
16109
|
+
);
|
|
16110
|
+
const center = gapCenterAlongSegment.translate(extrusion.multiply(0.5));
|
|
16111
|
+
tabCutouts.push({
|
|
16112
|
+
type: "pcb_cutout",
|
|
16113
|
+
shape: "rect",
|
|
16114
|
+
center,
|
|
16115
|
+
width,
|
|
16116
|
+
height,
|
|
16117
|
+
corner_radius: Math.min(width, height) / 2
|
|
16118
|
+
});
|
|
16119
|
+
} else {
|
|
16120
|
+
const width = gapLength;
|
|
16121
|
+
const height = tabWidth;
|
|
16122
|
+
const gapCenterAlongSegment = Flatten.point(p1.x, p1.y).translate(
|
|
16123
|
+
segmentDirVec.multiply(gapStartDist + gapLength / 2)
|
|
16124
|
+
);
|
|
16125
|
+
const center = gapCenterAlongSegment.translate(extrusion.multiply(0.5));
|
|
16126
|
+
const rotationDeg = segmentDirVec.slope * 180 / Math.PI;
|
|
16127
|
+
tabCutouts.push({
|
|
16128
|
+
type: "pcb_cutout",
|
|
16129
|
+
shape: "rect",
|
|
16130
|
+
center,
|
|
16131
|
+
width,
|
|
16132
|
+
height,
|
|
16133
|
+
rotation: rotationDeg,
|
|
16134
|
+
corner_radius: Math.min(width, height) / 2
|
|
16135
|
+
});
|
|
16136
|
+
}
|
|
16137
|
+
}
|
|
16138
|
+
if (mouseBites) {
|
|
16139
|
+
const holeSpacing = mouseBiteHoleDiameter + mouseBiteHoleSpacing;
|
|
16140
|
+
for (const tab of tabsOnSegment) {
|
|
16141
|
+
const tabLength2 = tab.end - tab.start;
|
|
16142
|
+
if (tabLength2 < holeSpacing) continue;
|
|
16143
|
+
const numBitesInTab = Math.floor(tabLength2 / holeSpacing);
|
|
16144
|
+
if (numBitesInTab <= 0) continue;
|
|
16145
|
+
const biteStartOffset = tab.start + (tabLength2 - (numBitesInTab - 1) * holeSpacing) / 2;
|
|
16146
|
+
for (let k = 0; k < numBitesInTab; k++) {
|
|
16147
|
+
const biteDist = biteStartOffset + k * holeSpacing;
|
|
16148
|
+
const pos = Flatten.point(p1.x, p1.y).translate(
|
|
16149
|
+
segmentDirVec.multiply(biteDist)
|
|
16150
|
+
);
|
|
16151
|
+
mouseBiteHoles.push({
|
|
16152
|
+
x: pos.x,
|
|
16153
|
+
y: pos.y
|
|
16154
|
+
});
|
|
16155
|
+
}
|
|
16156
|
+
}
|
|
16157
|
+
}
|
|
16158
|
+
}
|
|
16159
|
+
return { tabCutouts, mouseBiteHoles };
|
|
16160
|
+
};
|
|
16022
16161
|
function generatePanelTabsAndMouseBites(boards, options) {
|
|
16023
|
-
const
|
|
16162
|
+
const finalTabCutouts = [];
|
|
16024
16163
|
const allMouseBites = [];
|
|
16025
16164
|
for (let boardIndex = 0; boardIndex < boards.length; boardIndex++) {
|
|
16026
16165
|
const board = boards[boardIndex];
|
|
16027
16166
|
const otherBoards = boards.filter((_, i) => i !== boardIndex);
|
|
16028
|
-
|
|
16029
|
-
const
|
|
16030
|
-
|
|
16031
|
-
|
|
16167
|
+
if (board.outline && board.outline.length > 0) {
|
|
16168
|
+
const mouseBiteDiameter2 = options.tabWidth * 0.45;
|
|
16169
|
+
const mouseBiteSpacing = mouseBiteDiameter2 * 0.1;
|
|
16170
|
+
const generated = generatePanelTabsAndMouseBitesForOutlines(
|
|
16171
|
+
board.outline,
|
|
16032
16172
|
otherBoards,
|
|
16033
|
-
|
|
16034
|
-
|
|
16035
|
-
|
|
16036
|
-
|
|
16037
|
-
|
|
16173
|
+
{
|
|
16174
|
+
...options,
|
|
16175
|
+
mouseBiteHoleDiameter: mouseBiteDiameter2,
|
|
16176
|
+
mouseBiteHoleSpacing: mouseBiteSpacing
|
|
16177
|
+
}
|
|
16178
|
+
);
|
|
16179
|
+
finalTabCutouts.push(...generated.tabCutouts);
|
|
16180
|
+
allMouseBites.push(...generated.mouseBiteHoles);
|
|
16181
|
+
} else {
|
|
16182
|
+
for (const edge of ["top", "bottom", "left", "right"]) {
|
|
16183
|
+
const edgeTabs = generateTabsForEdge({
|
|
16038
16184
|
board,
|
|
16039
16185
|
edge,
|
|
16040
|
-
|
|
16041
|
-
allBoards: otherBoards,
|
|
16186
|
+
otherBoards,
|
|
16042
16187
|
options
|
|
16043
16188
|
});
|
|
16044
|
-
|
|
16189
|
+
for (const tab of edgeTabs) {
|
|
16190
|
+
const tabWidthDimension = Math.min(tab.width, tab.height);
|
|
16191
|
+
finalTabCutouts.push({
|
|
16192
|
+
type: "pcb_cutout",
|
|
16193
|
+
shape: "rect",
|
|
16194
|
+
center: tab.center,
|
|
16195
|
+
width: tab.width,
|
|
16196
|
+
height: tab.height,
|
|
16197
|
+
corner_radius: tabWidthDimension / 2
|
|
16198
|
+
});
|
|
16199
|
+
}
|
|
16200
|
+
if (options.mouseBites) {
|
|
16201
|
+
const edgeMouseBites = generateMouseBitesForEdge({
|
|
16202
|
+
board,
|
|
16203
|
+
edge,
|
|
16204
|
+
edgeTabs,
|
|
16205
|
+
allBoards: otherBoards,
|
|
16206
|
+
options
|
|
16207
|
+
});
|
|
16208
|
+
allMouseBites.push(...edgeMouseBites);
|
|
16209
|
+
}
|
|
16045
16210
|
}
|
|
16046
16211
|
}
|
|
16047
16212
|
}
|
|
16048
|
-
const tabCutouts =
|
|
16049
|
-
|
|
16050
|
-
|
|
16051
|
-
|
|
16052
|
-
pcb_cutout_id: `panel_tab_${index}`,
|
|
16053
|
-
shape: "rect",
|
|
16054
|
-
center: tab.center,
|
|
16055
|
-
width: tab.width,
|
|
16056
|
-
height: tab.height,
|
|
16057
|
-
corner_radius: tabWidthDimension / 2
|
|
16058
|
-
};
|
|
16059
|
-
});
|
|
16213
|
+
const tabCutouts = finalTabCutouts.map((tab, index) => ({
|
|
16214
|
+
...tab,
|
|
16215
|
+
pcb_cutout_id: `panel_tab_${index}`
|
|
16216
|
+
}));
|
|
16060
16217
|
const mouseBiteDiameter = options.tabWidth * 0.45;
|
|
16061
16218
|
const mouseBiteHoles = allMouseBites.map((bite, index) => ({
|
|
16062
16219
|
type: "pcb_hole",
|
|
@@ -17211,8 +17368,8 @@ var PcbNotePath = class extends PrimitiveComponent2 {
|
|
|
17211
17368
|
const subcircuit = this.getSubcircuit();
|
|
17212
17369
|
const group = this.getGroup();
|
|
17213
17370
|
const pcb_component_id = this.parent?.pcb_component_id ?? this.getPrimitiveContainer()?.pcb_component_id ?? void 0;
|
|
17214
|
-
const transformedRoute = props.route.map((
|
|
17215
|
-
const { x, y, ...rest } =
|
|
17371
|
+
const transformedRoute = props.route.map((point2) => {
|
|
17372
|
+
const { x, y, ...rest } = point2;
|
|
17216
17373
|
const numericX = typeof x === "string" ? parseFloat(x) : x;
|
|
17217
17374
|
const numericY = typeof y === "string" ? parseFloat(y) : y;
|
|
17218
17375
|
const transformed = applyToPoint15(transform, { x: numericX, y: numericY });
|
|
@@ -17232,10 +17389,10 @@ var PcbNotePath = class extends PrimitiveComponent2 {
|
|
|
17232
17389
|
const { _parsedProps: props } = this;
|
|
17233
17390
|
if (props.route.length === 0) return { width: 0, height: 0 };
|
|
17234
17391
|
const xs = props.route.map(
|
|
17235
|
-
(
|
|
17392
|
+
(point2) => typeof point2.x === "string" ? parseFloat(point2.x) : point2.x
|
|
17236
17393
|
);
|
|
17237
17394
|
const ys = props.route.map(
|
|
17238
|
-
(
|
|
17395
|
+
(point2) => typeof point2.y === "string" ? parseFloat(point2.y) : point2.y
|
|
17239
17396
|
);
|
|
17240
17397
|
const minX = Math.min(...xs);
|
|
17241
17398
|
const maxX = Math.max(...xs);
|
|
@@ -19261,7 +19418,7 @@ import { identity as identity5 } from "transformation-matrix";
|
|
|
19261
19418
|
var package_default = {
|
|
19262
19419
|
name: "@tscircuit/core",
|
|
19263
19420
|
type: "module",
|
|
19264
|
-
version: "0.0.
|
|
19421
|
+
version: "0.0.906",
|
|
19265
19422
|
types: "dist/index.d.ts",
|
|
19266
19423
|
main: "dist/index.js",
|
|
19267
19424
|
module: "dist/index.js",
|
|
@@ -19324,7 +19481,7 @@ var package_default = {
|
|
|
19324
19481
|
"circuit-json-to-connectivity-map": "^0.0.22",
|
|
19325
19482
|
"circuit-json-to-gltf": "^0.0.31",
|
|
19326
19483
|
"circuit-json-to-simple-3d": "^0.0.9",
|
|
19327
|
-
"circuit-json-to-spice": "^0.0.
|
|
19484
|
+
"circuit-json-to-spice": "^0.0.30",
|
|
19328
19485
|
"circuit-to-svg": "^0.0.284",
|
|
19329
19486
|
concurrently: "^9.1.2",
|
|
19330
19487
|
"connectivity-map": "^1.0.0",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscircuit/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.907",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.js",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"circuit-json-to-connectivity-map": "^0.0.22",
|
|
65
65
|
"circuit-json-to-gltf": "^0.0.31",
|
|
66
66
|
"circuit-json-to-simple-3d": "^0.0.9",
|
|
67
|
-
"circuit-json-to-spice": "^0.0.
|
|
67
|
+
"circuit-json-to-spice": "^0.0.30",
|
|
68
68
|
"circuit-to-svg": "^0.0.284",
|
|
69
69
|
"concurrently": "^9.1.2",
|
|
70
70
|
"connectivity-map": "^1.0.0",
|