@pixerate/editor 0.24.0 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/README.md +71 -1
  2. package/THIRD_PARTY_NOTICES.md +29 -0
  3. package/dist/agent/index.cjs +10 -9
  4. package/dist/agent/index.cjs.map +1 -1
  5. package/dist/agent/index.d.cts +1 -1
  6. package/dist/agent/index.d.ts +1 -1
  7. package/dist/agent/index.js +4 -3
  8. package/dist/agent/index.js.map +1 -1
  9. package/dist/canvas/index.cjs +3173 -340
  10. package/dist/canvas/index.cjs.map +1 -1
  11. package/dist/canvas/index.d.cts +617 -4
  12. package/dist/canvas/index.d.ts +617 -4
  13. package/dist/canvas/index.js +3105 -272
  14. package/dist/canvas/index.js.map +1 -1
  15. package/dist/chunk-4BVP64JJ.cjs +1406 -0
  16. package/dist/chunk-4BVP64JJ.cjs.map +1 -0
  17. package/dist/{chunk-XNORY7M6.cjs → chunk-7WISYZFO.cjs} +105 -50
  18. package/dist/chunk-7WISYZFO.cjs.map +1 -0
  19. package/dist/{chunk-OLZJXL4R.cjs → chunk-AL6JMGWW.cjs} +59 -25
  20. package/dist/chunk-AL6JMGWW.cjs.map +1 -0
  21. package/dist/chunk-BVP3TSLH.cjs +69 -0
  22. package/dist/chunk-BVP3TSLH.cjs.map +1 -0
  23. package/dist/{chunk-MCSJFWAO.cjs → chunk-C7P22VIP.cjs} +670 -96
  24. package/dist/chunk-C7P22VIP.cjs.map +1 -0
  25. package/dist/{chunk-PGNZKFQS.js → chunk-ECCCYKGL.js} +76 -21
  26. package/dist/chunk-ECCCYKGL.js.map +1 -0
  27. package/dist/{chunk-3CN2WD3X.js → chunk-FH6F67DN.js} +646 -72
  28. package/dist/chunk-FH6F67DN.js.map +1 -0
  29. package/dist/chunk-HRMEDT2L.js +1406 -0
  30. package/dist/chunk-HRMEDT2L.js.map +1 -0
  31. package/dist/{chunk-ITBSKI26.js → chunk-IXHSYOVY.js} +941 -9
  32. package/dist/chunk-IXHSYOVY.js.map +1 -0
  33. package/dist/{chunk-FODNLX5N.js → chunk-NAXVVS5I.js} +38 -4
  34. package/dist/chunk-NAXVVS5I.js.map +1 -0
  35. package/dist/chunk-O5RYH2PG.js +69 -0
  36. package/dist/chunk-O5RYH2PG.js.map +1 -0
  37. package/dist/{chunk-SBCZ6RN5.cjs → chunk-PO6A6QQH.cjs} +1039 -107
  38. package/dist/chunk-PO6A6QQH.cjs.map +1 -0
  39. package/dist/{chunk-3LV6RRPH.js → chunk-QGYDWPRM.js} +2 -2
  40. package/dist/{chunk-U5KWZU4X.js → chunk-RR7F5GUM.js} +2632 -129
  41. package/dist/chunk-RR7F5GUM.js.map +1 -0
  42. package/dist/{chunk-5S3Z4PPF.js → chunk-UAKDG62Z.js} +232 -25
  43. package/dist/chunk-UAKDG62Z.js.map +1 -0
  44. package/dist/{chunk-SML64VJG.cjs → chunk-V3CHHWOE.cjs} +4 -4
  45. package/dist/{chunk-SML64VJG.cjs.map → chunk-V3CHHWOE.cjs.map} +1 -1
  46. package/dist/chunk-WSQKHXW7.cjs +5726 -0
  47. package/dist/chunk-WSQKHXW7.cjs.map +1 -0
  48. package/dist/{chunk-D27YFC46.cjs → chunk-X4N4WUKB.cjs} +267 -60
  49. package/dist/chunk-X4N4WUKB.cjs.map +1 -0
  50. package/dist/commands/index.cjs +74 -1
  51. package/dist/commands/index.cjs.map +1 -1
  52. package/dist/commands/index.d.cts +34 -1
  53. package/dist/commands/index.d.ts +34 -1
  54. package/dist/commands/index.js +73 -0
  55. package/dist/commands/index.js.map +1 -1
  56. package/dist/compare/index.cjs +3 -3
  57. package/dist/compare/index.d.cts +1 -1
  58. package/dist/compare/index.d.ts +1 -1
  59. package/dist/compare/index.js +2 -2
  60. package/dist/controller-BIJiNoVs.d.cts +1842 -0
  61. package/dist/controller-BIJiNoVs.d.ts +1842 -0
  62. package/dist/{documents-BQjzJNe2.d.ts → documents-CHT1U5Vs.d.ts} +10 -0
  63. package/dist/{documents-KRTPhvst.d.cts → documents-Gp7wb0Me.d.cts} +10 -0
  64. package/dist/extensions/index.cjs +53 -6
  65. package/dist/extensions/index.cjs.map +1 -1
  66. package/dist/extensions/index.d.cts +12 -4
  67. package/dist/extensions/index.d.ts +12 -4
  68. package/dist/extensions/index.js +53 -6
  69. package/dist/generation/index.cjs +1013 -69
  70. package/dist/generation/index.cjs.map +1 -1
  71. package/dist/generation/index.d.cts +474 -13
  72. package/dist/generation/index.d.ts +474 -13
  73. package/dist/generation/index.js +976 -32
  74. package/dist/generation/index.js.map +1 -1
  75. package/dist/image-editor/index.cjs +3385 -1275
  76. package/dist/image-editor/index.cjs.map +1 -1
  77. package/dist/image-editor/index.d.cts +693 -128
  78. package/dist/image-editor/index.d.ts +693 -128
  79. package/dist/image-editor/index.js +3325 -1215
  80. package/dist/image-editor/index.js.map +1 -1
  81. package/dist/{index-fJrlkJCd.d.ts → index-7a6bHTLy.d.ts} +494 -5
  82. package/dist/{index-BhJBSm2d.d.cts → index-Csd5qI8u.d.cts} +494 -5
  83. package/dist/index.cjs +1491 -45
  84. package/dist/index.cjs.map +1 -1
  85. package/dist/index.d.cts +110 -19
  86. package/dist/index.d.ts +110 -19
  87. package/dist/index.js +1464 -18
  88. package/dist/index.js.map +1 -1
  89. package/dist/mention-text-CDnCFd3c.d.cts +53 -0
  90. package/dist/mention-text-CDnCFd3c.d.ts +53 -0
  91. package/dist/model-C1zApQM8.d.cts +219 -0
  92. package/dist/model-C1zApQM8.d.ts +219 -0
  93. package/dist/persistence/index.d.cts +3 -120
  94. package/dist/persistence/index.d.ts +3 -120
  95. package/dist/{registry-GJI4gToU.d.cts → registry-CEgwXED1.d.cts} +12 -1
  96. package/dist/{registry-GJI4gToU.d.ts → registry-CEgwXED1.d.ts} +12 -1
  97. package/dist/serializers/index.cjs +12 -4
  98. package/dist/serializers/index.cjs.map +1 -1
  99. package/dist/serializers/index.d.cts +39 -12
  100. package/dist/serializers/index.d.ts +39 -12
  101. package/dist/serializers/index.js +12 -4
  102. package/dist/spreadsheet/index.cjs +127 -3
  103. package/dist/spreadsheet/index.cjs.map +1 -1
  104. package/dist/spreadsheet/index.d.cts +431 -11
  105. package/dist/spreadsheet/index.d.ts +431 -11
  106. package/dist/spreadsheet/index.js +127 -3
  107. package/dist/storage-BpFfspHm.d.cts +120 -0
  108. package/dist/storage-BpFfspHm.d.ts +120 -0
  109. package/dist/tokens/index.cjs +115 -0
  110. package/dist/tokens/index.cjs.map +1 -0
  111. package/dist/tokens/index.d.cts +212 -0
  112. package/dist/tokens/index.d.ts +212 -0
  113. package/dist/tokens/index.js +115 -0
  114. package/dist/tokens/index.js.map +1 -0
  115. package/dist/{track-changes-BK5sVf4_.d.cts → track-changes-D_VAPELi.d.cts} +95 -11
  116. package/dist/{track-changes-CDjCrwKe.d.ts → track-changes-Db_fGEvx.d.ts} +95 -11
  117. package/package.json +6 -1
  118. package/dist/chunk-3CN2WD3X.js.map +0 -1
  119. package/dist/chunk-5S3Z4PPF.js.map +0 -1
  120. package/dist/chunk-D27YFC46.cjs.map +0 -1
  121. package/dist/chunk-FODNLX5N.js.map +0 -1
  122. package/dist/chunk-ITBSKI26.js.map +0 -1
  123. package/dist/chunk-MA2F5KHF.cjs +0 -3223
  124. package/dist/chunk-MA2F5KHF.cjs.map +0 -1
  125. package/dist/chunk-MCSJFWAO.cjs.map +0 -1
  126. package/dist/chunk-OLZJXL4R.cjs.map +0 -1
  127. package/dist/chunk-PGNZKFQS.js.map +0 -1
  128. package/dist/chunk-SBCZ6RN5.cjs.map +0 -1
  129. package/dist/chunk-U5KWZU4X.js.map +0 -1
  130. package/dist/chunk-XNORY7M6.cjs.map +0 -1
  131. package/dist/controller-BhLLAoi8.d.cts +0 -1000
  132. package/dist/controller-BhLLAoi8.d.ts +0 -1000
  133. /package/dist/{chunk-3LV6RRPH.js.map → chunk-QGYDWPRM.js.map} +0 -0
@@ -1,5 +1,5 @@
1
1
  import { b as LoadReport, J as JsonObject, f as MigrationStep } from '../migrate-iTlm3a8h.js';
2
- import { A as AgentToolProvider } from '../registry-BDe-vlv3.js';
2
+ import { A as AgentToolProvider, a as AgentTool } from '../registry-BDe-vlv3.js';
3
3
  import '../schema-DYDGdYL9.js';
4
4
 
5
5
  /**
@@ -50,6 +50,94 @@ declare function blendPixel(mode: BlendMode, backdrop: readonly number[], source
50
50
  */
51
51
  declare function blendImageData(backdrop: ImageData, source: ImageData, mode: BlendMode, alpha?: number): void;
52
52
 
53
+ /**
54
+ * A selection: one 8-bit coverage value per image pixel (0 = not selected, 255 = fully
55
+ * selected), row-major over the whole source image in natural pixels — the same space as the
56
+ * crop box and annotations. Soft values are partial selection (feathered or anti-aliased edges).
57
+ *
58
+ * Treat a mask as immutable: every operation returns a new one, so history entries can share
59
+ * them without copying.
60
+ */
61
+ interface SelectionMask {
62
+ readonly width: number;
63
+ readonly height: number;
64
+ readonly data: Uint8Array;
65
+ /** Bounding box of the non-zero coverage, or `null` when nothing is selected. */
66
+ readonly bounds: CropBox | null;
67
+ }
68
+ /** How a new selection combines with the current one. */
69
+ type SelectionMode = 'replace' | 'add' | 'subtract' | 'intersect';
70
+ declare const SELECTION_MODES: readonly SelectionMode[];
71
+ declare function isSelectionMode(value: unknown): value is SelectionMode;
72
+ /** Parses `replace|add|subtract|intersect`; anything else is `replace`. */
73
+ declare function parseSelectionMode(value: unknown): SelectionMode;
74
+ /** RGBA pixels, 8 bits per channel, straight alpha (an `ImageData` qualifies). */
75
+ interface PixelBuffer {
76
+ width: number;
77
+ height: number;
78
+ data: ArrayLike<number>;
79
+ }
80
+ /** Serialized selection: a run-length encoding of the 8-bit coverage. */
81
+ interface SerializedSelection {
82
+ width: number;
83
+ height: number;
84
+ /** `r1:` + base64 of (value byte, LEB128 run length) pairs. */
85
+ rle: string;
86
+ }
87
+ /** Bounding box of non-zero bytes. */
88
+ declare function computeSelectionBounds(width: number, height: number, data: ArrayLike<number>): CropBox | null;
89
+ /** Wraps coverage bytes (taken over, not copied) as a selection, computing its bounds. */
90
+ declare function createSelectionMask(width: number, height: number, data?: Uint8Array): SelectionMask;
91
+ /** Select › All. */
92
+ declare function fullSelection(width: number, height: number): SelectionMask;
93
+ declare function isSelectionEmpty(mask: SelectionMask | null | undefined): boolean;
94
+ /** Coverage at a pixel, 0..1 (0 outside the image). */
95
+ declare function selectionValueAt(mask: SelectionMask, x: number, y: number): number;
96
+ /** 8-bit value of a coverage (clamped and rounded; NaN → 0). */
97
+ declare function coverageToByte(v: number): number;
98
+ /** A selection from 0..1 coverage. */
99
+ declare function selectionFromCoverage(width: number, height: number, coverage: ArrayLike<number>): SelectionMask;
100
+ /** The selection's coverage as 0..1 floats. */
101
+ declare function selectionToCoverage(mask: SelectionMask): Float32Array;
102
+ /** Number of fully-or-partly selected pixels, weighted by coverage (Σ coverage). */
103
+ declare function selectionArea(mask: SelectionMask | null | undefined): number;
104
+ /**
105
+ * Combines `next` with `prev` by `mode` (8-bit, exact: combining a mask with itself is a no-op).
106
+ * Add is the maximum, Subtract `max(prev − next, 0)`, Intersect the minimum. A missing `prev`
107
+ * reads as nothing selected. Returns `null` when nothing remains selected.
108
+ */
109
+ declare function combineSelections(prev: SelectionMask | null | undefined, next: SelectionMask, mode: SelectionMode): SelectionMask | null;
110
+ /** Select › Inverse. */
111
+ declare function invertSelection(mask: SelectionMask): SelectionMask;
112
+ /** Bilinear resample to another size (e.g. an AI mask returned at a different resolution). */
113
+ declare function resizeSelection(mask: SelectionMask, width: number, height: number): SelectionMask;
114
+ type SelectionChannel = 'alpha' | 'luminance' | 'red' | 'green' | 'blue';
115
+ /**
116
+ * A selection from an image: by default its luminance (white = selected, the usual convention
117
+ * of segmentation masks), or one channel. Partly transparent pixels count as black for
118
+ * luminance, so a mask PNG with transparency works either way.
119
+ */
120
+ declare function selectionFromPixels(pixels: PixelBuffer, options?: {
121
+ channel?: SelectionChannel;
122
+ invert?: boolean;
123
+ threshold?: number;
124
+ }): SelectionMask;
125
+ /** The selection as RGBA pixels: grey (white = selected, opaque) or white with coverage as alpha. */
126
+ declare function selectionToPixels(mask: SelectionMask, as?: 'gray' | 'alpha'): {
127
+ width: number;
128
+ height: number;
129
+ data: Uint8ClampedArray;
130
+ };
131
+ /** Run-length encodes coverage bytes: `r1:` + base64 of (value, LEB128 run length) pairs. */
132
+ declare function encodeSelectionRle(data: Uint8Array): string;
133
+ /** Decodes {@link encodeSelectionRle}; throws unless the runs cover exactly `length` bytes. */
134
+ declare function decodeSelectionRle(rle: string, length: number): Uint8Array;
135
+ declare function serializeSelection(mask: SelectionMask): SerializedSelection;
136
+ /** Restores a {@link SerializedSelection}; throws on damaged data. */
137
+ declare function deserializeSelection(value: unknown): SelectionMask;
138
+ /** A short, stable hash of a string or bytes (FNV-1a, 32-bit, hex) for cache keys. */
139
+ declare function hashMaskContent(content: string | Uint8Array): string;
140
+
53
141
  interface ImageDimensions {
54
142
  width: number;
55
143
  height: number;
@@ -209,6 +297,27 @@ interface AdjustmentLayerBase {
209
297
  opacity: number;
210
298
  /** How the adjusted colour is blended over the layers below. */
211
299
  blend: BlendMode;
300
+ /**
301
+ * Optional layer mask (natural image pixels): where it is 0 the layer has no effect. Missing:
302
+ * the layer applies everywhere (layers saved before masks existed are unchanged).
303
+ */
304
+ mask?: AdjustmentLayerMask;
305
+ }
306
+ /**
307
+ * A layer mask: 8-bit coverage of the source image, run-length encoded (see
308
+ * `encodeSelectionRle`), plus non-destructive density and feather.
309
+ */
310
+ interface AdjustmentLayerMask {
311
+ width: number;
312
+ height: number;
313
+ /** `r1:` run-length encoding of the mask bytes. */
314
+ rle: string;
315
+ /** 0..1 (missing = 1). */
316
+ density?: number;
317
+ /** Gaussian σ in pixels (missing = 0). */
318
+ feather?: number;
319
+ /** `false` keeps the mask but ignores it. */
320
+ enabled?: boolean;
212
321
  }
213
322
  /** A non-destructive adjustment layer (Photoshop's Layer › New Adjustment Layer). */
214
323
  type AdjustmentLayer = {
@@ -306,6 +415,13 @@ interface ImageEditorState {
306
415
  zoom: number;
307
416
  pan: ImagePoint;
308
417
  isOriginalCompared: boolean;
418
+ /**
419
+ * The active selection (8-bit coverage over the source image), or null/missing when nothing is
420
+ * selected. Recorded in undo history and saved as `selection` in `toJSON()`.
421
+ */
422
+ selection?: SelectionMask | null;
423
+ /** Quick Mask view: tint the unselected area instead of drawing marching ants (view state). */
424
+ quickMask?: boolean;
309
425
  }
310
426
  interface SerializedImageEditorState {
311
427
  /**
@@ -318,6 +434,8 @@ interface SerializedImageEditorState {
318
434
  adjustments: ImageAdjustments;
319
435
  depthMask: DepthMaskOptions;
320
436
  annotations: Annotation[];
437
+ /** The active selection, run-length encoded. Missing when nothing is selected. */
438
+ selection?: SerializedSelection;
321
439
  }
322
440
  interface ExportOptions {
323
441
  format?: 'image/png' | 'image/jpeg' | 'image/webp';
@@ -356,7 +474,9 @@ interface ImageEditorAIHooks {
356
474
  * ({@link applyProcess2Adjustments}); anything else (including a missing value, as in edits saved
357
475
  * before process versions existed) is the frozen legacy rendering ({@link applyLegacyAdjustments}).
358
476
  */
359
- declare function applyAdjustments(imageData: ImageData, adjustments: ImageAdjustments): void;
477
+ declare function applyAdjustments(imageData: ImageData, adjustments: ImageAdjustments, options?: {
478
+ layerMasks?: ReadonlyMap<string, ArrayLike<number>>;
479
+ }): void;
360
480
  /**
361
481
  * Process 1: the original 8-bit gamma-space rendering, clamping after every step. Frozen so
362
482
  * that edits saved without a `process` look exactly as they always have. `tint` is ignored.
@@ -540,6 +660,15 @@ interface RenderOptions {
540
660
  interactive?: boolean;
541
661
  draftAnnotation?: Annotation | null;
542
662
  draftCrop?: CropBox | null;
663
+ /**
664
+ * How the active selection is shown: marching ants (default when there is a selection),
665
+ * a Quick Mask tint over the unselected area (default when `state.quickMask`), or not at all.
666
+ */
667
+ selectionDisplay?: 'ants' | 'quickMask' | 'none';
668
+ /** Dash offset of the marching ants in screen pixels (animate it to make them march). */
669
+ antsOffset?: number;
670
+ /** A selection being drawn (e.g. a lasso), shown as a dashed outline in natural pixels. */
671
+ draftSelectionPath?: ImagePoint[] | null;
543
672
  }
544
673
  /**
545
674
  * Image Cache to avoid refetching HTMLImageElement objects repeatedly during re-renders.
@@ -581,6 +710,13 @@ declare class ImageEditorRenderer {
581
710
  * and the depth mask (which receives the identical transform so it stays aligned).
582
711
  */
583
712
  private renderBaseImage;
713
+ private quickMaskCache;
714
+ private outlineCache;
715
+ /** Rubylith over the unselected area, drawn in natural image space. */
716
+ private drawQuickMask;
717
+ /** Marching ants: a white line under a black dashed one, one screen pixel wide. */
718
+ private drawAnts;
719
+ private drawDraftPath;
584
720
  private getSourceId;
585
721
  /**
586
722
  * Draws an individual annotation onto the canvas.
@@ -623,10 +759,355 @@ declare class ImageEditorRenderer {
623
759
  renderMask(state: ImageEditorState, options?: {
624
760
  useAnnotations?: boolean;
625
761
  useCrop?: boolean;
762
+ useSelection?: boolean;
626
763
  }): Promise<HTMLCanvasElement>;
627
764
  private drawAnnotationMask;
628
765
  }
629
766
 
767
+ interface ShapeSelectionOptions {
768
+ /** Partial coverage along the edge (default true). */
769
+ antiAlias?: boolean;
770
+ }
771
+ /**
772
+ * Even-odd polygon coverage over a `width × height` image: exact horizontal coverage on 4
773
+ * sub-rows per pixel row (1 without anti-aliasing, where a pixel is in when its centre is).
774
+ * Each sub-row only tests the edges that cross it (an active edge list over edges sorted by
775
+ * their top), so the cost is about pixels + edges × rows they span.
776
+ */
777
+ declare function polygonCoverage(points: readonly ImagePoint[], width: number, height: number, antiAlias?: boolean): Float32Array;
778
+ /** Lasso / polygonal lasso: an even-odd polygon in natural image pixels. */
779
+ declare function polygonSelection(width: number, height: number, points: readonly ImagePoint[], options?: ShapeSelectionOptions): SelectionMask;
780
+ /** Normalises a rectangle with a negative width or height. */
781
+ declare function normalizeRect(rect: CropBox): CropBox;
782
+ /** Rectangular marquee. Fractional edges get partial coverage when anti-aliased. */
783
+ declare function rectSelection(width: number, height: number, rect: CropBox, options?: ShapeSelectionOptions): SelectionMask;
784
+ /** The ellipse inscribed in `rect` as a polygon fine enough that its chords stay within 0.05 px. */
785
+ declare function ellipsePoints(rect: CropBox): ImagePoint[];
786
+ /** Elliptical marquee inscribed in `rect`. */
787
+ declare function ellipseSelection(width: number, height: number, rect: CropBox, options?: ShapeSelectionOptions): SelectionMask;
788
+
789
+ /** How the magic wand measures colour difference. */
790
+ type ColorDistance = 'rgb' | 'perceptual';
791
+ interface MagicWandOptions {
792
+ /**
793
+ * 0..255. `rgb`: the largest per-channel difference in levels (alpha included), as
794
+ * Photoshop's wand. `perceptual`: CIE76 ΔE*ab, with 255 ≙ ΔE 100. Default 32.
795
+ */
796
+ tolerance?: number;
797
+ /** Only the 4-connected region around the seed (default true); otherwise every similar pixel. */
798
+ contiguous?: boolean;
799
+ /** Soft one-pixel fringe on the edge (default true). */
800
+ antiAlias?: boolean;
801
+ /** Default `rgb`. */
802
+ distance?: ColorDistance;
803
+ }
804
+ /** CIE Lab (D65) of an 8-bit sRGB colour. */
805
+ declare function srgb8ToLab(r: number, g: number, b: number): [number, number, number];
806
+ /**
807
+ * Magic wand: pixels similar to the seed pixel. Contiguous mode is a scanline span fill with an
808
+ * explicit stack (fill a run, then scan the rows above and below it for new runs), so it is
809
+ * linear in the pixels visited and never recurses. An empty selection when the seed is outside.
810
+ */
811
+ declare function magicWand(pixels: PixelBuffer, seed: ImagePoint, options?: MagicWandOptions): SelectionMask;
812
+ /** One Color Range sample: a colour (0..255 levels or `#rrggbb`) and, optionally, where it was picked. */
813
+ interface ColorRangeSample {
814
+ color: readonly [number, number, number] | string;
815
+ at?: ImagePoint;
816
+ }
817
+ interface ColorRangeOptions {
818
+ /** 0..200 levels (default 40): coverage falls off linearly to 0 at `fuzziness + 1` levels. */
819
+ fuzziness?: number;
820
+ /**
821
+ * Localized Color Clusters: a sample with a position also fades with distance from it,
822
+ * reaching 0 at this many pixels.
823
+ */
824
+ localized?: number;
825
+ }
826
+ /**
827
+ * Select › Color Range › Sampled Colors: each pixel takes its best match over the samples; a
828
+ * match falls off linearly with the largest per-channel difference, `1 − d / (fuzziness + 1)`.
829
+ * Transparent pixels are never selected.
830
+ */
831
+ declare function colorRange(pixels: PixelBuffer, samples: readonly ColorRangeSample[], options?: ColorRangeOptions): SelectionMask;
832
+ type ToneRangePreset = 'shadows' | 'midtones' | 'highlights';
833
+ /** Luma bounds (0..255, Rec. 601) of the tonal presets. */
834
+ declare const TONE_RANGE_PRESETS: Record<ToneRangePreset, [number, number]>;
835
+ /**
836
+ * Select › Color Range › Shadows / Midtones / Highlights: pixels whose luma lies in `lo..hi` are
837
+ * selected; outside, selection falls off linearly to 0 over `falloff` levels.
838
+ */
839
+ declare function toneRange(pixels: PixelBuffer, range: ToneRangePreset | readonly [number, number], falloff?: number): SelectionMask;
840
+ /**
841
+ * Select › Color Range › Reds … Magentas (`center` 0, 60, …, 300°): closeness of hue (full at
842
+ * the centre, none 60° away) × chroma × (2 − max), so neutrals are never selected.
843
+ */
844
+ declare function hueRange(pixels: PixelBuffer, center: number): SelectionMask;
845
+
846
+ /** Distance reported for every pixel when there is no seed at all. */
847
+ declare const EMPTY_DISTANCE = 10000000000;
848
+ /**
849
+ * Exact Euclidean distance from every pixel centre to the nearest seed pixel centre (row-major
850
+ * `inside`, non-zero = seed): nearest seeds along columns, then the lower envelope of parabolas
851
+ * along rows (Felzenszwalb & Huttenlocher). Linear in the pixel count.
852
+ */
853
+ declare function distanceTransform(inside: ArrayLike<number | boolean>, width: number, height: number): Float32Array;
854
+ /** Grows coverage (0..1) by `r` pixels: covered when the nearest selected centre is ≤ r away (fractional r → partial). */
855
+ declare function expandCoverage(m: ArrayLike<number>, w: number, h: number, r: number): Float32Array;
856
+ /** Shrinks coverage by `r` pixels (expands the inverse). */
857
+ declare function contractCoverage(m: ArrayLike<number>, w: number, h: number, r: number): Float32Array;
858
+ /**
859
+ * Select › Modify › Border: a soft band `2r` wide centred on the edge. A pixel `D` away (centre
860
+ * to centre) from the nearest pixel on the other side of the edge is selected `1 − (D − 1) / r`.
861
+ */
862
+ declare function borderCoverage(m: ArrayLike<number>, w: number, h: number, r: number): Float32Array;
863
+ /**
864
+ * Select › Modify › Smooth: box average of radius `round(r)` with replicated edges, then
865
+ * re-thresholded at ½ — specks drop, corners round, straight edges stay hard.
866
+ */
867
+ declare function smoothCoverage(m: ArrayLike<number>, w: number, h: number, r: number): Float32Array;
868
+ /** Above this σ a Gaussian is approximated by three box passes (cost independent of σ). */
869
+ declare const DIRECT_GAUSSIAN_MAX_SIGMA = 8;
870
+ type Edge = 'zero' | 'clamp';
871
+ /**
872
+ * Separable Gaussian blur of a single-channel float image. `edge` `zero` treats pixels beyond
873
+ * the image as 0 (selection feather), `clamp` replicates the border (mask refinement). σ up to
874
+ * {@link DIRECT_GAUSSIAN_MAX_SIGMA} is convolved directly; wider blurs use three box passes, so
875
+ * the cost per pixel never grows with σ.
876
+ */
877
+ declare function gaussianBlur(src: ArrayLike<number>, w: number, h: number, sigma: number, edge?: Edge): Float32Array;
878
+ /** Select › Modify › Feather: Gaussian blur with σ = radius (as Photoshop), zero beyond the image. */
879
+ declare function featherCoverage(m: ArrayLike<number>, w: number, h: number, radius: number): Float32Array;
880
+ /** Grey dilation (`grow`) or erosion with a square of radius `r`, separable, O(1) per pixel. */
881
+ declare function greyMorphology(src: ArrayLike<number>, w: number, h: number, r: number, grow: boolean): Float32Array;
882
+ /**
883
+ * Grows (positive) or shrinks (negative) soft coverage by a fractional distance: whole pixels
884
+ * use one morphology, the remainder blends with the next pixel, so 0.3 px differs from 1 px.
885
+ */
886
+ declare function shiftCoverage(src: ArrayLike<number>, w: number, h: number, amount: number): Float32Array;
887
+ type SelectionModifyOp = 'grow' | 'shrink' | 'feather' | 'border' | 'smooth';
888
+ declare const SELECTION_MODIFY_OPS: readonly SelectionModifyOp[];
889
+ /** Select › Modify (grow = Expand, shrink = Contract, feather, border, smooth) by `radius` pixels. */
890
+ declare function modifySelection(mask: SelectionMask, op: SelectionModifyOp, radius: number): SelectionMask;
891
+
892
+ /**
893
+ * Refine Edge / Select and Mask parameters (Photoshop's units). Refinement is edge-aware: within
894
+ * `radius` pixels of the mask's edge the coverage is re-estimated from the image with a colour
895
+ * guided filter (He et al.), so a coarse or misaligned mask (e.g. an AI segmentation) follows
896
+ * the real edges of the image.
897
+ */
898
+ interface RefineEdgeParams {
899
+ /** Edge-detection band radius in pixels (0 = no edge detection). */
900
+ radius?: number;
901
+ /** Narrow the band where the image edge is sharp (hair stays soft, hard edges stay hard). */
902
+ smartRadius?: boolean;
903
+ /** 0..100: rounds jagged edges. */
904
+ smooth?: number;
905
+ /** Pixels of Gaussian softening. */
906
+ feather?: number;
907
+ /** 0..100: hardens soft edges. */
908
+ contrast?: number;
909
+ /** −100..100: moves the edge out (positive) or in; 100 % is `max(radius, 4)` pixels. */
910
+ shiftEdge?: number;
911
+ }
912
+ declare const DEFAULT_REFINE_EDGE_PARAMS: Required<RefineEdgeParams>;
913
+ /** Guided-filter regulariser (colour guide, samples in 0..1). */
914
+ declare const GUIDED_FILTER_EPS = 0.0001;
915
+ /** Clamped, complete parameters. */
916
+ declare function normalizeRefineEdgeParams(p?: RefineEdgeParams): Required<RefineEdgeParams>;
917
+ /** Pixels around the mask's content that refinement can read or write. */
918
+ declare function refineEdgeHalo(params?: RefineEdgeParams): number;
919
+ /** Box mean of radius `r` (window clipped to the image, divided by its pixel count). O(1) per pixel. */
920
+ declare function boxMean(src: ArrayLike<number>, w: number, h: number, r: number): Float32Array;
921
+ /**
922
+ * Guided filter with a colour guide (He et al., Eq. 19–21: `a_k = (Σ_k + εU)⁻¹ cov_k(I, p)`):
923
+ * filters `p` so that it is locally a linear function of the guide's colour, which makes the
924
+ * output's edges follow the guide's edges. `guide` is three planes of 0..1 values.
925
+ */
926
+ declare function guidedFilterColor(guide: readonly [Float32Array, Float32Array, Float32Array], p: Float32Array, w: number, h: number, r: number, eps?: number): Float32Array;
927
+ /**
928
+ * Per-pixel transition width (pixels) of the guide's luminance: local range over local maximum
929
+ * gradient in a window of radius `r` (a sharp step gives about 2, a ramp of width L about L).
930
+ */
931
+ declare function edgeWidth(guide: readonly [Float32Array, Float32Array, Float32Array], w: number, h: number, r: number): Float32Array;
932
+ /**
933
+ * Refines soft coverage `m` (`w × h`, 0..1) with `guide` (three 0..1 planes, required when
934
+ * `radius > 0`): edge-aware re-estimation in a band around the edge, then smooth, feather,
935
+ * contrast and shift edge, in that order.
936
+ */
937
+ declare function refineCoverage(guide: readonly [Float32Array, Float32Array, Float32Array] | null, m: Float32Array, w: number, h: number, params?: RefineEdgeParams): Float32Array;
938
+ /** Three 0..1 planes of a window of an RGBA buffer. */
939
+ declare function guidePlanes(pixels: PixelBuffer, win?: CropBox): [Float32Array, Float32Array, Float32Array];
940
+ /**
941
+ * Refine Edge on a selection (or a coarse AI mask loaded as one) against `pixels` (the image,
942
+ * same size). Work is confined to the mask's bounds grown by {@link refineEdgeHalo}, so a small
943
+ * selection on a large image stays cheap.
944
+ */
945
+ declare function refineSelection(pixels: PixelBuffer | null, mask: SelectionMask, params?: RefineEdgeParams): SelectionMask;
946
+
947
+ type CropHandle = 'nw' | 'ne' | 'se' | 'sw' | 'n' | 's' | 'e' | 'w' | 'inside' | null;
948
+ interface ViewportMetrics {
949
+ vpWidth: number;
950
+ vpHeight: number;
951
+ centerX: number;
952
+ centerY: number;
953
+ baseW: number;
954
+ baseH: number;
955
+ fitScale: number;
956
+ renderW: number;
957
+ renderH: number;
958
+ totalScale: number;
959
+ imageRect: {
960
+ x: number;
961
+ y: number;
962
+ width: number;
963
+ height: number;
964
+ };
965
+ cropRect: {
966
+ x: number;
967
+ y: number;
968
+ width: number;
969
+ height: number;
970
+ } | null;
971
+ }
972
+ /**
973
+ * A complete description of the natural-image -> target mapping (see module comment).
974
+ */
975
+ interface ImageProjection {
976
+ /** Visible region in natural image pixels (crop box or full image). */
977
+ region: CropBox;
978
+ /** Rotation in degrees, normalised to [0, 360). */
979
+ angle: number;
980
+ flipH: boolean;
981
+ flipV: boolean;
982
+ /** Uniform scale from image pixels to target pixels. */
983
+ scale: number;
984
+ /** Target-space point that the centre of `region` maps to. */
985
+ originX: number;
986
+ originY: number;
987
+ }
988
+ /** Normalises any rotation in degrees to [0, 360). */
989
+ declare function normalizeAngle(degrees: number): number;
990
+ /** Whether the rotation swaps the displayed width and height. */
991
+ declare function isQuarterTurnSwapped(transform: Pick<ImageTransform, 'rotate'>): boolean;
992
+ /** Size of a region once rotated (bounding box for arbitrary angles). */
993
+ declare function getRotatedSize(width: number, height: number, transform: Pick<ImageTransform, 'rotate'>): {
994
+ width: number;
995
+ height: number;
996
+ };
997
+ /** Maps a natural-image point to target space. */
998
+ declare function projectImagePoint(pt: ImagePoint, p: ImageProjection): ImagePoint;
999
+ /** Exact inverse of {@link projectImagePoint}. */
1000
+ declare function unprojectCanvasPoint(pt: ImagePoint, p: ImageProjection): ImagePoint;
1001
+ /**
1002
+ * Applies the projection to a 2D context so that subsequent drawing in natural image
1003
+ * pixels lands exactly where {@link projectImagePoint} says it does.
1004
+ */
1005
+ declare function applyImageProjectionToContext(ctx: Pick<CanvasRenderingContext2D, 'translate' | 'scale' | 'rotate'>, p: ImageProjection): void;
1006
+ /** Projects an image-space rectangle and returns its target-space bounding box. */
1007
+ declare function projectImageRect(rect: CropBox, p: ImageProjection): {
1008
+ x: number;
1009
+ y: number;
1010
+ width: number;
1011
+ height: number;
1012
+ };
1013
+ /** Clamps a crop box to the image bounds. */
1014
+ declare function clampCropToImage(crop: CropBox, width: number, height: number): CropBox;
1015
+ /**
1016
+ * Returns the natural-image -> canvas projection used by the interactive viewport.
1017
+ */
1018
+ declare function getViewportProjection(state: ImageEditorState, vpWidth: number, vpHeight: number, isActivelyCropping?: boolean, cropOverride?: CropBox | null): ImageProjection;
1019
+ /**
1020
+ * Calculates current viewport projection metrics for canvas <-> image coordinate mapping.
1021
+ * `cropRect` is the on-screen (rotated/flipped) rectangle of the crop box.
1022
+ */
1023
+ declare function getViewportMetrics(state: ImageEditorState, vpWidth: number, vpHeight: number, isActivelyCropping?: boolean, cropOverride?: CropBox | null): ViewportMetrics;
1024
+ /**
1025
+ * Converts a point on the canvas (in internal canvas pixel space) to natural image pixel
1026
+ * space, accounting for zoom, pan, fit scale, crop offset, rotation and flips.
1027
+ */
1028
+ declare function canvasToImagePoint(canvasPt: ImagePoint, state: ImageEditorState, vpWidth: number, vpHeight: number, isActivelyCropping?: boolean): ImagePoint;
1029
+ /**
1030
+ * Converts a point in natural image pixel space to internal canvas pixel space.
1031
+ * Exact inverse of {@link canvasToImagePoint}.
1032
+ */
1033
+ declare function imageToCanvasPoint(imgPt: ImagePoint, state: ImageEditorState, vpWidth: number, vpHeight: number, isActivelyCropping?: boolean): ImagePoint;
1034
+ /**
1035
+ * Converts a crop handle in screen orientation to the equivalent edge/corner of the crop
1036
+ * box in natural image space, or the reverse with `toScreen = true`.
1037
+ */
1038
+ declare function mapCropHandle(handle: CropHandle, transform: ImageTransform, toScreen?: boolean): CropHandle;
1039
+ /**
1040
+ * Hit-tests the crop box and its corner/edge handles given a canvas point.
1041
+ * The returned handle names the edge/corner of the crop box in natural image space
1042
+ * (what {@link calculateCropDrag} expects); use `getCropCursor(handle, state.transform)`
1043
+ * to obtain the matching on-screen cursor.
1044
+ */
1045
+ declare function hitTestCrop(canvasPt: ImagePoint, state: ImageEditorState, vpWidth: number, vpHeight: number, handleThreshold?: number, cropOverride?: CropBox | null): CropHandle;
1046
+ /**
1047
+ * Returns CSS cursor style corresponding to a crop handle. Pass the current transform when
1048
+ * the handle comes from {@link hitTestCrop} (image space) so the cursor matches the
1049
+ * on-screen orientation under rotation/flip.
1050
+ */
1051
+ declare function getCropCursor(handle: CropHandle, transform?: ImageTransform): string;
1052
+ /**
1053
+ * Calculates updated crop rectangle given a drag interaction.
1054
+ */
1055
+ declare function calculateCropDrag(startCrop: CropBox, handle: CropHandle, startImgPt: ImagePoint, currentImgPt: ImagePoint, imgWidth: number, imgHeight: number, aspectRatio?: number | null, transform?: ImageTransform): CropBox;
1056
+ /**
1057
+ * Calculates bounding box of an annotation.
1058
+ */
1059
+ declare function getAnnotationBounds(ann: Annotation): {
1060
+ x: number;
1061
+ y: number;
1062
+ width: number;
1063
+ height: number;
1064
+ };
1065
+ /**
1066
+ * Hit tests if a point in image space is within an annotation's bounds.
1067
+ */
1068
+ declare function hitTestAnnotation(imgPt: ImagePoint, ann: Annotation, padding?: number): boolean;
1069
+
1070
+ /** Properties of a layer mask that leave its pixels intact (Photoshop's Properties › Masks). */
1071
+ interface LayerMaskProps {
1072
+ /** 0..1 (default 1): at 0.5 the masked-out areas still get half of the adjustment. */
1073
+ density?: number;
1074
+ /** Gaussian feather σ in pixels, 0..1000 (default 0). */
1075
+ feather?: number;
1076
+ /** Disabled masks are kept but ignored (the layer applies everywhere). Default true. */
1077
+ enabled?: boolean;
1078
+ }
1079
+ /**
1080
+ * A clean layer mask from stored data, or `null` when it is unusable. Defaults are left out
1081
+ * (density 1, feather 0, enabled), so a plain mask serializes as `{width, height, rle}`. The
1082
+ * RLE is only decoded when rendering.
1083
+ */
1084
+ declare function normalizeLayerMask(raw: unknown): AdjustmentLayerMask | null;
1085
+ /** A layer mask holding the selection's pixels (Add Layer Mask › Reveal Selection). */
1086
+ declare function layerMaskFromSelection(selection: SelectionMask, props?: LayerMaskProps): AdjustmentLayerMask;
1087
+ /** Applies property changes; `undefined` fields keep their value. */
1088
+ declare function updateLayerMaskProps(mask: AdjustmentLayerMask, props: LayerMaskProps): AdjustmentLayerMask;
1089
+ /** The mask's pixels as a selection (Load Selection from mask), or `null` when the data is damaged. */
1090
+ declare function decodeLayerMask(mask: AdjustmentLayerMask): SelectionMask | null;
1091
+ /** Cache key of everything about a mask that changes pixels. */
1092
+ declare function layerMaskKey(mask: AdjustmentLayerMask | undefined): string;
1093
+ /**
1094
+ * The mask's effective coverage (0..1, mask resolution): feathered (σ = feather, borders
1095
+ * replicated), then density applied as `1 − density·(1 − v)`. `null` for a disabled or damaged
1096
+ * mask, meaning "no mask".
1097
+ */
1098
+ declare function layerMaskCoverage(mask: AdjustmentLayerMask): Float32Array | null;
1099
+ /**
1100
+ * Resamples mask coverage (natural-image aligned, any resolution) into a target raster drawn
1101
+ * through `projection` (the base canvas of the renderer: crop, rotation, flips): each target
1102
+ * pixel centre is unprojected to natural pixels and sampled bilinearly.
1103
+ */
1104
+ declare function projectMaskCoverage(coverage: Float32Array, maskWidth: number, maskHeight: number, naturalWidth: number, naturalHeight: number, projection: ImageProjection, targetWidth: number, targetHeight: number): Float32Array;
1105
+ /**
1106
+ * Per-layer mask coverage for a render target, keyed by layer id; `undefined` when no layer has
1107
+ * an enabled, valid mask (so mask-free stacks take the exact same path as before).
1108
+ */
1109
+ declare function buildLayerMaskPlanes(layers: readonly AdjustmentLayer[] | undefined, naturalWidth: number, naturalHeight: number, projection: ImageProjection, targetWidth: number, targetHeight: number): Map<string, Float32Array> | undefined;
1110
+
630
1111
  /** Latest serialized schema version (`2`: adjustment layers). */
631
1112
  declare const IMAGE_EDITOR_SCHEMA_VERSION: 2;
632
1113
  /** Changes to an adjustment layer; `params` is merged into the current parameters. */
@@ -636,6 +1117,22 @@ interface AdjustmentLayerUpdate<K extends AdjustmentKind = AdjustmentKind> {
636
1117
  opacity?: number;
637
1118
  blend?: BlendMode;
638
1119
  name?: string;
1120
+ /** A layer mask, or `null` to remove it. */
1121
+ mask?: AdjustmentLayerMask | null;
1122
+ }
1123
+ /** Options shared by the selection commands. */
1124
+ interface SelectionCommandOptions {
1125
+ /** How the result combines with the current selection (default `replace`). */
1126
+ mode?: SelectionMode;
1127
+ /** Feather the new shape by this many pixels before combining (default 0). */
1128
+ feather?: number;
1129
+ }
1130
+ /** Where the selection tools read colours from. */
1131
+ interface SampleOptions {
1132
+ /** Sample the adjusted image (base adjustments and layers) instead of the source pixels. */
1133
+ sampleMerged?: boolean;
1134
+ /** Pixels to use instead of reading the source image (natural size, RGBA). */
1135
+ pixels?: PixelBuffer;
639
1136
  }
640
1137
  /** A new adjustment layer: its kind plus optional initial values. */
641
1138
  interface AdjustmentLayerInit<K extends AdjustmentKind = AdjustmentKind> extends AdjustmentLayerUpdate<K> {
@@ -674,6 +1171,9 @@ declare class ImageEditorController {
674
1171
  private maxHistoryDepth;
675
1172
  private isApplyingHistory;
676
1173
  private initialSnapshot;
1174
+ /** Pixels the selection tools sample (host-provided or read back from the source). */
1175
+ private samplePixels;
1176
+ private samplePixelsOverride;
677
1177
  constructor(options?: ImageEditorOptions);
678
1178
  /**
679
1179
  * Loads a new source image and makes it the baseline that `reset()` returns to.
@@ -735,6 +1235,79 @@ declare class ImageEditorController {
735
1235
  toggleAdjustmentLayer(id: string, enabled?: boolean): boolean;
736
1236
  /** Removes every adjustment layer as one undo step. */
737
1237
  clearAdjustmentLayers(): void;
1238
+ /** The active selection, or `null`. */
1239
+ getSelection(): SelectionMask | null;
1240
+ get hasSelection(): boolean;
1241
+ private get naturalSize();
1242
+ private dropMismatchedSelection;
1243
+ /**
1244
+ * Replaces the selection, or combines `mask` with it by `mode`, as one undo step. A mask of a
1245
+ * different size (e.g. an AI segmentation at another resolution) is resampled to the image.
1246
+ * Returns false when nothing changed.
1247
+ */
1248
+ setSelection(mask: SelectionMask | null, mode?: SelectionMode): boolean;
1249
+ /** Select › All. */
1250
+ selectAll(): boolean;
1251
+ /** Select › Deselect. */
1252
+ deselect(): boolean;
1253
+ /** Select › Inverse (with nothing selected, selects everything). */
1254
+ invertSelection(): boolean;
1255
+ private shapeCommand;
1256
+ /** Rectangular marquee in natural image pixels. */
1257
+ selectRect(rect: CropBox, options?: SelectionCommandOptions & ShapeSelectionOptions): boolean;
1258
+ /** Elliptical marquee inscribed in `rect`. */
1259
+ selectEllipse(rect: CropBox, options?: SelectionCommandOptions & ShapeSelectionOptions): boolean;
1260
+ /** Lasso / polygonal lasso. */
1261
+ selectPolygon(points: ImagePoint[], options?: SelectionCommandOptions & ShapeSelectionOptions): boolean;
1262
+ /**
1263
+ * Supplies the pixels the selection tools sample (natural size RGBA), e.g. decoded in a worker
1264
+ * or in a test; `null` goes back to reading the source image. A new source image clears it.
1265
+ */
1266
+ setSamplePixels(pixels: PixelBuffer | null): void;
1267
+ /**
1268
+ * The pixels the selection tools sample: the source image at natural size, or with
1269
+ * `sampleMerged` the source after the base adjustments and adjustment layers (no crop,
1270
+ * rotation or annotations). `null` without pixel access (no DOM, tainted canvas).
1271
+ */
1272
+ getSamplePixels(options?: SampleOptions): Promise<PixelBuffer | null>;
1273
+ private requirePixels;
1274
+ /**
1275
+ * Magic wand at `point` (natural image pixels). Resolves to the resulting selection (null when
1276
+ * nothing is selected).
1277
+ */
1278
+ magicWand(point: ImagePoint, options?: MagicWandOptions & SelectionCommandOptions & SampleOptions): Promise<SelectionMask | null>;
1279
+ /** Select › Color Range with colour samples (`#rrggbb` or `[r, g, b]`, optionally where they were picked). */
1280
+ selectColorRange(samples: ColorRangeSample[], options?: ColorRangeOptions & SelectionCommandOptions & SampleOptions): Promise<SelectionMask | null>;
1281
+ /** Select › Modify: grow, shrink, feather, border or smooth by `radius` pixels (one undo step). */
1282
+ modifySelection(op: SelectionModifyOp, radius: number): boolean;
1283
+ /**
1284
+ * Refine Edge: snaps the selection (e.g. a coarse AI mask loaded with `loadSelectionFromImage`)
1285
+ * to the image's edges with a guided filter, then smooth / feather / contrast / shift edge.
1286
+ */
1287
+ refineSelection(params: RefineEdgeParams, options?: SampleOptions): Promise<boolean>;
1288
+ /**
1289
+ * Loads a selection from a mask image (an AI segmentation, a saved mask): a data URL / URL or
1290
+ * RGBA pixels, by luminance (white = selected) or a channel. Any size; it is resampled.
1291
+ */
1292
+ loadSelectionFromImage(source: string | PixelBuffer, options?: {
1293
+ channel?: SelectionChannel;
1294
+ invert?: boolean;
1295
+ threshold?: number;
1296
+ mode?: SelectionMode;
1297
+ }): Promise<SelectionMask | null>;
1298
+ /** Quick Mask view (tints the unselected area). View state: no undo step. */
1299
+ setQuickMask(on: boolean): void;
1300
+ /**
1301
+ * Adds the selection as the layer's mask (Reveal Selection), replacing any mask, as one undo
1302
+ * step. Without a selection, returns false.
1303
+ */
1304
+ applySelectionAsLayerMask(layerId: string, props?: LayerMaskProps): boolean;
1305
+ /** Sets (from a selection-shaped mask) or removes (`null`) a layer's mask as one undo step. */
1306
+ setAdjustmentLayerMask(layerId: string, mask: SelectionMask | null, props?: LayerMaskProps): boolean;
1307
+ /** Changes a layer mask's density (0..1), feather (px) or enabled flag; the mask pixels are kept. */
1308
+ setAdjustmentLayerMaskProps(layerId: string, props: LayerMaskProps, commitToHistory?: boolean): boolean;
1309
+ /** Load Selection from a layer mask (its pixels; density and feather are not applied). */
1310
+ selectionFromLayerMask(layerId: string, mode?: SelectionMode): boolean;
738
1311
  /**
739
1312
  * Histogram of the last rendered preview (after adjustments and layers, before annotations),
740
1313
  * or `null` before the first render or without canvas pixel access.
@@ -762,10 +1335,12 @@ declare class ImageEditorController {
762
1335
  renderMask(options?: {
763
1336
  useAnnotations?: boolean;
764
1337
  useCrop?: boolean;
1338
+ useSelection?: boolean;
765
1339
  }): Promise<HTMLCanvasElement>;
766
1340
  toMaskDataURL(options?: {
767
1341
  useAnnotations?: boolean;
768
1342
  useCrop?: boolean;
1343
+ useSelection?: boolean;
769
1344
  }): Promise<string>;
770
1345
  /**
771
1346
  * Renders the current source image at natural size with no crop, rotation, flip,
@@ -785,135 +1360,13 @@ declare class ImageEditorController {
785
1360
  */
786
1361
  applyBackgroundRemovedImage(newDataUrl: string): Promise<void>;
787
1362
  private replaceSource;
1363
+ /** The serializable state; `selection` is included (run-length encoded) only when something is selected. */
788
1364
  toJSON(): SerializedImageEditorState;
789
1365
  loadJSON(data: SerializedImageEditorState): void;
790
1366
  private serializeState;
791
1367
  private applySerializedState;
792
1368
  }
793
1369
 
794
- type CropHandle = 'nw' | 'ne' | 'se' | 'sw' | 'n' | 's' | 'e' | 'w' | 'inside' | null;
795
- interface ViewportMetrics {
796
- vpWidth: number;
797
- vpHeight: number;
798
- centerX: number;
799
- centerY: number;
800
- baseW: number;
801
- baseH: number;
802
- fitScale: number;
803
- renderW: number;
804
- renderH: number;
805
- totalScale: number;
806
- imageRect: {
807
- x: number;
808
- y: number;
809
- width: number;
810
- height: number;
811
- };
812
- cropRect: {
813
- x: number;
814
- y: number;
815
- width: number;
816
- height: number;
817
- } | null;
818
- }
819
- /**
820
- * A complete description of the natural-image -> target mapping (see module comment).
821
- */
822
- interface ImageProjection {
823
- /** Visible region in natural image pixels (crop box or full image). */
824
- region: CropBox;
825
- /** Rotation in degrees, normalised to [0, 360). */
826
- angle: number;
827
- flipH: boolean;
828
- flipV: boolean;
829
- /** Uniform scale from image pixels to target pixels. */
830
- scale: number;
831
- /** Target-space point that the centre of `region` maps to. */
832
- originX: number;
833
- originY: number;
834
- }
835
- /** Normalises any rotation in degrees to [0, 360). */
836
- declare function normalizeAngle(degrees: number): number;
837
- /** Whether the rotation swaps the displayed width and height. */
838
- declare function isQuarterTurnSwapped(transform: Pick<ImageTransform, 'rotate'>): boolean;
839
- /** Size of a region once rotated (bounding box for arbitrary angles). */
840
- declare function getRotatedSize(width: number, height: number, transform: Pick<ImageTransform, 'rotate'>): {
841
- width: number;
842
- height: number;
843
- };
844
- /** Maps a natural-image point to target space. */
845
- declare function projectImagePoint(pt: ImagePoint, p: ImageProjection): ImagePoint;
846
- /** Exact inverse of {@link projectImagePoint}. */
847
- declare function unprojectCanvasPoint(pt: ImagePoint, p: ImageProjection): ImagePoint;
848
- /**
849
- * Applies the projection to a 2D context so that subsequent drawing in natural image
850
- * pixels lands exactly where {@link projectImagePoint} says it does.
851
- */
852
- declare function applyImageProjectionToContext(ctx: Pick<CanvasRenderingContext2D, 'translate' | 'scale' | 'rotate'>, p: ImageProjection): void;
853
- /** Projects an image-space rectangle and returns its target-space bounding box. */
854
- declare function projectImageRect(rect: CropBox, p: ImageProjection): {
855
- x: number;
856
- y: number;
857
- width: number;
858
- height: number;
859
- };
860
- /** Clamps a crop box to the image bounds. */
861
- declare function clampCropToImage(crop: CropBox, width: number, height: number): CropBox;
862
- /**
863
- * Returns the natural-image -> canvas projection used by the interactive viewport.
864
- */
865
- declare function getViewportProjection(state: ImageEditorState, vpWidth: number, vpHeight: number, isActivelyCropping?: boolean, cropOverride?: CropBox | null): ImageProjection;
866
- /**
867
- * Calculates current viewport projection metrics for canvas <-> image coordinate mapping.
868
- * `cropRect` is the on-screen (rotated/flipped) rectangle of the crop box.
869
- */
870
- declare function getViewportMetrics(state: ImageEditorState, vpWidth: number, vpHeight: number, isActivelyCropping?: boolean, cropOverride?: CropBox | null): ViewportMetrics;
871
- /**
872
- * Converts a point on the canvas (in internal canvas pixel space) to natural image pixel
873
- * space, accounting for zoom, pan, fit scale, crop offset, rotation and flips.
874
- */
875
- declare function canvasToImagePoint(canvasPt: ImagePoint, state: ImageEditorState, vpWidth: number, vpHeight: number, isActivelyCropping?: boolean): ImagePoint;
876
- /**
877
- * Converts a point in natural image pixel space to internal canvas pixel space.
878
- * Exact inverse of {@link canvasToImagePoint}.
879
- */
880
- declare function imageToCanvasPoint(imgPt: ImagePoint, state: ImageEditorState, vpWidth: number, vpHeight: number, isActivelyCropping?: boolean): ImagePoint;
881
- /**
882
- * Converts a crop handle in screen orientation to the equivalent edge/corner of the crop
883
- * box in natural image space, or the reverse with `toScreen = true`.
884
- */
885
- declare function mapCropHandle(handle: CropHandle, transform: ImageTransform, toScreen?: boolean): CropHandle;
886
- /**
887
- * Hit-tests the crop box and its corner/edge handles given a canvas point.
888
- * The returned handle names the edge/corner of the crop box in natural image space
889
- * (what {@link calculateCropDrag} expects); use `getCropCursor(handle, state.transform)`
890
- * to obtain the matching on-screen cursor.
891
- */
892
- declare function hitTestCrop(canvasPt: ImagePoint, state: ImageEditorState, vpWidth: number, vpHeight: number, handleThreshold?: number, cropOverride?: CropBox | null): CropHandle;
893
- /**
894
- * Returns CSS cursor style corresponding to a crop handle. Pass the current transform when
895
- * the handle comes from {@link hitTestCrop} (image space) so the cursor matches the
896
- * on-screen orientation under rotation/flip.
897
- */
898
- declare function getCropCursor(handle: CropHandle, transform?: ImageTransform): string;
899
- /**
900
- * Calculates updated crop rectangle given a drag interaction.
901
- */
902
- declare function calculateCropDrag(startCrop: CropBox, handle: CropHandle, startImgPt: ImagePoint, currentImgPt: ImagePoint, imgWidth: number, imgHeight: number, aspectRatio?: number | null, transform?: ImageTransform): CropBox;
903
- /**
904
- * Calculates bounding box of an annotation.
905
- */
906
- declare function getAnnotationBounds(ann: Annotation): {
907
- x: number;
908
- y: number;
909
- width: number;
910
- height: number;
911
- };
912
- /**
913
- * Hit tests if a point in image space is within an annotation's bounds.
914
- */
915
- declare function hitTestAnnotation(imgPt: ImagePoint, ann: Annotation, padding?: number): boolean;
916
-
917
1370
  /** The `version` that `ImageEditorController.toJSON()` writes. */
918
1371
  declare const IMAGE_EDITOR_STATE_VERSION = 1;
919
1372
  /**
@@ -934,7 +1387,8 @@ interface ImageEditorDocumentLoad {
934
1387
  * - Runs `imageEditorStateMigrations` up to `IMAGE_EDITOR_STATE_VERSION`; a missing
935
1388
  * `version` is taken as current.
936
1389
  * - A newer `version` is still loaded but reported `readOnly`: do not save over it.
937
- * - Each section (`crop`, `transform`, `adjustments`, `depthMask`, `annotations`)
1390
+ * - Each section (`crop`, `transform`, `adjustments`, `depthMask`, `annotations`, and the
1391
+ * optional run-length encoded `selection`)
938
1392
  * falls back to its default on its own; invalid annotations are dropped one by one.
939
1393
  * - Unknown top-level keys are returned in `unknown`.
940
1394
  *
@@ -976,6 +1430,7 @@ declare function createAdjustmentLayer<K extends AdjustmentKind>(kind: K, option
976
1430
  enabled?: boolean;
977
1431
  opacity?: number;
978
1432
  blend?: BlendMode;
1433
+ mask?: AdjustmentLayerMask;
979
1434
  }): AdjustmentLayerOf<K>;
980
1435
  /**
981
1436
  * A clean, deep-copied layer from stored or hand-written data: missing fields get neutral
@@ -1076,8 +1531,12 @@ declare function evaluateAdjustmentLayers(color: readonly number[], layers: read
1076
1531
  * Applies an adjustment-layer stack to 8-bit straight RGBA pixels in place. Each pixel is
1077
1532
  * decoded once, run through every layer in float, and encoded once. Transparent pixels are
1078
1533
  * left alone; alpha is never changed.
1534
+ *
1535
+ * `masks` (layer id → 0..1 coverage per pixel of `imageData`, see `buildLayerMaskPlanes`)
1536
+ * scales each masked layer's opacity per pixel: coverage 0 leaves the pixel as the layers below
1537
+ * made it, 1 applies the layer fully.
1079
1538
  */
1080
- declare function applyAdjustmentLayers(imageData: ImageData, layers: readonly AdjustmentLayer[] | undefined): void;
1539
+ declare function applyAdjustmentLayers(imageData: Pick<ImageData, 'data'>, layers: readonly AdjustmentLayer[] | undefined, masks?: ReadonlyMap<string, ArrayLike<number>>): void;
1081
1540
  /** Stable cache key of a layer stack's pixel effect (for renderer caches). */
1082
1541
  declare function adjustmentLayersKey(layers: readonly AdjustmentLayer[] | undefined): string;
1083
1542
 
@@ -1179,6 +1638,8 @@ interface ImageEditorToolProviderOptions {
1179
1638
  * control ranges and the applied values are echoed.
1180
1639
  * - `add_adjustment_layer {kind, params?, opacity?, blend?, name?}`.
1181
1640
  * - `render_preview {maxSide}`: the rendered image as a PNG, longest side at most `maxSide`.
1641
+ * - Selections and masks: `get_selection`, `select_region`, `select_by_color`, `modify_selection`,
1642
+ * `refine_selection`, `apply_selection_as_mask` (see `createImageSelectionTools`).
1182
1643
  */
1183
1644
  declare function createImageEditorToolProvider(controller: ImageEditorController, options?: ImageEditorToolProviderOptions): AgentToolProvider;
1184
1645
 
@@ -1203,4 +1664,108 @@ declare function moveCurvePoint(points: readonly CurvePoint[], index: number, p:
1203
1664
  /** Removes point `index`; a curve keeps at least two points. */
1204
1665
  declare function removeCurvePoint(points: readonly CurvePoint[], index: number): CurvePoint[];
1205
1666
 
1206
- export { ADJUSTMENT_KINDS, ADJUSTMENT_LAYER_CONTROLS, ADJUSTMENT_LAYER_OPACITY_CONTROL, ADJUSTMENT_LUT_SIZE, AS_SHOT_KELVIN, type AdjustmentKind, type AdjustmentKindInfo, type AdjustmentLayer, type AdjustmentLayerBase, type AdjustmentLayerInit, type AdjustmentLayerOf, type AdjustmentLayerUpdate, type AdjustmentParamsMap, type Annotation, type AnnotationType, type ArrowAnnotation, type AspectRatio, BLEND_MODES, type BaseAnnotation, type BlackWhiteParams, type BlendMode, type BlendModeInfo, type Chromaticity, type CircleAnnotation, type ColorBalanceParams, type ColorBalanceTone, type ControlSection, type ControlSpec, type ControlTrack, type CreateAnnotationPayload, type CropBox, type CropHandle, type CurvePoint, type CurvesParams, D65, DEFAULT_ADJUSTMENTS, DEFAULT_DEPTH_MASK, DEFAULT_TRANSFORM, type DepthMaskOptions, type ExportOptions, HISTOGRAM_BINS, HUE_RANGE_LABELS, type HistogramChannel, type HueRange, type HueSaturationParams, IDENTITY_MATRIX3, IMAGE_ADJUSTMENT_CONTROLS, IMAGE_EDITOR_SCHEMA_VERSION, IMAGE_EDITOR_STATE_VERSION, type ImageAdjustments, type ImageAnnotation, type ImageDimensions, type ImageEditorAIHooks, ImageEditorController, type ImageEditorDocumentLoad, type ImageEditorOptions, ImageEditorRenderer, type ImageEditorState, type ImageEditorTool, type ImageEditorToolProviderOptions, type ImageHistogram, type ImagePoint, type ImageProcessVersion, type ImageProjection, type ImageTransform, type InpaintHook, type InpaintOptions, type InvertParams, LATEST_PROCESS_VERSION, LEGACY_PROCESS_VERSION, LUMA_709, type LevelsChannel, type LevelsParams, type LineAnnotation, MAX_KELVIN, MIN_KELVIN, MIRED_PER_TEMPERATURE_UNIT, type Matrix3, type PenAnnotation, type PhotoFilterParams, type PixelOp, type PosterizeParams, type RectAnnotation, type RemoveBackgroundHook, type RemoveBackgroundOptions, type RenderOptions, type Rgb$1 as Rgb, type Rgba, type SerializedImageEditorState, TINT_SCALE, TONE_LUT_SIZE, type TextAnnotation, type ThresholdParams, type UnitLevels, VIBRANCE_GREY, type VibranceParams, type ViewportMetrics, activeAdjustmentLayers, adjustmentKindLabel, adjustmentLayersKey, applyAdjustmentLayers, applyAdjustments, applyDepthMask, applyImageProjectionToContext, applyLegacyAdjustments, applyMatrix3, applyProcess2Adjustments, blackWhiteGray, blendChannel, blendImageData, blendLum, blendPixel, blendRgb, boxToCurvePoint, bradfordAdaptation, buildToneLut, calculateCropDrag, canvasCompositeOperation, canvasToImagePoint, clampControlValue, clampCropToImage, colorBalanceChannel, compileAdjustmentLayer, computeHistogram, controlPosition, controlTrackBackground, createAdjustmentLayer, createImageEditorToolProvider, curveLut, curveLutFromLevels, curvePointToBox, curveSvgPath, defaultAdjustmentParams, evaluateAdjustmentLayers, findAdjustmentControl, findLayerControl, formatControlValue, getAnnotationBounds, getControlPath, getCropCursor, getRotatedSize, getViewportMetrics, getViewportProjection, globalImageCache, hexToRgb, histogramPath, hitTestAnnotation, hitTestCrop, hitTestCurvePoint, hslToRgb, hueRangeTables, hueRangeWeight, hueSaturation, identityCurve, identityLevels, imageEditorStateMigrations, imageToCanvasPoint, insertCurvePoint, invertMatrix3, isAdjustmentKind, isBlendMode, isQuarterTurnSwapped, isSeparableBlendMode, kelvinToTemperature, levelsValue, linearSrgbToXy, linearToSrgb, loadImageEditorDocument, mapCropHandle, migrateSerializedImageEditorState, moveCurvePoint, mulMatrix3, neutralHueRange, normalizeAdjustmentLayer, normalizeAdjustmentLayers, normalizeAngle, normalizeBlendMode, normalizeProcessVersion, normalizeStoredAdjustments, photoFilterMatrix, posterizeValue, projectImagePoint, projectImageRect, rangeLightness, readAdjustmentControls, removeAlpha, removeCurvePoint, rgbToGray, rgbToHsl, sampleLut, sampleToneLut, setControlPath, setLum, srgbToLinear, tempTintToXy, temperatureToKelvin, toneCurve, toneLuts, unprojectCanvasPoint, uvToXy, vibranceLinear, vibrancePixel, wbMatrix, whiteBalanceFromSample, whiteBalanceMatrix, xyToTempTint, xyToUv };
1667
+ /**
1668
+ * The selection's outline at `threshold` (0..255, default 128) as axis-aligned segments on pixel
1669
+ * boundaries, `[x0, y0, x1, y1, …]` in natural image pixels, with collinear neighbours merged.
1670
+ * This is what marching ants are drawn from. Linear in the pixel count.
1671
+ */
1672
+ declare function selectionOutline(mask: SelectionMask, threshold?: number): Float32Array;
1673
+ interface QuickMaskStyle {
1674
+ /** Overlay colour, `[r, g, b]` 0..255 (default Photoshop's rubylith red). */
1675
+ color?: readonly [number, number, number];
1676
+ /** 0..1 (default 0.5): opacity over fully unselected pixels. */
1677
+ opacity?: number;
1678
+ }
1679
+ /**
1680
+ * Quick Mask view: RGBA pixels (natural image size) tinting the *unselected* area, so the
1681
+ * selection shows through clear, as Photoshop's rubylith overlay.
1682
+ */
1683
+ declare function quickMaskPixels(mask: SelectionMask, style?: QuickMaskStyle): Uint8ClampedArray;
1684
+
1685
+ /** Selection tools of the image editor UI. */
1686
+ type SelectionToolKind = 'wand' | 'rect' | 'ellipse' | 'lasso';
1687
+ declare const SELECTION_TOOLS: readonly {
1688
+ id: SelectionToolKind;
1689
+ label: string;
1690
+ }[];
1691
+ declare const SELECTION_MODE_LABELS: Record<SelectionMode, string>;
1692
+ /** The options bar of the selection tools (shared by the React and Svelte UIs). */
1693
+ interface SelectionToolOptions {
1694
+ tool: SelectionToolKind;
1695
+ mode: SelectionMode;
1696
+ /** Magic wand tolerance, 0..255. */
1697
+ tolerance: number;
1698
+ contiguous: boolean;
1699
+ antiAlias: boolean;
1700
+ /** Sample the adjusted image instead of the source. */
1701
+ sampleMerged: boolean;
1702
+ distance: ColorDistance;
1703
+ }
1704
+ declare const DEFAULT_SELECTION_TOOL_OPTIONS: SelectionToolOptions;
1705
+ /**
1706
+ * Photoshop's modifier keys: Shift adds, Alt/Option subtracts, both intersect; otherwise the
1707
+ * options bar mode.
1708
+ */
1709
+ declare function selectionModeFromModifiers(modifiers: {
1710
+ shiftKey?: boolean;
1711
+ altKey?: boolean;
1712
+ }, fallback: SelectionMode): SelectionMode;
1713
+ interface RefineEdgeControl {
1714
+ id: keyof Omit<RefineEdgeParams, 'smartRadius'>;
1715
+ label: string;
1716
+ min: number;
1717
+ max: number;
1718
+ step: number;
1719
+ unit: string;
1720
+ }
1721
+ /** Sliders of the Refine Edge panel. */
1722
+ declare const REFINE_EDGE_CONTROLS: readonly RefineEdgeControl[];
1723
+ /** A one-line status: "No selection" or "W × H px selected (n % of the image)". */
1724
+ declare function describeSelection(mask: SelectionMask | null | undefined): string;
1725
+
1726
+ interface GestureModifiers {
1727
+ shiftKey?: boolean;
1728
+ altKey?: boolean;
1729
+ }
1730
+ /**
1731
+ * Pointer gestures of the selection tools, shared by the React and Svelte image editors: feed
1732
+ * it pointer positions in natural image pixels (`canvasToImagePoint(..., false)`).
1733
+ *
1734
+ * - Magic wand: selects on `begin` (async, as it may read pixels).
1735
+ * - Rectangle / ellipse: drag a box; a click without a drag deselects (replace mode).
1736
+ * - Lasso: drag a free-hand path, closed on `end`.
1737
+ *
1738
+ * Shift adds, Alt subtracts, both intersect (overriding the options bar mode). While dragging,
1739
+ * {@link draftPath} is the outline to show (`RenderOptions.draftSelectionPath`).
1740
+ */
1741
+ declare class SelectionGesture {
1742
+ readonly controller: ImageEditorController;
1743
+ private readonly getOptions;
1744
+ private start;
1745
+ private points;
1746
+ private current;
1747
+ private modifiers;
1748
+ /** The last error (e.g. pixels unavailable for the wand), for the UI to show. */
1749
+ error: string | null;
1750
+ constructor(controller: ImageEditorController, getOptions: () => SelectionToolOptions);
1751
+ get active(): boolean;
1752
+ /** The outline of the shape being drawn, or `null`. */
1753
+ get draftPath(): ImagePoint[] | null;
1754
+ /** Pointer down. Resolves once a wand click has been applied. */
1755
+ begin(point: ImagePoint, modifiers?: GestureModifiers): Promise<void>;
1756
+ /** Pointer move; returns true when the draft changed (re-render). */
1757
+ move(point: ImagePoint): boolean;
1758
+ /** Pointer up: commits the shape. Returns true when the selection changed. */
1759
+ end(point?: ImagePoint, modifiers?: GestureModifiers): boolean;
1760
+ /** Abandons a drag without changing the selection. */
1761
+ cancel(): void;
1762
+ }
1763
+
1764
+ /**
1765
+ * Agent tools for selections and masks (part of `createImageEditorToolProvider`):
1766
+ * `get_selection`, `select_region`, `select_by_color`, `modify_selection`, `refine_selection`
1767
+ * and `apply_selection_as_mask`. Coordinates are natural pixels of the source image.
1768
+ */
1769
+ declare function createImageSelectionTools(controller: ImageEditorController): AgentTool[];
1770
+
1771
+ export { ADJUSTMENT_KINDS, ADJUSTMENT_LAYER_CONTROLS, ADJUSTMENT_LAYER_OPACITY_CONTROL, ADJUSTMENT_LUT_SIZE, AS_SHOT_KELVIN, type AdjustmentKind, type AdjustmentKindInfo, type AdjustmentLayer, type AdjustmentLayerBase, type AdjustmentLayerInit, type AdjustmentLayerMask, type AdjustmentLayerOf, type AdjustmentLayerUpdate, type AdjustmentParamsMap, type Annotation, type AnnotationType, type ArrowAnnotation, type AspectRatio, BLEND_MODES, type BaseAnnotation, type BlackWhiteParams, type BlendMode, type BlendModeInfo, type Chromaticity, type CircleAnnotation, type ColorBalanceParams, type ColorBalanceTone, type ColorDistance, type ColorRangeOptions, type ColorRangeSample, type ControlSection, type ControlSpec, type ControlTrack, type CreateAnnotationPayload, type CropBox, type CropHandle, type CurvePoint, type CurvesParams, D65, DEFAULT_ADJUSTMENTS, DEFAULT_DEPTH_MASK, DEFAULT_REFINE_EDGE_PARAMS, DEFAULT_SELECTION_TOOL_OPTIONS, DEFAULT_TRANSFORM, DIRECT_GAUSSIAN_MAX_SIGMA, type DepthMaskOptions, EMPTY_DISTANCE, type ExportOptions, GUIDED_FILTER_EPS, type GestureModifiers, HISTOGRAM_BINS, HUE_RANGE_LABELS, type HistogramChannel, type HueRange, type HueSaturationParams, IDENTITY_MATRIX3, IMAGE_ADJUSTMENT_CONTROLS, IMAGE_EDITOR_SCHEMA_VERSION, IMAGE_EDITOR_STATE_VERSION, type ImageAdjustments, type ImageAnnotation, type ImageDimensions, type ImageEditorAIHooks, ImageEditorController, type ImageEditorDocumentLoad, type ImageEditorOptions, ImageEditorRenderer, type ImageEditorState, type ImageEditorTool, type ImageEditorToolProviderOptions, type ImageHistogram, type ImagePoint, type ImageProcessVersion, type ImageProjection, type ImageTransform, type InpaintHook, type InpaintOptions, type InvertParams, LATEST_PROCESS_VERSION, LEGACY_PROCESS_VERSION, LUMA_709, type LayerMaskProps, type LevelsChannel, type LevelsParams, type LineAnnotation, MAX_KELVIN, MIN_KELVIN, MIRED_PER_TEMPERATURE_UNIT, type MagicWandOptions, type Matrix3, type PenAnnotation, type PhotoFilterParams, type PixelBuffer, type PixelOp, type PosterizeParams, type QuickMaskStyle, REFINE_EDGE_CONTROLS, type RectAnnotation, type RefineEdgeControl, type RefineEdgeParams, type RemoveBackgroundHook, type RemoveBackgroundOptions, type RenderOptions, type Rgb$1 as Rgb, type Rgba, SELECTION_MODES, SELECTION_MODE_LABELS, SELECTION_MODIFY_OPS, SELECTION_TOOLS, type SampleOptions, type SelectionChannel, type SelectionCommandOptions, SelectionGesture, type SelectionMask, type SelectionMode, type SelectionModifyOp, type SelectionToolKind, type SelectionToolOptions, type SerializedImageEditorState, type SerializedSelection, type ShapeSelectionOptions, TINT_SCALE, TONE_LUT_SIZE, TONE_RANGE_PRESETS, type TextAnnotation, type ThresholdParams, type ToneRangePreset, type UnitLevels, VIBRANCE_GREY, type VibranceParams, type ViewportMetrics, activeAdjustmentLayers, adjustmentKindLabel, adjustmentLayersKey, applyAdjustmentLayers, applyAdjustments, applyDepthMask, applyImageProjectionToContext, applyLegacyAdjustments, applyMatrix3, applyProcess2Adjustments, blackWhiteGray, blendChannel, blendImageData, blendLum, blendPixel, blendRgb, borderCoverage, boxMean, boxToCurvePoint, bradfordAdaptation, buildLayerMaskPlanes, buildToneLut, calculateCropDrag, canvasCompositeOperation, canvasToImagePoint, clampControlValue, clampCropToImage, colorBalanceChannel, colorRange, combineSelections, compileAdjustmentLayer, computeHistogram, computeSelectionBounds, contractCoverage, controlPosition, controlTrackBackground, coverageToByte, createAdjustmentLayer, createImageEditorToolProvider, createImageSelectionTools, createSelectionMask, curveLut, curveLutFromLevels, curvePointToBox, curveSvgPath, decodeLayerMask, decodeSelectionRle, defaultAdjustmentParams, describeSelection, deserializeSelection, distanceTransform, edgeWidth, ellipsePoints, ellipseSelection, encodeSelectionRle, evaluateAdjustmentLayers, expandCoverage, featherCoverage, findAdjustmentControl, findLayerControl, formatControlValue, fullSelection, gaussianBlur, getAnnotationBounds, getControlPath, getCropCursor, getRotatedSize, getViewportMetrics, getViewportProjection, globalImageCache, greyMorphology, guidePlanes, guidedFilterColor, hashMaskContent, hexToRgb, histogramPath, hitTestAnnotation, hitTestCrop, hitTestCurvePoint, hslToRgb, hueRange, hueRangeTables, hueRangeWeight, hueSaturation, identityCurve, identityLevels, imageEditorStateMigrations, imageToCanvasPoint, insertCurvePoint, invertMatrix3, invertSelection, isAdjustmentKind, isBlendMode, isQuarterTurnSwapped, isSelectionEmpty, isSelectionMode, isSeparableBlendMode, kelvinToTemperature, layerMaskCoverage, layerMaskFromSelection, layerMaskKey, levelsValue, linearSrgbToXy, linearToSrgb, loadImageEditorDocument, magicWand, mapCropHandle, migrateSerializedImageEditorState, modifySelection, moveCurvePoint, mulMatrix3, neutralHueRange, normalizeAdjustmentLayer, normalizeAdjustmentLayers, normalizeAngle, normalizeBlendMode, normalizeLayerMask, normalizeProcessVersion, normalizeRect, normalizeRefineEdgeParams, normalizeStoredAdjustments, parseSelectionMode, photoFilterMatrix, polygonCoverage, polygonSelection, posterizeValue, projectImagePoint, projectImageRect, projectMaskCoverage, quickMaskPixels, rangeLightness, readAdjustmentControls, rectSelection, refineCoverage, refineEdgeHalo, refineSelection, removeAlpha, removeCurvePoint, resizeSelection, rgbToGray, rgbToHsl, sampleLut, sampleToneLut, selectionArea, selectionFromCoverage, selectionFromPixels, selectionModeFromModifiers, selectionOutline, selectionToCoverage, selectionToPixels, selectionValueAt, serializeSelection, setControlPath, setLum, shiftCoverage, smoothCoverage, srgb8ToLab, srgbToLinear, tempTintToXy, temperatureToKelvin, toneCurve, toneLuts, toneRange, unprojectCanvasPoint, updateLayerMaskProps, uvToXy, vibranceLinear, vibrancePixel, wbMatrix, whiteBalanceFromSample, whiteBalanceMatrix, xyToTempTint, xyToUv };