@neurodyn/core-ar 0.2.1 → 0.2.3

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.
@@ -1,4 +1,4 @@
1
- (()=>{"use strict";let e,t,i;function r(e,t){let i;try{i=new URL(e)}catch{throw TypeError(`${t} must be an absolute HTTP(S) URL`)}if("http:"!==i.protocol&&"https:"!==i.protocol)throw TypeError(`${t} must be an absolute HTTP(S) URL`);return i.origin}function o(){if(!e)throw Error("Core AR widget runtime is not configured");return e}function n(){return"u"<typeof navigator?"":navigator.userAgent||navigator.vendor||""}function a(){if("u"<typeof window||"u"<typeof navigator)return!1;let e="MacIntel"===navigator.platform&&navigator.maxTouchPoints>1;return(/iPad|iPhone|iPod/.test(n())||e)&&!("MSStream"in window)}function s(){if("u"<typeof window||"u"<typeof navigator)return!1;let e=navigator.maxTouchPoints>1,t=window.matchMedia?.("(pointer: coarse)").matches??!1,i=/Android|iPhone|iPad|iPod|webOS|BlackBerry|Windows Phone|Opera Mini|IEMobile|Mobile/i.test(n());return e&&t&&(i||a())}function l(){let e=n();return[[/edg/i,"Microsoft Edge"],[/trident/i,"Microsoft Internet Explorer"],[/firefox|fxios/i,"Mozilla Firefox"],[/opr\//i,"Opera"],[/ucbrowser/i,"UC Browser"],[/samsungbrowser/i,"Samsung Browser"],[/chrome|chromium|crios/i,"Google Chrome"],[/safari/i,"Apple Safari"]].find(([t])=>t.test(e))?.[1]??"Other"}function c(){let e=function(){let e=n(),t=e.match(/\bOS (\d+)/)?.[1]??e.match(/Version\/(\d+)/)?.[1];if(!t)return null;let i=Number.parseInt(t,10);return Number.isNaN(i)?null:i}();return null!==e&&e>=17}function d(e){let t;try{t=new URL(e)}catch{throw TypeError("Native AR asset URL must be absolute HTTP(S)")}if("http:"!==t.protocol&&"https:"!==t.protocol)throw TypeError("Native AR asset URL must be absolute HTTP(S)");return t.href}function u(e,t){let i=d(e.glbUrl),r=d(e.usdzUrl),o=encodeURIComponent(i),n=`intent://arvr.google.com/scene-viewer/1.0?file=${o}&resizable=false${"wall"===t||"ceiling"===t?"&enable_vertical_placement=true":""}&mode=ar_preferred#Intent;scheme=https;package=com.google.android.googlequicksearchbox;action=android.intent.action.VIEW;end;`,s=`${r}#allowsContentScaling=0`;return a()?s:n}function h(e,t=0){let i=document.createElement("a"),r=document.createElement("img");i.rel="ar",i.href=e,i.hidden=!0,r.alt="",r.hidden=!0,i.appendChild(r),document.body.appendChild(i),window.setTimeout(()=>{i.click(),i.remove()},t)}function g(e,t){let i=function(e,t){let{brand:i}=t??o();if(a()){let t=new URL("https://appclip.apple.com/id");return t.searchParams.set("p","com.us.vizbl.Clip"),t.searchParams.set("tinuuid",e),t.searchParams.set("region","arizo"===i?"ru":"en"),t.toString()}return`intent:/${window.location.pathname}#Intent;scheme=open;package=com.us.vizbl;end`}(e,t);window.self===window.top||l().toLowerCase().includes("edge")?window.location.assign(i):window.open(i,"_top")}function p(e,t,i=!1,r){let{viewerOrigin:n}=r??o(),a=new URL("/ar/index.html",n);return a.searchParams.set("tinuuid",e),t&&a.searchParams.set("hid",t),i&&a.searchParams.set("appview","true"),a.toString()}function m(){let e=new WeakMap;return function(t){let i=e.get(t);i?.cleanup?.();let r={revision:(i?.revision??0)+1};return e.set(t,r),{isCurrent:()=>e.get(t)===r,register(i){let o=!1,n=()=>{o||(o=!0,i())};return e.get(t)!==r?(n(),n):(r.cleanup=n,()=>{e.get(t)===r&&e.delete(t),n()})}}}}let v=0,f={arizo:{conjunction:"и",privacyLabel:"Политика конфиденциальности",privacyUrl:"https://arizo.ru/privacy-policy/",termsLabel:"Условия использования",termsUrl:"https://arizo.ru/terms-of-use/"},vizbl:{conjunction:"and",privacyLabel:"Privacy Policy",privacyUrl:"https://vizbl.com/legal/privacy-policy",termsLabel:"Terms of Use",termsUrl:"https://vizbl.com/legal/terms-of-use"}};function w(){return window.QRCode}function b(e,t,i){let r=document.createElement("a");return r.dataset.vizblLegalLink=e,r.href=t,r.rel="noopener noreferrer",r.target="_blank",r.textContent=i,Object.assign(r.style,{color:"inherit",textDecoration:"underline",textUnderlineOffset:"2px",whiteSpace:"nowrap"}),r}async function y(e,r="vizblQrModal",n,a){let s,l=++v;i?.(),document.querySelectorAll("[data-vizbl-qr-modal]").forEach(e=>e.remove());let c=function(e){let{brand:t,viewerOrigin:i}=e??o(),r="arizo"===t,n=document.createElement("div");n.dataset.vizblQrModal="",n.setAttribute("aria-label","View object in augmented reality"),n.setAttribute("aria-modal","true"),n.setAttribute("role","dialog"),Object.assign(n.style,{alignItems:"center",backgroundColor:"rgba(0,0,0,0.25)",display:"none",height:"100%",justifyContent:"center",left:"0",position:"fixed",top:"0",width:"100%",zIndex:"9999"});let a=document.createElement("div");Object.assign(a.style,{backgroundColor:"#fff",borderRadius:"12px",boxSizing:"border-box",color:"#000",fontFamily:"Inter, sans-serif",minHeight:"372px",padding:"48px 52px 40px",position:"relative",width:"min(460px, calc(100vw - 32px))"});let s=document.createElement("button");s.type="button",s.dataset.vizblQrClose="",s.setAttribute("aria-label","Close QR code"),s.textContent="\xd7",Object.assign(s.style,{background:"none",border:"none",color:"#AEB1B7",cursor:"pointer",fontSize:"24px",position:"absolute",right:"20px",top:"20px"});let l=document.createElement("div");l.dataset.vizblQrCode="",l.style.margin="0 auto",l.style.width="fit-content";let c=document.createElement("p");c.textContent="Scan this QR code with your phone camera to view the object in Augmented Reality",Object.assign(c.style,{fontSize:"16px",fontWeight:"500",lineHeight:"24px",margin:"24px 0 0",textAlign:"center"});let d=document.createElement("p");Object.assign(d.style,{color:"#93979F",fontSize:"12px",lineHeight:"16px",margin:"12px 0 0",textAlign:"center"});let u=f[t],h=b("terms",u.termsUrl,u.termsLabel),g=b("privacy",u.privacyUrl,u.privacyLabel);d.append(r?"*Требуется устройство и браузер с поддержкой AR. Рекомендуем iOS 12 или новее с Safari либо Android 7.0 или новее с Chrome.":"*Requires an AR-compatible device and browser. We recommend iOS 12 or later with Safari, or Android 7.0 or later with Chrome.",document.createElement("br"),h,` ${u.conjunction} `,g);let p=document.createElement("p");p.textContent=`Powered by ${r?"Arizo":"Vizbl"}`,Object.assign(p.style,{color:"#93979F",fontSize:"11px",letterSpacing:"1.5px",margin:"24px 0 4px",textAlign:"center",textTransform:"uppercase"});let m=document.createElement("a");m.dataset.vizblBrandLink="",m.href=r?"https://arizo.ru":"https://vizbl.com",m.style.display="block",m.style.textAlign="center";let v=document.createElement("img");return v.alt=`${r?"Arizo":"Vizbl"} logo`,v.src=`${i}/${r?"logoArizo.svg":"logo.svg"}`,v.height=20,v.width=r?76:60,m.appendChild(v),a.append(s,l,c,d,p,m),n.appendChild(a),n}(a);c.id=r;let d=c.querySelector("[data-vizbl-qr-close]"),u=Array.from(c.querySelectorAll("button, a[href]")),h=!1,g=e=>{if("Escape"===e.key){e.preventDefault(),s();return}if("Tab"!==e.key||0===u.length)return;let t=u[0],i=u.at(-1)??t;e.shiftKey&&(document.activeElement===t||!c.contains(document.activeElement))?(e.preventDefault(),i.focus()):e.shiftKey||document.activeElement!==i||(e.preventDefault(),t.focus())};i=s=()=>{h||(h=!0,document.removeEventListener("keydown",g),c.remove(),i===s&&(i=void 0),n?.focus({preventScroll:!0}))},d?.addEventListener("click",s),c.addEventListener("click",e=>{e.target===c&&s()}),document.body.appendChild(c),document.addEventListener("keydown",g),function(){let e="https://fonts.googleapis.com/css2?family=Inter&display=swap";if(Array.from(document.querySelectorAll('link[rel="stylesheet"]')).some(t=>t.href===e||t.getAttribute("href")===e))return;let t=document.createElement("link");t.rel="stylesheet",t.href=e,document.head.appendChild(t)}();try{let i=await function(e){let i=w();if(i)return Promise.resolve(i);if(t)return t;let{qrCodeScriptUrl:r}=e??o();return t=new Promise((e,i)=>{let o,n=document.createElement("script"),a=()=>{o();let r=w();r?e(r):(n.remove(),t=void 0,i(Error("QR code runtime did not expose QRCode")))},s=()=>{o(),n.remove(),t=void 0,i(Error("Failed to load QR code runtime"))};o=()=>{n.removeEventListener("load",a),n.removeEventListener("error",s)},n.addEventListener("load",a,{once:!0}),n.addEventListener("error",s,{once:!0}),n.src=r,n.async=!0,n.dataset.vizblQrScript="true",document.head.appendChild(n)})}(a);if(l!==v||!c.isConnected)return s(),s;let r=c.querySelector("[data-vizbl-qr-code]");return r&&new i(r,{correctLevel:i.CorrectLevel.L,height:148,text:e,width:148}),c.style.display="flex",d?.focus({preventScroll:!0}),s}catch(e){throw s(),e}}class E extends Error{code;constructor(e){super(e),this.code=e,this.name="WidgetRuntimeError"}}function A(e){return e.runtimeConfig??o()}function C(e,t,i={}){let r=new URL(t,e);for(let[e,t]of Object.entries(i))t&&r.searchParams.set(e,t);return r.toString()}async function I(e,t,i){try{return await (i.fetchImpl??i.runtimeConfig?.fetchImpl??o().fetchImpl)(e,{...t,signal:i.signal})}catch(e){if(e instanceof DOMException&&"AbortError"===e.name)throw e;throw new E("NETWORK_ERROR")}}async function x(e){try{let t=await e.json();return[t.code,t.error,t.message].flatMap(e=>Array.isArray(e)?e:[e]).filter(e=>"string"==typeof e).join(" ").toLowerCase()}catch{return""}}async function S(e,t){let i=await x(e);return new E(429===e.status?"RATE_LIMITED":e.status>=500?"API_UNAVAILABLE":404===e.status&&"object"===t?"OBJECT_NOT_FOUND":i.includes("domain")||i.includes("origin")?"DOMAIN_NOT_ALLOWED":i.includes("revoked")?"KEY_REVOKED":i.includes("expired")?"activation"===t?"KEY_EXPIRED":"SESSION_EXPIRED":i.includes("policy")||i.includes("not available for this object")?"POLICY_DENIED":401===e.status||403===e.status?"activation"===t?"INVALID_KEY":"SESSION_EXPIRED":"REQUEST_FAILED")}async function L(e){try{return await e.json()}catch{throw new E("INVALID_RESPONSE")}}function T(e){if(!e||"object"!=typeof e||"string"!=typeof e.token||!e.token.trim()||"string"!=typeof e.sid||!e.sid.trim()||"number"!=typeof e.expiresIn||!Number.isFinite(e.expiresIn)||e.expiresIn<=0)throw new E("INVALID_RESPONSE");return e}async function k(e,t={}){let{apiOrigin:i}=A(t),r=await I(C(i,"/public/widget/activate-core",{mode:t.mode}),{cache:"no-store",headers:{"x-api-key":e},method:"POST"},t);if(!r.ok)throw await S(r,"activation");let o=await L(r);if("string"!=typeof o.productType)throw new E("INVALID_RESPONSE");return{...T(o.widgetSession),productType:o.productType}}async function z(e,t,i={}){let{apiOrigin:r}=A(i),o=await I(`${r}/public/widget/token`,{body:JSON.stringify({token:t,...i.mode?{mode:i.mode}:{}}),cache:"no-store",headers:{"Content-Type":"application/json","x-api-key":e},method:"POST"},i);if(!o.ok)throw await S(o,"token");return T(await L(o))}async function O(e,t,i={}){let{apiOrigin:r}=A(i),o=await I(C(r,`/public/objects/by-tinuuid/${encodeURIComponent(e)}`,{variantId:i.variantId}),{cache:"no-store",headers:{"x-widget-session-token":t},method:"GET"},i);if(!o.ok)throw await S(o,"object");let n=await L(o);if(!n||"object"!=typeof n||Array.isArray(n))throw new E("INVALID_RESPONSE");return n}async function R(e,t,i,r={}){let{apiOrigin:o}=A(r),n=await I(`${o}/public/widget/events`,{body:JSON.stringify({event:e,...i?{objectId:i}:{},...r.variantId?{variantId:r.variantId}:{},timestamp:new Date().toISOString()}),cache:"no-store",headers:{"Content-Type":"application/json","x-widget-session-token":t},method:"POST"},r);if(!n.ok)throw await S(n,"event");let a=await L(n);if(!a||"object"!=typeof a||Array.isArray(a)||"boolean"!=typeof a.ok)throw new E("INVALID_RESPONSE")}async function N(e,t,i){let r=i??o(),{fetchImpl:n,legacyApiOrigin:a}=r,s=await I(`${a}/obj/Fetch`,{body:JSON.stringify({tinuuid:e}),headers:{"Content-Type":"application/json"},method:"POST"},{fetchImpl:n,runtimeConfig:r,signal:t});if(!s.ok)throw await S(s,"object");let l=await L(s);if(!l||"object"!=typeof l||Array.isArray(l))throw new E("INVALID_RESPONSE");return l}async function P(e,t){let{fetchImpl:i,legacyApiOrigin:r}=t??o();await i(`${r}/obj/IncrViews`,{body:JSON.stringify({tinuuid:e}),headers:{"Content-Type":"application/json"},method:"POST"})}function D(e){try{let t=e?.();t instanceof Promise&&t.catch(()=>void 0)}catch{}}let j=m();function _(e){if(e?.aborted)throw new DOMException("Aborted","AbortError")}async function U(e,t={}){let i,r,o=j(e),n=e.getAttribute("data-native-link"),d=e.dataset.objectTinuuid?.trim(),m=e.dataset.objectHid?.trim()||void 0;if(!d)throw Error("Object ID is required");_(t.signal);let v=t.loadObject??((e,i)=>N(e,i,t.runtimeConfig)),f=t.object??await v(d,t.signal);if(_(t.signal),!o.isCurrent())return()=>void 0;let w=m?f.materials.find(e=>e.hid===m):f.materials[0];if(!w?.native?.glbUrl||!w.native.usdzUrl)throw Error("Native AR assets are unavailable");let b=u(w.native,f.type),E=s(),A=!1,C=0;e.querySelector("img")||((i=document.createElement("img")).alt="",i.hidden=!0,e.appendChild(i));let I=()=>t.trackView?t.trackView():P(d,t.runtimeConfig),x=i=>{i.preventDefault(),D(()=>t.onAction?.("widget_opened"));let n=++C;r?.(),r=void 0,y(p(d,m,!0,t.runtimeConfig),`vizbl-${d}`,e,t.runtimeConfig).then(e=>{n===C&&o.isCurrent()?r=e:e()}).catch(()=>void 0)},S=async e=>{let i;if(i=l().toLowerCase(),["firefox","edge","opera"].some(e=>i.includes(e))){if(e.preventDefault(),A)return;A=!0,D(()=>t.onAction?.("ar_launched"));try{await Promise.resolve(I()).catch(()=>void 0)}finally{A=!1,a()&&c()?g(d,t.runtimeConfig):h(b)}return}D(()=>t.onAction?.("ar_launched")),D(I),a()&&c()?(e.preventDefault(),g(d,t.runtimeConfig)):h(b)};return E?(e.dataset.nativeLink=b,e.addEventListener("click",S)):e.addEventListener("click",x),o.register(()=>{C+=1,e.removeEventListener("click",x),e.removeEventListener("click",S),r?.(),i?.remove(),null===n?e.removeAttribute("data-native-link"):e.setAttribute("data-native-link",n)})}var M=!1;if("u">typeof window){var $={get passive(){M=!0;return}};window.addEventListener("testPassive",null,$),window.removeEventListener("testPassive",null,$)}var V="u">typeof window&&window.navigator&&window.navigator.platform&&(/iP(ad|hone|od)/.test(window.navigator.platform)||"MacIntel"===window.navigator.platform&&window.navigator.maxTouchPoints>1),B=[],q=!1,H=-1,W=void 0,F=void 0,Q=void 0,Y=function(e){return B.some(function(t){return!!(t.options.allowTouchMove&&t.options.allowTouchMove(e))})},K=function(e){var t=e||window.event;return!!Y(t.target)||t.touches.length>1||(t.preventDefault&&t.preventDefault(),!1)},X=function(e){if(void 0===Q){var t=!!e&&!0===e.reserveScrollBarGap,i=window.innerWidth-document.documentElement.clientWidth;if(t&&i>0){var r=parseInt(window.getComputedStyle(document.body).getPropertyValue("padding-right"),10);Q=document.body.style.paddingRight,document.body.style.paddingRight=r+i+"px"}}void 0===W&&(W=document.body.style.overflow,document.body.style.overflow="hidden")},J=function(){void 0!==Q&&(document.body.style.paddingRight=Q,Q=void 0),void 0!==W&&(document.body.style.overflow=W,W=void 0)},G=function(){if(void 0!==F){var e=-parseInt(document.body.style.top,10),t=-parseInt(document.body.style.left,10);document.body.style.position=F.position,document.body.style.top=F.top,document.body.style.left=F.left,window.scrollTo(t,e),F=void 0}},Z=function(e,t){var i=e.targetTouches[0].clientY-H;return!Y(e.target)&&(t&&0===t.scrollTop&&i>0?K(e):t&&t.scrollHeight-t.scrollTop<=t.clientHeight&&i<0?K(e):(e.stopPropagation(),!0))},ee=function(e,t){e?!B.some(function(t){return t.targetElement===e})&&(B=[].concat(function(e){if(!Array.isArray(e))return Array.from(e);for(var t=0,i=Array(e.length);t<e.length;t++)i[t]=e[t];return i}(B),[{targetElement:e,options:t||{}}]),V?window.requestAnimationFrame(function(){if(void 0===F){F={position:document.body.style.position,top:document.body.style.top,left:document.body.style.left};var e=window,t=e.scrollY,i=e.scrollX,r=e.innerHeight;document.body.style.position="fixed",document.body.style.top=-t,document.body.style.left=-i,setTimeout(function(){return window.requestAnimationFrame(function(){var e=r-window.innerHeight;e&&t>=r&&(document.body.style.top=-(t+e))})},300)}}):X(t),V&&(e.ontouchstart=function(e){1===e.targetTouches.length&&(H=e.targetTouches[0].clientY)},e.ontouchmove=function(t){1===t.targetTouches.length&&Z(t,e)},q||(document.addEventListener("touchmove",K,M?{passive:!1}:void 0),q=!0))):console.error("disableBodyScroll unsuccessful - targetElement must be provided when calling disableBodyScroll on IOS devices.")},et=function(e){e?(B=B.filter(function(t){return t.targetElement!==e}),V&&(e.ontouchstart=null,e.ontouchmove=null,q&&0===B.length&&(document.removeEventListener("touchmove",K,M?{passive:!1}:void 0),q=!1)),V?G():J()):console.error("enableBodyScroll unsuccessful - targetElement must be provided when calling enableBodyScroll on IOS devices.")};let ei=["cm","inch"],er="vizbl_viewer",eo=m(),en=m();function ea(e){if(e?.aborted)throw new DOMException("Aborted","AbortError")}async function es(e,t={}){let i,r,o=en(e),n=e.getAttribute("href"),a=e.getAttribute("rel"),l=e.dataset.objectTinuuid?.trim(),c=e.dataset.objectHid?.trim()||void 0;if(!l)throw Error("Object ID is required");ea(t.signal);let d=t.loadObject??((e,i)=>N(e,i,t.runtimeConfig)),h=t.object??await d(l,t.signal);if(ea(t.signal),!o.isCurrent())return()=>void 0;let g=c?h.materials.find(e=>e.hid===c):h.materials[0];if(!g?.native?.glbUrl||!g.native.usdzUrl)throw Error("Native AR assets are unavailable");let m=u(g.native,h.type),v=s(),f=0;e.rel="ar",e.querySelector("img")||((i=document.createElement("img")).alt="",i.hidden=!0,e.appendChild(i));let w=i=>{i.preventDefault(),D(()=>t.onAction?.("widget_opened"));let n=++f;r?.(),r=void 0,y(p(l,c,!1,t.runtimeConfig),`vizbl-${l}`,e,t.runtimeConfig).then(e=>{n===f&&o.isCurrent()?r=e:e()}).catch(()=>void 0)},b=()=>{D(t.trackView??(()=>P(l,t.runtimeConfig))),D(()=>t.onAction?.("ar_launched"))};return v?(e.href=m,e.addEventListener("click",b)):(e.href="#",e.addEventListener("click",w)),o.register(()=>{f+=1,e.removeEventListener("click",w),e.removeEventListener("click",b),r?.(),i?.remove(),null===n?e.removeAttribute("href"):e.setAttribute("href",n),null===a?e.removeAttribute("rel"):e.setAttribute("rel",a)})}let el=["advanced-ar","ar-one-click","ar-viewer"],ec={arizo:"arizo-core",vizbl:"vizbl-core"},ed=new Set(["core-ar","core-ar-shopify"]),eu={"advanced-ar":"View in advanced AR","ar-one-click":"View in AR","ar-viewer":"View in 3D & AR"},eh={"advanced-ar":"advanced-ar-view","ar-one-click":"ar-view","ar-viewer":"ar-viewer"},eg=["api-key","dev","object-id","size-type","trigger-class","type","variant-id"],ep=new Set(["API_UNAVAILABLE","INVALID_RESPONSE","NETWORK_ERROR","REQUEST_FAILED","SESSION_EXPIRED"]),em="core-ar-widget-styles";class ev extends Error{code;constructor(e){super(e),this.code=e,this.name="CoreArWidgetComponentError"}}function ef(e){return el.includes(e)}let ew="u"<typeof HTMLElement?class{}:HTMLElement;class eb extends ew{static get observedAttributes(){return[...eg]}get triggerClass(){return this.getAttribute("trigger-class")??""}set triggerClass(e){let t="string"==typeof e?e.trim():"";t?this.setAttribute("trigger-class",t):this.removeAttribute("trigger-class")}get unstyled(){return this.hasAttribute("unstyled")}set unstyled(e){this.toggleAttribute("unstyled",!!e)}abortController;actionResetTimer;cleanup;customLabelNodes=null;initializationRevision=0;object;queued=!1;session;trigger;variantId;widgetMode;connectedCallback(){!function(){if(document.getElementById(em))return;let e=document.createElement("style");e.id=em,e.textContent=`
1
+ (()=>{"use strict";let e,t,i;function r(e,t){let i;try{i=new URL(e)}catch{throw TypeError(`${t} must be an absolute HTTP(S) URL`)}if("http:"!==i.protocol&&"https:"!==i.protocol)throw TypeError(`${t} must be an absolute HTTP(S) URL`);return i.origin}function n(){if(!e)throw Error("Core AR widget runtime is not configured");return e}function o(){return"u"<typeof navigator?"":navigator.userAgent||navigator.vendor||""}function a(){if("u"<typeof window||"u"<typeof navigator)return!1;let e="MacIntel"===navigator.platform&&navigator.maxTouchPoints>1;return(/iPad|iPhone|iPod/.test(o())||e)&&!("MSStream"in window)}function s(){if("u"<typeof window||"u"<typeof navigator)return!1;let e=navigator.maxTouchPoints>1,t=window.matchMedia?.("(pointer: coarse)").matches??!1,i=/Android|iPhone|iPad|iPod|webOS|BlackBerry|Windows Phone|Opera Mini|IEMobile|Mobile/i.test(o());return e&&t&&(i||a())}function l(){let e=o();return[[/edg/i,"Microsoft Edge"],[/trident/i,"Microsoft Internet Explorer"],[/firefox|fxios/i,"Mozilla Firefox"],[/opr\//i,"Opera"],[/ucbrowser/i,"UC Browser"],[/samsungbrowser/i,"Samsung Browser"],[/chrome|chromium|crios/i,"Google Chrome"],[/safari/i,"Apple Safari"]].find(([t])=>t.test(e))?.[1]??"Other"}function d(){let e=function(){let e=o(),t=e.match(/\bOS (\d+)/)?.[1]??e.match(/Version\/(\d+)/)?.[1];if(!t)return null;let i=Number.parseInt(t,10);return Number.isNaN(i)?null:i}();return null!==e&&e>=17}function c(e){let t;try{t=new URL(e)}catch{throw TypeError("Native AR asset URL must be absolute HTTP(S)")}if("http:"!==t.protocol&&"https:"!==t.protocol)throw TypeError("Native AR asset URL must be absolute HTTP(S)");return t.href}function u(e,t){let i=c(e.glbUrl),r=c(e.usdzUrl),n=encodeURIComponent(i),o=`intent://arvr.google.com/scene-viewer/1.0?file=${n}&resizable=false${"wall"===t||"ceiling"===t?"&enable_vertical_placement=true":""}&mode=ar_preferred#Intent;scheme=https;package=com.google.android.googlequicksearchbox;action=android.intent.action.VIEW;end;`,s=`${r}#allowsContentScaling=0`;return a()?s:o}function g(e,t=0){let i=document.createElement("a"),r=document.createElement("img");i.rel="ar",i.href=e,i.hidden=!0,r.alt="",r.hidden=!0,i.appendChild(r),document.body.appendChild(i),window.setTimeout(()=>{i.click(),i.remove()},t)}function h(e,t,i){let r=function(e,t,i){let{brand:r}=i??n();if(a()){let i=new URL("https://appclip.apple.com/id");return i.searchParams.set("p","com.us.vizbl.Clip"),i.searchParams.set("tinuuid",e),t&&i.searchParams.set("hid",t),i.searchParams.set("region","arizo"===r?"ru":"en"),i.toString()}return`intent:/${window.location.pathname}#Intent;scheme=open;package=com.us.vizbl;end`}(e,t,i);window.self===window.top||l().toLowerCase().includes("edge")?window.location.assign(r):window.open(r,"_top")}function m(e,t,i=!1,r){let{viewerOrigin:o}=r??n(),a=new URL("/ar/index.html",o);return a.searchParams.set("tinuuid",e),t&&a.searchParams.set("hid",t),i&&a.searchParams.set("appview","true"),a.toString()}function p(){let e=new WeakMap;return function(t){let i=e.get(t);i?.cleanup?.();let r={revision:(i?.revision??0)+1};return e.set(t,r),{isCurrent:()=>e.get(t)===r,register(i){let n=!1,o=()=>{n||(n=!0,i())};return e.get(t)!==r?(o(),o):(r.cleanup=o,()=>{e.get(t)===r&&e.delete(t),o()})}}}}let f=0,v={arizo:{conjunction:"и",privacyLabel:"Политика конфиденциальности",privacyUrl:"https://arizo.ru/privacy-policy/",termsLabel:"Условия использования",termsUrl:"https://arizo.ru/terms-of-use/"},vizbl:{conjunction:"and",privacyLabel:"Privacy Policy",privacyUrl:"https://vizbl.com/legal/privacy-policy",termsLabel:"Terms of Use",termsUrl:"https://vizbl.com/legal/terms-of-use"}};function w(){return window.QRCode}function b(e,t,i){let r=document.createElement("a");return r.dataset.vizblLegalLink=e,r.href=t,r.rel="noopener noreferrer",r.target="_blank",r.textContent=i,Object.assign(r.style,{color:"inherit",textDecoration:"underline",textUnderlineOffset:"2px",whiteSpace:"nowrap"}),r}async function y(e,r="vizblQrModal",o,a){let s,l=++f;i?.(),document.querySelectorAll("[data-vizbl-qr-modal]").forEach(e=>e.remove());let d=function(e){let{brand:t,viewerOrigin:i}=e??n(),r="arizo"===t,o=document.createElement("div");o.dataset.vizblQrModal="",o.setAttribute("aria-label","View object in augmented reality"),o.setAttribute("aria-modal","true"),o.setAttribute("role","dialog"),Object.assign(o.style,{alignItems:"center",backgroundColor:"rgba(0,0,0,0.25)",display:"none",height:"100%",justifyContent:"center",left:"0",position:"fixed",top:"0",width:"100%",zIndex:"9999"});let a=document.createElement("div");Object.assign(a.style,{backgroundColor:"#fff",borderRadius:"12px",boxSizing:"border-box",color:"#000",fontFamily:"Inter, sans-serif",minHeight:"372px",padding:"48px 52px 40px",position:"relative",width:"min(460px, calc(100vw - 32px))"});let s=document.createElement("button");s.type="button",s.dataset.vizblQrClose="",s.setAttribute("aria-label","Close QR code"),s.textContent="\xd7",Object.assign(s.style,{background:"none",border:"none",color:"#AEB1B7",cursor:"pointer",fontSize:"24px",position:"absolute",right:"20px",top:"20px"});let l=document.createElement("div");l.dataset.vizblQrCode="",l.style.margin="0 auto",l.style.width="fit-content";let d=document.createElement("p");d.textContent=r?"Отсканируйте этот QR-код камерой телефона, чтобы примерить объект в интерьере":"Scan this QR code with your phone camera to view the object in Augmented Reality",Object.assign(d.style,{fontSize:"16px",fontWeight:"500",lineHeight:"24px",margin:"24px 0 0",textAlign:"center"});let c=document.createElement("p");Object.assign(c.style,{color:"#93979F",fontSize:"12px",lineHeight:"16px",margin:"12px 0 0",textAlign:"center"});let u=v[t],g=b("terms",u.termsUrl,u.termsLabel),h=b("privacy",u.privacyUrl,u.privacyLabel);c.append(r?"*Требуется устройство и браузер с поддержкой AR. Рекомендуем iOS 12 или новее с Safari либо Android 7.0 или новее с Chrome.":"*Requires an AR-compatible device and browser. We recommend iOS 12 or later with Safari, or Android 7.0 or later with Chrome.",document.createElement("br"),g,` ${u.conjunction} `,h);let m=document.createElement("p");m.textContent=`Powered by ${r?"Arizo":"Vizbl"}`,Object.assign(m.style,{color:"#93979F",fontSize:"11px",letterSpacing:"1.5px",margin:"24px 0 4px",textAlign:"center",textTransform:"uppercase"});let p=document.createElement("a");p.dataset.vizblBrandLink="",p.href=r?"https://arizo.ru":"https://vizbl.com",p.style.display="block",p.style.textAlign="center";let f=document.createElement("img");return f.alt=`${r?"Arizo":"Vizbl"} logo`,f.src=`${i}/${r?"logoArizo.svg":"logo.svg"}`,f.height=20,f.width=r?76:60,p.appendChild(f),a.append(s,l,d,c,m,p),o.appendChild(a),o}(a);d.id=r;let c=d.querySelector("[data-vizbl-qr-close]"),u=Array.from(d.querySelectorAll("button, a[href]")),g=!1,h=e=>{if("Escape"===e.key){e.preventDefault(),s();return}if("Tab"!==e.key||0===u.length)return;let t=u[0],i=u.at(-1)??t;e.shiftKey&&(document.activeElement===t||!d.contains(document.activeElement))?(e.preventDefault(),i.focus()):e.shiftKey||document.activeElement!==i||(e.preventDefault(),t.focus())};i=s=()=>{g||(g=!0,document.removeEventListener("keydown",h),d.remove(),i===s&&(i=void 0),o?.focus({preventScroll:!0}))},c?.addEventListener("click",s),d.addEventListener("click",e=>{e.target===d&&s()}),document.body.appendChild(d),document.addEventListener("keydown",h),function(){let e="https://fonts.googleapis.com/css2?family=Inter&display=swap";if(Array.from(document.querySelectorAll('link[rel="stylesheet"]')).some(t=>t.href===e||t.getAttribute("href")===e))return;let t=document.createElement("link");t.rel="stylesheet",t.href=e,document.head.appendChild(t)}();try{let i=await function(e){let i=w();if(i)return Promise.resolve(i);if(t)return t;let{qrCodeScriptUrl:r}=e??n();return t=new Promise((e,i)=>{let n,o=document.createElement("script"),a=()=>{n();let r=w();r?e(r):(o.remove(),t=void 0,i(Error("QR code runtime did not expose QRCode")))},s=()=>{n(),o.remove(),t=void 0,i(Error("Failed to load QR code runtime"))};n=()=>{o.removeEventListener("load",a),o.removeEventListener("error",s)},o.addEventListener("load",a,{once:!0}),o.addEventListener("error",s,{once:!0}),o.src=r,o.async=!0,o.dataset.vizblQrScript="true",document.head.appendChild(o)})}(a);if(l!==f||!d.isConnected)return s(),s;let r=d.querySelector("[data-vizbl-qr-code]");return r&&new i(r,{correctLevel:i.CorrectLevel.L,height:148,text:e,width:148}),d.style.display="flex",c?.focus({preventScroll:!0}),s}catch(e){throw s(),e}}class E extends Error{code;constructor(e){super(e),this.code=e,this.name="WidgetRuntimeError"}}function A(e){return e.runtimeConfig??n()}function I(e,t,i={}){let r=new URL(t,e);for(let[e,t]of Object.entries(i))t&&r.searchParams.set(e,t);return r.toString()}async function C(e,t,i){try{return await (i.fetchImpl??i.runtimeConfig?.fetchImpl??n().fetchImpl)(e,{...t,signal:i.signal})}catch(e){if(e instanceof DOMException&&"AbortError"===e.name)throw e;throw new E("NETWORK_ERROR")}}async function S(e){try{let t=await e.json();return[t.code,t.error,t.message].flatMap(e=>Array.isArray(e)?e:[e]).filter(e=>"string"==typeof e).join(" ").toLowerCase()}catch{return""}}async function k(e,t){let i=await S(e);return new E(429===e.status?"RATE_LIMITED":e.status>=500?"API_UNAVAILABLE":404===e.status&&"object"===t?"OBJECT_NOT_FOUND":i.includes("domain")||i.includes("origin")?"DOMAIN_NOT_ALLOWED":i.includes("revoked")?"KEY_REVOKED":i.includes("expired")?"activation"===t?"KEY_EXPIRED":"SESSION_EXPIRED":i.includes("policy")||i.includes("not available for this object")?"POLICY_DENIED":401===e.status||403===e.status?"activation"===t?"INVALID_KEY":"SESSION_EXPIRED":"REQUEST_FAILED")}async function T(e){try{return await e.json()}catch{throw new E("INVALID_RESPONSE")}}function L(e){if(!e||"object"!=typeof e||"string"!=typeof e.token||!e.token.trim()||"string"!=typeof e.sid||!e.sid.trim()||"number"!=typeof e.expiresIn||!Number.isFinite(e.expiresIn)||e.expiresIn<=0)throw new E("INVALID_RESPONSE");return e}async function x(e,t={}){let{apiOrigin:i}=A(t),r=await C(I(i,"/public/widget/activate-core",{mode:t.mode}),{cache:"no-store",headers:{"x-api-key":e},method:"POST"},t);if(!r.ok)throw await k(r,"activation");let n=await T(r);if("string"!=typeof n.productType)throw new E("INVALID_RESPONSE");return{...L(n.widgetSession),productType:n.productType}}async function z(e,t,i={}){let{apiOrigin:r}=A(i),n=await C(`${r}/public/widget/token`,{body:JSON.stringify({token:t,...i.mode?{mode:i.mode}:{}}),cache:"no-store",headers:{"Content-Type":"application/json","x-api-key":e},method:"POST"},i);if(!n.ok)throw await k(n,"token");return L(await T(n))}async function O(e,t,i={}){let{apiOrigin:r}=A(i),n=await C(I(r,`/public/objects/by-tinuuid/${encodeURIComponent(e)}`,{variantId:i.variantId}),{cache:"no-store",headers:{"x-widget-session-token":t},method:"GET"},i);if(!n.ok)throw await k(n,"object");let o=await T(n);if(!o||"object"!=typeof o||Array.isArray(o))throw new E("INVALID_RESPONSE");return o}async function R(e,t,i,r={}){let{apiOrigin:n}=A(r),o=await C(`${n}/public/widget/events`,{body:JSON.stringify({event:e,...i?{objectId:i}:{},...r.variantId?{variantId:r.variantId}:{},timestamp:new Date().toISOString()}),cache:"no-store",headers:{"Content-Type":"application/json","x-widget-session-token":t},keepalive:!0,method:"POST"},r);if(!o.ok)throw await k(o,"event");let a=await T(o);if(!a||"object"!=typeof a||Array.isArray(a)||"boolean"!=typeof a.ok)throw new E("INVALID_RESPONSE")}async function N(e,t,i){let r=i??n(),{fetchImpl:o,legacyApiOrigin:a}=r,s=await C(`${a}/obj/Fetch`,{body:JSON.stringify({tinuuid:e}),headers:{"Content-Type":"application/json"},method:"POST"},{fetchImpl:o,runtimeConfig:r,signal:t});if(!s.ok)throw await k(s,"object");let l=await T(s);if(!l||"object"!=typeof l||Array.isArray(l))throw new E("INVALID_RESPONSE");return l}async function D(e,t){let{fetchImpl:i,legacyApiOrigin:r}=t??n();await i(`${r}/obj/IncrViews`,{body:JSON.stringify({tinuuid:e}),headers:{"Content-Type":"application/json"},method:"POST"})}function P(e){try{let t=e?.();t instanceof Promise&&t.catch(()=>void 0)}catch{}}let j=p();function _(e){if(e?.aborted)throw new DOMException("Aborted","AbortError")}async function U(e,t={}){let i,r,n=j(e),o=e.getAttribute("data-native-link"),c=e.dataset.objectTinuuid?.trim(),p=e.dataset.objectHid?.trim()||void 0;if(!c)throw Error("Object ID is required");_(t.signal);let f=t.loadObject??((e,i)=>N(e,i,t.runtimeConfig)),v=t.object??await f(c,t.signal);if(_(t.signal),!n.isCurrent())return()=>void 0;let w=p?v.materials.find(e=>e.hid===p):v.materials[0];if(!w?.native?.glbUrl||!w.native.usdzUrl)throw Error("Native AR assets are unavailable");let b=u(w.native,v.type),E=s(),A=!1,I=0;e.querySelector("img")||((i=document.createElement("img")).alt="",i.hidden=!0,e.appendChild(i));let C=()=>t.trackView?t.trackView():D(c,t.runtimeConfig),S=i=>{i.preventDefault();let o=++I;r?.(),r=void 0,Promise.resolve(t.getDesktopQrUrl?.()??m(c,p,!0,t.runtimeConfig)).then(i=>{if(o===I&&n.isCurrent())return P(()=>t.onAction?.("interacted")),y(i,`vizbl-${c}`,e,t.runtimeConfig)}).then(e=>{if(e){if(o!==I||!n.isCurrent())return void e();r=e}}).catch(()=>void 0)},k=async e=>{let i;if(i=l().toLowerCase(),["firefox","edge","opera"].some(e=>i.includes(e))){if(e.preventDefault(),A)return;A=!0,P(()=>t.onAction?.("ar_launched"));try{await Promise.resolve(C()).catch(()=>void 0)}finally{A=!1,a()&&d()?h(c,p,t.runtimeConfig):g(b)}return}P(()=>t.onAction?.("ar_launched")),P(C),a()&&d()?(e.preventDefault(),h(c,p,t.runtimeConfig)):g(b)};return E?(e.dataset.nativeLink=b,e.addEventListener("click",k)):e.addEventListener("click",S),n.register(()=>{I+=1,e.removeEventListener("click",S),e.removeEventListener("click",k),r?.(),i?.remove(),null===o?e.removeAttribute("data-native-link"):e.setAttribute("data-native-link",o)})}var V=!1;if("u">typeof window){var M={get passive(){V=!0;return}};window.addEventListener("testPassive",null,M),window.removeEventListener("testPassive",null,M)}var $="u">typeof window&&window.navigator&&window.navigator.platform&&(/iP(ad|hone|od)/.test(window.navigator.platform)||"MacIntel"===window.navigator.platform&&window.navigator.maxTouchPoints>1),B=[],q=!1,H=-1,W=void 0,F=void 0,K=void 0,Q=function(e){return B.some(function(t){return!!(t.options.allowTouchMove&&t.options.allowTouchMove(e))})},Y=function(e){var t=e||window.event;return!!Q(t.target)||t.touches.length>1||(t.preventDefault&&t.preventDefault(),!1)},X=function(e){if(void 0===K){var t=!!e&&!0===e.reserveScrollBarGap,i=window.innerWidth-document.documentElement.clientWidth;if(t&&i>0){var r=parseInt(window.getComputedStyle(document.body).getPropertyValue("padding-right"),10);K=document.body.style.paddingRight,document.body.style.paddingRight=r+i+"px"}}void 0===W&&(W=document.body.style.overflow,document.body.style.overflow="hidden")},J=function(){void 0!==K&&(document.body.style.paddingRight=K,K=void 0),void 0!==W&&(document.body.style.overflow=W,W=void 0)},Z=function(){if(void 0!==F){var e=-parseInt(document.body.style.top,10),t=-parseInt(document.body.style.left,10);document.body.style.position=F.position,document.body.style.top=F.top,document.body.style.left=F.left,window.scrollTo(t,e),F=void 0}},G=function(e,t){var i=e.targetTouches[0].clientY-H;return!Q(e.target)&&(t&&0===t.scrollTop&&i>0?Y(e):t&&t.scrollHeight-t.scrollTop<=t.clientHeight&&i<0?Y(e):(e.stopPropagation(),!0))},ee=function(e,t){e?!B.some(function(t){return t.targetElement===e})&&(B=[].concat(function(e){if(!Array.isArray(e))return Array.from(e);for(var t=0,i=Array(e.length);t<e.length;t++)i[t]=e[t];return i}(B),[{targetElement:e,options:t||{}}]),$?window.requestAnimationFrame(function(){if(void 0===F){F={position:document.body.style.position,top:document.body.style.top,left:document.body.style.left};var e=window,t=e.scrollY,i=e.scrollX,r=e.innerHeight;document.body.style.position="fixed",document.body.style.top=-t,document.body.style.left=-i,setTimeout(function(){return window.requestAnimationFrame(function(){var e=r-window.innerHeight;e&&t>=r&&(document.body.style.top=-(t+e))})},300)}}):X(t),$&&(e.ontouchstart=function(e){1===e.targetTouches.length&&(H=e.targetTouches[0].clientY)},e.ontouchmove=function(t){1===t.targetTouches.length&&G(t,e)},q||(document.addEventListener("touchmove",Y,V?{passive:!1}:void 0),q=!0))):console.error("disableBodyScroll unsuccessful - targetElement must be provided when calling disableBodyScroll on IOS devices.")},et=function(e){e?(B=B.filter(function(t){return t.targetElement!==e}),$&&(e.ontouchstart=null,e.ontouchmove=null,q&&0===B.length&&(document.removeEventListener("touchmove",Y,V?{passive:!1}:void 0),q=!1)),$?Z():J()):console.error("enableBodyScroll unsuccessful - targetElement must be provided when calling enableBodyScroll on IOS devices.")};let ei=["cm","inch"],er="vizbl_viewer",en=p();function eo(e){return e&&ei.includes(e)?e:"inch"}function ea(e){let t=new URL("/model-viewer",e.modelViewerOrigin??n().modelViewerOrigin);t.searchParams.set("tinuuid",e.tinuuid),e.hid&&t.searchParams.set("hid",e.hid),t.searchParams.set("size-type",e.sizeType);let i=new URLSearchParams;return e.apiKey&&i.set("api-key",e.apiKey),e.mode&&i.set("mode",e.mode),e.widgetSessionToken&&i.set("widget-session-token",e.widgetSessionToken),t.hash=i.toString(),t.toString()}let es=p();function el(e){if(e?.aborted)throw new DOMException("Aborted","AbortError")}async function ed(e,t={}){let i,r,n=es(e),o=e.getAttribute("href"),a=e.getAttribute("rel"),l=e.dataset.objectTinuuid?.trim(),d=e.dataset.objectHid?.trim()||void 0;if(!l)throw Error("Object ID is required");el(t.signal);let c=t.loadObject??((e,i)=>N(e,i,t.runtimeConfig)),g=t.object??await c(l,t.signal);if(el(t.signal),!n.isCurrent())return()=>void 0;let h=d?g.materials.find(e=>e.hid===d):g.materials[0];if(!h?.native?.glbUrl||!h.native.usdzUrl)throw Error("Native AR assets are unavailable");let p=u(h.native,g.type),f=s(),v=0;e.rel="ar",e.querySelector("img")||((i=document.createElement("img")).alt="",i.hidden=!0,e.appendChild(i));let w=i=>{i.preventDefault();let o=++v;r?.(),r=void 0,Promise.resolve(t.getDesktopQrUrl?.()??m(l,d,!1,t.runtimeConfig)).then(i=>{if(o===v&&n.isCurrent())return P(()=>t.onAction?.("interacted")),y(i,`vizbl-${l}`,e,t.runtimeConfig)}).then(e=>{if(e){if(o!==v||!n.isCurrent())return void e();r=e}}).catch(()=>void 0)},b=()=>{P(t.trackView??(()=>D(l,t.runtimeConfig))),P(()=>t.onAction?.("ar_launched"))};return f?(e.href=p,e.addEventListener("click",b)):(e.href="#",e.addEventListener("click",w)),n.register(()=>{v+=1,e.removeEventListener("click",w),e.removeEventListener("click",b),r?.(),i?.remove(),null===o?e.removeAttribute("href"):e.setAttribute("href",o),null===a?e.removeAttribute("rel"):e.setAttribute("rel",a)})}let ec=["advanced-ar","ar-one-click","ar-viewer"],eu={arizo:"arizo-core",vizbl:"vizbl-core"},eg=new Set(["core-ar","core-ar-shopify"]),eh={"advanced-ar":"View in advanced AR","ar-one-click":"View in AR","ar-viewer":"View in 3D & AR"},em={"advanced-ar":"advanced-ar-view","ar-one-click":"ar-view","ar-viewer":"ar-viewer"},ep=["api-key","dev","object-id","size-type","trigger-class","type","variant-id"],ef=new Set(["API_UNAVAILABLE","INVALID_RESPONSE","NETWORK_ERROR","REQUEST_FAILED","SESSION_EXPIRED"]),ev="core-ar-widget-styles";class ew extends Error{code;constructor(e){super(e),this.code=e,this.name="CoreArWidgetComponentError"}}function eb(e){return ec.includes(e)}function ey(e,t){let i=Array.isArray(e.materials)?e.materials:[],r=t?i.find(e=>e.hid===t):i[0];if(!r)throw new ew(t?"VARIANT_NOT_FOUND":"MODEL_UNAVAILABLE");return r}function eE(e,t){let i=t.policy;if(!("ar-one-click"===e?i?.instantArView!==!1:i?.appClip!==!1))throw new ew("POLICY_DENIED")}let eA="u"<typeof HTMLElement?class{}:HTMLElement;class eI extends eA{static get observedAttributes(){return[...ep]}get triggerClass(){return this.getAttribute("trigger-class")??""}set triggerClass(e){let t="string"==typeof e?e.trim():"";t?this.setAttribute("trigger-class",t):this.removeAttribute("trigger-class")}get unstyled(){return this.hasAttribute("unstyled")}set unstyled(e){this.toggleAttribute("unstyled",!!e)}abortController;actionResetTimer;cleanup;customLabelNodes=null;initializationRevision=0;object;queued=!1;session;trigger;variantId;widgetMode;connectedCallback(){!function(){if(document.getElementById(ev))return;let e=document.createElement("style");e.id=ev,e.textContent=`
2
2
  :where(vizbl-core, arizo-core) {
3
3
  display: inline-block;
4
4
  --core-ar-widget-background: #3556f0;
@@ -65,4 +65,4 @@
65
65
  :where(vizbl-core, arizo-core)[data-state="error"] [data-core-ar-widget-trigger] {
66
66
  cursor: not-allowed;
67
67
  }
68
- `,document.head.appendChild(e)}(),this.captureCustomLabel(),this.queueInitialization()}disconnectedCallback(){this.initializationRevision+=1,this.abortController?.abort(),this.abortController=void 0,this.cleanup?.(),this.cleanup=void 0,this.clearActionResetTimer()}attributeChangedCallback(e,t,i){if(t!==i){if("trigger-class"===e)return void this.applyTriggerClass();("api-key"===e||"dev"===e)&&(this.session=void 0),this.isConnected&&(this.abortController?.abort(),this.cleanup?.(),this.cleanup=void 0,this.setState("loading"),this.queueInitialization())}}captureCustomLabel(){if(null!==this.customLabelNodes)return;let e=Array.from(this.childNodes),t=e.some(e=>e.nodeType!==Node.TEXT_NODE||!!e.textContent?.trim());this.customLabelNodes=t?e:[]}queueInitialization(){this.queued||(this.queued=!0,queueMicrotask(()=>{this.queued=!1,this.isConnected&&this.initialize()}))}async initialize(){let e=++this.initializationRevision;this.abortController?.abort(),this.cleanup?.(),this.cleanup=void 0,this.object=void 0,this.variantId=void 0,this.widgetMode=void 0,this.clearActionResetTimer();let t=new AbortController;this.abortController=t;let i=this.getAttribute("type")?.trim()??"",r=ef(i)?i:"ar-viewer",o=this.getAttribute("object-id")?.trim()??"",n=this.getAttribute("variant-id")?.trim()||void 0,a=this.getAttribute("api-key")?.trim()??"",s=this.getAttribute("size-type")?.trim()||void 0;this.removeAttribute("data-error-code"),this.setState("loading"),this.renderTrigger(r);try{let r=this.resolveRuntimeConfig();if(!a)throw new ev("MISSING_API_KEY");if(!o)throw new ev("MISSING_OBJECT_ID");if(!ef(i))throw new ev("INVALID_TYPE");if("ar-viewer"===i&&s&&"cm"!==s&&"inch"!==s)throw new ev("INVALID_SIZE_TYPE");let l=eh[i],c=await this.ensureSession(a,r,l,t.signal);this.assertCurrent(e,t.signal);let d=await this.fetchObjectWithSession(o,a,c,r,t.signal,n);this.assertCurrent(e,t.signal);let u=function(e,t){let i=Array.isArray(e.materials)?e.materials:[],r=t?i.find(e=>e.hid===t):i[0];if(!r)throw new ev(t?"VARIANT_NOT_FOUND":"MODEL_UNAVAILABLE");return r}(d,n),h=d.policy;if(!("ar-viewer"===i?h?.ignViewerModal!==!1:"ar-one-click"===i?h?.instantArView!==!1:h?.appClip!==!1))throw new ev("POLICY_DENIED");if("ar-viewer"!==i&&(!u.native?.glbUrl||!u.native.usdzUrl))throw new ev("MODEL_UNAVAILABLE");this.object=d,this.variantId=n,this.widgetMode=l,this.applyIntegrationData(o,n,s);let g=await this.initializeTrigger(i,d,r,t.signal);try{this.assertCurrent(e,t.signal)}catch(e){throw g(),e}this.cleanup=g,this.setState("ready"),this.dispatchWidgetEvent("core-ar-ready",{objectId:o,type:i})}catch(n){if(e!==this.initializationRevision||t.signal.aborted||n instanceof DOMException&&"AbortError"===n.name)return;let r=n instanceof ev||n instanceof E?n.code:"INITIALIZATION_FAILED";this.setAttribute("data-error-code",r),this.setState("error"),this.dispatchWidgetEvent("core-ar-error",{code:r,objectId:o,type:i})}}async ensureSession(e,t,i,r,o=!1){let n=`${t.apiOrigin}|${t.viewerOrigin}|${i}`,a=this.session?.publicKey===e&&this.session.runtimeKey===n?this.session:void 0;if(a&&!o&&a.expiresAt-Date.now()>3e4)return a;if(a)try{let i=await z(e,a.token,{mode:a.mode,runtimeConfig:t,signal:r}),o={...a,...i,expiresAt:Date.now()+1e3*i.expiresIn};return this.session=o,o}catch(e){if(!(e instanceof E)||!ep.has(e.code))throw e;this.session=void 0}let s=await k(e,{mode:i,runtimeConfig:t,signal:r});if(!ed.has(s.productType))throw new ev("POLICY_DENIED");let l={expiresAt:Date.now()+1e3*s.expiresIn,mode:i,productType:s.productType,publicKey:e,runtimeKey:n,sid:s.sid,token:s.token};return this.session=l,l}async fetchObjectWithSession(e,t,i,r,o,n){try{return await O(e,i.token,{runtimeConfig:r,signal:o,variantId:n})}catch(a){if(!(a instanceof E)||"SESSION_EXPIRED"!==a.code)throw a;return O(e,(await this.ensureSession(t,r,i.mode,o,!0)).token,{runtimeConfig:r,signal:o,variantId:n})}}assertCurrent(e,t){if(e!==this.initializationRevision||t.aborted)throw new DOMException("Aborted","AbortError")}renderTrigger(e){let t="ar-one-click"===e?document.createElement("a"):document.createElement("button");if(t.dataset.coreArWidgetTrigger="",t.setAttribute("part","trigger"),t.addEventListener("click",e=>{"ready"!==this.dataset.state&&(e.preventDefault(),e.stopImmediatePropagation())}),t instanceof HTMLButtonElement&&(t.type="button"),t instanceof HTMLAnchorElement&&(t.href="#",t.rel="ar"),"ar-viewer"===e&&t.setAttribute("aria-haspopup","dialog"),"ar-viewer"!==e){let e=document.createElement("img");e.alt="",e.hidden=!0,t.appendChild(e)}let i=document.createElement("span");i.dataset.coreArWidgetLabel="",this.customLabelNodes?.length?i.append(...this.customLabelNodes):i.textContent=eu[e],t.appendChild(i),this.trigger=t,this.applyTriggerClass(),this.replaceChildren(t),this.updateTriggerAccessibility(this.dataset.state)}applyTriggerClass(){if(!this.trigger)return;let e=this.triggerClass.trim();e?this.trigger.className=e:this.trigger.removeAttribute("class")}applyIntegrationData(e,t,i){this.trigger&&(this.trigger.dataset.objectTinuuid=e,t?this.trigger.dataset.objectHid=t:delete this.trigger.dataset.objectHid,i?this.trigger.dataset.sizeType=i:delete this.trigger.dataset.sizeType)}async initializeTrigger(e,t,i,r){if(!this.trigger)throw new ev("INITIALIZATION_FAILED");if("ar-viewer"===e)return function(e,t={}){let i,r=eo(e),n=()=>{var r;if(i)return;let n=e.dataset.objectTinuuid?.trim();if(!n)return;let a=function(e){var t,i,r,n;let a,s,l,c,d;if(document.getElementById(er))return null;let u=document.createElement("div"),h=document.createElement("div"),g=document.createElement("div"),p=e.containerClassName?document.getElementsByClassName(e.containerClassName)[0]:null,m=!!p,v=m?h:u,f=!1,w=e=>{"Escape"===e.key&&a()};a=()=>{f||(f=!0,document.removeEventListener("keydown",w),et(v),(m?h:u).remove(),e.onClose?.(),e.restoreFocusTo?.focus({preventScroll:!0}))},u.id=er,Object.assign(u.style,{inset:"0",overflow:"auto",position:"fixed",zIndex:"11111"}),u.style.webkitOverflowScrolling="touch",h.setAttribute("role","dialog"),h.setAttribute("aria-modal","true"),h.setAttribute("aria-label","3D model viewer"),Object.assign(g.style,{animation:"vex-fadein 0.5s",background:"#fff",inset:"0",position:"fixed",zIndex:"11111"}),g.addEventListener("click",a),(e.width||e.height)&&(g.style.background="rgba(0, 0, 0, 0.8)",Object.assign(h.style,{borderRadius:"12px",height:e.height??"100%",left:"50%",overflow:"hidden",position:"absolute",top:"50%",transform:"translate(-50%, -50%)",width:e.width??"100%",zIndex:"11112"}));let b=(t=e.crossClassName,i=a,(s=document.createElement("button")).type="button",s.setAttribute("aria-label","Close 3D model viewer"),t&&(s.className=t),Object.assign(s.style,{alignItems:"center",background:"#fff",border:"1px solid #E3E7E7",borderRadius:"4px",boxSizing:"border-box",cursor:"pointer",display:"flex",height:"40px",inset:"24px 24px auto auto",justifyContent:"center",padding:"8px 16px",position:"absolute",width:"56px",zIndex:"11113"}),s.innerHTML='<svg aria-hidden="true" style="flex-shrink:0" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12L19 6.41Z" fill="#484D50"/></svg>',s.addEventListener("click",i),s);return h.append((l=e.viewerOrigin??o().viewerOrigin,(c=new URL(e.hid?`${encodeURIComponent(e.tinuuid)}/${encodeURIComponent(e.hid)}`:encodeURIComponent(e.tinuuid),`${l.replace(/\/$/,"")}/`)).searchParams.set("hide-title",e.hideTitle??""),c.searchParams.set("hide-preview",e.hidePreview??""),c.searchParams.set("button-bg-color",e.buttonBgColor??""),c.searchParams.set("button-border-color",e.buttonBorderColor??""),c.searchParams.set("button-text-color",e.buttonTextColor??""),c.searchParams.set("background-color",e.backgroundColor??""),c.searchParams.set("size_type",e.sizeType),r=c.toString(),n=e.backgroundColor,(d=document.createElement("iframe")).src=r,d.title="3D model viewer",d.allow="fullscreen; xr-spatial-tracking",Object.assign(d.style,{backgroundColor:n??"white",border:"none",height:"100%",inset:"0",position:"absolute",width:"100%",zIndex:"11112"}),d),b),p?(h.id=er,p.appendChild(h)):(u.append(g,h),document.body.appendChild(u)),document.addEventListener("keydown",w),ee(v),b.focus({preventScroll:!0}),a}({backgroundColor:e.dataset.background,buttonBgColor:e.dataset.buttonBgColor,buttonBorderColor:e.dataset.buttonBorderColor,buttonTextColor:e.dataset.buttonTextColor,containerClassName:e.dataset.container,crossClassName:e.dataset.crossClassName,height:e.dataset.height?.trim(),hid:e.dataset.objectHid,hidePreview:e.dataset.hidePreview,hideTitle:e.dataset.hideTitle,onClose:()=>{i=void 0,t.onClose?.()},restoreFocusTo:e,sizeType:(r=e.dataset.sizeType)&&ei.includes(r)?r:"inch",tinuuid:n,viewerOrigin:t.viewerOrigin,width:e.dataset.width?.trim()});a&&(i=a,t.onOpen?.(),D(()=>t.onAction?.("widget_opened")))};return e.addEventListener("click",n),r.register(()=>{e.removeEventListener("click",n),i?.(),i=void 0})}(this.trigger,{onAction:e=>this.handleAction(e,i),onClose:()=>{this.isConnected&&this.setState("ready")},onOpen:()=>this.setState("opening"),viewerOrigin:i.viewerOrigin});let n={object:t,onAction:e=>this.handleAction(e,i),runtimeConfig:i,signal:r,trackView:()=>this.trackEvent("ar_launched",i)};if("ar-one-click"===e){if(!(this.trigger instanceof HTMLAnchorElement))throw new ev("INITIALIZATION_FAILED");return es(this.trigger,n)}return U(this.trigger,n)}handleAction(e,t){this.setState("opening"),"widget_opened"===e&&this.trackEvent(e,t),"ar-viewer"!==this.getAttribute("type")&&(this.clearActionResetTimer(),this.actionResetTimer=window.setTimeout(()=>{this.isConnected&&this.setState("ready")},300))}async trackEvent(e,t){let i=this.getAttribute("api-key")?.trim(),r=this.widgetMode;if(i&&r&&this.isConnected)try{let o=await this.ensureSession(i,t,r);await R(e,o.token,this.object?.uuid,{runtimeConfig:t,variantId:this.variantId})}catch{}}clearActionResetTimer(){void 0!==this.actionResetTimer&&(window.clearTimeout(this.actionResetTimer),this.actionResetTimer=void 0)}setState(e){this.dataset.state=e,this.updateTriggerAccessibility(e)}updateTriggerAccessibility(e){if(!this.trigger)return;let t="ready"===e;this.trigger.setAttribute("aria-busy",String("loading"===e)),this.trigger.setAttribute("aria-disabled",String(!t)),this.trigger.tabIndex=t?0:-1,this.trigger instanceof HTMLButtonElement&&(this.trigger.disabled=!t)}dispatchWidgetEvent(e,t){this.dispatchEvent(new CustomEvent(e,{bubbles:!0,composed:!0,detail:t}))}}function ey(e){if("u"<typeof customElements)return;let t=ec[e],i=customElements.get(t);if(i)return i;class o extends eb{resolveRuntimeConfig(){return function(e,t="prod"){var i,o;let n,a,s,l,c,d="arizo"===e?"arizo.ru":"vizbl.com",u="dev"===t?"-dev":"";return n=r((i={apiOrigin:`https://api${u}.${d}`,viewerOrigin:`https://viewer${u}.${d}`}).apiOrigin,"apiOrigin"),a=r(i.viewerOrigin,"viewerOrigin"),c=i.legacyApiOrigin?(s=r(o=i.legacyApiOrigin,"legacyApiOrigin"),(l=new URL(o).pathname.replace(/\/+$/,""))?`${s}${l}`:s):`${n}/v1`,{apiOrigin:n,brand:new URL(a).hostname.endsWith("arizo.ru")?"arizo":"vizbl",fetchImpl:i.fetchImpl??fetch,legacyApiOrigin:c,qrCodeScriptUrl:i.qrCodeScriptUrl??`${a}/vendor/qrcode.min.js`,viewerOrigin:a}}(e,this.hasAttribute("dev")?"dev":"prod")}}return customElements.define(t,o),o}ey("arizo"),ey("vizbl")})();
68
+ `,document.head.appendChild(e)}(),this.captureCustomLabel(),this.queueInitialization()}disconnectedCallback(){this.initializationRevision+=1,this.abortController?.abort(),this.abortController=void 0,this.cleanup?.(),this.cleanup=void 0,this.clearActionResetTimer()}attributeChangedCallback(e,t,i){if(t!==i){if("trigger-class"===e)return void this.applyTriggerClass();("api-key"===e||"dev"===e)&&(this.session=void 0),this.isConnected&&(this.abortController?.abort(),this.cleanup?.(),this.cleanup=void 0,this.setState("loading"),this.queueInitialization())}}captureCustomLabel(){if(null!==this.customLabelNodes)return;let e=Array.from(this.childNodes),t=e.some(e=>e.nodeType!==Node.TEXT_NODE||!!e.textContent?.trim());this.customLabelNodes=t?e:[]}queueInitialization(){this.queued||(this.queued=!0,queueMicrotask(()=>{this.queued=!1,this.isConnected&&this.initialize()}))}async initialize(){let e=++this.initializationRevision;this.abortController?.abort(),this.cleanup?.(),this.cleanup=void 0,this.object=void 0,this.variantId=void 0,this.widgetMode=void 0,this.clearActionResetTimer();let t=new AbortController;this.abortController=t;let i=this.getAttribute("type")?.trim()??"",r=eb(i)?i:"ar-viewer",n=this.getAttribute("object-id")?.trim()??"",o=this.getAttribute("variant-id")?.trim()||void 0,a=this.getAttribute("api-key")?.trim()??"",l=this.getAttribute("size-type")?.trim()||void 0;this.removeAttribute("data-error-code"),this.setState("loading"),this.renderTrigger(r);try{let r,d=this.resolveRuntimeConfig();if(!a)throw new ew("MISSING_API_KEY");if(!n)throw new ew("MISSING_OBJECT_ID");if(!eb(i))throw new ew("INVALID_TYPE");if("ar-viewer"===i&&l&&"cm"!==l&&"inch"!==l)throw new ew("INVALID_SIZE_TYPE");let c=em[i],u=await this.ensureSession(a,d,c,t.signal);if(this.assertCurrent(e,t.signal),this.variantId=o,this.widgetMode=c,this.applyIntegrationData(n,o,l),"ar-viewer"===i)r=await N(n,t.signal,d),this.assertCurrent(e,t.signal),ey(r,o),eE(i,r),this.object=r;else{r=s()?await this.fetchObjectWithSession(n,a,u,d,t.signal,o):await N(n,t.signal,d),this.assertCurrent(e,t.signal);let l=ey(r,o);if(eE(i,r),!l.native?.glbUrl||!l.native.usdzUrl)throw new ew("MODEL_UNAVAILABLE");this.object=r}let g=await this.initializeTrigger(i,r,d,t.signal,a,u);try{this.assertCurrent(e,t.signal)}catch(e){throw g(),e}this.cleanup=g,this.setState("ready"),this.dispatchWidgetEvent("core-ar-ready",{objectId:n,type:i})}catch(o){if(e!==this.initializationRevision||t.signal.aborted||o instanceof DOMException&&"AbortError"===o.name)return;let r=o instanceof ew||o instanceof E?o.code:"INITIALIZATION_FAILED";this.setAttribute("data-error-code",r),this.setState("error"),this.dispatchWidgetEvent("core-ar-error",{code:r,objectId:n,type:i})}}async ensureSession(e,t,i,r,n=!1){let o=`${t.apiOrigin}|${t.viewerOrigin}|${t.modelViewerOrigin}|${i}`,a=this.session?.publicKey===e&&this.session.runtimeKey===o?this.session:void 0;if(a&&!n&&a.expiresAt-Date.now()>3e4)return a;if(a)try{let i=await z(e,a.token,{mode:a.mode,runtimeConfig:t,signal:r}),n={...a,...i,expiresAt:Date.now()+1e3*i.expiresIn};return this.session=n,n}catch(e){if(!(e instanceof E)||!ef.has(e.code))throw e;this.session=void 0}let s=await x(e,{mode:i,runtimeConfig:t,signal:r});if(!eg.has(s.productType))throw new ew("POLICY_DENIED");let l={expiresAt:Date.now()+1e3*s.expiresIn,mode:i,productType:s.productType,publicKey:e,runtimeKey:o,sid:s.sid,token:s.token};return this.session=l,l}async fetchObjectWithSession(e,t,i,r,n,o){try{return await O(e,i.token,{runtimeConfig:r,signal:n,variantId:o})}catch(a){if(!(a instanceof E)||"SESSION_EXPIRED"!==a.code)throw a;return O(e,(await this.ensureSession(t,r,i.mode,n,!0)).token,{runtimeConfig:r,signal:n,variantId:o})}}assertCurrent(e,t){if(e!==this.initializationRevision||t.aborted)throw new DOMException("Aborted","AbortError")}renderTrigger(e){let t="ar-one-click"===e?document.createElement("a"):document.createElement("button");if(t.dataset.coreArWidgetTrigger="",t.setAttribute("part","trigger"),t.addEventListener("click",e=>{"ready"!==this.dataset.state&&(e.preventDefault(),e.stopImmediatePropagation())}),t instanceof HTMLButtonElement&&(t.type="button"),t instanceof HTMLAnchorElement&&(t.href="#",t.rel="ar"),"ar-viewer"===e&&t.setAttribute("aria-haspopup","dialog"),"ar-viewer"!==e){let e=document.createElement("img");e.alt="",e.hidden=!0,t.appendChild(e)}let i=document.createElement("span");i.dataset.coreArWidgetLabel="",this.customLabelNodes?.length?i.append(...this.customLabelNodes):i.textContent=eh[e],t.appendChild(i),this.trigger=t,this.applyTriggerClass(),this.replaceChildren(t),this.updateTriggerAccessibility(this.dataset.state)}applyTriggerClass(){if(!this.trigger)return;let e=this.triggerClass.trim();e?this.trigger.className=e:this.trigger.removeAttribute("class")}applyIntegrationData(e,t,i){this.trigger&&(this.trigger.dataset.objectTinuuid=e,t?this.trigger.dataset.objectHid=t:delete this.trigger.dataset.objectHid,i?this.trigger.dataset.sizeType=i:delete this.trigger.dataset.sizeType)}async initializeTrigger(e,t,i,r,n,o){if(!this.trigger)throw new ew("INITIALIZATION_FAILED");if("ar-viewer"===e)return function(e,t={}){let i,r=en(e),n=!1,o=async()=>{if(i||n)return;let o=e.dataset.objectTinuuid?.trim();if(!o)return;n=!0;let a=t.widgetSessionToken;try{t.getWidgetSessionToken&&(a=await t.getWidgetSessionToken())}catch{n=!1;return}if(n=!1,i||!r.isCurrent())return;let s=function(e){var t,i,r,n;let o,a,s;if(document.getElementById(er))return null;let l=document.createElement("div"),d=document.createElement("div"),c=document.createElement("div"),u=e.containerClassName?document.getElementsByClassName(e.containerClassName)[0]:null,g=!!u,h=g?d:l,m=!1,p=e=>{"Escape"===e.key&&o()};o=()=>{m||(m=!0,document.removeEventListener("keydown",p),et(h),(g?d:l).remove(),e.onClose?.(),e.restoreFocusTo?.focus({preventScroll:!0}))},l.id=er,Object.assign(l.style,{inset:"0",overflow:"auto",position:"fixed",zIndex:"11111"}),l.style.webkitOverflowScrolling="touch",d.setAttribute("role","dialog"),d.setAttribute("aria-modal","true"),d.setAttribute("aria-label","3D model viewer"),Object.assign(c.style,{animation:"vex-fadein 0.5s",background:"#fff",inset:"0",position:"fixed",zIndex:"11111"}),c.addEventListener("click",o),(e.width||e.height)&&(c.style.background="rgba(0, 0, 0, 0.8)",Object.assign(d.style,{borderRadius:"12px",height:e.height??"100%",left:"50%",overflow:"hidden",position:"absolute",top:"50%",transform:"translate(-50%, -50%)",width:e.width??"100%",zIndex:"11112"}));let f=(t=e.crossClassName,i=o,(a=document.createElement("button")).type="button",a.setAttribute("aria-label","Close 3D model viewer"),t&&(a.className=t),Object.assign(a.style,{alignItems:"center",background:"#fff",border:"1px solid #E3E7E7",borderRadius:"4px",boxSizing:"border-box",cursor:"pointer",display:"flex",height:"40px",inset:"24px 24px auto auto",justifyContent:"center",padding:"8px 16px",position:"absolute",width:"56px",zIndex:"11113"}),a.innerHTML='<svg aria-hidden="true" style="flex-shrink:0" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12L19 6.41Z" fill="#484D50"/></svg>',a.addEventListener("click",i),a);return d.append((r=ea(e),n=e.backgroundColor,(s=document.createElement("iframe")).src=r,s.title="3D model viewer",s.allow="fullscreen; xr-spatial-tracking",Object.assign(s.style,{backgroundColor:n??"white",border:"none",height:"100%",inset:"0",position:"absolute",width:"100%",zIndex:"11112"}),s),f),u?(d.id=er,u.appendChild(d)):(l.append(c,d),document.body.appendChild(l)),document.addEventListener("keydown",p),ee(h),f.focus({preventScroll:!0}),o}({apiKey:t.apiKey,backgroundColor:e.dataset.background,buttonBgColor:e.dataset.buttonBgColor,buttonBorderColor:e.dataset.buttonBorderColor,buttonTextColor:e.dataset.buttonTextColor,containerClassName:e.dataset.container,crossClassName:e.dataset.crossClassName,height:e.dataset.height?.trim(),hid:e.dataset.objectHid,hidePreview:e.dataset.hidePreview,hideTitle:e.dataset.hideTitle,mode:t.mode,modelViewerOrigin:t.modelViewerOrigin,onClose:()=>{i=void 0,t.onClose?.()},restoreFocusTo:e,sizeType:eo(e.dataset.sizeType),tinuuid:o,widgetSessionToken:a,width:e.dataset.width?.trim()});s&&(i=s,t.onOpen?.(),P(()=>t.onAction?.("widget_opened")))};return e.addEventListener("click",o),r.register(()=>{e.removeEventListener("click",o),i?.(),i=void 0})}(this.trigger,{apiKey:n,getWidgetSessionToken:async()=>(await this.ensureSession(n,i,o.mode)).token,mode:o.mode,modelViewerOrigin:i.modelViewerOrigin,onAction:e=>this.handleAction(e,i),onClose:()=>{this.isConnected&&this.setState("ready")},onOpen:()=>this.setState("opening"),widgetSessionToken:o.token});if(!t)throw new ew("INITIALIZATION_FAILED");let a={getDesktopQrUrl:async()=>{let e=await this.ensureSession(n,i,o.mode);return ea({apiKey:n,hid:this.variantId,mode:e.mode,modelViewerOrigin:i.modelViewerOrigin,sizeType:eo(this.trigger?.dataset.sizeType),tinuuid:this.trigger?.dataset.objectTinuuid??"",widgetSessionToken:e.token})},object:t,onAction:e=>this.handleAction(e,i),runtimeConfig:i,signal:r,trackView:()=>this.trackEvent("ar_launched",i)};if("ar-one-click"===e){if(!(this.trigger instanceof HTMLAnchorElement))throw new ew("INITIALIZATION_FAILED");return ed(this.trigger,a)}return U(this.trigger,a)}handleAction(e,t){this.setState("opening"),("interacted"===e||"widget_opened"===e)&&"ar-viewer"!==this.getAttribute("type")&&this.trackEvent(e,t),"ar-viewer"!==this.getAttribute("type")&&(this.clearActionResetTimer(),this.actionResetTimer=window.setTimeout(()=>{this.isConnected&&this.setState("ready")},300))}async trackEvent(e,t){let i=this.getAttribute("api-key")?.trim(),r=this.widgetMode;if(i&&r&&this.isConnected)try{let n=await this.ensureSession(i,t,r);await R(e,n.token,this.object?.uuid,{runtimeConfig:t,variantId:this.variantId})}catch{}}clearActionResetTimer(){void 0!==this.actionResetTimer&&(window.clearTimeout(this.actionResetTimer),this.actionResetTimer=void 0)}setState(e){this.dataset.state=e,this.updateTriggerAccessibility(e)}updateTriggerAccessibility(e){if(!this.trigger)return;let t="ready"===e;this.trigger.setAttribute("aria-busy",String("loading"===e)),this.trigger.setAttribute("aria-disabled",String(!t)),this.trigger.tabIndex=t?0:-1,this.trigger instanceof HTMLButtonElement&&(this.trigger.disabled=!t)}dispatchWidgetEvent(e,t){this.dispatchEvent(new CustomEvent(e,{bubbles:!0,composed:!0,detail:t}))}}function eC(e){if("u"<typeof customElements)return;let t=eu[e],i=customElements.get(t);if(i)return i;class n extends eI{resolveRuntimeConfig(){return function(e,t="prod"){var i,n;let o,a,s,l,d,c,u,g,h="arizo"===e?"arizo.ru":"vizbl.com",m="dev"===t?"-dev":"";return o=r((i={apiOrigin:`https://api${m}.${h}`,modelViewerOrigin:`https://integrations${m}.${h}`,viewerOrigin:`https://viewer${m}.${h}`}).apiOrigin,"apiOrigin"),a=r(i.viewerOrigin,"viewerOrigin"),d=i.modelViewerOrigin?r(i.modelViewerOrigin,"modelViewerOrigin"):(l=(s=new URL(a)).hostname.match(/^viewer(-dev)?\.(vizbl\.com|arizo\.ru)$/))?`${s.protocol}//integrations${l[1]??""}.${l[2]}`:a,g=i.legacyApiOrigin?(c=r(n=i.legacyApiOrigin,"legacyApiOrigin"),(u=new URL(n).pathname.replace(/\/+$/,""))?`${c}${u}`:c):`${o}/v1`,{apiOrigin:o,brand:new URL(a).hostname.endsWith("arizo.ru")?"arizo":"vizbl",fetchImpl:i.fetchImpl??fetch,legacyApiOrigin:g,modelViewerOrigin:d,qrCodeScriptUrl:i.qrCodeScriptUrl??`${a}/vendor/qrcode.min.js`,viewerOrigin:a}}(e,this.hasAttribute("dev")?"dev":"prod")}}return customElements.define(t,n),n}eC("arizo"),eC("vizbl")})();
package/dist/index.js CHANGED
@@ -15,9 +15,16 @@ function normalizeHttpBaseUrl(value, name) {
15
15
  const pathname = new URL(value).pathname.replace(/\/+$/, '');
16
16
  return pathname ? `${origin}${pathname}` : origin;
17
17
  }
18
+ function deriveModelViewerOrigin(viewerOrigin) {
19
+ const url = new URL(viewerOrigin);
20
+ const match = url.hostname.match(/^viewer(-dev)?\.(vizbl\.com|arizo\.ru)$/);
21
+ if (!match) return viewerOrigin;
22
+ return `${url.protocol}//integrations${match[1] ?? ''}.${match[2]}`;
23
+ }
18
24
  function resolveCoreArWidgetRuntimeConfig(config) {
19
25
  const apiOrigin = normalizeHttpOrigin(config.apiOrigin, 'apiOrigin');
20
26
  const viewerOrigin = normalizeHttpOrigin(config.viewerOrigin, 'viewerOrigin');
27
+ const modelViewerOrigin = config.modelViewerOrigin ? normalizeHttpOrigin(config.modelViewerOrigin, 'modelViewerOrigin') : deriveModelViewerOrigin(viewerOrigin);
21
28
  const legacyApiOrigin = config.legacyApiOrigin ? normalizeHttpBaseUrl(config.legacyApiOrigin, 'legacyApiOrigin') : `${apiOrigin}/v1`;
22
29
  const brand = new URL(viewerOrigin).hostname.endsWith('arizo.ru') ? 'arizo' : 'vizbl';
23
30
  return {
@@ -25,6 +32,7 @@ function resolveCoreArWidgetRuntimeConfig(config) {
25
32
  brand,
26
33
  fetchImpl: config.fetchImpl ?? fetch,
27
34
  legacyApiOrigin,
35
+ modelViewerOrigin,
28
36
  qrCodeScriptUrl: config.qrCodeScriptUrl ?? `${viewerOrigin}/vendor/qrcode.min.js`,
29
37
  viewerOrigin
30
38
  };
@@ -34,6 +42,7 @@ function createCoreArWidgetTenantConfig(brand, environment = 'prod') {
34
42
  const environmentSuffix = 'dev' === environment ? '-dev' : '';
35
43
  return resolveCoreArWidgetRuntimeConfig({
36
44
  apiOrigin: `https://api${environmentSuffix}.${domain}`,
45
+ modelViewerOrigin: `https://integrations${environmentSuffix}.${domain}`,
37
46
  viewerOrigin: `https://viewer${environmentSuffix}.${domain}`
38
47
  });
39
48
  }
@@ -148,19 +157,20 @@ function openNativeLink(nativeLink, delay = 0) {
148
157
  link.remove();
149
158
  }, delay);
150
159
  }
151
- function getAppViewLink(tinuuid, runtimeConfig) {
160
+ function getAppViewLink(tinuuid, variantId, runtimeConfig) {
152
161
  const { brand } = runtimeConfig ?? getCoreArWidgetRuntimeConfig();
153
162
  if (isIOS()) {
154
163
  const url = new URL('https://appclip.apple.com/id');
155
164
  url.searchParams.set('p', 'com.us.vizbl.Clip');
156
165
  url.searchParams.set('tinuuid', tinuuid);
166
+ if (variantId) url.searchParams.set('hid', variantId);
157
167
  url.searchParams.set('region', 'arizo' === brand ? 'ru' : 'en');
158
168
  return url.toString();
159
169
  }
160
170
  return `intent:/${window.location.pathname}#Intent;scheme=open;package=com.us.vizbl;end`;
161
171
  }
162
- function openAppViewLink(tinuuid, runtimeConfig) {
163
- const href = getAppViewLink(tinuuid, runtimeConfig);
172
+ function openAppViewLink(tinuuid, variantId, runtimeConfig) {
173
+ const href = getAppViewLink(tinuuid, variantId, runtimeConfig);
164
174
  const isIframe = window.self !== window.top;
165
175
  if (!isIframe) return void window.location.assign(href);
166
176
  if (getBrowserName().toLowerCase().includes('edge')) window.location.assign(href);
@@ -342,7 +352,7 @@ function createModal(runtimeConfig) {
342
352
  qr.style.margin = '0 auto';
343
353
  qr.style.width = 'fit-content';
344
354
  const instructions = document.createElement('p');
345
- instructions.textContent = 'Scan this QR code with your phone camera to view the object in Augmented Reality';
355
+ instructions.textContent = isArizo ? 'Отсканируйте этот QR-код камерой телефона, чтобы примерить объект в интерьере' : 'Scan this QR code with your phone camera to view the object in Augmented Reality';
346
356
  Object.assign(instructions.style, {
347
357
  fontSize: '16px',
348
358
  fontWeight: '500',
@@ -595,6 +605,7 @@ async function sendWidgetEvent(event, sessionToken, objectUuid, options = {}) {
595
605
  'Content-Type': 'application/json',
596
606
  'x-widget-session-token': sessionToken
597
607
  },
608
+ keepalive: true,
598
609
  method: 'POST'
599
610
  }, options);
600
611
  if (!response.ok) throw await toRuntimeError(response, 'event');
@@ -672,11 +683,15 @@ async function initializeAdvancedArTrigger(trigger, options = {}) {
672
683
  const trackView = ()=>options.trackView ? options.trackView() : incrementLegacyObjectView(objectId, options.runtimeConfig);
673
684
  const handleDesktopClick = (event)=>{
674
685
  event.preventDefault();
675
- runSafely(()=>options.onAction?.('widget_opened'));
676
686
  const revision = ++qrRevision;
677
687
  closeOwnedQr?.();
678
688
  closeOwnedQr = void 0;
679
- showQrModal(getArRedirectLink(objectId, variantId, true, options.runtimeConfig), `vizbl-${objectId}`, trigger, options.runtimeConfig).then((cleanup)=>{
689
+ Promise.resolve(options.getDesktopQrUrl?.() ?? getArRedirectLink(objectId, variantId, true, options.runtimeConfig)).then((url)=>{
690
+ if (revision !== qrRevision || !initialization.isCurrent()) return;
691
+ runSafely(()=>options.onAction?.('interacted'));
692
+ return showQrModal(url, `vizbl-${objectId}`, trigger, options.runtimeConfig);
693
+ }).then((cleanup)=>{
694
+ if (!cleanup) return;
680
695
  if (revision !== qrRevision || !initialization.isCurrent()) return void cleanup();
681
696
  closeOwnedQr = cleanup;
682
697
  }).catch(()=>void 0);
@@ -691,7 +706,7 @@ async function initializeAdvancedArTrigger(trigger, options = {}) {
691
706
  await Promise.resolve(trackView()).catch(()=>void 0);
692
707
  } finally{
693
708
  handlingUnsupportedClick = false;
694
- if (isIOS() && isSupportedAppClip()) openAppViewLink(objectId, options.runtimeConfig);
709
+ if (isIOS() && isSupportedAppClip()) openAppViewLink(objectId, variantId, options.runtimeConfig);
695
710
  else openNativeLink(nativeLink);
696
711
  }
697
712
  return;
@@ -700,7 +715,7 @@ async function initializeAdvancedArTrigger(trigger, options = {}) {
700
715
  runSafely(trackView);
701
716
  if (isIOS() && isSupportedAppClip()) {
702
717
  event.preventDefault();
703
- openAppViewLink(objectId, options.runtimeConfig);
718
+ openAppViewLink(objectId, variantId, options.runtimeConfig);
704
719
  } else openNativeLink(nativeLink);
705
720
  };
706
721
  if (mobile) {
@@ -728,16 +743,16 @@ function resolveSizeType(value) {
728
743
  return value && SIZE_TYPES.includes(value) ? value : DEFAULT_SIZE_TYPE;
729
744
  }
730
745
  function createModalViewerUrl(params) {
731
- const viewerOrigin = params.viewerOrigin ?? getCoreArWidgetRuntimeConfig().viewerOrigin;
732
- const objectPath = params.hid ? `${encodeURIComponent(params.tinuuid)}/${encodeURIComponent(params.hid)}` : encodeURIComponent(params.tinuuid);
733
- const url = new URL(objectPath, `${viewerOrigin.replace(/\/$/, '')}/`);
734
- url.searchParams.set('hide-title', params.hideTitle ?? '');
735
- url.searchParams.set('hide-preview', params.hidePreview ?? '');
736
- url.searchParams.set('button-bg-color', params.buttonBgColor ?? '');
737
- url.searchParams.set('button-border-color', params.buttonBorderColor ?? '');
738
- url.searchParams.set('button-text-color', params.buttonTextColor ?? '');
739
- url.searchParams.set('background-color', params.backgroundColor ?? '');
740
- url.searchParams.set('size_type', params.sizeType);
746
+ const modelViewerOrigin = params.modelViewerOrigin ?? getCoreArWidgetRuntimeConfig().modelViewerOrigin;
747
+ const url = new URL('/model-viewer', modelViewerOrigin);
748
+ url.searchParams.set('tinuuid', params.tinuuid);
749
+ if (params.hid) url.searchParams.set('hid', params.hid);
750
+ url.searchParams.set('size-type', params.sizeType);
751
+ const fragment = new URLSearchParams();
752
+ if (params.apiKey) fragment.set('api-key', params.apiKey);
753
+ if (params.mode) fragment.set('mode', params.mode);
754
+ if (params.widgetSessionToken) fragment.set('widget-session-token', params.widgetSessionToken);
755
+ url.hash = fragment.toString();
741
756
  return url.toString();
742
757
  }
743
758
  function createFrame(src, backgroundColor) {
@@ -857,11 +872,23 @@ function openModal(options) {
857
872
  function initializeModalTrigger(trigger, options = {}) {
858
873
  const initialization = modal_trigger_beginInitialization(trigger);
859
874
  let closeOwnedModal;
860
- const handleClick = ()=>{
861
- if (closeOwnedModal) return;
875
+ let pendingOpen = false;
876
+ const handleClick = async ()=>{
877
+ if (closeOwnedModal || pendingOpen) return;
862
878
  const objectId = trigger.dataset.objectTinuuid?.trim();
863
879
  if (!objectId) return;
880
+ pendingOpen = true;
881
+ let widgetSessionToken = options.widgetSessionToken;
882
+ try {
883
+ if (options.getWidgetSessionToken) widgetSessionToken = await options.getWidgetSessionToken();
884
+ } catch {
885
+ pendingOpen = false;
886
+ return;
887
+ }
888
+ pendingOpen = false;
889
+ if (closeOwnedModal || !initialization.isCurrent()) return;
864
890
  const opened = openModal({
891
+ apiKey: options.apiKey,
865
892
  backgroundColor: trigger.dataset.background,
866
893
  buttonBgColor: trigger.dataset.buttonBgColor,
867
894
  buttonBorderColor: trigger.dataset.buttonBorderColor,
@@ -872,6 +899,8 @@ function initializeModalTrigger(trigger, options = {}) {
872
899
  hid: trigger.dataset.objectHid,
873
900
  hidePreview: trigger.dataset.hidePreview,
874
901
  hideTitle: trigger.dataset.hideTitle,
902
+ mode: options.mode,
903
+ modelViewerOrigin: options.modelViewerOrigin,
875
904
  onClose: ()=>{
876
905
  closeOwnedModal = void 0;
877
906
  options.onClose?.();
@@ -879,7 +908,7 @@ function initializeModalTrigger(trigger, options = {}) {
879
908
  restoreFocusTo: trigger,
880
909
  sizeType: resolveSizeType(trigger.dataset.sizeType),
881
910
  tinuuid: objectId,
882
- viewerOrigin: options.viewerOrigin,
911
+ widgetSessionToken,
883
912
  width: trigger.dataset.width?.trim()
884
913
  });
885
914
  if (!opened) return;
@@ -926,11 +955,15 @@ async function initializeNativeArAnchor(link, options = {}) {
926
955
  }
927
956
  const handleDesktopClick = (event)=>{
928
957
  event.preventDefault();
929
- runSafely(()=>options.onAction?.('widget_opened'));
930
958
  const revision = ++qrRevision;
931
959
  closeOwnedQr?.();
932
960
  closeOwnedQr = void 0;
933
- showQrModal(getArRedirectLink(objectId, variantId, false, options.runtimeConfig), `vizbl-${objectId}`, link, options.runtimeConfig).then((cleanup)=>{
961
+ Promise.resolve(options.getDesktopQrUrl?.() ?? getArRedirectLink(objectId, variantId, false, options.runtimeConfig)).then((url)=>{
962
+ if (revision !== qrRevision || !initialization.isCurrent()) return;
963
+ runSafely(()=>options.onAction?.('interacted'));
964
+ return showQrModal(url, `vizbl-${objectId}`, link, options.runtimeConfig);
965
+ }).then((cleanup)=>{
966
+ if (!cleanup) return;
934
967
  if (revision !== qrRevision || !initialization.isCurrent()) return void cleanup();
935
968
  closeOwnedQr = cleanup;
936
969
  }).catch(()=>void 0);
@@ -1091,7 +1124,7 @@ function getSelectedMaterial(object, variantId) {
1091
1124
  }
1092
1125
  function assertPolicy(type, object) {
1093
1126
  const policy = object.policy;
1094
- const allowed = 'ar-viewer' === type ? policy?.ignViewerModal !== false : 'ar-one-click' === type ? policy?.instantArView !== false : policy?.appClip !== false;
1127
+ const allowed = 'ar-one-click' === type ? policy?.instantArView !== false : policy?.appClip !== false;
1095
1128
  if (!allowed) throw new CoreArWidgetComponentError('POLICY_DENIED');
1096
1129
  }
1097
1130
  function toErrorCode(error) {
@@ -1200,16 +1233,25 @@ class CoreArWidgetElement extends HTMLElementBase {
1200
1233
  const mode = BACKEND_WIDGET_MODES[rawType];
1201
1234
  const session = await this.ensureSession(publicKey, runtimeConfig, mode, abortController.signal);
1202
1235
  this.assertCurrent(revision, abortController.signal);
1203
- const object = await this.fetchObjectWithSession(objectId, publicKey, session, runtimeConfig, abortController.signal, variantId);
1204
- this.assertCurrent(revision, abortController.signal);
1205
- const material = getSelectedMaterial(object, variantId);
1206
- assertPolicy(rawType, object);
1207
- if ('ar-viewer' !== rawType && (!material.native?.glbUrl || !material.native.usdzUrl)) throw new CoreArWidgetComponentError('MODEL_UNAVAILABLE');
1208
- this.object = object;
1209
1236
  this.variantId = variantId;
1210
1237
  this.widgetMode = mode;
1211
1238
  this.applyIntegrationData(objectId, variantId, sizeType);
1212
- const cleanup = await this.initializeTrigger(rawType, object, runtimeConfig, abortController.signal);
1239
+ let object;
1240
+ if ('ar-viewer' === rawType) {
1241
+ object = await fetchLegacyObject(objectId, abortController.signal, runtimeConfig);
1242
+ this.assertCurrent(revision, abortController.signal);
1243
+ getSelectedMaterial(object, variantId);
1244
+ assertPolicy(rawType, object);
1245
+ this.object = object;
1246
+ } else {
1247
+ object = isMobile() ? await this.fetchObjectWithSession(objectId, publicKey, session, runtimeConfig, abortController.signal, variantId) : await fetchLegacyObject(objectId, abortController.signal, runtimeConfig);
1248
+ this.assertCurrent(revision, abortController.signal);
1249
+ const material = getSelectedMaterial(object, variantId);
1250
+ assertPolicy(rawType, object);
1251
+ if (!material.native?.glbUrl || !material.native.usdzUrl) throw new CoreArWidgetComponentError('MODEL_UNAVAILABLE');
1252
+ this.object = object;
1253
+ }
1254
+ const cleanup = await this.initializeTrigger(rawType, object, runtimeConfig, abortController.signal, publicKey, session);
1213
1255
  try {
1214
1256
  this.assertCurrent(revision, abortController.signal);
1215
1257
  } catch (error) {
@@ -1235,7 +1277,7 @@ class CoreArWidgetElement extends HTMLElementBase {
1235
1277
  }
1236
1278
  }
1237
1279
  async ensureSession(publicKey, runtimeConfig, mode, signal, forceRefresh = false) {
1238
- const runtimeKey = `${runtimeConfig.apiOrigin}|${runtimeConfig.viewerOrigin}|${mode}`;
1280
+ const runtimeKey = `${runtimeConfig.apiOrigin}|${runtimeConfig.viewerOrigin}|${runtimeConfig.modelViewerOrigin}|${mode}`;
1239
1281
  const existing = this.session?.publicKey === publicKey && this.session.runtimeKey === runtimeKey ? this.session : void 0;
1240
1282
  if (existing && !forceRefresh && existing.expiresAt - Date.now() > SESSION_REFRESH_THRESHOLD_MS) return existing;
1241
1283
  if (existing) try {
@@ -1338,17 +1380,37 @@ class CoreArWidgetElement extends HTMLElementBase {
1338
1380
  if (sizeType) this.trigger.dataset.sizeType = sizeType;
1339
1381
  else delete this.trigger.dataset.sizeType;
1340
1382
  }
1341
- async initializeTrigger(type, object, runtimeConfig, signal) {
1383
+ async initializeTrigger(type, object, runtimeConfig, signal, publicKey, session) {
1342
1384
  if (!this.trigger) throw new CoreArWidgetComponentError('INITIALIZATION_FAILED');
1343
1385
  if ('ar-viewer' === type) return initializeModalTrigger(this.trigger, {
1386
+ apiKey: publicKey,
1387
+ getWidgetSessionToken: async ()=>{
1388
+ const currentSession = await this.ensureSession(publicKey, runtimeConfig, session.mode);
1389
+ return currentSession.token;
1390
+ },
1391
+ mode: session.mode,
1392
+ modelViewerOrigin: runtimeConfig.modelViewerOrigin,
1344
1393
  onAction: (action)=>this.handleAction(action, runtimeConfig),
1345
1394
  onClose: ()=>{
1346
1395
  if (this.isConnected) this.setState('ready');
1347
1396
  },
1348
1397
  onOpen: ()=>this.setState('opening'),
1349
- viewerOrigin: runtimeConfig.viewerOrigin
1398
+ widgetSessionToken: session.token
1350
1399
  });
1400
+ if (!object) throw new CoreArWidgetComponentError('INITIALIZATION_FAILED');
1351
1401
  const options = {
1402
+ getDesktopQrUrl: async ()=>{
1403
+ const currentSession = await this.ensureSession(publicKey, runtimeConfig, session.mode);
1404
+ return createModalViewerUrl({
1405
+ apiKey: publicKey,
1406
+ hid: this.variantId,
1407
+ mode: currentSession.mode,
1408
+ modelViewerOrigin: runtimeConfig.modelViewerOrigin,
1409
+ sizeType: resolveSizeType(this.trigger?.dataset.sizeType),
1410
+ tinuuid: this.trigger?.dataset.objectTinuuid ?? '',
1411
+ widgetSessionToken: currentSession.token
1412
+ });
1413
+ },
1352
1414
  object,
1353
1415
  onAction: (action)=>this.handleAction(action, runtimeConfig),
1354
1416
  runtimeConfig,
@@ -1363,7 +1425,7 @@ class CoreArWidgetElement extends HTMLElementBase {
1363
1425
  }
1364
1426
  handleAction(action, runtimeConfig) {
1365
1427
  this.setState('opening');
1366
- if ('widget_opened' === action) this.trackEvent(action, runtimeConfig);
1428
+ if (('interacted' === action || 'widget_opened' === action) && 'ar-viewer' !== this.getAttribute('type')) this.trackEvent(action, runtimeConfig);
1367
1429
  if ('ar-viewer' === this.getAttribute('type')) return;
1368
1430
  this.clearActionResetTimer();
1369
1431
  this.actionResetTimer = window.setTimeout(()=>{
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@neurodyn/core-ar",
3
3
  "type": "module",
4
- "version": "0.2.1",
4
+ "version": "0.2.3",
5
5
  "sideEffects": false,
6
6
  "publishConfig": {
7
7
  "access": "public"