@willcgage/module-schematic 0.18.0 → 0.19.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 +55 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +36 -2
- package/dist/index.d.ts +36 -2
- package/dist/index.js +54 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -78,6 +78,11 @@ interface SchematicTrack {
|
|
|
78
78
|
* endplate A (past the throat = in the loop), lane is the ladder/arc index —
|
|
79
79
|
* one record drives both the unrolled fan and a geometric render. */
|
|
80
80
|
inLoop?: boolean;
|
|
81
|
+
/** Authored 2-D path for this track (module-local inches, open path with
|
|
82
|
+
* arcs) — the PHYSICAL shape a bent/rotated spur draws. Absent = derive from
|
|
83
|
+
* the main centre-line + lane, as before. Physical view only; the operations
|
|
84
|
+
* view stays positional (#2d-track). */
|
|
85
|
+
path?: BenchworkPoint[] | null;
|
|
81
86
|
}
|
|
82
87
|
interface SchematicTurnout {
|
|
83
88
|
id: string;
|
|
@@ -195,6 +200,10 @@ interface ModuleSchematicDoc {
|
|
|
195
200
|
outline?: BenchworkPoint[];
|
|
196
201
|
/** @deprecated pre-grouping flat signals; read for back-compat. */
|
|
197
202
|
signals?: SchematicSignal[];
|
|
203
|
+
/** Authored mainline centre-line (module-local inches, open path with arcs).
|
|
204
|
+
* Present = the owner drew the real shape; absent = derive from geometry.
|
|
205
|
+
* Physical view only — the operations view stays derived (#2d-track). */
|
|
206
|
+
mainPath?: BenchworkPoint[] | null;
|
|
198
207
|
}
|
|
199
208
|
/** A benchwork-outline vertex, module-local inches. The edge from this vertex
|
|
200
209
|
* to the NEXT one is a straight line, unless `bulge` is set — then it's a
|
|
@@ -222,6 +231,19 @@ declare function sampleBenchworkOutline(pts: BenchworkPoint[], segsPerArc?: numb
|
|
|
222
231
|
x: number;
|
|
223
232
|
y: number;
|
|
224
233
|
}[];
|
|
234
|
+
/**
|
|
235
|
+
* Expand an OPEN track path (whose edges may be arcs) into a dense polyline —
|
|
236
|
+
* the open-ended sibling of sampleBenchworkOutline (which closes the ring).
|
|
237
|
+
* Used for authored track centre-lines (a drawn mainline or spur). The final
|
|
238
|
+
* vertex is always emitted so the path reaches its end.
|
|
239
|
+
*/
|
|
240
|
+
declare function samplePath(pts: BenchworkPoint[], segsPerArc?: number): {
|
|
241
|
+
x: number;
|
|
242
|
+
y: number;
|
|
243
|
+
}[];
|
|
244
|
+
/** Normalise an authored track path from a doc, or null if it isn't a real path
|
|
245
|
+
* (needs ≥ 2 valid points). Keeps per-vertex bulge. */
|
|
246
|
+
declare function trackPath(path: BenchworkPoint[] | null | undefined): BenchworkPoint[] | null;
|
|
225
247
|
interface ModuleFootprintInput {
|
|
226
248
|
/** Mainline length (falls back to footprint length), inches. */
|
|
227
249
|
lengthInches: number;
|
|
@@ -232,6 +254,10 @@ interface ModuleFootprintInput {
|
|
|
232
254
|
endplateWidths?: Record<string, number>;
|
|
233
255
|
/** Authored benchwork outline (module-local inches), or absent for the band. */
|
|
234
256
|
outline?: BenchworkPoint[] | null;
|
|
257
|
+
/** Authored mainline centre-line (module-local inches, open path with arcs).
|
|
258
|
+
* When present it wins over the geometry-derived centre-line — the owner drew
|
|
259
|
+
* the real shape (#2d-track, physical view only). */
|
|
260
|
+
mainPath?: BenchworkPoint[] | null;
|
|
235
261
|
}
|
|
236
262
|
interface OutlineFace {
|
|
237
263
|
/** The endplate face's two corners + midpoint (the track point). */
|
|
@@ -249,7 +275,9 @@ interface ModuleFootprint {
|
|
|
249
275
|
/** Authored outline (arc-sampled closed ring) or null → render the band. */
|
|
250
276
|
outline: BenchworkPoint[] | null;
|
|
251
277
|
}
|
|
252
|
-
/** Module-local main track centre-line (A→B), sampling arcs for curves/corners.
|
|
278
|
+
/** Module-local main track centre-line (A→B), sampling arcs for curves/corners.
|
|
279
|
+
* An authored `mainPath` wins — the owner drew the real shape; otherwise the
|
|
280
|
+
* centre-line is derived from the geometry fields (length + type/degrees/offset). */
|
|
253
281
|
declare function moduleCenterline(input: ModuleFootprintInput): BenchworkPoint[];
|
|
254
282
|
/** Benchwork band: the centre-line offset ±half-width, tapering widthA→widthB. */
|
|
255
283
|
declare function benchworkBand(center: BenchworkPoint[], widthA?: number, widthB?: number): BenchworkPoint[];
|
|
@@ -295,6 +323,9 @@ interface EditorTrack {
|
|
|
295
323
|
trackName: string;
|
|
296
324
|
/** Inside the balloon of a loop module (#165). */
|
|
297
325
|
inLoop?: boolean;
|
|
326
|
+
/** Authored 2-D path (module-local inches) — a bent/rotated spur's real
|
|
327
|
+
* shape. Absent = derive from the main + lane (#2d-track). */
|
|
328
|
+
path?: BenchworkPoint[];
|
|
298
329
|
}
|
|
299
330
|
/** A module_tracks row as loaded for the editor. */
|
|
300
331
|
interface ModuleTrackRow {
|
|
@@ -393,6 +424,9 @@ interface EditorState {
|
|
|
393
424
|
controlPoints: EditorControlPoint[];
|
|
394
425
|
/** Rail-served industries — car-spot spans on a track (#industries). */
|
|
395
426
|
industries: EditorIndustry[];
|
|
427
|
+
/** Authored mainline centre-line (module-local inches) — empty = derive from
|
|
428
|
+
* geometry. The owner-drawn real shape (#2d-track, physical view only). */
|
|
429
|
+
mainPath: BenchworkPoint[];
|
|
396
430
|
}
|
|
397
431
|
/** Build the empty editor state for a module of the given length. */
|
|
398
432
|
declare function emptyEditorState(lengthInches: number): EditorState;
|
|
@@ -671,4 +705,4 @@ declare function poseOverridesFromDoc(doc: ModuleSchematicDoc): Record<string, {
|
|
|
671
705
|
heading: number;
|
|
672
706
|
}>;
|
|
673
707
|
|
|
674
|
-
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, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, type GeometryType, type IndustryLabelMode, 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 SchematicSignal, type SchematicTrack, type SchematicTurnout, type SignalFacing, type SignalSide, type TrackConfig, type TrackRole, type TurnoutKind, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleCenterline, moduleFeatures, moduleFootprint, nextId, poseNeedsManual, poseOverridesFromDoc, sampleBenchworkOutline, scaleFeetToInches, stateToDoc };
|
|
708
|
+
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, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, type GeometryType, type IndustryLabelMode, 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 SchematicSignal, type SchematicTrack, type SchematicTurnout, type SignalFacing, type SignalSide, type TrackConfig, type TrackRole, type TurnoutKind, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleCenterline, moduleFeatures, moduleFootprint, nextId, poseNeedsManual, poseOverridesFromDoc, sampleBenchworkOutline, samplePath, scaleFeetToInches, stateToDoc, trackPath };
|
package/dist/index.d.ts
CHANGED
|
@@ -78,6 +78,11 @@ interface SchematicTrack {
|
|
|
78
78
|
* endplate A (past the throat = in the loop), lane is the ladder/arc index —
|
|
79
79
|
* one record drives both the unrolled fan and a geometric render. */
|
|
80
80
|
inLoop?: boolean;
|
|
81
|
+
/** Authored 2-D path for this track (module-local inches, open path with
|
|
82
|
+
* arcs) — the PHYSICAL shape a bent/rotated spur draws. Absent = derive from
|
|
83
|
+
* the main centre-line + lane, as before. Physical view only; the operations
|
|
84
|
+
* view stays positional (#2d-track). */
|
|
85
|
+
path?: BenchworkPoint[] | null;
|
|
81
86
|
}
|
|
82
87
|
interface SchematicTurnout {
|
|
83
88
|
id: string;
|
|
@@ -195,6 +200,10 @@ interface ModuleSchematicDoc {
|
|
|
195
200
|
outline?: BenchworkPoint[];
|
|
196
201
|
/** @deprecated pre-grouping flat signals; read for back-compat. */
|
|
197
202
|
signals?: SchematicSignal[];
|
|
203
|
+
/** Authored mainline centre-line (module-local inches, open path with arcs).
|
|
204
|
+
* Present = the owner drew the real shape; absent = derive from geometry.
|
|
205
|
+
* Physical view only — the operations view stays derived (#2d-track). */
|
|
206
|
+
mainPath?: BenchworkPoint[] | null;
|
|
198
207
|
}
|
|
199
208
|
/** A benchwork-outline vertex, module-local inches. The edge from this vertex
|
|
200
209
|
* to the NEXT one is a straight line, unless `bulge` is set — then it's a
|
|
@@ -222,6 +231,19 @@ declare function sampleBenchworkOutline(pts: BenchworkPoint[], segsPerArc?: numb
|
|
|
222
231
|
x: number;
|
|
223
232
|
y: number;
|
|
224
233
|
}[];
|
|
234
|
+
/**
|
|
235
|
+
* Expand an OPEN track path (whose edges may be arcs) into a dense polyline —
|
|
236
|
+
* the open-ended sibling of sampleBenchworkOutline (which closes the ring).
|
|
237
|
+
* Used for authored track centre-lines (a drawn mainline or spur). The final
|
|
238
|
+
* vertex is always emitted so the path reaches its end.
|
|
239
|
+
*/
|
|
240
|
+
declare function samplePath(pts: BenchworkPoint[], segsPerArc?: number): {
|
|
241
|
+
x: number;
|
|
242
|
+
y: number;
|
|
243
|
+
}[];
|
|
244
|
+
/** Normalise an authored track path from a doc, or null if it isn't a real path
|
|
245
|
+
* (needs ≥ 2 valid points). Keeps per-vertex bulge. */
|
|
246
|
+
declare function trackPath(path: BenchworkPoint[] | null | undefined): BenchworkPoint[] | null;
|
|
225
247
|
interface ModuleFootprintInput {
|
|
226
248
|
/** Mainline length (falls back to footprint length), inches. */
|
|
227
249
|
lengthInches: number;
|
|
@@ -232,6 +254,10 @@ interface ModuleFootprintInput {
|
|
|
232
254
|
endplateWidths?: Record<string, number>;
|
|
233
255
|
/** Authored benchwork outline (module-local inches), or absent for the band. */
|
|
234
256
|
outline?: BenchworkPoint[] | null;
|
|
257
|
+
/** Authored mainline centre-line (module-local inches, open path with arcs).
|
|
258
|
+
* When present it wins over the geometry-derived centre-line — the owner drew
|
|
259
|
+
* the real shape (#2d-track, physical view only). */
|
|
260
|
+
mainPath?: BenchworkPoint[] | null;
|
|
235
261
|
}
|
|
236
262
|
interface OutlineFace {
|
|
237
263
|
/** The endplate face's two corners + midpoint (the track point). */
|
|
@@ -249,7 +275,9 @@ interface ModuleFootprint {
|
|
|
249
275
|
/** Authored outline (arc-sampled closed ring) or null → render the band. */
|
|
250
276
|
outline: BenchworkPoint[] | null;
|
|
251
277
|
}
|
|
252
|
-
/** Module-local main track centre-line (A→B), sampling arcs for curves/corners.
|
|
278
|
+
/** Module-local main track centre-line (A→B), sampling arcs for curves/corners.
|
|
279
|
+
* An authored `mainPath` wins — the owner drew the real shape; otherwise the
|
|
280
|
+
* centre-line is derived from the geometry fields (length + type/degrees/offset). */
|
|
253
281
|
declare function moduleCenterline(input: ModuleFootprintInput): BenchworkPoint[];
|
|
254
282
|
/** Benchwork band: the centre-line offset ±half-width, tapering widthA→widthB. */
|
|
255
283
|
declare function benchworkBand(center: BenchworkPoint[], widthA?: number, widthB?: number): BenchworkPoint[];
|
|
@@ -295,6 +323,9 @@ interface EditorTrack {
|
|
|
295
323
|
trackName: string;
|
|
296
324
|
/** Inside the balloon of a loop module (#165). */
|
|
297
325
|
inLoop?: boolean;
|
|
326
|
+
/** Authored 2-D path (module-local inches) — a bent/rotated spur's real
|
|
327
|
+
* shape. Absent = derive from the main + lane (#2d-track). */
|
|
328
|
+
path?: BenchworkPoint[];
|
|
298
329
|
}
|
|
299
330
|
/** A module_tracks row as loaded for the editor. */
|
|
300
331
|
interface ModuleTrackRow {
|
|
@@ -393,6 +424,9 @@ interface EditorState {
|
|
|
393
424
|
controlPoints: EditorControlPoint[];
|
|
394
425
|
/** Rail-served industries — car-spot spans on a track (#industries). */
|
|
395
426
|
industries: EditorIndustry[];
|
|
427
|
+
/** Authored mainline centre-line (module-local inches) — empty = derive from
|
|
428
|
+
* geometry. The owner-drawn real shape (#2d-track, physical view only). */
|
|
429
|
+
mainPath: BenchworkPoint[];
|
|
396
430
|
}
|
|
397
431
|
/** Build the empty editor state for a module of the given length. */
|
|
398
432
|
declare function emptyEditorState(lengthInches: number): EditorState;
|
|
@@ -671,4 +705,4 @@ declare function poseOverridesFromDoc(doc: ModuleSchematicDoc): Record<string, {
|
|
|
671
705
|
heading: number;
|
|
672
706
|
}>;
|
|
673
707
|
|
|
674
|
-
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, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, type GeometryType, type IndustryLabelMode, 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 SchematicSignal, type SchematicTrack, type SchematicTurnout, type SignalFacing, type SignalSide, type TrackConfig, type TrackRole, type TurnoutKind, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleCenterline, moduleFeatures, moduleFootprint, nextId, poseNeedsManual, poseOverridesFromDoc, sampleBenchworkOutline, scaleFeetToInches, stateToDoc };
|
|
708
|
+
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, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, type GeometryType, type IndustryLabelMode, 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 SchematicSignal, type SchematicTrack, type SchematicTurnout, type SignalFacing, type SignalSide, type TrackConfig, type TrackRole, type TurnoutKind, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleCenterline, moduleFeatures, moduleFootprint, nextId, poseNeedsManual, poseOverridesFromDoc, sampleBenchworkOutline, samplePath, scaleFeetToInches, stateToDoc, trackPath };
|
package/dist/index.js
CHANGED
|
@@ -43,6 +43,45 @@ function sampleBenchworkOutline(pts, segsPerArc = 20) {
|
|
|
43
43
|
}
|
|
44
44
|
return out;
|
|
45
45
|
}
|
|
46
|
+
function samplePath(pts, segsPerArc = 20) {
|
|
47
|
+
const n = pts.length;
|
|
48
|
+
if (n < 2) return pts.map((p) => ({ x: p.x, y: p.y }));
|
|
49
|
+
const out = [];
|
|
50
|
+
for (let i = 0; i < n - 1; i++) {
|
|
51
|
+
const p0 = pts[i];
|
|
52
|
+
const p1 = pts[i + 1];
|
|
53
|
+
out.push({ x: p0.x, y: p0.y });
|
|
54
|
+
const bulge = p0.bulge ?? 0;
|
|
55
|
+
if (!bulge) continue;
|
|
56
|
+
const dx = p1.x - p0.x;
|
|
57
|
+
const dy = p1.y - p0.y;
|
|
58
|
+
const c = Math.hypot(dx, dy);
|
|
59
|
+
if (c < 1e-6) continue;
|
|
60
|
+
const nx = -dy / c;
|
|
61
|
+
const ny = dx / c;
|
|
62
|
+
const mid = { x: (p0.x + p1.x) / 2 + nx * bulge, y: (p0.y + p1.y) / 2 + ny * bulge };
|
|
63
|
+
const circ = circleThrough(p0, mid, p1);
|
|
64
|
+
if (!circ) continue;
|
|
65
|
+
const a0 = Math.atan2(p0.y - circ.cy, p0.x - circ.cx);
|
|
66
|
+
const am = Math.atan2(mid.y - circ.cy, mid.x - circ.cx);
|
|
67
|
+
const a1 = Math.atan2(p1.y - circ.cy, p1.x - circ.cx);
|
|
68
|
+
const sweep = arcSweep(a0, a1, am);
|
|
69
|
+
for (let s = 1; s < segsPerArc; s++) {
|
|
70
|
+
const a = a0 + sweep * s / segsPerArc;
|
|
71
|
+
out.push({ x: circ.cx + circ.r * Math.cos(a), y: circ.cy + circ.r * Math.sin(a) });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
out.push({ x: pts[n - 1].x, y: pts[n - 1].y });
|
|
75
|
+
return out;
|
|
76
|
+
}
|
|
77
|
+
function trackPath(path) {
|
|
78
|
+
const pts = (path ?? []).filter((p) => p && Number.isFinite(p.x) && Number.isFinite(p.y)).map((p) => ({
|
|
79
|
+
x: p.x,
|
|
80
|
+
y: p.y,
|
|
81
|
+
...Number.isFinite(p.bulge) && p.bulge ? { bulge: p.bulge } : {}
|
|
82
|
+
}));
|
|
83
|
+
return pts.length >= 2 ? pts : null;
|
|
84
|
+
}
|
|
46
85
|
function circleThrough(a, b, c) {
|
|
47
86
|
const d = 2 * (a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y));
|
|
48
87
|
if (Math.abs(d) < 1e-9) return null;
|
|
@@ -65,6 +104,8 @@ function arcSweep(a0, a1, am) {
|
|
|
65
104
|
}
|
|
66
105
|
var DEG_FP = Math.PI / 180;
|
|
67
106
|
function moduleCenterline(input) {
|
|
107
|
+
const drawn = trackPath(input.mainPath);
|
|
108
|
+
if (drawn) return samplePath(drawn);
|
|
68
109
|
const L = input.lengthInches > 0 ? input.lengthInches : 24;
|
|
69
110
|
const gt = input.geometryType;
|
|
70
111
|
if (gt === "dead_end") return [{ x: 0, y: 0 }];
|
|
@@ -174,7 +215,8 @@ function emptyEditorState(lengthInches) {
|
|
|
174
215
|
endplateWidths: {},
|
|
175
216
|
outline: [],
|
|
176
217
|
controlPoints: [],
|
|
177
|
-
industries: []
|
|
218
|
+
industries: [],
|
|
219
|
+
mainPath: []
|
|
178
220
|
};
|
|
179
221
|
}
|
|
180
222
|
function isTransitionTurnout(t) {
|
|
@@ -311,7 +353,8 @@ function stateToDoc(state, recordNumber) {
|
|
|
311
353
|
moduleTrackId: t.moduleTrackId,
|
|
312
354
|
trackName: t.trackName || void 0,
|
|
313
355
|
capacityFeet: Math.round(inchesToScaleFeet(Math.abs(t.toPos - t.fromPos))),
|
|
314
|
-
...state.loop && t.inLoop ? { inLoop: true } : {}
|
|
356
|
+
...state.loop && t.inLoop ? { inLoop: true } : {},
|
|
357
|
+
...t.path && t.path.length >= 2 ? { path: t.path } : {}
|
|
315
358
|
}))
|
|
316
359
|
],
|
|
317
360
|
turnouts: state.turnouts.map((t) => ({
|
|
@@ -361,7 +404,9 @@ function stateToDoc(state, recordNumber) {
|
|
|
361
404
|
} : {},
|
|
362
405
|
// Benchwork footprint outline (module-local inches); only when it's a real
|
|
363
406
|
// ring (≥ 3 vertices).
|
|
364
|
-
...state.outline.length >= 3 ? { outline: state.outline } : {}
|
|
407
|
+
...state.outline.length >= 3 ? { outline: state.outline } : {},
|
|
408
|
+
// Authored mainline path (module-local inches); only when it's a real path.
|
|
409
|
+
...state.mainPath.length >= 2 ? { mainPath: state.mainPath } : {}
|
|
365
410
|
};
|
|
366
411
|
}
|
|
367
412
|
function docToState(doc, fallbackLength, moduleTracks = []) {
|
|
@@ -391,7 +436,9 @@ function docToState(doc, fallbackLength, moduleTracks = []) {
|
|
|
391
436
|
toPos: t.toPos != null ? sc(t.toPos) : len,
|
|
392
437
|
moduleTrackId,
|
|
393
438
|
trackName: t.trackName ?? nameOf(moduleTrackId),
|
|
394
|
-
...t.inLoop ? { inLoop: true } : {}
|
|
439
|
+
...t.inLoop ? { inLoop: true } : {},
|
|
440
|
+
// Authored path kept as-drawn (a physical shape, not rescaled with length).
|
|
441
|
+
...trackPath(t.path) ? { path: trackPath(t.path) } : {}
|
|
395
442
|
});
|
|
396
443
|
}
|
|
397
444
|
}
|
|
@@ -440,6 +487,7 @@ function docToState(doc, fallbackLength, moduleTracks = []) {
|
|
|
440
487
|
y: p.y,
|
|
441
488
|
...Number.isFinite(p.bulge) && p.bulge ? { bulge: p.bulge } : {}
|
|
442
489
|
}));
|
|
490
|
+
const mainPath = trackPath(d.mainPath) ?? [];
|
|
443
491
|
return {
|
|
444
492
|
lengthInches: len,
|
|
445
493
|
loop,
|
|
@@ -456,6 +504,7 @@ function docToState(doc, fallbackLength, moduleTracks = []) {
|
|
|
456
504
|
poseOverrides,
|
|
457
505
|
endplateWidths,
|
|
458
506
|
outline,
|
|
507
|
+
mainPath,
|
|
459
508
|
crossings: (d.crossings ?? []).map((x) => ({
|
|
460
509
|
id: x.id,
|
|
461
510
|
name: x.name ?? "",
|
|
@@ -942,6 +991,6 @@ function poseOverridesFromDoc(doc) {
|
|
|
942
991
|
return out;
|
|
943
992
|
}
|
|
944
993
|
|
|
945
|
-
export { FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, MAIN2_TRACK_ID, MAIN_TRACK_ID, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleCenterline, moduleFeatures, moduleFootprint, nextId, poseNeedsManual, poseOverridesFromDoc, sampleBenchworkOutline, scaleFeetToInches, stateToDoc };
|
|
994
|
+
export { FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, MAIN2_TRACK_ID, MAIN_TRACK_ID, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleCenterline, moduleFeatures, moduleFootprint, nextId, poseNeedsManual, poseOverridesFromDoc, sampleBenchworkOutline, samplePath, scaleFeetToInches, stateToDoc, trackPath };
|
|
946
995
|
//# sourceMappingURL=index.js.map
|
|
947
996
|
//# sourceMappingURL=index.js.map
|