jscad-electronics 0.0.154 → 0.0.156
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/README.md +18 -0
- package/dist/index.d.ts +2 -4
- package/dist/index.js +1137 -1129
- package/dist/index.js.map +1 -1
- package/dist/vanilla.js +556 -7
- package/dist/vanilla.js.map +1 -1
- package/package.json +3 -2
package/dist/vanilla.js
CHANGED
|
@@ -181,6 +181,7 @@ var ExtrudedPads = ({
|
|
|
181
181
|
|
|
182
182
|
// lib/Footprinter3d.tsx
|
|
183
183
|
import { fp as fp5 } from "@tscircuit/footprinter";
|
|
184
|
+
import { mp } from "@tscircuit/modelprinter";
|
|
184
185
|
|
|
185
186
|
// lib/ChipBody.tsx
|
|
186
187
|
var ChipBody = ({
|
|
@@ -854,7 +855,6 @@ var PinHeader = ({
|
|
|
854
855
|
bodyLength: bodyLength10 = 2.54,
|
|
855
856
|
bodyWidth = 2.54,
|
|
856
857
|
flipZ,
|
|
857
|
-
faceup,
|
|
858
858
|
smd,
|
|
859
859
|
rightangle
|
|
860
860
|
}) => {
|
|
@@ -867,7 +867,7 @@ var PinHeader = ({
|
|
|
867
867
|
center: [x, y, flipZ(bodyHeight / 2)]
|
|
868
868
|
}
|
|
869
869
|
) }),
|
|
870
|
-
|
|
870
|
+
/* @__PURE__ */ jsx(Colorize, { color: PIN_METAL_COLOR, children: smd ? /* @__PURE__ */ jsx(
|
|
871
871
|
SmdChipLead,
|
|
872
872
|
{
|
|
873
873
|
rotation: -Math.PI / 2,
|
|
@@ -935,7 +935,6 @@ var PinRow = ({
|
|
|
935
935
|
pitch = 2.54,
|
|
936
936
|
longSidePinLength = 6,
|
|
937
937
|
invert,
|
|
938
|
-
faceup,
|
|
939
938
|
rows = 1,
|
|
940
939
|
smd,
|
|
941
940
|
rightangle
|
|
@@ -946,8 +945,9 @@ var PinRow = ({
|
|
|
946
945
|
const rowSpacing = 2.54;
|
|
947
946
|
const shortSidePinLength = 3;
|
|
948
947
|
const xoff = -((pinsPerRow - 1) / 2) * pitch;
|
|
949
|
-
const
|
|
950
|
-
const
|
|
948
|
+
const throughHole = !smd && !rightangle;
|
|
949
|
+
const flipped = throughHole ? !invert : Boolean(invert);
|
|
950
|
+
const flipZ = (z) => flipped ? -z + bodyHeight : z;
|
|
951
951
|
return /* @__PURE__ */ jsx(Fragment2, { children: Array.from({ length: numberOfPins }, (_, i) => {
|
|
952
952
|
const row = Math.floor(i / pinsPerRow);
|
|
953
953
|
const col = i % pinsPerRow;
|
|
@@ -963,7 +963,6 @@ var PinRow = ({
|
|
|
963
963
|
longSidePinLength,
|
|
964
964
|
bodyHeight,
|
|
965
965
|
flipZ,
|
|
966
|
-
faceup,
|
|
967
966
|
smd,
|
|
968
967
|
rightangle
|
|
969
968
|
},
|
|
@@ -6459,8 +6458,559 @@ var BGA = ({
|
|
|
6459
6458
|
] });
|
|
6460
6459
|
};
|
|
6461
6460
|
|
|
6461
|
+
// lib/FlexScreen.tsx
|
|
6462
|
+
var DEFAULT_ASPECT_RATIO = 16 / 9;
|
|
6463
|
+
var DEFAULT_DIAGONAL = 40;
|
|
6464
|
+
var EPSILON = 1e-6;
|
|
6465
|
+
var assertPositive = (name, value) => {
|
|
6466
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
6467
|
+
throw new Error(`${name} must be a finite number greater than zero`);
|
|
6468
|
+
}
|
|
6469
|
+
};
|
|
6470
|
+
var resolveAspectRatio = (value) => {
|
|
6471
|
+
if (value === void 0) return DEFAULT_ASPECT_RATIO;
|
|
6472
|
+
if (typeof value === "number") {
|
|
6473
|
+
assertPositive("aspectRatio", value);
|
|
6474
|
+
return value;
|
|
6475
|
+
}
|
|
6476
|
+
if (typeof value !== "string") {
|
|
6477
|
+
const [ratioWidth2, ratioHeight2] = value;
|
|
6478
|
+
assertPositive("aspectRatio width", ratioWidth2);
|
|
6479
|
+
assertPositive("aspectRatio height", ratioHeight2);
|
|
6480
|
+
return ratioWidth2 / ratioHeight2;
|
|
6481
|
+
}
|
|
6482
|
+
const parts = value.split(":");
|
|
6483
|
+
if (parts.length !== 2) {
|
|
6484
|
+
throw new Error('aspectRatio must look like "16:9"');
|
|
6485
|
+
}
|
|
6486
|
+
const ratioWidth = Number(parts[0]);
|
|
6487
|
+
const ratioHeight = Number(parts[1]);
|
|
6488
|
+
assertPositive("aspectRatio width", ratioWidth);
|
|
6489
|
+
assertPositive("aspectRatio height", ratioHeight);
|
|
6490
|
+
return ratioWidth / ratioHeight;
|
|
6491
|
+
};
|
|
6492
|
+
var resolveFlexScreenSize = ({
|
|
6493
|
+
width: width10,
|
|
6494
|
+
height: height10,
|
|
6495
|
+
diagonal,
|
|
6496
|
+
aspectRatio,
|
|
6497
|
+
ratio,
|
|
6498
|
+
defaultDiagonal = DEFAULT_DIAGONAL
|
|
6499
|
+
}) => {
|
|
6500
|
+
const resolvedRatio = resolveAspectRatio(aspectRatio ?? ratio);
|
|
6501
|
+
if (width10 !== void 0) assertPositive("width", width10);
|
|
6502
|
+
if (height10 !== void 0) assertPositive("height", height10);
|
|
6503
|
+
if (diagonal !== void 0) assertPositive("diagonal", diagonal);
|
|
6504
|
+
assertPositive("defaultDiagonal", defaultDiagonal);
|
|
6505
|
+
let resolvedWidth;
|
|
6506
|
+
let resolvedHeight;
|
|
6507
|
+
if (width10 !== void 0 && height10 !== void 0) {
|
|
6508
|
+
resolvedWidth = width10;
|
|
6509
|
+
resolvedHeight = height10;
|
|
6510
|
+
} else if (diagonal !== void 0 && width10 !== void 0) {
|
|
6511
|
+
if (width10 >= diagonal) {
|
|
6512
|
+
throw new Error("width must be smaller than diagonal");
|
|
6513
|
+
}
|
|
6514
|
+
resolvedWidth = width10;
|
|
6515
|
+
resolvedHeight = Math.sqrt(diagonal ** 2 - width10 ** 2);
|
|
6516
|
+
} else if (diagonal !== void 0 && height10 !== void 0) {
|
|
6517
|
+
if (height10 >= diagonal) {
|
|
6518
|
+
throw new Error("height must be smaller than diagonal");
|
|
6519
|
+
}
|
|
6520
|
+
resolvedWidth = Math.sqrt(diagonal ** 2 - height10 ** 2);
|
|
6521
|
+
resolvedHeight = height10;
|
|
6522
|
+
} else if (width10 !== void 0) {
|
|
6523
|
+
resolvedWidth = width10;
|
|
6524
|
+
resolvedHeight = width10 / resolvedRatio;
|
|
6525
|
+
} else if (height10 !== void 0) {
|
|
6526
|
+
resolvedWidth = height10 * resolvedRatio;
|
|
6527
|
+
resolvedHeight = height10;
|
|
6528
|
+
} else {
|
|
6529
|
+
const resolvedDiagonal = diagonal ?? defaultDiagonal;
|
|
6530
|
+
resolvedHeight = resolvedDiagonal / Math.sqrt(resolvedRatio ** 2 + 1);
|
|
6531
|
+
resolvedWidth = resolvedHeight * resolvedRatio;
|
|
6532
|
+
}
|
|
6533
|
+
return {
|
|
6534
|
+
width: resolvedWidth,
|
|
6535
|
+
height: resolvedHeight,
|
|
6536
|
+
diagonal: Math.hypot(resolvedWidth, resolvedHeight),
|
|
6537
|
+
aspectRatio: resolvedWidth / resolvedHeight
|
|
6538
|
+
};
|
|
6539
|
+
};
|
|
6540
|
+
var resolveOrientation = (props) => {
|
|
6541
|
+
const shortcuts = [
|
|
6542
|
+
["sitsFlat", props.sitsFlat],
|
|
6543
|
+
["sitsFlatBelowBoard", props.sitsFlatBelowBoard],
|
|
6544
|
+
["foldedToFaceAboveBoard", props.foldedToFaceAboveBoard],
|
|
6545
|
+
["foldedToFaceBelowBoard", props.foldedToFaceBelowBoard],
|
|
6546
|
+
["foldedToFaceAboveBoard", props.foldsAboveBoard],
|
|
6547
|
+
["foldedToFaceBelowBoard", props.foldsBelowBoard],
|
|
6548
|
+
["foldedToRightAngleAboveBoard", props.foldedToRightAngleAboveBoard],
|
|
6549
|
+
["foldedToRightAngleBelowBoard", props.foldedToRightAngleBelowBoard]
|
|
6550
|
+
].filter((entry) => entry[1]);
|
|
6551
|
+
if (shortcuts.length > 1) {
|
|
6552
|
+
throw new Error(
|
|
6553
|
+
"Only one FlexScreen boolean orientation shortcut can be true"
|
|
6554
|
+
);
|
|
6555
|
+
}
|
|
6556
|
+
return shortcuts[0]?.[0] ?? props.orientation ?? "sitsFlat";
|
|
6557
|
+
};
|
|
6558
|
+
var distance = (a, b) => Math.hypot(b[0] - a[0], b[1] - a[1], b[2] - a[2]);
|
|
6559
|
+
var interpolate = (a, b, progress) => [
|
|
6560
|
+
a[0] + (b[0] - a[0]) * progress,
|
|
6561
|
+
a[1] + (b[1] - a[1]) * progress,
|
|
6562
|
+
a[2] + (b[2] - a[2]) * progress
|
|
6563
|
+
];
|
|
6564
|
+
var getPathDistances = (points) => {
|
|
6565
|
+
const distances = [0];
|
|
6566
|
+
for (let index = 1; index < points.length; index += 1) {
|
|
6567
|
+
distances.push(
|
|
6568
|
+
distances[index - 1] + distance(points[index - 1], points[index])
|
|
6569
|
+
);
|
|
6570
|
+
}
|
|
6571
|
+
return distances;
|
|
6572
|
+
};
|
|
6573
|
+
var pointAtDistance = (points, distances, targetDistance) => {
|
|
6574
|
+
if (targetDistance <= 0) return points[0];
|
|
6575
|
+
const totalLength = distances.at(-1);
|
|
6576
|
+
if (targetDistance >= totalLength) return points.at(-1);
|
|
6577
|
+
for (let index = 1; index < points.length; index += 1) {
|
|
6578
|
+
if (distances[index] >= targetDistance) {
|
|
6579
|
+
const segmentStart = distances[index - 1];
|
|
6580
|
+
const segmentLength = distances[index] - segmentStart;
|
|
6581
|
+
return interpolate(
|
|
6582
|
+
points[index - 1],
|
|
6583
|
+
points[index],
|
|
6584
|
+
(targetDistance - segmentStart) / segmentLength
|
|
6585
|
+
);
|
|
6586
|
+
}
|
|
6587
|
+
}
|
|
6588
|
+
return points.at(-1);
|
|
6589
|
+
};
|
|
6590
|
+
var slicePath = (points, startDistance, endDistance) => {
|
|
6591
|
+
const distances = getPathDistances(points);
|
|
6592
|
+
const totalLength = distances.at(-1);
|
|
6593
|
+
const safeStart = Math.max(0, Math.min(startDistance, totalLength));
|
|
6594
|
+
const safeEnd = Math.max(safeStart, Math.min(endDistance, totalLength));
|
|
6595
|
+
const result = [pointAtDistance(points, distances, safeStart)];
|
|
6596
|
+
for (let index = 1; index < points.length - 1; index += 1) {
|
|
6597
|
+
if (distances[index] > safeStart && distances[index] < safeEnd) {
|
|
6598
|
+
result.push(points[index]);
|
|
6599
|
+
}
|
|
6600
|
+
}
|
|
6601
|
+
result.push(pointAtDistance(points, distances, safeEnd));
|
|
6602
|
+
return result;
|
|
6603
|
+
};
|
|
6604
|
+
var createFlatPath = (start, flexCableLength) => [
|
|
6605
|
+
start,
|
|
6606
|
+
[start[0], start[1] + flexCableLength, start[2]]
|
|
6607
|
+
];
|
|
6608
|
+
var createFoldedPath = ({
|
|
6609
|
+
start,
|
|
6610
|
+
endZ,
|
|
6611
|
+
flexCableLength,
|
|
6612
|
+
foldDistanceFromConnector,
|
|
6613
|
+
foldOutset,
|
|
6614
|
+
foldSegments
|
|
6615
|
+
}) => {
|
|
6616
|
+
const points = [start];
|
|
6617
|
+
const foldStart = [
|
|
6618
|
+
start[0],
|
|
6619
|
+
start[1] + foldDistanceFromConnector,
|
|
6620
|
+
start[2]
|
|
6621
|
+
];
|
|
6622
|
+
if (foldDistanceFromConnector > EPSILON) points.push(foldStart);
|
|
6623
|
+
for (let index = 1; index <= foldSegments; index += 1) {
|
|
6624
|
+
const angle = Math.PI * index / foldSegments;
|
|
6625
|
+
points.push([
|
|
6626
|
+
start[0],
|
|
6627
|
+
foldStart[1] + foldOutset * Math.sin(angle),
|
|
6628
|
+
start[2] + (endZ - start[2]) * (1 - Math.cos(angle)) / 2
|
|
6629
|
+
]);
|
|
6630
|
+
}
|
|
6631
|
+
const minimumLength = getPathDistances(points).at(-1);
|
|
6632
|
+
if (minimumLength > flexCableLength + EPSILON) {
|
|
6633
|
+
throw new Error(
|
|
6634
|
+
`flexCableLength must be at least ${minimumLength.toFixed(2)} for this 180-degree fold`
|
|
6635
|
+
);
|
|
6636
|
+
}
|
|
6637
|
+
const tailLength = Math.max(0, flexCableLength - minimumLength);
|
|
6638
|
+
if (tailLength > EPSILON) {
|
|
6639
|
+
const foldEnd = points.at(-1);
|
|
6640
|
+
points.push([foldEnd[0], foldEnd[1] - tailLength, foldEnd[2]]);
|
|
6641
|
+
}
|
|
6642
|
+
return points;
|
|
6643
|
+
};
|
|
6644
|
+
var createRightAnglePath = ({
|
|
6645
|
+
start,
|
|
6646
|
+
flexCableLength,
|
|
6647
|
+
bendRadius,
|
|
6648
|
+
bendSegments,
|
|
6649
|
+
verticalLead,
|
|
6650
|
+
direction
|
|
6651
|
+
}) => {
|
|
6652
|
+
const bendLengthPerRadius = 2 * bendSegments * Math.sin(Math.PI / (4 * bendSegments));
|
|
6653
|
+
const resolvedRadius = Math.min(
|
|
6654
|
+
bendRadius,
|
|
6655
|
+
flexCableLength / bendLengthPerRadius
|
|
6656
|
+
);
|
|
6657
|
+
const bendLength = resolvedRadius * bendLengthPerRadius;
|
|
6658
|
+
const remainingLength = Math.max(0, flexCableLength - bendLength);
|
|
6659
|
+
const resolvedVerticalLead = Math.min(verticalLead, remainingLength * 0.45);
|
|
6660
|
+
const horizontalLength = remainingLength - resolvedVerticalLead;
|
|
6661
|
+
const points = [start];
|
|
6662
|
+
if (horizontalLength > EPSILON) {
|
|
6663
|
+
points.push([start[0], start[1] + horizontalLength, start[2]]);
|
|
6664
|
+
}
|
|
6665
|
+
for (let index = 1; index <= bendSegments; index += 1) {
|
|
6666
|
+
const angle = Math.PI / 2 * index / bendSegments;
|
|
6667
|
+
points.push([
|
|
6668
|
+
start[0],
|
|
6669
|
+
start[1] + horizontalLength + resolvedRadius * Math.sin(angle),
|
|
6670
|
+
start[2] + direction * resolvedRadius * (1 - Math.cos(angle))
|
|
6671
|
+
]);
|
|
6672
|
+
}
|
|
6673
|
+
if (resolvedVerticalLead > EPSILON) {
|
|
6674
|
+
const arcEnd = points.at(-1);
|
|
6675
|
+
points.push([
|
|
6676
|
+
arcEnd[0],
|
|
6677
|
+
arcEnd[1],
|
|
6678
|
+
arcEnd[2] + direction * resolvedVerticalLead
|
|
6679
|
+
]);
|
|
6680
|
+
}
|
|
6681
|
+
return points;
|
|
6682
|
+
};
|
|
6683
|
+
var CableStrip = ({
|
|
6684
|
+
points,
|
|
6685
|
+
width: width10,
|
|
6686
|
+
thickness,
|
|
6687
|
+
color,
|
|
6688
|
+
acrossOffset = 0,
|
|
6689
|
+
normalOffset = 0,
|
|
6690
|
+
overlap = 0.03
|
|
6691
|
+
}) => /* @__PURE__ */ jsx(Colorize, { color, children: points.slice(1).map((point, index) => {
|
|
6692
|
+
const previous = points[index];
|
|
6693
|
+
const dx = point[0] - previous[0];
|
|
6694
|
+
const dy = point[1] - previous[1];
|
|
6695
|
+
const dz = point[2] - previous[2];
|
|
6696
|
+
const segmentLength = Math.hypot(dx, dy, dz);
|
|
6697
|
+
if (segmentLength < EPSILON) return null;
|
|
6698
|
+
const pitch = Math.asin(dz / segmentLength);
|
|
6699
|
+
const yaw = Math.atan2(-dx, dy);
|
|
6700
|
+
const midpoint = [
|
|
6701
|
+
(previous[0] + point[0]) / 2,
|
|
6702
|
+
(previous[1] + point[1]) / 2,
|
|
6703
|
+
(previous[2] + point[2]) / 2
|
|
6704
|
+
];
|
|
6705
|
+
const roundRadius = Math.max(
|
|
6706
|
+
1e-3,
|
|
6707
|
+
Math.min(width10, thickness, segmentLength) / 2 - 1e-3
|
|
6708
|
+
);
|
|
6709
|
+
return /* @__PURE__ */ jsx(Translate, { offset: midpoint, children: /* @__PURE__ */ jsx(Rotate, { rotation: [pitch, 0, yaw], children: /* @__PURE__ */ jsx(
|
|
6710
|
+
RoundedCuboid,
|
|
6711
|
+
{
|
|
6712
|
+
size: [width10, segmentLength + overlap, thickness],
|
|
6713
|
+
center: [acrossOffset, 0, normalOffset],
|
|
6714
|
+
roundRadius
|
|
6715
|
+
}
|
|
6716
|
+
) }) }, `${index}:${midpoint.join(":")}`);
|
|
6717
|
+
}) });
|
|
6718
|
+
var FlexScreen = (props) => {
|
|
6719
|
+
const {
|
|
6720
|
+
width: width10,
|
|
6721
|
+
height: height10,
|
|
6722
|
+
diagonal,
|
|
6723
|
+
aspectRatio,
|
|
6724
|
+
ratio,
|
|
6725
|
+
defaultDiagonal,
|
|
6726
|
+
screenThickness = 1.2,
|
|
6727
|
+
bezelInset = 2,
|
|
6728
|
+
bezelDepth = 0.65,
|
|
6729
|
+
activeAreaWidth,
|
|
6730
|
+
activeAreaHeight,
|
|
6731
|
+
screenColor = "#071b24",
|
|
6732
|
+
bezelColor = "#15181d",
|
|
6733
|
+
showScreen = true,
|
|
6734
|
+
flexCableLength = 28,
|
|
6735
|
+
flexCableThickness = 0.18,
|
|
6736
|
+
flexCableColor = "#d79528",
|
|
6737
|
+
conductorCount = 8,
|
|
6738
|
+
conductorPitch,
|
|
6739
|
+
conductorWidth,
|
|
6740
|
+
conductorThickness = 0.035,
|
|
6741
|
+
conductorColor = "#8c4a18",
|
|
6742
|
+
cableEdgeMargin = 0.6,
|
|
6743
|
+
exposedContactLength = 2.4,
|
|
6744
|
+
showConductors = true,
|
|
6745
|
+
showFlexCable = true,
|
|
6746
|
+
showStiffeners = true,
|
|
6747
|
+
stiffenerLength = 3,
|
|
6748
|
+
stiffenerThickness = 0.16,
|
|
6749
|
+
stiffenerColor = "#416bb3",
|
|
6750
|
+
bendRadius = 3,
|
|
6751
|
+
bendSegments = 10,
|
|
6752
|
+
rightAngleVerticalLead = 3,
|
|
6753
|
+
distanceAboveBoard = 7,
|
|
6754
|
+
distanceBelowBoard = 7,
|
|
6755
|
+
foldDistanceFromConnector = 7,
|
|
6756
|
+
foldOutset = 4,
|
|
6757
|
+
foldSegments = 18,
|
|
6758
|
+
screenGap = 0.08,
|
|
6759
|
+
boardTopZ = 0,
|
|
6760
|
+
boardThickness = 1.6,
|
|
6761
|
+
boardClearance = 0.15,
|
|
6762
|
+
cableStartX = 0,
|
|
6763
|
+
cableStartY = 0,
|
|
6764
|
+
cableStartZ,
|
|
6765
|
+
cableLateralOffset = 0,
|
|
6766
|
+
screenOffset,
|
|
6767
|
+
screenRotation,
|
|
6768
|
+
rotation = [0, 0, 0],
|
|
6769
|
+
offset
|
|
6770
|
+
} = props;
|
|
6771
|
+
const size = resolveFlexScreenSize({
|
|
6772
|
+
width: width10,
|
|
6773
|
+
height: height10,
|
|
6774
|
+
diagonal,
|
|
6775
|
+
aspectRatio,
|
|
6776
|
+
ratio,
|
|
6777
|
+
defaultDiagonal
|
|
6778
|
+
});
|
|
6779
|
+
const orientation = resolveOrientation(props);
|
|
6780
|
+
const belowBoard = orientation === "sitsFlatBelowBoard" || orientation === "foldedToFaceBelowBoard" || orientation === "foldedToRightAngleBelowBoard";
|
|
6781
|
+
const foldedFace = orientation === "foldedToFaceAboveBoard" || orientation === "foldedToFaceBelowBoard";
|
|
6782
|
+
const rightAngle = orientation === "foldedToRightAngleAboveBoard" || orientation === "foldedToRightAngleBelowBoard";
|
|
6783
|
+
assertPositive("screenThickness", screenThickness);
|
|
6784
|
+
assertPositive("flexCableLength", flexCableLength);
|
|
6785
|
+
assertPositive("flexCableThickness", flexCableThickness);
|
|
6786
|
+
assertPositive("conductorThickness", conductorThickness);
|
|
6787
|
+
assertPositive("bendRadius", bendRadius);
|
|
6788
|
+
assertPositive("foldOutset", foldOutset);
|
|
6789
|
+
assertPositive("boardThickness", boardThickness);
|
|
6790
|
+
if (showStiffeners) assertPositive("stiffenerThickness", stiffenerThickness);
|
|
6791
|
+
if (!Number.isInteger(conductorCount) || conductorCount < 1) {
|
|
6792
|
+
throw new Error("conductorCount must be a positive integer");
|
|
6793
|
+
}
|
|
6794
|
+
if (!Number.isInteger(bendSegments) || bendSegments < 2) {
|
|
6795
|
+
throw new Error("bendSegments must be an integer of at least 2");
|
|
6796
|
+
}
|
|
6797
|
+
if (!Number.isInteger(foldSegments) || foldSegments < 4) {
|
|
6798
|
+
throw new Error("foldSegments must be an integer of at least 4");
|
|
6799
|
+
}
|
|
6800
|
+
if (boardClearance < 0 || screenGap < 0 || cableEdgeMargin < 0 || exposedContactLength < 0 || stiffenerLength < 0 || rightAngleVerticalLead < 0 || distanceAboveBoard < 0 || distanceBelowBoard < 0 || foldDistanceFromConnector < 0) {
|
|
6801
|
+
throw new Error(
|
|
6802
|
+
"clearances, margins, contact lengths, and lead lengths cannot be negative"
|
|
6803
|
+
);
|
|
6804
|
+
}
|
|
6805
|
+
const resolvedCableWidth = props.flexCableWidth ?? Math.min(12, Math.max(5, size.width * 0.3));
|
|
6806
|
+
assertPositive("flexCableWidth", resolvedCableWidth);
|
|
6807
|
+
const usableCableWidth = resolvedCableWidth - cableEdgeMargin * 2;
|
|
6808
|
+
if (usableCableWidth <= 0) {
|
|
6809
|
+
throw new Error("cableEdgeMargin leaves no usable flex cable width");
|
|
6810
|
+
}
|
|
6811
|
+
const resolvedConductorPitch = conductorPitch ?? (conductorCount === 1 ? 0 : usableCableWidth / conductorCount);
|
|
6812
|
+
if (conductorCount > 1 && (!Number.isFinite(resolvedConductorPitch) || resolvedConductorPitch <= 0)) {
|
|
6813
|
+
throw new Error("conductorPitch must be greater than zero");
|
|
6814
|
+
}
|
|
6815
|
+
const resolvedConductorWidth = conductorWidth ?? (conductorCount === 1 ? Math.min(usableCableWidth, resolvedCableWidth * 0.45) : resolvedConductorPitch * 0.48);
|
|
6816
|
+
assertPositive("conductorWidth", resolvedConductorWidth);
|
|
6817
|
+
const conductorSpan = (conductorCount - 1) * resolvedConductorPitch + resolvedConductorWidth;
|
|
6818
|
+
if (conductorSpan > usableCableWidth + EPSILON) {
|
|
6819
|
+
throw new Error(
|
|
6820
|
+
"conductorPitch and conductorWidth do not fit inside the flex cable margins"
|
|
6821
|
+
);
|
|
6822
|
+
}
|
|
6823
|
+
const cableStartsBelowBoard = belowBoard && !foldedFace;
|
|
6824
|
+
const defaultCableZ = cableStartsBelowBoard ? boardTopZ - boardThickness - boardClearance - flexCableThickness / 2 : boardTopZ + boardClearance + flexCableThickness / 2;
|
|
6825
|
+
const start = [
|
|
6826
|
+
cableStartX + cableLateralOffset,
|
|
6827
|
+
cableStartY,
|
|
6828
|
+
cableStartZ ?? defaultCableZ
|
|
6829
|
+
];
|
|
6830
|
+
const direction = belowBoard ? -1 : 1;
|
|
6831
|
+
const foldedScreenBackZ = orientation === "foldedToFaceAboveBoard" ? boardTopZ + distanceAboveBoard : boardTopZ - boardThickness - distanceBelowBoard;
|
|
6832
|
+
const foldedCableEndZ = orientation === "foldedToFaceAboveBoard" ? foldedScreenBackZ - screenGap - flexCableThickness / 2 : foldedScreenBackZ + screenGap + flexCableThickness / 2;
|
|
6833
|
+
const path = foldedFace ? createFoldedPath({
|
|
6834
|
+
start,
|
|
6835
|
+
endZ: foldedCableEndZ,
|
|
6836
|
+
flexCableLength,
|
|
6837
|
+
foldDistanceFromConnector,
|
|
6838
|
+
foldOutset,
|
|
6839
|
+
foldSegments
|
|
6840
|
+
}) : rightAngle ? createRightAnglePath({
|
|
6841
|
+
start,
|
|
6842
|
+
flexCableLength,
|
|
6843
|
+
bendRadius,
|
|
6844
|
+
bendSegments,
|
|
6845
|
+
verticalLead: rightAngleVerticalLead,
|
|
6846
|
+
direction
|
|
6847
|
+
}) : createFlatPath(start, flexCableLength);
|
|
6848
|
+
const totalCableLength = getPathDistances(path).at(-1);
|
|
6849
|
+
const contactLength = Math.min(
|
|
6850
|
+
Math.max(0, exposedContactLength),
|
|
6851
|
+
totalCableLength / 2
|
|
6852
|
+
);
|
|
6853
|
+
const resolvedStiffenerLength = Math.min(
|
|
6854
|
+
Math.max(0, stiffenerLength),
|
|
6855
|
+
totalCableLength / 2
|
|
6856
|
+
);
|
|
6857
|
+
const startContacts = slicePath(path, 0, contactLength);
|
|
6858
|
+
const endContacts = slicePath(
|
|
6859
|
+
path,
|
|
6860
|
+
totalCableLength - contactLength,
|
|
6861
|
+
totalCableLength
|
|
6862
|
+
);
|
|
6863
|
+
const startStiffener = slicePath(path, 0, resolvedStiffenerLength);
|
|
6864
|
+
const endStiffener = slicePath(
|
|
6865
|
+
path,
|
|
6866
|
+
totalCableLength - resolvedStiffenerLength,
|
|
6867
|
+
totalCableLength
|
|
6868
|
+
);
|
|
6869
|
+
const pathEnd = path.at(-1);
|
|
6870
|
+
let presetScreenRotation;
|
|
6871
|
+
let screenCenter;
|
|
6872
|
+
if (orientation === "sitsFlat") {
|
|
6873
|
+
presetScreenRotation = [0, 0, 0];
|
|
6874
|
+
screenCenter = [
|
|
6875
|
+
pathEnd[0],
|
|
6876
|
+
pathEnd[1] + size.height / 2,
|
|
6877
|
+
pathEnd[2] + flexCableThickness / 2 + screenGap
|
|
6878
|
+
];
|
|
6879
|
+
} else if (orientation === "sitsFlatBelowBoard") {
|
|
6880
|
+
presetScreenRotation = [0, Math.PI, 0];
|
|
6881
|
+
screenCenter = [
|
|
6882
|
+
pathEnd[0],
|
|
6883
|
+
pathEnd[1] + size.height / 2,
|
|
6884
|
+
pathEnd[2] - flexCableThickness / 2 - screenGap
|
|
6885
|
+
];
|
|
6886
|
+
} else if (orientation === "foldedToFaceAboveBoard") {
|
|
6887
|
+
presetScreenRotation = [0, 0, 0];
|
|
6888
|
+
screenCenter = [pathEnd[0], pathEnd[1] - size.height / 2, foldedScreenBackZ];
|
|
6889
|
+
} else if (orientation === "foldedToFaceBelowBoard") {
|
|
6890
|
+
presetScreenRotation = [0, Math.PI, 0];
|
|
6891
|
+
screenCenter = [pathEnd[0], pathEnd[1] - size.height / 2, foldedScreenBackZ];
|
|
6892
|
+
} else if (orientation === "foldedToRightAngleAboveBoard") {
|
|
6893
|
+
presetScreenRotation = [Math.PI / 2, 0, 0];
|
|
6894
|
+
screenCenter = [
|
|
6895
|
+
pathEnd[0],
|
|
6896
|
+
pathEnd[1] - flexCableThickness / 2 - screenGap,
|
|
6897
|
+
pathEnd[2] + size.height / 2
|
|
6898
|
+
];
|
|
6899
|
+
} else {
|
|
6900
|
+
presetScreenRotation = [-Math.PI / 2, 0, 0];
|
|
6901
|
+
screenCenter = [
|
|
6902
|
+
pathEnd[0],
|
|
6903
|
+
pathEnd[1] + flexCableThickness / 2 + screenGap,
|
|
6904
|
+
pathEnd[2] - size.height / 2
|
|
6905
|
+
];
|
|
6906
|
+
}
|
|
6907
|
+
screenCenter = [
|
|
6908
|
+
screenCenter[0] + (screenOffset?.x ?? 0),
|
|
6909
|
+
screenCenter[1] + (screenOffset?.y ?? 0),
|
|
6910
|
+
screenCenter[2] + (screenOffset?.z ?? 0)
|
|
6911
|
+
];
|
|
6912
|
+
const conductorOffsets = Array.from(
|
|
6913
|
+
{ length: conductorCount },
|
|
6914
|
+
(_, index) => conductorCount === 1 ? 0 : (index - (conductorCount - 1) / 2) * resolvedConductorPitch
|
|
6915
|
+
);
|
|
6916
|
+
const conductorNormalOffset = (flexCableThickness + conductorThickness) / 2;
|
|
6917
|
+
const stiffenerNormalOffset = -(flexCableThickness + stiffenerThickness) / 2;
|
|
6918
|
+
const assembly = /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
6919
|
+
showFlexCable && /* @__PURE__ */ jsx(
|
|
6920
|
+
CableStrip,
|
|
6921
|
+
{
|
|
6922
|
+
points: path,
|
|
6923
|
+
width: resolvedCableWidth,
|
|
6924
|
+
thickness: flexCableThickness,
|
|
6925
|
+
color: flexCableColor
|
|
6926
|
+
}
|
|
6927
|
+
),
|
|
6928
|
+
showFlexCable && showStiffeners && resolvedStiffenerLength > EPSILON && /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
6929
|
+
/* @__PURE__ */ jsx(
|
|
6930
|
+
CableStrip,
|
|
6931
|
+
{
|
|
6932
|
+
points: startStiffener,
|
|
6933
|
+
width: resolvedCableWidth,
|
|
6934
|
+
thickness: stiffenerThickness,
|
|
6935
|
+
color: stiffenerColor,
|
|
6936
|
+
normalOffset: stiffenerNormalOffset
|
|
6937
|
+
}
|
|
6938
|
+
),
|
|
6939
|
+
/* @__PURE__ */ jsx(
|
|
6940
|
+
CableStrip,
|
|
6941
|
+
{
|
|
6942
|
+
points: endStiffener,
|
|
6943
|
+
width: resolvedCableWidth,
|
|
6944
|
+
thickness: stiffenerThickness,
|
|
6945
|
+
color: stiffenerColor,
|
|
6946
|
+
normalOffset: stiffenerNormalOffset
|
|
6947
|
+
}
|
|
6948
|
+
)
|
|
6949
|
+
] }),
|
|
6950
|
+
showFlexCable && showConductors && contactLength > EPSILON && conductorOffsets.map((acrossOffset, index) => /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
6951
|
+
/* @__PURE__ */ jsx(
|
|
6952
|
+
CableStrip,
|
|
6953
|
+
{
|
|
6954
|
+
points: startContacts,
|
|
6955
|
+
width: resolvedConductorWidth,
|
|
6956
|
+
thickness: conductorThickness,
|
|
6957
|
+
color: conductorColor,
|
|
6958
|
+
acrossOffset,
|
|
6959
|
+
normalOffset: conductorNormalOffset
|
|
6960
|
+
}
|
|
6961
|
+
),
|
|
6962
|
+
/* @__PURE__ */ jsx(
|
|
6963
|
+
CableStrip,
|
|
6964
|
+
{
|
|
6965
|
+
points: endContacts,
|
|
6966
|
+
width: resolvedConductorWidth,
|
|
6967
|
+
thickness: conductorThickness,
|
|
6968
|
+
color: conductorColor,
|
|
6969
|
+
acrossOffset,
|
|
6970
|
+
normalOffset: conductorNormalOffset
|
|
6971
|
+
}
|
|
6972
|
+
)
|
|
6973
|
+
] }, `conductor:${index}`)),
|
|
6974
|
+
showScreen && /* @__PURE__ */ jsx(Translate, { offset: screenCenter, children: /* @__PURE__ */ jsx(Rotate, { rotation: screenRotation ?? presetScreenRotation, children: /* @__PURE__ */ jsx(
|
|
6975
|
+
Screen,
|
|
6976
|
+
{
|
|
6977
|
+
width: size.width,
|
|
6978
|
+
height: size.height,
|
|
6979
|
+
thickness: screenThickness,
|
|
6980
|
+
bezelInset,
|
|
6981
|
+
bezelDepth,
|
|
6982
|
+
screenWidth: activeAreaWidth,
|
|
6983
|
+
screenHeight: activeAreaHeight,
|
|
6984
|
+
screenColor,
|
|
6985
|
+
bezelColor
|
|
6986
|
+
}
|
|
6987
|
+
) }) })
|
|
6988
|
+
] });
|
|
6989
|
+
return /* @__PURE__ */ jsx(
|
|
6990
|
+
Translate,
|
|
6991
|
+
{
|
|
6992
|
+
offset: {
|
|
6993
|
+
x: offset?.x ?? 0,
|
|
6994
|
+
y: offset?.y ?? 0,
|
|
6995
|
+
z: offset?.z ?? 0
|
|
6996
|
+
},
|
|
6997
|
+
children: /* @__PURE__ */ jsx(Translate, { offset: start, children: /* @__PURE__ */ jsx(Rotate, { rotation, children: /* @__PURE__ */ jsx(Translate, { offset: [-start[0], -start[1], -start[2]], children: assembly }) }) })
|
|
6998
|
+
}
|
|
6999
|
+
);
|
|
7000
|
+
};
|
|
7001
|
+
|
|
6462
7002
|
// lib/Footprinter3d.tsx
|
|
6463
7003
|
var Footprinter3d = ({ footprint }) => {
|
|
7004
|
+
const modelFn = mp.string(footprint.split("_", 1)[0]).params().fn;
|
|
7005
|
+
if (mp.getModelNames().includes(modelFn)) {
|
|
7006
|
+
const model = mp.string(footprint).json();
|
|
7007
|
+
switch (model.fn) {
|
|
7008
|
+
case "flexscreen": {
|
|
7009
|
+
const { fn: _, ...flexScreenProps } = model;
|
|
7010
|
+
return /* @__PURE__ */ jsx(FlexScreen, { ...flexScreenProps });
|
|
7011
|
+
}
|
|
7012
|
+
}
|
|
7013
|
+
}
|
|
6464
7014
|
let normalizedFootprint = footprint;
|
|
6465
7015
|
if (footprint.startsWith("jstzh1_5mm")) {
|
|
6466
7016
|
const pinMatch = footprint.match(/jstzh1_5mm(\d+)?/);
|
|
@@ -6589,7 +7139,6 @@ var Footprinter3d = ({ footprint }) => {
|
|
|
6589
7139
|
numberOfPins: fpJson.num_pins,
|
|
6590
7140
|
pitch: fpJson.p,
|
|
6591
7141
|
invert: fpJson.invert,
|
|
6592
|
-
faceup: fpJson.faceup,
|
|
6593
7142
|
rows,
|
|
6594
7143
|
smd: fpJson.smd || fpJson.surface_mount,
|
|
6595
7144
|
rightangle: fpJson.rightangle
|