@multisetai/vps 1.0.7-beta.3 → 1.0.7-beta.5

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/README.md CHANGED
@@ -144,6 +144,8 @@ interface IMultisetSdkConfig {
144
144
  endpoints?: Partial<IMultisetSdkEndpoints>;
145
145
  /** If true, show the VPS map mesh in the AR session (map-only). */
146
146
  showMesh?: boolean;
147
+ /** If true, show the coordinate gizmo when a pose is found. Defaults to true. */
148
+ showGizmo?: boolean;
147
149
 
148
150
  // Localization behavior
149
151
  /** If true, automatically start a localization run when the AR session starts. */
@@ -148,10 +148,6 @@ interface IMultisetSdkConfig {
148
148
  confidenceCheck?: boolean;
149
149
  /** Minimum confidence (0.2–0.8) required when confidenceCheck is enabled. */
150
150
  confidenceThreshold?: number;
151
- /** Total single-frame attempts per localization run (1–5). */
152
- requestAttempts?: number;
153
- /** Time in seconds between attempts in a localization run (1–5). */
154
- localizationInterval?: number;
155
151
  /** Include device geo pose as a hint in localization requests. */
156
152
  passGeoPose?: boolean;
157
153
  /** Request geo coordinates in the localization response (if supported by backend). */
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/core/config.ts","../../src/lib/core/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { ILocalizeAndMapDetails, MapType } from './types';\n\n/** The subset of config that is safe to expose publicly (no credentials). */\nexport type IMultisetPublicConfig = Omit<IMultisetSdkConfig, 'clientId' | 'clientSecret'>;\n\nexport interface IMultisetSdkConfig {\n clientId: string;\n clientSecret: string;\n /** Map or map-set code used for localization. */\n code: string;\n /** Map or map-set type ('map' or 'map-set'). */\n mapType: MapType;\n endpoints?: Partial<IMultisetSdkEndpoints>;\n /** If true, show the mesh in the AR session. Default is false. */\n showMesh?: boolean;\n /** If true, show the coordinate gizmo when a pose is found. Defaults to true. */\n showGizmo?: boolean;\n /** If true, automatically start a localization run when the AR session starts. */\n autoLocalize?: boolean;\n /** If true, automatically re-localize when tracking is lost and then recovered. */\n relocalization?: boolean;\n /** When enabled, only accept a localization result if confidence >= confidenceThreshold. */\n confidenceCheck?: boolean;\n /** Minimum confidence (0.2–0.8) required when confidenceCheck is enabled. */\n confidenceThreshold?: number;\n /** Total single-frame attempts per localization run (1–5). */\n requestAttempts?: number;\n /** Time in seconds between attempts in a localization run (1–5). */\n localizationInterval?: number;\n /** Include device geo pose as a hint in localization requests. */\n passGeoPose?: boolean;\n /** Request geo coordinates in the localization response (if supported by backend). */\n geoCoordinatesInResponse?: boolean;\n /** Max time in ms to wait for a valid viewer pose before failing. Default 10000. */\n localizationTrackingTimeoutMs?: number;\n\n /** Invoked at the start of a localization run. */\n onLocalizationInit?: () => void;\n /** Invoked after a successful localization that meets confidence criteria (if enabled). */\n onLocalizationSuccess?: (result: ILocalizeAndMapDetails) => void;\n /** Invoked when all attempts fail or the best result is below the confidence threshold. */\n onLocalizationFailure?: (reason?: string) => void;\n\n /** Called after a successful authorization with the access token. */\n onAuthorize?: (token: string) => void;\n /** Called whenever a camera frame is captured and sent for localization. */\n onFrameCaptured?: (payload: IFrameCaptureEvent) => void;\n /** Called with the camera intrinsics used for a localization request. */\n onCameraIntrinsics?: (intrinsics: ICameraIntrinsicsEvent) => void;\n /** Called with the raw pose/localization result returned by the backend. */\n onPoseResult?: (payload: IPoseResultEvent) => void;\n /** Called when any error occurs during authorization or localization. */\n onError?: (error: unknown) => void;\n}\n\nexport interface IMultisetSdkEndpoints {\n authUrl: string;\n queryUrl: string;\n mapDetailsUrl: string;\n fileDownloadUrl: string;\n mapSetDetailsUrl: string;\n}\n\nexport interface IFrameCaptureEvent {\n blob: Blob;\n width: number;\n height: number;\n}\n\nexport interface ICameraIntrinsicsEvent {\n fx: number;\n fy: number;\n px: number;\n py: number;\n width: number;\n height: number;\n}\n\nexport interface IPoseResultEvent {\n poseFound: boolean;\n position: {\n x: number;\n y: number;\n z: number;\n };\n rotation: {\n x: number;\n y: number;\n z: number;\n w: number;\n };\n mapIds: string[];\n confidence?: number;\n}\n\nexport interface ILocalizeResultEvent {\n frame: IFrameCaptureEvent;\n intrinsics: ICameraIntrinsicsEvent;\n response: ILocalizeAndMapDetails | null;\n}\n\nexport const DEFAULT_ENDPOINTS: IMultisetSdkEndpoints = {\n authUrl: 'https://api.multiset.ai/v1/m2m/token',\n queryUrl: 'https://api.multiset.ai/v1/vps/map/query-form',\n mapDetailsUrl: 'https://api.multiset.ai/v1/vps/map/',\n mapSetDetailsUrl: 'https://api.multiset.ai/v1/vps/map-set/',\n fileDownloadUrl: 'https://api.multiset.ai/v1/file',\n};\n","import axios, { AxiosError } from 'axios';\nimport type {\n IMultisetSdkConfig,\n IMultisetPublicConfig,\n IMultisetSdkEndpoints,\n IFrameCaptureEvent,\n ICameraIntrinsicsEvent,\n} from './config';\nimport { DEFAULT_ENDPOINTS } from './config';\nimport type {\n ILocalizeAndMapDetails,\n ILocalizeResponse,\n IGetMapsDetailsResponse,\n} from './types';\n\nexport class MultisetClient {\n private readonly credentials: { clientId: string; clientSecret: string };\n private readonly config: IMultisetPublicConfig;\n private readonly endpoints: IMultisetSdkEndpoints;\n private accessToken: string | null = null;\n private mapDetailsCache: Record<string, IGetMapsDetailsResponse> = {};\n\n constructor(input: IMultisetSdkConfig) {\n const { clientId, clientSecret, ...rest } = input;\n this.credentials = { clientId, clientSecret };\n this.config = rest;\n this.endpoints = {\n ...DEFAULT_ENDPOINTS,\n ...rest.endpoints,\n };\n }\n\n get token(): string | null {\n return this.accessToken;\n }\n\n getConfig(): IMultisetPublicConfig {\n return this.config;\n }\n\n async downloadFile(key: string): Promise<string> {\n if (!this.accessToken || !key) {\n return '';\n }\n\n try {\n const response = await axios.get<{ url: string }>(\n `${this.endpoints.fileDownloadUrl}?key=${encodeURIComponent(key)}`,\n {\n headers: {\n Authorization: `Bearer ${this.accessToken}`,\n },\n }\n );\n\n return response.status === 200 ? response.data.url : '';\n } catch (error) {\n this.handleError(error);\n return '';\n }\n }\n\n async authorize(): Promise<string> {\n try {\n const response = await axios.post(\n this.endpoints.authUrl,\n {},\n {\n auth: {\n username: this.credentials.clientId,\n password: this.credentials.clientSecret,\n },\n }\n );\n\n const token: string | undefined =\n response.data?.token ?? response.data?.access_token;\n\n if (!token) {\n throw new Error('Authorization succeeded but no token was returned.');\n }\n\n this.accessToken = token;\n this.config.onAuthorize?.(token);\n return token;\n } catch (error) {\n this.handleError(error);\n throw error;\n }\n }\n\n private handleError(error: unknown): void {\n if (axios.isAxiosError(error)) {\n const axiosError = error as AxiosError;\n this.config.onError?.(axiosError);\n } else {\n this.config.onError?.(error);\n }\n }\n\n async localizeWithFrame(\n frame: IFrameCaptureEvent,\n intrinsics: ICameraIntrinsicsEvent\n ): Promise<ILocalizeAndMapDetails | null> {\n if (!this.accessToken) {\n throw new Error('Access token is missing. Call authorize() first.');\n }\n\n this.config.onFrameCaptured?.(frame);\n this.config.onCameraIntrinsics?.(intrinsics);\n\n const queryResult = await this.queryLocalization(frame, intrinsics);\n\n if (queryResult?.localizeData?.poseFound) {\n this.config.onPoseResult?.(queryResult.localizeData);\n }\n\n return queryResult;\n }\n\n private async getGeoPoseComponents(): Promise<\n { latitude: number, longitude: number, altitude: number } | null\n > {\n if (\n typeof navigator === 'undefined' ||\n !('geolocation' in navigator) ||\n !navigator.geolocation\n ) {\n return null;\n }\n\n try {\n const position = await new Promise<GeolocationPosition>((resolve, reject) => {\n navigator.geolocation.getCurrentPosition(resolve, reject, {\n enableHighAccuracy: true,\n timeout: 10000,\n maximumAge: 0,\n });\n });\n\n const { latitude, longitude, altitude } = position.coords;\n const safeAltitude =\n typeof altitude === 'number' && !Number.isNaN(altitude) ? altitude : 0.0;\n\n return { latitude, longitude, altitude: safeAltitude };\n } catch {\n return null;\n }\n }\n\n private async queryLocalization(\n frame: IFrameCaptureEvent,\n intrinsics: ICameraIntrinsicsEvent\n ): Promise<ILocalizeAndMapDetails | null> {\n const formData = new FormData();\n\n if (this.config.mapType === 'map') {\n formData.append('mapCode', this.config.code);\n } else {\n formData.append('mapSetCode', this.config.code);\n }\n formData.append('isRightHanded', 'true');\n formData.append('fx', `${intrinsics.fx}`);\n formData.append('fy', `${intrinsics.fy}`);\n formData.append('px', `${intrinsics.px}`);\n formData.append('py', `${intrinsics.py}`);\n formData.append('width', `${frame.width}`);\n formData.append('height', `${frame.height}`);\n formData.append('queryImage', frame.blob);\n if (this.config.geoCoordinatesInResponse) {\n formData.append('geoCoordinatesInResponse', 'true');\n }\n if (this.config.passGeoPose) {\n const components = await this.getGeoPoseComponents();\n if (components) {\n const { latitude, longitude, altitude } = components;\n const geoHint = `${latitude},${longitude},${altitude}`;\n formData.append('geoHint', geoHint);\n }\n }\n\n try {\n const response = await axios.post<ILocalizeResponse>(\n this.endpoints.queryUrl,\n formData,\n {\n headers: {\n Authorization: `Bearer ${this.accessToken}`,\n },\n }\n );\n\n const data = response.data;\n if (!data.poseFound) {\n return null;\n }\n\n const result: ILocalizeAndMapDetails = {\n localizeData: data,\n };\n\n if (\n this.config.showMesh &&\n data.mapCodes?.length\n ) {\n const mapCode = data.mapCodes[0];\n const cached = this.mapDetailsCache[mapCode];\n if (cached) {\n result.mapDetails = cached;\n } else {\n const mapDetails = await this.fetchMapDetails(mapCode);\n if (mapDetails) {\n this.mapDetailsCache[mapCode] = mapDetails;\n result.mapDetails = mapDetails;\n }\n }\n }\n\n return result;\n } catch (error) {\n this.handleError(error);\n return null;\n }\n }\n\n private async fetchMapDetails(mapCode: string): Promise<IGetMapsDetailsResponse | null> {\n try {\n const response = await axios.get<IGetMapsDetailsResponse>(\n `${this.endpoints.mapDetailsUrl}${mapCode}`,\n {\n headers: {\n Authorization: `Bearer ${this.accessToken}`,\n },\n }\n );\n return response.data;\n } catch (error) {\n this.handleError(error);\n return null;\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/lib/core/config.ts","../../src/lib/core/client.ts"],"names":[],"mappings":";;;AAiGO,IAAM,iBAAA,GAA2C;AAAA,EACtD,OAAA,EAAS,sCAAA;AAAA,EACT,QAAA,EAAU,+CAAA;AAAA,EACV,aAAA,EAAe,qCAAA;AAAA,EACf,gBAAA,EAAkB,yCAAA;AAAA,EAClB,eAAA,EAAiB;AACnB;ACxFO,IAAM,iBAAN,MAAqB;AAAA,EAO1B,YAAY,KAAA,EAA2B;AAHvC,IAAA,IAAA,CAAQ,WAAA,GAA6B,IAAA;AACrC,IAAA,IAAA,CAAQ,kBAA2D,EAAC;AAGlE,IAAA,MAAM,EAAE,QAAA,EAAU,YAAA,EAAc,GAAG,MAAK,GAAI,KAAA;AAC5C,IAAA,IAAA,CAAK,WAAA,GAAc,EAAE,QAAA,EAAU,YAAA,EAAa;AAC5C,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AACd,IAAA,IAAA,CAAK,SAAA,GAAY;AAAA,MACf,GAAG,iBAAA;AAAA,MACH,GAAG,IAAA,CAAK;AAAA,KACV;AAAA,EACF;AAAA,EAEA,IAAI,KAAA,GAAuB;AACzB,IAAA,OAAO,IAAA,CAAK,WAAA;AAAA,EACd;AAAA,EAEA,SAAA,GAAmC;AACjC,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA,EAEA,MAAM,aAAa,GAAA,EAA8B;AAC/C,IAAA,IAAI,CAAC,IAAA,CAAK,WAAA,IAAe,CAAC,GAAA,EAAK;AAC7B,MAAA,OAAO,EAAA;AAAA,IACT;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA;AAAA,QAC3B,GAAG,IAAA,CAAK,SAAA,CAAU,eAAe,CAAA,KAAA,EAAQ,kBAAA,CAAmB,GAAG,CAAC,CAAA,CAAA;AAAA,QAChE;AAAA,UACE,OAAA,EAAS;AAAA,YACP,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,WAAW,CAAA;AAAA;AAC3C;AACF,OACF;AAEA,MAAA,OAAO,QAAA,CAAS,MAAA,KAAW,GAAA,GAAM,QAAA,CAAS,KAAK,GAAA,GAAM,EAAA;AAAA,IACvD,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,YAAY,KAAK,CAAA;AACtB,MAAA,OAAO,EAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,SAAA,GAA6B;AACjC,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,IAAA;AAAA,QAC3B,KAAK,SAAA,CAAU,OAAA;AAAA,QACf,EAAC;AAAA,QACD;AAAA,UACE,IAAA,EAAM;AAAA,YACJ,QAAA,EAAU,KAAK,WAAA,CAAY,QAAA;AAAA,YAC3B,QAAA,EAAU,KAAK,WAAA,CAAY;AAAA;AAC7B;AACF,OACF;AAEA,MAAA,MAAM,KAAA,GACJ,QAAA,CAAS,IAAA,EAAM,KAAA,IAAS,SAAS,IAAA,EAAM,YAAA;AAEzC,MAAA,IAAI,CAAC,KAAA,EAAO;AACV,QAAA,MAAM,IAAI,MAAM,oDAAoD,CAAA;AAAA,MACtE;AAEA,MAAA,IAAA,CAAK,WAAA,GAAc,KAAA;AACnB,MAAA,IAAA,CAAK,MAAA,CAAO,cAAc,KAAK,CAAA;AAC/B,MAAA,OAAO,KAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,YAAY,KAAK,CAAA;AACtB,MAAA,MAAM,KAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEQ,YAAY,KAAA,EAAsB;AACxC,IAAA,IAAI,KAAA,CAAM,YAAA,CAAa,KAAK,CAAA,EAAG;AAC7B,MAAA,MAAM,UAAA,GAAa,KAAA;AACnB,MAAA,IAAA,CAAK,MAAA,CAAO,UAAU,UAAU,CAAA;AAAA,IAClC,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,MAAA,CAAO,UAAU,KAAK,CAAA;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,MAAM,iBAAA,CACJ,KAAA,EACA,UAAA,EACwC;AACxC,IAAA,IAAI,CAAC,KAAK,WAAA,EAAa;AACrB,MAAA,MAAM,IAAI,MAAM,kDAAkD,CAAA;AAAA,IACpE;AAEA,IAAA,IAAA,CAAK,MAAA,CAAO,kBAAkB,KAAK,CAAA;AACnC,IAAA,IAAA,CAAK,MAAA,CAAO,qBAAqB,UAAU,CAAA;AAE3C,IAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,iBAAA,CAAkB,OAAO,UAAU,CAAA;AAElE,IAAA,IAAI,WAAA,EAAa,cAAc,SAAA,EAAW;AACxC,MAAA,IAAA,CAAK,MAAA,CAAO,YAAA,GAAe,WAAA,CAAY,YAAY,CAAA;AAAA,IACrD;AAEA,IAAA,OAAO,WAAA;AAAA,EACT;AAAA,EAEA,MAAc,oBAAA,GAEZ;AACA,IAAA,IACE,OAAO,cAAc,WAAA,IACrB,EAAE,iBAAiB,SAAA,CAAA,IACnB,CAAC,UAAU,WAAA,EACX;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,WAAW,MAAM,IAAI,OAAA,CAA6B,CAAC,SAAS,MAAA,KAAW;AAC3E,QAAA,SAAA,CAAU,WAAA,CAAY,kBAAA,CAAmB,OAAA,EAAS,MAAA,EAAQ;AAAA,UACxD,kBAAA,EAAoB,IAAA;AAAA,UACpB,OAAA,EAAS,GAAA;AAAA,UACT,UAAA,EAAY;AAAA,SACb,CAAA;AAAA,MACH,CAAC,CAAA;AAED,MAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,QAAA,KAAa,QAAA,CAAS,MAAA;AACnD,MAAA,MAAM,YAAA,GACJ,OAAO,QAAA,KAAa,QAAA,IAAY,CAAC,MAAA,CAAO,KAAA,CAAM,QAAQ,CAAA,GAAI,QAAA,GAAW,CAAA;AAEvE,MAAA,OAAO,EAAE,QAAA,EAAU,SAAA,EAAW,QAAA,EAAU,YAAA,EAAa;AAAA,IACvD,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAc,iBAAA,CACZ,KAAA,EACA,UAAA,EACwC;AACxC,IAAA,MAAM,QAAA,GAAW,IAAI,QAAA,EAAS;AAE9B,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,OAAA,KAAY,KAAA,EAAO;AACjC,MAAA,QAAA,CAAS,MAAA,CAAO,SAAA,EAAW,IAAA,CAAK,MAAA,CAAO,IAAI,CAAA;AAAA,IAC7C,CAAA,MAAO;AACL,MAAA,QAAA,CAAS,MAAA,CAAO,YAAA,EAAc,IAAA,CAAK,MAAA,CAAO,IAAI,CAAA;AAAA,IAChD;AACA,IAAA,QAAA,CAAS,MAAA,CAAO,iBAAiB,MAAM,CAAA;AACvC,IAAA,QAAA,CAAS,MAAA,CAAO,IAAA,EAAM,CAAA,EAAG,UAAA,CAAW,EAAE,CAAA,CAAE,CAAA;AACxC,IAAA,QAAA,CAAS,MAAA,CAAO,IAAA,EAAM,CAAA,EAAG,UAAA,CAAW,EAAE,CAAA,CAAE,CAAA;AACxC,IAAA,QAAA,CAAS,MAAA,CAAO,IAAA,EAAM,CAAA,EAAG,UAAA,CAAW,EAAE,CAAA,CAAE,CAAA;AACxC,IAAA,QAAA,CAAS,MAAA,CAAO,IAAA,EAAM,CAAA,EAAG,UAAA,CAAW,EAAE,CAAA,CAAE,CAAA;AACxC,IAAA,QAAA,CAAS,MAAA,CAAO,OAAA,EAAS,CAAA,EAAG,KAAA,CAAM,KAAK,CAAA,CAAE,CAAA;AACzC,IAAA,QAAA,CAAS,MAAA,CAAO,QAAA,EAAU,CAAA,EAAG,KAAA,CAAM,MAAM,CAAA,CAAE,CAAA;AAC3C,IAAA,QAAA,CAAS,MAAA,CAAO,YAAA,EAAc,KAAA,CAAM,IAAI,CAAA;AACxC,IAAA,IAAI,IAAA,CAAK,OAAO,wBAAA,EAA0B;AACxC,MAAA,QAAA,CAAS,MAAA,CAAO,4BAA4B,MAAM,CAAA;AAAA,IACpD;AACA,IAAA,IAAI,IAAA,CAAK,OAAO,WAAA,EAAa;AAC3B,MAAA,MAAM,UAAA,GAAa,MAAM,IAAA,CAAK,oBAAA,EAAqB;AACnD,MAAA,IAAI,UAAA,EAAY;AACd,QAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,QAAA,EAAS,GAAI,UAAA;AAC1C,QAAA,MAAM,UAAU,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,SAAS,IAAI,QAAQ,CAAA,CAAA;AACpD,QAAA,QAAA,CAAS,MAAA,CAAO,WAAW,OAAO,CAAA;AAAA,MACpC;AAAA,IACF;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,IAAA;AAAA,QAC3B,KAAK,SAAA,CAAU,QAAA;AAAA,QACf,QAAA;AAAA,QACA;AAAA,UACE,OAAA,EAAS;AAAA,YACP,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,WAAW,CAAA;AAAA;AAC3C;AACF,OACF;AAEA,MAAA,MAAM,OAAO,QAAA,CAAS,IAAA;AACtB,MAAA,IAAI,CAAC,KAAK,SAAA,EAAW;AACnB,QAAA,OAAO,IAAA;AAAA,MACT;AAEA,MAAA,MAAM,MAAA,GAAiC;AAAA,QACrC,YAAA,EAAc;AAAA,OAChB;AAEA,MAAA,IACE,IAAA,CAAK,MAAA,CAAO,QAAA,IACZ,IAAA,CAAK,UAAU,MAAA,EACf;AACA,QAAA,MAAM,OAAA,GAAU,IAAA,CAAK,QAAA,CAAS,CAAC,CAAA;AAC/B,QAAA,MAAM,MAAA,GAAS,IAAA,CAAK,eAAA,CAAgB,OAAO,CAAA;AAC3C,QAAA,IAAI,MAAA,EAAQ;AACV,UAAA,MAAA,CAAO,UAAA,GAAa,MAAA;AAAA,QACtB,CAAA,MAAO;AACL,UAAA,MAAM,UAAA,GAAa,MAAM,IAAA,CAAK,eAAA,CAAgB,OAAO,CAAA;AACrD,UAAA,IAAI,UAAA,EAAY;AACd,YAAA,IAAA,CAAK,eAAA,CAAgB,OAAO,CAAA,GAAI,UAAA;AAChC,YAAA,MAAA,CAAO,UAAA,GAAa,UAAA;AAAA,UACtB;AAAA,QACF;AAAA,MACF;AAEA,MAAA,OAAO,MAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,YAAY,KAAK,CAAA;AACtB,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAc,gBAAgB,OAAA,EAA0D;AACtF,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA;AAAA,QAC3B,CAAA,EAAG,IAAA,CAAK,SAAA,CAAU,aAAa,GAAG,OAAO,CAAA,CAAA;AAAA,QACzC;AAAA,UACE,OAAA,EAAS;AAAA,YACP,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,WAAW,CAAA;AAAA;AAC3C;AACF,OACF;AACA,MAAA,OAAO,QAAA,CAAS,IAAA;AAAA,IAClB,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,YAAY,KAAK,CAAA;AACtB,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AACF","file":"index.js","sourcesContent":["import type { ILocalizeAndMapDetails, MapType } from './types';\n\n/** The subset of config that is safe to expose publicly (no credentials). */\nexport type IMultisetPublicConfig = Omit<IMultisetSdkConfig, 'clientId' | 'clientSecret'>;\n\nexport interface IMultisetSdkConfig {\n clientId: string;\n clientSecret: string;\n /** Map or map-set code used for localization. */\n code: string;\n /** Map or map-set type ('map' or 'map-set'). */\n mapType: MapType;\n endpoints?: Partial<IMultisetSdkEndpoints>;\n /** If true, show the mesh in the AR session. Default is false. */\n showMesh?: boolean;\n /** If true, show the coordinate gizmo when a pose is found. Defaults to true. */\n showGizmo?: boolean;\n /** If true, automatically start a localization run when the AR session starts. */\n autoLocalize?: boolean;\n /** If true, automatically re-localize when tracking is lost and then recovered. */\n relocalization?: boolean;\n /** When enabled, only accept a localization result if confidence >= confidenceThreshold. */\n confidenceCheck?: boolean;\n /** Minimum confidence (0.2–0.8) required when confidenceCheck is enabled. */\n confidenceThreshold?: number;\n /** Include device geo pose as a hint in localization requests. */\n passGeoPose?: boolean;\n /** Request geo coordinates in the localization response (if supported by backend). */\n geoCoordinatesInResponse?: boolean;\n /** Max time in ms to wait for a valid viewer pose before failing. Default 10000. */\n localizationTrackingTimeoutMs?: number;\n\n /** Invoked at the start of a localization run. */\n onLocalizationInit?: () => void;\n /** Invoked after a successful localization that meets confidence criteria (if enabled). */\n onLocalizationSuccess?: (result: ILocalizeAndMapDetails) => void;\n /** Invoked when all attempts fail or the best result is below the confidence threshold. */\n onLocalizationFailure?: (reason?: string) => void;\n\n /** Called after a successful authorization with the access token. */\n onAuthorize?: (token: string) => void;\n /** Called whenever a camera frame is captured and sent for localization. */\n onFrameCaptured?: (payload: IFrameCaptureEvent) => void;\n /** Called with the camera intrinsics used for a localization request. */\n onCameraIntrinsics?: (intrinsics: ICameraIntrinsicsEvent) => void;\n /** Called with the raw pose/localization result returned by the backend. */\n onPoseResult?: (payload: IPoseResultEvent) => void;\n /** Called when any error occurs during authorization or localization. */\n onError?: (error: unknown) => void;\n}\n\nexport interface IMultisetSdkEndpoints {\n authUrl: string;\n queryUrl: string;\n mapDetailsUrl: string;\n fileDownloadUrl: string;\n mapSetDetailsUrl: string;\n}\n\nexport interface IFrameCaptureEvent {\n blob: Blob;\n width: number;\n height: number;\n}\n\nexport interface ICameraIntrinsicsEvent {\n fx: number;\n fy: number;\n px: number;\n py: number;\n width: number;\n height: number;\n}\n\nexport interface IPoseResultEvent {\n poseFound: boolean;\n position: {\n x: number;\n y: number;\n z: number;\n };\n rotation: {\n x: number;\n y: number;\n z: number;\n w: number;\n };\n mapIds: string[];\n confidence?: number;\n}\n\nexport interface ILocalizeResultEvent {\n frame: IFrameCaptureEvent;\n intrinsics: ICameraIntrinsicsEvent;\n response: ILocalizeAndMapDetails | null;\n}\n\nexport const DEFAULT_ENDPOINTS: IMultisetSdkEndpoints = {\n authUrl: 'https://api.multiset.ai/v1/m2m/token',\n queryUrl: 'https://api.multiset.ai/v1/vps/map/query-form',\n mapDetailsUrl: 'https://api.multiset.ai/v1/vps/map/',\n mapSetDetailsUrl: 'https://api.multiset.ai/v1/vps/map-set/',\n fileDownloadUrl: 'https://api.multiset.ai/v1/file',\n};\n","import axios, { AxiosError } from 'axios';\nimport type {\n IMultisetSdkConfig,\n IMultisetPublicConfig,\n IMultisetSdkEndpoints,\n IFrameCaptureEvent,\n ICameraIntrinsicsEvent,\n} from './config';\nimport { DEFAULT_ENDPOINTS } from './config';\nimport type {\n ILocalizeAndMapDetails,\n ILocalizeResponse,\n IGetMapsDetailsResponse,\n} from './types';\n\nexport class MultisetClient {\n private readonly credentials: { clientId: string; clientSecret: string };\n private readonly config: IMultisetPublicConfig;\n private readonly endpoints: IMultisetSdkEndpoints;\n private accessToken: string | null = null;\n private mapDetailsCache: Record<string, IGetMapsDetailsResponse> = {};\n\n constructor(input: IMultisetSdkConfig) {\n const { clientId, clientSecret, ...rest } = input;\n this.credentials = { clientId, clientSecret };\n this.config = rest;\n this.endpoints = {\n ...DEFAULT_ENDPOINTS,\n ...rest.endpoints,\n };\n }\n\n get token(): string | null {\n return this.accessToken;\n }\n\n getConfig(): IMultisetPublicConfig {\n return this.config;\n }\n\n async downloadFile(key: string): Promise<string> {\n if (!this.accessToken || !key) {\n return '';\n }\n\n try {\n const response = await axios.get<{ url: string }>(\n `${this.endpoints.fileDownloadUrl}?key=${encodeURIComponent(key)}`,\n {\n headers: {\n Authorization: `Bearer ${this.accessToken}`,\n },\n }\n );\n\n return response.status === 200 ? response.data.url : '';\n } catch (error) {\n this.handleError(error);\n return '';\n }\n }\n\n async authorize(): Promise<string> {\n try {\n const response = await axios.post(\n this.endpoints.authUrl,\n {},\n {\n auth: {\n username: this.credentials.clientId,\n password: this.credentials.clientSecret,\n },\n }\n );\n\n const token: string | undefined =\n response.data?.token ?? response.data?.access_token;\n\n if (!token) {\n throw new Error('Authorization succeeded but no token was returned.');\n }\n\n this.accessToken = token;\n this.config.onAuthorize?.(token);\n return token;\n } catch (error) {\n this.handleError(error);\n throw error;\n }\n }\n\n private handleError(error: unknown): void {\n if (axios.isAxiosError(error)) {\n const axiosError = error as AxiosError;\n this.config.onError?.(axiosError);\n } else {\n this.config.onError?.(error);\n }\n }\n\n async localizeWithFrame(\n frame: IFrameCaptureEvent,\n intrinsics: ICameraIntrinsicsEvent\n ): Promise<ILocalizeAndMapDetails | null> {\n if (!this.accessToken) {\n throw new Error('Access token is missing. Call authorize() first.');\n }\n\n this.config.onFrameCaptured?.(frame);\n this.config.onCameraIntrinsics?.(intrinsics);\n\n const queryResult = await this.queryLocalization(frame, intrinsics);\n\n if (queryResult?.localizeData?.poseFound) {\n this.config.onPoseResult?.(queryResult.localizeData);\n }\n\n return queryResult;\n }\n\n private async getGeoPoseComponents(): Promise<\n { latitude: number, longitude: number, altitude: number } | null\n > {\n if (\n typeof navigator === 'undefined' ||\n !('geolocation' in navigator) ||\n !navigator.geolocation\n ) {\n return null;\n }\n\n try {\n const position = await new Promise<GeolocationPosition>((resolve, reject) => {\n navigator.geolocation.getCurrentPosition(resolve, reject, {\n enableHighAccuracy: true,\n timeout: 10000,\n maximumAge: 0,\n });\n });\n\n const { latitude, longitude, altitude } = position.coords;\n const safeAltitude =\n typeof altitude === 'number' && !Number.isNaN(altitude) ? altitude : 0.0;\n\n return { latitude, longitude, altitude: safeAltitude };\n } catch {\n return null;\n }\n }\n\n private async queryLocalization(\n frame: IFrameCaptureEvent,\n intrinsics: ICameraIntrinsicsEvent\n ): Promise<ILocalizeAndMapDetails | null> {\n const formData = new FormData();\n\n if (this.config.mapType === 'map') {\n formData.append('mapCode', this.config.code);\n } else {\n formData.append('mapSetCode', this.config.code);\n }\n formData.append('isRightHanded', 'true');\n formData.append('fx', `${intrinsics.fx}`);\n formData.append('fy', `${intrinsics.fy}`);\n formData.append('px', `${intrinsics.px}`);\n formData.append('py', `${intrinsics.py}`);\n formData.append('width', `${frame.width}`);\n formData.append('height', `${frame.height}`);\n formData.append('queryImage', frame.blob);\n if (this.config.geoCoordinatesInResponse) {\n formData.append('geoCoordinatesInResponse', 'true');\n }\n if (this.config.passGeoPose) {\n const components = await this.getGeoPoseComponents();\n if (components) {\n const { latitude, longitude, altitude } = components;\n const geoHint = `${latitude},${longitude},${altitude}`;\n formData.append('geoHint', geoHint);\n }\n }\n\n try {\n const response = await axios.post<ILocalizeResponse>(\n this.endpoints.queryUrl,\n formData,\n {\n headers: {\n Authorization: `Bearer ${this.accessToken}`,\n },\n }\n );\n\n const data = response.data;\n if (!data.poseFound) {\n return null;\n }\n\n const result: ILocalizeAndMapDetails = {\n localizeData: data,\n };\n\n if (\n this.config.showMesh &&\n data.mapCodes?.length\n ) {\n const mapCode = data.mapCodes[0];\n const cached = this.mapDetailsCache[mapCode];\n if (cached) {\n result.mapDetails = cached;\n } else {\n const mapDetails = await this.fetchMapDetails(mapCode);\n if (mapDetails) {\n this.mapDetailsCache[mapCode] = mapDetails;\n result.mapDetails = mapDetails;\n }\n }\n }\n\n return result;\n } catch (error) {\n this.handleError(error);\n return null;\n }\n }\n\n private async fetchMapDetails(mapCode: string): Promise<IGetMapsDetailsResponse | null> {\n try {\n const response = await axios.get<IGetMapsDetailsResponse>(\n `${this.endpoints.mapDetailsUrl}${mapCode}`,\n {\n headers: {\n Authorization: `Bearer ${this.accessToken}`,\n },\n }\n );\n return response.data;\n } catch (error) {\n this.handleError(error);\n return null;\n }\n }\n}\n"]}
package/dist/index.js CHANGED
@@ -407,7 +407,7 @@ void main() {
407
407
  `;
408
408
  function createGridMaterial(options = {}) {
409
409
  const color = options.color ?? "#7B2CBF";
410
- const opacity = options.opacity ?? 0.6;
410
+ const opacity = options.opacity ?? 150 / 255;
411
411
  const gridColor = options.gridColor ?? "#ffeb3b";
412
412
  const gridScale = options.gridScale ?? 2;
413
413
  const gridLineWidth = options.gridLineWidth ?? 0.02;
@@ -415,7 +415,7 @@ function createGridMaterial(options = {}) {
415
415
  const center = options.center ?? new THREE3.Vector3(0, 0, 0);
416
416
  const radius = options.radius ?? 1;
417
417
  const progress = options.progress ?? 1;
418
- const glowColor = options.glowColor ?? "#00ffff";
418
+ const glowColor = options.glowColor ?? "#FF3A00";
419
419
  const glowWidth = options.glowWidth ?? 0.05;
420
420
  const glowIntensity = options.glowIntensity ?? 2;
421
421
  const lightColor = options.lightColor ?? "#ffffff";
@@ -526,7 +526,7 @@ var MapMeshVisualizer = class {
526
526
  this.localRadius = Math.max(size / 2, 1e-3);
527
527
  const meshMaterial = createGridMaterial({
528
528
  color: "#7B2CBF",
529
- opacity: 0.4,
529
+ opacity: 0.58,
530
530
  gridColor: "#ffeb3b",
531
531
  gridScale: 2,
532
532
  gridLineWidth: 0.02,
@@ -534,7 +534,7 @@ var MapMeshVisualizer = class {
534
534
  center: this.localCenter.clone(),
535
535
  radius: this.localRadius,
536
536
  progress: 0,
537
- glowColor: "#00ffff",
537
+ glowColor: "#FF3A00",
538
538
  glowWidth: 0.05,
539
539
  glowIntensity: 2
540
540
  });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/core/config.ts","../src/lib/core/client.ts","../src/lib/webxr/internal/cameraIntrinsics.ts","../src/lib/webxr/internal/frameCapture.ts","../src/lib/webxr/experience/Experience.ts","../src/lib/webxr/materials/gridMaterial.ts","../src/lib/webxr/mapMeshVisualizer.ts","../src/lib/webxr/world/World.ts","../src/lib/webxr/controller.ts"],"names":["THREE","THREE2","THREE4"],"mappings":"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","file":"index.js","sourcesContent":["import type { ILocalizeAndMapDetails, MapType } from './types';\n\n/** The subset of config that is safe to expose publicly (no credentials). */\nexport type IMultisetPublicConfig = Omit<IMultisetSdkConfig, 'clientId' | 'clientSecret'>;\n\nexport interface IMultisetSdkConfig {\n clientId: string;\n clientSecret: string;\n /** Map or map-set code used for localization. */\n code: string;\n /** Map or map-set type ('map' or 'map-set'). */\n mapType: MapType;\n endpoints?: Partial<IMultisetSdkEndpoints>;\n /** If true, show the mesh in the AR session. Default is false. */\n showMesh?: boolean;\n /** If true, show the coordinate gizmo when a pose is found. Defaults to true. */\n showGizmo?: boolean;\n /** If true, automatically start a localization run when the AR session starts. */\n autoLocalize?: boolean;\n /** If true, automatically re-localize when tracking is lost and then recovered. */\n relocalization?: boolean;\n /** When enabled, only accept a localization result if confidence >= confidenceThreshold. */\n confidenceCheck?: boolean;\n /** Minimum confidence (0.2–0.8) required when confidenceCheck is enabled. */\n confidenceThreshold?: number;\n /** Total single-frame attempts per localization run (1–5). */\n requestAttempts?: number;\n /** Time in seconds between attempts in a localization run (1–5). */\n localizationInterval?: number;\n /** Include device geo pose as a hint in localization requests. */\n passGeoPose?: boolean;\n /** Request geo coordinates in the localization response (if supported by backend). */\n geoCoordinatesInResponse?: boolean;\n /** Max time in ms to wait for a valid viewer pose before failing. Default 10000. */\n localizationTrackingTimeoutMs?: number;\n\n /** Invoked at the start of a localization run. */\n onLocalizationInit?: () => void;\n /** Invoked after a successful localization that meets confidence criteria (if enabled). */\n onLocalizationSuccess?: (result: ILocalizeAndMapDetails) => void;\n /** Invoked when all attempts fail or the best result is below the confidence threshold. */\n onLocalizationFailure?: (reason?: string) => void;\n\n /** Called after a successful authorization with the access token. */\n onAuthorize?: (token: string) => void;\n /** Called whenever a camera frame is captured and sent for localization. */\n onFrameCaptured?: (payload: IFrameCaptureEvent) => void;\n /** Called with the camera intrinsics used for a localization request. */\n onCameraIntrinsics?: (intrinsics: ICameraIntrinsicsEvent) => void;\n /** Called with the raw pose/localization result returned by the backend. */\n onPoseResult?: (payload: IPoseResultEvent) => void;\n /** Called when any error occurs during authorization or localization. */\n onError?: (error: unknown) => void;\n}\n\nexport interface IMultisetSdkEndpoints {\n authUrl: string;\n queryUrl: string;\n mapDetailsUrl: string;\n fileDownloadUrl: string;\n mapSetDetailsUrl: string;\n}\n\nexport interface IFrameCaptureEvent {\n blob: Blob;\n width: number;\n height: number;\n}\n\nexport interface ICameraIntrinsicsEvent {\n fx: number;\n fy: number;\n px: number;\n py: number;\n width: number;\n height: number;\n}\n\nexport interface IPoseResultEvent {\n poseFound: boolean;\n position: {\n x: number;\n y: number;\n z: number;\n };\n rotation: {\n x: number;\n y: number;\n z: number;\n w: number;\n };\n mapIds: string[];\n confidence?: number;\n}\n\nexport interface ILocalizeResultEvent {\n frame: IFrameCaptureEvent;\n intrinsics: ICameraIntrinsicsEvent;\n response: ILocalizeAndMapDetails | null;\n}\n\nexport const DEFAULT_ENDPOINTS: IMultisetSdkEndpoints = {\n authUrl: 'https://api.multiset.ai/v1/m2m/token',\n queryUrl: 'https://api.multiset.ai/v1/vps/map/query-form',\n mapDetailsUrl: 'https://api.multiset.ai/v1/vps/map/',\n mapSetDetailsUrl: 'https://api.multiset.ai/v1/vps/map-set/',\n fileDownloadUrl: 'https://api.multiset.ai/v1/file',\n};\n","import axios, { AxiosError } from 'axios';\nimport type {\n IMultisetSdkConfig,\n IMultisetPublicConfig,\n IMultisetSdkEndpoints,\n IFrameCaptureEvent,\n ICameraIntrinsicsEvent,\n} from './config';\nimport { DEFAULT_ENDPOINTS } from './config';\nimport type {\n ILocalizeAndMapDetails,\n ILocalizeResponse,\n IGetMapsDetailsResponse,\n} from './types';\n\nexport class MultisetClient {\n private readonly credentials: { clientId: string; clientSecret: string };\n private readonly config: IMultisetPublicConfig;\n private readonly endpoints: IMultisetSdkEndpoints;\n private accessToken: string | null = null;\n private mapDetailsCache: Record<string, IGetMapsDetailsResponse> = {};\n\n constructor(input: IMultisetSdkConfig) {\n const { clientId, clientSecret, ...rest } = input;\n this.credentials = { clientId, clientSecret };\n this.config = rest;\n this.endpoints = {\n ...DEFAULT_ENDPOINTS,\n ...rest.endpoints,\n };\n }\n\n get token(): string | null {\n return this.accessToken;\n }\n\n getConfig(): IMultisetPublicConfig {\n return this.config;\n }\n\n async downloadFile(key: string): Promise<string> {\n if (!this.accessToken || !key) {\n return '';\n }\n\n try {\n const response = await axios.get<{ url: string }>(\n `${this.endpoints.fileDownloadUrl}?key=${encodeURIComponent(key)}`,\n {\n headers: {\n Authorization: `Bearer ${this.accessToken}`,\n },\n }\n );\n\n return response.status === 200 ? response.data.url : '';\n } catch (error) {\n this.handleError(error);\n return '';\n }\n }\n\n async authorize(): Promise<string> {\n try {\n const response = await axios.post(\n this.endpoints.authUrl,\n {},\n {\n auth: {\n username: this.credentials.clientId,\n password: this.credentials.clientSecret,\n },\n }\n );\n\n const token: string | undefined =\n response.data?.token ?? response.data?.access_token;\n\n if (!token) {\n throw new Error('Authorization succeeded but no token was returned.');\n }\n\n this.accessToken = token;\n this.config.onAuthorize?.(token);\n return token;\n } catch (error) {\n this.handleError(error);\n throw error;\n }\n }\n\n private handleError(error: unknown): void {\n if (axios.isAxiosError(error)) {\n const axiosError = error as AxiosError;\n this.config.onError?.(axiosError);\n } else {\n this.config.onError?.(error);\n }\n }\n\n async localizeWithFrame(\n frame: IFrameCaptureEvent,\n intrinsics: ICameraIntrinsicsEvent\n ): Promise<ILocalizeAndMapDetails | null> {\n if (!this.accessToken) {\n throw new Error('Access token is missing. Call authorize() first.');\n }\n\n this.config.onFrameCaptured?.(frame);\n this.config.onCameraIntrinsics?.(intrinsics);\n\n const queryResult = await this.queryLocalization(frame, intrinsics);\n\n if (queryResult?.localizeData?.poseFound) {\n this.config.onPoseResult?.(queryResult.localizeData);\n }\n\n return queryResult;\n }\n\n private async getGeoPoseComponents(): Promise<\n { latitude: number, longitude: number, altitude: number } | null\n > {\n if (\n typeof navigator === 'undefined' ||\n !('geolocation' in navigator) ||\n !navigator.geolocation\n ) {\n return null;\n }\n\n try {\n const position = await new Promise<GeolocationPosition>((resolve, reject) => {\n navigator.geolocation.getCurrentPosition(resolve, reject, {\n enableHighAccuracy: true,\n timeout: 10000,\n maximumAge: 0,\n });\n });\n\n const { latitude, longitude, altitude } = position.coords;\n const safeAltitude =\n typeof altitude === 'number' && !Number.isNaN(altitude) ? altitude : 0.0;\n\n return { latitude, longitude, altitude: safeAltitude };\n } catch {\n return null;\n }\n }\n\n private async queryLocalization(\n frame: IFrameCaptureEvent,\n intrinsics: ICameraIntrinsicsEvent\n ): Promise<ILocalizeAndMapDetails | null> {\n const formData = new FormData();\n\n if (this.config.mapType === 'map') {\n formData.append('mapCode', this.config.code);\n } else {\n formData.append('mapSetCode', this.config.code);\n }\n formData.append('isRightHanded', 'true');\n formData.append('fx', `${intrinsics.fx}`);\n formData.append('fy', `${intrinsics.fy}`);\n formData.append('px', `${intrinsics.px}`);\n formData.append('py', `${intrinsics.py}`);\n formData.append('width', `${frame.width}`);\n formData.append('height', `${frame.height}`);\n formData.append('queryImage', frame.blob);\n if (this.config.geoCoordinatesInResponse) {\n formData.append('geoCoordinatesInResponse', 'true');\n }\n if (this.config.passGeoPose) {\n const components = await this.getGeoPoseComponents();\n if (components) {\n const { latitude, longitude, altitude } = components;\n const geoHint = `${latitude},${longitude},${altitude}`;\n formData.append('geoHint', geoHint);\n }\n }\n\n try {\n const response = await axios.post<ILocalizeResponse>(\n this.endpoints.queryUrl,\n formData,\n {\n headers: {\n Authorization: `Bearer ${this.accessToken}`,\n },\n }\n );\n\n const data = response.data;\n if (!data.poseFound) {\n return null;\n }\n\n const result: ILocalizeAndMapDetails = {\n localizeData: data,\n };\n\n if (\n this.config.showMesh &&\n data.mapCodes?.length\n ) {\n const mapCode = data.mapCodes[0];\n const cached = this.mapDetailsCache[mapCode];\n if (cached) {\n result.mapDetails = cached;\n } else {\n const mapDetails = await this.fetchMapDetails(mapCode);\n if (mapDetails) {\n this.mapDetailsCache[mapCode] = mapDetails;\n result.mapDetails = mapDetails;\n }\n }\n }\n\n return result;\n } catch (error) {\n this.handleError(error);\n return null;\n }\n }\n\n private async fetchMapDetails(mapCode: string): Promise<IGetMapsDetailsResponse | null> {\n try {\n const response = await axios.get<IGetMapsDetailsResponse>(\n `${this.endpoints.mapDetailsUrl}${mapCode}`,\n {\n headers: {\n Authorization: `Bearer ${this.accessToken}`,\n },\n }\n );\n return response.data;\n } catch (error) {\n this.handleError(error);\n return null;\n }\n }\n}\n","import type { ICameraIntrinsicsEvent } from '../../core';\n\nexport function getCameraIntrinsics(\n projectionMatrix: Float32Array,\n viewport: XRViewport\n): ICameraIntrinsicsEvent {\n const p = projectionMatrix;\n const u0 = ((1 - p[8]) * viewport.width) / 2 + viewport.x;\n const v0 = ((1 - p[9]) * viewport.height) / 2 + viewport.y;\n const ax = (viewport.width / 2) * p[0];\n const ay = (viewport.height / 2) * p[5];\n\n return {\n fx: ax,\n fy: ay,\n px: u0,\n py: v0,\n width: viewport.width,\n height: viewport.height,\n };\n}\n","import * as THREE from 'three';\nimport type { IFrameCaptureEvent } from '../../core';\n\nexport async function compressToJpeg(\n buffer: ArrayBuffer,\n width: number,\n height: number,\n quality = 0.8\n): Promise<Blob> {\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n if (!ctx) return new Blob();\n\n const imageData = new ImageData(new Uint8ClampedArray(buffer), width, height);\n ctx.putImageData(imageData, 0, 0);\n\n return new Promise((resolve) => {\n canvas.toBlob((blob) => resolve(blob ?? new Blob()), 'image/jpeg', quality);\n });\n}\n\nexport async function getCameraTextureAsImage(\n renderer: THREE.WebGLRenderer,\n webGLTexture: WebGLTexture,\n width: number,\n height: number\n): Promise<IFrameCaptureEvent | null> {\n const gl = renderer.getContext();\n if (!gl) return null;\n\n const framebuffer = gl.createFramebuffer();\n if (!framebuffer) return null;\n\n let pixelBuffer: Uint8Array;\n try {\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.TEXTURE_2D,\n webGLTexture,\n 0\n );\n\n pixelBuffer = new Uint8Array(width * height * 4);\n gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixelBuffer);\n } finally {\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.deleteFramebuffer(framebuffer);\n }\n\n const flippedData = new Uint8ClampedArray(pixelBuffer.length);\n for (let row = 0; row < height; row += 1) {\n const sourceStart = row * width * 4;\n const destStart = (height - row - 1) * width * 4;\n flippedData.set(\n pixelBuffer.subarray(sourceStart, sourceStart + width * 4),\n destStart\n );\n }\n\n const blob = await compressToJpeg(flippedData.buffer, width, height, 0.7);\n\n if (!blob.size) {\n return null;\n }\n\n return {\n blob,\n width,\n height,\n };\n}\n","import * as THREE from 'three';\n\n/**\n * Owns the Three.js scene, camera, and renderer for the AR session.\n * Handles resize and dispose; animation loop remains in the controller.\n */\nexport class Experience {\n private scene: THREE.Scene;\n private camera: THREE.PerspectiveCamera;\n private renderer: THREE.WebGLRenderer;\n\n constructor(canvas: HTMLCanvasElement) {\n this.renderer = new THREE.WebGLRenderer({\n canvas,\n antialias: true,\n alpha: true,\n });\n this.renderer.setSize(window.innerWidth, window.innerHeight);\n this.renderer.setPixelRatio(window.devicePixelRatio);\n this.renderer.xr.enabled = true;\n\n this.camera = new THREE.PerspectiveCamera(\n 45,\n window.innerWidth / window.innerHeight,\n 0.2,\n 10000\n );\n\n this.scene = new THREE.Scene();\n this.setupLights();\n }\n\n private setupLights(): void {\n const light = new THREE.HemisphereLight(0xffffff, 0xf8f0ff, 1);\n light.position.set(0.5, 2, 0.25);\n this.scene.add(light);\n\n const diLight = new THREE.DirectionalLight('#7B2CBF');\n diLight.position.set(0, 2, 0);\n this.scene.add(diLight);\n }\n\n getScene(): THREE.Scene {\n return this.scene;\n }\n\n getCamera(): THREE.PerspectiveCamera {\n return this.camera;\n }\n\n getRenderer(): THREE.WebGLRenderer {\n return this.renderer;\n }\n\n resize(): void {\n this.camera.aspect = window.innerWidth / window.innerHeight;\n this.camera.updateProjectionMatrix();\n this.renderer.setSize(window.innerWidth, window.innerHeight);\n }\n\n dispose(): void {\n this.renderer.dispose();\n (this as unknown as { scene: THREE.Scene | null }).scene = null;\n (this as unknown as { camera: THREE.PerspectiveCamera | null }).camera = null;\n (this as unknown as { renderer: THREE.WebGLRenderer | null }).renderer = null;\n }\n}\n","import * as THREE from 'three';\n\nconst VERTEX = `\nvarying vec3 vWorldPosition;\nvarying vec3 vWorldNormal;\n\nvoid main() {\n vec4 worldPos = modelMatrix * vec4(position, 1.0);\n vWorldPosition = worldPos.xyz;\n vWorldNormal = normalize(mat3(modelMatrix) * normal);\n\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n`;\n\nconst FRAGMENT = `\nuniform vec3 uColor;\nuniform float uOpacity;\n\nuniform vec3 uGridColor;\nuniform float uGridSize;\nuniform float uGridLineWidth;\nuniform float uShowGrid;\n\nuniform vec3 uCenter;\nuniform float uRadius;\nuniform float uProgress;\n\nuniform vec3 uGlowColor;\nuniform float uGlowWidth;\nuniform float uGlowIntensity;\n\nuniform vec3 uLightColor;\nuniform vec3 uLightDirection;\n\nvarying vec3 vWorldPosition;\nvarying vec3 vWorldNormal;\n\nfloat getGridFactor(vec3 worldPos, vec3 worldNormal, float gridSize, float lineWidth) {\n vec3 absNormal = abs(worldNormal);\n vec2 gridCoord;\n\n if (absNormal.y > absNormal.x && absNormal.y > absNormal.z) {\n gridCoord = worldPos.xz / gridSize;\n } else if (absNormal.x > absNormal.z) {\n gridCoord = worldPos.yz / gridSize;\n } else {\n gridCoord = worldPos.xy / gridSize;\n }\n\n vec2 gridFract = fract(abs(gridCoord));\n vec2 distToLine = min(gridFract, 1.0 - gridFract);\n float minDist = min(distToLine.x, distToLine.y);\n float gridFactor = 1.0 - smoothstep(0.0, lineWidth, minDist);\n\n return gridFactor;\n}\n\nvoid main() {\n vec3 baseColor = uColor;\n float baseAlpha = uOpacity;\n\n float distanceFromCenter = length(vWorldPosition - uCenter);\n float normalizedDistance = distanceFromCenter / max(uRadius, 0.001);\n float threshold = uProgress;\n\n if (threshold - normalizedDistance - 0.001 < 0.0) {\n discard;\n }\n\n float distanceFromEdge = threshold - normalizedDistance;\n\n float gridFactor = getGridFactor(vWorldPosition, normalize(vWorldNormal), uGridSize, uGridLineWidth);\n\n vec3 colorGridMixed = mix(baseColor, uGridColor, gridFactor * uShowGrid);\n float alphaGridMixed = max(baseAlpha, gridFactor * uShowGrid);\n\n float glowFactor = clamp(1.0 - clamp(distanceFromEdge / max(uGlowWidth, 0.001), 0.0, 1.0), 0.0, 1.0);\n glowFactor *= glowFactor;\n\n vec3 glowContribution = uGlowColor * glowFactor * uGlowIntensity;\n\n float alphaWithGlow = max(alphaGridMixed, glowFactor);\n alphaWithGlow = max(alphaWithGlow, 0.3);\n\n vec3 N = normalize(vWorldNormal);\n vec3 L = normalize(uLightDirection);\n float ndotl = max(0.3, dot(N, L));\n vec3 ambient = vec3(0.4);\n vec3 lighting = uLightColor * ndotl + ambient;\n\n vec3 litColor = colorGridMixed * lighting;\n vec3 finalColor = litColor + glowContribution * 0.5;\n\n gl_FragColor = vec4(finalColor, alphaWithGlow);\n}\n`;\n\nexport interface IGridMaterialOptions {\n color?: string | THREE.Color;\n opacity?: number;\n\n gridColor?: string | THREE.Color;\n gridScale?: number;\n gridLineWidth?: number;\n showGrid?: number;\n\n /** Center of radial effect (world space; can be updated after creation). */\n center?: THREE.Vector3;\n /** Max radius for radial progress (world units). */\n radius?: number;\n /** Progress 0–1; 1 = fully visible. */\n progress?: number;\n\n glowColor?: string | THREE.Color;\n glowWidth?: number;\n glowIntensity?: number;\n\n lightColor?: string | THREE.Color;\n /** Direction from surface toward light (world space). */\n lightDirection?: THREE.Vector3;\n}\n\n/**\n * Creates a ShaderMaterial with radial progress reveal, grid overlay, edge glow,\n * and simple directional lighting (Unity-style).\n */\nexport function createGridMaterial(\n options: IGridMaterialOptions = {}\n): THREE.ShaderMaterial {\n const color = options.color ?? '#7B2CBF';\n const opacity = options.opacity ?? 0.6;\n\n const gridColor = options.gridColor ?? '#ffeb3b';\n const gridScale = options.gridScale ?? 2.0;\n const gridLineWidth = options.gridLineWidth ?? 0.02;\n const showGrid = options.showGrid ?? 1.0;\n\n const center = options.center ?? new THREE.Vector3(0, 0, 0);\n const radius = options.radius ?? 1.0;\n const progress = options.progress ?? 1.0;\n\n const glowColor = options.glowColor ?? '#00ffff';\n const glowWidth = options.glowWidth ?? 0.05;\n const glowIntensity = options.glowIntensity ?? 2.0;\n\n const lightColor = options.lightColor ?? '#ffffff';\n const lightDirection =\n options.lightDirection ?? new THREE.Vector3(0.3, 1.0, 0.3).normalize();\n\n return new THREE.ShaderMaterial({\n vertexShader: VERTEX,\n fragmentShader: FRAGMENT,\n transparent: true,\n side: THREE.DoubleSide,\n uniforms: {\n uColor: { value: typeof color === 'string' ? new THREE.Color(color) : color },\n uOpacity: { value: opacity },\n\n uGridColor: {\n value: typeof gridColor === 'string' ? new THREE.Color(gridColor) : gridColor,\n },\n uGridSize: { value: gridScale },\n uGridLineWidth: { value: gridLineWidth },\n uShowGrid: { value: showGrid },\n\n uCenter: { value: center.clone() },\n uRadius: { value: radius },\n uProgress: { value: progress },\n\n uGlowColor: {\n value: typeof glowColor === 'string' ? new THREE.Color(glowColor) : glowColor,\n },\n uGlowWidth: { value: glowWidth },\n uGlowIntensity: { value: glowIntensity },\n\n uLightColor: {\n value: typeof lightColor === 'string' ? new THREE.Color(lightColor) : lightColor,\n },\n uLightDirection: { value: lightDirection.clone() },\n },\n });\n}\n","import * as THREE from 'three';\nimport type { MultisetClient, ILocalizeAndMapDetails } from '../core';\nimport type { IGetMapsDetailsResponse } from '../core';\nimport { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { TransformControls } from 'three/examples/jsm/controls/TransformControls.js';\nimport { createGridMaterial } from './materials/gridMaterial';\n\nconst LARGE_MAP_THRESHOLD = 50.0;\n\nexport class MapMeshVisualizer {\n private readonly meshGroup: THREE.Group;\n private readonly gltfLoader: GLTFLoader;\n private readonly dracoLoader: DRACOLoader;\n\n private gizmoControl: TransformControls | null = null;\n private gizmoHelper: THREE.Object3D | null = null;\n private meshMaterial: THREE.ShaderMaterial | null = null;\n private readonly localCenter = new THREE.Vector3();\n private localRadius = 0;\n private readonly radialDuration = 4.0; // seconds for full radial reveal\n private readonly radialRepeatInterval = 20.0; // seconds before replaying the effect\n private idleTimeAfterReveal = 0; // seconds since progress reached 1\n private readonly lastViewerWorldPosition = new THREE.Vector3();\n\n constructor(\n private readonly scene: THREE.Scene,\n private readonly client: MultisetClient,\n private readonly renderer: THREE.WebGLRenderer,\n private readonly camera: THREE.Camera\n ) {\n this.meshGroup = new THREE.Group();\n this.meshGroup.visible = false;\n this.scene.add(this.meshGroup);\n\n this.dracoLoader = new DRACOLoader();\n this.dracoLoader.setDecoderPath('/draco/');\n\n this.gltfLoader = new GLTFLoader();\n this.gltfLoader.setDRACOLoader(this.dracoLoader);\n }\n\n getMeshGroup(): THREE.Group {\n return this.meshGroup;\n }\n\n async ensureGizmoLoaded(): Promise<void> {\n const cfg = this.client.getConfig();\n if (cfg.showGizmo === false) {\n return;\n }\n if (!this.gizmoControl) {\n const gizmo = new TransformControls(this.camera, this.renderer.domElement);\n gizmo.setMode('translate');\n gizmo.setSpace('local');\n gizmo.enabled = false;\n const helper = gizmo.getHelper();\n this.scene.add(helper);\n gizmo.attach(this.meshGroup);\n this.gizmoControl = gizmo;\n this.gizmoHelper = helper;\n }\n this.gizmoHelper!.visible = true;\n }\n\n async ensureMeshLoaded(mapDetails: IGetMapsDetailsResponse): Promise<void> {\n if (this.scene.getObjectByName(mapDetails._id)) {\n return;\n }\n\n const meshKey = mapDetails.mapMesh?.rawMesh?.meshLink;\n if (!meshKey) {\n return;\n }\n\n const url = await this.client.downloadFile(meshKey);\n if (!url) {\n return;\n }\n\n await new Promise<void>((resolve, reject) => {\n this.gltfLoader.load(\n url,\n (gltf) => {\n const box = new THREE.Box3().setFromObject(gltf.scene);\n const sizeVec = box.getSize(new THREE.Vector3());\n let size = sizeVec.length();\n const center = box.getCenter(new THREE.Vector3());\n\n if (size > LARGE_MAP_THRESHOLD) {\n size = LARGE_MAP_THRESHOLD;\n }\n\n this.localCenter.copy(center);\n this.localRadius = Math.max(size / 2, 0.001);\n\n const meshMaterial = createGridMaterial({\n color: '#7B2CBF',\n opacity: 0.4,\n gridColor: '#ffeb3b',\n gridScale: 2.0,\n gridLineWidth: 0.02,\n showGrid: 1.0,\n center: this.localCenter.clone(),\n radius: this.localRadius,\n progress: 0.0,\n glowColor: '#00ffff',\n glowWidth: 0.05,\n glowIntensity: 2.0,\n });\n\n this.meshMaterial = meshMaterial;\n\n gltf.scene.traverse((child) => {\n if ((child as THREE.Mesh).isMesh) {\n (child as THREE.Mesh).material = meshMaterial;\n }\n });\n\n gltf.scene.name = mapDetails._id;\n this.meshGroup.add(gltf.scene);\n resolve();\n },\n undefined,\n (error) => {\n reject(error instanceof Error ? error : new Error(String(error)));\n }\n );\n });\n }\n\n applyMeshTransform(\n best: ILocalizeAndMapDetails,\n trackerSpace: THREE.Matrix4\n ): void {\n const pose = best.localizeData;\n\n const resPosition = new THREE.Vector3(\n pose.position.x,\n pose.position.y,\n pose.position.z\n );\n\n const resRotation = new THREE.Quaternion(\n pose.rotation.x,\n pose.rotation.y,\n pose.rotation.z,\n pose.rotation.w\n );\n\n const responseMatrix = new THREE.Matrix4();\n responseMatrix.compose(resPosition, resRotation, new THREE.Vector3(1, 1, 1));\n\n const inverseResponseMatrix = responseMatrix.clone().invert();\n\n const resultantMatrix = new THREE.Matrix4();\n resultantMatrix.multiplyMatrices(trackerSpace, inverseResponseMatrix);\n\n const position = new THREE.Vector3();\n const rotation = new THREE.Quaternion();\n const scale = new THREE.Vector3();\n resultantMatrix.decompose(position, rotation, scale);\n\n this.meshGroup.position.copy(position);\n this.meshGroup.quaternion.copy(rotation);\n this.meshGroup.scale.set(1, 1, 1);\n this.meshGroup.visible = true;\n this.meshGroup.updateMatrix();\n\n if (this.meshMaterial) {\n this.meshMaterial.uniforms.uCenter.value\n .copy(this.localCenter)\n .applyMatrix4(this.meshGroup.matrixWorld);\n }\n }\n\n update(\n deltaSeconds: number,\n viewerWorldPosition?: THREE.Vector3 | null\n ): void {\n if (!this.meshMaterial) {\n return;\n }\n\n if (viewerWorldPosition) {\n this.lastViewerWorldPosition.copy(viewerWorldPosition);\n }\n\n const uniforms = this.meshMaterial.uniforms as {\n uProgress?: { value: number };\n uCenter?: { value: THREE.Vector3 };\n };\n\n if (!uniforms.uProgress) {\n return;\n }\n\n const current = uniforms.uProgress.value ?? 0;\n\n if (current === 0 && uniforms.uCenter && this.lastViewerWorldPosition.lengthSq() > 0) {\n uniforms.uCenter.value.copy(this.lastViewerWorldPosition);\n }\n\n if (current >= 1) {\n this.idleTimeAfterReveal += deltaSeconds;\n if (this.idleTimeAfterReveal >= this.radialRepeatInterval) {\n uniforms.uProgress.value = 0;\n this.idleTimeAfterReveal = 0;\n }\n return;\n }\n\n this.idleTimeAfterReveal = 0;\n const next = Math.min(\n current + deltaSeconds / this.radialDuration,\n 1\n );\n\n uniforms.uProgress.value = next;\n }\n\n dispose(): void {\n this.meshMaterial = null;\n this.meshGroup.traverse((child) => {\n const mesh = child as THREE.Mesh;\n if (mesh.isMesh) {\n mesh.geometry.dispose();\n if (Array.isArray(mesh.material)) {\n mesh.material.forEach((m) => m.dispose());\n } else {\n (mesh.material as THREE.Material).dispose();\n }\n }\n });\n this.scene.remove(this.meshGroup);\n this.dracoLoader.dispose();\n if (this.gizmoHelper) {\n this.scene.remove(this.gizmoHelper);\n }\n if (this.gizmoControl) {\n this.gizmoControl.dispose();\n }\n }\n}\n\n","import * as THREE from 'three';\nimport type { MultisetClient, ILocalizeAndMapDetails } from '../../core';\nimport type { IGetMapsDetailsResponse } from '../../core';\nimport { MapMeshVisualizer } from '../mapMeshVisualizer';\n\n/**\n * Composes scene content for the AR session (e.g. map mesh).\n * Delegates to MapMeshVisualizer for mesh load and transform.\n */\nexport class World {\n private readonly meshVisualizer: MapMeshVisualizer;\n\n constructor(\n scene: THREE.Scene,\n client: MultisetClient,\n renderer: THREE.WebGLRenderer,\n camera: THREE.Camera\n ) {\n this.meshVisualizer = new MapMeshVisualizer(scene, client, renderer, camera);\n }\n\n async ensureGizmoLoaded(): Promise<void> {\n await this.meshVisualizer.ensureGizmoLoaded();\n }\n\n async ensureMeshLoaded(mapDetails: IGetMapsDetailsResponse): Promise<void> {\n await this.meshVisualizer.ensureMeshLoaded(mapDetails);\n }\n\n applyMeshTransform(\n best: ILocalizeAndMapDetails,\n trackerSpace: THREE.Matrix4\n ): void {\n this.meshVisualizer.applyMeshTransform(best, trackerSpace);\n }\n\n update(\n deltaSeconds: number,\n viewerWorldPosition?: THREE.Vector3 | null\n ): void {\n this.meshVisualizer.update(deltaSeconds, viewerWorldPosition);\n }\n\n dispose(): void {\n this.meshVisualizer.dispose();\n }\n}\n","import * as THREE from 'three';\nimport { ARButton } from 'three/examples/jsm/webxr/ARButton.js';\n\nimport type {\n MultisetClient,\n ILocalizeAndMapDetails,\n} from '../core';\nimport { getCameraIntrinsics } from './internal/cameraIntrinsics';\nimport { getCameraTextureAsImage } from './internal/frameCapture';\nimport { Experience } from './experience/Experience';\nimport { World } from './world/World';\nconst CONFIDENCE_THRESHOLD_MIN = 0.2;\nconst CONFIDENCE_THRESHOLD_MAX = 0.8;\nconst TRACKING_LOSS_FRAME_THRESHOLD = 60;\n/** Default max time (ms) to wait for a valid viewer pose before failing. */\nconst DEFAULT_TRACKING_TIMEOUT_MS = 10_000;\n/** Max XR frames to wait for viewer pose (backup cap; ~10s at 30fps). */\nconst TRACKING_FRAME_CAP = 300;\n/** Max frames with valid pose but no camera image before failing. */\nconst CAMERA_IMAGE_MAX_ATTEMPTS = 10;\n\n/**\n * Options for WebxrController. Property names align with Unity SingleFrameLocalizationManager\n * where applicable (see https://docs.multiset.ai/unity-sdk/api-reference/singleframelocalizationmanager).\n */\nexport interface IWebxrControllerOptions {\n client: MultisetClient;\n canvas?: HTMLCanvasElement;\n overlayRoot?: HTMLElement;\n buttonContainer?: HTMLElement;\n onARButtonCreated?: (button: HTMLButtonElement) => void;\n onSessionStart?: () => void;\n onSessionEnd?: () => void;\n}\n\ntype XRViewWithCamera = XRView & {\n camera?: {\n width: number;\n height: number;\n [key: string]: unknown;\n };\n};\n\ntype XRWebGLBindingLike = {\n getCameraImage: (camera: XRViewWithCamera['camera']) => WebGLTexture | null;\n};\n\nexport class WebxrController {\n private experience: Experience | null = null;\n private world: World | null = null;\n private arButton: HTMLButtonElement | null = null;\n private resizeHandler: (() => void) | null = null;\n private isSessionActive: boolean = false;\n private trackingLossFrames: number = 0;\n private hadTrackingLoss: boolean = false;\n private isLocalizing: boolean = false;\n private trackerSpace: THREE.Matrix4 | null = null;\n\n constructor(private readonly options: IWebxrControllerOptions) { }\n\n async initialize(buttonContainer?: HTMLElement): Promise<HTMLButtonElement> {\n if (this.experience) {\n return this.arButton!;\n }\n\n if (!window.isSecureContext) {\n throw new Error('WebXR requires a secure context (HTTPS).');\n }\n\n const canvas = this.options.canvas ?? document.createElement('canvas');\n\n this.experience = new Experience(canvas);\n const renderer = this.experience.getRenderer();\n const camera = this.experience.getCamera();\n const scene = this.experience.getScene();\n\n this.world = new World(scene, this.options.client, renderer, camera);\n\n renderer.xr.addEventListener('sessionstart', () => {\n this.isSessionActive = true;\n this.options.onSessionStart?.();\n const cfg = this.options.client.getConfig();\n if (cfg.autoLocalize) {\n const session = renderer.xr.getSession();\n if (session) {\n session.requestAnimationFrame(() => {\n void this.localizeFrame();\n });\n } else {\n void this.localizeFrame();\n }\n }\n });\n\n renderer.xr.addEventListener('sessionend', () => {\n this.isSessionActive = false;\n this.options.onSessionEnd?.();\n });\n\n let lastTime = 0;\n\n const animationLoop = (time: number, frame: XRFrame | null) => {\n const deltaSeconds = lastTime === 0 ? 0 : (time - lastTime) / 1000;\n lastTime = time;\n\n let viewerWorldPosition: THREE.Vector3 | null = null;\n if (frame) {\n const refSpace = renderer.xr.getReferenceSpace();\n if (refSpace) {\n const viewerPose = frame.getViewerPose(refSpace);\n if (viewerPose) {\n const p = viewerPose.transform.position;\n viewerWorldPosition = new THREE.Vector3(p.x, p.y, p.z);\n }\n }\n }\n\n if (this.world && deltaSeconds > 0) {\n this.world.update(deltaSeconds, viewerWorldPosition);\n }\n\n renderer.render(scene, camera);\n const cfg = this.options.client.getConfig();\n if (cfg.relocalization && frame && !this.isLocalizing) {\n const refSpace = renderer.xr.getReferenceSpace();\n if (refSpace) {\n const viewerPose = frame.getViewerPose(refSpace);\n if (!viewerPose) {\n this.trackingLossFrames += 1;\n if (this.trackingLossFrames >= TRACKING_LOSS_FRAME_THRESHOLD) {\n this.hadTrackingLoss = true;\n }\n } else {\n if (this.hadTrackingLoss) {\n this.hadTrackingLoss = false;\n this.trackingLossFrames = 0;\n void this.localizeFrame();\n } else {\n this.trackingLossFrames = 0;\n }\n }\n }\n }\n };\n renderer.setAnimationLoop(animationLoop);\n\n const resizeHandler = () => {\n this.experience?.resize();\n };\n window.addEventListener('resize', resizeHandler);\n\n const overlayRoot = this.options.overlayRoot ?? document.body;\n const arButton = ARButton.createButton(renderer, {\n requiredFeatures: ['camera-access', 'dom-overlay'],\n domOverlay: { root: overlayRoot },\n }) as HTMLButtonElement;\n\n const buttonParent =\n buttonContainer && buttonContainer instanceof HTMLElement\n ? buttonContainer\n : this.options.buttonContainer &&\n this.options.buttonContainer instanceof HTMLElement\n ? this.options.buttonContainer\n : overlayRoot;\n\n if (!buttonParent.contains(arButton)) {\n buttonParent.appendChild(arButton);\n }\n\n this.arButton = arButton;\n this.resizeHandler = resizeHandler;\n\n this.options.onARButtonCreated?.(arButton);\n return arButton;\n }\n\n getScene(): THREE.Scene {\n if (!this.experience) {\n throw new Error('Scene: WebXR controller has not been initialized.');\n }\n return this.experience.getScene();\n }\n\n getCamera(): THREE.PerspectiveCamera {\n if (!this.experience) {\n throw new Error('Camera: WebXR controller has not been initialized.');\n }\n return this.experience.getCamera();\n }\n\n getRenderer(): THREE.WebGLRenderer {\n if (!this.experience) {\n throw new Error('Renderer: WebXR controller has not been initialized.');\n }\n return this.experience.getRenderer();\n }\n\n hasActiveSession(): boolean {\n return this.isSessionActive && this.experience?.getRenderer().xr.isPresenting === true;\n }\n\n /**\n * Runs a single-frame localization: captures one frame, evaluates the result\n * against the optional confidenceThreshold, and fires\n * onLocalizationInit / onLocalizationSuccess / onLocalizationFailure.\n * Aligns with Unity SingleFrameLocalizationManager.LocalizeFrame().\n */\n async localizeFrame(): Promise<ILocalizeAndMapDetails | null> {\n if (!this.experience) {\n throw new Error('WebXR: WebXR controller has not been initialized.');\n }\n const renderer = this.experience.getRenderer();\n const session = renderer.xr.getSession?.();\n if (!session) {\n throw new Error(\n 'WebXR Session: No active WebXR session. Start AR before calling localizeFrame().'\n );\n }\n\n const cfg = this.options.client.getConfig();\n const confidenceCheck = cfg.confidenceCheck ?? false;\n const confidenceThreshold = Math.max(\n CONFIDENCE_THRESHOLD_MIN,\n Math.min(cfg.confidenceThreshold ?? 0.5, CONFIDENCE_THRESHOLD_MAX)\n );\n\n cfg.onLocalizationInit?.();\n this.isLocalizing = true;\n\n let best: ILocalizeAndMapDetails | null = null;\n\n let failureReason: string | undefined;\n try {\n const captureResult = await this.captureFrame();\n best = captureResult.result;\n failureReason = captureResult.failureReason;\n } finally {\n this.isLocalizing = false;\n }\n\n const accepted =\n best &&\n (!confidenceCheck ||\n (best.localizeData.confidence ?? 0) >= confidenceThreshold);\n\n if (accepted && best) {\n cfg.onLocalizationSuccess?.(best);\n\n if (this.world && this.trackerSpace) {\n const willShowMesh = cfg.showMesh && !!best.mapDetails;\n const willShowGizmo = cfg.showGizmo !== false;\n if (willShowMesh || willShowGizmo) {\n try {\n await this.world.ensureGizmoLoaded();\n if (willShowMesh) {\n await this.world.ensureMeshLoaded(best.mapDetails!);\n }\n this.world.applyMeshTransform(best, this.trackerSpace);\n } catch {\n // Mesh/gizmo loading failure must not prevent returning the localization result\n }\n }\n }\n return best;\n }\n\n const reason =\n failureReason ??\n (!best\n ? 'All attempts failed to produce a pose.'\n : confidenceCheck\n ? `Best confidence ${best.localizeData.confidence ?? 0} below threshold ${confidenceThreshold}.`\n : undefined);\n cfg.onLocalizationFailure?.(reason);\n return null;\n }\n\n /**\n * Internal: captures one frame and calls the localization API. Waits for a\n * valid viewer pose up to localizationTrackingTimeoutMs (and TRACKING_FRAME_CAP),\n * then tries to get a camera image (up to CAMERA_IMAGE_MAX_ATTEMPTS). Returns\n * result, apiCalled, and an optional failureReason for onLocalizationFailure.\n */\n private async captureFrame(): Promise<{\n result: ILocalizeAndMapDetails | null;\n apiCalled: boolean;\n failureReason?: string;\n }> {\n if (!this.experience) {\n throw new Error('WebXR: WebXR controller has not been initialized.');\n }\n const renderer = this.experience.getRenderer();\n\n const session = renderer.xr.getSession?.();\n if (!session) {\n throw new Error(\n 'WebXR Session: No active WebXR session. Start AR before capturing.'\n );\n }\n\n const referenceSpace = renderer.xr.getReferenceSpace();\n if (!referenceSpace) {\n throw new Error(\n 'WebXR Reference Space: Unable to acquire XR reference space.'\n );\n }\n\n const gl = renderer.getContext();\n const cfg = this.options.client.getConfig();\n const timeoutMs = cfg.localizationTrackingTimeoutMs ?? DEFAULT_TRACKING_TIMEOUT_MS;\n\n return new Promise((resolve, reject) => {\n const startTime = Date.now();\n\n const tryFrame = (attempt: number, cameraAttemptsWithPose: number) => {\n session.requestAnimationFrame(async (_time: number, xrFrame: XRFrame) => {\n try {\n const elapsed = Date.now() - startTime;\n const viewerPose = xrFrame.getViewerPose(referenceSpace);\n if (!viewerPose) {\n if (elapsed >= timeoutMs || attempt + 1 >= TRACKING_FRAME_CAP) {\n const sec = (timeoutMs / 1000).toFixed(1);\n resolve({\n result: null,\n apiCalled: false,\n failureReason: `Tracking unavailable: no viewer pose within ${sec}s. Try moving the device or ensuring good lighting.`,\n });\n } else {\n tryFrame(attempt + 1, cameraAttemptsWithPose);\n }\n return;\n }\n\n const views = viewerPose.views as XRViewWithCamera[];\n for (let i = 0; i < views.length; i += 1) {\n const view = views[i];\n const xrCamera = view.camera;\n if (!xrCamera) continue;\n\n const gl2 = gl as unknown as WebGL2RenderingContext;\n const bindingCtor = XRWebGLBinding as unknown as {\n new(\n session: XRSession,\n context: WebGL2RenderingContext\n ): XRWebGLBindingLike;\n };\n const binding = new bindingCtor(session, gl2);\n const cameraTexture = binding.getCameraImage?.(xrCamera) ?? null;\n if (!cameraTexture) continue;\n\n const width = xrCamera.width;\n const height = xrCamera.height;\n if (!width || !height) continue;\n\n const frameData = await getCameraTextureAsImage(\n renderer,\n cameraTexture,\n width,\n height\n );\n\n const intrinsics = getCameraIntrinsics(view.projectionMatrix, {\n width,\n height,\n x: 0,\n y: 0,\n });\n\n if (frameData && intrinsics) {\n // Capture the camera pose from the current XRFrame's view transform\n // (column-major Float32Array, same convention as THREE.Matrix4.fromArray).\n // Using camera.matrix would give the previous render frame's pose.\n this.trackerSpace = new THREE.Matrix4().fromArray(view.transform.matrix);\n\n const result = await this.options.client.localizeWithFrame(\n frameData,\n intrinsics\n );\n resolve({ result, apiCalled: true });\n return;\n }\n }\n\n if (cameraAttemptsWithPose + 1 >= CAMERA_IMAGE_MAX_ATTEMPTS) {\n resolve({\n result: null,\n apiCalled: false,\n failureReason:\n 'Camera image not available. The device or browser may not support camera access in AR.',\n });\n } else {\n tryFrame(attempt + 1, cameraAttemptsWithPose + 1);\n }\n } catch (error) {\n reject(error);\n } finally {\n gl.bindFramebuffer(\n gl.FRAMEBUFFER,\n session.renderState.baseLayer?.framebuffer ?? null\n );\n }\n });\n };\n tryFrame(0, 0);\n });\n }\n\n dispose(): void {\n if (this.resizeHandler) {\n window.removeEventListener('resize', this.resizeHandler);\n }\n\n this.experience?.getRenderer().setAnimationLoop(null);\n this.experience?.dispose();\n this.experience = null;\n this.world?.dispose();\n this.world = null;\n this.trackingLossFrames = 0;\n this.hadTrackingLoss = false;\n\n if (this.arButton?.parentElement) {\n this.arButton.parentElement.removeChild(this.arButton);\n }\n this.arButton = null;\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/lib/core/config.ts","../src/lib/core/client.ts","../src/lib/webxr/internal/cameraIntrinsics.ts","../src/lib/webxr/internal/frameCapture.ts","../src/lib/webxr/experience/Experience.ts","../src/lib/webxr/materials/gridMaterial.ts","../src/lib/webxr/mapMeshVisualizer.ts","../src/lib/webxr/world/World.ts","../src/lib/webxr/controller.ts"],"names":["THREE","THREE2","THREE4"],"mappings":";;;;;;;;AAiGO,IAAM,iBAAA,GAA2C;AAAA,EACtD,OAAA,EAAS,sCAAA;AAAA,EACT,QAAA,EAAU,+CAAA;AAAA,EACV,aAAA,EAAe,qCAAA;AAAA,EACf,gBAAA,EAAkB,yCAAA;AAAA,EAClB,eAAA,EAAiB;AACnB;ACxFO,IAAM,iBAAN,MAAqB;AAAA,EAO1B,YAAY,KAAA,EAA2B;AAHvC,IAAA,IAAA,CAAQ,WAAA,GAA6B,IAAA;AACrC,IAAA,IAAA,CAAQ,kBAA2D,EAAC;AAGlE,IAAA,MAAM,EAAE,QAAA,EAAU,YAAA,EAAc,GAAG,MAAK,GAAI,KAAA;AAC5C,IAAA,IAAA,CAAK,WAAA,GAAc,EAAE,QAAA,EAAU,YAAA,EAAa;AAC5C,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AACd,IAAA,IAAA,CAAK,SAAA,GAAY;AAAA,MACf,GAAG,iBAAA;AAAA,MACH,GAAG,IAAA,CAAK;AAAA,KACV;AAAA,EACF;AAAA,EAEA,IAAI,KAAA,GAAuB;AACzB,IAAA,OAAO,IAAA,CAAK,WAAA;AAAA,EACd;AAAA,EAEA,SAAA,GAAmC;AACjC,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA,EAEA,MAAM,aAAa,GAAA,EAA8B;AAC/C,IAAA,IAAI,CAAC,IAAA,CAAK,WAAA,IAAe,CAAC,GAAA,EAAK;AAC7B,MAAA,OAAO,EAAA;AAAA,IACT;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA;AAAA,QAC3B,GAAG,IAAA,CAAK,SAAA,CAAU,eAAe,CAAA,KAAA,EAAQ,kBAAA,CAAmB,GAAG,CAAC,CAAA,CAAA;AAAA,QAChE;AAAA,UACE,OAAA,EAAS;AAAA,YACP,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,WAAW,CAAA;AAAA;AAC3C;AACF,OACF;AAEA,MAAA,OAAO,QAAA,CAAS,MAAA,KAAW,GAAA,GAAM,QAAA,CAAS,KAAK,GAAA,GAAM,EAAA;AAAA,IACvD,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,YAAY,KAAK,CAAA;AACtB,MAAA,OAAO,EAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,SAAA,GAA6B;AACjC,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,IAAA;AAAA,QAC3B,KAAK,SAAA,CAAU,OAAA;AAAA,QACf,EAAC;AAAA,QACD;AAAA,UACE,IAAA,EAAM;AAAA,YACJ,QAAA,EAAU,KAAK,WAAA,CAAY,QAAA;AAAA,YAC3B,QAAA,EAAU,KAAK,WAAA,CAAY;AAAA;AAC7B;AACF,OACF;AAEA,MAAA,MAAM,KAAA,GACJ,QAAA,CAAS,IAAA,EAAM,KAAA,IAAS,SAAS,IAAA,EAAM,YAAA;AAEzC,MAAA,IAAI,CAAC,KAAA,EAAO;AACV,QAAA,MAAM,IAAI,MAAM,oDAAoD,CAAA;AAAA,MACtE;AAEA,MAAA,IAAA,CAAK,WAAA,GAAc,KAAA;AACnB,MAAA,IAAA,CAAK,MAAA,CAAO,cAAc,KAAK,CAAA;AAC/B,MAAA,OAAO,KAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,YAAY,KAAK,CAAA;AACtB,MAAA,MAAM,KAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEQ,YAAY,KAAA,EAAsB;AACxC,IAAA,IAAI,KAAA,CAAM,YAAA,CAAa,KAAK,CAAA,EAAG;AAC7B,MAAA,MAAM,UAAA,GAAa,KAAA;AACnB,MAAA,IAAA,CAAK,MAAA,CAAO,UAAU,UAAU,CAAA;AAAA,IAClC,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,MAAA,CAAO,UAAU,KAAK,CAAA;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,MAAM,iBAAA,CACJ,KAAA,EACA,UAAA,EACwC;AACxC,IAAA,IAAI,CAAC,KAAK,WAAA,EAAa;AACrB,MAAA,MAAM,IAAI,MAAM,kDAAkD,CAAA;AAAA,IACpE;AAEA,IAAA,IAAA,CAAK,MAAA,CAAO,kBAAkB,KAAK,CAAA;AACnC,IAAA,IAAA,CAAK,MAAA,CAAO,qBAAqB,UAAU,CAAA;AAE3C,IAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,iBAAA,CAAkB,OAAO,UAAU,CAAA;AAElE,IAAA,IAAI,WAAA,EAAa,cAAc,SAAA,EAAW;AACxC,MAAA,IAAA,CAAK,MAAA,CAAO,YAAA,GAAe,WAAA,CAAY,YAAY,CAAA;AAAA,IACrD;AAEA,IAAA,OAAO,WAAA;AAAA,EACT;AAAA,EAEA,MAAc,oBAAA,GAEZ;AACA,IAAA,IACE,OAAO,cAAc,WAAA,IACrB,EAAE,iBAAiB,SAAA,CAAA,IACnB,CAAC,UAAU,WAAA,EACX;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,WAAW,MAAM,IAAI,OAAA,CAA6B,CAAC,SAAS,MAAA,KAAW;AAC3E,QAAA,SAAA,CAAU,WAAA,CAAY,kBAAA,CAAmB,OAAA,EAAS,MAAA,EAAQ;AAAA,UACxD,kBAAA,EAAoB,IAAA;AAAA,UACpB,OAAA,EAAS,GAAA;AAAA,UACT,UAAA,EAAY;AAAA,SACb,CAAA;AAAA,MACH,CAAC,CAAA;AAED,MAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,QAAA,KAAa,QAAA,CAAS,MAAA;AACnD,MAAA,MAAM,YAAA,GACJ,OAAO,QAAA,KAAa,QAAA,IAAY,CAAC,MAAA,CAAO,KAAA,CAAM,QAAQ,CAAA,GAAI,QAAA,GAAW,CAAA;AAEvE,MAAA,OAAO,EAAE,QAAA,EAAU,SAAA,EAAW,QAAA,EAAU,YAAA,EAAa;AAAA,IACvD,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAc,iBAAA,CACZ,KAAA,EACA,UAAA,EACwC;AACxC,IAAA,MAAM,QAAA,GAAW,IAAI,QAAA,EAAS;AAE9B,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,OAAA,KAAY,KAAA,EAAO;AACjC,MAAA,QAAA,CAAS,MAAA,CAAO,SAAA,EAAW,IAAA,CAAK,MAAA,CAAO,IAAI,CAAA;AAAA,IAC7C,CAAA,MAAO;AACL,MAAA,QAAA,CAAS,MAAA,CAAO,YAAA,EAAc,IAAA,CAAK,MAAA,CAAO,IAAI,CAAA;AAAA,IAChD;AACA,IAAA,QAAA,CAAS,MAAA,CAAO,iBAAiB,MAAM,CAAA;AACvC,IAAA,QAAA,CAAS,MAAA,CAAO,IAAA,EAAM,CAAA,EAAG,UAAA,CAAW,EAAE,CAAA,CAAE,CAAA;AACxC,IAAA,QAAA,CAAS,MAAA,CAAO,IAAA,EAAM,CAAA,EAAG,UAAA,CAAW,EAAE,CAAA,CAAE,CAAA;AACxC,IAAA,QAAA,CAAS,MAAA,CAAO,IAAA,EAAM,CAAA,EAAG,UAAA,CAAW,EAAE,CAAA,CAAE,CAAA;AACxC,IAAA,QAAA,CAAS,MAAA,CAAO,IAAA,EAAM,CAAA,EAAG,UAAA,CAAW,EAAE,CAAA,CAAE,CAAA;AACxC,IAAA,QAAA,CAAS,MAAA,CAAO,OAAA,EAAS,CAAA,EAAG,KAAA,CAAM,KAAK,CAAA,CAAE,CAAA;AACzC,IAAA,QAAA,CAAS,MAAA,CAAO,QAAA,EAAU,CAAA,EAAG,KAAA,CAAM,MAAM,CAAA,CAAE,CAAA;AAC3C,IAAA,QAAA,CAAS,MAAA,CAAO,YAAA,EAAc,KAAA,CAAM,IAAI,CAAA;AACxC,IAAA,IAAI,IAAA,CAAK,OAAO,wBAAA,EAA0B;AACxC,MAAA,QAAA,CAAS,MAAA,CAAO,4BAA4B,MAAM,CAAA;AAAA,IACpD;AACA,IAAA,IAAI,IAAA,CAAK,OAAO,WAAA,EAAa;AAC3B,MAAA,MAAM,UAAA,GAAa,MAAM,IAAA,CAAK,oBAAA,EAAqB;AACnD,MAAA,IAAI,UAAA,EAAY;AACd,QAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,QAAA,EAAS,GAAI,UAAA;AAC1C,QAAA,MAAM,UAAU,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,SAAS,IAAI,QAAQ,CAAA,CAAA;AACpD,QAAA,QAAA,CAAS,MAAA,CAAO,WAAW,OAAO,CAAA;AAAA,MACpC;AAAA,IACF;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,IAAA;AAAA,QAC3B,KAAK,SAAA,CAAU,QAAA;AAAA,QACf,QAAA;AAAA,QACA;AAAA,UACE,OAAA,EAAS;AAAA,YACP,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,WAAW,CAAA;AAAA;AAC3C;AACF,OACF;AAEA,MAAA,MAAM,OAAO,QAAA,CAAS,IAAA;AACtB,MAAA,IAAI,CAAC,KAAK,SAAA,EAAW;AACnB,QAAA,OAAO,IAAA;AAAA,MACT;AAEA,MAAA,MAAM,MAAA,GAAiC;AAAA,QACrC,YAAA,EAAc;AAAA,OAChB;AAEA,MAAA,IACE,IAAA,CAAK,MAAA,CAAO,QAAA,IACZ,IAAA,CAAK,UAAU,MAAA,EACf;AACA,QAAA,MAAM,OAAA,GAAU,IAAA,CAAK,QAAA,CAAS,CAAC,CAAA;AAC/B,QAAA,MAAM,MAAA,GAAS,IAAA,CAAK,eAAA,CAAgB,OAAO,CAAA;AAC3C,QAAA,IAAI,MAAA,EAAQ;AACV,UAAA,MAAA,CAAO,UAAA,GAAa,MAAA;AAAA,QACtB,CAAA,MAAO;AACL,UAAA,MAAM,UAAA,GAAa,MAAM,IAAA,CAAK,eAAA,CAAgB,OAAO,CAAA;AACrD,UAAA,IAAI,UAAA,EAAY;AACd,YAAA,IAAA,CAAK,eAAA,CAAgB,OAAO,CAAA,GAAI,UAAA;AAChC,YAAA,MAAA,CAAO,UAAA,GAAa,UAAA;AAAA,UACtB;AAAA,QACF;AAAA,MACF;AAEA,MAAA,OAAO,MAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,YAAY,KAAK,CAAA;AACtB,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAc,gBAAgB,OAAA,EAA0D;AACtF,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA;AAAA,QAC3B,CAAA,EAAG,IAAA,CAAK,SAAA,CAAU,aAAa,GAAG,OAAO,CAAA,CAAA;AAAA,QACzC;AAAA,UACE,OAAA,EAAS;AAAA,YACP,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,WAAW,CAAA;AAAA;AAC3C;AACF,OACF;AACA,MAAA,OAAO,QAAA,CAAS,IAAA;AAAA,IAClB,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,YAAY,KAAK,CAAA;AACtB,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AACF;;;AC/OO,SAAS,mBAAA,CACd,kBACA,QAAA,EACwB;AACxB,EAAA,MAAM,CAAA,GAAI,gBAAA;AACV,EAAA,MAAM,EAAA,GAAA,CAAO,IAAI,CAAA,CAAE,CAAC,KAAK,QAAA,CAAS,KAAA,GAAS,IAAI,QAAA,CAAS,CAAA;AACxD,EAAA,MAAM,EAAA,GAAA,CAAO,IAAI,CAAA,CAAE,CAAC,KAAK,QAAA,CAAS,MAAA,GAAU,IAAI,QAAA,CAAS,CAAA;AACzD,EAAA,MAAM,EAAA,GAAM,QAAA,CAAS,KAAA,GAAQ,CAAA,GAAK,EAAE,CAAC,CAAA;AACrC,EAAA,MAAM,EAAA,GAAM,QAAA,CAAS,MAAA,GAAS,CAAA,GAAK,EAAE,CAAC,CAAA;AAEtC,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,EAAA;AAAA,IACJ,EAAA,EAAI,EAAA;AAAA,IACJ,EAAA,EAAI,EAAA;AAAA,IACJ,EAAA,EAAI,EAAA;AAAA,IACJ,OAAO,QAAA,CAAS,KAAA;AAAA,IAChB,QAAQ,QAAA,CAAS;AAAA,GACnB;AACF;;;ACjBA,eAAsB,cAAA,CACpB,MAAA,EACA,KAAA,EACA,MAAA,EACA,UAAU,GAAA,EACK;AACf,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC9C,EAAA,MAAA,CAAO,KAAA,GAAQ,KAAA;AACf,EAAA,MAAA,CAAO,MAAA,GAAS,MAAA;AAChB,EAAA,MAAM,GAAA,GAAM,MAAA,CAAO,UAAA,CAAW,IAAI,CAAA;AAClC,EAAA,IAAI,CAAC,GAAA,EAAK,OAAO,IAAI,IAAA,EAAK;AAE1B,EAAA,MAAM,SAAA,GAAY,IAAI,SAAA,CAAU,IAAI,kBAAkB,MAAM,CAAA,EAAG,OAAO,MAAM,CAAA;AAC5E,EAAA,GAAA,CAAI,YAAA,CAAa,SAAA,EAAW,CAAA,EAAG,CAAC,CAAA;AAEhC,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC9B,IAAA,MAAA,CAAO,MAAA,CAAO,CAAC,IAAA,KAAS,OAAA,CAAQ,IAAA,IAAQ,IAAI,IAAA,EAAM,CAAA,EAAG,YAAA,EAAc,OAAO,CAAA;AAAA,EAC5E,CAAC,CAAA;AACH;AAEA,eAAsB,uBAAA,CACpB,QAAA,EACA,YAAA,EACA,KAAA,EACA,MAAA,EACoC;AACpC,EAAA,MAAM,EAAA,GAAK,SAAS,UAAA,EAAW;AAC/B,EAAA,IAAI,CAAC,IAAI,OAAO,IAAA;AAEhB,EAAA,MAAM,WAAA,GAAc,GAAG,iBAAA,EAAkB;AACzC,EAAA,IAAI,CAAC,aAAa,OAAO,IAAA;AAEzB,EAAA,IAAI,WAAA;AACJ,EAAA,IAAI;AACF,IAAA,EAAA,CAAG,eAAA,CAAgB,EAAA,CAAG,WAAA,EAAa,WAAW,CAAA;AAC9C,IAAA,EAAA,CAAG,oBAAA;AAAA,MACD,EAAA,CAAG,WAAA;AAAA,MACH,EAAA,CAAG,iBAAA;AAAA,MACH,EAAA,CAAG,UAAA;AAAA,MACH,YAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,WAAA,GAAc,IAAI,UAAA,CAAW,KAAA,GAAQ,MAAA,GAAS,CAAC,CAAA;AAC/C,IAAA,EAAA,CAAG,UAAA,CAAW,GAAG,CAAA,EAAG,KAAA,EAAO,QAAQ,EAAA,CAAG,IAAA,EAAM,EAAA,CAAG,aAAA,EAAe,WAAW,CAAA;AAAA,EAC3E,CAAA,SAAE;AACA,IAAA,EAAA,CAAG,eAAA,CAAgB,EAAA,CAAG,WAAA,EAAa,IAAI,CAAA;AACvC,IAAA,EAAA,CAAG,kBAAkB,WAAW,CAAA;AAAA,EAClC;AAEA,EAAA,MAAM,WAAA,GAAc,IAAI,iBAAA,CAAkB,WAAA,CAAY,MAAM,CAAA;AAC5D,EAAA,KAAA,IAAS,GAAA,GAAM,CAAA,EAAG,GAAA,GAAM,MAAA,EAAQ,OAAO,CAAA,EAAG;AACxC,IAAA,MAAM,WAAA,GAAc,MAAM,KAAA,GAAQ,CAAA;AAClC,IAAA,MAAM,SAAA,GAAA,CAAa,MAAA,GAAS,GAAA,GAAM,CAAA,IAAK,KAAA,GAAQ,CAAA;AAC/C,IAAA,WAAA,CAAY,GAAA;AAAA,MACV,WAAA,CAAY,QAAA,CAAS,WAAA,EAAa,WAAA,GAAc,QAAQ,CAAC,CAAA;AAAA,MACzD;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,OAAO,MAAM,cAAA,CAAe,YAAY,MAAA,EAAQ,KAAA,EAAO,QAAQ,GAAG,CAAA;AAExE,EAAA,IAAI,CAAC,KAAK,IAAA,EAAM;AACd,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,KAAA;AAAA,IACA;AAAA,GACF;AACF;ACpEO,IAAM,aAAN,MAAiB;AAAA,EAKtB,YAAY,MAAA,EAA2B;AACrC,IAAA,IAAA,CAAK,QAAA,GAAW,IAAUA,MAAA,CAAA,aAAA,CAAc;AAAA,MACtC,MAAA;AAAA,MACA,SAAA,EAAW,IAAA;AAAA,MACX,KAAA,EAAO;AAAA,KACR,CAAA;AACD,IAAA,IAAA,CAAK,QAAA,CAAS,OAAA,CAAQ,MAAA,CAAO,UAAA,EAAY,OAAO,WAAW,CAAA;AAC3D,IAAA,IAAA,CAAK,QAAA,CAAS,aAAA,CAAc,MAAA,CAAO,gBAAgB,CAAA;AACnD,IAAA,IAAA,CAAK,QAAA,CAAS,GAAG,OAAA,GAAU,IAAA;AAE3B,IAAA,IAAA,CAAK,SAAS,IAAUA,MAAA,CAAA,iBAAA;AAAA,MACtB,EAAA;AAAA,MACA,MAAA,CAAO,aAAa,MAAA,CAAO,WAAA;AAAA,MAC3B,GAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAUA,MAAA,CAAA,KAAA,EAAM;AAC7B,IAAA,IAAA,CAAK,WAAA,EAAY;AAAA,EACnB;AAAA,EAEQ,WAAA,GAAoB;AAC1B,IAAA,MAAM,KAAA,GAAQ,IAAUA,MAAA,CAAA,eAAA,CAAgB,QAAA,EAAU,UAAU,CAAC,CAAA;AAC7D,IAAA,KAAA,CAAM,QAAA,CAAS,GAAA,CAAI,GAAA,EAAK,CAAA,EAAG,IAAI,CAAA;AAC/B,IAAA,IAAA,CAAK,KAAA,CAAM,IAAI,KAAK,CAAA;AAEpB,IAAA,MAAM,OAAA,GAAU,IAAUA,MAAA,CAAA,gBAAA,CAAiB,SAAS,CAAA;AACpD,IAAA,OAAA,CAAQ,QAAA,CAAS,GAAA,CAAI,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAC5B,IAAA,IAAA,CAAK,KAAA,CAAM,IAAI,OAAO,CAAA;AAAA,EACxB;AAAA,EAEA,QAAA,GAAwB;AACtB,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AAAA,EAEA,SAAA,GAAqC;AACnC,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA,EAEA,WAAA,GAAmC;AACjC,IAAA,OAAO,IAAA,CAAK,QAAA;AAAA,EACd;AAAA,EAEA,MAAA,GAAe;AACb,IAAA,IAAA,CAAK,MAAA,CAAO,MAAA,GAAS,MAAA,CAAO,UAAA,GAAa,MAAA,CAAO,WAAA;AAChD,IAAA,IAAA,CAAK,OAAO,sBAAA,EAAuB;AACnC,IAAA,IAAA,CAAK,QAAA,CAAS,OAAA,CAAQ,MAAA,CAAO,UAAA,EAAY,OAAO,WAAW,CAAA;AAAA,EAC7D;AAAA,EAEA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,SAAS,OAAA,EAAQ;AACtB,IAAC,KAAkD,KAAA,GAAQ,IAAA;AAC3D,IAAC,KAA+D,MAAA,GAAS,IAAA;AACzE,IAAC,KAA6D,QAAA,GAAW,IAAA;AAAA,EAC3E;AACF,CAAA;AChEA,IAAM,MAAA,GAAS;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA,CAAA;AAaf,IAAM,QAAA,GAAW;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA,CAAA;AAgHV,SAAS,kBAAA,CACd,OAAA,GAAgC,EAAC,EACX;AACtB,EAAA,MAAM,KAAA,GAAQ,QAAQ,KAAA,IAAS,SAAA;AAC/B,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,OAAA,IAAY,GAAA,GAAM,GAAA;AAE1C,EAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,IAAa,SAAA;AACvC,EAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,IAAa,CAAA;AACvC,EAAA,MAAM,aAAA,GAAgB,QAAQ,aAAA,IAAiB,IAAA;AAC/C,EAAA,MAAM,QAAA,GAAW,QAAQ,QAAA,IAAY,CAAA;AAErC,EAAA,MAAM,SAAS,OAAA,CAAQ,MAAA,IAAU,IAAUC,MAAA,CAAA,OAAA,CAAQ,CAAA,EAAG,GAAG,CAAC,CAAA;AAC1D,EAAA,MAAM,MAAA,GAAS,QAAQ,MAAA,IAAU,CAAA;AACjC,EAAA,MAAM,QAAA,GAAW,QAAQ,QAAA,IAAY,CAAA;AAErC,EAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,IAAa,SAAA;AACvC,EAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,IAAa,IAAA;AACvC,EAAA,MAAM,aAAA,GAAgB,QAAQ,aAAA,IAAiB,CAAA;AAE/C,EAAA,MAAM,UAAA,GAAa,QAAQ,UAAA,IAAc,SAAA;AACzC,EAAA,MAAM,cAAA,GACJ,QAAQ,cAAA,IAAkB,IAAUA,eAAQ,GAAA,EAAK,CAAA,EAAK,GAAG,CAAA,CAAE,SAAA,EAAU;AAEvE,EAAA,OAAO,IAAUA,MAAA,CAAA,cAAA,CAAe;AAAA,IAC9B,YAAA,EAAc,MAAA;AAAA,IACd,cAAA,EAAgB,QAAA;AAAA,IAChB,WAAA,EAAa,IAAA;AAAA,IACb,IAAA,EAAYA,MAAA,CAAA,UAAA;AAAA,IACZ,QAAA,EAAU;AAAA,MACR,MAAA,EAAQ,EAAE,KAAA,EAAO,OAAO,KAAA,KAAU,WAAW,IAAUA,MAAA,CAAA,KAAA,CAAM,KAAK,CAAA,GAAI,KAAA,EAAM;AAAA,MAC5E,QAAA,EAAU,EAAE,KAAA,EAAO,OAAA,EAAQ;AAAA,MAE3B,UAAA,EAAY;AAAA,QACV,OAAO,OAAO,SAAA,KAAc,WAAW,IAAUA,MAAA,CAAA,KAAA,CAAM,SAAS,CAAA,GAAI;AAAA,OACtE;AAAA,MACA,SAAA,EAAW,EAAE,KAAA,EAAO,SAAA,EAAU;AAAA,MAC9B,cAAA,EAAgB,EAAE,KAAA,EAAO,aAAA,EAAc;AAAA,MACvC,SAAA,EAAW,EAAE,KAAA,EAAO,QAAA,EAAS;AAAA,MAE7B,OAAA,EAAS,EAAE,KAAA,EAAO,MAAA,CAAO,OAAM,EAAE;AAAA,MACjC,OAAA,EAAS,EAAE,KAAA,EAAO,MAAA,EAAO;AAAA,MACzB,SAAA,EAAW,EAAE,KAAA,EAAO,QAAA,EAAS;AAAA,MAE7B,UAAA,EAAY;AAAA,QACV,OAAO,OAAO,SAAA,KAAc,WAAW,IAAUA,MAAA,CAAA,KAAA,CAAM,SAAS,CAAA,GAAI;AAAA,OACtE;AAAA,MACA,UAAA,EAAY,EAAE,KAAA,EAAO,SAAA,EAAU;AAAA,MAC/B,cAAA,EAAgB,EAAE,KAAA,EAAO,aAAA,EAAc;AAAA,MAEvC,WAAA,EAAa;AAAA,QACX,OAAO,OAAO,UAAA,KAAe,WAAW,IAAUA,MAAA,CAAA,KAAA,CAAM,UAAU,CAAA,GAAI;AAAA,OACxE;AAAA,MACA,eAAA,EAAiB,EAAE,KAAA,EAAO,cAAA,CAAe,OAAM;AAAE;AACnD,GACD,CAAA;AACH;;;AC9KA,IAAM,mBAAA,GAAsB,EAAA;AAErB,IAAM,oBAAN,MAAwB;AAAA,EAe7B,WAAA,CACmB,KAAA,EACA,MAAA,EACA,QAAA,EACA,MAAA,EACjB;AAJiB,IAAA,IAAA,CAAA,KAAA,GAAA,KAAA;AACA,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACA,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AACA,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAdnB,IAAA,IAAA,CAAQ,YAAA,GAAyC,IAAA;AACjD,IAAA,IAAA,CAAQ,WAAA,GAAqC,IAAA;AAC7C,IAAA,IAAA,CAAQ,YAAA,GAA4C,IAAA;AACpD,IAAA,IAAA,CAAiB,WAAA,GAAc,IAAU,MAAA,CAAA,OAAA,EAAQ;AACjD,IAAA,IAAA,CAAQ,WAAA,GAAc,CAAA;AACtB,IAAA,IAAA,CAAiB,cAAA,GAAiB,CAAA;AAClC;AAAA,IAAA,IAAA,CAAiB,oBAAA,GAAuB,EAAA;AACxC;AAAA,IAAA,IAAA,CAAQ,mBAAA,GAAsB,CAAA;AAC9B;AAAA,IAAA,IAAA,CAAiB,uBAAA,GAA0B,IAAU,MAAA,CAAA,OAAA,EAAQ;AAQ3D,IAAA,IAAA,CAAK,SAAA,GAAY,IAAU,MAAA,CAAA,KAAA,EAAM;AACjC,IAAA,IAAA,CAAK,UAAU,OAAA,GAAU,KAAA;AACzB,IAAA,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,IAAA,CAAK,SAAS,CAAA;AAE7B,IAAA,IAAA,CAAK,WAAA,GAAc,IAAI,WAAA,EAAY;AACnC,IAAA,IAAA,CAAK,WAAA,CAAY,eAAe,SAAS,CAAA;AAEzC,IAAA,IAAA,CAAK,UAAA,GAAa,IAAI,UAAA,EAAW;AACjC,IAAA,IAAA,CAAK,UAAA,CAAW,cAAA,CAAe,IAAA,CAAK,WAAW,CAAA;AAAA,EACjD;AAAA,EAEA,YAAA,GAA4B;AAC1B,IAAA,OAAO,IAAA,CAAK,SAAA;AAAA,EACd;AAAA,EAEA,MAAM,iBAAA,GAAmC;AACvC,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,MAAA,CAAO,SAAA,EAAU;AAClC,IAAA,IAAI,GAAA,CAAI,cAAc,KAAA,EAAO;AAC3B,MAAA;AAAA,IACF;AACA,IAAA,IAAI,CAAC,KAAK,YAAA,EAAc;AACtB,MAAA,MAAM,QAAQ,IAAI,iBAAA,CAAkB,KAAK,MAAA,EAAQ,IAAA,CAAK,SAAS,UAAU,CAAA;AACzE,MAAA,KAAA,CAAM,QAAQ,WAAW,CAAA;AACzB,MAAA,KAAA,CAAM,SAAS,OAAO,CAAA;AACtB,MAAA,KAAA,CAAM,OAAA,GAAU,KAAA;AAChB,MAAA,MAAM,MAAA,GAAS,MAAM,SAAA,EAAU;AAC/B,MAAA,IAAA,CAAK,KAAA,CAAM,IAAI,MAAM,CAAA;AACrB,MAAA,KAAA,CAAM,MAAA,CAAO,KAAK,SAAS,CAAA;AAC3B,MAAA,IAAA,CAAK,YAAA,GAAe,KAAA;AACpB,MAAA,IAAA,CAAK,WAAA,GAAc,MAAA;AAAA,IACrB;AACA,IAAA,IAAA,CAAK,YAAa,OAAA,GAAU,IAAA;AAAA,EAC9B;AAAA,EAEA,MAAM,iBAAiB,UAAA,EAAoD;AACzE,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,eAAA,CAAgB,UAAA,CAAW,GAAG,CAAA,EAAG;AAC9C,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,OAAA,GAAU,UAAA,CAAW,OAAA,EAAS,OAAA,EAAS,QAAA;AAC7C,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,MAAA,CAAO,aAAa,OAAO,CAAA;AAClD,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,IAAI,OAAA,CAAc,CAAC,OAAA,EAAS,MAAA,KAAW;AAC3C,MAAA,IAAA,CAAK,UAAA,CAAW,IAAA;AAAA,QACd,GAAA;AAAA,QACA,CAAC,IAAA,KAAS;AACR,UAAA,MAAM,MAAM,IAAU,MAAA,CAAA,IAAA,EAAK,CAAE,aAAA,CAAc,KAAK,KAAK,CAAA;AACrD,UAAA,MAAM,OAAA,GAAU,GAAA,CAAI,OAAA,CAAQ,IAAU,gBAAS,CAAA;AAC/C,UAAA,IAAI,IAAA,GAAO,QAAQ,MAAA,EAAO;AAC1B,UAAA,MAAM,MAAA,GAAS,GAAA,CAAI,SAAA,CAAU,IAAU,gBAAS,CAAA;AAEhD,UAAA,IAAI,OAAO,mBAAA,EAAqB;AAC9B,YAAA,IAAA,GAAO,mBAAA;AAAA,UACT;AAEA,UAAA,IAAA,CAAK,WAAA,CAAY,KAAK,MAAM,CAAA;AAC5B,UAAA,IAAA,CAAK,WAAA,GAAc,IAAA,CAAK,GAAA,CAAI,IAAA,GAAO,GAAG,IAAK,CAAA;AAE3C,UAAA,MAAM,eAAe,kBAAA,CAAmB;AAAA,YACtC,KAAA,EAAO,SAAA;AAAA,YACP,OAAA,EAAS,IAAA;AAAA,YACT,SAAA,EAAW,SAAA;AAAA,YACX,SAAA,EAAW,CAAA;AAAA,YACX,aAAA,EAAe,IAAA;AAAA,YACf,QAAA,EAAU,CAAA;AAAA,YACV,MAAA,EAAQ,IAAA,CAAK,WAAA,CAAY,KAAA,EAAM;AAAA,YAC/B,QAAQ,IAAA,CAAK,WAAA;AAAA,YACb,QAAA,EAAU,CAAA;AAAA,YACV,SAAA,EAAW,SAAA;AAAA,YACX,SAAA,EAAW,IAAA;AAAA,YACX,aAAA,EAAe;AAAA,WAChB,CAAA;AAED,UAAA,IAAA,CAAK,YAAA,GAAe,YAAA;AAEpB,UAAA,IAAA,CAAK,KAAA,CAAM,QAAA,CAAS,CAAC,KAAA,KAAU;AAC7B,YAAA,IAAK,MAAqB,MAAA,EAAQ;AAChC,cAAC,MAAqB,QAAA,GAAW,YAAA;AAAA,YACnC;AAAA,UACF,CAAC,CAAA;AAED,UAAA,IAAA,CAAK,KAAA,CAAM,OAAO,UAAA,CAAW,GAAA;AAC7B,UAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,IAAA,CAAK,KAAK,CAAA;AAC7B,UAAA,OAAA,EAAQ;AAAA,QACV,CAAA;AAAA,QACA,MAAA;AAAA,QACA,CAAC,KAAA,KAAU;AACT,UAAA,MAAA,CAAO,KAAA,YAAiB,QAAQ,KAAA,GAAQ,IAAI,MAAM,MAAA,CAAO,KAAK,CAAC,CAAC,CAAA;AAAA,QAClE;AAAA,OACF;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,kBAAA,CACE,MACA,YAAA,EACM;AACN,IAAA,MAAM,OAAO,IAAA,CAAK,YAAA;AAElB,IAAA,MAAM,cAAc,IAAU,MAAA,CAAA,OAAA;AAAA,MAC5B,KAAK,QAAA,CAAS,CAAA;AAAA,MACd,KAAK,QAAA,CAAS,CAAA;AAAA,MACd,KAAK,QAAA,CAAS;AAAA,KAChB;AAEA,IAAA,MAAM,cAAc,IAAU,MAAA,CAAA,UAAA;AAAA,MAC5B,KAAK,QAAA,CAAS,CAAA;AAAA,MACd,KAAK,QAAA,CAAS,CAAA;AAAA,MACd,KAAK,QAAA,CAAS,CAAA;AAAA,MACd,KAAK,QAAA,CAAS;AAAA,KAChB;AAEA,IAAA,MAAM,cAAA,GAAiB,IAAU,MAAA,CAAA,OAAA,EAAQ;AACzC,IAAA,cAAA,CAAe,OAAA,CAAQ,aAAa,WAAA,EAAa,IAAU,eAAQ,CAAA,EAAG,CAAA,EAAG,CAAC,CAAC,CAAA;AAE3E,IAAA,MAAM,qBAAA,GAAwB,cAAA,CAAe,KAAA,EAAM,CAAE,MAAA,EAAO;AAE5D,IAAA,MAAM,eAAA,GAAkB,IAAU,MAAA,CAAA,OAAA,EAAQ;AAC1C,IAAA,eAAA,CAAgB,gBAAA,CAAiB,cAAc,qBAAqB,CAAA;AAEpE,IAAA,MAAM,QAAA,GAAW,IAAU,MAAA,CAAA,OAAA,EAAQ;AACnC,IAAA,MAAM,QAAA,GAAW,IAAU,MAAA,CAAA,UAAA,EAAW;AACtC,IAAA,MAAM,KAAA,GAAQ,IAAU,MAAA,CAAA,OAAA,EAAQ;AAChC,IAAA,eAAA,CAAgB,SAAA,CAAU,QAAA,EAAU,QAAA,EAAU,KAAK,CAAA;AAEnD,IAAA,IAAA,CAAK,SAAA,CAAU,QAAA,CAAS,IAAA,CAAK,QAAQ,CAAA;AACrC,IAAA,IAAA,CAAK,SAAA,CAAU,UAAA,CAAW,IAAA,CAAK,QAAQ,CAAA;AACvC,IAAA,IAAA,CAAK,SAAA,CAAU,KAAA,CAAM,GAAA,CAAI,CAAA,EAAG,GAAG,CAAC,CAAA;AAChC,IAAA,IAAA,CAAK,UAAU,OAAA,GAAU,IAAA;AACzB,IAAA,IAAA,CAAK,UAAU,YAAA,EAAa;AAE5B,IAAA,IAAI,KAAK,YAAA,EAAc;AACrB,MAAA,IAAA,CAAK,YAAA,CAAa,QAAA,CAAS,OAAA,CAAQ,KAAA,CAChC,IAAA,CAAK,IAAA,CAAK,WAAW,CAAA,CACrB,YAAA,CAAa,IAAA,CAAK,SAAA,CAAU,WAAW,CAAA;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,MAAA,CACE,cACA,mBAAA,EACM;AACN,IAAA,IAAI,CAAC,KAAK,YAAA,EAAc;AACtB,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,mBAAA,EAAqB;AACvB,MAAA,IAAA,CAAK,uBAAA,CAAwB,KAAK,mBAAmB,CAAA;AAAA,IACvD;AAEA,IAAA,MAAM,QAAA,GAAW,KAAK,YAAA,CAAa,QAAA;AAKnC,IAAA,IAAI,CAAC,SAAS,SAAA,EAAW;AACvB,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,OAAA,GAAU,QAAA,CAAS,SAAA,CAAU,KAAA,IAAS,CAAA;AAE5C,IAAA,IAAI,OAAA,KAAY,KAAK,QAAA,CAAS,OAAA,IAAW,KAAK,uBAAA,CAAwB,QAAA,KAAa,CAAA,EAAG;AACpF,MAAA,QAAA,CAAS,OAAA,CAAQ,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,uBAAuB,CAAA;AAAA,IAC1D;AAEA,IAAA,IAAI,WAAW,CAAA,EAAG;AAChB,MAAA,IAAA,CAAK,mBAAA,IAAuB,YAAA;AAC5B,MAAA,IAAI,IAAA,CAAK,mBAAA,IAAuB,IAAA,CAAK,oBAAA,EAAsB;AACzD,QAAA,QAAA,CAAS,UAAU,KAAA,GAAQ,CAAA;AAC3B,QAAA,IAAA,CAAK,mBAAA,GAAsB,CAAA;AAAA,MAC7B;AACA,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,mBAAA,GAAsB,CAAA;AAC3B,IAAA,MAAM,OAAO,IAAA,CAAK,GAAA;AAAA,MAChB,OAAA,GAAU,eAAe,IAAA,CAAK,cAAA;AAAA,MAC9B;AAAA,KACF;AAEA,IAAA,QAAA,CAAS,UAAU,KAAA,GAAQ,IAAA;AAAA,EAC7B;AAAA,EAEA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,YAAA,GAAe,IAAA;AACpB,IAAA,IAAA,CAAK,SAAA,CAAU,QAAA,CAAS,CAAC,KAAA,KAAU;AACjC,MAAA,MAAM,IAAA,GAAO,KAAA;AACb,MAAA,IAAI,KAAK,MAAA,EAAQ;AACf,QAAA,IAAA,CAAK,SAAS,OAAA,EAAQ;AACtB,QAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,QAAQ,CAAA,EAAG;AAChC,UAAA,IAAA,CAAK,SAAS,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,CAAA;AAAA,QAC1C,CAAA,MAAO;AACL,UAAC,IAAA,CAAK,SAA4B,OAAA,EAAQ;AAAA,QAC5C;AAAA,MACF;AAAA,IACF,CAAC,CAAA;AACD,IAAA,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA;AAChC,IAAA,IAAA,CAAK,YAAY,OAAA,EAAQ;AACzB,IAAA,IAAI,KAAK,WAAA,EAAa;AACpB,MAAA,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,IAAA,CAAK,WAAW,CAAA;AAAA,IACpC;AACA,IAAA,IAAI,KAAK,YAAA,EAAc;AACrB,MAAA,IAAA,CAAK,aAAa,OAAA,EAAQ;AAAA,IAC5B;AAAA,EACF;AACF,CAAA;;;AC1OO,IAAM,QAAN,MAAY;AAAA,EAGjB,WAAA,CACE,KAAA,EACA,MAAA,EACA,QAAA,EACA,MAAA,EACA;AACA,IAAA,IAAA,CAAK,iBAAiB,IAAI,iBAAA,CAAkB,KAAA,EAAO,MAAA,EAAQ,UAAU,MAAM,CAAA;AAAA,EAC7E;AAAA,EAEA,MAAM,iBAAA,GAAmC;AACvC,IAAA,MAAM,IAAA,CAAK,eAAe,iBAAA,EAAkB;AAAA,EAC9C;AAAA,EAEA,MAAM,iBAAiB,UAAA,EAAoD;AACzE,IAAA,MAAM,IAAA,CAAK,cAAA,CAAe,gBAAA,CAAiB,UAAU,CAAA;AAAA,EACvD;AAAA,EAEA,kBAAA,CACE,MACA,YAAA,EACM;AACN,IAAA,IAAA,CAAK,cAAA,CAAe,kBAAA,CAAmB,IAAA,EAAM,YAAY,CAAA;AAAA,EAC3D;AAAA,EAEA,MAAA,CACE,cACA,mBAAA,EACM;AACN,IAAA,IAAA,CAAK,cAAA,CAAe,MAAA,CAAO,YAAA,EAAc,mBAAmB,CAAA;AAAA,EAC9D;AAAA,EAEA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,eAAe,OAAA,EAAQ;AAAA,EAC9B;AACF,CAAA;;;ACnCA,IAAM,wBAAA,GAA2B,GAAA;AACjC,IAAM,wBAAA,GAA2B,GAAA;AACjC,IAAM,6BAAA,GAAgC,EAAA;AAEtC,IAAM,2BAAA,GAA8B,GAAA;AAEpC,IAAM,kBAAA,GAAqB,GAAA;AAE3B,IAAM,yBAAA,GAA4B,EAAA;AA4B3B,IAAM,kBAAN,MAAsB;AAAA,EAW3B,YAA6B,OAAA,EAAkC;AAAlC,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAV7B,IAAA,IAAA,CAAQ,UAAA,GAAgC,IAAA;AACxC,IAAA,IAAA,CAAQ,KAAA,GAAsB,IAAA;AAC9B,IAAA,IAAA,CAAQ,QAAA,GAAqC,IAAA;AAC7C,IAAA,IAAA,CAAQ,aAAA,GAAqC,IAAA;AAC7C,IAAA,IAAA,CAAQ,eAAA,GAA2B,KAAA;AACnC,IAAA,IAAA,CAAQ,kBAAA,GAA6B,CAAA;AACrC,IAAA,IAAA,CAAQ,eAAA,GAA2B,KAAA;AACnC,IAAA,IAAA,CAAQ,YAAA,GAAwB,KAAA;AAChC,IAAA,IAAA,CAAQ,YAAA,GAAqC,IAAA;AAAA,EAEoB;AAAA,EAEjE,MAAM,WAAW,eAAA,EAA2D;AAC1E,IAAA,IAAI,KAAK,UAAA,EAAY;AACnB,MAAA,OAAO,IAAA,CAAK,QAAA;AAAA,IACd;AAEA,IAAA,IAAI,CAAC,OAAO,eAAA,EAAiB;AAC3B,MAAA,MAAM,IAAI,MAAM,0CAA0C,CAAA;AAAA,IAC5D;AAEA,IAAA,MAAM,SAAS,IAAA,CAAK,OAAA,CAAQ,MAAA,IAAU,QAAA,CAAS,cAAc,QAAQ,CAAA;AAErE,IAAA,IAAA,CAAK,UAAA,GAAa,IAAI,UAAA,CAAW,MAAM,CAAA;AACvC,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,UAAA,CAAW,WAAA,EAAY;AAC7C,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,UAAA,CAAW,SAAA,EAAU;AACzC,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,UAAA,CAAW,QAAA,EAAS;AAEvC,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAI,KAAA,CAAM,KAAA,EAAO,KAAK,OAAA,CAAQ,MAAA,EAAQ,UAAU,MAAM,CAAA;AAEnE,IAAA,QAAA,CAAS,EAAA,CAAG,gBAAA,CAAiB,cAAA,EAAgB,MAAM;AACjD,MAAA,IAAA,CAAK,eAAA,GAAkB,IAAA;AACvB,MAAA,IAAA,CAAK,QAAQ,cAAA,IAAiB;AAC9B,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,SAAA,EAAU;AAC1C,MAAA,IAAI,IAAI,YAAA,EAAc;AACpB,QAAA,MAAM,OAAA,GAAU,QAAA,CAAS,EAAA,CAAG,UAAA,EAAW;AACvC,QAAA,IAAI,OAAA,EAAS;AACX,UAAA,OAAA,CAAQ,sBAAsB,MAAM;AAClC,YAAA,KAAK,KAAK,aAAA,EAAc;AAAA,UAC1B,CAAC,CAAA;AAAA,QACH,CAAA,MAAO;AACL,UAAA,KAAK,KAAK,aAAA,EAAc;AAAA,QAC1B;AAAA,MACF;AAAA,IACF,CAAC,CAAA;AAED,IAAA,QAAA,CAAS,EAAA,CAAG,gBAAA,CAAiB,YAAA,EAAc,MAAM;AAC/C,MAAA,IAAA,CAAK,eAAA,GAAkB,KAAA;AACvB,MAAA,IAAA,CAAK,QAAQ,YAAA,IAAe;AAAA,IAC9B,CAAC,CAAA;AAED,IAAA,IAAI,QAAA,GAAW,CAAA;AAEf,IAAA,MAAM,aAAA,GAAgB,CAAC,IAAA,EAAc,KAAA,KAA0B;AAC7D,MAAA,MAAM,YAAA,GAAe,QAAA,KAAa,CAAA,GAAI,CAAA,GAAA,CAAK,OAAO,QAAA,IAAY,GAAA;AAC9D,MAAA,QAAA,GAAW,IAAA;AAEX,MAAA,IAAI,mBAAA,GAA4C,IAAA;AAChD,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,MAAM,QAAA,GAAW,QAAA,CAAS,EAAA,CAAG,iBAAA,EAAkB;AAC/C,QAAA,IAAI,QAAA,EAAU;AACZ,UAAA,MAAM,UAAA,GAAa,KAAA,CAAM,aAAA,CAAc,QAAQ,CAAA;AAC/C,UAAA,IAAI,UAAA,EAAY;AACd,YAAA,MAAM,CAAA,GAAI,WAAW,SAAA,CAAU,QAAA;AAC/B,YAAA,mBAAA,GAAsB,IAAUC,MAAA,CAAA,OAAA,CAAQ,CAAA,CAAE,GAAG,CAAA,CAAE,CAAA,EAAG,EAAE,CAAC,CAAA;AAAA,UACvD;AAAA,QACF;AAAA,MACF;AAEA,MAAA,IAAI,IAAA,CAAK,KAAA,IAAS,YAAA,GAAe,CAAA,EAAG;AAClC,QAAA,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,YAAA,EAAc,mBAAmB,CAAA;AAAA,MACrD;AAEA,MAAA,QAAA,CAAS,MAAA,CAAO,OAAO,MAAM,CAAA;AAC7B,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,SAAA,EAAU;AAC1C,MAAA,IAAI,GAAA,CAAI,cAAA,IAAkB,KAAA,IAAS,CAAC,KAAK,YAAA,EAAc;AACrD,QAAA,MAAM,QAAA,GAAW,QAAA,CAAS,EAAA,CAAG,iBAAA,EAAkB;AAC/C,QAAA,IAAI,QAAA,EAAU;AACZ,UAAA,MAAM,UAAA,GAAa,KAAA,CAAM,aAAA,CAAc,QAAQ,CAAA;AAC/C,UAAA,IAAI,CAAC,UAAA,EAAY;AACf,YAAA,IAAA,CAAK,kBAAA,IAAsB,CAAA;AAC3B,YAAA,IAAI,IAAA,CAAK,sBAAsB,6BAAA,EAA+B;AAC5D,cAAA,IAAA,CAAK,eAAA,GAAkB,IAAA;AAAA,YACzB;AAAA,UACF,CAAA,MAAO;AACL,YAAA,IAAI,KAAK,eAAA,EAAiB;AACxB,cAAA,IAAA,CAAK,eAAA,GAAkB,KAAA;AACvB,cAAA,IAAA,CAAK,kBAAA,GAAqB,CAAA;AAC1B,cAAA,KAAK,KAAK,aAAA,EAAc;AAAA,YAC1B,CAAA,MAAO;AACL,cAAA,IAAA,CAAK,kBAAA,GAAqB,CAAA;AAAA,YAC5B;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAA;AACA,IAAA,QAAA,CAAS,iBAAiB,aAAa,CAAA;AAEvC,IAAA,MAAM,gBAAgB,MAAM;AAC1B,MAAA,IAAA,CAAK,YAAY,MAAA,EAAO;AAAA,IAC1B,CAAA;AACA,IAAA,MAAA,CAAO,gBAAA,CAAiB,UAAU,aAAa,CAAA;AAE/C,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,OAAA,CAAQ,WAAA,IAAe,QAAA,CAAS,IAAA;AACzD,IAAA,MAAM,QAAA,GAAW,QAAA,CAAS,YAAA,CAAa,QAAA,EAAU;AAAA,MAC/C,gBAAA,EAAkB,CAAC,eAAA,EAAiB,aAAa,CAAA;AAAA,MACjD,UAAA,EAAY,EAAE,IAAA,EAAM,WAAA;AAAY,KACjC,CAAA;AAED,IAAA,MAAM,YAAA,GACJ,eAAA,IAAmB,eAAA,YAA2B,WAAA,GAC1C,kBACA,IAAA,CAAK,OAAA,CAAQ,eAAA,IACb,IAAA,CAAK,OAAA,CAAQ,eAAA,YAA2B,WAAA,GACtC,IAAA,CAAK,QAAQ,eAAA,GACb,WAAA;AAER,IAAA,IAAI,CAAC,YAAA,CAAa,QAAA,CAAS,QAAQ,CAAA,EAAG;AACpC,MAAA,YAAA,CAAa,YAAY,QAAQ,CAAA;AAAA,IACnC;AAEA,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAChB,IAAA,IAAA,CAAK,aAAA,GAAgB,aAAA;AAErB,IAAA,IAAA,CAAK,OAAA,CAAQ,oBAAoB,QAAQ,CAAA;AACzC,IAAA,OAAO,QAAA;AAAA,EACT;AAAA,EAEA,QAAA,GAAwB;AACtB,IAAA,IAAI,CAAC,KAAK,UAAA,EAAY;AACpB,MAAA,MAAM,IAAI,MAAM,mDAAmD,CAAA;AAAA,IACrE;AACA,IAAA,OAAO,IAAA,CAAK,WAAW,QAAA,EAAS;AAAA,EAClC;AAAA,EAEA,SAAA,GAAqC;AACnC,IAAA,IAAI,CAAC,KAAK,UAAA,EAAY;AACpB,MAAA,MAAM,IAAI,MAAM,oDAAoD,CAAA;AAAA,IACtE;AACA,IAAA,OAAO,IAAA,CAAK,WAAW,SAAA,EAAU;AAAA,EACnC;AAAA,EAEA,WAAA,GAAmC;AACjC,IAAA,IAAI,CAAC,KAAK,UAAA,EAAY;AACpB,MAAA,MAAM,IAAI,MAAM,sDAAsD,CAAA;AAAA,IACxE;AACA,IAAA,OAAO,IAAA,CAAK,WAAW,WAAA,EAAY;AAAA,EACrC;AAAA,EAEA,gBAAA,GAA4B;AAC1B,IAAA,OAAO,KAAK,eAAA,IAAmB,IAAA,CAAK,YAAY,WAAA,EAAY,CAAE,GAAG,YAAA,KAAiB,IAAA;AAAA,EACpF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,aAAA,GAAwD;AAC5D,IAAA,IAAI,CAAC,KAAK,UAAA,EAAY;AACpB,MAAA,MAAM,IAAI,MAAM,mDAAmD,CAAA;AAAA,IACrE;AACA,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,UAAA,CAAW,WAAA,EAAY;AAC7C,IAAA,MAAM,OAAA,GAAU,QAAA,CAAS,EAAA,CAAG,UAAA,IAAa;AACzC,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,SAAA,EAAU;AAC1C,IAAA,MAAM,eAAA,GAAkB,IAAI,eAAA,IAAmB,KAAA;AAC/C,IAAA,MAAM,sBAAsB,IAAA,CAAK,GAAA;AAAA,MAC/B,wBAAA;AAAA,MACA,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,mBAAA,IAAuB,KAAK,wBAAwB;AAAA,KACnE;AAEA,IAAA,GAAA,CAAI,kBAAA,IAAqB;AACzB,IAAA,IAAA,CAAK,YAAA,GAAe,IAAA;AAEpB,IAAA,IAAI,IAAA,GAAsC,IAAA;AAE1C,IAAA,IAAI,aAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAM,aAAA,GAAgB,MAAM,IAAA,CAAK,YAAA,EAAa;AAC9C,MAAA,IAAA,GAAO,aAAA,CAAc,MAAA;AACrB,MAAA,aAAA,GAAgB,aAAA,CAAc,aAAA;AAAA,IAChC,CAAA,SAAE;AACA,MAAA,IAAA,CAAK,YAAA,GAAe,KAAA;AAAA,IACtB;AAEA,IAAA,MAAM,WACJ,IAAA,KACC,CAAC,oBACC,IAAA,CAAK,YAAA,CAAa,cAAc,CAAA,KAAM,mBAAA,CAAA;AAE3C,IAAA,IAAI,YAAY,IAAA,EAAM;AACpB,MAAA,GAAA,CAAI,wBAAwB,IAAI,CAAA;AAEhC,MAAA,IAAI,IAAA,CAAK,KAAA,IAAS,IAAA,CAAK,YAAA,EAAc;AACnC,QAAA,MAAM,YAAA,GAAe,GAAA,CAAI,QAAA,IAAY,CAAC,CAAC,IAAA,CAAK,UAAA;AAC5C,QAAA,MAAM,aAAA,GAAgB,IAAI,SAAA,KAAc,KAAA;AACxC,QAAA,IAAI,gBAAgB,aAAA,EAAe;AACjC,UAAA,IAAI;AACF,YAAA,MAAM,IAAA,CAAK,MAAM,iBAAA,EAAkB;AACnC,YAAA,IAAI,YAAA,EAAc;AAChB,cAAA,MAAM,IAAA,CAAK,KAAA,CAAM,gBAAA,CAAiB,IAAA,CAAK,UAAW,CAAA;AAAA,YACpD;AACA,YAAA,IAAA,CAAK,KAAA,CAAM,kBAAA,CAAmB,IAAA,EAAM,IAAA,CAAK,YAAY,CAAA;AAAA,UACvD,CAAA,CAAA,MAAQ;AAAA,UAER;AAAA,QACF;AAAA,MACF;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,MAAA,GACJ,aAAA,KACC,CAAC,IAAA,GACE,wCAAA,GACA,eAAA,GACE,CAAA,gBAAA,EAAmB,IAAA,CAAK,YAAA,CAAa,UAAA,IAAc,CAAC,CAAA,iBAAA,EAAoB,mBAAmB,CAAA,CAAA,CAAA,GAC3F,MAAA,CAAA;AACR,IAAA,GAAA,CAAI,wBAAwB,MAAM,CAAA;AAClC,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,YAAA,GAIX;AACD,IAAA,IAAI,CAAC,KAAK,UAAA,EAAY;AACpB,MAAA,MAAM,IAAI,MAAM,mDAAmD,CAAA;AAAA,IACrE;AACA,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,UAAA,CAAW,WAAA,EAAY;AAE7C,IAAA,MAAM,OAAA,GAAU,QAAA,CAAS,EAAA,CAAG,UAAA,IAAa;AACzC,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,cAAA,GAAiB,QAAA,CAAS,EAAA,CAAG,iBAAA,EAAkB;AACrD,IAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,EAAA,GAAK,SAAS,UAAA,EAAW;AAC/B,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,SAAA,EAAU;AAC1C,IAAA,MAAM,SAAA,GAAY,IAAI,6BAAA,IAAiC,2BAAA;AAEvD,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,MAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAE3B,MAAA,MAAM,QAAA,GAAW,CAAC,OAAA,EAAiB,sBAAA,KAAmC;AACpE,QAAA,OAAA,CAAQ,qBAAA,CAAsB,OAAO,KAAA,EAAe,OAAA,KAAqB;AACvE,UAAA,IAAI;AACF,YAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAC7B,YAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,aAAA,CAAc,cAAc,CAAA;AACvD,YAAA,IAAI,CAAC,UAAA,EAAY;AACf,cAAA,IAAI,OAAA,IAAW,SAAA,IAAa,OAAA,GAAU,CAAA,IAAK,kBAAA,EAAoB;AAC7D,gBAAA,MAAM,GAAA,GAAA,CAAO,SAAA,GAAY,GAAA,EAAM,OAAA,CAAQ,CAAC,CAAA;AACxC,gBAAA,OAAA,CAAQ;AAAA,kBACN,MAAA,EAAQ,IAAA;AAAA,kBACR,SAAA,EAAW,KAAA;AAAA,kBACX,aAAA,EAAe,+CAA+C,GAAG,CAAA,mDAAA;AAAA,iBAClE,CAAA;AAAA,cACH,CAAA,MAAO;AACL,gBAAA,QAAA,CAAS,OAAA,GAAU,GAAG,sBAAsB,CAAA;AAAA,cAC9C;AACA,cAAA;AAAA,YACF;AAEA,YAAA,MAAM,QAAQ,UAAA,CAAW,KAAA;AACzB,YAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,MAAA,EAAQ,KAAK,CAAA,EAAG;AACxC,cAAA,MAAM,IAAA,GAAO,MAAM,CAAC,CAAA;AACpB,cAAA,MAAM,WAAW,IAAA,CAAK,MAAA;AACtB,cAAA,IAAI,CAAC,QAAA,EAAU;AAEf,cAAA,MAAM,GAAA,GAAM,EAAA;AACZ,cAAA,MAAM,WAAA,GAAc,cAAA;AAMpB,cAAA,MAAM,OAAA,GAAU,IAAI,WAAA,CAAY,OAAA,EAAS,GAAG,CAAA;AAC5C,cAAA,MAAM,aAAA,GAAgB,OAAA,CAAQ,cAAA,GAAiB,QAAQ,CAAA,IAAK,IAAA;AAC5D,cAAA,IAAI,CAAC,aAAA,EAAe;AAEpB,cAAA,MAAM,QAAQ,QAAA,CAAS,KAAA;AACvB,cAAA,MAAM,SAAS,QAAA,CAAS,MAAA;AACxB,cAAA,IAAI,CAAC,KAAA,IAAS,CAAC,MAAA,EAAQ;AAEvB,cAAA,MAAM,YAAY,MAAM,uBAAA;AAAA,gBACtB,QAAA;AAAA,gBACA,aAAA;AAAA,gBACA,KAAA;AAAA,gBACA;AAAA,eACF;AAEA,cAAA,MAAM,UAAA,GAAa,mBAAA,CAAoB,IAAA,CAAK,gBAAA,EAAkB;AAAA,gBAC5D,KAAA;AAAA,gBACA,MAAA;AAAA,gBACA,CAAA,EAAG,CAAA;AAAA,gBACH,CAAA,EAAG;AAAA,eACJ,CAAA;AAED,cAAA,IAAI,aAAa,UAAA,EAAY;AAI3B,gBAAA,IAAA,CAAK,eAAe,IAAUA,MAAA,CAAA,OAAA,GAAU,SAAA,CAAU,IAAA,CAAK,UAAU,MAAM,CAAA;AAEvE,gBAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,iBAAA;AAAA,kBACvC,SAAA;AAAA,kBACA;AAAA,iBACF;AACA,gBAAA,OAAA,CAAQ,EAAE,MAAA,EAAQ,SAAA,EAAW,IAAA,EAAM,CAAA;AACnC,gBAAA;AAAA,cACF;AAAA,YACF;AAEA,YAAA,IAAI,sBAAA,GAAyB,KAAK,yBAAA,EAA2B;AAC3D,cAAA,OAAA,CAAQ;AAAA,gBACN,MAAA,EAAQ,IAAA;AAAA,gBACR,SAAA,EAAW,KAAA;AAAA,gBACX,aAAA,EACE;AAAA,eACH,CAAA;AAAA,YACH,CAAA,MAAO;AACL,cAAA,QAAA,CAAS,OAAA,GAAU,CAAA,EAAG,sBAAA,GAAyB,CAAC,CAAA;AAAA,YAClD;AAAA,UACF,SAAS,KAAA,EAAO;AACd,YAAA,MAAA,CAAO,KAAK,CAAA;AAAA,UACd,CAAA,SAAE;AACA,YAAA,EAAA,CAAG,eAAA;AAAA,cACD,EAAA,CAAG,WAAA;AAAA,cACH,OAAA,CAAQ,WAAA,CAAY,SAAA,EAAW,WAAA,IAAe;AAAA,aAChD;AAAA,UACF;AAAA,QACF,CAAC,CAAA;AAAA,MACH,CAAA;AACA,MAAA,QAAA,CAAS,GAAG,CAAC,CAAA;AAAA,IACf,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,OAAA,GAAgB;AACd,IAAA,IAAI,KAAK,aAAA,EAAe;AACtB,MAAA,MAAA,CAAO,mBAAA,CAAoB,QAAA,EAAU,IAAA,CAAK,aAAa,CAAA;AAAA,IACzD;AAEA,IAAA,IAAA,CAAK,UAAA,EAAY,WAAA,EAAY,CAAE,gBAAA,CAAiB,IAAI,CAAA;AACpD,IAAA,IAAA,CAAK,YAAY,OAAA,EAAQ;AACzB,IAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAClB,IAAA,IAAA,CAAK,OAAO,OAAA,EAAQ;AACpB,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AACb,IAAA,IAAA,CAAK,kBAAA,GAAqB,CAAA;AAC1B,IAAA,IAAA,CAAK,eAAA,GAAkB,KAAA;AAEvB,IAAA,IAAI,IAAA,CAAK,UAAU,aAAA,EAAe;AAChC,MAAA,IAAA,CAAK,QAAA,CAAS,aAAA,CAAc,WAAA,CAAY,IAAA,CAAK,QAAQ,CAAA;AAAA,IACvD;AACA,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAAA,EAClB;AACF","file":"index.js","sourcesContent":["import type { ILocalizeAndMapDetails, MapType } from './types';\n\n/** The subset of config that is safe to expose publicly (no credentials). */\nexport type IMultisetPublicConfig = Omit<IMultisetSdkConfig, 'clientId' | 'clientSecret'>;\n\nexport interface IMultisetSdkConfig {\n clientId: string;\n clientSecret: string;\n /** Map or map-set code used for localization. */\n code: string;\n /** Map or map-set type ('map' or 'map-set'). */\n mapType: MapType;\n endpoints?: Partial<IMultisetSdkEndpoints>;\n /** If true, show the mesh in the AR session. Default is false. */\n showMesh?: boolean;\n /** If true, show the coordinate gizmo when a pose is found. Defaults to true. */\n showGizmo?: boolean;\n /** If true, automatically start a localization run when the AR session starts. */\n autoLocalize?: boolean;\n /** If true, automatically re-localize when tracking is lost and then recovered. */\n relocalization?: boolean;\n /** When enabled, only accept a localization result if confidence >= confidenceThreshold. */\n confidenceCheck?: boolean;\n /** Minimum confidence (0.2–0.8) required when confidenceCheck is enabled. */\n confidenceThreshold?: number;\n /** Include device geo pose as a hint in localization requests. */\n passGeoPose?: boolean;\n /** Request geo coordinates in the localization response (if supported by backend). */\n geoCoordinatesInResponse?: boolean;\n /** Max time in ms to wait for a valid viewer pose before failing. Default 10000. */\n localizationTrackingTimeoutMs?: number;\n\n /** Invoked at the start of a localization run. */\n onLocalizationInit?: () => void;\n /** Invoked after a successful localization that meets confidence criteria (if enabled). */\n onLocalizationSuccess?: (result: ILocalizeAndMapDetails) => void;\n /** Invoked when all attempts fail or the best result is below the confidence threshold. */\n onLocalizationFailure?: (reason?: string) => void;\n\n /** Called after a successful authorization with the access token. */\n onAuthorize?: (token: string) => void;\n /** Called whenever a camera frame is captured and sent for localization. */\n onFrameCaptured?: (payload: IFrameCaptureEvent) => void;\n /** Called with the camera intrinsics used for a localization request. */\n onCameraIntrinsics?: (intrinsics: ICameraIntrinsicsEvent) => void;\n /** Called with the raw pose/localization result returned by the backend. */\n onPoseResult?: (payload: IPoseResultEvent) => void;\n /** Called when any error occurs during authorization or localization. */\n onError?: (error: unknown) => void;\n}\n\nexport interface IMultisetSdkEndpoints {\n authUrl: string;\n queryUrl: string;\n mapDetailsUrl: string;\n fileDownloadUrl: string;\n mapSetDetailsUrl: string;\n}\n\nexport interface IFrameCaptureEvent {\n blob: Blob;\n width: number;\n height: number;\n}\n\nexport interface ICameraIntrinsicsEvent {\n fx: number;\n fy: number;\n px: number;\n py: number;\n width: number;\n height: number;\n}\n\nexport interface IPoseResultEvent {\n poseFound: boolean;\n position: {\n x: number;\n y: number;\n z: number;\n };\n rotation: {\n x: number;\n y: number;\n z: number;\n w: number;\n };\n mapIds: string[];\n confidence?: number;\n}\n\nexport interface ILocalizeResultEvent {\n frame: IFrameCaptureEvent;\n intrinsics: ICameraIntrinsicsEvent;\n response: ILocalizeAndMapDetails | null;\n}\n\nexport const DEFAULT_ENDPOINTS: IMultisetSdkEndpoints = {\n authUrl: 'https://api.multiset.ai/v1/m2m/token',\n queryUrl: 'https://api.multiset.ai/v1/vps/map/query-form',\n mapDetailsUrl: 'https://api.multiset.ai/v1/vps/map/',\n mapSetDetailsUrl: 'https://api.multiset.ai/v1/vps/map-set/',\n fileDownloadUrl: 'https://api.multiset.ai/v1/file',\n};\n","import axios, { AxiosError } from 'axios';\nimport type {\n IMultisetSdkConfig,\n IMultisetPublicConfig,\n IMultisetSdkEndpoints,\n IFrameCaptureEvent,\n ICameraIntrinsicsEvent,\n} from './config';\nimport { DEFAULT_ENDPOINTS } from './config';\nimport type {\n ILocalizeAndMapDetails,\n ILocalizeResponse,\n IGetMapsDetailsResponse,\n} from './types';\n\nexport class MultisetClient {\n private readonly credentials: { clientId: string; clientSecret: string };\n private readonly config: IMultisetPublicConfig;\n private readonly endpoints: IMultisetSdkEndpoints;\n private accessToken: string | null = null;\n private mapDetailsCache: Record<string, IGetMapsDetailsResponse> = {};\n\n constructor(input: IMultisetSdkConfig) {\n const { clientId, clientSecret, ...rest } = input;\n this.credentials = { clientId, clientSecret };\n this.config = rest;\n this.endpoints = {\n ...DEFAULT_ENDPOINTS,\n ...rest.endpoints,\n };\n }\n\n get token(): string | null {\n return this.accessToken;\n }\n\n getConfig(): IMultisetPublicConfig {\n return this.config;\n }\n\n async downloadFile(key: string): Promise<string> {\n if (!this.accessToken || !key) {\n return '';\n }\n\n try {\n const response = await axios.get<{ url: string }>(\n `${this.endpoints.fileDownloadUrl}?key=${encodeURIComponent(key)}`,\n {\n headers: {\n Authorization: `Bearer ${this.accessToken}`,\n },\n }\n );\n\n return response.status === 200 ? response.data.url : '';\n } catch (error) {\n this.handleError(error);\n return '';\n }\n }\n\n async authorize(): Promise<string> {\n try {\n const response = await axios.post(\n this.endpoints.authUrl,\n {},\n {\n auth: {\n username: this.credentials.clientId,\n password: this.credentials.clientSecret,\n },\n }\n );\n\n const token: string | undefined =\n response.data?.token ?? response.data?.access_token;\n\n if (!token) {\n throw new Error('Authorization succeeded but no token was returned.');\n }\n\n this.accessToken = token;\n this.config.onAuthorize?.(token);\n return token;\n } catch (error) {\n this.handleError(error);\n throw error;\n }\n }\n\n private handleError(error: unknown): void {\n if (axios.isAxiosError(error)) {\n const axiosError = error as AxiosError;\n this.config.onError?.(axiosError);\n } else {\n this.config.onError?.(error);\n }\n }\n\n async localizeWithFrame(\n frame: IFrameCaptureEvent,\n intrinsics: ICameraIntrinsicsEvent\n ): Promise<ILocalizeAndMapDetails | null> {\n if (!this.accessToken) {\n throw new Error('Access token is missing. Call authorize() first.');\n }\n\n this.config.onFrameCaptured?.(frame);\n this.config.onCameraIntrinsics?.(intrinsics);\n\n const queryResult = await this.queryLocalization(frame, intrinsics);\n\n if (queryResult?.localizeData?.poseFound) {\n this.config.onPoseResult?.(queryResult.localizeData);\n }\n\n return queryResult;\n }\n\n private async getGeoPoseComponents(): Promise<\n { latitude: number, longitude: number, altitude: number } | null\n > {\n if (\n typeof navigator === 'undefined' ||\n !('geolocation' in navigator) ||\n !navigator.geolocation\n ) {\n return null;\n }\n\n try {\n const position = await new Promise<GeolocationPosition>((resolve, reject) => {\n navigator.geolocation.getCurrentPosition(resolve, reject, {\n enableHighAccuracy: true,\n timeout: 10000,\n maximumAge: 0,\n });\n });\n\n const { latitude, longitude, altitude } = position.coords;\n const safeAltitude =\n typeof altitude === 'number' && !Number.isNaN(altitude) ? altitude : 0.0;\n\n return { latitude, longitude, altitude: safeAltitude };\n } catch {\n return null;\n }\n }\n\n private async queryLocalization(\n frame: IFrameCaptureEvent,\n intrinsics: ICameraIntrinsicsEvent\n ): Promise<ILocalizeAndMapDetails | null> {\n const formData = new FormData();\n\n if (this.config.mapType === 'map') {\n formData.append('mapCode', this.config.code);\n } else {\n formData.append('mapSetCode', this.config.code);\n }\n formData.append('isRightHanded', 'true');\n formData.append('fx', `${intrinsics.fx}`);\n formData.append('fy', `${intrinsics.fy}`);\n formData.append('px', `${intrinsics.px}`);\n formData.append('py', `${intrinsics.py}`);\n formData.append('width', `${frame.width}`);\n formData.append('height', `${frame.height}`);\n formData.append('queryImage', frame.blob);\n if (this.config.geoCoordinatesInResponse) {\n formData.append('geoCoordinatesInResponse', 'true');\n }\n if (this.config.passGeoPose) {\n const components = await this.getGeoPoseComponents();\n if (components) {\n const { latitude, longitude, altitude } = components;\n const geoHint = `${latitude},${longitude},${altitude}`;\n formData.append('geoHint', geoHint);\n }\n }\n\n try {\n const response = await axios.post<ILocalizeResponse>(\n this.endpoints.queryUrl,\n formData,\n {\n headers: {\n Authorization: `Bearer ${this.accessToken}`,\n },\n }\n );\n\n const data = response.data;\n if (!data.poseFound) {\n return null;\n }\n\n const result: ILocalizeAndMapDetails = {\n localizeData: data,\n };\n\n if (\n this.config.showMesh &&\n data.mapCodes?.length\n ) {\n const mapCode = data.mapCodes[0];\n const cached = this.mapDetailsCache[mapCode];\n if (cached) {\n result.mapDetails = cached;\n } else {\n const mapDetails = await this.fetchMapDetails(mapCode);\n if (mapDetails) {\n this.mapDetailsCache[mapCode] = mapDetails;\n result.mapDetails = mapDetails;\n }\n }\n }\n\n return result;\n } catch (error) {\n this.handleError(error);\n return null;\n }\n }\n\n private async fetchMapDetails(mapCode: string): Promise<IGetMapsDetailsResponse | null> {\n try {\n const response = await axios.get<IGetMapsDetailsResponse>(\n `${this.endpoints.mapDetailsUrl}${mapCode}`,\n {\n headers: {\n Authorization: `Bearer ${this.accessToken}`,\n },\n }\n );\n return response.data;\n } catch (error) {\n this.handleError(error);\n return null;\n }\n }\n}\n","import type { ICameraIntrinsicsEvent } from '../../core';\n\nexport function getCameraIntrinsics(\n projectionMatrix: Float32Array,\n viewport: XRViewport\n): ICameraIntrinsicsEvent {\n const p = projectionMatrix;\n const u0 = ((1 - p[8]) * viewport.width) / 2 + viewport.x;\n const v0 = ((1 - p[9]) * viewport.height) / 2 + viewport.y;\n const ax = (viewport.width / 2) * p[0];\n const ay = (viewport.height / 2) * p[5];\n\n return {\n fx: ax,\n fy: ay,\n px: u0,\n py: v0,\n width: viewport.width,\n height: viewport.height,\n };\n}\n","import * as THREE from 'three';\nimport type { IFrameCaptureEvent } from '../../core';\n\nexport async function compressToJpeg(\n buffer: ArrayBuffer,\n width: number,\n height: number,\n quality = 0.8\n): Promise<Blob> {\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n if (!ctx) return new Blob();\n\n const imageData = new ImageData(new Uint8ClampedArray(buffer), width, height);\n ctx.putImageData(imageData, 0, 0);\n\n return new Promise((resolve) => {\n canvas.toBlob((blob) => resolve(blob ?? new Blob()), 'image/jpeg', quality);\n });\n}\n\nexport async function getCameraTextureAsImage(\n renderer: THREE.WebGLRenderer,\n webGLTexture: WebGLTexture,\n width: number,\n height: number\n): Promise<IFrameCaptureEvent | null> {\n const gl = renderer.getContext();\n if (!gl) return null;\n\n const framebuffer = gl.createFramebuffer();\n if (!framebuffer) return null;\n\n let pixelBuffer: Uint8Array;\n try {\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.TEXTURE_2D,\n webGLTexture,\n 0\n );\n\n pixelBuffer = new Uint8Array(width * height * 4);\n gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixelBuffer);\n } finally {\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.deleteFramebuffer(framebuffer);\n }\n\n const flippedData = new Uint8ClampedArray(pixelBuffer.length);\n for (let row = 0; row < height; row += 1) {\n const sourceStart = row * width * 4;\n const destStart = (height - row - 1) * width * 4;\n flippedData.set(\n pixelBuffer.subarray(sourceStart, sourceStart + width * 4),\n destStart\n );\n }\n\n const blob = await compressToJpeg(flippedData.buffer, width, height, 0.7);\n\n if (!blob.size) {\n return null;\n }\n\n return {\n blob,\n width,\n height,\n };\n}\n","import * as THREE from 'three';\n\n/**\n * Owns the Three.js scene, camera, and renderer for the AR session.\n * Handles resize and dispose; animation loop remains in the controller.\n */\nexport class Experience {\n private scene: THREE.Scene;\n private camera: THREE.PerspectiveCamera;\n private renderer: THREE.WebGLRenderer;\n\n constructor(canvas: HTMLCanvasElement) {\n this.renderer = new THREE.WebGLRenderer({\n canvas,\n antialias: true,\n alpha: true,\n });\n this.renderer.setSize(window.innerWidth, window.innerHeight);\n this.renderer.setPixelRatio(window.devicePixelRatio);\n this.renderer.xr.enabled = true;\n\n this.camera = new THREE.PerspectiveCamera(\n 45,\n window.innerWidth / window.innerHeight,\n 0.2,\n 10000\n );\n\n this.scene = new THREE.Scene();\n this.setupLights();\n }\n\n private setupLights(): void {\n const light = new THREE.HemisphereLight(0xffffff, 0xf8f0ff, 1);\n light.position.set(0.5, 2, 0.25);\n this.scene.add(light);\n\n const diLight = new THREE.DirectionalLight('#7B2CBF');\n diLight.position.set(0, 2, 0);\n this.scene.add(diLight);\n }\n\n getScene(): THREE.Scene {\n return this.scene;\n }\n\n getCamera(): THREE.PerspectiveCamera {\n return this.camera;\n }\n\n getRenderer(): THREE.WebGLRenderer {\n return this.renderer;\n }\n\n resize(): void {\n this.camera.aspect = window.innerWidth / window.innerHeight;\n this.camera.updateProjectionMatrix();\n this.renderer.setSize(window.innerWidth, window.innerHeight);\n }\n\n dispose(): void {\n this.renderer.dispose();\n (this as unknown as { scene: THREE.Scene | null }).scene = null;\n (this as unknown as { camera: THREE.PerspectiveCamera | null }).camera = null;\n (this as unknown as { renderer: THREE.WebGLRenderer | null }).renderer = null;\n }\n}\n","import * as THREE from 'three';\n\nconst VERTEX = `\nvarying vec3 vWorldPosition;\nvarying vec3 vWorldNormal;\n\nvoid main() {\n vec4 worldPos = modelMatrix * vec4(position, 1.0);\n vWorldPosition = worldPos.xyz;\n vWorldNormal = normalize(mat3(modelMatrix) * normal);\n\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n`;\n\nconst FRAGMENT = `\nuniform vec3 uColor;\nuniform float uOpacity;\n\nuniform vec3 uGridColor;\nuniform float uGridSize;\nuniform float uGridLineWidth;\nuniform float uShowGrid;\n\nuniform vec3 uCenter;\nuniform float uRadius;\nuniform float uProgress;\n\nuniform vec3 uGlowColor;\nuniform float uGlowWidth;\nuniform float uGlowIntensity;\n\nuniform vec3 uLightColor;\nuniform vec3 uLightDirection;\n\nvarying vec3 vWorldPosition;\nvarying vec3 vWorldNormal;\n\nfloat getGridFactor(vec3 worldPos, vec3 worldNormal, float gridSize, float lineWidth) {\n vec3 absNormal = abs(worldNormal);\n vec2 gridCoord;\n\n if (absNormal.y > absNormal.x && absNormal.y > absNormal.z) {\n gridCoord = worldPos.xz / gridSize;\n } else if (absNormal.x > absNormal.z) {\n gridCoord = worldPos.yz / gridSize;\n } else {\n gridCoord = worldPos.xy / gridSize;\n }\n\n vec2 gridFract = fract(abs(gridCoord));\n vec2 distToLine = min(gridFract, 1.0 - gridFract);\n float minDist = min(distToLine.x, distToLine.y);\n float gridFactor = 1.0 - smoothstep(0.0, lineWidth, minDist);\n\n return gridFactor;\n}\n\nvoid main() {\n vec3 baseColor = uColor;\n float baseAlpha = uOpacity;\n\n float distanceFromCenter = length(vWorldPosition - uCenter);\n float normalizedDistance = distanceFromCenter / max(uRadius, 0.001);\n float threshold = uProgress;\n\n if (threshold - normalizedDistance - 0.001 < 0.0) {\n discard;\n }\n\n float distanceFromEdge = threshold - normalizedDistance;\n\n float gridFactor = getGridFactor(vWorldPosition, normalize(vWorldNormal), uGridSize, uGridLineWidth);\n\n vec3 colorGridMixed = mix(baseColor, uGridColor, gridFactor * uShowGrid);\n float alphaGridMixed = max(baseAlpha, gridFactor * uShowGrid);\n\n float glowFactor = clamp(1.0 - clamp(distanceFromEdge / max(uGlowWidth, 0.001), 0.0, 1.0), 0.0, 1.0);\n glowFactor *= glowFactor;\n\n vec3 glowContribution = uGlowColor * glowFactor * uGlowIntensity;\n\n float alphaWithGlow = max(alphaGridMixed, glowFactor);\n alphaWithGlow = max(alphaWithGlow, 0.3);\n\n vec3 N = normalize(vWorldNormal);\n vec3 L = normalize(uLightDirection);\n float ndotl = max(0.3, dot(N, L));\n vec3 ambient = vec3(0.4);\n vec3 lighting = uLightColor * ndotl + ambient;\n\n vec3 litColor = colorGridMixed * lighting;\n vec3 finalColor = litColor + glowContribution * 0.5;\n\n gl_FragColor = vec4(finalColor, alphaWithGlow);\n}\n`;\n\nexport interface IGridMaterialOptions {\n color?: string | THREE.Color;\n opacity?: number;\n\n gridColor?: string | THREE.Color;\n gridScale?: number;\n gridLineWidth?: number;\n showGrid?: number;\n\n /** Center of radial effect (world space; can be updated after creation). */\n center?: THREE.Vector3;\n /** Max radius for radial progress (world units). */\n radius?: number;\n /** Progress 0–1; 1 = fully visible. */\n progress?: number;\n\n glowColor?: string | THREE.Color;\n glowWidth?: number;\n glowIntensity?: number;\n\n lightColor?: string | THREE.Color;\n /** Direction from surface toward light (world space). */\n lightDirection?: THREE.Vector3;\n}\n\n/**\n * Creates a ShaderMaterial with radial progress reveal, grid overlay, edge glow,\n * and simple directional lighting (Unity-style).\n */\nexport function createGridMaterial(\n options: IGridMaterialOptions = {}\n): THREE.ShaderMaterial {\n const color = options.color ?? '#7B2CBF';\n const opacity = options.opacity ?? (150 / 255);\n\n const gridColor = options.gridColor ?? '#ffeb3b';\n const gridScale = options.gridScale ?? 2.0;\n const gridLineWidth = options.gridLineWidth ?? 0.02;\n const showGrid = options.showGrid ?? 1.0;\n\n const center = options.center ?? new THREE.Vector3(0, 0, 0);\n const radius = options.radius ?? 1.0;\n const progress = options.progress ?? 1.0;\n\n const glowColor = options.glowColor ?? '#FF3A00';\n const glowWidth = options.glowWidth ?? 0.05;\n const glowIntensity = options.glowIntensity ?? 2.0;\n\n const lightColor = options.lightColor ?? '#ffffff';\n const lightDirection =\n options.lightDirection ?? new THREE.Vector3(0.3, 1.0, 0.3).normalize();\n\n return new THREE.ShaderMaterial({\n vertexShader: VERTEX,\n fragmentShader: FRAGMENT,\n transparent: true,\n side: THREE.DoubleSide,\n uniforms: {\n uColor: { value: typeof color === 'string' ? new THREE.Color(color) : color },\n uOpacity: { value: opacity },\n\n uGridColor: {\n value: typeof gridColor === 'string' ? new THREE.Color(gridColor) : gridColor,\n },\n uGridSize: { value: gridScale },\n uGridLineWidth: { value: gridLineWidth },\n uShowGrid: { value: showGrid },\n\n uCenter: { value: center.clone() },\n uRadius: { value: radius },\n uProgress: { value: progress },\n\n uGlowColor: {\n value: typeof glowColor === 'string' ? new THREE.Color(glowColor) : glowColor,\n },\n uGlowWidth: { value: glowWidth },\n uGlowIntensity: { value: glowIntensity },\n\n uLightColor: {\n value: typeof lightColor === 'string' ? new THREE.Color(lightColor) : lightColor,\n },\n uLightDirection: { value: lightDirection.clone() },\n },\n });\n}\n","import * as THREE from 'three';\nimport type { MultisetClient, ILocalizeAndMapDetails } from '../core';\nimport type { IGetMapsDetailsResponse } from '../core';\nimport { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { TransformControls } from 'three/examples/jsm/controls/TransformControls.js';\nimport { createGridMaterial } from './materials/gridMaterial';\n\nconst LARGE_MAP_THRESHOLD = 50.0;\n\nexport class MapMeshVisualizer {\n private readonly meshGroup: THREE.Group;\n private readonly gltfLoader: GLTFLoader;\n private readonly dracoLoader: DRACOLoader;\n\n private gizmoControl: TransformControls | null = null;\n private gizmoHelper: THREE.Object3D | null = null;\n private meshMaterial: THREE.ShaderMaterial | null = null;\n private readonly localCenter = new THREE.Vector3();\n private localRadius = 0;\n private readonly radialDuration = 4.0; // seconds for full radial reveal\n private readonly radialRepeatInterval = 20.0; // seconds before replaying the effect\n private idleTimeAfterReveal = 0; // seconds since progress reached 1\n private readonly lastViewerWorldPosition = new THREE.Vector3();\n\n constructor(\n private readonly scene: THREE.Scene,\n private readonly client: MultisetClient,\n private readonly renderer: THREE.WebGLRenderer,\n private readonly camera: THREE.Camera\n ) {\n this.meshGroup = new THREE.Group();\n this.meshGroup.visible = false;\n this.scene.add(this.meshGroup);\n\n this.dracoLoader = new DRACOLoader();\n this.dracoLoader.setDecoderPath('/draco/');\n\n this.gltfLoader = new GLTFLoader();\n this.gltfLoader.setDRACOLoader(this.dracoLoader);\n }\n\n getMeshGroup(): THREE.Group {\n return this.meshGroup;\n }\n\n async ensureGizmoLoaded(): Promise<void> {\n const cfg = this.client.getConfig();\n if (cfg.showGizmo === false) {\n return;\n }\n if (!this.gizmoControl) {\n const gizmo = new TransformControls(this.camera, this.renderer.domElement);\n gizmo.setMode('translate');\n gizmo.setSpace('local');\n gizmo.enabled = false;\n const helper = gizmo.getHelper();\n this.scene.add(helper);\n gizmo.attach(this.meshGroup);\n this.gizmoControl = gizmo;\n this.gizmoHelper = helper;\n }\n this.gizmoHelper!.visible = true;\n }\n\n async ensureMeshLoaded(mapDetails: IGetMapsDetailsResponse): Promise<void> {\n if (this.scene.getObjectByName(mapDetails._id)) {\n return;\n }\n\n const meshKey = mapDetails.mapMesh?.rawMesh?.meshLink;\n if (!meshKey) {\n return;\n }\n\n const url = await this.client.downloadFile(meshKey);\n if (!url) {\n return;\n }\n\n await new Promise<void>((resolve, reject) => {\n this.gltfLoader.load(\n url,\n (gltf) => {\n const box = new THREE.Box3().setFromObject(gltf.scene);\n const sizeVec = box.getSize(new THREE.Vector3());\n let size = sizeVec.length();\n const center = box.getCenter(new THREE.Vector3());\n\n if (size > LARGE_MAP_THRESHOLD) {\n size = LARGE_MAP_THRESHOLD;\n }\n\n this.localCenter.copy(center);\n this.localRadius = Math.max(size / 2, 0.001);\n\n const meshMaterial = createGridMaterial({\n color: '#7B2CBF',\n opacity: 0.58,\n gridColor: '#ffeb3b',\n gridScale: 2.0,\n gridLineWidth: 0.02,\n showGrid: 1.0,\n center: this.localCenter.clone(),\n radius: this.localRadius,\n progress: 0.0,\n glowColor: '#FF3A00',\n glowWidth: 0.05,\n glowIntensity: 2.0,\n });\n\n this.meshMaterial = meshMaterial;\n\n gltf.scene.traverse((child) => {\n if ((child as THREE.Mesh).isMesh) {\n (child as THREE.Mesh).material = meshMaterial;\n }\n });\n\n gltf.scene.name = mapDetails._id;\n this.meshGroup.add(gltf.scene);\n resolve();\n },\n undefined,\n (error) => {\n reject(error instanceof Error ? error : new Error(String(error)));\n }\n );\n });\n }\n\n applyMeshTransform(\n best: ILocalizeAndMapDetails,\n trackerSpace: THREE.Matrix4\n ): void {\n const pose = best.localizeData;\n\n const resPosition = new THREE.Vector3(\n pose.position.x,\n pose.position.y,\n pose.position.z\n );\n\n const resRotation = new THREE.Quaternion(\n pose.rotation.x,\n pose.rotation.y,\n pose.rotation.z,\n pose.rotation.w\n );\n\n const responseMatrix = new THREE.Matrix4();\n responseMatrix.compose(resPosition, resRotation, new THREE.Vector3(1, 1, 1));\n\n const inverseResponseMatrix = responseMatrix.clone().invert();\n\n const resultantMatrix = new THREE.Matrix4();\n resultantMatrix.multiplyMatrices(trackerSpace, inverseResponseMatrix);\n\n const position = new THREE.Vector3();\n const rotation = new THREE.Quaternion();\n const scale = new THREE.Vector3();\n resultantMatrix.decompose(position, rotation, scale);\n\n this.meshGroup.position.copy(position);\n this.meshGroup.quaternion.copy(rotation);\n this.meshGroup.scale.set(1, 1, 1);\n this.meshGroup.visible = true;\n this.meshGroup.updateMatrix();\n\n if (this.meshMaterial) {\n this.meshMaterial.uniforms.uCenter.value\n .copy(this.localCenter)\n .applyMatrix4(this.meshGroup.matrixWorld);\n }\n }\n\n update(\n deltaSeconds: number,\n viewerWorldPosition?: THREE.Vector3 | null\n ): void {\n if (!this.meshMaterial) {\n return;\n }\n\n if (viewerWorldPosition) {\n this.lastViewerWorldPosition.copy(viewerWorldPosition);\n }\n\n const uniforms = this.meshMaterial.uniforms as {\n uProgress?: { value: number };\n uCenter?: { value: THREE.Vector3 };\n };\n\n if (!uniforms.uProgress) {\n return;\n }\n\n const current = uniforms.uProgress.value ?? 0;\n\n if (current === 0 && uniforms.uCenter && this.lastViewerWorldPosition.lengthSq() > 0) {\n uniforms.uCenter.value.copy(this.lastViewerWorldPosition);\n }\n\n if (current >= 1) {\n this.idleTimeAfterReveal += deltaSeconds;\n if (this.idleTimeAfterReveal >= this.radialRepeatInterval) {\n uniforms.uProgress.value = 0;\n this.idleTimeAfterReveal = 0;\n }\n return;\n }\n\n this.idleTimeAfterReveal = 0;\n const next = Math.min(\n current + deltaSeconds / this.radialDuration,\n 1\n );\n\n uniforms.uProgress.value = next;\n }\n\n dispose(): void {\n this.meshMaterial = null;\n this.meshGroup.traverse((child) => {\n const mesh = child as THREE.Mesh;\n if (mesh.isMesh) {\n mesh.geometry.dispose();\n if (Array.isArray(mesh.material)) {\n mesh.material.forEach((m) => m.dispose());\n } else {\n (mesh.material as THREE.Material).dispose();\n }\n }\n });\n this.scene.remove(this.meshGroup);\n this.dracoLoader.dispose();\n if (this.gizmoHelper) {\n this.scene.remove(this.gizmoHelper);\n }\n if (this.gizmoControl) {\n this.gizmoControl.dispose();\n }\n }\n}\n\n","import * as THREE from 'three';\nimport type { MultisetClient, ILocalizeAndMapDetails } from '../../core';\nimport type { IGetMapsDetailsResponse } from '../../core';\nimport { MapMeshVisualizer } from '../mapMeshVisualizer';\n\n/**\n * Composes scene content for the AR session (e.g. map mesh).\n * Delegates to MapMeshVisualizer for mesh load and transform.\n */\nexport class World {\n private readonly meshVisualizer: MapMeshVisualizer;\n\n constructor(\n scene: THREE.Scene,\n client: MultisetClient,\n renderer: THREE.WebGLRenderer,\n camera: THREE.Camera\n ) {\n this.meshVisualizer = new MapMeshVisualizer(scene, client, renderer, camera);\n }\n\n async ensureGizmoLoaded(): Promise<void> {\n await this.meshVisualizer.ensureGizmoLoaded();\n }\n\n async ensureMeshLoaded(mapDetails: IGetMapsDetailsResponse): Promise<void> {\n await this.meshVisualizer.ensureMeshLoaded(mapDetails);\n }\n\n applyMeshTransform(\n best: ILocalizeAndMapDetails,\n trackerSpace: THREE.Matrix4\n ): void {\n this.meshVisualizer.applyMeshTransform(best, trackerSpace);\n }\n\n update(\n deltaSeconds: number,\n viewerWorldPosition?: THREE.Vector3 | null\n ): void {\n this.meshVisualizer.update(deltaSeconds, viewerWorldPosition);\n }\n\n dispose(): void {\n this.meshVisualizer.dispose();\n }\n}\n","import * as THREE from 'three';\nimport { ARButton } from 'three/examples/jsm/webxr/ARButton.js';\n\nimport type {\n MultisetClient,\n ILocalizeAndMapDetails,\n} from '../core';\nimport { getCameraIntrinsics } from './internal/cameraIntrinsics';\nimport { getCameraTextureAsImage } from './internal/frameCapture';\nimport { Experience } from './experience/Experience';\nimport { World } from './world/World';\nconst CONFIDENCE_THRESHOLD_MIN = 0.2;\nconst CONFIDENCE_THRESHOLD_MAX = 0.8;\nconst TRACKING_LOSS_FRAME_THRESHOLD = 60;\n/** Default max time (ms) to wait for a valid viewer pose before failing. */\nconst DEFAULT_TRACKING_TIMEOUT_MS = 10_000;\n/** Max XR frames to wait for viewer pose (backup cap; ~10s at 30fps). */\nconst TRACKING_FRAME_CAP = 300;\n/** Max frames with valid pose but no camera image before failing. */\nconst CAMERA_IMAGE_MAX_ATTEMPTS = 10;\n\n/**\n * Options for WebxrController. Property names align with Unity SingleFrameLocalizationManager\n * where applicable (see https://docs.multiset.ai/unity-sdk/api-reference/singleframelocalizationmanager).\n */\nexport interface IWebxrControllerOptions {\n client: MultisetClient;\n canvas?: HTMLCanvasElement;\n overlayRoot?: HTMLElement;\n buttonContainer?: HTMLElement;\n onARButtonCreated?: (button: HTMLButtonElement) => void;\n onSessionStart?: () => void;\n onSessionEnd?: () => void;\n}\n\ntype XRViewWithCamera = XRView & {\n camera?: {\n width: number;\n height: number;\n [key: string]: unknown;\n };\n};\n\ntype XRWebGLBindingLike = {\n getCameraImage: (camera: XRViewWithCamera['camera']) => WebGLTexture | null;\n};\n\nexport class WebxrController {\n private experience: Experience | null = null;\n private world: World | null = null;\n private arButton: HTMLButtonElement | null = null;\n private resizeHandler: (() => void) | null = null;\n private isSessionActive: boolean = false;\n private trackingLossFrames: number = 0;\n private hadTrackingLoss: boolean = false;\n private isLocalizing: boolean = false;\n private trackerSpace: THREE.Matrix4 | null = null;\n\n constructor(private readonly options: IWebxrControllerOptions) { }\n\n async initialize(buttonContainer?: HTMLElement): Promise<HTMLButtonElement> {\n if (this.experience) {\n return this.arButton!;\n }\n\n if (!window.isSecureContext) {\n throw new Error('WebXR requires a secure context (HTTPS).');\n }\n\n const canvas = this.options.canvas ?? document.createElement('canvas');\n\n this.experience = new Experience(canvas);\n const renderer = this.experience.getRenderer();\n const camera = this.experience.getCamera();\n const scene = this.experience.getScene();\n\n this.world = new World(scene, this.options.client, renderer, camera);\n\n renderer.xr.addEventListener('sessionstart', () => {\n this.isSessionActive = true;\n this.options.onSessionStart?.();\n const cfg = this.options.client.getConfig();\n if (cfg.autoLocalize) {\n const session = renderer.xr.getSession();\n if (session) {\n session.requestAnimationFrame(() => {\n void this.localizeFrame();\n });\n } else {\n void this.localizeFrame();\n }\n }\n });\n\n renderer.xr.addEventListener('sessionend', () => {\n this.isSessionActive = false;\n this.options.onSessionEnd?.();\n });\n\n let lastTime = 0;\n\n const animationLoop = (time: number, frame: XRFrame | null) => {\n const deltaSeconds = lastTime === 0 ? 0 : (time - lastTime) / 1000;\n lastTime = time;\n\n let viewerWorldPosition: THREE.Vector3 | null = null;\n if (frame) {\n const refSpace = renderer.xr.getReferenceSpace();\n if (refSpace) {\n const viewerPose = frame.getViewerPose(refSpace);\n if (viewerPose) {\n const p = viewerPose.transform.position;\n viewerWorldPosition = new THREE.Vector3(p.x, p.y, p.z);\n }\n }\n }\n\n if (this.world && deltaSeconds > 0) {\n this.world.update(deltaSeconds, viewerWorldPosition);\n }\n\n renderer.render(scene, camera);\n const cfg = this.options.client.getConfig();\n if (cfg.relocalization && frame && !this.isLocalizing) {\n const refSpace = renderer.xr.getReferenceSpace();\n if (refSpace) {\n const viewerPose = frame.getViewerPose(refSpace);\n if (!viewerPose) {\n this.trackingLossFrames += 1;\n if (this.trackingLossFrames >= TRACKING_LOSS_FRAME_THRESHOLD) {\n this.hadTrackingLoss = true;\n }\n } else {\n if (this.hadTrackingLoss) {\n this.hadTrackingLoss = false;\n this.trackingLossFrames = 0;\n void this.localizeFrame();\n } else {\n this.trackingLossFrames = 0;\n }\n }\n }\n }\n };\n renderer.setAnimationLoop(animationLoop);\n\n const resizeHandler = () => {\n this.experience?.resize();\n };\n window.addEventListener('resize', resizeHandler);\n\n const overlayRoot = this.options.overlayRoot ?? document.body;\n const arButton = ARButton.createButton(renderer, {\n requiredFeatures: ['camera-access', 'dom-overlay'],\n domOverlay: { root: overlayRoot },\n }) as HTMLButtonElement;\n\n const buttonParent =\n buttonContainer && buttonContainer instanceof HTMLElement\n ? buttonContainer\n : this.options.buttonContainer &&\n this.options.buttonContainer instanceof HTMLElement\n ? this.options.buttonContainer\n : overlayRoot;\n\n if (!buttonParent.contains(arButton)) {\n buttonParent.appendChild(arButton);\n }\n\n this.arButton = arButton;\n this.resizeHandler = resizeHandler;\n\n this.options.onARButtonCreated?.(arButton);\n return arButton;\n }\n\n getScene(): THREE.Scene {\n if (!this.experience) {\n throw new Error('Scene: WebXR controller has not been initialized.');\n }\n return this.experience.getScene();\n }\n\n getCamera(): THREE.PerspectiveCamera {\n if (!this.experience) {\n throw new Error('Camera: WebXR controller has not been initialized.');\n }\n return this.experience.getCamera();\n }\n\n getRenderer(): THREE.WebGLRenderer {\n if (!this.experience) {\n throw new Error('Renderer: WebXR controller has not been initialized.');\n }\n return this.experience.getRenderer();\n }\n\n hasActiveSession(): boolean {\n return this.isSessionActive && this.experience?.getRenderer().xr.isPresenting === true;\n }\n\n /**\n * Runs a single-frame localization: captures one frame, evaluates the result\n * against the optional confidenceThreshold, and fires\n * onLocalizationInit / onLocalizationSuccess / onLocalizationFailure.\n * Aligns with Unity SingleFrameLocalizationManager.LocalizeFrame().\n */\n async localizeFrame(): Promise<ILocalizeAndMapDetails | null> {\n if (!this.experience) {\n throw new Error('WebXR: WebXR controller has not been initialized.');\n }\n const renderer = this.experience.getRenderer();\n const session = renderer.xr.getSession?.();\n if (!session) {\n throw new Error(\n 'WebXR Session: No active WebXR session. Start AR before calling localizeFrame().'\n );\n }\n\n const cfg = this.options.client.getConfig();\n const confidenceCheck = cfg.confidenceCheck ?? false;\n const confidenceThreshold = Math.max(\n CONFIDENCE_THRESHOLD_MIN,\n Math.min(cfg.confidenceThreshold ?? 0.5, CONFIDENCE_THRESHOLD_MAX)\n );\n\n cfg.onLocalizationInit?.();\n this.isLocalizing = true;\n\n let best: ILocalizeAndMapDetails | null = null;\n\n let failureReason: string | undefined;\n try {\n const captureResult = await this.captureFrame();\n best = captureResult.result;\n failureReason = captureResult.failureReason;\n } finally {\n this.isLocalizing = false;\n }\n\n const accepted =\n best &&\n (!confidenceCheck ||\n (best.localizeData.confidence ?? 0) >= confidenceThreshold);\n\n if (accepted && best) {\n cfg.onLocalizationSuccess?.(best);\n\n if (this.world && this.trackerSpace) {\n const willShowMesh = cfg.showMesh && !!best.mapDetails;\n const willShowGizmo = cfg.showGizmo !== false;\n if (willShowMesh || willShowGizmo) {\n try {\n await this.world.ensureGizmoLoaded();\n if (willShowMesh) {\n await this.world.ensureMeshLoaded(best.mapDetails!);\n }\n this.world.applyMeshTransform(best, this.trackerSpace);\n } catch {\n // Mesh/gizmo loading failure must not prevent returning the localization result\n }\n }\n }\n return best;\n }\n\n const reason =\n failureReason ??\n (!best\n ? 'All attempts failed to produce a pose.'\n : confidenceCheck\n ? `Best confidence ${best.localizeData.confidence ?? 0} below threshold ${confidenceThreshold}.`\n : undefined);\n cfg.onLocalizationFailure?.(reason);\n return null;\n }\n\n /**\n * Internal: captures one frame and calls the localization API. Waits for a\n * valid viewer pose up to localizationTrackingTimeoutMs (and TRACKING_FRAME_CAP),\n * then tries to get a camera image (up to CAMERA_IMAGE_MAX_ATTEMPTS). Returns\n * result, apiCalled, and an optional failureReason for onLocalizationFailure.\n */\n private async captureFrame(): Promise<{\n result: ILocalizeAndMapDetails | null;\n apiCalled: boolean;\n failureReason?: string;\n }> {\n if (!this.experience) {\n throw new Error('WebXR: WebXR controller has not been initialized.');\n }\n const renderer = this.experience.getRenderer();\n\n const session = renderer.xr.getSession?.();\n if (!session) {\n throw new Error(\n 'WebXR Session: No active WebXR session. Start AR before capturing.'\n );\n }\n\n const referenceSpace = renderer.xr.getReferenceSpace();\n if (!referenceSpace) {\n throw new Error(\n 'WebXR Reference Space: Unable to acquire XR reference space.'\n );\n }\n\n const gl = renderer.getContext();\n const cfg = this.options.client.getConfig();\n const timeoutMs = cfg.localizationTrackingTimeoutMs ?? DEFAULT_TRACKING_TIMEOUT_MS;\n\n return new Promise((resolve, reject) => {\n const startTime = Date.now();\n\n const tryFrame = (attempt: number, cameraAttemptsWithPose: number) => {\n session.requestAnimationFrame(async (_time: number, xrFrame: XRFrame) => {\n try {\n const elapsed = Date.now() - startTime;\n const viewerPose = xrFrame.getViewerPose(referenceSpace);\n if (!viewerPose) {\n if (elapsed >= timeoutMs || attempt + 1 >= TRACKING_FRAME_CAP) {\n const sec = (timeoutMs / 1000).toFixed(1);\n resolve({\n result: null,\n apiCalled: false,\n failureReason: `Tracking unavailable: no viewer pose within ${sec}s. Try moving the device or ensuring good lighting.`,\n });\n } else {\n tryFrame(attempt + 1, cameraAttemptsWithPose);\n }\n return;\n }\n\n const views = viewerPose.views as XRViewWithCamera[];\n for (let i = 0; i < views.length; i += 1) {\n const view = views[i];\n const xrCamera = view.camera;\n if (!xrCamera) continue;\n\n const gl2 = gl as unknown as WebGL2RenderingContext;\n const bindingCtor = XRWebGLBinding as unknown as {\n new(\n session: XRSession,\n context: WebGL2RenderingContext\n ): XRWebGLBindingLike;\n };\n const binding = new bindingCtor(session, gl2);\n const cameraTexture = binding.getCameraImage?.(xrCamera) ?? null;\n if (!cameraTexture) continue;\n\n const width = xrCamera.width;\n const height = xrCamera.height;\n if (!width || !height) continue;\n\n const frameData = await getCameraTextureAsImage(\n renderer,\n cameraTexture,\n width,\n height\n );\n\n const intrinsics = getCameraIntrinsics(view.projectionMatrix, {\n width,\n height,\n x: 0,\n y: 0,\n });\n\n if (frameData && intrinsics) {\n // Capture the camera pose from the current XRFrame's view transform\n // (column-major Float32Array, same convention as THREE.Matrix4.fromArray).\n // Using camera.matrix would give the previous render frame's pose.\n this.trackerSpace = new THREE.Matrix4().fromArray(view.transform.matrix);\n\n const result = await this.options.client.localizeWithFrame(\n frameData,\n intrinsics\n );\n resolve({ result, apiCalled: true });\n return;\n }\n }\n\n if (cameraAttemptsWithPose + 1 >= CAMERA_IMAGE_MAX_ATTEMPTS) {\n resolve({\n result: null,\n apiCalled: false,\n failureReason:\n 'Camera image not available. The device or browser may not support camera access in AR.',\n });\n } else {\n tryFrame(attempt + 1, cameraAttemptsWithPose + 1);\n }\n } catch (error) {\n reject(error);\n } finally {\n gl.bindFramebuffer(\n gl.FRAMEBUFFER,\n session.renderState.baseLayer?.framebuffer ?? null\n );\n }\n });\n };\n tryFrame(0, 0);\n });\n }\n\n dispose(): void {\n if (this.resizeHandler) {\n window.removeEventListener('resize', this.resizeHandler);\n }\n\n this.experience?.getRenderer().setAnimationLoop(null);\n this.experience?.dispose();\n this.experience = null;\n this.world?.dispose();\n this.world = null;\n this.trackingLossFrames = 0;\n this.hadTrackingLoss = false;\n\n if (this.arButton?.parentElement) {\n this.arButton.parentElement.removeChild(this.arButton);\n }\n this.arButton = null;\n }\n}\n"]}
@@ -220,7 +220,7 @@ void main() {
220
220
  `;
221
221
  function createGridMaterial(options = {}) {
222
222
  const color = options.color ?? "#7B2CBF";
223
- const opacity = options.opacity ?? 0.6;
223
+ const opacity = options.opacity ?? 150 / 255;
224
224
  const gridColor = options.gridColor ?? "#ffeb3b";
225
225
  const gridScale = options.gridScale ?? 2;
226
226
  const gridLineWidth = options.gridLineWidth ?? 0.02;
@@ -228,7 +228,7 @@ function createGridMaterial(options = {}) {
228
228
  const center = options.center ?? new THREE3.Vector3(0, 0, 0);
229
229
  const radius = options.radius ?? 1;
230
230
  const progress = options.progress ?? 1;
231
- const glowColor = options.glowColor ?? "#00ffff";
231
+ const glowColor = options.glowColor ?? "#FF3A00";
232
232
  const glowWidth = options.glowWidth ?? 0.05;
233
233
  const glowIntensity = options.glowIntensity ?? 2;
234
234
  const lightColor = options.lightColor ?? "#ffffff";
@@ -339,7 +339,7 @@ var MapMeshVisualizer = class {
339
339
  this.localRadius = Math.max(size / 2, 1e-3);
340
340
  const meshMaterial = createGridMaterial({
341
341
  color: "#7B2CBF",
342
- opacity: 0.4,
342
+ opacity: 0.58,
343
343
  gridColor: "#ffeb3b",
344
344
  gridScale: 2,
345
345
  gridLineWidth: 0.02,
@@ -347,7 +347,7 @@ var MapMeshVisualizer = class {
347
347
  center: this.localCenter.clone(),
348
348
  radius: this.localRadius,
349
349
  progress: 0,
350
- glowColor: "#00ffff",
350
+ glowColor: "#FF3A00",
351
351
  glowWidth: 0.05,
352
352
  glowIntensity: 2
353
353
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/webxr/internal/cameraIntrinsics.ts","../../src/lib/webxr/internal/frameCapture.ts","../../src/lib/webxr/experience/Experience.ts","../../src/lib/webxr/materials/gridMaterial.ts","../../src/lib/webxr/mapMeshVisualizer.ts","../../src/lib/webxr/world/World.ts","../../src/lib/webxr/controller.ts"],"names":["THREE","THREE2","THREE4"],"mappings":"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","file":"index.js","sourcesContent":["import type { ICameraIntrinsicsEvent } from '../../core';\n\nexport function getCameraIntrinsics(\n projectionMatrix: Float32Array,\n viewport: XRViewport\n): ICameraIntrinsicsEvent {\n const p = projectionMatrix;\n const u0 = ((1 - p[8]) * viewport.width) / 2 + viewport.x;\n const v0 = ((1 - p[9]) * viewport.height) / 2 + viewport.y;\n const ax = (viewport.width / 2) * p[0];\n const ay = (viewport.height / 2) * p[5];\n\n return {\n fx: ax,\n fy: ay,\n px: u0,\n py: v0,\n width: viewport.width,\n height: viewport.height,\n };\n}\n","import * as THREE from 'three';\nimport type { IFrameCaptureEvent } from '../../core';\n\nexport async function compressToJpeg(\n buffer: ArrayBuffer,\n width: number,\n height: number,\n quality = 0.8\n): Promise<Blob> {\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n if (!ctx) return new Blob();\n\n const imageData = new ImageData(new Uint8ClampedArray(buffer), width, height);\n ctx.putImageData(imageData, 0, 0);\n\n return new Promise((resolve) => {\n canvas.toBlob((blob) => resolve(blob ?? new Blob()), 'image/jpeg', quality);\n });\n}\n\nexport async function getCameraTextureAsImage(\n renderer: THREE.WebGLRenderer,\n webGLTexture: WebGLTexture,\n width: number,\n height: number\n): Promise<IFrameCaptureEvent | null> {\n const gl = renderer.getContext();\n if (!gl) return null;\n\n const framebuffer = gl.createFramebuffer();\n if (!framebuffer) return null;\n\n let pixelBuffer: Uint8Array;\n try {\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.TEXTURE_2D,\n webGLTexture,\n 0\n );\n\n pixelBuffer = new Uint8Array(width * height * 4);\n gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixelBuffer);\n } finally {\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.deleteFramebuffer(framebuffer);\n }\n\n const flippedData = new Uint8ClampedArray(pixelBuffer.length);\n for (let row = 0; row < height; row += 1) {\n const sourceStart = row * width * 4;\n const destStart = (height - row - 1) * width * 4;\n flippedData.set(\n pixelBuffer.subarray(sourceStart, sourceStart + width * 4),\n destStart\n );\n }\n\n const blob = await compressToJpeg(flippedData.buffer, width, height, 0.7);\n\n if (!blob.size) {\n return null;\n }\n\n return {\n blob,\n width,\n height,\n };\n}\n","import * as THREE from 'three';\n\n/**\n * Owns the Three.js scene, camera, and renderer for the AR session.\n * Handles resize and dispose; animation loop remains in the controller.\n */\nexport class Experience {\n private scene: THREE.Scene;\n private camera: THREE.PerspectiveCamera;\n private renderer: THREE.WebGLRenderer;\n\n constructor(canvas: HTMLCanvasElement) {\n this.renderer = new THREE.WebGLRenderer({\n canvas,\n antialias: true,\n alpha: true,\n });\n this.renderer.setSize(window.innerWidth, window.innerHeight);\n this.renderer.setPixelRatio(window.devicePixelRatio);\n this.renderer.xr.enabled = true;\n\n this.camera = new THREE.PerspectiveCamera(\n 45,\n window.innerWidth / window.innerHeight,\n 0.2,\n 10000\n );\n\n this.scene = new THREE.Scene();\n this.setupLights();\n }\n\n private setupLights(): void {\n const light = new THREE.HemisphereLight(0xffffff, 0xf8f0ff, 1);\n light.position.set(0.5, 2, 0.25);\n this.scene.add(light);\n\n const diLight = new THREE.DirectionalLight('#7B2CBF');\n diLight.position.set(0, 2, 0);\n this.scene.add(diLight);\n }\n\n getScene(): THREE.Scene {\n return this.scene;\n }\n\n getCamera(): THREE.PerspectiveCamera {\n return this.camera;\n }\n\n getRenderer(): THREE.WebGLRenderer {\n return this.renderer;\n }\n\n resize(): void {\n this.camera.aspect = window.innerWidth / window.innerHeight;\n this.camera.updateProjectionMatrix();\n this.renderer.setSize(window.innerWidth, window.innerHeight);\n }\n\n dispose(): void {\n this.renderer.dispose();\n (this as unknown as { scene: THREE.Scene | null }).scene = null;\n (this as unknown as { camera: THREE.PerspectiveCamera | null }).camera = null;\n (this as unknown as { renderer: THREE.WebGLRenderer | null }).renderer = null;\n }\n}\n","import * as THREE from 'three';\n\nconst VERTEX = `\nvarying vec3 vWorldPosition;\nvarying vec3 vWorldNormal;\n\nvoid main() {\n vec4 worldPos = modelMatrix * vec4(position, 1.0);\n vWorldPosition = worldPos.xyz;\n vWorldNormal = normalize(mat3(modelMatrix) * normal);\n\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n`;\n\nconst FRAGMENT = `\nuniform vec3 uColor;\nuniform float uOpacity;\n\nuniform vec3 uGridColor;\nuniform float uGridSize;\nuniform float uGridLineWidth;\nuniform float uShowGrid;\n\nuniform vec3 uCenter;\nuniform float uRadius;\nuniform float uProgress;\n\nuniform vec3 uGlowColor;\nuniform float uGlowWidth;\nuniform float uGlowIntensity;\n\nuniform vec3 uLightColor;\nuniform vec3 uLightDirection;\n\nvarying vec3 vWorldPosition;\nvarying vec3 vWorldNormal;\n\nfloat getGridFactor(vec3 worldPos, vec3 worldNormal, float gridSize, float lineWidth) {\n vec3 absNormal = abs(worldNormal);\n vec2 gridCoord;\n\n if (absNormal.y > absNormal.x && absNormal.y > absNormal.z) {\n gridCoord = worldPos.xz / gridSize;\n } else if (absNormal.x > absNormal.z) {\n gridCoord = worldPos.yz / gridSize;\n } else {\n gridCoord = worldPos.xy / gridSize;\n }\n\n vec2 gridFract = fract(abs(gridCoord));\n vec2 distToLine = min(gridFract, 1.0 - gridFract);\n float minDist = min(distToLine.x, distToLine.y);\n float gridFactor = 1.0 - smoothstep(0.0, lineWidth, minDist);\n\n return gridFactor;\n}\n\nvoid main() {\n vec3 baseColor = uColor;\n float baseAlpha = uOpacity;\n\n float distanceFromCenter = length(vWorldPosition - uCenter);\n float normalizedDistance = distanceFromCenter / max(uRadius, 0.001);\n float threshold = uProgress;\n\n if (threshold - normalizedDistance - 0.001 < 0.0) {\n discard;\n }\n\n float distanceFromEdge = threshold - normalizedDistance;\n\n float gridFactor = getGridFactor(vWorldPosition, normalize(vWorldNormal), uGridSize, uGridLineWidth);\n\n vec3 colorGridMixed = mix(baseColor, uGridColor, gridFactor * uShowGrid);\n float alphaGridMixed = max(baseAlpha, gridFactor * uShowGrid);\n\n float glowFactor = clamp(1.0 - clamp(distanceFromEdge / max(uGlowWidth, 0.001), 0.0, 1.0), 0.0, 1.0);\n glowFactor *= glowFactor;\n\n vec3 glowContribution = uGlowColor * glowFactor * uGlowIntensity;\n\n float alphaWithGlow = max(alphaGridMixed, glowFactor);\n alphaWithGlow = max(alphaWithGlow, 0.3);\n\n vec3 N = normalize(vWorldNormal);\n vec3 L = normalize(uLightDirection);\n float ndotl = max(0.3, dot(N, L));\n vec3 ambient = vec3(0.4);\n vec3 lighting = uLightColor * ndotl + ambient;\n\n vec3 litColor = colorGridMixed * lighting;\n vec3 finalColor = litColor + glowContribution * 0.5;\n\n gl_FragColor = vec4(finalColor, alphaWithGlow);\n}\n`;\n\nexport interface IGridMaterialOptions {\n color?: string | THREE.Color;\n opacity?: number;\n\n gridColor?: string | THREE.Color;\n gridScale?: number;\n gridLineWidth?: number;\n showGrid?: number;\n\n /** Center of radial effect (world space; can be updated after creation). */\n center?: THREE.Vector3;\n /** Max radius for radial progress (world units). */\n radius?: number;\n /** Progress 0–1; 1 = fully visible. */\n progress?: number;\n\n glowColor?: string | THREE.Color;\n glowWidth?: number;\n glowIntensity?: number;\n\n lightColor?: string | THREE.Color;\n /** Direction from surface toward light (world space). */\n lightDirection?: THREE.Vector3;\n}\n\n/**\n * Creates a ShaderMaterial with radial progress reveal, grid overlay, edge glow,\n * and simple directional lighting (Unity-style).\n */\nexport function createGridMaterial(\n options: IGridMaterialOptions = {}\n): THREE.ShaderMaterial {\n const color = options.color ?? '#7B2CBF';\n const opacity = options.opacity ?? 0.6;\n\n const gridColor = options.gridColor ?? '#ffeb3b';\n const gridScale = options.gridScale ?? 2.0;\n const gridLineWidth = options.gridLineWidth ?? 0.02;\n const showGrid = options.showGrid ?? 1.0;\n\n const center = options.center ?? new THREE.Vector3(0, 0, 0);\n const radius = options.radius ?? 1.0;\n const progress = options.progress ?? 1.0;\n\n const glowColor = options.glowColor ?? '#00ffff';\n const glowWidth = options.glowWidth ?? 0.05;\n const glowIntensity = options.glowIntensity ?? 2.0;\n\n const lightColor = options.lightColor ?? '#ffffff';\n const lightDirection =\n options.lightDirection ?? new THREE.Vector3(0.3, 1.0, 0.3).normalize();\n\n return new THREE.ShaderMaterial({\n vertexShader: VERTEX,\n fragmentShader: FRAGMENT,\n transparent: true,\n side: THREE.DoubleSide,\n uniforms: {\n uColor: { value: typeof color === 'string' ? new THREE.Color(color) : color },\n uOpacity: { value: opacity },\n\n uGridColor: {\n value: typeof gridColor === 'string' ? new THREE.Color(gridColor) : gridColor,\n },\n uGridSize: { value: gridScale },\n uGridLineWidth: { value: gridLineWidth },\n uShowGrid: { value: showGrid },\n\n uCenter: { value: center.clone() },\n uRadius: { value: radius },\n uProgress: { value: progress },\n\n uGlowColor: {\n value: typeof glowColor === 'string' ? new THREE.Color(glowColor) : glowColor,\n },\n uGlowWidth: { value: glowWidth },\n uGlowIntensity: { value: glowIntensity },\n\n uLightColor: {\n value: typeof lightColor === 'string' ? new THREE.Color(lightColor) : lightColor,\n },\n uLightDirection: { value: lightDirection.clone() },\n },\n });\n}\n","import * as THREE from 'three';\nimport type { MultisetClient, ILocalizeAndMapDetails } from '../core';\nimport type { IGetMapsDetailsResponse } from '../core';\nimport { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { TransformControls } from 'three/examples/jsm/controls/TransformControls.js';\nimport { createGridMaterial } from './materials/gridMaterial';\n\nconst LARGE_MAP_THRESHOLD = 50.0;\n\nexport class MapMeshVisualizer {\n private readonly meshGroup: THREE.Group;\n private readonly gltfLoader: GLTFLoader;\n private readonly dracoLoader: DRACOLoader;\n\n private gizmoControl: TransformControls | null = null;\n private gizmoHelper: THREE.Object3D | null = null;\n private meshMaterial: THREE.ShaderMaterial | null = null;\n private readonly localCenter = new THREE.Vector3();\n private localRadius = 0;\n private readonly radialDuration = 4.0; // seconds for full radial reveal\n private readonly radialRepeatInterval = 20.0; // seconds before replaying the effect\n private idleTimeAfterReveal = 0; // seconds since progress reached 1\n private readonly lastViewerWorldPosition = new THREE.Vector3();\n\n constructor(\n private readonly scene: THREE.Scene,\n private readonly client: MultisetClient,\n private readonly renderer: THREE.WebGLRenderer,\n private readonly camera: THREE.Camera\n ) {\n this.meshGroup = new THREE.Group();\n this.meshGroup.visible = false;\n this.scene.add(this.meshGroup);\n\n this.dracoLoader = new DRACOLoader();\n this.dracoLoader.setDecoderPath('/draco/');\n\n this.gltfLoader = new GLTFLoader();\n this.gltfLoader.setDRACOLoader(this.dracoLoader);\n }\n\n getMeshGroup(): THREE.Group {\n return this.meshGroup;\n }\n\n async ensureGizmoLoaded(): Promise<void> {\n const cfg = this.client.getConfig();\n if (cfg.showGizmo === false) {\n return;\n }\n if (!this.gizmoControl) {\n const gizmo = new TransformControls(this.camera, this.renderer.domElement);\n gizmo.setMode('translate');\n gizmo.setSpace('local');\n gizmo.enabled = false;\n const helper = gizmo.getHelper();\n this.scene.add(helper);\n gizmo.attach(this.meshGroup);\n this.gizmoControl = gizmo;\n this.gizmoHelper = helper;\n }\n this.gizmoHelper!.visible = true;\n }\n\n async ensureMeshLoaded(mapDetails: IGetMapsDetailsResponse): Promise<void> {\n if (this.scene.getObjectByName(mapDetails._id)) {\n return;\n }\n\n const meshKey = mapDetails.mapMesh?.rawMesh?.meshLink;\n if (!meshKey) {\n return;\n }\n\n const url = await this.client.downloadFile(meshKey);\n if (!url) {\n return;\n }\n\n await new Promise<void>((resolve, reject) => {\n this.gltfLoader.load(\n url,\n (gltf) => {\n const box = new THREE.Box3().setFromObject(gltf.scene);\n const sizeVec = box.getSize(new THREE.Vector3());\n let size = sizeVec.length();\n const center = box.getCenter(new THREE.Vector3());\n\n if (size > LARGE_MAP_THRESHOLD) {\n size = LARGE_MAP_THRESHOLD;\n }\n\n this.localCenter.copy(center);\n this.localRadius = Math.max(size / 2, 0.001);\n\n const meshMaterial = createGridMaterial({\n color: '#7B2CBF',\n opacity: 0.4,\n gridColor: '#ffeb3b',\n gridScale: 2.0,\n gridLineWidth: 0.02,\n showGrid: 1.0,\n center: this.localCenter.clone(),\n radius: this.localRadius,\n progress: 0.0,\n glowColor: '#00ffff',\n glowWidth: 0.05,\n glowIntensity: 2.0,\n });\n\n this.meshMaterial = meshMaterial;\n\n gltf.scene.traverse((child) => {\n if ((child as THREE.Mesh).isMesh) {\n (child as THREE.Mesh).material = meshMaterial;\n }\n });\n\n gltf.scene.name = mapDetails._id;\n this.meshGroup.add(gltf.scene);\n resolve();\n },\n undefined,\n (error) => {\n reject(error instanceof Error ? error : new Error(String(error)));\n }\n );\n });\n }\n\n applyMeshTransform(\n best: ILocalizeAndMapDetails,\n trackerSpace: THREE.Matrix4\n ): void {\n const pose = best.localizeData;\n\n const resPosition = new THREE.Vector3(\n pose.position.x,\n pose.position.y,\n pose.position.z\n );\n\n const resRotation = new THREE.Quaternion(\n pose.rotation.x,\n pose.rotation.y,\n pose.rotation.z,\n pose.rotation.w\n );\n\n const responseMatrix = new THREE.Matrix4();\n responseMatrix.compose(resPosition, resRotation, new THREE.Vector3(1, 1, 1));\n\n const inverseResponseMatrix = responseMatrix.clone().invert();\n\n const resultantMatrix = new THREE.Matrix4();\n resultantMatrix.multiplyMatrices(trackerSpace, inverseResponseMatrix);\n\n const position = new THREE.Vector3();\n const rotation = new THREE.Quaternion();\n const scale = new THREE.Vector3();\n resultantMatrix.decompose(position, rotation, scale);\n\n this.meshGroup.position.copy(position);\n this.meshGroup.quaternion.copy(rotation);\n this.meshGroup.scale.set(1, 1, 1);\n this.meshGroup.visible = true;\n this.meshGroup.updateMatrix();\n\n if (this.meshMaterial) {\n this.meshMaterial.uniforms.uCenter.value\n .copy(this.localCenter)\n .applyMatrix4(this.meshGroup.matrixWorld);\n }\n }\n\n update(\n deltaSeconds: number,\n viewerWorldPosition?: THREE.Vector3 | null\n ): void {\n if (!this.meshMaterial) {\n return;\n }\n\n if (viewerWorldPosition) {\n this.lastViewerWorldPosition.copy(viewerWorldPosition);\n }\n\n const uniforms = this.meshMaterial.uniforms as {\n uProgress?: { value: number };\n uCenter?: { value: THREE.Vector3 };\n };\n\n if (!uniforms.uProgress) {\n return;\n }\n\n const current = uniforms.uProgress.value ?? 0;\n\n if (current === 0 && uniforms.uCenter && this.lastViewerWorldPosition.lengthSq() > 0) {\n uniforms.uCenter.value.copy(this.lastViewerWorldPosition);\n }\n\n if (current >= 1) {\n this.idleTimeAfterReveal += deltaSeconds;\n if (this.idleTimeAfterReveal >= this.radialRepeatInterval) {\n uniforms.uProgress.value = 0;\n this.idleTimeAfterReveal = 0;\n }\n return;\n }\n\n this.idleTimeAfterReveal = 0;\n const next = Math.min(\n current + deltaSeconds / this.radialDuration,\n 1\n );\n\n uniforms.uProgress.value = next;\n }\n\n dispose(): void {\n this.meshMaterial = null;\n this.meshGroup.traverse((child) => {\n const mesh = child as THREE.Mesh;\n if (mesh.isMesh) {\n mesh.geometry.dispose();\n if (Array.isArray(mesh.material)) {\n mesh.material.forEach((m) => m.dispose());\n } else {\n (mesh.material as THREE.Material).dispose();\n }\n }\n });\n this.scene.remove(this.meshGroup);\n this.dracoLoader.dispose();\n if (this.gizmoHelper) {\n this.scene.remove(this.gizmoHelper);\n }\n if (this.gizmoControl) {\n this.gizmoControl.dispose();\n }\n }\n}\n\n","import * as THREE from 'three';\nimport type { MultisetClient, ILocalizeAndMapDetails } from '../../core';\nimport type { IGetMapsDetailsResponse } from '../../core';\nimport { MapMeshVisualizer } from '../mapMeshVisualizer';\n\n/**\n * Composes scene content for the AR session (e.g. map mesh).\n * Delegates to MapMeshVisualizer for mesh load and transform.\n */\nexport class World {\n private readonly meshVisualizer: MapMeshVisualizer;\n\n constructor(\n scene: THREE.Scene,\n client: MultisetClient,\n renderer: THREE.WebGLRenderer,\n camera: THREE.Camera\n ) {\n this.meshVisualizer = new MapMeshVisualizer(scene, client, renderer, camera);\n }\n\n async ensureGizmoLoaded(): Promise<void> {\n await this.meshVisualizer.ensureGizmoLoaded();\n }\n\n async ensureMeshLoaded(mapDetails: IGetMapsDetailsResponse): Promise<void> {\n await this.meshVisualizer.ensureMeshLoaded(mapDetails);\n }\n\n applyMeshTransform(\n best: ILocalizeAndMapDetails,\n trackerSpace: THREE.Matrix4\n ): void {\n this.meshVisualizer.applyMeshTransform(best, trackerSpace);\n }\n\n update(\n deltaSeconds: number,\n viewerWorldPosition?: THREE.Vector3 | null\n ): void {\n this.meshVisualizer.update(deltaSeconds, viewerWorldPosition);\n }\n\n dispose(): void {\n this.meshVisualizer.dispose();\n }\n}\n","import * as THREE from 'three';\nimport { ARButton } from 'three/examples/jsm/webxr/ARButton.js';\n\nimport type {\n MultisetClient,\n ILocalizeAndMapDetails,\n} from '../core';\nimport { getCameraIntrinsics } from './internal/cameraIntrinsics';\nimport { getCameraTextureAsImage } from './internal/frameCapture';\nimport { Experience } from './experience/Experience';\nimport { World } from './world/World';\nconst CONFIDENCE_THRESHOLD_MIN = 0.2;\nconst CONFIDENCE_THRESHOLD_MAX = 0.8;\nconst TRACKING_LOSS_FRAME_THRESHOLD = 60;\n/** Default max time (ms) to wait for a valid viewer pose before failing. */\nconst DEFAULT_TRACKING_TIMEOUT_MS = 10_000;\n/** Max XR frames to wait for viewer pose (backup cap; ~10s at 30fps). */\nconst TRACKING_FRAME_CAP = 300;\n/** Max frames with valid pose but no camera image before failing. */\nconst CAMERA_IMAGE_MAX_ATTEMPTS = 10;\n\n/**\n * Options for WebxrController. Property names align with Unity SingleFrameLocalizationManager\n * where applicable (see https://docs.multiset.ai/unity-sdk/api-reference/singleframelocalizationmanager).\n */\nexport interface IWebxrControllerOptions {\n client: MultisetClient;\n canvas?: HTMLCanvasElement;\n overlayRoot?: HTMLElement;\n buttonContainer?: HTMLElement;\n onARButtonCreated?: (button: HTMLButtonElement) => void;\n onSessionStart?: () => void;\n onSessionEnd?: () => void;\n}\n\ntype XRViewWithCamera = XRView & {\n camera?: {\n width: number;\n height: number;\n [key: string]: unknown;\n };\n};\n\ntype XRWebGLBindingLike = {\n getCameraImage: (camera: XRViewWithCamera['camera']) => WebGLTexture | null;\n};\n\nexport class WebxrController {\n private experience: Experience | null = null;\n private world: World | null = null;\n private arButton: HTMLButtonElement | null = null;\n private resizeHandler: (() => void) | null = null;\n private isSessionActive: boolean = false;\n private trackingLossFrames: number = 0;\n private hadTrackingLoss: boolean = false;\n private isLocalizing: boolean = false;\n private trackerSpace: THREE.Matrix4 | null = null;\n\n constructor(private readonly options: IWebxrControllerOptions) { }\n\n async initialize(buttonContainer?: HTMLElement): Promise<HTMLButtonElement> {\n if (this.experience) {\n return this.arButton!;\n }\n\n if (!window.isSecureContext) {\n throw new Error('WebXR requires a secure context (HTTPS).');\n }\n\n const canvas = this.options.canvas ?? document.createElement('canvas');\n\n this.experience = new Experience(canvas);\n const renderer = this.experience.getRenderer();\n const camera = this.experience.getCamera();\n const scene = this.experience.getScene();\n\n this.world = new World(scene, this.options.client, renderer, camera);\n\n renderer.xr.addEventListener('sessionstart', () => {\n this.isSessionActive = true;\n this.options.onSessionStart?.();\n const cfg = this.options.client.getConfig();\n if (cfg.autoLocalize) {\n const session = renderer.xr.getSession();\n if (session) {\n session.requestAnimationFrame(() => {\n void this.localizeFrame();\n });\n } else {\n void this.localizeFrame();\n }\n }\n });\n\n renderer.xr.addEventListener('sessionend', () => {\n this.isSessionActive = false;\n this.options.onSessionEnd?.();\n });\n\n let lastTime = 0;\n\n const animationLoop = (time: number, frame: XRFrame | null) => {\n const deltaSeconds = lastTime === 0 ? 0 : (time - lastTime) / 1000;\n lastTime = time;\n\n let viewerWorldPosition: THREE.Vector3 | null = null;\n if (frame) {\n const refSpace = renderer.xr.getReferenceSpace();\n if (refSpace) {\n const viewerPose = frame.getViewerPose(refSpace);\n if (viewerPose) {\n const p = viewerPose.transform.position;\n viewerWorldPosition = new THREE.Vector3(p.x, p.y, p.z);\n }\n }\n }\n\n if (this.world && deltaSeconds > 0) {\n this.world.update(deltaSeconds, viewerWorldPosition);\n }\n\n renderer.render(scene, camera);\n const cfg = this.options.client.getConfig();\n if (cfg.relocalization && frame && !this.isLocalizing) {\n const refSpace = renderer.xr.getReferenceSpace();\n if (refSpace) {\n const viewerPose = frame.getViewerPose(refSpace);\n if (!viewerPose) {\n this.trackingLossFrames += 1;\n if (this.trackingLossFrames >= TRACKING_LOSS_FRAME_THRESHOLD) {\n this.hadTrackingLoss = true;\n }\n } else {\n if (this.hadTrackingLoss) {\n this.hadTrackingLoss = false;\n this.trackingLossFrames = 0;\n void this.localizeFrame();\n } else {\n this.trackingLossFrames = 0;\n }\n }\n }\n }\n };\n renderer.setAnimationLoop(animationLoop);\n\n const resizeHandler = () => {\n this.experience?.resize();\n };\n window.addEventListener('resize', resizeHandler);\n\n const overlayRoot = this.options.overlayRoot ?? document.body;\n const arButton = ARButton.createButton(renderer, {\n requiredFeatures: ['camera-access', 'dom-overlay'],\n domOverlay: { root: overlayRoot },\n }) as HTMLButtonElement;\n\n const buttonParent =\n buttonContainer && buttonContainer instanceof HTMLElement\n ? buttonContainer\n : this.options.buttonContainer &&\n this.options.buttonContainer instanceof HTMLElement\n ? this.options.buttonContainer\n : overlayRoot;\n\n if (!buttonParent.contains(arButton)) {\n buttonParent.appendChild(arButton);\n }\n\n this.arButton = arButton;\n this.resizeHandler = resizeHandler;\n\n this.options.onARButtonCreated?.(arButton);\n return arButton;\n }\n\n getScene(): THREE.Scene {\n if (!this.experience) {\n throw new Error('Scene: WebXR controller has not been initialized.');\n }\n return this.experience.getScene();\n }\n\n getCamera(): THREE.PerspectiveCamera {\n if (!this.experience) {\n throw new Error('Camera: WebXR controller has not been initialized.');\n }\n return this.experience.getCamera();\n }\n\n getRenderer(): THREE.WebGLRenderer {\n if (!this.experience) {\n throw new Error('Renderer: WebXR controller has not been initialized.');\n }\n return this.experience.getRenderer();\n }\n\n hasActiveSession(): boolean {\n return this.isSessionActive && this.experience?.getRenderer().xr.isPresenting === true;\n }\n\n /**\n * Runs a single-frame localization: captures one frame, evaluates the result\n * against the optional confidenceThreshold, and fires\n * onLocalizationInit / onLocalizationSuccess / onLocalizationFailure.\n * Aligns with Unity SingleFrameLocalizationManager.LocalizeFrame().\n */\n async localizeFrame(): Promise<ILocalizeAndMapDetails | null> {\n if (!this.experience) {\n throw new Error('WebXR: WebXR controller has not been initialized.');\n }\n const renderer = this.experience.getRenderer();\n const session = renderer.xr.getSession?.();\n if (!session) {\n throw new Error(\n 'WebXR Session: No active WebXR session. Start AR before calling localizeFrame().'\n );\n }\n\n const cfg = this.options.client.getConfig();\n const confidenceCheck = cfg.confidenceCheck ?? false;\n const confidenceThreshold = Math.max(\n CONFIDENCE_THRESHOLD_MIN,\n Math.min(cfg.confidenceThreshold ?? 0.5, CONFIDENCE_THRESHOLD_MAX)\n );\n\n cfg.onLocalizationInit?.();\n this.isLocalizing = true;\n\n let best: ILocalizeAndMapDetails | null = null;\n\n let failureReason: string | undefined;\n try {\n const captureResult = await this.captureFrame();\n best = captureResult.result;\n failureReason = captureResult.failureReason;\n } finally {\n this.isLocalizing = false;\n }\n\n const accepted =\n best &&\n (!confidenceCheck ||\n (best.localizeData.confidence ?? 0) >= confidenceThreshold);\n\n if (accepted && best) {\n cfg.onLocalizationSuccess?.(best);\n\n if (this.world && this.trackerSpace) {\n const willShowMesh = cfg.showMesh && !!best.mapDetails;\n const willShowGizmo = cfg.showGizmo !== false;\n if (willShowMesh || willShowGizmo) {\n try {\n await this.world.ensureGizmoLoaded();\n if (willShowMesh) {\n await this.world.ensureMeshLoaded(best.mapDetails!);\n }\n this.world.applyMeshTransform(best, this.trackerSpace);\n } catch {\n // Mesh/gizmo loading failure must not prevent returning the localization result\n }\n }\n }\n return best;\n }\n\n const reason =\n failureReason ??\n (!best\n ? 'All attempts failed to produce a pose.'\n : confidenceCheck\n ? `Best confidence ${best.localizeData.confidence ?? 0} below threshold ${confidenceThreshold}.`\n : undefined);\n cfg.onLocalizationFailure?.(reason);\n return null;\n }\n\n /**\n * Internal: captures one frame and calls the localization API. Waits for a\n * valid viewer pose up to localizationTrackingTimeoutMs (and TRACKING_FRAME_CAP),\n * then tries to get a camera image (up to CAMERA_IMAGE_MAX_ATTEMPTS). Returns\n * result, apiCalled, and an optional failureReason for onLocalizationFailure.\n */\n private async captureFrame(): Promise<{\n result: ILocalizeAndMapDetails | null;\n apiCalled: boolean;\n failureReason?: string;\n }> {\n if (!this.experience) {\n throw new Error('WebXR: WebXR controller has not been initialized.');\n }\n const renderer = this.experience.getRenderer();\n\n const session = renderer.xr.getSession?.();\n if (!session) {\n throw new Error(\n 'WebXR Session: No active WebXR session. Start AR before capturing.'\n );\n }\n\n const referenceSpace = renderer.xr.getReferenceSpace();\n if (!referenceSpace) {\n throw new Error(\n 'WebXR Reference Space: Unable to acquire XR reference space.'\n );\n }\n\n const gl = renderer.getContext();\n const cfg = this.options.client.getConfig();\n const timeoutMs = cfg.localizationTrackingTimeoutMs ?? DEFAULT_TRACKING_TIMEOUT_MS;\n\n return new Promise((resolve, reject) => {\n const startTime = Date.now();\n\n const tryFrame = (attempt: number, cameraAttemptsWithPose: number) => {\n session.requestAnimationFrame(async (_time: number, xrFrame: XRFrame) => {\n try {\n const elapsed = Date.now() - startTime;\n const viewerPose = xrFrame.getViewerPose(referenceSpace);\n if (!viewerPose) {\n if (elapsed >= timeoutMs || attempt + 1 >= TRACKING_FRAME_CAP) {\n const sec = (timeoutMs / 1000).toFixed(1);\n resolve({\n result: null,\n apiCalled: false,\n failureReason: `Tracking unavailable: no viewer pose within ${sec}s. Try moving the device or ensuring good lighting.`,\n });\n } else {\n tryFrame(attempt + 1, cameraAttemptsWithPose);\n }\n return;\n }\n\n const views = viewerPose.views as XRViewWithCamera[];\n for (let i = 0; i < views.length; i += 1) {\n const view = views[i];\n const xrCamera = view.camera;\n if (!xrCamera) continue;\n\n const gl2 = gl as unknown as WebGL2RenderingContext;\n const bindingCtor = XRWebGLBinding as unknown as {\n new(\n session: XRSession,\n context: WebGL2RenderingContext\n ): XRWebGLBindingLike;\n };\n const binding = new bindingCtor(session, gl2);\n const cameraTexture = binding.getCameraImage?.(xrCamera) ?? null;\n if (!cameraTexture) continue;\n\n const width = xrCamera.width;\n const height = xrCamera.height;\n if (!width || !height) continue;\n\n const frameData = await getCameraTextureAsImage(\n renderer,\n cameraTexture,\n width,\n height\n );\n\n const intrinsics = getCameraIntrinsics(view.projectionMatrix, {\n width,\n height,\n x: 0,\n y: 0,\n });\n\n if (frameData && intrinsics) {\n // Capture the camera pose from the current XRFrame's view transform\n // (column-major Float32Array, same convention as THREE.Matrix4.fromArray).\n // Using camera.matrix would give the previous render frame's pose.\n this.trackerSpace = new THREE.Matrix4().fromArray(view.transform.matrix);\n\n const result = await this.options.client.localizeWithFrame(\n frameData,\n intrinsics\n );\n resolve({ result, apiCalled: true });\n return;\n }\n }\n\n if (cameraAttemptsWithPose + 1 >= CAMERA_IMAGE_MAX_ATTEMPTS) {\n resolve({\n result: null,\n apiCalled: false,\n failureReason:\n 'Camera image not available. The device or browser may not support camera access in AR.',\n });\n } else {\n tryFrame(attempt + 1, cameraAttemptsWithPose + 1);\n }\n } catch (error) {\n reject(error);\n } finally {\n gl.bindFramebuffer(\n gl.FRAMEBUFFER,\n session.renderState.baseLayer?.framebuffer ?? null\n );\n }\n });\n };\n tryFrame(0, 0);\n });\n }\n\n dispose(): void {\n if (this.resizeHandler) {\n window.removeEventListener('resize', this.resizeHandler);\n }\n\n this.experience?.getRenderer().setAnimationLoop(null);\n this.experience?.dispose();\n this.experience = null;\n this.world?.dispose();\n this.world = null;\n this.trackingLossFrames = 0;\n this.hadTrackingLoss = false;\n\n if (this.arButton?.parentElement) {\n this.arButton.parentElement.removeChild(this.arButton);\n }\n this.arButton = null;\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/lib/webxr/internal/cameraIntrinsics.ts","../../src/lib/webxr/internal/frameCapture.ts","../../src/lib/webxr/experience/Experience.ts","../../src/lib/webxr/materials/gridMaterial.ts","../../src/lib/webxr/mapMeshVisualizer.ts","../../src/lib/webxr/world/World.ts","../../src/lib/webxr/controller.ts"],"names":["THREE","THREE2","THREE4"],"mappings":"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","file":"index.js","sourcesContent":["import type { ICameraIntrinsicsEvent } from '../../core';\n\nexport function getCameraIntrinsics(\n projectionMatrix: Float32Array,\n viewport: XRViewport\n): ICameraIntrinsicsEvent {\n const p = projectionMatrix;\n const u0 = ((1 - p[8]) * viewport.width) / 2 + viewport.x;\n const v0 = ((1 - p[9]) * viewport.height) / 2 + viewport.y;\n const ax = (viewport.width / 2) * p[0];\n const ay = (viewport.height / 2) * p[5];\n\n return {\n fx: ax,\n fy: ay,\n px: u0,\n py: v0,\n width: viewport.width,\n height: viewport.height,\n };\n}\n","import * as THREE from 'three';\nimport type { IFrameCaptureEvent } from '../../core';\n\nexport async function compressToJpeg(\n buffer: ArrayBuffer,\n width: number,\n height: number,\n quality = 0.8\n): Promise<Blob> {\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n if (!ctx) return new Blob();\n\n const imageData = new ImageData(new Uint8ClampedArray(buffer), width, height);\n ctx.putImageData(imageData, 0, 0);\n\n return new Promise((resolve) => {\n canvas.toBlob((blob) => resolve(blob ?? new Blob()), 'image/jpeg', quality);\n });\n}\n\nexport async function getCameraTextureAsImage(\n renderer: THREE.WebGLRenderer,\n webGLTexture: WebGLTexture,\n width: number,\n height: number\n): Promise<IFrameCaptureEvent | null> {\n const gl = renderer.getContext();\n if (!gl) return null;\n\n const framebuffer = gl.createFramebuffer();\n if (!framebuffer) return null;\n\n let pixelBuffer: Uint8Array;\n try {\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.TEXTURE_2D,\n webGLTexture,\n 0\n );\n\n pixelBuffer = new Uint8Array(width * height * 4);\n gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixelBuffer);\n } finally {\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.deleteFramebuffer(framebuffer);\n }\n\n const flippedData = new Uint8ClampedArray(pixelBuffer.length);\n for (let row = 0; row < height; row += 1) {\n const sourceStart = row * width * 4;\n const destStart = (height - row - 1) * width * 4;\n flippedData.set(\n pixelBuffer.subarray(sourceStart, sourceStart + width * 4),\n destStart\n );\n }\n\n const blob = await compressToJpeg(flippedData.buffer, width, height, 0.7);\n\n if (!blob.size) {\n return null;\n }\n\n return {\n blob,\n width,\n height,\n };\n}\n","import * as THREE from 'three';\n\n/**\n * Owns the Three.js scene, camera, and renderer for the AR session.\n * Handles resize and dispose; animation loop remains in the controller.\n */\nexport class Experience {\n private scene: THREE.Scene;\n private camera: THREE.PerspectiveCamera;\n private renderer: THREE.WebGLRenderer;\n\n constructor(canvas: HTMLCanvasElement) {\n this.renderer = new THREE.WebGLRenderer({\n canvas,\n antialias: true,\n alpha: true,\n });\n this.renderer.setSize(window.innerWidth, window.innerHeight);\n this.renderer.setPixelRatio(window.devicePixelRatio);\n this.renderer.xr.enabled = true;\n\n this.camera = new THREE.PerspectiveCamera(\n 45,\n window.innerWidth / window.innerHeight,\n 0.2,\n 10000\n );\n\n this.scene = new THREE.Scene();\n this.setupLights();\n }\n\n private setupLights(): void {\n const light = new THREE.HemisphereLight(0xffffff, 0xf8f0ff, 1);\n light.position.set(0.5, 2, 0.25);\n this.scene.add(light);\n\n const diLight = new THREE.DirectionalLight('#7B2CBF');\n diLight.position.set(0, 2, 0);\n this.scene.add(diLight);\n }\n\n getScene(): THREE.Scene {\n return this.scene;\n }\n\n getCamera(): THREE.PerspectiveCamera {\n return this.camera;\n }\n\n getRenderer(): THREE.WebGLRenderer {\n return this.renderer;\n }\n\n resize(): void {\n this.camera.aspect = window.innerWidth / window.innerHeight;\n this.camera.updateProjectionMatrix();\n this.renderer.setSize(window.innerWidth, window.innerHeight);\n }\n\n dispose(): void {\n this.renderer.dispose();\n (this as unknown as { scene: THREE.Scene | null }).scene = null;\n (this as unknown as { camera: THREE.PerspectiveCamera | null }).camera = null;\n (this as unknown as { renderer: THREE.WebGLRenderer | null }).renderer = null;\n }\n}\n","import * as THREE from 'three';\n\nconst VERTEX = `\nvarying vec3 vWorldPosition;\nvarying vec3 vWorldNormal;\n\nvoid main() {\n vec4 worldPos = modelMatrix * vec4(position, 1.0);\n vWorldPosition = worldPos.xyz;\n vWorldNormal = normalize(mat3(modelMatrix) * normal);\n\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n`;\n\nconst FRAGMENT = `\nuniform vec3 uColor;\nuniform float uOpacity;\n\nuniform vec3 uGridColor;\nuniform float uGridSize;\nuniform float uGridLineWidth;\nuniform float uShowGrid;\n\nuniform vec3 uCenter;\nuniform float uRadius;\nuniform float uProgress;\n\nuniform vec3 uGlowColor;\nuniform float uGlowWidth;\nuniform float uGlowIntensity;\n\nuniform vec3 uLightColor;\nuniform vec3 uLightDirection;\n\nvarying vec3 vWorldPosition;\nvarying vec3 vWorldNormal;\n\nfloat getGridFactor(vec3 worldPos, vec3 worldNormal, float gridSize, float lineWidth) {\n vec3 absNormal = abs(worldNormal);\n vec2 gridCoord;\n\n if (absNormal.y > absNormal.x && absNormal.y > absNormal.z) {\n gridCoord = worldPos.xz / gridSize;\n } else if (absNormal.x > absNormal.z) {\n gridCoord = worldPos.yz / gridSize;\n } else {\n gridCoord = worldPos.xy / gridSize;\n }\n\n vec2 gridFract = fract(abs(gridCoord));\n vec2 distToLine = min(gridFract, 1.0 - gridFract);\n float minDist = min(distToLine.x, distToLine.y);\n float gridFactor = 1.0 - smoothstep(0.0, lineWidth, minDist);\n\n return gridFactor;\n}\n\nvoid main() {\n vec3 baseColor = uColor;\n float baseAlpha = uOpacity;\n\n float distanceFromCenter = length(vWorldPosition - uCenter);\n float normalizedDistance = distanceFromCenter / max(uRadius, 0.001);\n float threshold = uProgress;\n\n if (threshold - normalizedDistance - 0.001 < 0.0) {\n discard;\n }\n\n float distanceFromEdge = threshold - normalizedDistance;\n\n float gridFactor = getGridFactor(vWorldPosition, normalize(vWorldNormal), uGridSize, uGridLineWidth);\n\n vec3 colorGridMixed = mix(baseColor, uGridColor, gridFactor * uShowGrid);\n float alphaGridMixed = max(baseAlpha, gridFactor * uShowGrid);\n\n float glowFactor = clamp(1.0 - clamp(distanceFromEdge / max(uGlowWidth, 0.001), 0.0, 1.0), 0.0, 1.0);\n glowFactor *= glowFactor;\n\n vec3 glowContribution = uGlowColor * glowFactor * uGlowIntensity;\n\n float alphaWithGlow = max(alphaGridMixed, glowFactor);\n alphaWithGlow = max(alphaWithGlow, 0.3);\n\n vec3 N = normalize(vWorldNormal);\n vec3 L = normalize(uLightDirection);\n float ndotl = max(0.3, dot(N, L));\n vec3 ambient = vec3(0.4);\n vec3 lighting = uLightColor * ndotl + ambient;\n\n vec3 litColor = colorGridMixed * lighting;\n vec3 finalColor = litColor + glowContribution * 0.5;\n\n gl_FragColor = vec4(finalColor, alphaWithGlow);\n}\n`;\n\nexport interface IGridMaterialOptions {\n color?: string | THREE.Color;\n opacity?: number;\n\n gridColor?: string | THREE.Color;\n gridScale?: number;\n gridLineWidth?: number;\n showGrid?: number;\n\n /** Center of radial effect (world space; can be updated after creation). */\n center?: THREE.Vector3;\n /** Max radius for radial progress (world units). */\n radius?: number;\n /** Progress 0–1; 1 = fully visible. */\n progress?: number;\n\n glowColor?: string | THREE.Color;\n glowWidth?: number;\n glowIntensity?: number;\n\n lightColor?: string | THREE.Color;\n /** Direction from surface toward light (world space). */\n lightDirection?: THREE.Vector3;\n}\n\n/**\n * Creates a ShaderMaterial with radial progress reveal, grid overlay, edge glow,\n * and simple directional lighting (Unity-style).\n */\nexport function createGridMaterial(\n options: IGridMaterialOptions = {}\n): THREE.ShaderMaterial {\n const color = options.color ?? '#7B2CBF';\n const opacity = options.opacity ?? (150 / 255);\n\n const gridColor = options.gridColor ?? '#ffeb3b';\n const gridScale = options.gridScale ?? 2.0;\n const gridLineWidth = options.gridLineWidth ?? 0.02;\n const showGrid = options.showGrid ?? 1.0;\n\n const center = options.center ?? new THREE.Vector3(0, 0, 0);\n const radius = options.radius ?? 1.0;\n const progress = options.progress ?? 1.0;\n\n const glowColor = options.glowColor ?? '#FF3A00';\n const glowWidth = options.glowWidth ?? 0.05;\n const glowIntensity = options.glowIntensity ?? 2.0;\n\n const lightColor = options.lightColor ?? '#ffffff';\n const lightDirection =\n options.lightDirection ?? new THREE.Vector3(0.3, 1.0, 0.3).normalize();\n\n return new THREE.ShaderMaterial({\n vertexShader: VERTEX,\n fragmentShader: FRAGMENT,\n transparent: true,\n side: THREE.DoubleSide,\n uniforms: {\n uColor: { value: typeof color === 'string' ? new THREE.Color(color) : color },\n uOpacity: { value: opacity },\n\n uGridColor: {\n value: typeof gridColor === 'string' ? new THREE.Color(gridColor) : gridColor,\n },\n uGridSize: { value: gridScale },\n uGridLineWidth: { value: gridLineWidth },\n uShowGrid: { value: showGrid },\n\n uCenter: { value: center.clone() },\n uRadius: { value: radius },\n uProgress: { value: progress },\n\n uGlowColor: {\n value: typeof glowColor === 'string' ? new THREE.Color(glowColor) : glowColor,\n },\n uGlowWidth: { value: glowWidth },\n uGlowIntensity: { value: glowIntensity },\n\n uLightColor: {\n value: typeof lightColor === 'string' ? new THREE.Color(lightColor) : lightColor,\n },\n uLightDirection: { value: lightDirection.clone() },\n },\n });\n}\n","import * as THREE from 'three';\nimport type { MultisetClient, ILocalizeAndMapDetails } from '../core';\nimport type { IGetMapsDetailsResponse } from '../core';\nimport { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { TransformControls } from 'three/examples/jsm/controls/TransformControls.js';\nimport { createGridMaterial } from './materials/gridMaterial';\n\nconst LARGE_MAP_THRESHOLD = 50.0;\n\nexport class MapMeshVisualizer {\n private readonly meshGroup: THREE.Group;\n private readonly gltfLoader: GLTFLoader;\n private readonly dracoLoader: DRACOLoader;\n\n private gizmoControl: TransformControls | null = null;\n private gizmoHelper: THREE.Object3D | null = null;\n private meshMaterial: THREE.ShaderMaterial | null = null;\n private readonly localCenter = new THREE.Vector3();\n private localRadius = 0;\n private readonly radialDuration = 4.0; // seconds for full radial reveal\n private readonly radialRepeatInterval = 20.0; // seconds before replaying the effect\n private idleTimeAfterReveal = 0; // seconds since progress reached 1\n private readonly lastViewerWorldPosition = new THREE.Vector3();\n\n constructor(\n private readonly scene: THREE.Scene,\n private readonly client: MultisetClient,\n private readonly renderer: THREE.WebGLRenderer,\n private readonly camera: THREE.Camera\n ) {\n this.meshGroup = new THREE.Group();\n this.meshGroup.visible = false;\n this.scene.add(this.meshGroup);\n\n this.dracoLoader = new DRACOLoader();\n this.dracoLoader.setDecoderPath('/draco/');\n\n this.gltfLoader = new GLTFLoader();\n this.gltfLoader.setDRACOLoader(this.dracoLoader);\n }\n\n getMeshGroup(): THREE.Group {\n return this.meshGroup;\n }\n\n async ensureGizmoLoaded(): Promise<void> {\n const cfg = this.client.getConfig();\n if (cfg.showGizmo === false) {\n return;\n }\n if (!this.gizmoControl) {\n const gizmo = new TransformControls(this.camera, this.renderer.domElement);\n gizmo.setMode('translate');\n gizmo.setSpace('local');\n gizmo.enabled = false;\n const helper = gizmo.getHelper();\n this.scene.add(helper);\n gizmo.attach(this.meshGroup);\n this.gizmoControl = gizmo;\n this.gizmoHelper = helper;\n }\n this.gizmoHelper!.visible = true;\n }\n\n async ensureMeshLoaded(mapDetails: IGetMapsDetailsResponse): Promise<void> {\n if (this.scene.getObjectByName(mapDetails._id)) {\n return;\n }\n\n const meshKey = mapDetails.mapMesh?.rawMesh?.meshLink;\n if (!meshKey) {\n return;\n }\n\n const url = await this.client.downloadFile(meshKey);\n if (!url) {\n return;\n }\n\n await new Promise<void>((resolve, reject) => {\n this.gltfLoader.load(\n url,\n (gltf) => {\n const box = new THREE.Box3().setFromObject(gltf.scene);\n const sizeVec = box.getSize(new THREE.Vector3());\n let size = sizeVec.length();\n const center = box.getCenter(new THREE.Vector3());\n\n if (size > LARGE_MAP_THRESHOLD) {\n size = LARGE_MAP_THRESHOLD;\n }\n\n this.localCenter.copy(center);\n this.localRadius = Math.max(size / 2, 0.001);\n\n const meshMaterial = createGridMaterial({\n color: '#7B2CBF',\n opacity: 0.58,\n gridColor: '#ffeb3b',\n gridScale: 2.0,\n gridLineWidth: 0.02,\n showGrid: 1.0,\n center: this.localCenter.clone(),\n radius: this.localRadius,\n progress: 0.0,\n glowColor: '#FF3A00',\n glowWidth: 0.05,\n glowIntensity: 2.0,\n });\n\n this.meshMaterial = meshMaterial;\n\n gltf.scene.traverse((child) => {\n if ((child as THREE.Mesh).isMesh) {\n (child as THREE.Mesh).material = meshMaterial;\n }\n });\n\n gltf.scene.name = mapDetails._id;\n this.meshGroup.add(gltf.scene);\n resolve();\n },\n undefined,\n (error) => {\n reject(error instanceof Error ? error : new Error(String(error)));\n }\n );\n });\n }\n\n applyMeshTransform(\n best: ILocalizeAndMapDetails,\n trackerSpace: THREE.Matrix4\n ): void {\n const pose = best.localizeData;\n\n const resPosition = new THREE.Vector3(\n pose.position.x,\n pose.position.y,\n pose.position.z\n );\n\n const resRotation = new THREE.Quaternion(\n pose.rotation.x,\n pose.rotation.y,\n pose.rotation.z,\n pose.rotation.w\n );\n\n const responseMatrix = new THREE.Matrix4();\n responseMatrix.compose(resPosition, resRotation, new THREE.Vector3(1, 1, 1));\n\n const inverseResponseMatrix = responseMatrix.clone().invert();\n\n const resultantMatrix = new THREE.Matrix4();\n resultantMatrix.multiplyMatrices(trackerSpace, inverseResponseMatrix);\n\n const position = new THREE.Vector3();\n const rotation = new THREE.Quaternion();\n const scale = new THREE.Vector3();\n resultantMatrix.decompose(position, rotation, scale);\n\n this.meshGroup.position.copy(position);\n this.meshGroup.quaternion.copy(rotation);\n this.meshGroup.scale.set(1, 1, 1);\n this.meshGroup.visible = true;\n this.meshGroup.updateMatrix();\n\n if (this.meshMaterial) {\n this.meshMaterial.uniforms.uCenter.value\n .copy(this.localCenter)\n .applyMatrix4(this.meshGroup.matrixWorld);\n }\n }\n\n update(\n deltaSeconds: number,\n viewerWorldPosition?: THREE.Vector3 | null\n ): void {\n if (!this.meshMaterial) {\n return;\n }\n\n if (viewerWorldPosition) {\n this.lastViewerWorldPosition.copy(viewerWorldPosition);\n }\n\n const uniforms = this.meshMaterial.uniforms as {\n uProgress?: { value: number };\n uCenter?: { value: THREE.Vector3 };\n };\n\n if (!uniforms.uProgress) {\n return;\n }\n\n const current = uniforms.uProgress.value ?? 0;\n\n if (current === 0 && uniforms.uCenter && this.lastViewerWorldPosition.lengthSq() > 0) {\n uniforms.uCenter.value.copy(this.lastViewerWorldPosition);\n }\n\n if (current >= 1) {\n this.idleTimeAfterReveal += deltaSeconds;\n if (this.idleTimeAfterReveal >= this.radialRepeatInterval) {\n uniforms.uProgress.value = 0;\n this.idleTimeAfterReveal = 0;\n }\n return;\n }\n\n this.idleTimeAfterReveal = 0;\n const next = Math.min(\n current + deltaSeconds / this.radialDuration,\n 1\n );\n\n uniforms.uProgress.value = next;\n }\n\n dispose(): void {\n this.meshMaterial = null;\n this.meshGroup.traverse((child) => {\n const mesh = child as THREE.Mesh;\n if (mesh.isMesh) {\n mesh.geometry.dispose();\n if (Array.isArray(mesh.material)) {\n mesh.material.forEach((m) => m.dispose());\n } else {\n (mesh.material as THREE.Material).dispose();\n }\n }\n });\n this.scene.remove(this.meshGroup);\n this.dracoLoader.dispose();\n if (this.gizmoHelper) {\n this.scene.remove(this.gizmoHelper);\n }\n if (this.gizmoControl) {\n this.gizmoControl.dispose();\n }\n }\n}\n\n","import * as THREE from 'three';\nimport type { MultisetClient, ILocalizeAndMapDetails } from '../../core';\nimport type { IGetMapsDetailsResponse } from '../../core';\nimport { MapMeshVisualizer } from '../mapMeshVisualizer';\n\n/**\n * Composes scene content for the AR session (e.g. map mesh).\n * Delegates to MapMeshVisualizer for mesh load and transform.\n */\nexport class World {\n private readonly meshVisualizer: MapMeshVisualizer;\n\n constructor(\n scene: THREE.Scene,\n client: MultisetClient,\n renderer: THREE.WebGLRenderer,\n camera: THREE.Camera\n ) {\n this.meshVisualizer = new MapMeshVisualizer(scene, client, renderer, camera);\n }\n\n async ensureGizmoLoaded(): Promise<void> {\n await this.meshVisualizer.ensureGizmoLoaded();\n }\n\n async ensureMeshLoaded(mapDetails: IGetMapsDetailsResponse): Promise<void> {\n await this.meshVisualizer.ensureMeshLoaded(mapDetails);\n }\n\n applyMeshTransform(\n best: ILocalizeAndMapDetails,\n trackerSpace: THREE.Matrix4\n ): void {\n this.meshVisualizer.applyMeshTransform(best, trackerSpace);\n }\n\n update(\n deltaSeconds: number,\n viewerWorldPosition?: THREE.Vector3 | null\n ): void {\n this.meshVisualizer.update(deltaSeconds, viewerWorldPosition);\n }\n\n dispose(): void {\n this.meshVisualizer.dispose();\n }\n}\n","import * as THREE from 'three';\nimport { ARButton } from 'three/examples/jsm/webxr/ARButton.js';\n\nimport type {\n MultisetClient,\n ILocalizeAndMapDetails,\n} from '../core';\nimport { getCameraIntrinsics } from './internal/cameraIntrinsics';\nimport { getCameraTextureAsImage } from './internal/frameCapture';\nimport { Experience } from './experience/Experience';\nimport { World } from './world/World';\nconst CONFIDENCE_THRESHOLD_MIN = 0.2;\nconst CONFIDENCE_THRESHOLD_MAX = 0.8;\nconst TRACKING_LOSS_FRAME_THRESHOLD = 60;\n/** Default max time (ms) to wait for a valid viewer pose before failing. */\nconst DEFAULT_TRACKING_TIMEOUT_MS = 10_000;\n/** Max XR frames to wait for viewer pose (backup cap; ~10s at 30fps). */\nconst TRACKING_FRAME_CAP = 300;\n/** Max frames with valid pose but no camera image before failing. */\nconst CAMERA_IMAGE_MAX_ATTEMPTS = 10;\n\n/**\n * Options for WebxrController. Property names align with Unity SingleFrameLocalizationManager\n * where applicable (see https://docs.multiset.ai/unity-sdk/api-reference/singleframelocalizationmanager).\n */\nexport interface IWebxrControllerOptions {\n client: MultisetClient;\n canvas?: HTMLCanvasElement;\n overlayRoot?: HTMLElement;\n buttonContainer?: HTMLElement;\n onARButtonCreated?: (button: HTMLButtonElement) => void;\n onSessionStart?: () => void;\n onSessionEnd?: () => void;\n}\n\ntype XRViewWithCamera = XRView & {\n camera?: {\n width: number;\n height: number;\n [key: string]: unknown;\n };\n};\n\ntype XRWebGLBindingLike = {\n getCameraImage: (camera: XRViewWithCamera['camera']) => WebGLTexture | null;\n};\n\nexport class WebxrController {\n private experience: Experience | null = null;\n private world: World | null = null;\n private arButton: HTMLButtonElement | null = null;\n private resizeHandler: (() => void) | null = null;\n private isSessionActive: boolean = false;\n private trackingLossFrames: number = 0;\n private hadTrackingLoss: boolean = false;\n private isLocalizing: boolean = false;\n private trackerSpace: THREE.Matrix4 | null = null;\n\n constructor(private readonly options: IWebxrControllerOptions) { }\n\n async initialize(buttonContainer?: HTMLElement): Promise<HTMLButtonElement> {\n if (this.experience) {\n return this.arButton!;\n }\n\n if (!window.isSecureContext) {\n throw new Error('WebXR requires a secure context (HTTPS).');\n }\n\n const canvas = this.options.canvas ?? document.createElement('canvas');\n\n this.experience = new Experience(canvas);\n const renderer = this.experience.getRenderer();\n const camera = this.experience.getCamera();\n const scene = this.experience.getScene();\n\n this.world = new World(scene, this.options.client, renderer, camera);\n\n renderer.xr.addEventListener('sessionstart', () => {\n this.isSessionActive = true;\n this.options.onSessionStart?.();\n const cfg = this.options.client.getConfig();\n if (cfg.autoLocalize) {\n const session = renderer.xr.getSession();\n if (session) {\n session.requestAnimationFrame(() => {\n void this.localizeFrame();\n });\n } else {\n void this.localizeFrame();\n }\n }\n });\n\n renderer.xr.addEventListener('sessionend', () => {\n this.isSessionActive = false;\n this.options.onSessionEnd?.();\n });\n\n let lastTime = 0;\n\n const animationLoop = (time: number, frame: XRFrame | null) => {\n const deltaSeconds = lastTime === 0 ? 0 : (time - lastTime) / 1000;\n lastTime = time;\n\n let viewerWorldPosition: THREE.Vector3 | null = null;\n if (frame) {\n const refSpace = renderer.xr.getReferenceSpace();\n if (refSpace) {\n const viewerPose = frame.getViewerPose(refSpace);\n if (viewerPose) {\n const p = viewerPose.transform.position;\n viewerWorldPosition = new THREE.Vector3(p.x, p.y, p.z);\n }\n }\n }\n\n if (this.world && deltaSeconds > 0) {\n this.world.update(deltaSeconds, viewerWorldPosition);\n }\n\n renderer.render(scene, camera);\n const cfg = this.options.client.getConfig();\n if (cfg.relocalization && frame && !this.isLocalizing) {\n const refSpace = renderer.xr.getReferenceSpace();\n if (refSpace) {\n const viewerPose = frame.getViewerPose(refSpace);\n if (!viewerPose) {\n this.trackingLossFrames += 1;\n if (this.trackingLossFrames >= TRACKING_LOSS_FRAME_THRESHOLD) {\n this.hadTrackingLoss = true;\n }\n } else {\n if (this.hadTrackingLoss) {\n this.hadTrackingLoss = false;\n this.trackingLossFrames = 0;\n void this.localizeFrame();\n } else {\n this.trackingLossFrames = 0;\n }\n }\n }\n }\n };\n renderer.setAnimationLoop(animationLoop);\n\n const resizeHandler = () => {\n this.experience?.resize();\n };\n window.addEventListener('resize', resizeHandler);\n\n const overlayRoot = this.options.overlayRoot ?? document.body;\n const arButton = ARButton.createButton(renderer, {\n requiredFeatures: ['camera-access', 'dom-overlay'],\n domOverlay: { root: overlayRoot },\n }) as HTMLButtonElement;\n\n const buttonParent =\n buttonContainer && buttonContainer instanceof HTMLElement\n ? buttonContainer\n : this.options.buttonContainer &&\n this.options.buttonContainer instanceof HTMLElement\n ? this.options.buttonContainer\n : overlayRoot;\n\n if (!buttonParent.contains(arButton)) {\n buttonParent.appendChild(arButton);\n }\n\n this.arButton = arButton;\n this.resizeHandler = resizeHandler;\n\n this.options.onARButtonCreated?.(arButton);\n return arButton;\n }\n\n getScene(): THREE.Scene {\n if (!this.experience) {\n throw new Error('Scene: WebXR controller has not been initialized.');\n }\n return this.experience.getScene();\n }\n\n getCamera(): THREE.PerspectiveCamera {\n if (!this.experience) {\n throw new Error('Camera: WebXR controller has not been initialized.');\n }\n return this.experience.getCamera();\n }\n\n getRenderer(): THREE.WebGLRenderer {\n if (!this.experience) {\n throw new Error('Renderer: WebXR controller has not been initialized.');\n }\n return this.experience.getRenderer();\n }\n\n hasActiveSession(): boolean {\n return this.isSessionActive && this.experience?.getRenderer().xr.isPresenting === true;\n }\n\n /**\n * Runs a single-frame localization: captures one frame, evaluates the result\n * against the optional confidenceThreshold, and fires\n * onLocalizationInit / onLocalizationSuccess / onLocalizationFailure.\n * Aligns with Unity SingleFrameLocalizationManager.LocalizeFrame().\n */\n async localizeFrame(): Promise<ILocalizeAndMapDetails | null> {\n if (!this.experience) {\n throw new Error('WebXR: WebXR controller has not been initialized.');\n }\n const renderer = this.experience.getRenderer();\n const session = renderer.xr.getSession?.();\n if (!session) {\n throw new Error(\n 'WebXR Session: No active WebXR session. Start AR before calling localizeFrame().'\n );\n }\n\n const cfg = this.options.client.getConfig();\n const confidenceCheck = cfg.confidenceCheck ?? false;\n const confidenceThreshold = Math.max(\n CONFIDENCE_THRESHOLD_MIN,\n Math.min(cfg.confidenceThreshold ?? 0.5, CONFIDENCE_THRESHOLD_MAX)\n );\n\n cfg.onLocalizationInit?.();\n this.isLocalizing = true;\n\n let best: ILocalizeAndMapDetails | null = null;\n\n let failureReason: string | undefined;\n try {\n const captureResult = await this.captureFrame();\n best = captureResult.result;\n failureReason = captureResult.failureReason;\n } finally {\n this.isLocalizing = false;\n }\n\n const accepted =\n best &&\n (!confidenceCheck ||\n (best.localizeData.confidence ?? 0) >= confidenceThreshold);\n\n if (accepted && best) {\n cfg.onLocalizationSuccess?.(best);\n\n if (this.world && this.trackerSpace) {\n const willShowMesh = cfg.showMesh && !!best.mapDetails;\n const willShowGizmo = cfg.showGizmo !== false;\n if (willShowMesh || willShowGizmo) {\n try {\n await this.world.ensureGizmoLoaded();\n if (willShowMesh) {\n await this.world.ensureMeshLoaded(best.mapDetails!);\n }\n this.world.applyMeshTransform(best, this.trackerSpace);\n } catch {\n // Mesh/gizmo loading failure must not prevent returning the localization result\n }\n }\n }\n return best;\n }\n\n const reason =\n failureReason ??\n (!best\n ? 'All attempts failed to produce a pose.'\n : confidenceCheck\n ? `Best confidence ${best.localizeData.confidence ?? 0} below threshold ${confidenceThreshold}.`\n : undefined);\n cfg.onLocalizationFailure?.(reason);\n return null;\n }\n\n /**\n * Internal: captures one frame and calls the localization API. Waits for a\n * valid viewer pose up to localizationTrackingTimeoutMs (and TRACKING_FRAME_CAP),\n * then tries to get a camera image (up to CAMERA_IMAGE_MAX_ATTEMPTS). Returns\n * result, apiCalled, and an optional failureReason for onLocalizationFailure.\n */\n private async captureFrame(): Promise<{\n result: ILocalizeAndMapDetails | null;\n apiCalled: boolean;\n failureReason?: string;\n }> {\n if (!this.experience) {\n throw new Error('WebXR: WebXR controller has not been initialized.');\n }\n const renderer = this.experience.getRenderer();\n\n const session = renderer.xr.getSession?.();\n if (!session) {\n throw new Error(\n 'WebXR Session: No active WebXR session. Start AR before capturing.'\n );\n }\n\n const referenceSpace = renderer.xr.getReferenceSpace();\n if (!referenceSpace) {\n throw new Error(\n 'WebXR Reference Space: Unable to acquire XR reference space.'\n );\n }\n\n const gl = renderer.getContext();\n const cfg = this.options.client.getConfig();\n const timeoutMs = cfg.localizationTrackingTimeoutMs ?? DEFAULT_TRACKING_TIMEOUT_MS;\n\n return new Promise((resolve, reject) => {\n const startTime = Date.now();\n\n const tryFrame = (attempt: number, cameraAttemptsWithPose: number) => {\n session.requestAnimationFrame(async (_time: number, xrFrame: XRFrame) => {\n try {\n const elapsed = Date.now() - startTime;\n const viewerPose = xrFrame.getViewerPose(referenceSpace);\n if (!viewerPose) {\n if (elapsed >= timeoutMs || attempt + 1 >= TRACKING_FRAME_CAP) {\n const sec = (timeoutMs / 1000).toFixed(1);\n resolve({\n result: null,\n apiCalled: false,\n failureReason: `Tracking unavailable: no viewer pose within ${sec}s. Try moving the device or ensuring good lighting.`,\n });\n } else {\n tryFrame(attempt + 1, cameraAttemptsWithPose);\n }\n return;\n }\n\n const views = viewerPose.views as XRViewWithCamera[];\n for (let i = 0; i < views.length; i += 1) {\n const view = views[i];\n const xrCamera = view.camera;\n if (!xrCamera) continue;\n\n const gl2 = gl as unknown as WebGL2RenderingContext;\n const bindingCtor = XRWebGLBinding as unknown as {\n new(\n session: XRSession,\n context: WebGL2RenderingContext\n ): XRWebGLBindingLike;\n };\n const binding = new bindingCtor(session, gl2);\n const cameraTexture = binding.getCameraImage?.(xrCamera) ?? null;\n if (!cameraTexture) continue;\n\n const width = xrCamera.width;\n const height = xrCamera.height;\n if (!width || !height) continue;\n\n const frameData = await getCameraTextureAsImage(\n renderer,\n cameraTexture,\n width,\n height\n );\n\n const intrinsics = getCameraIntrinsics(view.projectionMatrix, {\n width,\n height,\n x: 0,\n y: 0,\n });\n\n if (frameData && intrinsics) {\n // Capture the camera pose from the current XRFrame's view transform\n // (column-major Float32Array, same convention as THREE.Matrix4.fromArray).\n // Using camera.matrix would give the previous render frame's pose.\n this.trackerSpace = new THREE.Matrix4().fromArray(view.transform.matrix);\n\n const result = await this.options.client.localizeWithFrame(\n frameData,\n intrinsics\n );\n resolve({ result, apiCalled: true });\n return;\n }\n }\n\n if (cameraAttemptsWithPose + 1 >= CAMERA_IMAGE_MAX_ATTEMPTS) {\n resolve({\n result: null,\n apiCalled: false,\n failureReason:\n 'Camera image not available. The device or browser may not support camera access in AR.',\n });\n } else {\n tryFrame(attempt + 1, cameraAttemptsWithPose + 1);\n }\n } catch (error) {\n reject(error);\n } finally {\n gl.bindFramebuffer(\n gl.FRAMEBUFFER,\n session.renderState.baseLayer?.framebuffer ?? null\n );\n }\n });\n };\n tryFrame(0, 0);\n });\n }\n\n dispose(): void {\n if (this.resizeHandler) {\n window.removeEventListener('resize', this.resizeHandler);\n }\n\n this.experience?.getRenderer().setAnimationLoop(null);\n this.experience?.dispose();\n this.experience = null;\n this.world?.dispose();\n this.world = null;\n this.trackingLossFrames = 0;\n this.hadTrackingLoss = false;\n\n if (this.arButton?.parentElement) {\n this.arButton.parentElement.removeChild(this.arButton);\n }\n this.arButton = null;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@multisetai/vps",
3
- "version": "1.0.7-beta.3",
3
+ "version": "1.0.7-beta.5",
4
4
  "description": "Multiset VPS WebXR SDK - Core client and WebXR controller.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",