@ericchen1990/pano-view 2.3.0 → 2.4.0

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/dist/index.cjs CHANGED
@@ -2305,7 +2305,30 @@ module.exports = __toCommonJS(index_exports);
2305
2305
  // src/pano-viewer.tsx
2306
2306
  var import_fiber10 = require("@react-three/fiber");
2307
2307
  var import_xr3 = require("@react-three/xr");
2308
- var import_react22 = require("react");
2308
+ var import_react24 = require("react");
2309
+
2310
+ // src/background-audio-host.ts
2311
+ var import_react = require("react");
2312
+ var BackgroundAudioHostContext = (0, import_react.createContext)(null);
2313
+ function createBackgroundAudioHost() {
2314
+ return {
2315
+ controller: null,
2316
+ revision: 0,
2317
+ listeners: /* @__PURE__ */ new Set()
2318
+ };
2319
+ }
2320
+ function notifyBackgroundAudioHost(host) {
2321
+ host.revision += 1;
2322
+ for (const listener of host.listeners) {
2323
+ listener();
2324
+ }
2325
+ }
2326
+ function subscribeBackgroundAudioHost(host, listener) {
2327
+ host.listeners.add(listener);
2328
+ return () => {
2329
+ host.listeners.delete(listener);
2330
+ };
2331
+ }
2309
2332
 
2310
2333
  // src/cn.ts
2311
2334
  function cn(...values) {
@@ -2314,10 +2337,10 @@ function cn(...values) {
2314
2337
 
2315
2338
  // src/auto-rotate.tsx
2316
2339
  var import_fiber2 = require("@react-three/fiber");
2317
- var import_react3 = require("react");
2340
+ var import_react4 = require("react");
2318
2341
 
2319
2342
  // src/pano-event-bus.ts
2320
- var import_react = require("react");
2343
+ var import_react2 = require("react");
2321
2344
  function createPanoEventBus() {
2322
2345
  const listeners = /* @__PURE__ */ new Map();
2323
2346
  return {
@@ -2346,12 +2369,12 @@ function createPanoEventBus() {
2346
2369
  }
2347
2370
  };
2348
2371
  }
2349
- var PanoEventBusContext = (0, import_react.createContext)(null);
2372
+ var PanoEventBusContext = (0, import_react2.createContext)(null);
2350
2373
 
2351
2374
  // src/panorama-view-runtime.tsx
2352
2375
  var import_fiber = require("@react-three/fiber");
2353
2376
  var import_xr = require("@react-three/xr");
2354
- var import_react2 = require("react");
2377
+ var import_react3 = require("react");
2355
2378
  var import_three = require("three");
2356
2379
  var MAX_PITCH = 90;
2357
2380
  var BOUNCE_OVERSHOOT_PITCH = 12;
@@ -2362,7 +2385,7 @@ var DEFAULT_ROTATE_DAMPING = 14;
2362
2385
  var DEFAULT_ZOOM_DAMPING = 16;
2363
2386
  var DEFAULT_FRICTION_STOP = 0.01;
2364
2387
  var VIEW_SETTLE_EPSILON = 1e-3;
2365
- var PanoramaViewContext = (0, import_react2.createContext)(null);
2388
+ var PanoramaViewContext = (0, import_react3.createContext)(null);
2366
2389
  function clamp(value, min, max) {
2367
2390
  return Math.max(min, Math.min(max, value));
2368
2391
  }
@@ -2384,36 +2407,36 @@ function resolveFrictionStop(value) {
2384
2407
  function viewsEqual(a, b) {
2385
2408
  return a.yaw === b.yaw && a.pitch === b.pitch && a.fov === b.fov;
2386
2409
  }
2387
- var PanoramaViewRuntime = (0, import_react2.forwardRef)(function PanoramaViewRuntime2({ initialView, minFov, maxFov, options, eventBus }, ref) {
2410
+ var PanoramaViewRuntime = (0, import_react3.forwardRef)(function PanoramaViewRuntime2({ initialView, minFov, maxFov, options, eventBus }, ref) {
2388
2411
  const { camera, gl } = (0, import_fiber.useThree)();
2389
2412
  const xrSession = (0, import_xr.useXR)((state) => state.session);
2390
- const xrSessionRef = (0, import_react2.useRef)(xrSession);
2391
- const viewRef = (0, import_react2.useRef)({ ...initialView });
2392
- const targetViewRef = (0, import_react2.useRef)({ ...initialView });
2393
- const initialViewRef = (0, import_react2.useRef)({ ...initialView });
2394
- const yawVelocityRef = (0, import_react2.useRef)(0);
2395
- const pitchVelocityRef = (0, import_react2.useRef)(0);
2396
- const zoomVelocityRef = (0, import_react2.useRef)(0);
2397
- const dirtyRef = (0, import_react2.useRef)(true);
2398
- const settledRef = (0, import_react2.useRef)(false);
2399
- const interactingRef = (0, import_react2.useRef)(false);
2400
- const mouseActiveRef = (0, import_react2.useRef)(false);
2401
- const touchActiveRef = (0, import_react2.useRef)(false);
2402
- const interactionLockCountRef = (0, import_react2.useRef)(0);
2403
- const keyboardActiveRef = (0, import_react2.useRef)(false);
2404
- const gyroActiveRef = (0, import_react2.useRef)(false);
2405
- const gyroPoseRef = (0, import_react2.useRef)({ yaw: 0, pitch: 0, roll: 0 });
2406
- const gyroOffsetRef = (0, import_react2.useRef)({ yaw: 0, pitch: 0 });
2407
- const gyroTouchModeRef = (0, import_react2.useRef)("full");
2408
- const cameraRollRef = (0, import_react2.useRef)(0);
2409
- const lastVelocitySampleAtRef = (0, import_react2.useRef)(null);
2410
- const optionsRef = (0, import_react2.useRef)(options);
2411
- const eventBusRef = (0, import_react2.useRef)(eventBus);
2412
- const lastEmittedViewRef = (0, import_react2.useRef)(null);
2413
- const eulerRef = (0, import_react2.useRef)(new import_three.Euler(0, 0, 0, "YXZ"));
2414
- const xrEulerRef = (0, import_react2.useRef)(new import_three.Euler(0, 0, 0, "YXZ"));
2415
- const minFovRef = (0, import_react2.useRef)(minFov);
2416
- const maxFovRef = (0, import_react2.useRef)(maxFov);
2413
+ const xrSessionRef = (0, import_react3.useRef)(xrSession);
2414
+ const viewRef = (0, import_react3.useRef)({ ...initialView });
2415
+ const targetViewRef = (0, import_react3.useRef)({ ...initialView });
2416
+ const initialViewRef = (0, import_react3.useRef)({ ...initialView });
2417
+ const yawVelocityRef = (0, import_react3.useRef)(0);
2418
+ const pitchVelocityRef = (0, import_react3.useRef)(0);
2419
+ const zoomVelocityRef = (0, import_react3.useRef)(0);
2420
+ const dirtyRef = (0, import_react3.useRef)(true);
2421
+ const settledRef = (0, import_react3.useRef)(false);
2422
+ const interactingRef = (0, import_react3.useRef)(false);
2423
+ const mouseActiveRef = (0, import_react3.useRef)(false);
2424
+ const touchActiveRef = (0, import_react3.useRef)(false);
2425
+ const interactionLockCountRef = (0, import_react3.useRef)(0);
2426
+ const keyboardActiveRef = (0, import_react3.useRef)(false);
2427
+ const gyroActiveRef = (0, import_react3.useRef)(false);
2428
+ const gyroPoseRef = (0, import_react3.useRef)({ yaw: 0, pitch: 0, roll: 0 });
2429
+ const gyroOffsetRef = (0, import_react3.useRef)({ yaw: 0, pitch: 0 });
2430
+ const gyroTouchModeRef = (0, import_react3.useRef)("full");
2431
+ const cameraRollRef = (0, import_react3.useRef)(0);
2432
+ const lastVelocitySampleAtRef = (0, import_react3.useRef)(null);
2433
+ const optionsRef = (0, import_react3.useRef)(options);
2434
+ const eventBusRef = (0, import_react3.useRef)(eventBus);
2435
+ const lastEmittedViewRef = (0, import_react3.useRef)(null);
2436
+ const eulerRef = (0, import_react3.useRef)(new import_three.Euler(0, 0, 0, "YXZ"));
2437
+ const xrEulerRef = (0, import_react3.useRef)(new import_three.Euler(0, 0, 0, "YXZ"));
2438
+ const minFovRef = (0, import_react3.useRef)(minFov);
2439
+ const maxFovRef = (0, import_react3.useRef)(maxFov);
2417
2440
  optionsRef.current = options;
2418
2441
  eventBusRef.current = eventBus;
2419
2442
  xrSessionRef.current = xrSession;
@@ -2556,7 +2579,7 @@ var PanoramaViewRuntime = (0, import_react2.forwardRef)(function PanoramaViewRun
2556
2579
  }
2557
2580
  return true;
2558
2581
  };
2559
- (0, import_react2.useImperativeHandle)(
2582
+ (0, import_react3.useImperativeHandle)(
2560
2583
  ref,
2561
2584
  () => ({
2562
2585
  getView: () => ({ ...viewRef.current }),
@@ -2646,7 +2669,7 @@ var PanoramaViewRuntime = (0, import_react2.forwardRef)(function PanoramaViewRun
2646
2669
  }),
2647
2670
  []
2648
2671
  );
2649
- (0, import_react2.useEffect)(() => {
2672
+ (0, import_react3.useEffect)(() => {
2650
2673
  initialViewRef.current = { ...initialView };
2651
2674
  setView(initialView);
2652
2675
  }, [initialView.fov, initialView.pitch, initialView.yaw]);
@@ -2775,16 +2798,16 @@ function AutoRotate({
2775
2798
  acceleration = DEFAULT_AUTO_ROTATE_ACCELERATION,
2776
2799
  startDelay = DEFAULT_AUTO_ROTATE_START_DELAY
2777
2800
  }) {
2778
- const controlsRef = (0, import_react3.useContext)(PanoramaViewContext);
2779
- const eventBus = (0, import_react3.useContext)(PanoEventBusContext);
2780
- const elapsedRef = (0, import_react3.useRef)(0);
2781
- const rotationSpeedRef = (0, import_react3.useRef)(0);
2782
- const rotatingRef = (0, import_react3.useRef)(false);
2783
- const yawAccumulatedRef = (0, import_react3.useRef)(0);
2801
+ const controlsRef = (0, import_react4.useContext)(PanoramaViewContext);
2802
+ const eventBus = (0, import_react4.useContext)(PanoEventBusContext);
2803
+ const elapsedRef = (0, import_react4.useRef)(0);
2804
+ const rotationSpeedRef = (0, import_react4.useRef)(0);
2805
+ const rotatingRef = (0, import_react4.useRef)(false);
2806
+ const yawAccumulatedRef = (0, import_react4.useRef)(0);
2784
2807
  if (!controlsRef) {
2785
2808
  throw new Error("<AutoRotate> must be rendered inside <PanoViewer>.");
2786
2809
  }
2787
- (0, import_react3.useEffect)(() => {
2810
+ (0, import_react4.useEffect)(() => {
2788
2811
  elapsedRef.current = 0;
2789
2812
  rotationSpeedRef.current = 0;
2790
2813
  yawAccumulatedRef.current = 0;
@@ -2839,9 +2862,9 @@ function AutoRotate({
2839
2862
  }
2840
2863
 
2841
2864
  // src/control-claims.ts
2842
- var import_react4 = require("react");
2843
- var ControlClaimsContext = (0, import_react4.createContext)(null);
2844
- var DefaultControlChannelContext = (0, import_react4.createContext)(false);
2865
+ var import_react5 = require("react");
2866
+ var ControlClaimsContext = (0, import_react5.createContext)(null);
2867
+ var DefaultControlChannelContext = (0, import_react5.createContext)(false);
2845
2868
  var CHANNEL_COMPONENT = {
2846
2869
  mouse: "MouseControls",
2847
2870
  touch: "TouchControls",
@@ -2860,8 +2883,8 @@ function isProduction() {
2860
2883
  return nodeEnv === "production";
2861
2884
  }
2862
2885
  function useClaimControlChannel(channel) {
2863
- const claims = (0, import_react4.useContext)(ControlClaimsContext);
2864
- const isDefault = (0, import_react4.useContext)(DefaultControlChannelContext);
2886
+ const claims = (0, import_react5.useContext)(ControlClaimsContext);
2887
+ const isDefault = (0, import_react5.useContext)(DefaultControlChannelContext);
2865
2888
  if (!claims || isDefault) {
2866
2889
  return;
2867
2890
  }
@@ -2922,9 +2945,9 @@ function subscribeFullscreenChange(onChange) {
2922
2945
  }
2923
2946
 
2924
2947
  // src/hotspot/accessibility.tsx
2925
- var import_react5 = require("react");
2948
+ var import_react6 = require("react");
2926
2949
  var import_jsx_runtime = require("react/jsx-runtime");
2927
- var HotspotAccessibilityContext = (0, import_react5.createContext)(null);
2950
+ var HotspotAccessibilityContext = (0, import_react6.createContext)(null);
2928
2951
  function warnAboutMissingLabel(id) {
2929
2952
  const nodeEnv = globalThis.process?.env?.NODE_ENV;
2930
2953
  if (nodeEnv !== "production") {
@@ -2938,12 +2961,12 @@ function useHotspotAccessibility({
2938
2961
  ariaLabel,
2939
2962
  onActivate
2940
2963
  }) {
2941
- const registry = (0, import_react5.useContext)(HotspotAccessibilityContext);
2942
- const [focused, setFocused] = (0, import_react5.useState)(false);
2943
- const activateRef = (0, import_react5.useRef)(onActivate);
2964
+ const registry = (0, import_react6.useContext)(HotspotAccessibilityContext);
2965
+ const [focused, setFocused] = (0, import_react6.useState)(false);
2966
+ const activateRef = (0, import_react6.useRef)(onActivate);
2944
2967
  const enabled = Boolean(onActivate);
2945
2968
  activateRef.current = onActivate;
2946
- (0, import_react5.useEffect)(() => {
2969
+ (0, import_react6.useEffect)(() => {
2947
2970
  if (!enabled) {
2948
2971
  setFocused(false);
2949
2972
  return;
@@ -2965,8 +2988,8 @@ function useHotspotAccessibility({
2965
2988
  return focused;
2966
2989
  }
2967
2990
  function useHotspotAccessibilityLayer() {
2968
- const [entries, setEntries] = (0, import_react5.useState)(() => /* @__PURE__ */ new Map());
2969
- const register = (0, import_react5.useCallback)(
2991
+ const [entries, setEntries] = (0, import_react6.useState)(() => /* @__PURE__ */ new Map());
2992
+ const register = (0, import_react6.useCallback)(
2970
2993
  (entry) => {
2971
2994
  const token = Symbol(entry.id);
2972
2995
  const nextEntry = { ...entry, token };
@@ -2988,11 +3011,11 @@ function useHotspotAccessibilityLayer() {
2988
3011
  },
2989
3012
  []
2990
3013
  );
2991
- const registry = (0, import_react5.useMemo)(
3014
+ const registry = (0, import_react6.useMemo)(
2992
3015
  () => ({ register }),
2993
3016
  [register]
2994
3017
  );
2995
- const controls = (0, import_react5.useMemo)(
3018
+ const controls = (0, import_react6.useMemo)(
2996
3019
  () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { "aria-label": "Panorama hotspots", style: { pointerEvents: "none" }, children: Array.from(entries.values()).map((entry) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2997
3020
  "button",
2998
3021
  {
@@ -3019,7 +3042,7 @@ function useHotspotAccessibilityLayer() {
3019
3042
 
3020
3043
  // src/keyboard-controls.tsx
3021
3044
  var import_fiber3 = require("@react-three/fiber");
3022
- var import_react6 = require("react");
3045
+ var import_react7 = require("react");
3023
3046
  var DEFAULT_ROTATE_SPEED = 60;
3024
3047
  var DEFAULT_ZOOM_SPEED = 30;
3025
3048
  var DEFAULT_SHIFT_MULTIPLIER = 3;
@@ -3089,15 +3112,15 @@ function KeyboardControls({
3089
3112
  onNextScene
3090
3113
  }) {
3091
3114
  useClaimControlChannel("keyboard");
3092
- const controlsRef = (0, import_react6.useContext)(PanoramaViewContext);
3115
+ const controlsRef = (0, import_react7.useContext)(PanoramaViewContext);
3093
3116
  const { gl } = (0, import_fiber3.useThree)();
3094
- const pressedRef = (0, import_react6.useRef)(/* @__PURE__ */ new Set());
3095
- const shiftHeldRef = (0, import_react6.useRef)(false);
3096
- const invertRef = (0, import_react6.useRef)(invert);
3097
- const fovSpeedRef = (0, import_react6.useRef)(fovSpeed);
3098
- const onPreviousSceneRef = (0, import_react6.useRef)(onPreviousScene);
3099
- const onNextSceneRef = (0, import_react6.useRef)(onNextScene);
3100
- const keyMap = (0, import_react6.useMemo)(() => resolveKeyMap(keys), [keys]);
3117
+ const pressedRef = (0, import_react7.useRef)(/* @__PURE__ */ new Set());
3118
+ const shiftHeldRef = (0, import_react7.useRef)(false);
3119
+ const invertRef = (0, import_react7.useRef)(invert);
3120
+ const fovSpeedRef = (0, import_react7.useRef)(fovSpeed);
3121
+ const onPreviousSceneRef = (0, import_react7.useRef)(onPreviousScene);
3122
+ const onNextSceneRef = (0, import_react7.useRef)(onNextScene);
3123
+ const keyMap = (0, import_react7.useMemo)(() => resolveKeyMap(keys), [keys]);
3101
3124
  if (!controlsRef) {
3102
3125
  throw new Error("<KeyboardControls> must be rendered inside <PanoViewer>.");
3103
3126
  }
@@ -3105,7 +3128,7 @@ function KeyboardControls({
3105
3128
  fovSpeedRef.current = fovSpeed;
3106
3129
  onPreviousSceneRef.current = onPreviousScene;
3107
3130
  onNextSceneRef.current = onNextScene;
3108
- (0, import_react6.useEffect)(() => {
3131
+ (0, import_react7.useEffect)(() => {
3109
3132
  const element = gl.domElement;
3110
3133
  if (!enabled) {
3111
3134
  pressedRef.current.clear();
@@ -3263,7 +3286,7 @@ function KeyboardControls({
3263
3286
 
3264
3287
  // src/mouse-controls.tsx
3265
3288
  var import_fiber4 = require("@react-three/fiber");
3266
- var import_react7 = require("react");
3289
+ var import_react8 = require("react");
3267
3290
  var DEFAULT_ROTATE_SPEED2 = 0.35;
3268
3291
  var DEFAULT_ZOOM_SPEED2 = 0.08;
3269
3292
  var BUTTON_FLAG = {
@@ -3288,12 +3311,12 @@ function MouseControls({
3288
3311
  fovSpeed
3289
3312
  }) {
3290
3313
  useClaimControlChannel("mouse");
3291
- const controlsRef = (0, import_react7.useContext)(PanoramaViewContext);
3314
+ const controlsRef = (0, import_react8.useContext)(PanoramaViewContext);
3292
3315
  const { gl } = (0, import_fiber4.useThree)();
3293
- const pointersRef = (0, import_react7.useRef)(
3316
+ const pointersRef = (0, import_react8.useRef)(
3294
3317
  /* @__PURE__ */ new Map()
3295
3318
  );
3296
- const optionsRef = (0, import_react7.useRef)({
3319
+ const optionsRef = (0, import_react8.useRef)({
3297
3320
  rotateSpeed,
3298
3321
  zoomSpeed,
3299
3322
  wheel,
@@ -3310,7 +3333,7 @@ function MouseControls({
3310
3333
  invert,
3311
3334
  fovSpeed
3312
3335
  };
3313
- (0, import_react7.useEffect)(() => {
3336
+ (0, import_react8.useEffect)(() => {
3314
3337
  const element = gl.domElement;
3315
3338
  const allowedButtons = resolveButtons(buttons);
3316
3339
  const clearPointers = () => {
@@ -3434,7 +3457,7 @@ function MouseControls({
3434
3457
  }
3435
3458
 
3436
3459
  // src/pano-filter/host.ts
3437
- var import_react8 = require("react");
3460
+ var import_react9 = require("react");
3438
3461
 
3439
3462
  // src/pano-filter/presets.ts
3440
3463
  var PANO_FILTER_PRESETS = [
@@ -3475,7 +3498,7 @@ function isPanoFilterActive(snapshot) {
3475
3498
  }
3476
3499
 
3477
3500
  // src/pano-filter/host.ts
3478
- var PanoFilterHostContext = (0, import_react8.createContext)(null);
3501
+ var PanoFilterHostContext = (0, import_react9.createContext)(null);
3479
3502
  function createPanoFilterHost() {
3480
3503
  return {
3481
3504
  snapshot: { ...DEFAULT_PANO_FILTER_SNAPSHOT },
@@ -3529,8 +3552,8 @@ function subscribeNoop() {
3529
3552
  };
3530
3553
  }
3531
3554
  function usePanoFilterSnapshot() {
3532
- const host = (0, import_react8.useContext)(PanoFilterHostContext);
3533
- const revision = (0, import_react8.useSyncExternalStore)(
3555
+ const host = (0, import_react9.useContext)(PanoFilterHostContext);
3556
+ const revision = (0, import_react9.useSyncExternalStore)(
3534
3557
  host ? (onStoreChange) => subscribePanoFilterHost(host, onStoreChange) : subscribeNoop,
3535
3558
  () => host ? getPanoFilterHostRevision(host) : 0,
3536
3559
  () => host ? getPanoFilterHostRevision(host) : 0
@@ -3544,12 +3567,12 @@ function isProduction2() {
3544
3567
  }
3545
3568
 
3546
3569
  // src/pano-context-menu.tsx
3547
- var import_react9 = require("react");
3570
+ var import_react10 = require("react");
3548
3571
  var import_jsx_runtime2 = require("react/jsx-runtime");
3549
3572
  var DEFAULT_ICON_SIZE = 16;
3550
3573
  var MENU_EDGE_PADDING = 8;
3551
3574
  var MIN_PANO_CONTEXT_MENU_BACKGROUND_OPACITY = 0.4;
3552
- var PanoContextMenuOverlayContext = (0, import_react9.createContext)(null);
3575
+ var PanoContextMenuOverlayContext = (0, import_react10.createContext)(null);
3553
3576
  var DEFAULT_APPEARANCE = {
3554
3577
  background: "#161616",
3555
3578
  color: "#f4f4f4",
@@ -3589,11 +3612,11 @@ function DefaultContextMenuPanel({
3589
3612
  selectContext,
3590
3613
  onRequestClose
3591
3614
  }) {
3592
- const menuRef = (0, import_react9.useRef)(null);
3593
- const [activeIndex, setActiveIndex] = (0, import_react9.useState)(0);
3615
+ const menuRef = (0, import_react10.useRef)(null);
3616
+ const [activeIndex, setActiveIndex] = (0, import_react10.useState)(0);
3594
3617
  const resolved = { ...DEFAULT_APPEARANCE, ...appearance };
3595
3618
  const iconSize = Number.isFinite(resolved.iconSize) ? Math.max(0, resolved.iconSize) : DEFAULT_ICON_SIZE;
3596
- const visibleItems = (0, import_react9.useMemo)(
3619
+ const visibleItems = (0, import_react10.useMemo)(
3597
3620
  () => items.filter((item) => {
3598
3621
  if (!isActionItem(item)) {
3599
3622
  return true;
@@ -3602,7 +3625,7 @@ function DefaultContextMenuPanel({
3602
3625
  }),
3603
3626
  [items]
3604
3627
  );
3605
- const focusableIndices = (0, import_react9.useMemo)(() => {
3628
+ const focusableIndices = (0, import_react10.useMemo)(() => {
3606
3629
  const indices = [];
3607
3630
  visibleItems.forEach((item, index) => {
3608
3631
  if (isActionItem(item) && !item.disabled) {
@@ -3611,7 +3634,7 @@ function DefaultContextMenuPanel({
3611
3634
  });
3612
3635
  return indices;
3613
3636
  }, [visibleItems]);
3614
- (0, import_react9.useEffect)(() => {
3637
+ (0, import_react10.useEffect)(() => {
3615
3638
  const first = focusableIndices[0];
3616
3639
  setActiveIndex(first ?? 0);
3617
3640
  const frame = requestAnimationFrame(() => {
@@ -3622,7 +3645,7 @@ function DefaultContextMenuPanel({
3622
3645
  });
3623
3646
  return () => cancelAnimationFrame(frame);
3624
3647
  }, [focusableIndices]);
3625
- const activateItem = (0, import_react9.useCallback)(
3648
+ const activateItem = (0, import_react10.useCallback)(
3626
3649
  (item) => {
3627
3650
  if (item.disabled) {
3628
3651
  return;
@@ -3828,9 +3851,9 @@ function PositionedMenuShell({
3828
3851
  overlayElement,
3829
3852
  children
3830
3853
  }) {
3831
- const shellRef = (0, import_react9.useRef)(null);
3832
- const [offset, setOffset] = (0, import_react9.useState)({ left: 0, top: 0 });
3833
- (0, import_react9.useLayoutEffect)(() => {
3854
+ const shellRef = (0, import_react10.useRef)(null);
3855
+ const [offset, setOffset] = (0, import_react10.useState)({ left: 0, top: 0 });
3856
+ (0, import_react10.useLayoutEffect)(() => {
3834
3857
  const shell = shellRef.current;
3835
3858
  if (!overlayElement || !shell) {
3836
3859
  return;
@@ -3866,20 +3889,20 @@ function PositionedMenuShell({
3866
3889
  );
3867
3890
  }
3868
3891
  function usePanoContextMenuOverlay() {
3869
- const [session2, setSession] = (0, import_react9.useState)(null);
3870
- const overlayRef = (0, import_react9.useRef)(null);
3871
- const [overlayElement, setOverlayElement] = (0, import_react9.useState)(
3892
+ const [session2, setSession] = (0, import_react10.useState)(null);
3893
+ const overlayRef = (0, import_react10.useRef)(null);
3894
+ const [overlayElement, setOverlayElement] = (0, import_react10.useState)(
3872
3895
  null
3873
3896
  );
3874
- const api = (0, import_react9.useMemo)(
3897
+ const api = (0, import_react10.useMemo)(
3875
3898
  () => ({ setSession, overlayRef }),
3876
3899
  []
3877
3900
  );
3878
- const setOverlayNode = (0, import_react9.useCallback)((node) => {
3901
+ const setOverlayNode = (0, import_react10.useCallback)((node) => {
3879
3902
  overlayRef.current = node;
3880
3903
  setOverlayElement(node);
3881
3904
  }, []);
3882
- (0, import_react9.useEffect)(() => {
3905
+ (0, import_react10.useEffect)(() => {
3883
3906
  if (!session2) {
3884
3907
  return;
3885
3908
  }
@@ -3947,13 +3970,13 @@ function PanoContextMenu({
3947
3970
  separatorClassName,
3948
3971
  children
3949
3972
  }) {
3950
- const eventBus = (0, import_react9.useContext)(PanoEventBusContext);
3951
- const controlsRef = (0, import_react9.useContext)(PanoramaViewContext);
3952
- const overlayApi = (0, import_react9.useContext)(PanoContextMenuOverlayContext);
3953
- const actions = (0, import_react9.useContext)(PanoContextMenuActionsContext);
3954
- const instanceId = (0, import_react9.useId)();
3955
- const sessionKeyRef = (0, import_react9.useRef)(0);
3956
- const propsRef = (0, import_react9.useRef)({
3973
+ const eventBus = (0, import_react10.useContext)(PanoEventBusContext);
3974
+ const controlsRef = (0, import_react10.useContext)(PanoramaViewContext);
3975
+ const overlayApi = (0, import_react10.useContext)(PanoContextMenuOverlayContext);
3976
+ const actions = (0, import_react10.useContext)(PanoContextMenuActionsContext);
3977
+ const instanceId = (0, import_react10.useId)();
3978
+ const sessionKeyRef = (0, import_react10.useRef)(0);
3979
+ const propsRef = (0, import_react10.useRef)({
3957
3980
  items,
3958
3981
  prepend,
3959
3982
  append,
@@ -3983,10 +4006,10 @@ function PanoContextMenu({
3983
4006
  "<PanoContextMenu> requires the PanoViewer context-menu overlay host."
3984
4007
  );
3985
4008
  }
3986
- const close = (0, import_react9.useCallback)(() => {
4009
+ const close = (0, import_react10.useCallback)(() => {
3987
4010
  overlayApi.setSession(null);
3988
4011
  }, [overlayApi]);
3989
- const openMenu = (0, import_react9.useCallback)(
4012
+ const openMenu = (0, import_react10.useCallback)(
3990
4013
  (event) => {
3991
4014
  event.nativeEvent.preventDefault();
3992
4015
  const view = controlsRef.current?.getView() ?? {
@@ -4035,7 +4058,7 @@ function PanoContextMenu({
4035
4058
  },
4036
4059
  [actions, close, controlsRef, instanceId, overlayApi]
4037
4060
  );
4038
- (0, import_react9.useEffect)(() => {
4061
+ (0, import_react10.useEffect)(() => {
4039
4062
  const unsubscribeContextMenu = eventBus.subscribe(
4040
4063
  "contextmenu",
4041
4064
  openMenu
@@ -4214,11 +4237,11 @@ function composePanoContextMenuItems(props, presets) {
4214
4237
  ...resolvePanoContextMenuEntries(props.append ?? [], presets)
4215
4238
  ];
4216
4239
  }
4217
- var PanoContextMenuActionsContext = (0, import_react9.createContext)(null);
4240
+ var PanoContextMenuActionsContext = (0, import_react10.createContext)(null);
4218
4241
 
4219
4242
  // src/pano-cursor.tsx
4220
4243
  var import_fiber5 = require("@react-three/fiber");
4221
- var import_react10 = require("react");
4244
+ var import_react11 = require("react");
4222
4245
  var import_jsx_runtime3 = require("react/jsx-runtime");
4223
4246
  var DEFAULT_PANO_CURSORS = {
4224
4247
  default: "grab",
@@ -4233,9 +4256,9 @@ var LAYER_PRIORITY = {
4233
4256
  hotspotDragging: 3,
4234
4257
  hidden: 4
4235
4258
  };
4236
- var PanoCursorContext = (0, import_react10.createContext)(null);
4259
+ var PanoCursorContext = (0, import_react11.createContext)(null);
4237
4260
  function usePanoCursor() {
4238
- return (0, import_react10.useContext)(PanoCursorContext);
4261
+ return (0, import_react11.useContext)(PanoCursorContext);
4239
4262
  }
4240
4263
  function hotspotCursorClaimId(id) {
4241
4264
  return `pano-cursor:hotspot:${id}`;
@@ -4287,12 +4310,12 @@ function PanoCursorController({
4287
4310
  children
4288
4311
  }) {
4289
4312
  const { gl } = (0, import_fiber5.useThree)();
4290
- const eventBus = (0, import_react10.useContext)(PanoEventBusContext);
4291
- const claimsRef = (0, import_react10.useRef)(/* @__PURE__ */ new Map());
4292
- const cursorsRef = (0, import_react10.useRef)(cursors);
4293
- const appliedCursorRef = (0, import_react10.useRef)(null);
4313
+ const eventBus = (0, import_react11.useContext)(PanoEventBusContext);
4314
+ const claimsRef = (0, import_react11.useRef)(/* @__PURE__ */ new Map());
4315
+ const cursorsRef = (0, import_react11.useRef)(cursors);
4316
+ const appliedCursorRef = (0, import_react11.useRef)(null);
4294
4317
  cursorsRef.current = cursors;
4295
- const applyCursor = (0, import_react10.useCallback)(() => {
4318
+ const applyCursor = (0, import_react11.useCallback)(() => {
4296
4319
  const next = resolveHighestCursor(claimsRef.current, cursorsRef.current);
4297
4320
  const element = gl.domElement;
4298
4321
  if (appliedCursorRef.current === next && element.style.cursor === next) {
@@ -4301,14 +4324,14 @@ function PanoCursorController({
4301
4324
  element.style.cursor = next;
4302
4325
  appliedCursorRef.current = next;
4303
4326
  }, [gl]);
4304
- const claim = (0, import_react10.useCallback)(
4327
+ const claim = (0, import_react11.useCallback)(
4305
4328
  (id, layer, cursor) => {
4306
4329
  claimsRef.current.set(id, { layer, cursor });
4307
4330
  applyCursor();
4308
4331
  },
4309
4332
  [applyCursor]
4310
4333
  );
4311
- const release = (0, import_react10.useCallback)(
4334
+ const release = (0, import_react11.useCallback)(
4312
4335
  (id) => {
4313
4336
  if (claimsRef.current.delete(id)) {
4314
4337
  applyCursor();
@@ -4316,7 +4339,7 @@ function PanoCursorController({
4316
4339
  },
4317
4340
  [applyCursor]
4318
4341
  );
4319
- const api = (0, import_react10.useMemo)(
4342
+ const api = (0, import_react11.useMemo)(
4320
4343
  () => ({
4321
4344
  cursors,
4322
4345
  claim,
@@ -4324,7 +4347,7 @@ function PanoCursorController({
4324
4347
  }),
4325
4348
  [claim, cursors, release]
4326
4349
  );
4327
- (0, import_react10.useEffect)(() => {
4350
+ (0, import_react11.useEffect)(() => {
4328
4351
  const element = gl.domElement;
4329
4352
  const previous = element.style.cursor;
4330
4353
  return () => {
@@ -4333,10 +4356,10 @@ function PanoCursorController({
4333
4356
  element.style.cursor = previous;
4334
4357
  };
4335
4358
  }, [gl]);
4336
- (0, import_react10.useEffect)(() => {
4359
+ (0, import_react11.useEffect)(() => {
4337
4360
  applyCursor();
4338
4361
  }, [applyCursor, cursors]);
4339
- (0, import_react10.useEffect)(() => {
4362
+ (0, import_react11.useEffect)(() => {
4340
4363
  if (!eventBus) {
4341
4364
  return;
4342
4365
  }
@@ -4366,7 +4389,7 @@ function PanoCursorController({
4366
4389
 
4367
4390
  // src/pano-events.tsx
4368
4391
  var import_fiber6 = require("@react-three/fiber");
4369
- var import_react11 = require("react");
4392
+ var import_react12 = require("react");
4370
4393
  var DEFAULT_IDLE_TIME_MS = 2e3;
4371
4394
  function resolveIdleTime(value) {
4372
4395
  return Number.isFinite(value) && value >= 0 ? value : DEFAULT_IDLE_TIME_MS;
@@ -4404,13 +4427,13 @@ function usePanoEvents({
4404
4427
  onVRDenied,
4405
4428
  onVRUnknownDevice
4406
4429
  }) {
4407
- const eventBus = (0, import_react11.useContext)(PanoEventBusContext);
4408
- const controlsRef = (0, import_react11.useContext)(PanoramaViewContext);
4430
+ const eventBus = (0, import_react12.useContext)(PanoEventBusContext);
4431
+ const controlsRef = (0, import_react12.useContext)(PanoramaViewContext);
4409
4432
  const { gl } = (0, import_fiber6.useThree)();
4410
4433
  if (!eventBus || !controlsRef) {
4411
4434
  throw new Error("usePanoEvents must be used inside <PanoViewer>.");
4412
4435
  }
4413
- const callbacksRef = (0, import_react11.useRef)({
4436
+ const callbacksRef = (0, import_react12.useRef)({
4414
4437
  onViewChange,
4415
4438
  onViewSettled,
4416
4439
  onViewInteractionStart,
@@ -4474,15 +4497,15 @@ function usePanoEvents({
4474
4497
  onVRDenied,
4475
4498
  onVRUnknownDevice
4476
4499
  };
4477
- const idleElapsedRef = (0, import_react11.useRef)(0);
4478
- const isIdleRef = (0, import_react11.useRef)(false);
4479
- const idleTimeRef = (0, import_react11.useRef)(resolveIdleTime(idleTime));
4500
+ const idleElapsedRef = (0, import_react12.useRef)(0);
4501
+ const isIdleRef = (0, import_react12.useRef)(false);
4502
+ const idleTimeRef = (0, import_react12.useRef)(resolveIdleTime(idleTime));
4480
4503
  idleTimeRef.current = resolveIdleTime(idleTime);
4481
- (0, import_react11.useEffect)(() => {
4504
+ (0, import_react12.useEffect)(() => {
4482
4505
  idleElapsedRef.current = 0;
4483
4506
  isIdleRef.current = false;
4484
4507
  }, [idleTime]);
4485
- (0, import_react11.useEffect)(() => {
4508
+ (0, import_react12.useEffect)(() => {
4486
4509
  const unsubscribers = [
4487
4510
  eventBus.subscribe("viewchange", (view) => {
4488
4511
  callbacksRef.current.onViewChange?.(view);
@@ -4563,7 +4586,7 @@ function usePanoEvents({
4563
4586
  }
4564
4587
  };
4565
4588
  }, [eventBus]);
4566
- (0, import_react11.useEffect)(() => {
4589
+ (0, import_react12.useEffect)(() => {
4567
4590
  const element = gl.domElement;
4568
4591
  const handleWheel = (nativeEvent) => {
4569
4592
  callbacksRef.current.onWheel?.({
@@ -4576,7 +4599,7 @@ function usePanoEvents({
4576
4599
  element.removeEventListener("wheel", handleWheel);
4577
4600
  };
4578
4601
  }, [gl]);
4579
- (0, import_react11.useEffect)(() => {
4602
+ (0, import_react12.useEffect)(() => {
4580
4603
  if (typeof document === "undefined") {
4581
4604
  return;
4582
4605
  }
@@ -4602,7 +4625,7 @@ function usePanoEvents({
4602
4625
  wasFullscreenRef.current = isViewerFullscreen();
4603
4626
  return subscribeFullscreenChange(handleFullscreenChange);
4604
4627
  }, [gl]);
4605
- (0, import_react11.useEffect)(() => {
4628
+ (0, import_react12.useEffect)(() => {
4606
4629
  const element = gl.domElement;
4607
4630
  if (typeof ResizeObserver === "undefined") {
4608
4631
  return;
@@ -4644,7 +4667,7 @@ function PanoEvents(props) {
4644
4667
 
4645
4668
  // src/panorama-event-surface.tsx
4646
4669
  var import_fiber7 = require("@react-three/fiber");
4647
- var import_react12 = require("react");
4670
+ var import_react13 = require("react");
4648
4671
  var import_three3 = require("three");
4649
4672
 
4650
4673
  // src/hotspot/coordinates.ts
@@ -4737,9 +4760,9 @@ function makePanoramaPointerEvent(event) {
4737
4760
  };
4738
4761
  }
4739
4762
  function PanoramaEventSurface() {
4740
- const eventBus = (0, import_react12.useContext)(PanoEventBusContext);
4763
+ const eventBus = (0, import_react13.useContext)(PanoEventBusContext);
4741
4764
  const { camera, gl } = (0, import_fiber7.useThree)();
4742
- (0, import_react12.useEffect)(() => {
4765
+ (0, import_react13.useEffect)(() => {
4743
4766
  if (!eventBus) {
4744
4767
  return;
4745
4768
  }
@@ -4807,9 +4830,26 @@ function PanoramaEventSurface() {
4807
4830
  );
4808
4831
  }
4809
4832
 
4833
+ // src/scenes-host.ts
4834
+ var import_react14 = require("react");
4835
+ var ScenesHostContext = (0, import_react14.createContext)(null);
4836
+ function createScenesHost() {
4837
+ return {
4838
+ controller: null,
4839
+ revision: 0,
4840
+ listeners: /* @__PURE__ */ new Set()
4841
+ };
4842
+ }
4843
+ function notifyScenesHost(host) {
4844
+ host.revision += 1;
4845
+ for (const listener of host.listeners) {
4846
+ listener();
4847
+ }
4848
+ }
4849
+
4810
4850
  // src/touch-controls.tsx
4811
4851
  var import_fiber8 = require("@react-three/fiber");
4812
- var import_react13 = require("react");
4852
+ var import_react15 = require("react");
4813
4853
  var DEFAULT_ROTATE_SPEED3 = 0.35;
4814
4854
  function resolveSpeed3(value, fallback) {
4815
4855
  return Number.isFinite(value) && value >= 0 ? value : fallback;
@@ -4824,16 +4864,16 @@ function TouchControls({
4824
4864
  pinchZoom = true
4825
4865
  }) {
4826
4866
  useClaimControlChannel("touch");
4827
- const controlsRef = (0, import_react13.useContext)(PanoramaViewContext);
4867
+ const controlsRef = (0, import_react15.useContext)(PanoramaViewContext);
4828
4868
  const { gl } = (0, import_fiber8.useThree)();
4829
- const pointersRef = (0, import_react13.useRef)(/* @__PURE__ */ new Map());
4830
- const pinchDistanceRef = (0, import_react13.useRef)(null);
4831
- const optionsRef = (0, import_react13.useRef)({ rotateSpeed, invert, pinchZoom });
4869
+ const pointersRef = (0, import_react15.useRef)(/* @__PURE__ */ new Map());
4870
+ const pinchDistanceRef = (0, import_react15.useRef)(null);
4871
+ const optionsRef = (0, import_react15.useRef)({ rotateSpeed, invert, pinchZoom });
4832
4872
  if (!controlsRef) {
4833
4873
  throw new Error("<TouchControls> must be rendered inside <PanoViewer>.");
4834
4874
  }
4835
4875
  optionsRef.current = { rotateSpeed, invert, pinchZoom };
4836
- (0, import_react13.useEffect)(() => {
4876
+ (0, import_react15.useEffect)(() => {
4837
4877
  const element = gl.domElement;
4838
4878
  const clearPointers = () => {
4839
4879
  for (const pointerId of pointersRef.current.keys()) {
@@ -4955,17 +4995,17 @@ function TouchControls({
4955
4995
  }
4956
4996
 
4957
4997
  // src/video/chrome-overlay.tsx
4958
- var import_react14 = require("react");
4998
+ var import_react16 = require("react");
4959
4999
  var import_jsx_runtime5 = require("react/jsx-runtime");
4960
- var PanoChromeOverlayContext = (0, import_react14.createContext)(null);
5000
+ var PanoChromeOverlayContext = (0, import_react16.createContext)(null);
4961
5001
  function usePanoChromeOverlay() {
4962
- const [overlayElement, setOverlayElement] = (0, import_react14.useState)(
5002
+ const [overlayElement, setOverlayElement] = (0, import_react16.useState)(
4963
5003
  null
4964
5004
  );
4965
- const setOverlayNode = (0, import_react14.useCallback)((node) => {
5005
+ const setOverlayNode = (0, import_react16.useCallback)((node) => {
4966
5006
  setOverlayElement(node);
4967
5007
  }, []);
4968
- const api = (0, import_react14.useMemo)(
5008
+ const api = (0, import_react16.useMemo)(
4969
5009
  () => ({ overlayElement }),
4970
5010
  [overlayElement]
4971
5011
  );
@@ -4981,9 +5021,9 @@ function usePanoChromeOverlay() {
4981
5021
  }
4982
5022
 
4983
5023
  // src/video/host.ts
4984
- var import_react15 = require("react");
4985
- var PanoVideoHostContext = (0, import_react15.createContext)(null);
4986
- var DefaultPanoVideoControlsContext = (0, import_react15.createContext)(false);
5024
+ var import_react17 = require("react");
5025
+ var PanoVideoHostContext = (0, import_react17.createContext)(null);
5026
+ var DefaultPanoVideoControlsContext = (0, import_react17.createContext)(false);
4987
5027
  function createPanoVideoHost() {
4988
5028
  return {
4989
5029
  controller: null,
@@ -5014,8 +5054,8 @@ function isProduction3() {
5014
5054
  return nodeEnv === "production";
5015
5055
  }
5016
5056
  function useClaimPanoVideoControls() {
5017
- const host = (0, import_react15.useContext)(PanoVideoHostContext);
5018
- const isDefault = (0, import_react15.useContext)(DefaultPanoVideoControlsContext);
5057
+ const host = (0, import_react17.useContext)(PanoVideoHostContext);
5058
+ const isDefault = (0, import_react17.useContext)(DefaultPanoVideoControlsContext);
5019
5059
  if (!host || isDefault) {
5020
5060
  return;
5021
5061
  }
@@ -5028,10 +5068,10 @@ function useClaimPanoVideoControls() {
5028
5068
  }
5029
5069
 
5030
5070
  // src/video/pano-video-chrome-bridge.tsx
5031
- var import_react18 = require("react");
5071
+ var import_react20 = require("react");
5032
5072
 
5033
5073
  // src/video/pano-video-captions.tsx
5034
- var import_react16 = require("react");
5074
+ var import_react18 = require("react");
5035
5075
  var import_jsx_runtime6 = require("react/jsx-runtime");
5036
5076
  var DEFAULT_PANO_VIDEO_CAPTION_APPEARANCE = {
5037
5077
  color: "#ffffff",
@@ -5055,7 +5095,7 @@ function resolvePanoVideoCaptionAppearance(appearance) {
5055
5095
  function PanoVideoCaptionsOverlay({
5056
5096
  controller
5057
5097
  }) {
5058
- const snapshot = (0, import_react16.useSyncExternalStore)(
5098
+ const snapshot = (0, import_react18.useSyncExternalStore)(
5059
5099
  controller.subscribe,
5060
5100
  controller.getSnapshot,
5061
5101
  controller.getSnapshot
@@ -5097,7 +5137,7 @@ function PanoVideoCaptions({
5097
5137
  }
5098
5138
 
5099
5139
  // src/video/pano-video-controls.tsx
5100
- var import_react17 = require("react");
5140
+ var import_react19 = require("react");
5101
5141
 
5102
5142
  // src/video/format.ts
5103
5143
  var DEFAULT_PANO_VIDEO_PLAYBACK_RATES = [0.5, 1, 1.25, 1.5, 2];
@@ -5549,7 +5589,7 @@ function VerticalVolumeSlider({
5549
5589
  onVolume,
5550
5590
  volume
5551
5591
  }) {
5552
- const trackRef = (0, import_react17.useRef)(null);
5592
+ const trackRef = (0, import_react19.useRef)(null);
5553
5593
  const applyPointer = (event) => {
5554
5594
  const track = trackRef.current;
5555
5595
  if (!track) {
@@ -5685,14 +5725,14 @@ function VolumeControl({
5685
5725
  volume,
5686
5726
  volumeAdjustable
5687
5727
  }) {
5688
- const rootRef = (0, import_react17.useRef)(null);
5689
- const [open, setOpen] = (0, import_react17.useState)(false);
5728
+ const rootRef = (0, import_react19.useRef)(null);
5729
+ const [open, setOpen] = (0, import_react19.useState)(false);
5690
5730
  const displayVolume = muted ? 0 : volume;
5691
5731
  const mutedOrSilent = muted || volume === 0;
5692
- (0, import_react17.useEffect)(() => {
5732
+ (0, import_react19.useEffect)(() => {
5693
5733
  onOpenChange(open);
5694
5734
  }, [onOpenChange, open]);
5695
- (0, import_react17.useEffect)(() => {
5735
+ (0, import_react19.useEffect)(() => {
5696
5736
  if (!open || !volumeAdjustable || hasFinePointerHover()) {
5697
5737
  return;
5698
5738
  }
@@ -5779,24 +5819,24 @@ function PanoVideoControlsHud({
5779
5819
  fullscreen,
5780
5820
  overlayElement
5781
5821
  }) {
5782
- const resolved = (0, import_react17.useMemo)(
5822
+ const resolved = (0, import_react19.useMemo)(
5783
5823
  () => resolveControlsAppearance(appearance),
5784
5824
  [appearance]
5785
5825
  );
5786
- const snapshot = (0, import_react17.useSyncExternalStore)(
5826
+ const snapshot = (0, import_react19.useSyncExternalStore)(
5787
5827
  controller.subscribe,
5788
5828
  controller.getSnapshot,
5789
5829
  controller.getSnapshot
5790
5830
  );
5791
- const [menu, setMenu] = (0, import_react17.useState)(null);
5792
- const [captionsPanel, setCaptionsPanel] = (0, import_react17.useState)("tracks");
5793
- const [visible, setVisible] = (0, import_react17.useState)(true);
5794
- const [volumeOpen, setVolumeOpen] = (0, import_react17.useState)(false);
5795
- const [overlayWidth, setOverlayWidth] = (0, import_react17.useState)(
5831
+ const [menu, setMenu] = (0, import_react19.useState)(null);
5832
+ const [captionsPanel, setCaptionsPanel] = (0, import_react19.useState)("tracks");
5833
+ const [visible, setVisible] = (0, import_react19.useState)(true);
5834
+ const [volumeOpen, setVolumeOpen] = (0, import_react19.useState)(false);
5835
+ const [overlayWidth, setOverlayWidth] = (0, import_react19.useState)(
5796
5836
  () => overlayElement.clientWidth
5797
5837
  );
5798
- const idleTimerRef = (0, import_react17.useRef)(0);
5799
- const barId = (0, import_react17.useId)();
5838
+ const idleTimerRef = (0, import_react19.useRef)(0);
5839
+ const barId = (0, import_react19.useId)();
5800
5840
  const rateMenuId = `${barId}-rate`;
5801
5841
  const variantMenuId = `${barId}-variant`;
5802
5842
  const captionsMenuId = `${barId}-captions`;
@@ -5804,7 +5844,7 @@ function PanoVideoControlsHud({
5804
5844
  const compact = overlayWidth < COMPACT_CONTROLS_WIDTH;
5805
5845
  const hideTime = overlayWidth < NARROW_CONTROLS_WIDTH;
5806
5846
  const showFullscreen = isFullscreenEnabled();
5807
- const bumpVisibility = (0, import_react17.useCallback)(
5847
+ const bumpVisibility = (0, import_react19.useCallback)(
5808
5848
  (playing) => {
5809
5849
  setVisible(true);
5810
5850
  window.clearTimeout(idleTimerRef.current);
@@ -5817,7 +5857,7 @@ function PanoVideoControlsHud({
5817
5857
  },
5818
5858
  [menu, volumeOpen]
5819
5859
  );
5820
- (0, import_react17.useEffect)(() => {
5860
+ (0, import_react19.useEffect)(() => {
5821
5861
  if (typeof ResizeObserver === "undefined") {
5822
5862
  return;
5823
5863
  }
@@ -5832,15 +5872,15 @@ function PanoVideoControlsHud({
5832
5872
  observer.disconnect();
5833
5873
  };
5834
5874
  }, [overlayElement]);
5835
- (0, import_react17.useEffect)(() => {
5875
+ (0, import_react19.useEffect)(() => {
5836
5876
  if (!compact && menu === "more") {
5837
5877
  setMenu(null);
5838
5878
  }
5839
5879
  }, [compact, menu]);
5840
- (0, import_react17.useEffect)(() => {
5880
+ (0, import_react19.useEffect)(() => {
5841
5881
  bumpVisibility(snapshot.playing);
5842
5882
  }, [bumpVisibility, snapshot.playing]);
5843
- (0, import_react17.useEffect)(() => {
5883
+ (0, import_react19.useEffect)(() => {
5844
5884
  const root = overlayElement.parentElement;
5845
5885
  if (!root) {
5846
5886
  return;
@@ -5899,7 +5939,7 @@ function PanoVideoControlsHud({
5899
5939
  document.removeEventListener("pointerdown", handlePointerDown, true);
5900
5940
  };
5901
5941
  }, [bumpVisibility, controller, menu, overlayElement, snapshot.playing, volumeOpen]);
5902
- (0, import_react17.useEffect)(
5942
+ (0, import_react19.useEffect)(
5903
5943
  () => () => {
5904
5944
  window.clearTimeout(idleTimerRef.current);
5905
5945
  },
@@ -6190,7 +6230,7 @@ function PanoVideoControlsHud({
6190
6230
  }
6191
6231
  function PanoVideoControls({ appearance }) {
6192
6232
  useClaimPanoVideoControls();
6193
- const host = (0, import_react17.useContext)(PanoVideoHostContext);
6233
+ const host = (0, import_react19.useContext)(PanoVideoHostContext);
6194
6234
  if (host && appearance) {
6195
6235
  host.controls = appearance;
6196
6236
  }
@@ -6204,7 +6244,7 @@ function PanoVideoChromeBridge({
6204
6244
  host,
6205
6245
  overlayElement
6206
6246
  }) {
6207
- (0, import_react18.useSyncExternalStore)(
6247
+ (0, import_react20.useSyncExternalStore)(
6208
6248
  (onStoreChange) => subscribePanoVideoHost(host, onStoreChange),
6209
6249
  () => getPanoVideoHostRevision(host),
6210
6250
  () => getPanoVideoHostRevision(host)
@@ -6228,11 +6268,11 @@ function PanoVideoChromeBridge({
6228
6268
  }
6229
6269
 
6230
6270
  // src/webvr/chrome.tsx
6231
- var import_react20 = require("react");
6271
+ var import_react22 = require("react");
6232
6272
 
6233
6273
  // src/webvr/host.ts
6234
- var import_react19 = require("react");
6235
- var WebVRRuntimeContext = (0, import_react19.createContext)(null);
6274
+ var import_react21 = require("react");
6275
+ var WebVRRuntimeContext = (0, import_react21.createContext)(null);
6236
6276
  function createWebVRHost() {
6237
6277
  return {
6238
6278
  controller: null,
@@ -6503,7 +6543,7 @@ function SetupPanel({
6503
6543
  );
6504
6544
  }
6505
6545
  function WebVRChromeBridge({ host }) {
6506
- (0, import_react20.useSyncExternalStore)(
6546
+ (0, import_react22.useSyncExternalStore)(
6507
6547
  (listener) => subscribeWebVRHost(host, listener),
6508
6548
  () => host.revision,
6509
6549
  () => host.revision
@@ -6587,12 +6627,12 @@ function projectStereoHtmlPosition(el, camera, size, eye) {
6587
6627
  // src/webvr/xr-origin.tsx
6588
6628
  var import_fiber9 = require("@react-three/fiber");
6589
6629
  var import_xr2 = require("@react-three/xr");
6590
- var import_react21 = require("react");
6630
+ var import_react23 = require("react");
6591
6631
  var import_three5 = require("three");
6592
6632
  var import_jsx_runtime10 = require("react/jsx-runtime");
6593
6633
  function PanoramaXROrigin() {
6594
- const originRef = (0, import_react21.useRef)(null);
6595
- const localHeadPositionRef = (0, import_react21.useRef)(new import_three5.Vector3());
6634
+ const originRef = (0, import_react23.useRef)(null);
6635
+ const localHeadPositionRef = (0, import_react23.useRef)(new import_three5.Vector3());
6596
6636
  const session2 = (0, import_xr2.useXR)((state) => state.session);
6597
6637
  const gl = (0, import_fiber9.useThree)((state) => state.gl);
6598
6638
  (0, import_fiber9.useFrame)(() => {
@@ -6657,7 +6697,7 @@ function PanoCursorTree({
6657
6697
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PanoCursorController, { cursors, children });
6658
6698
  }
6659
6699
  function PanoVideoHostReset() {
6660
- const host = (0, import_react22.useContext)(PanoVideoHostContext);
6700
+ const host = (0, import_react24.useContext)(PanoVideoHostContext);
6661
6701
  if (host) {
6662
6702
  host.controlClaims = 0;
6663
6703
  }
@@ -6670,7 +6710,7 @@ function DefaultControlChannels({
6670
6710
  keyboardChannel,
6671
6711
  fovSpeed
6672
6712
  }) {
6673
- const claims = (0, import_react22.useContext)(ControlClaimsContext);
6713
+ const claims = (0, import_react24.useContext)(ControlClaimsContext);
6674
6714
  if (!claims) {
6675
6715
  return null;
6676
6716
  }
@@ -6686,7 +6726,7 @@ function DefaultControlChannels({
6686
6726
  ) : null
6687
6727
  ] });
6688
6728
  }
6689
- var PanoViewer = (0, import_react22.forwardRef)(
6729
+ var PanoViewer = (0, import_react24.forwardRef)(
6690
6730
  function PanoViewer2({
6691
6731
  children,
6692
6732
  initialView,
@@ -6704,17 +6744,19 @@ var PanoViewer = (0, import_react22.forwardRef)(
6704
6744
  "aria-label": ariaLabel = "Panorama viewer",
6705
6745
  ...divProps
6706
6746
  }, ref) {
6707
- const rootRef = (0, import_react22.useRef)(null);
6708
- const controlsRef = (0, import_react22.useRef)(null);
6709
- const eventBus = (0, import_react22.useMemo)(() => createPanoEventBus(), []);
6747
+ const rootRef = (0, import_react24.useRef)(null);
6748
+ const controlsRef = (0, import_react24.useRef)(null);
6749
+ const eventBus = (0, import_react24.useMemo)(() => createPanoEventBus(), []);
6710
6750
  const { controls: hotspotAccessibilityControls, registry } = useHotspotAccessibilityLayer();
6711
6751
  const { api: contextMenuOverlayApi, overlay: contextMenuOverlay } = usePanoContextMenuOverlay();
6712
6752
  const { api: chromeOverlayApi, setOverlayNode, overlayElement } = usePanoChromeOverlay();
6713
- const videoHost = (0, import_react22.useMemo)(() => createPanoVideoHost(), []);
6714
- const filterHost = (0, import_react22.useMemo)(() => createPanoFilterHost(), []);
6715
- const webVRHost = (0, import_react22.useMemo)(() => createWebVRHost(), []);
6716
- const stereoView = (0, import_react22.useMemo)(() => createWebVRStereoView(), []);
6717
- const xrStore = (0, import_react22.useMemo)(
6753
+ const videoHost = (0, import_react24.useMemo)(() => createPanoVideoHost(), []);
6754
+ const filterHost = (0, import_react24.useMemo)(() => createPanoFilterHost(), []);
6755
+ const webVRHost = (0, import_react24.useMemo)(() => createWebVRHost(), []);
6756
+ const scenesHost = (0, import_react24.useMemo)(() => createScenesHost(), []);
6757
+ const bgmHost = (0, import_react24.useMemo)(() => createBackgroundAudioHost(), []);
6758
+ const stereoView = (0, import_react24.useMemo)(() => createWebVRStereoView(), []);
6759
+ const xrStore = (0, import_react24.useMemo)(
6718
6760
  () => (0, import_xr3.createXRStore)({
6719
6761
  anchors: false,
6720
6762
  bodyTracking: false,
@@ -6730,13 +6772,13 @@ var PanoViewer = (0, import_react22.forwardRef)(
6730
6772
  }),
6731
6773
  []
6732
6774
  );
6733
- const fallbackViewRef = (0, import_react22.useRef)(DEFAULT_VIEW);
6775
+ const fallbackViewRef = (0, import_react24.useRef)(DEFAULT_VIEW);
6734
6776
  const normalizedMinFov = Math.max(1, Math.min(minFov, maxFov - 1));
6735
6777
  const normalizedMaxFov = Math.min(
6736
6778
  179,
6737
6779
  Math.max(maxFov, normalizedMinFov + 1)
6738
6780
  );
6739
- const normalizedInitialView = (0, import_react22.useMemo)(
6781
+ const normalizedInitialView = (0, import_react24.useMemo)(
6740
6782
  () => ({
6741
6783
  yaw: initialView?.yaw ?? DEFAULT_VIEW.yaw,
6742
6784
  pitch: clampPanoPitch(initialView?.pitch ?? DEFAULT_VIEW.pitch),
@@ -6754,10 +6796,10 @@ var PanoViewer = (0, import_react22.forwardRef)(
6754
6796
  ]
6755
6797
  );
6756
6798
  fallbackViewRef.current = normalizedInitialView;
6757
- const controlClaims = (0, import_react22.useMemo)(() => createControlClaims(), []);
6799
+ const controlClaims = (0, import_react24.useMemo)(() => createControlClaims(), []);
6758
6800
  resetControlClaims(controlClaims);
6759
6801
  const controlsEnabled = controls !== false;
6760
- const controlOptions = (0, import_react22.useMemo)(
6802
+ const controlOptions = (0, import_react24.useMemo)(
6761
6803
  () => typeof controls === "object" ? controls : {},
6762
6804
  [controls]
6763
6805
  );
@@ -6765,7 +6807,7 @@ var PanoViewer = (0, import_react22.forwardRef)(
6765
6807
  const allModeInvert = controlOptions.invert === true;
6766
6808
  const topRotateSpeed = controlOptions.rotateSpeed ?? DEFAULT_POINTER_ROTATE_SPEED;
6767
6809
  const topZoomSpeed = controlOptions.zoomSpeed ?? DEFAULT_MOUSE_ZOOM_SPEED;
6768
- const mouseChannel = (0, import_react22.useMemo)(
6810
+ const mouseChannel = (0, import_react24.useMemo)(
6769
6811
  () => resolveChannel(controlOptions.mouse, {
6770
6812
  enabled: true,
6771
6813
  rotateSpeed: topRotateSpeed,
@@ -6781,7 +6823,7 @@ var PanoViewer = (0, import_react22.forwardRef)(
6781
6823
  topZoomSpeed
6782
6824
  ]
6783
6825
  );
6784
- const touchChannel = (0, import_react22.useMemo)(
6826
+ const touchChannel = (0, import_react24.useMemo)(
6785
6827
  () => resolveChannel(controlOptions.touch, {
6786
6828
  enabled: true,
6787
6829
  rotateSpeed: topRotateSpeed,
@@ -6790,13 +6832,35 @@ var PanoViewer = (0, import_react22.forwardRef)(
6790
6832
  }),
6791
6833
  [allModeInvert, controlOptions.touch, topRotateSpeed]
6792
6834
  );
6793
- const keyboardChannel = (0, import_react22.useMemo)(
6835
+ const keyboardChannel = (0, import_react24.useMemo)(
6794
6836
  () => resolveChannel(controlOptions.keyboard, {
6795
6837
  enabled: true
6796
6838
  }),
6797
6839
  [controlOptions.keyboard]
6798
6840
  );
6799
- const toggleFullscreen = (0, import_react22.useCallback)(async () => {
6841
+ const enterFullscreen = (0, import_react24.useCallback)(async () => {
6842
+ if (typeof document === "undefined") {
6843
+ return;
6844
+ }
6845
+ if (getFullscreenElement()) {
6846
+ return;
6847
+ }
6848
+ const root = rootRef.current;
6849
+ if (!root) {
6850
+ return;
6851
+ }
6852
+ await requestElementFullscreen(root);
6853
+ }, []);
6854
+ const exitFullscreen = (0, import_react24.useCallback)(async () => {
6855
+ if (typeof document === "undefined") {
6856
+ return;
6857
+ }
6858
+ if (!getFullscreenElement()) {
6859
+ return;
6860
+ }
6861
+ await exitElementFullscreen();
6862
+ }, []);
6863
+ const toggleFullscreen = (0, import_react24.useCallback)(async () => {
6800
6864
  if (typeof document === "undefined") {
6801
6865
  return;
6802
6866
  }
@@ -6810,8 +6874,8 @@ var PanoViewer = (0, import_react22.forwardRef)(
6810
6874
  }
6811
6875
  await requestElementFullscreen(root);
6812
6876
  }, []);
6813
- const [isViewerFullscreen, setIsViewerFullscreen] = (0, import_react22.useState)(false);
6814
- (0, import_react22.useEffect)(() => {
6877
+ const [isViewerFullscreen, setIsViewerFullscreen] = (0, import_react24.useState)(false);
6878
+ (0, import_react24.useEffect)(() => {
6815
6879
  if (typeof document === "undefined") {
6816
6880
  return;
6817
6881
  }
@@ -6829,7 +6893,7 @@ var PanoViewer = (0, import_react22.forwardRef)(
6829
6893
  syncFullscreen();
6830
6894
  return subscribeFullscreenChange(syncFullscreen);
6831
6895
  }, []);
6832
- (0, import_react22.useEffect)(() => {
6896
+ (0, import_react24.useEffect)(() => {
6833
6897
  const root = rootRef.current;
6834
6898
  if (!root) {
6835
6899
  return;
@@ -6842,7 +6906,7 @@ var PanoViewer = (0, import_react22.forwardRef)(
6842
6906
  root.removeEventListener("contextmenu", suppressNativeContextMenu, true);
6843
6907
  };
6844
6908
  }, []);
6845
- const contextMenuActions = (0, import_react22.useMemo)(
6909
+ const contextMenuActions = (0, import_react24.useMemo)(
6846
6910
  () => ({
6847
6911
  reset: () => {
6848
6912
  controlsRef.current?.reset();
@@ -6854,24 +6918,27 @@ var PanoViewer = (0, import_react22.forwardRef)(
6854
6918
  }),
6855
6919
  [isViewerFullscreen, toggleFullscreen]
6856
6920
  );
6857
- const contextMenuChannel = (0, import_react22.useMemo)(
6921
+ const contextMenuChannel = (0, import_react24.useMemo)(
6858
6922
  () => resolveContextMenuChannel(contextMenu),
6859
6923
  [contextMenu]
6860
6924
  );
6861
- const resolvedCursors = (0, import_react22.useMemo)(
6925
+ const resolvedCursors = (0, import_react24.useMemo)(
6862
6926
  () => resolvePanoCursors(cursors),
6863
6927
  [cursors]
6864
6928
  );
6865
6929
  const legacyAutoRotateOptions = controlOptions;
6866
- const [legacyAutoRotate, setLegacyAutoRotate] = (0, import_react22.useState)(
6930
+ const [legacyAutoRotate, setLegacyAutoRotate] = (0, import_react24.useState)(
6867
6931
  legacyAutoRotateOptions.autoRotate ?? false
6868
6932
  );
6869
- (0, import_react22.useEffect)(() => {
6933
+ (0, import_react24.useEffect)(() => {
6870
6934
  setLegacyAutoRotate(legacyAutoRotateOptions.autoRotate ?? false);
6871
6935
  }, [legacyAutoRotateOptions.autoRotate]);
6872
- (0, import_react22.useImperativeHandle)(
6936
+ const isFullscreenRef = (0, import_react24.useRef)(false);
6937
+ isFullscreenRef.current = isViewerFullscreen;
6938
+ (0, import_react24.useImperativeHandle)(
6873
6939
  ref,
6874
6940
  () => ({
6941
+ // -- View --
6875
6942
  getView: () => controlsRef.current?.getView() ?? { ...fallbackViewRef.current },
6876
6943
  setView: (view, options) => {
6877
6944
  controlsRef.current?.setView(view, options);
@@ -6879,17 +6946,67 @@ var PanoViewer = (0, import_react22.forwardRef)(
6879
6946
  reset: () => {
6880
6947
  controlsRef.current?.reset();
6881
6948
  },
6949
+ // -- Fullscreen --
6950
+ enterFullscreen,
6951
+ exitFullscreen,
6952
+ toggleFullscreen,
6953
+ isFullscreen: () => isFullscreenRef.current,
6954
+ // -- Scenes --
6955
+ setScene: (id) => scenesHost.controller?.setScene(id) ?? false,
6956
+ nextScene: () => scenesHost.controller?.nextScene() ?? false,
6957
+ previousScene: () => scenesHost.controller?.previousScene() ?? false,
6958
+ getActiveSceneId: () => scenesHost.controller?.getActiveSceneId() ?? null,
6959
+ getSceneIds: () => scenesHost.controller?.getSceneIds() ?? [],
6960
+ isSceneTransitioning: () => scenesHost.controller?.isTransitioning() ?? false,
6961
+ // -- WebVR --
6962
+ enterVR: () => webVRHost.controller?.enterVR() ?? Promise.resolve(false),
6963
+ exitVR: () => webVRHost.controller?.exitVR() ?? Promise.resolve(),
6964
+ toggleVR: () => webVRHost.controller?.toggleVR() ?? Promise.resolve(false),
6965
+ isVRAvailable: () => webVRHost.snapshot.available,
6966
+ isVREnabled: () => webVRHost.snapshot.mode !== null,
6967
+ getVRMode: () => webVRHost.snapshot.mode,
6968
+ requestVRPermission: () => webVRHost.controller?.requestPermission() ?? Promise.resolve(false),
6969
+ // -- Video --
6970
+ getVideo: () => videoHost.controller,
6971
+ subscribeVideo: (onStoreChange) => subscribePanoVideoHost(videoHost, onStoreChange),
6972
+ playVideo: () => videoHost.controller?.play() ?? Promise.resolve(),
6973
+ pauseVideo: () => videoHost.controller?.pause(),
6974
+ toggleVideo: () => videoHost.controller?.togglePlay(),
6975
+ seekVideo: (time) => videoHost.controller?.seek(time),
6976
+ setVideoVolume: (vol) => videoHost.controller?.setVolume(vol),
6977
+ setVideoMuted: (m) => videoHost.controller?.setMuted(m),
6978
+ toggleVideoMuted: () => videoHost.controller?.toggleMuted(),
6979
+ // -- Background Audio --
6980
+ getBackgroundAudio: () => bgmHost.controller,
6981
+ subscribeBackgroundAudio: (onStoreChange) => subscribeBackgroundAudioHost(bgmHost, onStoreChange),
6982
+ playBackgroundAudio: () => {
6983
+ bgmHost.controller?.play();
6984
+ return Promise.resolve();
6985
+ },
6986
+ pauseBackgroundAudio: () => bgmHost.controller?.pause(),
6987
+ toggleBackgroundAudio: () => bgmHost.controller?.togglePlay(),
6988
+ setBackgroundAudioVolume: (vol) => bgmHost.controller?.setVolume(vol),
6989
+ setBackgroundAudioMuted: (m) => bgmHost.controller?.setMuted(m),
6990
+ toggleBackgroundAudioMuted: () => bgmHost.controller?.toggleMuted(),
6991
+ // -- Deprecated --
6882
6992
  startAutoRotate: () => {
6883
6993
  setLegacyAutoRotate(true);
6884
6994
  },
6885
6995
  stopAutoRotate: () => {
6886
6996
  setLegacyAutoRotate(false);
6887
- },
6888
- toggleFullscreen
6997
+ }
6889
6998
  }),
6890
- [toggleFullscreen]
6999
+ [
7000
+ bgmHost,
7001
+ enterFullscreen,
7002
+ exitFullscreen,
7003
+ scenesHost,
7004
+ toggleFullscreen,
7005
+ videoHost,
7006
+ webVRHost
7007
+ ]
6891
7008
  );
6892
- const rootStyle = (0, import_react22.useMemo)(
7009
+ const rootStyle = (0, import_react24.useMemo)(
6893
7010
  () => ({
6894
7011
  overflow: "hidden",
6895
7012
  position: "relative",
@@ -6939,11 +7056,11 @@ var PanoViewer = (0, import_react22.forwardRef)(
6939
7056
  PanoContextMenuOverlayContext.Provider,
6940
7057
  {
6941
7058
  value: contextMenuOverlayApi,
6942
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PanoChromeOverlayContext.Provider, { value: chromeOverlayApi, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PanoVideoHostContext.Provider, { value: videoHost, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PanoFilterHostContext.Provider, { value: filterHost, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
7059
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PanoChromeOverlayContext.Provider, { value: chromeOverlayApi, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PanoVideoHostContext.Provider, { value: videoHost, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PanoFilterHostContext.Provider, { value: filterHost, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
6943
7060
  PanoContextMenuActionsContext.Provider,
6944
7061
  {
6945
7062
  value: contextMenuActions,
6946
- children: [
7063
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ScenesHostContext.Provider, { value: scenesHost, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(BackgroundAudioHostContext.Provider, { value: bgmHost, children: [
6947
7064
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PanoVideoHostReset, {}),
6948
7065
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
6949
7066
  PanoramaViewRuntime,
@@ -6987,7 +7104,7 @@ var PanoViewer = (0, import_react22.forwardRef)(
6987
7104
  }
6988
7105
  )
6989
7106
  ] })
6990
- ]
7107
+ ] }) })
6991
7108
  }
6992
7109
  ) }) }) })
6993
7110
  }
@@ -7025,7 +7142,7 @@ var PanoViewer = (0, import_react22.forwardRef)(
7025
7142
  );
7026
7143
 
7027
7144
  // src/background-audio.tsx
7028
- var import_react23 = require("react");
7145
+ var import_react25 = require("react");
7029
7146
 
7030
7147
  // src/audio/howl.ts
7031
7148
  var import_howler = __toESM(require_howler());
@@ -7195,7 +7312,8 @@ function BackgroundAudio({
7195
7312
  src,
7196
7313
  sources,
7197
7314
  sceneId,
7198
- playing,
7315
+ playing: controlledPlaying,
7316
+ defaultPlaying = false,
7199
7317
  loop = true,
7200
7318
  muted = false,
7201
7319
  volume = 1,
@@ -7207,25 +7325,28 @@ function BackgroundAudio({
7207
7325
  onEnded,
7208
7326
  onError
7209
7327
  }) {
7210
- const controlsRef = (0, import_react23.useContext)(PanoramaViewContext);
7328
+ const controlsRef = (0, import_react25.useContext)(PanoramaViewContext);
7211
7329
  if (!controlsRef) {
7212
7330
  throw new Error("<BackgroundAudio> must be rendered inside <PanoViewer>.");
7213
7331
  }
7332
+ const isControlled = controlledPlaying !== void 0;
7333
+ const [internalPlaying, setInternalPlaying] = (0, import_react25.useState)(defaultPlaying);
7334
+ const playing = isControlled ? controlledPlaying : internalPlaying;
7214
7335
  const urls = resolveBackgroundAudioUrls(src, sources, sceneId);
7215
7336
  const trackKey = urls.join("\0");
7216
- const currentRef = (0, import_react23.useRef)(null);
7217
- const outgoingRef = (0, import_react23.useRef)([]);
7218
- const fadingInRef = (0, import_react23.useRef)(false);
7219
- const isFirstTrackRef = (0, import_react23.useRef)(true);
7220
- const playingRef = (0, import_react23.useRef)(playing);
7221
- const loopRef = (0, import_react23.useRef)(loop);
7222
- const mutedRef = (0, import_react23.useRef)(muted);
7223
- const volumeRef = (0, import_react23.useRef)(volume);
7224
- const fadeMsRef = (0, import_react23.useRef)(resolveFadeMs(fadeMs));
7225
- const onPlaybackStateChangeRef = (0, import_react23.useRef)(onPlaybackStateChange);
7226
- const onPlaybackErrorRef = (0, import_react23.useRef)(onPlaybackError);
7227
- const onEndedRef = (0, import_react23.useRef)(onEnded);
7228
- const onErrorRef = (0, import_react23.useRef)(onError);
7337
+ const currentRef = (0, import_react25.useRef)(null);
7338
+ const outgoingRef = (0, import_react25.useRef)([]);
7339
+ const fadingInRef = (0, import_react25.useRef)(false);
7340
+ const isFirstTrackRef = (0, import_react25.useRef)(true);
7341
+ const playingRef = (0, import_react25.useRef)(playing);
7342
+ const loopRef = (0, import_react25.useRef)(loop);
7343
+ const mutedRef = (0, import_react25.useRef)(muted);
7344
+ const volumeRef = (0, import_react25.useRef)(volume);
7345
+ const fadeMsRef = (0, import_react25.useRef)(resolveFadeMs(fadeMs));
7346
+ const onPlaybackStateChangeRef = (0, import_react25.useRef)(onPlaybackStateChange);
7347
+ const onPlaybackErrorRef = (0, import_react25.useRef)(onPlaybackError);
7348
+ const onEndedRef = (0, import_react25.useRef)(onEnded);
7349
+ const onErrorRef = (0, import_react25.useRef)(onError);
7229
7350
  playingRef.current = playing;
7230
7351
  loopRef.current = loop;
7231
7352
  mutedRef.current = muted;
@@ -7235,7 +7356,100 @@ function BackgroundAudio({
7235
7356
  onPlaybackErrorRef.current = onPlaybackError;
7236
7357
  onEndedRef.current = onEnded;
7237
7358
  onErrorRef.current = onError;
7238
- (0, import_react23.useEffect)(() => {
7359
+ const snapshotRef = (0, import_react25.useRef)({
7360
+ ready: false,
7361
+ playing: false,
7362
+ blocked: false,
7363
+ ended: false,
7364
+ muted,
7365
+ volume
7366
+ });
7367
+ const snapshotListenersRef = (0, import_react25.useRef)(/* @__PURE__ */ new Set());
7368
+ const notifySnapshot = (patch) => {
7369
+ const prev = snapshotRef.current;
7370
+ snapshotRef.current = { ...prev, ...patch };
7371
+ for (const listener of snapshotListenersRef.current) {
7372
+ listener();
7373
+ }
7374
+ };
7375
+ const isControlledRef = (0, import_react25.useRef)(isControlled);
7376
+ isControlledRef.current = isControlled;
7377
+ const controller = (0, import_react25.useMemo)(
7378
+ () => ({
7379
+ subscribe: (onStoreChange) => {
7380
+ snapshotListenersRef.current.add(onStoreChange);
7381
+ return () => {
7382
+ snapshotListenersRef.current.delete(onStoreChange);
7383
+ };
7384
+ },
7385
+ getSnapshot: () => snapshotRef.current,
7386
+ play: () => {
7387
+ if (isControlledRef.current) {
7388
+ return;
7389
+ }
7390
+ setInternalPlaying(true);
7391
+ },
7392
+ pause: () => {
7393
+ if (isControlledRef.current) {
7394
+ return;
7395
+ }
7396
+ setInternalPlaying(false);
7397
+ },
7398
+ togglePlay: () => {
7399
+ if (isControlledRef.current) {
7400
+ return;
7401
+ }
7402
+ setInternalPlaying((prev) => !prev);
7403
+ },
7404
+ setVolume: (vol) => {
7405
+ if (isControlledRef.current) {
7406
+ return;
7407
+ }
7408
+ const howl = currentRef.current?.handle.howl;
7409
+ if (howl) {
7410
+ howl.volume(clampAudioVolume(vol));
7411
+ }
7412
+ notifySnapshot({ volume: clampAudioVolume(vol) });
7413
+ },
7414
+ setMuted: (m) => {
7415
+ if (isControlledRef.current) {
7416
+ return;
7417
+ }
7418
+ const howl = currentRef.current?.handle.howl;
7419
+ if (howl) {
7420
+ howl.mute(m);
7421
+ }
7422
+ notifySnapshot({ muted: m });
7423
+ },
7424
+ toggleMuted: () => {
7425
+ if (isControlledRef.current) {
7426
+ return;
7427
+ }
7428
+ const next = !snapshotRef.current.muted;
7429
+ const howl = currentRef.current?.handle.howl;
7430
+ if (howl) {
7431
+ howl.mute(next);
7432
+ }
7433
+ notifySnapshot({ muted: next });
7434
+ }
7435
+ }),
7436
+ []
7437
+ );
7438
+ const bgmHost = (0, import_react25.useContext)(BackgroundAudioHostContext);
7439
+ (0, import_react25.useEffect)(() => {
7440
+ if (!bgmHost) {
7441
+ return;
7442
+ }
7443
+ bgmHost.controller = controller;
7444
+ notifyBackgroundAudioHost(bgmHost);
7445
+ return () => {
7446
+ if (bgmHost.controller === controller) {
7447
+ bgmHost.controller = null;
7448
+ notifyBackgroundAudioHost(bgmHost);
7449
+ }
7450
+ };
7451
+ }, [bgmHost, controller]);
7452
+ (0, import_react25.useEffect)(() => {
7239
7453
  return () => {
7240
7454
  fadingInRef.current = false;
7241
7455
  isFirstTrackRef.current = true;
@@ -7247,7 +7461,7 @@ function BackgroundAudio({
7247
7461
  outgoingRef.current = [];
7248
7462
  };
7249
7463
  }, []);
7250
- (0, import_react23.useEffect)(() => {
7464
+ (0, import_react25.useEffect)(() => {
7251
7465
  const previous = currentRef.current;
7252
7466
  if (previous?.key === trackKey && previous.crossOrigin === crossOrigin) {
7253
7467
  return;
@@ -7281,6 +7495,7 @@ function BackgroundAudio({
7281
7495
  isActive: () => currentRef.current?.key === trackKey,
7282
7496
  shouldRetryPlay: () => currentRef.current?.key === trackKey && playingRef.current,
7283
7497
  onEnded: () => {
7498
+ notifySnapshot({ playing: false, ended: true });
7284
7499
  onPlaybackStateChangeRef.current?.("ended");
7285
7500
  onEndedRef.current?.();
7286
7501
  },
@@ -7292,15 +7507,18 @@ function BackgroundAudio({
7292
7507
  durationMs
7293
7508
  );
7294
7509
  }
7510
+ notifySnapshot({ ready: true, playing: true, blocked: false, ended: false });
7295
7511
  onPlaybackStateChangeRef.current?.("playing");
7296
7512
  },
7297
7513
  onPause: () => {
7514
+ notifySnapshot({ playing: false });
7298
7515
  onPlaybackStateChangeRef.current?.("paused");
7299
7516
  },
7300
7517
  onLoadError: (error) => {
7301
7518
  onErrorRef.current?.({ error });
7302
7519
  },
7303
7520
  onPlayError: (error) => {
7521
+ notifySnapshot({ blocked: true });
7304
7522
  onPlaybackStateChangeRef.current?.("blocked");
7305
7523
  onPlaybackErrorRef.current?.(error);
7306
7524
  }
@@ -7343,7 +7561,7 @@ function BackgroundAudio({
7343
7561
  retire(previous);
7344
7562
  }
7345
7563
  }, [crossOrigin, trackKey]);
7346
- (0, import_react23.useEffect)(() => {
7564
+ (0, import_react25.useEffect)(() => {
7347
7565
  const howl = currentRef.current?.handle.howl;
7348
7566
  if (!howl) {
7349
7567
  return;
@@ -7359,7 +7577,7 @@ function BackgroundAudio({
7359
7577
  }
7360
7578
  howl.play();
7361
7579
  }, [playing, trackKey]);
7362
- (0, import_react23.useEffect)(() => {
7580
+ (0, import_react25.useEffect)(() => {
7363
7581
  const slot = currentRef.current;
7364
7582
  if (!slot) {
7365
7583
  return;
@@ -7369,8 +7587,9 @@ function BackgroundAudio({
7369
7587
  if (!fadingInRef.current) {
7370
7588
  slot.handle.howl.volume(clampAudioVolume(volume));
7371
7589
  }
7590
+ notifySnapshot({ muted, volume: clampAudioVolume(volume) });
7372
7591
  }, [loop, muted, trackKey, volume]);
7373
- (0, import_react23.useEffect)(() => {
7592
+ (0, import_react25.useEffect)(() => {
7374
7593
  if (!pauseWhenHidden) {
7375
7594
  return;
7376
7595
  }
@@ -7396,27 +7615,27 @@ function BackgroundAudio({
7396
7615
  }
7397
7616
 
7398
7617
  // src/pano-filter/pano-filter.tsx
7399
- var import_react24 = require("react");
7618
+ var import_react26 = require("react");
7400
7619
  function PanoFilter({
7401
7620
  preset = "none",
7402
7621
  intensity,
7403
7622
  enabled = true
7404
7623
  }) {
7405
- const host = (0, import_react24.useContext)(PanoFilterHostContext);
7624
+ const host = (0, import_react26.useContext)(PanoFilterHostContext);
7406
7625
  if (!host) {
7407
7626
  throw new Error("<PanoFilter> must be rendered inside <PanoViewer>.");
7408
7627
  }
7409
- const snapshot = (0, import_react24.useMemo)(
7628
+ const snapshot = (0, import_react26.useMemo)(
7410
7629
  () => resolvePanoFilterSnapshot({ preset, intensity, enabled }),
7411
7630
  [enabled, intensity, preset]
7412
7631
  );
7413
- (0, import_react24.useEffect)(() => {
7632
+ (0, import_react26.useEffect)(() => {
7414
7633
  claimPanoFilter(host);
7415
7634
  return () => {
7416
7635
  releasePanoFilter(host);
7417
7636
  };
7418
7637
  }, [host]);
7419
- (0, import_react24.useEffect)(() => {
7638
+ (0, import_react26.useEffect)(() => {
7420
7639
  setPanoFilterSnapshot(host, snapshot);
7421
7640
  }, [host, snapshot]);
7422
7641
  return null;
@@ -7424,7 +7643,7 @@ function PanoFilter({
7424
7643
 
7425
7644
  // src/gyro.tsx
7426
7645
  var import_fiber11 = require("@react-three/fiber");
7427
- var import_react25 = require("react");
7646
+ var import_react27 = require("react");
7428
7647
 
7429
7648
  // src/gyro-orientation.ts
7430
7649
  var import_three7 = require("three");
@@ -7509,7 +7728,7 @@ function resolveSoftstart(value) {
7509
7728
  function posesNearlyEqual(a, b) {
7510
7729
  return Math.abs(shortestYawDelta2(a.yaw, b.yaw)) < 1e-4 && Math.abs(a.pitch - b.pitch) < 1e-4 && Math.abs(a.roll - b.roll) < 1e-4;
7511
7730
  }
7512
- var Gyro = (0, import_react25.forwardRef)(function Gyro2({
7731
+ var Gyro = (0, import_react27.forwardRef)(function Gyro2({
7513
7732
  enabled = false,
7514
7733
  camroll = true,
7515
7734
  absolute = false,
@@ -7524,24 +7743,24 @@ var Gyro = (0, import_react25.forwardRef)(function Gyro2({
7524
7743
  onDisable,
7525
7744
  onDenied
7526
7745
  }, ref) {
7527
- const controlsRef = (0, import_react25.useContext)(PanoramaViewContext);
7528
- const eventBus = (0, import_react25.useContext)(PanoEventBusContext);
7746
+ const controlsRef = (0, import_react27.useContext)(PanoramaViewContext);
7747
+ const eventBus = (0, import_react27.useContext)(PanoEventBusContext);
7529
7748
  const { gl } = (0, import_fiber11.useThree)();
7530
- const [internallyDisabled, setInternallyDisabled] = (0, import_react25.useState)(false);
7531
- const availableRef = (0, import_react25.useRef)(false);
7532
- const availabilityReportedRef = (0, import_react25.useRef)(null);
7533
- const activeRef = (0, import_react25.useRef)(false);
7534
- const permissionRef = (0, import_react25.useRef)(deviceOrientationPermissionState);
7535
- const absoluteEventSourceRef = (0, import_react25.useRef)(null);
7536
- const rawQuaternionRef = (0, import_react25.useRef)(null);
7537
- const calibrationRef = (0, import_react25.useRef)(null);
7538
- const absoluteOffsetRef = (0, import_react25.useRef)({ yaw: 0, pitch: 0 });
7539
- const screenAngleRef = (0, import_react25.useRef)(getScreenOrientationAngle());
7540
- const startPoseRef = (0, import_react25.useRef)(null);
7541
- const enabledAtRef = (0, import_react25.useRef)(0);
7542
- const filteredPoseRef = (0, import_react25.useRef)(null);
7543
- const lastAppliedPoseRef = (0, import_react25.useRef)(null);
7544
- const callbacksRef = (0, import_react25.useRef)({
7749
+ const [internallyDisabled, setInternallyDisabled] = (0, import_react27.useState)(false);
7750
+ const availableRef = (0, import_react27.useRef)(false);
7751
+ const availabilityReportedRef = (0, import_react27.useRef)(null);
7752
+ const activeRef = (0, import_react27.useRef)(false);
7753
+ const permissionRef = (0, import_react27.useRef)(deviceOrientationPermissionState);
7754
+ const absoluteEventSourceRef = (0, import_react27.useRef)(null);
7755
+ const rawQuaternionRef = (0, import_react27.useRef)(null);
7756
+ const calibrationRef = (0, import_react27.useRef)(null);
7757
+ const absoluteOffsetRef = (0, import_react27.useRef)({ yaw: 0, pitch: 0 });
7758
+ const screenAngleRef = (0, import_react27.useRef)(getScreenOrientationAngle());
7759
+ const startPoseRef = (0, import_react27.useRef)(null);
7760
+ const enabledAtRef = (0, import_react27.useRef)(0);
7761
+ const filteredPoseRef = (0, import_react27.useRef)(null);
7762
+ const lastAppliedPoseRef = (0, import_react27.useRef)(null);
7763
+ const callbacksRef = (0, import_react27.useRef)({
7545
7764
  onAvailable,
7546
7765
  onUnavailable,
7547
7766
  onEnable,
@@ -7558,7 +7777,7 @@ var Gyro = (0, import_react25.forwardRef)(function Gyro2({
7558
7777
  if (!controlsRef) {
7559
7778
  throw new Error("<Gyro> must be rendered inside <PanoViewer>.");
7560
7779
  }
7561
- const emit = (0, import_react25.useCallback)(
7780
+ const emit = (0, import_react27.useCallback)(
7562
7781
  (type) => {
7563
7782
  eventBus?.emit(type, void 0);
7564
7783
  switch (type) {
@@ -7585,7 +7804,7 @@ var Gyro = (0, import_react25.forwardRef)(function Gyro2({
7585
7804
  },
7586
7805
  [eventBus]
7587
7806
  );
7588
- const setAvailable = (0, import_react25.useCallback)(
7807
+ const setAvailable = (0, import_react27.useCallback)(
7589
7808
  (available) => {
7590
7809
  availableRef.current = available;
7591
7810
  if (availabilityReportedRef.current === available) {
@@ -7596,7 +7815,7 @@ var Gyro = (0, import_react25.forwardRef)(function Gyro2({
7596
7815
  },
7597
7816
  [emit]
7598
7817
  );
7599
- const requestPermission = (0, import_react25.useCallback)(async () => {
7818
+ const requestPermission = (0, import_react27.useCallback)(async () => {
7600
7819
  if (!availableRef.current) {
7601
7820
  return false;
7602
7821
  }
@@ -7629,7 +7848,7 @@ var Gyro = (0, import_react25.forwardRef)(function Gyro2({
7629
7848
  emit("gyrodenied");
7630
7849
  return false;
7631
7850
  }, [emit, setAvailable]);
7632
- const deactivate = (0, import_react25.useCallback)(() => {
7851
+ const deactivate = (0, import_react27.useCallback)(() => {
7633
7852
  if (activeRef.current) {
7634
7853
  activeRef.current = false;
7635
7854
  controlsRef.current?.setGyroActive(false);
@@ -7641,7 +7860,7 @@ var Gyro = (0, import_react25.forwardRef)(function Gyro2({
7641
7860
  filteredPoseRef.current = null;
7642
7861
  lastAppliedPoseRef.current = null;
7643
7862
  }, [controlsRef, emit]);
7644
- const resetSensor = (0, import_react25.useCallback)(
7863
+ const resetSensor = (0, import_react27.useCallback)(
7645
7864
  (yaw, pitch) => {
7646
7865
  const rawQuaternion = rawQuaternionRef.current;
7647
7866
  if (!rawQuaternion) {
@@ -7676,7 +7895,7 @@ var Gyro = (0, import_react25.forwardRef)(function Gyro2({
7676
7895
  },
7677
7896
  [absolute, controlsRef, north]
7678
7897
  );
7679
- (0, import_react25.useImperativeHandle)(
7898
+ (0, import_react27.useImperativeHandle)(
7680
7899
  ref,
7681
7900
  () => ({
7682
7901
  resetSensor,
@@ -7686,22 +7905,22 @@ var Gyro = (0, import_react25.forwardRef)(function Gyro2({
7686
7905
  }),
7687
7906
  [requestPermission, resetSensor]
7688
7907
  );
7689
- (0, import_react25.useEffect)(() => {
7908
+ (0, import_react27.useEffect)(() => {
7690
7909
  if (!enabled) {
7691
7910
  setInternallyDisabled(false);
7692
7911
  }
7693
7912
  }, [enabled]);
7694
- (0, import_react25.useEffect)(() => {
7913
+ (0, import_react27.useEffect)(() => {
7695
7914
  const supported = typeof window !== "undefined" && window.isSecureContext && typeof DeviceOrientationEvent !== "undefined" && (desktopSupport || isMobileDevice());
7696
7915
  setAvailable(supported);
7697
7916
  return () => {
7698
7917
  availableRef.current = false;
7699
7918
  };
7700
7919
  }, [desktopSupport, setAvailable]);
7701
- (0, import_react25.useEffect)(() => {
7920
+ (0, import_react27.useEffect)(() => {
7702
7921
  controlsRef.current?.setGyroTouchMode(touchMode);
7703
7922
  }, [controlsRef, touchMode]);
7704
- (0, import_react25.useEffect)(() => {
7923
+ (0, import_react27.useEffect)(() => {
7705
7924
  if (!enabled || internallyDisabled || touchMode !== "disablegyro") {
7706
7925
  return;
7707
7926
  }
@@ -7715,7 +7934,7 @@ var Gyro = (0, import_react25.forwardRef)(function Gyro2({
7715
7934
  gl.domElement.removeEventListener("pointerdown", onPointerDown);
7716
7935
  };
7717
7936
  }, [enabled, gl, internallyDisabled, touchMode]);
7718
- (0, import_react25.useEffect)(() => {
7937
+ (0, import_react27.useEffect)(() => {
7719
7938
  if (!enabled || internallyDisabled || !availableRef.current) {
7720
7939
  deactivate();
7721
7940
  return;
@@ -7877,7 +8096,7 @@ var Gyro = (0, import_react25.forwardRef)(function Gyro2({
7877
8096
 
7878
8097
  // src/webvr/webvr.tsx
7879
8098
  var import_fiber14 = require("@react-three/fiber");
7880
- var import_react30 = require("react");
8099
+ var import_react32 = require("react");
7881
8100
 
7882
8101
  // src/webvr/detect.ts
7883
8102
  function isMobileVRDevice() {
@@ -7900,7 +8119,7 @@ async function detectWebVRCapabilities() {
7900
8119
 
7901
8120
  // src/webvr/reticle.tsx
7902
8121
  var import_fiber12 = require("@react-three/fiber");
7903
- var import_react26 = require("react");
8122
+ var import_react28 = require("react");
7904
8123
  var import_three8 = require("three");
7905
8124
  var import_jsx_runtime12 = require("react/jsx-runtime");
7906
8125
  var CENTER_NDC = new import_three8.Vector2(0, 0);
@@ -7986,13 +8205,13 @@ function WebVRReticle({
7986
8205
  dwellMs,
7987
8206
  visible
7988
8207
  }) {
7989
- const groupRef = (0, import_react26.useRef)(null);
7990
- const ringMeshRef = (0, import_react26.useRef)(null);
7991
- const directionRef = (0, import_react26.useRef)(new import_three8.Vector3());
7992
- const raycasterRef = (0, import_react26.useRef)(new import_three8.Raycaster());
7993
- const hoveredRef = (0, import_react26.useRef)(null);
7994
- const dwellRef = (0, import_react26.useRef)(0);
7995
- const clickedRef = (0, import_react26.useRef)(false);
8208
+ const groupRef = (0, import_react28.useRef)(null);
8209
+ const ringMeshRef = (0, import_react28.useRef)(null);
8210
+ const directionRef = (0, import_react28.useRef)(new import_three8.Vector3());
8211
+ const raycasterRef = (0, import_react28.useRef)(new import_three8.Raycaster());
8212
+ const hoveredRef = (0, import_react28.useRef)(null);
8213
+ const dwellRef = (0, import_react28.useRef)(0);
8214
+ const clickedRef = (0, import_react28.useRef)(false);
7996
8215
  const { camera, gl, scene } = (0, import_fiber12.useThree)();
7997
8216
  (0, import_fiber12.useFrame)((_, deltaSeconds) => {
7998
8217
  const group = groupRef.current;
@@ -8155,7 +8374,7 @@ function WebVRReticle({
8155
8374
 
8156
8375
  // src/webvr/stereo.tsx
8157
8376
  var import_fiber13 = require("@react-three/fiber");
8158
- var import_react27 = require("react");
8377
+ var import_react29 = require("react");
8159
8378
  var import_three9 = require("three");
8160
8379
  var vertexShader = `
8161
8380
  varying vec2 vUv;
@@ -8230,25 +8449,25 @@ function WebVRStereoRenderer({
8230
8449
  screensize
8231
8450
  }) {
8232
8451
  const { camera, gl } = (0, import_fiber13.useThree)();
8233
- const runtime = (0, import_react27.useContext)(WebVRRuntimeContext);
8234
- const fallbackStereoRef = (0, import_react27.useRef)(null);
8452
+ const runtime = (0, import_react29.useContext)(WebVRRuntimeContext);
8453
+ const fallbackStereoRef = (0, import_react29.useRef)(null);
8235
8454
  if (!fallbackStereoRef.current) {
8236
8455
  fallbackStereoRef.current = new import_three9.StereoCamera();
8237
8456
  }
8238
8457
  const stereo = runtime?.stereoView.stereo ?? fallbackStereoRef.current;
8239
- const stereoRef = (0, import_react27.useRef)(stereo);
8458
+ const stereoRef = (0, import_react29.useRef)(stereo);
8240
8459
  stereoRef.current = stereo;
8241
- const resources = (0, import_react27.useMemo)(createDistortionResources, []);
8242
- const drawingSizeRef = (0, import_react27.useRef)(new import_three9.Vector2());
8243
- const viewportRef = (0, import_react27.useRef)(new import_three9.Vector4());
8244
- const scissorRef = (0, import_react27.useRef)(new import_three9.Vector4());
8245
- const originalFovRef = (0, import_react27.useRef)(null);
8246
- const stereoActiveRef = (0, import_react27.useRef)(false);
8247
- const profileRef = (0, import_react27.useRef)(profile);
8248
- const screensizeRef = (0, import_react27.useRef)(screensize);
8460
+ const resources = (0, import_react29.useMemo)(createDistortionResources, []);
8461
+ const drawingSizeRef = (0, import_react29.useRef)(new import_three9.Vector2());
8462
+ const viewportRef = (0, import_react29.useRef)(new import_three9.Vector4());
8463
+ const scissorRef = (0, import_react29.useRef)(new import_three9.Vector4());
8464
+ const originalFovRef = (0, import_react29.useRef)(null);
8465
+ const stereoActiveRef = (0, import_react29.useRef)(false);
8466
+ const profileRef = (0, import_react29.useRef)(profile);
8467
+ const screensizeRef = (0, import_react29.useRef)(screensize);
8249
8468
  profileRef.current = profile;
8250
8469
  screensizeRef.current = screensize;
8251
- (0, import_react27.useEffect)(
8470
+ (0, import_react29.useEffect)(
8252
8471
  () => () => {
8253
8472
  resources.geometry.dispose();
8254
8473
  resources.material.dispose();
@@ -8256,7 +8475,7 @@ function WebVRStereoRenderer({
8256
8475
  },
8257
8476
  [resources]
8258
8477
  );
8259
- (0, import_react27.useEffect)(() => {
8478
+ (0, import_react29.useEffect)(() => {
8260
8479
  const originalRender = gl.render.bind(gl);
8261
8480
  gl.render = (sceneToRender, cameraToRender) => {
8262
8481
  if (!stereoActiveRef.current || !(cameraToRender instanceof import_three9.PerspectiveCamera)) {
@@ -8320,7 +8539,7 @@ function WebVRStereoRenderer({
8320
8539
  gl.render = originalRender;
8321
8540
  };
8322
8541
  }, [gl, resources]);
8323
- (0, import_react27.useEffect)(
8542
+ (0, import_react29.useEffect)(
8324
8543
  () => () => {
8325
8544
  if (runtime) {
8326
8545
  runtime.stereoView.active = false;
@@ -8355,7 +8574,7 @@ function WebVRStereoRenderer({
8355
8574
  }
8356
8575
 
8357
8576
  // src/webvr/pointerlock.ts
8358
- var import_react28 = require("react");
8577
+ var import_react30 = require("react");
8359
8578
  var POINTER_LOCK_CURSOR_ID = "webvr:pointerlock";
8360
8579
  async function requestWebVRPointerLock(element) {
8361
8580
  if (typeof document === "undefined") {
@@ -8388,11 +8607,11 @@ function exitWebVRPointerLock(element) {
8388
8607
  }
8389
8608
  function useWebVRPointerLock(enabled, element) {
8390
8609
  const cursor = usePanoCursor();
8391
- const cursorRef = (0, import_react28.useRef)(cursor);
8392
- const enabledRef = (0, import_react28.useRef)(enabled);
8610
+ const cursorRef = (0, import_react30.useRef)(cursor);
8611
+ const enabledRef = (0, import_react30.useRef)(enabled);
8393
8612
  cursorRef.current = cursor;
8394
8613
  enabledRef.current = enabled;
8395
- (0, import_react28.useEffect)(() => {
8614
+ (0, import_react30.useEffect)(() => {
8396
8615
  if (!enabled || !element) {
8397
8616
  return;
8398
8617
  }
@@ -8422,7 +8641,7 @@ function useWebVRPointerLock(enabled, element) {
8422
8641
  }
8423
8642
 
8424
8643
  // src/webvr/wakelock.ts
8425
- var import_react29 = require("react");
8644
+ var import_react31 = require("react");
8426
8645
 
8427
8646
  // src/webvr/wakelock-fallback.ts
8428
8647
  var WEBVR_WAKELOCK_FALLBACK_VIDEO_BASE64 = "AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDEAAAbBbW9vdgAAAGxtdmhkAAAAAAAAAAAAAAAAAAAD6AAAD4AAAQAAAQAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAxt0cmFrAAAAXHRraGQAAAADAAAAAAAAAAAAAAABAAAAAAAAAggAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAABAAAAAQAAAAAAAkZWR0cwAAABxlbHN0AAAAAAAAAAEAAAIIAAAEAAABAAAAAAKTbWRpYQAAACBtZGhkAAAAAAAAAAAAAAAAAAAyAAAAGgBVxAAAAAAALWhkbHIAAAAAAAAAAHZpZGUAAAAAAAAAAAAAAABWaWRlb0hhbmRsZXIAAAACPm1pbmYAAAAUdm1oZAAAAAEAAAAAAAAAAAAAACRkaW5mAAAAHGRyZWYAAAAAAAAAAQAAAAx1cmwgAAAAAQAAAf5zdGJsAAAAvnN0c2QAAAAAAAAAAQAAAK5hdmMxAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAABAAEABIAAAASAAAAAAAAAABFUxhdmM2Mi4xMS4xMDAgbGlieDI2NAAAAAAAAAAAAAAAGP//AAAANGF2Y0MBZAAK/+EAF2dkAAqs2V7ARAAAAwAEAAADAMg8SJZYAQAGaOvjyyLA/fj4AAAAABBwYXNwAAAAAQAAAAEAAAAUYnRydAAAAAAAADQ5AAAAAAAAABhzdHRzAAAAAAAAAAEAAAANAAACAAAAABRzdHNzAAAAAAAAAAEAAAABAAAAeGN0dHMAAAAAAAAADQAAAAEAAAQAAAAAAQAACgAAAAABAAAEAAAAAAEAAAAAAAAAAQAAAgAAAAABAAAKAAAAAAEAAAQAAAAAAQAAAAAAAAABAAACAAAAAAEAAAoAAAAAAQAABAAAAAABAAAAAAAAAAEAAAIAAAAAKHN0c2MAAAAAAAAAAgAAAAEAAAADAAAAAQAAAAUAAAABAAAAAQAAAEhzdHN6AAAAAAAAAAAAAAANAAACxQAAAAwAAAAMAAAADAAAAAwAAAASAAAADgAAAAwAAAAMAAAAEgAAAA4AAAAMAAAADAAAACRzdGNvAAAAAAAAAAUAAAcGAAAJ5wAAChUAAAo/AAAKbwAAAtF0cmFrAAAAXHRraGQAAAADAAAAAAAAAAAAAAACAAAAAAAAD4AAAAAAAAAAAAAAAAEBAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAkZWR0cwAAABxlbHN0AAAAAAAAAAEAAA+AAAAEAAABAAAAAAJJbWRpYQAAACBtZGhkAAAAAAAAAAAAAAAAAAAfQAAAgABVxAAAAAAALWhkbHIAAAAAAAAAAHNvdW4AAAAAAAAAAAAAAABTb3VuZEhhbmRsZXIAAAAB9G1pbmYAAAAQc21oZAAAAAAAAAAAAAAAJGRpbmYAAAAcZHJlZgAAAAAAAAABAAAADHVybCAAAAABAAABuHN0YmwAAAB+c3RzZAAAAAAAAAABAAAAbm1wNGEAAAAAAAAAAQAAAAAAAAAAAAEAEAAAAAAfQAAAAAAANmVzZHMAAAAAA4CAgCUAAgAEgICAF0AVAAAAAAAfQAAAARsFgICABRWIVuUABoCAgAECAAAAFGJ0cnQAAAAAAAAfQAAAARsAAAAYc3R0cwAAAAAAAAABAAAAIAAABAAAAAAoc3RzYwAAAAAAAAACAAAAAQAAAAEAAAABAAAABgAAABsAAAABAAAAlHN0c3oAAAAAAAAAAAAAACAAAAAVAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAChzdGNvAAAAAAAAAAYAAAbxAAAJ4wAAChEAAAo7AAAKawAACnsAAAAac2dwZAEAAAByb2xsAAAAAgAAAAH//wAAABxzYmdwAAAAAHJvbGwAAAABAAAAIAAAAAEAAABhdWR0YQAAAFltZXRhAAAAAAAAACFoZGxyAAAAAAAAAABtZGlyYXBwbAAAAAAAAAAAAAAAACxpbHN0AAAAJKl0b28AAAAcZGF0YQAAAAEAAAAATGF2ZjYyLjMuMTAwAAAACGZyZWUAAAP+bWRhdN4CAExhdmM2Mi4xMS4xMDAAAjBADgAAAq4GBf//qtxF6b3m2Ui3lizYINkj7u94MjY0IC0gY29yZSAxNjUgcjMyMjIgYjM1NjA1YSAtIEguMjY0L01QRUctNCBBVkMgY29kZWMgLSBDb3B5bGVmdCAyMDAzLTIwMjUgLSBodHRwOi8vd3d3LnZpZGVvbGFuLm9yZy94MjY0Lmh0bWwgLSBvcHRpb25zOiBjYWJhYz0xIHJlZj0zIGRlYmxvY2s9MTowOjAgYW5hbHlzZT0weDM6MHgxMTMgbWU9aGV4IHN1Ym1lPTcgcHN5PTEgcHN5X3JkPTEuMDA6MC4wMCBtaXhlZF9yZWY9MSBtZV9yYW5nZT0xNiBjaHJvbWFfbWU9MSB0cmVsbGlzPTEgOHg4ZGN0PTEgY3FtPTAgZGVhZHpvbmU9MjEsMTEgZmFzdF9wc2tpcD0xIGNocm9tYV9xcF9vZmZzZXQ9LTIgdGhyZWFkcz0xIGxvb2thaGVhZF90aHJlYWRzPTEgc2xpY2VkX3RocmVhZHM9MCBucj0wIGRlY2ltYXRlPTEgaW50ZXJsYWNlZD0wIGJsdXJheV9jb21wYXQ9MCBjb25zdHJhaW5lZF9pbnRyYT0wIGJmcmFtZXM9MyBiX3B5cmFtaWQ9MiBiX2FkYXB0PTEgYl9iaWFzPTAgZGlyZWN0PTEgd2VpZ2h0Yj0xIG9wZW5fZ29wPTAgd2VpZ2h0cD0yIGtleWludD0yNTAga2V5aW50X21pbj0yNSBzY2VuZWN1dD00MCBpbnRyYV9yZWZyZXNoPTAgcmNfbG9va2FoZWFkPTQwIHJjPWNyZiBtYnRyZWU9MSBjcmY9MjMuMCBxY29tcD0wLjYwIHFwbWluPTAgcXBtYXg9NjkgcXBzdGVwPTQgaXBfcmF0aW89MS40MCBhcT0xOjEuMDAAgAAAAA9liIQAO//+906/AptUwmEAAAAIQZokbEN//uAAAAAIQZ5CeIX/wYEBGCAHAAAACAGeYXRCv8SAAAAACAGeY2pCv8SBAAAADkGaaEmoQWiZTAhn//7hARggBwAAAApBnoZFESwv/8GBAAAACAGepXRCv8SBAAAACAGep2pCv8SAARggBwAAAA5BmqxJqEFsmUwIV//+wAAAAApBnspFFSwv/8GBAAAACAGe6XRCv8SAARggBwAAAAgBnutqQr/EgAEYIAcBGCAHARggBwEYIAcBGCAHARggBwEYIAcBGCAHARggBwEYIAcBGCAHARggBwEYIAcBGCAHARggBwEYIAcBGCAHARggBwEYIAcBGCAHARggBwEYIAcBGCAHARggBwEYIAcBGCAHARggBw==";
@@ -8556,7 +8775,7 @@ function releaseWebVRWakeLock() {
8556
8775
  stopFallbackVideo();
8557
8776
  }
8558
8777
  function useWebVRWakeLock(enabled) {
8559
- (0, import_react29.useEffect)(() => {
8778
+ (0, import_react31.useEffect)(() => {
8560
8779
  if (!enabled) {
8561
8780
  return;
8562
8781
  }
@@ -8586,7 +8805,7 @@ function initializeSettings(screensize, profile) {
8586
8805
  function getViewerElement(canvas) {
8587
8806
  return canvas.closest("[data-pano-viewer]") ?? canvas.parentElement ?? canvas;
8588
8807
  }
8589
- var WebVR = (0, import_react30.forwardRef)(function WebVR2({
8808
+ var WebVR = (0, import_react32.forwardRef)(function WebVR2({
8590
8809
  chrome = true,
8591
8810
  mobileVr = true,
8592
8811
  desktopSupport = false,
@@ -8604,24 +8823,24 @@ var WebVR = (0, import_react30.forwardRef)(function WebVR2({
8604
8823
  onDenied,
8605
8824
  onUnknownDevice
8606
8825
  }, ref) {
8607
- const runtime = (0, import_react30.useContext)(WebVRRuntimeContext);
8608
- const controlsRef = (0, import_react30.useContext)(PanoramaViewContext);
8609
- const eventBus = (0, import_react30.useContext)(PanoEventBusContext);
8826
+ const runtime = (0, import_react32.useContext)(WebVRRuntimeContext);
8827
+ const controlsRef = (0, import_react32.useContext)(PanoramaViewContext);
8828
+ const eventBus = (0, import_react32.useContext)(PanoEventBusContext);
8610
8829
  const gl = (0, import_fiber14.useThree)((state) => state.gl);
8611
- const gyroRef = (0, import_react30.useRef)(null);
8612
- const capabilitiesRef = (0, import_react30.useRef)({
8830
+ const gyroRef = (0, import_react32.useRef)(null);
8831
+ const capabilitiesRef = (0, import_react32.useRef)({
8613
8832
  mobile: false,
8614
8833
  sensor: false,
8615
8834
  webxr: false
8616
8835
  });
8617
- const availableRef = (0, import_react30.useRef)(false);
8618
- const modeRef = (0, import_react30.useRef)(null);
8619
- const webXRSessionRef = (0, import_react30.useRef)(null);
8620
- const [mode, setMode] = (0, import_react30.useState)(null);
8621
- const [settings, setSettings] = (0, import_react30.useState)(
8836
+ const availableRef = (0, import_react32.useRef)(false);
8837
+ const modeRef = (0, import_react32.useRef)(null);
8838
+ const webXRSessionRef = (0, import_react32.useRef)(null);
8839
+ const [mode, setMode] = (0, import_react32.useState)(null);
8840
+ const [settings, setSettings] = (0, import_react32.useState)(
8622
8841
  () => initializeSettings(screensize, profile)
8623
8842
  );
8624
- const callbacksRef = (0, import_react30.useRef)({
8843
+ const callbacksRef = (0, import_react32.useRef)({
8625
8844
  onAvailable,
8626
8845
  onDenied,
8627
8846
  onEnterVR,
@@ -8641,22 +8860,22 @@ var WebVR = (0, import_react30.forwardRef)(function WebVR2({
8641
8860
  throw new Error("<WebVR> must be rendered inside <PanoViewer>.");
8642
8861
  }
8643
8862
  const { host, xrStore } = runtime;
8644
- const resolvedProfile = (0, import_react30.useMemo)(
8863
+ const resolvedProfile = (0, import_react32.useMemo)(
8645
8864
  () => resolveWebVRProfile(profile, settings.profileId),
8646
8865
  [profile, settings.profileId]
8647
8866
  );
8648
- const reportDenied = (0, import_react30.useCallback)(
8867
+ const reportDenied = (0, import_react32.useCallback)(
8649
8868
  (error) => {
8650
8869
  eventBus.emit("vrdenied", { error });
8651
8870
  callbacksRef.current.onDenied?.(error);
8652
8871
  },
8653
8872
  [eventBus]
8654
8873
  );
8655
- const reportUnknownDevice = (0, import_react30.useCallback)(() => {
8874
+ const reportUnknownDevice = (0, import_react32.useCallback)(() => {
8656
8875
  eventBus.emit("vrunknowndevice", void 0);
8657
8876
  callbacksRef.current.onUnknownDevice?.();
8658
8877
  }, [eventBus]);
8659
- const activate = (0, import_react30.useCallback)(
8878
+ const activate = (0, import_react32.useCallback)(
8660
8879
  (nextMode) => {
8661
8880
  if (modeRef.current === nextMode) {
8662
8881
  return;
@@ -8671,7 +8890,7 @@ var WebVR = (0, import_react30.forwardRef)(function WebVR2({
8671
8890
  },
8672
8891
  [controlsRef, eventBus]
8673
8892
  );
8674
- const deactivate = (0, import_react30.useCallback)(
8893
+ const deactivate = (0, import_react32.useCallback)(
8675
8894
  (expectedMode) => {
8676
8895
  const previousMode = modeRef.current;
8677
8896
  if (!previousMode || expectedMode && previousMode !== expectedMode) {
@@ -8688,10 +8907,10 @@ var WebVR = (0, import_react30.forwardRef)(function WebVR2({
8688
8907
  },
8689
8908
  [controlsRef, eventBus, gl.domElement]
8690
8909
  );
8691
- const requestPermission = (0, import_react30.useCallback)(async () => {
8910
+ const requestPermission = (0, import_react32.useCallback)(async () => {
8692
8911
  return await gyroRef.current?.requestPermission() ?? false;
8693
8912
  }, []);
8694
- const enterVR = (0, import_react30.useCallback)(async () => {
8913
+ const enterVR = (0, import_react32.useCallback)(async () => {
8695
8914
  if (modeRef.current) {
8696
8915
  return true;
8697
8916
  }
@@ -8776,7 +8995,7 @@ var WebVR = (0, import_react30.forwardRef)(function WebVR2({
8776
8995
  wakelock,
8777
8996
  xrStore
8778
8997
  ]);
8779
- const exitVR = (0, import_react30.useCallback)(async () => {
8998
+ const exitVR = (0, import_react32.useCallback)(async () => {
8780
8999
  if (modeRef.current === "webxr") {
8781
9000
  const session2 = webXRSessionRef.current ?? xrStore.getState().session ?? null;
8782
9001
  if (session2) {
@@ -8791,14 +9010,14 @@ var WebVR = (0, import_react30.forwardRef)(function WebVR2({
8791
9010
  await exitElementFullscreen();
8792
9011
  }
8793
9012
  }, [deactivate, xrStore]);
8794
- const toggleVR = (0, import_react30.useCallback)(async () => {
9013
+ const toggleVR = (0, import_react32.useCallback)(async () => {
8795
9014
  if (modeRef.current) {
8796
9015
  await exitVR();
8797
9016
  return false;
8798
9017
  }
8799
9018
  return enterVR();
8800
9019
  }, [enterVR, exitVR]);
8801
- const updateSettings = (0, import_react30.useCallback)((next) => {
9020
+ const updateSettings = (0, import_react32.useCallback)((next) => {
8802
9021
  const normalized = {
8803
9022
  profileId: next.profileId,
8804
9023
  screensize: next.screensize === "auto" ? "auto" : Math.round(Math.max(3, Math.min(20, next.screensize)) * 10) / 10
@@ -8806,18 +9025,19 @@ var WebVR = (0, import_react30.forwardRef)(function WebVR2({
8806
9025
  setSettings(normalized);
8807
9026
  saveWebVRSettings(normalized);
8808
9027
  }, []);
8809
- const controller = (0, import_react30.useMemo)(
9028
+ const controller = (0, import_react32.useMemo)(
8810
9029
  () => ({
8811
9030
  closeSetup: () => updateWebVRHost(host, { setupOpen: false }),
8812
9031
  enterVR,
8813
9032
  exitVR,
8814
9033
  openSetup: () => updateWebVRHost(host, { setupOpen: true }),
9034
+ requestPermission,
8815
9035
  toggleVR,
8816
9036
  updateSettings
8817
9037
  }),
8818
- [enterVR, exitVR, host, toggleVR, updateSettings]
9038
+ [enterVR, exitVR, host, requestPermission, toggleVR, updateSettings]
8819
9039
  );
8820
- (0, import_react30.useImperativeHandle)(
9040
+ (0, import_react32.useImperativeHandle)(
8821
9041
  ref,
8822
9042
  () => ({
8823
9043
  enterVR,
@@ -8830,7 +9050,7 @@ var WebVR = (0, import_react30.forwardRef)(function WebVR2({
8830
9050
  }),
8831
9051
  [enterVR, exitVR, requestPermission, toggleVR]
8832
9052
  );
8833
- (0, import_react30.useEffect)(() => {
9053
+ (0, import_react32.useEffect)(() => {
8834
9054
  let active = true;
8835
9055
  void detectWebVRCapabilities().then((capabilities) => {
8836
9056
  if (!active) {
@@ -8852,7 +9072,7 @@ var WebVR = (0, import_react30.forwardRef)(function WebVR2({
8852
9072
  active = false;
8853
9073
  };
8854
9074
  }, [desktopSupport, eventBus, fakeSupport, host, mobileVr]);
8855
- (0, import_react30.useEffect)(() => {
9075
+ (0, import_react32.useEffect)(() => {
8856
9076
  host.controller = controller;
8857
9077
  return () => {
8858
9078
  if (host.controller === controller) {
@@ -8861,10 +9081,10 @@ var WebVR = (0, import_react30.forwardRef)(function WebVR2({
8861
9081
  }
8862
9082
  };
8863
9083
  }, [controller, host]);
8864
- (0, import_react30.useEffect)(() => {
9084
+ (0, import_react32.useEffect)(() => {
8865
9085
  updateWebVRHost(host, { chrome, mode, settings });
8866
9086
  }, [chrome, host, mode, settings]);
8867
- (0, import_react30.useEffect)(() => {
9087
+ (0, import_react32.useEffect)(() => {
8868
9088
  if (mode !== "fake") {
8869
9089
  return;
8870
9090
  }
@@ -8888,7 +9108,7 @@ var WebVR = (0, import_react30.forwardRef)(function WebVR2({
8888
9108
  document.removeEventListener("mousemove", onMouseMove);
8889
9109
  };
8890
9110
  }, [controlsRef, gl.domElement, mode, mousePointerLock]);
8891
- (0, import_react30.useEffect)(
9111
+ (0, import_react32.useEffect)(
8892
9112
  () => () => {
8893
9113
  const session2 = webXRSessionRef.current;
8894
9114
  if (session2) {
@@ -8942,7 +9162,7 @@ var WebVR = (0, import_react30.forwardRef)(function WebVR2({
8942
9162
 
8943
9163
  // src/sphere.tsx
8944
9164
  var import_fiber15 = require("@react-three/fiber");
8945
- var import_react32 = require("react");
9165
+ var import_react34 = require("react");
8946
9166
  var import_three10 = require("three");
8947
9167
 
8948
9168
  // src/asset-url.ts
@@ -8967,7 +9187,7 @@ function resolveUrlAgainstFile(fileUrl, path) {
8967
9187
  }
8968
9188
 
8969
9189
  // src/pano-filter/pano-basic-material.tsx
8970
- var import_react31 = require("react");
9190
+ var import_react33 = require("react");
8971
9191
 
8972
9192
  // src/pano-filter/shaders.ts
8973
9193
  var GLSL_FILTER_COMMON = `
@@ -9127,13 +9347,13 @@ function PanoBasicMaterial({
9127
9347
  toneMapped = false
9128
9348
  }) {
9129
9349
  const snapshot = usePanoFilterSnapshot();
9130
- const materialRef = (0, import_react31.useRef)(null);
9131
- const intensityRef = (0, import_react31.useRef)(snapshot.intensity);
9132
- const intensityUniformRef = (0, import_react31.useRef)(null);
9350
+ const materialRef = (0, import_react33.useRef)(null);
9351
+ const intensityRef = (0, import_react33.useRef)(snapshot.intensity);
9352
+ const intensityUniformRef = (0, import_react33.useRef)(null);
9133
9353
  intensityRef.current = snapshot.intensity;
9134
9354
  const active = isPanoFilterActive(snapshot);
9135
9355
  const preset = snapshot.preset;
9136
- const onBeforeCompile = (0, import_react31.useMemo)(() => {
9356
+ const onBeforeCompile = (0, import_react33.useMemo)(() => {
9137
9357
  if (!active || preset === "none") {
9138
9358
  return void 0;
9139
9359
  }
@@ -9150,7 +9370,7 @@ function PanoBasicMaterial({
9150
9370
  compile.toString = () => `pano-filter:${preset}`;
9151
9371
  return compile;
9152
9372
  }, [active, preset]);
9153
- (0, import_react31.useLayoutEffect)(() => {
9373
+ (0, import_react33.useLayoutEffect)(() => {
9154
9374
  if (!active) {
9155
9375
  intensityUniformRef.current = null;
9156
9376
  }
@@ -9160,7 +9380,7 @@ function PanoBasicMaterial({
9160
9380
  }
9161
9381
  material.needsUpdate = true;
9162
9382
  }, [active, preset]);
9163
- (0, import_react31.useLayoutEffect)(() => {
9383
+ (0, import_react33.useLayoutEffect)(() => {
9164
9384
  if (intensityUniformRef.current) {
9165
9385
  intensityUniformRef.current.value = snapshot.intensity;
9166
9386
  }
@@ -9183,12 +9403,12 @@ function PanoBasicMaterial({
9183
9403
  // src/sphere.tsx
9184
9404
  var import_jsx_runtime15 = require("react/jsx-runtime");
9185
9405
  function useEquirectTexture(url, anisotropy, generateMipmaps, onLoad, onError) {
9186
- const [texture, setTexture] = (0, import_react32.useState)(null);
9187
- const onLoadRef = (0, import_react32.useRef)(onLoad);
9188
- const onErrorRef = (0, import_react32.useRef)(onError);
9406
+ const [texture, setTexture] = (0, import_react34.useState)(null);
9407
+ const onLoadRef = (0, import_react34.useRef)(onLoad);
9408
+ const onErrorRef = (0, import_react34.useRef)(onError);
9189
9409
  onLoadRef.current = onLoad;
9190
9410
  onErrorRef.current = onError;
9191
- (0, import_react32.useEffect)(() => {
9411
+ (0, import_react34.useEffect)(() => {
9192
9412
  if (!url) {
9193
9413
  setTexture(null);
9194
9414
  return;
@@ -9227,7 +9447,7 @@ function useEquirectTexture(url, anisotropy, generateMipmaps, onLoad, onError) {
9227
9447
  active = false;
9228
9448
  };
9229
9449
  }, [anisotropy, generateMipmaps, url]);
9230
- (0, import_react32.useEffect)(
9450
+ (0, import_react34.useEffect)(
9231
9451
  () => () => {
9232
9452
  texture?.dispose();
9233
9453
  },
@@ -9247,7 +9467,7 @@ function Sphere({
9247
9467
  }) {
9248
9468
  const gl = (0, import_fiber15.useThree)((state) => state.gl);
9249
9469
  const anisotropy = gl.capabilities.getMaxAnisotropy();
9250
- const resolvedPreviewUrl = (0, import_react32.useMemo)(
9470
+ const resolvedPreviewUrl = (0, import_react34.useMemo)(
9251
9471
  () => resolveUrlAgainstFile(src, previewUrl),
9252
9472
  [previewUrl, src]
9253
9473
  );
@@ -9266,11 +9486,11 @@ function Sphere({
9266
9486
  onPreviewError
9267
9487
  );
9268
9488
  const displayTexture = texture ?? previewTexture;
9269
- const readyRef = (0, import_react32.useRef)(false);
9270
- (0, import_react32.useEffect)(() => {
9489
+ const readyRef = (0, import_react34.useRef)(false);
9490
+ (0, import_react34.useEffect)(() => {
9271
9491
  readyRef.current = false;
9272
9492
  }, [resolvedPreviewUrl, src]);
9273
- (0, import_react32.useEffect)(() => {
9493
+ (0, import_react34.useEffect)(() => {
9274
9494
  if (!displayTexture || readyRef.current) {
9275
9495
  return;
9276
9496
  }
@@ -9302,7 +9522,7 @@ function Sphere({
9302
9522
 
9303
9523
  // src/video/pano-video.tsx
9304
9524
  var import_fiber16 = require("@react-three/fiber");
9305
- var import_react33 = require("react");
9525
+ var import_react35 = require("react");
9306
9526
  var import_three11 = require("three");
9307
9527
  var import_jsx_runtime16 = require("react/jsx-runtime");
9308
9528
  var EMPTY_TRACKS = [];
@@ -9389,10 +9609,10 @@ function applyEquirectangularLayout(texture, anisotropy) {
9389
9609
  }
9390
9610
  function usePosterTexture(poster, onError) {
9391
9611
  const gl = (0, import_fiber16.useThree)((state) => state.gl);
9392
- const [texture, setTexture] = (0, import_react33.useState)(null);
9393
- const onErrorRef = (0, import_react33.useRef)(onError);
9612
+ const [texture, setTexture] = (0, import_react35.useState)(null);
9613
+ const onErrorRef = (0, import_react35.useRef)(onError);
9394
9614
  onErrorRef.current = onError;
9395
- (0, import_react33.useEffect)(() => {
9615
+ (0, import_react35.useEffect)(() => {
9396
9616
  let active = true;
9397
9617
  setTexture(null);
9398
9618
  if (!poster) {
@@ -9429,7 +9649,7 @@ function usePosterTexture(poster, onError) {
9429
9649
  active = false;
9430
9650
  };
9431
9651
  }, [gl, poster]);
9432
- (0, import_react33.useEffect)(
9652
+ (0, import_react35.useEffect)(
9433
9653
  () => () => {
9434
9654
  texture?.dispose();
9435
9655
  },
@@ -9487,38 +9707,38 @@ function PanoVideo({
9487
9707
  onTrackChange
9488
9708
  }) {
9489
9709
  const gl = (0, import_fiber16.useThree)((state) => state.gl);
9490
- const host = (0, import_react33.useContext)(PanoVideoHostContext);
9491
- const overlay = (0, import_react33.useContext)(PanoChromeOverlayContext);
9492
- const variants = (0, import_react33.useMemo)(
9710
+ const host = (0, import_react35.useContext)(PanoVideoHostContext);
9711
+ const overlay = (0, import_react35.useContext)(PanoChromeOverlayContext);
9712
+ const variants = (0, import_react35.useMemo)(
9493
9713
  () => resolvePanoVideoVariants({ poster, src, variants: variantsProp }),
9494
9714
  [poster, src, variantsProp]
9495
9715
  );
9496
9716
  const tracks = tracksProp ?? EMPTY_TRACKS;
9497
9717
  const captionsEnabled = captions !== false;
9498
- const captionAppearance = (0, import_react33.useMemo)(
9718
+ const captionAppearance = (0, import_react35.useMemo)(
9499
9719
  () => resolvePanoVideoCaptionAppearance(
9500
9720
  typeof captions === "object" ? captions : void 0
9501
9721
  ),
9502
9722
  [captions]
9503
9723
  );
9504
- const [variantId, setVariantId] = (0, import_react33.useState)(
9724
+ const [variantId, setVariantId] = (0, import_react35.useState)(
9505
9725
  () => resolvePanoVideoVariantId(variants, defaultVariantId)
9506
9726
  );
9507
- const [trackId, setTrackId] = (0, import_react33.useState)(
9727
+ const [trackId, setTrackId] = (0, import_react35.useState)(
9508
9728
  () => captionsEnabled ? defaultPanoVideoTrackId(tracks) : null
9509
9729
  );
9510
- const [ready, setReady] = (0, import_react33.useState)(false);
9511
- const autoPlayRef = (0, import_react33.useRef)(autoPlay);
9730
+ const [ready, setReady] = (0, import_react35.useState)(false);
9731
+ const autoPlayRef = (0, import_react35.useRef)(autoPlay);
9512
9732
  autoPlayRef.current = autoPlay;
9513
- const blockedRef = (0, import_react33.useRef)(false);
9514
- const captionAppearanceOverrideRef = (0, import_react33.useRef)(
9733
+ const blockedRef = (0, import_react35.useRef)(false);
9734
+ const captionAppearanceOverrideRef = (0, import_react35.useRef)(
9515
9735
  {}
9516
9736
  );
9517
- const mediaCapabilitiesRef = (0, import_react33.useRef)({
9737
+ const mediaCapabilitiesRef = (0, import_react35.useRef)({
9518
9738
  volumeAdjustable: true,
9519
9739
  playbackRates: [...DEFAULT_PANO_VIDEO_PLAYBACK_RATES]
9520
9740
  });
9521
- const storeRef = (0, import_react33.useRef)(null);
9741
+ const storeRef = (0, import_react35.useRef)(null);
9522
9742
  if (!storeRef.current) {
9523
9743
  storeRef.current = {
9524
9744
  snapshot: {
@@ -9528,7 +9748,7 @@ function PanoVideo({
9528
9748
  listeners: /* @__PURE__ */ new Set()
9529
9749
  };
9530
9750
  }
9531
- const actionsRef = (0, import_react33.useRef)({
9751
+ const actionsRef = (0, import_react35.useRef)({
9532
9752
  play: async () => {
9533
9753
  },
9534
9754
  pause: () => {
@@ -9548,19 +9768,19 @@ function PanoVideo({
9548
9768
  setCaptionAppearance: (_appearance) => {
9549
9769
  }
9550
9770
  });
9551
- const onLoadRef = (0, import_react33.useRef)(onLoad);
9552
- const onErrorRef = (0, import_react33.useRef)(onError);
9553
- const onPlaybackStateChangeRef = (0, import_react33.useRef)(onPlaybackStateChange);
9554
- const onEndedRef = (0, import_react33.useRef)(onEnded);
9555
- const onVariantChangeRef = (0, import_react33.useRef)(onVariantChange);
9556
- const onTrackChangeRef = (0, import_react33.useRef)(onTrackChange);
9771
+ const onLoadRef = (0, import_react35.useRef)(onLoad);
9772
+ const onErrorRef = (0, import_react35.useRef)(onError);
9773
+ const onPlaybackStateChangeRef = (0, import_react35.useRef)(onPlaybackStateChange);
9774
+ const onEndedRef = (0, import_react35.useRef)(onEnded);
9775
+ const onVariantChangeRef = (0, import_react35.useRef)(onVariantChange);
9776
+ const onTrackChangeRef = (0, import_react35.useRef)(onTrackChange);
9557
9777
  onLoadRef.current = onLoad;
9558
9778
  onErrorRef.current = onError;
9559
9779
  onPlaybackStateChangeRef.current = onPlaybackStateChange;
9560
9780
  onEndedRef.current = onEnded;
9561
9781
  onVariantChangeRef.current = onVariantChange;
9562
9782
  onTrackChangeRef.current = onTrackChange;
9563
- const resource = (0, import_react33.useMemo)(() => {
9783
+ const resource = (0, import_react35.useMemo)(() => {
9564
9784
  if (typeof document === "undefined") {
9565
9785
  return null;
9566
9786
  }
@@ -9577,7 +9797,7 @@ function PanoVideo({
9577
9797
  texture.generateMipmaps = false;
9578
9798
  return { video, texture };
9579
9799
  }, []);
9580
- (0, import_react33.useEffect)(
9800
+ (0, import_react35.useEffect)(
9581
9801
  () => () => {
9582
9802
  if (!resource) {
9583
9803
  return;
@@ -9592,13 +9812,13 @@ function PanoVideo({
9592
9812
  },
9593
9813
  [resource]
9594
9814
  );
9595
- (0, import_react33.useEffect)(() => {
9815
+ (0, import_react35.useEffect)(() => {
9596
9816
  if (!resource) {
9597
9817
  return;
9598
9818
  }
9599
9819
  resource.texture.anisotropy = gl.capabilities.getMaxAnisotropy();
9600
9820
  }, [gl, resource]);
9601
- (0, import_react33.useEffect)(() => {
9821
+ (0, import_react35.useEffect)(() => {
9602
9822
  if (!resource || !overlay?.overlayElement) {
9603
9823
  return;
9604
9824
  }
@@ -9621,7 +9841,7 @@ function PanoVideo({
9621
9841
  activeVariant?.poster ?? poster,
9622
9842
  onError
9623
9843
  );
9624
- const emitSnapshot = (0, import_react33.useCallback)(
9844
+ const emitSnapshot = (0, import_react35.useCallback)(
9625
9845
  (patch) => {
9626
9846
  const store = storeRef.current;
9627
9847
  const video = resource?.video;
@@ -9673,7 +9893,7 @@ function PanoVideo({
9673
9893
  captionAppearance
9674
9894
  ]
9675
9895
  );
9676
- const controller = (0, import_react33.useMemo)(
9896
+ const controller = (0, import_react35.useMemo)(
9677
9897
  () => ({
9678
9898
  subscribe: (onStoreChange) => {
9679
9899
  const store = storeRef.current;
@@ -9725,7 +9945,7 @@ function PanoVideo({
9725
9945
  }),
9726
9946
  []
9727
9947
  );
9728
- (0, import_react33.useLayoutEffect)(() => {
9948
+ (0, import_react35.useLayoutEffect)(() => {
9729
9949
  if (!host || variants.length === 0) {
9730
9950
  return;
9731
9951
  }
@@ -9738,7 +9958,7 @@ function PanoVideo({
9738
9958
  notifyPanoVideoHost(host);
9739
9959
  };
9740
9960
  }, [captionsEnabled, controller, controls, host, variants.length]);
9741
- (0, import_react33.useLayoutEffect)(() => {
9961
+ (0, import_react35.useLayoutEffect)(() => {
9742
9962
  if (!resource) {
9743
9963
  return;
9744
9964
  }
@@ -9751,10 +9971,10 @@ function PanoVideo({
9751
9971
  };
9752
9972
  emitSnapshot();
9753
9973
  }, [emitSnapshot, playbackRates, resource]);
9754
- (0, import_react33.useEffect)(() => {
9974
+ (0, import_react35.useEffect)(() => {
9755
9975
  emitSnapshot();
9756
9976
  }, [emitSnapshot]);
9757
- (0, import_react33.useEffect)(() => {
9977
+ (0, import_react35.useEffect)(() => {
9758
9978
  if (!resource || !activeVariant || !mediaKey) {
9759
9979
  return;
9760
9980
  }
@@ -9811,7 +10031,7 @@ function PanoVideo({
9811
10031
  video.removeEventListener("error", handleError);
9812
10032
  };
9813
10033
  }, [mediaKey, resource]);
9814
- (0, import_react33.useEffect)(() => {
10034
+ (0, import_react35.useEffect)(() => {
9815
10035
  if (!resource) {
9816
10036
  return;
9817
10037
  }
@@ -9901,7 +10121,7 @@ function PanoVideo({
9901
10121
  }
9902
10122
  };
9903
10123
  }, [emitSnapshot, resource]);
9904
- (0, import_react33.useEffect)(() => {
10124
+ (0, import_react35.useEffect)(() => {
9905
10125
  if (!resource) {
9906
10126
  return;
9907
10127
  }
@@ -9914,7 +10134,7 @@ function PanoVideo({
9914
10134
  video.playsInline = playsInline;
9915
10135
  video.preload = preload;
9916
10136
  }, [loop, muted, playsInline, preload, resource, volume]);
9917
- (0, import_react33.useEffect)(() => {
10137
+ (0, import_react35.useEffect)(() => {
9918
10138
  if (!resource) {
9919
10139
  return;
9920
10140
  }
@@ -9964,7 +10184,7 @@ function PanoVideo({
9964
10184
  video.removeEventListener("ratechange", handleVolume);
9965
10185
  };
9966
10186
  }, [emitSnapshot, resource]);
9967
- (0, import_react33.useEffect)(() => {
10187
+ (0, import_react35.useEffect)(() => {
9968
10188
  if (!resource) {
9969
10189
  return;
9970
10190
  }
@@ -9999,7 +10219,7 @@ function PanoVideo({
9999
10219
  video.textTracks.removeEventListener("change", applyModes);
10000
10220
  };
10001
10221
  }, [emitSnapshot, resource, trackId, tracks]);
10002
- (0, import_react33.useEffect)(() => {
10222
+ (0, import_react35.useEffect)(() => {
10003
10223
  if (!captionsEnabled) {
10004
10224
  setTrackId(null);
10005
10225
  return;
@@ -10035,7 +10255,7 @@ function PanoVideo({
10035
10255
 
10036
10256
  // src/scenes.tsx
10037
10257
  var import_fiber21 = require("@react-three/fiber");
10038
- var import_react38 = require("react");
10258
+ var import_react40 = require("react");
10039
10259
  var import_three19 = require("three");
10040
10260
 
10041
10261
  // src/scene-transitions/presets.ts
@@ -10086,7 +10306,7 @@ function isSnapshotTransition(preset) {
10086
10306
 
10087
10307
  // src/scene-transitions/particle-overlay.tsx
10088
10308
  var import_fiber17 = require("@react-three/fiber");
10089
- var import_react34 = require("react");
10309
+ var import_react36 = require("react");
10090
10310
  var import_three13 = require("three");
10091
10311
 
10092
10312
  // src/scene-transitions/glsl.ts
@@ -10218,12 +10438,12 @@ function ParticleOverlay({
10218
10438
  onFinish
10219
10439
  }) {
10220
10440
  const { camera } = (0, import_fiber17.useThree)();
10221
- const meshRef = (0, import_react34.useRef)(null);
10222
- const startRef = (0, import_react34.useRef)(null);
10223
- const finishedRef = (0, import_react34.useRef)(false);
10224
- const directionRef = (0, import_react34.useRef)(new import_three13.Vector3());
10225
- const geometry = (0, import_react34.useMemo)(() => createParticleGeometry(), []);
10226
- const material = (0, import_react34.useMemo)(
10441
+ const meshRef = (0, import_react36.useRef)(null);
10442
+ const startRef = (0, import_react36.useRef)(null);
10443
+ const finishedRef = (0, import_react36.useRef)(false);
10444
+ const directionRef = (0, import_react36.useRef)(new import_three13.Vector3());
10445
+ const geometry = (0, import_react36.useMemo)(() => createParticleGeometry(), []);
10446
+ const material = (0, import_react36.useMemo)(
10227
10447
  () => new import_three13.ShaderMaterial({
10228
10448
  transparent: true,
10229
10449
  depthTest: false,
@@ -10239,9 +10459,9 @@ function ParticleOverlay({
10239
10459
  }),
10240
10460
  [snapshot.texture]
10241
10461
  );
10242
- (0, import_react34.useEffect)(() => () => geometry.dispose(), [geometry]);
10243
- (0, import_react34.useEffect)(() => () => material.dispose(), [material]);
10244
- (0, import_react34.useEffect)(() => {
10462
+ (0, import_react36.useEffect)(() => () => geometry.dispose(), [geometry]);
10463
+ (0, import_react36.useEffect)(() => () => material.dispose(), [material]);
10464
+ (0, import_react36.useEffect)(() => {
10245
10465
  startRef.current = null;
10246
10466
  finishedRef.current = false;
10247
10467
  material.uniforms.progress.value = 0;
@@ -10277,7 +10497,7 @@ function ParticleOverlay({
10277
10497
 
10278
10498
  // src/scene-transitions/snapshot-overlay.tsx
10279
10499
  var import_fiber18 = require("@react-three/fiber");
10280
- var import_react35 = require("react");
10500
+ var import_react37 = require("react");
10281
10501
  var import_three15 = require("three");
10282
10502
 
10283
10503
  // src/scene-transitions/snapshot-shaders.ts
@@ -10566,18 +10786,18 @@ function SnapshotOverlay({
10566
10786
  onFinish
10567
10787
  }) {
10568
10788
  const { camera, gl } = (0, import_fiber18.useThree)();
10569
- const meshRef = (0, import_react35.useRef)(null);
10570
- const startRef = (0, import_react35.useRef)(null);
10571
- const finishedRef = (0, import_react35.useRef)(false);
10572
- const directionRef = (0, import_react35.useRef)(new import_three15.Vector3());
10573
- const material = (0, import_react35.useMemo)(() => {
10789
+ const meshRef = (0, import_react37.useRef)(null);
10790
+ const startRef = (0, import_react37.useRef)(null);
10791
+ const finishedRef = (0, import_react37.useRef)(false);
10792
+ const directionRef = (0, import_react37.useRef)(new import_three15.Vector3());
10793
+ const material = (0, import_react37.useMemo)(() => {
10574
10794
  if (!isSnapshotTransition(transition.preset)) {
10575
10795
  return null;
10576
10796
  }
10577
10797
  return createSnapshotMaterial(transition.preset, snapshot.texture);
10578
10798
  }, [snapshot.texture, transition.preset]);
10579
- (0, import_react35.useEffect)(() => () => material?.dispose(), [material]);
10580
- (0, import_react35.useEffect)(() => {
10799
+ (0, import_react37.useEffect)(() => () => material?.dispose(), [material]);
10800
+ (0, import_react37.useEffect)(() => {
10581
10801
  startRef.current = null;
10582
10802
  finishedRef.current = false;
10583
10803
  if (material) {
@@ -10659,7 +10879,7 @@ function TransitionOverlay(props) {
10659
10879
 
10660
10880
  // src/tile/texture-manager-context.tsx
10661
10881
  var import_fiber19 = require("@react-three/fiber");
10662
- var import_react36 = require("react");
10882
+ var import_react38 = require("react");
10663
10883
 
10664
10884
  // src/tile/texture-manager.ts
10665
10885
  var import_three16 = require("three");
@@ -10884,7 +11104,7 @@ var TileTextureManager = class {
10884
11104
 
10885
11105
  // src/tile/texture-manager-context.tsx
10886
11106
  var import_jsx_runtime20 = require("react/jsx-runtime");
10887
- var TileTextureManagerContext = (0, import_react36.createContext)(
11107
+ var TileTextureManagerContext = (0, import_react38.createContext)(
10888
11108
  null
10889
11109
  );
10890
11110
  function TileTextureManagerProvider({
@@ -10894,7 +11114,7 @@ function TileTextureManagerProvider({
10894
11114
  }) {
10895
11115
  const gl = (0, import_fiber19.useThree)((state) => state.gl);
10896
11116
  const anisotropy = gl.capabilities.getMaxAnisotropy();
10897
- const manager = (0, import_react36.useMemo)(
11117
+ const manager = (0, import_react38.useMemo)(
10898
11118
  () => new TileTextureManager({
10899
11119
  anisotropy,
10900
11120
  maxBytes: Math.max(1, maxTextureMemoryMb) * 1024 * 1024,
@@ -10903,19 +11123,19 @@ function TileTextureManagerProvider({
10903
11123
  }),
10904
11124
  [anisotropy, maxConcurrentLoads, maxTextureMemoryMb]
10905
11125
  );
10906
- (0, import_react36.useEffect)(() => {
11126
+ (0, import_react38.useEffect)(() => {
10907
11127
  manager.resume();
10908
11128
  return () => manager.dispose();
10909
11129
  }, [manager]);
10910
11130
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TileTextureManagerContext.Provider, { value: manager, children });
10911
11131
  }
10912
11132
  function useSharedTileTextureManager() {
10913
- return (0, import_react36.useContext)(TileTextureManagerContext);
11133
+ return (0, import_react38.useContext)(TileTextureManagerContext);
10914
11134
  }
10915
11135
 
10916
11136
  // src/tile/tile.tsx
10917
11137
  var import_fiber20 = require("@react-three/fiber");
10918
- var import_react37 = require("react");
11138
+ var import_react39 = require("react");
10919
11139
  var import_three18 = require("three");
10920
11140
 
10921
11141
  // src/tile/face-layout.ts
@@ -11104,10 +11324,10 @@ var VISIBILITY_FOV_PADDING_DEGREES = 8;
11104
11324
  var PREVIEW_RADIUS = CUBE_RADIUS + 0.05;
11105
11325
  var SHARED_TILE_GEOMETRY = new import_three18.PlaneGeometry(1, 1);
11106
11326
  function usePreviewTexture(url, anisotropy, onError) {
11107
- const [texture, setTexture] = (0, import_react37.useState)(null);
11108
- const onErrorRef = (0, import_react37.useRef)(onError);
11327
+ const [texture, setTexture] = (0, import_react39.useState)(null);
11328
+ const onErrorRef = (0, import_react39.useRef)(onError);
11109
11329
  onErrorRef.current = onError;
11110
- (0, import_react37.useEffect)(() => {
11330
+ (0, import_react39.useEffect)(() => {
11111
11331
  if (!url) {
11112
11332
  setTexture(null);
11113
11333
  return;
@@ -11144,7 +11364,7 @@ function usePreviewTexture(url, anisotropy, onError) {
11144
11364
  active = false;
11145
11365
  };
11146
11366
  }, [anisotropy, url]);
11147
- (0, import_react37.useEffect)(
11367
+ (0, import_react39.useEffect)(
11148
11368
  () => () => {
11149
11369
  texture?.dispose();
11150
11370
  },
@@ -11157,7 +11377,7 @@ function PreviewFace({
11157
11377
  texture,
11158
11378
  faceOrder
11159
11379
  }) {
11160
- const geometry = (0, import_react37.useMemo)(() => {
11380
+ const geometry = (0, import_react39.useMemo)(() => {
11161
11381
  const nextGeometry = new import_three18.PlaneGeometry(
11162
11382
  PREVIEW_RADIUS * 2,
11163
11383
  PREVIEW_RADIUS * 2
@@ -11175,7 +11395,7 @@ function PreviewFace({
11175
11395
  uv.needsUpdate = true;
11176
11396
  return nextGeometry;
11177
11397
  }, [face, faceOrder]);
11178
- (0, import_react37.useEffect)(
11398
+ (0, import_react39.useEffect)(
11179
11399
  () => () => {
11180
11400
  geometry.dispose();
11181
11401
  },
@@ -11216,14 +11436,14 @@ function PreviewCube({
11216
11436
  ));
11217
11437
  }
11218
11438
  function useManagedTexture(manager, key, url, address) {
11219
- const [managedState, setManagedState] = (0, import_react37.useState)(() => ({
11439
+ const [managedState, setManagedState] = (0, import_react39.useState)(() => ({
11220
11440
  manager,
11221
11441
  key,
11222
11442
  url,
11223
11443
  snapshot: manager.getSnapshot(key)
11224
11444
  }));
11225
11445
  const snapshot = managedState.manager === manager && managedState.key === key && managedState.url === url ? managedState.snapshot : manager.getSnapshot(key);
11226
- (0, import_react37.useEffect)(
11446
+ (0, import_react39.useEffect)(
11227
11447
  () => manager.acquire(key, url, address, (nextSnapshot) => {
11228
11448
  setManagedState({
11229
11449
  manager,
@@ -11236,7 +11456,7 @@ function useManagedTexture(manager, key, url, address) {
11236
11456
  );
11237
11457
  return snapshot;
11238
11458
  }
11239
- var TileMesh = (0, import_react37.memo)(function TileMesh2({
11459
+ var TileMesh = (0, import_react39.memo)(function TileMesh2({
11240
11460
  address,
11241
11461
  manager,
11242
11462
  renderOrder,
@@ -11269,7 +11489,7 @@ var TileMesh = (0, import_react37.memo)(function TileMesh2({
11269
11489
  }
11270
11490
  ) });
11271
11491
  });
11272
- var TileLayerMeshes = (0, import_react37.memo)(function TileLayerMeshes2({
11492
+ var TileLayerMeshes = (0, import_react39.memo)(function TileLayerMeshes2({
11273
11493
  layer,
11274
11494
  manager,
11275
11495
  resolveUrl
@@ -11443,10 +11663,10 @@ function Tile({
11443
11663
  onLevelChange
11444
11664
  }) {
11445
11665
  const { camera, gl, size } = (0, import_fiber20.useThree)();
11446
- const multiresConfig = (0, import_react37.useMemo)(() => parseMultires(multires), [multires]);
11666
+ const multiresConfig = (0, import_react39.useMemo)(() => parseMultires(multires), [multires]);
11447
11667
  const { levels, tileSize } = multiresConfig;
11448
11668
  const multiresToken = `${tileSize}:${levels.join(",")}`;
11449
- const candidatesByLevel = (0, import_react37.useMemo)(
11669
+ const candidatesByLevel = (0, import_react39.useMemo)(
11450
11670
  () => buildTileCandidates(levels, tileSize),
11451
11671
  [levels, tileSize]
11452
11672
  );
@@ -11458,13 +11678,13 @@ function Tile({
11458
11678
  onPreviewError
11459
11679
  );
11460
11680
  const sharedManager = useSharedTileTextureManager();
11461
- const progressRef = (0, import_react37.useRef)(onLoadProgress);
11462
- const errorRef = (0, import_react37.useRef)(onTileError);
11463
- const levelChangeRef = (0, import_react37.useRef)(onLevelChange);
11681
+ const progressRef = (0, import_react39.useRef)(onLoadProgress);
11682
+ const errorRef = (0, import_react39.useRef)(onTileError);
11683
+ const levelChangeRef = (0, import_react39.useRef)(onLevelChange);
11464
11684
  progressRef.current = onLoadProgress;
11465
11685
  errorRef.current = onTileError;
11466
11686
  levelChangeRef.current = onLevelChange;
11467
- const ownedManager = (0, import_react37.useMemo)(
11687
+ const ownedManager = (0, import_react39.useMemo)(
11468
11688
  () => new TileTextureManager({
11469
11689
  anisotropy,
11470
11690
  maxBytes: Math.max(1, maxTextureMemoryMb) * 1024 * 1024,
@@ -11485,7 +11705,7 @@ function Tile({
11485
11705
  ]
11486
11706
  );
11487
11707
  const manager = sharedManager ?? ownedManager;
11488
- (0, import_react37.useEffect)(() => {
11708
+ (0, import_react39.useEffect)(() => {
11489
11709
  manager.resume();
11490
11710
  return () => {
11491
11711
  if (manager === ownedManager) {
@@ -11495,11 +11715,11 @@ function Tile({
11495
11715
  queueMicrotask(() => manager.releaseUnused());
11496
11716
  };
11497
11717
  }, [manager, ownedManager]);
11498
- const readyRef = (0, import_react37.useRef)(false);
11499
- (0, import_react37.useEffect)(() => {
11718
+ const readyRef = (0, import_react39.useRef)(false);
11719
+ (0, import_react39.useEffect)(() => {
11500
11720
  readyRef.current = false;
11501
11721
  }, [effectivePreviewUrl]);
11502
- (0, import_react37.useEffect)(() => {
11722
+ (0, import_react39.useEffect)(() => {
11503
11723
  if (!previewTexture || readyRef.current) {
11504
11724
  return;
11505
11725
  }
@@ -11507,31 +11727,31 @@ function Tile({
11507
11727
  onReady?.();
11508
11728
  }, [onReady, previewTexture]);
11509
11729
  const template = urlTemplate ?? buildDefaultTileUrlTemplate();
11510
- const resolveUrl = (0, import_react37.useMemo)(
11730
+ const resolveUrl = (0, import_react39.useMemo)(
11511
11731
  () => (address) => {
11512
11732
  const relativePath = resolveTileUrl ? resolveTileUrl(address) : resolveTemplateUrl(template, address);
11513
11733
  return resolveRelativeTileUrl(baseUrl, relativePath);
11514
11734
  },
11515
11735
  [baseUrl, resolveTileUrl, template]
11516
11736
  );
11517
- const [layers, setLayers] = (0, import_react37.useState)([]);
11518
- const layerTokenRef = (0, import_react37.useRef)("");
11519
- const currentLevelRef = (0, import_react37.useRef)(1);
11520
- const lastUpdateAtRef = (0, import_react37.useRef)(-Infinity);
11521
- const visibilityDirtyRef = (0, import_react37.useRef)(true);
11522
- const lastVisibilityQuaternionRef = (0, import_react37.useRef)(camera.quaternion.clone());
11523
- const lastVisibilityFovRef = (0, import_react37.useRef)(Number.NaN);
11524
- const lastViewportRef = (0, import_react37.useRef)({ width: 0, height: 0, dpr: 0 });
11525
- const frustumRef = (0, import_react37.useRef)(new import_three18.Frustum());
11526
- const projectionMatrixRef = (0, import_react37.useRef)(new import_three18.Matrix4());
11527
- const visibilityCameraRef = (0, import_react37.useRef)(new import_three18.PerspectiveCamera());
11528
- (0, import_react37.useEffect)(() => {
11737
+ const [layers, setLayers] = (0, import_react39.useState)([]);
11738
+ const layerTokenRef = (0, import_react39.useRef)("");
11739
+ const currentLevelRef = (0, import_react39.useRef)(1);
11740
+ const lastUpdateAtRef = (0, import_react39.useRef)(-Infinity);
11741
+ const visibilityDirtyRef = (0, import_react39.useRef)(true);
11742
+ const lastVisibilityQuaternionRef = (0, import_react39.useRef)(camera.quaternion.clone());
11743
+ const lastVisibilityFovRef = (0, import_react39.useRef)(Number.NaN);
11744
+ const lastViewportRef = (0, import_react39.useRef)({ width: 0, height: 0, dpr: 0 });
11745
+ const frustumRef = (0, import_react39.useRef)(new import_three18.Frustum());
11746
+ const projectionMatrixRef = (0, import_react39.useRef)(new import_three18.Matrix4());
11747
+ const visibilityCameraRef = (0, import_react39.useRef)(new import_three18.PerspectiveCamera());
11748
+ (0, import_react39.useEffect)(() => {
11529
11749
  currentLevelRef.current = 1;
11530
11750
  layerTokenRef.current = "";
11531
11751
  visibilityDirtyRef.current = true;
11532
11752
  setLayers([]);
11533
11753
  }, [manager, multiresToken]);
11534
- (0, import_react37.useEffect)(() => {
11754
+ (0, import_react39.useEffect)(() => {
11535
11755
  if (loadMode !== "preview") {
11536
11756
  return;
11537
11757
  }
@@ -11682,9 +11902,9 @@ function SnapshotCapture({
11682
11902
  onCaptured
11683
11903
  }) {
11684
11904
  const { camera, gl, scene, size } = (0, import_fiber21.useThree)();
11685
- const capturedRequestRef = (0, import_react38.useRef)(0);
11686
- const renderTargetRef = (0, import_react38.useRef)(null);
11687
- (0, import_react38.useEffect)(
11905
+ const capturedRequestRef = (0, import_react40.useRef)(0);
11906
+ const renderTargetRef = (0, import_react40.useRef)(null);
11907
+ (0, import_react40.useEffect)(
11688
11908
  () => () => {
11689
11909
  renderTargetRef.current?.dispose();
11690
11910
  renderTargetRef.current = null;
@@ -11737,49 +11957,53 @@ function ScenesController({
11737
11957
  renderHotspots,
11738
11958
  onTransitionEnd,
11739
11959
  onTransitionError,
11740
- snapshotMaxPixels = 3686400
11960
+ snapshotMaxPixels = 3686400,
11961
+ phaseRef: externalPhaseRef
11741
11962
  }) {
11742
- const controlsRef = (0, import_react38.useContext)(PanoramaViewContext);
11963
+ const controlsRef = (0, import_react40.useContext)(PanoramaViewContext);
11743
11964
  const manager = useSharedTileTextureManager();
11744
- const transition = (0, import_react38.useMemo)(
11965
+ const transition = (0, import_react40.useMemo)(
11745
11966
  () => resolveTransition(transitionInput),
11746
11967
  [transitionInput]
11747
11968
  );
11748
- const sceneMap = (0, import_react38.useMemo)(
11969
+ const sceneMap = (0, import_react40.useMemo)(
11749
11970
  () => new Map(scenes.map((scene) => [scene.id, scene])),
11750
11971
  [scenes]
11751
11972
  );
11752
11973
  const initialScene = sceneMap.get(activeSceneId) ?? null;
11753
- const [slots, setSlots] = (0, import_react38.useState)([
11974
+ const [slots, setSlots] = (0, import_react40.useState)([
11754
11975
  initialScene,
11755
11976
  null
11756
11977
  ]);
11757
- const [activeSlot, setActiveSlot] = (0, import_react38.useState)(0);
11758
- const [liveSlot, setLiveSlot] = (0, import_react38.useState)(0);
11759
- const [pendingSlot, setPendingSlot] = (0, import_react38.useState)(null);
11760
- const [phase, setPhase] = (0, import_react38.useState)(initialScene ? "idle" : "preloading");
11761
- const [captureRequestId, setCaptureRequestId] = (0, import_react38.useState)(0);
11762
- const [transitionRunId, setTransitionRunId] = (0, import_react38.useState)(0);
11763
- const [snapshot, setSnapshot] = (0, import_react38.useState)(null);
11764
- const [recoveryKey, setRecoveryKey] = (0, import_react38.useState)(0);
11765
- const requestedSceneIdRef = (0, import_react38.useRef)(activeSceneId);
11766
- const captureReasonRef = (0, import_react38.useRef)("start");
11767
- const interactionReleaseRef = (0, import_react38.useRef)(null);
11768
- const slotsRef = (0, import_react38.useRef)(slots);
11769
- const phaseRef = (0, import_react38.useRef)(phase);
11770
- const liveSlotRef = (0, import_react38.useRef)(liveSlot);
11771
- const transitionFromRef = (0, import_react38.useRef)(initialScene);
11978
+ const [activeSlot, setActiveSlot] = (0, import_react40.useState)(0);
11979
+ const [liveSlot, setLiveSlot] = (0, import_react40.useState)(0);
11980
+ const [pendingSlot, setPendingSlot] = (0, import_react40.useState)(null);
11981
+ const [phase, setPhase] = (0, import_react40.useState)(initialScene ? "idle" : "preloading");
11982
+ const [captureRequestId, setCaptureRequestId] = (0, import_react40.useState)(0);
11983
+ const [transitionRunId, setTransitionRunId] = (0, import_react40.useState)(0);
11984
+ const [snapshot, setSnapshot] = (0, import_react40.useState)(null);
11985
+ const [recoveryKey, setRecoveryKey] = (0, import_react40.useState)(0);
11986
+ const requestedSceneIdRef = (0, import_react40.useRef)(activeSceneId);
11987
+ const captureReasonRef = (0, import_react40.useRef)("start");
11988
+ const interactionReleaseRef = (0, import_react40.useRef)(null);
11989
+ const slotsRef = (0, import_react40.useRef)(slots);
11990
+ const phaseRef = (0, import_react40.useRef)(phase);
11991
+ const liveSlotRef = (0, import_react40.useRef)(liveSlot);
11992
+ const transitionFromRef = (0, import_react40.useRef)(initialScene);
11772
11993
  slotsRef.current = slots;
11773
11994
  phaseRef.current = phase;
11995
+ if (externalPhaseRef) {
11996
+ externalPhaseRef.current = phase;
11997
+ }
11774
11998
  liveSlotRef.current = liveSlot;
11775
- const releaseInteraction = (0, import_react38.useCallback)(() => {
11999
+ const releaseInteraction = (0, import_react40.useCallback)(() => {
11776
12000
  interactionReleaseRef.current?.();
11777
12001
  interactionReleaseRef.current = null;
11778
12002
  }, []);
11779
- const reportError = (0, import_react38.useCallback)((sceneId, error) => {
12003
+ const reportError = (0, import_react40.useCallback)((sceneId, error) => {
11780
12004
  onTransitionError?.({ sceneId, error });
11781
12005
  }, [onTransitionError]);
11782
- const startPreload = (0, import_react38.useCallback)((scene) => {
12006
+ const startPreload = (0, import_react40.useCallback)((scene) => {
11783
12007
  const nextSlot = 1 - liveSlotRef.current;
11784
12008
  requestedSceneIdRef.current = scene.id;
11785
12009
  setSlots((current) => {
@@ -11790,7 +12014,7 @@ function ScenesController({
11790
12014
  setPendingSlot(nextSlot);
11791
12015
  setPhase("preloading");
11792
12016
  }, []);
11793
- (0, import_react38.useEffect)(() => {
12017
+ (0, import_react40.useEffect)(() => {
11794
12018
  const requested = sceneMap.get(activeSceneId);
11795
12019
  if (!requested) {
11796
12020
  reportError(activeSceneId, new Error(`Unknown panorama scene: ${activeSceneId}`));
@@ -11814,7 +12038,7 @@ function ScenesController({
11814
12038
  }
11815
12039
  startPreload(requested);
11816
12040
  }, [activeSceneId, pendingSlot, reportError, sceneMap, startPreload]);
11817
- const handleReady = (0, import_react38.useCallback)((slot) => {
12041
+ const handleReady = (0, import_react40.useCallback)((slot) => {
11818
12042
  if (slot !== pendingSlot || phaseRef.current !== "preloading") {
11819
12043
  return;
11820
12044
  }
@@ -11845,7 +12069,7 @@ function ScenesController({
11845
12069
  setPhase("capturing");
11846
12070
  setCaptureRequestId((current) => current + 1);
11847
12071
  }, [controlsRef, onTransitionEnd, pendingSlot, transition.preset]);
11848
- const handleCaptured = (0, import_react38.useCallback)((nextSnapshot) => {
12072
+ const handleCaptured = (0, import_react40.useCallback)((nextSnapshot) => {
11849
12073
  setSnapshot((current) => {
11850
12074
  current?.dispose();
11851
12075
  return nextSnapshot;
@@ -11867,7 +12091,7 @@ function ScenesController({
11867
12091
  setPhase("transitioning");
11868
12092
  setTransitionRunId((current) => current + 1);
11869
12093
  }, [manager, pendingSlot, sceneMap, startPreload]);
11870
- const finishTransition = (0, import_react38.useCallback)(() => {
12094
+ const finishTransition = (0, import_react40.useCallback)(() => {
11871
12095
  const nextSlot = pendingSlot;
11872
12096
  const previousScene = transitionFromRef.current;
11873
12097
  const nextScene = nextSlot === null ? null : slotsRef.current[nextSlot];
@@ -11892,12 +12116,12 @@ function ScenesController({
11892
12116
  });
11893
12117
  }
11894
12118
  }, [onTransitionEnd, pendingSlot, releaseInteraction, snapshot, transition.preset]);
11895
- (0, import_react38.useEffect)(() => () => {
12119
+ (0, import_react40.useEffect)(() => () => {
11896
12120
  releaseInteraction();
11897
12121
  snapshot?.dispose();
11898
12122
  }, [releaseInteraction, snapshot]);
11899
12123
  const { gl } = (0, import_fiber21.useThree)();
11900
- (0, import_react38.useEffect)(() => {
12124
+ (0, import_react40.useEffect)(() => {
11901
12125
  const canvas = gl.domElement;
11902
12126
  const onContextLost = (event) => {
11903
12127
  event.preventDefault();
@@ -11921,7 +12145,7 @@ function ScenesController({
11921
12145
  }, [gl, manager, releaseInteraction, snapshot]);
11922
12146
  const renderedScene = slots[liveSlot];
11923
12147
  const snapshotVisible = snapshot !== null && (phase === "transitioning" || phase === "recapturing" || phase === "preloading");
11924
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react38.Fragment, { children: [
12148
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react40.Fragment, { children: [
11925
12149
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
11926
12150
  SnapshotCapture,
11927
12151
  {
@@ -11966,39 +12190,122 @@ function ScenesController({
11966
12190
  function Scenes({
11967
12191
  maxTextureMemoryMb,
11968
12192
  maxConcurrentTileLoads,
11969
- ...props
12193
+ activeSceneId: controlledId,
12194
+ defaultActiveSceneId,
12195
+ onActiveSceneIdChange,
12196
+ scenes,
12197
+ ...rest
11970
12198
  }) {
12199
+ const isControlled = controlledId !== void 0;
12200
+ const [internalId, setInternalId] = (0, import_react40.useState)(
12201
+ () => controlledId ?? defaultActiveSceneId ?? scenes[0]?.id ?? ""
12202
+ );
12203
+ const resolvedId = isControlled ? controlledId : internalId;
12204
+ const requestSceneChange = (0, import_react40.useCallback)(
12205
+ (id) => {
12206
+ if (isControlled) {
12207
+ onActiveSceneIdChange?.(id);
12208
+ } else {
12209
+ setInternalId(id);
12210
+ }
12211
+ },
12212
+ [isControlled, onActiveSceneIdChange]
12213
+ );
12214
+ const scenesRef = (0, import_react40.useRef)(scenes);
12215
+ scenesRef.current = scenes;
12216
+ const resolvedIdRef = (0, import_react40.useRef)(resolvedId);
12217
+ resolvedIdRef.current = resolvedId;
12218
+ const host = (0, import_react40.useContext)(ScenesHostContext);
12219
+ const phaseRef = (0, import_react40.useRef)("idle");
12220
+ (0, import_react40.useEffect)(() => {
12221
+ if (!host) {
12222
+ return;
12223
+ }
12224
+ const controller = {
12225
+ setScene: (id) => {
12226
+ const match = scenesRef.current.find((s) => s.id === id);
12227
+ if (!match) {
12228
+ return false;
12229
+ }
12230
+ requestSceneChange(id);
12231
+ return true;
12232
+ },
12233
+ nextScene: () => {
12234
+ const next = cycleSceneId(
12235
+ scenesRef.current,
12236
+ resolvedIdRef.current,
12237
+ 1
12238
+ );
12239
+ if (next === null) {
12240
+ return false;
12241
+ }
12242
+ requestSceneChange(next);
12243
+ return true;
12244
+ },
12245
+ previousScene: () => {
12246
+ const next = cycleSceneId(
12247
+ scenesRef.current,
12248
+ resolvedIdRef.current,
12249
+ -1
12250
+ );
12251
+ if (next === null) {
12252
+ return false;
12253
+ }
12254
+ requestSceneChange(next);
12255
+ return true;
12256
+ },
12257
+ getActiveSceneId: () => resolvedIdRef.current,
12258
+ getSceneIds: () => scenesRef.current.map((s) => s.id),
12259
+ isTransitioning: () => phaseRef.current !== "idle"
12260
+ };
12261
+ host.controller = controller;
12262
+ notifyScenesHost(host);
12263
+ return () => {
12264
+ if (host.controller === controller) {
12265
+ host.controller = null;
12266
+ notifyScenesHost(host);
12267
+ }
12268
+ };
12269
+ }, [host, requestSceneChange]);
11971
12270
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
11972
12271
  TileTextureManagerProvider,
11973
12272
  {
11974
12273
  maxTextureMemoryMb,
11975
12274
  maxConcurrentLoads: maxConcurrentTileLoads,
11976
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ScenesController, { ...props })
12275
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
12276
+ ScenesController,
12277
+ {
12278
+ ...rest,
12279
+ scenes,
12280
+ activeSceneId: resolvedId,
12281
+ phaseRef
12282
+ }
12283
+ )
11977
12284
  }
11978
12285
  );
11979
12286
  }
11980
12287
 
11981
12288
  // src/hotspot/image-hotspot.tsx
11982
12289
  var import_fiber23 = require("@react-three/fiber");
11983
- var import_react42 = require("react");
12290
+ var import_react44 = require("react");
11984
12291
  var import_three22 = require("three");
11985
12292
 
11986
12293
  // src/hotspot/hotspot-anchor.tsx
11987
12294
  var import_fiber22 = require("@react-three/fiber");
11988
- var import_react41 = require("react");
12295
+ var import_react43 = require("react");
11989
12296
  var import_three20 = require("three");
11990
12297
 
11991
12298
  // src/hotspot/hotspot-tooltip.tsx
11992
- var import_react40 = require("react");
12299
+ var import_react42 = require("react");
11993
12300
 
11994
12301
  // src/webvr/stereo-html.tsx
11995
12302
  var import_drei = require("@react-three/drei");
11996
- var import_react39 = require("react");
12303
+ var import_react41 = require("react");
11997
12304
  var import_jsx_runtime23 = require("react/jsx-runtime");
11998
12305
  function useFallbackStereoView() {
11999
- const runtime = (0, import_react39.useContext)(WebVRRuntimeContext);
12306
+ const runtime = (0, import_react41.useContext)(WebVRRuntimeContext);
12000
12307
  const host = runtime?.host ?? null;
12001
- const fallback = (0, import_react39.useSyncExternalStore)(
12308
+ const fallback = (0, import_react41.useSyncExternalStore)(
12002
12309
  (onStoreChange) => host ? subscribeWebVRHost(host, onStoreChange) : () => void 0,
12003
12310
  () => isFallbackStereoMode(host?.snapshot.mode ?? null),
12004
12311
  () => false
@@ -12112,16 +12419,16 @@ function HotspotTooltip({
12112
12419
  offset = DEFAULT_HOTSPOT_TOOLTIP_OFFSET,
12113
12420
  appearance
12114
12421
  }) {
12115
- const [imageFailed, setImageFailed] = (0, import_react40.useState)(false);
12116
- (0, import_react40.useEffect)(() => {
12422
+ const [imageFailed, setImageFailed] = (0, import_react42.useState)(false);
12423
+ (0, import_react42.useEffect)(() => {
12117
12424
  setImageFailed(false);
12118
12425
  }, [content.image]);
12119
12426
  const showImage = Boolean(content.image) && !imageFailed;
12120
- const resolvedAppearance = (0, import_react40.useMemo)(
12427
+ const resolvedAppearance = (0, import_react42.useMemo)(
12121
12428
  () => resolveHotspotTooltipAppearance(appearance),
12122
12429
  [appearance]
12123
12430
  );
12124
- const bubbleStyle = (0, import_react40.useMemo)(
12431
+ const bubbleStyle = (0, import_react42.useMemo)(
12125
12432
  () => ({
12126
12433
  background: resolvedAppearance.background,
12127
12434
  border: resolvedAppearance.border,
@@ -12500,18 +12807,18 @@ function HotspotAnchor({
12500
12807
  onPositionChange,
12501
12808
  onDragEnd
12502
12809
  }) {
12503
- const controlsRef = (0, import_react41.useContext)(PanoramaViewContext);
12504
- const eventBus = (0, import_react41.useContext)(PanoEventBusContext);
12810
+ const controlsRef = (0, import_react43.useContext)(PanoramaViewContext);
12811
+ const eventBus = (0, import_react43.useContext)(PanoEventBusContext);
12505
12812
  const cursorApi = usePanoCursor();
12506
12813
  const { camera, size } = (0, import_fiber22.useThree)();
12507
- const groupRef = (0, import_react41.useRef)(null);
12508
- const tooltipAnchorRef = (0, import_react41.useRef)(null);
12509
- const dragStateRef = (0, import_react41.useRef)(null);
12510
- const suppressNextClickRef = (0, import_react41.useRef)(false);
12511
- const [hovered, setHovered] = (0, import_react41.useState)(false);
12512
- const [dragging, setDragging] = (0, import_react41.useState)(false);
12513
- const [pinned, setPinned] = (0, import_react41.useState)(false);
12514
- const tooltipContent = (0, import_react41.useMemo)(
12814
+ const groupRef = (0, import_react43.useRef)(null);
12815
+ const tooltipAnchorRef = (0, import_react43.useRef)(null);
12816
+ const dragStateRef = (0, import_react43.useRef)(null);
12817
+ const suppressNextClickRef = (0, import_react43.useRef)(false);
12818
+ const [hovered, setHovered] = (0, import_react43.useState)(false);
12819
+ const [dragging, setDragging] = (0, import_react43.useState)(false);
12820
+ const [pinned, setPinned] = (0, import_react43.useState)(false);
12821
+ const tooltipContent = (0, import_react43.useMemo)(
12515
12822
  () => resolveHotspotTooltipContent(tooltip),
12516
12823
  [tooltip]
12517
12824
  );
@@ -12527,17 +12834,17 @@ function HotspotAnchor({
12527
12834
  scaledWidth,
12528
12835
  scaledHeight
12529
12836
  );
12530
- const worldPosition = (0, import_react41.useMemo)(
12837
+ const worldPosition = (0, import_react43.useMemo)(
12531
12838
  () => panoPositionToVector3(normalizedPosition, resolvedDistance),
12532
12839
  [normalizedPosition.pitch, normalizedPosition.yaw, resolvedDistance]
12533
12840
  );
12534
- const surfaceQuaternion3 = (0, import_react41.useMemo)(
12841
+ const surfaceQuaternion3 = (0, import_react43.useMemo)(
12535
12842
  () => createSurfaceQuaternion(normalizedPosition),
12536
12843
  [normalizedPosition.pitch, normalizedPosition.yaw]
12537
12844
  );
12538
12845
  const worldWidth = angularSizeToWorldSize(scaledWidth, resolvedDistance);
12539
12846
  const worldHeight = angularSizeToWorldSize(scaledHeight, resolvedDistance);
12540
- const focusGeometry = (0, import_react41.useMemo)(() => {
12847
+ const focusGeometry = (0, import_react43.useMemo)(() => {
12541
12848
  const planeGeometry = new import_three20.PlaneGeometry(1, 1);
12542
12849
  const geometry = new import_three20.EdgesGeometry(planeGeometry);
12543
12850
  planeGeometry.dispose();
@@ -12564,14 +12871,14 @@ function HotspotAnchor({
12564
12871
  });
12565
12872
  const tooltipOpen = visible && tooltipContent !== null && isTooltipOpen(tooltipTrigger, hovered, focused, pinned);
12566
12873
  const cursorClaimId = hotspotCursorClaimId(id);
12567
- (0, import_react41.useEffect)(
12874
+ (0, import_react43.useEffect)(
12568
12875
  () => () => {
12569
12876
  dragStateRef.current?.releaseInteractionLock();
12570
12877
  dragStateRef.current = null;
12571
12878
  },
12572
12879
  []
12573
12880
  );
12574
- (0, import_react41.useEffect)(() => {
12881
+ (0, import_react43.useEffect)(() => {
12575
12882
  if (!cursorApi) {
12576
12883
  return;
12577
12884
  }
@@ -12593,14 +12900,14 @@ function HotspotAnchor({
12593
12900
  hovered,
12594
12901
  visible
12595
12902
  ]);
12596
- (0, import_react41.useEffect)(
12903
+ (0, import_react43.useEffect)(
12597
12904
  () => () => {
12598
12905
  cursorApi?.release(cursorClaimId);
12599
12906
  },
12600
12907
  [cursorApi, cursorClaimId]
12601
12908
  );
12602
- (0, import_react41.useEffect)(() => () => focusGeometry.dispose(), [focusGeometry]);
12603
- (0, import_react41.useEffect)(() => {
12909
+ (0, import_react43.useEffect)(() => () => focusGeometry.dispose(), [focusGeometry]);
12910
+ (0, import_react43.useEffect)(() => {
12604
12911
  if (tooltipTrigger !== "click") {
12605
12912
  setPinned(false);
12606
12913
  return;
@@ -12609,12 +12916,12 @@ function HotspotAnchor({
12609
12916
  setPinned(false);
12610
12917
  });
12611
12918
  }, [eventBus, tooltipTrigger]);
12612
- (0, import_react41.useEffect)(() => {
12919
+ (0, import_react43.useEffect)(() => {
12613
12920
  if (tooltipTrigger !== "hover") {
12614
12921
  setHovered(false);
12615
12922
  }
12616
12923
  }, [tooltipTrigger]);
12617
- (0, import_react41.useEffect)(() => {
12924
+ (0, import_react43.useEffect)(() => {
12618
12925
  if (acceptsPointer) {
12619
12926
  return;
12620
12927
  }
@@ -12627,7 +12934,7 @@ function HotspotAnchor({
12627
12934
  dragStateRef.current = null;
12628
12935
  setDragging(false);
12629
12936
  }, [acceptsPointer]);
12630
- (0, import_react41.useLayoutEffect)(() => {
12937
+ (0, import_react43.useLayoutEffect)(() => {
12631
12938
  const group = groupRef.current;
12632
12939
  if (!group) {
12633
12940
  return;
@@ -12953,12 +13260,12 @@ function HotspotPlane({
12953
13260
  var import_jsx_runtime27 = require("react/jsx-runtime");
12954
13261
  function useHotspotImageTexture(src, onLoad, onError) {
12955
13262
  const gl = (0, import_fiber23.useThree)((state) => state.gl);
12956
- const [texture, setTexture] = (0, import_react42.useState)(null);
12957
- const onLoadRef = (0, import_react42.useRef)(onLoad);
12958
- const onErrorRef = (0, import_react42.useRef)(onError);
13263
+ const [texture, setTexture] = (0, import_react44.useState)(null);
13264
+ const onLoadRef = (0, import_react44.useRef)(onLoad);
13265
+ const onErrorRef = (0, import_react44.useRef)(onError);
12959
13266
  onLoadRef.current = onLoad;
12960
13267
  onErrorRef.current = onError;
12961
- (0, import_react42.useEffect)(() => {
13268
+ (0, import_react44.useEffect)(() => {
12962
13269
  let active = true;
12963
13270
  setTexture(null);
12964
13271
  if (!src) {
@@ -12996,7 +13303,7 @@ function useHotspotImageTexture(src, onLoad, onError) {
12996
13303
  active = false;
12997
13304
  };
12998
13305
  }, [gl, src]);
12999
- (0, import_react42.useEffect)(
13306
+ (0, import_react44.useEffect)(
13000
13307
  () => () => {
13001
13308
  texture?.dispose();
13002
13309
  },
@@ -13018,13 +13325,13 @@ function ImageHotspot({
13018
13325
  }
13019
13326
 
13020
13327
  // src/hotspot/polygon-hotspot.tsx
13021
- var import_react44 = require("react");
13328
+ var import_react46 = require("react");
13022
13329
  var import_three24 = require("three");
13023
13330
 
13024
13331
  // src/hotspot/hotspot-stroke-line.tsx
13025
13332
  var import_drei2 = require("@react-three/drei");
13026
13333
  var import_fiber24 = require("@react-three/fiber");
13027
- var import_react43 = require("react");
13334
+ var import_react45 = require("react");
13028
13335
  var import_three23 = require("three");
13029
13336
  var import_jsx_runtime28 = require("react/jsx-runtime");
13030
13337
  var LINE_WORLD_POSITION = new import_three23.Vector3();
@@ -13057,10 +13364,10 @@ function HotspotStrokeLine({
13057
13364
  dashSize,
13058
13365
  gapSize
13059
13366
  }) {
13060
- const lineRef = (0, import_react43.useRef)(null);
13367
+ const lineRef = (0, import_react45.useRef)(null);
13061
13368
  const { camera, size } = (0, import_fiber24.useThree)();
13062
13369
  const dash = resolveDash(dashSize, gapSize);
13063
- (0, import_react43.useLayoutEffect)(() => {
13370
+ (0, import_react45.useLayoutEffect)(() => {
13064
13371
  if (!dash.dashed) {
13065
13372
  return;
13066
13373
  }
@@ -13350,24 +13657,24 @@ function PolygonHotspot({
13350
13657
  onInvalid,
13351
13658
  ...anchorProps
13352
13659
  }) {
13353
- const issues = (0, import_react44.useMemo)(() => validatePolygonVertices(vertices), [vertices]);
13660
+ const issues = (0, import_react46.useMemo)(() => validatePolygonVertices(vertices), [vertices]);
13354
13661
  const valid = issues.length === 0;
13355
- const center = (0, import_react44.useMemo)(() => valid ? polygonCenter(vertices) : null, [valid, vertices]);
13356
- const fillGeometry = (0, import_react44.useMemo)(
13662
+ const center = (0, import_react46.useMemo)(() => valid ? polygonCenter(vertices) : null, [valid, vertices]);
13663
+ const fillGeometry = (0, import_react46.useMemo)(
13357
13664
  () => valid && center ? makeFillGeometry(vertices, center) : null,
13358
13665
  [center, valid, vertices]
13359
13666
  );
13360
- const strokePoints = (0, import_react44.useMemo)(
13667
+ const strokePoints = (0, import_react46.useMemo)(
13361
13668
  () => valid && center ? makeStrokePositions(vertices, center) : null,
13362
13669
  [center, valid, vertices]
13363
13670
  );
13364
13671
  const resolvedStrokeOpacity = Math.max(0, Math.min(strokeOpacity, 1));
13365
- const startVerticesRef = (0, import_react44.useRef)(null);
13672
+ const startVerticesRef = (0, import_react46.useRef)(null);
13366
13673
  const issuesKey = issues.map((issue) => issue.code).join(",");
13367
- (0, import_react44.useEffect)(() => {
13674
+ (0, import_react46.useEffect)(() => {
13368
13675
  if (!valid) onInvalid?.(issues);
13369
13676
  }, [issues, issuesKey, onInvalid, valid]);
13370
- (0, import_react44.useEffect)(() => () => fillGeometry?.dispose(), [fillGeometry]);
13677
+ (0, import_react46.useEffect)(() => () => fillGeometry?.dispose(), [fillGeometry]);
13371
13678
  if (!valid || !center || !fillGeometry || !strokePoints || strokePoints.length < 2) {
13372
13679
  return null;
13373
13680
  }
@@ -13447,7 +13754,7 @@ function PolygonHotspot({
13447
13754
  }
13448
13755
 
13449
13756
  // src/hotspot/polyline-hotspot.tsx
13450
- var import_react45 = require("react");
13757
+ var import_react47 = require("react");
13451
13758
  var import_three25 = require("three");
13452
13759
  var import_jsx_runtime30 = require("react/jsx-runtime");
13453
13760
  var POLYLINE_RADIUS = 990;
@@ -13566,16 +13873,16 @@ function PolylineHotspot({
13566
13873
  onInvalid,
13567
13874
  ...anchorProps
13568
13875
  }) {
13569
- const issues = (0, import_react45.useMemo)(() => validatePolylineVertices(vertices), [vertices]);
13876
+ const issues = (0, import_react47.useMemo)(() => validatePolylineVertices(vertices), [vertices]);
13570
13877
  const valid = issues.length === 0;
13571
- const center = (0, import_react45.useMemo)(() => valid ? polylineCenter(vertices) : null, [valid, vertices]);
13572
- const linePoints = (0, import_react45.useMemo)(
13878
+ const center = (0, import_react47.useMemo)(() => valid ? polylineCenter(vertices) : null, [valid, vertices]);
13879
+ const linePoints = (0, import_react47.useMemo)(
13573
13880
  () => valid && center ? makeLinePositions(vertices, center) : null,
13574
13881
  [center, valid, vertices]
13575
13882
  );
13576
13883
  const opacity = Math.max(0, Math.min(strokeOpacity, 1));
13577
- const startVerticesRef = (0, import_react45.useRef)(null);
13578
- (0, import_react45.useEffect)(() => {
13884
+ const startVerticesRef = (0, import_react47.useRef)(null);
13885
+ (0, import_react47.useEffect)(() => {
13579
13886
  if (!valid) onInvalid?.(issues);
13580
13887
  }, [issues, onInvalid, valid]);
13581
13888
  if (!valid || !center || !linePoints || linePoints.length < 2) return null;
@@ -13641,7 +13948,7 @@ function PolylineHotspot({
13641
13948
  }
13642
13949
 
13643
13950
  // src/hotspot/graphic-hotspot.tsx
13644
- var import_react46 = require("react");
13951
+ var import_react48 = require("react");
13645
13952
  var import_three26 = require("three");
13646
13953
  var import_jsx_runtime31 = require("react/jsx-runtime");
13647
13954
  var GRAPHIC_TEXTURE_SIZE = 512;
@@ -13832,12 +14139,12 @@ function createGraphicTexture(graphic, aspectWidth, aspectHeight) {
13832
14139
  return texture;
13833
14140
  }
13834
14141
  function useGraphicTexture(graphic, aspectWidth, aspectHeight, onLoad, onError) {
13835
- const [texture, setTexture] = (0, import_react46.useState)(null);
13836
- const onLoadRef = (0, import_react46.useRef)(onLoad);
13837
- const onErrorRef = (0, import_react46.useRef)(onError);
14142
+ const [texture, setTexture] = (0, import_react48.useState)(null);
14143
+ const onLoadRef = (0, import_react48.useRef)(onLoad);
14144
+ const onErrorRef = (0, import_react48.useRef)(onError);
13838
14145
  onLoadRef.current = onLoad;
13839
14146
  onErrorRef.current = onError;
13840
- (0, import_react46.useEffect)(() => {
14147
+ (0, import_react48.useEffect)(() => {
13841
14148
  let nextTexture = null;
13842
14149
  try {
13843
14150
  nextTexture = createGraphicTexture(graphic, aspectWidth, aspectHeight);
@@ -13876,7 +14183,7 @@ function GraphicHotspot(props) {
13876
14183
 
13877
14184
  // src/hotspot/sequence-hotspot.tsx
13878
14185
  var import_fiber25 = require("@react-three/fiber");
13879
- var import_react47 = require("react");
14186
+ var import_react49 = require("react");
13880
14187
  var import_three27 = require("three");
13881
14188
  var import_jsx_runtime32 = require("react/jsx-runtime");
13882
14189
  var DEFAULT_SEQUENCE_FPS = 12;
@@ -13893,12 +14200,12 @@ function useSpriteTexture({
13893
14200
  onLoadProgress
13894
14201
  }) {
13895
14202
  const gl = (0, import_fiber25.useThree)((state) => state.gl);
13896
- const [texture, setTexture] = (0, import_react47.useState)(null);
13897
- const onErrorRef = (0, import_react47.useRef)(onError);
13898
- const onLoadProgressRef = (0, import_react47.useRef)(onLoadProgress);
14203
+ const [texture, setTexture] = (0, import_react49.useState)(null);
14204
+ const onErrorRef = (0, import_react49.useRef)(onError);
14205
+ const onLoadProgressRef = (0, import_react49.useRef)(onLoadProgress);
13899
14206
  onErrorRef.current = onError;
13900
14207
  onLoadProgressRef.current = onLoadProgress;
13901
- (0, import_react47.useEffect)(() => {
14208
+ (0, import_react49.useEffect)(() => {
13902
14209
  let active = true;
13903
14210
  setTexture(null);
13904
14211
  if (!src) {
@@ -13939,7 +14246,7 @@ function useSpriteTexture({
13939
14246
  active = false;
13940
14247
  };
13941
14248
  }, [gl, id, src]);
13942
- (0, import_react47.useEffect)(
14249
+ (0, import_react49.useEffect)(
13943
14250
  () => () => {
13944
14251
  texture?.dispose();
13945
14252
  },
@@ -13968,24 +14275,24 @@ function SequenceHotspot({
13968
14275
  const texture = useSpriteTexture({ id, src, onError, onLoadProgress });
13969
14276
  const frameCount = resolveFrameCount(requestedFrameCount);
13970
14277
  const safeFps = resolveFps(fps);
13971
- const [frameIndex, setFrameIndex] = (0, import_react47.useState)(0);
13972
- const elapsedRef = (0, import_react47.useRef)(0);
13973
- const frameIndexRef = (0, import_react47.useRef)(0);
13974
- const endedRef = (0, import_react47.useRef)(false);
13975
- const lastPlaybackStateRef = (0, import_react47.useRef)(null);
13976
- const onFrameChangeRef = (0, import_react47.useRef)(onFrameChange);
13977
- const onPlaybackStateChangeRef = (0, import_react47.useRef)(onPlaybackStateChange);
13978
- const onEndedRef = (0, import_react47.useRef)(onEnded);
14278
+ const [frameIndex, setFrameIndex] = (0, import_react49.useState)(0);
14279
+ const elapsedRef = (0, import_react49.useRef)(0);
14280
+ const frameIndexRef = (0, import_react49.useRef)(0);
14281
+ const endedRef = (0, import_react49.useRef)(false);
14282
+ const lastPlaybackStateRef = (0, import_react49.useRef)(null);
14283
+ const onFrameChangeRef = (0, import_react49.useRef)(onFrameChange);
14284
+ const onPlaybackStateChangeRef = (0, import_react49.useRef)(onPlaybackStateChange);
14285
+ const onEndedRef = (0, import_react49.useRef)(onEnded);
13979
14286
  onFrameChangeRef.current = onFrameChange;
13980
14287
  onPlaybackStateChangeRef.current = onPlaybackStateChange;
13981
14288
  onEndedRef.current = onEnded;
13982
- (0, import_react47.useEffect)(() => {
14289
+ (0, import_react49.useEffect)(() => {
13983
14290
  elapsedRef.current = 0;
13984
14291
  frameIndexRef.current = 0;
13985
14292
  endedRef.current = false;
13986
14293
  setFrameIndex(0);
13987
14294
  }, [frameCount, frameDirection, src]);
13988
- (0, import_react47.useEffect)(() => {
14295
+ (0, import_react49.useEffect)(() => {
13989
14296
  if (!texture) {
13990
14297
  return;
13991
14298
  }
@@ -13999,13 +14306,13 @@ function SequenceHotspot({
13999
14306
  );
14000
14307
  texture.needsUpdate = true;
14001
14308
  }, [frameCount, frameDirection, frameIndex, texture]);
14002
- (0, import_react47.useEffect)(() => {
14309
+ (0, import_react49.useEffect)(() => {
14003
14310
  if (!texture) {
14004
14311
  return;
14005
14312
  }
14006
14313
  onFrameChangeRef.current?.({ id, index: 0, src });
14007
14314
  }, [id, src, texture]);
14008
- (0, import_react47.useEffect)(() => {
14315
+ (0, import_react49.useEffect)(() => {
14009
14316
  if (!texture) {
14010
14317
  return;
14011
14318
  }
@@ -14059,7 +14366,7 @@ function SequenceHotspot({
14059
14366
 
14060
14367
  // src/hotspot/video-hotspot.tsx
14061
14368
  var import_fiber26 = require("@react-three/fiber");
14062
- var import_react48 = require("react");
14369
+ var import_react50 = require("react");
14063
14370
  var import_three28 = require("three");
14064
14371
  var import_jsx_runtime33 = require("react/jsx-runtime");
14065
14372
  function clampVolume2(volume) {
@@ -14070,10 +14377,10 @@ function clampVolume2(volume) {
14070
14377
  }
14071
14378
  function usePosterTexture2(id, poster, onError) {
14072
14379
  const gl = (0, import_fiber26.useThree)((state) => state.gl);
14073
- const [texture, setTexture] = (0, import_react48.useState)(null);
14074
- const onErrorRef = (0, import_react48.useRef)(onError);
14380
+ const [texture, setTexture] = (0, import_react50.useState)(null);
14381
+ const onErrorRef = (0, import_react50.useRef)(onError);
14075
14382
  onErrorRef.current = onError;
14076
- (0, import_react48.useEffect)(() => {
14383
+ (0, import_react50.useEffect)(() => {
14077
14384
  let active = true;
14078
14385
  setTexture(null);
14079
14386
  if (!poster) {
@@ -14110,7 +14417,7 @@ function usePosterTexture2(id, poster, onError) {
14110
14417
  active = false;
14111
14418
  };
14112
14419
  }, [gl, id, poster]);
14113
- (0, import_react48.useEffect)(
14420
+ (0, import_react50.useEffect)(
14114
14421
  () => () => {
14115
14422
  texture?.dispose();
14116
14423
  },
@@ -14128,14 +14435,14 @@ function useVideoResource({
14128
14435
  poster,
14129
14436
  src
14130
14437
  }) {
14131
- const [resource, setResource] = (0, import_react48.useState)(null);
14132
- const onEndedRef = (0, import_react48.useRef)(onEnded);
14133
- const onErrorRef = (0, import_react48.useRef)(onError);
14134
- const onPlaybackStateChangeRef = (0, import_react48.useRef)(onPlaybackStateChange);
14438
+ const [resource, setResource] = (0, import_react50.useState)(null);
14439
+ const onEndedRef = (0, import_react50.useRef)(onEnded);
14440
+ const onErrorRef = (0, import_react50.useRef)(onError);
14441
+ const onPlaybackStateChangeRef = (0, import_react50.useRef)(onPlaybackStateChange);
14135
14442
  onEndedRef.current = onEnded;
14136
14443
  onErrorRef.current = onError;
14137
14444
  onPlaybackStateChangeRef.current = onPlaybackStateChange;
14138
- (0, import_react48.useEffect)(() => {
14445
+ (0, import_react50.useEffect)(() => {
14139
14446
  if (!src) {
14140
14447
  setResource(null);
14141
14448
  return;
@@ -14236,11 +14543,11 @@ function VideoHotspot({
14236
14543
  src
14237
14544
  });
14238
14545
  const posterTexture = usePosterTexture2(id, poster, onError);
14239
- const onPlaybackErrorRef = (0, import_react48.useRef)(onPlaybackError);
14240
- const onPlaybackStateChangeRef = (0, import_react48.useRef)(onPlaybackStateChange);
14546
+ const onPlaybackErrorRef = (0, import_react50.useRef)(onPlaybackError);
14547
+ const onPlaybackStateChangeRef = (0, import_react50.useRef)(onPlaybackStateChange);
14241
14548
  onPlaybackErrorRef.current = onPlaybackError;
14242
14549
  onPlaybackStateChangeRef.current = onPlaybackStateChange;
14243
- (0, import_react48.useEffect)(() => {
14550
+ (0, import_react50.useEffect)(() => {
14244
14551
  if (!resource) {
14245
14552
  return;
14246
14553
  }
@@ -14250,7 +14557,7 @@ function VideoHotspot({
14250
14557
  resource.video.playsInline = playsInline;
14251
14558
  resource.video.preload = preload;
14252
14559
  }, [loop, muted, playsInline, preload, resource, volume]);
14253
- (0, import_react48.useEffect)(() => {
14560
+ (0, import_react50.useEffect)(() => {
14254
14561
  if (!resource) {
14255
14562
  return;
14256
14563
  }
@@ -14278,7 +14585,7 @@ function VideoHotspot({
14278
14585
 
14279
14586
  // src/hotspot/audio-hotspot.tsx
14280
14587
  var import_fiber27 = require("@react-three/fiber");
14281
- var import_react49 = require("react");
14588
+ var import_react51 = require("react");
14282
14589
  var import_three29 = require("three");
14283
14590
  var import_jsx_runtime34 = require("react/jsx-runtime");
14284
14591
  var SPEAKER_TEXTURE_SIZE = 512;
@@ -14344,8 +14651,8 @@ function createSpeakerTexture(state) {
14344
14651
  return texture;
14345
14652
  }
14346
14653
  function useSpeakerTextures(enabled) {
14347
- const [textures, setTextures] = (0, import_react49.useState)({ playing: null, stopped: null });
14348
- (0, import_react49.useEffect)(() => {
14654
+ const [textures, setTextures] = (0, import_react51.useState)({ playing: null, stopped: null });
14655
+ (0, import_react51.useEffect)(() => {
14349
14656
  if (!enabled) {
14350
14657
  setTextures({ playing: null, stopped: null });
14351
14658
  return;
@@ -14362,10 +14669,10 @@ function useSpeakerTextures(enabled) {
14362
14669
  }
14363
14670
  function useIconTexture(icon, enabled, onError, id) {
14364
14671
  const gl = (0, import_fiber27.useThree)((state) => state.gl);
14365
- const [texture, setTexture] = (0, import_react49.useState)(null);
14366
- const onErrorRef = (0, import_react49.useRef)(onError);
14672
+ const [texture, setTexture] = (0, import_react51.useState)(null);
14673
+ const onErrorRef = (0, import_react51.useRef)(onError);
14367
14674
  onErrorRef.current = onError;
14368
- (0, import_react49.useEffect)(() => {
14675
+ (0, import_react51.useEffect)(() => {
14369
14676
  let active = true;
14370
14677
  setTexture(null);
14371
14678
  if (!enabled || !icon) {
@@ -14402,7 +14709,7 @@ function useIconTexture(icon, enabled, onError, id) {
14402
14709
  active = false;
14403
14710
  };
14404
14711
  }, [enabled, gl, icon, id]);
14405
- (0, import_react49.useEffect)(
14712
+ (0, import_react51.useEffect)(
14406
14713
  () => () => {
14407
14714
  texture?.dispose();
14408
14715
  },
@@ -14421,13 +14728,13 @@ function useAudioHowl({
14421
14728
  playing,
14422
14729
  src
14423
14730
  }) {
14424
- const [howl, setHowl] = (0, import_react49.useState)(null);
14425
- const playingRef = (0, import_react49.useRef)(playing);
14426
- const loopRef = (0, import_react49.useRef)(loop ?? false);
14427
- const onEndedRef = (0, import_react49.useRef)(onEnded);
14428
- const onErrorRef = (0, import_react49.useRef)(onError);
14429
- const onPlaybackErrorRef = (0, import_react49.useRef)(onPlaybackError);
14430
- const onPlaybackStateChangeRef = (0, import_react49.useRef)(onPlaybackStateChange);
14731
+ const [howl, setHowl] = (0, import_react51.useState)(null);
14732
+ const playingRef = (0, import_react51.useRef)(playing);
14733
+ const loopRef = (0, import_react51.useRef)(loop ?? false);
14734
+ const onEndedRef = (0, import_react51.useRef)(onEnded);
14735
+ const onErrorRef = (0, import_react51.useRef)(onError);
14736
+ const onPlaybackErrorRef = (0, import_react51.useRef)(onPlaybackError);
14737
+ const onPlaybackStateChangeRef = (0, import_react51.useRef)(onPlaybackStateChange);
14431
14738
  playingRef.current = playing;
14432
14739
  loopRef.current = loop ?? false;
14433
14740
  onEndedRef.current = onEnded;
@@ -14435,7 +14742,7 @@ function useAudioHowl({
14435
14742
  onPlaybackErrorRef.current = onPlaybackError;
14436
14743
  onPlaybackStateChangeRef.current = onPlaybackStateChange;
14437
14744
  const sourcesKey = sourceList(src).join("\0");
14438
- (0, import_react49.useEffect)(() => {
14745
+ (0, import_react51.useEffect)(() => {
14439
14746
  const sources = sourcesKey.length > 0 ? sourcesKey.split("\0") : [];
14440
14747
  if (sources.length === 0) {
14441
14748
  setHowl(null);
@@ -14472,7 +14779,7 @@ function useAudioHowl({
14472
14779
  handle.dispose();
14473
14780
  };
14474
14781
  }, [crossOrigin, id, sourcesKey]);
14475
- (0, import_react49.useEffect)(() => {
14782
+ (0, import_react51.useEffect)(() => {
14476
14783
  howl?.loop(loop ?? false);
14477
14784
  }, [howl, loop]);
14478
14785
  return howl;
@@ -14515,15 +14822,15 @@ function AudioHotspot({
14515
14822
  const stoppedIconTexture = useIconTexture(icon, marker, onError, id);
14516
14823
  const playingIconTexture = useIconTexture(playingIcon, marker, onError, id);
14517
14824
  const markerTexture = playing ? playingIconTexture ?? stoppedIconTexture ?? speakerTextures.playing : stoppedIconTexture ?? speakerTextures.stopped;
14518
- const playingRef = (0, import_react49.useRef)(playing);
14825
+ const playingRef = (0, import_react51.useRef)(playing);
14519
14826
  playingRef.current = playing;
14520
- const mutedRef = (0, import_react49.useRef)(muted);
14521
- const volumeRef = (0, import_react49.useRef)(volume);
14522
- const rangeRef = (0, import_react49.useRef)(range);
14827
+ const mutedRef = (0, import_react51.useRef)(muted);
14828
+ const volumeRef = (0, import_react51.useRef)(volume);
14829
+ const rangeRef = (0, import_react51.useRef)(range);
14523
14830
  mutedRef.current = muted;
14524
14831
  volumeRef.current = volume;
14525
14832
  rangeRef.current = range;
14526
- (0, import_react49.useEffect)(() => {
14833
+ (0, import_react51.useEffect)(() => {
14527
14834
  if (!howl) {
14528
14835
  return;
14529
14836
  }
@@ -14533,7 +14840,7 @@ function AudioHotspot({
14533
14840
  }
14534
14841
  howl.play();
14535
14842
  }, [howl, playing]);
14536
- (0, import_react49.useEffect)(() => {
14843
+ (0, import_react51.useEffect)(() => {
14537
14844
  if (!howl || !pauseWhenHidden) {
14538
14845
  return;
14539
14846
  }
@@ -14568,7 +14875,7 @@ function AudioHotspot({
14568
14875
  }
14569
14876
 
14570
14877
  // src/hotspot/text-hotspot.tsx
14571
- var import_react50 = require("react");
14878
+ var import_react52 = require("react");
14572
14879
  var import_three30 = require("three");
14573
14880
  var import_jsx_runtime35 = require("react/jsx-runtime");
14574
14881
  var TEXT_TEXTURE_LONG_SIDE = 1024;
@@ -14790,12 +15097,12 @@ function createTextTexture(text, width, height, style) {
14790
15097
  return texture;
14791
15098
  }
14792
15099
  function useTextTexture(text, width, height, style, onLoad, onError) {
14793
- const [texture, setTexture] = (0, import_react50.useState)(null);
14794
- const onLoadRef = (0, import_react50.useRef)(onLoad);
14795
- const onErrorRef = (0, import_react50.useRef)(onError);
15100
+ const [texture, setTexture] = (0, import_react52.useState)(null);
15101
+ const onLoadRef = (0, import_react52.useRef)(onLoad);
15102
+ const onErrorRef = (0, import_react52.useRef)(onError);
14796
15103
  onLoadRef.current = onLoad;
14797
15104
  onErrorRef.current = onError;
14798
- (0, import_react50.useEffect)(() => {
15105
+ (0, import_react52.useEffect)(() => {
14799
15106
  let cancelled = false;
14800
15107
  let nextTexture = null;
14801
15108
  const run = async () => {