muse-image-editor 1.0.0 → 1.0.1
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.
- package/dist/index.js +233 -231
- package/dist/types.d.ts +2 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsxs as c, jsx as r, Fragment as ce } from "react/jsx-runtime";
|
|
2
2
|
import ge, { useState as U, useRef as B, useCallback as C, useEffect as V } from "react";
|
|
3
|
-
import { Paintbrush as xe, Eraser as pe, Trash2 as fe, Undo2 as be, Redo2 as ve, X as we, ZoomOut as ze, ZoomIn as ye, Loader2 as
|
|
3
|
+
import { Paintbrush as xe, Eraser as pe, Trash2 as fe, Undo2 as be, Redo2 as ve, X as we, ZoomOut as ze, ZoomIn as ye, Loader2 as he, ChevronRight as ke, ChevronDown as Ce, Sparkles as Ne, Check as me } from "lucide-react";
|
|
4
4
|
function Ie(s, u) {
|
|
5
5
|
const y = Math.max(4, s * u), x = y / 2, N = y + 2, l = N / 2, g = `<svg xmlns='http://www.w3.org/2000/svg' width='${N}' height='${N}'><circle cx='${l}' cy='${l}' r='${x}' fill='none' stroke='white' stroke-width='1.5'/><circle cx='${l}' cy='${l}' r='${x}' fill='none' stroke='black' stroke-width='0.75'/></svg>`;
|
|
6
6
|
return `url("data:image/svg+xml,${encodeURIComponent(g)}") ${N / 2} ${N / 2}, crosshair`;
|
|
@@ -21,183 +21,183 @@ function de(s, u, y, x, N) {
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
function Me(s = {}) {
|
|
24
|
-
const { enableShortcuts: u = !0, isActive: y = !0 } = s, [x, N] = U("brush"), [l, g] = U(24), [
|
|
25
|
-
const t =
|
|
24
|
+
const { enableShortcuts: u = !0, isActive: y = !0 } = s, [x, N] = U("brush"), [l, g] = U(24), [v, I] = U(1), [d, k] = U({ x: 0, y: 0 }), w = B(null), i = B(null), R = B(null), T = B(!1), M = B(null), Z = B(!1), O = B({ x: 0, y: 0 }), E = B({ x: 0, y: 0 }), [z, W] = U([]), [$, A] = U([]), S = B(null), [P, b] = U({ width: 0, height: 0 }), H = C((n) => {
|
|
25
|
+
const t = R.current;
|
|
26
26
|
if (!t) return { x: 0, y: 0 };
|
|
27
|
-
const
|
|
27
|
+
const a = t.getBoundingClientRect(), o = t.width / a.width, m = t.height / a.height;
|
|
28
28
|
return {
|
|
29
|
-
x: (n.clientX -
|
|
30
|
-
y: (n.clientY -
|
|
29
|
+
x: (n.clientX - a.left) * o,
|
|
30
|
+
y: (n.clientY - a.top) * m
|
|
31
31
|
};
|
|
32
|
-
}, []),
|
|
33
|
-
const t =
|
|
32
|
+
}, []), K = C((n) => {
|
|
33
|
+
const t = R.current;
|
|
34
34
|
if (!t) return;
|
|
35
|
-
const
|
|
36
|
-
|
|
35
|
+
const a = t.getContext("2d");
|
|
36
|
+
a && de(a, n, t.width, t.height, 0.5);
|
|
37
37
|
}, []), ee = C((n) => {
|
|
38
38
|
if (n.button === 1) {
|
|
39
|
-
n.preventDefault(), Z.current = !0,
|
|
39
|
+
n.preventDefault(), Z.current = !0, O.current = { x: n.clientX, y: n.clientY }, E.current = { ...d }, n.target.setPointerCapture(n.pointerId);
|
|
40
40
|
return;
|
|
41
41
|
}
|
|
42
42
|
if (n.button !== 0) return;
|
|
43
43
|
n.preventDefault(), n.target.setPointerCapture(n.pointerId), T.current = !0;
|
|
44
|
-
const t =
|
|
45
|
-
M.current = t,
|
|
44
|
+
const t = H(n);
|
|
45
|
+
M.current = t, S.current = {
|
|
46
46
|
points: [t],
|
|
47
47
|
size: l,
|
|
48
48
|
tool: x
|
|
49
49
|
};
|
|
50
|
-
const
|
|
51
|
-
if (!
|
|
52
|
-
const o =
|
|
50
|
+
const a = R.current;
|
|
51
|
+
if (!a) return;
|
|
52
|
+
const o = a.getContext("2d");
|
|
53
53
|
o && (o.save(), x === "eraser" ? (o.globalCompositeOperation = "destination-out", o.globalAlpha = 1) : (o.globalCompositeOperation = "source-over", o.globalAlpha = 0.5), o.fillStyle = "white", o.beginPath(), o.arc(t.x, t.y, l / 2, 0, Math.PI * 2), o.fill(), o.restore());
|
|
54
|
-
}, [x, l,
|
|
54
|
+
}, [x, l, H, d]), te = C((n) => {
|
|
55
55
|
if (Z.current) {
|
|
56
|
-
const
|
|
57
|
-
k({ x: E.current.x +
|
|
56
|
+
const m = n.clientX - O.current.x, p = n.clientY - O.current.y;
|
|
57
|
+
k({ x: E.current.x + m, y: E.current.y + p });
|
|
58
58
|
return;
|
|
59
59
|
}
|
|
60
|
-
if (!T.current || !
|
|
61
|
-
const t =
|
|
62
|
-
|
|
63
|
-
const
|
|
64
|
-
if (!
|
|
65
|
-
const o =
|
|
60
|
+
if (!T.current || !S.current) return;
|
|
61
|
+
const t = H(n);
|
|
62
|
+
S.current.points.push(t);
|
|
63
|
+
const a = R.current;
|
|
64
|
+
if (!a) return;
|
|
65
|
+
const o = a.getContext("2d");
|
|
66
66
|
!o || !M.current || (o.save(), x === "eraser" ? (o.globalCompositeOperation = "destination-out", o.globalAlpha = 1) : (o.globalCompositeOperation = "source-over", o.globalAlpha = 0.5), o.strokeStyle = "white", o.lineWidth = l, o.lineCap = "round", o.lineJoin = "round", o.beginPath(), o.moveTo(M.current.x, M.current.y), o.lineTo(t.x, t.y), o.stroke(), o.restore(), M.current = t);
|
|
67
|
-
}, [x, l,
|
|
67
|
+
}, [x, l, H]), ne = C((n) => {
|
|
68
68
|
if (Z.current) {
|
|
69
69
|
Z.current = !1;
|
|
70
70
|
return;
|
|
71
71
|
}
|
|
72
|
-
if (T.current && (T.current = !1, M.current = null,
|
|
73
|
-
const t =
|
|
74
|
-
|
|
75
|
-
const o = [...
|
|
76
|
-
return
|
|
72
|
+
if (T.current && (T.current = !1, M.current = null, S.current)) {
|
|
73
|
+
const t = S.current;
|
|
74
|
+
S.current = null, W((a) => {
|
|
75
|
+
const o = [...a, t];
|
|
76
|
+
return K(o), o;
|
|
77
77
|
}), A([]);
|
|
78
78
|
}
|
|
79
|
-
}, [
|
|
80
|
-
|
|
79
|
+
}, [K]), X = C(() => {
|
|
80
|
+
W((n) => {
|
|
81
81
|
if (n.length === 0) return n;
|
|
82
82
|
const t = n[n.length - 1];
|
|
83
83
|
A((o) => [t, ...o]);
|
|
84
|
-
const
|
|
85
|
-
return
|
|
84
|
+
const a = n.slice(0, -1);
|
|
85
|
+
return K(a), a;
|
|
86
86
|
});
|
|
87
|
-
}, [
|
|
87
|
+
}, [K]), q = C(() => {
|
|
88
88
|
A((n) => {
|
|
89
89
|
if (n.length === 0) return n;
|
|
90
|
-
const [t, ...
|
|
91
|
-
return
|
|
92
|
-
const
|
|
93
|
-
return
|
|
94
|
-
}),
|
|
90
|
+
const [t, ...a] = n;
|
|
91
|
+
return W((o) => {
|
|
92
|
+
const m = [...o, t];
|
|
93
|
+
return K(m), m;
|
|
94
|
+
}), a;
|
|
95
95
|
});
|
|
96
|
-
}, [
|
|
97
|
-
const n =
|
|
96
|
+
}, [K]), re = C(() => {
|
|
97
|
+
const n = R.current;
|
|
98
98
|
if (!n) return;
|
|
99
99
|
const t = n.getContext("2d");
|
|
100
|
-
t && t.clearRect(0, 0, n.width, n.height),
|
|
101
|
-
}, []),
|
|
100
|
+
t && t.clearRect(0, 0, n.width, n.height), W([]), A([]);
|
|
101
|
+
}, []), ie = C(() => I((n) => Math.min(5, n + 0.25)), []), ae = C(() => I((n) => Math.max(0.1, n - 0.25)), []), se = C((n) => {
|
|
102
102
|
n.preventDefault();
|
|
103
103
|
const t = n.deltaY > 0 ? -0.1 : 0.1;
|
|
104
|
-
I((
|
|
104
|
+
I((a) => Math.min(5, Math.max(0.1, a + t)));
|
|
105
105
|
}, []);
|
|
106
106
|
V(() => {
|
|
107
107
|
if (!u || !y) return;
|
|
108
108
|
const n = (t) => {
|
|
109
|
-
t.key === "[" ? (t.preventDefault(), g((
|
|
109
|
+
t.key === "[" ? (t.preventDefault(), g((a) => Math.max(4, a - 4))) : t.key === "]" ? (t.preventDefault(), g((a) => Math.min(100, a + 4))) : t.key === "z" && (t.ctrlKey || t.metaKey) && t.shiftKey ? (t.preventDefault(), q()) : t.key === "z" && (t.ctrlKey || t.metaKey) && !t.shiftKey && (t.preventDefault(), X());
|
|
110
110
|
};
|
|
111
111
|
return window.addEventListener("keydown", n), () => window.removeEventListener("keydown", n);
|
|
112
112
|
}, [u, y, X, q]);
|
|
113
|
-
const le = C((n, t) => new Promise((
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
const
|
|
119
|
-
if (
|
|
120
|
-
|
|
121
|
-
const L =
|
|
122
|
-
L && (L.clearRect(0, 0,
|
|
113
|
+
const le = C((n, t) => new Promise((a, o) => {
|
|
114
|
+
const m = new Image();
|
|
115
|
+
m.crossOrigin = "anonymous", m.onload = () => {
|
|
116
|
+
const p = m.naturalWidth, D = m.naturalHeight;
|
|
117
|
+
b({ width: p, height: D });
|
|
118
|
+
const j = i.current;
|
|
119
|
+
if (j) {
|
|
120
|
+
j.width = p, j.height = D;
|
|
121
|
+
const L = j.getContext("2d");
|
|
122
|
+
L && (L.clearRect(0, 0, p, D), L.drawImage(m, 0, 0));
|
|
123
123
|
}
|
|
124
|
-
const Y =
|
|
124
|
+
const Y = R.current;
|
|
125
125
|
if (Y) {
|
|
126
|
-
Y.width =
|
|
126
|
+
Y.width = p, Y.height = D;
|
|
127
127
|
const L = Y.getContext("2d");
|
|
128
|
-
L && L.clearRect(0, 0,
|
|
128
|
+
L && L.clearRect(0, 0, p, D);
|
|
129
129
|
}
|
|
130
|
-
if (
|
|
130
|
+
if (W([]), A([]), !t) {
|
|
131
131
|
k({ x: 0, y: 0 });
|
|
132
132
|
const L = w.current;
|
|
133
|
-
if (L &&
|
|
134
|
-
const
|
|
133
|
+
if (L && p > 0 && D > 0) {
|
|
134
|
+
const F = L.getBoundingClientRect(), Q = 40, J = F.width - Q, G = F.height - Q;
|
|
135
135
|
if (J > 0 && G > 0) {
|
|
136
|
-
const _ = Math.min(J /
|
|
136
|
+
const _ = Math.min(J / p, G / D, 1);
|
|
137
137
|
I(_);
|
|
138
138
|
} else
|
|
139
139
|
I(1);
|
|
140
140
|
} else
|
|
141
141
|
I(1);
|
|
142
142
|
}
|
|
143
|
-
|
|
144
|
-
},
|
|
143
|
+
a();
|
|
144
|
+
}, m.onerror = () => o(new Error("Failed to load image")), m.src = n;
|
|
145
145
|
}), []), oe = C(() => {
|
|
146
|
-
const n =
|
|
146
|
+
const n = i.current;
|
|
147
147
|
if (!n) return null;
|
|
148
|
-
const { width: t, height:
|
|
149
|
-
if (t === 0 ||
|
|
148
|
+
const { width: t, height: a } = P;
|
|
149
|
+
if (t === 0 || a === 0) return null;
|
|
150
150
|
const o = document.createElement("canvas");
|
|
151
|
-
o.width = t, o.height =
|
|
152
|
-
const
|
|
153
|
-
if (!
|
|
154
|
-
if (
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
const
|
|
158
|
-
|
|
151
|
+
o.width = t, o.height = a;
|
|
152
|
+
const m = o.getContext("2d");
|
|
153
|
+
if (!m) return null;
|
|
154
|
+
if (m.drawImage(n, 0, 0), z.length > 0) {
|
|
155
|
+
const p = document.createElement("canvas");
|
|
156
|
+
p.width = t, p.height = a;
|
|
157
|
+
const D = p.getContext("2d");
|
|
158
|
+
D && (de(D, z, t, a, 1), m.drawImage(p, 0, 0));
|
|
159
159
|
}
|
|
160
160
|
return o.toDataURL("image/png");
|
|
161
|
-
}, [z,
|
|
162
|
-
const t =
|
|
161
|
+
}, [z, P]), e = C((n = 20) => {
|
|
162
|
+
const t = i.current;
|
|
163
163
|
if (!t || z.length === 0) return null;
|
|
164
|
-
const { width:
|
|
165
|
-
if (
|
|
166
|
-
let
|
|
164
|
+
const { width: a, height: o } = P;
|
|
165
|
+
if (a === 0 || o === 0) return null;
|
|
166
|
+
let m = 1 / 0, p = 1 / 0, D = -1 / 0, j = -1 / 0;
|
|
167
167
|
for (const J of z) {
|
|
168
168
|
if (J.tool === "eraser") continue;
|
|
169
169
|
const G = J.size / 2;
|
|
170
170
|
for (const _ of J.points)
|
|
171
|
-
|
|
171
|
+
m = Math.min(m, _.x - G), p = Math.min(p, _.y - G), D = Math.max(D, _.x + G), j = Math.max(j, _.y + G);
|
|
172
172
|
}
|
|
173
|
-
if (
|
|
174
|
-
|
|
175
|
-
const Y =
|
|
173
|
+
if (m === 1 / 0) return null;
|
|
174
|
+
m = Math.max(0, Math.floor(m - n)), p = Math.max(0, Math.floor(p - n)), D = Math.min(a, Math.ceil(D + n)), j = Math.min(o, Math.ceil(j + n));
|
|
175
|
+
const Y = D - m, L = j - p;
|
|
176
176
|
if (Y <= 0 || L <= 0) return null;
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
const Q =
|
|
180
|
-
return Q ? (Q.drawImage(t,
|
|
181
|
-
}, [z,
|
|
182
|
-
const { width: n, height: t } =
|
|
177
|
+
const F = document.createElement("canvas");
|
|
178
|
+
F.width = Y, F.height = L;
|
|
179
|
+
const Q = F.getContext("2d");
|
|
180
|
+
return Q ? (Q.drawImage(t, m, p, Y, L, 0, 0, Y, L), F.toDataURL("image/png")) : null;
|
|
181
|
+
}, [z, P]), h = C(() => {
|
|
182
|
+
const { width: n, height: t } = P;
|
|
183
183
|
if (n === 0 || t === 0 || z.length === 0) return null;
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
const o =
|
|
187
|
-
return o ? (de(o, z, n, t, 1),
|
|
188
|
-
}, [z,
|
|
184
|
+
const a = document.createElement("canvas");
|
|
185
|
+
a.width = n, a.height = t;
|
|
186
|
+
const o = a.getContext("2d");
|
|
187
|
+
return o ? (de(o, z, n, t, 1), a) : null;
|
|
188
|
+
}, [z, P]), f = Ie(l, v);
|
|
189
189
|
return {
|
|
190
|
-
imageCanvasRef:
|
|
191
|
-
maskCanvasRef:
|
|
190
|
+
imageCanvasRef: i,
|
|
191
|
+
maskCanvasRef: R,
|
|
192
192
|
containerRef: w,
|
|
193
193
|
activeTool: x,
|
|
194
194
|
setActiveTool: N,
|
|
195
195
|
brushSize: l,
|
|
196
196
|
setBrushSize: g,
|
|
197
|
-
zoom:
|
|
197
|
+
zoom: v,
|
|
198
198
|
pan: d,
|
|
199
|
-
handleZoomIn:
|
|
200
|
-
handleZoomOut:
|
|
199
|
+
handleZoomIn: ie,
|
|
200
|
+
handleZoomOut: ae,
|
|
201
201
|
handleWheel: se,
|
|
202
202
|
strokes: z,
|
|
203
203
|
redoStack: $,
|
|
@@ -207,58 +207,58 @@ function Me(s = {}) {
|
|
|
207
207
|
handlePointerDown: ee,
|
|
208
208
|
handlePointerMove: te,
|
|
209
209
|
handlePointerUp: ne,
|
|
210
|
-
imageDimensions:
|
|
210
|
+
imageDimensions: P,
|
|
211
211
|
loadImage: le,
|
|
212
212
|
exportMaskedImage: oe,
|
|
213
213
|
exportCroppedRegion: e,
|
|
214
|
-
exportMask:
|
|
215
|
-
cursorStyle:
|
|
214
|
+
exportMask: h,
|
|
215
|
+
cursorStyle: f
|
|
216
216
|
};
|
|
217
217
|
}
|
|
218
218
|
const De = (s, u, y) => new Promise((x, N) => {
|
|
219
219
|
const l = new Image(), g = new Image();
|
|
220
|
-
let
|
|
220
|
+
let v = 0;
|
|
221
221
|
const I = () => {
|
|
222
|
-
const k = y.width, w = y.height,
|
|
223
|
-
for (let
|
|
224
|
-
T[
|
|
225
|
-
const M = 8, Z = ue(T, k, w, M),
|
|
222
|
+
const k = y.width, w = y.height, R = y.getContext("2d").getImageData(0, 0, k, w), T = new Float32Array(k * w);
|
|
223
|
+
for (let S = 0; S < k * w; S++)
|
|
224
|
+
T[S] = R.data[S * 4] / 255;
|
|
225
|
+
const M = 8, Z = ue(T, k, w, M), O = ue(Z, k, w, M), E = document.createElement("canvas");
|
|
226
226
|
E.width = k, E.height = w;
|
|
227
227
|
const z = E.getContext("2d");
|
|
228
228
|
z.drawImage(l, 0, 0, k, w);
|
|
229
|
-
const
|
|
229
|
+
const W = z.getImageData(0, 0, k, w);
|
|
230
230
|
z.clearRect(0, 0, k, w), z.drawImage(g, 0, 0, k, w);
|
|
231
231
|
const $ = z.getImageData(0, 0, k, w), A = z.createImageData(k, w);
|
|
232
|
-
for (let
|
|
233
|
-
const
|
|
234
|
-
A.data[
|
|
232
|
+
for (let S = 0; S < k * w; S++) {
|
|
233
|
+
const P = O[S], b = S * 4;
|
|
234
|
+
A.data[b] = Math.round(W.data[b] * (1 - P) + $.data[b] * P), A.data[b + 1] = Math.round(W.data[b + 1] * (1 - P) + $.data[b + 1] * P), A.data[b + 2] = Math.round(W.data[b + 2] * (1 - P) + $.data[b + 2] * P), A.data[b + 3] = 255;
|
|
235
235
|
}
|
|
236
236
|
z.putImageData(A, 0, 0), x(E.toDataURL("image/png"));
|
|
237
237
|
}, d = () => {
|
|
238
|
-
++
|
|
238
|
+
++v === 2 && I();
|
|
239
239
|
};
|
|
240
240
|
l.onload = d, l.onerror = N, l.src = s, g.onload = d, g.onerror = N, g.src = u;
|
|
241
241
|
}), ue = (s, u, y, x) => {
|
|
242
242
|
const N = new Float32Array(u * y), l = x * 2 + 1;
|
|
243
|
-
for (let
|
|
243
|
+
for (let v = 0; v < y; v++) {
|
|
244
244
|
let I = 0;
|
|
245
245
|
for (let d = -x; d <= x; d++)
|
|
246
|
-
I += s[
|
|
246
|
+
I += s[v * u + Math.max(0, Math.min(u - 1, d))];
|
|
247
247
|
for (let d = 0; d < u; d++) {
|
|
248
|
-
N[
|
|
248
|
+
N[v * u + d] = I / l;
|
|
249
249
|
const k = Math.min(u - 1, d + x + 1), w = Math.max(0, d - x);
|
|
250
|
-
I += s[
|
|
250
|
+
I += s[v * u + k] - s[v * u + w];
|
|
251
251
|
}
|
|
252
252
|
}
|
|
253
253
|
const g = new Float32Array(u * y);
|
|
254
|
-
for (let
|
|
254
|
+
for (let v = 0; v < u; v++) {
|
|
255
255
|
let I = 0;
|
|
256
256
|
for (let d = -x; d <= x; d++)
|
|
257
|
-
I += N[Math.max(0, Math.min(y - 1, d)) * u +
|
|
257
|
+
I += N[Math.max(0, Math.min(y - 1, d)) * u + v];
|
|
258
258
|
for (let d = 0; d < y; d++) {
|
|
259
|
-
g[d * u +
|
|
259
|
+
g[d * u + v] = I / l;
|
|
260
260
|
const k = Math.min(y - 1, d + x + 1), w = Math.max(0, d - x);
|
|
261
|
-
I += N[k * u +
|
|
261
|
+
I += N[k * u + v] - N[w * u + v];
|
|
262
262
|
}
|
|
263
263
|
}
|
|
264
264
|
return g;
|
|
@@ -271,13 +271,13 @@ function Ue({
|
|
|
271
271
|
imageUrl: N,
|
|
272
272
|
onGenerate: l,
|
|
273
273
|
referenceImages: g,
|
|
274
|
-
defaultReferenceIds:
|
|
274
|
+
defaultReferenceIds: v,
|
|
275
275
|
presets: I,
|
|
276
276
|
initialHistory: d,
|
|
277
277
|
imageResolution: k,
|
|
278
278
|
title: w = "Image Editor"
|
|
279
279
|
}) {
|
|
280
|
-
const
|
|
280
|
+
const i = Me({ isActive: s }), [R, T] = U([]), [M, Z] = U(0), [O, E] = U(!0), [z, W] = U(!1), [$, A] = U([]), [S, P] = U(/* @__PURE__ */ new Set()), [b, H] = U(""), [K, ee] = U(null), [te, ne] = U(!1), X = B(!1);
|
|
281
281
|
V(() => {
|
|
282
282
|
if (!s) {
|
|
283
283
|
X.current = !1;
|
|
@@ -286,37 +286,37 @@ function Ue({
|
|
|
286
286
|
if (d && d.length > 0 && !X.current) {
|
|
287
287
|
X.current = !0, T(d);
|
|
288
288
|
const e = d[d.length - 1];
|
|
289
|
-
Z(e.index), E(!0),
|
|
289
|
+
Z(e.index), E(!0), i.loadImage(e.imageDataUrl).then(() => E(!1)).catch(() => E(!1));
|
|
290
290
|
return;
|
|
291
291
|
}
|
|
292
|
-
X.current || (X.current = !0, E(!0),
|
|
293
|
-
const e =
|
|
292
|
+
X.current || (X.current = !0, E(!0), i.loadImage(N).then(() => {
|
|
293
|
+
const e = i.imageCanvasRef.current;
|
|
294
294
|
if (e) {
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
const
|
|
298
|
-
|
|
295
|
+
const h = document.createElement("canvas");
|
|
296
|
+
h.width = e.width, h.height = e.height;
|
|
297
|
+
const f = h.getContext("2d");
|
|
298
|
+
f && f.drawImage(e, 0, 0), T([{
|
|
299
299
|
index: 0,
|
|
300
300
|
label: "Original",
|
|
301
|
-
imageDataUrl:
|
|
301
|
+
imageDataUrl: h.toDataURL("image/png"),
|
|
302
302
|
prompt: ""
|
|
303
303
|
}]), Z(0);
|
|
304
304
|
}
|
|
305
305
|
E(!1);
|
|
306
306
|
}).catch(() => E(!1)));
|
|
307
307
|
}, [s, N, d]), V(() => {
|
|
308
|
-
s &&
|
|
309
|
-
}, [s,
|
|
308
|
+
s && v && v.length > 0 && A(v);
|
|
309
|
+
}, [s, v]);
|
|
310
310
|
const q = C((e) => {
|
|
311
|
-
|
|
312
|
-
const
|
|
313
|
-
return
|
|
311
|
+
P((h) => {
|
|
312
|
+
const f = new Set(h);
|
|
313
|
+
return f.has(e) ? f.delete(e) : f.add(e), f;
|
|
314
314
|
});
|
|
315
315
|
}, []);
|
|
316
316
|
V(() => {
|
|
317
317
|
if (!s) return;
|
|
318
|
-
const e = (
|
|
319
|
-
|
|
318
|
+
const e = (h) => {
|
|
319
|
+
h.key === "Escape" && u();
|
|
320
320
|
};
|
|
321
321
|
return window.addEventListener("keydown", e), () => window.removeEventListener("keydown", e);
|
|
322
322
|
}, [s, u]), V(() => {
|
|
@@ -326,66 +326,68 @@ function Ue({
|
|
|
326
326
|
};
|
|
327
327
|
}, [s]);
|
|
328
328
|
const re = C((e) => {
|
|
329
|
-
A((
|
|
330
|
-
}, []),
|
|
329
|
+
A((h) => h.includes(e) ? h.filter((f) => f !== e) : [...h, e]);
|
|
330
|
+
}, []), ie = C(
|
|
331
331
|
(e) => {
|
|
332
|
-
Z(e.index),
|
|
332
|
+
Z(e.index), i.loadImage(e.imageDataUrl, !0), H(e.prompt);
|
|
333
333
|
},
|
|
334
|
-
[
|
|
335
|
-
),
|
|
336
|
-
if (!l || !
|
|
337
|
-
const e =
|
|
334
|
+
[i.loadImage]
|
|
335
|
+
), ae = C(async () => {
|
|
336
|
+
if (!l || !b.trim()) return;
|
|
337
|
+
const e = R[M];
|
|
338
338
|
if (!e) return;
|
|
339
|
-
const
|
|
339
|
+
const h = i.strokes.length > 0 ? i.exportMaskedImage() : void 0;
|
|
340
340
|
ne(!0);
|
|
341
341
|
try {
|
|
342
|
-
const
|
|
342
|
+
const { width: f, height: n } = i.imageDimensions, t = await l({
|
|
343
343
|
sourceImageDataUrl: e.imageDataUrl,
|
|
344
|
-
prompt:
|
|
345
|
-
maskedImageDataUrl:
|
|
346
|
-
selectedReferenceIds: $.length > 0 ? [...$] : void 0
|
|
344
|
+
prompt: b.trim(),
|
|
345
|
+
maskedImageDataUrl: h || void 0,
|
|
346
|
+
selectedReferenceIds: $.length > 0 ? [...$] : void 0,
|
|
347
|
+
sourceWidth: f,
|
|
348
|
+
sourceHeight: n
|
|
347
349
|
});
|
|
348
|
-
let
|
|
349
|
-
if (z &&
|
|
350
|
-
const
|
|
351
|
-
|
|
350
|
+
let a = t;
|
|
351
|
+
if (z && h) {
|
|
352
|
+
const D = i.exportMask();
|
|
353
|
+
D && (a = await De(e.imageDataUrl, t, D));
|
|
352
354
|
}
|
|
353
|
-
const
|
|
354
|
-
index:
|
|
355
|
-
label:
|
|
356
|
-
imageDataUrl:
|
|
357
|
-
prompt:
|
|
358
|
-
maskDataUrl:
|
|
355
|
+
const o = R.slice(0, M + 1), m = o.length, p = {
|
|
356
|
+
index: m,
|
|
357
|
+
label: b.trim().slice(0, 40),
|
|
358
|
+
imageDataUrl: a,
|
|
359
|
+
prompt: b.trim(),
|
|
360
|
+
maskDataUrl: h || void 0
|
|
359
361
|
};
|
|
360
|
-
T([...
|
|
361
|
-
} catch (
|
|
362
|
-
console.error("[ImageEditor] Edit failed:",
|
|
362
|
+
T([...o, p]), Z(m), i.loadImage(a, !0), x && x(p);
|
|
363
|
+
} catch (f) {
|
|
364
|
+
console.error("[ImageEditor] Edit failed:", f), alert(`Edit failed: ${f.message || f}`);
|
|
363
365
|
} finally {
|
|
364
366
|
ne(!1);
|
|
365
367
|
}
|
|
366
|
-
}, [
|
|
367
|
-
const e =
|
|
368
|
+
}, [b, R, M, i, $, l, z, x]), se = C(() => {
|
|
369
|
+
const e = R[M];
|
|
368
370
|
!e || M === 0 || y(e.imageDataUrl);
|
|
369
|
-
}, [
|
|
370
|
-
|
|
371
|
+
}, [R, M, y]), le = C((e) => {
|
|
372
|
+
H(e.prompt), ee(e.id);
|
|
371
373
|
}, []);
|
|
372
374
|
if (!s) return null;
|
|
373
375
|
const oe = ge.useMemo(() => {
|
|
374
376
|
if (!g || g.length === 0) return [];
|
|
375
377
|
const e = /* @__PURE__ */ new Map();
|
|
376
|
-
for (const
|
|
377
|
-
const
|
|
378
|
-
e.has(
|
|
378
|
+
for (const h of g) {
|
|
379
|
+
const f = h.category ?? "general";
|
|
380
|
+
e.has(f) || e.set(f, []), e.get(f).push(h);
|
|
379
381
|
}
|
|
380
|
-
return Array.from(e.entries()).sort(([
|
|
382
|
+
return Array.from(e.entries()).sort(([h], [f]) => h.localeCompare(f));
|
|
381
383
|
}, [g]);
|
|
382
384
|
return /* @__PURE__ */ c("div", { className: "fixed inset-0 z-50 bg-black/90 flex flex-col", children: [
|
|
383
385
|
/* @__PURE__ */ c("div", { className: "flex items-center gap-3 px-4 py-2.5 bg-zinc-900 border-b border-zinc-800", children: [
|
|
384
386
|
/* @__PURE__ */ c(
|
|
385
387
|
"button",
|
|
386
388
|
{
|
|
387
|
-
onClick: () =>
|
|
388
|
-
className: `flex items-center gap-1.5 px-3 py-1.5 rounded text-sm font-medium transition-colors ${
|
|
389
|
+
onClick: () => i.setActiveTool("brush"),
|
|
390
|
+
className: `flex items-center gap-1.5 px-3 py-1.5 rounded text-sm font-medium transition-colors ${i.activeTool === "brush" ? "bg-purple-600 text-white" : "bg-zinc-800 text-zinc-400 hover:text-zinc-200"}`,
|
|
389
391
|
title: "Brush (paint mask)",
|
|
390
392
|
children: [
|
|
391
393
|
/* @__PURE__ */ r(xe, { size: 16 }),
|
|
@@ -396,8 +398,8 @@ function Ue({
|
|
|
396
398
|
/* @__PURE__ */ c(
|
|
397
399
|
"button",
|
|
398
400
|
{
|
|
399
|
-
onClick: () =>
|
|
400
|
-
className: `flex items-center gap-1.5 px-3 py-1.5 rounded text-sm font-medium transition-colors ${
|
|
401
|
+
onClick: () => i.setActiveTool("eraser"),
|
|
402
|
+
className: `flex items-center gap-1.5 px-3 py-1.5 rounded text-sm font-medium transition-colors ${i.activeTool === "eraser" ? "bg-purple-600 text-white" : "bg-zinc-800 text-zinc-400 hover:text-zinc-200"}`,
|
|
401
403
|
title: "Eraser (remove mask)",
|
|
402
404
|
children: [
|
|
403
405
|
/* @__PURE__ */ r(pe, { size: 16 }),
|
|
@@ -414,18 +416,18 @@ function Ue({
|
|
|
414
416
|
type: "range",
|
|
415
417
|
min: 4,
|
|
416
418
|
max: 500,
|
|
417
|
-
value:
|
|
418
|
-
onChange: (e) =>
|
|
419
|
+
value: i.brushSize,
|
|
420
|
+
onChange: (e) => i.setBrushSize(Number(e.target.value)),
|
|
419
421
|
className: "w-28 accent-purple-500"
|
|
420
422
|
}
|
|
421
423
|
),
|
|
422
|
-
/* @__PURE__ */ r("span", { className: "text-xs text-zinc-400 w-8 text-right", children:
|
|
424
|
+
/* @__PURE__ */ r("span", { className: "text-xs text-zinc-400 w-8 text-right", children: i.brushSize })
|
|
423
425
|
] }),
|
|
424
426
|
/* @__PURE__ */ r("div", { className: "w-px h-6 bg-zinc-700" }),
|
|
425
427
|
/* @__PURE__ */ c(
|
|
426
428
|
"button",
|
|
427
429
|
{
|
|
428
|
-
onClick:
|
|
430
|
+
onClick: i.handleClearMask,
|
|
429
431
|
className: "flex items-center gap-1.5 px-3 py-1.5 rounded text-sm text-zinc-400 bg-zinc-800 hover:text-zinc-200 hover:bg-zinc-700 transition-colors",
|
|
430
432
|
title: "Clear mask",
|
|
431
433
|
children: [
|
|
@@ -440,8 +442,8 @@ function Ue({
|
|
|
440
442
|
/* @__PURE__ */ r(
|
|
441
443
|
"button",
|
|
442
444
|
{
|
|
443
|
-
onClick:
|
|
444
|
-
disabled:
|
|
445
|
+
onClick: i.handleUndo,
|
|
446
|
+
disabled: i.strokes.length === 0,
|
|
445
447
|
className: "p-1.5 rounded text-zinc-400 hover:text-zinc-200 disabled:opacity-30 disabled:cursor-not-allowed transition-colors",
|
|
446
448
|
title: "Undo (Ctrl+Z)",
|
|
447
449
|
children: /* @__PURE__ */ r(be, { size: 18 })
|
|
@@ -450,8 +452,8 @@ function Ue({
|
|
|
450
452
|
/* @__PURE__ */ r(
|
|
451
453
|
"button",
|
|
452
454
|
{
|
|
453
|
-
onClick:
|
|
454
|
-
disabled:
|
|
455
|
+
onClick: i.handleRedo,
|
|
456
|
+
disabled: i.redoStack.length === 0,
|
|
455
457
|
className: "p-1.5 rounded text-zinc-400 hover:text-zinc-200 disabled:opacity-30 disabled:cursor-not-allowed transition-colors",
|
|
456
458
|
title: "Redo (Ctrl+Shift+Z)",
|
|
457
459
|
children: /* @__PURE__ */ r(ve, { size: 18 })
|
|
@@ -473,16 +475,16 @@ function Ue({
|
|
|
473
475
|
"div",
|
|
474
476
|
{
|
|
475
477
|
className: "flex-1 flex items-center justify-center bg-zinc-950 overflow-hidden relative",
|
|
476
|
-
onWheel:
|
|
478
|
+
onWheel: i.handleWheel,
|
|
477
479
|
children: [
|
|
478
480
|
/* @__PURE__ */ c(
|
|
479
481
|
"div",
|
|
480
482
|
{
|
|
481
|
-
ref:
|
|
483
|
+
ref: i.containerRef,
|
|
482
484
|
style: {
|
|
483
|
-
transform: `translate(${
|
|
484
|
-
width:
|
|
485
|
-
height:
|
|
485
|
+
transform: `translate(${i.pan.x}px, ${i.pan.y}px) scale(${i.zoom})`,
|
|
486
|
+
width: i.imageDimensions.width > 0 ? i.imageDimensions.width : void 0,
|
|
487
|
+
height: i.imageDimensions.height > 0 ? i.imageDimensions.height : void 0,
|
|
486
488
|
transformOrigin: "center center",
|
|
487
489
|
position: "relative"
|
|
488
490
|
},
|
|
@@ -490,24 +492,24 @@ function Ue({
|
|
|
490
492
|
/* @__PURE__ */ r(
|
|
491
493
|
"canvas",
|
|
492
494
|
{
|
|
493
|
-
ref:
|
|
495
|
+
ref: i.imageCanvasRef,
|
|
494
496
|
style: { position: "absolute", top: 0, left: 0 }
|
|
495
497
|
}
|
|
496
498
|
),
|
|
497
499
|
/* @__PURE__ */ r(
|
|
498
500
|
"canvas",
|
|
499
501
|
{
|
|
500
|
-
ref:
|
|
502
|
+
ref: i.maskCanvasRef,
|
|
501
503
|
style: {
|
|
502
504
|
position: "absolute",
|
|
503
505
|
top: 0,
|
|
504
506
|
left: 0,
|
|
505
|
-
cursor:
|
|
507
|
+
cursor: i.cursorStyle
|
|
506
508
|
},
|
|
507
|
-
onPointerDown:
|
|
508
|
-
onPointerMove:
|
|
509
|
-
onPointerUp:
|
|
510
|
-
onPointerCancel:
|
|
509
|
+
onPointerDown: i.handlePointerDown,
|
|
510
|
+
onPointerMove: i.handlePointerMove,
|
|
511
|
+
onPointerUp: i.handlePointerUp,
|
|
512
|
+
onPointerCancel: i.handlePointerUp,
|
|
511
513
|
onContextMenu: (e) => e.preventDefault()
|
|
512
514
|
}
|
|
513
515
|
)
|
|
@@ -515,19 +517,19 @@ function Ue({
|
|
|
515
517
|
}
|
|
516
518
|
),
|
|
517
519
|
/* @__PURE__ */ c("div", { className: "absolute bottom-4 right-4 flex items-center gap-1 bg-zinc-900/80 rounded-lg px-2 py-1 border border-zinc-800", children: [
|
|
518
|
-
/* @__PURE__ */ r("button", { onClick:
|
|
520
|
+
/* @__PURE__ */ r("button", { onClick: i.handleZoomOut, className: "p-1 text-zinc-400 hover:text-white transition-colors", title: "Zoom out", children: /* @__PURE__ */ r(ze, { size: 16 }) }),
|
|
519
521
|
/* @__PURE__ */ c("span", { className: "text-xs text-zinc-400 w-12 text-center", children: [
|
|
520
|
-
Math.round(
|
|
522
|
+
Math.round(i.zoom * 100),
|
|
521
523
|
"%"
|
|
522
524
|
] }),
|
|
523
|
-
/* @__PURE__ */ r("button", { onClick:
|
|
525
|
+
/* @__PURE__ */ r("button", { onClick: i.handleZoomIn, className: "p-1 text-zinc-400 hover:text-white transition-colors", title: "Zoom in", children: /* @__PURE__ */ r(ye, { size: 16 }) })
|
|
524
526
|
] }),
|
|
525
|
-
|
|
526
|
-
|
|
527
|
+
i.imageDimensions.width > 0 && /* @__PURE__ */ c("div", { className: "absolute bottom-4 left-4 text-xs text-zinc-600", children: [
|
|
528
|
+
i.imageDimensions.width,
|
|
527
529
|
" x ",
|
|
528
|
-
|
|
530
|
+
i.imageDimensions.height
|
|
529
531
|
] }),
|
|
530
|
-
|
|
532
|
+
O && /* @__PURE__ */ r("div", { className: "absolute inset-0 flex items-center justify-center bg-zinc-950", children: /* @__PURE__ */ r(he, { size: 24, className: "text-zinc-500 animate-spin" }) })
|
|
531
533
|
]
|
|
532
534
|
}
|
|
533
535
|
),
|
|
@@ -540,8 +542,8 @@ function Ue({
|
|
|
540
542
|
" selected"
|
|
541
543
|
] })
|
|
542
544
|
] }) }),
|
|
543
|
-
oe.map(([e,
|
|
544
|
-
const
|
|
545
|
+
oe.map(([e, h]) => {
|
|
546
|
+
const f = S.has(e), n = h.filter((t) => $.includes(t.id)).length;
|
|
545
547
|
return /* @__PURE__ */ c("div", { className: "border-t border-zinc-800/50", children: [
|
|
546
548
|
/* @__PURE__ */ c(
|
|
547
549
|
"button",
|
|
@@ -549,9 +551,9 @@ function Ue({
|
|
|
549
551
|
onClick: () => q(e),
|
|
550
552
|
className: "flex items-center gap-1.5 w-full px-3 py-1.5 text-left hover:bg-zinc-800/30 transition-colors",
|
|
551
553
|
children: [
|
|
552
|
-
|
|
554
|
+
f ? /* @__PURE__ */ r(ke, { size: 12, className: "text-zinc-600" }) : /* @__PURE__ */ r(Ce, { size: 12, className: "text-zinc-600" }),
|
|
553
555
|
/* @__PURE__ */ r("span", { className: "text-[11px] font-medium text-zinc-400 capitalize", children: e }),
|
|
554
|
-
/* @__PURE__ */ r("span", { className: "text-[10px] text-zinc-600", children:
|
|
556
|
+
/* @__PURE__ */ r("span", { className: "text-[10px] text-zinc-600", children: h.length }),
|
|
555
557
|
n > 0 && /* @__PURE__ */ c("span", { className: "ml-auto text-[9px] text-blue-400", children: [
|
|
556
558
|
n,
|
|
557
559
|
" sel"
|
|
@@ -559,17 +561,17 @@ function Ue({
|
|
|
559
561
|
]
|
|
560
562
|
}
|
|
561
563
|
),
|
|
562
|
-
!
|
|
563
|
-
const
|
|
564
|
+
!f && /* @__PURE__ */ r("div", { className: "grid grid-cols-4 gap-1.5 px-3 pb-2", children: h.map((t) => {
|
|
565
|
+
const a = t.thumbnailUrl ?? t.url, o = t.name || t.category || "ref", m = $.indexOf(t.id), p = m !== -1;
|
|
564
566
|
return /* @__PURE__ */ c(
|
|
565
567
|
"button",
|
|
566
568
|
{
|
|
567
569
|
onClick: () => re(t.id),
|
|
568
|
-
className: `relative rounded overflow-hidden aspect-square border-2 transition-colors ${
|
|
570
|
+
className: `relative rounded overflow-hidden aspect-square border-2 transition-colors ${p ? "border-blue-500" : "border-transparent hover:border-zinc-600"}`,
|
|
569
571
|
title: t.name || o,
|
|
570
572
|
children: [
|
|
571
|
-
|
|
572
|
-
|
|
573
|
+
a && /* @__PURE__ */ r("img", { src: a, alt: o, className: "w-full h-full object-cover" }),
|
|
574
|
+
p && /* @__PURE__ */ r("span", { className: "absolute top-0.5 right-0.5 w-4 h-4 flex items-center justify-center text-[9px] font-bold bg-blue-600 text-white rounded-full leading-none", children: m + 1 }),
|
|
573
575
|
/* @__PURE__ */ r("div", { className: "absolute bottom-0 left-0 right-0 bg-black/60 text-[8px] text-zinc-300 px-1 py-0.5 text-center truncate", children: o })
|
|
574
576
|
]
|
|
575
577
|
},
|
|
@@ -585,20 +587,20 @@ function Ue({
|
|
|
585
587
|
"button",
|
|
586
588
|
{
|
|
587
589
|
onClick: () => le(e),
|
|
588
|
-
className: `px-2 py-1 rounded text-xs font-medium transition-colors ${
|
|
590
|
+
className: `px-2 py-1 rounded text-xs font-medium transition-colors ${K === e.id ? "bg-indigo-600 text-white" : "bg-zinc-800 text-zinc-400 hover:text-zinc-200 hover:bg-zinc-700"}`,
|
|
589
591
|
children: e.label
|
|
590
592
|
},
|
|
591
593
|
e.id
|
|
592
594
|
)) }),
|
|
593
595
|
/* @__PURE__ */ c("div", { className: "relative", children: [
|
|
594
|
-
/\[(source|mask|image\d+)\]/i.test(
|
|
596
|
+
/\[(source|mask|image\d+)\]/i.test(b) && /* @__PURE__ */ c(
|
|
595
597
|
"div",
|
|
596
598
|
{
|
|
597
599
|
className: "absolute inset-0 px-2.5 py-2 text-sm whitespace-pre-wrap break-words overflow-hidden pointer-events-none rounded",
|
|
598
600
|
style: { lineHeight: "1.5" },
|
|
599
601
|
children: [
|
|
600
|
-
|
|
601
|
-
(e,
|
|
602
|
+
b.split(/(\[(?:source|mask|image\d+)\])/gi).map(
|
|
603
|
+
(e, h) => /^\[(?:source|mask|image\d+)\]$/i.test(e) ? /* @__PURE__ */ r("span", { className: "bg-blue-500/30 text-blue-300 rounded px-0.5 font-semibold", children: e }, h) : /* @__PURE__ */ r("span", { children: e }, h)
|
|
602
604
|
),
|
|
603
605
|
`
|
|
604
606
|
`
|
|
@@ -608,14 +610,14 @@ function Ue({
|
|
|
608
610
|
/* @__PURE__ */ r(
|
|
609
611
|
"textarea",
|
|
610
612
|
{
|
|
611
|
-
value:
|
|
613
|
+
value: b,
|
|
612
614
|
onChange: (e) => {
|
|
613
|
-
|
|
615
|
+
H(e.target.value), ee(null);
|
|
614
616
|
},
|
|
615
617
|
placeholder: "Describe what to edit or change...",
|
|
616
618
|
rows: 3,
|
|
617
|
-
className: `w-full bg-zinc-800 border border-zinc-700 rounded px-2.5 py-2 text-sm placeholder-zinc-600 resize-none focus:outline-none focus:border-indigo-500 ${/\[(source|mask|image\d+)\]/i.test(
|
|
618
|
-
style: { lineHeight: "1.5", background: /\[(source|mask|image\d+)\]/i.test(
|
|
619
|
+
className: `w-full bg-zinc-800 border border-zinc-700 rounded px-2.5 py-2 text-sm placeholder-zinc-600 resize-none focus:outline-none focus:border-indigo-500 ${/\[(source|mask|image\d+)\]/i.test(b) ? "text-transparent caret-zinc-200" : "text-zinc-200"}`,
|
|
620
|
+
style: { lineHeight: "1.5", background: /\[(source|mask|image\d+)\]/i.test(b) ? "rgba(39,39,42,0.95)" : void 0 }
|
|
619
621
|
}
|
|
620
622
|
)
|
|
621
623
|
] }),
|
|
@@ -623,7 +625,7 @@ function Ue({
|
|
|
623
625
|
"Use [source] for the original image",
|
|
624
626
|
$.length > 0 && /* @__PURE__ */ c(ce, { children: [
|
|
625
627
|
", ",
|
|
626
|
-
$.map((e,
|
|
628
|
+
$.map((e, h) => `[image${h + 1}]`).join(", "),
|
|
627
629
|
" for references"
|
|
628
630
|
] })
|
|
629
631
|
] })
|
|
@@ -635,7 +637,7 @@ function Ue({
|
|
|
635
637
|
{
|
|
636
638
|
type: "checkbox",
|
|
637
639
|
checked: z,
|
|
638
|
-
onChange: (e) =>
|
|
640
|
+
onChange: (e) => W(e.target.checked),
|
|
639
641
|
className: "accent-indigo-500"
|
|
640
642
|
}
|
|
641
643
|
),
|
|
@@ -645,11 +647,11 @@ function Ue({
|
|
|
645
647
|
/* @__PURE__ */ r(
|
|
646
648
|
"button",
|
|
647
649
|
{
|
|
648
|
-
onClick:
|
|
649
|
-
disabled: !
|
|
650
|
+
onClick: ae,
|
|
651
|
+
disabled: !b.trim() || te,
|
|
650
652
|
className: "w-full flex items-center justify-center gap-2 px-4 py-2.5 rounded-lg text-sm font-semibold transition-colors bg-indigo-600 text-white hover:bg-indigo-500 disabled:opacity-40 disabled:cursor-not-allowed",
|
|
651
653
|
children: te ? /* @__PURE__ */ c(ce, { children: [
|
|
652
|
-
/* @__PURE__ */ r(
|
|
654
|
+
/* @__PURE__ */ r(he, { size: 16, className: "animate-spin" }),
|
|
653
655
|
"Generating..."
|
|
654
656
|
] }) : /* @__PURE__ */ c(ce, { children: [
|
|
655
657
|
/* @__PURE__ */ r(Ne, { size: 16 }),
|
|
@@ -657,14 +659,14 @@ function Ue({
|
|
|
657
659
|
] })
|
|
658
660
|
}
|
|
659
661
|
),
|
|
660
|
-
/* @__PURE__ */ r("p", { className: "text-[10px] text-zinc-600 mt-1.5 text-center", children:
|
|
662
|
+
/* @__PURE__ */ r("p", { className: "text-[10px] text-zinc-600 mt-1.5 text-center", children: b.trim() ? i.strokes.length === 0 ? "Ready — paint a mask for targeted edits" : "Ready to generate" : "Enter a prompt or pick a preset" })
|
|
661
663
|
] }),
|
|
662
664
|
/* @__PURE__ */ c("div", { className: "p-3 flex-1 min-h-0 overflow-y-auto", children: [
|
|
663
665
|
/* @__PURE__ */ r("h3", { className: "text-xs font-semibold text-zinc-400 uppercase tracking-wider mb-2", children: "Edit History" }),
|
|
664
|
-
/* @__PURE__ */ r("div", { className: "flex flex-col gap-1", children:
|
|
666
|
+
/* @__PURE__ */ r("div", { className: "flex flex-col gap-1", children: R.map((e) => /* @__PURE__ */ c(
|
|
665
667
|
"button",
|
|
666
668
|
{
|
|
667
|
-
onClick: () =>
|
|
669
|
+
onClick: () => ie(e),
|
|
668
670
|
className: `flex items-center gap-2 px-2.5 py-2 rounded text-left transition-colors ${M === e.index ? "bg-indigo-600/20 border border-indigo-500 text-zinc-200" : "bg-zinc-800/50 border border-transparent text-zinc-400 hover:text-zinc-200 hover:bg-zinc-800"}`,
|
|
669
671
|
children: [
|
|
670
672
|
/* @__PURE__ */ r("div", { className: "w-8 h-8 rounded overflow-hidden flex-shrink-0 bg-zinc-700", children: /* @__PURE__ */ r("img", { src: e.imageDataUrl, alt: e.label, className: "w-full h-full object-cover" }) }),
|
|
@@ -675,7 +677,7 @@ function Ue({
|
|
|
675
677
|
e.index
|
|
676
678
|
] })
|
|
677
679
|
] }),
|
|
678
|
-
M === e.index && /* @__PURE__ */ r(
|
|
680
|
+
M === e.index && /* @__PURE__ */ r(me, { size: 14, className: "text-indigo-400 flex-shrink-0" })
|
|
679
681
|
]
|
|
680
682
|
},
|
|
681
683
|
e.index
|
|
@@ -697,7 +699,7 @@ function Ue({
|
|
|
697
699
|
disabled: M === 0,
|
|
698
700
|
className: "flex-1 flex items-center justify-center gap-1.5 px-3 py-2 rounded text-sm font-semibold bg-green-600 text-white hover:bg-green-500 disabled:opacity-40 disabled:cursor-not-allowed transition-colors",
|
|
699
701
|
children: [
|
|
700
|
-
/* @__PURE__ */ r(
|
|
702
|
+
/* @__PURE__ */ r(me, { size: 14 }),
|
|
701
703
|
"Apply"
|
|
702
704
|
]
|
|
703
705
|
}
|
package/dist/types.d.ts
CHANGED