@pixerate/editor 0.23.0 → 0.25.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.
Files changed (187) hide show
  1. package/README.md +167 -2
  2. package/THIRD_PARTY_NOTICES.md +80 -0
  3. package/dist/agent/index.cjs +10 -8
  4. package/dist/agent/index.cjs.map +1 -1
  5. package/dist/agent/index.d.cts +4 -3
  6. package/dist/agent/index.d.ts +4 -3
  7. package/dist/agent/index.js +4 -2
  8. package/dist/agent/index.js.map +1 -1
  9. package/dist/canvas/index.cjs +4437 -411
  10. package/dist/canvas/index.cjs.map +1 -1
  11. package/dist/canvas/index.d.cts +934 -4
  12. package/dist/canvas/index.d.ts +934 -4
  13. package/dist/canvas/index.js +4309 -283
  14. package/dist/canvas/index.js.map +1 -1
  15. package/dist/chunk-4BVP64JJ.cjs +1406 -0
  16. package/dist/chunk-4BVP64JJ.cjs.map +1 -0
  17. package/dist/chunk-664LQYFJ.js +115 -0
  18. package/dist/chunk-664LQYFJ.js.map +1 -0
  19. package/dist/chunk-7WISYZFO.cjs +740 -0
  20. package/dist/chunk-7WISYZFO.cjs.map +1 -0
  21. package/dist/chunk-AL6JMGWW.cjs +783 -0
  22. package/dist/chunk-AL6JMGWW.cjs.map +1 -0
  23. package/dist/chunk-BVP3TSLH.cjs +69 -0
  24. package/dist/chunk-BVP3TSLH.cjs.map +1 -0
  25. package/dist/{chunk-RIKBJLS2.cjs → chunk-C7P22VIP.cjs} +2001 -279
  26. package/dist/chunk-C7P22VIP.cjs.map +1 -0
  27. package/dist/chunk-D6FH2YAX.cjs +131 -0
  28. package/dist/chunk-D6FH2YAX.cjs.map +1 -0
  29. package/dist/chunk-ECCCYKGL.js +740 -0
  30. package/dist/chunk-ECCCYKGL.js.map +1 -0
  31. package/dist/{chunk-4SUNJZWB.cjs → chunk-FD4LPFAE.cjs} +48 -200
  32. package/dist/chunk-FD4LPFAE.cjs.map +1 -0
  33. package/dist/{chunk-QBJ22YZR.js → chunk-FH6F67DN.js} +1999 -277
  34. package/dist/chunk-FH6F67DN.js.map +1 -0
  35. package/dist/{chunk-OYXSKQFR.js → chunk-FPENXAEJ.js} +35 -187
  36. package/dist/chunk-FPENXAEJ.js.map +1 -0
  37. package/dist/chunk-HLIMTC6N.js +1 -0
  38. package/dist/chunk-HLIMTC6N.js.map +1 -0
  39. package/dist/chunk-HRMEDT2L.js +1406 -0
  40. package/dist/chunk-HRMEDT2L.js.map +1 -0
  41. package/dist/{chunk-QGHGJ56O.js → chunk-IXHSYOVY.js} +2518 -122
  42. package/dist/chunk-IXHSYOVY.js.map +1 -0
  43. package/dist/chunk-MKA3AHLV.cjs +256 -0
  44. package/dist/chunk-MKA3AHLV.cjs.map +1 -0
  45. package/dist/chunk-NAXVVS5I.js +783 -0
  46. package/dist/chunk-NAXVVS5I.js.map +1 -0
  47. package/dist/chunk-O5RYH2PG.js +69 -0
  48. package/dist/chunk-O5RYH2PG.js.map +1 -0
  49. package/dist/chunk-OXSV64JX.js +689 -0
  50. package/dist/chunk-OXSV64JX.js.map +1 -0
  51. package/dist/chunk-P3RQ5UJE.cjs +689 -0
  52. package/dist/chunk-P3RQ5UJE.cjs.map +1 -0
  53. package/dist/chunk-P6ODPZ4W.js +256 -0
  54. package/dist/chunk-P6ODPZ4W.js.map +1 -0
  55. package/dist/chunk-PL4JB3BF.cjs +1 -0
  56. package/dist/chunk-PL4JB3BF.cjs.map +1 -0
  57. package/dist/{chunk-GVSMRPHB.cjs → chunk-PO6A6QQH.cjs} +2607 -211
  58. package/dist/chunk-PO6A6QQH.cjs.map +1 -0
  59. package/dist/{chunk-JJDLPEWL.js → chunk-QGYDWPRM.js} +2 -2
  60. package/dist/chunk-RR7F5GUM.js +5726 -0
  61. package/dist/chunk-RR7F5GUM.js.map +1 -0
  62. package/dist/chunk-TNNJXF46.cjs +115 -0
  63. package/dist/chunk-TNNJXF46.cjs.map +1 -0
  64. package/dist/chunk-U5HZSFCS.js +131 -0
  65. package/dist/chunk-U5HZSFCS.js.map +1 -0
  66. package/dist/{chunk-MJZBNWG7.js → chunk-UAKDG62Z.js} +309 -581
  67. package/dist/chunk-UAKDG62Z.js.map +1 -0
  68. package/dist/{chunk-CL37JGFW.cjs → chunk-V3CHHWOE.cjs} +4 -4
  69. package/dist/{chunk-CL37JGFW.cjs.map → chunk-V3CHHWOE.cjs.map} +1 -1
  70. package/dist/chunk-WSQKHXW7.cjs +5726 -0
  71. package/dist/chunk-WSQKHXW7.cjs.map +1 -0
  72. package/dist/{chunk-AA4ZEVCC.cjs → chunk-X4N4WUKB.cjs} +336 -608
  73. package/dist/chunk-X4N4WUKB.cjs.map +1 -0
  74. package/dist/commands/index.cjs +74 -1
  75. package/dist/commands/index.cjs.map +1 -1
  76. package/dist/commands/index.d.cts +38 -353
  77. package/dist/commands/index.d.ts +38 -353
  78. package/dist/commands/index.js +73 -0
  79. package/dist/commands/index.js.map +1 -1
  80. package/dist/comment-store-BEMgVlAA.d.cts +135 -0
  81. package/dist/comment-store-BEMgVlAA.d.ts +135 -0
  82. package/dist/compare/index.cjs +15 -0
  83. package/dist/compare/index.cjs.map +1 -0
  84. package/dist/compare/index.d.cts +58 -0
  85. package/dist/compare/index.d.ts +58 -0
  86. package/dist/compare/index.js +15 -0
  87. package/dist/compare/index.js.map +1 -0
  88. package/dist/controller-BIJiNoVs.d.cts +1842 -0
  89. package/dist/controller-BIJiNoVs.d.ts +1842 -0
  90. package/dist/documents-CHT1U5Vs.d.ts +86 -0
  91. package/dist/documents-Gp7wb0Me.d.cts +86 -0
  92. package/dist/extensions/index.cjs +100 -5
  93. package/dist/extensions/index.cjs.map +1 -1
  94. package/dist/extensions/index.d.cts +16 -4
  95. package/dist/extensions/index.d.ts +16 -4
  96. package/dist/extensions/index.js +100 -5
  97. package/dist/generation/index.cjs +2317 -0
  98. package/dist/generation/index.cjs.map +1 -0
  99. package/dist/generation/index.d.cts +1015 -0
  100. package/dist/generation/index.d.ts +1015 -0
  101. package/dist/generation/index.js +2317 -0
  102. package/dist/generation/index.js.map +1 -0
  103. package/dist/grammar/index.cjs +48 -3
  104. package/dist/grammar/index.cjs.map +1 -1
  105. package/dist/grammar/index.d.cts +322 -100
  106. package/dist/grammar/index.d.ts +322 -100
  107. package/dist/grammar/index.js +54 -9
  108. package/dist/image-editor/index.cjs +4392 -481
  109. package/dist/image-editor/index.cjs.map +1 -1
  110. package/dist/image-editor/index.d.cts +1249 -97
  111. package/dist/image-editor/index.d.ts +1249 -97
  112. package/dist/image-editor/index.js +4281 -370
  113. package/dist/image-editor/index.js.map +1 -1
  114. package/dist/index-7a6bHTLy.d.ts +1754 -0
  115. package/dist/index-Csd5qI8u.d.cts +1754 -0
  116. package/dist/index.cjs +1682 -99
  117. package/dist/index.cjs.map +1 -1
  118. package/dist/index.d.cts +118 -21
  119. package/dist/index.d.ts +118 -21
  120. package/dist/index.js +1630 -47
  121. package/dist/index.js.map +1 -1
  122. package/dist/mention-text-CDnCFd3c.d.cts +53 -0
  123. package/dist/mention-text-CDnCFd3c.d.ts +53 -0
  124. package/dist/migrate-iTlm3a8h.d.cts +112 -0
  125. package/dist/migrate-iTlm3a8h.d.ts +112 -0
  126. package/dist/model-C1zApQM8.d.cts +219 -0
  127. package/dist/model-C1zApQM8.d.ts +219 -0
  128. package/dist/persistence/index.cjs +676 -0
  129. package/dist/persistence/index.cjs.map +1 -0
  130. package/dist/persistence/index.d.cts +230 -0
  131. package/dist/persistence/index.d.ts +230 -0
  132. package/dist/persistence/index.js +676 -0
  133. package/dist/persistence/index.js.map +1 -0
  134. package/dist/{registry-D5-R90p0.d.cts → registry-BDe-vlv3.d.ts} +2 -40
  135. package/dist/{registry-GJI4gToU.d.ts → registry-CEgwXED1.d.cts} +12 -1
  136. package/dist/{registry-GJI4gToU.d.cts → registry-CEgwXED1.d.ts} +12 -1
  137. package/dist/registry-D32LpIc4.d.cts +354 -0
  138. package/dist/{registry-D5-R90p0.d.ts → registry-DnzpgY27.d.cts} +2 -40
  139. package/dist/registry-evKTP4ls.d.ts +354 -0
  140. package/dist/schema-DYDGdYL9.d.cts +41 -0
  141. package/dist/schema-DYDGdYL9.d.ts +41 -0
  142. package/dist/serializers/index.cjs +12 -3
  143. package/dist/serializers/index.cjs.map +1 -1
  144. package/dist/serializers/index.d.cts +40 -12
  145. package/dist/serializers/index.d.ts +40 -12
  146. package/dist/serializers/index.js +12 -3
  147. package/dist/sourcemap-C8AH3MBQ.d.cts +91 -0
  148. package/dist/sourcemap-DA1Evhrv.d.ts +91 -0
  149. package/dist/spreadsheet/index.cjs +161 -3
  150. package/dist/spreadsheet/index.cjs.map +1 -1
  151. package/dist/spreadsheet/index.d.cts +611 -20
  152. package/dist/spreadsheet/index.d.ts +611 -20
  153. package/dist/spreadsheet/index.js +168 -10
  154. package/dist/storage-BpFfspHm.d.cts +120 -0
  155. package/dist/storage-BpFfspHm.d.ts +120 -0
  156. package/dist/tokens/index.cjs +115 -0
  157. package/dist/tokens/index.cjs.map +1 -0
  158. package/dist/tokens/index.d.cts +212 -0
  159. package/dist/tokens/index.d.ts +212 -0
  160. package/dist/tokens/index.js +115 -0
  161. package/dist/tokens/index.js.map +1 -0
  162. package/dist/{tokens-CyLZmIei.d.cts → tokens-D7yXvUU6.d.cts} +15 -2
  163. package/dist/{tokens-CyLZmIei.d.ts → tokens-D7yXvUU6.d.ts} +15 -2
  164. package/dist/{track-changes-BSF58RK0.d.cts → track-changes-D_VAPELi.d.cts} +110 -144
  165. package/dist/{track-changes-BSF58RK0.d.ts → track-changes-Db_fGEvx.d.ts} +110 -144
  166. package/package.json +21 -1
  167. package/dist/chunk-4SUNJZWB.cjs.map +0 -1
  168. package/dist/chunk-AA4ZEVCC.cjs.map +0 -1
  169. package/dist/chunk-AXV2ZW34.cjs +0 -118
  170. package/dist/chunk-AXV2ZW34.cjs.map +0 -1
  171. package/dist/chunk-B2ZRLN4S.js +0 -118
  172. package/dist/chunk-B2ZRLN4S.js.map +0 -1
  173. package/dist/chunk-GVSMRPHB.cjs.map +0 -1
  174. package/dist/chunk-K3R5NG2D.js +0 -3100
  175. package/dist/chunk-K3R5NG2D.js.map +0 -1
  176. package/dist/chunk-MJZBNWG7.js.map +0 -1
  177. package/dist/chunk-OYXSKQFR.js.map +0 -1
  178. package/dist/chunk-QBJ22YZR.js.map +0 -1
  179. package/dist/chunk-QGHGJ56O.js.map +0 -1
  180. package/dist/chunk-RIKBJLS2.cjs.map +0 -1
  181. package/dist/chunk-XDMXXC4Z.cjs +0 -3100
  182. package/dist/chunk-XDMXXC4Z.cjs.map +0 -1
  183. package/dist/controller-pePCJLT1.d.cts +0 -959
  184. package/dist/controller-pePCJLT1.d.ts +0 -959
  185. package/dist/index-CCr_z9kF.d.cts +0 -899
  186. package/dist/index-Ck6ajwXh.d.ts +0 -899
  187. /package/dist/{chunk-JJDLPEWL.js.map → chunk-QGYDWPRM.js.map} +0 -0
@@ -3,6 +3,7 @@ export { h as CanvasDockingCallbacks, i as CollapseNodeOptions, j as Displacemen
3
3
  import { b as CanvasNodeUpdate, N as NodeRectOptions, A as AlignEdge, c as AlignNodesOptions, D as DistributeAxis, a as DistributeMode, d as DistributeNodesOptions, S as SizeDimension, M as MatchSizeOptions, Z as ZOrderOperation, C as CanvasArrangeAction } from '../arrangeShortcuts-B8O3f8-P.cjs';
4
4
  export { e as ArrangeShortcutBinding, f as DEFAULT_ARRANGE_SHORTCUTS, L as LOCKED_DATA_KEY, g as LOCKED_PREVIOUS_FLAGS_KEY, h as alignNodes, i as applyNodeUpdates, j as createNodeLookup, k as distributeNodes, l as getAbsolutePosition, m as getNodeRect, n as getNodeSize, o as invertNodeUpdates, p as isLocked, q as lockNodes, r as matchArrangeShortcut, s as matchSize, t as readStyleSize, u as reorderNodes, v as toggleLockNodes, w as unlockNodes, x as withStyleSize } from '../arrangeShortcuts-B8O3f8-P.cjs';
5
5
  import { C as Command } from '../types-GT5a5YAX.cjs';
6
+ import { r as TokenType, o as TokenScope, f as TokenLiteral, c as TokenVariable, e as TokenResolution, d as TokenModeContext, T as TokenState } from '../model-C1zApQM8.cjs';
6
7
 
7
8
  declare const DEFAULT_NODE_WIDTH = 200;
8
9
  declare const DEFAULT_NODE_HEIGHT = 60;
@@ -898,6 +899,346 @@ interface PolygonToPathOptions {
898
899
  */
899
900
  declare function polygonToSvgPath(input: MultiPolygon | PolygonRing[], options?: PolygonToPathOptions): string;
900
901
 
902
+ /**
903
+ * Bézier path model shared by the curve-preserving path operations: absolute `M` / `L` /
904
+ * `Q` / `C` / `Z` commands, conversion from SVG path data (arcs become cubics), segment
905
+ * math (evaluation, splitting, extrema, nearest point), exact areas, winding numbers and
906
+ * arc-length utilities.
907
+ */
908
+
909
+ /** One absolute path command. Every subpath starts with `M`; `Z` closes it. */
910
+ type BezierCommand = {
911
+ type: 'M';
912
+ x: number;
913
+ y: number;
914
+ } | {
915
+ type: 'L';
916
+ x: number;
917
+ y: number;
918
+ } | {
919
+ type: 'Q';
920
+ x1: number;
921
+ y1: number;
922
+ x: number;
923
+ y: number;
924
+ } | {
925
+ type: 'C';
926
+ x1: number;
927
+ y1: number;
928
+ x2: number;
929
+ y2: number;
930
+ x: number;
931
+ y: number;
932
+ } | {
933
+ type: 'Z';
934
+ };
935
+ /** A path as a list of absolute move / line / quadratic / cubic / close commands. */
936
+ type BezierPath = BezierCommand[];
937
+ /** Anything the path operations accept as a path: SVG path data, parsed commands or a `BezierPath`. */
938
+ type BezierPathInput = string | readonly BezierCommand[] | readonly PathCommand[];
939
+ /**
940
+ * One segment as its control points: 2 points for a line, 3 for a quadratic and 4 for a
941
+ * cubic Bézier.
942
+ */
943
+ type BezierSegment = readonly Point[];
944
+ /** A subpath as a chain of segments (each starts where the previous one ends). */
945
+ interface BezierContour {
946
+ segments: BezierSegment[];
947
+ closed: boolean;
948
+ }
949
+ /** Point at parameter `t` (de Casteljau, works for any degree). */
950
+ declare function segmentPoint(seg: BezierSegment, t: number): Point;
951
+ /** First derivative at `t`. */
952
+ declare function segmentDerivative(seg: BezierSegment, t: number): Point;
953
+ /**
954
+ * Unit tangent at `t`. Where the derivative vanishes (a handle on its anchor) the direction
955
+ * a hair further along is used, and the chord as the last resort.
956
+ */
957
+ declare function segmentTangent(seg: BezierSegment, t: number): Point;
958
+ /** Signed curvature at `t` (positive when turning counter-clockwise in a y-up frame). */
959
+ declare function segmentCurvature(seg: BezierSegment, t: number): number;
960
+ /** Splits a segment at `t` (de Casteljau). */
961
+ declare function splitSegment(seg: BezierSegment, t: number): [Point[], Point[]];
962
+ /** The part of a segment between parameters `t0` and `t1` (reversed when `t1 < t0`). */
963
+ declare function subSegment(seg: BezierSegment, t0: number, t1: number): Point[];
964
+ /** Parameters in (0, 1) where the segment's `axis` coordinate has a local extremum. */
965
+ declare function segmentExtrema(seg: BezierSegment, axis: 0 | 1): number[];
966
+ /** Exact axis-aligned bounds of a segment. */
967
+ declare function segmentBounds(seg: BezierSegment): {
968
+ minX: number;
969
+ minY: number;
970
+ maxX: number;
971
+ maxY: number;
972
+ };
973
+ /** Arc length of the segment between `t0` and `t1` (default the whole segment). */
974
+ declare function segmentLength(seg: BezierSegment, t0?: number, t1?: number, tolerance?: number): number;
975
+ /** Parameter at arc length `length` from the segment start (clamped to [0, 1]). */
976
+ declare function segmentParamAtLength(seg: BezierSegment, length: number, total?: number): number;
977
+ /**
978
+ * Nearest point of the segment to `p`: the parameter and the distance. Coarse sampling
979
+ * followed by Newton refinement around the best samples.
980
+ */
981
+ declare function segmentNearest(seg: BezierSegment, p: Point): {
982
+ t: number;
983
+ distance: number;
984
+ };
985
+ /** Converts an SVG elliptical arc (SVG 1.1 F.6.5) to cubic segments, at most 90° each. */
986
+ declare function arcToCubics(from: Point, cmd: {
987
+ rx: number;
988
+ ry: number;
989
+ rotation: number;
990
+ largeArc: boolean;
991
+ sweep: boolean;
992
+ x: number;
993
+ y: number;
994
+ }): Point[][];
995
+ /**
996
+ * Converts SVG path data or parsed commands to a `BezierPath` (absolute `M` / `L` / `Q` /
997
+ * `C` / `Z`); elliptical arcs become cubic Béziers (at most 90° each).
998
+ */
999
+ declare function toBezierPath(input: BezierPathInput): BezierPath;
1000
+ /** Splits a path into contours of segments. Zero-length segments are dropped. */
1001
+ declare function pathToContours(input: BezierPathInput): BezierContour[];
1002
+ /** Builds a path from contours (a closed contour's closing line is left to `Z`). */
1003
+ declare function contoursToPath(contours: readonly BezierContour[]): BezierPath;
1004
+ interface BezierPathToSvgOptions {
1005
+ /** Decimal places (default 3). */
1006
+ precision?: number;
1007
+ /** Added to every point before formatting. */
1008
+ offset?: {
1009
+ x: number;
1010
+ y: number;
1011
+ };
1012
+ }
1013
+ /** Writes a path as compact SVG path data. */
1014
+ declare function bezierPathToSvg(input: BezierPathInput, options?: BezierPathToSvgOptions): string;
1015
+ /** 2D affine matrix `[a, b, c, d, e, f]` mapping `(x, y)` to `(a x + c y + e, b x + d y + f)`. */
1016
+ type AffineMatrix = readonly [number, number, number, number, number, number];
1017
+ /** Applies an affine transform to every point (exact for Bézier curves). */
1018
+ declare function transformBezierPath(input: BezierPathInput, m: AffineMatrix): BezierPath;
1019
+ /** Number of drawing segments (`L` / `Q` / `C`, plus the closing line of `Z` when it has length). */
1020
+ declare function countPathSegments(input: BezierPathInput): {
1021
+ lines: number;
1022
+ quads: number;
1023
+ cubics: number;
1024
+ };
1025
+ /** The contour's segments, with the closing line added when the contour is closed (or filled). */
1026
+ declare function closeContour(contour: BezierContour, force?: boolean): BezierSegment[];
1027
+ /** Exact bounds of a path, or `null` when it has no points. */
1028
+ declare function bezierPathBounds(input: BezierPathInput): {
1029
+ minX: number;
1030
+ minY: number;
1031
+ maxX: number;
1032
+ maxY: number;
1033
+ } | null;
1034
+ /**
1035
+ * Signed area of the path as drawn: every subpath closed, contributions summed (positive
1036
+ * for counter-clockwise subpaths in a y-up frame). Exact for curves. Overlapping subpaths
1037
+ * count with their multiplicity; use `bezierPathArea` for the filled area.
1038
+ */
1039
+ declare function bezierPathSignedArea(input: BezierPathInput): number;
1040
+ /** Signed area of a closed chain of segments. */
1041
+ declare function contourSignedArea(segs: readonly BezierSegment[]): number;
1042
+ /** Arc length of a path (closing lines of closed subpaths included). */
1043
+ declare function bezierPathLength(input: BezierPathInput): number;
1044
+ /** Point, unit tangent and angle (radians) at an arc length along the path. */
1045
+ interface PathPointAtLength {
1046
+ point: Point;
1047
+ tangent: Point;
1048
+ angle: number;
1049
+ /** Subpath index. */
1050
+ contour: number;
1051
+ /** Segment index within the subpath (closing line last). */
1052
+ segment: number;
1053
+ /** Parameter within the segment. */
1054
+ t: number;
1055
+ }
1056
+ /**
1057
+ * The point at arc length `length` from the start of the path (clamped to the path). Arc
1058
+ * lengths run through the subpaths in order, as `bezierPathLength` counts them.
1059
+ */
1060
+ declare function bezierPathPointAtLength(input: BezierPathInput, length: number): PathPointAtLength | null;
1061
+ /**
1062
+ * Splits a segment chain by arc length: the part between `from` and `to` (measured from the
1063
+ * chain's start) as new segments.
1064
+ */
1065
+ declare function trimSegments(segs: readonly BezierSegment[], from: number, to: number, lengths?: number[]): Point[][];
1066
+ /**
1067
+ * Winding number of a set of closed segment chains around `point` (ray to +x, half-open
1068
+ * crossing rule). Points exactly on the outline may report either side.
1069
+ */
1070
+ declare function windingNumber(chains: readonly (readonly BezierSegment[])[], point: Point): number;
1071
+ /** Whether `point` is inside the filled path (every subpath closed for filling). */
1072
+ declare function pointInBezierPath(input: BezierPathInput, point: Point, fillRule?: PolygonFillRule): boolean;
1073
+ /** Distance from `point` to the path outline (closing lines of closed subpaths included). */
1074
+ declare function distanceToBezierPath(input: BezierPathInput | readonly BezierContour[], point: Point): number;
1075
+
1076
+ /** Boolean operations (same names as `polygonBoolean`). `xor` is Exclude. */
1077
+ type PathBooleanOperation = PolygonBooleanOperation;
1078
+ /** A path with the fill rule it is read with (default `nonzero`). */
1079
+ interface PathOperand {
1080
+ path: BezierPathInput;
1081
+ fillRule?: PolygonFillRule;
1082
+ }
1083
+ type PathOperandInput = BezierPathInput | PathOperand;
1084
+ interface PathOpsOptions {
1085
+ /**
1086
+ * Distance below which points are treated as equal. Defaults to `1e-9` times the
1087
+ * largest coordinate magnitude (at least `1e-9`).
1088
+ */
1089
+ epsilon?: number;
1090
+ /** Fall back to the polygon engine when the curve engine fails (default `true`). */
1091
+ fallback?: boolean;
1092
+ /** Flattening tolerance used by the polygon fallback (default 0.05). */
1093
+ fallbackTolerance?: number;
1094
+ /** Called with the reason whenever the polygon fallback is used. */
1095
+ onFallback?: (reason: string) => void;
1096
+ /**
1097
+ * Work budget of the curve–curve intersection search (flat sub-curve pairs per pair of
1098
+ * pieces, default 20,000). Exceeding it (nearly coincident curves) falls back.
1099
+ */
1100
+ subdivisionBudget?: number;
1101
+ }
1102
+ /** Which engine produced a result, and why the curve engine was not used. */
1103
+ interface PathOpsReport {
1104
+ engine: 'curve' | 'polygon';
1105
+ fallbackReason?: string;
1106
+ /** Set when the input cannot be processed at all (non-finite coordinates); the result is empty. */
1107
+ error?: string;
1108
+ }
1109
+ interface PathBooleanResult extends PathOpsReport {
1110
+ path: BezierPath;
1111
+ }
1112
+ /** One region of `dividePaths`, with the indices of the operands that cover it. */
1113
+ interface PathPiece {
1114
+ path: BezierPath;
1115
+ operands: number[];
1116
+ }
1117
+ interface DividePathsResult extends PathOpsReport {
1118
+ pieces: PathPiece[];
1119
+ }
1120
+ /** Raised by the curve engine when it cannot produce a reliable arrangement. */
1121
+ declare class PathOpsError extends Error {
1122
+ constructor(message: string);
1123
+ }
1124
+ /**
1125
+ * Applies a boolean operation to any number of path operands, keeping curves:
1126
+ * - `union`: covered by any operand.
1127
+ * - `intersection`: covered by every operand.
1128
+ * - `difference`: the first operand minus all others.
1129
+ * - `xor`: covered by an odd number of operands (Exclude).
1130
+ *
1131
+ * Open subpaths are closed for filling. Non-finite input gives an empty path (`error`); with
1132
+ * `fallback: false` a failure of the curve engine throws a `PathOpsError`. The result is a set of simple closed subpaths that
1133
+ * never cross (they may touch at points): outer subpaths run counter-clockwise in a y-up
1134
+ * frame (clockwise on screen), holes the other way, so it fills the same with `nonzero`
1135
+ * and `evenodd`. Segments of the inputs are kept as exact sub-curves.
1136
+ */
1137
+ declare function pathBoolean(operation: PathBooleanOperation, operands: PathOperandInput[], options?: PathOpsOptions): PathBooleanResult;
1138
+ declare const unitePaths: (a: PathOperandInput, b: PathOperandInput, options?: PathOpsOptions) => BezierPath;
1139
+ declare const intersectPaths: (a: PathOperandInput, b: PathOperandInput, options?: PathOpsOptions) => BezierPath;
1140
+ declare const subtractPaths: (a: PathOperandInput, b: PathOperandInput, options?: PathOpsOptions) => BezierPath;
1141
+ declare const excludePaths: (a: PathOperandInput, b: PathOperandInput, options?: PathOpsOptions) => BezierPath;
1142
+ /**
1143
+ * Splits the arrangement of the operands into its regions (Divide): every connected area
1144
+ * covered by the same set of operands becomes one piece (an outer subpath with its holes).
1145
+ * Pieces are ordered by operand set, then by area (largest first).
1146
+ */
1147
+ declare function dividePaths(operands: PathOperandInput[], options?: PathOpsOptions): DividePathsResult;
1148
+ /**
1149
+ * Resolves self-intersections and overlaps of one filled path into simple, consistently
1150
+ * oriented subpaths (outer subpaths and holes) under its fill rule.
1151
+ */
1152
+ declare function normalizeBezierPath(path: BezierPathInput, fillRule?: PolygonFillRule, options?: PathOpsOptions): BezierPath;
1153
+ /** Filled area of a path under its fill rule (overlaps counted once; exact for curves). */
1154
+ declare function bezierPathArea(path: BezierPathInput, fillRule?: PolygonFillRule, options?: PathOpsOptions): number;
1155
+
1156
+ /**
1157
+ * Offset Path and Outline Stroke on Bézier paths.
1158
+ *
1159
+ * The stroker offsets every segment by ± half the width (lines exactly, curves by cubic
1160
+ * approximations refined until they stay within `tolerance` of the true offset), joins the
1161
+ * pieces (miter with a miter limit, round or bevel on the outer side of a turn; through the
1162
+ * vertex on the inner side) and adds caps (butt, round, square) to open subpaths. Dashes
1163
+ * follow arc length, restart on every subpath and join across the start of a closed
1164
+ * subpath. The raw outline overlaps itself, so it is filled with the non-zero rule and
1165
+ * normalised with the curve boolean engine.
1166
+ *
1167
+ * When the stroke is wider than a curve's radius of curvature the inner offset turns inside
1168
+ * out and its loops cancel winding, leaving holes that are really covered. Every face of
1169
+ * the true result is bounded by the arrangement, so a face is spurious exactly when a point
1170
+ * deep inside it is closer to the path than the offset distance (holes when growing,
1171
+ * islands when insetting); such faces are dropped.
1172
+ *
1173
+ * Portions ported from vectorcraft-main/crates/pathops/src/offset.rs,
1174
+ * vectorcraft-main/crates/pathops/src/boolean.rs (`try_merge`) and
1175
+ * vectorcraft-main/crates/effects/src/stroke/dash.rs (MIT OR Apache-2.0, © ArtCraft Team
1176
+ * and contributors). See THIRD_PARTY_NOTICES.md.
1177
+ */
1178
+
1179
+ /** Line join (as SVG `stroke-linejoin`). */
1180
+ type StrokeJoin = 'miter' | 'round' | 'bevel';
1181
+ /** Line cap (as SVG `stroke-linecap`). */
1182
+ type StrokeCap = 'butt' | 'round' | 'square';
1183
+ interface OutlineStrokeOptions extends PathOpsOptions {
1184
+ /** Stroke width. Non-positive or non-finite widths give an empty result. */
1185
+ width: number;
1186
+ /** Default `miter` (as SVG). */
1187
+ join?: StrokeJoin;
1188
+ /** Default `butt` (as SVG). */
1189
+ cap?: StrokeCap;
1190
+ /** Miter length / stroke width above which a miter join is bevelled (default 4, as SVG). */
1191
+ miterLimit?: number;
1192
+ /** Dash pattern (as SVG `stroke-dasharray`); odd patterns repeat twice. */
1193
+ dash?: readonly number[];
1194
+ /** Distance into the dash pattern at the start of each subpath (as `stroke-dashoffset`). */
1195
+ dashOffset?: number;
1196
+ /** Maximum distance between the approximated and the true offset curve (default 0.01). */
1197
+ tolerance?: number;
1198
+ }
1199
+ interface OffsetPathOptions extends PathOpsOptions {
1200
+ /** Corner style of the grown / shrunk outline (default `miter`). */
1201
+ join?: StrokeJoin;
1202
+ /** Miter limit (default 4). */
1203
+ miterLimit?: number;
1204
+ /** Fill rule of the input (default `nonzero`). */
1205
+ fillRule?: PolygonFillRule;
1206
+ /** Maximum distance between the approximated and the true offset curve (default 0.01). */
1207
+ tolerance?: number;
1208
+ }
1209
+ interface DashedPath {
1210
+ /** The dashes, as open subpaths. */
1211
+ contours: BezierContour[];
1212
+ /** Zero-length dashes: where they sit and the path direction there. */
1213
+ dots: {
1214
+ point: Point;
1215
+ tangent: Point;
1216
+ }[];
1217
+ }
1218
+ /**
1219
+ * Applies a dash pattern (SVG `stroke-dasharray` / `stroke-dashoffset` semantics) to the
1220
+ * subpaths. Returns `null` when the pattern is invalid (negative or non-finite entries),
1221
+ * has no positive entry, or would make more than 200,000 dashes: the line is solid.
1222
+ */
1223
+ declare function dashContours(contours: readonly BezierContour[], pattern: readonly number[], offset?: number): DashedPath | null;
1224
+ /**
1225
+ * The raw (overlapping) outline of a stroke as closed subpaths to fill with `nonzero`.
1226
+ * `outlineStroke` normalises it; this is useful for previews.
1227
+ */
1228
+ declare function strokeOutlineRings(input: BezierPathInput, options: OutlineStrokeOptions): BezierPath;
1229
+ /**
1230
+ * Outline Stroke: the filled area painted by stroking `path`, as one clean path (overlaps
1231
+ * removed, consistently oriented). Joins, caps, miter limit and dashes follow SVG.
1232
+ */
1233
+ declare function outlineStroke(input: BezierPathInput, options: OutlineStrokeOptions): BezierPath;
1234
+ /**
1235
+ * Offset Path: grows (`distance > 0`) or shrinks (`distance < 0`) the filled area by
1236
+ * `distance`. Closed subpaths are a filled region (read with `fillRule`); open subpaths are
1237
+ * outlined with a stroke of width `2·|distance|` and butt caps (when growing). Loops of the
1238
+ * offset curves are removed.
1239
+ */
1240
+ declare function offsetPath(input: BezierPathInput, distance: number, options?: OffsetPathOptions): BezierPath;
1241
+
901
1242
  /**
902
1243
  * Shape nodes and Freeform-style shape boolean operations (Unite / Intersect / Subtract /
903
1244
  * Exclude / Divide) on canvas nodes.
@@ -929,6 +1270,22 @@ declare function shapeNodeToPolygon(node: CanvasNode, lookup?: ReadonlyMap<strin
929
1270
  rings: PolygonRing[];
930
1271
  fillRule: PolygonFillRule;
931
1272
  } | null;
1273
+ /**
1274
+ * A shape as an exact Bézier path in node-local pixels (rotation and path view boxes
1275
+ * applied; arcs become cubics), with the fill rule it is read with.
1276
+ */
1277
+ declare function shapeToBezierPath(shape: ShapeDescription, size: ShapeSize): {
1278
+ path: BezierPath;
1279
+ fillRule: PolygonFillRule;
1280
+ };
1281
+ /**
1282
+ * A shape node's outline as an exact Bézier path in absolute flow coordinates (parent
1283
+ * offsets, size and rotation applied), or `null` for non-shape nodes.
1284
+ */
1285
+ declare function shapeNodeToBezierPath(node: CanvasNode, lookup?: ReadonlyMap<string, CanvasNode>, options?: NodeRectOptions): {
1286
+ path: BezierPath;
1287
+ fillRule: PolygonFillRule;
1288
+ } | null;
932
1289
  /** Why `combineShapeNodes` refused. */
933
1290
  type CombineShapeNodesRefusal =
934
1291
  /** A selected shape is locked; locked shapes are never consumed. */
@@ -955,9 +1312,20 @@ interface CombineShapeNodesOptions extends ShapeNodePolygonOptions {
955
1312
  /** Ramer–Douglas–Peucker simplification tolerance for the result (default 0, off). */
956
1313
  simplify?: number;
957
1314
  /**
958
- * How the result's outline is written: `'fit'` (default) fits smooth cubic curves to the
959
- * flattened result, so booleans of curved shapes stay curved (sharp corners and straight
960
- * edges are kept); `'lines'` writes the polygon as straight segments.
1315
+ * Geometry engine. `'curve'` (default) computes the operation on the exact Bézier
1316
+ * outlines and keeps the inputs' curves (circles stay cubic arcs, rectangles stay four
1317
+ * lines); it falls back to `'polygon'` when it cannot resolve the input (reported as
1318
+ * `engine` / `fallbackReason` on the result). `'polygon'` flattens the shapes and uses
1319
+ * `polygonBoolean` (the behaviour before curve booleans). `curves: 'lines'` implies
1320
+ * `'polygon'` unless an engine is named.
1321
+ */
1322
+ engine?: 'curve' | 'polygon';
1323
+ /** Called with the reason when the curve engine falls back to polygons. */
1324
+ onFallback?: (reason: string) => void;
1325
+ /**
1326
+ * Polygon engine only: how the result's outline is written: `'fit'` (default) fits
1327
+ * smooth cubic curves to the flattened result (sharp corners and straight edges are
1328
+ * kept); `'lines'` writes the polygon as straight segments.
961
1329
  */
962
1330
  curves?: 'lines' | 'fit';
963
1331
  /** Curve-fitting tolerance in flow units for `curves: 'fit'` (default: `tolerance`, 0.25). */
@@ -976,6 +1344,10 @@ type CombineShapeNodesResult<TNode extends CanvasNode = CanvasNode> = {
976
1344
  removeIds: string[];
977
1345
  /** New path shape node(s): one, or one per region for `divide`. */
978
1346
  nodes: TNode[];
1347
+ /** Engine that produced the geometry (`polygon` after a fallback). */
1348
+ engine: 'curve' | 'polygon';
1349
+ /** Why the curve engine fell back to polygons. */
1350
+ fallbackReason?: string;
979
1351
  } | {
980
1352
  ok: false;
981
1353
  operation: ShapeOperation;
@@ -1029,6 +1401,129 @@ declare function revertShapeCombination<TNode extends CanvasNode>(nodes: TNode[]
1029
1401
  removeIds: Iterable<string>;
1030
1402
  nodes: TNode[];
1031
1403
  }, previous: TNode[]): TNode[];
1404
+ /** Per-node path edits: `offset` (Offset Path) and `outlineStroke` (Outline Stroke). */
1405
+ type ShapePathEditOperation = 'offset' | 'outlineStroke';
1406
+ /** Why `offsetShapeNodes` / `outlineShapeNodeStrokes` refused. */
1407
+ type ShapePathEditRefusal =
1408
+ /** A selected shape is locked. */
1409
+ 'locked'
1410
+ /** No shape node was selected. */
1411
+ | 'no-shapes'
1412
+ /** Outline Stroke: no selected shape has a visible stroke. */
1413
+ | 'no-stroke'
1414
+ /** Every result is empty (e.g. an inset larger than the shapes). */
1415
+ | 'empty'
1416
+ /** The offset distance or stroke width is not a finite number. */
1417
+ | 'invalid';
1418
+ type ShapePathEditResult<TNode extends CanvasNode = CanvasNode> = {
1419
+ ok: true;
1420
+ operation: ShapePathEditOperation;
1421
+ /** Ids of the replaced nodes. */
1422
+ removeIds: string[];
1423
+ /** All new nodes (a replaced node may come back with the same id). */
1424
+ nodes: TNode[];
1425
+ /** Each replaced node with the nodes that take its place, in stacking order. */
1426
+ replacements: {
1427
+ id: string;
1428
+ nodes: TNode[];
1429
+ }[];
1430
+ } | {
1431
+ ok: false;
1432
+ operation: ShapePathEditOperation;
1433
+ reason: ShapePathEditRefusal;
1434
+ };
1435
+ interface ShapePathEditBaseOptions extends NodeRectOptions {
1436
+ /** Id factory for new nodes (default `crypto.randomUUID`, with a counter fallback). */
1437
+ createId?: (index: number) => string;
1438
+ /** Node `type` for the new nodes (default: the source node's type). */
1439
+ nodeType?: string;
1440
+ /** Decimal places in the path data (default 3). */
1441
+ precision?: number;
1442
+ /** Select the new nodes (default `true`). */
1443
+ select?: boolean;
1444
+ /** Maximum error of the approximated offset curves in flow units (default 0.01). */
1445
+ tolerance?: number;
1446
+ /** Point-merge tolerance passed to the boolean engine. */
1447
+ epsilon?: number;
1448
+ /** Called with the reason when the curve engine falls back to polygons. */
1449
+ onFallback?: (reason: string) => void;
1450
+ }
1451
+ interface OffsetShapeNodesOptions extends ShapePathEditBaseOptions {
1452
+ /** Corner style of the offset outline (default `miter`). */
1453
+ join?: StrokeJoin;
1454
+ /** Miter limit (default 4). */
1455
+ miterLimit?: number;
1456
+ /** Keep the original shape above the offset one (Illustrator style; default `false`: replace it). */
1457
+ keepOriginal?: boolean;
1458
+ }
1459
+ interface OutlineShapeStrokesOptions extends ShapePathEditBaseOptions {
1460
+ /** Stroke width in flow units (default: the shape's `strokeWidth`, 1 when unset). */
1461
+ width?: number;
1462
+ /** Default `miter`, as SVG. */
1463
+ join?: StrokeJoin;
1464
+ /** Default `butt`, as SVG. */
1465
+ cap?: StrokeCap;
1466
+ /** Default 4, as SVG. */
1467
+ miterLimit?: number;
1468
+ /** Dash pattern (as `stroke-dasharray`). */
1469
+ dash?: readonly number[];
1470
+ dashOffset?: number;
1471
+ /**
1472
+ * Keep the shape's fill as the original node with its stroke removed, below the outlined
1473
+ * stroke (default `true`). With `false`, or when the shape has no visible fill, the node is
1474
+ * replaced by the outlined stroke alone.
1475
+ */
1476
+ keepFill?: boolean;
1477
+ }
1478
+ /** Whether a shape draws a stroke (a stroke colour other than `none` and a positive width). */
1479
+ declare function hasVisibleStroke(shape: ShapeDescription | null): boolean;
1480
+ /** Checks whether `offsetShapeNodes` can run (it cannot predict an `empty` result). */
1481
+ declare function canOffsetShapeNodes(nodes: CanvasNode[], ids: Iterable<string>): {
1482
+ ok: true;
1483
+ shapeIds: string[];
1484
+ } | {
1485
+ ok: false;
1486
+ reason: 'locked' | 'no-shapes';
1487
+ };
1488
+ /** Checks whether `outlineShapeNodeStrokes` can run. */
1489
+ declare function canOutlineShapeNodeStrokes(nodes: CanvasNode[], ids: Iterable<string>): {
1490
+ ok: true;
1491
+ shapeIds: string[];
1492
+ } | {
1493
+ ok: false;
1494
+ reason: 'locked' | 'no-shapes' | 'no-stroke';
1495
+ };
1496
+ /**
1497
+ * Offset Path on shape nodes: each selected shape grows (`distance > 0`) or shrinks
1498
+ * (`distance < 0`) by `distance` flow units, keeping curves. The result replaces the shape
1499
+ * (or sits below it with `keepOriginal`) as a `path` shape node with the same paint. Shapes
1500
+ * whose offset is empty are left unchanged; refuses when every result is empty, a selected
1501
+ * shape is locked or no shape is selected. Pure: apply with `applyShapeReplacement`.
1502
+ */
1503
+ declare function offsetShapeNodes<TNode extends CanvasNode>(nodes: TNode[], ids: Iterable<string>, distance: number, options?: OffsetShapeNodesOptions): ShapePathEditResult<TNode>;
1504
+ /**
1505
+ * Outline Stroke on shape nodes: each selected shape with a visible stroke gets its stroke
1506
+ * converted to a filled `path` shape node (filled with the stroke colour, no stroke), using
1507
+ * the stroke width in flow units (strokes do not scale with the node) and SVG's default
1508
+ * miter join, miter limit 4 and butt caps unless overridden. The shape's fill stays as the
1509
+ * original node without its stroke, below the outline (`keepFill`). Pure: apply with
1510
+ * `applyShapeReplacement`.
1511
+ */
1512
+ declare function outlineShapeNodeStrokes<TNode extends CanvasNode>(nodes: TNode[], ids: Iterable<string>, options?: OutlineShapeStrokesOptions): ShapePathEditResult<TNode>;
1513
+ /**
1514
+ * Applies a successful `offsetShapeNodes` / `outlineShapeNodeStrokes` result: each replaced
1515
+ * node is swapped in place for its replacement nodes, so the stacking order of everything
1516
+ * else is kept. With `deselect` (default `true`) other nodes are deselected when the
1517
+ * result is selected. Undo with `revertShapeCombination(nodes, result, previous)`.
1518
+ */
1519
+ declare function applyShapeReplacement<TNode extends CanvasNode>(nodes: TNode[], change: {
1520
+ replacements: {
1521
+ id: string;
1522
+ nodes: TNode[];
1523
+ }[];
1524
+ }, options?: {
1525
+ deselect?: boolean;
1526
+ }): TNode[];
1032
1527
 
1033
1528
  /** A resize handle, named like xyflow's `ControlPosition`. */
1034
1529
  type ResizeHandle = 'top-left' | 'top' | 'top-right' | 'right' | 'bottom-right' | 'bottom' | 'bottom-left' | 'left';
@@ -1100,6 +1595,214 @@ declare function snapNodeResize(nodes: CanvasNode[], id: string, rect: Rect, han
1100
1595
  */
1101
1596
  declare function getResizingNodeRect(node: CanvasNode, lookup: ReadonlyMap<string, CanvasNode>, options?: NodeRectOptions): Rect;
1102
1597
 
1598
+ /**
1599
+ * Figma-style auto layout for xyflow sub-flows.
1600
+ *
1601
+ * A *frame* is any node with `data.layout` (an {@link AutoLayout}); its children are the nodes
1602
+ * whose `parentId` is the frame, in node-array order. Children may carry `data.childLayout`
1603
+ * (an {@link AutoLayoutChild}) for their own sizing, min / max, absolute positioning,
1604
+ * constraints and grid cell. The functions here are pure: they return `CanvasNodeUpdate`s
1605
+ * (positions relative to the parent, sizes) for `applyNodeUpdates`.
1606
+ */
1607
+ /** Data key holding a frame's {@link AutoLayout}. */
1608
+ declare const AUTO_LAYOUT_DATA_KEY = "layout";
1609
+ /** Data key holding a child's {@link AutoLayoutChild}. */
1610
+ declare const CHILD_LAYOUT_DATA_KEY = "childLayout";
1611
+ type AutoLayoutMode = 'horizontal' | 'vertical' | 'grid';
1612
+ /** `fixed` keeps the size, `hug` fits the content (frames and text), `fill` shares the parent's free space. */
1613
+ type AutoLayoutSizing = 'fixed' | 'hug' | 'fill';
1614
+ type AutoLayoutAlignMain = 'start' | 'center' | 'end' | 'space-between' | 'space-around' | 'space-evenly';
1615
+ type AutoLayoutAlignCross = 'start' | 'center' | 'end' | 'stretch' | 'baseline';
1616
+ /** How wrapped lines share the free cross space: packed by `alignCross` (`auto`) or spread (`space-between`). */
1617
+ type AutoLayoutAlignContent = 'auto' | 'space-between';
1618
+ /** `number` (all sides), `[vertical, horizontal]`, `[top, right, bottom, left]` or per side. */
1619
+ type AutoLayoutPadding = number | [number, number] | [number, number, number, number] | {
1620
+ top?: number;
1621
+ right?: number;
1622
+ bottom?: number;
1623
+ left?: number;
1624
+ };
1625
+ interface AutoLayoutSize {
1626
+ width?: number;
1627
+ height?: number;
1628
+ }
1629
+ interface AutoLayoutSizingPair {
1630
+ width?: AutoLayoutSizing;
1631
+ height?: AutoLayoutSizing;
1632
+ }
1633
+ /** A grid track: pixels, `'hug'` (fits its content), `'2fr'` or `{ fr: 2 }` (shares the rest like CSS `fr`). */
1634
+ type AutoLayoutGridTrack = number | 'hug' | `${number}fr` | {
1635
+ fr: number;
1636
+ };
1637
+ interface AutoLayoutGrid {
1638
+ /** Column count (all `1fr`) or the column tracks (default 2 columns). */
1639
+ columns?: number | AutoLayoutGridTrack[];
1640
+ /** Minimum row count or the row tracks (default 1); rows are added to fit the children. Missing tracks are `1fr`. */
1641
+ rows?: number | AutoLayoutGridTrack[];
1642
+ }
1643
+ /** A frame's auto layout (`node.data.layout`). */
1644
+ interface AutoLayout {
1645
+ mode: AutoLayoutMode;
1646
+ /** Main-axis gap (grid: column gap). Negative gaps overlap. Default 0. */
1647
+ gap?: number;
1648
+ /** Gap between wrapped lines (grid: row gap). Default: `gap`. */
1649
+ rowGap?: number;
1650
+ /** Default 0. */
1651
+ padding?: AutoLayoutPadding;
1652
+ /** Horizontal / vertical: wrap into lines when the main axis runs out (ignored while hugging it). */
1653
+ wrap?: boolean;
1654
+ /** Default `start`. Grid: the cell alignment along x (`start`, `center`, `end`). */
1655
+ alignMain?: AutoLayoutAlignMain;
1656
+ /** Default `start`. `baseline` applies to horizontal layouts. Grid: the cell alignment along y. */
1657
+ alignCross?: AutoLayoutAlignCross;
1658
+ alignContent?: AutoLayoutAlignContent;
1659
+ /** The frame's own sizing (`childLayout.sizing` wins when both are set). Default `fixed`. */
1660
+ sizing?: AutoLayoutSizingPair;
1661
+ /** The frame's own limits (`childLayout.min` / `max` win when set). */
1662
+ min?: AutoLayoutSize;
1663
+ max?: AutoLayoutSize;
1664
+ grid?: AutoLayoutGrid;
1665
+ }
1666
+ type AutoLayoutHorizontalConstraint = 'left' | 'right' | 'leftRight' | 'center' | 'scale';
1667
+ type AutoLayoutVerticalConstraint = 'top' | 'bottom' | 'topBottom' | 'center' | 'scale';
1668
+ interface AutoLayoutConstraints {
1669
+ horizontal?: AutoLayoutHorizontalConstraint;
1670
+ vertical?: AutoLayoutVerticalConstraint;
1671
+ }
1672
+ type AutoLayoutCellAlign = 'start' | 'center' | 'end';
1673
+ /** A grid child's cell. Column / row are 0-based anchors; unanchored children flow in reading order. */
1674
+ interface AutoLayoutGridArea {
1675
+ column?: number;
1676
+ row?: number;
1677
+ columnSpan?: number;
1678
+ rowSpan?: number;
1679
+ /** The child's own alignment in its cell (wins over the frame's). */
1680
+ alignX?: AutoLayoutCellAlign;
1681
+ alignY?: AutoLayoutCellAlign;
1682
+ }
1683
+ /** A child's layout properties (`node.data.childLayout`). */
1684
+ interface AutoLayoutChild {
1685
+ sizing?: AutoLayoutSizingPair;
1686
+ min?: AutoLayoutSize;
1687
+ max?: AutoLayoutSize;
1688
+ /** Ignore auto layout: keep its place and follow `constraints` when the frame resizes. */
1689
+ absolute?: boolean;
1690
+ /** How the child follows its parent's resizes (default left / top). */
1691
+ constraints?: AutoLayoutConstraints;
1692
+ gridArea?: AutoLayoutGridArea;
1693
+ }
1694
+ /**
1695
+ * Measuring hooks. `size` defaults to `getNodeSize` (xyflow `measured` size, then `width` /
1696
+ * `height`, then style). Nodes for which `textSize` returns a size are *text-like*: they can
1697
+ * hug, and wrap (`textHeight`) when their width is set by the layout.
1698
+ */
1699
+ interface AutoLayoutMeasure {
1700
+ size?: (node: CanvasNode) => {
1701
+ width: number;
1702
+ height: number;
1703
+ } | undefined;
1704
+ /** Natural (unwrapped) size of a text-like node. */
1705
+ textSize?: (node: CanvasNode) => {
1706
+ width: number;
1707
+ height: number;
1708
+ } | undefined;
1709
+ /** Height of a text-like node wrapped at `width`. */
1710
+ textHeight?: (node: CanvasNode, width: number) => number | undefined;
1711
+ /** Distance from the node's top to its first text baseline (for `alignCross: 'baseline'`). */
1712
+ textBaseline?: (node: CanvasNode) => number | undefined;
1713
+ }
1714
+ interface AutoLayoutOptions {
1715
+ measure?: AutoLayoutMeasure;
1716
+ /** Size resolution for unmeasured nodes when `measure.size` is not given. */
1717
+ rectOptions?: NodeRectOptions;
1718
+ }
1719
+ type Axis = 'width' | 'height';
1720
+ /** Clamps a size to `[min, max]`; non-finite or negative sizes become 0 and min wins over a smaller max. */
1721
+ declare function clampLayoutSize(value: number, min?: number, max?: number): number;
1722
+ /** The node's auto layout, or `undefined` when it is not an auto layout frame. */
1723
+ declare function getAutoLayout(node: CanvasNode | undefined | null): AutoLayout | undefined;
1724
+ /** Whether the node is an auto layout frame. */
1725
+ declare function isAutoLayoutFrame(node: CanvasNode | undefined | null): boolean;
1726
+ /** The node's child layout properties (empty when unset). */
1727
+ declare function getChildLayout(node: CanvasNode | undefined | null): AutoLayoutChild;
1728
+ /** Effective sizing of a node on one axis: `childLayout.sizing`, then `layout.sizing`, then `fixed`. */
1729
+ declare function getLayoutSizing(node: CanvasNode, axis: Axis): AutoLayoutSizing;
1730
+ /** Padding as `[top, right, bottom, left]`, sanitised (non-finite and negative values become 0). */
1731
+ declare function resolvePadding(padding: AutoLayoutPadding | undefined): [number, number, number, number];
1732
+ /** A grid child's cell (0-based column / row and spans). */
1733
+ interface AutoLayoutGridCell {
1734
+ id: string;
1735
+ column: number;
1736
+ row: number;
1737
+ columnSpan: number;
1738
+ rowSpan: number;
1739
+ }
1740
+ /** A grid frame's resolved geometry (frame-local): column x ranges, row y ranges, cells and the size it wants. */
1741
+ interface AutoLayoutGridGeometry {
1742
+ columns: [number, number][];
1743
+ rows: [number, number][];
1744
+ cells: AutoLayoutGridCell[];
1745
+ width: number;
1746
+ height: number;
1747
+ }
1748
+ /**
1749
+ * Lays out one auto layout frame's children and sizes the frame when it hugs (nested frames
1750
+ * that are resized by the layout are laid out again). Returns the position / size updates.
1751
+ */
1752
+ declare function layoutFrame(nodes: CanvasNode[], frameId: string, options?: AutoLayoutOptions): CanvasNodeUpdate[];
1753
+ /** Lays out every auto layout frame, children before parents, so nested hugging settles in one pass. */
1754
+ declare function layoutAll(nodes: CanvasNode[], options?: AutoLayoutOptions): CanvasNodeUpdate[];
1755
+ /**
1756
+ * Lays out `changedId` (when it is a frame) and then each of its auto layout ancestors,
1757
+ * innermost first. Use it after a node inside a frame was added, removed, resized or moved.
1758
+ */
1759
+ declare function layoutUp(nodes: CanvasNode[], changedId: string, options?: AutoLayoutOptions): CanvasNodeUpdate[];
1760
+ /** {@link layoutUp} for several changed nodes at once (each chain once, innermost frames first). */
1761
+ declare function layoutUpMany(nodes: CanvasNode[], changedIds: Iterable<string>, options?: AutoLayoutOptions): CanvasNodeUpdate[];
1762
+ /**
1763
+ * Children of `parentId` follow their constraints after the parent was resized from
1764
+ * `previousSize` to its current size. In an auto layout frame only absolute children move
1765
+ * (the layout places the others). Returns the updates.
1766
+ */
1767
+ declare function applyConstraints(nodes: CanvasNode[], parentId: string, previousSize: {
1768
+ width: number;
1769
+ height: number;
1770
+ }, options?: AutoLayoutOptions): CanvasNodeUpdate[];
1771
+ /** The resolved grid of a grid frame (frame-local), from its children's current sizes. */
1772
+ declare function getAutoLayoutGrid(nodes: CanvasNode[], frameId: string, options?: AutoLayoutOptions): AutoLayoutGridGeometry | undefined;
1773
+ /** Ids of the children a frame places (visible, not absolute), in order. */
1774
+ declare function getFlowChildren(nodes: CanvasNode[], frameId: string): string[];
1775
+ /** The nearest auto layout frame that places `id` (its parent, when `id` is a flow child). */
1776
+ declare function getLayoutParent(nodes: CanvasNode[], id: string): CanvasNode | undefined;
1777
+ /**
1778
+ * Makes a node's sizing coherent with where it sits, and that of its children: `fill` needs an
1779
+ * auto layout parent that does not hug that axis (and a flow child), `hug` needs an auto layout
1780
+ * frame or a text-like node (see `measure.textSize`); otherwise the axis becomes `fixed`.
1781
+ * Writes `data.childLayout.sizing`. Returns a new array (unchanged nodes keep their identity).
1782
+ */
1783
+ declare function makeSizingCoherent<TNode extends CanvasNode>(nodes: TNode[], id: string, options?: AutoLayoutOptions): TNode[];
1784
+ interface AutoLayoutInsertTarget {
1785
+ frameId: string;
1786
+ /** Index among the frame's flow children, not counting the dragged node. */
1787
+ index: number;
1788
+ /** Insertion marker (absolute flow coordinates) for `<CanvasGuidesLayer>`. */
1789
+ guide: GuideLine;
1790
+ }
1791
+ /**
1792
+ * Where a node dropped at `point` (absolute flow coordinates) goes among the flow children of
1793
+ * auto layout frame `frameId`: the reading-order index of the slot under the point. `excludeId`
1794
+ * (the dragged node) is left out of the siblings.
1795
+ */
1796
+ declare function getAutoLayoutInsertTarget(nodes: CanvasNode[], frameId: string, point: XYPosition, options?: AutoLayoutOptions & {
1797
+ excludeId?: string;
1798
+ }): AutoLayoutInsertTarget | undefined;
1799
+ /**
1800
+ * Moves child `childId` of an auto layout frame to flow index `index` (among its flow siblings)
1801
+ * by reordering the node array; parents still precede their children. Returns a new array
1802
+ * (the same array when nothing moves).
1803
+ */
1804
+ declare function moveLayoutChild<TNode extends CanvasNode>(nodes: TNode[], childId: string, index: number): TNode[];
1805
+
1103
1806
  /** Minimal history surface (`HistoryManager` satisfies it). */
1104
1807
  interface ArrangeHistoryTarget {
1105
1808
  execute(command: Command): void;
@@ -1129,6 +1832,11 @@ interface CanvasArrangeControllerOptions<TNode extends CanvasNode = CanvasNode>
1129
1832
  rectOptions?: NodeRectOptions;
1130
1833
  /** Called whenever the guide segments change (set while dragging, cleared on drop). */
1131
1834
  onGuidesChange?: (guides: GuideLine[]) => void;
1835
+ /**
1836
+ * Re-run auto layout (`data.layout` frames) around the nodes an arrange action moves or
1837
+ * resizes, in the same undoable step. `true` uses the default measuring.
1838
+ */
1839
+ autoLayout?: boolean | AutoLayoutOptions;
1132
1840
  }
1133
1841
  /**
1134
1842
  * A React Flow / SvelteFlow style node change; only `position` changes are inspected.
@@ -1176,6 +1884,23 @@ declare function createCanvasArrangeController<TNode extends CanvasNode = Canvas
1176
1884
  divide: (ids?: Iterable<string>, o?: CombineShapeNodesOptions) => CombineShapeNodesResult<TNode>;
1177
1885
  /** Whether the shape operations can run on `ids` (default: the selection). */
1178
1886
  canCombineShapes: (ids?: Iterable<string>) => boolean;
1887
+ /**
1888
+ * Offset Path: grows (`distance > 0`) or shrinks (`distance < 0`) every shape among
1889
+ * `ids` (default: the selection) by `distance` flow units, keeping curves, as one
1890
+ * undoable step. Refuses without changing anything when a shape is locked, no shape is
1891
+ * selected or every result is empty.
1892
+ */
1893
+ offsetShapes(distance: number, ids?: Iterable<string>, offsetOptions?: OffsetShapeNodesOptions): ShapePathEditResult<TNode>;
1894
+ /** Whether `offsetShapes` can run on `ids` (default: the selection). */
1895
+ canOffsetShapes: (ids?: Iterable<string>) => boolean;
1896
+ /**
1897
+ * Outline Stroke: converts the strokes of the shapes among `ids` (default: the
1898
+ * selection) to filled path shapes, as one undoable step. Refuses when a shape is
1899
+ * locked or no selected shape has a visible stroke.
1900
+ */
1901
+ outlineStroke(ids?: Iterable<string>, outlineOptions?: OutlineShapeStrokesOptions): ShapePathEditResult<TNode>;
1902
+ /** Whether `outlineStroke` can run on `ids` (default: the selection). */
1903
+ canOutlineStroke: (ids?: Iterable<string>) => boolean;
1179
1904
  /**
1180
1905
  * Runs a shortcut action. Scene actions are not handled here (see the scenes store);
1181
1906
  * returns `false` for them and for unknown actions.
@@ -1370,4 +2095,209 @@ declare function fitPathData(ring: readonly Point[], options?: FitPathDataOption
1370
2095
  */
1371
2096
  declare function fitFreehandPath(points: readonly Point[], options?: Omit<FitPathDataOptions, 'closed'>): string;
1372
2097
 
1373
- export { AlignEdge, AlignNodesOptions, type ArrangeHistoryTarget, CONNECTION_LINE_TYPES, CanvasArrangeAction, type CanvasArrangeController, type CanvasArrangeControllerOptions, CanvasClipboardPayload, type CanvasConnectionLineType, CanvasEdge, type CanvasHeightOptions, CanvasLayoutOptions, CanvasNode, CanvasNodeStyle, CanvasNodeUpdate, type CanvasScene, type CanvasScenesOptions, type CanvasScenesState, CanvasScenesStore, type CanvasViewport, type Clock, type CombineShapeNodesOptions, type CombineShapeNodesRefusal, type CombineShapeNodesResult, type ConnectorSnap, type ConnectorSnapOptions, type ConnectorSnapTarget, type CubicSegment, DEFAULT_NODE_HEIGHT, DEFAULT_NODE_WIDTH, DEFAULT_PLACEMENT_GAP, DirectionalDisplacementOptions, DistributeAxis, DistributeMode, DistributeNodesOptions, type EllipseShape, FanOutTrajectoryOptions, type FitCubicsOptions, type FitPathDataOptions, type FitViewportOptions, type FlattenOptions, type GuideIndex, type GuideLine, IncrementalLayoutOptions, ManualClock, MatchSizeOptions, type MeasureGuide, type MeasureSelectionOptions, type MeasureSelectionResult, type MultiNodeTransitionOptions, type MultiPolygon, NodeRectOptions, NodeTransition, type PathCommand, type PathShape, PlaceBesideOptions, Point, type PolygonBooleanOperation, type PolygonBooleanOptions, type PolygonFillRule, type PolygonInput, type PolygonOperand, type PolygonPiece, type PolygonRing, type PolygonToPathOptions, type PolygonWithHoles, Position, type PositionChangeLike, RESIZE_HANDLES, Rect, type RectShape, ReflowDisplacementOptions, type RegularPolygonShape, type ResizeHandle, SHAPE_DATA_KEY, SHAPE_KINDS, SHAPE_NODE_TYPE, SHAPE_OPERATIONS, type SerializedCanvasScenes, type ShapeDescription, type ShapeKind, type ShapeNodePolygonOptions, type ShapeOperation, type ShapePaint, type ShapeRenderData, type ShapeSize, Side, SizeDimension, type SnapGuidesOptions, type SnapNodeDragOptions, type SnapNodeDragResult, type SnapNodeResizeOptions, type SnapNodeResizeResult, type SnapResizeOptions, type SnapResizeResult, type SnapResult, type StarShape, StreamingLayoutManager, type StreamingLayoutManagerOptions, TrajectoryFunction, XYPosition, ZOrderOperation, applyShapeCombination, blendLayout, boundsOf, calculateDagreReflowDisplacement, calculateDirectionalDisplacement, canCombineShapeNodes, canvasHeight, centerNodes, centre, collectDescendantIds, combineShapeNodes, computeNodesBoundingBox, computeSnapGuides, connectedOnly, createBezierTrajectory, createCanvasArrangeController, createCanvasScenesStore, createFanOutTrajectory, createGuideIndex, createNodeGuideIndex, cubicPointAt, cubicsToPathData, defaultEasing, dividePolygons, ensureLayout, estimateCanvasHeight, estimateNodeSize, findConnectorSnap, fitCubicRun, fitCubics, fitFreehandPath, fitPathData, fitViewportToNodes, fitViewportToRect, flattenSvgPath, flowSide, formatNumber, getCenteredNodePosition, getLayoutedNodes, getNodeShape, getResizingNodeRect, getShapeRenderData, getShapeSvg, handlePoint, inferResizeHandle, intersectPolygons, isEventFromTextInput, isMeasureModifierHeld, isShapeDescription, isShapeNode, isStraightCubic, isValidCanvasEdge, isValidCanvasNode, isValidCanvasScene, isValidUrl, layoutBounds, linearPositionTrajectory, linearTrajectory, measureBetween, measureLabel, measureSelection, measureToLine, multiPolygonArea, multiPolygonBounds, nearestHandlePositions, oppositePosition, overlaps, pageHidden, parseCanvasClipboardData, parseCanvasScenes, parseSvgPath, placeBeside, pointInMultiPolygon, pointInRings, polygonArea, polygonBoolean, polygonToSvgPath, positionToSide, realClock, remapPastedNodes, repositionNodesTo, resizeHandleAxes, revertShapeCombination, ringSignedArea, runMultiNodeTransition, serializeCanvasNodes, shapeNodeToPolygon, shapeToPolygon, sideToPosition, simplifyRing, snapNodeDrag, snapNodeResize, snapResize, snapToGrid, subtractPolygons, unionPolygons, withStyleOpacity, xorPolygons };
2098
+ interface CanvasAutoLayoutControllerOptions<TNode extends CanvasNode = CanvasNode> extends AutoLayoutOptions {
2099
+ getNodes: () => TNode[];
2100
+ setNodes: (nodes: TNode[]) => void;
2101
+ /** When set, controller actions (add / remove / resize / reorder / apply) are one undoable step each. */
2102
+ history?: ArrangeHistoryTarget;
2103
+ /** Turns automatic relayout off (explicit `applyAutoLayout` still works). Default `true`. */
2104
+ enabled?: boolean;
2105
+ /** Reorder flow children by dragging them inside their frame (default `true`). */
2106
+ dragReorder?: boolean;
2107
+ /** Called when the drop marker of a reorder drag changes (empty when none). */
2108
+ onGuidesChange?: (guides: GuideLine[]) => void;
2109
+ }
2110
+ /**
2111
+ * Merges the updates of several layout passes (later ones win per field).
2112
+ */
2113
+ declare function mergeNodeUpdates(...lists: CanvasNodeUpdate[][]): CanvasNodeUpdate[];
2114
+ /**
2115
+ * Updates that re-run auto layout around `ids` after a change: each id's own layout (if a
2116
+ * frame) and its auto layout ancestors, plus the frames that lost removed children
2117
+ * (`parentIds`). Pure helper used by the controllers.
2118
+ */
2119
+ declare function relayoutUpdates(nodes: CanvasNode[], ids: Iterable<string>, options?: AutoLayoutOptions): CanvasNodeUpdate[];
2120
+ /**
2121
+ * Framework-agnostic auto layout controller shared by the React hook and the Svelte rune.
2122
+ * Applies auto layout to frames (`data.layout`) after nodes inside them are added, removed,
2123
+ * resized or reordered, either through its own (undoable) actions or by watching the flow's
2124
+ * node changes (`noteChanges` + `flush`), and reorders flow children dragged within a frame.
2125
+ */
2126
+ declare function createCanvasAutoLayoutController<TNode extends CanvasNode = CanvasNode>(options: CanvasAutoLayoutControllerOptions<TNode>): {
2127
+ /** Drop marker of the active reorder drag (flow coordinates); empty otherwise. */
2128
+ readonly guides: GuideLine[];
2129
+ /**
2130
+ * Lays out frame `frameId` and its auto layout ancestors (default: every frame) as one
2131
+ * (optionally undoable) step. Returns the updates.
2132
+ */
2133
+ applyAutoLayout(frameId?: string): CanvasNodeUpdate[];
2134
+ /** Updates that relayout around `ids` on the current nodes, without applying them. */
2135
+ layoutUpdates(ids: Iterable<string>): CanvasNodeUpdate[];
2136
+ /**
2137
+ * Applies the relayout around `ids` (frames, or nodes inside frames) directly, not
2138
+ * recorded in history: auto layout is derived state, re-run after any change.
2139
+ */
2140
+ relayout(ids: Iterable<string>): CanvasNodeUpdate[];
2141
+ /**
2142
+ * Adds `node` (into the frame named by its `parentId`, at flow `index` when given) and
2143
+ * lays out its frame, as one step.
2144
+ */
2145
+ addNode(node: TNode, addOptions?: {
2146
+ index?: number;
2147
+ }): CanvasNodeUpdate[];
2148
+ /** Removes nodes (and their descendants) and lays out the frames they leave, as one step. */
2149
+ removeNodes(ids: Iterable<string>): CanvasNodeUpdate[];
2150
+ /**
2151
+ * Resizes node `id` (its children follow their constraints) and lays out around it,
2152
+ * as one step.
2153
+ */
2154
+ resizeNode(id: string, size: {
2155
+ width?: number;
2156
+ height?: number;
2157
+ }): CanvasNodeUpdate[];
2158
+ /** Moves flow child `childId` to flow index `index` in its frame and lays it out, as one step. */
2159
+ moveChild(childId: string, index: number): CanvasNodeUpdate[];
2160
+ /** Where flow child `id` would drop if released at `point` (default: its centre). */
2161
+ getInsertTarget(id: string, point?: XYPosition): AutoLayoutInsertTarget | undefined;
2162
+ /** Records the start position of a reorder drag. Optional: `dragReorder` records it lazily. */
2163
+ beginReorderDrag(id: string): void;
2164
+ /**
2165
+ * While flow child `id` is dragged (as currently positioned in `getNodes()`): updates the
2166
+ * drop marker. Returns the insert target.
2167
+ */
2168
+ dragReorder(id: string, point?: XYPosition): AutoLayoutInsertTarget | undefined;
2169
+ /**
2170
+ * Ends a reorder drag: moves `id` to the slot under `point` (default: its centre) and lays
2171
+ * the frame out, as one undoable step whose undo puts the node back where the drag began.
2172
+ */
2173
+ endReorderDrag(id: string, point?: XYPosition): CanvasNodeUpdate[];
2174
+ /**
2175
+ * Notes a batch of React Flow / SvelteFlow style node changes (before or after they are
2176
+ * applied) so `flush` can relayout: dimension changes (measured sizes, resize ends),
2177
+ * added and removed nodes, and position changes of flow children (reorder drags).
2178
+ * Returns the changes unchanged.
2179
+ */
2180
+ noteChanges<TChange extends PositionChangeLike>(changes: TChange[]): TChange[];
2181
+ /**
2182
+ * Notes nodes that were already removed (e.g. SvelteFlow's `ondelete`), so `flush`
2183
+ * relayouts the frames they left. The nodes must still carry their `parentId`.
2184
+ */
2185
+ noteRemoved(removed: Iterable<{
2186
+ id: string;
2187
+ parentId?: string;
2188
+ }>): void;
2189
+ /** Whether `noteChanges` left work for `flush`. */
2190
+ readonly hasPending: boolean;
2191
+ /**
2192
+ * Applies the work noted by `noteChanges` to the current nodes: drop markers while
2193
+ * dragging, committed reorders on drop (undoable), and a relayout (not recorded) for
2194
+ * size, add and remove changes. Call it once the changes are applied.
2195
+ */
2196
+ flush(): CanvasNodeUpdate[];
2197
+ /** Whether `id` is an auto layout frame. */
2198
+ isFrame: (id: string) => boolean;
2199
+ };
2200
+ type CanvasAutoLayoutController<TNode extends CanvasNode = CanvasNode> = ReturnType<typeof createCanvasAutoLayoutController<TNode>>;
2201
+
2202
+ /**
2203
+ * Design-token bindings on canvas nodes.
2204
+ *
2205
+ * - `node.data.tokenBindings` maps a property key (`fill`, `opacity`, `gap`, …) to a variable id.
2206
+ * - `node.data.tokenModes` maps a collection id to a mode id: an explicit mode for the node and
2207
+ * its descendants (via `parentId`); the nearest ancestor wins, then the root `modes` option,
2208
+ * then the collection's default mode.
2209
+ *
2210
+ * Bound properties are *materialised*: `resolveCanvasTokens` writes the resolved values into
2211
+ * the ordinary node fields (`data.shape.fill`, `style.backgroundColor`, `data.layout.gap`, …), so
2212
+ * renderers, auto layout and exports need no token awareness, and a node whose variable is
2213
+ * gone keeps its last value. Both keys live in `data`, so they survive copy / paste,
2214
+ * duplication and serialisation unchanged.
2215
+ */
2216
+ /** Data key holding a node's property → variable id bindings. */
2217
+ declare const TOKEN_BINDINGS_DATA_KEY = "tokenBindings";
2218
+ /** Data key holding a node's explicit collection → mode choices. */
2219
+ declare const TOKEN_MODES_DATA_KEY = "tokenModes";
2220
+ /** A node property a variable can drive. */
2221
+ interface CanvasTokenProperty {
2222
+ key: string;
2223
+ label: string;
2224
+ /** The variable type it takes. */
2225
+ type: TokenType;
2226
+ /** The scope pickers filter by (variables scoped elsewhere are not offered). */
2227
+ scope?: TokenScope | ((node: CanvasNode) => TokenScope | undefined);
2228
+ appliesTo(node: CanvasNode): boolean;
2229
+ read(node: CanvasNode): TokenLiteral | undefined;
2230
+ /** Returns the node with the value written, or the same node when nothing changes. */
2231
+ write(node: CanvasNode, value: TokenLiteral): CanvasNode;
2232
+ }
2233
+ /** A style property (camelCase name) from a style string or object. */
2234
+ declare function readNodeStyleProperty(style: CanvasNodeStyle | undefined | null, prop: string): string | number | undefined;
2235
+ /**
2236
+ * Returns `style` with one property set (or removed with `undefined`), keeping its
2237
+ * representation. Numbers become `px` in style strings unless `unitless`.
2238
+ */
2239
+ declare function writeNodeStyleProperty(style: CanvasNodeStyle | undefined | null, prop: string, value: string | number | undefined, unitless?: boolean): CanvasNodeStyle | undefined;
2240
+ /** The built-in bindable properties. */
2241
+ declare const CANVAS_TOKEN_PROPERTIES: readonly CanvasTokenProperty[];
2242
+ interface CanvasTokenOptions {
2243
+ /** Modes for nodes without an explicit mode up their tree (e.g. the page's). */
2244
+ modes?: TokenModeContext;
2245
+ /** Bindable properties (default {@link CANVAS_TOKEN_PROPERTIES}); add your own to extend. */
2246
+ properties?: readonly CanvasTokenProperty[];
2247
+ }
2248
+ /** The node's property → variable id bindings. */
2249
+ declare function getNodeTokenBindings(node: CanvasNode | undefined | null): Readonly<Record<string, string>>;
2250
+ /** The node's own explicit modes (collection id → mode id). */
2251
+ declare function getNodeTokenModes(node: CanvasNode | undefined | null): Readonly<Record<string, string>>;
2252
+ declare function getCanvasTokenProperty(key: string, options?: CanvasTokenOptions): CanvasTokenProperty | undefined;
2253
+ /** Properties a variable can be bound to on this node. */
2254
+ declare function getBindableTokenProperties(node: CanvasNode, options?: CanvasTokenOptions): CanvasTokenProperty[];
2255
+ /** The scope of a property on a node. */
2256
+ declare function getTokenPropertyScope(property: CanvasTokenProperty, node: CanvasNode): TokenScope | undefined;
2257
+ /** Variables a picker offers for `property` on `node`: the property's type, in scope. */
2258
+ declare function getTokensForProperty(state: TokenState, property: CanvasTokenProperty, node: CanvasNode): TokenVariable[];
2259
+ /**
2260
+ * The modes `node` is in: the root `modes`, overridden by each ancestor's explicit modes from
2261
+ * the top down, then the node's own. Modes `state` doesn't know are ignored.
2262
+ */
2263
+ declare function getEffectiveTokenModes(node: CanvasNode, nodes: readonly CanvasNode[] | ReadonlyMap<string, CanvasNode>, state?: TokenState, options?: Pick<CanvasTokenOptions, 'modes'>): Record<string, string>;
2264
+ /**
2265
+ * Writes every bound property's resolved value into its node. Returns the same array when
2266
+ * nothing changed (unchanged nodes keep their identity), so it is safe to run on every change.
2267
+ * Bindings that don't resolve (deleted variable, cycle) keep the node's current value.
2268
+ */
2269
+ declare function resolveCanvasTokens<TNode extends CanvasNode>(nodes: readonly TNode[], state: TokenState, options?: CanvasTokenOptions): TNode[];
2270
+ interface CanvasTokenBindingInfo {
2271
+ property: CanvasTokenProperty;
2272
+ variableId: string;
2273
+ variable: TokenVariable | undefined;
2274
+ resolution: TokenResolution;
2275
+ }
2276
+ /** Each binding of a node with its variable and resolution (for inspectors and diagnostics). */
2277
+ declare function inspectNodeTokens(node: CanvasNode, nodes: readonly CanvasNode[], state: TokenState, options?: CanvasTokenOptions): CanvasTokenBindingInfo[];
2278
+ /**
2279
+ * Binds `property` of each node in `ids` to `variableId` (or unbinds with `null`, keeping the
2280
+ * current value) and resolves. Throws `type-mismatch` when the variable's type doesn't fit the
2281
+ * property, `not-found` for unknown variables or properties. Nodes the property doesn't apply
2282
+ * to are left alone.
2283
+ */
2284
+ declare function bindCanvasToken<TNode extends CanvasNode>(nodes: readonly TNode[], ids: Iterable<string>, propertyKey: string, variableId: string | null, state: TokenState, options?: CanvasTokenOptions): TNode[];
2285
+ /**
2286
+ * Sets (or with `null` clears, back to "Auto") the explicit mode of `collectionId` on each node
2287
+ * in `ids`, then resolves, so descendants follow.
2288
+ */
2289
+ declare function setCanvasTokenMode<TNode extends CanvasNode>(nodes: readonly TNode[], ids: Iterable<string>, collectionId: string, modeId: string | null, state: TokenState, options?: CanvasTokenOptions): TNode[];
2290
+ /**
2291
+ * Detaches bindings to `variableIds` (default: every binding whose variable is missing from
2292
+ * `state`): each property keeps its value resolved in `state` and the binding is removed. Pass
2293
+ * the state from *before* a delete (`TokenChangeEvent.previous`) so deleted variables still
2294
+ * resolve.
2295
+ */
2296
+ declare function detachTokenBindings<TNode extends CanvasNode>(nodes: readonly TNode[], state: TokenState, variableIds?: Iterable<string>, options?: CanvasTokenOptions): TNode[];
2297
+ /**
2298
+ * Removes explicit modes `state` no longer knows (deleted collections or modes), like figcraft
2299
+ * resetting such layers to "Auto". Resolution already ignores them; this tidies the data.
2300
+ */
2301
+ declare function pruneCanvasTokenModes<TNode extends CanvasNode>(nodes: readonly TNode[], state: TokenState): TNode[];
2302
+
2303
+ export { AUTO_LAYOUT_DATA_KEY, type AffineMatrix, AlignEdge, AlignNodesOptions, type ArrangeHistoryTarget, type AutoLayout, type AutoLayoutAlignContent, type AutoLayoutAlignCross, type AutoLayoutAlignMain, type AutoLayoutCellAlign, type AutoLayoutChild, type AutoLayoutConstraints, type AutoLayoutGrid, type AutoLayoutGridArea, type AutoLayoutGridCell, type AutoLayoutGridGeometry, type AutoLayoutGridTrack, type AutoLayoutHorizontalConstraint, type AutoLayoutInsertTarget, type AutoLayoutMeasure, type AutoLayoutMode, type AutoLayoutOptions, type AutoLayoutPadding, type AutoLayoutSize, type AutoLayoutSizing, type AutoLayoutSizingPair, type AutoLayoutVerticalConstraint, type BezierCommand, type BezierContour, type BezierPath, type BezierPathInput, type BezierPathToSvgOptions, type BezierSegment, CANVAS_TOKEN_PROPERTIES, CHILD_LAYOUT_DATA_KEY, CONNECTION_LINE_TYPES, CanvasArrangeAction, type CanvasArrangeController, type CanvasArrangeControllerOptions, type CanvasAutoLayoutController, type CanvasAutoLayoutControllerOptions, CanvasClipboardPayload, type CanvasConnectionLineType, CanvasEdge, type CanvasHeightOptions, CanvasLayoutOptions, CanvasNode, CanvasNodeStyle, CanvasNodeUpdate, type CanvasScene, type CanvasScenesOptions, type CanvasScenesState, CanvasScenesStore, type CanvasTokenBindingInfo, type CanvasTokenOptions, type CanvasTokenProperty, type CanvasViewport, type Clock, type CombineShapeNodesOptions, type CombineShapeNodesRefusal, type CombineShapeNodesResult, type ConnectorSnap, type ConnectorSnapOptions, type ConnectorSnapTarget, type CubicSegment, DEFAULT_NODE_HEIGHT, DEFAULT_NODE_WIDTH, DEFAULT_PLACEMENT_GAP, type DashedPath, DirectionalDisplacementOptions, DistributeAxis, DistributeMode, DistributeNodesOptions, type DividePathsResult, type EllipseShape, FanOutTrajectoryOptions, type FitCubicsOptions, type FitPathDataOptions, type FitViewportOptions, type FlattenOptions, type GuideIndex, type GuideLine, IncrementalLayoutOptions, ManualClock, MatchSizeOptions, type MeasureGuide, type MeasureSelectionOptions, type MeasureSelectionResult, type MultiNodeTransitionOptions, type MultiPolygon, NodeRectOptions, NodeTransition, type OffsetPathOptions, type OffsetShapeNodesOptions, type OutlineShapeStrokesOptions, type OutlineStrokeOptions, type PathBooleanOperation, type PathBooleanResult, type PathCommand, type PathOperand, type PathOperandInput, PathOpsError, type PathOpsOptions, type PathOpsReport, type PathPiece, type PathPointAtLength, type PathShape, PlaceBesideOptions, Point, type PolygonBooleanOperation, type PolygonBooleanOptions, type PolygonFillRule, type PolygonInput, type PolygonOperand, type PolygonPiece, type PolygonRing, type PolygonToPathOptions, type PolygonWithHoles, Position, type PositionChangeLike, RESIZE_HANDLES, Rect, type RectShape, ReflowDisplacementOptions, type RegularPolygonShape, type ResizeHandle, SHAPE_DATA_KEY, SHAPE_KINDS, SHAPE_NODE_TYPE, SHAPE_OPERATIONS, type SerializedCanvasScenes, type ShapeDescription, type ShapeKind, type ShapeNodePolygonOptions, type ShapeOperation, type ShapePaint, type ShapePathEditOperation, type ShapePathEditRefusal, type ShapePathEditResult, type ShapeRenderData, type ShapeSize, Side, SizeDimension, type SnapGuidesOptions, type SnapNodeDragOptions, type SnapNodeDragResult, type SnapNodeResizeOptions, type SnapNodeResizeResult, type SnapResizeOptions, type SnapResizeResult, type SnapResult, type StarShape, StreamingLayoutManager, type StreamingLayoutManagerOptions, type StrokeCap, type StrokeJoin, TOKEN_BINDINGS_DATA_KEY, TOKEN_MODES_DATA_KEY, TrajectoryFunction, XYPosition, ZOrderOperation, applyConstraints, applyShapeCombination, applyShapeReplacement, arcToCubics, bezierPathArea, bezierPathBounds, bezierPathLength, bezierPathPointAtLength, bezierPathSignedArea, bezierPathToSvg, bindCanvasToken, blendLayout, boundsOf, calculateDagreReflowDisplacement, calculateDirectionalDisplacement, canCombineShapeNodes, canOffsetShapeNodes, canOutlineShapeNodeStrokes, canvasHeight, centerNodes, centre, clampLayoutSize, closeContour, collectDescendantIds, combineShapeNodes, computeNodesBoundingBox, computeSnapGuides, connectedOnly, contourSignedArea, contoursToPath, countPathSegments, createBezierTrajectory, createCanvasArrangeController, createCanvasAutoLayoutController, createCanvasScenesStore, createFanOutTrajectory, createGuideIndex, createNodeGuideIndex, cubicPointAt, cubicsToPathData, dashContours, defaultEasing, detachTokenBindings, distanceToBezierPath, dividePaths, dividePolygons, ensureLayout, estimateCanvasHeight, estimateNodeSize, excludePaths, findConnectorSnap, fitCubicRun, fitCubics, fitFreehandPath, fitPathData, fitViewportToNodes, fitViewportToRect, flattenSvgPath, flowSide, formatNumber, getAutoLayout, getAutoLayoutGrid, getAutoLayoutInsertTarget, getBindableTokenProperties, getCanvasTokenProperty, getCenteredNodePosition, getChildLayout, getEffectiveTokenModes, getFlowChildren, getLayoutParent, getLayoutSizing, getLayoutedNodes, getNodeShape, getNodeTokenBindings, getNodeTokenModes, getResizingNodeRect, getShapeRenderData, getShapeSvg, getTokenPropertyScope, getTokensForProperty, handlePoint, hasVisibleStroke, inferResizeHandle, inspectNodeTokens, intersectPaths, intersectPolygons, isAutoLayoutFrame, isEventFromTextInput, isMeasureModifierHeld, isShapeDescription, isShapeNode, isStraightCubic, isValidCanvasEdge, isValidCanvasNode, isValidCanvasScene, isValidUrl, layoutAll, layoutBounds, layoutFrame, layoutUp, layoutUpMany, linearPositionTrajectory, linearTrajectory, makeSizingCoherent, measureBetween, measureLabel, measureSelection, measureToLine, mergeNodeUpdates, moveLayoutChild, multiPolygonArea, multiPolygonBounds, nearestHandlePositions, normalizeBezierPath, offsetPath, offsetShapeNodes, oppositePosition, outlineShapeNodeStrokes, outlineStroke, overlaps, pageHidden, parseCanvasClipboardData, parseCanvasScenes, parseSvgPath, pathBoolean, pathToContours, placeBeside, pointInBezierPath, pointInMultiPolygon, pointInRings, polygonArea, polygonBoolean, polygonToSvgPath, positionToSide, pruneCanvasTokenModes, readNodeStyleProperty, realClock, relayoutUpdates, remapPastedNodes, repositionNodesTo, resizeHandleAxes, resolveCanvasTokens, resolvePadding, revertShapeCombination, ringSignedArea, runMultiNodeTransition, segmentBounds, segmentCurvature, segmentDerivative, segmentExtrema, segmentLength, segmentNearest, segmentParamAtLength, segmentPoint, segmentTangent, serializeCanvasNodes, setCanvasTokenMode, shapeNodeToBezierPath, shapeNodeToPolygon, shapeToBezierPath, shapeToPolygon, sideToPosition, simplifyRing, snapNodeDrag, snapNodeResize, snapResize, snapToGrid, splitSegment, strokeOutlineRings, subSegment, subtractPaths, subtractPolygons, toBezierPath, transformBezierPath, trimSegments, unionPolygons, unitePaths, windingNumber, withStyleOpacity, writeNodeStyleProperty, xorPolygons };