@pixerate/editor-react 0.72.0 → 0.73.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.
@@ -32,6 +32,7 @@ var image_editor_exports = {};
32
32
  __export(image_editor_exports, {
33
33
  AdjustmentLayersPanel: () => AdjustmentLayersPanel,
34
34
  BrushOptionsBar: () => BrushOptionsBar,
35
+ ColorProfilePanel: () => ColorProfilePanel,
35
36
  ControlSlider: () => ControlSlider,
36
37
  CurvesEditor: () => CurvesEditor,
37
38
  FreeTransformOptionsBar: () => FreeTransformOptionsBar,
@@ -207,8 +208,8 @@ function useImageEditor(options = {}) {
207
208
  }
208
209
 
209
210
  // src/image-editor/ImageEditor.tsx
210
- var import_react13 = __toESM(require("react"), 1);
211
- var import_image_editor14 = require("@pixerate/editor/image-editor");
211
+ var import_react14 = __toESM(require("react"), 1);
212
+ var import_image_editor15 = require("@pixerate/editor/image-editor");
212
213
 
213
214
  // src/image-editor/ControlSlider.tsx
214
215
  var import_image_editor2 = require("@pixerate/editor/image-editor");
@@ -943,6 +944,17 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
943
944
  children: "\u22EF"
944
945
  }
945
946
  ),
947
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
948
+ "select",
949
+ {
950
+ "aria-label": "Bits per channel",
951
+ title: "Image \u203A Mode: bits per channel",
952
+ className: "rounded bg-slate-800 px-1 py-0.5 text-[11px] text-slate-200",
953
+ value: controller.bitDepth,
954
+ onChange: (e) => attempt(() => controller.setBitDepth(Number(e.target.value))),
955
+ children: import_image_editor7.BIT_DEPTH_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: o.depth, title: o.title, children: o.label }, o.depth))
956
+ }
957
+ ),
946
958
  psd && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
947
959
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: iconButton, onClick: () => fileInput.current?.click(), children: "Open PSD\u2026" }),
948
960
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: iconButton, onClick: () => psdTask(async () => (await (0, import_image_editor7.downloadPsd)(controller, psdFileName)).warnings), children: "Export PSD" }),
@@ -1445,10 +1457,90 @@ var BrushOptionsBar = ({ controller, className }) => {
1445
1457
  ] });
1446
1458
  };
1447
1459
 
1448
- // src/image-editor/SelectionOptionsBar.tsx
1460
+ // src/image-editor/ColorProfilePanel.tsx
1449
1461
  var import_react8 = require("react");
1450
1462
  var import_image_editor9 = require("@pixerate/editor/image-editor");
1451
1463
  var import_jsx_runtime8 = require("react/jsx-runtime");
1464
+ var chip2 = "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white";
1465
+ var select = "rounded bg-slate-800 px-1 py-0.5 text-[11px] text-slate-200";
1466
+ var ColorProfilePanel = ({ controller, className }) => {
1467
+ const [, setTick] = (0, import_react8.useState)(0);
1468
+ (0, import_react8.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
1469
+ const [target, setTarget] = (0, import_react8.useState)("display-p3");
1470
+ const [intent, setIntent] = (0, import_react8.useState)("relative");
1471
+ const [bpc, setBpc] = (0, import_react8.useState)(true);
1472
+ const [error, setError] = (0, import_react8.useState)(null);
1473
+ const view = (0, import_image_editor9.colorPanelView)(controller);
1474
+ const attempt = (fn) => {
1475
+ try {
1476
+ setError(null);
1477
+ fn();
1478
+ } catch (err) {
1479
+ setError(err instanceof Error ? err.message : String(err));
1480
+ }
1481
+ };
1482
+ const proofWith = (patch) => {
1483
+ const cur = view.proof;
1484
+ const id = patch.id ?? cur?.id ?? "coated-cmyk";
1485
+ attempt(
1486
+ () => controller.setProofSetup({
1487
+ profile: id,
1488
+ intent: patch.intent ?? cur?.intent ?? "relative",
1489
+ simulatePaper: patch.simulatePaper ?? cur?.simulatePaper ?? false,
1490
+ gamutWarning: patch.gamutWarning ?? cur?.gamutWarning ?? false
1491
+ })
1492
+ );
1493
+ };
1494
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "color-profile-panel", children: [
1495
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center gap-2", children: [
1496
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-slate-400", children: "Profile" }),
1497
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { "data-testid": "color-profile-name", children: view.profileName })
1498
+ ] }),
1499
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Assign or convert", children: [
1500
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("select", { "aria-label": "Target profile", className: select, value: target, onChange: (e) => setTarget(e.target.value), children: import_image_editor9.WORKING_SPACE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: o.id, children: o.label }, o.id)) }),
1501
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("select", { "aria-label": "Rendering intent", className: select, value: intent, onChange: (e) => setIntent(e.target.value), children: import_image_editor9.INTENT_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: o.id, title: o.title, children: o.label }, o.id)) }),
1502
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "flex items-center gap-1", children: [
1503
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("input", { type: "checkbox", "aria-label": "Black point compensation", checked: bpc, onChange: (e) => setBpc(e.target.checked), className: "accent-indigo-500" }),
1504
+ "BPC"
1505
+ ] }),
1506
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: chip2, title: "Edit \u203A Assign Profile: keep the numbers", onClick: () => attempt(() => controller.assignProfile(target)), children: "Assign" }),
1507
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: chip2, title: "Edit \u203A Convert to Profile: keep the look", onClick: () => attempt(() => controller.convertToProfile(target, { intent, bpc })), children: "Convert" })
1508
+ ] }),
1509
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Proof setup", children: [
1510
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-slate-400", children: "Proof" }),
1511
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1512
+ "select",
1513
+ {
1514
+ "aria-label": "Proof profile",
1515
+ className: select,
1516
+ value: view.proof?.id ?? "",
1517
+ onChange: (e) => e.target.value ? proofWith({ id: e.target.value }) : attempt(() => controller.setProofSetup(null)),
1518
+ children: [
1519
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "", children: "Off" }),
1520
+ import_image_editor9.PROOF_PROFILE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: o.id, children: o.label }, o.id))
1521
+ ]
1522
+ }
1523
+ ),
1524
+ view.proof && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
1525
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("select", { "aria-label": "Proof intent", className: select, value: view.proof.intent, onChange: (e) => proofWith({ intent: e.target.value }), children: import_image_editor9.INTENT_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: o.id, children: o.label }, o.id)) }),
1526
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "flex items-center gap-1", children: [
1527
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("input", { type: "checkbox", "aria-label": "Simulate paper colour", checked: view.proof.simulatePaper, onChange: (e) => proofWith({ simulatePaper: e.target.checked }), className: "accent-indigo-500" }),
1528
+ "Paper"
1529
+ ] }),
1530
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "flex items-center gap-1", children: [
1531
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("input", { type: "checkbox", "aria-label": "Gamut warning", checked: view.proof.gamutWarning, onChange: (e) => proofWith({ gamutWarning: e.target.checked }), className: "accent-indigo-500" }),
1532
+ "Gamut warning"
1533
+ ] })
1534
+ ] })
1535
+ ] }),
1536
+ error && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
1537
+ ] });
1538
+ };
1539
+
1540
+ // src/image-editor/SelectionOptionsBar.tsx
1541
+ var import_react9 = require("react");
1542
+ var import_image_editor10 = require("@pixerate/editor/image-editor");
1543
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1452
1544
  var MODIFY_OPS = [
1453
1545
  { op: "grow", label: "Grow" },
1454
1546
  { op: "shrink", label: "Shrink" },
@@ -1465,20 +1557,20 @@ var SelectionOptionsBar = ({
1465
1557
  quickMask,
1466
1558
  className = ""
1467
1559
  }) => {
1468
- const [radius, setRadius] = (0, import_react8.useState)(2);
1560
+ const [radius, setRadius] = (0, import_react9.useState)(2);
1469
1561
  const set = (patch) => onOptionsChange({ ...options, ...patch });
1470
1562
  const sel = selection === void 0 ? controller.getSelection() : selection;
1471
1563
  const qm = quickMask ?? Boolean(controller.getState().quickMask);
1472
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { "data-testid": "selection-options-bar", className: `flex flex-col gap-3 text-xs ${className}`, children: [
1473
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { role: "group", "aria-label": "Selection tool", className: "flex flex-wrap gap-1", children: import_image_editor9.SELECTION_TOOLS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("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)) }),
1474
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { role: "group", "aria-label": "Selection mode", className: "flex flex-wrap gap-1", children: import_image_editor9.SELECTION_MODES.map((m) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", "aria-pressed": options.mode === m, className: btn(options.mode === m), onClick: () => set({ mode: m }), children: import_image_editor9.SELECTION_MODE_LABELS[m] }, m)) }),
1475
- options.tool === "wand" && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-col gap-2", children: [
1476
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "flex flex-col gap-1", children: [
1477
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
1478
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "Tolerance" }),
1479
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "font-mono", children: options.tolerance })
1564
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { "data-testid": "selection-options-bar", className: `flex flex-col gap-3 text-xs ${className}`, children: [
1565
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { role: "group", "aria-label": "Selection tool", className: "flex flex-wrap gap-1", children: import_image_editor10.SELECTION_TOOLS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("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)) }),
1566
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { role: "group", "aria-label": "Selection mode", className: "flex flex-wrap gap-1", children: import_image_editor10.SELECTION_MODES.map((m) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", "aria-pressed": options.mode === m, className: btn(options.mode === m), onClick: () => set({ mode: m }), children: import_image_editor10.SELECTION_MODE_LABELS[m] }, m)) }),
1567
+ options.tool === "wand" && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-col gap-2", children: [
1568
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex flex-col gap-1", children: [
1569
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
1570
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: "Tolerance" }),
1571
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "font-mono", children: options.tolerance })
1480
1572
  ] }),
1481
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1573
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1482
1574
  "input",
1483
1575
  {
1484
1576
  type: "range",
@@ -1492,17 +1584,17 @@ var SelectionOptionsBar = ({
1492
1584
  }
1493
1585
  )
1494
1586
  ] }),
1495
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
1496
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("input", { type: "checkbox", checked: options.contiguous, onChange: (e) => set({ contiguous: e.target.checked }) }),
1587
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
1588
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("input", { type: "checkbox", checked: options.contiguous, onChange: (e) => set({ contiguous: e.target.checked }) }),
1497
1589
  "Contiguous"
1498
1590
  ] }),
1499
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
1500
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("input", { type: "checkbox", checked: options.sampleMerged, onChange: (e) => set({ sampleMerged: e.target.checked }) }),
1591
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
1592
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("input", { type: "checkbox", checked: options.sampleMerged, onChange: (e) => set({ sampleMerged: e.target.checked }) }),
1501
1593
  "Sample adjusted image"
1502
1594
  ] }),
1503
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
1595
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
1504
1596
  "Sample",
1505
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1597
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1506
1598
  "select",
1507
1599
  {
1508
1600
  "aria-label": "Sample from",
@@ -1510,27 +1602,27 @@ var SelectionOptionsBar = ({
1510
1602
  onChange: (e) => set({ sample: e.target.value }),
1511
1603
  className: "bg-slate-800 border border-slate-700 rounded px-1 py-0.5",
1512
1604
  children: [
1513
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "composite", children: "All layers" }),
1514
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "active-layer", children: "Active layer" })
1605
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: "composite", children: "All layers" }),
1606
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: "active-layer", children: "Active layer" })
1515
1607
  ]
1516
1608
  }
1517
1609
  )
1518
1610
  ] })
1519
1611
  ] }),
1520
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
1521
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("input", { type: "checkbox", checked: options.antiAlias, onChange: (e) => set({ antiAlias: e.target.checked }) }),
1612
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
1613
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("input", { type: "checkbox", checked: options.antiAlias, onChange: (e) => set({ antiAlias: e.target.checked }) }),
1522
1614
  "Anti-alias"
1523
1615
  ] }),
1524
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
1525
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: btn(false), onClick: () => controller.selectAll(), children: "Select All" }),
1526
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: btn(false), disabled: !sel, onClick: () => controller.deselect(), children: "Deselect" }),
1527
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: btn(false), onClick: () => controller.invertSelection(), children: "Inverse" }),
1528
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", "aria-pressed": qm, className: btn(qm), onClick: () => controller.setQuickMask(!qm), children: "Quick Mask" })
1616
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
1617
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: btn(false), onClick: () => controller.selectAll(), children: "Select All" }),
1618
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: btn(false), disabled: !sel, onClick: () => controller.deselect(), children: "Deselect" }),
1619
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: btn(false), onClick: () => controller.invertSelection(), children: "Inverse" }),
1620
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", "aria-pressed": qm, className: btn(qm), onClick: () => controller.setQuickMask(!qm), children: "Quick Mask" })
1529
1621
  ] }),
1530
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
1531
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "flex items-center gap-1 text-slate-400", children: [
1622
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
1623
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex items-center gap-1 text-slate-400", children: [
1532
1624
  "Radius",
1533
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1625
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1534
1626
  "input",
1535
1627
  {
1536
1628
  type: "number",
@@ -1544,24 +1636,24 @@ var SelectionOptionsBar = ({
1544
1636
  }
1545
1637
  )
1546
1638
  ] }),
1547
- MODIFY_OPS.map(({ op, label }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: btn(false), disabled: !sel, onClick: () => controller.modifySelection(op, radius), children: label }, op))
1639
+ MODIFY_OPS.map(({ op, label }) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: btn(false), disabled: !sel, onClick: () => controller.modifySelection(op, radius), children: label }, op))
1548
1640
  ] }),
1549
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { "data-testid": "selection-status", className: "text-slate-400", children: (0, import_image_editor9.describeSelection)(sel) })
1641
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { "data-testid": "selection-status", className: "text-slate-400", children: (0, import_image_editor10.describeSelection)(sel) })
1550
1642
  ] });
1551
1643
  };
1552
1644
 
1553
1645
  // src/image-editor/RefineEdgePanel.tsx
1554
- var import_react9 = require("react");
1555
- var import_image_editor10 = require("@pixerate/editor/image-editor");
1556
- var import_jsx_runtime9 = require("react/jsx-runtime");
1646
+ var import_react10 = require("react");
1647
+ var import_image_editor11 = require("@pixerate/editor/image-editor");
1648
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1557
1649
  var DEFAULT_PARAMS = { radius: 8, smartRadius: false, smooth: 0, feather: 0, contrast: 0, shiftEdge: 0 };
1558
1650
  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";
1559
1651
  var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
1560
- const [params, setParams] = (0, import_react9.useState)(DEFAULT_PARAMS);
1561
- const [busy, setBusy] = (0, import_react9.useState)(false);
1562
- const [error, setError] = (0, import_react9.useState)(null);
1563
- const [layerId, setLayerId] = (0, import_react9.useState)("");
1564
- const [newKind, setNewKind] = (0, import_react9.useState)("hueSaturation");
1652
+ const [params, setParams] = (0, import_react10.useState)(DEFAULT_PARAMS);
1653
+ const [busy, setBusy] = (0, import_react10.useState)(false);
1654
+ const [error, setError] = (0, import_react10.useState)(null);
1655
+ const [layerId, setLayerId] = (0, import_react10.useState)("");
1656
+ const [newKind, setNewKind] = (0, import_react10.useState)("hueSaturation");
1565
1657
  const sel = selection === void 0 ? controller.getSelection() : selection;
1566
1658
  const list = layers ?? controller.getAdjustmentLayers();
1567
1659
  const target = list.find((l) => l.id === layerId) ?? list[list.length - 1];
@@ -1576,17 +1668,17 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
1576
1668
  setBusy(false);
1577
1669
  }
1578
1670
  };
1579
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { "data-testid": "refine-edge-panel", className: `flex flex-col gap-3 text-xs ${className}`, children: [
1580
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Refine Edge" }),
1581
- import_image_editor10.REFINE_EDGE_CONTROLS.map((c) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex flex-col gap-1", children: [
1582
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
1583
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: c.label }),
1584
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "font-mono", children: [
1671
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { "data-testid": "refine-edge-panel", className: `flex flex-col gap-3 text-xs ${className}`, children: [
1672
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Refine Edge" }),
1673
+ import_image_editor11.REFINE_EDGE_CONTROLS.map((c) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex flex-col gap-1", children: [
1674
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
1675
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: c.label }),
1676
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "font-mono", children: [
1585
1677
  params[c.id],
1586
1678
  c.unit
1587
1679
  ] })
1588
1680
  ] }),
1589
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1681
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1590
1682
  "input",
1591
1683
  {
1592
1684
  type: "range",
@@ -1600,67 +1692,67 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
1600
1692
  }
1601
1693
  )
1602
1694
  ] }, c.id)),
1603
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
1604
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("input", { type: "checkbox", checked: params.smartRadius, onChange: (e) => setParams({ ...params, smartRadius: e.target.checked }) }),
1695
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
1696
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { type: "checkbox", checked: params.smartRadius, onChange: (e) => setParams({ ...params, smartRadius: e.target.checked }) }),
1605
1697
  "Smart Radius"
1606
1698
  ] }),
1607
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex gap-1", children: [
1608
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: button2, disabled: !sel || busy, onClick: refine, children: "Refine Edge" }),
1609
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: button2, onClick: () => setParams(DEFAULT_PARAMS), children: "Reset" })
1699
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex gap-1", children: [
1700
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: button2, disabled: !sel || busy, onClick: refine, children: "Refine Edge" }),
1701
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: button2, onClick: () => setParams(DEFAULT_PARAMS), children: "Reset" })
1610
1702
  ] }),
1611
- error && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { role: "alert", className: "text-rose-400", children: error }),
1612
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] mt-2", children: "Layer Mask" }),
1613
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex gap-1 items-center", children: [
1614
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1703
+ error && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { role: "alert", className: "text-rose-400", children: error }),
1704
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] mt-2", children: "Layer Mask" }),
1705
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex gap-1 items-center", children: [
1706
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1615
1707
  "select",
1616
1708
  {
1617
1709
  "aria-label": "New masked layer kind",
1618
1710
  value: newKind,
1619
1711
  onChange: (e) => setNewKind(e.target.value),
1620
1712
  className: "flex-1 bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
1621
- children: import_image_editor10.ADJUSTMENT_KINDS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: k.kind, children: k.label }, k.kind))
1713
+ children: import_image_editor11.ADJUSTMENT_KINDS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: k.kind, children: k.label }, k.kind))
1622
1714
  }
1623
1715
  ),
1624
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1716
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1625
1717
  "button",
1626
1718
  {
1627
1719
  type: "button",
1628
1720
  className: button2,
1629
1721
  disabled: !sel,
1630
- onClick: () => sel && setLayerId(controller.addAdjustmentLayer({ kind: newKind, mask: (0, import_image_editor10.layerMaskFromSelection)(sel) })),
1722
+ onClick: () => sel && setLayerId(controller.addAdjustmentLayer({ kind: newKind, mask: (0, import_image_editor11.layerMaskFromSelection)(sel) })),
1631
1723
  children: "New Masked Layer"
1632
1724
  }
1633
1725
  )
1634
1726
  ] }),
1635
- list.length > 0 && target && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-col gap-2", children: [
1636
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1727
+ list.length > 0 && target && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-col gap-2", children: [
1728
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1637
1729
  "select",
1638
1730
  {
1639
1731
  "aria-label": "Mask layer",
1640
1732
  value: target.id,
1641
1733
  onChange: (e) => setLayerId(e.target.value),
1642
1734
  className: "bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
1643
- children: list.map((l) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("option", { value: l.id, children: [
1644
- l.name || (0, import_image_editor10.adjustmentKindLabel)(l.kind),
1735
+ children: list.map((l) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("option", { value: l.id, children: [
1736
+ l.name || (0, import_image_editor11.adjustmentKindLabel)(l.kind),
1645
1737
  l.mask ? " (masked)" : ""
1646
1738
  ] }, l.id))
1647
1739
  }
1648
1740
  ),
1649
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
1650
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: button2, disabled: !sel, onClick: () => controller.applySelectionAsLayerMask(target.id), children: "Mask with Selection" }),
1651
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: button2, disabled: !target.mask, onClick: () => controller.selectionFromLayerMask(target.id), children: "Load as Selection" }),
1652
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: button2, disabled: !target.mask, onClick: () => controller.setAdjustmentLayerMask(target.id, null), children: "Remove Mask" })
1741
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
1742
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: button2, disabled: !sel, onClick: () => controller.applySelectionAsLayerMask(target.id), children: "Mask with Selection" }),
1743
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: button2, disabled: !target.mask, onClick: () => controller.selectionFromLayerMask(target.id), children: "Load as Selection" }),
1744
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: button2, disabled: !target.mask, onClick: () => controller.setAdjustmentLayerMask(target.id, null), children: "Remove Mask" })
1653
1745
  ] }),
1654
- target.mask && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1655
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex flex-col gap-1", children: [
1656
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
1657
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: "Density" }),
1658
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "font-mono", children: [
1746
+ target.mask && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1747
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex flex-col gap-1", children: [
1748
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
1749
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "Density" }),
1750
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "font-mono", children: [
1659
1751
  Math.round((target.mask.density ?? 1) * 100),
1660
1752
  "%"
1661
1753
  ] })
1662
1754
  ] }),
1663
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1755
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1664
1756
  "input",
1665
1757
  {
1666
1758
  type: "range",
@@ -1674,15 +1766,15 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
1674
1766
  }
1675
1767
  )
1676
1768
  ] }),
1677
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex flex-col gap-1", children: [
1678
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
1679
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: "Mask Feather" }),
1680
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "font-mono", children: [
1769
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex flex-col gap-1", children: [
1770
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
1771
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "Mask Feather" }),
1772
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "font-mono", children: [
1681
1773
  target.mask.feather ?? 0,
1682
1774
  "px"
1683
1775
  ] })
1684
1776
  ] }),
1685
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1777
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1686
1778
  "input",
1687
1779
  {
1688
1780
  type: "range",
@@ -1702,14 +1794,14 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
1702
1794
  };
1703
1795
 
1704
1796
  // src/image-editor/FreeTransformOptionsBar.tsx
1705
- var import_react10 = require("react");
1706
- var import_image_editor11 = require("@pixerate/editor/image-editor");
1707
- var import_jsx_runtime10 = require("react/jsx-runtime");
1708
- 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"}`;
1797
+ var import_react11 = require("react");
1798
+ var import_image_editor12 = require("@pixerate/editor/image-editor");
1799
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1800
+ 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"}`;
1709
1801
  var round = (v, unit) => unit === "px" ? Math.round(v * 10) / 10 : Math.round(v * 100) / 100;
1710
1802
  var FreeTransformOptionsBar = ({ tool, className }) => {
1711
- const [, setTick] = (0, import_react10.useState)(0);
1712
- (0, import_react10.useEffect)(() => tool.subscribe(() => setTick((n) => n + 1)), [tool]);
1803
+ const [, setTick] = (0, import_react11.useState)(0);
1804
+ (0, import_react11.useEffect)(() => tool.subscribe(() => setTick((n) => n + 1)), [tool]);
1713
1805
  const bar = tool.bar();
1714
1806
  if (!tool.active || !bar) return null;
1715
1807
  const warp = tool.warpBar();
@@ -1721,17 +1813,17 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
1721
1813
  const v = Number(raw);
1722
1814
  if (raw.trim() !== "" && Number.isFinite(v) && Math.abs(v - bar[field]) > 1e-9) tool.setField(field, v);
1723
1815
  };
1724
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: `flex flex-wrap items-center gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "free-transform-options", role: "toolbar", "aria-label": "Free Transform options", children: [
1725
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex gap-1", role: "group", "aria-label": "Transform mode", children: import_image_editor11.FREE_TRANSFORM_MODE_OPTIONS.map((m) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", title: m.title, "aria-pressed": tool.mode === m.id, className: chip2(tool.mode === m.id), onClick: () => tool.setMode(m.id), children: m.label }, m.id)) }),
1726
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "grid grid-cols-3 gap-px", role: "group", "aria-label": "Reference point", children: import_image_editor11.TRANSFORM_ANCHORS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", "aria-label": `Reference point ${a}`, title: `Reference point: ${a}`, className: "h-2.5 w-2.5 rounded-sm bg-slate-700 hover:bg-indigo-500", onClick: () => tool.setReference(a) }, a)) }),
1727
- tool.mode === "warp" && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-wrap items-center gap-2", role: "group", "aria-label": "Warp options", children: [
1728
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex items-center gap-1", children: [
1729
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-slate-400", children: "Warp" }),
1730
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("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: import_image_editor11.WARP_STYLE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: o.id, children: o.label }, o.id)) })
1816
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: `flex flex-wrap items-center gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "free-transform-options", role: "toolbar", "aria-label": "Free Transform options", children: [
1817
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "flex gap-1", role: "group", "aria-label": "Transform mode", children: import_image_editor12.FREE_TRANSFORM_MODE_OPTIONS.map((m) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("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)) }),
1818
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "grid grid-cols-3 gap-px", role: "group", "aria-label": "Reference point", children: import_image_editor12.TRANSFORM_ANCHORS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", "aria-label": `Reference point ${a}`, title: `Reference point: ${a}`, className: "h-2.5 w-2.5 rounded-sm bg-slate-700 hover:bg-indigo-500", onClick: () => tool.setReference(a) }, a)) }),
1819
+ tool.mode === "warp" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-wrap items-center gap-2", role: "group", "aria-label": "Warp options", children: [
1820
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
1821
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-slate-400", children: "Warp" }),
1822
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("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: import_image_editor12.WARP_STYLE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: o.id, children: o.label }, o.id)) })
1731
1823
  ] }),
1732
- ["bend", "horizontal", "vertical"].map((k) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex items-center gap-1", children: [
1733
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-slate-400", children: k === "bend" ? "Bend" : k === "horizontal" ? "H" : "V" }),
1734
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1824
+ ["bend", "horizontal", "vertical"].map((k) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
1825
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-slate-400", children: k === "bend" ? "Bend" : k === "horizontal" ? "H" : "V" }),
1826
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1735
1827
  "input",
1736
1828
  {
1737
1829
  type: "number",
@@ -1752,40 +1844,40 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
1752
1844
  },
1753
1845
  `${k}:${warp[k]}`
1754
1846
  ),
1755
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-slate-500", children: "%" })
1847
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-slate-500", children: "%" })
1756
1848
  ] }, k)),
1757
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1849
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1758
1850
  "button",
1759
1851
  {
1760
1852
  type: "button",
1761
1853
  title: "Bend along the vertical axis",
1762
1854
  "aria-pressed": warp.orientation === "vertical",
1763
1855
  disabled: warp.style === "custom",
1764
- className: chip2(warp.orientation === "vertical"),
1856
+ className: chip3(warp.orientation === "vertical"),
1765
1857
  onClick: () => tool.setWarp({ orientation: warp.orientation === "vertical" ? "horizontal" : "vertical" }),
1766
1858
  children: "Vertical"
1767
1859
  }
1768
1860
  ),
1769
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex items-center gap-1", children: [
1770
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-slate-400", children: "Grid" }),
1771
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1861
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
1862
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-slate-400", children: "Grid" }),
1863
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1772
1864
  "select",
1773
1865
  {
1774
1866
  "aria-label": "Warp grid",
1775
- value: import_image_editor11.WARP_GRID_OPTIONS.find((g) => g.columns === warp.columns && g.rows === warp.rows)?.id ?? "1x1",
1867
+ value: import_image_editor12.WARP_GRID_OPTIONS.find((g) => g.columns === warp.columns && g.rows === warp.rows)?.id ?? "1x1",
1776
1868
  onChange: (e) => {
1777
- const g = import_image_editor11.WARP_GRID_OPTIONS.find((o) => o.id === e.target.value);
1869
+ const g = import_image_editor12.WARP_GRID_OPTIONS.find((o) => o.id === e.target.value);
1778
1870
  tool.setWarp({ columns: g.columns, rows: g.rows });
1779
1871
  },
1780
1872
  className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
1781
- children: import_image_editor11.WARP_GRID_OPTIONS.map((g) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: g.id, children: g.label }, g.id))
1873
+ children: import_image_editor12.WARP_GRID_OPTIONS.map((g) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: g.id, children: g.label }, g.id))
1782
1874
  }
1783
1875
  )
1784
1876
  ] })
1785
1877
  ] }),
1786
- tool.mode !== "warp" && import_image_editor11.FREE_TRANSFORM_FIELDS.map((f) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex items-center gap-1", title: f.title, children: [
1787
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-slate-400", children: f.label }),
1788
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1878
+ tool.mode !== "warp" && import_image_editor12.FREE_TRANSFORM_FIELDS.map((f) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", title: f.title, children: [
1879
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-slate-400", children: f.label }),
1880
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1789
1881
  "input",
1790
1882
  {
1791
1883
  type: "number",
@@ -1805,14 +1897,14 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
1805
1897
  },
1806
1898
  `${f.id}:${round(bar[f.id], f.unit)}`
1807
1899
  ),
1808
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-slate-500", children: f.unit }),
1809
- f.id === "scaleX" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1900
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-slate-500", children: f.unit }),
1901
+ f.id === "scaleX" && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1810
1902
  "button",
1811
1903
  {
1812
1904
  type: "button",
1813
1905
  "aria-label": "Keep width and height proportional",
1814
1906
  "aria-pressed": tool.proportional,
1815
- className: chip2(tool.proportional),
1907
+ className: chip3(tool.proportional),
1816
1908
  onClick: () => {
1817
1909
  tool.proportional = !tool.proportional;
1818
1910
  setTick((n) => n + 1);
@@ -1821,34 +1913,34 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
1821
1913
  }
1822
1914
  )
1823
1915
  ] }, f.id)),
1824
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex items-center gap-1", children: [
1825
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-slate-400", children: "Interpolation" }),
1826
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1916
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
1917
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-slate-400", children: "Interpolation" }),
1918
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1827
1919
  "select",
1828
1920
  {
1829
1921
  "aria-label": "Interpolation",
1830
1922
  value: tool.interpolation,
1831
1923
  onChange: (e) => tool.setInterpolation(e.target.value),
1832
1924
  className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
1833
- children: import_image_editor11.INTERPOLATIONS.map((i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: i, children: i[0].toUpperCase() + i.slice(1) }, i))
1925
+ children: import_image_editor12.INTERPOLATIONS.map((i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: i, children: i[0].toUpperCase() + i.slice(1) }, i))
1834
1926
  }
1835
1927
  )
1836
1928
  ] }),
1837
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", title: "Commit (Enter)", className: "px-2 py-1 rounded bg-emerald-600 text-white hover:bg-emerald-500", onClick: () => tool.commit(), children: "Commit" }),
1838
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", title: "Cancel (Esc)", className: chip2(false), onClick: () => tool.cancel(), children: "Cancel" }),
1839
- tool.error && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { role: "alert", className: "text-rose-400", children: tool.error })
1929
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", title: "Commit (Enter)", className: "px-2 py-1 rounded bg-emerald-600 text-white hover:bg-emerald-500", onClick: () => tool.commit(), children: "Commit" }),
1930
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", title: "Cancel (Esc)", className: chip3(false), onClick: () => tool.cancel(), children: "Cancel" }),
1931
+ tool.error && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { role: "alert", className: "text-rose-400", children: tool.error })
1840
1932
  ] });
1841
1933
  };
1842
1934
 
1843
1935
  // src/image-editor/ShapeOptionsBar.tsx
1844
- var import_react11 = require("react");
1845
- var import_image_editor12 = require("@pixerate/editor/image-editor");
1846
- var import_jsx_runtime11 = require("react/jsx-runtime");
1847
- 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"}`;
1936
+ var import_react12 = require("react");
1937
+ var import_image_editor13 = require("@pixerate/editor/image-editor");
1938
+ var import_jsx_runtime12 = require("react/jsx-runtime");
1939
+ 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"}`;
1848
1940
  var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
1849
- const [, setTick] = (0, import_react11.useState)(0);
1850
- (0, import_react11.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
1851
- const [error, setError] = (0, import_react11.useState)(null);
1941
+ const [, setTick] = (0, import_react12.useState)(0);
1942
+ (0, import_react12.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
1943
+ const [error, setError] = (0, import_react12.useState)(null);
1852
1944
  const active = controller.getActiveLayer();
1853
1945
  const shapeId = active?.type === "shape" ? active.id : null;
1854
1946
  const set = (change) => {
@@ -1856,19 +1948,19 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
1856
1948
  if (!shapeId) return;
1857
1949
  try {
1858
1950
  setError(null);
1859
- (0, import_image_editor12.applyShapeOptions)(controller, shapeId, change);
1951
+ (0, import_image_editor13.applyShapeOptions)(controller, shapeId, change);
1860
1952
  } catch (e) {
1861
1953
  setError(e instanceof Error ? e.message : String(e));
1862
1954
  }
1863
1955
  };
1864
1956
  const num = (v, min, max) => Math.max(min, Math.min(max, Number(v) || min));
1865
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "shape-options", children: [
1866
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "flex flex-wrap gap-1", role: "toolbar", "aria-label": "Shape kind", children: import_image_editor12.LIVE_SHAPE_KINDS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", "aria-pressed": options.kind === k, className: chip3(options.kind === k), onClick: () => onChange({ ...options, kind: k }), children: import_image_editor12.SHAPE_KIND_LABELS[k] }, k)) }),
1867
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
1868
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
1869
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { type: "checkbox", "aria-label": "Fill", checked: options.fill !== null, onChange: (e) => set({ fill: e.target.checked ? "#4f46e5" : null }) }),
1957
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "shape-options", children: [
1958
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "flex flex-wrap gap-1", role: "toolbar", "aria-label": "Shape kind", children: import_image_editor13.LIVE_SHAPE_KINDS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", "aria-pressed": options.kind === k, className: chip4(options.kind === k), onClick: () => onChange({ ...options, kind: k }), children: import_image_editor13.SHAPE_KIND_LABELS[k] }, k)) }),
1959
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
1960
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
1961
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "checkbox", "aria-label": "Fill", checked: options.fill !== null, onChange: (e) => set({ fill: e.target.checked ? "#4f46e5" : null }) }),
1870
1962
  "Fill",
1871
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1963
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1872
1964
  "input",
1873
1965
  {
1874
1966
  type: "color",
@@ -1880,10 +1972,10 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
1880
1972
  }
1881
1973
  )
1882
1974
  ] }),
1883
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
1884
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { type: "checkbox", "aria-label": "Stroke", checked: options.stroke !== null, onChange: (e) => set({ stroke: e.target.checked ? "#000000" : null }) }),
1975
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
1976
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "checkbox", "aria-label": "Stroke", checked: options.stroke !== null, onChange: (e) => set({ stroke: e.target.checked ? "#000000" : null }) }),
1885
1977
  "Stroke",
1886
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1978
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1887
1979
  "input",
1888
1980
  {
1889
1981
  type: "color",
@@ -1895,9 +1987,9 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
1895
1987
  }
1896
1988
  )
1897
1989
  ] }),
1898
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
1990
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
1899
1991
  "Width",
1900
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1992
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1901
1993
  "input",
1902
1994
  {
1903
1995
  type: "number",
@@ -1911,23 +2003,23 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
1911
2003
  )
1912
2004
  ] })
1913
2005
  ] }),
1914
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
1915
- options.kind === "rect" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
2006
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
2007
+ options.kind === "rect" && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
1916
2008
  "Radius",
1917
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("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" })
2009
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("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" })
1918
2010
  ] }),
1919
- options.kind === "polygon" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
2011
+ options.kind === "polygon" && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
1920
2012
  "Sides",
1921
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("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" })
2013
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("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" })
1922
2014
  ] }),
1923
- options.kind === "star" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
1924
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
2015
+ options.kind === "star" && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
2016
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
1925
2017
  "Points",
1926
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("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" })
2018
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("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" })
1927
2019
  ] }),
1928
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
2020
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
1929
2021
  "Inner",
1930
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2022
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1931
2023
  "input",
1932
2024
  {
1933
2025
  type: "range",
@@ -1942,33 +2034,33 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
1942
2034
  )
1943
2035
  ] })
1944
2036
  ] }),
1945
- options.kind === "line" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
1946
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
2037
+ options.kind === "line" && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
2038
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
1947
2039
  "Weight",
1948
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("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" })
2040
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("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" })
1949
2041
  ] }),
1950
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
1951
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { type: "checkbox", "aria-label": "Arrowhead", checked: options.arrow, onChange: (e) => set({ arrow: e.target.checked }) }),
2042
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
2043
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "checkbox", "aria-label": "Arrowhead", checked: options.arrow, onChange: (e) => set({ arrow: e.target.checked }) }),
1952
2044
  "Arrowhead"
1953
2045
  ] })
1954
2046
  ] })
1955
2047
  ] }),
1956
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("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." }),
1957
- error && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
2048
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("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." }),
2049
+ error && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
1958
2050
  ] });
1959
2051
  };
1960
2052
 
1961
2053
  // src/image-editor/TypeOptionsBar.tsx
1962
- var import_react12 = require("react");
1963
- var import_image_editor13 = require("@pixerate/editor/image-editor");
1964
- var import_jsx_runtime12 = require("react/jsx-runtime");
1965
- 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"}`;
2054
+ var import_react13 = require("react");
2055
+ var import_image_editor14 = require("@pixerate/editor/image-editor");
2056
+ var import_jsx_runtime13 = require("react/jsx-runtime");
2057
+ 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"}`;
1966
2058
  var ALIGN_LABELS = { left: "Left", center: "Centre", right: "Right", justify: "Justify" };
1967
2059
  var TypeOptionsBar = ({ controller, options, onChange, session, className }) => {
1968
- const [, setTick] = (0, import_react12.useState)(0);
1969
- (0, import_react12.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
1970
- (0, import_react12.useEffect)(() => session?.subscribe(() => setTick((n) => n + 1)), [session]);
1971
- const [error, setError] = (0, import_react12.useState)(null);
2060
+ const [, setTick] = (0, import_react13.useState)(0);
2061
+ (0, import_react13.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
2062
+ (0, import_react13.useEffect)(() => session?.subscribe(() => setTick((n) => n + 1)), [session]);
2063
+ const [error, setError] = (0, import_react13.useState)(null);
1972
2064
  const active = controller.getActiveLayer();
1973
2065
  const typeId = !session && active?.type === "type" ? active.id : null;
1974
2066
  const here = session?.alive ? session.styleHere() : {};
@@ -2000,11 +2092,11 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
2000
2092
  setError(e instanceof Error ? e.message : String(e));
2001
2093
  }
2002
2094
  };
2003
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "type-options", children: [
2004
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
2005
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
2095
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "type-options", children: [
2096
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
2097
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "flex items-center gap-1", children: [
2006
2098
  "Font",
2007
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2099
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2008
2100
  "input",
2009
2101
  {
2010
2102
  list: "pixerate-type-fonts",
@@ -2014,11 +2106,11 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
2014
2106
  className: "w-32 rounded border border-slate-700 bg-slate-950 px-1 py-0.5"
2015
2107
  }
2016
2108
  ),
2017
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("datalist", { id: "pixerate-type-fonts", children: fonts.map((f) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: f }, f)) })
2109
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("datalist", { id: "pixerate-type-fonts", children: fonts.map((f) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: f }, f)) })
2018
2110
  ] }),
2019
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
2111
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "flex items-center gap-1", children: [
2020
2112
  "Size",
2021
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2113
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2022
2114
  "input",
2023
2115
  {
2024
2116
  type: "number",
@@ -2031,24 +2123,24 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
2031
2123
  }
2032
2124
  )
2033
2125
  ] }),
2034
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("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" }),
2035
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", "aria-pressed": shown.italic, className: `${chip4(shown.italic)} italic`, onClick: () => style({ italic: !shown.italic }), children: "I" }),
2036
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("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" })
2126
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("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" }),
2127
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", "aria-pressed": shown.italic, className: `${chip5(shown.italic)} italic`, onClick: () => style({ italic: !shown.italic }), children: "I" }),
2128
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("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" })
2037
2129
  ] }),
2038
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "flex gap-1", role: "toolbar", "aria-label": "Alignment", children: import_image_editor13.TEXT_ALIGNS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", "aria-pressed": options.align === a, className: chip4(options.align === a), onClick: () => style({ align: a }), children: ALIGN_LABELS[a] }, a)) }),
2039
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("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." }),
2040
- missing.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("p", { role: "status", className: "text-amber-400", "data-testid": "type-missing-fonts", children: [
2130
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "flex gap-1", role: "toolbar", "aria-label": "Alignment", children: import_image_editor14.TEXT_ALIGNS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", "aria-pressed": options.align === a, className: chip5(options.align === a), onClick: () => style({ align: a }), children: ALIGN_LABELS[a] }, a)) }),
2131
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("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." }),
2132
+ missing.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("p", { role: "status", className: "text-amber-400", "data-testid": "type-missing-fonts", children: [
2041
2133
  "Missing ",
2042
2134
  missing.length === 1 ? "font" : "fonts",
2043
2135
  ": ",
2044
2136
  missing.join(", ")
2045
2137
  ] }),
2046
- error && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
2138
+ error && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
2047
2139
  ] });
2048
2140
  };
2049
2141
 
2050
2142
  // src/image-editor/ImageEditor.tsx
2051
- var import_jsx_runtime13 = require("react/jsx-runtime");
2143
+ var import_jsx_runtime14 = require("react/jsx-runtime");
2052
2144
  var ImageEditor = ({
2053
2145
  editor: externalEditor,
2054
2146
  src,
@@ -2063,65 +2155,65 @@ var ImageEditor = ({
2063
2155
  const internalEditor = useImageEditor({ image: src });
2064
2156
  const editor = externalEditor || internalEditor;
2065
2157
  const { state, controller } = editor;
2066
- const legacyProcess = (0, import_image_editor14.normalizeProcessVersion)(state.adjustments.process) < import_image_editor14.LATEST_PROCESS_VERSION;
2067
- const canvasRef = (0, import_react13.useRef)(null);
2068
- const containerRef = (0, import_react13.useRef)(null);
2069
- const [activeTab, setActiveTab] = (0, import_react13.useState)("crop");
2070
- const [activeCropRatio, setActiveCropRatio] = (0, import_react13.useState)(null);
2071
- const [selectionOptions, setSelectionOptions] = (0, import_react13.useState)(import_image_editor14.DEFAULT_SELECTION_TOOL_OPTIONS);
2072
- const selectionOptionsRef = (0, import_react13.useRef)(selectionOptions);
2158
+ const legacyProcess = (0, import_image_editor15.normalizeProcessVersion)(state.adjustments.process) < import_image_editor15.LATEST_PROCESS_VERSION;
2159
+ const canvasRef = (0, import_react14.useRef)(null);
2160
+ const containerRef = (0, import_react14.useRef)(null);
2161
+ const [activeTab, setActiveTab] = (0, import_react14.useState)("crop");
2162
+ const [activeCropRatio, setActiveCropRatio] = (0, import_react14.useState)(null);
2163
+ const [selectionOptions, setSelectionOptions] = (0, import_react14.useState)(import_image_editor15.DEFAULT_SELECTION_TOOL_OPTIONS);
2164
+ const selectionOptionsRef = (0, import_react14.useRef)(selectionOptions);
2073
2165
  selectionOptionsRef.current = selectionOptions;
2074
- const selectionGestureRef = (0, import_react13.useRef)(null);
2166
+ const selectionGestureRef = (0, import_react14.useRef)(null);
2075
2167
  if (!selectionGestureRef.current || selectionGestureRef.current.controller !== controller) {
2076
- selectionGestureRef.current = new import_image_editor14.SelectionGesture(controller, () => selectionOptionsRef.current);
2168
+ selectionGestureRef.current = new import_image_editor15.SelectionGesture(controller, () => selectionOptionsRef.current);
2077
2169
  }
2078
- const selectionDraftRef = (0, import_react13.useRef)(null);
2079
- const [selectionError, setSelectionError] = (0, import_react13.useState)(null);
2080
- const paintGestureRef = (0, import_react13.useRef)(null);
2081
- const paintControllerRef = (0, import_react13.useRef)(controller);
2170
+ const selectionDraftRef = (0, import_react14.useRef)(null);
2171
+ const [selectionError, setSelectionError] = (0, import_react14.useState)(null);
2172
+ const paintGestureRef = (0, import_react14.useRef)(null);
2173
+ const paintControllerRef = (0, import_react14.useRef)(controller);
2082
2174
  if (!paintGestureRef.current || paintControllerRef.current !== controller) {
2083
- paintGestureRef.current = new import_image_editor14.PaintGesture(controller);
2175
+ paintGestureRef.current = new import_image_editor15.PaintGesture(controller);
2084
2176
  paintControllerRef.current = controller;
2085
2177
  }
2086
- const brushCursorRef = (0, import_react13.useRef)(null);
2087
- const [paintError, setPaintError] = (0, import_react13.useState)(null);
2088
- const transformToolRef = (0, import_react13.useRef)(null);
2089
- const transformControllerRef = (0, import_react13.useRef)(controller);
2178
+ const brushCursorRef = (0, import_react14.useRef)(null);
2179
+ const [paintError, setPaintError] = (0, import_react14.useState)(null);
2180
+ const transformToolRef = (0, import_react14.useRef)(null);
2181
+ const transformControllerRef = (0, import_react14.useRef)(controller);
2090
2182
  if (!transformToolRef.current || transformControllerRef.current !== controller) {
2091
2183
  transformToolRef.current?.cancel();
2092
- transformToolRef.current = new import_image_editor14.FreeTransformTool(controller, {
2184
+ transformToolRef.current = new import_image_editor15.FreeTransformTool(controller, {
2093
2185
  schedule: (run) => typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame(run) : run()
2094
2186
  });
2095
2187
  transformControllerRef.current = controller;
2096
2188
  }
2097
2189
  const transformTool = transformToolRef.current;
2098
- const [, setTransformTick] = (0, import_react13.useState)(0);
2099
- const [transformCursor, setTransformCursor] = (0, import_react13.useState)("default");
2100
- const [shapeOptions, setShapeOptions] = (0, import_react13.useState)(import_image_editor14.DEFAULT_SHAPE_TOOL_OPTIONS);
2101
- const shapeOptionsRef = (0, import_react13.useRef)(shapeOptions);
2190
+ const [, setTransformTick] = (0, import_react14.useState)(0);
2191
+ const [transformCursor, setTransformCursor] = (0, import_react14.useState)("default");
2192
+ const [shapeOptions, setShapeOptions] = (0, import_react14.useState)(import_image_editor15.DEFAULT_SHAPE_TOOL_OPTIONS);
2193
+ const shapeOptionsRef = (0, import_react14.useRef)(shapeOptions);
2102
2194
  shapeOptionsRef.current = shapeOptions;
2103
- const [typeOptions, setTypeOptions] = (0, import_react13.useState)(import_image_editor14.DEFAULT_TYPE_TOOL_OPTIONS);
2104
- const typeOptionsRef = (0, import_react13.useRef)(typeOptions);
2195
+ const [typeOptions, setTypeOptions] = (0, import_react14.useState)(import_image_editor15.DEFAULT_TYPE_TOOL_OPTIONS);
2196
+ const typeOptionsRef = (0, import_react14.useRef)(typeOptions);
2105
2197
  typeOptionsRef.current = typeOptions;
2106
- const shapeGestureRef = (0, import_react13.useRef)(null);
2107
- const typeToolRef = (0, import_react13.useRef)(null);
2108
- const shapeTypeControllerRef = (0, import_react13.useRef)(controller);
2198
+ const shapeGestureRef = (0, import_react14.useRef)(null);
2199
+ const typeToolRef = (0, import_react14.useRef)(null);
2200
+ const shapeTypeControllerRef = (0, import_react14.useRef)(controller);
2109
2201
  if (!shapeGestureRef.current || !typeToolRef.current || shapeTypeControllerRef.current !== controller) {
2110
2202
  typeToolRef.current?.finish();
2111
- shapeGestureRef.current = new import_image_editor14.ShapeDrawGesture(controller, () => shapeOptionsRef.current);
2112
- typeToolRef.current = new import_image_editor14.TypeToolGesture(controller, () => typeOptionsRef.current);
2203
+ shapeGestureRef.current = new import_image_editor15.ShapeDrawGesture(controller, () => shapeOptionsRef.current);
2204
+ typeToolRef.current = new import_image_editor15.TypeToolGesture(controller, () => typeOptionsRef.current);
2113
2205
  shapeTypeControllerRef.current = controller;
2114
2206
  }
2115
- const typeInputRef = (0, import_react13.useRef)(null);
2116
- const [typeSession, setTypeSession] = (0, import_react13.useState)(typeToolRef.current.session);
2117
- const [shapeTypeError, setShapeTypeError] = (0, import_react13.useState)(null);
2118
- const [inpaintPrompt, setInpaintPrompt] = (0, import_react13.useState)("");
2119
- const [inpaintMaskMode, setInpaintMaskMode] = (0, import_react13.useState)("annotations");
2120
- const [isRemovingBg, setIsRemovingBg] = (0, import_react13.useState)(false);
2121
- const [isInpainting, setIsInpainting] = (0, import_react13.useState)(false);
2122
- const [aiError, setAiError] = (0, import_react13.useState)(null);
2123
- const [aiSuccess, setAiSuccess] = (0, import_react13.useState)(null);
2124
- const [aiTarget, setAiTarget] = (0, import_react13.useState)("auto");
2207
+ const typeInputRef = (0, import_react14.useRef)(null);
2208
+ const [typeSession, setTypeSession] = (0, import_react14.useState)(typeToolRef.current.session);
2209
+ const [shapeTypeError, setShapeTypeError] = (0, import_react14.useState)(null);
2210
+ const [inpaintPrompt, setInpaintPrompt] = (0, import_react14.useState)("");
2211
+ const [inpaintMaskMode, setInpaintMaskMode] = (0, import_react14.useState)("annotations");
2212
+ const [isRemovingBg, setIsRemovingBg] = (0, import_react14.useState)(false);
2213
+ const [isInpainting, setIsInpainting] = (0, import_react14.useState)(false);
2214
+ const [aiError, setAiError] = (0, import_react14.useState)(null);
2215
+ const [aiSuccess, setAiSuccess] = (0, import_react14.useState)(null);
2216
+ const [aiTarget, setAiTarget] = (0, import_react14.useState)("auto");
2125
2217
  const aiOptions = aiTarget === "auto" ? {} : { target: aiTarget };
2126
2218
  const effectiveOnInpaint = onInpaint || aiHooks?.onInpaint;
2127
2219
  const effectiveOnRemoveBg = onRemoveBackground || aiHooks?.onRemoveBackground;
@@ -2184,18 +2276,18 @@ var ImageEditor = ({
2184
2276
  setIsInpainting(false);
2185
2277
  }
2186
2278
  };
2187
- const [activeColor, setActiveColor] = (0, import_react13.useState)("#ef4444");
2188
- const [strokeWidth, setStrokeWidth] = (0, import_react13.useState)(3);
2189
- const [fontSize, setFontSize] = (0, import_react13.useState)(24);
2190
- const [textInput, setTextInput] = (0, import_react13.useState)("");
2191
- const draftAnnotationRef = (0, import_react13.useRef)(null);
2192
- const draftCropRef = (0, import_react13.useRef)(null);
2193
- const cropDragInfoRef = (0, import_react13.useRef)(null);
2194
- const annotationDragInfoRef = (0, import_react13.useRef)(null);
2195
- const isDrawingRef = (0, import_react13.useRef)(false);
2196
- const currentPathRef = (0, import_react13.useRef)([]);
2197
- const dragStartPointRef = (0, import_react13.useRef)(null);
2198
- const renderCanvas = (0, import_react13.useCallback)(
2279
+ const [activeColor, setActiveColor] = (0, import_react14.useState)("#ef4444");
2280
+ const [strokeWidth, setStrokeWidth] = (0, import_react14.useState)(3);
2281
+ const [fontSize, setFontSize] = (0, import_react14.useState)(24);
2282
+ const [textInput, setTextInput] = (0, import_react14.useState)("");
2283
+ const draftAnnotationRef = (0, import_react14.useRef)(null);
2284
+ const draftCropRef = (0, import_react14.useRef)(null);
2285
+ const cropDragInfoRef = (0, import_react14.useRef)(null);
2286
+ const annotationDragInfoRef = (0, import_react14.useRef)(null);
2287
+ const isDrawingRef = (0, import_react14.useRef)(false);
2288
+ const currentPathRef = (0, import_react14.useRef)([]);
2289
+ const dragStartPointRef = (0, import_react14.useRef)(null);
2290
+ const renderCanvas = (0, import_react14.useCallback)(
2199
2291
  async (draftAnnotation, draftCrop) => {
2200
2292
  const canvas = canvasRef.current;
2201
2293
  const container = containerRef.current;
@@ -2218,8 +2310,8 @@ var ImageEditor = ({
2218
2310
  },
2219
2311
  [controller, activeTab, transformTool]
2220
2312
  );
2221
- (0, import_react13.useEffect)(() => typeSession?.subscribe(() => void renderCanvas()), [typeSession, renderCanvas]);
2222
- (0, import_react13.useEffect)(() => {
2313
+ (0, import_react14.useEffect)(() => typeSession?.subscribe(() => void renderCanvas()), [typeSession, renderCanvas]);
2314
+ (0, import_react14.useEffect)(() => {
2223
2315
  if (activeTab === "annotate" && state.activeTool === "type") return;
2224
2316
  if (typeToolRef.current?.session) {
2225
2317
  typeToolRef.current.finish();
@@ -2254,7 +2346,7 @@ var ImageEditor = ({
2254
2346
  el.value = "";
2255
2347
  }
2256
2348
  };
2257
- (0, import_react13.useEffect)(() => transformTool.subscribe(() => {
2349
+ (0, import_react14.useEffect)(() => transformTool.subscribe(() => {
2258
2350
  setTransformTick((n) => n + 1);
2259
2351
  void renderCanvas();
2260
2352
  }), [transformTool, renderCanvas]);
@@ -2265,8 +2357,8 @@ var ImageEditor = ({
2265
2357
  const sy = rect.height > 0 ? canvas.height / rect.height : 1;
2266
2358
  const s = controller.getState();
2267
2359
  const cropping = activeTab === "crop";
2268
- const projection = (0, import_image_editor14.getViewportProjection)(s, canvas.width, canvas.height, cropping);
2269
- const pt = (0, import_image_editor14.canvasToImagePoint)({ x: (e.clientX - rect.left) * sx, y: (e.clientY - rect.top) * sy }, s, canvas.width, canvas.height, cropping);
2360
+ const projection = (0, import_image_editor15.getViewportProjection)(s, canvas.width, canvas.height, cropping);
2361
+ const pt = (0, import_image_editor15.canvasToImagePoint)({ x: (e.clientX - rect.left) * sx, y: (e.clientY - rect.top) * sy }, s, canvas.width, canvas.height, cropping);
2270
2362
  transformTool.setView(projection.scale);
2271
2363
  return { pt, tolerance: 6 / (projection.scale || 1) };
2272
2364
  };
@@ -2297,7 +2389,7 @@ var ImageEditor = ({
2297
2389
  transformTool.up();
2298
2390
  return true;
2299
2391
  };
2300
- (0, import_react13.useEffect)(() => {
2392
+ (0, import_react14.useEffect)(() => {
2301
2393
  if (typeof window === "undefined") return;
2302
2394
  const onKey = (e) => {
2303
2395
  if (transformTool.key(e)) e.preventDefault();
@@ -2305,7 +2397,7 @@ var ImageEditor = ({
2305
2397
  window.addEventListener("keydown", onKey);
2306
2398
  return () => window.removeEventListener("keydown", onKey);
2307
2399
  }, [transformTool]);
2308
- (0, import_react13.useEffect)(() => {
2400
+ (0, import_react14.useEffect)(() => {
2309
2401
  const raf = typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : (cb) => setTimeout(cb, 0);
2310
2402
  const caf = typeof cancelAnimationFrame !== "undefined" ? cancelAnimationFrame : (id) => clearTimeout(id);
2311
2403
  const animId = raf(() => {
@@ -2313,12 +2405,12 @@ var ImageEditor = ({
2313
2405
  });
2314
2406
  return () => caf(animId);
2315
2407
  }, [renderCanvas, state]);
2316
- (0, import_react13.useEffect)(() => {
2408
+ (0, import_react14.useEffect)(() => {
2317
2409
  if (activeTab === "crop" && editor.state.activeTool !== "crop") {
2318
2410
  editor.setTool("crop");
2319
2411
  }
2320
2412
  }, [activeTab, editor]);
2321
- (0, import_react13.useEffect)(() => {
2413
+ (0, import_react14.useEffect)(() => {
2322
2414
  const container = containerRef.current;
2323
2415
  if (!container) return;
2324
2416
  if (typeof ResizeObserver !== "undefined") {
@@ -2354,8 +2446,8 @@ var ImageEditor = ({
2354
2446
  const sy = rect.height > 0 ? canvas.height / rect.height : 1;
2355
2447
  const s = controller.getState();
2356
2448
  return list.map((ev) => ({
2357
- ...(0, import_image_editor14.canvasToImagePoint)({ x: (ev.clientX - rect.left) * sx, y: (ev.clientY - rect.top) * sy }, s, canvas.width, canvas.height, false),
2358
- pressure: (0, import_image_editor14.pointerPressure)(ev)
2449
+ ...(0, import_image_editor15.canvasToImagePoint)({ x: (ev.clientX - rect.left) * sx, y: (ev.clientY - rect.top) * sy }, s, canvas.width, canvas.height, false),
2450
+ pressure: (0, import_image_editor15.pointerPressure)(ev)
2359
2451
  }));
2360
2452
  };
2361
2453
  const handlePaintPointerDown = (e) => {
@@ -2386,10 +2478,10 @@ var ImageEditor = ({
2386
2478
  if (g.error) setPaintError(g.error);
2387
2479
  }
2388
2480
  };
2389
- (0, import_react13.useEffect)(() => {
2481
+ (0, import_react14.useEffect)(() => {
2390
2482
  if (activeTab !== "paint" || typeof window === "undefined") return;
2391
2483
  const onKey = (e) => {
2392
- if ((0, import_image_editor14.handlePaintShortcut)(controller, e)) e.preventDefault();
2484
+ if ((0, import_image_editor15.handlePaintShortcut)(controller, e)) e.preventDefault();
2393
2485
  };
2394
2486
  window.addEventListener("keydown", onKey);
2395
2487
  return () => window.removeEventListener("keydown", onKey);
@@ -2400,7 +2492,7 @@ var ImageEditor = ({
2400
2492
  const canvasPt = getCanvasEventPoint(e);
2401
2493
  if (activeTab === "select") {
2402
2494
  const gesture = selectionGestureRef.current;
2403
- const imgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
2495
+ const imgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
2404
2496
  void gesture.begin(imgPt, e).then(() => setSelectionError(gesture.error));
2405
2497
  return;
2406
2498
  }
@@ -2411,8 +2503,8 @@ var ImageEditor = ({
2411
2503
  width: state.imageDimensions.width,
2412
2504
  height: state.imageDimensions.height
2413
2505
  };
2414
- const handle = (0, import_image_editor14.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
2415
- const startImgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
2506
+ const handle = (0, import_image_editor15.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
2507
+ const startImgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
2416
2508
  if (handle) {
2417
2509
  cropDragInfoRef.current = {
2418
2510
  handle,
@@ -2431,7 +2523,7 @@ var ImageEditor = ({
2431
2523
  return;
2432
2524
  }
2433
2525
  if (activeTab === "annotate" && (state.activeTool === "shape" || state.activeTool === "type")) {
2434
- const imgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
2526
+ const imgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
2435
2527
  setShapeTypeError(null);
2436
2528
  if (state.activeTool === "shape") shapeGestureRef.current.down(imgPt);
2437
2529
  else {
@@ -2442,12 +2534,12 @@ var ImageEditor = ({
2442
2534
  return;
2443
2535
  }
2444
2536
  if (activeTab === "annotate") {
2445
- const imgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
2537
+ const imgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
2446
2538
  dragStartPointRef.current = imgPt;
2447
2539
  if (state.activeTool === "select") {
2448
2540
  for (let i = state.annotations.length - 1; i >= 0; i--) {
2449
2541
  const ann = state.annotations[i];
2450
- if ((0, import_image_editor14.hitTestAnnotation)(imgPt, ann)) {
2542
+ if ((0, import_image_editor15.hitTestAnnotation)(imgPt, ann)) {
2451
2543
  editor.selectAnnotation(ann.id);
2452
2544
  annotationDragInfoRef.current = {
2453
2545
  annId: ann.id,
@@ -2483,7 +2575,7 @@ var ImageEditor = ({
2483
2575
  const canvasPt = getCanvasEventPoint(e);
2484
2576
  if (activeTab === "select") {
2485
2577
  const gesture = selectionGestureRef.current;
2486
- if (gesture.active && gesture.move((0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false))) {
2578
+ if (gesture.active && gesture.move((0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false))) {
2487
2579
  selectionDraftRef.current = gesture.draftPath;
2488
2580
  renderCanvas();
2489
2581
  }
@@ -2492,7 +2584,7 @@ var ImageEditor = ({
2492
2584
  if (activeTab === "crop") {
2493
2585
  const drag = cropDragInfoRef.current;
2494
2586
  if (drag) {
2495
- const currentImgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
2587
+ const currentImgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
2496
2588
  let newCrop;
2497
2589
  if (drag.handle === "new") {
2498
2590
  const minX = Math.max(0, Math.min(drag.startImgPt.x, currentImgPt.x));
@@ -2506,7 +2598,7 @@ var ImageEditor = ({
2506
2598
  height: Math.round(Math.max(20, maxY - minY))
2507
2599
  };
2508
2600
  } else {
2509
- newCrop = (0, import_image_editor14.calculateCropDrag)(
2601
+ newCrop = (0, import_image_editor15.calculateCropDrag)(
2510
2602
  drag.startCrop,
2511
2603
  drag.handle,
2512
2604
  drag.startImgPt,
@@ -2526,15 +2618,15 @@ var ImageEditor = ({
2526
2618
  width: state.imageDimensions.width,
2527
2619
  height: state.imageDimensions.height
2528
2620
  };
2529
- const handle = (0, import_image_editor14.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
2530
- canvas.style.cursor = (0, import_image_editor14.getCropCursor)(handle, state.transform);
2621
+ const handle = (0, import_image_editor15.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
2622
+ canvas.style.cursor = (0, import_image_editor15.getCropCursor)(handle, state.transform);
2531
2623
  }
2532
2624
  return;
2533
2625
  }
2534
2626
  if (activeTab === "annotate" && state.activeTool === "shape") {
2535
2627
  const g = shapeGestureRef.current;
2536
2628
  if (g.active) {
2537
- g.move((0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), { shift: e.shiftKey, alt: e.altKey });
2629
+ g.move((0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), { shift: e.shiftKey, alt: e.altKey });
2538
2630
  if (g.error) setShapeTypeError(g.error);
2539
2631
  }
2540
2632
  return;
@@ -2542,7 +2634,7 @@ var ImageEditor = ({
2542
2634
  if (activeTab === "annotate") {
2543
2635
  if (annotationDragInfoRef.current) {
2544
2636
  const drag = annotationDragInfoRef.current;
2545
- const currentImgPt2 = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
2637
+ const currentImgPt2 = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
2546
2638
  const dx = currentImgPt2.x - drag.startImgPt.x;
2547
2639
  const dy = currentImgPt2.y - drag.startImgPt.y;
2548
2640
  editor.updateAnnotation(drag.annId, {
@@ -2554,10 +2646,10 @@ var ImageEditor = ({
2554
2646
  const startPt = dragStartPointRef.current;
2555
2647
  if (!startPt) {
2556
2648
  if (state.activeTool === "select") {
2557
- const imgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
2649
+ const imgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
2558
2650
  let hovered = false;
2559
2651
  for (let i = state.annotations.length - 1; i >= 0; i--) {
2560
- if ((0, import_image_editor14.hitTestAnnotation)(imgPt, state.annotations[i])) {
2652
+ if ((0, import_image_editor15.hitTestAnnotation)(imgPt, state.annotations[i])) {
2561
2653
  hovered = true;
2562
2654
  break;
2563
2655
  }
@@ -2568,7 +2660,7 @@ var ImageEditor = ({
2568
2660
  }
2569
2661
  return;
2570
2662
  }
2571
- const currentImgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
2663
+ const currentImgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
2572
2664
  if (state.activeTool === "pen" && isDrawingRef.current) {
2573
2665
  currentPathRef.current.push(currentImgPt);
2574
2666
  const draft = {
@@ -2648,7 +2740,7 @@ var ImageEditor = ({
2648
2740
  if (activeTab === "select") {
2649
2741
  const gesture = selectionGestureRef.current;
2650
2742
  if (gesture.active) {
2651
- gesture.end((0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), e);
2743
+ gesture.end((0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), e);
2652
2744
  selectionDraftRef.current = null;
2653
2745
  renderCanvas();
2654
2746
  }
@@ -2671,7 +2763,7 @@ var ImageEditor = ({
2671
2763
  }
2672
2764
  if (activeTab === "annotate" && state.activeTool === "type") {
2673
2765
  const tool = typeToolRef.current;
2674
- tool.up((0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false));
2766
+ tool.up((0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false));
2675
2767
  setTypeSession(tool.session);
2676
2768
  if (tool.error) setShapeTypeError(tool.error);
2677
2769
  void renderCanvas();
@@ -2685,7 +2777,7 @@ var ImageEditor = ({
2685
2777
  }
2686
2778
  const startPt = dragStartPointRef.current;
2687
2779
  if (startPt) {
2688
- const currentImgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
2780
+ const currentImgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
2689
2781
  if (state.activeTool === "pen" && isDrawingRef.current) {
2690
2782
  if (currentPathRef.current.length > 1) {
2691
2783
  editor.addAnnotation({
@@ -2781,15 +2873,15 @@ var ImageEditor = ({
2781
2873
  link.click();
2782
2874
  }
2783
2875
  };
2784
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2876
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2785
2877
  "div",
2786
2878
  {
2787
2879
  className: `flex flex-col bg-slate-900 border border-slate-800 rounded-xl overflow-hidden shadow-2xl text-slate-100 ${className}`,
2788
2880
  style,
2789
2881
  children: [
2790
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-wrap items-center justify-between px-4 py-3 bg-slate-950/80 border-b border-slate-800 gap-3", children: [
2791
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-1 bg-slate-900 p-1 rounded-lg border border-slate-800 text-xs", children: [
2792
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2882
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-wrap items-center justify-between px-4 py-3 bg-slate-950/80 border-b border-slate-800 gap-3", children: [
2883
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-1 bg-slate-900 p-1 rounded-lg border border-slate-800 text-xs", children: [
2884
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2793
2885
  "button",
2794
2886
  {
2795
2887
  type: "button",
@@ -2801,7 +2893,7 @@ var ImageEditor = ({
2801
2893
  children: "Transform & Crop"
2802
2894
  }
2803
2895
  ),
2804
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2896
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2805
2897
  "button",
2806
2898
  {
2807
2899
  type: "button",
@@ -2813,7 +2905,7 @@ var ImageEditor = ({
2813
2905
  children: "Adjustments"
2814
2906
  }
2815
2907
  ),
2816
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2908
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2817
2909
  "button",
2818
2910
  {
2819
2911
  type: "button",
@@ -2825,7 +2917,7 @@ var ImageEditor = ({
2825
2917
  children: "Layers"
2826
2918
  }
2827
2919
  ),
2828
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2920
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2829
2921
  "button",
2830
2922
  {
2831
2923
  type: "button",
@@ -2837,7 +2929,7 @@ var ImageEditor = ({
2837
2929
  children: "Paint"
2838
2930
  }
2839
2931
  ),
2840
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2932
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2841
2933
  "button",
2842
2934
  {
2843
2935
  type: "button",
@@ -2849,7 +2941,7 @@ var ImageEditor = ({
2849
2941
  children: "Select & Mask"
2850
2942
  }
2851
2943
  ),
2852
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2944
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2853
2945
  "button",
2854
2946
  {
2855
2947
  type: "button",
@@ -2861,7 +2953,7 @@ var ImageEditor = ({
2861
2953
  children: "Annotations"
2862
2954
  }
2863
2955
  ),
2864
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2956
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2865
2957
  "button",
2866
2958
  {
2867
2959
  type: "button",
@@ -2873,7 +2965,7 @@ var ImageEditor = ({
2873
2965
  children: "Depth Mask"
2874
2966
  }
2875
2967
  ),
2876
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2968
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2877
2969
  "button",
2878
2970
  {
2879
2971
  type: "button",
@@ -2883,14 +2975,14 @@ var ImageEditor = ({
2883
2975
  },
2884
2976
  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"}`,
2885
2977
  children: [
2886
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" }) }),
2978
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" }) }),
2887
2979
  "AI Tools"
2888
2980
  ]
2889
2981
  }
2890
2982
  )
2891
2983
  ] }),
2892
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-2 text-xs", children: [
2893
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2984
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-2 text-xs", children: [
2985
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2894
2986
  "button",
2895
2987
  {
2896
2988
  type: "button",
@@ -2901,7 +2993,7 @@ var ImageEditor = ({
2901
2993
  children: "\u21A9"
2902
2994
  }
2903
2995
  ),
2904
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2996
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2905
2997
  "button",
2906
2998
  {
2907
2999
  type: "button",
@@ -2912,7 +3004,7 @@ var ImageEditor = ({
2912
3004
  children: "\u21AA"
2913
3005
  }
2914
3006
  ),
2915
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3007
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2916
3008
  "button",
2917
3009
  {
2918
3010
  type: "button",
@@ -2921,8 +3013,8 @@ var ImageEditor = ({
2921
3013
  children: "Reset"
2922
3014
  }
2923
3015
  ),
2924
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
2925
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3016
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
3017
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2926
3018
  "button",
2927
3019
  {
2928
3020
  type: "button",
@@ -2932,11 +3024,11 @@ var ImageEditor = ({
2932
3024
  children: "-"
2933
3025
  }
2934
3026
  ),
2935
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "font-mono text-slate-400 w-10 text-center", children: [
3027
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "font-mono text-slate-400 w-10 text-center", children: [
2936
3028
  Math.round(state.zoom * 100),
2937
3029
  "%"
2938
3030
  ] }),
2939
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3031
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2940
3032
  "button",
2941
3033
  {
2942
3034
  type: "button",
@@ -2946,8 +3038,8 @@ var ImageEditor = ({
2946
3038
  children: "+"
2947
3039
  }
2948
3040
  ),
2949
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
2950
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3041
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
3042
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2951
3043
  "button",
2952
3044
  {
2953
3045
  type: "button",
@@ -2958,7 +3050,7 @@ var ImageEditor = ({
2958
3050
  children: "Hold Compare"
2959
3051
  }
2960
3052
  ),
2961
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3053
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2962
3054
  "button",
2963
3055
  {
2964
3056
  type: "button",
@@ -2969,16 +3061,16 @@ var ImageEditor = ({
2969
3061
  )
2970
3062
  ] })
2971
3063
  ] }),
2972
- transformTool.active && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(FreeTransformOptionsBar, { tool: transformTool, className: "border-b border-slate-800 bg-slate-900/95 px-4 py-2" }),
2973
- !transformTool.active && transformTool.error && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { role: "alert", className: "border-b border-rose-900 bg-rose-950/80 px-4 py-1.5 text-xs text-rose-200", children: transformTool.error }),
2974
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col md:flex-row flex-1 min-h-[520px] md:h-[560px]", children: [
2975
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
3064
+ transformTool.active && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(FreeTransformOptionsBar, { tool: transformTool, className: "border-b border-slate-800 bg-slate-900/95 px-4 py-2" }),
3065
+ !transformTool.active && transformTool.error && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { role: "alert", className: "border-b border-rose-900 bg-rose-950/80 px-4 py-1.5 text-xs text-rose-200", children: transformTool.error }),
3066
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col md:flex-row flex-1 min-h-[520px] md:h-[560px]", children: [
3067
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2976
3068
  "div",
2977
3069
  {
2978
3070
  ref: containerRef,
2979
3071
  className: "relative flex-1 h-[360px] md:h-full min-h-[320px] bg-slate-950 overflow-hidden select-none",
2980
3072
  children: [
2981
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3073
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2982
3074
  "canvas",
2983
3075
  {
2984
3076
  ref: canvasRef,
@@ -2995,7 +3087,7 @@ var ImageEditor = ({
2995
3087
  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" : ""}`
2996
3088
  }
2997
3089
  ),
2998
- typeSession && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3090
+ typeSession && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2999
3091
  "textarea",
3000
3092
  {
3001
3093
  ref: typeInputRef,
@@ -3017,11 +3109,11 @@ var ImageEditor = ({
3017
3109
  ]
3018
3110
  }
3019
3111
  ),
3020
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "w-full md:w-80 bg-slate-900/90 border-t md:border-t-0 md:border-l border-slate-800 p-4 overflow-y-auto h-auto md:h-full md:max-h-[560px]", children: [
3021
- activeTab === "crop" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
3022
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Aspect Ratio Presets" }),
3023
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "grid grid-cols-3 gap-2", children: [
3024
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3112
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "w-full md:w-80 bg-slate-900/90 border-t md:border-t-0 md:border-l border-slate-800 p-4 overflow-y-auto h-auto md:h-full md:max-h-[560px]", children: [
3113
+ activeTab === "crop" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
3114
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Aspect Ratio Presets" }),
3115
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "grid grid-cols-3 gap-2", children: [
3116
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3025
3117
  "button",
3026
3118
  {
3027
3119
  type: "button",
@@ -3033,7 +3125,7 @@ var ImageEditor = ({
3033
3125
  children: "Freeform"
3034
3126
  }
3035
3127
  ),
3036
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3128
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3037
3129
  "button",
3038
3130
  {
3039
3131
  type: "button",
@@ -3045,7 +3137,7 @@ var ImageEditor = ({
3045
3137
  children: "1:1 Square"
3046
3138
  }
3047
3139
  ),
3048
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3140
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3049
3141
  "button",
3050
3142
  {
3051
3143
  type: "button",
@@ -3057,7 +3149,7 @@ var ImageEditor = ({
3057
3149
  children: "4:3 Standard"
3058
3150
  }
3059
3151
  ),
3060
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3152
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3061
3153
  "button",
3062
3154
  {
3063
3155
  type: "button",
@@ -3069,7 +3161,7 @@ var ImageEditor = ({
3069
3161
  children: "16:9 Wide"
3070
3162
  }
3071
3163
  ),
3072
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3164
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3073
3165
  "button",
3074
3166
  {
3075
3167
  type: "button",
@@ -3081,7 +3173,7 @@ var ImageEditor = ({
3081
3173
  children: "3:2 Photo"
3082
3174
  }
3083
3175
  ),
3084
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3176
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3085
3177
  "button",
3086
3178
  {
3087
3179
  type: "button",
@@ -3094,10 +3186,10 @@ var ImageEditor = ({
3094
3186
  }
3095
3187
  )
3096
3188
  ] }),
3097
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
3098
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Orientation & Flips" }),
3099
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
3100
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3189
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
3190
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Orientation & Flips" }),
3191
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
3192
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3101
3193
  "button",
3102
3194
  {
3103
3195
  type: "button",
@@ -3106,7 +3198,7 @@ var ImageEditor = ({
3106
3198
  children: "Rotate -90\xB0"
3107
3199
  }
3108
3200
  ),
3109
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3201
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3110
3202
  "button",
3111
3203
  {
3112
3204
  type: "button",
@@ -3115,7 +3207,7 @@ var ImageEditor = ({
3115
3207
  children: "Rotate +90\xB0"
3116
3208
  }
3117
3209
  ),
3118
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3210
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3119
3211
  "button",
3120
3212
  {
3121
3213
  type: "button",
@@ -3124,7 +3216,7 @@ var ImageEditor = ({
3124
3216
  children: "Flip Horizontal"
3125
3217
  }
3126
3218
  ),
3127
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3219
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3128
3220
  "button",
3129
3221
  {
3130
3222
  type: "button",
@@ -3135,10 +3227,10 @@ var ImageEditor = ({
3135
3227
  )
3136
3228
  ] })
3137
3229
  ] }),
3138
- activeTab === "adjust" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
3139
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center justify-between", children: [
3140
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Color Adjustments" }),
3141
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3230
+ activeTab === "adjust" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
3231
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center justify-between", children: [
3232
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Color Adjustments" }),
3233
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3142
3234
  "button",
3143
3235
  {
3144
3236
  type: "button",
@@ -3148,25 +3240,25 @@ var ImageEditor = ({
3148
3240
  }
3149
3241
  )
3150
3242
  ] }),
3151
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Histogram, { histogram: editor.histogram }),
3152
- import_image_editor14.IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react13.default.Fragment, { children: [
3153
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3243
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Histogram, { histogram: editor.histogram }),
3244
+ import_image_editor15.IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react14.default.Fragment, { children: [
3245
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3154
3246
  ControlSlider,
3155
3247
  {
3156
3248
  spec,
3157
- value: (0, import_image_editor14.readAdjustmentControls)(state.adjustments)[spec.id],
3249
+ value: (0, import_image_editor15.readAdjustmentControls)(state.adjustments)[spec.id],
3158
3250
  disabled: spec.requiresProcess !== void 0 && legacyProcess,
3159
3251
  onChange: (v) => editor.setAdjustments({ [spec.id]: v })
3160
3252
  }
3161
3253
  ),
3162
- spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
3254
+ spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
3163
3255
  "div",
3164
3256
  {
3165
3257
  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",
3166
3258
  "data-testid": "image-editor-process-notice",
3167
3259
  children: [
3168
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Legacy rendering (process 1). Tint needs the current process." }),
3169
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3260
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Legacy rendering (process 1). Tint needs the current process." }),
3261
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3170
3262
  "button",
3171
3263
  {
3172
3264
  type: "button",
@@ -3179,7 +3271,7 @@ var ImageEditor = ({
3179
3271
  }
3180
3272
  )
3181
3273
  ] }, spec.id)),
3182
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3274
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3183
3275
  AdjustmentLayersPanel,
3184
3276
  {
3185
3277
  controller,
@@ -3188,9 +3280,9 @@ var ImageEditor = ({
3188
3280
  }
3189
3281
  ) })
3190
3282
  ] }),
3191
- activeTab === "layers" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
3192
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Layers" }),
3193
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3283
+ activeTab === "layers" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
3284
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Layers" }),
3285
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3194
3286
  "button",
3195
3287
  {
3196
3288
  type: "button",
@@ -3201,12 +3293,14 @@ var ImageEditor = ({
3201
3293
  children: "Free Transform"
3202
3294
  }
3203
3295
  ),
3204
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(LayersPanel, { controller })
3296
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(LayersPanel, { controller }),
3297
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Colour" }),
3298
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ColorProfilePanel, { controller })
3205
3299
  ] }),
3206
- activeTab === "paint" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
3207
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Paint" }),
3208
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(BrushOptionsBar, { controller }),
3209
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3300
+ activeTab === "paint" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
3301
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Paint" }),
3302
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(BrushOptionsBar, { controller }),
3303
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3210
3304
  "button",
3211
3305
  {
3212
3306
  type: "button",
@@ -3217,12 +3311,12 @@ var ImageEditor = ({
3217
3311
  children: "Free Transform"
3218
3312
  }
3219
3313
  ),
3220
- paintError && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "paint-error", children: paintError }),
3221
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(LayersPanel, { controller }) })
3314
+ paintError && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "paint-error", children: paintError }),
3315
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(LayersPanel, { controller }) })
3222
3316
  ] }),
3223
- activeTab === "annotate" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
3224
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Shape & Type Layers" }),
3225
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "grid grid-cols-2 gap-1.5", children: ["shape", "type"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3317
+ activeTab === "annotate" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
3318
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Shape & Type Layers" }),
3319
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "grid grid-cols-2 gap-1.5", children: ["shape", "type"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3226
3320
  "button",
3227
3321
  {
3228
3322
  type: "button",
@@ -3233,13 +3327,13 @@ var ImageEditor = ({
3233
3327
  },
3234
3328
  t
3235
3329
  )) }),
3236
- state.activeTool === "shape" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ShapeOptionsBar, { controller, options: shapeOptions, onChange: setShapeOptions }),
3237
- state.activeTool === "type" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TypeOptionsBar, { controller, options: typeOptions, onChange: setTypeOptions, session: typeSession }),
3238
- state.activeTool === "type" && typeSession && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("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" }),
3239
- shapeTypeError && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "shape-type-error", children: shapeTypeError }),
3240
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
3241
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Draw & Annotate" }),
3242
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "grid grid-cols-3 gap-1.5", children: ["pen", "rect", "circle", "arrow", "line"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3330
+ state.activeTool === "shape" && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ShapeOptionsBar, { controller, options: shapeOptions, onChange: setShapeOptions }),
3331
+ state.activeTool === "type" && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(TypeOptionsBar, { controller, options: typeOptions, onChange: setTypeOptions, session: typeSession }),
3332
+ state.activeTool === "type" && typeSession && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("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" }),
3333
+ shapeTypeError && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "shape-type-error", children: shapeTypeError }),
3334
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
3335
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Draw & Annotate" }),
3336
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "grid grid-cols-3 gap-1.5", children: ["pen", "rect", "circle", "arrow", "line"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3243
3337
  "button",
3244
3338
  {
3245
3339
  type: "button",
@@ -3249,9 +3343,9 @@ var ImageEditor = ({
3249
3343
  },
3250
3344
  t
3251
3345
  )) }),
3252
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-2 mt-2", children: [
3253
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { className: "text-slate-400", children: "Color:" }),
3254
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3346
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-2 mt-2", children: [
3347
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("label", { className: "text-slate-400", children: "Color:" }),
3348
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3255
3349
  "input",
3256
3350
  {
3257
3351
  type: "color",
@@ -3260,15 +3354,15 @@ var ImageEditor = ({
3260
3354
  className: "w-8 h-8 rounded border border-slate-700 cursor-pointer bg-transparent"
3261
3355
  }
3262
3356
  ),
3263
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex-1 ml-2", children: [
3264
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex justify-between text-slate-400 mb-0.5", children: [
3265
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Width:" }),
3266
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "font-mono", children: [
3357
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex-1 ml-2", children: [
3358
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex justify-between text-slate-400 mb-0.5", children: [
3359
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Width:" }),
3360
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "font-mono", children: [
3267
3361
  strokeWidth,
3268
3362
  "px"
3269
3363
  ] })
3270
3364
  ] }),
3271
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3365
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3272
3366
  "input",
3273
3367
  {
3274
3368
  type: "range",
@@ -3281,10 +3375,10 @@ var ImageEditor = ({
3281
3375
  )
3282
3376
  ] })
3283
3377
  ] }),
3284
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
3285
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Add Text" }),
3286
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex gap-2", children: [
3287
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3378
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
3379
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Add Text" }),
3380
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex gap-2", children: [
3381
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3288
3382
  "input",
3289
3383
  {
3290
3384
  type: "text",
@@ -3295,7 +3389,7 @@ var ImageEditor = ({
3295
3389
  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"
3296
3390
  }
3297
3391
  ),
3298
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3392
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3299
3393
  "button",
3300
3394
  {
3301
3395
  type: "button",
@@ -3305,14 +3399,14 @@ var ImageEditor = ({
3305
3399
  }
3306
3400
  )
3307
3401
  ] }),
3308
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center justify-between text-slate-400", children: [
3309
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Font Size:" }),
3310
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "font-mono", children: [
3402
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center justify-between text-slate-400", children: [
3403
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Font Size:" }),
3404
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "font-mono", children: [
3311
3405
  fontSize,
3312
3406
  "px"
3313
3407
  ] })
3314
3408
  ] }),
3315
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3409
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3316
3410
  "input",
3317
3411
  {
3318
3412
  type: "range",
@@ -3323,14 +3417,14 @@ var ImageEditor = ({
3323
3417
  className: "w-full accent-indigo-500"
3324
3418
  }
3325
3419
  ),
3326
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
3327
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center justify-between", children: [
3328
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "text-slate-400", children: [
3420
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
3421
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center justify-between", children: [
3422
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "text-slate-400", children: [
3329
3423
  "Layers (",
3330
3424
  state.annotations.length,
3331
3425
  ")"
3332
3426
  ] }),
3333
- state.selectedAnnotationId && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3427
+ state.selectedAnnotationId && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3334
3428
  "button",
3335
3429
  {
3336
3430
  type: "button",
@@ -3339,7 +3433,7 @@ var ImageEditor = ({
3339
3433
  children: "Delete Selected"
3340
3434
  }
3341
3435
  ),
3342
- state.annotations.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3436
+ state.annotations.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3343
3437
  "button",
3344
3438
  {
3345
3439
  type: "button",
@@ -3350,10 +3444,10 @@ var ImageEditor = ({
3350
3444
  )
3351
3445
  ] })
3352
3446
  ] }),
3353
- activeTab === "depth" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
3354
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center justify-between", children: [
3355
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Depth Masking" }),
3356
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3447
+ activeTab === "depth" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
3448
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center justify-between", children: [
3449
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Depth Masking" }),
3450
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3357
3451
  "button",
3358
3452
  {
3359
3453
  type: "button",
@@ -3363,8 +3457,8 @@ var ImageEditor = ({
3363
3457
  }
3364
3458
  )
3365
3459
  ] }),
3366
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300", children: [
3367
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3460
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300", children: [
3461
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3368
3462
  "input",
3369
3463
  {
3370
3464
  type: "checkbox",
@@ -3373,12 +3467,12 @@ var ImageEditor = ({
3373
3467
  className: "rounded accent-indigo-500"
3374
3468
  }
3375
3469
  ),
3376
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Enable Depth / Alpha Mask" })
3470
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Enable Depth / Alpha Mask" })
3377
3471
  ] }),
3378
- state.depthMask.enabled && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
3379
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { children: [
3380
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { className: "text-slate-400 block mb-1", children: "Mask Image URL:" }),
3381
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3472
+ state.depthMask.enabled && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
3473
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
3474
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("label", { className: "text-slate-400 block mb-1", children: "Mask Image URL:" }),
3475
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3382
3476
  "input",
3383
3477
  {
3384
3478
  type: "text",
@@ -3389,8 +3483,8 @@ var ImageEditor = ({
3389
3483
  }
3390
3484
  )
3391
3485
  ] }),
3392
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex gap-2", children: [
3393
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3486
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex gap-2", children: [
3487
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3394
3488
  "button",
3395
3489
  {
3396
3490
  type: "button",
@@ -3399,7 +3493,7 @@ var ImageEditor = ({
3399
3493
  children: "Threshold Mode"
3400
3494
  }
3401
3495
  ),
3402
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3496
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3403
3497
  "button",
3404
3498
  {
3405
3499
  type: "button",
@@ -3409,12 +3503,12 @@ var ImageEditor = ({
3409
3503
  }
3410
3504
  )
3411
3505
  ] }),
3412
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { children: [
3413
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
3414
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Depth Start (Lower):" }),
3415
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[0] })
3506
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
3507
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
3508
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Depth Start (Lower):" }),
3509
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[0] })
3416
3510
  ] }),
3417
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3511
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3418
3512
  "input",
3419
3513
  {
3420
3514
  type: "range",
@@ -3428,12 +3522,12 @@ var ImageEditor = ({
3428
3522
  }
3429
3523
  )
3430
3524
  ] }),
3431
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { children: [
3432
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
3433
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Depth Stop (Upper):" }),
3434
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[1] })
3525
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
3526
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
3527
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Depth Stop (Upper):" }),
3528
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[1] })
3435
3529
  ] }),
3436
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3530
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3437
3531
  "input",
3438
3532
  {
3439
3533
  type: "range",
@@ -3447,12 +3541,12 @@ var ImageEditor = ({
3447
3541
  }
3448
3542
  )
3449
3543
  ] }),
3450
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { children: [
3451
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
3452
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Softness:" }),
3453
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-mono", children: state.depthMask.softness })
3544
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
3545
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
3546
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Softness:" }),
3547
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-mono", children: state.depthMask.softness })
3454
3548
  ] }),
3455
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3549
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3456
3550
  "input",
3457
3551
  {
3458
3552
  type: "range",
@@ -3464,8 +3558,8 @@ var ImageEditor = ({
3464
3558
  }
3465
3559
  )
3466
3560
  ] }),
3467
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300 mt-1", children: [
3468
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3561
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300 mt-1", children: [
3562
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3469
3563
  "input",
3470
3564
  {
3471
3565
  type: "checkbox",
@@ -3474,12 +3568,12 @@ var ImageEditor = ({
3474
3568
  className: "rounded accent-indigo-500"
3475
3569
  }
3476
3570
  ),
3477
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Invert Mask" })
3571
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Invert Mask" })
3478
3572
  ] })
3479
3573
  ] })
3480
3574
  ] }),
3481
- activeTab === "select" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
3482
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3575
+ activeTab === "select" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
3576
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3483
3577
  SelectionOptionsBar,
3484
3578
  {
3485
3579
  controller,
@@ -3489,9 +3583,9 @@ var ImageEditor = ({
3489
3583
  quickMask: Boolean(state.quickMask)
3490
3584
  }
3491
3585
  ),
3492
- selectionError && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { role: "alert", className: "text-rose-400", children: selectionError }),
3493
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex gap-1", children: [
3494
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3586
+ selectionError && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { role: "alert", className: "text-rose-400", children: selectionError }),
3587
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex gap-1", children: [
3588
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3495
3589
  "button",
3496
3590
  {
3497
3591
  type: "button",
@@ -3502,7 +3596,7 @@ var ImageEditor = ({
3502
3596
  children: "Transform Selection"
3503
3597
  }
3504
3598
  ),
3505
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3599
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3506
3600
  "button",
3507
3601
  {
3508
3602
  type: "button",
@@ -3514,12 +3608,12 @@ var ImageEditor = ({
3514
3608
  }
3515
3609
  )
3516
3610
  ] }),
3517
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(RefineEdgePanel, { controller, selection: state.selection ?? null, layers: state.adjustments.layers })
3611
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(RefineEdgePanel, { controller, selection: state.selection ?? null, layers: state.adjustments.layers })
3518
3612
  ] }),
3519
- activeTab === "ai" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
3520
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "flex items-center justify-between gap-2 text-slate-300", children: [
3521
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Results go to" }),
3522
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
3613
+ activeTab === "ai" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
3614
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center justify-between gap-2 text-slate-300", children: [
3615
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Results go to" }),
3616
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
3523
3617
  "select",
3524
3618
  {
3525
3619
  "aria-label": "AI result target",
@@ -3527,54 +3621,54 @@ var ImageEditor = ({
3527
3621
  onChange: (e) => setAiTarget(e.target.value),
3528
3622
  className: "bg-slate-800 border border-slate-700 rounded px-1.5 py-1",
3529
3623
  children: [
3530
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "auto", children: controller.isMultiLayer ? "Auto (new layer)" : "Auto (replace image)" }),
3531
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "new-layer", children: "New layer / mask" }),
3532
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "replace", children: "Replace image" })
3624
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("option", { value: "auto", children: controller.isMultiLayer ? "Auto (new layer)" : "Auto (replace image)" }),
3625
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("option", { value: "new-layer", children: "New layer / mask" }),
3626
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("option", { value: "replace", children: "Replace image" })
3533
3627
  ]
3534
3628
  }
3535
3629
  )
3536
3630
  ] }),
3537
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
3538
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center justify-between", children: [
3539
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
3540
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("svg", { className: "w-3.5 h-3.5 text-indigo-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M6 3v12M18 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM6 21a3 3 0 1 0 0-6 3 3 0 0 0 0 6z" }) }),
3631
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
3632
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center justify-between", children: [
3633
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
3634
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("svg", { className: "w-3.5 h-3.5 text-indigo-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M6 3v12M18 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM6 21a3 3 0 1 0 0-6 3 3 0 0 0 0 6z" }) }),
3541
3635
  "Background Removal"
3542
3636
  ] }),
3543
- isRemovingBg && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-indigo-900/60 text-indigo-300 animate-pulse", children: "Removing..." })
3637
+ isRemovingBg && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-indigo-900/60 text-indigo-300 animate-pulse", children: "Removing..." })
3544
3638
  ] }),
3545
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Isolate foreground subject with AI alpha transparency segmentation." }),
3546
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3639
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Isolate foreground subject with AI alpha transparency segmentation." }),
3640
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3547
3641
  "button",
3548
3642
  {
3549
3643
  type: "button",
3550
3644
  onClick: handleRemoveBackground,
3551
3645
  disabled: isRemovingBg || isInpainting,
3552
3646
  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",
3553
- children: isRemovingBg ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
3554
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
3647
+ children: isRemovingBg ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
3648
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
3555
3649
  "Removing Background..."
3556
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
3557
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" }) }),
3650
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
3651
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" }) }),
3558
3652
  "Remove Background"
3559
3653
  ] })
3560
3654
  }
3561
3655
  )
3562
3656
  ] }),
3563
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
3564
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center justify-between", children: [
3565
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
3566
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("svg", { className: "w-3.5 h-3.5 text-purple-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
3567
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "m21.64 3.64-1.28-1.28a1.2 1.2 0 0 0-1.7 0l-9.72 9.72-1.94 4.86 4.86-1.94 9.72-9.72a1.2 1.2 0 0 0 .06-1.64z" }),
3568
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "m14 7 3 3" })
3657
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
3658
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center justify-between", children: [
3659
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
3660
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("svg", { className: "w-3.5 h-3.5 text-purple-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
3661
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "m21.64 3.64-1.28-1.28a1.2 1.2 0 0 0-1.7 0l-9.72 9.72-1.94 4.86 4.86-1.94 9.72-9.72a1.2 1.2 0 0 0 .06-1.64z" }),
3662
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "m14 7 3 3" })
3569
3663
  ] }),
3570
3664
  "Generative Inpainting"
3571
3665
  ] }),
3572
- isInpainting && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-purple-900/60 text-purple-300 animate-pulse", children: "Inpainting..." })
3666
+ isInpainting && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-purple-900/60 text-purple-300 animate-pulse", children: "Inpainting..." })
3573
3667
  ] }),
3574
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Replace, modify, or fill selected regions using prompt-guided generative inpainting." }),
3575
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-1", children: [
3576
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { htmlFor: "ai-inpaint-prompt-react", className: "text-slate-300 text-[11px] font-medium", children: "Prompt" }),
3577
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3668
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Replace, modify, or fill selected regions using prompt-guided generative inpainting." }),
3669
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-1", children: [
3670
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("label", { htmlFor: "ai-inpaint-prompt-react", className: "text-slate-300 text-[11px] font-medium", children: "Prompt" }),
3671
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3578
3672
  "textarea",
3579
3673
  {
3580
3674
  id: "ai-inpaint-prompt-react",
@@ -3586,10 +3680,10 @@ var ImageEditor = ({
3586
3680
  }
3587
3681
  )
3588
3682
  ] }),
3589
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-1", children: [
3590
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-slate-300 text-[11px] font-medium", children: "Target Mask Region" }),
3591
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "grid grid-cols-2 gap-1.5", children: [
3592
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
3683
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-1", children: [
3684
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "text-slate-300 text-[11px] font-medium", children: "Target Mask Region" }),
3685
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "grid grid-cols-2 gap-1.5", children: [
3686
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
3593
3687
  "button",
3594
3688
  {
3595
3689
  type: "button",
@@ -3602,7 +3696,7 @@ var ImageEditor = ({
3602
3696
  ]
3603
3697
  }
3604
3698
  ),
3605
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
3699
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
3606
3700
  "button",
3607
3701
  {
3608
3702
  type: "button",
@@ -3617,25 +3711,25 @@ var ImageEditor = ({
3617
3711
  )
3618
3712
  ] })
3619
3713
  ] }),
3620
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3714
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3621
3715
  "button",
3622
3716
  {
3623
3717
  type: "button",
3624
3718
  onClick: handleInpaint,
3625
3719
  disabled: isInpainting || isRemovingBg || !inpaintPrompt.trim(),
3626
3720
  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",
3627
- children: isInpainting ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
3628
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
3721
+ children: isInpainting ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
3722
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
3629
3723
  "Generating Inpaint..."
3630
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
3631
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" }) }),
3724
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
3725
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" }) }),
3632
3726
  "Apply Inpainting"
3633
3727
  ] })
3634
3728
  }
3635
3729
  )
3636
3730
  ] }),
3637
- aiError && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "p-2.5 rounded-lg bg-rose-950/60 border border-rose-800 text-rose-300 text-[11px]", children: aiError }),
3638
- aiSuccess && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "p-2.5 rounded-lg bg-emerald-950/60 border border-emerald-800 text-emerald-300 text-[11px]", children: aiSuccess })
3731
+ aiError && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "p-2.5 rounded-lg bg-rose-950/60 border border-rose-800 text-rose-300 text-[11px]", children: aiError }),
3732
+ aiSuccess && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "p-2.5 rounded-lg bg-emerald-950/60 border border-emerald-800 text-emerald-300 text-[11px]", children: aiSuccess })
3639
3733
  ] })
3640
3734
  ] })
3641
3735
  ] })
@@ -3647,6 +3741,7 @@ var ImageEditor = ({
3647
3741
  0 && (module.exports = {
3648
3742
  AdjustmentLayersPanel,
3649
3743
  BrushOptionsBar,
3744
+ ColorProfilePanel,
3650
3745
  ControlSlider,
3651
3746
  CurvesEditor,
3652
3747
  FreeTransformOptionsBar,