@willcgage/module-schematic 0.30.0 → 0.31.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.d.cts CHANGED
@@ -273,6 +273,18 @@ interface BenchworkPoint {
273
273
  bulge?: number;
274
274
  }
275
275
  /** One bench-work section of a module (#96 phase 2). */
276
+ interface SectionFootprint {
277
+ id: string;
278
+ name?: string;
279
+ outline: {
280
+ x: number;
281
+ y: number;
282
+ }[];
283
+ /** True when this shape is DERIVED from the section's span rather than
284
+ * authored — a derived outline follows the board when it's resized, an
285
+ * authored one stays exactly as drawn (#96 phase 2b). */
286
+ derived: boolean;
287
+ }
276
288
  interface SchematicSection {
277
289
  id: string;
278
290
  /** What the owner calls this board — "west transition", "double #3". */
@@ -314,14 +326,18 @@ declare function moduleSections(doc: {
314
326
  * bring in real clipping. */
315
327
  declare function sectionFootprints(doc: {
316
328
  sections?: SchematicSection[] | null;
317
- } | null | undefined): {
318
- id: string;
319
- name?: string;
320
- outline: {
321
- x: number;
322
- y: number;
323
- }[];
324
- }[];
329
+ } | null | undefined,
330
+ /** The module's spine and dimensions. Given these, a section with no
331
+ * authored polygon gets a band derived from its own span, so every section
332
+ * has a shape and a resized board reshapes with it (#96 phase 2b). Omit to
333
+ * get authored outlines only. */
334
+ derive?: {
335
+ centerline: BenchworkPoint[];
336
+ widthA: number;
337
+ widthB: number;
338
+ offsetA: number;
339
+ offsetB: number;
340
+ }): SectionFootprint[];
325
341
  /**
326
342
  * Expand a benchwork outline (whose edges may be arcs) into a dense closed
327
343
  * polyline for rendering — the SAME sampling both the Repository preview and
@@ -387,17 +403,10 @@ interface ModuleFootprint {
387
403
  /** Authored outline (arc-sampled closed ring) or null → render the band.
388
404
  * Null too when `sectionOutlines` is non-empty — the sections ARE the shape. */
389
405
  outline: BenchworkPoint[] | null;
390
- /** Per-section footprints, arc-sampled (#96 phase 2). Draw every one: together
406
+ /** Per-section footprints, arc-sampled (#96 phase 2b). Draw every one: together
391
407
  * they are the module's footprint. Empty = this module doesn't use sections,
392
408
  * so fall back to `outline ?? band` exactly as before. */
393
- sectionOutlines: {
394
- id: string;
395
- name?: string;
396
- outline: {
397
- x: number;
398
- y: number;
399
- }[];
400
- }[];
409
+ sectionOutlines: SectionFootprint[];
401
410
  }
402
411
  /** Module-local main track centre-line (A→B), sampling arcs for curves/corners.
403
412
  * An authored `mainPath` wins — the owner drew the real shape; otherwise the
@@ -434,6 +443,18 @@ declare function sectionedCenterline(doc: {
434
443
  } | null | undefined): BenchworkPoint[];
435
444
  /** Benchwork band: the centre-line offset ±half-width, tapering widthA→widthB. */
436
445
  declare function benchworkBand(center: BenchworkPoint[], widthA?: number, widthB?: number, offsetA?: number, offsetB?: number): BenchworkPoint[];
446
+ /** The sub-polyline of a centre-line between two arc-length positions, with
447
+ * the cut ends interpolated so a slice starts and finishes exactly on them. */
448
+ declare function sliceCenterline(center: BenchworkPoint[], fromPos: number, toPos: number): BenchworkPoint[];
449
+ /** One section's bench-work as a band over its own stretch of centre-line —
450
+ * the per-section equivalent of `benchworkBand` (#96 phase 2b). Width and
451
+ * plate offset are interpolated from the module's ends exactly as the whole
452
+ * band does, so a section's derived shape lines up with its neighbours.
453
+ *
454
+ * This is what makes an outline BELONG to the section: a section without an
455
+ * authored polygon gets one derived from its span, so resizing the board
456
+ * reshapes it instead of leaving a hand-drawn outline stranded. */
457
+ declare function sectionBand(center: BenchworkPoint[], fromPos: number, toPos: number, widthA?: number, widthB?: number, offsetA?: number, offsetB?: number): BenchworkPoint[];
437
458
  /** The two endplate faces (the band's flat ends): [A end at widthA, B end at widthB]. */
438
459
  declare function endplateFaceSegments(center: BenchworkPoint[], widthA?: number, widthB?: number, offsetA?: number, offsetB?: number): OutlineFace[];
439
460
  /**
@@ -920,4 +941,4 @@ declare function poseOverridesFromDoc(doc: ModuleSchematicDoc): Record<string, {
920
941
  heading: number;
921
942
  }>;
922
943
 
923
- export { type BenchworkPoint, type BranchConnector, type DrawCrossing, type DrawCrossover, type DrawIndustry, type DrawSignal, type DrawTrack, type DrawTurnout, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorIndustry, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplatePose, type EndplateWidthIssue, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_TRACK_SPACING_INCHES, type GeometryType, type IndustryLabelMode, type IndustrySpot, MAIN2_TRACK_ID, MAIN_TRACK_ID, type ModuleFeatures, type ModuleFootprint, type ModuleFootprintInput, type ModuleGeometryInput, type ModuleSchematicDoc, type ModuleTrackRow, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, type OutlineFace, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicIndustry, type SchematicSection, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SignalFacing, type SignalSide, type TrackConfig, type TrackRole, type TurnoutKind, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, checkEndplateWidth, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateTrackOffsetFor, endplateTrackOffsetInches, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, poseNeedsManual, poseOverridesFromDoc, sampleBenchworkOutline, samplePath, scaleFeetToInches, sectionBreaksFromSections, sectionFootprints, sectionSpans, sectionedCenterline, stateToDoc, trackPath };
944
+ export { type BenchworkPoint, type BranchConnector, type DrawCrossing, type DrawCrossover, type DrawIndustry, type DrawSignal, type DrawTrack, type DrawTurnout, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorIndustry, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplatePose, type EndplateWidthIssue, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_TRACK_SPACING_INCHES, type GeometryType, type IndustryLabelMode, type IndustrySpot, MAIN2_TRACK_ID, MAIN_TRACK_ID, type ModuleFeatures, type ModuleFootprint, type ModuleFootprintInput, type ModuleGeometryInput, type ModuleSchematicDoc, type ModuleTrackRow, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, type OutlineFace, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicIndustry, type SchematicSection, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SectionFootprint, type SignalFacing, type SignalSide, type TrackConfig, type TrackRole, type TurnoutKind, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, checkEndplateWidth, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateTrackOffsetFor, endplateTrackOffsetInches, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, poseNeedsManual, poseOverridesFromDoc, sampleBenchworkOutline, samplePath, scaleFeetToInches, sectionBand, sectionBreaksFromSections, sectionFootprints, sectionSpans, sectionedCenterline, sliceCenterline, stateToDoc, trackPath };
package/dist/index.d.ts CHANGED
@@ -273,6 +273,18 @@ interface BenchworkPoint {
273
273
  bulge?: number;
274
274
  }
275
275
  /** One bench-work section of a module (#96 phase 2). */
276
+ interface SectionFootprint {
277
+ id: string;
278
+ name?: string;
279
+ outline: {
280
+ x: number;
281
+ y: number;
282
+ }[];
283
+ /** True when this shape is DERIVED from the section's span rather than
284
+ * authored — a derived outline follows the board when it's resized, an
285
+ * authored one stays exactly as drawn (#96 phase 2b). */
286
+ derived: boolean;
287
+ }
276
288
  interface SchematicSection {
277
289
  id: string;
278
290
  /** What the owner calls this board — "west transition", "double #3". */
@@ -314,14 +326,18 @@ declare function moduleSections(doc: {
314
326
  * bring in real clipping. */
315
327
  declare function sectionFootprints(doc: {
316
328
  sections?: SchematicSection[] | null;
317
- } | null | undefined): {
318
- id: string;
319
- name?: string;
320
- outline: {
321
- x: number;
322
- y: number;
323
- }[];
324
- }[];
329
+ } | null | undefined,
330
+ /** The module's spine and dimensions. Given these, a section with no
331
+ * authored polygon gets a band derived from its own span, so every section
332
+ * has a shape and a resized board reshapes with it (#96 phase 2b). Omit to
333
+ * get authored outlines only. */
334
+ derive?: {
335
+ centerline: BenchworkPoint[];
336
+ widthA: number;
337
+ widthB: number;
338
+ offsetA: number;
339
+ offsetB: number;
340
+ }): SectionFootprint[];
325
341
  /**
326
342
  * Expand a benchwork outline (whose edges may be arcs) into a dense closed
327
343
  * polyline for rendering — the SAME sampling both the Repository preview and
@@ -387,17 +403,10 @@ interface ModuleFootprint {
387
403
  /** Authored outline (arc-sampled closed ring) or null → render the band.
388
404
  * Null too when `sectionOutlines` is non-empty — the sections ARE the shape. */
389
405
  outline: BenchworkPoint[] | null;
390
- /** Per-section footprints, arc-sampled (#96 phase 2). Draw every one: together
406
+ /** Per-section footprints, arc-sampled (#96 phase 2b). Draw every one: together
391
407
  * they are the module's footprint. Empty = this module doesn't use sections,
392
408
  * so fall back to `outline ?? band` exactly as before. */
393
- sectionOutlines: {
394
- id: string;
395
- name?: string;
396
- outline: {
397
- x: number;
398
- y: number;
399
- }[];
400
- }[];
409
+ sectionOutlines: SectionFootprint[];
401
410
  }
402
411
  /** Module-local main track centre-line (A→B), sampling arcs for curves/corners.
403
412
  * An authored `mainPath` wins — the owner drew the real shape; otherwise the
@@ -434,6 +443,18 @@ declare function sectionedCenterline(doc: {
434
443
  } | null | undefined): BenchworkPoint[];
435
444
  /** Benchwork band: the centre-line offset ±half-width, tapering widthA→widthB. */
436
445
  declare function benchworkBand(center: BenchworkPoint[], widthA?: number, widthB?: number, offsetA?: number, offsetB?: number): BenchworkPoint[];
446
+ /** The sub-polyline of a centre-line between two arc-length positions, with
447
+ * the cut ends interpolated so a slice starts and finishes exactly on them. */
448
+ declare function sliceCenterline(center: BenchworkPoint[], fromPos: number, toPos: number): BenchworkPoint[];
449
+ /** One section's bench-work as a band over its own stretch of centre-line —
450
+ * the per-section equivalent of `benchworkBand` (#96 phase 2b). Width and
451
+ * plate offset are interpolated from the module's ends exactly as the whole
452
+ * band does, so a section's derived shape lines up with its neighbours.
453
+ *
454
+ * This is what makes an outline BELONG to the section: a section without an
455
+ * authored polygon gets one derived from its span, so resizing the board
456
+ * reshapes it instead of leaving a hand-drawn outline stranded. */
457
+ declare function sectionBand(center: BenchworkPoint[], fromPos: number, toPos: number, widthA?: number, widthB?: number, offsetA?: number, offsetB?: number): BenchworkPoint[];
437
458
  /** The two endplate faces (the band's flat ends): [A end at widthA, B end at widthB]. */
438
459
  declare function endplateFaceSegments(center: BenchworkPoint[], widthA?: number, widthB?: number, offsetA?: number, offsetB?: number): OutlineFace[];
439
460
  /**
@@ -920,4 +941,4 @@ declare function poseOverridesFromDoc(doc: ModuleSchematicDoc): Record<string, {
920
941
  heading: number;
921
942
  }>;
922
943
 
923
- export { type BenchworkPoint, type BranchConnector, type DrawCrossing, type DrawCrossover, type DrawIndustry, type DrawSignal, type DrawTrack, type DrawTurnout, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorIndustry, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplatePose, type EndplateWidthIssue, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_TRACK_SPACING_INCHES, type GeometryType, type IndustryLabelMode, type IndustrySpot, MAIN2_TRACK_ID, MAIN_TRACK_ID, type ModuleFeatures, type ModuleFootprint, type ModuleFootprintInput, type ModuleGeometryInput, type ModuleSchematicDoc, type ModuleTrackRow, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, type OutlineFace, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicIndustry, type SchematicSection, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SignalFacing, type SignalSide, type TrackConfig, type TrackRole, type TurnoutKind, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, checkEndplateWidth, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateTrackOffsetFor, endplateTrackOffsetInches, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, poseNeedsManual, poseOverridesFromDoc, sampleBenchworkOutline, samplePath, scaleFeetToInches, sectionBreaksFromSections, sectionFootprints, sectionSpans, sectionedCenterline, stateToDoc, trackPath };
944
+ export { type BenchworkPoint, type BranchConnector, type DrawCrossing, type DrawCrossover, type DrawIndustry, type DrawSignal, type DrawTrack, type DrawTurnout, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorIndustry, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplatePose, type EndplateWidthIssue, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_TRACK_SPACING_INCHES, type GeometryType, type IndustryLabelMode, type IndustrySpot, MAIN2_TRACK_ID, MAIN_TRACK_ID, type ModuleFeatures, type ModuleFootprint, type ModuleFootprintInput, type ModuleGeometryInput, type ModuleSchematicDoc, type ModuleTrackRow, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, type OutlineFace, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicIndustry, type SchematicSection, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SectionFootprint, type SignalFacing, type SignalSide, type TrackConfig, type TrackRole, type TurnoutKind, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, checkEndplateWidth, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateTrackOffsetFor, endplateTrackOffsetInches, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, poseNeedsManual, poseOverridesFromDoc, sampleBenchworkOutline, samplePath, scaleFeetToInches, sectionBand, sectionBreaksFromSections, sectionFootprints, sectionSpans, sectionedCenterline, sliceCenterline, stateToDoc, trackPath };
package/dist/index.js CHANGED
@@ -33,12 +33,26 @@ function moduleSections(doc) {
33
33
  };
34
34
  });
35
35
  }
36
- function sectionFootprints(doc) {
37
- return moduleSections(doc).filter((sec) => sec.outline).map((sec) => ({
38
- id: sec.id,
39
- ...sec.name ? { name: sec.name } : {},
40
- outline: sampleBenchworkOutline(sec.outline)
41
- }));
36
+ function sectionFootprints(doc, derive) {
37
+ const spans = derive ? sectionSpans(doc) : [];
38
+ const spanOf = new Map(spans.map((sp) => [sp.id, sp]));
39
+ return moduleSections(doc).map((sec) => {
40
+ const name = sec.name ? { name: sec.name } : {};
41
+ if (sec.outline)
42
+ return { id: sec.id, ...name, outline: sampleBenchworkOutline(sec.outline), derived: false };
43
+ const sp = spanOf.get(sec.id);
44
+ if (!sp || !derive) return null;
45
+ const band = sectionBand(
46
+ derive.centerline,
47
+ sp.fromPos,
48
+ sp.toPos,
49
+ derive.widthA,
50
+ derive.widthB,
51
+ derive.offsetA,
52
+ derive.offsetB
53
+ );
54
+ return band.length >= 3 ? { id: sec.id, ...name, outline: band, derived: true } : null;
55
+ }).filter((x) => x !== null);
42
56
  }
43
57
  function sampleBenchworkOutline(pts, segsPerArc = 20) {
44
58
  const n = pts.length;
@@ -254,6 +268,63 @@ function benchworkBand(center, widthA = FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES
254
268
  }));
255
269
  return [...left, ...right.reverse()];
256
270
  }
271
+ function sliceCenterline(center, fromPos, toPos) {
272
+ if (center.length < 2) return [];
273
+ const cum = [0];
274
+ for (let i = 1; i < center.length; i++)
275
+ cum.push(cum[i - 1] + Math.hypot(center[i].x - center[i - 1].x, center[i].y - center[i - 1].y));
276
+ const total = cum[cum.length - 1];
277
+ const a = Math.max(0, Math.min(total, Math.min(fromPos, toPos)));
278
+ const b = Math.max(0, Math.min(total, Math.max(fromPos, toPos)));
279
+ if (b - a <= 0) return [];
280
+ const at = (d) => {
281
+ for (let i = 1; i < center.length; i++) {
282
+ if (d <= cum[i] || i === center.length - 1) {
283
+ const seg = cum[i] - cum[i - 1] || 1;
284
+ const t = Math.max(0, Math.min(1, (d - cum[i - 1]) / seg));
285
+ return {
286
+ x: center[i - 1].x + (center[i].x - center[i - 1].x) * t,
287
+ y: center[i - 1].y + (center[i].y - center[i - 1].y) * t
288
+ };
289
+ }
290
+ }
291
+ return center[center.length - 1];
292
+ };
293
+ const out = [at(a)];
294
+ for (let i = 0; i < center.length; i++) {
295
+ if (cum[i] > a && cum[i] < b) out.push({ x: center[i].x, y: center[i].y });
296
+ }
297
+ out.push(at(b));
298
+ return out;
299
+ }
300
+ function sectionBand(center, fromPos, toPos, widthA = FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, widthB = FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, offsetA = 0, offsetB = 0) {
301
+ const slice = sliceCenterline(center, fromPos, toPos);
302
+ if (slice.length < 2) return [];
303
+ let total = 0;
304
+ for (let i = 1; i < center.length; i++)
305
+ total += Math.hypot(center[i].x - center[i - 1].x, center[i].y - center[i - 1].y);
306
+ total = total || 1;
307
+ const lo = Math.min(fromPos, toPos);
308
+ let acc = 0;
309
+ const fr = [0];
310
+ for (let i = 1; i < slice.length; i++) {
311
+ acc += Math.hypot(slice[i].x - slice[i - 1].x, slice[i].y - slice[i - 1].y);
312
+ fr.push(acc);
313
+ }
314
+ const f = fr.map((d) => Math.max(0, Math.min(1, (lo + d) / total)));
315
+ const n = centerlineNormals(slice);
316
+ const half = (i) => (widthA * (1 - f[i]) + widthB * f[i]) / 2;
317
+ const off = (i) => offsetA * (1 - f[i]) + offsetB * f[i];
318
+ const left = slice.map((p, i) => ({
319
+ x: p.x + n[i].x * (off(i) + half(i)),
320
+ y: p.y + n[i].y * (off(i) + half(i))
321
+ }));
322
+ const right = slice.map((p, i) => ({
323
+ x: p.x + n[i].x * (off(i) - half(i)),
324
+ y: p.y + n[i].y * (off(i) - half(i))
325
+ }));
326
+ return [...left, ...right.reverse()];
327
+ }
257
328
  function endplateFaceSegments(center, widthA = FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, widthB = FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, offsetA = 0, offsetB = 0) {
258
329
  if (center.length < 2) return [];
259
330
  const n = centerlineNormals(center);
@@ -271,7 +342,13 @@ function moduleFootprint(input) {
271
342
  const authored = benchworkOutline(input);
272
343
  const offA = input.endplateTrackOffsets?.["A"] ?? 0;
273
344
  const offB = input.endplateTrackOffsets?.["B"] ?? 0;
274
- const sectionOutlines = sectionFootprints(input);
345
+ const sectionOutlines = sectionFootprints(input, {
346
+ centerline,
347
+ widthA,
348
+ widthB,
349
+ offsetA: offA,
350
+ offsetB: offB
351
+ });
275
352
  return {
276
353
  centerline,
277
354
  band: benchworkBand(centerline, widthA, widthB, offA, offB),
@@ -1192,6 +1269,6 @@ function poseOverridesFromDoc(doc) {
1192
1269
  return out;
1193
1270
  }
1194
1271
 
1195
- export { FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_TRACK_SPACING_INCHES, MAIN2_TRACK_ID, MAIN_TRACK_ID, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, checkEndplateWidth, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateTrackOffsetFor, endplateTrackOffsetInches, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, poseNeedsManual, poseOverridesFromDoc, sampleBenchworkOutline, samplePath, scaleFeetToInches, sectionBreaksFromSections, sectionFootprints, sectionSpans, sectionedCenterline, stateToDoc, trackPath };
1272
+ export { FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_TRACK_SPACING_INCHES, MAIN2_TRACK_ID, MAIN_TRACK_ID, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, checkEndplateWidth, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateTrackOffsetFor, endplateTrackOffsetInches, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, poseNeedsManual, poseOverridesFromDoc, sampleBenchworkOutline, samplePath, scaleFeetToInches, sectionBand, sectionBreaksFromSections, sectionFootprints, sectionSpans, sectionedCenterline, sliceCenterline, stateToDoc, trackPath };
1196
1273
  //# sourceMappingURL=index.js.map
1197
1274
  //# sourceMappingURL=index.js.map