@pixerate/editor 0.23.0 → 0.24.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 (155) hide show
  1. package/README.md +96 -1
  2. package/THIRD_PARTY_NOTICES.md +51 -0
  3. package/dist/agent/index.cjs +9 -8
  4. package/dist/agent/index.cjs.map +1 -1
  5. package/dist/agent/index.d.cts +4 -3
  6. package/dist/agent/index.d.ts +4 -3
  7. package/dist/agent/index.js +3 -2
  8. package/dist/agent/index.js.map +1 -1
  9. package/dist/canvas/index.cjs +1210 -17
  10. package/dist/canvas/index.cjs.map +1 -1
  11. package/dist/canvas/index.d.cts +318 -1
  12. package/dist/canvas/index.d.ts +318 -1
  13. package/dist/canvas/index.js +1199 -6
  14. package/dist/canvas/index.js.map +1 -1
  15. package/dist/{chunk-QBJ22YZR.js → chunk-3CN2WD3X.js} +1354 -206
  16. package/dist/chunk-3CN2WD3X.js.map +1 -0
  17. package/dist/{chunk-JJDLPEWL.js → chunk-3LV6RRPH.js} +2 -2
  18. package/dist/{chunk-MJZBNWG7.js → chunk-5S3Z4PPF.js} +78 -557
  19. package/dist/chunk-5S3Z4PPF.js.map +1 -0
  20. package/dist/chunk-664LQYFJ.js +115 -0
  21. package/dist/chunk-664LQYFJ.js.map +1 -0
  22. package/dist/{chunk-AA4ZEVCC.cjs → chunk-D27YFC46.cjs} +101 -580
  23. package/dist/chunk-D27YFC46.cjs.map +1 -0
  24. package/dist/chunk-D6FH2YAX.cjs +131 -0
  25. package/dist/chunk-D6FH2YAX.cjs.map +1 -0
  26. package/dist/{chunk-4SUNJZWB.cjs → chunk-FD4LPFAE.cjs} +48 -200
  27. package/dist/chunk-FD4LPFAE.cjs.map +1 -0
  28. package/dist/chunk-FODNLX5N.js +749 -0
  29. package/dist/chunk-FODNLX5N.js.map +1 -0
  30. package/dist/{chunk-OYXSKQFR.js → chunk-FPENXAEJ.js} +35 -187
  31. package/dist/chunk-FPENXAEJ.js.map +1 -0
  32. package/dist/chunk-HLIMTC6N.js +1 -0
  33. package/dist/chunk-HLIMTC6N.js.map +1 -0
  34. package/dist/{chunk-QGHGJ56O.js → chunk-ITBSKI26.js} +1483 -19
  35. package/dist/chunk-ITBSKI26.js.map +1 -0
  36. package/dist/{chunk-XDMXXC4Z.cjs → chunk-MA2F5KHF.cjs} +350 -227
  37. package/dist/chunk-MA2F5KHF.cjs.map +1 -0
  38. package/dist/{chunk-RIKBJLS2.cjs → chunk-MCSJFWAO.cjs} +1356 -208
  39. package/dist/chunk-MCSJFWAO.cjs.map +1 -0
  40. package/dist/chunk-MKA3AHLV.cjs +256 -0
  41. package/dist/chunk-MKA3AHLV.cjs.map +1 -0
  42. package/dist/chunk-OLZJXL4R.cjs +749 -0
  43. package/dist/chunk-OLZJXL4R.cjs.map +1 -0
  44. package/dist/chunk-OXSV64JX.js +689 -0
  45. package/dist/chunk-OXSV64JX.js.map +1 -0
  46. package/dist/chunk-P3RQ5UJE.cjs +689 -0
  47. package/dist/chunk-P3RQ5UJE.cjs.map +1 -0
  48. package/dist/chunk-P6ODPZ4W.js +256 -0
  49. package/dist/chunk-P6ODPZ4W.js.map +1 -0
  50. package/dist/chunk-PGNZKFQS.js +685 -0
  51. package/dist/chunk-PGNZKFQS.js.map +1 -0
  52. package/dist/chunk-PL4JB3BF.cjs +1 -0
  53. package/dist/chunk-PL4JB3BF.cjs.map +1 -0
  54. package/dist/{chunk-GVSMRPHB.cjs → chunk-SBCZ6RN5.cjs} +1568 -104
  55. package/dist/chunk-SBCZ6RN5.cjs.map +1 -0
  56. package/dist/{chunk-CL37JGFW.cjs → chunk-SML64VJG.cjs} +4 -4
  57. package/dist/{chunk-CL37JGFW.cjs.map → chunk-SML64VJG.cjs.map} +1 -1
  58. package/dist/chunk-TNNJXF46.cjs +115 -0
  59. package/dist/chunk-TNNJXF46.cjs.map +1 -0
  60. package/dist/chunk-U5HZSFCS.js +131 -0
  61. package/dist/chunk-U5HZSFCS.js.map +1 -0
  62. package/dist/{chunk-K3R5NG2D.js → chunk-U5KWZU4X.js} +251 -128
  63. package/dist/chunk-U5KWZU4X.js.map +1 -0
  64. package/dist/chunk-XNORY7M6.cjs +685 -0
  65. package/dist/chunk-XNORY7M6.cjs.map +1 -0
  66. package/dist/commands/index.d.cts +5 -353
  67. package/dist/commands/index.d.ts +5 -353
  68. package/dist/comment-store-BEMgVlAA.d.cts +135 -0
  69. package/dist/comment-store-BEMgVlAA.d.ts +135 -0
  70. package/dist/compare/index.cjs +15 -0
  71. package/dist/compare/index.cjs.map +1 -0
  72. package/dist/compare/index.d.cts +58 -0
  73. package/dist/compare/index.d.ts +58 -0
  74. package/dist/compare/index.js +15 -0
  75. package/dist/compare/index.js.map +1 -0
  76. package/dist/{controller-pePCJLT1.d.cts → controller-BhLLAoi8.d.cts} +45 -4
  77. package/dist/{controller-pePCJLT1.d.ts → controller-BhLLAoi8.d.ts} +45 -4
  78. package/dist/documents-BQjzJNe2.d.ts +76 -0
  79. package/dist/documents-KRTPhvst.d.cts +76 -0
  80. package/dist/extensions/index.cjs +53 -5
  81. package/dist/extensions/index.cjs.map +1 -1
  82. package/dist/extensions/index.d.cts +7 -3
  83. package/dist/extensions/index.d.ts +7 -3
  84. package/dist/extensions/index.js +52 -4
  85. package/dist/generation/index.cjs +1373 -0
  86. package/dist/generation/index.cjs.map +1 -0
  87. package/dist/generation/index.d.cts +554 -0
  88. package/dist/generation/index.d.ts +554 -0
  89. package/dist/generation/index.js +1373 -0
  90. package/dist/generation/index.js.map +1 -0
  91. package/dist/grammar/index.cjs +48 -3
  92. package/dist/grammar/index.cjs.map +1 -1
  93. package/dist/grammar/index.d.cts +322 -100
  94. package/dist/grammar/index.d.ts +322 -100
  95. package/dist/grammar/index.js +54 -9
  96. package/dist/image-editor/index.cjs +1831 -30
  97. package/dist/image-editor/index.cjs.map +1 -1
  98. package/dist/image-editor/index.d.cts +590 -3
  99. package/dist/image-editor/index.d.ts +590 -3
  100. package/dist/image-editor/index.js +1807 -6
  101. package/dist/image-editor/index.js.map +1 -1
  102. package/dist/{index-CCr_z9kF.d.cts → index-BhJBSm2d.d.cts} +370 -4
  103. package/dist/{index-Ck6ajwXh.d.ts → index-fJrlkJCd.d.ts} +370 -4
  104. package/dist/index.cjs +162 -25
  105. package/dist/index.cjs.map +1 -1
  106. package/dist/index.d.cts +14 -8
  107. package/dist/index.d.ts +14 -8
  108. package/dist/index.js +174 -37
  109. package/dist/index.js.map +1 -1
  110. package/dist/migrate-iTlm3a8h.d.cts +112 -0
  111. package/dist/migrate-iTlm3a8h.d.ts +112 -0
  112. package/dist/persistence/index.cjs +676 -0
  113. package/dist/persistence/index.cjs.map +1 -0
  114. package/dist/persistence/index.d.cts +347 -0
  115. package/dist/persistence/index.d.ts +347 -0
  116. package/dist/persistence/index.js +676 -0
  117. package/dist/persistence/index.js.map +1 -0
  118. package/dist/{registry-D5-R90p0.d.cts → registry-BDe-vlv3.d.ts} +2 -40
  119. package/dist/registry-D32LpIc4.d.cts +354 -0
  120. package/dist/{registry-D5-R90p0.d.ts → registry-DnzpgY27.d.cts} +2 -40
  121. package/dist/registry-evKTP4ls.d.ts +354 -0
  122. package/dist/schema-DYDGdYL9.d.cts +41 -0
  123. package/dist/schema-DYDGdYL9.d.ts +41 -0
  124. package/dist/serializers/index.cjs +4 -3
  125. package/dist/serializers/index.cjs.map +1 -1
  126. package/dist/serializers/index.d.cts +2 -1
  127. package/dist/serializers/index.d.ts +2 -1
  128. package/dist/serializers/index.js +3 -2
  129. package/dist/sourcemap-C8AH3MBQ.d.cts +91 -0
  130. package/dist/sourcemap-DA1Evhrv.d.ts +91 -0
  131. package/dist/spreadsheet/index.cjs +37 -3
  132. package/dist/spreadsheet/index.cjs.map +1 -1
  133. package/dist/spreadsheet/index.d.cts +188 -17
  134. package/dist/spreadsheet/index.d.ts +188 -17
  135. package/dist/spreadsheet/index.js +43 -9
  136. package/dist/{tokens-CyLZmIei.d.cts → tokens-D7yXvUU6.d.cts} +15 -2
  137. package/dist/{tokens-CyLZmIei.d.ts → tokens-D7yXvUU6.d.ts} +15 -2
  138. package/dist/{track-changes-BSF58RK0.d.ts → track-changes-BK5sVf4_.d.cts} +18 -136
  139. package/dist/{track-changes-BSF58RK0.d.cts → track-changes-CDjCrwKe.d.ts} +18 -136
  140. package/package.json +16 -1
  141. package/dist/chunk-4SUNJZWB.cjs.map +0 -1
  142. package/dist/chunk-AA4ZEVCC.cjs.map +0 -1
  143. package/dist/chunk-AXV2ZW34.cjs +0 -118
  144. package/dist/chunk-AXV2ZW34.cjs.map +0 -1
  145. package/dist/chunk-B2ZRLN4S.js +0 -118
  146. package/dist/chunk-B2ZRLN4S.js.map +0 -1
  147. package/dist/chunk-GVSMRPHB.cjs.map +0 -1
  148. package/dist/chunk-K3R5NG2D.js.map +0 -1
  149. package/dist/chunk-MJZBNWG7.js.map +0 -1
  150. package/dist/chunk-OYXSKQFR.js.map +0 -1
  151. package/dist/chunk-QBJ22YZR.js.map +0 -1
  152. package/dist/chunk-QGHGJ56O.js.map +0 -1
  153. package/dist/chunk-RIKBJLS2.cjs.map +0 -1
  154. package/dist/chunk-XDMXXC4Z.cjs.map +0 -1
  155. /package/dist/{chunk-JJDLPEWL.js.map → chunk-3LV6RRPH.js.map} +0 -0
@@ -1,3 +1,55 @@
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';
3
+ import '../schema-DYDGdYL9.js';
4
+
5
+ /**
6
+ * Photoshop blend modes on straight (non-premultiplied) 0..1 colours.
7
+ *
8
+ * Formulas follow the W3C Compositing / ISO 32000 definitions, with Photoshop's variants where
9
+ * they differ (Soft Light, Vivid / Linear / Pin Light, Hard Mix, Linear Burn / Dodge, Subtract,
10
+ * Divide, Darker / Lighter Color), and the hardened `ClipColor` for the non-separable modes.
11
+ */
12
+ type BlendMode = 'normal' | 'darken' | 'multiply' | 'color-burn' | 'linear-burn' | 'darker-color' | 'lighten' | 'screen' | 'color-dodge' | 'linear-dodge' | 'lighter-color' | 'overlay' | 'soft-light' | 'hard-light' | 'vivid-light' | 'linear-light' | 'pin-light' | 'hard-mix' | 'difference' | 'exclusion' | 'subtract' | 'divide' | 'hue' | 'saturation' | 'color' | 'luminosity';
13
+ interface BlendModeInfo {
14
+ id: BlendMode;
15
+ label: string;
16
+ /** Canvas `globalCompositeOperation` with the same maths, when there is one. */
17
+ canvas: GlobalCompositeOperation | null;
18
+ }
19
+ /** Every blend mode, in Photoshop's menu order. */
20
+ declare const BLEND_MODES: readonly BlendModeInfo[];
21
+ declare function isBlendMode(value: unknown): value is BlendMode;
22
+ /** A stored blend mode, or `normal` for a missing / unknown value. */
23
+ declare function normalizeBlendMode(value: unknown): BlendMode;
24
+ /**
25
+ * The canvas composite operation that implements `mode` exactly, or `null` when the canvas has
26
+ * none (draw through {@link blendImageData} instead).
27
+ */
28
+ declare function canvasCompositeOperation(mode: BlendMode | undefined): GlobalCompositeOperation | null;
29
+ /** Whether a mode works on whole colours (hue, saturation, colour, luminosity, darker / lighter colour). */
30
+ declare function isSeparableBlendMode(mode: BlendMode): boolean;
31
+ /** Separable blend function `B(cb, cs)` of one channel. Non-separable modes return `cs`. */
32
+ declare function blendChannel(mode: BlendMode, cb: number, cs: number): number;
33
+ type Rgb$1 = [number, number, number];
34
+ type Rgba = [number, number, number, number];
35
+ /** Luminosity of the non-separable modes (W3C / ISO 32000 weights). */
36
+ declare function blendLum(c: readonly number[]): number;
37
+ /** `c` with its luminosity moved to `l`, clipped back into gamut towards grey (SetLum + ClipColor). */
38
+ declare function setLum(c: readonly number[], l: number): Rgb$1;
39
+ /** `B(Cb, Cs)` of a whole colour, including the non-separable modes. */
40
+ declare function blendRgb(mode: BlendMode, cb: readonly number[], cs: readonly number[]): Rgb$1;
41
+ /**
42
+ * Composites a straight-alpha `source` over a straight-alpha `backdrop` (both RGBA in 0..1) with a
43
+ * blend mode and an extra `alpha` (opacity), using the W3C general formula:
44
+ * `αo = αs + αb(1 − αs)`, `αo·Co = (1 − αs)·αb·Cb + (1 − αb)·αs·Cs + αs·αb·B(Cb, Cs)`.
45
+ */
46
+ declare function blendPixel(mode: BlendMode, backdrop: readonly number[], source: readonly number[], alpha?: number): Rgba;
47
+ /**
48
+ * Blends `source` into `backdrop` in place (8-bit straight RGBA of the same size) with
49
+ * {@link blendPixel}. The scalar fallback for modes the canvas cannot composite.
50
+ */
51
+ declare function blendImageData(backdrop: ImageData, source: ImageData, mode: BlendMode, alpha?: number): void;
52
+
1
53
  interface ImageDimensions {
2
54
  width: number;
3
55
  height: number;
@@ -38,7 +90,136 @@ interface ImageAdjustments {
38
90
  * versions existed look exactly as they did. See `normalizeProcessVersion`.
39
91
  */
40
92
  process?: 1 | 2;
93
+ /**
94
+ * Non-destructive adjustment layers, evaluated bottom (first) to top (last) after the base
95
+ * adjustments above, on the encoded sRGB result. Missing or empty: no layers (edits saved
96
+ * before layers existed render exactly as before).
97
+ */
98
+ layers?: AdjustmentLayer[];
99
+ }
100
+ type AdjustmentKind = 'curves' | 'levels' | 'hueSaturation' | 'vibrance' | 'colorBalance' | 'blackWhite' | 'invert' | 'posterize' | 'threshold' | 'photoFilter';
101
+ /** A Curves point; `input` and `output` are levels, 0..255. */
102
+ interface CurvePoint {
103
+ input: number;
104
+ output: number;
105
+ }
106
+ /** Curves: each channel's curve first, then the master (composite) curve, as in Photoshop. */
107
+ interface CurvesParams {
108
+ master: CurvePoint[];
109
+ red: CurvePoint[];
110
+ green: CurvePoint[];
111
+ blue: CurvePoint[];
112
+ }
113
+ /** One Levels record. Black / white points are levels (0..255); `gamma` is the midtone slider (0.1..9.99). */
114
+ interface LevelsChannel {
115
+ inBlack: number;
116
+ inWhite: number;
117
+ gamma: number;
118
+ outBlack: number;
119
+ outWhite: number;
120
+ }
121
+ /** Levels: each channel's record first, then the master record, as in Photoshop. */
122
+ interface LevelsParams {
123
+ master: LevelsChannel;
124
+ red: LevelsChannel;
125
+ green: LevelsChannel;
126
+ blue: LevelsChannel;
127
+ }
128
+ /** One of Hue/Saturation's six colour ranges (reds, yellows, greens, cyans, blues, magentas). */
129
+ interface HueRange {
130
+ /** Hue shift in degrees (-180..180). */
131
+ hue: number;
132
+ /** Saturation change in percent (-100..100). */
133
+ saturation: number;
134
+ /** Lightness change in percent (-100..100). */
135
+ lightness: number;
136
+ /** Hue degrees where the range starts fading in, is fully on, starts fading out and ends (may wrap). */
137
+ bounds: [number, number, number, number];
138
+ }
139
+ interface HueSaturationParams {
140
+ /** Master hue shift in degrees (-180..180), or the hue when colorizing (0..360). */
141
+ hue: number;
142
+ /** Percent, -100..100 (0..100 when colorizing). */
143
+ saturation: number;
144
+ /** Percent, -100..100. */
145
+ lightness: number;
146
+ colorize: boolean;
147
+ /** Six ranges: reds, yellows, greens, cyans, blues, magentas. */
148
+ ranges: HueRange[];
149
+ }
150
+ interface VibranceParams {
151
+ /** -100..100 */
152
+ vibrance: number;
153
+ /** -100..100 */
154
+ saturation: number;
155
+ }
156
+ /** Cyan–red, magenta–green, yellow–blue sliders, -100..100 each. */
157
+ type ColorBalanceTone = [number, number, number];
158
+ interface ColorBalanceParams {
159
+ shadows: ColorBalanceTone;
160
+ midtones: ColorBalanceTone;
161
+ highlights: ColorBalanceTone;
162
+ preserveLuminosity: boolean;
163
+ }
164
+ /** Black & White: percent weights of the six colours (Photoshop defaults 40 60 40 60 20 80). */
165
+ interface BlackWhiteParams {
166
+ reds: number;
167
+ yellows: number;
168
+ greens: number;
169
+ cyans: number;
170
+ blues: number;
171
+ magentas: number;
172
+ /** Tint colour (`#rrggbb`), applied like the Color blend mode, or `null` for none. */
173
+ tint: string | null;
174
+ }
175
+ interface PhotoFilterParams {
176
+ /** Filter colour, `#rrggbb`. */
177
+ color: string;
178
+ /** Percent, 0..100. */
179
+ density: number;
180
+ preserveLuminosity: boolean;
181
+ }
182
+ interface PosterizeParams {
183
+ /** 2..255 */
184
+ levels: number;
185
+ }
186
+ interface ThresholdParams {
187
+ /** 1..255: luma at or above it becomes white. */
188
+ level: number;
189
+ }
190
+ type InvertParams = Record<string, never>;
191
+ interface AdjustmentParamsMap {
192
+ curves: CurvesParams;
193
+ levels: LevelsParams;
194
+ hueSaturation: HueSaturationParams;
195
+ vibrance: VibranceParams;
196
+ colorBalance: ColorBalanceParams;
197
+ blackWhite: BlackWhiteParams;
198
+ invert: InvertParams;
199
+ posterize: PosterizeParams;
200
+ threshold: ThresholdParams;
201
+ photoFilter: PhotoFilterParams;
41
202
  }
203
+ interface AdjustmentLayerBase {
204
+ id: string;
205
+ /** Optional display name. */
206
+ name?: string;
207
+ enabled: boolean;
208
+ /** 0..1 */
209
+ opacity: number;
210
+ /** How the adjusted colour is blended over the layers below. */
211
+ blend: BlendMode;
212
+ }
213
+ /** A non-destructive adjustment layer (Photoshop's Layer › New Adjustment Layer). */
214
+ type AdjustmentLayer = {
215
+ [K in AdjustmentKind]: AdjustmentLayerBase & {
216
+ kind: K;
217
+ params: AdjustmentParamsMap[K];
218
+ };
219
+ }[AdjustmentKind];
220
+ type AdjustmentLayerOf<K extends AdjustmentKind> = Extract<AdjustmentLayer, {
221
+ kind: K;
222
+ }>;
42
223
  interface DepthMaskOptions {
43
224
  enabled: boolean;
44
225
  maskSource: string | null;
@@ -55,6 +236,8 @@ interface BaseAnnotation {
55
236
  y: number;
56
237
  rotation?: number;
57
238
  opacity?: number;
239
+ /** Blend mode the annotation is drawn with (default `normal`). */
240
+ blend?: BlendMode;
58
241
  }
59
242
  interface PenAnnotation extends BaseAnnotation {
60
243
  type: 'pen';
@@ -125,7 +308,11 @@ interface ImageEditorState {
125
308
  isOriginalCompared: boolean;
126
309
  }
127
310
  interface SerializedImageEditorState {
128
- version: 1;
311
+ /**
312
+ * Schema version. `2` adds `adjustments.layers`; states without layers are still written as
313
+ * `1` so they round-trip unchanged. See `migrateSerializedImageEditorState`.
314
+ */
315
+ version: 1 | 2;
129
316
  crop: CropBox | null;
130
317
  transform: ImageTransform;
131
318
  adjustments: ImageAdjustments;
@@ -163,7 +350,7 @@ interface ImageEditorAIHooks {
163
350
 
164
351
  /**
165
352
  * Applies color and tone adjustments (brightness, contrast, saturation, exposure, temperature, tint,
166
- * opacity, blur) directly to the pixel data of an ImageData buffer.
353
+ * opacity, then any adjustment `layers`, then blur) directly to the pixel data of an ImageData buffer.
167
354
  *
168
355
  * `adjustments.process` selects the rendering: `2` is the linear-light pipeline
169
356
  * ({@link applyProcess2Adjustments}); anything else (including a missing value, as in edits saved
@@ -304,6 +491,47 @@ declare function buildToneLut(contrast: number, brightness: number, headroom?: n
304
491
  /** Linearly interpolated lookup into a LUT from {@link buildToneLut}. */
305
492
  declare function sampleToneLut(lut: Float32Array, headroom: number, y: number): number;
306
493
 
494
+ /** Display bins of a histogram. */
495
+ declare const HISTOGRAM_BINS = 256;
496
+ interface ImageHistogram {
497
+ /** 256-bin counts per channel. */
498
+ red: Uint32Array;
499
+ green: Uint32Array;
500
+ blue: Uint32Array;
501
+ /** 256-bin counts of Rec.709 luma `round(0.2126 R + 0.7152 G + 0.0722 B)` of the encoded values. */
502
+ luminance: Uint32Array;
503
+ /** Visible pixels counted (alpha > 0). Each counts once, partially transparent ones included. */
504
+ samples: number;
505
+ /** Fully transparent pixels, excluded from every bin. */
506
+ transparent: number;
507
+ /** Per channel (R, G, B): visible pixels at exactly 0. */
508
+ shadows: [number, number, number];
509
+ /** Per channel (R, G, B): visible pixels at exactly 255. */
510
+ highlights: [number, number, number];
511
+ /** Largest bin count over R, G, B and luminance (for scaling a plot). */
512
+ max: number;
513
+ }
514
+ interface PixelSource {
515
+ data: ArrayLike<number>;
516
+ width?: number;
517
+ height?: number;
518
+ }
519
+ /**
520
+ * Per-channel and luminance histograms of straight 8-bit RGBA pixels (an `ImageData` or anything
521
+ * with `data`), with clipping counts at the exact endpoints. Transparent pixels cannot add
522
+ * phantom peaks: they are counted separately and excluded.
523
+ */
524
+ declare function computeHistogram(imageData: PixelSource): ImageHistogram;
525
+ type HistogramChannel = 'red' | 'green' | 'blue' | 'luminance';
526
+ /**
527
+ * An SVG path (`M … Z`) of one channel scaled into a `width` × `height` box, bins left to right,
528
+ * counts up from the bottom. `scale: 'sqrt'` (default) keeps small populations visible.
529
+ */
530
+ declare function histogramPath(histogram: ImageHistogram, channel: HistogramChannel, width: number, height: number, options?: {
531
+ scale?: 'linear' | 'sqrt';
532
+ max?: number;
533
+ }): string;
534
+
307
535
  interface RenderOptions {
308
536
  viewportWidth?: number;
309
537
  viewportHeight?: number;
@@ -331,6 +559,13 @@ declare class ImageEditorRenderer {
331
559
  imageCache: ImageCache;
332
560
  private cachedBaseCanvas;
333
561
  private cachedBaseKey;
562
+ /**
563
+ * Histogram of the last viewport base render (after adjustments and layers, before
564
+ * annotations); `null` until a render with pixel access has happened.
565
+ */
566
+ previewHistogram: ImageHistogram | null;
567
+ /** Called whenever the viewport base image is re-rendered with the new histogram. */
568
+ onPreviewHistogram?: (histogram: ImageHistogram | null) => void;
334
569
  private sourceIds;
335
570
  private nextSourceId;
336
571
  /**
@@ -351,6 +586,14 @@ declare class ImageEditorRenderer {
351
586
  * Draws an individual annotation onto the canvas.
352
587
  */
353
588
  drawAnnotation(ctx: CanvasRenderingContext2D, ann: Annotation): Promise<void>;
589
+ /**
590
+ * Scalar fallback for blend modes the canvas cannot composite (Photoshop soft light, linear /
591
+ * vivid / pin light, hard mix, subtract, divide, darker / lighter colour, linear burn / dodge):
592
+ * draws the annotation on a same-size layer with the same transform, blends it into a copy of
593
+ * the target's pixels with `blendImageData`, and copies the result back inside the current clip.
594
+ */
595
+ private drawAnnotationBlended;
596
+ private drawAnnotationContent;
354
597
  /**
355
598
  * Draws selection box around active annotation.
356
599
  */
@@ -384,12 +627,35 @@ declare class ImageEditorRenderer {
384
627
  private drawAnnotationMask;
385
628
  }
386
629
 
630
+ /** Latest serialized schema version (`2`: adjustment layers). */
631
+ declare const IMAGE_EDITOR_SCHEMA_VERSION: 2;
632
+ /** Changes to an adjustment layer; `params` is merged into the current parameters. */
633
+ interface AdjustmentLayerUpdate<K extends AdjustmentKind = AdjustmentKind> {
634
+ params?: Partial<AdjustmentParamsMap[K]>;
635
+ enabled?: boolean;
636
+ opacity?: number;
637
+ blend?: BlendMode;
638
+ name?: string;
639
+ }
640
+ /** A new adjustment layer: its kind plus optional initial values. */
641
+ interface AdjustmentLayerInit<K extends AdjustmentKind = AdjustmentKind> extends AdjustmentLayerUpdate<K> {
642
+ kind: K;
643
+ id?: string;
644
+ }
387
645
  declare const DEFAULT_ADJUSTMENTS: ImageAdjustments;
388
646
  /**
389
647
  * Fills in defaults for stored adjustments. A stored object without `process` was saved before
390
648
  * process versions existed and keeps the legacy rendering.
391
649
  */
392
650
  declare function normalizeStoredAdjustments(stored: Partial<ImageAdjustments> | undefined | null): ImageAdjustments;
651
+ /**
652
+ * Brings a stored editor state of any schema version to the current shape. Version 1 (and a
653
+ * missing version) has no adjustment layers; everything else is unchanged, so old states load
654
+ * and render exactly as before.
655
+ */
656
+ declare function migrateSerializedImageEditorState(data: Partial<SerializedImageEditorState> & {
657
+ version?: number;
658
+ }): SerializedImageEditorState;
393
659
  declare const DEFAULT_TRANSFORM: ImageTransform;
394
660
  declare const DEFAULT_DEPTH_MASK: DepthMaskOptions;
395
661
  /**
@@ -401,6 +667,7 @@ declare class ImageEditorController {
401
667
  private renderer;
402
668
  private imageElement;
403
669
  private listeners;
670
+ private histogramListeners;
404
671
  private onStateChange?;
405
672
  private undoStack;
406
673
  private redoStack;
@@ -443,7 +710,38 @@ declare class ImageEditorController {
443
710
  * rendering process (one undo step). Returns false when already current.
444
711
  */
445
712
  upgradeProcess(): boolean;
713
+ /** Resets the base sliders (latest process). Adjustment layers are kept; see `clearAdjustmentLayers`. */
446
714
  resetAdjustments(): void;
715
+ /** The adjustment layers, bottom (first) to top (last). */
716
+ getAdjustmentLayers(): AdjustmentLayer[];
717
+ getAdjustmentLayer(id: string): AdjustmentLayer | undefined;
718
+ private setLayers;
719
+ /**
720
+ * Adds an adjustment layer on top (or at `index`, 0 = bottom) as one undo step and returns
721
+ * its id. `kind` alone gives neutral parameters.
722
+ */
723
+ addAdjustmentLayer<K extends AdjustmentKind>(init: K | AdjustmentLayerInit<K>, index?: number): string;
724
+ /**
725
+ * Updates a layer (`params` merged into the current ones, then normalised). Pass
726
+ * `commitToHistory = false` for the moves of a drag after recording its start once.
727
+ * Returns false for an unknown id.
728
+ */
729
+ updateAdjustmentLayer(id: string, update: AdjustmentLayerUpdate, commitToHistory?: boolean): boolean;
730
+ /** Removes a layer as one undo step. Returns false for an unknown id. */
731
+ removeAdjustmentLayer(id: string): boolean;
732
+ /** Moves a layer to `toIndex` (0 = bottom) as one undo step. Returns false if nothing moved. */
733
+ moveAdjustmentLayer(id: string, toIndex: number): boolean;
734
+ /** Shows or hides a layer (flips it without `enabled`) as one undo step. */
735
+ toggleAdjustmentLayer(id: string, enabled?: boolean): boolean;
736
+ /** Removes every adjustment layer as one undo step. */
737
+ clearAdjustmentLayers(): void;
738
+ /**
739
+ * Histogram of the last rendered preview (after adjustments and layers, before annotations),
740
+ * or `null` before the first render or without canvas pixel access.
741
+ */
742
+ getHistogram(): ImageHistogram | null;
743
+ /** Calls `listener` now and whenever a render produces a new preview histogram. */
744
+ subscribeHistogram(listener: (histogram: ImageHistogram | null) => void): () => void;
447
745
  setDepthMask(partial: Partial<DepthMaskOptions>): void;
448
746
  resetDepthMask(): void;
449
747
  addAnnotation(annotation: CreateAnnotationPayload): string;
@@ -616,4 +914,293 @@ declare function getAnnotationBounds(ann: Annotation): {
616
914
  */
617
915
  declare function hitTestAnnotation(imgPt: ImagePoint, ann: Annotation, padding?: number): boolean;
618
916
 
619
- export { AS_SHOT_KELVIN, type Annotation, type AnnotationType, type ArrowAnnotation, type AspectRatio, type BaseAnnotation, type Chromaticity, type CircleAnnotation, type CreateAnnotationPayload, type CropBox, type CropHandle, D65, DEFAULT_ADJUSTMENTS, DEFAULT_DEPTH_MASK, DEFAULT_TRANSFORM, type DepthMaskOptions, type ExportOptions, IDENTITY_MATRIX3, type ImageAdjustments, type ImageAnnotation, type ImageDimensions, type ImageEditorAIHooks, ImageEditorController, type ImageEditorOptions, ImageEditorRenderer, type ImageEditorState, type ImageEditorTool, type ImagePoint, type ImageProcessVersion, type ImageProjection, type ImageTransform, type InpaintHook, type InpaintOptions, LATEST_PROCESS_VERSION, LEGACY_PROCESS_VERSION, LUMA_709, type LineAnnotation, MAX_KELVIN, MIN_KELVIN, MIRED_PER_TEMPERATURE_UNIT, type Matrix3, type PenAnnotation, type RectAnnotation, type RemoveBackgroundHook, type RemoveBackgroundOptions, type RenderOptions, type SerializedImageEditorState, TINT_SCALE, TONE_LUT_SIZE, type TextAnnotation, type ViewportMetrics, applyAdjustments, applyDepthMask, applyImageProjectionToContext, applyLegacyAdjustments, applyMatrix3, applyProcess2Adjustments, bradfordAdaptation, buildToneLut, calculateCropDrag, canvasToImagePoint, clampCropToImage, getAnnotationBounds, getCropCursor, getRotatedSize, getViewportMetrics, getViewportProjection, globalImageCache, hitTestAnnotation, hitTestCrop, imageToCanvasPoint, invertMatrix3, isQuarterTurnSwapped, kelvinToTemperature, linearSrgbToXy, linearToSrgb, mapCropHandle, mulMatrix3, normalizeAngle, normalizeProcessVersion, normalizeStoredAdjustments, projectImagePoint, projectImageRect, removeAlpha, sampleToneLut, srgbToLinear, tempTintToXy, temperatureToKelvin, toneCurve, unprojectCanvasPoint, uvToXy, wbMatrix, whiteBalanceFromSample, whiteBalanceMatrix, xyToTempTint, xyToUv };
917
+ /** The `version` that `ImageEditorController.toJSON()` writes. */
918
+ declare const IMAGE_EDITOR_STATE_VERSION = 1;
919
+ /**
920
+ * Migration steps for `SerializedImageEditorState`, keyed by the version they
921
+ * start from. Empty while only version 1 exists.
922
+ */
923
+ declare const imageEditorStateMigrations: Record<number, MigrationStep>;
924
+ interface ImageEditorDocumentLoad {
925
+ /** State to pass to `loadJSON` / `initialState`. */
926
+ state: SerializedImageEditorState;
927
+ report: LoadReport;
928
+ /** Top-level keys this build does not know; spread them into the saved JSON to keep them. */
929
+ unknown: JsonObject;
930
+ }
931
+ /**
932
+ * Loads stored image editor state (a JSON string or object) with a `LoadReport`:
933
+ *
934
+ * - Runs `imageEditorStateMigrations` up to `IMAGE_EDITOR_STATE_VERSION`; a missing
935
+ * `version` is taken as current.
936
+ * - A newer `version` is still loaded but reported `readOnly`: do not save over it.
937
+ * - Each section (`crop`, `transform`, `adjustments`, `depthMask`, `annotations`)
938
+ * falls back to its default on its own; invalid annotations are dropped one by one.
939
+ * - Unknown top-level keys are returned in `unknown`.
940
+ *
941
+ * Valid state from `toJSON()` comes back unchanged, so `loadJSON(state)` behaves
942
+ * exactly as with the raw object.
943
+ */
944
+ declare function loadImageEditorDocument(input: unknown): ImageEditorDocumentLoad;
945
+
946
+ /**
947
+ * Adjustment layers: Photoshop-matching evaluation on encoded sRGB colours in 0..1.
948
+ *
949
+ * Every layer is compiled once per parameter change into a per-pixel function (per-channel kinds
950
+ * into three 4096-entry LUTs); {@link applyAdjustmentLayers} runs the stack on an ImageData.
951
+ */
952
+ type Rgb = [number, number, number];
953
+ /** Entries in a tone LUT (curves, levels, colour balance). */
954
+ declare const ADJUSTMENT_LUT_SIZE = 4096;
955
+ /** Linear interpolation into a 0..1-domain LUT. */
956
+ declare function sampleLut(table: ArrayLike<number>, v: number): number;
957
+ interface AdjustmentKindInfo {
958
+ kind: AdjustmentKind;
959
+ label: string;
960
+ }
961
+ declare const ADJUSTMENT_KINDS: readonly AdjustmentKindInfo[];
962
+ declare function isAdjustmentKind(value: unknown): value is AdjustmentKind;
963
+ declare function adjustmentKindLabel(kind: AdjustmentKind): string;
964
+ declare const HUE_RANGE_LABELS: readonly ["Reds", "Yellows", "Greens", "Cyans", "Blues", "Magentas"];
965
+ /** The neutral range `i` (0 reds … 5 magentas): fully on for 30° around its centre, fading over 30° each side. */
966
+ declare function neutralHueRange(i: number): HueRange;
967
+ declare const identityCurve: () => CurvePoint[];
968
+ declare const identityLevels: () => LevelsChannel;
969
+ /** Neutral parameters of every kind (fresh objects on every call). */
970
+ declare function defaultAdjustmentParams<K extends AdjustmentKind>(kind: K): AdjustmentParamsMap[K];
971
+ /** A new layer of `kind` with neutral (or the given) parameters, enabled, opacity 1, normal blend. */
972
+ declare function createAdjustmentLayer<K extends AdjustmentKind>(kind: K, options?: {
973
+ id?: string;
974
+ name?: string;
975
+ params?: Partial<AdjustmentParamsMap[K]>;
976
+ enabled?: boolean;
977
+ opacity?: number;
978
+ blend?: BlendMode;
979
+ }): AdjustmentLayerOf<K>;
980
+ /**
981
+ * A clean, deep-copied layer from stored or hand-written data: missing fields get neutral
982
+ * defaults, numbers are clamped to their ranges. `null` for an unknown kind.
983
+ */
984
+ declare function normalizeAdjustmentLayer(raw: unknown): AdjustmentLayer | null;
985
+ /** Normalises a stored layer list (drops unknown kinds, de-duplicates ids). */
986
+ declare function normalizeAdjustmentLayers(raw: unknown): AdjustmentLayer[];
987
+ /**
988
+ * Photoshop curve: a natural cubic spline through the points (0..1 in and out; it may overshoot
989
+ * between points, as Photoshop's does), constant outside the first / last point, clamped to
990
+ * 0..1, sampled into a LUT. Fewer than two distinct points: the identity.
991
+ */
992
+ declare function curveLut(points: ReadonlyArray<{
993
+ input: number;
994
+ output: number;
995
+ }>, size?: number): Float32Array;
996
+ /** {@link curveLut} for Curves points in levels (0..255). */
997
+ declare function curveLutFromLevels(points: readonly CurvePoint[]): Float32Array;
998
+ /** A Levels record with values in 0..1 (as `levelsValue` takes them). */
999
+ interface UnitLevels {
1000
+ inBlack: number;
1001
+ inWhite: number;
1002
+ gamma: number;
1003
+ outBlack: number;
1004
+ outWhite: number;
1005
+ }
1006
+ /**
1007
+ * One Levels record on `v` (0..1). With `quantum` (8-bit: 255) Photoshop works on whole levels:
1008
+ * the input is a level and the stretch is rounded (half up) before the gamma. A gamma above 1 has
1009
+ * Photoshop's soft shadow toe: a p-norm soft-min of the power curve and a line of slope ≈ 2^gamma.
1010
+ */
1011
+ declare function levelsValue(ch: UnitLevels, v: number, quantum?: number): number;
1012
+ /** RGB (0..1) → HSL with hue in turns (0..1). */
1013
+ declare function rgbToHsl(c: readonly number[]): [number, number, number];
1014
+ declare function hslToRgb(h: number, s: number, l: number): Rgb;
1015
+ /** How much a pixel of hue `deg` belongs to `range` (0..1): a trapezoid that may wrap past 0/360. */
1016
+ declare function hueRangeWeight(range: Pick<HueRange, 'bounds'>, deg: number): number;
1017
+ /** Range edits as three hue-indexed tables (hue shift in degrees, saturation and lightness as fractions). */
1018
+ declare function hueRangeTables(ranges: readonly HueRange[]): [Float32Array, Float32Array, Float32Array];
1019
+ /**
1020
+ * One Hue/Saturation evaluation: hue shift in degrees, saturation and lightness in -1..1.
1021
+ * Lightness first, then hue and saturation (raising divides by 1 − s, lowering multiplies by
1022
+ * 1 + s). Colorize sets hue and saturation at the lightened lightness.
1023
+ */
1024
+ declare function hueSaturation(c: readonly number[], hue: number, s: number, l: number, colorize: boolean): Rgb;
1025
+ /** A colour range's Lightness: towards the brightest channel when raised, the darkest when lowered. */
1026
+ declare function rangeLightness(c: readonly number[], l: number): Rgb;
1027
+ /** Grey Vibrance › Saturation desaturates to (linear light; blue has no weight). */
1028
+ declare const VIBRANCE_GREY: readonly [number, number];
1029
+ /** The Vibrance slider (`v` in -1..1) on a linear-light pixel: an HSV change that keeps the hue. */
1030
+ declare function vibranceLinear(c: Rgb, v: number): Rgb;
1031
+ /** Photoshop's Vibrance on one encoded sRGB pixel (`v`, `s`: the sliders / 100). */
1032
+ declare function vibrancePixel(c: readonly number[], v: number, s: number): Rgb;
1033
+ /**
1034
+ * Color Balance on channel `ch` (0 red, 1 green, 2 blue) of `v` (0..1); `tones` are the
1035
+ * shadows, midtones and highlights slider triples (-100..100). Highlights, shadows, then midtones.
1036
+ */
1037
+ declare function colorBalanceChannel(tones: readonly [readonly number[], readonly number[], readonly number[]], preserveLuminosity: boolean, ch: number, v: number): number;
1038
+ /**
1039
+ * Black & White grey: the smallest channel, plus the secondary part (middle − smallest) and the
1040
+ * primary part (largest − middle) weighted by the sliders (percent: reds, yellows, greens, cyans,
1041
+ * blues, magentas).
1042
+ */
1043
+ declare function blackWhiteGray(c: readonly number[], weights: readonly number[]): number;
1044
+ /**
1045
+ * Photo Filter's linear-light RGB matrix (row-major 3×3): the pixel's D50 XYZ, relative to white,
1046
+ * multiplied by the filter colour's mixed in by `density` (0..1). `normalizeY` keeps luminance Y.
1047
+ */
1048
+ declare function photoFilterMatrix(color: readonly number[], density: number, normalizeY?: boolean): number[][];
1049
+ /** Photoshop posterize: `levels` equal input bins over 0..255, outputs `floor(k·255 / (levels − 1))`. */
1050
+ declare function posterizeValue(v: number, levels: number): number;
1051
+ /** Rec.601 luma (Photoshop's grey for Threshold). */
1052
+ declare const rgbToGray: (c: readonly number[]) => number;
1053
+ /** `#rrggbb` → 0..1 RGB (black for anything else). */
1054
+ declare function hexToRgb(hex: string): Rgb;
1055
+ /** Mutates an encoded sRGB colour (0..1) in place. */
1056
+ type PixelOp = (c: Rgb) => void;
1057
+ /**
1058
+ * Per-channel LUTs of a Curves or Levels layer: each channel's record first, then the master.
1059
+ * `null` for any other kind.
1060
+ */
1061
+ declare function toneLuts(layer: AdjustmentLayer): [Float32Array, Float32Array, Float32Array] | null;
1062
+ /**
1063
+ * Compiles a layer into a pixel function, or `null` when it is the identity (neutral parameters).
1064
+ * Pure: depends on `kind` and `params` only.
1065
+ */
1066
+ declare function compileAdjustmentLayer(layer: AdjustmentLayer): PixelOp | null;
1067
+ /** Layers that change pixels: enabled, visible, not the identity. */
1068
+ declare function activeAdjustmentLayers(layers: readonly AdjustmentLayer[] | undefined): AdjustmentLayer[];
1069
+ /**
1070
+ * Evaluates one colour (encoded sRGB, 0..1) through a layer stack: each layer adjusts the result
1071
+ * of the layers below and is blended over it with its blend mode and opacity (an opaque
1072
+ * backdrop, so `(1 − α)·Cb + α·B(Cb, Cs)`).
1073
+ */
1074
+ declare function evaluateAdjustmentLayers(color: readonly number[], layers: readonly AdjustmentLayer[]): Rgb;
1075
+ /**
1076
+ * Applies an adjustment-layer stack to 8-bit straight RGBA pixels in place. Each pixel is
1077
+ * decoded once, run through every layer in float, and encoded once. Transparent pixels are
1078
+ * left alone; alpha is never changed.
1079
+ */
1080
+ declare function applyAdjustmentLayers(imageData: ImageData, layers: readonly AdjustmentLayer[] | undefined): void;
1081
+ /** Stable cache key of a layer stack's pixel effect (for renderer caches). */
1082
+ declare function adjustmentLayersKey(layers: readonly AdjustmentLayer[] | undefined): string;
1083
+
1084
+ /**
1085
+ * Control specs: one table describes every numeric adjustment slider (id, label, section, range,
1086
+ * default, step, display precision and track style). The React and Svelte panels render from it,
1087
+ * the agent tools expose it as a schema, and values are addressed by id.
1088
+ */
1089
+ type ControlSection = 'light' | 'color' | 'effects' | 'layer';
1090
+ /** How a slider track is drawn. */
1091
+ type ControlTrack =
1092
+ /** Plain track, fill from the minimum. */
1093
+ {
1094
+ kind: 'plain';
1095
+ }
1096
+ /** Zero in the middle. */
1097
+ | {
1098
+ kind: 'centered';
1099
+ }
1100
+ /** Blue → yellow (white-balance temperature). */
1101
+ | {
1102
+ kind: 'temp';
1103
+ }
1104
+ /** Green → magenta (tint). */
1105
+ | {
1106
+ kind: 'tint';
1107
+ }
1108
+ /** A two-colour gradient. */
1109
+ | {
1110
+ kind: 'gradient';
1111
+ from: string;
1112
+ to: string;
1113
+ }
1114
+ /** Full hue rainbow. */
1115
+ | {
1116
+ kind: 'rainbow';
1117
+ };
1118
+ interface ControlSpec {
1119
+ /** Dotted path of the value (`exposure`; inside a layer's params: `midtones.0`, `ranges.4.hue`). */
1120
+ id: string;
1121
+ label: string;
1122
+ section: ControlSection;
1123
+ min: number;
1124
+ max: number;
1125
+ step: number;
1126
+ default: number;
1127
+ /** Decimal places shown (after `displayScale`). */
1128
+ decimals: number;
1129
+ track: ControlTrack;
1130
+ /** Multiplier for display (opacity 0..1 shows as 0..100 %). */
1131
+ displayScale?: number;
1132
+ /** Unit suffix for display (`px`, `%`, `°`). */
1133
+ unit?: string;
1134
+ /** The rendering process the control needs (tint: process 2). */
1135
+ requiresProcess?: 1 | 2;
1136
+ }
1137
+ /** Every numeric base adjustment, in panel order. */
1138
+ declare const IMAGE_ADJUSTMENT_CONTROLS: readonly ControlSpec[];
1139
+ /**
1140
+ * Numeric parameters of each adjustment-layer kind, addressed inside `layer.params`. Curves points
1141
+ * and booleans / colours (colorize, preserve luminosity, tint, filter colour) are edited by the
1142
+ * dedicated controls, not sliders.
1143
+ */
1144
+ declare const ADJUSTMENT_LAYER_CONTROLS: Readonly<Record<AdjustmentKind, readonly ControlSpec[]>>;
1145
+ /** Opacity of any adjustment layer (0..1, shown as %). */
1146
+ declare const ADJUSTMENT_LAYER_OPACITY_CONTROL: ControlSpec;
1147
+ /** The base-adjustment control with this id. */
1148
+ declare function findAdjustmentControl(id: string): ControlSpec | undefined;
1149
+ /** The control of a layer parameter (`opacity` included). */
1150
+ declare function findLayerControl(kind: AdjustmentKind, id: string): ControlSpec | undefined;
1151
+ /** `v` clamped to the control's range and snapped to its step; non-finite values give the default. */
1152
+ declare function clampControlValue(spec: ControlSpec, v: unknown): number;
1153
+ /** A value as the slider shows it (`+12`, `35%`, `4px`). */
1154
+ declare function formatControlValue(spec: ControlSpec, v: number): string;
1155
+ /** Where `v` sits on the track, 0 (left) to 1 (right). */
1156
+ declare function controlPosition(spec: ControlSpec, v: number): number;
1157
+ /** CSS background for a control's track. */
1158
+ declare function controlTrackBackground(spec: ControlSpec): string | undefined;
1159
+ /** Reads a dotted path (`ranges.2.hue`) from an object. */
1160
+ declare function getControlPath(obj: unknown, path: string): unknown;
1161
+ /** A copy of `obj` with the dotted path set (arrays and objects along the path are cloned). */
1162
+ declare function setControlPath<T>(obj: T, path: string, value: unknown): T;
1163
+ /** The base adjustment values the control table describes. */
1164
+ declare function readAdjustmentControls(adjustments: ImageAdjustments): Record<string, number>;
1165
+
1166
+ interface ImageEditorToolProviderOptions {
1167
+ /** Provider id (unique per registry). Default `image-editor`. */
1168
+ id?: string;
1169
+ /** Always prefix tool names with `<namespace>__`. */
1170
+ namespace?: string;
1171
+ }
1172
+ /**
1173
+ * Agent tools for an image editor, for a `ToolRegistry`:
1174
+ *
1175
+ * - `get_adjustments`: base slider values (by control id), process version and adjustment layers.
1176
+ * - `list_controls`: the control table (ids, ranges, defaults, steps), layer kinds and blend modes.
1177
+ * - `set_adjustments {values, label}`: sets base controls (`exposure`) and layer parameters
1178
+ * (`layers.<id>.vibrance`, `layers.<id>.opacity`) in one undo step; values are clamped to the
1179
+ * control ranges and the applied values are echoed.
1180
+ * - `add_adjustment_layer {kind, params?, opacity?, blend?, name?}`.
1181
+ * - `render_preview {maxSide}`: the rendered image as a PNG, longest side at most `maxSide`.
1182
+ */
1183
+ declare function createImageEditorToolProvider(controller: ImageEditorController, options?: ImageEditorToolProviderOptions): AgentToolProvider;
1184
+
1185
+ /** Box coordinates of a curve point. */
1186
+ declare function curvePointToBox(p: CurvePoint, width: number, height: number): {
1187
+ x: number;
1188
+ y: number;
1189
+ };
1190
+ /** The curve point (whole levels, clamped) under box coordinates. */
1191
+ declare function boxToCurvePoint(x: number, y: number, width: number, height: number): CurvePoint;
1192
+ /** An SVG polyline path of the evaluated curve (spline, clamped, constant beyond the end points). */
1193
+ declare function curveSvgPath(points: readonly CurvePoint[], width: number, height: number, samples?: number): string;
1194
+ /** Index of the point within `radius` box units of (x, y), nearest first; -1 for none. */
1195
+ declare function hitTestCurvePoint(points: readonly CurvePoint[], x: number, y: number, width: number, height: number, radius?: number): number;
1196
+ /** Inserts a point in input order (replacing one at the same input). Returns the new list and its index. */
1197
+ declare function insertCurvePoint(points: readonly CurvePoint[], p: CurvePoint): {
1198
+ points: CurvePoint[];
1199
+ index: number;
1200
+ };
1201
+ /** Moves point `index`, keeping its input strictly between its neighbours'. */
1202
+ declare function moveCurvePoint(points: readonly CurvePoint[], index: number, p: CurvePoint): CurvePoint[];
1203
+ /** Removes point `index`; a curve keeps at least two points. */
1204
+ declare function removeCurvePoint(points: readonly CurvePoint[], index: number): CurvePoint[];
1205
+
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 };