@pixerate/editor-react 0.64.0 → 0.65.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.
@@ -34,6 +34,7 @@ __export(image_editor_exports, {
34
34
  BrushOptionsBar: () => BrushOptionsBar,
35
35
  ControlSlider: () => ControlSlider,
36
36
  CurvesEditor: () => CurvesEditor,
37
+ FreeTransformOptionsBar: () => FreeTransformOptionsBar,
37
38
  Histogram: () => Histogram,
38
39
  ImageEditor: () => ImageEditor,
39
40
  LayerEffectsPanel: () => LayerEffectsPanel,
@@ -204,8 +205,8 @@ function useImageEditor(options = {}) {
204
205
  }
205
206
 
206
207
  // src/image-editor/ImageEditor.tsx
207
- var import_react10 = __toESM(require("react"), 1);
208
- var import_image_editor11 = require("@pixerate/editor/image-editor");
208
+ var import_react11 = __toESM(require("react"), 1);
209
+ var import_image_editor12 = require("@pixerate/editor/image-editor");
209
210
 
210
211
  // src/image-editor/ControlSlider.tsx
211
212
  var import_image_editor2 = require("@pixerate/editor/image-editor");
@@ -1124,6 +1125,22 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
1124
1125
  children: (0, import_image_editor7.layerBadge)(layer)
1125
1126
  }
1126
1127
  ),
1128
+ layer.mask && !layer.mask.source && layer.type === "pixel" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1129
+ "button",
1130
+ {
1131
+ type: "button",
1132
+ "aria-label": `${layer.mask.linked === false ? "Link" : "Unlink"} ${row.label} mask`,
1133
+ "aria-pressed": layer.mask.linked !== false,
1134
+ title: layer.mask.linked === false ? "Mask unlinked: it stays put when the layer moves or transforms. Click to link." : "Mask linked: it moves with the layer. Click to unlink.",
1135
+ "data-testid": "layer-mask-link",
1136
+ className: `shrink-0 text-[10px] leading-none ${layer.mask.linked === false ? "text-slate-600" : "text-slate-300"}`,
1137
+ onClick: (e) => {
1138
+ e.stopPropagation();
1139
+ attempt(() => controller.setLayerMaskProps(layer.id, { linked: layer.mask.linked === false }));
1140
+ },
1141
+ children: layer.mask.linked === false ? "\u26D3\uFE0E\u0338" : "\u26D3\uFE0E"
1142
+ }
1143
+ ),
1127
1144
  layer.mask && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1128
1145
  Thumbnail,
1129
1146
  {
@@ -1635,8 +1652,83 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
1635
1652
  ] });
1636
1653
  };
1637
1654
 
1638
- // src/image-editor/ImageEditor.tsx
1655
+ // src/image-editor/FreeTransformOptionsBar.tsx
1656
+ var import_react10 = require("react");
1657
+ var import_image_editor11 = require("@pixerate/editor/image-editor");
1639
1658
  var import_jsx_runtime10 = require("react/jsx-runtime");
1659
+ var chip2 = (on) => `px-2 py-1 rounded text-[11px] ${on ? "bg-indigo-600 text-white" : "bg-slate-800 text-slate-300 hover:text-white"}`;
1660
+ var round = (v, unit) => unit === "px" ? Math.round(v * 10) / 10 : Math.round(v * 100) / 100;
1661
+ var FreeTransformOptionsBar = ({ tool, className }) => {
1662
+ const [, setTick] = (0, import_react10.useState)(0);
1663
+ (0, import_react10.useEffect)(() => tool.subscribe(() => setTick((n) => n + 1)), [tool]);
1664
+ const bar = tool.bar();
1665
+ if (!tool.active || !bar) return null;
1666
+ const apply = (field, raw) => {
1667
+ const v = Number(raw);
1668
+ if (raw.trim() !== "" && Number.isFinite(v) && Math.abs(v - bar[field]) > 1e-9) tool.setField(field, v);
1669
+ };
1670
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("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: [
1671
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex gap-1", role: "group", "aria-label": "Transform mode", children: import_image_editor11.FREE_TRANSFORM_MODE_OPTIONS.map((m) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", title: m.title, "aria-pressed": tool.mode === m.id, className: chip2(tool.mode === m.id), onClick: () => tool.setMode(m.id), children: m.label }, m.id)) }),
1672
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "grid grid-cols-3 gap-px", role: "group", "aria-label": "Reference point", children: import_image_editor11.TRANSFORM_ANCHORS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("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)) }),
1673
+ import_image_editor11.FREE_TRANSFORM_FIELDS.map((f) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex items-center gap-1", title: f.title, children: [
1674
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-slate-400", children: f.label }),
1675
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1676
+ "input",
1677
+ {
1678
+ type: "number",
1679
+ "aria-label": f.title,
1680
+ defaultValue: round(bar[f.id], f.unit),
1681
+ disabled: !bar.affine,
1682
+ step: f.unit === "px" ? 1 : 0.1,
1683
+ className: "w-16 rounded border border-slate-700 bg-slate-900 px-1 py-0.5 text-right disabled:opacity-40",
1684
+ onBlur: (e) => apply(f.id, e.currentTarget.value),
1685
+ onKeyDown: (e) => {
1686
+ if (e.key === "Enter") {
1687
+ e.preventDefault();
1688
+ e.stopPropagation();
1689
+ apply(f.id, e.currentTarget.value);
1690
+ }
1691
+ }
1692
+ },
1693
+ `${f.id}:${round(bar[f.id], f.unit)}`
1694
+ ),
1695
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-slate-500", children: f.unit }),
1696
+ f.id === "scaleX" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1697
+ "button",
1698
+ {
1699
+ type: "button",
1700
+ "aria-label": "Keep width and height proportional",
1701
+ "aria-pressed": tool.proportional,
1702
+ className: chip2(tool.proportional),
1703
+ onClick: () => {
1704
+ tool.proportional = !tool.proportional;
1705
+ setTick((n) => n + 1);
1706
+ },
1707
+ children: "\u26D3\uFE0E"
1708
+ }
1709
+ )
1710
+ ] }, f.id)),
1711
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex items-center gap-1", children: [
1712
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-slate-400", children: "Interpolation" }),
1713
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1714
+ "select",
1715
+ {
1716
+ "aria-label": "Interpolation",
1717
+ value: tool.interpolation,
1718
+ onChange: (e) => tool.setInterpolation(e.target.value),
1719
+ className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
1720
+ children: import_image_editor11.INTERPOLATIONS.map((i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: i, children: i[0].toUpperCase() + i.slice(1) }, i))
1721
+ }
1722
+ )
1723
+ ] }),
1724
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("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" }),
1725
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", title: "Cancel (Esc)", className: chip2(false), onClick: () => tool.cancel(), children: "Cancel" }),
1726
+ tool.error && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { role: "alert", className: "text-rose-400", children: tool.error })
1727
+ ] });
1728
+ };
1729
+
1730
+ // src/image-editor/ImageEditor.tsx
1731
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1640
1732
  var ImageEditor = ({
1641
1733
  editor: externalEditor,
1642
1734
  src,
@@ -1651,35 +1743,47 @@ var ImageEditor = ({
1651
1743
  const internalEditor = useImageEditor({ image: src });
1652
1744
  const editor = externalEditor || internalEditor;
1653
1745
  const { state, controller } = editor;
1654
- const legacyProcess = (0, import_image_editor11.normalizeProcessVersion)(state.adjustments.process) < import_image_editor11.LATEST_PROCESS_VERSION;
1655
- const canvasRef = (0, import_react10.useRef)(null);
1656
- const containerRef = (0, import_react10.useRef)(null);
1657
- const [activeTab, setActiveTab] = (0, import_react10.useState)("crop");
1658
- const [activeCropRatio, setActiveCropRatio] = (0, import_react10.useState)(null);
1659
- const [selectionOptions, setSelectionOptions] = (0, import_react10.useState)(import_image_editor11.DEFAULT_SELECTION_TOOL_OPTIONS);
1660
- const selectionOptionsRef = (0, import_react10.useRef)(selectionOptions);
1746
+ const legacyProcess = (0, import_image_editor12.normalizeProcessVersion)(state.adjustments.process) < import_image_editor12.LATEST_PROCESS_VERSION;
1747
+ const canvasRef = (0, import_react11.useRef)(null);
1748
+ const containerRef = (0, import_react11.useRef)(null);
1749
+ const [activeTab, setActiveTab] = (0, import_react11.useState)("crop");
1750
+ const [activeCropRatio, setActiveCropRatio] = (0, import_react11.useState)(null);
1751
+ const [selectionOptions, setSelectionOptions] = (0, import_react11.useState)(import_image_editor12.DEFAULT_SELECTION_TOOL_OPTIONS);
1752
+ const selectionOptionsRef = (0, import_react11.useRef)(selectionOptions);
1661
1753
  selectionOptionsRef.current = selectionOptions;
1662
- const selectionGestureRef = (0, import_react10.useRef)(null);
1754
+ const selectionGestureRef = (0, import_react11.useRef)(null);
1663
1755
  if (!selectionGestureRef.current || selectionGestureRef.current.controller !== controller) {
1664
- selectionGestureRef.current = new import_image_editor11.SelectionGesture(controller, () => selectionOptionsRef.current);
1756
+ selectionGestureRef.current = new import_image_editor12.SelectionGesture(controller, () => selectionOptionsRef.current);
1665
1757
  }
1666
- const selectionDraftRef = (0, import_react10.useRef)(null);
1667
- const [selectionError, setSelectionError] = (0, import_react10.useState)(null);
1668
- const paintGestureRef = (0, import_react10.useRef)(null);
1669
- const paintControllerRef = (0, import_react10.useRef)(controller);
1758
+ const selectionDraftRef = (0, import_react11.useRef)(null);
1759
+ const [selectionError, setSelectionError] = (0, import_react11.useState)(null);
1760
+ const paintGestureRef = (0, import_react11.useRef)(null);
1761
+ const paintControllerRef = (0, import_react11.useRef)(controller);
1670
1762
  if (!paintGestureRef.current || paintControllerRef.current !== controller) {
1671
- paintGestureRef.current = new import_image_editor11.PaintGesture(controller);
1763
+ paintGestureRef.current = new import_image_editor12.PaintGesture(controller);
1672
1764
  paintControllerRef.current = controller;
1673
1765
  }
1674
- const brushCursorRef = (0, import_react10.useRef)(null);
1675
- const [paintError, setPaintError] = (0, import_react10.useState)(null);
1676
- const [inpaintPrompt, setInpaintPrompt] = (0, import_react10.useState)("");
1677
- const [inpaintMaskMode, setInpaintMaskMode] = (0, import_react10.useState)("annotations");
1678
- const [isRemovingBg, setIsRemovingBg] = (0, import_react10.useState)(false);
1679
- const [isInpainting, setIsInpainting] = (0, import_react10.useState)(false);
1680
- const [aiError, setAiError] = (0, import_react10.useState)(null);
1681
- const [aiSuccess, setAiSuccess] = (0, import_react10.useState)(null);
1682
- const [aiTarget, setAiTarget] = (0, import_react10.useState)("auto");
1766
+ const brushCursorRef = (0, import_react11.useRef)(null);
1767
+ const [paintError, setPaintError] = (0, import_react11.useState)(null);
1768
+ const transformToolRef = (0, import_react11.useRef)(null);
1769
+ const transformControllerRef = (0, import_react11.useRef)(controller);
1770
+ if (!transformToolRef.current || transformControllerRef.current !== controller) {
1771
+ transformToolRef.current?.cancel();
1772
+ transformToolRef.current = new import_image_editor12.FreeTransformTool(controller, {
1773
+ schedule: (run) => typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame(run) : run()
1774
+ });
1775
+ transformControllerRef.current = controller;
1776
+ }
1777
+ const transformTool = transformToolRef.current;
1778
+ const [, setTransformTick] = (0, import_react11.useState)(0);
1779
+ const [transformCursor, setTransformCursor] = (0, import_react11.useState)("default");
1780
+ const [inpaintPrompt, setInpaintPrompt] = (0, import_react11.useState)("");
1781
+ const [inpaintMaskMode, setInpaintMaskMode] = (0, import_react11.useState)("annotations");
1782
+ const [isRemovingBg, setIsRemovingBg] = (0, import_react11.useState)(false);
1783
+ const [isInpainting, setIsInpainting] = (0, import_react11.useState)(false);
1784
+ const [aiError, setAiError] = (0, import_react11.useState)(null);
1785
+ const [aiSuccess, setAiSuccess] = (0, import_react11.useState)(null);
1786
+ const [aiTarget, setAiTarget] = (0, import_react11.useState)("auto");
1683
1787
  const aiOptions = aiTarget === "auto" ? {} : { target: aiTarget };
1684
1788
  const effectiveOnInpaint = onInpaint || aiHooks?.onInpaint;
1685
1789
  const effectiveOnRemoveBg = onRemoveBackground || aiHooks?.onRemoveBackground;
@@ -1742,18 +1846,18 @@ var ImageEditor = ({
1742
1846
  setIsInpainting(false);
1743
1847
  }
1744
1848
  };
1745
- const [activeColor, setActiveColor] = (0, import_react10.useState)("#ef4444");
1746
- const [strokeWidth, setStrokeWidth] = (0, import_react10.useState)(3);
1747
- const [fontSize, setFontSize] = (0, import_react10.useState)(24);
1748
- const [textInput, setTextInput] = (0, import_react10.useState)("");
1749
- const draftAnnotationRef = (0, import_react10.useRef)(null);
1750
- const draftCropRef = (0, import_react10.useRef)(null);
1751
- const cropDragInfoRef = (0, import_react10.useRef)(null);
1752
- const annotationDragInfoRef = (0, import_react10.useRef)(null);
1753
- const isDrawingRef = (0, import_react10.useRef)(false);
1754
- const currentPathRef = (0, import_react10.useRef)([]);
1755
- const dragStartPointRef = (0, import_react10.useRef)(null);
1756
- const renderCanvas = (0, import_react10.useCallback)(
1849
+ const [activeColor, setActiveColor] = (0, import_react11.useState)("#ef4444");
1850
+ const [strokeWidth, setStrokeWidth] = (0, import_react11.useState)(3);
1851
+ const [fontSize, setFontSize] = (0, import_react11.useState)(24);
1852
+ const [textInput, setTextInput] = (0, import_react11.useState)("");
1853
+ const draftAnnotationRef = (0, import_react11.useRef)(null);
1854
+ const draftCropRef = (0, import_react11.useRef)(null);
1855
+ const cropDragInfoRef = (0, import_react11.useRef)(null);
1856
+ const annotationDragInfoRef = (0, import_react11.useRef)(null);
1857
+ const isDrawingRef = (0, import_react11.useRef)(false);
1858
+ const currentPathRef = (0, import_react11.useRef)([]);
1859
+ const dragStartPointRef = (0, import_react11.useRef)(null);
1860
+ const renderCanvas = (0, import_react11.useCallback)(
1757
1861
  async (draftAnnotation, draftCrop) => {
1758
1862
  const canvas = canvasRef.current;
1759
1863
  const container = containerRef.current;
@@ -1769,12 +1873,64 @@ var ImageEditor = ({
1769
1873
  draftAnnotation: draftAnnotation !== void 0 ? draftAnnotation : draftAnnotationRef.current,
1770
1874
  draftCrop: draftCrop !== void 0 ? draftCrop : draftCropRef.current,
1771
1875
  draftSelectionPath: selectionDraftRef.current,
1772
- brushCursor: activeTab === "paint" && brushCursorRef.current && controller.getState().activeTool !== "move" ? { ...brushCursorRef.current, diameter: controller.getState().paint.brush.size } : null
1876
+ brushCursor: activeTab === "paint" && brushCursorRef.current && controller.getState().activeTool !== "move" && !transformTool.active ? { ...brushCursorRef.current, diameter: controller.getState().paint.brush.size } : null,
1877
+ freeTransform: transformTool.overlay()
1773
1878
  });
1774
1879
  },
1775
- [controller, activeTab]
1880
+ [controller, activeTab, transformTool]
1776
1881
  );
1777
- (0, import_react10.useEffect)(() => {
1882
+ (0, import_react11.useEffect)(() => transformTool.subscribe(() => {
1883
+ setTransformTick((n) => n + 1);
1884
+ void renderCanvas();
1885
+ }), [transformTool, renderCanvas]);
1886
+ const transformPoint = (e) => {
1887
+ const canvas = canvasRef.current;
1888
+ const rect = canvas.getBoundingClientRect();
1889
+ const sx = rect.width > 0 ? canvas.width / rect.width : 1;
1890
+ const sy = rect.height > 0 ? canvas.height / rect.height : 1;
1891
+ const s = controller.getState();
1892
+ const cropping = activeTab === "crop";
1893
+ const projection = (0, import_image_editor12.getViewportProjection)(s, canvas.width, canvas.height, cropping);
1894
+ const pt = (0, import_image_editor12.canvasToImagePoint)({ x: (e.clientX - rect.left) * sx, y: (e.clientY - rect.top) * sy }, s, canvas.width, canvas.height, cropping);
1895
+ transformTool.setView(projection.scale);
1896
+ return { pt, tolerance: 6 / (projection.scale || 1) };
1897
+ };
1898
+ const handleTransformPointerDown = (e) => {
1899
+ if (!transformTool.active) return false;
1900
+ if (e.button !== 0) return true;
1901
+ e.preventDefault();
1902
+ try {
1903
+ e.currentTarget.setPointerCapture?.(e.pointerId);
1904
+ } catch {
1905
+ }
1906
+ const { pt, tolerance } = transformPoint(e);
1907
+ transformTool.down(pt, tolerance);
1908
+ return true;
1909
+ };
1910
+ const handleTransformPointerMove = (e) => {
1911
+ if (!transformTool.active) return false;
1912
+ const { pt, tolerance } = transformPoint(e);
1913
+ if (e.buttons & 1) transformTool.move(pt, e);
1914
+ else {
1915
+ const over = transformTool.hit(pt, tolerance);
1916
+ setTransformCursor(transformTool.cursor(over));
1917
+ }
1918
+ return true;
1919
+ };
1920
+ const handleTransformPointerUp = () => {
1921
+ if (!transformTool.active) return false;
1922
+ transformTool.up();
1923
+ return true;
1924
+ };
1925
+ (0, import_react11.useEffect)(() => {
1926
+ if (typeof window === "undefined") return;
1927
+ const onKey = (e) => {
1928
+ if (transformTool.key(e)) e.preventDefault();
1929
+ };
1930
+ window.addEventListener("keydown", onKey);
1931
+ return () => window.removeEventListener("keydown", onKey);
1932
+ }, [transformTool]);
1933
+ (0, import_react11.useEffect)(() => {
1778
1934
  const raf = typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : (cb) => setTimeout(cb, 0);
1779
1935
  const caf = typeof cancelAnimationFrame !== "undefined" ? cancelAnimationFrame : (id) => clearTimeout(id);
1780
1936
  const animId = raf(() => {
@@ -1782,12 +1938,12 @@ var ImageEditor = ({
1782
1938
  });
1783
1939
  return () => caf(animId);
1784
1940
  }, [renderCanvas, state]);
1785
- (0, import_react10.useEffect)(() => {
1941
+ (0, import_react11.useEffect)(() => {
1786
1942
  if (activeTab === "crop" && editor.state.activeTool !== "crop") {
1787
1943
  editor.setTool("crop");
1788
1944
  }
1789
1945
  }, [activeTab, editor]);
1790
- (0, import_react10.useEffect)(() => {
1946
+ (0, import_react11.useEffect)(() => {
1791
1947
  const container = containerRef.current;
1792
1948
  if (!container) return;
1793
1949
  if (typeof ResizeObserver !== "undefined") {
@@ -1823,11 +1979,12 @@ var ImageEditor = ({
1823
1979
  const sy = rect.height > 0 ? canvas.height / rect.height : 1;
1824
1980
  const s = controller.getState();
1825
1981
  return list.map((ev) => ({
1826
- ...(0, import_image_editor11.canvasToImagePoint)({ x: (ev.clientX - rect.left) * sx, y: (ev.clientY - rect.top) * sy }, s, canvas.width, canvas.height, false),
1827
- pressure: (0, import_image_editor11.pointerPressure)(ev)
1982
+ ...(0, import_image_editor12.canvasToImagePoint)({ x: (ev.clientX - rect.left) * sx, y: (ev.clientY - rect.top) * sy }, s, canvas.width, canvas.height, false),
1983
+ pressure: (0, import_image_editor12.pointerPressure)(ev)
1828
1984
  }));
1829
1985
  };
1830
1986
  const handlePaintPointerDown = (e) => {
1987
+ if (handleTransformPointerDown(e)) return;
1831
1988
  if (activeTab !== "paint" || e.button !== 0) return;
1832
1989
  e.preventDefault();
1833
1990
  try {
@@ -1838,6 +1995,7 @@ var ImageEditor = ({
1838
1995
  setPaintError(paintGestureRef.current.down(first));
1839
1996
  };
1840
1997
  const handlePaintPointerMove = (e) => {
1998
+ if (handleTransformPointerMove(e)) return;
1841
1999
  if (activeTab !== "paint") return;
1842
2000
  const samples = paintSamples(e);
1843
2001
  brushCursorRef.current = samples[samples.length - 1] ?? null;
@@ -1845,6 +2003,7 @@ var ImageEditor = ({
1845
2003
  else void renderCanvas();
1846
2004
  };
1847
2005
  const handlePaintPointerUp = () => {
2006
+ if (handleTransformPointerUp()) return;
1848
2007
  if (activeTab !== "paint") return;
1849
2008
  const g = paintGestureRef.current;
1850
2009
  if (g.active) {
@@ -1852,21 +2011,21 @@ var ImageEditor = ({
1852
2011
  if (g.error) setPaintError(g.error);
1853
2012
  }
1854
2013
  };
1855
- (0, import_react10.useEffect)(() => {
2014
+ (0, import_react11.useEffect)(() => {
1856
2015
  if (activeTab !== "paint" || typeof window === "undefined") return;
1857
2016
  const onKey = (e) => {
1858
- if ((0, import_image_editor11.handlePaintShortcut)(controller, e)) e.preventDefault();
2017
+ if ((0, import_image_editor12.handlePaintShortcut)(controller, e)) e.preventDefault();
1859
2018
  };
1860
2019
  window.addEventListener("keydown", onKey);
1861
2020
  return () => window.removeEventListener("keydown", onKey);
1862
2021
  }, [activeTab, controller]);
1863
2022
  const handleMouseDown = (e) => {
1864
2023
  const canvas = canvasRef.current;
1865
- if (!canvas) return;
2024
+ if (!canvas || transformTool.active) return;
1866
2025
  const canvasPt = getCanvasEventPoint(e);
1867
2026
  if (activeTab === "select") {
1868
2027
  const gesture = selectionGestureRef.current;
1869
- const imgPt = (0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
2028
+ const imgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
1870
2029
  void gesture.begin(imgPt, e).then(() => setSelectionError(gesture.error));
1871
2030
  return;
1872
2031
  }
@@ -1877,8 +2036,8 @@ var ImageEditor = ({
1877
2036
  width: state.imageDimensions.width,
1878
2037
  height: state.imageDimensions.height
1879
2038
  };
1880
- const handle = (0, import_image_editor11.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
1881
- const startImgPt = (0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
2039
+ const handle = (0, import_image_editor12.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
2040
+ const startImgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
1882
2041
  if (handle) {
1883
2042
  cropDragInfoRef.current = {
1884
2043
  handle,
@@ -1897,12 +2056,12 @@ var ImageEditor = ({
1897
2056
  return;
1898
2057
  }
1899
2058
  if (activeTab === "annotate") {
1900
- const imgPt = (0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
2059
+ const imgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
1901
2060
  dragStartPointRef.current = imgPt;
1902
2061
  if (state.activeTool === "select") {
1903
2062
  for (let i = state.annotations.length - 1; i >= 0; i--) {
1904
2063
  const ann = state.annotations[i];
1905
- if ((0, import_image_editor11.hitTestAnnotation)(imgPt, ann)) {
2064
+ if ((0, import_image_editor12.hitTestAnnotation)(imgPt, ann)) {
1906
2065
  editor.selectAnnotation(ann.id);
1907
2066
  annotationDragInfoRef.current = {
1908
2067
  annId: ann.id,
@@ -1934,11 +2093,11 @@ var ImageEditor = ({
1934
2093
  };
1935
2094
  const handleMouseMove = (e) => {
1936
2095
  const canvas = canvasRef.current;
1937
- if (!canvas) return;
2096
+ if (!canvas || transformTool.active) return;
1938
2097
  const canvasPt = getCanvasEventPoint(e);
1939
2098
  if (activeTab === "select") {
1940
2099
  const gesture = selectionGestureRef.current;
1941
- if (gesture.active && gesture.move((0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false))) {
2100
+ if (gesture.active && gesture.move((0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false))) {
1942
2101
  selectionDraftRef.current = gesture.draftPath;
1943
2102
  renderCanvas();
1944
2103
  }
@@ -1947,7 +2106,7 @@ var ImageEditor = ({
1947
2106
  if (activeTab === "crop") {
1948
2107
  const drag = cropDragInfoRef.current;
1949
2108
  if (drag) {
1950
- const currentImgPt = (0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
2109
+ const currentImgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
1951
2110
  let newCrop;
1952
2111
  if (drag.handle === "new") {
1953
2112
  const minX = Math.max(0, Math.min(drag.startImgPt.x, currentImgPt.x));
@@ -1961,7 +2120,7 @@ var ImageEditor = ({
1961
2120
  height: Math.round(Math.max(20, maxY - minY))
1962
2121
  };
1963
2122
  } else {
1964
- newCrop = (0, import_image_editor11.calculateCropDrag)(
2123
+ newCrop = (0, import_image_editor12.calculateCropDrag)(
1965
2124
  drag.startCrop,
1966
2125
  drag.handle,
1967
2126
  drag.startImgPt,
@@ -1981,15 +2140,15 @@ var ImageEditor = ({
1981
2140
  width: state.imageDimensions.width,
1982
2141
  height: state.imageDimensions.height
1983
2142
  };
1984
- const handle = (0, import_image_editor11.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
1985
- canvas.style.cursor = (0, import_image_editor11.getCropCursor)(handle, state.transform);
2143
+ const handle = (0, import_image_editor12.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
2144
+ canvas.style.cursor = (0, import_image_editor12.getCropCursor)(handle, state.transform);
1986
2145
  }
1987
2146
  return;
1988
2147
  }
1989
2148
  if (activeTab === "annotate") {
1990
2149
  if (annotationDragInfoRef.current) {
1991
2150
  const drag = annotationDragInfoRef.current;
1992
- const currentImgPt2 = (0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
2151
+ const currentImgPt2 = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
1993
2152
  const dx = currentImgPt2.x - drag.startImgPt.x;
1994
2153
  const dy = currentImgPt2.y - drag.startImgPt.y;
1995
2154
  editor.updateAnnotation(drag.annId, {
@@ -2001,10 +2160,10 @@ var ImageEditor = ({
2001
2160
  const startPt = dragStartPointRef.current;
2002
2161
  if (!startPt) {
2003
2162
  if (state.activeTool === "select") {
2004
- const imgPt = (0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
2163
+ const imgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
2005
2164
  let hovered = false;
2006
2165
  for (let i = state.annotations.length - 1; i >= 0; i--) {
2007
- if ((0, import_image_editor11.hitTestAnnotation)(imgPt, state.annotations[i])) {
2166
+ if ((0, import_image_editor12.hitTestAnnotation)(imgPt, state.annotations[i])) {
2008
2167
  hovered = true;
2009
2168
  break;
2010
2169
  }
@@ -2015,7 +2174,7 @@ var ImageEditor = ({
2015
2174
  }
2016
2175
  return;
2017
2176
  }
2018
- const currentImgPt = (0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
2177
+ const currentImgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
2019
2178
  if (state.activeTool === "pen" && isDrawingRef.current) {
2020
2179
  currentPathRef.current.push(currentImgPt);
2021
2180
  const draft = {
@@ -2090,12 +2249,12 @@ var ImageEditor = ({
2090
2249
  };
2091
2250
  const handleMouseUp = (e) => {
2092
2251
  const canvas = canvasRef.current;
2093
- if (!canvas) return;
2252
+ if (!canvas || transformTool.active) return;
2094
2253
  const canvasPt = getCanvasEventPoint(e);
2095
2254
  if (activeTab === "select") {
2096
2255
  const gesture = selectionGestureRef.current;
2097
2256
  if (gesture.active) {
2098
- gesture.end((0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), e);
2257
+ gesture.end((0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), e);
2099
2258
  selectionDraftRef.current = null;
2100
2259
  renderCanvas();
2101
2260
  }
@@ -2119,7 +2278,7 @@ var ImageEditor = ({
2119
2278
  }
2120
2279
  const startPt = dragStartPointRef.current;
2121
2280
  if (startPt) {
2122
- const currentImgPt = (0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
2281
+ const currentImgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
2123
2282
  if (state.activeTool === "pen" && isDrawingRef.current) {
2124
2283
  if (currentPathRef.current.length > 1) {
2125
2284
  editor.addAnnotation({
@@ -2215,15 +2374,15 @@ var ImageEditor = ({
2215
2374
  link.click();
2216
2375
  }
2217
2376
  };
2218
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
2377
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2219
2378
  "div",
2220
2379
  {
2221
2380
  className: `flex flex-col bg-slate-900 border border-slate-800 rounded-xl overflow-hidden shadow-2xl text-slate-100 ${className}`,
2222
2381
  style,
2223
2382
  children: [
2224
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("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: [
2225
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-1 bg-slate-900 p-1 rounded-lg border border-slate-800 text-xs", children: [
2226
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2383
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("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: [
2384
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-1 bg-slate-900 p-1 rounded-lg border border-slate-800 text-xs", children: [
2385
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2227
2386
  "button",
2228
2387
  {
2229
2388
  type: "button",
@@ -2235,7 +2394,7 @@ var ImageEditor = ({
2235
2394
  children: "Transform & Crop"
2236
2395
  }
2237
2396
  ),
2238
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2397
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2239
2398
  "button",
2240
2399
  {
2241
2400
  type: "button",
@@ -2247,7 +2406,7 @@ var ImageEditor = ({
2247
2406
  children: "Adjustments"
2248
2407
  }
2249
2408
  ),
2250
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2409
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2251
2410
  "button",
2252
2411
  {
2253
2412
  type: "button",
@@ -2259,7 +2418,7 @@ var ImageEditor = ({
2259
2418
  children: "Layers"
2260
2419
  }
2261
2420
  ),
2262
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2421
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2263
2422
  "button",
2264
2423
  {
2265
2424
  type: "button",
@@ -2271,7 +2430,7 @@ var ImageEditor = ({
2271
2430
  children: "Paint"
2272
2431
  }
2273
2432
  ),
2274
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2433
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2275
2434
  "button",
2276
2435
  {
2277
2436
  type: "button",
@@ -2283,7 +2442,7 @@ var ImageEditor = ({
2283
2442
  children: "Select & Mask"
2284
2443
  }
2285
2444
  ),
2286
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2445
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2287
2446
  "button",
2288
2447
  {
2289
2448
  type: "button",
@@ -2295,7 +2454,7 @@ var ImageEditor = ({
2295
2454
  children: "Annotations"
2296
2455
  }
2297
2456
  ),
2298
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2457
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2299
2458
  "button",
2300
2459
  {
2301
2460
  type: "button",
@@ -2307,7 +2466,7 @@ var ImageEditor = ({
2307
2466
  children: "Depth Mask"
2308
2467
  }
2309
2468
  ),
2310
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
2469
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2311
2470
  "button",
2312
2471
  {
2313
2472
  type: "button",
@@ -2317,14 +2476,14 @@ var ImageEditor = ({
2317
2476
  },
2318
2477
  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"}`,
2319
2478
  children: [
2320
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("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" }) }),
2479
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("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" }) }),
2321
2480
  "AI Tools"
2322
2481
  ]
2323
2482
  }
2324
2483
  )
2325
2484
  ] }),
2326
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-2 text-xs", children: [
2327
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2485
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2 text-xs", children: [
2486
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2328
2487
  "button",
2329
2488
  {
2330
2489
  type: "button",
@@ -2335,7 +2494,7 @@ var ImageEditor = ({
2335
2494
  children: "\u21A9"
2336
2495
  }
2337
2496
  ),
2338
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2497
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2339
2498
  "button",
2340
2499
  {
2341
2500
  type: "button",
@@ -2346,7 +2505,7 @@ var ImageEditor = ({
2346
2505
  children: "\u21AA"
2347
2506
  }
2348
2507
  ),
2349
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2508
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2350
2509
  "button",
2351
2510
  {
2352
2511
  type: "button",
@@ -2355,8 +2514,8 @@ var ImageEditor = ({
2355
2514
  children: "Reset"
2356
2515
  }
2357
2516
  ),
2358
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
2359
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2517
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
2518
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2360
2519
  "button",
2361
2520
  {
2362
2521
  type: "button",
@@ -2366,11 +2525,11 @@ var ImageEditor = ({
2366
2525
  children: "-"
2367
2526
  }
2368
2527
  ),
2369
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "font-mono text-slate-400 w-10 text-center", children: [
2528
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "font-mono text-slate-400 w-10 text-center", children: [
2370
2529
  Math.round(state.zoom * 100),
2371
2530
  "%"
2372
2531
  ] }),
2373
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2532
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2374
2533
  "button",
2375
2534
  {
2376
2535
  type: "button",
@@ -2380,8 +2539,8 @@ var ImageEditor = ({
2380
2539
  children: "+"
2381
2540
  }
2382
2541
  ),
2383
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
2384
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2542
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
2543
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2385
2544
  "button",
2386
2545
  {
2387
2546
  type: "button",
@@ -2392,7 +2551,7 @@ var ImageEditor = ({
2392
2551
  children: "Hold Compare"
2393
2552
  }
2394
2553
  ),
2395
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2554
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2396
2555
  "button",
2397
2556
  {
2398
2557
  type: "button",
@@ -2403,13 +2562,15 @@ var ImageEditor = ({
2403
2562
  )
2404
2563
  ] })
2405
2564
  ] }),
2406
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-col md:flex-row flex-1 min-h-[520px] md:h-[560px]", children: [
2407
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2565
+ transformTool.active && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(FreeTransformOptionsBar, { tool: transformTool, className: "border-b border-slate-800 bg-slate-900/95 px-4 py-2" }),
2566
+ !transformTool.active && transformTool.error && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("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 }),
2567
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col md:flex-row flex-1 min-h-[520px] md:h-[560px]", children: [
2568
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2408
2569
  "div",
2409
2570
  {
2410
2571
  ref: containerRef,
2411
2572
  className: "relative flex-1 h-[360px] md:h-full min-h-[320px] bg-slate-950 overflow-hidden select-none",
2412
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2573
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2413
2574
  "canvas",
2414
2575
  {
2415
2576
  ref: canvasRef,
@@ -2422,16 +2583,17 @@ var ImageEditor = ({
2422
2583
  onPointerUp: handlePaintPointerUp,
2423
2584
  onPointerCancel: () => paintGestureRef.current?.cancel(),
2424
2585
  "data-testid": "image-editor-canvas",
2425
- className: `absolute inset-0 w-full h-full block ${activeTab === "paint" ? "touch-none cursor-crosshair" : ""}`
2586
+ style: transformTool.active ? { cursor: transformCursor } : void 0,
2587
+ className: `absolute inset-0 w-full h-full block ${transformTool.active ? "touch-none" : activeTab === "paint" ? "touch-none cursor-crosshair" : ""}`
2426
2588
  }
2427
2589
  )
2428
2590
  }
2429
2591
  ),
2430
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("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: [
2431
- activeTab === "crop" && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
2432
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Aspect Ratio Presets" }),
2433
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "grid grid-cols-3 gap-2", children: [
2434
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2592
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("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: [
2593
+ activeTab === "crop" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
2594
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Aspect Ratio Presets" }),
2595
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "grid grid-cols-3 gap-2", children: [
2596
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2435
2597
  "button",
2436
2598
  {
2437
2599
  type: "button",
@@ -2443,7 +2605,7 @@ var ImageEditor = ({
2443
2605
  children: "Freeform"
2444
2606
  }
2445
2607
  ),
2446
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2608
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2447
2609
  "button",
2448
2610
  {
2449
2611
  type: "button",
@@ -2455,7 +2617,7 @@ var ImageEditor = ({
2455
2617
  children: "1:1 Square"
2456
2618
  }
2457
2619
  ),
2458
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2620
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2459
2621
  "button",
2460
2622
  {
2461
2623
  type: "button",
@@ -2467,7 +2629,7 @@ var ImageEditor = ({
2467
2629
  children: "4:3 Standard"
2468
2630
  }
2469
2631
  ),
2470
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2632
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2471
2633
  "button",
2472
2634
  {
2473
2635
  type: "button",
@@ -2479,7 +2641,7 @@ var ImageEditor = ({
2479
2641
  children: "16:9 Wide"
2480
2642
  }
2481
2643
  ),
2482
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2644
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2483
2645
  "button",
2484
2646
  {
2485
2647
  type: "button",
@@ -2491,7 +2653,7 @@ var ImageEditor = ({
2491
2653
  children: "3:2 Photo"
2492
2654
  }
2493
2655
  ),
2494
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2656
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2495
2657
  "button",
2496
2658
  {
2497
2659
  type: "button",
@@ -2504,10 +2666,10 @@ var ImageEditor = ({
2504
2666
  }
2505
2667
  )
2506
2668
  ] }),
2507
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
2508
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Orientation & Flips" }),
2509
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
2510
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2669
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
2670
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Orientation & Flips" }),
2671
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
2672
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2511
2673
  "button",
2512
2674
  {
2513
2675
  type: "button",
@@ -2516,7 +2678,7 @@ var ImageEditor = ({
2516
2678
  children: "Rotate -90\xB0"
2517
2679
  }
2518
2680
  ),
2519
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2681
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2520
2682
  "button",
2521
2683
  {
2522
2684
  type: "button",
@@ -2525,7 +2687,7 @@ var ImageEditor = ({
2525
2687
  children: "Rotate +90\xB0"
2526
2688
  }
2527
2689
  ),
2528
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2690
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2529
2691
  "button",
2530
2692
  {
2531
2693
  type: "button",
@@ -2534,7 +2696,7 @@ var ImageEditor = ({
2534
2696
  children: "Flip Horizontal"
2535
2697
  }
2536
2698
  ),
2537
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2699
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2538
2700
  "button",
2539
2701
  {
2540
2702
  type: "button",
@@ -2545,10 +2707,10 @@ var ImageEditor = ({
2545
2707
  )
2546
2708
  ] })
2547
2709
  ] }),
2548
- activeTab === "adjust" && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
2549
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-between", children: [
2550
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Color Adjustments" }),
2551
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2710
+ activeTab === "adjust" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
2711
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between", children: [
2712
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Color Adjustments" }),
2713
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2552
2714
  "button",
2553
2715
  {
2554
2716
  type: "button",
@@ -2558,25 +2720,25 @@ var ImageEditor = ({
2558
2720
  }
2559
2721
  )
2560
2722
  ] }),
2561
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Histogram, { histogram: editor.histogram }),
2562
- import_image_editor11.IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react10.default.Fragment, { children: [
2563
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2723
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Histogram, { histogram: editor.histogram }),
2724
+ import_image_editor12.IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react11.default.Fragment, { children: [
2725
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2564
2726
  ControlSlider,
2565
2727
  {
2566
2728
  spec,
2567
- value: (0, import_image_editor11.readAdjustmentControls)(state.adjustments)[spec.id],
2729
+ value: (0, import_image_editor12.readAdjustmentControls)(state.adjustments)[spec.id],
2568
2730
  disabled: spec.requiresProcess !== void 0 && legacyProcess,
2569
2731
  onChange: (v) => editor.setAdjustments({ [spec.id]: v })
2570
2732
  }
2571
2733
  ),
2572
- spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
2734
+ spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2573
2735
  "div",
2574
2736
  {
2575
2737
  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",
2576
2738
  "data-testid": "image-editor-process-notice",
2577
2739
  children: [
2578
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "Legacy rendering (process 1). Tint needs the current process." }),
2579
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2740
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Legacy rendering (process 1). Tint needs the current process." }),
2741
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2580
2742
  "button",
2581
2743
  {
2582
2744
  type: "button",
@@ -2589,7 +2751,7 @@ var ImageEditor = ({
2589
2751
  }
2590
2752
  )
2591
2753
  ] }, spec.id)),
2592
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2754
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2593
2755
  AdjustmentLayersPanel,
2594
2756
  {
2595
2757
  controller,
@@ -2598,19 +2760,41 @@ var ImageEditor = ({
2598
2760
  }
2599
2761
  ) })
2600
2762
  ] }),
2601
- activeTab === "layers" && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
2602
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Layers" }),
2603
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(LayersPanel, { controller })
2763
+ activeTab === "layers" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
2764
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Layers" }),
2765
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2766
+ "button",
2767
+ {
2768
+ type: "button",
2769
+ title: "Edit \u203A Free Transform (Ctrl/Cmd+T): the selected pixels, or the whole active layer",
2770
+ className: "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white self-start disabled:opacity-40",
2771
+ disabled: transformTool.active,
2772
+ onClick: () => transformTool.begin(),
2773
+ children: "Free Transform"
2774
+ }
2775
+ ),
2776
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(LayersPanel, { controller })
2604
2777
  ] }),
2605
- activeTab === "paint" && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
2606
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Paint" }),
2607
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(BrushOptionsBar, { controller }),
2608
- paintError && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "paint-error", children: paintError }),
2609
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(LayersPanel, { controller }) })
2778
+ activeTab === "paint" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
2779
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Paint" }),
2780
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(BrushOptionsBar, { controller }),
2781
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2782
+ "button",
2783
+ {
2784
+ type: "button",
2785
+ title: "Edit \u203A Free Transform (Ctrl/Cmd+T): the selected pixels, or the whole active layer",
2786
+ className: "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white self-start",
2787
+ disabled: transformTool.active,
2788
+ onClick: () => transformTool.begin(),
2789
+ children: "Free Transform"
2790
+ }
2791
+ ),
2792
+ paintError && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "paint-error", children: paintError }),
2793
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(LayersPanel, { controller }) })
2610
2794
  ] }),
2611
- activeTab === "annotate" && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
2612
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Draw & Annotate" }),
2613
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "grid grid-cols-3 gap-1.5", children: ["pen", "rect", "circle", "arrow", "line"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2795
+ activeTab === "annotate" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
2796
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Draw & Annotate" }),
2797
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "grid grid-cols-3 gap-1.5", children: ["pen", "rect", "circle", "arrow", "line"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2614
2798
  "button",
2615
2799
  {
2616
2800
  type: "button",
@@ -2620,9 +2804,9 @@ var ImageEditor = ({
2620
2804
  },
2621
2805
  t
2622
2806
  )) }),
2623
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-2 mt-2", children: [
2624
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "text-slate-400", children: "Color:" }),
2625
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2807
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2 mt-2", children: [
2808
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("label", { className: "text-slate-400", children: "Color:" }),
2809
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2626
2810
  "input",
2627
2811
  {
2628
2812
  type: "color",
@@ -2631,15 +2815,15 @@ var ImageEditor = ({
2631
2815
  className: "w-8 h-8 rounded border border-slate-700 cursor-pointer bg-transparent"
2632
2816
  }
2633
2817
  ),
2634
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex-1 ml-2", children: [
2635
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex justify-between text-slate-400 mb-0.5", children: [
2636
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "Width:" }),
2637
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "font-mono", children: [
2818
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex-1 ml-2", children: [
2819
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex justify-between text-slate-400 mb-0.5", children: [
2820
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Width:" }),
2821
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "font-mono", children: [
2638
2822
  strokeWidth,
2639
2823
  "px"
2640
2824
  ] })
2641
2825
  ] }),
2642
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2826
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2643
2827
  "input",
2644
2828
  {
2645
2829
  type: "range",
@@ -2652,10 +2836,10 @@ var ImageEditor = ({
2652
2836
  )
2653
2837
  ] })
2654
2838
  ] }),
2655
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
2656
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Add Text" }),
2657
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex gap-2", children: [
2658
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2839
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
2840
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Add Text" }),
2841
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex gap-2", children: [
2842
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2659
2843
  "input",
2660
2844
  {
2661
2845
  type: "text",
@@ -2666,7 +2850,7 @@ var ImageEditor = ({
2666
2850
  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"
2667
2851
  }
2668
2852
  ),
2669
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2853
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2670
2854
  "button",
2671
2855
  {
2672
2856
  type: "button",
@@ -2676,14 +2860,14 @@ var ImageEditor = ({
2676
2860
  }
2677
2861
  )
2678
2862
  ] }),
2679
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-between text-slate-400", children: [
2680
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "Font Size:" }),
2681
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "font-mono", children: [
2863
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between text-slate-400", children: [
2864
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Font Size:" }),
2865
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "font-mono", children: [
2682
2866
  fontSize,
2683
2867
  "px"
2684
2868
  ] })
2685
2869
  ] }),
2686
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2870
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2687
2871
  "input",
2688
2872
  {
2689
2873
  type: "range",
@@ -2694,14 +2878,14 @@ var ImageEditor = ({
2694
2878
  className: "w-full accent-indigo-500"
2695
2879
  }
2696
2880
  ),
2697
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
2698
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-between", children: [
2699
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "text-slate-400", children: [
2881
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
2882
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between", children: [
2883
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "text-slate-400", children: [
2700
2884
  "Layers (",
2701
2885
  state.annotations.length,
2702
2886
  ")"
2703
2887
  ] }),
2704
- state.selectedAnnotationId && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2888
+ state.selectedAnnotationId && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2705
2889
  "button",
2706
2890
  {
2707
2891
  type: "button",
@@ -2710,7 +2894,7 @@ var ImageEditor = ({
2710
2894
  children: "Delete Selected"
2711
2895
  }
2712
2896
  ),
2713
- state.annotations.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2897
+ state.annotations.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2714
2898
  "button",
2715
2899
  {
2716
2900
  type: "button",
@@ -2721,10 +2905,10 @@ var ImageEditor = ({
2721
2905
  )
2722
2906
  ] })
2723
2907
  ] }),
2724
- activeTab === "depth" && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
2725
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-between", children: [
2726
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Depth Masking" }),
2727
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2908
+ activeTab === "depth" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
2909
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between", children: [
2910
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Depth Masking" }),
2911
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2728
2912
  "button",
2729
2913
  {
2730
2914
  type: "button",
@@ -2734,8 +2918,8 @@ var ImageEditor = ({
2734
2918
  }
2735
2919
  )
2736
2920
  ] }),
2737
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300", children: [
2738
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2921
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300", children: [
2922
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2739
2923
  "input",
2740
2924
  {
2741
2925
  type: "checkbox",
@@ -2744,12 +2928,12 @@ var ImageEditor = ({
2744
2928
  className: "rounded accent-indigo-500"
2745
2929
  }
2746
2930
  ),
2747
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "Enable Depth / Alpha Mask" })
2931
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Enable Depth / Alpha Mask" })
2748
2932
  ] }),
2749
- state.depthMask.enabled && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
2750
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
2751
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "text-slate-400 block mb-1", children: "Mask Image URL:" }),
2752
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2933
+ state.depthMask.enabled && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
2934
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
2935
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("label", { className: "text-slate-400 block mb-1", children: "Mask Image URL:" }),
2936
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2753
2937
  "input",
2754
2938
  {
2755
2939
  type: "text",
@@ -2760,8 +2944,8 @@ var ImageEditor = ({
2760
2944
  }
2761
2945
  )
2762
2946
  ] }),
2763
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex gap-2", children: [
2764
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2947
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex gap-2", children: [
2948
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2765
2949
  "button",
2766
2950
  {
2767
2951
  type: "button",
@@ -2770,7 +2954,7 @@ var ImageEditor = ({
2770
2954
  children: "Threshold Mode"
2771
2955
  }
2772
2956
  ),
2773
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2957
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2774
2958
  "button",
2775
2959
  {
2776
2960
  type: "button",
@@ -2780,12 +2964,12 @@ var ImageEditor = ({
2780
2964
  }
2781
2965
  )
2782
2966
  ] }),
2783
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
2784
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
2785
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "Depth Start (Lower):" }),
2786
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[0] })
2967
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
2968
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
2969
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Depth Start (Lower):" }),
2970
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[0] })
2787
2971
  ] }),
2788
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2972
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2789
2973
  "input",
2790
2974
  {
2791
2975
  type: "range",
@@ -2799,12 +2983,12 @@ var ImageEditor = ({
2799
2983
  }
2800
2984
  )
2801
2985
  ] }),
2802
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
2803
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
2804
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "Depth Stop (Upper):" }),
2805
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[1] })
2986
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
2987
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
2988
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Depth Stop (Upper):" }),
2989
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[1] })
2806
2990
  ] }),
2807
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2991
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2808
2992
  "input",
2809
2993
  {
2810
2994
  type: "range",
@@ -2818,12 +3002,12 @@ var ImageEditor = ({
2818
3002
  }
2819
3003
  )
2820
3004
  ] }),
2821
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
2822
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
2823
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "Softness:" }),
2824
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "font-mono", children: state.depthMask.softness })
3005
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
3006
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
3007
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Softness:" }),
3008
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-mono", children: state.depthMask.softness })
2825
3009
  ] }),
2826
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
3010
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2827
3011
  "input",
2828
3012
  {
2829
3013
  type: "range",
@@ -2835,8 +3019,8 @@ var ImageEditor = ({
2835
3019
  }
2836
3020
  )
2837
3021
  ] }),
2838
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300 mt-1", children: [
2839
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
3022
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300 mt-1", children: [
3023
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2840
3024
  "input",
2841
3025
  {
2842
3026
  type: "checkbox",
@@ -2845,12 +3029,12 @@ var ImageEditor = ({
2845
3029
  className: "rounded accent-indigo-500"
2846
3030
  }
2847
3031
  ),
2848
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "Invert Mask" })
3032
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Invert Mask" })
2849
3033
  ] })
2850
3034
  ] })
2851
3035
  ] }),
2852
- activeTab === "select" && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
2853
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
3036
+ activeTab === "select" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
3037
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2854
3038
  SelectionOptionsBar,
2855
3039
  {
2856
3040
  controller,
@@ -2860,13 +3044,37 @@ var ImageEditor = ({
2860
3044
  quickMask: Boolean(state.quickMask)
2861
3045
  }
2862
3046
  ),
2863
- selectionError && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { role: "alert", className: "text-rose-400", children: selectionError }),
2864
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(RefineEdgePanel, { controller, selection: state.selection ?? null, layers: state.adjustments.layers })
3047
+ selectionError && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { role: "alert", className: "text-rose-400", children: selectionError }),
3048
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex gap-1", children: [
3049
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3050
+ "button",
3051
+ {
3052
+ type: "button",
3053
+ title: "Select \u203A Transform Selection: the outline only",
3054
+ className: "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white self-start disabled:opacity-40",
3055
+ disabled: transformTool.active,
3056
+ onClick: () => transformTool.begin({ content: "selection-outline" }),
3057
+ children: "Transform Selection"
3058
+ }
3059
+ ),
3060
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3061
+ "button",
3062
+ {
3063
+ type: "button",
3064
+ title: "Edit \u203A Free Transform: the selected pixels of the active layer",
3065
+ className: "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white self-start disabled:opacity-40",
3066
+ disabled: transformTool.active,
3067
+ onClick: () => transformTool.begin({ content: "selection" }),
3068
+ children: "Free Transform Pixels"
3069
+ }
3070
+ )
3071
+ ] }),
3072
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(RefineEdgePanel, { controller, selection: state.selection ?? null, layers: state.adjustments.layers })
2865
3073
  ] }),
2866
- activeTab === "ai" && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
2867
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex items-center justify-between gap-2 text-slate-300", children: [
2868
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "Results go to" }),
2869
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
3074
+ activeTab === "ai" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
3075
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center justify-between gap-2 text-slate-300", children: [
3076
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Results go to" }),
3077
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2870
3078
  "select",
2871
3079
  {
2872
3080
  "aria-label": "AI result target",
@@ -2874,54 +3082,54 @@ var ImageEditor = ({
2874
3082
  onChange: (e) => setAiTarget(e.target.value),
2875
3083
  className: "bg-slate-800 border border-slate-700 rounded px-1.5 py-1",
2876
3084
  children: [
2877
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "auto", children: controller.isMultiLayer ? "Auto (new layer)" : "Auto (replace image)" }),
2878
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "new-layer", children: "New layer / mask" }),
2879
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "replace", children: "Replace image" })
3085
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "auto", children: controller.isMultiLayer ? "Auto (new layer)" : "Auto (replace image)" }),
3086
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "new-layer", children: "New layer / mask" }),
3087
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "replace", children: "Replace image" })
2880
3088
  ]
2881
3089
  }
2882
3090
  )
2883
3091
  ] }),
2884
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
2885
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-between", children: [
2886
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
2887
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { className: "w-3.5 h-3.5 text-indigo-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("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" }) }),
3092
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
3093
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between", children: [
3094
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
3095
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { className: "w-3.5 h-3.5 text-indigo-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("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" }) }),
2888
3096
  "Background Removal"
2889
3097
  ] }),
2890
- isRemovingBg && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("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..." })
3098
+ isRemovingBg && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("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..." })
2891
3099
  ] }),
2892
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Isolate foreground subject with AI alpha transparency segmentation." }),
2893
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
3100
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Isolate foreground subject with AI alpha transparency segmentation." }),
3101
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2894
3102
  "button",
2895
3103
  {
2896
3104
  type: "button",
2897
3105
  onClick: handleRemoveBackground,
2898
3106
  disabled: isRemovingBg || isInpainting,
2899
3107
  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",
2900
- children: isRemovingBg ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
2901
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
3108
+ children: isRemovingBg ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
3109
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
2902
3110
  "Removing Background..."
2903
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
2904
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("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" }) }),
3111
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
3112
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("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" }) }),
2905
3113
  "Remove Background"
2906
3114
  ] })
2907
3115
  }
2908
3116
  )
2909
3117
  ] }),
2910
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
2911
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-between", children: [
2912
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
2913
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { className: "w-3.5 h-3.5 text-purple-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
2914
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("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" }),
2915
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "m14 7 3 3" })
3118
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
3119
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between", children: [
3120
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
3121
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("svg", { className: "w-3.5 h-3.5 text-purple-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
3122
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("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" }),
3123
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "m14 7 3 3" })
2916
3124
  ] }),
2917
3125
  "Generative Inpainting"
2918
3126
  ] }),
2919
- isInpainting && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("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..." })
3127
+ isInpainting && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("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..." })
2920
3128
  ] }),
2921
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Replace, modify, or fill selected regions using prompt-guided generative inpainting." }),
2922
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-col gap-1", children: [
2923
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { htmlFor: "ai-inpaint-prompt-react", className: "text-slate-300 text-[11px] font-medium", children: "Prompt" }),
2924
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
3129
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Replace, modify, or fill selected regions using prompt-guided generative inpainting." }),
3130
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-1", children: [
3131
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("label", { htmlFor: "ai-inpaint-prompt-react", className: "text-slate-300 text-[11px] font-medium", children: "Prompt" }),
3132
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2925
3133
  "textarea",
2926
3134
  {
2927
3135
  id: "ai-inpaint-prompt-react",
@@ -2933,10 +3141,10 @@ var ImageEditor = ({
2933
3141
  }
2934
3142
  )
2935
3143
  ] }),
2936
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-col gap-1", children: [
2937
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-slate-300 text-[11px] font-medium", children: "Target Mask Region" }),
2938
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "grid grid-cols-2 gap-1.5", children: [
2939
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
3144
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-1", children: [
3145
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-slate-300 text-[11px] font-medium", children: "Target Mask Region" }),
3146
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "grid grid-cols-2 gap-1.5", children: [
3147
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2940
3148
  "button",
2941
3149
  {
2942
3150
  type: "button",
@@ -2949,7 +3157,7 @@ var ImageEditor = ({
2949
3157
  ]
2950
3158
  }
2951
3159
  ),
2952
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
3160
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2953
3161
  "button",
2954
3162
  {
2955
3163
  type: "button",
@@ -2964,25 +3172,25 @@ var ImageEditor = ({
2964
3172
  )
2965
3173
  ] })
2966
3174
  ] }),
2967
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
3175
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2968
3176
  "button",
2969
3177
  {
2970
3178
  type: "button",
2971
3179
  onClick: handleInpaint,
2972
3180
  disabled: isInpainting || isRemovingBg || !inpaintPrompt.trim(),
2973
3181
  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",
2974
- children: isInpainting ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
2975
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
3182
+ children: isInpainting ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
3183
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
2976
3184
  "Generating Inpaint..."
2977
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
2978
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("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__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
3186
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("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" }) }),
2979
3187
  "Apply Inpainting"
2980
3188
  ] })
2981
3189
  }
2982
3190
  )
2983
3191
  ] }),
2984
- aiError && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "p-2.5 rounded-lg bg-rose-950/60 border border-rose-800 text-rose-300 text-[11px]", children: aiError }),
2985
- aiSuccess && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "p-2.5 rounded-lg bg-emerald-950/60 border border-emerald-800 text-emerald-300 text-[11px]", children: aiSuccess })
3192
+ aiError && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "p-2.5 rounded-lg bg-rose-950/60 border border-rose-800 text-rose-300 text-[11px]", children: aiError }),
3193
+ aiSuccess && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "p-2.5 rounded-lg bg-emerald-950/60 border border-emerald-800 text-emerald-300 text-[11px]", children: aiSuccess })
2986
3194
  ] })
2987
3195
  ] })
2988
3196
  ] })
@@ -2996,6 +3204,7 @@ var ImageEditor = ({
2996
3204
  BrushOptionsBar,
2997
3205
  ControlSlider,
2998
3206
  CurvesEditor,
3207
+ FreeTransformOptionsBar,
2999
3208
  Histogram,
3000
3209
  ImageEditor,
3001
3210
  LayerEffectsPanel,