@statelyai/layout 0.2.0 → 0.4.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/NOTICE.md +4 -2
- package/README.md +221 -13
- package/dist/elkjs/index.cjs +3 -2
- package/dist/elkjs/index.d.cts +13 -2
- package/dist/elkjs/index.d.mts +13 -2
- package/dist/elkjs/index.mjs +3 -3
- package/dist/elkjs/main.cjs +2 -2
- package/dist/elkjs/main.d.cts +2 -2
- package/dist/elkjs/main.d.mts +2 -2
- package/dist/elkjs/main.mjs +2 -2
- package/dist/elkjs/worker-api.cjs +1 -1
- package/dist/elkjs/worker-api.d.cts +2 -2
- package/dist/elkjs/worker-api.d.mts +2 -2
- package/dist/elkjs/worker-api.mjs +1 -1
- package/dist/elkjs/worker.cjs +2 -2
- package/dist/elkjs/worker.mjs +2 -2
- package/dist/elkjs-UciYx7lD.mjs +2973 -0
- package/dist/elkjs-ggjsBuVP.cjs +3002 -0
- package/dist/index-B6cWNrMw.d.cts +80 -0
- package/dist/index-CJQLUKD9.d.mts +80 -0
- package/dist/{index-BSH2bloA.d.mts → index-DT6lPMfS.d.cts} +117 -5
- package/dist/{index-CG712jzV.d.cts → index-F1U-fCTu.d.mts} +117 -5
- package/dist/index.cjs +39 -9
- package/dist/index.d.cts +4 -3
- package/dist/index.d.mts +4 -3
- package/dist/index.mjs +4 -3
- package/dist/layered/index.cjs +3 -1
- package/dist/layered/index.d.cts +3 -2
- package/dist/layered/index.d.mts +3 -2
- package/dist/layered/index.mjs +2 -2
- package/dist/{layered-Bz2nWmVp.mjs → layered-C7ERzZjR.mjs} +12592 -4682
- package/dist/{layered-Cf9Rn8l7.cjs → layered-CBPg6_6_.cjs} +12711 -4717
- package/dist/{layout-engine-BNex9jxg.cjs → layout-engine-DAw06RhN.cjs} +5 -18
- package/dist/{layout-engine-WbC0YjjT.mjs → layout-engine-DC3IYkIy.mjs} +3 -10
- package/dist/routing/index.cjs +29 -0
- package/dist/routing/index.d.cts +3 -0
- package/dist/routing/index.d.mts +3 -0
- package/dist/routing/index.mjs +3 -0
- package/dist/routing-CR8flv8b.mjs +2780 -0
- package/dist/routing-QIdGGFBe.cjs +2996 -0
- package/dist/types-CT2akdK0.d.mts +133 -0
- package/dist/types-uxPlGRof.d.cts +133 -0
- package/dist/{worker-client-DAT_z2OR.d.mts → worker-client-BwGGRD5y.d.mts} +1 -1
- package/dist/{worker-client-DVhklF6A.d.cts → worker-client-D4zNyPEI.d.cts} +1 -1
- package/package.json +14 -3
- package/src/authoring/coordinates.ts +38 -10
- package/src/authoring/partial.ts +7 -2
- package/src/authoring/routing.ts +4 -1
- package/src/constraints.ts +174 -6
- package/src/elkjs/index.ts +1397 -452
- package/src/elkjs/layout-quality.ts +219 -0
- package/src/elkjs/opposing-tracks.ts +161 -0
- package/src/elkjs/orthogonal-junctions.ts +174 -0
- package/src/elkjs/routes.ts +147 -0
- package/src/elkjs/statechart.ts +9 -3
- package/src/elkjs/types.ts +2 -0
- package/src/index.ts +8 -0
- package/src/internal/elkjs-compatibility.ts +4 -1
- package/src/internal/layered-trace.ts +48 -0
- package/src/internal/layout-engine.ts +2 -1
- package/src/java-random.ts +6 -0
- package/src/layered/bk-node-placement.ts +403 -92
- package/src/layered/center-labels.ts +398 -0
- package/src/layered/compaction-bounds.ts +26 -0
- package/src/layered/compaction-errors.ts +2 -0
- package/src/layered/compaction-scanline.ts +63 -0
- package/src/layered/compound-boundaries.ts +99 -0
- package/src/layered/compound.ts +445 -0
- package/src/layered/constraint-orientation.ts +141 -0
- package/src/layered/crossing-constraints.ts +243 -0
- package/src/layered/crossing-counter.ts +221 -0
- package/src/layered/crossing-graph.ts +401 -0
- package/src/layered/cycle-random.ts +22 -0
- package/src/layered/elk-port-lists.ts +243 -0
- package/src/layered/end-labels.ts +124 -0
- package/src/layered/external-port-dummy.ts +137 -0
- package/src/layered/feedback-chains.ts +114 -0
- package/src/layered/fixed-self-loop.ts +150 -0
- package/src/layered/greedy-switch-decider.ts +356 -0
- package/src/layered/grouped-compaction.ts +787 -0
- package/src/layered/gwt-sort.ts +53 -0
- package/src/layered/hierarchical-port-phases.ts +242 -0
- package/src/layered/hierarchical-port-restoration.ts +233 -0
- package/src/layered/hierarchical-port-routing.ts +179 -0
- package/src/layered/hierarchy-crossing.ts +121 -0
- package/src/layered/hierarchy-sweepiness.ts +83 -0
- package/src/layered/hints.ts +371 -0
- package/src/layered/hyperedge-dummy-merger.ts +195 -0
- package/src/layered/index.ts +911 -261
- package/src/layered/initial-model-order.ts +404 -0
- package/src/layered/inverted-ports.ts +207 -0
- package/src/layered/label-dummy-switcher.ts +200 -0
- package/src/layered/long-edges.ts +135 -44
- package/src/layered/loop-envelopes.ts +184 -0
- package/src/layered/native-routing.ts +275 -0
- package/src/layered/network-simplex.ts +11 -15
- package/src/layered/node-margins.ts +59 -0
- package/src/layered/north-south-ports.ts +271 -0
- package/src/layered/opposing-tracks.ts +944 -0
- package/src/layered/orthogonal-cycle-order.ts +106 -0
- package/src/layered/orthogonal-hypersegments.ts +92 -0
- package/src/layered/orthogonal-junctions.ts +202 -0
- package/src/layered/orthogonal-segments.ts +243 -0
- package/src/layered/placement-orientation.ts +22 -0
- package/src/layered/port-distributor.ts +192 -0
- package/src/layered/port-edge-order.ts +20 -0
- package/src/layered/replace-routing.ts +45 -0
- package/src/layered/routing-coordinates.ts +32 -0
- package/src/layered/separate-exterior-labels.ts +24 -6
- package/src/layered/spacing.ts +34 -12
- package/src/layered/splitter-order.ts +106 -0
- package/src/layered/strategies.ts +2024 -883
- package/src/layered/types.ts +34 -0
- package/src/layered/weighted-compaction.ts +84 -0
- package/src/routing/adapters.ts +143 -0
- package/src/routing/algorithms.ts +1088 -0
- package/src/routing/coordination.ts +91 -0
- package/src/routing/engine.ts +473 -0
- package/src/routing/index.ts +69 -0
- package/src/routing/layout-cache.ts +65 -0
- package/src/routing/model.ts +218 -0
- package/src/routing/path.ts +324 -0
- package/src/routing/persistent.ts +117 -0
- package/src/routing/search.ts +358 -0
- package/src/routing/spatial.ts +78 -0
- package/src/routing/types.ts +146 -0
- package/dist/elkjs-BVnDwnBQ.cjs +0 -1551
- package/dist/elkjs-CFlfkEBz.mjs +0 -1528
- /package/dist/{public-types-B8rAALJq.d.mts → public-types-9NCPoqbp.d.mts} +0 -0
- /package/dist/{public-types-CVB0hXGk.d.cts → public-types-BcRZoJE3.d.cts} +0 -0
- /package/dist/{worker-client-DkwS4sHx.mjs → worker-client-BNjwT1AJ.mjs} +0 -0
- /package/dist/{worker-client-D3HMK33r.cjs → worker-client-D4oEvhAl.cjs} +0 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import type { ElkExtendedEdge, ElkNode, ElkPoint } from "./public-types";
|
|
2
|
+
import { pathFromPoints } from "../routing/path";
|
|
3
|
+
import { pathFromSplinePoints } from "../routing/adapters";
|
|
4
|
+
import { freeze } from "../routing/model";
|
|
5
|
+
import type { Route, RouteEndpoint, RoutePath, RoutePoint, RouteSection } from "../routing/types";
|
|
6
|
+
|
|
7
|
+
export interface ElkRouteOptions {
|
|
8
|
+
/** ELK stores spline controls in bendPoints; the caller must identify that encoding. */
|
|
9
|
+
routing?: "ORTHOGONAL" | "POLYLINE" | "SPLINES";
|
|
10
|
+
}
|
|
11
|
+
/** Normalize any ELK layout's section geometry, preserving ports and hyperedge junctions. */
|
|
12
|
+
export function getElkRoutes(
|
|
13
|
+
graph: ElkNode,
|
|
14
|
+
options: ElkRouteOptions = {},
|
|
15
|
+
): ReadonlyMap<string, Route> {
|
|
16
|
+
const shapes = new Map<string, { ref: RouteEndpoint; center: RoutePoint }>(),
|
|
17
|
+
frames = new Map<string, RoutePoint>();
|
|
18
|
+
const edges: { edge: ElkExtendedEdge; offset: RoutePoint; routing: string }[] = [];
|
|
19
|
+
function visit(node: ElkNode, offset: RoutePoint, inherited: string) {
|
|
20
|
+
const position = { x: offset.x + (node.x ?? 0), y: offset.y + (node.y ?? 0) };
|
|
21
|
+
const routing =
|
|
22
|
+
node.layoutOptions?.["elk.edgeRouting"] ??
|
|
23
|
+
node.layoutOptions?.["org.eclipse.elk.edgeRouting"] ??
|
|
24
|
+
inherited;
|
|
25
|
+
frames.set(node.id, position);
|
|
26
|
+
shapes.set(node.id, {
|
|
27
|
+
ref: { kind: "node", nodeId: node.id },
|
|
28
|
+
center: { x: position.x + (node.width ?? 0) / 2, y: position.y + (node.height ?? 0) / 2 },
|
|
29
|
+
});
|
|
30
|
+
for (const port of node.ports ?? [])
|
|
31
|
+
shapes.set(port.id, {
|
|
32
|
+
ref: { kind: "node", nodeId: node.id, port: port.id },
|
|
33
|
+
center: {
|
|
34
|
+
x: position.x + (port.x ?? 0) + (port.width ?? 0) / 2,
|
|
35
|
+
y: position.y + (port.y ?? 0) + (port.height ?? 0) / 2,
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
for (const edge of node.edges ?? [])
|
|
39
|
+
edges.push({
|
|
40
|
+
edge,
|
|
41
|
+
offset: position,
|
|
42
|
+
routing:
|
|
43
|
+
edge.layoutOptions?.["elk.edgeRouting"] ??
|
|
44
|
+
edge.layoutOptions?.["org.eclipse.elk.edgeRouting"] ??
|
|
45
|
+
routing,
|
|
46
|
+
});
|
|
47
|
+
for (const child of node.children ?? []) visit(child, position, routing);
|
|
48
|
+
}
|
|
49
|
+
visit(graph, { x: 0, y: 0 }, options.routing ?? "POLYLINE");
|
|
50
|
+
const result = new Map<string, Route>();
|
|
51
|
+
for (const { edge, offset: inheritedOffset, routing } of edges) {
|
|
52
|
+
const offset = edge.container
|
|
53
|
+
? (frames.get(edge.container) ?? inheritedOffset)
|
|
54
|
+
: inheritedOffset;
|
|
55
|
+
const point = (p: ElkPoint): RoutePoint => ({ x: p.x + offset.x, y: p.y + offset.y });
|
|
56
|
+
// Join section endpoints by topology, never by equal coordinates alone.
|
|
57
|
+
const parents = new Map<string, string>();
|
|
58
|
+
const root = (key: string): string => {
|
|
59
|
+
let current = key;
|
|
60
|
+
while (parents.has(current)) current = parents.get(current)!;
|
|
61
|
+
return current;
|
|
62
|
+
};
|
|
63
|
+
const join = (a: string, b: string) => {
|
|
64
|
+
const x = root(a),
|
|
65
|
+
y = root(b);
|
|
66
|
+
if (x !== y) parents.set(x < y ? y : x, x < y ? x : y);
|
|
67
|
+
};
|
|
68
|
+
for (const section of edge.sections ?? []) {
|
|
69
|
+
for (const id of section.outgoingSections ?? []) join(`${section.id}:end`, `${id}:start`);
|
|
70
|
+
for (const id of section.incomingSections ?? []) join(`${id}:end`, `${section.id}:start`);
|
|
71
|
+
}
|
|
72
|
+
const sections: RouteSection[] = [];
|
|
73
|
+
let malformed = false;
|
|
74
|
+
for (const section of edge.sections ?? []) {
|
|
75
|
+
const points = [section.startPoint, ...(section.bendPoints ?? []), section.endPoint].map(
|
|
76
|
+
point,
|
|
77
|
+
);
|
|
78
|
+
let path: RoutePath;
|
|
79
|
+
if (points.some((p) => !Number.isFinite(p.x) || !Number.isFinite(p.y))) {
|
|
80
|
+
malformed = true;
|
|
81
|
+
for (let i = 0; i < points.length; i++)
|
|
82
|
+
if (!Number.isFinite(points[i]!.x) || !Number.isFinite(points[i]!.y))
|
|
83
|
+
points[i] = { x: offset.x + i * 20, y: offset.y };
|
|
84
|
+
}
|
|
85
|
+
if (routing === "SPLINES") {
|
|
86
|
+
if ((points.length - 1) % 3 || points.length < 4) {
|
|
87
|
+
malformed = true;
|
|
88
|
+
path = pathFromPoints([points[0]!, points.at(-1)!]);
|
|
89
|
+
} else path = pathFromSplinePoints(points);
|
|
90
|
+
} else path = pathFromPoints(points);
|
|
91
|
+
const fromShape =
|
|
92
|
+
section.incomingShape ??
|
|
93
|
+
(!section.incomingSections?.length && edge.sources.length === 1
|
|
94
|
+
? edge.sources[0]
|
|
95
|
+
: undefined);
|
|
96
|
+
const toShape =
|
|
97
|
+
section.outgoingShape ??
|
|
98
|
+
(!section.outgoingSections?.length && edge.targets.length === 1
|
|
99
|
+
? edge.targets[0]
|
|
100
|
+
: undefined);
|
|
101
|
+
sections.push({
|
|
102
|
+
id: section.id,
|
|
103
|
+
from: fromShape
|
|
104
|
+
? (shapes.get(fromShape)?.ref ?? { kind: "node", nodeId: fromShape })
|
|
105
|
+
: { kind: "junction", id: `${edge.id}:${root(`${section.id}:start`)}` },
|
|
106
|
+
to: toShape
|
|
107
|
+
? (shapes.get(toShape)?.ref ?? { kind: "node", nodeId: toShape })
|
|
108
|
+
: { kind: "junction", id: `${edge.id}:${root(`${section.id}:end`)}` },
|
|
109
|
+
path,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
if (!sections.length) {
|
|
113
|
+
malformed = true;
|
|
114
|
+
const source = shapes.get(edge.sources[0] ?? ""),
|
|
115
|
+
origin = source?.center ?? { x: 0, y: 0 };
|
|
116
|
+
const targets = [...edge.targets, ...edge.sources.slice(1)];
|
|
117
|
+
for (const [i, id] of (targets.length ? targets : [""]).entries()) {
|
|
118
|
+
const target = shapes.get(id);
|
|
119
|
+
sections.push({
|
|
120
|
+
id: `${edge.id}:fallback:${i}`,
|
|
121
|
+
from: source?.ref ?? { kind: "node", nodeId: edge.sources[0] ?? "" },
|
|
122
|
+
to: target?.ref ?? { kind: "node", nodeId: id },
|
|
123
|
+
path: pathFromPoints([origin, target?.center ?? { x: origin.x + 40, y: origin.y + 40 }]),
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
result.set(
|
|
128
|
+
edge.id,
|
|
129
|
+
freeze({
|
|
130
|
+
edgeId: edge.id,
|
|
131
|
+
sections,
|
|
132
|
+
status: malformed ? "fallback" : "routed",
|
|
133
|
+
diagnostics: malformed
|
|
134
|
+
? [
|
|
135
|
+
{
|
|
136
|
+
code: "MISSING_GEOMETRY",
|
|
137
|
+
edgeId: edge.id,
|
|
138
|
+
message:
|
|
139
|
+
"ELK sections contain missing or invalid geometry; rendered fallback paths",
|
|
140
|
+
},
|
|
141
|
+
]
|
|
142
|
+
: [],
|
|
143
|
+
}),
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
return result;
|
|
147
|
+
}
|
package/src/elkjs/statechart.ts
CHANGED
|
@@ -178,8 +178,14 @@ export function scoreStatechartLayout(
|
|
|
178
178
|
height: shape.height ?? 0,
|
|
179
179
|
};
|
|
180
180
|
};
|
|
181
|
-
const visit = (
|
|
182
|
-
|
|
181
|
+
const visit = (
|
|
182
|
+
node: ElkNode,
|
|
183
|
+
x: number,
|
|
184
|
+
y: number,
|
|
185
|
+
ancestors: ElkNode[],
|
|
186
|
+
inheritedDirection = "RIGHT",
|
|
187
|
+
) => {
|
|
188
|
+
const direction = String(option(node, "direction") ?? inheritedDirection).toUpperCase();
|
|
183
189
|
const horizontal = direction === "RIGHT" || direction === "LEFT";
|
|
184
190
|
const sign = direction === "LEFT" || direction === "UP" ? -1 : 1;
|
|
185
191
|
const path = paths[String(node.id)] ?? [];
|
|
@@ -199,7 +205,7 @@ export function scoreStatechartLayout(
|
|
|
199
205
|
)
|
|
200
206
|
score.invalid++;
|
|
201
207
|
boxes.push({ rect: box, ancestors, node: child });
|
|
202
|
-
visit(child, box.x, box.y, [...ancestors, child]);
|
|
208
|
+
visit(child, box.x, box.y, [...ancestors, child], direction);
|
|
203
209
|
}
|
|
204
210
|
for (const edge of node.edges ?? []) {
|
|
205
211
|
if (String(option(edge, "noLayout")).toLowerCase() === "true") continue;
|
package/src/elkjs/types.ts
CHANGED
|
@@ -35,6 +35,8 @@ export interface ElkEdgeSection extends ElkGraphElement {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
export interface ElkEdge extends ElkGraphElement {
|
|
38
|
+
/** Node whose coordinate frame contains the exported route. */
|
|
39
|
+
container?: ElkId;
|
|
38
40
|
sources?: ElkId[];
|
|
39
41
|
targets?: ElkId[];
|
|
40
42
|
source?: ElkId;
|
package/src/index.ts
CHANGED
|
@@ -71,6 +71,10 @@ export type {
|
|
|
71
71
|
EdgeRoutes,
|
|
72
72
|
LayerAssigner,
|
|
73
73
|
LayerAssignment,
|
|
74
|
+
CompoundVisualGraph,
|
|
75
|
+
CompoundLayoutOptions,
|
|
76
|
+
CompoundLayoutGeometry,
|
|
77
|
+
CompoundEdgeAttachment,
|
|
74
78
|
LayeredLayoutOptions,
|
|
75
79
|
LayeredAdvancedOptions,
|
|
76
80
|
ElkLayeredOptionId,
|
|
@@ -92,6 +96,8 @@ export type {
|
|
|
92
96
|
} from "./layered";
|
|
93
97
|
|
|
94
98
|
export { c } from "./constraints";
|
|
99
|
+
export { hint, statechartHints } from "./layered/hints";
|
|
100
|
+
export type { AnchorHint, ChainHint, HintStrength, LayoutHint } from "./layered/hints";
|
|
95
101
|
export type {
|
|
96
102
|
LayoutConstraint,
|
|
97
103
|
GeometryReference,
|
|
@@ -103,3 +109,5 @@ export type {
|
|
|
103
109
|
LinearConstraint,
|
|
104
110
|
WaypointConstraint,
|
|
105
111
|
} from "./constraints";
|
|
112
|
+
|
|
113
|
+
export * from "./routing";
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import type { VisualGraph } from "@statelyai/graph";
|
|
1
|
+
import type { VisualGraph, Point } from "@statelyai/graph";
|
|
2
2
|
|
|
3
3
|
export interface Elkjs0111ResultPolicy {
|
|
4
|
+
junctionPointsByEdgeId?: ReadonlyMap<string, readonly Point[]>;
|
|
5
|
+
placementCrossBounds?: { axis: "x" | "y"; maximum: number };
|
|
6
|
+
normalizationBounds?: { left: number; top: number; right: number; bottom: number };
|
|
4
7
|
providerBounds?: { width: number; height: number };
|
|
5
8
|
preserveEdgeSections?: boolean;
|
|
6
9
|
skipBoundsNormalization?: boolean;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/** Development-only phase observations for differential tracing against real ELK. */
|
|
2
|
+
export type LayeredTraceEvent =
|
|
3
|
+
| {
|
|
4
|
+
kind: "sweep";
|
|
5
|
+
scope: string;
|
|
6
|
+
attempt: number;
|
|
7
|
+
forward: boolean;
|
|
8
|
+
firstSweep: boolean;
|
|
9
|
+
crossings: number;
|
|
10
|
+
layers: readonly (readonly string[])[];
|
|
11
|
+
}
|
|
12
|
+
| {
|
|
13
|
+
kind: "port-lists";
|
|
14
|
+
scope: string;
|
|
15
|
+
ports: ReadonlyMap<
|
|
16
|
+
string,
|
|
17
|
+
readonly { name?: string; outgoing: readonly string[]; incoming: readonly string[] }[]
|
|
18
|
+
>;
|
|
19
|
+
}
|
|
20
|
+
| {
|
|
21
|
+
kind: "initial-order";
|
|
22
|
+
scope: string;
|
|
23
|
+
layers: readonly (readonly string[])[];
|
|
24
|
+
}
|
|
25
|
+
| {
|
|
26
|
+
kind: "crossing-order";
|
|
27
|
+
scope: string;
|
|
28
|
+
edgeIds: readonly string[];
|
|
29
|
+
reversedEdgeIds: readonly string[];
|
|
30
|
+
layerByNodeId: ReadonlyMap<string, number>;
|
|
31
|
+
layers: readonly (readonly string[])[];
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
let observer: ((event: LayeredTraceEvent) => void) | undefined;
|
|
35
|
+
|
|
36
|
+
/** Install an observer and return the previous one. Production code never sets one. */
|
|
37
|
+
export function setLayeredTraceObserver(
|
|
38
|
+
next: ((event: LayeredTraceEvent) => void) | undefined,
|
|
39
|
+
): ((event: LayeredTraceEvent) => void) | undefined {
|
|
40
|
+
const previous = observer;
|
|
41
|
+
observer = next;
|
|
42
|
+
return previous;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Build and emit an event only while an observer is installed. */
|
|
46
|
+
export function traceLayeredPhase(event: () => LayeredTraceEvent): void {
|
|
47
|
+
observer?.(event());
|
|
48
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Graph, VisualGraph } from "@statelyai/graph";
|
|
2
2
|
import { boxAlgorithm, elkjs0111BoxAlgorithm, type BoxLayoutOptions } from "../box";
|
|
3
3
|
import { fixedAlgorithm, type FixedLayoutOptions } from "../fixed";
|
|
4
|
-
import { layeredAlgorithm, type LayeredLayoutOptions } from "../layered";
|
|
4
|
+
import { layeredAlgorithm, elkjs0111LayeredAlgorithm, type LayeredLayoutOptions } from "../layered";
|
|
5
5
|
import {
|
|
6
6
|
elkjs0111RectanglePackingAlgorithm,
|
|
7
7
|
rectanglePackingAlgorithm,
|
|
@@ -43,6 +43,7 @@ const elkjs0111LayoutAlgorithms = {
|
|
|
43
43
|
...builtInLayoutAlgorithms,
|
|
44
44
|
box: elkjs0111BoxAlgorithm,
|
|
45
45
|
random: elkjs0111RandomAlgorithm,
|
|
46
|
+
layered: elkjs0111LayeredAlgorithm,
|
|
46
47
|
rectpacking: elkjs0111RectanglePackingAlgorithm,
|
|
47
48
|
} satisfies {
|
|
48
49
|
[Id in BuiltInLayoutAlgorithmId]: LayoutAlgorithm<BuiltInLayoutOptionsById[Id]>;
|
package/src/java-random.ts
CHANGED
|
@@ -9,6 +9,12 @@ export class JavaRandom {
|
|
|
9
9
|
this.#seed = (BigInt(seed) ^ JavaRandom.#multiplier) & JavaRandom.#mask;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
clone(): JavaRandom {
|
|
13
|
+
const copy = new JavaRandom(0);
|
|
14
|
+
copy.#seed = this.#seed;
|
|
15
|
+
return copy;
|
|
16
|
+
}
|
|
17
|
+
|
|
12
18
|
#next(bits: number): number {
|
|
13
19
|
this.#seed = (this.#seed * JavaRandom.#multiplier + JavaRandom.#addend) & JavaRandom.#mask;
|
|
14
20
|
return Number(this.#seed >> BigInt(48 - bits));
|