1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[6878],{86878:function(e,t,a){a.r(t),a.d(t,{ARViewer:function(){return b}});var s=a(27573),r=a(31988),n=a(10269),i=a(27126),o=a(47686),l=a(99851),d=a(7653);a(99238);var c=a(73657),m=a(78813),u=a(92247);function h(e){return .0254*e}async function x(e){let{config:t,frameStyle:a,matColor:s,matInnerColor:r,imageDataUrl:n}=e,i=new m.xsS,o=h(t.artworkWidth),l=h(t.artworkHeight),d=h(a.mouldingWidth),c=h(a.usableDepth),x=0,p=0;"none"!==t.matType&&(x=h(t.matBorderWidth),p="double"===t.matType?h(t.matRevealWidth):0);let f=new m.ZAu;if(f.name="CustomFrame",n){let e=new m.dpR,t=await new Promise((t,a)=>{e.load(n,t,void 0,a)});t.colorSpace=m.KI_;let a=new m._12(o,l),s=new m.Wid({map:t,roughness:.8,metalness:0,side:m.Wl3}),r=new m.Kj0(a,s);r.name="Artwork",r.position.z=-(.5*c),f.add(r)}let b=o,j=l;if("none"!==t.matType&&s){let e=w(b=o+2*x,j=l+2*x,o+2*p,l+2*p,.002,new m.Wid({color:new m.Ilk(s.hexColor||s.color||"#FFFFFF"),roughness:.8,metalness:0}));if(e.name="OuterMat",e.position.z=-(.15*c),f.add(e),"double"===t.matType&&r){let e=w(o+2*p+2*x,l+2*p+2*x,o,l,.002,new m.Wid({color:new m.Ilk(r.hexColor||r.color||"#FFFFFF"),roughness:.8,metalness:0}));e.name="InnerMat",e.position.z=-(.35*c),f.add(e)}}let g=b+2*d,v=j+2*d,y=new m.Ilk(a.color||"#8B7355"),N=new m.Wid({color:y,roughness:.6,metalness:.1}),k=new m.DvJ(g-2*d,d,c),z=new m.Kj0(k,N);z.name="FrameTop",z.position.y=v/2-d/2,z.position.z=0,f.add(z);let F=new m.DvJ(g-2*d,d,c),R=new m.Kj0(F,N);R.name="FrameBottom",R.position.y=-(v/2)+d/2,R.position.z=0,f.add(R);let A=new m.DvJ(d,v,c),C=new m.Kj0(A,N);C.name="FrameLeft",C.position.x=-(g/2)+d/2,C.position.z=0,f.add(C);let S=new m.DvJ(d,v,c),E=new m.Kj0(S,N);E.name="FrameRight",E.position.x=g/2-d/2,E.position.z=0,f.add(E);let W=new m._12(g,v),T=new m.EJi({color:16777215,transparent:!0,opacity:.05,roughness:.1,metalness:0,reflectivity:.2}),K=new m.Kj0(W,T);K.name="Glass",K.position.z=.4*c,f.add(K);let L=new m.Ox3(16777215,.8);L.position.set(1,1,1),i.add(L),i.add(f);let M=new u.M;return new Promise((e,t)=>{M.parse(i,t=>{let a;a=t instanceof ArrayBuffer?new Blob([t],{type:"model/gltf-binary"}):new Blob([JSON.stringify(t)],{type:"model/gltf+json"}),e(URL.createObjectURL(a))},e=>t(e),{binary:!0})})}function w(e,t,a,s,r,n){let i=new m.ZAu,o=(e-a)/2,l=(t-s)/2,d=new m.DvJ(e,l,r),c=new m.Kj0(d,n);c.position.y=t/2-l/2,c.position.z=0,i.add(c);let u=new m.DvJ(e,l,r),h=new m.Kj0(u,n);h.position.y=-(t/2)+l/2,h.position.z=0,i.add(h);let x=new m.DvJ(o,s,r),w=new m.Kj0(x,n);w.position.x=-(e/2)+o/2,w.position.z=0,i.add(w);let p=new m.DvJ(o,s,r),f=new m.Kj0(p,n);return f.position.x=e/2-o/2,f.position.z=0,i.add(f),i}var p=a(96979),f=a(51602);function b(e){let{config:t,onClose:a,onSizeUpdate:m}=e,[u,h]=(0,d.useState)(!0),[w,b]=(0,d.useState)(null),[j,g]=(0,d.useState)(null),[v,y]=(0,d.useState)(!1),[N,k]=(0,d.useState)(1),[z,F]=(0,d.useState)(!1),R=(0,d.useRef)(null),{data:A,isLoading:C}=(0,r.a)({queryKey:["/api/frames/styles"],staleTime:3e5,refetchOnMount:!0}),{data:S,isLoading:E}=(0,r.a)({queryKey:["/api/mats"],staleTime:3e5,refetchOnMount:!0}),W=null==S?void 0:S.mats;(0,d.useEffect)(()=>()=>{w&&URL.revokeObjectURL(w)},[w]),(0,d.useEffect)(()=>{if("xr"in navigator){var e;null===(e=navigator.xr)||void 0===e||e.isSessionSupported("immersive-ar").then(e=>{y(e)})}},[]),(0,d.useEffect)(()=>{let e=R.current;if(!e)return;let t=e=>{let t="session-started"===e.detail.status;F(t),t||k(1)},a=()=>{if(e.scale){let t=parseFloat(e.scale.split(" ")[0]);isNaN(t)||t===N||k(t)}};e.addEventListener("ar-status",t),e.addEventListener("scale-change",a);let s=setInterval(()=>{z&&e.scale&&a()},500);return()=>{e.removeEventListener("ar-status",t),e.removeEventListener("scale-change",a),clearInterval(s)}},[z,N]),(0,d.useEffect)(()=>{let e="none"!==t.matType;!A||e&&!W||C||E||T()},[t,A,W,C,E]);let T=async()=>{h(!0),g(null);try{let e,a,s;if(!A)throw Error("Frame styles not loaded");let r=A.find(e=>e.id===t.frameStyleId);if(!r)throw Error("Frame style not found");if("none"!==t.matType&&W&&(e=W.find(e=>e.id===t.matColorId),"double"===t.matType&&(a=W.find(e=>e.id===t.matInnerColorId))),t.imageUrl)try{s=await (0,c.Xl)(t.imageUrl)}catch(e){console.error("[AR Viewer] Error loading image:",e)}let n=await x({config:t,frameStyle:r,matColor:e,matInnerColor:a,imageDataUrl:s});b(n)}catch(e){console.error("[AR Viewer] Error generating model:",e),g(e instanceof Error?e.message:"Failed to load AR model")}finally{h(!1)}};return j?(0,s.jsx)("div",{className:"fixed inset-0 bg-background/95 z-50 flex items-center justify-center p-4",children:(0,s.jsxs)(f.Zb,{className:"max-w-md w-full p-6",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between mb-4",children:[(0,s.jsx)("h2",{className:"text-lg font-semibold",children:"AR View Error"}),(0,s.jsx)(p.z,{size:"icon",variant:"ghost",onClick:a,"data-testid":"button-close-ar",children:(0,s.jsx)(n.Z,{className:"h-4 w-4"})})]}),(0,s.jsx)("p",{className:"text-muted-foreground mb-4",children:j}),(0,s.jsx)(p.z,{onClick:a,className:"w-full","data-testid":"button-dismiss-error",children:"Close"})]})}):(0,s.jsxs)("div",{className:"fixed inset-0 bg-background z-50 flex flex-col",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between p-4 border-b bg-background/95 backdrop-blur relative z-10",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("h2",{className:"text-lg font-semibold",children:"AR Preview"}),u&&(0,s.jsx)("span",{className:"text-sm text-muted-foreground",children:"Loading..."})]}),(0,s.jsx)(p.z,{size:"icon",variant:"ghost",onClick:a,"data-testid":"button-close-ar-viewer",className:"relative z-20",children:(0,s.jsx)(n.Z,{className:"h-4 w-4"})})]}),(0,s.jsxs)("div",{className:"flex-1 relative",children:[w&&(0,s.jsxs)("model-viewer",{ref:R,src:w,ar:!0,"ar-modes":"webxr scene-viewer quick-look","camera-controls":!0,"touch-action":"pan-y",alt:"Custom Frame AR Preview",style:{width:"100%",height:"100%"},"data-testid":"model-viewer",children:[(0,s.jsx)("button",{slot:"ar-button",style:{display:"none"},"data-testid":"button-activate-ar-slot",children:"View on Your Wall"}),u&&(0,s.jsx)("div",{slot:"poster",className:"absolute inset-0 flex items-center justify-center bg-muted",children:(0,s.jsxs)("div",{className:"text-center",children:[(0,s.jsx)("div",{className:"w-12 h-12 border-4 border-primary border-t-transparent roun
1ded-full animate-spin mx-auto mb-4"}),(0,s.jsx)("p",{className:"text-muted-foreground",children:"Generating 3D model..."})]})})]}),!u&&w&&1===N&&(0,s.jsx)("div",{className:"absolute bottom-24 left-1/2 -translate-x-1/2 z-10",children:(0,s.jsx)(p.z,{size:"lg",className:"shadow-xl",onClick:()=>{R.current&&(R.current.canActivateAR?R.current.activateAR():alert("AR requires a mobile device with iOS 12+ (Safari) or Android 8+ (Chrome). On desktop, you can rotate and zoom the 3D model using your mouse."))},"data-testid":"button-activate-ar",children:"View on Your Wall"})}),!u&&w&&!z&&(0,s.jsx)("div",{className:"absolute top-4 left-4 right-4 md:left-auto md:w-80",children:(0,s.jsx)(f.Zb,{className:"p-4 bg-background/95 backdrop-blur",children:(0,s.jsxs)("div",{className:"flex items-start gap-3",children:[(0,s.jsx)(i.Z,{className:"h-5 w-5 text-primary shrink-0 mt-0.5"}),(0,s.jsxs)("div",{className:"text-sm space-y-2",children:[(0,s.jsx)("p",{className:"font-medium",children:"How to use AR:"}),(0,s.jsxs)("ol",{className:"list-decimal list-inside space-y-1 text-muted-foreground",children:[(0,s.jsx)("li",{children:'Tap "View on Your Wall" below'}),(0,s.jsx)("li",{children:"Point your camera at a wall"}),(0,s.jsx)("li",{children:"Tap to place the frame and see how it looks"})]}),!v&&(0,s.jsx)("p",{className:"text-xs text-yellow-600 dark:text-yellow-500 mt-2",children:"AR mode works best on mobile devices with iOS 12+ (Safari) or Android 8+ (Chrome)"})]})]})})}),z&&1!==N&&(0,s.jsx)("div",{className:"absolute top-4 left-1/2 -translate-x-1/2 z-10",children:(0,s.jsx)(f.Zb,{className:"p-3 bg-background/95 backdrop-blur",children:(0,s.jsxs)("div",{className:"text-center text-sm",children:[(0,s.jsxs)("p",{className:"font-medium",children:["New Size: ",Math.round(t.artworkWidth*N*100)/100,'" \xd7'," ",Math.round(t.artworkHeight*N*100)/100,'"']}),(0,s.jsx)("p",{className:"text-xs text-muted-foreground mt-1",children:N>1?"".concat(Math.round((N-1)*100),"% larger"):"".concat(Math.round((1-N)*100),"% smaller")})]})})}),m&&1!==N&&(0,s.jsx)("div",{className:"absolute bottom-24 left-1/2 -translate-x-1/2 z-10",children:(0,s.jsxs)(p.z,{size:"lg",className:"shadow-xl",onClick:()=>{if(m&&1!==N)m(Math.round(t.artworkWidth*N*100)/100,Math.round(t.artworkHeight*N*100)/100),a()},"data-testid":"button-lock-size",children:[(0,s.jsx)(o.Z,{className:"h-5 w-5 mr-2"}),"Lock Size & Update Cart"]})})]}),!u&&w&&(0,s.jsxs)("div",{className:"border-t bg-background/95 backdrop-blur p-4",children:[(0,s.jsx)("div",{className:"flex items-center justify-center gap-3 max-w-md mx-auto",children:(0,s.jsxs)(p.z,{variant:"outline",size:"sm",onClick:()=>{if(R.current){let e=R.current.getCameraOrbit();R.current.cameraOrbit="".concat(e.theta,"deg ").concat(e.phi,"deg ").concat(e.radius,"m")}},className:"flex items-center gap-2","data-testid":"button-rotate-model",children:[(0,s.jsx)(l.Z,{className:"h-4 w-4"}),"Rotate"]})}),(0,s.jsxs)("div",{className:"mt-4 text-center text-sm text-muted-foreground",children:[(0,s.jsxs)("p",{children:[1!==N&&"Original: ",t.artworkWidth,'" \xd7 ',t.artworkHeight,'"',"none"!==t.matType&&" with ".concat(t.matType," mat")]}),1!==N&&(0,s.jsxs)("p",{className:"mt-1 text-primary font-medium",children:["Adjusted: ",Math.round(t.artworkWidth*N*100)/100,'" \xd7'," ",Math.round(t.artworkHeight*N*100)/100,'"']})]})]})]})}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.