@willcgage/module-schematic 0.70.0 → 0.72.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 +203 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +225 -13
- package/dist/index.d.ts +225 -13
- package/dist/index.js +193 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -123,6 +123,14 @@ interface SchematicTrack {
|
|
|
123
123
|
* the main centre-line + lane, as before. Physical view only; the operations
|
|
124
124
|
* view stays positional (#2d-track). */
|
|
125
125
|
path?: BenchworkPoint[] | null;
|
|
126
|
+
/** The flex product this run is laid with — a slug from the parts library
|
|
127
|
+
* (#193). Absent = the default. Per TRACK, so a module can have its mains in
|
|
128
|
+
* one product and a siding in another. */
|
|
129
|
+
flexPartId?: string | null;
|
|
130
|
+
/** Authored rail joints, inches along this run. Absent = derived from the
|
|
131
|
+
* product's maximum piece length. Present = these are the ONLY joints, so an
|
|
132
|
+
* owner's deliberate cut survives a change elsewhere on the module. */
|
|
133
|
+
flexCuts?: number[] | null;
|
|
126
134
|
}
|
|
127
135
|
interface SchematicTurnout {
|
|
128
136
|
id: string;
|
|
@@ -428,10 +436,18 @@ interface ModuleFootprintInput {
|
|
|
428
436
|
/** Where each endplate's CENTRE sits relative to the main centre-line at that
|
|
429
437
|
* end, inches (signed, along the +normal). Free-moN puts a **double**-track
|
|
430
438
|
* plate's two tracks 9/16″ either side of its centre, so with Main 1 on the
|
|
431
|
-
* centre-line the plate centre is half a track spacing
|
|
432
|
-
*
|
|
433
|
-
*
|
|
439
|
+
* centre-line the plate centre is half a track spacing toward Main 2. Single
|
|
440
|
+
* track crosses at the centre ⇒ 0, and an off-centre track is a signed value.
|
|
441
|
+
* {@link endplateCentreOffsetInches} computes it from what the owner authored.
|
|
442
|
+
*
|
|
443
|
+
* ⚠️ OMITTING an end no longer means 0 — it means "use §2.0", which is a
|
|
444
|
+
* straddle on a double end. Centring a double plate on Main 1 drew its pair
|
|
445
|
+
* wholly to one side, which is what the read-only and catalog views did by
|
|
446
|
+
* passing nothing at all (#190). Pass an explicit number to place a plate. */
|
|
434
447
|
endplateTrackOffsets?: Record<string, number>;
|
|
448
|
+
/** Whether Main 2 runs BELOW Main 1 (`mainsSwapped`, #131). Only affects which
|
|
449
|
+
* way an unauthored double plate straddles. */
|
|
450
|
+
mainsSwapped?: boolean;
|
|
435
451
|
/** Authored benchwork outline (module-local inches), or absent for the band. */
|
|
436
452
|
outline?: BenchworkPoint[] | null;
|
|
437
453
|
/** Authored benchwork HOLE — the inner boundary punched out of `outline` to
|
|
@@ -637,23 +653,45 @@ declare function endplateFaceSegments(center: BenchworkPoint[], widthA?: number,
|
|
|
637
653
|
*/
|
|
638
654
|
declare function moduleFootprint(input: ModuleFootprintInput): ModuleFootprint;
|
|
639
655
|
/**
|
|
640
|
-
*
|
|
641
|
-
*
|
|
642
|
-
*
|
|
643
|
-
*
|
|
656
|
+
* Where an endplate's CENTRE sits relative to MAIN 1 — the renderer's framing,
|
|
657
|
+
* and the one number a drawing needs to place the plate.
|
|
658
|
+
*
|
|
659
|
+
* ⭐ THE single definition. Two callers had their own: the builder computed it
|
|
660
|
+
* inline (swap-aware), and the read-only/catalog footprint **passed nothing at
|
|
661
|
+
* all**, so every plate there was centred on Main 1 — a double end drew its pair
|
|
662
|
+
* entirely to one side of the plate instead of straddling it (#190).
|
|
663
|
+
*
|
|
664
|
+
* §2.0 puts a double end's two tracks 0.5625″ either side of the plate centre,
|
|
665
|
+
* so the plate centre is half a track spacing away from Main 1 — **toward Main
|
|
666
|
+
* 2**, which is why the swap matters: with Main 2 below, the plate centre is
|
|
667
|
+
* below too. An authored offset always wins (an off-centre end is legal since
|
|
668
|
+
* the 20220628 revision), and is given in the standard's own framing — Main 1's
|
|
669
|
+
* distance from the plate centre — so it comes back negated here.
|
|
644
670
|
*/
|
|
645
|
-
declare function
|
|
671
|
+
declare function endplateCentreOffsetInches(input: {
|
|
672
|
+
config?: TrackConfig | "none" | null;
|
|
673
|
+
/** Main 1's signed distance from the plate centre, as authored. */
|
|
674
|
+
authoredTrackOffsetInches?: number | null;
|
|
675
|
+
/** Whether Main 2 runs below Main 1 (the mains are swapped). */
|
|
676
|
+
main2Below?: boolean;
|
|
677
|
+
}): number;
|
|
646
678
|
/**
|
|
647
679
|
* Where an endplate's PRIMARY track (Main 1) crosses, as a signed distance from
|
|
648
680
|
* the plate's CENTRE — the standard's own framing. Authored value wins; absent
|
|
649
681
|
* falls back to the §2.0 recommendations: a single track centred (0), a double
|
|
650
682
|
* straddling so its two tracks land ∓ half the track spacing (Main 1 low).
|
|
651
683
|
*/
|
|
652
|
-
declare function endplateTrackOffsetInches(authored: number | null | undefined, config: TrackConfig | "none" | undefined
|
|
684
|
+
declare function endplateTrackOffsetInches(authored: number | null | undefined, config: TrackConfig | "none" | undefined,
|
|
685
|
+
/** Whether Main 2 runs BELOW Main 1 (the mains are swapped). The pair
|
|
686
|
+
* straddles the plate centre either way, so Main 1 sits on the side AWAY from
|
|
687
|
+
* Main 2 — low when Main 2 is high, high when it's low. Omitting this
|
|
688
|
+
* hard-coded "Main 2 is above", which is the assumption behind #190. */
|
|
689
|
+
main2Below?: boolean): number;
|
|
653
690
|
/** A Free-moN conformance problem with an endplate's width/track placement. */
|
|
654
691
|
interface EndplateWidthIssue {
|
|
655
|
-
/** "narrow" = below the 12″ minimum; "clearance" = a track too near a fascia
|
|
656
|
-
|
|
692
|
+
/** "narrow" = below the 12″ minimum; "clearance" = a track too near a fascia;
|
|
693
|
+
* "offcentre" = a double end whose pair doesn't straddle the plate centre. */
|
|
694
|
+
code: "narrow" | "clearance" | "offcentre";
|
|
657
695
|
/** Plain-language problem, for the author. */
|
|
658
696
|
message: string;
|
|
659
697
|
/** The width that would satisfy this rule, inches. */
|
|
@@ -676,6 +714,10 @@ declare function checkEndplateWidth(input: {
|
|
|
676
714
|
widthInches?: number | null;
|
|
677
715
|
config?: TrackConfig | "none" | null;
|
|
678
716
|
trackOffsetInches?: number | null;
|
|
717
|
+
/** Whether Main 2 runs BELOW Main 1 (the mains are swapped). Without it a
|
|
718
|
+
* double end's second track was assumed to be one spacing ABOVE Main 1, so a
|
|
719
|
+
* swapped pair was measured on the wrong side of the plate (#190). */
|
|
720
|
+
main2Below?: boolean;
|
|
679
721
|
}): EndplateWidthIssue[];
|
|
680
722
|
/**
|
|
681
723
|
* Whether a module presents NO far endplate — one conforming face only.
|
|
@@ -863,6 +905,19 @@ interface EditorState {
|
|
|
863
905
|
y: number;
|
|
864
906
|
heading: number;
|
|
865
907
|
}>;
|
|
908
|
+
/**
|
|
909
|
+
* Flex track settings by TRACK id (#193) — which product a run is laid with,
|
|
910
|
+
* and where the owner has decided its rail joints fall.
|
|
911
|
+
*
|
|
912
|
+
* One map rather than fields, because the MAINS aren't `extraTracks` (the main
|
|
913
|
+
* IS the centre-line), so per-track settings would otherwise need a separate
|
|
914
|
+
* pair of fields for Main 1 and Main 2 — four ways to say one thing. Round-trips
|
|
915
|
+
* onto each track in the doc, where it's self-describing for Free-Dispatcher.
|
|
916
|
+
*/
|
|
917
|
+
flexByTrack: Record<string, {
|
|
918
|
+
partId?: string;
|
|
919
|
+
cuts?: number[];
|
|
920
|
+
}>;
|
|
866
921
|
/** Authored endplate face widths by endplate id, inches (Free-moN 12″ min,
|
|
867
922
|
* 24″ recommended). Absent id = the recommended default. */
|
|
868
923
|
endplateWidths: Record<string, number>;
|
|
@@ -1208,7 +1263,10 @@ interface TrackPart {
|
|
|
1208
1263
|
line: string;
|
|
1209
1264
|
scale: "N";
|
|
1210
1265
|
name: string;
|
|
1211
|
-
|
|
1266
|
+
/** `flex` is track sold by the length rather than as a fixed geometry — its
|
|
1267
|
+
* {@link overallLength} is the LONGEST piece you can lay from it, not a shape
|
|
1268
|
+
* (#193). */
|
|
1269
|
+
kind: "turnout" | "wye" | "curved-turnout" | "crossing" | "flex";
|
|
1212
1270
|
/** Manufacturer part numbers by hand, where the part has a hand. */
|
|
1213
1271
|
partNumbers?: {
|
|
1214
1272
|
left?: string;
|
|
@@ -1316,10 +1374,164 @@ declare const CODE55_RAIL_HEIGHT_INCHES = 0.055;
|
|
|
1316
1374
|
* everything else is a tooling decision. **Measure the part. Do not model it.**
|
|
1317
1375
|
*/
|
|
1318
1376
|
declare const ATLAS_CODE55_N: TrackPart[];
|
|
1377
|
+
/**
|
|
1378
|
+
* Flex track — the stuff every run that isn't a turnout or a crossing is made
|
|
1379
|
+
* of (#193). A length of flex has no fixed geometry, so the only dimension it
|
|
1380
|
+
* carries is **how long a piece you can lay from one**: past that you have
|
|
1381
|
+
* another length, with a rail joint between them.
|
|
1382
|
+
*
|
|
1383
|
+
* ⚠️ These lengths are the NOMINAL PRODUCT LENGTHS as reported by Will Gage
|
|
1384
|
+
* (2026-07-26), not values read off a spec sheet or measured. They are what the
|
|
1385
|
+
* product is sold as — "30 inch flex track" — which is exactly the number a
|
|
1386
|
+
* builder plans cuts against, so they're recorded as `manufacturer` with the
|
|
1387
|
+
* source named. Correct them if a listing says otherwise.
|
|
1388
|
+
*
|
|
1389
|
+
* No part numbers here: I don't have them confirmed, and a wrong part number is
|
|
1390
|
+
* worse than none — someone would order against it.
|
|
1391
|
+
*/
|
|
1392
|
+
declare const FLEX_TRACK_PARTS: TrackPart[];
|
|
1393
|
+
/** What a track is laid with when nobody has said — the commonest N-scale flex. */
|
|
1394
|
+
declare const DEFAULT_FLEX_PART_ID = "atlas-c55-n-flex";
|
|
1319
1395
|
/** Every built-in part, across manufacturers. */
|
|
1320
1396
|
declare const BUILT_IN_TRACK_PARTS: TrackPart[];
|
|
1397
|
+
/** Every flex product a track can be laid with. */
|
|
1398
|
+
declare function flexParts(library?: TrackPart[]): TrackPart[];
|
|
1399
|
+
/**
|
|
1400
|
+
* The flex product a track is laid with, falling back to the default rather
|
|
1401
|
+
* than to nothing: every non-turnout inch of track IS some product, and a run
|
|
1402
|
+
* whose owner hasn't chosen still gets cut into buyable lengths.
|
|
1403
|
+
*/
|
|
1404
|
+
declare function flexPartFor(id: string | null | undefined, library?: TrackPart[]): TrackPart | null;
|
|
1405
|
+
/** How long a single piece of this product can be, inches. */
|
|
1406
|
+
declare function maxFlexPieceInches(id: string | null | undefined, library?: TrackPart[]): number;
|
|
1321
1407
|
/** Look a part up by its slug. */
|
|
1322
1408
|
declare function trackPart(id: string, library?: TrackPart[]): TrackPart | null;
|
|
1409
|
+
/** One length of flex track in a run — a real object you could pick up (#193). */
|
|
1410
|
+
interface FlexPiece {
|
|
1411
|
+
/** Position in the run, west to east. Stable enough to select and label by. */
|
|
1412
|
+
index: number;
|
|
1413
|
+
/** Inches along the RUN, not the module — the same coordinate turnouts,
|
|
1414
|
+
* industries and signals use, so a piece can be placed without a second
|
|
1415
|
+
* geometry to keep in step. */
|
|
1416
|
+
fromPos: number;
|
|
1417
|
+
toPos: number;
|
|
1418
|
+
lengthInches: number;
|
|
1419
|
+
/** Longer than the product allows. Only reachable from AUTHORED cuts, or from
|
|
1420
|
+
* a run that grew after they were authored — which is precisely when someone
|
|
1421
|
+
* needs telling. */
|
|
1422
|
+
overlong: boolean;
|
|
1423
|
+
/** What this piece butts against at each end: another piece, a part (turnout
|
|
1424
|
+
* or crossing), or the end of the run. */
|
|
1425
|
+
fromEnd: FlexPieceEnd;
|
|
1426
|
+
toEnd: FlexPieceEnd;
|
|
1427
|
+
}
|
|
1428
|
+
/** What a flex piece meets at one of its ends. */
|
|
1429
|
+
type FlexPieceEnd = "piece" | "part" | "runEnd";
|
|
1430
|
+
/**
|
|
1431
|
+
* A stretch of a run that is NOT flex — a turnout's or a crossing's own body.
|
|
1432
|
+
*
|
|
1433
|
+
* A **zero-length** span is meaningful: it's a break in the run at a point whose
|
|
1434
|
+
* own length we don't know. That's a crossing today — the run stops and starts
|
|
1435
|
+
* there, giving a rail joint, but we've measured no crossing part so claiming an
|
|
1436
|
+
* extent for it would be inventing one.
|
|
1437
|
+
*/
|
|
1438
|
+
interface OccupiedSpan {
|
|
1439
|
+
fromPos: number;
|
|
1440
|
+
toPos: number;
|
|
1441
|
+
}
|
|
1442
|
+
/**
|
|
1443
|
+
* Cut a run into lengths of flex track.
|
|
1444
|
+
*
|
|
1445
|
+
* The model (#193): everything that isn't a turnout or a crossing is flex, flex
|
|
1446
|
+
* comes in pieces of a maximum length, and where two pieces meet is a rail
|
|
1447
|
+
* joint — the same joint a turnout makes with the track past it (#189). A 96″
|
|
1448
|
+
* main isn't one piece of track; it's four lengths of Atlas flex with three
|
|
1449
|
+
* joints in it, which is what someone actually buys and lays.
|
|
1450
|
+
*
|
|
1451
|
+
* Pieces are **spans of the run**, not free-floating geometry. That's deliberate:
|
|
1452
|
+
* `pos` — inches along the run — is what every turnout, industry and signal is
|
|
1453
|
+
* placed in, so a piece that carried its own shape would be a second geometry to
|
|
1454
|
+
* keep in step with the first. As spans they get identity, a length you can
|
|
1455
|
+
* change, and ends that meet their neighbours by construction.
|
|
1456
|
+
*
|
|
1457
|
+
* `cuts` is the owner's authoring and is **complete when present**: those are
|
|
1458
|
+
* the only joints, and a piece that ends up too long is flagged rather than
|
|
1459
|
+
* silently re-cut. Absent, the cuts are derived — full lengths from the start of
|
|
1460
|
+
* each gap, remainder at the end, which is how you lay it. That's what lets
|
|
1461
|
+
* every existing module arrive already cut up without anyone touching it.
|
|
1462
|
+
*/
|
|
1463
|
+
declare function flexPieces(input: {
|
|
1464
|
+
fromPos: number;
|
|
1465
|
+
toPos: number;
|
|
1466
|
+
/** Longest single piece of the product this run is laid with. */
|
|
1467
|
+
maxPieceInches: number;
|
|
1468
|
+
/** Stretches the run gives up to parts — turnout bodies, crossings. */
|
|
1469
|
+
occupied?: OccupiedSpan[] | null;
|
|
1470
|
+
/** Authored joint positions, inches along the run. Absent = derive. */
|
|
1471
|
+
cuts?: number[] | null;
|
|
1472
|
+
}): FlexPiece[];
|
|
1473
|
+
/**
|
|
1474
|
+
* Which way a turnout faces along its host track: `+1` = its points look toward
|
|
1475
|
+
* increasing pos, `-1` = the other way.
|
|
1476
|
+
*
|
|
1477
|
+
* ⭐ ONE definition. The canvas had this inline for drawing the leg, and the
|
|
1478
|
+
* flex solver needs the same answer to know which side of `pos` the moulding
|
|
1479
|
+
* extends — a turnout's body is NOT symmetric about its points (an Atlas #7 is
|
|
1480
|
+
* about 0.9″ behind them and 5.1″ ahead), so getting the facing wrong moves a
|
|
1481
|
+
* rail joint four inches (#193).
|
|
1482
|
+
*
|
|
1483
|
+
* The rule: the turnout faces the way its diverging track LEAVES, because that's
|
|
1484
|
+
* where the frog is. `flipped` is the owner's override — rotating the part 180°
|
|
1485
|
+
* faces the points the other way, which is the only thing that can be right for
|
|
1486
|
+
* a siding pinned at a module end where the geometry reads ambiguously.
|
|
1487
|
+
*
|
|
1488
|
+
* `divergeFarPos` is whatever the caller can measure best: the canvas projects
|
|
1489
|
+
* the diverging track's real far end back onto the main, the editor uses its
|
|
1490
|
+
* authored extent. Same rule either way; only the precision of the input differs.
|
|
1491
|
+
*/
|
|
1492
|
+
declare function turnoutFacing(input: {
|
|
1493
|
+
pos: number;
|
|
1494
|
+
/** Where the diverging track ends up, in the same coordinate as `pos`. */
|
|
1495
|
+
divergeFarPos?: number | null;
|
|
1496
|
+
flipped?: boolean;
|
|
1497
|
+
}): 1 | -1;
|
|
1498
|
+
/**
|
|
1499
|
+
* The stretch of its host run a turnout's moulding occupies (#193) — what flex
|
|
1500
|
+
* track has to stop short of on each side.
|
|
1501
|
+
*
|
|
1502
|
+
* Null when the part hasn't been measured, exactly as {@link partExtent} is:
|
|
1503
|
+
* without a real length we don't know where the moulding stops, and a guessed
|
|
1504
|
+
* body would put a rail joint on track nobody has checked.
|
|
1505
|
+
*/
|
|
1506
|
+
declare function turnoutOccupiedSpan(input: {
|
|
1507
|
+
pos: number;
|
|
1508
|
+
extent: PartExtent | null | undefined;
|
|
1509
|
+
facing: 1 | -1;
|
|
1510
|
+
}): OccupiedSpan | null;
|
|
1511
|
+
/**
|
|
1512
|
+
* Retype one piece's length: move the rail joint at its far end, and let its
|
|
1513
|
+
* NEIGHBOUR take up the difference (#193).
|
|
1514
|
+
*
|
|
1515
|
+
* That's what cutting one piece longer actually does — the run doesn't grow, so
|
|
1516
|
+
* the next piece gets shorter by the same amount. The pair's total is fixed,
|
|
1517
|
+
* which is why the value is clamped to it: without that, asking for a length
|
|
1518
|
+
* past the next joint silently reorders the cuts and you get back something you
|
|
1519
|
+
* didn't ask for.
|
|
1520
|
+
*
|
|
1521
|
+
* Returns the run's COMPLETE new cut list (`flexCuts`), or null when the piece
|
|
1522
|
+
* has no neighbour to trade with — the last piece in a gap butts a turnout or
|
|
1523
|
+
* the endplate, and its length is set by what it meets, not by preference.
|
|
1524
|
+
*/
|
|
1525
|
+
declare function resizeFlexPiece(pieces: FlexPiece[], index: number, nextLengthInches: number): number[] | null;
|
|
1526
|
+
/** What a run costs in flex, for someone about to order it (#193). */
|
|
1527
|
+
declare function flexUsage(pieces: FlexPiece[]): {
|
|
1528
|
+
/** How many separate lengths have to be cut. */
|
|
1529
|
+
pieces: number;
|
|
1530
|
+
/** Total flex laid, inches — the run minus whatever the parts occupy. */
|
|
1531
|
+
totalInches: number;
|
|
1532
|
+
/** Pieces the product can't actually supply in one length. */
|
|
1533
|
+
overlong: number;
|
|
1534
|
+
};
|
|
1323
1535
|
/** Half an N-scale tie, inches — a 8′6″ tie is 102″ prototype, /160 ≈ 0.638″.
|
|
1324
1536
|
* The half-width a tie strip extends either side of the rail it carries, which
|
|
1325
1537
|
* is what gives a drawn turnout body its width. */
|
|
@@ -1810,4 +2022,4 @@ declare function poseOverridesFromDoc(doc: ModuleSchematicDoc): Record<string, {
|
|
|
1810
2022
|
heading: number;
|
|
1811
2023
|
}>;
|
|
1812
2024
|
|
|
1813
|
-
export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, type BenchworkPoint, type BranchConnector, CODE55_RAIL_HEIGHT_INCHES, type DimensionSource, type DrawCrossing, type DrawCrossover, type DrawIndustry, type DrawSignal, type DrawTrack, type DrawTurnout, ENDPLATE_FASCIA_CLEAR_INCHES, ENDPLATE_LEAD_INCHES, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorIndustry, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplatePose, type EndplateTrackIssue, type EndplateWidthIssue, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_TRACK_SPACING_INCHES, type FrogCasting, type GeometryType, type ImportedPart, 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 PartAngle, type PartDimension, type PartEnd, type PartExtent, type PartSegment, RAIL_GAUGE_INCHES, type ReturnLoopGeometry, type ReturnLoopShape, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicIndustry, type SchematicSection, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SectionAdjacency, type SectionFootprint, type SectionRelativePos, type SignalFacing, type SignalSide, type StoredTrackPart, TIE_HALF_LENGTH_INCHES, TURNOUT_LEAD_INCHES_PER_FROG, type TrackConfig, type TrackPart, type TrackRole, type TurnoutClosure, type TurnoutKind, WHOLE_MODULE_SECTION_ID, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, checkEndplateWidth, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateLead,
|
|
2025
|
+
export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, type BenchworkPoint, type BranchConnector, CODE55_RAIL_HEIGHT_INCHES, DEFAULT_FLEX_PART_ID, type DimensionSource, type DrawCrossing, type DrawCrossover, type DrawIndustry, type DrawSignal, type DrawTrack, type DrawTurnout, ENDPLATE_FASCIA_CLEAR_INCHES, ENDPLATE_LEAD_INCHES, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorIndustry, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplatePose, type EndplateTrackIssue, type EndplateWidthIssue, FLEX_TRACK_PARTS, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_TRACK_SPACING_INCHES, type FlexPiece, type FlexPieceEnd, type FrogCasting, type GeometryType, type ImportedPart, 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 OccupiedSpan, type OutlineFace, type PartAngle, type PartDimension, type PartEnd, type PartExtent, type PartSegment, RAIL_GAUGE_INCHES, type ReturnLoopGeometry, type ReturnLoopShape, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicIndustry, type SchematicSection, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SectionAdjacency, type SectionFootprint, type SectionRelativePos, type SignalFacing, type SignalSide, type StoredTrackPart, TIE_HALF_LENGTH_INCHES, TURNOUT_LEAD_INCHES_PER_FROG, type TrackConfig, type TrackPart, type TrackRole, type TurnoutClosure, type TurnoutKind, WHOLE_MODULE_SECTION_ID, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, checkEndplateWidth, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateCentreOffsetInches, endplateFaceSegments, endplateLead, endplateTrackOffsetInches, endplateWidthInches, flexPartFor, flexParts, flexPieces, flexUsage, frogCasting, frogNumberFromName, fromSectionRelative, geometryTurnDegrees, hasNoFarEndplate, importedPartToTrackPart, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, leadInchesForSize, maxFlexPieceInches, mergeImportedParts, mergeStoredParts, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partExtent, partExtentForSize, partOutlineAtFrog, pastFrogInchesForSize, pathLengthInches, poseNeedsManual, poseOverridesFromDoc, remapPos, resizeFlexPiece, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionedCenterline, sectionedEndPose, sliceCenterline, stateToDoc, storedPartToTrackPart, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutFacing, turnoutOccupiedSpan, turnoutPartForSize };
|
package/dist/index.d.ts
CHANGED
|
@@ -123,6 +123,14 @@ interface SchematicTrack {
|
|
|
123
123
|
* the main centre-line + lane, as before. Physical view only; the operations
|
|
124
124
|
* view stays positional (#2d-track). */
|
|
125
125
|
path?: BenchworkPoint[] | null;
|
|
126
|
+
/** The flex product this run is laid with — a slug from the parts library
|
|
127
|
+
* (#193). Absent = the default. Per TRACK, so a module can have its mains in
|
|
128
|
+
* one product and a siding in another. */
|
|
129
|
+
flexPartId?: string | null;
|
|
130
|
+
/** Authored rail joints, inches along this run. Absent = derived from the
|
|
131
|
+
* product's maximum piece length. Present = these are the ONLY joints, so an
|
|
132
|
+
* owner's deliberate cut survives a change elsewhere on the module. */
|
|
133
|
+
flexCuts?: number[] | null;
|
|
126
134
|
}
|
|
127
135
|
interface SchematicTurnout {
|
|
128
136
|
id: string;
|
|
@@ -428,10 +436,18 @@ interface ModuleFootprintInput {
|
|
|
428
436
|
/** Where each endplate's CENTRE sits relative to the main centre-line at that
|
|
429
437
|
* end, inches (signed, along the +normal). Free-moN puts a **double**-track
|
|
430
438
|
* plate's two tracks 9/16″ either side of its centre, so with Main 1 on the
|
|
431
|
-
* centre-line the plate centre is half a track spacing
|
|
432
|
-
*
|
|
433
|
-
*
|
|
439
|
+
* centre-line the plate centre is half a track spacing toward Main 2. Single
|
|
440
|
+
* track crosses at the centre ⇒ 0, and an off-centre track is a signed value.
|
|
441
|
+
* {@link endplateCentreOffsetInches} computes it from what the owner authored.
|
|
442
|
+
*
|
|
443
|
+
* ⚠️ OMITTING an end no longer means 0 — it means "use §2.0", which is a
|
|
444
|
+
* straddle on a double end. Centring a double plate on Main 1 drew its pair
|
|
445
|
+
* wholly to one side, which is what the read-only and catalog views did by
|
|
446
|
+
* passing nothing at all (#190). Pass an explicit number to place a plate. */
|
|
434
447
|
endplateTrackOffsets?: Record<string, number>;
|
|
448
|
+
/** Whether Main 2 runs BELOW Main 1 (`mainsSwapped`, #131). Only affects which
|
|
449
|
+
* way an unauthored double plate straddles. */
|
|
450
|
+
mainsSwapped?: boolean;
|
|
435
451
|
/** Authored benchwork outline (module-local inches), or absent for the band. */
|
|
436
452
|
outline?: BenchworkPoint[] | null;
|
|
437
453
|
/** Authored benchwork HOLE — the inner boundary punched out of `outline` to
|
|
@@ -637,23 +653,45 @@ declare function endplateFaceSegments(center: BenchworkPoint[], widthA?: number,
|
|
|
637
653
|
*/
|
|
638
654
|
declare function moduleFootprint(input: ModuleFootprintInput): ModuleFootprint;
|
|
639
655
|
/**
|
|
640
|
-
*
|
|
641
|
-
*
|
|
642
|
-
*
|
|
643
|
-
*
|
|
656
|
+
* Where an endplate's CENTRE sits relative to MAIN 1 — the renderer's framing,
|
|
657
|
+
* and the one number a drawing needs to place the plate.
|
|
658
|
+
*
|
|
659
|
+
* ⭐ THE single definition. Two callers had their own: the builder computed it
|
|
660
|
+
* inline (swap-aware), and the read-only/catalog footprint **passed nothing at
|
|
661
|
+
* all**, so every plate there was centred on Main 1 — a double end drew its pair
|
|
662
|
+
* entirely to one side of the plate instead of straddling it (#190).
|
|
663
|
+
*
|
|
664
|
+
* §2.0 puts a double end's two tracks 0.5625″ either side of the plate centre,
|
|
665
|
+
* so the plate centre is half a track spacing away from Main 1 — **toward Main
|
|
666
|
+
* 2**, which is why the swap matters: with Main 2 below, the plate centre is
|
|
667
|
+
* below too. An authored offset always wins (an off-centre end is legal since
|
|
668
|
+
* the 20220628 revision), and is given in the standard's own framing — Main 1's
|
|
669
|
+
* distance from the plate centre — so it comes back negated here.
|
|
644
670
|
*/
|
|
645
|
-
declare function
|
|
671
|
+
declare function endplateCentreOffsetInches(input: {
|
|
672
|
+
config?: TrackConfig | "none" | null;
|
|
673
|
+
/** Main 1's signed distance from the plate centre, as authored. */
|
|
674
|
+
authoredTrackOffsetInches?: number | null;
|
|
675
|
+
/** Whether Main 2 runs below Main 1 (the mains are swapped). */
|
|
676
|
+
main2Below?: boolean;
|
|
677
|
+
}): number;
|
|
646
678
|
/**
|
|
647
679
|
* Where an endplate's PRIMARY track (Main 1) crosses, as a signed distance from
|
|
648
680
|
* the plate's CENTRE — the standard's own framing. Authored value wins; absent
|
|
649
681
|
* falls back to the §2.0 recommendations: a single track centred (0), a double
|
|
650
682
|
* straddling so its two tracks land ∓ half the track spacing (Main 1 low).
|
|
651
683
|
*/
|
|
652
|
-
declare function endplateTrackOffsetInches(authored: number | null | undefined, config: TrackConfig | "none" | undefined
|
|
684
|
+
declare function endplateTrackOffsetInches(authored: number | null | undefined, config: TrackConfig | "none" | undefined,
|
|
685
|
+
/** Whether Main 2 runs BELOW Main 1 (the mains are swapped). The pair
|
|
686
|
+
* straddles the plate centre either way, so Main 1 sits on the side AWAY from
|
|
687
|
+
* Main 2 — low when Main 2 is high, high when it's low. Omitting this
|
|
688
|
+
* hard-coded "Main 2 is above", which is the assumption behind #190. */
|
|
689
|
+
main2Below?: boolean): number;
|
|
653
690
|
/** A Free-moN conformance problem with an endplate's width/track placement. */
|
|
654
691
|
interface EndplateWidthIssue {
|
|
655
|
-
/** "narrow" = below the 12″ minimum; "clearance" = a track too near a fascia
|
|
656
|
-
|
|
692
|
+
/** "narrow" = below the 12″ minimum; "clearance" = a track too near a fascia;
|
|
693
|
+
* "offcentre" = a double end whose pair doesn't straddle the plate centre. */
|
|
694
|
+
code: "narrow" | "clearance" | "offcentre";
|
|
657
695
|
/** Plain-language problem, for the author. */
|
|
658
696
|
message: string;
|
|
659
697
|
/** The width that would satisfy this rule, inches. */
|
|
@@ -676,6 +714,10 @@ declare function checkEndplateWidth(input: {
|
|
|
676
714
|
widthInches?: number | null;
|
|
677
715
|
config?: TrackConfig | "none" | null;
|
|
678
716
|
trackOffsetInches?: number | null;
|
|
717
|
+
/** Whether Main 2 runs BELOW Main 1 (the mains are swapped). Without it a
|
|
718
|
+
* double end's second track was assumed to be one spacing ABOVE Main 1, so a
|
|
719
|
+
* swapped pair was measured on the wrong side of the plate (#190). */
|
|
720
|
+
main2Below?: boolean;
|
|
679
721
|
}): EndplateWidthIssue[];
|
|
680
722
|
/**
|
|
681
723
|
* Whether a module presents NO far endplate — one conforming face only.
|
|
@@ -863,6 +905,19 @@ interface EditorState {
|
|
|
863
905
|
y: number;
|
|
864
906
|
heading: number;
|
|
865
907
|
}>;
|
|
908
|
+
/**
|
|
909
|
+
* Flex track settings by TRACK id (#193) — which product a run is laid with,
|
|
910
|
+
* and where the owner has decided its rail joints fall.
|
|
911
|
+
*
|
|
912
|
+
* One map rather than fields, because the MAINS aren't `extraTracks` (the main
|
|
913
|
+
* IS the centre-line), so per-track settings would otherwise need a separate
|
|
914
|
+
* pair of fields for Main 1 and Main 2 — four ways to say one thing. Round-trips
|
|
915
|
+
* onto each track in the doc, where it's self-describing for Free-Dispatcher.
|
|
916
|
+
*/
|
|
917
|
+
flexByTrack: Record<string, {
|
|
918
|
+
partId?: string;
|
|
919
|
+
cuts?: number[];
|
|
920
|
+
}>;
|
|
866
921
|
/** Authored endplate face widths by endplate id, inches (Free-moN 12″ min,
|
|
867
922
|
* 24″ recommended). Absent id = the recommended default. */
|
|
868
923
|
endplateWidths: Record<string, number>;
|
|
@@ -1208,7 +1263,10 @@ interface TrackPart {
|
|
|
1208
1263
|
line: string;
|
|
1209
1264
|
scale: "N";
|
|
1210
1265
|
name: string;
|
|
1211
|
-
|
|
1266
|
+
/** `flex` is track sold by the length rather than as a fixed geometry — its
|
|
1267
|
+
* {@link overallLength} is the LONGEST piece you can lay from it, not a shape
|
|
1268
|
+
* (#193). */
|
|
1269
|
+
kind: "turnout" | "wye" | "curved-turnout" | "crossing" | "flex";
|
|
1212
1270
|
/** Manufacturer part numbers by hand, where the part has a hand. */
|
|
1213
1271
|
partNumbers?: {
|
|
1214
1272
|
left?: string;
|
|
@@ -1316,10 +1374,164 @@ declare const CODE55_RAIL_HEIGHT_INCHES = 0.055;
|
|
|
1316
1374
|
* everything else is a tooling decision. **Measure the part. Do not model it.**
|
|
1317
1375
|
*/
|
|
1318
1376
|
declare const ATLAS_CODE55_N: TrackPart[];
|
|
1377
|
+
/**
|
|
1378
|
+
* Flex track — the stuff every run that isn't a turnout or a crossing is made
|
|
1379
|
+
* of (#193). A length of flex has no fixed geometry, so the only dimension it
|
|
1380
|
+
* carries is **how long a piece you can lay from one**: past that you have
|
|
1381
|
+
* another length, with a rail joint between them.
|
|
1382
|
+
*
|
|
1383
|
+
* ⚠️ These lengths are the NOMINAL PRODUCT LENGTHS as reported by Will Gage
|
|
1384
|
+
* (2026-07-26), not values read off a spec sheet or measured. They are what the
|
|
1385
|
+
* product is sold as — "30 inch flex track" — which is exactly the number a
|
|
1386
|
+
* builder plans cuts against, so they're recorded as `manufacturer` with the
|
|
1387
|
+
* source named. Correct them if a listing says otherwise.
|
|
1388
|
+
*
|
|
1389
|
+
* No part numbers here: I don't have them confirmed, and a wrong part number is
|
|
1390
|
+
* worse than none — someone would order against it.
|
|
1391
|
+
*/
|
|
1392
|
+
declare const FLEX_TRACK_PARTS: TrackPart[];
|
|
1393
|
+
/** What a track is laid with when nobody has said — the commonest N-scale flex. */
|
|
1394
|
+
declare const DEFAULT_FLEX_PART_ID = "atlas-c55-n-flex";
|
|
1319
1395
|
/** Every built-in part, across manufacturers. */
|
|
1320
1396
|
declare const BUILT_IN_TRACK_PARTS: TrackPart[];
|
|
1397
|
+
/** Every flex product a track can be laid with. */
|
|
1398
|
+
declare function flexParts(library?: TrackPart[]): TrackPart[];
|
|
1399
|
+
/**
|
|
1400
|
+
* The flex product a track is laid with, falling back to the default rather
|
|
1401
|
+
* than to nothing: every non-turnout inch of track IS some product, and a run
|
|
1402
|
+
* whose owner hasn't chosen still gets cut into buyable lengths.
|
|
1403
|
+
*/
|
|
1404
|
+
declare function flexPartFor(id: string | null | undefined, library?: TrackPart[]): TrackPart | null;
|
|
1405
|
+
/** How long a single piece of this product can be, inches. */
|
|
1406
|
+
declare function maxFlexPieceInches(id: string | null | undefined, library?: TrackPart[]): number;
|
|
1321
1407
|
/** Look a part up by its slug. */
|
|
1322
1408
|
declare function trackPart(id: string, library?: TrackPart[]): TrackPart | null;
|
|
1409
|
+
/** One length of flex track in a run — a real object you could pick up (#193). */
|
|
1410
|
+
interface FlexPiece {
|
|
1411
|
+
/** Position in the run, west to east. Stable enough to select and label by. */
|
|
1412
|
+
index: number;
|
|
1413
|
+
/** Inches along the RUN, not the module — the same coordinate turnouts,
|
|
1414
|
+
* industries and signals use, so a piece can be placed without a second
|
|
1415
|
+
* geometry to keep in step. */
|
|
1416
|
+
fromPos: number;
|
|
1417
|
+
toPos: number;
|
|
1418
|
+
lengthInches: number;
|
|
1419
|
+
/** Longer than the product allows. Only reachable from AUTHORED cuts, or from
|
|
1420
|
+
* a run that grew after they were authored — which is precisely when someone
|
|
1421
|
+
* needs telling. */
|
|
1422
|
+
overlong: boolean;
|
|
1423
|
+
/** What this piece butts against at each end: another piece, a part (turnout
|
|
1424
|
+
* or crossing), or the end of the run. */
|
|
1425
|
+
fromEnd: FlexPieceEnd;
|
|
1426
|
+
toEnd: FlexPieceEnd;
|
|
1427
|
+
}
|
|
1428
|
+
/** What a flex piece meets at one of its ends. */
|
|
1429
|
+
type FlexPieceEnd = "piece" | "part" | "runEnd";
|
|
1430
|
+
/**
|
|
1431
|
+
* A stretch of a run that is NOT flex — a turnout's or a crossing's own body.
|
|
1432
|
+
*
|
|
1433
|
+
* A **zero-length** span is meaningful: it's a break in the run at a point whose
|
|
1434
|
+
* own length we don't know. That's a crossing today — the run stops and starts
|
|
1435
|
+
* there, giving a rail joint, but we've measured no crossing part so claiming an
|
|
1436
|
+
* extent for it would be inventing one.
|
|
1437
|
+
*/
|
|
1438
|
+
interface OccupiedSpan {
|
|
1439
|
+
fromPos: number;
|
|
1440
|
+
toPos: number;
|
|
1441
|
+
}
|
|
1442
|
+
/**
|
|
1443
|
+
* Cut a run into lengths of flex track.
|
|
1444
|
+
*
|
|
1445
|
+
* The model (#193): everything that isn't a turnout or a crossing is flex, flex
|
|
1446
|
+
* comes in pieces of a maximum length, and where two pieces meet is a rail
|
|
1447
|
+
* joint — the same joint a turnout makes with the track past it (#189). A 96″
|
|
1448
|
+
* main isn't one piece of track; it's four lengths of Atlas flex with three
|
|
1449
|
+
* joints in it, which is what someone actually buys and lays.
|
|
1450
|
+
*
|
|
1451
|
+
* Pieces are **spans of the run**, not free-floating geometry. That's deliberate:
|
|
1452
|
+
* `pos` — inches along the run — is what every turnout, industry and signal is
|
|
1453
|
+
* placed in, so a piece that carried its own shape would be a second geometry to
|
|
1454
|
+
* keep in step with the first. As spans they get identity, a length you can
|
|
1455
|
+
* change, and ends that meet their neighbours by construction.
|
|
1456
|
+
*
|
|
1457
|
+
* `cuts` is the owner's authoring and is **complete when present**: those are
|
|
1458
|
+
* the only joints, and a piece that ends up too long is flagged rather than
|
|
1459
|
+
* silently re-cut. Absent, the cuts are derived — full lengths from the start of
|
|
1460
|
+
* each gap, remainder at the end, which is how you lay it. That's what lets
|
|
1461
|
+
* every existing module arrive already cut up without anyone touching it.
|
|
1462
|
+
*/
|
|
1463
|
+
declare function flexPieces(input: {
|
|
1464
|
+
fromPos: number;
|
|
1465
|
+
toPos: number;
|
|
1466
|
+
/** Longest single piece of the product this run is laid with. */
|
|
1467
|
+
maxPieceInches: number;
|
|
1468
|
+
/** Stretches the run gives up to parts — turnout bodies, crossings. */
|
|
1469
|
+
occupied?: OccupiedSpan[] | null;
|
|
1470
|
+
/** Authored joint positions, inches along the run. Absent = derive. */
|
|
1471
|
+
cuts?: number[] | null;
|
|
1472
|
+
}): FlexPiece[];
|
|
1473
|
+
/**
|
|
1474
|
+
* Which way a turnout faces along its host track: `+1` = its points look toward
|
|
1475
|
+
* increasing pos, `-1` = the other way.
|
|
1476
|
+
*
|
|
1477
|
+
* ⭐ ONE definition. The canvas had this inline for drawing the leg, and the
|
|
1478
|
+
* flex solver needs the same answer to know which side of `pos` the moulding
|
|
1479
|
+
* extends — a turnout's body is NOT symmetric about its points (an Atlas #7 is
|
|
1480
|
+
* about 0.9″ behind them and 5.1″ ahead), so getting the facing wrong moves a
|
|
1481
|
+
* rail joint four inches (#193).
|
|
1482
|
+
*
|
|
1483
|
+
* The rule: the turnout faces the way its diverging track LEAVES, because that's
|
|
1484
|
+
* where the frog is. `flipped` is the owner's override — rotating the part 180°
|
|
1485
|
+
* faces the points the other way, which is the only thing that can be right for
|
|
1486
|
+
* a siding pinned at a module end where the geometry reads ambiguously.
|
|
1487
|
+
*
|
|
1488
|
+
* `divergeFarPos` is whatever the caller can measure best: the canvas projects
|
|
1489
|
+
* the diverging track's real far end back onto the main, the editor uses its
|
|
1490
|
+
* authored extent. Same rule either way; only the precision of the input differs.
|
|
1491
|
+
*/
|
|
1492
|
+
declare function turnoutFacing(input: {
|
|
1493
|
+
pos: number;
|
|
1494
|
+
/** Where the diverging track ends up, in the same coordinate as `pos`. */
|
|
1495
|
+
divergeFarPos?: number | null;
|
|
1496
|
+
flipped?: boolean;
|
|
1497
|
+
}): 1 | -1;
|
|
1498
|
+
/**
|
|
1499
|
+
* The stretch of its host run a turnout's moulding occupies (#193) — what flex
|
|
1500
|
+
* track has to stop short of on each side.
|
|
1501
|
+
*
|
|
1502
|
+
* Null when the part hasn't been measured, exactly as {@link partExtent} is:
|
|
1503
|
+
* without a real length we don't know where the moulding stops, and a guessed
|
|
1504
|
+
* body would put a rail joint on track nobody has checked.
|
|
1505
|
+
*/
|
|
1506
|
+
declare function turnoutOccupiedSpan(input: {
|
|
1507
|
+
pos: number;
|
|
1508
|
+
extent: PartExtent | null | undefined;
|
|
1509
|
+
facing: 1 | -1;
|
|
1510
|
+
}): OccupiedSpan | null;
|
|
1511
|
+
/**
|
|
1512
|
+
* Retype one piece's length: move the rail joint at its far end, and let its
|
|
1513
|
+
* NEIGHBOUR take up the difference (#193).
|
|
1514
|
+
*
|
|
1515
|
+
* That's what cutting one piece longer actually does — the run doesn't grow, so
|
|
1516
|
+
* the next piece gets shorter by the same amount. The pair's total is fixed,
|
|
1517
|
+
* which is why the value is clamped to it: without that, asking for a length
|
|
1518
|
+
* past the next joint silently reorders the cuts and you get back something you
|
|
1519
|
+
* didn't ask for.
|
|
1520
|
+
*
|
|
1521
|
+
* Returns the run's COMPLETE new cut list (`flexCuts`), or null when the piece
|
|
1522
|
+
* has no neighbour to trade with — the last piece in a gap butts a turnout or
|
|
1523
|
+
* the endplate, and its length is set by what it meets, not by preference.
|
|
1524
|
+
*/
|
|
1525
|
+
declare function resizeFlexPiece(pieces: FlexPiece[], index: number, nextLengthInches: number): number[] | null;
|
|
1526
|
+
/** What a run costs in flex, for someone about to order it (#193). */
|
|
1527
|
+
declare function flexUsage(pieces: FlexPiece[]): {
|
|
1528
|
+
/** How many separate lengths have to be cut. */
|
|
1529
|
+
pieces: number;
|
|
1530
|
+
/** Total flex laid, inches — the run minus whatever the parts occupy. */
|
|
1531
|
+
totalInches: number;
|
|
1532
|
+
/** Pieces the product can't actually supply in one length. */
|
|
1533
|
+
overlong: number;
|
|
1534
|
+
};
|
|
1323
1535
|
/** Half an N-scale tie, inches — a 8′6″ tie is 102″ prototype, /160 ≈ 0.638″.
|
|
1324
1536
|
* The half-width a tie strip extends either side of the rail it carries, which
|
|
1325
1537
|
* is what gives a drawn turnout body its width. */
|
|
@@ -1810,4 +2022,4 @@ declare function poseOverridesFromDoc(doc: ModuleSchematicDoc): Record<string, {
|
|
|
1810
2022
|
heading: number;
|
|
1811
2023
|
}>;
|
|
1812
2024
|
|
|
1813
|
-
export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, type BenchworkPoint, type BranchConnector, CODE55_RAIL_HEIGHT_INCHES, type DimensionSource, type DrawCrossing, type DrawCrossover, type DrawIndustry, type DrawSignal, type DrawTrack, type DrawTurnout, ENDPLATE_FASCIA_CLEAR_INCHES, ENDPLATE_LEAD_INCHES, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorIndustry, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplatePose, type EndplateTrackIssue, type EndplateWidthIssue, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_TRACK_SPACING_INCHES, type FrogCasting, type GeometryType, type ImportedPart, 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 PartAngle, type PartDimension, type PartEnd, type PartExtent, type PartSegment, RAIL_GAUGE_INCHES, type ReturnLoopGeometry, type ReturnLoopShape, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicIndustry, type SchematicSection, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SectionAdjacency, type SectionFootprint, type SectionRelativePos, type SignalFacing, type SignalSide, type StoredTrackPart, TIE_HALF_LENGTH_INCHES, TURNOUT_LEAD_INCHES_PER_FROG, type TrackConfig, type TrackPart, type TrackRole, type TurnoutClosure, type TurnoutKind, WHOLE_MODULE_SECTION_ID, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, checkEndplateWidth, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateLead,
|
|
2025
|
+
export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, type BenchworkPoint, type BranchConnector, CODE55_RAIL_HEIGHT_INCHES, DEFAULT_FLEX_PART_ID, type DimensionSource, type DrawCrossing, type DrawCrossover, type DrawIndustry, type DrawSignal, type DrawTrack, type DrawTurnout, ENDPLATE_FASCIA_CLEAR_INCHES, ENDPLATE_LEAD_INCHES, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorIndustry, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplatePose, type EndplateTrackIssue, type EndplateWidthIssue, FLEX_TRACK_PARTS, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_TRACK_SPACING_INCHES, type FlexPiece, type FlexPieceEnd, type FrogCasting, type GeometryType, type ImportedPart, 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 OccupiedSpan, type OutlineFace, type PartAngle, type PartDimension, type PartEnd, type PartExtent, type PartSegment, RAIL_GAUGE_INCHES, type ReturnLoopGeometry, type ReturnLoopShape, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicIndustry, type SchematicSection, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SectionAdjacency, type SectionFootprint, type SectionRelativePos, type SignalFacing, type SignalSide, type StoredTrackPart, TIE_HALF_LENGTH_INCHES, TURNOUT_LEAD_INCHES_PER_FROG, type TrackConfig, type TrackPart, type TrackRole, type TurnoutClosure, type TurnoutKind, WHOLE_MODULE_SECTION_ID, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, checkEndplateWidth, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateCentreOffsetInches, endplateFaceSegments, endplateLead, endplateTrackOffsetInches, endplateWidthInches, flexPartFor, flexParts, flexPieces, flexUsage, frogCasting, frogNumberFromName, fromSectionRelative, geometryTurnDegrees, hasNoFarEndplate, importedPartToTrackPart, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, leadInchesForSize, maxFlexPieceInches, mergeImportedParts, mergeStoredParts, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partExtent, partExtentForSize, partOutlineAtFrog, pastFrogInchesForSize, pathLengthInches, poseNeedsManual, poseOverridesFromDoc, remapPos, resizeFlexPiece, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionedCenterline, sectionedEndPose, sliceCenterline, stateToDoc, storedPartToTrackPart, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutFacing, turnoutOccupiedSpan, turnoutPartForSize };
|