@willcgage/module-schematic 0.74.0 → 0.75.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 +68 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +75 -1
- package/dist/index.d.ts +75 -1
- package/dist/index.js +66 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -577,6 +577,56 @@ function scaleFeetToInches(feet, ratio = N_SCALE_RATIO) {
|
|
|
577
577
|
return feet * 12 / ratio;
|
|
578
578
|
}
|
|
579
579
|
var N_CAR_LENGTH_INCHES = 3.3;
|
|
580
|
+
var CLEARANCE_SPACING_INCHES = FREEMO_TRACK_SPACING_INCHES;
|
|
581
|
+
function clearancePointPastFrogInches(size, library = BUILT_IN_TRACK_PARTS, clearanceInches = CLEARANCE_SPACING_INCHES) {
|
|
582
|
+
const N = size > 0 ? size : 6;
|
|
583
|
+
const lead = leadInchesForSize(N, library);
|
|
584
|
+
const cl = turnoutClosure(N, { leadInches: lead });
|
|
585
|
+
let lo = 0;
|
|
586
|
+
let hi = Math.max(4 * lead, 4 * clearanceInches * N);
|
|
587
|
+
if (cl.offsetAt(hi) < clearanceInches) return hi - lead;
|
|
588
|
+
for (let i = 0; i < 60; i++) {
|
|
589
|
+
const mid = (lo + hi) / 2;
|
|
590
|
+
if (cl.offsetAt(mid) < clearanceInches) lo = mid;
|
|
591
|
+
else hi = mid;
|
|
592
|
+
}
|
|
593
|
+
return Math.max(0, hi - lead);
|
|
594
|
+
}
|
|
595
|
+
function usableCapacity(input) {
|
|
596
|
+
const lo = Math.min(input.fromPos, input.toPos);
|
|
597
|
+
const hi = Math.max(input.fromPos, input.toPos);
|
|
598
|
+
const drawn = hi - lo;
|
|
599
|
+
const carLen = input.carLengthInches ?? N_CAR_LENGTH_INCHES;
|
|
600
|
+
if (typeof input.measuredUsableInches === "number" && input.measuredUsableInches >= 0) {
|
|
601
|
+
const m = input.measuredUsableInches;
|
|
602
|
+
return {
|
|
603
|
+
fromPos: lo,
|
|
604
|
+
toPos: lo + m,
|
|
605
|
+
usableInches: m,
|
|
606
|
+
drawnInches: drawn,
|
|
607
|
+
givenUpInches: Math.max(0, drawn - m),
|
|
608
|
+
cars: carCapacity(0, m, carLen),
|
|
609
|
+
scaleFeet: Math.round(inchesToScaleFeet(m))
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
let a = lo;
|
|
613
|
+
let b = hi;
|
|
614
|
+
for (const sw of input.governing ?? []) {
|
|
615
|
+
const c = clearancePointPastFrogInches(sw.size ?? 6, input.library);
|
|
616
|
+
if (Math.abs(sw.pos - lo) <= Math.abs(sw.pos - hi)) a = Math.max(a, lo + c);
|
|
617
|
+
else b = Math.min(b, hi - c);
|
|
618
|
+
}
|
|
619
|
+
const usable = Math.max(0, b - a);
|
|
620
|
+
return {
|
|
621
|
+
fromPos: a,
|
|
622
|
+
toPos: Math.max(a, b),
|
|
623
|
+
usableInches: usable,
|
|
624
|
+
drawnInches: drawn,
|
|
625
|
+
givenUpInches: Math.max(0, drawn - usable),
|
|
626
|
+
cars: carCapacity(0, usable, carLen),
|
|
627
|
+
scaleFeet: Math.round(inchesToScaleFeet(usable))
|
|
628
|
+
};
|
|
629
|
+
}
|
|
580
630
|
function spanOverhang(input) {
|
|
581
631
|
const lo = Math.min(input.fromPos, input.toPos);
|
|
582
632
|
const hi = Math.max(input.fromPos, input.toPos);
|
|
@@ -827,7 +877,17 @@ function stateToDoc(state, recordNumber) {
|
|
|
827
877
|
toPos: t.toPos,
|
|
828
878
|
moduleTrackId: t.moduleTrackId,
|
|
829
879
|
trackName: t.trackName || void 0,
|
|
830
|
-
|
|
880
|
+
// ⚠️ USABLE capacity, measured from the governing turnouts' CLEARANCE
|
|
881
|
+
// POINTS (#19) — not the drawn rail-to-rail length, which counts track
|
|
882
|
+
// a car can't stand on without fouling the route it diverged from.
|
|
883
|
+
// FMN-0040's 70″ siding is 21 cars drawn and 17 usable.
|
|
884
|
+
capacityFeet: usableCapacity({
|
|
885
|
+
fromPos: t.fromPos,
|
|
886
|
+
toPos: t.toPos,
|
|
887
|
+
governing: state.turnouts.filter((sw) => sw.divergeTrack === t.id),
|
|
888
|
+
measuredUsableInches: t.measuredUsableInches
|
|
889
|
+
}).scaleFeet,
|
|
890
|
+
...typeof t.measuredUsableInches === "number" && t.measuredUsableInches >= 0 ? { measuredUsableInches: t.measuredUsableInches } : {},
|
|
831
891
|
...state.loop && t.inLoop ? { inLoop: true } : {},
|
|
832
892
|
...t.path && t.path.length >= 2 ? { path: t.path } : {}
|
|
833
893
|
}))
|
|
@@ -926,7 +986,10 @@ function docToState(doc, fallbackLength, moduleTracks = []) {
|
|
|
926
986
|
trackName: t.trackName ?? nameOf(moduleTrackId),
|
|
927
987
|
...t.inLoop ? { inLoop: true } : {},
|
|
928
988
|
// Authored path kept as-drawn (a physical shape, not rescaled with length).
|
|
929
|
-
...trackPath(t.path) ? { path: trackPath(t.path) } : {}
|
|
989
|
+
...trackPath(t.path) ? { path: trackPath(t.path) } : {},
|
|
990
|
+
// A MEASURED length is a real-world fact about the physical track, so it
|
|
991
|
+
// rescales with the module exactly as its positions do (#20).
|
|
992
|
+
...typeof t.measuredUsableInches === "number" && Number.isFinite(t.measuredUsableInches) ? { measuredUsableInches: sc(t.measuredUsableInches) } : {}
|
|
930
993
|
});
|
|
931
994
|
}
|
|
932
995
|
}
|
|
@@ -2364,6 +2427,7 @@ function poseOverridesFromDoc(doc) {
|
|
|
2364
2427
|
|
|
2365
2428
|
exports.ATLAS_CODE55_N = ATLAS_CODE55_N;
|
|
2366
2429
|
exports.BUILT_IN_TRACK_PARTS = BUILT_IN_TRACK_PARTS;
|
|
2430
|
+
exports.CLEARANCE_SPACING_INCHES = CLEARANCE_SPACING_INCHES;
|
|
2367
2431
|
exports.CODE55_RAIL_HEIGHT_INCHES = CODE55_RAIL_HEIGHT_INCHES;
|
|
2368
2432
|
exports.DEFAULT_FLEX_PART_ID = DEFAULT_FLEX_PART_ID;
|
|
2369
2433
|
exports.ENDPLATE_FASCIA_CLEAR_INCHES = ENDPLATE_FASCIA_CLEAR_INCHES;
|
|
@@ -2389,6 +2453,7 @@ exports.buildPassingSiding = buildPassingSiding;
|
|
|
2389
2453
|
exports.buildTransition = buildTransition;
|
|
2390
2454
|
exports.carCapacity = carCapacity;
|
|
2391
2455
|
exports.checkEndplateWidth = checkEndplateWidth;
|
|
2456
|
+
exports.clearancePointPastFrogInches = clearancePointPastFrogInches;
|
|
2392
2457
|
exports.deriveEndplatePoses = deriveEndplatePoses;
|
|
2393
2458
|
exports.divergeSideForHand = divergeSideForHand;
|
|
2394
2459
|
exports.docToState = docToState;
|
|
@@ -2458,5 +2523,6 @@ exports.turnoutClosure = turnoutClosure;
|
|
|
2458
2523
|
exports.turnoutFacing = turnoutFacing;
|
|
2459
2524
|
exports.turnoutOccupiedSpan = turnoutOccupiedSpan;
|
|
2460
2525
|
exports.turnoutPartForSize = turnoutPartForSize;
|
|
2526
|
+
exports.usableCapacity = usableCapacity;
|
|
2461
2527
|
//# sourceMappingURL=index.cjs.map
|
|
2462
2528
|
//# sourceMappingURL=index.cjs.map
|