@pixerate/editor-react 0.72.0 → 0.74.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.
@@ -159,7 +159,7 @@ function useImageEditor(options = {}) {
159
159
  }
160
160
 
161
161
  // src/image-editor/ImageEditor.tsx
162
- import React12, { useRef as useRef5, useEffect as useEffect10, useState as useState13, useCallback as useCallback2 } from "react";
162
+ import React13, { useRef as useRef5, useEffect as useEffect11, useState as useState14, useCallback as useCallback2 } from "react";
163
163
  import {
164
164
  canvasToImagePoint,
165
165
  hitTestCrop,
@@ -823,6 +823,7 @@ var LayerEffectsPanel = ({ controller, layerId, className }) => {
823
823
 
824
824
  // src/image-editor/LayersPanel.tsx
825
825
  import {
826
+ BIT_DEPTH_OPTIONS,
826
827
  BLEND_MODES as BLEND_MODES2,
827
828
  PSD_FILE_ACCEPT,
828
829
  downloadPsd,
@@ -949,6 +950,17 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
949
950
  children: "\u22EF"
950
951
  }
951
952
  ),
953
+ /* @__PURE__ */ jsx6(
954
+ "select",
955
+ {
956
+ "aria-label": "Bits per channel",
957
+ title: "Image \u203A Mode: bits per channel",
958
+ className: "rounded bg-slate-800 px-1 py-0.5 text-[11px] text-slate-200",
959
+ value: controller.bitDepth,
960
+ onChange: (e) => attempt(() => controller.setBitDepth(Number(e.target.value))),
961
+ children: BIT_DEPTH_OPTIONS.map((o) => /* @__PURE__ */ jsx6("option", { value: o.depth, title: o.title, children: o.label }, o.depth))
962
+ }
963
+ ),
952
964
  psd && /* @__PURE__ */ jsxs6(Fragment, { children: [
953
965
  /* @__PURE__ */ jsx6("button", { type: "button", className: iconButton, onClick: () => fileInput.current?.click(), children: "Open PSD\u2026" }),
954
966
  /* @__PURE__ */ jsx6("button", { type: "button", className: iconButton, onClick: () => psdTask(async () => (await downloadPsd(controller, psdFileName)).warnings), children: "Export PSD" }),
@@ -1463,15 +1475,100 @@ var BrushOptionsBar = ({ controller, className }) => {
1463
1475
  ] });
1464
1476
  };
1465
1477
 
1478
+ // src/image-editor/ColorProfilePanel.tsx
1479
+ import { useEffect as useEffect7, useState as useState8 } from "react";
1480
+ 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";
1482
+ var chip2 = "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white";
1483
+ var select = "rounded bg-slate-800 px-1 py-0.5 text-[11px] text-slate-200";
1484
+ 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);
1491
+ const view = colorPanelView(controller);
1492
+ const attempt = (fn) => {
1493
+ try {
1494
+ setError(null);
1495
+ fn();
1496
+ } catch (err) {
1497
+ setError(err instanceof Error ? err.message : String(err));
1498
+ }
1499
+ };
1500
+ const proofWith = (patch) => {
1501
+ const cur = view.proof;
1502
+ const id = patch.id ?? cur?.id ?? "coated-cmyk";
1503
+ attempt(
1504
+ () => controller.setProofSetup({
1505
+ profile: id,
1506
+ intent: patch.intent ?? cur?.intent ?? "relative",
1507
+ simulatePaper: patch.simulatePaper ?? cur?.simulatePaper ?? false,
1508
+ gamutWarning: patch.gamutWarning ?? cur?.gamutWarning ?? false
1509
+ })
1510
+ );
1511
+ };
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 })
1516
+ ] }),
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 })
1521
+ ] }),
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" }),
1527
+ "BPC"
1528
+ ] }),
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" })
1531
+ ] }),
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(
1535
+ "select",
1536
+ {
1537
+ "aria-label": "Proof profile",
1538
+ className: select,
1539
+ value: view.proof?.id ?? "",
1540
+ onChange: (e) => e.target.value ? proofWith({ id: e.target.value }) : attempt(() => controller.setProofSetup(null)),
1541
+ 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))
1544
+ ]
1545
+ }
1546
+ ),
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" }),
1551
+ "Paper"
1552
+ ] }),
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" }),
1555
+ "Gamut warning"
1556
+ ] })
1557
+ ] })
1558
+ ] }),
1559
+ error && /* @__PURE__ */ jsx8("p", { role: "alert", className: "text-rose-400", children: error })
1560
+ ] });
1561
+ };
1562
+
1466
1563
  // src/image-editor/SelectionOptionsBar.tsx
1467
- import { useState as useState8 } from "react";
1564
+ import { useState as useState9 } from "react";
1468
1565
  import {
1469
1566
  SELECTION_MODES,
1470
1567
  SELECTION_MODE_LABELS,
1471
1568
  SELECTION_TOOLS,
1472
1569
  describeSelection
1473
1570
  } from "@pixerate/editor/image-editor";
1474
- import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
1571
+ import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
1475
1572
  var MODIFY_OPS = [
1476
1573
  { op: "grow", label: "Grow" },
1477
1574
  { op: "shrink", label: "Shrink" },
@@ -1488,20 +1585,20 @@ var SelectionOptionsBar = ({
1488
1585
  quickMask,
1489
1586
  className = ""
1490
1587
  }) => {
1491
- const [radius, setRadius] = useState8(2);
1588
+ const [radius, setRadius] = useState9(2);
1492
1589
  const set = (patch) => onOptionsChange({ ...options, ...patch });
1493
1590
  const sel = selection === void 0 ? controller.getSelection() : selection;
1494
1591
  const qm = quickMask ?? Boolean(controller.getState().quickMask);
1495
- return /* @__PURE__ */ jsxs8("div", { "data-testid": "selection-options-bar", className: `flex flex-col gap-3 text-xs ${className}`, children: [
1496
- /* @__PURE__ */ jsx8("div", { role: "group", "aria-label": "Selection tool", className: "flex flex-wrap gap-1", children: SELECTION_TOOLS.map((t) => /* @__PURE__ */ jsx8("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)) }),
1497
- /* @__PURE__ */ jsx8("div", { role: "group", "aria-label": "Selection mode", className: "flex flex-wrap gap-1", children: SELECTION_MODES.map((m) => /* @__PURE__ */ jsx8("button", { type: "button", "aria-pressed": options.mode === m, className: btn(options.mode === m), onClick: () => set({ mode: m }), children: SELECTION_MODE_LABELS[m] }, m)) }),
1498
- options.tool === "wand" && /* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-2", children: [
1499
- /* @__PURE__ */ jsxs8("label", { className: "flex flex-col gap-1", children: [
1500
- /* @__PURE__ */ jsxs8("span", { className: "flex justify-between text-slate-400", children: [
1501
- /* @__PURE__ */ jsx8("span", { children: "Tolerance" }),
1502
- /* @__PURE__ */ jsx8("span", { className: "font-mono", children: options.tolerance })
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 })
1503
1600
  ] }),
1504
- /* @__PURE__ */ jsx8(
1601
+ /* @__PURE__ */ jsx9(
1505
1602
  "input",
1506
1603
  {
1507
1604
  type: "range",
@@ -1515,17 +1612,17 @@ var SelectionOptionsBar = ({
1515
1612
  }
1516
1613
  )
1517
1614
  ] }),
1518
- /* @__PURE__ */ jsxs8("label", { className: "flex items-center gap-2 text-slate-300", children: [
1519
- /* @__PURE__ */ jsx8("input", { type: "checkbox", checked: options.contiguous, onChange: (e) => set({ contiguous: e.target.checked }) }),
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 }) }),
1520
1617
  "Contiguous"
1521
1618
  ] }),
1522
- /* @__PURE__ */ jsxs8("label", { className: "flex items-center gap-2 text-slate-300", children: [
1523
- /* @__PURE__ */ jsx8("input", { type: "checkbox", checked: options.sampleMerged, onChange: (e) => set({ sampleMerged: e.target.checked }) }),
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 }) }),
1524
1621
  "Sample adjusted image"
1525
1622
  ] }),
1526
- /* @__PURE__ */ jsxs8("label", { className: "flex items-center gap-2 text-slate-300", children: [
1623
+ /* @__PURE__ */ jsxs9("label", { className: "flex items-center gap-2 text-slate-300", children: [
1527
1624
  "Sample",
1528
- /* @__PURE__ */ jsxs8(
1625
+ /* @__PURE__ */ jsxs9(
1529
1626
  "select",
1530
1627
  {
1531
1628
  "aria-label": "Sample from",
@@ -1533,27 +1630,27 @@ var SelectionOptionsBar = ({
1533
1630
  onChange: (e) => set({ sample: e.target.value }),
1534
1631
  className: "bg-slate-800 border border-slate-700 rounded px-1 py-0.5",
1535
1632
  children: [
1536
- /* @__PURE__ */ jsx8("option", { value: "composite", children: "All layers" }),
1537
- /* @__PURE__ */ jsx8("option", { value: "active-layer", children: "Active layer" })
1633
+ /* @__PURE__ */ jsx9("option", { value: "composite", children: "All layers" }),
1634
+ /* @__PURE__ */ jsx9("option", { value: "active-layer", children: "Active layer" })
1538
1635
  ]
1539
1636
  }
1540
1637
  )
1541
1638
  ] })
1542
1639
  ] }),
1543
- /* @__PURE__ */ jsxs8("label", { className: "flex items-center gap-2 text-slate-300", children: [
1544
- /* @__PURE__ */ jsx8("input", { type: "checkbox", checked: options.antiAlias, onChange: (e) => set({ antiAlias: e.target.checked }) }),
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 }) }),
1545
1642
  "Anti-alias"
1546
1643
  ] }),
1547
- /* @__PURE__ */ jsxs8("div", { className: "flex flex-wrap gap-1", children: [
1548
- /* @__PURE__ */ jsx8("button", { type: "button", className: btn(false), onClick: () => controller.selectAll(), children: "Select All" }),
1549
- /* @__PURE__ */ jsx8("button", { type: "button", className: btn(false), disabled: !sel, onClick: () => controller.deselect(), children: "Deselect" }),
1550
- /* @__PURE__ */ jsx8("button", { type: "button", className: btn(false), onClick: () => controller.invertSelection(), children: "Inverse" }),
1551
- /* @__PURE__ */ jsx8("button", { type: "button", "aria-pressed": qm, className: btn(qm), onClick: () => controller.setQuickMask(!qm), children: "Quick Mask" })
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" })
1552
1649
  ] }),
1553
- /* @__PURE__ */ jsxs8("div", { className: "flex flex-wrap items-center gap-1", children: [
1554
- /* @__PURE__ */ jsxs8("label", { className: "flex items-center gap-1 text-slate-400", children: [
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: [
1555
1652
  "Radius",
1556
- /* @__PURE__ */ jsx8(
1653
+ /* @__PURE__ */ jsx9(
1557
1654
  "input",
1558
1655
  {
1559
1656
  type: "number",
@@ -1567,29 +1664,29 @@ var SelectionOptionsBar = ({
1567
1664
  }
1568
1665
  )
1569
1666
  ] }),
1570
- MODIFY_OPS.map(({ op, label }) => /* @__PURE__ */ jsx8("button", { type: "button", className: btn(false), disabled: !sel, onClick: () => controller.modifySelection(op, radius), children: label }, op))
1667
+ MODIFY_OPS.map(({ op, label }) => /* @__PURE__ */ jsx9("button", { type: "button", className: btn(false), disabled: !sel, onClick: () => controller.modifySelection(op, radius), children: label }, op))
1571
1668
  ] }),
1572
- /* @__PURE__ */ jsx8("p", { "data-testid": "selection-status", className: "text-slate-400", children: describeSelection(sel) })
1669
+ /* @__PURE__ */ jsx9("p", { "data-testid": "selection-status", className: "text-slate-400", children: describeSelection(sel) })
1573
1670
  ] });
1574
1671
  };
1575
1672
 
1576
1673
  // src/image-editor/RefineEdgePanel.tsx
1577
- import { useState as useState9 } from "react";
1674
+ import { useState as useState10 } from "react";
1578
1675
  import {
1579
1676
  ADJUSTMENT_KINDS as ADJUSTMENT_KINDS2,
1580
1677
  REFINE_EDGE_CONTROLS,
1581
1678
  adjustmentKindLabel as adjustmentKindLabel2,
1582
1679
  layerMaskFromSelection
1583
1680
  } from "@pixerate/editor/image-editor";
1584
- import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
1681
+ import { Fragment as Fragment3, jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
1585
1682
  var DEFAULT_PARAMS = { radius: 8, smartRadius: false, smooth: 0, feather: 0, contrast: 0, shiftEdge: 0 };
1586
1683
  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";
1587
1684
  var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
1588
- const [params, setParams] = useState9(DEFAULT_PARAMS);
1589
- const [busy, setBusy] = useState9(false);
1590
- const [error, setError] = useState9(null);
1591
- const [layerId, setLayerId] = useState9("");
1592
- const [newKind, setNewKind] = useState9("hueSaturation");
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");
1593
1690
  const sel = selection === void 0 ? controller.getSelection() : selection;
1594
1691
  const list = layers ?? controller.getAdjustmentLayers();
1595
1692
  const target = list.find((l) => l.id === layerId) ?? list[list.length - 1];
@@ -1604,17 +1701,17 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
1604
1701
  setBusy(false);
1605
1702
  }
1606
1703
  };
1607
- return /* @__PURE__ */ jsxs9("div", { "data-testid": "refine-edge-panel", className: `flex flex-col gap-3 text-xs ${className}`, children: [
1608
- /* @__PURE__ */ jsx9("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Refine Edge" }),
1609
- REFINE_EDGE_CONTROLS.map((c) => /* @__PURE__ */ jsxs9("label", { className: "flex flex-col gap-1", children: [
1610
- /* @__PURE__ */ jsxs9("span", { className: "flex justify-between text-slate-400", children: [
1611
- /* @__PURE__ */ jsx9("span", { children: c.label }),
1612
- /* @__PURE__ */ jsxs9("span", { className: "font-mono", children: [
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: [
1613
1710
  params[c.id],
1614
1711
  c.unit
1615
1712
  ] })
1616
1713
  ] }),
1617
- /* @__PURE__ */ jsx9(
1714
+ /* @__PURE__ */ jsx10(
1618
1715
  "input",
1619
1716
  {
1620
1717
  type: "range",
@@ -1628,28 +1725,28 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
1628
1725
  }
1629
1726
  )
1630
1727
  ] }, c.id)),
1631
- /* @__PURE__ */ jsxs9("label", { className: "flex items-center gap-2 text-slate-300", children: [
1632
- /* @__PURE__ */ jsx9("input", { type: "checkbox", checked: params.smartRadius, onChange: (e) => setParams({ ...params, smartRadius: e.target.checked }) }),
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 }) }),
1633
1730
  "Smart Radius"
1634
1731
  ] }),
1635
- /* @__PURE__ */ jsxs9("div", { className: "flex gap-1", children: [
1636
- /* @__PURE__ */ jsx9("button", { type: "button", className: button2, disabled: !sel || busy, onClick: refine, children: "Refine Edge" }),
1637
- /* @__PURE__ */ jsx9("button", { type: "button", className: button2, onClick: () => setParams(DEFAULT_PARAMS), children: "Reset" })
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" })
1638
1735
  ] }),
1639
- error && /* @__PURE__ */ jsx9("p", { role: "alert", className: "text-rose-400", children: error }),
1640
- /* @__PURE__ */ jsx9("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] mt-2", children: "Layer Mask" }),
1641
- /* @__PURE__ */ jsxs9("div", { className: "flex gap-1 items-center", children: [
1642
- /* @__PURE__ */ jsx9(
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(
1643
1740
  "select",
1644
1741
  {
1645
1742
  "aria-label": "New masked layer kind",
1646
1743
  value: newKind,
1647
1744
  onChange: (e) => setNewKind(e.target.value),
1648
1745
  className: "flex-1 bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
1649
- children: ADJUSTMENT_KINDS2.map((k) => /* @__PURE__ */ jsx9("option", { value: k.kind, children: k.label }, k.kind))
1746
+ children: ADJUSTMENT_KINDS2.map((k) => /* @__PURE__ */ jsx10("option", { value: k.kind, children: k.label }, k.kind))
1650
1747
  }
1651
1748
  ),
1652
- /* @__PURE__ */ jsx9(
1749
+ /* @__PURE__ */ jsx10(
1653
1750
  "button",
1654
1751
  {
1655
1752
  type: "button",
@@ -1660,35 +1757,35 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
1660
1757
  }
1661
1758
  )
1662
1759
  ] }),
1663
- list.length > 0 && target && /* @__PURE__ */ jsxs9("div", { className: "flex flex-col gap-2", children: [
1664
- /* @__PURE__ */ jsx9(
1760
+ list.length > 0 && target && /* @__PURE__ */ jsxs10("div", { className: "flex flex-col gap-2", children: [
1761
+ /* @__PURE__ */ jsx10(
1665
1762
  "select",
1666
1763
  {
1667
1764
  "aria-label": "Mask layer",
1668
1765
  value: target.id,
1669
1766
  onChange: (e) => setLayerId(e.target.value),
1670
1767
  className: "bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
1671
- children: list.map((l) => /* @__PURE__ */ jsxs9("option", { value: l.id, children: [
1768
+ children: list.map((l) => /* @__PURE__ */ jsxs10("option", { value: l.id, children: [
1672
1769
  l.name || adjustmentKindLabel2(l.kind),
1673
1770
  l.mask ? " (masked)" : ""
1674
1771
  ] }, l.id))
1675
1772
  }
1676
1773
  ),
1677
- /* @__PURE__ */ jsxs9("div", { className: "flex flex-wrap gap-1", children: [
1678
- /* @__PURE__ */ jsx9("button", { type: "button", className: button2, disabled: !sel, onClick: () => controller.applySelectionAsLayerMask(target.id), children: "Mask with Selection" }),
1679
- /* @__PURE__ */ jsx9("button", { type: "button", className: button2, disabled: !target.mask, onClick: () => controller.selectionFromLayerMask(target.id), children: "Load as Selection" }),
1680
- /* @__PURE__ */ jsx9("button", { type: "button", className: button2, disabled: !target.mask, onClick: () => controller.setAdjustmentLayerMask(target.id, null), children: "Remove Mask" })
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" })
1681
1778
  ] }),
1682
- target.mask && /* @__PURE__ */ jsxs9(Fragment2, { children: [
1683
- /* @__PURE__ */ jsxs9("label", { className: "flex flex-col gap-1", children: [
1684
- /* @__PURE__ */ jsxs9("span", { className: "flex justify-between text-slate-400", children: [
1685
- /* @__PURE__ */ jsx9("span", { children: "Density" }),
1686
- /* @__PURE__ */ jsxs9("span", { className: "font-mono", children: [
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: [
1687
1784
  Math.round((target.mask.density ?? 1) * 100),
1688
1785
  "%"
1689
1786
  ] })
1690
1787
  ] }),
1691
- /* @__PURE__ */ jsx9(
1788
+ /* @__PURE__ */ jsx10(
1692
1789
  "input",
1693
1790
  {
1694
1791
  type: "range",
@@ -1702,15 +1799,15 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
1702
1799
  }
1703
1800
  )
1704
1801
  ] }),
1705
- /* @__PURE__ */ jsxs9("label", { className: "flex flex-col gap-1", children: [
1706
- /* @__PURE__ */ jsxs9("span", { className: "flex justify-between text-slate-400", children: [
1707
- /* @__PURE__ */ jsx9("span", { children: "Mask Feather" }),
1708
- /* @__PURE__ */ jsxs9("span", { className: "font-mono", children: [
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: [
1709
1806
  target.mask.feather ?? 0,
1710
1807
  "px"
1711
1808
  ] })
1712
1809
  ] }),
1713
- /* @__PURE__ */ jsx9(
1810
+ /* @__PURE__ */ jsx10(
1714
1811
  "input",
1715
1812
  {
1716
1813
  type: "range",
@@ -1730,14 +1827,14 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
1730
1827
  };
1731
1828
 
1732
1829
  // src/image-editor/FreeTransformOptionsBar.tsx
1733
- import { useEffect as useEffect7, useState as useState10 } from "react";
1830
+ import { useEffect as useEffect8, useState as useState11 } from "react";
1734
1831
  import { FREE_TRANSFORM_FIELDS, FREE_TRANSFORM_MODE_OPTIONS, INTERPOLATIONS, TRANSFORM_ANCHORS, WARP_GRID_OPTIONS, WARP_STYLE_OPTIONS } from "@pixerate/editor/image-editor";
1735
- import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
1736
- 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"}`;
1832
+ import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
1833
+ 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"}`;
1737
1834
  var round = (v, unit) => unit === "px" ? Math.round(v * 10) / 10 : Math.round(v * 100) / 100;
1738
1835
  var FreeTransformOptionsBar = ({ tool, className }) => {
1739
- const [, setTick] = useState10(0);
1740
- useEffect7(() => tool.subscribe(() => setTick((n) => n + 1)), [tool]);
1836
+ const [, setTick] = useState11(0);
1837
+ useEffect8(() => tool.subscribe(() => setTick((n) => n + 1)), [tool]);
1741
1838
  const bar = tool.bar();
1742
1839
  if (!tool.active || !bar) return null;
1743
1840
  const warp = tool.warpBar();
@@ -1749,17 +1846,17 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
1749
1846
  const v = Number(raw);
1750
1847
  if (raw.trim() !== "" && Number.isFinite(v) && Math.abs(v - bar[field]) > 1e-9) tool.setField(field, v);
1751
1848
  };
1752
- return /* @__PURE__ */ jsxs10("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: [
1753
- /* @__PURE__ */ jsx10("div", { className: "flex gap-1", role: "group", "aria-label": "Transform mode", children: FREE_TRANSFORM_MODE_OPTIONS.map((m) => /* @__PURE__ */ jsx10("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)) }),
1754
- /* @__PURE__ */ jsx10("div", { className: "grid grid-cols-3 gap-px", role: "group", "aria-label": "Reference point", children: TRANSFORM_ANCHORS.map((a) => /* @__PURE__ */ jsx10("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)) }),
1755
- tool.mode === "warp" && /* @__PURE__ */ jsxs10("div", { className: "flex flex-wrap items-center gap-2", role: "group", "aria-label": "Warp options", children: [
1756
- /* @__PURE__ */ jsxs10("label", { className: "flex items-center gap-1", children: [
1757
- /* @__PURE__ */ jsx10("span", { className: "text-slate-400", children: "Warp" }),
1758
- /* @__PURE__ */ jsx10("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__ */ jsx10("option", { value: o.id, children: o.label }, o.id)) })
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)) })
1759
1856
  ] }),
1760
- ["bend", "horizontal", "vertical"].map((k) => /* @__PURE__ */ jsxs10("label", { className: "flex items-center gap-1", children: [
1761
- /* @__PURE__ */ jsx10("span", { className: "text-slate-400", children: k === "bend" ? "Bend" : k === "horizontal" ? "H" : "V" }),
1762
- /* @__PURE__ */ jsx10(
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(
1763
1860
  "input",
1764
1861
  {
1765
1862
  type: "number",
@@ -1780,23 +1877,23 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
1780
1877
  },
1781
1878
  `${k}:${warp[k]}`
1782
1879
  ),
1783
- /* @__PURE__ */ jsx10("span", { className: "text-slate-500", children: "%" })
1880
+ /* @__PURE__ */ jsx11("span", { className: "text-slate-500", children: "%" })
1784
1881
  ] }, k)),
1785
- /* @__PURE__ */ jsx10(
1882
+ /* @__PURE__ */ jsx11(
1786
1883
  "button",
1787
1884
  {
1788
1885
  type: "button",
1789
1886
  title: "Bend along the vertical axis",
1790
1887
  "aria-pressed": warp.orientation === "vertical",
1791
1888
  disabled: warp.style === "custom",
1792
- className: chip2(warp.orientation === "vertical"),
1889
+ className: chip3(warp.orientation === "vertical"),
1793
1890
  onClick: () => tool.setWarp({ orientation: warp.orientation === "vertical" ? "horizontal" : "vertical" }),
1794
1891
  children: "Vertical"
1795
1892
  }
1796
1893
  ),
1797
- /* @__PURE__ */ jsxs10("label", { className: "flex items-center gap-1", children: [
1798
- /* @__PURE__ */ jsx10("span", { className: "text-slate-400", children: "Grid" }),
1799
- /* @__PURE__ */ jsx10(
1894
+ /* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-1", children: [
1895
+ /* @__PURE__ */ jsx11("span", { className: "text-slate-400", children: "Grid" }),
1896
+ /* @__PURE__ */ jsx11(
1800
1897
  "select",
1801
1898
  {
1802
1899
  "aria-label": "Warp grid",
@@ -1806,14 +1903,14 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
1806
1903
  tool.setWarp({ columns: g.columns, rows: g.rows });
1807
1904
  },
1808
1905
  className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
1809
- children: WARP_GRID_OPTIONS.map((g) => /* @__PURE__ */ jsx10("option", { value: g.id, children: g.label }, g.id))
1906
+ children: WARP_GRID_OPTIONS.map((g) => /* @__PURE__ */ jsx11("option", { value: g.id, children: g.label }, g.id))
1810
1907
  }
1811
1908
  )
1812
1909
  ] })
1813
1910
  ] }),
1814
- tool.mode !== "warp" && FREE_TRANSFORM_FIELDS.map((f) => /* @__PURE__ */ jsxs10("label", { className: "flex items-center gap-1", title: f.title, children: [
1815
- /* @__PURE__ */ jsx10("span", { className: "text-slate-400", children: f.label }),
1816
- /* @__PURE__ */ jsx10(
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(
1817
1914
  "input",
1818
1915
  {
1819
1916
  type: "number",
@@ -1833,14 +1930,14 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
1833
1930
  },
1834
1931
  `${f.id}:${round(bar[f.id], f.unit)}`
1835
1932
  ),
1836
- /* @__PURE__ */ jsx10("span", { className: "text-slate-500", children: f.unit }),
1837
- f.id === "scaleX" && /* @__PURE__ */ jsx10(
1933
+ /* @__PURE__ */ jsx11("span", { className: "text-slate-500", children: f.unit }),
1934
+ f.id === "scaleX" && /* @__PURE__ */ jsx11(
1838
1935
  "button",
1839
1936
  {
1840
1937
  type: "button",
1841
1938
  "aria-label": "Keep width and height proportional",
1842
1939
  "aria-pressed": tool.proportional,
1843
- className: chip2(tool.proportional),
1940
+ className: chip3(tool.proportional),
1844
1941
  onClick: () => {
1845
1942
  tool.proportional = !tool.proportional;
1846
1943
  setTick((n) => n + 1);
@@ -1849,34 +1946,34 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
1849
1946
  }
1850
1947
  )
1851
1948
  ] }, f.id)),
1852
- /* @__PURE__ */ jsxs10("label", { className: "flex items-center gap-1", children: [
1853
- /* @__PURE__ */ jsx10("span", { className: "text-slate-400", children: "Interpolation" }),
1854
- /* @__PURE__ */ jsx10(
1949
+ /* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-1", children: [
1950
+ /* @__PURE__ */ jsx11("span", { className: "text-slate-400", children: "Interpolation" }),
1951
+ /* @__PURE__ */ jsx11(
1855
1952
  "select",
1856
1953
  {
1857
1954
  "aria-label": "Interpolation",
1858
1955
  value: tool.interpolation,
1859
1956
  onChange: (e) => tool.setInterpolation(e.target.value),
1860
1957
  className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
1861
- children: INTERPOLATIONS.map((i) => /* @__PURE__ */ jsx10("option", { value: i, children: i[0].toUpperCase() + i.slice(1) }, i))
1958
+ children: INTERPOLATIONS.map((i) => /* @__PURE__ */ jsx11("option", { value: i, children: i[0].toUpperCase() + i.slice(1) }, i))
1862
1959
  }
1863
1960
  )
1864
1961
  ] }),
1865
- /* @__PURE__ */ jsx10("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" }),
1866
- /* @__PURE__ */ jsx10("button", { type: "button", title: "Cancel (Esc)", className: chip2(false), onClick: () => tool.cancel(), children: "Cancel" }),
1867
- tool.error && /* @__PURE__ */ jsx10("span", { role: "alert", className: "text-rose-400", children: tool.error })
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 })
1868
1965
  ] });
1869
1966
  };
1870
1967
 
1871
1968
  // src/image-editor/ShapeOptionsBar.tsx
1872
- import { useEffect as useEffect8, useState as useState11 } from "react";
1969
+ import { useEffect as useEffect9, useState as useState12 } from "react";
1873
1970
  import { LIVE_SHAPE_KINDS, SHAPE_KIND_LABELS, applyShapeOptions } from "@pixerate/editor/image-editor";
1874
- import { Fragment as Fragment3, jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
1875
- 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"}`;
1971
+ import { Fragment as Fragment4, jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
1972
+ 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"}`;
1876
1973
  var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
1877
- const [, setTick] = useState11(0);
1878
- useEffect8(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
1879
- const [error, setError] = useState11(null);
1974
+ const [, setTick] = useState12(0);
1975
+ useEffect9(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
1976
+ const [error, setError] = useState12(null);
1880
1977
  const active = controller.getActiveLayer();
1881
1978
  const shapeId = active?.type === "shape" ? active.id : null;
1882
1979
  const set = (change) => {
@@ -1890,13 +1987,13 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
1890
1987
  }
1891
1988
  };
1892
1989
  const num = (v, min, max) => Math.max(min, Math.min(max, Number(v) || min));
1893
- return /* @__PURE__ */ jsxs11("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "shape-options", children: [
1894
- /* @__PURE__ */ jsx11("div", { className: "flex flex-wrap gap-1", role: "toolbar", "aria-label": "Shape kind", children: LIVE_SHAPE_KINDS.map((k) => /* @__PURE__ */ jsx11("button", { type: "button", "aria-pressed": options.kind === k, className: chip3(options.kind === k), onClick: () => onChange({ ...options, kind: k }), children: SHAPE_KIND_LABELS[k] }, k)) }),
1895
- /* @__PURE__ */ jsxs11("div", { className: "flex flex-wrap items-center gap-3", children: [
1896
- /* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-1", children: [
1897
- /* @__PURE__ */ jsx11("input", { type: "checkbox", "aria-label": "Fill", checked: options.fill !== null, onChange: (e) => set({ fill: e.target.checked ? "#4f46e5" : null }) }),
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 }) }),
1898
1995
  "Fill",
1899
- /* @__PURE__ */ jsx11(
1996
+ /* @__PURE__ */ jsx12(
1900
1997
  "input",
1901
1998
  {
1902
1999
  type: "color",
@@ -1908,10 +2005,10 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
1908
2005
  }
1909
2006
  )
1910
2007
  ] }),
1911
- /* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-1", children: [
1912
- /* @__PURE__ */ jsx11("input", { type: "checkbox", "aria-label": "Stroke", checked: options.stroke !== null, onChange: (e) => set({ stroke: e.target.checked ? "#000000" : null }) }),
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 }) }),
1913
2010
  "Stroke",
1914
- /* @__PURE__ */ jsx11(
2011
+ /* @__PURE__ */ jsx12(
1915
2012
  "input",
1916
2013
  {
1917
2014
  type: "color",
@@ -1923,9 +2020,9 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
1923
2020
  }
1924
2021
  )
1925
2022
  ] }),
1926
- /* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-1", children: [
2023
+ /* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", children: [
1927
2024
  "Width",
1928
- /* @__PURE__ */ jsx11(
2025
+ /* @__PURE__ */ jsx12(
1929
2026
  "input",
1930
2027
  {
1931
2028
  type: "number",
@@ -1939,23 +2036,23 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
1939
2036
  )
1940
2037
  ] })
1941
2038
  ] }),
1942
- /* @__PURE__ */ jsxs11("div", { className: "flex flex-wrap items-center gap-3", children: [
1943
- options.kind === "rect" && /* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-1", children: [
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: [
1944
2041
  "Radius",
1945
- /* @__PURE__ */ jsx11("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" })
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" })
1946
2043
  ] }),
1947
- options.kind === "polygon" && /* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-1", children: [
2044
+ options.kind === "polygon" && /* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", children: [
1948
2045
  "Sides",
1949
- /* @__PURE__ */ jsx11("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" })
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" })
1950
2047
  ] }),
1951
- options.kind === "star" && /* @__PURE__ */ jsxs11(Fragment3, { children: [
1952
- /* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-1", children: [
2048
+ options.kind === "star" && /* @__PURE__ */ jsxs12(Fragment4, { children: [
2049
+ /* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", children: [
1953
2050
  "Points",
1954
- /* @__PURE__ */ jsx11("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" })
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" })
1955
2052
  ] }),
1956
- /* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-1", children: [
2053
+ /* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", children: [
1957
2054
  "Inner",
1958
- /* @__PURE__ */ jsx11(
2055
+ /* @__PURE__ */ jsx12(
1959
2056
  "input",
1960
2057
  {
1961
2058
  type: "range",
@@ -1970,33 +2067,33 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
1970
2067
  )
1971
2068
  ] })
1972
2069
  ] }),
1973
- options.kind === "line" && /* @__PURE__ */ jsxs11(Fragment3, { children: [
1974
- /* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-1", children: [
2070
+ options.kind === "line" && /* @__PURE__ */ jsxs12(Fragment4, { children: [
2071
+ /* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", children: [
1975
2072
  "Weight",
1976
- /* @__PURE__ */ jsx11("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" })
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" })
1977
2074
  ] }),
1978
- /* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-1", children: [
1979
- /* @__PURE__ */ jsx11("input", { type: "checkbox", "aria-label": "Arrowhead", checked: options.arrow, onChange: (e) => set({ arrow: e.target.checked }) }),
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 }) }),
1980
2077
  "Arrowhead"
1981
2078
  ] })
1982
2079
  ] })
1983
2080
  ] }),
1984
- /* @__PURE__ */ jsx11("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." }),
1985
- error && /* @__PURE__ */ jsx11("p", { role: "alert", className: "text-rose-400", children: error })
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 })
1986
2083
  ] });
1987
2084
  };
1988
2085
 
1989
2086
  // src/image-editor/TypeOptionsBar.tsx
1990
- import { useEffect as useEffect9, useState as useState12 } from "react";
2087
+ import { useEffect as useEffect10, useState as useState13 } from "react";
1991
2088
  import { TEXT_ALIGNS } from "@pixerate/editor/image-editor";
1992
- import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
1993
- 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"}`;
2089
+ import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
2090
+ 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"}`;
1994
2091
  var ALIGN_LABELS = { left: "Left", center: "Centre", right: "Right", justify: "Justify" };
1995
2092
  var TypeOptionsBar = ({ controller, options, onChange, session, className }) => {
1996
- const [, setTick] = useState12(0);
1997
- useEffect9(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
1998
- useEffect9(() => session?.subscribe(() => setTick((n) => n + 1)), [session]);
1999
- const [error, setError] = useState12(null);
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);
2000
2097
  const active = controller.getActiveLayer();
2001
2098
  const typeId = !session && active?.type === "type" ? active.id : null;
2002
2099
  const here = session?.alive ? session.styleHere() : {};
@@ -2028,11 +2125,11 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
2028
2125
  setError(e instanceof Error ? e.message : String(e));
2029
2126
  }
2030
2127
  };
2031
- return /* @__PURE__ */ jsxs12("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "type-options", children: [
2032
- /* @__PURE__ */ jsxs12("div", { className: "flex flex-wrap items-center gap-2", children: [
2033
- /* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", children: [
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: [
2034
2131
  "Font",
2035
- /* @__PURE__ */ jsx12(
2132
+ /* @__PURE__ */ jsx13(
2036
2133
  "input",
2037
2134
  {
2038
2135
  list: "pixerate-type-fonts",
@@ -2042,11 +2139,11 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
2042
2139
  className: "w-32 rounded border border-slate-700 bg-slate-950 px-1 py-0.5"
2043
2140
  }
2044
2141
  ),
2045
- /* @__PURE__ */ jsx12("datalist", { id: "pixerate-type-fonts", children: fonts.map((f) => /* @__PURE__ */ jsx12("option", { value: f }, f)) })
2142
+ /* @__PURE__ */ jsx13("datalist", { id: "pixerate-type-fonts", children: fonts.map((f) => /* @__PURE__ */ jsx13("option", { value: f }, f)) })
2046
2143
  ] }),
2047
- /* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", children: [
2144
+ /* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-1", children: [
2048
2145
  "Size",
2049
- /* @__PURE__ */ jsx12(
2146
+ /* @__PURE__ */ jsx13(
2050
2147
  "input",
2051
2148
  {
2052
2149
  type: "number",
@@ -2059,24 +2156,24 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
2059
2156
  }
2060
2157
  )
2061
2158
  ] }),
2062
- /* @__PURE__ */ jsx12("button", { type: "button", "aria-pressed": shown.fontWeight >= 600, className: `${chip4(shown.fontWeight >= 600)} font-bold`, onClick: () => style({ fontWeight: shown.fontWeight >= 600 ? 400 : 700 }), children: "B" }),
2063
- /* @__PURE__ */ jsx12("button", { type: "button", "aria-pressed": shown.italic, className: `${chip4(shown.italic)} italic`, onClick: () => style({ italic: !shown.italic }), children: "I" }),
2064
- /* @__PURE__ */ jsx12("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" })
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" })
2065
2162
  ] }),
2066
- /* @__PURE__ */ jsx12("div", { className: "flex gap-1", role: "toolbar", "aria-label": "Alignment", children: TEXT_ALIGNS.map((a) => /* @__PURE__ */ jsx12("button", { type: "button", "aria-pressed": options.align === a, className: chip4(options.align === a), onClick: () => style({ align: a }), children: ALIGN_LABELS[a] }, a)) }),
2067
- /* @__PURE__ */ jsx12("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." }),
2068
- missing.length > 0 && /* @__PURE__ */ jsxs12("p", { role: "status", className: "text-amber-400", "data-testid": "type-missing-fonts", children: [
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: [
2069
2166
  "Missing ",
2070
2167
  missing.length === 1 ? "font" : "fonts",
2071
2168
  ": ",
2072
2169
  missing.join(", ")
2073
2170
  ] }),
2074
- error && /* @__PURE__ */ jsx12("p", { role: "alert", className: "text-rose-400", children: error })
2171
+ error && /* @__PURE__ */ jsx13("p", { role: "alert", className: "text-rose-400", children: error })
2075
2172
  ] });
2076
2173
  };
2077
2174
 
2078
2175
  // src/image-editor/ImageEditor.tsx
2079
- import { Fragment as Fragment4, jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
2176
+ import { Fragment as Fragment5, jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
2080
2177
  var ImageEditor = ({
2081
2178
  editor: externalEditor,
2082
2179
  src,
@@ -2094,9 +2191,9 @@ var ImageEditor = ({
2094
2191
  const legacyProcess = normalizeProcessVersion(state.adjustments.process) < LATEST_PROCESS_VERSION;
2095
2192
  const canvasRef = useRef5(null);
2096
2193
  const containerRef = useRef5(null);
2097
- const [activeTab, setActiveTab] = useState13("crop");
2098
- const [activeCropRatio, setActiveCropRatio] = useState13(null);
2099
- const [selectionOptions, setSelectionOptions] = useState13(DEFAULT_SELECTION_TOOL_OPTIONS);
2194
+ const [activeTab, setActiveTab] = useState14("crop");
2195
+ const [activeCropRatio, setActiveCropRatio] = useState14(null);
2196
+ const [selectionOptions, setSelectionOptions] = useState14(DEFAULT_SELECTION_TOOL_OPTIONS);
2100
2197
  const selectionOptionsRef = useRef5(selectionOptions);
2101
2198
  selectionOptionsRef.current = selectionOptions;
2102
2199
  const selectionGestureRef = useRef5(null);
@@ -2104,7 +2201,7 @@ var ImageEditor = ({
2104
2201
  selectionGestureRef.current = new SelectionGesture(controller, () => selectionOptionsRef.current);
2105
2202
  }
2106
2203
  const selectionDraftRef = useRef5(null);
2107
- const [selectionError, setSelectionError] = useState13(null);
2204
+ const [selectionError, setSelectionError] = useState14(null);
2108
2205
  const paintGestureRef = useRef5(null);
2109
2206
  const paintControllerRef = useRef5(controller);
2110
2207
  if (!paintGestureRef.current || paintControllerRef.current !== controller) {
@@ -2112,7 +2209,7 @@ var ImageEditor = ({
2112
2209
  paintControllerRef.current = controller;
2113
2210
  }
2114
2211
  const brushCursorRef = useRef5(null);
2115
- const [paintError, setPaintError] = useState13(null);
2212
+ const [paintError, setPaintError] = useState14(null);
2116
2213
  const transformToolRef = useRef5(null);
2117
2214
  const transformControllerRef = useRef5(controller);
2118
2215
  if (!transformToolRef.current || transformControllerRef.current !== controller) {
@@ -2123,12 +2220,12 @@ var ImageEditor = ({
2123
2220
  transformControllerRef.current = controller;
2124
2221
  }
2125
2222
  const transformTool = transformToolRef.current;
2126
- const [, setTransformTick] = useState13(0);
2127
- const [transformCursor, setTransformCursor] = useState13("default");
2128
- const [shapeOptions, setShapeOptions] = useState13(DEFAULT_SHAPE_TOOL_OPTIONS);
2223
+ const [, setTransformTick] = useState14(0);
2224
+ const [transformCursor, setTransformCursor] = useState14("default");
2225
+ const [shapeOptions, setShapeOptions] = useState14(DEFAULT_SHAPE_TOOL_OPTIONS);
2129
2226
  const shapeOptionsRef = useRef5(shapeOptions);
2130
2227
  shapeOptionsRef.current = shapeOptions;
2131
- const [typeOptions, setTypeOptions] = useState13(DEFAULT_TYPE_TOOL_OPTIONS);
2228
+ const [typeOptions, setTypeOptions] = useState14(DEFAULT_TYPE_TOOL_OPTIONS);
2132
2229
  const typeOptionsRef = useRef5(typeOptions);
2133
2230
  typeOptionsRef.current = typeOptions;
2134
2231
  const shapeGestureRef = useRef5(null);
@@ -2141,15 +2238,15 @@ var ImageEditor = ({
2141
2238
  shapeTypeControllerRef.current = controller;
2142
2239
  }
2143
2240
  const typeInputRef = useRef5(null);
2144
- const [typeSession, setTypeSession] = useState13(typeToolRef.current.session);
2145
- const [shapeTypeError, setShapeTypeError] = useState13(null);
2146
- const [inpaintPrompt, setInpaintPrompt] = useState13("");
2147
- const [inpaintMaskMode, setInpaintMaskMode] = useState13("annotations");
2148
- const [isRemovingBg, setIsRemovingBg] = useState13(false);
2149
- const [isInpainting, setIsInpainting] = useState13(false);
2150
- const [aiError, setAiError] = useState13(null);
2151
- const [aiSuccess, setAiSuccess] = useState13(null);
2152
- const [aiTarget, setAiTarget] = useState13("auto");
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");
2153
2250
  const aiOptions = aiTarget === "auto" ? {} : { target: aiTarget };
2154
2251
  const effectiveOnInpaint = onInpaint || aiHooks?.onInpaint;
2155
2252
  const effectiveOnRemoveBg = onRemoveBackground || aiHooks?.onRemoveBackground;
@@ -2212,10 +2309,10 @@ var ImageEditor = ({
2212
2309
  setIsInpainting(false);
2213
2310
  }
2214
2311
  };
2215
- const [activeColor, setActiveColor] = useState13("#ef4444");
2216
- const [strokeWidth, setStrokeWidth] = useState13(3);
2217
- const [fontSize, setFontSize] = useState13(24);
2218
- const [textInput, setTextInput] = useState13("");
2312
+ const [activeColor, setActiveColor] = useState14("#ef4444");
2313
+ const [strokeWidth, setStrokeWidth] = useState14(3);
2314
+ const [fontSize, setFontSize] = useState14(24);
2315
+ const [textInput, setTextInput] = useState14("");
2219
2316
  const draftAnnotationRef = useRef5(null);
2220
2317
  const draftCropRef = useRef5(null);
2221
2318
  const cropDragInfoRef = useRef5(null);
@@ -2246,8 +2343,8 @@ var ImageEditor = ({
2246
2343
  },
2247
2344
  [controller, activeTab, transformTool]
2248
2345
  );
2249
- useEffect10(() => typeSession?.subscribe(() => void renderCanvas()), [typeSession, renderCanvas]);
2250
- useEffect10(() => {
2346
+ useEffect11(() => typeSession?.subscribe(() => void renderCanvas()), [typeSession, renderCanvas]);
2347
+ useEffect11(() => {
2251
2348
  if (activeTab === "annotate" && state.activeTool === "type") return;
2252
2349
  if (typeToolRef.current?.session) {
2253
2350
  typeToolRef.current.finish();
@@ -2282,7 +2379,7 @@ var ImageEditor = ({
2282
2379
  el.value = "";
2283
2380
  }
2284
2381
  };
2285
- useEffect10(() => transformTool.subscribe(() => {
2382
+ useEffect11(() => transformTool.subscribe(() => {
2286
2383
  setTransformTick((n) => n + 1);
2287
2384
  void renderCanvas();
2288
2385
  }), [transformTool, renderCanvas]);
@@ -2325,7 +2422,7 @@ var ImageEditor = ({
2325
2422
  transformTool.up();
2326
2423
  return true;
2327
2424
  };
2328
- useEffect10(() => {
2425
+ useEffect11(() => {
2329
2426
  if (typeof window === "undefined") return;
2330
2427
  const onKey = (e) => {
2331
2428
  if (transformTool.key(e)) e.preventDefault();
@@ -2333,7 +2430,7 @@ var ImageEditor = ({
2333
2430
  window.addEventListener("keydown", onKey);
2334
2431
  return () => window.removeEventListener("keydown", onKey);
2335
2432
  }, [transformTool]);
2336
- useEffect10(() => {
2433
+ useEffect11(() => {
2337
2434
  const raf = typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : (cb) => setTimeout(cb, 0);
2338
2435
  const caf = typeof cancelAnimationFrame !== "undefined" ? cancelAnimationFrame : (id) => clearTimeout(id);
2339
2436
  const animId = raf(() => {
@@ -2341,12 +2438,12 @@ var ImageEditor = ({
2341
2438
  });
2342
2439
  return () => caf(animId);
2343
2440
  }, [renderCanvas, state]);
2344
- useEffect10(() => {
2441
+ useEffect11(() => {
2345
2442
  if (activeTab === "crop" && editor.state.activeTool !== "crop") {
2346
2443
  editor.setTool("crop");
2347
2444
  }
2348
2445
  }, [activeTab, editor]);
2349
- useEffect10(() => {
2446
+ useEffect11(() => {
2350
2447
  const container = containerRef.current;
2351
2448
  if (!container) return;
2352
2449
  if (typeof ResizeObserver !== "undefined") {
@@ -2414,7 +2511,7 @@ var ImageEditor = ({
2414
2511
  if (g.error) setPaintError(g.error);
2415
2512
  }
2416
2513
  };
2417
- useEffect10(() => {
2514
+ useEffect11(() => {
2418
2515
  if (activeTab !== "paint" || typeof window === "undefined") return;
2419
2516
  const onKey = (e) => {
2420
2517
  if (handlePaintShortcut(controller, e)) e.preventDefault();
@@ -2809,15 +2906,15 @@ var ImageEditor = ({
2809
2906
  link.click();
2810
2907
  }
2811
2908
  };
2812
- return /* @__PURE__ */ jsxs13(
2909
+ return /* @__PURE__ */ jsxs14(
2813
2910
  "div",
2814
2911
  {
2815
2912
  className: `flex flex-col bg-slate-900 border border-slate-800 rounded-xl overflow-hidden shadow-2xl text-slate-100 ${className}`,
2816
2913
  style,
2817
2914
  children: [
2818
- /* @__PURE__ */ jsxs13("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: [
2819
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-1 bg-slate-900 p-1 rounded-lg border border-slate-800 text-xs", children: [
2820
- /* @__PURE__ */ jsx13(
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(
2821
2918
  "button",
2822
2919
  {
2823
2920
  type: "button",
@@ -2829,7 +2926,7 @@ var ImageEditor = ({
2829
2926
  children: "Transform & Crop"
2830
2927
  }
2831
2928
  ),
2832
- /* @__PURE__ */ jsx13(
2929
+ /* @__PURE__ */ jsx14(
2833
2930
  "button",
2834
2931
  {
2835
2932
  type: "button",
@@ -2841,7 +2938,7 @@ var ImageEditor = ({
2841
2938
  children: "Adjustments"
2842
2939
  }
2843
2940
  ),
2844
- /* @__PURE__ */ jsx13(
2941
+ /* @__PURE__ */ jsx14(
2845
2942
  "button",
2846
2943
  {
2847
2944
  type: "button",
@@ -2853,7 +2950,7 @@ var ImageEditor = ({
2853
2950
  children: "Layers"
2854
2951
  }
2855
2952
  ),
2856
- /* @__PURE__ */ jsx13(
2953
+ /* @__PURE__ */ jsx14(
2857
2954
  "button",
2858
2955
  {
2859
2956
  type: "button",
@@ -2865,7 +2962,7 @@ var ImageEditor = ({
2865
2962
  children: "Paint"
2866
2963
  }
2867
2964
  ),
2868
- /* @__PURE__ */ jsx13(
2965
+ /* @__PURE__ */ jsx14(
2869
2966
  "button",
2870
2967
  {
2871
2968
  type: "button",
@@ -2877,7 +2974,7 @@ var ImageEditor = ({
2877
2974
  children: "Select & Mask"
2878
2975
  }
2879
2976
  ),
2880
- /* @__PURE__ */ jsx13(
2977
+ /* @__PURE__ */ jsx14(
2881
2978
  "button",
2882
2979
  {
2883
2980
  type: "button",
@@ -2889,7 +2986,7 @@ var ImageEditor = ({
2889
2986
  children: "Annotations"
2890
2987
  }
2891
2988
  ),
2892
- /* @__PURE__ */ jsx13(
2989
+ /* @__PURE__ */ jsx14(
2893
2990
  "button",
2894
2991
  {
2895
2992
  type: "button",
@@ -2901,7 +2998,7 @@ var ImageEditor = ({
2901
2998
  children: "Depth Mask"
2902
2999
  }
2903
3000
  ),
2904
- /* @__PURE__ */ jsxs13(
3001
+ /* @__PURE__ */ jsxs14(
2905
3002
  "button",
2906
3003
  {
2907
3004
  type: "button",
@@ -2911,14 +3008,14 @@ var ImageEditor = ({
2911
3008
  },
2912
3009
  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"}`,
2913
3010
  children: [
2914
- /* @__PURE__ */ jsx13("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx13("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" }) }),
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" }) }),
2915
3012
  "AI Tools"
2916
3013
  ]
2917
3014
  }
2918
3015
  )
2919
3016
  ] }),
2920
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2 text-xs", children: [
2921
- /* @__PURE__ */ jsx13(
3017
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2 text-xs", children: [
3018
+ /* @__PURE__ */ jsx14(
2922
3019
  "button",
2923
3020
  {
2924
3021
  type: "button",
@@ -2929,7 +3026,7 @@ var ImageEditor = ({
2929
3026
  children: "\u21A9"
2930
3027
  }
2931
3028
  ),
2932
- /* @__PURE__ */ jsx13(
3029
+ /* @__PURE__ */ jsx14(
2933
3030
  "button",
2934
3031
  {
2935
3032
  type: "button",
@@ -2940,7 +3037,7 @@ var ImageEditor = ({
2940
3037
  children: "\u21AA"
2941
3038
  }
2942
3039
  ),
2943
- /* @__PURE__ */ jsx13(
3040
+ /* @__PURE__ */ jsx14(
2944
3041
  "button",
2945
3042
  {
2946
3043
  type: "button",
@@ -2949,8 +3046,8 @@ var ImageEditor = ({
2949
3046
  children: "Reset"
2950
3047
  }
2951
3048
  ),
2952
- /* @__PURE__ */ jsx13("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
2953
- /* @__PURE__ */ jsx13(
3049
+ /* @__PURE__ */ jsx14("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
3050
+ /* @__PURE__ */ jsx14(
2954
3051
  "button",
2955
3052
  {
2956
3053
  type: "button",
@@ -2960,11 +3057,11 @@ var ImageEditor = ({
2960
3057
  children: "-"
2961
3058
  }
2962
3059
  ),
2963
- /* @__PURE__ */ jsxs13("span", { className: "font-mono text-slate-400 w-10 text-center", children: [
3060
+ /* @__PURE__ */ jsxs14("span", { className: "font-mono text-slate-400 w-10 text-center", children: [
2964
3061
  Math.round(state.zoom * 100),
2965
3062
  "%"
2966
3063
  ] }),
2967
- /* @__PURE__ */ jsx13(
3064
+ /* @__PURE__ */ jsx14(
2968
3065
  "button",
2969
3066
  {
2970
3067
  type: "button",
@@ -2974,8 +3071,8 @@ var ImageEditor = ({
2974
3071
  children: "+"
2975
3072
  }
2976
3073
  ),
2977
- /* @__PURE__ */ jsx13("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
2978
- /* @__PURE__ */ jsx13(
3074
+ /* @__PURE__ */ jsx14("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
3075
+ /* @__PURE__ */ jsx14(
2979
3076
  "button",
2980
3077
  {
2981
3078
  type: "button",
@@ -2986,7 +3083,7 @@ var ImageEditor = ({
2986
3083
  children: "Hold Compare"
2987
3084
  }
2988
3085
  ),
2989
- /* @__PURE__ */ jsx13(
3086
+ /* @__PURE__ */ jsx14(
2990
3087
  "button",
2991
3088
  {
2992
3089
  type: "button",
@@ -2997,16 +3094,16 @@ var ImageEditor = ({
2997
3094
  )
2998
3095
  ] })
2999
3096
  ] }),
3000
- transformTool.active && /* @__PURE__ */ jsx13(FreeTransformOptionsBar, { tool: transformTool, className: "border-b border-slate-800 bg-slate-900/95 px-4 py-2" }),
3001
- !transformTool.active && transformTool.error && /* @__PURE__ */ jsx13("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 }),
3002
- /* @__PURE__ */ jsxs13("div", { className: "flex flex-col md:flex-row flex-1 min-h-[520px] md:h-[560px]", children: [
3003
- /* @__PURE__ */ jsxs13(
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(
3004
3101
  "div",
3005
3102
  {
3006
3103
  ref: containerRef,
3007
3104
  className: "relative flex-1 h-[360px] md:h-full min-h-[320px] bg-slate-950 overflow-hidden select-none",
3008
3105
  children: [
3009
- /* @__PURE__ */ jsx13(
3106
+ /* @__PURE__ */ jsx14(
3010
3107
  "canvas",
3011
3108
  {
3012
3109
  ref: canvasRef,
@@ -3023,7 +3120,7 @@ var ImageEditor = ({
3023
3120
  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" : ""}`
3024
3121
  }
3025
3122
  ),
3026
- typeSession && /* @__PURE__ */ jsx13(
3123
+ typeSession && /* @__PURE__ */ jsx14(
3027
3124
  "textarea",
3028
3125
  {
3029
3126
  ref: typeInputRef,
@@ -3045,11 +3142,11 @@ var ImageEditor = ({
3045
3142
  ]
3046
3143
  }
3047
3144
  ),
3048
- /* @__PURE__ */ jsxs13("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: [
3049
- activeTab === "crop" && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-4 text-xs", children: [
3050
- /* @__PURE__ */ jsx13("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Aspect Ratio Presets" }),
3051
- /* @__PURE__ */ jsxs13("div", { className: "grid grid-cols-3 gap-2", children: [
3052
- /* @__PURE__ */ jsx13(
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(
3053
3150
  "button",
3054
3151
  {
3055
3152
  type: "button",
@@ -3061,7 +3158,7 @@ var ImageEditor = ({
3061
3158
  children: "Freeform"
3062
3159
  }
3063
3160
  ),
3064
- /* @__PURE__ */ jsx13(
3161
+ /* @__PURE__ */ jsx14(
3065
3162
  "button",
3066
3163
  {
3067
3164
  type: "button",
@@ -3073,7 +3170,7 @@ var ImageEditor = ({
3073
3170
  children: "1:1 Square"
3074
3171
  }
3075
3172
  ),
3076
- /* @__PURE__ */ jsx13(
3173
+ /* @__PURE__ */ jsx14(
3077
3174
  "button",
3078
3175
  {
3079
3176
  type: "button",
@@ -3085,7 +3182,7 @@ var ImageEditor = ({
3085
3182
  children: "4:3 Standard"
3086
3183
  }
3087
3184
  ),
3088
- /* @__PURE__ */ jsx13(
3185
+ /* @__PURE__ */ jsx14(
3089
3186
  "button",
3090
3187
  {
3091
3188
  type: "button",
@@ -3097,7 +3194,7 @@ var ImageEditor = ({
3097
3194
  children: "16:9 Wide"
3098
3195
  }
3099
3196
  ),
3100
- /* @__PURE__ */ jsx13(
3197
+ /* @__PURE__ */ jsx14(
3101
3198
  "button",
3102
3199
  {
3103
3200
  type: "button",
@@ -3109,7 +3206,7 @@ var ImageEditor = ({
3109
3206
  children: "3:2 Photo"
3110
3207
  }
3111
3208
  ),
3112
- /* @__PURE__ */ jsx13(
3209
+ /* @__PURE__ */ jsx14(
3113
3210
  "button",
3114
3211
  {
3115
3212
  type: "button",
@@ -3122,10 +3219,10 @@ var ImageEditor = ({
3122
3219
  }
3123
3220
  )
3124
3221
  ] }),
3125
- /* @__PURE__ */ jsx13("div", { className: "h-px bg-slate-800 my-1" }),
3126
- /* @__PURE__ */ jsx13("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Orientation & Flips" }),
3127
- /* @__PURE__ */ jsxs13("div", { className: "grid grid-cols-2 gap-2", children: [
3128
- /* @__PURE__ */ jsx13(
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(
3129
3226
  "button",
3130
3227
  {
3131
3228
  type: "button",
@@ -3134,7 +3231,7 @@ var ImageEditor = ({
3134
3231
  children: "Rotate -90\xB0"
3135
3232
  }
3136
3233
  ),
3137
- /* @__PURE__ */ jsx13(
3234
+ /* @__PURE__ */ jsx14(
3138
3235
  "button",
3139
3236
  {
3140
3237
  type: "button",
@@ -3143,7 +3240,7 @@ var ImageEditor = ({
3143
3240
  children: "Rotate +90\xB0"
3144
3241
  }
3145
3242
  ),
3146
- /* @__PURE__ */ jsx13(
3243
+ /* @__PURE__ */ jsx14(
3147
3244
  "button",
3148
3245
  {
3149
3246
  type: "button",
@@ -3152,7 +3249,7 @@ var ImageEditor = ({
3152
3249
  children: "Flip Horizontal"
3153
3250
  }
3154
3251
  ),
3155
- /* @__PURE__ */ jsx13(
3252
+ /* @__PURE__ */ jsx14(
3156
3253
  "button",
3157
3254
  {
3158
3255
  type: "button",
@@ -3163,10 +3260,10 @@ var ImageEditor = ({
3163
3260
  )
3164
3261
  ] })
3165
3262
  ] }),
3166
- activeTab === "adjust" && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-3 text-xs", children: [
3167
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between", children: [
3168
- /* @__PURE__ */ jsx13("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Color Adjustments" }),
3169
- /* @__PURE__ */ jsx13(
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(
3170
3267
  "button",
3171
3268
  {
3172
3269
  type: "button",
@@ -3176,9 +3273,9 @@ var ImageEditor = ({
3176
3273
  }
3177
3274
  )
3178
3275
  ] }),
3179
- /* @__PURE__ */ jsx13(Histogram, { histogram: editor.histogram }),
3180
- IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */ jsxs13(React12.Fragment, { children: [
3181
- /* @__PURE__ */ jsx13(
3276
+ /* @__PURE__ */ jsx14(Histogram, { histogram: editor.histogram }),
3277
+ IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */ jsxs14(React13.Fragment, { children: [
3278
+ /* @__PURE__ */ jsx14(
3182
3279
  ControlSlider,
3183
3280
  {
3184
3281
  spec,
@@ -3187,14 +3284,14 @@ var ImageEditor = ({
3187
3284
  onChange: (v) => editor.setAdjustments({ [spec.id]: v })
3188
3285
  }
3189
3286
  ),
3190
- spec.id === "tint" && legacyProcess && /* @__PURE__ */ jsxs13(
3287
+ spec.id === "tint" && legacyProcess && /* @__PURE__ */ jsxs14(
3191
3288
  "div",
3192
3289
  {
3193
3290
  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",
3194
3291
  "data-testid": "image-editor-process-notice",
3195
3292
  children: [
3196
- /* @__PURE__ */ jsx13("span", { children: "Legacy rendering (process 1). Tint needs the current process." }),
3197
- /* @__PURE__ */ jsx13(
3293
+ /* @__PURE__ */ jsx14("span", { children: "Legacy rendering (process 1). Tint needs the current process." }),
3294
+ /* @__PURE__ */ jsx14(
3198
3295
  "button",
3199
3296
  {
3200
3297
  type: "button",
@@ -3207,7 +3304,7 @@ var ImageEditor = ({
3207
3304
  }
3208
3305
  )
3209
3306
  ] }, spec.id)),
3210
- /* @__PURE__ */ jsx13("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ jsx13(
3307
+ /* @__PURE__ */ jsx14("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ jsx14(
3211
3308
  AdjustmentLayersPanel,
3212
3309
  {
3213
3310
  controller,
@@ -3216,9 +3313,9 @@ var ImageEditor = ({
3216
3313
  }
3217
3314
  ) })
3218
3315
  ] }),
3219
- activeTab === "layers" && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-3 text-xs", children: [
3220
- /* @__PURE__ */ jsx13("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Layers" }),
3221
- /* @__PURE__ */ jsx13(
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(
3222
3319
  "button",
3223
3320
  {
3224
3321
  type: "button",
@@ -3229,12 +3326,14 @@ var ImageEditor = ({
3229
3326
  children: "Free Transform"
3230
3327
  }
3231
3328
  ),
3232
- /* @__PURE__ */ jsx13(LayersPanel, { controller })
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 })
3233
3332
  ] }),
3234
- activeTab === "paint" && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-3 text-xs", children: [
3235
- /* @__PURE__ */ jsx13("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Paint" }),
3236
- /* @__PURE__ */ jsx13(BrushOptionsBar, { controller }),
3237
- /* @__PURE__ */ jsx13(
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(
3238
3337
  "button",
3239
3338
  {
3240
3339
  type: "button",
@@ -3245,12 +3344,12 @@ var ImageEditor = ({
3245
3344
  children: "Free Transform"
3246
3345
  }
3247
3346
  ),
3248
- paintError && /* @__PURE__ */ jsx13("p", { role: "alert", className: "text-rose-400", "data-testid": "paint-error", children: paintError }),
3249
- /* @__PURE__ */ jsx13("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ jsx13(LayersPanel, { controller }) })
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 }) })
3250
3349
  ] }),
3251
- activeTab === "annotate" && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-3 text-xs", children: [
3252
- /* @__PURE__ */ jsx13("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Shape & Type Layers" }),
3253
- /* @__PURE__ */ jsx13("div", { className: "grid grid-cols-2 gap-1.5", children: ["shape", "type"].map((t) => /* @__PURE__ */ jsx13(
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(
3254
3353
  "button",
3255
3354
  {
3256
3355
  type: "button",
@@ -3261,13 +3360,13 @@ var ImageEditor = ({
3261
3360
  },
3262
3361
  t
3263
3362
  )) }),
3264
- state.activeTool === "shape" && /* @__PURE__ */ jsx13(ShapeOptionsBar, { controller, options: shapeOptions, onChange: setShapeOptions }),
3265
- state.activeTool === "type" && /* @__PURE__ */ jsx13(TypeOptionsBar, { controller, options: typeOptions, onChange: setTypeOptions, session: typeSession }),
3266
- state.activeTool === "type" && typeSession && /* @__PURE__ */ jsx13("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" }),
3267
- shapeTypeError && /* @__PURE__ */ jsx13("p", { role: "alert", className: "text-rose-400", "data-testid": "shape-type-error", children: shapeTypeError }),
3268
- /* @__PURE__ */ jsx13("div", { className: "h-px bg-slate-800 my-1" }),
3269
- /* @__PURE__ */ jsx13("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Draw & Annotate" }),
3270
- /* @__PURE__ */ jsx13("div", { className: "grid grid-cols-3 gap-1.5", children: ["pen", "rect", "circle", "arrow", "line"].map((t) => /* @__PURE__ */ jsx13(
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(
3271
3370
  "button",
3272
3371
  {
3273
3372
  type: "button",
@@ -3277,9 +3376,9 @@ var ImageEditor = ({
3277
3376
  },
3278
3377
  t
3279
3378
  )) }),
3280
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2 mt-2", children: [
3281
- /* @__PURE__ */ jsx13("label", { className: "text-slate-400", children: "Color:" }),
3282
- /* @__PURE__ */ jsx13(
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(
3283
3382
  "input",
3284
3383
  {
3285
3384
  type: "color",
@@ -3288,15 +3387,15 @@ var ImageEditor = ({
3288
3387
  className: "w-8 h-8 rounded border border-slate-700 cursor-pointer bg-transparent"
3289
3388
  }
3290
3389
  ),
3291
- /* @__PURE__ */ jsxs13("div", { className: "flex-1 ml-2", children: [
3292
- /* @__PURE__ */ jsxs13("div", { className: "flex justify-between text-slate-400 mb-0.5", children: [
3293
- /* @__PURE__ */ jsx13("span", { children: "Width:" }),
3294
- /* @__PURE__ */ jsxs13("span", { className: "font-mono", children: [
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: [
3295
3394
  strokeWidth,
3296
3395
  "px"
3297
3396
  ] })
3298
3397
  ] }),
3299
- /* @__PURE__ */ jsx13(
3398
+ /* @__PURE__ */ jsx14(
3300
3399
  "input",
3301
3400
  {
3302
3401
  type: "range",
@@ -3309,10 +3408,10 @@ var ImageEditor = ({
3309
3408
  )
3310
3409
  ] })
3311
3410
  ] }),
3312
- /* @__PURE__ */ jsx13("div", { className: "h-px bg-slate-800 my-1" }),
3313
- /* @__PURE__ */ jsx13("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Add Text" }),
3314
- /* @__PURE__ */ jsxs13("div", { className: "flex gap-2", children: [
3315
- /* @__PURE__ */ jsx13(
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(
3316
3415
  "input",
3317
3416
  {
3318
3417
  type: "text",
@@ -3323,7 +3422,7 @@ var ImageEditor = ({
3323
3422
  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"
3324
3423
  }
3325
3424
  ),
3326
- /* @__PURE__ */ jsx13(
3425
+ /* @__PURE__ */ jsx14(
3327
3426
  "button",
3328
3427
  {
3329
3428
  type: "button",
@@ -3333,14 +3432,14 @@ var ImageEditor = ({
3333
3432
  }
3334
3433
  )
3335
3434
  ] }),
3336
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between text-slate-400", children: [
3337
- /* @__PURE__ */ jsx13("span", { children: "Font Size:" }),
3338
- /* @__PURE__ */ jsxs13("span", { className: "font-mono", children: [
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: [
3339
3438
  fontSize,
3340
3439
  "px"
3341
3440
  ] })
3342
3441
  ] }),
3343
- /* @__PURE__ */ jsx13(
3442
+ /* @__PURE__ */ jsx14(
3344
3443
  "input",
3345
3444
  {
3346
3445
  type: "range",
@@ -3351,14 +3450,14 @@ var ImageEditor = ({
3351
3450
  className: "w-full accent-indigo-500"
3352
3451
  }
3353
3452
  ),
3354
- /* @__PURE__ */ jsx13("div", { className: "h-px bg-slate-800 my-1" }),
3355
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between", children: [
3356
- /* @__PURE__ */ jsxs13("span", { className: "text-slate-400", children: [
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: [
3357
3456
  "Layers (",
3358
3457
  state.annotations.length,
3359
3458
  ")"
3360
3459
  ] }),
3361
- state.selectedAnnotationId && /* @__PURE__ */ jsx13(
3460
+ state.selectedAnnotationId && /* @__PURE__ */ jsx14(
3362
3461
  "button",
3363
3462
  {
3364
3463
  type: "button",
@@ -3367,7 +3466,7 @@ var ImageEditor = ({
3367
3466
  children: "Delete Selected"
3368
3467
  }
3369
3468
  ),
3370
- state.annotations.length > 0 && /* @__PURE__ */ jsx13(
3469
+ state.annotations.length > 0 && /* @__PURE__ */ jsx14(
3371
3470
  "button",
3372
3471
  {
3373
3472
  type: "button",
@@ -3378,10 +3477,10 @@ var ImageEditor = ({
3378
3477
  )
3379
3478
  ] })
3380
3479
  ] }),
3381
- activeTab === "depth" && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-3 text-xs", children: [
3382
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between", children: [
3383
- /* @__PURE__ */ jsx13("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Depth Masking" }),
3384
- /* @__PURE__ */ jsx13(
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(
3385
3484
  "button",
3386
3485
  {
3387
3486
  type: "button",
@@ -3391,8 +3490,8 @@ var ImageEditor = ({
3391
3490
  }
3392
3491
  )
3393
3492
  ] }),
3394
- /* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300", children: [
3395
- /* @__PURE__ */ jsx13(
3493
+ /* @__PURE__ */ jsxs14("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300", children: [
3494
+ /* @__PURE__ */ jsx14(
3396
3495
  "input",
3397
3496
  {
3398
3497
  type: "checkbox",
@@ -3401,12 +3500,12 @@ var ImageEditor = ({
3401
3500
  className: "rounded accent-indigo-500"
3402
3501
  }
3403
3502
  ),
3404
- /* @__PURE__ */ jsx13("span", { children: "Enable Depth / Alpha Mask" })
3503
+ /* @__PURE__ */ jsx14("span", { children: "Enable Depth / Alpha Mask" })
3405
3504
  ] }),
3406
- state.depthMask.enabled && /* @__PURE__ */ jsxs13(Fragment4, { children: [
3407
- /* @__PURE__ */ jsxs13("div", { children: [
3408
- /* @__PURE__ */ jsx13("label", { className: "text-slate-400 block mb-1", children: "Mask Image URL:" }),
3409
- /* @__PURE__ */ jsx13(
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(
3410
3509
  "input",
3411
3510
  {
3412
3511
  type: "text",
@@ -3417,8 +3516,8 @@ var ImageEditor = ({
3417
3516
  }
3418
3517
  )
3419
3518
  ] }),
3420
- /* @__PURE__ */ jsxs13("div", { className: "flex gap-2", children: [
3421
- /* @__PURE__ */ jsx13(
3519
+ /* @__PURE__ */ jsxs14("div", { className: "flex gap-2", children: [
3520
+ /* @__PURE__ */ jsx14(
3422
3521
  "button",
3423
3522
  {
3424
3523
  type: "button",
@@ -3427,7 +3526,7 @@ var ImageEditor = ({
3427
3526
  children: "Threshold Mode"
3428
3527
  }
3429
3528
  ),
3430
- /* @__PURE__ */ jsx13(
3529
+ /* @__PURE__ */ jsx14(
3431
3530
  "button",
3432
3531
  {
3433
3532
  type: "button",
@@ -3437,12 +3536,12 @@ var ImageEditor = ({
3437
3536
  }
3438
3537
  )
3439
3538
  ] }),
3440
- /* @__PURE__ */ jsxs13("div", { children: [
3441
- /* @__PURE__ */ jsxs13("div", { className: "flex justify-between text-slate-400 mb-1", children: [
3442
- /* @__PURE__ */ jsx13("span", { children: "Depth Start (Lower):" }),
3443
- /* @__PURE__ */ jsx13("span", { className: "font-mono", children: state.depthMask.depthRange[0] })
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] })
3444
3543
  ] }),
3445
- /* @__PURE__ */ jsx13(
3544
+ /* @__PURE__ */ jsx14(
3446
3545
  "input",
3447
3546
  {
3448
3547
  type: "range",
@@ -3456,12 +3555,12 @@ var ImageEditor = ({
3456
3555
  }
3457
3556
  )
3458
3557
  ] }),
3459
- /* @__PURE__ */ jsxs13("div", { children: [
3460
- /* @__PURE__ */ jsxs13("div", { className: "flex justify-between text-slate-400 mb-1", children: [
3461
- /* @__PURE__ */ jsx13("span", { children: "Depth Stop (Upper):" }),
3462
- /* @__PURE__ */ jsx13("span", { className: "font-mono", children: state.depthMask.depthRange[1] })
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] })
3463
3562
  ] }),
3464
- /* @__PURE__ */ jsx13(
3563
+ /* @__PURE__ */ jsx14(
3465
3564
  "input",
3466
3565
  {
3467
3566
  type: "range",
@@ -3475,12 +3574,12 @@ var ImageEditor = ({
3475
3574
  }
3476
3575
  )
3477
3576
  ] }),
3478
- /* @__PURE__ */ jsxs13("div", { children: [
3479
- /* @__PURE__ */ jsxs13("div", { className: "flex justify-between text-slate-400 mb-1", children: [
3480
- /* @__PURE__ */ jsx13("span", { children: "Softness:" }),
3481
- /* @__PURE__ */ jsx13("span", { className: "font-mono", children: state.depthMask.softness })
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 })
3482
3581
  ] }),
3483
- /* @__PURE__ */ jsx13(
3582
+ /* @__PURE__ */ jsx14(
3484
3583
  "input",
3485
3584
  {
3486
3585
  type: "range",
@@ -3492,8 +3591,8 @@ var ImageEditor = ({
3492
3591
  }
3493
3592
  )
3494
3593
  ] }),
3495
- /* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300 mt-1", children: [
3496
- /* @__PURE__ */ jsx13(
3594
+ /* @__PURE__ */ jsxs14("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300 mt-1", children: [
3595
+ /* @__PURE__ */ jsx14(
3497
3596
  "input",
3498
3597
  {
3499
3598
  type: "checkbox",
@@ -3502,12 +3601,12 @@ var ImageEditor = ({
3502
3601
  className: "rounded accent-indigo-500"
3503
3602
  }
3504
3603
  ),
3505
- /* @__PURE__ */ jsx13("span", { children: "Invert Mask" })
3604
+ /* @__PURE__ */ jsx14("span", { children: "Invert Mask" })
3506
3605
  ] })
3507
3606
  ] })
3508
3607
  ] }),
3509
- activeTab === "select" && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-4 text-xs", children: [
3510
- /* @__PURE__ */ jsx13(
3608
+ activeTab === "select" && /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-4 text-xs", children: [
3609
+ /* @__PURE__ */ jsx14(
3511
3610
  SelectionOptionsBar,
3512
3611
  {
3513
3612
  controller,
@@ -3517,9 +3616,9 @@ var ImageEditor = ({
3517
3616
  quickMask: Boolean(state.quickMask)
3518
3617
  }
3519
3618
  ),
3520
- selectionError && /* @__PURE__ */ jsx13("p", { role: "alert", className: "text-rose-400", children: selectionError }),
3521
- /* @__PURE__ */ jsxs13("div", { className: "flex gap-1", children: [
3522
- /* @__PURE__ */ jsx13(
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(
3523
3622
  "button",
3524
3623
  {
3525
3624
  type: "button",
@@ -3530,7 +3629,7 @@ var ImageEditor = ({
3530
3629
  children: "Transform Selection"
3531
3630
  }
3532
3631
  ),
3533
- /* @__PURE__ */ jsx13(
3632
+ /* @__PURE__ */ jsx14(
3534
3633
  "button",
3535
3634
  {
3536
3635
  type: "button",
@@ -3542,12 +3641,12 @@ var ImageEditor = ({
3542
3641
  }
3543
3642
  )
3544
3643
  ] }),
3545
- /* @__PURE__ */ jsx13(RefineEdgePanel, { controller, selection: state.selection ?? null, layers: state.adjustments.layers })
3644
+ /* @__PURE__ */ jsx14(RefineEdgePanel, { controller, selection: state.selection ?? null, layers: state.adjustments.layers })
3546
3645
  ] }),
3547
- activeTab === "ai" && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-4 text-xs", children: [
3548
- /* @__PURE__ */ jsxs13("label", { className: "flex items-center justify-between gap-2 text-slate-300", children: [
3549
- /* @__PURE__ */ jsx13("span", { children: "Results go to" }),
3550
- /* @__PURE__ */ jsxs13(
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(
3551
3650
  "select",
3552
3651
  {
3553
3652
  "aria-label": "AI result target",
@@ -3555,54 +3654,54 @@ var ImageEditor = ({
3555
3654
  onChange: (e) => setAiTarget(e.target.value),
3556
3655
  className: "bg-slate-800 border border-slate-700 rounded px-1.5 py-1",
3557
3656
  children: [
3558
- /* @__PURE__ */ jsx13("option", { value: "auto", children: controller.isMultiLayer ? "Auto (new layer)" : "Auto (replace image)" }),
3559
- /* @__PURE__ */ jsx13("option", { value: "new-layer", children: "New layer / mask" }),
3560
- /* @__PURE__ */ jsx13("option", { value: "replace", children: "Replace image" })
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" })
3561
3660
  ]
3562
3661
  }
3563
3662
  )
3564
3663
  ] }),
3565
- /* @__PURE__ */ jsxs13("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
3566
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between", children: [
3567
- /* @__PURE__ */ jsxs13("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
3568
- /* @__PURE__ */ jsx13("svg", { className: "w-3.5 h-3.5 text-indigo-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx13("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" }) }),
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" }) }),
3569
3668
  "Background Removal"
3570
3669
  ] }),
3571
- isRemovingBg && /* @__PURE__ */ jsx13("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..." })
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..." })
3572
3671
  ] }),
3573
- /* @__PURE__ */ jsx13("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Isolate foreground subject with AI alpha transparency segmentation." }),
3574
- /* @__PURE__ */ jsx13(
3672
+ /* @__PURE__ */ jsx14("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Isolate foreground subject with AI alpha transparency segmentation." }),
3673
+ /* @__PURE__ */ jsx14(
3575
3674
  "button",
3576
3675
  {
3577
3676
  type: "button",
3578
3677
  onClick: handleRemoveBackground,
3579
3678
  disabled: isRemovingBg || isInpainting,
3580
3679
  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",
3581
- children: isRemovingBg ? /* @__PURE__ */ jsxs13(Fragment4, { children: [
3582
- /* @__PURE__ */ jsx13("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
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" }),
3583
3682
  "Removing Background..."
3584
- ] }) : /* @__PURE__ */ jsxs13(Fragment4, { children: [
3585
- /* @__PURE__ */ jsx13("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx13("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" }) }),
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" }) }),
3586
3685
  "Remove Background"
3587
3686
  ] })
3588
3687
  }
3589
3688
  )
3590
3689
  ] }),
3591
- /* @__PURE__ */ jsxs13("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
3592
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between", children: [
3593
- /* @__PURE__ */ jsxs13("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
3594
- /* @__PURE__ */ jsxs13("svg", { className: "w-3.5 h-3.5 text-purple-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
3595
- /* @__PURE__ */ jsx13("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" }),
3596
- /* @__PURE__ */ jsx13("path", { d: "m14 7 3 3" })
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" })
3597
3696
  ] }),
3598
3697
  "Generative Inpainting"
3599
3698
  ] }),
3600
- isInpainting && /* @__PURE__ */ jsx13("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..." })
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..." })
3601
3700
  ] }),
3602
- /* @__PURE__ */ jsx13("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Replace, modify, or fill selected regions using prompt-guided generative inpainting." }),
3603
- /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-1", children: [
3604
- /* @__PURE__ */ jsx13("label", { htmlFor: "ai-inpaint-prompt-react", className: "text-slate-300 text-[11px] font-medium", children: "Prompt" }),
3605
- /* @__PURE__ */ jsx13(
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(
3606
3705
  "textarea",
3607
3706
  {
3608
3707
  id: "ai-inpaint-prompt-react",
@@ -3614,10 +3713,10 @@ var ImageEditor = ({
3614
3713
  }
3615
3714
  )
3616
3715
  ] }),
3617
- /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-1", children: [
3618
- /* @__PURE__ */ jsx13("span", { className: "text-slate-300 text-[11px] font-medium", children: "Target Mask Region" }),
3619
- /* @__PURE__ */ jsxs13("div", { className: "grid grid-cols-2 gap-1.5", children: [
3620
- /* @__PURE__ */ jsxs13(
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(
3621
3720
  "button",
3622
3721
  {
3623
3722
  type: "button",
@@ -3630,7 +3729,7 @@ var ImageEditor = ({
3630
3729
  ]
3631
3730
  }
3632
3731
  ),
3633
- /* @__PURE__ */ jsxs13(
3732
+ /* @__PURE__ */ jsxs14(
3634
3733
  "button",
3635
3734
  {
3636
3735
  type: "button",
@@ -3645,25 +3744,25 @@ var ImageEditor = ({
3645
3744
  )
3646
3745
  ] })
3647
3746
  ] }),
3648
- /* @__PURE__ */ jsx13(
3747
+ /* @__PURE__ */ jsx14(
3649
3748
  "button",
3650
3749
  {
3651
3750
  type: "button",
3652
3751
  onClick: handleInpaint,
3653
3752
  disabled: isInpainting || isRemovingBg || !inpaintPrompt.trim(),
3654
3753
  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",
3655
- children: isInpainting ? /* @__PURE__ */ jsxs13(Fragment4, { children: [
3656
- /* @__PURE__ */ jsx13("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
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" }),
3657
3756
  "Generating Inpaint..."
3658
- ] }) : /* @__PURE__ */ jsxs13(Fragment4, { children: [
3659
- /* @__PURE__ */ jsx13("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx13("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" }) }),
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" }) }),
3660
3759
  "Apply Inpainting"
3661
3760
  ] })
3662
3761
  }
3663
3762
  )
3664
3763
  ] }),
3665
- aiError && /* @__PURE__ */ jsx13("div", { className: "p-2.5 rounded-lg bg-rose-950/60 border border-rose-800 text-rose-300 text-[11px]", children: aiError }),
3666
- aiSuccess && /* @__PURE__ */ jsx13("div", { className: "p-2.5 rounded-lg bg-emerald-950/60 border border-emerald-800 text-emerald-300 text-[11px]", children: aiSuccess })
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 })
3667
3766
  ] })
3668
3767
  ] })
3669
3768
  ] })
@@ -3682,6 +3781,7 @@ export {
3682
3781
  LayerEffectsPanel,
3683
3782
  LayersPanel,
3684
3783
  BrushOptionsBar,
3784
+ ColorProfilePanel,
3685
3785
  SelectionOptionsBar,
3686
3786
  RefineEdgePanel,
3687
3787
  FreeTransformOptionsBar,
@@ -3689,4 +3789,4 @@ export {
3689
3789
  TypeOptionsBar,
3690
3790
  ImageEditor
3691
3791
  };
3692
- //# sourceMappingURL=chunk-YAFNCBDA.js.map
3792
+ //# sourceMappingURL=chunk-LWMUV5TC.js.map