@tscircuit/core 0.0.2300 → 0.0.2302
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +885 -124
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -11356,6 +11356,42 @@ var underscorifyPortArrangement = (portArrangement, pinLabels) => {
|
|
|
11356
11356
|
return void 0;
|
|
11357
11357
|
};
|
|
11358
11358
|
|
|
11359
|
+
// lib/utils/join-imported-courtyard-outlines.ts
|
|
11360
|
+
function joinImportedCourtyardOutlines(courtyards, componentName) {
|
|
11361
|
+
const polygons = /* @__PURE__ */ new Map();
|
|
11362
|
+
const pending = courtyards.filter(
|
|
11363
|
+
(courtyard) => courtyard.outline.length === 2
|
|
11364
|
+
);
|
|
11365
|
+
const samePoint2 = (a2, b2) => Math.hypot(a2.x - b2.x, a2.y - b2.y) < 1e-6;
|
|
11366
|
+
while (pending.length) {
|
|
11367
|
+
const first = pending.shift();
|
|
11368
|
+
const outline = [...first.outline];
|
|
11369
|
+
while (!samePoint2(outline[0], outline.at(-1))) {
|
|
11370
|
+
const end = outline.at(-1);
|
|
11371
|
+
const nextIndex = pending.findIndex(
|
|
11372
|
+
(candidate) => candidate.pcb_component_id === first.pcb_component_id && candidate.layer === first.layer && candidate.outline.some((point8) => samePoint2(point8, end))
|
|
11373
|
+
);
|
|
11374
|
+
if (nextIndex === -1) {
|
|
11375
|
+
throw new Error(
|
|
11376
|
+
`Imported courtyard for "${componentName}" has disconnected line segments; provide a complete closed polygon.`
|
|
11377
|
+
);
|
|
11378
|
+
}
|
|
11379
|
+
const [next] = pending.splice(nextIndex, 1);
|
|
11380
|
+
outline.push(
|
|
11381
|
+
samePoint2(next.outline[0], end) ? next.outline[1] : next.outline[0]
|
|
11382
|
+
);
|
|
11383
|
+
}
|
|
11384
|
+
outline.pop();
|
|
11385
|
+
if (outline.length < 3) {
|
|
11386
|
+
throw new Error(
|
|
11387
|
+
`Imported courtyard for "${componentName}" needs at least three polygon vertices.`
|
|
11388
|
+
);
|
|
11389
|
+
}
|
|
11390
|
+
polygons.set(first, outline);
|
|
11391
|
+
}
|
|
11392
|
+
return polygons;
|
|
11393
|
+
}
|
|
11394
|
+
|
|
11359
11395
|
// lib/utils/createComponentsFromCircuitJson.ts
|
|
11360
11396
|
import { getUnitVectorFromDirection as getUnitVectorFromDirection2 } from "@tscircuit/math-utils";
|
|
11361
11397
|
import {
|
|
@@ -15829,6 +15865,10 @@ var createComponentsFromCircuitJson = ({
|
|
|
15829
15865
|
pcbPinLabels,
|
|
15830
15866
|
preserveSolderPaste = false
|
|
15831
15867
|
}, circuitJson) => {
|
|
15868
|
+
const joinedCourtyards = joinImportedCourtyardOutlines(
|
|
15869
|
+
circuitJson.filter((elm) => elm.type === "pcb_courtyard_outline"),
|
|
15870
|
+
componentName
|
|
15871
|
+
);
|
|
15832
15872
|
const importedSourcePorts = circuitJson.filter(
|
|
15833
15873
|
(elm) => elm.type === "source_port"
|
|
15834
15874
|
);
|
|
@@ -16540,9 +16580,11 @@ var createComponentsFromCircuitJson = ({
|
|
|
16540
16580
|
})
|
|
16541
16581
|
);
|
|
16542
16582
|
} else if (elm.type === "pcb_courtyard_outline") {
|
|
16583
|
+
const outline = elm.outline.length === 2 ? joinedCourtyards.get(elm) : elm.outline;
|
|
16584
|
+
if (!outline) continue;
|
|
16543
16585
|
components.push(
|
|
16544
16586
|
new CourtyardOutline({
|
|
16545
|
-
outline
|
|
16587
|
+
outline,
|
|
16546
16588
|
layer: elm.layer
|
|
16547
16589
|
})
|
|
16548
16590
|
);
|
|
@@ -22331,7 +22373,7 @@ function intersectsObstacle(points, obstacle, depth = 0) {
|
|
|
22331
22373
|
// lib/utils/system-blocks/round-system-block-route.ts
|
|
22332
22374
|
import { applyToPoint as applyToPoint33, compose as compose9, rotate as rotate4, translate as translate7 } from "transformation-matrix";
|
|
22333
22375
|
var EPSILON = 1e-8;
|
|
22334
|
-
function roundSystemBlockRoute(route, obstacles) {
|
|
22376
|
+
function roundSystemBlockRoute(route, obstacles, wireObstacles = []) {
|
|
22335
22377
|
const points = [];
|
|
22336
22378
|
for (const point8 of route) {
|
|
22337
22379
|
if (points.length && distance9(points.at(-1), point8) < EPSILON) continue;
|
|
@@ -22356,6 +22398,27 @@ function roundSystemBlockRoute(route, obstacles) {
|
|
|
22356
22398
|
const previous = points[index2 - 1];
|
|
22357
22399
|
const corner = points[index2];
|
|
22358
22400
|
const next = points[index2 + 1];
|
|
22401
|
+
const cornerObstacles = [
|
|
22402
|
+
...obstacles,
|
|
22403
|
+
...wireObstacles.map((wire) => {
|
|
22404
|
+
const clearance = Math.min(
|
|
22405
|
+
3,
|
|
22406
|
+
Math.max(
|
|
22407
|
+
0,
|
|
22408
|
+
wire.minX - corner.x,
|
|
22409
|
+
corner.x - wire.maxX,
|
|
22410
|
+
wire.minY - corner.y,
|
|
22411
|
+
corner.y - wire.maxY
|
|
22412
|
+
)
|
|
22413
|
+
);
|
|
22414
|
+
return {
|
|
22415
|
+
minX: wire.minX - clearance,
|
|
22416
|
+
maxX: wire.maxX + clearance,
|
|
22417
|
+
minY: wire.minY - clearance,
|
|
22418
|
+
maxY: wire.maxY + clearance
|
|
22419
|
+
};
|
|
22420
|
+
})
|
|
22421
|
+
];
|
|
22359
22422
|
const incoming = unitDirection(previous, corner);
|
|
22360
22423
|
const outgoing = unitDirection(corner, next);
|
|
22361
22424
|
const turn = Math.atan2(
|
|
@@ -22384,7 +22447,7 @@ function roundSystemBlockRoute(route, obstacles) {
|
|
|
22384
22447
|
const maxX = Math.max(start.x, corner.x, end.x);
|
|
22385
22448
|
const minY = Math.min(start.y, corner.y, end.y);
|
|
22386
22449
|
const maxY = Math.max(start.y, corner.y, end.y);
|
|
22387
|
-
const blocked =
|
|
22450
|
+
const blocked = cornerObstacles.some(
|
|
22388
22451
|
(obstacle) => minX < obstacle.maxX && maxX > obstacle.minX && minY < obstacle.maxY && maxY > obstacle.minY
|
|
22389
22452
|
);
|
|
22390
22453
|
if (!blocked || trim < 1e-3) break;
|
|
@@ -22439,103 +22502,744 @@ function unitDirection(a2, b2) {
|
|
|
22439
22502
|
return { x: (b2.x - a2.x) / length9, y: (b2.y - a2.y) / length9 };
|
|
22440
22503
|
}
|
|
22441
22504
|
|
|
22442
|
-
// lib/utils/system-blocks/
|
|
22443
|
-
function
|
|
22444
|
-
|
|
22445
|
-
|
|
22446
|
-
|
|
22447
|
-
|
|
22448
|
-
|
|
22449
|
-
|
|
22450
|
-
|
|
22451
|
-
|
|
22452
|
-
|
|
22453
|
-
|
|
22454
|
-
|
|
22455
|
-
|
|
22456
|
-
|
|
22457
|
-
|
|
22458
|
-
|
|
22459
|
-
|
|
22460
|
-
|
|
22461
|
-
|
|
22462
|
-
|
|
22463
|
-
|
|
22464
|
-
|
|
22465
|
-
|
|
22466
|
-
|
|
22467
|
-
|
|
22468
|
-
|
|
22505
|
+
// lib/utils/system-blocks/measure-system-route-quality.ts
|
|
22506
|
+
function measureSystemRouteQuality(routes) {
|
|
22507
|
+
let crossings = 0;
|
|
22508
|
+
let sharedLength = 0;
|
|
22509
|
+
let closeParallelLength = 0;
|
|
22510
|
+
let length9 = 0;
|
|
22511
|
+
let bends = 0;
|
|
22512
|
+
const segments = routes.map(
|
|
22513
|
+
(route) => route.slice(1).map((end, index2) => {
|
|
22514
|
+
const start = route[index2];
|
|
22515
|
+
length9 += Math.abs(end.x - start.x) + Math.abs(end.y - start.y);
|
|
22516
|
+
return { start, end, horizontal: start.y === end.y };
|
|
22517
|
+
})
|
|
22518
|
+
);
|
|
22519
|
+
for (const route of routes) bends += Math.max(0, route.length - 2);
|
|
22520
|
+
for (let i2 = 0; i2 < segments.length; i2++) {
|
|
22521
|
+
for (let j2 = i2 + 1; j2 < segments.length; j2++) {
|
|
22522
|
+
const intersections2 = /* @__PURE__ */ new Set();
|
|
22523
|
+
for (const a2 of segments[i2])
|
|
22524
|
+
for (const b2 of segments[j2]) {
|
|
22525
|
+
if (a2.horizontal === b2.horizontal) {
|
|
22526
|
+
const along2 = a2.horizontal ? "x" : "y";
|
|
22527
|
+
const across = a2.horizontal ? "y" : "x";
|
|
22528
|
+
const overlap = Math.min(
|
|
22529
|
+
Math.max(a2.start[along2], a2.end[along2]),
|
|
22530
|
+
Math.max(b2.start[along2], b2.end[along2])
|
|
22531
|
+
) - Math.max(
|
|
22532
|
+
Math.min(a2.start[along2], a2.end[along2]),
|
|
22533
|
+
Math.min(b2.start[along2], b2.end[along2])
|
|
22534
|
+
);
|
|
22535
|
+
if (overlap <= 1e-6) continue;
|
|
22536
|
+
const separation = Math.abs(a2.start[across] - b2.start[across]);
|
|
22537
|
+
if (separation < 1e-6) sharedLength += overlap;
|
|
22538
|
+
if (separation < 3 - 1e-6)
|
|
22539
|
+
closeParallelLength += overlap * (3 - separation) / 3;
|
|
22540
|
+
} else {
|
|
22541
|
+
const h2 = a2.horizontal ? a2 : b2, v2 = a2.horizontal ? b2 : a2;
|
|
22542
|
+
const x2 = v2.start.x, y2 = h2.start.y;
|
|
22543
|
+
if (x2 >= Math.min(h2.start.x, h2.end.x) - 1e-6 && x2 <= Math.max(h2.start.x, h2.end.x) + 1e-6 && y2 >= Math.min(v2.start.y, v2.end.y) - 1e-6 && y2 <= Math.max(v2.start.y, v2.end.y) + 1e-6) {
|
|
22544
|
+
intersections2.add(`${x2.toFixed(6)},${y2.toFixed(6)}`);
|
|
22545
|
+
}
|
|
22546
|
+
}
|
|
22547
|
+
}
|
|
22548
|
+
crossings += intersections2.size;
|
|
22549
|
+
}
|
|
22469
22550
|
}
|
|
22470
|
-
|
|
22471
|
-
|
|
22472
|
-
|
|
22473
|
-
|
|
22474
|
-
|
|
22475
|
-
|
|
22476
|
-
|
|
22477
|
-
|
|
22478
|
-
|
|
22479
|
-
|
|
22480
|
-
|
|
22481
|
-
|
|
22482
|
-
|
|
22483
|
-
|
|
22484
|
-
|
|
22485
|
-
|
|
22486
|
-
|
|
22487
|
-
|
|
22488
|
-
|
|
22489
|
-
|
|
22490
|
-
|
|
22491
|
-
|
|
22492
|
-
|
|
22493
|
-
|
|
22494
|
-
|
|
22495
|
-
|
|
22551
|
+
return {
|
|
22552
|
+
crossings,
|
|
22553
|
+
sharedLength,
|
|
22554
|
+
closeParallelLength,
|
|
22555
|
+
bends,
|
|
22556
|
+
length: length9,
|
|
22557
|
+
score: crossings * 200 + sharedLength * 100 + closeParallelLength * 10 + bends * 3 + length9 * 0.05
|
|
22558
|
+
};
|
|
22559
|
+
}
|
|
22560
|
+
|
|
22561
|
+
// lib/utils/system-blocks/find-system-orthogonal-path.ts
|
|
22562
|
+
function findSystemOrthogonalPath(start, end, obstacles, routedSegments) {
|
|
22563
|
+
const xs = [
|
|
22564
|
+
.../* @__PURE__ */ new Set([
|
|
22565
|
+
start.x,
|
|
22566
|
+
end.x,
|
|
22567
|
+
...obstacles.flatMap((r2) => [r2.left, r2.right]),
|
|
22568
|
+
...routedSegments.filter(([a2, b2]) => a2.x === b2.x).flatMap(([a2]) => [a2.x - 3, a2.x + 3])
|
|
22569
|
+
])
|
|
22570
|
+
].sort((a2, b2) => a2 - b2);
|
|
22571
|
+
const ys = [
|
|
22572
|
+
.../* @__PURE__ */ new Set([
|
|
22573
|
+
start.y,
|
|
22574
|
+
end.y,
|
|
22575
|
+
...obstacles.flatMap((r2) => [r2.bottom, r2.top]),
|
|
22576
|
+
...routedSegments.filter(([a2, b2]) => a2.y === b2.y).flatMap(([a2]) => [a2.y - 3, a2.y + 3])
|
|
22577
|
+
])
|
|
22578
|
+
].sort((a2, b2) => a2 - b2);
|
|
22579
|
+
xs.unshift(xs[0] - 5);
|
|
22580
|
+
xs.push(xs.at(-1) + 5);
|
|
22581
|
+
ys.unshift(ys[0] - 5);
|
|
22582
|
+
ys.push(ys.at(-1) + 5);
|
|
22583
|
+
const columns = xs.length;
|
|
22584
|
+
const pointAt2 = (node) => ({
|
|
22585
|
+
x: xs[node % columns],
|
|
22586
|
+
y: ys[Math.floor(node / columns)]
|
|
22587
|
+
});
|
|
22588
|
+
const startNode = ys.indexOf(start.y) * columns + xs.indexOf(start.x);
|
|
22589
|
+
const endNode = ys.indexOf(end.y) * columns + xs.indexOf(end.x);
|
|
22590
|
+
const costs = new Float64Array(xs.length * ys.length * 3).fill(Infinity);
|
|
22591
|
+
const previous = new Int32Array(costs.length).fill(-1);
|
|
22592
|
+
const horizontalCosts = new Float64Array(xs.length * ys.length).fill(NaN);
|
|
22593
|
+
const verticalCosts = new Float64Array(horizontalCosts.length).fill(NaN);
|
|
22594
|
+
const queue = [];
|
|
22595
|
+
const enqueue = (state, cost2, priority) => {
|
|
22596
|
+
const entry = { state, cost: cost2, priority };
|
|
22597
|
+
queue.push(entry);
|
|
22598
|
+
let i2 = queue.length - 1;
|
|
22599
|
+
while (i2 > 0) {
|
|
22600
|
+
const parent = i2 - 1 >> 1;
|
|
22601
|
+
if (queue[parent].priority <= priority) break;
|
|
22602
|
+
queue[i2] = queue[parent];
|
|
22603
|
+
i2 = parent;
|
|
22604
|
+
}
|
|
22605
|
+
queue[i2] = entry;
|
|
22606
|
+
};
|
|
22607
|
+
costs[startNode * 3 + 2] = 0;
|
|
22608
|
+
enqueue(startNode * 3 + 2, 0, 0);
|
|
22609
|
+
while (queue.length) {
|
|
22610
|
+
const current2 = queue[0];
|
|
22611
|
+
const last = queue.pop();
|
|
22612
|
+
if (queue.length) {
|
|
22613
|
+
let i2 = 0;
|
|
22614
|
+
while (2 * i2 + 1 < queue.length) {
|
|
22615
|
+
let child = 2 * i2 + 1;
|
|
22616
|
+
if (child + 1 < queue.length && queue[child + 1].priority < queue[child].priority)
|
|
22617
|
+
child++;
|
|
22618
|
+
if (last.priority <= queue[child].priority) break;
|
|
22619
|
+
queue[i2] = queue[child];
|
|
22620
|
+
i2 = child;
|
|
22621
|
+
}
|
|
22622
|
+
queue[i2] = last;
|
|
22623
|
+
}
|
|
22624
|
+
if (current2.cost !== costs[current2.state]) continue;
|
|
22625
|
+
const node = Math.floor(current2.state / 3);
|
|
22626
|
+
if (node === endNode) {
|
|
22627
|
+
const path = [];
|
|
22628
|
+
for (let state = current2.state; state !== -1; state = previous[state])
|
|
22629
|
+
path.push(pointAt2(Math.floor(state / 3)));
|
|
22630
|
+
return path.reverse();
|
|
22631
|
+
}
|
|
22632
|
+
const from = pointAt2(node);
|
|
22633
|
+
const col = node % columns;
|
|
22634
|
+
const row = Math.floor(node / columns);
|
|
22635
|
+
const neighbors = [
|
|
22636
|
+
...col > 0 ? [node - 1] : [],
|
|
22637
|
+
...col + 1 < columns ? [node + 1] : [],
|
|
22638
|
+
...row > 0 ? [node - columns] : [],
|
|
22639
|
+
...row + 1 < ys.length ? [node + columns] : []
|
|
22640
|
+
];
|
|
22641
|
+
for (const neighbor of neighbors) {
|
|
22642
|
+
const to = pointAt2(neighbor);
|
|
22643
|
+
const horizontal = from.y === to.y;
|
|
22644
|
+
const left = Math.min(from.x, to.x), right = Math.max(from.x, to.x);
|
|
22645
|
+
const bottom = Math.min(from.y, to.y), top = Math.max(from.y, to.y);
|
|
22646
|
+
const edgeCosts = horizontal ? horizontalCosts : verticalCosts;
|
|
22647
|
+
const edgeIndex = Math.min(node, neighbor);
|
|
22648
|
+
let travelCost = edgeCosts[edgeIndex];
|
|
22649
|
+
if (Number.isNaN(travelCost)) {
|
|
22650
|
+
if (obstacles.some(
|
|
22651
|
+
(r2) => horizontal ? from.y > r2.bottom + 1e-6 && from.y < r2.top - 1e-6 && right > r2.left + 1e-6 && left < r2.right - 1e-6 : from.x > r2.left + 1e-6 && from.x < r2.right - 1e-6 && top > r2.bottom + 1e-6 && bottom < r2.top - 1e-6
|
|
22652
|
+
)) {
|
|
22653
|
+
edgeCosts[edgeIndex] = Infinity;
|
|
22654
|
+
continue;
|
|
22496
22655
|
}
|
|
22497
|
-
|
|
22656
|
+
let congestion = 0;
|
|
22657
|
+
for (const [a2, b2] of routedSegments) {
|
|
22658
|
+
const sameAxis = a2.y === b2.y === horizontal;
|
|
22659
|
+
if (sameAxis) {
|
|
22660
|
+
const separation = horizontal ? Math.abs(a2.y - from.y) : Math.abs(a2.x - from.x);
|
|
22661
|
+
if (horizontal && separation < 3)
|
|
22662
|
+
congestion += Math.max(
|
|
22663
|
+
0,
|
|
22664
|
+
Math.min(right, Math.max(a2.x, b2.x)) - Math.max(left, Math.min(a2.x, b2.x))
|
|
22665
|
+
) * (separation < 1e-6 ? 40 : (3 - separation) * 8);
|
|
22666
|
+
if (!horizontal && separation < 3)
|
|
22667
|
+
congestion += Math.max(
|
|
22668
|
+
0,
|
|
22669
|
+
Math.min(top, Math.max(a2.y, b2.y)) - Math.max(bottom, Math.min(a2.y, b2.y))
|
|
22670
|
+
) * (separation < 1e-6 ? 40 : (3 - separation) * 8);
|
|
22671
|
+
} else if (horizontal ? a2.x >= left && a2.x <= right && from.y >= Math.min(a2.y, b2.y) && from.y <= Math.max(a2.y, b2.y) : a2.y >= bottom && a2.y <= top && from.x >= Math.min(a2.x, b2.x) && from.x <= Math.max(a2.x, b2.x))
|
|
22672
|
+
congestion += 80;
|
|
22673
|
+
}
|
|
22674
|
+
travelCost = right - left + top - bottom + congestion;
|
|
22675
|
+
edgeCosts[edgeIndex] = travelCost;
|
|
22676
|
+
}
|
|
22677
|
+
if (travelCost === Infinity) continue;
|
|
22678
|
+
const axis = horizontal ? 0 : 1;
|
|
22679
|
+
const state = neighbor * 3 + axis;
|
|
22680
|
+
const bend = current2.state % 3 === 2 || current2.state % 3 === axis ? 0 : 6;
|
|
22681
|
+
const cost2 = current2.cost + travelCost + bend;
|
|
22682
|
+
if (cost2 >= costs[state]) continue;
|
|
22683
|
+
costs[state] = cost2;
|
|
22684
|
+
previous[state] = current2.state;
|
|
22685
|
+
enqueue(
|
|
22686
|
+
state,
|
|
22687
|
+
cost2,
|
|
22688
|
+
cost2 + Math.abs(to.x - end.x) + Math.abs(to.y - end.y)
|
|
22689
|
+
);
|
|
22690
|
+
}
|
|
22691
|
+
}
|
|
22692
|
+
}
|
|
22693
|
+
|
|
22694
|
+
// lib/utils/system-blocks/route-system-blocks.ts
|
|
22695
|
+
var SYSTEM_CONNECTION_LABEL_HORIZONTAL_PADDING = 3;
|
|
22696
|
+
function getSystemConnectionLabelWidth(label) {
|
|
22697
|
+
let width = SYSTEM_CONNECTION_LABEL_HORIZONTAL_PADDING;
|
|
22698
|
+
for (const character of label) {
|
|
22699
|
+
width += /[MW@%#&]|[^\x00-\x7f]/.test(character) ? 2.5 : /[A-Z0-9]/.test(character) ? 1.85 : /[il.,:;!| ']/.test(character) ? 0.85 : 1.5;
|
|
22700
|
+
}
|
|
22701
|
+
return width;
|
|
22702
|
+
}
|
|
22703
|
+
function routeSystemBlocks(tree, bounds, initialRoutes) {
|
|
22704
|
+
const obstacles = [...bounds].map(
|
|
22705
|
+
([block, box3]) => ({
|
|
22706
|
+
left: box3.center.x - box3.width / 2 - 2,
|
|
22707
|
+
right: tree.groups.includes(block) ? box3.center.x - box3.width / 2 + Math.min(
|
|
22708
|
+
box3.width,
|
|
22709
|
+
block._parsedProps.description ? box3.width : (block._parsedProps.displayName ?? block.name).length * 1.8 + 6
|
|
22710
|
+
) : box3.center.x + box3.width / 2 + 2,
|
|
22711
|
+
bottom: tree.groups.includes(block) ? box3.center.y + box3.height / 2 - (block._parsedProps.description ? 12 : 7) : box3.center.y - box3.height / 2 - 2,
|
|
22712
|
+
top: box3.center.y + box3.height / 2 + 2
|
|
22498
22713
|
})
|
|
22499
22714
|
);
|
|
22500
|
-
const
|
|
22501
|
-
|
|
22502
|
-
|
|
22715
|
+
const portsByBlock = /* @__PURE__ */ new Map();
|
|
22716
|
+
const portsByConnection = /* @__PURE__ */ new Map();
|
|
22717
|
+
for (const connection of tree.connections) {
|
|
22718
|
+
const endpoints = tree.endpoints.get(connection);
|
|
22719
|
+
const route = initialRoutes.get(connection).route;
|
|
22720
|
+
const ports = [endpoints.from, endpoints.to].map((block, end) => {
|
|
22721
|
+
const box3 = bounds.get(block);
|
|
22722
|
+
const target = bounds.get(
|
|
22723
|
+
end === 0 ? endpoints.to : endpoints.from
|
|
22724
|
+
).center;
|
|
22725
|
+
const guide = initialRoutes.get(connection).label_anchor_center ?? target;
|
|
22726
|
+
const point8 = endpoints.from === endpoints.to ? end === 0 ? route[0] : route.at(-1) : guide;
|
|
22727
|
+
const dx2 = (point8.x - box3.center.x) / box3.width;
|
|
22728
|
+
const dy2 = (point8.y - box3.center.y) / box3.height;
|
|
22729
|
+
const side = Math.abs(dx2) >= Math.abs(dy2) ? dx2 >= 0 ? 0 : 2 : dy2 >= 0 ? 1 : 3;
|
|
22730
|
+
const port = {
|
|
22731
|
+
point: { ...point8 },
|
|
22732
|
+
escape: { ...point8 },
|
|
22733
|
+
side,
|
|
22734
|
+
target: guide,
|
|
22735
|
+
connection
|
|
22736
|
+
};
|
|
22737
|
+
const ports2 = portsByBlock.get(block) ?? [];
|
|
22738
|
+
ports2.push(port);
|
|
22739
|
+
portsByBlock.set(block, ports2);
|
|
22740
|
+
return port;
|
|
22741
|
+
});
|
|
22742
|
+
portsByConnection.set(connection, ports);
|
|
22743
|
+
}
|
|
22744
|
+
for (const [block, ports] of portsByBlock) {
|
|
22745
|
+
const box3 = bounds.get(block);
|
|
22746
|
+
for (const side of [0, 1, 2, 3]) {
|
|
22747
|
+
const horizontal = side % 2 === 0;
|
|
22748
|
+
const facePorts = ports.filter((p2) => p2.side === side).sort(
|
|
22749
|
+
(a2, b2) => horizontal ? (a2.target.y - box3.center.y) / Math.max(1, Math.abs(a2.target.x - box3.center.x)) - (b2.target.y - box3.center.y) / Math.max(1, Math.abs(b2.target.x - box3.center.x)) : (a2.target.x - box3.center.x) / Math.max(1, Math.abs(a2.target.y - box3.center.y)) - (b2.target.x - box3.center.x) / Math.max(1, Math.abs(b2.target.y - box3.center.y))
|
|
22750
|
+
);
|
|
22751
|
+
const span = horizontal ? box3.height : box3.width;
|
|
22752
|
+
const spacing = Math.min(
|
|
22753
|
+
4,
|
|
22754
|
+
(span - 4) / Math.max(1, facePorts.length - 1)
|
|
22755
|
+
);
|
|
22756
|
+
facePorts.forEach((port, index2) => {
|
|
22757
|
+
const offset = (index2 - (facePorts.length - 1) / 2) * spacing;
|
|
22758
|
+
const sign = side < 2 ? 1 : -1;
|
|
22759
|
+
port.point = horizontal ? {
|
|
22760
|
+
x: box3.center.x + sign * box3.width / 2,
|
|
22761
|
+
y: box3.center.y + offset
|
|
22762
|
+
} : {
|
|
22763
|
+
x: box3.center.x + offset,
|
|
22764
|
+
y: box3.center.y + sign * box3.height / 2
|
|
22765
|
+
};
|
|
22766
|
+
port.escape = horizontal ? { x: port.point.x + sign * 4, y: port.point.y } : { x: port.point.x, y: port.point.y + sign * 4 };
|
|
22767
|
+
});
|
|
22768
|
+
}
|
|
22769
|
+
}
|
|
22770
|
+
const labels = /* @__PURE__ */ new Map();
|
|
22771
|
+
const labelCenters = /* @__PURE__ */ new Map();
|
|
22772
|
+
const labelAttachments = /* @__PURE__ */ new Map();
|
|
22773
|
+
const portObstacles = [...portsByConnection.values()].flat().map(({ escape }) => ({
|
|
22774
|
+
left: escape.x - 1,
|
|
22775
|
+
right: escape.x + 1,
|
|
22776
|
+
bottom: escape.y - 1,
|
|
22777
|
+
top: escape.y + 1
|
|
22778
|
+
}));
|
|
22779
|
+
for (const connection of tree.connections) {
|
|
22780
|
+
const label = connection._parsedProps.label;
|
|
22781
|
+
const center = initialRoutes.get(connection).label_anchor_center;
|
|
22782
|
+
if (label !== void 0 && center) {
|
|
22783
|
+
const halfWidth = getSystemConnectionLabelWidth(label) / 2;
|
|
22784
|
+
const occupied = [...obstacles, ...labels.values(), ...portObstacles];
|
|
22785
|
+
const fits = (rectangle) => !occupied.some(
|
|
22786
|
+
(r2) => rectangle.left < r2.right + 1 && rectangle.right > r2.left - 1 && rectangle.bottom < r2.top + 1 && rectangle.top > r2.bottom - 1
|
|
22787
|
+
);
|
|
22788
|
+
const [start, end] = portsByConnection.get(connection);
|
|
22789
|
+
const endpoints = tree.endpoints.get(connection);
|
|
22790
|
+
const selfLoop = endpoints.from === endpoints.to;
|
|
22791
|
+
const vertical = start.escape.x === end.escape.x;
|
|
22792
|
+
const horizontal = start.escape.y === end.escape.y;
|
|
22793
|
+
const oppositeFaces = (start.side + 2) % 4 === end.side;
|
|
22794
|
+
const straightAxis = vertical && start.side % 2 === 1 ? "y" : horizontal && start.side % 2 === 0 ? "x" : void 0;
|
|
22795
|
+
const straight = !selfLoop && oppositeFaces && straightAxis !== void 0 && (end.escape[straightAxis] - start.escape[straightAxis]) * (start.escape[straightAxis] - start.point[straightAxis]) >= 0;
|
|
22796
|
+
const sameFaceReturn = selfLoop && start.side === end.side;
|
|
22797
|
+
const textFitsHorizontalSpan = horizontal && !selfLoop && Math.abs(start.escape.x - end.escape.x) >= halfWidth * 2;
|
|
22798
|
+
if ((straight || sameFaceReturn) && !textFitsHorizontalSpan && !obstacles.some(
|
|
22799
|
+
(r2) => vertical ? start.escape.x > r2.left && start.escape.x < r2.right && Math.max(start.escape.y, end.escape.y) > r2.bottom && Math.min(start.escape.y, end.escape.y) < r2.top : start.escape.y > r2.bottom && start.escape.y < r2.top && Math.max(start.escape.x, end.escape.x) > r2.left && Math.min(start.escape.x, end.escape.x) < r2.right
|
|
22800
|
+
)) {
|
|
22801
|
+
const attachment = {
|
|
22802
|
+
x: (start.escape.x + end.escape.x) / 2,
|
|
22803
|
+
y: (start.escape.y + end.escape.y) / 2
|
|
22804
|
+
};
|
|
22805
|
+
const signs = selfLoop ? [start.side < 2 ? 1 : -1] : [1, -1];
|
|
22806
|
+
for (const sign of signs) {
|
|
22807
|
+
const candidate = vertical ? { x: attachment.x + sign * (halfWidth + 2), y: attachment.y } : { x: attachment.x, y: attachment.y + sign * 4.5 };
|
|
22808
|
+
const rectangle = {
|
|
22809
|
+
left: candidate.x - halfWidth,
|
|
22810
|
+
right: candidate.x + halfWidth,
|
|
22811
|
+
bottom: candidate.y - 2.5,
|
|
22812
|
+
top: candidate.y + 2.5
|
|
22813
|
+
};
|
|
22814
|
+
if (!fits(rectangle)) continue;
|
|
22815
|
+
labels.set(connection, rectangle);
|
|
22816
|
+
labelCenters.set(connection, candidate);
|
|
22817
|
+
labelAttachments.set(connection, attachment);
|
|
22818
|
+
break;
|
|
22819
|
+
}
|
|
22820
|
+
if (labelAttachments.has(connection)) continue;
|
|
22821
|
+
}
|
|
22822
|
+
let placed = false;
|
|
22823
|
+
for (let radius = 0; !placed; radius++) {
|
|
22824
|
+
const offsets = radius === 0 ? [[0, 0]] : [
|
|
22825
|
+
[0, radius * 6],
|
|
22826
|
+
[0, -radius * 6],
|
|
22827
|
+
[radius * 6, 0],
|
|
22828
|
+
[-radius * 6, 0]
|
|
22829
|
+
];
|
|
22830
|
+
for (const [dx2, dy2] of offsets) {
|
|
22831
|
+
const candidate = { x: center.x + dx2, y: center.y + dy2 };
|
|
22832
|
+
const rectangle = {
|
|
22833
|
+
left: candidate.x - halfWidth,
|
|
22834
|
+
right: candidate.x + halfWidth,
|
|
22835
|
+
bottom: candidate.y - 2.5,
|
|
22836
|
+
top: candidate.y + 2.5
|
|
22837
|
+
};
|
|
22838
|
+
if (!fits(rectangle)) continue;
|
|
22839
|
+
labels.set(connection, rectangle);
|
|
22840
|
+
labelCenters.set(connection, candidate);
|
|
22841
|
+
placed = true;
|
|
22842
|
+
break;
|
|
22843
|
+
}
|
|
22844
|
+
}
|
|
22845
|
+
}
|
|
22846
|
+
}
|
|
22847
|
+
const routeConnection = (connection, routedSegments) => {
|
|
22848
|
+
const [start, end] = portsByConnection.get(connection);
|
|
22849
|
+
const label = labels.get(connection);
|
|
22850
|
+
const attachment = labelAttachments.get(connection);
|
|
22851
|
+
const blocked = [
|
|
22852
|
+
...obstacles,
|
|
22853
|
+
...[...labels].filter(([c2]) => c2 !== connection).map(([, r2]) => r2)
|
|
22854
|
+
];
|
|
22855
|
+
const waypoints = [start.escape];
|
|
22856
|
+
if (attachment) {
|
|
22857
|
+
waypoints.push(attachment);
|
|
22858
|
+
} else if (label) {
|
|
22859
|
+
const y2 = labelCenters.get(connection).y;
|
|
22860
|
+
const labelPorts = [
|
|
22861
|
+
{ x: label.left, y: y2 },
|
|
22862
|
+
{ x: label.right, y: y2 }
|
|
22863
|
+
];
|
|
22864
|
+
if (start.escape.x > end.escape.x) labelPorts.reverse();
|
|
22865
|
+
waypoints.push(...labelPorts);
|
|
22866
|
+
}
|
|
22867
|
+
waypoints.push(end.escape);
|
|
22868
|
+
const route = [start.point];
|
|
22869
|
+
for (let i2 = 1; i2 < waypoints.length; i2++) {
|
|
22870
|
+
const legObstacles = label && (attachment || i2 !== 2) ? [...blocked, label] : blocked;
|
|
22871
|
+
const leg = findSystemOrthogonalPath(
|
|
22872
|
+
waypoints[i2 - 1],
|
|
22873
|
+
waypoints[i2],
|
|
22874
|
+
legObstacles,
|
|
22875
|
+
routedSegments
|
|
22876
|
+
);
|
|
22877
|
+
if (!leg) {
|
|
22878
|
+
throw new Error(
|
|
22879
|
+
`Cannot route system connection from "${connection._parsedProps.from}" to "${connection._parsedProps.to}" around blocks and labels`
|
|
22880
|
+
);
|
|
22881
|
+
}
|
|
22882
|
+
route.push(...leg);
|
|
22883
|
+
}
|
|
22884
|
+
route.push(end.point);
|
|
22885
|
+
const simplified = [];
|
|
22886
|
+
for (const point8 of route) {
|
|
22887
|
+
const previous = simplified.at(-1);
|
|
22888
|
+
if (previous?.x === point8.x && previous.y === point8.y) continue;
|
|
22889
|
+
const before = simplified.at(-2);
|
|
22890
|
+
if (before && previous && (before.x === previous.x && previous.x === point8.x || before.y === previous.y && previous.y === point8.y))
|
|
22891
|
+
simplified.pop();
|
|
22892
|
+
simplified.push(point8);
|
|
22893
|
+
}
|
|
22503
22894
|
return {
|
|
22504
|
-
|
|
22505
|
-
|
|
22506
|
-
minY: tree.groups.some((group) => group === block) ? top - 12 : center.y - height2 / 2,
|
|
22507
|
-
maxY: top
|
|
22895
|
+
route: simplified,
|
|
22896
|
+
label_anchor_center: labelCenters.get(connection)
|
|
22508
22897
|
};
|
|
22898
|
+
};
|
|
22899
|
+
const connections = [...tree.connections].sort((a2, b2) => {
|
|
22900
|
+
const distance29 = (connection) => {
|
|
22901
|
+
const [from, to] = portsByConnection.get(connection);
|
|
22902
|
+
return Math.abs(from.point.x - to.point.x) + Math.abs(from.point.y - to.point.y);
|
|
22903
|
+
};
|
|
22904
|
+
return distance29(a2) - distance29(b2) || a2._parsedProps.from.localeCompare(b2._parsedProps.from) || a2._parsedProps.to.localeCompare(b2._parsedProps.to) || (a2._parsedProps.label ?? "").localeCompare(b2._parsedProps.label ?? "");
|
|
22509
22905
|
});
|
|
22510
|
-
|
|
22511
|
-
|
|
22512
|
-
|
|
22513
|
-
|
|
22906
|
+
const segmentsOf = (resolvedRoutes) => [...resolvedRoutes].flatMap(
|
|
22907
|
+
({ route }) => route.slice(1).map((point8, index2) => [route[index2], point8])
|
|
22908
|
+
);
|
|
22909
|
+
let routes = /* @__PURE__ */ new Map();
|
|
22910
|
+
for (const connection of connections)
|
|
22911
|
+
routes.set(
|
|
22912
|
+
connection,
|
|
22913
|
+
routeConnection(connection, segmentsOf(routes.values()))
|
|
22914
|
+
);
|
|
22915
|
+
let score = measureSystemRouteQuality(
|
|
22916
|
+
[...routes.values()].map((r2) => r2.route)
|
|
22917
|
+
).score;
|
|
22918
|
+
const reroute = (affected) => {
|
|
22919
|
+
const candidate = new Map(
|
|
22920
|
+
[...routes].filter(([connection]) => !affected.has(connection))
|
|
22921
|
+
);
|
|
22922
|
+
for (const connection of connections.filter((c2) => affected.has(c2)))
|
|
22923
|
+
candidate.set(
|
|
22924
|
+
connection,
|
|
22925
|
+
routeConnection(connection, segmentsOf(candidate.values()))
|
|
22926
|
+
);
|
|
22927
|
+
const candidateScore = measureSystemRouteQuality(
|
|
22928
|
+
[...candidate.values()].map((r2) => r2.route)
|
|
22929
|
+
).score;
|
|
22930
|
+
if (candidateScore >= score - 1e-6) return false;
|
|
22931
|
+
routes = candidate;
|
|
22932
|
+
score = candidateScore;
|
|
22933
|
+
return true;
|
|
22934
|
+
};
|
|
22935
|
+
let proposals = 0;
|
|
22936
|
+
const proposalLimit = Math.min(64, connections.length * 4);
|
|
22937
|
+
for (let pass = 0; pass < 4 && proposals < proposalLimit; pass++) {
|
|
22938
|
+
let improved = false;
|
|
22939
|
+
for (const [block, ports] of portsByBlock) {
|
|
22940
|
+
if (ports.length < 2) continue;
|
|
22941
|
+
const center = bounds.get(block).center;
|
|
22942
|
+
const perimeter = [...ports].sort(
|
|
22943
|
+
(a2, b2) => Math.atan2(a2.point.y - center.y, a2.point.x - center.x) - Math.atan2(b2.point.y - center.y, b2.point.x - center.x)
|
|
22944
|
+
);
|
|
22945
|
+
for (let i2 = 0; i2 < perimeter.length && proposals < proposalLimit; i2++) {
|
|
22946
|
+
proposals++;
|
|
22947
|
+
const a2 = perimeter[i2], b2 = perimeter[(i2 + 1) % perimeter.length];
|
|
22948
|
+
const swap2 = () => {
|
|
22949
|
+
;
|
|
22950
|
+
[a2.point, b2.point] = [b2.point, a2.point];
|
|
22951
|
+
[a2.escape, b2.escape] = [b2.escape, a2.escape];
|
|
22952
|
+
[a2.side, b2.side] = [b2.side, a2.side];
|
|
22953
|
+
};
|
|
22954
|
+
swap2();
|
|
22955
|
+
if (reroute(/* @__PURE__ */ new Set([a2.connection, b2.connection]))) {
|
|
22956
|
+
improved = true;
|
|
22957
|
+
perimeter[i2] = b2;
|
|
22958
|
+
perimeter[(i2 + 1) % perimeter.length] = a2;
|
|
22959
|
+
} else swap2();
|
|
22960
|
+
}
|
|
22961
|
+
}
|
|
22962
|
+
if (!improved) break;
|
|
22963
|
+
const quality = measureSystemRouteQuality(
|
|
22964
|
+
[...routes.values()].map((r2) => r2.route)
|
|
22965
|
+
);
|
|
22966
|
+
if (quality.crossings === 0 && quality.sharedLength === 0 && quality.closeParallelLength === 0)
|
|
22967
|
+
break;
|
|
22968
|
+
}
|
|
22969
|
+
for (const connection of connections) reroute(/* @__PURE__ */ new Set([connection]));
|
|
22970
|
+
return routes;
|
|
22971
|
+
}
|
|
22972
|
+
|
|
22973
|
+
// lib/utils/system-blocks/round-system-block-connections.ts
|
|
22974
|
+
function roundSystemBlockConnections(tree, bounds, routes) {
|
|
22975
|
+
const obstacles = [...bounds].map(
|
|
22976
|
+
([block, box3]) => ({
|
|
22977
|
+
minX: box3.center.x - box3.width / 2,
|
|
22978
|
+
maxX: box3.center.x + box3.width / 2,
|
|
22979
|
+
minY: tree.groups.includes(block) ? box3.center.y + box3.height / 2 - (block._parsedProps.description ? 12 : 7) : box3.center.y - box3.height / 2,
|
|
22980
|
+
maxY: box3.center.y + box3.height / 2
|
|
22981
|
+
})
|
|
22982
|
+
);
|
|
22983
|
+
for (const [connection, resolved] of routes) {
|
|
22984
|
+
const label = resolved.label_anchor_center;
|
|
22985
|
+
if (!label) continue;
|
|
22986
|
+
const halfWidth = (getSystemConnectionLabelWidth(connection._parsedProps.label) - SYSTEM_CONNECTION_LABEL_HORIZONTAL_PADDING) / 2;
|
|
22514
22987
|
obstacles.push({
|
|
22515
|
-
minX: label.x -
|
|
22516
|
-
maxX: label.x +
|
|
22517
|
-
minY: label.y -
|
|
22518
|
-
maxY: label.y +
|
|
22988
|
+
minX: label.x - halfWidth,
|
|
22989
|
+
maxX: label.x + halfWidth,
|
|
22990
|
+
minY: label.y - 2.5,
|
|
22991
|
+
maxY: label.y + 2.5
|
|
22992
|
+
});
|
|
22993
|
+
}
|
|
22994
|
+
const rounded = new Map(routes);
|
|
22995
|
+
for (const [connection, resolved] of routes) {
|
|
22996
|
+
const wireObstacles = [];
|
|
22997
|
+
for (const [other, { route }] of rounded) {
|
|
22998
|
+
if (other === connection) continue;
|
|
22999
|
+
for (let index2 = 1; index2 < route.length; index2++) {
|
|
23000
|
+
const end = route[index2];
|
|
23001
|
+
const points = [
|
|
23002
|
+
route[index2 - 1],
|
|
23003
|
+
...end.cubic_bezier_control_points ?? [],
|
|
23004
|
+
end
|
|
23005
|
+
];
|
|
23006
|
+
wireObstacles.push({
|
|
23007
|
+
minX: Math.min(...points.map((p2) => p2.x)),
|
|
23008
|
+
maxX: Math.max(...points.map((p2) => p2.x)),
|
|
23009
|
+
minY: Math.min(...points.map((p2) => p2.y)),
|
|
23010
|
+
maxY: Math.max(...points.map((p2) => p2.y))
|
|
23011
|
+
});
|
|
23012
|
+
}
|
|
23013
|
+
}
|
|
23014
|
+
const blocked = [
|
|
23015
|
+
...obstacles,
|
|
23016
|
+
...wireObstacles.map((wire) => ({
|
|
23017
|
+
minX: wire.minX - 3,
|
|
23018
|
+
maxX: wire.maxX + 3,
|
|
23019
|
+
minY: wire.minY - 3,
|
|
23020
|
+
maxY: wire.maxY + 3
|
|
23021
|
+
}))
|
|
23022
|
+
];
|
|
23023
|
+
const { from, to } = tree.endpoints.get(connection);
|
|
23024
|
+
const selfLoop = from === to ? createSystemBlockSelfLoop(resolved.route, bounds.get(from), blocked) : void 0;
|
|
23025
|
+
rounded.set(connection, {
|
|
23026
|
+
...resolved,
|
|
23027
|
+
route: selfLoop ?? roundSystemBlockRoute(resolved.route, obstacles, wireObstacles)
|
|
22519
23028
|
});
|
|
22520
23029
|
}
|
|
22521
|
-
|
|
22522
|
-
|
|
22523
|
-
|
|
22524
|
-
|
|
22525
|
-
|
|
23030
|
+
return rounded;
|
|
23031
|
+
}
|
|
23032
|
+
|
|
23033
|
+
// lib/utils/system-blocks/layout-system-blocks.ts
|
|
23034
|
+
function layoutSystemBlocks(tree, direction) {
|
|
23035
|
+
const degrees2 = /* @__PURE__ */ new Map();
|
|
23036
|
+
for (const {
|
|
23037
|
+
_parsedProps: { from, to }
|
|
23038
|
+
} of tree.connections) {
|
|
23039
|
+
degrees2.set(from, (degrees2.get(from) ?? 0) + 1);
|
|
23040
|
+
degrees2.set(to, (degrees2.get(to) ?? 0) + 1);
|
|
23041
|
+
}
|
|
23042
|
+
const layout = layoutContainer(tree, void 0, direction ?? "right", degrees2);
|
|
23043
|
+
const toPage = compose10(
|
|
23044
|
+
translate8(-layout.width / 2, layout.height / 2),
|
|
23045
|
+
scale3(1, -1)
|
|
23046
|
+
);
|
|
23047
|
+
for (const box3 of layout.bounds.values())
|
|
23048
|
+
box3.center = applyToPoint34(toPage, box3.center);
|
|
23049
|
+
for (const [connection, resolved] of layout.routes) {
|
|
23050
|
+
resolved.route = resolved.route.map((point8) => applyToPoint34(toPage, point8));
|
|
23051
|
+
if (resolved.label_anchor_center)
|
|
23052
|
+
resolved.label_anchor_center = applyToPoint34(
|
|
23053
|
+
toPage,
|
|
23054
|
+
resolved.label_anchor_center
|
|
23055
|
+
);
|
|
23056
|
+
const endpoints = tree.endpoints.get(connection);
|
|
23057
|
+
for (const [block, index2] of [
|
|
23058
|
+
[endpoints.from, 0],
|
|
23059
|
+
[endpoints.to, resolved.route.length - 1]
|
|
23060
|
+
]) {
|
|
23061
|
+
const box3 = layout.bounds.get(block);
|
|
23062
|
+
const point8 = resolved.route[index2];
|
|
23063
|
+
let dx2 = point8.x - box3.center.x, dy2 = point8.y - box3.center.y;
|
|
23064
|
+
if (dx2 === 0 && dy2 === 0) {
|
|
23065
|
+
const neighbor = resolved.route[index2 === 0 ? 1 : index2 - 1];
|
|
23066
|
+
dx2 = neighbor.x - point8.x;
|
|
23067
|
+
dy2 = neighbor.y - point8.y;
|
|
23068
|
+
}
|
|
23069
|
+
const factor = Math.max(
|
|
23070
|
+
Math.abs(dx2) / (box3.width / 2),
|
|
23071
|
+
Math.abs(dy2) / (box3.height / 2)
|
|
22526
23072
|
);
|
|
22527
|
-
|
|
22528
|
-
|
|
22529
|
-
|
|
22530
|
-
|
|
22531
|
-
|
|
22532
|
-
|
|
22533
|
-
|
|
22534
|
-
|
|
22535
|
-
|
|
22536
|
-
|
|
22537
|
-
})
|
|
23073
|
+
resolved.route[index2] = {
|
|
23074
|
+
x: box3.center.x + dx2 / factor,
|
|
23075
|
+
y: box3.center.y + dy2 / factor
|
|
23076
|
+
};
|
|
23077
|
+
}
|
|
23078
|
+
}
|
|
23079
|
+
const routes = roundSystemBlockConnections(
|
|
23080
|
+
tree,
|
|
23081
|
+
layout.bounds,
|
|
23082
|
+
routeSystemBlocks(tree, layout.bounds, layout.routes)
|
|
22538
23083
|
);
|
|
23084
|
+
let width = layout.width, height = layout.height;
|
|
23085
|
+
for (const [connection, resolved] of routes) {
|
|
23086
|
+
for (const point8 of resolved.route) {
|
|
23087
|
+
width = Math.max(width, 2 * (Math.abs(point8.x) + 6));
|
|
23088
|
+
height = Math.max(height, 2 * (Math.abs(point8.y) + 6));
|
|
23089
|
+
}
|
|
23090
|
+
if (resolved.label_anchor_center) {
|
|
23091
|
+
width = Math.max(
|
|
23092
|
+
width,
|
|
23093
|
+
2 * (Math.abs(resolved.label_anchor_center.x) + getSystemConnectionLabelWidth(connection._parsedProps.label) / 2 + 6)
|
|
23094
|
+
);
|
|
23095
|
+
height = Math.max(
|
|
23096
|
+
height,
|
|
23097
|
+
2 * (Math.abs(resolved.label_anchor_center.y) + 8)
|
|
23098
|
+
);
|
|
23099
|
+
}
|
|
23100
|
+
}
|
|
23101
|
+
return { width, height, bounds: layout.bounds, routes };
|
|
23102
|
+
}
|
|
23103
|
+
function layoutContainer(tree, parent, direction, degrees2) {
|
|
23104
|
+
const children = [
|
|
23105
|
+
...tree.groups,
|
|
23106
|
+
...tree.components
|
|
23107
|
+
].filter((block) => tree.parents.get(block) === parent);
|
|
23108
|
+
const groupLayouts = /* @__PURE__ */ new Map();
|
|
23109
|
+
const graph = new dagre.graphlib.Graph({ multigraph: true });
|
|
23110
|
+
graph.setGraph({
|
|
23111
|
+
rankdir: { right: "LR", left: "RL", down: "TB", up: "BT" }[direction],
|
|
23112
|
+
nodesep: parent ? 12 : 18,
|
|
23113
|
+
ranksep: 18,
|
|
23114
|
+
edgesep: 8,
|
|
23115
|
+
marginx: 8,
|
|
23116
|
+
marginy: 8
|
|
23117
|
+
});
|
|
23118
|
+
for (const block of children) {
|
|
23119
|
+
if (tree.groups.includes(block)) {
|
|
23120
|
+
const child = layoutContainer(
|
|
23121
|
+
tree,
|
|
23122
|
+
block,
|
|
23123
|
+
direction,
|
|
23124
|
+
degrees2
|
|
23125
|
+
);
|
|
23126
|
+
groupLayouts.set(block, child);
|
|
23127
|
+
graph.setNode(block.name, { width: child.width, height: child.height });
|
|
23128
|
+
} else {
|
|
23129
|
+
const { name, displayName, description } = block._parsedProps;
|
|
23130
|
+
const width2 = Math.max(
|
|
23131
|
+
32,
|
|
23132
|
+
Math.min(62, (displayName ?? name).length * 1.5 + 8)
|
|
23133
|
+
);
|
|
23134
|
+
const descriptionLines = description ? Math.ceil(description.length / ((width2 - 8) / 1.3)) : 0;
|
|
23135
|
+
graph.setNode(name, {
|
|
23136
|
+
width: width2,
|
|
23137
|
+
height: Math.max(18, 12 + descriptionLines * 3.5)
|
|
23138
|
+
});
|
|
23139
|
+
}
|
|
23140
|
+
}
|
|
23141
|
+
const childFor = (block) => {
|
|
23142
|
+
let current2 = block;
|
|
23143
|
+
while (current2 && tree.parents.get(current2) !== parent)
|
|
23144
|
+
current2 = tree.parents.get(current2);
|
|
23145
|
+
return current2;
|
|
23146
|
+
};
|
|
23147
|
+
const edges = /* @__PURE__ */ new Map();
|
|
23148
|
+
for (const [index2, connection] of tree.connections.entries()) {
|
|
23149
|
+
const endpoints = tree.endpoints.get(connection);
|
|
23150
|
+
const from = childFor(endpoints.from), to = childFor(endpoints.to);
|
|
23151
|
+
if (!from || !to || from === to && (from !== endpoints.from || to !== endpoints.to))
|
|
23152
|
+
continue;
|
|
23153
|
+
const props = connection._parsedProps;
|
|
23154
|
+
const reverse4 = props.direction === "both" && degrees2.get(props.to) > degrees2.get(props.from);
|
|
23155
|
+
const edge = {
|
|
23156
|
+
v: (reverse4 ? to : from).name,
|
|
23157
|
+
w: (reverse4 ? from : to).name,
|
|
23158
|
+
name: `connection_${index2}`
|
|
23159
|
+
};
|
|
23160
|
+
graph.setEdge(edge, {
|
|
23161
|
+
width: props.label === void 0 ? 0 : getSystemConnectionLabelWidth(props.label),
|
|
23162
|
+
height: props.label === void 0 ? 0 : 5,
|
|
23163
|
+
labelpos: "c",
|
|
23164
|
+
labeloffset: 0
|
|
23165
|
+
});
|
|
23166
|
+
edges.set(connection, edge);
|
|
23167
|
+
}
|
|
23168
|
+
if (children.length) dagre.layout(graph);
|
|
23169
|
+
const heading = parent ? parent._parsedProps.description ? 14 : 8 : 0;
|
|
23170
|
+
const minimumWidth = parent ? Math.min(
|
|
23171
|
+
90,
|
|
23172
|
+
(parent._parsedProps.displayName ?? parent.name).length * 1.8 + 8
|
|
23173
|
+
) : 32;
|
|
23174
|
+
const width = Math.max(minimumWidth, graph.graph().width ?? 0);
|
|
23175
|
+
const height = Math.max(24, (graph.graph().height ?? 0) + heading);
|
|
23176
|
+
const bounds = /* @__PURE__ */ new Map();
|
|
23177
|
+
const routes = /* @__PURE__ */ new Map();
|
|
23178
|
+
for (const block of children) {
|
|
23179
|
+
const node = graph.node(block.name);
|
|
23180
|
+
bounds.set(block, {
|
|
23181
|
+
center: { x: node.x, y: node.y + heading },
|
|
23182
|
+
width: node.width,
|
|
23183
|
+
height: node.height
|
|
23184
|
+
});
|
|
23185
|
+
const child = groupLayouts.get(block);
|
|
23186
|
+
if (!child) continue;
|
|
23187
|
+
const offset = {
|
|
23188
|
+
x: node.x - child.width / 2,
|
|
23189
|
+
y: node.y + heading - child.height / 2
|
|
23190
|
+
};
|
|
23191
|
+
const shift = (point8) => ({
|
|
23192
|
+
x: point8.x + offset.x,
|
|
23193
|
+
y: point8.y + offset.y
|
|
23194
|
+
});
|
|
23195
|
+
for (const [descendant, box3] of child.bounds)
|
|
23196
|
+
bounds.set(descendant, { ...box3, center: shift(box3.center) });
|
|
23197
|
+
for (const [connection, resolved] of child.routes)
|
|
23198
|
+
routes.set(connection, {
|
|
23199
|
+
route: resolved.route.map(shift),
|
|
23200
|
+
label_anchor_center: resolved.label_anchor_center ? shift(resolved.label_anchor_center) : void 0
|
|
23201
|
+
});
|
|
23202
|
+
}
|
|
23203
|
+
for (const [connection, edgeKey] of edges) {
|
|
23204
|
+
const edge = graph.edge(edgeKey);
|
|
23205
|
+
const route = edge.points.map((point8) => ({
|
|
23206
|
+
x: point8.x,
|
|
23207
|
+
y: point8.y + heading
|
|
23208
|
+
}));
|
|
23209
|
+
const from = childFor(tree.endpoints.get(connection).from);
|
|
23210
|
+
if (edgeKey.v !== from.name) route.reverse();
|
|
23211
|
+
routes.set(connection, {
|
|
23212
|
+
route,
|
|
23213
|
+
label_anchor_center: connection._parsedProps.label === void 0 ? void 0 : { x: edge.x, y: edge.y + heading }
|
|
23214
|
+
});
|
|
23215
|
+
}
|
|
23216
|
+
const bundles = /* @__PURE__ */ new Map();
|
|
23217
|
+
for (const [connection, edge] of edges) {
|
|
23218
|
+
if (connection._parsedProps.label === void 0) continue;
|
|
23219
|
+
const targets = bundles.get(edge.v) ?? /* @__PURE__ */ new Map();
|
|
23220
|
+
const connections = targets.get(edge.w) ?? [];
|
|
23221
|
+
connections.push(connection);
|
|
23222
|
+
targets.set(edge.w, connections);
|
|
23223
|
+
bundles.set(edge.v, targets);
|
|
23224
|
+
}
|
|
23225
|
+
const crossAxis = direction === "right" || direction === "left" ? "y" : "x";
|
|
23226
|
+
for (const targets of bundles.values()) {
|
|
23227
|
+
for (const connections of targets.values()) {
|
|
23228
|
+
const slots = connections.map((c2) => routes.get(c2).label_anchor_center).sort((a2, b2) => a2[crossAxis] - b2[crossAxis]);
|
|
23229
|
+
const destinationPosition = (connection) => {
|
|
23230
|
+
const endpoints = tree.endpoints.get(connection);
|
|
23231
|
+
const targetChild = edges.get(connection).w;
|
|
23232
|
+
const endpoint = childFor(endpoints.to).name === targetChild ? endpoints.to : endpoints.from;
|
|
23233
|
+
return bounds.get(endpoint).center[crossAxis];
|
|
23234
|
+
};
|
|
23235
|
+
connections.sort(
|
|
23236
|
+
(a2, b2) => destinationPosition(a2) - destinationPosition(b2)
|
|
23237
|
+
);
|
|
23238
|
+
connections.forEach((connection, index2) => {
|
|
23239
|
+
routes.get(connection).label_anchor_center = slots[index2];
|
|
23240
|
+
});
|
|
23241
|
+
}
|
|
23242
|
+
}
|
|
22539
23243
|
return { width, height, bounds, routes };
|
|
22540
23244
|
}
|
|
22541
23245
|
|
|
@@ -22634,7 +23338,7 @@ function SystemBlockPage_doInitialSystemBlockRender(page) {
|
|
|
22634
23338
|
}
|
|
22635
23339
|
for (const connection of tree.connections) {
|
|
22636
23340
|
const { from, to } = tree.endpoints.get(connection);
|
|
22637
|
-
const { name: name2, kind, direction: direction2, label } = connection._parsedProps;
|
|
23341
|
+
const { name: name2, kind, direction: direction2, label, color: color3, lineStyle } = connection._parsedProps;
|
|
22638
23342
|
db2.system_block_connection.insert({
|
|
22639
23343
|
system_block_page_id: page.system_block_page_id,
|
|
22640
23344
|
from_system_block_component_id: componentIds.get(from),
|
|
@@ -22642,6 +23346,8 @@ function SystemBlockPage_doInitialSystemBlockRender(page) {
|
|
|
22642
23346
|
name: name2,
|
|
22643
23347
|
label,
|
|
22644
23348
|
direction: direction2,
|
|
23349
|
+
color: color3,
|
|
23350
|
+
line_style: lineStyle,
|
|
22645
23351
|
is_signal: kind === "signal",
|
|
22646
23352
|
is_power: kind === "power",
|
|
22647
23353
|
...layout.routes.get(connection)
|
|
@@ -69965,11 +70671,14 @@ function extractTraceCopper3(trace, layerNames) {
|
|
|
69965
70671
|
type: "via",
|
|
69966
70672
|
center: { x: routePoint.x, y: routePoint.y },
|
|
69967
70673
|
diameter: routePoint.via_diameter ?? 0,
|
|
69968
|
-
layers:
|
|
69969
|
-
routePoint.from_layer,
|
|
69970
|
-
routePoint.to_layer,
|
|
69971
|
-
|
|
69972
|
-
|
|
70674
|
+
layers: getRouteViaSpanLayers3({
|
|
70675
|
+
fromLayer: routePoint.from_layer,
|
|
70676
|
+
toLayer: routePoint.to_layer,
|
|
70677
|
+
layers: "layers" in routePoint && Array.isArray(routePoint.layers) ? routePoint.layers : void 0,
|
|
70678
|
+
layerNames,
|
|
70679
|
+
// Preserve endpoint-derived spans when physical metadata is absent.
|
|
70680
|
+
allowBlindAndBuriedVias: true
|
|
70681
|
+
})
|
|
69973
70682
|
});
|
|
69974
70683
|
previousWire = void 0;
|
|
69975
70684
|
continue;
|
|
@@ -84818,7 +85527,12 @@ function routeAlternateSignalDogbones(input, options, attempt) {
|
|
|
84818
85527
|
},
|
|
84819
85528
|
connections: input.connections.map((c2) => ({
|
|
84820
85529
|
...c2,
|
|
84821
|
-
pointsToConnect: c2.pointsToConnect.map((p2) =>
|
|
85530
|
+
pointsToConnect: c2.pointsToConnect.map((p2) => {
|
|
85531
|
+
const point52 = rotate22(p2, turns);
|
|
85532
|
+
if (!point52.layers) return point52;
|
|
85533
|
+
const { layer: _layer, ...handoff } = point52;
|
|
85534
|
+
return handoff;
|
|
85535
|
+
})
|
|
84822
85536
|
})),
|
|
84823
85537
|
obstacles: input.obstacles.map((o2) => ({
|
|
84824
85538
|
...o2,
|
|
@@ -87589,7 +88303,7 @@ function initialSignalDogbones(input, options, attempt) {
|
|
|
87589
88303
|
throw error;
|
|
87590
88304
|
const targets = new Map(options.targetLayers);
|
|
87591
88305
|
const available = (c2, layer) => (!input.allowedLayers || input.allowedLayers.includes(layer)) && c2.pointsToConnect.every(
|
|
87592
|
-
(p2) => p2.
|
|
88306
|
+
(p2) => (p2.layers ?? [p2.layer]).includes(layer) && (p2.layers !== void 0 || isUnroutedComponentPad(input, c2, p2))
|
|
87593
88307
|
) && (input.buses ?? []).every(
|
|
87594
88308
|
(b2) => !b2.connectionNames.includes(c2.name) || !b2.allowedLayers || b2.allowedLayers.includes(layer)
|
|
87595
88309
|
);
|
|
@@ -87732,6 +88446,7 @@ function* routeMultiTerminalBuses(input, options) {
|
|
|
87732
88446
|
}).sort((a2, b2) => b2.padCount - a2.padCount).map(({ terminal }) => terminal)
|
|
87733
88447
|
}));
|
|
87734
88448
|
const completed = [];
|
|
88449
|
+
const physicalLayers = getCopperLayerNames3(input.layerCount);
|
|
87735
88450
|
let groups = [
|
|
87736
88451
|
connections.map((connection) => ({
|
|
87737
88452
|
...connection,
|
|
@@ -87758,8 +88473,6 @@ function* routeMultiTerminalBuses(input, options) {
|
|
|
87758
88473
|
(pair) => pair.connectionNames.every((name) => names.has(name))
|
|
87759
88474
|
)
|
|
87760
88475
|
};
|
|
87761
|
-
if (terminalIndex > 1)
|
|
87762
|
-
request.allowedLayers = [group[0].pointsToConnect[1].layer];
|
|
87763
88476
|
const solver = new BusLanesPipelineSolver(request, options);
|
|
87764
88477
|
while (!solver.solved && !solver.failed) {
|
|
87765
88478
|
solver.step();
|
|
@@ -87780,18 +88493,36 @@ function* routeMultiTerminalBuses(input, options) {
|
|
|
87780
88493
|
if (!terminal) continue;
|
|
87781
88494
|
if (!effectiveCarrierLayers(input, connection).includes(terminal.layer))
|
|
87782
88495
|
throw Error("No permitted surface layer for a multi-terminal branch");
|
|
87783
|
-
const attachments = completed.filter((trace) => trace.connection_name === connection.name).flatMap(
|
|
87784
|
-
|
|
87785
|
-
if (point52.route_type
|
|
87786
|
-
|
|
87787
|
-
|
|
87788
|
-
|
|
87789
|
-
|
|
87790
|
-
|
|
87791
|
-
|
|
87792
|
-
|
|
87793
|
-
|
|
87794
|
-
|
|
88496
|
+
const attachments = completed.filter((trace) => trace.connection_name === connection.name).flatMap((trace) => {
|
|
88497
|
+
const vias = trace.route.flatMap((point52) => {
|
|
88498
|
+
if (point52.route_type !== "via") return [];
|
|
88499
|
+
const layers = getRouteViaSpanLayers3({
|
|
88500
|
+
fromLayer: point52.from_layer,
|
|
88501
|
+
toLayer: point52.to_layer,
|
|
88502
|
+
layers: point52.layers,
|
|
88503
|
+
layerNames: physicalLayers,
|
|
88504
|
+
allowBlindAndBuriedVias: input.allowBlindAndBuriedVias ?? false
|
|
88505
|
+
});
|
|
88506
|
+
if (!layers.includes(terminal.layer)) return [];
|
|
88507
|
+
return [{ x: point52.x, y: point52.y, layer: terminal.layer, layers }];
|
|
88508
|
+
});
|
|
88509
|
+
return [
|
|
88510
|
+
...vias,
|
|
88511
|
+
...trace.route.flatMap(
|
|
88512
|
+
(point52) => point52.route_type === "wire" && point52.layer === terminal.layer ? [point52] : []
|
|
88513
|
+
)
|
|
88514
|
+
];
|
|
88515
|
+
});
|
|
88516
|
+
const carrierLayers = effectiveCarrierLayers(input, connection);
|
|
88517
|
+
attachments.sort((a2, b2) => {
|
|
88518
|
+
const reachesAnotherCarrierA = !!a2.layers?.some(
|
|
88519
|
+
(layer) => layer !== terminal.layer && carrierLayers.includes(layer)
|
|
88520
|
+
);
|
|
88521
|
+
const reachesAnotherCarrierB = !!b2.layers?.some(
|
|
88522
|
+
(layer) => layer !== terminal.layer && carrierLayers.includes(layer)
|
|
88523
|
+
);
|
|
88524
|
+
return Number(reachesAnotherCarrierB) - Number(reachesAnotherCarrierA) || Math.hypot(a2.x - terminal.x, a2.y - terminal.y) - Math.hypot(b2.x - terminal.x, b2.y - terminal.y);
|
|
88525
|
+
});
|
|
87795
88526
|
if (!attachments.length)
|
|
87796
88527
|
throw Error("No routed copper for a multi-terminal branch");
|
|
87797
88528
|
const branch = {
|
|
@@ -114658,16 +115389,18 @@ function* expandedSignalSites({
|
|
|
114658
115389
|
);
|
|
114659
115390
|
for (const end of [0, 1]) {
|
|
114660
115391
|
const pad = connection.pointsToConnect[end];
|
|
114661
|
-
if (pad.
|
|
115392
|
+
if ((pad.layers ?? [pad.layer]).includes(targetLayer2)) {
|
|
115393
|
+
const { layers: _layers, ...fixedPad } = pad;
|
|
115394
|
+
const point52 = { ...fixedPad, layer: targetLayer2 };
|
|
114662
115395
|
ends[end].push({
|
|
114663
|
-
point:
|
|
115396
|
+
point: point52,
|
|
114664
115397
|
length: 0,
|
|
114665
115398
|
escape: {
|
|
114666
115399
|
type: "pcb_trace",
|
|
114667
115400
|
pcb_trace_id: `expanded_surface_${connection.name}_${end}`,
|
|
114668
115401
|
connection_name: connection.name,
|
|
114669
115402
|
source_trace_id: connection.source_trace_id ?? connection.name,
|
|
114670
|
-
route: [{ ...
|
|
115403
|
+
route: [{ ...point52, route_type: "wire", width }]
|
|
114671
115404
|
}
|
|
114672
115405
|
});
|
|
114673
115406
|
continue;
|
|
@@ -116208,9 +116941,12 @@ function* negotiateSignalSites(state, remove, stopWithOneRemaining = false, expa
|
|
|
116208
116941
|
const carrierLayers = signalLayers(native, connection);
|
|
116209
116942
|
for (let end = 0; end < 2; end++) {
|
|
116210
116943
|
const point52 = connection.pointsToConnect[end];
|
|
116211
|
-
|
|
116944
|
+
for (const layer of carrierLayers) {
|
|
116945
|
+
if (!(point52.layers ?? [point52.layer]).includes(layer)) continue;
|
|
116946
|
+
const { layers: _layers, ...fixedPoint } = point52;
|
|
116947
|
+
const handoff = { ...fixedPoint, layer };
|
|
116212
116948
|
ends[end].push({
|
|
116213
|
-
point:
|
|
116949
|
+
point: handoff,
|
|
116214
116950
|
escape: {
|
|
116215
116951
|
type: "pcb_trace",
|
|
116216
116952
|
pcb_trace_id: `local_surface_${connection.name}_${end}`,
|
|
@@ -116218,14 +116954,14 @@ function* negotiateSignalSites(state, remove, stopWithOneRemaining = false, expa
|
|
|
116218
116954
|
source_trace_id: connection.source_trace_id ?? connection.name,
|
|
116219
116955
|
route: [
|
|
116220
116956
|
{
|
|
116221
|
-
...
|
|
116957
|
+
...handoff,
|
|
116222
116958
|
route_type: "wire",
|
|
116223
|
-
layer: point52.layer,
|
|
116224
116959
|
width: signalWidth(native, connection)
|
|
116225
116960
|
}
|
|
116226
116961
|
]
|
|
116227
116962
|
}
|
|
116228
116963
|
});
|
|
116964
|
+
}
|
|
116229
116965
|
}
|
|
116230
116966
|
for (let variant = 0; variant < 4; variant++) {
|
|
116231
116967
|
try {
|
|
@@ -122123,6 +122859,29 @@ var BusLanesPipelineSolver = class extends BaseSolver9 {
|
|
|
122123
122859
|
this.phase = "native_pair_approaches";
|
|
122124
122860
|
}
|
|
122125
122861
|
}
|
|
122862
|
+
isNegotiableTerminal(connection, point52) {
|
|
122863
|
+
if (isUnroutedComponentPad(this.routingInput, connection, point52))
|
|
122864
|
+
return true;
|
|
122865
|
+
if (!point52.layers?.length || !point52.layers.includes(point52.layer))
|
|
122866
|
+
return false;
|
|
122867
|
+
const physical = getCopperLayerNames3(this.routingInput.layerCount);
|
|
122868
|
+
return !!this.routingInput.traces?.some(
|
|
122869
|
+
(trace) => (trace.connection_name === connection.name || connection.source_trace_id !== void 0 && trace.source_trace_id === connection.source_trace_id) && trace.route.some((via) => {
|
|
122870
|
+
if (via.route_type !== "via" || Math.hypot(via.x - point52.x, via.y - point52.y) > 1e-8)
|
|
122871
|
+
return false;
|
|
122872
|
+
const span = getRouteViaSpanLayers3({
|
|
122873
|
+
fromLayer: via.from_layer,
|
|
122874
|
+
toLayer: via.to_layer,
|
|
122875
|
+
layers: via.layers,
|
|
122876
|
+
layerNames: physical,
|
|
122877
|
+
allowBlindAndBuriedVias: this.routingInput.allowBlindAndBuriedVias ?? false
|
|
122878
|
+
});
|
|
122879
|
+
return point52.layers.every(
|
|
122880
|
+
(layer) => physical.includes(layer) && span.includes(layer)
|
|
122881
|
+
);
|
|
122882
|
+
})
|
|
122883
|
+
);
|
|
122884
|
+
}
|
|
122126
122885
|
getConstructorParams() {
|
|
122127
122886
|
return [this.input, this.options];
|
|
122128
122887
|
}
|
|
@@ -122442,8 +123201,10 @@ var BusLanesPipelineSolver = class extends BaseSolver9 {
|
|
|
122442
123201
|
)
|
|
122443
123202
|
);
|
|
122444
123203
|
this.canNegotiateGeneratedSites = !!(usedNativeFallback && this.routingInput.traces?.length && this.options.denseSearch && this.options.smoothTuning && !this.routingInput.differentialPairs?.length && this.routingInput.connections.every(
|
|
122445
|
-
(connection) => connection.pointsToConnect.
|
|
123204
|
+
(connection) => connection.pointsToConnect.some(
|
|
122446
123205
|
(point52) => isUnroutedComponentPad(this.routingInput, connection, point52)
|
|
123206
|
+
) && connection.pointsToConnect.every(
|
|
123207
|
+
(point52) => this.isNegotiableTerminal(connection, point52)
|
|
122447
123208
|
)
|
|
122448
123209
|
));
|
|
122449
123210
|
const terminalLayers = /* @__PURE__ */ new Map();
|
|
@@ -158599,7 +159360,7 @@ var RoutingPhasePreparationError = class extends Error {
|
|
|
158599
159360
|
var package_default = {
|
|
158600
159361
|
name: "@tscircuit/core",
|
|
158601
159362
|
type: "module",
|
|
158602
|
-
version: "0.0.
|
|
159363
|
+
version: "0.0.2301",
|
|
158603
159364
|
types: "dist/index.d.ts",
|
|
158604
159365
|
main: "dist/index.js",
|
|
158605
159366
|
module: "dist/index.js",
|
|
@@ -158637,9 +159398,9 @@ var package_default = {
|
|
|
158637
159398
|
"@tsci/tscircuit.ti": "github:tscircuit/ti#57e314be4b2b06bc546d4def7453e619604d1157",
|
|
158638
159399
|
"@tscircuit/alphabet": "0.0.25",
|
|
158639
159400
|
"@tscircuit/bga-fanout-solver": "github:tscircuit/bga-fanout-solver#247c835cb8d69b65e53891dcf869731079415b39",
|
|
158640
|
-
"@tscircuit/bus-lanes-solver": "https://jscdn.tscircuit.com/@tscircuit/bus-lanes-solver/0.0.
|
|
159401
|
+
"@tscircuit/bus-lanes-solver": "https://jscdn.tscircuit.com/@tscircuit/bus-lanes-solver/0.0.49.tgz",
|
|
158641
159402
|
"@tscircuit/cableprinter": "^0.0.6",
|
|
158642
|
-
"@tscircuit/capacity-autorouter": "^0.0.
|
|
159403
|
+
"@tscircuit/capacity-autorouter": "^0.0.1060",
|
|
158643
159404
|
"@tscircuit/checks": "^0.0.270",
|
|
158644
159405
|
"@tscircuit/circuit-json-util": "^0.0.128",
|
|
158645
159406
|
"@tscircuit/common": "^0.0.20",
|
|
@@ -158677,12 +159438,12 @@ var package_default = {
|
|
|
158677
159438
|
"bun-match-svg": "0.0.12",
|
|
158678
159439
|
"calculate-elbow": "^0.0.12",
|
|
158679
159440
|
"chokidar-cli": "^3.0.0",
|
|
158680
|
-
"circuit-json": "^0.0.
|
|
159441
|
+
"circuit-json": "^0.0.548",
|
|
158681
159442
|
"circuit-json-to-bom-csv": "^0.0.28",
|
|
158682
159443
|
"circuit-json-to-bpc": "^0.0.13",
|
|
158683
159444
|
"circuit-json-to-connectivity-map": "^0.0.33",
|
|
158684
159445
|
"circuit-json-to-spice": "^0.0.45",
|
|
158685
|
-
"circuit-to-svg": "^0.0.
|
|
159446
|
+
"circuit-to-svg": "^0.0.457",
|
|
158686
159447
|
concurrently: "^9.1.2",
|
|
158687
159448
|
"connectivity-map": "^1.0.1",
|
|
158688
159449
|
debug: "^4.3.6",
|
|
@@ -158769,7 +159530,7 @@ var package_default = {
|
|
|
158769
159530
|
overrides: {
|
|
158770
159531
|
"@tscircuit/graphics-debug-3d": "https://jscdn.tscircuit.com/@tscircuit/graphics-debug-3d/0.0.1.tgz",
|
|
158771
159532
|
"@tscircuit/props": "^0.0.721",
|
|
158772
|
-
"circuit-json": "^0.0.
|
|
159533
|
+
"circuit-json": "^0.0.548",
|
|
158773
159534
|
"@tscircuit/cableprinter": "^0.0.6"
|
|
158774
159535
|
},
|
|
158775
159536
|
browser: {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscircuit/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.2302",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.js",
|
|
@@ -39,9 +39,9 @@
|
|
|
39
39
|
"@tsci/tscircuit.ti": "github:tscircuit/ti#57e314be4b2b06bc546d4def7453e619604d1157",
|
|
40
40
|
"@tscircuit/alphabet": "0.0.25",
|
|
41
41
|
"@tscircuit/bga-fanout-solver": "github:tscircuit/bga-fanout-solver#247c835cb8d69b65e53891dcf869731079415b39",
|
|
42
|
-
"@tscircuit/bus-lanes-solver": "https://jscdn.tscircuit.com/@tscircuit/bus-lanes-solver/0.0.
|
|
42
|
+
"@tscircuit/bus-lanes-solver": "https://jscdn.tscircuit.com/@tscircuit/bus-lanes-solver/0.0.49.tgz",
|
|
43
43
|
"@tscircuit/cableprinter": "^0.0.6",
|
|
44
|
-
"@tscircuit/capacity-autorouter": "^0.0.
|
|
44
|
+
"@tscircuit/capacity-autorouter": "^0.0.1060",
|
|
45
45
|
"@tscircuit/checks": "^0.0.270",
|
|
46
46
|
"@tscircuit/circuit-json-util": "^0.0.128",
|
|
47
47
|
"@tscircuit/common": "^0.0.20",
|
|
@@ -79,12 +79,12 @@
|
|
|
79
79
|
"bun-match-svg": "0.0.12",
|
|
80
80
|
"calculate-elbow": "^0.0.12",
|
|
81
81
|
"chokidar-cli": "^3.0.0",
|
|
82
|
-
"circuit-json": "^0.0.
|
|
82
|
+
"circuit-json": "^0.0.548",
|
|
83
83
|
"circuit-json-to-bom-csv": "^0.0.28",
|
|
84
84
|
"circuit-json-to-bpc": "^0.0.13",
|
|
85
85
|
"circuit-json-to-connectivity-map": "^0.0.33",
|
|
86
86
|
"circuit-json-to-spice": "^0.0.45",
|
|
87
|
-
"circuit-to-svg": "^0.0.
|
|
87
|
+
"circuit-to-svg": "^0.0.457",
|
|
88
88
|
"concurrently": "^9.1.2",
|
|
89
89
|
"connectivity-map": "^1.0.1",
|
|
90
90
|
"debug": "^4.3.6",
|
|
@@ -171,7 +171,7 @@
|
|
|
171
171
|
"overrides": {
|
|
172
172
|
"@tscircuit/graphics-debug-3d": "https://jscdn.tscircuit.com/@tscircuit/graphics-debug-3d/0.0.1.tgz",
|
|
173
173
|
"@tscircuit/props": "^0.0.721",
|
|
174
|
-
"circuit-json": "^0.0.
|
|
174
|
+
"circuit-json": "^0.0.548",
|
|
175
175
|
"@tscircuit/cableprinter": "^0.0.6"
|
|
176
176
|
},
|
|
177
177
|
"browser": {
|