@willcgage/module-schematic 0.93.0 → 0.95.0
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.cjs +57 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -1
- package/dist/index.d.ts +38 -1
- package/dist/index.js +55 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2306,6 +2306,16 @@ function pieceRoutePaths(piece, library = BUILT_IN_TRACK_PARTS) {
|
|
|
2306
2306
|
}
|
|
2307
2307
|
return out;
|
|
2308
2308
|
}
|
|
2309
|
+
function pieceHand(part, flipped) {
|
|
2310
|
+
const n = part.partNumbers;
|
|
2311
|
+
if (!n?.left || !n?.right) return null;
|
|
2312
|
+
return flipped ? "right" : "left";
|
|
2313
|
+
}
|
|
2314
|
+
function piecePartNumber(part, flipped) {
|
|
2315
|
+
const hand = pieceHand(part, flipped);
|
|
2316
|
+
if (!hand) return part.partNumbers?.single;
|
|
2317
|
+
return part.partNumbers?.[hand];
|
|
2318
|
+
}
|
|
2309
2319
|
function partsPlaceable(library = BUILT_IN_TRACK_PARTS) {
|
|
2310
2320
|
const placeable = [];
|
|
2311
2321
|
const blocked = [];
|
|
@@ -2442,6 +2452,33 @@ function snapPiece(moving, others, library = BUILT_IN_TRACK_PARTS, withinInches
|
|
|
2442
2452
|
to: best.t.key
|
|
2443
2453
|
};
|
|
2444
2454
|
}
|
|
2455
|
+
function fitFlexBetween(piece, others, library = BUILT_IN_TRACK_PARTS, withinInches = 0.5) {
|
|
2456
|
+
const part = library.find((p) => p.id === piece.partId);
|
|
2457
|
+
if (part?.kind !== "flex" || piece.radiusInches) return null;
|
|
2458
|
+
const mine = placedJoints([piece], library);
|
|
2459
|
+
const far = mine.find((j) => j.joint === "b");
|
|
2460
|
+
const near = mine.find((j) => j.joint === "a");
|
|
2461
|
+
if (!far || !near) return null;
|
|
2462
|
+
const graph = buildTrackGraph(others, library);
|
|
2463
|
+
const taken = new Set(graph.connections.flatMap((c) => [c.a, c.b]));
|
|
2464
|
+
let best = null;
|
|
2465
|
+
for (const j of graph.joints) {
|
|
2466
|
+
if (taken.has(j.key)) continue;
|
|
2467
|
+
if (Math.hypot(j.x - near.x, j.y - near.y) <= JOINT_SNAP_INCHES) continue;
|
|
2468
|
+
const d = Math.hypot(j.x - far.x, j.y - far.y);
|
|
2469
|
+
if (d <= withinInches && (!best || d < best.d)) best = { j, d };
|
|
2470
|
+
}
|
|
2471
|
+
if (!best) return null;
|
|
2472
|
+
const dx = best.j.x - piece.x;
|
|
2473
|
+
const dy = best.j.y - piece.y;
|
|
2474
|
+
const len = Math.hypot(dx, dy);
|
|
2475
|
+
if (!(len > 0)) return null;
|
|
2476
|
+
return {
|
|
2477
|
+
...piece,
|
|
2478
|
+
rotationDeg: norm360(Math.atan2(dy, dx) * 180 / Math.PI),
|
|
2479
|
+
lengthInches: Math.round(len * 1e3) / 1e3
|
|
2480
|
+
};
|
|
2481
|
+
}
|
|
2445
2482
|
var danglingDivergeWarning = (id) => `the route diverging at ${id} is not connected to anything`;
|
|
2446
2483
|
var unreachedWarning = (id) => `${id} is not reachable from the endplate \u2014 nothing connects it`;
|
|
2447
2484
|
function walkTrackGraph(graph, pieces, startAt, library = BUILT_IN_TRACK_PARTS) {
|
|
@@ -2635,9 +2672,16 @@ function graphToDoc(pieces, input) {
|
|
|
2635
2672
|
const trackIdOf = /* @__PURE__ */ new Map([["main", MAIN_TRACK_ID]]);
|
|
2636
2673
|
if (twoMains) trackIdOf.set("main2:main", MAIN2_TRACK_ID);
|
|
2637
2674
|
for (const r of branches) trackIdOf.set(r.id, r.pieces[0]);
|
|
2638
|
-
const
|
|
2675
|
+
const emitted = /* @__PURE__ */ new Set();
|
|
2676
|
+
const uniqueBranches = branches.filter((r) => {
|
|
2677
|
+
const id = trackIdOf.get(r.id);
|
|
2678
|
+
if (emitted.has(id)) return false;
|
|
2679
|
+
emitted.add(id);
|
|
2680
|
+
return true;
|
|
2681
|
+
});
|
|
2682
|
+
const laneOf = (r, among) => {
|
|
2639
2683
|
const side = Math.sign(r.lateral) || 1;
|
|
2640
|
-
const sameSide =
|
|
2684
|
+
const sameSide = among.filter((x) => (Math.sign(x.lateral) || 1) === side).sort((a, b) => Math.abs(a.lateral) - Math.abs(b.lateral));
|
|
2641
2685
|
const taken = side === main2Lane ? 1 : 0;
|
|
2642
2686
|
return side * (sameSide.indexOf(r) + 1 + taken);
|
|
2643
2687
|
};
|
|
@@ -2663,7 +2707,7 @@ function graphToDoc(pieces, input) {
|
|
|
2663
2707
|
}
|
|
2664
2708
|
] : []
|
|
2665
2709
|
];
|
|
2666
|
-
for (const r of
|
|
2710
|
+
for (const r of uniqueBranches) {
|
|
2667
2711
|
const id = trackIdOf.get(r.id);
|
|
2668
2712
|
const meta = input.meta?.[id] ?? {};
|
|
2669
2713
|
tracks.push({
|
|
@@ -2671,7 +2715,7 @@ function graphToDoc(pieces, input) {
|
|
|
2671
2715
|
// It runs back into a second turnout, or it doesn't. That is the whole
|
|
2672
2716
|
// difference between a siding and a spur, and it is read, not declared.
|
|
2673
2717
|
role: r.endsAt ? "siding" : "spur",
|
|
2674
|
-
lane: laneOf(r),
|
|
2718
|
+
lane: laneOf(r, uniqueBranches),
|
|
2675
2719
|
fromPos: round(Math.min(r.fromPos, r.toPos)),
|
|
2676
2720
|
toPos: round(Math.max(r.fromPos, r.toPos)),
|
|
2677
2721
|
...meta.trackName ? { trackName: meta.trackName } : {},
|
|
@@ -2722,6 +2766,12 @@ function graphToDoc(pieces, input) {
|
|
|
2722
2766
|
});
|
|
2723
2767
|
}
|
|
2724
2768
|
turnouts.sort((a, b) => a.pos - b.pos);
|
|
2769
|
+
for (const t of tracks) {
|
|
2770
|
+
if (t.role === "main") continue;
|
|
2771
|
+
const ends = turnouts.filter((sw) => sw.divergeTrack === t.id);
|
|
2772
|
+
if (ends.length >= 2 && new Set(ends.map((sw) => sw.onTrack)).size >= 2)
|
|
2773
|
+
t.role = "crossover";
|
|
2774
|
+
}
|
|
2725
2775
|
const place = (a, what) => {
|
|
2726
2776
|
if (!a) return null;
|
|
2727
2777
|
const hit = resolveGraphAnchor(a, walk, pieces, library);
|
|
@@ -3475,6 +3525,7 @@ exports.endplateFaceSegments = endplateFaceSegments;
|
|
|
3475
3525
|
exports.endplateLead = endplateLead;
|
|
3476
3526
|
exports.endplateTrackOffsetInches = endplateTrackOffsetInches;
|
|
3477
3527
|
exports.endplateWidthInches = endplateWidthInches;
|
|
3528
|
+
exports.fitFlexBetween = fitFlexBetween;
|
|
3478
3529
|
exports.flexPartFor = flexPartFor;
|
|
3479
3530
|
exports.flexParts = flexParts;
|
|
3480
3531
|
exports.flexPieces = flexPieces;
|
|
@@ -3510,6 +3561,8 @@ exports.partOutlineAtFrog = partOutlineAtFrog;
|
|
|
3510
3561
|
exports.partsPlaceable = partsPlaceable;
|
|
3511
3562
|
exports.pastFrogInchesForSize = pastFrogInchesForSize;
|
|
3512
3563
|
exports.pathLengthInches = pathLengthInches;
|
|
3564
|
+
exports.pieceHand = pieceHand;
|
|
3565
|
+
exports.piecePartNumber = piecePartNumber;
|
|
3513
3566
|
exports.pieceRoutePaths = pieceRoutePaths;
|
|
3514
3567
|
exports.placedJoints = placedJoints;
|
|
3515
3568
|
exports.poseNeedsManual = poseNeedsManual;
|