@willcgage/module-schematic 0.61.0 → 0.63.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 CHANGED
@@ -669,7 +669,7 @@ function buildTransition(state) {
669
669
  }
670
670
  function withPoses(endplates, overrides) {
671
671
  return endplates.map(
672
- (e) => overrides[e.id] ? { ...e, pose: overrides[e.id] } : e
672
+ (e) => overrides[e.id] ? { ...e, pose: overrides[e.id], poseAuthored: true } : e
673
673
  );
674
674
  }
675
675
  function withWidths(endplates, widths, offsets = {}) {
@@ -1241,6 +1241,24 @@ var BUILT_IN_TRACK_PARTS = [...ATLAS_CODE55_N];
1241
1241
  function trackPart(id, library = BUILT_IN_TRACK_PARTS) {
1242
1242
  return library.find((p) => p.id === id) ?? null;
1243
1243
  }
1244
+ var TIE_HALF_LENGTH_INCHES = 0.319;
1245
+ function partExtent(part) {
1246
+ const pts = part?.pointsOffset;
1247
+ const overall = part?.overallLength;
1248
+ if (!pts || !overall) return null;
1249
+ if (pts.source !== "measured" || overall.source !== "measured") return null;
1250
+ const frog = part?.frogOffset;
1251
+ const aheadOfPoints = overall.inches - pts.inches;
1252
+ return {
1253
+ behindPoints: pts.inches,
1254
+ aheadOfPoints,
1255
+ pastFrog: frog && frog.source === "measured" ? overall.inches - frog.inches : aheadOfPoints
1256
+ };
1257
+ }
1258
+ function partExtentForSize(size, library = BUILT_IN_TRACK_PARTS) {
1259
+ const part = turnoutPartForSize(size, library);
1260
+ return part && part.frogNumber === size ? partExtent(part) : null;
1261
+ }
1244
1262
  function turnoutPartForSize(size, library = BUILT_IN_TRACK_PARTS) {
1245
1263
  const turnouts = library.filter((p) => p.kind === "turnout" && p.frogNumber != null);
1246
1264
  if (!turnouts.length) return null;
@@ -2033,10 +2051,26 @@ function trackMeetsEndplateIssues(path, pose, opts) {
2033
2051
  function poseNeedsManual(geometryType) {
2034
2052
  return geometryType === "wye" || geometryType === "other";
2035
2053
  }
2054
+ function isAxialPose(p) {
2055
+ const h = norm360(p.heading);
2056
+ return Math.abs(p.y) < 1e-6 && (Math.abs(h) < 1e-6 || Math.abs(h - 180) < 1e-6);
2057
+ }
2036
2058
  function poseOverridesFromDoc(doc) {
2037
2059
  const out = {};
2038
2060
  for (const e of doc.endplates ?? []) {
2039
- if (e.id && e.pose && typeof e.pose.x === "number" && typeof e.pose.y === "number" && typeof e.pose.heading === "number") {
2061
+ if (e.id && e.pose && typeof e.pose.x === "number" && typeof e.pose.y === "number" && typeof e.pose.heading === "number" && // Only an AUTHORED pose overrides derivation (#182) — but docs written
2062
+ // before the flag existed have to keep working, so authorship is inferred
2063
+ // for the two cases that can only BE authored:
2064
+ // · a placed branch endplate (`at`) — dropping it on the board is the
2065
+ // gesture, and it has no derivable position at all;
2066
+ // · an OFF-AXIS pose on A/B — a hand-placed plate is off-axis by
2067
+ // definition (that's why it needed hand placing, e.g. a wye's B).
2068
+ // What's left is an axial A/B pose, which is exactly the shape plain
2069
+ // derivation produces — residue. Honouring it silently pins the plate so
2070
+ // it stops following the module and goes stale (FMN-0068's B sat at 48 on
2071
+ // a 47.9″ board). Anything saved from now on carries the flag, so this
2072
+ // guesswork only ever applies to old docs.
2073
+ (e.poseAuthored === true || !!e.at || !isAxialPose(e.pose))) {
2040
2074
  out[e.id] = { x: e.pose.x, y: e.pose.y, heading: e.pose.heading };
2041
2075
  }
2042
2076
  }
@@ -2057,6 +2091,7 @@ exports.MAIN_TRACK_ID = MAIN_TRACK_ID;
2057
2091
  exports.N_CAR_LENGTH_INCHES = N_CAR_LENGTH_INCHES;
2058
2092
  exports.N_SCALE_RATIO = N_SCALE_RATIO;
2059
2093
  exports.RAIL_GAUGE_INCHES = RAIL_GAUGE_INCHES;
2094
+ exports.TIE_HALF_LENGTH_INCHES = TIE_HALF_LENGTH_INCHES;
2060
2095
  exports.TURNOUT_LEAD_INCHES_PER_FROG = TURNOUT_LEAD_INCHES_PER_FROG;
2061
2096
  exports.WHOLE_MODULE_SECTION_ID = WHOLE_MODULE_SECTION_ID;
2062
2097
  exports.asModuleSchematic = asModuleSchematic;
@@ -2093,6 +2128,8 @@ exports.moduleLengthFromSections = moduleLengthFromSections;
2093
2128
  exports.moduleSections = moduleSections;
2094
2129
  exports.nextId = nextId;
2095
2130
  exports.parseXtpLibrary = parseXtpLibrary;
2131
+ exports.partExtent = partExtent;
2132
+ exports.partExtentForSize = partExtentForSize;
2096
2133
  exports.partOutlineAtFrog = partOutlineAtFrog;
2097
2134
  exports.pathLengthInches = pathLengthInches;
2098
2135
  exports.poseNeedsManual = poseNeedsManual;