@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,39 +1 @@
1
- "use strict";
2
-
3
- let image;
4
- export function loadImageClipboard() {
5
- if (typeof navigator === 'undefined' || !navigator.clipboard) return null;
6
- return {
7
- async hasImageAsync() {
8
- image = undefined;
9
- if (!navigator.clipboard.read) return false;
10
- const items = await navigator.clipboard.read();
11
- for (const item of items) {
12
- const type = item.types.find(value => value.startsWith('image/'));
13
- if (type) {
14
- image = await item.getType(type);
15
- return true;
16
- }
17
- }
18
- return false;
19
- },
20
- async getImageAsync() {
21
- if (!image) return null;
22
- const blob = image;
23
- image = undefined;
24
- const data = await new Promise((resolve, reject) => {
25
- const reader = new FileReader();
26
- reader.onload = () => resolve(String(reader.result));
27
- reader.onerror = reject;
28
- reader.readAsDataURL(blob);
29
- });
30
- return {
31
- data
32
- };
33
- },
34
- getStringAsync: () => navigator.clipboard.readText()
35
- };
36
- }
37
- export function loadTextClipboard() {
38
- return null;
39
- }
1
+ "use strict";let e;export function loadImageClipboard(){if(typeof navigator==="undefined"||!navigator.clipboard)return null;return{async hasImageAsync(){e=void 0;if(!navigator.clipboard.read)return false;const n=await navigator.clipboard.read();for(const t of n){const r=t.types.find(i=>i.startsWith("image/"));if(r){e=await t.getType(r);return true}}return false},async getImageAsync(){if(!e)return null;const n=e;e=void 0;const t=await new Promise((r,i)=>{const a=new FileReader;a.onload=()=>r(String(a.result));a.onerror=i;a.readAsDataURL(n)});return{data:t}},getStringAsync:()=>navigator.clipboard.readText()}}export function loadTextClipboard(){return null}
@@ -1,35 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * @buoy-gg/image-overlay
5
- *
6
- * Image overlay tool for comparing design mockups against your running app.
7
- *
8
- * PUBLIC API - Only these exports are supported for external use.
9
- */
10
-
11
- // =============================================================================
12
- // PRESET (Primary entry point for users)
13
- // =============================================================================
14
- export { imageOverlayToolPreset, createImageOverlayTool } from "./preset";
15
-
16
- // =============================================================================
17
- // COMPONENTS (For custom UI implementations)
18
- // =============================================================================
19
- export { ImageOverlayModal, ImageOverlayToolView } from "./imageOverlay/components/ImageOverlayModal";
20
- export { ImageOverlayStandalone } from "./imageOverlay/components/ImageOverlayStandalone";
21
-
22
- // =============================================================================
23
- // CONTROLLER (For programmatic control)
24
- // =============================================================================
25
- export { ImageOverlayController } from "./imageOverlay/utils/ImageOverlayController";
26
-
27
- // =============================================================================
28
- // UTILITIES (For custom integrations)
29
- // =============================================================================
30
- export { scanForImageTargets } from "./imageOverlay/utils/fiberScanner";
31
- export { setDevToolsHookOverride } from "./imageOverlay/utils/devtoolsHook";
32
-
33
- // =============================================================================
34
- // TYPES (For TypeScript users)
35
- // =============================================================================
1
+ "use strict";export{imageOverlayToolPreset,createImageOverlayTool}from"./preset";export{ImageOverlayModal,ImageOverlayToolView}from"./imageOverlay/components/ImageOverlayModal";export{ImageOverlayStandalone}from"./imageOverlay/components/ImageOverlayStandalone";export{ImageOverlayController}from"./imageOverlay/utils/ImageOverlayController";export{scanForImageTargets}from"./imageOverlay/utils/fiberScanner";export{setDevToolsHookOverride}from"./imageOverlay/utils/devtoolsHook";
@@ -1,38 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * Pre-configured image overlay tool for FloatingDevTools
5
- *
6
- * @example
7
- * ```tsx
8
- * import { imageOverlayToolPreset } from '@buoy-gg/image-overlay';
9
- *
10
- * const installedApps = [
11
- * imageOverlayToolPreset,
12
- * ];
13
- * ```
14
- */
15
-
16
- import { ImageOverlayIcon, createToolFactory, defineToolPreset } from "@buoy-gg/shared-ui";
17
- import { ImageOverlayModal } from "./imageOverlay/components/ImageOverlayModal";
18
- import { jsx as _jsx } from "react/jsx-runtime";
19
- export const IMAGE_OVERLAY_ICON_COLOR = "#A855F7";
20
- export const imageOverlayToolPreset = defineToolPreset({
21
- id: "image-overlay",
22
- name: "IMG",
23
- description: "Design mockup overlay",
24
- slot: "both",
25
- icon: ({
26
- size
27
- }) => /*#__PURE__*/_jsx(ImageOverlayIcon, {
28
- size: size,
29
- color: IMAGE_OVERLAY_ICON_COLOR
30
- }),
31
- component: ImageOverlayModal,
32
- props: {
33
- enableSharedModalDimensions: false
34
- }
35
- });
36
- export const createImageOverlayTool = createToolFactory(imageOverlayToolPreset, options => ({
37
- enableSharedModalDimensions: options.enableSharedModalDimensions ?? false
38
- }));
1
+ "use strict";import{ImageOverlayIcon as o,createToolFactory as a,defineToolPreset as r}from"@buoy-gg/shared-ui";import{ImageOverlayModal as s}from"./imageOverlay/components/ImageOverlayModal";import{jsx as l}from"react/jsx-runtime";export const IMAGE_OVERLAY_ICON_COLOR="#A855F7";export const imageOverlayToolPreset=r({id:"image-overlay",name:"IMG",description:"Design mockup overlay",slot:"both",icon:({size:e})=>l(o,{size:e,color:IMAGE_OVERLAY_ICON_COLOR}),component:s,props:{enableSharedModalDimensions:false}});export const createImageOverlayTool=a(imageOverlayToolPreset,e=>({enableSharedModalDimensions:e.enableSharedModalDimensions??false}));
package/lib/web/index.mjs CHANGED
@@ -1,5 +1,4 @@
1
- "use client";
2
- var _e=Object.defineProperty;var at=Object.getOwnPropertyDescriptor;var it=Object.getOwnPropertyNames;var lt=Object.prototype.hasOwnProperty;var st=(e,o)=>{for(var n in o)_e(e,n,{get:o[n],enumerable:!0})},Fe=(e,o,n,a)=>{if(o&&typeof o=="object"||typeof o=="function")for(let r of it(o))!lt.call(e,r)&&r!==n&&_e(e,r,{get:()=>o[r],enumerable:!(a=at(o,r))||a.enumerable});return e},M=(e,o,n)=>(Fe(e,o,"default"),n&&Fe(n,o,"default"));typeof window<"u"&&typeof globalThis.global>"u"&&(globalThis.global=globalThis);import{ImageOverlayIcon as Po,createToolFactory as Bo,defineToolPreset as Wo}from"@buoy-gg/shared-ui/web";var fe;function Xe(){return typeof navigator>"u"||!navigator.clipboard?null:{async hasImageAsync(){if(fe=void 0,!navigator.clipboard.read)return!1;let e=await navigator.clipboard.read();for(let o of e){let n=o.types.find(a=>a.startsWith("image/"));if(n)return fe=await o.getType(n),!0}return!1},async getImageAsync(){if(!fe)return null;let e=fe;return fe=void 0,{data:await new Promise((n,a)=>{let r=new FileReader;r.onload=()=>n(String(r.result)),r.onerror=a,r.readAsDataURL(e)})}},getStringAsync:()=>navigator.clipboard.readText()}}function Ye(){return null}import{useState as Te,useEffect as De,useCallback as ue}from"react";var R={};st(R,{AccessibilityInfo:()=>Tt,ActivityIndicator:()=>ht,Alert:()=>le,Animated:()=>wt,AppRegistry:()=>St,AppState:()=>Rt,Appearance:()=>vt,BackHandler:()=>Ct,Button:()=>yt,CheckBox:()=>Dt,Clipboard:()=>It,DeviceEventEmitter:()=>Qt,Dimensions:()=>se,Easing:()=>Ot,FlatList:()=>Et,I18nManager:()=>Mt,Image:()=>pe,ImageBackground:()=>Ft,InteractionManager:()=>Pt,Keyboard:()=>Vt,KeyboardAvoidingView:()=>_t,LayoutAnimation:()=>Bt,Linking:()=>Wt,LogBox:()=>Zt,Modal:()=>pt,NativeEventEmitter:()=>Ht,NativeModules:()=>xt,PanResponder:()=>ce,Picker:()=>Xt,PixelRatio:()=>kt,Platform:()=>At,Pressable:()=>ft,ProgressBar:()=>Yt,RefreshControl:()=>Nt,SafeAreaView:()=>Ut,ScrollView:()=>Pe,SectionList:()=>$t,Share:()=>Lt,StatusBar:()=>jt,StyleSheet:()=>J,Switch:()=>mt,Text:()=>g,TextInput:()=>we,Touchable:()=>Gt,TouchableHighlight:()=>ut,TouchableNativeFeedback:()=>qt,TouchableOpacity:()=>O,TouchableWithoutFeedback:()=>gt,UIManager:()=>We,Vibration:()=>zt,View:()=>l,VirtualizedList:()=>Kt,YellowBox:()=>Jt,findNodeHandle:()=>Be,unstable_createElement:()=>bt,useColorScheme:()=>eo,useLocaleContext:()=>to,useWindowDimensions:()=>oo});M(R,Go);import*as Go from"react-native-web";import{unstable_createElement as bt,NativeModules as xt,AccessibilityInfo as Tt,Animated as wt,Appearance as vt,AppRegistry as St,AppState as Rt,BackHandler as Ct,Clipboard as It,Dimensions as se,Easing as Ot,I18nManager as Mt,Keyboard as Vt,InteractionManager as Pt,LayoutAnimation as Bt,Linking as Wt,NativeEventEmitter as Ht,PanResponder as ce,PixelRatio as kt,Platform as At,Share as Lt,StyleSheet as J,UIManager as We,Vibration as zt,CheckBox as Dt,FlatList as Et,Image as pe,ImageBackground as Ft,KeyboardAvoidingView as _t,Picker as Xt,ProgressBar as Yt,RefreshControl as Nt,SafeAreaView as Ut,SectionList as $t,StatusBar as jt,Touchable as Gt,TouchableNativeFeedback as qt,VirtualizedList as Kt,YellowBox as Jt,LogBox as Zt,DeviceEventEmitter as Qt,useColorScheme as eo,useLocaleContext as to,useWindowDimensions as oo}from"react-native-web";import*as I from"react-native-web";import{createElement as ct,forwardRef as dt}from"react";function j(e){let o=dt((a,r)=>{let{accessibilityState:y,accessibilityValue:T,...h}=a;for(let b of["busy","checked","disabled","expanded","selected"])y?.[b]!==void 0&&h[`aria-${b}`]===void 0&&(h[`aria-${b}`]=y[b]);for(let[b,c]of Object.entries({min:"valuemin",max:"valuemax",now:"valuenow",text:"valuetext"}))T?.[b]!==void 0&&h[`aria-${c}`]===void 0&&(h[`aria-${c}`]=T[b]);return ct(e,{...h,ref:r})}),n=e.State;return n&&Object.assign(o,{State:n}),o.displayName=e.displayName??e.name??"NativeWebView",o}var l=j(I.View),g=j(I.Text),we=j(I.TextInput),O=j(I.TouchableOpacity),ut=j(I.TouchableHighlight),gt=j(I.TouchableWithoutFeedback),ft=j(I.Pressable),Pe=j(I.ScrollView),pt=j(I.Modal),mt=j(I.Switch),ht=j(I.ActivityIndicator),yt=j(I.Button),Be=I.findNodeHandle,le={alert(e,o,n,a){if(typeof document>"u")return;let r=document.createElement("dialog");r.dataset.buoyRoot="",r.setAttribute("aria-label",e),r.style.cssText="position:fixed;inset:0;margin:auto;width:min(440px,90vw);padding:24px;border:1px solid #475569;border-radius:14px;background:#17212e;color:#f1f5f9;font:14px system-ui;box-shadow:0 20px 80px #0008;z-index:2147483647";let y=document.createElement("h2");if(y.textContent=e,y.style.cssText="font-size:18px;margin:0 0 12px",r.appendChild(y),o){let c=document.createElement("p");c.textContent=o,c.style.cssText="line-height:1.5;white-space:pre-wrap;margin:0 0 20px",r.appendChild(c)}let T=document.createElement("div");T.style.cssText="display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px";let h=n?.length?n:[{text:"OK"}],b=()=>{r.close?.(),r.remove()};for(let c of h){let v=document.createElement("button");v.type="button",v.textContent=c.text??"OK",v.style.cssText=`padding:9px 14px;border:1px solid #64748b;border-radius:7px;color:white;background:${c.style==="destructive"?"#a52b38":"#283a4d"};cursor:pointer;font:inherit`,v.onclick=()=>{b(),c.onPress?.()},T.appendChild(v)}r.addEventListener("cancel",c=>{c.preventDefault(),a?.cancelable!==!1&&(b(),a?.onDismiss?.())}),r.appendChild(T),document.body.appendChild(r),r.showModal?r.showModal():r.setAttribute("open","")}};import{JsModal as vo,ModalHeader as Oe,macOSColors as Je,night as m,Trash2 as So,SquareDashed as Ro,Image as Co,PowerToggleButton as Io,windowDragProps as Oo,ToggleRow as Ee,monoFont as Mo}from"@buoy-gg/shared-ui/web";function ve(e){return new Promise(o=>{try{let n=[];e&&n.push(e),e?.canonical?.publicInstance&&n.push(e.canonical.publicInstance),e?.canonical&&e.canonical!==e&&n.push(e.canonical);for(let a of n)if(typeof a.getBoundingClientRect=="function")try{let r=a.getBoundingClientRect();if(r&&typeof r.x=="number"&&typeof r.y=="number"&&typeof r.width=="number"&&typeof r.height=="number"&&r.width>0&&r.height>0){o({x:r.x,y:r.y,width:r.width,height:r.height});return}}catch{}for(let a of n)if(typeof a.measure=="function"){let r=setTimeout(()=>o(null),200);a.measure((y,T,h,b,c,v)=>{clearTimeout(r),c!=null&&v!=null&&h!=null&&b!=null&&h>0&&b>0?o({x:c,y:v,width:h,height:b}):o(null)});return}try{let a=Be(e);if(a!=null){let r=setTimeout(()=>o(null),200);We.measure(a,(y,T,h,b,c,v)=>{clearTimeout(r),c!=null&&v!=null&&h!=null&&b!=null&&h>0&&b>0?o({x:c,y:v,width:h,height:b}):o(null)});return}}catch{}o(null)}catch{o(null)}})}var He=null;function no(e){He=e??null}function Se(){return He||(typeof globalThis>"u"?null:globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__??null)}var Ne="image-target:",ro=5,ao=22;function io(){let e=Se();if(!e?.getFiberRoots)return[];let o=new Set,n=e.renderers?.keys?Array.from(e.renderers.keys()):[1];for(let a of n)try{e.getFiberRoots(a)?.forEach(r=>o.add(r))}catch{}return[...o]}function lo(e){return e.tag===ao&&e.memoizedState!==null}function so(e){return e.memoizedProps?.activityState===0}function me(e,o,n=0,a=new Set){if(!(!e||a.has(e)||n>500)){if(a.add(e),lo(e)){e.sibling&&me(e.sibling,o,n,a);return}if(so(e)){e.sibling&&me(e.sibling,o,n,a);return}o(e,n),e.child&&me(e.child,o,n+1,a),e.sibling&&me(e.sibling,o,n,a)}}function co(e){let o=new Set(["View","RCTView","Text","RCTText","Image","RCTImageView","ScrollView","RCTScrollView","TextInput","RCTTextInput","TouchableOpacity","TouchableHighlight","TouchableWithoutFeedback","Pressable","FlatList","SectionList","SafeAreaView"]),n=e._debugOwner||e.return,a=0;for(;n&&a<30;){a++;let r=n.type;if(r){let y=typeof r=="string"?r:r.displayName||r.name;if(y&&!o.has(y))return y}n=n.return}return null}function ne(){let e=io();if(e.length===0)return[];let o=[];for(let n of e)me(n.current,a=>{if(a.tag!==ro)return;let r=a.memoizedProps?.testID??a.pendingProps?.testID??a.memoizedProps?.["data-testid"]??a.pendingProps?.["data-testid"];if(!r||!r.startsWith(Ne))return;let y=r.slice(Ne.length);y&&o.push({label:y,testID:r,fiber:a,instance:a.stateNode,componentName:co(a)})});return o}var Ge={mode:null,enabled:!1,imageUri:null,imageWidth:null,imageHeight:null,targetTag:null,targetLabel:null,targetRect:null,showOutline:!0,opacity:.5,scale:1,offsetX:0,offsetY:0,invertX:!1,invertY:!1,locked:!1,freeX:0,freeY:0,freeWidth:200,freeHeight:200},i={...Ge},Ae=new Set,Z=null,Re=null,he=!1,ye=null,uo=null;function V(){for(let e of Ae)e(i)}function go(e){return e?typeof e._nativeTag=="number"?e._nativeTag:typeof e.canonical?._nativeTag=="number"?e.canonical._nativeTag:typeof e.__nativeTag=="number"?e.__nativeTag:null:null}async function Ue(e,o){let n=await ve(e);if(n)return{rect:n,freshInstance:e};let r=ne().find(y=>y.label===o);return r&&(n=await ve(r.instance),n)?{rect:n,freshInstance:r.instance}:{rect:null,freshInstance:e}}function fo(){if(ye)return;let e=Se();if(e){if(e.rendererInterfaces)for(let[,o]of e.rendererInterfaces)typeof o.setTraceUpdatesEnabled=="function"&&o.setTraceUpdatesEnabled(!0);typeof e.sub=="function"&&(ye=e.sub("traceUpdates",ho))}}var de=null,ke=!1;function po(){if(de!==null||typeof requestAnimationFrame!="function")return;let e=()=>{de=requestAnimationFrame(e),!(ke||!he||!Z)&&(ke=!0,qe().finally(()=>{ke=!1}))};de=requestAnimationFrame(e)}function mo(){de!==null&&typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(de),de=null}function $e(){mo(),ye&&(ye(),ye=null)}function ho(e){!he||!Z||qe()}function qe(){return ve(Z).then(e=>{if(e&&i.targetRect){let o=i.targetRect;(Math.abs(e.x-o.x)>.5||Math.abs(e.y-o.y)>.5||Math.abs(e.width-o.width)>.5||Math.abs(e.height-o.height)>.5)&&(i={...i,targetRect:e},V())}}).catch(()=>{})}function je(e){return new Promise(o=>{pe.getSize(e,(n,a)=>o({width:n,height:a}),()=>o(null))})}var p={subscribe(e){return Ae.add(e),e(i),()=>Ae.delete(e)},getState(){return i},async setTarget(e,o,n){Z=e,Re=o;let a=n?.stateNode??e,{rect:r,freshInstance:y}=await Ue(a,o);Z=y;let T=go(Z);i={...i,mode:"component",targetTag:T,targetLabel:o,targetRect:r},V()},async setImageUri(e){let o=await je(e),n=1;o&&i.targetRect&&o.width>0&&(n=i.targetRect.width/o.width),i={...i,imageUri:e,imageWidth:o?.width??null,imageHeight:o?.height??null,scale:n,showOutline:!1},V()},setOpacity(e){i={...i,opacity:Math.max(0,Math.min(1,e))},V()},setScale(e){i={...i,scale:Math.max(.01,Math.min(5,e))},V()},setOffset(e,o){i={...i,offsetX:e,offsetY:o},V()},toggleInvertX(){i={...i,invertX:!i.invertX},V()},toggleInvertY(){i={...i,invertY:!i.invertY},V()},setLocked(e){i={...i,locked:e},V()},setAutoTrack(e){he=e,e?(fo(),po()):$e()},isAutoTracking(){return he},setShowOutline(e){i={...i,showOutline:e},V()},setEnabled(e){i={...i,enabled:e},V()},toggle(){i={...i,enabled:!i.enabled},V()},fitWidth(){i.imageWidth&&i.targetRect&&i.imageWidth>0&&(i={...i,scale:i.targetRect.width/i.imageWidth},V())},fitHeight(){i.imageHeight&&i.targetRect&&i.imageHeight>0&&(i={...i,scale:i.targetRect.height/i.imageHeight},V())},resetSettings(){if(i.mode==="free"){let e=se.get("window"),o=i.imageWidth??200,n=i.imageHeight??200;i={...i,opacity:.5,freeX:(e.width-o)/2,freeY:(e.height-n)/2,freeWidth:o,freeHeight:n}}else{let e=1;i.imageWidth&&i.targetRect&&i.imageWidth>0&&(e=i.targetRect.width/i.imageWidth),i={...i,opacity:.5,scale:e,offsetX:0,offsetY:0}}V()},async remeasure(){if(!Re)return;let{rect:e,freshInstance:o}=await Ue(Z,Re);Z=o,e&&(i={...i,targetRect:e},V())},async startFreeMode(e){let o=await je(e),n=se.get("window"),a=o?.width??200,r=o?.height??200,y=a,T=r,h=n.width*.8,b=n.height*.6;if(y>h||T>b){let c=Math.min(h/y,b/T);y=Math.round(y*c),T=Math.round(T*c)}i={...i,mode:"free",enabled:!0,imageUri:e,imageWidth:o?.width??null,imageHeight:o?.height??null,opacity:.5,freeX:Math.round((n.width-y)/2),freeY:Math.round((n.height-T)/2),freeWidth:Math.round(y),freeHeight:Math.round(T)},V()},setFreePosition(e,o){i={...i,freeX:e,freeY:o},V()},setFreeDimensions(e,o,n,a){i={...i,freeWidth:e,freeHeight:o,freeX:n,freeY:a},V()},reset(){$e(),he=!1,uo=null,Z=null,Re=null,i={...Ge},V()}};import{ChevronRight as yo,night as q,Hash as bo,ToolEmptyState as xo,monoFont as Le}from"@buoy-gg/shared-ui/web";import{jsx as K,jsxs as be}from"react/jsx-runtime";function To({target:e,onSelect:o}){return be(O,{style:X.card,onPress:o,activeOpacity:.7,children:[K(l,{style:X.colorIndicator}),be(l,{style:X.content,children:[K(l,{style:X.topRow,children:K(g,{style:X.label,numberOfLines:1,children:e.label})}),be(l,{style:X.bottomRow,children:[be(l,{style:X.badgeRow,children:[be(l,{style:X.testIdBadge,children:[K(bo,{size:8,color:q.color.accent}),K(g,{style:X.testIdBadgeText,children:"testID"})]}),K(g,{style:X.testIdValue,numberOfLines:1,children:e.testID})]}),e.componentName&&K(g,{style:X.componentName,numberOfLines:1,children:e.componentName})]})]}),K(yo,{size:16,color:q.color.textTertiary})]})}function Ke({targets:e,onSelect:o}){return e.length===0?K(xo,{testID:"buoy-image-overlay-empty",otto:"scanning",title:"No targets found",message:`Tag components with
3
- testID="image-target:YourLabel"`}):K(Pe,{style:X.list,contentContainerStyle:X.listContent,children:e.map(n=>K(To,{target:n,onSelect:()=>o(n)},n.testID))})}var X=J.create({list:{flex:1},listContent:{paddingTop:8,paddingBottom:20},card:{flexDirection:"row",alignItems:"center",paddingVertical:10,paddingHorizontal:12,marginHorizontal:12,marginBottom:6,backgroundColor:q.color.surface,borderRadius:8,borderWidth:1,borderColor:q.color.border},colorIndicator:{width:4,height:36,borderRadius:2,marginRight:10,backgroundColor:q.color.accent},content:{flex:1,marginRight:8},topRow:{flexDirection:"row",alignItems:"center",marginBottom:4},label:{fontSize:13,fontWeight:"600",color:q.color.text,flex:1},bottomRow:{gap:2},badgeRow:{flexDirection:"row",alignItems:"center",gap:4},testIdBadge:{flexDirection:"row",alignItems:"center",paddingVertical:2,paddingHorizontal:5,borderRadius:4,backgroundColor:q.color.accentSoft,gap:3},testIdBadgeText:{fontSize:9,fontWeight:"700",color:q.color.accent},testIdValue:{fontSize:11,color:q.color.text,fontFamily:Le,flex:1},componentName:{fontSize:10,color:"#a855f7",fontFamily:Le,marginTop:1},emptyState:{alignItems:"center",paddingVertical:40,paddingHorizontal:32},emptyTitle:{color:q.color.text,fontSize:14,fontWeight:"600",marginBottom:6},emptyText:{color:q.color.textTertiary,fontSize:12,textAlign:"center",lineHeight:18,fontFamily:Le}});import{useRef as oe,useCallback as Ce}from"react";import{night as Q,monoFont as wo}from"@buoy-gg/shared-ui/web";import{jsx as F,jsxs as Ie}from"react/jsx-runtime";function xe({label:e,value:o,min:n,max:a,step:r,displayValue:y,onChange:T}){let h=oe(0),b=oe(0),c=Ce(S=>Math.max(n,Math.min(a,S)),[n,a]),v=a>n?(o-n)/(a-n):0,L=oe(T),N=oe(c),u=oe(n),W=oe(a);L.current=T,N.current=c,u.current=n,W.current=a;let H=Ce(S=>{let E=S-b.current,k=Math.max(0,Math.min(1,E/h.current)),A=u.current+k*(W.current-u.current);L.current(N.current(A))},[]),D=oe(ce.create({onStartShouldSetPanResponder:()=>!0,onMoveShouldSetPanResponder:()=>!0,onPanResponderTerminationRequest:()=>!1,onPanResponderGrant:S=>{H(S.nativeEvent.pageX)},onPanResponderMove:S=>{H(S.nativeEvent.pageX)}})).current,U=Ce(S=>{h.current=S.nativeEvent.layout.width},[]),ee=oe(null),_=Ce(()=>{ee.current?.measure?.((S,E,k,A,x)=>{b.current=x})},[]);return Ie(l,{style:Y.controlRow,children:[F(g,{style:Y.label,children:e}),Ie(l,{style:Y.controlRight,children:[F(O,{style:Y.stepperButton,onPress:()=>T(c(o-r)),activeOpacity:.6,children:F(g,{style:Y.stepperButtonText,children:"-"})}),F(l,{style:Y.sliderHitArea,...D.panHandlers,children:Ie(l,{ref:ee,style:Y.sliderTrack,onLayout:S=>{U(S),_()},pointerEvents:"none",children:[F(l,{style:[Y.sliderFill,{width:`${v*100}%`}]}),F(l,{style:[Y.sliderThumb,{left:`${v*100}%`}]})]})}),F(O,{style:Y.stepperButton,onPress:()=>T(c(o+r)),activeOpacity:.6,children:F(g,{style:Y.stepperButtonText,children:"+"})}),F(g,{style:Y.valueText,children:y})]})]})}function ze({opacity:e,scale:o,offsetX:n,offsetY:a,onOpacityChange:r,onScaleChange:y,onOffsetChange:T,opacityOnly:h}){return h?F(xe,{label:"Opacity",value:e,min:0,max:1,step:.05,displayValue:`${Math.round(e*100)}%`,onChange:r}):Ie(l,{style:Y.container,children:[F(xe,{label:"Opacity",value:e,min:0,max:1,step:.05,displayValue:`${Math.round(e*100)}%`,onChange:r}),F(xe,{label:"Scale",value:o,min:.05,max:3,step:.05,displayValue:`${Math.round(o*100)}%`,onChange:y}),F(xe,{label:"Offset X",value:n,min:-200,max:200,step:2,displayValue:`${Math.round(n)}px`,onChange:b=>T(Math.round(b),a)}),F(xe,{label:"Offset Y",value:a,min:-200,max:200,step:2,displayValue:`${Math.round(a)}px`,onChange:b=>T(n,Math.round(b))})]})}var Y=J.create({container:{gap:8},controlRow:{paddingHorizontal:12,gap:4},label:{fontSize:11,fontWeight:"600",color:Q.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},controlRight:{flexDirection:"row",alignItems:"center",gap:6},stepperButton:{width:28,height:28,borderRadius:6,backgroundColor:Q.color.surfaceElevated,borderWidth:1,borderColor:Q.color.border,justifyContent:"center",alignItems:"center"},stepperButtonText:{fontSize:16,fontWeight:"700",color:Q.color.text,lineHeight:18},sliderHitArea:{flex:1,paddingVertical:20,paddingHorizontal:40,marginVertical:-20,marginHorizontal:-40},sliderTrack:{height:28,justifyContent:"center",borderRadius:6,backgroundColor:Q.color.bg,borderWidth:1,borderColor:Q.color.border,overflow:"hidden"},sliderFill:{position:"absolute",left:0,top:0,bottom:0,backgroundColor:Q.color.accentFill,borderRadius:5},sliderThumb:{position:"absolute",width:4,top:4,bottom:4,marginLeft:-2,borderRadius:2,backgroundColor:Q.color.accent},valueText:{fontSize:11,fontWeight:"600",color:Q.color.text,width:45,textAlign:"right",fontFamily:wo}});import{Fragment as Ze,jsx as s,jsxs as f}from"react/jsx-runtime";var re="";function Me({visible:e,onClose:o,onBack:n,onMinimize:a,enableSharedModalDimensions:r=!1,initialModalState:y,minimizeTargetPosition:T,inline:h=!1,initialView:b}){let[c,v]=Te(()=>{if(b)return b;let d=p.getState();return d.mode==="free"?"free":d.targetRect?"controls":"idle"}),[L,N]=Te(()=>b==="targets"?ne():[]),[u,W]=Te(()=>p.getState()),[H,D]=Te(re),[U,ee]=Te(()=>p.isAutoTracking());De(()=>{re=H},[H]),De(()=>p.subscribe(W),[]),De(()=>(p.setAutoTrack(U),()=>{}),[U]);let _=ue(()=>{let d=ne();N(d),v("targets")},[]),S=ue(async d=>{await p.setTarget(d.instance,d.label,d.fiber),re.trim()&&(await p.setImageUri(re.trim()),p.setEnabled(!0)),v("controls")},[]),E=ue(async()=>{let d=re.trim();d&&(c==="free"?await p.startFreeMode(d):(await p.setImageUri(d),p.setEnabled(!0)))},[c]),k=ue(async()=>{let d=null;try{d=Xe()}catch{}let w=null;if(!d)try{let C=Ye();w=C.default||C}catch{}if(!d&&!w){le.alert("Clipboard not available","Install expo-clipboard or @react-native-clipboard/clipboard to use paste.");return}try{if(d&&typeof d.hasImageAsync=="function"&&await d.hasImageAsync()){let $=await d.getImageAsync({format:"png"});if($?.data){c==="free"?await p.startFreeMode($.data):(await p.setImageUri($.data),p.setEnabled(!0));return}}let C=null;if(d&&typeof d.getStringAsync=="function"?C=await d.getStringAsync():w&&typeof w.getString=="function"&&(C=await w.getString()),C&&(C.startsWith("http")||C.startsWith("data:"))){D(C),re=C;return}d?le.alert("No image detected","Try saving your design image, opening it in Photos or Preview, and copying it from there."):le.alert("Image paste requires expo-clipboard","Your project uses @react-native-clipboard/clipboard which only supports text. Install expo-clipboard to paste images directly, or paste an image URL instead.")}catch{le.alert("Paste failed","Something went wrong reading the clipboard. Try copying the image again.")}},[c]),A=ue(()=>{p.reset(),re="",v("idle"),D(""),N([])},[]),x=ue(()=>{if(c==="controls"){let d=ne();N(d),v("targets")}else(c==="targets"||c==="free")&&p.reset(),v("idle")},[c]),z=(()=>{switch(c){case"targets":return`Targets (${L.length})`;case"controls":return u.targetLabel||"Component Match";case"free":return"Free Placement";default:return"Image Overlay"}})(),ae={showToggleButton:!1,customContent:f(Oe,{children:[s(Oe.Navigation,{onBack:c!=="idle"?x:n}),s(Oe.Content,{title:z}),f(Oe.Actions,{children:[c==="targets"&&s(O,{style:t.headerTextButton,onPress:_,activeOpacity:.7,children:s(g,{style:t.headerTextButtonLabel,children:"Scan"})}),(c==="controls"||c==="free")&&u.imageUri&&s(Io,{isEnabled:u.enabled,onToggle:()=>p.toggle(),accessibilityLabel:"Toggle image overlay"}),c!=="idle"&&s(O,{style:t.headerActionButton,onPress:A,activeOpacity:.7,children:s(So,{size:14,color:m.color.textSecondary})})]})]})},ie=f(l,{style:t.container,children:[c==="idle"&&f(l,{style:t.homeContainer,children:[s(g,{style:t.homeSubtitle,children:"Choose a mode"}),f(l,{style:t.modeGrid,children:[f(O,{style:t.modePanel,onPress:_,activeOpacity:.7,children:[s(l,{style:[t.modeIconCircle,{backgroundColor:m.color.accentSoft}],children:s(Ro,{size:24,color:m.color.accent})}),f(g,{style:t.modePanelTitle,children:["Component",`
4
- `,"Match"]}),s(g,{style:t.modePanelDesc,children:"Overlay on a tagged component"})]}),f(O,{style:t.modePanel,onPress:()=>v("free"),activeOpacity:.7,children:[s(l,{style:[t.modeIconCircle,{backgroundColor:m.color.accentSoft}],children:s(Co,{size:24,color:m.color.accent})}),f(g,{style:t.modePanelTitle,children:["Free",`
5
- `,"Placement"]}),s(g,{style:t.modePanelDesc,children:"Drag and resize anywhere"})]})]})]}),c==="targets"&&s(Ke,{targets:L,onSelect:S}),c==="controls"&&f(l,{style:t.controlsContainer,children:[u.targetRect&&f(l,{style:t.infoCard,children:[f(l,{style:t.infoRow,children:[s(g,{style:t.infoLabel,children:"Component"}),s(g,{style:t.infoValue,children:u.targetLabel})]}),f(l,{style:t.infoRow,children:[s(g,{style:t.infoLabel,children:"Size"}),f(g,{style:t.infoValueMono,children:[Math.round(u.targetRect.width)," x ",Math.round(u.targetRect.height)]})]}),f(l,{style:t.infoRow,children:[s(g,{style:t.infoLabel,children:"Position"}),f(g,{style:t.infoValueMono,children:[Math.round(u.targetRect.x),", ",Math.round(u.targetRect.y)]})]}),u.imageWidth!=null&&u.imageHeight!=null&&f(l,{style:t.infoRow,children:[s(g,{style:t.infoLabel,children:"Image"}),f(g,{style:t.infoValueMono,children:[u.imageWidth," x ",u.imageHeight]})]})]}),f(l,{style:t.inputSection,children:[s(g,{style:t.sectionLabel,children:"Image"}),s(O,{style:t.pasteButton,onPress:k,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",children:s(g,{style:t.pasteButtonText,children:"Paste from Clipboard"})}),f(l,{style:t.urlRow,children:[s(we,{style:t.urlInput,value:H,onChangeText:D,placeholder:"or enter URL...",placeholderTextColor:m.color.placeholder,autoCapitalize:"none",autoCorrect:!1,returnKeyType:"go",onSubmitEditing:E}),s(O,{style:[t.loadButton,!H.trim()&&t.loadButtonDisabled],onPress:E,disabled:!H.trim(),activeOpacity:.7,children:s(g,{style:t.loadButtonText,children:"Load"})})]})]}),f(l,{style:t.toggleSection,children:[s(Ee,{label:"Show Outline",value:u.showOutline,onValueChange:d=>p.setShowOutline(d)}),s(Ee,{label:"Auto Track",value:U,onValueChange:ee}),u.imageUri&&f(Ze,{children:[f(l,{style:t.blendRow,children:[s(g,{style:t.toggleLabel,children:"Opacity"}),s(l,{style:t.blendButtons,children:[0,25,50,75,100].map(d=>s(O,{style:[t.blendButton,Math.round(u.opacity*100)===d&&t.blendButtonActive],onPress:()=>p.setOpacity(d/100),activeOpacity:.7,children:f(g,{style:[t.blendButtonText,Math.round(u.opacity*100)===d&&t.blendButtonTextActive],children:[d,"%"]})},d))})]}),f(l,{style:t.blendRow,children:[s(g,{style:t.toggleLabel,children:"Flip"}),f(l,{style:t.blendButtons,children:[s(O,{style:[t.blendButton,u.invertX&&t.blendButtonActive],onPress:()=>p.toggleInvertX(),activeOpacity:.7,children:s(g,{style:[t.blendButtonText,u.invertX&&t.blendButtonTextActive],children:"Horizontal"})}),s(O,{style:[t.blendButton,u.invertY&&t.blendButtonActive],onPress:()=>p.toggleInvertY(),activeOpacity:.7,children:s(g,{style:[t.blendButtonText,u.invertY&&t.blendButtonTextActive],children:"Vertical"})})]})]})]})]}),u.imageUri&&s(ze,{opacity:u.opacity,scale:u.scale,offsetX:u.offsetX,offsetY:u.offsetY,onOpacityChange:d=>p.setOpacity(d),onScaleChange:d=>p.setScale(d),onOffsetChange:(d,w)=>p.setOffset(d,w)}),f(l,{style:t.actions,children:[s(O,{style:t.actionButton,onPress:()=>p.resetSettings(),activeOpacity:.7,children:s(g,{style:t.actionButtonText,children:"Reset Settings"})}),s(O,{style:t.actionButton,onPress:()=>p.remeasure(),activeOpacity:.7,children:s(g,{style:t.actionButtonText,children:"Remeasure"})})]})]}),c==="free"&&f(l,{style:t.controlsContainer,children:[f(l,{style:t.inputSection,children:[s(g,{style:t.sectionLabel,children:"Image"}),s(O,{style:t.pasteButton,onPress:k,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",children:s(g,{style:t.pasteButtonText,children:"Paste from Clipboard"})}),f(l,{style:t.urlRow,children:[s(we,{style:t.urlInput,value:H,onChangeText:D,placeholder:"or enter URL...",placeholderTextColor:m.color.placeholder,autoCapitalize:"none",autoCorrect:!1,returnKeyType:"go",onSubmitEditing:E}),s(O,{style:[t.loadButton,!H.trim()&&t.loadButtonDisabled],onPress:E,disabled:!H.trim(),activeOpacity:.7,children:s(g,{style:t.loadButtonText,children:"Load"})})]})]}),u.imageUri&&u.mode==="free"&&f(Ze,{children:[f(l,{style:t.infoCard,children:[f(l,{style:t.infoRow,children:[s(g,{style:t.infoLabel,children:"Position"}),f(g,{style:t.infoValueMono,children:[Math.round(u.freeX),", ",Math.round(u.freeY)]})]}),f(l,{style:t.infoRow,children:[s(g,{style:t.infoLabel,children:"Size"}),f(g,{style:t.infoValueMono,children:[Math.round(u.freeWidth)," x ",Math.round(u.freeHeight)]})]}),u.imageWidth!=null&&u.imageHeight!=null&&f(l,{style:t.infoRow,children:[s(g,{style:t.infoLabel,children:"Original"}),f(g,{style:t.infoValueMono,children:[u.imageWidth," x ",u.imageHeight]})]})]}),s(l,{style:t.inputSection,children:s(ze,{opacity:u.opacity,scale:1,offsetX:0,offsetY:0,onOpacityChange:d=>p.setOpacity(d),onScaleChange:()=>{},onOffsetChange:()=>{},opacityOnly:!0})}),f(l,{style:t.toggleSection,children:[s(Ee,{label:"Lock Position",tone:"warning",value:u.locked,onValueChange:d=>p.setLocked(d)}),f(l,{style:t.blendRow,children:[s(g,{style:t.toggleLabel,children:"Opacity"}),s(l,{style:t.blendButtons,children:[0,25,50,75,100].map(d=>s(O,{style:[t.blendButton,Math.round(u.opacity*100)===d&&t.blendButtonActive],onPress:()=>p.setOpacity(d/100),activeOpacity:.7,children:f(g,{style:[t.blendButtonText,Math.round(u.opacity*100)===d&&t.blendButtonTextActive],children:[d,"%"]})},d))})]}),f(l,{style:t.blendRow,children:[s(g,{style:t.toggleLabel,children:"Flip"}),f(l,{style:t.blendButtons,children:[s(O,{style:[t.blendButton,u.invertX&&t.blendButtonActive],onPress:()=>p.toggleInvertX(),activeOpacity:.7,children:s(g,{style:[t.blendButtonText,u.invertX&&t.blendButtonTextActive],children:"Horizontal"})}),s(O,{style:[t.blendButton,u.invertY&&t.blendButtonActive],onPress:()=>p.toggleInvertY(),activeOpacity:.7,children:s(g,{style:[t.blendButtonText,u.invertY&&t.blendButtonTextActive],children:"Vertical"})})]})]})]}),s(l,{style:t.actions,children:s(O,{style:t.actionButton,onPress:()=>p.resetSettings(),activeOpacity:.7,children:s(g,{style:t.actionButtonText,children:"Reset Position"})})})]})]})]});return h?f(l,{style:t.inlineRoot,children:[s(l,{style:t.inlineHeader,...Oo,children:ae.customContent}),ie]}):s(vo,{visible:e,onClose:o,onMinimize:a,minimizeTargetPosition:T,initialModalState:y,header:ae,initialMode:"bottomSheet",persistenceKey:"buoy-image-overlay-modal",enablePersistence:!0,children:ie})}function Vo(e={}){return s(Me,{...e,inline:!0,visible:!0,onClose:()=>{}})}var t=J.create({inlineRoot:{flex:1,minHeight:0,backgroundColor:Je.background.base},inlineHeader:{borderBottomWidth:1,borderBottomColor:Je.border.default,backgroundColor:"transparent"},container:{flex:1,backgroundColor:"transparent"},headerTextButton:{height:32,paddingHorizontal:12,borderRadius:8,backgroundColor:m.color.buttonSurface,borderWidth:1,borderColor:m.color.border,alignItems:"center",justifyContent:"center"},headerTextButtonLabel:{fontSize:12,fontWeight:"600",color:m.color.accent},headerActionButton:{width:32,height:32,borderRadius:8,backgroundColor:m.color.buttonSurface,borderWidth:1,borderColor:m.color.border,alignItems:"center",justifyContent:"center"},homeContainer:{flex:1,paddingHorizontal:12,paddingTop:16,paddingBottom:20,gap:12},homeSubtitle:{fontSize:12,fontWeight:"600",color:m.color.textTertiary,textTransform:"uppercase",letterSpacing:.5,textAlign:"center"},modeGrid:{flexDirection:"row",gap:10},modePanel:{flex:1,alignItems:"center",paddingVertical:20,paddingHorizontal:12,backgroundColor:m.color.surface,borderRadius:12,borderWidth:1,borderColor:m.color.border,gap:8},modeIconCircle:{width:48,height:48,borderRadius:24,alignItems:"center",justifyContent:"center",marginBottom:4},modePanelTitle:{fontSize:13,fontWeight:"700",color:m.color.text,textAlign:"center",lineHeight:17},modePanelDesc:{fontSize:11,color:m.color.textTertiary,textAlign:"center",lineHeight:15},controlsContainer:{flex:1,paddingTop:8,paddingBottom:24,gap:10},infoCard:{marginHorizontal:12,backgroundColor:m.color.surface,borderRadius:8,borderWidth:1,borderColor:m.color.border,padding:10,gap:4},infoRow:{flexDirection:"row",justifyContent:"space-between",alignItems:"center"},infoLabel:{fontSize:11,fontWeight:"500",color:m.color.textTertiary,textTransform:"uppercase",letterSpacing:.3},infoValue:{fontSize:12,fontWeight:"600",color:m.color.text},infoValueMono:{fontSize:12,fontWeight:"600",color:m.color.text,fontFamily:Mo},inputSection:{paddingHorizontal:12,gap:6},sectionLabel:{fontSize:11,fontWeight:"600",color:m.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},pasteButton:{paddingVertical:10,borderRadius:8,backgroundColor:m.color.accentSoft,borderWidth:1,borderColor:m.color.accentBorderStrong,alignItems:"center"},pasteButtonText:{fontSize:13,fontWeight:"600",color:m.color.accent},urlRow:{flexDirection:"row",gap:8},urlInput:{flex:1,height:36,borderRadius:10,backgroundColor:m.color.surfaceElevated,borderWidth:1,borderColor:m.color.border,paddingHorizontal:12,fontSize:13,color:m.color.text},loadButton:{height:36,paddingHorizontal:14,borderRadius:8,backgroundColor:m.color.accent,justifyContent:"center",alignItems:"center"},loadButtonDisabled:{opacity:.4},loadButtonText:{fontSize:13,fontWeight:"600",color:m.color.onAccent},toggleSection:{paddingHorizontal:12,gap:6},toggleRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:m.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:m.color.border,paddingHorizontal:12,paddingVertical:8},toggleLabel:{fontSize:13,fontWeight:"500",color:m.color.textSecondary},blendRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:m.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:m.color.border,paddingHorizontal:12,paddingVertical:6},blendButtons:{flexDirection:"row",gap:4},blendButton:{paddingHorizontal:10,paddingVertical:5,borderRadius:6,backgroundColor:"transparent"},blendButtonActive:{backgroundColor:m.color.accentSoft},blendButtonText:{fontSize:12,fontWeight:"600",color:m.color.textTertiary},blendButtonTextActive:{color:m.color.accent},actions:{flexDirection:"row",paddingHorizontal:12,gap:8,marginTop:4},actionButton:{flex:1,flexDirection:"row",alignItems:"center",justifyContent:"center",gap:6,paddingVertical:8,paddingHorizontal:12,borderRadius:8,backgroundColor:m.color.surfaceElevated,borderWidth:1,borderColor:m.color.border},actionButtonText:{fontSize:12,fontWeight:"500",color:m.color.textSecondary}});import{jsx as Ao}from"react/jsx-runtime";var Ho="#A855F7",Qe=Wo({id:"image-overlay",name:"IMG",description:"Design mockup overlay",slot:"both",icon:({size:e})=>Ao(Po,{size:e,color:Ho}),component:Me,props:{enableSharedModalDimensions:!1}}),ko=Bo(Qe,e=>({enableSharedModalDimensions:e.enableSharedModalDimensions??!1}));import{useState as ot,useEffect as Lo,useRef as et,useMemo as tt,useCallback as zo}from"react";import{absoluteFill as Do,monoFont as Eo}from"@buoy-gg/shared-ui/web";import{Fragment as rt,jsx as B,jsxs as Ve}from"react/jsx-runtime";function nt({uri:e,style:o,invertX:n,invertY:a}){let r=[];n&&r.push({scaleX:-1}),a&&r.push({scaleY:-1});let y=r.length>0?{transform:r}:{};return B(pe,{testID:"buoy-internal-image-overlay",source:{uri:e},style:[o,y],pointerEvents:"none"})}var ge=30;function Fo({imageUri:e,x:o,y:n,width:a,height:r,opacity:y,aspectRatio:T,invertX:h,invertY:b,locked:c}){let[v,L]=ot(!1),N=et({x:0,y:0}),u=et({x:0,y:0,width:0,height:0}),W=se.get("window"),H=tt(()=>ce.create({onStartShouldSetPanResponder:()=>!c,onMoveShouldSetPanResponder:(_,S)=>!c&&(Math.abs(S.dx)>2||Math.abs(S.dy)>2),onPanResponderTerminationRequest:()=>!1,onPanResponderGrant:()=>{let _=p.getState();N.current={x:_.freeX,y:_.freeY},L(!0)},onPanResponderMove:(_,S)=>{let E=p.getState(),k=Math.max(0,Math.min(N.current.x+S.dx,W.width-E.freeWidth)),A=Math.max(0,Math.min(N.current.y+S.dy,W.height-E.freeHeight));p.setFreePosition(k,A)},onPanResponderRelease:()=>L(!1),onPanResponderTerminate:()=>L(!1)}),[W.width,W.height,c]),D=zo(_=>ce.create({onStartShouldSetPanResponder:()=>!c,onMoveShouldSetPanResponder:()=>!c,onPanResponderTerminationRequest:()=>!1,onPanResponderGrant:()=>{let S=p.getState();u.current={x:S.freeX,y:S.freeY,width:S.freeWidth,height:S.freeHeight},L(!0)},onPanResponderMove:(S,E)=>{let{dx:k,dy:A}=E;if(Math.abs(k)<.5&&Math.abs(A)<.5)return;let x=u.current,z=T>0?T:x.width/x.height,ae=Math.abs(k),ie=Math.abs(A),d=ae>=ie,w,C,te=x.x,$=x.y;switch(_){case"bottomRight":{w=d?x.width+k:(x.height+A)*z,w=Math.max(ge,Math.min(w,W.width-x.x)),C=w/z;break}case"bottomLeft":{w=d?x.width-k:(x.height+A)*z,w=Math.max(ge,w),C=w/z,te=x.x+x.width-w,te=Math.max(0,te),w=Math.min(w,x.x+x.width),C=w/z;break}case"topRight":{w=d?x.width+k:(x.height-A)*z,w=Math.max(ge,Math.min(w,W.width-x.x)),C=w/z,$=x.y+x.height-C,$=Math.max(0,$),C=Math.min(C,x.y+x.height),w=C*z;break}case"topLeft":{w=d?x.width-k:(x.height-A)*z,w=Math.max(ge,w),C=w/z,te=x.x+x.width-w,$=x.y+x.height-C,te=Math.max(0,te),$=Math.max(0,$),w=Math.min(w,x.x+x.width),C=w/z,$=x.y+x.height-C;break}}w=Math.max(ge,Math.round(w)),C=Math.max(ge,Math.round(C)),p.setFreeDimensions(w,C,Math.round(te),Math.round($))},onPanResponderRelease:()=>L(!1),onPanResponderTerminate:()=>L(!1)}),[W.width,W.height,T,c]),U=tt(()=>({topLeft:D("topLeft"),topRight:D("topRight"),bottomLeft:D("bottomLeft"),bottomRight:D("bottomRight")}),[D]),ee={...Do,opacity:y};return Ve(l,{style:{position:"absolute",left:o,top:n,width:a,height:r},pointerEvents:c?"none":"auto",children:[B(l,{style:J.absoluteFill,...c?{}:H.panHandlers,children:B(nt,{uri:e,style:ee,invertX:h,invertY:b})}),B(l,{pointerEvents:"none",style:[P.freeBorder,v&&P.freeBorderActive,c&&P.freeBorderLocked]}),!c&&Ve(rt,{children:[B(l,{...U.topLeft.panHandlers,style:[P.cornerWrapper,{top:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:B(l,{style:[P.cornerHandle,v&&P.cornerHandleActive]})}),B(l,{...U.topRight.panHandlers,style:[P.cornerWrapper,{top:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:B(l,{style:[P.cornerHandle,v&&P.cornerHandleActive]})}),B(l,{...U.bottomLeft.panHandlers,style:[P.cornerWrapper,{bottom:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:B(l,{style:[P.cornerHandle,v&&P.cornerHandleActive]})}),B(l,{...U.bottomRight.panHandlers,style:[P.cornerWrapper,{bottom:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:B(l,{style:[P.cornerHandle,v&&P.cornerHandleActive]})})]})]})}function _o(){let[e,o]=ot(()=>p.getState());Lo(()=>p.subscribe(o),[]);let{mode:n,enabled:a,imageUri:r,imageWidth:y,imageHeight:T,targetRect:h,targetLabel:b,showOutline:c,opacity:v,scale:L,offsetX:N,offsetY:u,invertX:W,invertY:H,locked:D,freeX:U,freeY:ee,freeWidth:_,freeHeight:S}=e,E=y&&T&&T>0?y/T:0;if(n==="free"&&a&&r)return B(l,{style:P.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:B(Fo,{imageUri:r,x:U,y:ee,width:_,height:S,opacity:v,aspectRatio:E,invertX:W,invertY:H,locked:D})});if(!h)return null;let k=a&&r;return Ve(l,{style:P.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:[c&&Ve(rt,{children:[B(l,{pointerEvents:"none",nativeID:"__image_overlay_highlight__",style:[P.highlight,{left:h.x-3,top:h.y-3,width:h.width+6,height:h.height+6}]}),b&&B(l,{pointerEvents:"none",style:[P.label,{left:h.x,top:h.y-20}],children:B(g,{style:P.labelText,children:b})})]}),k&&(()=>{let A=(y??h.width)*L,x=(T??h.height)*L,z=h.x+h.width/2,ae=h.y+h.height/2,ie={position:"absolute",left:z-A/2+N,top:ae-x/2+u,width:A,height:x,opacity:v};return B(nt,{uri:r,style:ie,invertX:W,invertY:H})})()]})}var P=J.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:Eo},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}});export{p as ImageOverlayController,Me as ImageOverlayModal,_o as ImageOverlayStandalone,Vo as ImageOverlayToolView,ko as createImageOverlayTool,Qe as imageOverlayToolPreset,ne as scanForImageTargets,no as setDevToolsHookOverride};
1
+ "use client";var ke=Object.defineProperty;var et=Object.getOwnPropertyDescriptor;var tt=Object.getOwnPropertyNames;var ot=Object.prototype.hasOwnProperty;var nt=(e,o)=>{for(var n in o)ke(e,n,{get:o[n],enumerable:true})},He=(e,o,n,r)=>{if(o&&typeof o=="object"||typeof o=="function")for(let a of tt(o))!ot.call(e,a)&&a!==n&&ke(e,a,{get:()=>o[a],enumerable:!(r=et(o,a))||r.enumerable});return e},rt=(e,o,n)=>(He(e,o,"default"),n&&He(n,o,"default"));typeof window<"u"&&typeof globalThis.global>"u"&&(globalThis.global=globalThis);import{ImageOverlayIcon as at,createToolFactory as it,defineToolPreset as lt}from"@buoy-gg/shared-ui/web";var ie;function st(){return typeof navigator>"u"||!navigator.clipboard?null:{async hasImageAsync(){if(ie=void 0,!navigator.clipboard.read)return false;let e=await navigator.clipboard.read();for(let o of e){let n=o.types.find(r=>r.startsWith("image/"));if(n)return ie=await o.getType(n),true}return false},async getImageAsync(){if(!ie)return null;let e=ie;return ie=void 0,{data:await new Promise((o,n)=>{let r=new FileReader;r.onload=()=>o(String(r.result)),r.onerror=n,r.readAsDataURL(e)})}},getStringAsync:()=>navigator.clipboard.readText()}}function ct(){return null}import{useState as le,useEffect as Se,useCallback as oe}from"react";var Ae={};nt(Ae,{AccessibilityInfo:()=>gt,ActivityIndicator:()=>no,Alert:()=>se,Animated:()=>ft,AppRegistry:()=>mt,AppState:()=>yt,Appearance:()=>pt,BackHandler:()=>bt,Button:()=>ro,CheckBox:()=>kt,Clipboard:()=>xt,DeviceEventEmitter:()=>Ut,Dimensions:()=>pe,Easing:()=>vt,FlatList:()=>Ht,I18nManager:()=>wt,Image:()=>Te,ImageBackground:()=>At,InteractionManager:()=>Tt,Keyboard:()=>St,KeyboardAvoidingView:()=>Wt,LayoutAnimation:()=>Ct,Linking:()=>Rt,LogBox:()=>Nt,Modal:()=>to,NativeEventEmitter:()=>Bt,NativeModules:()=>ut,PanResponder:()=>me,Picker:()=>zt,PixelRatio:()=>Mt,Platform:()=>It,Pressable:()=>eo,ProgressBar:()=>Lt,RefreshControl:()=>Vt,SafeAreaView:()=>Dt,ScrollView:()=>ze,SectionList:()=>Et,Share:()=>Pt,StatusBar:()=>Ft,StyleSheet:()=>ne,Switch:()=>oo,Text:()=>u,TextInput:()=>Ce,Touchable:()=>Yt,TouchableHighlight:()=>Qt,TouchableNativeFeedback:()=>Xt,TouchableOpacity:()=>R,TouchableWithoutFeedback:()=>Zt,UIManager:()=>We,Vibration:()=>Ot,View:()=>s,VirtualizedList:()=>_t,YellowBox:()=>jt,findNodeHandle:()=>Le,unstable_createElement:()=>ht,useColorScheme:()=>$t,useLocaleContext:()=>Kt,useWindowDimensions:()=>qt});rt(Ae,dt);import*as dt from"react-native-web";import{unstable_createElement as ht,NativeModules as ut,AccessibilityInfo as gt,Animated as ft,Appearance as pt,AppRegistry as mt,AppState as yt,BackHandler as bt,Clipboard as xt,Dimensions as pe,Easing as vt,I18nManager as wt,Keyboard as St,InteractionManager as Tt,LayoutAnimation as Ct,Linking as Rt,NativeEventEmitter as Bt,PanResponder as me,PixelRatio as Mt,Platform as It,Share as Pt,StyleSheet as ne,UIManager as We,Vibration as Ot,CheckBox as kt,FlatList as Ht,Image as Te,ImageBackground as At,KeyboardAvoidingView as Wt,Picker as zt,ProgressBar as Lt,RefreshControl as Vt,SafeAreaView as Dt,SectionList as Et,StatusBar as Ft,Touchable as Yt,TouchableNativeFeedback as Xt,VirtualizedList as _t,YellowBox as jt,LogBox as Nt,DeviceEventEmitter as Ut,useColorScheme as $t,useLocaleContext as Kt,useWindowDimensions as qt}from"react-native-web";import*as E from"react-native-web";import{createElement as Gt,forwardRef as Jt}from"react";function j(e){let o=Jt((r,a)=>{let{accessibilityState:y,accessibilityValue:v,...p}=r;for(let b of["busy","checked","disabled","expanded","selected"])y?.[b]!==void 0&&p[`aria-${b}`]===void 0&&(p[`aria-${b}`]=y[b]);for(let[b,c]of Object.entries({min:"valuemin",max:"valuemax",now:"valuenow",text:"valuetext"}))v?.[b]!==void 0&&p[`aria-${c}`]===void 0&&(p[`aria-${c}`]=v[b]);return Gt(e,{...p,ref:a})}),n=e.State;return n&&Object.assign(o,{State:n}),o.displayName=e.displayName??e.name??"NativeWebView",o}var s=j(E.View),u=j(E.Text),Ce=j(E.TextInput),R=j(E.TouchableOpacity),Qt=j(E.TouchableHighlight),Zt=j(E.TouchableWithoutFeedback),eo=j(E.Pressable),ze=j(E.ScrollView),to=j(E.Modal),oo=j(E.Switch),no=j(E.ActivityIndicator),ro=j(E.Button),Le=E.findNodeHandle,se={alert(e,o,n,r){if(typeof document>"u")return;let a=document.createElement("dialog");a.dataset.buoyRoot="",a.setAttribute("aria-label",e),a.style.cssText="position:fixed;inset:0;margin:auto;width:min(440px,90vw);padding:24px;border:1px solid #475569;border-radius:14px;background:#17212e;color:#f1f5f9;font:14px system-ui;box-shadow:0 20px 80px #0008;z-index:2147483647";let y=document.createElement("h2");if(y.textContent=e,y.style.cssText="font-size:18px;margin:0 0 12px",a.appendChild(y),o){let c=document.createElement("p");c.textContent=o,c.style.cssText="line-height:1.5;white-space:pre-wrap;margin:0 0 20px",a.appendChild(c)}let v=document.createElement("div");v.style.cssText="display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px";let p=n?.length?n:[{text:"OK"}],b=()=>{a.close?.(),a.remove()};for(let c of p){let S=document.createElement("button");S.type="button",S.textContent=c.text??"OK",S.style.cssText=`padding:9px 14px;border:1px solid #64748b;border-radius:7px;color:white;background:${c.style==="destructive"?"#a52b38":"#283a4d"};cursor:pointer;font:inherit`,S.onclick=()=>{b(),c.onPress?.()},v.appendChild(S)}a.addEventListener("cancel",c=>{c.preventDefault(),r?.cancelable!==false&&(b(),r?.onDismiss?.())}),a.appendChild(v),document.body.appendChild(a),a.showModal?a.showModal():a.setAttribute("open","")}};import{JsModal as ao,ModalHeader as ye,macOSColors as Ve,night as f,Trash2 as io,SquareDashed as lo,Image as so,PowerToggleButton as co,windowDragProps as ho,ToggleRow as Re,monoFont as uo}from"@buoy-gg/shared-ui/web";function Be(e){return new Promise(o=>{try{let n=[];e&&n.push(e),e?.canonical?.publicInstance&&n.push(e.canonical.publicInstance),e?.canonical&&e.canonical!==e&&n.push(e.canonical);for(let r of n)if(typeof r.getBoundingClientRect=="function")try{let a=r.getBoundingClientRect();if(a&&typeof a.x=="number"&&typeof a.y=="number"&&typeof a.width=="number"&&typeof a.height=="number"&&a.width>0&&a.height>0){o({x:a.x,y:a.y,width:a.width,height:a.height});return}}catch{}for(let r of n)if(typeof r.measure=="function"){let a=setTimeout(()=>o(null),200);r.measure((y,v,p,b,c,S)=>{clearTimeout(a),c!=null&&S!=null&&p!=null&&b!=null&&p>0&&b>0?o({x:c,y:S,width:p,height:b}):o(null)});return}try{let r=Le(e);if(r!=null){let a=setTimeout(()=>o(null),200);We.measure(r,(y,v,p,b,c,S)=>{clearTimeout(a),c!=null&&S!=null&&p!=null&&b!=null&&p>0&&b>0?o({x:c,y:S,width:p,height:b}):o(null)});return}}catch{}o(null)}catch{o(null)}})}var De=null;function go(e){De=e??null}function Ee(){return De||(typeof globalThis>"u"?null:globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__??null)}var Fe="image-target:",fo=5,po=22;function mo(){let e=Ee();if(!e?.getFiberRoots)return[];let o=new Set,n=e.renderers?.keys?Array.from(e.renderers.keys()):[1];for(let r of n)try{e.getFiberRoots(r)?.forEach(a=>o.add(a))}catch{}return[...o]}function yo(e){return e.tag===po&&e.memoizedState!==null}function bo(e){return e.memoizedProps?.activityState===0}function ce(e,o,n=0,r=new Set){if(!(!e||r.has(e)||n>500)){if(r.add(e),yo(e)){e.sibling&&ce(e.sibling,o,n,r);return}if(bo(e)){e.sibling&&ce(e.sibling,o,n,r);return}o(e,n),e.child&&ce(e.child,o,n+1,r),e.sibling&&ce(e.sibling,o,n,r)}}function xo(e){let o=new Set(["View","RCTView","Text","RCTText","Image","RCTImageView","ScrollView","RCTScrollView","TextInput","RCTTextInput","TouchableOpacity","TouchableHighlight","TouchableWithoutFeedback","Pressable","FlatList","SectionList","SafeAreaView"]),n=e._debugOwner||e.return,r=0;for(;n&&r<30;){r++;let a=n.type;if(a){let y=typeof a=="string"?a:a.displayName||a.name;if(y&&!o.has(y))return y}n=n.return}return null}function de(){let e=mo();if(e.length===0)return[];let o=[];for(let n of e)ce(n.current,r=>{if(r.tag!==fo)return;let a=r.memoizedProps?.testID??r.pendingProps?.testID??r.memoizedProps?.["data-testid"]??r.pendingProps?.["data-testid"];if(!a||!a.startsWith(Fe))return;let y=a.slice(Fe.length);y&&o.push({label:y,testID:a,fiber:r,instance:r.stateNode,componentName:xo(r)})});return o}var Ye={mode:null,enabled:false,imageUri:null,imageWidth:null,imageHeight:null,targetTag:null,targetLabel:null,targetRect:null,showOutline:true,opacity:.5,scale:1,offsetX:0,offsetY:0,invertX:false,invertY:false,locked:false,freeX:0,freeY:0,freeWidth:200,freeHeight:200},i={...Ye},Me=new Set,K=null,be=null,he=false,ue=null,vo=null;function B(){for(let e of Me)e(i)}function wo(e){return e?typeof e._nativeTag=="number"?e._nativeTag:typeof e.canonical?._nativeTag=="number"?e.canonical._nativeTag:typeof e.__nativeTag=="number"?e.__nativeTag:null:null}async function Xe(e,o){let n=await Be(e);if(n)return{rect:n,freshInstance:e};let r=de().find(a=>a.label===o);return r&&(n=await Be(r.instance),n)?{rect:n,freshInstance:r.instance}:{rect:null,freshInstance:e}}function So(){if(ue)return;let e=Ee();if(e){if(e.rendererInterfaces)for(let[,o]of e.rendererInterfaces)typeof o.setTraceUpdatesEnabled=="function"&&o.setTraceUpdatesEnabled(true);typeof e.sub=="function"&&(ue=e.sub("traceUpdates",Ro))}}var re=null,Ie=false;function To(){if(re!==null||typeof requestAnimationFrame!="function")return;let e=()=>{re=requestAnimationFrame(e),!(Ie||!he||!K)&&(Ie=true,je().finally(()=>{Ie=false}))};re=requestAnimationFrame(e)}function Co(){re!==null&&typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(re),re=null}function _e(){Co(),ue&&(ue(),ue=null)}function Ro(e){!he||!K||je()}function je(){return Be(K).then(e=>{if(e&&i.targetRect){let o=i.targetRect;(Math.abs(e.x-o.x)>.5||Math.abs(e.y-o.y)>.5||Math.abs(e.width-o.width)>.5||Math.abs(e.height-o.height)>.5)&&(i={...i,targetRect:e},B())}}).catch(()=>{})}function Ne(e){return new Promise(o=>{Te.getSize(e,(n,r)=>o({width:n,height:r}),()=>o(null))})}var m={subscribe(e){return Me.add(e),e(i),()=>Me.delete(e)},getState(){return i},async setTarget(e,o,n){K=e,be=o;let r=n?.stateNode??e,{rect:a,freshInstance:y}=await Xe(r,o);K=y;let v=wo(K);i={...i,mode:"component",targetTag:v,targetLabel:o,targetRect:a},B()},async setImageUri(e){let o=await Ne(e),n=1;o&&i.targetRect&&o.width>0&&(n=i.targetRect.width/o.width),i={...i,imageUri:e,imageWidth:o?.width??null,imageHeight:o?.height??null,scale:n,showOutline:false},B()},setOpacity(e){i={...i,opacity:Math.max(0,Math.min(1,e))},B()},setScale(e){i={...i,scale:Math.max(.01,Math.min(5,e))},B()},setOffset(e,o){i={...i,offsetX:e,offsetY:o},B()},toggleInvertX(){i={...i,invertX:!i.invertX},B()},toggleInvertY(){i={...i,invertY:!i.invertY},B()},setLocked(e){i={...i,locked:e},B()},setAutoTrack(e){he=e,e?(So(),To()):_e()},isAutoTracking(){return he},setShowOutline(e){i={...i,showOutline:e},B()},setEnabled(e){i={...i,enabled:e},B()},toggle(){i={...i,enabled:!i.enabled},B()},fitWidth(){i.imageWidth&&i.targetRect&&i.imageWidth>0&&(i={...i,scale:i.targetRect.width/i.imageWidth},B())},fitHeight(){i.imageHeight&&i.targetRect&&i.imageHeight>0&&(i={...i,scale:i.targetRect.height/i.imageHeight},B())},resetSettings(){if(i.mode==="free"){let e=pe.get("window"),o=i.imageWidth??200,n=i.imageHeight??200;i={...i,opacity:.5,freeX:(e.width-o)/2,freeY:(e.height-n)/2,freeWidth:o,freeHeight:n}}else{let e=1;i.imageWidth&&i.targetRect&&i.imageWidth>0&&(e=i.targetRect.width/i.imageWidth),i={...i,opacity:.5,scale:e,offsetX:0,offsetY:0}}B()},async remeasure(){if(!be)return;let{rect:e,freshInstance:o}=await Xe(K,be);K=o,e&&(i={...i,targetRect:e},B())},async startFreeMode(e){let o=await Ne(e),n=pe.get("window"),r=o?.width??200,a=o?.height??200,y=r,v=a,p=n.width*.8,b=n.height*.6;if(y>p||v>b){let c=Math.min(p/y,b/v);y=Math.round(y*c),v=Math.round(v*c)}i={...i,mode:"free",enabled:true,imageUri:e,imageWidth:o?.width??null,imageHeight:o?.height??null,opacity:.5,freeX:Math.round((n.width-y)/2),freeY:Math.round((n.height-v)/2),freeWidth:Math.round(y),freeHeight:Math.round(v)},B()},setFreePosition(e,o){i={...i,freeX:e,freeY:o},B()},setFreeDimensions(e,o,n,r){i={...i,freeWidth:e,freeHeight:o,freeX:n,freeY:r},B()},reset(){_e(),he=false,vo=null,K=null,be=null,i={...Ye},B()}};import{ChevronRight as Bo,night as U,Hash as Mo,ToolEmptyState as Io,monoFont as Pe}from"@buoy-gg/shared-ui/web";import{jsx as $,jsxs as ge}from"react/jsx-runtime";function Po({target:e,onSelect:o}){return ge(R,{style:F.card,onPress:o,activeOpacity:.7,children:[$(s,{style:F.colorIndicator}),ge(s,{style:F.content,children:[$(s,{style:F.topRow,children:$(u,{style:F.label,numberOfLines:1,children:e.label})}),ge(s,{style:F.bottomRow,children:[ge(s,{style:F.badgeRow,children:[ge(s,{style:F.testIdBadge,children:[$(Mo,{size:8,color:U.color.accent}),$(u,{style:F.testIdBadgeText,children:"testID"})]}),$(u,{style:F.testIdValue,numberOfLines:1,children:e.testID})]}),e.componentName&&$(u,{style:F.componentName,numberOfLines:1,children:e.componentName})]})]}),$(Bo,{size:16,color:U.color.textTertiary})]})}function Oo({targets:e,onSelect:o}){return e.length===0?$(Io,{testID:"buoy-image-overlay-empty",otto:"scanning",title:"No targets found",message:`Tag components with
2
+ testID="image-target:YourLabel"`}):$(ze,{style:F.list,contentContainerStyle:F.listContent,children:e.map(n=>$(Po,{target:n,onSelect:()=>o(n)},n.testID))})}var F=ne.create({list:{flex:1},listContent:{paddingTop:8,paddingBottom:20},card:{flexDirection:"row",alignItems:"center",paddingVertical:10,paddingHorizontal:12,marginHorizontal:12,marginBottom:6,backgroundColor:U.color.surface,borderRadius:8,borderWidth:1,borderColor:U.color.border},colorIndicator:{width:4,height:36,borderRadius:2,marginRight:10,backgroundColor:U.color.accent},content:{flex:1,marginRight:8},topRow:{flexDirection:"row",alignItems:"center",marginBottom:4},label:{fontSize:13,fontWeight:"600",color:U.color.text,flex:1},bottomRow:{gap:2},badgeRow:{flexDirection:"row",alignItems:"center",gap:4},testIdBadge:{flexDirection:"row",alignItems:"center",paddingVertical:2,paddingHorizontal:5,borderRadius:4,backgroundColor:U.color.accentSoft,gap:3},testIdBadgeText:{fontSize:9,fontWeight:"700",color:U.color.accent},testIdValue:{fontSize:11,color:U.color.text,fontFamily:Pe,flex:1},componentName:{fontSize:10,color:"#a855f7",fontFamily:Pe,marginTop:1},emptyState:{alignItems:"center",paddingVertical:40,paddingHorizontal:32},emptyTitle:{color:U.color.text,fontSize:14,fontWeight:"600",marginBottom:6},emptyText:{color:U.color.textTertiary,fontSize:12,textAlign:"center",lineHeight:18,fontFamily:Pe}});import{useRef as Q,useCallback as xe}from"react";import{night as q,monoFont as ko}from"@buoy-gg/shared-ui/web";import{jsx as V,jsxs as ve}from"react/jsx-runtime";function fe({label:e,value:o,min:n,max:r,step:a,displayValue:y,onChange:v}){let p=Q(0),b=Q(0),c=xe(T=>Math.max(n,Math.min(r,T)),[n,r]),S=r>n?(o-n)/(r-n):0,A=Q(v),X=Q(c),h=Q(n),P=Q(r);A.current=v,X.current=c,h.current=n,P.current=r;let O=xe(T=>{let L=T-b.current,k=Math.max(0,Math.min(1,L/p.current)),H=h.current+k*(P.current-h.current);A.current(X.current(H))},[]),z=Q(me.create({onStartShouldSetPanResponder:()=>true,onMoveShouldSetPanResponder:()=>true,onPanResponderTerminationRequest:()=>false,onPanResponderGrant:T=>{O(T.nativeEvent.pageX)},onPanResponderMove:T=>{O(T.nativeEvent.pageX)}})).current,_=xe(T=>{p.current=T.nativeEvent.layout.width},[]),G=Q(null),D=xe(()=>{G.current?.measure?.((T,L,k,H,x)=>{b.current=x})},[]);return ve(s,{style:Y.controlRow,children:[V(u,{style:Y.label,children:e}),ve(s,{style:Y.controlRight,children:[V(R,{style:Y.stepperButton,onPress:()=>v(c(o-a)),activeOpacity:.6,children:V(u,{style:Y.stepperButtonText,children:"-"})}),V(s,{style:Y.sliderHitArea,...z.panHandlers,children:ve(s,{ref:G,style:Y.sliderTrack,onLayout:T=>{_(T),D()},pointerEvents:"none",children:[V(s,{style:[Y.sliderFill,{width:`${S*100}%`}]}),V(s,{style:[Y.sliderThumb,{left:`${S*100}%`}]})]})}),V(R,{style:Y.stepperButton,onPress:()=>v(c(o+a)),activeOpacity:.6,children:V(u,{style:Y.stepperButtonText,children:"+"})}),V(u,{style:Y.valueText,children:y})]})]})}function Ue({opacity:e,scale:o,offsetX:n,offsetY:r,onOpacityChange:a,onScaleChange:y,onOffsetChange:v,opacityOnly:p}){return p?V(fe,{label:"Opacity",value:e,min:0,max:1,step:.05,displayValue:`${Math.round(e*100)}%`,onChange:a}):ve(s,{style:Y.container,children:[V(fe,{label:"Opacity",value:e,min:0,max:1,step:.05,displayValue:`${Math.round(e*100)}%`,onChange:a}),V(fe,{label:"Scale",value:o,min:.05,max:3,step:.05,displayValue:`${Math.round(o*100)}%`,onChange:y}),V(fe,{label:"Offset X",value:n,min:-200,max:200,step:2,displayValue:`${Math.round(n)}px`,onChange:b=>v(Math.round(b),r)}),V(fe,{label:"Offset Y",value:r,min:-200,max:200,step:2,displayValue:`${Math.round(r)}px`,onChange:b=>v(n,Math.round(b))})]})}var Y=ne.create({container:{gap:8},controlRow:{paddingHorizontal:12,gap:4},label:{fontSize:11,fontWeight:"600",color:q.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},controlRight:{flexDirection:"row",alignItems:"center",gap:6},stepperButton:{width:28,height:28,borderRadius:6,backgroundColor:q.color.surfaceElevated,borderWidth:1,borderColor:q.color.border,justifyContent:"center",alignItems:"center"},stepperButtonText:{fontSize:16,fontWeight:"700",color:q.color.text,lineHeight:18},sliderHitArea:{flex:1,paddingVertical:20,paddingHorizontal:40,marginVertical:-20,marginHorizontal:-40},sliderTrack:{height:28,justifyContent:"center",borderRadius:6,backgroundColor:q.color.bg,borderWidth:1,borderColor:q.color.border,overflow:"hidden"},sliderFill:{position:"absolute",left:0,top:0,bottom:0,backgroundColor:q.color.accentFill,borderRadius:5},sliderThumb:{position:"absolute",width:4,top:4,bottom:4,marginLeft:-2,borderRadius:2,backgroundColor:q.color.accent},valueText:{fontSize:11,fontWeight:"600",color:q.color.text,width:45,textAlign:"right",fontFamily:ko}});import{Fragment as $e,jsx as l,jsxs as g}from"react/jsx-runtime";var Z="";function Oe({visible:e,onClose:o,onBack:n,onMinimize:r,enableSharedModalDimensions:a=false,initialModalState:y,minimizeTargetPosition:v,inline:p=false,initialView:b}){let[c,S]=le(()=>{if(b)return b;let d=m.getState();return d.mode==="free"?"free":d.targetRect?"controls":"idle"}),[A,X]=le(()=>b==="targets"?de():[]),[h,P]=le(()=>m.getState()),[O,z]=le(Z),[_,G]=le(()=>m.isAutoTracking());Se(()=>{Z=O},[O]),Se(()=>m.subscribe(P),[]),Se(()=>(m.setAutoTrack(_),()=>{}),[_]);let D=oe(()=>{let d=de();X(d),S("targets")},[]),T=oe(async d=>{await m.setTarget(d.instance,d.label,d.fiber),Z.trim()&&(await m.setImageUri(Z.trim()),m.setEnabled(true)),S("controls")},[]),L=oe(async()=>{let d=Z.trim();d&&(c==="free"?await m.startFreeMode(d):(await m.setImageUri(d),m.setEnabled(true)))},[c]),k=oe(async()=>{let d=null;try{d=st()}catch{}let w=null;if(!d)try{let C=ct();w=C.default||C}catch{}if(!d&&!w){se.alert("Clipboard not available","Install expo-clipboard or @react-native-clipboard/clipboard to use paste.");return}try{if(d&&typeof d.hasImageAsync=="function"&&await d.hasImageAsync()){let N=await d.getImageAsync({format:"png"});if(N?.data){c==="free"?await m.startFreeMode(N.data):(await m.setImageUri(N.data),m.setEnabled(true));return}}let C=null;if(d&&typeof d.getStringAsync=="function"?C=await d.getStringAsync():w&&typeof w.getString=="function"&&(C=await w.getString()),C&&(C.startsWith("http")||C.startsWith("data:"))){z(C),Z=C;return}d?se.alert("No image detected","Try saving your design image, opening it in Photos or Preview, and copying it from there."):se.alert("Image paste requires expo-clipboard","Your project uses @react-native-clipboard/clipboard which only supports text. Install expo-clipboard to paste images directly, or paste an image URL instead.")}catch{se.alert("Paste failed","Something went wrong reading the clipboard. Try copying the image again.")}},[c]),H=oe(()=>{m.reset(),Z="",S("idle"),z(""),X([])},[]),x=oe(()=>{if(c==="controls"){let d=de();X(d),S("targets")}else(c==="targets"||c==="free")&&m.reset(),S("idle")},[c]),W=(()=>{switch(c){case"targets":return`Targets (${A.length})`;case"controls":return h.targetLabel||"Component Match";case"free":return"Free Placement";default:return"Image Overlay"}})(),ee={showToggleButton:false,customContent:g(ye,{children:[l(ye.Navigation,{onBack:c!=="idle"?x:n}),l(ye.Content,{title:W}),g(ye.Actions,{children:[c==="targets"&&l(R,{style:t.headerTextButton,onPress:D,activeOpacity:.7,children:l(u,{style:t.headerTextButtonLabel,children:"Scan"})}),(c==="controls"||c==="free")&&h.imageUri&&l(co,{isEnabled:h.enabled,onToggle:()=>m.toggle(),accessibilityLabel:"Toggle image overlay"}),c!=="idle"&&l(R,{style:t.headerActionButton,onPress:H,activeOpacity:.7,children:l(io,{size:14,color:f.color.textSecondary})})]})]})},te=g(s,{style:t.container,children:[c==="idle"&&g(s,{style:t.homeContainer,children:[l(u,{style:t.homeSubtitle,children:"Choose a mode"}),g(s,{style:t.modeGrid,children:[g(R,{style:t.modePanel,onPress:D,activeOpacity:.7,children:[l(s,{style:[t.modeIconCircle,{backgroundColor:f.color.accentSoft}],children:l(lo,{size:24,color:f.color.accent})}),g(u,{style:t.modePanelTitle,children:["Component",`
3
+ `,"Match"]}),l(u,{style:t.modePanelDesc,children:"Overlay on a tagged component"})]}),g(R,{style:t.modePanel,onPress:()=>S("free"),activeOpacity:.7,children:[l(s,{style:[t.modeIconCircle,{backgroundColor:f.color.accentSoft}],children:l(so,{size:24,color:f.color.accent})}),g(u,{style:t.modePanelTitle,children:["Free",`
4
+ `,"Placement"]}),l(u,{style:t.modePanelDesc,children:"Drag and resize anywhere"})]})]})]}),c==="targets"&&l(Oo,{targets:A,onSelect:T}),c==="controls"&&g(s,{style:t.controlsContainer,children:[h.targetRect&&g(s,{style:t.infoCard,children:[g(s,{style:t.infoRow,children:[l(u,{style:t.infoLabel,children:"Component"}),l(u,{style:t.infoValue,children:h.targetLabel})]}),g(s,{style:t.infoRow,children:[l(u,{style:t.infoLabel,children:"Size"}),g(u,{style:t.infoValueMono,children:[Math.round(h.targetRect.width)," x ",Math.round(h.targetRect.height)]})]}),g(s,{style:t.infoRow,children:[l(u,{style:t.infoLabel,children:"Position"}),g(u,{style:t.infoValueMono,children:[Math.round(h.targetRect.x),", ",Math.round(h.targetRect.y)]})]}),h.imageWidth!=null&&h.imageHeight!=null&&g(s,{style:t.infoRow,children:[l(u,{style:t.infoLabel,children:"Image"}),g(u,{style:t.infoValueMono,children:[h.imageWidth," x ",h.imageHeight]})]})]}),g(s,{style:t.inputSection,children:[l(u,{style:t.sectionLabel,children:"Image"}),l(R,{style:t.pasteButton,onPress:k,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",children:l(u,{style:t.pasteButtonText,children:"Paste from Clipboard"})}),g(s,{style:t.urlRow,children:[l(Ce,{style:t.urlInput,value:O,onChangeText:z,placeholder:"or enter URL...",placeholderTextColor:f.color.placeholder,autoCapitalize:"none",autoCorrect:false,returnKeyType:"go",onSubmitEditing:L}),l(R,{style:[t.loadButton,!O.trim()&&t.loadButtonDisabled],onPress:L,disabled:!O.trim(),activeOpacity:.7,children:l(u,{style:t.loadButtonText,children:"Load"})})]})]}),g(s,{style:t.toggleSection,children:[l(Re,{label:"Show Outline",value:h.showOutline,onValueChange:d=>m.setShowOutline(d)}),l(Re,{label:"Auto Track",value:_,onValueChange:G}),h.imageUri&&g($e,{children:[g(s,{style:t.blendRow,children:[l(u,{style:t.toggleLabel,children:"Opacity"}),l(s,{style:t.blendButtons,children:[0,25,50,75,100].map(d=>l(R,{style:[t.blendButton,Math.round(h.opacity*100)===d&&t.blendButtonActive],onPress:()=>m.setOpacity(d/100),activeOpacity:.7,children:g(u,{style:[t.blendButtonText,Math.round(h.opacity*100)===d&&t.blendButtonTextActive],children:[d,"%"]})},d))})]}),g(s,{style:t.blendRow,children:[l(u,{style:t.toggleLabel,children:"Flip"}),g(s,{style:t.blendButtons,children:[l(R,{style:[t.blendButton,h.invertX&&t.blendButtonActive],onPress:()=>m.toggleInvertX(),activeOpacity:.7,children:l(u,{style:[t.blendButtonText,h.invertX&&t.blendButtonTextActive],children:"Horizontal"})}),l(R,{style:[t.blendButton,h.invertY&&t.blendButtonActive],onPress:()=>m.toggleInvertY(),activeOpacity:.7,children:l(u,{style:[t.blendButtonText,h.invertY&&t.blendButtonTextActive],children:"Vertical"})})]})]})]})]}),h.imageUri&&l(Ue,{opacity:h.opacity,scale:h.scale,offsetX:h.offsetX,offsetY:h.offsetY,onOpacityChange:d=>m.setOpacity(d),onScaleChange:d=>m.setScale(d),onOffsetChange:(d,w)=>m.setOffset(d,w)}),g(s,{style:t.actions,children:[l(R,{style:t.actionButton,onPress:()=>m.resetSettings(),activeOpacity:.7,children:l(u,{style:t.actionButtonText,children:"Reset Settings"})}),l(R,{style:t.actionButton,onPress:()=>m.remeasure(),activeOpacity:.7,children:l(u,{style:t.actionButtonText,children:"Remeasure"})})]})]}),c==="free"&&g(s,{style:t.controlsContainer,children:[g(s,{style:t.inputSection,children:[l(u,{style:t.sectionLabel,children:"Image"}),l(R,{style:t.pasteButton,onPress:k,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",children:l(u,{style:t.pasteButtonText,children:"Paste from Clipboard"})}),g(s,{style:t.urlRow,children:[l(Ce,{style:t.urlInput,value:O,onChangeText:z,placeholder:"or enter URL...",placeholderTextColor:f.color.placeholder,autoCapitalize:"none",autoCorrect:false,returnKeyType:"go",onSubmitEditing:L}),l(R,{style:[t.loadButton,!O.trim()&&t.loadButtonDisabled],onPress:L,disabled:!O.trim(),activeOpacity:.7,children:l(u,{style:t.loadButtonText,children:"Load"})})]})]}),h.imageUri&&h.mode==="free"&&g($e,{children:[g(s,{style:t.infoCard,children:[g(s,{style:t.infoRow,children:[l(u,{style:t.infoLabel,children:"Position"}),g(u,{style:t.infoValueMono,children:[Math.round(h.freeX),", ",Math.round(h.freeY)]})]}),g(s,{style:t.infoRow,children:[l(u,{style:t.infoLabel,children:"Size"}),g(u,{style:t.infoValueMono,children:[Math.round(h.freeWidth)," x ",Math.round(h.freeHeight)]})]}),h.imageWidth!=null&&h.imageHeight!=null&&g(s,{style:t.infoRow,children:[l(u,{style:t.infoLabel,children:"Original"}),g(u,{style:t.infoValueMono,children:[h.imageWidth," x ",h.imageHeight]})]})]}),l(s,{style:t.inputSection,children:l(Ue,{opacity:h.opacity,scale:1,offsetX:0,offsetY:0,onOpacityChange:d=>m.setOpacity(d),onScaleChange:()=>{},onOffsetChange:()=>{},opacityOnly:true})}),g(s,{style:t.toggleSection,children:[l(Re,{label:"Lock Position",tone:"warning",value:h.locked,onValueChange:d=>m.setLocked(d)}),g(s,{style:t.blendRow,children:[l(u,{style:t.toggleLabel,children:"Opacity"}),l(s,{style:t.blendButtons,children:[0,25,50,75,100].map(d=>l(R,{style:[t.blendButton,Math.round(h.opacity*100)===d&&t.blendButtonActive],onPress:()=>m.setOpacity(d/100),activeOpacity:.7,children:g(u,{style:[t.blendButtonText,Math.round(h.opacity*100)===d&&t.blendButtonTextActive],children:[d,"%"]})},d))})]}),g(s,{style:t.blendRow,children:[l(u,{style:t.toggleLabel,children:"Flip"}),g(s,{style:t.blendButtons,children:[l(R,{style:[t.blendButton,h.invertX&&t.blendButtonActive],onPress:()=>m.toggleInvertX(),activeOpacity:.7,children:l(u,{style:[t.blendButtonText,h.invertX&&t.blendButtonTextActive],children:"Horizontal"})}),l(R,{style:[t.blendButton,h.invertY&&t.blendButtonActive],onPress:()=>m.toggleInvertY(),activeOpacity:.7,children:l(u,{style:[t.blendButtonText,h.invertY&&t.blendButtonTextActive],children:"Vertical"})})]})]})]}),l(s,{style:t.actions,children:l(R,{style:t.actionButton,onPress:()=>m.resetSettings(),activeOpacity:.7,children:l(u,{style:t.actionButtonText,children:"Reset Position"})})})]})]})]});return p?g(s,{style:t.inlineRoot,children:[l(s,{style:t.inlineHeader,...ho,children:ee.customContent}),te]}):l(ao,{visible:e,onClose:o,onMinimize:r,minimizeTargetPosition:v,initialModalState:y,header:ee,initialMode:"bottomSheet",persistenceKey:"buoy-image-overlay-modal",enablePersistence:true,children:te})}function Ho(e={}){return l(Oe,{...e,inline:true,visible:true,onClose:()=>{}})}var t=ne.create({inlineRoot:{flex:1,minHeight:0,backgroundColor:Ve.background.base},inlineHeader:{borderBottomWidth:1,borderBottomColor:Ve.border.default,backgroundColor:"transparent"},container:{flex:1,backgroundColor:"transparent"},headerTextButton:{height:32,paddingHorizontal:12,borderRadius:8,backgroundColor:f.color.buttonSurface,borderWidth:1,borderColor:f.color.border,alignItems:"center",justifyContent:"center"},headerTextButtonLabel:{fontSize:12,fontWeight:"600",color:f.color.accent},headerActionButton:{width:32,height:32,borderRadius:8,backgroundColor:f.color.buttonSurface,borderWidth:1,borderColor:f.color.border,alignItems:"center",justifyContent:"center"},homeContainer:{flex:1,paddingHorizontal:12,paddingTop:16,paddingBottom:20,gap:12},homeSubtitle:{fontSize:12,fontWeight:"600",color:f.color.textTertiary,textTransform:"uppercase",letterSpacing:.5,textAlign:"center"},modeGrid:{flexDirection:"row",gap:10},modePanel:{flex:1,alignItems:"center",paddingVertical:20,paddingHorizontal:12,backgroundColor:f.color.surface,borderRadius:12,borderWidth:1,borderColor:f.color.border,gap:8},modeIconCircle:{width:48,height:48,borderRadius:24,alignItems:"center",justifyContent:"center",marginBottom:4},modePanelTitle:{fontSize:13,fontWeight:"700",color:f.color.text,textAlign:"center",lineHeight:17},modePanelDesc:{fontSize:11,color:f.color.textTertiary,textAlign:"center",lineHeight:15},controlsContainer:{flex:1,paddingTop:8,paddingBottom:24,gap:10},infoCard:{marginHorizontal:12,backgroundColor:f.color.surface,borderRadius:8,borderWidth:1,borderColor:f.color.border,padding:10,gap:4},infoRow:{flexDirection:"row",justifyContent:"space-between",alignItems:"center"},infoLabel:{fontSize:11,fontWeight:"500",color:f.color.textTertiary,textTransform:"uppercase",letterSpacing:.3},infoValue:{fontSize:12,fontWeight:"600",color:f.color.text},infoValueMono:{fontSize:12,fontWeight:"600",color:f.color.text,fontFamily:uo},inputSection:{paddingHorizontal:12,gap:6},sectionLabel:{fontSize:11,fontWeight:"600",color:f.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},pasteButton:{paddingVertical:10,borderRadius:8,backgroundColor:f.color.accentSoft,borderWidth:1,borderColor:f.color.accentBorderStrong,alignItems:"center"},pasteButtonText:{fontSize:13,fontWeight:"600",color:f.color.accent},urlRow:{flexDirection:"row",gap:8},urlInput:{flex:1,height:36,borderRadius:10,backgroundColor:f.color.surfaceElevated,borderWidth:1,borderColor:f.color.border,paddingHorizontal:12,fontSize:13,color:f.color.text},loadButton:{height:36,paddingHorizontal:14,borderRadius:8,backgroundColor:f.color.accent,justifyContent:"center",alignItems:"center"},loadButtonDisabled:{opacity:.4},loadButtonText:{fontSize:13,fontWeight:"600",color:f.color.onAccent},toggleSection:{paddingHorizontal:12,gap:6},toggleRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:f.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:f.color.border,paddingHorizontal:12,paddingVertical:8},toggleLabel:{fontSize:13,fontWeight:"500",color:f.color.textSecondary},blendRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:f.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:f.color.border,paddingHorizontal:12,paddingVertical:6},blendButtons:{flexDirection:"row",gap:4},blendButton:{paddingHorizontal:10,paddingVertical:5,borderRadius:6,backgroundColor:"transparent"},blendButtonActive:{backgroundColor:f.color.accentSoft},blendButtonText:{fontSize:12,fontWeight:"600",color:f.color.textTertiary},blendButtonTextActive:{color:f.color.accent},actions:{flexDirection:"row",paddingHorizontal:12,gap:8,marginTop:4},actionButton:{flex:1,flexDirection:"row",alignItems:"center",justifyContent:"center",gap:6,paddingVertical:8,paddingHorizontal:12,borderRadius:8,backgroundColor:f.color.surfaceElevated,borderWidth:1,borderColor:f.color.border},actionButtonText:{fontSize:12,fontWeight:"500",color:f.color.textSecondary}});import{jsx as Ao}from"react/jsx-runtime";var Wo="#A855F7",Ke=lt({id:"image-overlay",name:"IMG",description:"Design mockup overlay",slot:"both",icon:({size:e})=>Ao(at,{size:e,color:Wo}),component:Oe,props:{enableSharedModalDimensions:false}}),zo=it(Ke,e=>({enableSharedModalDimensions:e.enableSharedModalDimensions??false}));import{useState as qe,useEffect as Lo,useRef as Ge,useMemo as Je,useCallback as Vo}from"react";import{absoluteFill as Do,monoFont as Eo}from"@buoy-gg/shared-ui/web";import{Fragment as Qe,jsx as I,jsxs as we}from"react/jsx-runtime";function Ze({uri:e,style:o,invertX:n,invertY:r}){let a=[];n&&a.push({scaleX:-1}),r&&a.push({scaleY:-1});let y=a.length>0?{transform:a}:{};return I(Te,{testID:"buoy-internal-image-overlay",source:{uri:e},style:[o,y],pointerEvents:"none"})}var ae=30;function Fo({imageUri:e,x:o,y:n,width:r,height:a,opacity:y,aspectRatio:v,invertX:p,invertY:b,locked:c}){let[S,A]=qe(false),X=Ge({x:0,y:0}),h=Ge({x:0,y:0,width:0,height:0}),P=pe.get("window"),O=Je(()=>me.create({onStartShouldSetPanResponder:()=>!c,onMoveShouldSetPanResponder:(D,T)=>!c&&(Math.abs(T.dx)>2||Math.abs(T.dy)>2),onPanResponderTerminationRequest:()=>false,onPanResponderGrant:()=>{let D=m.getState();X.current={x:D.freeX,y:D.freeY},A(true)},onPanResponderMove:(D,T)=>{let L=m.getState(),k=Math.max(0,Math.min(X.current.x+T.dx,P.width-L.freeWidth)),H=Math.max(0,Math.min(X.current.y+T.dy,P.height-L.freeHeight));m.setFreePosition(k,H)},onPanResponderRelease:()=>A(false),onPanResponderTerminate:()=>A(false)}),[P.width,P.height,c]),z=Vo(D=>me.create({onStartShouldSetPanResponder:()=>!c,onMoveShouldSetPanResponder:()=>!c,onPanResponderTerminationRequest:()=>false,onPanResponderGrant:()=>{let T=m.getState();h.current={x:T.freeX,y:T.freeY,width:T.freeWidth,height:T.freeHeight},A(true)},onPanResponderMove:(T,L)=>{let{dx:k,dy:H}=L;if(Math.abs(k)<.5&&Math.abs(H)<.5)return;let x=h.current,W=v>0?v:x.width/x.height,ee=Math.abs(k),te=Math.abs(H),d=ee>=te,w,C,N=x.x,J=x.y;switch(D){case"bottomRight":{w=d?x.width+k:(x.height+H)*W,w=Math.max(ae,Math.min(w,P.width-x.x)),C=w/W;break}case"bottomLeft":{w=d?x.width-k:(x.height+H)*W,w=Math.max(ae,w),C=w/W,N=x.x+x.width-w,N=Math.max(0,N),w=Math.min(w,x.x+x.width),C=w/W;break}case"topRight":{w=d?x.width+k:(x.height-H)*W,w=Math.max(ae,Math.min(w,P.width-x.x)),C=w/W,J=x.y+x.height-C,J=Math.max(0,J),C=Math.min(C,x.y+x.height),w=C*W;break}case"topLeft":{w=d?x.width-k:(x.height-H)*W,w=Math.max(ae,w),C=w/W,N=x.x+x.width-w,J=x.y+x.height-C,N=Math.max(0,N),J=Math.max(0,J),w=Math.min(w,x.x+x.width),C=w/W,J=x.y+x.height-C;break}}w=Math.max(ae,Math.round(w)),C=Math.max(ae,Math.round(C)),m.setFreeDimensions(w,C,Math.round(N),Math.round(J))},onPanResponderRelease:()=>A(false),onPanResponderTerminate:()=>A(false)}),[P.width,P.height,v,c]),_=Je(()=>({topLeft:z("topLeft"),topRight:z("topRight"),bottomLeft:z("bottomLeft"),bottomRight:z("bottomRight")}),[z]),G={...Do,opacity:y};return we(s,{style:{position:"absolute",left:o,top:n,width:r,height:a},pointerEvents:c?"none":"auto",children:[I(s,{style:ne.absoluteFill,...c?{}:O.panHandlers,children:I(Ze,{uri:e,style:G,invertX:p,invertY:b})}),I(s,{pointerEvents:"none",style:[M.freeBorder,S&&M.freeBorderActive,c&&M.freeBorderLocked]}),!c&&we(Qe,{children:[I(s,{..._.topLeft.panHandlers,style:[M.cornerWrapper,{top:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:I(s,{style:[M.cornerHandle,S&&M.cornerHandleActive]})}),I(s,{..._.topRight.panHandlers,style:[M.cornerWrapper,{top:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:I(s,{style:[M.cornerHandle,S&&M.cornerHandleActive]})}),I(s,{..._.bottomLeft.panHandlers,style:[M.cornerWrapper,{bottom:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:I(s,{style:[M.cornerHandle,S&&M.cornerHandleActive]})}),I(s,{..._.bottomRight.panHandlers,style:[M.cornerWrapper,{bottom:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:I(s,{style:[M.cornerHandle,S&&M.cornerHandleActive]})})]})]})}function Yo(){let[e,o]=qe(()=>m.getState());Lo(()=>m.subscribe(o),[]);let{mode:n,enabled:r,imageUri:a,imageWidth:y,imageHeight:v,targetRect:p,targetLabel:b,showOutline:c,opacity:S,scale:A,offsetX:X,offsetY:h,invertX:P,invertY:O,locked:z,freeX:_,freeY:G,freeWidth:D,freeHeight:T}=e,L=y&&v&&v>0?y/v:0;if(n==="free"&&r&&a)return I(s,{style:M.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:I(Fo,{imageUri:a,x:_,y:G,width:D,height:T,opacity:S,aspectRatio:L,invertX:P,invertY:O,locked:z})});if(!p)return null;let k=r&&a;return we(s,{style:M.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:[c&&we(Qe,{children:[I(s,{pointerEvents:"none",nativeID:"__image_overlay_highlight__",style:[M.highlight,{left:p.x-3,top:p.y-3,width:p.width+6,height:p.height+6}]}),b&&I(s,{pointerEvents:"none",style:[M.label,{left:p.x,top:p.y-20}],children:I(u,{style:M.labelText,children:b})})]}),k&&(()=>{let H=(y??p.width)*A,x=(v??p.height)*A,W=p.x+p.width/2,ee=p.y+p.height/2,te={position:"absolute",left:W-H/2+X,top:ee-x/2+h,width:H,height:x,opacity:S};return I(Ze,{uri:a,style:te,invertX:P,invertY:O})})()]})}var M=ne.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:Eo},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}});export{m as ImageOverlayController,Oe as ImageOverlayModal,Yo as ImageOverlayStandalone,Ho as ImageOverlayToolView,zo as createImageOverlayTool,Ke as imageOverlayToolPreset,de as scanForImageTargets,go as setDevToolsHookOverride};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buoy-gg/image-overlay",
3
- "version": "7.0.41",
3
+ "version": "7.0.42",
4
4
  "description": "Overlay a design mockup on a running React Native app and adjust opacity to compare spacing and alignment.",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
@@ -34,7 +34,7 @@
34
34
  ],
35
35
  "sideEffects": false,
36
36
  "dependencies": {
37
- "@buoy-gg/shared-ui": "^7.0.41"
37
+ "@buoy-gg/shared-ui": "^7.0.42"
38
38
  },
39
39
  "peerDependencies": {
40
40
  "react": "*",
@@ -1 +0,0 @@
1
- {"version":3,"file":"ImageOverlayModal.d.ts","sourceRoot":"","sources":["../../../../src/imageOverlay/components/ImageOverlayModal.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,sBAAsB,EAAkC,MAAM,UAAU,CAAC;AAMvF,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;AAKjE,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,OAAO,EACP,MAAM,EACN,UAAU,EACV,2BAAmC,EACnC,iBAAiB,EACjB,sBAAsB,EACtB,MAAc,EACd,WAAW,GACZ,EAAE,sBAAsB,+BAwiBxB;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,GAAE,IAAI,CAAC,sBAAsB,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAM,+BAG3E"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ImageOverlayStandalone.d.ts","sourceRoot":"","sources":["../../../../src/imageOverlay/components/ImageOverlayStandalone.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAA4D,MAAM,OAAO,CAAC;AA2NjF,wBAAgB,sBAAsB,IAAI,KAAK,CAAC,YAAY,GAAG,IAAI,CAuFlE"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"OverlayControls.d.ts","sourceRoot":"","sources":["../../../../src/imageOverlay/components/OverlayControls.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAmIH,UAAU,oBAAoB;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,cAAc,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,gCAAgC;IAChC,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAgB,eAAe,CAAC,EAC9B,OAAO,EACP,KAAK,EACL,OAAO,EACP,OAAO,EACP,eAAe,EACf,aAAa,EACb,cAAc,EACd,WAAW,GACZ,EAAE,oBAAoB,+BAuDtB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"TargetList.d.ts","sourceRoot":"","sources":["../../../../src/imageOverlay/components/TargetList.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAwCjD,UAAU,eAAe;IACvB,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,QAAQ,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;CAC9C;AAED,wBAAgB,UAAU,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,eAAe,+BAwBhE"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/imageOverlay/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,YAAY;IAC3B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,MAAM,GAAG,IAAI,CAAC;AACtD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,YAAY,GAAG,IAAI,CAAC;IAChC,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAEhB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,GAAG,CAAC;IACX,QAAQ,EAAE,GAAG,CAAC;IACd,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3C,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC,iBAAiB,CAAC,EAAE,GAAG,CAAC;IACxB,sBAAsB,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClD,gFAAgF;IAChF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,kFAAkF;IAClF,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;IACvD,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ImageOverlayController.d.ts","sourceRoot":"","sources":["../../../../src/imageOverlay/utils/ImageOverlayController.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAgB,YAAY,EAAE,MAAM,UAAU,CAAC;AAK3D,KAAK,QAAQ,GAAG,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;AAsK9C,eAAO,MAAM,sBAAsB;wBACb,QAAQ,GAAG,MAAM,IAAI;gBAM7B,YAAY;wBAME,GAAG,SAAS,MAAM,UAAU,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;qBAmBlD,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;sBAmB3B,MAAM;oBAKR,MAAM;iBAKT,MAAM,KAAK,MAAM;;;sBAeZ,OAAO;0BAKH,OAAO;sBAUX,OAAO;yBAIJ,OAAO;wBAKR,OAAO;;;;;iBA+CR,OAAO,CAAC,IAAI,CAAC;uBAYP,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;uBAkC5B,MAAM,KAAK,MAAM;6BAKX,MAAM,UAAU,MAAM,KAAK,MAAM,KAAK,MAAM;;CAgBtE,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"componentMeasurement.d.ts","sourceRoot":"","sources":["../../../../src/imageOverlay/utils/componentMeasurement.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,GAAG,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAoG3E"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"devtoolsHook.d.ts","sourceRoot":"","sources":["../../../../src/imageOverlay/utils/devtoolsHook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAE3D;AAED,wBAAgB,eAAe,IAAI,GAAG,CAIrC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"fiberScanner.d.ts","sourceRoot":"","sources":["../../../../src/imageOverlay/utils/fiberScanner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAkFjD;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,gBAAgB,EAAE,CAmCxD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"imageClipboard.d.ts","sourceRoot":"","sources":["../../../../src/imageOverlay/utils/imageClipboard.ts"],"names":[],"mappings":"AAAA,wBAAgB,kBAAkB,IAAI,GAAG,CAAqE;AAC9G,wBAAgB,iBAAiB,IAAI,GAAG,CAAwH"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"imageClipboard.web.d.ts","sourceRoot":"","sources":["../../../../src/imageOverlay/utils/imageClipboard.web.ts"],"names":[],"mappings":"AACA,wBAAgB,kBAAkB;;;;;;SAuBjC;AACD,wBAAgB,iBAAiB,IAAI,IAAI,CAAiB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAK1E,OAAO,EACL,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,kDAAkD,CAAC;AAK1F,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AAKrF,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AAK5E,YAAY,EACV,sBAAsB,EACtB,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,gBAAgB,GACjB,MAAM,sBAAsB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"preset.d.ts","sourceRoot":"","sources":["../../src/preset.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAC;AAEhF,eAAO,MAAM,wBAAwB,YAAY,CAAC;AAElD,eAAO,MAAM,sBAAsB;;;;;qBAKhB;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE;;;;;CAOjC,CAAC;AAEH,eAAO,MAAM,sBAAsB;IAG/B,qCAAqC;kCACP,OAAO;;;;;;qBAbtB;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE;;;;;CAiBlC,CAAC"}