react-native-mask-segment-c.../dist/components/MaskSegmentCanvas.js
a1518 8bc66a4ee9
Some checks failed
Publish to npm / publish (push) Has been cancelled
refactor: remove Chinese, add build obfuscation, polish README
- Remove all Chinese characters from src/, example/, ios/, patches/, tests/
- Add esbuild-based build obfuscation (minify + identifier mangle + no sourcemaps)
- Drop src/ from npm publish, only ship minified dist/
- Remove source maps and declaration maps from build output
- Add README icons and visual polish throughout
- Fix broken Table of Contents anchor links in README

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-01 19:07:32 -07:00

2 lines
24 KiB
JavaScript

"use strict";var Ct=Object.create;var Rn=Object.defineProperty;var bt=Object.getOwnPropertyDescriptor;var vt=Object.getOwnPropertyNames;var Mt=Object.getPrototypeOf,xt=Object.prototype.hasOwnProperty;var It=(w,M)=>{for(var H in M)Rn(w,H,{get:M[H],enumerable:!0})},Vr=(w,M,H,Ke)=>{if(M&&typeof M=="object"||typeof M=="function")for(let re of vt(M))!xt.call(w,re)&&re!==H&&Rn(w,re,{get:()=>M[re],enumerable:!(Ke=bt(M,re))||Ke.enumerable});return w};var Bt=(w,M,H)=>(H=w!=null?Ct(Mt(w)):{},Vr(M||!w||!w.__esModule?Rn(H,"default",{value:w,enumerable:!0}):H,w)),Ft=w=>Vr(Rn({},"__esModule",{value:!0}),w);var Ot={};It(Ot,{default:()=>Lt});module.exports=Ft(Ot);var f=require("react/jsx-runtime"),e=require("react"),ne=require("react-native"),ee=require("react-native-gesture-handler"),U=require("react-native-reanimated"),Kr=Bt(require("../utils/opencvAdapter")),E=require("../utils/maskSegmentation"),Zr=require("../utils/wallTextureSplit"),Z=require("../utils/pngImage"),Me=require("../utils/resolveImageUrl"),Xr=require("../utils/compositePaintedImage"),Ve=require("../utils/exportUtils"),yn=require("../utils/freqLayerPrep"),$e=require("../utils/paintShaderRuntime"),h=require("../utils/maskSegmentRuntime"),d=require("@shopify/react-native-skia"),c=require("../utils/canvasGeometry");const Et=(0,e.forwardRef)(function(M,H){const{originUrl:Ke,maskUrl:re,originImgPath:Yr,maskImgPath:jr,maskConfig:kn,pipelinePreset:Yn,pipelineConfig:jn,paintConfig:wn,interactionConfig:Sn,semanticColors:Pn,regionOutlineColor:Cn,initialSession:xe,initialPaintColor:Qr,initialPaintConfigJson:et,disabled:Ie=!1,style:nt,onWatch:bn,onPaintCallback:vn,onError:Mn,autoExportOnReady:Qn,onExported:xn}=M,te=Ke??Yr??"",oe=re??jr??"",In=(0,e.useMemo)(()=>Pn?{...kn,semanticColors:Pn}:kn,[kn,Pn]),Ze=(0,e.useMemo)(()=>Cn?{...wn,regionOverlayFill:Cn}:wn,[wn,Cn]),[Be,er]=(0,e.useState)(""),[Fe,nr]=(0,e.useState)(""),[A,rt]=(0,e.useState)(Be),[z,tt]=(0,e.useState)(Fe),rr=(0,e.useRef)(""),tr=(0,e.useRef)(""),Xe=(0,e.useMemo)(()=>(0,h.resolvePipelineConfig)(Yn,jn),[Yn,jn]),Bn=(0,e.useRef)((0,h.createRuntimeConfig)({maskConfig:In,pipelineConfig:Xe,paintConfig:Ze,interactionConfig:Sn})),or=(0,e.useRef)(null),sr=(0,e.useRef)(null);(0,e.useEffect)(()=>{const n=or.current,t=Ze||{},r=!n||["colorBaseOpacity","lLightOpacity","textureOpacity","lLowBlurKernel","lLowContrast","lLowBrightness","lHighGain","maskFeatherColor","maskFeatherTexture","regionOverlayFill"].some(s=>t[s]!==n[s]),i=JSON.stringify(Xe),a=sr.current!==i;(r||a)&&(r&&(or.current={...t}),a&&(sr.current=i),Bn.current=(0,h.setMaskSegmentRuntimeConfig)({maskConfig:In,pipelineConfig:Xe,paintConfig:Ze,interactionConfig:Sn}))},[In,Xe,Ze,Sn]);const ir=Bn.current.paint.palette,ar=(0,h.getMaskSegmentRuntimeConfig)().paint,Wt=(0,h.getMaskSegmentRuntimeConfig)().interaction,cr=(0,e.useRef)(bn),Fn=(0,e.useRef)(vn),En=(0,e.useRef)(Mn),ur=(0,e.useRef)(xn);(0,e.useEffect)(()=>{cr.current=bn,Fn.current=vn,En.current=Mn,ur.current=xn},[bn,vn,Mn,xn]);const Ln=(0,e.useRef)(0),lr=(0,e.useRef)(null),On=(0,e.useRef)(null),P=(0,e.useCallback)((n,t)=>{const o=[n,t?.regionCount??"",t?.maskPathsReady??"",t?.freqLayersReady??"",t?.errorMessage??""].join("|");if(On.current===o)return;On.current=o,lr.current=n;const r=Ln.current?performance.now()-Ln.current:0;cr.current?.(n,r,t)},[]),ae=(0,e.useCallback)((n,t)=>{P("error",{errorMessage:n}),En.current?En.current(n,t):__DEV__&&console.error("[MaskSegment]",n,t)},[P]),[ce,fr]=(0,e.useState)(Qr??null),ue=(0,e.useRef)(et),gr=(0,e.useRef)(te),mr=(0,e.useRef)(oe);(0,e.useEffect)(()=>{gr.current=te,mr.current=oe},[te,oe]),(0,e.useEffect)(()=>{let n=!1;if(!te||!oe){er(""),nr("");return}return(async()=>{try{const[t,o]=await Promise.all([(0,Me.resolveImageUrl)(te,`origin_${(0,Me.hashUrl)(te)}.png`),(0,Me.resolveImageUrl)(oe,`mask_${(0,Me.hashUrl)(oe)}.png`)]);n||(er(t),nr(o))}catch(t){if(!n){const o=t instanceof Error?t.message:String(t);ae(o,t)}}})(),()=>{n=!0}},[te,oe,ae]),(0,e.useEffect)(()=>{rt(Be),tt(Fe),Be&&Fe&&(0,Z.prewarmPngBgrCache)([Be,Fe])},[Be,Fe]),(0,e.useEffect)(()=>{rr.current=A||"",tr.current=z||""},[A,z]);const[Ye,je]=(0,e.useState)(null),C=(0,e.useRef)(null),le=(0,e.useRef)(null),[Qe,Wn]=(0,e.useState)(null),[y,Ee]=(0,e.useState)(()=>new Map),R=(0,e.useRef)(new Map),[dr,Le]=(0,e.useState)([]);R.current=y;const[fe,ge]=(0,e.useState)(null),[An,me]=(0,e.useState)(null),[pr,en]=(0,e.useState)(null),L=(0,e.useRef)(null),Oe=(0,e.useRef)(0),X=(0,e.useRef)(!1),We=(0,e.useRef)([]),nn=(0,e.useRef)(!1);(0,e.useEffect)(()=>{R.current=y},[y]);const Ae=(0,e.useRef)(null),_=(0,e.useRef)(null),rn=(0,e.useRef)(!1),k=(0,e.useRef)([]),zn=(0,e.useRef)(null),ze=(0,e.useRef)(null),De=(0,e.useRef)(null),tn=(0,e.useRef)(null),Y=(0,e.useRef)(null),hr=(0,e.useRef)(()=>Promise.resolve()),[q,Dn]=(0,e.useState)(!1),[on,de]=(0,e.useState)(!1),sn=(0,e.useRef)(null),Tn=(0,e.useRef)(null),[pe,Rr]=(0,e.useState)([]),[yr,kr]=(0,e.useState)(0),[x,ot]=(0,e.useState)(null),wr=(0,d.useCanvasRef)(),[J,Sr]=(0,e.useState)(null),[st,Pr]=(0,e.useState)(!1),[Te,it]=(0,e.useState)(null),[m,Cr]=(0,e.useState)(!1),he=(0,e.useRef)(!1),Re=(0,e.useRef)(!1),[br,vr]=(0,e.useState)(!1),[Mr,xr]=(0,e.useState)(!1),Hn=(0,e.useRef)(!1),[an,Ir]=(0,e.useState)(null),He=(0,e.useRef)(null),j=Ye?.lowFreqImage??null,cn=Ye?.highFreqImage??null,I=Te?.w??1,B=Te?.h??1,at=Te!=null&&Te.w>0&&Te.h>0,N=(0,e.useRef)(I),G=(0,e.useRef)(B),[_e,Br]=(0,e.useState)(1),[qe,_n]=(0,e.useState)({x:0,y:0}),D=(0,e.useRef)(1),V=(0,e.useRef)({x:0,y:0}),Fr=(0,e.useRef)(1),Er=(0,e.useRef)({x:0,y:0}),Lr=(0,e.useRef)({x:0,y:0}),qn=(0,e.useRef)({x:0,y:0}),Un=(0,e.useRef)(null);(0,e.useEffect)(()=>{D.current=_e},[_e]),(0,e.useEffect)(()=>{V.current=qe},[qe]);const ct=(0,e.useCallback)((n,t)=>{n<=0||t<=0||(N.current=n,G.current=t,it(o=>o?.w===n&&o?.h===t?o:{w:n,h:t}))},[]),$=(0,e.useCallback)(()=>{Br(1),_n({x:0,y:0}),D.current=1,V.current={x:0,y:0}},[]),g=(0,e.useMemo)(()=>x?(0,c.getContainRect)(I,B,x.w,x.h):null,[x,I,B]);(0,e.useEffect)(()=>{Un.current=g},[g]);const T=(0,e.useRef)(0),un=(0,e.useRef)(""),ye=(0,e.useRef)(""),ke=(0,e.useRef)(null);(0,e.useEffect)(()=>{C.current=Ye},[Ye]),(0,e.useEffect)(()=>{he.current=m},[m]),(0,e.useEffect)(()=>{Re.current=on},[on]);const Or=(0,e.useCallback)(()=>{!he.current||!C.current||P("layers_ready",{regionCount:k.current.length,maskPathsReady:Re.current,freqLayersReady:!0})},[P]),ln=(0,e.useCallback)(()=>{!he.current||!Re.current||P("mask_paths_ready",{regionCount:k.current.length,maskPathsReady:!0,freqLayersReady:!0})},[P]),Ue=(0,e.useCallback)(()=>{!he.current||!C.current||(Or(),P("interactive",{regionCount:k.current.length,maskPathsReady:Re.current,freqLayersReady:!0}),vr(!0))},[P,Or]),fn=(0,e.useMemo)(()=>{const n=ze.current;if(le.current?.dispose(),!n||y.size===0)return le.current=null,null;const t=(0,$e.createPaintColorMapForPaint)(n.buffer,n.cols,n.rows,y);return le.current=t,t},[y,q,m,(0,h.getMaskRuntimeRevision)()]),se=(0,e.useRef)(new Map),gn=(0,e.useCallback)(async(n,t)=>{const o=++T.current,r=()=>{if(o===T.current)return!1;const u=rr.current||n,l=tr.current||t;return!(u===n&&l===t)},i=(0,h.getMaskSegmentRuntimeConfig)().pipeline;Ln.current=performance.now(),lr.current=null,On.current=null,P("init"),(0,c.timeLog)("\u25B6 start segmentation"),he.current=!1,Cr(!1),Wn(null);const a=new Map;R.current=a,Ee(a),Le([]),ge(null),me(null),en(null),X.current=!1,Oe.current=0,We.current=[],L.current&&(clearTimeout(L.current),L.current=null),nn.current=!1,Ae.current=null,_.current&&(clearTimeout(_.current),_.current=null),rn.current=!1,k.current=[],zn.current=null,ze.current=null,De.current=null,tn.current=null,Y.current=null,Se(new Map),de(!1),Dn(!1),sn.current=null,Tn.current=null,ke.current=null,Rr([]),kr(0),Sr(null),Pr(!1);const s=C.current;s&&((0,c.releasePaintResourceLayers)(s),C.current=null,je(null)),(0,c.releaseOriginSkImage)(He.current),He.current=null,Ir(null);try{(0,c.timeLog)("\u25B6 reading origin PNG");const u=(0,Z.readPngBgrBuffer)(n);(0,c.timeLog)("\u25B6 reading mask PNG");const l=(0,Z.readPngBgrBuffer)(t),p=await u;if(r())return;const b=p.cols,v=p.rows;ot({w:b,h:v});let S=1;Math.max(b,v)>i.maxImageLongSide&&(S=i.maxImageLongSide/Math.max(b,v));const Ce=Math.floor(b*S),be=Math.floor(v*S),Q=i.minContourArea*S*S,yt=(0,c.prepareWorkScaledBgrBuffer)(p.buffer,b,v,S).then(F=>(r()||(tn.current=F,Sr({w:F.cols,h:F.rows}),Pr(!0),hr.current()),F)),kt=l.then(async F=>{if(r())throw new Error("cancelled");(0,c.timeLog)("\u25B6 PNG read completed"),P("images_loaded"),(0,c.timeLog)(`\u25B6 image size: ${b}x${v}`);const{buffer:ve,cols:pn,rows:hn}=F,Ge=(0,Z.resizeBgrBuffer)(ve,pn,hn,Ce,be);return(0,c.timeLog)(`\u25B6 mask scale: ${S.toFixed(3)}`),P("mask_aligned"),(0,E.extractRegionsFromMaskBufferSync)(Ge,Ce,be,{minArea:Q,approxEpsilon:i.contourApproxEpsilon})});l.then(async F=>{const{buffer:ve,cols:pn,rows:hn}=F;let Ge;pn!==b||hn!==v?Ge=await Kr.default.resizeBgrBuffer(ve,pn,hn,b,v):Ge=new Uint8Array(ve),o===T.current&&(zn.current={buffer:Ge,cols:b,rows:v})});const[wt,St]=await Promise.all([kt,yt]);if(r())return;let W=wt;(0,h.getMaskSegmentRuntimeConfig)().mask.splitWalls&&(W=(0,Zr.splitWallRegionsByTexture)(W,St.buffer,Ce,be,Q));const Pt=Y.current??Promise.resolve();P("mask_sampled",{regionCount:W.regions.length}),(0,c.timeLog)(`\u25B6 segmentation completed, valid regions: ${W.regions.length}`);const Nr=W.regions;__DEV__&&Nr.length===0&&console.warn("[MaskSegment] not recognized any valid regions, please check if the mask is a pure color region image");let K=Nr;K.length>i.maxRegions&&(K=K.slice(0,i.maxRegions)),k.current=K,ze.current=W.pickMap,De.current={labels:W.labels,baseboardBinary:W.baseboardBinary,cols:W.segCols,rows:W.segRows,wallSubLabels:W.wallSubLabels},sn.current=null,Tn.current=K.find(F=>F.thinStrip)?.id??null;const Gr=(0,c.getContainRect)(N.current,G.current,b,v);ke.current=Gr,Se(new Map),de(!1),Rr(K),kr(K.length),un.current=`${n}|${t}`,he.current=!0,Cr(!0),P("regions_ready",{regionCount:K.length}),Ue(),(async()=>{if(o!==T.current)return;const F=(0,E.downsampleMaskDataForPaths)(De.current,i.maskPathMaxLongSide),ve=(0,E.buildAllRegionOutlinePaths)(K,F,Gr);o===T.current&&(Se(ve),de(!0),Re.current=!0,ln())})(),(async()=>o===T.current&&(await Pt,o===T.current&&(sn.current=(0,E.upscaleBinaryMask)(W.baseboardBinary,Ce,be,b,v))))()}catch(u){const l=u instanceof Error?u.message:String(u);r()||(console.error("[SDK-SEGMENT] segmentation failed",u),ae(l,u))}},[P,Ue,ln,ae]),Jn=(0,e.useCallback)(()=>{if(C.current)return Promise.resolve();if(Y.current)return Y.current;const n=tn.current;if(!n)return Promise.resolve();const t=T.current;let o;return o=(async()=>{(0,c.timeLog)("\u25B6 start loading paint shader textures");try{const r=await(0,yn.preparePaintResourcesFromWorkBuffer)(n.buffer,n.cols,n.rows,i=>{if(t!==T.current){(0,yn.releaseFreqLayerImages)(i);return}je(i),C.current=i,Dn(!0),(0,c.timeLog)("\u25B6 paint shader textures ready"),Ue()});if(t!==T.current){r&&(r.originImage.dispose(),(0,c.releasePaintResourceLayers)(r.layers));return}if(!r)return;(0,c.releaseOriginSkImage)(He.current),He.current=r.originImage,Ir(r.originImage),(0,c.timeLog)("\u25B6 origin Skia work resolution"),C.current||(je(r.layers),C.current=r.layers,Dn(!0)),Ue()}catch(r){__DEV__&&console.warn("[MaskSegment] failed to prepare paint shader textures",r)}finally{Y.current===o&&(Y.current=null)}})(),Y.current=o,o},[Ue]);hr.current=Jn;const Wr=(0,e.useCallback)(async()=>{if(!(Hn.current||!A||!z)){Hn.current=!0;try{$();const n=C.current;n&&((0,c.releasePaintResourceLayers)(n),C.current=null,je(null)),await(0,Z.clearDerivedImageCache)(),un.current="",await gn(A,z)}catch(n){const t=n instanceof Error?n.message:String(n);ae(t,n)}finally{Hn.current=!1}}},[A,z,gn,ae,$]);(0,e.useEffect)(()=>{if(!A||!z)return;const n=`${A}|${z}`;if(!(un.current===n||ye.current===n))return $(),ye.current=n,gn(A,z).finally(()=>{ye.current===n&&(ye.current="")}),()=>{T.current+=1,ye.current===n&&(ye.current="");const t=C.current;t&&((0,c.releasePaintResourceLayers)(t),C.current=null),le.current?.dispose(),le.current=null,k.current=[],We.current=[],X.current=!1,Oe.current=0,L.current&&(clearTimeout(L.current),L.current=null),en(null)}},[A,z,$]);const Nn=(0,e.useCallback)(()=>{const n=[],t=R.current&&R.current.size>0?R.current:y;for(const[o,r]of t){const i=k.current.find(a=>a.id===o);n.push({regionId:o,regionName:i?.name??String(o),color:r,configJson:se.current.get(o)})}return n},[y]),mn=(0,e.useCallback)(n=>{const t=new Map;se.current=new Map;const o=k.current||[],r=new Map;for(const s of o)if(s&&s.name){const u=String(s.name).trim().toLowerCase();u&&!r.has(u)&&r.set(u,s.id)}const i=new Map;for(const s of n.painted||[])s&&typeof s.regionId=="number"&&s.regionName&&i.set(s.regionId,String(s.regionName));for(const s of n.painted||[]){if(!s)continue;let u=s.regionId;if(s.regionName){const l=String(s.regionName).trim().toLowerCase(),p=r.get(l);typeof p=="number"&&(u=p)}t.set(u,s.color),s.configJson&&se.current.set(u,s.configJson)}const a=[];for(const s of n.paintHistory||[]){if(typeof s!="number")continue;const u=i.get(s);if(u){const l=r.get(String(u).trim().toLowerCase());if(typeof l=="number"){a.push(l);continue}}o.some(l=>l&&l.id===s)&&a.push(s)}R.current=t,Ee(t),Le(a.length?a:[...n.paintHistory||[]]),n.currentColor&&(fr(n.currentColor),ue.current=n.currentColorConfigJson,Wn(null))},[]);(0,e.useEffect)(()=>{!xe||!m||nn.current||(nn.current=!0,mn(xe))},[xe,m,mn]),(0,e.useEffect)(()=>()=>{L.current&&clearTimeout(L.current)},[]);const ie=(0,e.useCallback)(()=>{X.current=!1,L.current&&(clearTimeout(L.current),L.current=null),en(null)},[]),Ar=(0,e.useCallback)(()=>{const n=(0,h.getMaskSegmentRuntimeConfig)().interaction;if(!n.enableInitRegionFlash||X.current)return;const t=k.current;if(t.length===0)return;const o=we.current,r=o?Math.max(500,o.w*o.h*.002):500;We.current=t.filter(a=>!R.current.has(a.id)&&a.area>=r),X.current=!0,Oe.current=0;const i=()=>{if(!X.current||We.current.length===0)return;const a=We.current,s=Oe.current;if(s>=a.length){ie();return}en(a[s].id),Oe.current+=1,L.current=setTimeout(i,n.initRegionFlashMs)};i()},[]),O=(0,e.useCallback)(()=>{ie()},[ie]);(0,e.useEffect)(()=>{X.current&&R.current.size>0&&ie()},[y,ie]),(0,e.useEffect)(()=>{if(m&&on&&g&&yr>0&&br){X.current||Ar();return}m||(ie(),vr(!1))},[m,on,g,yr,br,Ar,ie]);const zr=(0,e.useCallback)(()=>ce||(Qe==null?null:ir[Qe]??null),[ce,Qe,ir]),Je=ce!=null||Qe!=null,Dr=(0,e.useCallback)((n,t)=>{let o=!1;if(Ee(r=>{const i=r.get(n);if(i&&(0,c.bgrColorEquals)(i,t))return r;o=!0,Le(s=>s[s.length-1]===n?s:[...s.filter(l=>l!==n),n]);const a=new Map(r);return a.set(n,t),R.current=a,a}),o){const r=ue.current??se.current.get(n);ue.current&&se.current.set(n,ue.current);const i=k.current.find(a=>a.id===n);Fn.current?.({kind:"painted",regionId:n,regionName:i?.name??String(n),color:t,configJson:r})}},[]),Ne=(0,e.useCallback)((n,t,o=!1)=>{if(!m||!x||k.current.length===0)return null;const r=(0,c.canvasToNormalized)(n,t,I,B,x.w,x.h);if(!r)return null;const i=ze.current;if(i){const u=(0,c.lookupRegionFromPickMap)(r.x,r.y,i,o?0:(0,h.getMaskSegmentRuntimeConfig)().interaction.pickMapSearchRadiusPx);if(u!=null)return u;if(o)return null}const a=zn.current,s=Tn.current;if(!o){const u=(0,c.resolveRegionHit)(k.current,r.x,r.y);if(u!=null)return u}if(a&&s!=null){const u=sn.current,l=(0,c.pickKickRegionFromMask)(r.x,r.y,a,s,u,o);if(l!=null)return l;if(!o){const p=k.current.find(Pe=>Pe.id===s);if(p&&(0,c.pickKickNearStrip)(r.x,r.y,p))return s}}return null},[m,x,I,B]),Gn=(0,e.useCallback)((n,t)=>{if(O(),!m||!x||k.current.length===0||!Je||!q||Ie)return;const o=Ne(n,t);if(o==null)return;const r=zr();r&&(Dr(o,r),!q&&!Y.current&&Jn())},[m,x,Je,q,Ie,Ne,zr,Dr,O,Jn]),Vn=(0,e.useRef)(Je),Tr=(0,e.useRef)(Ie),Hr=(0,e.useRef)(m),we=(0,e.useRef)(x);(0,e.useEffect)(()=>{N.current=I},[I]),(0,e.useEffect)(()=>{G.current=B},[B]),(0,e.useEffect)(()=>{Vn.current=Je},[Je]),(0,e.useEffect)(()=>{Tr.current=Ie},[Ie]),(0,e.useEffect)(()=>{Hr.current=m},[m]),(0,e.useEffect)(()=>{we.current=x},[x]);const $n=(0,e.useRef)(Ne),Kn=(0,e.useRef)(Gn),_r=(0,e.useRef)(O),Zn=(0,e.useRef)($);(0,e.useEffect)(()=>{$n.current=Ne},[Ne]),(0,e.useEffect)(()=>{Kn.current=Gn},[Gn]),(0,e.useEffect)(()=>{_r.current=O},[O]),(0,e.useEffect)(()=>{Zn.current=$},[$]);const Xn=(0,e.useCallback)(()=>{O(),Le(n=>{if(n.length===0)return n;const t=n[n.length-1];return Ee(o=>{const r=new Map(o);return r.delete(t),R.current=r,r}),se.current.delete(t),n.slice(0,-1)})},[O]),qr=(0,e.useCallback)(()=>{O();const n=new Map;R.current=n,Ee(n),Le([]),se.current=new Map,Ae.current=null,$()},[O,$]),Ur=(0,e.useCallback)(async()=>{try{const n=wr.current;if(!n||!J)return;let o=n.makeImageSnapshot?.();if(o||(await new Promise(a=>requestAnimationFrame(()=>a())),o=n.makeImageSnapshot?.()),!o)return;const r=o.encodeToBase64;if(typeof r!="function")return;const i=r.call(o)||"";return i.length>0?i:void 0}catch(n){console.warn("[VIZ-SAVE] highResExportCanvas makeImageSnapshot failed:",n);return}},[J]),dn=(0,e.useCallback)(async(n,t)=>{const o=tn.current,r=ze.current;if(!o||!r)throw new Error("image not ready, cannot save");let i;n.size>0&&(i=await Ur());const a=C.current,s=le.current,u=He.current??a?.lowFreqImage??null,l=!i&&u&&a&&s&&q?{originImage:u,paintColorMap:s,lowFreqImage:a.lowFreqImage,highFreqImage:a.highFreqImage}:void 0,p=await(0,Xr.compositePaintedImage)({originBuffer:o.buffer,cols:o.cols,rows:o.rows,pickBuffer:r.buffer,paintedRegions:n,destDir:t,...i?{exportPngBase64:i}:{},shaderTextures:l,renderWidth:o.cols,renderHeight:o.rows});return Ae.current={fingerprint:(0,Ve.paintedRegionsFingerprint)(n),result:p},p},[Ur,q]);(0,e.useEffect)(()=>{if(Qn&&!(!m||!q)&&!(xe&&!nn.current)&&y.size!==0)return _.current&&clearTimeout(_.current),_.current=setTimeout(()=>{if(_.current=null,rn.current)return;const n=R.current;!n||n.size===0||(rn.current=!0,(async()=>{try{const t=await dn(n);ur.current?.(t)}catch(t){console.log("[VIZ-SAVE] debounced autoExport threw (non-fatal):",t)}finally{rn.current=!1}})())},400),()=>{_.current&&(clearTimeout(_.current),_.current=null)}},[Qn,m,q,xe,y,dn]),(0,e.useImperativeHandle)(H,()=>({reset:Xn,swap:n=>{O(),xr(n===void 0?t=>!t:n)},save:async n=>{const t=R.current&&R.current.size>0?R.current:y,o=(0,Ve.paintedRegionsFingerprint)(t),r=Ae.current;if(r?.fingerprint===o&&r.result)return(0,Ve.resolveExportResultForDestDir)(r.result,n?.destDir);try{return await dn(t,n?.destDir)}catch(i){throw console.error("[VIZ-SAVE] SDK save() composite threw:",i),i}},getLastExport:()=>Ae.current?.result??null,session:()=>({version:1,originUrl:gr.current,maskUrl:mr.current,painted:Nn(),paintHistory:[...dr],currentColor:ce??void 0,currentColorConfigJson:ue.current,savedAt:Date.now()}),loadSession:mn,setPaintColor:(n,t)=>{fr(n),ue.current=t,Wn(null)},setMaskConfig:n=>{(0,h.setMaskSegmentRuntimeConfig)({maskConfig:n}),Bn.current=(0,h.getMaskSegmentRuntimeConfig)(),A&&z&&(un.current="",gn(A,z))},clearAllPaint:qr,undoSelection:Xn,resegment:Wr,getRegions:()=>[...k.current],getPaintedRegions:()=>Nn()}),[Xn,O,y,dr,ce,Nn,mn,qr,Wr,dn]);const[ut,Se]=(0,e.useState)(new Map);(0,e.useEffect)(()=>{if(!m||!g||pe.length===0){m||(Se(new Map),de(!1),ke.current=null);return}const n=De.current;if(!n){Se(new Map),de(!1);return}if(ke.current&&(0,c.rectsEqual)(ke.current,g))return;const t=__DEV__?performance.now():0,o=(0,E.downsampleMaskDataForPaths)(n,(0,h.getMaskSegmentRuntimeConfig)().pipeline.maskPathMaxLongSide),r=(0,E.buildAllRegionOutlinePaths)(pe,o,g);ke.current=g,Se(r),de(!0),Re.current=!0,ln()},[m,g,pe,ln]);const At=(0,e.useMemo)(()=>{if(fe==null||An==null||!g||pe.length===0)return null;const n=De.current;if(!n)return null;const t=(0,E.downsampleMaskDataForPaths)(n,(0,h.getMaskSegmentRuntimeConfig)().pipeline.maskPathMaxLongSide);return(0,E.buildRegionOutlinePathForRegion)(fe,pe,t,g,An)},[fe,An,g,pe]),lt=(n,t=1)=>!n||!g?null:(0,f.jsx)(d.Image,{image:n,x:g.x,y:g.y,width:g.w,height:g.h,opacity:t}),Jr=(n,t)=>{const o=ut.get(n);return!o||!g?null:(0,f.jsxs)(f.Fragment,{children:[(0,f.jsx)(d.Path,{path:o,color:ar.regionOverlayFill,style:"fill",opacity:.05},`${t}-fill-${n}`),(0,f.jsx)(d.Path,{path:o,color:ar.regionOverlayFill,style:"stroke",strokeWidth:3,strokeJoin:"round",antiAlias:!0,children:(0,f.jsx)(d.DashPathEffect,{intervals:[8,6]})},`${t}-stroke-${n}`)]})},ft=(0,e.useMemo)(()=>{if(!(_e<=1))return(0,c.buildZoomPanMatrix)(qe.x,qe.y,_e,I,B)},[_e,qe,I,B]),gt=()=>{const n=an??j;if(!n||!g)return null;const t=!Mr&&m,o=fn&&j&&cn&&q,r=!Mr&&y.size>0&&o,i=an??j;return(0,f.jsxs)(f.Fragment,{children:[(0,f.jsx)(d.Rect,{x:0,y:0,width:I,height:B,color:"#F0F1F3"}),(0,f.jsx)(d.Group,{clip:d.Skia.XYWHRect(0,0,I,B),children:(0,f.jsxs)(d.Group,{matrix:ft,children:[r&&i?(0,f.jsx)($e.PaintShaderLayer,{originImage:i,paintColorMap:fn,lowFreqImage:j,highFreqImage:cn,x:g.x,y:g.y,width:g.w,height:g.h,showOrigin:!1}):lt(n),t&&pr!=null&&Jr(pr,"init-overlay"),t&&fe!=null&&!y.has(fe)&&Jr(fe,"hold-overlay")]})})]})},mt=()=>{const n=J;if(!n)return null;const t=n.w,o=n.h,r=fn&&j&&cn&&q,i=y.size>0&&r,a=an??j;if(i&&a)return(0,f.jsx)($e.PaintShaderLayer,{originImage:a,paintColorMap:fn,lowFreqImage:j,highFreqImage:cn,x:0,y:0,width:t,height:o,showOrigin:!1});const s=an??j;return s?(0,f.jsx)(d.Image,{image:s,x:0,y:0,width:t,height:o}):null},dt=(0,e.useMemo)(()=>{const n=(r,i)=>{_r.current?.();const a=(0,c.screenToCanvasCoords)(r,i,N.current,G.current,D.current,V.current),s=$n.current(a.x,a.y,!0);if(s==null||!we.current){ge(null),me(null);return}if(R.current&&R.current.has(s)){ge(null),me(null);return}const u=(0,c.canvasToNormalized)(a.x,a.y,N.current,G.current,we.current.w,we.current.h);ge(s),me(u)},t=(r,i,a)=>{if(!a)return;const s=(0,c.screenToCanvasCoords)(r,i,N.current,G.current,D.current,V.current);if(Vn.current)Kn.current(s.x,s.y);else{if(O(),Tr.current||!Hr.current||!we.current)return;const u=$n.current(s.x,s.y);if(u==null)return;const l=k.current.find(p=>p.id===u);Fn.current?.({kind:"brush_required",hint:"please select a brush color first",regionId:u,regionName:l?.name??String(u)})}},o=(r,i)=>{if(Vn.current){ge(null),me(null);return}const a=(0,c.screenToCanvasCoords)(r,i,N.current,G.current,D.current,V.current);Kn.current(a.x,a.y),ge(null),me(null)};return ee.Gesture.Tap().onBegin(r=>{"worklet";(0,U.runOnJS)(n)(r.x,r.y)}).onEnd((r,i)=>{"worklet";(0,U.runOnJS)(t)(r.x,r.y,i)}).onFinalize(r=>{"worklet";(0,U.runOnJS)(o)(r.x,r.y)})},[]),pt=(0,e.useMemo)(()=>{const n=(r,i)=>{Fr.current=D.current,Er.current={...V.current},Lr.current={x:r,y:i}},t=(r,i,a)=>{const s=N.current,u=G.current;if(s<=0||u<=0)return;const l=s/2,p=u/2,Pe=Fr.current,b=Er.current,v=Lr.current;let S=Math.max(1,Math.min(Pe*r,5));const Ce=(v.x-b.x-l)/Pe+l,be=(v.y-b.y-p)/Pe+p;let Q={x:i-l-S*(Ce-l),y:a-p-S*(be-p)};S<=1?(S=1,Q={x:0,y:0}):Q=(0,c.clampPanOffset)(Q,S,s,u,Un.current),Br(S),_n(Q),D.current=S,V.current=Q},o=()=>{D.current<=1.01&&Zn.current?.()};return ee.Gesture.Pinch().onStart(r=>{"worklet";(0,U.runOnJS)(n)(r.focalX,r.focalY)}).onUpdate(r=>{"worklet";(0,U.runOnJS)(t)(r.scale,r.focalX,r.focalY)}).onEnd(()=>{"worklet";(0,U.runOnJS)(o)()})},[]),ht=(0,e.useMemo)(()=>{const n=()=>{qn.current={...V.current}},t=(r,i)=>{if(D.current<=1)return;const a=(0,c.clampPanOffset)({x:qn.current.x+r,y:qn.current.y+i},D.current,N.current,G.current,Un.current);_n(a),V.current=a},o=()=>{D.current<=1.01&&Zn.current?.()};return ee.Gesture.Pan().minPointers(1).maxPointers(1).minDistance(10).onStart(()=>{"worklet";(0,U.runOnJS)(n)()}).onUpdate(r=>{"worklet";(0,U.runOnJS)(t)(r.translationX,r.translationY)}).onEnd(()=>{"worklet";(0,U.runOnJS)(o)()})},[]),Rt=(0,e.useMemo)(()=>ee.Gesture.Exclusive(ee.Gesture.Simultaneous(pt,ht),dt),[]);return(0,f.jsxs)(ne.View,{style:[$r.container,nt],children:[(0,f.jsx)(ne.View,{style:$r.canvasWrap,onLayout:n=>{const{width:t,height:o}=n.nativeEvent.layout;ct(t,o)},children:at?(0,f.jsx)(ee.GestureDetector,{gesture:Rt,children:(0,f.jsx)(ne.View,{style:{width:I,height:B},children:(0,f.jsx)(d.Canvas,{style:{width:I,height:B},pointerEvents:"none",children:gt()})})}):null}),st&&J?(0,f.jsx)(ne.View,{style:{position:"absolute",left:-J.w-200,top:0,width:J.w,height:J.h,opacity:0,overflow:"hidden"},pointerEvents:"none",children:(0,f.jsx)(d.Canvas,{ref:wr,style:{width:J.w,height:J.h},pointerEvents:"none",children:(0,f.jsx)(d.Group,{children:mt()})})}):null]})}),$r=ne.StyleSheet.create({container:{flex:1,backgroundColor:"#fff"},canvasWrap:{flex:1,width:"100%",alignSelf:"stretch",position:"relative",backgroundColor:"#f5f5f5",borderWidth:ne.StyleSheet.hairlineWidth,borderColor:"#ddd",overflow:"hidden"}});var Lt=Et;