@lumiscaphe/viewer 4.1.15 → 4.1.16

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.
package/CLAUDE.md ADDED
@@ -0,0 +1,174 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ Lumiscaphe 3D Viewer (@lumiscaphe/viewer) is a TypeScript-based WebGL viewer library for rendering interactive 3D products from WebRender server. It supports multiple viewing modes (static images, VRCube panoramas, VRObject rotation) and integrates with Lumiscaphe's WebRender API (v1 and v2).
8
+
9
+ ## Common Commands
10
+
11
+ ### Development
12
+ ```bash
13
+ npm run dev # Start development server with sample viewer
14
+ npm run preview # Preview built sample application
15
+ ```
16
+
17
+ ### Building
18
+ ```bash
19
+ npm run build:lib # Build library distribution (ES + CJS)
20
+ npm run build:sample # Build sample application
21
+ ```
22
+
23
+ ### Linting
24
+ ```bash
25
+ npm run lint # Run ESLint on all TypeScript files in src/
26
+ ```
27
+
28
+ ### Pre-commit Hook
29
+ The repository uses Husky with a pre-commit hook that runs `npm run lint` automatically before commits.
30
+
31
+ ## Architecture
32
+
33
+ ### Core Components
34
+
35
+ **Viewer (src/lib/Viewer.ts)**
36
+ - Main entry point and orchestrator
37
+ - Manages canvas instances (Canvas2D, Canvas3D, Video)
38
+ - Handles scene loading, view changes, and user interactions
39
+ - Delegates rendering to Widget implementations based on view mode
40
+ - Uses debouncing for resize and loading operations
41
+
42
+ **Widget System**
43
+ - `Widget` interface defines the contract for all view modes
44
+ - Four concrete implementations:
45
+ - `WidgetImage`: Static image rendering using Canvas2D
46
+ - `WidgetVideo`: Video playback for animations
47
+ - `WidgetVRCube`: Interactive WebGL cube map viewer with camera controls
48
+ - `WidgetVRObject`: Image sequence viewer for product rotation
49
+ - Each widget handles its own interaction model and rendering
50
+
51
+ **Loader (src/lib/Loader.ts)**
52
+ - Abstracts WebRender API communication
53
+ - Supports three API modes: 'static', 'v1', 'v2'
54
+ - Manages progressive loading with priority-based image loading (center-out for VRObject)
55
+ - Handles conversion between v1 camera paths and v2 camera IDs
56
+ - Caches database XML for camera lookups
57
+
58
+ **WebRender Integrations**
59
+ - `WebRenderStatic`: Direct image URLs
60
+ - `WebRenderV1`: Legacy API using camera paths (e.g., "EXTER/1")
61
+ - `WebRenderV2`: Modern REST API using GUIDs and structured requests
62
+ - API requests use POST with JSON body for snapshots, hotspots, and picking
63
+
64
+ ### Canvas Architecture
65
+
66
+ **Canvas3D (src/lib/Canvas3D.ts)**
67
+ - WebGL rendering context for VRCube mode
68
+ - Uses twgl.js for WebGL utilities
69
+ - Handles context loss detection
70
+ - Implements preserveDrawingBuffer for snapshot capability
71
+
72
+ **Canvas2D (src/lib/Canvas2D.ts)**
73
+ - 2D rendering for images and VRObject sequences
74
+ - Supports three fit modes: 'cover', 'contain', 'fill'
75
+
76
+ **WidgetVRCube WebGL Pipeline**
77
+ - Uses custom GLSL shaders (WidgetVRCube.frag, WidgetVRCube.vert)
78
+ - Implements cube map texture rendering
79
+ - Features camera interaction with inertia
80
+ - Handles hotspot projection from cube faces to screen space
81
+ - Includes workaround for MacIntel Chrome OpenGL texture size limit (1812x1812)
82
+
83
+ ### Scene and View Model
84
+
85
+ **Scene**
86
+ - Array of products with database GUID, configuration strings, and animations
87
+ - Supports decor and accessory products with transformation data
88
+ - Configuration format: slash-separated values (e.g., "Bin.Blue/Cabin.Yellow/Style.Design1")
89
+
90
+ **View**
91
+ - Defines rendering mode: 'image', 'video', 'vrcube', 'vrobject'
92
+ - Camera specification (v1: path string, v2: GUID or camera object with POV)
93
+ - Background modes: 'product', 'transparent', 'gradient'
94
+ - VRObject supports both animation-based and bookmark-set navigation
95
+
96
+ **Snapshot**
97
+ - Internal type combining Scene, View, Parameters, and Encoder
98
+ - Used for all WebRender API requests
99
+
100
+ ### Interaction System
101
+
102
+ **InteractiveCamera/InteractivePosition**
103
+ - Implements mouse/touch drag with inertia physics
104
+ - VRCube uses spherical coordinates for camera rotation
105
+ - VRObject uses discrete position indices
106
+ - Debounced interaction callbacks prevent excessive API calls
107
+
108
+ **Hotspots**
109
+ - 3D position markers projected to 2D screen space
110
+ - Supports both tag-based (string) and position-based (Vector3D) definitions
111
+ - Visibility culling based on camera frustum
112
+ - Requires WebRender API v2
113
+
114
+ **Picking**
115
+ - Ray-casting for 3D point selection on product surface
116
+ - Returns point, normal, and material information
117
+ - VRCube implements custom cube face determination and UV mapping
118
+
119
+ ## Key Implementation Details
120
+
121
+ ### API Version Compatibility
122
+ - Loader automatically uses WebRenderV2 for hotspots and picking even when main API is v1
123
+ - Database caching prevents redundant XML fetches during v1-to-v2 camera path conversion
124
+ - Camera conversion logic in `Loader.convert()` handles both camera IDs and camera group IDs
125
+
126
+ ### GLSL Shader Integration
127
+ - Vite plugin 'vite-plugin-glsl' processes .frag and .vert files
128
+ - Custom type declarations in src/lib/types/ for shader imports
129
+ - Shaders are imported as strings and compiled at runtime via twgl.createProgramInfo
130
+
131
+ ### ESLint Configuration
132
+ - Uses flat config format (eslint.config.mjs)
133
+ - Enforces explicit function return types but allows expressions
134
+ - Disables @typescript-eslint/no-explicit-any (project uses `any` extensively)
135
+ - Disabled unused-vars checking
136
+
137
+ ### Build Configuration
138
+ - Two separate Vite configs:
139
+ - `vite.config.lib.ts`: Library build (ES + CJS) with type declarations
140
+ - `vite.config.sample.ts`: Sample app for development/testing
141
+ - CSS injection via vite-plugin-css-injected-by-js (no separate CSS file)
142
+ - External dependencies: debounce-promise, regression, twgl.js
143
+ - Tree-shaking enabled with moduleSideEffects: false
144
+
145
+ ### Resolution and Viewport
146
+ - Auto-resolution (`autores: true`) computes standard resolutions based on viewport
147
+ - `Viewport.getStandardResolution()` rounds to WebRender-friendly dimensions
148
+ - Super-sampling coefficient (1-4) for quality control
149
+ - Separate parameters for render resolution vs canvas display size
150
+
151
+ ### Loading Strategy
152
+ - LoadingId pattern prevents race conditions when requests are cancelled
153
+ - Progressive image loading for VRObject starts from current position and spirals outward
154
+ - Video frame extraction uses canvas.toDataURL for animation sequences
155
+ - Debounced onLoadError prevents error spam during rapid view changes
156
+
157
+ ## WebRender API Types
158
+
159
+ The `WRAPIv2` namespace (src/lib/WRAPIv2.ts) defines comprehensive TypeScript types for:
160
+ - Scene composition (Product, Scene)
161
+ - Rendering modes (ImageMode, VrCubeMode, VrObjectMode, AnimationMode)
162
+ - Requests (SnapshotRequest, HotspotRequest, PickRequest)
163
+ - Camera specifications (including POV and lens parameters)
164
+ - Encoder configurations (JPEG, PNG, WebP)
165
+
166
+ ## Testing Notes
167
+
168
+ This project does not currently have automated tests. When adding features, manual testing should cover:
169
+ - All four view modes with representative scenes
170
+ - API version switching (static, v1, v2)
171
+ - Hotspot visibility and picking accuracy
172
+ - Cross-browser WebGL compatibility (especially Mac Chrome with OpenGL)
173
+ - Touch and mouse interactions with proper inertia
174
+ - Loading cancellation during rapid scene/view changes
@@ -1,5 +1,5 @@
1
1
  (function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode(".ls-viewer-container{display:block;position:relative;overflow:hidden;-webkit-user-select:none;user-select:none;width:100%;height:100%}.ls-viewer-container-image,.ls-viewer-container-video{cursor:default;pointer-events:none}.ls-viewer-container-vrcube{cursor:pointer;cursor:grab}.ls-viewer-container-vrcube-grabbing{cursor:move;cursor:grabbing}.ls-viewer-container-vrobject{cursor:move;cursor:grab}.ls-viewer-container-vrobject-grabbing{cursor:move;cursor:grabbing}.ls-viewer-container-loading{cursor:progress}.ls-viewer-canvas{position:absolute;opacity:0;transition:opacity .5s}.ls-viewer-video{position:absolute}")),document.head.appendChild(e)}}catch(r){console.error("vite-plugin-css-injected-by-js",r)}})();
2
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const C=require("debounce-promise"),h=require("twgl.js"),N=require("regression");function B(l){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(l){for(const e in l)if(e!=="default"){const i=Object.getOwnPropertyDescriptor(l,e);Object.defineProperty(t,e,i.get?i:{enumerable:!0,get:()=>l[e]})}}return t.default=l,Object.freeze(t)}const x=B(h);class y{constructor(t,e){this.width=t,this.height=e}get aspect(){return this.width/this.height}}class w{constructor(t,e,i,s){this.top=t,this.left=e,this.width=i,this.height=s}static contains(t,e){return e.x>=0&&e.x<t.width&&e.y>=0&&e.y<t.height}static fit(t,e,i){const s=t.aspect,r=e.aspect;let n=0,a=0;switch(i){case"contain":n=r<s?e.width:e.height*s,a=r<s?e.width/s:e.height;break;case"cover":default:n=r<s?e.height*s:e.width,a=r<s?e.height:e.width/s;break;case"fill":n=e.width,a=e.height;break}const o=(e.height-a)/2,d=(e.width-n)/2;return new w(o,d,n,a)}static project(t,e,i,s){const r=w.fit(t,e,i),n=r.width/t.width,a=r.height/t.height;return{x:Math.round(r.left+s.x*n),y:Math.round(r.top+s.y*a)}}static unproject(t,e,i,s){const r=w.fit(t,e,i),n=r.width/t.width,a=r.height/t.height;return{x:Math.round((s.x-r.left)/n),y:Math.round((s.y-r.top)/a)}}static getStandardAspectRatio(t,e){if(t===0||e===0)return 0;const i=t/e;if(t<e){const n=Math.abs(.75-i),a=Math.abs(9/16-i);return n<a?3/4:9/16}const s=Math.abs(4/3-i),r=Math.abs(16/9-i);return s<r?4/3:16/9}static getStandardResolution(t,e){if(t===0||e===0)return new y(0,0);const i=w.getStandardAspectRatio(t,e);if(t<e){const r=w.getStandardQuality(Math.max(e*i,t));return new y(Math.round(r),Math.round(r/i))}const s=w.getStandardQuality(Math.max(t/i,e));return new y(Math.round(s*i),Math.round(s))}static getStandardQuality(t){return t<=240?240:t<=360?360:t<=480?480:t<=720?720:1080}}class X{constructor(t){this.element=document.createElement("canvas"),this.element.classList.add("ls-viewer-canvas"),this.element.style.opacity="0",this.element.width=0,this.element.height=0,this.context=this.element.getContext("2d"),this.backCanvas=document.createElement("canvas"),this.backContext=this.backCanvas.getContext("2d"),this.fit=t,this.pixelRatio=1}destroy(){this.requestAnimationId&&(cancelAnimationFrame(this.requestAnimationId),this.requestAnimationId=void 0)}show(t){t?this.element.style.display="block":this.element.style.opacity="1"}hide(t){t?this.element.style.display="none":this.element.style.opacity="0"}get resolution(){return new y(this.element.width/this.pixelRatio,this.element.height/this.pixelRatio)}resize(t,e,i){this.element.width=t*i,this.element.height=e*i,this.element.style.width=`${t}px`,this.element.style.height=`${e}px`,this.backCanvas.width=t*i,this.backCanvas.height=e*i,this.pixelRatio=i}draw(t,e,i){if(!t)return;this.requestAnimationId&&(cancelAnimationFrame(this.requestAnimationId),this.requestAnimationId=void 0);const s=w.fit(new y(t.width,t.height),new y(this.element.width,this.element.height),this.fit);e?(this.backContext.drawImage(this.element,0,0),this.context.globalAlpha=0,this.fadeLoop(t,i||0)):(this.context.globalAlpha=1,this.context.drawImage(t,s.left,s.top,s.width,s.height)),this.image=t}fadeLoop(t,e){if(this.context.globalAlpha>=1){cancelAnimationFrame(this.requestAnimationId),this.requestAnimationId=void 0;return}const i=Math.min(this.context.globalAlpha+e,1),s=w.fit(new y(t.width,t.height),new y(this.element.width,this.element.height),this.fit);this.context.clearRect(0,0,this.element.width,this.element.height),this.context.globalAlpha=1,this.context.drawImage(this.backCanvas,0,0),this.context.globalAlpha=i,this.context.drawImage(t,s.left,s.top,s.width,s.height),this.requestAnimationId=requestAnimationFrame(()=>{this.fadeLoop(t,e)})}}class Y{constructor(){this.element=document.createElement("canvas"),this.element.classList.add("ls-viewer-canvas"),this.element.style.opacity="0",this.element.width=0,this.element.height=0,this.context=x.getContext(this.element,{preserveDrawingBuffer:!0}),this.context&&this.context.isContextLost()&&(this.context=void 0),x.setDefaults({textureColor:[1,1,1,1]})}show(){this.element.style.opacity="1"}hide(){this.element.style.opacity="0"}resize(t,e,i){this.element.width=t*i,this.element.height=e*i,this.element.style.width=`${t}px`,this.element.style.height=`${e}px`}}class g{static accelerate(t,e){const i=e||1.5;return Math.abs(t)**i*(t>0?1:-1)}static clamp(t,e,i){return Math.max(Math.min(t,i),e)}static degreesToRadians(t){return t*(Math.PI/180)}static radiansToDegrees(t){return t*(180/Math.PI)}static mod(t,e){return t-e*Math.floor(t/e)}static perspectiveWithFovX(t,e,i,s,r){const n=Math.tan(t/2),a=n/e;return this.perspectiveWithLeft(-n,n,-a,a,i,s,r)}static perspectiveWithFovY(t,e,i,s,r){const n=i*Math.tan(t/2),a=n*e;return this.perspectiveWithLeft(-a,a,-n,n,i,s,r)}static perspectiveWithLeft(t,e,i,s,r,n,a){a=a||new Float32Array(16);const o=e+t,d=e-t,u=s+i,p=s-i,c=n-r;return a[0]=2*r/d,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=2*r/p,a[6]=0,a[7]=0,a[8]=o/d,a[9]=u/p,a[10]=-n/c,a[11]=-1,a[12]=0,a[13]=0,a[14]=-n*r/c,a[15]=0,a}}const F=class F{static initCubeFace(t,e,i){let s=[0,0,0];const r=h.v3.subtract(e,t),n=h.v3.mulScalar([0,1,0],h.v3.length(r)),a=h.v3.mulScalar(h.v3.normalize(h.v3.cross(r,n)),h.v3.length(r)),o=h.v3.mulScalar(h.v3.normalize(h.v3.cross(n,a)),h.v3.length(r));switch(i){case"front":e=h.v3.add(t,o),s=h.v3.normalize(n);break;case"right":e=h.v3.add(t,a),s=h.v3.normalize(n);break;case"back":e=h.v3.subtract(t,o),s=h.v3.normalize(n);break;case"left":e=h.v3.subtract(t,a),s=h.v3.normalize(n);break;case"up":e=h.v3.add(t,n),s=h.v3.normalize(h.v3.mulScalar(o,-1));break;case"down":e=h.v3.subtract(t,n),s=h.v3.normalize(o);break}return new F(e,t,s)}constructor(t,e,i){this.target=h.v3.copy(t),this.eye=h.v3.copy(e),this.up=h.v3.copy(i)}get viewVector(){return h.v3.subtract(this.target,this.eye)}get rightVector(){return h.v3.normalize(h.v3.cross(this.viewVector,this.up))}get viewMatrix(){return h.m4.inverse(h.m4.lookAt(this.eye,this.target,this.up))}clone(){return new F(h.v3.copy(this.target),h.v3.copy(this.eye),h.v3.copy(this.up))}};F.default=new F([0,0,0],[2,2,2],[0,1,0]);let I=F;class W{constructor(t){this.target=t.target;const e=h.v3.normalize(h.v3.subtract(t.eye,t.target)),i=h.v3.dot(e,[1,0,0]),s=h.v3.dot(e,[0,1,0]),r=h.v3.dot(e,[0,0,1]);this.longitude=Math.atan2(i,r),this.latitude=Math.atan2(s,Math.sqrt(i*i+r*r)),h.v3.dot(t.up,[0,1,0])<0&&(this.longitude=Math.PI+this.longitude,this.latitude=Math.PI-this.latitude),this.distance=h.v3.length(h.v3.subtract(t.target,t.eye))}get vector(){const t=Math.cos(this.latitude)*this.distance,e=Math.sin(this.latitude)*this.distance,i=Math.cos(this.longitude)*t,s=Math.sin(this.longitude)*t;return[i,e,s]}pointOfView(t){const e=h.m4.rotationY(this.longitude),i=h.m4.rotationX(-this.latitude),s=h.m4.rotationZ(0),r=h.m4.multiply(e,h.m4.multiply(i,s));let n=[0,0,-1];n=h.m4.transformPoint(r,n);let a=[0,1,0];a=h.m4.transformPoint(r,a);const o=h.v3.subtract(t,h.v3.mulScalar(n,this.distance));return new I(t,o,a)}}class J{constructor(){}async animation(t){return t.scene}async database(t){throw new Error("Unavailable")}async image(t){return t.scene}async video(t){return t.scene}async vrCube(t){return t.scene}async vrObject(t){return t.scene}}class j{constructor(t){this.xmlDoc=t}get id(){var t;return(t=this.xmlDoc.getElementsByTagName("Database")[0])==null?void 0:t.getAttribute("id")}getCameraId(t,e){var i,s;return e?(i=this.xmlDoc.querySelector(`RootCameraGroup Group[name="${e}"] Camera[name="${t}"]`))==null?void 0:i.getAttribute("id"):(s=this.xmlDoc.querySelector(`RootCameraGroup Camera[name="${t}"]`))==null?void 0:s.getAttribute("id")}getCameraById(t,e){let i;return t&&e?i=this.xmlDoc.querySelector(`RootCameraGroup Group[id="${e}"] Camera[id="${t}"]`):i=this.xmlDoc.querySelector(`RootCameraGroup Camera[id="${t}"]`),i?this.mapElementToCamera(i):null}getCameraByName(t,e){let i;return e&&t?i=this.xmlDoc.querySelector(`RootCameraGroup Group[name="${e}"] Camera[name="${t}"]`):i=this.xmlDoc.querySelector(`RootCameraGroup Camera[name="${t}"]`),i?this.mapElementToCamera(i):null}getCameraGroupId(t){var e;return(e=this.xmlDoc.querySelector(`RootCameraGroup Group[name="${t}"]`))==null?void 0:e.getAttribute("id")}getCameraGroupById(t){const e=this.xmlDoc.querySelector(`RootCameraGroup Group[id="${t}"]`);return e?this.mapElementToCameraGroup(e):null}getCameraGroupByName(t){const e=this.xmlDoc.querySelector(`RootCameraGroup Group[name="${t}"]`);return e?this.mapElementToCameraGroup(e):null}mapElementToCamera(t){return{id:t.getAttribute("id"),name:t.getAttribute("name"),pointOfView:new I([parseFloat(t.querySelector("PointOfView Target").getAttribute("x")),parseFloat(t.querySelector("PointOfView Target").getAttribute("y")),parseFloat(t.querySelector("PointOfView Target").getAttribute("z"))],[parseFloat(t.querySelector("PointOfView Eye").getAttribute("x")),parseFloat(t.querySelector("PointOfView Eye").getAttribute("y")),parseFloat(t.querySelector("PointOfView Eye").getAttribute("z"))],[parseFloat(t.querySelector("PointOfView Up").getAttribute("x")),parseFloat(t.querySelector("PointOfView Up").getAttribute("y")),parseFloat(t.querySelector("PointOfView Up").getAttribute("z"))])}}mapElementToCameraGroup(t){return{id:t.getAttribute("id"),name:t.getAttribute("name"),cameras:[...t.querySelectorAll("Camera")].map(e=>this.mapElementToCamera(e))}}}const v=class v{constructor(t){this.server=t}static buildQuery(t){return Object.entries(t).filter(([e,i])=>i!=null).map(([e,i])=>`${e}=${i}`).join("&")}static sceneParameters(t){var n,a;const e=t.scene,i=e.length>1?e.find(o=>o.accessory):null,s=e.length>1?e.find(o=>o.decor):null,r=e.find(o=>o!==i&&o!==s);return{databaseId:r.database,configuration:r==null?void 0:r.configuration,animations:(n=r==null?void 0:r.animations)==null?void 0:n.join("/"),accessoryDatabaseId:i==null?void 0:i.database,decorDatabaseId:s==null?void 0:s.database,decorDeltaAltitude:(a=s==null?void 0:s.translation)==null?void 0:a.y}}static renderParameters(t){const{parameters:e,view:i}=t;return{background:i.background,width:e.width,height:e.height,softwareAntialiasing:e.antialiasing,superSampling:e.superSampling}}static encoderParameters(t){const{encoder:e}=t;return{imageFormat:e.format,imageQuality:e.quality}}static async fetch(t){return fetch(t).then(e=>e.text()).then(e=>{const s=e.replace(/&amp;/g,"&").match(this.xmlRegex);return s?s.map(r=>r.replace(this.xmlRegex,"$1")):Promise.reject()})}async animation(t){const e={...v.sceneParameters(t),animation:t.view.animation,bookmarkSet:t.view.camera.split("/")[0],bookmark:t.view.camera.split("/")[1],frames:t.view.frames,loop:!!t.view.loop,...v.renderParameters(t),...v.encoderParameters(t)},i=v.buildQuery(e);return v.fetch(`${this.server}/ImagesFromAnimation?${i}`)}async database(t){return fetch(`${this.server}/Database?databaseId=${t}`).then(e=>e.text()).then(e=>{const i=new DOMParser().parseFromString(e,"application/xml");return new j(i)})}async image(t){const e={...v.sceneParameters(t),bookmarkSet:t.view.camera.split("/")[0],bookmark:t.view.camera.split("/")[1],...v.renderParameters(t),...v.encoderParameters(t)},i=v.buildQuery(e);return Promise.resolve(`${this.server}/ImageFromBookmark?${i}`)}async video(t){const e={...v.sceneParameters(t),animation:t.view.animation,bookmarkSet:t.view.camera.split("/")[0],bookmark:t.view.camera.split("/")[1],duration:t.view.duration,frames:t.view.frames,loop:!!t.view.loop,reverse:!!t.view.reverse,...v.renderParameters(t),...v.encoderParameters(t)},i=v.buildQuery(e);return Promise.resolve(`${this.server}/ImagesFromAnimation?${i}`)}async vrCube(t){const e={...v.sceneParameters(t),bookmarkSet:t.view.camera.split("/")[0],bookmark:t.view.camera.split("/")[1],...v.renderParameters(t),...v.encoderParameters(t)};e.width=Math.max(e.width,e.height),e.height=Math.max(e.width,e.height);const i=v.buildQuery(e);return v.fetch(`${this.server}/CubeFromBookmark?${i}`)}async vrObject(t){const e={...v.sceneParameters(t),bookmarkSet:t.view.camera,...v.renderParameters(t),...v.encoderParameters(t)},i=v.buildQuery(e);return v.fetch(`${this.server}/ImagesFromBookmarkSet?${i}`)}};v.xmlRegex=/directUrl="([^"]*)"/g;let S=v;class m{constructor(t){this.server=t}static scene(t){return t.scene.map(e=>{const{accessory:i,decor:s,...r}=e;return r})}static renderParameters(t){return{...t.parameters,superSampling:t.parameters.superSampling.toString()}}static encoder(t){switch(t.encoder.format){case"jpeg":return{jpeg:{quality:t.encoder.quality}};case"png":return{png:{compression:t.encoder.compression}};case"webp":return{webp:{quality:t.encoder.quality}}}return{jpeg:{quality:80}}}static async fetchFrame(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json()).then(i=>i.url)}static async fetchFrameArray(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json()).then(i=>i.map(s=>s.url))}static async fetchHotspots(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json())}static async fetchHotspotsArray(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json())}static async fetchPick(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json()).then(i=>i[0])}async database(t){return fetch(`${this.server}/Database?databaseId=${t}`).then(e=>e.text()).then(e=>{const i=new DOMParser().parseFromString(e,"application/xml");return new j(i)})}async image(t){const e={scene:m.scene(t),mode:{image:{camera:t.view.camera}},renderParameters:m.renderParameters(t),encoder:m.encoder(t)};return m.fetchFrame(`${this.server}/Snapshot`,e)}async vrCube(t){const e={scene:m.scene(t),mode:{vrCube:{camera:t.view.camera}},renderParameters:m.renderParameters(t),encoder:m.encoder(t)};return e.renderParameters.width=Math.max(e.renderParameters.width,e.renderParameters.height),e.renderParameters.height=Math.max(e.renderParameters.width,e.renderParameters.height),m.fetchFrameArray(`${this.server}/Snapshot`,e)}async vrObject(t){let e;t.view.cameraGroup?e={images:{cameraGroup:t.view.cameraGroup}}:t.view.frames?e={vrObject:{camera:t.view.camera,frames:t.view.frames}}:e={vrObject:{camera:t.view.camera,panFrames:t.view.panFrames||1,panFrom:t.view.panFrom||0,panTo:t.view.panTo||0,panLoop:t.view.panLoop||!1,tiltFrames:t.view.tiltFrames||1,tiltFrom:t.view.tiltFrom||0,tiltTo:t.view.tiltTo||0,tiltLoop:t.view.tiltLoop||!1}};const i={scene:m.scene(t),mode:e,renderParameters:m.renderParameters(t),encoder:m.encoder(t)};return m.fetchFrameArray(`${this.server}/Snapshot`,i)}async animation(t){const e={scene:m.scene(t),mode:{animation:{id:t.view.animation,camera:t.view.camera,fps:t.view.fps}},renderParameters:m.renderParameters(t),encoder:m.encoder(t)};return m.fetchFrameArray(`${this.server}/Snapshot`,e)}async imageHotspots(t,e){const i={scene:m.scene(t),mode:{image:{camera:t.view.camera}},renderParameters:m.renderParameters(t),...this.hotspotsBody(e)};return await m.fetchHotspots(`${this.server}/Hotspot`,i)}async imagePick(t,e){const i={scene:m.scene(t),camera:t.view.camera,renderParameters:m.renderParameters(t),positions:[e]};return await m.fetchPick(`${this.server}/Pick`,i)}async vrCubeHotspots(t,e){const i={scene:m.scene(t),mode:{vrCube:{camera:t.view.camera}},renderParameters:m.renderParameters(t),...this.hotspotsBody(e)};return i.renderParameters.width=Math.max(i.renderParameters.width,i.renderParameters.height),i.renderParameters.height=Math.max(i.renderParameters.width,i.renderParameters.height),await m.fetchHotspotsArray(`${this.server}/Hotspot`,i)}async vrObjectHotspots(t,e){let i;t.view.cameraGroup?i={images:{cameraGroup:t.view.cameraGroup}}:t.view.frames?i={vrObject:{camera:t.view.camera,frames:t.view.frames}}:i={vrObject:{camera:t.view.camera,panFrames:t.view.panFrames||1,panFrom:t.view.panFrom||0,panTo:t.view.panTo||0,panLoop:t.view.panLoop||!1,tiltFrames:t.view.tiltFrames||1,tiltFrom:t.view.tiltFrom||0,tiltTo:t.view.tiltTo||0,tiltLoop:t.view.tiltLoop||!1}};const s={scene:m.scene(t),mode:i,renderParameters:m.renderParameters(t),...this.hotspotsBody(e)};return await m.fetchHotspotsArray(`${this.server}/Hotspot`,s)}hotspotsBody(t){return{positions:t.every(e=>typeof e!="string")?t:void 0,tags:t.every(e=>typeof e=="string")?t:void 0}}}class k{constructor(t,e,i){switch(e){case"static":this.webrender=new J;break;case"v1":this.webrender=new S(t),this.webrenderV2=new m(t);break;case"v2":this.webrender=new m(t),this.webrenderV2=new m(t);break;default:this.webrender=new S(t),this.webrenderV2=new m(t);break}this.delegate=i,this.loadingId=0,this.loaded=0,this.total=0,this.databases=[],this.onLoadStart=i&&i.onLoadStart?i.onLoadStart:()=>{},this.onLoadProgress=i&&i.onLoadProgress?i.onLoadProgress:()=>{},this.onLoadEnd=i&&i.onLoadEnd?i.onLoadEnd:()=>{}}get progress(){return this.total?this.loaded/this.total:0}async loadImageSnapshot(t){this.loadingId+=1,this.loaded=0,this.total=1,this.onLoadStart(this.progress);const{loadingId:e}=this;return this.webrender.image(t).then(i=>this.loadImage(i,e)).then(i=>(this.onLoadEnd(this.progress),i))}async loadVideoSnapshot(t,e){this.loadingId+=1,this.loaded=0,this.total=1,this.onLoadStart(this.progress);const{loadingId:i}=this;return this.webrender.video(e).then(s=>this.loadVideo(t,s,!!e.view.loop,i)).then(()=>(this.onLoadEnd(this.progress),t))}async loadVRCubeSnapshot(t){this.loadingId+=1,this.loaded=0,this.total=0,this.onLoadStart(this.progress);const{loadingId:e}=this;return this.webrender.vrCube(t).then(i=>{this.total=i.length;const s=i.map(r=>this.loadImage(r,e));return Promise.all(s)}).then(i=>(this.onLoadEnd(this.progress),i))}async loadVRObjectSnapshot(t,e){var s;this.loadingId+=1,this.loaded=0,this.total=0,this.onLoadStart(this.progress);const{loadingId:i}=this;return t.view.animation?((s=t.encoder)==null?void 0:s.format)==="mp4"?this.webrender.video(t).then(r=>this.loadVideoFrames(r,t.view.frames,30,i)):this.webrender.animation(t).then(r=>this.loadImageFrames(r,t.view.loop,e,i)):this.webrender.vrObject(t).then(r=>this.loadImageFrames(r,t.view.loop,e,i))}async loadImage(t,e){const i=new Image;i.crossOrigin=location.protocol==="file:"&&!k.isValidHttpUrl(t)?null:"anonymous";const s=new Promise((r,n)=>{i.addEventListener("load",()=>{e===this.loadingId&&(this.loaded+=1,this.onLoadProgress(this.progress),r(i))},{once:!0}),i.addEventListener("error",a=>{e===this.loadingId&&n(`${a.type} : ${t}`)},{once:!0})});return i.src=t,s}loadImageFrames(t,e,i,s){this.total=t.length;const r=new Array(t.length),n=i||0;for(let a=0,o=t.length;a<o;a+=1){const d=Math.ceil(a/2)*(a%2===0?1:-1),u=e?g.mod(n+d,o):a;r[u]=this.loadImage(t[u],s)}return Promise.all(r).then(()=>this.onLoadEnd(this.progress)).catch(()=>{}),r}async loadVideo(t,e,i,s){t.loop=i;const r=new Promise((n,a)=>{t.addEventListener("canplaythrough",()=>{s===this.loadingId&&(this.loaded+=1,this.onLoadProgress(this.progress),n())},{once:!0}),t.addEventListener("error",o=>{s===this.loadingId&&a(`${o.type} : ${e}`)},{once:!0})});return t.src=e,t.load(),r}async loadVideoFrame(t,e,i,s,r){let n=0;return new Promise((a,o)=>{const d=()=>{if(r!==this.loadingId)return;if(n!==s){n+=1;return}t.removeEventListener("seeked",d);const u=document.createElement("canvas");u.width=t.videoWidth,u.height=t.videoHeight,u.getContext("2d").drawImage(t,0,0);const c=new Image;c.src=u.toDataURL(),a(c),this.loaded+=1,this.onLoadProgress(this.progress),s!==i-1&&(t.currentTime+=1/e)};t.addEventListener("seeked",d),t.addEventListener("error",u=>{r===this.loadingId&&o(u)},{once:!0})})}loadVideoFrames(t,e,i,s){this.total=e;const r=new Array(e),n=document.createElement("video");for(let a=0,o=e;a<o;a+=1)r[a]=this.loadVideoFrame(n,i,e,a,s);return n.addEventListener("canplaythrough",()=>{s===this.loadingId&&(n.currentTime=1/i/2)},{once:!0}),n.src=t,n.load(),Promise.all(r).then(()=>this.onLoadEnd(this.progress)).catch(()=>{}),r}async loadImageHotspots(t,e){return this.webrenderV2?await this.webrenderV2.imageHotspots(await this.convert(t),e):Promise.reject(new Error("Hotspots only available with api V2"))}async loadVRCubeHotspots(t,e){return this.webrenderV2?await this.webrenderV2.vrCubeHotspots(await this.convert(t),e):Promise.reject(new Error("Hotspots only available with api V2"))}async loadVRObjectHotspots(t,e){return this.webrenderV2?await this.webrenderV2.vrObjectHotspots(await this.convert(t),e):Promise.reject(new Error("Hotspots only available with api V2"))}async loadImagePick(t,e){return this.webrenderV2?await this.webrenderV2.imagePick(await this.convert(t),e):Promise.reject(new Error("Picking only available with api V2"))}async loadVRObjectPick(t,e,i,s){return this.webrenderV2?await this.webrenderV2.imagePick(await this.vrObjectFrameSnapshot(t,i,s),e):Promise.reject(new Error("Picking only available with api V2"))}async loadVRCubePick(t,e,i){return this.webrenderV2?await this.webrenderV2.imagePick(await this.vrCubeFrameSnapshot(t,i),e):Promise.reject(new Error("Picking only available with api V2"))}async convert(t){var o;if(!this.webrenderV2||this.webrender instanceof m||!t.view.camera)return t;const e=t.scene.find(d=>!d.decor&&!d.accessory);if(!e)return t;let i=this.databases.find(d=>d.id===e.database);(!i||!i.xmlDoc)&&(i=await this.webrender.database(e.database),this.databases.push(i));const s=(o=t.view.camera)==null?void 0:o.split("/"),r=s.length===2?s[0]:void 0,n=s.length===2?s[1]:s[0],a=i.getCameraId(n,r);if(a)return{...t,view:{...t.view,camera:a}};{const d=i.getCameraGroupId(n);return d?{...t,view:{...t.view,cameraGroup:d}}:t}}async vrObjectFrameSnapshot(t,e,i){if(!this.webrenderV2)return t;const s=t.scene.find(n=>!n.decor&&!n.accessory);if(!s)return t;let r=this.databases.find(n=>n.id===s.database);if(r||(r=await this.webrender.database(s.database),this.databases.push(r)),this.webrender instanceof S){if(!t.view.camera)return t;const n=r.getCameraGroupId(t.view.camera);if(!n)return t;const a=r.getCameraGroupById(n);if(!a)return t;const o=a.cameras[e];return o?{...t,view:{...t.view,camera:o.id}}:t}else if(this.webrender instanceof m)if(t.view.camera){const n=r.getCameraById(t.view.camera);if(!n)return t;const a=new W(n.pointOfView),o=2*Math.PI/i;a.longitude+=e*o%(2*Math.PI);const d=a.pointOfView(n.pointOfView.target);return{...t,view:{...t.view,camera:{id:n.id,pov:{target:{x:d.target[0],y:d.target[1],z:d.target[2]},eye:{x:d.eye[0],y:d.eye[1],z:d.eye[2]},up:{x:d.up[0],y:d.up[1],z:d.up[2]}}}}}}else if(t.view.cameraGroup){const n=r.getCameraGroupById(t.view.cameraGroup);if(!n)return t;const a=n.cameras[e];return a?{...t,view:{...t.view,camera:a.id}}:t}else return t;else return t}async vrCubeFrameSnapshot(t,e){const i=t.scene.find(o=>!o.decor&&!o.accessory);if(!i)return t;let s=this.databases.find(o=>o.id===i.database);if(s||(s=await this.webrender.database(i.database),this.databases.push(s)),!t.view.camera)return t;let r;if(this.webrender instanceof S){const o=t.view.camera.split("/"),d=o.length===2?o[0]:void 0,u=o.length===2?o[1]:o[0];r=s.getCameraId(u,d)}else this.webrender instanceof m&&(r=t.view.camera);if(!r)return t;const n=s.getCameraById(r);if(!n)return t;const a=I.initCubeFace(n.pointOfView.eye,n.pointOfView.target,e);return{...t,view:{...t.view,camera:{id:n.id,pov:{target:{x:a.target[0],y:a.target[1],z:a.target[2]},eye:{x:a.eye[0],y:a.eye[1],z:a.eye[2]},up:{x:a.up[0],y:a.up[1],z:a.up[2]}},lens:{fov:90}}},parameters:{...t.parameters,width:Math.max(t.parameters.width,t.parameters.height),height:Math.max(t.parameters.width,t.parameters.height)}}}onLoadStart(t){this.delegate&&this.delegate.onLoadStart(t)}onLoadProgress(t){this.delegate&&this.delegate.onLoadProgress(t)}onLoadEnd(t){this.delegate&&this.delegate.onLoadEnd(t)}static isValidHttpUrl(t){let e;try{e=new URL(t)}catch{return!1}return e.protocol==="http:"||e.protocol==="https:"}}class Z{constructor(){this.element=document.createElement("video"),this.element.classList.add("ls-viewer-video"),this.element.style.opacity="0",this.element.width=0,this.element.height=0,this.element.setAttribute("muted",""),this.element.setAttribute("playsinline",""),this.element.setAttribute("preload","auto")}show(){this.element.style.opacity="1"}hide(){this.element.style.opacity="0"}resize(t,e,i,s){const r=w.fit(i,new y(t,e),s);this.element.style.top=`${r.top}px`,this.element.style.left=`${r.left}px`,this.element.style.width=`${r.width}px`,this.element.style.height=`${r.height}px`,(i.width!==this.element.width||i.height!==this.element.height)&&(this.element.width=i.width,this.element.height=i.height)}}class q{constructor(t,e,i){this.container=t,this.canvas=e,this.loader=i,this.hotspotList=[]}destroy(){}show(){this.canvas.show(!1),this.container.classList.add("ls-viewer-container-image")}hide(){this.canvas.hide(!1),this.container.classList.remove("ls-viewer-container-image")}async load(t,e,i,s){let r=Promise.resolve();const n=JSON.stringify(t);n===this.snapshotHash&&this.image?r=r.then(()=>this.canvas.draw(this.image,s,.05)):r=r.then(()=>this.loader.loadImageSnapshot(t).then(o=>{this.canvas.draw(o,s,.05),this.image=o}));const a=JSON.stringify(e);return(n!==this.snapshotHash||a!==this.hotspotsHash)&&(e.length?r=r.then(()=>this.loader.loadImageHotspots(t,e).then(o=>{this.hotspotList=o})):this.hotspotList=[]),this.hotspotsHash=a,this.snapshotHash=n,r}async pick(t,e){const i=new y(t.parameters.width,t.parameters.height),s=w.unproject(i,this.canvas.resolution,this.canvas.fit,e);return this.loader.loadImagePick(t,s)}hotspots(t){return this.hotspotList.map(e=>({...e,position2D:w.project(t,this.canvas.resolution,this.canvas.fit,e.position2D)})).map(e=>({...e,visibility:w.contains(this.canvas.resolution,e.position2D)?e.visibility:"OutOfFrustum"}))}snapshot(t,e){return this.canvas.element.toDataURL(t,e)}onMouseDown(t){}onMouseMove(t){}onMouseUp(t){}onMouseEnter(t){}onTouchStart(t){}onTouchMove(t){}onTouchEnd(t){}onDeviceOrientation(t){}}class E{constructor(t,e){this.x=t,this.y=e}clone(){return new E(this.x,this.y)}}class f{static pointFromMouseEvent(t){return new E(t.screenX,t.screenY)}static pointFromTouchEvent(t){const e=t.targetTouches[0]||t.changedTouches[0];return new E(e.screenX,e.screenY)}}class V{constructor(...t){t.length===3?({0:this.u,1:this.v,2:this.o}=t,this.w=h.v3.cross(this.u,this.v)):t.length===4?{0:this.u,1:this.v,2:this.w,3:this.o}=t:(this.u=[1,0,0],this.v=[0,1,0],this.w=[0,0,1],this.o=[0,0,0])}get localToGlobalMatrix(){const t=[this.u[0],this.u[1],this.u[2],0],e=[this.v[0],this.v[1],this.v[2],0],i=[this.w[0],this.w[1],this.w[2],0],s=[this.o[0],this.o[1],this.o[2],1];return[...t,...e,...i,...s]}get globalToLocalMatrix(){return h.m4.inverse(this.localToGlobalMatrix)}}class Q{constructor(t,e,i){this.x=t,this.y=e,this.time=i}}class H{constructor(t){this.points=[],this.onMotion=t,this.lastPoint=new E(0,0),this.velocity=new E(0,0),this.loop=this.loop.bind(this)}destroy(){this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0)}track(t){const e=Date.now();this.points=this.points.filter(i=>e-i.time<=100),this.points.push(new Q(t.x,t.y,e)),this.lastPoint=t}start(){if(this.points.length===0)return;const t=this.points[0],e=this.points[this.points.length-1],i=e.x-t.x,s=e.y-t.y,r=e.time-t.time;this.velocity=new E(r===0?0:i/(r/15),r===0?0:s/(r/15)),this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0),this.animationFrameId=requestAnimationFrame(this.loop)}stop(){this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0),this.points=[]}loop(){if(Math.abs(this.velocity.x)<1&&Math.abs(this.velocity.y)<1){this.animationFrameId=void 0,this.points=[];return}this.lastPoint.x+=this.velocity.x,this.lastPoint.y+=this.velocity.y,this.velocity.x*=.9,this.velocity.y*=.9,this.onMotion(this.lastPoint.clone()),this.animationFrameId=requestAnimationFrame(this.loop)}}class _{constructor(t,e,i){this.isStarted=!1,this.pov=t,this.fov=g.degreesToRadians(e),this.orientationMatrix=h.m4.identity(),this.inertia=new H(this.motion.bind(this)),this.onMotion=i,this.initPov=this.pov,this.initFov=this.fov,this.initOrientation=g.degreesToRadians(window.orientation)||0,this.startPov=new I([0,0,1],[0,0,0],[0,1,0]),this.startSize={width:0,height:0},this.previousPoint=new E(0,0)}destroy(){this.inertia.destroy()}get orientedPov(){const t=h.v3.normalize(h.v3.cross(this.pov.up,this.pov.target)),e=new V(t,[0,1,0],this.pov.eye),i=h.m4.identity();h.m4.multiply(i,e.localToGlobalMatrix,i),h.m4.multiply(i,this.orientationMatrix,i),h.m4.multiply(i,e.globalToLocalMatrix,i);const s=h.m4.transformDirection(i,this.pov.target),r=this.pov.eye,n=h.m4.transformDirection(i,this.pov.up);return new I(s,r,n)}reset(){this.pov=this.initPov.clone(),this.fov=this.initFov}start(t,e){this.isStarted=!0,this.startPov=this.pov,this.startSize=e,this.previousPoint=t,this.inertia.stop()}motion(t){this.isStarted&&this.inertia.track(t);const e={x:t.x-this.previousPoint.x,y:t.y-this.previousPoint.y},i=g.accelerate(e.x,1.3)/this.startSize.width*.2*Math.PI*1.5,s=g.accelerate(e.y,1.3)/this.startSize.height*.2*Math.PI,r=h.m4.multiply(h.m4.rotationY(i),h.m4.rotationX(-s)),n=h.v3.normalize(h.v3.cross(this.pov.up,this.pov.target)),a=new V(n,[0,1,0],this.pov.eye),o=h.m4.identity();h.m4.multiply(o,a.localToGlobalMatrix,o),h.m4.multiply(o,r,o),h.m4.multiply(o,a.globalToLocalMatrix,o);const d=h.m4.transformPoint(o,this.pov.target),u=h.m4.transformDirection(o,this.pov.up);h.v3.cross(u,[0,0,1])[0]>=0&&(this.pov.target=d,this.pov.up=u),this.previousPoint=t,this.onMotion()}end(t,e){this.isStarted=!1,e&&(this.inertia.track(t),this.inertia.start())}orientation(t,e,i){const s=g.degreesToRadians(window.orientation)||0,r=g.degreesToRadians(t),n=g.degreesToRadians(-e),a=g.degreesToRadians(-i),o=h.m4.rotationX(g.degreesToRadians(90));h.m4.rotateZ(o,this.initOrientation,o),h.m4.rotateZ(o,r,o),h.m4.rotateX(o,n,o),h.m4.rotateY(o,a,o),h.m4.rotateZ(o,-s,o),this.orientationMatrix=o,this.onMotion()}}var K=`precision mediump float;
2
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const C=require("debounce-promise"),h=require("twgl.js"),U=require("regression");function N(l){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(l){for(const e in l)if(e!=="default"){const i=Object.getOwnPropertyDescriptor(l,e);Object.defineProperty(t,e,i.get?i:{enumerable:!0,get:()=>l[e]})}}return t.default=l,Object.freeze(t)}const P=N(h);class y{constructor(t,e){this.width=t,this.height=e}get aspect(){return this.width/this.height}}class w{constructor(t,e,i,s){this.top=t,this.left=e,this.width=i,this.height=s}static contains(t,e){return e.x>=0&&e.x<t.width&&e.y>=0&&e.y<t.height}static fit(t,e,i){const s=t.aspect,r=e.aspect;let n=0,a=0;switch(i){case"contain":n=r<s?e.width:e.height*s,a=r<s?e.width/s:e.height;break;case"cover":default:n=r<s?e.height*s:e.width,a=r<s?e.height:e.width/s;break;case"fill":n=e.width,a=e.height;break}const o=(e.height-a)/2,d=(e.width-n)/2;return new w(o,d,n,a)}static project(t,e,i,s){const r=w.fit(t,e,i),n=r.width/t.width,a=r.height/t.height;return{x:Math.round(r.left+s.x*n),y:Math.round(r.top+s.y*a)}}static unproject(t,e,i,s){const r=w.fit(t,e,i),n=r.width/t.width,a=r.height/t.height;return{x:Math.round((s.x-r.left)/n),y:Math.round((s.y-r.top)/a)}}static getStandardAspectRatio(t,e){if(t===0||e===0)return 0;const i=t/e;if(t<e){const n=Math.abs(.75-i),a=Math.abs(9/16-i);return n<a?3/4:9/16}const s=Math.abs(4/3-i),r=Math.abs(16/9-i);return s<r?4/3:16/9}static getStandardResolution(t,e){if(t===0||e===0)return new y(0,0);const i=w.getStandardAspectRatio(t,e);if(t<e){const r=w.getStandardQuality(Math.max(e*i,t));return new y(Math.round(r),Math.round(r/i))}const s=w.getStandardQuality(Math.max(t/i,e));return new y(Math.round(s*i),Math.round(s))}static getStandardQuality(t){return t<=240?240:t<=360?360:t<=480?480:t<=720?720:1080}}class B{constructor(t){this.element=document.createElement("canvas"),this.element.classList.add("ls-viewer-canvas"),this.element.style.opacity="0",this.element.width=0,this.element.height=0,this.context=this.element.getContext("2d"),this.backCanvas=document.createElement("canvas"),this.backContext=this.backCanvas.getContext("2d"),this.fit=t,this.pixelRatio=1}destroy(){this.requestAnimationId&&(cancelAnimationFrame(this.requestAnimationId),this.requestAnimationId=void 0)}show(t){t?this.element.style.display="block":this.element.style.opacity="1"}hide(t){t?this.element.style.display="none":this.element.style.opacity="0"}get resolution(){return new y(this.element.width/this.pixelRatio,this.element.height/this.pixelRatio)}resize(t,e,i){this.element.width=t*i,this.element.height=e*i,this.element.style.width=`${t}px`,this.element.style.height=`${e}px`,this.backCanvas.width=t*i,this.backCanvas.height=e*i,this.pixelRatio=i}draw(t,e,i){if(!t)return;this.requestAnimationId&&(cancelAnimationFrame(this.requestAnimationId),this.requestAnimationId=void 0);const s=w.fit(new y(t.width,t.height),new y(this.element.width,this.element.height),this.fit);e?(this.backContext.drawImage(this.element,0,0),this.context.globalAlpha=0,this.fadeLoop(t,i||0)):(this.context.globalAlpha=1,this.context.drawImage(t,s.left,s.top,s.width,s.height)),this.image=t}fadeLoop(t,e){if(this.context.globalAlpha>=1){cancelAnimationFrame(this.requestAnimationId),this.requestAnimationId=void 0;return}const i=Math.min(this.context.globalAlpha+e,1),s=w.fit(new y(t.width,t.height),new y(this.element.width,this.element.height),this.fit);this.context.clearRect(0,0,this.element.width,this.element.height),this.context.globalAlpha=1,this.context.drawImage(this.backCanvas,0,0),this.context.globalAlpha=i,this.context.drawImage(t,s.left,s.top,s.width,s.height),this.requestAnimationId=requestAnimationFrame(()=>{this.fadeLoop(t,e)})}}class X{constructor(){this.element=document.createElement("canvas"),this.element.classList.add("ls-viewer-canvas"),this.element.style.opacity="0",this.element.width=0,this.element.height=0,this.context=P.getContext(this.element,{preserveDrawingBuffer:!0}),this.context&&this.context.isContextLost()&&(this.context=void 0),P.setDefaults({textureColor:[1,1,1,1]})}show(){this.element.style.opacity="1"}hide(){this.element.style.opacity="0"}resize(t,e,i){this.element.width=t*i,this.element.height=e*i,this.element.style.width=`${t}px`,this.element.style.height=`${e}px`}}class g{static accelerate(t,e){const i=e||1.5;return Math.abs(t)**i*(t>0?1:-1)}static clamp(t,e,i){return Math.max(Math.min(t,i),e)}static degreesToRadians(t){return t*(Math.PI/180)}static radiansToDegrees(t){return t*(180/Math.PI)}static mod(t,e){return t-e*Math.floor(t/e)}static perspectiveWithFovX(t,e,i,s,r){const n=Math.tan(t/2),a=n/e;return this.perspectiveWithLeft(-n,n,-a,a,i,s,r)}static perspectiveWithFovY(t,e,i,s,r){const n=i*Math.tan(t/2),a=n*e;return this.perspectiveWithLeft(-a,a,-n,n,i,s,r)}static perspectiveWithLeft(t,e,i,s,r,n,a){a=a||new Float32Array(16);const o=e+t,d=e-t,u=s+i,p=s-i,c=n-r;return a[0]=2*r/d,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=2*r/p,a[6]=0,a[7]=0,a[8]=o/d,a[9]=u/p,a[10]=-n/c,a[11]=-1,a[12]=0,a[13]=0,a[14]=-n*r/c,a[15]=0,a}}const F=class F{static initCubeFace(t,e,i){let s=[0,0,0];const r=h.v3.subtract(e,t),n=h.v3.mulScalar([0,1,0],h.v3.length(r)),a=h.v3.mulScalar(h.v3.normalize(h.v3.cross(r,n)),h.v3.length(r)),o=h.v3.mulScalar(h.v3.normalize(h.v3.cross(n,a)),h.v3.length(r));switch(i){case"front":e=h.v3.add(t,o),s=h.v3.normalize(n);break;case"right":e=h.v3.add(t,a),s=h.v3.normalize(n);break;case"back":e=h.v3.subtract(t,o),s=h.v3.normalize(n);break;case"left":e=h.v3.subtract(t,a),s=h.v3.normalize(n);break;case"up":e=h.v3.add(t,n),s=h.v3.normalize(h.v3.mulScalar(o,-1));break;case"down":e=h.v3.subtract(t,n),s=h.v3.normalize(o);break}return new F(e,t,s)}constructor(t,e,i){this.target=h.v3.copy(t),this.eye=h.v3.copy(e),this.up=h.v3.copy(i)}get viewVector(){return h.v3.subtract(this.target,this.eye)}get rightVector(){return h.v3.normalize(h.v3.cross(this.viewVector,this.up))}get viewMatrix(){return h.m4.inverse(h.m4.lookAt(this.eye,this.target,this.up))}clone(){return new F(h.v3.copy(this.target),h.v3.copy(this.eye),h.v3.copy(this.up))}};F.default=new F([0,0,0],[2,2,2],[0,1,0]);let I=F;class Y{constructor(t){this.target=t.target;const e=h.v3.normalize(h.v3.subtract(t.eye,t.target)),i=h.v3.dot(e,[1,0,0]),s=h.v3.dot(e,[0,1,0]),r=h.v3.dot(e,[0,0,1]);this.longitude=Math.atan2(i,r),this.latitude=Math.atan2(s,Math.sqrt(i*i+r*r)),h.v3.dot(t.up,[0,1,0])<0&&(this.longitude=Math.PI+this.longitude,this.latitude=Math.PI-this.latitude),this.distance=h.v3.length(h.v3.subtract(t.target,t.eye))}get vector(){const t=Math.cos(this.latitude)*this.distance,e=Math.sin(this.latitude)*this.distance,i=Math.cos(this.longitude)*t,s=Math.sin(this.longitude)*t;return[i,e,s]}pointOfView(t){const e=h.m4.rotationY(this.longitude),i=h.m4.rotationX(-this.latitude),s=h.m4.rotationZ(0),r=h.m4.multiply(e,h.m4.multiply(i,s));let n=[0,0,-1];n=h.m4.transformPoint(r,n);let a=[0,1,0];a=h.m4.transformPoint(r,a);const o=h.v3.subtract(t,h.v3.mulScalar(n,this.distance));return new I(t,o,a)}}class W{constructor(){}async animation(t){return t.scene}async database(t){throw new Error("Unavailable")}async image(t){return t.scene}async video(t){return t.scene}async vrCube(t){return t.scene}async vrObject(t){return t.scene}}class V{constructor(t){this.xmlDoc=t}get id(){return this.xmlDoc.getElementsByTagName("Database")[0]?.getAttribute("id")}getCameraId(t,e){return e?this.xmlDoc.querySelector(`RootCameraGroup Group[name="${e}"] Camera[name="${t}"]`)?.getAttribute("id"):this.xmlDoc.querySelector(`RootCameraGroup Camera[name="${t}"]`)?.getAttribute("id")}getCameraById(t,e){let i;return t&&e?i=this.xmlDoc.querySelector(`RootCameraGroup Group[id="${e}"] Camera[id="${t}"]`):i=this.xmlDoc.querySelector(`RootCameraGroup Camera[id="${t}"]`),i?this.mapElementToCamera(i):null}getCameraByName(t,e){let i;return e&&t?i=this.xmlDoc.querySelector(`RootCameraGroup Group[name="${e}"] Camera[name="${t}"]`):i=this.xmlDoc.querySelector(`RootCameraGroup Camera[name="${t}"]`),i?this.mapElementToCamera(i):null}getCameraGroupId(t){return this.xmlDoc.querySelector(`RootCameraGroup Group[name="${t}"]`)?.getAttribute("id")}getCameraGroupById(t){const e=this.xmlDoc.querySelector(`RootCameraGroup Group[id="${t}"]`);return e?this.mapElementToCameraGroup(e):null}getCameraGroupByName(t){const e=this.xmlDoc.querySelector(`RootCameraGroup Group[name="${t}"]`);return e?this.mapElementToCameraGroup(e):null}mapElementToCamera(t){return{id:t.getAttribute("id"),name:t.getAttribute("name"),pointOfView:new I([parseFloat(t.querySelector("PointOfView Target").getAttribute("x")),parseFloat(t.querySelector("PointOfView Target").getAttribute("y")),parseFloat(t.querySelector("PointOfView Target").getAttribute("z"))],[parseFloat(t.querySelector("PointOfView Eye").getAttribute("x")),parseFloat(t.querySelector("PointOfView Eye").getAttribute("y")),parseFloat(t.querySelector("PointOfView Eye").getAttribute("z"))],[parseFloat(t.querySelector("PointOfView Up").getAttribute("x")),parseFloat(t.querySelector("PointOfView Up").getAttribute("y")),parseFloat(t.querySelector("PointOfView Up").getAttribute("z"))])}}mapElementToCameraGroup(t){return{id:t.getAttribute("id"),name:t.getAttribute("name"),cameras:[...t.querySelectorAll("Camera")].map(e=>this.mapElementToCamera(e))}}}const v=class v{constructor(t){this.server=t}static buildQuery(t){return Object.entries(t).filter(([e,i])=>i!=null).map(([e,i])=>`${e}=${i}`).join("&")}static sceneParameters(t){const e=t.scene,i=e.length>1?e.find(n=>n.accessory):null,s=e.length>1?e.find(n=>n.decor):null,r=e.find(n=>n!==i&&n!==s);return{databaseId:r.database,configuration:r?.configuration,animations:r?.animations?.join("/"),accessoryDatabaseId:i?.database,decorDatabaseId:s?.database,decorDeltaAltitude:s?.translation?.y}}static renderParameters(t){const{parameters:e,view:i}=t;return{background:i.background,width:e.width,height:e.height,softwareAntialiasing:e.antialiasing,superSampling:e.superSampling}}static encoderParameters(t){const{encoder:e}=t;return{imageFormat:e.format,imageQuality:e.quality}}static async fetch(t){return fetch(t).then(e=>e.text()).then(e=>{const s=e.replace(/&amp;/g,"&").match(this.xmlRegex);return s?s.map(r=>r.replace(this.xmlRegex,"$1")):Promise.reject()})}async animation(t){const e={...v.sceneParameters(t),animation:t.view.animation,bookmarkSet:t.view.camera.split("/")[0],bookmark:t.view.camera.split("/")[1],frames:t.view.frames,loop:!!t.view.loop,...v.renderParameters(t),...v.encoderParameters(t)},i=v.buildQuery(e);return v.fetch(`${this.server}/ImagesFromAnimation?${i}`)}async database(t){return fetch(`${this.server}/Database?databaseId=${t}`).then(e=>e.text()).then(e=>{const i=new DOMParser().parseFromString(e,"application/xml");return new V(i)})}async image(t){const e={...v.sceneParameters(t),bookmarkSet:t.view.camera.split("/")[0],bookmark:t.view.camera.split("/")[1],...v.renderParameters(t),...v.encoderParameters(t)},i=v.buildQuery(e);return Promise.resolve(`${this.server}/ImageFromBookmark?${i}`)}async video(t){const e={...v.sceneParameters(t),animation:t.view.animation,bookmarkSet:t.view.camera.split("/")[0],bookmark:t.view.camera.split("/")[1],duration:t.view.duration,frames:t.view.frames,loop:!!t.view.loop,reverse:!!t.view.reverse,...v.renderParameters(t),...v.encoderParameters(t)},i=v.buildQuery(e);return Promise.resolve(`${this.server}/ImagesFromAnimation?${i}`)}async vrCube(t){const e={...v.sceneParameters(t),bookmarkSet:t.view.camera.split("/")[0],bookmark:t.view.camera.split("/")[1],...v.renderParameters(t),...v.encoderParameters(t)};e.width=Math.max(e.width,e.height),e.height=Math.max(e.width,e.height);const i=v.buildQuery(e);return v.fetch(`${this.server}/CubeFromBookmark?${i}`)}async vrObject(t){const e={...v.sceneParameters(t),bookmarkSet:t.view.camera,...v.renderParameters(t),...v.encoderParameters(t)},i=v.buildQuery(e);return v.fetch(`${this.server}/ImagesFromBookmarkSet?${i}`)}};v.xmlRegex=/directUrl="([^"]*)"/g;let S=v;class m{constructor(t){this.server=t}static scene(t){return t.scene.map(e=>{const{accessory:i,decor:s,...r}=e;return r})}static renderParameters(t){return{...t.parameters,superSampling:t.parameters.superSampling.toString()}}static encoder(t){switch(t.encoder.format){case"jpeg":return{jpeg:{quality:t.encoder.quality}};case"png":return{png:{compression:t.encoder.compression}};case"webp":return{webp:{quality:t.encoder.quality}}}return{jpeg:{quality:80}}}static async fetchFrame(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json()).then(i=>i.url)}static async fetchFrameArray(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json()).then(i=>i.map(s=>s.url))}static async fetchHotspots(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json())}static async fetchHotspotsArray(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json())}static async fetchPick(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json()).then(i=>i[0])}async database(t){return fetch(`${this.server}/Database?databaseId=${t}`).then(e=>e.text()).then(e=>{const i=new DOMParser().parseFromString(e,"application/xml");return new V(i)})}async image(t){const e={scene:m.scene(t),mode:{image:{camera:t.view.camera}},renderParameters:m.renderParameters(t),encoder:m.encoder(t)};return m.fetchFrame(`${this.server}/Snapshot`,e)}async vrCube(t){const e={scene:m.scene(t),mode:{vrCube:{camera:t.view.camera}},renderParameters:m.renderParameters(t),encoder:m.encoder(t)};return e.renderParameters.width=Math.max(e.renderParameters.width,e.renderParameters.height),e.renderParameters.height=Math.max(e.renderParameters.width,e.renderParameters.height),m.fetchFrameArray(`${this.server}/Snapshot`,e)}async vrObject(t){let e;t.view.cameraGroup?e={images:{cameraGroup:t.view.cameraGroup}}:t.view.frames?e={vrObject:{camera:t.view.camera,frames:t.view.frames}}:e={vrObject:{camera:t.view.camera,panFrames:t.view.panFrames||1,panFrom:t.view.panFrom||0,panTo:t.view.panTo||0,panLoop:t.view.panLoop||!1,tiltFrames:t.view.tiltFrames||1,tiltFrom:t.view.tiltFrom||0,tiltTo:t.view.tiltTo||0,tiltLoop:t.view.tiltLoop||!1}};const i={scene:m.scene(t),mode:e,renderParameters:m.renderParameters(t),encoder:m.encoder(t)};return m.fetchFrameArray(`${this.server}/Snapshot`,i)}async animation(t){const e={scene:m.scene(t),mode:{animation:{id:t.view.animation,camera:t.view.camera,fps:t.view.fps}},renderParameters:m.renderParameters(t),encoder:m.encoder(t)};return m.fetchFrameArray(`${this.server}/Snapshot`,e)}async imageHotspots(t,e){const i={scene:m.scene(t),mode:{image:{camera:t.view.camera}},renderParameters:m.renderParameters(t),...this.hotspotsBody(e)};return await m.fetchHotspots(`${this.server}/Hotspot`,i)}async imagePick(t,e){const i={scene:m.scene(t),camera:t.view.camera,renderParameters:m.renderParameters(t),positions:[e]};return await m.fetchPick(`${this.server}/Pick`,i)}async vrCubeHotspots(t,e){const i={scene:m.scene(t),mode:{vrCube:{camera:t.view.camera}},renderParameters:m.renderParameters(t),...this.hotspotsBody(e)};return i.renderParameters.width=Math.max(i.renderParameters.width,i.renderParameters.height),i.renderParameters.height=Math.max(i.renderParameters.width,i.renderParameters.height),await m.fetchHotspotsArray(`${this.server}/Hotspot`,i)}async vrObjectHotspots(t,e){let i;t.view.cameraGroup?i={images:{cameraGroup:t.view.cameraGroup}}:t.view.frames?i={vrObject:{camera:t.view.camera,frames:t.view.frames}}:i={vrObject:{camera:t.view.camera,panFrames:t.view.panFrames||1,panFrom:t.view.panFrom||0,panTo:t.view.panTo||0,panLoop:t.view.panLoop||!1,tiltFrames:t.view.tiltFrames||1,tiltFrom:t.view.tiltFrom||0,tiltTo:t.view.tiltTo||0,tiltLoop:t.view.tiltLoop||!1}};const s={scene:m.scene(t),mode:i,renderParameters:m.renderParameters(t),...this.hotspotsBody(e)};return await m.fetchHotspotsArray(`${this.server}/Hotspot`,s)}hotspotsBody(t){return{positions:t.every(e=>typeof e!="string")?t:void 0,tags:t.every(e=>typeof e=="string")?t:void 0}}}class k{constructor(t,e,i){switch(e){case"static":this.webrender=new W;break;case"v1":this.webrender=new S(t),this.webrenderV2=new m(t);break;case"v2":this.webrender=new m(t),this.webrenderV2=new m(t);break;default:this.webrender=new S(t),this.webrenderV2=new m(t);break}this.delegate=i,this.loadingId=0,this.loaded=0,this.total=0,this.databases=[],this.onLoadStart=i&&i.onLoadStart?i.onLoadStart:()=>{},this.onLoadProgress=i&&i.onLoadProgress?i.onLoadProgress:()=>{},this.onLoadEnd=i&&i.onLoadEnd?i.onLoadEnd:()=>{}}get progress(){return this.total?this.loaded/this.total:0}async loadImageSnapshot(t){this.loadingId+=1,this.loaded=0,this.total=1,this.onLoadStart(this.progress);const{loadingId:e}=this;return this.webrender.image(t).then(i=>this.loadImage(i,e)).then(i=>(this.onLoadEnd(this.progress),i))}async loadVideoSnapshot(t,e){this.loadingId+=1,this.loaded=0,this.total=1,this.onLoadStart(this.progress);const{loadingId:i}=this;return this.webrender.video(e).then(s=>this.loadVideo(t,s,!!e.view.loop,i)).then(()=>(this.onLoadEnd(this.progress),t))}async loadVRCubeSnapshot(t){this.loadingId+=1,this.loaded=0,this.total=0,this.onLoadStart(this.progress);const{loadingId:e}=this;return this.webrender.vrCube(t).then(i=>{this.total=i.length;const s=i.map(r=>this.loadImage(r,e));return Promise.all(s)}).then(i=>(this.onLoadEnd(this.progress),i))}async loadVRObjectSnapshot(t,e){this.loadingId+=1,this.loaded=0,this.total=0,this.onLoadStart(this.progress);const{loadingId:i}=this;return t.view.animation?t.encoder?.format==="mp4"?this.webrender.video(t).then(s=>this.loadVideoFrames(s,t.view.frames,30,i)):this.webrender.animation(t).then(s=>this.loadImageFrames(s,t.view.loop,e,i)):this.webrender.vrObject(t).then(s=>this.loadImageFrames(s,t.view.loop,e,i))}async loadImage(t,e){const i=new Image;i.crossOrigin=location.protocol==="file:"&&!k.isValidHttpUrl(t)?null:"anonymous";const s=new Promise((r,n)=>{i.addEventListener("load",()=>{e===this.loadingId&&(this.loaded+=1,this.onLoadProgress(this.progress),r(i))},{once:!0}),i.addEventListener("error",a=>{e===this.loadingId&&n(`${a.type} : ${t}`)},{once:!0})});return i.src=t,s}loadImageFrames(t,e,i,s){this.total=t.length;const r=new Array(t.length),n=i||0;for(let a=0,o=t.length;a<o;a+=1){const d=Math.ceil(a/2)*(a%2===0?1:-1),u=e?g.mod(n+d,o):a;r[u]=this.loadImage(t[u],s)}return Promise.all(r).then(()=>this.onLoadEnd(this.progress)).catch(()=>{}),r}async loadVideo(t,e,i,s){t.loop=i;const r=new Promise((n,a)=>{t.addEventListener("canplaythrough",()=>{s===this.loadingId&&(this.loaded+=1,this.onLoadProgress(this.progress),n())},{once:!0}),t.addEventListener("error",o=>{s===this.loadingId&&a(`${o.type} : ${e}`)},{once:!0})});return t.src=e,t.load(),r}async loadVideoFrame(t,e,i,s,r){let n=0;return new Promise((a,o)=>{const d=()=>{if(r!==this.loadingId)return;if(n!==s){n+=1;return}t.removeEventListener("seeked",d);const u=document.createElement("canvas");u.width=t.videoWidth,u.height=t.videoHeight,u.getContext("2d").drawImage(t,0,0);const c=new Image;c.src=u.toDataURL(),a(c),this.loaded+=1,this.onLoadProgress(this.progress),s!==i-1&&(t.currentTime+=1/e)};t.addEventListener("seeked",d),t.addEventListener("error",u=>{r===this.loadingId&&o(u)},{once:!0})})}loadVideoFrames(t,e,i,s){this.total=e;const r=new Array(e),n=document.createElement("video");for(let a=0,o=e;a<o;a+=1)r[a]=this.loadVideoFrame(n,i,e,a,s);return n.addEventListener("canplaythrough",()=>{s===this.loadingId&&(n.currentTime=1/i/2)},{once:!0}),n.src=t,n.load(),Promise.all(r).then(()=>this.onLoadEnd(this.progress)).catch(()=>{}),r}async loadImageHotspots(t,e){return this.webrenderV2?await this.webrenderV2.imageHotspots(await this.convert(t),e):Promise.reject(new Error("Hotspots only available with api V2"))}async loadVRCubeHotspots(t,e){return this.webrenderV2?await this.webrenderV2.vrCubeHotspots(await this.convert(t),e):Promise.reject(new Error("Hotspots only available with api V2"))}async loadVRObjectHotspots(t,e){return this.webrenderV2?await this.webrenderV2.vrObjectHotspots(await this.convert(t),e):Promise.reject(new Error("Hotspots only available with api V2"))}async loadImagePick(t,e){return this.webrenderV2?await this.webrenderV2.imagePick(await this.convert(t),e):Promise.reject(new Error("Picking only available with api V2"))}async loadVRObjectPick(t,e,i,s){return this.webrenderV2?await this.webrenderV2.imagePick(await this.vrObjectFrameSnapshot(t,i,s),e):Promise.reject(new Error("Picking only available with api V2"))}async loadVRCubePick(t,e,i){return this.webrenderV2?await this.webrenderV2.imagePick(await this.vrCubeFrameSnapshot(t,i),e):Promise.reject(new Error("Picking only available with api V2"))}async convert(t){if(!this.webrenderV2||this.webrender instanceof m||!t.view.camera)return t;const e=t.scene.find(o=>!o.decor&&!o.accessory);if(!e)return t;let i=this.databases.find(o=>o.id===e.database);(!i||!i.xmlDoc)&&(i=await this.webrender.database(e.database),this.databases.push(i));const s=t.view.camera?.split("/"),r=s.length===2?s[0]:void 0,n=s.length===2?s[1]:s[0],a=i.getCameraId(n,r);if(a)return{...t,view:{...t.view,camera:a}};{const o=i.getCameraGroupId(n);return o?{...t,view:{...t.view,cameraGroup:o}}:t}}async vrObjectFrameSnapshot(t,e,i){if(!this.webrenderV2)return t;const s=t.scene.find(n=>!n.decor&&!n.accessory);if(!s)return t;let r=this.databases.find(n=>n.id===s.database);if(r||(r=await this.webrender.database(s.database),this.databases.push(r)),this.webrender instanceof S){if(!t.view.camera)return t;const n=r.getCameraGroupId(t.view.camera);if(!n)return t;const a=r.getCameraGroupById(n);if(!a)return t;const o=a.cameras[e];return o?{...t,view:{...t.view,camera:o.id}}:t}else if(this.webrender instanceof m)if(t.view.camera){const n=r.getCameraById(t.view.camera);if(!n)return t;const a=new Y(n.pointOfView),o=2*Math.PI/i;a.longitude+=e*o%(2*Math.PI);const d=a.pointOfView(n.pointOfView.target);return{...t,view:{...t.view,camera:{id:n.id,pov:{target:{x:d.target[0],y:d.target[1],z:d.target[2]},eye:{x:d.eye[0],y:d.eye[1],z:d.eye[2]},up:{x:d.up[0],y:d.up[1],z:d.up[2]}}}}}}else if(t.view.cameraGroup){const n=r.getCameraGroupById(t.view.cameraGroup);if(!n)return t;const a=n.cameras[e];return a?{...t,view:{...t.view,camera:a.id}}:t}else return t;else return t}async vrCubeFrameSnapshot(t,e){const i=t.scene.find(o=>!o.decor&&!o.accessory);if(!i)return t;let s=this.databases.find(o=>o.id===i.database);if(s||(s=await this.webrender.database(i.database),this.databases.push(s)),!t.view.camera)return t;let r;if(this.webrender instanceof S){const o=t.view.camera.split("/"),d=o.length===2?o[0]:void 0,u=o.length===2?o[1]:o[0];r=s.getCameraId(u,d)}else this.webrender instanceof m&&(r=t.view.camera);if(!r)return t;const n=s.getCameraById(r);if(!n)return t;const a=I.initCubeFace(n.pointOfView.eye,n.pointOfView.target,e);return{...t,view:{...t.view,camera:{id:n.id,pov:{target:{x:a.target[0],y:a.target[1],z:a.target[2]},eye:{x:a.eye[0],y:a.eye[1],z:a.eye[2]},up:{x:a.up[0],y:a.up[1],z:a.up[2]}},lens:{fov:90}}},parameters:{...t.parameters,width:Math.max(t.parameters.width,t.parameters.height),height:Math.max(t.parameters.width,t.parameters.height)}}}onLoadStart(t){this.delegate&&this.delegate.onLoadStart(t)}onLoadProgress(t){this.delegate&&this.delegate.onLoadProgress(t)}onLoadEnd(t){this.delegate&&this.delegate.onLoadEnd(t)}static isValidHttpUrl(t){let e;try{e=new URL(t)}catch{return!1}return e.protocol==="http:"||e.protocol==="https:"}}class J{constructor(){this.element=document.createElement("video"),this.element.classList.add("ls-viewer-video"),this.element.style.opacity="0",this.element.width=0,this.element.height=0,this.element.setAttribute("muted",""),this.element.setAttribute("playsinline",""),this.element.setAttribute("preload","auto")}show(){this.element.style.opacity="1"}hide(){this.element.style.opacity="0"}resize(t,e,i,s){const r=w.fit(i,new y(t,e),s);this.element.style.top=`${r.top}px`,this.element.style.left=`${r.left}px`,this.element.style.width=`${r.width}px`,this.element.style.height=`${r.height}px`,(i.width!==this.element.width||i.height!==this.element.height)&&(this.element.width=i.width,this.element.height=i.height)}}class j{constructor(t,e,i){this.container=t,this.canvas=e,this.loader=i,this.hotspotList=[]}destroy(){}show(){this.canvas.show(!1),this.container.classList.add("ls-viewer-container-image")}hide(){this.canvas.hide(!1),this.container.classList.remove("ls-viewer-container-image")}async load(t,e,i,s){let r=Promise.resolve();const n=JSON.stringify(t);n===this.snapshotHash&&this.image?r=r.then(()=>this.canvas.draw(this.image,s,.05)):r=r.then(()=>this.loader.loadImageSnapshot(t).then(o=>{this.canvas.draw(o,s,.05),this.image=o}));const a=JSON.stringify(e);return(n!==this.snapshotHash||a!==this.hotspotsHash)&&(e.length?r=r.then(()=>this.loader.loadImageHotspots(t,e).then(o=>{this.hotspotList=o})):this.hotspotList=[]),this.hotspotsHash=a,this.snapshotHash=n,r}async pick(t,e){const i=new y(t.parameters.width,t.parameters.height),s=w.unproject(i,this.canvas.resolution,this.canvas.fit,e);return this.loader.loadImagePick(t,s)}hotspots(t){return this.hotspotList.map(e=>({...e,position2D:w.project(t,this.canvas.resolution,this.canvas.fit,e.position2D)})).map(e=>({...e,visibility:w.contains(this.canvas.resolution,e.position2D)?e.visibility:"OutOfFrustum"}))}snapshot(t,e){return this.canvas.element.toDataURL(t,e)}onMouseDown(t){}onMouseMove(t){}onMouseUp(t){}onMouseEnter(t){}onTouchStart(t){}onTouchMove(t){}onTouchEnd(t){}onDeviceOrientation(t){}}class E{constructor(t,e){this.x=t,this.y=e}clone(){return new E(this.x,this.y)}}class f{static pointFromMouseEvent(t){return new E(t.screenX,t.screenY)}static pointFromTouchEvent(t){const e=t.targetTouches[0]||t.changedTouches[0];return new E(e.screenX,e.screenY)}}class D{constructor(...t){t.length===3?({0:this.u,1:this.v,2:this.o}=t,this.w=h.v3.cross(this.u,this.v)):t.length===4?{0:this.u,1:this.v,2:this.w,3:this.o}=t:(this.u=[1,0,0],this.v=[0,1,0],this.w=[0,0,1],this.o=[0,0,0])}get localToGlobalMatrix(){const t=[this.u[0],this.u[1],this.u[2],0],e=[this.v[0],this.v[1],this.v[2],0],i=[this.w[0],this.w[1],this.w[2],0],s=[this.o[0],this.o[1],this.o[2],1];return[...t,...e,...i,...s]}get globalToLocalMatrix(){return h.m4.inverse(this.localToGlobalMatrix)}}class Z{constructor(t,e,i){this.x=t,this.y=e,this.time=i}}class q{constructor(t){this.points=[],this.onMotion=t,this.lastPoint=new E(0,0),this.velocity=new E(0,0),this.loop=this.loop.bind(this)}destroy(){this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0)}track(t){const e=Date.now();this.points=this.points.filter(i=>e-i.time<=100),this.points.push(new Z(t.x,t.y,e)),this.lastPoint=t}start(){if(this.points.length===0)return;const t=this.points[0],e=this.points[this.points.length-1],i=e.x-t.x,s=e.y-t.y,r=e.time-t.time;this.velocity=new E(r===0?0:i/(r/15),r===0?0:s/(r/15)),this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0),this.animationFrameId=requestAnimationFrame(this.loop)}stop(){this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0),this.points=[]}loop(){if(Math.abs(this.velocity.x)<1&&Math.abs(this.velocity.y)<1){this.animationFrameId=void 0,this.points=[];return}this.lastPoint.x+=this.velocity.x,this.lastPoint.y+=this.velocity.y,this.velocity.x*=.9,this.velocity.y*=.9,this.onMotion(this.lastPoint.clone()),this.animationFrameId=requestAnimationFrame(this.loop)}}class Q{constructor(t,e,i){this.isStarted=!1,this.pov=t,this.fov=g.degreesToRadians(e),this.orientationMatrix=h.m4.identity(),this.inertia=new q(this.motion.bind(this)),this.onMotion=i,this.initPov=this.pov,this.initFov=this.fov,this.initOrientation=g.degreesToRadians(window.orientation)||0,this.startPov=new I([0,0,1],[0,0,0],[0,1,0]),this.startSize={width:0,height:0},this.previousPoint=new E(0,0)}destroy(){this.inertia.destroy()}get orientedPov(){const t=h.v3.normalize(h.v3.cross(this.pov.up,this.pov.target)),e=new D(t,[0,1,0],this.pov.eye),i=h.m4.identity();h.m4.multiply(i,e.localToGlobalMatrix,i),h.m4.multiply(i,this.orientationMatrix,i),h.m4.multiply(i,e.globalToLocalMatrix,i);const s=h.m4.transformDirection(i,this.pov.target),r=this.pov.eye,n=h.m4.transformDirection(i,this.pov.up);return new I(s,r,n)}reset(){this.pov=this.initPov.clone(),this.fov=this.initFov}start(t,e){this.isStarted=!0,this.startPov=this.pov,this.startSize=e,this.previousPoint=t,this.inertia.stop()}motion(t){this.isStarted&&this.inertia.track(t);const e={x:t.x-this.previousPoint.x,y:t.y-this.previousPoint.y},i=g.accelerate(e.x,1.3)/this.startSize.width*.2*Math.PI*1.5,s=g.accelerate(e.y,1.3)/this.startSize.height*.2*Math.PI,r=h.m4.multiply(h.m4.rotationY(i),h.m4.rotationX(-s)),n=h.v3.normalize(h.v3.cross(this.pov.up,this.pov.target)),a=new D(n,[0,1,0],this.pov.eye),o=h.m4.identity();h.m4.multiply(o,a.localToGlobalMatrix,o),h.m4.multiply(o,r,o),h.m4.multiply(o,a.globalToLocalMatrix,o);const d=h.m4.transformPoint(o,this.pov.target),u=h.m4.transformDirection(o,this.pov.up);h.v3.cross(u,[0,0,1])[0]>=0&&(this.pov.target=d,this.pov.up=u),this.previousPoint=t,this.onMotion()}end(t,e){this.isStarted=!1,e&&(this.inertia.track(t),this.inertia.start())}orientation(t,e,i){const s=g.degreesToRadians(window.orientation)||0,r=g.degreesToRadians(t),n=g.degreesToRadians(-e),a=g.degreesToRadians(-i),o=h.m4.rotationX(g.degreesToRadians(90));h.m4.rotateZ(o,this.initOrientation,o),h.m4.rotateZ(o,r,o),h.m4.rotateX(o,n,o),h.m4.rotateY(o,a,o),h.m4.rotateZ(o,-s,o),this.orientationMatrix=o,this.onMotion()}}var _=`precision mediump float;
3
3
 
4
4
  uniform float u_mix;
5
5
  uniform samplerCube u_texture;
@@ -11,7 +11,7 @@ void main() {
11
11
  vec4 backColor = textureCube(u_texture_back, direction);
12
12
  vec4 color = textureCube(u_texture, direction);
13
13
  gl_FragColor = mix(backColor, color, u_mix);
14
- }`,tt=`attribute vec4 position;
14
+ }`,K=`attribute vec4 position;
15
15
 
16
16
  uniform mat4 u_mvpi;
17
17
 
@@ -20,6 +20,6 @@ varying vec3 direction;
20
20
  void main() {
21
21
  direction = (u_mvpi * position).xyz;
22
22
  gl_Position = position;
23
- }`;class G{constructor(t,e,i,s){this.container=t,this.canvas=e,this.loader=i,this.images=[],this.hotspotsList=[[]];const r=new I([0,0,1],[0,0,0],[0,1,0]),n=60,a=h.m4.rotationX(g.degreesToRadians(15));h.m4.transformDirection(a,r.target,r.target),h.m4.transformDirection(a,r.up,r.up),this.interaction=new _(r,n,()=>{this.animationFrameId=requestAnimationFrame(this.render),this.onInteraction({pov:this.interaction.pov.clone(),fov:this.interaction.fov})}),this.onInteraction=s,this.gl=this.canvas.context,this.programInfo=x.createProgramInfo(this.gl,[`${tt}
24
- `,`${K}
25
- `]),this.quad=x.primitives.createXYQuadBufferInfo(this.gl),this.uniforms={u_mvpi:h.m4.identity(),u_mix:0,u_texture_back:x.createTexture(this.gl,{target:this.gl.TEXTURE_CUBE_MAP,minMag:this.gl.LINEAR,width:1,height:1}),u_texture:x.createTexture(this.gl,{target:this.gl.TEXTURE_CUBE_MAP,minMag:this.gl.LINEAR,width:1,height:1})},this.render=this.render.bind(this)}destroy(){this.interaction.destroy(),this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0)}show(){this.canvas.show(),this.container.classList.add("ls-viewer-container-vrcube")}hide(){this.canvas.hide(),this.container.classList.remove("ls-viewer-container-vrcube")}get pov(){return this.interaction.pov}set pov(t){this.interaction.pov.eye.every((e,i)=>e===t.eye[i])&&this.interaction.pov.target.every((e,i)=>e===t.target[i])&&this.interaction.pov.up.every((e,i)=>e===t.up[i])||(this.interaction.pov=t.clone(),this.animationFrameId=requestAnimationFrame(this.render))}get fov(){return g.radiansToDegrees(this.interaction.fov)}set fov(t){this.interaction.fov!==t&&(this.interaction.fov=g.degreesToRadians(t),this.animationFrameId=requestAnimationFrame(this.render))}async load(t,e,i,s){let r=Promise.resolve();{const o=this.gl.getExtension("WEBGL_debug_renderer_info");o&&navigator.platform==="MacIntel"&&navigator.userAgent.includes("Chrome")&&this.gl.getParameter(o.UNMASKED_RENDERER_WEBGL).includes("OpenGL")&&(t.parameters.width=Math.min(t.parameters.width,1812),t.parameters.height=Math.min(t.parameters.height,1812))}const n=JSON.stringify(t);n===this.snapshotHash?r=r.then(()=>(this.animationFrameId=requestAnimationFrame(this.render),Promise.resolve())):(this.images=[],this.animationFrameId=requestAnimationFrame(this.render),r=r.then(()=>this.loader.loadVRCubeSnapshot(t).then(o=>{this.images=o,x.createTexture(this.gl,{target:this.gl.TEXTURE_CUBE_MAP,min:this.gl.LINEAR_MIPMAP_LINEAR,minMag:this.gl.LINEAR,cubeFaceOrder:[this.gl.TEXTURE_CUBE_MAP_POSITIVE_Z,this.gl.TEXTURE_CUBE_MAP_POSITIVE_X,this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Z,this.gl.TEXTURE_CUBE_MAP_NEGATIVE_X,this.gl.TEXTURE_CUBE_MAP_POSITIVE_Y,this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Y],src:o},(d,u)=>{d||(i&&this.interaction.reset(),this.uniforms.u_mix=s?0:1,this.uniforms.u_texture_back=this.uniforms.u_texture,this.uniforms.u_texture=u,this.animationFrameId=requestAnimationFrame(this.render))})})));const a=JSON.stringify(e);return(n!==this.snapshotHash||a!==this.hotspotsHash)&&(e.length?r=r.then(()=>this.loader.loadVRCubeHotspots(t,e).then(o=>{this.hotspotsList=o})):this.hotspotsList=[[]]),this.hotspotsHash=a,this.snapshotHash=n,r}async pick(t,e){const i=this.canvas.element.clientWidth,s=this.canvas.element.clientHeight,r=e.x,n=s-e.y,a=2*r/i-1,o=2*n/s-1,d=[a,o,0],u=this.modelViewProjectionMatrix,p=h.m4.inverse(u),c=h.v3.normalize(h.m4.transformPoint(p,d)),O=Math.max(Math.abs(c[0]),Math.abs(c[1]),Math.abs(c[2]));let L="";Math.abs(c[0])===O?L=c[0]>0?"XPOS":"XNEG":Math.abs(c[1])===O?L=c[1]>0?"YPOS":"YNEG":L=c[2]>0?"ZPOS":"ZNEG";let P=0,b=0,M="";switch(L){case"XPOS":P=(-c[2]/Math.abs(c[0])+1)/2,b=(-c[1]/Math.abs(c[0])+1)/2,M="right";break;case"XNEG":P=(c[2]/Math.abs(c[0])+1)/2,b=(-c[1]/Math.abs(c[0])+1)/2,M="left";break;case"YPOS":P=(c[0]/Math.abs(c[1])+1)/2,b=(c[2]/Math.abs(c[1])+1)/2,M="up";break;case"YNEG":P=(c[0]/Math.abs(c[1])+1)/2,b=(-c[2]/Math.abs(c[1])+1)/2,M="down";break;case"ZPOS":P=(c[0]/Math.abs(c[2])+1)/2,b=(-c[1]/Math.abs(c[2])+1)/2,M="front";break;case"ZNEG":P=(-c[0]/Math.abs(c[2])+1)/2,b=(-c[1]/Math.abs(c[2])+1)/2,M="back";break}const T={x:Math.round(P*Math.max(t.parameters.width,t.parameters.height)),y:Math.round(b*Math.max(t.parameters.width,t.parameters.height))};return this.loader.loadVRCubePick(t,T,M)}hotspots(){var s;const t=[];if(this.hotspotsList.length===0)return[];const e=((s=this.hotspotsList[0])==null?void 0:s.length)??0,i=this.modelViewProjectionMatrix;for(let r=0;r<e;r++){const n=this.hotspotsList.findIndex(U=>U[r].visibility!=="OutOfFrustum");if(n===-1)continue;const a={...this.hotspotsList[n][r]},o=a.position2D.x/this.images[0].width,d=a.position2D.y/this.images[0].height;let u=0,p=0,c=0;switch(n){case 0:this.pov.target[2]<0&&(a.visibility="OutOfFrustum"),u=2*o-1,p=1-2*d,c=1;break;case 1:this.pov.target[0]>0&&(a.visibility="OutOfFrustum"),u=1,p=1-2*d,c=1-2*o;break;case 2:this.pov.target[2]>0&&(a.visibility="OutOfFrustum"),u=1-2*o,p=1-2*d,c=-1;break;case 3:this.pov.target[0]<0&&(a.visibility="OutOfFrustum"),u=-1,p=1-2*d,c=2*o-1;break;case 4:this.pov.target[1]<0&&(a.visibility="OutOfFrustum"),u=2*o-1,p=1,c=2*d-1;break;case 5:this.pov.target[1]>0&&(a.visibility="OutOfFrustum"),u=2*o-1,p=-1,c=1-2*d;break}const O=h.v3.normalize([u,p,c]),L=h.m4.transformPoint(i,O),P=this.canvas.element.clientWidth,b=this.canvas.element.clientHeight,M=.5*P*(L[0]+1),T=.5*b*(L[1]+1),D={x:Math.round(M),y:Math.round(b-T)},z=new y(P,b),$=w.contains(z,D)?a.visibility:"OutOfFrustum";t.push({...a,position2D:D,visibility:$})}return t}snapshot(t,e){return this.canvas.element.toDataURL(t,e)}get modelViewProjectionMatrix(){const t=this.canvas.element.clientWidth,e=this.canvas.element.clientHeight,i=t>e?t/e:e/t,s=w.getStandardAspectRatio(t,e),r=this.interaction.fov*(s/i),n=h.m4.setAxis(h.m4.identity(),[-1,0,0],0),a=t>e?g.perspectiveWithFovY(r,t/e,.5,100):g.perspectiveWithFovX(r,t/e,.5,100),o=this.interaction.orientedPov,d=h.m4.inverse(h.m4.lookAt(o.eye,o.target,o.up));return h.m4.multiply(h.m4.multiply(a,d),n)}render(){this.gl.viewport(0,0,this.gl.canvas.width,this.gl.canvas.height),this.uniforms.u_mvpi=h.m4.inverse(this.modelViewProjectionMatrix),this.gl.useProgram(this.programInfo.program),x.setBuffersAndAttributes(this.gl,this.programInfo,this.quad),x.setUniforms(this.programInfo,this.uniforms),x.drawBufferInfo(this.gl,this.quad),this.uniforms.u_mix<1&&(this.uniforms.u_mix=Math.min(this.uniforms.u_mix+.05,1),this.animationFrameId=requestAnimationFrame(this.render))}onMouseDown(t){this.container.classList.add("ls-viewer-container-vrcube-grabbing"),this.interaction.start(f.pointFromMouseEvent(t),{width:this.gl.canvas.width,height:this.gl.canvas.height})}onMouseMove(t){this.interaction.isStarted&&(this.interaction.motion(f.pointFromMouseEvent(t)),t.preventDefault())}onMouseUp(t){this.interaction.isStarted&&(this.container.classList.remove("ls-viewer-container-vrcube-grabbing"),this.interaction.end(f.pointFromMouseEvent(t),!0))}onMouseEnter(t){this.interaction.isStarted&&t.buttons===0&&(this.container.classList.remove("ls-viewer-container-vrcube-grabbing"),this.interaction.end(f.pointFromMouseEvent(t),!1))}onTouchStart(t){this.container.classList.add("ls-viewer-container-vrcube-grabbing"),this.interaction.start(f.pointFromTouchEvent(t),{width:this.gl.canvas.width,height:this.gl.canvas.height})}onTouchMove(t){this.interaction.isStarted&&(this.interaction.motion(f.pointFromTouchEvent(t)),t.preventDefault())}onTouchEnd(t){this.interaction.isStarted&&(this.container.classList.remove("ls-viewer-container-vrcube-grabbing"),this.interaction.end(f.pointFromTouchEvent(t),!0))}onDeviceOrientation(t){this.interaction.orientation(t.alpha,t.beta,t.gamma)}}class et{constructor(t,e,i,s,r){this.isStarted=!1,this.position=t,this.frames=e,this.rows=i,this.loop=s,this.onMotion=r,this.inertia=new H(this.motion.bind(this)),this.initPosition={...this.position},this.startPosition={x:0,y:0},this.startPoint=new E(0,0),this.startSize={width:0,height:0},this.lastPoints=[],this.lastPointsNumber=20}destroy(){this.inertia.destroy()}reset(){this.position={...this.initPosition}}get positionIndex(){return this.frames*this.position.y+this.position.x}set positionIndex(t){if(this.positionIndex===t)return;const e=this.loop?g.mod(t,this.frames*this.rows):Math.max(0,Math.min(t,this.frames*this.rows));this.position.x=g.mod(e,this.frames),this.position.y=Math.floor(e/this.frames)}start(t,e){this.isStarted=!0,this.startPosition={...this.position},this.startPoint=t,this.startSize=e,this.lastPoints=[],this.inertia.stop()}motion(t){this.isStarted&&this.inertia.track(t),this.lastPoints.push({x:t.x,y:t.y}),this.lastPoints.splice(0,this.lastPoints.length-this.lastPointsNumber);const e=N.linear(this.lastPoints.map(s=>[s.x,s.y])),i=25;if(Math.abs(e.equation[0])<1){const s=g.accelerate(t.x-this.startPoint.x,1.3)/this.startSize.width*(this.frames/4);let r=this.startPosition.x-Math.round(s);r=this.loop?g.mod(r,this.frames):Math.max(0,Math.min(r,this.frames-1)),r!==this.position.x&&(this.position.x=r,this.onMotion());const n=Math.min(...this.lastPoints.map(o=>o.x));Math.max(...this.lastPoints.map(o=>o.x))-n>i&&(this.startPoint.y=t.y,this.startPosition.y=this.position.y)}else{const s=g.accelerate(t.y-this.startPoint.y,1.7)/this.startSize.height*(this.rows/4);let r=this.startPosition.y+Math.round(s);r=Math.max(0,Math.min(r,this.rows-1)),r!==this.position.y&&(this.position.y=r,this.onMotion());const n=Math.min(...this.lastPoints.map(o=>o.y));Math.max(...this.lastPoints.map(o=>o.y))-n>i&&(this.startPoint.x=t.x,this.startPosition.x=this.position.x)}}end(t,e){this.isStarted=!1,e&&(this.inertia.track(t),this.inertia.start())}}class A{constructor(t,e,i,s){this.container=t,this.canvas=e,this.loader=i,this.images=[],this.frames=24,this.hotspotsList=[[]],this.interaction=new et({x:0,y:0},1,1,!1,()=>{this.canvas.draw(this.image,!0,.5),this.onInteraction({position:this.interaction.positionIndex})}),this.onInteraction=s}destroy(){this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0)}show(){this.canvas.show(!1),this.container.classList.add("ls-viewer-container-vrobject")}hide(){this.canvas.hide(!1),this.container.classList.remove("ls-viewer-container-vrobject")}async goto(t){return new Promise(e=>{let i=this.interaction.positionIndex;const s=()=>{if(this.interaction.positionIndex===t)e();else{let r=i>t?-1:1;this.interaction.loop&&this.interaction.frames-i+t<Math.abs(t-i)&&(r*=-1),i+=.5*r,this.position=Math.floor(i),this.animationFrameId=requestAnimationFrame(s)}};this.animationFrameId=requestAnimationFrame(s)})}get position(){return this.interaction.positionIndex}set position(t){this.interaction.positionIndex=t,this.canvas.draw(this.image,!0,.5)}get image(){return this.images[this.interaction.positionIndex]}async load(t,e,i,s){let r=Promise.resolve();i&&this.interaction.reset();const n=JSON.stringify(t);n===this.snapshotHash&&this.image?r=r.then(()=>this.canvas.draw(this.image,s,.05)):(this.images=[],r=r.then(()=>this.loader.loadVRObjectSnapshot(t,this.interaction.positionIndex).then(o=>{const d=o.length;return this.images=new Array(d),this.interaction.frames=t.view.frames??t.view.panFrames??this.frames,this.interaction.rows=d/this.interaction.frames,this.interaction.loop=!!t.view.loop,i&&this.interaction.reset(),o.forEach((u,p)=>{u.then(c=>{this.images[p]=c,c===this.image&&this.canvas.draw(this.image,s,.05)}).catch(()=>{})}),o[this.interaction.positionIndex].then(()=>Promise.resolve())})));const a=JSON.stringify(e);return(n!==this.snapshotHash||a!==this.hotspotsHash)&&(e.length?r=r.then(()=>this.loader.loadVRObjectHotspots(t,e).then(o=>{this.hotspotsList=o})):this.hotspotsList=[[]]),this.hotspotsHash=a,this.snapshotHash=n,r}async pick(t,e){const i=new y(t.parameters.width,t.parameters.height),s=w.unproject(i,this.canvas.resolution,this.canvas.fit,e);return this.loader.loadVRObjectPick(t,s,this.position,this.frames)}hotspots(t){return(this.hotspotsList[this.interaction.positionIndex]||[]).map(i=>({...i,position2D:w.project(t,this.canvas.resolution,this.canvas.fit,i.position2D)})).map(i=>({...i,visibility:w.contains(this.canvas.resolution,i.position2D)?i.visibility:"OutOfFrustum"}))}snapshot(t,e){return this.canvas.element.toDataURL(t,e)}onMouseDown(t){this.container.classList.add("ls-viewer-container-vrobject-grabbing"),this.interaction.start(f.pointFromMouseEvent(t),{width:this.canvas.element.width,height:this.canvas.element.height})}onMouseMove(t){this.interaction.isStarted&&(this.interaction.motion(f.pointFromMouseEvent(t)),t.preventDefault())}onMouseUp(t){this.interaction.isStarted&&(this.container.classList.remove("ls-viewer-container-vrobject-grabbing"),this.interaction.end(f.pointFromMouseEvent(t),!0))}onMouseEnter(t){this.interaction.isStarted&&t.buttons===0&&(this.container.classList.remove("ls-viewer-container-vrobject-grabbing"),this.interaction.end(f.pointFromMouseEvent(t),!1))}onTouchStart(t){this.container.classList.add("ls-viewer-container-vrobject-grabbing"),this.interaction.start(f.pointFromTouchEvent(t),{width:this.canvas.element.width,height:this.canvas.element.height})}onTouchMove(t){this.interaction.isStarted&&(this.interaction.motion(f.pointFromTouchEvent(t)),t.preventDefault())}onTouchEnd(t){this.interaction.isStarted&&(this.container.classList.remove("ls-viewer-container-vrobject-grabbing"),this.interaction.end(f.pointFromTouchEvent(t),!0))}onDeviceOrientation(t){}}class R{constructor(t,e,i){this.container=t,this.loader=i,this.video=e}destroy(){}show(){this.video.show(),this.container.classList.add("ls-viewer-container-video")}hide(){this.video.hide(),this.container.classList.remove("ls-viewer-container-video")}async load(t){const e=JSON.stringify(t);return e===this.hash?(this.video.element.load(),Promise.resolve()):(this.hash=e,this.loader.loadVideoSnapshot(this.video.element,t))}async pick(t,e){return Promise.reject()}hotspots(t){return[]}snapshot(t,e){return"data:image/gif;base64,R0lGODlhAQABAIAAAP7//wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="}async play(){return new Promise((t,e)=>{this.video.element.addEventListener("ended",()=>{t()},{once:!0}),this.video.element.play().catch(e),this.show()})}onMouseDown(t){}onMouseMove(t){}onMouseUp(t){}onMouseEnter(t){}onTouchStart(t){}onTouchMove(t){}onTouchEnd(t){}onDeviceOrientation(t){}}class it{constructor(t,e){this.checkResize=this.checkResize.bind(this),this.onDeviceOrientation=this.onDeviceOrientation.bind(this),this.onResize=this.onResize.bind(this),this.onMouseDown=this.onMouseDown.bind(this),this.onMouseMove=this.onMouseMove.bind(this),this.onMouseUp=this.onMouseUp.bind(this),this.onMouseEnter=this.onMouseEnter.bind(this),this.onTouchStart=this.onTouchStart.bind(this),this.onTouchMove=this.onTouchMove.bind(this),this.onTouchEnd=this.onTouchEnd.bind(this),this.onLoadStart=this.onLoadStart.bind(this),this.onLoadProgress=this.onLoadProgress.bind(this),this.onLoadEnd=this.onLoadEnd.bind(this),this.onLoadError=this.onLoadError.bind(this),this.onHotspotsChange=this.onHotspotsChange.bind(this),this.onVrcubeInteraction=this.onVrcubeInteraction.bind(this),this.onVrobjectInteraction=this.onVrobjectInteraction.bind(this),this.options={server:"localhost",api:"v1",autores:!0,fit:"cover",image:{},video:{},vrcube:{},vrobject:{},events:{},...e},this.options.events={onLoadStart:()=>{},onLoadProgress:()=>{},onLoadEnd:()=>{},onLoadError:()=>{},onInteraction:()=>{},onVrcubeInteraction:()=>{},onVrobjectInteraction:()=>{},onHotspotsChange:()=>{},...e.events},this.options.events.onLoadError=C(this.options.events.onLoadError,10),this.container=t,this.container.classList.add("ls-viewer-container"),this.containerWidth=0,this.containerHeight=0,this.canvas2D=new X(this.options.fit),this.container.prepend(this.canvas2D.element),this.canvas3D=new Y,this.container.prepend(this.canvas3D.element),this.video=new Z,this.container.prepend(this.video.element),this.loader=new k(this.options.server,this.options.api,this),this.resolution=new y(0,0),this.parameters={width:0,height:0,antialiasing:!1,superSampling:2},this.encoder={format:"jpeg",quality:80},this.hotspots=[],this.widgetImage=new q(t,this.canvas2D,this.loader),this.widgetVideo=new R(t,this.video,this.loader),this.widgetVRObject=new A(t,this.canvas2D,this.loader,this.onVrobjectInteraction),this.canvas3D.context&&(this.widgetVRCube=new G(t,this.canvas3D,this.loader,this.onVrcubeInteraction)),this.widget=this.widgetImage,this.isDestroyed=!1,this.container.addEventListener("mousedown",this.onMouseDown),this.container.addEventListener("mouseenter",this.onMouseEnter),this.container.addEventListener("touchstart",this.onTouchStart),document.addEventListener("mousemove",this.onMouseMove,{passive:!1}),document.addEventListener("mouseup",this.onMouseUp),document.addEventListener("touchmove",this.onTouchMove,{passive:!1}),document.addEventListener("touchend",this.onTouchEnd),this.loadWidget=C(this.loadWidget,10),this.onResize=C(this.onResize,250),requestAnimationFrame(this.checkResize)}destroy(){this.canvas2D.destroy(),this.container.removeEventListener("mousedown",this.onMouseDown),this.container.removeEventListener("mouseenter",this.onMouseEnter),this.container.removeEventListener("touchstart",this.onTouchStart),document.removeEventListener("mousemove",this.onMouseMove),document.removeEventListener("mouseup",this.onMouseUp),document.removeEventListener("touchmove",this.onTouchMove),document.removeEventListener("touchend",this.onTouchEnd),this.isDestroyed=!0}async load(t,e){let i=Promise.resolve();return e!=null&&e.animation&&(i=i.then(()=>this.loadAnimation(e.animation))),this.view&&(e==null?void 0:e.fromPosition)!==void 0&&this.viewWidget instanceof A&&(this.view.mode,i=i.then(()=>this.viewWidget.goto(e.fromPosition))),e!=null&&e.animation&&(i=i.then(()=>this.widgetVideo.play())),i=i.then(()=>(this.scene=Array.isArray(t)?[...t]:[t],this.loadWidget(!1,!(e&&e.animation)))),i.catch(s=>{this.onLoadError(s)}),i}async setEncoder(t){this.encoder={...t};let e=Promise.resolve();return e=e.then(()=>this.loadWidget(!1,!0)),e.catch(i=>{this.onLoadError(i)}),e}setParameters(t){t.width&&t.height&&(this.resolution=new y(t.width,t.height)),this.parameters={...t},this.parameters.width=this.resolution.width,this.parameters.height=this.resolution.height;let e=Promise.resolve();return e=e.then(()=>this.loadWidget(!1,!0)),e.catch(i=>{this.onLoadError(i)}),e}setHotspots(t){this.hotspots=t,this.loadWidget(!1,!1)}async setView(t,e){let i=Promise.resolve();return e!=null&&e.animation&&(i=i.then(()=>this.loadAnimation(e.animation))),this.view&&(e==null?void 0:e.fromPosition)!==void 0&&this.viewWidget instanceof A&&(i=i.then(()=>this.viewWidget.goto(e.fromPosition))),e!=null&&e.animation&&(i=i.then(()=>this.widgetVideo.play())),i=i.then(()=>{let s=!0;return this.view={...t},this.view&&this.viewWidget instanceof A&&(e==null?void 0:e.toPosition)!==void 0&&(s=!1,this.viewWidget.position=e.toPosition),this.loadWidget(s,!(e&&e.animation))}),i.catch(s=>{this.onLoadError(s)}),i}setVrcube(t){this.widgetVRCube&&Object.assign(this.widgetVRCube,t)}setVrobject(t){Object.assign(this.widgetVRObject,t)}async loadAnimation(t){var i;const e={scene:this.scene,view:{animation:t.name,camera:t.camera,duration:t.duration,loop:t.loop,reverse:t.reverse},parameters:this.parameters,encoder:{format:"mp4"}};return(i=e.view)!=null&&i.background||(e.view.background="product"),this.widgetVideo.load(e).then(()=>Promise.resolve())}async playAnimation(t){return this.loadAnimation(t).then(()=>this.widgetVideo.play()).catch(e=>{this.onLoadError(e)})}stopAnimation(){this.widgetVideo.hide()}async pick(t){if(!this.scene)throw new Error("No scene set");if(!this.view)throw new Error("No view set");if(!this.view.camera&&!this.view.cameraGroup)throw new Error("No camera set");const e={scene:this.scene,view:this.view,parameters:this.parameters,encoder:this.encoder};return await this.viewWidget.pick(e,t)}async pickHotspot(t){const e=await this.pick(t),i=Object.values(e.point),s=h.v3.normalize(Object.values(e.normal)),r=h.v3.add(i,h.v3.mulScalar(s,.01));return e.point={x:r[0],y:r[1],z:r[2]},e}snapshot(t,e){return this.viewWidget.snapshot(t,e)}async loadWidget(t,e){if(!this.scene||!this.view||!this.parameters.width||!this.parameters.height)return Promise.resolve();const i=this.viewWidget;if(!i)return Promise.reject(new Error("Unknown view mode"));const s={scene:this.scene,view:this.view,parameters:this.parameters,encoder:this.encoder};return s.view.background||(s.view.background="product"),i.load(s,this.hotspots,t,e).then(()=>{this.widget.hide(),this.widget=i,this.widget.show(),this.widgetVideo.hide(),this.onHotspotsChange()})}get viewWidget(){var t;switch((t=this.view)==null?void 0:t.mode){case"image":return this.widgetImage;case"video":return this.widgetVideo;case"vrcube":return this.widgetVRCube??this.widgetImage;case"vrobject":return this.widgetVRObject;default:return this.widgetImage}}checkResize(){if(this.isDestroyed)return;const t=this.container.clientWidth,e=this.container.clientHeight;(t!==this.containerWidth||e!==this.containerHeight)&&(this.containerWidth=t,this.containerHeight=e,this.onResize()),this.isDestroyed||requestAnimationFrame(this.checkResize)}onMouseDown(t){this.widget.onMouseDown(t)}onMouseEnter(t){this.widget.onMouseEnter(t)}onMouseMove(t){this.widget.onMouseMove(t)}onMouseUp(t){this.widget.onMouseUp(t)}onTouchStart(t){this.widget.onTouchStart(t)}onTouchMove(t){this.widget.onTouchMove(t)}onTouchEnd(t){this.widget.onTouchEnd(t)}onDeviceOrientation(t){this.widget.onDeviceOrientation(t)}onResize(){const t=this.container.clientWidth,e=this.container.clientHeight;this.options.autores&&(this.resolution=w.getStandardResolution(t*window.devicePixelRatio,e*window.devicePixelRatio),this.parameters.width=this.resolution.width,this.parameters.height=this.resolution.height),this.canvas2D.resize(t,e,window.devicePixelRatio),this.canvas3D.resize(t,e,window.devicePixelRatio),this.video.resize(t,e,this.resolution,this.options.fit),this.loadWidget(!1,!1).then(()=>{this.onHotspotsChange()}).catch(i=>{this.onLoadError(i)})}onVrcubeInteraction(...t){this.onHotspotsChange(),this.options.events.onInteraction(...t),this.options.events.onVrcubeInteraction(...t)}onVrobjectInteraction(t){this.onHotspotsChange(),this.options.events.onInteraction(t.position),this.options.events.onVrobjectInteraction(t.position)}onHotspotsChange(){const t=this.widget.hotspots(this.resolution);t.length&&this.options.events.onHotspotsChange(t)}onLoadStart(...t){this.container.classList.add("ls-viewer-container-loading"),this.options.events.onLoadStart(...t)}onLoadProgress(...t){this.options.events.onLoadProgress(...t)}onLoadEnd(...t){this.container.classList.remove("ls-viewer-container-loading"),this.options.events.onLoadEnd(...t)}onLoadError(...t){this.container.classList.remove("ls-viewer-container-loading"),this.options.events.onLoadError(...t)}}exports.WRAPIv2=void 0;(l=>{(t=>{t.Visible="Visible",t.Occluded="Occluded",t.Clipped="Clipped",t.OutOfFrustum="OutOfFrustum"})(l.HotspotVisibility||(l.HotspotVisibility={})),(t=>{t.VeryLow="veryLow",t.Low="low",t.Medium="medium",t.Fine="fine",t.Ultra="ultra"})(l.SunShadowQualityMode||(l.SunShadowQualityMode={})),(t=>{t.None="none",t.Weak="weak",t.Normal="normal",t.Fine="fine",t.UltraFine="ultraFine",t.Max="max"})(l.SunShadowSmoothnessMode||(l.SunShadowSmoothnessMode={})),(t=>{t.Manual="manual",t.ExtractedFromEnv="extractedFromEnv"})(l.SunUseCaseMode||(l.SunUseCaseMode={})),(t=>{t.ShowOnly="showOnly",t.HideOnly="hideOnly"})(l.SurfacesFilterMode||(l.SurfacesFilterMode={}))})(exports.WRAPIv2||(exports.WRAPIv2={}));exports.Viewer=it;exports.WidgetImage=q;exports.WidgetVRCube=G;exports.WidgetVRObject=A;exports.WidgetVideo=R;
23
+ }`;class H{constructor(t,e,i,s){this.container=t,this.canvas=e,this.loader=i,this.images=[],this.hotspotsList=[[]];const r=new I([0,0,1],[0,0,0],[0,1,0]),n=60,a=h.m4.rotationX(g.degreesToRadians(15));h.m4.transformDirection(a,r.target,r.target),h.m4.transformDirection(a,r.up,r.up),this.interaction=new Q(r,n,()=>{this.animationFrameId=requestAnimationFrame(this.render),this.onInteraction({pov:this.interaction.pov.clone(),fov:this.interaction.fov})}),this.onInteraction=s,this.gl=this.canvas.context,this.programInfo=P.createProgramInfo(this.gl,[`${K}
24
+ `,`${_}
25
+ `]),this.quad=P.primitives.createXYQuadBufferInfo(this.gl),this.uniforms={u_mvpi:h.m4.identity(),u_mix:0,u_texture_back:P.createTexture(this.gl,{target:this.gl.TEXTURE_CUBE_MAP,minMag:this.gl.LINEAR,width:1,height:1}),u_texture:P.createTexture(this.gl,{target:this.gl.TEXTURE_CUBE_MAP,minMag:this.gl.LINEAR,width:1,height:1})},this.render=this.render.bind(this)}destroy(){this.interaction.destroy(),this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0)}show(){this.canvas.show(),this.container.classList.add("ls-viewer-container-vrcube")}hide(){this.canvas.hide(),this.container.classList.remove("ls-viewer-container-vrcube")}get pov(){return this.interaction.pov}set pov(t){this.interaction.pov.eye.every((e,i)=>e===t.eye[i])&&this.interaction.pov.target.every((e,i)=>e===t.target[i])&&this.interaction.pov.up.every((e,i)=>e===t.up[i])||(this.interaction.pov=t.clone(),this.animationFrameId=requestAnimationFrame(this.render))}get fov(){return g.radiansToDegrees(this.interaction.fov)}set fov(t){this.interaction.fov!==t&&(this.interaction.fov=g.degreesToRadians(t),this.animationFrameId=requestAnimationFrame(this.render))}async load(t,e,i,s){let r=Promise.resolve();{const o=this.gl.getExtension("WEBGL_debug_renderer_info");o&&navigator.platform==="MacIntel"&&navigator.userAgent.includes("Chrome")&&this.gl.getParameter(o.UNMASKED_RENDERER_WEBGL).includes("OpenGL")&&(t.parameters.width=Math.min(t.parameters.width,1812),t.parameters.height=Math.min(t.parameters.height,1812))}const n=JSON.stringify(t);n===this.snapshotHash?r=r.then(()=>(this.animationFrameId=requestAnimationFrame(this.render),Promise.resolve())):(this.images=[],this.animationFrameId=requestAnimationFrame(this.render),r=r.then(()=>this.loader.loadVRCubeSnapshot(t).then(o=>{this.images=o,P.createTexture(this.gl,{target:this.gl.TEXTURE_CUBE_MAP,min:this.gl.LINEAR_MIPMAP_LINEAR,minMag:this.gl.LINEAR,cubeFaceOrder:[this.gl.TEXTURE_CUBE_MAP_POSITIVE_Z,this.gl.TEXTURE_CUBE_MAP_POSITIVE_X,this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Z,this.gl.TEXTURE_CUBE_MAP_NEGATIVE_X,this.gl.TEXTURE_CUBE_MAP_POSITIVE_Y,this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Y],src:o},(d,u)=>{d||(i&&this.interaction.reset(),this.uniforms.u_mix=s?0:1,this.uniforms.u_texture_back=this.uniforms.u_texture,this.uniforms.u_texture=u,this.animationFrameId=requestAnimationFrame(this.render))})})));const a=JSON.stringify(e);return(n!==this.snapshotHash||a!==this.hotspotsHash)&&(e.length?r=r.then(()=>this.loader.loadVRCubeHotspots(t,e).then(o=>{this.hotspotsList=o})):this.hotspotsList=[[]]),this.hotspotsHash=a,this.snapshotHash=n,r}async pick(t,e){const i=this.canvas.element.clientWidth,s=this.canvas.element.clientHeight,r=e.x,n=s-e.y,a=2*r/i-1,o=2*n/s-1,d=[a,o,0],u=this.modelViewProjectionMatrix,p=h.m4.inverse(u),c=h.v3.normalize(h.m4.transformPoint(p,d)),A=Math.max(Math.abs(c[0]),Math.abs(c[1]),Math.abs(c[2]));let L="";Math.abs(c[0])===A?L=c[0]>0?"XPOS":"XNEG":Math.abs(c[1])===A?L=c[1]>0?"YPOS":"YNEG":L=c[2]>0?"ZPOS":"ZNEG";let b=0,x=0,M="";switch(L){case"XPOS":b=(-c[2]/Math.abs(c[0])+1)/2,x=(-c[1]/Math.abs(c[0])+1)/2,M="right";break;case"XNEG":b=(c[2]/Math.abs(c[0])+1)/2,x=(-c[1]/Math.abs(c[0])+1)/2,M="left";break;case"YPOS":b=(c[0]/Math.abs(c[1])+1)/2,x=(c[2]/Math.abs(c[1])+1)/2,M="up";break;case"YNEG":b=(c[0]/Math.abs(c[1])+1)/2,x=(-c[2]/Math.abs(c[1])+1)/2,M="down";break;case"ZPOS":b=(c[0]/Math.abs(c[2])+1)/2,x=(-c[1]/Math.abs(c[2])+1)/2,M="front";break;case"ZNEG":b=(-c[0]/Math.abs(c[2])+1)/2,x=(-c[1]/Math.abs(c[2])+1)/2,M="back";break}const T={x:Math.round(b*Math.max(t.parameters.width,t.parameters.height)),y:Math.round(x*Math.max(t.parameters.width,t.parameters.height))};return this.loader.loadVRCubePick(t,T,M)}hotspots(){const t=[];if(this.hotspotsList.length===0)return[];const e=this.hotspotsList[0]?.length??0,i=this.modelViewProjectionMatrix;for(let s=0;s<e;s++){const r=this.hotspotsList.findIndex($=>$[s].visibility!=="OutOfFrustum");if(r===-1)continue;const n={...this.hotspotsList[r][s]},a=n.position2D.x/this.images[0].width,o=n.position2D.y/this.images[0].height;let d=0,u=0,p=0;switch(r){case 0:this.pov.target[2]<0&&(n.visibility="OutOfFrustum"),d=2*a-1,u=1-2*o,p=1;break;case 1:this.pov.target[0]>0&&(n.visibility="OutOfFrustum"),d=1,u=1-2*o,p=1-2*a;break;case 2:this.pov.target[2]>0&&(n.visibility="OutOfFrustum"),d=1-2*a,u=1-2*o,p=-1;break;case 3:this.pov.target[0]<0&&(n.visibility="OutOfFrustum"),d=-1,u=1-2*o,p=2*a-1;break;case 4:this.pov.target[1]<0&&(n.visibility="OutOfFrustum"),d=2*a-1,u=1,p=2*o-1;break;case 5:this.pov.target[1]>0&&(n.visibility="OutOfFrustum"),d=2*a-1,u=-1,p=1-2*o;break}const c=h.v3.normalize([d,u,p]),A=h.m4.transformPoint(i,c),L=this.canvas.element.clientWidth,b=this.canvas.element.clientHeight,x=.5*L*(A[0]+1),M=.5*b*(A[1]+1),T={x:Math.round(x),y:Math.round(b-M)},R=new y(L,b),z=w.contains(R,T)?n.visibility:"OutOfFrustum";t.push({...n,position2D:T,visibility:z})}return t}snapshot(t,e){return this.canvas.element.toDataURL(t,e)}get modelViewProjectionMatrix(){const t=this.canvas.element.clientWidth,e=this.canvas.element.clientHeight,i=t>e?t/e:e/t,s=w.getStandardAspectRatio(t,e),r=this.interaction.fov*(s/i),n=h.m4.setAxis(h.m4.identity(),[-1,0,0],0),a=t>e?g.perspectiveWithFovY(r,t/e,.5,100):g.perspectiveWithFovX(r,t/e,.5,100),o=this.interaction.orientedPov,d=h.m4.inverse(h.m4.lookAt(o.eye,o.target,o.up));return h.m4.multiply(h.m4.multiply(a,d),n)}render(){this.gl.viewport(0,0,this.gl.canvas.width,this.gl.canvas.height),this.uniforms.u_mvpi=h.m4.inverse(this.modelViewProjectionMatrix),this.gl.useProgram(this.programInfo.program),P.setBuffersAndAttributes(this.gl,this.programInfo,this.quad),P.setUniforms(this.programInfo,this.uniforms),P.drawBufferInfo(this.gl,this.quad),this.uniforms.u_mix<1&&(this.uniforms.u_mix=Math.min(this.uniforms.u_mix+.05,1),this.animationFrameId=requestAnimationFrame(this.render))}onMouseDown(t){this.container.classList.add("ls-viewer-container-vrcube-grabbing"),this.interaction.start(f.pointFromMouseEvent(t),{width:this.gl.canvas.width,height:this.gl.canvas.height})}onMouseMove(t){this.interaction.isStarted&&(this.interaction.motion(f.pointFromMouseEvent(t)),t.preventDefault())}onMouseUp(t){this.interaction.isStarted&&(this.container.classList.remove("ls-viewer-container-vrcube-grabbing"),this.interaction.end(f.pointFromMouseEvent(t),!0))}onMouseEnter(t){this.interaction.isStarted&&t.buttons===0&&(this.container.classList.remove("ls-viewer-container-vrcube-grabbing"),this.interaction.end(f.pointFromMouseEvent(t),!1))}onTouchStart(t){this.container.classList.add("ls-viewer-container-vrcube-grabbing"),this.interaction.start(f.pointFromTouchEvent(t),{width:this.gl.canvas.width,height:this.gl.canvas.height})}onTouchMove(t){this.interaction.isStarted&&(this.interaction.motion(f.pointFromTouchEvent(t)),t.preventDefault())}onTouchEnd(t){this.interaction.isStarted&&(this.container.classList.remove("ls-viewer-container-vrcube-grabbing"),this.interaction.end(f.pointFromTouchEvent(t),!0))}onDeviceOrientation(t){this.interaction.orientation(t.alpha,t.beta,t.gamma)}}class tt{constructor(t,e,i,s,r){this.isStarted=!1,this.position=t,this.frames=e,this.rows=i,this.loop=s,this.onMotion=r,this.inertia=new q(this.motion.bind(this)),this.initPosition={...this.position},this.startPosition={x:0,y:0},this.startPoint=new E(0,0),this.startSize={width:0,height:0},this.lastPoints=[],this.lastPointsNumber=20}destroy(){this.inertia.destroy()}reset(){this.position={...this.initPosition}}get positionIndex(){return this.frames*this.position.y+this.position.x}set positionIndex(t){if(this.positionIndex===t)return;const e=this.loop?g.mod(t,this.frames*this.rows):Math.max(0,Math.min(t,this.frames*this.rows));this.position.x=g.mod(e,this.frames),this.position.y=Math.floor(e/this.frames)}start(t,e){this.isStarted=!0,this.startPosition={...this.position},this.startPoint=t,this.startSize=e,this.lastPoints=[],this.inertia.stop()}motion(t){this.isStarted&&this.inertia.track(t),this.lastPoints.push({x:t.x,y:t.y}),this.lastPoints.splice(0,this.lastPoints.length-this.lastPointsNumber);const e=U.linear(this.lastPoints.map(s=>[s.x,s.y])),i=25;if(Math.abs(e.equation[0])<1){const s=g.accelerate(t.x-this.startPoint.x,1.3)/this.startSize.width*(this.frames/4);let r=this.startPosition.x-Math.round(s);r=this.loop?g.mod(r,this.frames):Math.max(0,Math.min(r,this.frames-1)),r!==this.position.x&&(this.position.x=r,this.onMotion());const n=Math.min(...this.lastPoints.map(o=>o.x));Math.max(...this.lastPoints.map(o=>o.x))-n>i&&(this.startPoint.y=t.y,this.startPosition.y=this.position.y)}else{const s=g.accelerate(t.y-this.startPoint.y,1.7)/this.startSize.height*(this.rows/4);let r=this.startPosition.y+Math.round(s);r=Math.max(0,Math.min(r,this.rows-1)),r!==this.position.y&&(this.position.y=r,this.onMotion());const n=Math.min(...this.lastPoints.map(o=>o.y));Math.max(...this.lastPoints.map(o=>o.y))-n>i&&(this.startPoint.x=t.x,this.startPosition.x=this.position.x)}}end(t,e){this.isStarted=!1,e&&(this.inertia.track(t),this.inertia.start())}}class O{constructor(t,e,i,s){this.container=t,this.canvas=e,this.loader=i,this.images=[],this.frames=24,this.hotspotsList=[[]],this.interaction=new tt({x:0,y:0},1,1,!1,()=>{this.canvas.draw(this.image,!0,.5),this.onInteraction({position:this.interaction.positionIndex})}),this.onInteraction=s}destroy(){this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0)}show(){this.canvas.show(!1),this.container.classList.add("ls-viewer-container-vrobject")}hide(){this.canvas.hide(!1),this.container.classList.remove("ls-viewer-container-vrobject")}async goto(t){return new Promise(e=>{let i=this.interaction.positionIndex;const s=()=>{if(this.interaction.positionIndex===t)e();else{let r=i>t?-1:1;this.interaction.loop&&this.interaction.frames-i+t<Math.abs(t-i)&&(r*=-1),i+=.5*r,this.position=Math.floor(i),this.animationFrameId=requestAnimationFrame(s)}};this.animationFrameId=requestAnimationFrame(s)})}get position(){return this.interaction.positionIndex}set position(t){this.interaction.positionIndex=t,this.canvas.draw(this.image,!0,.5)}get image(){return this.images[this.interaction.positionIndex]}async load(t,e,i,s){let r=Promise.resolve();i&&this.interaction.reset();const n=JSON.stringify(t);n===this.snapshotHash&&this.image?r=r.then(()=>this.canvas.draw(this.image,s,.05)):(this.images=[],r=r.then(()=>this.loader.loadVRObjectSnapshot(t,this.interaction.positionIndex).then(o=>{const d=o.length;return this.images=new Array(d),this.interaction.frames=t.view.frames??t.view.panFrames??this.frames,this.interaction.rows=d/this.interaction.frames,this.interaction.loop=!!t.view.loop,i&&this.interaction.reset(),o.forEach((u,p)=>{u.then(c=>{this.images[p]=c,c===this.image&&this.canvas.draw(this.image,s,.05)}).catch(()=>{})}),o[this.interaction.positionIndex].then(()=>Promise.resolve())})));const a=JSON.stringify(e);return(n!==this.snapshotHash||a!==this.hotspotsHash)&&(e.length?r=r.then(()=>this.loader.loadVRObjectHotspots(t,e).then(o=>{this.hotspotsList=o})):this.hotspotsList=[[]]),this.hotspotsHash=a,this.snapshotHash=n,r}async pick(t,e){const i=new y(t.parameters.width,t.parameters.height),s=w.unproject(i,this.canvas.resolution,this.canvas.fit,e);return this.loader.loadVRObjectPick(t,s,this.position,this.frames)}hotspots(t){return(this.hotspotsList[this.interaction.positionIndex]||[]).map(i=>({...i,position2D:w.project(t,this.canvas.resolution,this.canvas.fit,i.position2D)})).map(i=>({...i,visibility:w.contains(this.canvas.resolution,i.position2D)?i.visibility:"OutOfFrustum"}))}snapshot(t,e){return this.canvas.element.toDataURL(t,e)}onMouseDown(t){this.container.classList.add("ls-viewer-container-vrobject-grabbing"),this.interaction.start(f.pointFromMouseEvent(t),{width:this.canvas.element.width,height:this.canvas.element.height})}onMouseMove(t){this.interaction.isStarted&&(this.interaction.motion(f.pointFromMouseEvent(t)),t.preventDefault())}onMouseUp(t){this.interaction.isStarted&&(this.container.classList.remove("ls-viewer-container-vrobject-grabbing"),this.interaction.end(f.pointFromMouseEvent(t),!0))}onMouseEnter(t){this.interaction.isStarted&&t.buttons===0&&(this.container.classList.remove("ls-viewer-container-vrobject-grabbing"),this.interaction.end(f.pointFromMouseEvent(t),!1))}onTouchStart(t){this.container.classList.add("ls-viewer-container-vrobject-grabbing"),this.interaction.start(f.pointFromTouchEvent(t),{width:this.canvas.element.width,height:this.canvas.element.height})}onTouchMove(t){this.interaction.isStarted&&(this.interaction.motion(f.pointFromTouchEvent(t)),t.preventDefault())}onTouchEnd(t){this.interaction.isStarted&&(this.container.classList.remove("ls-viewer-container-vrobject-grabbing"),this.interaction.end(f.pointFromTouchEvent(t),!0))}onDeviceOrientation(t){}}class G{constructor(t,e,i){this.container=t,this.loader=i,this.video=e}destroy(){}show(){this.video.show(),this.container.classList.add("ls-viewer-container-video")}hide(){this.video.hide(),this.container.classList.remove("ls-viewer-container-video")}async load(t){const e=JSON.stringify(t);return e===this.hash?(this.video.element.load(),Promise.resolve()):(this.hash=e,this.loader.loadVideoSnapshot(this.video.element,t))}async pick(t,e){return Promise.reject()}hotspots(t){return[]}snapshot(t,e){return"data:image/gif;base64,R0lGODlhAQABAIAAAP7//wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="}async play(){return new Promise((t,e)=>{this.video.element.addEventListener("ended",()=>{t()},{once:!0}),this.video.element.play().catch(e),this.show()})}onMouseDown(t){}onMouseMove(t){}onMouseUp(t){}onMouseEnter(t){}onTouchStart(t){}onTouchMove(t){}onTouchEnd(t){}onDeviceOrientation(t){}}class et{constructor(t,e){this.checkResize=this.checkResize.bind(this),this.onDeviceOrientation=this.onDeviceOrientation.bind(this),this.onResize=this.onResize.bind(this),this.onMouseDown=this.onMouseDown.bind(this),this.onMouseMove=this.onMouseMove.bind(this),this.onMouseUp=this.onMouseUp.bind(this),this.onMouseEnter=this.onMouseEnter.bind(this),this.onTouchStart=this.onTouchStart.bind(this),this.onTouchMove=this.onTouchMove.bind(this),this.onTouchEnd=this.onTouchEnd.bind(this),this.onLoadStart=this.onLoadStart.bind(this),this.onLoadProgress=this.onLoadProgress.bind(this),this.onLoadEnd=this.onLoadEnd.bind(this),this.onLoadError=this.onLoadError.bind(this),this.onHotspotsChange=this.onHotspotsChange.bind(this),this.onVrcubeInteraction=this.onVrcubeInteraction.bind(this),this.onVrobjectInteraction=this.onVrobjectInteraction.bind(this),this.options={server:"localhost",api:"v1",autores:!0,fit:"cover",image:{},video:{},vrcube:{},vrobject:{},events:{},...e},this.options.events={onLoadStart:()=>{},onLoadProgress:()=>{},onLoadEnd:()=>{},onLoadError:()=>{},onInteraction:()=>{},onVrcubeInteraction:()=>{},onVrobjectInteraction:()=>{},onHotspotsChange:()=>{},...e.events},this.options.events.onLoadError=C(this.options.events.onLoadError,10),this.container=t,this.container.classList.add("ls-viewer-container"),this.containerWidth=0,this.containerHeight=0,this.canvas2D=new B(this.options.fit),this.container.prepend(this.canvas2D.element),this.canvas3D=new X,this.container.prepend(this.canvas3D.element),this.video=new J,this.container.prepend(this.video.element),this.loader=new k(this.options.server,this.options.api,this),this.resolution=new y(0,0),this.parameters={width:0,height:0,antialiasing:!1,superSampling:2},this.encoder={format:"jpeg",quality:80},this.hotspots=[],this.widgetImage=new j(t,this.canvas2D,this.loader),this.widgetVideo=new G(t,this.video,this.loader),this.widgetVRObject=new O(t,this.canvas2D,this.loader,this.onVrobjectInteraction),this.canvas3D.context&&(this.widgetVRCube=new H(t,this.canvas3D,this.loader,this.onVrcubeInteraction)),this.widget=this.widgetImage,this.isDestroyed=!1,this.container.addEventListener("mousedown",this.onMouseDown),this.container.addEventListener("mouseenter",this.onMouseEnter),this.container.addEventListener("touchstart",this.onTouchStart),document.addEventListener("mousemove",this.onMouseMove,{passive:!1}),document.addEventListener("mouseup",this.onMouseUp),document.addEventListener("touchmove",this.onTouchMove,{passive:!1}),document.addEventListener("touchend",this.onTouchEnd),this.loadWidget=C(this.loadWidget,10),this.onResize=C(this.onResize,250),requestAnimationFrame(this.checkResize)}destroy(){this.canvas2D.destroy(),this.container.removeEventListener("mousedown",this.onMouseDown),this.container.removeEventListener("mouseenter",this.onMouseEnter),this.container.removeEventListener("touchstart",this.onTouchStart),document.removeEventListener("mousemove",this.onMouseMove),document.removeEventListener("mouseup",this.onMouseUp),document.removeEventListener("touchmove",this.onTouchMove),document.removeEventListener("touchend",this.onTouchEnd),this.isDestroyed=!0}async load(t,e){let i=Promise.resolve();return e?.animation&&(i=i.then(()=>this.loadAnimation(e.animation))),this.view&&e?.fromPosition!==void 0&&this.viewWidget instanceof O&&(this.view.mode,i=i.then(()=>this.viewWidget.goto(e.fromPosition))),e?.animation&&(i=i.then(()=>this.widgetVideo.play())),i=i.then(()=>(this.scene=Array.isArray(t)?[...t]:[t],this.loadWidget(!1,!(e&&e.animation)))),i.catch(s=>{this.onLoadError(s)}),i}async setEncoder(t){this.encoder={...t};let e=Promise.resolve();return e=e.then(()=>this.loadWidget(!1,!0)),e.catch(i=>{this.onLoadError(i)}),e}setParameters(t){t.width&&t.height&&(this.resolution=new y(t.width,t.height)),this.parameters={...t},this.parameters.width=this.resolution.width,this.parameters.height=this.resolution.height;let e=Promise.resolve();return e=e.then(()=>this.loadWidget(!1,!0)),e.catch(i=>{this.onLoadError(i)}),e}setHotspots(t){this.hotspots=t,this.loadWidget(!1,!1)}async setView(t,e){let i=Promise.resolve();return e?.animation&&(i=i.then(()=>this.loadAnimation(e.animation))),this.view&&e?.fromPosition!==void 0&&this.viewWidget instanceof O&&(i=i.then(()=>this.viewWidget.goto(e.fromPosition))),e?.animation&&(i=i.then(()=>this.widgetVideo.play())),i=i.then(()=>{let s=!0;return this.view={...t},this.view&&this.viewWidget instanceof O&&e?.toPosition!==void 0&&(s=!1,this.viewWidget.position=e.toPosition),this.loadWidget(s,!(e&&e.animation))}),i.catch(s=>{this.onLoadError(s)}),i}setVrcube(t){this.widgetVRCube&&Object.assign(this.widgetVRCube,t)}setVrobject(t){Object.assign(this.widgetVRObject,t)}async loadAnimation(t){const e={scene:this.scene,view:{animation:t.name,camera:t.camera,duration:t.duration,loop:t.loop,reverse:t.reverse},parameters:this.parameters,encoder:{format:"mp4"}};return e.view?.background||(e.view.background="product"),this.widgetVideo.load(e).then(()=>Promise.resolve())}async playAnimation(t){return this.loadAnimation(t).then(()=>this.widgetVideo.play()).catch(e=>{this.onLoadError(e)})}stopAnimation(){this.widgetVideo.hide()}async pick(t){if(!this.scene)throw new Error("No scene set");if(!this.view)throw new Error("No view set");if(!this.view.camera&&!this.view.cameraGroup)throw new Error("No camera set");const e={scene:this.scene,view:this.view,parameters:this.parameters,encoder:this.encoder};return await this.viewWidget.pick(e,t)}async pickHotspot(t){const e=await this.pick(t),i=Object.values(e.point),s=h.v3.normalize(Object.values(e.normal)),r=h.v3.add(i,h.v3.mulScalar(s,.01));return e.point={x:r[0],y:r[1],z:r[2]},e}snapshot(t,e){return this.viewWidget.snapshot(t,e)}async loadWidget(t,e){if(!this.scene||!this.view||!this.parameters.width||!this.parameters.height)return Promise.resolve();const i=this.viewWidget;if(!i)return Promise.reject(new Error("Unknown view mode"));const s={scene:this.scene,view:this.view,parameters:this.parameters,encoder:this.encoder};return s.view.background||(s.view.background="product"),i.load(s,this.hotspots,t,e).then(()=>{this.widget.hide(),this.widget=i,this.widget.show(),this.widgetVideo.hide(),this.onHotspotsChange()})}get viewWidget(){switch(this.view?.mode){case"image":return this.widgetImage;case"video":return this.widgetVideo;case"vrcube":return this.widgetVRCube??this.widgetImage;case"vrobject":return this.widgetVRObject;default:return this.widgetImage}}checkResize(){if(this.isDestroyed)return;const t=this.container.clientWidth,e=this.container.clientHeight;(t!==this.containerWidth||e!==this.containerHeight)&&(this.containerWidth=t,this.containerHeight=e,this.onResize()),this.isDestroyed||requestAnimationFrame(this.checkResize)}onMouseDown(t){this.widget.onMouseDown(t)}onMouseEnter(t){this.widget.onMouseEnter(t)}onMouseMove(t){this.widget.onMouseMove(t)}onMouseUp(t){this.widget.onMouseUp(t)}onTouchStart(t){this.widget.onTouchStart(t)}onTouchMove(t){this.widget.onTouchMove(t)}onTouchEnd(t){this.widget.onTouchEnd(t)}onDeviceOrientation(t){this.widget.onDeviceOrientation(t)}onResize(){const t=this.container.clientWidth,e=this.container.clientHeight;this.options.autores&&(this.resolution=w.getStandardResolution(t*window.devicePixelRatio,e*window.devicePixelRatio),this.parameters.width=this.resolution.width,this.parameters.height=this.resolution.height),this.canvas2D.resize(t,e,window.devicePixelRatio),this.canvas3D.resize(t,e,window.devicePixelRatio),this.video.resize(t,e,this.resolution,this.options.fit),this.loadWidget(!1,!1).then(()=>{this.onHotspotsChange()}).catch(i=>{this.onLoadError(i)})}onVrcubeInteraction(...t){this.onHotspotsChange(),this.options.events.onInteraction(...t),this.options.events.onVrcubeInteraction(...t)}onVrobjectInteraction(t){this.onHotspotsChange(),this.options.events.onInteraction(t.position),this.options.events.onVrobjectInteraction(t.position)}onHotspotsChange(){const t=this.widget.hotspots(this.resolution);t.length&&this.options.events.onHotspotsChange(t)}onLoadStart(...t){this.container.classList.add("ls-viewer-container-loading"),this.options.events.onLoadStart(...t)}onLoadProgress(...t){this.options.events.onLoadProgress(...t)}onLoadEnd(...t){this.container.classList.remove("ls-viewer-container-loading"),this.options.events.onLoadEnd(...t)}onLoadError(...t){this.container.classList.remove("ls-viewer-container-loading"),this.options.events.onLoadError(...t)}}exports.WRAPIv2=void 0;(l=>{(t=>{t.Visible="Visible",t.Occluded="Occluded",t.Clipped="Clipped",t.OutOfFrustum="OutOfFrustum"})(l.HotspotVisibility||(l.HotspotVisibility={})),(t=>{t.VeryLow="veryLow",t.Low="low",t.Medium="medium",t.Fine="fine",t.Ultra="ultra"})(l.SunShadowQualityMode||(l.SunShadowQualityMode={})),(t=>{t.None="none",t.Weak="weak",t.Normal="normal",t.Fine="fine",t.UltraFine="ultraFine",t.Max="max"})(l.SunShadowSmoothnessMode||(l.SunShadowSmoothnessMode={})),(t=>{t.Manual="manual",t.ExtractedFromEnv="extractedFromEnv"})(l.SunUseCaseMode||(l.SunUseCaseMode={})),(t=>{t.ShowOnly="showOnly",t.HideOnly="hideOnly"})(l.SurfacesFilterMode||(l.SurfacesFilterMode={}))})(exports.WRAPIv2||(exports.WRAPIv2={}));exports.Viewer=et;exports.WidgetImage=j;exports.WidgetVRCube=H;exports.WidgetVRObject=O;exports.WidgetVideo=G;
package/dist/lib/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  (function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode(".ls-viewer-container{display:block;position:relative;overflow:hidden;-webkit-user-select:none;user-select:none;width:100%;height:100%}.ls-viewer-container-image,.ls-viewer-container-video{cursor:default;pointer-events:none}.ls-viewer-container-vrcube{cursor:pointer;cursor:grab}.ls-viewer-container-vrcube-grabbing{cursor:move;cursor:grabbing}.ls-viewer-container-vrobject{cursor:move;cursor:grab}.ls-viewer-container-vrobject-grabbing{cursor:move;cursor:grabbing}.ls-viewer-container-loading{cursor:progress}.ls-viewer-canvas{position:absolute;opacity:0;transition:opacity .5s}.ls-viewer-video{position:absolute}")),document.head.appendChild(e)}}catch(r){console.error("vite-plugin-css-injected-by-js",r)}})();
2
2
  import k from "debounce-promise";
3
- import * as M from "twgl.js";
4
- import { v3 as h, m4 as l } from "twgl.js";
5
- import U from "regression";
3
+ import * as P from "twgl.js";
4
+ import { v3 as h, m4 as c } from "twgl.js";
5
+ import $ from "regression";
6
6
  class b {
7
7
  constructor(t, e) {
8
8
  this.width = t, this.height = e;
@@ -33,8 +33,8 @@ class p {
33
33
  n = e.width, a = e.height;
34
34
  break;
35
35
  }
36
- const o = (e.height - a) / 2, d = (e.width - n) / 2;
37
- return new p(o, d, n, a);
36
+ const o = (e.height - a) / 2, l = (e.width - n) / 2;
37
+ return new p(o, l, n, a);
38
38
  }
39
39
  static project(t, e, i, s) {
40
40
  const r = p.fit(t, e, i), n = r.width / t.width, a = r.height / t.height;
@@ -76,7 +76,7 @@ class p {
76
76
  return t <= 240 ? 240 : t <= 360 ? 360 : t <= 480 ? 480 : t <= 720 ? 720 : 1080;
77
77
  }
78
78
  }
79
- class N {
79
+ class U {
80
80
  constructor(t) {
81
81
  this.element = document.createElement("canvas"), this.element.classList.add("ls-viewer-canvas"), this.element.style.opacity = "0", this.element.width = 0, this.element.height = 0, this.context = this.element.getContext("2d"), this.backCanvas = document.createElement("canvas"), this.backContext = this.backCanvas.getContext("2d"), this.fit = t, this.pixelRatio = 1;
82
82
  }
@@ -113,9 +113,9 @@ class N {
113
113
  });
114
114
  }
115
115
  }
116
- class B {
116
+ class N {
117
117
  constructor() {
118
- this.element = document.createElement("canvas"), this.element.classList.add("ls-viewer-canvas"), this.element.style.opacity = "0", this.element.width = 0, this.element.height = 0, this.context = M.getContext(this.element, { preserveDrawingBuffer: !0 }), this.context && this.context.isContextLost() && (this.context = void 0), M.setDefaults({ textureColor: [1, 1, 1, 1] });
118
+ this.element = document.createElement("canvas"), this.element.classList.add("ls-viewer-canvas"), this.element.style.opacity = "0", this.element.width = 0, this.element.height = 0, this.context = P.getContext(this.element, { preserveDrawingBuffer: !0 }), this.context && this.context.isContextLost() && (this.context = void 0), P.setDefaults({ textureColor: [1, 1, 1, 1] });
119
119
  }
120
120
  show() {
121
121
  this.element.style.opacity = "1";
@@ -154,8 +154,8 @@ class w {
154
154
  }
155
155
  static perspectiveWithLeft(t, e, i, s, r, n, a) {
156
156
  a = a || new Float32Array(16);
157
- const o = e + t, d = e - t, u = s + i, f = s - i, c = n - r;
158
- return a[0] = 2 * r / d, a[1] = 0, a[2] = 0, a[3] = 0, a[4] = 0, a[5] = 2 * r / f, a[6] = 0, a[7] = 0, a[8] = o / d, a[9] = u / f, a[10] = -n / c, a[11] = -1, a[12] = 0, a[13] = 0, a[14] = -n * r / c, a[15] = 0, a;
157
+ const o = e + t, l = e - t, u = s + i, f = s - i, d = n - r;
158
+ return a[0] = 2 * r / l, a[1] = 0, a[2] = 0, a[3] = 0, a[4] = 0, a[5] = 2 * r / f, a[6] = 0, a[7] = 0, a[8] = o / l, a[9] = u / f, a[10] = -n / d, a[11] = -1, a[12] = 0, a[13] = 0, a[14] = -n * r / d, a[15] = 0, a;
159
159
  }
160
160
  }
161
161
  const A = class A {
@@ -194,7 +194,7 @@ const A = class A {
194
194
  return h.normalize(h.cross(this.viewVector, this.up));
195
195
  }
196
196
  get viewMatrix() {
197
- return l.inverse(l.lookAt(this.eye, this.target, this.up));
197
+ return c.inverse(c.lookAt(this.eye, this.target, this.up));
198
198
  }
199
199
  clone() {
200
200
  return new A(h.copy(this.target), h.copy(this.eye), h.copy(this.up));
@@ -202,7 +202,7 @@ const A = class A {
202
202
  };
203
203
  A.default = new A([0, 0, 0], [2, 2, 2], [0, 1, 0]);
204
204
  let L = A;
205
- class X {
205
+ class B {
206
206
  constructor(t) {
207
207
  this.target = t.target;
208
208
  const e = h.normalize(h.subtract(t.eye, t.target)), i = h.dot(e, [1, 0, 0]), s = h.dot(e, [0, 1, 0]), r = h.dot(e, [0, 0, 1]);
@@ -213,16 +213,16 @@ class X {
213
213
  return [i, e, s];
214
214
  }
215
215
  pointOfView(t) {
216
- const e = l.rotationY(this.longitude), i = l.rotationX(-this.latitude), s = l.rotationZ(0), r = l.multiply(e, l.multiply(i, s));
216
+ const e = c.rotationY(this.longitude), i = c.rotationX(-this.latitude), s = c.rotationZ(0), r = c.multiply(e, c.multiply(i, s));
217
217
  let n = [0, 0, -1];
218
- n = l.transformPoint(r, n);
218
+ n = c.transformPoint(r, n);
219
219
  let a = [0, 1, 0];
220
- a = l.transformPoint(r, a);
220
+ a = c.transformPoint(r, a);
221
221
  const o = h.subtract(t, h.mulScalar(n, this.distance));
222
222
  return new L(t, o, a);
223
223
  }
224
224
  }
225
- class Y {
225
+ class X {
226
226
  constructor() {
227
227
  }
228
228
  async animation(t) {
@@ -244,17 +244,15 @@ class Y {
244
244
  return t.scene;
245
245
  }
246
246
  }
247
- class q {
247
+ class H {
248
248
  constructor(t) {
249
249
  this.xmlDoc = t;
250
250
  }
251
251
  get id() {
252
- var t;
253
- return (t = this.xmlDoc.getElementsByTagName("Database")[0]) == null ? void 0 : t.getAttribute("id");
252
+ return this.xmlDoc.getElementsByTagName("Database")[0]?.getAttribute("id");
254
253
  }
255
254
  getCameraId(t, e) {
256
- var i, s;
257
- return e ? (i = this.xmlDoc.querySelector(`RootCameraGroup Group[name="${e}"] Camera[name="${t}"]`)) == null ? void 0 : i.getAttribute("id") : (s = this.xmlDoc.querySelector(`RootCameraGroup Camera[name="${t}"]`)) == null ? void 0 : s.getAttribute("id");
255
+ return e ? this.xmlDoc.querySelector(`RootCameraGroup Group[name="${e}"] Camera[name="${t}"]`)?.getAttribute("id") : this.xmlDoc.querySelector(`RootCameraGroup Camera[name="${t}"]`)?.getAttribute("id");
258
256
  }
259
257
  getCameraById(t, e) {
260
258
  let i;
@@ -265,8 +263,7 @@ class q {
265
263
  return e && t ? i = this.xmlDoc.querySelector(`RootCameraGroup Group[name="${e}"] Camera[name="${t}"]`) : i = this.xmlDoc.querySelector(`RootCameraGroup Camera[name="${t}"]`), i ? this.mapElementToCamera(i) : null;
266
264
  }
267
265
  getCameraGroupId(t) {
268
- var e;
269
- return (e = this.xmlDoc.querySelector(`RootCameraGroup Group[name="${t}"]`)) == null ? void 0 : e.getAttribute("id");
266
+ return this.xmlDoc.querySelector(`RootCameraGroup Group[name="${t}"]`)?.getAttribute("id");
270
267
  }
271
268
  getCameraGroupById(t) {
272
269
  const e = this.xmlDoc.querySelector(`RootCameraGroup Group[id="${t}"]`);
@@ -318,15 +315,14 @@ const g = class g {
318
315
  return Object.entries(t).filter(([e, i]) => i != null).map(([e, i]) => `${e}=${i}`).join("&");
319
316
  }
320
317
  static sceneParameters(t) {
321
- var n, a;
322
- const e = t.scene, i = e.length > 1 ? e.find((o) => o.accessory) : null, s = e.length > 1 ? e.find((o) => o.decor) : null, r = e.find((o) => o !== i && o !== s);
318
+ const e = t.scene, i = e.length > 1 ? e.find((n) => n.accessory) : null, s = e.length > 1 ? e.find((n) => n.decor) : null, r = e.find((n) => n !== i && n !== s);
323
319
  return {
324
320
  databaseId: r.database,
325
- configuration: r == null ? void 0 : r.configuration,
326
- animations: (n = r == null ? void 0 : r.animations) == null ? void 0 : n.join("/"),
327
- accessoryDatabaseId: i == null ? void 0 : i.database,
328
- decorDatabaseId: s == null ? void 0 : s.database,
329
- decorDeltaAltitude: (a = s == null ? void 0 : s.translation) == null ? void 0 : a.y
321
+ configuration: r?.configuration,
322
+ animations: r?.animations?.join("/"),
323
+ accessoryDatabaseId: i?.database,
324
+ decorDatabaseId: s?.database,
325
+ decorDeltaAltitude: s?.translation?.y
330
326
  };
331
327
  }
332
328
  static renderParameters(t) {
@@ -368,7 +364,7 @@ const g = class g {
368
364
  async database(t) {
369
365
  return fetch(`${this.server}/Database?databaseId=${t}`).then((e) => e.text()).then((e) => {
370
366
  const i = new DOMParser().parseFromString(e, "application/xml");
371
- return new q(i);
367
+ return new H(i);
372
368
  });
373
369
  }
374
370
  async image(t) {
@@ -481,7 +477,7 @@ class m {
481
477
  async database(t) {
482
478
  return fetch(`${this.server}/Database?databaseId=${t}`).then((e) => e.text()).then((e) => {
483
479
  const i = new DOMParser().parseFromString(e, "application/xml");
484
- return new q(i);
480
+ return new H(i);
485
481
  });
486
482
  }
487
483
  async image(t) {
@@ -635,7 +631,7 @@ class D {
635
631
  constructor(t, e, i) {
636
632
  switch (e) {
637
633
  case "static":
638
- this.webrender = new Y();
634
+ this.webrender = new X();
639
635
  break;
640
636
  case "v1":
641
637
  this.webrender = new S(t), this.webrenderV2 = new m(t);
@@ -675,10 +671,9 @@ class D {
675
671
  }).then((i) => (this.onLoadEnd(this.progress), i));
676
672
  }
677
673
  async loadVRObjectSnapshot(t, e) {
678
- var s;
679
674
  this.loadingId += 1, this.loaded = 0, this.total = 0, this.onLoadStart(this.progress);
680
675
  const { loadingId: i } = this;
681
- return t.view.animation ? ((s = t.encoder) == null ? void 0 : s.format) === "mp4" ? this.webrender.video(t).then((r) => this.loadVideoFrames(r, t.view.frames, 30, i)) : this.webrender.animation(t).then((r) => this.loadImageFrames(r, t.view.loop, e, i)) : this.webrender.vrObject(t).then((r) => this.loadImageFrames(r, t.view.loop, e, i));
676
+ return t.view.animation ? t.encoder?.format === "mp4" ? this.webrender.video(t).then((s) => this.loadVideoFrames(s, t.view.frames, 30, i)) : this.webrender.animation(t).then((s) => this.loadImageFrames(s, t.view.loop, e, i)) : this.webrender.vrObject(t).then((s) => this.loadImageFrames(s, t.view.loop, e, i));
682
677
  }
683
678
  async loadImage(t, e) {
684
679
  const i = new Image();
@@ -704,7 +699,7 @@ class D {
704
699
  this.total = t.length;
705
700
  const r = new Array(t.length), n = i || 0;
706
701
  for (let a = 0, o = t.length; a < o; a += 1) {
707
- const d = Math.ceil(a / 2) * (a % 2 === 0 ? 1 : -1), u = e ? w.mod(n + d, o) : a;
702
+ const l = Math.ceil(a / 2) * (a % 2 === 0 ? 1 : -1), u = e ? w.mod(n + l, o) : a;
708
703
  r[u] = this.loadImage(t[u], s);
709
704
  }
710
705
  return Promise.all(r).then(() => this.onLoadEnd(this.progress)).catch(() => {
@@ -732,19 +727,19 @@ class D {
732
727
  async loadVideoFrame(t, e, i, s, r) {
733
728
  let n = 0;
734
729
  return new Promise((a, o) => {
735
- const d = () => {
730
+ const l = () => {
736
731
  if (r !== this.loadingId) return;
737
732
  if (n !== s) {
738
733
  n += 1;
739
734
  return;
740
735
  }
741
- t.removeEventListener("seeked", d);
736
+ t.removeEventListener("seeked", l);
742
737
  const u = document.createElement("canvas");
743
738
  u.width = t.videoWidth, u.height = t.videoHeight, u.getContext("2d").drawImage(t, 0, 0);
744
- const c = new Image();
745
- c.src = u.toDataURL(), a(c), this.loaded += 1, this.onLoadProgress(this.progress), s !== i - 1 && (t.currentTime += 1 / e);
739
+ const d = new Image();
740
+ d.src = u.toDataURL(), a(d), this.loaded += 1, this.onLoadProgress(this.progress), s !== i - 1 && (t.currentTime += 1 / e);
746
741
  };
747
- t.addEventListener("seeked", d), t.addEventListener(
742
+ t.addEventListener("seeked", l), t.addEventListener(
748
743
  "error",
749
744
  (u) => {
750
745
  r === this.loadingId && o(u);
@@ -786,20 +781,19 @@ class D {
786
781
  return this.webrenderV2 ? await this.webrenderV2.imagePick(await this.vrCubeFrameSnapshot(t, i), e) : Promise.reject(new Error("Picking only available with api V2"));
787
782
  }
788
783
  async convert(t) {
789
- var o;
790
784
  if (!this.webrenderV2 || this.webrender instanceof m || !t.view.camera)
791
785
  return t;
792
- const e = t.scene.find((d) => !d.decor && !d.accessory);
786
+ const e = t.scene.find((o) => !o.decor && !o.accessory);
793
787
  if (!e)
794
788
  return t;
795
- let i = this.databases.find((d) => d.id === e.database);
789
+ let i = this.databases.find((o) => o.id === e.database);
796
790
  (!i || !i.xmlDoc) && (i = await this.webrender.database(e.database), this.databases.push(i));
797
- const s = (o = t.view.camera) == null ? void 0 : o.split("/"), r = s.length === 2 ? s[0] : void 0, n = s.length === 2 ? s[1] : s[0], a = i.getCameraId(n, r);
791
+ const s = t.view.camera?.split("/"), r = s.length === 2 ? s[0] : void 0, n = s.length === 2 ? s[1] : s[0], a = i.getCameraId(n, r);
798
792
  if (a)
799
793
  return { ...t, view: { ...t.view, camera: a } };
800
794
  {
801
- const d = i.getCameraGroupId(n);
802
- return d ? { ...t, view: { ...t.view, cameraGroup: d } } : t;
795
+ const o = i.getCameraGroupId(n);
796
+ return o ? { ...t, view: { ...t.view, cameraGroup: o } } : t;
803
797
  }
804
798
  }
805
799
  async vrObjectFrameSnapshot(t, e, i) {
@@ -825,9 +819,9 @@ class D {
825
819
  const n = r.getCameraById(t.view.camera);
826
820
  if (!n)
827
821
  return t;
828
- const a = new X(n.pointOfView), o = 2 * Math.PI / i;
822
+ const a = new B(n.pointOfView), o = 2 * Math.PI / i;
829
823
  a.longitude += e * o % (2 * Math.PI);
830
- const d = a.pointOfView(n.pointOfView.target);
824
+ const l = a.pointOfView(n.pointOfView.target);
831
825
  return {
832
826
  ...t,
833
827
  view: {
@@ -836,19 +830,19 @@ class D {
836
830
  id: n.id,
837
831
  pov: {
838
832
  target: {
839
- x: d.target[0],
840
- y: d.target[1],
841
- z: d.target[2]
833
+ x: l.target[0],
834
+ y: l.target[1],
835
+ z: l.target[2]
842
836
  },
843
837
  eye: {
844
- x: d.eye[0],
845
- y: d.eye[1],
846
- z: d.eye[2]
838
+ x: l.eye[0],
839
+ y: l.eye[1],
840
+ z: l.eye[2]
847
841
  },
848
842
  up: {
849
- x: d.up[0],
850
- y: d.up[1],
851
- z: d.up[2]
843
+ x: l.up[0],
844
+ y: l.up[1],
845
+ z: l.up[2]
852
846
  }
853
847
  }
854
848
  }
@@ -874,8 +868,8 @@ class D {
874
868
  return t;
875
869
  let r;
876
870
  if (this.webrender instanceof S) {
877
- const o = t.view.camera.split("/"), d = o.length === 2 ? o[0] : void 0, u = o.length === 2 ? o[1] : o[0];
878
- r = s.getCameraId(u, d);
871
+ const o = t.view.camera.split("/"), l = o.length === 2 ? o[0] : void 0, u = o.length === 2 ? o[1] : o[0];
872
+ r = s.getCameraId(u, l);
879
873
  } else this.webrender instanceof m && (r = t.view.camera);
880
874
  if (!r)
881
875
  return t;
@@ -937,7 +931,7 @@ class D {
937
931
  return e.protocol === "http:" || e.protocol === "https:";
938
932
  }
939
933
  }
940
- class J {
934
+ class Y {
941
935
  constructor() {
942
936
  this.element = document.createElement("video"), this.element.classList.add("ls-viewer-video"), this.element.style.opacity = "0", this.element.width = 0, this.element.height = 0, this.element.setAttribute("muted", ""), this.element.setAttribute("playsinline", ""), this.element.setAttribute("preload", "auto");
943
937
  }
@@ -952,7 +946,7 @@ class J {
952
946
  this.element.style.top = `${r.top}px`, this.element.style.left = `${r.left}px`, this.element.style.width = `${r.width}px`, this.element.style.height = `${r.height}px`, (i.width !== this.element.width || i.height !== this.element.height) && (this.element.width = i.width, this.element.height = i.height);
953
947
  }
954
948
  }
955
- class Z {
949
+ class J {
956
950
  constructor(t, e, i) {
957
951
  this.container = t, this.canvas = e, this.loader = i, this.hotspotList = [];
958
952
  }
@@ -1023,7 +1017,7 @@ class y {
1023
1017
  return new I(e.screenX, e.screenY);
1024
1018
  }
1025
1019
  }
1026
- class j {
1020
+ class V {
1027
1021
  constructor(...t) {
1028
1022
  t.length === 3 ? ({ 0: this.u, 1: this.v, 2: this.o } = t, this.w = h.cross(this.u, this.v)) : t.length === 4 ? { 0: this.u, 1: this.v, 2: this.w, 3: this.o } = t : (this.u = [1, 0, 0], this.v = [0, 1, 0], this.w = [0, 0, 1], this.o = [0, 0, 0]);
1029
1023
  }
@@ -1032,15 +1026,15 @@ class j {
1032
1026
  return [...t, ...e, ...i, ...s];
1033
1027
  }
1034
1028
  get globalToLocalMatrix() {
1035
- return l.inverse(this.localToGlobalMatrix);
1029
+ return c.inverse(this.localToGlobalMatrix);
1036
1030
  }
1037
1031
  }
1038
- class Q {
1032
+ class Z {
1039
1033
  constructor(t, e, i) {
1040
1034
  this.x = t, this.y = e, this.time = i;
1041
1035
  }
1042
1036
  }
1043
- class G {
1037
+ class q {
1044
1038
  constructor(t) {
1045
1039
  this.points = [], this.onMotion = t, this.lastPoint = new I(0, 0), this.velocity = new I(0, 0), this.loop = this.loop.bind(this);
1046
1040
  }
@@ -1049,7 +1043,7 @@ class G {
1049
1043
  }
1050
1044
  track(t) {
1051
1045
  const e = Date.now();
1052
- this.points = this.points.filter((i) => e - i.time <= 100), this.points.push(new Q(t.x, t.y, e)), this.lastPoint = t;
1046
+ this.points = this.points.filter((i) => e - i.time <= 100), this.points.push(new Z(t.x, t.y, e)), this.lastPoint = t;
1053
1047
  }
1054
1048
  start() {
1055
1049
  if (this.points.length === 0)
@@ -1068,17 +1062,17 @@ class G {
1068
1062
  this.lastPoint.x += this.velocity.x, this.lastPoint.y += this.velocity.y, this.velocity.x *= 0.9, this.velocity.y *= 0.9, this.onMotion(this.lastPoint.clone()), this.animationFrameId = requestAnimationFrame(this.loop);
1069
1063
  }
1070
1064
  }
1071
- class W {
1065
+ class Q {
1072
1066
  constructor(t, e, i) {
1073
- this.isStarted = !1, this.pov = t, this.fov = w.degreesToRadians(e), this.orientationMatrix = l.identity(), this.inertia = new G(this.motion.bind(this)), this.onMotion = i, this.initPov = this.pov, this.initFov = this.fov, this.initOrientation = w.degreesToRadians(window.orientation) || 0, this.startPov = new L([0, 0, 1], [0, 0, 0], [0, 1, 0]), this.startSize = { width: 0, height: 0 }, this.previousPoint = new I(0, 0);
1067
+ this.isStarted = !1, this.pov = t, this.fov = w.degreesToRadians(e), this.orientationMatrix = c.identity(), this.inertia = new q(this.motion.bind(this)), this.onMotion = i, this.initPov = this.pov, this.initFov = this.fov, this.initOrientation = w.degreesToRadians(window.orientation) || 0, this.startPov = new L([0, 0, 1], [0, 0, 0], [0, 1, 0]), this.startSize = { width: 0, height: 0 }, this.previousPoint = new I(0, 0);
1074
1068
  }
1075
1069
  destroy() {
1076
1070
  this.inertia.destroy();
1077
1071
  }
1078
1072
  get orientedPov() {
1079
- const t = h.normalize(h.cross(this.pov.up, this.pov.target)), e = new j(t, [0, 1, 0], this.pov.eye), i = l.identity();
1080
- l.multiply(i, e.localToGlobalMatrix, i), l.multiply(i, this.orientationMatrix, i), l.multiply(i, e.globalToLocalMatrix, i);
1081
- const s = l.transformDirection(i, this.pov.target), r = this.pov.eye, n = l.transformDirection(i, this.pov.up);
1073
+ const t = h.normalize(h.cross(this.pov.up, this.pov.target)), e = new V(t, [0, 1, 0], this.pov.eye), i = c.identity();
1074
+ c.multiply(i, e.localToGlobalMatrix, i), c.multiply(i, this.orientationMatrix, i), c.multiply(i, e.globalToLocalMatrix, i);
1075
+ const s = c.transformDirection(i, this.pov.target), r = this.pov.eye, n = c.transformDirection(i, this.pov.up);
1082
1076
  return new L(s, r, n);
1083
1077
  }
1084
1078
  reset() {
@@ -1092,20 +1086,20 @@ class W {
1092
1086
  const e = {
1093
1087
  x: t.x - this.previousPoint.x,
1094
1088
  y: t.y - this.previousPoint.y
1095
- }, i = w.accelerate(e.x, 1.3) / this.startSize.width * 0.2 * Math.PI * 1.5, s = w.accelerate(e.y, 1.3) / this.startSize.height * 0.2 * Math.PI, r = l.multiply(l.rotationY(i), l.rotationX(-s)), n = h.normalize(h.cross(this.pov.up, this.pov.target)), a = new j(n, [0, 1, 0], this.pov.eye), o = l.identity();
1096
- l.multiply(o, a.localToGlobalMatrix, o), l.multiply(o, r, o), l.multiply(o, a.globalToLocalMatrix, o);
1097
- const d = l.transformPoint(o, this.pov.target), u = l.transformDirection(o, this.pov.up);
1098
- h.cross(u, [0, 0, 1])[0] >= 0 && (this.pov.target = d, this.pov.up = u), this.previousPoint = t, this.onMotion();
1089
+ }, i = w.accelerate(e.x, 1.3) / this.startSize.width * 0.2 * Math.PI * 1.5, s = w.accelerate(e.y, 1.3) / this.startSize.height * 0.2 * Math.PI, r = c.multiply(c.rotationY(i), c.rotationX(-s)), n = h.normalize(h.cross(this.pov.up, this.pov.target)), a = new V(n, [0, 1, 0], this.pov.eye), o = c.identity();
1090
+ c.multiply(o, a.localToGlobalMatrix, o), c.multiply(o, r, o), c.multiply(o, a.globalToLocalMatrix, o);
1091
+ const l = c.transformPoint(o, this.pov.target), u = c.transformDirection(o, this.pov.up);
1092
+ h.cross(u, [0, 0, 1])[0] >= 0 && (this.pov.target = l, this.pov.up = u), this.previousPoint = t, this.onMotion();
1099
1093
  }
1100
1094
  end(t, e) {
1101
1095
  this.isStarted = !1, e && (this.inertia.track(t), this.inertia.start());
1102
1096
  }
1103
1097
  orientation(t, e, i) {
1104
- const s = w.degreesToRadians(window.orientation) || 0, r = w.degreesToRadians(t), n = w.degreesToRadians(-e), a = w.degreesToRadians(-i), o = l.rotationX(w.degreesToRadians(90));
1105
- l.rotateZ(o, this.initOrientation, o), l.rotateZ(o, r, o), l.rotateX(o, n, o), l.rotateY(o, a, o), l.rotateZ(o, -s, o), this.orientationMatrix = o, this.onMotion();
1098
+ const s = w.degreesToRadians(window.orientation) || 0, r = w.degreesToRadians(t), n = w.degreesToRadians(-e), a = w.degreesToRadians(-i), o = c.rotationX(w.degreesToRadians(90));
1099
+ c.rotateZ(o, this.initOrientation, o), c.rotateZ(o, r, o), c.rotateX(o, n, o), c.rotateY(o, a, o), c.rotateZ(o, -s, o), this.orientationMatrix = o, this.onMotion();
1106
1100
  }
1107
1101
  }
1108
- var _ = `precision mediump float;
1102
+ var W = `precision mediump float;
1109
1103
 
1110
1104
  uniform float u_mix;
1111
1105
  uniform samplerCube u_texture;
@@ -1117,7 +1111,7 @@ void main() {
1117
1111
  vec4 backColor = textureCube(u_texture_back, direction);
1118
1112
  vec4 color = textureCube(u_texture, direction);
1119
1113
  gl_FragColor = mix(backColor, color, u_mix);
1120
- }`, K = `attribute vec4 position;
1114
+ }`, _ = `attribute vec4 position;
1121
1115
 
1122
1116
  uniform mat4 u_mvpi;
1123
1117
 
@@ -1127,27 +1121,27 @@ void main() {
1127
1121
  direction = (u_mvpi * position).xyz;
1128
1122
  gl_Position = position;
1129
1123
  }`;
1130
- class tt {
1124
+ class K {
1131
1125
  constructor(t, e, i, s) {
1132
1126
  this.container = t, this.canvas = e, this.loader = i, this.images = [], this.hotspotsList = [[]];
1133
- const r = new L([0, 0, 1], [0, 0, 0], [0, 1, 0]), n = 60, a = l.rotationX(w.degreesToRadians(15));
1134
- l.transformDirection(a, r.target, r.target), l.transformDirection(a, r.up, r.up), this.interaction = new W(r, n, () => {
1127
+ const r = new L([0, 0, 1], [0, 0, 0], [0, 1, 0]), n = 60, a = c.rotationX(w.degreesToRadians(15));
1128
+ c.transformDirection(a, r.target, r.target), c.transformDirection(a, r.up, r.up), this.interaction = new Q(r, n, () => {
1135
1129
  this.animationFrameId = requestAnimationFrame(this.render), this.onInteraction({
1136
1130
  pov: this.interaction.pov.clone(),
1137
1131
  fov: this.interaction.fov
1138
1132
  });
1139
- }), this.onInteraction = s, this.gl = this.canvas.context, this.programInfo = M.createProgramInfo(this.gl, [`${K}
1140
- `, `${_}
1141
- `]), this.quad = M.primitives.createXYQuadBufferInfo(this.gl), this.uniforms = {
1142
- u_mvpi: l.identity(),
1133
+ }), this.onInteraction = s, this.gl = this.canvas.context, this.programInfo = P.createProgramInfo(this.gl, [`${_}
1134
+ `, `${W}
1135
+ `]), this.quad = P.primitives.createXYQuadBufferInfo(this.gl), this.uniforms = {
1136
+ u_mvpi: c.identity(),
1143
1137
  u_mix: 0,
1144
- u_texture_back: M.createTexture(this.gl, {
1138
+ u_texture_back: P.createTexture(this.gl, {
1145
1139
  target: this.gl.TEXTURE_CUBE_MAP,
1146
1140
  minMag: this.gl.LINEAR,
1147
1141
  width: 1,
1148
1142
  height: 1
1149
1143
  }),
1150
- u_texture: M.createTexture(this.gl, {
1144
+ u_texture: P.createTexture(this.gl, {
1151
1145
  target: this.gl.TEXTURE_CUBE_MAP,
1152
1146
  minMag: this.gl.LINEAR,
1153
1147
  width: 1,
@@ -1185,7 +1179,7 @@ class tt {
1185
1179
  const n = JSON.stringify(t);
1186
1180
  n === this.snapshotHash ? r = r.then(() => (this.animationFrameId = requestAnimationFrame(this.render), Promise.resolve())) : (this.images = [], this.animationFrameId = requestAnimationFrame(this.render), r = r.then(
1187
1181
  () => this.loader.loadVRCubeSnapshot(t).then((o) => {
1188
- this.images = o, M.createTexture(
1182
+ this.images = o, P.createTexture(
1189
1183
  this.gl,
1190
1184
  {
1191
1185
  target: this.gl.TEXTURE_CUBE_MAP,
@@ -1202,8 +1196,8 @@ class tt {
1202
1196
  ],
1203
1197
  src: o
1204
1198
  },
1205
- (d, u) => {
1206
- d || (i && this.interaction.reset(), this.uniforms.u_mix = s ? 0 : 1, this.uniforms.u_texture_back = this.uniforms.u_texture, this.uniforms.u_texture = u, this.animationFrameId = requestAnimationFrame(this.render));
1199
+ (l, u) => {
1200
+ l || (i && this.interaction.reset(), this.uniforms.u_mix = s ? 0 : 1, this.uniforms.u_texture_back = this.uniforms.u_texture, this.uniforms.u_texture = u, this.animationFrameId = requestAnimationFrame(this.render));
1207
1201
  }
1208
1202
  );
1209
1203
  })
@@ -1216,73 +1210,72 @@ class tt {
1216
1210
  ) : this.hotspotsList = [[]]), this.hotspotsHash = a, this.snapshotHash = n, r;
1217
1211
  }
1218
1212
  async pick(t, e) {
1219
- const i = this.canvas.element.clientWidth, s = this.canvas.element.clientHeight, r = e.x, n = s - e.y, a = 2 * r / i - 1, o = 2 * n / s - 1, d = [a, o, 0], u = this.modelViewProjectionMatrix, f = l.inverse(u), c = h.normalize(l.transformPoint(f, d)), T = Math.max(Math.abs(c[0]), Math.abs(c[1]), Math.abs(c[2]));
1213
+ const i = this.canvas.element.clientWidth, s = this.canvas.element.clientHeight, r = e.x, n = s - e.y, a = 2 * r / i - 1, o = 2 * n / s - 1, l = [a, o, 0], u = this.modelViewProjectionMatrix, f = c.inverse(u), d = h.normalize(c.transformPoint(f, l)), T = Math.max(Math.abs(d[0]), Math.abs(d[1]), Math.abs(d[2]));
1220
1214
  let F = "";
1221
- Math.abs(c[0]) === T ? F = c[0] > 0 ? "XPOS" : "XNEG" : Math.abs(c[1]) === T ? F = c[1] > 0 ? "YPOS" : "YNEG" : F = c[2] > 0 ? "ZPOS" : "ZNEG";
1222
- let P = 0, x = 0, E = "";
1215
+ Math.abs(d[0]) === T ? F = d[0] > 0 ? "XPOS" : "XNEG" : Math.abs(d[1]) === T ? F = d[1] > 0 ? "YPOS" : "YNEG" : F = d[2] > 0 ? "ZPOS" : "ZNEG";
1216
+ let x = 0, M = 0, E = "";
1223
1217
  switch (F) {
1224
1218
  case "XPOS":
1225
- P = (-c[2] / Math.abs(c[0]) + 1) / 2, x = (-c[1] / Math.abs(c[0]) + 1) / 2, E = "right";
1219
+ x = (-d[2] / Math.abs(d[0]) + 1) / 2, M = (-d[1] / Math.abs(d[0]) + 1) / 2, E = "right";
1226
1220
  break;
1227
1221
  case "XNEG":
1228
- P = (c[2] / Math.abs(c[0]) + 1) / 2, x = (-c[1] / Math.abs(c[0]) + 1) / 2, E = "left";
1222
+ x = (d[2] / Math.abs(d[0]) + 1) / 2, M = (-d[1] / Math.abs(d[0]) + 1) / 2, E = "left";
1229
1223
  break;
1230
1224
  case "YPOS":
1231
- P = (c[0] / Math.abs(c[1]) + 1) / 2, x = (c[2] / Math.abs(c[1]) + 1) / 2, E = "up";
1225
+ x = (d[0] / Math.abs(d[1]) + 1) / 2, M = (d[2] / Math.abs(d[1]) + 1) / 2, E = "up";
1232
1226
  break;
1233
1227
  case "YNEG":
1234
- P = (c[0] / Math.abs(c[1]) + 1) / 2, x = (-c[2] / Math.abs(c[1]) + 1) / 2, E = "down";
1228
+ x = (d[0] / Math.abs(d[1]) + 1) / 2, M = (-d[2] / Math.abs(d[1]) + 1) / 2, E = "down";
1235
1229
  break;
1236
1230
  case "ZPOS":
1237
- P = (c[0] / Math.abs(c[2]) + 1) / 2, x = (-c[1] / Math.abs(c[2]) + 1) / 2, E = "front";
1231
+ x = (d[0] / Math.abs(d[2]) + 1) / 2, M = (-d[1] / Math.abs(d[2]) + 1) / 2, E = "front";
1238
1232
  break;
1239
1233
  case "ZNEG":
1240
- P = (-c[0] / Math.abs(c[2]) + 1) / 2, x = (-c[1] / Math.abs(c[2]) + 1) / 2, E = "back";
1234
+ x = (-d[0] / Math.abs(d[2]) + 1) / 2, M = (-d[1] / Math.abs(d[2]) + 1) / 2, E = "back";
1241
1235
  break;
1242
1236
  }
1243
- const O = {
1244
- x: Math.round(P * Math.max(t.parameters.width, t.parameters.height)),
1245
- y: Math.round(x * Math.max(t.parameters.width, t.parameters.height))
1237
+ const C = {
1238
+ x: Math.round(x * Math.max(t.parameters.width, t.parameters.height)),
1239
+ y: Math.round(M * Math.max(t.parameters.width, t.parameters.height))
1246
1240
  };
1247
- return this.loader.loadVRCubePick(t, O, E);
1241
+ return this.loader.loadVRCubePick(t, C, E);
1248
1242
  }
1249
1243
  hotspots() {
1250
- var s;
1251
1244
  const t = [];
1252
1245
  if (this.hotspotsList.length === 0)
1253
1246
  return [];
1254
- const e = ((s = this.hotspotsList[0]) == null ? void 0 : s.length) ?? 0, i = this.modelViewProjectionMatrix;
1255
- for (let r = 0; r < e; r++) {
1256
- const n = this.hotspotsList.findIndex(($) => $[r].visibility !== "OutOfFrustum");
1257
- if (n === -1)
1247
+ const e = this.hotspotsList[0]?.length ?? 0, i = this.modelViewProjectionMatrix;
1248
+ for (let s = 0; s < e; s++) {
1249
+ const r = this.hotspotsList.findIndex((R) => R[s].visibility !== "OutOfFrustum");
1250
+ if (r === -1)
1258
1251
  continue;
1259
- const a = { ...this.hotspotsList[n][r] }, o = a.position2D.x / this.images[0].width, d = a.position2D.y / this.images[0].height;
1260
- let u = 0, f = 0, c = 0;
1261
- switch (n) {
1252
+ const n = { ...this.hotspotsList[r][s] }, a = n.position2D.x / this.images[0].width, o = n.position2D.y / this.images[0].height;
1253
+ let l = 0, u = 0, f = 0;
1254
+ switch (r) {
1262
1255
  case 0:
1263
- this.pov.target[2] < 0 && (a.visibility = "OutOfFrustum"), u = 2 * o - 1, f = 1 - 2 * d, c = 1;
1256
+ this.pov.target[2] < 0 && (n.visibility = "OutOfFrustum"), l = 2 * a - 1, u = 1 - 2 * o, f = 1;
1264
1257
  break;
1265
1258
  case 1:
1266
- this.pov.target[0] > 0 && (a.visibility = "OutOfFrustum"), u = 1, f = 1 - 2 * d, c = 1 - 2 * o;
1259
+ this.pov.target[0] > 0 && (n.visibility = "OutOfFrustum"), l = 1, u = 1 - 2 * o, f = 1 - 2 * a;
1267
1260
  break;
1268
1261
  case 2:
1269
- this.pov.target[2] > 0 && (a.visibility = "OutOfFrustum"), u = 1 - 2 * o, f = 1 - 2 * d, c = -1;
1262
+ this.pov.target[2] > 0 && (n.visibility = "OutOfFrustum"), l = 1 - 2 * a, u = 1 - 2 * o, f = -1;
1270
1263
  break;
1271
1264
  case 3:
1272
- this.pov.target[0] < 0 && (a.visibility = "OutOfFrustum"), u = -1, f = 1 - 2 * d, c = 2 * o - 1;
1265
+ this.pov.target[0] < 0 && (n.visibility = "OutOfFrustum"), l = -1, u = 1 - 2 * o, f = 2 * a - 1;
1273
1266
  break;
1274
1267
  case 4:
1275
- this.pov.target[1] < 0 && (a.visibility = "OutOfFrustum"), u = 2 * o - 1, f = 1, c = 2 * d - 1;
1268
+ this.pov.target[1] < 0 && (n.visibility = "OutOfFrustum"), l = 2 * a - 1, u = 1, f = 2 * o - 1;
1276
1269
  break;
1277
1270
  case 5:
1278
- this.pov.target[1] > 0 && (a.visibility = "OutOfFrustum"), u = 2 * o - 1, f = -1, c = 1 - 2 * d;
1271
+ this.pov.target[1] > 0 && (n.visibility = "OutOfFrustum"), l = 2 * a - 1, u = -1, f = 1 - 2 * o;
1279
1272
  break;
1280
1273
  }
1281
- const T = h.normalize([u, f, c]), F = l.transformPoint(i, T), P = this.canvas.element.clientWidth, x = this.canvas.element.clientHeight, E = 0.5 * P * (F[0] + 1), O = 0.5 * x * (F[1] + 1), V = {
1282
- x: Math.round(E),
1283
- y: Math.round(x - O)
1284
- }, z = new b(P, x), R = p.contains(z, V) ? a.visibility : "OutOfFrustum";
1285
- t.push({ ...a, position2D: V, visibility: R });
1274
+ const d = h.normalize([l, u, f]), T = c.transformPoint(i, d), F = this.canvas.element.clientWidth, x = this.canvas.element.clientHeight, M = 0.5 * F * (T[0] + 1), E = 0.5 * x * (T[1] + 1), C = {
1275
+ x: Math.round(M),
1276
+ y: Math.round(x - E)
1277
+ }, G = new b(F, x), z = p.contains(G, C) ? n.visibility : "OutOfFrustum";
1278
+ t.push({ ...n, position2D: C, visibility: z });
1286
1279
  }
1287
1280
  return t;
1288
1281
  }
@@ -1290,11 +1283,11 @@ class tt {
1290
1283
  return this.canvas.element.toDataURL(t, e);
1291
1284
  }
1292
1285
  get modelViewProjectionMatrix() {
1293
- const t = this.canvas.element.clientWidth, e = this.canvas.element.clientHeight, i = t > e ? t / e : e / t, s = p.getStandardAspectRatio(t, e), r = this.interaction.fov * (s / i), n = l.setAxis(l.identity(), [-1, 0, 0], 0), a = t > e ? w.perspectiveWithFovY(r, t / e, 0.5, 100) : w.perspectiveWithFovX(r, t / e, 0.5, 100), o = this.interaction.orientedPov, d = l.inverse(l.lookAt(o.eye, o.target, o.up));
1294
- return l.multiply(l.multiply(a, d), n);
1286
+ const t = this.canvas.element.clientWidth, e = this.canvas.element.clientHeight, i = t > e ? t / e : e / t, s = p.getStandardAspectRatio(t, e), r = this.interaction.fov * (s / i), n = c.setAxis(c.identity(), [-1, 0, 0], 0), a = t > e ? w.perspectiveWithFovY(r, t / e, 0.5, 100) : w.perspectiveWithFovX(r, t / e, 0.5, 100), o = this.interaction.orientedPov, l = c.inverse(c.lookAt(o.eye, o.target, o.up));
1287
+ return c.multiply(c.multiply(a, l), n);
1295
1288
  }
1296
1289
  render() {
1297
- this.gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height), this.uniforms.u_mvpi = l.inverse(this.modelViewProjectionMatrix), this.gl.useProgram(this.programInfo.program), M.setBuffersAndAttributes(this.gl, this.programInfo, this.quad), M.setUniforms(this.programInfo, this.uniforms), M.drawBufferInfo(this.gl, this.quad), this.uniforms.u_mix < 1 && (this.uniforms.u_mix = Math.min(this.uniforms.u_mix + 0.05, 1), this.animationFrameId = requestAnimationFrame(this.render));
1290
+ this.gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height), this.uniforms.u_mvpi = c.inverse(this.modelViewProjectionMatrix), this.gl.useProgram(this.programInfo.program), P.setBuffersAndAttributes(this.gl, this.programInfo, this.quad), P.setUniforms(this.programInfo, this.uniforms), P.drawBufferInfo(this.gl, this.quad), this.uniforms.u_mix < 1 && (this.uniforms.u_mix = Math.min(this.uniforms.u_mix + 0.05, 1), this.animationFrameId = requestAnimationFrame(this.render));
1298
1291
  }
1299
1292
  onMouseDown(t) {
1300
1293
  this.container.classList.add("ls-viewer-container-vrcube-grabbing"), this.interaction.start(y.pointFromMouseEvent(t), {
@@ -1327,9 +1320,9 @@ class tt {
1327
1320
  this.interaction.orientation(t.alpha, t.beta, t.gamma);
1328
1321
  }
1329
1322
  }
1330
- class et {
1323
+ class tt {
1331
1324
  constructor(t, e, i, s, r) {
1332
- this.isStarted = !1, this.position = t, this.frames = e, this.rows = i, this.loop = s, this.onMotion = r, this.inertia = new G(this.motion.bind(this)), this.initPosition = { ...this.position }, this.startPosition = { x: 0, y: 0 }, this.startPoint = new I(0, 0), this.startSize = { width: 0, height: 0 }, this.lastPoints = [], this.lastPointsNumber = 20;
1325
+ this.isStarted = !1, this.position = t, this.frames = e, this.rows = i, this.loop = s, this.onMotion = r, this.inertia = new q(this.motion.bind(this)), this.initPosition = { ...this.position }, this.startPosition = { x: 0, y: 0 }, this.startPoint = new I(0, 0), this.startSize = { width: 0, height: 0 }, this.lastPoints = [], this.lastPointsNumber = 20;
1333
1326
  }
1334
1327
  destroy() {
1335
1328
  this.inertia.destroy();
@@ -1351,7 +1344,7 @@ class et {
1351
1344
  }
1352
1345
  motion(t) {
1353
1346
  this.isStarted && this.inertia.track(t), this.lastPoints.push({ x: t.x, y: t.y }), this.lastPoints.splice(0, this.lastPoints.length - this.lastPointsNumber);
1354
- const e = U.linear(this.lastPoints.map((s) => [s.x, s.y])), i = 25;
1347
+ const e = $.linear(this.lastPoints.map((s) => [s.x, s.y])), i = 25;
1355
1348
  if (Math.abs(e.equation[0]) < 1) {
1356
1349
  const s = w.accelerate(t.x - this.startPoint.x, 1.3) / this.startSize.width * (this.frames / 4);
1357
1350
  let r = this.startPosition.x - Math.round(s);
@@ -1370,9 +1363,9 @@ class et {
1370
1363
  this.isStarted = !1, e && (this.inertia.track(t), this.inertia.start());
1371
1364
  }
1372
1365
  }
1373
- class C {
1366
+ class O {
1374
1367
  constructor(t, e, i, s) {
1375
- this.container = t, this.canvas = e, this.loader = i, this.images = [], this.frames = 24, this.hotspotsList = [[]], this.interaction = new et({ x: 0, y: 0 }, 1, 1, !1, () => {
1368
+ this.container = t, this.canvas = e, this.loader = i, this.images = [], this.frames = 24, this.hotspotsList = [[]], this.interaction = new tt({ x: 0, y: 0 }, 1, 1, !1, () => {
1376
1369
  this.canvas.draw(this.image, !0, 0.5), this.onInteraction({
1377
1370
  position: this.interaction.positionIndex
1378
1371
  });
@@ -1416,10 +1409,10 @@ class C {
1416
1409
  const n = JSON.stringify(t);
1417
1410
  n === this.snapshotHash && this.image ? r = r.then(() => this.canvas.draw(this.image, s, 0.05)) : (this.images = [], r = r.then(
1418
1411
  () => this.loader.loadVRObjectSnapshot(t, this.interaction.positionIndex).then((o) => {
1419
- const d = o.length;
1420
- return this.images = new Array(d), this.interaction.frames = t.view.frames ?? t.view.panFrames ?? this.frames, this.interaction.rows = d / this.interaction.frames, this.interaction.loop = !!t.view.loop, i && this.interaction.reset(), o.forEach((u, f) => {
1421
- u.then((c) => {
1422
- this.images[f] = c, c === this.image && this.canvas.draw(this.image, s, 0.05);
1412
+ const l = o.length;
1413
+ return this.images = new Array(l), this.interaction.frames = t.view.frames ?? t.view.panFrames ?? this.frames, this.interaction.rows = l / this.interaction.frames, this.interaction.loop = !!t.view.loop, i && this.interaction.reset(), o.forEach((u, f) => {
1414
+ u.then((d) => {
1415
+ this.images[f] = d, d === this.image && this.canvas.draw(this.image, s, 0.05);
1423
1416
  }).catch(() => {
1424
1417
  });
1425
1418
  }), o[this.interaction.positionIndex].then(() => Promise.resolve());
@@ -1472,7 +1465,7 @@ class C {
1472
1465
  onDeviceOrientation(t) {
1473
1466
  }
1474
1467
  }
1475
- class it {
1468
+ class et {
1476
1469
  constructor(t, e, i) {
1477
1470
  this.container = t, this.loader = i, this.video = e;
1478
1471
  }
@@ -1556,7 +1549,7 @@ class nt {
1556
1549
  onHotspotsChange: () => {
1557
1550
  },
1558
1551
  ...e.events
1559
- }, this.options.events.onLoadError = k(this.options.events.onLoadError, 10), this.container = t, this.container.classList.add("ls-viewer-container"), this.containerWidth = 0, this.containerHeight = 0, this.canvas2D = new N(this.options.fit), this.container.prepend(this.canvas2D.element), this.canvas3D = new B(), this.container.prepend(this.canvas3D.element), this.video = new J(), this.container.prepend(this.video.element), this.loader = new D(this.options.server, this.options.api, this), this.resolution = new b(0, 0), this.parameters = {
1552
+ }, this.options.events.onLoadError = k(this.options.events.onLoadError, 10), this.container = t, this.container.classList.add("ls-viewer-container"), this.containerWidth = 0, this.containerHeight = 0, this.canvas2D = new U(this.options.fit), this.container.prepend(this.canvas2D.element), this.canvas3D = new N(), this.container.prepend(this.canvas3D.element), this.video = new Y(), this.container.prepend(this.video.element), this.loader = new D(this.options.server, this.options.api, this), this.resolution = new b(0, 0), this.parameters = {
1560
1553
  width: 0,
1561
1554
  height: 0,
1562
1555
  antialiasing: !1,
@@ -1564,14 +1557,14 @@ class nt {
1564
1557
  }, this.encoder = {
1565
1558
  format: "jpeg",
1566
1559
  quality: 80
1567
- }, this.hotspots = [], this.widgetImage = new Z(t, this.canvas2D, this.loader), this.widgetVideo = new it(t, this.video, this.loader), this.widgetVRObject = new C(t, this.canvas2D, this.loader, this.onVrobjectInteraction), this.canvas3D.context && (this.widgetVRCube = new tt(t, this.canvas3D, this.loader, this.onVrcubeInteraction)), this.widget = this.widgetImage, this.isDestroyed = !1, this.container.addEventListener("mousedown", this.onMouseDown), this.container.addEventListener("mouseenter", this.onMouseEnter), this.container.addEventListener("touchstart", this.onTouchStart), document.addEventListener("mousemove", this.onMouseMove, { passive: !1 }), document.addEventListener("mouseup", this.onMouseUp), document.addEventListener("touchmove", this.onTouchMove, { passive: !1 }), document.addEventListener("touchend", this.onTouchEnd), this.loadWidget = k(this.loadWidget, 10), this.onResize = k(this.onResize, 250), requestAnimationFrame(this.checkResize);
1560
+ }, this.hotspots = [], this.widgetImage = new J(t, this.canvas2D, this.loader), this.widgetVideo = new et(t, this.video, this.loader), this.widgetVRObject = new O(t, this.canvas2D, this.loader, this.onVrobjectInteraction), this.canvas3D.context && (this.widgetVRCube = new K(t, this.canvas3D, this.loader, this.onVrcubeInteraction)), this.widget = this.widgetImage, this.isDestroyed = !1, this.container.addEventListener("mousedown", this.onMouseDown), this.container.addEventListener("mouseenter", this.onMouseEnter), this.container.addEventListener("touchstart", this.onTouchStart), document.addEventListener("mousemove", this.onMouseMove, { passive: !1 }), document.addEventListener("mouseup", this.onMouseUp), document.addEventListener("touchmove", this.onTouchMove, { passive: !1 }), document.addEventListener("touchend", this.onTouchEnd), this.loadWidget = k(this.loadWidget, 10), this.onResize = k(this.onResize, 250), requestAnimationFrame(this.checkResize);
1568
1561
  }
1569
1562
  destroy() {
1570
1563
  this.canvas2D.destroy(), this.container.removeEventListener("mousedown", this.onMouseDown), this.container.removeEventListener("mouseenter", this.onMouseEnter), this.container.removeEventListener("touchstart", this.onTouchStart), document.removeEventListener("mousemove", this.onMouseMove), document.removeEventListener("mouseup", this.onMouseUp), document.removeEventListener("touchmove", this.onTouchMove), document.removeEventListener("touchend", this.onTouchEnd), this.isDestroyed = !0;
1571
1564
  }
1572
1565
  async load(t, e) {
1573
1566
  let i = Promise.resolve();
1574
- return e != null && e.animation && (i = i.then(() => this.loadAnimation(e.animation))), this.view && (e == null ? void 0 : e.fromPosition) !== void 0 && this.viewWidget instanceof C && (this.view.mode, i = i.then(() => this.viewWidget.goto(e.fromPosition))), e != null && e.animation && (i = i.then(() => this.widgetVideo.play())), i = i.then(() => (this.scene = Array.isArray(t) ? [...t] : [t], this.loadWidget(!1, !(e && e.animation)))), i.catch((s) => {
1567
+ return e?.animation && (i = i.then(() => this.loadAnimation(e.animation))), this.view && e?.fromPosition !== void 0 && this.viewWidget instanceof O && (this.view.mode, i = i.then(() => this.viewWidget.goto(e.fromPosition))), e?.animation && (i = i.then(() => this.widgetVideo.play())), i = i.then(() => (this.scene = Array.isArray(t) ? [...t] : [t], this.loadWidget(!1, !(e && e.animation)))), i.catch((s) => {
1575
1568
  this.onLoadError(s);
1576
1569
  }), i;
1577
1570
  }
@@ -1594,9 +1587,9 @@ class nt {
1594
1587
  }
1595
1588
  async setView(t, e) {
1596
1589
  let i = Promise.resolve();
1597
- return e != null && e.animation && (i = i.then(() => this.loadAnimation(e.animation))), this.view && (e == null ? void 0 : e.fromPosition) !== void 0 && this.viewWidget instanceof C && (i = i.then(() => this.viewWidget.goto(e.fromPosition))), e != null && e.animation && (i = i.then(() => this.widgetVideo.play())), i = i.then(() => {
1590
+ return e?.animation && (i = i.then(() => this.loadAnimation(e.animation))), this.view && e?.fromPosition !== void 0 && this.viewWidget instanceof O && (i = i.then(() => this.viewWidget.goto(e.fromPosition))), e?.animation && (i = i.then(() => this.widgetVideo.play())), i = i.then(() => {
1598
1591
  let s = !0;
1599
- return this.view = { ...t }, this.view && this.viewWidget instanceof C && (e == null ? void 0 : e.toPosition) !== void 0 && (s = !1, this.viewWidget.position = e.toPosition), this.loadWidget(s, !(e && e.animation));
1592
+ return this.view = { ...t }, this.view && this.viewWidget instanceof O && e?.toPosition !== void 0 && (s = !1, this.viewWidget.position = e.toPosition), this.loadWidget(s, !(e && e.animation));
1600
1593
  }), i.catch((s) => {
1601
1594
  this.onLoadError(s);
1602
1595
  }), i;
@@ -1608,7 +1601,6 @@ class nt {
1608
1601
  Object.assign(this.widgetVRObject, t);
1609
1602
  }
1610
1603
  async loadAnimation(t) {
1611
- var i;
1612
1604
  const e = {
1613
1605
  scene: this.scene,
1614
1606
  view: {
@@ -1623,7 +1615,7 @@ class nt {
1623
1615
  format: "mp4"
1624
1616
  }
1625
1617
  };
1626
- return (i = e.view) != null && i.background || (e.view.background = "product"), this.widgetVideo.load(e).then(() => Promise.resolve());
1618
+ return e.view?.background || (e.view.background = "product"), this.widgetVideo.load(e).then(() => Promise.resolve());
1627
1619
  }
1628
1620
  async playAnimation(t) {
1629
1621
  return this.loadAnimation(t).then(() => this.widgetVideo.play()).catch((e) => {
@@ -1672,8 +1664,7 @@ class nt {
1672
1664
  });
1673
1665
  }
1674
1666
  get viewWidget() {
1675
- var t;
1676
- switch ((t = this.view) == null ? void 0 : t.mode) {
1667
+ switch (this.view?.mode) {
1677
1668
  case "image":
1678
1669
  return this.widgetImage;
1679
1670
  case "video":
@@ -1747,7 +1738,7 @@ class nt {
1747
1738
  this.container.classList.remove("ls-viewer-container-loading"), this.options.events.onLoadError(...t);
1748
1739
  }
1749
1740
  }
1750
- var H;
1741
+ var j;
1751
1742
  ((v) => {
1752
1743
  ((t) => {
1753
1744
  t.Visible = "Visible", t.Occluded = "Occluded", t.Clipped = "Clipped", t.OutOfFrustum = "OutOfFrustum";
@@ -1760,12 +1751,12 @@ var H;
1760
1751
  })(v.SunUseCaseMode || (v.SunUseCaseMode = {})), ((t) => {
1761
1752
  t.ShowOnly = "showOnly", t.HideOnly = "hideOnly";
1762
1753
  })(v.SurfacesFilterMode || (v.SurfacesFilterMode = {}));
1763
- })(H || (H = {}));
1754
+ })(j || (j = {}));
1764
1755
  export {
1765
1756
  nt as Viewer,
1766
- H as WRAPIv2,
1767
- Z as WidgetImage,
1768
- tt as WidgetVRCube,
1769
- C as WidgetVRObject,
1770
- it as WidgetVideo
1757
+ j as WRAPIv2,
1758
+ J as WidgetImage,
1759
+ K as WidgetVRCube,
1760
+ O as WidgetVRObject,
1761
+ et as WidgetVideo
1771
1762
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumiscaphe/viewer",
3
- "version": "4.1.15",
3
+ "version": "4.1.16",
4
4
  "description": "Lumiscaphe 3D Viewer",
5
5
  "type": "module",
6
6
  "main": "dist/lib/index.cjs",
@@ -18,20 +18,20 @@
18
18
  "dependencies": {
19
19
  "debounce-promise": "~3.1.0",
20
20
  "regression": "~2.0.0",
21
- "twgl.js": "~5.5.0"
21
+ "twgl.js": "~7.0.0"
22
22
  },
23
23
  "devDependencies": {
24
24
  "@types/debounce-promise": "~3.1.3",
25
- "@types/node": "~22.13.0",
25
+ "@types/node": "~24.0.0",
26
26
  "@types/regression": "~2.0.0",
27
- "eslint": "~9.23.0",
27
+ "eslint": "~9.39.0",
28
28
  "husky": "~9.1.0",
29
- "typescript": "~5.8.0",
30
- "typescript-eslint": "~8.28.0",
31
- "vite": "~6.2.0",
29
+ "typescript": "~5.9.0",
30
+ "typescript-eslint": "~8.52.0",
31
+ "vite": "~7.3.0",
32
32
  "vite-plugin-css-injected-by-js": "~3.5.0",
33
33
  "vite-plugin-dts": "~4.5.0",
34
34
  "vite-plugin-eslint": "~1.8.0",
35
- "vite-plugin-glsl": "~1.3.0"
35
+ "vite-plugin-glsl": "~1.5.0"
36
36
  }
37
37
  }