@kekonic/diagrams-geometry 1.0.0-rc.4

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kekonic
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,23 @@
1
+ # @kekonic/diagrams-geometry
2
+
3
+ Shared shape geometry for KDiagram: paths, safe content regions, ports, perimeter intersection, and layout footprints.
4
+
5
+ Renderers and layout/routing consume this package so semantic node kinds do not each invent their own shape math. The DSL exposes the same shape ids as first-class kinds (`diamond`, `cylinder`, `cloud`, …).
6
+
7
+ ## ShapeGeometry
8
+
9
+ ```ts
10
+ import { resolveShapeGeometry, resolveNodeTypeGeometry } from "@kekonic/diagrams-geometry";
11
+
12
+ const diamond = resolveShapeGeometry("diamond");
13
+ const fromKind = resolveNodeTypeGeometry("gateway"); // → hexagon
14
+ ```
15
+
16
+ Each geometry implements path generation, content/visual/footprint bounds, port placement, ray intersection, and hit testing.
17
+
18
+ Non-rect shapes project side/fan ports onto the silhouette (`projectSidePortOntoOutline`) so ELK `FIXED_POS` pins and `attachPointOnPerimeter` / `snapEdgeEndpointsToGeometry` agree — diamonds, hexes, ellipses, clouds, cylinders, pills, people, etc.
19
+
20
+ ## Related
21
+
22
+ - Kind catalog: `@kekonic/diagrams-core` (`BUILTIN_KIND_CATALOG`, `listGeometryKinds`)
23
+ - Pipeline boundaries: [`docs/architecture/pipeline.md`](../../docs/architecture/pipeline.md)
@@ -0,0 +1,393 @@
1
+ import { NodeCapability, Point, Point as Point$1, Rect, Rect as Rect$1, Vec2, Vec2 as Vec2$1 } from "@kekonic/diagrams-core";
2
+
3
+ //#region src/types.d.ts
4
+ /** Per-side insets in logical diagram units. */
5
+ type Insets = {
6
+ top: number;
7
+ right: number;
8
+ bottom: number;
9
+ left: number;
10
+ };
11
+ type Size = {
12
+ width: number;
13
+ height: number;
14
+ };
15
+ /** Cardinal / compass port sides. */
16
+ type PortSide = "north" | "east" | "south" | "west";
17
+ /** Optional corner ports. */
18
+ type PortCorner = "northwest" | "northeast" | "southeast" | "southwest";
19
+ type PortRef = {
20
+ kind: "side";
21
+ side: PortSide;
22
+ index?: number;
23
+ count?: number;
24
+ } | {
25
+ kind: "corner";
26
+ corner: PortCorner;
27
+ } | {
28
+ kind: "center";
29
+ } | {
30
+ kind: "radial";
31
+ angleDeg: number;
32
+ } | {
33
+ kind: "named";
34
+ name: string;
35
+ };
36
+ type PortStrategy = "bbox-mid" | "perimeter" | "distributed-sides" | "vertices" | "radial" | "semantic";
37
+ /** Stroke / fill hints that affect bounds and content insets. */
38
+ type ShapeStyle = {
39
+ strokeWidth?: number;
40
+ cornerRadius?: number; /** Shadow blur radius (visual bounds only). */
41
+ shadowBlur?: number;
42
+ shadowOffsetX?: number;
43
+ shadowOffsetY?: number;
44
+ };
45
+ type LayoutDensity = "compact" | "standard" | "presentation";
46
+ type LayoutContext = {
47
+ density?: LayoutDensity; /** Extra clear space beyond geometry defaults. */
48
+ clearSpace?: Partial<Insets>; /** Edge-launch corridor beyond the perimeter (layout footprint). */
49
+ edgeLaunch?: number; /** External label boxes already measured (world coords relative to node origin). */
50
+ externalLabels?: Rect[]; /** Badges / markers relative to node origin. */
51
+ badges?: Rect[];
52
+ };
53
+ /**
54
+ * Full anatomy of a placed node in logical units.
55
+ * Coordinates are relative to the geometry bounds origin unless noted.
56
+ */
57
+ type NodeBoundsModel = {
58
+ /** Visible outline of the primary shape (no shadows/labels/ports). */geometry: Rect; /** Interior region for text, icons, compartments. */
59
+ content: Rect; /** Complete visible extent including stroke, shadow, labels, badges, ports. */
60
+ visual: Rect; /** Pointer hit region (at least visual; may expand for small targets). */
61
+ interaction: Rect; /** Area reserved by layout (visual + clear space + launch corridors). */
62
+ footprint: Rect; /** Non-rendered exclusion zone around the node. */
63
+ clearSpace: Insets;
64
+ };
65
+ /** Path data returned by geometries — SVG `d` plus optional polygons. */
66
+ type PathData = {
67
+ /** Primary closed outline as SVG path `d`. */d: string; /** Optional secondary strokes (cylinder rim, subprocess markers, …). */
68
+ decorations?: Array<{
69
+ d: string;
70
+ role: string;
71
+ }>; /** Polygon vertices when the shape is polygonal (for intersection). */
72
+ polygon?: Point[];
73
+ };
74
+ type ContentPolicy = {
75
+ /** Preferred content alignment. */align?: "center" | "start" | "end"; /** Max preferred label lines before expand/truncate. */
76
+ maxLabelLines?: number; /** Whether long labels should prefer external placement. */
77
+ preferExternalLabel?: boolean; /** Icon placement when present. */
78
+ iconPlacement?: "leading" | "above" | "centered" | "none";
79
+ };
80
+ type ClearSpacePreset = LayoutDensity;
81
+ declare const CLEAR_SPACE_PRESETS: Record<ClearSpacePreset, number>;
82
+ declare const EDGE_LAUNCH_PRESETS: Record<ClearSpacePreset, number>;
83
+ /** Minimum interactive target in logical units (ports / markers). */
84
+ declare const MIN_INTERACTION_TARGET = 22;
85
+ declare const DEFAULT_STROKE_WIDTH = 1.6;
86
+ declare function uniformInsets(n: number): Insets;
87
+ declare function insets(partial: Partial<Insets>, fallback?: number): Insets;
88
+ declare function insetRect(r: Rect, pad: Insets | number): Rect;
89
+ declare function expandRectInsets(r: Rect, pad: Insets | number): Rect;
90
+ declare function unionRects(rects: Rect[]): Rect;
91
+ declare function rectFromSize(size: Size, origin?: Point): Rect;
92
+ declare function normalizeVector(v: Vec2): Vec2;
93
+ declare function sideNormal(side: PortSide): Vec2;
94
+ declare function sideMidpoint(bounds: Rect, side: PortSide): Point;
95
+ //#endregion
96
+ //#region src/shape-geometry.d.ts
97
+ /**
98
+ * Renderer-neutral shape geometry contract.
99
+ *
100
+ * Every foundational shape implements this so measure, layout, routing, and
101
+ * renderers share one source of truth for paths, content, ports, and hits.
102
+ */
103
+ interface ShapeGeometry {
104
+ readonly id: string;
105
+ /** SVG path / polygon for the primary outline. */
106
+ getPath(bounds: Rect$1, style?: ShapeStyle): PathData;
107
+ /** Safe interior rectangle for text/icons/compartments. */
108
+ getContentBounds(bounds: Rect$1, style?: ShapeStyle): Rect$1;
109
+ /** Visible extent including stroke (and optional shadow). */
110
+ getVisualBounds(bounds: Rect$1, style?: ShapeStyle): Rect$1;
111
+ /** Layout reservation including clear space and edge-launch corridor. */
112
+ getLayoutFootprint(bounds: Rect$1, context?: LayoutContext, style?: ShapeStyle): Rect$1;
113
+ /** World position of a port on/around the shape. */
114
+ getPortPosition(port: PortRef, bounds: Rect$1, style?: ShapeStyle): Point$1;
115
+ /** Outward unit normal at a port (edge launch direction). */
116
+ getPortNormal(port: PortRef, bounds: Rect$1, style?: ShapeStyle): Vec2$1;
117
+ /** Intersection of a ray with the visible perimeter. */
118
+ intersectRay(bounds: Rect$1, origin: Point$1, direction: Vec2$1, style?: ShapeStyle): Point$1 | null;
119
+ /** Point-in-shape test for hit testing (geometry fill, not interaction pad). */
120
+ containsPoint(bounds: Rect$1, point: Point$1, style?: ShapeStyle): boolean;
121
+ /** Optional preferred default / min sizes. */
122
+ defaultSize?: Size;
123
+ minSize?: Size;
124
+ defaultPadding?: Insets;
125
+ contentPolicy?: ContentPolicy;
126
+ /** Extra clear-space units beyond density preset (pointed corners, etc.). */
127
+ clearSpaceBoost?: number;
128
+ }
129
+ type ShapeGeometryBaseOptions = {
130
+ id: string;
131
+ defaultSize?: Size;
132
+ minSize?: Size;
133
+ defaultPadding?: Insets;
134
+ contentPolicy?: ContentPolicy; /** Extra clear space beyond density preset (e.g. pointed corners). */
135
+ clearSpaceBoost?: number;
136
+ };
137
+ /** Assemble the full node bounds model from a geometry + style + context. */
138
+ declare function buildNodeBoundsModel(geometry: ShapeGeometry, bounds: Rect$1, style?: ShapeStyle, context?: LayoutContext): NodeBoundsModel;
139
+ /** Shared helpers for concrete geometries. */
140
+ declare function defaultVisualBounds(bounds: Rect$1, style?: ShapeStyle): Rect$1;
141
+ declare function defaultLayoutFootprint(geometry: ShapeGeometry, bounds: Rect$1, context?: LayoutContext, style?: ShapeStyle): Rect$1;
142
+ declare function defaultSidePortPosition(port: PortRef, bounds: Rect$1): Point$1;
143
+ /**
144
+ * Place a side port on a non-rect silhouette.
145
+ * Starts from the AABB mid/distributed point, then casts from the shape center
146
+ * onto the outline so FIXED_POS pins and perimeter snap share one attach truth.
147
+ */
148
+ declare function projectSidePortOntoOutline(port: PortRef, bounds: Rect$1, hitFromCenter: (direction: Vec2$1) => Point$1 | null): Point$1;
149
+ /** Convenience: project onto a polygon silhouette via center→AABB ray. */
150
+ declare function projectSidePortOntoPolygon(port: PortRef, bounds: Rect$1, polygon: Point$1[], intersect: (polygon: Point$1[], origin: Point$1, direction: Vec2$1) => Point$1 | null): Point$1;
151
+ declare function distributedSidePort(bounds: Rect$1, side: PortSide, index: number, count: number, sideInset?: number): Point$1;
152
+ declare function defaultPortNormal(port: PortRef, _bounds: Rect$1): Vec2$1;
153
+ //#endregion
154
+ //#region src/math.d.ts
155
+ /** Ray from origin along direction; returns closest intersection with t >= 0. */
156
+ declare function intersectRayPolygon(polygon: Point[], origin: Point, direction: Vec2): Point | null;
157
+ /** Ellipse / circle ray intersection (axis-aligned). */
158
+ declare function intersectRayEllipse(bounds: Rect, origin: Point, direction: Vec2): Point | null;
159
+ /** Axis-aligned rect ray intersection. */
160
+ declare function intersectRayRect(bounds: Rect, origin: Point, direction: Vec2): Point | null;
161
+ declare function rectPolygon(bounds: Rect): Point[];
162
+ declare function pointInPolygon(point: Point, polygon: Point[]): boolean;
163
+ declare function pointInEllipse(point: Point, bounds: Rect): boolean;
164
+ declare function polygonToPath(points: Point[], close?: boolean): string;
165
+ /**
166
+ * Closed Catmull–Rom spline as cubic Béziers.
167
+ * Yields smooth SVG path data (`C` commands) from a polygon of control points.
168
+ */
169
+ declare function closedCatmullRomToPath(points: Point[]): string;
170
+ /** Inscribed content rect as a fraction of geometry bounds, centered. */
171
+ declare function centeredContentRect(bounds: Rect, widthRatio: number, heightRatio: number): Rect;
172
+ /** Stroke expands visual bounds by half stroke on each side. */
173
+ declare function strokeOutset(strokeWidth: number): number;
174
+ //#endregion
175
+ //#region src/registry.d.ts
176
+ type RenderDecoration = {
177
+ id: string; /** Decoration roles from PathData (rim, fold, markers, …). */
178
+ role: string;
179
+ };
180
+ type ShapeDefinition = {
181
+ id: string;
182
+ geometry: ShapeGeometry;
183
+ defaultSize: Size;
184
+ minSize: Size;
185
+ defaultPadding: Insets;
186
+ supportedPortStrategies: PortStrategy[];
187
+ contentPolicy: ContentPolicy;
188
+ renderDecorations?: RenderDecoration[];
189
+ };
190
+ type NodeTypeDefinition = {
191
+ id: string;
192
+ shapeId: string;
193
+ defaultIcon?: string;
194
+ defaultStyle?: Record<string, string>;
195
+ contentTemplate?: string;
196
+ defaultPorts?: Array<{
197
+ side: "north" | "east" | "south" | "west";
198
+ }>;
199
+ capabilities?: NodeCapability[];
200
+ subtitle?: string;
201
+ category?: string;
202
+ };
203
+ /** Register a custom shape without changing the renderer core. */
204
+ declare function registerShape(definition: ShapeDefinition): void;
205
+ declare function unregisterShape(id: string): void;
206
+ declare function getShapeDefinition(id: string): ShapeDefinition | undefined;
207
+ declare function getShapeGeometry(id: string): ShapeGeometry | undefined;
208
+ /**
209
+ * Resolve a shape id with fallback.
210
+ * Unknown ids fall back to rounded rectangle (same as historic SVG default).
211
+ */
212
+ declare function resolveShapeGeometry(id: string | undefined | null): ShapeGeometry;
213
+ declare function listRegisteredShapeIds(): string[];
214
+ /** Map authored shape synonyms onto registry ids (delegates to core). */
215
+ declare function normalizeShapeId(shape: string | undefined | null): string;
216
+ /** Register or override a semantic node type → shape mapping. */
217
+ declare function registerNodeType(definition: NodeTypeDefinition): void;
218
+ declare function unregisterNodeType(id: string): void;
219
+ declare function getNodeTypeDefinition(id: string): NodeTypeDefinition | undefined;
220
+ /**
221
+ * Resolve the geometry for a semantic kind (with optional shape override).
222
+ * Kind defaults come from the DSL catalog; shape overrides win.
223
+ */
224
+ declare function resolveNodeTypeGeometry(kind: string, shapeOverride?: string | null): ShapeGeometry;
225
+ declare function listRegisteredNodeTypeIds(): string[];
226
+ //#endregion
227
+ //#region src/measure.d.ts
228
+ type ContentSize = {
229
+ width: number;
230
+ height: number;
231
+ };
232
+ /**
233
+ * Given a measured content size, find geometry bounds large enough that
234
+ * getContentBounds() can contain it. Uses iterative refinement because
235
+ * content insets are not always linear (cylinder caps, hex chamfers, …).
236
+ */
237
+ declare function geometrySizeForContent(geometry: ShapeGeometry, content: ContentSize, seed?: ContentSize): ContentSize;
238
+ /** Relative content box (origin at geometry top-left) for MeasuredNode.contentBox. */
239
+ declare function relativeContentBox(geometry: ShapeGeometry, width: number, height: number): Rect;
240
+ //#endregion
241
+ //#region src/attach.d.ts
242
+ type PerimeterAttachInput = {
243
+ shapeId: string | undefined;
244
+ bounds: Rect; /** Ray origin (typically the adjacent bend / corridor point, outside the fill). */
245
+ origin: Point; /** Direction toward this node (will be normalized). */
246
+ direction: Vec2;
247
+ style?: ShapeStyle;
248
+ };
249
+ /** Intersection of a ray with the shape perimeter; falls back via center ray, then center. */
250
+ declare function attachPointOnPerimeter(input: PerimeterAttachInput): Point;
251
+ //#endregion
252
+ //#region src/shapes/rectangle.d.ts
253
+ declare const rectangleGeometry: ShapeGeometry;
254
+ declare const roundedRectangleGeometry: ShapeGeometry;
255
+ declare const pillGeometry: ShapeGeometry;
256
+ //#endregion
257
+ //#region src/shapes/diamond.d.ts
258
+ /** Diamond tips sit on bbox mid-sides so LR/TD ports land on vertices. */
259
+ declare function diamondPolygon(bounds: Rect): Point[];
260
+ declare function diamondPointsString(bounds: Rect): string;
261
+ declare const diamondGeometry: ShapeGeometry;
262
+ //#endregion
263
+ //#region src/shapes/hexagon.d.ts
264
+ /** Flat-top hexagon inset: height-led so wide short nodes keep real chamfers. */
265
+ declare function hexagonInset(width: number, height: number): number;
266
+ declare function hexagonPolygon(bounds: Rect): Point[];
267
+ declare function hexagonPointsString(bounds: Rect): string;
268
+ declare const hexagonGeometry: ShapeGeometry;
269
+ //#endregion
270
+ //#region src/shapes/cylinder.d.ts
271
+ declare function cylinderRadii(width: number, height: number): {
272
+ rx: number;
273
+ ry: number;
274
+ };
275
+ /**
276
+ * Cylinder as one closed silhouette + front rim arc.
277
+ * Prefer a single coordinated path set for intersection/hit testing.
278
+ */
279
+ declare function cylinderPaths(bounds: Rect): {
280
+ body: string;
281
+ rim: string;
282
+ };
283
+ /**
284
+ * Sampled silhouette matching `cylinderPaths` body (top arc → right side → bottom arc → left).
285
+ * Used for perimeter attachment so tall cylinders hit vertical walls, not a bounding ellipse.
286
+ */
287
+ declare function cylinderSilhouettePolygon(bounds: Rect, samplesPerCap?: number): Point[];
288
+ declare const cylinderGeometry: ShapeGeometry;
289
+ //#endregion
290
+ //#region src/shapes/queue.d.ts
291
+ /**
292
+ * Horizontal pipe (sideways cylinder) — the ubiquitous message-queue silhouette.
293
+ * End-cap radius is height-led so short wide queues keep readable openings.
294
+ */
295
+ declare function queueRadii(width: number, height: number): {
296
+ rx: number;
297
+ ry: number;
298
+ };
299
+ /**
300
+ * Pipe body + left-end rim (front opening), matching vertical cylinder conventions.
301
+ */
302
+ declare function queuePaths(bounds: Rect): {
303
+ body: string;
304
+ rim: string;
305
+ };
306
+ /**
307
+ * Sampled silhouette for ports / ray hits (left ellipse → top → right ellipse → bottom).
308
+ */
309
+ declare function queueSilhouettePolygon(bounds: Rect, samplesPerCap?: number): Point[];
310
+ declare const queueGeometry: ShapeGeometry;
311
+ //#endregion
312
+ //#region src/shapes/stream.d.ts
313
+ /** Corner radius for the stacked-log shell. */
314
+ declare function streamCornerRadius(height: number, width: number): number;
315
+ /**
316
+ * Partition y positions (absolute) for the stacked-log / Kafka-style silhouette.
317
+ * Two interior rules divide the card into three record bands.
318
+ */
319
+ declare function streamPartitionYs(bounds: Rect): [number, number];
320
+ declare function streamShellPath(bounds: Rect): string;
321
+ /**
322
+ * Short left-rail ticks — suggest stacked partitions without slicing through label/icon.
323
+ */
324
+ declare function streamPartitionPaths(bounds: Rect): string[];
325
+ /**
326
+ * Stacked-log card — ubiquitous for streams, topics, and append-only partitions.
327
+ * Outer shell holds the label; interior rules suggest record bands.
328
+ */
329
+ declare const streamGeometry: ShapeGeometry;
330
+ //#endregion
331
+ //#region src/shapes/ellipse.d.ts
332
+ declare const ellipseGeometry: ShapeGeometry;
333
+ declare const circleGeometry: ShapeGeometry;
334
+ //#endregion
335
+ //#region src/shapes/polygons.d.ts
336
+ declare const parallelogramGeometry: ShapeGeometry;
337
+ /** Manual operation: wider top. */
338
+ declare const trapezoidGeometry: ShapeGeometry;
339
+ declare const triangleGeometry: ShapeGeometry;
340
+ //#endregion
341
+ //#region src/shapes/document.d.ts
342
+ declare const documentGeometry: ShapeGeometry;
343
+ declare const foldedDocumentGeometry: ShapeGeometry;
344
+ //#endregion
345
+ //#region src/shapes/cloud.d.ts
346
+ declare const cloudGeometry: ShapeGeometry;
347
+ //#endregion
348
+ //#region src/shapes/person.d.ts
349
+ /** Port anchors: head (N), torso sides (E/W), feet (S). */
350
+ declare function personPortAnchors(bounds: Rect): Record<"north" | "east" | "south" | "west", Point>;
351
+ /** Closed silhouette for rays / multi-port projection (head arc + rounded torso). */
352
+ declare function personSilhouettePolygon(bounds: Rect, headSamples?: number): Point[];
353
+ /**
354
+ * Person / actor — C4-style head + rounded torso.
355
+ * The torso is the content box: it grows with label/subtitle width.
356
+ */
357
+ declare function personPaths(bounds: Rect): {
358
+ head: string;
359
+ body: string;
360
+ };
361
+ /** Extra height above the torso content for head + neck (used by measure). */
362
+ declare function personHeadStackHeight(bodyWidth: number): number;
363
+ declare const personGeometry: ShapeGeometry;
364
+ declare const compartmentedRectangleGeometry: ShapeGeometry;
365
+ declare const boundaryGeometry: ShapeGeometry;
366
+ //#endregion
367
+ //#region src/shapes/index.d.ts
368
+ /** All built-in geometries keyed by id. */
369
+ declare const BUILTIN_GEOMETRIES: {
370
+ readonly rectangle: ShapeGeometry;
371
+ readonly rounded: ShapeGeometry;
372
+ readonly pill: ShapeGeometry;
373
+ readonly diamond: ShapeGeometry;
374
+ readonly hexagon: ShapeGeometry;
375
+ readonly queue: ShapeGeometry;
376
+ readonly stream: ShapeGeometry;
377
+ readonly cylinder: ShapeGeometry;
378
+ readonly circle: ShapeGeometry;
379
+ readonly ellipse: ShapeGeometry;
380
+ readonly parallelogram: ShapeGeometry;
381
+ readonly trapezoid: ShapeGeometry;
382
+ readonly triangle: ShapeGeometry;
383
+ readonly document: ShapeGeometry;
384
+ readonly "folded-document": ShapeGeometry;
385
+ readonly cloud: ShapeGeometry;
386
+ readonly person: ShapeGeometry;
387
+ readonly table: ShapeGeometry;
388
+ readonly boundary: ShapeGeometry;
389
+ };
390
+ type BuiltinGeometryId = keyof typeof BUILTIN_GEOMETRIES;
391
+ //#endregion
392
+ export { BUILTIN_GEOMETRIES, BuiltinGeometryId, CLEAR_SPACE_PRESETS, type ClearSpacePreset, type ContentPolicy, type ContentSize, DEFAULT_STROKE_WIDTH, EDGE_LAUNCH_PRESETS, type Insets, type LayoutContext, type LayoutDensity, MIN_INTERACTION_TARGET, type NodeBoundsModel, type NodeTypeDefinition, type PathData, type PerimeterAttachInput, type Point, type PortCorner, type PortRef, type PortSide, type PortStrategy, type Rect, type RenderDecoration, type ShapeDefinition, type ShapeGeometry, type ShapeGeometryBaseOptions, type ShapeStyle, type Size, type Vec2, attachPointOnPerimeter, boundaryGeometry, buildNodeBoundsModel, centeredContentRect, circleGeometry, closedCatmullRomToPath, cloudGeometry, compartmentedRectangleGeometry, cylinderGeometry, cylinderPaths, cylinderRadii, cylinderSilhouettePolygon, defaultLayoutFootprint, defaultPortNormal, defaultSidePortPosition, defaultVisualBounds, diamondGeometry, diamondPointsString, diamondPolygon, distributedSidePort, documentGeometry, ellipseGeometry, expandRectInsets, foldedDocumentGeometry, geometrySizeForContent, getNodeTypeDefinition, getShapeDefinition, getShapeGeometry, hexagonGeometry, hexagonInset, hexagonPointsString, hexagonPolygon, insetRect, insets, intersectRayEllipse, intersectRayPolygon, intersectRayRect, listRegisteredNodeTypeIds, listRegisteredShapeIds, normalizeShapeId, normalizeVector, parallelogramGeometry, personGeometry, personHeadStackHeight, personPaths, personPortAnchors, personSilhouettePolygon, pillGeometry, pointInEllipse, pointInPolygon, polygonToPath, projectSidePortOntoOutline, projectSidePortOntoPolygon, queueGeometry, queuePaths, queueRadii, queueSilhouettePolygon, rectFromSize, rectPolygon, rectangleGeometry, registerNodeType, registerShape, relativeContentBox, resolveNodeTypeGeometry, resolveShapeGeometry, roundedRectangleGeometry, sideMidpoint, sideNormal, streamCornerRadius, streamGeometry, streamPartitionPaths, streamPartitionYs, streamShellPath, strokeOutset, trapezoidGeometry, triangleGeometry, uniformInsets, unionRects, unregisterNodeType, unregisterShape };
393
+ //# sourceMappingURL=index.d.mts.map