@virtualdisplay.io/client 4.0.0-alpha.1 → 4.0.0-alpha.11
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/CHANGELOG.md +74 -0
- package/README.md +105 -157
- package/dist/browser-CDLfpTNV.cjs +8 -0
- package/dist/browser-DxtIwHNu.js +1227 -0
- package/dist/chunk-BcutgqC9.cjs +1 -0
- package/dist/chunk-C_CI6nMA.js +13 -0
- package/dist/src/annotations/annotations.d.ts +20 -0
- package/dist/src/annotations/annotations.d.ts.map +1 -0
- package/dist/src/annotations/index.d.ts +2 -0
- package/dist/src/annotations/index.d.ts.map +1 -0
- package/dist/src/attributes/attribute.d.ts +38 -0
- package/dist/src/attributes/attribute.d.ts.map +1 -0
- package/dist/src/attributes/attributes.d.ts +43 -0
- package/dist/src/attributes/attributes.d.ts.map +1 -0
- package/dist/src/attributes/selections.d.ts +16 -0
- package/dist/src/attributes/selections.d.ts.map +1 -0
- package/dist/src/attributes/value.d.ts +13 -0
- package/dist/src/attributes/value.d.ts.map +1 -0
- package/dist/src/camera/camera.d.ts +40 -0
- package/dist/src/camera/camera.d.ts.map +1 -0
- package/dist/src/camera/index.d.ts +4 -0
- package/dist/src/camera/index.d.ts.map +1 -0
- package/dist/src/camera/position.d.ts +56 -0
- package/dist/src/camera/position.d.ts.map +1 -0
- package/dist/src/client/client.d.ts +51 -0
- package/dist/src/client/client.d.ts.map +1 -0
- package/dist/src/client/error.d.ts +26 -0
- package/dist/src/client/error.d.ts.map +1 -0
- package/dist/src/client/iframe-builder.d.ts +27 -0
- package/dist/src/client/iframe-builder.d.ts.map +1 -0
- package/dist/src/client/options.d.ts +19 -0
- package/dist/src/client/options.d.ts.map +1 -0
- package/dist/src/client/ready-state-tracker.d.ts +13 -0
- package/dist/src/client/ready-state-tracker.d.ts.map +1 -0
- package/dist/src/client/types.d.ts +19 -0
- package/dist/src/client/types.d.ts.map +1 -0
- package/dist/src/index.d.ts +12 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/snapshot/index.d.ts +3 -0
- package/dist/src/snapshot/index.d.ts.map +1 -0
- package/dist/src/snapshot/photo.d.ts +47 -0
- package/dist/src/snapshot/photo.d.ts.map +1 -0
- package/dist/src/snapshot/snapshot.d.ts +30 -0
- package/dist/src/snapshot/snapshot.d.ts.map +1 -0
- package/dist/src/ui/action-bar.d.ts +18 -0
- package/dist/src/ui/action-bar.d.ts.map +1 -0
- package/dist/src/ui/camera-controls.d.ts +8 -0
- package/dist/src/ui/camera-controls.d.ts.map +1 -0
- package/dist/src/ui/controls/attribute-group.d.ts +6 -0
- package/dist/src/ui/controls/attribute-group.d.ts.map +1 -0
- package/dist/src/ui/event-bus.d.ts +12 -0
- package/dist/src/ui/event-bus.d.ts.map +1 -0
- package/dist/src/ui/loading.d.ts +43 -0
- package/dist/src/ui/loading.d.ts.map +1 -0
- package/dist/src/ui/standard-interface.d.ts +41 -0
- package/dist/src/ui/standard-interface.d.ts.map +1 -0
- package/dist/src/ui/styles.d.ts +3 -0
- package/dist/src/ui/styles.d.ts.map +1 -0
- package/dist/src/utils/logger.d.ts +11 -0
- package/dist/src/utils/logger.d.ts.map +1 -0
- package/dist/virtualdisplay.client.cjs.js +303 -2
- package/dist/virtualdisplay.client.es.js +2213 -2
- package/dist/virtualdisplay.client.umd.js +310 -2
- package/package.json +3 -3
- package/dist/index.d.ts +0 -415
- package/dist/virtualdisplay.client.cjs.js.map +0 -1
- package/dist/virtualdisplay.client.es.js.map +0 -1
- package/dist/virtualdisplay.client.umd.js.map +0 -1
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Camera, CameraPosition } from '../camera';
|
|
2
|
+
export declare class CameraControls {
|
|
3
|
+
readonly element: HTMLElement;
|
|
4
|
+
constructor(camera: Camera, position: CameraPosition);
|
|
5
|
+
private static buildZoom;
|
|
6
|
+
private static buildDpad;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=camera-controls.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"camera-controls.d.ts","sourceRoot":"","sources":["../../../src/ui/camera-controls.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAuB,MAAM,WAAW,CAAC;AAY7E,qBAAa,cAAc;IACzB,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;gBAElB,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc;IAuBpD,OAAO,CAAC,MAAM,CAAC,SAAS;IAQxB,OAAO,CAAC,MAAM,CAAC,SAAS;CAiBzB"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { AttributeDefinition } from '@virtualdisplay.io/messaging';
|
|
2
|
+
import { Attributes } from '../../attributes/attributes';
|
|
3
|
+
import { AttributeValue } from '../../attributes/value';
|
|
4
|
+
import { UiEventBus } from '../event-bus';
|
|
5
|
+
export declare function buildAttributeGroup(def: AttributeDefinition, attributes: Attributes, eventBus: UiEventBus, onSelect: (name: string, value: string) => void, onSubscribe: (name: string, callback: (v: AttributeValue) => void) => void): HTMLElement;
|
|
6
|
+
//# sourceMappingURL=attribute-group.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attribute-group.d.ts","sourceRoot":"","sources":["../../../../src/ui/controls/attribute-group.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAU/C,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,mBAAmB,EACxB,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,UAAU,EACpB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,EAC/C,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,cAAc,KAAK,IAAI,KAAK,IAAI,GACzE,WAAW,CA4Bb"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { VirtualdisplayUiEventMap, VirtualdisplayUiEventType } from '../client/types';
|
|
2
|
+
/**
|
|
3
|
+
* Dispatches and subscribes to UI events on the client container element.
|
|
4
|
+
* These are DOM CustomEvents for developers — not postMessages to the server.
|
|
5
|
+
*/
|
|
6
|
+
export declare class UiEventBus {
|
|
7
|
+
private container;
|
|
8
|
+
attach(container: HTMLElement): void;
|
|
9
|
+
dispatch<T extends VirtualdisplayUiEventType>(type: T, detail: Omit<VirtualdisplayUiEventMap[T], 'preventDefault'>, cancelable?: boolean): CustomEvent;
|
|
10
|
+
on<T extends VirtualdisplayUiEventType>(type: T, callback: (event: VirtualdisplayUiEventMap[T]) => void): () => void;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=event-bus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-bus.d.ts","sourceRoot":"","sources":["../../../src/ui/event-bus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,yBAAyB,EAC1B,MAAM,iBAAiB,CAAC;AAEzB;;;GAGG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,SAAS,CAA4B;IAE7C,MAAM,CAAC,SAAS,EAAE,WAAW,GAAG,IAAI;IAIpC,QAAQ,CAAC,CAAC,SAAS,yBAAyB,EAC1C,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC,EAC3D,UAAU,UAAQ,GACjB,WAAW;IAMd,EAAE,CAAC,CAAC,SAAS,yBAAyB,EACpC,IAAI,EAAE,CAAC,EACP,QAAQ,EAAE,CAAC,KAAK,EAAE,wBAAwB,CAAC,CAAC,CAAC,KAAK,IAAI,GACrD,MAAM,IAAI;CASd"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loading indicator with building-cube wireframe animation.
|
|
3
|
+
*
|
|
4
|
+
* Self-contained overlay that shows during model loading.
|
|
5
|
+
* The cube edges draw → hold → reverse → pause in a loop.
|
|
6
|
+
*
|
|
7
|
+
* Supports delayed showing — only becomes visible if loading
|
|
8
|
+
* takes longer than the configured threshold.
|
|
9
|
+
*/
|
|
10
|
+
export interface LoadingIndicatorConfig {
|
|
11
|
+
showDelay?: number;
|
|
12
|
+
}
|
|
13
|
+
export declare class LoadingIndicator {
|
|
14
|
+
private readonly overlay;
|
|
15
|
+
private readonly canvas;
|
|
16
|
+
private readonly ctx;
|
|
17
|
+
private readonly pctEl;
|
|
18
|
+
private readonly phaseEl;
|
|
19
|
+
private animationId;
|
|
20
|
+
private showTimerId;
|
|
21
|
+
private readonly startTime;
|
|
22
|
+
private hidden;
|
|
23
|
+
private visible;
|
|
24
|
+
constructor(container: HTMLElement, config?: LoadingIndicatorConfig);
|
|
25
|
+
get loadingTexts(): {
|
|
26
|
+
downloading: string;
|
|
27
|
+
rendering: string;
|
|
28
|
+
};
|
|
29
|
+
updateProgress(pct: number, status: string): void;
|
|
30
|
+
/**
|
|
31
|
+
* Show an error state — stops animation and displays the error message.
|
|
32
|
+
* The overlay stays visible so the user knows something went wrong.
|
|
33
|
+
*/
|
|
34
|
+
showError(message: string): void;
|
|
35
|
+
hide(): void;
|
|
36
|
+
destroy(): void;
|
|
37
|
+
private reveal;
|
|
38
|
+
private cancelShowTimer;
|
|
39
|
+
private sizeCanvas;
|
|
40
|
+
private tick;
|
|
41
|
+
private drawFrame;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=loading.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loading.d.ts","sourceRoot":"","sources":["../../../src/ui/loading.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAkEH,MAAM,WAAW,sBAAsB;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAoDD,qBAAa,gBAAgB;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;IAC3C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAkC;IACtD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkB;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;IAC1C,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,WAAW,CAA8C;IACjE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;gBAEZ,SAAS,EAAE,WAAW,EAAE,MAAM,GAAE,sBAA2B;IAsBvE,IAAI,YAAY,IAAI;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAK7D;IAED,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAQjD;;;OAGG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IA2BhC,IAAI,IAAI,IAAI;IAqBZ,OAAO,IAAI,IAAI;IASf,OAAO,CAAC,MAAM;IAQd,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,IAAI,CAMV;IAEF,OAAO,CAAC,SAAS;CAmDpB"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ViewerSettings, AttributeDefinition } from '@virtualdisplay.io/messaging';
|
|
2
|
+
import { Snapshot } from '../snapshot';
|
|
3
|
+
import { Camera, CameraPosition } from '../camera';
|
|
4
|
+
import { Attributes } from '../attributes/attributes';
|
|
5
|
+
import { AttributeValue } from '../attributes/value';
|
|
6
|
+
import { UiEventBus } from './event-bus';
|
|
7
|
+
export interface StandardInterfaceOptions {
|
|
8
|
+
snapshotApi: Snapshot;
|
|
9
|
+
cameraApi: Camera;
|
|
10
|
+
cameraPositionApi: CameraPosition;
|
|
11
|
+
eventBus: UiEventBus;
|
|
12
|
+
onSelect: (name: string, value: string) => void;
|
|
13
|
+
onSubscribe: (name: string, callback: (v: AttributeValue) => void) => void;
|
|
14
|
+
onAr?: () => void;
|
|
15
|
+
}
|
|
16
|
+
export declare class StandardInterface {
|
|
17
|
+
private readonly options;
|
|
18
|
+
private settings;
|
|
19
|
+
private container;
|
|
20
|
+
private loading;
|
|
21
|
+
private slots;
|
|
22
|
+
private screenshotBtn;
|
|
23
|
+
private actionBar;
|
|
24
|
+
private cameraControls;
|
|
25
|
+
private attributes;
|
|
26
|
+
constructor(options: StandardInterfaceOptions);
|
|
27
|
+
attach(container: HTMLElement): void;
|
|
28
|
+
onReady(): void;
|
|
29
|
+
private mountToolbar;
|
|
30
|
+
private toggleFullscreen;
|
|
31
|
+
updateProgress(progress: number, phase: string): void;
|
|
32
|
+
showError(message: string): void;
|
|
33
|
+
applyViewerSettings(settings: ViewerSettings): void;
|
|
34
|
+
renderAttributeControls(attributes: Attributes, definitions: AttributeDefinition[]): void;
|
|
35
|
+
get viewerSettings(): ViewerSettings;
|
|
36
|
+
destroy(): void;
|
|
37
|
+
private createSlot;
|
|
38
|
+
private syncScreenshotButton;
|
|
39
|
+
private placeScreenshotButton;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=standard-interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"standard-interface.d.ts","sourceRoot":"","sources":["../../../src/ui/standard-interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAKxF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAc9C,MAAM,WAAW,wBAAwB;IACvC,WAAW,EAAE,QAAQ,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,cAAc,CAAC;IAClC,QAAQ,EAAE,UAAU,CAAC;IACrB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,cAAc,KAAK,IAAI,KAAK,IAAI,CAAC;IAC3E,IAAI,CAAC,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IACnD,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,SAAS,CAA4B;IAC7C,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,KAAK,CAA6H;IAC1I,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,UAAU,CAA4B;gBAElC,OAAO,EAAE,wBAAwB;IAI7C,MAAM,CAAC,SAAS,EAAE,WAAW,GAAG,IAAI;IAYpC,OAAO,IAAI,IAAI;IAQf,OAAO,CAAC,YAAY;IAwBpB,OAAO,CAAC,gBAAgB;IASxB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAIrD,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIhC,mBAAmB,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI;IAanD,uBAAuB,CAAC,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,mBAAmB,EAAE,GAAG,IAAI;IAqCzF,IAAI,cAAc,IAAI,cAAc,CAA0B;IAE9D,OAAO,IAAI,IAAI;IAWf,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,oBAAoB;IAoB5B,OAAO,CAAC,qBAAqB;CAQ9B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../src/ui/styles.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,MAAM,QAsFlB,CAAC;AAEF,wBAAgB,YAAY,IAAI,IAAI,CAOnC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type Attrs = Record<string, unknown> | unknown;
|
|
2
|
+
export declare let logger: {
|
|
3
|
+
debug: (msg: string, attrs?: Attrs) => void;
|
|
4
|
+
info: (msg: string, attrs?: Attrs) => void;
|
|
5
|
+
warn: (msg: string, attrs?: Attrs) => void;
|
|
6
|
+
error: (msg: string, attrs?: Attrs) => void;
|
|
7
|
+
};
|
|
8
|
+
export declare function enableDebugMode(): void;
|
|
9
|
+
export declare function isDebugMode(): boolean;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/utils/logger.ts"],"names":[],"mappings":"AAEA,KAAK,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;AA4B/C,eAAO,IAAI,MAAM;iBAbF,MAAM,UAAU,KAAK;gBACtB,MAAM,UAAU,KAAK;gBACrB,MAAM,UAAU,KAAK;iBACpB,MAAM,UAAU,KAAK;CAU4C,CAAC;AAEjF,wBAAgB,eAAe,IAAI,IAAI,CAGtC;AAED,wBAAgB,WAAW,IAAI,OAAO,CAErC"}
|
|
@@ -1,2 +1,303 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e={NO_MAPPING:"NO_MAPPING",ATTRIBUTE_NOT_FOUND:"ATTRIBUTE_NOT_FOUND",VALUE_NOT_FOUND:"VALUE_NOT_FOUND",PARENT_NOT_FOUND:"PARENT_NOT_FOUND",INVALID_PARAMETER:"INVALID_PARAMETER",SNAPSHOT_FAILED:"SNAPSHOT_FAILED"};class t extends Error{code;constructor(e,s){super(e),this.name="VirtualdisplayError",this.code=s,void 0!==Error.captureStackTrace&&Error.captureStackTrace(this,t)}static noMapping(){return new t("No attributes available. Waiting for server metadata.",e.NO_MAPPING)}static attributeNotFound(s){return new t(`Attribute "${s}" not found in mapping`,e.ATTRIBUTE_NOT_FOUND)}static valueNotFound(s,i){return new t(`Value "${i}" not found for attribute "${s}"`,e.VALUE_NOT_FOUND)}static parentNotFound(s){return new t(`Parent element not found: ${s}`,e.PARENT_NOT_FOUND)}static invalidParameter(s){return new t(s,e.INVALID_PARAMETER)}static snapshotFailed(s,i){return new t(`Snapshot failed for "${s}": ${i}`,e.SNAPSHOT_FAILED)}}const s={};class i{defaultServer="https://server.virtualdisplay.io";options;constructor(e){this.options=e}create(){const e=this.createIframe();return this.attachToParent(e),e}createIframe(){const e=document.createElement("iframe");return e.src=this.buildUrl(),Object.assign(e.style,{width:"100%",height:"100%",border:"none"}),e.setAttribute("allow","xr-spatial-tracking; fullscreen"),e}attachToParent(e){this.getParentElement().appendChild(e)}buildUrl(){const e=this.getServerUrl(),t=new URL(e);return t.searchParams.set("license",this.options.license),t.searchParams.set("model",this.options.model),!0===this.options.debug&&t.searchParams.set("debug","true"),void 0!==this.options.language&&t.searchParams.set("language",this.options.language),t.toString()}getServerUrl(){if(void 0===s?.VITE_VIRTUALDISPLAY_SERVER_HOST)return this.defaultServer}getParentElement(){if("string"!=typeof this.options.parent)return this.options.parent;const e=document.querySelector(this.options.parent);if(null===e)throw t.parentNotFound(this.options.parent);return e}}function n(e,t){const s=t?function(e){const t=new Date(e.timestamp).toLocaleTimeString("en-GB",{hour12:!1}),s=e.level.toUpperCase().padEnd(5),i=e.trace_id?.slice(0,8)??"--------",n=e.msg,r=["timestamp","level","msg","service","trace_id","span_id"],a=Object.entries(e).filter(([e])=>!r.includes(e)).map(([e,t])=>`${e}=${JSON.stringify(t)}`).join(" ");return`${t} ${s} [${i}] ${n}${a?" "+a:""}`}(e):function(e){return JSON.stringify(e)}(e);"error"===e.level?console.error(s):"warn"===e.level?console.warn(s):console.log(s)}class r{constructor(e){this.config=e}log(e,t,s={}){const i=this.config.traceProvider?.()??{};var r;n({timestamp:(r=new Date,r.toISOString()),level:e,msg:t,service:this.config.service,...i,...s},this.config.isDev)}debug(e,t){this.config.isDev&&this.log("debug",e,t)}info(e,t){this.log("info",e,t)}warn(e,t){this.log("warn",e,t)}error(e,t){this.log("error",e,t)}with(e){const t=new r(this.config);return t.log=((t,s,i={})=>{this.log(t,s,{...e,...i})}).bind(this),t}}function a(e,t){const s=void 0!==t?.isDev?t.isDev:"undefined"==typeof process||"production"!==process.env.NODE_ENV;return new r({service:e,isDev:s,traceProvider:t?.traceProvider})}function o(e){if(void 0!==e)return"object"!=typeof e||null===e||Array.isArray(e)||e instanceof Error?e instanceof Error?{error:e.message}:{value:e}:e}function l(e){return{debug:(t,s)=>e.debug(t,o(s)),info:(t,s)=>e.info(t,o(s)),warn:(t,s)=>e.warn(t,o(s)),error:(t,s)=>e.error(t,o(s))}}let d=!1;function u(){d=!0,exports.logger=l(a("client",{isDev:!0}))}exports.logger=l(a("client",{isDev:!1}));class h{ready=!1;onReady;constructor(e){this.onReady=e}handleMappingReceived(){this.markReady("Mapping received from server")}handleMutationResult(e){e.isInitial&&this.markReady("Initial mutations processed")}get isReady(){return this.ready}clear(){this.ready=!1}markReady(e){this.ready||(this.ready=!0,exports.logger.info(`${e} - client is now ready`),this.onReady?.())}}class c{constructor(e,t){this.value=e,this.attribute=t}isSelectedValue=!1;get isSelected(){return this.isSelectedValue}setSelected(e){this.isSelectedValue=e}}class g{name;defaultValue;values;onSelect;onChangeCallback;constructor(e){this.name=e.name,this.defaultValue=e.defaultValue,this.onSelect=e.onSelect,this.values=this.createValues(e.values)}select(e){if(!this.values.has(e))throw t.valueNotFound(this.name,e);this.onSelect(this.name,e)}getValues(){return Array.from(this.values.values())}getValue(e){return this.values.get(e)}onChange(e){this.onChangeCallback=e}handleResult(e){let t;for(const s of this.values.values()){const i=s.value===e;s.setSelected(i),i&&(t=s)}void 0!==t&&void 0!==this.onChangeCallback&&this.onChangeCallback(t)}createValues(e){const t=new Map;for(const s of e){const e=new c(s,this.name);s===this.defaultValue&&e.setSelected(!0),t.set(s,e)}return t}}class p{attributes=new Map;constructor(e,t,s){for(const i of e){const e=this.buildOptions(i,t);this.attributes.set(i.name,new g(e))}this.onMutationFailed=s}onMutationFailed;get(e){return this.attributes.get(e)}defaults(){const e=[];for(const t of this.attributes.values())void 0!==t.defaultValue&&e.push({name:t.name,value:t.defaultValue});return e}handleResults(e){for(const t of e)t.success?this.get(t.name)?.handleResult(t.value):this.onMutationFailed?.(t.name,t.value)}buildOptions(e,t){const s={name:e.name,values:e.values,onSelect:(e,s)=>{t([{name:e,value:s}],!1)}};return void 0!==e.defaultValue?{...s,defaultValue:e.defaultValue}:s}}const f={READY:"ready",MUTATION:"mutation",STATE:"state",CONFIG:"config",CAMERA:"camera",SNAPSHOT:"snapshot",MAPPING:"mapping"},m=new Set(Object.values(f));function b(e){return"object"!=typeof e||null===e?null:e}class v{constructor(e){this.processor=e}pending=[];isReady=!1;enqueue(e){this.isReady?this.processor(e):this.pending.push(e)}markReady(){if(this.isReady)return;if(this.isReady=!0,0===this.pending.length)return;const e=[...this.pending];this.pending.length=0;for(const t of e)this.processor(t)}get ready(){return this.isReady}get pendingCount(){return this.pending.length}hasPending(e){return this.pending.some(t=>t.type===e)}clear(){this.pending.length=0}}class y{constructor(e,t){this.getTarget=e,this.sourceId=`vd-${Math.random().toString(36).slice(2,8)}`,this.publisher=new v(e=>this.post(e)),this.consumer=new v(e=>this.routeToHandler(e)),this.shouldBuffer=t?.shouldBuffer??null,!0!==t?.bufferIncoming&&this.consumer.markReady()}handlers=new Map;publisher;consumer;shouldBuffer;listener=null;sourceId;on(e,t){this.handlers.set(e,t)}off(e){this.handlers.delete(e)}send(e){this.publisher.enqueue(e)}markReady(){this.publisher.markReady()}markConsumerReady(){this.consumer.markReady()}consumerHasPending(e){return this.consumer.hasPending(e)}start(){null===this.listener&&(this.listener=e=>{const{data:t}=e;if(!function(e){if("object"!=typeof e||null===e)return!1;const t=e;return"string"!=typeof t.target&&"string"==typeof t.type&&m.has(t.type)}(t))return;if(t._source===this.sourceId)return;const s=t;null===this.shouldBuffer||this.shouldBuffer(s)?this.consumer.enqueue(s):this.routeToHandler(s)},window.addEventListener("message",this.listener))}destroy(){null!==this.listener&&(window.removeEventListener("message",this.listener),this.listener=null),this.publisher.clear(),this.consumer.clear(),this.handlers.clear()}get ready(){return this.publisher.ready}get pendingCount(){return this.publisher.pendingCount}post(e){const t=this.getTarget();null!==t&&t.postMessage({...e,_source:this.sourceId},"*")}routeToHandler(e){const t=this.handlers.get(e.type);if(void 0===t)return;const s=t(e);s instanceof Promise&&s.catch(t=>{const s=t instanceof Error?t.message:String(t);console.error(`Virtualdisplay: error handling ${e.type}: ${s}`)})}}class A{constructor(e,t){this.send=e,this.onMutationFailed=t}registry;pendingCallbacks=[];handleMappingReceived(e){exports.logger.debug("Initializing from server mapping",{attributeCount:e.attributes.length}),this.registry=new p(e.attributes,(e,t)=>this.sendMutation(e,t),this.onMutationFailed);const t=this.registry.defaults();t.length>0&&this.sendMutation(t,!0),this.replayPendingCallbacks()}handleMutationResult(e){this.registry?.handleResults(e.results)}select(e,t){this.sendMutation([{name:e,value:t}],!1)}getValues(e){return this.registry?.get(e)?.getValues()??[]}getValue(e,t){return this.registry?.get(e)?.getValue(t)}onChange(e,t){if(void 0===this.registry)return void this.pendingCallbacks.push({name:e,callback:t});const s=this.registry.get(e);void 0!==s?s.onChange(t):exports.logger.warn(`onChange: attribute "${e}" not found — callback will not fire`)}getAttribute(e){return this.registry?.get(e)}get hasMapping(){return void 0!==this.registry}sendMutation(e,t){const s={type:f.MUTATION,mutations:e,isInitial:t};this.send(s)}replayPendingCallbacks(){for(const{name:e,callback:t}of this.pendingCallbacks){const s=this.registry?.get(e);void 0===s&&exports.logger.warn(`onChange: attribute "${e}" not found — buffered callback will not fire`),s?.onChange(t)}this.pendingCallbacks.length=0}}class E{constructor(e){this.send=e}commands=[];rotate(e){return this.validateFiniteNumber(e,"rotate"),this.commands.push({action:"rotate",value:e}),this}tilt(e){return this.validateFiniteNumber(e,"tilt"),this.commands.push({action:"tilt",value:e}),this}zoom(e){return this.validateFiniteNumber(e,"zoom"),this.commands.push({action:"zoom",value:e}),this}set(){if(0===this.commands.length)throw t.invalidParameter("No camera commands to execute. Call rotate(), tilt(), or zoom() before set().");const e={type:f.CAMERA,commands:this.commands};this.send(e),this.commands=[]}validateFiniteNumber(e,s){if(!Number.isFinite(e))throw t.invalidParameter(`${s}() requires a finite number, got ${String(e)}`)}reset(){const e={type:f.CAMERA,commands:[{action:"reset"}]};this.send(e)}}class C{state;changeCallbacks=[];constructor(){this.state={rotation:0,tilt:0,zoom:0}}get rotation(){return this.state.rotation}get tilt(){return this.state.tilt}get zoom(){return this.state.zoom}onChange(e){this.changeCallbacks.push(e)}handlePositionUpdate(e){this.update(e.transforms)}update(e){let t=!1;for(const s of e)switch(s.type){case"rotation":this.state.rotation=s.value,t=!0;break;case"tilt":this.state.tilt=s.value,t=!0;break;case"zoom":this.state.zoom=s.value,t=!0}if(t){const e={rotation:this.rotation,tilt:this.tilt,zoom:this.zoom};for(const t of this.changeCallbacks)t(e)}}}class I{constructor(e){this.filename=e}developedCallbacks=new Set;errorCallbacks=new Set;developed=!1;failed=!1;photoData=null;onDeveloped(e){return this.developed&&null!==this.photoData?(e(this.photoData),this):(this.developedCallbacks.add(e),this)}onError(e){return this.errorCallbacks.add(e),this}getFilename(){return this.filename}develop(e){this.developed||this.failed||(this.photoData=e,this.developed=!0,this.developedCallbacks.forEach(e=>{e(this.photoData)}),this.developedCallbacks.clear(),this.errorCallbacks.clear())}fail(e){this.developed||this.failed||(this.failed=!0,this.errorCallbacks.forEach(t=>{t(e)}),this.developedCallbacks.clear(),this.errorCallbacks.clear())}}class w{constructor(e){this.send=e}validExtensions=[".png"];pendingPhotos=new Map;take(e){this.validateFilename(e),exports.logger.debug("Taking snapshot",{filename:e});const t=new I(e);return this.pendingPhotos.set(t.getFilename(),t),this.send({type:f.SNAPSHOT,filename:e}),t}handleSnapshotResult(s){const i=this.pendingPhotos.get(s.filename);void 0!==i?(this.pendingPhotos.delete(s.filename),void 0===s.error?void 0!==s.data&&i.develop({filename:s.filename,data:s.data}):i.fail(new t(s.error,e.SNAPSHOT_FAILED))):exports.logger.warn("No pending photo found for filename",{filename:s.filename,pendingFilenames:Array.from(this.pendingPhotos.keys())})}validateFilename(s){if(""===s||"string"!=typeof s)throw new t("Filename must be a non-empty string",e.INVALID_PARAMETER);if(!this.validExtensions.some(e=>s.toLowerCase().endsWith(e)))throw new t(`Invalid filename: "${s}". Filename must end with one of: ${this.validExtensions.join(", ")}`,e.INVALID_PARAMETER);if(s.includes("..")||s.includes("/")||s.includes("\\"))throw new t('Filename cannot contain path separators or ".."',e.INVALID_PARAMETER)}}class S{send;constructor(e){this.send=e}sendInitialConfig(e){const t=this.buildUIConfig(e),s=this.buildViewerConfig(t,e.camera);void 0!==s&&this.sendConfig(s)}buildUIConfig(e){const t=this.extractUIValues(e);if(Object.values(t).some(e=>void 0!==e))return{...void 0!==t.arEnabled&&{arEnabled:t.arEnabled},...void 0!==t.fullscreenEnabled&&{fullscreenEnabled:t.fullscreenEnabled},...void 0!==t.loadingIndicatorEnabled&&{loadingIndicatorEnabled:t.loadingIndicatorEnabled}}}extractUIValues(e){return{arEnabled:e.arEnabled??e.ui?.arEnabled,fullscreenEnabled:e.fullscreenEnabled??e.ui?.fullscreenEnabled,loadingIndicatorEnabled:e.loadingIndicatorEnabled??e.ui?.loadingIndicatorEnabled}}buildViewerConfig(e,t){if(void 0!==e||void 0!==t)return{...void 0!==e&&{ui:e},...void 0!==t&&{camera:t}}}setArEnabled(e){exports.logger.debug(`Setting AR button enabled: ${e}`),this.updateUIConfig({arEnabled:e})}setFullscreenEnabled(e){exports.logger.debug(`Setting fullscreen button enabled: ${e}`),this.updateUIConfig({fullscreenEnabled:e})}setLoadingIndicatorEnabled(e){exports.logger.debug(`Setting loading indicator enabled: ${e}`),this.updateUIConfig({loadingIndicatorEnabled:e})}updateUIConfig(e){exports.logger.debug("Updating UI configuration",e),Object.keys(e).length>0&&this.sendConfig({ui:e})}hideAllUI(){exports.logger.debug("Hiding all UI elements"),this.sendUIConfig({arEnabled:!1,fullscreenEnabled:!1,loadingIndicatorEnabled:!1})}showAllUI(){exports.logger.debug("Showing all UI elements"),this.sendUIConfig({arEnabled:!0,fullscreenEnabled:!0,loadingIndicatorEnabled:!0})}sendUIConfig(e){this.sendConfig({ui:e})}sendConfig(e){const t={type:f.CONFIG,config:e};exports.logger.debug("Sending config",t),this.send(t)}}exports.Attribute=g,exports.AttributeValue=c,exports.Camera=E,exports.ERROR_CODES=e,exports.Photo=I,exports.Snapshot=w,exports.VirtualdisplayClient=class{attributes;readyStateTracker;messenger;viewerService;cameraApi;cameraPositionApi;snapshotApi;options;iframe;readyCallbacks=[];mutationFailedCallbacks=[];constructor(e){this.options=e,this.initializeLogging(),this.messenger=new y(()=>this.iframe?.contentWindow??null);const t=e=>{this.messenger.send(e)};this.attributes=new A(t,(e,t)=>{for(const s of this.mutationFailedCallbacks)s({attribute:e,value:t})}),this.readyStateTracker=new h(()=>{const e=this.readyCallbacks;this.readyCallbacks=[];for(const t of e)t(this)}),this.viewerService=new S(t),this.cameraApi=new E(t),this.cameraPositionApi=new C,this.snapshotApi=new w(t),this.registerHandlers(),this.messenger.start(),this.createAndConnectIframe()}registerHandlers(){this.messenger.on(f.READY,e=>{(function(e){const t=b(e);return null!==t&&t.type===f.READY})(e)&&(exports.logger.info("Server ready — flushing publisher queue"),this.messenger.markReady(),this.viewerService.sendInitialConfig(this.options))}),this.messenger.on(f.MUTATION,e=>{(function(e){const t=b(e);return null!==t&&t.type===f.MUTATION&&Array.isArray(t.results)})(e)&&(this.attributes.handleMutationResult(e),this.readyStateTracker.handleMutationResult(e))}),this.messenger.on(f.SNAPSHOT,e=>{(function(e){const t=b(e);return null!==t&&t.type===f.SNAPSHOT&&("data"in t||"error"in t)})(e)&&this.snapshotApi.handleSnapshotResult(e)}),this.messenger.on(f.CAMERA,e=>{(function(e){const t=b(e);return null!==t&&t.type===f.CAMERA&&Array.isArray(t.transforms)})(e)&&this.cameraPositionApi.handlePositionUpdate(e)}),this.messenger.on(f.MAPPING,e=>{(function(e){const t=b(e);return null!==t&&t.type===f.MAPPING&&Array.isArray(t.attributes)})(e)&&(this.attributes.handleMappingReceived(e),this.readyStateTracker.handleMappingReceived())})}initializeLogging(){!0===this.options.debug&&u(),exports.logger.info("Initializing Virtualdisplay client",{model:this.options.model,debug:this.options.debug,language:this.options.language})}createAndConnectIframe(){exports.logger.debug("Creating iframe for Virtualdisplay viewer");const e=new i(this.options);this.iframe=e.create(),exports.logger.debug("Iframe created, waiting for server READY")}select(e,t){this.attributes.select(e,t)}getValues(e){return this.attributes.getValues(e)}getValue(e,t){return this.attributes.getValue(e,t)}onChange(e,t){this.attributes.onChange(e,t)}getAttribute(e){return this.attributes.getAttribute(e)}get isReady(){return this.readyStateTracker.isReady}onReady(e){this.readyStateTracker.isReady?e(this):this.readyCallbacks.push(e)}onMutationFailed(e){this.mutationFailedCallbacks.push(e)}get viewer(){return this.viewerService}get camera(){return this.cameraApi}get cameraPosition(){return this.cameraPositionApi}get snapshot(){return this.snapshotApi}destroy(){exports.logger.info("Destroying Virtualdisplay client"),this.readyStateTracker.clear(),this.readyCallbacks=[],this.messenger.destroy(),null!==this.iframe?.parentElement&&void 0!==this.iframe?.parentElement&&this.iframe.parentElement.removeChild(this.iframe),this.iframe=void 0,exports.logger.debug("Virtualdisplay client destroyed")}},exports.VirtualdisplayError=t,exports.VirtualdisplayViewerService=S,exports.enableDebugMode=u,exports.isDebugMode=function(){return d};
|
|
2
|
-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./chunk-BcutgqC9.cjs`);var t={NO_MAPPING:`NO_MAPPING`,ATTRIBUTE_NOT_FOUND:`ATTRIBUTE_NOT_FOUND`,VALUE_NOT_FOUND:`VALUE_NOT_FOUND`,PARENT_NOT_FOUND:`PARENT_NOT_FOUND`,INVALID_PARAMETER:`INVALID_PARAMETER`,SNAPSHOT_FAILED:`SNAPSHOT_FAILED`},n=class e extends Error{code;constructor(e,t){super(e),this.name=`VirtualdisplayError`,this.code=t}static noMapping(){return new e(`No attributes available. Waiting for server metadata.`,t.NO_MAPPING)}static attributeNotFound(n){return new e(`Attribute "${n}" not found in mapping`,t.ATTRIBUTE_NOT_FOUND)}static valueNotFound(n,r){return new e(`Value "${r}" not found for attribute "${n}"`,t.VALUE_NOT_FOUND)}static parentNotFound(n){return new e(`Parent element not found: ${n}`,t.PARENT_NOT_FOUND)}static invalidParameter(n){return new e(n,t.INVALID_PARAMETER)}static snapshotFailed(n,r){return new e(`Snapshot failed for "${n}": ${r}`,t.SNAPSHOT_FAILED)}},r=class{defaultServer=`https://server.virtualdisplay.io`;options;constructor(e){this.options=e}create(){let e=this.createContainer(),t=this.createIframe();return e.appendChild(t),this.attachToParent(e),{container:e,iframe:t}}createContainer(){let e=document.createElement(`div`);return e.className=`vd-container`,Object.assign(e.style,{position:`relative`,width:`100%`,height:`100%`,overflow:`hidden`}),e}createIframe(){let e=document.createElement(`iframe`);return e.src=this.buildUrl(),Object.assign(e.style,{width:`100%`,height:`100%`,border:`none`,display:`block`}),e.setAttribute(`allow`,`xr-spatial-tracking; fullscreen`),e}attachToParent(e){this.getParentElement().appendChild(e)}buildUrl(){let e=this.getServerUrl(),t=new URL(e);return t.searchParams.set(`license`,this.options.license),t.searchParams.set(`model`,this.options.model),this.options.language!==void 0&&t.searchParams.set(`language`,this.options.language),this.options.debug===!0&&t.searchParams.set(`debug`,`true`),this.options.traceparent!==void 0&&t.searchParams.set(`traceparent`,this.options.traceparent),t.toString()}getServerUrl(){return this.defaultServer}getParentElement(){if(typeof this.options.parent!=`string`)return this.options.parent;let e=document.querySelector(this.options.parent);if(e===null)throw n.parentNotFound(this.options.parent);return e}};function i(e){let t=new Date(e.timestamp).toLocaleTimeString(`en-GB`,{hour12:!1}),n=e.level.toUpperCase().padEnd(5),r=e.trace_id?.slice(0,8)??`--------`,i=e.msg,a=[`timestamp`,`level`,`msg`,`service`,`trace_id`,`span_id`],o=Object.entries(e).filter(([e])=>!a.includes(e)).map(([e,t])=>`${e}=${JSON.stringify(t)}`).join(` `);return`${t} ${n} [${r}] ${i}${o?` `+o:``}`}function a(e){return JSON.stringify(e)}function o(e,t){let n=t?i(e):a(e);e.level===`error`?console.error(n):e.level===`warn`?console.warn(n):console.log(n)}function s(e,t=0){let n={name:e.name,message:e.message};e.stack!==void 0&&(n.stack=e.stack);for(let t of Object.getOwnPropertyNames(e)){if(t===`name`||t===`message`||t===`stack`||t===`cause`)continue;let r=e[t];r!==void 0&&(n[t]=r)}return e.cause!==void 0&&e.cause!==null&&(n.cause=e.cause instanceof Error&&t<5?s(e.cause,t+1):String(e.cause)),n}function c(e){let t={};for(let[n,r]of Object.entries(e))t[n]=r instanceof Error?s(r):r;return t}function l(){return new Date}function u(e){return e.toISOString()}function d(){return typeof navigator>`u`?``:navigator.userAgent}function f(){return typeof navigator>`u`?!1:navigator.platform===`MacIntel`&&navigator.maxTouchPoints>1}function p(){return/iPhone|iPad|iPod/i.test(d())||f()}function m(){return/Android/i.test(d())}function h(){return p()||m()}var g=class e{constructor(e){this.config=e}log(e,t,n={}){let r=this.config.traceProvider?.()??{};o({timestamp:u(l()),level:e,msg:t,service:this.config.service,...r,...c(n)},this.config.isDev)}debug(e,t){this.config.isDev&&this.log(`debug`,e,t)}info(e,t){this.log(`info`,e,t)}warn(e,t){this.log(`warn`,e,t)}error(e,t){this.log(`error`,e,t)}with(t){let n=new e(this.config);return n.log=((e,n,r={})=>{this.log(e,n,{...t,...r})}).bind(this),n}};function _(e,t){return new g({service:e,isDev:t?.isDev===void 0?typeof process<`u`?process.env.NODE_ENV!==`production`:!0:t.isDev,traceProvider:t?.traceProvider})}function v(e){if(e!==void 0)return typeof e==`object`&&e&&!Array.isArray(e)&&!(e instanceof Error)?e:e instanceof Error?{error:e.message}:{value:e}}function ee(e){return{debug:(t,n)=>e.debug(t,v(n)),info:(t,n)=>e.info(t,v(n)),warn:(t,n)=>e.warn(t,v(n)),error:(t,n)=>e.error(t,v(n))}}var te=!1,y=ee(_(`client`,{isDev:!1}));function ne(){te=!0,y=ee(_(`client`,{isDev:!0}))}function re(){return te}var ie=class{ready=!1;onReady;constructor(e){this.onReady=e}handleMappingReceived(){this.ready||(this.ready=!0,y.info(`Mapping received from server, client is now ready`),this.onReady?.())}get isReady(){return this.ready}clear(){this.ready=!1}},b={HANDSHAKE:`handshake`,MUTATION:`mutation`,STATE:`state`,LOADING_INDICATOR:`loading_indicator`,CAMERA:`camera`,SNAPSHOT:`snapshot`,MAPPING:`mapping`,AR_ACTIVATE:`ar_activate`,CONFIG:`config`,INTERACTION:`interaction`,ANNOTATION_PLACE_MODE:`annotation_place_mode`,ANNOTATION_PLACED:`annotation_placed`,ANNOTATION_TOGGLE:`annotation_toggle`},ae=new Set(Object.values(b));function oe(e){if(typeof e!=`object`||!e)return!1;let t=e;return typeof t.target==`string`?!1:typeof t.type==`string`&&ae.has(t.type)}function se(e){let t=x(e);return t!==null&&t.type===b.HANDSHAKE}function ce(e){let t=x(e);return t!==null&&t.type===b.MUTATION&&Array.isArray(t.results)}function le(e){let t=x(e);return t!==null&&t.type===b.SNAPSHOT&&(`data`in t||`error`in t)}function ue(e){let t=x(e);return t!==null&&t.type===b.CAMERA&&Array.isArray(t.transforms)}function de(e){let t=x(e);return t!==null&&t.type===b.MAPPING&&Array.isArray(t.attributes)}function fe(e){let t=x(e);return t!==null&&t.type===b.LOADING_INDICATOR&&typeof t.progress==`number`}function pe(e){let t=x(e);return t!==null&&t.type===b.CONFIG&&typeof t.viewerSettings==`object`}function me(e){let t=x(e);return t!==null&&t.type===b.ANNOTATION_PLACED&&typeof t.position==`object`&&t.position!==null}function x(e){return typeof e!=`object`||!e?null:e}var he=class{pending=[];isReady=!1;constructor(e){this.processor=e}enqueue(e){if(this.isReady){this.processor(e);return}this.pending.push(e)}markReady(){if(this.isReady||(this.isReady=!0,this.pending.length===0))return;let e=[...this.pending];this.pending.length=0;for(let t of e)this.processor(t)}get ready(){return this.isReady}get pendingCount(){return this.pending.length}hasPending(e){return this.pending.some(t=>t.type===e)}clear(){this.pending.length=0}},ge=class{handlers=new Map;publisher;consumer;shouldBuffer;listener=null;sourceId;targetOrigin;constructor(e,t){this.getTarget=e,this.sourceId=`vd-${Math.random().toString(36).slice(2,8)}`,this.targetOrigin=t?.targetOrigin??`*`,this.publisher=new he(e=>this.post(e)),this.consumer=new he(e=>this.routeToHandler(e)),this.shouldBuffer=t?.shouldBuffer??null,t?.bufferIncoming!==!0&&this.consumer.markReady()}on(e,t){this.handlers.set(e,t)}off(e){this.handlers.delete(e)}setTargetOrigin(e){this.targetOrigin=e}send(e){this.publisher.enqueue(e)}markReady(){this.publisher.markReady()}markConsumerReady(){this.consumer.markReady()}consumerHasPending(e){return this.consumer.hasPending(e)}start(){this.listener===null&&(this.listener=e=>{let{data:t}=e;if(!oe(t)||t._source===this.sourceId)return;let n=this.getTarget();if(n!==null&&e.source!==null&&e.source!==n)return;let r=t;if(this.shouldBuffer!==null&&!this.shouldBuffer(r)){this.routeToHandler(r);return}this.consumer.enqueue(r)},window.addEventListener(`message`,this.listener))}destroy(){this.listener!==null&&(window.removeEventListener(`message`,this.listener),this.listener=null),this.publisher.clear(),this.consumer.clear(),this.handlers.clear()}get ready(){return this.publisher.ready}get pendingCount(){return this.publisher.pendingCount}post(e){let t=this.getTarget();t!==null&&t.postMessage({...e,_source:this.sourceId},this.targetOrigin)}routeToHandler(e){let t=this.handlers.get(e.type);if(t===void 0)return;let n=t(e);n instanceof Promise&&n.catch(t=>{let n=t instanceof Error?t.message:String(t);console.error(`Virtualdisplay: error handling ${e.type}: ${n}`)})}};new Set([b.CAMERA]);var S=class{placedCallbacks=[];constructor(e){this.send=e}setEnabled(e){this.send({type:b.ANNOTATION_TOGGLE,enabled:e})}startPlacing(){this.send({type:b.ANNOTATION_PLACE_MODE,enabled:!0})}stopPlacing(){this.send({type:b.ANNOTATION_PLACE_MODE,enabled:!1})}onPlaced(e){this.placedCallbacks.push(e)}handlePlaced(e){for(let t of this.placedCallbacks)t(e)}},C=class{isSelectedValue=!1;constructor(e,t){this.value=e,this.attribute=t}get isSelected(){return this.isSelectedValue}setSelected(e){this.isSelectedValue=e}},_e=class{name;defaultValue;values;onSelect;onChangeCallback;constructor(e){this.name=e.name,this.defaultValue=e.defaultValue,this.onSelect=e.onSelect,this.values=this.createValues(e.values)}select(e){if(!this.values.has(e))throw n.valueNotFound(this.name,e);this.onSelect(this.name,e)}getValues(){return Array.from(this.values.values())}getValue(e){return this.values.get(e)}onChange(e){this.onChangeCallback=e}handleResult(e){let t;for(let n of this.values.values()){let r=n.value===e;n.setSelected(r),r&&(t=n)}t!==void 0&&this.onChangeCallback!==void 0&&this.onChangeCallback(t)}createValues(e){let t=new Map;for(let n of e){let e=new C(n,this.name);n===this.defaultValue&&e.setSelected(!0),t.set(n,e)}return t}},ve=class{attributes=new Map;constructor(e,t,n){for(let n of e){let e=this.buildOptions(n,t);this.attributes.set(n.name,new _e(e))}this.onMutationFailed=n}onMutationFailed;get(e){return this.attributes.get(e)}defaults(){let e=[];for(let t of this.attributes.values())t.defaultValue!==void 0&&e.push({name:t.name,value:t.defaultValue});return e}handleResults(e){for(let t of e){if(!t.success){this.onMutationFailed?.(t.name,t.value);continue}this.get(t.name)?.handleResult(t.value)}}buildOptions(e,t){let n={name:e.name,values:e.values,onSelect:(e,n)=>{t([{name:e,value:n}],!1)}};return e.defaultValue===void 0?n:{...n,defaultValue:e.defaultValue}}},ye=class{registry;pendingCallbacks=[];constructor(e,t){this.send=e,this.onMutationFailed=t}handleMappingReceived(e){y.debug(`Initializing from server mapping`,{attributeCount:e.attributes.length}),this.registry=new ve(e.attributes,(e,t)=>this.sendMutation(e,t),this.onMutationFailed),this.replayPendingCallbacks()}handleMutationResult(e){this.registry?.handleResults(e.results)}select(e,t){this.sendMutation([{name:e,value:t}],!1)}getValues(e){return this.registry?.get(e)?.getValues()??[]}getValue(e,t){return this.registry?.get(e)?.getValue(t)}onChange(e,t){if(this.registry===void 0){this.pendingCallbacks.push({name:e,callback:t});return}let n=this.registry.get(e);if(n===void 0){y.warn(`onChange: attribute "${e}" not found — callback will not fire`);return}n.onChange(t)}getAttribute(e){return this.registry?.get(e)}get hasMapping(){return this.registry!==void 0}sendMutation(e,t){let n={type:b.MUTATION,mutations:e,isInitial:t};this.send(n)}replayPendingCallbacks(){for(let{name:e,callback:t}of this.pendingCallbacks){let n=this.registry?.get(e);n===void 0&&y.warn(`onChange: attribute "${e}" not found — buffered callback will not fire`),n?.onChange(t)}this.pendingCallbacks.length=0}},be=class{commands=[];constructor(e){this.send=e}rotate(e){return this.validateFiniteNumber(e,`rotate`),this.commands.push({action:`rotate`,value:e}),this}tilt(e){return this.validateFiniteNumber(e,`tilt`),this.commands.push({action:`tilt`,value:e}),this}zoom(e){return this.validateFiniteNumber(e,`zoom`),this.commands.push({action:`zoom`,value:e}),this}set(){if(this.commands.length===0)throw n.invalidParameter(`No camera commands to execute. Call rotate(), tilt(), or zoom() before set().`);let e={type:b.CAMERA,commands:this.commands};this.send(e),this.commands=[]}validateFiniteNumber(e,t){if(!Number.isFinite(e))throw n.invalidParameter(`${t}() requires a finite number, got ${String(e)}`)}reset(){let e={type:b.CAMERA,commands:[{action:`reset`}]};this.send(e)}},xe=class{state;limitsState;changeCallbacks=[];constructor(){this.state={rotation:0,tilt:0,zoom:100}}get rotation(){return this.state.rotation}get tilt(){return this.state.tilt}get zoom(){return this.state.zoom}onChange(e){this.changeCallbacks.push(e)}get limits(){return this.limitsState}applyLimits(e){this.limitsState=e;let t={rotation:this.rotation,tilt:this.tilt,zoom:this.zoom};for(let e of this.changeCallbacks)e(t)}handlePositionUpdate(e){this.update(e.transforms)}update(e){let t=!1;for(let n of e)switch(n.type){case`rotation`:this.state.rotation=n.value,t=!0;break;case`tilt`:this.state.tilt=n.value,t=!0;break;case`zoom`:this.state.zoom=n.value,t=!0;break;default:break}if(t){let e={rotation:this.rotation,tilt:this.tilt,zoom:this.zoom};for(let t of this.changeCallbacks)t(e)}}},Se=class{developedCallbacks=new Set;errorCallbacks=new Set;developed=!1;failed=!1;photoData=null;constructor(e){this.filename=e}onDeveloped(e){return this.developed&&this.photoData!==null?(e(this.photoData),this):(this.developedCallbacks.add(e),this)}onError(e){return this.errorCallbacks.add(e),this}getFilename(){return this.filename}develop(e){this.developed||this.failed||(this.photoData=e,this.developed=!0,this.developedCallbacks.forEach(e=>{e(this.photoData)}),this.developedCallbacks.clear(),this.errorCallbacks.clear())}fail(e){this.developed||this.failed||(this.failed=!0,this.errorCallbacks.forEach(t=>{t(e)}),this.developedCallbacks.clear(),this.errorCallbacks.clear())}},Ce=class{validExtensions=[`.png`];pendingPhotos=new Map;constructor(e){this.send=e}take(e){this.validateFilename(e),y.debug(`Taking snapshot`,{filename:e});let t=new Se(e);return this.pendingPhotos.set(t.getFilename(),t),this.send({type:b.SNAPSHOT,filename:e}),t}handleSnapshotResult(e){let r=this.pendingPhotos.get(e.filename);if(r===void 0){y.warn(`No pending photo found for filename`,{filename:e.filename,pendingFilenames:Array.from(this.pendingPhotos.keys())});return}if(this.pendingPhotos.delete(e.filename),e.error!==void 0){r.fail(new n(e.error,t.SNAPSHOT_FAILED));return}e.data!==void 0&&r.develop({filename:e.filename,data:e.data})}validateFilename(e){if(e===``||typeof e!=`string`)throw new n(`Filename must be a non-empty string`,t.INVALID_PARAMETER);if(!this.validExtensions.some(t=>e.toLowerCase().endsWith(t)))throw new n(`Invalid filename: "${e}". Filename must end with one of: ${this.validExtensions.join(`, `)}`,t.INVALID_PARAMETER);if(e.includes(`..`)||e.includes(`/`)||e.includes(`\\`))throw new n(`Filename cannot contain path separators or ".."`,t.INVALID_PARAMETER)}},we=class{container=null;attach(e){this.container=e}dispatch(e,t,n=!1){let r=new CustomEvent(e,{detail:t,cancelable:n});return this.container?.dispatchEvent(r),r}on(e,t){let n=e=>{let n=e;t({...n.detail,preventDefault:()=>{n.preventDefault()}})};return this.container?.addEventListener(e,n),()=>{this.container?.removeEventListener(e,n)}}},Te={},Ee=[`en`,`nl`,`de`],w=[`baseLocale`],De=[],Oe,ke;function Ae(e){if(De.length===0)return;let t=typeof e==`string`?e:e.href;if(Oe===t)return ke;let n=new URL(t,`http://dummy.com`),r;for(let e of De)if(new Te(e.match,n.href).exec(n.href)){r=e;break}return Oe=t,ke=r,r}function je(e){let t=Ae(e);return t&&t.exclude!==!0&&Array.isArray(t.strategy)?t.strategy:w}var Me=void 0,T=typeof window>`u`;globalThis.__paraglide=globalThis.__paraglide??{},globalThis.__paraglide.ssr=globalThis.__paraglide.ssr??{};var E=!1,D=()=>{if(Me){let e=Me?.getStore()?.locale;if(e)return e}let e=w;!T&&typeof window<`u`&&window.location?.href&&(e=je(window.location.href));let t=Ne(e,typeof window<`u`?window.location?.href:void 0);if(t)return E||(E=!0,O(t,{reload:!1})),t;throw Error(`No locale found. Read the docs https://inlang.com/m/gerre34r/library-inlang-paraglideJs/errors#no-locale-found`)};function Ne(e,t){let n;for(let t of e){if(t===`baseLocale`)n=`en`;else if(j(t)&&A.has(t)){let e=A.get(t);if(e){let t=e.getLocale();if(t instanceof Promise)continue;if(t!==void 0)return Fe(t)}}let e=k(n);if(e)return e}}var Pe=e=>{e?window.location.href=e:window.location.reload()},O=(e,t)=>{let n={reload:!0,...t},r;try{r=D()}catch{}let i=[],a=w;!T&&typeof window<`u`&&window.location?.href&&(a=je(window.location.href));for(let t of a)if(t===`baseLocale`)continue;else if(j(t)&&A.has(t)){let n=A.get(t);if(n){let r=n.setLocale(e);r instanceof Promise&&(r=r.catch(e=>{throw Error(`Custom strategy "${t}" setLocale failed.`,{cause:e})}),i.push(r))}}let o=()=>{!T&&n.reload&&window.location&&e!==r&&Pe(void 0)};if(i.length)return Promise.all(i).then(()=>{o()});o()};function k(e){if(typeof e!=`string`)return;let t=e.toLowerCase();for(let e of Ee)if(e.toLowerCase()===t)return e}function Fe(e){let t=k(e);if(t)return t;throw Error(`Invalid locale: ${e}. Expected one of: ${Ee.join(`, `)}`)}var A=new Map;function j(e){return typeof e==`string`&&/^custom-[A-Za-z0-9_-]+$/.test(e)}var Ie=()=>`Activate AR`,Le=()=>`AR activeren`,Re=()=>`AR aktivieren`,ze=((e={},t={})=>{let n=t.locale??D();return n===`en`?Ie(e):n===`nl`?Le(e):Re(e)}),Be=()=>`Scan to view in AR`,Ve=()=>`Scan om in AR te bekijken`,He=()=>`Scannen für AR-Ansicht`,Ue=((e={},t={})=>{let n=t.locale??D();return n===`en`?Be(e):n===`nl`?Ve(e):He(e)}),We=()=>`Use your smartphone camera to scan this QR code`,Ge=()=>`Gebruik de camera van je smartphone om deze QR-code te scannen`,Ke=()=>`Verwenden Sie die Kamera Ihres Smartphones, um diesen QR-Code zu scannen`,qe=((e={},t={})=>{let n=t.locale??D();return n===`en`?We(e):n===`nl`?Ge(e):Ke(e)}),Je=()=>`The 3D model will open in your phone's AR mode`,Ye=()=>`Het 3D-model wordt geopend in de AR-modus van je telefoon`,Xe=()=>`Das 3D-Modell wird im AR-Modus Ihres Telefons geöffnet`,Ze=((e={},t={})=>{let n=t.locale??D();return n===`en`?Je(e):n===`nl`?Ye(e):Xe(e)}),Qe=()=>`Close`,$e=()=>`Sluiten`,et=()=>`Schließen`,tt=((e={},t={})=>{let n=t.locale??D();return n===`en`?Qe(e):n===`nl`?$e(e):et(e)}),nt=()=>`Toggle fullscreen`,rt=()=>`Volledig scherm`,it=()=>`Vollbild umschalten`,at=((e={},t={})=>{let n=t.locale??D();return n===`en`?nt(e):n===`nl`?rt(e):it(e)}),ot=()=>`Downloading`,st=()=>`Downloaden`,ct=()=>`Herunterladen`,M=((e={},t={})=>{let n=t.locale??D();return n===`en`?ot(e):n===`nl`?st(e):ct(e)}),lt=()=>`Rendering`,ut=()=>`Renderen`,dt=()=>`Rendern`,ft=((e={},t={})=>{let n=t.locale??D();return n===`en`?lt(e):n===`nl`?ut(e):dt(e)}),pt=()=>`Screenshot`,mt=()=>`Screenshot`,ht=()=>`Screenshot`,gt=((e={},t={})=>{let n=t.locale??D();return n===`en`?pt(e):n===`nl`?mt(e):ht(e)}),_t=()=>`Reset camera`,vt=()=>`Camera resetten`,yt=()=>`Kamera zurücksetzen`,bt=((e={},t={})=>{let n=t.locale??D();return n===`en`?_t(e):n===`nl`?vt(e):yt(e)}),xt=()=>`Zoom in`,St=()=>`Inzoomen`,Ct=()=>`Hineinzoomen`,wt=((e={},t={})=>{let n=t.locale??D();return n===`en`?xt(e):n===`nl`?St(e):Ct(e)}),Tt=()=>`Zoom out`,Et=()=>`Uitzoomen`,Dt=()=>`Herauszoomen`,Ot=((e={},t={})=>{let n=t.locale??D();return n===`en`?Tt(e):n===`nl`?Et(e):Dt(e)}),kt=()=>`Rotate left`,At=()=>`Naar links draaien`,jt=()=>`Nach links drehen`,Mt=((e={},t={})=>{let n=t.locale??D();return n===`en`?kt(e):n===`nl`?At(e):jt(e)}),Nt=()=>`Rotate right`,Pt=()=>`Naar rechts draaien`,Ft=()=>`Nach rechts drehen`,It=((e={},t={})=>{let n=t.locale??D();return n===`en`?Nt(e):n===`nl`?Pt(e):Ft(e)}),Lt=()=>`Tilt up`,Rt=()=>`Omhoog kantelen`,zt=()=>`Nach oben kippen`,Bt=((e={},t={})=>{let n=t.locale??D();return n===`en`?Lt(e):n===`nl`?Rt(e):zt(e)}),Vt=()=>`Tilt down`,Ht=()=>`Omlaag kantelen`,Ut=()=>`Nach unten kippen`,Wt=((e={},t={})=>{let n=t.locale??D();return n===`en`?Vt(e):n===`nl`?Ht(e):Ut(e)}),Gt={xmlns:`http://www.w3.org/2000/svg`,width:24,height:24,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,"stroke-width":2,"stroke-linecap":`round`,"stroke-linejoin":`round`},N=([e,t,n])=>{let r=document.createElementNS(`http://www.w3.org/2000/svg`,e);return Object.keys(t).forEach(e=>{r.setAttribute(e,String(t[e]))}),n?.length&&n.forEach(e=>{let t=N(e);r.appendChild(t)}),r},P=(e,t={})=>N([`svg`,{...Gt,...t},e]),Kt=[[`path`,{d:`M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z`}],[`path`,{d:`m3.3 7 8.7 5 8.7-5`}],[`path`,{d:`M12 22V12`}]],qt=[[`path`,{d:`M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z`}],[`circle`,{cx:`12`,cy:`13`,r:`3`}]],F=[[`path`,{d:`m6 9 6 6 6-6`}]],Jt=[[`path`,{d:`m15 18-6-6 6-6`}]],Yt=[[`path`,{d:`m9 18 6-6-6-6`}]],Xt=[[`path`,{d:`m18 15-6-6-6 6`}]],Zt=[[`path`,{d:`M15 3h6v6`}],[`path`,{d:`m21 3-7 7`}],[`path`,{d:`m3 21 7-7`}],[`path`,{d:`M9 21H3v-6`}]],Qt=[[`path`,{d:`m14 10 7-7`}],[`path`,{d:`M20 10h-6V4`}],[`path`,{d:`m3 21 7-7`}],[`path`,{d:`M4 14h6v6`}]],$t=[[`path`,{d:`M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8`}],[`path`,{d:`M3 3v5h5`}]],en=[[`circle`,{cx:`11`,cy:`11`,r:`8`}],[`line`,{x1:`21`,x2:`16.65`,y1:`21`,y2:`16.65`}],[`line`,{x1:`11`,x2:`11`,y1:`8`,y2:`14`}],[`line`,{x1:`8`,x2:`14`,y1:`11`,y2:`11`}]],tn=[[`circle`,{cx:`11`,cy:`11`,r:`8`}],[`line`,{x1:`21`,x2:`16.65`,y1:`21`,y2:`16.65`}],[`line`,{x1:`8`,x2:`14`,y1:`11`,y2:`11`}]];function I(e,{size:t=20,strokeWidth:n=1.75}={}){return P(e,{width:t,height:t,"stroke-width":n})}var L={ar:e=>I(Kt,e),fullscreen:e=>I(Zt,e),exitFullscreen:e=>I(Qt,e),screenshot:e=>I(qt,e),tiltUp:e=>I(Xt,e),tiltDown:e=>I(F,e),rotateLeft:e=>I(Jt,e),rotateRight:e=>I(Yt,e),zoomIn:e=>I(en,e),zoomOut:e=>I(tn,e),reset:e=>I($t,e)},R=class{element;constructor({variant:e=`default`,size:t=`default`,label:n,icon:r,onClick:i,disabled:a=!1}={}){this.element=document.createElement(`button`),this.element.className=`ui-btn ui-btn--${e} ui-btn--size-${t}`,n!==void 0&&(this.element.setAttribute(`aria-label`,n),this.element.title=n),r===void 0?n!==void 0&&(this.element.textContent=n):this.element.appendChild(r),i&&this.element.addEventListener(`click`,i),this.element.disabled=a}setIcon(e){let t=this.element.querySelector(`svg`);t===null?this.element.appendChild(e):t.replaceWith(e)}},z={brand:{DEFAULT:`#171717`,primary:`#171717`,hover:`#262626`,light:`#f5f5f5`,50:`#fafafa`,100:`#f5f5f5`,200:`#e5e5e5`,300:`#d4d4d4`,400:`#a3a3a3`,500:`#737373`,600:`#525252`,700:`#404040`,800:`#262626`,900:`#171717`,950:`#0a0a0a`},semantic:{success:`#16a34a`,warning:`#ca8a04`,error:`#dc2626`,info:`#0891b2`},neutral:{50:`#fafafa`,100:`#f5f5f5`,200:`#e5e5e5`,300:`#d4d4d4`,400:`#a3a3a3`,500:`#737373`,600:`#525252`,700:`#404040`,800:`#262626`,900:`#171717`,950:`#0a0a0a`},white:`#ffffff`,black:`#000000`},B={px:`1px`,0:`0`,.5:`0.125rem`,1:`0.25rem`,1.5:`0.375rem`,2:`0.5rem`,2.5:`0.625rem`,3:`0.75rem`,3.5:`0.875rem`,4:`1rem`,5:`1.25rem`,6:`1.5rem`,7:`1.75rem`,8:`2rem`,9:`2.25rem`,10:`2.5rem`,12:`3rem`,14:`3.5rem`,16:`4rem`,20:`5rem`,24:`6rem`};B[1],B[2],B[4],B[6],B[8],B[12];var nn=class{element;constructor(){this.element=document.createElement(`div`),Object.assign(this.element.style,{background:z.white,borderRadius:B[3],padding:B[6],boxShadow:`0 ${B[2]} ${B[8]} oklch(0% 0 0 / 20%)`,maxWidth:`20rem`,width:`100%`})}},rn=class{card;backdrop;keyHandler=null;constructor(e={}){this.options=e,this.card=new nn,this.backdrop=this.createBackdrop(),this.backdrop.appendChild(this.card.element)}open(){document.body.appendChild(this.backdrop),this.keyHandler=e=>{e.key===`Escape`&&this.close()},document.addEventListener(`keydown`,this.keyHandler)}close(){this.backdrop.remove(),this.keyHandler!==null&&(document.removeEventListener(`keydown`,this.keyHandler),this.keyHandler=null),this.options.onClose?.()}createBackdrop(){let e=document.createElement(`div`);return Object.assign(e.style,{position:`fixed`,inset:B[0],background:`oklch(0% 0 0 / 50%)`,zIndex:`9999`,display:`flex`,alignItems:`center`,justifyContent:`center`}),e.addEventListener(`click`,t=>{t.target===e&&this.close()}),e}},an=class{element;selectCallback=null;constructor(e,t,n){this.element=document.createElement(`div`),this.element.className=`ui-toggle-group`;for(let r=0;r<e.length;r++){let i=e[r],a=document.createElement(`button`);a.className=`ui-toggle-group-item`,a.dataset.value=i,a.textContent=n?.[r]??i,a.dataset.state=i===t?`on`:`off`,a.addEventListener(`click`,()=>{this.selectCallback?.(i)}),this.element.appendChild(a)}}setSelected(e){for(let t of this.element.querySelectorAll(`.ui-toggle-group-item`))t.dataset.state=t.dataset.value===e?`on`:`off`}onSelect(e){this.selectCallback=e}},on=class{element;select;constructor(e,t,n,r,i){this.select=document.createElement(`select`),this.select.className=`ui-native-select`,this.select.dataset.name=e;let a=document.createElement(`option`);a.value=``,a.disabled=!0,a.textContent=n,this.select.appendChild(a);let o=!1;for(let e=0;e<t.length;e++){let n=t[e],a=document.createElement(`option`);a.value=n,a.textContent=i?.[e]??n,n===r&&(a.selected=!0,o=!0),this.select.appendChild(a)}o||(a.selected=!0);let s=P(F,{width:16,height:16,"stroke-width":2});s.classList.add(`ui-native-select-icon`),this.element=document.createElement(`div`),this.element.className=`ui-native-select-wrap`,this.element.appendChild(this.select),this.element.appendChild(s)}setSelected(e){this.select.value=e}onSelect(e){this.select.addEventListener(`change`,()=>{e(this.select.value)})}},V={fontFamily:{sans:[`Mona Sans`,`ui-sans-serif`,`system-ui`,`sans-serif`,`Apple Color Emoji`,`Segoe UI Emoji`,`Segoe UI Symbol`,`Noto Color Emoji`],mono:[`JetBrains Mono`,`ui-monospace`,`monospace`]},fontSize:{xs:`0.75rem`,sm:`0.875rem`,base:`1rem`,lg:`1.125rem`,xl:`1.25rem`,"2xl":`1.5rem`,"3xl":`1.875rem`,"4xl":`2.25rem`},fontWeight:{normal:`400`,medium:`500`,semibold:`600`,bold:`700`},lineHeight:{tight:`1.25`,normal:`1.5`,relaxed:`1.75`}},sn=V.fontFamily.sans.join(`, `),cn=class{qrLib=null;dialog=null;async show(t){this.hide(),this.qrLib??=await Promise.resolve().then(()=>e.n(require(`./browser-CDLfpTNV.cjs`).default,1));let n=await this.qrLib.toDataURL(t,{width:256,margin:4,errorCorrectionLevel:`M`,color:{dark:z.black,light:z.white}});this.dialog=new rn({onClose:()=>{this.dialog=null}}),Object.assign(this.dialog.card.element.style,{display:`flex`,flexDirection:`column`,alignItems:`center`,gap:B[3],fontFamily:sn}),this.dialog.card.element.appendChild(this.createText(Ue(),{fontSize:V.fontSize.base,fontWeight:V.fontWeight.semibold,color:z.neutral[900]})),this.dialog.card.element.appendChild(this.createText(qe(),{fontSize:V.fontSize.sm,color:z.neutral[600]})),this.dialog.card.element.appendChild(this.createQrImage(n)),this.dialog.card.element.appendChild(this.createText(Ze(),{fontSize:V.fontSize.xs,color:z.neutral[500]}));let r=new R({variant:`outline`,label:tt(),onClick:()=>{this.hide()}});this.dialog.card.element.appendChild(r.element),this.dialog.open()}hide(){this.dialog?.close(),this.dialog=null}createText(e,t){let n=document.createElement(`p`);return n.textContent=e,Object.assign(n.style,{margin:`0`,textAlign:`center`,...t}),n}createQrImage(e){let t=document.createElement(`img`);return t.src=e,t.alt=`QR code`,Object.assign(t.style,{width:B[24],height:B[24],borderRadius:B[1]}),t}},H=V.fontFamily.sans.join(`, `),ln=`
|
|
2
|
+
:root {
|
|
3
|
+
--primary: oklch(5% 0 0);
|
|
4
|
+
--primary-foreground: oklch(100% 0 0);
|
|
5
|
+
--secondary: oklch(92% 0 0);
|
|
6
|
+
--secondary-foreground: oklch(5% 0 0);
|
|
7
|
+
--background: oklch(100% 0 0);
|
|
8
|
+
--foreground: oklch(5% 0 0);
|
|
9
|
+
--border: oklch(92% 0 0);
|
|
10
|
+
--ring: oklch(44% 0 0);
|
|
11
|
+
--radius: 0.625rem;
|
|
12
|
+
--accent: oklch(92% 0 0);
|
|
13
|
+
--accent-foreground: oklch(5% 0 0);
|
|
14
|
+
--muted-foreground: oklch(44% 0 0);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/* ── Button ──────────────────────────────────────────────── */
|
|
18
|
+
.ui-btn {
|
|
19
|
+
display: inline-flex;
|
|
20
|
+
align-items: center;
|
|
21
|
+
justify-content: center;
|
|
22
|
+
gap: 0.5rem;
|
|
23
|
+
border: 1px solid transparent;
|
|
24
|
+
border-radius: var(--radius);
|
|
25
|
+
font-family: ${H};
|
|
26
|
+
font-size: 0.875rem;
|
|
27
|
+
font-weight: 600;
|
|
28
|
+
white-space: nowrap;
|
|
29
|
+
cursor: pointer;
|
|
30
|
+
transition: all 200ms;
|
|
31
|
+
flex-shrink: 0;
|
|
32
|
+
}
|
|
33
|
+
.ui-btn:active { transform: scale(0.98); }
|
|
34
|
+
.ui-btn:disabled { opacity: 0.5; pointer-events: none; }
|
|
35
|
+
.ui-btn svg { inline-size: 1rem; block-size: 1rem; pointer-events: none; flex-shrink: 0; }
|
|
36
|
+
|
|
37
|
+
.ui-btn--default {
|
|
38
|
+
background: var(--primary);
|
|
39
|
+
color: var(--primary-foreground);
|
|
40
|
+
box-shadow: 0 1px 3px oklch(5% 0 0 / 20%);
|
|
41
|
+
}
|
|
42
|
+
.ui-btn--default:hover { background: oklch(10% 0 0); }
|
|
43
|
+
|
|
44
|
+
.ui-btn--outline {
|
|
45
|
+
background: var(--background);
|
|
46
|
+
color: var(--foreground);
|
|
47
|
+
border-color: var(--border);
|
|
48
|
+
box-shadow: 0 1px 2px oklch(5% 0 0 / 8%);
|
|
49
|
+
}
|
|
50
|
+
.ui-btn--outline:hover { background: var(--accent); border-color: oklch(85% 0 0); }
|
|
51
|
+
|
|
52
|
+
.ui-btn--secondary {
|
|
53
|
+
background: var(--secondary);
|
|
54
|
+
color: var(--secondary-foreground);
|
|
55
|
+
box-shadow: 0 1px 2px oklch(5% 0 0 / 8%);
|
|
56
|
+
}
|
|
57
|
+
.ui-btn--secondary:hover { background: oklch(88% 0 0); }
|
|
58
|
+
|
|
59
|
+
.ui-btn--ghost { background: transparent; color: var(--foreground); }
|
|
60
|
+
.ui-btn--ghost:hover { background: var(--accent); }
|
|
61
|
+
|
|
62
|
+
.ui-btn--size-default { block-size: 2.25rem; padding: 0 1rem; }
|
|
63
|
+
.ui-btn--size-sm { block-size: 2rem; padding: 0 0.75rem; border-radius: calc(var(--radius) - 0.125rem); }
|
|
64
|
+
.ui-btn--size-lg { block-size: 2.5rem; padding: 0 1.5rem; }
|
|
65
|
+
.ui-btn--size-icon { inline-size: 2.25rem; block-size: 2.25rem; padding: 0; }
|
|
66
|
+
.ui-btn--size-icon-sm { inline-size: 2rem; block-size: 2rem; padding: 0; }
|
|
67
|
+
.ui-btn--size-icon-lg { inline-size: 2.5rem; block-size: 2.5rem; padding: 0; }
|
|
68
|
+
|
|
69
|
+
/* ── Toggle group ────────────────────────────────────────── */
|
|
70
|
+
.ui-toggle-group { display: inline-flex; flex-wrap: wrap; gap: 0.25rem; }
|
|
71
|
+
|
|
72
|
+
.ui-toggle-group-item {
|
|
73
|
+
display: inline-flex;
|
|
74
|
+
align-items: center;
|
|
75
|
+
justify-content: center;
|
|
76
|
+
block-size: 2rem;
|
|
77
|
+
padding: 0 0.75rem;
|
|
78
|
+
border: 1px solid var(--border);
|
|
79
|
+
border-radius: var(--radius);
|
|
80
|
+
background: var(--background);
|
|
81
|
+
color: var(--foreground);
|
|
82
|
+
font-family: ${H};
|
|
83
|
+
font-size: 0.875rem;
|
|
84
|
+
font-weight: 600;
|
|
85
|
+
cursor: pointer;
|
|
86
|
+
white-space: nowrap;
|
|
87
|
+
transition: all 200ms;
|
|
88
|
+
box-shadow: 0 1px 2px oklch(5% 0 0 / 8%);
|
|
89
|
+
}
|
|
90
|
+
.ui-toggle-group-item:hover { background: var(--accent); border-color: oklch(85% 0 0); }
|
|
91
|
+
.ui-toggle-group-item:active { transform: scale(0.98); }
|
|
92
|
+
.ui-toggle-group-item[data-state="on"] {
|
|
93
|
+
background: var(--primary);
|
|
94
|
+
color: var(--primary-foreground);
|
|
95
|
+
border-color: var(--primary);
|
|
96
|
+
}
|
|
97
|
+
.ui-toggle-group-item[data-state="on"]:hover { background: oklch(10% 0 0); }
|
|
98
|
+
|
|
99
|
+
/* ── Native select ───────────────────────────────────────── */
|
|
100
|
+
.ui-native-select-wrap {
|
|
101
|
+
position: relative;
|
|
102
|
+
display: inline-flex;
|
|
103
|
+
min-inline-size: 8rem;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.ui-native-select {
|
|
107
|
+
display: block;
|
|
108
|
+
inline-size: 100%;
|
|
109
|
+
block-size: 2.25rem;
|
|
110
|
+
padding: 0 2.25rem 0 0.75rem;
|
|
111
|
+
border: 1px solid var(--border);
|
|
112
|
+
border-radius: var(--radius);
|
|
113
|
+
background: var(--background);
|
|
114
|
+
appearance: none;
|
|
115
|
+
color: var(--foreground);
|
|
116
|
+
font-family: ${H};
|
|
117
|
+
font-size: 0.875rem;
|
|
118
|
+
font-weight: 400;
|
|
119
|
+
cursor: pointer;
|
|
120
|
+
transition: color 200ms, box-shadow 200ms, border-color 200ms;
|
|
121
|
+
box-shadow: 0 1px 2px oklch(5% 0 0 / 8%);
|
|
122
|
+
}
|
|
123
|
+
.ui-native-select:hover { border-color: oklch(85% 0 0); }
|
|
124
|
+
.ui-native-select:focus-visible {
|
|
125
|
+
outline: none;
|
|
126
|
+
border-color: var(--ring);
|
|
127
|
+
box-shadow: 0 0 0 3px oklch(5% 0 0 / 12%);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.ui-native-select-icon {
|
|
131
|
+
position: absolute;
|
|
132
|
+
inset-block-start: 50%;
|
|
133
|
+
inset-inline-end: 0.625rem;
|
|
134
|
+
transform: translateY(-50%);
|
|
135
|
+
color: var(--muted-foreground);
|
|
136
|
+
pointer-events: none;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/* ── Annotation layer ───────────────────────────────────── */
|
|
140
|
+
.vd-annotations-layer {
|
|
141
|
+
position: absolute;
|
|
142
|
+
inset-block-start: 0;
|
|
143
|
+
inset-inline-start: 0;
|
|
144
|
+
inline-size: 100%;
|
|
145
|
+
block-size: 100%;
|
|
146
|
+
pointer-events: none;
|
|
147
|
+
overflow: visible !important; /* override CSS2DRenderer inline style */
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.vd-annotation-marker {
|
|
151
|
+
display: flex;
|
|
152
|
+
align-items: center;
|
|
153
|
+
justify-content: center;
|
|
154
|
+
inline-size: 1.75rem;
|
|
155
|
+
block-size: 1.75rem;
|
|
156
|
+
border-radius: 50%;
|
|
157
|
+
border: 2px solid oklch(100% 0 0);
|
|
158
|
+
background: var(--primary);
|
|
159
|
+
color: var(--primary-foreground);
|
|
160
|
+
font-family: ${H};
|
|
161
|
+
font-size: 0.8125rem;
|
|
162
|
+
font-weight: 600;
|
|
163
|
+
cursor: pointer;
|
|
164
|
+
pointer-events: auto;
|
|
165
|
+
box-shadow: 0 2px 8px oklch(5% 0 0 / 20%);
|
|
166
|
+
transition: transform 100ms ease;
|
|
167
|
+
position: relative;
|
|
168
|
+
}
|
|
169
|
+
.vd-annotation-marker:hover { transform: scale(1.1); }
|
|
170
|
+
|
|
171
|
+
.vd-annotation-popup {
|
|
172
|
+
position: absolute;
|
|
173
|
+
inset-block-end: calc(100% + 0.5rem);
|
|
174
|
+
inset-inline-start: 50%;
|
|
175
|
+
transform: translateX(-50%);
|
|
176
|
+
background: var(--background);
|
|
177
|
+
color: var(--foreground);
|
|
178
|
+
border: 1px solid var(--border);
|
|
179
|
+
border-radius: var(--radius);
|
|
180
|
+
padding: 0.75rem 1rem;
|
|
181
|
+
max-inline-size: 15rem;
|
|
182
|
+
box-shadow: 0 4px 6px oklch(5% 0 0 / 8%), 0 2px 4px oklch(5% 0 0 / 6%);
|
|
183
|
+
pointer-events: auto;
|
|
184
|
+
white-space: normal;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
188
|
+
.vd-annotation-popup {
|
|
189
|
+
animation: vd-popup-in 150ms ease;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
@keyframes vd-popup-in {
|
|
194
|
+
from { opacity: 0; transform: translateX(-50%) translateY(4px); }
|
|
195
|
+
to { opacity: 1; transform: translateX(-50%) translateY(0); }
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.vd-annotation-popup-title {
|
|
199
|
+
font-family: ${H};
|
|
200
|
+
font-size: 0.875rem;
|
|
201
|
+
font-weight: 600;
|
|
202
|
+
line-height: 1.25rem;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.vd-annotation-popup-description {
|
|
206
|
+
font-family: ${H};
|
|
207
|
+
font-size: 0.8125rem;
|
|
208
|
+
font-weight: 400;
|
|
209
|
+
line-height: 1.125rem;
|
|
210
|
+
color: var(--muted-foreground);
|
|
211
|
+
margin-block-start: 0.25rem;
|
|
212
|
+
}
|
|
213
|
+
`,un=!1;function dn(){if(un||typeof document>`u`)return;un=!0;let e=document.createElement(`style`);e.id=`vd-ui-vanilla`,e.textContent=ln,document.head.appendChild(e)}function fn(e){let t=Math.max(0,Math.min(1,e));return t*t*(3-2*t)}function pn(e,t,n,r,i,a){let[o,s,c]=e,l=Math.cos(t),u=Math.sin(t),d=l*o+u*c,f=-u*o+l*c,p=Math.cos(n),m=Math.sin(n),h=p*s-m*f,g=m*s+p*f,_=.55;return[r+d*a*_,i-h*a*_,g]}function mn(e,t,n){e.beginPath(),e.moveTo(t[0],t[1]),e.lineTo(n[0],n[1]),e.strokeStyle=`#000`,e.lineWidth=2,e.stroke()}function hn(e,t,n,r,i){let a=t(n),o=t(r);mn(e,a,[a[0]+(o[0]-a[0])*i,a[1]+(o[1]-a[1])*i,a[2]])}var U=[-1,-1,1],W=[1,-1,1],G=[1,-1,-1],K=[-1,-1,-1],q=[-1,1,1],J=[1,1,1],Y=[1,1,-1],X=[-1,1,-1],gn=[[U,W],[W,G],[G,K],[K,U],[U,q],[W,J],[G,Y],[K,X],[q,J],[J,Y],[Y,X],[X,q]],_n=400,vn=`-apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif`;function yn(){let e=document.createElement(`div`);Object.assign(e.style,{position:`absolute`,inset:`0`,display:`flex`,flexDirection:`column`,alignItems:`center`,justifyContent:`center`,background:`#fff`,zIndex:`20`,opacity:`0`,transition:`opacity 0.3s ease-in-out`});let t=document.createElement(`canvas`);Object.assign(t.style,{width:`100%`,height:`100%`,position:`absolute`,inset:`0`});let n=document.createElement(`div`);Object.assign(n.style,{position:`absolute`,top:`56%`,left:`0`,right:`0`,textAlign:`center`,pointerEvents:`none`});let r=document.createElement(`span`);Object.assign(r.style,{fontSize:`13px`,fontWeight:`400`,color:`#000`,fontVariantNumeric:`tabular-nums`,fontFamily:vn});let i=document.createElement(`span`);return Object.assign(i.style,{fontSize:`13px`,color:`#000`,fontFamily:vn}),i.textContent=M(),n.appendChild(r),n.appendChild(i),e.appendChild(t),e.appendChild(n),{overlay:e,canvas:t,pctEl:r,phaseEl:i}}var bn=class{overlay;canvas;ctx;pctEl;phaseEl;animationId=null;showTimerId=null;startTime;hidden=!1;visible=!1;constructor(e,t={}){this.startTime=performance.now();let n=yn();this.overlay=n.overlay,this.canvas=n.canvas,this.pctEl=n.pctEl,this.phaseEl=n.phaseEl,e.appendChild(this.overlay),this.ctx=this.canvas.getContext(`2d`),this.ctx!==null&&(this.sizeCanvas(),this.tick());let r=t.showDelay??_n;this.showTimerId=setTimeout(()=>{this.reveal()},r)}get loadingTexts(){return{downloading:M(),rendering:ft()}}updateProgress(e,t){this.hidden||(this.pctEl.textContent=`${Math.round(e)}%`,this.phaseEl.textContent=t===``?``:` \u00B7 ${t}`)}showError(e){if(this.hidden=!1,this.animationId!==null&&(cancelAnimationFrame(this.animationId),this.animationId=null),this.ctx!==null){let e=Math.min(devicePixelRatio,2),t=this.canvas.width/e,n=this.canvas.height/e;this.ctx.fillStyle=`#fff`,this.ctx.fillRect(0,0,t*e,n*e)}this.pctEl.textContent=``,this.phaseEl.textContent=e,this.phaseEl.style.color=`#b91c1c`,this.reveal()}hide(){if(!this.hidden){if(this.hidden=!0,this.cancelShowTimer(),!this.visible){this.destroy();return}this.overlay.style.opacity=`0`,this.overlay.addEventListener(`transitionend`,()=>{this.destroy()},{once:!0}),setTimeout(()=>{this.destroy()},500)}}destroy(){this.cancelShowTimer(),this.animationId!==null&&(cancelAnimationFrame(this.animationId),this.animationId=null),this.overlay.remove()}reveal(){this.hidden||this.visible||(this.visible=!0,this.overlay.style.opacity=`1`)}cancelShowTimer(){this.showTimerId!==null&&(clearTimeout(this.showTimerId),this.showTimerId=null)}sizeCanvas(){if(this.ctx===null)return;let e=Math.min(devicePixelRatio,2),t=this.overlay.clientWidth||440,n=this.overlay.clientHeight||360;this.canvas.width=t*e,this.canvas.height=n*e,this.ctx.scale(e,e),this.ctx.lineCap=`round`,this.ctx.lineJoin=`round`}tick=()=>{this.hidden||(this.drawFrame(),this.animationId=requestAnimationFrame(this.tick))};drawFrame(){if(this.ctx===null)return;let e=this.canvas.width/Math.min(devicePixelRatio,2),t=this.canvas.height/Math.min(devicePixelRatio,2),n=(performance.now()-this.startTime)/1e3;this.ctx.fillStyle=`#fff`,this.ctx.fillRect(0,0,e,t);let r=e/2,i=t*.44,a=Math.min(e,t)*.08,o=e=>pn(e,.785,.615,r,i,a),s=n%6/6,c=gn.length,l;l=s<.35?fn(s/.35)*c:s<.55?c:s<.9?(1-fn((s-.55)/.35))*c:0,this.ctx.shadowBlur=5,this.ctx.shadowColor=`rgba(30,30,30,0.08)`;for(let e=0;e<c&&!(e>=l);e++){let t=gn[e];if(t===void 0)continue;let n=Math.min(1,l-e);hn(this.ctx,o,t[0],t[1],n)}this.ctx.shadowBlur=0}},xn=class{element;arBtn=null;fullscreenBtn=null;onFullscreenChange;constructor(e){this.options=e,this.element=document.createElement(`div`),Object.assign(this.element.style,{display:`flex`,gap:`0.375rem`}),this.onFullscreenChange=()=>{this.setFullscreenIcon(document.fullscreenElement!==null)},document.addEventListener(`fullscreenchange`,this.onFullscreenChange)}setFullscreenIcon(e){this.fullscreenBtn!==null&&this.fullscreenBtn.setIcon(e?L.exitFullscreen():L.fullscreen())}syncButton(e,t,n){if(t&&e===null){let e=n();return this.element.appendChild(e.element),e}return!t&&e!==null?(e.element.remove(),null):e}applySettings(e){this.arBtn=this.syncButton(this.arBtn,e.ar!==!1&&this.options.onAr!==void 0,()=>new R({variant:`outline`,size:`icon`,label:ze(),icon:L.ar(),onClick:()=>{this.options.onAr?.()}})),this.fullscreenBtn=this.syncButton(this.fullscreenBtn,e.fullscreen!==!1&&this.options.onFullscreen!==void 0,()=>new R({variant:`outline`,size:`icon`,label:at(),icon:L.fullscreen(),onClick:()=>{this.options.onFullscreen?.()}}))}destroy(){document.removeEventListener(`fullscreenchange`,this.onFullscreenChange)}},Z=.5,Sn=class e{element;constructor(t,n){this.element=Object.assign(document.createElement(`div`),{className:`vd-camera-controls`});let r={targetRotation:n.rotation,targetTilt:n.tilt,targetZoom:n.zoom,thetaOffset:0},i=Cn(t,n,r);n.onChange(e=>{r.targetRotation=e.rotation-r.thetaOffset,r.targetTilt=e.tilt,r.targetZoom=e.zoom,wn(i,n,e)}),this.element.appendChild(e.buildZoom(i.zoomOut,i.zoomIn)),this.element.appendChild(e.buildDpad(i.tiltUp,i.rotateLeft,i.reset,i.rotateRight,i.tiltDown))}static buildZoom(e,t){let n=document.createElement(`div`);return n.className=`vd-zoom`,n.appendChild(e.element),n.appendChild(t.element),n}static buildDpad(e,t,n,r,i){let a=document.createElement(`div`);a.className=`vd-dpad`;for(let[o,s]of[[e,`up`],[t,`left`],[n,`center`],[r,`right`],[i,`down`]])o.element.classList.add(`vd-dpad-${s}`),a.appendChild(o.element);return a}};function Cn(e,t,n){let r=e=>Math.max(t.limits?.minZoom??1,Math.min(t.limits?.maxZoom??1/0,e)),i=e=>{let n=t.limits?.minRotate,r=t.limits?.maxRotate;return n!==void 0||r!==void 0?Math.max(n??-1/0,Math.min(r??1/0,e)):e},a=r=>{let i=t.limits?.minTilt,a=t.limits?.maxTilt;if(i!==void 0||a!==void 0){n.targetTilt=Math.max(i??0,Math.min(a??180,n.targetTilt+r)),e.tilt(n.targetTilt).set();return}let o=n.targetTilt+r;o>180||o<0?(n.targetTilt=o>180?360-o:-o,n.thetaOffset=(n.thetaOffset+180)%360,e.tilt(n.targetTilt).rotate(n.targetRotation+n.thetaOffset).set()):(n.targetTilt=o,e.tilt(n.targetTilt).set())};return{zoomOut:new R({variant:`outline`,size:`icon`,label:Ot(),icon:L.zoomOut(),onClick:()=>{n.targetZoom=r(n.targetZoom-10),e.zoom(n.targetZoom).set()}}),zoomIn:new R({variant:`outline`,size:`icon`,label:wt(),icon:L.zoomIn(),onClick:()=>{n.targetZoom=r(n.targetZoom+10),e.zoom(n.targetZoom).set()}}),tiltUp:new R({variant:`outline`,size:`icon`,label:Bt(),icon:L.tiltUp(),onClick:()=>{a(-15)}}),rotateLeft:new R({variant:`outline`,size:`icon`,label:Mt(),icon:L.rotateLeft(),onClick:()=>{n.targetRotation=i(n.targetRotation-15),e.rotate(n.targetRotation+n.thetaOffset).set()}}),reset:new R({variant:`outline`,size:`icon`,label:bt(),icon:L.reset(),onClick:()=>{n.thetaOffset=0,e.reset()}}),rotateRight:new R({variant:`outline`,size:`icon`,label:It(),icon:L.rotateRight(),onClick:()=>{n.targetRotation=i(n.targetRotation+15),e.rotate(n.targetRotation+n.thetaOffset).set()}}),tiltDown:new R({variant:`outline`,size:`icon`,label:Wt(),icon:L.tiltDown(),onClick:()=>{a(15)}})}}function wn(e,t,n){let r=t.limits;r!==void 0&&(e.zoomOut.element.disabled=r.minZoom!==void 0&&n.zoom<=r.minZoom+Z,e.zoomIn.element.disabled=r.maxZoom!==void 0&&n.zoom>=r.maxZoom-Z,e.tiltUp.element.disabled=r.minTilt!==void 0&&n.tilt<=r.minTilt+Z,e.tiltDown.element.disabled=r.maxTilt!==void 0&&n.tilt>=r.maxTilt-Z,e.rotateLeft.element.disabled=r.minRotate!==void 0&&n.rotation<=r.minRotate+Z,e.rotateRight.element.disabled=r.maxRotate!==void 0&&n.rotation>=r.maxRotate-Z)}var Tn=5;function Q(e){let t=e.replace(/([A-Z])/g,` $1`).trim();return t.charAt(0).toUpperCase()+t.slice(1).toLowerCase()}function En(e,t,n,r,i){let a=document.createElement(`div`);a.className=`vd-attribute`,a.dataset.name=e.name;let o=document.createElement(`span`);o.className=`vd-attribute-label`,o.textContent=Q(e.name),a.appendChild(o);let s=e.values.find(n=>t.getValue(e.name,n)?.isSelected===!0),c=e.values.map(Q),l=e.values.length<=Tn?new an(e.values,s,c):new on(e.name,e.values,Q(e.name),s,c);return l.onSelect(t=>{n.dispatch(`ui:select`,{attribute:e.name,value:t},!0).defaultPrevented||r(e.name,t)}),i(e.name,t=>{l.setSelected(t.value),n.dispatch(`ui:selected`,{attribute:e.name,value:t.value})}),a.appendChild(l.element),a}var Dn=V.fontFamily.sans.join(`, `),$=`
|
|
214
|
+
position: absolute;
|
|
215
|
+
display: flex;
|
|
216
|
+
z-index: 10;
|
|
217
|
+
`,On=`
|
|
218
|
+
/* Override browser's default black fullscreen backdrop */
|
|
219
|
+
.vd-container:fullscreen {
|
|
220
|
+
background: oklch(100% 0 0);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/* Layout slots — four corners */
|
|
224
|
+
.vd-slot-top-right {
|
|
225
|
+
${$}
|
|
226
|
+
inset-block-start: ${B[3]};
|
|
227
|
+
inset-inline-end: ${B[3]};
|
|
228
|
+
flex-direction: column;
|
|
229
|
+
align-items: flex-end;
|
|
230
|
+
gap: ${B[1.5]};
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.vd-slot-bottom-left {
|
|
234
|
+
${$}
|
|
235
|
+
inset-block-end: ${B[3]};
|
|
236
|
+
inset-inline-start: ${B[3]};
|
|
237
|
+
flex-direction: column;
|
|
238
|
+
align-items: flex-start;
|
|
239
|
+
gap: ${B[1.5]};
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.vd-slot-bottom-right {
|
|
243
|
+
${$}
|
|
244
|
+
inset-block-end: ${B[3]};
|
|
245
|
+
inset-inline-end: ${B[3]};
|
|
246
|
+
flex-direction: row;
|
|
247
|
+
gap: ${B[1.5]};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/* Component styles — no positioning */
|
|
251
|
+
.vd-camera-controls {
|
|
252
|
+
display: flex;
|
|
253
|
+
flex-direction: column;
|
|
254
|
+
gap: ${B[1]};
|
|
255
|
+
background: color-mix(in oklch, ${z.white} 85%, transparent);
|
|
256
|
+
backdrop-filter: blur(8px);
|
|
257
|
+
border-radius: ${B[2]};
|
|
258
|
+
padding: ${B[2]};
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
.vd-zoom {
|
|
262
|
+
display: flex;
|
|
263
|
+
gap: ${B[.5]};
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.vd-dpad {
|
|
267
|
+
display: grid;
|
|
268
|
+
grid-template-columns: repeat(3, ${B[9]});
|
|
269
|
+
grid-template-rows: repeat(3, ${B[9]});
|
|
270
|
+
gap: ${B[.5]};
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
.vd-dpad-up { grid-column: 2; grid-row: 1; }
|
|
274
|
+
.vd-dpad-left { grid-column: 1; grid-row: 2; }
|
|
275
|
+
.vd-dpad-center { grid-column: 2; grid-row: 2; }
|
|
276
|
+
.vd-dpad-right { grid-column: 3; grid-row: 2; }
|
|
277
|
+
.vd-dpad-down { grid-column: 2; grid-row: 3; }
|
|
278
|
+
|
|
279
|
+
.vd-attributes {
|
|
280
|
+
display: flex;
|
|
281
|
+
flex-direction: column;
|
|
282
|
+
gap: ${B[2]};
|
|
283
|
+
background: color-mix(in oklch, ${z.white} 85%, transparent);
|
|
284
|
+
backdrop-filter: blur(8px);
|
|
285
|
+
border-radius: ${B[2]};
|
|
286
|
+
padding: ${B[2]};
|
|
287
|
+
font-family: ${Dn};
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.vd-attribute {
|
|
291
|
+
display: flex;
|
|
292
|
+
flex-direction: column;
|
|
293
|
+
gap: ${B[1]};
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.vd-attribute-label {
|
|
297
|
+
font-size: ${V.fontSize.xs};
|
|
298
|
+
font-weight: ${V.fontWeight.medium};
|
|
299
|
+
color: ${z.neutral[900]};
|
|
300
|
+
font-family: ${Dn};
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
`;function kn(){if(dn(),document.getElementById(`vd-styles`)!==null)return;let e=document.createElement(`style`);e.id=`vd-styles`,e.textContent=On,document.head.appendChild(e)}function An(e,t){let n=document.createElement(`a`);n.href=`data:image/png;base64,${e}`,n.download=t,n.click()}var jn=class{options;settings={};container=null;loading=null;slots={topRight:null,bottomLeft:null,bottomRight:null};screenshotBtn=null;actionBar=null;cameraControls=null;attributes=null;constructor(e){this.options=e}attach(e){kn(),this.container=e,this.loading=new bn(e),this.slots.topRight=this.createSlot(e,`vd-slot-top-right`),this.slots.bottomLeft=this.createSlot(e,`vd-slot-bottom-left`),this.slots.bottomRight=this.createSlot(e,`vd-slot-bottom-right`)}onReady(){this.loading?.hide(),this.loading=null,this.mountToolbar(),this.cameraControls!==null&&(this.cameraControls.element.style.display=`flex`),this.attributes!==null&&(this.attributes.style.display=`flex`)}mountToolbar(){if(this.actionBar!==null||this.slots.bottomRight===null||this.container===null)return;let e=typeof this.container.requestFullscreen==`function`;this.actionBar=new xn({onAr:this.options.onAr,onFullscreen:e?()=>{this.toggleFullscreen()}:void 0}),this.actionBar.applySettings(this.settings),this.slots.bottomRight.appendChild(this.actionBar.element),this.syncScreenshotButton(),this.placeScreenshotButton()}toggleFullscreen(){this.container!==null&&(document.fullscreenElement===null?this.container.requestFullscreen():document.exitFullscreen())}updateProgress(e,t){this.loading?.updateProgress(e,t)}showError(e){this.loading?.showError(e)}applyViewerSettings(e){this.settings=e,e.language!==void 0&&O(e.language,{reload:!1}),this.syncScreenshotButton(),this.actionBar?.applySettings(e),this.cameraControls!==null&&(this.cameraControls.element.style.display=e.cameraControls===!0?`flex`:`none`),this.placeScreenshotButton()}renderAttributeControls(e,t){if(!(this.container===null||this.slots.topRight===null)&&(this.cameraControls?.element.remove(),this.cameraControls=null,this.attributes?.remove(),this.attributes=null,this.settings.cameraControls===!0&&(this.cameraControls=new Sn(this.options.cameraApi,this.options.cameraPositionApi),this.cameraControls.element.style.display=`none`,this.slots.topRight.appendChild(this.cameraControls.element)),this.placeScreenshotButton(),!(t.length===0||this.settings.attributeControls===!1))){this.attributes=document.createElement(`div`),this.attributes.className=`vd-attributes`,this.attributes.style.display=`none`;for(let n of t)this.attributes.appendChild(En(n,e,this.options.eventBus,this.options.onSelect,this.options.onSubscribe));this.slots.bottomLeft.appendChild(this.attributes)}}get viewerSettings(){return this.settings}destroy(){this.loading?.destroy(),this.screenshotBtn?.element.remove(),this.actionBar?.destroy(),this.actionBar?.element.remove(),this.cameraControls?.element.remove(),this.attributes?.remove();for(let e of Object.values(this.slots))e?.remove();this.container=null}createSlot(e,t){let n=document.createElement(`div`);return n.className=t,e.appendChild(n),n}syncScreenshotButton(){let e=this.settings.screenshot===!0;e&&this.screenshotBtn===null&&(this.screenshotBtn=new R({variant:`outline`,size:`icon`,label:gt(),icon:L.screenshot(),onClick:()=>{this.options.snapshotApi.take(`snapshot.png`).onDeveloped(({data:e,filename:t})=>{An(e,t)})}})),!e&&this.screenshotBtn!==null&&(this.screenshotBtn.element.remove(),this.screenshotBtn=null)}placeScreenshotButton(){this.screenshotBtn===null||this.slots.topRight===null||(this.cameraControls===null?this.slots.topRight.appendChild(this.screenshotBtn.element):this.cameraControls.element.appendChild(this.screenshotBtn.element))}},Mn=class{attributes;readyStateTracker;messenger;cameraApi;cameraPositionApi;snapshotApi;annotationsApi;eventBus;ui;qrModal;options;iframe;container;readyCallbacks=[];mutationFailedCallbacks=[];constructor(e){this.options=e,this.initializeLogging(),this.messenger=new ge(()=>this.iframe?.contentWindow??null);let t=e=>{this.messenger.send(e)};this.attributes=new ye(t,(e,t)=>{for(let n of this.mutationFailedCallbacks)n({attribute:e,value:t})}),this.snapshotApi=new Ce(t),this.annotationsApi=new S(t),this.cameraApi=new be(t),this.cameraPositionApi=new xe,this.eventBus=new we,this.qrModal=new cn,this.readyStateTracker=new ie(()=>{let e=this.readyCallbacks;this.readyCallbacks=[];for(let t of e)t(this);this.ui.onReady()}),this.ui=new jn({snapshotApi:this.snapshotApi,cameraApi:this.cameraApi,cameraPositionApi:this.cameraPositionApi,eventBus:this.eventBus,onSelect:(e,t)=>this.attributes.select(e,t),onSubscribe:(e,t)=>this.attributes.onChange(e,t),onAr:()=>{this.activateAr()}}),this.registerHandlers(),this.messenger.start(),this.createAndConnectIframe()}registerHandlers(){this.messenger.on(b.HANDSHAKE,e=>{se(e)&&(y.info(`Server handshake received, flushing publisher queue`),this.messenger.markReady())}),this.messenger.on(b.MUTATION,e=>{ce(e)&&this.attributes.handleMutationResult(e)}),this.messenger.on(b.SNAPSHOT,e=>{le(e)&&this.snapshotApi.handleSnapshotResult(e)}),this.messenger.on(b.CAMERA,e=>{ue(e)&&this.cameraPositionApi.handlePositionUpdate(e)}),this.messenger.on(b.LOADING_INDICATOR,e=>{fe(e)&&(e.error===void 0?this.ui.updateProgress(e.progress,e.phase):this.ui.showError(e.error))}),this.messenger.on(b.CONFIG,e=>{pe(e)&&this.handleConfig(e)}),this.messenger.on(b.ANNOTATION_PLACED,e=>{me(e)&&this.annotationsApi.handlePlaced(e.position)}),this.messenger.on(b.MAPPING,e=>{de(e)&&(this.attributes.handleMappingReceived(e),this.ui.renderAttributeControls(this.attributes,e.attributes),this.readyStateTracker.handleMappingReceived())})}handleConfig(e){let t=e.viewerSettings,n=this.options.viewerSettings;if(t!==void 0||n!==void 0){let e=n===void 0?t:{...t??{},...n};if(n!==void 0&&t!==void 0){let e=Object.entries(n).filter(([e,n])=>t[e]!==n).map(([e,n])=>`${e} (metadata: ${t[e]??`undefined`}, override: ${n})`);e.length>0&&y.warn(`Viewer settings override active: ${e.join(`, `)}`)}this.ui.applyViewerSettings(e),this.annotationsApi.setEnabled(e.annotations!==!1)}this.cameraPositionApi.applyLimits(e.cameraLimits)}activateAr(){if(h()){this.messenger.send({type:b.AR_ACTIVATE});return}this.qrModal.show(this.iframe?.src??``)}initializeLogging(){this.options.debug===!0&&ne(),y.info(`Initializing Virtualdisplay client`,{model:this.options.model})}createAndConnectIframe(){let e=new r(this.options).create();this.container=e.container,this.iframe=e.iframe,this.eventBus.attach(this.container),this.ui.attach(this.container);try{let e=new URL(this.iframe.src).origin;this.messenger.setTargetOrigin(e)}catch{}}select(e,t){this.attributes.select(e,t)}getValues(e){return this.attributes.getValues(e)}getValue(e,t){return this.attributes.getValue(e,t)}onChange(e,t){this.attributes.onChange(e,t)}getAttribute(e){return this.attributes.getAttribute(e)}get isReady(){return this.readyStateTracker.isReady}onReady(e){if(this.readyStateTracker.isReady){e(this);return}this.readyCallbacks.push(e)}onMutationFailed(e){this.mutationFailedCallbacks.push(e)}on(e,t){this.eventBus.on(e,t)}get annotations(){return this.annotationsApi}get camera(){return this.cameraApi}get cameraPosition(){return this.cameraPositionApi}get snapshot(){return this.snapshotApi}get viewerSettings(){return this.ui.viewerSettings}destroy(){this.readyStateTracker.clear(),this.readyCallbacks=[],this.messenger.destroy(),this.qrModal.hide(),this.ui.destroy(),this.container?.parentElement!==null&&this.container?.parentElement!==void 0&&this.container.parentElement.removeChild(this.container),this.container=void 0,this.iframe=void 0}};exports.Annotations=S,exports.Attribute=_e,exports.AttributeValue=C,exports.Camera=be,exports.ERROR_CODES=t,exports.Photo=Se,exports.Snapshot=Ce,exports.VirtualdisplayClient=Mn,exports.VirtualdisplayError=n,exports.enableDebugMode=ne,exports.isDebugMode=re,Object.defineProperty(exports,`logger`,{enumerable:!0,get:function(){return y}});
|