@willcgage/module-schematic 0.40.0 → 0.42.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 +76 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +60 -2
- package/dist/index.d.ts +60 -2
- package/dist/index.js +73 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -617,7 +617,11 @@ function buildTransition(state) {
|
|
|
617
617
|
// Branton, #131). Main 1 runs the full module; Main 2 is the branch.
|
|
618
618
|
onTrack: MAIN_TRACK_ID,
|
|
619
619
|
divergeTrack: MAIN2_TRACK_ID,
|
|
620
|
-
|
|
620
|
+
// Hand so the diverging leg lands on Main 2's side. Main 2 extends toward
|
|
621
|
+
// the double end (sign −1 west / +1 east) and sits above (+1) or, when the
|
|
622
|
+
// mains are swapped, below (−1). divergeSideForHand(left)=sign(toward),
|
|
623
|
+
// (right)=−sign(toward), so pick the hand whose side matches Main 2's (#131).
|
|
624
|
+
kind: (aDouble ? -1 : 1) === (state.mainsSwapped ? -1 : 1) ? "left" : "right"
|
|
621
625
|
};
|
|
622
626
|
const cpId = nextId("cp", state.controlPoints.map((c) => c.id));
|
|
623
627
|
const sig = (facing) => ({
|
|
@@ -691,7 +695,9 @@ function stateToDoc(state, recordNumber) {
|
|
|
691
695
|
// C, D, E…
|
|
692
696
|
label: b.label || `Branch ${i + 1}`,
|
|
693
697
|
tracks: [{ trackId: MAIN_TRACK_ID, lane: 0, config: b.config }],
|
|
694
|
-
at: { pos: b.pos, side: b.side }
|
|
698
|
+
at: { pos: b.pos, side: b.side },
|
|
699
|
+
kind: b.kind ?? "branch",
|
|
700
|
+
...b.trackId ? { trackId: b.trackId } : {}
|
|
695
701
|
}))
|
|
696
702
|
],
|
|
697
703
|
state.poseOverrides
|
|
@@ -893,7 +899,9 @@ function docToState(doc, fallbackLength, moduleTracks = []) {
|
|
|
893
899
|
label: ep.label ?? "Branch",
|
|
894
900
|
pos: sc(ep.at.pos),
|
|
895
901
|
side: ep.at.side === "down" ? "down" : "up",
|
|
896
|
-
config: ep.tracks?.[0]?.config === "double" ? "double" : "single"
|
|
902
|
+
config: ep.tracks?.[0]?.config === "double" ? "double" : "single",
|
|
903
|
+
kind: ep.kind === "main" ? "main" : "branch",
|
|
904
|
+
trackId: ep.trackId ?? null
|
|
897
905
|
})),
|
|
898
906
|
poseOverrides,
|
|
899
907
|
endplateWidths,
|
|
@@ -1403,6 +1411,67 @@ function deriveEndplatePoses(geo) {
|
|
|
1403
1411
|
}
|
|
1404
1412
|
return poses;
|
|
1405
1413
|
}
|
|
1414
|
+
var ENDPLATE_LEAD_INCHES = 4;
|
|
1415
|
+
var ENDPLATE_FASCIA_CLEAR_INCHES = 4;
|
|
1416
|
+
function endplateLead(pose, leadInches = ENDPLATE_LEAD_INCHES) {
|
|
1417
|
+
const inwardHeading = norm360(pose.heading + 180);
|
|
1418
|
+
const r = inwardHeading * DEG;
|
|
1419
|
+
return {
|
|
1420
|
+
face: { x: pose.x, y: pose.y },
|
|
1421
|
+
inboard: { x: pose.x + Math.cos(r) * leadInches, y: pose.y + Math.sin(r) * leadInches },
|
|
1422
|
+
inwardHeading
|
|
1423
|
+
};
|
|
1424
|
+
}
|
|
1425
|
+
function trackMeetsEndplateIssues(path, pose, opts) {
|
|
1426
|
+
const issues = [];
|
|
1427
|
+
const lead = opts?.leadInches ?? ENDPLATE_LEAD_INCHES;
|
|
1428
|
+
const tol = opts?.toleranceDeg ?? 5;
|
|
1429
|
+
if (path && path.length >= 2) {
|
|
1430
|
+
const seq = (opts?.end ?? "last") === "last" ? [...path].reverse() : path.slice();
|
|
1431
|
+
const p0 = seq[0];
|
|
1432
|
+
const p1 = seq[1];
|
|
1433
|
+
const wantIn = norm360(pose.heading + 180);
|
|
1434
|
+
const inHead = norm360(Math.atan2(p1.y - p0.y, p1.x - p0.x) / DEG);
|
|
1435
|
+
const diff = Math.abs((inHead - wantIn + 540) % 360 - 180);
|
|
1436
|
+
if (diff > tol)
|
|
1437
|
+
issues.push({
|
|
1438
|
+
code: "not-perpendicular",
|
|
1439
|
+
message: `Track must cross the endplate square (within ${tol}\xB0); it is off by ${Math.round(diff)}\xB0.`
|
|
1440
|
+
});
|
|
1441
|
+
const r = wantIn * DEG;
|
|
1442
|
+
const ux = Math.cos(r);
|
|
1443
|
+
const uy = Math.sin(r);
|
|
1444
|
+
let curved = false;
|
|
1445
|
+
let acc = 0;
|
|
1446
|
+
for (let i = 1; i < seq.length && acc < lead; i++) {
|
|
1447
|
+
const a = seq[i - 1];
|
|
1448
|
+
const b = seq[i];
|
|
1449
|
+
if (a.bulge) curved = true;
|
|
1450
|
+
const rx = b.x - p0.x;
|
|
1451
|
+
const ry = b.y - p0.y;
|
|
1452
|
+
const along = rx * ux + ry * uy;
|
|
1453
|
+
const lat = Math.abs(rx * -uy + ry * ux);
|
|
1454
|
+
if (along <= lead + 0.01 && lat > 0.25) curved = true;
|
|
1455
|
+
acc += Math.hypot(b.x - a.x, b.y - a.y);
|
|
1456
|
+
}
|
|
1457
|
+
if (curved)
|
|
1458
|
+
issues.push({
|
|
1459
|
+
code: "short-lead",
|
|
1460
|
+
message: `The first ${lead}\u2033 from the endplate must be straight and perpendicular.`
|
|
1461
|
+
});
|
|
1462
|
+
}
|
|
1463
|
+
const w = opts?.faceWidthInches;
|
|
1464
|
+
const off = opts?.trackOffsetInches;
|
|
1465
|
+
if (typeof w === "number" && w > 0 && typeof off === "number") {
|
|
1466
|
+
const clear = w / 2 - Math.abs(off);
|
|
1467
|
+
if (clear < ENDPLATE_FASCIA_CLEAR_INCHES)
|
|
1468
|
+
issues.push({
|
|
1469
|
+
code: "fascia-clearance",
|
|
1470
|
+
message: `Track must stay \u2265${ENDPLATE_FASCIA_CLEAR_INCHES}\u2033 from either fascia; it is ${clear.toFixed(1)}\u2033.`
|
|
1471
|
+
});
|
|
1472
|
+
}
|
|
1473
|
+
return issues;
|
|
1474
|
+
}
|
|
1406
1475
|
function poseNeedsManual(geometryType) {
|
|
1407
1476
|
return geometryType === "wye" || geometryType === "other";
|
|
1408
1477
|
}
|
|
@@ -1416,6 +1485,8 @@ function poseOverridesFromDoc(doc) {
|
|
|
1416
1485
|
return out;
|
|
1417
1486
|
}
|
|
1418
1487
|
|
|
1488
|
+
exports.ENDPLATE_FASCIA_CLEAR_INCHES = ENDPLATE_FASCIA_CLEAR_INCHES;
|
|
1489
|
+
exports.ENDPLATE_LEAD_INCHES = ENDPLATE_LEAD_INCHES;
|
|
1419
1490
|
exports.FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES = FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES;
|
|
1420
1491
|
exports.FREEMO_ENDPLATE_WIDTH_MIN_INCHES = FREEMO_ENDPLATE_WIDTH_MIN_INCHES;
|
|
1421
1492
|
exports.FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES = FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES;
|
|
@@ -1438,6 +1509,7 @@ exports.divergeSideForHand = divergeSideForHand;
|
|
|
1438
1509
|
exports.docToState = docToState;
|
|
1439
1510
|
exports.emptyEditorState = emptyEditorState;
|
|
1440
1511
|
exports.endplateFaceSegments = endplateFaceSegments;
|
|
1512
|
+
exports.endplateLead = endplateLead;
|
|
1441
1513
|
exports.endplateTrackOffsetFor = endplateTrackOffsetFor;
|
|
1442
1514
|
exports.endplateTrackOffsetInches = endplateTrackOffsetInches;
|
|
1443
1515
|
exports.endplateWidthInches = endplateWidthInches;
|
|
@@ -1471,6 +1543,7 @@ exports.sectionedEndPose = sectionedEndPose;
|
|
|
1471
1543
|
exports.sliceCenterline = sliceCenterline;
|
|
1472
1544
|
exports.stateToDoc = stateToDoc;
|
|
1473
1545
|
exports.toSectionRelative = toSectionRelative;
|
|
1546
|
+
exports.trackMeetsEndplateIssues = trackMeetsEndplateIssues;
|
|
1474
1547
|
exports.trackPath = trackPath;
|
|
1475
1548
|
//# sourceMappingURL=index.cjs.map
|
|
1476
1549
|
//# sourceMappingURL=index.cjs.map
|