@willcgage/module-schematic 0.24.0 → 0.26.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 +28 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +28 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -201,6 +201,10 @@ interface ModuleSchematicDoc {
|
|
|
201
201
|
* tracks unrolled as a ladder past the throat — the default when inLoop
|
|
202
202
|
* tracks exist), "geometric" (drawn balloon, AL&E-style). */
|
|
203
203
|
loopRender?: "bulb" | "fan" | "geometric";
|
|
204
|
+
/** The two mains' positions are swapped: Main 1 draws above (lane 1), Main 2
|
|
205
|
+
* on the centre line (lane 0). Absent/false = the default (Main 1 below).
|
|
206
|
+
* Identities are unchanged — only which lane each is drawn in (#FMN-0043). */
|
|
207
|
+
mainsSwapped?: boolean;
|
|
204
208
|
endplates: SchematicEndplate[];
|
|
205
209
|
tracks: SchematicTrack[];
|
|
206
210
|
turnouts?: SchematicTurnout[];
|
|
@@ -429,6 +433,11 @@ interface EditorState {
|
|
|
429
433
|
loopReturn: "same" | "main2";
|
|
430
434
|
configA: TrackConfig;
|
|
431
435
|
configB: EndplateBConfig;
|
|
436
|
+
/** Swap the two mains' POSITIONS: Main 1 draws above (lane 1) and Main 2 on
|
|
437
|
+
* the centre line (lane 0). The module decides which physical track is which
|
|
438
|
+
* main — on some modules the upper track is the through/primary main
|
|
439
|
+
* (#FMN-0043). Identities and references are unchanged; only the lanes swap. */
|
|
440
|
+
mainsSwapped: boolean;
|
|
432
441
|
extraTracks: EditorTrack[];
|
|
433
442
|
turnouts: EditorTurnout[];
|
|
434
443
|
/** Grade crossings / diamonds (#170). */
|
package/dist/index.d.ts
CHANGED
|
@@ -201,6 +201,10 @@ interface ModuleSchematicDoc {
|
|
|
201
201
|
* tracks unrolled as a ladder past the throat — the default when inLoop
|
|
202
202
|
* tracks exist), "geometric" (drawn balloon, AL&E-style). */
|
|
203
203
|
loopRender?: "bulb" | "fan" | "geometric";
|
|
204
|
+
/** The two mains' positions are swapped: Main 1 draws above (lane 1), Main 2
|
|
205
|
+
* on the centre line (lane 0). Absent/false = the default (Main 1 below).
|
|
206
|
+
* Identities are unchanged — only which lane each is drawn in (#FMN-0043). */
|
|
207
|
+
mainsSwapped?: boolean;
|
|
204
208
|
endplates: SchematicEndplate[];
|
|
205
209
|
tracks: SchematicTrack[];
|
|
206
210
|
turnouts?: SchematicTurnout[];
|
|
@@ -429,6 +433,11 @@ interface EditorState {
|
|
|
429
433
|
loopReturn: "same" | "main2";
|
|
430
434
|
configA: TrackConfig;
|
|
431
435
|
configB: EndplateBConfig;
|
|
436
|
+
/** Swap the two mains' POSITIONS: Main 1 draws above (lane 1) and Main 2 on
|
|
437
|
+
* the centre line (lane 0). The module decides which physical track is which
|
|
438
|
+
* main — on some modules the upper track is the through/primary main
|
|
439
|
+
* (#FMN-0043). Identities and references are unchanged; only the lanes swap. */
|
|
440
|
+
mainsSwapped: boolean;
|
|
432
441
|
extraTracks: EditorTrack[];
|
|
433
442
|
turnouts: EditorTurnout[];
|
|
434
443
|
/** Grade crossings / diamonds (#170). */
|
package/dist/index.js
CHANGED
|
@@ -208,6 +208,7 @@ function emptyEditorState(lengthInches) {
|
|
|
208
208
|
loopReturn: "same",
|
|
209
209
|
configA: "single",
|
|
210
210
|
configB: "single",
|
|
211
|
+
mainsSwapped: false,
|
|
211
212
|
extraTracks: [],
|
|
212
213
|
turnouts: [],
|
|
213
214
|
crossings: [],
|
|
@@ -224,18 +225,35 @@ function emptyEditorState(lengthInches) {
|
|
|
224
225
|
function isTransitionTurnout(t) {
|
|
225
226
|
return t.onTrack === MAIN_TRACK_ID && t.divergeTrack === MAIN2_TRACK_ID || t.onTrack === MAIN2_TRACK_ID && t.divergeTrack === MAIN_TRACK_ID;
|
|
226
227
|
}
|
|
228
|
+
function main1Track(state) {
|
|
229
|
+
const bothDouble = state.configA === "double" && state.configB === "double";
|
|
230
|
+
const isDouble = state.configA === "double" || state.configB === "double";
|
|
231
|
+
const sw = state.turnouts.find(isTransitionTurnout);
|
|
232
|
+
const lane = state.mainsSwapped && isDouble ? 1 : 0;
|
|
233
|
+
if (!isDouble || bothDouble || !sw || sw.onTrack !== MAIN2_TRACK_ID) {
|
|
234
|
+
return { id: MAIN_TRACK_ID, role: "main", lane, from: "A", to: "B" };
|
|
235
|
+
}
|
|
236
|
+
return state.configA === "double" ? (
|
|
237
|
+
// Double at A: Main 1 runs from A and ends at the turnout.
|
|
238
|
+
{ id: MAIN_TRACK_ID, role: "main", lane, fromPos: 0, toPos: sw.pos }
|
|
239
|
+
) : (
|
|
240
|
+
// Double at B: Main 1 begins at the turnout and runs to B.
|
|
241
|
+
{ id: MAIN_TRACK_ID, role: "main", lane, fromPos: sw.pos, toPos: state.lengthInches }
|
|
242
|
+
);
|
|
243
|
+
}
|
|
227
244
|
function main2Track(state) {
|
|
228
245
|
const bothDouble = state.configA === "double" && state.configB === "double";
|
|
229
246
|
const sw = state.turnouts.find(isTransitionTurnout);
|
|
247
|
+
const lane = state.mainsSwapped ? 0 : 1;
|
|
230
248
|
if (bothDouble || !sw || sw.divergeTrack !== MAIN2_TRACK_ID) {
|
|
231
|
-
return { id: MAIN2_TRACK_ID, role: "main", lane
|
|
249
|
+
return { id: MAIN2_TRACK_ID, role: "main", lane, from: "A", to: "B" };
|
|
232
250
|
}
|
|
233
251
|
return state.configA === "double" ? (
|
|
234
252
|
// Double at A: Main 2 runs from A and ends at the turnout.
|
|
235
|
-
{ id: MAIN2_TRACK_ID, role: "main", lane
|
|
253
|
+
{ id: MAIN2_TRACK_ID, role: "main", lane, fromPos: 0, toPos: sw.pos }
|
|
236
254
|
) : (
|
|
237
255
|
// Double at B: Main 2 begins at the turnout and runs to B.
|
|
238
|
-
{ id: MAIN2_TRACK_ID, role: "main", lane
|
|
256
|
+
{ id: MAIN2_TRACK_ID, role: "main", lane, fromPos: sw.pos, toPos: state.lengthInches }
|
|
239
257
|
);
|
|
240
258
|
}
|
|
241
259
|
function buildTransition(state) {
|
|
@@ -292,6 +310,7 @@ function stateToDoc(state, recordNumber) {
|
|
|
292
310
|
lengthInches: state.lengthInches,
|
|
293
311
|
...state.loop ? { loop: true } : {},
|
|
294
312
|
...state.loop && state.loopReturn === "main2" ? { loopReturn: "main2" } : {},
|
|
313
|
+
...state.mainsSwapped ? { mainsSwapped: true } : {},
|
|
295
314
|
endplates: withWidths(
|
|
296
315
|
withPoses(
|
|
297
316
|
[
|
|
@@ -336,7 +355,11 @@ function stateToDoc(state, recordNumber) {
|
|
|
336
355
|
state.loop ? (
|
|
337
356
|
// The main runs the lead from A and turns back at the balloon.
|
|
338
357
|
{ id: MAIN_TRACK_ID, role: "main", lane: 0, fromPos: 0, toPos: state.lengthInches }
|
|
339
|
-
) :
|
|
358
|
+
) : (
|
|
359
|
+
// Normally A→B; partial when MAIN 2 is the through main and Main 1 is
|
|
360
|
+
// the one that ends at the transition turnout (#FMN-0043).
|
|
361
|
+
main1Track(state)
|
|
362
|
+
),
|
|
340
363
|
// Double track: Main 2 is a real entity so turnouts/signals can attach.
|
|
341
364
|
// On a loop it exists only for a Main 2 directional return (the U joins
|
|
342
365
|
// the two lanes at the balloon); a same-main loop's parallel lead legs
|
|
@@ -499,6 +522,7 @@ function docToState(doc, fallbackLength, moduleTracks = []) {
|
|
|
499
522
|
lengthInches: len,
|
|
500
523
|
loop,
|
|
501
524
|
loopReturn: loop && d.loopReturn === "main2" ? "main2" : "same",
|
|
525
|
+
mainsSwapped: d.mainsSwapped === true,
|
|
502
526
|
configA: configOf("A"),
|
|
503
527
|
// On a loop, a missing B means pure turnback; present = interchange loop.
|
|
504
528
|
configB: loop && !hasB ? "none" : configOf("B"),
|