@willcgage/module-schematic 0.93.0 → 0.94.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 +45 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -1
- package/dist/index.d.ts +17 -1
- package/dist/index.js +45 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2442,6 +2442,33 @@ function snapPiece(moving, others, library = BUILT_IN_TRACK_PARTS, withinInches
|
|
|
2442
2442
|
to: best.t.key
|
|
2443
2443
|
};
|
|
2444
2444
|
}
|
|
2445
|
+
function fitFlexBetween(piece, others, library = BUILT_IN_TRACK_PARTS, withinInches = 0.5) {
|
|
2446
|
+
const part = library.find((p) => p.id === piece.partId);
|
|
2447
|
+
if (part?.kind !== "flex" || piece.radiusInches) return null;
|
|
2448
|
+
const mine = placedJoints([piece], library);
|
|
2449
|
+
const far = mine.find((j) => j.joint === "b");
|
|
2450
|
+
const near = mine.find((j) => j.joint === "a");
|
|
2451
|
+
if (!far || !near) return null;
|
|
2452
|
+
const graph = buildTrackGraph(others, library);
|
|
2453
|
+
const taken = new Set(graph.connections.flatMap((c) => [c.a, c.b]));
|
|
2454
|
+
let best = null;
|
|
2455
|
+
for (const j of graph.joints) {
|
|
2456
|
+
if (taken.has(j.key)) continue;
|
|
2457
|
+
if (Math.hypot(j.x - near.x, j.y - near.y) <= JOINT_SNAP_INCHES) continue;
|
|
2458
|
+
const d = Math.hypot(j.x - far.x, j.y - far.y);
|
|
2459
|
+
if (d <= withinInches && (!best || d < best.d)) best = { j, d };
|
|
2460
|
+
}
|
|
2461
|
+
if (!best) return null;
|
|
2462
|
+
const dx = best.j.x - piece.x;
|
|
2463
|
+
const dy = best.j.y - piece.y;
|
|
2464
|
+
const len = Math.hypot(dx, dy);
|
|
2465
|
+
if (!(len > 0)) return null;
|
|
2466
|
+
return {
|
|
2467
|
+
...piece,
|
|
2468
|
+
rotationDeg: norm360(Math.atan2(dy, dx) * 180 / Math.PI),
|
|
2469
|
+
lengthInches: Math.round(len * 1e3) / 1e3
|
|
2470
|
+
};
|
|
2471
|
+
}
|
|
2445
2472
|
var danglingDivergeWarning = (id) => `the route diverging at ${id} is not connected to anything`;
|
|
2446
2473
|
var unreachedWarning = (id) => `${id} is not reachable from the endplate \u2014 nothing connects it`;
|
|
2447
2474
|
function walkTrackGraph(graph, pieces, startAt, library = BUILT_IN_TRACK_PARTS) {
|
|
@@ -2635,9 +2662,16 @@ function graphToDoc(pieces, input) {
|
|
|
2635
2662
|
const trackIdOf = /* @__PURE__ */ new Map([["main", MAIN_TRACK_ID]]);
|
|
2636
2663
|
if (twoMains) trackIdOf.set("main2:main", MAIN2_TRACK_ID);
|
|
2637
2664
|
for (const r of branches) trackIdOf.set(r.id, r.pieces[0]);
|
|
2638
|
-
const
|
|
2665
|
+
const emitted = /* @__PURE__ */ new Set();
|
|
2666
|
+
const uniqueBranches = branches.filter((r) => {
|
|
2667
|
+
const id = trackIdOf.get(r.id);
|
|
2668
|
+
if (emitted.has(id)) return false;
|
|
2669
|
+
emitted.add(id);
|
|
2670
|
+
return true;
|
|
2671
|
+
});
|
|
2672
|
+
const laneOf = (r, among) => {
|
|
2639
2673
|
const side = Math.sign(r.lateral) || 1;
|
|
2640
|
-
const sameSide =
|
|
2674
|
+
const sameSide = among.filter((x) => (Math.sign(x.lateral) || 1) === side).sort((a, b) => Math.abs(a.lateral) - Math.abs(b.lateral));
|
|
2641
2675
|
const taken = side === main2Lane ? 1 : 0;
|
|
2642
2676
|
return side * (sameSide.indexOf(r) + 1 + taken);
|
|
2643
2677
|
};
|
|
@@ -2663,7 +2697,7 @@ function graphToDoc(pieces, input) {
|
|
|
2663
2697
|
}
|
|
2664
2698
|
] : []
|
|
2665
2699
|
];
|
|
2666
|
-
for (const r of
|
|
2700
|
+
for (const r of uniqueBranches) {
|
|
2667
2701
|
const id = trackIdOf.get(r.id);
|
|
2668
2702
|
const meta = input.meta?.[id] ?? {};
|
|
2669
2703
|
tracks.push({
|
|
@@ -2671,7 +2705,7 @@ function graphToDoc(pieces, input) {
|
|
|
2671
2705
|
// It runs back into a second turnout, or it doesn't. That is the whole
|
|
2672
2706
|
// difference between a siding and a spur, and it is read, not declared.
|
|
2673
2707
|
role: r.endsAt ? "siding" : "spur",
|
|
2674
|
-
lane: laneOf(r),
|
|
2708
|
+
lane: laneOf(r, uniqueBranches),
|
|
2675
2709
|
fromPos: round(Math.min(r.fromPos, r.toPos)),
|
|
2676
2710
|
toPos: round(Math.max(r.fromPos, r.toPos)),
|
|
2677
2711
|
...meta.trackName ? { trackName: meta.trackName } : {},
|
|
@@ -2722,6 +2756,12 @@ function graphToDoc(pieces, input) {
|
|
|
2722
2756
|
});
|
|
2723
2757
|
}
|
|
2724
2758
|
turnouts.sort((a, b) => a.pos - b.pos);
|
|
2759
|
+
for (const t of tracks) {
|
|
2760
|
+
if (t.role === "main") continue;
|
|
2761
|
+
const ends = turnouts.filter((sw) => sw.divergeTrack === t.id);
|
|
2762
|
+
if (ends.length >= 2 && new Set(ends.map((sw) => sw.onTrack)).size >= 2)
|
|
2763
|
+
t.role = "crossover";
|
|
2764
|
+
}
|
|
2725
2765
|
const place = (a, what) => {
|
|
2726
2766
|
if (!a) return null;
|
|
2727
2767
|
const hit = resolveGraphAnchor(a, walk, pieces, library);
|
|
@@ -3475,6 +3515,7 @@ exports.endplateFaceSegments = endplateFaceSegments;
|
|
|
3475
3515
|
exports.endplateLead = endplateLead;
|
|
3476
3516
|
exports.endplateTrackOffsetInches = endplateTrackOffsetInches;
|
|
3477
3517
|
exports.endplateWidthInches = endplateWidthInches;
|
|
3518
|
+
exports.fitFlexBetween = fitFlexBetween;
|
|
3478
3519
|
exports.flexPartFor = flexPartFor;
|
|
3479
3520
|
exports.flexParts = flexParts;
|
|
3480
3521
|
exports.flexPieces = flexPieces;
|