@willcgage/module-schematic 0.86.0 → 0.90.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 +262 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +214 -1
- package/dist/index.d.ts +214 -1
- package/dist/index.js +258 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1044,6 +1044,10 @@ function stateToDoc(state, recordNumber) {
|
|
|
1044
1044
|
track: ind.track,
|
|
1045
1045
|
fromPos: ind.fromPos,
|
|
1046
1046
|
toPos: ind.toPos,
|
|
1047
|
+
// Carried, not interpreted. An anchor is what HOLDS the span (ADR
|
|
1048
|
+
// 0001); dropping it here would quietly convert an anchored
|
|
1049
|
+
// industry back into a typed number the next time anyone saved.
|
|
1050
|
+
...ind.anchor ? { anchor: ind.anchor } : {},
|
|
1047
1051
|
...ind.spots?.length ? { spots: ind.spots } : {},
|
|
1048
1052
|
side: ind.side,
|
|
1049
1053
|
...ind.labelMode && ind.labelMode !== "none" ? { labelMode: ind.labelMode } : {},
|
|
@@ -1063,7 +1067,11 @@ function stateToDoc(state, recordNumber) {
|
|
|
1063
1067
|
...state.sections.length ? { sections: moduleSections({ sections: state.sections }) } : {},
|
|
1064
1068
|
// Authored mainline path (module-local inches); only when it's a real path.
|
|
1065
1069
|
...state.mainPath.length >= 2 ? { mainPath: state.mainPath } : {},
|
|
1066
|
-
...state.main2Path.length >= 2 ? { main2Path: state.main2Path } : {}
|
|
1070
|
+
...state.main2Path.length >= 2 ? { main2Path: state.main2Path } : {},
|
|
1071
|
+
// The pieces the owner drew, carried verbatim (ADR 0001). This function
|
|
1072
|
+
// stays dumb about them on purpose: deriving here would put the derivation
|
|
1073
|
+
// in every save path in both apps. `deriveGraphDoc` is the one place.
|
|
1074
|
+
...state.graph?.pieces?.length ? { graph: state.graph } : {}
|
|
1067
1075
|
};
|
|
1068
1076
|
}
|
|
1069
1077
|
function docToState(doc, fallbackLength, moduleTracks = []) {
|
|
@@ -1208,6 +1216,10 @@ function docToState(doc, fallbackLength, moduleTracks = []) {
|
|
|
1208
1216
|
sections: moduleSections(d),
|
|
1209
1217
|
mainPath,
|
|
1210
1218
|
main2Path,
|
|
1219
|
+
// ⚠️ NOT scaled by `sc()` like every position above it. A piece is placed in
|
|
1220
|
+
// real inches on the board; stretching the module's length does not move it,
|
|
1221
|
+
// and the length is DERIVED from the pieces anyway when a graph is present.
|
|
1222
|
+
...d.graph?.pieces?.length ? { graph: d.graph } : {},
|
|
1211
1223
|
crossings: (d.crossings ?? []).map((x) => ({
|
|
1212
1224
|
id: x.id,
|
|
1213
1225
|
name: x.name ?? "",
|
|
@@ -1242,12 +1254,14 @@ function docToState(doc, fallbackLength, moduleTracks = []) {
|
|
|
1242
1254
|
track: s.track,
|
|
1243
1255
|
fromPos: sc(s.fromPos ?? 0),
|
|
1244
1256
|
toPos: s.toPos != null ? sc(s.toPos) : len,
|
|
1245
|
-
...s.side ? { side: s.side } : {}
|
|
1257
|
+
...s.side ? { side: s.side } : {},
|
|
1258
|
+
...s.anchor ? { anchor: s.anchor } : {}
|
|
1246
1259
|
})),
|
|
1247
1260
|
side: ind.side ?? "above",
|
|
1248
1261
|
labelMode: ind.labelMode ?? "none",
|
|
1249
1262
|
carTypes: Array.isArray(ind.carTypes) ? ind.carTypes : [],
|
|
1250
|
-
moduleIndustryId: ind.moduleIndustryId ?? null
|
|
1263
|
+
moduleIndustryId: ind.moduleIndustryId ?? null,
|
|
1264
|
+
...ind.anchor ? { anchor: ind.anchor } : {}
|
|
1251
1265
|
}))
|
|
1252
1266
|
};
|
|
1253
1267
|
}
|
|
@@ -2232,6 +2246,54 @@ function partGeometry(part, library = BUILT_IN_TRACK_PARTS) {
|
|
|
2232
2246
|
divergingEndMeasured: de.measured
|
|
2233
2247
|
};
|
|
2234
2248
|
}
|
|
2249
|
+
function pieceRoutePaths(piece, library = BUILT_IN_TRACK_PARTS) {
|
|
2250
|
+
const part = library.find((p) => p.id === piece.partId);
|
|
2251
|
+
if (!part) return [];
|
|
2252
|
+
const geo = partGeometry(part, library);
|
|
2253
|
+
if (!geo) return [];
|
|
2254
|
+
const joints = placedJoints([piece], library);
|
|
2255
|
+
const at = (id) => joints.find((j) => j.joint === id);
|
|
2256
|
+
const RAD = Math.PI / 180;
|
|
2257
|
+
const c = Math.cos(piece.rotationDeg * RAD);
|
|
2258
|
+
const s = Math.sin(piece.rotationDeg * RAD);
|
|
2259
|
+
const place = (x, y) => {
|
|
2260
|
+
const ly = piece.flipped ? -y : y;
|
|
2261
|
+
return { x: piece.x + x * c - ly * s, y: piece.y + x * s + ly * c };
|
|
2262
|
+
};
|
|
2263
|
+
const out = [];
|
|
2264
|
+
for (const route of geo.routes) {
|
|
2265
|
+
const a = at(route[0]);
|
|
2266
|
+
const b = at(route[1]);
|
|
2267
|
+
if (!a || !b) continue;
|
|
2268
|
+
const ends = [{ x: a.x, y: a.y }, { x: b.x, y: b.y }];
|
|
2269
|
+
const diverging = route.some((r) => r === "diverge" || r === "legA" || r === "legB");
|
|
2270
|
+
if (!diverging || part.kind === "flex") {
|
|
2271
|
+
out.push({ route, points: ends });
|
|
2272
|
+
continue;
|
|
2273
|
+
}
|
|
2274
|
+
const lead = part.lead?.inches ?? 0;
|
|
2275
|
+
const pts0 = part.pointsOffset?.inches ?? 0;
|
|
2276
|
+
const far = geo.joints.find((j) => j.id === route[1]) ?? geo.joints.find((j) => j.id === route[0]);
|
|
2277
|
+
if (!far || !(lead > 0)) {
|
|
2278
|
+
out.push({ route, points: ends });
|
|
2279
|
+
continue;
|
|
2280
|
+
}
|
|
2281
|
+
const isWye = part.kind === "wye";
|
|
2282
|
+
const closure = turnoutClosure(isWye ? part.frogNumber * 2 : part.frogNumber, {
|
|
2283
|
+
leadInches: lead
|
|
2284
|
+
});
|
|
2285
|
+
const mirror = route.includes("legB") ? -1 : 1;
|
|
2286
|
+
const pts = [place(0, 0), place(pts0, 0)];
|
|
2287
|
+
const steps = 12;
|
|
2288
|
+
for (let i = 1; i <= steps; i++) {
|
|
2289
|
+
const x = pts0 + (far.x - pts0) * i / steps;
|
|
2290
|
+
pts.push(place(x, mirror * closure.offsetAt(x - pts0)));
|
|
2291
|
+
}
|
|
2292
|
+
pts[pts.length - 1] = { x: b.x, y: b.y };
|
|
2293
|
+
out.push({ route, points: route[0] === "throat" ? pts : pts.slice().reverse() });
|
|
2294
|
+
}
|
|
2295
|
+
return out;
|
|
2296
|
+
}
|
|
2235
2297
|
function partsPlaceable(library = BUILT_IN_TRACK_PARTS) {
|
|
2236
2298
|
const placeable = [];
|
|
2237
2299
|
const blocked = [];
|
|
@@ -2316,6 +2378,36 @@ function buildTrackGraph(pieces, library = BUILT_IN_TRACK_PARTS, snapInches = JO
|
|
|
2316
2378
|
}
|
|
2317
2379
|
return { joints, connections, open, conflicts, unplaceable };
|
|
2318
2380
|
}
|
|
2381
|
+
function snapPiece(moving, others, library = BUILT_IN_TRACK_PARTS, withinInches = 0.5) {
|
|
2382
|
+
const mine = placedJoints([moving], library);
|
|
2383
|
+
if (!mine.length) return null;
|
|
2384
|
+
const graph = buildTrackGraph(others, library);
|
|
2385
|
+
const taken = new Set(graph.connections.flatMap((c2) => [c2.a, c2.b]));
|
|
2386
|
+
const open = graph.joints.filter((j) => !taken.has(j.key));
|
|
2387
|
+
let best = null;
|
|
2388
|
+
for (const m of mine)
|
|
2389
|
+
for (const t of open) {
|
|
2390
|
+
const d = Math.hypot(t.x - m.x, t.y - m.y);
|
|
2391
|
+
if (d <= withinInches && (!best || d < best.d)) best = { m, t, d };
|
|
2392
|
+
}
|
|
2393
|
+
if (!best) return null;
|
|
2394
|
+
const RAD = Math.PI / 180;
|
|
2395
|
+
const dRot = norm360(best.t.headingDeg + 180 - best.m.headingDeg);
|
|
2396
|
+
const c = Math.cos(dRot * RAD);
|
|
2397
|
+
const s = Math.sin(dRot * RAD);
|
|
2398
|
+
const ox = moving.x - best.m.x;
|
|
2399
|
+
const oy = moving.y - best.m.y;
|
|
2400
|
+
return {
|
|
2401
|
+
piece: {
|
|
2402
|
+
...moving,
|
|
2403
|
+
rotationDeg: norm360(moving.rotationDeg + dRot),
|
|
2404
|
+
x: best.t.x + ox * c - oy * s,
|
|
2405
|
+
y: best.t.y + ox * s + oy * c
|
|
2406
|
+
},
|
|
2407
|
+
from: best.m.key,
|
|
2408
|
+
to: best.t.key
|
|
2409
|
+
};
|
|
2410
|
+
}
|
|
2319
2411
|
function walkTrackGraph(graph, pieces, startAt, library = BUILT_IN_TRACK_PARTS) {
|
|
2320
2412
|
const byKey = new Map(graph.joints.map((j) => [j.key, j]));
|
|
2321
2413
|
const pieceById = new Map(pieces.map((p) => [p.id, p]));
|
|
@@ -2346,6 +2438,7 @@ function walkTrackGraph(graph, pieces, startAt, library = BUILT_IN_TRACK_PARTS)
|
|
|
2346
2438
|
bornAt,
|
|
2347
2439
|
endsAt: null,
|
|
2348
2440
|
pieces: [],
|
|
2441
|
+
spans: [],
|
|
2349
2442
|
lateral: 0
|
|
2350
2443
|
};
|
|
2351
2444
|
let cur = startKey;
|
|
@@ -2403,7 +2496,15 @@ function walkTrackGraph(graph, pieces, startAt, library = BUILT_IN_TRACK_PARTS)
|
|
|
2403
2496
|
for (const j of graph.joints)
|
|
2404
2497
|
if (j.piece === here.piece && Math.abs(j.y) > Math.abs(route.lateral))
|
|
2405
2498
|
route.lateral = j.y;
|
|
2499
|
+
const entered = pos;
|
|
2406
2500
|
pos += gap(here, exit);
|
|
2501
|
+
route.spans.push({
|
|
2502
|
+
piece: here.piece,
|
|
2503
|
+
entryJoint: here.joint,
|
|
2504
|
+
exitJoint,
|
|
2505
|
+
fromPos: entered,
|
|
2506
|
+
toPos: pos
|
|
2507
|
+
});
|
|
2407
2508
|
route.toPos = pos;
|
|
2408
2509
|
const next = exit ? link.get(exit.key) : void 0;
|
|
2409
2510
|
if (!next) break;
|
|
@@ -2420,6 +2521,12 @@ function walkTrackGraph(graph, pieces, startAt, library = BUILT_IN_TRACK_PARTS)
|
|
|
2420
2521
|
warnings.push(`the route diverging at ${b.from} is not connected to anything`);
|
|
2421
2522
|
continue;
|
|
2422
2523
|
}
|
|
2524
|
+
const already = routes.find((r2) => r2.pieces.includes(byKey.get(start).piece));
|
|
2525
|
+
if (already) {
|
|
2526
|
+
const swFar = turnouts.find((t) => t.id === b.from);
|
|
2527
|
+
if (swFar && !swFar.divergeRoute) swFar.divergeRoute = already.id;
|
|
2528
|
+
continue;
|
|
2529
|
+
}
|
|
2423
2530
|
n += 1;
|
|
2424
2531
|
const r = walk(start, b.at + b.skew, `route${n}`, b.from);
|
|
2425
2532
|
r.fromPos = b.at;
|
|
@@ -2434,6 +2541,153 @@ function walkTrackGraph(graph, pieces, startAt, library = BUILT_IN_TRACK_PARTS)
|
|
|
2434
2541
|
for (const c of graph.conflicts) warnings.push(c.reason);
|
|
2435
2542
|
return { routes, turnouts, warnings };
|
|
2436
2543
|
}
|
|
2544
|
+
function resolveGraphAnchor(anchor, walk, pieces, library = BUILT_IN_TRACK_PARTS) {
|
|
2545
|
+
const piece = pieces.find((p) => p.id === anchor.piece);
|
|
2546
|
+
const part = piece ? library.find((x) => x.id === piece.partId) : void 0;
|
|
2547
|
+
const origin = part?.kind === "flex" ? "a" : "throat";
|
|
2548
|
+
for (const r of walk.routes) {
|
|
2549
|
+
const span = r.spans.find((s) => s.piece === anchor.piece);
|
|
2550
|
+
if (!span) continue;
|
|
2551
|
+
if (span.entryJoint === origin)
|
|
2552
|
+
return { pos: span.fromPos + anchor.atInches, routeId: r.id, reversed: false };
|
|
2553
|
+
if (span.exitJoint === origin)
|
|
2554
|
+
return { pos: span.toPos - anchor.atInches, routeId: r.id, reversed: true };
|
|
2555
|
+
return null;
|
|
2556
|
+
}
|
|
2557
|
+
return null;
|
|
2558
|
+
}
|
|
2559
|
+
function graphToDoc(pieces, input) {
|
|
2560
|
+
const library = input.library ?? BUILT_IN_TRACK_PARTS;
|
|
2561
|
+
const graph = buildTrackGraph(pieces, library);
|
|
2562
|
+
const walk = walkTrackGraph(graph, pieces, input.startAt, library);
|
|
2563
|
+
const warnings = [...walk.warnings];
|
|
2564
|
+
const round = (n) => Math.round(n * 100) / 100;
|
|
2565
|
+
const base = input.base ?? {};
|
|
2566
|
+
const endplates = base.endplates && base.endplates.length ? base.endplates : [{ id: "A", label: "West" }, { id: "B", label: "East" }];
|
|
2567
|
+
const epA = endplates[0];
|
|
2568
|
+
const epB = endplates[1];
|
|
2569
|
+
const main = walk.routes.find((r) => r.id === "main");
|
|
2570
|
+
const lengthInches = round(main.toPos);
|
|
2571
|
+
const branches = walk.routes.filter((r) => r.id !== "main" && r.pieces.length);
|
|
2572
|
+
const trackIdOf = /* @__PURE__ */ new Map([["main", MAIN_TRACK_ID]]);
|
|
2573
|
+
for (const r of branches) trackIdOf.set(r.id, r.pieces[0]);
|
|
2574
|
+
const laneOf = (r) => {
|
|
2575
|
+
const side = Math.sign(r.lateral) || 1;
|
|
2576
|
+
const sameSide = branches.filter((x) => (Math.sign(x.lateral) || 1) === side).sort((a, b) => Math.abs(a.lateral) - Math.abs(b.lateral));
|
|
2577
|
+
return side * (sameSide.indexOf(r) + 1);
|
|
2578
|
+
};
|
|
2579
|
+
const tracks = [
|
|
2580
|
+
{
|
|
2581
|
+
id: MAIN_TRACK_ID,
|
|
2582
|
+
role: "main",
|
|
2583
|
+
lane: 0,
|
|
2584
|
+
from: epA?.id ?? "A",
|
|
2585
|
+
...epB ? { to: epB.id } : {}
|
|
2586
|
+
}
|
|
2587
|
+
];
|
|
2588
|
+
for (const r of branches) {
|
|
2589
|
+
const id = trackIdOf.get(r.id);
|
|
2590
|
+
const meta = input.meta?.[id] ?? {};
|
|
2591
|
+
tracks.push({
|
|
2592
|
+
id,
|
|
2593
|
+
// It runs back into a second turnout, or it doesn't. That is the whole
|
|
2594
|
+
// difference between a siding and a spur, and it is read, not declared.
|
|
2595
|
+
role: r.endsAt ? "siding" : "spur",
|
|
2596
|
+
lane: laneOf(r),
|
|
2597
|
+
fromPos: round(Math.min(r.fromPos, r.toPos)),
|
|
2598
|
+
toPos: round(Math.max(r.fromPos, r.toPos)),
|
|
2599
|
+
...meta.trackName ? { trackName: meta.trackName } : {},
|
|
2600
|
+
...meta.capacityFeet != null ? { capacityFeet: meta.capacityFeet } : {},
|
|
2601
|
+
...meta.moduleTrackId != null ? { moduleTrackId: meta.moduleTrackId } : {}
|
|
2602
|
+
});
|
|
2603
|
+
}
|
|
2604
|
+
const pieceById = new Map(pieces.map((p) => [p.id, p]));
|
|
2605
|
+
const turnouts = [];
|
|
2606
|
+
for (const t of walk.turnouts) {
|
|
2607
|
+
const diverge = t.divergeRoute ? trackIdOf.get(t.divergeRoute) : void 0;
|
|
2608
|
+
if (!diverge) {
|
|
2609
|
+
warnings.push(
|
|
2610
|
+
`${t.id} is placed but its diverging route goes nowhere, so it is not in the operations view`
|
|
2611
|
+
);
|
|
2612
|
+
continue;
|
|
2613
|
+
}
|
|
2614
|
+
const piece = pieceById.get(t.id);
|
|
2615
|
+
const part = piece ? library.find((p) => p.id === piece.partId) : void 0;
|
|
2616
|
+
turnouts.push({
|
|
2617
|
+
id: t.id,
|
|
2618
|
+
pos: round(t.pos),
|
|
2619
|
+
onTrack: trackIdOf.get(t.onRoute) ?? MAIN_TRACK_ID,
|
|
2620
|
+
divergeTrack: diverge,
|
|
2621
|
+
...piece?.name ? { name: piece.name } : {},
|
|
2622
|
+
...part?.frogNumber != null ? { size: part.frogNumber } : {},
|
|
2623
|
+
...part ? { partId: part.id } : {}
|
|
2624
|
+
});
|
|
2625
|
+
}
|
|
2626
|
+
turnouts.sort((a, b) => a.pos - b.pos);
|
|
2627
|
+
const place = (a, what) => {
|
|
2628
|
+
if (!a) return null;
|
|
2629
|
+
const hit = resolveGraphAnchor(a, walk, pieces, library);
|
|
2630
|
+
if (!hit) {
|
|
2631
|
+
warnings.push(
|
|
2632
|
+
`${what} is anchored to ${a.piece}, which is not on any route \u2014 its authored position stands`
|
|
2633
|
+
);
|
|
2634
|
+
return null;
|
|
2635
|
+
}
|
|
2636
|
+
return hit;
|
|
2637
|
+
};
|
|
2638
|
+
const spanAt = (hit, from, to) => {
|
|
2639
|
+
const len = Math.abs(to - from);
|
|
2640
|
+
return hit.reversed ? [round(hit.pos - len), round(hit.pos)] : [round(hit.pos), round(hit.pos + len)];
|
|
2641
|
+
};
|
|
2642
|
+
const industries = base.industries?.map((ind) => {
|
|
2643
|
+
const hit = place(ind.anchor, `industry "${ind.name}"`);
|
|
2644
|
+
const spots = ind.spots?.map((s) => {
|
|
2645
|
+
const sh = place(s.anchor, `a spot of industry "${ind.name}"`);
|
|
2646
|
+
if (!sh) return s;
|
|
2647
|
+
const [from, to] = spanAt(sh, s.fromPos, s.toPos);
|
|
2648
|
+
return { ...s, track: trackIdOf.get(sh.routeId) ?? s.track, fromPos: from, toPos: to };
|
|
2649
|
+
});
|
|
2650
|
+
if (!hit) return spots ? { ...ind, spots } : ind;
|
|
2651
|
+
const [fromPos, toPos] = spanAt(hit, ind.fromPos, ind.toPos);
|
|
2652
|
+
return {
|
|
2653
|
+
...ind,
|
|
2654
|
+
track: trackIdOf.get(hit.routeId) ?? ind.track,
|
|
2655
|
+
fromPos,
|
|
2656
|
+
toPos,
|
|
2657
|
+
...spots ? { spots } : {}
|
|
2658
|
+
};
|
|
2659
|
+
});
|
|
2660
|
+
const signals = base.signals?.map((sig) => {
|
|
2661
|
+
const hit = place(sig.anchor, `signal "${sig.name ?? sig.id}"`);
|
|
2662
|
+
return hit ? { ...sig, pos: round(hit.pos), track: trackIdOf.get(hit.routeId) ?? sig.track } : sig;
|
|
2663
|
+
});
|
|
2664
|
+
const doc = {
|
|
2665
|
+
version: 1,
|
|
2666
|
+
...base,
|
|
2667
|
+
lengthInches,
|
|
2668
|
+
endplates,
|
|
2669
|
+
tracks,
|
|
2670
|
+
turnouts,
|
|
2671
|
+
...industries ? { industries } : {},
|
|
2672
|
+
...signals ? { signals } : {}
|
|
2673
|
+
};
|
|
2674
|
+
return { doc, graph, walk, warnings };
|
|
2675
|
+
}
|
|
2676
|
+
function deriveGraphDoc(doc, library = BUILT_IN_TRACK_PARTS) {
|
|
2677
|
+
const g = doc.graph;
|
|
2678
|
+
if (!g || !g.pieces?.length || !g.startAt) return { doc, warnings: [] };
|
|
2679
|
+
const meta = {};
|
|
2680
|
+
for (const t of doc.tracks ?? []) {
|
|
2681
|
+
if (t.role === "main") continue;
|
|
2682
|
+
meta[t.id] = {
|
|
2683
|
+
...t.trackName ? { trackName: t.trackName } : {},
|
|
2684
|
+
...t.capacityFeet != null ? { capacityFeet: t.capacityFeet } : {},
|
|
2685
|
+
...t.moduleTrackId != null ? { moduleTrackId: t.moduleTrackId } : {}
|
|
2686
|
+
};
|
|
2687
|
+
}
|
|
2688
|
+
const out = graphToDoc(g.pieces, { startAt: g.startAt, base: doc, meta, library });
|
|
2689
|
+
return { doc: out.doc, warnings: out.warnings };
|
|
2690
|
+
}
|
|
2437
2691
|
function frogCasting(cl, opts = {}) {
|
|
2438
2692
|
const g = opts.gaugeInches ?? RAIL_GAUGE_INCHES;
|
|
2439
2693
|
const w = opts.reachInches ?? g * 1.5;
|
|
@@ -3067,6 +3321,6 @@ function poseOverridesFromDoc(doc) {
|
|
|
3067
3321
|
return out;
|
|
3068
3322
|
}
|
|
3069
3323
|
|
|
3070
|
-
export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, CLEARANCE_SPACING_INCHES, CODE55_RAIL_HEIGHT_INCHES, DEFAULT_FLEX_PART_ID, ENDPLATE_FASCIA_CLEAR_INCHES, ENDPLATE_LEAD_INCHES, FAST_TRACKS_N_ME55, FAST_TRACKS_N_ME55_CROSSOVERS, FLEX_TRACK_PARTS, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_TRACK_SPACING_INCHES, JOINT_SNAP_INCHES, MAIN2_TRACK_ID, MAIN_TRACK_ID, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, PINCH_EASE_INCHES, RAIL_GAUGE_INCHES, TIE_HALF_LENGTH_INCHES, TURNOUT_LEAD_INCHES_PER_FROG, WHOLE_MODULE_SECTION_ID, asModuleSchematic, assessSectionEnd, assessSectionJoint, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTrackGraph, buildTransition, carCapacity, checkEndplateWidth, clearancePointPastFrogInches, crossoverPinches, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateCentreOffsetInches, endplateEdgePose, endplateFaceSegments, endplateLead, endplateTrackOffsetInches, endplateWidthInches, flexPartFor, flexParts, flexPieces, flexUsage, frogCasting, frogNumberFromName, fromSectionRelative, geometryTurnDegrees, hasNoFarEndplate, importedPartToTrackPart, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, laneOffsetAt, leadInchesForSize, maxFlexPieceInches, mergeImportedParts, mergeStoredParts, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partExtent, partExtentForSize, partGeometry, partGeometryGap, partOutlineAtFrog, partsPlaceable, pastFrogInchesForSize, pathLengthInches, placedJoints, poseNeedsManual, poseOverridesFromDoc, remapPos, resizeFlexPiece, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionedCenterline, sectionedEndPose, sliceCenterline, spanOverhang, stateToDoc, storedPartToTrackPart, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutFacing, turnoutOccupiedSpan, turnoutPartForSize, usableCapacity, walkTrackGraph };
|
|
3324
|
+
export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, CLEARANCE_SPACING_INCHES, CODE55_RAIL_HEIGHT_INCHES, DEFAULT_FLEX_PART_ID, ENDPLATE_FASCIA_CLEAR_INCHES, ENDPLATE_LEAD_INCHES, FAST_TRACKS_N_ME55, FAST_TRACKS_N_ME55_CROSSOVERS, FLEX_TRACK_PARTS, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_TRACK_SPACING_INCHES, JOINT_SNAP_INCHES, MAIN2_TRACK_ID, MAIN_TRACK_ID, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, PINCH_EASE_INCHES, RAIL_GAUGE_INCHES, TIE_HALF_LENGTH_INCHES, TURNOUT_LEAD_INCHES_PER_FROG, WHOLE_MODULE_SECTION_ID, asModuleSchematic, assessSectionEnd, assessSectionJoint, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTrackGraph, buildTransition, carCapacity, checkEndplateWidth, clearancePointPastFrogInches, crossoverPinches, deriveEndplatePoses, deriveGraphDoc, divergeSideForHand, docToState, emptyEditorState, endplateCentreOffsetInches, endplateEdgePose, endplateFaceSegments, endplateLead, endplateTrackOffsetInches, endplateWidthInches, flexPartFor, flexParts, flexPieces, flexUsage, frogCasting, frogNumberFromName, fromSectionRelative, geometryTurnDegrees, graphToDoc, hasNoFarEndplate, importedPartToTrackPart, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, laneOffsetAt, leadInchesForSize, maxFlexPieceInches, mergeImportedParts, mergeStoredParts, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partExtent, partExtentForSize, partGeometry, partGeometryGap, partOutlineAtFrog, partsPlaceable, pastFrogInchesForSize, pathLengthInches, pieceRoutePaths, placedJoints, poseNeedsManual, poseOverridesFromDoc, remapPos, resizeFlexPiece, resolveGraphAnchor, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionedCenterline, sectionedEndPose, sliceCenterline, snapPiece, spanOverhang, stateToDoc, storedPartToTrackPart, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutFacing, turnoutOccupiedSpan, turnoutPartForSize, usableCapacity, walkTrackGraph };
|
|
3071
3325
|
//# sourceMappingURL=index.js.map
|
|
3072
3326
|
//# sourceMappingURL=index.js.map
|