@pixerate/editor-react 0.76.0 → 0.78.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 (49) hide show
  1. package/dist/PaintGradientEditorView-CCPCY5Ib.d.cts +14 -0
  2. package/dist/PaintGradientEditorView-CCPCY5Ib.d.ts +14 -0
  3. package/dist/canvas/index.cjs +662 -561
  4. package/dist/canvas/index.cjs.map +1 -1
  5. package/dist/canvas/index.d.cts +36 -5
  6. package/dist/canvas/index.d.ts +36 -5
  7. package/dist/canvas/index.js +232 -129
  8. package/dist/canvas/index.js.map +1 -1
  9. package/dist/{chunk-LWMUV5TC.js → chunk-2EW42UXC.js} +639 -461
  10. package/dist/chunk-2EW42UXC.js.map +1 -0
  11. package/dist/chunk-FX3EREF5.js +206 -0
  12. package/dist/chunk-FX3EREF5.js.map +1 -0
  13. package/dist/chunk-MO354USR.js +126 -0
  14. package/dist/chunk-MO354USR.js.map +1 -0
  15. package/dist/chunk-ZQZAKUUM.js +416 -0
  16. package/dist/chunk-ZQZAKUUM.js.map +1 -0
  17. package/dist/effects/index.cjs +606 -0
  18. package/dist/effects/index.cjs.map +1 -0
  19. package/dist/effects/index.d.cts +80 -0
  20. package/dist/effects/index.d.ts +80 -0
  21. package/dist/effects/index.js +16 -0
  22. package/dist/effects/index.js.map +1 -0
  23. package/dist/image-editor/index.cjs +1388 -534
  24. package/dist/image-editor/index.cjs.map +1 -1
  25. package/dist/image-editor/index.d.cts +36 -3
  26. package/dist/image-editor/index.d.ts +36 -3
  27. package/dist/image-editor/index.js +10 -1
  28. package/dist/index.cjs +1806 -952
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.d.cts +4 -1
  31. package/dist/index.d.ts +4 -1
  32. package/dist/index.js +10 -1
  33. package/dist/index.js.map +1 -1
  34. package/dist/paint-editor/index.cjs +438 -289
  35. package/dist/paint-editor/index.cjs.map +1 -1
  36. package/dist/paint-editor/index.d.cts +8 -3
  37. package/dist/paint-editor/index.d.ts +8 -3
  38. package/dist/paint-editor/index.js +215 -187
  39. package/dist/paint-editor/index.js.map +1 -1
  40. package/dist/parameters/index.js +55 -439
  41. package/dist/parameters/index.js.map +1 -1
  42. package/dist/video-editor/index.cjs +732 -17
  43. package/dist/video-editor/index.cjs.map +1 -1
  44. package/dist/video-editor/index.d.cts +31 -3
  45. package/dist/video-editor/index.d.ts +31 -3
  46. package/dist/video-editor/index.js +184 -17
  47. package/dist/video-editor/index.js.map +1 -1
  48. package/package.json +8 -3
  49. package/dist/chunk-LWMUV5TC.js.map +0 -1
@@ -1,7 +1,18 @@
1
+ import {
2
+ EffectParameters,
3
+ EffectsBrowser,
4
+ useEffectDescription,
5
+ useEffects
6
+ } from "./chunk-FX3EREF5.js";
7
+ import {
8
+ PaintGradientEditorView
9
+ } from "./chunk-MO354USR.js";
10
+
1
11
  // src/image-editor/useImageEditor.ts
2
12
  import { useRef, useState, useEffect, useCallback, useMemo } from "react";
3
13
  import {
4
- ImageEditorController
14
+ ImageEditorController,
15
+ createImageEffectsToolProvider
5
16
  } from "@pixerate/editor/image-editor";
6
17
  function useImageEditor(options = {}) {
7
18
  const controllerRef = useRef(null);
@@ -157,9 +168,16 @@ function useImageEditor(options = {}) {
157
168
  [controller, state, historyTicks, histogram]
158
169
  );
159
170
  }
171
+ function useImageEffectsTools(registry, controller, options = {}) {
172
+ const { id, namespace, readOnly } = options;
173
+ useEffect(() => {
174
+ if (!registry) return;
175
+ return registry.register(createImageEffectsToolProvider(controller, { id, namespace, readOnly }));
176
+ }, [registry, controller, id, namespace, readOnly]);
177
+ }
160
178
 
161
179
  // src/image-editor/ImageEditor.tsx
162
- import React13, { useRef as useRef5, useEffect as useEffect11, useState as useState14, useCallback as useCallback2 } from "react";
180
+ import React14, { useRef as useRef5, useEffect as useEffect12, useState as useState15, useCallback as useCallback2 } from "react";
163
181
  import {
164
182
  canvasToImagePoint,
165
183
  hitTestCrop,
@@ -1264,8 +1282,139 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
1264
1282
  ] });
1265
1283
  };
1266
1284
 
1285
+ // src/image-editor/ImageProviderEffectsPanel.tsx
1286
+ import React6, { useEffect as useEffect6, useState as useState7 } from "react";
1287
+ import { findLayer } from "@pixerate/editor/image-editor";
1288
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
1289
+ var btn = "rounded border border-slate-700 px-1.5 py-0.5 text-[11px] text-slate-300 hover:text-white disabled:opacity-40";
1290
+ function Controls({
1291
+ provider,
1292
+ effect,
1293
+ name,
1294
+ values,
1295
+ onChange,
1296
+ onPreset
1297
+ }) {
1298
+ const { description, error } = useEffectDescription(provider, effect);
1299
+ if (!provider) return /* @__PURE__ */ jsxs7("p", { className: "text-[11px] text-slate-400", children: [
1300
+ 'No effects provider: "',
1301
+ name ?? effect,
1302
+ '" is kept but not drawn.'
1303
+ ] });
1304
+ if (error) return /* @__PURE__ */ jsx7("p", { className: "text-[11px] text-amber-400", children: error });
1305
+ if (!description) return /* @__PURE__ */ jsx7("p", { className: "text-[11px] text-slate-400", children: "Loading\u2026" });
1306
+ return /* @__PURE__ */ jsx7(EffectParameters, { description, values, onChange, onReset: (k) => onChange(k, description.defaults[k], null), onPreset });
1307
+ }
1308
+ function ImageProviderEffectsPanel({ controller, className = "" }) {
1309
+ const [, setTick] = useState7(0);
1310
+ useEffect6(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
1311
+ const [browse, setBrowse] = useState7(null);
1312
+ const [message, setMessage] = useState7(null);
1313
+ const [open, setOpen] = useState7(null);
1314
+ const provider = controller.effectsProvider;
1315
+ const state = controller.getState();
1316
+ const layer = state.activeLayerId ? findLayer(state.layers, state.activeLayerId)?.layer ?? null : null;
1317
+ const run = (work) => {
1318
+ setMessage(null);
1319
+ Promise.resolve().then(work).catch((e) => setMessage(e instanceof Error ? e.message : String(e)));
1320
+ };
1321
+ const drags = React6.useRef(/* @__PURE__ */ new Set());
1322
+ const commit = (gesture) => {
1323
+ if (gesture) {
1324
+ if (!drags.current.has(gesture)) {
1325
+ drags.current.add(gesture);
1326
+ return true;
1327
+ }
1328
+ return false;
1329
+ }
1330
+ return true;
1331
+ };
1332
+ const filters = layer?.type === "smart" ? (layer.smartFilters?.filters ?? []).filter((f) => f.kind === "effect") : [];
1333
+ const generator = layer?.type === "pixel" ? layer.generator : void 0;
1334
+ const canFilter = !!layer && layer.type !== "adjustment" && layer.type !== "annotation";
1335
+ return /* @__PURE__ */ jsxs7("section", { className: `flex flex-col gap-2 text-xs ${className}`, "aria-label": "Provider effects", "data-image-provider-effects": "", children: [
1336
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-1", children: [
1337
+ /* @__PURE__ */ jsx7("span", { className: "flex-1 font-semibold uppercase tracking-wider text-[11px] text-slate-200", children: "Effects" }),
1338
+ /* @__PURE__ */ jsx7("button", { type: "button", className: btn, disabled: !provider || !canFilter, "aria-pressed": browse === "filter", onClick: () => setBrowse(browse === "filter" ? null : "filter"), children: "Apply effect\u2026" }),
1339
+ /* @__PURE__ */ jsx7("button", { type: "button", className: btn, disabled: !provider, "aria-pressed": browse === "layer", onClick: () => setBrowse(browse === "layer" ? null : "layer"), children: "Effect layer\u2026" })
1340
+ ] }),
1341
+ !provider && /* @__PURE__ */ jsx7("p", { className: "text-[11px] text-slate-400", children: "No effects provider is registered. Effects in the document are kept." }),
1342
+ browse === "filter" && layer && /* @__PURE__ */ jsx7(EffectsBrowser, { provider, uses: ["filter"], title: "Filters", onPick: (e) => (setBrowse(null), run(() => controller.applyEffectFilter(layer.id, e.id))) }),
1343
+ browse === "layer" && /* @__PURE__ */ jsx7(EffectsBrowser, { provider, uses: ["generator", "overlay", "title"], title: "Generators and overlays", onPick: (e) => (setBrowse(null), run(() => controller.addEffectLayer(e.id))) }),
1344
+ generator && layer && /* @__PURE__ */ jsxs7("div", { className: "space-y-1", "data-effect-part": "generator", children: [
1345
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-1", children: [
1346
+ /* @__PURE__ */ jsx7("span", { className: "flex-1 font-medium text-slate-200", children: generator.name ?? generator.effect }),
1347
+ /* @__PURE__ */ jsx7("button", { type: "button", className: btn, title: "Keep the pixels as a plain layer", onClick: () => run(() => controller.rasterizeEffectLayer(layer.id)), children: "Rasterize" })
1348
+ ] }),
1349
+ /* @__PURE__ */ jsx7(
1350
+ Controls,
1351
+ {
1352
+ provider,
1353
+ effect: generator.effect,
1354
+ name: generator.name,
1355
+ values: generator.values,
1356
+ onChange: (k, v, gesture) => run(() => controller.updateEffectLayer(layer.id, { values: { [k]: v } }, commit(gesture))),
1357
+ onPreset: (values) => run(() => controller.updateEffectLayer(layer.id, { values }))
1358
+ }
1359
+ )
1360
+ ] }),
1361
+ filters.length > 0 && layer && /* @__PURE__ */ jsx7("ol", { className: "space-y-1", "data-effect-part": "filters", children: filters.map((f) => {
1362
+ const label = f.kind === "effect" ? f.name ?? f.effect : f.kind;
1363
+ const all = layer.smartFilters.filters;
1364
+ const index = all.indexOf(f);
1365
+ if (f.kind !== "effect") return null;
1366
+ return /* @__PURE__ */ jsxs7("li", { className: "rounded border border-slate-700 p-1", "data-smart-effect": f.id, children: [
1367
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-1", children: [
1368
+ /* @__PURE__ */ jsx7("input", { type: "checkbox", checked: f.enabled, "aria-label": `${label} on`, onChange: (e) => {
1369
+ const enabled = e.currentTarget.checked;
1370
+ run(() => controller.updateEffectFilter(layer.id, f.id, { enabled }));
1371
+ } }),
1372
+ /* @__PURE__ */ jsx7("button", { type: "button", className: "min-w-0 flex-1 truncate text-left text-slate-200", "aria-expanded": open === f.id, onClick: () => setOpen(open === f.id ? null : f.id), children: label }),
1373
+ /* @__PURE__ */ jsx7("button", { type: "button", className: btn, disabled: index === all.length - 1, "aria-label": "Move up", onClick: () => run(() => controller.updateEffectFilter(layer.id, f.id, { index: index + 1 })), children: "\u2191" }),
1374
+ /* @__PURE__ */ jsx7("button", { type: "button", className: btn, disabled: index === 0, "aria-label": "Move down", onClick: () => run(() => controller.updateEffectFilter(layer.id, f.id, { index: index - 1 })), children: "\u2193" }),
1375
+ /* @__PURE__ */ jsx7("button", { type: "button", className: btn, "aria-label": `Remove ${label}`, onClick: () => run(() => controller.removeSmartFilter(layer.id, f.id)), children: "\u2715" })
1376
+ ] }),
1377
+ open === f.id && /* @__PURE__ */ jsxs7("div", { className: "mt-1 space-y-2", children: [
1378
+ /* @__PURE__ */ jsxs7("label", { className: "flex items-center gap-1", children: [
1379
+ /* @__PURE__ */ jsx7("span", { className: "w-14 text-[11px] text-slate-300", children: "Opacity" }),
1380
+ /* @__PURE__ */ jsx7(
1381
+ "input",
1382
+ {
1383
+ type: "range",
1384
+ min: 0,
1385
+ max: 1,
1386
+ step: 0.01,
1387
+ className: "flex-1",
1388
+ value: f.opacity,
1389
+ "aria-label": `${label} opacity`,
1390
+ onChange: (e) => {
1391
+ const opacity = Number(e.currentTarget.value);
1392
+ run(() => controller.updateEffectFilter(layer.id, f.id, { opacity }));
1393
+ }
1394
+ }
1395
+ )
1396
+ ] }),
1397
+ /* @__PURE__ */ jsx7(
1398
+ Controls,
1399
+ {
1400
+ provider,
1401
+ effect: f.effect,
1402
+ name: f.name,
1403
+ values: f.values,
1404
+ onChange: (k, v, gesture) => run(() => controller.updateEffectFilter(layer.id, f.id, { values: { [k]: v } }, commit(gesture))),
1405
+ onPreset: (values) => run(() => controller.updateEffectFilter(layer.id, f.id, { values }))
1406
+ }
1407
+ )
1408
+ ] })
1409
+ ] }, f.id);
1410
+ }) }),
1411
+ !layer && /* @__PURE__ */ jsx7("p", { className: "text-[11px] text-slate-400", children: "Select a layer to apply effects to it." }),
1412
+ message && /* @__PURE__ */ jsx7("p", { role: "alert", className: "text-[11px] text-rose-400", children: message })
1413
+ ] });
1414
+ }
1415
+
1267
1416
  // src/image-editor/BrushOptionsBar.tsx
1268
- import { useEffect as useEffect6, useState as useState7 } from "react";
1417
+ import { useEffect as useEffect7, useState as useState8 } from "react";
1269
1418
  import {
1270
1419
  BRUSH_OPTION_CONTROLS,
1271
1420
  MIXER_MIXING_OPTIONS,
@@ -1279,14 +1428,22 @@ import {
1279
1428
  rgbUnitToHex,
1280
1429
  setRetouchChoice
1281
1430
  } from "@pixerate/editor/image-editor";
1282
- import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
1431
+ import { DEFAULT_PAINT_GRADIENT } from "@pixerate/editor/image-editor";
1432
+
1433
+ // src/image-editor/PaintGradientEditor.tsx
1434
+ import { PAINT_GRADIENT_KIT } from "@pixerate/editor/image-editor";
1435
+ import { jsx as jsx8 } from "react/jsx-runtime";
1436
+ var PaintGradientEditor = (props) => /* @__PURE__ */ jsx8(PaintGradientEditorView, { ...props, kit: PAINT_GRADIENT_KIT });
1437
+
1438
+ // src/image-editor/BrushOptionsBar.tsx
1439
+ import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
1283
1440
  var chip = (on) => `px-2 py-1 rounded text-[11px] ${on ? "bg-indigo-600 text-white" : "bg-slate-800 text-slate-300 hover:text-white"}`;
1284
1441
  var BrushOptionsBar = ({ controller, className }) => {
1285
- const [, setTick] = useState7(0);
1286
- useEffect6(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
1287
- const [error, setError] = useState7(null);
1442
+ const [, setTick] = useState8(0);
1443
+ useEffect7(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
1444
+ const [error, setError] = useState8(null);
1288
1445
  const state = controller.getState();
1289
- const { brush, foreground, background, mixer, mixerLoad, retouch, cloneSource } = state.paint;
1446
+ const { brush, foreground, background, mixer, mixerLoad, retouch, cloneSource, paint } = state.paint;
1290
1447
  const tool = state.activeTool;
1291
1448
  const attempt = (fn) => {
1292
1449
  try {
@@ -1296,8 +1453,8 @@ var BrushOptionsBar = ({ controller, className }) => {
1296
1453
  setError(err instanceof Error ? err.message : String(err));
1297
1454
  }
1298
1455
  };
1299
- return /* @__PURE__ */ jsxs7("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "brush-options", children: [
1300
- /* @__PURE__ */ jsx7("div", { className: "flex flex-wrap gap-1", role: "toolbar", "aria-label": "Paint tools", children: PAINT_TOOLS.map((t) => /* @__PURE__ */ jsx7(
1456
+ return /* @__PURE__ */ jsxs8("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "brush-options", children: [
1457
+ /* @__PURE__ */ jsx9("div", { className: "flex flex-wrap gap-1", role: "toolbar", "aria-label": "Paint tools", children: PAINT_TOOLS.map((t) => /* @__PURE__ */ jsx9(
1301
1458
  "button",
1302
1459
  {
1303
1460
  type: "button",
@@ -1309,9 +1466,9 @@ var BrushOptionsBar = ({ controller, className }) => {
1309
1466
  },
1310
1467
  t.id
1311
1468
  )) }),
1312
- /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", role: "group", "aria-label": "Colours", children: [
1313
- /* @__PURE__ */ jsxs7("label", { className: "flex items-center gap-1", children: [
1314
- /* @__PURE__ */ jsx7(
1469
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", role: "group", "aria-label": "Colours", children: [
1470
+ /* @__PURE__ */ jsxs8("label", { className: "flex items-center gap-1", children: [
1471
+ /* @__PURE__ */ jsx9(
1315
1472
  "input",
1316
1473
  {
1317
1474
  type: "color",
@@ -1321,10 +1478,10 @@ var BrushOptionsBar = ({ controller, className }) => {
1321
1478
  className: "h-6 w-8 rounded border border-slate-700 bg-transparent"
1322
1479
  }
1323
1480
  ),
1324
- /* @__PURE__ */ jsx7("span", { className: "text-slate-400", children: "FG" })
1481
+ /* @__PURE__ */ jsx9("span", { className: "text-slate-400", children: "FG" })
1325
1482
  ] }),
1326
- /* @__PURE__ */ jsxs7("label", { className: "flex items-center gap-1", children: [
1327
- /* @__PURE__ */ jsx7(
1483
+ /* @__PURE__ */ jsxs8("label", { className: "flex items-center gap-1", children: [
1484
+ /* @__PURE__ */ jsx9(
1328
1485
  "input",
1329
1486
  {
1330
1487
  type: "color",
@@ -1334,12 +1491,24 @@ var BrushOptionsBar = ({ controller, className }) => {
1334
1491
  className: "h-6 w-8 rounded border border-slate-700 bg-transparent"
1335
1492
  }
1336
1493
  ),
1337
- /* @__PURE__ */ jsx7("span", { className: "text-slate-400", children: "BG" })
1494
+ /* @__PURE__ */ jsx9("span", { className: "text-slate-400", children: "BG" })
1338
1495
  ] }),
1339
- /* @__PURE__ */ jsx7("button", { type: "button", title: "Swap colours (X)", className: chip(false), onClick: () => controller.swapPaintColors(), children: "Swap" }),
1340
- /* @__PURE__ */ jsx7("button", { type: "button", title: "Default colours (D)", className: chip(false), onClick: () => controller.resetPaintColors(), children: "Default" })
1496
+ /* @__PURE__ */ jsx9("button", { type: "button", title: "Swap colours (X)", className: chip(false), onClick: () => controller.swapPaintColors(), children: "Swap" }),
1497
+ /* @__PURE__ */ jsx9("button", { type: "button", title: "Default colours (D)", className: chip(false), onClick: () => controller.resetPaintColors(), children: "Default" }),
1498
+ state.activeTool === "brush" && /* @__PURE__ */ jsx9(
1499
+ "button",
1500
+ {
1501
+ type: "button",
1502
+ "aria-pressed": paint.type === "gradient",
1503
+ title: "Gradient paint: the brush changes colour as the stroke goes",
1504
+ className: chip(paint.type === "gradient"),
1505
+ onClick: () => attempt(() => controller.setPaintOptions(paint.type === "gradient" ? { foreground } : { paint: DEFAULT_PAINT_GRADIENT })),
1506
+ children: "Gradient"
1507
+ }
1508
+ )
1341
1509
  ] }),
1342
- BRUSH_OPTION_CONTROLS.map((spec) => /* @__PURE__ */ jsx7(
1510
+ state.activeTool === "brush" && paint.type === "gradient" && /* @__PURE__ */ jsx9(PaintGradientEditor, { value: paint, colors: { paint: foreground, secondary: background }, onChange: (g) => attempt(() => controller.setPaintOptions({ paint: g })) }),
1511
+ BRUSH_OPTION_CONTROLS.map((spec) => /* @__PURE__ */ jsx9(
1343
1512
  ControlSlider,
1344
1513
  {
1345
1514
  spec,
@@ -1348,9 +1517,9 @@ var BrushOptionsBar = ({ controller, className }) => {
1348
1517
  },
1349
1518
  spec.id
1350
1519
  )),
1351
- state.activeTool === "mixer" && /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-2 border-t border-slate-800 pt-2", role: "group", "aria-label": "Mixer Brush", "data-testid": "mixer-options", children: [
1352
- /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
1353
- /* @__PURE__ */ jsx7(
1520
+ state.activeTool === "mixer" && /* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-2 border-t border-slate-800 pt-2", role: "group", "aria-label": "Mixer Brush", "data-testid": "mixer-options", children: [
1521
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
1522
+ /* @__PURE__ */ jsx9(
1354
1523
  "span",
1355
1524
  {
1356
1525
  "aria-label": "Brush load",
@@ -1359,10 +1528,10 @@ var BrushOptionsBar = ({ controller, className }) => {
1359
1528
  style: { background: mixerLoad.reservoir ? rgbUnitToHex(mixerLoad.reservoir) : "transparent" }
1360
1529
  }
1361
1530
  ),
1362
- /* @__PURE__ */ jsx7("button", { type: "button", title: "Fill the reservoir with the foreground colour", className: chip(false), onClick: () => controller.loadMixerBrush(), children: "Load brush" }),
1363
- /* @__PURE__ */ jsx7("button", { type: "button", title: "Empty the picked-up colour", className: chip(false), onClick: () => controller.cleanMixerBrush(), children: "Clean brush" })
1531
+ /* @__PURE__ */ jsx9("button", { type: "button", title: "Fill the reservoir with the foreground colour", className: chip(false), onClick: () => controller.loadMixerBrush(), children: "Load brush" }),
1532
+ /* @__PURE__ */ jsx9("button", { type: "button", title: "Empty the picked-up colour", className: chip(false), onClick: () => controller.cleanMixerBrush(), children: "Clean brush" })
1364
1533
  ] }),
1365
- /* @__PURE__ */ jsx7("div", { className: "flex gap-1", role: "group", "aria-label": "Mixing", children: MIXER_MIXING_OPTIONS.map((m) => /* @__PURE__ */ jsx7(
1534
+ /* @__PURE__ */ jsx9("div", { className: "flex gap-1", role: "group", "aria-label": "Mixing", children: MIXER_MIXING_OPTIONS.map((m) => /* @__PURE__ */ jsx9(
1366
1535
  "button",
1367
1536
  {
1368
1537
  type: "button",
@@ -1374,10 +1543,10 @@ var BrushOptionsBar = ({ controller, className }) => {
1374
1543
  },
1375
1544
  m.id
1376
1545
  )) }),
1377
- MIXER_OPTION_CONTROLS.map((spec) => /* @__PURE__ */ jsx7(ControlSlider, { spec, value: mixer[spec.id], onChange: (v) => controller.setPaintOptions({ mixer: { [spec.id]: v } }) }, spec.id)),
1378
- /* @__PURE__ */ jsxs7("div", { className: "flex flex-wrap gap-3 text-slate-300", children: [
1379
- /* @__PURE__ */ jsxs7("label", { className: "flex items-center gap-1.5", children: [
1380
- /* @__PURE__ */ jsx7(
1546
+ MIXER_OPTION_CONTROLS.map((spec) => /* @__PURE__ */ jsx9(ControlSlider, { spec, value: mixer[spec.id], onChange: (v) => controller.setPaintOptions({ mixer: { [spec.id]: v } }) }, spec.id)),
1547
+ /* @__PURE__ */ jsxs8("div", { className: "flex flex-wrap gap-3 text-slate-300", children: [
1548
+ /* @__PURE__ */ jsxs8("label", { className: "flex items-center gap-1.5", children: [
1549
+ /* @__PURE__ */ jsx9(
1381
1550
  "input",
1382
1551
  {
1383
1552
  type: "checkbox",
@@ -1389,8 +1558,8 @@ var BrushOptionsBar = ({ controller, className }) => {
1389
1558
  ),
1390
1559
  "Load each stroke"
1391
1560
  ] }),
1392
- /* @__PURE__ */ jsxs7("label", { className: "flex items-center gap-1.5", children: [
1393
- /* @__PURE__ */ jsx7(
1561
+ /* @__PURE__ */ jsxs8("label", { className: "flex items-center gap-1.5", children: [
1562
+ /* @__PURE__ */ jsx9(
1394
1563
  "input",
1395
1564
  {
1396
1565
  type: "checkbox",
@@ -1404,14 +1573,14 @@ var BrushOptionsBar = ({ controller, className }) => {
1404
1573
  ] })
1405
1574
  ] })
1406
1575
  ] }),
1407
- isRetouchPaintTool(tool) && /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-2 border-t border-slate-800 pt-2", role: "group", "aria-label": "Retouch options", "data-testid": "retouch-options", children: [
1408
- (tool === "clone" || tool === "heal") && /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
1409
- /* @__PURE__ */ jsx7("span", { className: "text-slate-400", "data-testid": "clone-source", children: cloneSourceLabel(controller) }),
1410
- cloneSource && /* @__PURE__ */ jsx7("button", { type: "button", title: "Forget the source point", className: chip(false), onClick: () => controller.setCloneSource(null), children: "Clear source" })
1576
+ isRetouchPaintTool(tool) && /* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-2 border-t border-slate-800 pt-2", role: "group", "aria-label": "Retouch options", "data-testid": "retouch-options", children: [
1577
+ (tool === "clone" || tool === "heal") && /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
1578
+ /* @__PURE__ */ jsx9("span", { className: "text-slate-400", "data-testid": "clone-source", children: cloneSourceLabel(controller) }),
1579
+ cloneSource && /* @__PURE__ */ jsx9("button", { type: "button", title: "Forget the source point", className: chip(false), onClick: () => controller.setCloneSource(null), children: "Clear source" })
1411
1580
  ] }),
1412
- RETOUCH_CHOICES.filter((c) => c.tools.includes(tool)).map((choice) => /* @__PURE__ */ jsxs7("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": choice.label, children: [
1413
- /* @__PURE__ */ jsx7("span", { className: "text-slate-400", children: choice.label }),
1414
- choice.options.map((o) => /* @__PURE__ */ jsx7(
1581
+ RETOUCH_CHOICES.filter((c) => c.tools.includes(tool)).map((choice) => /* @__PURE__ */ jsxs8("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": choice.label, children: [
1582
+ /* @__PURE__ */ jsx9("span", { className: "text-slate-400", children: choice.label }),
1583
+ choice.options.map((o) => /* @__PURE__ */ jsx9(
1415
1584
  "button",
1416
1585
  {
1417
1586
  type: "button",
@@ -1424,9 +1593,9 @@ var BrushOptionsBar = ({ controller, className }) => {
1424
1593
  o.id
1425
1594
  ))
1426
1595
  ] }, choice.id)),
1427
- RETOUCH_OPTION_CONTROLS.filter((c) => c.tools.includes(tool)).map((spec) => /* @__PURE__ */ jsx7(ControlSlider, { spec, value: retouch[spec.id], onChange: (v) => controller.setPaintOptions({ retouch: { [spec.id]: v } }) }, spec.id)),
1428
- /* @__PURE__ */ jsx7("div", { className: "flex flex-wrap gap-3 text-slate-300", children: RETOUCH_TOGGLES.filter((t) => t.tools.includes(tool)).map((t) => /* @__PURE__ */ jsxs7("label", { className: "flex items-center gap-1.5", children: [
1429
- /* @__PURE__ */ jsx7(
1596
+ RETOUCH_OPTION_CONTROLS.filter((c) => c.tools.includes(tool)).map((spec) => /* @__PURE__ */ jsx9(ControlSlider, { spec, value: retouch[spec.id], onChange: (v) => controller.setPaintOptions({ retouch: { [spec.id]: v } }) }, spec.id)),
1597
+ /* @__PURE__ */ jsx9("div", { className: "flex flex-wrap gap-3 text-slate-300", children: RETOUCH_TOGGLES.filter((t) => t.tools.includes(tool)).map((t) => /* @__PURE__ */ jsxs8("label", { className: "flex items-center gap-1.5", children: [
1598
+ /* @__PURE__ */ jsx9(
1430
1599
  "input",
1431
1600
  {
1432
1601
  type: "checkbox",
@@ -1439,9 +1608,9 @@ var BrushOptionsBar = ({ controller, className }) => {
1439
1608
  t.label
1440
1609
  ] }, t.id)) })
1441
1610
  ] }),
1442
- /* @__PURE__ */ jsxs7("div", { className: "flex flex-wrap gap-3 text-slate-300", role: "group", "aria-label": "Pressure", children: [
1443
- /* @__PURE__ */ jsxs7("label", { className: "flex items-center gap-1.5", children: [
1444
- /* @__PURE__ */ jsx7(
1611
+ /* @__PURE__ */ jsxs8("div", { className: "flex flex-wrap gap-3 text-slate-300", role: "group", "aria-label": "Pressure", children: [
1612
+ /* @__PURE__ */ jsxs8("label", { className: "flex items-center gap-1.5", children: [
1613
+ /* @__PURE__ */ jsx9(
1445
1614
  "input",
1446
1615
  {
1447
1616
  type: "checkbox",
@@ -1453,8 +1622,8 @@ var BrushOptionsBar = ({ controller, className }) => {
1453
1622
  ),
1454
1623
  "Pressure size"
1455
1624
  ] }),
1456
- /* @__PURE__ */ jsxs7("label", { className: "flex items-center gap-1.5", children: [
1457
- /* @__PURE__ */ jsx7(
1625
+ /* @__PURE__ */ jsxs8("label", { className: "flex items-center gap-1.5", children: [
1626
+ /* @__PURE__ */ jsx9(
1458
1627
  "input",
1459
1628
  {
1460
1629
  type: "checkbox",
@@ -1467,27 +1636,27 @@ var BrushOptionsBar = ({ controller, className }) => {
1467
1636
  "Pressure opacity"
1468
1637
  ] })
1469
1638
  ] }),
1470
- /* @__PURE__ */ jsxs7("div", { className: "flex gap-1", children: [
1471
- /* @__PURE__ */ jsx7("button", { type: "button", className: chip(false), onClick: () => attempt(() => controller.fillPixels()), children: "Fill" }),
1472
- /* @__PURE__ */ jsx7("button", { type: "button", className: chip(false), onClick: () => attempt(() => controller.clearPixels()), children: "Clear" })
1639
+ /* @__PURE__ */ jsxs8("div", { className: "flex gap-1", children: [
1640
+ /* @__PURE__ */ jsx9("button", { type: "button", className: chip(false), onClick: () => attempt(() => controller.fillPixels()), children: "Fill" }),
1641
+ /* @__PURE__ */ jsx9("button", { type: "button", className: chip(false), onClick: () => attempt(() => controller.clearPixels()), children: "Clear" })
1473
1642
  ] }),
1474
- error && /* @__PURE__ */ jsx7("p", { role: "alert", className: "text-rose-400", children: error })
1643
+ error && /* @__PURE__ */ jsx9("p", { role: "alert", className: "text-rose-400", children: error })
1475
1644
  ] });
1476
1645
  };
1477
1646
 
1478
1647
  // src/image-editor/ColorProfilePanel.tsx
1479
- import { useEffect as useEffect7, useState as useState8 } from "react";
1648
+ import { useEffect as useEffect8, useState as useState9 } from "react";
1480
1649
  import { COLOR_MODE_OPTIONS, INTENT_OPTIONS, PROOF_PROFILE_OPTIONS, WORKING_SPACE_OPTIONS, colorPanelView } from "@pixerate/editor/image-editor";
1481
- import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
1650
+ import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
1482
1651
  var chip2 = "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white";
1483
1652
  var select = "rounded bg-slate-800 px-1 py-0.5 text-[11px] text-slate-200";
1484
1653
  var ColorProfilePanel = ({ controller, className }) => {
1485
- const [, setTick] = useState8(0);
1486
- useEffect7(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
1487
- const [target, setTarget] = useState8("display-p3");
1488
- const [intent, setIntent] = useState8("relative");
1489
- const [bpc, setBpc] = useState8(true);
1490
- const [error, setError] = useState8(null);
1654
+ const [, setTick] = useState9(0);
1655
+ useEffect8(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
1656
+ const [target, setTarget] = useState9("display-p3");
1657
+ const [intent, setIntent] = useState9("relative");
1658
+ const [bpc, setBpc] = useState9(true);
1659
+ const [error, setError] = useState9(null);
1491
1660
  const view = colorPanelView(controller);
1492
1661
  const attempt = (fn) => {
1493
1662
  try {
@@ -1509,29 +1678,29 @@ var ColorProfilePanel = ({ controller, className }) => {
1509
1678
  })
1510
1679
  );
1511
1680
  };
1512
- return /* @__PURE__ */ jsxs8("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "color-profile-panel", children: [
1513
- /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
1514
- /* @__PURE__ */ jsx8("span", { className: "text-slate-400", children: "Profile" }),
1515
- /* @__PURE__ */ jsx8("span", { "data-testid": "color-profile-name", children: view.profileName })
1681
+ return /* @__PURE__ */ jsxs9("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "color-profile-panel", children: [
1682
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
1683
+ /* @__PURE__ */ jsx10("span", { className: "text-slate-400", children: "Profile" }),
1684
+ /* @__PURE__ */ jsx10("span", { "data-testid": "color-profile-name", children: view.profileName })
1516
1685
  ] }),
1517
- /* @__PURE__ */ jsxs8("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Colour mode", children: [
1518
- /* @__PURE__ */ jsx8("span", { className: "text-slate-400", children: "Mode" }),
1519
- /* @__PURE__ */ jsx8("select", { "aria-label": "Colour mode", className: select, value: view.mode, onChange: (e) => attempt(() => controller.setColorMode(e.target.value)), children: COLOR_MODE_OPTIONS.map((o) => /* @__PURE__ */ jsx8("option", { value: o.id, title: o.title, children: o.label }, o.id)) }),
1520
- view.cmykProfileName && /* @__PURE__ */ jsx8("span", { className: "text-slate-400", children: view.cmykProfileName })
1686
+ /* @__PURE__ */ jsxs9("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Colour mode", children: [
1687
+ /* @__PURE__ */ jsx10("span", { className: "text-slate-400", children: "Mode" }),
1688
+ /* @__PURE__ */ jsx10("select", { "aria-label": "Colour mode", className: select, value: view.mode, onChange: (e) => attempt(() => controller.setColorMode(e.target.value)), children: COLOR_MODE_OPTIONS.map((o) => /* @__PURE__ */ jsx10("option", { value: o.id, title: o.title, children: o.label }, o.id)) }),
1689
+ view.cmykProfileName && /* @__PURE__ */ jsx10("span", { className: "text-slate-400", children: view.cmykProfileName })
1521
1690
  ] }),
1522
- /* @__PURE__ */ jsxs8("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Assign or convert", children: [
1523
- /* @__PURE__ */ jsx8("select", { "aria-label": "Target profile", className: select, value: target, onChange: (e) => setTarget(e.target.value), children: WORKING_SPACE_OPTIONS.map((o) => /* @__PURE__ */ jsx8("option", { value: o.id, children: o.label }, o.id)) }),
1524
- /* @__PURE__ */ jsx8("select", { "aria-label": "Rendering intent", className: select, value: intent, onChange: (e) => setIntent(e.target.value), children: INTENT_OPTIONS.map((o) => /* @__PURE__ */ jsx8("option", { value: o.id, title: o.title, children: o.label }, o.id)) }),
1525
- /* @__PURE__ */ jsxs8("label", { className: "flex items-center gap-1", children: [
1526
- /* @__PURE__ */ jsx8("input", { type: "checkbox", "aria-label": "Black point compensation", checked: bpc, onChange: (e) => setBpc(e.target.checked), className: "accent-indigo-500" }),
1691
+ /* @__PURE__ */ jsxs9("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Assign or convert", children: [
1692
+ /* @__PURE__ */ jsx10("select", { "aria-label": "Target profile", className: select, value: target, onChange: (e) => setTarget(e.target.value), children: WORKING_SPACE_OPTIONS.map((o) => /* @__PURE__ */ jsx10("option", { value: o.id, children: o.label }, o.id)) }),
1693
+ /* @__PURE__ */ jsx10("select", { "aria-label": "Rendering intent", className: select, value: intent, onChange: (e) => setIntent(e.target.value), children: INTENT_OPTIONS.map((o) => /* @__PURE__ */ jsx10("option", { value: o.id, title: o.title, children: o.label }, o.id)) }),
1694
+ /* @__PURE__ */ jsxs9("label", { className: "flex items-center gap-1", children: [
1695
+ /* @__PURE__ */ jsx10("input", { type: "checkbox", "aria-label": "Black point compensation", checked: bpc, onChange: (e) => setBpc(e.target.checked), className: "accent-indigo-500" }),
1527
1696
  "BPC"
1528
1697
  ] }),
1529
- /* @__PURE__ */ jsx8("button", { type: "button", className: chip2, title: "Edit \u203A Assign Profile: keep the numbers", onClick: () => attempt(() => controller.assignProfile(target)), children: "Assign" }),
1530
- /* @__PURE__ */ jsx8("button", { type: "button", className: chip2, title: "Edit \u203A Convert to Profile: keep the look", onClick: () => attempt(() => controller.convertToProfile(target, { intent, bpc })), children: "Convert" })
1698
+ /* @__PURE__ */ jsx10("button", { type: "button", className: chip2, title: "Edit \u203A Assign Profile: keep the numbers", onClick: () => attempt(() => controller.assignProfile(target)), children: "Assign" }),
1699
+ /* @__PURE__ */ jsx10("button", { type: "button", className: chip2, title: "Edit \u203A Convert to Profile: keep the look", onClick: () => attempt(() => controller.convertToProfile(target, { intent, bpc })), children: "Convert" })
1531
1700
  ] }),
1532
- /* @__PURE__ */ jsxs8("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Proof setup", children: [
1533
- /* @__PURE__ */ jsx8("span", { className: "text-slate-400", children: "Proof" }),
1534
- /* @__PURE__ */ jsxs8(
1701
+ /* @__PURE__ */ jsxs9("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Proof setup", children: [
1702
+ /* @__PURE__ */ jsx10("span", { className: "text-slate-400", children: "Proof" }),
1703
+ /* @__PURE__ */ jsxs9(
1535
1704
  "select",
1536
1705
  {
1537
1706
  "aria-label": "Proof profile",
@@ -1539,36 +1708,36 @@ var ColorProfilePanel = ({ controller, className }) => {
1539
1708
  value: view.proof?.id ?? "",
1540
1709
  onChange: (e) => e.target.value ? proofWith({ id: e.target.value }) : attempt(() => controller.setProofSetup(null)),
1541
1710
  children: [
1542
- /* @__PURE__ */ jsx8("option", { value: "", children: "Off" }),
1543
- PROOF_PROFILE_OPTIONS.map((o) => /* @__PURE__ */ jsx8("option", { value: o.id, children: o.label }, o.id))
1711
+ /* @__PURE__ */ jsx10("option", { value: "", children: "Off" }),
1712
+ PROOF_PROFILE_OPTIONS.map((o) => /* @__PURE__ */ jsx10("option", { value: o.id, children: o.label }, o.id))
1544
1713
  ]
1545
1714
  }
1546
1715
  ),
1547
- view.proof && /* @__PURE__ */ jsxs8(Fragment2, { children: [
1548
- /* @__PURE__ */ jsx8("select", { "aria-label": "Proof intent", className: select, value: view.proof.intent, onChange: (e) => proofWith({ intent: e.target.value }), children: INTENT_OPTIONS.map((o) => /* @__PURE__ */ jsx8("option", { value: o.id, children: o.label }, o.id)) }),
1549
- /* @__PURE__ */ jsxs8("label", { className: "flex items-center gap-1", children: [
1550
- /* @__PURE__ */ jsx8("input", { type: "checkbox", "aria-label": "Simulate paper colour", checked: view.proof.simulatePaper, onChange: (e) => proofWith({ simulatePaper: e.target.checked }), className: "accent-indigo-500" }),
1716
+ view.proof && /* @__PURE__ */ jsxs9(Fragment2, { children: [
1717
+ /* @__PURE__ */ jsx10("select", { "aria-label": "Proof intent", className: select, value: view.proof.intent, onChange: (e) => proofWith({ intent: e.target.value }), children: INTENT_OPTIONS.map((o) => /* @__PURE__ */ jsx10("option", { value: o.id, children: o.label }, o.id)) }),
1718
+ /* @__PURE__ */ jsxs9("label", { className: "flex items-center gap-1", children: [
1719
+ /* @__PURE__ */ jsx10("input", { type: "checkbox", "aria-label": "Simulate paper colour", checked: view.proof.simulatePaper, onChange: (e) => proofWith({ simulatePaper: e.target.checked }), className: "accent-indigo-500" }),
1551
1720
  "Paper"
1552
1721
  ] }),
1553
- /* @__PURE__ */ jsxs8("label", { className: "flex items-center gap-1", children: [
1554
- /* @__PURE__ */ jsx8("input", { type: "checkbox", "aria-label": "Gamut warning", checked: view.proof.gamutWarning, onChange: (e) => proofWith({ gamutWarning: e.target.checked }), className: "accent-indigo-500" }),
1722
+ /* @__PURE__ */ jsxs9("label", { className: "flex items-center gap-1", children: [
1723
+ /* @__PURE__ */ jsx10("input", { type: "checkbox", "aria-label": "Gamut warning", checked: view.proof.gamutWarning, onChange: (e) => proofWith({ gamutWarning: e.target.checked }), className: "accent-indigo-500" }),
1555
1724
  "Gamut warning"
1556
1725
  ] })
1557
1726
  ] })
1558
1727
  ] }),
1559
- error && /* @__PURE__ */ jsx8("p", { role: "alert", className: "text-rose-400", children: error })
1728
+ error && /* @__PURE__ */ jsx10("p", { role: "alert", className: "text-rose-400", children: error })
1560
1729
  ] });
1561
1730
  };
1562
1731
 
1563
1732
  // src/image-editor/SelectionOptionsBar.tsx
1564
- import { useState as useState9 } from "react";
1733
+ import { useState as useState10 } from "react";
1565
1734
  import {
1566
1735
  SELECTION_MODES,
1567
1736
  SELECTION_MODE_LABELS,
1568
1737
  SELECTION_TOOLS,
1569
1738
  describeSelection
1570
1739
  } from "@pixerate/editor/image-editor";
1571
- import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
1740
+ import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
1572
1741
  var MODIFY_OPS = [
1573
1742
  { op: "grow", label: "Grow" },
1574
1743
  { op: "shrink", label: "Shrink" },
@@ -1576,7 +1745,7 @@ var MODIFY_OPS = [
1576
1745
  { op: "border", label: "Border" },
1577
1746
  { op: "smooth", label: "Smooth" }
1578
1747
  ];
1579
- var btn = (on) => `px-2 py-1 rounded-md border text-[11px] transition-colors ${on ? "bg-indigo-600 border-indigo-500 text-white" : "bg-slate-950 border-slate-800 text-slate-300 hover:text-white"}`;
1748
+ var btn2 = (on) => `px-2 py-1 rounded-md border text-[11px] transition-colors ${on ? "bg-indigo-600 border-indigo-500 text-white" : "bg-slate-950 border-slate-800 text-slate-300 hover:text-white"}`;
1580
1749
  var SelectionOptionsBar = ({
1581
1750
  controller,
1582
1751
  options,
@@ -1585,20 +1754,20 @@ var SelectionOptionsBar = ({
1585
1754
  quickMask,
1586
1755
  className = ""
1587
1756
  }) => {
1588
- const [radius, setRadius] = useState9(2);
1757
+ const [radius, setRadius] = useState10(2);
1589
1758
  const set = (patch) => onOptionsChange({ ...options, ...patch });
1590
1759
  const sel = selection === void 0 ? controller.getSelection() : selection;
1591
1760
  const qm = quickMask ?? Boolean(controller.getState().quickMask);
1592
- return /* @__PURE__ */ jsxs9("div", { "data-testid": "selection-options-bar", className: `flex flex-col gap-3 text-xs ${className}`, children: [
1593
- /* @__PURE__ */ jsx9("div", { role: "group", "aria-label": "Selection tool", className: "flex flex-wrap gap-1", children: SELECTION_TOOLS.map((t) => /* @__PURE__ */ jsx9("button", { type: "button", "aria-pressed": options.tool === t.id, className: btn(options.tool === t.id), onClick: () => set({ tool: t.id }), children: t.label }, t.id)) }),
1594
- /* @__PURE__ */ jsx9("div", { role: "group", "aria-label": "Selection mode", className: "flex flex-wrap gap-1", children: SELECTION_MODES.map((m) => /* @__PURE__ */ jsx9("button", { type: "button", "aria-pressed": options.mode === m, className: btn(options.mode === m), onClick: () => set({ mode: m }), children: SELECTION_MODE_LABELS[m] }, m)) }),
1595
- options.tool === "wand" && /* @__PURE__ */ jsxs9("div", { className: "flex flex-col gap-2", children: [
1596
- /* @__PURE__ */ jsxs9("label", { className: "flex flex-col gap-1", children: [
1597
- /* @__PURE__ */ jsxs9("span", { className: "flex justify-between text-slate-400", children: [
1598
- /* @__PURE__ */ jsx9("span", { children: "Tolerance" }),
1599
- /* @__PURE__ */ jsx9("span", { className: "font-mono", children: options.tolerance })
1761
+ return /* @__PURE__ */ jsxs10("div", { "data-testid": "selection-options-bar", className: `flex flex-col gap-3 text-xs ${className}`, children: [
1762
+ /* @__PURE__ */ jsx11("div", { role: "group", "aria-label": "Selection tool", className: "flex flex-wrap gap-1", children: SELECTION_TOOLS.map((t) => /* @__PURE__ */ jsx11("button", { type: "button", "aria-pressed": options.tool === t.id, className: btn2(options.tool === t.id), onClick: () => set({ tool: t.id }), children: t.label }, t.id)) }),
1763
+ /* @__PURE__ */ jsx11("div", { role: "group", "aria-label": "Selection mode", className: "flex flex-wrap gap-1", children: SELECTION_MODES.map((m) => /* @__PURE__ */ jsx11("button", { type: "button", "aria-pressed": options.mode === m, className: btn2(options.mode === m), onClick: () => set({ mode: m }), children: SELECTION_MODE_LABELS[m] }, m)) }),
1764
+ options.tool === "wand" && /* @__PURE__ */ jsxs10("div", { className: "flex flex-col gap-2", children: [
1765
+ /* @__PURE__ */ jsxs10("label", { className: "flex flex-col gap-1", children: [
1766
+ /* @__PURE__ */ jsxs10("span", { className: "flex justify-between text-slate-400", children: [
1767
+ /* @__PURE__ */ jsx11("span", { children: "Tolerance" }),
1768
+ /* @__PURE__ */ jsx11("span", { className: "font-mono", children: options.tolerance })
1600
1769
  ] }),
1601
- /* @__PURE__ */ jsx9(
1770
+ /* @__PURE__ */ jsx11(
1602
1771
  "input",
1603
1772
  {
1604
1773
  type: "range",
@@ -1612,17 +1781,17 @@ var SelectionOptionsBar = ({
1612
1781
  }
1613
1782
  )
1614
1783
  ] }),
1615
- /* @__PURE__ */ jsxs9("label", { className: "flex items-center gap-2 text-slate-300", children: [
1616
- /* @__PURE__ */ jsx9("input", { type: "checkbox", checked: options.contiguous, onChange: (e) => set({ contiguous: e.target.checked }) }),
1784
+ /* @__PURE__ */ jsxs10("label", { className: "flex items-center gap-2 text-slate-300", children: [
1785
+ /* @__PURE__ */ jsx11("input", { type: "checkbox", checked: options.contiguous, onChange: (e) => set({ contiguous: e.target.checked }) }),
1617
1786
  "Contiguous"
1618
1787
  ] }),
1619
- /* @__PURE__ */ jsxs9("label", { className: "flex items-center gap-2 text-slate-300", children: [
1620
- /* @__PURE__ */ jsx9("input", { type: "checkbox", checked: options.sampleMerged, onChange: (e) => set({ sampleMerged: e.target.checked }) }),
1788
+ /* @__PURE__ */ jsxs10("label", { className: "flex items-center gap-2 text-slate-300", children: [
1789
+ /* @__PURE__ */ jsx11("input", { type: "checkbox", checked: options.sampleMerged, onChange: (e) => set({ sampleMerged: e.target.checked }) }),
1621
1790
  "Sample adjusted image"
1622
1791
  ] }),
1623
- /* @__PURE__ */ jsxs9("label", { className: "flex items-center gap-2 text-slate-300", children: [
1792
+ /* @__PURE__ */ jsxs10("label", { className: "flex items-center gap-2 text-slate-300", children: [
1624
1793
  "Sample",
1625
- /* @__PURE__ */ jsxs9(
1794
+ /* @__PURE__ */ jsxs10(
1626
1795
  "select",
1627
1796
  {
1628
1797
  "aria-label": "Sample from",
@@ -1630,27 +1799,27 @@ var SelectionOptionsBar = ({
1630
1799
  onChange: (e) => set({ sample: e.target.value }),
1631
1800
  className: "bg-slate-800 border border-slate-700 rounded px-1 py-0.5",
1632
1801
  children: [
1633
- /* @__PURE__ */ jsx9("option", { value: "composite", children: "All layers" }),
1634
- /* @__PURE__ */ jsx9("option", { value: "active-layer", children: "Active layer" })
1802
+ /* @__PURE__ */ jsx11("option", { value: "composite", children: "All layers" }),
1803
+ /* @__PURE__ */ jsx11("option", { value: "active-layer", children: "Active layer" })
1635
1804
  ]
1636
1805
  }
1637
1806
  )
1638
1807
  ] })
1639
1808
  ] }),
1640
- /* @__PURE__ */ jsxs9("label", { className: "flex items-center gap-2 text-slate-300", children: [
1641
- /* @__PURE__ */ jsx9("input", { type: "checkbox", checked: options.antiAlias, onChange: (e) => set({ antiAlias: e.target.checked }) }),
1809
+ /* @__PURE__ */ jsxs10("label", { className: "flex items-center gap-2 text-slate-300", children: [
1810
+ /* @__PURE__ */ jsx11("input", { type: "checkbox", checked: options.antiAlias, onChange: (e) => set({ antiAlias: e.target.checked }) }),
1642
1811
  "Anti-alias"
1643
1812
  ] }),
1644
- /* @__PURE__ */ jsxs9("div", { className: "flex flex-wrap gap-1", children: [
1645
- /* @__PURE__ */ jsx9("button", { type: "button", className: btn(false), onClick: () => controller.selectAll(), children: "Select All" }),
1646
- /* @__PURE__ */ jsx9("button", { type: "button", className: btn(false), disabled: !sel, onClick: () => controller.deselect(), children: "Deselect" }),
1647
- /* @__PURE__ */ jsx9("button", { type: "button", className: btn(false), onClick: () => controller.invertSelection(), children: "Inverse" }),
1648
- /* @__PURE__ */ jsx9("button", { type: "button", "aria-pressed": qm, className: btn(qm), onClick: () => controller.setQuickMask(!qm), children: "Quick Mask" })
1813
+ /* @__PURE__ */ jsxs10("div", { className: "flex flex-wrap gap-1", children: [
1814
+ /* @__PURE__ */ jsx11("button", { type: "button", className: btn2(false), onClick: () => controller.selectAll(), children: "Select All" }),
1815
+ /* @__PURE__ */ jsx11("button", { type: "button", className: btn2(false), disabled: !sel, onClick: () => controller.deselect(), children: "Deselect" }),
1816
+ /* @__PURE__ */ jsx11("button", { type: "button", className: btn2(false), onClick: () => controller.invertSelection(), children: "Inverse" }),
1817
+ /* @__PURE__ */ jsx11("button", { type: "button", "aria-pressed": qm, className: btn2(qm), onClick: () => controller.setQuickMask(!qm), children: "Quick Mask" })
1649
1818
  ] }),
1650
- /* @__PURE__ */ jsxs9("div", { className: "flex flex-wrap items-center gap-1", children: [
1651
- /* @__PURE__ */ jsxs9("label", { className: "flex items-center gap-1 text-slate-400", children: [
1819
+ /* @__PURE__ */ jsxs10("div", { className: "flex flex-wrap items-center gap-1", children: [
1820
+ /* @__PURE__ */ jsxs10("label", { className: "flex items-center gap-1 text-slate-400", children: [
1652
1821
  "Radius",
1653
- /* @__PURE__ */ jsx9(
1822
+ /* @__PURE__ */ jsx11(
1654
1823
  "input",
1655
1824
  {
1656
1825
  type: "number",
@@ -1664,29 +1833,29 @@ var SelectionOptionsBar = ({
1664
1833
  }
1665
1834
  )
1666
1835
  ] }),
1667
- MODIFY_OPS.map(({ op, label }) => /* @__PURE__ */ jsx9("button", { type: "button", className: btn(false), disabled: !sel, onClick: () => controller.modifySelection(op, radius), children: label }, op))
1836
+ MODIFY_OPS.map(({ op, label }) => /* @__PURE__ */ jsx11("button", { type: "button", className: btn2(false), disabled: !sel, onClick: () => controller.modifySelection(op, radius), children: label }, op))
1668
1837
  ] }),
1669
- /* @__PURE__ */ jsx9("p", { "data-testid": "selection-status", className: "text-slate-400", children: describeSelection(sel) })
1838
+ /* @__PURE__ */ jsx11("p", { "data-testid": "selection-status", className: "text-slate-400", children: describeSelection(sel) })
1670
1839
  ] });
1671
1840
  };
1672
1841
 
1673
1842
  // src/image-editor/RefineEdgePanel.tsx
1674
- import { useState as useState10 } from "react";
1843
+ import { useState as useState11 } from "react";
1675
1844
  import {
1676
1845
  ADJUSTMENT_KINDS as ADJUSTMENT_KINDS2,
1677
1846
  REFINE_EDGE_CONTROLS,
1678
1847
  adjustmentKindLabel as adjustmentKindLabel2,
1679
1848
  layerMaskFromSelection
1680
1849
  } from "@pixerate/editor/image-editor";
1681
- import { Fragment as Fragment3, jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
1850
+ import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
1682
1851
  var DEFAULT_PARAMS = { radius: 8, smartRadius: false, smooth: 0, feather: 0, contrast: 0, shiftEdge: 0 };
1683
1852
  var button2 = "px-2 py-1 rounded-md border border-slate-800 bg-slate-950 text-[11px] text-slate-200 hover:text-white disabled:opacity-40";
1684
1853
  var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
1685
- const [params, setParams] = useState10(DEFAULT_PARAMS);
1686
- const [busy, setBusy] = useState10(false);
1687
- const [error, setError] = useState10(null);
1688
- const [layerId, setLayerId] = useState10("");
1689
- const [newKind, setNewKind] = useState10("hueSaturation");
1854
+ const [params, setParams] = useState11(DEFAULT_PARAMS);
1855
+ const [busy, setBusy] = useState11(false);
1856
+ const [error, setError] = useState11(null);
1857
+ const [layerId, setLayerId] = useState11("");
1858
+ const [newKind, setNewKind] = useState11("hueSaturation");
1690
1859
  const sel = selection === void 0 ? controller.getSelection() : selection;
1691
1860
  const list = layers ?? controller.getAdjustmentLayers();
1692
1861
  const target = list.find((l) => l.id === layerId) ?? list[list.length - 1];
@@ -1701,17 +1870,17 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
1701
1870
  setBusy(false);
1702
1871
  }
1703
1872
  };
1704
- return /* @__PURE__ */ jsxs10("div", { "data-testid": "refine-edge-panel", className: `flex flex-col gap-3 text-xs ${className}`, children: [
1705
- /* @__PURE__ */ jsx10("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Refine Edge" }),
1706
- REFINE_EDGE_CONTROLS.map((c) => /* @__PURE__ */ jsxs10("label", { className: "flex flex-col gap-1", children: [
1707
- /* @__PURE__ */ jsxs10("span", { className: "flex justify-between text-slate-400", children: [
1708
- /* @__PURE__ */ jsx10("span", { children: c.label }),
1709
- /* @__PURE__ */ jsxs10("span", { className: "font-mono", children: [
1873
+ return /* @__PURE__ */ jsxs11("div", { "data-testid": "refine-edge-panel", className: `flex flex-col gap-3 text-xs ${className}`, children: [
1874
+ /* @__PURE__ */ jsx12("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Refine Edge" }),
1875
+ REFINE_EDGE_CONTROLS.map((c) => /* @__PURE__ */ jsxs11("label", { className: "flex flex-col gap-1", children: [
1876
+ /* @__PURE__ */ jsxs11("span", { className: "flex justify-between text-slate-400", children: [
1877
+ /* @__PURE__ */ jsx12("span", { children: c.label }),
1878
+ /* @__PURE__ */ jsxs11("span", { className: "font-mono", children: [
1710
1879
  params[c.id],
1711
1880
  c.unit
1712
1881
  ] })
1713
1882
  ] }),
1714
- /* @__PURE__ */ jsx10(
1883
+ /* @__PURE__ */ jsx12(
1715
1884
  "input",
1716
1885
  {
1717
1886
  type: "range",
@@ -1725,28 +1894,28 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
1725
1894
  }
1726
1895
  )
1727
1896
  ] }, c.id)),
1728
- /* @__PURE__ */ jsxs10("label", { className: "flex items-center gap-2 text-slate-300", children: [
1729
- /* @__PURE__ */ jsx10("input", { type: "checkbox", checked: params.smartRadius, onChange: (e) => setParams({ ...params, smartRadius: e.target.checked }) }),
1897
+ /* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-2 text-slate-300", children: [
1898
+ /* @__PURE__ */ jsx12("input", { type: "checkbox", checked: params.smartRadius, onChange: (e) => setParams({ ...params, smartRadius: e.target.checked }) }),
1730
1899
  "Smart Radius"
1731
1900
  ] }),
1732
- /* @__PURE__ */ jsxs10("div", { className: "flex gap-1", children: [
1733
- /* @__PURE__ */ jsx10("button", { type: "button", className: button2, disabled: !sel || busy, onClick: refine, children: "Refine Edge" }),
1734
- /* @__PURE__ */ jsx10("button", { type: "button", className: button2, onClick: () => setParams(DEFAULT_PARAMS), children: "Reset" })
1901
+ /* @__PURE__ */ jsxs11("div", { className: "flex gap-1", children: [
1902
+ /* @__PURE__ */ jsx12("button", { type: "button", className: button2, disabled: !sel || busy, onClick: refine, children: "Refine Edge" }),
1903
+ /* @__PURE__ */ jsx12("button", { type: "button", className: button2, onClick: () => setParams(DEFAULT_PARAMS), children: "Reset" })
1735
1904
  ] }),
1736
- error && /* @__PURE__ */ jsx10("p", { role: "alert", className: "text-rose-400", children: error }),
1737
- /* @__PURE__ */ jsx10("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] mt-2", children: "Layer Mask" }),
1738
- /* @__PURE__ */ jsxs10("div", { className: "flex gap-1 items-center", children: [
1739
- /* @__PURE__ */ jsx10(
1905
+ error && /* @__PURE__ */ jsx12("p", { role: "alert", className: "text-rose-400", children: error }),
1906
+ /* @__PURE__ */ jsx12("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] mt-2", children: "Layer Mask" }),
1907
+ /* @__PURE__ */ jsxs11("div", { className: "flex gap-1 items-center", children: [
1908
+ /* @__PURE__ */ jsx12(
1740
1909
  "select",
1741
1910
  {
1742
1911
  "aria-label": "New masked layer kind",
1743
1912
  value: newKind,
1744
1913
  onChange: (e) => setNewKind(e.target.value),
1745
1914
  className: "flex-1 bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
1746
- children: ADJUSTMENT_KINDS2.map((k) => /* @__PURE__ */ jsx10("option", { value: k.kind, children: k.label }, k.kind))
1915
+ children: ADJUSTMENT_KINDS2.map((k) => /* @__PURE__ */ jsx12("option", { value: k.kind, children: k.label }, k.kind))
1747
1916
  }
1748
1917
  ),
1749
- /* @__PURE__ */ jsx10(
1918
+ /* @__PURE__ */ jsx12(
1750
1919
  "button",
1751
1920
  {
1752
1921
  type: "button",
@@ -1757,35 +1926,35 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
1757
1926
  }
1758
1927
  )
1759
1928
  ] }),
1760
- list.length > 0 && target && /* @__PURE__ */ jsxs10("div", { className: "flex flex-col gap-2", children: [
1761
- /* @__PURE__ */ jsx10(
1929
+ list.length > 0 && target && /* @__PURE__ */ jsxs11("div", { className: "flex flex-col gap-2", children: [
1930
+ /* @__PURE__ */ jsx12(
1762
1931
  "select",
1763
1932
  {
1764
1933
  "aria-label": "Mask layer",
1765
1934
  value: target.id,
1766
1935
  onChange: (e) => setLayerId(e.target.value),
1767
1936
  className: "bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
1768
- children: list.map((l) => /* @__PURE__ */ jsxs10("option", { value: l.id, children: [
1937
+ children: list.map((l) => /* @__PURE__ */ jsxs11("option", { value: l.id, children: [
1769
1938
  l.name || adjustmentKindLabel2(l.kind),
1770
1939
  l.mask ? " (masked)" : ""
1771
1940
  ] }, l.id))
1772
1941
  }
1773
1942
  ),
1774
- /* @__PURE__ */ jsxs10("div", { className: "flex flex-wrap gap-1", children: [
1775
- /* @__PURE__ */ jsx10("button", { type: "button", className: button2, disabled: !sel, onClick: () => controller.applySelectionAsLayerMask(target.id), children: "Mask with Selection" }),
1776
- /* @__PURE__ */ jsx10("button", { type: "button", className: button2, disabled: !target.mask, onClick: () => controller.selectionFromLayerMask(target.id), children: "Load as Selection" }),
1777
- /* @__PURE__ */ jsx10("button", { type: "button", className: button2, disabled: !target.mask, onClick: () => controller.setAdjustmentLayerMask(target.id, null), children: "Remove Mask" })
1943
+ /* @__PURE__ */ jsxs11("div", { className: "flex flex-wrap gap-1", children: [
1944
+ /* @__PURE__ */ jsx12("button", { type: "button", className: button2, disabled: !sel, onClick: () => controller.applySelectionAsLayerMask(target.id), children: "Mask with Selection" }),
1945
+ /* @__PURE__ */ jsx12("button", { type: "button", className: button2, disabled: !target.mask, onClick: () => controller.selectionFromLayerMask(target.id), children: "Load as Selection" }),
1946
+ /* @__PURE__ */ jsx12("button", { type: "button", className: button2, disabled: !target.mask, onClick: () => controller.setAdjustmentLayerMask(target.id, null), children: "Remove Mask" })
1778
1947
  ] }),
1779
- target.mask && /* @__PURE__ */ jsxs10(Fragment3, { children: [
1780
- /* @__PURE__ */ jsxs10("label", { className: "flex flex-col gap-1", children: [
1781
- /* @__PURE__ */ jsxs10("span", { className: "flex justify-between text-slate-400", children: [
1782
- /* @__PURE__ */ jsx10("span", { children: "Density" }),
1783
- /* @__PURE__ */ jsxs10("span", { className: "font-mono", children: [
1948
+ target.mask && /* @__PURE__ */ jsxs11(Fragment3, { children: [
1949
+ /* @__PURE__ */ jsxs11("label", { className: "flex flex-col gap-1", children: [
1950
+ /* @__PURE__ */ jsxs11("span", { className: "flex justify-between text-slate-400", children: [
1951
+ /* @__PURE__ */ jsx12("span", { children: "Density" }),
1952
+ /* @__PURE__ */ jsxs11("span", { className: "font-mono", children: [
1784
1953
  Math.round((target.mask.density ?? 1) * 100),
1785
1954
  "%"
1786
1955
  ] })
1787
1956
  ] }),
1788
- /* @__PURE__ */ jsx10(
1957
+ /* @__PURE__ */ jsx12(
1789
1958
  "input",
1790
1959
  {
1791
1960
  type: "range",
@@ -1799,15 +1968,15 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
1799
1968
  }
1800
1969
  )
1801
1970
  ] }),
1802
- /* @__PURE__ */ jsxs10("label", { className: "flex flex-col gap-1", children: [
1803
- /* @__PURE__ */ jsxs10("span", { className: "flex justify-between text-slate-400", children: [
1804
- /* @__PURE__ */ jsx10("span", { children: "Mask Feather" }),
1805
- /* @__PURE__ */ jsxs10("span", { className: "font-mono", children: [
1971
+ /* @__PURE__ */ jsxs11("label", { className: "flex flex-col gap-1", children: [
1972
+ /* @__PURE__ */ jsxs11("span", { className: "flex justify-between text-slate-400", children: [
1973
+ /* @__PURE__ */ jsx12("span", { children: "Mask Feather" }),
1974
+ /* @__PURE__ */ jsxs11("span", { className: "font-mono", children: [
1806
1975
  target.mask.feather ?? 0,
1807
1976
  "px"
1808
1977
  ] })
1809
1978
  ] }),
1810
- /* @__PURE__ */ jsx10(
1979
+ /* @__PURE__ */ jsx12(
1811
1980
  "input",
1812
1981
  {
1813
1982
  type: "range",
@@ -1827,14 +1996,14 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
1827
1996
  };
1828
1997
 
1829
1998
  // src/image-editor/FreeTransformOptionsBar.tsx
1830
- import { useEffect as useEffect8, useState as useState11 } from "react";
1999
+ import { useEffect as useEffect9, useState as useState12 } from "react";
1831
2000
  import { FREE_TRANSFORM_FIELDS, FREE_TRANSFORM_MODE_OPTIONS, INTERPOLATIONS, TRANSFORM_ANCHORS, WARP_GRID_OPTIONS, WARP_STYLE_OPTIONS } from "@pixerate/editor/image-editor";
1832
- import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
2001
+ import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
1833
2002
  var chip3 = (on) => `px-2 py-1 rounded text-[11px] ${on ? "bg-indigo-600 text-white" : "bg-slate-800 text-slate-300 hover:text-white"}`;
1834
2003
  var round = (v, unit) => unit === "px" ? Math.round(v * 10) / 10 : Math.round(v * 100) / 100;
1835
2004
  var FreeTransformOptionsBar = ({ tool, className }) => {
1836
- const [, setTick] = useState11(0);
1837
- useEffect8(() => tool.subscribe(() => setTick((n) => n + 1)), [tool]);
2005
+ const [, setTick] = useState12(0);
2006
+ useEffect9(() => tool.subscribe(() => setTick((n) => n + 1)), [tool]);
1838
2007
  const bar = tool.bar();
1839
2008
  if (!tool.active || !bar) return null;
1840
2009
  const warp = tool.warpBar();
@@ -1846,17 +2015,17 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
1846
2015
  const v = Number(raw);
1847
2016
  if (raw.trim() !== "" && Number.isFinite(v) && Math.abs(v - bar[field]) > 1e-9) tool.setField(field, v);
1848
2017
  };
1849
- return /* @__PURE__ */ jsxs11("div", { className: `flex flex-wrap items-center gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "free-transform-options", role: "toolbar", "aria-label": "Free Transform options", children: [
1850
- /* @__PURE__ */ jsx11("div", { className: "flex gap-1", role: "group", "aria-label": "Transform mode", children: FREE_TRANSFORM_MODE_OPTIONS.map((m) => /* @__PURE__ */ jsx11("button", { type: "button", title: m.title, "aria-pressed": tool.mode === m.id, className: chip3(tool.mode === m.id), onClick: () => tool.setMode(m.id), children: m.label }, m.id)) }),
1851
- /* @__PURE__ */ jsx11("div", { className: "grid grid-cols-3 gap-px", role: "group", "aria-label": "Reference point", children: TRANSFORM_ANCHORS.map((a) => /* @__PURE__ */ jsx11("button", { type: "button", "aria-label": `Reference point ${a}`, title: `Reference point: ${a}`, className: "h-2.5 w-2.5 rounded-sm bg-slate-700 hover:bg-indigo-500", onClick: () => tool.setReference(a) }, a)) }),
1852
- tool.mode === "warp" && /* @__PURE__ */ jsxs11("div", { className: "flex flex-wrap items-center gap-2", role: "group", "aria-label": "Warp options", children: [
1853
- /* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-1", children: [
1854
- /* @__PURE__ */ jsx11("span", { className: "text-slate-400", children: "Warp" }),
1855
- /* @__PURE__ */ jsx11("select", { "aria-label": "Warp style", value: warp.style, onChange: (e) => tool.setWarp({ style: e.target.value }), className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5", children: WARP_STYLE_OPTIONS.map((o) => /* @__PURE__ */ jsx11("option", { value: o.id, children: o.label }, o.id)) })
2018
+ return /* @__PURE__ */ jsxs12("div", { className: `flex flex-wrap items-center gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "free-transform-options", role: "toolbar", "aria-label": "Free Transform options", children: [
2019
+ /* @__PURE__ */ jsx13("div", { className: "flex gap-1", role: "group", "aria-label": "Transform mode", children: FREE_TRANSFORM_MODE_OPTIONS.map((m) => /* @__PURE__ */ jsx13("button", { type: "button", title: m.title, "aria-pressed": tool.mode === m.id, className: chip3(tool.mode === m.id), onClick: () => tool.setMode(m.id), children: m.label }, m.id)) }),
2020
+ /* @__PURE__ */ jsx13("div", { className: "grid grid-cols-3 gap-px", role: "group", "aria-label": "Reference point", children: TRANSFORM_ANCHORS.map((a) => /* @__PURE__ */ jsx13("button", { type: "button", "aria-label": `Reference point ${a}`, title: `Reference point: ${a}`, className: "h-2.5 w-2.5 rounded-sm bg-slate-700 hover:bg-indigo-500", onClick: () => tool.setReference(a) }, a)) }),
2021
+ tool.mode === "warp" && /* @__PURE__ */ jsxs12("div", { className: "flex flex-wrap items-center gap-2", role: "group", "aria-label": "Warp options", children: [
2022
+ /* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", children: [
2023
+ /* @__PURE__ */ jsx13("span", { className: "text-slate-400", children: "Warp" }),
2024
+ /* @__PURE__ */ jsx13("select", { "aria-label": "Warp style", value: warp.style, onChange: (e) => tool.setWarp({ style: e.target.value }), className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5", children: WARP_STYLE_OPTIONS.map((o) => /* @__PURE__ */ jsx13("option", { value: o.id, children: o.label }, o.id)) })
1856
2025
  ] }),
1857
- ["bend", "horizontal", "vertical"].map((k) => /* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-1", children: [
1858
- /* @__PURE__ */ jsx11("span", { className: "text-slate-400", children: k === "bend" ? "Bend" : k === "horizontal" ? "H" : "V" }),
1859
- /* @__PURE__ */ jsx11(
2026
+ ["bend", "horizontal", "vertical"].map((k) => /* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", children: [
2027
+ /* @__PURE__ */ jsx13("span", { className: "text-slate-400", children: k === "bend" ? "Bend" : k === "horizontal" ? "H" : "V" }),
2028
+ /* @__PURE__ */ jsx13(
1860
2029
  "input",
1861
2030
  {
1862
2031
  type: "number",
@@ -1877,9 +2046,9 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
1877
2046
  },
1878
2047
  `${k}:${warp[k]}`
1879
2048
  ),
1880
- /* @__PURE__ */ jsx11("span", { className: "text-slate-500", children: "%" })
2049
+ /* @__PURE__ */ jsx13("span", { className: "text-slate-500", children: "%" })
1881
2050
  ] }, k)),
1882
- /* @__PURE__ */ jsx11(
2051
+ /* @__PURE__ */ jsx13(
1883
2052
  "button",
1884
2053
  {
1885
2054
  type: "button",
@@ -1891,9 +2060,9 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
1891
2060
  children: "Vertical"
1892
2061
  }
1893
2062
  ),
1894
- /* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-1", children: [
1895
- /* @__PURE__ */ jsx11("span", { className: "text-slate-400", children: "Grid" }),
1896
- /* @__PURE__ */ jsx11(
2063
+ /* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", children: [
2064
+ /* @__PURE__ */ jsx13("span", { className: "text-slate-400", children: "Grid" }),
2065
+ /* @__PURE__ */ jsx13(
1897
2066
  "select",
1898
2067
  {
1899
2068
  "aria-label": "Warp grid",
@@ -1903,14 +2072,14 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
1903
2072
  tool.setWarp({ columns: g.columns, rows: g.rows });
1904
2073
  },
1905
2074
  className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
1906
- children: WARP_GRID_OPTIONS.map((g) => /* @__PURE__ */ jsx11("option", { value: g.id, children: g.label }, g.id))
2075
+ children: WARP_GRID_OPTIONS.map((g) => /* @__PURE__ */ jsx13("option", { value: g.id, children: g.label }, g.id))
1907
2076
  }
1908
2077
  )
1909
2078
  ] })
1910
2079
  ] }),
1911
- tool.mode !== "warp" && FREE_TRANSFORM_FIELDS.map((f) => /* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-1", title: f.title, children: [
1912
- /* @__PURE__ */ jsx11("span", { className: "text-slate-400", children: f.label }),
1913
- /* @__PURE__ */ jsx11(
2080
+ tool.mode !== "warp" && FREE_TRANSFORM_FIELDS.map((f) => /* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", title: f.title, children: [
2081
+ /* @__PURE__ */ jsx13("span", { className: "text-slate-400", children: f.label }),
2082
+ /* @__PURE__ */ jsx13(
1914
2083
  "input",
1915
2084
  {
1916
2085
  type: "number",
@@ -1930,8 +2099,8 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
1930
2099
  },
1931
2100
  `${f.id}:${round(bar[f.id], f.unit)}`
1932
2101
  ),
1933
- /* @__PURE__ */ jsx11("span", { className: "text-slate-500", children: f.unit }),
1934
- f.id === "scaleX" && /* @__PURE__ */ jsx11(
2102
+ /* @__PURE__ */ jsx13("span", { className: "text-slate-500", children: f.unit }),
2103
+ f.id === "scaleX" && /* @__PURE__ */ jsx13(
1935
2104
  "button",
1936
2105
  {
1937
2106
  type: "button",
@@ -1946,34 +2115,34 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
1946
2115
  }
1947
2116
  )
1948
2117
  ] }, f.id)),
1949
- /* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-1", children: [
1950
- /* @__PURE__ */ jsx11("span", { className: "text-slate-400", children: "Interpolation" }),
1951
- /* @__PURE__ */ jsx11(
2118
+ /* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", children: [
2119
+ /* @__PURE__ */ jsx13("span", { className: "text-slate-400", children: "Interpolation" }),
2120
+ /* @__PURE__ */ jsx13(
1952
2121
  "select",
1953
2122
  {
1954
2123
  "aria-label": "Interpolation",
1955
2124
  value: tool.interpolation,
1956
2125
  onChange: (e) => tool.setInterpolation(e.target.value),
1957
2126
  className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
1958
- children: INTERPOLATIONS.map((i) => /* @__PURE__ */ jsx11("option", { value: i, children: i[0].toUpperCase() + i.slice(1) }, i))
2127
+ children: INTERPOLATIONS.map((i) => /* @__PURE__ */ jsx13("option", { value: i, children: i[0].toUpperCase() + i.slice(1) }, i))
1959
2128
  }
1960
2129
  )
1961
2130
  ] }),
1962
- /* @__PURE__ */ jsx11("button", { type: "button", title: "Commit (Enter)", className: "px-2 py-1 rounded bg-emerald-600 text-white hover:bg-emerald-500", onClick: () => tool.commit(), children: "Commit" }),
1963
- /* @__PURE__ */ jsx11("button", { type: "button", title: "Cancel (Esc)", className: chip3(false), onClick: () => tool.cancel(), children: "Cancel" }),
1964
- tool.error && /* @__PURE__ */ jsx11("span", { role: "alert", className: "text-rose-400", children: tool.error })
2131
+ /* @__PURE__ */ jsx13("button", { type: "button", title: "Commit (Enter)", className: "px-2 py-1 rounded bg-emerald-600 text-white hover:bg-emerald-500", onClick: () => tool.commit(), children: "Commit" }),
2132
+ /* @__PURE__ */ jsx13("button", { type: "button", title: "Cancel (Esc)", className: chip3(false), onClick: () => tool.cancel(), children: "Cancel" }),
2133
+ tool.error && /* @__PURE__ */ jsx13("span", { role: "alert", className: "text-rose-400", children: tool.error })
1965
2134
  ] });
1966
2135
  };
1967
2136
 
1968
2137
  // src/image-editor/ShapeOptionsBar.tsx
1969
- import { useEffect as useEffect9, useState as useState12 } from "react";
2138
+ import { useEffect as useEffect10, useState as useState13 } from "react";
1970
2139
  import { LIVE_SHAPE_KINDS, SHAPE_KIND_LABELS, applyShapeOptions } from "@pixerate/editor/image-editor";
1971
- import { Fragment as Fragment4, jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
2140
+ import { Fragment as Fragment4, jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
1972
2141
  var chip4 = (on) => `px-2 py-1 rounded text-[11px] ${on ? "bg-indigo-600 text-white" : "bg-slate-800 text-slate-300 hover:text-white"}`;
1973
2142
  var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
1974
- const [, setTick] = useState12(0);
1975
- useEffect9(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
1976
- const [error, setError] = useState12(null);
2143
+ const [, setTick] = useState13(0);
2144
+ useEffect10(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
2145
+ const [error, setError] = useState13(null);
1977
2146
  const active = controller.getActiveLayer();
1978
2147
  const shapeId = active?.type === "shape" ? active.id : null;
1979
2148
  const set = (change) => {
@@ -1987,13 +2156,13 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
1987
2156
  }
1988
2157
  };
1989
2158
  const num = (v, min, max) => Math.max(min, Math.min(max, Number(v) || min));
1990
- return /* @__PURE__ */ jsxs12("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "shape-options", children: [
1991
- /* @__PURE__ */ jsx12("div", { className: "flex flex-wrap gap-1", role: "toolbar", "aria-label": "Shape kind", children: LIVE_SHAPE_KINDS.map((k) => /* @__PURE__ */ jsx12("button", { type: "button", "aria-pressed": options.kind === k, className: chip4(options.kind === k), onClick: () => onChange({ ...options, kind: k }), children: SHAPE_KIND_LABELS[k] }, k)) }),
1992
- /* @__PURE__ */ jsxs12("div", { className: "flex flex-wrap items-center gap-3", children: [
1993
- /* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", children: [
1994
- /* @__PURE__ */ jsx12("input", { type: "checkbox", "aria-label": "Fill", checked: options.fill !== null, onChange: (e) => set({ fill: e.target.checked ? "#4f46e5" : null }) }),
2159
+ return /* @__PURE__ */ jsxs13("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "shape-options", children: [
2160
+ /* @__PURE__ */ jsx14("div", { className: "flex flex-wrap gap-1", role: "toolbar", "aria-label": "Shape kind", children: LIVE_SHAPE_KINDS.map((k) => /* @__PURE__ */ jsx14("button", { type: "button", "aria-pressed": options.kind === k, className: chip4(options.kind === k), onClick: () => onChange({ ...options, kind: k }), children: SHAPE_KIND_LABELS[k] }, k)) }),
2161
+ /* @__PURE__ */ jsxs13("div", { className: "flex flex-wrap items-center gap-3", children: [
2162
+ /* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-1", children: [
2163
+ /* @__PURE__ */ jsx14("input", { type: "checkbox", "aria-label": "Fill", checked: options.fill !== null, onChange: (e) => set({ fill: e.target.checked ? "#4f46e5" : null }) }),
1995
2164
  "Fill",
1996
- /* @__PURE__ */ jsx12(
2165
+ /* @__PURE__ */ jsx14(
1997
2166
  "input",
1998
2167
  {
1999
2168
  type: "color",
@@ -2005,10 +2174,10 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
2005
2174
  }
2006
2175
  )
2007
2176
  ] }),
2008
- /* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", children: [
2009
- /* @__PURE__ */ jsx12("input", { type: "checkbox", "aria-label": "Stroke", checked: options.stroke !== null, onChange: (e) => set({ stroke: e.target.checked ? "#000000" : null }) }),
2177
+ /* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-1", children: [
2178
+ /* @__PURE__ */ jsx14("input", { type: "checkbox", "aria-label": "Stroke", checked: options.stroke !== null, onChange: (e) => set({ stroke: e.target.checked ? "#000000" : null }) }),
2010
2179
  "Stroke",
2011
- /* @__PURE__ */ jsx12(
2180
+ /* @__PURE__ */ jsx14(
2012
2181
  "input",
2013
2182
  {
2014
2183
  type: "color",
@@ -2020,9 +2189,9 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
2020
2189
  }
2021
2190
  )
2022
2191
  ] }),
2023
- /* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", children: [
2192
+ /* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-1", children: [
2024
2193
  "Width",
2025
- /* @__PURE__ */ jsx12(
2194
+ /* @__PURE__ */ jsx14(
2026
2195
  "input",
2027
2196
  {
2028
2197
  type: "number",
@@ -2036,23 +2205,23 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
2036
2205
  )
2037
2206
  ] })
2038
2207
  ] }),
2039
- /* @__PURE__ */ jsxs12("div", { className: "flex flex-wrap items-center gap-3", children: [
2040
- options.kind === "rect" && /* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", children: [
2208
+ /* @__PURE__ */ jsxs13("div", { className: "flex flex-wrap items-center gap-3", children: [
2209
+ options.kind === "rect" && /* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-1", children: [
2041
2210
  "Radius",
2042
- /* @__PURE__ */ jsx12("input", { type: "number", "aria-label": "Corner radius", min: 0, max: 1e3, value: options.radius, onChange: (e) => set({ radius: num(e.target.value, 0, 1e3) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
2211
+ /* @__PURE__ */ jsx14("input", { type: "number", "aria-label": "Corner radius", min: 0, max: 1e3, value: options.radius, onChange: (e) => set({ radius: num(e.target.value, 0, 1e3) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
2043
2212
  ] }),
2044
- options.kind === "polygon" && /* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", children: [
2213
+ options.kind === "polygon" && /* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-1", children: [
2045
2214
  "Sides",
2046
- /* @__PURE__ */ jsx12("input", { type: "number", "aria-label": "Sides", min: 3, max: 100, value: options.sides, onChange: (e) => set({ sides: num(e.target.value, 3, 100) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
2215
+ /* @__PURE__ */ jsx14("input", { type: "number", "aria-label": "Sides", min: 3, max: 100, value: options.sides, onChange: (e) => set({ sides: num(e.target.value, 3, 100) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
2047
2216
  ] }),
2048
- options.kind === "star" && /* @__PURE__ */ jsxs12(Fragment4, { children: [
2049
- /* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", children: [
2217
+ options.kind === "star" && /* @__PURE__ */ jsxs13(Fragment4, { children: [
2218
+ /* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-1", children: [
2050
2219
  "Points",
2051
- /* @__PURE__ */ jsx12("input", { type: "number", "aria-label": "Points", min: 3, max: 100, value: options.points, onChange: (e) => set({ points: num(e.target.value, 3, 100) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
2220
+ /* @__PURE__ */ jsx14("input", { type: "number", "aria-label": "Points", min: 3, max: 100, value: options.points, onChange: (e) => set({ points: num(e.target.value, 3, 100) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
2052
2221
  ] }),
2053
- /* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", children: [
2222
+ /* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-1", children: [
2054
2223
  "Inner",
2055
- /* @__PURE__ */ jsx12(
2224
+ /* @__PURE__ */ jsx14(
2056
2225
  "input",
2057
2226
  {
2058
2227
  type: "range",
@@ -2067,33 +2236,33 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
2067
2236
  )
2068
2237
  ] })
2069
2238
  ] }),
2070
- options.kind === "line" && /* @__PURE__ */ jsxs12(Fragment4, { children: [
2071
- /* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", children: [
2239
+ options.kind === "line" && /* @__PURE__ */ jsxs13(Fragment4, { children: [
2240
+ /* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-1", children: [
2072
2241
  "Weight",
2073
- /* @__PURE__ */ jsx12("input", { type: "number", "aria-label": "Line weight", min: 1, max: 200, value: options.weight, onChange: (e) => set({ weight: num(e.target.value, 1, 200) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
2242
+ /* @__PURE__ */ jsx14("input", { type: "number", "aria-label": "Line weight", min: 1, max: 200, value: options.weight, onChange: (e) => set({ weight: num(e.target.value, 1, 200) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
2074
2243
  ] }),
2075
- /* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", children: [
2076
- /* @__PURE__ */ jsx12("input", { type: "checkbox", "aria-label": "Arrowhead", checked: options.arrow, onChange: (e) => set({ arrow: e.target.checked }) }),
2244
+ /* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-1", children: [
2245
+ /* @__PURE__ */ jsx14("input", { type: "checkbox", "aria-label": "Arrowhead", checked: options.arrow, onChange: (e) => set({ arrow: e.target.checked }) }),
2077
2246
  "Arrowhead"
2078
2247
  ] })
2079
2248
  ] })
2080
2249
  ] }),
2081
- /* @__PURE__ */ jsx12("p", { className: "text-[10px] text-slate-500", children: "Drag on the image to draw. Shift: square, circle or 45\xB0 line. Alt: from the centre." }),
2082
- error && /* @__PURE__ */ jsx12("p", { role: "alert", className: "text-rose-400", children: error })
2250
+ /* @__PURE__ */ jsx14("p", { className: "text-[10px] text-slate-500", children: "Drag on the image to draw. Shift: square, circle or 45\xB0 line. Alt: from the centre." }),
2251
+ error && /* @__PURE__ */ jsx14("p", { role: "alert", className: "text-rose-400", children: error })
2083
2252
  ] });
2084
2253
  };
2085
2254
 
2086
2255
  // src/image-editor/TypeOptionsBar.tsx
2087
- import { useEffect as useEffect10, useState as useState13 } from "react";
2256
+ import { useEffect as useEffect11, useState as useState14 } from "react";
2088
2257
  import { TEXT_ALIGNS } from "@pixerate/editor/image-editor";
2089
- import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
2258
+ import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
2090
2259
  var chip5 = (on) => `px-2 py-1 rounded text-[11px] ${on ? "bg-indigo-600 text-white" : "bg-slate-800 text-slate-300 hover:text-white"}`;
2091
2260
  var ALIGN_LABELS = { left: "Left", center: "Centre", right: "Right", justify: "Justify" };
2092
2261
  var TypeOptionsBar = ({ controller, options, onChange, session, className }) => {
2093
- const [, setTick] = useState13(0);
2094
- useEffect10(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
2095
- useEffect10(() => session?.subscribe(() => setTick((n) => n + 1)), [session]);
2096
- const [error, setError] = useState13(null);
2262
+ const [, setTick] = useState14(0);
2263
+ useEffect11(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
2264
+ useEffect11(() => session?.subscribe(() => setTick((n) => n + 1)), [session]);
2265
+ const [error, setError] = useState14(null);
2097
2266
  const active = controller.getActiveLayer();
2098
2267
  const typeId = !session && active?.type === "type" ? active.id : null;
2099
2268
  const here = session?.alive ? session.styleHere() : {};
@@ -2125,11 +2294,11 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
2125
2294
  setError(e instanceof Error ? e.message : String(e));
2126
2295
  }
2127
2296
  };
2128
- return /* @__PURE__ */ jsxs13("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "type-options", children: [
2129
- /* @__PURE__ */ jsxs13("div", { className: "flex flex-wrap items-center gap-2", children: [
2130
- /* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-1", children: [
2297
+ return /* @__PURE__ */ jsxs14("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "type-options", children: [
2298
+ /* @__PURE__ */ jsxs14("div", { className: "flex flex-wrap items-center gap-2", children: [
2299
+ /* @__PURE__ */ jsxs14("label", { className: "flex items-center gap-1", children: [
2131
2300
  "Font",
2132
- /* @__PURE__ */ jsx13(
2301
+ /* @__PURE__ */ jsx15(
2133
2302
  "input",
2134
2303
  {
2135
2304
  list: "pixerate-type-fonts",
@@ -2139,11 +2308,11 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
2139
2308
  className: "w-32 rounded border border-slate-700 bg-slate-950 px-1 py-0.5"
2140
2309
  }
2141
2310
  ),
2142
- /* @__PURE__ */ jsx13("datalist", { id: "pixerate-type-fonts", children: fonts.map((f) => /* @__PURE__ */ jsx13("option", { value: f }, f)) })
2311
+ /* @__PURE__ */ jsx15("datalist", { id: "pixerate-type-fonts", children: fonts.map((f) => /* @__PURE__ */ jsx15("option", { value: f }, f)) })
2143
2312
  ] }),
2144
- /* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-1", children: [
2313
+ /* @__PURE__ */ jsxs14("label", { className: "flex items-center gap-1", children: [
2145
2314
  "Size",
2146
- /* @__PURE__ */ jsx13(
2315
+ /* @__PURE__ */ jsx15(
2147
2316
  "input",
2148
2317
  {
2149
2318
  type: "number",
@@ -2156,24 +2325,24 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
2156
2325
  }
2157
2326
  )
2158
2327
  ] }),
2159
- /* @__PURE__ */ jsx13("button", { type: "button", "aria-pressed": shown.fontWeight >= 600, className: `${chip5(shown.fontWeight >= 600)} font-bold`, onClick: () => style({ fontWeight: shown.fontWeight >= 600 ? 400 : 700 }), children: "B" }),
2160
- /* @__PURE__ */ jsx13("button", { type: "button", "aria-pressed": shown.italic, className: `${chip5(shown.italic)} italic`, onClick: () => style({ italic: !shown.italic }), children: "I" }),
2161
- /* @__PURE__ */ jsx13("input", { type: "color", "aria-label": "Text colour", value: shown.color, onChange: (e) => style({ color: e.target.value }), className: "h-6 w-8 rounded border border-slate-700 bg-transparent" })
2328
+ /* @__PURE__ */ jsx15("button", { type: "button", "aria-pressed": shown.fontWeight >= 600, className: `${chip5(shown.fontWeight >= 600)} font-bold`, onClick: () => style({ fontWeight: shown.fontWeight >= 600 ? 400 : 700 }), children: "B" }),
2329
+ /* @__PURE__ */ jsx15("button", { type: "button", "aria-pressed": shown.italic, className: `${chip5(shown.italic)} italic`, onClick: () => style({ italic: !shown.italic }), children: "I" }),
2330
+ /* @__PURE__ */ jsx15("input", { type: "color", "aria-label": "Text colour", value: shown.color, onChange: (e) => style({ color: e.target.value }), className: "h-6 w-8 rounded border border-slate-700 bg-transparent" })
2162
2331
  ] }),
2163
- /* @__PURE__ */ jsx13("div", { className: "flex gap-1", role: "toolbar", "aria-label": "Alignment", children: TEXT_ALIGNS.map((a) => /* @__PURE__ */ jsx13("button", { type: "button", "aria-pressed": options.align === a, className: chip5(options.align === a), onClick: () => style({ align: a }), children: ALIGN_LABELS[a] }, a)) }),
2164
- /* @__PURE__ */ jsx13("p", { className: "text-[10px] text-slate-500", children: "Click to type point text, drag for a paragraph box, click text to edit it. Esc finishes." }),
2165
- missing.length > 0 && /* @__PURE__ */ jsxs13("p", { role: "status", className: "text-amber-400", "data-testid": "type-missing-fonts", children: [
2332
+ /* @__PURE__ */ jsx15("div", { className: "flex gap-1", role: "toolbar", "aria-label": "Alignment", children: TEXT_ALIGNS.map((a) => /* @__PURE__ */ jsx15("button", { type: "button", "aria-pressed": options.align === a, className: chip5(options.align === a), onClick: () => style({ align: a }), children: ALIGN_LABELS[a] }, a)) }),
2333
+ /* @__PURE__ */ jsx15("p", { className: "text-[10px] text-slate-500", children: "Click to type point text, drag for a paragraph box, click text to edit it. Esc finishes." }),
2334
+ missing.length > 0 && /* @__PURE__ */ jsxs14("p", { role: "status", className: "text-amber-400", "data-testid": "type-missing-fonts", children: [
2166
2335
  "Missing ",
2167
2336
  missing.length === 1 ? "font" : "fonts",
2168
2337
  ": ",
2169
2338
  missing.join(", ")
2170
2339
  ] }),
2171
- error && /* @__PURE__ */ jsx13("p", { role: "alert", className: "text-rose-400", children: error })
2340
+ error && /* @__PURE__ */ jsx15("p", { role: "alert", className: "text-rose-400", children: error })
2172
2341
  ] });
2173
2342
  };
2174
2343
 
2175
2344
  // src/image-editor/ImageEditor.tsx
2176
- import { Fragment as Fragment5, jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
2345
+ import { Fragment as Fragment5, jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
2177
2346
  var ImageEditor = ({
2178
2347
  editor: externalEditor,
2179
2348
  src,
@@ -2183,17 +2352,22 @@ var ImageEditor = ({
2183
2352
  exportOptions,
2184
2353
  onInpaint,
2185
2354
  onRemoveBackground,
2186
- aiHooks
2355
+ aiHooks,
2356
+ effects
2187
2357
  }) => {
2188
2358
  const internalEditor = useImageEditor({ image: src });
2189
2359
  const editor = externalEditor || internalEditor;
2190
2360
  const { state, controller } = editor;
2361
+ useEffects(controller, effects);
2362
+ const effectsShown = !!controller.effectsProvider || state.layers.some(function has(l) {
2363
+ return l.type === "pixel" && !!l.generator || l.type === "smart" && !!l.smartFilters?.filters.some((f) => f.kind === "effect") || l.type === "group" && l.children.some(has);
2364
+ });
2191
2365
  const legacyProcess = normalizeProcessVersion(state.adjustments.process) < LATEST_PROCESS_VERSION;
2192
2366
  const canvasRef = useRef5(null);
2193
2367
  const containerRef = useRef5(null);
2194
- const [activeTab, setActiveTab] = useState14("crop");
2195
- const [activeCropRatio, setActiveCropRatio] = useState14(null);
2196
- const [selectionOptions, setSelectionOptions] = useState14(DEFAULT_SELECTION_TOOL_OPTIONS);
2368
+ const [activeTab, setActiveTab] = useState15("crop");
2369
+ const [activeCropRatio, setActiveCropRatio] = useState15(null);
2370
+ const [selectionOptions, setSelectionOptions] = useState15(DEFAULT_SELECTION_TOOL_OPTIONS);
2197
2371
  const selectionOptionsRef = useRef5(selectionOptions);
2198
2372
  selectionOptionsRef.current = selectionOptions;
2199
2373
  const selectionGestureRef = useRef5(null);
@@ -2201,7 +2375,7 @@ var ImageEditor = ({
2201
2375
  selectionGestureRef.current = new SelectionGesture(controller, () => selectionOptionsRef.current);
2202
2376
  }
2203
2377
  const selectionDraftRef = useRef5(null);
2204
- const [selectionError, setSelectionError] = useState14(null);
2378
+ const [selectionError, setSelectionError] = useState15(null);
2205
2379
  const paintGestureRef = useRef5(null);
2206
2380
  const paintControllerRef = useRef5(controller);
2207
2381
  if (!paintGestureRef.current || paintControllerRef.current !== controller) {
@@ -2209,7 +2383,7 @@ var ImageEditor = ({
2209
2383
  paintControllerRef.current = controller;
2210
2384
  }
2211
2385
  const brushCursorRef = useRef5(null);
2212
- const [paintError, setPaintError] = useState14(null);
2386
+ const [paintError, setPaintError] = useState15(null);
2213
2387
  const transformToolRef = useRef5(null);
2214
2388
  const transformControllerRef = useRef5(controller);
2215
2389
  if (!transformToolRef.current || transformControllerRef.current !== controller) {
@@ -2220,12 +2394,12 @@ var ImageEditor = ({
2220
2394
  transformControllerRef.current = controller;
2221
2395
  }
2222
2396
  const transformTool = transformToolRef.current;
2223
- const [, setTransformTick] = useState14(0);
2224
- const [transformCursor, setTransformCursor] = useState14("default");
2225
- const [shapeOptions, setShapeOptions] = useState14(DEFAULT_SHAPE_TOOL_OPTIONS);
2397
+ const [, setTransformTick] = useState15(0);
2398
+ const [transformCursor, setTransformCursor] = useState15("default");
2399
+ const [shapeOptions, setShapeOptions] = useState15(DEFAULT_SHAPE_TOOL_OPTIONS);
2226
2400
  const shapeOptionsRef = useRef5(shapeOptions);
2227
2401
  shapeOptionsRef.current = shapeOptions;
2228
- const [typeOptions, setTypeOptions] = useState14(DEFAULT_TYPE_TOOL_OPTIONS);
2402
+ const [typeOptions, setTypeOptions] = useState15(DEFAULT_TYPE_TOOL_OPTIONS);
2229
2403
  const typeOptionsRef = useRef5(typeOptions);
2230
2404
  typeOptionsRef.current = typeOptions;
2231
2405
  const shapeGestureRef = useRef5(null);
@@ -2238,15 +2412,15 @@ var ImageEditor = ({
2238
2412
  shapeTypeControllerRef.current = controller;
2239
2413
  }
2240
2414
  const typeInputRef = useRef5(null);
2241
- const [typeSession, setTypeSession] = useState14(typeToolRef.current.session);
2242
- const [shapeTypeError, setShapeTypeError] = useState14(null);
2243
- const [inpaintPrompt, setInpaintPrompt] = useState14("");
2244
- const [inpaintMaskMode, setInpaintMaskMode] = useState14("annotations");
2245
- const [isRemovingBg, setIsRemovingBg] = useState14(false);
2246
- const [isInpainting, setIsInpainting] = useState14(false);
2247
- const [aiError, setAiError] = useState14(null);
2248
- const [aiSuccess, setAiSuccess] = useState14(null);
2249
- const [aiTarget, setAiTarget] = useState14("auto");
2415
+ const [typeSession, setTypeSession] = useState15(typeToolRef.current.session);
2416
+ const [shapeTypeError, setShapeTypeError] = useState15(null);
2417
+ const [inpaintPrompt, setInpaintPrompt] = useState15("");
2418
+ const [inpaintMaskMode, setInpaintMaskMode] = useState15("annotations");
2419
+ const [isRemovingBg, setIsRemovingBg] = useState15(false);
2420
+ const [isInpainting, setIsInpainting] = useState15(false);
2421
+ const [aiError, setAiError] = useState15(null);
2422
+ const [aiSuccess, setAiSuccess] = useState15(null);
2423
+ const [aiTarget, setAiTarget] = useState15("auto");
2250
2424
  const aiOptions = aiTarget === "auto" ? {} : { target: aiTarget };
2251
2425
  const effectiveOnInpaint = onInpaint || aiHooks?.onInpaint;
2252
2426
  const effectiveOnRemoveBg = onRemoveBackground || aiHooks?.onRemoveBackground;
@@ -2309,10 +2483,10 @@ var ImageEditor = ({
2309
2483
  setIsInpainting(false);
2310
2484
  }
2311
2485
  };
2312
- const [activeColor, setActiveColor] = useState14("#ef4444");
2313
- const [strokeWidth, setStrokeWidth] = useState14(3);
2314
- const [fontSize, setFontSize] = useState14(24);
2315
- const [textInput, setTextInput] = useState14("");
2486
+ const [activeColor, setActiveColor] = useState15("#ef4444");
2487
+ const [strokeWidth, setStrokeWidth] = useState15(3);
2488
+ const [fontSize, setFontSize] = useState15(24);
2489
+ const [textInput, setTextInput] = useState15("");
2316
2490
  const draftAnnotationRef = useRef5(null);
2317
2491
  const draftCropRef = useRef5(null);
2318
2492
  const cropDragInfoRef = useRef5(null);
@@ -2343,8 +2517,8 @@ var ImageEditor = ({
2343
2517
  },
2344
2518
  [controller, activeTab, transformTool]
2345
2519
  );
2346
- useEffect11(() => typeSession?.subscribe(() => void renderCanvas()), [typeSession, renderCanvas]);
2347
- useEffect11(() => {
2520
+ useEffect12(() => typeSession?.subscribe(() => void renderCanvas()), [typeSession, renderCanvas]);
2521
+ useEffect12(() => {
2348
2522
  if (activeTab === "annotate" && state.activeTool === "type") return;
2349
2523
  if (typeToolRef.current?.session) {
2350
2524
  typeToolRef.current.finish();
@@ -2379,7 +2553,7 @@ var ImageEditor = ({
2379
2553
  el.value = "";
2380
2554
  }
2381
2555
  };
2382
- useEffect11(() => transformTool.subscribe(() => {
2556
+ useEffect12(() => transformTool.subscribe(() => {
2383
2557
  setTransformTick((n) => n + 1);
2384
2558
  void renderCanvas();
2385
2559
  }), [transformTool, renderCanvas]);
@@ -2422,7 +2596,7 @@ var ImageEditor = ({
2422
2596
  transformTool.up();
2423
2597
  return true;
2424
2598
  };
2425
- useEffect11(() => {
2599
+ useEffect12(() => {
2426
2600
  if (typeof window === "undefined") return;
2427
2601
  const onKey = (e) => {
2428
2602
  if (transformTool.key(e)) e.preventDefault();
@@ -2430,7 +2604,7 @@ var ImageEditor = ({
2430
2604
  window.addEventListener("keydown", onKey);
2431
2605
  return () => window.removeEventListener("keydown", onKey);
2432
2606
  }, [transformTool]);
2433
- useEffect11(() => {
2607
+ useEffect12(() => {
2434
2608
  const raf = typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : (cb) => setTimeout(cb, 0);
2435
2609
  const caf = typeof cancelAnimationFrame !== "undefined" ? cancelAnimationFrame : (id) => clearTimeout(id);
2436
2610
  const animId = raf(() => {
@@ -2438,12 +2612,12 @@ var ImageEditor = ({
2438
2612
  });
2439
2613
  return () => caf(animId);
2440
2614
  }, [renderCanvas, state]);
2441
- useEffect11(() => {
2615
+ useEffect12(() => {
2442
2616
  if (activeTab === "crop" && editor.state.activeTool !== "crop") {
2443
2617
  editor.setTool("crop");
2444
2618
  }
2445
2619
  }, [activeTab, editor]);
2446
- useEffect11(() => {
2620
+ useEffect12(() => {
2447
2621
  const container = containerRef.current;
2448
2622
  if (!container) return;
2449
2623
  if (typeof ResizeObserver !== "undefined") {
@@ -2511,7 +2685,7 @@ var ImageEditor = ({
2511
2685
  if (g.error) setPaintError(g.error);
2512
2686
  }
2513
2687
  };
2514
- useEffect11(() => {
2688
+ useEffect12(() => {
2515
2689
  if (activeTab !== "paint" || typeof window === "undefined") return;
2516
2690
  const onKey = (e) => {
2517
2691
  if (handlePaintShortcut(controller, e)) e.preventDefault();
@@ -2906,15 +3080,15 @@ var ImageEditor = ({
2906
3080
  link.click();
2907
3081
  }
2908
3082
  };
2909
- return /* @__PURE__ */ jsxs14(
3083
+ return /* @__PURE__ */ jsxs15(
2910
3084
  "div",
2911
3085
  {
2912
3086
  className: `flex flex-col bg-slate-900 border border-slate-800 rounded-xl overflow-hidden shadow-2xl text-slate-100 ${className}`,
2913
3087
  style,
2914
3088
  children: [
2915
- /* @__PURE__ */ jsxs14("div", { className: "flex flex-wrap items-center justify-between px-4 py-3 bg-slate-950/80 border-b border-slate-800 gap-3", children: [
2916
- /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-1 bg-slate-900 p-1 rounded-lg border border-slate-800 text-xs", children: [
2917
- /* @__PURE__ */ jsx14(
3089
+ /* @__PURE__ */ jsxs15("div", { className: "flex flex-wrap items-center justify-between px-4 py-3 bg-slate-950/80 border-b border-slate-800 gap-3", children: [
3090
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-1 bg-slate-900 p-1 rounded-lg border border-slate-800 text-xs", children: [
3091
+ /* @__PURE__ */ jsx16(
2918
3092
  "button",
2919
3093
  {
2920
3094
  type: "button",
@@ -2926,7 +3100,7 @@ var ImageEditor = ({
2926
3100
  children: "Transform & Crop"
2927
3101
  }
2928
3102
  ),
2929
- /* @__PURE__ */ jsx14(
3103
+ /* @__PURE__ */ jsx16(
2930
3104
  "button",
2931
3105
  {
2932
3106
  type: "button",
@@ -2938,7 +3112,7 @@ var ImageEditor = ({
2938
3112
  children: "Adjustments"
2939
3113
  }
2940
3114
  ),
2941
- /* @__PURE__ */ jsx14(
3115
+ /* @__PURE__ */ jsx16(
2942
3116
  "button",
2943
3117
  {
2944
3118
  type: "button",
@@ -2950,7 +3124,7 @@ var ImageEditor = ({
2950
3124
  children: "Layers"
2951
3125
  }
2952
3126
  ),
2953
- /* @__PURE__ */ jsx14(
3127
+ /* @__PURE__ */ jsx16(
2954
3128
  "button",
2955
3129
  {
2956
3130
  type: "button",
@@ -2962,7 +3136,7 @@ var ImageEditor = ({
2962
3136
  children: "Paint"
2963
3137
  }
2964
3138
  ),
2965
- /* @__PURE__ */ jsx14(
3139
+ /* @__PURE__ */ jsx16(
2966
3140
  "button",
2967
3141
  {
2968
3142
  type: "button",
@@ -2974,7 +3148,7 @@ var ImageEditor = ({
2974
3148
  children: "Select & Mask"
2975
3149
  }
2976
3150
  ),
2977
- /* @__PURE__ */ jsx14(
3151
+ /* @__PURE__ */ jsx16(
2978
3152
  "button",
2979
3153
  {
2980
3154
  type: "button",
@@ -2986,7 +3160,7 @@ var ImageEditor = ({
2986
3160
  children: "Annotations"
2987
3161
  }
2988
3162
  ),
2989
- /* @__PURE__ */ jsx14(
3163
+ /* @__PURE__ */ jsx16(
2990
3164
  "button",
2991
3165
  {
2992
3166
  type: "button",
@@ -2998,7 +3172,7 @@ var ImageEditor = ({
2998
3172
  children: "Depth Mask"
2999
3173
  }
3000
3174
  ),
3001
- /* @__PURE__ */ jsxs14(
3175
+ /* @__PURE__ */ jsxs15(
3002
3176
  "button",
3003
3177
  {
3004
3178
  type: "button",
@@ -3008,14 +3182,14 @@ var ImageEditor = ({
3008
3182
  },
3009
3183
  className: `px-3 py-1.5 rounded-md font-medium transition-colors flex items-center gap-1.5 ${activeTab === "ai" ? "bg-indigo-600 text-white shadow" : "text-slate-400 hover:text-slate-200"}`,
3010
3184
  children: [
3011
- /* @__PURE__ */ jsx14("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx14("path", { d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" }) }),
3185
+ /* @__PURE__ */ jsx16("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx16("path", { d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" }) }),
3012
3186
  "AI Tools"
3013
3187
  ]
3014
3188
  }
3015
3189
  )
3016
3190
  ] }),
3017
- /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2 text-xs", children: [
3018
- /* @__PURE__ */ jsx14(
3191
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2 text-xs", children: [
3192
+ /* @__PURE__ */ jsx16(
3019
3193
  "button",
3020
3194
  {
3021
3195
  type: "button",
@@ -3026,7 +3200,7 @@ var ImageEditor = ({
3026
3200
  children: "\u21A9"
3027
3201
  }
3028
3202
  ),
3029
- /* @__PURE__ */ jsx14(
3203
+ /* @__PURE__ */ jsx16(
3030
3204
  "button",
3031
3205
  {
3032
3206
  type: "button",
@@ -3037,7 +3211,7 @@ var ImageEditor = ({
3037
3211
  children: "\u21AA"
3038
3212
  }
3039
3213
  ),
3040
- /* @__PURE__ */ jsx14(
3214
+ /* @__PURE__ */ jsx16(
3041
3215
  "button",
3042
3216
  {
3043
3217
  type: "button",
@@ -3046,8 +3220,8 @@ var ImageEditor = ({
3046
3220
  children: "Reset"
3047
3221
  }
3048
3222
  ),
3049
- /* @__PURE__ */ jsx14("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
3050
- /* @__PURE__ */ jsx14(
3223
+ /* @__PURE__ */ jsx16("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
3224
+ /* @__PURE__ */ jsx16(
3051
3225
  "button",
3052
3226
  {
3053
3227
  type: "button",
@@ -3057,11 +3231,11 @@ var ImageEditor = ({
3057
3231
  children: "-"
3058
3232
  }
3059
3233
  ),
3060
- /* @__PURE__ */ jsxs14("span", { className: "font-mono text-slate-400 w-10 text-center", children: [
3234
+ /* @__PURE__ */ jsxs15("span", { className: "font-mono text-slate-400 w-10 text-center", children: [
3061
3235
  Math.round(state.zoom * 100),
3062
3236
  "%"
3063
3237
  ] }),
3064
- /* @__PURE__ */ jsx14(
3238
+ /* @__PURE__ */ jsx16(
3065
3239
  "button",
3066
3240
  {
3067
3241
  type: "button",
@@ -3071,8 +3245,8 @@ var ImageEditor = ({
3071
3245
  children: "+"
3072
3246
  }
3073
3247
  ),
3074
- /* @__PURE__ */ jsx14("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
3075
- /* @__PURE__ */ jsx14(
3248
+ /* @__PURE__ */ jsx16("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
3249
+ /* @__PURE__ */ jsx16(
3076
3250
  "button",
3077
3251
  {
3078
3252
  type: "button",
@@ -3083,7 +3257,7 @@ var ImageEditor = ({
3083
3257
  children: "Hold Compare"
3084
3258
  }
3085
3259
  ),
3086
- /* @__PURE__ */ jsx14(
3260
+ /* @__PURE__ */ jsx16(
3087
3261
  "button",
3088
3262
  {
3089
3263
  type: "button",
@@ -3094,16 +3268,16 @@ var ImageEditor = ({
3094
3268
  )
3095
3269
  ] })
3096
3270
  ] }),
3097
- transformTool.active && /* @__PURE__ */ jsx14(FreeTransformOptionsBar, { tool: transformTool, className: "border-b border-slate-800 bg-slate-900/95 px-4 py-2" }),
3098
- !transformTool.active && transformTool.error && /* @__PURE__ */ jsx14("div", { role: "alert", className: "border-b border-rose-900 bg-rose-950/80 px-4 py-1.5 text-xs text-rose-200", children: transformTool.error }),
3099
- /* @__PURE__ */ jsxs14("div", { className: "flex flex-col md:flex-row flex-1 min-h-[520px] md:h-[560px]", children: [
3100
- /* @__PURE__ */ jsxs14(
3271
+ transformTool.active && /* @__PURE__ */ jsx16(FreeTransformOptionsBar, { tool: transformTool, className: "border-b border-slate-800 bg-slate-900/95 px-4 py-2" }),
3272
+ !transformTool.active && transformTool.error && /* @__PURE__ */ jsx16("div", { role: "alert", className: "border-b border-rose-900 bg-rose-950/80 px-4 py-1.5 text-xs text-rose-200", children: transformTool.error }),
3273
+ /* @__PURE__ */ jsxs15("div", { className: "flex flex-col md:flex-row flex-1 min-h-[520px] md:h-[560px]", children: [
3274
+ /* @__PURE__ */ jsxs15(
3101
3275
  "div",
3102
3276
  {
3103
3277
  ref: containerRef,
3104
3278
  className: "relative flex-1 h-[360px] md:h-full min-h-[320px] bg-slate-950 overflow-hidden select-none",
3105
3279
  children: [
3106
- /* @__PURE__ */ jsx14(
3280
+ /* @__PURE__ */ jsx16(
3107
3281
  "canvas",
3108
3282
  {
3109
3283
  ref: canvasRef,
@@ -3120,7 +3294,7 @@ var ImageEditor = ({
3120
3294
  className: `absolute inset-0 w-full h-full block ${transformTool.active ? "touch-none" : activeTab === "paint" ? "touch-none cursor-crosshair" : activeTab === "annotate" && state.activeTool === "type" ? "cursor-text" : activeTab === "annotate" && state.activeTool === "shape" ? "cursor-crosshair" : ""}`
3121
3295
  }
3122
3296
  ),
3123
- typeSession && /* @__PURE__ */ jsx14(
3297
+ typeSession && /* @__PURE__ */ jsx16(
3124
3298
  "textarea",
3125
3299
  {
3126
3300
  ref: typeInputRef,
@@ -3142,11 +3316,11 @@ var ImageEditor = ({
3142
3316
  ]
3143
3317
  }
3144
3318
  ),
3145
- /* @__PURE__ */ jsxs14("div", { className: "w-full md:w-80 bg-slate-900/90 border-t md:border-t-0 md:border-l border-slate-800 p-4 overflow-y-auto h-auto md:h-full md:max-h-[560px]", children: [
3146
- activeTab === "crop" && /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-4 text-xs", children: [
3147
- /* @__PURE__ */ jsx14("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Aspect Ratio Presets" }),
3148
- /* @__PURE__ */ jsxs14("div", { className: "grid grid-cols-3 gap-2", children: [
3149
- /* @__PURE__ */ jsx14(
3319
+ /* @__PURE__ */ jsxs15("div", { className: "w-full md:w-80 bg-slate-900/90 border-t md:border-t-0 md:border-l border-slate-800 p-4 overflow-y-auto h-auto md:h-full md:max-h-[560px]", children: [
3320
+ activeTab === "crop" && /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-4 text-xs", children: [
3321
+ /* @__PURE__ */ jsx16("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Aspect Ratio Presets" }),
3322
+ /* @__PURE__ */ jsxs15("div", { className: "grid grid-cols-3 gap-2", children: [
3323
+ /* @__PURE__ */ jsx16(
3150
3324
  "button",
3151
3325
  {
3152
3326
  type: "button",
@@ -3158,7 +3332,7 @@ var ImageEditor = ({
3158
3332
  children: "Freeform"
3159
3333
  }
3160
3334
  ),
3161
- /* @__PURE__ */ jsx14(
3335
+ /* @__PURE__ */ jsx16(
3162
3336
  "button",
3163
3337
  {
3164
3338
  type: "button",
@@ -3170,7 +3344,7 @@ var ImageEditor = ({
3170
3344
  children: "1:1 Square"
3171
3345
  }
3172
3346
  ),
3173
- /* @__PURE__ */ jsx14(
3347
+ /* @__PURE__ */ jsx16(
3174
3348
  "button",
3175
3349
  {
3176
3350
  type: "button",
@@ -3182,7 +3356,7 @@ var ImageEditor = ({
3182
3356
  children: "4:3 Standard"
3183
3357
  }
3184
3358
  ),
3185
- /* @__PURE__ */ jsx14(
3359
+ /* @__PURE__ */ jsx16(
3186
3360
  "button",
3187
3361
  {
3188
3362
  type: "button",
@@ -3194,7 +3368,7 @@ var ImageEditor = ({
3194
3368
  children: "16:9 Wide"
3195
3369
  }
3196
3370
  ),
3197
- /* @__PURE__ */ jsx14(
3371
+ /* @__PURE__ */ jsx16(
3198
3372
  "button",
3199
3373
  {
3200
3374
  type: "button",
@@ -3206,7 +3380,7 @@ var ImageEditor = ({
3206
3380
  children: "3:2 Photo"
3207
3381
  }
3208
3382
  ),
3209
- /* @__PURE__ */ jsx14(
3383
+ /* @__PURE__ */ jsx16(
3210
3384
  "button",
3211
3385
  {
3212
3386
  type: "button",
@@ -3219,10 +3393,10 @@ var ImageEditor = ({
3219
3393
  }
3220
3394
  )
3221
3395
  ] }),
3222
- /* @__PURE__ */ jsx14("div", { className: "h-px bg-slate-800 my-1" }),
3223
- /* @__PURE__ */ jsx14("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Orientation & Flips" }),
3224
- /* @__PURE__ */ jsxs14("div", { className: "grid grid-cols-2 gap-2", children: [
3225
- /* @__PURE__ */ jsx14(
3396
+ /* @__PURE__ */ jsx16("div", { className: "h-px bg-slate-800 my-1" }),
3397
+ /* @__PURE__ */ jsx16("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Orientation & Flips" }),
3398
+ /* @__PURE__ */ jsxs15("div", { className: "grid grid-cols-2 gap-2", children: [
3399
+ /* @__PURE__ */ jsx16(
3226
3400
  "button",
3227
3401
  {
3228
3402
  type: "button",
@@ -3231,7 +3405,7 @@ var ImageEditor = ({
3231
3405
  children: "Rotate -90\xB0"
3232
3406
  }
3233
3407
  ),
3234
- /* @__PURE__ */ jsx14(
3408
+ /* @__PURE__ */ jsx16(
3235
3409
  "button",
3236
3410
  {
3237
3411
  type: "button",
@@ -3240,7 +3414,7 @@ var ImageEditor = ({
3240
3414
  children: "Rotate +90\xB0"
3241
3415
  }
3242
3416
  ),
3243
- /* @__PURE__ */ jsx14(
3417
+ /* @__PURE__ */ jsx16(
3244
3418
  "button",
3245
3419
  {
3246
3420
  type: "button",
@@ -3249,7 +3423,7 @@ var ImageEditor = ({
3249
3423
  children: "Flip Horizontal"
3250
3424
  }
3251
3425
  ),
3252
- /* @__PURE__ */ jsx14(
3426
+ /* @__PURE__ */ jsx16(
3253
3427
  "button",
3254
3428
  {
3255
3429
  type: "button",
@@ -3260,10 +3434,10 @@ var ImageEditor = ({
3260
3434
  )
3261
3435
  ] })
3262
3436
  ] }),
3263
- activeTab === "adjust" && /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-3 text-xs", children: [
3264
- /* @__PURE__ */ jsxs14("div", { className: "flex items-center justify-between", children: [
3265
- /* @__PURE__ */ jsx14("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Color Adjustments" }),
3266
- /* @__PURE__ */ jsx14(
3437
+ activeTab === "adjust" && /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-3 text-xs", children: [
3438
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between", children: [
3439
+ /* @__PURE__ */ jsx16("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Color Adjustments" }),
3440
+ /* @__PURE__ */ jsx16(
3267
3441
  "button",
3268
3442
  {
3269
3443
  type: "button",
@@ -3273,9 +3447,9 @@ var ImageEditor = ({
3273
3447
  }
3274
3448
  )
3275
3449
  ] }),
3276
- /* @__PURE__ */ jsx14(Histogram, { histogram: editor.histogram }),
3277
- IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */ jsxs14(React13.Fragment, { children: [
3278
- /* @__PURE__ */ jsx14(
3450
+ /* @__PURE__ */ jsx16(Histogram, { histogram: editor.histogram }),
3451
+ IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */ jsxs15(React14.Fragment, { children: [
3452
+ /* @__PURE__ */ jsx16(
3279
3453
  ControlSlider,
3280
3454
  {
3281
3455
  spec,
@@ -3284,14 +3458,14 @@ var ImageEditor = ({
3284
3458
  onChange: (v) => editor.setAdjustments({ [spec.id]: v })
3285
3459
  }
3286
3460
  ),
3287
- spec.id === "tint" && legacyProcess && /* @__PURE__ */ jsxs14(
3461
+ spec.id === "tint" && legacyProcess && /* @__PURE__ */ jsxs15(
3288
3462
  "div",
3289
3463
  {
3290
3464
  className: "flex items-center justify-between gap-2 rounded border border-amber-500/30 bg-amber-500/10 px-2 py-1.5 text-[10px] text-amber-200",
3291
3465
  "data-testid": "image-editor-process-notice",
3292
3466
  children: [
3293
- /* @__PURE__ */ jsx14("span", { children: "Legacy rendering (process 1). Tint needs the current process." }),
3294
- /* @__PURE__ */ jsx14(
3467
+ /* @__PURE__ */ jsx16("span", { children: "Legacy rendering (process 1). Tint needs the current process." }),
3468
+ /* @__PURE__ */ jsx16(
3295
3469
  "button",
3296
3470
  {
3297
3471
  type: "button",
@@ -3304,7 +3478,7 @@ var ImageEditor = ({
3304
3478
  }
3305
3479
  )
3306
3480
  ] }, spec.id)),
3307
- /* @__PURE__ */ jsx14("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ jsx14(
3481
+ /* @__PURE__ */ jsx16("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ jsx16(
3308
3482
  AdjustmentLayersPanel,
3309
3483
  {
3310
3484
  controller,
@@ -3313,9 +3487,9 @@ var ImageEditor = ({
3313
3487
  }
3314
3488
  ) })
3315
3489
  ] }),
3316
- activeTab === "layers" && /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-3 text-xs", children: [
3317
- /* @__PURE__ */ jsx14("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Layers" }),
3318
- /* @__PURE__ */ jsx14(
3490
+ activeTab === "layers" && /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-3 text-xs", children: [
3491
+ /* @__PURE__ */ jsx16("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Layers" }),
3492
+ /* @__PURE__ */ jsx16(
3319
3493
  "button",
3320
3494
  {
3321
3495
  type: "button",
@@ -3326,14 +3500,15 @@ var ImageEditor = ({
3326
3500
  children: "Free Transform"
3327
3501
  }
3328
3502
  ),
3329
- /* @__PURE__ */ jsx14(LayersPanel, { controller }),
3330
- /* @__PURE__ */ jsx14("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Colour" }),
3331
- /* @__PURE__ */ jsx14(ColorProfilePanel, { controller })
3503
+ /* @__PURE__ */ jsx16(LayersPanel, { controller }),
3504
+ effectsShown && /* @__PURE__ */ jsx16(ImageProviderEffectsPanel, { controller, className: "border-t border-slate-700/60 pt-3" }),
3505
+ /* @__PURE__ */ jsx16("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Colour" }),
3506
+ /* @__PURE__ */ jsx16(ColorProfilePanel, { controller })
3332
3507
  ] }),
3333
- activeTab === "paint" && /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-3 text-xs", children: [
3334
- /* @__PURE__ */ jsx14("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Paint" }),
3335
- /* @__PURE__ */ jsx14(BrushOptionsBar, { controller }),
3336
- /* @__PURE__ */ jsx14(
3508
+ activeTab === "paint" && /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-3 text-xs", children: [
3509
+ /* @__PURE__ */ jsx16("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Paint" }),
3510
+ /* @__PURE__ */ jsx16(BrushOptionsBar, { controller }),
3511
+ /* @__PURE__ */ jsx16(
3337
3512
  "button",
3338
3513
  {
3339
3514
  type: "button",
@@ -3344,12 +3519,12 @@ var ImageEditor = ({
3344
3519
  children: "Free Transform"
3345
3520
  }
3346
3521
  ),
3347
- paintError && /* @__PURE__ */ jsx14("p", { role: "alert", className: "text-rose-400", "data-testid": "paint-error", children: paintError }),
3348
- /* @__PURE__ */ jsx14("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ jsx14(LayersPanel, { controller }) })
3522
+ paintError && /* @__PURE__ */ jsx16("p", { role: "alert", className: "text-rose-400", "data-testid": "paint-error", children: paintError }),
3523
+ /* @__PURE__ */ jsx16("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ jsx16(LayersPanel, { controller }) })
3349
3524
  ] }),
3350
- activeTab === "annotate" && /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-3 text-xs", children: [
3351
- /* @__PURE__ */ jsx14("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Shape & Type Layers" }),
3352
- /* @__PURE__ */ jsx14("div", { className: "grid grid-cols-2 gap-1.5", children: ["shape", "type"].map((t) => /* @__PURE__ */ jsx14(
3525
+ activeTab === "annotate" && /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-3 text-xs", children: [
3526
+ /* @__PURE__ */ jsx16("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Shape & Type Layers" }),
3527
+ /* @__PURE__ */ jsx16("div", { className: "grid grid-cols-2 gap-1.5", children: ["shape", "type"].map((t) => /* @__PURE__ */ jsx16(
3353
3528
  "button",
3354
3529
  {
3355
3530
  type: "button",
@@ -3360,13 +3535,13 @@ var ImageEditor = ({
3360
3535
  },
3361
3536
  t
3362
3537
  )) }),
3363
- state.activeTool === "shape" && /* @__PURE__ */ jsx14(ShapeOptionsBar, { controller, options: shapeOptions, onChange: setShapeOptions }),
3364
- state.activeTool === "type" && /* @__PURE__ */ jsx14(TypeOptionsBar, { controller, options: typeOptions, onChange: setTypeOptions, session: typeSession }),
3365
- state.activeTool === "type" && typeSession && /* @__PURE__ */ jsx14("button", { type: "button", onClick: finishTyping, className: "self-start rounded bg-slate-800 px-2 py-1 text-[11px] text-slate-200 hover:bg-slate-700", children: "Done editing text" }),
3366
- shapeTypeError && /* @__PURE__ */ jsx14("p", { role: "alert", className: "text-rose-400", "data-testid": "shape-type-error", children: shapeTypeError }),
3367
- /* @__PURE__ */ jsx14("div", { className: "h-px bg-slate-800 my-1" }),
3368
- /* @__PURE__ */ jsx14("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Draw & Annotate" }),
3369
- /* @__PURE__ */ jsx14("div", { className: "grid grid-cols-3 gap-1.5", children: ["pen", "rect", "circle", "arrow", "line"].map((t) => /* @__PURE__ */ jsx14(
3538
+ state.activeTool === "shape" && /* @__PURE__ */ jsx16(ShapeOptionsBar, { controller, options: shapeOptions, onChange: setShapeOptions }),
3539
+ state.activeTool === "type" && /* @__PURE__ */ jsx16(TypeOptionsBar, { controller, options: typeOptions, onChange: setTypeOptions, session: typeSession }),
3540
+ state.activeTool === "type" && typeSession && /* @__PURE__ */ jsx16("button", { type: "button", onClick: finishTyping, className: "self-start rounded bg-slate-800 px-2 py-1 text-[11px] text-slate-200 hover:bg-slate-700", children: "Done editing text" }),
3541
+ shapeTypeError && /* @__PURE__ */ jsx16("p", { role: "alert", className: "text-rose-400", "data-testid": "shape-type-error", children: shapeTypeError }),
3542
+ /* @__PURE__ */ jsx16("div", { className: "h-px bg-slate-800 my-1" }),
3543
+ /* @__PURE__ */ jsx16("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Draw & Annotate" }),
3544
+ /* @__PURE__ */ jsx16("div", { className: "grid grid-cols-3 gap-1.5", children: ["pen", "rect", "circle", "arrow", "line"].map((t) => /* @__PURE__ */ jsx16(
3370
3545
  "button",
3371
3546
  {
3372
3547
  type: "button",
@@ -3376,9 +3551,9 @@ var ImageEditor = ({
3376
3551
  },
3377
3552
  t
3378
3553
  )) }),
3379
- /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2 mt-2", children: [
3380
- /* @__PURE__ */ jsx14("label", { className: "text-slate-400", children: "Color:" }),
3381
- /* @__PURE__ */ jsx14(
3554
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2 mt-2", children: [
3555
+ /* @__PURE__ */ jsx16("label", { className: "text-slate-400", children: "Color:" }),
3556
+ /* @__PURE__ */ jsx16(
3382
3557
  "input",
3383
3558
  {
3384
3559
  type: "color",
@@ -3387,15 +3562,15 @@ var ImageEditor = ({
3387
3562
  className: "w-8 h-8 rounded border border-slate-700 cursor-pointer bg-transparent"
3388
3563
  }
3389
3564
  ),
3390
- /* @__PURE__ */ jsxs14("div", { className: "flex-1 ml-2", children: [
3391
- /* @__PURE__ */ jsxs14("div", { className: "flex justify-between text-slate-400 mb-0.5", children: [
3392
- /* @__PURE__ */ jsx14("span", { children: "Width:" }),
3393
- /* @__PURE__ */ jsxs14("span", { className: "font-mono", children: [
3565
+ /* @__PURE__ */ jsxs15("div", { className: "flex-1 ml-2", children: [
3566
+ /* @__PURE__ */ jsxs15("div", { className: "flex justify-between text-slate-400 mb-0.5", children: [
3567
+ /* @__PURE__ */ jsx16("span", { children: "Width:" }),
3568
+ /* @__PURE__ */ jsxs15("span", { className: "font-mono", children: [
3394
3569
  strokeWidth,
3395
3570
  "px"
3396
3571
  ] })
3397
3572
  ] }),
3398
- /* @__PURE__ */ jsx14(
3573
+ /* @__PURE__ */ jsx16(
3399
3574
  "input",
3400
3575
  {
3401
3576
  type: "range",
@@ -3408,10 +3583,10 @@ var ImageEditor = ({
3408
3583
  )
3409
3584
  ] })
3410
3585
  ] }),
3411
- /* @__PURE__ */ jsx14("div", { className: "h-px bg-slate-800 my-1" }),
3412
- /* @__PURE__ */ jsx14("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Add Text" }),
3413
- /* @__PURE__ */ jsxs14("div", { className: "flex gap-2", children: [
3414
- /* @__PURE__ */ jsx14(
3586
+ /* @__PURE__ */ jsx16("div", { className: "h-px bg-slate-800 my-1" }),
3587
+ /* @__PURE__ */ jsx16("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Add Text" }),
3588
+ /* @__PURE__ */ jsxs15("div", { className: "flex gap-2", children: [
3589
+ /* @__PURE__ */ jsx16(
3415
3590
  "input",
3416
3591
  {
3417
3592
  type: "text",
@@ -3422,7 +3597,7 @@ var ImageEditor = ({
3422
3597
  className: "flex-1 bg-slate-950 border border-slate-700 rounded-lg px-2.5 py-1.5 text-xs text-slate-100 placeholder-slate-500 focus:outline-none focus:border-indigo-500"
3423
3598
  }
3424
3599
  ),
3425
- /* @__PURE__ */ jsx14(
3600
+ /* @__PURE__ */ jsx16(
3426
3601
  "button",
3427
3602
  {
3428
3603
  type: "button",
@@ -3432,14 +3607,14 @@ var ImageEditor = ({
3432
3607
  }
3433
3608
  )
3434
3609
  ] }),
3435
- /* @__PURE__ */ jsxs14("div", { className: "flex items-center justify-between text-slate-400", children: [
3436
- /* @__PURE__ */ jsx14("span", { children: "Font Size:" }),
3437
- /* @__PURE__ */ jsxs14("span", { className: "font-mono", children: [
3610
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between text-slate-400", children: [
3611
+ /* @__PURE__ */ jsx16("span", { children: "Font Size:" }),
3612
+ /* @__PURE__ */ jsxs15("span", { className: "font-mono", children: [
3438
3613
  fontSize,
3439
3614
  "px"
3440
3615
  ] })
3441
3616
  ] }),
3442
- /* @__PURE__ */ jsx14(
3617
+ /* @__PURE__ */ jsx16(
3443
3618
  "input",
3444
3619
  {
3445
3620
  type: "range",
@@ -3450,14 +3625,14 @@ var ImageEditor = ({
3450
3625
  className: "w-full accent-indigo-500"
3451
3626
  }
3452
3627
  ),
3453
- /* @__PURE__ */ jsx14("div", { className: "h-px bg-slate-800 my-1" }),
3454
- /* @__PURE__ */ jsxs14("div", { className: "flex items-center justify-between", children: [
3455
- /* @__PURE__ */ jsxs14("span", { className: "text-slate-400", children: [
3628
+ /* @__PURE__ */ jsx16("div", { className: "h-px bg-slate-800 my-1" }),
3629
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between", children: [
3630
+ /* @__PURE__ */ jsxs15("span", { className: "text-slate-400", children: [
3456
3631
  "Layers (",
3457
3632
  state.annotations.length,
3458
3633
  ")"
3459
3634
  ] }),
3460
- state.selectedAnnotationId && /* @__PURE__ */ jsx14(
3635
+ state.selectedAnnotationId && /* @__PURE__ */ jsx16(
3461
3636
  "button",
3462
3637
  {
3463
3638
  type: "button",
@@ -3466,7 +3641,7 @@ var ImageEditor = ({
3466
3641
  children: "Delete Selected"
3467
3642
  }
3468
3643
  ),
3469
- state.annotations.length > 0 && /* @__PURE__ */ jsx14(
3644
+ state.annotations.length > 0 && /* @__PURE__ */ jsx16(
3470
3645
  "button",
3471
3646
  {
3472
3647
  type: "button",
@@ -3477,10 +3652,10 @@ var ImageEditor = ({
3477
3652
  )
3478
3653
  ] })
3479
3654
  ] }),
3480
- activeTab === "depth" && /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-3 text-xs", children: [
3481
- /* @__PURE__ */ jsxs14("div", { className: "flex items-center justify-between", children: [
3482
- /* @__PURE__ */ jsx14("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Depth Masking" }),
3483
- /* @__PURE__ */ jsx14(
3655
+ activeTab === "depth" && /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-3 text-xs", children: [
3656
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between", children: [
3657
+ /* @__PURE__ */ jsx16("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Depth Masking" }),
3658
+ /* @__PURE__ */ jsx16(
3484
3659
  "button",
3485
3660
  {
3486
3661
  type: "button",
@@ -3490,8 +3665,8 @@ var ImageEditor = ({
3490
3665
  }
3491
3666
  )
3492
3667
  ] }),
3493
- /* @__PURE__ */ jsxs14("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300", children: [
3494
- /* @__PURE__ */ jsx14(
3668
+ /* @__PURE__ */ jsxs15("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300", children: [
3669
+ /* @__PURE__ */ jsx16(
3495
3670
  "input",
3496
3671
  {
3497
3672
  type: "checkbox",
@@ -3500,12 +3675,12 @@ var ImageEditor = ({
3500
3675
  className: "rounded accent-indigo-500"
3501
3676
  }
3502
3677
  ),
3503
- /* @__PURE__ */ jsx14("span", { children: "Enable Depth / Alpha Mask" })
3678
+ /* @__PURE__ */ jsx16("span", { children: "Enable Depth / Alpha Mask" })
3504
3679
  ] }),
3505
- state.depthMask.enabled && /* @__PURE__ */ jsxs14(Fragment5, { children: [
3506
- /* @__PURE__ */ jsxs14("div", { children: [
3507
- /* @__PURE__ */ jsx14("label", { className: "text-slate-400 block mb-1", children: "Mask Image URL:" }),
3508
- /* @__PURE__ */ jsx14(
3680
+ state.depthMask.enabled && /* @__PURE__ */ jsxs15(Fragment5, { children: [
3681
+ /* @__PURE__ */ jsxs15("div", { children: [
3682
+ /* @__PURE__ */ jsx16("label", { className: "text-slate-400 block mb-1", children: "Mask Image URL:" }),
3683
+ /* @__PURE__ */ jsx16(
3509
3684
  "input",
3510
3685
  {
3511
3686
  type: "text",
@@ -3516,8 +3691,8 @@ var ImageEditor = ({
3516
3691
  }
3517
3692
  )
3518
3693
  ] }),
3519
- /* @__PURE__ */ jsxs14("div", { className: "flex gap-2", children: [
3520
- /* @__PURE__ */ jsx14(
3694
+ /* @__PURE__ */ jsxs15("div", { className: "flex gap-2", children: [
3695
+ /* @__PURE__ */ jsx16(
3521
3696
  "button",
3522
3697
  {
3523
3698
  type: "button",
@@ -3526,7 +3701,7 @@ var ImageEditor = ({
3526
3701
  children: "Threshold Mode"
3527
3702
  }
3528
3703
  ),
3529
- /* @__PURE__ */ jsx14(
3704
+ /* @__PURE__ */ jsx16(
3530
3705
  "button",
3531
3706
  {
3532
3707
  type: "button",
@@ -3536,12 +3711,12 @@ var ImageEditor = ({
3536
3711
  }
3537
3712
  )
3538
3713
  ] }),
3539
- /* @__PURE__ */ jsxs14("div", { children: [
3540
- /* @__PURE__ */ jsxs14("div", { className: "flex justify-between text-slate-400 mb-1", children: [
3541
- /* @__PURE__ */ jsx14("span", { children: "Depth Start (Lower):" }),
3542
- /* @__PURE__ */ jsx14("span", { className: "font-mono", children: state.depthMask.depthRange[0] })
3714
+ /* @__PURE__ */ jsxs15("div", { children: [
3715
+ /* @__PURE__ */ jsxs15("div", { className: "flex justify-between text-slate-400 mb-1", children: [
3716
+ /* @__PURE__ */ jsx16("span", { children: "Depth Start (Lower):" }),
3717
+ /* @__PURE__ */ jsx16("span", { className: "font-mono", children: state.depthMask.depthRange[0] })
3543
3718
  ] }),
3544
- /* @__PURE__ */ jsx14(
3719
+ /* @__PURE__ */ jsx16(
3545
3720
  "input",
3546
3721
  {
3547
3722
  type: "range",
@@ -3555,12 +3730,12 @@ var ImageEditor = ({
3555
3730
  }
3556
3731
  )
3557
3732
  ] }),
3558
- /* @__PURE__ */ jsxs14("div", { children: [
3559
- /* @__PURE__ */ jsxs14("div", { className: "flex justify-between text-slate-400 mb-1", children: [
3560
- /* @__PURE__ */ jsx14("span", { children: "Depth Stop (Upper):" }),
3561
- /* @__PURE__ */ jsx14("span", { className: "font-mono", children: state.depthMask.depthRange[1] })
3733
+ /* @__PURE__ */ jsxs15("div", { children: [
3734
+ /* @__PURE__ */ jsxs15("div", { className: "flex justify-between text-slate-400 mb-1", children: [
3735
+ /* @__PURE__ */ jsx16("span", { children: "Depth Stop (Upper):" }),
3736
+ /* @__PURE__ */ jsx16("span", { className: "font-mono", children: state.depthMask.depthRange[1] })
3562
3737
  ] }),
3563
- /* @__PURE__ */ jsx14(
3738
+ /* @__PURE__ */ jsx16(
3564
3739
  "input",
3565
3740
  {
3566
3741
  type: "range",
@@ -3574,12 +3749,12 @@ var ImageEditor = ({
3574
3749
  }
3575
3750
  )
3576
3751
  ] }),
3577
- /* @__PURE__ */ jsxs14("div", { children: [
3578
- /* @__PURE__ */ jsxs14("div", { className: "flex justify-between text-slate-400 mb-1", children: [
3579
- /* @__PURE__ */ jsx14("span", { children: "Softness:" }),
3580
- /* @__PURE__ */ jsx14("span", { className: "font-mono", children: state.depthMask.softness })
3752
+ /* @__PURE__ */ jsxs15("div", { children: [
3753
+ /* @__PURE__ */ jsxs15("div", { className: "flex justify-between text-slate-400 mb-1", children: [
3754
+ /* @__PURE__ */ jsx16("span", { children: "Softness:" }),
3755
+ /* @__PURE__ */ jsx16("span", { className: "font-mono", children: state.depthMask.softness })
3581
3756
  ] }),
3582
- /* @__PURE__ */ jsx14(
3757
+ /* @__PURE__ */ jsx16(
3583
3758
  "input",
3584
3759
  {
3585
3760
  type: "range",
@@ -3591,8 +3766,8 @@ var ImageEditor = ({
3591
3766
  }
3592
3767
  )
3593
3768
  ] }),
3594
- /* @__PURE__ */ jsxs14("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300 mt-1", children: [
3595
- /* @__PURE__ */ jsx14(
3769
+ /* @__PURE__ */ jsxs15("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300 mt-1", children: [
3770
+ /* @__PURE__ */ jsx16(
3596
3771
  "input",
3597
3772
  {
3598
3773
  type: "checkbox",
@@ -3601,12 +3776,12 @@ var ImageEditor = ({
3601
3776
  className: "rounded accent-indigo-500"
3602
3777
  }
3603
3778
  ),
3604
- /* @__PURE__ */ jsx14("span", { children: "Invert Mask" })
3779
+ /* @__PURE__ */ jsx16("span", { children: "Invert Mask" })
3605
3780
  ] })
3606
3781
  ] })
3607
3782
  ] }),
3608
- activeTab === "select" && /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-4 text-xs", children: [
3609
- /* @__PURE__ */ jsx14(
3783
+ activeTab === "select" && /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-4 text-xs", children: [
3784
+ /* @__PURE__ */ jsx16(
3610
3785
  SelectionOptionsBar,
3611
3786
  {
3612
3787
  controller,
@@ -3616,9 +3791,9 @@ var ImageEditor = ({
3616
3791
  quickMask: Boolean(state.quickMask)
3617
3792
  }
3618
3793
  ),
3619
- selectionError && /* @__PURE__ */ jsx14("p", { role: "alert", className: "text-rose-400", children: selectionError }),
3620
- /* @__PURE__ */ jsxs14("div", { className: "flex gap-1", children: [
3621
- /* @__PURE__ */ jsx14(
3794
+ selectionError && /* @__PURE__ */ jsx16("p", { role: "alert", className: "text-rose-400", children: selectionError }),
3795
+ /* @__PURE__ */ jsxs15("div", { className: "flex gap-1", children: [
3796
+ /* @__PURE__ */ jsx16(
3622
3797
  "button",
3623
3798
  {
3624
3799
  type: "button",
@@ -3629,7 +3804,7 @@ var ImageEditor = ({
3629
3804
  children: "Transform Selection"
3630
3805
  }
3631
3806
  ),
3632
- /* @__PURE__ */ jsx14(
3807
+ /* @__PURE__ */ jsx16(
3633
3808
  "button",
3634
3809
  {
3635
3810
  type: "button",
@@ -3641,12 +3816,12 @@ var ImageEditor = ({
3641
3816
  }
3642
3817
  )
3643
3818
  ] }),
3644
- /* @__PURE__ */ jsx14(RefineEdgePanel, { controller, selection: state.selection ?? null, layers: state.adjustments.layers })
3819
+ /* @__PURE__ */ jsx16(RefineEdgePanel, { controller, selection: state.selection ?? null, layers: state.adjustments.layers })
3645
3820
  ] }),
3646
- activeTab === "ai" && /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-4 text-xs", children: [
3647
- /* @__PURE__ */ jsxs14("label", { className: "flex items-center justify-between gap-2 text-slate-300", children: [
3648
- /* @__PURE__ */ jsx14("span", { children: "Results go to" }),
3649
- /* @__PURE__ */ jsxs14(
3821
+ activeTab === "ai" && /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-4 text-xs", children: [
3822
+ /* @__PURE__ */ jsxs15("label", { className: "flex items-center justify-between gap-2 text-slate-300", children: [
3823
+ /* @__PURE__ */ jsx16("span", { children: "Results go to" }),
3824
+ /* @__PURE__ */ jsxs15(
3650
3825
  "select",
3651
3826
  {
3652
3827
  "aria-label": "AI result target",
@@ -3654,54 +3829,54 @@ var ImageEditor = ({
3654
3829
  onChange: (e) => setAiTarget(e.target.value),
3655
3830
  className: "bg-slate-800 border border-slate-700 rounded px-1.5 py-1",
3656
3831
  children: [
3657
- /* @__PURE__ */ jsx14("option", { value: "auto", children: controller.isMultiLayer ? "Auto (new layer)" : "Auto (replace image)" }),
3658
- /* @__PURE__ */ jsx14("option", { value: "new-layer", children: "New layer / mask" }),
3659
- /* @__PURE__ */ jsx14("option", { value: "replace", children: "Replace image" })
3832
+ /* @__PURE__ */ jsx16("option", { value: "auto", children: controller.isMultiLayer ? "Auto (new layer)" : "Auto (replace image)" }),
3833
+ /* @__PURE__ */ jsx16("option", { value: "new-layer", children: "New layer / mask" }),
3834
+ /* @__PURE__ */ jsx16("option", { value: "replace", children: "Replace image" })
3660
3835
  ]
3661
3836
  }
3662
3837
  )
3663
3838
  ] }),
3664
- /* @__PURE__ */ jsxs14("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
3665
- /* @__PURE__ */ jsxs14("div", { className: "flex items-center justify-between", children: [
3666
- /* @__PURE__ */ jsxs14("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
3667
- /* @__PURE__ */ jsx14("svg", { className: "w-3.5 h-3.5 text-indigo-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx14("path", { d: "M6 3v12M18 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM6 21a3 3 0 1 0 0-6 3 3 0 0 0 0 6z" }) }),
3839
+ /* @__PURE__ */ jsxs15("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
3840
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between", children: [
3841
+ /* @__PURE__ */ jsxs15("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
3842
+ /* @__PURE__ */ jsx16("svg", { className: "w-3.5 h-3.5 text-indigo-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx16("path", { d: "M6 3v12M18 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM6 21a3 3 0 1 0 0-6 3 3 0 0 0 0 6z" }) }),
3668
3843
  "Background Removal"
3669
3844
  ] }),
3670
- isRemovingBg && /* @__PURE__ */ jsx14("span", { className: "inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-indigo-900/60 text-indigo-300 animate-pulse", children: "Removing..." })
3845
+ isRemovingBg && /* @__PURE__ */ jsx16("span", { className: "inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-indigo-900/60 text-indigo-300 animate-pulse", children: "Removing..." })
3671
3846
  ] }),
3672
- /* @__PURE__ */ jsx14("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Isolate foreground subject with AI alpha transparency segmentation." }),
3673
- /* @__PURE__ */ jsx14(
3847
+ /* @__PURE__ */ jsx16("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Isolate foreground subject with AI alpha transparency segmentation." }),
3848
+ /* @__PURE__ */ jsx16(
3674
3849
  "button",
3675
3850
  {
3676
3851
  type: "button",
3677
3852
  onClick: handleRemoveBackground,
3678
3853
  disabled: isRemovingBg || isInpainting,
3679
3854
  className: "mt-1 px-3 py-2 rounded-lg bg-indigo-600 hover:bg-indigo-500 disabled:opacity-50 text-white font-medium shadow transition-colors flex items-center justify-center gap-2",
3680
- children: isRemovingBg ? /* @__PURE__ */ jsxs14(Fragment5, { children: [
3681
- /* @__PURE__ */ jsx14("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
3855
+ children: isRemovingBg ? /* @__PURE__ */ jsxs15(Fragment5, { children: [
3856
+ /* @__PURE__ */ jsx16("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
3682
3857
  "Removing Background..."
3683
- ] }) : /* @__PURE__ */ jsxs14(Fragment5, { children: [
3684
- /* @__PURE__ */ jsx14("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx14("path", { d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" }) }),
3858
+ ] }) : /* @__PURE__ */ jsxs15(Fragment5, { children: [
3859
+ /* @__PURE__ */ jsx16("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx16("path", { d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" }) }),
3685
3860
  "Remove Background"
3686
3861
  ] })
3687
3862
  }
3688
3863
  )
3689
3864
  ] }),
3690
- /* @__PURE__ */ jsxs14("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
3691
- /* @__PURE__ */ jsxs14("div", { className: "flex items-center justify-between", children: [
3692
- /* @__PURE__ */ jsxs14("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
3693
- /* @__PURE__ */ jsxs14("svg", { className: "w-3.5 h-3.5 text-purple-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
3694
- /* @__PURE__ */ jsx14("path", { d: "m21.64 3.64-1.28-1.28a1.2 1.2 0 0 0-1.7 0l-9.72 9.72-1.94 4.86 4.86-1.94 9.72-9.72a1.2 1.2 0 0 0 .06-1.64z" }),
3695
- /* @__PURE__ */ jsx14("path", { d: "m14 7 3 3" })
3865
+ /* @__PURE__ */ jsxs15("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
3866
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between", children: [
3867
+ /* @__PURE__ */ jsxs15("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
3868
+ /* @__PURE__ */ jsxs15("svg", { className: "w-3.5 h-3.5 text-purple-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
3869
+ /* @__PURE__ */ jsx16("path", { d: "m21.64 3.64-1.28-1.28a1.2 1.2 0 0 0-1.7 0l-9.72 9.72-1.94 4.86 4.86-1.94 9.72-9.72a1.2 1.2 0 0 0 .06-1.64z" }),
3870
+ /* @__PURE__ */ jsx16("path", { d: "m14 7 3 3" })
3696
3871
  ] }),
3697
3872
  "Generative Inpainting"
3698
3873
  ] }),
3699
- isInpainting && /* @__PURE__ */ jsx14("span", { className: "inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-purple-900/60 text-purple-300 animate-pulse", children: "Inpainting..." })
3874
+ isInpainting && /* @__PURE__ */ jsx16("span", { className: "inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-purple-900/60 text-purple-300 animate-pulse", children: "Inpainting..." })
3700
3875
  ] }),
3701
- /* @__PURE__ */ jsx14("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Replace, modify, or fill selected regions using prompt-guided generative inpainting." }),
3702
- /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-1", children: [
3703
- /* @__PURE__ */ jsx14("label", { htmlFor: "ai-inpaint-prompt-react", className: "text-slate-300 text-[11px] font-medium", children: "Prompt" }),
3704
- /* @__PURE__ */ jsx14(
3876
+ /* @__PURE__ */ jsx16("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Replace, modify, or fill selected regions using prompt-guided generative inpainting." }),
3877
+ /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-1", children: [
3878
+ /* @__PURE__ */ jsx16("label", { htmlFor: "ai-inpaint-prompt-react", className: "text-slate-300 text-[11px] font-medium", children: "Prompt" }),
3879
+ /* @__PURE__ */ jsx16(
3705
3880
  "textarea",
3706
3881
  {
3707
3882
  id: "ai-inpaint-prompt-react",
@@ -3713,10 +3888,10 @@ var ImageEditor = ({
3713
3888
  }
3714
3889
  )
3715
3890
  ] }),
3716
- /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-1", children: [
3717
- /* @__PURE__ */ jsx14("span", { className: "text-slate-300 text-[11px] font-medium", children: "Target Mask Region" }),
3718
- /* @__PURE__ */ jsxs14("div", { className: "grid grid-cols-2 gap-1.5", children: [
3719
- /* @__PURE__ */ jsxs14(
3891
+ /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-1", children: [
3892
+ /* @__PURE__ */ jsx16("span", { className: "text-slate-300 text-[11px] font-medium", children: "Target Mask Region" }),
3893
+ /* @__PURE__ */ jsxs15("div", { className: "grid grid-cols-2 gap-1.5", children: [
3894
+ /* @__PURE__ */ jsxs15(
3720
3895
  "button",
3721
3896
  {
3722
3897
  type: "button",
@@ -3729,7 +3904,7 @@ var ImageEditor = ({
3729
3904
  ]
3730
3905
  }
3731
3906
  ),
3732
- /* @__PURE__ */ jsxs14(
3907
+ /* @__PURE__ */ jsxs15(
3733
3908
  "button",
3734
3909
  {
3735
3910
  type: "button",
@@ -3744,25 +3919,25 @@ var ImageEditor = ({
3744
3919
  )
3745
3920
  ] })
3746
3921
  ] }),
3747
- /* @__PURE__ */ jsx14(
3922
+ /* @__PURE__ */ jsx16(
3748
3923
  "button",
3749
3924
  {
3750
3925
  type: "button",
3751
3926
  onClick: handleInpaint,
3752
3927
  disabled: isInpainting || isRemovingBg || !inpaintPrompt.trim(),
3753
3928
  className: "mt-1 px-3 py-2 rounded-lg bg-purple-600 hover:bg-purple-500 disabled:opacity-50 text-white font-medium shadow transition-colors flex items-center justify-center gap-2",
3754
- children: isInpainting ? /* @__PURE__ */ jsxs14(Fragment5, { children: [
3755
- /* @__PURE__ */ jsx14("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
3929
+ children: isInpainting ? /* @__PURE__ */ jsxs15(Fragment5, { children: [
3930
+ /* @__PURE__ */ jsx16("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
3756
3931
  "Generating Inpaint..."
3757
- ] }) : /* @__PURE__ */ jsxs14(Fragment5, { children: [
3758
- /* @__PURE__ */ jsx14("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx14("path", { d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" }) }),
3932
+ ] }) : /* @__PURE__ */ jsxs15(Fragment5, { children: [
3933
+ /* @__PURE__ */ jsx16("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx16("path", { d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" }) }),
3759
3934
  "Apply Inpainting"
3760
3935
  ] })
3761
3936
  }
3762
3937
  )
3763
3938
  ] }),
3764
- aiError && /* @__PURE__ */ jsx14("div", { className: "p-2.5 rounded-lg bg-rose-950/60 border border-rose-800 text-rose-300 text-[11px]", children: aiError }),
3765
- aiSuccess && /* @__PURE__ */ jsx14("div", { className: "p-2.5 rounded-lg bg-emerald-950/60 border border-emerald-800 text-emerald-300 text-[11px]", children: aiSuccess })
3939
+ aiError && /* @__PURE__ */ jsx16("div", { className: "p-2.5 rounded-lg bg-rose-950/60 border border-rose-800 text-rose-300 text-[11px]", children: aiError }),
3940
+ aiSuccess && /* @__PURE__ */ jsx16("div", { className: "p-2.5 rounded-lg bg-emerald-950/60 border border-emerald-800 text-emerald-300 text-[11px]", children: aiSuccess })
3766
3941
  ] })
3767
3942
  ] })
3768
3943
  ] })
@@ -3773,6 +3948,7 @@ var ImageEditor = ({
3773
3948
 
3774
3949
  export {
3775
3950
  useImageEditor,
3951
+ useImageEffectsTools,
3776
3952
  ControlSlider,
3777
3953
  Histogram,
3778
3954
  useImageHistogram,
@@ -3780,6 +3956,8 @@ export {
3780
3956
  AdjustmentLayersPanel,
3781
3957
  LayerEffectsPanel,
3782
3958
  LayersPanel,
3959
+ ImageProviderEffectsPanel,
3960
+ PaintGradientEditor,
3783
3961
  BrushOptionsBar,
3784
3962
  ColorProfilePanel,
3785
3963
  SelectionOptionsBar,
@@ -3789,4 +3967,4 @@ export {
3789
3967
  TypeOptionsBar,
3790
3968
  ImageEditor
3791
3969
  };
3792
- //# sourceMappingURL=chunk-LWMUV5TC.js.map
3970
+ //# sourceMappingURL=chunk-2EW42UXC.js.map