@pixerate/editor 0.42.0 → 0.44.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.
@@ -1,4 +1,4 @@
1
- import { C as CanvasGradientDef, A as AffineMatrix, B as BezierPathInput, a as BezierPath, S as SvgGradientDef, b as StrokeJoin, c as StrokeCap, d as BezierSegment, P as PlanarMap, e as PathfinderOperation, f as PathfinderShape, G as GradientStop } from '../pathfinder-D7hXenzu.js';
1
+ import { C as CanvasGradientDef, A as AffineMatrix, B as BezierPathInput, a as BezierPath, S as SvgGradientDef, b as StrokeJoin, c as StrokeCap, d as BezierSegment, P as PlanarMap, e as PathfinderOperation, f as PathfinderShape } from '../pathfinder-D98S2lV5.js';
2
2
  import { P as Point } from '../types-BFkYA4eF.js';
3
3
  import { H as HistoryManager } from '../HistoryManager-DWSLd6Tf.js';
4
4
  import { C as CommandSpec } from '../registry-DhVUZioj.js';
@@ -58,8 +58,93 @@ interface VectorSubpath {
58
58
  /** Joins the last anchor back to the first. */
59
59
  closed: boolean;
60
60
  }
61
+ /**
62
+ * Gradient styles: `linear` (start → end), `radial` (centred on the start, reaching the end;
63
+ * focal point and aspect), `conic` (an angle sweep around the start, from the end's direction
64
+ * towards the aspect handle's: clockwise on screen), `reflected` (linear mirrored about the
65
+ * start) and `diamond` (`|u| + |v|` in the gradient's frame: a rhombus through the end and the
66
+ * aspect handle).
67
+ */
68
+ type VectorGradientType = 'linear' | 'radial' | 'conic' | 'reflected' | 'diamond';
69
+ declare const VECTOR_GRADIENT_TYPES: readonly VectorGradientType[];
70
+ /** What a gradient paints past its ends: the end colours, mirrored periods or repeated periods. */
71
+ type VectorGradientSpread = 'pad' | 'reflect' | 'repeat';
72
+ declare const VECTOR_GRADIENT_SPREADS: readonly VectorGradientSpread[];
73
+ /** Where colours mix between stops: sRGB (SVG's own), linear light or Oklab. */
74
+ type VectorGradientInterpolation = 'srgb' | 'linear' | 'oklab';
75
+ declare const VECTOR_GRADIENT_INTERPOLATIONS: readonly VectorGradientInterpolation[];
76
+ /**
77
+ * The space a gradient's points are in: fractions of the shape's bounding box (SVG's
78
+ * `objectBoundingBox`, the default) or the node's own coordinates (`userSpaceOnUse`).
79
+ */
80
+ type VectorGradientUnits = 'objectBoundingBox' | 'userSpaceOnUse';
81
+ /**
82
+ * How a gradient lies on a stroke: `within` (laid over the stroke's area like a fill), `along`
83
+ * (t runs from 0 at the start of each subpath to 1 at its end) or `across` (from the stroke's
84
+ * left edge to its right edge, looking along the path).
85
+ */
86
+ type VectorStrokeGradientMode = 'within' | 'along' | 'across';
87
+ declare const VECTOR_STROKE_GRADIENT_MODES: readonly VectorStrokeGradientMode[];
88
+ /** A colour stop. `opacity` multiplies the colour's own alpha. */
89
+ interface VectorGradientStop {
90
+ /** 0–1. */
91
+ offset: number;
92
+ color: string;
93
+ /** 0–1, default 1. */
94
+ opacity?: number;
95
+ /**
96
+ * Where, between this stop and the next (0–1 of the way), the colour is half-way between
97
+ * them. Default 0.5 (an even mix).
98
+ */
99
+ midpoint?: number;
100
+ }
101
+ /**
102
+ * A gradient paint. `CanvasGradientDef` (the canvas package's linear `angle` / radial
103
+ * `cx, cy, r` gradients) is a valid value: those fields are the shorthand form. Explicit
104
+ * geometry (`start` / `end`, in `units`) wins over the shorthand.
105
+ */
106
+ interface VectorGradient {
107
+ type: VectorGradientType;
108
+ stops: VectorGradientStop[];
109
+ /**
110
+ * Shorthand direction in degrees, CSS style (0 points up, clockwise): a linear or reflected
111
+ * gradient's direction across the box (default 180), a conic gradient's start angle or a
112
+ * diamond's turn (default 90).
113
+ */
114
+ angle?: number;
115
+ /** Shorthand centre and radius of radial, conic and diamond gradients (fractions of the box, default 0.5). */
116
+ cx?: number;
117
+ cy?: number;
118
+ r?: number;
119
+ /** Where t = 0: a linear gradient's start, the centre of the other styles. */
120
+ start?: Vec2;
121
+ /** Where t = 1 along the gradient's main axis (a radial gradient's radius). */
122
+ end?: Vec2;
123
+ /**
124
+ * The end of the secondary axis (radial, conic and diamond): its distance from `start` over
125
+ * the main axis' length is the aspect ratio. Absent: square to the main axis, as long.
126
+ */
127
+ width?: Vec2 | null;
128
+ /** A radial gradient's focal point (where t = 0); absent: the centre. */
129
+ focal?: Vec2 | null;
130
+ /** Radius of the focal circle as a fraction of the radius (SVG `fr`, default 0). */
131
+ focalRadius?: number;
132
+ /** Space of `start`, `end`, `width` and `focal` (default `objectBoundingBox`). */
133
+ units?: VectorGradientUnits;
134
+ /** Default `pad`. */
135
+ spread?: VectorGradientSpread;
136
+ /** Default `srgb`. */
137
+ interpolation?: VectorGradientInterpolation;
138
+ /**
139
+ * 0–1: how far the colours follow a smooth spline through the stops instead of straight
140
+ * lines (Photoshop's Smoothness). Default 0.
141
+ */
142
+ smoothness?: number;
143
+ /** On a stroke: how the gradient lies on it (default `within`). Ignored on fills. */
144
+ strokeMode?: VectorStrokeGradientMode;
145
+ }
61
146
  /** A fill or stroke: any CSS colour, a gradient, or `null` / `'none'` for no paint. */
62
- type VectorPaint = string | CanvasGradientDef | null;
147
+ type VectorPaint = string | VectorGradient | CanvasGradientDef | null;
63
148
  type VectorFillRule = 'nonzero' | 'evenodd';
64
149
  type VectorLineCap = 'butt' | 'round' | 'square';
65
150
  type VectorLineJoin = 'miter' | 'round' | 'bevel';
@@ -234,9 +319,10 @@ interface VectorHandleRef extends VectorAnchorRef {
234
319
  * `shapeBuilder` merges (Alt: deletes) the faces the selected shapes make, and `paintBucket`
235
320
  * fills the region the visible outlines enclose around a click with a new shape. `blend`
236
321
  * blends the shape clicked first into the one clicked next (clicking an anchor of a closed path
237
- * starts the blend there).
322
+ * starts the blend there). `envelope` edits the mesh of the selection's envelope: drag its
323
+ * anchors and handles, or inside a patch to pull the surface.
238
324
  */
239
- type VectorTool = 'select' | 'direct' | 'pen' | 'pencil' | 'rect' | 'ellipse' | 'polygon' | 'star' | 'line' | 'scissors' | 'knife' | 'eraser' | 'width' | 'shapeBuilder' | 'paintBucket' | 'blend';
325
+ type VectorTool = 'select' | 'direct' | 'pen' | 'pencil' | 'rect' | 'ellipse' | 'polygon' | 'star' | 'line' | 'scissors' | 'knife' | 'eraser' | 'width' | 'shapeBuilder' | 'paintBucket' | 'blend' | 'gradient' | 'envelope';
240
326
  declare const VECTOR_TOOLS: readonly VectorTool[];
241
327
  /** Keyboard modifiers held during a pointer event. */
242
328
  interface VectorModifiers {
@@ -285,10 +371,24 @@ type VectorAverageAxis = 'horizontal' | 'vertical' | 'both';
285
371
  /**
286
372
  * Live path effects (After Effects' path operators): `trim` (Trim Paths), `roundCorners`,
287
373
  * `puckerBloat`, `twist`, `zigzag`, `wiggle` (Wiggle Paths), `offset` (Offset Paths), `merge`
288
- * (Merge Paths) and `repeater`.
374
+ * (Merge Paths), `repeater` and `envelope` (an envelope distortion: a warp preset or a mesh).
289
375
  */
290
- type VectorEffectType = 'trim' | 'roundCorners' | 'puckerBloat' | 'twist' | 'zigzag' | 'wiggle' | 'offset' | 'merge' | 'repeater';
376
+ type VectorEffectType = 'trim' | 'roundCorners' | 'puckerBloat' | 'twist' | 'zigzag' | 'wiggle' | 'offset' | 'merge' | 'repeater' | 'envelope';
291
377
  declare const VECTOR_EFFECT_TYPES: readonly VectorEffectType[];
378
+ /** Warp presets (Photoshop's fifteen, in menu order). */
379
+ type VectorWarpStyle = 'arc' | 'arcLower' | 'arcUpper' | 'arch' | 'bulge' | 'shellLower' | 'shellUpper' | 'flag' | 'wave' | 'fish' | 'rise' | 'fisheye' | 'inflate' | 'squeeze' | 'twist';
380
+ /**
381
+ * A grid of bicubic Bézier patches mapping a source box onto the plane. `us` / `vs` are the patch
382
+ * boundaries as fractions of the box (increasing, first 0, last 1); `points` is the
383
+ * `(3·(us.length − 1) + 1) × (3·(vs.length − 1) + 1)` control grid, row by row, in the node's own
384
+ * space. Neighbouring patches share their edge row: anchors sit where both indices are multiples
385
+ * of 3, handles where one is.
386
+ */
387
+ interface VectorWarpMesh {
388
+ us: number[];
389
+ vs: number[];
390
+ points: Vec2[];
391
+ }
292
392
  /** Merge Paths modes: a compound path (no boolean), union, the first minus the others, intersection or exclusion. */
293
393
  type VectorMergeMode = 'merge' | 'add' | 'subtract' | 'intersect' | 'exclude';
294
394
  declare const VECTOR_MERGE_MODES: readonly VectorMergeMode[];
@@ -373,6 +473,23 @@ interface VectorEffectParamsMap {
373
473
  /** `below`: each copy draws under the one before it; `above`: over it. */
374
474
  composite: 'below' | 'above';
375
475
  };
476
+ /**
477
+ * Envelope distortion: the paths above it are mapped from their combined bounds through a warp
478
+ * preset (bend and horizontal / vertical distortion in percent) or, with style `mesh`, through
479
+ * `mesh` (null: the flat mesh of `columns × rows` patches over the bounds). The bounds are
480
+ * taken afresh each time, so editing the contents keeps the envelope.
481
+ */
482
+ envelope: {
483
+ style: VectorWarpStyle | 'mesh';
484
+ bend: number;
485
+ horizontal: number;
486
+ vertical: number;
487
+ orientation: 'horizontal' | 'vertical';
488
+ /** Patches of the mesh (a preset turns into a mesh of this size when it is edited). */
489
+ rows: number;
490
+ columns: number;
491
+ mesh: VectorWarpMesh | null;
492
+ };
376
493
  }
377
494
  /** One entry of an effect stack. */
378
495
  type VectorEffect = {
@@ -392,11 +509,6 @@ interface VectorSegmentRef {
392
509
  segment: number;
393
510
  }
394
511
 
395
- /**
396
- * Vector path geometry: anchors and handles to Bézier paths and back, bounds, hit-testing,
397
- * affine transforms, segment splitting, anchor-type conversion and shape factories.
398
- */
399
-
400
512
  declare const cloneAnchor: (a: VectorAnchor) => VectorAnchor;
401
513
  declare const cloneSubpath: (s: VectorSubpath) => VectorSubpath;
402
514
  /** A deep copy of a node (ids kept). */
@@ -577,6 +689,266 @@ declare function lineSubpath(a: Vec2, b: Vec2): VectorSubpath;
577
689
  /** Rounds every coordinate to `precision` decimals (stable JSON and SVG output). */
578
690
  declare function roundSubpaths(subpaths: readonly VectorSubpath[], precision?: number): VectorSubpath[];
579
691
 
692
+ /** True when `paint` is a gradient (any style). */
693
+ declare function isVectorGradient(paint: VectorPaint | undefined): paint is VectorGradient;
694
+ /** Straight-alpha sRGB channels, 0–1. */
695
+ type VectorRgba = [number, number, number, number];
696
+ /** A CSS colour as 0–1 channels (hex, `rgb()`, `transparent`, `black`, `white`), or null. */
697
+ declare function parseVectorColor(color: string): VectorRgba | null;
698
+ /** Fewest stops a gradient keeps when one is removed. */
699
+ declare const VECTOR_GRADIENT_MIN_STOPS = 2;
700
+ /**
701
+ * Where relative position `u` of a segment lands once its midpoint is `m` (0.5 = unchanged): the
702
+ * colour is half-way at `m`, linear on either side (photocraft `midpoint_remap`).
703
+ */
704
+ declare function gradientMidpointRemap(u: number, m: number): number;
705
+ /** The stops sorted by offset (stable), offsets clamped to 0–1, unreadable offsets dropped. */
706
+ declare function sortedVectorGradientStops(g: Pick<VectorGradient, 'stops'>): VectorGradientStop[];
707
+ /** Does the gradient need extra stops to look the same in SVG (midpoints, smoothness or a non-sRGB space)? */
708
+ declare function vectorGradientNeedsExpansion(g: VectorGradient): boolean;
709
+ /** A gradient's colour ramp, prepared for sampling. */
710
+ interface VectorGradientRamp {
711
+ /** Straight-alpha sRGB at `t` (clamped to 0–1). */
712
+ sample(t: number): VectorRgba;
713
+ }
714
+ /**
715
+ * The colour ramp of a gradient (midpoints, smoothness and interpolation space applied), or null
716
+ * when a stop colour is not one `parseVectorColor` reads.
717
+ */
718
+ declare function vectorGradientRamp(g: Pick<VectorGradient, 'stops' | 'interpolation' | 'smoothness'>): VectorGradientRamp | null;
719
+ /** What the gradient paints at `t` (0–1 along its stops): `#rrggbb` and opacity. */
720
+ declare function sampleVectorGradient(g: VectorGradient, t: number): {
721
+ color: string;
722
+ opacity: number;
723
+ };
724
+ /**
725
+ * Plain stops (no midpoints) that SVG's sRGB interpolation turns into the gradient's colours:
726
+ * the stops as they are when nothing needs expanding; one extra stop per off-centre midpoint for
727
+ * sRGB without smoothness (exact: the midpoint makes each half linear); otherwise stops placed
728
+ * adaptively until linear interpolation between them is within `tolerance` (0–1 per channel,
729
+ * default half a level) of the true curve everywhere they were checked.
730
+ */
731
+ declare function expandVectorGradientStops(g: VectorGradient, options?: {
732
+ tolerance?: number;
733
+ }): VectorGradientStop[];
734
+ /** Linear interpolation between plain stops (what SVG draws from them), straight alpha. */
735
+ declare function samplePlainStops(stops: readonly VectorGradientStop[], t: number): VectorRgba;
736
+ /** The gradient with its stops reversed, each midpoint measured from the other side (vectorcraft `reverse`). */
737
+ declare function reverseVectorGradient<T extends Pick<VectorGradient, 'stops'>>(g: T): T;
738
+ /** A stop added at `offset` painting what the gradient paints there; returns the stops and its index. */
739
+ declare function insertVectorGradientStop(g: VectorGradient, offset: number): {
740
+ stops: VectorGradientStop[];
741
+ index: number;
742
+ };
743
+ /** Stop `index` moved to `offset` (re-sorted); returns the stops and its new index. */
744
+ declare function moveVectorGradientStop(stops: readonly VectorGradientStop[], index: number, offset: number): {
745
+ stops: VectorGradientStop[];
746
+ index: number;
747
+ };
748
+ /** The stops without stop `index`, or null when that would leave fewer than two. */
749
+ declare function removeVectorGradientStop(stops: readonly VectorGradientStop[], index: number): VectorGradientStop[] | null;
750
+ /** Where (0–1 along the gradient) the midpoint after stop `index` sits, or null for the last stop. */
751
+ declare function vectorGradientMidpointPosition(stops: readonly VectorGradientStop[], index: number): number | null;
752
+ /** The midpoint of stop `index` that puts it at position `pos` (clamped to 0.05–0.95), or null. */
753
+ declare function vectorGradientMidpointFromPosition(stops: readonly VectorGradientStop[], index: number, pos: number): number | null;
754
+ /**
755
+ * The part of the gradient from `from` to `to` (0–1, either order) as plain stops over 0–1
756
+ * (vectorcraft `span`): the colours at both ends plus the expanded stops between them.
757
+ */
758
+ declare function spanVectorGradientStops(g: VectorGradient, from: number, to: number, expanded?: VectorGradientStop[]): VectorGradientStop[];
759
+ /** A gradient's frame points, in its units (see `VectorGradient`). */
760
+ interface VectorGradientPoints {
761
+ start: Vec2;
762
+ end: Vec2;
763
+ width: Vec2;
764
+ focal: Vec2 | null;
765
+ focalRadius: number;
766
+ units: VectorGradientUnits;
767
+ }
768
+ /** Whether the gradient carries its own points (rather than the angle / centre shorthand). */
769
+ declare const hasExplicitGradientGeometry: (g: VectorGradient) => boolean;
770
+ /** The gradient's frame points in its units, the shorthand resolved (it is always in the box). */
771
+ declare function vectorGradientPoints(g: VectorGradient): VectorGradientPoints;
772
+ /**
773
+ * The unit box → `bounds` matrix of `objectBoundingBox` gradients. A side with no extent (a
774
+ * horizontal or vertical line) takes the other side's, centred, so the gradient still paints
775
+ * (SVG paints nothing there).
776
+ */
777
+ declare function vectorBoxMatrix(bounds: VectorBounds | null | undefined): VectorMatrix;
778
+ /** The gradient's units → node space (the box matrix for `objectBoundingBox`, else the identity). */
779
+ declare function vectorGradientUnitsMatrix(g: VectorGradient, bounds: VectorBounds | null | undefined): VectorMatrix;
780
+ /** The gradient's unit frame → node space: u = 1 at the end, v = 1 at the width point. */
781
+ declare function vectorGradientMatrix(g: VectorGradient, bounds: VectorBounds | null | undefined): VectorMatrix;
782
+ /**
783
+ * t of a radial gradient at unit-frame point `q` with the focal circle centred on `f` with radius
784
+ * `fr` and the end circle the unit circle (SVG's two-point conical gradient). With `fr = 0` this
785
+ * is the focal ray: t is the distance from the focal point to `q` over the distance from it to
786
+ * the circle along the same ray (effectcraft `GradientRamp::t`, vectorcraft `param_at`).
787
+ */
788
+ declare function vectorGradientFocalParam(q: Vec2, f?: Vec2, fr?: number): number;
789
+ /**
790
+ * The raw gradient parameter (before the spread) of a style at unit-frame point `q`: linear `u`,
791
+ * reflected `|u|`, diamond `|u| + |v|`, conic the turn from the u axis towards the v axis (0–1),
792
+ * radial the distance through the focal circle (photocraft `gradient_t`).
793
+ */
794
+ declare function vectorGradientParam(type: VectorGradientType, q: Vec2, focal?: {
795
+ f: Vec2;
796
+ fr: number;
797
+ } | null): number;
798
+ /** `t` folded into 0–1 by a spread mode. */
799
+ declare function applyVectorGradientSpread(t: number, spread?: VectorGradientSpread): number;
800
+ /** The gradient's t (spread applied) at node-space point `p` of a shape with box `bounds`. */
801
+ declare function vectorGradientTAt(g: VectorGradient, bounds: VectorBounds | null | undefined, p: Vec2): number;
802
+ /** What the gradient paints at node-space point `p` (straight-alpha sRGB, 0–1). */
803
+ declare function sampleVectorGradientAt(g: VectorGradient, bounds: VectorBounds | null | undefined, p: Vec2): VectorRgba;
804
+ /** The main axis length over the secondary's: |width − start| / |end − start| (signed by side). */
805
+ declare function vectorGradientAspect(g: VectorGradient): number;
806
+ /** The gradient with explicit points (in its units) replacing the shorthand. */
807
+ declare function explicitVectorGradient(g: VectorGradient): VectorGradient;
808
+ /**
809
+ * The gradient in the node's own space (`userSpaceOnUse`), painting what it paints on a shape
810
+ * with box `bounds` (vectorcraft `GradientPaint::pin`): its points mapped through the box.
811
+ */
812
+ declare function pinVectorGradient(g: VectorGradient, bounds: VectorBounds | null | undefined): VectorGradient;
813
+ /**
814
+ * The gradient after the node's geometry is mapped by `m`: a `userSpaceOnUse` gradient's points
815
+ * are mapped too (any affine map keeps every style's t, since t is measured in the frame the
816
+ * three points span); a box gradient follows the box and is unchanged.
817
+ */
818
+ declare function transformVectorGradient(g: VectorGradient, m: VectorMatrix): VectorGradient;
819
+ /**
820
+ * A gradient after its node's geometry goes through a non-affine map `f` (Free Distort, an
821
+ * envelope): handles in the node's own space (`userSpaceOnUse`) are mapped point by point, which
822
+ * keeps the gradient's frame where the shape went; bounding-box gradients are left alone, as they
823
+ * already follow the shape's new bounds.
824
+ */
825
+ declare function mapVectorGradient(g: VectorGradient, f: (p: Vec2) => Vec2): VectorGradient;
826
+ /** A paint after its node's geometry goes through a non-affine map `f` (see `mapVectorGradient`). */
827
+ declare function mapVectorPaint<T extends VectorPaint | undefined>(paint: T, f: (p: Vec2) => Vec2): T;
828
+ /** A paint after its node's geometry is mapped by `m` (colours unchanged). */
829
+ declare function transformVectorPaint<T extends VectorPaint | undefined>(paint: T, m: VectorMatrix): T;
830
+ /**
831
+ * An on-canvas handle of a gradient: `start` (a radial, conic or diamond gradient's centre),
832
+ * `end` (a linear or reflected gradient's end), `radius` (the end of the others), `aspect` (the
833
+ * secondary axis' end) and `focal` (radial).
834
+ */
835
+ type VectorGradientHandle = 'start' | 'end' | 'radius' | 'aspect' | 'focal';
836
+ /** Whether the style has a centre with a radius (rather than a start and an end). */
837
+ declare const isCentredVectorGradient: (type: VectorGradientType) => type is "radial" | "conic" | "diamond";
838
+ /** The handles of a gradient in the space `toWorld` maps the node's space to (the document, the screen). */
839
+ declare function vectorGradientHandles(g: VectorGradient, bounds: VectorBounds | null | undefined, toWorld?: VectorMatrix): {
840
+ start: Vec2;
841
+ end: Vec2;
842
+ aspect: Vec2 | null;
843
+ focal: Vec2 | null;
844
+ };
845
+ /**
846
+ * The gradient (pinned to the node's space) with a handle dragged to node-space point `to`.
847
+ * `start` moves the whole gradient by `to − from`; `end` / `radius` move the end, the secondary
848
+ * axis and focal point following; `aspect` sets the secondary axis' length square to the main
849
+ * one; `focal` sets the focal point (pulled inside the circle; null centres it).
850
+ */
851
+ declare function moveVectorGradientHandle(g: VectorGradient, bounds: VectorBounds | null | undefined, handle: VectorGradientHandle, to: Vec2, from?: Vec2): VectorGradient;
852
+ /** The gradient set to run from `start` to `end` (node space), its secondary axis square to it with its aspect kept. */
853
+ declare function setVectorGradientVector(g: VectorGradient, bounds: VectorBounds | null | undefined, start: Vec2, end: Vec2): VectorGradient;
854
+ /** Most periods a spread is expanded to (vectorcraft `MAX_PERIODS`). */
855
+ declare const VECTOR_GRADIENT_MAX_PERIODS = 64;
856
+ /**
857
+ * Stops repeating the gradient's plain stops over periods `lo` … `hi` (integers, at most
858
+ * `VECTOR_GRADIENT_MAX_PERIODS`), period `k` mirrored when `mirrored(k)`; offsets over 0–1 span
859
+ * the whole range (vectorcraft `spread::expand`, which emulates `reflect` and `repeat` this way).
860
+ */
861
+ declare function periodicVectorGradientStops(stops: readonly VectorGradientStop[], lo: number, hi: number, mirrored: (k: number) => boolean): VectorGradientStop[];
862
+ /**
863
+ * A linear or reflected gradient's spread as stop periods over `area` (node space), for
864
+ * renderers (and combinations) without the spread mode: vectorcraft's SVG import emulates
865
+ * `reflect` and `repeat` this way. Returns where the periods start and end and their stops, or
866
+ * null when a linear gradient pads (nothing to repeat). Reflected gradients always get at least
867
+ * the period either side of the start (the one before it mirrored). `from` / `to` are the
868
+ * periods' ends along the frame's u axis (`matrix` maps the frame to node space).
869
+ */
870
+ declare function expandVectorGradientSpread(g: VectorGradient, bounds: VectorBounds | null | undefined, area: VectorBounds): {
871
+ start: Vec2;
872
+ end: Vec2;
873
+ from: number;
874
+ to: number;
875
+ matrix: VectorMatrix;
876
+ stops: VectorGradientStop[];
877
+ capped: boolean;
878
+ } | null;
879
+ /**
880
+ * A `<pattern>` paint server in user space: draw `gradients` (inside it or in `<defs>`) and then
881
+ * each tile (`d` filled with `fill`) in order, all in the painted element's user space (the
882
+ * `viewBox` in `attrs` matches the tile, so keep it). Conic and diamond gradients, and gradients along
883
+ * or across a stroke, take this form.
884
+ */
885
+ interface VectorSvgPatternDef {
886
+ id: string;
887
+ type: 'pattern';
888
+ /** `x`, `y`, `width`, `height`, `patternUnits="userSpaceOnUse"` and the matching `viewBox`. */
889
+ attrs: Record<string, string | number>;
890
+ gradients: SvgGradientDef[];
891
+ tiles: {
892
+ d: string;
893
+ fill: string;
894
+ }[];
895
+ }
896
+ /** A paint server for `fill` / `stroke`: a gradient element or a pattern of gradient tiles. */
897
+ type VectorPaintDef = SvgGradientDef | VectorSvgPatternDef;
898
+ interface VectorGradientSvgOptions {
899
+ /** The shape's box in its own space (for `objectBoundingBox` gradients). */
900
+ bounds?: VectorBounds | null;
901
+ /** The area the paint must cover (pattern tiles, spread periods); default `bounds` padded by 1. */
902
+ area?: VectorBounds | null;
903
+ /** Wedges of a conic gradient (default 72: 5° each). */
904
+ wedges?: number;
905
+ precision?: number;
906
+ }
907
+ /** The area a gradient on a shape with box `bounds` paints (the box padded by 1). */
908
+ declare const vectorGradientArea: (bounds: VectorBounds | null | undefined) => VectorBounds;
909
+ /**
910
+ * A user-space pattern tile over `area`. Without a `viewBox` SVG puts the content's origin at the
911
+ * tile's corner; the matching `viewBox` keeps the content in the painted element's user space.
912
+ */
913
+ declare function patternAttrs(area: VectorBounds): Record<string, string>;
914
+ /**
915
+ * The SVG paint servers of a gradient on a shape: the first def's id is `id` (reference it as
916
+ * `url(#id)`), any others are what it uses. All are in the user space of the element painted
917
+ * (the node's own space).
918
+ */
919
+ declare function vectorGradientSvgDefs(g: VectorGradient, id: string, options?: VectorGradientSvgOptions): VectorPaintDef[];
920
+ /**
921
+ * What a `userSpaceOnUse` paint server from `vectorGradientSvgDefs` paints at point `p` (straight
922
+ * alpha, 0–1) the way an SVG renderer would: a gradient's stops interpolated in sRGB, a pattern's
923
+ * topmost tile containing `p`. Null for a point no tile covers.
924
+ */
925
+ declare function sampleVectorPaintDefAt(defs: readonly VectorPaintDef[], id: string, p: Vec2): VectorRgba | null;
926
+ /**
927
+ * A gradient from untrusted input (agent commands, SVG data attributes), or null when it is not
928
+ * one: unknown fields dropped, numbers clamped, at least one stop.
929
+ */
930
+ declare function sanitizeVectorGradient(input: unknown): VectorGradient | null;
931
+ /**
932
+ * A gradient changed to style `type`, keeping its stops, colour settings and placement: explicit
933
+ * points stay where they are (a linear end becomes a radius), shorthand is redone for the style.
934
+ */
935
+ declare function convertVectorGradient(g: VectorGradient, type: VectorGradientType): VectorGradient;
936
+ /** A default gradient for a paint that was a colour (or nothing): the colour fading to white. */
937
+ declare function defaultVectorGradient(type?: VectorGradientType, from?: VectorPaint): VectorGradient;
938
+ /**
939
+ * Changes to a gradient (`vector.setGradient`, the gradient editor): any gradient field, plus
940
+ * `aspect` (the secondary axis' length over the main one, square to it) and `reverse`. `focal` or
941
+ * `width` set to null removes them.
942
+ */
943
+ interface VectorGradientPatch extends Partial<Omit<VectorGradient, 'focal' | 'width'>> {
944
+ focal?: Vec2 | null;
945
+ width?: Vec2 | null;
946
+ aspect?: number;
947
+ reverse?: boolean;
948
+ }
949
+ /** `g` with `patch` applied (a style change converts it first), or null when the result is not a gradient. */
950
+ declare function applyVectorGradientPatch(g: VectorGradient, patch: VectorGradientPatch): VectorGradient | null;
951
+
580
952
  interface VectorSvgExportOptions {
581
953
  /** Decimal places for coordinates (default 3). */
582
954
  precision?: number;
@@ -599,10 +971,23 @@ interface VectorSvgExportOptions {
599
971
  declare function vectorCornersAttribute(subpaths: readonly VectorSubpath[], precision?: number): string;
600
972
  /** Puts `data-vector-corners` back on subpaths (malformed entries are ignored). */
601
973
  declare function applyVectorCornersAttribute(subpaths: VectorSubpath[], value: string): VectorSubpath[];
602
- /** A paint as an SVG attribute value plus the gradient def it needs (if any). */
603
- declare function vectorPaintToSvg(paint: VectorPaint | undefined, gradientId: string): {
974
+ /** Where a paint goes: what `vectorPaintToSvg` needs to place a gradient on a shape. */
975
+ interface VectorPaintSvgOptions {
976
+ /** The path painted (its box places `objectBoundingBox` gradients; strokes need its geometry). */
977
+ node?: VectorPathNode;
978
+ /** `stroke` lays `along` / `across` gradients on the stroke and covers its reach (default `fill`). */
979
+ role?: 'fill' | 'stroke';
980
+ precision?: number;
981
+ }
982
+ /** The box of a path's drawn outline in its own space (null when it has no points). */
983
+ declare function vectorPathLocalBounds(node: VectorPathNode): VectorBounds | null;
984
+ /**
985
+ * A paint as an SVG attribute value plus the paint servers it needs (`url(#id)` refers to the
986
+ * first). Gradients sit in the painted element's user space (the node's own space).
987
+ */
988
+ declare function vectorPaintToSvg(paint: VectorPaint | undefined, gradientId: string, options?: VectorPaintSvgOptions): {
604
989
  value: string;
605
- gradient: SvgGradientDef | null;
990
+ defs: VectorPaintDef[];
606
991
  };
607
992
  /** The parts of an aligned or arrowed stroke (see `VectorRenderPath.strokeParts`). */
608
993
  interface VectorRenderStrokeParts {
@@ -833,6 +1218,325 @@ declare function pressureWidthProfile(samples: readonly {
833
1218
  tolerance?: number;
834
1219
  }): VectorWidthPoint[];
835
1220
 
1221
+ /**
1222
+ * The Gradient tool's on-canvas annotator: a bar from the start (or centre) handle to the end (or
1223
+ * radius) handle with the colour stops under it and midpoint diamonds above it, plus a radial,
1224
+ * conic or diamond gradient's extent outline, aspect handle and (radial) focal point. All in
1225
+ * screen pixels, for hit-testing and the overlay.
1226
+ *
1227
+ * After vectorcraft `crates/tools/src/xform/gradient.rs` (`Annotator`: stop chips below the bar,
1228
+ * midpoints above it, a stop dragged off the bar is removed, a click on the bar adds one), ArtCraft,
1229
+ * MIT OR Apache-2.0 — see THIRD_PARTY_NOTICES.md.
1230
+ */
1231
+
1232
+ /** Which paint of the selection the Gradient tool and the gradient editor work on. */
1233
+ type VectorGradientTarget = 'fill' | 'stroke';
1234
+ /** A part of the annotator under the pointer. */
1235
+ type VectorGradientPart = {
1236
+ kind: 'handle';
1237
+ handle: VectorGradientHandle;
1238
+ } | {
1239
+ kind: 'stop';
1240
+ index: number;
1241
+ } | {
1242
+ kind: 'midpoint';
1243
+ index: number;
1244
+ }
1245
+ /** The bar at `offset` (0–1): a click adds a stop there, a drag moves the gradient. */
1246
+ | {
1247
+ kind: 'bar';
1248
+ offset: number;
1249
+ };
1250
+ /** Distance of the stop chips below the bar, the midpoint diamonds above it (screen pixels). */
1251
+ declare const VECTOR_GRADIENT_STOP_GAP = 12;
1252
+ declare const VECTOR_GRADIENT_MIDPOINT_GAP = 9;
1253
+ /** How far off the bar a dragged stop goes before it is removed (screen pixels). */
1254
+ declare const VECTOR_GRADIENT_OFF_BAR = 24;
1255
+ interface VectorGradientAnnotator {
1256
+ nodeId: string;
1257
+ target: VectorGradientTarget;
1258
+ gradient: VectorGradient;
1259
+ /** The path's box in its own space. */
1260
+ bounds: VectorBounds | null;
1261
+ /** The path's own space → document. */
1262
+ world: AffineMatrix;
1263
+ /** Screen positions of the handles. */
1264
+ start: Vec2;
1265
+ end: Vec2;
1266
+ /** Radial, conic and diamond gradients. */
1267
+ aspect: Vec2 | null;
1268
+ /** Radial gradients. */
1269
+ focal: Vec2 | null;
1270
+ /** Unit normal to the bar towards the stop chips (screen). */
1271
+ normal: Vec2;
1272
+ /** Stops (sorted, as the gradient stores them) with their chips' screen positions. */
1273
+ stops: (VectorGradientStop & {
1274
+ index: number;
1275
+ x: number;
1276
+ y: number;
1277
+ })[];
1278
+ /** The midpoint diamond after each stop but the last (screen). */
1279
+ midpoints: {
1280
+ index: number;
1281
+ x: number;
1282
+ y: number;
1283
+ midpoint: number;
1284
+ }[];
1285
+ /** Screen path of the extent: an ellipse (radial, conic) or a rhombus (diamond). */
1286
+ extent: string | null;
1287
+ }
1288
+ /** The path whose `target` paint the annotator shows: the first path of the selection with a gradient there. */
1289
+ declare function vectorGradientTargetPath(doc: VectorDocument, selection: readonly string[], target: VectorGradientTarget): VectorPathNode | null;
1290
+ /** The annotator of the selection's gradient (`target` paint), in screen pixels, or null when it has none. */
1291
+ declare function getVectorGradientAnnotator(doc: VectorDocument, selection: readonly string[], viewport: VectorViewport, target: VectorGradientTarget): VectorGradientAnnotator | null;
1292
+ /** Where `p` lies relative to the bar: offset along it (0 at the start, 1 at the end) and distance towards the stop chips. */
1293
+ declare function vectorGradientBarPosition(a: Pick<VectorGradientAnnotator, 'start' | 'end' | 'normal'>, p: Vec2): {
1294
+ offset: number;
1295
+ across: number;
1296
+ };
1297
+ /** The annotator part under screen point `p`: stops, then midpoints, the handles and the bar. */
1298
+ declare function hitVectorGradientAnnotator(a: VectorGradientAnnotator, p: Vec2): VectorGradientPart | null;
1299
+
1300
+ /**
1301
+ * Live appearance: path effect stacks and live boolean groups, evaluated on demand while the
1302
+ * stored anchors and children stay editable.
1303
+ *
1304
+ * `expandVectorAppearance` is the one place the effected geometry is made (cached per node
1305
+ * object, so an edit recomputes only the nodes it replaced). Rendering, hit-testing, bounds,
1306
+ * snapping, booleans, the Pathfinder, the Shape Builder and SVG export all read it, the way they
1307
+ * read live corners through `subpathsToBezier`; Expand Appearance stores it.
1308
+ *
1309
+ * Stacking follows After Effects' shape layers (effectcraft `crates/render/src/shapes.rs`): an
1310
+ * effect acts on every path above it — the node's own outline, or for a group every path of its
1311
+ * children (nested groups included, as drawn by their own effects) — in the order of the stack,
1312
+ * and effects placed after a repeater act on its copies. The result paints with the style of the
1313
+ * path each shape came from; Merge Paths and live booleans paint with the bottom one's.
1314
+ *
1315
+ * Live booleans fold their operands bottom to top, each combined with the result below it by its
1316
+ * own operation or the group's, and every prefix of the fold is cached under a rolling hash of the
1317
+ * operands it covers, so editing one operand recombines only the operands from it up; the cache
1318
+ * drops its least recently used half when full. Live groups are hit by their result except while
1319
+ * they are being edited (`vectorEnteredGroups`).
1320
+ *
1321
+ * Ported from ArtCraft (MIT OR Apache-2.0, © ArtCraft Team and contributors; see
1322
+ * THIRD_PARTY_NOTICES.md): the stacking rule of effectcraft `crates/render/src/shapes.rs`
1323
+ * (`collect()`); figcraft `crates/render/src/boolean.rs` (`fold_cached`, `PathCache`) and
1324
+ * `crates/engine/src/booleans.rs` (`operand_op`, `result_outline`); and the live-object model of
1325
+ * vectorcraft `crates/doc/src/live.rs` (`expand_live`, `expanded_group`, `subtree_has_live`).
1326
+ */
1327
+
1328
+ /** One shape of a node's appearance: a path in the node's own space, painted in `source`'s style. */
1329
+ interface VectorAppearanceShape {
1330
+ /** The path whose style paints it. */
1331
+ source: VectorPathNode;
1332
+ path: BezierPath;
1333
+ /** Opacity factor relative to the node (its own opacity not included). */
1334
+ opacity: number;
1335
+ /** Draw-order key (compared element by element). */
1336
+ order: number[];
1337
+ }
1338
+ /** Default parameters of each effect type. */
1339
+ declare const VECTOR_EFFECT_DEFAULTS: {
1340
+ readonly [K in VectorEffectType]: VectorEffectParamsMap[K];
1341
+ };
1342
+ declare const VECTOR_EFFECT_LABELS: Record<VectorEffectType, string>;
1343
+ /** How a panel edits one effect parameter. */
1344
+ type VectorEffectParamSpec = {
1345
+ key: string;
1346
+ label: string;
1347
+ kind: 'number';
1348
+ min?: number;
1349
+ max?: number;
1350
+ step: number;
1351
+ slider?: boolean;
1352
+ } | {
1353
+ key: string;
1354
+ label: string;
1355
+ kind: 'vec2';
1356
+ step: number;
1357
+ } | {
1358
+ key: string;
1359
+ label: string;
1360
+ kind: 'boolean';
1361
+ } | {
1362
+ key: string;
1363
+ label: string;
1364
+ kind: 'select';
1365
+ options: {
1366
+ value: string;
1367
+ label: string;
1368
+ }[];
1369
+ };
1370
+ /** The editable parameters of each effect type, in panel order. */
1371
+ declare const VECTOR_EFFECT_PARAM_SPECS: Record<VectorEffectType, VectorEffectParamSpec[]>;
1372
+ /** Envelope parameters. */
1373
+ type VectorEnvelopeParams = VectorEffectParamsMap['envelope'];
1374
+ /**
1375
+ * The envelope's mesh over `bounds` (the paths' combined bounds), in the node's space: its own
1376
+ * mesh, the flat mesh of `columns × rows` patches, or a preset split exactly into that many patches.
1377
+ */
1378
+ declare function vectorEnvelopeMesh(params: VectorEnvelopeParams, bounds: VectorBounds): VectorWarpMesh;
1379
+ /** The envelope as a map of the node's space over `bounds`, or null when it changes nothing (or the box is empty). */
1380
+ declare function vectorEnvelopeMap(params: VectorEnvelopeParams, bounds: VectorBounds | null): ((p: {
1381
+ x: number;
1382
+ y: number;
1383
+ }) => {
1384
+ x: number;
1385
+ y: number;
1386
+ }) | null;
1387
+ /**
1388
+ * Effect parameters with defaults filled in and invalid values dropped (unknown keys go too).
1389
+ * Returns null for an unknown type.
1390
+ */
1391
+ declare function normalizeVectorEffectParams<K extends VectorEffectType>(type: K, params: Record<string, unknown> | null | undefined, base?: VectorEffectParamsMap[K]): VectorEffectParamsMap[K] | null;
1392
+ /** A new effect of `type` (defaults merged with `params`), or null for an unknown type. */
1393
+ declare function createVectorEffect<K extends VectorEffectType>(type: K, id: string, params?: Partial<VectorEffectParamsMap[K]> | Record<string, unknown>): Extract<VectorEffect, {
1394
+ type: K;
1395
+ }> | null;
1396
+ /** The node's effects that take part (enabled, of a known type). */
1397
+ declare function activeVectorEffects(node: VectorNode): VectorEffect[];
1398
+ /** Whether the node itself draws differently from its stored geometry (effects or a live boolean). */
1399
+ declare function hasOwnVectorAppearance(node: VectorNode): boolean;
1400
+ /** Whether the node or anything inside it has a live appearance. */
1401
+ declare function hasVectorAppearance(node: VectorNode): boolean;
1402
+ /** A live boolean group (its children are operands). */
1403
+ declare function isVectorLiveBoolean(node: VectorNode | null | undefined): node is VectorGroupNode & {
1404
+ liveBoolean: VectorBooleanOperation;
1405
+ };
1406
+ /** How operand `child` of a live boolean group combines with the operands below it. */
1407
+ declare function vectorOperandOperation(group: VectorGroupNode, child: VectorNode): VectorBooleanOperation;
1408
+ /** How many boolean steps (one operand combined with the result below it) live booleans have computed: what a cache miss costs. */
1409
+ declare function vectorLiveBooleanSteps(): number;
1410
+ /** Empties the live boolean prefix cache. */
1411
+ declare function clearVectorLiveBooleanCache(): void;
1412
+ /** One operand of a live boolean: its outline (group space), fill rule and operation (unused for the bottom one). */
1413
+ interface VectorBooleanOperand {
1414
+ path: BezierPath;
1415
+ fillRule: VectorFillRule;
1416
+ operation: VectorBooleanOperation;
1417
+ }
1418
+ /**
1419
+ * The result of folding `operands` bottom to top, reusing the longest cached prefix: only the
1420
+ * operands above it are combined. Invalid geometry gives an empty path.
1421
+ */
1422
+ declare function foldVectorBooleanOperands(operands: readonly VectorBooleanOperand[]): BezierPath;
1423
+ /** Applies an effect stack to shapes, top to bottom (disabled effects skipped). */
1424
+ declare function applyVectorEffects(shapes: readonly VectorAppearanceShape[], effects: readonly VectorEffect[] | null | undefined): VectorAppearanceShape[];
1425
+ /** The paths entering effect `effectId` of the node's stack (those above it applied), in the node's own space. */
1426
+ declare function vectorEffectInputPaths(node: VectorNode, effectId: string): BezierPath[] | null;
1427
+ /** The box effect `effectId` (an envelope) bends: the combined bounds of the paths entering it, in the node's own space. */
1428
+ declare function vectorEffectInputBounds(node: VectorNode, effectId: string): VectorBounds | null;
1429
+ /** The node's first enabled envelope effect, or null. */
1430
+ declare function vectorNodeEnvelope(node: VectorNode | null | undefined): Extract<VectorEffect, {
1431
+ type: 'envelope';
1432
+ }> | null;
1433
+ /**
1434
+ * The editable mesh of a node's envelope (its own mesh, or the preset or flat mesh it stands for)
1435
+ * with the box it bends, in the node's own space; null without an envelope or contents.
1436
+ */
1437
+ declare function vectorEnvelopeFrame(node: VectorNode, effectId?: string): {
1438
+ effectId: string;
1439
+ bounds: VectorBounds;
1440
+ mesh: VectorWarpMesh;
1441
+ } | null;
1442
+ /**
1443
+ * What a node draws as: shapes in its own space (its `transform` and opacity not applied),
1444
+ * bottom to top, with its effects and those of everything inside it applied. Cached per node
1445
+ * object.
1446
+ */
1447
+ declare function vectorAppearanceShapes(node: VectorNode): VectorAppearanceShape[];
1448
+ /** Everything a node draws as one path in its own space (live corners cut, effects applied). */
1449
+ declare function vectorAppearanceOutline(node: VectorNode): BezierPath;
1450
+ /** What a node draws as, one plain path per shape (ids `<id>~fx<n>`, opacity relative to the node). */
1451
+ declare function vectorAppearanceNodes(node: VectorNode): VectorPathNode[];
1452
+ /**
1453
+ * The node as plain geometry: path effects and live booleans evaluated into paths (the node
1454
+ * itself when nothing inside it is live). A path keeps its id when it draws as one shape;
1455
+ * otherwise, like any live group, it becomes a group with that id holding one path per shape
1456
+ * (ids `<id>~fx<n>`). Groups without effects of their own keep their structure. Cached per node.
1457
+ */
1458
+ declare function expandVectorAppearance(node: VectorNode): VectorNode;
1459
+ /** Every node of a list expanded (the same array when nothing in it is live). */
1460
+ declare function expandVectorAppearances(nodes: readonly VectorNode[]): VectorNode[];
1461
+ /**
1462
+ * Reads effects from untrusted data (JSON, agent input): unknown types and malformed entries are
1463
+ * dropped, parameters normalized, ids made unique.
1464
+ */
1465
+ declare function sanitizeVectorEffects(value: unknown): VectorEffect[];
1466
+ /**
1467
+ * Effect parameters carried through a linear map baked into a node's geometry (scaling or
1468
+ * flipping it): offsets and positions move with it, angles turn the other way when it mirrors.
1469
+ * Lengths such as sizes and radii are kept, like stroke widths.
1470
+ */
1471
+ declare function transformVectorEffects(effects: readonly VectorEffect[], m: AffineMatrix, node?: VectorNode): VectorEffect[];
1472
+ /**
1473
+ * The live groups (live booleans and groups with effects) being edited: those in `ids` and those
1474
+ * holding a node in `ids`. Their children are hit and outlined as stored instead of as drawn, so
1475
+ * each operand can be picked (figcraft `crates/engine/src/booleans.rs`, `result_outline`).
1476
+ */
1477
+ declare function vectorEnteredGroups(nodes: readonly VectorNode[], ids: readonly string[]): Set<string>;
1478
+
1479
+ /** A map of the plane (document or node space). */
1480
+ type VectorPointMap = (p: Vec2) => Vec2;
1481
+ /** Every anchor and handle of `subpaths` through `f` (no subdivision). */
1482
+ declare function mapVectorPoints(subpaths: readonly VectorSubpath[], f: VectorPointMap): VectorSubpath[];
1483
+ interface MapVectorSubpathsOptions {
1484
+ /** Refit runs of split pieces with fewer cubics where they stay within the tolerance (default true). */
1485
+ refit?: boolean;
1486
+ }
1487
+ /**
1488
+ * `subpaths` through a smooth, possibly non-linear map `f`: each segment is split in halves until
1489
+ * its mapped control points follow the mapped curve within `tolerance` (at most 64 pieces a
1490
+ * segment, fewer for huge paths), then refitted with fewer cubics where possible. A straight
1491
+ * segment whose image is straight stays a straight segment; anchors keep their types and live
1492
+ * corners, and the anchors added are smooth.
1493
+ */
1494
+ declare function mapVectorSubpaths(subpaths: readonly VectorSubpath[], f: VectorPointMap, tolerance?: number, options?: MapVectorSubpathsOptions): VectorSubpath[];
1495
+ /** `mapVectorSubpaths` for Bézier commands (live corners are not involved). */
1496
+ declare function mapBezierPath(path: BezierPathInput, f: VectorPointMap, tolerance?: number, options?: MapVectorSubpathsOptions): BezierPath;
1497
+
1498
+ /**
1499
+ * Free Distort, perspective and skew: the selection box's corners or sides dragged, and nodes sent
1500
+ * through a map of document space while each keeps its own (rigid) transform.
1501
+ *
1502
+ * Ported from ArtCraft (MIT OR Apache-2.0, © ArtCraft Team and contributors; see
1503
+ * THIRD_PARTY_NOTICES.md): vectorcraft `crates/tools/src/xform/free.rs` (`distort_quad`: a corner
1504
+ * moved freely, or with its partner mirrored along the dominant axis for perspective, and a side's
1505
+ * two corners moved together; `shear_for_side`: a side handle shears about the opposite side, or
1506
+ * the centre with Alt).
1507
+ */
1508
+
1509
+ /** Default tolerance (document units) of Free Distort's adaptive path mapping. */
1510
+ declare const VECTOR_DISTORT_TOLERANCE = 0.05;
1511
+ /** How dragging a selection box handle distorts it: each corner freely, or in symmetric perspective. */
1512
+ type VectorDistortMode = 'distort' | 'perspective';
1513
+ /** A box's corners clockwise from the top left. */
1514
+ declare const vectorBoxCorners: (b: VectorBounds) => Vec2[];
1515
+ /**
1516
+ * The quad (clockwise from the top left) box `b` becomes when handle `handle` is dragged by `d`: a
1517
+ * corner moves by `d` (`distort`), or along the drag's dominant axis with the corner beside it on
1518
+ * that side moving the opposite way (`perspective`); a side moves both its corners.
1519
+ */
1520
+ declare function vectorDistortQuad(b: VectorBounds, handle: VectorTransformHandle, d: Vec2, mode?: VectorDistortMode): Vec2[];
1521
+ /**
1522
+ * The skew for dragging side `handle` of box `b` by `d`: along that side, about the opposite side
1523
+ * (or the centre, `fromCenter`). Corners give the identity.
1524
+ */
1525
+ declare function vectorShearForSide(b: VectorBounds, handle: VectorTransformHandle, d: Vec2, fromCenter?: boolean): AffineMatrix;
1526
+ /**
1527
+ * A skew by `ax` degrees horizontally (vertical lines lean right for positive angles: x' = x + tan(ax)·y)
1528
+ * and `ay` degrees vertically (y' = y + tan(ay)·x), about `origin`.
1529
+ */
1530
+ declare function vectorSkewMatrix(ax: number, ay: number, origin?: Vec2): AffineMatrix;
1531
+ /**
1532
+ * A node sent through `f`, a map of the space `parentToDoc` maps its parent to (the document):
1533
+ * every anchor and handle is mapped in the node's own space, adaptively so curves stay within
1534
+ * `tolerance`, and the node keeps its rigid `transform`. Gradients in the node's space have their
1535
+ * handles mapped (bounding-box ones follow the new bounds), envelope meshes and a blend's spine
1536
+ * are mapped too; stroke widths, live corner radii and effect parameters are kept.
1537
+ */
1538
+ declare function distortVectorNode<T extends VectorNode>(node: T, parentToDoc: AffineMatrix, f: VectorPointMap, tolerance?: number): T;
1539
+
836
1540
  /**
837
1541
  * What a guide line shows: `align` lines run from a target through the snapped point or box,
838
1542
  * `construction` lines from where a drawn point leaves, `spacing` marks equal gaps and `size`
@@ -1101,6 +1805,8 @@ interface VectorEditorOptions {
1101
1805
  createId?: () => string;
1102
1806
  /** Called after the document changes (edits, undo, redo, load). */
1103
1807
  onChange?: (document: VectorDocument) => void;
1808
+ /** Start in Free Distort mode (see `setFreeDistort`). */
1809
+ freeDistort?: boolean;
1104
1810
  }
1105
1811
  /** A pointer event as the controller needs it. Positions are in screen pixels relative to the canvas. */
1106
1812
  interface VectorPointerInput extends VectorModifiers {
@@ -1170,6 +1876,13 @@ interface VectorHover {
1170
1876
  };
1171
1877
  /** A spot on a stroke away from its width points (width tool). */
1172
1878
  strokeSpot?: VectorStrokeSpot;
1879
+ /** A part of the gradient annotator (gradient tool). */
1880
+ gradient?: VectorGradientPart;
1881
+ /** A control point of the selected envelope's mesh (`index`), or a spot inside it (`index` null): Envelope tool. */
1882
+ envelope?: {
1883
+ nodeId: string;
1884
+ index: number | null;
1885
+ };
1173
1886
  }
1174
1887
  /** The drag in progress, for overlays and status text. */
1175
1888
  type VectorInteraction = {
@@ -1224,6 +1937,25 @@ type VectorInteraction = {
1224
1937
  } | {
1225
1938
  type: 'pen';
1226
1939
  nodeId: string;
1940
+ }
1941
+ /** A gradient tool drag: drawing a new vector, or a handle, stop, midpoint or the bar (`removing`: a stop dragged off the bar). */
1942
+ | {
1943
+ type: 'gradient';
1944
+ part: 'create' | VectorGradientPart['kind'];
1945
+ handle?: VectorGradientHandle;
1946
+ removing?: boolean;
1947
+ }
1948
+ /** Free Distort: the selection box's corners as dragged so far (document space, clockwise from the top left). */
1949
+ | {
1950
+ type: 'distort';
1951
+ mode: VectorDistortMode | 'skew';
1952
+ corners: Vec2[];
1953
+ }
1954
+ /** Envelope tool: a mesh point (`index`) or the surface (`index` null) being dragged. */
1955
+ | {
1956
+ type: 'envelope';
1957
+ nodeId: string;
1958
+ index: number | null;
1227
1959
  } | {
1228
1960
  type: 'pan';
1229
1961
  };
@@ -1269,6 +2001,17 @@ interface VectorEditorState {
1269
2001
  blendStart: VectorBlendStart | null;
1270
2002
  /** Options new blends get. */
1271
2003
  blendDefaults: VectorBlendOptions;
2004
+ /** The paint the gradient tool and gradient editor work on, and the selected stop (index into the sorted stops). */
2005
+ gradientEdit: {
2006
+ target: VectorGradientTarget;
2007
+ stop: number | null;
2008
+ };
2009
+ /**
2010
+ * Free Distort mode of the selection box: dragging a corner distorts in perspective (each corner
2011
+ * on its own; Shift+Alt+Mod: symmetric perspective), a side moves its two corners, and Mod-dragging
2012
+ * a side skews along it (Alt: about the centre).
2013
+ */
2014
+ freeDistort: boolean;
1272
2015
  canUndo: boolean;
1273
2016
  canRedo: boolean;
1274
2017
  undoLabel: string;
@@ -1474,6 +2217,19 @@ interface VectorSelectionBoxGeometry {
1474
2217
  corners: Vec2[];
1475
2218
  }
1476
2219
  declare function getVectorSelectionBoxGeometry(frame: VectorSelectionFrame, viewport: VectorViewport): VectorSelectionBoxGeometry;
2220
+ /**
2221
+ * The node the Envelope tool edits: the one selected node with an enabled envelope, with the
2222
+ * envelope's mesh and box (node space) and the node → document matrix. Null otherwise.
2223
+ */
2224
+ declare function getVectorEnvelopeTarget(doc: VectorDocument, selection: readonly string[]): {
2225
+ node: VectorNode;
2226
+ frame: {
2227
+ effectId: string;
2228
+ bounds: VectorBounds;
2229
+ mesh: VectorWarpMesh;
2230
+ };
2231
+ world: AffineMatrix;
2232
+ } | null;
1477
2233
  /** The resize cursor for a handle of a box rotated by `angle` degrees. */
1478
2234
  declare function vectorResizeCursor(handle: VectorTransformHandle, angle?: number): string;
1479
2235
  declare function vectorToolLabel(tool: VectorTool): string;
@@ -1524,6 +2280,8 @@ declare class VectorEditorController {
1524
2280
  private blendStart;
1525
2281
  /** Options new blends get (the toolbars edit them along with the selected blend's). */
1526
2282
  private blendDefaults;
2283
+ private gradientEdit;
2284
+ private freeDistort;
1527
2285
  /** What the highlight shows, to skip notifying when the pointer stays over the same face. */
1528
2286
  private builderHoverKey;
1529
2287
  private readonly createId;
@@ -1536,7 +2294,13 @@ declare class VectorEditorController {
1536
2294
  private revision;
1537
2295
  private state;
1538
2296
  constructor(options?: VectorEditorOptions);
1539
- /** Stops listening to the history. */
2297
+ /** Listens to the history (once; again after `destroy`). */
2298
+ private connect;
2299
+ private historyDiffers;
2300
+ /**
2301
+ * Stops listening to the history and drops all listeners. A later `subscribe` reconnects, so a
2302
+ * controller torn down by React StrictMode's double effect keeps working when it is reused.
2303
+ */
1540
2304
  destroy(): void;
1541
2305
  /** The current snapshot (stable until the next change). */
1542
2306
  getState: () => VectorEditorState;
@@ -1658,6 +2422,47 @@ declare class VectorEditorController {
1658
2422
  } | null, options?: {
1659
2423
  ids?: readonly string[];
1660
2424
  }): VectorActionResult;
2425
+ /** Which paint (fill or stroke) the gradient tool and editor work on. */
2426
+ setGradientTarget(target: VectorGradientTarget): void;
2427
+ /** Selects a stop of the gradient being edited (index into its sorted stops), or none. */
2428
+ selectGradientStop(index: number | null): void;
2429
+ /** The gradient tool's annotator for the selection (screen pixels), or null when its paint is not a gradient. */
2430
+ getGradientAnnotator(): VectorGradientAnnotator | null;
2431
+ /** Unlocked paths of `ids` (default: the selection). */
2432
+ private gradientPaths;
2433
+ /**
2434
+ * Edits the gradient of the `target` paint (default: the editor's) of the selected (or given)
2435
+ * paths with `patch`: a colour or no paint becomes a gradient (`patch.type`, default linear,
2436
+ * from the colour to white). Consecutive edits with the same `merge` key are one undo step.
2437
+ */
2438
+ setGradient(patch: VectorGradientPatch, options?: {
2439
+ ids?: readonly string[];
2440
+ target?: VectorGradientTarget;
2441
+ label?: string;
2442
+ merge?: string;
2443
+ }): VectorActionResult;
2444
+ /** Applies `fn` to every target gradient of the selection (paths whose paint is not a gradient are skipped). */
2445
+ private editGradients;
2446
+ /** Changes stop `index` (colour, opacity, offset or midpoint) of the selection's gradients; selects it. */
2447
+ setGradientStop(index: number, patch: {
2448
+ color?: string;
2449
+ opacity?: number;
2450
+ offset?: number;
2451
+ midpoint?: number;
2452
+ }, options?: {
2453
+ merge?: string;
2454
+ }): VectorActionResult;
2455
+ /** Adds a stop at `offset` (painting what the gradient paints there) to the selection's gradients and selects it. */
2456
+ addGradientStop(offset: number): VectorActionResult;
2457
+ /** Removes stop `index` of the selection's gradients (never below two stops). */
2458
+ removeGradientStop(index: number): VectorActionResult;
2459
+ /** Reverses the selection's gradients (stops and midpoints). */
2460
+ reverseGradient(): VectorActionResult;
2461
+ /** `doc` with path `id`'s `target` paint replaced. */
2462
+ private withGradient;
2463
+ private downGradient;
2464
+ private moveGradient;
2465
+ private upGradient;
1661
2466
  /** Removes one width point of a path's profile. */
1662
2467
  removeWidthPoint(ref: Pick<VectorWidthPointRef, 'nodeId' | 'index'>): VectorActionResult;
1663
2468
  /** Removes width points (default: the selected ones — the width tool's Delete), as one undo step. */
@@ -1783,6 +2588,83 @@ declare class VectorEditorController {
1783
2588
  private selectedRoots;
1784
2589
  /** `m`, given in a frame rotated by `angle`, as a document-space matrix. */
1785
2590
  private inFrame;
2591
+ /** The selection frame's corners in document space, clockwise from the top left. */
2592
+ private frameCorners;
2593
+ /** `doc` with nodes `ids` sent through `f` (a map of document space), each in its own space (see `distortVectorNode`). */
2594
+ private distorted;
2595
+ /**
2596
+ * Free Distort mode of the selection box (`state.freeDistort`): dragging a corner distorts the
2597
+ * selection in perspective, each corner on its own (Shift+Alt+Mod: symmetric perspective, the
2598
+ * corner beside it moving the other way); dragging a side moves its two corners; Mod-dragging a
2599
+ * side skews along it (Alt: about the centre). Each drag is one undo step.
2600
+ */
2601
+ setFreeDistort(on: boolean): void;
2602
+ /**
2603
+ * Distorts the selected (or given) nodes so the corners of their selection box (clockwise from
2604
+ * the top left, in the box's own rotation) land on `corners` (document space): a projective map,
2605
+ * so straight lines stay straight. Curves are followed within `tolerance` (document units).
2606
+ * One undo step.
2607
+ */
2608
+ distort(corners: readonly Vec2[], options?: {
2609
+ ids?: readonly string[];
2610
+ tolerance?: number;
2611
+ }): VectorActionResult;
2612
+ /**
2613
+ * Skews the selected (or given) nodes along the selection box's own axes by `ax` degrees
2614
+ * horizontally (x' = x + tan(ax)·y: vertical lines lean right for positive angles) and `ay`
2615
+ * vertically, about `origin` (default: the box centre, document space). One undo step.
2616
+ */
2617
+ skew(ax: number, ay?: number, options?: {
2618
+ ids?: readonly string[];
2619
+ origin?: Vec2;
2620
+ }): VectorActionResult;
2621
+ /** A selection box handle dragged in Free Distort mode. */
2622
+ private moveDistort;
2623
+ /** Selected (or given) roots that can carry an envelope. */
2624
+ private envelopeTargets;
2625
+ /** Envelope parameters for `node` after `patch`: a preset switched to a mesh becomes the mesh it stood for. */
2626
+ private envelopeParams;
2627
+ /**
2628
+ * Gives the selected (or given) nodes an envelope distortion, or changes the one they have: a
2629
+ * warp preset (`style` with `bend`, `horizontal` and `vertical` in percent and `orientation`) or
2630
+ * a mesh (`style: 'mesh'` with `rows` and `columns`, and optionally its `mesh` points). The
2631
+ * envelope stays live (an `envelope` effect: edit it with the Envelope tool, Expand Appearance
2632
+ * bakes it). One undo step (with `merge`, consecutive changes fold into one, as a slider drag
2633
+ * should). Returns the envelope of each node.
2634
+ */
2635
+ envelope(params?: Partial<VectorEnvelopeParams>, options?: {
2636
+ ids?: readonly string[];
2637
+ merge?: boolean;
2638
+ }): {
2639
+ nodeId: string;
2640
+ effectId: string;
2641
+ }[];
2642
+ /**
2643
+ * Make with Top Object: the topmost selected object's outline (a closed path) becomes the envelope
2644
+ * of the other selected objects (grouped when there are several; they must share a parent), as a
2645
+ * mesh of `columns × rows` patches whose border follows the outline. The top object is used up.
2646
+ * One undo step; returns the id of the enveloped node.
2647
+ */
2648
+ makeEnvelopeWithTopObject(options?: {
2649
+ ids?: readonly string[];
2650
+ rows?: number;
2651
+ columns?: number;
2652
+ }): VectorActionResult & {
2653
+ nodeId?: string;
2654
+ };
2655
+ /**
2656
+ * Release: the selected (or given) nodes lose their envelope, and its shape (the mesh's border)
2657
+ * comes back as a path above each of them. One undo step; returns the new paths' ids.
2658
+ */
2659
+ releaseEnvelope(options?: {
2660
+ ids?: readonly string[];
2661
+ }): string[];
2662
+ /** The selected node the Envelope tool edits, with its mesh (node space) and node → document matrix. */
2663
+ private envelopeTarget;
2664
+ /** The envelope mesh point under `screen` (handles first), or a spot inside the mesh. */
2665
+ private hitEnvelope;
2666
+ private downEnvelope;
2667
+ private moveEnvelope;
1786
2668
  /** Applies a matrix to the selected (or given) nodes as one undo step. */
1787
2669
  transform(matrix: AffineMatrix, options?: {
1788
2670
  ids?: readonly string[];
@@ -2172,153 +3054,6 @@ declare function scaleFor(handle: VectorTransformHandle, b: VectorBounds, p: Vec
2172
3054
  origin: Vec2;
2173
3055
  };
2174
3056
 
2175
- /**
2176
- * Live appearance: path effect stacks and live boolean groups, evaluated on demand while the
2177
- * stored anchors and children stay editable.
2178
- *
2179
- * `expandVectorAppearance` is the one place the effected geometry is made (cached per node
2180
- * object, so an edit recomputes only the nodes it replaced). Rendering, hit-testing, bounds,
2181
- * snapping, booleans, the Pathfinder, the Shape Builder and SVG export all read it, the way they
2182
- * read live corners through `subpathsToBezier`; Expand Appearance stores it.
2183
- *
2184
- * Stacking follows After Effects' shape layers (effectcraft `crates/render/src/shapes.rs`): an
2185
- * effect acts on every path above it — the node's own outline, or for a group every path of its
2186
- * children (nested groups included, as drawn by their own effects) — in the order of the stack,
2187
- * and effects placed after a repeater act on its copies. The result paints with the style of the
2188
- * path each shape came from; Merge Paths and live booleans paint with the bottom one's.
2189
- *
2190
- * Live booleans fold their operands bottom to top, each combined with the result below it by its
2191
- * own operation or the group's, and every prefix of the fold is cached under a rolling hash of the
2192
- * operands it covers, so editing one operand recombines only the operands from it up; the cache
2193
- * drops its least recently used half when full. Live groups are hit by their result except while
2194
- * they are being edited (`vectorEnteredGroups`).
2195
- *
2196
- * Ported from ArtCraft (MIT OR Apache-2.0, © ArtCraft Team and contributors; see
2197
- * THIRD_PARTY_NOTICES.md): the stacking rule of effectcraft `crates/render/src/shapes.rs`
2198
- * (`collect()`); figcraft `crates/render/src/boolean.rs` (`fold_cached`, `PathCache`) and
2199
- * `crates/engine/src/booleans.rs` (`operand_op`, `result_outline`); and the live-object model of
2200
- * vectorcraft `crates/doc/src/live.rs` (`expand_live`, `expanded_group`, `subtree_has_live`).
2201
- */
2202
-
2203
- /** One shape of a node's appearance: a path in the node's own space, painted in `source`'s style. */
2204
- interface VectorAppearanceShape {
2205
- /** The path whose style paints it. */
2206
- source: VectorPathNode;
2207
- path: BezierPath;
2208
- /** Opacity factor relative to the node (its own opacity not included). */
2209
- opacity: number;
2210
- /** Draw-order key (compared element by element). */
2211
- order: number[];
2212
- }
2213
- /** Default parameters of each effect type. */
2214
- declare const VECTOR_EFFECT_DEFAULTS: {
2215
- readonly [K in VectorEffectType]: VectorEffectParamsMap[K];
2216
- };
2217
- declare const VECTOR_EFFECT_LABELS: Record<VectorEffectType, string>;
2218
- /** How a panel edits one effect parameter. */
2219
- type VectorEffectParamSpec = {
2220
- key: string;
2221
- label: string;
2222
- kind: 'number';
2223
- min?: number;
2224
- max?: number;
2225
- step: number;
2226
- slider?: boolean;
2227
- } | {
2228
- key: string;
2229
- label: string;
2230
- kind: 'vec2';
2231
- step: number;
2232
- } | {
2233
- key: string;
2234
- label: string;
2235
- kind: 'boolean';
2236
- } | {
2237
- key: string;
2238
- label: string;
2239
- kind: 'select';
2240
- options: {
2241
- value: string;
2242
- label: string;
2243
- }[];
2244
- };
2245
- /** The editable parameters of each effect type, in panel order. */
2246
- declare const VECTOR_EFFECT_PARAM_SPECS: Record<VectorEffectType, VectorEffectParamSpec[]>;
2247
- /**
2248
- * Effect parameters with defaults filled in and invalid values dropped (unknown keys go too).
2249
- * Returns null for an unknown type.
2250
- */
2251
- declare function normalizeVectorEffectParams<K extends VectorEffectType>(type: K, params: Record<string, unknown> | null | undefined, base?: VectorEffectParamsMap[K]): VectorEffectParamsMap[K] | null;
2252
- /** A new effect of `type` (defaults merged with `params`), or null for an unknown type. */
2253
- declare function createVectorEffect<K extends VectorEffectType>(type: K, id: string, params?: Partial<VectorEffectParamsMap[K]> | Record<string, unknown>): Extract<VectorEffect, {
2254
- type: K;
2255
- }> | null;
2256
- /** The node's effects that take part (enabled, of a known type). */
2257
- declare function activeVectorEffects(node: VectorNode): VectorEffect[];
2258
- /** Whether the node itself draws differently from its stored geometry (effects or a live boolean). */
2259
- declare function hasOwnVectorAppearance(node: VectorNode): boolean;
2260
- /** Whether the node or anything inside it has a live appearance. */
2261
- declare function hasVectorAppearance(node: VectorNode): boolean;
2262
- /** A live boolean group (its children are operands). */
2263
- declare function isVectorLiveBoolean(node: VectorNode | null | undefined): node is VectorGroupNode & {
2264
- liveBoolean: VectorBooleanOperation;
2265
- };
2266
- /** How operand `child` of a live boolean group combines with the operands below it. */
2267
- declare function vectorOperandOperation(group: VectorGroupNode, child: VectorNode): VectorBooleanOperation;
2268
- /** How many boolean steps (one operand combined with the result below it) live booleans have computed: what a cache miss costs. */
2269
- declare function vectorLiveBooleanSteps(): number;
2270
- /** Empties the live boolean prefix cache. */
2271
- declare function clearVectorLiveBooleanCache(): void;
2272
- /** One operand of a live boolean: its outline (group space), fill rule and operation (unused for the bottom one). */
2273
- interface VectorBooleanOperand {
2274
- path: BezierPath;
2275
- fillRule: VectorFillRule;
2276
- operation: VectorBooleanOperation;
2277
- }
2278
- /**
2279
- * The result of folding `operands` bottom to top, reusing the longest cached prefix: only the
2280
- * operands above it are combined. Invalid geometry gives an empty path.
2281
- */
2282
- declare function foldVectorBooleanOperands(operands: readonly VectorBooleanOperand[]): BezierPath;
2283
- /** Applies an effect stack to shapes, top to bottom (disabled effects skipped). */
2284
- declare function applyVectorEffects(shapes: readonly VectorAppearanceShape[], effects: readonly VectorEffect[] | null | undefined): VectorAppearanceShape[];
2285
- /**
2286
- * What a node draws as: shapes in its own space (its `transform` and opacity not applied),
2287
- * bottom to top, with its effects and those of everything inside it applied. Cached per node
2288
- * object.
2289
- */
2290
- declare function vectorAppearanceShapes(node: VectorNode): VectorAppearanceShape[];
2291
- /** Everything a node draws as one path in its own space (live corners cut, effects applied). */
2292
- declare function vectorAppearanceOutline(node: VectorNode): BezierPath;
2293
- /** What a node draws as, one plain path per shape (ids `<id>~fx<n>`, opacity relative to the node). */
2294
- declare function vectorAppearanceNodes(node: VectorNode): VectorPathNode[];
2295
- /**
2296
- * The node as plain geometry: path effects and live booleans evaluated into paths (the node
2297
- * itself when nothing inside it is live). A path keeps its id when it draws as one shape;
2298
- * otherwise, like any live group, it becomes a group with that id holding one path per shape
2299
- * (ids `<id>~fx<n>`). Groups without effects of their own keep their structure. Cached per node.
2300
- */
2301
- declare function expandVectorAppearance(node: VectorNode): VectorNode;
2302
- /** Every node of a list expanded (the same array when nothing in it is live). */
2303
- declare function expandVectorAppearances(nodes: readonly VectorNode[]): VectorNode[];
2304
- /**
2305
- * Reads effects from untrusted data (JSON, agent input): unknown types and malformed entries are
2306
- * dropped, parameters normalized, ids made unique.
2307
- */
2308
- declare function sanitizeVectorEffects(value: unknown): VectorEffect[];
2309
- /**
2310
- * Effect parameters carried through a linear map baked into a node's geometry (scaling or
2311
- * flipping it): offsets and positions move with it, angles turn the other way when it mirrors.
2312
- * Lengths such as sizes and radii are kept, like stroke widths.
2313
- */
2314
- declare function transformVectorEffects(effects: readonly VectorEffect[], m: AffineMatrix): VectorEffect[];
2315
- /**
2316
- * The live groups (live booleans and groups with effects) being edited: those in `ids` and those
2317
- * holding a node in `ids`. Their children are hit and outlined as stored instead of as drawn, so
2318
- * each operand can be picked (figcraft `crates/engine/src/booleans.rs`, `result_outline`).
2319
- */
2320
- declare function vectorEnteredGroups(nodes: readonly VectorNode[], ids: readonly string[]): Set<string>;
2321
-
2322
3057
  interface VectorRenderPath {
2323
3058
  kind: 'path';
2324
3059
  id: string;
@@ -2357,8 +3092,12 @@ interface VectorSceneRenderData {
2357
3092
  width: number;
2358
3093
  height: number;
2359
3094
  background?: string;
2360
- /** Gradients referenced by `fill` / `stroke` values. */
2361
- defs: SvgGradientDef[];
3095
+ /**
3096
+ * Paint servers referenced by `fill` / `stroke` values: `<linearGradient>` /
3097
+ * `<radialGradient>` descriptors and `pattern`s (conic, diamond and stroke-mode gradients:
3098
+ * draw each of `gradients`, then each tile filled, inside a `<pattern>`).
3099
+ */
3100
+ defs: VectorPaintDef[];
2362
3101
  /** Visible nodes, bottom to top. */
2363
3102
  nodes: VectorRenderNode[];
2364
3103
  }
@@ -2441,7 +3180,43 @@ interface VectorOverlayRenderData {
2441
3180
  transform: string;
2442
3181
  corners: Vec2[];
2443
3182
  handles: VectorSelectionBoxGeometry['handles'];
3183
+ freeDistort: boolean;
2444
3184
  }) | null;
3185
+ /**
3186
+ * A Free Distort drag (screen space): the quad the selection box's corners make so far (`d`,
3187
+ * closed path data) and its corners clockwise from the top left. The box is hidden meanwhile.
3188
+ */
3189
+ distort: {
3190
+ mode: 'distort' | 'perspective' | 'skew';
3191
+ d: string;
3192
+ corners: Vec2[];
3193
+ } | null;
3194
+ /**
3195
+ * The Envelope tool's mesh of the selected envelope (screen space): `grid` is the grid lines as
3196
+ * path data, `anchors` the points where they cross and `handles` the handles along them, each
3197
+ * with the anchor it belongs to (`index` is the point's index in the mesh). Draw anchors as
3198
+ * squares and handles as dots joined to their anchors.
3199
+ */
3200
+ envelope: {
3201
+ nodeId: string;
3202
+ grid: string;
3203
+ anchors: {
3204
+ index: number;
3205
+ x: number;
3206
+ y: number;
3207
+ hovered: boolean;
3208
+ active: boolean;
3209
+ }[];
3210
+ handles: {
3211
+ index: number;
3212
+ x: number;
3213
+ y: number;
3214
+ anchorX: number;
3215
+ anchorY: number;
3216
+ hovered: boolean;
3217
+ active: boolean;
3218
+ }[];
3219
+ } | null;
2445
3220
  anchors: VectorRenderAnchor[];
2446
3221
  handles: VectorRenderHandle[];
2447
3222
  /** Marquee rectangle, screen space. */
@@ -2528,9 +3303,62 @@ interface VectorOverlayRenderData {
2528
3303
  hovered: boolean;
2529
3304
  }[];
2530
3305
  };
3306
+ /** The gradient tool's annotator over the selection's gradient (screen space), or null. */
3307
+ gradient: VectorRenderGradientAnnotator | null;
2531
3308
  /** A short status, e.g. "W 120 × H 80" or "45°". */
2532
3309
  status: string | null;
2533
3310
  }
3311
+ /**
3312
+ * The gradient annotator in screen pixels: draw the `extent` outline (dashed), the bar from
3313
+ * `start` to `end`, the handles, each stop's chip (a swatch at `x, y` with a tick to `barX, barY`;
3314
+ * `removing`: the dragged stop is off the bar and will be deleted, draw it faded) and the
3315
+ * midpoint diamonds.
3316
+ */
3317
+ interface VectorRenderGradientAnnotator {
3318
+ nodeId: string;
3319
+ type: VectorGradientType;
3320
+ start: {
3321
+ x: number;
3322
+ y: number;
3323
+ hovered: boolean;
3324
+ };
3325
+ /** `radius` for radial, conic and diamond gradients. */
3326
+ end: {
3327
+ x: number;
3328
+ y: number;
3329
+ hovered: boolean;
3330
+ handle: 'end' | 'radius';
3331
+ };
3332
+ aspect: {
3333
+ x: number;
3334
+ y: number;
3335
+ hovered: boolean;
3336
+ } | null;
3337
+ focal: {
3338
+ x: number;
3339
+ y: number;
3340
+ hovered: boolean;
3341
+ } | null;
3342
+ stops: {
3343
+ index: number;
3344
+ x: number;
3345
+ y: number;
3346
+ barX: number;
3347
+ barY: number;
3348
+ color: string;
3349
+ opacity: number;
3350
+ selected: boolean;
3351
+ hovered: boolean;
3352
+ }[];
3353
+ midpoints: {
3354
+ index: number;
3355
+ x: number;
3356
+ y: number;
3357
+ hovered: boolean;
3358
+ }[];
3359
+ extent: string | null;
3360
+ removing: boolean;
3361
+ }
2534
3362
  /** Distance between the Shape Builder's hatch lines over a face (screen pixels). */
2535
3363
  declare const VECTOR_BUILDER_HATCH_GAP = 6;
2536
3364
  /**
@@ -2544,6 +3372,31 @@ declare function getVectorSceneRenderData(state: Pick<VectorEditorState, 'docume
2544
3372
  declare function getVectorEnteredGroups(state: Pick<VectorEditorState, 'document' | 'selection' | 'editingId'>): Set<string>;
2545
3373
  /** The editing overlay in screen pixels. Render it on top of the scene, untransformed. */
2546
3374
  declare function getVectorOverlayRenderData(state: VectorEditorState): VectorOverlayRenderData;
3375
+ /** Warp choices of an envelope: the fifteen presets, then Mesh. */
3376
+ declare const VECTOR_ENVELOPE_STYLE_OPTIONS: readonly {
3377
+ value: VectorEnvelopeParams['style'];
3378
+ label: string;
3379
+ }[];
3380
+ /** What a Distort / Envelope panel shows for the selection. */
3381
+ interface VectorEnvelopePanelData {
3382
+ /** The one selected node, or null when several are selected. */
3383
+ nodeId: string | null;
3384
+ count: number;
3385
+ /** The selected node's envelope (the first one in its stack), if any. */
3386
+ envelope: {
3387
+ effectId: string;
3388
+ enabled: boolean;
3389
+ params: VectorEnvelopeParams;
3390
+ } | null;
3391
+ /** Some selected node can take an envelope (Make with Warp / Mesh). */
3392
+ canMake: boolean;
3393
+ /** Make with Top Object: several objects selected and the topmost is a closed path. */
3394
+ canMakeWithTopObject: boolean;
3395
+ /** Some selected node has an envelope (Release, Expand). */
3396
+ canRelease: boolean;
3397
+ }
3398
+ /** The Distort / Envelope panel of the selection, or null when nothing is selected. */
3399
+ declare function getVectorEnvelopePanel(state: Pick<VectorEditorState, 'document' | 'selection'>): VectorEnvelopePanelData | null;
2547
3400
  /** What the Blend controls of a toolbar or style panel show. */
2548
3401
  interface VectorBlendControls {
2549
3402
  /** Ids of the selected blends (a selected key counts as its blend). */
@@ -2680,6 +3533,38 @@ declare const VECTOR_CORNER_KIND_LABELS: Readonly<Record<VectorCornerKind, strin
2680
3533
  declare const VECTOR_ARROWHEAD_LABELS: Readonly<Record<VectorArrowhead, string>>;
2681
3534
  /** A paint as `#rrggbb` for `<input type="color">`, or null for none, gradients and other CSS colours. */
2682
3535
  declare function vectorPaintToHex(paint: VectorPaint | undefined): string | null;
3536
+ declare const VECTOR_GRADIENT_TYPE_LABELS: Readonly<Record<VectorGradientType, string>>;
3537
+ declare const VECTOR_GRADIENT_SPREAD_LABELS: Readonly<Record<VectorGradientSpread, string>>;
3538
+ declare const VECTOR_GRADIENT_INTERPOLATION_LABELS: Readonly<Record<VectorGradientInterpolation, string>>;
3539
+ declare const VECTOR_STROKE_GRADIENT_MODE_LABELS: Readonly<Record<VectorStrokeGradientMode, string>>;
3540
+ /** What a gradient editor shows for the selection's `target` paint (see `getVectorGradientEditor`). */
3541
+ interface VectorGradientEditorData {
3542
+ target: 'fill' | 'stroke';
3543
+ /** The first selected path's paint is a gradient. */
3544
+ gradient: VectorGradient | null;
3545
+ /** The paint as a `#rrggbb` colour when it is one (what a new gradient starts from). */
3546
+ color: string | null;
3547
+ /** Sorted stops; `index` is what `setGradientStop` takes. */
3548
+ stops: (VectorGradientStop & {
3549
+ index: number;
3550
+ selected: boolean;
3551
+ })[];
3552
+ selected: (VectorGradientStop & {
3553
+ index: number;
3554
+ last: boolean;
3555
+ }) | null;
3556
+ /** A CSS `linear-gradient(to right, …)` of the ramp (midpoints and colour space expanded). */
3557
+ preview: string | null;
3558
+ type: VectorGradientType | null;
3559
+ spread: VectorGradientSpread;
3560
+ interpolation: VectorGradientInterpolation;
3561
+ smoothness: number;
3562
+ strokeMode: VectorStrokeGradientMode;
3563
+ /** The selected paths' gradients differ. */
3564
+ mixed: boolean;
3565
+ }
3566
+ /** The gradient editor of the selection's fill or stroke (`state.gradientEdit.target`), or null with nothing selected. */
3567
+ declare function getVectorGradientEditor(state: Pick<VectorEditorState, 'document' | 'selection' | 'gradientEdit'>): VectorGradientEditorData | null;
2683
3568
  /** A path-editing button of the bundled toolbars. */
2684
3569
  interface VectorPathAction {
2685
3570
  id: 'join' | 'average' | 'cut' | 'clean' | 'smooth' | 'outline';
@@ -2716,6 +3601,7 @@ interface VectorEffectsPanelItem {
2716
3601
  label: string;
2717
3602
  enabled: boolean;
2718
3603
  params: Record<string, unknown>;
3604
+ /** The parameters to edit (none for an envelope: `getVectorEnvelopePanel` and the Envelope panels edit it). */
2719
3605
  specs: readonly VectorEffectParamSpec[];
2720
3606
  }
2721
3607
  /** What an Effects panel shows for the selection. */
@@ -3267,7 +4153,7 @@ declare function vectorFillMap(doc: VectorDocument, gap?: number): PlanarMap | n
3267
4153
  * pair turns the same way), so a nonzero fill keeps its holes.
3268
4154
  * - **In-betweens** follow the shapes' best-fit rotation and scale (Procrustes), with the
3269
4155
  * leftover difference blended in linearly, so a turning shape turns instead of collapsing.
3270
- * - **Paint**: colours mix in OKLab, gradients of one kind resample their stops to a common
4156
+ * - **Paint**: colours mix in OKLab, gradients of one style resample their stops to a common
3271
4157
  * set, a missing paint fades from transparent; stroke width, opacity, dashes, arrowhead
3272
4158
  * scales and width profiles interpolate, and the rest switches halfway.
3273
4159
  * - **Transforms**: both shapes are blended in their parent's space; the in-between's rigid
@@ -3368,8 +4254,11 @@ declare function interpolateMorphContours(a: readonly VectorMorphContour[], b: r
3368
4254
  declare function interpolateRigidMatrix(a: AffineMatrix, b: AffineMatrix, t: number): AffineMatrix;
3369
4255
  /** Two colours mixed in OKLab (premultiplied alpha); unreadable colours switch halfway. */
3370
4256
  declare function interpolateVectorColor(a: string, b: string, t: number): string;
3371
- /** A gradient's stops resampled at `offsets`, each painting what the gradient paints there. */
3372
- declare function resampleGradientStops(g: CanvasGradientDef, offsets: readonly number[]): GradientStop[];
4257
+ /**
4258
+ * A gradient's stops resampled at `offsets`, each painting what the gradient paints there (its
4259
+ * midpoints, smoothness and interpolation space included).
4260
+ */
4261
+ declare function resampleGradientStops(g: VectorGradient, offsets: readonly number[]): VectorGradientStop[];
3373
4262
  /**
3374
4263
  * Interpolates paints: colours in OKLab, gradients of one kind with their stops resampled to a
3375
4264
  * common set, a colour and a gradient through a gradient of that colour, and a missing paint
@@ -3561,4 +4450,173 @@ declare function repeatPaths(paths: readonly BezierPath[], r: VectorEffectParams
3561
4450
  /** The middle of the paths' bounds (the origin when they are empty). */
3562
4451
  declare function pathsCenter(paths: readonly BezierPath[]): Vec2;
3563
4452
 
3564
- export { type AddVectorNodeOptions, AffineMatrix, DEFAULT_VECTOR_BLEND_DISTANCE, DEFAULT_VECTOR_BLEND_STEPS, DEFAULT_VECTOR_PATH_EDIT, DEFAULT_VECTOR_SNAP, IDENTITY_MATRIX, KAPPA, LazyMouse, type NearestSegment, type RecognizeInkOptions, SvgGradientDef, VECTOR_ARROWHEADS, VECTOR_ARROWHEAD_LABELS, VECTOR_BLEND_MAX_SMOOTH_STEPS, VECTOR_BLEND_MAX_STEPS, VECTOR_BLEND_SPACINGS, VECTOR_BLEND_SPACING_LABELS, VECTOR_BUILDER_HATCH_GAP, VECTOR_CLIPBOARD_TYPE, VECTOR_CONSTRUCTION_ANGLES, VECTOR_CORNER_KINDS, VECTOR_CORNER_KIND_LABELS, VECTOR_CORNER_WIDGET_INSET, VECTOR_EDIT_TOGGLES, VECTOR_EFFECT_DEFAULTS, VECTOR_EFFECT_LABELS, VECTOR_EFFECT_MENU, VECTOR_EFFECT_PARAM_SPECS, VECTOR_EFFECT_TYPES, VECTOR_FILL_GAP, VECTOR_INK_MAX_CORNERS, VECTOR_MERGE_MODES, VECTOR_OVERLAY_THEME, VECTOR_PATHFINDER_ACTIONS, VECTOR_PATHFINDER_LABELS, VECTOR_PATHFINDER_OPERATIONS, VECTOR_PATH_ACTIONS, VECTOR_PENCIL_STRING_PX, VECTOR_PRESSURE_NOMINAL, VECTOR_ROTATE_HANDLE_OFFSET, VECTOR_STROKE_ALIGN_LABELS, VECTOR_STYLE_KEYS, VECTOR_TOOLS, VECTOR_TOOL_GLYPHS, VECTOR_TOOL_SHORTCUTS, VECTOR_TRANSFORM_HANDLES, VECTOR_WIDTH_PRESETS, VECTOR_WIDTH_PRESET_IDS, VECTOR_WIDTH_PROFILE_MAX_POINTS, VECTOR_WIDTH_PROFILE_MAX_SCALE, VECTOR_WIDTH_SAME_T, type VariableStrokeOptions, type Vec2, type VectorActionResult, type VectorAlign, type VectorAnchor, type VectorAnchorRef, type VectorAnchorType, type VectorAppearanceShape, type VectorArrange, type VectorArrowAlign, type VectorArrowhead, type VectorArrowheadShape, type VectorAverageAxis, type VectorBlend, type VectorBlendControls, type VectorBlendInput, type VectorBlendOptions, type VectorBlendRail, type VectorBlendSpacing, type VectorBlendStart, type VectorBooleanOperand, type VectorBooleanOperation, type VectorBounds, type VectorBuilderHit, type VectorBuilderLinePiece, type VectorBuilderPreview, type VectorBuilderReplacement, type VectorBuilderTouched, type VectorCommandOptions, type VectorCorner, type VectorCornerInfo, type VectorCornerKind, type VectorCornerWidget, type VectorDefaults, type VectorDistribute, type VectorDocument, VectorEditorController, type VectorEditorOptions, type VectorEditorState, type VectorEffect, type VectorEffectParamSpec, type VectorEffectParamsMap, type VectorEffectType, type VectorEffectsPanelData, type VectorEffectsPanelItem, type VectorFillRule, type VectorGroupNode, type VectorGuideKind, type VectorGuideLabel, type VectorGuideLine, type VectorHandleRef, type VectorHitTestOptions, type VectorHover, type VectorInkShape, type VectorInteraction, type VectorKeyInput, type VectorLineCap, type VectorLineJoin, type VectorMatrix, type VectorMergeMode, type VectorModifiers, type VectorMorph, type VectorMorphContour, type VectorMorphCorrespondence, type VectorMorphOptions, type VectorNode, type VectorNodeListing, type VectorOverlayRenderData, type VectorPaint, type VectorPathAction, type VectorPathEditOptions, type VectorPathEntry, type VectorPathKeyframe, type VectorPathNode, type VectorPathfinderAction, type VectorPathfinderOperation, type VectorPathfinderPaint, type VectorPointSnap, type VectorPointerInput, type VectorRectSnap, type VectorRenderAnchor, type VectorRenderCornerWidget, type VectorRenderGroup, type VectorRenderGuideLabel, type VectorRenderGuideLine, type VectorRenderHandle, type VectorRenderNode, type VectorRenderPath, type VectorRenderStrokeParts, type VectorRenderWidthPoint, type VectorRepeaterCopy, type VectorScaleSnap, type VectorSceneRenderData, type VectorSegmentRef, type VectorSelectionBoxGeometry, type VectorSelectionFrame, type VectorSelectionStyle, type VectorShapeBuilderFace, type VectorShapeBuilderMap, type VectorShapeBuilderPlan, type VectorShapeBuilderResult, type VectorShapeInput, type VectorSnapGuides, type VectorSnapKind, type VectorSnapLeave, type VectorSnapOptions, VectorSnapTargets, type VectorStrokeAlign, type VectorStrokeParts, type VectorStrokeSpot, type VectorStyle, type VectorSubpath, type VectorSvgExportOptions, type VectorSvgImportOptions, type VectorTaperOptions, type VectorTool, type VectorTransformHandle, type VectorViewport, type VectorWaveOptions, type VectorWidthHandle, type VectorWidthPoint, type VectorWidthPointEdit, type VectorWidthPointRef, type VectorWidthPreset, type VectorWidthPresetInfo, activeVectorEffects, addBuilderHit, applyMatrix, applyMatrixLinear, applyVectorBlendOptions, applyVectorCornersAttribute, applyVectorEffects, arrowheadInset, arrowheadPath, arrowheadWeight, bendSegment, bezierToSubpaths, boundsFromPoints, boundsIntersect, clearVectorLiveBooleanCache, cloneAnchor, cloneSubpath, cloneVectorDocument, cloneVectorNode, collectPathNodes, constrainToLeave, convertAnchor, cornerBisectorPoint, cornerRadiusChange, cornerSetback, correspondMorphContours, createVectorCommands, createVectorEffect, createVectorMorph, curvatureMoveAnchor, cutSubpathAt, dashIntervals, decomposeRigid, effectPathLength, effectPathVertexCount, effectiveStrokeAlign, ellipseSubpath, eraseFromFill, eraseFromOutline, eraserRegion, evaluateVectorPathKeyframes, expandVectorAppearance, expandVectorAppearances, expandVectorBlend, expandVectorCorners, expandVectorCornersOf, findVectorNode, fitCornerRadius, foldVectorBooleanOperands, generateVectorBlendChildren, generateWidthProfile, getAnchor, getAnchorWorld, getEditablePathIds, getTransformHandlePositions, getVectorBlendControls, getVectorCornerWidgets, getVectorEffectsPanel, getVectorEnteredGroups, getVectorOverlayRenderData, getVectorSceneRenderData, getVectorSelectionBoxGeometry, getVectorSelectionFrame, getVectorSelectionStyle, getVectorWidthHandles, getVisibleAnchors, getVisibleHandles, hasOwnVectorAppearance, hasPaint, hasStrokeExtras, hasVectorAppearance, hasVectorCorners, hitTestVectorNode, hitTestVectorNodes, hitTestVectorStroke, inferAnchorType, insertAnchor, insertWidthPoint, interpolateMorphContours, interpolateRigidMatrix, interpolateVectorColor, interpolateVectorPaint, interpolateVectorPaths, interpolateVectorStyle, interpolateWidthProfiles, invertMatrix, isClosedBezierShape, isIdentityMatrix, isUniformWidthProfile, isVectorBlendGroup, isVectorLiveBoolean, isVectorTextTarget, joinSubpaths, knifePath, lineSubpath, locateVectorNode, matrixRotation, mergePaths, mirrorWidthProfile, morphContourToSubpath, morphPathsCross, moveAnchorHandle, multiplyMatrices, nearestSegment, nearestStrokePosition, nextVectorCornerKind, nodeMatrix, normalizeVectorEffectParams, offsetPaths, parseSvgTransform, parseVectorSvg, pathsCenter, planShapeBuilder, polygonSubpath, polylineBounds, pressureWidthProfile, puckerBloatPaths, recognizeInkShape, rectSubpath, refineMorphContour, refreshVectorBlends, releaseVectorBlend, removeAnchorKeepingShape, removeAnchors, removeAnchorsKeepingShape, removeRedundantPoints, removeWidthPoints, repeatPaths, resampleGradientStops, resolveVectorBlendOptions, reverseMorphContour, reverseSubpath, reverseWidthProfile, rotateMatrix, roundCornerPaths, roundSubpaths, samplePolyline, sanitizeVectorEffects, sanitizeWidthProfile, scaleFor, scaleMatrix, setAnchorCorner, setSubpathCorners, setWidthPoint, simplifyPolyline, smoothSubpath, splitIntoFaces, splitSubpathAt, starSubpath, strokePositionPoint, strokeWidthProfileOf, subpathEnclosesArea, subpathPointAt, subpathSegment, subpathSegmentCount, subpathToMorphContour, subpathsToBezier, taperWaveFactor, toVectorKeyInput, toVectorModifiers, toVectorPointerInput, transformVectorEffects, transformVectorNode, translateAnchor, translateMatrix, trimIntervals, trimPaths, trimPathsIndividually, turnMorphContour, twistPaths, unionBounds, variableStrokeOutline, variableStrokeRings, vectorAppearanceNodes, vectorAppearanceOutline, vectorAppearanceShapes, vectorBlendColorDistance, vectorBlendKeyTargets, vectorBlendKeys, vectorBlendRail, vectorBlendRailAt, vectorBlendSpine, vectorBlendStepCount, vectorBuilderErasedEdges, vectorCornerAt, vectorCorners, vectorCornersAttribute, vectorDiamondPath, vectorDocumentToSvg, vectorEnteredGroups, vectorFillMap, vectorInkShapeName, vectorLiveBooleanSteps, vectorNodeBounds, vectorNodeRotation, vectorNodeToBezier, vectorOperandOperation, vectorPaintToHex, vectorPaintToSvg, vectorParentMatrix, vectorPathData, vectorPathEntries, vectorPathWorldBezier, vectorPathfinderShape, vectorRepeaterCopies, vectorResizeCursor, vectorResultStyle, vectorShapeBuilderHit, vectorShapeBuilderMap, vectorStrokeLineArea, vectorStrokeOutline, vectorStrokeOutlinePath, vectorStrokeParts, vectorStrokeReach, vectorStrokeSvgParts, vectorStrokeWidthGeometry, vectorToolLabel, vectorWorldMatrix, walkVectorNodes, widthProfileAt, widthProfileFromAttribute, widthProfileMaxScale, widthProfilePreset, widthProfilePresetId, widthProfileToAttribute, wigglePaths, zigzagPaths };
4453
+ /**
4454
+ * The paint server of a gradient along or across the stroke of `node` (in its own space): a
4455
+ * pattern whose first def id is `id`. `area` defaults to the path's box padded by the stroke's
4456
+ * reach.
4457
+ */
4458
+ declare function vectorStrokeGradientDefs(g: VectorGradient, id: string, node: VectorPathNode, options?: {
4459
+ bounds?: VectorBounds | null;
4460
+ area?: VectorBounds | null;
4461
+ precision?: number;
4462
+ }): VectorPaintDef[];
4463
+
4464
+ /**
4465
+ * Perspective (projective) maps between quadrilaterals: what Free Distort needs. Pure maths;
4466
+ * degenerate or non-finite quads give `null` instead of NaNs.
4467
+ *
4468
+ * Ported from ArtCraft (MIT OR Apache-2.0, © ArtCraft Team and contributors; see
4469
+ * THIRD_PARTY_NOTICES.md): pdfcraft `crates/geom/src/perspective.rs` (`Homography::from_points`,
4470
+ * `Homography::apply`, `solve8`, `order_quad`).
4471
+ */
4472
+
4473
+ /** A 3×3 projective map, row-major, normalised so that the last entry is 1. */
4474
+ type VectorHomography = readonly [number, number, number, number, number, number, number, number, number];
4475
+ /**
4476
+ * Gaussian elimination with partial pivoting on an 8×8 system (the 9th column of each row is the
4477
+ * right-hand side). Null when the system is singular.
4478
+ */
4479
+ declare function solve8(rows: readonly (readonly number[])[]): number[] | null;
4480
+ /** The image of `p`, or null where the map sends it to infinity. */
4481
+ declare function applyVectorHomography(h: VectorHomography, p: Vec2): Vec2 | null;
4482
+ /**
4483
+ * The projective map that takes each of `from` to the point at the same index of `to`. Null when
4484
+ * three of either set are collinear or a coordinate is not finite.
4485
+ */
4486
+ declare function vectorHomography(from: readonly Vec2[], to: readonly Vec2[]): VectorHomography | null;
4487
+ /**
4488
+ * Whether `h` maps the whole convex quad `quad` without sending any of it through infinity (the
4489
+ * denominator keeps one sign over it): what a usable distortion needs.
4490
+ */
4491
+ declare function vectorHomographyKeepsQuad(h: VectorHomography, quad: readonly Vec2[]): boolean;
4492
+ /**
4493
+ * The four corners in reading order for a y-down space: top-left, top-right, bottom-right,
4494
+ * bottom-left, whatever order they come in. Null unless they form a convex quadrilateral with a
4495
+ * non-negligible area.
4496
+ */
4497
+ declare function orderVectorQuad(points: readonly Vec2[]): Vec2[] | null;
4498
+
4499
+ /**
4500
+ * Warp geometry for envelope distortion: preset warp styles and editable Bézier meshes, both
4501
+ * forward maps from a source box (the bounds of the paths an envelope bends) to the node's space.
4502
+ *
4503
+ * - **Presets** (`VectorWarpStyle`, Photoshop's fifteen with bend and horizontal / vertical
4504
+ * distortion in percent): each is one bicubic Bézier patch whose 4 × 4 control grid follows the
4505
+ * bend (`vectorWarpPresetGrid`). Every preset is the identity at bend 0 and continuous in it.
4506
+ * - **Meshes** (`VectorWarpMesh`): a grid of bicubic patches. Splitting a mesh (`splitVectorMeshU`
4507
+ * / `V`) is an exact de Casteljau subdivision, so it never changes the shape, and a preset turns
4508
+ * into an editable mesh of any size exactly.
4509
+ *
4510
+ * Ported from ArtCraft (MIT OR Apache-2.0, © ArtCraft Team and contributors; see
4511
+ * THIRD_PARTY_NOTICES.md): photocraft `crates/geom/src/warp.rs` (`WarpStyle`, `StyleWarp`,
4512
+ * `rest_grid`, `edge_arc`, `arc_grid`, `blend_rows`, `preset_grid`, `bernstein`, `split_cubic`,
4513
+ * `BERN_INV`, and `BezierMesh`: `identity`, `fit`, `eval`, `split_u`, `split_v`, `remove_split_u`,
4514
+ * `transpose`, `map_points`, `param_at`, `pull`, `smooth_lines`, `drag_point`, `control_bounds`;
4515
+ * `Warp::map` and `Warp::to_mesh`). The Coons patch of `vectorMeshFromOutline` is our own.
4516
+ */
4517
+
4518
+ /** The fifteen presets in Photoshop's menu order. */
4519
+ declare const VECTOR_WARP_STYLES: readonly VectorWarpStyle[];
4520
+ declare const VECTOR_WARP_STYLE_LABELS: Readonly<Record<VectorWarpStyle, string>>;
4521
+ /**
4522
+ * A preset as a Bézier control grid (rows of `[x, y]` in box units, y down). `b`, `hd`, `vd` are
4523
+ * the bend and the horizontal / vertical distortion as fractions (−1…1); `aspect` is the box's
4524
+ * height over its width. The arc family stays circular in pixels, the other offsets scale with the
4525
+ * box, and a vertical warp is the horizontal one with the axes (and distortions) swapped.
4526
+ */
4527
+ declare function vectorWarpPresetGrid(style: VectorWarpStyle, b: number, hd: number, vd: number, vertical: boolean, aspect: number): [number, number][][];
4528
+ /** A preset warp's settings (bend and distortions in percent, −100…100). */
4529
+ interface VectorWarpPreset {
4530
+ style: VectorWarpStyle;
4531
+ bend: number;
4532
+ horizontal?: number;
4533
+ vertical?: number;
4534
+ /** Bend along the vertical axis. */
4535
+ orientation?: 'horizontal' | 'vertical';
4536
+ }
4537
+ /**
4538
+ * A preset as one Bézier patch over `bounds` (points in the bounds' space), or null when it
4539
+ * changes nothing (an unknown style, all-zero amounts, or an empty box).
4540
+ */
4541
+ declare function vectorWarpPresetMesh(preset: VectorWarpPreset, bounds: VectorBounds): VectorWarpMesh | null;
4542
+ /** Control points per row. */
4543
+ declare const vectorMeshColumns: (m: VectorWarpMesh) => number;
4544
+ /** Control point rows. */
4545
+ declare const vectorMeshRows: (m: VectorWarpMesh) => number;
4546
+ /** Whether a mesh is well formed: knots from 0 to 1 increasing, the right number of finite points. */
4547
+ declare function isValidVectorMesh(m: unknown): m is VectorWarpMesh;
4548
+ /** Fits a mesh with patch boundaries `us` / `vs` to the map `f` (box fractions → output) by interpolating it at each patch's thirds. Exact for bicubic maps (affine maps included). */
4549
+ declare function fitVectorMesh(f: (s: number, t: number) => Vec2, us: readonly number[], vs: readonly number[]): VectorWarpMesh;
4550
+ /** The identity mesh over `bounds` with `columns × rows` patches. */
4551
+ declare function vectorIdentityMesh(bounds: VectorBounds, columns?: number, rows?: number): VectorWarpMesh;
4552
+ /** The surface at box fractions `(s, t)`. */
4553
+ declare function evalVectorMesh(m: VectorWarpMesh, s: number, t: number): Vec2;
4554
+ /** The mesh with the patch column holding `s` split at `s` (exact). Null when `s` is on or too close to a boundary. */
4555
+ declare function splitVectorMeshU(m: VectorWarpMesh, s: number): VectorWarpMesh | null;
4556
+ /** The mesh with the patch row holding `t` split at `t` (exact). */
4557
+ declare function splitVectorMeshV(m: VectorWarpMesh, t: number): VectorWarpMesh | null;
4558
+ /**
4559
+ * The mesh without interior vertical boundary `k` (1 … us.length − 2), its two patch columns
4560
+ * merged: exact when they came from an unedited split; otherwise the outer control points stay and
4561
+ * the inner handles are extrapolated.
4562
+ */
4563
+ declare function removeVectorMeshSplitU(m: VectorWarpMesh, k: number): VectorWarpMesh | null;
4564
+ /** Removes interior horizontal boundary `k`. */
4565
+ declare function removeVectorMeshSplitV(m: VectorWarpMesh, k: number): VectorWarpMesh | null;
4566
+ /** Every control point through `f` (exact for affine maps). */
4567
+ declare function mapVectorMeshPoints(m: VectorWarpMesh, f: (p: Vec2) => Vec2): VectorWarpMesh;
4568
+ /**
4569
+ * The mesh with `columns × rows` patches over the same surface: split exactly when its knots are
4570
+ * a subset of the new even ones (a one-patch mesh always is), otherwise refitted.
4571
+ */
4572
+ declare function resizeVectorMesh(m: VectorWarpMesh, columns: number, rows: number): VectorWarpMesh;
4573
+ /** Bounding box of the control points (the surface lies inside it). */
4574
+ declare function vectorMeshControlBounds(m: VectorWarpMesh): VectorBounds;
4575
+ /** Box fractions `(s, t)` whose surface point is nearest `p` (a coarse search, then Newton steps). */
4576
+ declare function vectorMeshParamAt(m: VectorWarpMesh, p: Vec2): {
4577
+ s: number;
4578
+ t: number;
4579
+ distance: number;
4580
+ };
4581
+ /**
4582
+ * `base` with control point `index` dragged by `d`, keeping the surface smooth across the grid
4583
+ * lines: an anchor moves with the eight points around it as one block; a handle moves with the two
4584
+ * points beside it across its line, and the handle opposite it on the same anchor turns the other
4585
+ * way (with its two neighbours), so the line keeps passing straight through the anchor. An inner
4586
+ * point of a patch moves alone.
4587
+ */
4588
+ declare function dragVectorMeshPoint(base: VectorWarpMesh, index: number, d: Vec2): VectorWarpMesh;
4589
+ /**
4590
+ * `base` with its surface point at box fractions `(s, t)` pulled by `d`, the way dragging inside a
4591
+ * patch works: interior anchors within about two cells follow by a share of `d` that fades with
4592
+ * distance (each with its block of handles, so grid lines stay smooth); the outer border stays
4593
+ * pinned unless the grab is near it, and then it bows; the four corners never move. The grabbed
4594
+ * patch's inner points (and, near the border, the border's handles) make up the rest, so the
4595
+ * grabbed point lands exactly at its start + `d`.
4596
+ */
4597
+ declare function pullVectorMesh(base: VectorWarpMesh, s: number, t: number, d: Vec2): VectorWarpMesh;
4598
+ /**
4599
+ * A mesh whose border follows a closed outline (Illustrator's Make with Top Object): the outline is
4600
+ * cut into four sides at the points nearest its bounding box's corners, and the interior is the
4601
+ * Coons patch of those sides, fitted with `columns × rows` patches. Null for an open or degenerate
4602
+ * outline.
4603
+ */
4604
+ declare function vectorMeshFromOutline(sp: VectorSubpath, columns?: number, rows?: number): VectorWarpMesh | null;
4605
+ /** The mesh's border as one closed subpath (clockwise from the top-left corner): what Release gives back as the envelope's shape. */
4606
+ declare function vectorMeshOutline(m: VectorWarpMesh): VectorSubpath;
4607
+ /**
4608
+ * The control points an editor shows: the anchors (where grid lines cross) and the handles along
4609
+ * the grid lines, each with the anchor it belongs to. Points inside a patch are left out (drag
4610
+ * inside a patch to pull the surface instead).
4611
+ */
4612
+ declare function vectorMeshEditPoints(m: VectorWarpMesh): {
4613
+ anchors: number[];
4614
+ handles: {
4615
+ index: number;
4616
+ anchor: number;
4617
+ }[];
4618
+ };
4619
+ /** The mesh's grid lines (patch borders) as cubics `[p0, p1, p2, p3]`. */
4620
+ declare function vectorMeshGridCurves(m: VectorWarpMesh): Vec2[][];
4621
+
4622
+ export { type AddVectorNodeOptions, AffineMatrix, DEFAULT_VECTOR_BLEND_DISTANCE, DEFAULT_VECTOR_BLEND_STEPS, DEFAULT_VECTOR_PATH_EDIT, DEFAULT_VECTOR_SNAP, IDENTITY_MATRIX, KAPPA, LazyMouse, type MapVectorSubpathsOptions, type NearestSegment, type RecognizeInkOptions, SvgGradientDef, VECTOR_ARROWHEADS, VECTOR_ARROWHEAD_LABELS, VECTOR_BLEND_MAX_SMOOTH_STEPS, VECTOR_BLEND_MAX_STEPS, VECTOR_BLEND_SPACINGS, VECTOR_BLEND_SPACING_LABELS, VECTOR_BUILDER_HATCH_GAP, VECTOR_CLIPBOARD_TYPE, VECTOR_CONSTRUCTION_ANGLES, VECTOR_CORNER_KINDS, VECTOR_CORNER_KIND_LABELS, VECTOR_CORNER_WIDGET_INSET, VECTOR_DISTORT_TOLERANCE, VECTOR_EDIT_TOGGLES, VECTOR_EFFECT_DEFAULTS, VECTOR_EFFECT_LABELS, VECTOR_EFFECT_MENU, VECTOR_EFFECT_PARAM_SPECS, VECTOR_EFFECT_TYPES, VECTOR_ENVELOPE_STYLE_OPTIONS, VECTOR_FILL_GAP, VECTOR_GRADIENT_INTERPOLATIONS, VECTOR_GRADIENT_INTERPOLATION_LABELS, VECTOR_GRADIENT_MAX_PERIODS, VECTOR_GRADIENT_MIDPOINT_GAP, VECTOR_GRADIENT_MIN_STOPS, VECTOR_GRADIENT_OFF_BAR, VECTOR_GRADIENT_SPREADS, VECTOR_GRADIENT_SPREAD_LABELS, VECTOR_GRADIENT_STOP_GAP, VECTOR_GRADIENT_TYPES, VECTOR_GRADIENT_TYPE_LABELS, VECTOR_INK_MAX_CORNERS, VECTOR_MERGE_MODES, VECTOR_OVERLAY_THEME, VECTOR_PATHFINDER_ACTIONS, VECTOR_PATHFINDER_LABELS, VECTOR_PATHFINDER_OPERATIONS, VECTOR_PATH_ACTIONS, VECTOR_PENCIL_STRING_PX, VECTOR_PRESSURE_NOMINAL, VECTOR_ROTATE_HANDLE_OFFSET, VECTOR_STROKE_ALIGN_LABELS, VECTOR_STROKE_GRADIENT_MODES, VECTOR_STROKE_GRADIENT_MODE_LABELS, VECTOR_STYLE_KEYS, VECTOR_TOOLS, VECTOR_TOOL_GLYPHS, VECTOR_TOOL_SHORTCUTS, VECTOR_TRANSFORM_HANDLES, VECTOR_WARP_STYLES, VECTOR_WARP_STYLE_LABELS, VECTOR_WIDTH_PRESETS, VECTOR_WIDTH_PRESET_IDS, VECTOR_WIDTH_PROFILE_MAX_POINTS, VECTOR_WIDTH_PROFILE_MAX_SCALE, VECTOR_WIDTH_SAME_T, type VariableStrokeOptions, type Vec2, type VectorActionResult, type VectorAlign, type VectorAnchor, type VectorAnchorRef, type VectorAnchorType, type VectorAppearanceShape, type VectorArrange, type VectorArrowAlign, type VectorArrowhead, type VectorArrowheadShape, type VectorAverageAxis, type VectorBlend, type VectorBlendControls, type VectorBlendInput, type VectorBlendOptions, type VectorBlendRail, type VectorBlendSpacing, type VectorBlendStart, type VectorBooleanOperand, type VectorBooleanOperation, type VectorBounds, type VectorBuilderHit, type VectorBuilderLinePiece, type VectorBuilderPreview, type VectorBuilderReplacement, type VectorBuilderTouched, type VectorCommandOptions, type VectorCorner, type VectorCornerInfo, type VectorCornerKind, type VectorCornerWidget, type VectorDefaults, type VectorDistortMode, type VectorDistribute, type VectorDocument, VectorEditorController, type VectorEditorOptions, type VectorEditorState, type VectorEffect, type VectorEffectParamSpec, type VectorEffectParamsMap, type VectorEffectType, type VectorEffectsPanelData, type VectorEffectsPanelItem, type VectorEnvelopePanelData, type VectorEnvelopeParams, type VectorFillRule, type VectorGradient, type VectorGradientAnnotator, type VectorGradientEditorData, type VectorGradientHandle, type VectorGradientInterpolation, type VectorGradientPart, type VectorGradientPatch, type VectorGradientPoints, type VectorGradientRamp, type VectorGradientSpread, type VectorGradientStop, type VectorGradientSvgOptions, type VectorGradientTarget, type VectorGradientType, type VectorGradientUnits, type VectorGroupNode, type VectorGuideKind, type VectorGuideLabel, type VectorGuideLine, type VectorHandleRef, type VectorHitTestOptions, type VectorHomography, type VectorHover, type VectorInkShape, type VectorInteraction, type VectorKeyInput, type VectorLineCap, type VectorLineJoin, type VectorMatrix, type VectorMergeMode, type VectorModifiers, type VectorMorph, type VectorMorphContour, type VectorMorphCorrespondence, type VectorMorphOptions, type VectorNode, type VectorNodeListing, type VectorOverlayRenderData, type VectorPaint, type VectorPaintDef, type VectorPaintSvgOptions, type VectorPathAction, type VectorPathEditOptions, type VectorPathEntry, type VectorPathKeyframe, type VectorPathNode, type VectorPathfinderAction, type VectorPathfinderOperation, type VectorPathfinderPaint, type VectorPointMap, type VectorPointSnap, type VectorPointerInput, type VectorRectSnap, type VectorRenderAnchor, type VectorRenderCornerWidget, type VectorRenderGradientAnnotator, type VectorRenderGroup, type VectorRenderGuideLabel, type VectorRenderGuideLine, type VectorRenderHandle, type VectorRenderNode, type VectorRenderPath, type VectorRenderStrokeParts, type VectorRenderWidthPoint, type VectorRepeaterCopy, type VectorRgba, type VectorScaleSnap, type VectorSceneRenderData, type VectorSegmentRef, type VectorSelectionBoxGeometry, type VectorSelectionFrame, type VectorSelectionStyle, type VectorShapeBuilderFace, type VectorShapeBuilderMap, type VectorShapeBuilderPlan, type VectorShapeBuilderResult, type VectorShapeInput, type VectorSnapGuides, type VectorSnapKind, type VectorSnapLeave, type VectorSnapOptions, VectorSnapTargets, type VectorStrokeAlign, type VectorStrokeGradientMode, type VectorStrokeParts, type VectorStrokeSpot, type VectorStyle, type VectorSubpath, type VectorSvgExportOptions, type VectorSvgImportOptions, type VectorSvgPatternDef, type VectorTaperOptions, type VectorTool, type VectorTransformHandle, type VectorViewport, type VectorWarpMesh, type VectorWarpPreset, type VectorWarpStyle, type VectorWaveOptions, type VectorWidthHandle, type VectorWidthPoint, type VectorWidthPointEdit, type VectorWidthPointRef, type VectorWidthPreset, type VectorWidthPresetInfo, activeVectorEffects, addBuilderHit, applyMatrix, applyMatrixLinear, applyVectorBlendOptions, applyVectorCornersAttribute, applyVectorEffects, applyVectorGradientPatch, applyVectorGradientSpread, applyVectorHomography, arrowheadInset, arrowheadPath, arrowheadWeight, bendSegment, bezierToSubpaths, boundsFromPoints, boundsIntersect, clearVectorLiveBooleanCache, cloneAnchor, cloneSubpath, cloneVectorDocument, cloneVectorNode, collectPathNodes, constrainToLeave, convertAnchor, convertVectorGradient, cornerBisectorPoint, cornerRadiusChange, cornerSetback, correspondMorphContours, createVectorCommands, createVectorEffect, createVectorMorph, curvatureMoveAnchor, cutSubpathAt, dashIntervals, decomposeRigid, defaultVectorGradient, distortVectorNode, dragVectorMeshPoint, effectPathLength, effectPathVertexCount, effectiveStrokeAlign, ellipseSubpath, eraseFromFill, eraseFromOutline, eraserRegion, evalVectorMesh, evaluateVectorPathKeyframes, expandVectorAppearance, expandVectorAppearances, expandVectorBlend, expandVectorCorners, expandVectorCornersOf, expandVectorGradientSpread, expandVectorGradientStops, explicitVectorGradient, findVectorNode, fitCornerRadius, fitVectorMesh, foldVectorBooleanOperands, generateVectorBlendChildren, generateWidthProfile, getAnchor, getAnchorWorld, getEditablePathIds, getTransformHandlePositions, getVectorBlendControls, getVectorCornerWidgets, getVectorEffectsPanel, getVectorEnteredGroups, getVectorEnvelopePanel, getVectorEnvelopeTarget, getVectorGradientAnnotator, getVectorGradientEditor, getVectorOverlayRenderData, getVectorSceneRenderData, getVectorSelectionBoxGeometry, getVectorSelectionFrame, getVectorSelectionStyle, getVectorWidthHandles, getVisibleAnchors, getVisibleHandles, gradientMidpointRemap, hasExplicitGradientGeometry, hasOwnVectorAppearance, hasPaint, hasStrokeExtras, hasVectorAppearance, hasVectorCorners, hitTestVectorNode, hitTestVectorNodes, hitTestVectorStroke, hitVectorGradientAnnotator, inferAnchorType, insertAnchor, insertVectorGradientStop, insertWidthPoint, interpolateMorphContours, interpolateRigidMatrix, interpolateVectorColor, interpolateVectorPaint, interpolateVectorPaths, interpolateVectorStyle, interpolateWidthProfiles, invertMatrix, isCentredVectorGradient, isClosedBezierShape, isIdentityMatrix, isUniformWidthProfile, isValidVectorMesh, isVectorBlendGroup, isVectorGradient, isVectorLiveBoolean, isVectorTextTarget, joinSubpaths, knifePath, lineSubpath, locateVectorNode, mapBezierPath, mapVectorGradient, mapVectorMeshPoints, mapVectorPaint, mapVectorPoints, mapVectorSubpaths, matrixRotation, mergePaths, mirrorWidthProfile, morphContourToSubpath, morphPathsCross, moveAnchorHandle, moveVectorGradientHandle, moveVectorGradientStop, multiplyMatrices, nearestSegment, nearestStrokePosition, nextVectorCornerKind, nodeMatrix, normalizeVectorEffectParams, offsetPaths, orderVectorQuad, parseSvgTransform, parseVectorColor, parseVectorSvg, pathsCenter, patternAttrs, periodicVectorGradientStops, pinVectorGradient, planShapeBuilder, polygonSubpath, polylineBounds, pressureWidthProfile, puckerBloatPaths, pullVectorMesh, recognizeInkShape, rectSubpath, refineMorphContour, refreshVectorBlends, releaseVectorBlend, removeAnchorKeepingShape, removeAnchors, removeAnchorsKeepingShape, removeRedundantPoints, removeVectorGradientStop, removeVectorMeshSplitU, removeVectorMeshSplitV, removeWidthPoints, repeatPaths, resampleGradientStops, resizeVectorMesh, resolveVectorBlendOptions, reverseMorphContour, reverseSubpath, reverseVectorGradient, reverseWidthProfile, rotateMatrix, roundCornerPaths, roundSubpaths, samplePlainStops, samplePolyline, sampleVectorGradient, sampleVectorGradientAt, sampleVectorPaintDefAt, sanitizeVectorEffects, sanitizeVectorGradient, sanitizeWidthProfile, scaleFor, scaleMatrix, setAnchorCorner, setSubpathCorners, setVectorGradientVector, setWidthPoint, simplifyPolyline, smoothSubpath, solve8, sortedVectorGradientStops, spanVectorGradientStops, splitIntoFaces, splitSubpathAt, splitVectorMeshU, splitVectorMeshV, starSubpath, strokePositionPoint, strokeWidthProfileOf, subpathEnclosesArea, subpathPointAt, subpathSegment, subpathSegmentCount, subpathToMorphContour, subpathsToBezier, taperWaveFactor, toVectorKeyInput, toVectorModifiers, toVectorPointerInput, transformVectorEffects, transformVectorGradient, transformVectorNode, transformVectorPaint, translateAnchor, translateMatrix, trimIntervals, trimPaths, trimPathsIndividually, turnMorphContour, twistPaths, unionBounds, variableStrokeOutline, variableStrokeRings, vectorAppearanceNodes, vectorAppearanceOutline, vectorAppearanceShapes, vectorBlendColorDistance, vectorBlendKeyTargets, vectorBlendKeys, vectorBlendRail, vectorBlendRailAt, vectorBlendSpine, vectorBlendStepCount, vectorBoxCorners, vectorBoxMatrix, vectorBuilderErasedEdges, vectorCornerAt, vectorCorners, vectorCornersAttribute, vectorDiamondPath, vectorDistortQuad, vectorDocumentToSvg, vectorEffectInputBounds, vectorEffectInputPaths, vectorEnteredGroups, vectorEnvelopeFrame, vectorEnvelopeMap, vectorEnvelopeMesh, vectorFillMap, vectorGradientArea, vectorGradientAspect, vectorGradientBarPosition, vectorGradientFocalParam, vectorGradientHandles, vectorGradientMatrix, vectorGradientMidpointFromPosition, vectorGradientMidpointPosition, vectorGradientNeedsExpansion, vectorGradientParam, vectorGradientPoints, vectorGradientRamp, vectorGradientSvgDefs, vectorGradientTAt, vectorGradientTargetPath, vectorGradientUnitsMatrix, vectorHomography, vectorHomographyKeepsQuad, vectorIdentityMesh, vectorInkShapeName, vectorLiveBooleanSteps, vectorMeshColumns, vectorMeshControlBounds, vectorMeshEditPoints, vectorMeshFromOutline, vectorMeshGridCurves, vectorMeshOutline, vectorMeshParamAt, vectorMeshRows, vectorNodeBounds, vectorNodeEnvelope, vectorNodeRotation, vectorNodeToBezier, vectorOperandOperation, vectorPaintToHex, vectorPaintToSvg, vectorParentMatrix, vectorPathData, vectorPathEntries, vectorPathLocalBounds, vectorPathWorldBezier, vectorPathfinderShape, vectorRepeaterCopies, vectorResizeCursor, vectorResultStyle, vectorShapeBuilderHit, vectorShapeBuilderMap, vectorShearForSide, vectorSkewMatrix, vectorStrokeGradientDefs, vectorStrokeLineArea, vectorStrokeOutline, vectorStrokeOutlinePath, vectorStrokeParts, vectorStrokeReach, vectorStrokeSvgParts, vectorStrokeWidthGeometry, vectorToolLabel, vectorWarpPresetGrid, vectorWarpPresetMesh, vectorWorldMatrix, walkVectorNodes, widthProfileAt, widthProfileFromAttribute, widthProfileMaxScale, widthProfilePreset, widthProfilePresetId, widthProfileToAttribute, wigglePaths, zigzagPaths };