@tscircuit/cli 0.1.125 → 0.1.127
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 +2 -1
- package/dist/main.js +948 -428
- package/package.json +6 -3
package/dist/main.js
CHANGED
|
@@ -305499,9 +305499,9 @@ var require_color_string = __commonJS((exports2, module2) => {
|
|
|
305499
305499
|
return null;
|
|
305500
305500
|
}
|
|
305501
305501
|
for (i = 0;i < 3; i++) {
|
|
305502
|
-
rgb2[i] =
|
|
305502
|
+
rgb2[i] = clamp5(rgb2[i], 0, 255);
|
|
305503
305503
|
}
|
|
305504
|
-
rgb2[3] =
|
|
305504
|
+
rgb2[3] = clamp5(rgb2[3], 0, 1);
|
|
305505
305505
|
return rgb2;
|
|
305506
305506
|
};
|
|
305507
305507
|
cs.get.hsl = function(string) {
|
|
@@ -305513,9 +305513,9 @@ var require_color_string = __commonJS((exports2, module2) => {
|
|
|
305513
305513
|
if (match) {
|
|
305514
305514
|
var alpha = parseFloat(match[4]);
|
|
305515
305515
|
var h = (parseFloat(match[1]) % 360 + 360) % 360;
|
|
305516
|
-
var s =
|
|
305517
|
-
var l =
|
|
305518
|
-
var a =
|
|
305516
|
+
var s = clamp5(parseFloat(match[2]), 0, 100);
|
|
305517
|
+
var l = clamp5(parseFloat(match[3]), 0, 100);
|
|
305518
|
+
var a = clamp5(isNaN(alpha) ? 1 : alpha, 0, 1);
|
|
305519
305519
|
return [h, s, l, a];
|
|
305520
305520
|
}
|
|
305521
305521
|
return null;
|
|
@@ -305529,9 +305529,9 @@ var require_color_string = __commonJS((exports2, module2) => {
|
|
|
305529
305529
|
if (match) {
|
|
305530
305530
|
var alpha = parseFloat(match[4]);
|
|
305531
305531
|
var h = (parseFloat(match[1]) % 360 + 360) % 360;
|
|
305532
|
-
var w =
|
|
305533
|
-
var b =
|
|
305534
|
-
var a =
|
|
305532
|
+
var w = clamp5(parseFloat(match[2]), 0, 100);
|
|
305533
|
+
var b = clamp5(parseFloat(match[3]), 0, 100);
|
|
305534
|
+
var a = clamp5(isNaN(alpha) ? 1 : alpha, 0, 1);
|
|
305535
305535
|
return [h, w, b, a];
|
|
305536
305536
|
}
|
|
305537
305537
|
return null;
|
|
@@ -305566,7 +305566,7 @@ var require_color_string = __commonJS((exports2, module2) => {
|
|
|
305566
305566
|
cs.to.keyword = function(rgb2) {
|
|
305567
305567
|
return reverseNames[rgb2.slice(0, 3)];
|
|
305568
305568
|
};
|
|
305569
|
-
function
|
|
305569
|
+
function clamp5(num, min, max) {
|
|
305570
305570
|
return Math.min(Math.max(min, num), max);
|
|
305571
305571
|
}
|
|
305572
305572
|
function hexDouble(num) {
|
|
@@ -305720,9 +305720,9 @@ var require_conversions = __commonJS((exports2, module2) => {
|
|
|
305720
305720
|
let currentClosestKeyword;
|
|
305721
305721
|
for (const keyword of Object.keys(cssKeywords)) {
|
|
305722
305722
|
const value2 = cssKeywords[keyword];
|
|
305723
|
-
const
|
|
305724
|
-
if (
|
|
305725
|
-
currentClosestDistance =
|
|
305723
|
+
const distance6 = comparativeDistance(rgb2, value2);
|
|
305724
|
+
if (distance6 < currentClosestDistance) {
|
|
305725
|
+
currentClosestDistance = distance6;
|
|
305726
305726
|
currentClosestKeyword = keyword;
|
|
305727
305727
|
}
|
|
305728
305728
|
}
|
|
@@ -441906,7 +441906,7 @@ var getGlobalDepsInstallCommand = (packageManager, deps) => {
|
|
|
441906
441906
|
import { execSync as execSync2 } from "node:child_process";
|
|
441907
441907
|
var import_semver2 = __toESM2(require_semver2(), 1);
|
|
441908
441908
|
// package.json
|
|
441909
|
-
var version = "0.1.
|
|
441909
|
+
var version = "0.1.126";
|
|
441910
441910
|
var package_default = {
|
|
441911
441911
|
name: "@tscircuit/cli",
|
|
441912
441912
|
version,
|
|
@@ -441917,6 +441917,7 @@ var package_default = {
|
|
|
441917
441917
|
"@tscircuit/fake-snippets": "^0.0.75",
|
|
441918
441918
|
"@tscircuit/file-server": "^0.0.24",
|
|
441919
441919
|
"@tscircuit/runframe": "^0.0.566",
|
|
441920
|
+
"@tscircuit/math-utils": "^0.0.18",
|
|
441920
441921
|
"@types/bun": "^1.2.2",
|
|
441921
441922
|
"@types/configstore": "^6.0.2",
|
|
441922
441923
|
"@types/debug": "^4.1.12",
|
|
@@ -441948,9 +441949,11 @@ var package_default = {
|
|
|
441948
441949
|
redaxios: "^0.5.1",
|
|
441949
441950
|
semver: "^7.6.3",
|
|
441950
441951
|
tempy: "^3.1.0",
|
|
441951
|
-
tscircuit: "^0.0.
|
|
441952
|
+
tscircuit: "^0.0.491",
|
|
441952
441953
|
"@tscircuit/circuit-json-util": "^0.0.47",
|
|
441953
|
-
"typed-ky": "^0.0.4"
|
|
441954
|
+
"typed-ky": "^0.0.4",
|
|
441955
|
+
"circuit-json-to-simple-3d": "^0.0.3",
|
|
441956
|
+
"@tscircuit/simple-3d-svg": "^0.0.10"
|
|
441954
441957
|
},
|
|
441955
441958
|
peerDependencies: {
|
|
441956
441959
|
typescript: "^5.0.0"
|
|
@@ -464847,21 +464850,221 @@ init_dist2();
|
|
|
464847
464850
|
// node_modules/@tscircuit/math-utils/dist/index.js
|
|
464848
464851
|
var exports_dist3 = {};
|
|
464849
464852
|
__export2(exports_dist3, {
|
|
464853
|
+
segmentToSegmentMinDistance: () => segmentToSegmentMinDistance,
|
|
464854
|
+
segmentToCircleMinDistance: () => segmentToCircleMinDistance,
|
|
464855
|
+
segmentToBoxMinDistance: () => segmentToBoxMinDistance,
|
|
464856
|
+
segmentToBoundsMinDistance: () => segmentToBoundsMinDistance,
|
|
464850
464857
|
pointToSegmentDistance: () => pointToSegmentDistance2,
|
|
464858
|
+
pointToSegmentClosestPoint: () => pointToSegmentClosestPoint,
|
|
464859
|
+
pointToBoxDistance: () => pointToBoxDistance,
|
|
464860
|
+
pointToBoundsDistance: () => pointToBoundsDistance,
|
|
464851
464861
|
orientation: () => orientation2,
|
|
464852
464862
|
onSegment: () => onSegment2,
|
|
464863
|
+
midpoint: () => midpoint,
|
|
464853
464864
|
grid: () => grid,
|
|
464854
464865
|
getUnitVectorFromPointAToB: () => getUnitVectorFromPointAToB,
|
|
464855
464866
|
getUnitVectorFromDirection: () => getUnitVectorFromDirection,
|
|
464867
|
+
getSegmentIntersection: () => getSegmentIntersection,
|
|
464856
464868
|
getBoundingBox: () => getBoundingBox2,
|
|
464857
464869
|
findNearestPointsBetweenBoxSets: () => findNearestPointsBetweenBoxSets2,
|
|
464858
464870
|
doesLineIntersectLine: () => doesLineIntersectLine2,
|
|
464859
464871
|
doSegmentsIntersect: () => doSegmentsIntersect2,
|
|
464860
464872
|
distance: () => distance4,
|
|
464873
|
+
distSq: () => distSq,
|
|
464861
464874
|
computeDistanceBetweenBoxes: () => computeDistanceBetweenBoxes2,
|
|
464862
464875
|
clamp: () => clamp2
|
|
464863
464876
|
});
|
|
464864
464877
|
|
|
464878
|
+
// node_modules/@tscircuit/math-utils/dist/chunk-3453HRP7.js
|
|
464879
|
+
function doesLineIntersectLine2([a1, a2], [b1, b2], {
|
|
464880
|
+
lineThickness = 0
|
|
464881
|
+
} = {}) {
|
|
464882
|
+
if (lineThickness === 0) {
|
|
464883
|
+
return doSegmentsIntersect2(a1, a2, b1, b2);
|
|
464884
|
+
}
|
|
464885
|
+
const minDist = segmentsDistance2(a1, a2, b1, b2);
|
|
464886
|
+
return minDist <= lineThickness;
|
|
464887
|
+
}
|
|
464888
|
+
function doSegmentsIntersect2(p1, q1, p2, q2) {
|
|
464889
|
+
const o1 = orientation2(p1, q1, p2);
|
|
464890
|
+
const o2 = orientation2(p1, q1, q2);
|
|
464891
|
+
const o3 = orientation2(p2, q2, p1);
|
|
464892
|
+
const o4 = orientation2(p2, q2, q1);
|
|
464893
|
+
if (o1 !== o2 && o3 !== o4) {
|
|
464894
|
+
return true;
|
|
464895
|
+
}
|
|
464896
|
+
if (o1 === 0 && onSegment2(p1, p2, q1))
|
|
464897
|
+
return true;
|
|
464898
|
+
if (o2 === 0 && onSegment2(p1, q2, q1))
|
|
464899
|
+
return true;
|
|
464900
|
+
if (o3 === 0 && onSegment2(p2, p1, q2))
|
|
464901
|
+
return true;
|
|
464902
|
+
if (o4 === 0 && onSegment2(p2, q1, q2))
|
|
464903
|
+
return true;
|
|
464904
|
+
return false;
|
|
464905
|
+
}
|
|
464906
|
+
function orientation2(p, q, r) {
|
|
464907
|
+
const val54 = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
|
|
464908
|
+
if (val54 === 0)
|
|
464909
|
+
return 0;
|
|
464910
|
+
return val54 > 0 ? 1 : 2;
|
|
464911
|
+
}
|
|
464912
|
+
function onSegment2(p, q, r) {
|
|
464913
|
+
return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);
|
|
464914
|
+
}
|
|
464915
|
+
function segmentsDistance2(a1, a2, b1, b2) {
|
|
464916
|
+
if (a1.x === a2.x && a1.y === a2.y) {
|
|
464917
|
+
return pointToSegmentDistance2(a1, b1, b2);
|
|
464918
|
+
}
|
|
464919
|
+
if (b1.x === b2.x && b1.y === b2.y) {
|
|
464920
|
+
return pointToSegmentDistance2(b1, a1, a2);
|
|
464921
|
+
}
|
|
464922
|
+
if (doSegmentsIntersect2(a1, a2, b1, b2)) {
|
|
464923
|
+
return 0;
|
|
464924
|
+
}
|
|
464925
|
+
const distances = [
|
|
464926
|
+
pointToSegmentDistance2(a1, b1, b2),
|
|
464927
|
+
pointToSegmentDistance2(a2, b1, b2),
|
|
464928
|
+
pointToSegmentDistance2(b1, a1, a2),
|
|
464929
|
+
pointToSegmentDistance2(b2, a1, a2)
|
|
464930
|
+
];
|
|
464931
|
+
return Math.min(...distances);
|
|
464932
|
+
}
|
|
464933
|
+
function pointToSegmentDistance2(p, v, w) {
|
|
464934
|
+
const l2 = (w.x - v.x) ** 2 + (w.y - v.y) ** 2;
|
|
464935
|
+
if (l2 === 0)
|
|
464936
|
+
return distance4(p, v);
|
|
464937
|
+
let t2 = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2;
|
|
464938
|
+
t2 = Math.max(0, Math.min(1, t2));
|
|
464939
|
+
const projection = {
|
|
464940
|
+
x: v.x + t2 * (w.x - v.x),
|
|
464941
|
+
y: v.y + t2 * (w.y - v.y)
|
|
464942
|
+
};
|
|
464943
|
+
return distance4(p, projection);
|
|
464944
|
+
}
|
|
464945
|
+
function distance4(p1, p2) {
|
|
464946
|
+
const dx = p1.x - p2.x;
|
|
464947
|
+
const dy = p1.y - p2.y;
|
|
464948
|
+
return Math.sqrt(dx * dx + dy * dy);
|
|
464949
|
+
}
|
|
464950
|
+
function getSegmentIntersection(a, b, u, v) {
|
|
464951
|
+
const dx1 = b.x - a.x;
|
|
464952
|
+
const dy1 = b.y - a.y;
|
|
464953
|
+
const dx2 = v.x - u.x;
|
|
464954
|
+
const dy2 = v.y - u.y;
|
|
464955
|
+
const dx3 = a.x - u.x;
|
|
464956
|
+
const dy3 = a.y - u.y;
|
|
464957
|
+
const denominator = dx1 * dy2 - dy1 * dx2;
|
|
464958
|
+
if (Math.abs(denominator) < 0.0000000001) {
|
|
464959
|
+
return null;
|
|
464960
|
+
}
|
|
464961
|
+
const t2 = (dy3 * dx2 - dx3 * dy2) / denominator;
|
|
464962
|
+
const s = (dx1 * dy3 - dy1 * dx3) / denominator;
|
|
464963
|
+
const epsilon = 0.000000001;
|
|
464964
|
+
if (t2 >= -epsilon && t2 <= 1 + epsilon && s >= -epsilon && s <= 1 + epsilon) {
|
|
464965
|
+
const intersectionX = a.x + t2 * dx1;
|
|
464966
|
+
const intersectionY = a.y + t2 * dy1;
|
|
464967
|
+
return { x: intersectionX, y: intersectionY };
|
|
464968
|
+
}
|
|
464969
|
+
return null;
|
|
464970
|
+
}
|
|
464971
|
+
|
|
464972
|
+
// node_modules/@tscircuit/math-utils/dist/chunk-FWQGMQBW.js
|
|
464973
|
+
function segmentToSegmentMinDistance(a, b, u, v) {
|
|
464974
|
+
if (a.x === b.x && a.y === b.y) {
|
|
464975
|
+
return pointToSegmentDistance2(a, u, v);
|
|
464976
|
+
}
|
|
464977
|
+
if (u.x === v.x && u.y === v.y) {
|
|
464978
|
+
return pointToSegmentDistance2(u, a, b);
|
|
464979
|
+
}
|
|
464980
|
+
if (doSegmentsIntersect2(a, b, u, v)) {
|
|
464981
|
+
return 0;
|
|
464982
|
+
}
|
|
464983
|
+
const distances = [
|
|
464984
|
+
pointToSegmentDistance2(a, u, v),
|
|
464985
|
+
pointToSegmentDistance2(b, u, v),
|
|
464986
|
+
pointToSegmentDistance2(u, a, b),
|
|
464987
|
+
pointToSegmentDistance2(v, a, b)
|
|
464988
|
+
];
|
|
464989
|
+
return Math.min(...distances);
|
|
464990
|
+
}
|
|
464991
|
+
function segmentToBoundsMinDistance(a, b, bounds6) {
|
|
464992
|
+
const topLeft = { x: bounds6.minX, y: bounds6.minY };
|
|
464993
|
+
const topRight = { x: bounds6.maxX, y: bounds6.minY };
|
|
464994
|
+
const bottomLeft = { x: bounds6.minX, y: bounds6.maxY };
|
|
464995
|
+
const bottomRight = { x: bounds6.maxX, y: bounds6.maxY };
|
|
464996
|
+
if (doSegmentsIntersect2(a, b, topLeft, topRight) || doSegmentsIntersect2(a, b, topRight, bottomRight) || doSegmentsIntersect2(a, b, bottomRight, bottomLeft) || doSegmentsIntersect2(a, b, bottomLeft, topLeft)) {
|
|
464997
|
+
return 0;
|
|
464998
|
+
}
|
|
464999
|
+
if (a.x >= bounds6.minX && a.x <= bounds6.maxX && a.y >= bounds6.minY && a.y <= bounds6.maxY && b.x >= bounds6.minX && b.x <= bounds6.maxX && b.y >= bounds6.minY && b.y <= bounds6.maxY) {
|
|
465000
|
+
return 0;
|
|
465001
|
+
}
|
|
465002
|
+
const distances = [
|
|
465003
|
+
pointToSegmentDistance2(topLeft, a, b),
|
|
465004
|
+
pointToSegmentDistance2(topRight, a, b),
|
|
465005
|
+
pointToSegmentDistance2(bottomLeft, a, b),
|
|
465006
|
+
pointToSegmentDistance2(bottomRight, a, b)
|
|
465007
|
+
];
|
|
465008
|
+
if (a.x >= bounds6.minX && a.x <= bounds6.maxX && a.y >= bounds6.minY && a.y <= bounds6.maxY) {
|
|
465009
|
+
return 0;
|
|
465010
|
+
}
|
|
465011
|
+
if (b.x >= bounds6.minX && b.x <= bounds6.maxX && b.y >= bounds6.minY && b.y <= bounds6.maxY) {
|
|
465012
|
+
return 0;
|
|
465013
|
+
}
|
|
465014
|
+
if (a.x < bounds6.minX || a.x > bounds6.maxX || a.y < bounds6.minY || a.y > bounds6.maxY) {
|
|
465015
|
+
const closestX = clamp2(a.x, bounds6.minX, bounds6.maxX);
|
|
465016
|
+
const closestY = clamp2(a.y, bounds6.minY, bounds6.maxY);
|
|
465017
|
+
distances.push(distance4(a, { x: closestX, y: closestY }));
|
|
465018
|
+
}
|
|
465019
|
+
if (b.x < bounds6.minX || b.x > bounds6.maxX || b.y < bounds6.minY || b.y > bounds6.maxY) {
|
|
465020
|
+
const closestX = clamp2(b.x, bounds6.minX, bounds6.maxX);
|
|
465021
|
+
const closestY = clamp2(b.y, bounds6.minY, bounds6.maxY);
|
|
465022
|
+
distances.push(distance4(b, { x: closestX, y: closestY }));
|
|
465023
|
+
}
|
|
465024
|
+
return Math.min(...distances);
|
|
465025
|
+
}
|
|
465026
|
+
function segmentToBoxMinDistance(a, b, box) {
|
|
465027
|
+
const halfWidth = box.width / 2;
|
|
465028
|
+
const halfHeight = box.height / 2;
|
|
465029
|
+
const bounds6 = {
|
|
465030
|
+
minX: box.center.x - halfWidth,
|
|
465031
|
+
maxX: box.center.x + halfWidth,
|
|
465032
|
+
minY: box.center.y - halfHeight,
|
|
465033
|
+
maxY: box.center.y + halfHeight
|
|
465034
|
+
};
|
|
465035
|
+
return segmentToBoundsMinDistance(a, b, bounds6);
|
|
465036
|
+
}
|
|
465037
|
+
function segmentToCircleMinDistance(a, b, circle) {
|
|
465038
|
+
const circleCenter = { x: circle.x, y: circle.y };
|
|
465039
|
+
if (a.x === b.x && a.y === b.y) {
|
|
465040
|
+
return Math.max(0, distance4(a, circleCenter) - circle.radius);
|
|
465041
|
+
}
|
|
465042
|
+
const ab = { x: b.x - a.x, y: b.y - a.y };
|
|
465043
|
+
const ac = { x: circleCenter.x - a.x, y: circleCenter.y - a.y };
|
|
465044
|
+
const abLengthSq = ab.x * ab.x + ab.y * ab.y;
|
|
465045
|
+
const t2 = Math.max(0, Math.min(1, (ab.x * ac.x + ab.y * ac.y) / abLengthSq));
|
|
465046
|
+
const closestPoint = {
|
|
465047
|
+
x: a.x + t2 * ab.x,
|
|
465048
|
+
y: a.y + t2 * ab.y
|
|
465049
|
+
};
|
|
465050
|
+
const distToCenter = distance4(closestPoint, circleCenter);
|
|
465051
|
+
return Math.max(0, distToCenter - circle.radius);
|
|
465052
|
+
}
|
|
465053
|
+
function pointToSegmentClosestPoint(p, a, b) {
|
|
465054
|
+
const dx_ab = b.x - a.x;
|
|
465055
|
+
const dy_ab = b.y - a.y;
|
|
465056
|
+
const l2 = dx_ab * dx_ab + dy_ab * dy_ab;
|
|
465057
|
+
if (l2 === 0)
|
|
465058
|
+
return { x: a.x, y: a.y };
|
|
465059
|
+
let t2 = ((p.x - a.x) * dx_ab + (p.y - a.y) * dy_ab) / l2;
|
|
465060
|
+
t2 = Math.max(0, Math.min(1, t2));
|
|
465061
|
+
const closestPoint = {
|
|
465062
|
+
x: a.x + t2 * dx_ab,
|
|
465063
|
+
y: a.y + t2 * dy_ab
|
|
465064
|
+
};
|
|
465065
|
+
return closestPoint;
|
|
465066
|
+
}
|
|
465067
|
+
|
|
464865
465068
|
// node_modules/@tscircuit/math-utils/dist/chunk-GIGMPRPV.js
|
|
464866
465069
|
var getUnitVectorFromPointAToB = (a, b) => {
|
|
464867
465070
|
const delta = {
|
|
@@ -464934,77 +465137,39 @@ function grid({
|
|
|
464934
465137
|
return cells;
|
|
464935
465138
|
}
|
|
464936
465139
|
|
|
464937
|
-
// node_modules/@tscircuit/math-utils/dist/chunk-
|
|
464938
|
-
function
|
|
464939
|
-
|
|
464940
|
-
|
|
464941
|
-
|
|
464942
|
-
|
|
464943
|
-
|
|
464944
|
-
const
|
|
464945
|
-
|
|
464946
|
-
}
|
|
464947
|
-
function doSegmentsIntersect2(p1, q1, p2, q2) {
|
|
464948
|
-
const o1 = orientation2(p1, q1, p2);
|
|
464949
|
-
const o2 = orientation2(p1, q1, q2);
|
|
464950
|
-
const o3 = orientation2(p2, q2, p1);
|
|
464951
|
-
const o4 = orientation2(p2, q2, q1);
|
|
464952
|
-
if (o1 !== o2 && o3 !== o4) {
|
|
464953
|
-
return true;
|
|
464954
|
-
}
|
|
464955
|
-
if (o1 === 0 && onSegment2(p1, p2, q1))
|
|
464956
|
-
return true;
|
|
464957
|
-
if (o2 === 0 && onSegment2(p1, q2, q1))
|
|
464958
|
-
return true;
|
|
464959
|
-
if (o3 === 0 && onSegment2(p2, p1, q2))
|
|
464960
|
-
return true;
|
|
464961
|
-
if (o4 === 0 && onSegment2(p2, q1, q2))
|
|
464962
|
-
return true;
|
|
464963
|
-
return false;
|
|
464964
|
-
}
|
|
464965
|
-
function orientation2(p, q, r) {
|
|
464966
|
-
const val54 = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
|
|
464967
|
-
if (val54 === 0)
|
|
465140
|
+
// node_modules/@tscircuit/math-utils/dist/chunk-SLG2OU3P.js
|
|
465141
|
+
function pointToBoxDistance(p, box) {
|
|
465142
|
+
const halfWidth = box.width / 2;
|
|
465143
|
+
const halfHeight = box.height / 2;
|
|
465144
|
+
const minX = box.center.x - halfWidth;
|
|
465145
|
+
const maxX = box.center.x + halfWidth;
|
|
465146
|
+
const minY = box.center.y - halfHeight;
|
|
465147
|
+
const maxY = box.center.y + halfHeight;
|
|
465148
|
+
if (p.x >= minX && p.x <= maxX && p.y >= minY && p.y <= maxY) {
|
|
464968
465149
|
return 0;
|
|
464969
|
-
return val54 > 0 ? 1 : 2;
|
|
464970
|
-
}
|
|
464971
|
-
function onSegment2(p, q, r) {
|
|
464972
|
-
return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);
|
|
464973
|
-
}
|
|
464974
|
-
function segmentsDistance2(a1, a2, b1, b2) {
|
|
464975
|
-
if (a1.x === a2.x && a1.y === a2.y) {
|
|
464976
|
-
return pointToSegmentDistance2(a1, b1, b2);
|
|
464977
465150
|
}
|
|
464978
|
-
|
|
464979
|
-
|
|
464980
|
-
}
|
|
464981
|
-
|
|
465151
|
+
const closestX = clamp2(p.x, minX, maxX);
|
|
465152
|
+
const closestY = clamp2(p.y, minY, maxY);
|
|
465153
|
+
return distance4(p, { x: closestX, y: closestY });
|
|
465154
|
+
}
|
|
465155
|
+
function pointToBoundsDistance(p, bounds6) {
|
|
465156
|
+
if (p.x >= bounds6.minX && p.x <= bounds6.maxX && p.y >= bounds6.minY && p.y <= bounds6.maxY) {
|
|
464982
465157
|
return 0;
|
|
464983
465158
|
}
|
|
464984
|
-
const
|
|
464985
|
-
|
|
464986
|
-
|
|
464987
|
-
pointToSegmentDistance2(b1, a1, a2),
|
|
464988
|
-
pointToSegmentDistance2(b2, a1, a2)
|
|
464989
|
-
];
|
|
464990
|
-
return Math.min(...distances);
|
|
465159
|
+
const closestX = clamp2(p.x, bounds6.minX, bounds6.maxX);
|
|
465160
|
+
const closestY = clamp2(p.y, bounds6.minY, bounds6.maxY);
|
|
465161
|
+
return distance4(p, { x: closestX, y: closestY });
|
|
464991
465162
|
}
|
|
464992
|
-
function
|
|
464993
|
-
|
|
464994
|
-
|
|
464995
|
-
|
|
464996
|
-
let t2 = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2;
|
|
464997
|
-
t2 = Math.max(0, Math.min(1, t2));
|
|
464998
|
-
const projection = {
|
|
464999
|
-
x: v.x + t2 * (w.x - v.x),
|
|
465000
|
-
y: v.y + t2 * (w.y - v.y)
|
|
465163
|
+
function midpoint(p1, p2) {
|
|
465164
|
+
return {
|
|
465165
|
+
x: (p1.x + p2.x) / 2,
|
|
465166
|
+
y: (p1.y + p2.y) / 2
|
|
465001
465167
|
};
|
|
465002
|
-
return distance4(p, projection);
|
|
465003
465168
|
}
|
|
465004
|
-
function
|
|
465169
|
+
function distSq(p1, p2) {
|
|
465005
465170
|
const dx = p1.x - p2.x;
|
|
465006
465171
|
const dy = p1.y - p2.y;
|
|
465007
|
-
return
|
|
465172
|
+
return dx * dx + dy * dy;
|
|
465008
465173
|
}
|
|
465009
465174
|
|
|
465010
465175
|
// node_modules/@tscircuit/core/dist/index.js
|
|
@@ -468117,7 +468282,7 @@ function distance5(p1, p2) {
|
|
|
468117
468282
|
const dy = p1.y - p2.y;
|
|
468118
468283
|
return Math.sqrt(dx * dx + dy * dy);
|
|
468119
468284
|
}
|
|
468120
|
-
function
|
|
468285
|
+
function getSegmentIntersection2(a, b, u, v) {
|
|
468121
468286
|
const dx1 = b.x - a.x;
|
|
468122
468287
|
const dy1 = b.y - a.y;
|
|
468123
468288
|
const dx2 = v.x - u.x;
|
|
@@ -468168,7 +468333,7 @@ function computeDistanceBetweenBoxes3(boxA, boxB) {
|
|
|
468168
468333
|
function clamp3(value2, min, max) {
|
|
468169
468334
|
return Math.max(min, Math.min(max, value2));
|
|
468170
468335
|
}
|
|
468171
|
-
function
|
|
468336
|
+
function segmentToSegmentMinDistance2(a, b, u, v) {
|
|
468172
468337
|
if (a.x === b.x && a.y === b.y) {
|
|
468173
468338
|
return pointToSegmentDistance3(a, u, v);
|
|
468174
468339
|
}
|
|
@@ -468186,7 +468351,7 @@ function segmentToSegmentMinDistance(a, b, u, v) {
|
|
|
468186
468351
|
];
|
|
468187
468352
|
return Math.min(...distances);
|
|
468188
468353
|
}
|
|
468189
|
-
function
|
|
468354
|
+
function segmentToBoundsMinDistance2(a, b, bounds6) {
|
|
468190
468355
|
const topLeft = { x: bounds6.minX, y: bounds6.minY };
|
|
468191
468356
|
const topRight = { x: bounds6.maxX, y: bounds6.minY };
|
|
468192
468357
|
const bottomLeft = { x: bounds6.minX, y: bounds6.maxY };
|
|
@@ -468221,7 +468386,7 @@ function segmentToBoundsMinDistance(a, b, bounds6) {
|
|
|
468221
468386
|
}
|
|
468222
468387
|
return Math.min(...distances);
|
|
468223
468388
|
}
|
|
468224
|
-
function
|
|
468389
|
+
function segmentToBoxMinDistance2(a, b, box) {
|
|
468225
468390
|
const halfWidth = box.width / 2;
|
|
468226
468391
|
const halfHeight = box.height / 2;
|
|
468227
468392
|
const bounds6 = {
|
|
@@ -468230,9 +468395,9 @@ function segmentToBoxMinDistance(a, b, box) {
|
|
|
468230
468395
|
minY: box.center.y - halfHeight,
|
|
468231
468396
|
maxY: box.center.y + halfHeight
|
|
468232
468397
|
};
|
|
468233
|
-
return
|
|
468398
|
+
return segmentToBoundsMinDistance2(a, b, bounds6);
|
|
468234
468399
|
}
|
|
468235
|
-
function
|
|
468400
|
+
function pointToSegmentClosestPoint2(p, a, b) {
|
|
468236
468401
|
const dx_ab = b.x - a.x;
|
|
468237
468402
|
const dy_ab = b.y - a.y;
|
|
468238
468403
|
const l2 = dx_ab * dx_ab + dy_ab * dy_ab;
|
|
@@ -468246,7 +468411,7 @@ function pointToSegmentClosestPoint(p, a, b) {
|
|
|
468246
468411
|
};
|
|
468247
468412
|
return closestPoint;
|
|
468248
468413
|
}
|
|
468249
|
-
function
|
|
468414
|
+
function midpoint2(p1, p2) {
|
|
468250
468415
|
return {
|
|
468251
468416
|
x: (p1.x + p2.x) / 2,
|
|
468252
468417
|
y: (p1.y + p2.y) / 2
|
|
@@ -469298,7 +469463,7 @@ function computeDumbbellPaths({
|
|
|
469298
469463
|
margin,
|
|
469299
469464
|
subdivisions = 0
|
|
469300
469465
|
}) {
|
|
469301
|
-
const
|
|
469466
|
+
const midpoint22 = (p1, p2) => ({
|
|
469302
469467
|
x: (p1.x + p2.x) / 2,
|
|
469303
469468
|
y: (p1.y + p2.y) / 2
|
|
469304
469469
|
});
|
|
@@ -469505,8 +469670,8 @@ function computeDumbbellPaths({
|
|
|
469505
469670
|
innerPoints.B_Left,
|
|
469506
469671
|
innerPoints.B_Opp,
|
|
469507
469672
|
innerPoints.B_Right,
|
|
469508
|
-
|
|
469509
|
-
|
|
469673
|
+
midpoint22(innerPoints.midpoint, midpoint22(innerPoints.B_Right, innerPoints.A_Right)),
|
|
469674
|
+
midpoint22(innerPoints.midpoint, midpoint22(innerPoints.A_Left, innerPoints.B_Left)),
|
|
469510
469675
|
innerPoints.A_Left,
|
|
469511
469676
|
innerPoints.A_Opp,
|
|
469512
469677
|
innerPoints.A_Right,
|
|
@@ -469517,8 +469682,8 @@ function computeDumbbellPaths({
|
|
|
469517
469682
|
innerPoints.B_Right,
|
|
469518
469683
|
innerPoints.B_Opp,
|
|
469519
469684
|
innerPoints.B_Left,
|
|
469520
|
-
|
|
469521
|
-
|
|
469685
|
+
midpoint22(innerPoints.midpoint, midpoint22(innerPoints.A_Left, innerPoints.B_Left)),
|
|
469686
|
+
midpoint22(innerPoints.midpoint, midpoint22(innerPoints.A_Right, innerPoints.B_Right)),
|
|
469522
469687
|
innerPoints.A_Right,
|
|
469523
469688
|
innerPoints.A_Opp,
|
|
469524
469689
|
innerPoints.A_Left,
|
|
@@ -469529,8 +469694,8 @@ function computeDumbbellPaths({
|
|
|
469529
469694
|
innerPoints.B_Left,
|
|
469530
469695
|
innerPoints.B_Opp,
|
|
469531
469696
|
innerPoints.B_Right,
|
|
469532
|
-
|
|
469533
|
-
|
|
469697
|
+
midpoint22(innerPoints.midpoint, midpoint22(innerPoints.A_Right, innerPoints.B_Right)),
|
|
469698
|
+
midpoint22(innerPoints.midpoint, midpoint22(innerPoints.A_Left, innerPoints.B_Left)),
|
|
469534
469699
|
innerPoints.A_Left,
|
|
469535
469700
|
innerPoints.A_Opp,
|
|
469536
469701
|
innerPoints.A_Right,
|
|
@@ -469541,8 +469706,8 @@ function computeDumbbellPaths({
|
|
|
469541
469706
|
innerPoints.B_Right,
|
|
469542
469707
|
innerPoints.B_Opp,
|
|
469543
469708
|
innerPoints.B_Left,
|
|
469544
|
-
|
|
469545
|
-
|
|
469709
|
+
midpoint22(innerPoints.midpoint, midpoint22(innerPoints.A_Left, innerPoints.B_Left)),
|
|
469710
|
+
midpoint22(innerPoints.midpoint, midpoint22(innerPoints.A_Right, innerPoints.B_Right)),
|
|
469546
469711
|
innerPoints.A_Right,
|
|
469547
469712
|
innerPoints.A_Opp,
|
|
469548
469713
|
innerPoints.A_Left,
|
|
@@ -469550,8 +469715,8 @@ function computeDumbbellPaths({
|
|
|
469550
469715
|
]
|
|
469551
469716
|
];
|
|
469552
469717
|
const getJLines = () => {
|
|
469553
|
-
const mid_AR_BR =
|
|
469554
|
-
const mid_AL_BL =
|
|
469718
|
+
const mid_AR_BR = midpoint22(innerPoints.A_Right, innerPoints.B_Right);
|
|
469719
|
+
const mid_AL_BL = midpoint22(innerPoints.B_Left, innerPoints.A_Left);
|
|
469555
469720
|
return [
|
|
469556
469721
|
{ startsAt: "E", goesTo: "B", points: [E, B] },
|
|
469557
469722
|
{ startsAt: "E", goesTo: "A", points: [E, A] },
|
|
@@ -471246,7 +471411,7 @@ var ViaPossibilitiesSolver2 = class extends BaseSolver {
|
|
|
471246
471411
|
if (segment[0].z !== this.currentHead.z) {
|
|
471247
471412
|
continue;
|
|
471248
471413
|
}
|
|
471249
|
-
const intersection =
|
|
471414
|
+
const intersection = getSegmentIntersection2(proposedSegment[0], proposedSegment[1], segment[0], segment[1]);
|
|
471250
471415
|
if (intersection) {
|
|
471251
471416
|
const distToIntersection = distance5(this.currentHead, intersection);
|
|
471252
471417
|
if (distToIntersection < 0.000001)
|
|
@@ -471269,7 +471434,7 @@ var ViaPossibilitiesSolver2 = class extends BaseSolver {
|
|
|
471269
471434
|
let viaXY;
|
|
471270
471435
|
const distToIntersection = closestIntersection.dist;
|
|
471271
471436
|
if (distToIntersection < this.VIA_INTERSECTION_BUFFER_DISTANCE) {
|
|
471272
|
-
viaXY =
|
|
471437
|
+
viaXY = midpoint2(this.currentHead, closestIntersection.point);
|
|
471273
471438
|
} else {
|
|
471274
471439
|
const intersectionPoint = closestIntersection.point;
|
|
471275
471440
|
const vectorX = intersectionPoint.x - this.currentHead.x;
|
|
@@ -471294,7 +471459,7 @@ var ViaPossibilitiesSolver2 = class extends BaseSolver {
|
|
|
471294
471459
|
let viaXY;
|
|
471295
471460
|
const distToTarget = distance5(this.currentHead, targetEnd);
|
|
471296
471461
|
if (distToTarget < this.VIA_INTERSECTION_BUFFER_DISTANCE) {
|
|
471297
|
-
viaXY =
|
|
471462
|
+
viaXY = midpoint2(this.currentHead, targetEnd);
|
|
471298
471463
|
} else {
|
|
471299
471464
|
const vectorX = targetEnd.x - this.currentHead.x;
|
|
471300
471465
|
const vectorY = targetEnd.y - this.currentHead.y;
|
|
@@ -472304,7 +472469,7 @@ var MultiHeadPolyLineIntraNodeSolver = class extends BaseSolver {
|
|
|
472304
472469
|
const path2Segments = path2SegmentsByLayer.get(zLayer) ?? [];
|
|
472305
472470
|
for (const segment1 of path1Segments) {
|
|
472306
472471
|
for (const segment2 of path2Segments) {
|
|
472307
|
-
minGap = Math.min(minGap,
|
|
472472
|
+
minGap = Math.min(minGap, segmentToSegmentMinDistance2(segment1[0], segment1[1], segment2[0], segment2[1]) - this.traceWidth);
|
|
472308
472473
|
}
|
|
472309
472474
|
}
|
|
472310
472475
|
for (const via of path1Vias) {
|
|
@@ -472513,7 +472678,7 @@ var MultiHeadPolyLineIntraNodeSolver = class extends BaseSolver {
|
|
|
472513
472678
|
for (const seg1 of segments1) {
|
|
472514
472679
|
for (const seg2 of segments2) {
|
|
472515
472680
|
if (seg1.layer === seg2.layer) {
|
|
472516
|
-
const minDist =
|
|
472681
|
+
const minDist = segmentToSegmentMinDistance2(seg1.p1, seg1.p2, seg2.p1, seg2.p2);
|
|
472517
472682
|
if (minDist < EPSILON4)
|
|
472518
472683
|
continue;
|
|
472519
472684
|
const center1 = {
|
|
@@ -472535,7 +472700,7 @@ var MultiHeadPolyLineIntraNodeSolver = class extends BaseSolver {
|
|
|
472535
472700
|
const sourceIdSeg2 = `seg:${j}:${seg2.p1Idx}:${seg2.p2Idx}`;
|
|
472536
472701
|
const sourceIdSeg1 = `seg:${i}:${seg1.p1Idx}:${seg1.p2Idx}`;
|
|
472537
472702
|
const endpointForce = (ep, epIdx, otherSeg, targetLine, oppLine, srcIdOpp, srcIdThis) => {
|
|
472538
|
-
const cp =
|
|
472703
|
+
const cp = pointToSegmentClosestPoint2(ep, otherSeg.p1, otherSeg.p2);
|
|
472539
472704
|
const dx2 = ep.x - cp.x;
|
|
472540
472705
|
const dy2 = ep.y - cp.y;
|
|
472541
472706
|
const dSq2 = dx2 * dx2 + dy2 * dy2;
|
|
@@ -472560,7 +472725,7 @@ var MultiHeadPolyLineIntraNodeSolver = class extends BaseSolver {
|
|
|
472560
472725
|
for (const via1 of vias1) {
|
|
472561
472726
|
for (const seg2 of segments2) {
|
|
472562
472727
|
if (via1.layers.includes(seg2.layer)) {
|
|
472563
|
-
const closestPointOnSeg =
|
|
472728
|
+
const closestPointOnSeg = pointToSegmentClosestPoint2(via1.point, seg2.p1, seg2.p2);
|
|
472564
472729
|
const dx = via1.point.x - closestPointOnSeg.x;
|
|
472565
472730
|
const dy = via1.point.y - closestPointOnSeg.y;
|
|
472566
472731
|
const dSq = dx * dx + dy * dy;
|
|
@@ -472589,7 +472754,7 @@ var MultiHeadPolyLineIntraNodeSolver = class extends BaseSolver {
|
|
|
472589
472754
|
for (const via2 of vias2) {
|
|
472590
472755
|
for (const seg1 of segments1) {
|
|
472591
472756
|
if (via2.layers.includes(seg1.layer)) {
|
|
472592
|
-
const closestPointOnSeg =
|
|
472757
|
+
const closestPointOnSeg = pointToSegmentClosestPoint2(via2.point, seg1.p1, seg1.p2);
|
|
472593
472758
|
const dx = via2.point.x - closestPointOnSeg.x;
|
|
472594
472759
|
const dy = via2.point.y - closestPointOnSeg.y;
|
|
472595
472760
|
const dSq = dx * dx + dy * dy;
|
|
@@ -473054,7 +473219,7 @@ var MultiHeadPolyLineIntraNodeSolver2 = class extends MultiHeadPolyLineIntraNode
|
|
|
473054
473219
|
}
|
|
473055
473220
|
};
|
|
473056
473221
|
const endpointForce = (ep, epIdx, otherSeg, targetLine, oppLine) => {
|
|
473057
|
-
const cp =
|
|
473222
|
+
const cp = pointToSegmentClosestPoint2(ep, otherSeg.p1, otherSeg.p2);
|
|
473058
473223
|
const dx = ep.x - cp.x;
|
|
473059
473224
|
const dy = ep.y - cp.y;
|
|
473060
473225
|
const dSq = dx * dx + dy * dy;
|
|
@@ -473107,7 +473272,7 @@ var MultiHeadPolyLineIntraNodeSolver2 = class extends MultiHeadPolyLineIntraNode
|
|
|
473107
473272
|
for (const seg1 of segments1) {
|
|
473108
473273
|
for (const seg2 of segments2) {
|
|
473109
473274
|
if (seg1.layer === seg2.layer) {
|
|
473110
|
-
const minDist =
|
|
473275
|
+
const minDist = segmentToSegmentMinDistance2(seg1.p1, seg1.p2, seg2.p1, seg2.p2);
|
|
473111
473276
|
endpointForce(seg1.p1, seg1.p1Idx, seg2, i, j);
|
|
473112
473277
|
endpointForce(seg1.p2, seg1.p2Idx, seg2, i, j);
|
|
473113
473278
|
endpointForce(seg2.p1, seg2.p1Idx, seg1, j, i);
|
|
@@ -473118,7 +473283,7 @@ var MultiHeadPolyLineIntraNodeSolver2 = class extends MultiHeadPolyLineIntraNode
|
|
|
473118
473283
|
for (const via1 of vias1) {
|
|
473119
473284
|
for (const seg2 of segments2) {
|
|
473120
473285
|
if (via1.layers.includes(seg2.layer)) {
|
|
473121
|
-
const closestPointOnSeg =
|
|
473286
|
+
const closestPointOnSeg = pointToSegmentClosestPoint2(via1.point, seg2.p1, seg2.p2);
|
|
473122
473287
|
const dx = via1.point.x - closestPointOnSeg.x;
|
|
473123
473288
|
const dy = via1.point.y - closestPointOnSeg.y;
|
|
473124
473289
|
const dSq = dx * dx + dy * dy;
|
|
@@ -473145,7 +473310,7 @@ var MultiHeadPolyLineIntraNodeSolver2 = class extends MultiHeadPolyLineIntraNode
|
|
|
473145
473310
|
for (const via2 of vias2) {
|
|
473146
473311
|
for (const seg1 of segments1) {
|
|
473147
473312
|
if (via2.layers.includes(seg1.layer)) {
|
|
473148
|
-
const closestPointOnSeg =
|
|
473313
|
+
const closestPointOnSeg = pointToSegmentClosestPoint2(via2.point, seg1.p1, seg1.p2);
|
|
473149
473314
|
const dx = via2.point.x - closestPointOnSeg.x;
|
|
473150
473315
|
const dy = via2.point.y - closestPointOnSeg.y;
|
|
473151
473316
|
const dSq = dx * dx + dy * dy;
|
|
@@ -479036,7 +479201,7 @@ var SingleSimplifiedPathSolver5 = class extends SingleSimplifiedPathSolver {
|
|
|
479036
479201
|
if (!obstacle.zLayers?.includes(start.z)) {
|
|
479037
479202
|
continue;
|
|
479038
479203
|
}
|
|
479039
|
-
const distToObstacle =
|
|
479204
|
+
const distToObstacle = segmentToBoxMinDistance2(start, end, obstacle);
|
|
479040
479205
|
if (distToObstacle < this.OBSTACLE_MARGIN + this.TRACE_THICKNESS / 2) {
|
|
479041
479206
|
return false;
|
|
479042
479207
|
}
|
|
@@ -479954,7 +480119,7 @@ var SingleRouteUselessViaRemovalSolver = class extends BaseSolver {
|
|
|
479954
480119
|
};
|
|
479955
480120
|
const obstacles = this.obstacleSHI.searchArea(segmentBox.centerX, segmentBox.centerY, segmentBox.width + (this.TRACE_THICKNESS + this.OBSTACLE_MARGIN) * 2, segmentBox.height + (this.TRACE_THICKNESS + this.OBSTACLE_MARGIN) * 2);
|
|
479956
480121
|
for (const obstacle of obstacles) {
|
|
479957
|
-
const distToObstacle =
|
|
480122
|
+
const distToObstacle = segmentToBoxMinDistance2(A, B, obstacle);
|
|
479958
480123
|
if (distToObstacle < this.TRACE_THICKNESS + this.OBSTACLE_MARGIN) {
|
|
479959
480124
|
return false;
|
|
479960
480125
|
}
|
|
@@ -480502,303 +480667,13 @@ init_dist2();
|
|
|
480502
480667
|
// node_modules/@tscircuit/checks/dist/index.js
|
|
480503
480668
|
init_dist4();
|
|
480504
480669
|
init_dist4();
|
|
480505
|
-
|
|
480506
|
-
// node_modules/@tscircuit/checks/node_modules/circuit-json-to-connectivity-map/dist/index.js
|
|
480507
|
-
function findConnectedNetworks2(connections) {
|
|
480508
|
-
const networks = /* @__PURE__ */ new Map;
|
|
480509
|
-
let netCounter = 0;
|
|
480510
|
-
function getOrCreateNetwork(nodeId) {
|
|
480511
|
-
for (const [, network] of networks) {
|
|
480512
|
-
if (network.has(nodeId)) {
|
|
480513
|
-
return network;
|
|
480514
|
-
}
|
|
480515
|
-
}
|
|
480516
|
-
const newNetwork = /* @__PURE__ */ new Set;
|
|
480517
|
-
networks.set(`connectivity_net${netCounter++}`, newNetwork);
|
|
480518
|
-
return newNetwork;
|
|
480519
|
-
}
|
|
480520
|
-
for (const connection of connections) {
|
|
480521
|
-
let network = null;
|
|
480522
|
-
for (const nodeId of connection) {
|
|
480523
|
-
if (!network) {
|
|
480524
|
-
network = getOrCreateNetwork(nodeId);
|
|
480525
|
-
} else if (!network.has(nodeId)) {
|
|
480526
|
-
const existingNetwork = getOrCreateNetwork(nodeId);
|
|
480527
|
-
if (existingNetwork !== network) {
|
|
480528
|
-
for (const node of existingNetwork) {
|
|
480529
|
-
network.add(node);
|
|
480530
|
-
}
|
|
480531
|
-
networks.delete(Array.from(networks.entries()).find(([, net2]) => net2 === existingNetwork)[0]);
|
|
480532
|
-
}
|
|
480533
|
-
}
|
|
480534
|
-
network.add(nodeId);
|
|
480535
|
-
}
|
|
480536
|
-
}
|
|
480537
|
-
return Object.fromEntries(Array.from(networks.entries()).map(([netId, connectedNodes]) => [
|
|
480538
|
-
netId,
|
|
480539
|
-
Array.from(connectedNodes)
|
|
480540
|
-
]));
|
|
480541
|
-
}
|
|
480542
|
-
var ConnectivityMap3 = class {
|
|
480543
|
-
netMap;
|
|
480544
|
-
idToNetMap;
|
|
480545
|
-
constructor(netMap) {
|
|
480546
|
-
this.netMap = netMap;
|
|
480547
|
-
this.idToNetMap = {};
|
|
480548
|
-
for (const [netId, ids] of Object.entries(netMap)) {
|
|
480549
|
-
for (const id of ids) {
|
|
480550
|
-
this.idToNetMap[id] = netId;
|
|
480551
|
-
}
|
|
480552
|
-
}
|
|
480553
|
-
}
|
|
480554
|
-
addConnections(connections) {
|
|
480555
|
-
for (const connection of connections) {
|
|
480556
|
-
const existingNets = /* @__PURE__ */ new Set;
|
|
480557
|
-
for (const id of connection) {
|
|
480558
|
-
const existingNetId = this.idToNetMap[id];
|
|
480559
|
-
if (existingNetId) {
|
|
480560
|
-
existingNets.add(existingNetId);
|
|
480561
|
-
}
|
|
480562
|
-
}
|
|
480563
|
-
let targetNetId;
|
|
480564
|
-
if (existingNets.size === 0) {
|
|
480565
|
-
targetNetId = `connectivity_net${Object.keys(this.netMap).length}`;
|
|
480566
|
-
this.netMap[targetNetId] = [];
|
|
480567
|
-
} else if (existingNets.size === 1) {
|
|
480568
|
-
targetNetId = existingNets.values().next().value ?? `connectivity_net${Object.keys(this.netMap).length}`;
|
|
480569
|
-
} else {
|
|
480570
|
-
targetNetId = existingNets.values().next().value ?? `connectivity_net${Object.keys(this.netMap).length}`;
|
|
480571
|
-
for (const netId of existingNets) {
|
|
480572
|
-
if (netId !== targetNetId) {
|
|
480573
|
-
this.netMap[targetNetId].push(...this.netMap[netId]);
|
|
480574
|
-
this.netMap[netId] = this.netMap[targetNetId];
|
|
480575
|
-
for (const id of this.netMap[targetNetId]) {
|
|
480576
|
-
this.idToNetMap[id] = targetNetId;
|
|
480577
|
-
}
|
|
480578
|
-
}
|
|
480579
|
-
}
|
|
480580
|
-
}
|
|
480581
|
-
for (const id of connection) {
|
|
480582
|
-
if (!this.netMap[targetNetId].includes(id)) {
|
|
480583
|
-
this.netMap[targetNetId].push(id);
|
|
480584
|
-
}
|
|
480585
|
-
this.idToNetMap[id] = targetNetId;
|
|
480586
|
-
}
|
|
480587
|
-
}
|
|
480588
|
-
}
|
|
480589
|
-
getIdsConnectedToNet(netId) {
|
|
480590
|
-
return this.netMap[netId] || [];
|
|
480591
|
-
}
|
|
480592
|
-
getNetConnectedToId(id) {
|
|
480593
|
-
return this.idToNetMap[id];
|
|
480594
|
-
}
|
|
480595
|
-
areIdsConnected(id1, id2) {
|
|
480596
|
-
if (id1 === id2)
|
|
480597
|
-
return true;
|
|
480598
|
-
const netId1 = this.getNetConnectedToId(id1);
|
|
480599
|
-
if (!netId1)
|
|
480600
|
-
return false;
|
|
480601
|
-
const netId2 = this.getNetConnectedToId(id2);
|
|
480602
|
-
if (!netId2)
|
|
480603
|
-
return false;
|
|
480604
|
-
return netId1 === netId2 || netId2 === id1 || netId2 === id1;
|
|
480605
|
-
}
|
|
480606
|
-
areAllIdsConnected(ids) {
|
|
480607
|
-
const netId = this.getNetConnectedToId(ids[0]);
|
|
480608
|
-
for (const id of ids) {
|
|
480609
|
-
const nextNetId = this.getNetConnectedToId(id);
|
|
480610
|
-
if (nextNetId === undefined) {
|
|
480611
|
-
return false;
|
|
480612
|
-
}
|
|
480613
|
-
if (nextNetId !== netId) {
|
|
480614
|
-
return false;
|
|
480615
|
-
}
|
|
480616
|
-
}
|
|
480617
|
-
return true;
|
|
480618
|
-
}
|
|
480619
|
-
};
|
|
480620
|
-
var getFullConnectivityMapFromCircuitJson2 = (circuitJson) => {
|
|
480621
|
-
const connections = [];
|
|
480622
|
-
for (const element of circuitJson) {
|
|
480623
|
-
if (element.type === "source_trace") {
|
|
480624
|
-
connections.push([
|
|
480625
|
-
element.source_trace_id,
|
|
480626
|
-
...element.connected_source_port_ids ?? [],
|
|
480627
|
-
...element.connected_source_net_ids ?? []
|
|
480628
|
-
].filter(Boolean));
|
|
480629
|
-
} else if (element.type === "pcb_port") {
|
|
480630
|
-
const { pcb_port_id, source_port_id } = element;
|
|
480631
|
-
if (source_port_id && pcb_port_id) {
|
|
480632
|
-
connections.push([source_port_id, pcb_port_id]);
|
|
480633
|
-
}
|
|
480634
|
-
} else if (element.type === "pcb_smtpad") {
|
|
480635
|
-
const { pcb_smtpad_id, pcb_port_id } = element;
|
|
480636
|
-
if (pcb_port_id && pcb_smtpad_id) {
|
|
480637
|
-
connections.push([pcb_smtpad_id, pcb_port_id]);
|
|
480638
|
-
}
|
|
480639
|
-
} else if (element.type === "pcb_plated_hole") {
|
|
480640
|
-
const { pcb_plated_hole_id, pcb_port_id } = element;
|
|
480641
|
-
if (pcb_port_id && pcb_plated_hole_id) {
|
|
480642
|
-
connections.push([pcb_plated_hole_id, pcb_port_id]);
|
|
480643
|
-
}
|
|
480644
|
-
} else if (element.type === "pcb_trace") {
|
|
480645
|
-
const { pcb_trace_id, source_trace_id } = element;
|
|
480646
|
-
const route = Array.isArray(element.route) ? element.route.filter((rp) => rp && rp.route_type === "wire") : [];
|
|
480647
|
-
if (source_trace_id && pcb_trace_id) {
|
|
480648
|
-
connections.push([pcb_trace_id, source_trace_id]);
|
|
480649
|
-
}
|
|
480650
|
-
if (Array.isArray(route)) {
|
|
480651
|
-
const startId = route.find((rp) => rp && rp.start_pcb_port_id)?.start_pcb_port_id;
|
|
480652
|
-
const endId = route.find((rp) => rp && rp.end_pcb_port_id)?.end_pcb_port_id;
|
|
480653
|
-
if (startId && pcb_trace_id && endId) {
|
|
480654
|
-
connections.push([startId, pcb_trace_id, endId]);
|
|
480655
|
-
}
|
|
480656
|
-
}
|
|
480657
|
-
} else if (element.type === "pcb_via") {
|
|
480658
|
-
const { pcb_via_id, pcb_trace_id } = element;
|
|
480659
|
-
if (pcb_trace_id && pcb_via_id) {
|
|
480660
|
-
connections.push([pcb_via_id, pcb_trace_id]);
|
|
480661
|
-
}
|
|
480662
|
-
} else if (element.type === "source_component") {
|
|
480663
|
-
if (element.internally_connected_source_port_ids) {
|
|
480664
|
-
for (const portGroup of element.internally_connected_source_port_ids) {
|
|
480665
|
-
connections.push(portGroup);
|
|
480666
|
-
}
|
|
480667
|
-
}
|
|
480668
|
-
}
|
|
480669
|
-
}
|
|
480670
|
-
const netMap = findConnectedNetworks2(connections);
|
|
480671
|
-
return new ConnectivityMap3(netMap);
|
|
480672
|
-
};
|
|
480673
|
-
|
|
480674
|
-
// node_modules/@tscircuit/checks/dist/index.js
|
|
480670
|
+
init_dist2();
|
|
480675
480671
|
init_dist4();
|
|
480676
|
-
|
|
480677
|
-
// node_modules/@tscircuit/checks/node_modules/@tscircuit/math-utils/dist/chunk-3453HRP7.js
|
|
480678
|
-
function doSegmentsIntersect5(p1, q1, p2, q2) {
|
|
480679
|
-
const o1 = orientation5(p1, q1, p2);
|
|
480680
|
-
const o2 = orientation5(p1, q1, q2);
|
|
480681
|
-
const o3 = orientation5(p2, q2, p1);
|
|
480682
|
-
const o4 = orientation5(p2, q2, q1);
|
|
480683
|
-
if (o1 !== o2 && o3 !== o4) {
|
|
480684
|
-
return true;
|
|
480685
|
-
}
|
|
480686
|
-
if (o1 === 0 && onSegment5(p1, p2, q1))
|
|
480687
|
-
return true;
|
|
480688
|
-
if (o2 === 0 && onSegment5(p1, q2, q1))
|
|
480689
|
-
return true;
|
|
480690
|
-
if (o3 === 0 && onSegment5(p2, p1, q2))
|
|
480691
|
-
return true;
|
|
480692
|
-
if (o4 === 0 && onSegment5(p2, q1, q2))
|
|
480693
|
-
return true;
|
|
480694
|
-
return false;
|
|
480695
|
-
}
|
|
480696
|
-
function orientation5(p, q, r) {
|
|
480697
|
-
const val54 = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
|
|
480698
|
-
if (val54 === 0)
|
|
480699
|
-
return 0;
|
|
480700
|
-
return val54 > 0 ? 1 : 2;
|
|
480701
|
-
}
|
|
480702
|
-
function onSegment5(p, q, r) {
|
|
480703
|
-
return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);
|
|
480704
|
-
}
|
|
480705
|
-
function pointToSegmentDistance5(p, v, w) {
|
|
480706
|
-
const l2 = (w.x - v.x) ** 2 + (w.y - v.y) ** 2;
|
|
480707
|
-
if (l2 === 0)
|
|
480708
|
-
return distance7(p, v);
|
|
480709
|
-
let t2 = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2;
|
|
480710
|
-
t2 = Math.max(0, Math.min(1, t2));
|
|
480711
|
-
const projection = {
|
|
480712
|
-
x: v.x + t2 * (w.x - v.x),
|
|
480713
|
-
y: v.y + t2 * (w.y - v.y)
|
|
480714
|
-
};
|
|
480715
|
-
return distance7(p, projection);
|
|
480716
|
-
}
|
|
480717
|
-
function distance7(p1, p2) {
|
|
480718
|
-
const dx = p1.x - p2.x;
|
|
480719
|
-
const dy = p1.y - p2.y;
|
|
480720
|
-
return Math.sqrt(dx * dx + dy * dy);
|
|
480721
|
-
}
|
|
480722
|
-
|
|
480723
|
-
// node_modules/@tscircuit/checks/node_modules/@tscircuit/math-utils/dist/chunk-MHHTZHOJ.js
|
|
480724
|
-
function clamp5(value2, min, max) {
|
|
480725
|
-
return Math.max(min, Math.min(max, value2));
|
|
480726
|
-
}
|
|
480727
|
-
|
|
480728
|
-
// node_modules/@tscircuit/checks/node_modules/@tscircuit/math-utils/dist/chunk-FWQGMQBW.js
|
|
480729
|
-
function segmentToSegmentMinDistance2(a, b, u, v) {
|
|
480730
|
-
if (a.x === b.x && a.y === b.y) {
|
|
480731
|
-
return pointToSegmentDistance5(a, u, v);
|
|
480732
|
-
}
|
|
480733
|
-
if (u.x === v.x && u.y === v.y) {
|
|
480734
|
-
return pointToSegmentDistance5(u, a, b);
|
|
480735
|
-
}
|
|
480736
|
-
if (doSegmentsIntersect5(a, b, u, v)) {
|
|
480737
|
-
return 0;
|
|
480738
|
-
}
|
|
480739
|
-
const distances = [
|
|
480740
|
-
pointToSegmentDistance5(a, u, v),
|
|
480741
|
-
pointToSegmentDistance5(b, u, v),
|
|
480742
|
-
pointToSegmentDistance5(u, a, b),
|
|
480743
|
-
pointToSegmentDistance5(v, a, b)
|
|
480744
|
-
];
|
|
480745
|
-
return Math.min(...distances);
|
|
480746
|
-
}
|
|
480747
|
-
function segmentToBoundsMinDistance2(a, b, bounds6) {
|
|
480748
|
-
const topLeft = { x: bounds6.minX, y: bounds6.minY };
|
|
480749
|
-
const topRight = { x: bounds6.maxX, y: bounds6.minY };
|
|
480750
|
-
const bottomLeft = { x: bounds6.minX, y: bounds6.maxY };
|
|
480751
|
-
const bottomRight = { x: bounds6.maxX, y: bounds6.maxY };
|
|
480752
|
-
if (doSegmentsIntersect5(a, b, topLeft, topRight) || doSegmentsIntersect5(a, b, topRight, bottomRight) || doSegmentsIntersect5(a, b, bottomRight, bottomLeft) || doSegmentsIntersect5(a, b, bottomLeft, topLeft)) {
|
|
480753
|
-
return 0;
|
|
480754
|
-
}
|
|
480755
|
-
if (a.x >= bounds6.minX && a.x <= bounds6.maxX && a.y >= bounds6.minY && a.y <= bounds6.maxY && b.x >= bounds6.minX && b.x <= bounds6.maxX && b.y >= bounds6.minY && b.y <= bounds6.maxY) {
|
|
480756
|
-
return 0;
|
|
480757
|
-
}
|
|
480758
|
-
const distances = [
|
|
480759
|
-
pointToSegmentDistance5(topLeft, a, b),
|
|
480760
|
-
pointToSegmentDistance5(topRight, a, b),
|
|
480761
|
-
pointToSegmentDistance5(bottomLeft, a, b),
|
|
480762
|
-
pointToSegmentDistance5(bottomRight, a, b)
|
|
480763
|
-
];
|
|
480764
|
-
if (a.x >= bounds6.minX && a.x <= bounds6.maxX && a.y >= bounds6.minY && a.y <= bounds6.maxY) {
|
|
480765
|
-
return 0;
|
|
480766
|
-
}
|
|
480767
|
-
if (b.x >= bounds6.minX && b.x <= bounds6.maxX && b.y >= bounds6.minY && b.y <= bounds6.maxY) {
|
|
480768
|
-
return 0;
|
|
480769
|
-
}
|
|
480770
|
-
if (a.x < bounds6.minX || a.x > bounds6.maxX || a.y < bounds6.minY || a.y > bounds6.maxY) {
|
|
480771
|
-
const closestX = clamp5(a.x, bounds6.minX, bounds6.maxX);
|
|
480772
|
-
const closestY = clamp5(a.y, bounds6.minY, bounds6.maxY);
|
|
480773
|
-
distances.push(distance7(a, { x: closestX, y: closestY }));
|
|
480774
|
-
}
|
|
480775
|
-
if (b.x < bounds6.minX || b.x > bounds6.maxX || b.y < bounds6.minY || b.y > bounds6.maxY) {
|
|
480776
|
-
const closestX = clamp5(b.x, bounds6.minX, bounds6.maxX);
|
|
480777
|
-
const closestY = clamp5(b.y, bounds6.minY, bounds6.maxY);
|
|
480778
|
-
distances.push(distance7(b, { x: closestX, y: closestY }));
|
|
480779
|
-
}
|
|
480780
|
-
return Math.min(...distances);
|
|
480781
|
-
}
|
|
480782
|
-
function segmentToCircleMinDistance(a, b, circle) {
|
|
480783
|
-
const circleCenter = { x: circle.x, y: circle.y };
|
|
480784
|
-
if (a.x === b.x && a.y === b.y) {
|
|
480785
|
-
return Math.max(0, distance7(a, circleCenter) - circle.radius);
|
|
480786
|
-
}
|
|
480787
|
-
const ab = { x: b.x - a.x, y: b.y - a.y };
|
|
480788
|
-
const ac = { x: circleCenter.x - a.x, y: circleCenter.y - a.y };
|
|
480789
|
-
const abLengthSq = ab.x * ab.x + ab.y * ab.y;
|
|
480790
|
-
const t2 = Math.max(0, Math.min(1, (ab.x * ac.x + ab.y * ac.y) / abLengthSq));
|
|
480791
|
-
const closestPoint = {
|
|
480792
|
-
x: a.x + t2 * ab.x,
|
|
480793
|
-
y: a.y + t2 * ab.y
|
|
480794
|
-
};
|
|
480795
|
-
const distToCenter = distance7(closestPoint, circleCenter);
|
|
480796
|
-
return Math.max(0, distToCenter - circle.radius);
|
|
480797
|
-
}
|
|
480798
|
-
|
|
480799
|
-
// node_modules/@tscircuit/checks/dist/index.js
|
|
480800
480672
|
init_dist4();
|
|
480801
480673
|
init_dist3();
|
|
480674
|
+
init_dist4();
|
|
480675
|
+
init_dist4();
|
|
480676
|
+
init_dist2();
|
|
480802
480677
|
var SpatialObjectIndex = class {
|
|
480803
480678
|
buckets;
|
|
480804
480679
|
objectsById;
|
|
@@ -480950,7 +480825,7 @@ var getClosestPointBetweenSegments = (segmentA, segmentB) => {
|
|
|
480950
480825
|
};
|
|
480951
480826
|
}
|
|
480952
480827
|
if (lenSqrA === 0) {
|
|
480953
|
-
const t22 =
|
|
480828
|
+
const t22 = clamp4(((a1.x - b1.x) * vb.x + (a1.y - b1.y) * vb.y) / lenSqrB, 0, 1);
|
|
480954
480829
|
const closestOnB2 = {
|
|
480955
480830
|
x: b1.x + t22 * vb.x,
|
|
480956
480831
|
y: b1.y + t22 * vb.y
|
|
@@ -480960,7 +480835,7 @@ var getClosestPointBetweenSegments = (segmentA, segmentB) => {
|
|
|
480960
480835
|
y: (a1.y + closestOnB2.y) / 2
|
|
480961
480836
|
};
|
|
480962
480837
|
}
|
|
480963
|
-
const t2 =
|
|
480838
|
+
const t2 = clamp4(((b1.x - a1.x) * va.x + (b1.y - a1.y) * va.y) / lenSqrA, 0, 1);
|
|
480964
480839
|
const closestOnA2 = {
|
|
480965
480840
|
x: a1.x + t2 * va.x,
|
|
480966
480841
|
y: a1.y + t2 * va.y
|
|
@@ -480982,12 +480857,12 @@ var getClosestPointBetweenSegments = (segmentA, segmentB) => {
|
|
|
480982
480857
|
}
|
|
480983
480858
|
let tA = (dotAB * dotBW - dotBB * dotAW) / denominator;
|
|
480984
480859
|
let tB = (dotAA * dotBW - dotAB * dotAW) / denominator;
|
|
480985
|
-
tA =
|
|
480986
|
-
tB =
|
|
480860
|
+
tA = clamp4(tA, 0, 1);
|
|
480861
|
+
tB = clamp4(tB, 0, 1);
|
|
480987
480862
|
tB = (tA * dotAB + dotBW) / dotBB;
|
|
480988
|
-
tB =
|
|
480863
|
+
tB = clamp4(tB, 0, 1);
|
|
480989
480864
|
tA = (tB * dotAB - dotAW) / dotAA;
|
|
480990
|
-
tA =
|
|
480865
|
+
tA = clamp4(tA, 0, 1);
|
|
480991
480866
|
const closestOnA = {
|
|
480992
480867
|
x: a1.x + tA * va.x,
|
|
480993
480868
|
y: a1.y + tA * va.y
|
|
@@ -480998,7 +480873,7 @@ var getClosestPointBetweenSegments = (segmentA, segmentB) => {
|
|
|
480998
480873
|
};
|
|
480999
480874
|
const dx = closestOnA.x - closestOnB.x;
|
|
481000
480875
|
const dy = closestOnA.y - closestOnB.y;
|
|
481001
|
-
const
|
|
480876
|
+
const distance32 = Math.sqrt(dx * dx + dy * dy);
|
|
481002
480877
|
const averagePoint = {
|
|
481003
480878
|
x: (closestOnA.x + closestOnB.x) / 2,
|
|
481004
480879
|
y: (closestOnA.y + closestOnB.y) / 2
|
|
@@ -481007,16 +480882,16 @@ var getClosestPointBetweenSegments = (segmentA, segmentB) => {
|
|
|
481007
480882
|
};
|
|
481008
480883
|
var closestPointsParallelSegments = (a1, a2, b1, b2, va, vb, lenSqrA, lenSqrB) => {
|
|
481009
480884
|
let tA = ((b1.x - a1.x) * va.x + (b1.y - a1.y) * va.y) / lenSqrA;
|
|
481010
|
-
tA =
|
|
480885
|
+
tA = clamp4(tA, 0, 1);
|
|
481011
480886
|
const pointOnA1 = { x: a1.x + tA * va.x, y: a1.y + tA * va.y };
|
|
481012
480887
|
let tA2 = ((b2.x - a1.x) * va.x + (b2.y - a1.y) * va.y) / lenSqrA;
|
|
481013
|
-
tA2 =
|
|
480888
|
+
tA2 = clamp4(tA2, 0, 1);
|
|
481014
480889
|
const pointOnA2 = { x: a1.x + tA2 * va.x, y: a1.y + tA2 * va.y };
|
|
481015
480890
|
let tB = ((a1.x - b1.x) * vb.x + (a1.y - b1.y) * vb.y) / lenSqrB;
|
|
481016
|
-
tB =
|
|
480891
|
+
tB = clamp4(tB, 0, 1);
|
|
481017
480892
|
const pointOnB1 = { x: b1.x + tB * vb.x, y: b1.y + tB * vb.y };
|
|
481018
480893
|
let tB2 = ((a2.x - b1.x) * vb.x + (a2.y - b1.y) * vb.y) / lenSqrB;
|
|
481019
|
-
tB2 =
|
|
480894
|
+
tB2 = clamp4(tB2, 0, 1);
|
|
481020
480895
|
const pointOnB2 = { x: b1.x + tB2 * vb.x, y: b1.y + tB2 * vb.y };
|
|
481021
480896
|
const distances = [
|
|
481022
480897
|
{
|
|
@@ -481046,7 +480921,7 @@ var closestPointsParallelSegments = (a1, a2, b1, b2, va, vb, lenSqrA, lenSqrB) =
|
|
|
481046
480921
|
y: (closestPair.pointA.y + closestPair.pointB.y) / 2
|
|
481047
480922
|
};
|
|
481048
480923
|
};
|
|
481049
|
-
var
|
|
480924
|
+
var clamp4 = (value2, min, max) => {
|
|
481050
480925
|
return Math.max(min, Math.min(max, value2));
|
|
481051
480926
|
};
|
|
481052
480927
|
var getRadiusOfCircuitJsonElement = (obj) => {
|
|
@@ -481177,7 +481052,7 @@ function checkEachPcbTraceNonOverlapping(circuitJson, {
|
|
|
481177
481052
|
connMap
|
|
481178
481053
|
} = {}) {
|
|
481179
481054
|
const errors = [];
|
|
481180
|
-
connMap ??=
|
|
481055
|
+
connMap ??= getFullConnectivityMapFromCircuitJson(circuitJson);
|
|
481181
481056
|
const pcbTraces = cju_default(circuitJson).pcb_trace.list();
|
|
481182
481057
|
const pcbTraceSegments = pcbTraces.flatMap((pcbTrace) => {
|
|
481183
481058
|
const segments = [];
|
|
@@ -481239,7 +481114,7 @@ function checkEachPcbTraceNonOverlapping(circuitJson, {
|
|
|
481239
481114
|
continue;
|
|
481240
481115
|
if (connMap.areIdsConnected(segmentA.pcb_trace_id, segmentB.pcb_trace_id))
|
|
481241
481116
|
continue;
|
|
481242
|
-
const gap2 =
|
|
481117
|
+
const gap2 = segmentToSegmentMinDistance({ x: segmentA.x1, y: segmentA.y1 }, { x: segmentA.x2, y: segmentA.y2 }, { x: segmentB.x1, y: segmentB.y1 }, { x: segmentB.x2, y: segmentB.y2 }) - segmentA.thickness / 2 - segmentB.thickness / 2;
|
|
481243
481118
|
if (gap2 > DEFAULT_TRACE_MARGIN - EPSILON4)
|
|
481244
481119
|
continue;
|
|
481245
481120
|
const pcb_trace_error_id = `overlap_${segmentA.pcb_trace_id}_${segmentB.pcb_trace_id}`;
|
|
@@ -481271,8 +481146,8 @@ function checkEachPcbTraceNonOverlapping(circuitJson, {
|
|
|
481271
481146
|
const isCircular = obj.type === "pcb_via" || obj.type === "pcb_plated_hole" && obj.shape === "circle" || obj.type === "pcb_hole" || obj.type === "pcb_smtpad" && obj.shape === "circle";
|
|
481272
481147
|
if (isCircular) {
|
|
481273
481148
|
const radius = getRadiusOfCircuitJsonElement(obj);
|
|
481274
|
-
const
|
|
481275
|
-
const gap2 =
|
|
481149
|
+
const distance32 = segmentToCircleMinDistance({ x: segmentA.x1, y: segmentA.y1 }, { x: segmentA.x2, y: segmentA.y2 }, { x: obj.x, y: obj.y, radius });
|
|
481150
|
+
const gap2 = distance32 - segmentA.thickness / 2;
|
|
481276
481151
|
if (gap2 > DEFAULT_TRACE_MARGIN - EPSILON4)
|
|
481277
481152
|
continue;
|
|
481278
481153
|
const pcb_trace_error_id = `overlap_${segmentA.pcb_trace_id}_${primaryObjId}`;
|
|
@@ -481296,7 +481171,7 @@ function checkEachPcbTraceNonOverlapping(circuitJson, {
|
|
|
481296
481171
|
].filter(Boolean)
|
|
481297
481172
|
});
|
|
481298
481173
|
}
|
|
481299
|
-
const gap =
|
|
481174
|
+
const gap = segmentToBoundsMinDistance({ x: segmentA.x1, y: segmentA.y1 }, { x: segmentA.x2, y: segmentA.y2 }, getCollidableBounds(obj)) - segmentA.thickness / 2;
|
|
481300
481175
|
if (gap + EPSILON4 < requiredMargin) {
|
|
481301
481176
|
const pcb_trace_error_id = `overlap_${segmentA.pcb_trace_id}_${primaryObjId}`;
|
|
481302
481177
|
if (errorIds.has(pcb_trace_error_id))
|
|
@@ -482231,8 +482106,8 @@ var PinBuilder = class {
|
|
|
482231
482106
|
};
|
|
482232
482107
|
pathfinder.addObstacle(obstacle);
|
|
482233
482108
|
}
|
|
482234
|
-
const
|
|
482235
|
-
if (
|
|
482109
|
+
const distance6 = Math.abs(targetX - this.x) + Math.abs(targetY - this.y);
|
|
482110
|
+
if (distance6 < 10) {
|
|
482236
482111
|
const path21 = pathfinder.findPath(currentPos, targetPos);
|
|
482237
482112
|
if (path21.length > 0) {
|
|
482238
482113
|
for (let i = 1;i < path21.length; i++) {
|
|
@@ -484304,9 +484179,9 @@ function findBestPinToRemove(params2) {
|
|
|
484304
484179
|
pinNumber: pin.pinNumber
|
|
484305
484180
|
};
|
|
484306
484181
|
applyEditOperation(testTemplate, testOp);
|
|
484307
|
-
const
|
|
484308
|
-
if (
|
|
484309
|
-
bestDistance =
|
|
484182
|
+
const distance6 = computeSimilarityDistanceAfterRemoval(testTemplate, target);
|
|
484183
|
+
if (distance6 < bestDistance) {
|
|
484184
|
+
bestDistance = distance6;
|
|
484310
484185
|
bestPinNumber = pin.pinNumber;
|
|
484311
484186
|
}
|
|
484312
484187
|
} catch (error) {
|
|
@@ -495909,9 +495784,648 @@ var registerBuild = (program3) => {
|
|
|
495909
495784
|
import fs24 from "node:fs";
|
|
495910
495785
|
import path24 from "node:path";
|
|
495911
495786
|
init_dist6();
|
|
495787
|
+
|
|
495788
|
+
// node_modules/circuit-json-to-simple-3d/dist/index.js
|
|
495789
|
+
init_dist4();
|
|
495790
|
+
|
|
495791
|
+
// node_modules/@tscircuit/simple-3d-svg/dist/index.js
|
|
495792
|
+
var stlCache = /* @__PURE__ */ new Map;
|
|
495793
|
+
async function loadSTL(url) {
|
|
495794
|
+
if (stlCache.has(url)) {
|
|
495795
|
+
return stlCache.get(url);
|
|
495796
|
+
}
|
|
495797
|
+
const response = await fetch(url);
|
|
495798
|
+
const buffer = await response.arrayBuffer();
|
|
495799
|
+
const mesh = parseSTL(buffer);
|
|
495800
|
+
stlCache.set(url, mesh);
|
|
495801
|
+
return mesh;
|
|
495802
|
+
}
|
|
495803
|
+
function parseSTL(buffer) {
|
|
495804
|
+
const view = new DataView(buffer);
|
|
495805
|
+
const header = new TextDecoder().decode(buffer.slice(0, 5));
|
|
495806
|
+
if (header.toLowerCase() === "solid") {
|
|
495807
|
+
return parseASCIISTL(buffer);
|
|
495808
|
+
} else {
|
|
495809
|
+
return parseBinarySTL(view);
|
|
495810
|
+
}
|
|
495811
|
+
}
|
|
495812
|
+
function parseASCIISTL(buffer) {
|
|
495813
|
+
const text = new TextDecoder().decode(buffer);
|
|
495814
|
+
const lines = text.split(`
|
|
495815
|
+
`).map((line) => line.trim());
|
|
495816
|
+
const triangles = [];
|
|
495817
|
+
let i = 0;
|
|
495818
|
+
while (i < lines.length) {
|
|
495819
|
+
const line = lines[i];
|
|
495820
|
+
if (line && line.startsWith("facet normal")) {
|
|
495821
|
+
const normalMatch = line.match(/facet normal\s+([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)\s+([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)\s+([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)/);
|
|
495822
|
+
const normal = normalMatch ? {
|
|
495823
|
+
x: parseFloat(normalMatch[1]),
|
|
495824
|
+
y: parseFloat(normalMatch[2]),
|
|
495825
|
+
z: parseFloat(normalMatch[3])
|
|
495826
|
+
} : { x: 0, y: 0, z: 1 };
|
|
495827
|
+
i++;
|
|
495828
|
+
const vertices = [];
|
|
495829
|
+
while (i < lines.length && lines[i] && !lines[i].startsWith("endfacet")) {
|
|
495830
|
+
const vertexLine = lines[i];
|
|
495831
|
+
if (vertexLine.startsWith("vertex")) {
|
|
495832
|
+
const vertexMatch = vertexLine.match(/vertex\s+([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)\s+([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)\s+([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)/);
|
|
495833
|
+
if (vertexMatch) {
|
|
495834
|
+
vertices.push({
|
|
495835
|
+
x: parseFloat(vertexMatch[1]),
|
|
495836
|
+
y: parseFloat(vertexMatch[2]),
|
|
495837
|
+
z: parseFloat(vertexMatch[3])
|
|
495838
|
+
});
|
|
495839
|
+
}
|
|
495840
|
+
}
|
|
495841
|
+
i++;
|
|
495842
|
+
}
|
|
495843
|
+
if (vertices.length === 3) {
|
|
495844
|
+
triangles.push({
|
|
495845
|
+
vertices: [vertices[0], vertices[1], vertices[2]],
|
|
495846
|
+
normal
|
|
495847
|
+
});
|
|
495848
|
+
}
|
|
495849
|
+
}
|
|
495850
|
+
i++;
|
|
495851
|
+
}
|
|
495852
|
+
return {
|
|
495853
|
+
triangles,
|
|
495854
|
+
boundingBox: calculateBoundingBox(triangles)
|
|
495855
|
+
};
|
|
495856
|
+
}
|
|
495857
|
+
function parseBinarySTL(view) {
|
|
495858
|
+
let offset = 80;
|
|
495859
|
+
const numTriangles = view.getUint32(offset, true);
|
|
495860
|
+
offset += 4;
|
|
495861
|
+
const triangles = [];
|
|
495862
|
+
for (let i = 0;i < numTriangles; i++) {
|
|
495863
|
+
const normal = {
|
|
495864
|
+
x: view.getFloat32(offset, true),
|
|
495865
|
+
y: view.getFloat32(offset + 4, true),
|
|
495866
|
+
z: view.getFloat32(offset + 8, true)
|
|
495867
|
+
};
|
|
495868
|
+
offset += 12;
|
|
495869
|
+
const vertices = [
|
|
495870
|
+
{
|
|
495871
|
+
x: view.getFloat32(offset, true),
|
|
495872
|
+
y: view.getFloat32(offset + 4, true),
|
|
495873
|
+
z: view.getFloat32(offset + 8, true)
|
|
495874
|
+
},
|
|
495875
|
+
{
|
|
495876
|
+
x: view.getFloat32(offset + 12, true),
|
|
495877
|
+
y: view.getFloat32(offset + 16, true),
|
|
495878
|
+
z: view.getFloat32(offset + 20, true)
|
|
495879
|
+
},
|
|
495880
|
+
{
|
|
495881
|
+
x: view.getFloat32(offset + 24, true),
|
|
495882
|
+
y: view.getFloat32(offset + 28, true),
|
|
495883
|
+
z: view.getFloat32(offset + 32, true)
|
|
495884
|
+
}
|
|
495885
|
+
];
|
|
495886
|
+
offset += 36;
|
|
495887
|
+
offset += 2;
|
|
495888
|
+
triangles.push({ vertices, normal });
|
|
495889
|
+
}
|
|
495890
|
+
return {
|
|
495891
|
+
triangles,
|
|
495892
|
+
boundingBox: calculateBoundingBox(triangles)
|
|
495893
|
+
};
|
|
495894
|
+
}
|
|
495895
|
+
function calculateBoundingBox(triangles) {
|
|
495896
|
+
if (triangles.length === 0) {
|
|
495897
|
+
return {
|
|
495898
|
+
min: { x: 0, y: 0, z: 0 },
|
|
495899
|
+
max: { x: 0, y: 0, z: 0 }
|
|
495900
|
+
};
|
|
495901
|
+
}
|
|
495902
|
+
let minX = Infinity, minY = Infinity, minZ = Infinity;
|
|
495903
|
+
let maxX = -Infinity, maxY = -Infinity, maxZ = -Infinity;
|
|
495904
|
+
for (const triangle of triangles) {
|
|
495905
|
+
for (const vertex of triangle.vertices) {
|
|
495906
|
+
minX = Math.min(minX, vertex.x);
|
|
495907
|
+
minY = Math.min(minY, vertex.y);
|
|
495908
|
+
minZ = Math.min(minZ, vertex.z);
|
|
495909
|
+
maxX = Math.max(maxX, vertex.x);
|
|
495910
|
+
maxY = Math.max(maxY, vertex.y);
|
|
495911
|
+
maxZ = Math.max(maxZ, vertex.z);
|
|
495912
|
+
}
|
|
495913
|
+
}
|
|
495914
|
+
return {
|
|
495915
|
+
min: { x: minX, y: minY, z: minZ },
|
|
495916
|
+
max: { x: maxX, y: maxY, z: maxZ }
|
|
495917
|
+
};
|
|
495918
|
+
}
|
|
495919
|
+
function colorToCss(c) {
|
|
495920
|
+
return typeof c === "string" ? c : `rgba(${c[0]},${c[1]},${c[2]},${c[3]})`;
|
|
495921
|
+
}
|
|
495922
|
+
function add(a, b) {
|
|
495923
|
+
return { x: a.x + b.x, y: a.y + b.y, z: a.z + b.z };
|
|
495924
|
+
}
|
|
495925
|
+
function sub(a, b) {
|
|
495926
|
+
return { x: a.x - b.x, y: a.y - b.y, z: a.z - b.z };
|
|
495927
|
+
}
|
|
495928
|
+
function dot(a, b) {
|
|
495929
|
+
return a.x * b.x + a.y * b.y + a.z * b.z;
|
|
495930
|
+
}
|
|
495931
|
+
function cross3(a, b) {
|
|
495932
|
+
return {
|
|
495933
|
+
x: a.y * b.z - a.z * b.y,
|
|
495934
|
+
y: a.z * b.x - a.x * b.z,
|
|
495935
|
+
z: a.x * b.y - a.y * b.x
|
|
495936
|
+
};
|
|
495937
|
+
}
|
|
495938
|
+
function scale9(v, k) {
|
|
495939
|
+
return { x: v.x * k, y: v.y * k, z: v.z * k };
|
|
495940
|
+
}
|
|
495941
|
+
function len(v) {
|
|
495942
|
+
return Math.sqrt(dot(v, v));
|
|
495943
|
+
}
|
|
495944
|
+
function norm(v) {
|
|
495945
|
+
const l = len(v) || 1;
|
|
495946
|
+
return scale9(v, 1 / l);
|
|
495947
|
+
}
|
|
495948
|
+
function rotLocal(p, r = { x: 0, y: 0, z: 0 }) {
|
|
495949
|
+
let { x, y, z: z3 } = p;
|
|
495950
|
+
if (r.x) {
|
|
495951
|
+
const c = Math.cos(r.x);
|
|
495952
|
+
const s = Math.sin(r.x);
|
|
495953
|
+
const y2 = y * c - z3 * s;
|
|
495954
|
+
z3 = y * s + z3 * c;
|
|
495955
|
+
y = y2;
|
|
495956
|
+
}
|
|
495957
|
+
if (r.y) {
|
|
495958
|
+
const c = Math.cos(r.y);
|
|
495959
|
+
const s = Math.sin(r.y);
|
|
495960
|
+
const x2 = x * c + z3 * s;
|
|
495961
|
+
z3 = -x * s + z3 * c;
|
|
495962
|
+
x = x2;
|
|
495963
|
+
}
|
|
495964
|
+
if (r.z) {
|
|
495965
|
+
const c = Math.cos(r.z);
|
|
495966
|
+
const s = Math.sin(r.z);
|
|
495967
|
+
const x2 = x * c - y * s;
|
|
495968
|
+
y = x * s + y * c;
|
|
495969
|
+
x = x2;
|
|
495970
|
+
}
|
|
495971
|
+
return { x, y, z: z3 };
|
|
495972
|
+
}
|
|
495973
|
+
var W_DEF = 400;
|
|
495974
|
+
var H_DEF = 400;
|
|
495975
|
+
var FOCAL = 2;
|
|
495976
|
+
function axes(cam) {
|
|
495977
|
+
const f = norm(sub(cam.lookAt, cam.position));
|
|
495978
|
+
const wUp = { x: 0, y: 1, z: 0 };
|
|
495979
|
+
let r = norm(cross3(f, wUp));
|
|
495980
|
+
if (!len(r))
|
|
495981
|
+
r = { x: 1, y: 0, z: 0 };
|
|
495982
|
+
const u = cross3(r, f);
|
|
495983
|
+
return { r, u, f };
|
|
495984
|
+
}
|
|
495985
|
+
function toCam(p, cam) {
|
|
495986
|
+
const { r, u, f } = axes(cam);
|
|
495987
|
+
const d = sub(p, cam.position);
|
|
495988
|
+
return { x: dot(d, r), y: dot(d, u), z: dot(d, f) };
|
|
495989
|
+
}
|
|
495990
|
+
function proj(p, w, h, focal) {
|
|
495991
|
+
if (p.z <= 0)
|
|
495992
|
+
return null;
|
|
495993
|
+
const s = focal / p.z;
|
|
495994
|
+
return { x: p.x * s * w / 2, y: -p.y * s * h / 2, z: p.z };
|
|
495995
|
+
}
|
|
495996
|
+
var FACES = [
|
|
495997
|
+
[0, 1, 2, 3],
|
|
495998
|
+
[4, 5, 6, 7],
|
|
495999
|
+
[0, 1, 5, 4],
|
|
496000
|
+
[3, 2, 6, 7],
|
|
496001
|
+
[1, 2, 6, 5],
|
|
496002
|
+
[0, 3, 7, 4]
|
|
496003
|
+
];
|
|
496004
|
+
var TOP = [3, 2, 6, 7];
|
|
496005
|
+
function verts(b) {
|
|
496006
|
+
const {
|
|
496007
|
+
size: { x: sx, y: sy, z: sz },
|
|
496008
|
+
center,
|
|
496009
|
+
rotation: rotation4
|
|
496010
|
+
} = b;
|
|
496011
|
+
const offs = [
|
|
496012
|
+
{ x: -sx / 2, y: -sy / 2, z: -sz / 2 },
|
|
496013
|
+
{ x: sx / 2, y: -sy / 2, z: -sz / 2 },
|
|
496014
|
+
{ x: sx / 2, y: sy / 2, z: -sz / 2 },
|
|
496015
|
+
{ x: -sx / 2, y: sy / 2, z: -sz / 2 },
|
|
496016
|
+
{ x: -sx / 2, y: -sy / 2, z: sz / 2 },
|
|
496017
|
+
{ x: sx / 2, y: -sy / 2, z: sz / 2 },
|
|
496018
|
+
{ x: sx / 2, y: sy / 2, z: sz / 2 },
|
|
496019
|
+
{ x: -sx / 2, y: sy / 2, z: sz / 2 }
|
|
496020
|
+
];
|
|
496021
|
+
return offs.map((o) => add(center, rotLocal(o, rotation4)));
|
|
496022
|
+
}
|
|
496023
|
+
function inv3(m2) {
|
|
496024
|
+
const a = m2[0][0], d = m2[0][1], g = m2[0][2];
|
|
496025
|
+
const b = m2[1][0], e = m2[1][1], h = m2[1][2];
|
|
496026
|
+
const c = m2[2][0], f = m2[2][1], i = m2[2][2];
|
|
496027
|
+
const A = e * i - f * h;
|
|
496028
|
+
const B = -(d * i - f * g);
|
|
496029
|
+
const C = d * h - e * g;
|
|
496030
|
+
const D = -(b * i - c * h);
|
|
496031
|
+
const E = a * i - c * g;
|
|
496032
|
+
const F = -(a * h - b * g);
|
|
496033
|
+
const G = b * f - c * e;
|
|
496034
|
+
const H = -(a * f - c * d);
|
|
496035
|
+
const I = a * e - b * d;
|
|
496036
|
+
const det = a * A + d * D + g * G;
|
|
496037
|
+
const invDet = det ? 1 / det : 0;
|
|
496038
|
+
return [
|
|
496039
|
+
[A * invDet, B * invDet, C * invDet],
|
|
496040
|
+
[D * invDet, E * invDet, F * invDet],
|
|
496041
|
+
[G * invDet, H * invDet, I * invDet]
|
|
496042
|
+
];
|
|
496043
|
+
}
|
|
496044
|
+
function mul3(a, b) {
|
|
496045
|
+
const r = [
|
|
496046
|
+
[0, 0, 0],
|
|
496047
|
+
[0, 0, 0],
|
|
496048
|
+
[0, 0, 0]
|
|
496049
|
+
];
|
|
496050
|
+
for (let i = 0;i < 3; i++) {
|
|
496051
|
+
for (let j = 0;j < 3; j++) {
|
|
496052
|
+
r[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j] + a[i][2] * b[2][j];
|
|
496053
|
+
}
|
|
496054
|
+
}
|
|
496055
|
+
return r;
|
|
496056
|
+
}
|
|
496057
|
+
function affineMatrix(src, dst) {
|
|
496058
|
+
const S = [
|
|
496059
|
+
[src[0].x, src[1].x, src[2].x],
|
|
496060
|
+
[src[0].y, src[1].y, src[2].y],
|
|
496061
|
+
[1, 1, 1]
|
|
496062
|
+
];
|
|
496063
|
+
const D = [
|
|
496064
|
+
[dst[0].x, dst[1].x, dst[2].x],
|
|
496065
|
+
[dst[0].y, dst[1].y, dst[2].y],
|
|
496066
|
+
[1, 1, 1]
|
|
496067
|
+
];
|
|
496068
|
+
const M = mul3(D, inv3(S));
|
|
496069
|
+
return `matrix(${M[0][0]} ${M[1][0]} ${M[0][1]} ${M[1][1]} ${M[0][2]} ${M[1][2]})`;
|
|
496070
|
+
}
|
|
496071
|
+
function scaleAndPositionMesh(mesh, box) {
|
|
496072
|
+
const { boundingBox } = mesh;
|
|
496073
|
+
const meshSize = sub(boundingBox.max, boundingBox.min);
|
|
496074
|
+
const boxSize = box.size;
|
|
496075
|
+
const scaleX = boxSize.x / meshSize.x;
|
|
496076
|
+
const scaleY = boxSize.y / meshSize.y;
|
|
496077
|
+
const scaleZ = boxSize.z / meshSize.z;
|
|
496078
|
+
const uniformScale = Math.min(scaleX, scaleY, scaleZ);
|
|
496079
|
+
const meshCenter = scale9(add(boundingBox.min, boundingBox.max), 0.5);
|
|
496080
|
+
const transformedVertices = [];
|
|
496081
|
+
for (const triangle of mesh.triangles) {
|
|
496082
|
+
for (const vertex of triangle.vertices) {
|
|
496083
|
+
let transformed = sub(vertex, meshCenter);
|
|
496084
|
+
transformed = scale9(transformed, uniformScale);
|
|
496085
|
+
if (box.stlRotation) {
|
|
496086
|
+
transformed = rotLocal(transformed, box.stlRotation);
|
|
496087
|
+
}
|
|
496088
|
+
if (box.stlPosition) {
|
|
496089
|
+
transformed = add(transformed, box.stlPosition);
|
|
496090
|
+
}
|
|
496091
|
+
if (box.rotation) {
|
|
496092
|
+
transformed = rotLocal(transformed, box.rotation);
|
|
496093
|
+
}
|
|
496094
|
+
transformed = add(transformed, box.center);
|
|
496095
|
+
transformedVertices.push(transformed);
|
|
496096
|
+
}
|
|
496097
|
+
}
|
|
496098
|
+
return transformedVertices;
|
|
496099
|
+
}
|
|
496100
|
+
async function renderScene(scene, opt = {}) {
|
|
496101
|
+
const W = opt.width ?? W_DEF;
|
|
496102
|
+
const H = opt.height ?? H_DEF;
|
|
496103
|
+
const focal = scene.camera.focalLength ?? FOCAL;
|
|
496104
|
+
const faces = [];
|
|
496105
|
+
const images = [];
|
|
496106
|
+
const labels = [];
|
|
496107
|
+
let clipSeq = 0;
|
|
496108
|
+
const texId = /* @__PURE__ */ new Map;
|
|
496109
|
+
const stlMeshes = /* @__PURE__ */ new Map;
|
|
496110
|
+
for (const box of scene.boxes) {
|
|
496111
|
+
if (box.stlUrl && !stlMeshes.has(box.stlUrl)) {
|
|
496112
|
+
try {
|
|
496113
|
+
const mesh = await loadSTL(box.stlUrl);
|
|
496114
|
+
stlMeshes.set(box.stlUrl, mesh);
|
|
496115
|
+
} catch (error) {
|
|
496116
|
+
console.warn(`Failed to load STL from ${box.stlUrl}:`, error);
|
|
496117
|
+
}
|
|
496118
|
+
}
|
|
496119
|
+
}
|
|
496120
|
+
for (const box of scene.boxes) {
|
|
496121
|
+
if (box.stlUrl && stlMeshes.has(box.stlUrl)) {
|
|
496122
|
+
const mesh = stlMeshes.get(box.stlUrl);
|
|
496123
|
+
const transformedVertices = scaleAndPositionMesh(mesh, box);
|
|
496124
|
+
for (let i = 0;i < mesh.triangles.length; i++) {
|
|
496125
|
+
const triangle = mesh.triangles[i];
|
|
496126
|
+
const vertexStart = i * 3;
|
|
496127
|
+
const v0w = transformedVertices[vertexStart];
|
|
496128
|
+
const v1w = transformedVertices[vertexStart + 1];
|
|
496129
|
+
const v2w = transformedVertices[vertexStart + 2];
|
|
496130
|
+
const v0c = toCam(v0w, scene.camera);
|
|
496131
|
+
const v1c = toCam(v1w, scene.camera);
|
|
496132
|
+
const v2c = toCam(v2w, scene.camera);
|
|
496133
|
+
const v0p = proj(v0c, W, H, focal);
|
|
496134
|
+
const v1p = proj(v1c, W, H, focal);
|
|
496135
|
+
const v2p = proj(v2c, W, H, focal);
|
|
496136
|
+
if (v0p && v1p && v2p) {
|
|
496137
|
+
const edge1 = sub(v1c, v0c);
|
|
496138
|
+
const edge2 = sub(v2c, v0c);
|
|
496139
|
+
const faceNormal = cross3(edge1, edge2);
|
|
496140
|
+
if (faceNormal.z < 0) {
|
|
496141
|
+
const depth = Math.max(v0c.z, v1c.z, v2c.z);
|
|
496142
|
+
faces.push({
|
|
496143
|
+
pts: [v0p, v1p, v2p],
|
|
496144
|
+
depth,
|
|
496145
|
+
fill: colorToCss(box.color)
|
|
496146
|
+
});
|
|
496147
|
+
}
|
|
496148
|
+
}
|
|
496149
|
+
}
|
|
496150
|
+
} else {
|
|
496151
|
+
const vw = verts(box);
|
|
496152
|
+
const vc = vw.map((v) => toCam(v, scene.camera));
|
|
496153
|
+
const vp = vc.map((v) => proj(v, W, H, focal));
|
|
496154
|
+
for (const idx of FACES) {
|
|
496155
|
+
const p4 = [];
|
|
496156
|
+
let zMax = -Infinity;
|
|
496157
|
+
let behind = false;
|
|
496158
|
+
for (const i of idx) {
|
|
496159
|
+
const p = vp[i];
|
|
496160
|
+
if (!p) {
|
|
496161
|
+
behind = true;
|
|
496162
|
+
break;
|
|
496163
|
+
}
|
|
496164
|
+
p4.push(p);
|
|
496165
|
+
zMax = Math.max(zMax, vc[i].z);
|
|
496166
|
+
}
|
|
496167
|
+
if (behind)
|
|
496168
|
+
continue;
|
|
496169
|
+
const [a, b, c] = idx;
|
|
496170
|
+
const n2 = cross3(sub(vc[b], vc[a]), sub(vc[c], vc[a]));
|
|
496171
|
+
if (n2.z >= 0)
|
|
496172
|
+
continue;
|
|
496173
|
+
faces.push({
|
|
496174
|
+
pts: p4,
|
|
496175
|
+
depth: zMax,
|
|
496176
|
+
fill: colorToCss(box.color)
|
|
496177
|
+
});
|
|
496178
|
+
}
|
|
496179
|
+
if (box.faceImages?.top) {
|
|
496180
|
+
const pts = TOP.map((i) => vp[i]);
|
|
496181
|
+
if (pts.every(Boolean)) {
|
|
496182
|
+
const dst = pts;
|
|
496183
|
+
const cz = Math.max(...TOP.map((i) => vc[i].z));
|
|
496184
|
+
const href = box.faceImages.top;
|
|
496185
|
+
if (!texId.has(href)) {
|
|
496186
|
+
texId.set(href, `tex${texId.size}`);
|
|
496187
|
+
}
|
|
496188
|
+
const sym = texId.get(href);
|
|
496189
|
+
const subdivisions = box.projectionSubdivision ?? 2;
|
|
496190
|
+
const quadsPerSide = subdivisions;
|
|
496191
|
+
for (let row = 0;row < quadsPerSide; row++) {
|
|
496192
|
+
for (let col = 0;col < quadsPerSide; col++) {
|
|
496193
|
+
const u0 = col / quadsPerSide;
|
|
496194
|
+
const u1 = (col + 1) / quadsPerSide;
|
|
496195
|
+
const v0 = row / quadsPerSide;
|
|
496196
|
+
const v1 = (row + 1) / quadsPerSide;
|
|
496197
|
+
const lerp = (a, b, t2) => ({
|
|
496198
|
+
x: a.x * (1 - t2) + b.x * t2,
|
|
496199
|
+
y: a.y * (1 - t2) + b.y * t2,
|
|
496200
|
+
z: a.z * (1 - t2) + b.z * t2
|
|
496201
|
+
});
|
|
496202
|
+
const p00 = lerp(lerp(dst[0], dst[1], u0), lerp(dst[3], dst[2], u0), v0);
|
|
496203
|
+
const p10 = lerp(lerp(dst[0], dst[1], u1), lerp(dst[3], dst[2], u1), v0);
|
|
496204
|
+
const p01 = lerp(lerp(dst[0], dst[1], u0), lerp(dst[3], dst[2], u0), v1);
|
|
496205
|
+
const p11 = lerp(lerp(dst[0], dst[1], u1), lerp(dst[3], dst[2], u1), v1);
|
|
496206
|
+
const tri0Mat = affineMatrix([
|
|
496207
|
+
{ x: u0, y: v0 },
|
|
496208
|
+
{ x: u1, y: v0 },
|
|
496209
|
+
{ x: u1, y: v1 }
|
|
496210
|
+
], [p00, p10, p11]);
|
|
496211
|
+
const id0 = `clip${clipSeq++}`;
|
|
496212
|
+
images.push({
|
|
496213
|
+
matrix: tri0Mat,
|
|
496214
|
+
depth: cz,
|
|
496215
|
+
href,
|
|
496216
|
+
clip: id0,
|
|
496217
|
+
points: `${u0},${v0} ${u1},${v0} ${u1},${v1}`,
|
|
496218
|
+
sym
|
|
496219
|
+
});
|
|
496220
|
+
const tri1Mat = affineMatrix([
|
|
496221
|
+
{ x: u0, y: v0 },
|
|
496222
|
+
{ x: u1, y: v1 },
|
|
496223
|
+
{ x: u0, y: v1 }
|
|
496224
|
+
], [p00, p11, p01]);
|
|
496225
|
+
const id1 = `clip${clipSeq++}`;
|
|
496226
|
+
images.push({
|
|
496227
|
+
matrix: tri1Mat,
|
|
496228
|
+
depth: cz,
|
|
496229
|
+
href,
|
|
496230
|
+
clip: id1,
|
|
496231
|
+
points: `${u0},${v0} ${u1},${v1} ${u0},${v1}`,
|
|
496232
|
+
sym
|
|
496233
|
+
});
|
|
496234
|
+
}
|
|
496235
|
+
}
|
|
496236
|
+
}
|
|
496237
|
+
}
|
|
496238
|
+
if (box.topLabel) {
|
|
496239
|
+
const pts = TOP.map((i) => vp[i]);
|
|
496240
|
+
if (pts.every(Boolean)) {
|
|
496241
|
+
const p0 = pts[0];
|
|
496242
|
+
const p1 = pts[1];
|
|
496243
|
+
const p3 = pts[3];
|
|
496244
|
+
const u = sub(p1, p0);
|
|
496245
|
+
const v = sub(p3, p0);
|
|
496246
|
+
const lu = len(u);
|
|
496247
|
+
const lv = len(v);
|
|
496248
|
+
if (lu && lv) {
|
|
496249
|
+
const uN = scale9(u, 1 / lu);
|
|
496250
|
+
const vN = scale9(v, 1 / lv);
|
|
496251
|
+
const cx = pts.reduce((s, p) => s + p.x, 0) / 4;
|
|
496252
|
+
const cy = pts.reduce((s, p) => s + p.y, 0) / 4;
|
|
496253
|
+
const cz = Math.max(...TOP.map((i) => vc[i].z));
|
|
496254
|
+
const m2 = `matrix(${uN.x} ${uN.y} ${vN.x} ${vN.y} ${cx} ${cy})`;
|
|
496255
|
+
const fillCol = box.topLabelColor ?? [0, 0, 0, 1];
|
|
496256
|
+
labels.push({
|
|
496257
|
+
matrix: m2,
|
|
496258
|
+
depth: cz,
|
|
496259
|
+
text: box.topLabel,
|
|
496260
|
+
fill: colorToCss(fillCol)
|
|
496261
|
+
});
|
|
496262
|
+
}
|
|
496263
|
+
}
|
|
496264
|
+
}
|
|
496265
|
+
}
|
|
496266
|
+
}
|
|
496267
|
+
const allElements = [
|
|
496268
|
+
...faces.map((f) => ({ type: "face", data: f })),
|
|
496269
|
+
...images.map((i) => ({ type: "image", data: i })),
|
|
496270
|
+
...labels.map((l) => ({ type: "label", data: l }))
|
|
496271
|
+
];
|
|
496272
|
+
allElements.sort((a, b) => b.data.depth - a.data.depth);
|
|
496273
|
+
const out = [];
|
|
496274
|
+
out.push(`<svg xmlns="http://www.w3.org/2000/svg" width="${W}" height="${H}" viewBox="${-W / 2} ${-H / 2} ${W} ${H}">`);
|
|
496275
|
+
if (opt.backgroundColor) {
|
|
496276
|
+
out.push(` <rect x="${-W / 2}" y="${-H / 2}" width="${W}" height="${H}" fill="${colorToCss(opt.backgroundColor)}" />
|
|
496277
|
+
`);
|
|
496278
|
+
}
|
|
496279
|
+
if (images.length) {
|
|
496280
|
+
out.push(` <defs>
|
|
496281
|
+
`);
|
|
496282
|
+
for (const [href, id] of texId) {
|
|
496283
|
+
out.push(` <image id="${id}" href="${href}" width="1" height="1" preserveAspectRatio="none" style="image-rendering:pixelated"/>
|
|
496284
|
+
`);
|
|
496285
|
+
}
|
|
496286
|
+
for (const img of images) {
|
|
496287
|
+
out.push(` <clipPath id="${img.clip}" clipPathUnits="objectBoundingBox"><polygon points="${img.points}" /></clipPath>
|
|
496288
|
+
`);
|
|
496289
|
+
}
|
|
496290
|
+
out.push(` </defs>
|
|
496291
|
+
`);
|
|
496292
|
+
}
|
|
496293
|
+
let inStrokeGroup = false;
|
|
496294
|
+
for (const element of allElements) {
|
|
496295
|
+
if (element.type === "face" || element.type === "image") {
|
|
496296
|
+
if (!inStrokeGroup) {
|
|
496297
|
+
out.push(` <g stroke="#000" stroke-width="1" stroke-linecap="round" stroke-linejoin="round">
|
|
496298
|
+
`);
|
|
496299
|
+
inStrokeGroup = true;
|
|
496300
|
+
}
|
|
496301
|
+
if (element.type === "face") {
|
|
496302
|
+
const f = element.data;
|
|
496303
|
+
out.push(` <polygon fill="${f.fill}" points="${f.pts.map((p) => `${p.x},${p.y}`).join(" ")}" />
|
|
496304
|
+
`);
|
|
496305
|
+
} else {
|
|
496306
|
+
const img = element.data;
|
|
496307
|
+
out.push(` <g transform="${img.matrix}" clip-path="url(#${img.clip})"><use href="#${img.sym}"/></g>
|
|
496308
|
+
`);
|
|
496309
|
+
}
|
|
496310
|
+
} else if (element.type === "label") {
|
|
496311
|
+
if (inStrokeGroup) {
|
|
496312
|
+
out.push(` </g>
|
|
496313
|
+
`);
|
|
496314
|
+
inStrokeGroup = false;
|
|
496315
|
+
}
|
|
496316
|
+
const l = element.data;
|
|
496317
|
+
out.push(` <g font-family="sans-serif" font-size="14" text-anchor="middle" dominant-baseline="central" transform="${l.matrix}"><text x="0" y="0" fill="${l.fill}">${l.text}</text></g>
|
|
496318
|
+
`);
|
|
496319
|
+
}
|
|
496320
|
+
}
|
|
496321
|
+
if (inStrokeGroup) {
|
|
496322
|
+
out.push(` </g>
|
|
496323
|
+
`);
|
|
496324
|
+
}
|
|
496325
|
+
out.push("</svg>");
|
|
496326
|
+
return out.join("");
|
|
496327
|
+
}
|
|
496328
|
+
|
|
496329
|
+
// node_modules/circuit-json-to-simple-3d/dist/index.js
|
|
496330
|
+
init_dist6();
|
|
496331
|
+
function getDefaultCameraForPcbBoard(pcbBoard, anglePreset = "angle1") {
|
|
496332
|
+
const w = pcbBoard.width;
|
|
496333
|
+
const h = pcbBoard.height;
|
|
496334
|
+
const cx = pcbBoard.center?.x;
|
|
496335
|
+
const cz = pcbBoard.center?.y;
|
|
496336
|
+
const dist = Math.max(w, h) * 1.5;
|
|
496337
|
+
let position4;
|
|
496338
|
+
if (anglePreset === "angle1") {
|
|
496339
|
+
position4 = { x: cx - dist, y: dist, z: cz - dist };
|
|
496340
|
+
} else if (anglePreset === "angle2") {
|
|
496341
|
+
position4 = { x: cx + dist, y: dist, z: cz - dist };
|
|
496342
|
+
} else if (anglePreset === "left") {
|
|
496343
|
+
position4 = { x: cx - dist, y: 0, z: 0 };
|
|
496344
|
+
} else if (anglePreset === "right") {
|
|
496345
|
+
position4 = { x: cx + dist, y: 0, z: 0 };
|
|
496346
|
+
} else if (anglePreset === "left-raised") {
|
|
496347
|
+
position4 = { x: cx - dist, y: dist, z: 0 };
|
|
496348
|
+
} else if (anglePreset === "right-raised") {
|
|
496349
|
+
position4 = { x: cx + dist, y: dist, z: 0 };
|
|
496350
|
+
} else {
|
|
496351
|
+
throw new Error(`Unknown angle preset: ${anglePreset}`);
|
|
496352
|
+
}
|
|
496353
|
+
return {
|
|
496354
|
+
position: position4,
|
|
496355
|
+
lookAt: { x: cx, y: 0, z: cz },
|
|
496356
|
+
focalLength: 2
|
|
496357
|
+
};
|
|
496358
|
+
}
|
|
496359
|
+
async function convertCircuitJsonToSimple3dSvg(circuitJson, opts = {}) {
|
|
496360
|
+
const db = cju_default(circuitJson);
|
|
496361
|
+
const boxes = [];
|
|
496362
|
+
const pcbTopSvg = convertCircuitJsonToPcbSvg(circuitJson, {
|
|
496363
|
+
layer: "top",
|
|
496364
|
+
matchBoardAspectRatio: true,
|
|
496365
|
+
backgroundColor: "transparent",
|
|
496366
|
+
drawPaddingOutsideBoard: false,
|
|
496367
|
+
colorOverrides: {
|
|
496368
|
+
copper: {
|
|
496369
|
+
top: "#ffe066",
|
|
496370
|
+
bottom: "#ffe066"
|
|
496371
|
+
},
|
|
496372
|
+
drill: "rgba(0,0,0,0.5)"
|
|
496373
|
+
}
|
|
496374
|
+
}).replace("<svg", "<svg transform='scale(1, -1)'");
|
|
496375
|
+
const pcbBoard = db.pcb_board.list()[0];
|
|
496376
|
+
if (!pcbBoard)
|
|
496377
|
+
throw new Error("No pcb_board, can't render to 3d");
|
|
496378
|
+
const camera = opts.camera ?? getDefaultCameraForPcbBoard(pcbBoard, opts.anglePreset ?? "angle1");
|
|
496379
|
+
if (!camera.focalLength) {
|
|
496380
|
+
camera.focalLength = 1;
|
|
496381
|
+
}
|
|
496382
|
+
boxes.push({
|
|
496383
|
+
center: {
|
|
496384
|
+
x: pcbBoard.center.x,
|
|
496385
|
+
y: 0,
|
|
496386
|
+
z: pcbBoard.center.y
|
|
496387
|
+
},
|
|
496388
|
+
size: {
|
|
496389
|
+
x: pcbBoard.width,
|
|
496390
|
+
y: pcbBoard.thickness,
|
|
496391
|
+
z: pcbBoard.height
|
|
496392
|
+
},
|
|
496393
|
+
faceImages: {
|
|
496394
|
+
top: `data:image/svg+xml;base64,${btoa(pcbTopSvg)}`
|
|
496395
|
+
},
|
|
496396
|
+
projectionSubdivision: 10,
|
|
496397
|
+
color: "rgba(0,140,0,0.8)"
|
|
496398
|
+
});
|
|
496399
|
+
const DEFAULT_COMP_HEIGHT = 2;
|
|
496400
|
+
for (const comp of db.pcb_component.list()) {
|
|
496401
|
+
const sourceComponent = db.source_component.get(comp.source_component_id);
|
|
496402
|
+
const compHeight = Math.min(Math.min(comp.width, comp.height), DEFAULT_COMP_HEIGHT);
|
|
496403
|
+
boxes.push({
|
|
496404
|
+
center: {
|
|
496405
|
+
x: comp.center.x,
|
|
496406
|
+
y: pcbBoard.thickness / 2 + compHeight / 2,
|
|
496407
|
+
z: comp.center.y
|
|
496408
|
+
},
|
|
496409
|
+
size: {
|
|
496410
|
+
x: comp.width,
|
|
496411
|
+
y: compHeight,
|
|
496412
|
+
z: comp.height
|
|
496413
|
+
},
|
|
496414
|
+
color: "rgba(128,128,128,0.5)",
|
|
496415
|
+
topLabel: sourceComponent?.name ?? "?",
|
|
496416
|
+
topLabelColor: "white"
|
|
496417
|
+
});
|
|
496418
|
+
}
|
|
496419
|
+
return await renderScene({ boxes, camera }, {
|
|
496420
|
+
backgroundColor: "lightgray"
|
|
496421
|
+
});
|
|
496422
|
+
}
|
|
496423
|
+
|
|
496424
|
+
// lib/shared/snapshot-project.ts
|
|
495912
496425
|
var snapshotProject = async ({
|
|
495913
496426
|
update = false,
|
|
495914
496427
|
ignored = [],
|
|
496428
|
+
threeD = false,
|
|
495915
496429
|
onExit = (code) => process.exit(code),
|
|
495916
496430
|
onError = (msg) => console.error(msg),
|
|
495917
496431
|
onSuccess = (msg) => console.log(msg)
|
|
@@ -495938,13 +496452,18 @@ var snapshotProject = async ({
|
|
|
495938
496452
|
const { circuitJson } = await generateCircuitJson({ filePath: file });
|
|
495939
496453
|
const pcbSvg = convertCircuitJsonToPcbSvg(circuitJson);
|
|
495940
496454
|
const schSvg = convertCircuitJsonToSchematicSvg(circuitJson);
|
|
496455
|
+
const svg3d = threeD ? await convertCircuitJsonToSimple3dSvg(circuitJson) : null;
|
|
495941
496456
|
const snapDir = path24.join(path24.dirname(file), "__snapshots__");
|
|
495942
496457
|
fs24.mkdirSync(snapDir, { recursive: true });
|
|
495943
496458
|
const base = path24.basename(file).replace(/\.tsx$/, "");
|
|
495944
|
-
|
|
496459
|
+
const snapshotPairs = [
|
|
495945
496460
|
["pcb", pcbSvg],
|
|
495946
496461
|
["schematic", schSvg]
|
|
495947
|
-
]
|
|
496462
|
+
];
|
|
496463
|
+
if (threeD && svg3d) {
|
|
496464
|
+
snapshotPairs.push(["3d", svg3d]);
|
|
496465
|
+
}
|
|
496466
|
+
for (const [type, svg] of snapshotPairs) {
|
|
495948
496467
|
const snapPath = path24.join(snapDir, `${base}-${type}.snap.svg`);
|
|
495949
496468
|
if (update || !fs24.existsSync(snapPath)) {
|
|
495950
496469
|
fs24.writeFileSync(snapPath, svg);
|
|
@@ -495971,9 +496490,10 @@ ${mismatches.join(`
|
|
|
495971
496490
|
|
|
495972
496491
|
// cli/snapshot/register.ts
|
|
495973
496492
|
var registerSnapshot = (program3) => {
|
|
495974
|
-
program3.command("snapshot").description("Generate schematic and PCB snapshots").option("-u, --update", "Update snapshots on disk").action(async (options) => {
|
|
496493
|
+
program3.command("snapshot").description("Generate schematic and PCB snapshots (add --3d for 3d preview)").option("-u, --update", "Update snapshots on disk").option("--3d", "Generate 3d preview snapshots").action(async (options) => {
|
|
495975
496494
|
await snapshotProject({
|
|
495976
496495
|
update: options.update ?? false,
|
|
496496
|
+
threeD: options["3d"] ?? false,
|
|
495977
496497
|
onExit: (code) => process.exit(code),
|
|
495978
496498
|
onError: (msg) => console.error(msg),
|
|
495979
496499
|
onSuccess: (msg) => console.log(msg)
|