@mark1russell7/highways 0.3.0 → 0.4.1

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.
Files changed (43) hide show
  1. package/README.md +66 -2
  2. package/build/index.d.ts +1009 -12
  3. package/build/index.d.ts.map +1 -1
  4. package/build/index.js +4408 -195
  5. package/build/index.js.map +1 -1
  6. package/package.json +4 -1
  7. package/src/bench/compare.ts +41 -6
  8. package/src/bench/measures/bundles.ts +101 -2
  9. package/src/bench/measures/index.ts +1 -0
  10. package/src/bench/measures/order.ts +97 -0
  11. package/src/bench/room.ts +126 -9
  12. package/src/bench/screen/forms.ts +372 -0
  13. package/src/bench/screen/generators.ts +54 -0
  14. package/src/bench/screen/hash.ts +129 -0
  15. package/src/bench/screen/index.ts +6 -0
  16. package/src/bench/screen/measures.ts +126 -0
  17. package/src/bench/screen/screen.ts +454 -0
  18. package/src/bench/screen/set.ts +136 -0
  19. package/src/bench/suite.ts +71 -13
  20. package/src/highways/corridors/index.ts +305 -0
  21. package/src/highways/follow.ts +155 -0
  22. package/src/highways/index.ts +7 -0
  23. package/src/highways/keys/index.ts +15 -0
  24. package/src/highways/model.ts +111 -0
  25. package/src/highways/result.ts +34 -0
  26. package/src/highways/router.ts +40 -0
  27. package/src/highways/shared-ways/index.ts +15 -0
  28. package/src/index.ts +4 -0
  29. package/src/order/index.ts +65 -0
  30. package/src/plugs/justify.ts +48 -0
  31. package/src/plugs/side.ts +138 -0
  32. package/src/repair/index.ts +377 -0
  33. package/src/repair/walk.ts +220 -0
  34. package/src/room/lanes.ts +109 -10
  35. package/src/routers/corners.ts +73 -6
  36. package/src/routers/fan.ts +145 -0
  37. package/src/routers/index.ts +2 -2
  38. package/src/routers/shared.ts +107 -8
  39. package/src/routers/snell.ts +140 -0
  40. package/src/routers/trunks.ts +43 -2
  41. package/src/strategies/builtins.ts +82 -6
  42. package/src/strategies/model.ts +36 -6
  43. package/src/strategies/schemas.ts +66 -2
package/build/index.d.ts CHANGED
@@ -983,12 +983,24 @@ export declare const straightRouter: Router;
983
983
  * It goes to the target plug on the curve of the rule. This router measures the rule alone.
984
984
  */
985
985
  export declare const plugsRouter: Router;
986
+ /** The ways to place a free plug of the corner router. */
987
+ type PlugPlace = "facing" | "side";
986
988
  /** The options of the corner router. */
987
989
  interface CornersOptions extends WayOptions {
988
990
  /** The name in the benchmark. */
989
991
  readonly name: string;
990
992
  /** The benchmark skips a fixture with more nodes. */
991
993
  readonly maxNodes?: number;
994
+ /**
995
+ * The place of a free plug. The default is `facing`: the plug faces the other end (`placePlug`).
996
+ * With `side`, the search starts from the whole free side, and the plug goes where the way leaves the side (`sidePlugs`, WILD-001).
997
+ */
998
+ readonly plugs?: PlugPlace;
999
+ /**
1000
+ * The least gap between two free plugs of one side. The default is 0: each plug stays where it is.
1001
+ * Above 0, the free plugs of each side keep their order and move the least distance (`justifyPlugs`, WILD-002).
1002
+ */
1003
+ readonly plugGap?: number;
992
1004
  }
993
1005
  /**
994
1006
  * This function makes a router that goes around the nodes.
@@ -996,6 +1008,12 @@ interface CornersOptions extends WayOptions {
996
1008
  * of the box corners, without the needless corners. It enters the target plug along its normal.
997
1009
  */
998
1010
  export declare function cornersRouter(options: CornersOptions): Router;
1011
+ /** The cost of a link that edges of one key share: a fixed discount, or the flow cost `len * f^alpha` (EDA-029). */
1012
+ type ShareCost = "fixed" | "flow";
1013
+ /** The order of the edges of one key: the longest first, the shortest first, the most load first, or the order of the input (NAT-024). */
1014
+ type ShareOrder = "span" | "shortest" | "load" | "input";
1015
+ /** The place where a route joins or leaves a run: at a corner of the graph, or at the Snell angle (NAT-035). */
1016
+ type ShareMerge = "corner" | "snell";
999
1017
  /** The options of the router with shared ways. */
1000
1018
  interface SharedOptions extends WayOptions {
1001
1019
  /** The name in the benchmark. */
@@ -1006,6 +1024,25 @@ interface SharedOptions extends WayOptions {
1006
1024
  readonly discount?: number;
1007
1025
  /** The lane order of the runs. With `bundle`, the default, two edges keep one order on each run of their common stretch. With `run`, each run gets its order alone. */
1008
1026
  readonly laneOrder?: RunOrder;
1027
+ /**
1028
+ * The cost of a shared link. With `fixed`, the default, a link that the key uses already costs `discount` times its length.
1029
+ * With `flow`, one more edge on a link with `f` edges costs `len * ((f + 1)^alpha - f^alpha)` (EDA-029).
1030
+ */
1031
+ readonly cost?: ShareCost;
1032
+ /** The exponent of the flow cost, from 0.1 to 1. A smaller value gives more sharing. The default is 0.6. Only the cost `flow` uses it. */
1033
+ readonly alpha?: number;
1034
+ /** The number of passes. In each pass after the first, each edge leaves its links and finds its way again with the others fixed (HWY-039). The default is 1. */
1035
+ readonly passes?: number;
1036
+ /**
1037
+ * The order of the edges of one key. With `span`, the default, the longest edge goes first. With `shortest`, the shortest edge goes first.
1038
+ * With `load`, the edge with the most edges between its two sections goes first. With `input`, the edges keep the order of the graph (NAT-024).
1039
+ */
1040
+ readonly order?: ShareOrder;
1041
+ /**
1042
+ * The place where a route joins or leaves a run. With `corner`, the default, it is a corner of the graph.
1043
+ * With `snell`, the route meets the run at the angle `acos(d)`, with `d` the cost share of the run for the route (NAT-035).
1044
+ */
1045
+ readonly merge?: ShareMerge;
1009
1046
  /** The benchmark skips a fixture with more nodes. */
1010
1047
  readonly maxNodes?: number;
1011
1048
  }
@@ -1038,6 +1075,64 @@ interface LevelLinkOptions extends WayOptions {
1038
1075
  */
1039
1076
  readonly throughCost?: number;
1040
1077
  }
1078
+ /** The input of a highway strategy: the boxes and the edges, and optionally the first routes of a router. */
1079
+ interface HighwayInput {
1080
+ readonly graph: Graph;
1081
+ /**
1082
+ * These routes are the first routes, from a router. A strategy that reads first routes makes them itself when this value is absent.
1083
+ * The strategy `corridors` makes the ways of the corner graph, as the router `corners` finds them.
1084
+ */
1085
+ readonly routes?: Result;
1086
+ }
1087
+ /**
1088
+ * One edge of a highway. The edge joins the spine at the merge point and leaves it at the split point.
1089
+ * A place on the spine is the index of a point of the spine plus the share of the next leg. Point `i` of the spine is at `i`.
1090
+ * When `on` is larger than `off`, the edge goes along the spine from its last point to its first point.
1091
+ */
1092
+ interface HighwayMember {
1093
+ readonly edge: string;
1094
+ /** The place of the merge point on the spine. */
1095
+ readonly on: number;
1096
+ /** The place of the split point on the spine. */
1097
+ readonly off: number;
1098
+ /** The point where the edge joins the spine. */
1099
+ readonly merge: Point;
1100
+ /** The point where the edge leaves the spine. */
1101
+ readonly split: Point;
1102
+ /**
1103
+ * The place of this highway in the trip of the edge, from 0. An edge can go along several highways, one after the other.
1104
+ * `follow` takes the highways of an edge in the order of this value.
1105
+ */
1106
+ readonly seq: number;
1107
+ }
1108
+ /** A highway: a shared way that a bundle of edges follows, from their merge points to their split points. */
1109
+ interface Highway {
1110
+ readonly id: string;
1111
+ /** The key of the highway, for example the key of the grouping rule or the index of a cluster. */
1112
+ readonly key: string;
1113
+ /** The spine: the polyline that the edges follow, in free space. */
1114
+ readonly spine: readonly Point[];
1115
+ /** The edges in lane order. Lane 0 is on the left of the spine, from its first point to its last point. The y axis points down. */
1116
+ readonly lanes: readonly string[];
1117
+ /** The edges with their merge points and their split points, in the order of `lanes`. */
1118
+ readonly members: readonly HighwayMember[];
1119
+ }
1120
+ /** The output of a highway strategy: the highways, as data. `follow` routes the edges along them. */
1121
+ interface HighwayPlan {
1122
+ readonly highways: readonly Highway[];
1123
+ }
1124
+ /** This function gives the point at a place on a polyline. A place outside the polyline gives its nearest end. */
1125
+ export declare function pointAt(line: readonly Point[], at: number): Point;
1126
+ /** This function gives the length of a polyline from the place `from` to the place `to`, with `from` not larger than `to`. */
1127
+ export declare function lengthBetween(line: readonly Point[], from: number, to: number): number;
1128
+ /** This function gives a member of a highway with its merge point and its split point at the places `on` and `off` of the spine. */
1129
+ export declare function memberAt(spine: readonly Point[], edge: string, on: number, off: number, seq?: number): HighwayMember;
1130
+ /**
1131
+ * This function lists the problems of a plan against its graph. A good plan gives an empty list.
1132
+ * Each highway has a spine of two points or more, and two members or more. Each member is an edge of the graph, with `on` and `off` on the spine and apart.
1133
+ * An edge is a member of a highway one time at most.
1134
+ */
1135
+ export declare function checkPlan(graph: Graph, plan: HighwayPlan): string[];
1041
1136
  /**
1042
1137
  * The options of the room for the bends of the bundles (HWC-D). With them, `roomDemand` also opens the gaps where a bundle bends.
1043
1138
  * The values agree with the options of `highwayCurves` that draw the bundles.
@@ -1296,6 +1391,25 @@ export interface CurveInput {
1296
1391
  readonly endNormal?: Point;
1297
1392
  /** The boxes that the curve must not go through, from `curveSpace`. */
1298
1393
  readonly space?: CurveSpace;
1394
+ /**
1395
+ * The lane of the polyline on its board, for a strategy that bends the lanes of a bundle as one. Then `points` is the route of `laneRoutes` with the index `index`.
1396
+ * The other strategies do not read it.
1397
+ */
1398
+ readonly lane?: {
1399
+ readonly board: LaneBoard;
1400
+ readonly index: number;
1401
+ };
1402
+ }
1403
+ /** The lanes of the bundles of one board: the input of `laneRoutes` and `highwayCurves`. */
1404
+ export interface LaneBoard {
1405
+ /** The shared segments and the paths of the routes, from `segmentsOf`. */
1406
+ readonly graph: SegmentGraph;
1407
+ /** The keys of the open segments, from `runKey`. Each edge of an open segment gets its own lane. */
1408
+ readonly open: ReadonlySet<string>;
1409
+ /** The distance between two lanes of an open segment. */
1410
+ readonly width: number;
1411
+ /** The largest width of an open segment, from its outer lane to its outer lane. The default is `Infinity`. */
1412
+ readonly maxWidth?: number;
1299
1413
  }
1300
1414
  /** The input of a room strategy: the boxes of a board and the links between them. */
1301
1415
  export interface RoomInput {
@@ -1312,6 +1426,7 @@ export interface RoomInput {
1312
1426
  *
1313
1427
  * - `group`: a graph in, the tree of sections out. The router `sections` makes its hubs and its zoom levels from this tree.
1314
1428
  * - `router`: a graph in, the routes (and the `levels`, `bundles` and `runs`) out.
1429
+ * - `highway`: a graph and optionally its first routes in, a highway plan out. `follow` routes the edges along the plan.
1315
1430
  * - `curve`: a polyline in, the segments of a curve out.
1316
1431
  * - `room`: the boxes and links of a board in, the gaps of the board with their need out.
1317
1432
  */
@@ -1324,6 +1439,10 @@ export interface StepTypes {
1324
1439
  readonly input: Graph;
1325
1440
  readonly output: Result;
1326
1441
  };
1442
+ readonly highway: {
1443
+ readonly input: HighwayInput;
1444
+ readonly output: HighwayPlan;
1445
+ };
1327
1446
  readonly curve: {
1328
1447
  readonly input: CurveInput;
1329
1448
  readonly output: CurveSegment[];
@@ -1384,10 +1503,11 @@ export declare function defineStrategy<S extends Step, O extends object>(definit
1384
1503
  /**
1385
1504
  * A registry: the strategies of each step, in order. A registry is data. No import changes it.
1386
1505
  * A consumer makes its own registry with `createRegistry`, and adds a strategy with `register`.
1387
- * The list `group` is optional in the type, so a registry from version 0.1.5 stays a registry. `createRegistry` always gives it.
1506
+ * The lists `group` and `highway` are optional in the type, so a registry from version 0.1.5 or 0.3.0 stays a registry. `createRegistry` always gives them.
1388
1507
  */
1389
- export type Registry = { readonly [S in Exclude<Step, "group">]: readonly Strategy<S>[]; } & {
1508
+ export type Registry = { readonly [S in Exclude<Step, "group" | "highway">]: readonly Strategy<S>[]; } & {
1390
1509
  readonly group?: readonly Strategy<"group">[];
1510
+ readonly highway?: readonly Strategy<"highway">[];
1391
1511
  };
1392
1512
  /** This function makes a registry from a list of strategies. It keeps their order. Two strategies with one step and one name are an error. */
1393
1513
  export declare function createRegistry(strategies: readonly AnyStrategy[]): Registry;
@@ -1474,11 +1594,29 @@ interface TrunksOptions extends WayOptions {
1474
1594
  * A lane that turns back over the trunk leaves at an earlier point of the trunk. With `split`, each lane leaves at the split point, as in version 0.2.0.
1475
1595
  */
1476
1596
  readonly leave?: TrunkLeave;
1597
+ /**
1598
+ * The place of the split point. With `share`, the default, it is at `split` of the way to the center of the targets.
1599
+ * With `gilbert`, it is where the flow cost of the trunk and its branches is least, with the exponent `alpha` (EDA-030).
1600
+ */
1601
+ readonly splitAt?: TrunkSplit;
1602
+ /** The exponent of the flow cost of the split `gilbert`, from 0 to 1. The default is 0.5. */
1603
+ readonly alpha?: number;
1604
+ /**
1605
+ * The shape of each group. With `split`, the default, the edges share a trunk to a split point.
1606
+ * With `tree`, the edges grow a balancing-factor tree from the plug, with the factor `bf` (NAT-017).
1607
+ */
1608
+ readonly fan?: TrunkFan;
1609
+ /** The balancing factor of the fan `tree`, from 0 to 1. 0 gives the least ink, and a larger factor gives more direct routes. The default is 0.4. */
1610
+ readonly bf?: number;
1477
1611
  /** The benchmark skips a fixture with more nodes. */
1478
1612
  readonly maxNodes?: number;
1479
1613
  }
1480
1614
  /** The place where the lanes of a trunk leave it: where their ways part, or at the split point. */
1481
1615
  type TrunkLeave = "part" | "split";
1616
+ /** The place of the split point of a trunk: at a share of the way, or at the Gilbert point of the flow cost (EDA-030). */
1617
+ type TrunkSplit = "share" | "gilbert";
1618
+ /** The shape of a group of the router `trunks`: a trunk and a split point, or a balancing-factor tree (NAT-017). */
1619
+ type TrunkFan = "split" | "tree";
1482
1620
  /** The rule that groups the edges by the collection of their target, in `data.collection`. */
1483
1621
  export declare const byCollection: GroupRule;
1484
1622
  /**
@@ -1517,6 +1655,17 @@ export declare const ROUTERS: readonly Router[];
1517
1655
  export type LaneOrder = "links" | "ends" | "crossings";
1518
1656
  /** The lane orders of `gapLanes`, in the order of the benchmark. */
1519
1657
  export declare const LANE_ORDERS: readonly LaneOrder[];
1658
+ /**
1659
+ * The rule that gives each piece of a gap its lane (its track), after the lane order.
1660
+ *
1661
+ * - `stack`: a piece goes one lane past each piece before it in the order that it overlaps. Thus two pieces that overlap keep their order.
1662
+ * - `left-edge`: the constrained left-edge rule of chip routing (EDA-004). Two pieces that overlap keep their order only where a swap adds crossings.
1663
+ * The rule fills the lowest lane first, with the pieces sorted by their start. Two pieces that do not overlap can share a lane.
1664
+ * - `free`: the left-edge rule without the order. It gives the fewest lanes, but it can add crossings.
1665
+ */
1666
+ export type LaneTracks = "stack" | "left-edge" | "free";
1667
+ /** The lane rules of `gapLanes`, in the order of the benchmark. */
1668
+ export declare const LANE_TRACKS: readonly LaneTracks[];
1520
1669
  /** The options of `gapLanes`. */
1521
1670
  export interface GapLaneOptions {
1522
1671
  /** The largest distance between two lanes. A narrow gap puts its lanes nearer. The default is 4. */
@@ -1525,6 +1674,21 @@ export interface GapLaneOptions {
1525
1674
  readonly order?: LaneOrder;
1526
1675
  /** Two box edges nearer than this distance make one boundary of the sweep, as in `boardGaps`. The default is 0.5. */
1527
1676
  readonly snap?: number;
1677
+ /** The rule that gives each piece its lane. The default is `stack`. */
1678
+ readonly tracks?: LaneTracks;
1679
+ }
1680
+ /** The lanes of one gap: the axis and the place of the gap, and the number of lanes that its pieces use. */
1681
+ export interface GapLaneCount {
1682
+ readonly axis: "x" | "y";
1683
+ readonly at: number;
1684
+ /** The width of the gap. */
1685
+ readonly width: number;
1686
+ /** The number of lanes of the gap. */
1687
+ readonly lanes: number;
1688
+ /** The number of pieces in the gap: the legs of the links that run along it. */
1689
+ readonly pieces: number;
1690
+ /** The largest number of pieces that overlap at one place of the gap. No rule gives fewer lanes. */
1691
+ readonly density: number;
1528
1692
  }
1529
1693
  /**
1530
1694
  * This function gives each link that runs along a gap its own lane in the gap. The lanes of a gap are `spacing` apart, around its middle line.
@@ -1532,6 +1696,8 @@ export interface GapLaneOptions {
1532
1696
  * When a move puts a link through more boxes than before, the link keeps its points.
1533
1697
  */
1534
1698
  export declare function gapLanes(items: readonly Boxed[], links: readonly LevelLink[], options?: GapLaneOptions): LevelLink[];
1699
+ /** This function gives the lanes of each gap that holds a piece of a link, with the options of `gapLanes`. A gap without a piece is not in the list. */
1700
+ export declare function gapLaneCounts(items: readonly Boxed[], links: readonly LevelLink[], options?: GapLaneOptions): GapLaneCount[];
1535
1701
  /**
1536
1702
  * The boards of the zoom levels of `levelRoom`.
1537
1703
  *
@@ -2108,6 +2274,42 @@ export interface BendRoomRow extends HighwayMeasures {
2108
2274
  export declare function benchBendRoom(router: Router, fixture: string, graph: Graph, options?: RoomOptions): BendRoomRow[];
2109
2275
  /** This function writes the rows of `benchBendRoom` as a Markdown table. The spacing error is a percent of the spacing. */
2110
2276
  export declare function formatBendRoom(rows: readonly BendRoomRow[]): string;
2277
+ /** One row of `benchTracks` (EDA-004): the lanes of the far view of one board with one lane rule of `gapLanes`. */
2278
+ export interface TrackBenchRow {
2279
+ readonly fixture: string;
2280
+ /** The board: `given` (the board as it is) or `open` (the board that `makeRoom` opens at gutter 8 and spacing 4). */
2281
+ readonly board: string;
2282
+ readonly tracks: LaneTracks;
2283
+ /** The number of gaps with at least one piece. */
2284
+ readonly gaps: number;
2285
+ /** The sum of the lanes of the gaps. */
2286
+ readonly lanes: number;
2287
+ /** The sum of the densities of the gaps: the most pieces that overlap at one place. No rule gives fewer lanes. */
2288
+ readonly density: number;
2289
+ /** The number of gaps whose lanes are nearer than `spacing`, because the gap is too narrow for its lanes. */
2290
+ readonly squeezed: number;
2291
+ /** The crossings of the links of the far view (`measureQuality`). */
2292
+ readonly crossings: number;
2293
+ /** The ink of the links of the far view. */
2294
+ readonly ink: number;
2295
+ /** R12: the length of parallel legs of two links nearer than `spacing`, as a share of the ink. */
2296
+ readonly separation: number;
2297
+ /** The number of links of the far view that go through a box. */
2298
+ readonly through: number;
2299
+ }
2300
+ /**
2301
+ * This function gives R12 (lane separation) of the links. Two legs of two links are near when they are parallel and nearer than `near`.
2302
+ * R12 is the length of the near legs, as a share of the ink.
2303
+ * It reads only the legs on an axis. The links of the far view have no other legs.
2304
+ */
2305
+ export declare function laneSeparation(links: readonly LevelLink[], near: number): number;
2306
+ /**
2307
+ * This function measures each lane rule of `gapLanes` (EDA-004) on the board as it is, and on the board that `makeRoom` opens.
2308
+ * The lane order is `crossings` for each rule. The lanes are `spacing` apart where the gap has room.
2309
+ */
2310
+ export declare function benchTracks(fixture: string, graph: Graph, spacing?: number, rules?: readonly LaneTracks[]): TrackBenchRow[];
2311
+ /** This function writes the rows of `benchTracks` as a Markdown table. */
2312
+ export declare function formatTracks(rows: readonly TrackBenchRow[]): string;
2111
2313
  /** The options of one setting of the router `sections`, without the name. */
2112
2314
  export type SectionsSettingOptions = Omit<SectionsOptions, "name" | "maxNodes">;
2113
2315
  /** One setting of a sweep of the router `sections`. */
@@ -2294,6 +2496,34 @@ export interface AmbiguityOptions {
2294
2496
  * `amb = Σ_v count(w in N(v) : no edge v-w) / Σ_v count(N(v))`. The cost is quadratic, so a seeded sample serves above `exact` nodes.
2295
2497
  */
2296
2498
  export declare function ambiguity(graph: Graph, routes: readonly Route[], options?: AmbiguityOptions): Ambiguity;
2499
+ /**
2500
+ * This function gives the bundled share of a result (B2 of MEAS0): `count(e : e is in a run or a bundle) / m`.
2501
+ * An edge is also in a bundle when its route shares a drawn segment with the route of another edge. Thus a router without `runs` and `bundles` gets a value too.
2502
+ * The scale is 0 to 1. A higher value is better only in context. The cost is linear.
2503
+ */
2504
+ export declare function bundledShare(result: Result): number;
2505
+ /** The bundle stretch of the routes against base routes (B3 of MEAS0). */
2506
+ export interface BundleStretch {
2507
+ /** The median of `st(e) = L(r_e) / L(r*_e)`. A value of 1 is the length of the base route. Lower is better. */
2508
+ readonly median: number;
2509
+ /** The `0.95` quantile of `st(e)`: the tail of long detours that the bundles add. */
2510
+ readonly q95: number;
2511
+ /** The number of edges with a route in both lists and a base route longer than 1 unit. */
2512
+ readonly edges: number;
2513
+ }
2514
+ /**
2515
+ * This function gives the bundle stretch (B3 of MEAS0): `st(e) = L(r_e) / L(r*_e)` for each edge, with `r*_e` the base route of the edge.
2516
+ * The base routes are the routes of `corners` on the same input. An edge without a base route, or with a base route of 1 unit or less, does not count.
2517
+ * The cost is an extra run of the base router, and then linear.
2518
+ */
2519
+ export declare function bundleStretch(routes: readonly Route[], base: readonly Route[]): BundleStretch;
2520
+ /**
2521
+ * This function gives the merge angle of the routes (B6 of MEAS0): the largest turn of a lane where it joins or leaves a run, in degrees.
2522
+ * A run is a drawn segment that the routes of two edges or more share. A route joins or leaves a run at a vertex where the edges on its segment change.
2523
+ * One of the two segments at that vertex has two edges or more. The turn is the angle between the two segments.
2524
+ * Routes without a shared segment give 0. The scale is 0 to 180 degrees, and lower is better. The cost is linear.
2525
+ */
2526
+ export declare function mergeAngle(routes: readonly Route[]): number;
2297
2527
  /** A joint of a curve: the end of one drawn segment and the start of the next drawn segment. */
2298
2528
  export interface CurveJoint {
2299
2529
  readonly at: Point;
@@ -2475,6 +2705,43 @@ export declare function dominates(a: Readonly<Record<string, number>>, b: Readon
2475
2705
  * The function `values` gives the measures of an item. The front keeps the order of the list. The cost is quadratic in the items.
2476
2706
  */
2477
2707
  export declare function paretoFront<T>(items: readonly T[], values: (item: T) => Readonly<Record<string, number>>, objectives: readonly Objective[]): T[];
2708
+ /** The order fragility of a router on one graph (W3 of MEAS3, from WILD-056). */
2709
+ export interface OrderFragility {
2710
+ /** The number of random orders. */
2711
+ readonly orders: number;
2712
+ /** `IQR / median` of the crossings (R1) over the orders. A value of 0 is a router that the order does not move. */
2713
+ readonly crossings: number;
2714
+ /** `IQR / median` of the median detour (R5) over the orders. */
2715
+ readonly detour: number;
2716
+ /** `IQR / median` of the ink saved (B1) over the orders. */
2717
+ readonly inkSaved: number;
2718
+ /** `IQR / median` of the ink over the orders. */
2719
+ readonly ink: number;
2720
+ /** The share of the orders whose routes differ from the routes of the input order. A value of 0 is a router that is free of the order. */
2721
+ readonly changed: number;
2722
+ /**
2723
+ * The crossings of the input order divided by the fewest crossings over the orders (the price of anarchy of WILD-056).
2724
+ * A value of 1 is a default order as good as the best random order. It is `NaN` when the best order has 0 crossings and the input order has more.
2725
+ */
2726
+ readonly poa: number;
2727
+ }
2728
+ /** The options of `orderFragility`. */
2729
+ export interface OrderFragilityOptions {
2730
+ /** The number of random orders of the edges. The default is 20. */
2731
+ readonly orders?: number;
2732
+ /** The seed of the first order. The order `k` has the seed `seed + k`. The default is 1. */
2733
+ readonly seed?: number;
2734
+ /** The result of the input order, when the caller has it. Without it, the function routes the input order one time more. */
2735
+ readonly base?: Result;
2736
+ }
2737
+ /**
2738
+ * This function measures the order fragility of a router on one graph (W3, from WILD-056).
2739
+ * It routes the graph with `orders` random orders of the edges.
2740
+ * It gives the spread `IQR / median` of the crossings, the detour, the ink saved and the ink.
2741
+ * It also gives the share of orders that change a route, and the price of anarchy of the crossings.
2742
+ * The cost is `orders` extra runs of the router.
2743
+ */
2744
+ export declare function orderFragility(graph: Graph, route: (graph: Graph) => Result, options?: OrderFragilityOptions): OrderFragility;
2478
2745
  /** The names of the proposed hard rules of MEAS0. The suite counts them. It does not apply them as rules yet. */
2479
2746
  export declare const PROPOSED_RULES: readonly string[];
2480
2747
  /** The options of `runSuite`. */
@@ -2615,6 +2882,11 @@ export interface CurveRunOptions {
2615
2882
  readonly normals: ReadonlySet<string>;
2616
2883
  /** The options of each curve strategy, by its name. A strategy without an entry gets its defaults. */
2617
2884
  readonly curveOptions?: Readonly<Record<string, object>>;
2885
+ /**
2886
+ * With this board, each curve draws the lanes of `laneRoutes` in place of the routes of the result, and each input has its `lane`.
2887
+ * So the curve `highway` bends the lanes of a bundle as one. Without it, each curve draws the routes of the result.
2888
+ */
2889
+ readonly lanes?: LaneBoard;
2618
2890
  }
2619
2891
  /** One curve strategy on the routes of one result: the row of the suite and the drawn curves. */
2620
2892
  export interface CurveRun {
@@ -2645,8 +2917,8 @@ export declare function groupRun(graph: Graph, strategy: Strategy<"group">, opti
2645
2917
  readonly seed: number;
2646
2918
  }): GroupRun;
2647
2919
  /**
2648
- * This function gives the options of a grouping rule on a fixture. The rule `keys` gets a key from the data of the edges:
2649
- * the collection of the first edge into the node. A node without such an edge is a group alone.
2920
+ * This function gives the options of a grouping rule on a fixture. The rule `keys` gets the string `data.group` of the node.
2921
+ * A node without it gets a key from the data of the edges: the collection of the first edge into the node. A node without such an edge is a group alone.
2650
2922
  */
2651
2923
  export declare function fixtureGroupOptions(strategy: string, graph: Graph): object;
2652
2924
  /**
@@ -2659,7 +2931,7 @@ export declare function runSuite(options?: SuiteOptions): {
2659
2931
  };
2660
2932
  /**
2661
2933
  * This function puts the rows of the suite in the order of one run. It sorts them by fixture family, then by seed.
2662
- * In one seed, the routers come first, and the curves come after the router of the curves. The grouping rules and the room come last.
2934
+ * In one seed, the routers come first, and the curves come after the router of the curves. Then the highway strategies come, and the grouping rules and the room come last.
2663
2935
  * A name that is not in its list goes after the names of the list.
2664
2936
  * The workflow `Bench` uses it to join the reports of its parts.
2665
2937
  */
@@ -2703,6 +2975,58 @@ export declare function formatRules(rules: readonly RuleCount[]): string;
2703
2975
  * It gives one row for each fixture family of a step. The extra routes of the stability measures have their own column.
2704
2976
  */
2705
2977
  export declare function formatMeasureTime(rows: readonly SuiteRow[], step?: Step): string;
2978
+ /**
2979
+ * The options of the highway strategy `corridors` (HWY-031 of the note on highways).
2980
+ * The options `margin` and `k` set the corner graph of the first ways, when the input has no first routes.
2981
+ */
2982
+ interface CorridorOptions extends Pick<WayOptions, "margin" | "k"> {
2983
+ /** Two edges join when their common links are this share of the shorter way, or longer. The default is 0.3. */
2984
+ readonly rho: number;
2985
+ /** A highway has this number of edges or more. The default is 2. */
2986
+ readonly minSize: number;
2987
+ /** The number of hash functions of the MinHash signature of a way. The default is 64. */
2988
+ readonly hashes: number;
2989
+ /** The number of bands of the signature. Two ways with one equal band are a candidate pair. The default is 32. */
2990
+ readonly bands: number;
2991
+ /** Two link ends nearer than this grid size are one point. With 0, the default, only equal points are one point. */
2992
+ readonly near: number;
2993
+ /** The gap between two lanes. Two edges join only when their common links are longer than the break-even overlap for this gap. The default is 4. */
2994
+ readonly lane: number;
2995
+ }
2996
+ /** The default options of the strategy `corridors`. */
2997
+ export declare const CORRIDOR_DEFAULTS: Readonly<Required<Omit<CorridorOptions, "margin" | "k">>>;
2998
+ /**
2999
+ * The break-even overlap of two parallel edges for each unit of the lane gap, with the cost exponent 0.5 of the note.
3000
+ * A shared stretch shorter than this times the gap adds ink.
3001
+ */
3002
+ export declare const BREAK_EVEN: number;
3003
+ /** This function gives the MinHash signature of a set of keys with `count` hash functions. */
3004
+ export declare function minHash(keys: Iterable<string>, count: number): number[];
3005
+ /**
3006
+ * This function gives the highways of corridor signatures (HWY-031). Each edge gets a first way: the route of `input.routes`, or its way through the corner graph.
3007
+ * The signature of a way is the set of its links. Two edges join when their common links are at least `rho` times the shorter way, and longer than the break-even overlap.
3008
+ * MinHash with `hashes` hash functions in `bands` bands finds the candidate pairs fast. Union-find gives the clusters.
3009
+ *
3010
+ * In each cluster, the spine is the longest common run of links of the way with the most shared length. Each edge on the spine joins it at its first common link and leaves it at its last one.
3011
+ * The edges of the cluster that are not on the spine make the next highway, while `minSize` of them remain.
3012
+ */
3013
+ export declare function corridorPlan(input: HighwayInput, o: Readonly<CorridorOptions>): HighwayPlan;
3014
+ /** The options of the highway strategy `keys`: the options of the router `trunks`, without the name and the limit of the benchmark. */
3015
+ type KeysOptions = Omit<TrunksOptions, "name" | "maxNodes">;
3016
+ /**
3017
+ * This function gives the highways that the router `trunks` decides. A rule gives each edge a key.
3018
+ * The edges from one plug with one key share a trunk to a split point. The edges that go on together share a run past it.
3019
+ * Each trunk and each run becomes one highway. The function does not change the router: it reads its bundles and its runs.
3020
+ */
3021
+ export declare function keysPlan(input: HighwayInput, options: KeysOptions): HighwayPlan;
3022
+ /** The options of the highway strategy `shared-ways`: the options of the router `shared`, without the name and the limit of the benchmark. */
3023
+ type SharedWaysOptions = Omit<SharedOptions, "name" | "maxNodes">;
3024
+ /**
3025
+ * This function gives the highways that the router `shared` decides. The edges of one key go one by one through the corner graph.
3026
+ * A link that the key uses already costs less, so the ways of a key come together. Each stretch that two edges or more share becomes one highway.
3027
+ * The function does not change the router: it reads its runs.
3028
+ */
3029
+ export declare function sharedWaysPlan(input: HighwayInput, options: SharedWaysOptions): HighwayPlan;
2706
3030
  /** The options of a router strategy: the options of its router, without the name and the limit of the benchmark. */
2707
3031
  export type RouterPreset<O> = Omit<O, "name" | "maxNodes">;
2708
3032
  /** The built-in router strategies, in the order of the benchmark. They route as the routers of `ROUTERS`. */
@@ -2727,7 +3051,10 @@ export interface TensionOptions {
2727
3051
  /** The tension of the spline, from 0 (the spline) to 1 (the polyline). The default is 0. */
2728
3052
  readonly tension: number;
2729
3053
  }
2730
- /** The options of the curve strategy `highway`. */
3054
+ /**
3055
+ * The options of the curve strategy `highway`. The options `minRadius`, `jog` and `jogPieces` change only the lanes of a bundle.
3056
+ * So they change the curve only when the input has a `lane` on a board with open segments.
3057
+ */
2731
3058
  export interface HighwayStrategyOptions {
2732
3059
  /** The radius of the center line of a bundle at a bend, and of each lone corner. The default is 12. */
2733
3060
  readonly radius: number;
@@ -2756,7 +3083,7 @@ export interface ClothoidStrategyOptions {
2756
3083
  }
2757
3084
  /**
2758
3085
  * The built-in curve strategies. The first six are in the order of `CURVE_TYPES`, and each one gives the same segments as `curveOf` with its type.
2759
- * The strategy `highway` gives the curve of `arc` for one polyline. `highwayCurves` bends the lanes of a bundle as one.
3086
+ * The strategy `highway` gives the curve of `arc` for one polyline. For a polyline with a `lane`, it bends the lanes of each bundle as one with `highwayCurves`.
2760
3087
  */
2761
3088
  export declare const curveStrategies: {
2762
3089
  readonly straight: Strategy<"curve", object>;
@@ -2784,12 +3111,24 @@ export declare const groupStrategies: {
2784
3111
  readonly kd: Strategy<"group", Required<KdOptions>>;
2785
3112
  readonly cut: Strategy<"group", Required<CutOptions>>;
2786
3113
  };
3114
+ /**
3115
+ * The built-in highway strategies: the decisions of the routers `trunks` and `shared` as plans, and corridor signatures (HWY-031).
3116
+ * `follow` routes the edges along a plan, and `highwayRouter` gives a router that does both.
3117
+ */
3118
+ export declare const highwayStrategies: {
3119
+ readonly keys: Strategy<"highway", KeysOptions>;
3120
+ readonly "shared-ways": Strategy<"highway", SharedWaysOptions>;
3121
+ readonly corridors: Strategy<"highway", CorridorOptions>;
3122
+ };
2787
3123
  /** The built-in strategies of each step, in order. A consumer adds its own: `createRegistry([...BUILT_IN_STRATEGIES, mine])`. */
2788
3124
  export declare const BUILT_IN_STRATEGIES: readonly AnyStrategy[];
2789
3125
  /** The registry of the built-in strategies. The benchmark and the site take their lists from it. */
2790
3126
  export declare const STRATEGIES: Registry;
2791
- /** The steps that `compareStep` compares. The step `room` takes a packed board, not a graph, so it is not in the list. */
2792
- export type CompareStep = Exclude<Step, "room">;
3127
+ /**
3128
+ * The steps that `compareStep` compares. The step `room` takes a packed board, not a graph, so it is not in the list.
3129
+ * The step `highway` gives a plan, not routes. The screen routes each plan with `follow` and compares it as a router.
3130
+ */
3131
+ export type CompareStep = Exclude<Step, "room" | "highway">;
2793
3132
  /** The steps that `compareStep` compares, in the order of the pipeline. */
2794
3133
  export declare const COMPARE_STEPS: readonly CompareStep[];
2795
3134
  /** The options of `compareStep`. */
@@ -2800,6 +3139,14 @@ export interface CompareOptions {
2800
3139
  readonly options?: Readonly<Record<string, object>>;
2801
3140
  /** The router whose routes the step `curve` draws. The default is `corners`, as in `runSuite`. */
2802
3141
  readonly curveRouter?: string;
3142
+ /**
3143
+ * With this value, the step `curve` opens each shared segment of the routes of `curveRouter`, and each curve draws the lanes of `laneRoutes`.
3144
+ * So the curve `highway` bends the lanes of a bundle as one. Without it, each curve draws the routes. A router without shared segments gives the routes in both cases.
3145
+ */
3146
+ readonly lanes?: {
3147
+ readonly width: number;
3148
+ readonly maxWidth?: number;
3149
+ };
2803
3150
  /** The seed of the small change of the graph for the stability measures (Z10 and G9). The default is 1. */
2804
3151
  readonly seed?: number;
2805
3152
  /** The route stability (Z10) routes a changed graph again, so the function measures it only up to this number of nodes. The default is 1000. */
@@ -2815,7 +3162,10 @@ export interface CompareRow {
2815
3162
  readonly violations: number;
2816
3163
  /** The time of the step, in milliseconds. For the step `router`, it is the median of two routes. */
2817
3164
  readonly ms: number;
2818
- /** The measures, by the keys of `runSuite`, and `ms`. The step `router` adds `ink`, and the step `curve` adds `C5.peak`. */
3165
+ /**
3166
+ * The measures, by the keys of `runSuite`, and `ms`. The step `router` adds `ink`, and the step `curve` adds `C5.peak`.
3167
+ * A router with zoom levels also gets `Z3.through` and `Z3.length`, the measures of its level links.
3168
+ */
2819
3169
  readonly values: Readonly<Record<string, number>>;
2820
3170
  /** The reason when the strategy did not run, for example a graph over its `maxNodes`. */
2821
3171
  readonly skipped?: string;
@@ -2842,11 +3192,658 @@ export interface StepComparison {
2842
3192
  }
2843
3193
  /**
2844
3194
  * This function runs each strategy of one step on one graph and measures it with the measures of `runSuite`. Then it gives the Pareto front.
2845
- * The step `router` routes the graph with each router. The step `curve` draws the routes of `curveRouter` with each curve.
3195
+ * The step `router` routes the graph with each router. The step `curve` draws the routes of `curveRouter` with each curve, or their lanes with the option `lanes`.
2846
3196
  * The step `group` routes the graph with `sections` on the tree of each grouping rule.
2847
3197
  *
2848
3198
  * The same graph and the same options give the same measures. Only the times change.
2849
3199
  */
2850
3200
  export declare function compareStep(step: CompareStep, graph: Graph, options?: CompareOptions): StepComparison;
2851
- export type { ArcOptions, ClothoidOptions, CornersOptions, CurveSpace, CutObjective, CutOptions, HighwayOptions, JogStyle, KdAxis, KdLine, KdOptions, KeyOptions, LaneCurve, NodeKey, RoomBends, RoundedOptions, SectionsOptions, SharedOptions, SmoothOptions, SplineOptions, TrunksOptions };
3201
+ /** This function gives the bytes of a string in UTF-8. */
3202
+ export declare function utf8(text: string): Uint8Array;
3203
+ /** This function gives the SHA-256 digest of a string, as 64 lowercase hex characters. It encodes the string in UTF-8. */
3204
+ export declare function sha256Hex(text: string): string;
3205
+ /**
3206
+ * This function writes a value as canonical JSON: the keys of each object in sorted order, and no whitespace.
3207
+ * It drops a key whose value is `undefined`, as `JSON.stringify` does.
3208
+ */
3209
+ export declare function canonicalJson(value: unknown): string;
3210
+ /**
3211
+ * This function gives the hash of a JSON document: the first 16 hex characters of the SHA-256 of its canonical JSON.
3212
+ * The document does not include its own field `hash`. The function removes that field before it calculates the hash.
3213
+ */
3214
+ export declare function documentHash(value: object): string;
3215
+ /** This function gives the 32-bit FNV-1a hash of the UTF-8 bytes of a text, as an unsigned integer. */
3216
+ export declare function fnv1a32(text: string): number;
3217
+ /** This function gives the seed of one step of a generator: `fnv1a32("<seed>:<step>")`. */
3218
+ export declare function stepSeed(seed: number, step: string): number;
3219
+ /** This function gives the generator `mulberry32` for a seed. Each call gives the next number from 0 to below 1. */
3220
+ export declare function mulberry32(seed: number): () => number;
3221
+ /** This function rounds a number to 3 decimals, as the files of a corpus keep it. The value `-0` becomes `0`. */
3222
+ export declare function round3(value: number): number;
3223
+ /** The side of a port in an input file. The router calls the same sides `north`, `east`, `south` and `west`. */
3224
+ export type LayoutSide = "top" | "right" | "bottom" | "left";
3225
+ /** A port of a box in an input file. */
3226
+ export interface LayoutPort {
3227
+ readonly id: string;
3228
+ /** The side of the box. Without it and without `x` and `y`, the router picks the side. */
3229
+ readonly side?: LayoutSide;
3230
+ /** The fixed place of the port, from the top-left corner of the box. The router does not move a port with `x` and `y`. */
3231
+ readonly x?: number;
3232
+ readonly y?: number;
3233
+ }
3234
+ /** A point of a region: `[x, y]`. The y axis points down. */
3235
+ export type RegionPoint = readonly [number, number];
3236
+ /**
3237
+ * An area of the plane. The y axis points down. A ring of a polygon closes itself: its last point joins its first point.
3238
+ * A hole of a polygon does not touch the outer ring. The router reads only the bounding box of a region.
3239
+ */
3240
+ export type Region = {
3241
+ readonly kind: "rect";
3242
+ readonly x: number;
3243
+ readonly y: number;
3244
+ readonly w: number;
3245
+ readonly h: number;
3246
+ } | {
3247
+ readonly kind: "polygon";
3248
+ readonly points: readonly RegionPoint[];
3249
+ readonly holes?: readonly (readonly RegionPoint[])[];
3250
+ } | {
3251
+ readonly kind: "circle";
3252
+ readonly cx: number;
3253
+ readonly cy: number;
3254
+ readonly r: number;
3255
+ } | {
3256
+ readonly kind: "ellipse";
3257
+ readonly cx: number;
3258
+ readonly cy: number;
3259
+ readonly rx: number;
3260
+ readonly ry: number;
3261
+ };
3262
+ /** An area that the boxes and the routes must not use. The router uses the bounding box of its region as a box without edges. */
3263
+ export interface LayoutObstacle {
3264
+ readonly id: string;
3265
+ readonly region: Region;
3266
+ /** The cost to move the obstacle. Only the packer reads it. */
3267
+ readonly move?: {
3268
+ readonly cost: number;
3269
+ };
3270
+ }
3271
+ /** A box of an input file. */
3272
+ export interface LayoutBox {
3273
+ readonly id: string;
3274
+ readonly w: number;
3275
+ readonly h: number;
3276
+ /** The position of the top-left corner. The packer writes it. The router reads it. */
3277
+ readonly x?: number;
3278
+ readonly y?: number;
3279
+ /** The id of the box that holds this box. */
3280
+ readonly parent?: string;
3281
+ /** The group of the box. */
3282
+ readonly group?: string;
3283
+ /** This value is `true` when the box is an obstacle: the packer keeps its `x` and `y`. The router ignores it. */
3284
+ readonly locked?: true;
3285
+ /** The reading order that the caller wants. The router ignores it. */
3286
+ readonly rank?: number;
3287
+ readonly ports?: readonly LayoutPort[];
3288
+ /** The shape of the box, relative to the top-left corner of the box. The router ignores it and uses `w` and `h` as the bounding box. */
3289
+ readonly shape?: Region;
3290
+ /** The free data of the node. The grouping rule `keys` reads `data.group`. */
3291
+ readonly data?: Readonly<Record<string, unknown>>;
3292
+ }
3293
+ /** An edge of an input file. `sourcePort` and `targetPort` name a port of the box at that end. */
3294
+ export interface LayoutEdge {
3295
+ readonly id: string;
3296
+ readonly source: string;
3297
+ readonly target: string;
3298
+ readonly sourcePort?: string;
3299
+ readonly targetPort?: string;
3300
+ readonly data?: Readonly<Record<string, unknown>>;
3301
+ }
3302
+ /** The change of a variant against its base input. */
3303
+ export type LayoutChange = "add" | "remove" | "resize" | "reorder" | "packed";
3304
+ /** The origin of an input: `made-up`, `published:<set>` or `known-best:<construction>`. */
3305
+ export type LayoutSource = "made-up" | `published:${string}` | `known-best:${string}`;
3306
+ /** The generator of an input. The same name, version, parameters and seed give the same file, byte for byte. */
3307
+ export interface LayoutGenerator {
3308
+ readonly name: string;
3309
+ readonly version: number;
3310
+ readonly params: Readonly<Record<string, unknown>>;
3311
+ readonly seed: number;
3312
+ }
3313
+ /**
3314
+ * The cell of an input in the taxonomy of the corpus, with one value for each dimension.
3315
+ * The packer reads the first six dimensions. The router reads the last four.
3316
+ */
3317
+ export interface LayoutCell {
3318
+ readonly containerSize?: "fixed" | "freeWidth" | "freeAspect";
3319
+ readonly containerShape?: "rect" | "convex" | "polygon" | "circle" | "ellipse" | "holes";
3320
+ readonly obstacles?: "none" | "center" | "scattered" | "wall" | "corridors" | "touching" | "edge";
3321
+ readonly sizes?: "identical" | "uniform" | "heavyTail" | "bimodal" | "extremeAspect" | "nearIdentical";
3322
+ readonly count?: "1" | "10" | "100" | "1k" | "10k";
3323
+ readonly mode?: "offline" | "online" | "incremental";
3324
+ readonly edgeDensity?: "sparse" | "medium" | "dense";
3325
+ readonly edgeShape?: "random" | "clustered" | "hubChain" | "longRange" | "tree" | "bundled";
3326
+ readonly groups?: "none" | "flat" | "nested";
3327
+ readonly ports?: "free" | "sides" | "fixed";
3328
+ }
3329
+ /** The outer rectangle of a packing. The router ignores it. */
3330
+ export interface LayoutContainer {
3331
+ readonly w?: number;
3332
+ readonly h?: number;
3333
+ /** `none`: the packer picks the size. `width`: the width stays. `height`: the height stays. `size`: the width and the height stay. */
3334
+ readonly fixed: "none" | "width" | "height" | "size";
3335
+ /** The ratio `w / h` that the packer aims for. */
3336
+ readonly aspect?: number;
3337
+ /** The shape of the container. */
3338
+ readonly shape?: Region;
3339
+ }
3340
+ /** The identity of an input in a set: the set, the family, the seed, and the base of a variant. */
3341
+ export interface LayoutInputHead {
3342
+ /** The id: `<set>/<family>/s<seed>`. */
3343
+ readonly id: string;
3344
+ readonly set: string;
3345
+ readonly family: string;
3346
+ readonly seed: number;
3347
+ /** The id of the base input of a variant. The stability measures compare the run on the variant with the run on its base. */
3348
+ readonly base?: string;
3349
+ readonly change?: LayoutChange;
3350
+ /** The place of the input in a change sequence. */
3351
+ readonly step?: number;
3352
+ /** The generator of the input. The default is `null`: a hand-made input. */
3353
+ readonly generator?: LayoutGenerator | null;
3354
+ /** The origin of the input. The default is `made-up`. */
3355
+ readonly source?: LayoutSource;
3356
+ readonly cell?: LayoutCell;
3357
+ }
3358
+ /**
3359
+ * An input file of the form `layout-input/1`. The packer and the router read the same files.
3360
+ * The file `docs/LAYOUT-RECORDS.md` gives the form. The repository `packing` keeps a twin of that document.
3361
+ */
3362
+ export interface LayoutInput extends LayoutInputHead {
3363
+ readonly schema: "layout-input/1";
3364
+ /** The origin of the input. The data of this repository is made-up, because the repository is public. */
3365
+ readonly source: LayoutSource;
3366
+ /** The generator of the input, or `null` for a hand-made input. */
3367
+ readonly generator: LayoutGenerator | null;
3368
+ /** The first 16 hex characters of the SHA-256 of the canonical file without this field. `documentHash` calculates it. */
3369
+ readonly hash: string;
3370
+ readonly container?: LayoutContainer;
3371
+ /** The space between two boxes. The router ignores it. */
3372
+ readonly gap?: number;
3373
+ /** The areas that the boxes and the routes must not use. */
3374
+ readonly obstacles?: readonly LayoutObstacle[];
3375
+ readonly boxes: readonly LayoutBox[];
3376
+ readonly edges: readonly LayoutEdge[];
3377
+ }
3378
+ /** One run of one strategy on one input and one seed: a line of the form `layout-record/1`. */
3379
+ export interface LayoutRecord {
3380
+ readonly schema: "layout-record/1";
3381
+ /** `pack`, `route` or `joint`. The screen of this package writes `route`. */
3382
+ readonly stage: "pack" | "route" | "joint";
3383
+ readonly step: string;
3384
+ readonly strategy: string;
3385
+ /** The options of the run: the defaults of the strategy with the options of the caller. A function is the text `function:<name>`. */
3386
+ readonly options: Readonly<Record<string, unknown>>;
3387
+ /** The corpus version, for example `screen-v1`. */
3388
+ readonly corpus: string;
3389
+ /** The id of the input. */
3390
+ readonly input: string;
3391
+ /** The `hash` of the input file. */
3392
+ readonly inputHash: string;
3393
+ readonly set: string;
3394
+ readonly seed: number;
3395
+ readonly nodes: number;
3396
+ readonly edges: number;
3397
+ /** The measures, by the names of `MEASURES`. A measure without a finite value is not in the record. */
3398
+ readonly measures: Readonly<Record<string, number>>;
3399
+ /** The count of the breaks of each hard rule. A good run has 0 for each rule. */
3400
+ readonly hard: Readonly<Record<string, number>>;
3401
+ /** The tolerance of each hard rule of the run, for example `{ through: 0.5 }`. */
3402
+ readonly tolerance?: Readonly<Record<string, number>>;
3403
+ /** This value is `true` when two runs on the same input give the same output. */
3404
+ readonly deterministic: boolean;
3405
+ /** The id of the prediction of this run, from the predictions file. */
3406
+ readonly prediction?: string;
3407
+ /** The time of the run, in milliseconds. Only the times of CI compare. */
3408
+ readonly ms: number;
3409
+ /** The commit of the code that made the record. */
3410
+ readonly commit?: string;
3411
+ /** The reason when the strategy did not run, for example an input over its `maxNodes`. Then the record has no measures. */
3412
+ readonly skipped?: string;
3413
+ }
3414
+ /** The comparison of a prediction. Without it, `<=` applies to a measure where lower is better, and `>=` to the other measures. */
3415
+ export type PredictionOp = "<" | "<=" | "=" | ">=" | ">";
3416
+ /** A prediction about a run: one line of a predictions file. A commit adds the file before the run starts. */
3417
+ export interface LayoutPrediction {
3418
+ readonly schema?: "layout-prediction/1";
3419
+ readonly id: string;
3420
+ readonly strategy: string;
3421
+ readonly set: string;
3422
+ /** The id of one input. Without it, the prediction is about the median of the measure over the set. */
3423
+ readonly input?: string;
3424
+ /** The name of the measure, from `MEASURES`. */
3425
+ readonly measure: string;
3426
+ readonly expected: number;
3427
+ readonly op?: PredictionOp;
3428
+ readonly reason: string;
3429
+ }
3430
+ /**
3431
+ * This function writes a graph as an input file of the form `layout-input/1`, with its hash.
3432
+ * A fixed plug gets `x`, `y` and the side that holds it. `inputGraph` reads the file back.
3433
+ */
3434
+ export declare function graphInput(graph: Graph, head: LayoutInputHead): LayoutInput;
3435
+ /**
3436
+ * This function gives the bounding box of a region: the smallest box that holds it.
3437
+ */
3438
+ export declare function regionBounds(region: Region): {
3439
+ x: number;
3440
+ y: number;
3441
+ w: number;
3442
+ h: number;
3443
+ };
3444
+ /**
3445
+ * This function reads the graph of the router from an input file. The router reads the positions, the ports, the edges and the data.
3446
+ * Each obstacle becomes a node without edges, with the bounding box of its region, after the boxes.
3447
+ * The router ignores the other fields of the packer: `container`, `gap`, `locked`, `rank`, the `shape` of a box and the `move` of an obstacle.
3448
+ * A box without `x` and `y` is an error.
3449
+ */
3450
+ export declare function inputGraph(input: LayoutInput): Graph;
3451
+ /**
3452
+ * This function writes an input file as text: the keys in sorted order, and one box or one edge on each line.
3453
+ * `JSON.parse` of the text gives the input again.
3454
+ */
3455
+ export declare function formatInput(input: LayoutInput): string;
3456
+ /** This function writes records as JSON Lines: one record on each line. */
3457
+ export declare function recordLines(records: readonly LayoutRecord[]): string;
3458
+ /** This function reads JSON Lines. It ignores an empty line. */
3459
+ export declare function parseLines<T>(text: string): T[];
3460
+ /**
3461
+ * This function gives a copy of a value that JSON keeps.
3462
+ * A function becomes the text `function:<name>`, and a number that is not finite becomes its text.
3463
+ */
3464
+ export declare function jsonSafe(value: unknown): unknown;
3465
+ /**
3466
+ * One measure of a record. `key` is the key of the measure in the values of `runSuite` and `compareStep`.
3467
+ * `name` is the name of the measure in a record of the form `layout-record/1`.
3468
+ */
3469
+ export interface MeasureInfo {
3470
+ /** The key in the values of `runSuite` and `compareStep`, for example `R5.median`. */
3471
+ readonly key: string;
3472
+ /** The id of the measure in `docs/research/MEASURES.md` (MEAS0), for example `R5`. */
3473
+ readonly id: string;
3474
+ /** The name in a record: lowercase, with a dot after the stage, for example `route.detour.median`. */
3475
+ readonly name: string;
3476
+ readonly unit: string;
3477
+ readonly better: "lower" | "higher";
3478
+ /**
3479
+ * This value is `true` when the positions of the boxes alone can move the value, with the same router.
3480
+ * Then two values compare only on the same input. The value is `false` when the measure scores the routes or the curves for a fixed placement.
3481
+ */
3482
+ readonly placementDependent: boolean;
3483
+ }
3484
+ /**
3485
+ * The measures of the records of the stage `route`, with the placement dependence of each one.
3486
+ * A joint harness that moves the boxes and routes the edges reads `placementDependent`.
3487
+ * It compares a measure with the value `true` only between runs on the same input.
3488
+ */
3489
+ export declare const MEASURES: readonly MeasureInfo[];
3490
+ /** This function gives the measure of a key of `runSuite` or `compareStep`, or `undefined` for a key that is not in `MEASURES`. */
3491
+ export declare function measureByKey(key: string): MeasureInfo | undefined;
3492
+ /** This function gives the measure of a name of a record, or `undefined` for a name that is not in `MEASURES`. */
3493
+ export declare function measureByName(name: string): MeasureInfo | undefined;
3494
+ /** This function gives the name of a key in a record. A key that is not in `MEASURES` gets the name `route.other.<key>`. */
3495
+ export declare function measureName(key: string): string;
3496
+ /** This function gives the objectives of a Pareto front by the names of a record, from objectives by the keys of `runSuite`. */
3497
+ export declare function namedObjectives(objectives: readonly Objective[]): Objective[];
3498
+ /** A family of boards of a screen set. The member `k` of the family has the seed `k`. */
3499
+ export interface ScreenFamily {
3500
+ readonly name: string;
3501
+ /** The known hard case that the family shows, in a few words. */
3502
+ readonly shows: string;
3503
+ /** The number of members. */
3504
+ readonly seeds: number;
3505
+ /** This function makes the member `k`. The same `k` always gives the same graph. */
3506
+ readonly make: (k: number) => Graph;
3507
+ /** This function gives the generator of the member `k`: its name, version, parameters and seed. */
3508
+ readonly generator: (k: number) => LayoutGenerator;
3509
+ /** The cell of each member in the taxonomy of the corpus. */
3510
+ readonly cell: LayoutCell;
3511
+ }
3512
+ /** A screen set: a fixed list of small boards with an id. A new board or a changed board gets a new id. */
3513
+ export interface ScreenSet {
3514
+ /** The id of the set, for example `screen-v1`. The records name it in `set` and `corpus`. */
3515
+ readonly id: string;
3516
+ readonly families: readonly ScreenFamily[];
3517
+ }
3518
+ /**
3519
+ * The screen set `screen-v1`: 14 boards of made-up data from 10 to 150 nodes. Each family shows a known hard case.
3520
+ * The seed 0 of each family is the fixture or the case board of the benchmark. The seed `k` of a fixture family is `familySeed(spec, k)`, as in `runSuite`.
3521
+ * The generators wrap the fixtures and the case boards without a change to their output.
3522
+ * This set does not change. The tests compare it with the files in `corpus/screen-v1`.
3523
+ */
3524
+ export declare const SCREEN_V1: ScreenSet;
3525
+ /** The screen sets by id. */
3526
+ export declare const SCREEN_SETS: Readonly<Record<string, ScreenSet>>;
3527
+ /** This function gives the id of the member `seed` of a family of a set: `<set>/<family>/s<seed>`. */
3528
+ export declare function inputId(set: string, family: string, seed: number): string;
3529
+ /** This function gives the input files of a screen set, in the order of its families and seeds. Each file has its hash. */
3530
+ export declare function screenInputs(set?: ScreenSet): LayoutInput[];
3531
+ /** A spec of a manifest: one generator with its version and parameters, and the seeds that the corpus uses. */
3532
+ export interface CorpusSpec {
3533
+ readonly generator: string;
3534
+ readonly version: number;
3535
+ readonly params: Readonly<Record<string, unknown>>;
3536
+ readonly seeds: readonly number[];
3537
+ }
3538
+ /** The manifest `corpus.json` of a corpus, of the form `layout-corpus/1`. */
3539
+ export interface LayoutCorpus {
3540
+ readonly schema: "layout-corpus/1";
3541
+ readonly corpus: string;
3542
+ readonly specs: readonly CorpusSpec[];
3543
+ readonly inputs: readonly {
3544
+ readonly id: string;
3545
+ readonly hash: string;
3546
+ readonly cell: LayoutCell;
3547
+ }[];
3548
+ }
3549
+ /** This function gives the manifest of a list of inputs. The inputs of one generator, version and parameters share one spec. */
3550
+ export declare function corpusManifest(corpus: string, inputs: readonly LayoutInput[]): LayoutCorpus;
3551
+ /**
3552
+ * The steps of the screen: the steps of `compareStep` and the step `highway`.
3553
+ * The screen of the step `highway` routes the plan of each strategy with `follow`, and measures the routes as the routes of a router.
3554
+ */
3555
+ export type ScreenStep = CompareStep | "highway";
3556
+ /** The steps of the screen, in the order of the pipeline. */
3557
+ export declare const SCREEN_STEPS: readonly ScreenStep[];
3558
+ /** The routers that the screen of the step `highway` also runs by default. They are the baselines of the note on highways. */
3559
+ export declare const HIGHWAY_BASE_ROUTERS: readonly string[];
3560
+ /**
3561
+ * A wrapper of each router of a screen. `stable` routes the edges in the stable order of WILD-053 (`stableOrderStrategy`).
3562
+ * `repair` runs the repair step of RULE-046 after the router (`repairStrategy`).
3563
+ */
3564
+ export type ScreenWrap = "stable" | "repair";
3565
+ /** The wrappers of `ScreenWrap`. */
3566
+ export declare const SCREEN_WRAPS: readonly ScreenWrap[];
3567
+ /** The hard rules of each step of the screen, in the order of the records. A good run has 0 for each rule. */
3568
+ export declare const SCREEN_RULES: Readonly<Record<ScreenStep, readonly string[]>>;
3569
+ /** The options of `screen`. */
3570
+ export interface ScreenOptions {
3571
+ /** The screen set. The default is `SCREEN_V1`. */
3572
+ readonly set?: ScreenSet;
3573
+ /** The input files. The default is the files of `set`. */
3574
+ readonly inputs?: readonly LayoutInput[];
3575
+ /** The families of the inputs that the screen runs. The default is each family. */
3576
+ readonly families?: readonly string[];
3577
+ /**
3578
+ * With `true`, the screen also runs each built-in strategy of the step, and the front compares the new strategies with them.
3579
+ * With `false`, it runs only the strategies of the call. The default is `true`.
3580
+ */
3581
+ readonly baseline?: boolean;
3582
+ /** The options of each strategy, by its name. A strategy without an entry gets its defaults. */
3583
+ readonly options?: Readonly<Record<string, object>>;
3584
+ /** The router whose routes the step `curve` draws. The default is `corners`. */
3585
+ readonly curveRouter?: string;
3586
+ /**
3587
+ * The routers that the screen of the step `highway` also runs. Their records have the step `router`.
3588
+ * The default is `HIGHWAY_BASE_ROUTERS`. The other steps do not read it.
3589
+ */
3590
+ readonly baseRouters?: readonly string[];
3591
+ /** The seed of the small change of the stability measures, and of the first random order of `shuffles`. The default is 1. */
3592
+ readonly seed?: number;
3593
+ /**
3594
+ * The wrappers of each router of the steps `router` and `highway`. Each wrapper `w` adds the router `<name>+<w>` as a new strategy, beside the router `<name>`.
3595
+ * The default is none. The steps `group` and `curve` do not read it.
3596
+ */
3597
+ readonly wrap?: readonly ScreenWrap[];
3598
+ /**
3599
+ * The number of random orders of the edges for the order fragility (W3, from WILD-056). Each router routes each input this number of times more.
3600
+ * The default is 0: no measure of the order fragility. The steps `group` and `curve` do not read it.
3601
+ */
3602
+ readonly shuffles?: number;
3603
+ /** The commit of the code, for the records. */
3604
+ readonly commit?: string;
3605
+ /** The predictions of the run. Each record names the first prediction with its strategy, its set and its input. */
3606
+ readonly predictions?: readonly LayoutPrediction[];
3607
+ /** This function gets one line of progress for each input. */
3608
+ readonly log?: (line: string) => void;
3609
+ }
3610
+ /** The summary of one strategy over the inputs of a screen. */
3611
+ export interface ScreenStrategySummary {
3612
+ readonly strategy: string;
3613
+ /** This value is `true` for a strategy of the call, and `false` for a built-in strategy of the baseline. */
3614
+ readonly candidate: boolean;
3615
+ /** The number of inputs where the strategy ran. */
3616
+ readonly runs: number;
3617
+ /** The number of inputs that the strategy skipped. */
3618
+ readonly skipped: number;
3619
+ /** This value is `true` when each run gave the same output two times. */
3620
+ readonly deterministic: boolean;
3621
+ /** The sum of the breaks of each hard rule over the runs. */
3622
+ readonly hard: Readonly<Record<string, number>>;
3623
+ /** The sum of `hard`. */
3624
+ readonly hardTotal: number;
3625
+ /**
3626
+ * The breaks over the floor of each input. The floor is the counts of the built-in strategy with the fewest breaks on that input.
3627
+ * Each built-in breaks a rule on some boards, for example on a board where the boxes touch. Without built-ins, the floor is 0.
3628
+ */
3629
+ readonly hardOverFloor: number;
3630
+ /** The median of each measure over the runs, by the names of a record. */
3631
+ readonly medians: Readonly<Record<string, number>>;
3632
+ /** The median time of a run, in milliseconds. */
3633
+ readonly ms: number;
3634
+ /** The number of inputs where the strategy is on the Pareto front of its input. */
3635
+ readonly onFront: number;
3636
+ }
3637
+ /** A prediction with the measured value. */
3638
+ export interface PredictionCheck extends LayoutPrediction {
3639
+ readonly op: PredictionOp;
3640
+ /** The measured value: the value of the record of the input, or the median over the set. It is absent when no record has the measure. */
3641
+ readonly measured?: number;
3642
+ /** This value is `true` when the measured value meets the prediction. It is absent when there is no measured value. */
3643
+ readonly met?: boolean;
3644
+ }
3645
+ /** The summary of a screen. */
3646
+ export interface ScreenSummary {
3647
+ readonly set: string;
3648
+ readonly step: ScreenStep;
3649
+ /** The number of inputs. */
3650
+ readonly inputs: number;
3651
+ /** The axes of the Pareto front, by the names of a record. */
3652
+ readonly objectives: readonly Objective[];
3653
+ /** One summary for each strategy, in the order of the registry. */
3654
+ readonly strategies: readonly ScreenStrategySummary[];
3655
+ /** The strategies on the Pareto front of the medians over the set. */
3656
+ readonly front: readonly string[];
3657
+ /** The strategies with a break over the floor, without a run or with two different outputs of one input. They do not enter the front. */
3658
+ readonly excluded: readonly string[];
3659
+ readonly predictions: readonly PredictionCheck[];
3660
+ }
3661
+ /** The result of `screen`: one record for each strategy and input, and the summary. */
3662
+ export interface ScreenReport {
3663
+ readonly records: readonly LayoutRecord[];
3664
+ readonly summary: ScreenSummary;
3665
+ }
3666
+ /** This function gives the name of a router without the suffix of a wrapper, for example `shared` for `shared+repair`. */
3667
+ export declare function unwrappedName(name: string): string;
3668
+ /**
3669
+ * This function screens strategies of one step on the inputs of a screen set. It is the cheap test of a new idea before a full build.
3670
+ * Each strategy runs on each input with `compareStep`, and each run gives one record of the form `layout-record/1`.
3671
+ * A strategy can be a name of the registry or a strategy object, for example from a prototype file. The registry does not change.
3672
+ *
3673
+ * The step `router` routes each input two times for the rule "same twice". The steps `group` and `curve` run each input two times for the same rule.
3674
+ *
3675
+ * The step `highway` makes the plan of each strategy and routes it with `follow`, two times. It also runs the routers of `baseRouters`.
3676
+ * An input with a `base` in the inputs also gets the measures `route.stability.base.*`: the routes on the variant against the routes on its base.
3677
+ * The same inputs and the same options give the same records. Only the times change.
3678
+ */
3679
+ export declare function screen(step: ScreenStep, strategies?: readonly (Strategy<ScreenStep> | string)[], options?: ScreenOptions): ScreenReport;
3680
+ /** This function writes the summary of a screen as Markdown: one row for each strategy, the front and the predictions. */
3681
+ export declare function formatScreen(summary: ScreenSummary): string;
3682
+ /** This function gives a whole number from `lo` to `hi`, both included, from a generator of random numbers. */
3683
+ export declare function randomInt(r: () => number, lo: number, hi: number): number;
3684
+ /** The parameters of the generator `rect-scattered`. */
3685
+ export interface RectScatteredParams {
3686
+ /** The number of boxes. */
3687
+ readonly count: number;
3688
+ }
3689
+ /**
3690
+ * This function makes the input of the shared generator `rect-scattered`, version 1: a fixed rectangle container, scattered obstacles and boxes without positions.
3691
+ * The repository `packing` makes the same file, byte for byte. A test in each repository pins the hashes of the seeds 1, 2 and 3.
3692
+ * The steps are `container`, `obstacles` and `boxes`. Each step has its own generator from `stepSeed`.
3693
+ */
3694
+ export declare function rectScattered(seed: number, params: RectScatteredParams, set?: string): LayoutInput;
3695
+ /** The options of `follow`. */
3696
+ interface FollowOptions extends WayOptions {
3697
+ /**
3698
+ * These routes are the routes of the base router. Each edge outside the plan keeps its route from them.
3699
+ * Without them, or for an edge without a route in them, `follow` routes the edge as the router `corners` does.
3700
+ */
3701
+ readonly routes?: Result;
3702
+ /** The lane order of the shared runs. The default is `bundle`. */
3703
+ readonly laneOrder?: RunOrder;
3704
+ }
3705
+ /**
3706
+ * This function routes the edges along a highway plan.
3707
+ *
3708
+ * An edge of a highway goes from its source plug to its merge point. Then it goes along the spine to its split point, and to its target plug.
3709
+ * The ramps go around the boxes through the corner graph (`WayFinder.fromPlug` and `WayFinder.toPlug`).
3710
+ * A spine point on the box of the node is the plug itself. When the end has a fixed plug, the point is at that plug.
3711
+ *
3712
+ * An edge on several highways takes them in the order of `seq`.
3713
+ * A way through the corner graph goes from each split point to the next merge point.
3714
+ * An edge outside the plan keeps its route from `options.routes`, or goes as in the router `corners`.
3715
+ *
3716
+ * The result has a shared run for each stretch of a spine where the same two edges or more go. Each run holds the points of its routes in a row.
3717
+ * The same graph, plan and options give the same result.
3718
+ */
3719
+ export declare function follow(graph: Graph, plan: HighwayPlan, options?: FollowOptions): Result;
3720
+ /**
3721
+ * This function gives the highways of a result of a router: one highway for each shared run and for each trunk of a bundle.
3722
+ * The spine is the points of the run or of the trunk. Each edge of the run is a member, from one end of the spine to the other end, in the way of its route.
3723
+ * The member `seq` is the place of the shared stretch in the route of the edge. The lanes keep the lane order of the router.
3724
+ *
3725
+ * Thus `follow` routes each edge along the shared stretches of the router. A route that does not hold its run is not a member.
3726
+ */
3727
+ export declare function planOfResult(result: Result): HighwayPlan;
3728
+ /**
3729
+ * This function gives a router that runs a highway strategy and then `follow`. The strategy gets the graph without first routes.
3730
+ * The way finder of `follow` takes `margin` and `k` from the options of the strategy, and then from `followOptions`.
3731
+ * The router keeps the name and the `maxNodes` of the strategy.
3732
+ */
3733
+ export declare function highwayRouter<O extends object>(strategy: Strategy<"highway", O>, options?: Partial<O>, followOptions?: FollowOptions): Router;
3734
+ /**
3735
+ * This function gives a router strategy that runs a highway strategy and then `follow`.
3736
+ * The router strategy has the name, the options and the schema of the highway strategy.
3737
+ * The benchmark and the screen race such a router with the other routers.
3738
+ */
3739
+ export declare function highwayRouterStrategy<O extends object>(strategy: Strategy<"highway", O>): Strategy<"router", O>;
3740
+ /**
3741
+ * This function gives the graph with its edges in the stable order of WILD-053: by the FNV-1a hash of the id, then by the id.
3742
+ * The nodes and the edges do not change. Two orders of the same edges give the same graph.
3743
+ * The hash spreads the edges, so the stable order does not favor the edges of one node or one collection.
3744
+ */
3745
+ export declare function stableOrder(graph: Graph): Graph;
3746
+ /** This function gives the graph with its edges in a random order of the seed. The same graph and seed always give the same order. */
3747
+ export declare function shuffleEdges(graph: Graph, seed: number): Graph;
3748
+ /**
3749
+ * This function routes the graph in the stable order of `stableOrder`, with the function `route`.
3750
+ * The routes come back in the order of the input edges, so the caller sees no change of order.
3751
+ * The bundles, the runs and the levels come from the stable order. Thus each order of the input gives the same data.
3752
+ */
3753
+ export declare function routeInStableOrder(graph: Graph, route: (graph: Graph) => Result): Result;
3754
+ /** This function gives a router that routes each graph in the stable order of WILD-053. It keeps the name and the `maxNodes` of the router. */
3755
+ export declare function withStableOrder(router: Router): Router;
3756
+ /**
3757
+ * This function gives a router strategy that runs `strategy` in the stable order of WILD-053. The output does not depend on the order of the input edges.
3758
+ * The new strategy has the name `<name>+stable`, and the options and the schema of `strategy`. The strategy `strategy` does not change.
3759
+ */
3760
+ export declare function stableOrderStrategy<O extends object>(strategy: Strategy<"router", O>): Strategy<"router", O>;
3761
+ /**
3762
+ * The boundary walk of the repair step (RULE-046): a graph of the sides of the boxes.
3763
+ * The vertices are the corners of the boxes. The edges are the parts of each side between two corners on it.
3764
+ * A walk on this graph goes along the boundaries of the boxes, and not through a box. Thus it joins two boxes also when the boxes touch.
3765
+ * The graph drops each part of a side that goes through another box, so overlapping boxes do not open a way.
3766
+ */
3767
+ export declare class BoundaryWalk {
3768
+ #private;
3769
+ /** This constructor makes the graph of the sides of the nodes. `grid` holds the nodes by their boxes. */
3770
+ constructor(nodes: readonly Node[], grid: Grid<Node>);
3771
+ /**
3772
+ * This method gives a way along the boundaries of the boxes. The way goes from the point `a` on the box of `s` to the point `b` on the box of `t`.
3773
+ * A point that is not on its box goes first to the nearest point of the boundary.
3774
+ * The method gives `undefined` when no way joins the two boxes.
3775
+ */
3776
+ path(a: Point, s: Node, b: Point, t: Node): Point[] | undefined;
3777
+ }
3778
+ /** This function gives the point of the boundary of the box that is nearest to `p`. A point on the boundary gives itself. */
3779
+ export declare function nearestOnBoundary(box: Box, p: Point): Point;
3780
+ /** The options of the repair step (RULE-046). */
3781
+ export interface RepairOptions {
3782
+ /** The distance from a box to the corners of a detour, and twice the clearance of a pushed leg. The default is 5. */
3783
+ readonly margin?: number;
3784
+ /** The number of visible neighbours of each corner of the detour graph. The default is 8. */
3785
+ readonly k?: number;
3786
+ /** With `false`, the step does not push a leg out of a box. The default is `true`. */
3787
+ readonly push?: boolean;
3788
+ /** With `false`, the step takes no detour through the corner graph. The default is `true`. */
3789
+ readonly detour?: boolean;
3790
+ /** With `false`, the step does not route a whole faulty route again through the corner graph. The default is `true`. */
3791
+ readonly reroute?: boolean;
3792
+ /** With `false`, the step does not walk along the boundaries of the boxes. The default is `true`. */
3793
+ readonly walk?: boolean;
3794
+ }
3795
+ /** The counts of one repair: what the step found and what it did. */
3796
+ export interface RepairCounts {
3797
+ /** The number of edges whose two nodes are in the graph. */
3798
+ readonly routes: number;
3799
+ /** The routes with a break of a hard rule before the repair, and the missing routes. */
3800
+ readonly faulty: number;
3801
+ /** The ends that the step moved back to their plugs or to the boxes of their nodes. */
3802
+ readonly snapped: number;
3803
+ /** The legs that the step pushed out of a box. */
3804
+ readonly pushed: number;
3805
+ /** The legs that the step replaced with a detour through the corner graph. */
3806
+ readonly detoured: number;
3807
+ /** The faulty routes that the step routed again from end to end through the corner graph. */
3808
+ readonly rerouted: number;
3809
+ /** The faulty routes that the step replaced with a walk along the boundaries of the boxes. */
3810
+ readonly walked: number;
3811
+ /** The missing routes that the step added. */
3812
+ readonly added: number;
3813
+ /** The faulty routes that the step could not repair. They keep their base routes. */
3814
+ readonly kept: number;
3815
+ /** The edges that the step took out of a run or a bundle. The repaired route of such an edge does not hold the run or the trunk. */
3816
+ readonly unbundled: number;
3817
+ /** The ends of level links that the step moved to the boundaries of their items. */
3818
+ readonly linkEnds: number;
3819
+ }
3820
+ /** The result of `repairResult`: the repaired result and the counts. */
3821
+ export interface RepairReport {
3822
+ readonly result: Result;
3823
+ readonly counts: RepairCounts;
3824
+ }
3825
+ /**
3826
+ * This function repairs the breaks of the hard rules in the routes of any router (RULE-046). The input result does not change.
3827
+ *
3828
+ * - It adds a route through the corner graph for each edge without a route (`complete`).
3829
+ * - It moves each end back to its fixed plug, or to the nearest point of the box of its node (`ends-at-plugs` and `fixed-plugs`).
3830
+ * - It pushes each inner leg out of a box that it goes through, to the near side of the box (`no-pass-through`).
3831
+ * - It replaces each other leg through a box with a detour through the corner graph.
3832
+ * - When a leg does not repair, it routes the whole route again through the corner graph.
3833
+ * Else it walks along the boundaries of the boxes (`BoundaryWalk`).
3834
+ * - A route that still breaks a rule keeps its base route.
3835
+ * - It takes an edge out of a run or a bundle when its new route does not hold the run or the trunk (`run-shared` and `bundle-trunk`).
3836
+ * - It moves the ends of each level link to the boundaries of its items (`link-ends`).
3837
+ *
3838
+ * A route without a break does not change. The same input gives the same output.
3839
+ */
3840
+ export declare function repairResult(graph: Graph, result: Result, options?: RepairOptions): RepairReport;
3841
+ /** This function gives a router that repairs the routes of `router` with `repairResult`. It keeps the name and the `maxNodes` of the router. */
3842
+ export declare function withRepair(router: Router, options?: RepairOptions): Router;
3843
+ /**
3844
+ * This function gives a router strategy that runs `strategy` and then the repair step (RULE-046) with `repair`.
3845
+ * The new strategy has the name `<name>+repair`, and the options and the schema of `strategy`. The strategy `strategy` does not change.
3846
+ */
3847
+ export declare function repairStrategy<O extends object>(strategy: Strategy<"router", O>, repair?: RepairOptions): Strategy<"router", O>;
3848
+ export type { ArcOptions, ClothoidOptions, CornersOptions, CorridorOptions, CurveSpace, CutObjective, CutOptions, FollowOptions, Highway, HighwayInput, HighwayMember, HighwayOptions, HighwayPlan, JogStyle, KdAxis, KdLine, KdOptions, KeyOptions, KeysOptions, LaneCurve, NodeKey, RoomBends, RoundedOptions, SectionsOptions, ShareCost, ShareMerge, ShareOrder, SharedOptions, SharedWaysOptions, SmoothOptions, SplineOptions, TrunkFan, TrunkSplit, TrunksOptions };
2852
3849
  //# sourceMappingURL=index.d.ts.map