@buoy-gg/image-overlay 7.0.41 → 7.0.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +12 -76
  2. package/lib/commonjs/imageOverlay/components/ImageOverlayModal.js +1 -880
  3. package/lib/commonjs/imageOverlay/components/ImageOverlayStandalone.js +1 -463
  4. package/lib/commonjs/imageOverlay/components/OverlayControls.js +1 -253
  5. package/lib/commonjs/imageOverlay/components/TargetList.js +1 -181
  6. package/lib/commonjs/imageOverlay/types/index.js +1 -1
  7. package/lib/commonjs/imageOverlay/utils/ImageOverlayController.js +1 -426
  8. package/lib/commonjs/imageOverlay/utils/componentMeasurement.js +1 -106
  9. package/lib/commonjs/imageOverlay/utils/devtoolsHook.js +1 -36
  10. package/lib/commonjs/imageOverlay/utils/fiberScanner.js +1 -104
  11. package/lib/commonjs/imageOverlay/utils/imageClipboard.js +1 -22
  12. package/lib/commonjs/imageOverlay/utils/imageClipboard.web.js +1 -44
  13. package/lib/commonjs/index.js +1 -59
  14. package/lib/commonjs/preset.js +1 -42
  15. package/lib/module/imageOverlay/components/ImageOverlayModal.js +1 -875
  16. package/lib/module/imageOverlay/components/ImageOverlayStandalone.js +1 -459
  17. package/lib/module/imageOverlay/components/OverlayControls.js +1 -249
  18. package/lib/module/imageOverlay/components/TargetList.js +1 -177
  19. package/lib/module/imageOverlay/types/index.js +1 -1
  20. package/lib/module/imageOverlay/utils/ImageOverlayController.js +1 -422
  21. package/lib/module/imageOverlay/utils/componentMeasurement.js +1 -102
  22. package/lib/module/imageOverlay/utils/devtoolsHook.js +1 -31
  23. package/lib/module/imageOverlay/utils/fiberScanner.js +1 -100
  24. package/lib/module/imageOverlay/utils/imageClipboard.js +1 -17
  25. package/lib/module/imageOverlay/utils/imageClipboard.web.js +1 -39
  26. package/lib/module/index.js +1 -35
  27. package/lib/module/preset.js +1 -38
  28. package/lib/web/index.mjs +4 -5
  29. package/package.json +2 -2
  30. package/lib/typescript/imageOverlay/components/ImageOverlayModal.d.ts.map +0 -1
  31. package/lib/typescript/imageOverlay/components/ImageOverlayStandalone.d.ts.map +0 -1
  32. package/lib/typescript/imageOverlay/components/OverlayControls.d.ts.map +0 -1
  33. package/lib/typescript/imageOverlay/components/TargetList.d.ts.map +0 -1
  34. package/lib/typescript/imageOverlay/types/index.d.ts.map +0 -1
  35. package/lib/typescript/imageOverlay/utils/ImageOverlayController.d.ts.map +0 -1
  36. package/lib/typescript/imageOverlay/utils/componentMeasurement.d.ts.map +0 -1
  37. package/lib/typescript/imageOverlay/utils/devtoolsHook.d.ts.map +0 -1
  38. package/lib/typescript/imageOverlay/utils/fiberScanner.d.ts.map +0 -1
  39. package/lib/typescript/imageOverlay/utils/imageClipboard.d.ts.map +0 -1
  40. package/lib/typescript/imageOverlay/utils/imageClipboard.web.d.ts.map +0 -1
  41. package/lib/typescript/index.d.ts.map +0 -1
  42. package/lib/typescript/preset.d.ts.map +0 -1
@@ -1,463 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.ImageOverlayStandalone = ImageOverlayStandalone;
7
- var _react = _interopRequireWildcard(require("react"));
8
- var _reactNative = require("react-native");
9
- var _sharedUi = require("@buoy-gg/shared-ui");
10
- var _ImageOverlayController = require("../utils/ImageOverlayController");
11
- var _jsxRuntime = require("react/jsx-runtime");
12
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
13
- /**
14
- * Standalone overlay that renders:
15
- * - Component mode: highlight border + image overlay on a tagged component
16
- * - Free mode: draggable, resizable image anywhere on screen (aspect-ratio locked)
17
- *
18
- * Supports Normal, Difference, and Multiply blend modes.
19
- * Supports image inversion (flip X/Y) and position locking.
20
- * Auto-mounted by FloatingDevTools alongside other standalone overlays.
21
- */
22
-
23
- // ─── Overlay Image (handles flip transforms) ─────────────────────────────────
24
- function OverlayImage({
25
- uri,
26
- style,
27
- invertX,
28
- invertY
29
- }) {
30
- const transform = [];
31
- if (invertX) transform.push({
32
- scaleX: -1
33
- });
34
- if (invertY) transform.push({
35
- scaleY: -1
36
- });
37
- const flipStyle = transform.length > 0 ? {
38
- transform
39
- } : {};
40
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Image, {
41
- testID: "buoy-internal-image-overlay",
42
- source: {
43
- uri
44
- },
45
- style: [style, flipStyle]
46
- // @ts-ignore
47
- ,
48
- pointerEvents: "none"
49
- });
50
- }
51
-
52
- // ─── Free Placement ───────────────────────────────────────────────────────────
53
-
54
- const FREE_MIN_SIZE = 30;
55
- function FreePlacement({
56
- imageUri,
57
- x,
58
- y,
59
- width,
60
- height,
61
- opacity,
62
- aspectRatio,
63
- invertX,
64
- invertY,
65
- locked
66
- }) {
67
- const [isInteracting, setIsInteracting] = (0, _react.useState)(false);
68
- const startPosRef = (0, _react.useRef)({
69
- x: 0,
70
- y: 0
71
- });
72
- const startDimsRef = (0, _react.useRef)({
73
- x: 0,
74
- y: 0,
75
- width: 0,
76
- height: 0
77
- });
78
- const screen = _reactNative.Dimensions.get("window");
79
-
80
- // ── Drag ──
81
- const dragResponder = (0, _react.useMemo)(() => _reactNative.PanResponder.create({
82
- onStartShouldSetPanResponder: () => !locked,
83
- onMoveShouldSetPanResponder: (_, g) => !locked && (Math.abs(g.dx) > 2 || Math.abs(g.dy) > 2),
84
- onPanResponderTerminationRequest: () => false,
85
- onPanResponderGrant: () => {
86
- const s = _ImageOverlayController.ImageOverlayController.getState();
87
- startPosRef.current = {
88
- x: s.freeX,
89
- y: s.freeY
90
- };
91
- setIsInteracting(true);
92
- },
93
- onPanResponderMove: (_, g) => {
94
- const s = _ImageOverlayController.ImageOverlayController.getState();
95
- const newX = Math.max(0, Math.min(startPosRef.current.x + g.dx, screen.width - s.freeWidth));
96
- const newY = Math.max(0, Math.min(startPosRef.current.y + g.dy, screen.height - s.freeHeight));
97
- _ImageOverlayController.ImageOverlayController.setFreePosition(newX, newY);
98
- },
99
- onPanResponderRelease: () => setIsInteracting(false),
100
- onPanResponderTerminate: () => setIsInteracting(false)
101
- }), [screen.width, screen.height, locked]);
102
-
103
- // ── Aspect-ratio-locked corner resize ──
104
- const createResizeHandler = (0, _react.useCallback)(corner => _reactNative.PanResponder.create({
105
- onStartShouldSetPanResponder: () => !locked,
106
- onMoveShouldSetPanResponder: () => !locked,
107
- onPanResponderTerminationRequest: () => false,
108
- onPanResponderGrant: () => {
109
- const s = _ImageOverlayController.ImageOverlayController.getState();
110
- startDimsRef.current = {
111
- x: s.freeX,
112
- y: s.freeY,
113
- width: s.freeWidth,
114
- height: s.freeHeight
115
- };
116
- setIsInteracting(true);
117
- },
118
- onPanResponderMove: (_, g) => {
119
- const {
120
- dx,
121
- dy
122
- } = g;
123
- if (Math.abs(dx) < 0.5 && Math.abs(dy) < 0.5) return;
124
- const start = startDimsRef.current;
125
- const ratio = aspectRatio > 0 ? aspectRatio : start.width / start.height;
126
- const absDx = Math.abs(dx);
127
- const absDy = Math.abs(dy);
128
- const useDx = absDx >= absDy;
129
- let newWidth;
130
- let newHeight;
131
- let newX = start.x;
132
- let newY = start.y;
133
- switch (corner) {
134
- case "bottomRight":
135
- {
136
- newWidth = useDx ? start.width + dx : (start.height + dy) * ratio;
137
- newWidth = Math.max(FREE_MIN_SIZE, Math.min(newWidth, screen.width - start.x));
138
- newHeight = newWidth / ratio;
139
- break;
140
- }
141
- case "bottomLeft":
142
- {
143
- newWidth = useDx ? start.width - dx : (start.height + dy) * ratio;
144
- newWidth = Math.max(FREE_MIN_SIZE, newWidth);
145
- newHeight = newWidth / ratio;
146
- newX = start.x + start.width - newWidth;
147
- newX = Math.max(0, newX);
148
- newWidth = Math.min(newWidth, start.x + start.width);
149
- newHeight = newWidth / ratio;
150
- break;
151
- }
152
- case "topRight":
153
- {
154
- newWidth = useDx ? start.width + dx : (start.height - dy) * ratio;
155
- newWidth = Math.max(FREE_MIN_SIZE, Math.min(newWidth, screen.width - start.x));
156
- newHeight = newWidth / ratio;
157
- newY = start.y + start.height - newHeight;
158
- newY = Math.max(0, newY);
159
- newHeight = Math.min(newHeight, start.y + start.height);
160
- newWidth = newHeight * ratio;
161
- break;
162
- }
163
- case "topLeft":
164
- {
165
- newWidth = useDx ? start.width - dx : (start.height - dy) * ratio;
166
- newWidth = Math.max(FREE_MIN_SIZE, newWidth);
167
- newHeight = newWidth / ratio;
168
- newX = start.x + start.width - newWidth;
169
- newY = start.y + start.height - newHeight;
170
- newX = Math.max(0, newX);
171
- newY = Math.max(0, newY);
172
- newWidth = Math.min(newWidth, start.x + start.width);
173
- newHeight = newWidth / ratio;
174
- newY = start.y + start.height - newHeight;
175
- break;
176
- }
177
- }
178
- newWidth = Math.max(FREE_MIN_SIZE, Math.round(newWidth));
179
- newHeight = Math.max(FREE_MIN_SIZE, Math.round(newHeight));
180
- _ImageOverlayController.ImageOverlayController.setFreeDimensions(newWidth, newHeight, Math.round(newX), Math.round(newY));
181
- },
182
- onPanResponderRelease: () => setIsInteracting(false),
183
- onPanResponderTerminate: () => setIsInteracting(false)
184
- }), [screen.width, screen.height, aspectRatio, locked]);
185
- const resizeHandlers = (0, _react.useMemo)(() => ({
186
- topLeft: createResizeHandler("topLeft"),
187
- topRight: createResizeHandler("topRight"),
188
- bottomLeft: createResizeHandler("bottomLeft"),
189
- bottomRight: createResizeHandler("bottomRight")
190
- }), [createResizeHandler]);
191
- const imageStyle = {
192
- ..._sharedUi.absoluteFill,
193
- opacity
194
- };
195
- return (
196
- /*#__PURE__*/
197
- // Locked means "let me use the app under it": the box must not swallow
198
- // touches, or a locked full-screen mockup blocks every tap on the screen.
199
- (0, _jsxRuntime.jsxs)(_reactNative.View, {
200
- style: {
201
- position: "absolute",
202
- left: x,
203
- top: y,
204
- width,
205
- height
206
- },
207
- pointerEvents: locked ? "none" : "auto",
208
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
209
- style: _reactNative.StyleSheet.absoluteFill,
210
- ...(locked ? {} : dragResponder.panHandlers),
211
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(OverlayImage, {
212
- uri: imageUri,
213
- style: imageStyle,
214
- invertX: invertX,
215
- invertY: invertY
216
- })
217
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
218
- pointerEvents: "none",
219
- style: [styles.freeBorder, isInteracting && styles.freeBorderActive, locked && styles.freeBorderLocked]
220
- }), !locked && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
221
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
222
- ...resizeHandlers.topLeft.panHandlers,
223
- style: [styles.cornerWrapper, {
224
- top: -20,
225
- left: -20
226
- }],
227
- hitSlop: {
228
- top: 10,
229
- left: 10,
230
- right: 10,
231
- bottom: 10
232
- },
233
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
234
- style: [styles.cornerHandle, isInteracting && styles.cornerHandleActive]
235
- })
236
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
237
- ...resizeHandlers.topRight.panHandlers,
238
- style: [styles.cornerWrapper, {
239
- top: -20,
240
- right: -20
241
- }],
242
- hitSlop: {
243
- top: 10,
244
- left: 10,
245
- right: 10,
246
- bottom: 10
247
- },
248
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
249
- style: [styles.cornerHandle, isInteracting && styles.cornerHandleActive]
250
- })
251
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
252
- ...resizeHandlers.bottomLeft.panHandlers,
253
- style: [styles.cornerWrapper, {
254
- bottom: -20,
255
- left: -20
256
- }],
257
- hitSlop: {
258
- top: 10,
259
- left: 10,
260
- right: 10,
261
- bottom: 10
262
- },
263
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
264
- style: [styles.cornerHandle, isInteracting && styles.cornerHandleActive]
265
- })
266
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
267
- ...resizeHandlers.bottomRight.panHandlers,
268
- style: [styles.cornerWrapper, {
269
- bottom: -20,
270
- right: -20
271
- }],
272
- hitSlop: {
273
- top: 10,
274
- left: 10,
275
- right: 10,
276
- bottom: 10
277
- },
278
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
279
- style: [styles.cornerHandle, isInteracting && styles.cornerHandleActive]
280
- })
281
- })]
282
- })]
283
- })
284
- );
285
- }
286
-
287
- // ─── Main Standalone Overlay ──────────────────────────────────────────────────
288
-
289
- function ImageOverlayStandalone() {
290
- const [state, setState] = (0, _react.useState)(() => _ImageOverlayController.ImageOverlayController.getState());
291
- (0, _react.useEffect)(() => {
292
- return _ImageOverlayController.ImageOverlayController.subscribe(setState);
293
- }, []);
294
- const {
295
- mode,
296
- enabled,
297
- imageUri,
298
- imageWidth,
299
- imageHeight,
300
- targetRect,
301
- targetLabel,
302
- showOutline,
303
- opacity,
304
- scale,
305
- offsetX,
306
- offsetY,
307
- invertX,
308
- invertY,
309
- locked,
310
- freeX,
311
- freeY,
312
- freeWidth,
313
- freeHeight
314
- } = state;
315
- const aspectRatio = imageWidth && imageHeight && imageHeight > 0 ? imageWidth / imageHeight : 0;
316
-
317
- // ─── Free Placement Mode ───
318
- if (mode === "free" && enabled && imageUri) {
319
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
320
- style: styles.overlay,
321
- pointerEvents: "box-none",
322
- nativeID: "image-overlay-standalone",
323
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(FreePlacement, {
324
- imageUri: imageUri,
325
- x: freeX,
326
- y: freeY,
327
- width: freeWidth,
328
- height: freeHeight,
329
- opacity: opacity,
330
- aspectRatio: aspectRatio,
331
- invertX: invertX,
332
- invertY: invertY,
333
- locked: locked
334
- })
335
- });
336
- }
337
-
338
- // ─── Component Match Mode ───
339
- if (!targetRect) return null;
340
- const showImage = enabled && imageUri;
341
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
342
- style: styles.overlay,
343
- pointerEvents: "box-none",
344
- nativeID: "image-overlay-standalone",
345
- children: [showOutline && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
346
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
347
- pointerEvents: "none",
348
- nativeID: "__image_overlay_highlight__",
349
- style: [styles.highlight, {
350
- left: targetRect.x - 3,
351
- top: targetRect.y - 3,
352
- width: targetRect.width + 6,
353
- height: targetRect.height + 6
354
- }]
355
- }), targetLabel && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
356
- pointerEvents: "none",
357
- style: [styles.label, {
358
- left: targetRect.x,
359
- top: targetRect.y - 20
360
- }],
361
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
362
- style: styles.labelText,
363
- children: targetLabel
364
- })
365
- })]
366
- }), showImage && (() => {
367
- const w = (imageWidth ?? targetRect.width) * scale;
368
- const h = (imageHeight ?? targetRect.height) * scale;
369
- const centerX = targetRect.x + targetRect.width / 2;
370
- const centerY = targetRect.y + targetRect.height / 2;
371
- const imgStyle = {
372
- position: "absolute",
373
- left: centerX - w / 2 + offsetX,
374
- top: centerY - h / 2 + offsetY,
375
- width: w,
376
- height: h,
377
- opacity
378
- };
379
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(OverlayImage, {
380
- uri: imageUri,
381
- style: imgStyle,
382
- invertX: invertX,
383
- invertY: invertY
384
- });
385
- })()]
386
- });
387
- }
388
- const styles = _reactNative.StyleSheet.create({
389
- overlay: {
390
- position: "absolute",
391
- top: 0,
392
- left: 0,
393
- right: 0,
394
- bottom: 0,
395
- zIndex: 999999,
396
- elevation: 999999,
397
- borderWidth: 0
398
- },
399
- highlight: {
400
- position: "absolute",
401
- borderWidth: 2,
402
- borderStyle: "dashed",
403
- borderColor: "#20C997",
404
- backgroundColor: "transparent"
405
- },
406
- label: {
407
- position: "absolute",
408
- backgroundColor: "#20C997",
409
- paddingHorizontal: 6,
410
- paddingVertical: 2,
411
- borderRadius: 3
412
- },
413
- labelText: {
414
- color: "#fff",
415
- fontSize: 10,
416
- fontWeight: "700",
417
- fontFamily: _sharedUi.monoFont
418
- },
419
- freeBorder: {
420
- position: "absolute",
421
- top: -6,
422
- left: -6,
423
- right: -6,
424
- bottom: -6,
425
- borderWidth: 1,
426
- borderColor: "transparent",
427
- borderRadius: 4
428
- },
429
- freeBorderActive: {
430
- borderColor: "#20C997",
431
- borderStyle: "dashed"
432
- },
433
- freeBorderLocked: {
434
- borderColor: "#f59e0b",
435
- borderStyle: "solid"
436
- },
437
- cornerWrapper: {
438
- position: "absolute",
439
- width: 24,
440
- height: 24,
441
- zIndex: 1000,
442
- alignItems: "center",
443
- justifyContent: "center"
444
- },
445
- cornerHandle: {
446
- width: 12,
447
- height: 12,
448
- borderRadius: 6,
449
- backgroundColor: "#20C997",
450
- borderWidth: 2,
451
- borderColor: "#fff"
452
- },
453
- cornerHandleActive: {
454
- backgroundColor: "#10b981",
455
- shadowColor: "#10b981",
456
- shadowOffset: {
457
- width: 0,
458
- height: 0
459
- },
460
- shadowOpacity: 0.8,
461
- shadowRadius: 6
462
- }
463
- });
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.ImageOverlayStandalone=ImageOverlayStandalone;var _react=_interopRequireWildcard(require("react"));var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _ImageOverlayController=require("../utils/ImageOverlayController");var _jsxRuntime=require("react/jsx-runtime");function _interopRequireWildcard(x,w){if("function"==typeof WeakMap)var v=new WeakMap,u=new WeakMap;return(_interopRequireWildcard=function(r,c){if(!c&&r&&r.__esModule)return r;var a,o,g={__proto__:null,default:r};if(null===r||"object"!=typeof r&&"function"!=typeof r)return g;if(a=c?u:v){if(a.has(r))return a.get(r);a.set(r,g)}for(const n in r)"default"!==n&&{}.hasOwnProperty.call(r,n)&&((o=(a=Object.defineProperty)&&Object.getOwnPropertyDescriptor(r,n))&&(o.get||o.set)?a(g,n,o):g[n]=r[n]);return g})(x,w)}function OverlayImage({uri:x,style:w,invertX:v,invertY:u}){const r=[];if(v)r.push({scaleX:-1});if(u)r.push({scaleY:-1});const c=r.length>0?{transform:r}:{};return(0,_jsxRuntime.jsx)(_reactNative.Image,{testID:"buoy-internal-image-overlay",source:{uri:x},style:[w,c],pointerEvents:"none"})}const FREE_MIN_SIZE=30;function FreePlacement({imageUri:x,x:w,y:v,width:u,height:r,opacity:c,aspectRatio:a,invertX:o,invertY:g,locked:n}){const[y,p]=(0,_react.useState)(false);const I=(0,_react.useRef)({x:0,y:0});const C=(0,_react.useRef)({x:0,y:0,width:0,height:0});const h=_reactNative.Dimensions.get("window");const _=(0,_react.useMemo)(()=>_reactNative.PanResponder.create({onStartShouldSetPanResponder:()=>!n,onMoveShouldSetPanResponder:(m,s)=>!n&&(Math.abs(s.dx)>2||Math.abs(s.dy)>2),onPanResponderTerminationRequest:()=>false,onPanResponderGrant:()=>{const m=_ImageOverlayController.ImageOverlayController.getState();I.current={x:m.freeX,y:m.freeY};p(true)},onPanResponderMove:(m,s)=>{const j=_ImageOverlayController.ImageOverlayController.getState();const f=Math.max(0,Math.min(I.current.x+s.dx,h.width-j.freeWidth));const d=Math.max(0,Math.min(I.current.y+s.dy,h.height-j.freeHeight));_ImageOverlayController.ImageOverlayController.setFreePosition(f,d)},onPanResponderRelease:()=>p(false),onPanResponderTerminate:()=>p(false)}),[h.width,h.height,n]);const R=(0,_react.useCallback)(m=>_reactNative.PanResponder.create({onStartShouldSetPanResponder:()=>!n,onMoveShouldSetPanResponder:()=>!n,onPanResponderTerminationRequest:()=>false,onPanResponderGrant:()=>{const s=_ImageOverlayController.ImageOverlayController.getState();C.current={x:s.freeX,y:s.freeY,width:s.freeWidth,height:s.freeHeight};p(true)},onPanResponderMove:(s,j)=>{const{dx:f,dy:d}=j;if(Math.abs(f)<.5&&Math.abs(d)<.5)return;const e=C.current;const l=a>0?a:e.width/e.height;const O=Math.abs(f);const W=Math.abs(d);const H=O>=W;let t;let i;let M=e.x;let b=e.y;switch(m){case"bottomRight":{t=H?e.width+f:(e.height+d)*l;t=Math.max(FREE_MIN_SIZE,Math.min(t,h.width-e.x));i=t/l;break}case"bottomLeft":{t=H?e.width-f:(e.height+d)*l;t=Math.max(FREE_MIN_SIZE,t);i=t/l;M=e.x+e.width-t;M=Math.max(0,M);t=Math.min(t,e.x+e.width);i=t/l;break}case"topRight":{t=H?e.width+f:(e.height-d)*l;t=Math.max(FREE_MIN_SIZE,Math.min(t,h.width-e.x));i=t/l;b=e.y+e.height-i;b=Math.max(0,b);i=Math.min(i,e.y+e.height);t=i*l;break}case"topLeft":{t=H?e.width-f:(e.height-d)*l;t=Math.max(FREE_MIN_SIZE,t);i=t/l;M=e.x+e.width-t;b=e.y+e.height-i;M=Math.max(0,M);b=Math.max(0,b);t=Math.min(t,e.x+e.width);i=t/l;b=e.y+e.height-i;break}}t=Math.max(FREE_MIN_SIZE,Math.round(t));i=Math.max(FREE_MIN_SIZE,Math.round(i));_ImageOverlayController.ImageOverlayController.setFreeDimensions(t,i,Math.round(M),Math.round(b))},onPanResponderRelease:()=>p(false),onPanResponderTerminate:()=>p(false)}),[h.width,h.height,a,n]);const S=(0,_react.useMemo)(()=>({topLeft:R("topLeft"),topRight:R("topRight"),bottomLeft:R("bottomLeft"),bottomRight:R("bottomRight")}),[R]);const P={..._sharedUi.absoluteFill,opacity:c};return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{position:"absolute",left:w,top:v,width:u,height:r},pointerEvents:n?"none":"auto",children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:_reactNative.StyleSheet.absoluteFill,...n?{}:_.panHandlers,children:(0,_jsxRuntime.jsx)(OverlayImage,{uri:x,style:P,invertX:o,invertY:g})}),(0,_jsxRuntime.jsx)(_reactNative.View,{pointerEvents:"none",style:[styles.freeBorder,y&&styles.freeBorderActive,n&&styles.freeBorderLocked]}),!n&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsx)(_reactNative.View,{...S.topLeft.panHandlers,style:[styles.cornerWrapper,{top:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.cornerHandle,y&&styles.cornerHandleActive]})}),(0,_jsxRuntime.jsx)(_reactNative.View,{...S.topRight.panHandlers,style:[styles.cornerWrapper,{top:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.cornerHandle,y&&styles.cornerHandleActive]})}),(0,_jsxRuntime.jsx)(_reactNative.View,{...S.bottomLeft.panHandlers,style:[styles.cornerWrapper,{bottom:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.cornerHandle,y&&styles.cornerHandleActive]})}),(0,_jsxRuntime.jsx)(_reactNative.View,{...S.bottomRight.panHandlers,style:[styles.cornerWrapper,{bottom:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.cornerHandle,y&&styles.cornerHandleActive]})})]})]})}function ImageOverlayStandalone(){const[x,w]=(0,_react.useState)(()=>_ImageOverlayController.ImageOverlayController.getState());(0,_react.useEffect)(()=>{return _ImageOverlayController.ImageOverlayController.subscribe(w)},[]);const{mode:v,enabled:u,imageUri:r,imageWidth:c,imageHeight:a,targetRect:o,targetLabel:g,showOutline:n,opacity:y,scale:p,offsetX:I,offsetY:C,invertX:h,invertY:_,locked:R,freeX:S,freeY:P,freeWidth:m,freeHeight:s}=x;const j=c&&a&&a>0?c/a:0;if(v==="free"&&u&&r){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:(0,_jsxRuntime.jsx)(FreePlacement,{imageUri:r,x:S,y:P,width:m,height:s,opacity:y,aspectRatio:j,invertX:h,invertY:_,locked:R})})}if(!o)return null;const f=u&&r;return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:[n&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsx)(_reactNative.View,{pointerEvents:"none",nativeID:"__image_overlay_highlight__",style:[styles.highlight,{left:o.x-3,top:o.y-3,width:o.width+6,height:o.height+6}]}),g&&(0,_jsxRuntime.jsx)(_reactNative.View,{pointerEvents:"none",style:[styles.label,{left:o.x,top:o.y-20}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.labelText,children:g})})]}),f&&(()=>{const d=(c??o.width)*p;const e=(a??o.height)*p;const l=o.x+o.width/2;const O=o.y+o.height/2;const W={position:"absolute",left:l-d/2+I,top:O-e/2+C,width:d,height:e,opacity:y};return(0,_jsxRuntime.jsx)(OverlayImage,{uri:r,style:W,invertX:h,invertY:_})})()]})}const styles=_reactNative.StyleSheet.create({overlay:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:999999,elevation:999999,borderWidth:0},highlight:{position:"absolute",borderWidth:2,borderStyle:"dashed",borderColor:"#20C997",backgroundColor:"transparent"},label:{position:"absolute",backgroundColor:"#20C997",paddingHorizontal:6,paddingVertical:2,borderRadius:3},labelText:{color:"#fff",fontSize:10,fontWeight:"700",fontFamily:_sharedUi.monoFont},freeBorder:{position:"absolute",top:-6,left:-6,right:-6,bottom:-6,borderWidth:1,borderColor:"transparent",borderRadius:4},freeBorderActive:{borderColor:"#20C997",borderStyle:"dashed"},freeBorderLocked:{borderColor:"#f59e0b",borderStyle:"solid"},cornerWrapper:{position:"absolute",width:24,height:24,zIndex:1e3,alignItems:"center",justifyContent:"center"},cornerHandle:{width:12,height:12,borderRadius:6,backgroundColor:"#20C997",borderWidth:2,borderColor:"#fff"},cornerHandleActive:{backgroundColor:"#10b981",shadowColor:"#10b981",shadowOffset:{width:0,height:0},shadowOpacity:.8,shadowRadius:6}});