@ericchen1990/pano-view 0.1.5 → 0.2.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/README.md +276 -7
- package/dist/index.cjs +2410 -653
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +395 -12
- package/dist/index.d.ts +395 -12
- package/dist/index.mjs +2423 -671
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/pano-view.tsx","../src/panorama-controls.tsx","../src/auto-rotate.tsx","../src/hotspot/accessibility.tsx","../src/panorama-event-surface.tsx","../src/hotspot/coordinates.ts","../src/hotspot/types.ts","../src/panorama-radius.ts","../src/sphere.tsx","../src/panorama-scenes.tsx","../src/tile/texture-manager-context.tsx","../src/tile/texture-manager.ts","../src/tile/tile.tsx","../src/tile/face-layout.ts","../src/tile/multires.ts","../src/hotspot/image-hotspot.tsx","../src/hotspot/hotspot-anchor.tsx","../src/hotspot/polygon-hotspot.tsx","../src/hotspot/polyline-hotspot.tsx","../src/hotspot/graphic-hotspot.tsx","../src/hotspot/sequence-hotspot.tsx","../src/hotspot/video-hotspot.tsx"],"sourcesContent":["export { PanoView } from \"./pano-view\";\nexport type { PanoViewProps } from \"./pano-view\";\nexport { AutoRotate } from \"./auto-rotate\";\nexport type { AutoRotateProps } from \"./auto-rotate\";\nexport { Sphere } from \"./sphere\";\nexport type { SphereProps } from \"./sphere\";\nexport { PanoramaScenes } from \"./panorama-scenes\";\nexport type {\n PanoramaScene,\n PanoramaScenesProps,\n PanoramaTransition,\n PanoramaTransitionEndEvent,\n PanoramaTransitionErrorEvent,\n PanoramaTransitionPreset,\n SpherePanoramaScene,\n TilePanoramaScene,\n} from \"./panorama-scenes\";\nexport { ImageHotspot } from \"./hotspot/image-hotspot\";\nexport type { ImageHotspotProps } from \"./hotspot/image-hotspot\";\nexport { PolygonHotspot } from \"./hotspot/polygon-hotspot\";\nexport type {\n PolygonHotspotProps,\n PolygonValidationCode,\n PolygonValidationIssue,\n PolygonVerticesChangeEvent,\n} from \"./hotspot/polygon-hotspot\";\nexport { PolylineHotspot, validatePolylineVertices } from \"./hotspot/polyline-hotspot\";\nexport type {\n PolylineHotspotProps,\n PolylineValidationIssue,\n PolylineVerticesChangeEvent,\n} from \"./hotspot/polyline-hotspot\";\nexport {\n unwrapPolygonVertices,\n validatePolygonVertices,\n} from \"./hotspot/polygon-hotspot\";\nexport { GraphicHotspot } from \"./hotspot/graphic-hotspot\";\nexport type {\n CircleGraphic,\n GraphicDefinition,\n GraphicHotspotProps,\n RectangleGraphic,\n RingGraphic,\n SvgGraphic,\n SvgPathGraphic,\n} from \"./hotspot/graphic-hotspot\";\nexport { SequenceHotspot } from \"./hotspot/sequence-hotspot\";\nexport type {\n SequenceFrameEvent,\n SequenceFrameDirection,\n SequenceHotspotErrorEvent,\n SequenceHotspotProps,\n SequenceLoadProgress,\n SequencePlaybackState,\n} from \"./hotspot/sequence-hotspot\";\nexport { VideoHotspot } from \"./hotspot/video-hotspot\";\nexport type {\n VideoHotspotErrorEvent,\n VideoHotspotProps,\n VideoPlaybackState,\n} from \"./hotspot/video-hotspot\";\nexport { Tile } from \"./tile/tile\";\nexport type {\n CubeFaceCode,\n TileAddress,\n TileLoadError,\n TileLoadProgress,\n TileMultiresConfig,\n TileProps,\n} from \"./tile/types\";\nexport type {\n PanoramaControlsOptions,\n PanoViewHandle,\n PanoViewState,\n SetPanoViewOptions,\n} from \"./types\";\nexport {\n clampPanoPitch,\n normalizePanoPosition,\n normalizePanoYaw,\n panoPositionToVector3,\n vector3ToPanoPosition,\n} from \"./hotspot/coordinates\";\nexport { MAX_HOTSPOT_PITCH } from \"./hotspot/types\";\nexport type {\n HotspotDragEvent,\n HotspotInputSource,\n HotspotInteractionEvent,\n HotspotCommonProps,\n HotspotMode,\n HotspotScaleMode,\n HotspotPosition,\n PanoramaPointerEvent,\n} from \"./hotspot/types\";\nexport type {\n GraphicHotspotDefinition,\n HotspotDefinition,\n HotspotDefinitionBase,\n ImageHotspotDefinition,\n PointHotspotDefinition,\n PointHotspotDefinitionBase,\n PolygonHotspotDefinition,\n PolylineHotspotDefinition,\n SequenceHotspotDefinition,\n VideoHotspotDefinition,\n} from \"./hotspot/definitions\";\n","import { Canvas } from \"@react-three/fiber\";\nimport {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type {\n ComponentPropsWithoutRef,\n CSSProperties,\n ReactNode,\n} from \"react\";\nimport {\n PanoramaControls,\n type PanoramaControlsHandle,\n} from \"./panorama-controls\";\nimport { AutoRotate, PanoramaControlsContext } from \"./auto-rotate\";\nimport {\n HotspotAccessibilityContext,\n useHotspotAccessibilityLayer,\n} from \"./hotspot/accessibility\";\nimport type { PanoramaPointerEvent } from \"./hotspot/types\";\nimport { PanoramaEventSurface } from \"./panorama-event-surface\";\nimport {\n DEFAULT_PANORAMA_CAMERA_FAR,\n DEFAULT_PANORAMA_CAMERA_NEAR,\n} from \"./panorama-radius\";\nimport type {\n PanoramaControlsOptions,\n PanoViewHandle,\n PanoViewState,\n} from \"./types\";\n\nconst DEFAULT_VIEW: PanoViewState = {\n yaw: 0,\n pitch: 0,\n fov: 75,\n};\n\nconst DEFAULT_CANVAS_STYLE: CSSProperties = {\n display: \"block\",\n height: \"100%\",\n width: \"100%\",\n};\n\nexport type PanoViewProps = Omit<\n ComponentPropsWithoutRef<\"div\">,\n \"children\" | \"onChange\"\n> & {\n children?: ReactNode;\n initialView?: Partial<PanoViewState>;\n minFov?: number;\n maxFov?: number;\n controls?: boolean | PanoramaControlsOptions;\n onViewChange?: (view: PanoViewState) => void;\n onPanoramaClick?: (event: PanoramaPointerEvent) => void;\n onPanoramaDoubleClick?: (event: PanoramaPointerEvent) => void;\n onPanoramaPointerMove?: (event: PanoramaPointerEvent) => void;\n /** Canvas pixel ratio. Defaults to a capped range of 1–2. */\n dpr?: number | [number, number];\n};\n\nexport const PanoView = forwardRef<PanoViewHandle, PanoViewProps>(\n function PanoView(\n {\n children,\n initialView,\n minFov = 30,\n maxFov = 100,\n controls = true,\n onViewChange,\n onPanoramaClick,\n onPanoramaDoubleClick,\n onPanoramaPointerMove,\n dpr = [1, 2],\n style,\n \"aria-label\": ariaLabel = \"Panorama viewer\",\n ...divProps\n },\n ref,\n ) {\n const rootRef = useRef<HTMLDivElement>(null);\n const controlsRef = useRef<PanoramaControlsHandle>(null);\n const { controls: hotspotAccessibilityControls, registry } =\n useHotspotAccessibilityLayer();\n const fallbackViewRef = useRef<PanoViewState>(DEFAULT_VIEW);\n const normalizedMinFov = Math.max(1, Math.min(minFov, maxFov - 1));\n const normalizedMaxFov = Math.min(\n 179,\n Math.max(maxFov, normalizedMinFov + 1),\n );\n const normalizedInitialView = useMemo<PanoViewState>(\n () => ({\n yaw: initialView?.yaw ?? DEFAULT_VIEW.yaw,\n pitch: initialView?.pitch ?? DEFAULT_VIEW.pitch,\n fov: Math.max(\n normalizedMinFov,\n Math.min(initialView?.fov ?? DEFAULT_VIEW.fov, normalizedMaxFov),\n ),\n }),\n [\n initialView?.fov,\n initialView?.pitch,\n initialView?.yaw,\n normalizedMaxFov,\n normalizedMinFov,\n ],\n );\n fallbackViewRef.current = normalizedInitialView;\n\n const controlsEnabled = controls !== false;\n const controlOptions = useMemo<PanoramaControlsOptions>(\n () => (typeof controls === \"object\" ? controls : {}),\n [controls],\n );\n // Bridge deprecated controls.autoRotate / autoRotateSpeed without\n // surfacing @deprecated diagnostics on this compatibility path.\n const legacyAutoRotateOptions = controlOptions as {\n autoRotate?: boolean;\n autoRotateSpeed?: number;\n };\n const [legacyAutoRotate, setLegacyAutoRotate] = useState(\n legacyAutoRotateOptions.autoRotate ?? false,\n );\n\n useEffect(() => {\n setLegacyAutoRotate(legacyAutoRotateOptions.autoRotate ?? false);\n }, [legacyAutoRotateOptions.autoRotate]);\n\n useImperativeHandle(\n ref,\n () => ({\n getView: () =>\n controlsRef.current?.getView() ?? { ...fallbackViewRef.current },\n setView: (view, options) => {\n controlsRef.current?.setView(view, options);\n },\n reset: () => {\n controlsRef.current?.reset();\n },\n startAutoRotate: () => {\n setLegacyAutoRotate(true);\n },\n stopAutoRotate: () => {\n setLegacyAutoRotate(false);\n },\n toggleFullscreen: async () => {\n if (typeof document === \"undefined\") {\n return;\n }\n if (document.fullscreenElement) {\n await document.exitFullscreen?.();\n return;\n }\n await rootRef.current?.requestFullscreen?.();\n },\n }),\n [],\n );\n\n const rootStyle = useMemo<CSSProperties>(\n () => ({\n overflow: \"hidden\",\n position: \"relative\",\n ...style,\n }),\n [style],\n );\n\n return (\n <div\n {...divProps}\n ref={rootRef}\n aria-label={ariaLabel}\n style={rootStyle}\n >\n <Canvas\n aria-label={`${ariaLabel} canvas`}\n camera={{\n far: DEFAULT_PANORAMA_CAMERA_FAR,\n fov: normalizedInitialView.fov,\n near: DEFAULT_PANORAMA_CAMERA_NEAR,\n position: [0, 0, 0.01],\n }}\n dpr={dpr}\n gl={{\n // Hotspots contain transparent textures and curved outlines. Keep\n // the canvas multisampled so their visible edges are smoothed.\n antialias: true,\n powerPreference: \"high-performance\",\n stencil: false,\n }}\n style={{\n ...DEFAULT_CANVAS_STYLE,\n touchAction: controlsEnabled ? \"none\" : \"auto\",\n }}\n tabIndex={controlsEnabled ? 0 : undefined}\n >\n <HotspotAccessibilityContext.Provider value={registry}>\n <PanoramaControlsContext.Provider value={controlsRef}>\n <PanoramaControls\n ref={controlsRef}\n enabled={controlsEnabled}\n initialView={normalizedInitialView}\n maxFov={normalizedMaxFov}\n minFov={normalizedMinFov}\n onViewChange={onViewChange}\n options={controlOptions}\n />\n <AutoRotate\n enabled={legacyAutoRotate}\n speed={legacyAutoRotateOptions.autoRotateSpeed}\n />\n <PanoramaEventSurface\n onClick={onPanoramaClick}\n onDoubleClick={onPanoramaDoubleClick}\n onPointerMove={onPanoramaPointerMove}\n />\n {children}\n </PanoramaControlsContext.Provider>\n </HotspotAccessibilityContext.Provider>\n </Canvas>\n {hotspotAccessibilityControls}\n </div>\n );\n },\n);\n","import { useFrame, useThree } from \"@react-three/fiber\";\nimport {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n} from \"react\";\nimport { Euler, MathUtils, PerspectiveCamera } from \"three\";\nimport type {\n PanoramaControlsOptions,\n PanoViewState,\n SetPanoViewOptions,\n} from \"./types\";\n\nconst MAX_PITCH = 89.9;\nconst INERTIA_ROTATION_DAMPING = 8;\nconst INERTIA_ZOOM_DAMPING = 12;\nconst DEFAULT_ROTATE_DAMPING = 14;\nconst DEFAULT_ZOOM_DAMPING = 16;\nconst MIN_ROTATION_VELOCITY = 0.01;\nconst MIN_ZOOM_VELOCITY = 0.01;\nconst VIEW_SETTLE_EPSILON = 0.001;\n\ntype PointerPosition = {\n x: number;\n y: number;\n at: number;\n};\n\nexport type PanoramaControlsHandle = {\n getView: () => PanoViewState;\n setView: (\n view: Partial<PanoViewState>,\n options?: SetPanoViewOptions,\n ) => void;\n reset: () => void;\n applyAutoRotation: (yawDelta: number) => boolean;\n acquireInteractionLock: () => () => void;\n};\n\ntype PanoramaControlsProps = {\n enabled: boolean;\n initialView: PanoViewState;\n minFov: number;\n maxFov: number;\n options: PanoramaControlsOptions;\n onViewChange?: (view: PanoViewState) => void;\n};\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n\nfunction normalizeYaw(yaw: number): number {\n return MathUtils.euclideanModulo(yaw + 180, 360) - 180;\n}\n\nfunction shortestYawDelta(from: number, to: number): number {\n return normalizeYaw(to - from);\n}\n\nfunction dampingFactor(damping: number, deltaSeconds: number): number {\n return damping === 0 ? 1 : 1 - Math.exp(-damping * deltaSeconds);\n}\n\nfunction resolveDamping(value: number | undefined, fallback: number): number {\n return Number.isFinite(value) && value! >= 0 ? value! : fallback;\n}\n\nfunction pointerDistance(a: PointerPosition, b: PointerPosition): number {\n return Math.hypot(a.x - b.x, a.y - b.y);\n}\n\nfunction viewsEqual(a: PanoViewState, b: PanoViewState): boolean {\n return a.yaw === b.yaw && a.pitch === b.pitch && a.fov === b.fov;\n}\n\nexport const PanoramaControls = forwardRef<\n PanoramaControlsHandle,\n PanoramaControlsProps\n>(function PanoramaControls(\n { enabled, initialView, minFov, maxFov, options, onViewChange },\n ref,\n) {\n const { camera, gl } = useThree();\n const viewRef = useRef<PanoViewState>({ ...initialView });\n const targetViewRef = useRef<PanoViewState>({ ...initialView });\n const initialViewRef = useRef<PanoViewState>({ ...initialView });\n const pointersRef = useRef(new Map<number, PointerPosition>());\n const pinchDistanceRef = useRef<number | null>(null);\n const yawVelocityRef = useRef(0);\n const pitchVelocityRef = useRef(0);\n const zoomVelocityRef = useRef(0);\n const dirtyRef = useRef(true);\n const interactingRef = useRef(false);\n const interactionLockCountRef = useRef(0);\n const optionsRef = useRef(options);\n const onViewChangeRef = useRef(onViewChange);\n const lastEmittedViewRef = useRef<PanoViewState | null>(null);\n const eulerRef = useRef(new Euler(0, 0, 0, \"YXZ\"));\n\n optionsRef.current = options;\n onViewChangeRef.current = onViewChange;\n\n const constrainView = (\n view: Partial<PanoViewState>,\n current: PanoViewState = targetViewRef.current,\n ): PanoViewState => {\n return {\n yaw: normalizeYaw(view.yaw ?? current.yaw),\n pitch: clamp(view.pitch ?? current.pitch, -MAX_PITCH, MAX_PITCH),\n fov: clamp(view.fov ?? current.fov, minFov, maxFov),\n };\n };\n\n const stopVelocity = () => {\n yawVelocityRef.current = 0;\n pitchVelocityRef.current = 0;\n zoomVelocityRef.current = 0;\n };\n\n const acquireInteractionLock = () => {\n interactionLockCountRef.current += 1;\n stopVelocity();\n interactingRef.current = false;\n pinchDistanceRef.current = null;\n for (const pointerId of pointersRef.current.keys()) {\n if (gl.domElement.hasPointerCapture?.(pointerId)) {\n gl.domElement.releasePointerCapture?.(pointerId);\n }\n }\n pointersRef.current.clear();\n\n let released = false;\n return () => {\n if (released) {\n return;\n }\n released = true;\n interactionLockCountRef.current = Math.max(\n 0,\n interactionLockCountRef.current - 1,\n );\n };\n };\n\n const setView = (\n view: Partial<PanoViewState>,\n setOptions?: SetPanoViewOptions,\n ) => {\n const nextView = constrainView(view);\n targetViewRef.current = nextView;\n viewRef.current = nextView;\n if (setOptions?.immediate !== false) {\n stopVelocity();\n }\n dirtyRef.current = true;\n };\n\n useImperativeHandle(\n ref,\n () => ({\n getView: () => ({ ...viewRef.current }),\n setView,\n reset: () => setView(initialViewRef.current),\n acquireInteractionLock,\n applyAutoRotation: (yawDelta: number) => {\n const inertiaFinished =\n yawVelocityRef.current === 0 &&\n pitchVelocityRef.current === 0 &&\n zoomVelocityRef.current === 0;\n if (\n !Number.isFinite(yawDelta) ||\n interactionLockCountRef.current > 0 ||\n interactingRef.current ||\n !inertiaFinished\n ) {\n return false;\n }\n\n targetViewRef.current.yaw += yawDelta;\n dirtyRef.current = true;\n return true;\n },\n }),\n [gl, maxFov, minFov],\n );\n\n useEffect(() => {\n initialViewRef.current = { ...initialView };\n setView(initialView);\n }, [initialView.fov, initialView.pitch, initialView.yaw]);\n\n useEffect(() => {\n const element = gl.domElement;\n if (!enabled) {\n pointersRef.current.clear();\n interactingRef.current = false;\n return;\n }\n\n const updatePointer = (event: PointerEvent) => {\n const previous = pointersRef.current.get(event.pointerId);\n const now = performance.now();\n const next = { x: event.clientX, y: event.clientY, at: now };\n pointersRef.current.set(event.pointerId, next);\n return { previous, next };\n };\n\n const onPointerDown = (event: PointerEvent) => {\n if (interactionLockCountRef.current > 0) {\n return;\n }\n event.preventDefault();\n interactingRef.current = true;\n stopVelocity();\n pointersRef.current.set(event.pointerId, {\n x: event.clientX,\n y: event.clientY,\n at: performance.now(),\n });\n element.setPointerCapture?.(event.pointerId);\n\n if (pointersRef.current.size === 2) {\n const [first, second] = Array.from(pointersRef.current.values());\n pinchDistanceRef.current = pointerDistance(first!, second!);\n }\n };\n\n const onPointerMove = (event: PointerEvent) => {\n if (interactionLockCountRef.current > 0) {\n return;\n }\n if (!pointersRef.current.has(event.pointerId)) {\n return;\n }\n\n event.preventDefault();\n const { previous, next } = updatePointer(event);\n if (!previous) {\n return;\n }\n\n const pointers = Array.from(pointersRef.current.values());\n if (pointers.length >= 2) {\n const distance = pointerDistance(pointers[0]!, pointers[1]!);\n const previousDistance = pinchDistanceRef.current;\n pinchDistanceRef.current = distance;\n if (previousDistance && distance > 0) {\n const currentFov = targetViewRef.current.fov;\n const nextFov = clamp(\n currentFov * (previousDistance / distance),\n minFov,\n maxFov,\n );\n const elapsed = Math.max((next.at - previous.at) / 1000, 1 / 120);\n zoomVelocityRef.current = (nextFov - currentFov) / elapsed;\n targetViewRef.current = {\n ...targetViewRef.current,\n fov: nextFov,\n };\n dirtyRef.current = true;\n }\n return;\n }\n\n const rect = element.getBoundingClientRect();\n const rotateSpeed = optionsRef.current.rotateSpeed ?? 0.35;\n const deltaYaw =\n (-(next.x - previous.x) * 360 * rotateSpeed) /\n Math.max(rect.width, 1);\n const deltaPitch =\n ((next.y - previous.y) * 180 * rotateSpeed) /\n Math.max(rect.height, 1);\n const elapsed = Math.max((next.at - previous.at) / 1000, 1 / 120);\n\n targetViewRef.current = constrainView({\n yaw: targetViewRef.current.yaw + deltaYaw,\n pitch: targetViewRef.current.pitch + deltaPitch,\n });\n yawVelocityRef.current = deltaYaw / elapsed;\n pitchVelocityRef.current = deltaPitch / elapsed;\n dirtyRef.current = true;\n };\n\n const releasePointer = (event: PointerEvent) => {\n pointersRef.current.delete(event.pointerId);\n if (element.hasPointerCapture?.(event.pointerId)) {\n element.releasePointerCapture?.(event.pointerId);\n }\n if (pointersRef.current.size < 2) {\n pinchDistanceRef.current = null;\n }\n interactingRef.current = pointersRef.current.size > 0;\n };\n\n const onWheel = (event: WheelEvent) => {\n if (interactionLockCountRef.current > 0) {\n event.preventDefault();\n return;\n }\n event.preventDefault();\n const zoomSpeed = optionsRef.current.zoomSpeed ?? 0.08;\n const delta = event.deltaY * zoomSpeed;\n const nextFov = clamp(\n targetViewRef.current.fov + delta,\n minFov,\n maxFov,\n );\n zoomVelocityRef.current = clamp(\n zoomVelocityRef.current + delta * 12,\n -180,\n 180,\n );\n targetViewRef.current = {\n ...targetViewRef.current,\n fov: nextFov,\n };\n dirtyRef.current = true;\n };\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (interactionLockCountRef.current > 0) {\n return;\n }\n if (optionsRef.current.keyboard === false) {\n return;\n }\n\n const step = event.shiftKey ? 10 : 3;\n let next: Partial<PanoViewState> | null = null;\n if (event.key === \"ArrowLeft\") {\n next = { yaw: targetViewRef.current.yaw - step };\n } else if (event.key === \"ArrowRight\") {\n next = { yaw: targetViewRef.current.yaw + step };\n } else if (event.key === \"ArrowUp\") {\n next = { pitch: targetViewRef.current.pitch + step };\n } else if (event.key === \"ArrowDown\") {\n next = { pitch: targetViewRef.current.pitch - step };\n } else if (event.key === \"+\" || event.key === \"=\") {\n next = { fov: targetViewRef.current.fov - step };\n } else if (event.key === \"-\" || event.key === \"_\") {\n next = { fov: targetViewRef.current.fov + step };\n } else if (event.key === \"0\") {\n setView(initialViewRef.current);\n event.preventDefault();\n return;\n }\n\n if (next) {\n event.preventDefault();\n targetViewRef.current = constrainView(next);\n dirtyRef.current = true;\n }\n };\n\n element.addEventListener(\"pointerdown\", onPointerDown);\n element.addEventListener(\"pointermove\", onPointerMove);\n element.addEventListener(\"pointerup\", releasePointer);\n element.addEventListener(\"pointercancel\", releasePointer);\n element.addEventListener(\"wheel\", onWheel, { passive: false });\n element.addEventListener(\"keydown\", onKeyDown);\n\n return () => {\n element.removeEventListener(\"pointerdown\", onPointerDown);\n element.removeEventListener(\"pointermove\", onPointerMove);\n element.removeEventListener(\"pointerup\", releasePointer);\n element.removeEventListener(\"pointercancel\", releasePointer);\n element.removeEventListener(\"wheel\", onWheel);\n element.removeEventListener(\"keydown\", onKeyDown);\n pointersRef.current.clear();\n };\n }, [enabled, gl, maxFov, minFov]);\n\n useFrame((_, deltaSeconds) => {\n if (!(camera instanceof PerspectiveCamera)) {\n return;\n }\n\n const inertiaEnabled = optionsRef.current.inertia !== false;\n if (!interactingRef.current && inertiaEnabled) {\n const rotationDamping = Math.exp(\n -INERTIA_ROTATION_DAMPING * deltaSeconds,\n );\n const zoomDamping = Math.exp(-INERTIA_ZOOM_DAMPING * deltaSeconds);\n\n if (Math.abs(yawVelocityRef.current) >= MIN_ROTATION_VELOCITY) {\n targetViewRef.current.yaw += yawVelocityRef.current * deltaSeconds;\n yawVelocityRef.current *= rotationDamping;\n dirtyRef.current = true;\n } else {\n yawVelocityRef.current = 0;\n }\n\n if (Math.abs(pitchVelocityRef.current) >= MIN_ROTATION_VELOCITY) {\n targetViewRef.current.pitch += pitchVelocityRef.current * deltaSeconds;\n pitchVelocityRef.current *= rotationDamping;\n dirtyRef.current = true;\n } else {\n pitchVelocityRef.current = 0;\n }\n\n if (Math.abs(zoomVelocityRef.current) >= MIN_ZOOM_VELOCITY) {\n targetViewRef.current.fov += zoomVelocityRef.current * deltaSeconds;\n zoomVelocityRef.current *= zoomDamping;\n dirtyRef.current = true;\n } else {\n zoomVelocityRef.current = 0;\n }\n } else if (!inertiaEnabled) {\n stopVelocity();\n }\n\n targetViewRef.current = constrainView(targetViewRef.current);\n\n if (!dirtyRef.current) {\n return;\n }\n\n const targetView = targetViewRef.current;\n const rotateDamping = resolveDamping(\n optionsRef.current.rotateDamping,\n DEFAULT_ROTATE_DAMPING,\n );\n const zoomDamping = resolveDamping(\n optionsRef.current.zoomDamping,\n DEFAULT_ZOOM_DAMPING,\n );\n const rotationFactor = dampingFactor(rotateDamping, deltaSeconds);\n const zoomFactor = dampingFactor(zoomDamping, deltaSeconds);\n const yawDelta = shortestYawDelta(viewRef.current.yaw, targetView.yaw);\n const smoothedView = {\n yaw: normalizeYaw(viewRef.current.yaw + yawDelta * rotationFactor),\n pitch:\n viewRef.current.pitch +\n (targetView.pitch - viewRef.current.pitch) * rotationFactor,\n fov:\n viewRef.current.fov +\n (targetView.fov - viewRef.current.fov) * zoomFactor,\n };\n const hasSettled =\n Math.abs(shortestYawDelta(smoothedView.yaw, targetView.yaw)) <\n VIEW_SETTLE_EPSILON &&\n Math.abs(smoothedView.pitch - targetView.pitch) < VIEW_SETTLE_EPSILON &&\n Math.abs(smoothedView.fov - targetView.fov) < VIEW_SETTLE_EPSILON;\n viewRef.current = hasSettled ? { ...targetView } : smoothedView;\n eulerRef.current.set(\n MathUtils.degToRad(viewRef.current.pitch),\n MathUtils.degToRad(-viewRef.current.yaw),\n 0,\n \"YXZ\",\n );\n camera.quaternion.setFromEuler(eulerRef.current);\n camera.fov = viewRef.current.fov;\n camera.updateProjectionMatrix();\n camera.updateMatrixWorld();\n\n const nextView = { ...viewRef.current };\n const lastEmitted = lastEmittedViewRef.current;\n if (!lastEmitted || !viewsEqual(lastEmitted, nextView)) {\n lastEmittedViewRef.current = nextView;\n onViewChangeRef.current?.(nextView);\n }\n dirtyRef.current = !hasSettled;\n });\n\n return null;\n});\n","import { useFrame } from \"@react-three/fiber\";\nimport {\n createContext,\n useContext,\n useEffect,\n useRef,\n} from \"react\";\nimport type { RefObject } from \"react\";\nimport type { PanoramaControlsHandle } from \"./panorama-controls\";\n\nconst DEFAULT_AUTO_ROTATE_SPEED = 18;\nconst DEFAULT_AUTO_ROTATE_ACCELERATION = 18;\nconst DEFAULT_AUTO_ROTATE_START_DELAY = 2;\n\n/** Options for automatic horizontal panorama rotation. */\nexport type AutoRotateProps = {\n /** Whether automatic rotation is active. Defaults to true. */\n enabled?: boolean;\n /** Rotation speed in degrees per second. Negative values rotate left. */\n speed?: number;\n /**\n * Rate at which rotation reaches its target speed, in degrees per second\n * squared. Use 0 to disable the speed ramp. Defaults to 18.\n */\n acceleration?: number;\n /** Milliseconds to wait after enabling before rotation begins. */\n startDelay?: number;\n};\n\nexport const PanoramaControlsContext = createContext<\n RefObject<PanoramaControlsHandle | null> | null\n>(null);\n\nfunction resolveStartDelay(value: number | undefined): number {\n return Number.isFinite(value) ? Math.max(value!, 0) : 0;\n}\n\nfunction resolveAcceleration(value: number | undefined): number {\n return Number.isFinite(value) && value! >= 0\n ? value!\n : DEFAULT_AUTO_ROTATE_ACCELERATION;\n}\n\n/**\n * Adds automatic rotation to the nearest PanoView. Render one instance as a\n * child of PanoView, alongside its panorama source.\n */\nexport function AutoRotate({\n enabled = true,\n speed = DEFAULT_AUTO_ROTATE_SPEED,\n acceleration = DEFAULT_AUTO_ROTATE_ACCELERATION,\n startDelay = DEFAULT_AUTO_ROTATE_START_DELAY,\n}: AutoRotateProps) {\n const controlsRef = useContext(PanoramaControlsContext);\n const elapsedRef = useRef(0);\n const rotationSpeedRef = useRef(0);\n\n if (!controlsRef) {\n throw new Error(\"<AutoRotate> must be rendered inside <PanoView>.\");\n }\n\n useEffect(() => {\n elapsedRef.current = 0;\n rotationSpeedRef.current = 0;\n }, [enabled, startDelay]);\n\n useFrame((_, deltaSeconds) => {\n if (!enabled || !Number.isFinite(speed) || speed === 0) {\n rotationSpeedRef.current = 0;\n return;\n }\n\n const delaySeconds = resolveStartDelay(startDelay) / 1000;\n elapsedRef.current += deltaSeconds;\n if (elapsedRef.current < delaySeconds) {\n return;\n }\n\n const targetSpeed = Math.abs(speed);\n const currentSpeed = rotationSpeedRef.current;\n const accelerationPerSecond = resolveAcceleration(acceleration);\n const nextSpeed =\n accelerationPerSecond === 0\n ? targetSpeed\n : Math.min(\n targetSpeed,\n currentSpeed + accelerationPerSecond * deltaSeconds,\n );\n const averageSpeed = (currentSpeed + nextSpeed) / 2;\n const yawDelta = Math.sign(speed) * averageSpeed * deltaSeconds;\n\n if (!controlsRef.current?.applyAutoRotation(yawDelta)) {\n rotationSpeedRef.current = 0;\n return;\n }\n\n rotationSpeedRef.current = nextSpeed;\n });\n\n return null;\n}\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { CSSProperties, ReactNode } from \"react\";\n\ntype HotspotActivationEvent = KeyboardEvent | MouseEvent;\n\ntype HotspotAccessibilityEntry = {\n id: string;\n label: string;\n token: symbol;\n activate: (event: HotspotActivationEvent) => void;\n onFocusChange: (focused: boolean) => void;\n};\n\ntype HotspotAccessibilityRegistry = {\n register: (\n entry: Omit<HotspotAccessibilityEntry, \"token\">,\n ) => () => void;\n};\n\nexport const HotspotAccessibilityContext =\n createContext<HotspotAccessibilityRegistry | null>(null);\n\nconst VISUALLY_HIDDEN_STYLE: CSSProperties = {\n border: 0,\n clip: \"rect(0 0 0 0)\",\n clipPath: \"inset(50%)\",\n height: 1,\n margin: -1,\n overflow: \"hidden\",\n padding: 0,\n position: \"absolute\",\n whiteSpace: \"nowrap\",\n width: 1,\n};\n\nfunction warnAboutMissingLabel(id: string) {\n const nodeEnv = (\n globalThis as typeof globalThis & {\n process?: { env?: { NODE_ENV?: string } };\n }\n ).process?.env?.NODE_ENV;\n if (nodeEnv !== \"production\") {\n console.warn(\n `Hotspot \"${id}\" is clickable but has no ariaLabel, so it is unavailable to keyboard and screen-reader users.`,\n );\n }\n}\n\nexport function useHotspotAccessibility({\n id,\n ariaLabel,\n onActivate,\n}: {\n id: string;\n ariaLabel?: string;\n onActivate?: (event: HotspotActivationEvent) => void;\n}): boolean {\n const registry = useContext(HotspotAccessibilityContext);\n const [focused, setFocused] = useState(false);\n const activateRef = useRef(onActivate);\n const enabled = Boolean(onActivate);\n activateRef.current = onActivate;\n\n useEffect(() => {\n if (!enabled) {\n setFocused(false);\n return;\n }\n if (!ariaLabel) {\n warnAboutMissingLabel(id);\n return;\n }\n if (!registry) {\n return;\n }\n\n return registry.register({\n id,\n label: ariaLabel,\n activate: (event) => activateRef.current?.(event),\n onFocusChange: setFocused,\n });\n }, [ariaLabel, enabled, id, registry]);\n\n return focused;\n}\n\nexport function useHotspotAccessibilityLayer(): {\n controls: ReactNode;\n registry: HotspotAccessibilityRegistry;\n} {\n const [entries, setEntries] = useState<\n Map<string, HotspotAccessibilityEntry>\n >(() => new Map());\n\n const register = useCallback(\n (entry: Omit<HotspotAccessibilityEntry, \"token\">) => {\n const token = Symbol(entry.id);\n const nextEntry: HotspotAccessibilityEntry = { ...entry, token };\n setEntries((current) => {\n const next = new Map(current);\n next.set(entry.id, nextEntry);\n return next;\n });\n\n return () => {\n setEntries((current) => {\n if (current.get(entry.id)?.token !== token) {\n return current;\n }\n const next = new Map(current);\n next.delete(entry.id);\n return next;\n });\n };\n },\n [],\n );\n\n const registry = useMemo<HotspotAccessibilityRegistry>(\n () => ({ register }),\n [register],\n );\n const controls = useMemo(\n () => (\n <div aria-label=\"Panorama hotspots\" style={{ pointerEvents: \"none\" }}>\n {Array.from(entries.values()).map((entry) => (\n <button\n aria-label={entry.label}\n key={entry.id}\n onBlur={() => entry.onFocusChange(false)}\n onClick={(event) => entry.activate(event.nativeEvent)}\n onFocus={() => entry.onFocusChange(true)}\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n entry.activate(event.nativeEvent);\n }\n }}\n style={VISUALLY_HIDDEN_STYLE}\n type=\"button\"\n >\n {entry.label}\n </button>\n ))}\n </div>\n ),\n [entries],\n );\n\n return { controls, registry };\n}\n","import type { ThreeEvent } from \"@react-three/fiber\";\nimport { BackSide } from \"three\";\nimport { vector3ToPanoPosition } from \"./hotspot/coordinates\";\nimport type { PanoramaPointerEvent } from \"./hotspot/types\";\nimport { DEFAULT_PANORAMA_RADIUS } from \"./panorama-radius\";\n\nconst EVENT_SURFACE_RADIUS = DEFAULT_PANORAMA_RADIUS - 1;\n\ntype PanoramaEventSurfaceProps = {\n onClick?: (event: PanoramaPointerEvent) => void;\n onDoubleClick?: (event: PanoramaPointerEvent) => void;\n onPointerMove?: (event: PanoramaPointerEvent) => void;\n};\n\nfunction makePanoramaPointerEvent(\n event: ThreeEvent<MouseEvent | PointerEvent>,\n): PanoramaPointerEvent {\n const nativeEvent = event.nativeEvent;\n return {\n position: vector3ToPanoPosition(event.ray.direction),\n nativeEvent,\n pointerId:\n \"pointerId\" in nativeEvent ? nativeEvent.pointerId : undefined,\n button: nativeEvent.button,\n buttons: nativeEvent.buttons,\n clientX: nativeEvent.clientX,\n clientY: nativeEvent.clientY,\n };\n}\n\nfunction emitPanoramaEvent(\n event: ThreeEvent<MouseEvent | PointerEvent>,\n callback: ((event: PanoramaPointerEvent) => void) | undefined,\n) {\n if (!callback) {\n return;\n }\n event.stopPropagation();\n callback(makePanoramaPointerEvent(event));\n}\n\nexport function PanoramaEventSurface({\n onClick,\n onDoubleClick,\n onPointerMove,\n}: PanoramaEventSurfaceProps) {\n if (!onClick && !onDoubleClick && !onPointerMove) {\n return null;\n }\n\n return (\n <mesh\n renderOrder={-200}\n onClick={(event) => emitPanoramaEvent(event, onClick)}\n onDoubleClick={(event) => emitPanoramaEvent(event, onDoubleClick)}\n onPointerMove={(event) => emitPanoramaEvent(event, onPointerMove)}\n >\n <sphereGeometry args={[EVENT_SURFACE_RADIUS, 64, 32]} />\n <meshBasicMaterial\n colorWrite={false}\n depthTest={false}\n depthWrite={false}\n opacity={0}\n side={BackSide}\n transparent\n />\n </mesh>\n );\n}\n","import { MathUtils, Vector3 } from \"three\";\nimport { MAX_HOTSPOT_PITCH } from \"./types\";\nimport type { HotspotPosition } from \"./types\";\n\nexport function normalizePanoYaw(yaw: number): number {\n if (!Number.isFinite(yaw)) {\n return 0;\n }\n return MathUtils.euclideanModulo(yaw + 180, 360) - 180;\n}\n\nexport function clampPanoPitch(pitch: number): number {\n if (!Number.isFinite(pitch)) {\n return 0;\n }\n return MathUtils.clamp(pitch, -MAX_HOTSPOT_PITCH, MAX_HOTSPOT_PITCH);\n}\n\nexport function normalizePanoPosition(\n position: HotspotPosition,\n): HotspotPosition {\n return {\n yaw: normalizePanoYaw(position.yaw),\n pitch: clampPanoPitch(position.pitch),\n };\n}\n\nexport function panoPositionToVector3(\n position: HotspotPosition,\n radius = 1,\n): Vector3 {\n const normalized = normalizePanoPosition(position);\n const safeRadius = Number.isFinite(radius) ? Math.max(0, radius) : 1;\n const yaw = MathUtils.degToRad(normalized.yaw);\n const pitch = MathUtils.degToRad(normalized.pitch);\n const cosPitch = Math.cos(pitch);\n\n return new Vector3(\n cosPitch * Math.sin(yaw) * safeRadius,\n Math.sin(pitch) * safeRadius,\n -cosPitch * Math.cos(yaw) * safeRadius,\n );\n}\n\nexport function vector3ToPanoPosition(\n vector: Pick<Vector3, \"x\" | \"y\" | \"z\">,\n): HotspotPosition {\n const length = Math.hypot(vector.x, vector.y, vector.z);\n if (!Number.isFinite(length) || length === 0) {\n return { yaw: 0, pitch: 0 };\n }\n\n return normalizePanoPosition({\n yaw: MathUtils.radToDeg(Math.atan2(vector.x, -vector.z)),\n pitch: MathUtils.radToDeg(\n Math.asin(MathUtils.clamp(vector.y / length, -1, 1)),\n ),\n });\n}\n","export const MAX_HOTSPOT_PITCH = 89.9;\n\nexport type HotspotPosition = {\n /** Horizontal panorama angle in degrees. Positive values look right. */\n yaw: number;\n /** Vertical panorama angle in degrees. Positive values look up. */\n pitch: number;\n};\n\n/**\n * A safe point-hotspot rendering mode.\n *\n * `surface` attaches the visual to the panorama shell. `billboard` floats it\n * in front of the shell and keeps it facing the camera.\n */\nexport type HotspotMode = \"surface\" | \"billboard\";\n\n/** Whether a hotspot grows with panorama zoom or preserves its screen size. */\nexport type HotspotScaleMode = \"fov\" | \"fixed\";\n\nexport type HotspotInputSource = \"pointer\" | \"keyboard\";\n\nexport type HotspotInteractionEvent = {\n id: string;\n position: HotspotPosition;\n source: HotspotInputSource;\n nativeEvent: MouseEvent | PointerEvent | KeyboardEvent;\n};\n\nexport type HotspotDragEvent = HotspotInteractionEvent & {\n source: \"pointer\";\n startPosition: HotspotPosition;\n};\n\nexport type HotspotCommonProps = {\n id: string;\n position: HotspotPosition;\n /** Angular width in degrees. Defaults to 12. */\n width?: number;\n /** Angular height in degrees. Defaults to 8. */\n height?: number;\n /** Defaults to \"billboard\". */\n mode?: HotspotMode;\n /**\n * World-space distance for `mode=\"billboard\"`. Defaults to 10 and is capped\n * when needed so the full hotspot remains inside the panorama shell.\n */\n distance?: number;\n /** FOV grows/shrinks with zoom; fixed preserves the reference screen size. */\n scaleMode?: HotspotScaleMode;\n /** Reference FOV in degrees used when scaleMode is \"fixed\". Defaults to 75. */\n referenceFov?: number;\n /** Clockwise rotation around the hotspot normal in degrees. */\n rotation?: number;\n opacity?: number;\n renderOrder?: number;\n visible?: boolean;\n /** Whether the hotspot accepts pointer and keyboard interaction. Defaults to true. */\n interactive?: boolean;\n draggable?: boolean;\n /** Required for keyboard-accessible clickable hotspots. */\n ariaLabel?: string;\n onClick?: (event: HotspotInteractionEvent) => void;\n onHoverChange?: (hovered: boolean, event: HotspotInteractionEvent) => void;\n onDragStart?: (event: HotspotDragEvent) => void;\n onPositionChange?: (event: HotspotDragEvent) => void;\n onDragEnd?: (event: HotspotDragEvent) => void;\n};\n\nexport type PanoramaPointerEvent = {\n position: HotspotPosition;\n nativeEvent: MouseEvent | PointerEvent;\n pointerId?: number;\n button: number;\n buttons: number;\n clientX: number;\n clientY: number;\n};\n","/**\n * Shared world-space radius for the built-in sphere and cube-tile panoramas.\n * Hotspots and the invisible event surface use the same scale.\n */\nexport const DEFAULT_PANORAMA_RADIUS = 1_000;\n/** Keeps depth-buffer precision stable for hotspots near the panorama shell. */\nexport const DEFAULT_PANORAMA_CAMERA_NEAR = 0.1;\nexport const DEFAULT_PANORAMA_CAMERA_FAR = DEFAULT_PANORAMA_RADIUS * 2;\n","import { useThree } from \"@react-three/fiber\";\nimport { useEffect, useRef, useState } from \"react\";\nimport {\n BackSide,\n LinearFilter,\n LinearMipmapLinearFilter,\n MathUtils,\n RepeatWrapping,\n SRGBColorSpace,\n Texture,\n TextureLoader,\n} from \"three\";\nimport { DEFAULT_PANORAMA_RADIUS } from \"./panorama-radius\";\n\nexport type SphereProps = {\n src: string;\n /** Horizontal image offset in degrees. */\n yawOffset?: number;\n onLoad?: (texture: Texture) => void;\n onError?: (error: unknown) => void;\n /** Keeps the source mounted for preloading without drawing it. */\n visible?: boolean;\n};\n\nexport function Sphere({\n src,\n yawOffset = 0,\n onLoad,\n onError,\n visible = true,\n}: SphereProps) {\n const gl = useThree((state) => state.gl);\n const [texture, setTexture] = useState<Texture | null>(null);\n const onLoadRef = useRef(onLoad);\n const onErrorRef = useRef(onError);\n onLoadRef.current = onLoad;\n onErrorRef.current = onError;\n\n useEffect(() => {\n let active = true;\n const loader = new TextureLoader();\n setTexture(null);\n\n loader.load(\n src,\n (loadedTexture) => {\n if (!active) {\n loadedTexture.dispose();\n return;\n }\n\n loadedTexture.colorSpace = SRGBColorSpace;\n loadedTexture.wrapS = RepeatWrapping;\n loadedTexture.repeat.x = -1;\n loadedTexture.offset.x = 1;\n loadedTexture.anisotropy = gl.capabilities.getMaxAnisotropy();\n loadedTexture.magFilter = LinearFilter;\n loadedTexture.minFilter = LinearMipmapLinearFilter;\n loadedTexture.generateMipmaps = true;\n loadedTexture.needsUpdate = true;\n setTexture(loadedTexture);\n onLoadRef.current?.(loadedTexture);\n },\n undefined,\n (error) => {\n if (active) {\n onErrorRef.current?.(error);\n }\n },\n );\n\n return () => {\n active = false;\n };\n }, [gl, src]);\n\n useEffect(\n () => () => {\n texture?.dispose();\n },\n [texture],\n );\n\n if (!texture) {\n return null;\n }\n\n return (\n <mesh\n rotation={[0, MathUtils.degToRad(90 + yawOffset), 0]}\n visible={visible}\n >\n <sphereGeometry args={[DEFAULT_PANORAMA_RADIUS, 128, 64]} />\n <meshBasicMaterial\n map={texture}\n side={BackSide}\n toneMapped={false}\n />\n </mesh>\n );\n}\n","import { useFrame, useThree } from \"@react-three/fiber\";\nimport {\n Fragment,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { ReactNode } from \"react\";\nimport {\n DoubleSide,\n LinearSRGBColorSpace,\n LinearFilter,\n Mesh,\n PlaneGeometry,\n PerspectiveCamera,\n ShaderMaterial,\n Texture,\n Vector2,\n Vector3,\n WebGLRenderTarget,\n} from \"three\";\nimport { PanoramaControlsContext } from \"./auto-rotate\";\nimport { Sphere } from \"./sphere\";\nimport {\n TileTextureManagerProvider,\n useSharedTileTextureManager,\n} from \"./tile/texture-manager-context\";\nimport { Tile } from \"./tile/tile\";\nimport type { TileProps } from \"./tile/types\";\n\nexport type PanoramaTransitionPreset =\n | \"none\"\n | \"crossfade\"\n | \"zoom\"\n | \"blackout\"\n | \"whiteFlash\"\n | \"slideRightToLeft\"\n | \"slideTopToBottom\"\n | \"slideDiagonal\"\n | \"circleOpen\"\n | \"verticalOpen\"\n | \"horizontalOpen\"\n | \"ellipticZoomOpen\";\n\nexport type PanoramaTransition =\n | PanoramaTransitionPreset\n | {\n preset: PanoramaTransitionPreset;\n /** Overrides the KRpano-compatible default duration in seconds. */\n duration?: number;\n };\n\nexport type SpherePanoramaScene = {\n id: string;\n type: \"sphere\";\n src: string;\n yawOffset?: number;\n};\n\nexport type TilePanoramaScene = Omit<\n TileProps,\n | \"loadMode\"\n | \"visible\"\n | \"onReady\"\n | \"onPreviewError\"\n | \"onLoadProgress\"\n | \"onTileError\"\n | \"onLevelChange\"\n> & {\n id: string;\n type: \"tile\";\n};\n\nexport type PanoramaScene = SpherePanoramaScene | TilePanoramaScene;\n\nexport type PanoramaTransitionEndEvent = {\n previousSceneId: string;\n sceneId: string;\n preset: PanoramaTransitionPreset;\n};\n\nexport type PanoramaTransitionErrorEvent = {\n sceneId: string;\n error: unknown;\n};\n\nexport type PanoramaScenesProps = {\n scenes: readonly PanoramaScene[];\n activeSceneId: string;\n transition?: PanoramaTransition;\n /** Rendered only after a scene has finished transitioning in. */\n renderHotspots?: (scene: PanoramaScene) => ReactNode;\n onTransitionEnd?: (event: PanoramaTransitionEndEvent) => void;\n onTransitionError?: (event: PanoramaTransitionErrorEvent) => void;\n /** Viewer-wide budget shared by every tile scene. Defaults to 128 MiB. */\n maxTextureMemoryMb?: number;\n /** Viewer-wide tile request limit. Defaults to 4. */\n maxConcurrentTileLoads?: number;\n /** Maximum physical-pixel area of the outgoing GPU snapshot. */\n snapshotMaxPixels?: number;\n};\n\ntype TransitionDefinition = {\n preset: PanoramaTransitionPreset;\n duration: number;\n};\n\ntype Snapshot = {\n texture: Texture;\n dispose: () => void;\n};\n\ntype Phase = \"idle\" | \"preloading\" | \"capturing\" | \"recapturing\" | \"transitioning\";\n\nconst TRANSITION_DEFAULTS: Record<PanoramaTransitionPreset, {\n duration: number;\n krpanoBlend: string;\n}> = {\n none: { duration: 0, krpanoBlend: \"NOBLEND\" },\n crossfade: { duration: 1, krpanoBlend: \"BLEND(1.0, easeInCubic)\" },\n zoom: { duration: 2, krpanoBlend: \"ZOOMBLEND(2.0, 2.0, easeInOutSine)\" },\n blackout: { duration: 2, krpanoBlend: \"COLORBLEND(2.0, 0x000000, easeOutSine)\" },\n whiteFlash: { duration: 1, krpanoBlend: \"LIGHTBLEND(1.0, 0xFFFFFF, 2.0, linear)\" },\n slideRightToLeft: { duration: 1, krpanoBlend: \"SLIDEBLEND(1.0, 0.0, 0.2, linear)\" },\n slideTopToBottom: { duration: 1, krpanoBlend: \"SLIDEBLEND(1.0, 90.0, 0.01, linear)\" },\n slideDiagonal: { duration: 1, krpanoBlend: \"SLIDEBLEND(1.0, 135.0, 0.4, linear)\" },\n circleOpen: { duration: 1, krpanoBlend: \"OPENBLEND(1.0, 0.0, 0.2, 0.0, linear)\" },\n verticalOpen: { duration: 0.7, krpanoBlend: \"OPENBLEND(0.7, 1.0, 0.1, 0.0, linear)\" },\n horizontalOpen: { duration: 1, krpanoBlend: \"OPENBLEND(1.0, -1.0, 0.3, 0.0, linear)\" },\n ellipticZoomOpen: { duration: 1, krpanoBlend: \"OPENBLEND(1.0, -0.5, 0.3, 0.8, linear)\" },\n};\n\nconst EFFECT_INDEX: Record<PanoramaTransitionPreset, number> = {\n none: 0,\n crossfade: 1,\n zoom: 2,\n blackout: 3,\n whiteFlash: 4,\n slideRightToLeft: 5,\n slideTopToBottom: 6,\n slideDiagonal: 7,\n circleOpen: 8,\n verticalOpen: 9,\n horizontalOpen: 10,\n ellipticZoomOpen: 11,\n};\n\nfunction resolveTransition(transition: PanoramaTransition | undefined): TransitionDefinition {\n const preset = typeof transition === \"string\" ? transition : transition?.preset ?? \"crossfade\";\n return {\n preset,\n duration: Math.max(\n 0,\n transition && typeof transition === \"object\" && Number.isFinite(transition.duration)\n ? transition.duration!\n : TRANSITION_DEFAULTS[preset].duration,\n ),\n };\n}\n\nfunction SceneSource({\n scene,\n visible,\n baseOnly,\n onReady,\n onError,\n}: {\n scene: PanoramaScene | null;\n visible: boolean;\n baseOnly: boolean;\n onReady: () => void;\n onError: (error: unknown) => void;\n}) {\n if (!scene) {\n return null;\n }\n\n if (scene.type === \"sphere\") {\n return (\n <Sphere\n src={scene.src}\n yawOffset={scene.yawOffset}\n visible={visible}\n onLoad={onReady}\n onError={onError}\n />\n );\n }\n\n const { id: _id, type: _type, ...tileProps } = scene;\n return (\n <Tile\n {...tileProps}\n visible={visible}\n loadMode={baseOnly ? \"base\" : \"full\"}\n onReady={onReady}\n onPreviewError={onError}\n />\n );\n}\n\nfunction SnapshotCapture({\n requestId,\n maxPixels,\n onCaptured,\n}: {\n requestId: number;\n maxPixels: number;\n onCaptured: (snapshot: Snapshot) => void;\n}) {\n const { camera, gl, scene, size } = useThree();\n const capturedRequestRef = useRef(0);\n const renderTargetRef = useRef<WebGLRenderTarget | null>(null);\n\n useEffect(\n () => () => {\n renderTargetRef.current?.dispose();\n renderTargetRef.current = null;\n },\n [],\n );\n\n useFrame(() => {\n if (requestId === 0 || requestId === capturedRequestRef.current) {\n return;\n }\n\n const pixelRatio = gl.getPixelRatio();\n const sourceWidth = Math.max(1, Math.floor(size.width * pixelRatio));\n const sourceHeight = Math.max(1, Math.floor(size.height * pixelRatio));\n const scale = Math.min(1, Math.sqrt(maxPixels / (sourceWidth * sourceHeight)));\n const width = Math.max(1, Math.floor(sourceWidth * scale));\n const height = Math.max(1, Math.floor(sourceHeight * scale));\n const nextTarget = new WebGLRenderTarget(width, height, {\n depthBuffer: false,\n stencilBuffer: false,\n });\n // WebGLRenderer renders non-XR targets in its linear working color space.\n // Keep this metadata accurate so the snapshot is not treated as display-encoded.\n nextTarget.texture.colorSpace = LinearSRGBColorSpace;\n nextTarget.texture.generateMipmaps = false;\n nextTarget.texture.minFilter = LinearFilter;\n nextTarget.texture.magFilter = LinearFilter;\n\n // This one-off render keeps the transfer entirely on the GPU and permits\n // downscaling the snapshot before its texture is retained for blending.\n const previousTarget = gl.getRenderTarget();\n gl.setRenderTarget(nextTarget);\n gl.clear();\n gl.render(scene, camera);\n gl.setRenderTarget(previousTarget);\n\n capturedRequestRef.current = requestId;\n const previous = renderTargetRef.current;\n renderTargetRef.current = nextTarget;\n previous?.dispose();\n onCaptured({\n texture: nextTarget.texture,\n dispose: () => {\n if (renderTargetRef.current === nextTarget) {\n renderTargetRef.current = null;\n }\n nextTarget.dispose();\n },\n });\n });\n\n return null;\n}\n\nfunction SnapshotOverlay({\n snapshot,\n transition,\n running,\n runId,\n onFinish,\n}: {\n snapshot: Snapshot;\n transition: TransitionDefinition;\n running: boolean;\n runId: number;\n onFinish: () => void;\n}) {\n const { camera, size } = useThree();\n const meshRef = useRef<Mesh>(null);\n const startRef = useRef<number | null>(null);\n const finishedRef = useRef(false);\n const directionRef = useRef(new Vector3());\n const material = useMemo(\n () =>\n new ShaderMaterial({\n transparent: true,\n depthTest: false,\n depthWrite: false,\n side: DoubleSide,\n uniforms: {\n map: { value: snapshot.texture },\n progress: { value: 0 },\n effect: { value: EFFECT_INDEX[transition.preset] },\n },\n vertexShader: `\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n `,\n fragmentShader: `\n uniform sampler2D map;\n uniform float progress;\n uniform float effect;\n varying vec2 vUv;\n\n float easeInCubic(float t) { return t * t * t; }\n float easeOutSine(float t) { return sin(t * 1.57079632679); }\n float easeInOutSine(float t) { return -(cos(3.14159265359 * t) - 1.0) * 0.5; }\n\n void main() {\n float t = clamp(progress, 0.0, 1.0);\n vec2 uv = vUv;\n vec4 old = texture2D(map, uv);\n float alpha = 1.0;\n\n if (effect == 1.0) {\n alpha = 1.0 - easeInCubic(t);\n } else if (effect == 2.0) {\n float eased = easeInOutSine(t);\n // ZOOMBLEND(2.0, 2.0, easeInOutSine): reach 2x zoom.\n uv = 0.5 + (vUv - 0.5) / mix(1.0, 2.0, eased);\n old = texture2D(map, uv);\n alpha = 1.0 - eased;\n } else if (effect == 3.0) {\n // COLORBLEND(2.0, 0x000000, easeOutSine).\n float blackout = easeOutSine(min(1.0, t * 2.0));\n float reveal = easeOutSine(max(0.0, (t - 0.5) * 2.0));\n old.rgb = mix(old.rgb, vec3(0.0), blackout);\n alpha = 1.0 - reveal;\n } else if (effect == 4.0) {\n // LIGHTBLEND(1.0, 0xFFFFFF, 2.0, linear).\n float flash = min(1.0, 2.0 * sin(t * 3.14159265359));\n old.rgb = mix(old.rgb, vec3(1.0), flash);\n alpha = 1.0 - t;\n } else if (effect >= 5.0 && effect <= 7.0) {\n vec2 direction = effect == 5.0 ? vec2(1.0, 0.0) : (effect == 6.0 ? vec2(0.0, 1.0) : normalize(vec2(-1.0, 1.0)));\n float coordinate = dot(vUv - 0.5, direction) + 0.5;\n float softness = effect == 5.0 ? 0.2 : (effect == 6.0 ? 0.01 : 0.4);\n alpha = smoothstep(t - softness, t + softness, coordinate);\n } else if (effect >= 8.0) {\n vec2 point = vUv - 0.5;\n vec2 scale = effect == 9.0 ? vec2(4.0, 1.0) : (effect == 10.0 ? vec2(1.0, 4.0) : vec2(1.35, 0.8));\n float distanceFromCenter = length(point * scale);\n float edge = effect == 8.0 ? 0.2 : (effect == 9.0 ? 0.1 : 0.3);\n float radius = t * (effect == 9.0 ? 1.1 : 1.45);\n alpha = smoothstep(radius, radius + edge, distanceFromCenter);\n if (effect == 11.0) {\n // OPENBLEND(1.0, -0.5, 0.3, 0.8, linear).\n old = texture2D(map, 0.5 + point / (1.0 + 0.8 * t));\n }\n }\n gl_FragColor = vec4(old.rgb, old.a * alpha);\n // The snapshot is linear. Encode it for the drawing buffer so it\n // matches the newly rendered panorama beneath this overlay.\n #include <colorspace_fragment>\n }\n `,\n }),\n [snapshot.texture, transition.preset],\n );\n\n useEffect(() => () => material.dispose(), [material]);\n useEffect(() => {\n startRef.current = null;\n finishedRef.current = false;\n material.uniforms.progress.value = 0;\n }, [material, runId]);\n\n useFrame((state) => {\n const mesh = meshRef.current;\n if (!mesh || !(camera as { isPerspectiveCamera?: boolean }).isPerspectiveCamera) {\n return;\n }\n const perspectiveCamera = camera as PerspectiveCamera;\n const distance = Math.max(perspectiveCamera.near * 1.1, 0.11);\n camera.getWorldDirection(directionRef.current);\n mesh.position.copy(camera.position).addScaledVector(directionRef.current, distance);\n mesh.quaternion.copy(camera.quaternion);\n const height = 2 * distance * Math.tan((perspectiveCamera.fov * Math.PI) / 360);\n mesh.scale.set(height * perspectiveCamera.aspect, height, 1);\n\n if (!running || finishedRef.current) {\n return;\n }\n if (startRef.current === null) {\n startRef.current = state.clock.elapsedTime;\n }\n const progress = transition.duration === 0\n ? 1\n : Math.min(1, (state.clock.elapsedTime - startRef.current) / transition.duration);\n material.uniforms.progress.value = progress;\n if (progress === 1) {\n finishedRef.current = true;\n onFinish();\n }\n });\n\n return (\n <mesh ref={meshRef} renderOrder={10_000} frustumCulled={false}>\n <primitive attach=\"geometry\" object={FULLSCREEN_PLANE} />\n <primitive attach=\"material\" object={material} />\n </mesh>\n );\n}\n\nconst FULLSCREEN_PLANE = new PlaneGeometry(1, 1);\n\nfunction PanoramaScenesController({\n scenes,\n activeSceneId,\n transition: transitionInput,\n renderHotspots,\n onTransitionEnd,\n onTransitionError,\n snapshotMaxPixels = 3_686_400,\n}: Omit<PanoramaScenesProps, \"maxTextureMemoryMb\" | \"maxConcurrentTileLoads\">) {\n const controlsRef = useContext(PanoramaControlsContext);\n const manager = useSharedTileTextureManager();\n const transition = useMemo(\n () => resolveTransition(transitionInput),\n [transitionInput],\n );\n const sceneMap = useMemo(\n () => new Map(scenes.map((scene) => [scene.id, scene])),\n [scenes],\n );\n const initialScene = sceneMap.get(activeSceneId) ?? null;\n const [slots, setSlots] = useState<[PanoramaScene | null, PanoramaScene | null]>([\n initialScene,\n null,\n ]);\n const [activeSlot, setActiveSlot] = useState(0);\n const [liveSlot, setLiveSlot] = useState(0);\n const [pendingSlot, setPendingSlot] = useState<number | null>(null);\n const [phase, setPhase] = useState<Phase>(initialScene ? \"idle\" : \"preloading\");\n const [captureRequestId, setCaptureRequestId] = useState(0);\n const [transitionRunId, setTransitionRunId] = useState(0);\n const [snapshot, setSnapshot] = useState<Snapshot | null>(null);\n const [recoveryKey, setRecoveryKey] = useState(0);\n const requestedSceneIdRef = useRef(activeSceneId);\n const captureReasonRef = useRef<\"start\" | \"interrupt\">(\"start\");\n const interactionReleaseRef = useRef<(() => void) | null>(null);\n const slotsRef = useRef(slots);\n const phaseRef = useRef(phase);\n const liveSlotRef = useRef(liveSlot);\n const transitionFromRef = useRef<PanoramaScene | null>(initialScene);\n slotsRef.current = slots;\n phaseRef.current = phase;\n liveSlotRef.current = liveSlot;\n\n const releaseInteraction = useCallback(() => {\n interactionReleaseRef.current?.();\n interactionReleaseRef.current = null;\n }, []);\n\n const reportError = useCallback((sceneId: string, error: unknown) => {\n onTransitionError?.({ sceneId, error });\n }, [onTransitionError]);\n\n const startPreload = useCallback((scene: PanoramaScene) => {\n const nextSlot = 1 - liveSlotRef.current;\n requestedSceneIdRef.current = scene.id;\n setSlots((current) => {\n const next: [PanoramaScene | null, PanoramaScene | null] = [...current] as [PanoramaScene | null, PanoramaScene | null];\n next[nextSlot] = scene;\n return next;\n });\n setPendingSlot(nextSlot);\n setPhase(\"preloading\");\n }, []);\n\n useEffect(() => {\n const requested = sceneMap.get(activeSceneId);\n if (!requested) {\n reportError(activeSceneId, new Error(`Unknown panorama scene: ${activeSceneId}`));\n return;\n }\n\n const liveScene = slotsRef.current[liveSlotRef.current];\n if (phaseRef.current === \"idle\" && liveScene?.id === requested.id) {\n requestedSceneIdRef.current = requested.id;\n return;\n }\n if (\n phaseRef.current === \"preloading\" &&\n pendingSlot !== null &&\n slotsRef.current[pendingSlot]?.id === requested.id\n ) {\n requestedSceneIdRef.current = requested.id;\n return;\n }\n if (phaseRef.current === \"transitioning\" || phaseRef.current === \"capturing\") {\n requestedSceneIdRef.current = requested.id;\n captureReasonRef.current = \"interrupt\";\n setPhase(\"recapturing\");\n setCaptureRequestId((current) => current + 1);\n return;\n }\n startPreload(requested);\n }, [activeSceneId, pendingSlot, reportError, sceneMap, startPreload]);\n\n const handleReady = useCallback((slot: number) => {\n if (slot !== pendingSlot || phaseRef.current !== \"preloading\") {\n return;\n }\n if (transition.preset === \"none\") {\n const previousScene = slotsRef.current[liveSlotRef.current];\n const nextScene = slotsRef.current[slot];\n setSlots((current) => {\n const next: [PanoramaScene | null, PanoramaScene | null] = [...current] as [PanoramaScene | null, PanoramaScene | null];\n next[liveSlotRef.current] = null;\n return next;\n });\n setLiveSlot(slot);\n setActiveSlot(slot);\n setPendingSlot(null);\n setPhase(\"idle\");\n if (previousScene && nextScene) {\n onTransitionEnd?.({\n previousSceneId: previousScene.id,\n sceneId: nextScene.id,\n preset: \"none\",\n });\n }\n return;\n }\n interactionReleaseRef.current ??= controlsRef?.current?.acquireInteractionLock() ?? null;\n transitionFromRef.current = slotsRef.current[liveSlotRef.current];\n captureReasonRef.current = \"start\";\n setPhase(\"capturing\");\n setCaptureRequestId((current) => current + 1);\n }, [controlsRef, onTransitionEnd, pendingSlot, transition.preset]);\n\n const handleCaptured = useCallback((nextSnapshot: Snapshot) => {\n setSnapshot((current) => {\n current?.dispose();\n return nextSnapshot;\n });\n\n if (captureReasonRef.current === \"interrupt\") {\n startPreload(sceneMap.get(requestedSceneIdRef.current)!);\n return;\n }\n\n const sourceSlot = liveSlotRef.current;\n setSlots((current) => {\n const next: [PanoramaScene | null, PanoramaScene | null] = [...current] as [PanoramaScene | null, PanoramaScene | null];\n next[sourceSlot] = null;\n return next;\n });\n manager?.releaseUnused();\n if (pendingSlot !== null) {\n setLiveSlot(pendingSlot);\n }\n setPhase(\"transitioning\");\n setTransitionRunId((current) => current + 1);\n }, [manager, pendingSlot, sceneMap, startPreload]);\n\n const finishTransition = useCallback(() => {\n const nextSlot = pendingSlot;\n const previousScene = transitionFromRef.current;\n const nextScene = nextSlot === null ? null : slotsRef.current[nextSlot];\n if (nextSlot === null || !nextScene) {\n releaseInteraction();\n setPhase(\"idle\");\n return;\n }\n setActiveSlot(nextSlot);\n setLiveSlot(nextSlot);\n setPendingSlot(null);\n setPhase(\"idle\");\n const oldSnapshot = snapshot;\n setSnapshot(null);\n oldSnapshot?.dispose();\n releaseInteraction();\n if (previousScene) {\n onTransitionEnd?.({\n previousSceneId: previousScene.id,\n sceneId: nextScene.id,\n preset: transition.preset,\n });\n }\n }, [onTransitionEnd, pendingSlot, releaseInteraction, snapshot, transition.preset]);\n\n useEffect(() => () => {\n releaseInteraction();\n snapshot?.dispose();\n }, [releaseInteraction, snapshot]);\n\n const { gl } = useThree();\n useEffect(() => {\n const canvas = gl.domElement;\n const onContextLost = (event: Event) => {\n event.preventDefault();\n releaseInteraction();\n manager?.dispose();\n snapshot?.dispose();\n setSnapshot(null);\n setPendingSlot(null);\n setPhase(\"idle\");\n };\n const onContextRestored = () => {\n manager?.resume();\n setRecoveryKey((current) => current + 1);\n };\n canvas.addEventListener(\"webglcontextlost\", onContextLost);\n canvas.addEventListener(\"webglcontextrestored\", onContextRestored);\n return () => {\n canvas.removeEventListener(\"webglcontextlost\", onContextLost);\n canvas.removeEventListener(\"webglcontextrestored\", onContextRestored);\n };\n }, [gl, manager, releaseInteraction, snapshot]);\n\n const renderedScene = slots[liveSlot];\n const snapshotVisible = snapshot !== null && (\n phase === \"transitioning\" ||\n phase === \"recapturing\" ||\n phase === \"preloading\"\n );\n\n return (\n <Fragment>\n <SnapshotCapture\n requestId={captureRequestId}\n maxPixels={Math.max(1, snapshotMaxPixels)}\n onCaptured={handleCaptured}\n />\n {[0, 1].map((slot) => {\n const source = slots[slot];\n const isLive = slot === liveSlot;\n const isPending = slot === pendingSlot;\n return (\n <SceneSource\n key={`${slot}:${source?.id ?? \"empty\"}:${recoveryKey}`}\n scene={source}\n visible={isLive}\n baseOnly={isPending && phase !== \"idle\"}\n onReady={() => handleReady(slot)}\n onError={(error) => {\n if (source) {\n reportError(source.id, error);\n }\n }}\n />\n );\n })}\n {snapshotVisible ? (\n <SnapshotOverlay\n snapshot={snapshot}\n transition={transition}\n running={phase === \"transitioning\"}\n runId={transitionRunId}\n onFinish={finishTransition}\n />\n ) : null}\n {phase === \"idle\" && renderedScene ? renderHotspots?.(renderedScene) : null}\n </Fragment>\n );\n}\n\nexport function PanoramaScenes({\n maxTextureMemoryMb,\n maxConcurrentTileLoads,\n ...props\n}: PanoramaScenesProps) {\n return (\n <TileTextureManagerProvider\n maxTextureMemoryMb={maxTextureMemoryMb}\n maxConcurrentLoads={maxConcurrentTileLoads}\n >\n <PanoramaScenesController {...props} />\n </TileTextureManagerProvider>\n );\n}\n","import { useThree } from \"@react-three/fiber\";\nimport {\n createContext,\n useContext,\n useEffect,\n useMemo,\n} from \"react\";\nimport type { ReactNode } from \"react\";\nimport { TileTextureManager } from \"./texture-manager\";\n\nconst TileTextureManagerContext = createContext<TileTextureManager | null>(\n null,\n);\n\nexport type TileTextureManagerProviderProps = {\n children?: ReactNode;\n /** Shared viewer-wide GPU budget. Defaults to 128 MiB. */\n maxTextureMemoryMb?: number;\n /** Shared limit for tile image requests. Defaults to 4. */\n maxConcurrentLoads?: number;\n};\n\n/**\n * Provides one tile cache for a panorama scene controller. Keeping this scope\n * at the viewer level prevents a leaving and entering scene from each claiming\n * an independent texture-memory budget.\n */\nexport function TileTextureManagerProvider({\n children,\n maxTextureMemoryMb = 128,\n maxConcurrentLoads = 4,\n}: TileTextureManagerProviderProps) {\n const gl = useThree((state) => state.gl);\n const anisotropy = gl.capabilities.getMaxAnisotropy();\n const manager = useMemo(\n () =>\n new TileTextureManager({\n anisotropy,\n maxBytes: Math.max(1, maxTextureMemoryMb) * 1024 * 1024,\n concurrency: Math.max(1, Math.floor(maxConcurrentLoads)),\n retryCount: 1,\n }),\n [anisotropy, maxConcurrentLoads, maxTextureMemoryMb],\n );\n\n useEffect(() => {\n manager.resume();\n return () => manager.dispose();\n }, [manager]);\n\n return (\n <TileTextureManagerContext.Provider value={manager}>\n {children}\n </TileTextureManagerContext.Provider>\n );\n}\n\nexport function useSharedTileTextureManager() {\n return useContext(TileTextureManagerContext);\n}\n","import {\n ClampToEdgeWrapping,\n LinearFilter,\n SRGBColorSpace,\n Texture,\n TextureLoader,\n} from \"three\";\nimport type {\n TextureEntrySnapshot,\n TileAddress,\n TileLoadError,\n TileLoadProgress,\n} from \"./types\";\n\ntype Listener = (snapshot: TextureEntrySnapshot) => void;\n\ntype TextureEntry = TextureEntrySnapshot & {\n key: string;\n url: string;\n address: TileAddress;\n refs: number;\n listeners: Set<Listener>;\n lastUsed: number;\n bytes: number;\n};\n\ntype TextureManagerOptions = {\n anisotropy: number;\n maxBytes: number;\n concurrency: number;\n retryCount: number;\n onProgress?: (progress: TileLoadProgress) => void;\n onError?: (event: TileLoadError) => void;\n};\n\nconst EMPTY_TEXTURE_SNAPSHOT: TextureEntrySnapshot = {\n status: \"idle\",\n texture: null,\n error: null,\n};\n\nexport class TileTextureManager {\n private readonly loader = new TextureLoader();\n private readonly entries = new Map<string, TextureEntry>();\n private readonly queue: TextureEntry[] = [];\n private activeLoads = 0;\n private totalBytes = 0;\n private requested = 0;\n private loaded = 0;\n private failed = 0;\n private disposed = false;\n private generation = 0;\n private options: TextureManagerOptions;\n\n constructor(options: TextureManagerOptions) {\n this.options = options;\n }\n\n resume() {\n this.disposed = false;\n this.drain();\n }\n\n getSnapshot(key: string): TextureEntrySnapshot {\n const entry = this.entries.get(key);\n return entry ? this.snapshot(entry) : EMPTY_TEXTURE_SNAPSHOT;\n }\n\n acquire(\n key: string,\n url: string,\n address: TileAddress,\n listener: Listener,\n ): () => void {\n let entry = this.entries.get(key);\n if (!entry) {\n entry = {\n key,\n url,\n address,\n status: \"idle\",\n texture: null,\n error: null,\n refs: 0,\n listeners: new Set(),\n lastUsed: performance.now(),\n bytes: 0,\n };\n this.entries.set(key, entry);\n }\n\n entry.refs += 1;\n entry.lastUsed = performance.now();\n entry.listeners.add(listener);\n listener(this.snapshot(entry));\n\n if (entry.status === \"idle\") {\n entry.status = \"queued\";\n this.queue.push(entry);\n this.requested += 1;\n this.emitProgress();\n this.drain();\n }\n\n return () => {\n entry!.listeners.delete(listener);\n entry!.refs = Math.max(0, entry!.refs - 1);\n entry!.lastUsed = performance.now();\n\n if (entry!.refs === 0 && entry!.status === \"queued\") {\n const queueIndex = this.queue.indexOf(entry!);\n if (queueIndex >= 0) {\n this.queue.splice(queueIndex, 1);\n }\n entry!.status = \"idle\";\n this.entries.delete(entry!.key);\n this.requested = Math.max(0, this.requested - 1);\n this.emitProgress();\n this.drain();\n return;\n }\n\n this.evict();\n };\n }\n\n dispose() {\n this.disposed = true;\n this.generation += 1;\n this.queue.length = 0;\n for (const entry of this.entries.values()) {\n entry.texture?.dispose();\n entry.listeners.clear();\n }\n this.entries.clear();\n this.totalBytes = 0;\n }\n\n /**\n * Releases textures that are no longer rendered by any Tile instance.\n * Scene transitions call this after the outgoing panorama has been\n * snapshotted, so the incoming scene never competes with stale GPU tiles.\n */\n releaseUnused() {\n for (const entry of Array.from(this.entries.values())) {\n if (entry.refs > 0) {\n continue;\n }\n entry.texture?.dispose();\n this.totalBytes -= entry.bytes;\n this.entries.delete(entry.key);\n }\n this.totalBytes = Math.max(0, this.totalBytes);\n }\n\n private snapshot(entry: TextureEntry): TextureEntrySnapshot {\n return {\n status: entry.status,\n texture: entry.texture,\n error: entry.error,\n };\n }\n\n private notify(entry: TextureEntry) {\n const snapshot = this.snapshot(entry);\n for (const listener of entry.listeners) {\n listener(snapshot);\n }\n }\n\n private emitProgress() {\n this.options.onProgress?.({\n requested: this.requested,\n loaded: this.loaded,\n failed: this.failed,\n active: this.activeLoads,\n queued: this.queue.length,\n });\n }\n\n private drain() {\n while (\n !this.disposed &&\n this.activeLoads < this.options.concurrency &&\n this.queue.length > 0\n ) {\n const entry = this.queue.shift()!;\n if (entry.refs === 0) {\n entry.status = \"idle\";\n this.entries.delete(entry.key);\n this.requested = Math.max(0, this.requested - 1);\n continue;\n }\n entry.status = \"loading\";\n this.activeLoads += 1;\n this.notify(entry);\n this.emitProgress();\n void this.loadAndFinish(entry);\n }\n }\n\n private async load(entry: TextureEntry, generation: number) {\n let lastError: unknown = null;\n for (let attempt = 0; attempt <= this.options.retryCount; attempt += 1) {\n try {\n const texture = await this.loader.loadAsync(entry.url);\n if (this.disposed || generation !== this.generation) {\n texture.dispose();\n return;\n }\n this.configureTexture(texture);\n entry.texture = texture;\n entry.status = \"loaded\";\n entry.error = null;\n entry.bytes = entry.address.width * entry.address.height * 4;\n entry.lastUsed = performance.now();\n this.totalBytes += entry.bytes;\n this.loaded += 1;\n this.notify(entry);\n return;\n } catch (error) {\n lastError = error;\n }\n }\n\n if (!this.disposed && generation === this.generation) {\n entry.status = \"error\";\n entry.error = lastError;\n this.failed += 1;\n this.notify(entry);\n this.options.onError?.({\n address: entry.address,\n url: entry.url,\n error: lastError,\n });\n }\n }\n\n private configureTexture(texture: Texture) {\n texture.colorSpace = SRGBColorSpace;\n texture.wrapS = ClampToEdgeWrapping;\n texture.wrapT = ClampToEdgeWrapping;\n texture.magFilter = LinearFilter;\n texture.minFilter = LinearFilter;\n texture.generateMipmaps = false;\n texture.anisotropy = Math.min(4, this.options.anisotropy);\n texture.needsUpdate = true;\n }\n\n private evict() {\n if (this.totalBytes <= this.options.maxBytes) {\n return;\n }\n\n const candidates = Array.from(this.entries.values())\n .filter((entry) => entry.refs === 0 && entry.texture)\n .sort((a, b) => a.lastUsed - b.lastUsed);\n for (const entry of candidates) {\n if (this.totalBytes <= this.options.maxBytes) {\n break;\n }\n entry.texture?.dispose();\n this.totalBytes -= entry.bytes;\n this.entries.delete(entry.key);\n }\n this.totalBytes = Math.max(0, this.totalBytes);\n }\n\n private finishLoad(generation: number) {\n this.activeLoads = Math.max(0, this.activeLoads - 1);\n if (!this.disposed && generation === this.generation) {\n this.emitProgress();\n this.evict();\n }\n if (!this.disposed) {\n this.drain();\n }\n }\n\n private async loadAndFinish(entry: TextureEntry) {\n const generation = this.generation;\n try {\n await this.load(entry, generation);\n } finally {\n this.finishLoad(generation);\n }\n }\n}\n","import { useFrame, useThree } from \"@react-three/fiber\";\nimport {\n memo,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n Box3,\n ClampToEdgeWrapping,\n Frustum,\n LinearFilter,\n Matrix4,\n PlaneGeometry,\n PerspectiveCamera,\n SRGBColorSpace,\n Texture,\n TextureLoader,\n Vector3,\n} from \"three\";\nimport {\n CUBE_FACES,\n CUBE_RADIUS,\n PREVIEW_FACE_ORDER,\n getFaceTransform,\n getPreferredLevel,\n getTileBoundingBox,\n getTileLocalLayout,\n makeTileAddress,\n previewAtlasVRange,\n tileKey,\n} from \"./face-layout\";\nimport {\n buildDefaultTileUrlTemplate,\n parseMultires,\n resolveRelativeTileUrl,\n resolveTemplateUrl,\n} from \"./multires\";\nimport { TileTextureManager } from \"./texture-manager\";\nimport { useSharedTileTextureManager } from \"./texture-manager-context\";\nimport type {\n CubeFaceCode,\n TextureEntrySnapshot,\n TileAddress,\n TileProps,\n} from \"./types\";\n\nconst MAX_LOD_UPDATE_INTERVAL_MS = 100;\nconst FAST_ROTATION_THRESHOLD_RADIANS = Math.PI / 180;\nconst FAST_FOV_THRESHOLD_DEGREES = 0.5;\nconst VIEW_CHANGE_EPSILON = 0.0001;\nconst VISIBILITY_FOV_PADDING_DEGREES = 8;\nconst PREVIEW_RADIUS = CUBE_RADIUS + 0.05;\nconst SHARED_TILE_GEOMETRY = new PlaneGeometry(1, 1);\n\ntype TileLayer = {\n level: number;\n addresses: TileAddress[];\n renderOrder: number;\n};\n\ntype TileCandidate = {\n address: TileAddress;\n bounds: Box3;\n};\n\nfunction usePreviewTexture(\n url: string | null,\n anisotropy: number,\n onError?: (error: unknown) => void,\n) {\n const [texture, setTexture] = useState<Texture | null>(null);\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n\n useEffect(() => {\n if (!url) {\n setTexture(null);\n return;\n }\n\n let active = true;\n const loader = new TextureLoader();\n setTexture(null);\n loader.load(\n url,\n (loadedTexture) => {\n if (!active) {\n loadedTexture.dispose();\n return;\n }\n loadedTexture.colorSpace = SRGBColorSpace;\n loadedTexture.wrapS = ClampToEdgeWrapping;\n loadedTexture.wrapT = ClampToEdgeWrapping;\n loadedTexture.magFilter = LinearFilter;\n loadedTexture.minFilter = LinearFilter;\n loadedTexture.generateMipmaps = false;\n loadedTexture.anisotropy = Math.min(4, anisotropy);\n loadedTexture.needsUpdate = true;\n setTexture(loadedTexture);\n },\n undefined,\n (error) => {\n if (active) {\n setTexture(null);\n onErrorRef.current?.(error);\n }\n },\n );\n\n return () => {\n active = false;\n };\n }, [anisotropy, url]);\n\n useEffect(\n () => () => {\n texture?.dispose();\n },\n [texture],\n );\n\n return texture;\n}\n\nfunction PreviewFace({\n face,\n texture,\n faceOrder,\n}: {\n face: CubeFaceCode;\n texture: Texture;\n faceOrder: readonly CubeFaceCode[];\n}) {\n const geometry = useMemo(() => {\n const nextGeometry = new PlaneGeometry(\n PREVIEW_RADIUS * 2,\n PREVIEW_RADIUS * 2,\n );\n const uv = nextGeometry.getAttribute(\"uv\");\n const { offset, scale } = previewAtlasVRange(face, faceOrder);\n const inset = scale / 512;\n for (let index = 0; index < uv.count; index += 1) {\n const sourceV = uv.getY(index);\n uv.setY(\n index,\n offset + inset + sourceV * Math.max(0, scale - inset * 2),\n );\n }\n uv.needsUpdate = true;\n return nextGeometry;\n }, [face, faceOrder]);\n\n useEffect(\n () => () => {\n geometry.dispose();\n },\n [geometry],\n );\n\n const transform = getFaceTransform(face, PREVIEW_RADIUS);\n return (\n <mesh\n geometry={geometry}\n position={transform.position}\n renderOrder={-100}\n rotation={transform.rotation}\n >\n <meshBasicMaterial\n depthTest={false}\n depthWrite={false}\n map={texture}\n toneMapped={false}\n />\n </mesh>\n );\n}\n\nfunction PreviewCube({\n texture,\n faceOrder,\n}: {\n texture: Texture;\n faceOrder: readonly CubeFaceCode[];\n}) {\n return CUBE_FACES.map((face) => (\n <PreviewFace\n key={face}\n face={face}\n texture={texture}\n faceOrder={faceOrder}\n />\n ));\n}\n\nfunction useManagedTexture(\n manager: TileTextureManager,\n key: string,\n url: string,\n address: TileAddress,\n): TextureEntrySnapshot {\n const [managedState, setManagedState] = useState(() => ({\n manager,\n key,\n url,\n snapshot: manager.getSnapshot(key),\n }));\n\n const snapshot =\n managedState.manager === manager &&\n managedState.key === key &&\n managedState.url === url\n ? managedState.snapshot\n : manager.getSnapshot(key);\n\n useEffect(\n () =>\n manager.acquire(key, url, address, (nextSnapshot) => {\n setManagedState({\n manager,\n key,\n url,\n snapshot: nextSnapshot,\n });\n }),\n [key, manager, url],\n );\n\n return snapshot;\n}\n\nconst TileMesh = memo(function TileMesh({\n address,\n manager,\n renderOrder,\n resolveUrl,\n}: {\n address: TileAddress;\n manager: TileTextureManager;\n renderOrder: number;\n resolveUrl: (address: TileAddress) => string;\n}) {\n const url = resolveUrl(address);\n // A viewer-scoped manager serves multiple scenes. The tile coordinate alone\n // is only unique within one cube panorama, so include the resolved resource\n // URL to prevent same-address tiles from different scenes sharing a texture.\n const cacheKey = `${url}\\u0000${tileKey(address)}`;\n const snapshot = useManagedTexture(manager, cacheKey, url, address);\n const layout = getTileLocalLayout(address);\n const transform = getFaceTransform(address.face);\n\n if (!snapshot.texture) {\n return null;\n }\n\n return (\n <group position={transform.position} rotation={transform.rotation}>\n <mesh\n geometry={SHARED_TILE_GEOMETRY}\n position={[layout.x, layout.y, 0]}\n renderOrder={renderOrder}\n scale={[layout.width, layout.height, 1]}\n >\n <meshBasicMaterial\n depthTest={false}\n depthWrite={false}\n map={snapshot.texture}\n toneMapped={false}\n />\n </mesh>\n </group>\n );\n});\n\nconst TileLayerMeshes = memo(function TileLayerMeshes({\n layer,\n manager,\n resolveUrl,\n}: {\n layer: TileLayer;\n manager: TileTextureManager;\n resolveUrl: (address: TileAddress) => string;\n}) {\n return layer.addresses.map((address) => (\n <TileMesh\n key={tileKey(address)}\n address={address}\n manager={manager}\n renderOrder={layer.renderOrder}\n resolveUrl={resolveUrl}\n />\n ));\n});\n\nfunction buildTileCandidates(\n levels: number[],\n tileSize: number,\n): TileCandidate[][] {\n return levels.map((faceSize, index) => {\n const level = index + 1;\n const cols = Math.ceil(faceSize / tileSize);\n const rows = Math.ceil(faceSize / tileSize);\n const candidates: TileCandidate[] = [];\n\n for (const face of CUBE_FACES) {\n for (let row = 1; row <= rows; row += 1) {\n for (let col = 1; col <= cols; col += 1) {\n const address = makeTileAddress(\n face,\n level,\n faceSize,\n tileSize,\n col,\n row,\n );\n candidates.push({\n address,\n bounds: getTileBoundingBox(address),\n });\n }\n }\n }\n\n return candidates;\n });\n}\n\nfunction visibleAddresses(\n candidates: TileCandidate[],\n frustum: Frustum,\n): TileAddress[] {\n return candidates\n .filter((candidate) => frustum.intersectsBox(candidate.bounds))\n .map((candidate) => candidate.address);\n}\n\nfunction updateVisibilityFrustum(\n camera: PerspectiveCamera,\n projectionMatrix: Matrix4,\n frustum: Frustum,\n) {\n camera.updateProjectionMatrix();\n camera.updateMatrixWorld();\n camera.matrixWorldInverse.copy(camera.matrixWorld).invert();\n projectionMatrix.multiplyMatrices(\n camera.projectionMatrix,\n camera.matrixWorldInverse,\n );\n frustum.setFromProjectionMatrix(projectionMatrix);\n}\n\nfunction addAddress(\n addressesByLevel: Map<number, Map<string, TileAddress>>,\n address: TileAddress,\n) {\n let levelAddresses = addressesByLevel.get(address.level);\n if (!levelAddresses) {\n levelAddresses = new Map();\n addressesByLevel.set(address.level, levelAddresses);\n }\n levelAddresses.set(tileKey(address), address);\n}\n\nfunction parentAddresses(\n child: TileAddress,\n parentLevel: number,\n parentFaceSize: number,\n tileSize: number,\n): TileAddress[] {\n const childLeft = ((child.col - 1) * child.tileSize) / child.faceSize;\n const childTop = ((child.row - 1) * child.tileSize) / child.faceSize;\n const childRight = childLeft + child.width / child.faceSize;\n const childBottom = childTop + child.height / child.faceSize;\n const cols = Math.ceil(parentFaceSize / tileSize);\n const rows = Math.ceil(parentFaceSize / tileSize);\n const firstCol = Math.max(\n 1,\n Math.floor((childLeft * parentFaceSize) / tileSize) + 1,\n );\n const lastCol = Math.min(\n cols,\n Math.ceil((childRight * parentFaceSize) / tileSize),\n );\n const firstRow = Math.max(\n 1,\n Math.floor((childTop * parentFaceSize) / tileSize) + 1,\n );\n const lastRow = Math.min(\n rows,\n Math.ceil((childBottom * parentFaceSize) / tileSize),\n );\n const addresses: TileAddress[] = [];\n\n for (let row = firstRow; row <= lastRow; row += 1) {\n for (let col = firstCol; col <= lastCol; col += 1) {\n addresses.push(\n makeTileAddress(\n child.face,\n parentLevel,\n parentFaceSize,\n tileSize,\n col,\n row,\n ),\n );\n }\n }\n return addresses;\n}\n\nfunction centerFacingAddress(\n candidates: TileCandidate[],\n camera: PerspectiveCamera,\n): TileAddress {\n const direction = camera.getWorldDirection(new Vector3());\n const center = new Vector3();\n let bestCandidate = candidates[0]!;\n let bestAlignment = -Infinity;\n\n for (const candidate of candidates) {\n candidate.bounds.getCenter(center).normalize();\n const alignment = center.dot(direction);\n if (alignment > bestAlignment) {\n bestCandidate = candidate;\n bestAlignment = alignment;\n }\n }\n\n return bestCandidate.address;\n}\n\nfunction buildLayers(\n targetLevel: number,\n levels: number[],\n tileSize: number,\n frustum: Frustum,\n camera: PerspectiveCamera,\n candidatesByLevel: TileCandidate[][],\n): TileLayer[] {\n const addressesByLevel = new Map<number, Map<string, TileAddress>>();\n const targetCandidates = candidatesByLevel[targetLevel - 1]!;\n const targetAddresses = visibleAddresses(targetCandidates, frustum);\n\n // A stale camera matrix must not schedule an entire face. The center-facing\n // target and its parent chain provide a bounded fallback until the next pass.\n const visibleTargets =\n targetAddresses.length > 0\n ? targetAddresses\n : [centerFacingAddress(targetCandidates, camera)];\n\n for (const address of visibleTargets) {\n addAddress(addressesByLevel, address);\n }\n\n let children = visibleTargets;\n for (let parentLevel = targetLevel - 1; parentLevel >= 1; parentLevel -= 1) {\n const parentFaceSize = levels[parentLevel - 1]!;\n const parents = new Map<string, TileAddress>();\n for (const child of children) {\n for (const parent of parentAddresses(\n child,\n parentLevel,\n parentFaceSize,\n tileSize,\n )) {\n parents.set(tileKey(parent), parent);\n addAddress(addressesByLevel, parent);\n }\n }\n children = Array.from(parents.values());\n }\n\n return Array.from(addressesByLevel.entries())\n .sort(([firstLevel], [secondLevel]) => firstLevel - secondLevel)\n .map(([level, addresses]) => ({\n level,\n addresses: Array.from(addresses.values()),\n renderOrder: -100 + level * 10,\n }));\n}\n\nfunction layerToken(layers: TileLayer[]): string {\n return layers\n .map(\n (layer) =>\n `${layer.level}:${layer.addresses.map(tileKey).join(\",\")}`,\n )\n .join(\"|\");\n}\n\nexport function Tile({\n baseUrl,\n multires,\n previewUrl,\n previewFaceOrder = PREVIEW_FACE_ORDER,\n urlTemplate,\n resolveTileUrl,\n maxTextureMemoryMb = 128,\n maxConcurrentLoads = 8,\n retryCount = 1,\n loadMode = \"full\",\n visible = true,\n onReady,\n onPreviewError,\n onLoadProgress,\n onTileError,\n onLevelChange,\n}: TileProps) {\n const { camera, gl, size } = useThree();\n const multiresConfig = useMemo(() => parseMultires(multires), [multires]);\n const { levels, tileSize } = multiresConfig;\n const multiresToken = `${tileSize}:${levels.join(\",\")}`;\n const candidatesByLevel = useMemo(\n () => buildTileCandidates(levels, tileSize),\n [levels, tileSize],\n );\n const anisotropy = gl.capabilities.getMaxAnisotropy();\n const effectivePreviewUrl =\n previewUrl === undefined\n ? `${baseUrl.replace(/\\/$/, \"\")}/previews/cube-vertical.webp`\n : previewUrl;\n const previewTexture = usePreviewTexture(\n effectivePreviewUrl,\n anisotropy,\n onPreviewError,\n );\n const sharedManager = useSharedTileTextureManager();\n const progressRef = useRef(onLoadProgress);\n const errorRef = useRef(onTileError);\n const levelChangeRef = useRef(onLevelChange);\n progressRef.current = onLoadProgress;\n errorRef.current = onTileError;\n levelChangeRef.current = onLevelChange;\n\n const ownedManager = useMemo(\n () =>\n new TileTextureManager({\n anisotropy,\n maxBytes: Math.max(1, maxTextureMemoryMb) * 1024 * 1024,\n concurrency: Math.max(1, Math.floor(maxConcurrentLoads)),\n retryCount: Math.max(0, Math.floor(retryCount)),\n onProgress: (progress) => progressRef.current?.(progress),\n onError: (event) => errorRef.current?.(event),\n }),\n [\n anisotropy,\n baseUrl,\n maxConcurrentLoads,\n maxTextureMemoryMb,\n multiresToken,\n retryCount,\n resolveTileUrl,\n urlTemplate,\n ],\n );\n const manager = sharedManager ?? ownedManager;\n useEffect(() => {\n manager.resume();\n return () => {\n if (manager === ownedManager) {\n manager.dispose();\n return;\n }\n queueMicrotask(() => manager.releaseUnused());\n };\n }, [manager, ownedManager]);\n\n const readyRef = useRef(false);\n useEffect(() => {\n readyRef.current = false;\n }, [effectivePreviewUrl]);\n useEffect(() => {\n if (!previewTexture || readyRef.current) {\n return;\n }\n readyRef.current = true;\n onReady?.();\n }, [onReady, previewTexture]);\n\n const template = urlTemplate ?? buildDefaultTileUrlTemplate();\n const resolveUrl = useMemo(\n () => (address: TileAddress) => {\n const relativePath = resolveTileUrl\n ? resolveTileUrl(address)\n : resolveTemplateUrl(template, address);\n return resolveRelativeTileUrl(baseUrl, relativePath);\n },\n [baseUrl, resolveTileUrl, template],\n );\n\n const [layers, setLayers] = useState<TileLayer[]>([]);\n const layerTokenRef = useRef(\"\");\n const currentLevelRef = useRef(1);\n const lastUpdateAtRef = useRef(-Infinity);\n const visibilityDirtyRef = useRef(true);\n const lastVisibilityQuaternionRef = useRef(camera.quaternion.clone());\n const lastVisibilityFovRef = useRef(Number.NaN);\n const lastViewportRef = useRef({ width: 0, height: 0, dpr: 0 });\n const frustumRef = useRef(new Frustum());\n const projectionMatrixRef = useRef(new Matrix4());\n const visibilityCameraRef = useRef(new PerspectiveCamera());\n\n useEffect(() => {\n currentLevelRef.current = 1;\n layerTokenRef.current = \"\";\n visibilityDirtyRef.current = true;\n setLayers([]);\n }, [manager, multiresToken]);\n\n useEffect(() => {\n if (loadMode !== \"preview\") {\n return;\n }\n layerTokenRef.current = \"\";\n setLayers([]);\n }, [loadMode]);\n\n const commitLayers = (nextLayers: TileLayer[]) => {\n const nextToken = layerToken(nextLayers);\n if (nextToken !== layerTokenRef.current) {\n layerTokenRef.current = nextToken;\n setLayers(nextLayers);\n }\n };\n\n useFrame(() => {\n if (loadMode === \"preview\") {\n return;\n }\n if (!(camera instanceof PerspectiveCamera)) {\n return;\n }\n\n const now = performance.now();\n const pixelRatio = gl.getPixelRatio();\n const rotationDelta = lastVisibilityQuaternionRef.current.angleTo(\n camera.quaternion,\n );\n const fovDelta = Number.isFinite(lastVisibilityFovRef.current)\n ? Math.abs(camera.fov - lastVisibilityFovRef.current)\n : Infinity;\n const lastViewport = lastViewportRef.current;\n const viewportChanged =\n lastViewport.width !== size.width ||\n lastViewport.height !== size.height ||\n lastViewport.dpr !== pixelRatio;\n const viewChanged =\n visibilityDirtyRef.current ||\n viewportChanged ||\n rotationDelta > VIEW_CHANGE_EPSILON ||\n fovDelta > VIEW_CHANGE_EPSILON;\n const movingQuickly =\n rotationDelta >= FAST_ROTATION_THRESHOLD_RADIANS ||\n fovDelta >= FAST_FOV_THRESHOLD_DEGREES;\n\n if (!viewChanged) {\n return;\n }\n\n const needsImmediateUpdate =\n visibilityDirtyRef.current ||\n viewportChanged ||\n movingQuickly;\n if (\n !needsImmediateUpdate &&\n now - lastUpdateAtRef.current < MAX_LOD_UPDATE_INTERVAL_MS\n ) {\n return;\n }\n\n lastUpdateAtRef.current = now;\n\n const targetLevel = loadMode === \"base\"\n ? 1\n : getPreferredLevel(\n levels,\n size.height,\n pixelRatio,\n camera.fov,\n currentLevelRef.current,\n );\n if (targetLevel !== currentLevelRef.current) {\n currentLevelRef.current = targetLevel;\n levelChangeRef.current?.(targetLevel);\n }\n\n const visibilityCamera = visibilityCameraRef.current;\n visibilityCamera.copy(camera, false);\n visibilityCamera.fov = Math.min(\n 179,\n camera.fov + VISIBILITY_FOV_PADDING_DEGREES,\n );\n visibilityCamera.aspect = camera.aspect;\n updateVisibilityFrustum(\n visibilityCamera,\n projectionMatrixRef.current,\n frustumRef.current,\n );\n\n const nextLayers = buildLayers(\n targetLevel,\n levels,\n tileSize,\n frustumRef.current,\n camera,\n candidatesByLevel,\n );\n visibilityDirtyRef.current = false;\n lastVisibilityQuaternionRef.current.copy(camera.quaternion);\n lastVisibilityFovRef.current = camera.fov;\n lastViewportRef.current = {\n width: size.width,\n height: size.height,\n dpr: pixelRatio,\n };\n commitLayers(nextLayers);\n });\n\n return (\n <group visible={visible}>\n {previewTexture ? (\n <PreviewCube\n texture={previewTexture}\n faceOrder={previewFaceOrder}\n />\n ) : null}\n {layers.map((layer) => (\n <TileLayerMeshes\n key={layer.level}\n layer={layer}\n manager={manager}\n resolveUrl={resolveUrl}\n />\n ))}\n </group>\n );\n}\n","import {\n Box3,\n Euler,\n Quaternion,\n Vector3,\n} from \"three\";\nimport type { CubeFaceCode, TileAddress } from \"./types\";\nimport { DEFAULT_PANORAMA_RADIUS } from \"../panorama-radius\";\n\nexport const CUBE_FACES: CubeFaceCode[] = [\"f\", \"r\", \"b\", \"l\", \"u\", \"d\"];\nexport const PREVIEW_FACE_ORDER: CubeFaceCode[] = [\"l\", \"f\", \"r\", \"b\", \"u\", \"d\"];\nexport const CUBE_RADIUS = DEFAULT_PANORAMA_RADIUS;\n\nexport type FaceTransform = {\n position: [number, number, number];\n rotation: [number, number, number];\n};\n\nexport function getFaceTransform(\n face: CubeFaceCode,\n radius = CUBE_RADIUS,\n): FaceTransform {\n switch (face) {\n case \"f\":\n return { position: [0, 0, -radius], rotation: [0, 0, 0] };\n case \"b\":\n return { position: [0, 0, radius], rotation: [0, Math.PI, 0] };\n case \"r\":\n return {\n position: [radius, 0, 0],\n rotation: [0, -Math.PI / 2, 0],\n };\n case \"l\":\n return {\n position: [-radius, 0, 0],\n rotation: [0, Math.PI / 2, 0],\n };\n case \"u\":\n return {\n position: [0, radius, 0],\n rotation: [Math.PI / 2, 0, 0],\n };\n case \"d\":\n return {\n position: [0, -radius, 0],\n rotation: [-Math.PI / 2, 0, 0],\n };\n }\n}\n\nexport function getTileLocalLayout(address: TileAddress, radius = CUBE_RADIUS) {\n const left = (address.col - 1) * address.tileSize;\n const top = (address.row - 1) * address.tileSize;\n const right = left + address.width;\n const bottom = top + address.height;\n return {\n x: (((left + right) / address.faceSize) - 1) * radius,\n y: (1 - (top + bottom) / address.faceSize) * radius,\n width: (address.width / address.faceSize) * radius * 2,\n height: (address.height / address.faceSize) * radius * 2,\n };\n}\n\nconst faceQuaternionCache = new Map<CubeFaceCode, Quaternion>();\n\nfunction getFaceQuaternion(face: CubeFaceCode): Quaternion {\n const cached = faceQuaternionCache.get(face);\n if (cached) {\n return cached;\n }\n const transform = getFaceTransform(face);\n const quaternion = new Quaternion().setFromEuler(\n new Euler(...transform.rotation, \"XYZ\"),\n );\n faceQuaternionCache.set(face, quaternion);\n return quaternion;\n}\n\nexport function getTileBoundingBox(\n address: TileAddress,\n radius = CUBE_RADIUS,\n): Box3 {\n const transform = getFaceTransform(address.face, radius);\n const local = getTileLocalLayout(address, radius);\n const halfWidth = local.width / 2;\n const halfHeight = local.height / 2;\n const quaternion = getFaceQuaternion(address.face);\n const position = new Vector3(...transform.position);\n const corners = [\n new Vector3(local.x - halfWidth, local.y - halfHeight, 0),\n new Vector3(local.x + halfWidth, local.y - halfHeight, 0),\n new Vector3(local.x - halfWidth, local.y + halfHeight, 0),\n new Vector3(local.x + halfWidth, local.y + halfHeight, 0),\n ];\n\n for (const corner of corners) {\n corner.applyQuaternion(quaternion).add(position);\n }\n\n return new Box3().setFromPoints(corners);\n}\n\nexport function makeTileAddress(\n face: CubeFaceCode,\n level: number,\n faceSize: number,\n tileSize: number,\n col: number,\n row: number,\n): TileAddress {\n const left = (col - 1) * tileSize;\n const top = (row - 1) * tileSize;\n return {\n face,\n level,\n row,\n col,\n faceSize,\n tileSize,\n width: Math.min(tileSize, faceSize - left),\n height: Math.min(tileSize, faceSize - top),\n };\n}\n\nexport function tileKey(address: TileAddress): string {\n return `${address.level}/${address.face}/${address.row}/${address.col}`;\n}\n\nexport function getPreferredLevel(\n levels: number[],\n viewportHeight: number,\n pixelRatio: number,\n verticalFov: number,\n currentLevel: number,\n): number {\n const requiredFaceSize =\n viewportHeight * pixelRatio * (90 / Math.max(verticalFov, 1));\n let preferredLevel = levels.length;\n for (let index = 0; index < levels.length; index += 1) {\n if (levels[index]! >= requiredFaceSize) {\n preferredLevel = index + 1;\n break;\n }\n }\n\n if (preferredLevel > currentLevel) {\n const currentSize = levels[currentLevel - 1] ?? levels[0]!;\n return requiredFaceSize > currentSize * 1.2\n ? preferredLevel\n : currentLevel;\n }\n if (preferredLevel < currentLevel) {\n const preferredSize = levels[preferredLevel - 1] ?? levels[0]!;\n return requiredFaceSize < preferredSize * 0.8\n ? preferredLevel\n : currentLevel;\n }\n return currentLevel;\n}\n\nexport function previewAtlasVRange(\n face: CubeFaceCode,\n faceOrder: readonly CubeFaceCode[] = PREVIEW_FACE_ORDER,\n): {\n offset: number;\n scale: number;\n} {\n const index = faceOrder.indexOf(face);\n return {\n offset: (faceOrder.length - index - 1) / faceOrder.length,\n scale: 1 / faceOrder.length,\n };\n}\n","import type {\n TileAddress,\n TileMultiresConfig,\n} from \"./types\";\n\nfunction positiveInteger(value: number, name: string): number {\n if (!Number.isFinite(value) || value <= 0 || !Number.isInteger(value)) {\n throw new Error(`${name} must be a positive integer, received ${String(value)}`);\n }\n return value;\n}\n\nfunction ascendingLevels(levels: number[]): number[] {\n for (let index = 1; index < levels.length; index += 1) {\n if (levels[index]! <= levels[index - 1]!) {\n throw new Error(\"multires face sizes must be strictly ascending\");\n }\n }\n return levels;\n}\n\nexport function parseMultires(\n multires: string | TileMultiresConfig,\n): TileMultiresConfig {\n if (typeof multires !== \"string\") {\n const tileSize = positiveInteger(multires.tileSize, \"multires.tileSize\");\n if (multires.levels.length === 0) {\n throw new Error(\"multires.levels must contain at least one face size\");\n }\n const levels = ascendingLevels(\n multires.levels.map((level, index) =>\n positiveInteger(level, `multires.levels[${index}]`),\n ),\n );\n return { tileSize, levels };\n }\n\n const values = multires.split(\",\").map((part) => Number(part.trim()));\n\n if (values.length < 2 || values.some((value) => !Number.isFinite(value))) {\n throw new Error(\n \"multires must contain a tile size followed by at least one face size\",\n );\n }\n\n const tileSize = positiveInteger(values[0]!, \"multires tile size\");\n const levels = ascendingLevels(\n values.slice(1).map((level, index) =>\n positiveInteger(level, `multires level ${index + 1}`),\n ),\n );\n return { tileSize, levels };\n}\n\nexport function buildDefaultTileUrlTemplate(): string {\n return \"tiles/%s/l%l/%v/l%l_%s_%h_%v.webp\";\n}\n\nexport function resolveRelativeTileUrl(\n baseUrl: string,\n relativePath: string,\n): string {\n const normalizedBaseUrl = baseUrl.replace(/\\/+$/, \"\");\n const normalizedPath = relativePath.replace(/^\\/+/, \"\");\n return normalizedBaseUrl\n ? `${normalizedBaseUrl}/${normalizedPath}`\n : normalizedPath;\n}\n\nexport function resolveTemplateUrl(\n template: string,\n address: TileAddress,\n): string {\n return template\n .replace(/%s/g, address.face)\n .replace(/%l/g, String(address.level))\n .replace(/%(0*)([hxucvywr])/g, (_match, zeroes: string, placeholder: string) => {\n const value = \"hxuc\".includes(placeholder)\n ? address.col\n : address.row;\n return String(value).padStart(zeroes.length + 1, \"0\");\n });\n}\n","import { useThree } from \"@react-three/fiber\";\nimport { useEffect, useRef, useState } from \"react\";\nimport {\n ClampToEdgeWrapping,\n DoubleSide,\n LinearFilter,\n LinearMipmapLinearFilter,\n SRGBColorSpace,\n Texture,\n TextureLoader,\n} from \"three\";\nimport { HotspotAnchor } from \"./hotspot-anchor\";\nimport type { HotspotCommonProps } from \"./types\";\n\nexport type ImageHotspotProps = HotspotCommonProps & {\n src: string;\n onLoad?: (texture: Texture) => void;\n onError?: (error: unknown) => void;\n};\n\nfunction clampOpacity(opacity: number | undefined): number {\n if (!Number.isFinite(opacity)) {\n return 1;\n }\n return Math.max(0, Math.min(opacity!, 1));\n}\n\nfunction useHotspotImageTexture(\n src: string,\n onLoad: ImageHotspotProps[\"onLoad\"],\n onError: ImageHotspotProps[\"onError\"],\n) {\n const gl = useThree((state) => state.gl);\n const [texture, setTexture] = useState<Texture | null>(null);\n const onLoadRef = useRef(onLoad);\n const onErrorRef = useRef(onError);\n onLoadRef.current = onLoad;\n onErrorRef.current = onError;\n\n useEffect(() => {\n let active = true;\n setTexture(null);\n if (!src) {\n return () => {\n active = false;\n };\n }\n\n const loader = new TextureLoader();\n loader.load(\n src,\n (loadedTexture) => {\n if (!active) {\n loadedTexture.dispose();\n return;\n }\n loadedTexture.colorSpace = SRGBColorSpace;\n loadedTexture.wrapS = ClampToEdgeWrapping;\n loadedTexture.wrapT = ClampToEdgeWrapping;\n loadedTexture.magFilter = LinearFilter;\n loadedTexture.minFilter = LinearMipmapLinearFilter;\n loadedTexture.generateMipmaps = true;\n loadedTexture.anisotropy = gl.capabilities.getMaxAnisotropy();\n loadedTexture.needsUpdate = true;\n setTexture(loadedTexture);\n onLoadRef.current?.(loadedTexture);\n },\n undefined,\n (error) => {\n if (active) {\n onErrorRef.current?.(error);\n }\n },\n );\n\n return () => {\n active = false;\n };\n }, [gl, src]);\n\n useEffect(\n () => () => {\n texture?.dispose();\n },\n [texture],\n );\n\n return texture;\n}\n\nexport function ImageHotspot({\n src,\n width = 12,\n height = 8,\n opacity,\n onLoad,\n onError,\n ...anchorProps\n}: ImageHotspotProps) {\n const texture = useHotspotImageTexture(src, onLoad, onError);\n\n return (\n <HotspotAnchor {...anchorProps} height={height} width={width}>\n <mesh>\n <planeGeometry args={[1, 1]} />\n <meshBasicMaterial\n map={texture}\n opacity={texture ? clampOpacity(opacity) : 0}\n side={DoubleSide}\n toneMapped={false}\n transparent\n />\n </mesh>\n </HotspotAnchor>\n );\n}\n","import type { ThreeEvent } from \"@react-three/fiber\";\nimport { useFrame } from \"@react-three/fiber\";\nimport {\n useContext,\n useEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport type { ReactNode } from \"react\";\nimport {\n EdgesGeometry,\n MathUtils,\n Matrix4,\n Object3D,\n PlaneGeometry,\n PerspectiveCamera,\n Quaternion,\n Vector3,\n} from \"three\";\nimport { PanoramaControlsContext } from \"../auto-rotate\";\nimport { DEFAULT_PANORAMA_RADIUS } from \"../panorama-radius\";\nimport { useHotspotAccessibility } from \"./accessibility\";\nimport {\n normalizePanoPosition,\n panoPositionToVector3,\n vector3ToPanoPosition,\n} from \"./coordinates\";\nimport type {\n HotspotCommonProps,\n HotspotInteractionEvent,\n HotspotMode,\n HotspotPosition,\n} from \"./types\";\n\nconst DEFAULT_FLOATING_DISTANCE = 10;\nconst PANORAMA_RADIUS = DEFAULT_PANORAMA_RADIUS;\n// Keep a stable gap from the shell; a sub-unit gap z-fights at radius 1000.\nconst PANORAMA_SURFACE_INSET = 4;\nconst DEFAULT_REFERENCE_FOV = 75;\nconst MIN_ANGULAR_SIZE = 0.01;\nconst MAX_ANGULAR_SIZE = 179;\nconst DRAG_EPSILON_DEGREES = 0.001;\nconst LOCAL_FORWARD = new Vector3(0, 0, 1);\nconst HOTSPOT_MODE_RENDERING: Record<\n HotspotMode,\n { orientation: \"billboard\" | \"surface\"; placement: \"surface\" | \"floating\" }\n> = {\n surface: { orientation: \"surface\", placement: \"surface\" },\n billboard: { orientation: \"billboard\", placement: \"floating\" },\n};\n\ntype DragState = {\n pointerId: number;\n startPosition: HotspotPosition;\n releaseInteractionLock: () => void;\n moved: boolean;\n};\n\nexport type HotspotAnchorProps = Omit<HotspotCommonProps, \"opacity\"> & {\n width: number;\n height: number;\n /** Internal escape hatch for world-space children such as polygons. */\n useAngularScale?: boolean;\n focusContent?: ReactNode;\n children?: ReactNode;\n /** Private support for world-space polygon and polyline primitives. */\n internalOrientation?: \"billboard\" | \"surface\";\n /** Private support for world-space polygon and polyline primitives. */\n internalPlacement?: \"surface\" | \"floating\";\n};\n\nfunction angularSizeToWorldSize(size: number, radius: number): number {\n const safeSize = Number.isFinite(size)\n ? MathUtils.clamp(Math.abs(size), MIN_ANGULAR_SIZE, MAX_ANGULAR_SIZE)\n : MIN_ANGULAR_SIZE;\n return 2 * radius * Math.tan(MathUtils.degToRad(safeSize) / 2);\n}\n\nfunction resolveDistance(\n placement: \"surface\" | \"floating\",\n distance: number | undefined,\n width: number,\n height: number,\n): number {\n const maximumDistance = maximumHotspotDistance(width, height);\n if (placement === \"surface\") {\n return maximumDistance;\n }\n if (!Number.isFinite(distance)) {\n return DEFAULT_FLOATING_DISTANCE;\n }\n return MathUtils.clamp(Math.abs(distance!), 0.1, maximumDistance);\n}\n\nfunction maximumHotspotDistance(width: number, height: number): number {\n const safeWidth = MathUtils.clamp(\n Math.abs(Number.isFinite(width) ? width : MIN_ANGULAR_SIZE),\n MIN_ANGULAR_SIZE,\n MAX_ANGULAR_SIZE,\n );\n const safeHeight = MathUtils.clamp(\n Math.abs(Number.isFinite(height) ? height : MIN_ANGULAR_SIZE),\n MIN_ANGULAR_SIZE,\n MAX_ANGULAR_SIZE,\n );\n const cornerFactor = Math.hypot(\n 1,\n Math.tan(MathUtils.degToRad(safeWidth) / 2),\n Math.tan(MathUtils.degToRad(safeHeight) / 2),\n );\n return (PANORAMA_RADIUS - PANORAMA_SURFACE_INSET) / cornerFactor;\n}\n\nfunction fixedScaleFactor(cameraFov: number, referenceFov: number): number {\n const safeReferenceFov = MathUtils.clamp(referenceFov, 1, 179);\n return (\n Math.tan(MathUtils.degToRad(cameraFov) / 2) /\n Math.tan(MathUtils.degToRad(safeReferenceFov) / 2)\n );\n}\n\nfunction createSurfaceQuaternion(position: HotspotPosition): Quaternion {\n const outward = panoPositionToVector3(position).normalize();\n const inward = outward.clone().negate();\n const pitch = MathUtils.degToRad(position.pitch);\n const yaw = MathUtils.degToRad(position.yaw);\n const localUp = new Vector3(\n -Math.sin(pitch) * Math.sin(yaw),\n Math.cos(pitch),\n Math.sin(pitch) * Math.cos(yaw),\n ).normalize();\n const localRight = localUp.clone().cross(inward).normalize();\n const basis = new Matrix4().makeBasis(localRight, localUp, inward);\n return new Quaternion().setFromRotationMatrix(basis);\n}\n\nfunction makeInteractionEvent(\n id: string,\n position: HotspotPosition,\n event: ThreeEvent<MouseEvent | PointerEvent>,\n): HotspotInteractionEvent {\n return {\n id,\n position: normalizePanoPosition(position),\n source: \"pointer\",\n nativeEvent: event.nativeEvent,\n };\n}\n\nfunction angularDistance(a: HotspotPosition, b: HotspotPosition): number {\n const aVector = panoPositionToVector3(a);\n const bVector = panoPositionToVector3(b);\n return MathUtils.radToDeg(aVector.angleTo(bVector));\n}\n\n/** Internal spatial and interaction primitive shared by concrete hotspots. */\nexport function HotspotAnchor({\n id,\n position,\n width,\n height,\n useAngularScale = true,\n focusContent,\n mode = \"billboard\",\n distance,\n internalOrientation,\n internalPlacement,\n scaleMode = \"fov\",\n referenceFov = DEFAULT_REFERENCE_FOV,\n rotation = 0,\n renderOrder = 0,\n visible = true,\n draggable = false,\n interactive = true,\n ariaLabel,\n children,\n onClick,\n onHoverChange,\n onDragStart,\n onPositionChange,\n onDragEnd,\n}: HotspotAnchorProps) {\n const controlsRef = useContext(PanoramaControlsContext);\n const groupRef = useRef<Object3D>(null);\n const dragStateRef = useRef<DragState | null>(null);\n const suppressNextClickRef = useRef(false);\n const normalizedPosition = normalizePanoPosition(position);\n const rendering =\n internalOrientation && internalPlacement\n ? { orientation: internalOrientation, placement: internalPlacement }\n : HOTSPOT_MODE_RENDERING[mode];\n const { orientation, placement } = rendering;\n const resolvedDistance = resolveDistance(placement, distance, width, height);\n const worldPosition = useMemo(\n () => panoPositionToVector3(normalizedPosition, resolvedDistance),\n [normalizedPosition.pitch, normalizedPosition.yaw, resolvedDistance],\n );\n const surfaceQuaternion = useMemo(\n () => createSurfaceQuaternion(normalizedPosition),\n [normalizedPosition.pitch, normalizedPosition.yaw],\n );\n const worldWidth = angularSizeToWorldSize(width, resolvedDistance);\n const worldHeight = angularSizeToWorldSize(height, resolvedDistance);\n const focusGeometry = useMemo(() => {\n const planeGeometry = new PlaneGeometry(1, 1);\n const geometry = new EdgesGeometry(planeGeometry);\n planeGeometry.dispose();\n return geometry;\n }, []);\n const focused = useHotspotAccessibility({\n id,\n ariaLabel,\n onActivate: visible && interactive && onClick\n ? (event) => {\n onClick({\n id,\n position: normalizedPosition,\n source: \"keyboard\",\n nativeEvent: event,\n });\n }\n : undefined,\n });\n\n useEffect(\n () => () => {\n dragStateRef.current?.releaseInteractionLock();\n dragStateRef.current = null;\n },\n [],\n );\n\n useEffect(() => () => focusGeometry.dispose(), [focusGeometry]);\n\n useFrame(({ camera }) => {\n if (!groupRef.current) {\n return;\n }\n if (orientation === \"billboard\") {\n groupRef.current.quaternion.copy(camera.quaternion);\n } else {\n groupRef.current.quaternion.copy(surfaceQuaternion);\n }\n groupRef.current.rotateOnAxis(\n LOCAL_FORWARD,\n MathUtils.degToRad(rotation),\n );\n const scaleFactor =\n scaleMode === \"fixed\" && camera instanceof PerspectiveCamera\n ? fixedScaleFactor(camera.fov, referenceFov)\n : 1;\n groupRef.current.scale.set(\n (useAngularScale ? worldWidth : 1) * scaleFactor,\n (useAngularScale ? worldHeight : 1) * scaleFactor,\n 1,\n );\n });\n\n const stopPointerEvent = (event: ThreeEvent<MouseEvent | PointerEvent>) => {\n event.stopPropagation();\n event.nativeEvent.stopImmediatePropagation?.();\n };\n\n const releasePointer = (\n event: ThreeEvent<PointerEvent>,\n emitDragEnd: boolean,\n ) => {\n const dragState = dragStateRef.current;\n if (!dragState || dragState.pointerId !== event.pointerId) {\n return;\n }\n\n stopPointerEvent(event);\n const target = event.target as Element;\n if (target.hasPointerCapture?.(event.pointerId)) {\n target.releasePointerCapture?.(event.pointerId);\n }\n const nextPosition = vector3ToPanoPosition(event.ray.direction);\n if (emitDragEnd) {\n onDragEnd?.({\n ...makeInteractionEvent(id, nextPosition, event),\n source: \"pointer\",\n startPosition: dragState.startPosition,\n });\n }\n suppressNextClickRef.current = dragState.moved;\n dragState.releaseInteractionLock();\n dragStateRef.current = null;\n };\n\n return (\n <group\n ref={groupRef}\n position={worldPosition}\n renderOrder={renderOrder}\n scale={[worldWidth, worldHeight, 1]}\n visible={visible}\n onClick={interactive ? (event) => {\n stopPointerEvent(event);\n if (!suppressNextClickRef.current) {\n onClick?.(makeInteractionEvent(id, normalizedPosition, event));\n }\n suppressNextClickRef.current = false;\n } : undefined}\n onLostPointerCapture={interactive ? (event) => releasePointer(event, false) : undefined}\n onPointerCancel={interactive ? (event) => releasePointer(event, false) : undefined}\n onPointerDown={interactive ? (event) => {\n stopPointerEvent(event);\n if (!draggable || dragStateRef.current) {\n return;\n }\n const releaseInteractionLock =\n controlsRef?.current?.acquireInteractionLock() ?? (() => undefined);\n const target = event.target as Element;\n target.setPointerCapture?.(event.pointerId);\n const startPosition = { ...normalizedPosition };\n dragStateRef.current = {\n pointerId: event.pointerId,\n startPosition,\n releaseInteractionLock,\n moved: false,\n };\n onDragStart?.({\n ...makeInteractionEvent(id, startPosition, event),\n source: \"pointer\",\n startPosition,\n });\n } : undefined}\n onPointerMove={interactive ? (event) => {\n const dragState = dragStateRef.current;\n if (!dragState || dragState.pointerId !== event.pointerId) {\n return;\n }\n stopPointerEvent(event);\n const nextPosition = vector3ToPanoPosition(event.ray.direction);\n dragState.moved ||=\n angularDistance(dragState.startPosition, nextPosition) >\n DRAG_EPSILON_DEGREES;\n onPositionChange?.({\n ...makeInteractionEvent(id, nextPosition, event),\n source: \"pointer\",\n startPosition: dragState.startPosition,\n });\n } : undefined}\n onPointerOut={interactive ? (event) => {\n if (!dragStateRef.current) {\n onHoverChange?.(\n false,\n makeInteractionEvent(id, normalizedPosition, event),\n );\n }\n } : undefined}\n onPointerOver={interactive ? (event) => {\n if (!dragStateRef.current) {\n onHoverChange?.(\n true,\n makeInteractionEvent(id, normalizedPosition, event),\n );\n }\n } : undefined}\n onPointerUp={interactive ? (event) => releasePointer(event, true) : undefined}\n >\n {focused ? (focusContent ?? (\n <lineSegments\n geometry={focusGeometry}\n position={[0, 0, 0.01]}\n renderOrder={renderOrder + 1}\n scale={[1.12, 1.12, 1]}\n >\n <lineBasicMaterial color=\"#f5fbfc\" depthTest={false} />\n </lineSegments>\n )) : null}\n {children}\n </group>\n );\n}\n","import { useThree } from \"@react-three/fiber\";\nimport { useEffect, useMemo, useRef } from \"react\";\nimport {\n BufferGeometry,\n ColorRepresentation,\n DoubleSide,\n Float32BufferAttribute,\n Matrix4,\n Quaternion,\n ShapeUtils,\n Vector2,\n Vector3,\n} from \"three\";\nimport { Line2 } from \"three/addons/lines/Line2.js\";\nimport { LineGeometry } from \"three/addons/lines/LineGeometry.js\";\nimport { LineMaterial } from \"three/addons/lines/LineMaterial.js\";\nimport { HotspotAnchor } from \"./hotspot-anchor\";\nimport {\n clampPanoPitch,\n normalizePanoPosition,\n normalizePanoYaw,\n panoPositionToVector3,\n vector3ToPanoPosition,\n} from \"./coordinates\";\nimport type {\n HotspotCommonProps,\n HotspotDragEvent,\n HotspotInteractionEvent,\n HotspotPosition,\n} from \"./types\";\n\nconst POLYGON_RADIUS = 990;\nconst MAX_FILL_SEGMENT_DEGREES = 7;\n\nexport type PolygonValidationCode =\n | \"too_few_vertices\"\n | \"self_intersection\"\n | \"contains_pole\"\n | \"outside_hemisphere\";\n\nexport type PolygonValidationIssue = {\n code: PolygonValidationCode;\n message: string;\n};\n\nexport type PolygonVerticesChangeEvent = {\n id: string;\n vertices: HotspotPosition[];\n startVertices: HotspotPosition[];\n position: HotspotPosition;\n startPosition: HotspotPosition;\n};\n\nexport type PolygonHotspotProps = Omit<\n HotspotCommonProps,\n | \"position\"\n | \"width\"\n | \"height\"\n | \"mode\"\n | \"distance\"\n | \"scaleMode\"\n | \"onDragStart\"\n | \"onPositionChange\"\n | \"onDragEnd\"\n> & {\n vertices: HotspotPosition[];\n fill?: ColorRepresentation;\n fillOpacity?: number;\n stroke?: ColorRepresentation;\n /** Screen-space border width in CSS pixels. Defaults to 2. */\n strokeWidth?: number;\n /** Opacity of the polygon boundary, from 0 to 1. Defaults to 1. */\n strokeOpacity?: number;\n onVerticesChange?: (event: PolygonVerticesChangeEvent) => void;\n onDragStart?: (event: PolygonVerticesChangeEvent) => void;\n onDragEnd?: (event: PolygonVerticesChangeEvent) => void;\n onInvalid?: (issues: PolygonValidationIssue[]) => void;\n};\n\ntype UnwrappedVertex = HotspotPosition & { unwrappedYaw: number };\n\nfunction cloneVertices(vertices: HotspotPosition[]): HotspotPosition[] {\n return vertices.map((vertex) => normalizePanoPosition(vertex));\n}\n\nexport function unwrapPolygonVertices(\n vertices: HotspotPosition[],\n): UnwrappedVertex[] {\n const unwrapped: UnwrappedVertex[] = [];\n for (const vertex of vertices) {\n const normalized = normalizePanoPosition(vertex);\n const previous = unwrapped[unwrapped.length - 1];\n if (!previous) {\n unwrapped.push({ ...normalized, unwrappedYaw: normalized.yaw });\n continue;\n }\n const previousYaw = previous.unwrappedYaw;\n let yaw = normalized.yaw;\n while (yaw - previousYaw > 180) yaw -= 360;\n while (yaw - previousYaw <= -180) yaw += 360;\n unwrapped.push({ ...normalized, unwrappedYaw: yaw });\n }\n return unwrapped;\n}\n\nfunction orientation(a: Vector2, b: Vector2, c: Vector2): number {\n return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);\n}\n\nfunction intersects(a: Vector2, b: Vector2, c: Vector2, d: Vector2): boolean {\n const abC = orientation(a, b, c);\n const abD = orientation(a, b, d);\n const cdA = orientation(c, d, a);\n const cdB = orientation(c, d, b);\n return (\n Math.sign(abC) !== Math.sign(abD) &&\n Math.sign(cdA) !== Math.sign(cdB)\n );\n}\n\nfunction hasSelfIntersection(vertices: UnwrappedVertex[]): boolean {\n const points = vertices.map((vertex) =>\n new Vector2(vertex.unwrappedYaw, vertex.pitch),\n );\n for (let index = 0; index < points.length; index += 1) {\n const nextIndex = (index + 1) % points.length;\n for (let other = index + 1; other < points.length; other += 1) {\n const otherNext = (other + 1) % points.length;\n if (\n index === other ||\n nextIndex === other ||\n otherNext === index ||\n (index === 0 && otherNext === 0)\n ) {\n continue;\n }\n if (intersects(points[index]!, points[nextIndex]!, points[other]!, points[otherNext]!)) {\n return true;\n }\n }\n }\n return false;\n}\n\nfunction polygonContainsDirection(\n vertices: HotspotPosition[],\n direction: Vector3,\n): boolean {\n let winding = 0;\n for (let index = 0; index < vertices.length; index += 1) {\n const a = panoPositionToVector3(vertices[index]!).normalize();\n const b = panoPositionToVector3(vertices[(index + 1) % vertices.length]!).normalize();\n const projectedA = a.clone().addScaledVector(direction, -a.dot(direction));\n const projectedB = b.clone().addScaledVector(direction, -b.dot(direction));\n if (projectedA.lengthSq() < 1e-8 || projectedB.lengthSq() < 1e-8) {\n return false;\n }\n projectedA.normalize();\n projectedB.normalize();\n winding += Math.atan2(\n direction.dot(projectedA.clone().cross(projectedB)),\n projectedA.dot(projectedB),\n );\n }\n return Math.abs(winding) > Math.PI;\n}\n\nfunction fitsHemisphere(vertices: HotspotPosition[]): boolean {\n const directions = vertices.map((vertex) => panoPositionToVector3(vertex).normalize());\n const candidates = [new Vector3()];\n for (const direction of directions) {\n candidates[0]!.add(direction);\n candidates.push(direction.clone());\n }\n for (let index = 0; index < directions.length; index += 1) {\n for (let other = index + 1; other < directions.length; other += 1) {\n candidates.push(directions[index]!.clone().add(directions[other]!));\n }\n }\n return candidates.some((candidate) =>\n candidate.lengthSq() > 1e-8 &&\n directions.every((direction) => candidate.dot(direction) > 1e-6),\n );\n}\n\nexport function validatePolygonVertices(\n vertices: HotspotPosition[],\n): PolygonValidationIssue[] {\n if (vertices.length < 3) {\n return [{ code: \"too_few_vertices\", message: \"A polygon needs at least three vertices.\" }];\n }\n const normalized = cloneVertices(vertices);\n const unwrapped = unwrapPolygonVertices(normalized);\n const issues: PolygonValidationIssue[] = [];\n if (hasSelfIntersection(unwrapped)) {\n issues.push({ code: \"self_intersection\", message: \"Polygon edges cannot cross.\" });\n }\n if (\n polygonContainsDirection(normalized, new Vector3(0, 1, 0)) ||\n polygonContainsDirection(normalized, new Vector3(0, -1, 0))\n ) {\n issues.push({ code: \"contains_pole\", message: \"Polygons cannot contain a panorama pole.\" });\n }\n if (!fitsHemisphere(normalized)) {\n issues.push({ code: \"outside_hemisphere\", message: \"Polygons must fit within one hemisphere.\" });\n }\n return issues;\n}\n\nfunction polygonCenter(vertices: HotspotPosition[]): HotspotPosition {\n const sum = vertices.reduce(\n (total, vertex) => total.add(panoPositionToVector3(vertex).normalize()),\n new Vector3(),\n );\n return sum.lengthSq() > 1e-8\n ? vector3ToPanoPosition(sum)\n : normalizePanoPosition(vertices[0]!);\n}\n\nfunction surfaceQuaternion(position: HotspotPosition): Quaternion {\n const outward = panoPositionToVector3(position).normalize();\n const inward = outward.clone().negate();\n const pitch = (position.pitch * Math.PI) / 180;\n const yaw = (position.yaw * Math.PI) / 180;\n const localUp = new Vector3(\n -Math.sin(pitch) * Math.sin(yaw),\n Math.cos(pitch),\n Math.sin(pitch) * Math.cos(yaw),\n ).normalize();\n return new Quaternion().setFromRotationMatrix(\n new Matrix4().makeBasis(localUp.clone().cross(inward).normalize(), localUp, inward),\n );\n}\n\nfunction makeWorldToLocal(center: HotspotPosition): Matrix4 {\n return new Matrix4()\n .compose(\n panoPositionToVector3(center, POLYGON_RADIUS),\n surfaceQuaternion(center),\n new Vector3(1, 1, 1),\n )\n .invert();\n}\n\nfunction projectedPoint(\n a: UnwrappedVertex,\n b: UnwrappedVertex,\n c: UnwrappedVertex,\n weightB: number,\n weightC: number,\n radius: number,\n worldToLocal: Matrix4,\n): Vector3 {\n const weightA = 1 - weightB - weightC;\n return panoPositionToVector3(\n {\n yaw: a.unwrappedYaw * weightA + b.unwrappedYaw * weightB + c.unwrappedYaw * weightC,\n pitch: a.pitch * weightA + b.pitch * weightB + c.pitch * weightC,\n },\n radius,\n ).applyMatrix4(worldToLocal);\n}\n\nfunction polygonSubdivisionSteps(vertices: HotspotPosition[]): number {\n let maxAngle = 0;\n for (let index = 0; index < vertices.length; index += 1) {\n const start = panoPositionToVector3(vertices[index]!).normalize();\n for (let other = index + 1; other < vertices.length; other += 1) {\n maxAngle = Math.max(\n maxAngle,\n start.angleTo(panoPositionToVector3(vertices[other]!).normalize()),\n );\n }\n }\n return Math.min(\n 8,\n Math.max(1, Math.ceil((maxAngle * 180) / Math.PI / MAX_FILL_SEGMENT_DEGREES)),\n );\n}\n\nfunction addSubdividedTriangle(\n positions: number[],\n indices: number[],\n a: UnwrappedVertex,\n b: UnwrappedVertex,\n c: UnwrappedVertex,\n worldToLocal: Matrix4,\n steps: number,\n): void {\n const grid = new Map<string, number>();\n const pointIndex = (i: number, j: number) => {\n const key = `${i}:${j}`;\n const existing = grid.get(key);\n if (existing !== undefined) return existing;\n const point = projectedPoint(a, b, c, i / steps, j / steps, POLYGON_RADIUS, worldToLocal);\n const index = positions.length / 3;\n positions.push(point.x, point.y, point.z);\n grid.set(key, index);\n return index;\n };\n for (let i = 0; i <= steps; i += 1) {\n for (let j = 0; j <= steps - i; j += 1) pointIndex(i, j);\n }\n for (let i = 0; i < steps; i += 1) {\n for (let j = 0; j < steps - i; j += 1) {\n indices.push(pointIndex(i, j), pointIndex(i + 1, j), pointIndex(i, j + 1));\n if (i + j < steps - 1) {\n indices.push(pointIndex(i + 1, j), pointIndex(i + 1, j + 1), pointIndex(i, j + 1));\n }\n }\n }\n}\n\nfunction makeFillGeometry(vertices: HotspotPosition[], center: HotspotPosition): BufferGeometry {\n const unwrapped = unwrapPolygonVertices(vertices);\n const contour = unwrapped.map((vertex) => new Vector2(vertex.unwrappedYaw, vertex.pitch));\n const triangles = ShapeUtils.triangulateShape(contour, []);\n const positions: number[] = [];\n const indices: number[] = [];\n const worldToLocal = makeWorldToLocal(center);\n const steps = polygonSubdivisionSteps(vertices);\n for (const [a, b, c] of triangles) {\n addSubdividedTriangle(\n positions,\n indices,\n unwrapped[a]!,\n unwrapped[b]!,\n unwrapped[c]!,\n worldToLocal,\n steps,\n );\n }\n return new BufferGeometry()\n .setAttribute(\"position\", new Float32BufferAttribute(positions, 3))\n .setIndex(indices);\n}\n\nfunction makeStrokePositions(\n vertices: HotspotPosition[],\n center: HotspotPosition,\n): number[] {\n const positions: number[] = [];\n const worldToLocal = makeWorldToLocal(center);\n const unwrapped = unwrapPolygonVertices(vertices);\n const steps = polygonSubdivisionSteps(vertices);\n\n for (let edge = 0; edge < unwrapped.length; edge += 1) {\n const start = unwrapped[edge]!;\n const end = unwrapped[(edge + 1) % unwrapped.length]!;\n\n // This is intentionally the same yaw/pitch interpolation and segment\n // density used by the fill geometry. The outline therefore sits directly\n // on its outer boundary instead of following a different great-circle arc.\n for (let step = 0; step < steps; step += 1) {\n const progress = step / steps;\n const point = panoPositionToVector3(\n {\n yaw: start.unwrappedYaw + (end.unwrappedYaw - start.unwrappedYaw) * progress,\n pitch: start.pitch + (end.pitch - start.pitch) * progress,\n },\n POLYGON_RADIUS,\n )\n .applyMatrix4(worldToLocal);\n positions.push(point.x, point.y, point.z);\n }\n }\n positions.push(...positions.slice(0, 3));\n return positions;\n}\n\nfunction makeStrokeLine(\n positions: number[],\n color: ColorRepresentation,\n width: number,\n opacity: number,\n): Line2 {\n const geometry = new LineGeometry();\n geometry.setPositions(positions);\n const material = new LineMaterial({\n color,\n depthTest: true,\n depthWrite: false,\n linewidth: Math.max(0.5, width),\n opacity,\n transparent: true,\n worldUnits: false,\n alphaToCoverage: true,\n });\n const line = new Line2(geometry, material);\n line.computeLineDistances();\n return line;\n}\n\nfunction disposeStrokeLine(line: Line2 | null): void {\n if (!line) return;\n line.geometry.dispose();\n (line.material as LineMaterial).dispose();\n}\n\nfunction translateVertices(\n vertices: HotspotPosition[],\n from: HotspotPosition,\n to: HotspotPosition,\n): HotspotPosition[] {\n const yawOffset = normalizePanoYaw(to.yaw - from.yaw);\n const pitchOffset = to.pitch - from.pitch;\n return vertices.map((vertex) => ({\n yaw: normalizePanoYaw(vertex.yaw + yawOffset),\n pitch: clampPanoPitch(vertex.pitch + pitchOffset),\n }));\n}\n\nexport function PolygonHotspot({\n id,\n vertices,\n fill = \"#df6b42\",\n fillOpacity = 0.34,\n stroke = \"#f5fbfc\",\n strokeWidth = 2,\n strokeOpacity = 1,\n interactive = true,\n renderOrder = 10,\n draggable = false,\n onVerticesChange,\n onDragStart,\n onDragEnd,\n onInvalid,\n ...anchorProps\n}: PolygonHotspotProps) {\n const gl = useThree((state) => state.gl);\n const size = useThree((state) => state.size);\n const issues = useMemo(() => validatePolygonVertices(vertices), [vertices]);\n const valid = issues.length === 0;\n const center = useMemo(() => valid ? polygonCenter(vertices) : null, [valid, vertices]);\n const fillGeometry = useMemo(\n () => valid && center ? makeFillGeometry(vertices, center) : null,\n [center, valid, vertices],\n );\n const strokePositions = useMemo(\n () => valid && center ? makeStrokePositions(vertices, center) : null,\n [center, valid, vertices],\n );\n const resolvedStrokeOpacity = Math.max(0, Math.min(strokeOpacity, 1));\n const devicePixelRatio = gl.getPixelRatio();\n const strokeLine = useMemo(\n () => strokePositions\n ? makeStrokeLine(strokePositions, stroke, strokeWidth * devicePixelRatio, resolvedStrokeOpacity)\n : null,\n [devicePixelRatio, resolvedStrokeOpacity, stroke, strokePositions, strokeWidth],\n );\n const focusStrokeLine = useMemo(\n () => strokePositions\n ? makeStrokeLine(strokePositions, \"#75cbd3\", (strokeWidth + 2) * devicePixelRatio, 1)\n : null,\n [devicePixelRatio, strokePositions, strokeWidth],\n );\n const startVerticesRef = useRef<HotspotPosition[] | null>(null);\n const issuesKey = issues.map((issue) => issue.code).join(\",\");\n\n useEffect(() => {\n if (!valid) onInvalid?.(issues);\n }, [issues, issuesKey, onInvalid, valid]);\n useEffect(() => () => fillGeometry?.dispose(), [fillGeometry]);\n useEffect(() => () => disposeStrokeLine(strokeLine), [strokeLine]);\n useEffect(() => () => disposeStrokeLine(focusStrokeLine), [focusStrokeLine]);\n useEffect(() => {\n const width = gl.domElement.width;\n const height = gl.domElement.height;\n for (const line of [strokeLine, focusStrokeLine]) {\n if (line) (line.material as LineMaterial).resolution.set(width, height);\n }\n }, [focusStrokeLine, gl, size.height, size.width, strokeLine]);\n\n if (!valid || !center || !fillGeometry || !strokeLine || !focusStrokeLine) return null;\n\n const emitVerticesChange = (event: HotspotDragEvent, callback?: (event: PolygonVerticesChangeEvent) => void) => {\n const startVertices = startVerticesRef.current ?? cloneVertices(vertices);\n const nextVertices = translateVertices(startVertices, event.startPosition, event.position);\n callback?.({\n id,\n vertices: nextVertices,\n startVertices,\n position: event.position,\n startPosition: event.startPosition,\n });\n };\n\n return (\n <HotspotAnchor\n {...anchorProps}\n id={id}\n position={center}\n width={1}\n height={1}\n internalPlacement=\"floating\"\n distance={POLYGON_RADIUS}\n internalOrientation=\"surface\"\n renderOrder={renderOrder}\n draggable={draggable}\n interactive={interactive}\n useAngularScale={false}\n focusContent={\n <primitive object={focusStrokeLine} renderOrder={renderOrder + 2} />\n }\n onDragStart={(event) => {\n startVerticesRef.current = cloneVertices(vertices);\n emitVerticesChange(event, onDragStart);\n }}\n onPositionChange={(event) => emitVerticesChange(event, onVerticesChange)}\n onDragEnd={(event) => {\n emitVerticesChange(event, onDragEnd);\n startVerticesRef.current = null;\n }}\n >\n <mesh geometry={fillGeometry} renderOrder={renderOrder}>\n <meshBasicMaterial\n color={fill}\n depthWrite={false}\n opacity={Math.max(0, Math.min(fillOpacity, 1))}\n side={DoubleSide}\n transparent\n />\n </mesh>\n <primitive object={strokeLine} renderOrder={renderOrder + 1} />\n </HotspotAnchor>\n );\n}\n","import { useThree } from \"@react-three/fiber\";\nimport { useEffect, useMemo, useRef } from \"react\";\nimport {\n ColorRepresentation,\n MathUtils,\n Matrix4,\n Quaternion,\n Vector3,\n} from \"three\";\nimport { Line2 } from \"three/addons/lines/Line2.js\";\nimport { LineGeometry } from \"three/addons/lines/LineGeometry.js\";\nimport { LineMaterial } from \"three/addons/lines/LineMaterial.js\";\nimport { HotspotAnchor } from \"./hotspot-anchor\";\nimport {\n clampPanoPitch,\n normalizePanoPosition,\n normalizePanoYaw,\n panoPositionToVector3,\n vector3ToPanoPosition,\n} from \"./coordinates\";\nimport type {\n HotspotCommonProps,\n HotspotDragEvent,\n HotspotPosition,\n} from \"./types\";\n\nconst POLYLINE_RADIUS = 990;\nconst MAX_SEGMENT_DEGREES = 7;\n\nexport type PolylineValidationIssue = {\n code: \"too_few_vertices\";\n message: string;\n};\n\nexport type PolylineVerticesChangeEvent = {\n id: string;\n vertices: HotspotPosition[];\n startVertices: HotspotPosition[];\n position: HotspotPosition;\n startPosition: HotspotPosition;\n};\n\nexport type PolylineHotspotProps = Omit<\n HotspotCommonProps,\n | \"position\"\n | \"width\"\n | \"height\"\n | \"mode\"\n | \"distance\"\n | \"scaleMode\"\n | \"onDragStart\"\n | \"onPositionChange\"\n | \"onDragEnd\"\n> & {\n vertices: HotspotPosition[];\n stroke?: ColorRepresentation;\n /** Screen-space line width in CSS pixels. Defaults to 2. */\n strokeWidth?: number;\n strokeOpacity?: number;\n onVerticesChange?: (event: PolylineVerticesChangeEvent) => void;\n onDragStart?: (event: PolylineVerticesChangeEvent) => void;\n onDragEnd?: (event: PolylineVerticesChangeEvent) => void;\n onInvalid?: (issues: PolylineValidationIssue[]) => void;\n};\n\ntype UnwrappedVertex = HotspotPosition & { unwrappedYaw: number };\n\nfunction cloneVertices(vertices: HotspotPosition[]): HotspotPosition[] {\n return vertices.map((vertex) => normalizePanoPosition(vertex));\n}\n\nfunction unwrapVertices(vertices: HotspotPosition[]): UnwrappedVertex[] {\n const unwrapped: UnwrappedVertex[] = [];\n for (const vertex of vertices) {\n const normalized = normalizePanoPosition(vertex);\n const previous = unwrapped[unwrapped.length - 1];\n if (!previous) {\n unwrapped.push({ ...normalized, unwrappedYaw: normalized.yaw });\n continue;\n }\n let yaw = normalized.yaw;\n while (yaw - previous.unwrappedYaw > 180) yaw -= 360;\n while (yaw - previous.unwrappedYaw <= -180) yaw += 360;\n unwrapped.push({ ...normalized, unwrappedYaw: yaw });\n }\n return unwrapped;\n}\n\nfunction polylineCenter(vertices: HotspotPosition[]): HotspotPosition {\n const sum = vertices.reduce(\n (total, vertex) => total.add(panoPositionToVector3(vertex).normalize()),\n new Vector3(),\n );\n return sum.lengthSq() > 1e-8\n ? vector3ToPanoPosition(sum)\n : normalizePanoPosition(vertices[0]!);\n}\n\nfunction surfaceQuaternion(position: HotspotPosition): Quaternion {\n const outward = panoPositionToVector3(position).normalize();\n const inward = outward.clone().negate();\n const pitch = MathUtils.degToRad(position.pitch);\n const yaw = MathUtils.degToRad(position.yaw);\n const localUp = new Vector3(\n -Math.sin(pitch) * Math.sin(yaw),\n Math.cos(pitch),\n Math.sin(pitch) * Math.cos(yaw),\n ).normalize();\n return new Quaternion().setFromRotationMatrix(\n new Matrix4().makeBasis(localUp.clone().cross(inward).normalize(), localUp, inward),\n );\n}\n\nfunction makeWorldToLocal(center: HotspotPosition): Matrix4 {\n return new Matrix4()\n .compose(\n panoPositionToVector3(center, POLYLINE_RADIUS),\n surfaceQuaternion(center),\n new Vector3(1, 1, 1),\n )\n .invert();\n}\n\nfunction subdivisionSteps(vertices: HotspotPosition[]): number {\n let maxAngle = 0;\n for (let index = 0; index < vertices.length - 1; index += 1) {\n maxAngle = Math.max(\n maxAngle,\n panoPositionToVector3(vertices[index]!).angleTo(\n panoPositionToVector3(vertices[index + 1]!),\n ),\n );\n }\n return Math.min(\n 8,\n Math.max(1, Math.ceil((MathUtils.radToDeg(maxAngle)) / MAX_SEGMENT_DEGREES)),\n );\n}\n\nfunction makeLinePositions(vertices: HotspotPosition[], center: HotspotPosition): number[] {\n const positions: number[] = [];\n const worldToLocal = makeWorldToLocal(center);\n const unwrapped = unwrapVertices(vertices);\n const steps = subdivisionSteps(vertices);\n\n for (let edge = 0; edge < unwrapped.length - 1; edge += 1) {\n const start = unwrapped[edge]!;\n const end = unwrapped[edge + 1]!;\n for (let step = 0; step < steps; step += 1) {\n const progress = step / steps;\n const point = panoPositionToVector3(\n {\n yaw: start.unwrappedYaw + (end.unwrappedYaw - start.unwrappedYaw) * progress,\n pitch: start.pitch + (end.pitch - start.pitch) * progress,\n },\n POLYLINE_RADIUS,\n ).applyMatrix4(worldToLocal);\n positions.push(point.x, point.y, point.z);\n }\n }\n\n const last = unwrapped[unwrapped.length - 1]!;\n const lastPoint = panoPositionToVector3(last, POLYLINE_RADIUS).applyMatrix4(worldToLocal);\n positions.push(lastPoint.x, lastPoint.y, lastPoint.z);\n return positions;\n}\n\nfunction makeLine(\n positions: number[],\n color: ColorRepresentation,\n width: number,\n opacity: number,\n): Line2 {\n const geometry = new LineGeometry();\n geometry.setPositions(positions);\n const material = new LineMaterial({\n color,\n depthTest: true,\n depthWrite: false,\n linewidth: Math.max(0.5, width),\n opacity,\n transparent: true,\n worldUnits: false,\n alphaToCoverage: true,\n });\n const line = new Line2(geometry, material);\n line.computeLineDistances();\n return line;\n}\n\nfunction disposeLine(line: Line2 | null): void {\n if (!line) return;\n line.geometry.dispose();\n (line.material as LineMaterial).dispose();\n}\n\nfunction translateVertices(\n vertices: HotspotPosition[],\n from: HotspotPosition,\n to: HotspotPosition,\n): HotspotPosition[] {\n const yawOffset = normalizePanoYaw(to.yaw - from.yaw);\n const pitchOffset = to.pitch - from.pitch;\n return vertices.map((vertex) => ({\n yaw: normalizePanoYaw(vertex.yaw + yawOffset),\n pitch: clampPanoPitch(vertex.pitch + pitchOffset),\n }));\n}\n\nexport function validatePolylineVertices(\n vertices: HotspotPosition[],\n): PolylineValidationIssue[] {\n return vertices.length < 2\n ? [{ code: \"too_few_vertices\", message: \"A polyline needs at least two vertices.\" }]\n : [];\n}\n\nexport function PolylineHotspot({\n id,\n vertices,\n stroke = \"#f5fbfc\",\n strokeWidth = 2,\n strokeOpacity = 1,\n renderOrder = 10,\n draggable = false,\n onVerticesChange,\n onDragStart,\n onDragEnd,\n onInvalid,\n ...anchorProps\n}: PolylineHotspotProps) {\n const gl = useThree((state) => state.gl);\n const size = useThree((state) => state.size);\n const issues = useMemo(() => validatePolylineVertices(vertices), [vertices]);\n const valid = issues.length === 0;\n const center = useMemo(() => valid ? polylineCenter(vertices) : null, [valid, vertices]);\n const linePositions = useMemo(\n () => valid && center ? makeLinePositions(vertices, center) : null,\n [center, valid, vertices],\n );\n const devicePixelRatio = gl.getPixelRatio();\n const opacity = Math.max(0, Math.min(strokeOpacity, 1));\n const line = useMemo(\n () => linePositions ? makeLine(linePositions, stroke, strokeWidth * devicePixelRatio, opacity) : null,\n [devicePixelRatio, linePositions, opacity, stroke, strokeWidth],\n );\n const focusLine = useMemo(\n () => linePositions ? makeLine(linePositions, \"#75cbd3\", (strokeWidth + 2) * devicePixelRatio, 1) : null,\n [devicePixelRatio, linePositions, strokeWidth],\n );\n const startVerticesRef = useRef<HotspotPosition[] | null>(null);\n\n useEffect(() => {\n if (!valid) onInvalid?.(issues);\n }, [issues, onInvalid, valid]);\n useEffect(() => () => disposeLine(line), [line]);\n useEffect(() => () => disposeLine(focusLine), [focusLine]);\n useEffect(() => {\n const width = gl.domElement.width;\n const height = gl.domElement.height;\n for (const nextLine of [line, focusLine]) {\n if (nextLine) (nextLine.material as LineMaterial).resolution.set(width, height);\n }\n }, [focusLine, gl, line, size.height, size.width]);\n\n if (!valid || !center || !line || !focusLine) return null;\n\n const emitVerticesChange = (\n event: HotspotDragEvent,\n callback?: (event: PolylineVerticesChangeEvent) => void,\n ) => {\n const startVertices = startVerticesRef.current ?? cloneVertices(vertices);\n callback?.({\n id,\n vertices: translateVertices(startVertices, event.startPosition, event.position),\n startVertices,\n position: event.position,\n startPosition: event.startPosition,\n });\n };\n\n return (\n <HotspotAnchor\n {...anchorProps}\n id={id}\n position={center}\n width={1}\n height={1}\n internalPlacement=\"floating\"\n distance={POLYLINE_RADIUS}\n internalOrientation=\"surface\"\n renderOrder={renderOrder}\n draggable={draggable}\n useAngularScale={false}\n focusContent={<primitive object={focusLine} renderOrder={renderOrder + 2} />}\n onDragStart={(event) => {\n startVerticesRef.current = cloneVertices(vertices);\n emitVerticesChange(event, onDragStart);\n }}\n onPositionChange={(event) => emitVerticesChange(event, onVerticesChange)}\n onDragEnd={(event) => {\n emitVerticesChange(event, onDragEnd);\n startVerticesRef.current = null;\n }}\n >\n <primitive object={line} renderOrder={renderOrder + 1} />\n </HotspotAnchor>\n );\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport {\n CanvasTexture,\n ClampToEdgeWrapping,\n DoubleSide,\n LinearFilter,\n LinearMipmapLinearFilter,\n SRGBColorSpace,\n Texture,\n} from \"three\";\nimport { HotspotAnchor } from \"./hotspot-anchor\";\nimport { ImageHotspot } from \"./image-hotspot\";\nimport type { HotspotCommonProps } from \"./types\";\n\nconst GRAPHIC_TEXTURE_SIZE = 512;\n\ntype GraphicPaint = {\n fill?: string;\n stroke?: string;\n strokeWidth?: number;\n};\n\nexport type CircleGraphic = GraphicPaint & {\n kind: \"circle\";\n};\n\nexport type RectangleGraphic = GraphicPaint & {\n kind: \"rectangle\";\n cornerRadius?: number;\n};\n\nexport type RingGraphic = GraphicPaint & {\n kind: \"ring\";\n innerRadius?: number;\n};\n\nexport type SvgGraphic = {\n kind: \"svg\";\n src: string;\n};\n\nexport type SvgPathGraphic = GraphicPaint & {\n kind: \"path\";\n path: string;\n viewBox: [x: number, y: number, width: number, height: number];\n};\n\nexport type GraphicDefinition =\n | CircleGraphic\n | RectangleGraphic\n | RingGraphic\n | SvgGraphic\n | SvgPathGraphic;\n\nexport type GraphicHotspotProps = HotspotCommonProps & {\n graphic: GraphicDefinition;\n onLoad?: (texture: Texture) => void;\n onError?: (error: unknown) => void;\n};\n\nfunction clampOpacity(opacity: number | undefined): number {\n if (!Number.isFinite(opacity)) {\n return 1;\n }\n return Math.max(0, Math.min(opacity!, 1));\n}\n\nfunction resolveStrokeWidth(value: number | undefined): number {\n return Number.isFinite(value) ? Math.max(value!, 0) : 8;\n}\n\nfunction roundedRectanglePath(\n context: CanvasRenderingContext2D,\n x: number,\n y: number,\n width: number,\n height: number,\n radius: number,\n) {\n const safeRadius = Math.min(Math.max(radius, 0), width / 2, height / 2);\n context.beginPath();\n context.moveTo(x + safeRadius, y);\n context.arcTo(x + width, y, x + width, y + height, safeRadius);\n context.arcTo(x + width, y + height, x, y + height, safeRadius);\n context.arcTo(x, y + height, x, y, safeRadius);\n context.arcTo(x, y, x + width, y, safeRadius);\n context.closePath();\n}\n\nfunction paintPath(\n context: CanvasRenderingContext2D,\n graphic: GraphicPaint,\n path?: Path2D,\n) {\n if (graphic.fill) {\n context.fillStyle = graphic.fill;\n path ? context.fill(path) : context.fill();\n }\n if (graphic.stroke) {\n context.strokeStyle = graphic.stroke;\n context.lineWidth = resolveStrokeWidth(graphic.strokeWidth);\n path ? context.stroke(path) : context.stroke();\n }\n}\n\nfunction drawGraphic(\n context: CanvasRenderingContext2D,\n graphic: Exclude<GraphicDefinition, SvgGraphic>,\n) {\n const padding = Math.max(resolveStrokeWidth(graphic.strokeWidth) / 2 + 2, 4);\n const drawableSize = GRAPHIC_TEXTURE_SIZE - padding * 2;\n\n context.clearRect(0, 0, GRAPHIC_TEXTURE_SIZE, GRAPHIC_TEXTURE_SIZE);\n context.lineJoin = \"round\";\n context.lineCap = \"round\";\n\n if (graphic.kind === \"circle\") {\n context.beginPath();\n context.arc(\n GRAPHIC_TEXTURE_SIZE / 2,\n GRAPHIC_TEXTURE_SIZE / 2,\n drawableSize / 2,\n 0,\n Math.PI * 2,\n );\n paintPath(context, graphic);\n return;\n }\n\n if (graphic.kind === \"rectangle\") {\n roundedRectanglePath(\n context,\n padding,\n padding,\n drawableSize,\n drawableSize,\n graphic.cornerRadius ?? 0,\n );\n paintPath(context, graphic);\n return;\n }\n\n if (graphic.kind === \"ring\") {\n const center = GRAPHIC_TEXTURE_SIZE / 2;\n const outerRadius = drawableSize / 2;\n const innerRadius = Math.max(\n 0,\n Math.min(outerRadius - 1, (graphic.innerRadius ?? 0.58) * outerRadius),\n );\n context.beginPath();\n context.arc(center, center, outerRadius, 0, Math.PI * 2);\n context.moveTo(center + innerRadius, center);\n context.arc(center, center, innerRadius, 0, Math.PI * 2, true);\n if (graphic.fill ?? graphic.stroke) {\n context.fillStyle = graphic.fill ?? graphic.stroke ?? \"#ffffff\";\n context.fill(\"evenodd\");\n }\n if (graphic.stroke) {\n context.strokeStyle = graphic.stroke;\n context.lineWidth = resolveStrokeWidth(graphic.strokeWidth);\n context.stroke();\n }\n return;\n }\n\n const [x, y, width, height] = graphic.viewBox;\n if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) {\n throw new Error(\"SVG path viewBox must have a positive width and height.\");\n }\n const path = new Path2D(graphic.path);\n context.save();\n context.translate(padding, padding);\n context.scale(drawableSize / width, drawableSize / height);\n context.translate(-x, -y);\n paintPath(context, graphic, path);\n context.restore();\n}\n\nfunction createGraphicTexture(\n graphic: Exclude<GraphicDefinition, SvgGraphic>,\n): CanvasTexture {\n const canvas = document.createElement(\"canvas\");\n canvas.width = GRAPHIC_TEXTURE_SIZE;\n canvas.height = GRAPHIC_TEXTURE_SIZE;\n const context = canvas.getContext(\"2d\");\n if (!context) {\n throw new Error(\"Canvas 2D is unavailable for this graphic hotspot.\");\n }\n drawGraphic(context, graphic);\n\n const texture = new CanvasTexture(canvas);\n texture.colorSpace = SRGBColorSpace;\n texture.wrapS = ClampToEdgeWrapping;\n texture.wrapT = ClampToEdgeWrapping;\n texture.magFilter = LinearFilter;\n texture.minFilter = LinearMipmapLinearFilter;\n texture.generateMipmaps = true;\n texture.needsUpdate = true;\n return texture;\n}\n\nfunction useGraphicTexture(\n graphic: Exclude<GraphicDefinition, SvgGraphic>,\n onLoad: GraphicHotspotProps[\"onLoad\"],\n onError: GraphicHotspotProps[\"onError\"],\n) {\n const [texture, setTexture] = useState<CanvasTexture | null>(null);\n const onLoadRef = useRef(onLoad);\n const onErrorRef = useRef(onError);\n onLoadRef.current = onLoad;\n onErrorRef.current = onError;\n\n useEffect(() => {\n let nextTexture: CanvasTexture | null = null;\n try {\n nextTexture = createGraphicTexture(graphic);\n setTexture(nextTexture);\n onLoadRef.current?.(nextTexture);\n } catch (error) {\n setTexture(null);\n onErrorRef.current?.(error);\n }\n\n return () => {\n nextTexture?.dispose();\n };\n }, [graphic]);\n\n return texture;\n}\n\nfunction CanvasGraphicHotspot({\n graphic,\n width = 10,\n height = 10,\n opacity,\n onLoad,\n onError,\n ...anchorProps\n}: GraphicHotspotProps & { graphic: Exclude<GraphicDefinition, SvgGraphic> }) {\n const texture = useGraphicTexture(graphic, onLoad, onError);\n\n return (\n <HotspotAnchor {...anchorProps} height={height} width={width}>\n <mesh>\n <planeGeometry args={[1, 1]} />\n <meshBasicMaterial\n map={texture}\n opacity={texture ? clampOpacity(opacity) : 0}\n side={DoubleSide}\n toneMapped={false}\n transparent\n />\n </mesh>\n </HotspotAnchor>\n );\n}\n\nexport function GraphicHotspot(props: GraphicHotspotProps) {\n const { graphic, ...restProps } = props;\n if (graphic.kind === \"svg\") {\n const imageProps = restProps;\n return <ImageHotspot {...imageProps} src={graphic.src} />;\n }\n\n return <CanvasGraphicHotspot {...restProps} graphic={graphic} />;\n}\n","import { useFrame, useThree } from \"@react-three/fiber\";\nimport { useEffect, useRef, useState } from \"react\";\nimport {\n ClampToEdgeWrapping,\n DoubleSide,\n LinearFilter,\n LinearMipmapLinearFilter,\n SRGBColorSpace,\n Texture,\n TextureLoader,\n} from \"three\";\nimport { HotspotAnchor } from \"./hotspot-anchor\";\nimport type { HotspotCommonProps } from \"./types\";\n\nconst DEFAULT_SEQUENCE_FPS = 12;\n\nexport type SequenceFrameDirection = \"horizontal\" | \"vertical\";\n\nexport type SequenceLoadProgress = {\n id: string;\n total: number;\n loaded: number;\n failed: number;\n};\n\nexport type SequenceFrameEvent = {\n id: string;\n index: number;\n src: string;\n};\n\nexport type SequencePlaybackState = \"playing\" | \"paused\" | \"ended\";\n\nexport type SequenceHotspotErrorEvent = {\n id: string;\n src: string;\n error: unknown;\n};\n\nexport type SequenceHotspotProps = HotspotCommonProps & {\n /** A sprite sheet containing each frame in equally sized cells. */\n src: string;\n /** Number of cells in the sprite sheet, from left-to-right or top-to-bottom. */\n frameCount: number;\n frameDirection?: SequenceFrameDirection;\n playing: boolean;\n fps?: number;\n loop?: boolean;\n onFrameChange?: (event: SequenceFrameEvent) => void;\n onLoadProgress?: (progress: SequenceLoadProgress) => void;\n onPlaybackStateChange?: (state: SequencePlaybackState) => void;\n onEnded?: () => void;\n onError?: (event: SequenceHotspotErrorEvent) => void;\n};\n\nfunction clampOpacity(opacity: number | undefined): number {\n if (!Number.isFinite(opacity)) {\n return 1;\n }\n return Math.max(0, Math.min(opacity!, 1));\n}\n\nfunction resolveFps(value: number | undefined): number {\n return Number.isFinite(value) && value! > 0 ? value! : DEFAULT_SEQUENCE_FPS;\n}\n\nfunction resolveFrameCount(value: number): number {\n return Number.isFinite(value) ? Math.max(1, Math.floor(value)) : 1;\n}\n\nfunction useSpriteTexture({\n id,\n src,\n onError,\n onLoadProgress,\n}: Pick<SequenceHotspotProps, \"id\" | \"src\" | \"onError\" | \"onLoadProgress\">) {\n const gl = useThree((state) => state.gl);\n const [texture, setTexture] = useState<Texture | null>(null);\n const onErrorRef = useRef(onError);\n const onLoadProgressRef = useRef(onLoadProgress);\n onErrorRef.current = onError;\n onLoadProgressRef.current = onLoadProgress;\n\n useEffect(() => {\n let active = true;\n setTexture(null);\n if (!src) {\n onLoadProgressRef.current?.({ id, total: 1, loaded: 0, failed: 1 });\n return () => {\n active = false;\n };\n }\n\n const loader = new TextureLoader();\n loader.load(\n src,\n (loadedTexture) => {\n if (!active) {\n loadedTexture.dispose();\n return;\n }\n loadedTexture.colorSpace = SRGBColorSpace;\n loadedTexture.wrapS = ClampToEdgeWrapping;\n loadedTexture.wrapT = ClampToEdgeWrapping;\n loadedTexture.magFilter = LinearFilter;\n loadedTexture.minFilter = LinearMipmapLinearFilter;\n loadedTexture.generateMipmaps = true;\n loadedTexture.anisotropy = gl.capabilities.getMaxAnisotropy();\n loadedTexture.needsUpdate = true;\n onLoadProgressRef.current?.({ id, total: 1, loaded: 1, failed: 0 });\n setTexture(loadedTexture);\n },\n undefined,\n (error) => {\n if (!active) {\n return;\n }\n onLoadProgressRef.current?.({ id, total: 1, loaded: 0, failed: 1 });\n onErrorRef.current?.({ id, src, error });\n },\n );\n\n return () => {\n active = false;\n };\n }, [gl, id, src]);\n\n useEffect(\n () => () => {\n texture?.dispose();\n },\n [texture],\n );\n\n return texture;\n}\n\nexport function SequenceHotspot({\n id,\n src,\n frameCount: requestedFrameCount,\n frameDirection = \"vertical\",\n playing,\n fps,\n loop = true,\n width = 12,\n height = 8,\n opacity,\n onFrameChange,\n onLoadProgress,\n onPlaybackStateChange,\n onEnded,\n onError,\n ...anchorProps\n}: SequenceHotspotProps) {\n const texture = useSpriteTexture({ id, src, onError, onLoadProgress });\n const frameCount = resolveFrameCount(requestedFrameCount);\n const safeFps = resolveFps(fps);\n const [frameIndex, setFrameIndex] = useState(0);\n const elapsedRef = useRef(0);\n const frameIndexRef = useRef(0);\n const endedRef = useRef(false);\n const lastPlaybackStateRef = useRef<SequencePlaybackState | null>(null);\n const onFrameChangeRef = useRef(onFrameChange);\n const onPlaybackStateChangeRef = useRef(onPlaybackStateChange);\n const onEndedRef = useRef(onEnded);\n onFrameChangeRef.current = onFrameChange;\n onPlaybackStateChangeRef.current = onPlaybackStateChange;\n onEndedRef.current = onEnded;\n\n useEffect(() => {\n elapsedRef.current = 0;\n frameIndexRef.current = 0;\n endedRef.current = false;\n setFrameIndex(0);\n }, [frameCount, frameDirection, src]);\n\n useEffect(() => {\n if (!texture) {\n return;\n }\n texture.repeat.set(\n frameDirection === \"horizontal\" ? 1 / frameCount : 1,\n frameDirection === \"vertical\" ? 1 / frameCount : 1,\n );\n texture.offset.set(\n frameDirection === \"horizontal\" ? frameIndex / frameCount : 0,\n frameDirection === \"vertical\" ? 1 - (frameIndex + 1) / frameCount : 0,\n );\n texture.needsUpdate = true;\n }, [frameCount, frameDirection, frameIndex, texture]);\n\n useEffect(() => {\n if (!texture) {\n return;\n }\n onFrameChangeRef.current?.({ id, index: 0, src });\n }, [id, src, texture]);\n\n useEffect(() => {\n if (!texture) {\n return;\n }\n if (playing && endedRef.current) {\n elapsedRef.current = 0;\n frameIndexRef.current = 0;\n endedRef.current = false;\n setFrameIndex(0);\n }\n if (!playing && endedRef.current) {\n return;\n }\n const nextState: SequencePlaybackState = playing ? \"playing\" : \"paused\";\n if (lastPlaybackStateRef.current !== nextState) {\n lastPlaybackStateRef.current = nextState;\n onPlaybackStateChangeRef.current?.(nextState);\n }\n }, [playing, texture]);\n\n useFrame((_, deltaSeconds) => {\n if (!texture || !playing || endedRef.current) {\n return;\n }\n elapsedRef.current += deltaSeconds;\n const steps = Math.floor(elapsedRef.current * safeFps);\n if (steps === 0) {\n return;\n }\n elapsedRef.current -= steps / safeFps;\n\n let nextIndex = frameIndexRef.current + steps;\n if (nextIndex >= frameCount) {\n if (loop) {\n nextIndex %= frameCount;\n } else {\n nextIndex = frameCount - 1;\n endedRef.current = true;\n if (lastPlaybackStateRef.current !== \"ended\") {\n lastPlaybackStateRef.current = \"ended\";\n onPlaybackStateChangeRef.current?.(\"ended\");\n onEndedRef.current?.();\n }\n }\n }\n\n if (nextIndex !== frameIndexRef.current) {\n frameIndexRef.current = nextIndex;\n setFrameIndex(nextIndex);\n onFrameChangeRef.current?.({ id, index: nextIndex, src });\n }\n });\n\n return (\n <HotspotAnchor {...anchorProps} id={id} height={height} width={width}>\n <mesh>\n <planeGeometry args={[1, 1]} />\n <meshBasicMaterial\n map={texture}\n opacity={texture ? clampOpacity(opacity) : 0}\n side={DoubleSide}\n toneMapped={false}\n transparent\n />\n </mesh>\n </HotspotAnchor>\n );\n}\n","import { useThree } from \"@react-three/fiber\";\nimport { useEffect, useRef, useState } from \"react\";\nimport {\n ClampToEdgeWrapping,\n DoubleSide,\n LinearFilter,\n LinearMipmapLinearFilter,\n SRGBColorSpace,\n Texture,\n TextureLoader,\n VideoTexture,\n} from \"three\";\nimport { HotspotAnchor } from \"./hotspot-anchor\";\nimport type { HotspotCommonProps } from \"./types\";\n\nexport type VideoPlaybackState = \"playing\" | \"paused\" | \"ended\" | \"blocked\";\n\nexport type VideoHotspotErrorEvent = {\n id: string;\n source: \"poster\" | \"video\";\n error: unknown;\n};\n\nexport type VideoHotspotProps = HotspotCommonProps & {\n src: string;\n playing: boolean;\n poster?: string;\n loop?: boolean;\n muted?: boolean;\n volume?: number;\n playsInline?: boolean;\n preload?: \"none\" | \"metadata\" | \"auto\";\n crossOrigin?: \"\" | \"anonymous\" | \"use-credentials\";\n onPlaybackStateChange?: (state: VideoPlaybackState) => void;\n onPlaybackError?: (error: unknown) => void;\n onEnded?: () => void;\n onError?: (event: VideoHotspotErrorEvent) => void;\n};\n\ntype VideoResource = {\n video: HTMLVideoElement;\n texture: VideoTexture;\n ready: boolean;\n};\n\nfunction clampOpacity(opacity: number | undefined): number {\n if (!Number.isFinite(opacity)) {\n return 1;\n }\n return Math.max(0, Math.min(opacity!, 1));\n}\n\nfunction clampVolume(volume: number | undefined): number {\n if (!Number.isFinite(volume)) {\n return 1;\n }\n return Math.max(0, Math.min(volume!, 1));\n}\n\nfunction usePosterTexture(\n id: string,\n poster: string | undefined,\n onError: VideoHotspotProps[\"onError\"],\n) {\n const gl = useThree((state) => state.gl);\n const [texture, setTexture] = useState<Texture | null>(null);\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n\n useEffect(() => {\n let active = true;\n setTexture(null);\n if (!poster) {\n return () => {\n active = false;\n };\n }\n\n const loader = new TextureLoader();\n loader.load(\n poster,\n (loadedTexture) => {\n if (!active) {\n loadedTexture.dispose();\n return;\n }\n loadedTexture.colorSpace = SRGBColorSpace;\n loadedTexture.wrapS = ClampToEdgeWrapping;\n loadedTexture.wrapT = ClampToEdgeWrapping;\n loadedTexture.magFilter = LinearFilter;\n loadedTexture.minFilter = LinearMipmapLinearFilter;\n loadedTexture.generateMipmaps = true;\n loadedTexture.anisotropy = gl.capabilities.getMaxAnisotropy();\n loadedTexture.needsUpdate = true;\n setTexture(loadedTexture);\n },\n undefined,\n (error) => {\n if (active) {\n onErrorRef.current?.({ id, source: \"poster\", error });\n }\n },\n );\n\n return () => {\n active = false;\n };\n }, [gl, id, poster]);\n\n useEffect(\n () => () => {\n texture?.dispose();\n },\n [texture],\n );\n\n return texture;\n}\n\nfunction useVideoResource({\n crossOrigin,\n id,\n onEnded,\n onError,\n onPlaybackStateChange,\n playsInline,\n poster,\n src,\n}: Pick<\n VideoHotspotProps,\n | \"crossOrigin\"\n | \"id\"\n | \"onEnded\"\n | \"onError\"\n | \"onPlaybackStateChange\"\n | \"playsInline\"\n | \"poster\"\n | \"src\"\n>) {\n const [resource, setResource] = useState<VideoResource | null>(null);\n const onEndedRef = useRef(onEnded);\n const onErrorRef = useRef(onError);\n const onPlaybackStateChangeRef = useRef(onPlaybackStateChange);\n onEndedRef.current = onEnded;\n onErrorRef.current = onError;\n onPlaybackStateChangeRef.current = onPlaybackStateChange;\n\n useEffect(() => {\n if (!src) {\n setResource(null);\n return;\n }\n\n let active = true;\n const video = document.createElement(\"video\");\n if (crossOrigin !== undefined) {\n video.crossOrigin = crossOrigin;\n }\n video.playsInline = playsInline ?? true;\n video.poster = poster ?? \"\";\n const texture = new VideoTexture(video);\n texture.colorSpace = SRGBColorSpace;\n texture.wrapS = ClampToEdgeWrapping;\n texture.wrapT = ClampToEdgeWrapping;\n texture.magFilter = LinearFilter;\n texture.minFilter = LinearFilter;\n texture.generateMipmaps = false;\n\n const notifyState = (state: VideoPlaybackState) => {\n if (active) {\n onPlaybackStateChangeRef.current?.(state);\n }\n };\n const markReady = () => {\n if (!active) {\n return;\n }\n setResource((current) =>\n current?.video === video ? { ...current, ready: true } : current,\n );\n };\n const reportError = () => {\n if (active) {\n onErrorRef.current?.({\n id,\n source: \"video\",\n error: video.error ?? new Error(`Unable to load video source: ${src}`),\n });\n }\n };\n\n const handleEnded = () => {\n notifyState(\"ended\");\n onEndedRef.current?.();\n };\n const handlePause = () => notifyState(\"paused\");\n const handlePlay = () => notifyState(\"playing\");\n video.addEventListener(\"canplay\", markReady);\n video.addEventListener(\"ended\", handleEnded);\n video.addEventListener(\"error\", reportError);\n video.addEventListener(\"pause\", handlePause);\n video.addEventListener(\"play\", handlePlay);\n setResource({ video, texture, ready: false });\n video.src = src;\n video.load();\n\n return () => {\n active = false;\n video.removeEventListener(\"canplay\", markReady);\n video.removeEventListener(\"ended\", handleEnded);\n video.removeEventListener(\"error\", reportError);\n video.removeEventListener(\"pause\", handlePause);\n video.removeEventListener(\"play\", handlePlay);\n video.pause();\n video.removeAttribute(\"src\");\n video.load();\n texture.dispose();\n };\n }, [crossOrigin, id, playsInline, poster, src]);\n\n return resource;\n}\n\nexport function VideoHotspot({\n id,\n src,\n playing,\n poster,\n loop = false,\n muted = true,\n volume = 1,\n playsInline = true,\n preload = \"metadata\",\n crossOrigin,\n width = 16,\n height = 9,\n opacity,\n onPlaybackStateChange,\n onPlaybackError,\n onEnded,\n onError,\n ...anchorProps\n}: VideoHotspotProps) {\n const resource = useVideoResource({\n crossOrigin,\n id,\n onEnded,\n onError,\n onPlaybackStateChange,\n playsInline,\n poster,\n src,\n });\n const posterTexture = usePosterTexture(id, poster, onError);\n const onPlaybackErrorRef = useRef(onPlaybackError);\n const onPlaybackStateChangeRef = useRef(onPlaybackStateChange);\n onPlaybackErrorRef.current = onPlaybackError;\n onPlaybackStateChangeRef.current = onPlaybackStateChange;\n\n useEffect(() => {\n if (!resource) {\n return;\n }\n resource.video.loop = loop;\n resource.video.muted = muted;\n resource.video.volume = clampVolume(volume);\n resource.video.playsInline = playsInline;\n resource.video.preload = preload;\n }, [loop, muted, playsInline, preload, resource, volume]);\n\n useEffect(() => {\n if (!resource) {\n return;\n }\n let active = true;\n if (!playing) {\n resource.video.pause();\n return () => {\n active = false;\n };\n }\n\n void resource.video.play().catch((error: unknown) => {\n if (!active) {\n return;\n }\n onPlaybackStateChangeRef.current?.(\"blocked\");\n onPlaybackErrorRef.current?.(error);\n });\n\n return () => {\n active = false;\n };\n }, [playing, resource]);\n\n const activeTexture = resource?.ready ? resource.texture : posterTexture;\n\n return (\n <HotspotAnchor {...anchorProps} id={id} height={height} width={width}>\n <mesh>\n <planeGeometry args={[1, 1]} />\n <meshBasicMaterial\n map={activeTexture}\n opacity={activeTexture ? clampOpacity(opacity) : 0}\n side={DoubleSide}\n toneMapped={false}\n transparent\n />\n </mesh>\n </HotspotAnchor>\n );\n}\n"],"mappings":"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","names":["import_fiber","import_react","PanoramaControls","elapsed","zoomDamping","import_fiber","import_react","import_react","import_three","import_three","import_jsx_runtime","import_jsx_runtime","PanoView","import_fiber","import_react","import_three","import_jsx_runtime","import_fiber","import_react","import_three","import_fiber","import_react","import_three","import_jsx_runtime","import_fiber","import_react","import_three","import_three","tileSize","levels","import_jsx_runtime","TileMesh","TileLayerMeshes","import_jsx_runtime","import_fiber","import_react","import_three","import_fiber","import_react","import_three","import_jsx_runtime","orientation","surfaceQuaternion","import_jsx_runtime","import_fiber","import_react","import_three","import_jsx_runtime","import_fiber","import_react","import_three","import_Line2","import_LineGeometry","import_LineMaterial","import_jsx_runtime","cloneVertices","surfaceQuaternion","makeWorldToLocal","translateVertices","import_react","import_three","import_jsx_runtime","clampOpacity","import_fiber","import_react","import_three","import_jsx_runtime","clampOpacity","import_fiber","import_react","import_three","import_jsx_runtime","clampOpacity"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/pano-view.tsx","../src/auto-rotate.tsx","../src/pano-event-bus.ts","../src/panorama-view-runtime.tsx","../src/hotspot/accessibility.tsx","../src/keyboard-controls.tsx","../src/mouse-controls.tsx","../src/pano-context-menu.tsx","../src/pano-events.tsx","../src/panorama-event-surface.tsx","../src/hotspot/coordinates.ts","../src/hotspot/types.ts","../src/panorama-radius.ts","../src/touch-controls.tsx","../src/sphere.tsx","../src/panorama-scenes.tsx","../src/tile/texture-manager-context.tsx","../src/tile/texture-manager.ts","../src/tile/tile.tsx","../src/tile/face-layout.ts","../src/tile/multires.ts","../src/hotspot/image-hotspot.tsx","../src/hotspot/hotspot-anchor.tsx","../src/hotspot/polygon-hotspot.tsx","../src/hotspot/polyline-hotspot.tsx","../src/hotspot/graphic-hotspot.tsx","../src/hotspot/sequence-hotspot.tsx","../src/hotspot/video-hotspot.tsx"],"sourcesContent":["export { PanoView } from \"./pano-view\";\nexport type { PanoViewProps } from \"./pano-view\";\nexport { AutoRotate } from \"./auto-rotate\";\nexport type { AutoRotateProps } from \"./auto-rotate\";\nexport { PanoContextMenu } from \"./pano-context-menu\";\nexport {\n composePanoContextMenuItems,\n createDefaultPanoContextMenuItems,\n createPanoContextMenuPresets,\n MIN_PANO_CONTEXT_MENU_BACKGROUND_OPACITY,\n resolvePanoContextMenuEntries,\n} from \"./pano-context-menu\";\nexport type {\n PanoContextMenuActionItem,\n PanoContextMenuAppearance,\n PanoContextMenuEntry,\n PanoContextMenuItem,\n PanoContextMenuPresetActions,\n PanoContextMenuPresetId,\n PanoContextMenuPresetRef,\n PanoContextMenuPresets,\n PanoContextMenuProps,\n PanoContextMenuRenderProps,\n PanoContextMenuSelectContext,\n PanoContextMenuSeparatorItem,\n} from \"./pano-context-menu\";\nexport { PanoEvents, usePanoEvents } from \"./pano-events\";\nexport type { PanoEventsProps } from \"./pano-events\";\nexport type {\n PanoEventBus,\n PanoEventListener,\n PanoEventMap,\n PanoEventType,\n PanoResizeEvent,\n PanoWheelEvent,\n ViewInteractionEvent,\n ViewInteractionSource,\n} from \"./pano-event-bus\";\nexport { KeyboardControls, cycleSceneId } from \"./keyboard-controls\";\nexport type {\n KeyboardControlAction,\n KeyboardControlKeys,\n KeyboardControlsProps,\n} from \"./keyboard-controls\";\nexport { MouseControls } from \"./mouse-controls\";\nexport type { MouseControlsProps } from \"./mouse-controls\";\nexport { TouchControls } from \"./touch-controls\";\nexport type { TouchControlsProps } from \"./touch-controls\";\nexport { Sphere } from \"./sphere\";\nexport type { SphereProps } from \"./sphere\";\nexport { PanoramaScenes } from \"./panorama-scenes\";\nexport type {\n PanoramaScene,\n PanoramaScenesProps,\n PanoramaTransition,\n PanoramaTransitionEndEvent,\n PanoramaTransitionErrorEvent,\n PanoramaTransitionPreset,\n SpherePanoramaScene,\n TilePanoramaScene,\n} from \"./panorama-scenes\";\nexport { ImageHotspot } from \"./hotspot/image-hotspot\";\nexport type { ImageHotspotProps } from \"./hotspot/image-hotspot\";\nexport { PolygonHotspot } from \"./hotspot/polygon-hotspot\";\nexport type {\n PolygonHotspotProps,\n PolygonValidationCode,\n PolygonValidationIssue,\n PolygonVerticesChangeEvent,\n} from \"./hotspot/polygon-hotspot\";\nexport { PolylineHotspot, validatePolylineVertices } from \"./hotspot/polyline-hotspot\";\nexport type {\n PolylineHotspotProps,\n PolylineValidationIssue,\n PolylineVerticesChangeEvent,\n} from \"./hotspot/polyline-hotspot\";\nexport {\n unwrapPolygonVertices,\n validatePolygonVertices,\n} from \"./hotspot/polygon-hotspot\";\nexport { GraphicHotspot } from \"./hotspot/graphic-hotspot\";\nexport type {\n ArrowGraphic,\n CircleGraphic,\n DiamondGraphic,\n GraphicDefinition,\n GraphicHotspotProps,\n RectangleGraphic,\n RingGraphic,\n StarGraphic,\n SvgGraphic,\n SvgPathGraphic,\n TriangleGraphic,\n} from \"./hotspot/graphic-hotspot\";\nexport { SequenceHotspot } from \"./hotspot/sequence-hotspot\";\nexport type {\n SequenceFrameEvent,\n SequenceFrameDirection,\n SequenceHotspotErrorEvent,\n SequenceHotspotProps,\n SequenceLoadProgress,\n SequencePlaybackState,\n} from \"./hotspot/sequence-hotspot\";\nexport { VideoHotspot } from \"./hotspot/video-hotspot\";\nexport type {\n VideoHotspotErrorEvent,\n VideoHotspotProps,\n VideoPlaybackState,\n} from \"./hotspot/video-hotspot\";\nexport { Tile } from \"./tile/tile\";\nexport type {\n CubeFaceCode,\n TileAddress,\n TileLoadError,\n TileLoadProgress,\n TileMultiresConfig,\n TileProps,\n} from \"./tile/types\";\nexport type {\n MouseControlButton,\n MouseControlsOptions,\n PanoramaControlsOptions,\n PanoViewHandle,\n PanoViewState,\n SetPanoViewOptions,\n TouchControlsOptions,\n} from \"./types\";\nexport {\n clampPanoPitch,\n normalizePanoPosition,\n normalizePanoYaw,\n panoPositionToVector3,\n vector3ToPanoPosition,\n} from \"./hotspot/coordinates\";\nexport { MAX_HOTSPOT_PITCH } from \"./hotspot/types\";\nexport type {\n HotspotDragEvent,\n HotspotInputSource,\n HotspotInteractionEvent,\n HotspotCommonProps,\n HotspotMode,\n HotspotScaleMode,\n HotspotPosition,\n PanoramaPointerEvent,\n} from \"./hotspot/types\";\nexport type {\n GraphicHotspotDefinition,\n HotspotDefinition,\n HotspotDefinitionBase,\n ImageHotspotDefinition,\n PointHotspotDefinition,\n PointHotspotDefinitionBase,\n PolygonHotspotDefinition,\n PolylineHotspotDefinition,\n SequenceHotspotDefinition,\n VideoHotspotDefinition,\n} from \"./hotspot/definitions\";\n","import { Canvas } from \"@react-three/fiber\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type {\n ComponentPropsWithoutRef,\n CSSProperties,\n ReactNode,\n} from \"react\";\nimport { AutoRotate } from \"./auto-rotate\";\nimport {\n HotspotAccessibilityContext,\n useHotspotAccessibilityLayer,\n} from \"./hotspot/accessibility\";\nimport type { PanoramaPointerEvent } from \"./hotspot/types\";\nimport {\n KeyboardControls,\n type KeyboardControlsProps,\n} from \"./keyboard-controls\";\nimport { MouseControls } from \"./mouse-controls\";\nimport {\n PanoContextMenu,\n PanoContextMenuActionsContext,\n PanoContextMenuOverlayContext,\n usePanoContextMenuOverlay,\n type PanoContextMenuProps,\n} from \"./pano-context-menu\";\nimport {\n createPanoEventBus,\n PanoEventBusContext,\n} from \"./pano-event-bus\";\nimport { PanoEvents } from \"./pano-events\";\nimport { PanoramaEventSurface } from \"./panorama-event-surface\";\nimport {\n DEFAULT_PANORAMA_CAMERA_FAR,\n DEFAULT_PANORAMA_CAMERA_NEAR,\n} from \"./panorama-radius\";\nimport {\n PanoramaViewContext,\n PanoramaViewRuntime,\n type PanoramaViewRuntimeHandle,\n} from \"./panorama-view-runtime\";\nimport { clampPanoPitch } from \"./hotspot/coordinates\";\nimport { TouchControls } from \"./touch-controls\";\nimport type {\n MouseControlsOptions,\n PanoramaControlsOptions,\n PanoViewHandle,\n PanoViewState,\n TouchControlsOptions,\n} from \"./types\";\n\nconst DEFAULT_VIEW: PanoViewState = {\n yaw: 0,\n pitch: 0,\n fov: 75,\n};\n\nconst DEFAULT_POINTER_ROTATE_SPEED = 0.35;\nconst DEFAULT_MOUSE_ZOOM_SPEED = 0.08;\n\nconst DEFAULT_CANVAS_STYLE: CSSProperties = {\n display: \"block\",\n height: \"100%\",\n width: \"100%\",\n};\n\nexport type PanoViewProps = Omit<\n ComponentPropsWithoutRef<\"div\">,\n \"children\" | \"onChange\" | \"contextMenu\"\n> & {\n children?: ReactNode;\n initialView?: Partial<PanoViewState>;\n minFov?: number;\n maxFov?: number;\n controls?: boolean | PanoramaControlsOptions;\n /**\n * Default context menu. `true` / omit mounts Reset view + Fullscreen;\n * `false` skips the default instance; an object merges appearance and\n * may use `items` (full replace, supports preset ids), or `prepend` /\n * `append` to keep the defaults and add entries.\n */\n contextMenu?: boolean | PanoContextMenuProps;\n onViewChange?: (view: PanoViewState) => void;\n onPanoramaClick?: (event: PanoramaPointerEvent) => void;\n onPanoramaDoubleClick?: (event: PanoramaPointerEvent) => void;\n onPanoramaPointerMove?: (event: PanoramaPointerEvent) => void;\n /** Canvas pixel ratio. Defaults to a capped range of 1–2. */\n dpr?: number | [number, number];\n};\n\ntype ChannelMount<T> =\n | { mount: false }\n | { mount: true; props: T };\n\nfunction resolveChannel<T extends { enabled?: boolean }>(\n value: boolean | T | undefined,\n defaults: T,\n): ChannelMount<T> {\n if (value === false) {\n return { mount: false };\n }\n if (value === true || value === undefined) {\n return { mount: true, props: { ...defaults } };\n }\n return {\n mount: true,\n props: {\n ...defaults,\n ...value,\n enabled: value.enabled !== false,\n },\n };\n}\n\nfunction resolveContextMenuChannel(\n value: boolean | PanoContextMenuProps | undefined,\n): ChannelMount<PanoContextMenuProps> {\n if (value === false) {\n return { mount: false };\n }\n if (value === true || value === undefined) {\n return { mount: true, props: {} };\n }\n return { mount: true, props: { ...value } };\n}\n\nexport const PanoView = forwardRef<PanoViewHandle, PanoViewProps>(\n function PanoView(\n {\n children,\n initialView,\n minFov = 30,\n maxFov = 100,\n controls = true,\n contextMenu = true,\n onViewChange,\n onPanoramaClick,\n onPanoramaDoubleClick,\n onPanoramaPointerMove,\n dpr = [1, 2],\n style,\n \"aria-label\": ariaLabel = \"Panorama viewer\",\n ...divProps\n },\n ref,\n ) {\n const rootRef = useRef<HTMLDivElement>(null);\n const controlsRef = useRef<PanoramaViewRuntimeHandle>(null);\n const eventBus = useMemo(() => createPanoEventBus(), []);\n const { controls: hotspotAccessibilityControls, registry } =\n useHotspotAccessibilityLayer();\n const { api: contextMenuOverlayApi, overlay: contextMenuOverlay } =\n usePanoContextMenuOverlay();\n const fallbackViewRef = useRef<PanoViewState>(DEFAULT_VIEW);\n const normalizedMinFov = Math.max(1, Math.min(minFov, maxFov - 1));\n const normalizedMaxFov = Math.min(\n 179,\n Math.max(maxFov, normalizedMinFov + 1),\n );\n const normalizedInitialView = useMemo<PanoViewState>(\n () => ({\n yaw: initialView?.yaw ?? DEFAULT_VIEW.yaw,\n pitch: clampPanoPitch(initialView?.pitch ?? DEFAULT_VIEW.pitch),\n fov: Math.max(\n normalizedMinFov,\n Math.min(initialView?.fov ?? DEFAULT_VIEW.fov, normalizedMaxFov),\n ),\n }),\n [\n initialView?.fov,\n initialView?.pitch,\n initialView?.yaw,\n normalizedMaxFov,\n normalizedMinFov,\n ],\n );\n fallbackViewRef.current = normalizedInitialView;\n\n const controlsEnabled = controls !== false;\n const controlOptions = useMemo<PanoramaControlsOptions>(\n () => (typeof controls === \"object\" ? controls : {}),\n [controls],\n );\n const userControlsEnabled =\n controlsEnabled && controlOptions.enabled !== false;\n\n const allModeInvert = controlOptions.invert === true;\n const topRotateSpeed =\n controlOptions.rotateSpeed ?? DEFAULT_POINTER_ROTATE_SPEED;\n const topZoomSpeed = controlOptions.zoomSpeed ?? DEFAULT_MOUSE_ZOOM_SPEED;\n\n const mouseChannel = useMemo(\n () =>\n resolveChannel<MouseControlsOptions>(controlOptions.mouse, {\n enabled: true,\n rotateSpeed: topRotateSpeed,\n zoomSpeed: topZoomSpeed,\n wheel: true,\n invert: allModeInvert,\n buttons: [\"left\"],\n }),\n [\n allModeInvert,\n controlOptions.mouse,\n topRotateSpeed,\n topZoomSpeed,\n ],\n );\n const touchChannel = useMemo(\n () =>\n resolveChannel<TouchControlsOptions>(controlOptions.touch, {\n enabled: true,\n rotateSpeed: topRotateSpeed,\n invert: allModeInvert,\n pinchZoom: true,\n }),\n [allModeInvert, controlOptions.touch, topRotateSpeed],\n );\n const keyboardChannel = useMemo(\n () =>\n resolveChannel<KeyboardControlsProps>(controlOptions.keyboard, {\n enabled: true,\n }),\n [controlOptions.keyboard],\n );\n\n const toggleFullscreen = useCallback(async () => {\n if (typeof document === \"undefined\") {\n return;\n }\n if (document.fullscreenElement) {\n await document.exitFullscreen?.();\n return;\n }\n await rootRef.current?.requestFullscreen?.();\n }, []);\n\n const [isViewerFullscreen, setIsViewerFullscreen] = useState(false);\n\n useEffect(() => {\n if (typeof document === \"undefined\") {\n return;\n }\n\n const syncFullscreen = () => {\n const fullscreenElement = document.fullscreenElement;\n const root = rootRef.current;\n if (!fullscreenElement || !root) {\n setIsViewerFullscreen(false);\n return;\n }\n setIsViewerFullscreen(\n fullscreenElement === root ||\n fullscreenElement.contains(root) ||\n root.contains(fullscreenElement),\n );\n };\n\n syncFullscreen();\n document.addEventListener(\"fullscreenchange\", syncFullscreen);\n return () => {\n document.removeEventListener(\"fullscreenchange\", syncFullscreen);\n };\n }, []);\n\n const contextMenuActions = useMemo(\n () => ({\n reset: () => {\n controlsRef.current?.reset();\n },\n toggleFullscreen: () => {\n void toggleFullscreen();\n },\n isFullscreen: isViewerFullscreen,\n }),\n [isViewerFullscreen, toggleFullscreen],\n );\n\n const contextMenuChannel = useMemo(\n () => resolveContextMenuChannel(contextMenu),\n [contextMenu],\n );\n\n // Bridge deprecated controls.autoRotate / autoRotateSpeed without\n // surfacing @deprecated diagnostics on this compatibility path.\n const legacyAutoRotateOptions = controlOptions as {\n autoRotate?: boolean;\n autoRotateSpeed?: number;\n };\n const [legacyAutoRotate, setLegacyAutoRotate] = useState(\n legacyAutoRotateOptions.autoRotate ?? false,\n );\n\n useEffect(() => {\n setLegacyAutoRotate(legacyAutoRotateOptions.autoRotate ?? false);\n }, [legacyAutoRotateOptions.autoRotate]);\n\n useImperativeHandle(\n ref,\n () => ({\n getView: () =>\n controlsRef.current?.getView() ?? { ...fallbackViewRef.current },\n setView: (view, options) => {\n controlsRef.current?.setView(view, options);\n },\n reset: () => {\n controlsRef.current?.reset();\n },\n startAutoRotate: () => {\n setLegacyAutoRotate(true);\n },\n stopAutoRotate: () => {\n setLegacyAutoRotate(false);\n },\n toggleFullscreen,\n }),\n [toggleFullscreen],\n );\n\n const rootStyle = useMemo<CSSProperties>(\n () => ({\n overflow: \"hidden\",\n position: \"relative\",\n ...style,\n }),\n [style],\n );\n\n return (\n <div\n {...divProps}\n ref={rootRef}\n aria-label={ariaLabel}\n style={rootStyle}\n >\n <Canvas\n aria-label={`${ariaLabel} canvas`}\n camera={{\n far: DEFAULT_PANORAMA_CAMERA_FAR,\n fov: normalizedInitialView.fov,\n near: DEFAULT_PANORAMA_CAMERA_NEAR,\n position: [0, 0, 0.01],\n }}\n dpr={dpr}\n gl={{\n // Hotspots contain transparent textures and curved outlines. Keep\n // the canvas multisampled so their visible edges are smoothed.\n antialias: true,\n powerPreference: \"high-performance\",\n stencil: false,\n }}\n style={{\n ...DEFAULT_CANVAS_STYLE,\n touchAction: userControlsEnabled ? \"none\" : \"auto\",\n }}\n tabIndex={userControlsEnabled ? 0 : undefined}\n >\n <HotspotAccessibilityContext.Provider value={registry}>\n <PanoEventBusContext.Provider value={eventBus}>\n <PanoramaViewContext.Provider value={controlsRef}>\n <PanoContextMenuOverlayContext.Provider\n value={contextMenuOverlayApi}\n >\n <PanoContextMenuActionsContext.Provider\n value={contextMenuActions}\n >\n <PanoramaViewRuntime\n ref={controlsRef}\n eventBus={eventBus}\n initialView={normalizedInitialView}\n maxFov={normalizedMaxFov}\n minFov={normalizedMinFov}\n options={controlOptions}\n />\n {(onViewChange ||\n onPanoramaClick ||\n onPanoramaDoubleClick ||\n onPanoramaPointerMove) && (\n <PanoEvents\n onViewChange={onViewChange}\n onClick={onPanoramaClick}\n onDoubleClick={onPanoramaDoubleClick}\n onPointerMove={onPanoramaPointerMove}\n />\n )}\n <AutoRotate\n enabled={legacyAutoRotate}\n speed={legacyAutoRotateOptions.autoRotateSpeed}\n />\n {userControlsEnabled && mouseChannel.mount ? (\n <MouseControls\n {...mouseChannel.props}\n fovSpeed={controlOptions.fovSpeed}\n />\n ) : null}\n {userControlsEnabled && touchChannel.mount ? (\n <TouchControls {...touchChannel.props} />\n ) : null}\n {userControlsEnabled && keyboardChannel.mount ? (\n <KeyboardControls\n {...keyboardChannel.props}\n fovSpeed={\n keyboardChannel.props.fovSpeed ??\n controlOptions.fovSpeed\n }\n />\n ) : null}\n <PanoramaEventSurface />\n {contextMenuChannel.mount ? (\n <PanoContextMenu {...contextMenuChannel.props} />\n ) : null}\n {children}\n </PanoContextMenuActionsContext.Provider>\n </PanoContextMenuOverlayContext.Provider>\n </PanoramaViewContext.Provider>\n </PanoEventBusContext.Provider>\n </HotspotAccessibilityContext.Provider>\n </Canvas>\n {contextMenuOverlay}\n {hotspotAccessibilityControls}\n </div>\n );\n },\n);\n","import { useFrame } from \"@react-three/fiber\";\nimport { useContext, useEffect, useRef } from \"react\";\nimport { PanoEventBusContext } from \"./pano-event-bus\";\nimport { PanoramaViewContext } from \"./panorama-view-runtime\";\n\nconst DEFAULT_AUTO_ROTATE_SPEED = 18;\nconst DEFAULT_AUTO_ROTATE_ACCELERATION = 18;\nconst DEFAULT_AUTO_ROTATE_START_DELAY = 2;\n\n/** Options for automatic horizontal panorama rotation. */\nexport type AutoRotateProps = {\n /** Whether automatic rotation is active. Defaults to true. */\n enabled?: boolean;\n /** Rotation speed in degrees per second. Negative values rotate left. */\n speed?: number;\n /**\n * Rate at which rotation reaches its target speed, in degrees per second\n * squared. Use 0 to disable the speed ramp. Defaults to 18.\n */\n acceleration?: number;\n /** Milliseconds to wait after enabling before rotation begins. */\n startDelay?: number;\n};\n\nfunction resolveStartDelay(value: number | undefined): number {\n return Number.isFinite(value) ? Math.max(value!, 0) : 0;\n}\n\nfunction resolveAcceleration(value: number | undefined): number {\n return Number.isFinite(value) && value! >= 0\n ? value!\n : DEFAULT_AUTO_ROTATE_ACCELERATION;\n}\n\n/**\n * Adds automatic rotation to the nearest PanoView. Render one instance as a\n * child of PanoView, alongside its panorama source.\n */\nexport function AutoRotate({\n enabled = true,\n speed = DEFAULT_AUTO_ROTATE_SPEED,\n acceleration = DEFAULT_AUTO_ROTATE_ACCELERATION,\n startDelay = DEFAULT_AUTO_ROTATE_START_DELAY,\n}: AutoRotateProps) {\n const controlsRef = useContext(PanoramaViewContext);\n const eventBus = useContext(PanoEventBusContext);\n const elapsedRef = useRef(0);\n const rotationSpeedRef = useRef(0);\n const rotatingRef = useRef(false);\n const yawAccumulatedRef = useRef(0);\n\n if (!controlsRef) {\n throw new Error(\"<AutoRotate> must be rendered inside <PanoView>.\");\n }\n\n useEffect(() => {\n elapsedRef.current = 0;\n rotationSpeedRef.current = 0;\n yawAccumulatedRef.current = 0;\n if (rotatingRef.current) {\n rotatingRef.current = false;\n eventBus?.emit(\"autorotatestop\", undefined);\n }\n }, [enabled, eventBus, startDelay]);\n\n useFrame((_, deltaSeconds) => {\n if (!enabled || !Number.isFinite(speed) || speed === 0) {\n rotationSpeedRef.current = 0;\n if (rotatingRef.current) {\n rotatingRef.current = false;\n eventBus?.emit(\"autorotatestop\", undefined);\n }\n return;\n }\n\n const delaySeconds = resolveStartDelay(startDelay) / 1000;\n elapsedRef.current += deltaSeconds;\n if (elapsedRef.current < delaySeconds) {\n return;\n }\n\n const targetSpeed = Math.abs(speed);\n const currentSpeed = rotationSpeedRef.current;\n const accelerationPerSecond = resolveAcceleration(acceleration);\n const nextSpeed =\n accelerationPerSecond === 0\n ? targetSpeed\n : Math.min(\n targetSpeed,\n currentSpeed + accelerationPerSecond * deltaSeconds,\n );\n const averageSpeed = (currentSpeed + nextSpeed) / 2;\n const yawDelta = Math.sign(speed) * averageSpeed * deltaSeconds;\n\n if (!controlsRef.current?.applyAutoRotation(yawDelta)) {\n rotationSpeedRef.current = 0;\n if (rotatingRef.current) {\n rotatingRef.current = false;\n eventBus?.emit(\"autorotatestop\", undefined);\n }\n return;\n }\n\n if (!rotatingRef.current) {\n rotatingRef.current = true;\n eventBus?.emit(\"autorotatestart\", undefined);\n }\n\n yawAccumulatedRef.current += Math.abs(yawDelta);\n while (yawAccumulatedRef.current >= 360) {\n yawAccumulatedRef.current -= 360;\n eventBus?.emit(\"autorotateoneround\", undefined);\n }\n\n rotationSpeedRef.current = nextSpeed;\n });\n\n return null;\n}\n","import { createContext } from \"react\";\nimport type { PanoramaPointerEvent } from \"./hotspot/types\";\nimport type { PanoViewState } from \"./types\";\n\nexport type ViewInteractionSource = \"mouse\" | \"touch\" | \"keyboard\";\n\nexport type PanoWheelEvent = {\n /** Signed wheel delta (same sign convention as WheelEvent.deltaY). */\n delta: number;\n nativeEvent: WheelEvent;\n};\n\nexport type PanoResizeEvent = {\n width: number;\n height: number;\n};\n\nexport type ViewInteractionEvent = {\n source: ViewInteractionSource;\n};\n\nexport type PanoEventMap = {\n viewchange: PanoViewState;\n viewsettled: PanoViewState;\n viewinteractionstart: ViewInteractionEvent;\n viewinteractionend: ViewInteractionEvent;\n click: PanoramaPointerEvent;\n doubleclick: PanoramaPointerEvent;\n pointerdown: PanoramaPointerEvent;\n pointerup: PanoramaPointerEvent;\n pointermove: PanoramaPointerEvent;\n contextmenu: PanoramaPointerEvent;\n wheel: PanoWheelEvent;\n idle: undefined;\n idleend: undefined;\n enterfullscreen: undefined;\n exitfullscreen: undefined;\n resize: PanoResizeEvent;\n autorotatestart: undefined;\n autorotatestop: undefined;\n autorotateoneround: undefined;\n};\n\nexport type PanoEventType = keyof PanoEventMap;\n\nexport type PanoEventListener<T extends PanoEventType> = (\n payload: PanoEventMap[T],\n) => void;\n\nexport type PanoEventBus = {\n subscribe: <T extends PanoEventType>(\n type: T,\n listener: PanoEventListener<T>,\n ) => () => void;\n emit: <T extends PanoEventType>(type: T, payload: PanoEventMap[T]) => void;\n};\n\nexport function createPanoEventBus(): PanoEventBus {\n const listeners = new Map<PanoEventType, Set<PanoEventListener<PanoEventType>>>();\n\n return {\n subscribe(type, listener) {\n let set = listeners.get(type);\n if (!set) {\n set = new Set();\n listeners.set(type, set);\n }\n set.add(listener as PanoEventListener<PanoEventType>);\n return () => {\n set?.delete(listener as PanoEventListener<PanoEventType>);\n if (set && set.size === 0) {\n listeners.delete(type);\n }\n };\n },\n emit(type, payload) {\n const set = listeners.get(type);\n if (!set || set.size === 0) {\n return;\n }\n for (const listener of [...set]) {\n (listener as PanoEventListener<typeof type>)(payload);\n }\n },\n };\n}\n\nexport const PanoEventBusContext = createContext<PanoEventBus | null>(null);\n","import { useFrame, useThree } from \"@react-three/fiber\";\nimport {\n createContext,\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n} from \"react\";\nimport type { RefObject } from \"react\";\nimport { Euler, MathUtils, PerspectiveCamera } from \"three\";\nimport type { PanoEventBus } from \"./pano-event-bus\";\nimport type {\n PanoramaControlsOptions,\n PanoViewState,\n SetPanoViewOptions,\n} from \"./types\";\n\nconst MAX_PITCH = 90;\nconst BOUNCE_OVERSHOOT_PITCH = 12;\nconst BOUNCE_OVERSHOOT_FOV_RATIO = 0.15;\nconst INERTIA_ROTATION_DAMPING = 8;\nconst INERTIA_ZOOM_DAMPING = 12;\nconst DEFAULT_ROTATE_DAMPING = 14;\nconst DEFAULT_ZOOM_DAMPING = 16;\nconst DEFAULT_FRICTION_STOP = 0.01;\nconst VIEW_SETTLE_EPSILON = 0.001;\n\nexport type ApplyViewDeltaOptions = {\n /** When true, records yaw/pitch/fov velocity for post-drag inertia. */\n recordVelocity?: boolean;\n};\n\nexport type PanoramaViewRuntimeHandle = {\n getView: () => PanoViewState;\n /** Target view used by drag/zoom input before camera smoothing. */\n getTargetView: () => PanoViewState;\n setView: (\n view: Partial<PanoViewState>,\n options?: SetPanoViewOptions,\n ) => void;\n reset: () => void;\n /**\n * Adjusts the target view by relative deltas without snapping the current\n * view. Returns false while an interaction lock is held.\n */\n applyViewDelta: (\n delta: Partial<PanoViewState>,\n options?: ApplyViewDeltaOptions,\n ) => boolean;\n /** Marks whether keyboard navigation is currently driving the view. */\n setKeyboardActive: (active: boolean) => void;\n /** Marks whether mouse or touch input is currently driving the view. */\n setPointerActive: (source: \"mouse\" | \"touch\", active: boolean) => void;\n /** Whether hotspot / transition locks currently block user input. */\n isInteractionLocked: () => boolean;\n /**\n * True while pointer/keyboard input, post-drag inertia, or an interaction\n * lock is active. Used by idle timers and AutoRotate pause logic.\n */\n isUserInteracting: () => boolean;\n applyAutoRotation: (yawDelta: number) => boolean;\n acquireInteractionLock: () => () => void;\n};\n\nexport const PanoramaViewContext = createContext<\n RefObject<PanoramaViewRuntimeHandle | null> | null\n>(null);\n\ntype PanoramaViewRuntimeProps = {\n initialView: PanoViewState;\n minFov: number;\n maxFov: number;\n options: PanoramaControlsOptions;\n eventBus: PanoEventBus;\n};\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n\nfunction normalizeYaw(yaw: number): number {\n return MathUtils.euclideanModulo(yaw + 180, 360) - 180;\n}\n\nfunction shortestYawDelta(from: number, to: number): number {\n return normalizeYaw(to - from);\n}\n\nfunction dampingFactor(damping: number, deltaSeconds: number): number {\n return damping === 0 ? 1 : 1 - Math.exp(-damping * deltaSeconds);\n}\n\nfunction resolveDamping(value: number | undefined, fallback: number): number {\n return Number.isFinite(value) && value! >= 0 ? value! : fallback;\n}\n\nfunction resolveFrictionStop(value: number | undefined): number {\n return Number.isFinite(value) && value! >= 0 ? value! : DEFAULT_FRICTION_STOP;\n}\n\nfunction viewsEqual(a: PanoViewState, b: PanoViewState): boolean {\n return a.yaw === b.yaw && a.pitch === b.pitch && a.fov === b.fov;\n}\n\n/**\n * Internal canvas host for view following, inertia, and interaction locks.\n * Not part of the public API — input is provided by Mouse/Touch/Keyboard.\n */\nexport const PanoramaViewRuntime = forwardRef<\n PanoramaViewRuntimeHandle,\n PanoramaViewRuntimeProps\n>(function PanoramaViewRuntime(\n { initialView, minFov, maxFov, options, eventBus },\n ref,\n) {\n const { camera } = useThree();\n const viewRef = useRef<PanoViewState>({ ...initialView });\n const targetViewRef = useRef<PanoViewState>({ ...initialView });\n const initialViewRef = useRef<PanoViewState>({ ...initialView });\n const yawVelocityRef = useRef(0);\n const pitchVelocityRef = useRef(0);\n const zoomVelocityRef = useRef(0);\n const dirtyRef = useRef(true);\n const settledRef = useRef(false);\n const interactingRef = useRef(false);\n const mouseActiveRef = useRef(false);\n const touchActiveRef = useRef(false);\n const interactionLockCountRef = useRef(0);\n const keyboardActiveRef = useRef(false);\n const lastVelocitySampleAtRef = useRef<number | null>(null);\n const optionsRef = useRef(options);\n const eventBusRef = useRef(eventBus);\n const lastEmittedViewRef = useRef<PanoViewState | null>(null);\n const eulerRef = useRef(new Euler(0, 0, 0, \"YXZ\"));\n const minFovRef = useRef(minFov);\n const maxFovRef = useRef(maxFov);\n\n optionsRef.current = options;\n eventBusRef.current = eventBus;\n minFovRef.current = minFov;\n maxFovRef.current = maxFov;\n\n const hasInertia = () =>\n yawVelocityRef.current !== 0 ||\n pitchVelocityRef.current !== 0 ||\n zoomVelocityRef.current !== 0;\n\n const isUserInteracting = () =>\n mouseActiveRef.current ||\n touchActiveRef.current ||\n keyboardActiveRef.current ||\n interactionLockCountRef.current > 0 ||\n hasInertia();\n\n const syncInteracting = () => {\n interactingRef.current = mouseActiveRef.current || touchActiveRef.current;\n };\n\n const hardConstrainView = (\n view: Partial<PanoViewState>,\n current: PanoViewState = targetViewRef.current,\n ): PanoViewState => {\n return {\n yaw: normalizeYaw(view.yaw ?? current.yaw),\n pitch: clamp(view.pitch ?? current.pitch, -MAX_PITCH, MAX_PITCH),\n fov: clamp(\n view.fov ?? current.fov,\n minFovRef.current,\n maxFovRef.current,\n ),\n };\n };\n\n const softConstrainView = (\n view: Partial<PanoViewState>,\n current: PanoViewState = targetViewRef.current,\n ): PanoViewState => {\n const bouncing = optionsRef.current.bouncingLimits === true;\n if (!bouncing || !interactingRef.current) {\n return hardConstrainView(view, current);\n }\n\n const fovRange = Math.max(maxFovRef.current - minFovRef.current, 1);\n const fovOvershoot = fovRange * BOUNCE_OVERSHOOT_FOV_RATIO;\n return {\n yaw: normalizeYaw(view.yaw ?? current.yaw),\n pitch: clamp(\n view.pitch ?? current.pitch,\n -MAX_PITCH - BOUNCE_OVERSHOOT_PITCH,\n MAX_PITCH + BOUNCE_OVERSHOOT_PITCH,\n ),\n fov: clamp(\n view.fov ?? current.fov,\n minFovRef.current - fovOvershoot,\n maxFovRef.current + fovOvershoot,\n ),\n };\n };\n\n const stopVelocity = () => {\n yawVelocityRef.current = 0;\n pitchVelocityRef.current = 0;\n zoomVelocityRef.current = 0;\n lastVelocitySampleAtRef.current = null;\n };\n\n const markDirty = () => {\n dirtyRef.current = true;\n settledRef.current = false;\n };\n\n const snapTargetToHardLimits = () => {\n const next = hardConstrainView(targetViewRef.current);\n if (\n next.yaw !== targetViewRef.current.yaw ||\n next.pitch !== targetViewRef.current.pitch ||\n next.fov !== targetViewRef.current.fov\n ) {\n targetViewRef.current = next;\n markDirty();\n }\n };\n\n const acquireInteractionLock = () => {\n interactionLockCountRef.current += 1;\n stopVelocity();\n if (mouseActiveRef.current) {\n mouseActiveRef.current = false;\n eventBusRef.current.emit(\"viewinteractionend\", { source: \"mouse\" });\n }\n if (touchActiveRef.current) {\n touchActiveRef.current = false;\n eventBusRef.current.emit(\"viewinteractionend\", { source: \"touch\" });\n }\n syncInteracting();\n\n let released = false;\n return () => {\n if (released) {\n return;\n }\n released = true;\n interactionLockCountRef.current = Math.max(\n 0,\n interactionLockCountRef.current - 1,\n );\n };\n };\n\n const setView = (\n view: Partial<PanoViewState>,\n setOptions?: SetPanoViewOptions,\n ) => {\n const nextView = hardConstrainView(view);\n targetViewRef.current = nextView;\n viewRef.current = nextView;\n if (setOptions?.immediate !== false) {\n stopVelocity();\n }\n markDirty();\n };\n\n const applyViewDelta = (\n delta: Partial<PanoViewState>,\n applyOptions?: ApplyViewDeltaOptions,\n ): boolean => {\n if (interactionLockCountRef.current > 0) {\n return false;\n }\n\n const current = targetViewRef.current;\n const nextYaw =\n delta.yaw !== undefined && Number.isFinite(delta.yaw)\n ? current.yaw + delta.yaw\n : current.yaw;\n const nextPitch =\n delta.pitch !== undefined && Number.isFinite(delta.pitch)\n ? current.pitch + delta.pitch\n : current.pitch;\n const nextFov =\n delta.fov !== undefined && Number.isFinite(delta.fov)\n ? current.fov + delta.fov\n : current.fov;\n\n targetViewRef.current = softConstrainView({\n yaw: nextYaw,\n pitch: nextPitch,\n fov: nextFov,\n });\n markDirty();\n\n if (applyOptions?.recordVelocity) {\n const now = performance.now();\n const previousAt = lastVelocitySampleAtRef.current;\n const elapsed =\n previousAt === null\n ? 1 / 60\n : Math.max((now - previousAt) / 1000, 1 / 120);\n lastVelocitySampleAtRef.current = now;\n\n if (delta.yaw !== undefined && Number.isFinite(delta.yaw)) {\n yawVelocityRef.current = delta.yaw / elapsed;\n }\n if (delta.pitch !== undefined && Number.isFinite(delta.pitch)) {\n pitchVelocityRef.current = delta.pitch / elapsed;\n }\n if (delta.fov !== undefined && Number.isFinite(delta.fov)) {\n zoomVelocityRef.current = clamp(delta.fov / elapsed, -180, 180);\n }\n }\n\n return true;\n };\n\n useImperativeHandle(\n ref,\n () => ({\n getView: () => ({ ...viewRef.current }),\n getTargetView: () => ({ ...targetViewRef.current }),\n setView,\n reset: () => setView(initialViewRef.current),\n applyViewDelta,\n setKeyboardActive: (active: boolean) => {\n const wasActive = keyboardActiveRef.current;\n keyboardActiveRef.current = active;\n if (active && !wasActive) {\n eventBusRef.current.emit(\"viewinteractionstart\", {\n source: \"keyboard\",\n });\n } else if (!active && wasActive) {\n eventBusRef.current.emit(\"viewinteractionend\", {\n source: \"keyboard\",\n });\n }\n },\n setPointerActive: (source, active) => {\n const wasActive =\n source === \"mouse\"\n ? mouseActiveRef.current\n : touchActiveRef.current;\n if (source === \"mouse\") {\n mouseActiveRef.current = active;\n } else {\n touchActiveRef.current = active;\n }\n syncInteracting();\n if (active && !wasActive) {\n eventBusRef.current.emit(\"viewinteractionstart\", { source });\n } else if (!active && wasActive) {\n eventBusRef.current.emit(\"viewinteractionend\", { source });\n }\n if (active) {\n stopVelocity();\n } else if (!mouseActiveRef.current && !touchActiveRef.current) {\n lastVelocitySampleAtRef.current = null;\n snapTargetToHardLimits();\n }\n },\n isInteractionLocked: () => interactionLockCountRef.current > 0,\n isUserInteracting,\n acquireInteractionLock,\n applyAutoRotation: (yawDelta: number) => {\n const inertiaFinished =\n yawVelocityRef.current === 0 &&\n pitchVelocityRef.current === 0 &&\n zoomVelocityRef.current === 0;\n if (\n !Number.isFinite(yawDelta) ||\n interactionLockCountRef.current > 0 ||\n interactingRef.current ||\n keyboardActiveRef.current ||\n !inertiaFinished\n ) {\n return false;\n }\n\n targetViewRef.current.yaw += yawDelta;\n markDirty();\n return true;\n },\n }),\n [],\n );\n\n useEffect(() => {\n initialViewRef.current = { ...initialView };\n setView(initialView);\n }, [initialView.fov, initialView.pitch, initialView.yaw]);\n\n useFrame((_, deltaSeconds) => {\n if (!(camera instanceof PerspectiveCamera)) {\n return;\n }\n\n const frictionStop = resolveFrictionStop(optionsRef.current.frictionStop);\n const inertiaEnabled = optionsRef.current.inertia !== false;\n if (!interactingRef.current && inertiaEnabled) {\n const rotationDamping = Math.exp(\n -INERTIA_ROTATION_DAMPING * deltaSeconds,\n );\n const zoomDamping = Math.exp(-INERTIA_ZOOM_DAMPING * deltaSeconds);\n\n if (Math.abs(yawVelocityRef.current) >= frictionStop) {\n targetViewRef.current.yaw += yawVelocityRef.current * deltaSeconds;\n yawVelocityRef.current *= rotationDamping;\n markDirty();\n } else {\n yawVelocityRef.current = 0;\n }\n\n if (Math.abs(pitchVelocityRef.current) >= frictionStop) {\n targetViewRef.current.pitch += pitchVelocityRef.current * deltaSeconds;\n pitchVelocityRef.current *= rotationDamping;\n markDirty();\n } else {\n pitchVelocityRef.current = 0;\n }\n\n if (Math.abs(zoomVelocityRef.current) >= frictionStop) {\n targetViewRef.current.fov += zoomVelocityRef.current * deltaSeconds;\n zoomVelocityRef.current *= zoomDamping;\n markDirty();\n } else {\n zoomVelocityRef.current = 0;\n }\n } else if (!inertiaEnabled) {\n stopVelocity();\n }\n\n if (!interactingRef.current) {\n targetViewRef.current = hardConstrainView(targetViewRef.current);\n } else {\n targetViewRef.current = softConstrainView(targetViewRef.current);\n }\n\n if (!dirtyRef.current) {\n return;\n }\n\n const targetView = targetViewRef.current;\n const rotateDamping = resolveDamping(\n optionsRef.current.rotateDamping,\n DEFAULT_ROTATE_DAMPING,\n );\n const zoomDamping = resolveDamping(\n optionsRef.current.zoomDamping,\n DEFAULT_ZOOM_DAMPING,\n );\n const rotationFactor = dampingFactor(rotateDamping, deltaSeconds);\n const zoomFactor = dampingFactor(zoomDamping, deltaSeconds);\n const yawDelta = shortestYawDelta(viewRef.current.yaw, targetView.yaw);\n const smoothedView = {\n yaw: normalizeYaw(viewRef.current.yaw + yawDelta * rotationFactor),\n pitch:\n viewRef.current.pitch +\n (targetView.pitch - viewRef.current.pitch) * rotationFactor,\n fov:\n viewRef.current.fov +\n (targetView.fov - viewRef.current.fov) * zoomFactor,\n };\n const hasSettled =\n Math.abs(shortestYawDelta(smoothedView.yaw, targetView.yaw)) <\n VIEW_SETTLE_EPSILON &&\n Math.abs(smoothedView.pitch - targetView.pitch) < VIEW_SETTLE_EPSILON &&\n Math.abs(smoothedView.fov - targetView.fov) < VIEW_SETTLE_EPSILON;\n viewRef.current = hasSettled ? { ...targetView } : smoothedView;\n eulerRef.current.set(\n MathUtils.degToRad(viewRef.current.pitch),\n MathUtils.degToRad(-viewRef.current.yaw),\n 0,\n \"YXZ\",\n );\n camera.quaternion.setFromEuler(eulerRef.current);\n camera.fov = viewRef.current.fov;\n camera.updateProjectionMatrix();\n camera.updateMatrixWorld();\n\n const nextView = { ...viewRef.current };\n const lastEmitted = lastEmittedViewRef.current;\n if (!lastEmitted || !viewsEqual(lastEmitted, nextView)) {\n lastEmittedViewRef.current = nextView;\n eventBusRef.current.emit(\"viewchange\", nextView);\n }\n\n const wasSettled = settledRef.current;\n settledRef.current = hasSettled;\n if (hasSettled && !wasSettled) {\n eventBusRef.current.emit(\"viewsettled\", nextView);\n }\n\n dirtyRef.current = !hasSettled;\n });\n\n return null;\n});\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { CSSProperties, ReactNode } from \"react\";\n\ntype HotspotActivationEvent = KeyboardEvent | MouseEvent;\n\ntype HotspotAccessibilityEntry = {\n id: string;\n label: string;\n token: symbol;\n activate: (event: HotspotActivationEvent) => void;\n onFocusChange: (focused: boolean) => void;\n};\n\ntype HotspotAccessibilityRegistry = {\n register: (\n entry: Omit<HotspotAccessibilityEntry, \"token\">,\n ) => () => void;\n};\n\nexport const HotspotAccessibilityContext =\n createContext<HotspotAccessibilityRegistry | null>(null);\n\nconst VISUALLY_HIDDEN_STYLE: CSSProperties = {\n border: 0,\n clip: \"rect(0 0 0 0)\",\n clipPath: \"inset(50%)\",\n height: 1,\n margin: -1,\n overflow: \"hidden\",\n padding: 0,\n position: \"absolute\",\n whiteSpace: \"nowrap\",\n width: 1,\n};\n\nfunction warnAboutMissingLabel(id: string) {\n const nodeEnv = (\n globalThis as typeof globalThis & {\n process?: { env?: { NODE_ENV?: string } };\n }\n ).process?.env?.NODE_ENV;\n if (nodeEnv !== \"production\") {\n console.warn(\n `Hotspot \"${id}\" is clickable but has no ariaLabel, so it is unavailable to keyboard and screen-reader users.`,\n );\n }\n}\n\nexport function useHotspotAccessibility({\n id,\n ariaLabel,\n onActivate,\n}: {\n id: string;\n ariaLabel?: string;\n onActivate?: (event: HotspotActivationEvent) => void;\n}): boolean {\n const registry = useContext(HotspotAccessibilityContext);\n const [focused, setFocused] = useState(false);\n const activateRef = useRef(onActivate);\n const enabled = Boolean(onActivate);\n activateRef.current = onActivate;\n\n useEffect(() => {\n if (!enabled) {\n setFocused(false);\n return;\n }\n if (!ariaLabel) {\n warnAboutMissingLabel(id);\n return;\n }\n if (!registry) {\n return;\n }\n\n return registry.register({\n id,\n label: ariaLabel,\n activate: (event) => activateRef.current?.(event),\n onFocusChange: setFocused,\n });\n }, [ariaLabel, enabled, id, registry]);\n\n return focused;\n}\n\nexport function useHotspotAccessibilityLayer(): {\n controls: ReactNode;\n registry: HotspotAccessibilityRegistry;\n} {\n const [entries, setEntries] = useState<\n Map<string, HotspotAccessibilityEntry>\n >(() => new Map());\n\n const register = useCallback(\n (entry: Omit<HotspotAccessibilityEntry, \"token\">) => {\n const token = Symbol(entry.id);\n const nextEntry: HotspotAccessibilityEntry = { ...entry, token };\n setEntries((current) => {\n const next = new Map(current);\n next.set(entry.id, nextEntry);\n return next;\n });\n\n return () => {\n setEntries((current) => {\n if (current.get(entry.id)?.token !== token) {\n return current;\n }\n const next = new Map(current);\n next.delete(entry.id);\n return next;\n });\n };\n },\n [],\n );\n\n const registry = useMemo<HotspotAccessibilityRegistry>(\n () => ({ register }),\n [register],\n );\n const controls = useMemo(\n () => (\n <div aria-label=\"Panorama hotspots\" style={{ pointerEvents: \"none\" }}>\n {Array.from(entries.values()).map((entry) => (\n <button\n aria-label={entry.label}\n key={entry.id}\n onBlur={() => entry.onFocusChange(false)}\n onClick={(event) => entry.activate(event.nativeEvent)}\n onFocus={() => entry.onFocusChange(true)}\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n entry.activate(event.nativeEvent);\n }\n }}\n style={VISUALLY_HIDDEN_STYLE}\n type=\"button\"\n >\n {entry.label}\n </button>\n ))}\n </div>\n ),\n [entries],\n );\n\n return { controls, registry };\n}\n","import { useFrame, useThree } from \"@react-three/fiber\";\nimport { useContext, useEffect, useMemo, useRef } from \"react\";\nimport { PanoramaViewContext } from \"./panorama-view-runtime\";\n\nconst DEFAULT_ROTATE_SPEED = 60;\nconst DEFAULT_ZOOM_SPEED = 30;\nconst DEFAULT_SHIFT_MULTIPLIER = 3;\n\nexport type KeyboardControlAction =\n | \"left\"\n | \"right\"\n | \"up\"\n | \"down\"\n | \"zoomIn\"\n | \"zoomOut\"\n | \"previousScene\"\n | \"nextScene\"\n | \"reset\";\n\nexport type KeyboardControlKeys = Partial<\n Record<KeyboardControlAction, string | readonly string[]>\n>;\n\n/** Options for keyboard-driven panorama navigation. */\nexport type KeyboardControlsProps = {\n /** Whether keyboard handling is active. Defaults to true. */\n enabled?: boolean;\n /**\n * Custom key bindings. Each action accepts a key, code, or list of either.\n * Matching is case-insensitive for `event.key` and exact for `event.code`.\n */\n keys?: KeyboardControlKeys;\n /** Yaw/pitch change rate in degrees per second. Defaults to 60. */\n rotateSpeed?: number;\n /** FOV change rate in degrees per second. Defaults to 30. */\n zoomSpeed?: number;\n /** Speed multiplier while Shift is held. Defaults to 3. */\n shiftMultiplier?: number;\n /** Inverts up/down look direction. Defaults to false. */\n invert?: boolean;\n /**\n * Maximum FOV change rate in degrees per second. When omitted, no extra\n * rate cap is applied. Usually supplied by PanoView from `controls.fovSpeed`.\n */\n fovSpeed?: number;\n /** Called once when the previous-scene binding is pressed. */\n onPreviousScene?: () => void;\n /** Called once when the next-scene binding is pressed. */\n onNextScene?: () => void;\n};\n\nconst DEFAULT_KEYS: Record<KeyboardControlAction, readonly string[]> = {\n left: [\"ArrowLeft\"],\n right: [\"ArrowRight\"],\n up: [\"ArrowUp\"],\n down: [\"ArrowDown\"],\n zoomIn: [\"+\", \"=\"],\n zoomOut: [\"-\", \"_\"],\n previousScene: [\"[\", \"PageUp\"],\n nextScene: [\"]\", \"PageDown\"],\n reset: [\"0\"],\n};\n\nconst CONTINUOUS_ACTIONS = new Set<KeyboardControlAction>([\n \"left\",\n \"right\",\n \"up\",\n \"down\",\n \"zoomIn\",\n \"zoomOut\",\n]);\n\nfunction normalizeBinding(value: string | readonly string[] | undefined): string[] {\n if (value === undefined) {\n return [];\n }\n return (typeof value === \"string\" ? [value] : [...value]).filter(\n (entry) => entry.length > 0,\n );\n}\n\nfunction resolveKeyMap(\n overrides: KeyboardControlKeys | undefined,\n): Map<string, KeyboardControlAction> {\n const map = new Map<string, KeyboardControlAction>();\n for (const action of Object.keys(DEFAULT_KEYS) as KeyboardControlAction[]) {\n const bindings =\n overrides && action in overrides\n ? normalizeBinding(overrides[action])\n : [...DEFAULT_KEYS[action]];\n for (const binding of bindings) {\n map.set(binding.toLowerCase(), action);\n }\n }\n return map;\n}\n\nfunction matchAction(\n event: KeyboardEvent,\n keyMap: Map<string, KeyboardControlAction>,\n): KeyboardControlAction | null {\n return (\n keyMap.get(event.key.toLowerCase()) ??\n keyMap.get(event.code.toLowerCase()) ??\n null\n );\n}\n\nfunction resolveSpeed(value: number | undefined, fallback: number): number {\n return Number.isFinite(value) && value! >= 0 ? value! : fallback;\n}\n\n/**\n * Returns the scene id `step` positions away from `activeSceneId` in\n * `scenes`, wrapping at both ends. Returns `null` when the list is empty or\n * the active id is missing.\n */\nexport function cycleSceneId(\n scenes: readonly { id: string }[],\n activeSceneId: string,\n step: 1 | -1,\n): string | null {\n if (scenes.length === 0) {\n return null;\n }\n const index = scenes.findIndex((scene) => scene.id === activeSceneId);\n if (index < 0) {\n return null;\n }\n const nextIndex = (index + step + scenes.length) % scenes.length;\n return scenes[nextIndex]?.id ?? null;\n}\n\n/**\n * Adds keyboard navigation to the nearest PanoView. PanoView mounts a default\n * instance; render your own to customize bindings or scene callbacks. Hold\n * movement/zoom keys for continuous motion; scene and reset bindings fire once\n * per key press.\n */\nexport function KeyboardControls({\n enabled = true,\n keys,\n rotateSpeed = DEFAULT_ROTATE_SPEED,\n zoomSpeed = DEFAULT_ZOOM_SPEED,\n shiftMultiplier = DEFAULT_SHIFT_MULTIPLIER,\n invert = false,\n fovSpeed,\n onPreviousScene,\n onNextScene,\n}: KeyboardControlsProps) {\n const controlsRef = useContext(PanoramaViewContext);\n const { gl } = useThree();\n const pressedRef = useRef(new Set<KeyboardControlAction>());\n const shiftHeldRef = useRef(false);\n const invertRef = useRef(invert);\n const fovSpeedRef = useRef(fovSpeed);\n const onPreviousSceneRef = useRef(onPreviousScene);\n const onNextSceneRef = useRef(onNextScene);\n const keyMap = useMemo(() => resolveKeyMap(keys), [keys]);\n\n if (!controlsRef) {\n throw new Error(\"<KeyboardControls> must be rendered inside <PanoView>.\");\n }\n\n invertRef.current = invert;\n fovSpeedRef.current = fovSpeed;\n onPreviousSceneRef.current = onPreviousScene;\n onNextSceneRef.current = onNextScene;\n\n useEffect(() => {\n const element = gl.domElement;\n if (!enabled) {\n pressedRef.current.clear();\n shiftHeldRef.current = false;\n controlsRef.current?.setKeyboardActive(false);\n return;\n }\n\n const syncKeyboardActive = () => {\n let continuous = false;\n for (const action of pressedRef.current) {\n if (CONTINUOUS_ACTIONS.has(action)) {\n continuous = true;\n break;\n }\n }\n controlsRef.current?.setKeyboardActive(continuous);\n };\n\n const clearPressed = () => {\n pressedRef.current.clear();\n shiftHeldRef.current = false;\n controlsRef.current?.setKeyboardActive(false);\n };\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Shift\") {\n shiftHeldRef.current = true;\n }\n\n const action = matchAction(event, keyMap);\n if (!action) {\n return;\n }\n\n if (controlsRef.current?.isInteractionLocked()) {\n return;\n }\n\n event.preventDefault();\n\n if (action === \"reset\") {\n if (!event.repeat) {\n controlsRef.current?.reset();\n }\n return;\n }\n\n if (action === \"previousScene\") {\n if (!event.repeat) {\n onPreviousSceneRef.current?.();\n }\n return;\n }\n\n if (action === \"nextScene\") {\n if (!event.repeat) {\n onNextSceneRef.current?.();\n }\n return;\n }\n\n pressedRef.current.add(action);\n syncKeyboardActive();\n };\n\n const onKeyUp = (event: KeyboardEvent) => {\n if (event.key === \"Shift\") {\n shiftHeldRef.current = false;\n }\n\n const action = matchAction(event, keyMap);\n if (!action || !CONTINUOUS_ACTIONS.has(action)) {\n return;\n }\n\n pressedRef.current.delete(action);\n syncKeyboardActive();\n };\n\n const onBlur = () => {\n clearPressed();\n };\n\n element.addEventListener(\"keydown\", onKeyDown);\n element.addEventListener(\"keyup\", onKeyUp);\n element.addEventListener(\"blur\", onBlur);\n window.addEventListener(\"blur\", onBlur);\n\n return () => {\n element.removeEventListener(\"keydown\", onKeyDown);\n element.removeEventListener(\"keyup\", onKeyUp);\n element.removeEventListener(\"blur\", onBlur);\n window.removeEventListener(\"blur\", onBlur);\n clearPressed();\n };\n }, [controlsRef, enabled, gl, keyMap]);\n\n useFrame((_, deltaSeconds) => {\n if (!enabled || pressedRef.current.size === 0) {\n return;\n }\n\n const controls = controlsRef.current;\n if (!controls) {\n return;\n }\n\n const multiplier = shiftHeldRef.current\n ? resolveSpeed(shiftMultiplier, DEFAULT_SHIFT_MULTIPLIER)\n : 1;\n const rotation =\n resolveSpeed(rotateSpeed, DEFAULT_ROTATE_SPEED) * multiplier * deltaSeconds;\n let zoom =\n resolveSpeed(zoomSpeed, DEFAULT_ZOOM_SPEED) * multiplier * deltaSeconds;\n const fovCap = fovSpeedRef.current;\n if (Number.isFinite(fovCap) && fovCap! >= 0) {\n zoom = Math.min(zoom, fovCap! * deltaSeconds);\n }\n\n const pitchSign = invertRef.current ? -1 : 1;\n let yaw = 0;\n let pitch = 0;\n let fov = 0;\n\n for (const action of pressedRef.current) {\n switch (action) {\n case \"left\":\n yaw -= rotation;\n break;\n case \"right\":\n yaw += rotation;\n break;\n case \"up\":\n pitch += pitchSign * rotation;\n break;\n case \"down\":\n pitch -= pitchSign * rotation;\n break;\n case \"zoomIn\":\n fov -= zoom;\n break;\n case \"zoomOut\":\n fov += zoom;\n break;\n case \"previousScene\":\n case \"nextScene\":\n case \"reset\":\n break;\n default: {\n const _exhaustive: never = action;\n void _exhaustive;\n break;\n }\n }\n }\n\n if (yaw !== 0 || pitch !== 0 || fov !== 0) {\n controls.applyViewDelta({ yaw, pitch, fov });\n }\n });\n\n return null;\n}\n","import { useThree } from \"@react-three/fiber\";\nimport { useContext, useEffect, useRef } from \"react\";\nimport { PanoramaViewContext } from \"./panorama-view-runtime\";\nimport type { MouseControlButton, MouseControlsOptions } from \"./types\";\n\nconst DEFAULT_ROTATE_SPEED = 0.35;\nconst DEFAULT_ZOOM_SPEED = 0.08;\n\nconst BUTTON_FLAG: Record<MouseControlButton, number> = {\n left: 0,\n middle: 1,\n right: 2,\n};\n\nexport type MouseControlsProps = MouseControlsOptions & {\n /**\n * Maximum FOV change rate in degrees per second for wheel zoom. When\n * omitted, no extra rate cap is applied. Usually supplied by PanoView from\n * `controls.fovSpeed`.\n */\n fovSpeed?: number;\n};\n\nfunction resolveSpeed(value: number | undefined, fallback: number): number {\n return Number.isFinite(value) && value! >= 0 ? value! : fallback;\n}\n\nfunction resolveButtons(\n buttons: readonly MouseControlButton[] | undefined,\n): Set<number> {\n const list = buttons && buttons.length > 0 ? buttons : ([\"left\"] as const);\n return new Set(list.map((button) => BUTTON_FLAG[button]));\n}\n\n/**\n * Adds mouse (and pen) drag / wheel navigation to the nearest PanoView.\n * PanoView mounts a default instance; render your own only to override.\n */\nexport function MouseControls({\n enabled = true,\n rotateSpeed = DEFAULT_ROTATE_SPEED,\n zoomSpeed = DEFAULT_ZOOM_SPEED,\n wheel = true,\n invert = false,\n buttons,\n fovSpeed,\n}: MouseControlsProps) {\n const controlsRef = useContext(PanoramaViewContext);\n const { gl } = useThree();\n const pointersRef = useRef(\n new Map<number, { x: number; y: number; at: number }>(),\n );\n const optionsRef = useRef({\n rotateSpeed,\n zoomSpeed,\n wheel,\n invert,\n fovSpeed,\n });\n\n if (!controlsRef) {\n throw new Error(\"<MouseControls> must be rendered inside <PanoView>.\");\n }\n\n optionsRef.current = {\n rotateSpeed,\n zoomSpeed,\n wheel,\n invert,\n fovSpeed,\n };\n\n useEffect(() => {\n const element = gl.domElement;\n const allowedButtons = resolveButtons(buttons);\n\n const clearPointers = () => {\n for (const pointerId of pointersRef.current.keys()) {\n if (element.hasPointerCapture?.(pointerId)) {\n element.releasePointerCapture?.(pointerId);\n }\n }\n pointersRef.current.clear();\n controlsRef.current?.setPointerActive(\"mouse\", false);\n };\n\n if (!enabled) {\n clearPointers();\n return;\n }\n\n const isMouseLike = (event: PointerEvent) =>\n event.pointerType === \"mouse\" || event.pointerType === \"pen\";\n\n const syncActive = () => {\n controlsRef.current?.setPointerActive(\n \"mouse\",\n pointersRef.current.size > 0,\n );\n };\n\n const onPointerDown = (event: PointerEvent) => {\n if (!isMouseLike(event)) {\n return;\n }\n if (controlsRef.current?.isInteractionLocked()) {\n return;\n }\n if (!allowedButtons.has(event.button)) {\n return;\n }\n\n event.preventDefault();\n pointersRef.current.set(event.pointerId, {\n x: event.clientX,\n y: event.clientY,\n at: performance.now(),\n });\n element.setPointerCapture?.(event.pointerId);\n syncActive();\n };\n\n const onPointerMove = (event: PointerEvent) => {\n if (!isMouseLike(event)) {\n return;\n }\n if (controlsRef.current?.isInteractionLocked()) {\n return;\n }\n const previous = pointersRef.current.get(event.pointerId);\n if (!previous) {\n return;\n }\n\n event.preventDefault();\n const next = {\n x: event.clientX,\n y: event.clientY,\n at: performance.now(),\n };\n pointersRef.current.set(event.pointerId, next);\n\n const rect = element.getBoundingClientRect();\n const speed = resolveSpeed(\n optionsRef.current.rotateSpeed,\n DEFAULT_ROTATE_SPEED,\n );\n const sign = optionsRef.current.invert ? -1 : 1;\n const deltaYaw =\n (sign * -(next.x - previous.x) * 360 * speed) /\n Math.max(rect.width, 1);\n const deltaPitch =\n (sign * (next.y - previous.y) * 180 * speed) /\n Math.max(rect.height, 1);\n\n controlsRef.current?.applyViewDelta(\n { yaw: deltaYaw, pitch: deltaPitch },\n { recordVelocity: true },\n );\n };\n\n const releasePointer = (event: PointerEvent) => {\n if (!pointersRef.current.has(event.pointerId)) {\n return;\n }\n pointersRef.current.delete(event.pointerId);\n if (element.hasPointerCapture?.(event.pointerId)) {\n element.releasePointerCapture?.(event.pointerId);\n }\n syncActive();\n };\n\n const onWheel = (event: WheelEvent) => {\n if (!optionsRef.current.wheel) {\n return;\n }\n if (controlsRef.current?.isInteractionLocked()) {\n event.preventDefault();\n return;\n }\n event.preventDefault();\n\n const speed = resolveSpeed(\n optionsRef.current.zoomSpeed,\n DEFAULT_ZOOM_SPEED,\n );\n let delta = event.deltaY * speed;\n const cap = optionsRef.current.fovSpeed;\n if (Number.isFinite(cap) && cap! > 0) {\n delta = Math.max(-cap!, Math.min(cap!, delta));\n }\n\n controlsRef.current?.applyViewDelta(\n { fov: delta },\n { recordVelocity: true },\n );\n };\n\n element.addEventListener(\"pointerdown\", onPointerDown);\n element.addEventListener(\"pointermove\", onPointerMove);\n element.addEventListener(\"pointerup\", releasePointer);\n element.addEventListener(\"pointercancel\", releasePointer);\n element.addEventListener(\"wheel\", onWheel, { passive: false });\n\n return () => {\n element.removeEventListener(\"pointerdown\", onPointerDown);\n element.removeEventListener(\"pointermove\", onPointerMove);\n element.removeEventListener(\"pointerup\", releasePointer);\n element.removeEventListener(\"pointercancel\", releasePointer);\n element.removeEventListener(\"wheel\", onWheel);\n clearPointers();\n };\n }, [buttons, controlsRef, enabled, gl]);\n\n return null;\n}\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type {\n CSSProperties,\n KeyboardEvent as ReactKeyboardEvent,\n MouseEvent as ReactMouseEvent,\n ReactElement,\n ReactNode,\n} from \"react\";\nimport type { PanoramaPointerEvent } from \"./hotspot/types\";\nimport { PanoEventBusContext } from \"./pano-event-bus\";\nimport { PanoramaViewContext } from \"./panorama-view-runtime\";\nimport type { PanoViewState } from \"./types\";\n\nconst DEFAULT_ICON_SIZE = 16;\nconst MENU_EDGE_PADDING = 8;\n\n/** Lowest allowed `appearance.opacity` (background only). */\nexport const MIN_PANO_CONTEXT_MENU_BACKGROUND_OPACITY = 0.4;\n\nexport type PanoContextMenuSelectContext = {\n position: PanoramaPointerEvent[\"position\"];\n view: PanoViewState;\n nativeEvent: MouseEvent | PointerEvent;\n close: () => void;\n};\n\nexport type PanoContextMenuActionItem = {\n type?: \"item\";\n id: string;\n label: string;\n /** React icon node (inline SVG, icon library component, emoji, etc.). */\n icon?: ReactNode;\n /** Image URL; ignored when `icon` is set. */\n image?: string;\n imageAlt?: string;\n disabled?: boolean;\n hidden?: boolean;\n className?: string;\n style?: CSSProperties;\n onSelect: (context: PanoContextMenuSelectContext) => void;\n};\n\nexport type PanoContextMenuSeparatorItem = {\n type: \"separator\";\n id?: string;\n className?: string;\n style?: CSSProperties;\n};\n\nexport type PanoContextMenuItem =\n | PanoContextMenuActionItem\n | PanoContextMenuSeparatorItem;\n\n/** Built-in menu entries hosts can reuse without reimplementing behavior. */\nexport type PanoContextMenuPresetId =\n | \"resetView\"\n | \"fullscreen\"\n | \"separator\";\n\n/**\n * Reference a built-in preset, optionally overriding presentation fields.\n * Action wiring (reset / fullscreen toggle and enter/exit label) stays built-in.\n */\nexport type PanoContextMenuPresetRef = {\n preset: PanoContextMenuPresetId;\n id?: string;\n label?: string;\n className?: string;\n style?: CSSProperties;\n disabled?: boolean;\n hidden?: boolean;\n};\n\n/** A custom action item, a preset id string, or a preset ref with overrides. */\nexport type PanoContextMenuEntry =\n | PanoContextMenuActionItem\n | PanoContextMenuPresetId\n | PanoContextMenuPresetRef;\n\nexport type PanoContextMenuAppearance = {\n background?: string;\n color?: string;\n border?: string;\n borderRadius?: number | string;\n shadow?: string;\n /**\n * Background-only opacity from {@link MIN_PANO_CONTEXT_MENU_BACKGROUND_OPACITY}\n * to 1. Defaults to 1. Text and icons stay fully opaque.\n */\n opacity?: number;\n fontSize?: number | string;\n minWidth?: number | string;\n padding?: number | string;\n iconSize?: number;\n itemPadding?: string;\n itemHoverBackground?: string;\n itemDisabledColor?: string;\n separatorColor?: string;\n separatorMargin?: string;\n};\n\nexport type PanoContextMenuRenderProps = {\n event: PanoramaPointerEvent;\n view: PanoViewState;\n close: () => void;\n};\n\nexport type PanoContextMenuProps = {\n /**\n * Menu entries. May mix concrete items with built-in presets\n * (`\"resetView\"`, `\"fullscreen\"`, `\"separator\"`). When omitted, the\n * default Reset view / Fullscreen list is used (see also `prepend` /\n * `append`).\n */\n items?: readonly PanoContextMenuEntry[];\n /**\n * Entries placed before the default menu when `items` is omitted.\n * Ignored when `items` is provided.\n */\n prepend?: readonly PanoContextMenuEntry[];\n /**\n * Entries placed after the default menu when `items` is omitted.\n * Ignored when `items` is provided.\n */\n append?: readonly PanoContextMenuEntry[];\n appearance?: PanoContextMenuAppearance;\n className?: string;\n style?: CSSProperties;\n itemClassName?: string;\n separatorClassName?: string;\n /**\n * Fully custom menu content. When provided, takes precedence over `items`.\n * Opening, closing, and positioning remain handled by PanoContextMenu.\n */\n children?: (props: PanoContextMenuRenderProps) => ReactNode;\n};\n\ntype ContextMenuSession = {\n key: string;\n event: PanoramaPointerEvent;\n view: PanoViewState;\n render: () => ReactNode;\n};\n\ntype ContextMenuOverlayApi = {\n setSession: (session: ContextMenuSession | null) => void;\n overlayRef: { current: HTMLDivElement | null };\n};\n\nexport const PanoContextMenuOverlayContext =\n createContext<ContextMenuOverlayApi | null>(null);\n\nconst DEFAULT_APPEARANCE: Required<\n Pick<\n PanoContextMenuAppearance,\n | \"background\"\n | \"color\"\n | \"border\"\n | \"borderRadius\"\n | \"shadow\"\n | \"opacity\"\n | \"fontSize\"\n | \"minWidth\"\n | \"padding\"\n | \"iconSize\"\n | \"itemPadding\"\n | \"itemHoverBackground\"\n | \"itemDisabledColor\"\n | \"separatorColor\"\n | \"separatorMargin\"\n >\n> = {\n background: \"#161616\",\n color: \"#f4f4f4\",\n border: \"1px solid #2e2e2e\",\n borderRadius: 8,\n shadow: \"0 8px 24px rgba(0, 0, 0, 0.45)\",\n opacity: 1,\n fontSize: 13,\n minWidth: 180,\n padding: 4,\n iconSize: DEFAULT_ICON_SIZE,\n itemPadding: \"6px 10px\",\n itemHoverBackground: \"#2a2a2a\",\n itemDisabledColor: \"#777777\",\n separatorColor: \"#333333\",\n separatorMargin: \"4px 6px\",\n};\n\nfunction clampBackgroundOpacity(value: number | undefined): number {\n if (!Number.isFinite(value)) {\n return DEFAULT_APPEARANCE.opacity;\n }\n return Math.min(\n 1,\n Math.max(MIN_PANO_CONTEXT_MENU_BACKGROUND_OPACITY, value!),\n );\n}\n\nfunction isActionItem(\n item: PanoContextMenuItem,\n): item is PanoContextMenuActionItem {\n return item.type !== \"separator\";\n}\n\nfunction DefaultContextMenuPanel({\n items,\n appearance,\n className,\n style,\n itemClassName,\n separatorClassName,\n selectContext,\n onRequestClose,\n}: {\n items: readonly PanoContextMenuItem[];\n appearance?: PanoContextMenuAppearance;\n className?: string;\n style?: CSSProperties;\n itemClassName?: string;\n separatorClassName?: string;\n selectContext: PanoContextMenuSelectContext;\n onRequestClose: () => void;\n}) {\n const menuRef = useRef<HTMLDivElement>(null);\n const [activeIndex, setActiveIndex] = useState(0);\n const resolved = { ...DEFAULT_APPEARANCE, ...appearance };\n const iconSize = Number.isFinite(resolved.iconSize)\n ? Math.max(0, resolved.iconSize!)\n : DEFAULT_ICON_SIZE;\n\n const visibleItems = useMemo(\n () =>\n items.filter((item) => {\n if (!isActionItem(item)) {\n return true;\n }\n return !item.hidden;\n }),\n [items],\n );\n\n const focusableIndices = useMemo(() => {\n const indices: number[] = [];\n visibleItems.forEach((item, index) => {\n if (isActionItem(item) && !item.disabled) {\n indices.push(index);\n }\n });\n return indices;\n }, [visibleItems]);\n\n useEffect(() => {\n const first = focusableIndices[0];\n setActiveIndex(first ?? 0);\n const frame = requestAnimationFrame(() => {\n const buttons = menuRef.current?.querySelectorAll<HTMLButtonElement>(\n '[role=\"menuitem\"]:not([aria-disabled=\"true\"])',\n );\n buttons?.[0]?.focus();\n });\n return () => cancelAnimationFrame(frame);\n }, [focusableIndices]);\n\n const activateItem = useCallback(\n (item: PanoContextMenuActionItem) => {\n if (item.disabled) {\n return;\n }\n item.onSelect(selectContext);\n onRequestClose();\n },\n [onRequestClose, selectContext],\n );\n\n const moveFocus = (direction: 1 | -1) => {\n if (focusableIndices.length === 0) {\n return;\n }\n const currentSlot = focusableIndices.indexOf(activeIndex);\n const nextSlot =\n currentSlot === -1\n ? 0\n : (currentSlot + direction + focusableIndices.length) %\n focusableIndices.length;\n const nextIndex = focusableIndices[nextSlot]!;\n setActiveIndex(nextIndex);\n const buttons = menuRef.current?.querySelectorAll<HTMLButtonElement>(\n '[role=\"menuitem\"]',\n );\n buttons?.[nextIndex]?.focus();\n };\n\n const handleKeyDown = (event: ReactKeyboardEvent<HTMLDivElement>) => {\n switch (event.key) {\n case \"ArrowDown\":\n event.preventDefault();\n moveFocus(1);\n break;\n case \"ArrowUp\":\n event.preventDefault();\n moveFocus(-1);\n break;\n case \"Home\": {\n event.preventDefault();\n const first = focusableIndices[0];\n if (first !== undefined) {\n setActiveIndex(first);\n const buttons = menuRef.current?.querySelectorAll<HTMLButtonElement>(\n '[role=\"menuitem\"]',\n );\n buttons?.[first]?.focus();\n }\n break;\n }\n case \"End\": {\n event.preventDefault();\n const last = focusableIndices[focusableIndices.length - 1];\n if (last !== undefined) {\n setActiveIndex(last);\n const buttons = menuRef.current?.querySelectorAll<HTMLButtonElement>(\n '[role=\"menuitem\"]',\n );\n buttons?.[last]?.focus();\n }\n break;\n }\n case \"Escape\":\n event.preventDefault();\n onRequestClose();\n break;\n case \"Enter\":\n case \" \": {\n event.preventDefault();\n const item = visibleItems[activeIndex];\n if (item && isActionItem(item)) {\n activateItem(item);\n }\n break;\n }\n default: {\n break;\n }\n }\n };\n\n const backgroundOpacity = clampBackgroundOpacity(resolved.opacity);\n const panelStyle: CSSProperties = {\n color: resolved.color,\n border: resolved.border,\n borderRadius: resolved.borderRadius,\n boxShadow: resolved.shadow,\n fontSize: resolved.fontSize,\n minWidth: resolved.minWidth,\n padding: resolved.padding,\n pointerEvents: \"auto\",\n position: \"relative\",\n userSelect: \"none\",\n ...style,\n };\n\n return (\n <div\n ref={menuRef}\n aria-label=\"Panorama context menu\"\n className={className}\n onKeyDown={handleKeyDown}\n role=\"menu\"\n style={panelStyle}\n tabIndex={-1}\n >\n <div\n aria-hidden\n style={{\n background: resolved.background,\n borderRadius: resolved.borderRadius,\n inset: 0,\n opacity: backgroundOpacity,\n pointerEvents: \"none\",\n position: \"absolute\",\n zIndex: 0,\n }}\n />\n <div style={{ position: \"relative\", zIndex: 1 }}>\n {visibleItems.map((item, index) => {\n if (!isActionItem(item)) {\n return (\n <div\n aria-hidden\n className={[separatorClassName, item.className]\n .filter(Boolean)\n .join(\" \") || undefined}\n key={item.id ?? `separator-${index}`}\n role=\"separator\"\n style={{\n background: resolved.separatorColor,\n height: 1,\n margin: resolved.separatorMargin,\n ...item.style,\n }}\n />\n );\n }\n\n const disabled = item.disabled === true;\n const iconNode = item.icon ?? (\n item.image ? (\n <img\n alt={item.imageAlt ?? \"\"}\n draggable={false}\n src={item.image}\n style={{\n display: \"block\",\n height: iconSize,\n objectFit: \"contain\",\n width: iconSize,\n }}\n />\n ) : null\n );\n\n return (\n <button\n aria-disabled={disabled || undefined}\n className={[itemClassName, item.className]\n .filter(Boolean)\n .join(\" \") || undefined}\n disabled={disabled}\n key={item.id}\n onClick={(event: ReactMouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n activateItem(item);\n }}\n onMouseEnter={(event) => {\n if (!disabled) {\n setActiveIndex(index);\n event.currentTarget.focus();\n }\n }}\n role=\"menuitem\"\n style={{\n alignItems: \"center\",\n background:\n !disabled && activeIndex === index\n ? resolved.itemHoverBackground\n : \"transparent\",\n border: \"none\",\n borderRadius: 4,\n color: disabled ? resolved.itemDisabledColor : \"inherit\",\n cursor: disabled ? \"default\" : \"pointer\",\n display: \"flex\",\n font: \"inherit\",\n gap: 8,\n padding: resolved.itemPadding,\n textAlign: \"left\",\n width: \"100%\",\n ...item.style,\n }}\n tabIndex={disabled ? -1 : activeIndex === index ? 0 : -1}\n type=\"button\"\n >\n <span\n aria-hidden\n style={{\n alignItems: \"center\",\n display: \"inline-flex\",\n flexShrink: 0,\n height: iconSize,\n justifyContent: \"center\",\n width: iconSize,\n }}\n >\n {iconNode}\n </span>\n <span style={{ flex: 1 }}>{item.label}</span>\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n\nfunction PositionedMenuShell({\n clientX,\n clientY,\n overlayElement,\n children,\n}: {\n clientX: number;\n clientY: number;\n overlayElement: HTMLDivElement | null;\n children: ReactNode;\n}) {\n const shellRef = useRef<HTMLDivElement>(null);\n const [offset, setOffset] = useState({ left: 0, top: 0 });\n\n useLayoutEffect(() => {\n const shell = shellRef.current;\n if (!overlayElement || !shell) {\n return;\n }\n\n const overlayRect = overlayElement.getBoundingClientRect();\n const menuRect = shell.getBoundingClientRect();\n const rawLeft = clientX - overlayRect.left;\n const rawTop = clientY - overlayRect.top;\n const maxLeft = Math.max(\n MENU_EDGE_PADDING,\n overlayRect.width - menuRect.width - MENU_EDGE_PADDING,\n );\n const maxTop = Math.max(\n MENU_EDGE_PADDING,\n overlayRect.height - menuRect.height - MENU_EDGE_PADDING,\n );\n\n setOffset({\n left: Math.min(Math.max(rawLeft, MENU_EDGE_PADDING), maxLeft),\n top: Math.min(Math.max(rawTop, MENU_EDGE_PADDING), maxTop),\n });\n }, [clientX, clientY, overlayElement, children]);\n\n return (\n <div\n ref={shellRef}\n style={{\n left: offset.left,\n position: \"absolute\",\n top: offset.top,\n zIndex: 20,\n }}\n >\n {children}\n </div>\n );\n}\n\n/**\n * Creates a shared context-menu overlay API for PanoView. Provide `api`\n * inside the Canvas (R3F does not inherit outer React context) and render\n * `overlay` as a DOM sibling of the Canvas.\n */\nexport function usePanoContextMenuOverlay(): {\n api: ContextMenuOverlayApi;\n overlay: ReactElement;\n} {\n const [session, setSession] = useState<ContextMenuSession | null>(null);\n const overlayRef = useRef<HTMLDivElement>(null);\n const [overlayElement, setOverlayElement] = useState<HTMLDivElement | null>(\n null,\n );\n const api = useMemo<ContextMenuOverlayApi>(\n () => ({ setSession, overlayRef }),\n [],\n );\n\n const setOverlayNode = useCallback((node: HTMLDivElement | null) => {\n overlayRef.current = node;\n setOverlayElement(node);\n }, []);\n\n useEffect(() => {\n if (!session) {\n return;\n }\n\n const handlePointerDown = (event: PointerEvent) => {\n const overlay = overlayRef.current;\n if (!overlay) {\n return;\n }\n const target = event.target;\n if (target instanceof Node && overlay.contains(target)) {\n const menuRoot = overlay.querySelector(\n '[role=\"menu\"], [data-pano-context-menu]',\n );\n if (menuRoot && menuRoot.contains(target)) {\n return;\n }\n }\n setSession(null);\n };\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n setSession(null);\n }\n };\n\n document.addEventListener(\"pointerdown\", handlePointerDown, true);\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => {\n document.removeEventListener(\"pointerdown\", handlePointerDown, true);\n document.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [session]);\n\n const overlay = (\n <div\n ref={setOverlayNode}\n aria-hidden={session ? undefined : true}\n style={{\n inset: 0,\n pointerEvents: \"none\",\n position: \"absolute\",\n zIndex: 20,\n }}\n >\n {session ? (\n <PositionedMenuShell\n clientX={session.event.clientX}\n clientY={session.event.clientY}\n key={session.key}\n overlayElement={overlayElement}\n >\n {session.render()}\n </PositionedMenuShell>\n ) : null}\n </div>\n );\n\n return { api, overlay };\n}\n\n/**\n * Custom panorama context menu. Must render inside PanoView. Prefer\n * PanoView's `contextMenu` prop for the default menu; use this component\n * when replacing the default instance (`contextMenu={false}`).\n */\nexport function PanoContextMenu({\n items,\n prepend,\n append,\n appearance,\n className,\n style,\n itemClassName,\n separatorClassName,\n children,\n}: PanoContextMenuProps): null {\n const eventBus = useContext(PanoEventBusContext);\n const controlsRef = useContext(PanoramaViewContext);\n const overlayApi = useContext(PanoContextMenuOverlayContext);\n const actions = useContext(PanoContextMenuActionsContext);\n const instanceId = useId();\n const sessionKeyRef = useRef(0);\n const propsRef = useRef({\n items,\n prepend,\n append,\n appearance,\n className,\n style,\n itemClassName,\n separatorClassName,\n children,\n });\n propsRef.current = {\n items,\n prepend,\n append,\n appearance,\n className,\n style,\n itemClassName,\n separatorClassName,\n children,\n };\n\n if (!eventBus || !controlsRef) {\n throw new Error(\"<PanoContextMenu> must be rendered inside <PanoView>.\");\n }\n if (!overlayApi) {\n throw new Error(\n \"<PanoContextMenu> requires the PanoView context-menu overlay host.\",\n );\n }\n\n const close = useCallback(() => {\n overlayApi.setSession(null);\n }, [overlayApi]);\n\n const openMenu = useCallback(\n (event: PanoramaPointerEvent) => {\n event.nativeEvent.preventDefault();\n const view = controlsRef.current?.getView() ?? {\n yaw: 0,\n pitch: 0,\n fov: 75,\n };\n const selectContext: PanoContextMenuSelectContext = {\n position: event.position,\n view,\n nativeEvent: event.nativeEvent,\n close,\n };\n const current = propsRef.current;\n sessionKeyRef.current += 1;\n const key = `${instanceId}-${sessionKeyRef.current}`;\n\n const hasCustomChildren = typeof current.children === \"function\";\n const presets = actions\n ? createPanoContextMenuPresets(actions)\n : null;\n const resolvedItems = presets\n ? composePanoContextMenuItems(current, presets)\n : current.items?.filter(isActionEntry) ?? [];\n\n if (!hasCustomChildren && resolvedItems.length === 0) {\n return;\n }\n\n overlayApi.setSession({\n key,\n event,\n view,\n render: () => {\n if (hasCustomChildren && current.children) {\n return (\n <div data-pano-context-menu style={{ pointerEvents: \"auto\" }}>\n {current.children({ event, view, close })}\n </div>\n );\n }\n return (\n <DefaultContextMenuPanel\n appearance={current.appearance}\n className={current.className}\n itemClassName={current.itemClassName}\n items={resolvedItems}\n onRequestClose={close}\n selectContext={selectContext}\n separatorClassName={current.separatorClassName}\n style={current.style}\n />\n );\n },\n });\n },\n [actions, close, controlsRef, instanceId, overlayApi],\n );\n\n useEffect(() => {\n const unsubscribeContextMenu = eventBus.subscribe(\n \"contextmenu\",\n openMenu,\n );\n const unsubscribeInteraction = eventBus.subscribe(\n \"viewinteractionstart\",\n () => {\n close();\n },\n );\n return () => {\n unsubscribeContextMenu();\n unsubscribeInteraction();\n close();\n };\n }, [close, eventBus, openMenu]);\n\n return null;\n}\n\nfunction ResetViewIcon() {\n return (\n <svg\n aria-hidden\n fill=\"none\"\n height=\"100%\"\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"1.75\"\n viewBox=\"0 0 16 16\"\n width=\"100%\"\n >\n <path d=\"M3.5 6.5A4.5 4.5 0 1 1 4 10\" />\n <path d=\"M3.5 3.5v3h3\" />\n </svg>\n );\n}\n\nfunction FullscreenIcon() {\n return (\n <svg\n aria-hidden\n fill=\"none\"\n height=\"100%\"\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"1.75\"\n viewBox=\"0 0 16 16\"\n width=\"100%\"\n >\n <path d=\"M3 6V3h3M10 3h3v3M13 10v3h-3M6 13H3v-3\" />\n </svg>\n );\n}\n\nfunction ExitFullscreenIcon() {\n return (\n <svg\n aria-hidden\n fill=\"none\"\n height=\"100%\"\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"1.75\"\n viewBox=\"0 0 16 16\"\n width=\"100%\"\n >\n <path d=\"M6 3v3H3M10 3v3h3M3 10h3v3M10 10h3v3\" />\n </svg>\n );\n}\n\nexport type PanoContextMenuPresetActions = {\n reset: () => void;\n toggleFullscreen: () => void;\n /** When true, the fullscreen preset shows Exit fullscreen. */\n isFullscreen?: boolean;\n};\n\nexport type PanoContextMenuPresets = {\n resetView: PanoContextMenuActionItem;\n fullscreen: PanoContextMenuActionItem;\n separator: (id?: string) => PanoContextMenuSeparatorItem;\n /** Default menu: Reset view, separator, Enter/Exit fullscreen. */\n defaults: PanoContextMenuItem[];\n};\n\n/**\n * Builds reusable built-in context-menu items. Prefer preset id strings\n * (`\"resetView\"`, `\"fullscreen\"`) in `items` / `append` / `prepend` when\n * configuring `PanoView`; use this helper when assembling items manually.\n */\nexport function createPanoContextMenuPresets(\n actions: PanoContextMenuPresetActions,\n): PanoContextMenuPresets {\n const isFullscreen = actions.isFullscreen === true;\n const resetView: PanoContextMenuActionItem = {\n id: \"pano-reset-view\",\n label: \"Reset view\",\n icon: <ResetViewIcon />,\n onSelect: () => {\n actions.reset();\n },\n };\n const fullscreen: PanoContextMenuActionItem = {\n id: \"pano-fullscreen\",\n label: isFullscreen ? \"Exit fullscreen\" : \"Enter fullscreen\",\n icon: isFullscreen ? <ExitFullscreenIcon /> : <FullscreenIcon />,\n onSelect: () => {\n actions.toggleFullscreen();\n },\n };\n const separator = (id = \"pano-separator\"): PanoContextMenuSeparatorItem => ({\n type: \"separator\",\n id,\n });\n\n return {\n resetView,\n fullscreen,\n separator,\n defaults: [resetView, separator(\"pano-default-separator\"), fullscreen],\n };\n}\n\n/** Alias for `createPanoContextMenuPresets(actions).defaults`. */\nexport function createDefaultPanoContextMenuItems(\n actions: PanoContextMenuPresetActions,\n): PanoContextMenuItem[] {\n return createPanoContextMenuPresets(actions).defaults;\n}\n\nfunction isPresetId(value: unknown): value is PanoContextMenuPresetId {\n return (\n value === \"resetView\" || value === \"fullscreen\" || value === \"separator\"\n );\n}\n\nfunction isPresetRef(value: unknown): value is PanoContextMenuPresetRef {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"preset\" in value &&\n isPresetId((value as PanoContextMenuPresetRef).preset)\n );\n}\n\nfunction isActionEntry(\n value: PanoContextMenuEntry,\n): value is PanoContextMenuActionItem {\n if (typeof value === \"string\") {\n return false;\n }\n if (isPresetRef(value)) {\n return false;\n }\n return true;\n}\n\nfunction applyPresetOverrides(\n item: PanoContextMenuItem,\n overrides: Omit<PanoContextMenuPresetRef, \"preset\">,\n): PanoContextMenuItem {\n if (item.type === \"separator\") {\n return {\n ...item,\n id: overrides.id ?? item.id,\n className: overrides.className ?? item.className,\n style: overrides.style ?? item.style,\n };\n }\n return {\n ...item,\n id: overrides.id ?? item.id,\n label: overrides.label ?? item.label,\n className: overrides.className ?? item.className,\n style: overrides.style ?? item.style,\n disabled: overrides.disabled ?? item.disabled,\n hidden: overrides.hidden ?? item.hidden,\n };\n}\n\nfunction resolvePresetEntry(\n entry: PanoContextMenuPresetId | PanoContextMenuPresetRef,\n presets: PanoContextMenuPresets,\n): PanoContextMenuItem {\n const presetId = typeof entry === \"string\" ? entry : entry.preset;\n const overrides: Omit<PanoContextMenuPresetRef, \"preset\"> =\n typeof entry === \"string\" ? {} : entry;\n switch (presetId) {\n case \"resetView\":\n return applyPresetOverrides(presets.resetView, overrides);\n case \"fullscreen\":\n return applyPresetOverrides(presets.fullscreen, overrides);\n case \"separator\":\n return applyPresetOverrides(\n presets.separator(overrides.id ?? \"pano-separator\"),\n overrides,\n );\n default: {\n const _exhaustive: never = presetId;\n return _exhaustive;\n }\n }\n}\n\n/**\n * Expands preset ids / refs into concrete menu items using the given presets.\n */\nexport function resolvePanoContextMenuEntries(\n entries: readonly PanoContextMenuEntry[],\n presets: PanoContextMenuPresets,\n): PanoContextMenuItem[] {\n const resolved: PanoContextMenuItem[] = [];\n for (const entry of entries) {\n if (isActionEntry(entry)) {\n resolved.push(entry);\n continue;\n }\n resolved.push(resolvePresetEntry(entry, presets));\n }\n return resolved;\n}\n\n/**\n * Resolves `items`, or `prepend` + defaults + `append` when `items` is omitted.\n */\nexport function composePanoContextMenuItems(\n props: Pick<PanoContextMenuProps, \"items\" | \"prepend\" | \"append\">,\n presets: PanoContextMenuPresets,\n): PanoContextMenuItem[] {\n if (props.items) {\n return resolvePanoContextMenuEntries(props.items, presets);\n }\n return [\n ...resolvePanoContextMenuEntries(props.prepend ?? [], presets),\n ...presets.defaults,\n ...resolvePanoContextMenuEntries(props.append ?? [], presets),\n ];\n}\n\nexport type PanoContextMenuActionsApi = PanoContextMenuPresetActions;\n\nexport const PanoContextMenuActionsContext =\n createContext<PanoContextMenuActionsApi | null>(null);\n","import { useFrame, useThree } from \"@react-three/fiber\";\nimport { useContext, useEffect, useRef } from \"react\";\nimport type { PanoramaPointerEvent } from \"./hotspot/types\";\nimport {\n PanoEventBusContext,\n type PanoResizeEvent,\n type PanoWheelEvent,\n type ViewInteractionEvent,\n} from \"./pano-event-bus\";\nimport { PanoramaViewContext } from \"./panorama-view-runtime\";\nimport type { PanoViewState } from \"./types\";\n\nconst DEFAULT_IDLE_TIME_MS = 2000;\n\nexport type PanoEventsProps = {\n /**\n * Milliseconds without user interaction before `onIdle`. Defaults to 2000.\n * Each PanoEvents instance tracks idle independently.\n */\n idleTime?: number;\n onViewChange?: (view: PanoViewState) => void;\n onViewSettled?: (view: PanoViewState) => void;\n onViewInteractionStart?: (event: ViewInteractionEvent) => void;\n onViewInteractionEnd?: (event: ViewInteractionEvent) => void;\n onClick?: (event: PanoramaPointerEvent) => void;\n onDoubleClick?: (event: PanoramaPointerEvent) => void;\n onPointerDown?: (event: PanoramaPointerEvent) => void;\n onPointerUp?: (event: PanoramaPointerEvent) => void;\n onPointerMove?: (event: PanoramaPointerEvent) => void;\n onContextMenu?: (event: PanoramaPointerEvent) => void;\n onWheel?: (event: PanoWheelEvent) => void;\n onIdle?: () => void;\n onIdleEnd?: () => void;\n onEnterFullscreen?: () => void;\n onExitFullscreen?: () => void;\n onResize?: (event: PanoResizeEvent) => void;\n onAutoRotateStart?: () => void;\n onAutoRotateStop?: () => void;\n onAutoRotateOneRound?: () => void;\n};\n\nfunction resolveIdleTime(value: number | undefined): number {\n return Number.isFinite(value) && value! >= 0 ? value! : DEFAULT_IDLE_TIME_MS;\n}\n\n/**\n * Subscribes to viewer-level panorama events. Must run inside PanoView.\n * Prefer the {@link PanoEvents} component for declarative usage.\n */\nexport function usePanoEvents({\n idleTime = DEFAULT_IDLE_TIME_MS,\n onViewChange,\n onViewSettled,\n onViewInteractionStart,\n onViewInteractionEnd,\n onClick,\n onDoubleClick,\n onPointerDown,\n onPointerUp,\n onPointerMove,\n onContextMenu,\n onWheel,\n onIdle,\n onIdleEnd,\n onEnterFullscreen,\n onExitFullscreen,\n onResize,\n onAutoRotateStart,\n onAutoRotateStop,\n onAutoRotateOneRound,\n}: PanoEventsProps): void {\n const eventBus = useContext(PanoEventBusContext);\n const controlsRef = useContext(PanoramaViewContext);\n const { gl } = useThree();\n\n if (!eventBus || !controlsRef) {\n throw new Error(\"usePanoEvents must be used inside <PanoView>.\");\n }\n\n const callbacksRef = useRef({\n onViewChange,\n onViewSettled,\n onViewInteractionStart,\n onViewInteractionEnd,\n onClick,\n onDoubleClick,\n onPointerDown,\n onPointerUp,\n onPointerMove,\n onContextMenu,\n onWheel,\n onIdle,\n onIdleEnd,\n onEnterFullscreen,\n onExitFullscreen,\n onResize,\n onAutoRotateStart,\n onAutoRotateStop,\n onAutoRotateOneRound,\n });\n callbacksRef.current = {\n onViewChange,\n onViewSettled,\n onViewInteractionStart,\n onViewInteractionEnd,\n onClick,\n onDoubleClick,\n onPointerDown,\n onPointerUp,\n onPointerMove,\n onContextMenu,\n onWheel,\n onIdle,\n onIdleEnd,\n onEnterFullscreen,\n onExitFullscreen,\n onResize,\n onAutoRotateStart,\n onAutoRotateStop,\n onAutoRotateOneRound,\n };\n\n const idleElapsedRef = useRef(0);\n const isIdleRef = useRef(false);\n const idleTimeRef = useRef(resolveIdleTime(idleTime));\n idleTimeRef.current = resolveIdleTime(idleTime);\n\n useEffect(() => {\n idleElapsedRef.current = 0;\n isIdleRef.current = false;\n }, [idleTime]);\n\n useEffect(() => {\n const unsubscribers = [\n eventBus.subscribe(\"viewchange\", (view) => {\n callbacksRef.current.onViewChange?.(view);\n }),\n eventBus.subscribe(\"viewsettled\", (view) => {\n callbacksRef.current.onViewSettled?.(view);\n }),\n eventBus.subscribe(\"viewinteractionstart\", (event) => {\n callbacksRef.current.onViewInteractionStart?.(event);\n }),\n eventBus.subscribe(\"viewinteractionend\", (event) => {\n callbacksRef.current.onViewInteractionEnd?.(event);\n }),\n eventBus.subscribe(\"click\", (event) => {\n callbacksRef.current.onClick?.(event);\n }),\n eventBus.subscribe(\"doubleclick\", (event) => {\n callbacksRef.current.onDoubleClick?.(event);\n }),\n eventBus.subscribe(\"pointerdown\", (event) => {\n callbacksRef.current.onPointerDown?.(event);\n }),\n eventBus.subscribe(\"pointerup\", (event) => {\n callbacksRef.current.onPointerUp?.(event);\n }),\n eventBus.subscribe(\"pointermove\", (event) => {\n callbacksRef.current.onPointerMove?.(event);\n }),\n eventBus.subscribe(\"contextmenu\", (event) => {\n callbacksRef.current.onContextMenu?.(event);\n }),\n eventBus.subscribe(\"autorotatestart\", () => {\n callbacksRef.current.onAutoRotateStart?.();\n }),\n eventBus.subscribe(\"autorotatestop\", () => {\n callbacksRef.current.onAutoRotateStop?.();\n }),\n eventBus.subscribe(\"autorotateoneround\", () => {\n callbacksRef.current.onAutoRotateOneRound?.();\n }),\n ];\n return () => {\n for (const unsubscribe of unsubscribers) {\n unsubscribe();\n }\n };\n }, [eventBus]);\n\n useEffect(() => {\n const element = gl.domElement;\n\n const handleWheel = (nativeEvent: WheelEvent) => {\n callbacksRef.current.onWheel?.({\n delta: nativeEvent.deltaY,\n nativeEvent,\n });\n };\n\n element.addEventListener(\"wheel\", handleWheel, { passive: true });\n return () => {\n element.removeEventListener(\"wheel\", handleWheel);\n };\n }, [gl]);\n\n useEffect(() => {\n if (typeof document === \"undefined\") {\n return;\n }\n\n const wasFullscreenRef = { current: false };\n\n const isViewerFullscreen = () => {\n const fullscreenElement = document.fullscreenElement;\n if (!fullscreenElement) {\n return false;\n }\n const canvas = gl.domElement;\n return (\n fullscreenElement === canvas ||\n fullscreenElement.contains(canvas) ||\n canvas.contains(fullscreenElement)\n );\n };\n\n const handleFullscreenChange = () => {\n const isOurs = isViewerFullscreen();\n if (isOurs && !wasFullscreenRef.current) {\n wasFullscreenRef.current = true;\n callbacksRef.current.onEnterFullscreen?.();\n } else if (!isOurs && wasFullscreenRef.current) {\n wasFullscreenRef.current = false;\n callbacksRef.current.onExitFullscreen?.();\n }\n };\n\n wasFullscreenRef.current = isViewerFullscreen();\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n return () => {\n document.removeEventListener(\"fullscreenchange\", handleFullscreenChange);\n };\n }, [gl]);\n\n useEffect(() => {\n const element = gl.domElement;\n if (typeof ResizeObserver === \"undefined\") {\n return;\n }\n\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0];\n if (!entry) {\n return;\n }\n const { width, height } = entry.contentRect;\n callbacksRef.current.onResize?.({ width, height });\n });\n observer.observe(element);\n return () => {\n observer.disconnect();\n };\n }, [gl]);\n\n useFrame((_, deltaSeconds) => {\n const interacting = controlsRef.current?.isUserInteracting() ?? false;\n if (interacting) {\n idleElapsedRef.current = 0;\n if (isIdleRef.current) {\n isIdleRef.current = false;\n callbacksRef.current.onIdleEnd?.();\n }\n return;\n }\n\n idleElapsedRef.current += deltaSeconds * 1000;\n if (\n !isIdleRef.current &&\n idleElapsedRef.current >= idleTimeRef.current\n ) {\n isIdleRef.current = true;\n callbacksRef.current.onIdle?.();\n }\n });\n}\n\n/**\n * Declarative viewer-level event listeners for the nearest PanoView.\n * Multiple instances may coexist; each tracks its own idle timer.\n */\nexport function PanoEvents(props: PanoEventsProps) {\n usePanoEvents(props);\n return null;\n}\n","import type { ThreeEvent } from \"@react-three/fiber\";\nimport { useThree } from \"@react-three/fiber\";\nimport { useContext, useEffect } from \"react\";\nimport { BackSide, Raycaster, Vector2, Vector3 } from \"three\";\nimport { vector3ToPanoPosition } from \"./hotspot/coordinates\";\nimport type { PanoramaPointerEvent } from \"./hotspot/types\";\nimport { PanoEventBusContext } from \"./pano-event-bus\";\nimport { DEFAULT_PANORAMA_RADIUS } from \"./panorama-radius\";\n\nconst EVENT_SURFACE_RADIUS = DEFAULT_PANORAMA_RADIUS - 1;\n\nfunction makePanoramaPointerEvent(\n event: ThreeEvent<MouseEvent | PointerEvent>,\n): PanoramaPointerEvent {\n const nativeEvent = event.nativeEvent;\n return {\n position: vector3ToPanoPosition(event.ray.direction),\n nativeEvent,\n pointerId:\n \"pointerId\" in nativeEvent ? nativeEvent.pointerId : undefined,\n button: nativeEvent.button,\n buttons: nativeEvent.buttons,\n clientX: nativeEvent.clientX,\n clientY: nativeEvent.clientY,\n };\n}\n\n/**\n * Invisible inward sphere that maps pointer hits to panorama yaw/pitch and\n * publishes them on the viewer event bus.\n */\nexport function PanoramaEventSurface() {\n const eventBus = useContext(PanoEventBusContext);\n const { camera, gl } = useThree();\n\n useEffect(() => {\n if (!eventBus) {\n return;\n }\n\n const element = gl.domElement;\n const ndc = new Vector2();\n const raycaster = new Raycaster();\n const direction = new Vector3();\n\n const handleContextMenu = (nativeEvent: MouseEvent) => {\n const rect = element.getBoundingClientRect();\n if (rect.width <= 0 || rect.height <= 0) {\n return;\n }\n\n ndc.set(\n ((nativeEvent.clientX - rect.left) / rect.width) * 2 - 1,\n -((nativeEvent.clientY - rect.top) / rect.height) * 2 + 1,\n );\n raycaster.setFromCamera(ndc, camera);\n direction.copy(raycaster.ray.direction);\n\n eventBus.emit(\"contextmenu\", {\n position: vector3ToPanoPosition(direction),\n nativeEvent,\n pointerId:\n \"pointerId\" in nativeEvent\n ? (nativeEvent as PointerEvent).pointerId\n : undefined,\n button: nativeEvent.button,\n buttons: nativeEvent.buttons,\n clientX: nativeEvent.clientX,\n clientY: nativeEvent.clientY,\n });\n };\n\n element.addEventListener(\"contextmenu\", handleContextMenu);\n return () => {\n element.removeEventListener(\"contextmenu\", handleContextMenu);\n };\n }, [camera, eventBus, gl]);\n\n if (!eventBus) {\n return null;\n }\n\n const emit = (\n type: \"click\" | \"doubleclick\" | \"pointerdown\" | \"pointerup\" | \"pointermove\",\n event: ThreeEvent<MouseEvent | PointerEvent>,\n ) => {\n event.stopPropagation();\n eventBus.emit(type, makePanoramaPointerEvent(event));\n };\n\n return (\n <mesh\n renderOrder={-200}\n onClick={(event) => emit(\"click\", event)}\n onDoubleClick={(event) => emit(\"doubleclick\", event)}\n onPointerDown={(event) => emit(\"pointerdown\", event)}\n onPointerUp={(event) => emit(\"pointerup\", event)}\n onPointerMove={(event) => emit(\"pointermove\", event)}\n >\n <sphereGeometry args={[EVENT_SURFACE_RADIUS, 64, 32]} />\n <meshBasicMaterial\n colorWrite={false}\n depthTest={false}\n depthWrite={false}\n opacity={0}\n side={BackSide}\n transparent\n />\n </mesh>\n );\n}\n","import { MathUtils, Vector3 } from \"three\";\nimport { MAX_HOTSPOT_PITCH } from \"./types\";\nimport type { HotspotPosition } from \"./types\";\n\nconst POLE_EPSILON_DEGREES = 1e-6;\n\nexport function normalizePanoYaw(yaw: number): number {\n if (!Number.isFinite(yaw)) {\n return 0;\n }\n return MathUtils.euclideanModulo(yaw + 180, 360) - 180;\n}\n\nexport function clampPanoPitch(pitch: number): number {\n if (!Number.isFinite(pitch)) {\n return 0;\n }\n const clamped = MathUtils.clamp(\n pitch,\n -MAX_HOTSPOT_PITCH,\n MAX_HOTSPOT_PITCH,\n );\n return Math.abs(clamped) >= MAX_HOTSPOT_PITCH - POLE_EPSILON_DEGREES\n ? Math.sign(clamped) * MAX_HOTSPOT_PITCH\n : clamped;\n}\n\nexport function normalizePanoPosition(\n position: HotspotPosition,\n): HotspotPosition {\n const pitch = clampPanoPitch(position.pitch);\n return {\n yaw: Math.abs(pitch) === MAX_HOTSPOT_PITCH\n ? 0\n : normalizePanoYaw(position.yaw),\n pitch,\n };\n}\n\nexport function panoPositionToVector3(\n position: HotspotPosition,\n radius = 1,\n): Vector3 {\n const normalized = normalizePanoPosition(position);\n const safeRadius = Number.isFinite(radius) ? Math.max(0, radius) : 1;\n const yaw = MathUtils.degToRad(normalized.yaw);\n const pitch = MathUtils.degToRad(normalized.pitch);\n const cosPitch = Math.cos(pitch);\n\n return new Vector3(\n cosPitch * Math.sin(yaw) * safeRadius,\n Math.sin(pitch) * safeRadius,\n -cosPitch * Math.cos(yaw) * safeRadius,\n );\n}\n\nexport function vector3ToPanoPosition(\n vector: Pick<Vector3, \"x\" | \"y\" | \"z\">,\n): HotspotPosition {\n const length = Math.hypot(vector.x, vector.y, vector.z);\n if (!Number.isFinite(length) || length === 0) {\n return { yaw: 0, pitch: 0 };\n }\n\n return normalizePanoPosition({\n yaw: MathUtils.radToDeg(Math.atan2(vector.x, -vector.z)),\n pitch: MathUtils.radToDeg(\n Math.asin(MathUtils.clamp(vector.y / length, -1, 1)),\n ),\n });\n}\n","export const MAX_HOTSPOT_PITCH = 90;\n\nexport type HotspotPosition = {\n /** Horizontal panorama angle in degrees. Positive values look right. */\n yaw: number;\n /** Vertical panorama angle in degrees. Positive values look up. */\n pitch: number;\n};\n\n/**\n * A safe point-hotspot rendering mode.\n *\n * `surface` attaches the visual to the panorama shell. `billboard` floats it\n * in front of the shell and keeps it facing the camera.\n */\nexport type HotspotMode = \"surface\" | \"billboard\";\n\n/** Whether a hotspot grows with panorama zoom or preserves its screen size. */\nexport type HotspotScaleMode = \"fov\" | \"fixed\";\n\nexport type HotspotInputSource = \"pointer\" | \"keyboard\";\n\nexport type HotspotInteractionEvent = {\n id: string;\n position: HotspotPosition;\n source: HotspotInputSource;\n nativeEvent: MouseEvent | PointerEvent | KeyboardEvent;\n};\n\nexport type HotspotDragEvent = HotspotInteractionEvent & {\n source: \"pointer\";\n startPosition: HotspotPosition;\n};\n\nexport type HotspotCommonProps = {\n id: string;\n position: HotspotPosition;\n /** Angular width in degrees. Defaults to 12. */\n width?: number;\n /** Angular height in degrees. Defaults to 8. */\n height?: number;\n /** Overall multiplier for the hotspot's angular width and height. Defaults to 1. */\n scale?: number;\n /** Defaults to \"billboard\". */\n mode?: HotspotMode;\n /**\n * World-space distance for `mode=\"billboard\"`. Defaults to 10 and is capped\n * when needed so the full hotspot remains inside the panorama shell.\n */\n distance?: number;\n /** FOV grows/shrinks with zoom; fixed preserves the reference screen size. */\n scaleMode?: HotspotScaleMode;\n /** Reference FOV in degrees used when scaleMode is \"fixed\". Defaults to 75. */\n referenceFov?: number;\n /** Clockwise rotation around the hotspot normal in degrees. */\n rotation?: number;\n opacity?: number;\n renderOrder?: number;\n visible?: boolean;\n /** Whether the hotspot accepts pointer and keyboard interaction. Defaults to true. */\n interactive?: boolean;\n draggable?: boolean;\n /** Required for keyboard-accessible clickable hotspots. */\n ariaLabel?: string;\n onClick?: (event: HotspotInteractionEvent) => void;\n onHoverChange?: (hovered: boolean, event: HotspotInteractionEvent) => void;\n onDragStart?: (event: HotspotDragEvent) => void;\n onPositionChange?: (event: HotspotDragEvent) => void;\n onDragEnd?: (event: HotspotDragEvent) => void;\n};\n\nexport type PanoramaPointerEvent = {\n position: HotspotPosition;\n nativeEvent: MouseEvent | PointerEvent;\n pointerId?: number;\n button: number;\n buttons: number;\n clientX: number;\n clientY: number;\n};\n","/**\n * Shared world-space radius for the built-in sphere and cube-tile panoramas.\n * Hotspots and the invisible event surface use the same scale.\n */\nexport const DEFAULT_PANORAMA_RADIUS = 1_000;\n/** Keeps depth-buffer precision stable for hotspots near the panorama shell. */\nexport const DEFAULT_PANORAMA_CAMERA_NEAR = 0.1;\nexport const DEFAULT_PANORAMA_CAMERA_FAR = DEFAULT_PANORAMA_RADIUS * 2;\n","import { useThree } from \"@react-three/fiber\";\nimport { useContext, useEffect, useRef } from \"react\";\nimport { PanoramaViewContext } from \"./panorama-view-runtime\";\nimport type { TouchControlsOptions } from \"./types\";\n\nconst DEFAULT_ROTATE_SPEED = 0.35;\n\nexport type TouchControlsProps = TouchControlsOptions;\n\ntype PointerSample = {\n x: number;\n y: number;\n at: number;\n};\n\nfunction resolveSpeed(value: number | undefined, fallback: number): number {\n return Number.isFinite(value) && value! >= 0 ? value! : fallback;\n}\n\nfunction pointerDistance(a: PointerSample, b: PointerSample): number {\n return Math.hypot(a.x - b.x, a.y - b.y);\n}\n\n/**\n * Adds touch drag and pinch-zoom navigation to the nearest PanoView.\n * PanoView mounts a default instance; render your own only to override.\n */\nexport function TouchControls({\n enabled = true,\n rotateSpeed = DEFAULT_ROTATE_SPEED,\n invert = false,\n pinchZoom = true,\n}: TouchControlsProps) {\n const controlsRef = useContext(PanoramaViewContext);\n const { gl } = useThree();\n const pointersRef = useRef(new Map<number, PointerSample>());\n const pinchDistanceRef = useRef<number | null>(null);\n const optionsRef = useRef({ rotateSpeed, invert, pinchZoom });\n\n if (!controlsRef) {\n throw new Error(\"<TouchControls> must be rendered inside <PanoView>.\");\n }\n\n optionsRef.current = { rotateSpeed, invert, pinchZoom };\n\n useEffect(() => {\n const element = gl.domElement;\n\n const clearPointers = () => {\n for (const pointerId of pointersRef.current.keys()) {\n if (element.hasPointerCapture?.(pointerId)) {\n element.releasePointerCapture?.(pointerId);\n }\n }\n pointersRef.current.clear();\n pinchDistanceRef.current = null;\n controlsRef.current?.setPointerActive(\"touch\", false);\n };\n\n if (!enabled) {\n clearPointers();\n return;\n }\n\n const syncActive = () => {\n controlsRef.current?.setPointerActive(\n \"touch\",\n pointersRef.current.size > 0,\n );\n };\n\n const onPointerDown = (event: PointerEvent) => {\n if (event.pointerType !== \"touch\") {\n return;\n }\n if (controlsRef.current?.isInteractionLocked()) {\n return;\n }\n\n event.preventDefault();\n pointersRef.current.set(event.pointerId, {\n x: event.clientX,\n y: event.clientY,\n at: performance.now(),\n });\n element.setPointerCapture?.(event.pointerId);\n syncActive();\n\n if (pointersRef.current.size === 2) {\n const [first, second] = Array.from(pointersRef.current.values());\n pinchDistanceRef.current = pointerDistance(first!, second!);\n }\n };\n\n const onPointerMove = (event: PointerEvent) => {\n if (event.pointerType !== \"touch\") {\n return;\n }\n if (controlsRef.current?.isInteractionLocked()) {\n return;\n }\n const previous = pointersRef.current.get(event.pointerId);\n if (!previous) {\n return;\n }\n\n event.preventDefault();\n const next: PointerSample = {\n x: event.clientX,\n y: event.clientY,\n at: performance.now(),\n };\n pointersRef.current.set(event.pointerId, next);\n\n const pointers = Array.from(pointersRef.current.values());\n if (pointers.length >= 2) {\n if (!optionsRef.current.pinchZoom) {\n return;\n }\n const distance = pointerDistance(pointers[0]!, pointers[1]!);\n const previousDistance = pinchDistanceRef.current;\n pinchDistanceRef.current = distance;\n if (previousDistance && distance > 0) {\n const view = controlsRef.current?.getTargetView();\n if (view) {\n const nextFov = view.fov * (previousDistance / distance);\n controlsRef.current?.applyViewDelta(\n { fov: nextFov - view.fov },\n { recordVelocity: true },\n );\n }\n }\n return;\n }\n\n const rect = element.getBoundingClientRect();\n const speed = resolveSpeed(\n optionsRef.current.rotateSpeed,\n DEFAULT_ROTATE_SPEED,\n );\n const sign = optionsRef.current.invert ? -1 : 1;\n const deltaYaw =\n (sign * -(next.x - previous.x) * 360 * speed) /\n Math.max(rect.width, 1);\n const deltaPitch =\n (sign * (next.y - previous.y) * 180 * speed) /\n Math.max(rect.height, 1);\n\n controlsRef.current?.applyViewDelta(\n { yaw: deltaYaw, pitch: deltaPitch },\n { recordVelocity: true },\n );\n };\n\n const releasePointer = (event: PointerEvent) => {\n if (!pointersRef.current.has(event.pointerId)) {\n return;\n }\n pointersRef.current.delete(event.pointerId);\n if (element.hasPointerCapture?.(event.pointerId)) {\n element.releasePointerCapture?.(event.pointerId);\n }\n if (pointersRef.current.size < 2) {\n pinchDistanceRef.current = null;\n }\n syncActive();\n };\n\n element.addEventListener(\"pointerdown\", onPointerDown);\n element.addEventListener(\"pointermove\", onPointerMove);\n element.addEventListener(\"pointerup\", releasePointer);\n element.addEventListener(\"pointercancel\", releasePointer);\n\n return () => {\n element.removeEventListener(\"pointerdown\", onPointerDown);\n element.removeEventListener(\"pointermove\", onPointerMove);\n element.removeEventListener(\"pointerup\", releasePointer);\n element.removeEventListener(\"pointercancel\", releasePointer);\n clearPointers();\n };\n }, [controlsRef, enabled, gl]);\n\n return null;\n}\n","import { useThree } from \"@react-three/fiber\";\nimport { useEffect, useRef, useState } from \"react\";\nimport {\n BackSide,\n LinearFilter,\n LinearMipmapLinearFilter,\n MathUtils,\n RepeatWrapping,\n SRGBColorSpace,\n Texture,\n TextureLoader,\n} from \"three\";\nimport { DEFAULT_PANORAMA_RADIUS } from \"./panorama-radius\";\n\nexport type SphereProps = {\n src: string;\n /** Horizontal image offset in degrees. */\n yawOffset?: number;\n onLoad?: (texture: Texture) => void;\n onError?: (error: unknown) => void;\n /** Keeps the source mounted for preloading without drawing it. */\n visible?: boolean;\n};\n\nexport function Sphere({\n src,\n yawOffset = 0,\n onLoad,\n onError,\n visible = true,\n}: SphereProps) {\n const gl = useThree((state) => state.gl);\n const [texture, setTexture] = useState<Texture | null>(null);\n const onLoadRef = useRef(onLoad);\n const onErrorRef = useRef(onError);\n onLoadRef.current = onLoad;\n onErrorRef.current = onError;\n\n useEffect(() => {\n let active = true;\n const loader = new TextureLoader();\n setTexture(null);\n\n loader.load(\n src,\n (loadedTexture) => {\n if (!active) {\n loadedTexture.dispose();\n return;\n }\n\n loadedTexture.colorSpace = SRGBColorSpace;\n loadedTexture.wrapS = RepeatWrapping;\n loadedTexture.repeat.x = -1;\n loadedTexture.offset.x = 1;\n loadedTexture.anisotropy = gl.capabilities.getMaxAnisotropy();\n loadedTexture.magFilter = LinearFilter;\n loadedTexture.minFilter = LinearMipmapLinearFilter;\n loadedTexture.generateMipmaps = true;\n loadedTexture.needsUpdate = true;\n setTexture(loadedTexture);\n onLoadRef.current?.(loadedTexture);\n },\n undefined,\n (error) => {\n if (active) {\n onErrorRef.current?.(error);\n }\n },\n );\n\n return () => {\n active = false;\n };\n }, [gl, src]);\n\n useEffect(\n () => () => {\n texture?.dispose();\n },\n [texture],\n );\n\n if (!texture) {\n return null;\n }\n\n return (\n <mesh\n rotation={[0, MathUtils.degToRad(90 + yawOffset), 0]}\n visible={visible}\n >\n <sphereGeometry args={[DEFAULT_PANORAMA_RADIUS, 128, 64]} />\n <meshBasicMaterial\n map={texture}\n side={BackSide}\n toneMapped={false}\n />\n </mesh>\n );\n}\n","import { useFrame, useThree } from \"@react-three/fiber\";\nimport {\n Fragment,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { ReactNode } from \"react\";\nimport {\n DoubleSide,\n LinearSRGBColorSpace,\n LinearFilter,\n Mesh,\n PlaneGeometry,\n PerspectiveCamera,\n ShaderMaterial,\n Texture,\n Vector2,\n Vector3,\n WebGLRenderTarget,\n} from \"three\";\nimport { PanoramaViewContext } from \"./panorama-view-runtime\";\nimport { Sphere } from \"./sphere\";\nimport {\n TileTextureManagerProvider,\n useSharedTileTextureManager,\n} from \"./tile/texture-manager-context\";\nimport { Tile } from \"./tile/tile\";\nimport type { TileProps } from \"./tile/types\";\n\nexport type PanoramaTransitionPreset =\n | \"none\"\n | \"crossfade\"\n | \"zoom\"\n | \"blackout\"\n | \"whiteFlash\"\n | \"slideRightToLeft\"\n | \"slideTopToBottom\"\n | \"slideDiagonal\"\n | \"circleOpen\"\n | \"verticalOpen\"\n | \"horizontalOpen\"\n | \"ellipticZoomOpen\";\n\nexport type PanoramaTransition =\n | PanoramaTransitionPreset\n | {\n preset: PanoramaTransitionPreset;\n /** Overrides the KRpano-compatible default duration in seconds. */\n duration?: number;\n };\n\nexport type SpherePanoramaScene = {\n id: string;\n type: \"sphere\";\n src: string;\n yawOffset?: number;\n};\n\nexport type TilePanoramaScene = Omit<\n TileProps,\n | \"loadMode\"\n | \"visible\"\n | \"onReady\"\n | \"onPreviewError\"\n | \"onLoadProgress\"\n | \"onTileError\"\n | \"onLevelChange\"\n> & {\n id: string;\n type: \"tile\";\n};\n\nexport type PanoramaScene = SpherePanoramaScene | TilePanoramaScene;\n\nexport type PanoramaTransitionEndEvent = {\n previousSceneId: string;\n sceneId: string;\n preset: PanoramaTransitionPreset;\n};\n\nexport type PanoramaTransitionErrorEvent = {\n sceneId: string;\n error: unknown;\n};\n\nexport type PanoramaScenesProps = {\n scenes: readonly PanoramaScene[];\n activeSceneId: string;\n transition?: PanoramaTransition;\n /** Rendered only after a scene has finished transitioning in. */\n renderHotspots?: (scene: PanoramaScene) => ReactNode;\n onTransitionEnd?: (event: PanoramaTransitionEndEvent) => void;\n onTransitionError?: (event: PanoramaTransitionErrorEvent) => void;\n /** Viewer-wide budget shared by every tile scene. Defaults to 128 MiB. */\n maxTextureMemoryMb?: number;\n /** Viewer-wide tile request limit. Defaults to 4. */\n maxConcurrentTileLoads?: number;\n /** Maximum physical-pixel area of the outgoing GPU snapshot. */\n snapshotMaxPixels?: number;\n};\n\ntype TransitionDefinition = {\n preset: PanoramaTransitionPreset;\n duration: number;\n};\n\ntype Snapshot = {\n texture: Texture;\n dispose: () => void;\n};\n\ntype Phase = \"idle\" | \"preloading\" | \"capturing\" | \"recapturing\" | \"transitioning\";\n\nconst TRANSITION_DEFAULTS: Record<PanoramaTransitionPreset, {\n duration: number;\n krpanoBlend: string;\n}> = {\n none: { duration: 0, krpanoBlend: \"NOBLEND\" },\n crossfade: { duration: 1, krpanoBlend: \"BLEND(1.0, easeInCubic)\" },\n zoom: { duration: 2, krpanoBlend: \"ZOOMBLEND(2.0, 2.0, easeInOutSine)\" },\n blackout: { duration: 2, krpanoBlend: \"COLORBLEND(2.0, 0x000000, easeOutSine)\" },\n whiteFlash: { duration: 1, krpanoBlend: \"LIGHTBLEND(1.0, 0xFFFFFF, 2.0, linear)\" },\n slideRightToLeft: { duration: 1, krpanoBlend: \"SLIDEBLEND(1.0, 0.0, 0.2, linear)\" },\n slideTopToBottom: { duration: 1, krpanoBlend: \"SLIDEBLEND(1.0, 90.0, 0.01, linear)\" },\n slideDiagonal: { duration: 1, krpanoBlend: \"SLIDEBLEND(1.0, 135.0, 0.4, linear)\" },\n circleOpen: { duration: 1, krpanoBlend: \"OPENBLEND(1.0, 0.0, 0.2, 0.0, linear)\" },\n verticalOpen: { duration: 0.7, krpanoBlend: \"OPENBLEND(0.7, 1.0, 0.1, 0.0, linear)\" },\n horizontalOpen: { duration: 1, krpanoBlend: \"OPENBLEND(1.0, -1.0, 0.3, 0.0, linear)\" },\n ellipticZoomOpen: { duration: 1, krpanoBlend: \"OPENBLEND(1.0, -0.5, 0.3, 0.8, linear)\" },\n};\n\nconst EFFECT_INDEX: Record<PanoramaTransitionPreset, number> = {\n none: 0,\n crossfade: 1,\n zoom: 2,\n blackout: 3,\n whiteFlash: 4,\n slideRightToLeft: 5,\n slideTopToBottom: 6,\n slideDiagonal: 7,\n circleOpen: 8,\n verticalOpen: 9,\n horizontalOpen: 10,\n ellipticZoomOpen: 11,\n};\n\nfunction resolveTransition(transition: PanoramaTransition | undefined): TransitionDefinition {\n const preset = typeof transition === \"string\" ? transition : transition?.preset ?? \"crossfade\";\n return {\n preset,\n duration: Math.max(\n 0,\n transition && typeof transition === \"object\" && Number.isFinite(transition.duration)\n ? transition.duration!\n : TRANSITION_DEFAULTS[preset].duration,\n ),\n };\n}\n\nfunction SceneSource({\n scene,\n visible,\n baseOnly,\n onReady,\n onError,\n}: {\n scene: PanoramaScene | null;\n visible: boolean;\n baseOnly: boolean;\n onReady: () => void;\n onError: (error: unknown) => void;\n}) {\n if (!scene) {\n return null;\n }\n\n if (scene.type === \"sphere\") {\n return (\n <Sphere\n src={scene.src}\n yawOffset={scene.yawOffset}\n visible={visible}\n onLoad={onReady}\n onError={onError}\n />\n );\n }\n\n const { id: _id, type: _type, ...tileProps } = scene;\n return (\n <Tile\n {...tileProps}\n visible={visible}\n loadMode={baseOnly ? \"base\" : \"full\"}\n onReady={onReady}\n onPreviewError={onError}\n />\n );\n}\n\nfunction SnapshotCapture({\n requestId,\n maxPixels,\n onCaptured,\n}: {\n requestId: number;\n maxPixels: number;\n onCaptured: (snapshot: Snapshot) => void;\n}) {\n const { camera, gl, scene, size } = useThree();\n const capturedRequestRef = useRef(0);\n const renderTargetRef = useRef<WebGLRenderTarget | null>(null);\n\n useEffect(\n () => () => {\n renderTargetRef.current?.dispose();\n renderTargetRef.current = null;\n },\n [],\n );\n\n useFrame(() => {\n if (requestId === 0 || requestId === capturedRequestRef.current) {\n return;\n }\n\n const pixelRatio = gl.getPixelRatio();\n const sourceWidth = Math.max(1, Math.floor(size.width * pixelRatio));\n const sourceHeight = Math.max(1, Math.floor(size.height * pixelRatio));\n const scale = Math.min(1, Math.sqrt(maxPixels / (sourceWidth * sourceHeight)));\n const width = Math.max(1, Math.floor(sourceWidth * scale));\n const height = Math.max(1, Math.floor(sourceHeight * scale));\n const nextTarget = new WebGLRenderTarget(width, height, {\n depthBuffer: false,\n stencilBuffer: false,\n });\n // WebGLRenderer renders non-XR targets in its linear working color space.\n // Keep this metadata accurate so the snapshot is not treated as display-encoded.\n nextTarget.texture.colorSpace = LinearSRGBColorSpace;\n nextTarget.texture.generateMipmaps = false;\n nextTarget.texture.minFilter = LinearFilter;\n nextTarget.texture.magFilter = LinearFilter;\n\n // This one-off render keeps the transfer entirely on the GPU and permits\n // downscaling the snapshot before its texture is retained for blending.\n const previousTarget = gl.getRenderTarget();\n gl.setRenderTarget(nextTarget);\n gl.clear();\n gl.render(scene, camera);\n gl.setRenderTarget(previousTarget);\n\n capturedRequestRef.current = requestId;\n const previous = renderTargetRef.current;\n renderTargetRef.current = nextTarget;\n previous?.dispose();\n onCaptured({\n texture: nextTarget.texture,\n dispose: () => {\n if (renderTargetRef.current === nextTarget) {\n renderTargetRef.current = null;\n }\n nextTarget.dispose();\n },\n });\n });\n\n return null;\n}\n\nfunction SnapshotOverlay({\n snapshot,\n transition,\n running,\n runId,\n onFinish,\n}: {\n snapshot: Snapshot;\n transition: TransitionDefinition;\n running: boolean;\n runId: number;\n onFinish: () => void;\n}) {\n const { camera, size } = useThree();\n const meshRef = useRef<Mesh>(null);\n const startRef = useRef<number | null>(null);\n const finishedRef = useRef(false);\n const directionRef = useRef(new Vector3());\n const material = useMemo(\n () =>\n new ShaderMaterial({\n transparent: true,\n depthTest: false,\n depthWrite: false,\n side: DoubleSide,\n uniforms: {\n map: { value: snapshot.texture },\n progress: { value: 0 },\n effect: { value: EFFECT_INDEX[transition.preset] },\n },\n vertexShader: `\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n `,\n fragmentShader: `\n uniform sampler2D map;\n uniform float progress;\n uniform float effect;\n varying vec2 vUv;\n\n float easeInCubic(float t) { return t * t * t; }\n float easeOutSine(float t) { return sin(t * 1.57079632679); }\n float easeInOutSine(float t) { return -(cos(3.14159265359 * t) - 1.0) * 0.5; }\n\n void main() {\n float t = clamp(progress, 0.0, 1.0);\n vec2 uv = vUv;\n vec4 old = texture2D(map, uv);\n float alpha = 1.0;\n\n if (effect == 1.0) {\n alpha = 1.0 - easeInCubic(t);\n } else if (effect == 2.0) {\n float eased = easeInOutSine(t);\n // ZOOMBLEND(2.0, 2.0, easeInOutSine): reach 2x zoom.\n uv = 0.5 + (vUv - 0.5) / mix(1.0, 2.0, eased);\n old = texture2D(map, uv);\n alpha = 1.0 - eased;\n } else if (effect == 3.0) {\n // COLORBLEND(2.0, 0x000000, easeOutSine).\n float blackout = easeOutSine(min(1.0, t * 2.0));\n float reveal = easeOutSine(max(0.0, (t - 0.5) * 2.0));\n old.rgb = mix(old.rgb, vec3(0.0), blackout);\n alpha = 1.0 - reveal;\n } else if (effect == 4.0) {\n // LIGHTBLEND(1.0, 0xFFFFFF, 2.0, linear).\n float flash = min(1.0, 2.0 * sin(t * 3.14159265359));\n old.rgb = mix(old.rgb, vec3(1.0), flash);\n alpha = 1.0 - t;\n } else if (effect >= 5.0 && effect <= 7.0) {\n vec2 direction = effect == 5.0 ? vec2(1.0, 0.0) : (effect == 6.0 ? vec2(0.0, 1.0) : normalize(vec2(-1.0, 1.0)));\n float coordinate = dot(vUv - 0.5, direction) + 0.5;\n float softness = effect == 5.0 ? 0.2 : (effect == 6.0 ? 0.01 : 0.4);\n alpha = smoothstep(t - softness, t + softness, coordinate);\n } else if (effect >= 8.0) {\n vec2 point = vUv - 0.5;\n vec2 scale = effect == 9.0 ? vec2(4.0, 1.0) : (effect == 10.0 ? vec2(1.0, 4.0) : vec2(1.35, 0.8));\n float distanceFromCenter = length(point * scale);\n float edge = effect == 8.0 ? 0.2 : (effect == 9.0 ? 0.1 : 0.3);\n float radius = t * (effect == 9.0 ? 1.1 : 1.45);\n alpha = smoothstep(radius, radius + edge, distanceFromCenter);\n if (effect == 11.0) {\n // OPENBLEND(1.0, -0.5, 0.3, 0.8, linear).\n old = texture2D(map, 0.5 + point / (1.0 + 0.8 * t));\n }\n }\n gl_FragColor = vec4(old.rgb, old.a * alpha);\n // The snapshot is linear. Encode it for the drawing buffer so it\n // matches the newly rendered panorama beneath this overlay.\n #include <colorspace_fragment>\n }\n `,\n }),\n [snapshot.texture, transition.preset],\n );\n\n useEffect(() => () => material.dispose(), [material]);\n useEffect(() => {\n startRef.current = null;\n finishedRef.current = false;\n material.uniforms.progress.value = 0;\n }, [material, runId]);\n\n useFrame((state) => {\n const mesh = meshRef.current;\n if (!mesh || !(camera as { isPerspectiveCamera?: boolean }).isPerspectiveCamera) {\n return;\n }\n const perspectiveCamera = camera as PerspectiveCamera;\n const distance = Math.max(perspectiveCamera.near * 1.1, 0.11);\n camera.getWorldDirection(directionRef.current);\n mesh.position.copy(camera.position).addScaledVector(directionRef.current, distance);\n mesh.quaternion.copy(camera.quaternion);\n const height = 2 * distance * Math.tan((perspectiveCamera.fov * Math.PI) / 360);\n mesh.scale.set(height * perspectiveCamera.aspect, height, 1);\n\n if (!running || finishedRef.current) {\n return;\n }\n if (startRef.current === null) {\n startRef.current = state.clock.elapsedTime;\n }\n const progress = transition.duration === 0\n ? 1\n : Math.min(1, (state.clock.elapsedTime - startRef.current) / transition.duration);\n material.uniforms.progress.value = progress;\n if (progress === 1) {\n finishedRef.current = true;\n onFinish();\n }\n });\n\n return (\n <mesh ref={meshRef} renderOrder={10_000} frustumCulled={false}>\n <primitive attach=\"geometry\" object={FULLSCREEN_PLANE} />\n <primitive attach=\"material\" object={material} />\n </mesh>\n );\n}\n\nconst FULLSCREEN_PLANE = new PlaneGeometry(1, 1);\n\nfunction PanoramaScenesController({\n scenes,\n activeSceneId,\n transition: transitionInput,\n renderHotspots,\n onTransitionEnd,\n onTransitionError,\n snapshotMaxPixels = 3_686_400,\n}: Omit<PanoramaScenesProps, \"maxTextureMemoryMb\" | \"maxConcurrentTileLoads\">) {\n const controlsRef = useContext(PanoramaViewContext);\n const manager = useSharedTileTextureManager();\n const transition = useMemo(\n () => resolveTransition(transitionInput),\n [transitionInput],\n );\n const sceneMap = useMemo(\n () => new Map(scenes.map((scene) => [scene.id, scene])),\n [scenes],\n );\n const initialScene = sceneMap.get(activeSceneId) ?? null;\n const [slots, setSlots] = useState<[PanoramaScene | null, PanoramaScene | null]>([\n initialScene,\n null,\n ]);\n const [activeSlot, setActiveSlot] = useState(0);\n const [liveSlot, setLiveSlot] = useState(0);\n const [pendingSlot, setPendingSlot] = useState<number | null>(null);\n const [phase, setPhase] = useState<Phase>(initialScene ? \"idle\" : \"preloading\");\n const [captureRequestId, setCaptureRequestId] = useState(0);\n const [transitionRunId, setTransitionRunId] = useState(0);\n const [snapshot, setSnapshot] = useState<Snapshot | null>(null);\n const [recoveryKey, setRecoveryKey] = useState(0);\n const requestedSceneIdRef = useRef(activeSceneId);\n const captureReasonRef = useRef<\"start\" | \"interrupt\">(\"start\");\n const interactionReleaseRef = useRef<(() => void) | null>(null);\n const slotsRef = useRef(slots);\n const phaseRef = useRef(phase);\n const liveSlotRef = useRef(liveSlot);\n const transitionFromRef = useRef<PanoramaScene | null>(initialScene);\n slotsRef.current = slots;\n phaseRef.current = phase;\n liveSlotRef.current = liveSlot;\n\n const releaseInteraction = useCallback(() => {\n interactionReleaseRef.current?.();\n interactionReleaseRef.current = null;\n }, []);\n\n const reportError = useCallback((sceneId: string, error: unknown) => {\n onTransitionError?.({ sceneId, error });\n }, [onTransitionError]);\n\n const startPreload = useCallback((scene: PanoramaScene) => {\n const nextSlot = 1 - liveSlotRef.current;\n requestedSceneIdRef.current = scene.id;\n setSlots((current) => {\n const next: [PanoramaScene | null, PanoramaScene | null] = [...current] as [PanoramaScene | null, PanoramaScene | null];\n next[nextSlot] = scene;\n return next;\n });\n setPendingSlot(nextSlot);\n setPhase(\"preloading\");\n }, []);\n\n useEffect(() => {\n const requested = sceneMap.get(activeSceneId);\n if (!requested) {\n reportError(activeSceneId, new Error(`Unknown panorama scene: ${activeSceneId}`));\n return;\n }\n\n const liveScene = slotsRef.current[liveSlotRef.current];\n if (phaseRef.current === \"idle\" && liveScene?.id === requested.id) {\n requestedSceneIdRef.current = requested.id;\n return;\n }\n if (\n phaseRef.current === \"preloading\" &&\n pendingSlot !== null &&\n slotsRef.current[pendingSlot]?.id === requested.id\n ) {\n requestedSceneIdRef.current = requested.id;\n return;\n }\n if (phaseRef.current === \"transitioning\" || phaseRef.current === \"capturing\") {\n requestedSceneIdRef.current = requested.id;\n captureReasonRef.current = \"interrupt\";\n setPhase(\"recapturing\");\n setCaptureRequestId((current) => current + 1);\n return;\n }\n startPreload(requested);\n }, [activeSceneId, pendingSlot, reportError, sceneMap, startPreload]);\n\n const handleReady = useCallback((slot: number) => {\n if (slot !== pendingSlot || phaseRef.current !== \"preloading\") {\n return;\n }\n if (transition.preset === \"none\") {\n const previousScene = slotsRef.current[liveSlotRef.current];\n const nextScene = slotsRef.current[slot];\n setSlots((current) => {\n const next: [PanoramaScene | null, PanoramaScene | null] = [...current] as [PanoramaScene | null, PanoramaScene | null];\n next[liveSlotRef.current] = null;\n return next;\n });\n setLiveSlot(slot);\n setActiveSlot(slot);\n setPendingSlot(null);\n setPhase(\"idle\");\n if (previousScene && nextScene) {\n onTransitionEnd?.({\n previousSceneId: previousScene.id,\n sceneId: nextScene.id,\n preset: \"none\",\n });\n }\n return;\n }\n interactionReleaseRef.current ??= controlsRef?.current?.acquireInteractionLock() ?? null;\n transitionFromRef.current = slotsRef.current[liveSlotRef.current];\n captureReasonRef.current = \"start\";\n setPhase(\"capturing\");\n setCaptureRequestId((current) => current + 1);\n }, [controlsRef, onTransitionEnd, pendingSlot, transition.preset]);\n\n const handleCaptured = useCallback((nextSnapshot: Snapshot) => {\n setSnapshot((current) => {\n current?.dispose();\n return nextSnapshot;\n });\n\n if (captureReasonRef.current === \"interrupt\") {\n startPreload(sceneMap.get(requestedSceneIdRef.current)!);\n return;\n }\n\n const sourceSlot = liveSlotRef.current;\n setSlots((current) => {\n const next: [PanoramaScene | null, PanoramaScene | null] = [...current] as [PanoramaScene | null, PanoramaScene | null];\n next[sourceSlot] = null;\n return next;\n });\n manager?.releaseUnused();\n if (pendingSlot !== null) {\n setLiveSlot(pendingSlot);\n }\n setPhase(\"transitioning\");\n setTransitionRunId((current) => current + 1);\n }, [manager, pendingSlot, sceneMap, startPreload]);\n\n const finishTransition = useCallback(() => {\n const nextSlot = pendingSlot;\n const previousScene = transitionFromRef.current;\n const nextScene = nextSlot === null ? null : slotsRef.current[nextSlot];\n if (nextSlot === null || !nextScene) {\n releaseInteraction();\n setPhase(\"idle\");\n return;\n }\n setActiveSlot(nextSlot);\n setLiveSlot(nextSlot);\n setPendingSlot(null);\n setPhase(\"idle\");\n const oldSnapshot = snapshot;\n setSnapshot(null);\n oldSnapshot?.dispose();\n releaseInteraction();\n if (previousScene) {\n onTransitionEnd?.({\n previousSceneId: previousScene.id,\n sceneId: nextScene.id,\n preset: transition.preset,\n });\n }\n }, [onTransitionEnd, pendingSlot, releaseInteraction, snapshot, transition.preset]);\n\n useEffect(() => () => {\n releaseInteraction();\n snapshot?.dispose();\n }, [releaseInteraction, snapshot]);\n\n const { gl } = useThree();\n useEffect(() => {\n const canvas = gl.domElement;\n const onContextLost = (event: Event) => {\n event.preventDefault();\n releaseInteraction();\n manager?.dispose();\n snapshot?.dispose();\n setSnapshot(null);\n setPendingSlot(null);\n setPhase(\"idle\");\n };\n const onContextRestored = () => {\n manager?.resume();\n setRecoveryKey((current) => current + 1);\n };\n canvas.addEventListener(\"webglcontextlost\", onContextLost);\n canvas.addEventListener(\"webglcontextrestored\", onContextRestored);\n return () => {\n canvas.removeEventListener(\"webglcontextlost\", onContextLost);\n canvas.removeEventListener(\"webglcontextrestored\", onContextRestored);\n };\n }, [gl, manager, releaseInteraction, snapshot]);\n\n const renderedScene = slots[liveSlot];\n const snapshotVisible = snapshot !== null && (\n phase === \"transitioning\" ||\n phase === \"recapturing\" ||\n phase === \"preloading\"\n );\n\n return (\n <Fragment>\n <SnapshotCapture\n requestId={captureRequestId}\n maxPixels={Math.max(1, snapshotMaxPixels)}\n onCaptured={handleCaptured}\n />\n {[0, 1].map((slot) => {\n const source = slots[slot];\n const isLive = slot === liveSlot;\n const isPending = slot === pendingSlot;\n return (\n <SceneSource\n key={`${slot}:${source?.id ?? \"empty\"}:${recoveryKey}`}\n scene={source}\n visible={isLive}\n baseOnly={isPending && phase !== \"idle\"}\n onReady={() => handleReady(slot)}\n onError={(error) => {\n if (source) {\n reportError(source.id, error);\n }\n }}\n />\n );\n })}\n {snapshotVisible ? (\n <SnapshotOverlay\n snapshot={snapshot}\n transition={transition}\n running={phase === \"transitioning\"}\n runId={transitionRunId}\n onFinish={finishTransition}\n />\n ) : null}\n {phase === \"idle\" && renderedScene ? renderHotspots?.(renderedScene) : null}\n </Fragment>\n );\n}\n\nexport function PanoramaScenes({\n maxTextureMemoryMb,\n maxConcurrentTileLoads,\n ...props\n}: PanoramaScenesProps) {\n return (\n <TileTextureManagerProvider\n maxTextureMemoryMb={maxTextureMemoryMb}\n maxConcurrentLoads={maxConcurrentTileLoads}\n >\n <PanoramaScenesController {...props} />\n </TileTextureManagerProvider>\n );\n}\n","import { useThree } from \"@react-three/fiber\";\nimport {\n createContext,\n useContext,\n useEffect,\n useMemo,\n} from \"react\";\nimport type { ReactNode } from \"react\";\nimport { TileTextureManager } from \"./texture-manager\";\n\nconst TileTextureManagerContext = createContext<TileTextureManager | null>(\n null,\n);\n\nexport type TileTextureManagerProviderProps = {\n children?: ReactNode;\n /** Shared viewer-wide GPU budget. Defaults to 128 MiB. */\n maxTextureMemoryMb?: number;\n /** Shared limit for tile image requests. Defaults to 4. */\n maxConcurrentLoads?: number;\n};\n\n/**\n * Provides one tile cache for a panorama scene controller. Keeping this scope\n * at the viewer level prevents a leaving and entering scene from each claiming\n * an independent texture-memory budget.\n */\nexport function TileTextureManagerProvider({\n children,\n maxTextureMemoryMb = 128,\n maxConcurrentLoads = 4,\n}: TileTextureManagerProviderProps) {\n const gl = useThree((state) => state.gl);\n const anisotropy = gl.capabilities.getMaxAnisotropy();\n const manager = useMemo(\n () =>\n new TileTextureManager({\n anisotropy,\n maxBytes: Math.max(1, maxTextureMemoryMb) * 1024 * 1024,\n concurrency: Math.max(1, Math.floor(maxConcurrentLoads)),\n retryCount: 1,\n }),\n [anisotropy, maxConcurrentLoads, maxTextureMemoryMb],\n );\n\n useEffect(() => {\n manager.resume();\n return () => manager.dispose();\n }, [manager]);\n\n return (\n <TileTextureManagerContext.Provider value={manager}>\n {children}\n </TileTextureManagerContext.Provider>\n );\n}\n\nexport function useSharedTileTextureManager() {\n return useContext(TileTextureManagerContext);\n}\n","import {\n ClampToEdgeWrapping,\n LinearFilter,\n SRGBColorSpace,\n Texture,\n TextureLoader,\n} from \"three\";\nimport type {\n TextureEntrySnapshot,\n TileAddress,\n TileLoadError,\n TileLoadProgress,\n} from \"./types\";\n\ntype Listener = (snapshot: TextureEntrySnapshot) => void;\n\ntype TextureEntry = TextureEntrySnapshot & {\n key: string;\n url: string;\n address: TileAddress;\n refs: number;\n listeners: Set<Listener>;\n lastUsed: number;\n bytes: number;\n};\n\ntype TextureManagerOptions = {\n anisotropy: number;\n maxBytes: number;\n concurrency: number;\n retryCount: number;\n onProgress?: (progress: TileLoadProgress) => void;\n onError?: (event: TileLoadError) => void;\n};\n\nconst EMPTY_TEXTURE_SNAPSHOT: TextureEntrySnapshot = {\n status: \"idle\",\n texture: null,\n error: null,\n};\n\nexport class TileTextureManager {\n private readonly loader = new TextureLoader();\n private readonly entries = new Map<string, TextureEntry>();\n private readonly queue: TextureEntry[] = [];\n private activeLoads = 0;\n private totalBytes = 0;\n private requested = 0;\n private loaded = 0;\n private failed = 0;\n private disposed = false;\n private generation = 0;\n private options: TextureManagerOptions;\n\n constructor(options: TextureManagerOptions) {\n this.options = options;\n }\n\n resume() {\n this.disposed = false;\n this.drain();\n }\n\n getSnapshot(key: string): TextureEntrySnapshot {\n const entry = this.entries.get(key);\n return entry ? this.snapshot(entry) : EMPTY_TEXTURE_SNAPSHOT;\n }\n\n acquire(\n key: string,\n url: string,\n address: TileAddress,\n listener: Listener,\n ): () => void {\n let entry = this.entries.get(key);\n if (!entry) {\n entry = {\n key,\n url,\n address,\n status: \"idle\",\n texture: null,\n error: null,\n refs: 0,\n listeners: new Set(),\n lastUsed: performance.now(),\n bytes: 0,\n };\n this.entries.set(key, entry);\n }\n\n entry.refs += 1;\n entry.lastUsed = performance.now();\n entry.listeners.add(listener);\n listener(this.snapshot(entry));\n\n if (entry.status === \"idle\") {\n entry.status = \"queued\";\n this.queue.push(entry);\n this.requested += 1;\n this.emitProgress();\n this.drain();\n }\n\n return () => {\n entry!.listeners.delete(listener);\n entry!.refs = Math.max(0, entry!.refs - 1);\n entry!.lastUsed = performance.now();\n\n if (entry!.refs === 0 && entry!.status === \"queued\") {\n const queueIndex = this.queue.indexOf(entry!);\n if (queueIndex >= 0) {\n this.queue.splice(queueIndex, 1);\n }\n entry!.status = \"idle\";\n this.entries.delete(entry!.key);\n this.requested = Math.max(0, this.requested - 1);\n this.emitProgress();\n this.drain();\n return;\n }\n\n this.evict();\n };\n }\n\n dispose() {\n this.disposed = true;\n this.generation += 1;\n this.queue.length = 0;\n for (const entry of this.entries.values()) {\n entry.texture?.dispose();\n entry.listeners.clear();\n }\n this.entries.clear();\n this.totalBytes = 0;\n }\n\n /**\n * Releases textures that are no longer rendered by any Tile instance.\n * Scene transitions call this after the outgoing panorama has been\n * snapshotted, so the incoming scene never competes with stale GPU tiles.\n */\n releaseUnused() {\n for (const entry of Array.from(this.entries.values())) {\n if (entry.refs > 0) {\n continue;\n }\n entry.texture?.dispose();\n this.totalBytes -= entry.bytes;\n this.entries.delete(entry.key);\n }\n this.totalBytes = Math.max(0, this.totalBytes);\n }\n\n private snapshot(entry: TextureEntry): TextureEntrySnapshot {\n return {\n status: entry.status,\n texture: entry.texture,\n error: entry.error,\n };\n }\n\n private notify(entry: TextureEntry) {\n const snapshot = this.snapshot(entry);\n for (const listener of entry.listeners) {\n listener(snapshot);\n }\n }\n\n private emitProgress() {\n this.options.onProgress?.({\n requested: this.requested,\n loaded: this.loaded,\n failed: this.failed,\n active: this.activeLoads,\n queued: this.queue.length,\n });\n }\n\n private drain() {\n while (\n !this.disposed &&\n this.activeLoads < this.options.concurrency &&\n this.queue.length > 0\n ) {\n const entry = this.queue.shift()!;\n if (entry.refs === 0) {\n entry.status = \"idle\";\n this.entries.delete(entry.key);\n this.requested = Math.max(0, this.requested - 1);\n continue;\n }\n entry.status = \"loading\";\n this.activeLoads += 1;\n this.notify(entry);\n this.emitProgress();\n void this.loadAndFinish(entry);\n }\n }\n\n private async load(entry: TextureEntry, generation: number) {\n let lastError: unknown = null;\n for (let attempt = 0; attempt <= this.options.retryCount; attempt += 1) {\n try {\n const texture = await this.loader.loadAsync(entry.url);\n if (this.disposed || generation !== this.generation) {\n texture.dispose();\n return;\n }\n this.configureTexture(texture);\n entry.texture = texture;\n entry.status = \"loaded\";\n entry.error = null;\n entry.bytes = entry.address.width * entry.address.height * 4;\n entry.lastUsed = performance.now();\n this.totalBytes += entry.bytes;\n this.loaded += 1;\n this.notify(entry);\n return;\n } catch (error) {\n lastError = error;\n }\n }\n\n if (!this.disposed && generation === this.generation) {\n entry.status = \"error\";\n entry.error = lastError;\n this.failed += 1;\n this.notify(entry);\n this.options.onError?.({\n address: entry.address,\n url: entry.url,\n error: lastError,\n });\n }\n }\n\n private configureTexture(texture: Texture) {\n texture.colorSpace = SRGBColorSpace;\n texture.wrapS = ClampToEdgeWrapping;\n texture.wrapT = ClampToEdgeWrapping;\n texture.magFilter = LinearFilter;\n texture.minFilter = LinearFilter;\n texture.generateMipmaps = false;\n texture.anisotropy = Math.min(4, this.options.anisotropy);\n texture.needsUpdate = true;\n }\n\n private evict() {\n if (this.totalBytes <= this.options.maxBytes) {\n return;\n }\n\n const candidates = Array.from(this.entries.values())\n .filter((entry) => entry.refs === 0 && entry.texture)\n .sort((a, b) => a.lastUsed - b.lastUsed);\n for (const entry of candidates) {\n if (this.totalBytes <= this.options.maxBytes) {\n break;\n }\n entry.texture?.dispose();\n this.totalBytes -= entry.bytes;\n this.entries.delete(entry.key);\n }\n this.totalBytes = Math.max(0, this.totalBytes);\n }\n\n private finishLoad(generation: number) {\n this.activeLoads = Math.max(0, this.activeLoads - 1);\n if (!this.disposed && generation === this.generation) {\n this.emitProgress();\n this.evict();\n }\n if (!this.disposed) {\n this.drain();\n }\n }\n\n private async loadAndFinish(entry: TextureEntry) {\n const generation = this.generation;\n try {\n await this.load(entry, generation);\n } finally {\n this.finishLoad(generation);\n }\n }\n}\n","import { useFrame, useThree } from \"@react-three/fiber\";\nimport {\n memo,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n Box3,\n ClampToEdgeWrapping,\n Frustum,\n LinearFilter,\n Matrix4,\n PlaneGeometry,\n PerspectiveCamera,\n SRGBColorSpace,\n Texture,\n TextureLoader,\n Vector3,\n} from \"three\";\nimport {\n CUBE_FACES,\n CUBE_RADIUS,\n PREVIEW_FACE_ORDER,\n getFaceTransform,\n getPreferredLevel,\n getTileBoundingBox,\n getTileLocalLayout,\n makeTileAddress,\n previewAtlasVRange,\n tileKey,\n} from \"./face-layout\";\nimport {\n buildDefaultTileUrlTemplate,\n parseMultires,\n resolveRelativeTileUrl,\n resolveTemplateUrl,\n} from \"./multires\";\nimport { TileTextureManager } from \"./texture-manager\";\nimport { useSharedTileTextureManager } from \"./texture-manager-context\";\nimport type {\n CubeFaceCode,\n TextureEntrySnapshot,\n TileAddress,\n TileProps,\n} from \"./types\";\n\nconst MAX_LOD_UPDATE_INTERVAL_MS = 100;\nconst FAST_ROTATION_THRESHOLD_RADIANS = Math.PI / 180;\nconst FAST_FOV_THRESHOLD_DEGREES = 0.5;\nconst VIEW_CHANGE_EPSILON = 0.0001;\nconst VISIBILITY_FOV_PADDING_DEGREES = 8;\nconst PREVIEW_RADIUS = CUBE_RADIUS + 0.05;\nconst SHARED_TILE_GEOMETRY = new PlaneGeometry(1, 1);\n\ntype TileLayer = {\n level: number;\n addresses: TileAddress[];\n renderOrder: number;\n};\n\ntype TileCandidate = {\n address: TileAddress;\n bounds: Box3;\n};\n\nfunction usePreviewTexture(\n url: string | null,\n anisotropy: number,\n onError?: (error: unknown) => void,\n) {\n const [texture, setTexture] = useState<Texture | null>(null);\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n\n useEffect(() => {\n if (!url) {\n setTexture(null);\n return;\n }\n\n let active = true;\n const loader = new TextureLoader();\n setTexture(null);\n loader.load(\n url,\n (loadedTexture) => {\n if (!active) {\n loadedTexture.dispose();\n return;\n }\n loadedTexture.colorSpace = SRGBColorSpace;\n loadedTexture.wrapS = ClampToEdgeWrapping;\n loadedTexture.wrapT = ClampToEdgeWrapping;\n loadedTexture.magFilter = LinearFilter;\n loadedTexture.minFilter = LinearFilter;\n loadedTexture.generateMipmaps = false;\n loadedTexture.anisotropy = Math.min(4, anisotropy);\n loadedTexture.needsUpdate = true;\n setTexture(loadedTexture);\n },\n undefined,\n (error) => {\n if (active) {\n setTexture(null);\n onErrorRef.current?.(error);\n }\n },\n );\n\n return () => {\n active = false;\n };\n }, [anisotropy, url]);\n\n useEffect(\n () => () => {\n texture?.dispose();\n },\n [texture],\n );\n\n return texture;\n}\n\nfunction PreviewFace({\n face,\n texture,\n faceOrder,\n}: {\n face: CubeFaceCode;\n texture: Texture;\n faceOrder: readonly CubeFaceCode[];\n}) {\n const geometry = useMemo(() => {\n const nextGeometry = new PlaneGeometry(\n PREVIEW_RADIUS * 2,\n PREVIEW_RADIUS * 2,\n );\n const uv = nextGeometry.getAttribute(\"uv\");\n const { offset, scale } = previewAtlasVRange(face, faceOrder);\n const inset = scale / 512;\n for (let index = 0; index < uv.count; index += 1) {\n const sourceV = uv.getY(index);\n uv.setY(\n index,\n offset + inset + sourceV * Math.max(0, scale - inset * 2),\n );\n }\n uv.needsUpdate = true;\n return nextGeometry;\n }, [face, faceOrder]);\n\n useEffect(\n () => () => {\n geometry.dispose();\n },\n [geometry],\n );\n\n const transform = getFaceTransform(face, PREVIEW_RADIUS);\n return (\n <mesh\n geometry={geometry}\n position={transform.position}\n renderOrder={-100}\n rotation={transform.rotation}\n >\n <meshBasicMaterial\n depthTest={false}\n depthWrite={false}\n map={texture}\n toneMapped={false}\n />\n </mesh>\n );\n}\n\nfunction PreviewCube({\n texture,\n faceOrder,\n}: {\n texture: Texture;\n faceOrder: readonly CubeFaceCode[];\n}) {\n return CUBE_FACES.map((face) => (\n <PreviewFace\n key={face}\n face={face}\n texture={texture}\n faceOrder={faceOrder}\n />\n ));\n}\n\nfunction useManagedTexture(\n manager: TileTextureManager,\n key: string,\n url: string,\n address: TileAddress,\n): TextureEntrySnapshot {\n const [managedState, setManagedState] = useState(() => ({\n manager,\n key,\n url,\n snapshot: manager.getSnapshot(key),\n }));\n\n const snapshot =\n managedState.manager === manager &&\n managedState.key === key &&\n managedState.url === url\n ? managedState.snapshot\n : manager.getSnapshot(key);\n\n useEffect(\n () =>\n manager.acquire(key, url, address, (nextSnapshot) => {\n setManagedState({\n manager,\n key,\n url,\n snapshot: nextSnapshot,\n });\n }),\n [key, manager, url],\n );\n\n return snapshot;\n}\n\nconst TileMesh = memo(function TileMesh({\n address,\n manager,\n renderOrder,\n resolveUrl,\n}: {\n address: TileAddress;\n manager: TileTextureManager;\n renderOrder: number;\n resolveUrl: (address: TileAddress) => string;\n}) {\n const url = resolveUrl(address);\n // A viewer-scoped manager serves multiple scenes. The tile coordinate alone\n // is only unique within one cube panorama, so include the resolved resource\n // URL to prevent same-address tiles from different scenes sharing a texture.\n const cacheKey = `${url}\\u0000${tileKey(address)}`;\n const snapshot = useManagedTexture(manager, cacheKey, url, address);\n const layout = getTileLocalLayout(address);\n const transform = getFaceTransform(address.face);\n\n if (!snapshot.texture) {\n return null;\n }\n\n return (\n <group position={transform.position} rotation={transform.rotation}>\n <mesh\n geometry={SHARED_TILE_GEOMETRY}\n position={[layout.x, layout.y, 0]}\n renderOrder={renderOrder}\n scale={[layout.width, layout.height, 1]}\n >\n <meshBasicMaterial\n depthTest={false}\n depthWrite={false}\n map={snapshot.texture}\n toneMapped={false}\n />\n </mesh>\n </group>\n );\n});\n\nconst TileLayerMeshes = memo(function TileLayerMeshes({\n layer,\n manager,\n resolveUrl,\n}: {\n layer: TileLayer;\n manager: TileTextureManager;\n resolveUrl: (address: TileAddress) => string;\n}) {\n return layer.addresses.map((address) => (\n <TileMesh\n key={tileKey(address)}\n address={address}\n manager={manager}\n renderOrder={layer.renderOrder}\n resolveUrl={resolveUrl}\n />\n ));\n});\n\nfunction buildTileCandidates(\n levels: number[],\n tileSize: number,\n): TileCandidate[][] {\n return levels.map((faceSize, index) => {\n const level = index + 1;\n const cols = Math.ceil(faceSize / tileSize);\n const rows = Math.ceil(faceSize / tileSize);\n const candidates: TileCandidate[] = [];\n\n for (const face of CUBE_FACES) {\n for (let row = 1; row <= rows; row += 1) {\n for (let col = 1; col <= cols; col += 1) {\n const address = makeTileAddress(\n face,\n level,\n faceSize,\n tileSize,\n col,\n row,\n );\n candidates.push({\n address,\n bounds: getTileBoundingBox(address),\n });\n }\n }\n }\n\n return candidates;\n });\n}\n\nfunction visibleAddresses(\n candidates: TileCandidate[],\n frustum: Frustum,\n): TileAddress[] {\n return candidates\n .filter((candidate) => frustum.intersectsBox(candidate.bounds))\n .map((candidate) => candidate.address);\n}\n\nfunction updateVisibilityFrustum(\n camera: PerspectiveCamera,\n projectionMatrix: Matrix4,\n frustum: Frustum,\n) {\n camera.updateProjectionMatrix();\n camera.updateMatrixWorld();\n camera.matrixWorldInverse.copy(camera.matrixWorld).invert();\n projectionMatrix.multiplyMatrices(\n camera.projectionMatrix,\n camera.matrixWorldInverse,\n );\n frustum.setFromProjectionMatrix(projectionMatrix);\n}\n\nfunction addAddress(\n addressesByLevel: Map<number, Map<string, TileAddress>>,\n address: TileAddress,\n) {\n let levelAddresses = addressesByLevel.get(address.level);\n if (!levelAddresses) {\n levelAddresses = new Map();\n addressesByLevel.set(address.level, levelAddresses);\n }\n levelAddresses.set(tileKey(address), address);\n}\n\nfunction parentAddresses(\n child: TileAddress,\n parentLevel: number,\n parentFaceSize: number,\n tileSize: number,\n): TileAddress[] {\n const childLeft = ((child.col - 1) * child.tileSize) / child.faceSize;\n const childTop = ((child.row - 1) * child.tileSize) / child.faceSize;\n const childRight = childLeft + child.width / child.faceSize;\n const childBottom = childTop + child.height / child.faceSize;\n const cols = Math.ceil(parentFaceSize / tileSize);\n const rows = Math.ceil(parentFaceSize / tileSize);\n const firstCol = Math.max(\n 1,\n Math.floor((childLeft * parentFaceSize) / tileSize) + 1,\n );\n const lastCol = Math.min(\n cols,\n Math.ceil((childRight * parentFaceSize) / tileSize),\n );\n const firstRow = Math.max(\n 1,\n Math.floor((childTop * parentFaceSize) / tileSize) + 1,\n );\n const lastRow = Math.min(\n rows,\n Math.ceil((childBottom * parentFaceSize) / tileSize),\n );\n const addresses: TileAddress[] = [];\n\n for (let row = firstRow; row <= lastRow; row += 1) {\n for (let col = firstCol; col <= lastCol; col += 1) {\n addresses.push(\n makeTileAddress(\n child.face,\n parentLevel,\n parentFaceSize,\n tileSize,\n col,\n row,\n ),\n );\n }\n }\n return addresses;\n}\n\nfunction centerFacingAddress(\n candidates: TileCandidate[],\n camera: PerspectiveCamera,\n): TileAddress {\n const direction = camera.getWorldDirection(new Vector3());\n const center = new Vector3();\n let bestCandidate = candidates[0]!;\n let bestAlignment = -Infinity;\n\n for (const candidate of candidates) {\n candidate.bounds.getCenter(center).normalize();\n const alignment = center.dot(direction);\n if (alignment > bestAlignment) {\n bestCandidate = candidate;\n bestAlignment = alignment;\n }\n }\n\n return bestCandidate.address;\n}\n\nfunction buildLayers(\n targetLevel: number,\n levels: number[],\n tileSize: number,\n frustum: Frustum,\n camera: PerspectiveCamera,\n candidatesByLevel: TileCandidate[][],\n): TileLayer[] {\n const addressesByLevel = new Map<number, Map<string, TileAddress>>();\n const targetCandidates = candidatesByLevel[targetLevel - 1]!;\n const targetAddresses = visibleAddresses(targetCandidates, frustum);\n\n // A stale camera matrix must not schedule an entire face. The center-facing\n // target and its parent chain provide a bounded fallback until the next pass.\n const visibleTargets =\n targetAddresses.length > 0\n ? targetAddresses\n : [centerFacingAddress(targetCandidates, camera)];\n\n for (const address of visibleTargets) {\n addAddress(addressesByLevel, address);\n }\n\n let children = visibleTargets;\n for (let parentLevel = targetLevel - 1; parentLevel >= 1; parentLevel -= 1) {\n const parentFaceSize = levels[parentLevel - 1]!;\n const parents = new Map<string, TileAddress>();\n for (const child of children) {\n for (const parent of parentAddresses(\n child,\n parentLevel,\n parentFaceSize,\n tileSize,\n )) {\n parents.set(tileKey(parent), parent);\n addAddress(addressesByLevel, parent);\n }\n }\n children = Array.from(parents.values());\n }\n\n return Array.from(addressesByLevel.entries())\n .sort(([firstLevel], [secondLevel]) => firstLevel - secondLevel)\n .map(([level, addresses]) => ({\n level,\n addresses: Array.from(addresses.values()),\n renderOrder: -100 + level * 10,\n }));\n}\n\nfunction layerToken(layers: TileLayer[]): string {\n return layers\n .map(\n (layer) =>\n `${layer.level}:${layer.addresses.map(tileKey).join(\",\")}`,\n )\n .join(\"|\");\n}\n\nexport function Tile({\n baseUrl,\n multires,\n previewUrl,\n previewFaceOrder = PREVIEW_FACE_ORDER,\n urlTemplate,\n resolveTileUrl,\n maxTextureMemoryMb = 128,\n maxConcurrentLoads = 8,\n retryCount = 1,\n loadMode = \"full\",\n visible = true,\n onReady,\n onPreviewError,\n onLoadProgress,\n onTileError,\n onLevelChange,\n}: TileProps) {\n const { camera, gl, size } = useThree();\n const multiresConfig = useMemo(() => parseMultires(multires), [multires]);\n const { levels, tileSize } = multiresConfig;\n const multiresToken = `${tileSize}:${levels.join(\",\")}`;\n const candidatesByLevel = useMemo(\n () => buildTileCandidates(levels, tileSize),\n [levels, tileSize],\n );\n const anisotropy = gl.capabilities.getMaxAnisotropy();\n const effectivePreviewUrl =\n previewUrl === undefined\n ? `${baseUrl.replace(/\\/$/, \"\")}/previews/cube-vertical.webp`\n : previewUrl;\n const previewTexture = usePreviewTexture(\n effectivePreviewUrl,\n anisotropy,\n onPreviewError,\n );\n const sharedManager = useSharedTileTextureManager();\n const progressRef = useRef(onLoadProgress);\n const errorRef = useRef(onTileError);\n const levelChangeRef = useRef(onLevelChange);\n progressRef.current = onLoadProgress;\n errorRef.current = onTileError;\n levelChangeRef.current = onLevelChange;\n\n const ownedManager = useMemo(\n () =>\n new TileTextureManager({\n anisotropy,\n maxBytes: Math.max(1, maxTextureMemoryMb) * 1024 * 1024,\n concurrency: Math.max(1, Math.floor(maxConcurrentLoads)),\n retryCount: Math.max(0, Math.floor(retryCount)),\n onProgress: (progress) => progressRef.current?.(progress),\n onError: (event) => errorRef.current?.(event),\n }),\n [\n anisotropy,\n baseUrl,\n maxConcurrentLoads,\n maxTextureMemoryMb,\n multiresToken,\n retryCount,\n resolveTileUrl,\n urlTemplate,\n ],\n );\n const manager = sharedManager ?? ownedManager;\n useEffect(() => {\n manager.resume();\n return () => {\n if (manager === ownedManager) {\n manager.dispose();\n return;\n }\n queueMicrotask(() => manager.releaseUnused());\n };\n }, [manager, ownedManager]);\n\n const readyRef = useRef(false);\n useEffect(() => {\n readyRef.current = false;\n }, [effectivePreviewUrl]);\n useEffect(() => {\n if (!previewTexture || readyRef.current) {\n return;\n }\n readyRef.current = true;\n onReady?.();\n }, [onReady, previewTexture]);\n\n const template = urlTemplate ?? buildDefaultTileUrlTemplate();\n const resolveUrl = useMemo(\n () => (address: TileAddress) => {\n const relativePath = resolveTileUrl\n ? resolveTileUrl(address)\n : resolveTemplateUrl(template, address);\n return resolveRelativeTileUrl(baseUrl, relativePath);\n },\n [baseUrl, resolveTileUrl, template],\n );\n\n const [layers, setLayers] = useState<TileLayer[]>([]);\n const layerTokenRef = useRef(\"\");\n const currentLevelRef = useRef(1);\n const lastUpdateAtRef = useRef(-Infinity);\n const visibilityDirtyRef = useRef(true);\n const lastVisibilityQuaternionRef = useRef(camera.quaternion.clone());\n const lastVisibilityFovRef = useRef(Number.NaN);\n const lastViewportRef = useRef({ width: 0, height: 0, dpr: 0 });\n const frustumRef = useRef(new Frustum());\n const projectionMatrixRef = useRef(new Matrix4());\n const visibilityCameraRef = useRef(new PerspectiveCamera());\n\n useEffect(() => {\n currentLevelRef.current = 1;\n layerTokenRef.current = \"\";\n visibilityDirtyRef.current = true;\n setLayers([]);\n }, [manager, multiresToken]);\n\n useEffect(() => {\n if (loadMode !== \"preview\") {\n return;\n }\n layerTokenRef.current = \"\";\n setLayers([]);\n }, [loadMode]);\n\n const commitLayers = (nextLayers: TileLayer[]) => {\n const nextToken = layerToken(nextLayers);\n if (nextToken !== layerTokenRef.current) {\n layerTokenRef.current = nextToken;\n setLayers(nextLayers);\n }\n };\n\n useFrame(() => {\n if (loadMode === \"preview\") {\n return;\n }\n if (!(camera instanceof PerspectiveCamera)) {\n return;\n }\n\n const now = performance.now();\n const pixelRatio = gl.getPixelRatio();\n const rotationDelta = lastVisibilityQuaternionRef.current.angleTo(\n camera.quaternion,\n );\n const fovDelta = Number.isFinite(lastVisibilityFovRef.current)\n ? Math.abs(camera.fov - lastVisibilityFovRef.current)\n : Infinity;\n const lastViewport = lastViewportRef.current;\n const viewportChanged =\n lastViewport.width !== size.width ||\n lastViewport.height !== size.height ||\n lastViewport.dpr !== pixelRatio;\n const viewChanged =\n visibilityDirtyRef.current ||\n viewportChanged ||\n rotationDelta > VIEW_CHANGE_EPSILON ||\n fovDelta > VIEW_CHANGE_EPSILON;\n const movingQuickly =\n rotationDelta >= FAST_ROTATION_THRESHOLD_RADIANS ||\n fovDelta >= FAST_FOV_THRESHOLD_DEGREES;\n\n if (!viewChanged) {\n return;\n }\n\n const needsImmediateUpdate =\n visibilityDirtyRef.current ||\n viewportChanged ||\n movingQuickly;\n if (\n !needsImmediateUpdate &&\n now - lastUpdateAtRef.current < MAX_LOD_UPDATE_INTERVAL_MS\n ) {\n return;\n }\n\n lastUpdateAtRef.current = now;\n\n const targetLevel = loadMode === \"base\"\n ? 1\n : getPreferredLevel(\n levels,\n size.height,\n pixelRatio,\n camera.fov,\n currentLevelRef.current,\n );\n if (targetLevel !== currentLevelRef.current) {\n currentLevelRef.current = targetLevel;\n levelChangeRef.current?.(targetLevel);\n }\n\n const visibilityCamera = visibilityCameraRef.current;\n visibilityCamera.copy(camera, false);\n visibilityCamera.fov = Math.min(\n 179,\n camera.fov + VISIBILITY_FOV_PADDING_DEGREES,\n );\n visibilityCamera.aspect = camera.aspect;\n updateVisibilityFrustum(\n visibilityCamera,\n projectionMatrixRef.current,\n frustumRef.current,\n );\n\n const nextLayers = buildLayers(\n targetLevel,\n levels,\n tileSize,\n frustumRef.current,\n camera,\n candidatesByLevel,\n );\n visibilityDirtyRef.current = false;\n lastVisibilityQuaternionRef.current.copy(camera.quaternion);\n lastVisibilityFovRef.current = camera.fov;\n lastViewportRef.current = {\n width: size.width,\n height: size.height,\n dpr: pixelRatio,\n };\n commitLayers(nextLayers);\n });\n\n return (\n <group visible={visible}>\n {previewTexture ? (\n <PreviewCube\n texture={previewTexture}\n faceOrder={previewFaceOrder}\n />\n ) : null}\n {layers.map((layer) => (\n <TileLayerMeshes\n key={layer.level}\n layer={layer}\n manager={manager}\n resolveUrl={resolveUrl}\n />\n ))}\n </group>\n );\n}\n","import {\n Box3,\n Euler,\n Quaternion,\n Vector3,\n} from \"three\";\nimport type { CubeFaceCode, TileAddress } from \"./types\";\nimport { DEFAULT_PANORAMA_RADIUS } from \"../panorama-radius\";\n\nexport const CUBE_FACES: CubeFaceCode[] = [\"f\", \"r\", \"b\", \"l\", \"u\", \"d\"];\nexport const PREVIEW_FACE_ORDER: CubeFaceCode[] = [\"l\", \"f\", \"r\", \"b\", \"u\", \"d\"];\nexport const CUBE_RADIUS = DEFAULT_PANORAMA_RADIUS;\n\nexport type FaceTransform = {\n position: [number, number, number];\n rotation: [number, number, number];\n};\n\nexport function getFaceTransform(\n face: CubeFaceCode,\n radius = CUBE_RADIUS,\n): FaceTransform {\n switch (face) {\n case \"f\":\n return { position: [0, 0, -radius], rotation: [0, 0, 0] };\n case \"b\":\n return { position: [0, 0, radius], rotation: [0, Math.PI, 0] };\n case \"r\":\n return {\n position: [radius, 0, 0],\n rotation: [0, -Math.PI / 2, 0],\n };\n case \"l\":\n return {\n position: [-radius, 0, 0],\n rotation: [0, Math.PI / 2, 0],\n };\n case \"u\":\n return {\n position: [0, radius, 0],\n rotation: [Math.PI / 2, 0, 0],\n };\n case \"d\":\n return {\n position: [0, -radius, 0],\n rotation: [-Math.PI / 2, 0, 0],\n };\n }\n}\n\nexport function getTileLocalLayout(address: TileAddress, radius = CUBE_RADIUS) {\n const left = (address.col - 1) * address.tileSize;\n const top = (address.row - 1) * address.tileSize;\n const right = left + address.width;\n const bottom = top + address.height;\n return {\n x: (((left + right) / address.faceSize) - 1) * radius,\n y: (1 - (top + bottom) / address.faceSize) * radius,\n width: (address.width / address.faceSize) * radius * 2,\n height: (address.height / address.faceSize) * radius * 2,\n };\n}\n\nconst faceQuaternionCache = new Map<CubeFaceCode, Quaternion>();\n\nfunction getFaceQuaternion(face: CubeFaceCode): Quaternion {\n const cached = faceQuaternionCache.get(face);\n if (cached) {\n return cached;\n }\n const transform = getFaceTransform(face);\n const quaternion = new Quaternion().setFromEuler(\n new Euler(...transform.rotation, \"XYZ\"),\n );\n faceQuaternionCache.set(face, quaternion);\n return quaternion;\n}\n\nexport function getTileBoundingBox(\n address: TileAddress,\n radius = CUBE_RADIUS,\n): Box3 {\n const transform = getFaceTransform(address.face, radius);\n const local = getTileLocalLayout(address, radius);\n const halfWidth = local.width / 2;\n const halfHeight = local.height / 2;\n const quaternion = getFaceQuaternion(address.face);\n const position = new Vector3(...transform.position);\n const corners = [\n new Vector3(local.x - halfWidth, local.y - halfHeight, 0),\n new Vector3(local.x + halfWidth, local.y - halfHeight, 0),\n new Vector3(local.x - halfWidth, local.y + halfHeight, 0),\n new Vector3(local.x + halfWidth, local.y + halfHeight, 0),\n ];\n\n for (const corner of corners) {\n corner.applyQuaternion(quaternion).add(position);\n }\n\n return new Box3().setFromPoints(corners);\n}\n\nexport function makeTileAddress(\n face: CubeFaceCode,\n level: number,\n faceSize: number,\n tileSize: number,\n col: number,\n row: number,\n): TileAddress {\n const left = (col - 1) * tileSize;\n const top = (row - 1) * tileSize;\n return {\n face,\n level,\n row,\n col,\n faceSize,\n tileSize,\n width: Math.min(tileSize, faceSize - left),\n height: Math.min(tileSize, faceSize - top),\n };\n}\n\nexport function tileKey(address: TileAddress): string {\n return `${address.level}/${address.face}/${address.row}/${address.col}`;\n}\n\nexport function getPreferredLevel(\n levels: number[],\n viewportHeight: number,\n pixelRatio: number,\n verticalFov: number,\n currentLevel: number,\n): number {\n const requiredFaceSize =\n viewportHeight * pixelRatio * (90 / Math.max(verticalFov, 1));\n let preferredLevel = levels.length;\n for (let index = 0; index < levels.length; index += 1) {\n if (levels[index]! >= requiredFaceSize) {\n preferredLevel = index + 1;\n break;\n }\n }\n\n if (preferredLevel > currentLevel) {\n const currentSize = levels[currentLevel - 1] ?? levels[0]!;\n return requiredFaceSize > currentSize * 1.2\n ? preferredLevel\n : currentLevel;\n }\n if (preferredLevel < currentLevel) {\n const preferredSize = levels[preferredLevel - 1] ?? levels[0]!;\n return requiredFaceSize < preferredSize * 0.8\n ? preferredLevel\n : currentLevel;\n }\n return currentLevel;\n}\n\nexport function previewAtlasVRange(\n face: CubeFaceCode,\n faceOrder: readonly CubeFaceCode[] = PREVIEW_FACE_ORDER,\n): {\n offset: number;\n scale: number;\n} {\n const index = faceOrder.indexOf(face);\n return {\n offset: (faceOrder.length - index - 1) / faceOrder.length,\n scale: 1 / faceOrder.length,\n };\n}\n","import type {\n TileAddress,\n TileMultiresConfig,\n} from \"./types\";\n\nfunction positiveInteger(value: number, name: string): number {\n if (!Number.isFinite(value) || value <= 0 || !Number.isInteger(value)) {\n throw new Error(`${name} must be a positive integer, received ${String(value)}`);\n }\n return value;\n}\n\nfunction ascendingLevels(levels: number[]): number[] {\n for (let index = 1; index < levels.length; index += 1) {\n if (levels[index]! <= levels[index - 1]!) {\n throw new Error(\"multires face sizes must be strictly ascending\");\n }\n }\n return levels;\n}\n\nexport function parseMultires(\n multires: string | TileMultiresConfig,\n): TileMultiresConfig {\n if (typeof multires !== \"string\") {\n const tileSize = positiveInteger(multires.tileSize, \"multires.tileSize\");\n if (multires.levels.length === 0) {\n throw new Error(\"multires.levels must contain at least one face size\");\n }\n const levels = ascendingLevels(\n multires.levels.map((level, index) =>\n positiveInteger(level, `multires.levels[${index}]`),\n ),\n );\n return { tileSize, levels };\n }\n\n const values = multires.split(\",\").map((part) => Number(part.trim()));\n\n if (values.length < 2 || values.some((value) => !Number.isFinite(value))) {\n throw new Error(\n \"multires must contain a tile size followed by at least one face size\",\n );\n }\n\n const tileSize = positiveInteger(values[0]!, \"multires tile size\");\n const levels = ascendingLevels(\n values.slice(1).map((level, index) =>\n positiveInteger(level, `multires level ${index + 1}`),\n ),\n );\n return { tileSize, levels };\n}\n\nexport function buildDefaultTileUrlTemplate(): string {\n return \"tiles/%s/l%l/%v/l%l_%s_%h_%v.webp\";\n}\n\nexport function resolveRelativeTileUrl(\n baseUrl: string,\n relativePath: string,\n): string {\n const normalizedBaseUrl = baseUrl.replace(/\\/+$/, \"\");\n const normalizedPath = relativePath.replace(/^\\/+/, \"\");\n return normalizedBaseUrl\n ? `${normalizedBaseUrl}/${normalizedPath}`\n : normalizedPath;\n}\n\nexport function resolveTemplateUrl(\n template: string,\n address: TileAddress,\n): string {\n return template\n .replace(/%s/g, address.face)\n .replace(/%l/g, String(address.level))\n .replace(/%(0*)([hxucvywr])/g, (_match, zeroes: string, placeholder: string) => {\n const value = \"hxuc\".includes(placeholder)\n ? address.col\n : address.row;\n return String(value).padStart(zeroes.length + 1, \"0\");\n });\n}\n","import { useThree } from \"@react-three/fiber\";\nimport { useEffect, useRef, useState } from \"react\";\nimport {\n ClampToEdgeWrapping,\n DoubleSide,\n LinearFilter,\n LinearMipmapLinearFilter,\n SRGBColorSpace,\n Texture,\n TextureLoader,\n} from \"three\";\nimport { HotspotAnchor } from \"./hotspot-anchor\";\nimport type { HotspotCommonProps } from \"./types\";\n\nexport type ImageHotspotProps = HotspotCommonProps & {\n src: string;\n onLoad?: (texture: Texture) => void;\n onError?: (error: unknown) => void;\n};\n\nfunction clampOpacity(opacity: number | undefined): number {\n if (!Number.isFinite(opacity)) {\n return 1;\n }\n return Math.max(0, Math.min(opacity!, 1));\n}\n\nfunction useHotspotImageTexture(\n src: string,\n onLoad: ImageHotspotProps[\"onLoad\"],\n onError: ImageHotspotProps[\"onError\"],\n) {\n const gl = useThree((state) => state.gl);\n const [texture, setTexture] = useState<Texture | null>(null);\n const onLoadRef = useRef(onLoad);\n const onErrorRef = useRef(onError);\n onLoadRef.current = onLoad;\n onErrorRef.current = onError;\n\n useEffect(() => {\n let active = true;\n setTexture(null);\n if (!src) {\n return () => {\n active = false;\n };\n }\n\n const loader = new TextureLoader();\n loader.load(\n src,\n (loadedTexture) => {\n if (!active) {\n loadedTexture.dispose();\n return;\n }\n loadedTexture.colorSpace = SRGBColorSpace;\n loadedTexture.wrapS = ClampToEdgeWrapping;\n loadedTexture.wrapT = ClampToEdgeWrapping;\n loadedTexture.magFilter = LinearFilter;\n loadedTexture.minFilter = LinearMipmapLinearFilter;\n loadedTexture.generateMipmaps = true;\n loadedTexture.anisotropy = gl.capabilities.getMaxAnisotropy();\n loadedTexture.needsUpdate = true;\n setTexture(loadedTexture);\n onLoadRef.current?.(loadedTexture);\n },\n undefined,\n (error) => {\n if (active) {\n onErrorRef.current?.(error);\n }\n },\n );\n\n return () => {\n active = false;\n };\n }, [gl, src]);\n\n useEffect(\n () => () => {\n texture?.dispose();\n },\n [texture],\n );\n\n return texture;\n}\n\nexport function ImageHotspot({\n src,\n width = 12,\n height = 8,\n opacity,\n onLoad,\n onError,\n ...anchorProps\n}: ImageHotspotProps) {\n const texture = useHotspotImageTexture(src, onLoad, onError);\n\n return (\n <HotspotAnchor {...anchorProps} height={height} width={width}>\n <mesh>\n <planeGeometry args={[1, 1]} />\n <meshBasicMaterial\n map={texture}\n opacity={texture ? clampOpacity(opacity) : 0}\n side={DoubleSide}\n toneMapped={false}\n transparent\n />\n </mesh>\n </HotspotAnchor>\n );\n}\n","import type { ThreeEvent } from \"@react-three/fiber\";\nimport { useFrame } from \"@react-three/fiber\";\nimport {\n useContext,\n useEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport type { ReactNode } from \"react\";\nimport {\n EdgesGeometry,\n MathUtils,\n Matrix4,\n Object3D,\n PlaneGeometry,\n PerspectiveCamera,\n Quaternion,\n Vector3,\n} from \"three\";\nimport { PanoramaViewContext } from \"../panorama-view-runtime\";\nimport { DEFAULT_PANORAMA_RADIUS } from \"../panorama-radius\";\nimport { useHotspotAccessibility } from \"./accessibility\";\nimport {\n normalizePanoPosition,\n panoPositionToVector3,\n vector3ToPanoPosition,\n} from \"./coordinates\";\nimport type {\n HotspotCommonProps,\n HotspotInteractionEvent,\n HotspotMode,\n HotspotPosition,\n} from \"./types\";\n\nconst DEFAULT_FLOATING_DISTANCE = 10;\nconst PANORAMA_RADIUS = DEFAULT_PANORAMA_RADIUS;\n// Keep a stable gap from the shell; a sub-unit gap z-fights at radius 1000.\nconst PANORAMA_SURFACE_INSET = 4;\nconst DEFAULT_REFERENCE_FOV = 75;\nconst MIN_ANGULAR_SIZE = 0.01;\nconst MAX_ANGULAR_SIZE = 179;\nconst DRAG_EPSILON_DEGREES = 0.001;\nconst LOCAL_FORWARD = new Vector3(0, 0, 1);\nconst HOTSPOT_MODE_RENDERING: Record<\n HotspotMode,\n { orientation: \"billboard\" | \"surface\"; placement: \"surface\" | \"floating\" }\n> = {\n surface: { orientation: \"surface\", placement: \"surface\" },\n billboard: { orientation: \"billboard\", placement: \"floating\" },\n};\n\ntype DragState = {\n pointerId: number;\n startPosition: HotspotPosition;\n releaseInteractionLock: () => void;\n moved: boolean;\n};\n\nexport type HotspotAnchorProps = Omit<HotspotCommonProps, \"opacity\"> & {\n width: number;\n height: number;\n /** Internal escape hatch for world-space children such as polygons. */\n useAngularScale?: boolean;\n focusContent?: ReactNode;\n children?: ReactNode;\n /** Private support for world-space polygon and polyline primitives. */\n internalOrientation?: \"billboard\" | \"surface\";\n /** Private support for world-space polygon and polyline primitives. */\n internalPlacement?: \"surface\" | \"floating\";\n};\n\nfunction angularSizeToWorldSize(size: number, radius: number): number {\n const safeSize = Number.isFinite(size)\n ? MathUtils.clamp(Math.abs(size), MIN_ANGULAR_SIZE, MAX_ANGULAR_SIZE)\n : MIN_ANGULAR_SIZE;\n return 2 * radius * Math.tan(MathUtils.degToRad(safeSize) / 2);\n}\n\nfunction resolveScale(scale: number | undefined): number {\n return Number.isFinite(scale) && scale! > 0 ? scale! : 1;\n}\n\nfunction resolveDistance(\n placement: \"surface\" | \"floating\",\n distance: number | undefined,\n width: number,\n height: number,\n): number {\n const maximumDistance = maximumHotspotDistance(width, height);\n if (placement === \"surface\") {\n return maximumDistance;\n }\n if (!Number.isFinite(distance)) {\n return DEFAULT_FLOATING_DISTANCE;\n }\n return MathUtils.clamp(Math.abs(distance!), 0.1, maximumDistance);\n}\n\nfunction maximumHotspotDistance(width: number, height: number): number {\n const safeWidth = MathUtils.clamp(\n Math.abs(Number.isFinite(width) ? width : MIN_ANGULAR_SIZE),\n MIN_ANGULAR_SIZE,\n MAX_ANGULAR_SIZE,\n );\n const safeHeight = MathUtils.clamp(\n Math.abs(Number.isFinite(height) ? height : MIN_ANGULAR_SIZE),\n MIN_ANGULAR_SIZE,\n MAX_ANGULAR_SIZE,\n );\n const cornerFactor = Math.hypot(\n 1,\n Math.tan(MathUtils.degToRad(safeWidth) / 2),\n Math.tan(MathUtils.degToRad(safeHeight) / 2),\n );\n return (PANORAMA_RADIUS - PANORAMA_SURFACE_INSET) / cornerFactor;\n}\n\nfunction fixedScaleFactor(cameraFov: number, referenceFov: number): number {\n const safeReferenceFov = MathUtils.clamp(referenceFov, 1, 179);\n return (\n Math.tan(MathUtils.degToRad(cameraFov) / 2) /\n Math.tan(MathUtils.degToRad(safeReferenceFov) / 2)\n );\n}\n\nfunction createSurfaceQuaternion(position: HotspotPosition): Quaternion {\n const outward = panoPositionToVector3(position).normalize();\n const inward = outward.clone().negate();\n const pitch = MathUtils.degToRad(position.pitch);\n const yaw = MathUtils.degToRad(position.yaw);\n const localUp = new Vector3(\n -Math.sin(pitch) * Math.sin(yaw),\n Math.cos(pitch),\n Math.sin(pitch) * Math.cos(yaw),\n ).normalize();\n const localRight = localUp.clone().cross(inward).normalize();\n const basis = new Matrix4().makeBasis(localRight, localUp, inward);\n return new Quaternion().setFromRotationMatrix(basis);\n}\n\nfunction makeInteractionEvent(\n id: string,\n position: HotspotPosition,\n event: ThreeEvent<MouseEvent | PointerEvent>,\n): HotspotInteractionEvent {\n return {\n id,\n position: normalizePanoPosition(position),\n source: \"pointer\",\n nativeEvent: event.nativeEvent,\n };\n}\n\nfunction angularDistance(a: HotspotPosition, b: HotspotPosition): number {\n const aVector = panoPositionToVector3(a);\n const bVector = panoPositionToVector3(b);\n return MathUtils.radToDeg(aVector.angleTo(bVector));\n}\n\n/** Internal spatial and interaction primitive shared by concrete hotspots. */\nexport function HotspotAnchor({\n id,\n position,\n width,\n height,\n scale = 1,\n useAngularScale = true,\n focusContent,\n mode = \"billboard\",\n distance,\n internalOrientation,\n internalPlacement,\n scaleMode = \"fov\",\n referenceFov = DEFAULT_REFERENCE_FOV,\n rotation = 0,\n renderOrder = 0,\n visible = true,\n draggable = false,\n interactive = true,\n ariaLabel,\n children,\n onClick,\n onHoverChange,\n onDragStart,\n onPositionChange,\n onDragEnd,\n}: HotspotAnchorProps) {\n const controlsRef = useContext(PanoramaViewContext);\n const groupRef = useRef<Object3D>(null);\n const dragStateRef = useRef<DragState | null>(null);\n const suppressNextClickRef = useRef(false);\n const normalizedPosition = normalizePanoPosition(position);\n const rendering =\n internalOrientation && internalPlacement\n ? { orientation: internalOrientation, placement: internalPlacement }\n : HOTSPOT_MODE_RENDERING[mode];\n const { orientation, placement } = rendering;\n const resolvedScale = resolveScale(scale);\n const scaledWidth = width * resolvedScale;\n const scaledHeight = height * resolvedScale;\n const resolvedDistance = resolveDistance(\n placement,\n distance,\n scaledWidth,\n scaledHeight,\n );\n const worldPosition = useMemo(\n () => panoPositionToVector3(normalizedPosition, resolvedDistance),\n [normalizedPosition.pitch, normalizedPosition.yaw, resolvedDistance],\n );\n const surfaceQuaternion = useMemo(\n () => createSurfaceQuaternion(normalizedPosition),\n [normalizedPosition.pitch, normalizedPosition.yaw],\n );\n const worldWidth = angularSizeToWorldSize(scaledWidth, resolvedDistance);\n const worldHeight = angularSizeToWorldSize(scaledHeight, resolvedDistance);\n const focusGeometry = useMemo(() => {\n const planeGeometry = new PlaneGeometry(1, 1);\n const geometry = new EdgesGeometry(planeGeometry);\n planeGeometry.dispose();\n return geometry;\n }, []);\n const focused = useHotspotAccessibility({\n id,\n ariaLabel,\n onActivate: visible && interactive && onClick\n ? (event) => {\n onClick({\n id,\n position: normalizedPosition,\n source: \"keyboard\",\n nativeEvent: event,\n });\n }\n : undefined,\n });\n\n useEffect(\n () => () => {\n dragStateRef.current?.releaseInteractionLock();\n dragStateRef.current = null;\n },\n [],\n );\n\n useEffect(() => () => focusGeometry.dispose(), [focusGeometry]);\n\n useFrame(({ camera }) => {\n if (!groupRef.current) {\n return;\n }\n if (orientation === \"billboard\") {\n groupRef.current.quaternion.copy(camera.quaternion);\n } else {\n groupRef.current.quaternion.copy(surfaceQuaternion);\n }\n groupRef.current.rotateOnAxis(\n LOCAL_FORWARD,\n MathUtils.degToRad(-rotation),\n );\n const scaleFactor =\n scaleMode === \"fixed\" && camera instanceof PerspectiveCamera\n ? fixedScaleFactor(camera.fov, referenceFov)\n : 1;\n groupRef.current.scale.set(\n (useAngularScale ? worldWidth : 1) * scaleFactor,\n (useAngularScale ? worldHeight : 1) * scaleFactor,\n 1,\n );\n });\n\n const stopPointerEvent = (event: ThreeEvent<MouseEvent | PointerEvent>) => {\n event.stopPropagation();\n event.nativeEvent.stopImmediatePropagation?.();\n };\n\n const releasePointer = (\n event: ThreeEvent<PointerEvent>,\n emitDragEnd: boolean,\n ) => {\n const dragState = dragStateRef.current;\n if (!dragState || dragState.pointerId !== event.pointerId) {\n return;\n }\n\n stopPointerEvent(event);\n const target = event.target as Element;\n if (target.hasPointerCapture?.(event.pointerId)) {\n target.releasePointerCapture?.(event.pointerId);\n }\n const nextPosition = vector3ToPanoPosition(event.ray.direction);\n if (emitDragEnd) {\n onDragEnd?.({\n ...makeInteractionEvent(id, nextPosition, event),\n source: \"pointer\",\n startPosition: dragState.startPosition,\n });\n }\n suppressNextClickRef.current = dragState.moved;\n dragState.releaseInteractionLock();\n dragStateRef.current = null;\n };\n\n return (\n <group\n ref={groupRef}\n position={worldPosition}\n renderOrder={renderOrder}\n scale={[worldWidth, worldHeight, 1]}\n visible={visible}\n onClick={interactive ? (event) => {\n stopPointerEvent(event);\n if (!suppressNextClickRef.current) {\n onClick?.(makeInteractionEvent(id, normalizedPosition, event));\n }\n suppressNextClickRef.current = false;\n } : undefined}\n onLostPointerCapture={interactive ? (event) => releasePointer(event, false) : undefined}\n onPointerCancel={interactive ? (event) => releasePointer(event, false) : undefined}\n onPointerDown={interactive ? (event) => {\n stopPointerEvent(event);\n if (!draggable || dragStateRef.current) {\n return;\n }\n const releaseInteractionLock =\n controlsRef?.current?.acquireInteractionLock() ?? (() => undefined);\n const target = event.target as Element;\n target.setPointerCapture?.(event.pointerId);\n const startPosition = { ...normalizedPosition };\n dragStateRef.current = {\n pointerId: event.pointerId,\n startPosition,\n releaseInteractionLock,\n moved: false,\n };\n onDragStart?.({\n ...makeInteractionEvent(id, startPosition, event),\n source: \"pointer\",\n startPosition,\n });\n } : undefined}\n onPointerMove={interactive ? (event) => {\n const dragState = dragStateRef.current;\n if (!dragState || dragState.pointerId !== event.pointerId) {\n return;\n }\n stopPointerEvent(event);\n const nextPosition = vector3ToPanoPosition(event.ray.direction);\n dragState.moved ||=\n angularDistance(dragState.startPosition, nextPosition) >\n DRAG_EPSILON_DEGREES;\n onPositionChange?.({\n ...makeInteractionEvent(id, nextPosition, event),\n source: \"pointer\",\n startPosition: dragState.startPosition,\n });\n } : undefined}\n onPointerOut={interactive ? (event) => {\n if (!dragStateRef.current) {\n onHoverChange?.(\n false,\n makeInteractionEvent(id, normalizedPosition, event),\n );\n }\n } : undefined}\n onPointerOver={interactive ? (event) => {\n if (!dragStateRef.current) {\n onHoverChange?.(\n true,\n makeInteractionEvent(id, normalizedPosition, event),\n );\n }\n } : undefined}\n onPointerUp={interactive ? (event) => releasePointer(event, true) : undefined}\n >\n {focused ? (focusContent ?? (\n <lineSegments\n geometry={focusGeometry}\n position={[0, 0, 0.01]}\n renderOrder={renderOrder + 1}\n scale={[1.12, 1.12, 1]}\n >\n <lineBasicMaterial color=\"#f5fbfc\" depthTest={false} />\n </lineSegments>\n )) : null}\n {children}\n </group>\n );\n}\n","import { useThree } from \"@react-three/fiber\";\nimport { useEffect, useMemo, useRef } from \"react\";\nimport {\n BufferGeometry,\n ColorRepresentation,\n DoubleSide,\n Float32BufferAttribute,\n Matrix4,\n Quaternion,\n ShapeUtils,\n Vector2,\n Vector3,\n} from \"three\";\nimport { Line2 } from \"three/addons/lines/Line2.js\";\nimport { LineGeometry } from \"three/addons/lines/LineGeometry.js\";\nimport { LineMaterial } from \"three/addons/lines/LineMaterial.js\";\nimport { HotspotAnchor } from \"./hotspot-anchor\";\nimport {\n clampPanoPitch,\n normalizePanoPosition,\n normalizePanoYaw,\n panoPositionToVector3,\n vector3ToPanoPosition,\n} from \"./coordinates\";\nimport type {\n HotspotCommonProps,\n HotspotDragEvent,\n HotspotInteractionEvent,\n HotspotPosition,\n} from \"./types\";\n\nconst POLYGON_RADIUS = 990;\nconst MAX_FILL_SEGMENT_DEGREES = 7;\n\nexport type PolygonValidationCode =\n | \"too_few_vertices\"\n | \"self_intersection\"\n | \"contains_pole\"\n | \"outside_hemisphere\";\n\nexport type PolygonValidationIssue = {\n code: PolygonValidationCode;\n message: string;\n};\n\nexport type PolygonVerticesChangeEvent = {\n id: string;\n vertices: HotspotPosition[];\n startVertices: HotspotPosition[];\n position: HotspotPosition;\n startPosition: HotspotPosition;\n};\n\nexport type PolygonHotspotProps = Omit<\n HotspotCommonProps,\n | \"position\"\n | \"width\"\n | \"height\"\n | \"scale\"\n | \"mode\"\n | \"distance\"\n | \"scaleMode\"\n | \"rotation\"\n | \"onDragStart\"\n | \"onPositionChange\"\n | \"onDragEnd\"\n> & {\n vertices: HotspotPosition[];\n fill?: ColorRepresentation;\n fillOpacity?: number;\n stroke?: ColorRepresentation;\n /** Screen-space border width in CSS pixels. Defaults to 2. */\n strokeWidth?: number;\n /** Opacity of the polygon boundary, from 0 to 1. Defaults to 1. */\n strokeOpacity?: number;\n onVerticesChange?: (event: PolygonVerticesChangeEvent) => void;\n onDragStart?: (event: PolygonVerticesChangeEvent) => void;\n onDragEnd?: (event: PolygonVerticesChangeEvent) => void;\n onInvalid?: (issues: PolygonValidationIssue[]) => void;\n};\n\ntype UnwrappedVertex = HotspotPosition & { unwrappedYaw: number };\n\nfunction cloneVertices(vertices: HotspotPosition[]): HotspotPosition[] {\n return vertices.map((vertex) => normalizePanoPosition(vertex));\n}\n\nexport function unwrapPolygonVertices(\n vertices: HotspotPosition[],\n): UnwrappedVertex[] {\n const unwrapped: UnwrappedVertex[] = [];\n for (const vertex of vertices) {\n const normalized = normalizePanoPosition(vertex);\n const previous = unwrapped[unwrapped.length - 1];\n if (!previous) {\n unwrapped.push({ ...normalized, unwrappedYaw: normalized.yaw });\n continue;\n }\n const previousYaw = previous.unwrappedYaw;\n let yaw = normalized.yaw;\n while (yaw - previousYaw > 180) yaw -= 360;\n while (yaw - previousYaw <= -180) yaw += 360;\n unwrapped.push({ ...normalized, unwrappedYaw: yaw });\n }\n return unwrapped;\n}\n\nfunction orientation(a: Vector2, b: Vector2, c: Vector2): number {\n return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);\n}\n\nfunction intersects(a: Vector2, b: Vector2, c: Vector2, d: Vector2): boolean {\n const abC = orientation(a, b, c);\n const abD = orientation(a, b, d);\n const cdA = orientation(c, d, a);\n const cdB = orientation(c, d, b);\n return (\n Math.sign(abC) !== Math.sign(abD) &&\n Math.sign(cdA) !== Math.sign(cdB)\n );\n}\n\nfunction hasSelfIntersection(vertices: UnwrappedVertex[]): boolean {\n const points = vertices.map((vertex) =>\n new Vector2(vertex.unwrappedYaw, vertex.pitch),\n );\n for (let index = 0; index < points.length; index += 1) {\n const nextIndex = (index + 1) % points.length;\n for (let other = index + 1; other < points.length; other += 1) {\n const otherNext = (other + 1) % points.length;\n if (\n index === other ||\n nextIndex === other ||\n otherNext === index ||\n (index === 0 && otherNext === 0)\n ) {\n continue;\n }\n if (intersects(points[index]!, points[nextIndex]!, points[other]!, points[otherNext]!)) {\n return true;\n }\n }\n }\n return false;\n}\n\nfunction polygonContainsDirection(\n vertices: HotspotPosition[],\n direction: Vector3,\n): boolean {\n let winding = 0;\n for (let index = 0; index < vertices.length; index += 1) {\n const a = panoPositionToVector3(vertices[index]!).normalize();\n const b = panoPositionToVector3(vertices[(index + 1) % vertices.length]!).normalize();\n const projectedA = a.clone().addScaledVector(direction, -a.dot(direction));\n const projectedB = b.clone().addScaledVector(direction, -b.dot(direction));\n if (projectedA.lengthSq() < 1e-8 || projectedB.lengthSq() < 1e-8) {\n return false;\n }\n projectedA.normalize();\n projectedB.normalize();\n winding += Math.atan2(\n direction.dot(projectedA.clone().cross(projectedB)),\n projectedA.dot(projectedB),\n );\n }\n return Math.abs(winding) > Math.PI;\n}\n\nfunction fitsHemisphere(vertices: HotspotPosition[]): boolean {\n const directions = vertices.map((vertex) => panoPositionToVector3(vertex).normalize());\n const candidates = [new Vector3()];\n for (const direction of directions) {\n candidates[0]!.add(direction);\n candidates.push(direction.clone());\n }\n for (let index = 0; index < directions.length; index += 1) {\n for (let other = index + 1; other < directions.length; other += 1) {\n candidates.push(directions[index]!.clone().add(directions[other]!));\n }\n }\n return candidates.some((candidate) =>\n candidate.lengthSq() > 1e-8 &&\n directions.every((direction) => candidate.dot(direction) > 1e-6),\n );\n}\n\nexport function validatePolygonVertices(\n vertices: HotspotPosition[],\n): PolygonValidationIssue[] {\n if (vertices.length < 3) {\n return [{ code: \"too_few_vertices\", message: \"A polygon needs at least three vertices.\" }];\n }\n const normalized = cloneVertices(vertices);\n const unwrapped = unwrapPolygonVertices(normalized);\n const issues: PolygonValidationIssue[] = [];\n if (hasSelfIntersection(unwrapped)) {\n issues.push({ code: \"self_intersection\", message: \"Polygon edges cannot cross.\" });\n }\n if (\n polygonContainsDirection(normalized, new Vector3(0, 1, 0)) ||\n polygonContainsDirection(normalized, new Vector3(0, -1, 0))\n ) {\n issues.push({ code: \"contains_pole\", message: \"Polygons cannot contain a panorama pole.\" });\n }\n if (!fitsHemisphere(normalized)) {\n issues.push({ code: \"outside_hemisphere\", message: \"Polygons must fit within one hemisphere.\" });\n }\n return issues;\n}\n\nfunction polygonCenter(vertices: HotspotPosition[]): HotspotPosition {\n const sum = vertices.reduce(\n (total, vertex) => total.add(panoPositionToVector3(vertex).normalize()),\n new Vector3(),\n );\n return sum.lengthSq() > 1e-8\n ? vector3ToPanoPosition(sum)\n : normalizePanoPosition(vertices[0]!);\n}\n\nfunction surfaceQuaternion(position: HotspotPosition): Quaternion {\n const outward = panoPositionToVector3(position).normalize();\n const inward = outward.clone().negate();\n const pitch = (position.pitch * Math.PI) / 180;\n const yaw = (position.yaw * Math.PI) / 180;\n const localUp = new Vector3(\n -Math.sin(pitch) * Math.sin(yaw),\n Math.cos(pitch),\n Math.sin(pitch) * Math.cos(yaw),\n ).normalize();\n return new Quaternion().setFromRotationMatrix(\n new Matrix4().makeBasis(localUp.clone().cross(inward).normalize(), localUp, inward),\n );\n}\n\nfunction makeWorldToLocal(center: HotspotPosition): Matrix4 {\n return new Matrix4()\n .compose(\n panoPositionToVector3(center, POLYGON_RADIUS),\n surfaceQuaternion(center),\n new Vector3(1, 1, 1),\n )\n .invert();\n}\n\nfunction projectedPoint(\n a: UnwrappedVertex,\n b: UnwrappedVertex,\n c: UnwrappedVertex,\n weightB: number,\n weightC: number,\n radius: number,\n worldToLocal: Matrix4,\n): Vector3 {\n const weightA = 1 - weightB - weightC;\n return panoPositionToVector3(\n {\n yaw: a.unwrappedYaw * weightA + b.unwrappedYaw * weightB + c.unwrappedYaw * weightC,\n pitch: a.pitch * weightA + b.pitch * weightB + c.pitch * weightC,\n },\n radius,\n ).applyMatrix4(worldToLocal);\n}\n\nfunction polygonSubdivisionSteps(vertices: HotspotPosition[]): number {\n let maxAngle = 0;\n for (let index = 0; index < vertices.length; index += 1) {\n const start = panoPositionToVector3(vertices[index]!).normalize();\n for (let other = index + 1; other < vertices.length; other += 1) {\n maxAngle = Math.max(\n maxAngle,\n start.angleTo(panoPositionToVector3(vertices[other]!).normalize()),\n );\n }\n }\n return Math.min(\n 8,\n Math.max(1, Math.ceil((maxAngle * 180) / Math.PI / MAX_FILL_SEGMENT_DEGREES)),\n );\n}\n\nfunction addSubdividedTriangle(\n positions: number[],\n indices: number[],\n a: UnwrappedVertex,\n b: UnwrappedVertex,\n c: UnwrappedVertex,\n worldToLocal: Matrix4,\n steps: number,\n): void {\n const grid = new Map<string, number>();\n const pointIndex = (i: number, j: number) => {\n const key = `${i}:${j}`;\n const existing = grid.get(key);\n if (existing !== undefined) return existing;\n const point = projectedPoint(a, b, c, i / steps, j / steps, POLYGON_RADIUS, worldToLocal);\n const index = positions.length / 3;\n positions.push(point.x, point.y, point.z);\n grid.set(key, index);\n return index;\n };\n for (let i = 0; i <= steps; i += 1) {\n for (let j = 0; j <= steps - i; j += 1) pointIndex(i, j);\n }\n for (let i = 0; i < steps; i += 1) {\n for (let j = 0; j < steps - i; j += 1) {\n indices.push(pointIndex(i, j), pointIndex(i + 1, j), pointIndex(i, j + 1));\n if (i + j < steps - 1) {\n indices.push(pointIndex(i + 1, j), pointIndex(i + 1, j + 1), pointIndex(i, j + 1));\n }\n }\n }\n}\n\nfunction makeFillGeometry(vertices: HotspotPosition[], center: HotspotPosition): BufferGeometry {\n const unwrapped = unwrapPolygonVertices(vertices);\n const contour = unwrapped.map((vertex) => new Vector2(vertex.unwrappedYaw, vertex.pitch));\n const triangles = ShapeUtils.triangulateShape(contour, []);\n const positions: number[] = [];\n const indices: number[] = [];\n const worldToLocal = makeWorldToLocal(center);\n const steps = polygonSubdivisionSteps(vertices);\n for (const [a, b, c] of triangles) {\n addSubdividedTriangle(\n positions,\n indices,\n unwrapped[a]!,\n unwrapped[b]!,\n unwrapped[c]!,\n worldToLocal,\n steps,\n );\n }\n return new BufferGeometry()\n .setAttribute(\"position\", new Float32BufferAttribute(positions, 3))\n .setIndex(indices);\n}\n\nfunction makeStrokePositions(\n vertices: HotspotPosition[],\n center: HotspotPosition,\n): number[] {\n const positions: number[] = [];\n const worldToLocal = makeWorldToLocal(center);\n const unwrapped = unwrapPolygonVertices(vertices);\n const steps = polygonSubdivisionSteps(vertices);\n\n for (let edge = 0; edge < unwrapped.length; edge += 1) {\n const start = unwrapped[edge]!;\n const end = unwrapped[(edge + 1) % unwrapped.length]!;\n\n // This is intentionally the same yaw/pitch interpolation and segment\n // density used by the fill geometry. The outline therefore sits directly\n // on its outer boundary instead of following a different great-circle arc.\n for (let step = 0; step < steps; step += 1) {\n const progress = step / steps;\n const point = panoPositionToVector3(\n {\n yaw: start.unwrappedYaw + (end.unwrappedYaw - start.unwrappedYaw) * progress,\n pitch: start.pitch + (end.pitch - start.pitch) * progress,\n },\n POLYGON_RADIUS,\n )\n .applyMatrix4(worldToLocal);\n positions.push(point.x, point.y, point.z);\n }\n }\n positions.push(...positions.slice(0, 3));\n return positions;\n}\n\nfunction makeStrokeLine(\n positions: number[],\n color: ColorRepresentation,\n width: number,\n opacity: number,\n): Line2 {\n const geometry = new LineGeometry();\n geometry.setPositions(positions);\n const material = new LineMaterial({\n color,\n depthTest: true,\n depthWrite: false,\n linewidth: Math.max(0.5, width),\n opacity,\n transparent: true,\n worldUnits: false,\n alphaToCoverage: true,\n });\n const line = new Line2(geometry, material);\n line.computeLineDistances();\n return line;\n}\n\nfunction disposeStrokeLine(line: Line2 | null): void {\n if (!line) return;\n line.geometry.dispose();\n (line.material as LineMaterial).dispose();\n}\n\nfunction translateVertices(\n vertices: HotspotPosition[],\n from: HotspotPosition,\n to: HotspotPosition,\n): HotspotPosition[] {\n const yawOffset = normalizePanoYaw(to.yaw - from.yaw);\n const pitchOffset = to.pitch - from.pitch;\n return vertices.map((vertex) => ({\n yaw: normalizePanoYaw(vertex.yaw + yawOffset),\n pitch: clampPanoPitch(vertex.pitch + pitchOffset),\n }));\n}\n\nexport function PolygonHotspot({\n id,\n vertices,\n fill = \"#df6b42\",\n fillOpacity = 0.34,\n stroke = \"#f5fbfc\",\n strokeWidth = 2,\n strokeOpacity = 1,\n interactive = true,\n renderOrder = 10,\n draggable = false,\n onVerticesChange,\n onDragStart,\n onDragEnd,\n onInvalid,\n ...anchorProps\n}: PolygonHotspotProps) {\n const gl = useThree((state) => state.gl);\n const size = useThree((state) => state.size);\n const issues = useMemo(() => validatePolygonVertices(vertices), [vertices]);\n const valid = issues.length === 0;\n const center = useMemo(() => valid ? polygonCenter(vertices) : null, [valid, vertices]);\n const fillGeometry = useMemo(\n () => valid && center ? makeFillGeometry(vertices, center) : null,\n [center, valid, vertices],\n );\n const strokePositions = useMemo(\n () => valid && center ? makeStrokePositions(vertices, center) : null,\n [center, valid, vertices],\n );\n const resolvedStrokeOpacity = Math.max(0, Math.min(strokeOpacity, 1));\n const devicePixelRatio = gl.getPixelRatio();\n const strokeLine = useMemo(\n () => strokePositions\n ? makeStrokeLine(strokePositions, stroke, strokeWidth * devicePixelRatio, resolvedStrokeOpacity)\n : null,\n [devicePixelRatio, resolvedStrokeOpacity, stroke, strokePositions, strokeWidth],\n );\n const focusStrokeLine = useMemo(\n () => strokePositions\n ? makeStrokeLine(strokePositions, \"#75cbd3\", (strokeWidth + 2) * devicePixelRatio, 1)\n : null,\n [devicePixelRatio, strokePositions, strokeWidth],\n );\n const startVerticesRef = useRef<HotspotPosition[] | null>(null);\n const issuesKey = issues.map((issue) => issue.code).join(\",\");\n\n useEffect(() => {\n if (!valid) onInvalid?.(issues);\n }, [issues, issuesKey, onInvalid, valid]);\n useEffect(() => () => fillGeometry?.dispose(), [fillGeometry]);\n useEffect(() => () => disposeStrokeLine(strokeLine), [strokeLine]);\n useEffect(() => () => disposeStrokeLine(focusStrokeLine), [focusStrokeLine]);\n useEffect(() => {\n const width = gl.domElement.width;\n const height = gl.domElement.height;\n for (const line of [strokeLine, focusStrokeLine]) {\n if (line) (line.material as LineMaterial).resolution.set(width, height);\n }\n }, [focusStrokeLine, gl, size.height, size.width, strokeLine]);\n\n if (!valid || !center || !fillGeometry || !strokeLine || !focusStrokeLine) return null;\n\n const emitVerticesChange = (event: HotspotDragEvent, callback?: (event: PolygonVerticesChangeEvent) => void) => {\n const startVertices = startVerticesRef.current ?? cloneVertices(vertices);\n const nextVertices = translateVertices(startVertices, event.startPosition, event.position);\n callback?.({\n id,\n vertices: nextVertices,\n startVertices,\n position: event.position,\n startPosition: event.startPosition,\n });\n };\n\n return (\n <HotspotAnchor\n {...anchorProps}\n id={id}\n position={center}\n width={1}\n height={1}\n internalPlacement=\"floating\"\n distance={POLYGON_RADIUS}\n internalOrientation=\"surface\"\n renderOrder={renderOrder}\n draggable={draggable}\n interactive={interactive}\n useAngularScale={false}\n focusContent={\n <primitive object={focusStrokeLine} renderOrder={renderOrder + 2} />\n }\n onDragStart={(event) => {\n startVerticesRef.current = cloneVertices(vertices);\n emitVerticesChange(event, onDragStart);\n }}\n onPositionChange={(event) => emitVerticesChange(event, onVerticesChange)}\n onDragEnd={(event) => {\n emitVerticesChange(event, onDragEnd);\n startVerticesRef.current = null;\n }}\n >\n <mesh geometry={fillGeometry} renderOrder={renderOrder}>\n <meshBasicMaterial\n color={fill}\n depthWrite={false}\n opacity={Math.max(0, Math.min(fillOpacity, 1))}\n side={DoubleSide}\n transparent\n />\n </mesh>\n <primitive object={strokeLine} renderOrder={renderOrder + 1} />\n </HotspotAnchor>\n );\n}\n","import { useThree } from \"@react-three/fiber\";\nimport { useEffect, useMemo, useRef } from \"react\";\nimport {\n ColorRepresentation,\n MathUtils,\n Matrix4,\n Quaternion,\n Vector3,\n} from \"three\";\nimport { Line2 } from \"three/addons/lines/Line2.js\";\nimport { LineGeometry } from \"three/addons/lines/LineGeometry.js\";\nimport { LineMaterial } from \"three/addons/lines/LineMaterial.js\";\nimport { HotspotAnchor } from \"./hotspot-anchor\";\nimport {\n clampPanoPitch,\n normalizePanoPosition,\n normalizePanoYaw,\n panoPositionToVector3,\n vector3ToPanoPosition,\n} from \"./coordinates\";\nimport type {\n HotspotCommonProps,\n HotspotDragEvent,\n HotspotPosition,\n} from \"./types\";\n\nconst POLYLINE_RADIUS = 990;\nconst MAX_SEGMENT_DEGREES = 7;\n\nexport type PolylineValidationIssue = {\n code: \"too_few_vertices\";\n message: string;\n};\n\nexport type PolylineVerticesChangeEvent = {\n id: string;\n vertices: HotspotPosition[];\n startVertices: HotspotPosition[];\n position: HotspotPosition;\n startPosition: HotspotPosition;\n};\n\nexport type PolylineHotspotProps = Omit<\n HotspotCommonProps,\n | \"position\"\n | \"width\"\n | \"height\"\n | \"scale\"\n | \"mode\"\n | \"distance\"\n | \"scaleMode\"\n | \"rotation\"\n | \"onDragStart\"\n | \"onPositionChange\"\n | \"onDragEnd\"\n> & {\n vertices: HotspotPosition[];\n stroke?: ColorRepresentation;\n /** Screen-space line width in CSS pixels. Defaults to 2. */\n strokeWidth?: number;\n strokeOpacity?: number;\n onVerticesChange?: (event: PolylineVerticesChangeEvent) => void;\n onDragStart?: (event: PolylineVerticesChangeEvent) => void;\n onDragEnd?: (event: PolylineVerticesChangeEvent) => void;\n onInvalid?: (issues: PolylineValidationIssue[]) => void;\n};\n\ntype UnwrappedVertex = HotspotPosition & { unwrappedYaw: number };\n\nfunction cloneVertices(vertices: HotspotPosition[]): HotspotPosition[] {\n return vertices.map((vertex) => normalizePanoPosition(vertex));\n}\n\nfunction unwrapVertices(vertices: HotspotPosition[]): UnwrappedVertex[] {\n const unwrapped: UnwrappedVertex[] = [];\n for (const vertex of vertices) {\n const normalized = normalizePanoPosition(vertex);\n const previous = unwrapped[unwrapped.length - 1];\n if (!previous) {\n unwrapped.push({ ...normalized, unwrappedYaw: normalized.yaw });\n continue;\n }\n let yaw = normalized.yaw;\n while (yaw - previous.unwrappedYaw > 180) yaw -= 360;\n while (yaw - previous.unwrappedYaw <= -180) yaw += 360;\n unwrapped.push({ ...normalized, unwrappedYaw: yaw });\n }\n return unwrapped;\n}\n\nfunction polylineCenter(vertices: HotspotPosition[]): HotspotPosition {\n const sum = vertices.reduce(\n (total, vertex) => total.add(panoPositionToVector3(vertex).normalize()),\n new Vector3(),\n );\n return sum.lengthSq() > 1e-8\n ? vector3ToPanoPosition(sum)\n : normalizePanoPosition(vertices[0]!);\n}\n\nfunction surfaceQuaternion(position: HotspotPosition): Quaternion {\n const outward = panoPositionToVector3(position).normalize();\n const inward = outward.clone().negate();\n const pitch = MathUtils.degToRad(position.pitch);\n const yaw = MathUtils.degToRad(position.yaw);\n const localUp = new Vector3(\n -Math.sin(pitch) * Math.sin(yaw),\n Math.cos(pitch),\n Math.sin(pitch) * Math.cos(yaw),\n ).normalize();\n return new Quaternion().setFromRotationMatrix(\n new Matrix4().makeBasis(localUp.clone().cross(inward).normalize(), localUp, inward),\n );\n}\n\nfunction makeWorldToLocal(center: HotspotPosition): Matrix4 {\n return new Matrix4()\n .compose(\n panoPositionToVector3(center, POLYLINE_RADIUS),\n surfaceQuaternion(center),\n new Vector3(1, 1, 1),\n )\n .invert();\n}\n\nfunction subdivisionSteps(vertices: HotspotPosition[]): number {\n let maxAngle = 0;\n for (let index = 0; index < vertices.length - 1; index += 1) {\n maxAngle = Math.max(\n maxAngle,\n panoPositionToVector3(vertices[index]!).angleTo(\n panoPositionToVector3(vertices[index + 1]!),\n ),\n );\n }\n return Math.min(\n 8,\n Math.max(1, Math.ceil((MathUtils.radToDeg(maxAngle)) / MAX_SEGMENT_DEGREES)),\n );\n}\n\nfunction makeLinePositions(vertices: HotspotPosition[], center: HotspotPosition): number[] {\n const positions: number[] = [];\n const worldToLocal = makeWorldToLocal(center);\n const unwrapped = unwrapVertices(vertices);\n const steps = subdivisionSteps(vertices);\n\n for (let edge = 0; edge < unwrapped.length - 1; edge += 1) {\n const start = unwrapped[edge]!;\n const end = unwrapped[edge + 1]!;\n for (let step = 0; step < steps; step += 1) {\n const progress = step / steps;\n const point = panoPositionToVector3(\n {\n yaw: start.unwrappedYaw + (end.unwrappedYaw - start.unwrappedYaw) * progress,\n pitch: start.pitch + (end.pitch - start.pitch) * progress,\n },\n POLYLINE_RADIUS,\n ).applyMatrix4(worldToLocal);\n positions.push(point.x, point.y, point.z);\n }\n }\n\n const last = unwrapped[unwrapped.length - 1]!;\n const lastPoint = panoPositionToVector3(last, POLYLINE_RADIUS).applyMatrix4(worldToLocal);\n positions.push(lastPoint.x, lastPoint.y, lastPoint.z);\n return positions;\n}\n\nfunction makeLine(\n positions: number[],\n color: ColorRepresentation,\n width: number,\n opacity: number,\n): Line2 {\n const geometry = new LineGeometry();\n geometry.setPositions(positions);\n const material = new LineMaterial({\n color,\n depthTest: true,\n depthWrite: false,\n linewidth: Math.max(0.5, width),\n opacity,\n transparent: true,\n worldUnits: false,\n alphaToCoverage: true,\n });\n const line = new Line2(geometry, material);\n line.computeLineDistances();\n return line;\n}\n\nfunction disposeLine(line: Line2 | null): void {\n if (!line) return;\n line.geometry.dispose();\n (line.material as LineMaterial).dispose();\n}\n\nfunction translateVertices(\n vertices: HotspotPosition[],\n from: HotspotPosition,\n to: HotspotPosition,\n): HotspotPosition[] {\n const yawOffset = normalizePanoYaw(to.yaw - from.yaw);\n const pitchOffset = to.pitch - from.pitch;\n return vertices.map((vertex) => ({\n yaw: normalizePanoYaw(vertex.yaw + yawOffset),\n pitch: clampPanoPitch(vertex.pitch + pitchOffset),\n }));\n}\n\nexport function validatePolylineVertices(\n vertices: HotspotPosition[],\n): PolylineValidationIssue[] {\n return vertices.length < 2\n ? [{ code: \"too_few_vertices\", message: \"A polyline needs at least two vertices.\" }]\n : [];\n}\n\nexport function PolylineHotspot({\n id,\n vertices,\n stroke = \"#f5fbfc\",\n strokeWidth = 2,\n strokeOpacity = 1,\n renderOrder = 10,\n draggable = false,\n onVerticesChange,\n onDragStart,\n onDragEnd,\n onInvalid,\n ...anchorProps\n}: PolylineHotspotProps) {\n const gl = useThree((state) => state.gl);\n const size = useThree((state) => state.size);\n const issues = useMemo(() => validatePolylineVertices(vertices), [vertices]);\n const valid = issues.length === 0;\n const center = useMemo(() => valid ? polylineCenter(vertices) : null, [valid, vertices]);\n const linePositions = useMemo(\n () => valid && center ? makeLinePositions(vertices, center) : null,\n [center, valid, vertices],\n );\n const devicePixelRatio = gl.getPixelRatio();\n const opacity = Math.max(0, Math.min(strokeOpacity, 1));\n const line = useMemo(\n () => linePositions ? makeLine(linePositions, stroke, strokeWidth * devicePixelRatio, opacity) : null,\n [devicePixelRatio, linePositions, opacity, stroke, strokeWidth],\n );\n const focusLine = useMemo(\n () => linePositions ? makeLine(linePositions, \"#75cbd3\", (strokeWidth + 2) * devicePixelRatio, 1) : null,\n [devicePixelRatio, linePositions, strokeWidth],\n );\n const startVerticesRef = useRef<HotspotPosition[] | null>(null);\n\n useEffect(() => {\n if (!valid) onInvalid?.(issues);\n }, [issues, onInvalid, valid]);\n useEffect(() => () => disposeLine(line), [line]);\n useEffect(() => () => disposeLine(focusLine), [focusLine]);\n useEffect(() => {\n const width = gl.domElement.width;\n const height = gl.domElement.height;\n for (const nextLine of [line, focusLine]) {\n if (nextLine) (nextLine.material as LineMaterial).resolution.set(width, height);\n }\n }, [focusLine, gl, line, size.height, size.width]);\n\n if (!valid || !center || !line || !focusLine) return null;\n\n const emitVerticesChange = (\n event: HotspotDragEvent,\n callback?: (event: PolylineVerticesChangeEvent) => void,\n ) => {\n const startVertices = startVerticesRef.current ?? cloneVertices(vertices);\n callback?.({\n id,\n vertices: translateVertices(startVertices, event.startPosition, event.position),\n startVertices,\n position: event.position,\n startPosition: event.startPosition,\n });\n };\n\n return (\n <HotspotAnchor\n {...anchorProps}\n id={id}\n position={center}\n width={1}\n height={1}\n internalPlacement=\"floating\"\n distance={POLYLINE_RADIUS}\n internalOrientation=\"surface\"\n renderOrder={renderOrder}\n draggable={draggable}\n useAngularScale={false}\n focusContent={<primitive object={focusLine} renderOrder={renderOrder + 2} />}\n onDragStart={(event) => {\n startVerticesRef.current = cloneVertices(vertices);\n emitVerticesChange(event, onDragStart);\n }}\n onPositionChange={(event) => emitVerticesChange(event, onVerticesChange)}\n onDragEnd={(event) => {\n emitVerticesChange(event, onDragEnd);\n startVerticesRef.current = null;\n }}\n >\n <primitive object={line} renderOrder={renderOrder + 1} />\n </HotspotAnchor>\n );\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport {\n CanvasTexture,\n ClampToEdgeWrapping,\n DoubleSide,\n LinearFilter,\n LinearMipmapLinearFilter,\n SRGBColorSpace,\n Texture,\n} from \"three\";\nimport { HotspotAnchor } from \"./hotspot-anchor\";\nimport { ImageHotspot } from \"./image-hotspot\";\nimport type { HotspotCommonProps } from \"./types\";\n\nconst GRAPHIC_TEXTURE_SIZE = 512;\n\ntype GraphicPaint = {\n fill?: string;\n stroke?: string;\n strokeWidth?: number;\n};\n\nexport type CircleGraphic = GraphicPaint & {\n kind: \"circle\";\n};\n\nexport type TriangleGraphic = GraphicPaint & {\n kind: \"triangle\";\n};\n\nexport type DiamondGraphic = GraphicPaint & {\n kind: \"diamond\";\n};\n\nexport type StarGraphic = GraphicPaint & {\n kind: \"star\";\n};\n\nexport type ArrowGraphic = GraphicPaint & {\n kind: \"arrow\";\n};\n\nexport type RectangleGraphic = GraphicPaint & {\n kind: \"rectangle\";\n /** Relative radius from 0 (square corners) to 0.5 (maximum rounded corners). */\n cornerRadius?: number;\n};\n\nexport type RingGraphic = GraphicPaint & {\n kind: \"ring\";\n innerRadius?: number;\n};\n\nexport type SvgGraphic = {\n kind: \"svg\";\n src: string;\n};\n\nexport type SvgPathGraphic = GraphicPaint & {\n kind: \"path\";\n path: string;\n viewBox: [x: number, y: number, width: number, height: number];\n};\n\nexport type GraphicDefinition =\n | CircleGraphic\n | TriangleGraphic\n | DiamondGraphic\n | StarGraphic\n | ArrowGraphic\n | RectangleGraphic\n | RingGraphic\n | SvgGraphic\n | SvgPathGraphic;\n\nexport type GraphicHotspotProps = HotspotCommonProps & {\n graphic: GraphicDefinition;\n onLoad?: (texture: Texture) => void;\n onError?: (error: unknown) => void;\n};\n\nfunction clampOpacity(opacity: number | undefined): number {\n if (!Number.isFinite(opacity)) {\n return 1;\n }\n return Math.max(0, Math.min(opacity!, 1));\n}\n\nfunction resolveStrokeWidth(value: number | undefined): number {\n return Number.isFinite(value) ? Math.max(value!, 0) : 8;\n}\n\nfunction resolveCornerRadius(value: number | undefined): number {\n return Number.isFinite(value) ? Math.max(0, Math.min(value!, 0.5)) : 0;\n}\n\nfunction roundedRectanglePath(\n context: CanvasRenderingContext2D,\n x: number,\n y: number,\n width: number,\n height: number,\n radiusRatio: number,\n aspectWidth: number,\n aspectHeight: number,\n) {\n const safeAspectWidth = Number.isFinite(aspectWidth) && aspectWidth > 0 ? aspectWidth : 1;\n const safeAspectHeight = Number.isFinite(aspectHeight) && aspectHeight > 0 ? aspectHeight : 1;\n const shortSide = Math.min(safeAspectWidth, safeAspectHeight);\n const safeRadiusRatio = resolveCornerRadius(radiusRatio);\n const radiusX = Math.min(width / 2, (width * safeRadiusRatio * shortSide) / safeAspectWidth);\n const radiusY = Math.min(height / 2, (height * safeRadiusRatio * shortSide) / safeAspectHeight);\n\n context.beginPath();\n context.moveTo(x + radiusX, y);\n context.lineTo(x + width - radiusX, y);\n context.ellipse(x + width - radiusX, y + radiusY, radiusX, radiusY, 0, -Math.PI / 2, 0);\n context.lineTo(x + width, y + height - radiusY);\n context.ellipse(x + width - radiusX, y + height - radiusY, radiusX, radiusY, 0, 0, Math.PI / 2);\n context.lineTo(x + radiusX, y + height);\n context.ellipse(x + radiusX, y + height - radiusY, radiusX, radiusY, 0, Math.PI / 2, Math.PI);\n context.lineTo(x, y + radiusY);\n context.ellipse(x + radiusX, y + radiusY, radiusX, radiusY, 0, Math.PI, Math.PI * 1.5);\n context.closePath();\n}\n\nfunction polygonPath(\n context: CanvasRenderingContext2D,\n points: Array<[number, number]>,\n) {\n context.beginPath();\n context.moveTo(points[0]![0], points[0]![1]);\n for (const [x, y] of points.slice(1)) {\n context.lineTo(x, y);\n }\n context.closePath();\n}\n\nfunction paintPath(\n context: CanvasRenderingContext2D,\n graphic: GraphicPaint,\n path?: Path2D,\n) {\n if (graphic.fill) {\n context.fillStyle = graphic.fill;\n path ? context.fill(path) : context.fill();\n }\n if (graphic.stroke) {\n context.strokeStyle = graphic.stroke;\n context.lineWidth = resolveStrokeWidth(graphic.strokeWidth);\n path ? context.stroke(path) : context.stroke();\n }\n}\n\nfunction drawGraphic(\n context: CanvasRenderingContext2D,\n graphic: Exclude<GraphicDefinition, SvgGraphic>,\n aspectWidth: number,\n aspectHeight: number,\n) {\n const padding = Math.max(resolveStrokeWidth(graphic.strokeWidth) / 2 + 2, 4);\n const drawableSize = GRAPHIC_TEXTURE_SIZE - padding * 2;\n\n context.clearRect(0, 0, GRAPHIC_TEXTURE_SIZE, GRAPHIC_TEXTURE_SIZE);\n context.lineJoin = \"round\";\n context.lineCap = \"round\";\n\n if (graphic.kind === \"circle\") {\n context.beginPath();\n context.arc(\n GRAPHIC_TEXTURE_SIZE / 2,\n GRAPHIC_TEXTURE_SIZE / 2,\n drawableSize / 2,\n 0,\n Math.PI * 2,\n );\n paintPath(context, graphic);\n return;\n }\n\n if (graphic.kind === \"triangle\") {\n const center = GRAPHIC_TEXTURE_SIZE / 2;\n polygonPath(context, [\n [center, padding],\n [padding + drawableSize, padding + drawableSize],\n [padding, padding + drawableSize],\n ]);\n paintPath(context, graphic);\n return;\n }\n\n if (graphic.kind === \"diamond\") {\n const center = GRAPHIC_TEXTURE_SIZE / 2;\n polygonPath(context, [\n [center, padding],\n [padding + drawableSize, center],\n [center, padding + drawableSize],\n [padding, center],\n ]);\n paintPath(context, graphic);\n return;\n }\n\n if (graphic.kind === \"star\") {\n const center = GRAPHIC_TEXTURE_SIZE / 2;\n const outerRadius = drawableSize / 2;\n const innerRadius = outerRadius * 0.45;\n const points: Array<[number, number]> = [];\n for (let index = 0; index < 10; index += 1) {\n const angle = -Math.PI / 2 + (index * Math.PI) / 5;\n const radius = index % 2 === 0 ? outerRadius : innerRadius;\n points.push([\n center + Math.cos(angle) * radius,\n center + Math.sin(angle) * radius,\n ]);\n }\n polygonPath(context, points);\n paintPath(context, graphic);\n return;\n }\n\n if (graphic.kind === \"arrow\") {\n const center = GRAPHIC_TEXTURE_SIZE / 2;\n const top = padding;\n const bottom = padding + drawableSize;\n const headBottom = top + drawableSize * 0.43;\n const headHalfWidth = drawableSize * 0.38;\n const stemHalfWidth = drawableSize * 0.14;\n polygonPath(context, [\n [center, top],\n [center + headHalfWidth, headBottom],\n [center + stemHalfWidth, headBottom],\n [center + stemHalfWidth, bottom],\n [center - stemHalfWidth, bottom],\n [center - stemHalfWidth, headBottom],\n [center - headHalfWidth, headBottom],\n ]);\n paintPath(context, graphic);\n return;\n }\n\n if (graphic.kind === \"rectangle\") {\n roundedRectanglePath(\n context,\n padding,\n padding,\n drawableSize,\n drawableSize,\n graphic.cornerRadius ?? 0,\n aspectWidth,\n aspectHeight,\n );\n paintPath(context, graphic);\n return;\n }\n\n if (graphic.kind === \"ring\") {\n const center = GRAPHIC_TEXTURE_SIZE / 2;\n const outerRadius = drawableSize / 2;\n const innerRadius = Math.max(\n 0,\n Math.min(outerRadius - 1, (graphic.innerRadius ?? 0.58) * outerRadius),\n );\n context.beginPath();\n context.arc(center, center, outerRadius, 0, Math.PI * 2);\n context.moveTo(center + innerRadius, center);\n context.arc(center, center, innerRadius, 0, Math.PI * 2, true);\n if (graphic.fill ?? graphic.stroke) {\n context.fillStyle = graphic.fill ?? graphic.stroke ?? \"#ffffff\";\n context.fill(\"evenodd\");\n }\n if (graphic.stroke) {\n context.strokeStyle = graphic.stroke;\n context.lineWidth = resolveStrokeWidth(graphic.strokeWidth);\n context.stroke();\n }\n return;\n }\n\n const [x, y, width, height] = graphic.viewBox;\n if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) {\n throw new Error(\"SVG path viewBox must have a positive width and height.\");\n }\n const path = new Path2D(graphic.path);\n context.save();\n context.translate(padding, padding);\n context.scale(drawableSize / width, drawableSize / height);\n context.translate(-x, -y);\n paintPath(context, graphic, path);\n context.restore();\n}\n\nfunction createGraphicTexture(\n graphic: Exclude<GraphicDefinition, SvgGraphic>,\n aspectWidth: number,\n aspectHeight: number,\n): CanvasTexture {\n const canvas = document.createElement(\"canvas\");\n canvas.width = GRAPHIC_TEXTURE_SIZE;\n canvas.height = GRAPHIC_TEXTURE_SIZE;\n const context = canvas.getContext(\"2d\");\n if (!context) {\n throw new Error(\"Canvas 2D is unavailable for this graphic hotspot.\");\n }\n drawGraphic(context, graphic, aspectWidth, aspectHeight);\n\n const texture = new CanvasTexture(canvas);\n texture.colorSpace = SRGBColorSpace;\n texture.wrapS = ClampToEdgeWrapping;\n texture.wrapT = ClampToEdgeWrapping;\n texture.magFilter = LinearFilter;\n texture.minFilter = LinearMipmapLinearFilter;\n texture.generateMipmaps = true;\n texture.needsUpdate = true;\n return texture;\n}\n\nfunction useGraphicTexture(\n graphic: Exclude<GraphicDefinition, SvgGraphic>,\n aspectWidth: number,\n aspectHeight: number,\n onLoad: GraphicHotspotProps[\"onLoad\"],\n onError: GraphicHotspotProps[\"onError\"],\n) {\n const [texture, setTexture] = useState<CanvasTexture | null>(null);\n const onLoadRef = useRef(onLoad);\n const onErrorRef = useRef(onError);\n onLoadRef.current = onLoad;\n onErrorRef.current = onError;\n\n useEffect(() => {\n let nextTexture: CanvasTexture | null = null;\n try {\n nextTexture = createGraphicTexture(graphic, aspectWidth, aspectHeight);\n setTexture(nextTexture);\n onLoadRef.current?.(nextTexture);\n } catch (error) {\n setTexture(null);\n onErrorRef.current?.(error);\n }\n\n return () => {\n nextTexture?.dispose();\n };\n }, [aspectHeight, aspectWidth, graphic]);\n\n return texture;\n}\n\nfunction CanvasGraphicHotspot({\n graphic,\n width = 10,\n height = 10,\n opacity,\n onLoad,\n onError,\n ...anchorProps\n}: GraphicHotspotProps & { graphic: Exclude<GraphicDefinition, SvgGraphic> }) {\n const texture = useGraphicTexture(graphic, width, height, onLoad, onError);\n\n return (\n <HotspotAnchor {...anchorProps} height={height} width={width}>\n <mesh>\n <planeGeometry args={[1, 1]} />\n <meshBasicMaterial\n map={texture}\n opacity={texture ? clampOpacity(opacity) : 0}\n side={DoubleSide}\n toneMapped={false}\n transparent\n />\n </mesh>\n </HotspotAnchor>\n );\n}\n\nexport function GraphicHotspot(props: GraphicHotspotProps) {\n const { graphic, ...restProps } = props;\n if (graphic.kind === \"svg\") {\n const imageProps = restProps;\n return <ImageHotspot {...imageProps} src={graphic.src} />;\n }\n\n return <CanvasGraphicHotspot {...restProps} graphic={graphic} />;\n}\n","import { useFrame, useThree } from \"@react-three/fiber\";\nimport { useEffect, useRef, useState } from \"react\";\nimport {\n ClampToEdgeWrapping,\n DoubleSide,\n LinearFilter,\n LinearMipmapLinearFilter,\n SRGBColorSpace,\n Texture,\n TextureLoader,\n} from \"three\";\nimport { HotspotAnchor } from \"./hotspot-anchor\";\nimport type { HotspotCommonProps } from \"./types\";\n\nconst DEFAULT_SEQUENCE_FPS = 12;\n\nexport type SequenceFrameDirection = \"horizontal\" | \"vertical\";\n\nexport type SequenceLoadProgress = {\n id: string;\n total: number;\n loaded: number;\n failed: number;\n};\n\nexport type SequenceFrameEvent = {\n id: string;\n index: number;\n src: string;\n};\n\nexport type SequencePlaybackState = \"playing\" | \"paused\" | \"ended\";\n\nexport type SequenceHotspotErrorEvent = {\n id: string;\n src: string;\n error: unknown;\n};\n\nexport type SequenceHotspotProps = HotspotCommonProps & {\n /** A sprite sheet containing each frame in equally sized cells. */\n src: string;\n /** Number of cells in the sprite sheet, from left-to-right or top-to-bottom. */\n frameCount: number;\n frameDirection?: SequenceFrameDirection;\n playing: boolean;\n fps?: number;\n loop?: boolean;\n onFrameChange?: (event: SequenceFrameEvent) => void;\n onLoadProgress?: (progress: SequenceLoadProgress) => void;\n onPlaybackStateChange?: (state: SequencePlaybackState) => void;\n onEnded?: () => void;\n onError?: (event: SequenceHotspotErrorEvent) => void;\n};\n\nfunction clampOpacity(opacity: number | undefined): number {\n if (!Number.isFinite(opacity)) {\n return 1;\n }\n return Math.max(0, Math.min(opacity!, 1));\n}\n\nfunction resolveFps(value: number | undefined): number {\n return Number.isFinite(value) && value! > 0 ? value! : DEFAULT_SEQUENCE_FPS;\n}\n\nfunction resolveFrameCount(value: number): number {\n return Number.isFinite(value) ? Math.max(1, Math.floor(value)) : 1;\n}\n\nfunction useSpriteTexture({\n id,\n src,\n onError,\n onLoadProgress,\n}: Pick<SequenceHotspotProps, \"id\" | \"src\" | \"onError\" | \"onLoadProgress\">) {\n const gl = useThree((state) => state.gl);\n const [texture, setTexture] = useState<Texture | null>(null);\n const onErrorRef = useRef(onError);\n const onLoadProgressRef = useRef(onLoadProgress);\n onErrorRef.current = onError;\n onLoadProgressRef.current = onLoadProgress;\n\n useEffect(() => {\n let active = true;\n setTexture(null);\n if (!src) {\n onLoadProgressRef.current?.({ id, total: 1, loaded: 0, failed: 1 });\n return () => {\n active = false;\n };\n }\n\n const loader = new TextureLoader();\n loader.load(\n src,\n (loadedTexture) => {\n if (!active) {\n loadedTexture.dispose();\n return;\n }\n loadedTexture.colorSpace = SRGBColorSpace;\n loadedTexture.wrapS = ClampToEdgeWrapping;\n loadedTexture.wrapT = ClampToEdgeWrapping;\n loadedTexture.magFilter = LinearFilter;\n loadedTexture.minFilter = LinearMipmapLinearFilter;\n loadedTexture.generateMipmaps = true;\n loadedTexture.anisotropy = gl.capabilities.getMaxAnisotropy();\n loadedTexture.needsUpdate = true;\n onLoadProgressRef.current?.({ id, total: 1, loaded: 1, failed: 0 });\n setTexture(loadedTexture);\n },\n undefined,\n (error) => {\n if (!active) {\n return;\n }\n onLoadProgressRef.current?.({ id, total: 1, loaded: 0, failed: 1 });\n onErrorRef.current?.({ id, src, error });\n },\n );\n\n return () => {\n active = false;\n };\n }, [gl, id, src]);\n\n useEffect(\n () => () => {\n texture?.dispose();\n },\n [texture],\n );\n\n return texture;\n}\n\nexport function SequenceHotspot({\n id,\n src,\n frameCount: requestedFrameCount,\n frameDirection = \"vertical\",\n playing,\n fps,\n loop = true,\n width = 12,\n height = 8,\n opacity,\n onFrameChange,\n onLoadProgress,\n onPlaybackStateChange,\n onEnded,\n onError,\n ...anchorProps\n}: SequenceHotspotProps) {\n const texture = useSpriteTexture({ id, src, onError, onLoadProgress });\n const frameCount = resolveFrameCount(requestedFrameCount);\n const safeFps = resolveFps(fps);\n const [frameIndex, setFrameIndex] = useState(0);\n const elapsedRef = useRef(0);\n const frameIndexRef = useRef(0);\n const endedRef = useRef(false);\n const lastPlaybackStateRef = useRef<SequencePlaybackState | null>(null);\n const onFrameChangeRef = useRef(onFrameChange);\n const onPlaybackStateChangeRef = useRef(onPlaybackStateChange);\n const onEndedRef = useRef(onEnded);\n onFrameChangeRef.current = onFrameChange;\n onPlaybackStateChangeRef.current = onPlaybackStateChange;\n onEndedRef.current = onEnded;\n\n useEffect(() => {\n elapsedRef.current = 0;\n frameIndexRef.current = 0;\n endedRef.current = false;\n setFrameIndex(0);\n }, [frameCount, frameDirection, src]);\n\n useEffect(() => {\n if (!texture) {\n return;\n }\n texture.repeat.set(\n frameDirection === \"horizontal\" ? 1 / frameCount : 1,\n frameDirection === \"vertical\" ? 1 / frameCount : 1,\n );\n texture.offset.set(\n frameDirection === \"horizontal\" ? frameIndex / frameCount : 0,\n frameDirection === \"vertical\" ? 1 - (frameIndex + 1) / frameCount : 0,\n );\n texture.needsUpdate = true;\n }, [frameCount, frameDirection, frameIndex, texture]);\n\n useEffect(() => {\n if (!texture) {\n return;\n }\n onFrameChangeRef.current?.({ id, index: 0, src });\n }, [id, src, texture]);\n\n useEffect(() => {\n if (!texture) {\n return;\n }\n if (playing && endedRef.current) {\n elapsedRef.current = 0;\n frameIndexRef.current = 0;\n endedRef.current = false;\n setFrameIndex(0);\n }\n if (!playing && endedRef.current) {\n return;\n }\n const nextState: SequencePlaybackState = playing ? \"playing\" : \"paused\";\n if (lastPlaybackStateRef.current !== nextState) {\n lastPlaybackStateRef.current = nextState;\n onPlaybackStateChangeRef.current?.(nextState);\n }\n }, [playing, texture]);\n\n useFrame((_, deltaSeconds) => {\n if (!texture || !playing || endedRef.current) {\n return;\n }\n elapsedRef.current += deltaSeconds;\n const steps = Math.floor(elapsedRef.current * safeFps);\n if (steps === 0) {\n return;\n }\n elapsedRef.current -= steps / safeFps;\n\n let nextIndex = frameIndexRef.current + steps;\n if (nextIndex >= frameCount) {\n if (loop) {\n nextIndex %= frameCount;\n } else {\n nextIndex = frameCount - 1;\n endedRef.current = true;\n if (lastPlaybackStateRef.current !== \"ended\") {\n lastPlaybackStateRef.current = \"ended\";\n onPlaybackStateChangeRef.current?.(\"ended\");\n onEndedRef.current?.();\n }\n }\n }\n\n if (nextIndex !== frameIndexRef.current) {\n frameIndexRef.current = nextIndex;\n setFrameIndex(nextIndex);\n onFrameChangeRef.current?.({ id, index: nextIndex, src });\n }\n });\n\n return (\n <HotspotAnchor {...anchorProps} id={id} height={height} width={width}>\n <mesh>\n <planeGeometry args={[1, 1]} />\n <meshBasicMaterial\n map={texture}\n opacity={texture ? clampOpacity(opacity) : 0}\n side={DoubleSide}\n toneMapped={false}\n transparent\n />\n </mesh>\n </HotspotAnchor>\n );\n}\n","import { useThree } from \"@react-three/fiber\";\nimport { useEffect, useRef, useState } from \"react\";\nimport {\n ClampToEdgeWrapping,\n DoubleSide,\n LinearFilter,\n LinearMipmapLinearFilter,\n SRGBColorSpace,\n Texture,\n TextureLoader,\n VideoTexture,\n} from \"three\";\nimport { HotspotAnchor } from \"./hotspot-anchor\";\nimport type { HotspotCommonProps } from \"./types\";\n\nexport type VideoPlaybackState = \"playing\" | \"paused\" | \"ended\" | \"blocked\";\n\nexport type VideoHotspotErrorEvent = {\n id: string;\n source: \"poster\" | \"video\";\n error: unknown;\n};\n\nexport type VideoHotspotProps = HotspotCommonProps & {\n src: string;\n playing: boolean;\n poster?: string;\n loop?: boolean;\n muted?: boolean;\n volume?: number;\n playsInline?: boolean;\n preload?: \"none\" | \"metadata\" | \"auto\";\n crossOrigin?: \"\" | \"anonymous\" | \"use-credentials\";\n onPlaybackStateChange?: (state: VideoPlaybackState) => void;\n onPlaybackError?: (error: unknown) => void;\n onEnded?: () => void;\n onError?: (event: VideoHotspotErrorEvent) => void;\n};\n\ntype VideoResource = {\n video: HTMLVideoElement;\n texture: VideoTexture;\n ready: boolean;\n};\n\nfunction clampOpacity(opacity: number | undefined): number {\n if (!Number.isFinite(opacity)) {\n return 1;\n }\n return Math.max(0, Math.min(opacity!, 1));\n}\n\nfunction clampVolume(volume: number | undefined): number {\n if (!Number.isFinite(volume)) {\n return 1;\n }\n return Math.max(0, Math.min(volume!, 1));\n}\n\nfunction usePosterTexture(\n id: string,\n poster: string | undefined,\n onError: VideoHotspotProps[\"onError\"],\n) {\n const gl = useThree((state) => state.gl);\n const [texture, setTexture] = useState<Texture | null>(null);\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n\n useEffect(() => {\n let active = true;\n setTexture(null);\n if (!poster) {\n return () => {\n active = false;\n };\n }\n\n const loader = new TextureLoader();\n loader.load(\n poster,\n (loadedTexture) => {\n if (!active) {\n loadedTexture.dispose();\n return;\n }\n loadedTexture.colorSpace = SRGBColorSpace;\n loadedTexture.wrapS = ClampToEdgeWrapping;\n loadedTexture.wrapT = ClampToEdgeWrapping;\n loadedTexture.magFilter = LinearFilter;\n loadedTexture.minFilter = LinearMipmapLinearFilter;\n loadedTexture.generateMipmaps = true;\n loadedTexture.anisotropy = gl.capabilities.getMaxAnisotropy();\n loadedTexture.needsUpdate = true;\n setTexture(loadedTexture);\n },\n undefined,\n (error) => {\n if (active) {\n onErrorRef.current?.({ id, source: \"poster\", error });\n }\n },\n );\n\n return () => {\n active = false;\n };\n }, [gl, id, poster]);\n\n useEffect(\n () => () => {\n texture?.dispose();\n },\n [texture],\n );\n\n return texture;\n}\n\nfunction useVideoResource({\n crossOrigin,\n id,\n onEnded,\n onError,\n onPlaybackStateChange,\n playsInline,\n poster,\n src,\n}: Pick<\n VideoHotspotProps,\n | \"crossOrigin\"\n | \"id\"\n | \"onEnded\"\n | \"onError\"\n | \"onPlaybackStateChange\"\n | \"playsInline\"\n | \"poster\"\n | \"src\"\n>) {\n const [resource, setResource] = useState<VideoResource | null>(null);\n const onEndedRef = useRef(onEnded);\n const onErrorRef = useRef(onError);\n const onPlaybackStateChangeRef = useRef(onPlaybackStateChange);\n onEndedRef.current = onEnded;\n onErrorRef.current = onError;\n onPlaybackStateChangeRef.current = onPlaybackStateChange;\n\n useEffect(() => {\n if (!src) {\n setResource(null);\n return;\n }\n\n let active = true;\n const video = document.createElement(\"video\");\n if (crossOrigin !== undefined) {\n video.crossOrigin = crossOrigin;\n }\n video.playsInline = playsInline ?? true;\n video.poster = poster ?? \"\";\n const texture = new VideoTexture(video);\n texture.colorSpace = SRGBColorSpace;\n texture.wrapS = ClampToEdgeWrapping;\n texture.wrapT = ClampToEdgeWrapping;\n texture.magFilter = LinearFilter;\n texture.minFilter = LinearFilter;\n texture.generateMipmaps = false;\n\n const notifyState = (state: VideoPlaybackState) => {\n if (active) {\n onPlaybackStateChangeRef.current?.(state);\n }\n };\n const markReady = () => {\n if (!active) {\n return;\n }\n setResource((current) =>\n current?.video === video ? { ...current, ready: true } : current,\n );\n };\n const reportError = () => {\n if (active) {\n onErrorRef.current?.({\n id,\n source: \"video\",\n error: video.error ?? new Error(`Unable to load video source: ${src}`),\n });\n }\n };\n\n const handleEnded = () => {\n notifyState(\"ended\");\n onEndedRef.current?.();\n };\n const handlePause = () => notifyState(\"paused\");\n const handlePlay = () => notifyState(\"playing\");\n video.addEventListener(\"canplay\", markReady);\n video.addEventListener(\"ended\", handleEnded);\n video.addEventListener(\"error\", reportError);\n video.addEventListener(\"pause\", handlePause);\n video.addEventListener(\"play\", handlePlay);\n setResource({ video, texture, ready: false });\n video.src = src;\n video.load();\n\n return () => {\n active = false;\n video.removeEventListener(\"canplay\", markReady);\n video.removeEventListener(\"ended\", handleEnded);\n video.removeEventListener(\"error\", reportError);\n video.removeEventListener(\"pause\", handlePause);\n video.removeEventListener(\"play\", handlePlay);\n video.pause();\n video.removeAttribute(\"src\");\n video.load();\n texture.dispose();\n };\n }, [crossOrigin, id, playsInline, poster, src]);\n\n return resource;\n}\n\nexport function VideoHotspot({\n id,\n src,\n playing,\n poster,\n loop = false,\n muted = true,\n volume = 1,\n playsInline = true,\n preload = \"metadata\",\n crossOrigin,\n width = 16,\n height = 9,\n opacity,\n onPlaybackStateChange,\n onPlaybackError,\n onEnded,\n onError,\n ...anchorProps\n}: VideoHotspotProps) {\n const resource = useVideoResource({\n crossOrigin,\n id,\n onEnded,\n onError,\n onPlaybackStateChange,\n playsInline,\n poster,\n src,\n });\n const posterTexture = usePosterTexture(id, poster, onError);\n const onPlaybackErrorRef = useRef(onPlaybackError);\n const onPlaybackStateChangeRef = useRef(onPlaybackStateChange);\n onPlaybackErrorRef.current = onPlaybackError;\n onPlaybackStateChangeRef.current = onPlaybackStateChange;\n\n useEffect(() => {\n if (!resource) {\n return;\n }\n resource.video.loop = loop;\n resource.video.muted = muted;\n resource.video.volume = clampVolume(volume);\n resource.video.playsInline = playsInline;\n resource.video.preload = preload;\n }, [loop, muted, playsInline, preload, resource, volume]);\n\n useEffect(() => {\n if (!resource) {\n return;\n }\n let active = true;\n if (!playing) {\n resource.video.pause();\n return () => {\n active = false;\n };\n }\n\n void resource.video.play().catch((error: unknown) => {\n if (!active) {\n return;\n }\n onPlaybackStateChangeRef.current?.(\"blocked\");\n onPlaybackErrorRef.current?.(error);\n });\n\n return () => {\n active = false;\n };\n }, [playing, resource]);\n\n const activeTexture = resource?.ready ? resource.texture : posterTexture;\n\n return (\n <HotspotAnchor {...anchorProps} id={id} height={height} width={width}>\n <mesh>\n <planeGeometry args={[1, 1]} />\n <meshBasicMaterial\n map={activeTexture}\n opacity={activeTexture ? clampOpacity(opacity) : 0}\n side={DoubleSide}\n toneMapped={false}\n transparent\n />\n </mesh>\n </HotspotAnchor>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,gBAAuB;AACvB,IAAAC,iBAQO;;;ACTP,IAAAC,gBAAyB;AACzB,IAAAC,gBAA8C;;;ACD9C,mBAA8B;AAyDvB,SAAS,qBAAmC;AACjD,QAAM,YAAY,oBAAI,IAA0D;AAEhF,SAAO;AAAA,IACL,UAAU,MAAM,UAAU;AACxB,UAAI,MAAM,UAAU,IAAI,IAAI;AAC5B,UAAI,CAAC,KAAK;AACR,cAAM,oBAAI,IAAI;AACd,kBAAU,IAAI,MAAM,GAAG;AAAA,MACzB;AACA,UAAI,IAAI,QAA4C;AACpD,aAAO,MAAM;AACX,aAAK,OAAO,QAA4C;AACxD,YAAI,OAAO,IAAI,SAAS,GAAG;AACzB,oBAAU,OAAO,IAAI;AAAA,QACvB;AAAA,MACF;AAAA,IACF;AAAA,IACA,KAAK,MAAM,SAAS;AAClB,YAAM,MAAM,UAAU,IAAI,IAAI;AAC9B,UAAI,CAAC,OAAO,IAAI,SAAS,GAAG;AAC1B;AAAA,MACF;AACA,iBAAW,YAAY,CAAC,GAAG,GAAG,GAAG;AAC/B,QAAC,SAA4C,OAAO;AAAA,MACtD;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,0BAAsB,4BAAmC,IAAI;;;ACvF1E,mBAAmC;AACnC,IAAAC,gBAMO;AAEP,mBAAoD;AAQpD,IAAM,YAAY;AAClB,IAAM,yBAAyB;AAC/B,IAAM,6BAA6B;AACnC,IAAM,2BAA2B;AACjC,IAAM,uBAAuB;AAC7B,IAAM,yBAAyB;AAC/B,IAAM,uBAAuB;AAC7B,IAAM,wBAAwB;AAC9B,IAAM,sBAAsB;AAuCrB,IAAM,0BAAsB,6BAEjC,IAAI;AAUN,SAAS,MAAM,OAAe,KAAa,KAAqB;AAC9D,SAAO,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,KAAK,CAAC;AAC3C;AAEA,SAAS,aAAa,KAAqB;AACzC,SAAO,uBAAU,gBAAgB,MAAM,KAAK,GAAG,IAAI;AACrD;AAEA,SAAS,iBAAiB,MAAc,IAAoB;AAC1D,SAAO,aAAa,KAAK,IAAI;AAC/B;AAEA,SAAS,cAAc,SAAiB,cAA8B;AACpE,SAAO,YAAY,IAAI,IAAI,IAAI,KAAK,IAAI,CAAC,UAAU,YAAY;AACjE;AAEA,SAAS,eAAe,OAA2B,UAA0B;AAC3E,SAAO,OAAO,SAAS,KAAK,KAAK,SAAU,IAAI,QAAS;AAC1D;AAEA,SAAS,oBAAoB,OAAmC;AAC9D,SAAO,OAAO,SAAS,KAAK,KAAK,SAAU,IAAI,QAAS;AAC1D;AAEA,SAAS,WAAW,GAAkB,GAA2B;AAC/D,SAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE;AAC/D;AAMO,IAAM,0BAAsB,0BAGjC,SAASC,qBACT,EAAE,aAAa,QAAQ,QAAQ,SAAS,SAAS,GACjD,KACA;AACA,QAAM,EAAE,OAAO,QAAI,uBAAS;AAC5B,QAAM,cAAU,sBAAsB,EAAE,GAAG,YAAY,CAAC;AACxD,QAAM,oBAAgB,sBAAsB,EAAE,GAAG,YAAY,CAAC;AAC9D,QAAM,qBAAiB,sBAAsB,EAAE,GAAG,YAAY,CAAC;AAC/D,QAAM,qBAAiB,sBAAO,CAAC;AAC/B,QAAM,uBAAmB,sBAAO,CAAC;AACjC,QAAM,sBAAkB,sBAAO,CAAC;AAChC,QAAM,eAAW,sBAAO,IAAI;AAC5B,QAAM,iBAAa,sBAAO,KAAK;AAC/B,QAAM,qBAAiB,sBAAO,KAAK;AACnC,QAAM,qBAAiB,sBAAO,KAAK;AACnC,QAAM,qBAAiB,sBAAO,KAAK;AACnC,QAAM,8BAA0B,sBAAO,CAAC;AACxC,QAAM,wBAAoB,sBAAO,KAAK;AACtC,QAAM,8BAA0B,sBAAsB,IAAI;AAC1D,QAAM,iBAAa,sBAAO,OAAO;AACjC,QAAM,kBAAc,sBAAO,QAAQ;AACnC,QAAM,yBAAqB,sBAA6B,IAAI;AAC5D,QAAM,eAAW,sBAAO,IAAI,mBAAM,GAAG,GAAG,GAAG,KAAK,CAAC;AACjD,QAAM,gBAAY,sBAAO,MAAM;AAC/B,QAAM,gBAAY,sBAAO,MAAM;AAE/B,aAAW,UAAU;AACrB,cAAY,UAAU;AACtB,YAAU,UAAU;AACpB,YAAU,UAAU;AAEpB,QAAM,aAAa,MACjB,eAAe,YAAY,KAC3B,iBAAiB,YAAY,KAC7B,gBAAgB,YAAY;AAE9B,QAAM,oBAAoB,MACxB,eAAe,WACf,eAAe,WACf,kBAAkB,WAClB,wBAAwB,UAAU,KAClC,WAAW;AAEb,QAAM,kBAAkB,MAAM;AAC5B,mBAAe,UAAU,eAAe,WAAW,eAAe;AAAA,EACpE;AAEA,QAAM,oBAAoB,CACxB,MACA,UAAyB,cAAc,YACrB;AAClB,WAAO;AAAA,MACL,KAAK,aAAa,KAAK,OAAO,QAAQ,GAAG;AAAA,MACzC,OAAO,MAAM,KAAK,SAAS,QAAQ,OAAO,CAAC,WAAW,SAAS;AAAA,MAC/D,KAAK;AAAA,QACH,KAAK,OAAO,QAAQ;AAAA,QACpB,UAAU;AAAA,QACV,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAEA,QAAM,oBAAoB,CACxB,MACA,UAAyB,cAAc,YACrB;AAClB,UAAM,WAAW,WAAW,QAAQ,mBAAmB;AACvD,QAAI,CAAC,YAAY,CAAC,eAAe,SAAS;AACxC,aAAO,kBAAkB,MAAM,OAAO;AAAA,IACxC;AAEA,UAAM,WAAW,KAAK,IAAI,UAAU,UAAU,UAAU,SAAS,CAAC;AAClE,UAAM,eAAe,WAAW;AAChC,WAAO;AAAA,MACL,KAAK,aAAa,KAAK,OAAO,QAAQ,GAAG;AAAA,MACzC,OAAO;AAAA,QACL,KAAK,SAAS,QAAQ;AAAA,QACtB,CAAC,YAAY;AAAA,QACb,YAAY;AAAA,MACd;AAAA,MACA,KAAK;AAAA,QACH,KAAK,OAAO,QAAQ;AAAA,QACpB,UAAU,UAAU;AAAA,QACpB,UAAU,UAAU;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,eAAe,MAAM;AACzB,mBAAe,UAAU;AACzB,qBAAiB,UAAU;AAC3B,oBAAgB,UAAU;AAC1B,4BAAwB,UAAU;AAAA,EACpC;AAEA,QAAM,YAAY,MAAM;AACtB,aAAS,UAAU;AACnB,eAAW,UAAU;AAAA,EACvB;AAEA,QAAM,yBAAyB,MAAM;AACnC,UAAM,OAAO,kBAAkB,cAAc,OAAO;AACpD,QACE,KAAK,QAAQ,cAAc,QAAQ,OACnC,KAAK,UAAU,cAAc,QAAQ,SACrC,KAAK,QAAQ,cAAc,QAAQ,KACnC;AACA,oBAAc,UAAU;AACxB,gBAAU;AAAA,IACZ;AAAA,EACF;AAEA,QAAM,yBAAyB,MAAM;AACnC,4BAAwB,WAAW;AACnC,iBAAa;AACb,QAAI,eAAe,SAAS;AAC1B,qBAAe,UAAU;AACzB,kBAAY,QAAQ,KAAK,sBAAsB,EAAE,QAAQ,QAAQ,CAAC;AAAA,IACpE;AACA,QAAI,eAAe,SAAS;AAC1B,qBAAe,UAAU;AACzB,kBAAY,QAAQ,KAAK,sBAAsB,EAAE,QAAQ,QAAQ,CAAC;AAAA,IACpE;AACA,oBAAgB;AAEhB,QAAI,WAAW;AACf,WAAO,MAAM;AACX,UAAI,UAAU;AACZ;AAAA,MACF;AACA,iBAAW;AACX,8BAAwB,UAAU,KAAK;AAAA,QACrC;AAAA,QACA,wBAAwB,UAAU;AAAA,MACpC;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU,CACd,MACA,eACG;AACH,UAAM,WAAW,kBAAkB,IAAI;AACvC,kBAAc,UAAU;AACxB,YAAQ,UAAU;AAClB,QAAI,YAAY,cAAc,OAAO;AACnC,mBAAa;AAAA,IACf;AACA,cAAU;AAAA,EACZ;AAEA,QAAM,iBAAiB,CACrB,OACA,iBACY;AACZ,QAAI,wBAAwB,UAAU,GAAG;AACvC,aAAO;AAAA,IACT;AAEA,UAAM,UAAU,cAAc;AAC9B,UAAM,UACJ,MAAM,QAAQ,UAAa,OAAO,SAAS,MAAM,GAAG,IAChD,QAAQ,MAAM,MAAM,MACpB,QAAQ;AACd,UAAM,YACJ,MAAM,UAAU,UAAa,OAAO,SAAS,MAAM,KAAK,IACpD,QAAQ,QAAQ,MAAM,QACtB,QAAQ;AACd,UAAM,UACJ,MAAM,QAAQ,UAAa,OAAO,SAAS,MAAM,GAAG,IAChD,QAAQ,MAAM,MAAM,MACpB,QAAQ;AAEd,kBAAc,UAAU,kBAAkB;AAAA,MACxC,KAAK;AAAA,MACL,OAAO;AAAA,MACP,KAAK;AAAA,IACP,CAAC;AACD,cAAU;AAEV,QAAI,cAAc,gBAAgB;AAChC,YAAM,MAAM,YAAY,IAAI;AAC5B,YAAM,aAAa,wBAAwB;AAC3C,YAAM,UACJ,eAAe,OACX,IAAI,KACJ,KAAK,KAAK,MAAM,cAAc,KAAM,IAAI,GAAG;AACjD,8BAAwB,UAAU;AAElC,UAAI,MAAM,QAAQ,UAAa,OAAO,SAAS,MAAM,GAAG,GAAG;AACzD,uBAAe,UAAU,MAAM,MAAM;AAAA,MACvC;AACA,UAAI,MAAM,UAAU,UAAa,OAAO,SAAS,MAAM,KAAK,GAAG;AAC7D,yBAAiB,UAAU,MAAM,QAAQ;AAAA,MAC3C;AACA,UAAI,MAAM,QAAQ,UAAa,OAAO,SAAS,MAAM,GAAG,GAAG;AACzD,wBAAgB,UAAU,MAAM,MAAM,MAAM,SAAS,MAAM,GAAG;AAAA,MAChE;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA;AAAA,IACE;AAAA,IACA,OAAO;AAAA,MACL,SAAS,OAAO,EAAE,GAAG,QAAQ,QAAQ;AAAA,MACrC,eAAe,OAAO,EAAE,GAAG,cAAc,QAAQ;AAAA,MACjD;AAAA,MACA,OAAO,MAAM,QAAQ,eAAe,OAAO;AAAA,MAC3C;AAAA,MACA,mBAAmB,CAAC,WAAoB;AACtC,cAAM,YAAY,kBAAkB;AACpC,0BAAkB,UAAU;AAC5B,YAAI,UAAU,CAAC,WAAW;AACxB,sBAAY,QAAQ,KAAK,wBAAwB;AAAA,YAC/C,QAAQ;AAAA,UACV,CAAC;AAAA,QACH,WAAW,CAAC,UAAU,WAAW;AAC/B,sBAAY,QAAQ,KAAK,sBAAsB;AAAA,YAC7C,QAAQ;AAAA,UACV,CAAC;AAAA,QACH;AAAA,MACF;AAAA,MACA,kBAAkB,CAAC,QAAQ,WAAW;AACpC,cAAM,YACJ,WAAW,UACP,eAAe,UACf,eAAe;AACrB,YAAI,WAAW,SAAS;AACtB,yBAAe,UAAU;AAAA,QAC3B,OAAO;AACL,yBAAe,UAAU;AAAA,QAC3B;AACA,wBAAgB;AAChB,YAAI,UAAU,CAAC,WAAW;AACxB,sBAAY,QAAQ,KAAK,wBAAwB,EAAE,OAAO,CAAC;AAAA,QAC7D,WAAW,CAAC,UAAU,WAAW;AAC/B,sBAAY,QAAQ,KAAK,sBAAsB,EAAE,OAAO,CAAC;AAAA,QAC3D;AACA,YAAI,QAAQ;AACV,uBAAa;AAAA,QACf,WAAW,CAAC,eAAe,WAAW,CAAC,eAAe,SAAS;AAC7D,kCAAwB,UAAU;AAClC,iCAAuB;AAAA,QACzB;AAAA,MACF;AAAA,MACA,qBAAqB,MAAM,wBAAwB,UAAU;AAAA,MAC7D;AAAA,MACA;AAAA,MACA,mBAAmB,CAAC,aAAqB;AACvC,cAAM,kBACJ,eAAe,YAAY,KAC3B,iBAAiB,YAAY,KAC7B,gBAAgB,YAAY;AAC9B,YACE,CAAC,OAAO,SAAS,QAAQ,KACzB,wBAAwB,UAAU,KAClC,eAAe,WACf,kBAAkB,WAClB,CAAC,iBACD;AACA,iBAAO;AAAA,QACT;AAEA,sBAAc,QAAQ,OAAO;AAC7B,kBAAU;AACV,eAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,CAAC;AAAA,EACH;AAEA,+BAAU,MAAM;AACd,mBAAe,UAAU,EAAE,GAAG,YAAY;AAC1C,YAAQ,WAAW;AAAA,EACrB,GAAG,CAAC,YAAY,KAAK,YAAY,OAAO,YAAY,GAAG,CAAC;AAExD,6BAAS,CAAC,GAAG,iBAAiB;AAC5B,QAAI,EAAE,kBAAkB,iCAAoB;AAC1C;AAAA,IACF;AAEA,UAAM,eAAe,oBAAoB,WAAW,QAAQ,YAAY;AACxE,UAAM,iBAAiB,WAAW,QAAQ,YAAY;AACtD,QAAI,CAAC,eAAe,WAAW,gBAAgB;AAC7C,YAAM,kBAAkB,KAAK;AAAA,QAC3B,CAAC,2BAA2B;AAAA,MAC9B;AACA,YAAMC,eAAc,KAAK,IAAI,CAAC,uBAAuB,YAAY;AAEjE,UAAI,KAAK,IAAI,eAAe,OAAO,KAAK,cAAc;AACpD,sBAAc,QAAQ,OAAO,eAAe,UAAU;AACtD,uBAAe,WAAW;AAC1B,kBAAU;AAAA,MACZ,OAAO;AACL,uBAAe,UAAU;AAAA,MAC3B;AAEA,UAAI,KAAK,IAAI,iBAAiB,OAAO,KAAK,cAAc;AACtD,sBAAc,QAAQ,SAAS,iBAAiB,UAAU;AAC1D,yBAAiB,WAAW;AAC5B,kBAAU;AAAA,MACZ,OAAO;AACL,yBAAiB,UAAU;AAAA,MAC7B;AAEA,UAAI,KAAK,IAAI,gBAAgB,OAAO,KAAK,cAAc;AACrD,sBAAc,QAAQ,OAAO,gBAAgB,UAAU;AACvD,wBAAgB,WAAWA;AAC3B,kBAAU;AAAA,MACZ,OAAO;AACL,wBAAgB,UAAU;AAAA,MAC5B;AAAA,IACF,WAAW,CAAC,gBAAgB;AAC1B,mBAAa;AAAA,IACf;AAEA,QAAI,CAAC,eAAe,SAAS;AAC3B,oBAAc,UAAU,kBAAkB,cAAc,OAAO;AAAA,IACjE,OAAO;AACL,oBAAc,UAAU,kBAAkB,cAAc,OAAO;AAAA,IACjE;AAEA,QAAI,CAAC,SAAS,SAAS;AACrB;AAAA,IACF;AAEA,UAAM,aAAa,cAAc;AACjC,UAAM,gBAAgB;AAAA,MACpB,WAAW,QAAQ;AAAA,MACnB;AAAA,IACF;AACA,UAAM,cAAc;AAAA,MAClB,WAAW,QAAQ;AAAA,MACnB;AAAA,IACF;AACA,UAAM,iBAAiB,cAAc,eAAe,YAAY;AAChE,UAAM,aAAa,cAAc,aAAa,YAAY;AAC1D,UAAM,WAAW,iBAAiB,QAAQ,QAAQ,KAAK,WAAW,GAAG;AACrE,UAAM,eAAe;AAAA,MACnB,KAAK,aAAa,QAAQ,QAAQ,MAAM,WAAW,cAAc;AAAA,MACjE,OACE,QAAQ,QAAQ,SACf,WAAW,QAAQ,QAAQ,QAAQ,SAAS;AAAA,MAC/C,KACE,QAAQ,QAAQ,OACf,WAAW,MAAM,QAAQ,QAAQ,OAAO;AAAA,IAC7C;AACA,UAAM,aACJ,KAAK,IAAI,iBAAiB,aAAa,KAAK,WAAW,GAAG,CAAC,IACzD,uBACF,KAAK,IAAI,aAAa,QAAQ,WAAW,KAAK,IAAI,uBAClD,KAAK,IAAI,aAAa,MAAM,WAAW,GAAG,IAAI;AAChD,YAAQ,UAAU,aAAa,EAAE,GAAG,WAAW,IAAI;AACnD,aAAS,QAAQ;AAAA,MACf,uBAAU,SAAS,QAAQ,QAAQ,KAAK;AAAA,MACxC,uBAAU,SAAS,CAAC,QAAQ,QAAQ,GAAG;AAAA,MACvC;AAAA,MACA;AAAA,IACF;AACA,WAAO,WAAW,aAAa,SAAS,OAAO;AAC/C,WAAO,MAAM,QAAQ,QAAQ;AAC7B,WAAO,uBAAuB;AAC9B,WAAO,kBAAkB;AAEzB,UAAM,WAAW,EAAE,GAAG,QAAQ,QAAQ;AACtC,UAAM,cAAc,mBAAmB;AACvC,QAAI,CAAC,eAAe,CAAC,WAAW,aAAa,QAAQ,GAAG;AACtD,yBAAmB,UAAU;AAC7B,kBAAY,QAAQ,KAAK,cAAc,QAAQ;AAAA,IACjD;AAEA,UAAM,aAAa,WAAW;AAC9B,eAAW,UAAU;AACrB,QAAI,cAAc,CAAC,YAAY;AAC7B,kBAAY,QAAQ,KAAK,eAAe,QAAQ;AAAA,IAClD;AAEA,aAAS,UAAU,CAAC;AAAA,EACtB,CAAC;AAED,SAAO;AACT,CAAC;;;AFzeD,IAAM,4BAA4B;AAClC,IAAM,mCAAmC;AACzC,IAAM,kCAAkC;AAiBxC,SAAS,kBAAkB,OAAmC;AAC5D,SAAO,OAAO,SAAS,KAAK,IAAI,KAAK,IAAI,OAAQ,CAAC,IAAI;AACxD;AAEA,SAAS,oBAAoB,OAAmC;AAC9D,SAAO,OAAO,SAAS,KAAK,KAAK,SAAU,IACvC,QACA;AACN;AAMO,SAAS,WAAW;AAAA,EACzB,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,aAAa;AACf,GAAoB;AAClB,QAAM,kBAAc,0BAAW,mBAAmB;AAClD,QAAM,eAAW,0BAAW,mBAAmB;AAC/C,QAAM,iBAAa,sBAAO,CAAC;AAC3B,QAAM,uBAAmB,sBAAO,CAAC;AACjC,QAAM,kBAAc,sBAAO,KAAK;AAChC,QAAM,wBAAoB,sBAAO,CAAC;AAElC,MAAI,CAAC,aAAa;AAChB,UAAM,IAAI,MAAM,kDAAkD;AAAA,EACpE;AAEA,+BAAU,MAAM;AACd,eAAW,UAAU;AACrB,qBAAiB,UAAU;AAC3B,sBAAkB,UAAU;AAC5B,QAAI,YAAY,SAAS;AACvB,kBAAY,UAAU;AACtB,gBAAU,KAAK,kBAAkB,MAAS;AAAA,IAC5C;AAAA,EACF,GAAG,CAAC,SAAS,UAAU,UAAU,CAAC;AAElC,8BAAS,CAAC,GAAG,iBAAiB;AAC5B,QAAI,CAAC,WAAW,CAAC,OAAO,SAAS,KAAK,KAAK,UAAU,GAAG;AACtD,uBAAiB,UAAU;AAC3B,UAAI,YAAY,SAAS;AACvB,oBAAY,UAAU;AACtB,kBAAU,KAAK,kBAAkB,MAAS;AAAA,MAC5C;AACA;AAAA,IACF;AAEA,UAAM,eAAe,kBAAkB,UAAU,IAAI;AACrD,eAAW,WAAW;AACtB,QAAI,WAAW,UAAU,cAAc;AACrC;AAAA,IACF;AAEA,UAAM,cAAc,KAAK,IAAI,KAAK;AAClC,UAAM,eAAe,iBAAiB;AACtC,UAAM,wBAAwB,oBAAoB,YAAY;AAC9D,UAAM,YACJ,0BAA0B,IACtB,cACA,KAAK;AAAA,MACH;AAAA,MACA,eAAe,wBAAwB;AAAA,IACzC;AACN,UAAM,gBAAgB,eAAe,aAAa;AAClD,UAAM,WAAW,KAAK,KAAK,KAAK,IAAI,eAAe;AAEnD,QAAI,CAAC,YAAY,SAAS,kBAAkB,QAAQ,GAAG;AACrD,uBAAiB,UAAU;AAC3B,UAAI,YAAY,SAAS;AACvB,oBAAY,UAAU;AACtB,kBAAU,KAAK,kBAAkB,MAAS;AAAA,MAC5C;AACA;AAAA,IACF;AAEA,QAAI,CAAC,YAAY,SAAS;AACxB,kBAAY,UAAU;AACtB,gBAAU,KAAK,mBAAmB,MAAS;AAAA,IAC7C;AAEA,sBAAkB,WAAW,KAAK,IAAI,QAAQ;AAC9C,WAAO,kBAAkB,WAAW,KAAK;AACvC,wBAAkB,WAAW;AAC7B,gBAAU,KAAK,sBAAsB,MAAS;AAAA,IAChD;AAEA,qBAAiB,UAAU;AAAA,EAC7B,CAAC;AAED,SAAO;AACT;;;AGtHA,IAAAC,gBAQO;AA+HG;AA5GH,IAAM,kCACX,6BAAmD,IAAI;AAEzD,IAAM,wBAAuC;AAAA,EAC3C,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,SAAS;AAAA,EACT,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,OAAO;AACT;AAEA,SAAS,sBAAsB,IAAY;AACzC,QAAM,UACJ,WAGA,SAAS,KAAK;AAChB,MAAI,YAAY,cAAc;AAC5B,YAAQ;AAAA,MACN,YAAY,EAAE;AAAA,IAChB;AAAA,EACF;AACF;AAEO,SAAS,wBAAwB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AACF,GAIY;AACV,QAAM,eAAW,0BAAW,2BAA2B;AACvD,QAAM,CAAC,SAAS,UAAU,QAAI,wBAAS,KAAK;AAC5C,QAAM,kBAAc,sBAAO,UAAU;AACrC,QAAM,UAAU,QAAQ,UAAU;AAClC,cAAY,UAAU;AAEtB,+BAAU,MAAM;AACd,QAAI,CAAC,SAAS;AACZ,iBAAW,KAAK;AAChB;AAAA,IACF;AACA,QAAI,CAAC,WAAW;AACd,4BAAsB,EAAE;AACxB;AAAA,IACF;AACA,QAAI,CAAC,UAAU;AACb;AAAA,IACF;AAEA,WAAO,SAAS,SAAS;AAAA,MACvB;AAAA,MACA,OAAO;AAAA,MACP,UAAU,CAAC,UAAU,YAAY,UAAU,KAAK;AAAA,MAChD,eAAe;AAAA,IACjB,CAAC;AAAA,EACH,GAAG,CAAC,WAAW,SAAS,IAAI,QAAQ,CAAC;AAErC,SAAO;AACT;AAEO,SAAS,+BAGd;AACA,QAAM,CAAC,SAAS,UAAU,QAAI,wBAE5B,MAAM,oBAAI,IAAI,CAAC;AAEjB,QAAM,eAAW;AAAA,IACf,CAAC,UAAoD;AACnD,YAAM,QAAQ,OAAO,MAAM,EAAE;AAC7B,YAAM,YAAuC,EAAE,GAAG,OAAO,MAAM;AAC/D,iBAAW,CAAC,YAAY;AACtB,cAAM,OAAO,IAAI,IAAI,OAAO;AAC5B,aAAK,IAAI,MAAM,IAAI,SAAS;AAC5B,eAAO;AAAA,MACT,CAAC;AAED,aAAO,MAAM;AACX,mBAAW,CAAC,YAAY;AACtB,cAAI,QAAQ,IAAI,MAAM,EAAE,GAAG,UAAU,OAAO;AAC1C,mBAAO;AAAA,UACT;AACA,gBAAM,OAAO,IAAI,IAAI,OAAO;AAC5B,eAAK,OAAO,MAAM,EAAE;AACpB,iBAAO;AAAA,QACT,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,eAAW;AAAA,IACf,OAAO,EAAE,SAAS;AAAA,IAClB,CAAC,QAAQ;AAAA,EACX;AACA,QAAM,eAAW;AAAA,IACf,MACE,4CAAC,SAAI,cAAW,qBAAoB,OAAO,EAAE,eAAe,OAAO,GAChE,gBAAM,KAAK,QAAQ,OAAO,CAAC,EAAE,IAAI,CAAC,UACjC;AAAA,MAAC;AAAA;AAAA,QACC,cAAY,MAAM;AAAA,QAElB,QAAQ,MAAM,MAAM,cAAc,KAAK;AAAA,QACvC,SAAS,CAAC,UAAU,MAAM,SAAS,MAAM,WAAW;AAAA,QACpD,SAAS,MAAM,MAAM,cAAc,IAAI;AAAA,QACvC,WAAW,CAAC,UAAU;AACpB,cAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,KAAK;AAC9C,kBAAM,eAAe;AACrB,kBAAM,SAAS,MAAM,WAAW;AAAA,UAClC;AAAA,QACF;AAAA,QACA,OAAO;AAAA,QACP,MAAK;AAAA,QAEJ,gBAAM;AAAA;AAAA,MAbF,MAAM;AAAA,IAcb,CACD,GACH;AAAA,IAEF,CAAC,OAAO;AAAA,EACV;AAEA,SAAO,EAAE,UAAU,SAAS;AAC9B;;;AC/JA,IAAAC,gBAAmC;AACnC,IAAAC,gBAAuD;AAGvD,IAAM,uBAAuB;AAC7B,IAAM,qBAAqB;AAC3B,IAAM,2BAA2B;AA6CjC,IAAM,eAAiE;AAAA,EACrE,MAAM,CAAC,WAAW;AAAA,EAClB,OAAO,CAAC,YAAY;AAAA,EACpB,IAAI,CAAC,SAAS;AAAA,EACd,MAAM,CAAC,WAAW;AAAA,EAClB,QAAQ,CAAC,KAAK,GAAG;AAAA,EACjB,SAAS,CAAC,KAAK,GAAG;AAAA,EAClB,eAAe,CAAC,KAAK,QAAQ;AAAA,EAC7B,WAAW,CAAC,KAAK,UAAU;AAAA,EAC3B,OAAO,CAAC,GAAG;AACb;AAEA,IAAM,qBAAqB,oBAAI,IAA2B;AAAA,EACxD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,SAAS,iBAAiB,OAAyD;AACjF,MAAI,UAAU,QAAW;AACvB,WAAO,CAAC;AAAA,EACV;AACA,UAAQ,OAAO,UAAU,WAAW,CAAC,KAAK,IAAI,CAAC,GAAG,KAAK,GAAG;AAAA,IACxD,CAAC,UAAU,MAAM,SAAS;AAAA,EAC5B;AACF;AAEA,SAAS,cACP,WACoC;AACpC,QAAM,MAAM,oBAAI,IAAmC;AACnD,aAAW,UAAU,OAAO,KAAK,YAAY,GAA8B;AACzE,UAAM,WACJ,aAAa,UAAU,YACnB,iBAAiB,UAAU,MAAM,CAAC,IAClC,CAAC,GAAG,aAAa,MAAM,CAAC;AAC9B,eAAW,WAAW,UAAU;AAC9B,UAAI,IAAI,QAAQ,YAAY,GAAG,MAAM;AAAA,IACvC;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,YACP,OACA,QAC8B;AAC9B,SACE,OAAO,IAAI,MAAM,IAAI,YAAY,CAAC,KAClC,OAAO,IAAI,MAAM,KAAK,YAAY,CAAC,KACnC;AAEJ;AAEA,SAAS,aAAa,OAA2B,UAA0B;AACzE,SAAO,OAAO,SAAS,KAAK,KAAK,SAAU,IAAI,QAAS;AAC1D;AAOO,SAAS,aACd,QACA,eACA,MACe;AACf,MAAI,OAAO,WAAW,GAAG;AACvB,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,OAAO,UAAU,CAAC,UAAU,MAAM,OAAO,aAAa;AACpE,MAAI,QAAQ,GAAG;AACb,WAAO;AAAA,EACT;AACA,QAAM,aAAa,QAAQ,OAAO,OAAO,UAAU,OAAO;AAC1D,SAAO,OAAO,SAAS,GAAG,MAAM;AAClC;AAQO,SAAS,iBAAiB;AAAA,EAC/B,UAAU;AAAA,EACV;AAAA,EACA,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AACF,GAA0B;AACxB,QAAM,kBAAc,0BAAW,mBAAmB;AAClD,QAAM,EAAE,GAAG,QAAI,wBAAS;AACxB,QAAM,iBAAa,sBAAO,oBAAI,IAA2B,CAAC;AAC1D,QAAM,mBAAe,sBAAO,KAAK;AACjC,QAAM,gBAAY,sBAAO,MAAM;AAC/B,QAAM,kBAAc,sBAAO,QAAQ;AACnC,QAAM,yBAAqB,sBAAO,eAAe;AACjD,QAAM,qBAAiB,sBAAO,WAAW;AACzC,QAAM,aAAS,uBAAQ,MAAM,cAAc,IAAI,GAAG,CAAC,IAAI,CAAC;AAExD,MAAI,CAAC,aAAa;AAChB,UAAM,IAAI,MAAM,wDAAwD;AAAA,EAC1E;AAEA,YAAU,UAAU;AACpB,cAAY,UAAU;AACtB,qBAAmB,UAAU;AAC7B,iBAAe,UAAU;AAEzB,+BAAU,MAAM;AACd,UAAM,UAAU,GAAG;AACnB,QAAI,CAAC,SAAS;AACZ,iBAAW,QAAQ,MAAM;AACzB,mBAAa,UAAU;AACvB,kBAAY,SAAS,kBAAkB,KAAK;AAC5C;AAAA,IACF;AAEA,UAAM,qBAAqB,MAAM;AAC/B,UAAI,aAAa;AACjB,iBAAW,UAAU,WAAW,SAAS;AACvC,YAAI,mBAAmB,IAAI,MAAM,GAAG;AAClC,uBAAa;AACb;AAAA,QACF;AAAA,MACF;AACA,kBAAY,SAAS,kBAAkB,UAAU;AAAA,IACnD;AAEA,UAAM,eAAe,MAAM;AACzB,iBAAW,QAAQ,MAAM;AACzB,mBAAa,UAAU;AACvB,kBAAY,SAAS,kBAAkB,KAAK;AAAA,IAC9C;AAEA,UAAM,YAAY,CAAC,UAAyB;AAC1C,UAAI,MAAM,QAAQ,SAAS;AACzB,qBAAa,UAAU;AAAA,MACzB;AAEA,YAAM,SAAS,YAAY,OAAO,MAAM;AACxC,UAAI,CAAC,QAAQ;AACX;AAAA,MACF;AAEA,UAAI,YAAY,SAAS,oBAAoB,GAAG;AAC9C;AAAA,MACF;AAEA,YAAM,eAAe;AAErB,UAAI,WAAW,SAAS;AACtB,YAAI,CAAC,MAAM,QAAQ;AACjB,sBAAY,SAAS,MAAM;AAAA,QAC7B;AACA;AAAA,MACF;AAEA,UAAI,WAAW,iBAAiB;AAC9B,YAAI,CAAC,MAAM,QAAQ;AACjB,6BAAmB,UAAU;AAAA,QAC/B;AACA;AAAA,MACF;AAEA,UAAI,WAAW,aAAa;AAC1B,YAAI,CAAC,MAAM,QAAQ;AACjB,yBAAe,UAAU;AAAA,QAC3B;AACA;AAAA,MACF;AAEA,iBAAW,QAAQ,IAAI,MAAM;AAC7B,yBAAmB;AAAA,IACrB;AAEA,UAAM,UAAU,CAAC,UAAyB;AACxC,UAAI,MAAM,QAAQ,SAAS;AACzB,qBAAa,UAAU;AAAA,MACzB;AAEA,YAAM,SAAS,YAAY,OAAO,MAAM;AACxC,UAAI,CAAC,UAAU,CAAC,mBAAmB,IAAI,MAAM,GAAG;AAC9C;AAAA,MACF;AAEA,iBAAW,QAAQ,OAAO,MAAM;AAChC,yBAAmB;AAAA,IACrB;AAEA,UAAM,SAAS,MAAM;AACnB,mBAAa;AAAA,IACf;AAEA,YAAQ,iBAAiB,WAAW,SAAS;AAC7C,YAAQ,iBAAiB,SAAS,OAAO;AACzC,YAAQ,iBAAiB,QAAQ,MAAM;AACvC,WAAO,iBAAiB,QAAQ,MAAM;AAEtC,WAAO,MAAM;AACX,cAAQ,oBAAoB,WAAW,SAAS;AAChD,cAAQ,oBAAoB,SAAS,OAAO;AAC5C,cAAQ,oBAAoB,QAAQ,MAAM;AAC1C,aAAO,oBAAoB,QAAQ,MAAM;AACzC,mBAAa;AAAA,IACf;AAAA,EACF,GAAG,CAAC,aAAa,SAAS,IAAI,MAAM,CAAC;AAErC,8BAAS,CAAC,GAAG,iBAAiB;AAC5B,QAAI,CAAC,WAAW,WAAW,QAAQ,SAAS,GAAG;AAC7C;AAAA,IACF;AAEA,UAAM,WAAW,YAAY;AAC7B,QAAI,CAAC,UAAU;AACb;AAAA,IACF;AAEA,UAAM,aAAa,aAAa,UAC5B,aAAa,iBAAiB,wBAAwB,IACtD;AACJ,UAAM,WACJ,aAAa,aAAa,oBAAoB,IAAI,aAAa;AACjE,QAAI,OACF,aAAa,WAAW,kBAAkB,IAAI,aAAa;AAC7D,UAAM,SAAS,YAAY;AAC3B,QAAI,OAAO,SAAS,MAAM,KAAK,UAAW,GAAG;AAC3C,aAAO,KAAK,IAAI,MAAM,SAAU,YAAY;AAAA,IAC9C;AAEA,UAAM,YAAY,UAAU,UAAU,KAAK;AAC3C,QAAI,MAAM;AACV,QAAI,QAAQ;AACZ,QAAI,MAAM;AAEV,eAAW,UAAU,WAAW,SAAS;AACvC,cAAQ,QAAQ;AAAA,QACd,KAAK;AACH,iBAAO;AACP;AAAA,QACF,KAAK;AACH,iBAAO;AACP;AAAA,QACF,KAAK;AACH,mBAAS,YAAY;AACrB;AAAA,QACF,KAAK;AACH,mBAAS,YAAY;AACrB;AAAA,QACF,KAAK;AACH,iBAAO;AACP;AAAA,QACF,KAAK;AACH,iBAAO;AACP;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AACH;AAAA,QACF,SAAS;AACP,gBAAM,cAAqB;AAC3B,eAAK;AACL;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,QAAQ,KAAK,UAAU,KAAK,QAAQ,GAAG;AACzC,eAAS,eAAe,EAAE,KAAK,OAAO,IAAI,CAAC;AAAA,IAC7C;AAAA,EACF,CAAC;AAED,SAAO;AACT;;;AC7UA,IAAAC,gBAAyB;AACzB,IAAAC,gBAA8C;AAI9C,IAAMC,wBAAuB;AAC7B,IAAMC,sBAAqB;AAE3B,IAAM,cAAkD;AAAA,EACtD,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AACT;AAWA,SAASC,cAAa,OAA2B,UAA0B;AACzE,SAAO,OAAO,SAAS,KAAK,KAAK,SAAU,IAAI,QAAS;AAC1D;AAEA,SAAS,eACP,SACa;AACb,QAAM,OAAO,WAAW,QAAQ,SAAS,IAAI,UAAW,CAAC,MAAM;AAC/D,SAAO,IAAI,IAAI,KAAK,IAAI,CAAC,WAAW,YAAY,MAAM,CAAC,CAAC;AAC1D;AAMO,SAAS,cAAc;AAAA,EAC5B,UAAU;AAAA,EACV,cAAcF;AAAA,EACd,YAAYC;AAAA,EACZ,QAAQ;AAAA,EACR,SAAS;AAAA,EACT;AAAA,EACA;AACF,GAAuB;AACrB,QAAM,kBAAc,0BAAW,mBAAmB;AAClD,QAAM,EAAE,GAAG,QAAI,wBAAS;AACxB,QAAM,kBAAc;AAAA,IAClB,oBAAI,IAAkD;AAAA,EACxD;AACA,QAAM,iBAAa,sBAAO;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,MAAI,CAAC,aAAa;AAChB,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACvE;AAEA,aAAW,UAAU;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,+BAAU,MAAM;AACd,UAAM,UAAU,GAAG;AACnB,UAAM,iBAAiB,eAAe,OAAO;AAE7C,UAAM,gBAAgB,MAAM;AAC1B,iBAAW,aAAa,YAAY,QAAQ,KAAK,GAAG;AAClD,YAAI,QAAQ,oBAAoB,SAAS,GAAG;AAC1C,kBAAQ,wBAAwB,SAAS;AAAA,QAC3C;AAAA,MACF;AACA,kBAAY,QAAQ,MAAM;AAC1B,kBAAY,SAAS,iBAAiB,SAAS,KAAK;AAAA,IACtD;AAEA,QAAI,CAAC,SAAS;AACZ,oBAAc;AACd;AAAA,IACF;AAEA,UAAM,cAAc,CAAC,UACnB,MAAM,gBAAgB,WAAW,MAAM,gBAAgB;AAEzD,UAAM,aAAa,MAAM;AACvB,kBAAY,SAAS;AAAA,QACnB;AAAA,QACA,YAAY,QAAQ,OAAO;AAAA,MAC7B;AAAA,IACF;AAEA,UAAM,gBAAgB,CAAC,UAAwB;AAC7C,UAAI,CAAC,YAAY,KAAK,GAAG;AACvB;AAAA,MACF;AACA,UAAI,YAAY,SAAS,oBAAoB,GAAG;AAC9C;AAAA,MACF;AACA,UAAI,CAAC,eAAe,IAAI,MAAM,MAAM,GAAG;AACrC;AAAA,MACF;AAEA,YAAM,eAAe;AACrB,kBAAY,QAAQ,IAAI,MAAM,WAAW;AAAA,QACvC,GAAG,MAAM;AAAA,QACT,GAAG,MAAM;AAAA,QACT,IAAI,YAAY,IAAI;AAAA,MACtB,CAAC;AACD,cAAQ,oBAAoB,MAAM,SAAS;AAC3C,iBAAW;AAAA,IACb;AAEA,UAAM,gBAAgB,CAAC,UAAwB;AAC7C,UAAI,CAAC,YAAY,KAAK,GAAG;AACvB;AAAA,MACF;AACA,UAAI,YAAY,SAAS,oBAAoB,GAAG;AAC9C;AAAA,MACF;AACA,YAAM,WAAW,YAAY,QAAQ,IAAI,MAAM,SAAS;AACxD,UAAI,CAAC,UAAU;AACb;AAAA,MACF;AAEA,YAAM,eAAe;AACrB,YAAM,OAAO;AAAA,QACX,GAAG,MAAM;AAAA,QACT,GAAG,MAAM;AAAA,QACT,IAAI,YAAY,IAAI;AAAA,MACtB;AACA,kBAAY,QAAQ,IAAI,MAAM,WAAW,IAAI;AAE7C,YAAM,OAAO,QAAQ,sBAAsB;AAC3C,YAAM,QAAQC;AAAA,QACZ,WAAW,QAAQ;AAAA,QACnBF;AAAA,MACF;AACA,YAAM,OAAO,WAAW,QAAQ,SAAS,KAAK;AAC9C,YAAM,WACH,OAAO,EAAE,KAAK,IAAI,SAAS,KAAK,MAAM,QACvC,KAAK,IAAI,KAAK,OAAO,CAAC;AACxB,YAAM,aACH,QAAQ,KAAK,IAAI,SAAS,KAAK,MAAM,QACtC,KAAK,IAAI,KAAK,QAAQ,CAAC;AAEzB,kBAAY,SAAS;AAAA,QACnB,EAAE,KAAK,UAAU,OAAO,WAAW;AAAA,QACnC,EAAE,gBAAgB,KAAK;AAAA,MACzB;AAAA,IACF;AAEA,UAAM,iBAAiB,CAAC,UAAwB;AAC9C,UAAI,CAAC,YAAY,QAAQ,IAAI,MAAM,SAAS,GAAG;AAC7C;AAAA,MACF;AACA,kBAAY,QAAQ,OAAO,MAAM,SAAS;AAC1C,UAAI,QAAQ,oBAAoB,MAAM,SAAS,GAAG;AAChD,gBAAQ,wBAAwB,MAAM,SAAS;AAAA,MACjD;AACA,iBAAW;AAAA,IACb;AAEA,UAAM,UAAU,CAAC,UAAsB;AACrC,UAAI,CAAC,WAAW,QAAQ,OAAO;AAC7B;AAAA,MACF;AACA,UAAI,YAAY,SAAS,oBAAoB,GAAG;AAC9C,cAAM,eAAe;AACrB;AAAA,MACF;AACA,YAAM,eAAe;AAErB,YAAM,QAAQE;AAAA,QACZ,WAAW,QAAQ;AAAA,QACnBD;AAAA,MACF;AACA,UAAI,QAAQ,MAAM,SAAS;AAC3B,YAAM,MAAM,WAAW,QAAQ;AAC/B,UAAI,OAAO,SAAS,GAAG,KAAK,MAAO,GAAG;AACpC,gBAAQ,KAAK,IAAI,CAAC,KAAM,KAAK,IAAI,KAAM,KAAK,CAAC;AAAA,MAC/C;AAEA,kBAAY,SAAS;AAAA,QACnB,EAAE,KAAK,MAAM;AAAA,QACb,EAAE,gBAAgB,KAAK;AAAA,MACzB;AAAA,IACF;AAEA,YAAQ,iBAAiB,eAAe,aAAa;AACrD,YAAQ,iBAAiB,eAAe,aAAa;AACrD,YAAQ,iBAAiB,aAAa,cAAc;AACpD,YAAQ,iBAAiB,iBAAiB,cAAc;AACxD,YAAQ,iBAAiB,SAAS,SAAS,EAAE,SAAS,MAAM,CAAC;AAE7D,WAAO,MAAM;AACX,cAAQ,oBAAoB,eAAe,aAAa;AACxD,cAAQ,oBAAoB,eAAe,aAAa;AACxD,cAAQ,oBAAoB,aAAa,cAAc;AACvD,cAAQ,oBAAoB,iBAAiB,cAAc;AAC3D,cAAQ,oBAAoB,SAAS,OAAO;AAC5C,oBAAc;AAAA,IAChB;AAAA,EACF,GAAG,CAAC,SAAS,aAAa,SAAS,EAAE,CAAC;AAEtC,SAAO;AACT;;;ACvNA,IAAAE,gBAUO;AAmXD,IAAAC,sBAAA;AAtWN,IAAM,oBAAoB;AAC1B,IAAM,oBAAoB;AAGnB,IAAM,2CAA2C;AAoIjD,IAAM,oCACX,6BAA4C,IAAI;AAElD,IAAM,qBAmBF;AAAA,EACF,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,UAAU;AAAA,EACV,UAAU;AAAA,EACV,SAAS;AAAA,EACT,UAAU;AAAA,EACV,aAAa;AAAA,EACb,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,iBAAiB;AACnB;AAEA,SAAS,uBAAuB,OAAmC;AACjE,MAAI,CAAC,OAAO,SAAS,KAAK,GAAG;AAC3B,WAAO,mBAAmB;AAAA,EAC5B;AACA,SAAO,KAAK;AAAA,IACV;AAAA,IACA,KAAK,IAAI,0CAA0C,KAAM;AAAA,EAC3D;AACF;AAEA,SAAS,aACP,MACmC;AACnC,SAAO,KAAK,SAAS;AACvB;AAEA,SAAS,wBAAwB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GASG;AACD,QAAM,cAAU,sBAAuB,IAAI;AAC3C,QAAM,CAAC,aAAa,cAAc,QAAI,wBAAS,CAAC;AAChD,QAAM,WAAW,EAAE,GAAG,oBAAoB,GAAG,WAAW;AACxD,QAAM,WAAW,OAAO,SAAS,SAAS,QAAQ,IAC9C,KAAK,IAAI,GAAG,SAAS,QAAS,IAC9B;AAEJ,QAAM,mBAAe;AAAA,IACnB,MACE,MAAM,OAAO,CAAC,SAAS;AACrB,UAAI,CAAC,aAAa,IAAI,GAAG;AACvB,eAAO;AAAA,MACT;AACA,aAAO,CAAC,KAAK;AAAA,IACf,CAAC;AAAA,IACH,CAAC,KAAK;AAAA,EACR;AAEA,QAAM,uBAAmB,uBAAQ,MAAM;AACrC,UAAM,UAAoB,CAAC;AAC3B,iBAAa,QAAQ,CAAC,MAAM,UAAU;AACpC,UAAI,aAAa,IAAI,KAAK,CAAC,KAAK,UAAU;AACxC,gBAAQ,KAAK,KAAK;AAAA,MACpB;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT,GAAG,CAAC,YAAY,CAAC;AAEjB,+BAAU,MAAM;AACd,UAAM,QAAQ,iBAAiB,CAAC;AAChC,mBAAe,SAAS,CAAC;AACzB,UAAM,QAAQ,sBAAsB,MAAM;AACxC,YAAM,UAAU,QAAQ,SAAS;AAAA,QAC/B;AAAA,MACF;AACA,gBAAU,CAAC,GAAG,MAAM;AAAA,IACtB,CAAC;AACD,WAAO,MAAM,qBAAqB,KAAK;AAAA,EACzC,GAAG,CAAC,gBAAgB,CAAC;AAErB,QAAM,mBAAe;AAAA,IACnB,CAAC,SAAoC;AACnC,UAAI,KAAK,UAAU;AACjB;AAAA,MACF;AACA,WAAK,SAAS,aAAa;AAC3B,qBAAe;AAAA,IACjB;AAAA,IACA,CAAC,gBAAgB,aAAa;AAAA,EAChC;AAEA,QAAM,YAAY,CAAC,cAAsB;AACvC,QAAI,iBAAiB,WAAW,GAAG;AACjC;AAAA,IACF;AACA,UAAM,cAAc,iBAAiB,QAAQ,WAAW;AACxD,UAAM,WACJ,gBAAgB,KACZ,KACC,cAAc,YAAY,iBAAiB,UAC5C,iBAAiB;AACvB,UAAM,YAAY,iBAAiB,QAAQ;AAC3C,mBAAe,SAAS;AACxB,UAAM,UAAU,QAAQ,SAAS;AAAA,MAC/B;AAAA,IACF;AACA,cAAU,SAAS,GAAG,MAAM;AAAA,EAC9B;AAEA,QAAM,gBAAgB,CAAC,UAA8C;AACnE,YAAQ,MAAM,KAAK;AAAA,MACjB,KAAK;AACH,cAAM,eAAe;AACrB,kBAAU,CAAC;AACX;AAAA,MACF,KAAK;AACH,cAAM,eAAe;AACrB,kBAAU,EAAE;AACZ;AAAA,MACF,KAAK,QAAQ;AACX,cAAM,eAAe;AACrB,cAAM,QAAQ,iBAAiB,CAAC;AAChC,YAAI,UAAU,QAAW;AACvB,yBAAe,KAAK;AACpB,gBAAM,UAAU,QAAQ,SAAS;AAAA,YAC/B;AAAA,UACF;AACA,oBAAU,KAAK,GAAG,MAAM;AAAA,QAC1B;AACA;AAAA,MACF;AAAA,MACA,KAAK,OAAO;AACV,cAAM,eAAe;AACrB,cAAM,OAAO,iBAAiB,iBAAiB,SAAS,CAAC;AACzD,YAAI,SAAS,QAAW;AACtB,yBAAe,IAAI;AACnB,gBAAM,UAAU,QAAQ,SAAS;AAAA,YAC/B;AAAA,UACF;AACA,oBAAU,IAAI,GAAG,MAAM;AAAA,QACzB;AACA;AAAA,MACF;AAAA,MACA,KAAK;AACH,cAAM,eAAe;AACrB,uBAAe;AACf;AAAA,MACF,KAAK;AAAA,MACL,KAAK,KAAK;AACR,cAAM,eAAe;AACrB,cAAM,OAAO,aAAa,WAAW;AACrC,YAAI,QAAQ,aAAa,IAAI,GAAG;AAC9B,uBAAa,IAAI;AAAA,QACnB;AACA;AAAA,MACF;AAAA,MACA,SAAS;AACP;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,oBAAoB,uBAAuB,SAAS,OAAO;AACjE,QAAM,aAA4B;AAAA,IAChC,OAAO,SAAS;AAAA,IAChB,QAAQ,SAAS;AAAA,IACjB,cAAc,SAAS;AAAA,IACvB,WAAW,SAAS;AAAA,IACpB,UAAU,SAAS;AAAA,IACnB,UAAU,SAAS;AAAA,IACnB,SAAS,SAAS;AAAA,IAClB,eAAe;AAAA,IACf,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,GAAG;AAAA,EACL;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,cAAW;AAAA,MACX;AAAA,MACA,WAAW;AAAA,MACX,MAAK;AAAA,MACL,OAAO;AAAA,MACP,UAAU;AAAA,MAEV;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,eAAW;AAAA,YACX,OAAO;AAAA,cACL,YAAY,SAAS;AAAA,cACrB,cAAc,SAAS;AAAA,cACvB,OAAO;AAAA,cACP,SAAS;AAAA,cACT,eAAe;AAAA,cACf,UAAU;AAAA,cACV,QAAQ;AAAA,YACV;AAAA;AAAA,QACF;AAAA,QACA,6CAAC,SAAI,OAAO,EAAE,UAAU,YAAY,QAAQ,EAAE,GAC7C,uBAAa,IAAI,CAAC,MAAM,UAAU;AACjC,cAAI,CAAC,aAAa,IAAI,GAAG;AACvB,mBACE;AAAA,cAAC;AAAA;AAAA,gBACC,eAAW;AAAA,gBACX,WAAW,CAAC,oBAAoB,KAAK,SAAS,EAC3C,OAAO,OAAO,EACd,KAAK,GAAG,KAAK;AAAA,gBAEhB,MAAK;AAAA,gBACL,OAAO;AAAA,kBACL,YAAY,SAAS;AAAA,kBACrB,QAAQ;AAAA,kBACR,QAAQ,SAAS;AAAA,kBACjB,GAAG,KAAK;AAAA,gBACV;AAAA;AAAA,cAPK,KAAK,MAAM,aAAa,KAAK;AAAA,YAQpC;AAAA,UAEJ;AAEA,gBAAM,WAAW,KAAK,aAAa;AACnC,gBAAM,WAAW,KAAK,SACpB,KAAK,QACH;AAAA,YAAC;AAAA;AAAA,cACC,KAAK,KAAK,YAAY;AAAA,cACtB,WAAW;AAAA,cACX,KAAK,KAAK;AAAA,cACV,OAAO;AAAA,gBACL,SAAS;AAAA,gBACT,QAAQ;AAAA,gBACR,WAAW;AAAA,gBACX,OAAO;AAAA,cACT;AAAA;AAAA,UACF,IACE;AAGN,iBACE;AAAA,YAAC;AAAA;AAAA,cACC,iBAAe,YAAY;AAAA,cAC3B,WAAW,CAAC,eAAe,KAAK,SAAS,EACtC,OAAO,OAAO,EACd,KAAK,GAAG,KAAK;AAAA,cAChB;AAAA,cAEA,SAAS,CAAC,UAA8C;AACtD,sBAAM,eAAe;AACrB,sBAAM,gBAAgB;AACtB,6BAAa,IAAI;AAAA,cACnB;AAAA,cACA,cAAc,CAAC,UAAU;AACvB,oBAAI,CAAC,UAAU;AACb,iCAAe,KAAK;AACpB,wBAAM,cAAc,MAAM;AAAA,gBAC5B;AAAA,cACF;AAAA,cACA,MAAK;AAAA,cACL,OAAO;AAAA,gBACL,YAAY;AAAA,gBACZ,YACE,CAAC,YAAY,gBAAgB,QACzB,SAAS,sBACT;AAAA,gBACN,QAAQ;AAAA,gBACR,cAAc;AAAA,gBACd,OAAO,WAAW,SAAS,oBAAoB;AAAA,gBAC/C,QAAQ,WAAW,YAAY;AAAA,gBAC/B,SAAS;AAAA,gBACT,MAAM;AAAA,gBACN,KAAK;AAAA,gBACL,SAAS,SAAS;AAAA,gBAClB,WAAW;AAAA,gBACX,OAAO;AAAA,gBACP,GAAG,KAAK;AAAA,cACV;AAAA,cACA,UAAU,WAAW,KAAK,gBAAgB,QAAQ,IAAI;AAAA,cACtD,MAAK;AAAA,cAEL;AAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,eAAW;AAAA,oBACX,OAAO;AAAA,sBACL,YAAY;AAAA,sBACZ,SAAS;AAAA,sBACT,YAAY;AAAA,sBACZ,QAAQ;AAAA,sBACR,gBAAgB;AAAA,sBAChB,OAAO;AAAA,oBACT;AAAA,oBAEC;AAAA;AAAA,gBACH;AAAA,gBACA,6CAAC,UAAK,OAAO,EAAE,MAAM,EAAE,GAAI,eAAK,OAAM;AAAA;AAAA;AAAA,YA/CjC,KAAK;AAAA,UAgDZ;AAAA,QAEJ,CAAC,GACD;AAAA;AAAA;AAAA,EACF;AAEJ;AAEA,SAAS,oBAAoB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,QAAM,eAAW,sBAAuB,IAAI;AAC5C,QAAM,CAAC,QAAQ,SAAS,QAAI,wBAAS,EAAE,MAAM,GAAG,KAAK,EAAE,CAAC;AAExD,qCAAgB,MAAM;AACpB,UAAM,QAAQ,SAAS;AACvB,QAAI,CAAC,kBAAkB,CAAC,OAAO;AAC7B;AAAA,IACF;AAEA,UAAM,cAAc,eAAe,sBAAsB;AACzD,UAAM,WAAW,MAAM,sBAAsB;AAC7C,UAAM,UAAU,UAAU,YAAY;AACtC,UAAM,SAAS,UAAU,YAAY;AACrC,UAAM,UAAU,KAAK;AAAA,MACnB;AAAA,MACA,YAAY,QAAQ,SAAS,QAAQ;AAAA,IACvC;AACA,UAAM,SAAS,KAAK;AAAA,MAClB;AAAA,MACA,YAAY,SAAS,SAAS,SAAS;AAAA,IACzC;AAEA,cAAU;AAAA,MACR,MAAM,KAAK,IAAI,KAAK,IAAI,SAAS,iBAAiB,GAAG,OAAO;AAAA,MAC5D,KAAK,KAAK,IAAI,KAAK,IAAI,QAAQ,iBAAiB,GAAG,MAAM;AAAA,IAC3D,CAAC;AAAA,EACH,GAAG,CAAC,SAAS,SAAS,gBAAgB,QAAQ,CAAC;AAE/C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,OAAO;AAAA,QACL,MAAM,OAAO;AAAA,QACb,UAAU;AAAA,QACV,KAAK,OAAO;AAAA,QACZ,QAAQ;AAAA,MACV;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;AAOO,SAAS,4BAGd;AACA,QAAM,CAAC,SAAS,UAAU,QAAI,wBAAoC,IAAI;AACtE,QAAM,iBAAa,sBAAuB,IAAI;AAC9C,QAAM,CAAC,gBAAgB,iBAAiB,QAAI;AAAA,IAC1C;AAAA,EACF;AACA,QAAM,UAAM;AAAA,IACV,OAAO,EAAE,YAAY,WAAW;AAAA,IAChC,CAAC;AAAA,EACH;AAEA,QAAM,qBAAiB,2BAAY,CAAC,SAAgC;AAClE,eAAW,UAAU;AACrB,sBAAkB,IAAI;AAAA,EACxB,GAAG,CAAC,CAAC;AAEL,+BAAU,MAAM;AACd,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AAEA,UAAM,oBAAoB,CAAC,UAAwB;AACjD,YAAMC,WAAU,WAAW;AAC3B,UAAI,CAACA,UAAS;AACZ;AAAA,MACF;AACA,YAAM,SAAS,MAAM;AACrB,UAAI,kBAAkB,QAAQA,SAAQ,SAAS,MAAM,GAAG;AACtD,cAAM,WAAWA,SAAQ;AAAA,UACvB;AAAA,QACF;AACA,YAAI,YAAY,SAAS,SAAS,MAAM,GAAG;AACzC;AAAA,QACF;AAAA,MACF;AACA,iBAAW,IAAI;AAAA,IACjB;AAEA,UAAM,gBAAgB,CAAC,UAAyB;AAC9C,UAAI,MAAM,QAAQ,UAAU;AAC1B,mBAAW,IAAI;AAAA,MACjB;AAAA,IACF;AAEA,aAAS,iBAAiB,eAAe,mBAAmB,IAAI;AAChE,aAAS,iBAAiB,WAAW,aAAa;AAClD,WAAO,MAAM;AACX,eAAS,oBAAoB,eAAe,mBAAmB,IAAI;AACnE,eAAS,oBAAoB,WAAW,aAAa;AAAA,IACvD;AAAA,EACF,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,UACJ;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,eAAa,UAAU,SAAY;AAAA,MACnC,OAAO;AAAA,QACL,OAAO;AAAA,QACP,eAAe;AAAA,QACf,UAAU;AAAA,QACV,QAAQ;AAAA,MACV;AAAA,MAEC,oBACC;AAAA,QAAC;AAAA;AAAA,UACC,SAAS,QAAQ,MAAM;AAAA,UACvB,SAAS,QAAQ,MAAM;AAAA,UAEvB;AAAA,UAEC,kBAAQ,OAAO;AAAA;AAAA,QAHX,QAAQ;AAAA,MAIf,IACE;AAAA;AAAA,EACN;AAGF,SAAO,EAAE,KAAK,QAAQ;AACxB;AAOO,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA+B;AAC7B,QAAM,eAAW,0BAAW,mBAAmB;AAC/C,QAAM,kBAAc,0BAAW,mBAAmB;AAClD,QAAM,iBAAa,0BAAW,6BAA6B;AAC3D,QAAM,cAAU,0BAAW,6BAA6B;AACxD,QAAM,iBAAa,qBAAM;AACzB,QAAM,oBAAgB,sBAAO,CAAC;AAC9B,QAAM,eAAW,sBAAO;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,WAAS,UAAU;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,CAAC,YAAY,CAAC,aAAa;AAC7B,UAAM,IAAI,MAAM,uDAAuD;AAAA,EACzE;AACA,MAAI,CAAC,YAAY;AACf,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,YAAQ,2BAAY,MAAM;AAC9B,eAAW,WAAW,IAAI;AAAA,EAC5B,GAAG,CAAC,UAAU,CAAC;AAEf,QAAM,eAAW;AAAA,IACf,CAAC,UAAgC;AAC/B,YAAM,YAAY,eAAe;AACjC,YAAM,OAAO,YAAY,SAAS,QAAQ,KAAK;AAAA,QAC7C,KAAK;AAAA,QACL,OAAO;AAAA,QACP,KAAK;AAAA,MACP;AACA,YAAM,gBAA8C;AAAA,QAClD,UAAU,MAAM;AAAA,QAChB;AAAA,QACA,aAAa,MAAM;AAAA,QACnB;AAAA,MACF;AACA,YAAM,UAAU,SAAS;AACzB,oBAAc,WAAW;AACzB,YAAM,MAAM,GAAG,UAAU,IAAI,cAAc,OAAO;AAElD,YAAM,oBAAoB,OAAO,QAAQ,aAAa;AACtD,YAAM,UAAU,UACZ,6BAA6B,OAAO,IACpC;AACJ,YAAM,gBAAgB,UAClB,4BAA4B,SAAS,OAAO,IAC5C,QAAQ,OAAO,OAAO,aAAa,KAAK,CAAC;AAE7C,UAAI,CAAC,qBAAqB,cAAc,WAAW,GAAG;AACpD;AAAA,MACF;AAEA,iBAAW,WAAW;AAAA,QACpB;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ,MAAM;AACZ,cAAI,qBAAqB,QAAQ,UAAU;AACzC,mBACE,6CAAC,SAAI,0BAAsB,MAAC,OAAO,EAAE,eAAe,OAAO,GACxD,kBAAQ,SAAS,EAAE,OAAO,MAAM,MAAM,CAAC,GAC1C;AAAA,UAEJ;AACA,iBACE;AAAA,YAAC;AAAA;AAAA,cACC,YAAY,QAAQ;AAAA,cACpB,WAAW,QAAQ;AAAA,cACnB,eAAe,QAAQ;AAAA,cACvB,OAAO;AAAA,cACP,gBAAgB;AAAA,cAChB;AAAA,cACA,oBAAoB,QAAQ;AAAA,cAC5B,OAAO,QAAQ;AAAA;AAAA,UACjB;AAAA,QAEJ;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,CAAC,SAAS,OAAO,aAAa,YAAY,UAAU;AAAA,EACtD;AAEA,+BAAU,MAAM;AACd,UAAM,yBAAyB,SAAS;AAAA,MACtC;AAAA,MACA;AAAA,IACF;AACA,UAAM,yBAAyB,SAAS;AAAA,MACtC;AAAA,MACA,MAAM;AACJ,cAAM;AAAA,MACR;AAAA,IACF;AACA,WAAO,MAAM;AACX,6BAAuB;AACvB,6BAAuB;AACvB,YAAM;AAAA,IACR;AAAA,EACF,GAAG,CAAC,OAAO,UAAU,QAAQ,CAAC;AAE9B,SAAO;AACT;AAEA,SAAS,gBAAgB;AACvB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAW;AAAA,MACX,MAAK;AAAA,MACL,QAAO;AAAA,MACP,QAAO;AAAA,MACP,eAAc;AAAA,MACd,gBAAe;AAAA,MACf,aAAY;AAAA,MACZ,SAAQ;AAAA,MACR,OAAM;AAAA,MAEN;AAAA,qDAAC,UAAK,GAAE,+BAA8B;AAAA,QACtC,6CAAC,UAAK,GAAE,gBAAe;AAAA;AAAA;AAAA,EACzB;AAEJ;AAEA,SAAS,iBAAiB;AACxB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAW;AAAA,MACX,MAAK;AAAA,MACL,QAAO;AAAA,MACP,QAAO;AAAA,MACP,eAAc;AAAA,MACd,gBAAe;AAAA,MACf,aAAY;AAAA,MACZ,SAAQ;AAAA,MACR,OAAM;AAAA,MAEN,uDAAC,UAAK,GAAE,0CAAyC;AAAA;AAAA,EACnD;AAEJ;AAEA,SAAS,qBAAqB;AAC5B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAW;AAAA,MACX,MAAK;AAAA,MACL,QAAO;AAAA,MACP,QAAO;AAAA,MACP,eAAc;AAAA,MACd,gBAAe;AAAA,MACf,aAAY;AAAA,MACZ,SAAQ;AAAA,MACR,OAAM;AAAA,MAEN,uDAAC,UAAK,GAAE,wCAAuC;AAAA;AAAA,EACjD;AAEJ;AAsBO,SAAS,6BACd,SACwB;AACxB,QAAM,eAAe,QAAQ,iBAAiB;AAC9C,QAAM,YAAuC;AAAA,IAC3C,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,MAAM,6CAAC,iBAAc;AAAA,IACrB,UAAU,MAAM;AACd,cAAQ,MAAM;AAAA,IAChB;AAAA,EACF;AACA,QAAM,aAAwC;AAAA,IAC5C,IAAI;AAAA,IACJ,OAAO,eAAe,oBAAoB;AAAA,IAC1C,MAAM,eAAe,6CAAC,sBAAmB,IAAK,6CAAC,kBAAe;AAAA,IAC9D,UAAU,MAAM;AACd,cAAQ,iBAAiB;AAAA,IAC3B;AAAA,EACF;AACA,QAAM,YAAY,CAAC,KAAK,sBAAoD;AAAA,IAC1E,MAAM;AAAA,IACN;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU,CAAC,WAAW,UAAU,wBAAwB,GAAG,UAAU;AAAA,EACvE;AACF;AAGO,SAAS,kCACd,SACuB;AACvB,SAAO,6BAA6B,OAAO,EAAE;AAC/C;AAEA,SAAS,WAAW,OAAkD;AACpE,SACE,UAAU,eAAe,UAAU,gBAAgB,UAAU;AAEjE;AAEA,SAAS,YAAY,OAAmD;AACtE,SACE,OAAO,UAAU,YACjB,UAAU,QACV,YAAY,SACZ,WAAY,MAAmC,MAAM;AAEzD;AAEA,SAAS,cACP,OACoC;AACpC,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AACA,MAAI,YAAY,KAAK,GAAG;AACtB,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,qBACP,MACA,WACqB;AACrB,MAAI,KAAK,SAAS,aAAa;AAC7B,WAAO;AAAA,MACL,GAAG;AAAA,MACH,IAAI,UAAU,MAAM,KAAK;AAAA,MACzB,WAAW,UAAU,aAAa,KAAK;AAAA,MACvC,OAAO,UAAU,SAAS,KAAK;AAAA,IACjC;AAAA,EACF;AACA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,IAAI,UAAU,MAAM,KAAK;AAAA,IACzB,OAAO,UAAU,SAAS,KAAK;AAAA,IAC/B,WAAW,UAAU,aAAa,KAAK;AAAA,IACvC,OAAO,UAAU,SAAS,KAAK;AAAA,IAC/B,UAAU,UAAU,YAAY,KAAK;AAAA,IACrC,QAAQ,UAAU,UAAU,KAAK;AAAA,EACnC;AACF;AAEA,SAAS,mBACP,OACA,SACqB;AACrB,QAAM,WAAW,OAAO,UAAU,WAAW,QAAQ,MAAM;AAC3D,QAAM,YACJ,OAAO,UAAU,WAAW,CAAC,IAAI;AACnC,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAO,qBAAqB,QAAQ,WAAW,SAAS;AAAA,IAC1D,KAAK;AACH,aAAO,qBAAqB,QAAQ,YAAY,SAAS;AAAA,IAC3D,KAAK;AACH,aAAO;AAAA,QACL,QAAQ,UAAU,UAAU,MAAM,gBAAgB;AAAA,QAClD;AAAA,MACF;AAAA,IACF,SAAS;AACP,YAAM,cAAqB;AAC3B,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAKO,SAAS,8BACd,SACA,SACuB;AACvB,QAAM,WAAkC,CAAC;AACzC,aAAW,SAAS,SAAS;AAC3B,QAAI,cAAc,KAAK,GAAG;AACxB,eAAS,KAAK,KAAK;AACnB;AAAA,IACF;AACA,aAAS,KAAK,mBAAmB,OAAO,OAAO,CAAC;AAAA,EAClD;AACA,SAAO;AACT;AAKO,SAAS,4BACd,OACA,SACuB;AACvB,MAAI,MAAM,OAAO;AACf,WAAO,8BAA8B,MAAM,OAAO,OAAO;AAAA,EAC3D;AACA,SAAO;AAAA,IACL,GAAG,8BAA8B,MAAM,WAAW,CAAC,GAAG,OAAO;AAAA,IAC7D,GAAG,QAAQ;AAAA,IACX,GAAG,8BAA8B,MAAM,UAAU,CAAC,GAAG,OAAO;AAAA,EAC9D;AACF;AAIO,IAAM,oCACX,6BAAgD,IAAI;;;ACz+BtD,IAAAC,gBAAmC;AACnC,IAAAC,gBAA8C;AAW9C,IAAM,uBAAuB;AA6B7B,SAAS,gBAAgB,OAAmC;AAC1D,SAAO,OAAO,SAAS,KAAK,KAAK,SAAU,IAAI,QAAS;AAC1D;AAMO,SAAS,cAAc;AAAA,EAC5B,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA0B;AACxB,QAAM,eAAW,0BAAW,mBAAmB;AAC/C,QAAM,kBAAc,0BAAW,mBAAmB;AAClD,QAAM,EAAE,GAAG,QAAI,wBAAS;AAExB,MAAI,CAAC,YAAY,CAAC,aAAa;AAC7B,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACjE;AAEA,QAAM,mBAAe,sBAAO;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,eAAa,UAAU;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,qBAAiB,sBAAO,CAAC;AAC/B,QAAM,gBAAY,sBAAO,KAAK;AAC9B,QAAM,kBAAc,sBAAO,gBAAgB,QAAQ,CAAC;AACpD,cAAY,UAAU,gBAAgB,QAAQ;AAE9C,+BAAU,MAAM;AACd,mBAAe,UAAU;AACzB,cAAU,UAAU;AAAA,EACtB,GAAG,CAAC,QAAQ,CAAC;AAEb,+BAAU,MAAM;AACd,UAAM,gBAAgB;AAAA,MACpB,SAAS,UAAU,cAAc,CAAC,SAAS;AACzC,qBAAa,QAAQ,eAAe,IAAI;AAAA,MAC1C,CAAC;AAAA,MACD,SAAS,UAAU,eAAe,CAAC,SAAS;AAC1C,qBAAa,QAAQ,gBAAgB,IAAI;AAAA,MAC3C,CAAC;AAAA,MACD,SAAS,UAAU,wBAAwB,CAAC,UAAU;AACpD,qBAAa,QAAQ,yBAAyB,KAAK;AAAA,MACrD,CAAC;AAAA,MACD,SAAS,UAAU,sBAAsB,CAAC,UAAU;AAClD,qBAAa,QAAQ,uBAAuB,KAAK;AAAA,MACnD,CAAC;AAAA,MACD,SAAS,UAAU,SAAS,CAAC,UAAU;AACrC,qBAAa,QAAQ,UAAU,KAAK;AAAA,MACtC,CAAC;AAAA,MACD,SAAS,UAAU,eAAe,CAAC,UAAU;AAC3C,qBAAa,QAAQ,gBAAgB,KAAK;AAAA,MAC5C,CAAC;AAAA,MACD,SAAS,UAAU,eAAe,CAAC,UAAU;AAC3C,qBAAa,QAAQ,gBAAgB,KAAK;AAAA,MAC5C,CAAC;AAAA,MACD,SAAS,UAAU,aAAa,CAAC,UAAU;AACzC,qBAAa,QAAQ,cAAc,KAAK;AAAA,MAC1C,CAAC;AAAA,MACD,SAAS,UAAU,eAAe,CAAC,UAAU;AAC3C,qBAAa,QAAQ,gBAAgB,KAAK;AAAA,MAC5C,CAAC;AAAA,MACD,SAAS,UAAU,eAAe,CAAC,UAAU;AAC3C,qBAAa,QAAQ,gBAAgB,KAAK;AAAA,MAC5C,CAAC;AAAA,MACD,SAAS,UAAU,mBAAmB,MAAM;AAC1C,qBAAa,QAAQ,oBAAoB;AAAA,MAC3C,CAAC;AAAA,MACD,SAAS,UAAU,kBAAkB,MAAM;AACzC,qBAAa,QAAQ,mBAAmB;AAAA,MAC1C,CAAC;AAAA,MACD,SAAS,UAAU,sBAAsB,MAAM;AAC7C,qBAAa,QAAQ,uBAAuB;AAAA,MAC9C,CAAC;AAAA,IACH;AACA,WAAO,MAAM;AACX,iBAAW,eAAe,eAAe;AACvC,oBAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,CAAC;AAEb,+BAAU,MAAM;AACd,UAAM,UAAU,GAAG;AAEnB,UAAM,cAAc,CAAC,gBAA4B;AAC/C,mBAAa,QAAQ,UAAU;AAAA,QAC7B,OAAO,YAAY;AAAA,QACnB;AAAA,MACF,CAAC;AAAA,IACH;AAEA,YAAQ,iBAAiB,SAAS,aAAa,EAAE,SAAS,KAAK,CAAC;AAChE,WAAO,MAAM;AACX,cAAQ,oBAAoB,SAAS,WAAW;AAAA,IAClD;AAAA,EACF,GAAG,CAAC,EAAE,CAAC;AAEP,+BAAU,MAAM;AACd,QAAI,OAAO,aAAa,aAAa;AACnC;AAAA,IACF;AAEA,UAAM,mBAAmB,EAAE,SAAS,MAAM;AAE1C,UAAM,qBAAqB,MAAM;AAC/B,YAAM,oBAAoB,SAAS;AACnC,UAAI,CAAC,mBAAmB;AACtB,eAAO;AAAA,MACT;AACA,YAAM,SAAS,GAAG;AAClB,aACE,sBAAsB,UACtB,kBAAkB,SAAS,MAAM,KACjC,OAAO,SAAS,iBAAiB;AAAA,IAErC;AAEA,UAAM,yBAAyB,MAAM;AACnC,YAAM,SAAS,mBAAmB;AAClC,UAAI,UAAU,CAAC,iBAAiB,SAAS;AACvC,yBAAiB,UAAU;AAC3B,qBAAa,QAAQ,oBAAoB;AAAA,MAC3C,WAAW,CAAC,UAAU,iBAAiB,SAAS;AAC9C,yBAAiB,UAAU;AAC3B,qBAAa,QAAQ,mBAAmB;AAAA,MAC1C;AAAA,IACF;AAEA,qBAAiB,UAAU,mBAAmB;AAC9C,aAAS,iBAAiB,oBAAoB,sBAAsB;AACpE,WAAO,MAAM;AACX,eAAS,oBAAoB,oBAAoB,sBAAsB;AAAA,IACzE;AAAA,EACF,GAAG,CAAC,EAAE,CAAC;AAEP,+BAAU,MAAM;AACd,UAAM,UAAU,GAAG;AACnB,QAAI,OAAO,mBAAmB,aAAa;AACzC;AAAA,IACF;AAEA,UAAM,WAAW,IAAI,eAAe,CAAC,YAAY;AAC/C,YAAM,QAAQ,QAAQ,CAAC;AACvB,UAAI,CAAC,OAAO;AACV;AAAA,MACF;AACA,YAAM,EAAE,OAAO,OAAO,IAAI,MAAM;AAChC,mBAAa,QAAQ,WAAW,EAAE,OAAO,OAAO,CAAC;AAAA,IACnD,CAAC;AACD,aAAS,QAAQ,OAAO;AACxB,WAAO,MAAM;AACX,eAAS,WAAW;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,EAAE,CAAC;AAEP,8BAAS,CAAC,GAAG,iBAAiB;AAC5B,UAAM,cAAc,YAAY,SAAS,kBAAkB,KAAK;AAChE,QAAI,aAAa;AACf,qBAAe,UAAU;AACzB,UAAI,UAAU,SAAS;AACrB,kBAAU,UAAU;AACpB,qBAAa,QAAQ,YAAY;AAAA,MACnC;AACA;AAAA,IACF;AAEA,mBAAe,WAAW,eAAe;AACzC,QACE,CAAC,UAAU,WACX,eAAe,WAAW,YAAY,SACtC;AACA,gBAAU,UAAU;AACpB,mBAAa,QAAQ,SAAS;AAAA,IAChC;AAAA,EACF,CAAC;AACH;AAMO,SAAS,WAAW,OAAwB;AACjD,gBAAc,KAAK;AACnB,SAAO;AACT;;;AC3RA,IAAAC,gBAAyB;AACzB,IAAAC,gBAAsC;AACtC,IAAAC,gBAAsD;;;ACHtD,IAAAC,gBAAmC;;;ACA5B,IAAM,oBAAoB;;;ADIjC,IAAM,uBAAuB;AAEtB,SAAS,iBAAiB,KAAqB;AACpD,MAAI,CAAC,OAAO,SAAS,GAAG,GAAG;AACzB,WAAO;AAAA,EACT;AACA,SAAO,wBAAU,gBAAgB,MAAM,KAAK,GAAG,IAAI;AACrD;AAEO,SAAS,eAAe,OAAuB;AACpD,MAAI,CAAC,OAAO,SAAS,KAAK,GAAG;AAC3B,WAAO;AAAA,EACT;AACA,QAAM,UAAU,wBAAU;AAAA,IACxB;AAAA,IACA,CAAC;AAAA,IACD;AAAA,EACF;AACA,SAAO,KAAK,IAAI,OAAO,KAAK,oBAAoB,uBAC5C,KAAK,KAAK,OAAO,IAAI,oBACrB;AACN;AAEO,SAAS,sBACd,UACiB;AACjB,QAAM,QAAQ,eAAe,SAAS,KAAK;AAC3C,SAAO;AAAA,IACL,KAAK,KAAK,IAAI,KAAK,MAAM,oBACrB,IACA,iBAAiB,SAAS,GAAG;AAAA,IACjC;AAAA,EACF;AACF;AAEO,SAAS,sBACd,UACA,SAAS,GACA;AACT,QAAM,aAAa,sBAAsB,QAAQ;AACjD,QAAM,aAAa,OAAO,SAAS,MAAM,IAAI,KAAK,IAAI,GAAG,MAAM,IAAI;AACnE,QAAM,MAAM,wBAAU,SAAS,WAAW,GAAG;AAC7C,QAAM,QAAQ,wBAAU,SAAS,WAAW,KAAK;AACjD,QAAM,WAAW,KAAK,IAAI,KAAK;AAE/B,SAAO,IAAI;AAAA,IACT,WAAW,KAAK,IAAI,GAAG,IAAI;AAAA,IAC3B,KAAK,IAAI,KAAK,IAAI;AAAA,IAClB,CAAC,WAAW,KAAK,IAAI,GAAG,IAAI;AAAA,EAC9B;AACF;AAEO,SAAS,sBACd,QACiB;AACjB,QAAM,SAAS,KAAK,MAAM,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AACtD,MAAI,CAAC,OAAO,SAAS,MAAM,KAAK,WAAW,GAAG;AAC5C,WAAO,EAAE,KAAK,GAAG,OAAO,EAAE;AAAA,EAC5B;AAEA,SAAO,sBAAsB;AAAA,IAC3B,KAAK,wBAAU,SAAS,KAAK,MAAM,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC;AAAA,IACvD,OAAO,wBAAU;AAAA,MACf,KAAK,KAAK,wBAAU,MAAM,OAAO,IAAI,QAAQ,IAAI,CAAC,CAAC;AAAA,IACrD;AAAA,EACF,CAAC;AACH;;;AElEO,IAAM,0BAA0B;AAEhC,IAAM,+BAA+B;AACrC,IAAM,8BAA8B,0BAA0B;;;AHoFjE,IAAAC,sBAAA;AAlFJ,IAAM,uBAAuB,0BAA0B;AAEvD,SAAS,yBACP,OACsB;AACtB,QAAM,cAAc,MAAM;AAC1B,SAAO;AAAA,IACL,UAAU,sBAAsB,MAAM,IAAI,SAAS;AAAA,IACnD;AAAA,IACA,WACE,eAAe,cAAc,YAAY,YAAY;AAAA,IACvD,QAAQ,YAAY;AAAA,IACpB,SAAS,YAAY;AAAA,IACrB,SAAS,YAAY;AAAA,IACrB,SAAS,YAAY;AAAA,EACvB;AACF;AAMO,SAAS,uBAAuB;AACrC,QAAM,eAAW,0BAAW,mBAAmB;AAC/C,QAAM,EAAE,QAAQ,GAAG,QAAI,wBAAS;AAEhC,+BAAU,MAAM;AACd,QAAI,CAAC,UAAU;AACb;AAAA,IACF;AAEA,UAAM,UAAU,GAAG;AACnB,UAAM,MAAM,IAAI,sBAAQ;AACxB,UAAM,YAAY,IAAI,wBAAU;AAChC,UAAM,YAAY,IAAI,sBAAQ;AAE9B,UAAM,oBAAoB,CAAC,gBAA4B;AACrD,YAAM,OAAO,QAAQ,sBAAsB;AAC3C,UAAI,KAAK,SAAS,KAAK,KAAK,UAAU,GAAG;AACvC;AAAA,MACF;AAEA,UAAI;AAAA,SACA,YAAY,UAAU,KAAK,QAAQ,KAAK,QAAS,IAAI;AAAA,QACvD,GAAG,YAAY,UAAU,KAAK,OAAO,KAAK,UAAU,IAAI;AAAA,MAC1D;AACA,gBAAU,cAAc,KAAK,MAAM;AACnC,gBAAU,KAAK,UAAU,IAAI,SAAS;AAEtC,eAAS,KAAK,eAAe;AAAA,QAC3B,UAAU,sBAAsB,SAAS;AAAA,QACzC;AAAA,QACA,WACE,eAAe,cACV,YAA6B,YAC9B;AAAA,QACN,QAAQ,YAAY;AAAA,QACpB,SAAS,YAAY;AAAA,QACrB,SAAS,YAAY;AAAA,QACrB,SAAS,YAAY;AAAA,MACvB,CAAC;AAAA,IACH;AAEA,YAAQ,iBAAiB,eAAe,iBAAiB;AACzD,WAAO,MAAM;AACX,cAAQ,oBAAoB,eAAe,iBAAiB;AAAA,IAC9D;AAAA,EACF,GAAG,CAAC,QAAQ,UAAU,EAAE,CAAC;AAEzB,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,CACX,MACA,UACG;AACH,UAAM,gBAAgB;AACtB,aAAS,KAAK,MAAM,yBAAyB,KAAK,CAAC;AAAA,EACrD;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAa;AAAA,MACb,SAAS,CAAC,UAAU,KAAK,SAAS,KAAK;AAAA,MACvC,eAAe,CAAC,UAAU,KAAK,eAAe,KAAK;AAAA,MACnD,eAAe,CAAC,UAAU,KAAK,eAAe,KAAK;AAAA,MACnD,aAAa,CAAC,UAAU,KAAK,aAAa,KAAK;AAAA,MAC/C,eAAe,CAAC,UAAU,KAAK,eAAe,KAAK;AAAA,MAEnD;AAAA,qDAAC,oBAAe,MAAM,CAAC,sBAAsB,IAAI,EAAE,GAAG;AAAA,QACtD;AAAA,UAAC;AAAA;AAAA,YACC,YAAY;AAAA,YACZ,WAAW;AAAA,YACX,YAAY;AAAA,YACZ,SAAS;AAAA,YACT,MAAM;AAAA,YACN,aAAW;AAAA;AAAA,QACb;AAAA;AAAA;AAAA,EACF;AAEJ;;;AI9GA,IAAAC,gBAAyB;AACzB,IAAAC,iBAA8C;AAI9C,IAAMC,wBAAuB;AAU7B,SAASC,cAAa,OAA2B,UAA0B;AACzE,SAAO,OAAO,SAAS,KAAK,KAAK,SAAU,IAAI,QAAS;AAC1D;AAEA,SAAS,gBAAgB,GAAkB,GAA0B;AACnE,SAAO,KAAK,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AACxC;AAMO,SAAS,cAAc;AAAA,EAC5B,UAAU;AAAA,EACV,cAAcD;AAAA,EACd,SAAS;AAAA,EACT,YAAY;AACd,GAAuB;AACrB,QAAM,kBAAc,2BAAW,mBAAmB;AAClD,QAAM,EAAE,GAAG,QAAI,wBAAS;AACxB,QAAM,kBAAc,uBAAO,oBAAI,IAA2B,CAAC;AAC3D,QAAM,uBAAmB,uBAAsB,IAAI;AACnD,QAAM,iBAAa,uBAAO,EAAE,aAAa,QAAQ,UAAU,CAAC;AAE5D,MAAI,CAAC,aAAa;AAChB,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACvE;AAEA,aAAW,UAAU,EAAE,aAAa,QAAQ,UAAU;AAEtD,gCAAU,MAAM;AACd,UAAM,UAAU,GAAG;AAEnB,UAAM,gBAAgB,MAAM;AAC1B,iBAAW,aAAa,YAAY,QAAQ,KAAK,GAAG;AAClD,YAAI,QAAQ,oBAAoB,SAAS,GAAG;AAC1C,kBAAQ,wBAAwB,SAAS;AAAA,QAC3C;AAAA,MACF;AACA,kBAAY,QAAQ,MAAM;AAC1B,uBAAiB,UAAU;AAC3B,kBAAY,SAAS,iBAAiB,SAAS,KAAK;AAAA,IACtD;AAEA,QAAI,CAAC,SAAS;AACZ,oBAAc;AACd;AAAA,IACF;AAEA,UAAM,aAAa,MAAM;AACvB,kBAAY,SAAS;AAAA,QACnB;AAAA,QACA,YAAY,QAAQ,OAAO;AAAA,MAC7B;AAAA,IACF;AAEA,UAAM,gBAAgB,CAAC,UAAwB;AAC7C,UAAI,MAAM,gBAAgB,SAAS;AACjC;AAAA,MACF;AACA,UAAI,YAAY,SAAS,oBAAoB,GAAG;AAC9C;AAAA,MACF;AAEA,YAAM,eAAe;AACrB,kBAAY,QAAQ,IAAI,MAAM,WAAW;AAAA,QACvC,GAAG,MAAM;AAAA,QACT,GAAG,MAAM;AAAA,QACT,IAAI,YAAY,IAAI;AAAA,MACtB,CAAC;AACD,cAAQ,oBAAoB,MAAM,SAAS;AAC3C,iBAAW;AAEX,UAAI,YAAY,QAAQ,SAAS,GAAG;AAClC,cAAM,CAAC,OAAO,MAAM,IAAI,MAAM,KAAK,YAAY,QAAQ,OAAO,CAAC;AAC/D,yBAAiB,UAAU,gBAAgB,OAAQ,MAAO;AAAA,MAC5D;AAAA,IACF;AAEA,UAAM,gBAAgB,CAAC,UAAwB;AAC7C,UAAI,MAAM,gBAAgB,SAAS;AACjC;AAAA,MACF;AACA,UAAI,YAAY,SAAS,oBAAoB,GAAG;AAC9C;AAAA,MACF;AACA,YAAM,WAAW,YAAY,QAAQ,IAAI,MAAM,SAAS;AACxD,UAAI,CAAC,UAAU;AACb;AAAA,MACF;AAEA,YAAM,eAAe;AACrB,YAAM,OAAsB;AAAA,QAC1B,GAAG,MAAM;AAAA,QACT,GAAG,MAAM;AAAA,QACT,IAAI,YAAY,IAAI;AAAA,MACtB;AACA,kBAAY,QAAQ,IAAI,MAAM,WAAW,IAAI;AAE7C,YAAM,WAAW,MAAM,KAAK,YAAY,QAAQ,OAAO,CAAC;AACxD,UAAI,SAAS,UAAU,GAAG;AACxB,YAAI,CAAC,WAAW,QAAQ,WAAW;AACjC;AAAA,QACF;AACA,cAAM,WAAW,gBAAgB,SAAS,CAAC,GAAI,SAAS,CAAC,CAAE;AAC3D,cAAM,mBAAmB,iBAAiB;AAC1C,yBAAiB,UAAU;AAC3B,YAAI,oBAAoB,WAAW,GAAG;AACpC,gBAAM,OAAO,YAAY,SAAS,cAAc;AAChD,cAAI,MAAM;AACR,kBAAM,UAAU,KAAK,OAAO,mBAAmB;AAC/C,wBAAY,SAAS;AAAA,cACnB,EAAE,KAAK,UAAU,KAAK,IAAI;AAAA,cAC1B,EAAE,gBAAgB,KAAK;AAAA,YACzB;AAAA,UACF;AAAA,QACF;AACA;AAAA,MACF;AAEA,YAAM,OAAO,QAAQ,sBAAsB;AAC3C,YAAM,QAAQC;AAAA,QACZ,WAAW,QAAQ;AAAA,QACnBD;AAAA,MACF;AACA,YAAM,OAAO,WAAW,QAAQ,SAAS,KAAK;AAC9C,YAAM,WACH,OAAO,EAAE,KAAK,IAAI,SAAS,KAAK,MAAM,QACvC,KAAK,IAAI,KAAK,OAAO,CAAC;AACxB,YAAM,aACH,QAAQ,KAAK,IAAI,SAAS,KAAK,MAAM,QACtC,KAAK,IAAI,KAAK,QAAQ,CAAC;AAEzB,kBAAY,SAAS;AAAA,QACnB,EAAE,KAAK,UAAU,OAAO,WAAW;AAAA,QACnC,EAAE,gBAAgB,KAAK;AAAA,MACzB;AAAA,IACF;AAEA,UAAM,iBAAiB,CAAC,UAAwB;AAC9C,UAAI,CAAC,YAAY,QAAQ,IAAI,MAAM,SAAS,GAAG;AAC7C;AAAA,MACF;AACA,kBAAY,QAAQ,OAAO,MAAM,SAAS;AAC1C,UAAI,QAAQ,oBAAoB,MAAM,SAAS,GAAG;AAChD,gBAAQ,wBAAwB,MAAM,SAAS;AAAA,MACjD;AACA,UAAI,YAAY,QAAQ,OAAO,GAAG;AAChC,yBAAiB,UAAU;AAAA,MAC7B;AACA,iBAAW;AAAA,IACb;AAEA,YAAQ,iBAAiB,eAAe,aAAa;AACrD,YAAQ,iBAAiB,eAAe,aAAa;AACrD,YAAQ,iBAAiB,aAAa,cAAc;AACpD,YAAQ,iBAAiB,iBAAiB,cAAc;AAExD,WAAO,MAAM;AACX,cAAQ,oBAAoB,eAAe,aAAa;AACxD,cAAQ,oBAAoB,eAAe,aAAa;AACxD,cAAQ,oBAAoB,aAAa,cAAc;AACvD,cAAQ,oBAAoB,iBAAiB,cAAc;AAC3D,oBAAc;AAAA,IAChB;AAAA,EACF,GAAG,CAAC,aAAa,SAAS,EAAE,CAAC;AAE7B,SAAO;AACT;;;Ab2LkB,IAAAE,sBAAA;AAxTlB,IAAM,eAA8B;AAAA,EAClC,KAAK;AAAA,EACL,OAAO;AAAA,EACP,KAAK;AACP;AAEA,IAAM,+BAA+B;AACrC,IAAM,2BAA2B;AAEjC,IAAM,uBAAsC;AAAA,EAC1C,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,OAAO;AACT;AA8BA,SAAS,eACP,OACA,UACiB;AACjB,MAAI,UAAU,OAAO;AACnB,WAAO,EAAE,OAAO,MAAM;AAAA,EACxB;AACA,MAAI,UAAU,QAAQ,UAAU,QAAW;AACzC,WAAO,EAAE,OAAO,MAAM,OAAO,EAAE,GAAG,SAAS,EAAE;AAAA,EAC/C;AACA,SAAO;AAAA,IACL,OAAO;AAAA,IACP,OAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAG;AAAA,MACH,SAAS,MAAM,YAAY;AAAA,IAC7B;AAAA,EACF;AACF;AAEA,SAAS,0BACP,OACoC;AACpC,MAAI,UAAU,OAAO;AACnB,WAAO,EAAE,OAAO,MAAM;AAAA,EACxB;AACA,MAAI,UAAU,QAAQ,UAAU,QAAW;AACzC,WAAO,EAAE,OAAO,MAAM,OAAO,CAAC,EAAE;AAAA,EAClC;AACA,SAAO,EAAE,OAAO,MAAM,OAAO,EAAE,GAAG,MAAM,EAAE;AAC5C;AAEO,IAAM,eAAW;AAAA,EACtB,SAASC,UACP;AAAA,IACE;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,SAAS;AAAA,IACT,WAAW;AAAA,IACX,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM,CAAC,GAAG,CAAC;AAAA,IACX;AAAA,IACA,cAAc,YAAY;AAAA,IAC1B,GAAG;AAAA,EACL,GACA,KACA;AACA,UAAM,cAAU,uBAAuB,IAAI;AAC3C,UAAM,kBAAc,uBAAkC,IAAI;AAC1D,UAAM,eAAW,wBAAQ,MAAM,mBAAmB,GAAG,CAAC,CAAC;AACvD,UAAM,EAAE,UAAU,8BAA8B,SAAS,IACvD,6BAA6B;AAC/B,UAAM,EAAE,KAAK,uBAAuB,SAAS,mBAAmB,IAC9D,0BAA0B;AAC5B,UAAM,sBAAkB,uBAAsB,YAAY;AAC1D,UAAM,mBAAmB,KAAK,IAAI,GAAG,KAAK,IAAI,QAAQ,SAAS,CAAC,CAAC;AACjE,UAAM,mBAAmB,KAAK;AAAA,MAC5B;AAAA,MACA,KAAK,IAAI,QAAQ,mBAAmB,CAAC;AAAA,IACvC;AACA,UAAM,4BAAwB;AAAA,MAC5B,OAAO;AAAA,QACL,KAAK,aAAa,OAAO,aAAa;AAAA,QACtC,OAAO,eAAe,aAAa,SAAS,aAAa,KAAK;AAAA,QAC9D,KAAK,KAAK;AAAA,UACR;AAAA,UACA,KAAK,IAAI,aAAa,OAAO,aAAa,KAAK,gBAAgB;AAAA,QACjE;AAAA,MACF;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,aAAa;AAAA,QACb,aAAa;AAAA,QACb;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,oBAAgB,UAAU;AAE1B,UAAM,kBAAkB,aAAa;AACrC,UAAM,qBAAiB;AAAA,MACrB,MAAO,OAAO,aAAa,WAAW,WAAW,CAAC;AAAA,MAClD,CAAC,QAAQ;AAAA,IACX;AACA,UAAM,sBACJ,mBAAmB,eAAe,YAAY;AAEhD,UAAM,gBAAgB,eAAe,WAAW;AAChD,UAAM,iBACJ,eAAe,eAAe;AAChC,UAAM,eAAe,eAAe,aAAa;AAEjD,UAAM,mBAAe;AAAA,MACnB,MACE,eAAqC,eAAe,OAAO;AAAA,QACzD,SAAS;AAAA,QACT,aAAa;AAAA,QACb,WAAW;AAAA,QACX,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,SAAS,CAAC,MAAM;AAAA,MAClB,CAAC;AAAA,MACH;AAAA,QACE;AAAA,QACA,eAAe;AAAA,QACf;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,UAAM,mBAAe;AAAA,MACnB,MACE,eAAqC,eAAe,OAAO;AAAA,QACzD,SAAS;AAAA,QACT,aAAa;AAAA,QACb,QAAQ;AAAA,QACR,WAAW;AAAA,MACb,CAAC;AAAA,MACH,CAAC,eAAe,eAAe,OAAO,cAAc;AAAA,IACtD;AACA,UAAM,sBAAkB;AAAA,MACtB,MACE,eAAsC,eAAe,UAAU;AAAA,QAC7D,SAAS;AAAA,MACX,CAAC;AAAA,MACH,CAAC,eAAe,QAAQ;AAAA,IAC1B;AAEA,UAAM,uBAAmB,4BAAY,YAAY;AAC/C,UAAI,OAAO,aAAa,aAAa;AACnC;AAAA,MACF;AACA,UAAI,SAAS,mBAAmB;AAC9B,cAAM,SAAS,iBAAiB;AAChC;AAAA,MACF;AACA,YAAM,QAAQ,SAAS,oBAAoB;AAAA,IAC7C,GAAG,CAAC,CAAC;AAEL,UAAM,CAAC,oBAAoB,qBAAqB,QAAI,yBAAS,KAAK;AAElE,kCAAU,MAAM;AACd,UAAI,OAAO,aAAa,aAAa;AACnC;AAAA,MACF;AAEA,YAAM,iBAAiB,MAAM;AAC3B,cAAM,oBAAoB,SAAS;AACnC,cAAM,OAAO,QAAQ;AACrB,YAAI,CAAC,qBAAqB,CAAC,MAAM;AAC/B,gCAAsB,KAAK;AAC3B;AAAA,QACF;AACA;AAAA,UACE,sBAAsB,QACpB,kBAAkB,SAAS,IAAI,KAC/B,KAAK,SAAS,iBAAiB;AAAA,QACnC;AAAA,MACF;AAEA,qBAAe;AACf,eAAS,iBAAiB,oBAAoB,cAAc;AAC5D,aAAO,MAAM;AACX,iBAAS,oBAAoB,oBAAoB,cAAc;AAAA,MACjE;AAAA,IACF,GAAG,CAAC,CAAC;AAEL,UAAM,yBAAqB;AAAA,MACzB,OAAO;AAAA,QACL,OAAO,MAAM;AACX,sBAAY,SAAS,MAAM;AAAA,QAC7B;AAAA,QACA,kBAAkB,MAAM;AACtB,eAAK,iBAAiB;AAAA,QACxB;AAAA,QACA,cAAc;AAAA,MAChB;AAAA,MACA,CAAC,oBAAoB,gBAAgB;AAAA,IACvC;AAEA,UAAM,yBAAqB;AAAA,MACzB,MAAM,0BAA0B,WAAW;AAAA,MAC3C,CAAC,WAAW;AAAA,IACd;AAIA,UAAM,0BAA0B;AAIhC,UAAM,CAAC,kBAAkB,mBAAmB,QAAI;AAAA,MAC9C,wBAAwB,cAAc;AAAA,IACxC;AAEA,kCAAU,MAAM;AACd,0BAAoB,wBAAwB,cAAc,KAAK;AAAA,IACjE,GAAG,CAAC,wBAAwB,UAAU,CAAC;AAEvC;AAAA,MACE;AAAA,MACA,OAAO;AAAA,QACL,SAAS,MACP,YAAY,SAAS,QAAQ,KAAK,EAAE,GAAG,gBAAgB,QAAQ;AAAA,QACjE,SAAS,CAAC,MAAM,YAAY;AAC1B,sBAAY,SAAS,QAAQ,MAAM,OAAO;AAAA,QAC5C;AAAA,QACA,OAAO,MAAM;AACX,sBAAY,SAAS,MAAM;AAAA,QAC7B;AAAA,QACA,iBAAiB,MAAM;AACrB,8BAAoB,IAAI;AAAA,QAC1B;AAAA,QACA,gBAAgB,MAAM;AACpB,8BAAoB,KAAK;AAAA,QAC3B;AAAA,QACA;AAAA,MACF;AAAA,MACA,CAAC,gBAAgB;AAAA,IACnB;AAEA,UAAM,gBAAY;AAAA,MAChB,OAAO;AAAA,QACL,UAAU;AAAA,QACV,UAAU;AAAA,QACV,GAAG;AAAA,MACL;AAAA,MACA,CAAC,KAAK;AAAA,IACR;AAEA,WACE;AAAA,MAAC;AAAA;AAAA,QACE,GAAG;AAAA,QACJ,KAAK;AAAA,QACL,cAAY;AAAA,QACZ,OAAO;AAAA,QAEP;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,cAAY,GAAG,SAAS;AAAA,cACxB,QAAQ;AAAA,gBACN,KAAK;AAAA,gBACL,KAAK,sBAAsB;AAAA,gBAC3B,MAAM;AAAA,gBACN,UAAU,CAAC,GAAG,GAAG,IAAI;AAAA,cACvB;AAAA,cACA;AAAA,cACA,IAAI;AAAA;AAAA;AAAA,gBAGF,WAAW;AAAA,gBACX,iBAAiB;AAAA,gBACjB,SAAS;AAAA,cACX;AAAA,cACA,OAAO;AAAA,gBACL,GAAG;AAAA,gBACH,aAAa,sBAAsB,SAAS;AAAA,cAC9C;AAAA,cACA,UAAU,sBAAsB,IAAI;AAAA,cAEpC,uDAAC,4BAA4B,UAA5B,EAAqC,OAAO,UAC3C,uDAAC,oBAAoB,UAApB,EAA6B,OAAO,UACnC,uDAAC,oBAAoB,UAApB,EAA6B,OAAO,aACnC;AAAA,gBAAC,8BAA8B;AAAA,gBAA9B;AAAA,kBACC,OAAO;AAAA,kBAEP;AAAA,oBAAC,8BAA8B;AAAA,oBAA9B;AAAA,sBACC,OAAO;AAAA,sBAET;AAAA;AAAA,0BAAC;AAAA;AAAA,4BACC,KAAK;AAAA,4BACL;AAAA,4BACA,aAAa;AAAA,4BACb,QAAQ;AAAA,4BACR,QAAQ;AAAA,4BACR,SAAS;AAAA;AAAA,wBACX;AAAA,yBACE,gBACA,mBACA,yBACA,0BACA;AAAA,0BAAC;AAAA;AAAA,4BACC;AAAA,4BACA,SAAS;AAAA,4BACT,eAAe;AAAA,4BACf,eAAe;AAAA;AAAA,wBACjB;AAAA,wBAEF;AAAA,0BAAC;AAAA;AAAA,4BACC,SAAS;AAAA,4BACT,OAAO,wBAAwB;AAAA;AAAA,wBACjC;AAAA,wBACC,uBAAuB,aAAa,QACnC;AAAA,0BAAC;AAAA;AAAA,4BACE,GAAG,aAAa;AAAA,4BACjB,UAAU,eAAe;AAAA;AAAA,wBAC3B,IACE;AAAA,wBACH,uBAAuB,aAAa,QACnC,6CAAC,iBAAe,GAAG,aAAa,OAAO,IACrC;AAAA,wBACH,uBAAuB,gBAAgB,QACtC;AAAA,0BAAC;AAAA;AAAA,4BACE,GAAG,gBAAgB;AAAA,4BACpB,UACE,gBAAgB,MAAM,YACtB,eAAe;AAAA;AAAA,wBAEnB,IACE;AAAA,wBACJ,6CAAC,wBAAqB;AAAA,wBACrB,mBAAmB,QAClB,6CAAC,mBAAiB,GAAG,mBAAmB,OAAO,IAC7C;AAAA,wBACH;AAAA;AAAA;AAAA,kBACD;AAAA;AAAA,cACF,GACF,GACF,GACF;AAAA;AAAA,UACF;AAAA,UACC;AAAA,UACA;AAAA;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;;;Ac9aA,IAAAC,gBAAyB;AACzB,IAAAC,iBAA4C;AAC5C,IAAAC,gBASO;AA6EH,IAAAC,sBAAA;AAhEG,SAAS,OAAO;AAAA,EACrB;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA,UAAU;AACZ,GAAgB;AACd,QAAM,SAAK,wBAAS,CAAC,UAAU,MAAM,EAAE;AACvC,QAAM,CAAC,SAAS,UAAU,QAAI,yBAAyB,IAAI;AAC3D,QAAM,gBAAY,uBAAO,MAAM;AAC/B,QAAM,iBAAa,uBAAO,OAAO;AACjC,YAAU,UAAU;AACpB,aAAW,UAAU;AAErB,gCAAU,MAAM;AACd,QAAI,SAAS;AACb,UAAM,SAAS,IAAI,4BAAc;AACjC,eAAW,IAAI;AAEf,WAAO;AAAA,MACL;AAAA,MACA,CAAC,kBAAkB;AACjB,YAAI,CAAC,QAAQ;AACX,wBAAc,QAAQ;AACtB;AAAA,QACF;AAEA,sBAAc,aAAa;AAC3B,sBAAc,QAAQ;AACtB,sBAAc,OAAO,IAAI;AACzB,sBAAc,OAAO,IAAI;AACzB,sBAAc,aAAa,GAAG,aAAa,iBAAiB;AAC5D,sBAAc,YAAY;AAC1B,sBAAc,YAAY;AAC1B,sBAAc,kBAAkB;AAChC,sBAAc,cAAc;AAC5B,mBAAW,aAAa;AACxB,kBAAU,UAAU,aAAa;AAAA,MACnC;AAAA,MACA;AAAA,MACA,CAAC,UAAU;AACT,YAAI,QAAQ;AACV,qBAAW,UAAU,KAAK;AAAA,QAC5B;AAAA,MACF;AAAA,IACF;AAEA,WAAO,MAAM;AACX,eAAS;AAAA,IACX;AAAA,EACF,GAAG,CAAC,IAAI,GAAG,CAAC;AAEZ;AAAA,IACE,MAAM,MAAM;AACV,eAAS,QAAQ;AAAA,IACnB;AAAA,IACA,CAAC,OAAO;AAAA,EACV;AAEA,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,UAAU,CAAC,GAAG,wBAAU,SAAS,KAAK,SAAS,GAAG,CAAC;AAAA,MACnD;AAAA,MAEA;AAAA,qDAAC,oBAAe,MAAM,CAAC,yBAAyB,KAAK,EAAE,GAAG;AAAA,QAC1D;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,MAAM;AAAA,YACN,YAAY;AAAA;AAAA,QACd;AAAA;AAAA;AAAA,EACF;AAEJ;;;ACpGA,IAAAC,iBAAmC;AACnC,IAAAC,iBAQO;AAEP,IAAAC,gBAYO;;;ACvBP,IAAAC,iBAAyB;AACzB,IAAAC,iBAKO;;;ACNP,IAAAC,gBAMO;AA6BP,IAAM,yBAA+C;AAAA,EACnD,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,OAAO;AACT;AAEO,IAAM,qBAAN,MAAyB;AAAA,EAa9B,YAAY,SAAgC;AAZ5C,SAAiB,SAAS,IAAI,4BAAc;AAC5C,SAAiB,UAAU,oBAAI,IAA0B;AACzD,SAAiB,QAAwB,CAAC;AAC1C,SAAQ,cAAc;AACtB,SAAQ,aAAa;AACrB,SAAQ,YAAY;AACpB,SAAQ,SAAS;AACjB,SAAQ,SAAS;AACjB,SAAQ,WAAW;AACnB,SAAQ,aAAa;AAInB,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,SAAS;AACP,SAAK,WAAW;AAChB,SAAK,MAAM;AAAA,EACb;AAAA,EAEA,YAAY,KAAmC;AAC7C,UAAM,QAAQ,KAAK,QAAQ,IAAI,GAAG;AAClC,WAAO,QAAQ,KAAK,SAAS,KAAK,IAAI;AAAA,EACxC;AAAA,EAEA,QACE,KACA,KACA,SACA,UACY;AACZ,QAAI,QAAQ,KAAK,QAAQ,IAAI,GAAG;AAChC,QAAI,CAAC,OAAO;AACV,cAAQ;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,OAAO;AAAA,QACP,MAAM;AAAA,QACN,WAAW,oBAAI,IAAI;AAAA,QACnB,UAAU,YAAY,IAAI;AAAA,QAC1B,OAAO;AAAA,MACT;AACA,WAAK,QAAQ,IAAI,KAAK,KAAK;AAAA,IAC7B;AAEA,UAAM,QAAQ;AACd,UAAM,WAAW,YAAY,IAAI;AACjC,UAAM,UAAU,IAAI,QAAQ;AAC5B,aAAS,KAAK,SAAS,KAAK,CAAC;AAE7B,QAAI,MAAM,WAAW,QAAQ;AAC3B,YAAM,SAAS;AACf,WAAK,MAAM,KAAK,KAAK;AACrB,WAAK,aAAa;AAClB,WAAK,aAAa;AAClB,WAAK,MAAM;AAAA,IACb;AAEA,WAAO,MAAM;AACX,YAAO,UAAU,OAAO,QAAQ;AAChC,YAAO,OAAO,KAAK,IAAI,GAAG,MAAO,OAAO,CAAC;AACzC,YAAO,WAAW,YAAY,IAAI;AAElC,UAAI,MAAO,SAAS,KAAK,MAAO,WAAW,UAAU;AACnD,cAAM,aAAa,KAAK,MAAM,QAAQ,KAAM;AAC5C,YAAI,cAAc,GAAG;AACnB,eAAK,MAAM,OAAO,YAAY,CAAC;AAAA,QACjC;AACA,cAAO,SAAS;AAChB,aAAK,QAAQ,OAAO,MAAO,GAAG;AAC9B,aAAK,YAAY,KAAK,IAAI,GAAG,KAAK,YAAY,CAAC;AAC/C,aAAK,aAAa;AAClB,aAAK,MAAM;AACX;AAAA,MACF;AAEA,WAAK,MAAM;AAAA,IACb;AAAA,EACF;AAAA,EAEA,UAAU;AACR,SAAK,WAAW;AAChB,SAAK,cAAc;AACnB,SAAK,MAAM,SAAS;AACpB,eAAW,SAAS,KAAK,QAAQ,OAAO,GAAG;AACzC,YAAM,SAAS,QAAQ;AACvB,YAAM,UAAU,MAAM;AAAA,IACxB;AACA,SAAK,QAAQ,MAAM;AACnB,SAAK,aAAa;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,gBAAgB;AACd,eAAW,SAAS,MAAM,KAAK,KAAK,QAAQ,OAAO,CAAC,GAAG;AACrD,UAAI,MAAM,OAAO,GAAG;AAClB;AAAA,MACF;AACA,YAAM,SAAS,QAAQ;AACvB,WAAK,cAAc,MAAM;AACzB,WAAK,QAAQ,OAAO,MAAM,GAAG;AAAA,IAC/B;AACA,SAAK,aAAa,KAAK,IAAI,GAAG,KAAK,UAAU;AAAA,EAC/C;AAAA,EAEQ,SAAS,OAA2C;AAC1D,WAAO;AAAA,MACL,QAAQ,MAAM;AAAA,MACd,SAAS,MAAM;AAAA,MACf,OAAO,MAAM;AAAA,IACf;AAAA,EACF;AAAA,EAEQ,OAAO,OAAqB;AAClC,UAAM,WAAW,KAAK,SAAS,KAAK;AACpC,eAAW,YAAY,MAAM,WAAW;AACtC,eAAS,QAAQ;AAAA,IACnB;AAAA,EACF;AAAA,EAEQ,eAAe;AACrB,SAAK,QAAQ,aAAa;AAAA,MACxB,WAAW,KAAK;AAAA,MAChB,QAAQ,KAAK;AAAA,MACb,QAAQ,KAAK;AAAA,MACb,QAAQ,KAAK;AAAA,MACb,QAAQ,KAAK,MAAM;AAAA,IACrB,CAAC;AAAA,EACH;AAAA,EAEQ,QAAQ;AACd,WACE,CAAC,KAAK,YACN,KAAK,cAAc,KAAK,QAAQ,eAChC,KAAK,MAAM,SAAS,GACpB;AACA,YAAM,QAAQ,KAAK,MAAM,MAAM;AAC/B,UAAI,MAAM,SAAS,GAAG;AACpB,cAAM,SAAS;AACf,aAAK,QAAQ,OAAO,MAAM,GAAG;AAC7B,aAAK,YAAY,KAAK,IAAI,GAAG,KAAK,YAAY,CAAC;AAC/C;AAAA,MACF;AACA,YAAM,SAAS;AACf,WAAK,eAAe;AACpB,WAAK,OAAO,KAAK;AACjB,WAAK,aAAa;AAClB,WAAK,KAAK,cAAc,KAAK;AAAA,IAC/B;AAAA,EACF;AAAA,EAEA,MAAc,KAAK,OAAqB,YAAoB;AAC1D,QAAI,YAAqB;AACzB,aAAS,UAAU,GAAG,WAAW,KAAK,QAAQ,YAAY,WAAW,GAAG;AACtE,UAAI;AACF,cAAM,UAAU,MAAM,KAAK,OAAO,UAAU,MAAM,GAAG;AACrD,YAAI,KAAK,YAAY,eAAe,KAAK,YAAY;AACnD,kBAAQ,QAAQ;AAChB;AAAA,QACF;AACA,aAAK,iBAAiB,OAAO;AAC7B,cAAM,UAAU;AAChB,cAAM,SAAS;AACf,cAAM,QAAQ;AACd,cAAM,QAAQ,MAAM,QAAQ,QAAQ,MAAM,QAAQ,SAAS;AAC3D,cAAM,WAAW,YAAY,IAAI;AACjC,aAAK,cAAc,MAAM;AACzB,aAAK,UAAU;AACf,aAAK,OAAO,KAAK;AACjB;AAAA,MACF,SAAS,OAAO;AACd,oBAAY;AAAA,MACd;AAAA,IACF;AAEA,QAAI,CAAC,KAAK,YAAY,eAAe,KAAK,YAAY;AACpD,YAAM,SAAS;AACf,YAAM,QAAQ;AACd,WAAK,UAAU;AACf,WAAK,OAAO,KAAK;AACjB,WAAK,QAAQ,UAAU;AAAA,QACrB,SAAS,MAAM;AAAA,QACf,KAAK,MAAM;AAAA,QACX,OAAO;AAAA,MACT,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,iBAAiB,SAAkB;AACzC,YAAQ,aAAa;AACrB,YAAQ,QAAQ;AAChB,YAAQ,QAAQ;AAChB,YAAQ,YAAY;AACpB,YAAQ,YAAY;AACpB,YAAQ,kBAAkB;AAC1B,YAAQ,aAAa,KAAK,IAAI,GAAG,KAAK,QAAQ,UAAU;AACxD,YAAQ,cAAc;AAAA,EACxB;AAAA,EAEQ,QAAQ;AACd,QAAI,KAAK,cAAc,KAAK,QAAQ,UAAU;AAC5C;AAAA,IACF;AAEA,UAAM,aAAa,MAAM,KAAK,KAAK,QAAQ,OAAO,CAAC,EAChD,OAAO,CAAC,UAAU,MAAM,SAAS,KAAK,MAAM,OAAO,EACnD,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ;AACzC,eAAW,SAAS,YAAY;AAC9B,UAAI,KAAK,cAAc,KAAK,QAAQ,UAAU;AAC5C;AAAA,MACF;AACA,YAAM,SAAS,QAAQ;AACvB,WAAK,cAAc,MAAM;AACzB,WAAK,QAAQ,OAAO,MAAM,GAAG;AAAA,IAC/B;AACA,SAAK,aAAa,KAAK,IAAI,GAAG,KAAK,UAAU;AAAA,EAC/C;AAAA,EAEQ,WAAW,YAAoB;AACrC,SAAK,cAAc,KAAK,IAAI,GAAG,KAAK,cAAc,CAAC;AACnD,QAAI,CAAC,KAAK,YAAY,eAAe,KAAK,YAAY;AACpD,WAAK,aAAa;AAClB,WAAK,MAAM;AAAA,IACb;AACA,QAAI,CAAC,KAAK,UAAU;AAClB,WAAK,MAAM;AAAA,IACb;AAAA,EACF;AAAA,EAEA,MAAc,cAAc,OAAqB;AAC/C,UAAM,aAAa,KAAK;AACxB,QAAI;AACF,YAAM,KAAK,KAAK,OAAO,UAAU;AAAA,IACnC,UAAE;AACA,WAAK,WAAW,UAAU;AAAA,IAC5B;AAAA,EACF;AACF;;;AD5OI,IAAAC,sBAAA;AAzCJ,IAAM,gCAA4B;AAAA,EAChC;AACF;AAeO,SAAS,2BAA2B;AAAA,EACzC;AAAA,EACA,qBAAqB;AAAA,EACrB,qBAAqB;AACvB,GAAoC;AAClC,QAAM,SAAK,yBAAS,CAAC,UAAU,MAAM,EAAE;AACvC,QAAM,aAAa,GAAG,aAAa,iBAAiB;AACpD,QAAM,cAAU;AAAA,IACd,MACE,IAAI,mBAAmB;AAAA,MACrB;AAAA,MACA,UAAU,KAAK,IAAI,GAAG,kBAAkB,IAAI,OAAO;AAAA,MACnD,aAAa,KAAK,IAAI,GAAG,KAAK,MAAM,kBAAkB,CAAC;AAAA,MACvD,YAAY;AAAA,IACd,CAAC;AAAA,IACH,CAAC,YAAY,oBAAoB,kBAAkB;AAAA,EACrD;AAEA,gCAAU,MAAM;AACd,YAAQ,OAAO;AACf,WAAO,MAAM,QAAQ,QAAQ;AAAA,EAC/B,GAAG,CAAC,OAAO,CAAC;AAEZ,SACE,6CAAC,0BAA0B,UAA1B,EAAmC,OAAO,SACxC,UACH;AAEJ;AAEO,SAAS,8BAA8B;AAC5C,aAAO,2BAAW,yBAAyB;AAC7C;;;AE3DA,IAAAC,iBAAmC;AACnC,IAAAC,iBAMO;AACP,IAAAC,gBAYO;;;ACpBP,IAAAC,gBAKO;AAIA,IAAM,aAA6B,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAChE,IAAM,qBAAqC,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AACxE,IAAM,cAAc;AAOpB,SAAS,iBACd,MACA,SAAS,aACM;AACf,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO,EAAE,UAAU,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,UAAU,CAAC,GAAG,GAAG,CAAC,EAAE;AAAA,IAC1D,KAAK;AACH,aAAO,EAAE,UAAU,CAAC,GAAG,GAAG,MAAM,GAAG,UAAU,CAAC,GAAG,KAAK,IAAI,CAAC,EAAE;AAAA,IAC/D,KAAK;AACH,aAAO;AAAA,QACL,UAAU,CAAC,QAAQ,GAAG,CAAC;AAAA,QACvB,UAAU,CAAC,GAAG,CAAC,KAAK,KAAK,GAAG,CAAC;AAAA,MAC/B;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,UAAU,CAAC,CAAC,QAAQ,GAAG,CAAC;AAAA,QACxB,UAAU,CAAC,GAAG,KAAK,KAAK,GAAG,CAAC;AAAA,MAC9B;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,UAAU,CAAC,GAAG,QAAQ,CAAC;AAAA,QACvB,UAAU,CAAC,KAAK,KAAK,GAAG,GAAG,CAAC;AAAA,MAC9B;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC;AAAA,QACxB,UAAU,CAAC,CAAC,KAAK,KAAK,GAAG,GAAG,CAAC;AAAA,MAC/B;AAAA,EACJ;AACF;AAEO,SAAS,mBAAmB,SAAsB,SAAS,aAAa;AAC7E,QAAM,QAAQ,QAAQ,MAAM,KAAK,QAAQ;AACzC,QAAM,OAAO,QAAQ,MAAM,KAAK,QAAQ;AACxC,QAAM,QAAQ,OAAO,QAAQ;AAC7B,QAAM,SAAS,MAAM,QAAQ;AAC7B,SAAO;AAAA,IACL,KAAM,OAAO,SAAS,QAAQ,WAAY,KAAK;AAAA,IAC/C,IAAI,KAAK,MAAM,UAAU,QAAQ,YAAY;AAAA,IAC7C,OAAQ,QAAQ,QAAQ,QAAQ,WAAY,SAAS;AAAA,IACrD,QAAS,QAAQ,SAAS,QAAQ,WAAY,SAAS;AAAA,EACzD;AACF;AAEA,IAAM,sBAAsB,oBAAI,IAA8B;AAE9D,SAAS,kBAAkB,MAAgC;AACzD,QAAM,SAAS,oBAAoB,IAAI,IAAI;AAC3C,MAAI,QAAQ;AACV,WAAO;AAAA,EACT;AACA,QAAM,YAAY,iBAAiB,IAAI;AACvC,QAAM,aAAa,IAAI,yBAAW,EAAE;AAAA,IAClC,IAAI,oBAAM,GAAG,UAAU,UAAU,KAAK;AAAA,EACxC;AACA,sBAAoB,IAAI,MAAM,UAAU;AACxC,SAAO;AACT;AAEO,SAAS,mBACd,SACA,SAAS,aACH;AACN,QAAM,YAAY,iBAAiB,QAAQ,MAAM,MAAM;AACvD,QAAM,QAAQ,mBAAmB,SAAS,MAAM;AAChD,QAAM,YAAY,MAAM,QAAQ;AAChC,QAAM,aAAa,MAAM,SAAS;AAClC,QAAM,aAAa,kBAAkB,QAAQ,IAAI;AACjD,QAAM,WAAW,IAAI,sBAAQ,GAAG,UAAU,QAAQ;AAClD,QAAM,UAAU;AAAA,IACd,IAAI,sBAAQ,MAAM,IAAI,WAAW,MAAM,IAAI,YAAY,CAAC;AAAA,IACxD,IAAI,sBAAQ,MAAM,IAAI,WAAW,MAAM,IAAI,YAAY,CAAC;AAAA,IACxD,IAAI,sBAAQ,MAAM,IAAI,WAAW,MAAM,IAAI,YAAY,CAAC;AAAA,IACxD,IAAI,sBAAQ,MAAM,IAAI,WAAW,MAAM,IAAI,YAAY,CAAC;AAAA,EAC1D;AAEA,aAAW,UAAU,SAAS;AAC5B,WAAO,gBAAgB,UAAU,EAAE,IAAI,QAAQ;AAAA,EACjD;AAEA,SAAO,IAAI,mBAAK,EAAE,cAAc,OAAO;AACzC;AAEO,SAAS,gBACd,MACA,OACA,UACA,UACA,KACA,KACa;AACb,QAAM,QAAQ,MAAM,KAAK;AACzB,QAAM,OAAO,MAAM,KAAK;AACxB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,KAAK,IAAI,UAAU,WAAW,IAAI;AAAA,IACzC,QAAQ,KAAK,IAAI,UAAU,WAAW,GAAG;AAAA,EAC3C;AACF;AAEO,SAAS,QAAQ,SAA8B;AACpD,SAAO,GAAG,QAAQ,KAAK,IAAI,QAAQ,IAAI,IAAI,QAAQ,GAAG,IAAI,QAAQ,GAAG;AACvE;AAEO,SAAS,kBACd,QACA,gBACA,YACA,aACA,cACQ;AACR,QAAM,mBACJ,iBAAiB,cAAc,KAAK,KAAK,IAAI,aAAa,CAAC;AAC7D,MAAI,iBAAiB,OAAO;AAC5B,WAAS,QAAQ,GAAG,QAAQ,OAAO,QAAQ,SAAS,GAAG;AACrD,QAAI,OAAO,KAAK,KAAM,kBAAkB;AACtC,uBAAiB,QAAQ;AACzB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,iBAAiB,cAAc;AACjC,UAAM,cAAc,OAAO,eAAe,CAAC,KAAK,OAAO,CAAC;AACxD,WAAO,mBAAmB,cAAc,MACpC,iBACA;AAAA,EACN;AACA,MAAI,iBAAiB,cAAc;AACjC,UAAM,gBAAgB,OAAO,iBAAiB,CAAC,KAAK,OAAO,CAAC;AAC5D,WAAO,mBAAmB,gBAAgB,MACtC,iBACA;AAAA,EACN;AACA,SAAO;AACT;AAEO,SAAS,mBACd,MACA,YAAqC,oBAIrC;AACA,QAAM,QAAQ,UAAU,QAAQ,IAAI;AACpC,SAAO;AAAA,IACL,SAAS,UAAU,SAAS,QAAQ,KAAK,UAAU;AAAA,IACnD,OAAO,IAAI,UAAU;AAAA,EACvB;AACF;;;ACvKA,SAAS,gBAAgB,OAAe,MAAsB;AAC5D,MAAI,CAAC,OAAO,SAAS,KAAK,KAAK,SAAS,KAAK,CAAC,OAAO,UAAU,KAAK,GAAG;AACrE,UAAM,IAAI,MAAM,GAAG,IAAI,yCAAyC,OAAO,KAAK,CAAC,EAAE;AAAA,EACjF;AACA,SAAO;AACT;AAEA,SAAS,gBAAgB,QAA4B;AACnD,WAAS,QAAQ,GAAG,QAAQ,OAAO,QAAQ,SAAS,GAAG;AACrD,QAAI,OAAO,KAAK,KAAM,OAAO,QAAQ,CAAC,GAAI;AACxC,YAAM,IAAI,MAAM,gDAAgD;AAAA,IAClE;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,cACd,UACoB;AACpB,MAAI,OAAO,aAAa,UAAU;AAChC,UAAMC,YAAW,gBAAgB,SAAS,UAAU,mBAAmB;AACvE,QAAI,SAAS,OAAO,WAAW,GAAG;AAChC,YAAM,IAAI,MAAM,qDAAqD;AAAA,IACvE;AACA,UAAMC,UAAS;AAAA,MACb,SAAS,OAAO;AAAA,QAAI,CAAC,OAAO,UAC1B,gBAAgB,OAAO,mBAAmB,KAAK,GAAG;AAAA,MACpD;AAAA,IACF;AACA,WAAO,EAAE,UAAAD,WAAU,QAAAC,QAAO;AAAA,EAC5B;AAEA,QAAM,SAAS,SAAS,MAAM,GAAG,EAAE,IAAI,CAAC,SAAS,OAAO,KAAK,KAAK,CAAC,CAAC;AAEpE,MAAI,OAAO,SAAS,KAAK,OAAO,KAAK,CAAC,UAAU,CAAC,OAAO,SAAS,KAAK,CAAC,GAAG;AACxE,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,WAAW,gBAAgB,OAAO,CAAC,GAAI,oBAAoB;AACjE,QAAM,SAAS;AAAA,IACb,OAAO,MAAM,CAAC,EAAE;AAAA,MAAI,CAAC,OAAO,UAC1B,gBAAgB,OAAO,kBAAkB,QAAQ,CAAC,EAAE;AAAA,IACtD;AAAA,EACF;AACA,SAAO,EAAE,UAAU,OAAO;AAC5B;AAEO,SAAS,8BAAsC;AACpD,SAAO;AACT;AAEO,SAAS,uBACd,SACA,cACQ;AACR,QAAM,oBAAoB,QAAQ,QAAQ,QAAQ,EAAE;AACpD,QAAM,iBAAiB,aAAa,QAAQ,QAAQ,EAAE;AACtD,SAAO,oBACH,GAAG,iBAAiB,IAAI,cAAc,KACtC;AACN;AAEO,SAAS,mBACd,UACA,SACQ;AACR,SAAO,SACJ,QAAQ,OAAO,QAAQ,IAAI,EAC3B,QAAQ,OAAO,OAAO,QAAQ,KAAK,CAAC,EACpC,QAAQ,sBAAsB,CAAC,QAAQ,QAAgB,gBAAwB;AAC9E,UAAM,QAAQ,OAAO,SAAS,WAAW,IACrC,QAAQ,MACR,QAAQ;AACZ,WAAO,OAAO,KAAK,EAAE,SAAS,OAAO,SAAS,GAAG,GAAG;AAAA,EACtD,CAAC;AACL;;;AFuFM,IAAAC,sBAAA;AAzHN,IAAM,6BAA6B;AACnC,IAAM,kCAAkC,KAAK,KAAK;AAClD,IAAM,6BAA6B;AACnC,IAAM,sBAAsB;AAC5B,IAAM,iCAAiC;AACvC,IAAM,iBAAiB,cAAc;AACrC,IAAM,uBAAuB,IAAI,4BAAc,GAAG,CAAC;AAanD,SAAS,kBACP,KACA,YACA,SACA;AACA,QAAM,CAAC,SAAS,UAAU,QAAI,yBAAyB,IAAI;AAC3D,QAAM,iBAAa,uBAAO,OAAO;AACjC,aAAW,UAAU;AAErB,gCAAU,MAAM;AACd,QAAI,CAAC,KAAK;AACR,iBAAW,IAAI;AACf;AAAA,IACF;AAEA,QAAI,SAAS;AACb,UAAM,SAAS,IAAI,4BAAc;AACjC,eAAW,IAAI;AACf,WAAO;AAAA,MACL;AAAA,MACA,CAAC,kBAAkB;AACjB,YAAI,CAAC,QAAQ;AACX,wBAAc,QAAQ;AACtB;AAAA,QACF;AACA,sBAAc,aAAa;AAC3B,sBAAc,QAAQ;AACtB,sBAAc,QAAQ;AACtB,sBAAc,YAAY;AAC1B,sBAAc,YAAY;AAC1B,sBAAc,kBAAkB;AAChC,sBAAc,aAAa,KAAK,IAAI,GAAG,UAAU;AACjD,sBAAc,cAAc;AAC5B,mBAAW,aAAa;AAAA,MAC1B;AAAA,MACA;AAAA,MACA,CAAC,UAAU;AACT,YAAI,QAAQ;AACV,qBAAW,IAAI;AACf,qBAAW,UAAU,KAAK;AAAA,QAC5B;AAAA,MACF;AAAA,IACF;AAEA,WAAO,MAAM;AACX,eAAS;AAAA,IACX;AAAA,EACF,GAAG,CAAC,YAAY,GAAG,CAAC;AAEpB;AAAA,IACE,MAAM,MAAM;AACV,eAAS,QAAQ;AAAA,IACnB;AAAA,IACA,CAAC,OAAO;AAAA,EACV;AAEA,SAAO;AACT;AAEA,SAAS,YAAY;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,eAAW,wBAAQ,MAAM;AAC7B,UAAM,eAAe,IAAI;AAAA,MACvB,iBAAiB;AAAA,MACjB,iBAAiB;AAAA,IACnB;AACA,UAAM,KAAK,aAAa,aAAa,IAAI;AACzC,UAAM,EAAE,QAAQ,MAAM,IAAI,mBAAmB,MAAM,SAAS;AAC5D,UAAM,QAAQ,QAAQ;AACtB,aAAS,QAAQ,GAAG,QAAQ,GAAG,OAAO,SAAS,GAAG;AAChD,YAAM,UAAU,GAAG,KAAK,KAAK;AAC7B,SAAG;AAAA,QACD;AAAA,QACA,SAAS,QAAQ,UAAU,KAAK,IAAI,GAAG,QAAQ,QAAQ,CAAC;AAAA,MAC1D;AAAA,IACF;AACA,OAAG,cAAc;AACjB,WAAO;AAAA,EACT,GAAG,CAAC,MAAM,SAAS,CAAC;AAEpB;AAAA,IACE,MAAM,MAAM;AACV,eAAS,QAAQ;AAAA,IACnB;AAAA,IACA,CAAC,QAAQ;AAAA,EACX;AAEA,QAAM,YAAY,iBAAiB,MAAM,cAAc;AACvD,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,UAAU,UAAU;AAAA,MACpB,aAAa;AAAA,MACb,UAAU,UAAU;AAAA,MAEpB;AAAA,QAAC;AAAA;AAAA,UACC,WAAW;AAAA,UACX,YAAY;AAAA,UACZ,KAAK;AAAA,UACL,YAAY;AAAA;AAAA,MACd;AAAA;AAAA,EACF;AAEJ;AAEA,SAAS,YAAY;AAAA,EACnB;AAAA,EACA;AACF,GAGG;AACD,SAAO,WAAW,IAAI,CAAC,SACrB;AAAA,IAAC;AAAA;AAAA,MAEC;AAAA,MACA;AAAA,MACA;AAAA;AAAA,IAHK;AAAA,EAIP,CACD;AACH;AAEA,SAAS,kBACP,SACA,KACA,KACA,SACsB;AACtB,QAAM,CAAC,cAAc,eAAe,QAAI,yBAAS,OAAO;AAAA,IACtD;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU,QAAQ,YAAY,GAAG;AAAA,EACnC,EAAE;AAEF,QAAM,WACJ,aAAa,YAAY,WACzB,aAAa,QAAQ,OACrB,aAAa,QAAQ,MACjB,aAAa,WACb,QAAQ,YAAY,GAAG;AAE7B;AAAA,IACE,MACE,QAAQ,QAAQ,KAAK,KAAK,SAAS,CAAC,iBAAiB;AACnD,sBAAgB;AAAA,QACd;AAAA,QACA;AAAA,QACA;AAAA,QACA,UAAU;AAAA,MACZ,CAAC;AAAA,IACH,CAAC;AAAA,IACH,CAAC,KAAK,SAAS,GAAG;AAAA,EACpB;AAEA,SAAO;AACT;AAEA,IAAM,eAAW,qBAAK,SAASC,UAAS;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,QAAM,MAAM,WAAW,OAAO;AAI9B,QAAM,WAAW,GAAG,GAAG,KAAS,QAAQ,OAAO,CAAC;AAChD,QAAM,WAAW,kBAAkB,SAAS,UAAU,KAAK,OAAO;AAClE,QAAM,SAAS,mBAAmB,OAAO;AACzC,QAAM,YAAY,iBAAiB,QAAQ,IAAI;AAE/C,MAAI,CAAC,SAAS,SAAS;AACrB,WAAO;AAAA,EACT;AAEA,SACE,6CAAC,WAAM,UAAU,UAAU,UAAU,UAAU,UAAU,UACvD;AAAA,IAAC;AAAA;AAAA,MACC,UAAU;AAAA,MACV,UAAU,CAAC,OAAO,GAAG,OAAO,GAAG,CAAC;AAAA,MAChC;AAAA,MACA,OAAO,CAAC,OAAO,OAAO,OAAO,QAAQ,CAAC;AAAA,MAEtC;AAAA,QAAC;AAAA;AAAA,UACC,WAAW;AAAA,UACX,YAAY;AAAA,UACZ,KAAK,SAAS;AAAA,UACd,YAAY;AAAA;AAAA,MACd;AAAA;AAAA,EACF,GACF;AAEJ,CAAC;AAED,IAAM,sBAAkB,qBAAK,SAASC,iBAAgB;AAAA,EACpD;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,SAAO,MAAM,UAAU,IAAI,CAAC,YAC1B;AAAA,IAAC;AAAA;AAAA,MAEC;AAAA,MACA;AAAA,MACA,aAAa,MAAM;AAAA,MACnB;AAAA;AAAA,IAJK,QAAQ,OAAO;AAAA,EAKtB,CACD;AACH,CAAC;AAED,SAAS,oBACP,QACA,UACmB;AACnB,SAAO,OAAO,IAAI,CAAC,UAAU,UAAU;AACrC,UAAM,QAAQ,QAAQ;AACtB,UAAM,OAAO,KAAK,KAAK,WAAW,QAAQ;AAC1C,UAAM,OAAO,KAAK,KAAK,WAAW,QAAQ;AAC1C,UAAM,aAA8B,CAAC;AAErC,eAAW,QAAQ,YAAY;AAC7B,eAAS,MAAM,GAAG,OAAO,MAAM,OAAO,GAAG;AACvC,iBAAS,MAAM,GAAG,OAAO,MAAM,OAAO,GAAG;AACvC,gBAAM,UAAU;AAAA,YACd;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AACA,qBAAW,KAAK;AAAA,YACd;AAAA,YACA,QAAQ,mBAAmB,OAAO;AAAA,UACpC,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT,CAAC;AACH;AAEA,SAAS,iBACP,YACA,SACe;AACf,SAAO,WACJ,OAAO,CAAC,cAAc,QAAQ,cAAc,UAAU,MAAM,CAAC,EAC7D,IAAI,CAAC,cAAc,UAAU,OAAO;AACzC;AAEA,SAAS,wBACP,QACA,kBACA,SACA;AACA,SAAO,uBAAuB;AAC9B,SAAO,kBAAkB;AACzB,SAAO,mBAAmB,KAAK,OAAO,WAAW,EAAE,OAAO;AAC1D,mBAAiB;AAAA,IACf,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AACA,UAAQ,wBAAwB,gBAAgB;AAClD;AAEA,SAAS,WACP,kBACA,SACA;AACA,MAAI,iBAAiB,iBAAiB,IAAI,QAAQ,KAAK;AACvD,MAAI,CAAC,gBAAgB;AACnB,qBAAiB,oBAAI,IAAI;AACzB,qBAAiB,IAAI,QAAQ,OAAO,cAAc;AAAA,EACpD;AACA,iBAAe,IAAI,QAAQ,OAAO,GAAG,OAAO;AAC9C;AAEA,SAAS,gBACP,OACA,aACA,gBACA,UACe;AACf,QAAM,aAAc,MAAM,MAAM,KAAK,MAAM,WAAY,MAAM;AAC7D,QAAM,YAAa,MAAM,MAAM,KAAK,MAAM,WAAY,MAAM;AAC5D,QAAM,aAAa,YAAY,MAAM,QAAQ,MAAM;AACnD,QAAM,cAAc,WAAW,MAAM,SAAS,MAAM;AACpD,QAAM,OAAO,KAAK,KAAK,iBAAiB,QAAQ;AAChD,QAAM,OAAO,KAAK,KAAK,iBAAiB,QAAQ;AAChD,QAAM,WAAW,KAAK;AAAA,IACpB;AAAA,IACA,KAAK,MAAO,YAAY,iBAAkB,QAAQ,IAAI;AAAA,EACxD;AACA,QAAM,UAAU,KAAK;AAAA,IACnB;AAAA,IACA,KAAK,KAAM,aAAa,iBAAkB,QAAQ;AAAA,EACpD;AACA,QAAM,WAAW,KAAK;AAAA,IACpB;AAAA,IACA,KAAK,MAAO,WAAW,iBAAkB,QAAQ,IAAI;AAAA,EACvD;AACA,QAAM,UAAU,KAAK;AAAA,IACnB;AAAA,IACA,KAAK,KAAM,cAAc,iBAAkB,QAAQ;AAAA,EACrD;AACA,QAAM,YAA2B,CAAC;AAElC,WAAS,MAAM,UAAU,OAAO,SAAS,OAAO,GAAG;AACjD,aAAS,MAAM,UAAU,OAAO,SAAS,OAAO,GAAG;AACjD,gBAAU;AAAA,QACR;AAAA,UACE,MAAM;AAAA,UACN;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,oBACP,YACA,QACa;AACb,QAAM,YAAY,OAAO,kBAAkB,IAAI,sBAAQ,CAAC;AACxD,QAAM,SAAS,IAAI,sBAAQ;AAC3B,MAAI,gBAAgB,WAAW,CAAC;AAChC,MAAI,gBAAgB;AAEpB,aAAW,aAAa,YAAY;AAClC,cAAU,OAAO,UAAU,MAAM,EAAE,UAAU;AAC7C,UAAM,YAAY,OAAO,IAAI,SAAS;AACtC,QAAI,YAAY,eAAe;AAC7B,sBAAgB;AAChB,sBAAgB;AAAA,IAClB;AAAA,EACF;AAEA,SAAO,cAAc;AACvB;AAEA,SAAS,YACP,aACA,QACA,UACA,SACA,QACA,mBACa;AACb,QAAM,mBAAmB,oBAAI,IAAsC;AACnE,QAAM,mBAAmB,kBAAkB,cAAc,CAAC;AAC1D,QAAM,kBAAkB,iBAAiB,kBAAkB,OAAO;AAIlE,QAAM,iBACJ,gBAAgB,SAAS,IACrB,kBACA,CAAC,oBAAoB,kBAAkB,MAAM,CAAC;AAEpD,aAAW,WAAW,gBAAgB;AACpC,eAAW,kBAAkB,OAAO;AAAA,EACtC;AAEA,MAAI,WAAW;AACf,WAAS,cAAc,cAAc,GAAG,eAAe,GAAG,eAAe,GAAG;AAC1E,UAAM,iBAAiB,OAAO,cAAc,CAAC;AAC7C,UAAM,UAAU,oBAAI,IAAyB;AAC7C,eAAW,SAAS,UAAU;AAC5B,iBAAW,UAAU;AAAA,QACnB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,GAAG;AACD,gBAAQ,IAAI,QAAQ,MAAM,GAAG,MAAM;AACnC,mBAAW,kBAAkB,MAAM;AAAA,MACrC;AAAA,IACF;AACA,eAAW,MAAM,KAAK,QAAQ,OAAO,CAAC;AAAA,EACxC;AAEA,SAAO,MAAM,KAAK,iBAAiB,QAAQ,CAAC,EACzC,KAAK,CAAC,CAAC,UAAU,GAAG,CAAC,WAAW,MAAM,aAAa,WAAW,EAC9D,IAAI,CAAC,CAAC,OAAO,SAAS,OAAO;AAAA,IAC5B;AAAA,IACA,WAAW,MAAM,KAAK,UAAU,OAAO,CAAC;AAAA,IACxC,aAAa,OAAO,QAAQ;AAAA,EAC9B,EAAE;AACN;AAEA,SAAS,WAAW,QAA6B;AAC/C,SAAO,OACJ;AAAA,IACC,CAAC,UACC,GAAG,MAAM,KAAK,IAAI,MAAM,UAAU,IAAI,OAAO,EAAE,KAAK,GAAG,CAAC;AAAA,EAC5D,EACC,KAAK,GAAG;AACb;AAEO,SAAS,KAAK;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA,mBAAmB;AAAA,EACnB;AAAA,EACA;AAAA,EACA,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,aAAa;AAAA,EACb,WAAW;AAAA,EACX,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAc;AACZ,QAAM,EAAE,QAAQ,IAAI,KAAK,QAAI,yBAAS;AACtC,QAAM,qBAAiB,wBAAQ,MAAM,cAAc,QAAQ,GAAG,CAAC,QAAQ,CAAC;AACxE,QAAM,EAAE,QAAQ,SAAS,IAAI;AAC7B,QAAM,gBAAgB,GAAG,QAAQ,IAAI,OAAO,KAAK,GAAG,CAAC;AACrD,QAAM,wBAAoB;AAAA,IACxB,MAAM,oBAAoB,QAAQ,QAAQ;AAAA,IAC1C,CAAC,QAAQ,QAAQ;AAAA,EACnB;AACA,QAAM,aAAa,GAAG,aAAa,iBAAiB;AACpD,QAAM,sBACJ,eAAe,SACX,GAAG,QAAQ,QAAQ,OAAO,EAAE,CAAC,iCAC7B;AACN,QAAM,iBAAiB;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,gBAAgB,4BAA4B;AAClD,QAAM,kBAAc,uBAAO,cAAc;AACzC,QAAM,eAAW,uBAAO,WAAW;AACnC,QAAM,qBAAiB,uBAAO,aAAa;AAC3C,cAAY,UAAU;AACtB,WAAS,UAAU;AACnB,iBAAe,UAAU;AAEzB,QAAM,mBAAe;AAAA,IACnB,MACE,IAAI,mBAAmB;AAAA,MACrB;AAAA,MACA,UAAU,KAAK,IAAI,GAAG,kBAAkB,IAAI,OAAO;AAAA,MACnD,aAAa,KAAK,IAAI,GAAG,KAAK,MAAM,kBAAkB,CAAC;AAAA,MACvD,YAAY,KAAK,IAAI,GAAG,KAAK,MAAM,UAAU,CAAC;AAAA,MAC9C,YAAY,CAAC,aAAa,YAAY,UAAU,QAAQ;AAAA,MACxD,SAAS,CAAC,UAAU,SAAS,UAAU,KAAK;AAAA,IAC9C,CAAC;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,QAAM,UAAU,iBAAiB;AACjC,gCAAU,MAAM;AACd,YAAQ,OAAO;AACf,WAAO,MAAM;AACX,UAAI,YAAY,cAAc;AAC5B,gBAAQ,QAAQ;AAChB;AAAA,MACF;AACA,qBAAe,MAAM,QAAQ,cAAc,CAAC;AAAA,IAC9C;AAAA,EACF,GAAG,CAAC,SAAS,YAAY,CAAC;AAE1B,QAAM,eAAW,uBAAO,KAAK;AAC7B,gCAAU,MAAM;AACd,aAAS,UAAU;AAAA,EACrB,GAAG,CAAC,mBAAmB,CAAC;AACxB,gCAAU,MAAM;AACd,QAAI,CAAC,kBAAkB,SAAS,SAAS;AACvC;AAAA,IACF;AACA,aAAS,UAAU;AACnB,cAAU;AAAA,EACZ,GAAG,CAAC,SAAS,cAAc,CAAC;AAE5B,QAAM,WAAW,eAAe,4BAA4B;AAC5D,QAAM,iBAAa;AAAA,IACjB,MAAM,CAAC,YAAyB;AAC9B,YAAM,eAAe,iBACjB,eAAe,OAAO,IACtB,mBAAmB,UAAU,OAAO;AACxC,aAAO,uBAAuB,SAAS,YAAY;AAAA,IACrD;AAAA,IACA,CAAC,SAAS,gBAAgB,QAAQ;AAAA,EACpC;AAEA,QAAM,CAAC,QAAQ,SAAS,QAAI,yBAAsB,CAAC,CAAC;AACpD,QAAM,oBAAgB,uBAAO,EAAE;AAC/B,QAAM,sBAAkB,uBAAO,CAAC;AAChC,QAAM,sBAAkB,uBAAO,SAAS;AACxC,QAAM,yBAAqB,uBAAO,IAAI;AACtC,QAAM,kCAA8B,uBAAO,OAAO,WAAW,MAAM,CAAC;AACpE,QAAM,2BAAuB,uBAAO,OAAO,GAAG;AAC9C,QAAM,sBAAkB,uBAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,EAAE,CAAC;AAC9D,QAAM,iBAAa,uBAAO,IAAI,sBAAQ,CAAC;AACvC,QAAM,0BAAsB,uBAAO,IAAI,sBAAQ,CAAC;AAChD,QAAM,0BAAsB,uBAAO,IAAI,gCAAkB,CAAC;AAE1D,gCAAU,MAAM;AACd,oBAAgB,UAAU;AAC1B,kBAAc,UAAU;AACxB,uBAAmB,UAAU;AAC7B,cAAU,CAAC,CAAC;AAAA,EACd,GAAG,CAAC,SAAS,aAAa,CAAC;AAE3B,gCAAU,MAAM;AACd,QAAI,aAAa,WAAW;AAC1B;AAAA,IACF;AACA,kBAAc,UAAU;AACxB,cAAU,CAAC,CAAC;AAAA,EACd,GAAG,CAAC,QAAQ,CAAC;AAEb,QAAM,eAAe,CAAC,eAA4B;AAChD,UAAM,YAAY,WAAW,UAAU;AACvC,QAAI,cAAc,cAAc,SAAS;AACvC,oBAAc,UAAU;AACxB,gBAAU,UAAU;AAAA,IACtB;AAAA,EACF;AAEA,+BAAS,MAAM;AACb,QAAI,aAAa,WAAW;AAC1B;AAAA,IACF;AACA,QAAI,EAAE,kBAAkB,kCAAoB;AAC1C;AAAA,IACF;AAEA,UAAM,MAAM,YAAY,IAAI;AAC5B,UAAM,aAAa,GAAG,cAAc;AACpC,UAAM,gBAAgB,4BAA4B,QAAQ;AAAA,MACxD,OAAO;AAAA,IACT;AACA,UAAM,WAAW,OAAO,SAAS,qBAAqB,OAAO,IACzD,KAAK,IAAI,OAAO,MAAM,qBAAqB,OAAO,IAClD;AACJ,UAAM,eAAe,gBAAgB;AACrC,UAAM,kBACJ,aAAa,UAAU,KAAK,SAC5B,aAAa,WAAW,KAAK,UAC7B,aAAa,QAAQ;AACvB,UAAM,cACJ,mBAAmB,WACnB,mBACA,gBAAgB,uBAChB,WAAW;AACb,UAAM,gBACJ,iBAAiB,mCACjB,YAAY;AAEd,QAAI,CAAC,aAAa;AAChB;AAAA,IACF;AAEA,UAAM,uBACJ,mBAAmB,WACnB,mBACA;AACF,QACE,CAAC,wBACD,MAAM,gBAAgB,UAAU,4BAChC;AACA;AAAA,IACF;AAEA,oBAAgB,UAAU;AAE1B,UAAM,cAAc,aAAa,SAC7B,IACA;AAAA,MACA;AAAA,MACA,KAAK;AAAA,MACL;AAAA,MACA,OAAO;AAAA,MACP,gBAAgB;AAAA,IAClB;AACF,QAAI,gBAAgB,gBAAgB,SAAS;AAC3C,sBAAgB,UAAU;AAC1B,qBAAe,UAAU,WAAW;AAAA,IACtC;AAEA,UAAM,mBAAmB,oBAAoB;AAC7C,qBAAiB,KAAK,QAAQ,KAAK;AACnC,qBAAiB,MAAM,KAAK;AAAA,MAC1B;AAAA,MACA,OAAO,MAAM;AAAA,IACf;AACA,qBAAiB,SAAS,OAAO;AACjC;AAAA,MACE;AAAA,MACA,oBAAoB;AAAA,MACpB,WAAW;AAAA,IACb;AAEA,UAAM,aAAa;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX;AAAA,MACA;AAAA,IACF;AACA,uBAAmB,UAAU;AAC7B,gCAA4B,QAAQ,KAAK,OAAO,UAAU;AAC1D,yBAAqB,UAAU,OAAO;AACtC,oBAAgB,UAAU;AAAA,MACxB,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK;AAAA,MACb,KAAK;AAAA,IACP;AACA,iBAAa,UAAU;AAAA,EACzB,CAAC;AAED,SACE,8CAAC,WAAM,SACJ;AAAA,qBACC;AAAA,MAAC;AAAA;AAAA,QACC,SAAS;AAAA,QACT,WAAW;AAAA;AAAA,IACb,IACE;AAAA,IACH,OAAO,IAAI,CAAC,UACX;AAAA,MAAC;AAAA;AAAA,QAEC;AAAA,QACA;AAAA,QACA;AAAA;AAAA,MAHK,MAAM;AAAA,IAIb,CACD;AAAA,KACH;AAEJ;;;AH3iBM,IAAAC,sBAAA;AAjEN,IAAM,sBAGD;AAAA,EACH,MAAM,EAAE,UAAU,GAAG,aAAa,UAAU;AAAA,EAC5C,WAAW,EAAE,UAAU,GAAG,aAAa,0BAA0B;AAAA,EACjE,MAAM,EAAE,UAAU,GAAG,aAAa,qCAAqC;AAAA,EACvE,UAAU,EAAE,UAAU,GAAG,aAAa,yCAAyC;AAAA,EAC/E,YAAY,EAAE,UAAU,GAAG,aAAa,yCAAyC;AAAA,EACjF,kBAAkB,EAAE,UAAU,GAAG,aAAa,oCAAoC;AAAA,EAClF,kBAAkB,EAAE,UAAU,GAAG,aAAa,sCAAsC;AAAA,EACpF,eAAe,EAAE,UAAU,GAAG,aAAa,sCAAsC;AAAA,EACjF,YAAY,EAAE,UAAU,GAAG,aAAa,wCAAwC;AAAA,EAChF,cAAc,EAAE,UAAU,KAAK,aAAa,wCAAwC;AAAA,EACpF,gBAAgB,EAAE,UAAU,GAAG,aAAa,yCAAyC;AAAA,EACrF,kBAAkB,EAAE,UAAU,GAAG,aAAa,yCAAyC;AACzF;AAEA,IAAM,eAAyD;AAAA,EAC7D,MAAM;AAAA,EACN,WAAW;AAAA,EACX,MAAM;AAAA,EACN,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,kBAAkB;AACpB;AAEA,SAAS,kBAAkB,YAAkE;AAC3F,QAAM,SAAS,OAAO,eAAe,WAAW,aAAa,YAAY,UAAU;AACnF,SAAO;AAAA,IACL;AAAA,IACA,UAAU,KAAK;AAAA,MACb;AAAA,MACA,cAAc,OAAO,eAAe,YAAY,OAAO,SAAS,WAAW,QAAQ,IAC/E,WAAW,WACX,oBAAoB,MAAM,EAAE;AAAA,IAClC;AAAA,EACF;AACF;AAEA,SAAS,YAAY;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMG;AACD,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,SAAS,UAAU;AAC3B,WACE;AAAA,MAAC;AAAA;AAAA,QACC,KAAK,MAAM;AAAA,QACX,WAAW,MAAM;AAAA,QACjB;AAAA,QACA,QAAQ;AAAA,QACR;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,QAAM,EAAE,IAAI,KAAK,MAAM,OAAO,GAAG,UAAU,IAAI;AAC/C,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ;AAAA,MACA,UAAU,WAAW,SAAS;AAAA,MAC9B;AAAA,MACA,gBAAgB;AAAA;AAAA,EAClB;AAEJ;AAEA,SAAS,gBAAgB;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,EAAE,QAAQ,IAAI,OAAO,KAAK,QAAI,yBAAS;AAC7C,QAAM,yBAAqB,uBAAO,CAAC;AACnC,QAAM,sBAAkB,uBAAiC,IAAI;AAE7D;AAAA,IACE,MAAM,MAAM;AACV,sBAAgB,SAAS,QAAQ;AACjC,sBAAgB,UAAU;AAAA,IAC5B;AAAA,IACA,CAAC;AAAA,EACH;AAEA,+BAAS,MAAM;AACb,QAAI,cAAc,KAAK,cAAc,mBAAmB,SAAS;AAC/D;AAAA,IACF;AAEA,UAAM,aAAa,GAAG,cAAc;AACpC,UAAM,cAAc,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,QAAQ,UAAU,CAAC;AACnE,UAAM,eAAe,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,SAAS,UAAU,CAAC;AACrE,UAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,KAAK,aAAa,cAAc,aAAa,CAAC;AAC7E,UAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,cAAc,KAAK,CAAC;AACzD,UAAM,SAAS,KAAK,IAAI,GAAG,KAAK,MAAM,eAAe,KAAK,CAAC;AAC3D,UAAM,aAAa,IAAI,gCAAkB,OAAO,QAAQ;AAAA,MACtD,aAAa;AAAA,MACb,eAAe;AAAA,IACjB,CAAC;AAGD,eAAW,QAAQ,aAAa;AAChC,eAAW,QAAQ,kBAAkB;AACrC,eAAW,QAAQ,YAAY;AAC/B,eAAW,QAAQ,YAAY;AAI/B,UAAM,iBAAiB,GAAG,gBAAgB;AAC1C,OAAG,gBAAgB,UAAU;AAC7B,OAAG,MAAM;AACT,OAAG,OAAO,OAAO,MAAM;AACvB,OAAG,gBAAgB,cAAc;AAEjC,uBAAmB,UAAU;AAC7B,UAAM,WAAW,gBAAgB;AACjC,oBAAgB,UAAU;AAC1B,cAAU,QAAQ;AAClB,eAAW;AAAA,MACT,SAAS,WAAW;AAAA,MACpB,SAAS,MAAM;AACb,YAAI,gBAAgB,YAAY,YAAY;AAC1C,0BAAgB,UAAU;AAAA,QAC5B;AACA,mBAAW,QAAQ;AAAA,MACrB;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAED,SAAO;AACT;AAEA,SAAS,gBAAgB;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMG;AACD,QAAM,EAAE,QAAQ,KAAK,QAAI,yBAAS;AAClC,QAAM,cAAU,uBAAa,IAAI;AACjC,QAAM,eAAW,uBAAsB,IAAI;AAC3C,QAAM,kBAAc,uBAAO,KAAK;AAChC,QAAM,mBAAe,uBAAO,IAAI,sBAAQ,CAAC;AACzC,QAAM,eAAW;AAAA,IACf,MACE,IAAI,6BAAe;AAAA,MACjB,aAAa;AAAA,MACb,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,MAAM;AAAA,MACN,UAAU;AAAA,QACR,KAAK,EAAE,OAAO,SAAS,QAAQ;AAAA,QAC/B,UAAU,EAAE,OAAO,EAAE;AAAA,QACrB,QAAQ,EAAE,OAAO,aAAa,WAAW,MAAM,EAAE;AAAA,MACnD;AAAA,MACA,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOd,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IA0DlB,CAAC;AAAA,IACH,CAAC,SAAS,SAAS,WAAW,MAAM;AAAA,EACtC;AAEA,gCAAU,MAAM,MAAM,SAAS,QAAQ,GAAG,CAAC,QAAQ,CAAC;AACpD,gCAAU,MAAM;AACd,aAAS,UAAU;AACnB,gBAAY,UAAU;AACtB,aAAS,SAAS,SAAS,QAAQ;AAAA,EACrC,GAAG,CAAC,UAAU,KAAK,CAAC;AAEpB,+BAAS,CAAC,UAAU;AAClB,UAAM,OAAO,QAAQ;AACrB,QAAI,CAAC,QAAQ,CAAE,OAA6C,qBAAqB;AAC/E;AAAA,IACF;AACA,UAAM,oBAAoB;AAC1B,UAAM,WAAW,KAAK,IAAI,kBAAkB,OAAO,KAAK,IAAI;AAC5D,WAAO,kBAAkB,aAAa,OAAO;AAC7C,SAAK,SAAS,KAAK,OAAO,QAAQ,EAAE,gBAAgB,aAAa,SAAS,QAAQ;AAClF,SAAK,WAAW,KAAK,OAAO,UAAU;AACtC,UAAM,SAAS,IAAI,WAAW,KAAK,IAAK,kBAAkB,MAAM,KAAK,KAAM,GAAG;AAC9E,SAAK,MAAM,IAAI,SAAS,kBAAkB,QAAQ,QAAQ,CAAC;AAE3D,QAAI,CAAC,WAAW,YAAY,SAAS;AACnC;AAAA,IACF;AACA,QAAI,SAAS,YAAY,MAAM;AAC7B,eAAS,UAAU,MAAM,MAAM;AAAA,IACjC;AACA,UAAM,WAAW,WAAW,aAAa,IACrC,IACA,KAAK,IAAI,IAAI,MAAM,MAAM,cAAc,SAAS,WAAW,WAAW,QAAQ;AAClF,aAAS,SAAS,SAAS,QAAQ;AACnC,QAAI,aAAa,GAAG;AAClB,kBAAY,UAAU;AACtB,eAAS;AAAA,IACX;AAAA,EACF,CAAC;AAED,SACE,8CAAC,UAAK,KAAK,SAAS,aAAa,KAAQ,eAAe,OACtD;AAAA,iDAAC,eAAU,QAAO,YAAW,QAAQ,kBAAkB;AAAA,IACvD,6CAAC,eAAU,QAAO,YAAW,QAAQ,UAAU;AAAA,KACjD;AAEJ;AAEA,IAAM,mBAAmB,IAAI,4BAAc,GAAG,CAAC;AAE/C,SAAS,yBAAyB;AAAA,EAChC;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA,oBAAoB;AACtB,GAA+E;AAC7E,QAAM,kBAAc,2BAAW,mBAAmB;AAClD,QAAM,UAAU,4BAA4B;AAC5C,QAAM,iBAAa;AAAA,IACjB,MAAM,kBAAkB,eAAe;AAAA,IACvC,CAAC,eAAe;AAAA,EAClB;AACA,QAAM,eAAW;AAAA,IACf,MAAM,IAAI,IAAI,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;AAAA,IACtD,CAAC,MAAM;AAAA,EACT;AACA,QAAM,eAAe,SAAS,IAAI,aAAa,KAAK;AACpD,QAAM,CAAC,OAAO,QAAQ,QAAI,yBAAuD;AAAA,IAC/E;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,CAAC,YAAY,aAAa,QAAI,yBAAS,CAAC;AAC9C,QAAM,CAAC,UAAU,WAAW,QAAI,yBAAS,CAAC;AAC1C,QAAM,CAAC,aAAa,cAAc,QAAI,yBAAwB,IAAI;AAClE,QAAM,CAAC,OAAO,QAAQ,QAAI,yBAAgB,eAAe,SAAS,YAAY;AAC9E,QAAM,CAAC,kBAAkB,mBAAmB,QAAI,yBAAS,CAAC;AAC1D,QAAM,CAAC,iBAAiB,kBAAkB,QAAI,yBAAS,CAAC;AACxD,QAAM,CAAC,UAAU,WAAW,QAAI,yBAA0B,IAAI;AAC9D,QAAM,CAAC,aAAa,cAAc,QAAI,yBAAS,CAAC;AAChD,QAAM,0BAAsB,uBAAO,aAAa;AAChD,QAAM,uBAAmB,uBAA8B,OAAO;AAC9D,QAAM,4BAAwB,uBAA4B,IAAI;AAC9D,QAAM,eAAW,uBAAO,KAAK;AAC7B,QAAM,eAAW,uBAAO,KAAK;AAC7B,QAAM,kBAAc,uBAAO,QAAQ;AACnC,QAAM,wBAAoB,uBAA6B,YAAY;AACnE,WAAS,UAAU;AACnB,WAAS,UAAU;AACnB,cAAY,UAAU;AAEtB,QAAM,yBAAqB,4BAAY,MAAM;AAC3C,0BAAsB,UAAU;AAChC,0BAAsB,UAAU;AAAA,EAClC,GAAG,CAAC,CAAC;AAEL,QAAM,kBAAc,4BAAY,CAAC,SAAiB,UAAmB;AACnE,wBAAoB,EAAE,SAAS,MAAM,CAAC;AAAA,EACxC,GAAG,CAAC,iBAAiB,CAAC;AAEtB,QAAM,mBAAe,4BAAY,CAAC,UAAyB;AACzD,UAAM,WAAW,IAAI,YAAY;AACjC,wBAAoB,UAAU,MAAM;AACpC,aAAS,CAAC,YAAY;AACpB,YAAM,OAAqD,CAAC,GAAG,OAAO;AACtE,WAAK,QAAQ,IAAI;AACjB,aAAO;AAAA,IACT,CAAC;AACD,mBAAe,QAAQ;AACvB,aAAS,YAAY;AAAA,EACvB,GAAG,CAAC,CAAC;AAEL,gCAAU,MAAM;AACd,UAAM,YAAY,SAAS,IAAI,aAAa;AAC5C,QAAI,CAAC,WAAW;AACd,kBAAY,eAAe,IAAI,MAAM,2BAA2B,aAAa,EAAE,CAAC;AAChF;AAAA,IACF;AAEA,UAAM,YAAY,SAAS,QAAQ,YAAY,OAAO;AACtD,QAAI,SAAS,YAAY,UAAU,WAAW,OAAO,UAAU,IAAI;AACjE,0BAAoB,UAAU,UAAU;AACxC;AAAA,IACF;AACA,QACE,SAAS,YAAY,gBACrB,gBAAgB,QAChB,SAAS,QAAQ,WAAW,GAAG,OAAO,UAAU,IAChD;AACA,0BAAoB,UAAU,UAAU;AACxC;AAAA,IACF;AACA,QAAI,SAAS,YAAY,mBAAmB,SAAS,YAAY,aAAa;AAC5E,0BAAoB,UAAU,UAAU;AACxC,uBAAiB,UAAU;AAC3B,eAAS,aAAa;AACtB,0BAAoB,CAAC,YAAY,UAAU,CAAC;AAC5C;AAAA,IACF;AACA,iBAAa,SAAS;AAAA,EACxB,GAAG,CAAC,eAAe,aAAa,aAAa,UAAU,YAAY,CAAC;AAEpE,QAAM,kBAAc,4BAAY,CAAC,SAAiB;AAChD,QAAI,SAAS,eAAe,SAAS,YAAY,cAAc;AAC7D;AAAA,IACF;AACA,QAAI,WAAW,WAAW,QAAQ;AAChC,YAAM,gBAAgB,SAAS,QAAQ,YAAY,OAAO;AAC1D,YAAM,YAAY,SAAS,QAAQ,IAAI;AACvC,eAAS,CAAC,YAAY;AACpB,cAAM,OAAqD,CAAC,GAAG,OAAO;AACtE,aAAK,YAAY,OAAO,IAAI;AAC5B,eAAO;AAAA,MACT,CAAC;AACD,kBAAY,IAAI;AAChB,oBAAc,IAAI;AAClB,qBAAe,IAAI;AACnB,eAAS,MAAM;AACf,UAAI,iBAAiB,WAAW;AAC9B,0BAAkB;AAAA,UAChB,iBAAiB,cAAc;AAAA,UAC/B,SAAS,UAAU;AAAA,UACnB,QAAQ;AAAA,QACV,CAAC;AAAA,MACH;AACA;AAAA,IACF;AACA,0BAAsB,YAAtB,sBAAsB,UAAY,aAAa,SAAS,uBAAuB,KAAK;AACpF,sBAAkB,UAAU,SAAS,QAAQ,YAAY,OAAO;AAChE,qBAAiB,UAAU;AAC3B,aAAS,WAAW;AACpB,wBAAoB,CAAC,YAAY,UAAU,CAAC;AAAA,EAC9C,GAAG,CAAC,aAAa,iBAAiB,aAAa,WAAW,MAAM,CAAC;AAEjE,QAAM,qBAAiB,4BAAY,CAAC,iBAA2B;AAC7D,gBAAY,CAAC,YAAY;AACvB,eAAS,QAAQ;AACjB,aAAO;AAAA,IACT,CAAC;AAED,QAAI,iBAAiB,YAAY,aAAa;AAC5C,mBAAa,SAAS,IAAI,oBAAoB,OAAO,CAAE;AACvD;AAAA,IACF;AAEA,UAAM,aAAa,YAAY;AAC/B,aAAS,CAAC,YAAY;AACpB,YAAM,OAAqD,CAAC,GAAG,OAAO;AACtE,WAAK,UAAU,IAAI;AACnB,aAAO;AAAA,IACT,CAAC;AACD,aAAS,cAAc;AACvB,QAAI,gBAAgB,MAAM;AACxB,kBAAY,WAAW;AAAA,IACzB;AACA,aAAS,eAAe;AACxB,uBAAmB,CAAC,YAAY,UAAU,CAAC;AAAA,EAC7C,GAAG,CAAC,SAAS,aAAa,UAAU,YAAY,CAAC;AAEjD,QAAM,uBAAmB,4BAAY,MAAM;AACzC,UAAM,WAAW;AACjB,UAAM,gBAAgB,kBAAkB;AACxC,UAAM,YAAY,aAAa,OAAO,OAAO,SAAS,QAAQ,QAAQ;AACtE,QAAI,aAAa,QAAQ,CAAC,WAAW;AACnC,yBAAmB;AACnB,eAAS,MAAM;AACf;AAAA,IACF;AACA,kBAAc,QAAQ;AACtB,gBAAY,QAAQ;AACpB,mBAAe,IAAI;AACnB,aAAS,MAAM;AACf,UAAM,cAAc;AACpB,gBAAY,IAAI;AAChB,iBAAa,QAAQ;AACrB,uBAAmB;AACnB,QAAI,eAAe;AACjB,wBAAkB;AAAA,QAChB,iBAAiB,cAAc;AAAA,QAC/B,SAAS,UAAU;AAAA,QACnB,QAAQ,WAAW;AAAA,MACrB,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,iBAAiB,aAAa,oBAAoB,UAAU,WAAW,MAAM,CAAC;AAElF,gCAAU,MAAM,MAAM;AACpB,uBAAmB;AACnB,cAAU,QAAQ;AAAA,EACpB,GAAG,CAAC,oBAAoB,QAAQ,CAAC;AAEjC,QAAM,EAAE,GAAG,QAAI,yBAAS;AACxB,gCAAU,MAAM;AACd,UAAM,SAAS,GAAG;AAClB,UAAM,gBAAgB,CAAC,UAAiB;AACtC,YAAM,eAAe;AACrB,yBAAmB;AACnB,eAAS,QAAQ;AACjB,gBAAU,QAAQ;AAClB,kBAAY,IAAI;AAChB,qBAAe,IAAI;AACnB,eAAS,MAAM;AAAA,IACjB;AACA,UAAM,oBAAoB,MAAM;AAC9B,eAAS,OAAO;AAChB,qBAAe,CAAC,YAAY,UAAU,CAAC;AAAA,IACzC;AACA,WAAO,iBAAiB,oBAAoB,aAAa;AACzD,WAAO,iBAAiB,wBAAwB,iBAAiB;AACjE,WAAO,MAAM;AACX,aAAO,oBAAoB,oBAAoB,aAAa;AAC5D,aAAO,oBAAoB,wBAAwB,iBAAiB;AAAA,IACtE;AAAA,EACF,GAAG,CAAC,IAAI,SAAS,oBAAoB,QAAQ,CAAC;AAE9C,QAAM,gBAAgB,MAAM,QAAQ;AACpC,QAAM,kBAAkB,aAAa,SACnC,UAAU,mBACV,UAAU,iBACV,UAAU;AAGZ,SACE,8CAAC,2BACC;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAW;AAAA,QACX,WAAW,KAAK,IAAI,GAAG,iBAAiB;AAAA,QACxC,YAAY;AAAA;AAAA,IACd;AAAA,IACC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,SAAS;AACpB,YAAM,SAAS,MAAM,IAAI;AACzB,YAAM,SAAS,SAAS;AACxB,YAAM,YAAY,SAAS;AAC3B,aACE;AAAA,QAAC;AAAA;AAAA,UAEC,OAAO;AAAA,UACP,SAAS;AAAA,UACT,UAAU,aAAa,UAAU;AAAA,UACjC,SAAS,MAAM,YAAY,IAAI;AAAA,UAC/B,SAAS,CAAC,UAAU;AAClB,gBAAI,QAAQ;AACV,0BAAY,OAAO,IAAI,KAAK;AAAA,YAC9B;AAAA,UACF;AAAA;AAAA,QATK,GAAG,IAAI,IAAI,QAAQ,MAAM,OAAO,IAAI,WAAW;AAAA,MAUtD;AAAA,IAEJ,CAAC;AAAA,IACA,kBACC;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,SAAS,UAAU;AAAA,QACnB,OAAO;AAAA,QACP,UAAU;AAAA;AAAA,IACZ,IACE;AAAA,IACH,UAAU,UAAU,gBAAgB,iBAAiB,aAAa,IAAI;AAAA,KACzE;AAEJ;AAEO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAwB;AACtB,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,oBAAoB;AAAA,MAEpB,uDAAC,4BAA0B,GAAG,OAAO;AAAA;AAAA,EACvC;AAEJ;;;AM5qBA,IAAAC,iBAAyB;AACzB,IAAAC,iBAA4C;AAC5C,IAAAC,iBAQO;;;ACTP,IAAAC,iBAAyB;AACzB,IAAAC,iBAKO;AAEP,IAAAC,gBASO;AA8RH,IAAAC,sBAAA;AA9QJ,IAAM,4BAA4B;AAClC,IAAM,kBAAkB;AAExB,IAAM,yBAAyB;AAC/B,IAAM,wBAAwB;AAC9B,IAAM,mBAAmB;AACzB,IAAM,mBAAmB;AACzB,IAAM,uBAAuB;AAC7B,IAAM,gBAAgB,IAAI,sBAAQ,GAAG,GAAG,CAAC;AACzC,IAAM,yBAGF;AAAA,EACF,SAAS,EAAE,aAAa,WAAW,WAAW,UAAU;AAAA,EACxD,WAAW,EAAE,aAAa,aAAa,WAAW,WAAW;AAC/D;AAsBA,SAAS,uBAAuB,MAAc,QAAwB;AACpE,QAAM,WAAW,OAAO,SAAS,IAAI,IACjC,wBAAU,MAAM,KAAK,IAAI,IAAI,GAAG,kBAAkB,gBAAgB,IAClE;AACJ,SAAO,IAAI,SAAS,KAAK,IAAI,wBAAU,SAAS,QAAQ,IAAI,CAAC;AAC/D;AAEA,SAAS,aAAa,OAAmC;AACvD,SAAO,OAAO,SAAS,KAAK,KAAK,QAAS,IAAI,QAAS;AACzD;AAEA,SAAS,gBACP,WACA,UACA,OACA,QACQ;AACR,QAAM,kBAAkB,uBAAuB,OAAO,MAAM;AAC5D,MAAI,cAAc,WAAW;AAC3B,WAAO;AAAA,EACT;AACA,MAAI,CAAC,OAAO,SAAS,QAAQ,GAAG;AAC9B,WAAO;AAAA,EACT;AACA,SAAO,wBAAU,MAAM,KAAK,IAAI,QAAS,GAAG,KAAK,eAAe;AAClE;AAEA,SAAS,uBAAuB,OAAe,QAAwB;AACrE,QAAM,YAAY,wBAAU;AAAA,IAC1B,KAAK,IAAI,OAAO,SAAS,KAAK,IAAI,QAAQ,gBAAgB;AAAA,IAC1D;AAAA,IACA;AAAA,EACF;AACA,QAAM,aAAa,wBAAU;AAAA,IAC3B,KAAK,IAAI,OAAO,SAAS,MAAM,IAAI,SAAS,gBAAgB;AAAA,IAC5D;AAAA,IACA;AAAA,EACF;AACA,QAAM,eAAe,KAAK;AAAA,IACxB;AAAA,IACA,KAAK,IAAI,wBAAU,SAAS,SAAS,IAAI,CAAC;AAAA,IAC1C,KAAK,IAAI,wBAAU,SAAS,UAAU,IAAI,CAAC;AAAA,EAC7C;AACA,UAAQ,kBAAkB,0BAA0B;AACtD;AAEA,SAAS,iBAAiB,WAAmB,cAA8B;AACzE,QAAM,mBAAmB,wBAAU,MAAM,cAAc,GAAG,GAAG;AAC7D,SACE,KAAK,IAAI,wBAAU,SAAS,SAAS,IAAI,CAAC,IAC1C,KAAK,IAAI,wBAAU,SAAS,gBAAgB,IAAI,CAAC;AAErD;AAEA,SAAS,wBAAwB,UAAuC;AACtE,QAAM,UAAU,sBAAsB,QAAQ,EAAE,UAAU;AAC1D,QAAM,SAAS,QAAQ,MAAM,EAAE,OAAO;AACtC,QAAM,QAAQ,wBAAU,SAAS,SAAS,KAAK;AAC/C,QAAM,MAAM,wBAAU,SAAS,SAAS,GAAG;AAC3C,QAAM,UAAU,IAAI;AAAA,IAClB,CAAC,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,GAAG;AAAA,IAC/B,KAAK,IAAI,KAAK;AAAA,IACd,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,GAAG;AAAA,EAChC,EAAE,UAAU;AACZ,QAAM,aAAa,QAAQ,MAAM,EAAE,MAAM,MAAM,EAAE,UAAU;AAC3D,QAAM,QAAQ,IAAI,sBAAQ,EAAE,UAAU,YAAY,SAAS,MAAM;AACjE,SAAO,IAAI,yBAAW,EAAE,sBAAsB,KAAK;AACrD;AAEA,SAAS,qBACP,IACA,UACA,OACyB;AACzB,SAAO;AAAA,IACL;AAAA,IACA,UAAU,sBAAsB,QAAQ;AAAA,IACxC,QAAQ;AAAA,IACR,aAAa,MAAM;AAAA,EACrB;AACF;AAEA,SAAS,gBAAgB,GAAoB,GAA4B;AACvE,QAAM,UAAU,sBAAsB,CAAC;AACvC,QAAM,UAAU,sBAAsB,CAAC;AACvC,SAAO,wBAAU,SAAS,QAAQ,QAAQ,OAAO,CAAC;AACpD;AAGO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,kBAAkB;AAAA,EAClB;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,eAAe;AAAA,EACf,WAAW;AAAA,EACX,cAAc;AAAA,EACd,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAuB;AACrB,QAAM,kBAAc,2BAAW,mBAAmB;AAClD,QAAM,eAAW,uBAAiB,IAAI;AACtC,QAAM,mBAAe,uBAAyB,IAAI;AAClD,QAAM,2BAAuB,uBAAO,KAAK;AACzC,QAAM,qBAAqB,sBAAsB,QAAQ;AACzD,QAAM,YACJ,uBAAuB,oBACnB,EAAE,aAAa,qBAAqB,WAAW,kBAAkB,IACjE,uBAAuB,IAAI;AACjC,QAAM,EAAE,aAAAC,cAAa,UAAU,IAAI;AACnC,QAAM,gBAAgB,aAAa,KAAK;AACxC,QAAM,cAAc,QAAQ;AAC5B,QAAM,eAAe,SAAS;AAC9B,QAAM,mBAAmB;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,oBAAgB;AAAA,IACpB,MAAM,sBAAsB,oBAAoB,gBAAgB;AAAA,IAChE,CAAC,mBAAmB,OAAO,mBAAmB,KAAK,gBAAgB;AAAA,EACrE;AACA,QAAMC,yBAAoB;AAAA,IACxB,MAAM,wBAAwB,kBAAkB;AAAA,IAChD,CAAC,mBAAmB,OAAO,mBAAmB,GAAG;AAAA,EACnD;AACA,QAAM,aAAa,uBAAuB,aAAa,gBAAgB;AACvE,QAAM,cAAc,uBAAuB,cAAc,gBAAgB;AACzE,QAAM,oBAAgB,wBAAQ,MAAM;AAClC,UAAM,gBAAgB,IAAI,4BAAc,GAAG,CAAC;AAC5C,UAAM,WAAW,IAAI,4BAAc,aAAa;AAChD,kBAAc,QAAQ;AACtB,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AACL,QAAM,UAAU,wBAAwB;AAAA,IACtC;AAAA,IACA;AAAA,IACA,YAAY,WAAW,eAAe,UAClC,CAAC,UAAU;AACT,cAAQ;AAAA,QACN;AAAA,QACA,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,aAAa;AAAA,MACf,CAAC;AAAA,IACH,IACA;AAAA,EACN,CAAC;AAED;AAAA,IACE,MAAM,MAAM;AACV,mBAAa,SAAS,uBAAuB;AAC7C,mBAAa,UAAU;AAAA,IACzB;AAAA,IACA,CAAC;AAAA,EACH;AAEA,gCAAU,MAAM,MAAM,cAAc,QAAQ,GAAG,CAAC,aAAa,CAAC;AAE9D,+BAAS,CAAC,EAAE,OAAO,MAAM;AACvB,QAAI,CAAC,SAAS,SAAS;AACrB;AAAA,IACF;AACA,QAAID,iBAAgB,aAAa;AAC/B,eAAS,QAAQ,WAAW,KAAK,OAAO,UAAU;AAAA,IACpD,OAAO;AACL,eAAS,QAAQ,WAAW,KAAKC,kBAAiB;AAAA,IACpD;AACA,aAAS,QAAQ;AAAA,MACf;AAAA,MACA,wBAAU,SAAS,CAAC,QAAQ;AAAA,IAC9B;AACA,UAAM,cACJ,cAAc,WAAW,kBAAkB,kCACvC,iBAAiB,OAAO,KAAK,YAAY,IACzC;AACN,aAAS,QAAQ,MAAM;AAAA,OACpB,kBAAkB,aAAa,KAAK;AAAA,OACpC,kBAAkB,cAAc,KAAK;AAAA,MACtC;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,mBAAmB,CAAC,UAAiD;AACzE,UAAM,gBAAgB;AACtB,UAAM,YAAY,2BAA2B;AAAA,EAC/C;AAEA,QAAM,iBAAiB,CACrB,OACA,gBACG;AACH,UAAM,YAAY,aAAa;AAC/B,QAAI,CAAC,aAAa,UAAU,cAAc,MAAM,WAAW;AACzD;AAAA,IACF;AAEA,qBAAiB,KAAK;AACtB,UAAM,SAAS,MAAM;AACrB,QAAI,OAAO,oBAAoB,MAAM,SAAS,GAAG;AAC/C,aAAO,wBAAwB,MAAM,SAAS;AAAA,IAChD;AACA,UAAM,eAAe,sBAAsB,MAAM,IAAI,SAAS;AAC9D,QAAI,aAAa;AACf,kBAAY;AAAA,QACV,GAAG,qBAAqB,IAAI,cAAc,KAAK;AAAA,QAC/C,QAAQ;AAAA,QACR,eAAe,UAAU;AAAA,MAC3B,CAAC;AAAA,IACH;AACA,yBAAqB,UAAU,UAAU;AACzC,cAAU,uBAAuB;AACjC,iBAAa,UAAU;AAAA,EACzB;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,UAAU;AAAA,MACV;AAAA,MACA,OAAO,CAAC,YAAY,aAAa,CAAC;AAAA,MAClC;AAAA,MACA,SAAS,cAAc,CAAC,UAAU;AAChC,yBAAiB,KAAK;AACtB,YAAI,CAAC,qBAAqB,SAAS;AACjC,oBAAU,qBAAqB,IAAI,oBAAoB,KAAK,CAAC;AAAA,QAC/D;AACA,6BAAqB,UAAU;AAAA,MACjC,IAAI;AAAA,MACJ,sBAAsB,cAAc,CAAC,UAAU,eAAe,OAAO,KAAK,IAAI;AAAA,MAC9E,iBAAiB,cAAc,CAAC,UAAU,eAAe,OAAO,KAAK,IAAI;AAAA,MACzE,eAAe,cAAc,CAAC,UAAU;AACtC,yBAAiB,KAAK;AACtB,YAAI,CAAC,aAAa,aAAa,SAAS;AACtC;AAAA,QACF;AACA,cAAM,yBACJ,aAAa,SAAS,uBAAuB,MAAM,MAAM;AAC3D,cAAM,SAAS,MAAM;AACrB,eAAO,oBAAoB,MAAM,SAAS;AAC1C,cAAM,gBAAgB,EAAE,GAAG,mBAAmB;AAC9C,qBAAa,UAAU;AAAA,UACrB,WAAW,MAAM;AAAA,UACjB;AAAA,UACA;AAAA,UACA,OAAO;AAAA,QACT;AACA,sBAAc;AAAA,UACZ,GAAG,qBAAqB,IAAI,eAAe,KAAK;AAAA,UAChD,QAAQ;AAAA,UACR;AAAA,QACF,CAAC;AAAA,MACH,IAAI;AAAA,MACJ,eAAe,cAAc,CAAC,UAAU;AACtC,cAAM,YAAY,aAAa;AAC/B,YAAI,CAAC,aAAa,UAAU,cAAc,MAAM,WAAW;AACzD;AAAA,QACF;AACA,yBAAiB,KAAK;AACtB,cAAM,eAAe,sBAAsB,MAAM,IAAI,SAAS;AAC9D,kBAAU,UAAV,UAAU,QACR,gBAAgB,UAAU,eAAe,YAAY,IACrD;AACF,2BAAmB;AAAA,UACjB,GAAG,qBAAqB,IAAI,cAAc,KAAK;AAAA,UAC/C,QAAQ;AAAA,UACR,eAAe,UAAU;AAAA,QAC3B,CAAC;AAAA,MACH,IAAI;AAAA,MACJ,cAAc,cAAc,CAAC,UAAU;AACrC,YAAI,CAAC,aAAa,SAAS;AACzB;AAAA,YACE;AAAA,YACA,qBAAqB,IAAI,oBAAoB,KAAK;AAAA,UACpD;AAAA,QACF;AAAA,MACF,IAAI;AAAA,MACJ,eAAe,cAAc,CAAC,UAAU;AACtC,YAAI,CAAC,aAAa,SAAS;AACzB;AAAA,YACE;AAAA,YACA,qBAAqB,IAAI,oBAAoB,KAAK;AAAA,UACpD;AAAA,QACF;AAAA,MACF,IAAI;AAAA,MACJ,aAAa,cAAc,CAAC,UAAU,eAAe,OAAO,IAAI,IAAI;AAAA,MAEnE;AAAA,kBAAW,gBACV;AAAA,UAAC;AAAA;AAAA,YACC,UAAU;AAAA,YACV,UAAU,CAAC,GAAG,GAAG,IAAI;AAAA,YACrB,aAAa,cAAc;AAAA,YAC3B,OAAO,CAAC,MAAM,MAAM,CAAC;AAAA,YAErB,uDAAC,uBAAkB,OAAM,WAAU,WAAW,OAAO;AAAA;AAAA,QACvD,IACG;AAAA,QACJ;AAAA;AAAA;AAAA,EACH;AAEJ;;;AD7RM,IAAAC,uBAAA;AAnFN,SAAS,aAAa,SAAqC;AACzD,MAAI,CAAC,OAAO,SAAS,OAAO,GAAG;AAC7B,WAAO;AAAA,EACT;AACA,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,SAAU,CAAC,CAAC;AAC1C;AAEA,SAAS,uBACP,KACA,QACA,SACA;AACA,QAAM,SAAK,yBAAS,CAAC,UAAU,MAAM,EAAE;AACvC,QAAM,CAAC,SAAS,UAAU,QAAI,yBAAyB,IAAI;AAC3D,QAAM,gBAAY,uBAAO,MAAM;AAC/B,QAAM,iBAAa,uBAAO,OAAO;AACjC,YAAU,UAAU;AACpB,aAAW,UAAU;AAErB,gCAAU,MAAM;AACd,QAAI,SAAS;AACb,eAAW,IAAI;AACf,QAAI,CAAC,KAAK;AACR,aAAO,MAAM;AACX,iBAAS;AAAA,MACX;AAAA,IACF;AAEA,UAAM,SAAS,IAAI,6BAAc;AACjC,WAAO;AAAA,MACL;AAAA,MACA,CAAC,kBAAkB;AACjB,YAAI,CAAC,QAAQ;AACX,wBAAc,QAAQ;AACtB;AAAA,QACF;AACA,sBAAc,aAAa;AAC3B,sBAAc,QAAQ;AACtB,sBAAc,QAAQ;AACtB,sBAAc,YAAY;AAC1B,sBAAc,YAAY;AAC1B,sBAAc,kBAAkB;AAChC,sBAAc,aAAa,GAAG,aAAa,iBAAiB;AAC5D,sBAAc,cAAc;AAC5B,mBAAW,aAAa;AACxB,kBAAU,UAAU,aAAa;AAAA,MACnC;AAAA,MACA;AAAA,MACA,CAAC,UAAU;AACT,YAAI,QAAQ;AACV,qBAAW,UAAU,KAAK;AAAA,QAC5B;AAAA,MACF;AAAA,IACF;AAEA,WAAO,MAAM;AACX,eAAS;AAAA,IACX;AAAA,EACF,GAAG,CAAC,IAAI,GAAG,CAAC;AAEZ;AAAA,IACE,MAAM,MAAM;AACV,eAAS,QAAQ;AAAA,IACnB;AAAA,IACA,CAAC,OAAO;AAAA,EACV;AAEA,SAAO;AACT;AAEO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA,QAAQ;AAAA,EACR,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAsB;AACpB,QAAM,UAAU,uBAAuB,KAAK,QAAQ,OAAO;AAE3D,SACE,8CAAC,iBAAe,GAAG,aAAa,QAAgB,OAC9C,yDAAC,UACC;AAAA,kDAAC,mBAAc,MAAM,CAAC,GAAG,CAAC,GAAG;AAAA,IAC7B;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,SAAS,UAAU,aAAa,OAAO,IAAI;AAAA,QAC3C,MAAM;AAAA,QACN,YAAY;AAAA,QACZ,aAAW;AAAA;AAAA,IACb;AAAA,KACF,GACF;AAEJ;;;AEnHA,IAAAC,iBAAyB;AACzB,IAAAC,iBAA2C;AAC3C,IAAAC,iBAUO;AACP,mBAAsB;AACtB,0BAA6B;AAC7B,0BAA6B;AA2dzB,IAAAC,uBAAA;AA3cJ,IAAM,iBAAiB;AACvB,IAAM,2BAA2B;AAmDjC,SAAS,cAAc,UAAgD;AACrE,SAAO,SAAS,IAAI,CAAC,WAAW,sBAAsB,MAAM,CAAC;AAC/D;AAEO,SAAS,sBACd,UACmB;AACnB,QAAM,YAA+B,CAAC;AACtC,aAAW,UAAU,UAAU;AAC7B,UAAM,aAAa,sBAAsB,MAAM;AAC/C,UAAM,WAAW,UAAU,UAAU,SAAS,CAAC;AAC/C,QAAI,CAAC,UAAU;AACb,gBAAU,KAAK,EAAE,GAAG,YAAY,cAAc,WAAW,IAAI,CAAC;AAC9D;AAAA,IACF;AACA,UAAM,cAAc,SAAS;AAC7B,QAAI,MAAM,WAAW;AACrB,WAAO,MAAM,cAAc,IAAK,QAAO;AACvC,WAAO,MAAM,eAAe,KAAM,QAAO;AACzC,cAAU,KAAK,EAAE,GAAG,YAAY,cAAc,IAAI,CAAC;AAAA,EACrD;AACA,SAAO;AACT;AAEA,SAAS,YAAY,GAAY,GAAY,GAAoB;AAC/D,UAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;AAC5D;AAEA,SAAS,WAAW,GAAY,GAAY,GAAY,GAAqB;AAC3E,QAAM,MAAM,YAAY,GAAG,GAAG,CAAC;AAC/B,QAAM,MAAM,YAAY,GAAG,GAAG,CAAC;AAC/B,QAAM,MAAM,YAAY,GAAG,GAAG,CAAC;AAC/B,QAAM,MAAM,YAAY,GAAG,GAAG,CAAC;AAC/B,SACE,KAAK,KAAK,GAAG,MAAM,KAAK,KAAK,GAAG,KAChC,KAAK,KAAK,GAAG,MAAM,KAAK,KAAK,GAAG;AAEpC;AAEA,SAAS,oBAAoB,UAAsC;AACjE,QAAM,SAAS,SAAS;AAAA,IAAI,CAAC,WAC3B,IAAI,uBAAQ,OAAO,cAAc,OAAO,KAAK;AAAA,EAC/C;AACA,WAAS,QAAQ,GAAG,QAAQ,OAAO,QAAQ,SAAS,GAAG;AACrD,UAAM,aAAa,QAAQ,KAAK,OAAO;AACvC,aAAS,QAAQ,QAAQ,GAAG,QAAQ,OAAO,QAAQ,SAAS,GAAG;AAC7D,YAAM,aAAa,QAAQ,KAAK,OAAO;AACvC,UACE,UAAU,SACV,cAAc,SACd,cAAc,SACb,UAAU,KAAK,cAAc,GAC9B;AACA;AAAA,MACF;AACA,UAAI,WAAW,OAAO,KAAK,GAAI,OAAO,SAAS,GAAI,OAAO,KAAK,GAAI,OAAO,SAAS,CAAE,GAAG;AACtF,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,yBACP,UACA,WACS;AACT,MAAI,UAAU;AACd,WAAS,QAAQ,GAAG,QAAQ,SAAS,QAAQ,SAAS,GAAG;AACvD,UAAM,IAAI,sBAAsB,SAAS,KAAK,CAAE,EAAE,UAAU;AAC5D,UAAM,IAAI,sBAAsB,UAAU,QAAQ,KAAK,SAAS,MAAM,CAAE,EAAE,UAAU;AACpF,UAAM,aAAa,EAAE,MAAM,EAAE,gBAAgB,WAAW,CAAC,EAAE,IAAI,SAAS,CAAC;AACzE,UAAM,aAAa,EAAE,MAAM,EAAE,gBAAgB,WAAW,CAAC,EAAE,IAAI,SAAS,CAAC;AACzE,QAAI,WAAW,SAAS,IAAI,QAAQ,WAAW,SAAS,IAAI,MAAM;AAChE,aAAO;AAAA,IACT;AACA,eAAW,UAAU;AACrB,eAAW,UAAU;AACrB,eAAW,KAAK;AAAA,MACd,UAAU,IAAI,WAAW,MAAM,EAAE,MAAM,UAAU,CAAC;AAAA,MAClD,WAAW,IAAI,UAAU;AAAA,IAC3B;AAAA,EACF;AACA,SAAO,KAAK,IAAI,OAAO,IAAI,KAAK;AAClC;AAEA,SAAS,eAAe,UAAsC;AAC5D,QAAM,aAAa,SAAS,IAAI,CAAC,WAAW,sBAAsB,MAAM,EAAE,UAAU,CAAC;AACrF,QAAM,aAAa,CAAC,IAAI,uBAAQ,CAAC;AACjC,aAAW,aAAa,YAAY;AAClC,eAAW,CAAC,EAAG,IAAI,SAAS;AAC5B,eAAW,KAAK,UAAU,MAAM,CAAC;AAAA,EACnC;AACA,WAAS,QAAQ,GAAG,QAAQ,WAAW,QAAQ,SAAS,GAAG;AACzD,aAAS,QAAQ,QAAQ,GAAG,QAAQ,WAAW,QAAQ,SAAS,GAAG;AACjE,iBAAW,KAAK,WAAW,KAAK,EAAG,MAAM,EAAE,IAAI,WAAW,KAAK,CAAE,CAAC;AAAA,IACpE;AAAA,EACF;AACA,SAAO,WAAW;AAAA,IAAK,CAAC,cACtB,UAAU,SAAS,IAAI,QACvB,WAAW,MAAM,CAAC,cAAc,UAAU,IAAI,SAAS,IAAI,IAAI;AAAA,EACjE;AACF;AAEO,SAAS,wBACd,UAC0B;AAC1B,MAAI,SAAS,SAAS,GAAG;AACvB,WAAO,CAAC,EAAE,MAAM,oBAAoB,SAAS,2CAA2C,CAAC;AAAA,EAC3F;AACA,QAAM,aAAa,cAAc,QAAQ;AACzC,QAAM,YAAY,sBAAsB,UAAU;AAClD,QAAM,SAAmC,CAAC;AAC1C,MAAI,oBAAoB,SAAS,GAAG;AAClC,WAAO,KAAK,EAAE,MAAM,qBAAqB,SAAS,8BAA8B,CAAC;AAAA,EACnF;AACA,MACE,yBAAyB,YAAY,IAAI,uBAAQ,GAAG,GAAG,CAAC,CAAC,KACzD,yBAAyB,YAAY,IAAI,uBAAQ,GAAG,IAAI,CAAC,CAAC,GAC1D;AACA,WAAO,KAAK,EAAE,MAAM,iBAAiB,SAAS,2CAA2C,CAAC;AAAA,EAC5F;AACA,MAAI,CAAC,eAAe,UAAU,GAAG;AAC/B,WAAO,KAAK,EAAE,MAAM,sBAAsB,SAAS,2CAA2C,CAAC;AAAA,EACjG;AACA,SAAO;AACT;AAEA,SAAS,cAAc,UAA8C;AACnE,QAAM,MAAM,SAAS;AAAA,IACnB,CAAC,OAAO,WAAW,MAAM,IAAI,sBAAsB,MAAM,EAAE,UAAU,CAAC;AAAA,IACtE,IAAI,uBAAQ;AAAA,EACd;AACA,SAAO,IAAI,SAAS,IAAI,OACpB,sBAAsB,GAAG,IACzB,sBAAsB,SAAS,CAAC,CAAE;AACxC;AAEA,SAAS,kBAAkB,UAAuC;AAChE,QAAM,UAAU,sBAAsB,QAAQ,EAAE,UAAU;AAC1D,QAAM,SAAS,QAAQ,MAAM,EAAE,OAAO;AACtC,QAAM,QAAS,SAAS,QAAQ,KAAK,KAAM;AAC3C,QAAM,MAAO,SAAS,MAAM,KAAK,KAAM;AACvC,QAAM,UAAU,IAAI;AAAA,IAClB,CAAC,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,GAAG;AAAA,IAC/B,KAAK,IAAI,KAAK;AAAA,IACd,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,GAAG;AAAA,EAChC,EAAE,UAAU;AACZ,SAAO,IAAI,0BAAW,EAAE;AAAA,IACtB,IAAI,uBAAQ,EAAE,UAAU,QAAQ,MAAM,EAAE,MAAM,MAAM,EAAE,UAAU,GAAG,SAAS,MAAM;AAAA,EACpF;AACF;AAEA,SAAS,iBAAiB,QAAkC;AAC1D,SAAO,IAAI,uBAAQ,EAChB;AAAA,IACC,sBAAsB,QAAQ,cAAc;AAAA,IAC5C,kBAAkB,MAAM;AAAA,IACxB,IAAI,uBAAQ,GAAG,GAAG,CAAC;AAAA,EACrB,EACC,OAAO;AACZ;AAEA,SAAS,eACP,GACA,GACA,GACA,SACA,SACA,QACA,cACS;AACT,QAAM,UAAU,IAAI,UAAU;AAC9B,SAAO;AAAA,IACL;AAAA,MACE,KAAK,EAAE,eAAe,UAAU,EAAE,eAAe,UAAU,EAAE,eAAe;AAAA,MAC5E,OAAO,EAAE,QAAQ,UAAU,EAAE,QAAQ,UAAU,EAAE,QAAQ;AAAA,IAC3D;AAAA,IACA;AAAA,EACF,EAAE,aAAa,YAAY;AAC7B;AAEA,SAAS,wBAAwB,UAAqC;AACpE,MAAI,WAAW;AACf,WAAS,QAAQ,GAAG,QAAQ,SAAS,QAAQ,SAAS,GAAG;AACvD,UAAM,QAAQ,sBAAsB,SAAS,KAAK,CAAE,EAAE,UAAU;AAChE,aAAS,QAAQ,QAAQ,GAAG,QAAQ,SAAS,QAAQ,SAAS,GAAG;AAC/D,iBAAW,KAAK;AAAA,QACd;AAAA,QACA,MAAM,QAAQ,sBAAsB,SAAS,KAAK,CAAE,EAAE,UAAU,CAAC;AAAA,MACnE;AAAA,IACF;AAAA,EACF;AACA,SAAO,KAAK;AAAA,IACV;AAAA,IACA,KAAK,IAAI,GAAG,KAAK,KAAM,WAAW,MAAO,KAAK,KAAK,wBAAwB,CAAC;AAAA,EAC9E;AACF;AAEA,SAAS,sBACP,WACA,SACA,GACA,GACA,GACA,cACA,OACM;AACN,QAAM,OAAO,oBAAI,IAAoB;AACrC,QAAM,aAAa,CAAC,GAAW,MAAc;AAC3C,UAAM,MAAM,GAAG,CAAC,IAAI,CAAC;AACrB,UAAM,WAAW,KAAK,IAAI,GAAG;AAC7B,QAAI,aAAa,OAAW,QAAO;AACnC,UAAM,QAAQ,eAAe,GAAG,GAAG,GAAG,IAAI,OAAO,IAAI,OAAO,gBAAgB,YAAY;AACxF,UAAM,QAAQ,UAAU,SAAS;AACjC,cAAU,KAAK,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AACxC,SAAK,IAAI,KAAK,KAAK;AACnB,WAAO;AAAA,EACT;AACA,WAAS,IAAI,GAAG,KAAK,OAAO,KAAK,GAAG;AAClC,aAAS,IAAI,GAAG,KAAK,QAAQ,GAAG,KAAK,EAAG,YAAW,GAAG,CAAC;AAAA,EACzD;AACA,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK,GAAG;AACjC,aAAS,IAAI,GAAG,IAAI,QAAQ,GAAG,KAAK,GAAG;AACrC,cAAQ,KAAK,WAAW,GAAG,CAAC,GAAG,WAAW,IAAI,GAAG,CAAC,GAAG,WAAW,GAAG,IAAI,CAAC,CAAC;AACzE,UAAI,IAAI,IAAI,QAAQ,GAAG;AACrB,gBAAQ,KAAK,WAAW,IAAI,GAAG,CAAC,GAAG,WAAW,IAAI,GAAG,IAAI,CAAC,GAAG,WAAW,GAAG,IAAI,CAAC,CAAC;AAAA,MACnF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,UAA6B,QAAyC;AAC9F,QAAM,YAAY,sBAAsB,QAAQ;AAChD,QAAM,UAAU,UAAU,IAAI,CAAC,WAAW,IAAI,uBAAQ,OAAO,cAAc,OAAO,KAAK,CAAC;AACxF,QAAM,YAAY,0BAAW,iBAAiB,SAAS,CAAC,CAAC;AACzD,QAAM,YAAsB,CAAC;AAC7B,QAAM,UAAoB,CAAC;AAC3B,QAAM,eAAe,iBAAiB,MAAM;AAC5C,QAAM,QAAQ,wBAAwB,QAAQ;AAC9C,aAAW,CAAC,GAAG,GAAG,CAAC,KAAK,WAAW;AACjC;AAAA,MACE;AAAA,MACA;AAAA,MACA,UAAU,CAAC;AAAA,MACX,UAAU,CAAC;AAAA,MACX,UAAU,CAAC;AAAA,MACX;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,SAAO,IAAI,8BAAe,EACvB,aAAa,YAAY,IAAI,sCAAuB,WAAW,CAAC,CAAC,EACjE,SAAS,OAAO;AACrB;AAEA,SAAS,oBACP,UACA,QACU;AACV,QAAM,YAAsB,CAAC;AAC7B,QAAM,eAAe,iBAAiB,MAAM;AAC5C,QAAM,YAAY,sBAAsB,QAAQ;AAChD,QAAM,QAAQ,wBAAwB,QAAQ;AAE9C,WAAS,OAAO,GAAG,OAAO,UAAU,QAAQ,QAAQ,GAAG;AACrD,UAAM,QAAQ,UAAU,IAAI;AAC5B,UAAM,MAAM,WAAW,OAAO,KAAK,UAAU,MAAM;AAKnD,aAAS,OAAO,GAAG,OAAO,OAAO,QAAQ,GAAG;AAC1C,YAAM,WAAW,OAAO;AACxB,YAAM,QAAQ;AAAA,QACZ;AAAA,UACE,KAAK,MAAM,gBAAgB,IAAI,eAAe,MAAM,gBAAgB;AAAA,UACpE,OAAO,MAAM,SAAS,IAAI,QAAQ,MAAM,SAAS;AAAA,QACnD;AAAA,QACA;AAAA,MACF,EACC,aAAa,YAAY;AAC1B,gBAAU,KAAK,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAAA,IAC1C;AAAA,EACF;AACA,YAAU,KAAK,GAAG,UAAU,MAAM,GAAG,CAAC,CAAC;AACvC,SAAO;AACT;AAEA,SAAS,eACP,WACA,OACA,OACA,SACO;AACP,QAAM,WAAW,IAAI,iCAAa;AAClC,WAAS,aAAa,SAAS;AAC/B,QAAM,WAAW,IAAI,iCAAa;AAAA,IAChC;AAAA,IACA,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,WAAW,KAAK,IAAI,KAAK,KAAK;AAAA,IAC9B;AAAA,IACA,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,iBAAiB;AAAA,EACnB,CAAC;AACD,QAAM,OAAO,IAAI,mBAAM,UAAU,QAAQ;AACzC,OAAK,qBAAqB;AAC1B,SAAO;AACT;AAEA,SAAS,kBAAkB,MAA0B;AACnD,MAAI,CAAC,KAAM;AACX,OAAK,SAAS,QAAQ;AACtB,EAAC,KAAK,SAA0B,QAAQ;AAC1C;AAEA,SAAS,kBACP,UACA,MACA,IACmB;AACnB,QAAM,YAAY,iBAAiB,GAAG,MAAM,KAAK,GAAG;AACpD,QAAM,cAAc,GAAG,QAAQ,KAAK;AACpC,SAAO,SAAS,IAAI,CAAC,YAAY;AAAA,IAC/B,KAAK,iBAAiB,OAAO,MAAM,SAAS;AAAA,IAC5C,OAAO,eAAe,OAAO,QAAQ,WAAW;AAAA,EAClD,EAAE;AACJ;AAEO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,cAAc;AAAA,EACd,SAAS;AAAA,EACT,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,cAAc;AAAA,EACd,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAwB;AACtB,QAAM,SAAK,yBAAS,CAAC,UAAU,MAAM,EAAE;AACvC,QAAM,WAAO,yBAAS,CAAC,UAAU,MAAM,IAAI;AAC3C,QAAM,aAAS,wBAAQ,MAAM,wBAAwB,QAAQ,GAAG,CAAC,QAAQ,CAAC;AAC1E,QAAM,QAAQ,OAAO,WAAW;AAChC,QAAM,aAAS,wBAAQ,MAAM,QAAQ,cAAc,QAAQ,IAAI,MAAM,CAAC,OAAO,QAAQ,CAAC;AACtF,QAAM,mBAAe;AAAA,IACnB,MAAM,SAAS,SAAS,iBAAiB,UAAU,MAAM,IAAI;AAAA,IAC7D,CAAC,QAAQ,OAAO,QAAQ;AAAA,EAC1B;AACA,QAAM,sBAAkB;AAAA,IACtB,MAAM,SAAS,SAAS,oBAAoB,UAAU,MAAM,IAAI;AAAA,IAChE,CAAC,QAAQ,OAAO,QAAQ;AAAA,EAC1B;AACA,QAAM,wBAAwB,KAAK,IAAI,GAAG,KAAK,IAAI,eAAe,CAAC,CAAC;AACpE,QAAM,mBAAmB,GAAG,cAAc;AAC1C,QAAM,iBAAa;AAAA,IACjB,MAAM,kBACF,eAAe,iBAAiB,QAAQ,cAAc,kBAAkB,qBAAqB,IAC7F;AAAA,IACJ,CAAC,kBAAkB,uBAAuB,QAAQ,iBAAiB,WAAW;AAAA,EAChF;AACA,QAAM,sBAAkB;AAAA,IACtB,MAAM,kBACF,eAAe,iBAAiB,YAAY,cAAc,KAAK,kBAAkB,CAAC,IAClF;AAAA,IACJ,CAAC,kBAAkB,iBAAiB,WAAW;AAAA,EACjD;AACA,QAAM,uBAAmB,uBAAiC,IAAI;AAC9D,QAAM,YAAY,OAAO,IAAI,CAAC,UAAU,MAAM,IAAI,EAAE,KAAK,GAAG;AAE5D,gCAAU,MAAM;AACd,QAAI,CAAC,MAAO,aAAY,MAAM;AAAA,EAChC,GAAG,CAAC,QAAQ,WAAW,WAAW,KAAK,CAAC;AACxC,gCAAU,MAAM,MAAM,cAAc,QAAQ,GAAG,CAAC,YAAY,CAAC;AAC7D,gCAAU,MAAM,MAAM,kBAAkB,UAAU,GAAG,CAAC,UAAU,CAAC;AACjE,gCAAU,MAAM,MAAM,kBAAkB,eAAe,GAAG,CAAC,eAAe,CAAC;AAC3E,gCAAU,MAAM;AACd,UAAM,QAAQ,GAAG,WAAW;AAC5B,UAAM,SAAS,GAAG,WAAW;AAC7B,eAAW,QAAQ,CAAC,YAAY,eAAe,GAAG;AAChD,UAAI,KAAM,CAAC,KAAK,SAA0B,WAAW,IAAI,OAAO,MAAM;AAAA,IACxE;AAAA,EACF,GAAG,CAAC,iBAAiB,IAAI,KAAK,QAAQ,KAAK,OAAO,UAAU,CAAC;AAE7D,MAAI,CAAC,SAAS,CAAC,UAAU,CAAC,gBAAgB,CAAC,cAAc,CAAC,gBAAiB,QAAO;AAElF,QAAM,qBAAqB,CAAC,OAAyB,aAA2D;AAC9G,UAAM,gBAAgB,iBAAiB,WAAW,cAAc,QAAQ;AACxE,UAAM,eAAe,kBAAkB,eAAe,MAAM,eAAe,MAAM,QAAQ;AACzF,eAAW;AAAA,MACT;AAAA,MACA,UAAU;AAAA,MACV;AAAA,MACA,UAAU,MAAM;AAAA,MAChB,eAAe,MAAM;AAAA,IACvB,CAAC;AAAA,EACH;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ;AAAA,MACA,UAAU;AAAA,MACV,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,mBAAkB;AAAA,MAClB,UAAU;AAAA,MACV,qBAAoB;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA,iBAAiB;AAAA,MACjB,cACE,8CAAC,eAAU,QAAQ,iBAAiB,aAAa,cAAc,GAAG;AAAA,MAEpE,aAAa,CAAC,UAAU;AACtB,yBAAiB,UAAU,cAAc,QAAQ;AACjD,2BAAmB,OAAO,WAAW;AAAA,MACvC;AAAA,MACA,kBAAkB,CAAC,UAAU,mBAAmB,OAAO,gBAAgB;AAAA,MACvE,WAAW,CAAC,UAAU;AACpB,2BAAmB,OAAO,SAAS;AACnC,yBAAiB,UAAU;AAAA,MAC7B;AAAA,MAEA;AAAA,sDAAC,UAAK,UAAU,cAAc,aAC5B;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,YACP,YAAY;AAAA,YACZ,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,aAAa,CAAC,CAAC;AAAA,YAC7C,MAAM;AAAA,YACN,aAAW;AAAA;AAAA,QACb,GACF;AAAA,QACA,8CAAC,eAAU,QAAQ,YAAY,aAAa,cAAc,GAAG;AAAA;AAAA;AAAA,EAC/D;AAEJ;;;AChhBA,IAAAC,iBAAyB;AACzB,IAAAC,iBAA2C;AAC3C,IAAAC,iBAMO;AACP,IAAAC,gBAAsB;AACtB,IAAAC,uBAA6B;AAC7B,IAAAC,uBAA6B;AA6RT,IAAAC,uBAAA;AA9QpB,IAAM,kBAAkB;AACxB,IAAM,sBAAsB;AA0C5B,SAASC,eAAc,UAAgD;AACrE,SAAO,SAAS,IAAI,CAAC,WAAW,sBAAsB,MAAM,CAAC;AAC/D;AAEA,SAAS,eAAe,UAAgD;AACtE,QAAM,YAA+B,CAAC;AACtC,aAAW,UAAU,UAAU;AAC7B,UAAM,aAAa,sBAAsB,MAAM;AAC/C,UAAM,WAAW,UAAU,UAAU,SAAS,CAAC;AAC/C,QAAI,CAAC,UAAU;AACb,gBAAU,KAAK,EAAE,GAAG,YAAY,cAAc,WAAW,IAAI,CAAC;AAC9D;AAAA,IACF;AACA,QAAI,MAAM,WAAW;AACrB,WAAO,MAAM,SAAS,eAAe,IAAK,QAAO;AACjD,WAAO,MAAM,SAAS,gBAAgB,KAAM,QAAO;AACnD,cAAU,KAAK,EAAE,GAAG,YAAY,cAAc,IAAI,CAAC;AAAA,EACrD;AACA,SAAO;AACT;AAEA,SAAS,eAAe,UAA8C;AACpE,QAAM,MAAM,SAAS;AAAA,IACnB,CAAC,OAAO,WAAW,MAAM,IAAI,sBAAsB,MAAM,EAAE,UAAU,CAAC;AAAA,IACtE,IAAI,uBAAQ;AAAA,EACd;AACA,SAAO,IAAI,SAAS,IAAI,OACpB,sBAAsB,GAAG,IACzB,sBAAsB,SAAS,CAAC,CAAE;AACxC;AAEA,SAASC,mBAAkB,UAAuC;AAChE,QAAM,UAAU,sBAAsB,QAAQ,EAAE,UAAU;AAC1D,QAAM,SAAS,QAAQ,MAAM,EAAE,OAAO;AACtC,QAAM,QAAQ,yBAAU,SAAS,SAAS,KAAK;AAC/C,QAAM,MAAM,yBAAU,SAAS,SAAS,GAAG;AAC3C,QAAM,UAAU,IAAI;AAAA,IAClB,CAAC,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,GAAG;AAAA,IAC/B,KAAK,IAAI,KAAK;AAAA,IACd,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,GAAG;AAAA,EAChC,EAAE,UAAU;AACZ,SAAO,IAAI,0BAAW,EAAE;AAAA,IACtB,IAAI,uBAAQ,EAAE,UAAU,QAAQ,MAAM,EAAE,MAAM,MAAM,EAAE,UAAU,GAAG,SAAS,MAAM;AAAA,EACpF;AACF;AAEA,SAASC,kBAAiB,QAAkC;AAC1D,SAAO,IAAI,uBAAQ,EAChB;AAAA,IACC,sBAAsB,QAAQ,eAAe;AAAA,IAC7CD,mBAAkB,MAAM;AAAA,IACxB,IAAI,uBAAQ,GAAG,GAAG,CAAC;AAAA,EACrB,EACC,OAAO;AACZ;AAEA,SAAS,iBAAiB,UAAqC;AAC7D,MAAI,WAAW;AACf,WAAS,QAAQ,GAAG,QAAQ,SAAS,SAAS,GAAG,SAAS,GAAG;AAC3D,eAAW,KAAK;AAAA,MACd;AAAA,MACA,sBAAsB,SAAS,KAAK,CAAE,EAAE;AAAA,QACtC,sBAAsB,SAAS,QAAQ,CAAC,CAAE;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AACA,SAAO,KAAK;AAAA,IACV;AAAA,IACA,KAAK,IAAI,GAAG,KAAK,KAAM,yBAAU,SAAS,QAAQ,IAAK,mBAAmB,CAAC;AAAA,EAC7E;AACF;AAEA,SAAS,kBAAkB,UAA6B,QAAmC;AACzF,QAAM,YAAsB,CAAC;AAC7B,QAAM,eAAeC,kBAAiB,MAAM;AAC5C,QAAM,YAAY,eAAe,QAAQ;AACzC,QAAM,QAAQ,iBAAiB,QAAQ;AAEvC,WAAS,OAAO,GAAG,OAAO,UAAU,SAAS,GAAG,QAAQ,GAAG;AACzD,UAAM,QAAQ,UAAU,IAAI;AAC5B,UAAM,MAAM,UAAU,OAAO,CAAC;AAC9B,aAAS,OAAO,GAAG,OAAO,OAAO,QAAQ,GAAG;AAC1C,YAAM,WAAW,OAAO;AACxB,YAAM,QAAQ;AAAA,QACZ;AAAA,UACE,KAAK,MAAM,gBAAgB,IAAI,eAAe,MAAM,gBAAgB;AAAA,UACpE,OAAO,MAAM,SAAS,IAAI,QAAQ,MAAM,SAAS;AAAA,QACnD;AAAA,QACA;AAAA,MACF,EAAE,aAAa,YAAY;AAC3B,gBAAU,KAAK,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAAA,IAC1C;AAAA,EACF;AAEA,QAAM,OAAO,UAAU,UAAU,SAAS,CAAC;AAC3C,QAAM,YAAY,sBAAsB,MAAM,eAAe,EAAE,aAAa,YAAY;AACxF,YAAU,KAAK,UAAU,GAAG,UAAU,GAAG,UAAU,CAAC;AACpD,SAAO;AACT;AAEA,SAAS,SACP,WACA,OACA,OACA,SACO;AACP,QAAM,WAAW,IAAI,kCAAa;AAClC,WAAS,aAAa,SAAS;AAC/B,QAAM,WAAW,IAAI,kCAAa;AAAA,IAChC;AAAA,IACA,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,WAAW,KAAK,IAAI,KAAK,KAAK;AAAA,IAC9B;AAAA,IACA,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,iBAAiB;AAAA,EACnB,CAAC;AACD,QAAM,OAAO,IAAI,oBAAM,UAAU,QAAQ;AACzC,OAAK,qBAAqB;AAC1B,SAAO;AACT;AAEA,SAAS,YAAY,MAA0B;AAC7C,MAAI,CAAC,KAAM;AACX,OAAK,SAAS,QAAQ;AACtB,EAAC,KAAK,SAA0B,QAAQ;AAC1C;AAEA,SAASC,mBACP,UACA,MACA,IACmB;AACnB,QAAM,YAAY,iBAAiB,GAAG,MAAM,KAAK,GAAG;AACpD,QAAM,cAAc,GAAG,QAAQ,KAAK;AACpC,SAAO,SAAS,IAAI,CAAC,YAAY;AAAA,IAC/B,KAAK,iBAAiB,OAAO,MAAM,SAAS;AAAA,IAC5C,OAAO,eAAe,OAAO,QAAQ,WAAW;AAAA,EAClD,EAAE;AACJ;AAEO,SAAS,yBACd,UAC2B;AAC3B,SAAO,SAAS,SAAS,IACrB,CAAC,EAAE,MAAM,oBAAoB,SAAS,0CAA0C,CAAC,IACjF,CAAC;AACP;AAEO,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAyB;AACvB,QAAM,SAAK,yBAAS,CAAC,UAAU,MAAM,EAAE;AACvC,QAAM,WAAO,yBAAS,CAAC,UAAU,MAAM,IAAI;AAC3C,QAAM,aAAS,wBAAQ,MAAM,yBAAyB,QAAQ,GAAG,CAAC,QAAQ,CAAC;AAC3E,QAAM,QAAQ,OAAO,WAAW;AAChC,QAAM,aAAS,wBAAQ,MAAM,QAAQ,eAAe,QAAQ,IAAI,MAAM,CAAC,OAAO,QAAQ,CAAC;AACvF,QAAM,oBAAgB;AAAA,IACpB,MAAM,SAAS,SAAS,kBAAkB,UAAU,MAAM,IAAI;AAAA,IAC9D,CAAC,QAAQ,OAAO,QAAQ;AAAA,EAC1B;AACA,QAAM,mBAAmB,GAAG,cAAc;AAC1C,QAAM,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,eAAe,CAAC,CAAC;AACtD,QAAM,WAAO;AAAA,IACX,MAAM,gBAAgB,SAAS,eAAe,QAAQ,cAAc,kBAAkB,OAAO,IAAI;AAAA,IACjG,CAAC,kBAAkB,eAAe,SAAS,QAAQ,WAAW;AAAA,EAChE;AACA,QAAM,gBAAY;AAAA,IAChB,MAAM,gBAAgB,SAAS,eAAe,YAAY,cAAc,KAAK,kBAAkB,CAAC,IAAI;AAAA,IACpG,CAAC,kBAAkB,eAAe,WAAW;AAAA,EAC/C;AACA,QAAM,uBAAmB,uBAAiC,IAAI;AAE9D,gCAAU,MAAM;AACd,QAAI,CAAC,MAAO,aAAY,MAAM;AAAA,EAChC,GAAG,CAAC,QAAQ,WAAW,KAAK,CAAC;AAC7B,gCAAU,MAAM,MAAM,YAAY,IAAI,GAAG,CAAC,IAAI,CAAC;AAC/C,gCAAU,MAAM,MAAM,YAAY,SAAS,GAAG,CAAC,SAAS,CAAC;AACzD,gCAAU,MAAM;AACd,UAAM,QAAQ,GAAG,WAAW;AAC5B,UAAM,SAAS,GAAG,WAAW;AAC7B,eAAW,YAAY,CAAC,MAAM,SAAS,GAAG;AACxC,UAAI,SAAU,CAAC,SAAS,SAA0B,WAAW,IAAI,OAAO,MAAM;AAAA,IAChF;AAAA,EACF,GAAG,CAAC,WAAW,IAAI,MAAM,KAAK,QAAQ,KAAK,KAAK,CAAC;AAEjD,MAAI,CAAC,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC,UAAW,QAAO;AAErD,QAAM,qBAAqB,CACzB,OACA,aACG;AACH,UAAM,gBAAgB,iBAAiB,WAAWH,eAAc,QAAQ;AACxE,eAAW;AAAA,MACT;AAAA,MACA,UAAUG,mBAAkB,eAAe,MAAM,eAAe,MAAM,QAAQ;AAAA,MAC9E;AAAA,MACA,UAAU,MAAM;AAAA,MAChB,eAAe,MAAM;AAAA,IACvB,CAAC;AAAA,EACH;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ;AAAA,MACA,UAAU;AAAA,MACV,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,mBAAkB;AAAA,MAClB,UAAU;AAAA,MACV,qBAAoB;AAAA,MACpB;AAAA,MACA;AAAA,MACA,iBAAiB;AAAA,MACjB,cAAc,8CAAC,eAAU,QAAQ,WAAW,aAAa,cAAc,GAAG;AAAA,MAC1E,aAAa,CAAC,UAAU;AACtB,yBAAiB,UAAUH,eAAc,QAAQ;AACjD,2BAAmB,OAAO,WAAW;AAAA,MACvC;AAAA,MACA,kBAAkB,CAAC,UAAU,mBAAmB,OAAO,gBAAgB;AAAA,MACvE,WAAW,CAAC,UAAU;AACpB,2BAAmB,OAAO,SAAS;AACnC,yBAAiB,UAAU;AAAA,MAC7B;AAAA,MAEA,wDAAC,eAAU,QAAQ,MAAM,aAAa,cAAc,GAAG;AAAA;AAAA,EACzD;AAEJ;;;ACtTA,IAAAI,iBAA4C;AAC5C,IAAAC,iBAQO;AAiWD,IAAAC,uBAAA;AA5VN,IAAM,uBAAuB;AAmE7B,SAASC,cAAa,SAAqC;AACzD,MAAI,CAAC,OAAO,SAAS,OAAO,GAAG;AAC7B,WAAO;AAAA,EACT;AACA,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,SAAU,CAAC,CAAC;AAC1C;AAEA,SAAS,mBAAmB,OAAmC;AAC7D,SAAO,OAAO,SAAS,KAAK,IAAI,KAAK,IAAI,OAAQ,CAAC,IAAI;AACxD;AAEA,SAAS,oBAAoB,OAAmC;AAC9D,SAAO,OAAO,SAAS,KAAK,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,OAAQ,GAAG,CAAC,IAAI;AACvE;AAEA,SAAS,qBACP,SACA,GACA,GACA,OACA,QACA,aACA,aACA,cACA;AACA,QAAM,kBAAkB,OAAO,SAAS,WAAW,KAAK,cAAc,IAAI,cAAc;AACxF,QAAM,mBAAmB,OAAO,SAAS,YAAY,KAAK,eAAe,IAAI,eAAe;AAC5F,QAAM,YAAY,KAAK,IAAI,iBAAiB,gBAAgB;AAC5D,QAAM,kBAAkB,oBAAoB,WAAW;AACvD,QAAM,UAAU,KAAK,IAAI,QAAQ,GAAI,QAAQ,kBAAkB,YAAa,eAAe;AAC3F,QAAM,UAAU,KAAK,IAAI,SAAS,GAAI,SAAS,kBAAkB,YAAa,gBAAgB;AAE9F,UAAQ,UAAU;AAClB,UAAQ,OAAO,IAAI,SAAS,CAAC;AAC7B,UAAQ,OAAO,IAAI,QAAQ,SAAS,CAAC;AACrC,UAAQ,QAAQ,IAAI,QAAQ,SAAS,IAAI,SAAS,SAAS,SAAS,GAAG,CAAC,KAAK,KAAK,GAAG,CAAC;AACtF,UAAQ,OAAO,IAAI,OAAO,IAAI,SAAS,OAAO;AAC9C,UAAQ,QAAQ,IAAI,QAAQ,SAAS,IAAI,SAAS,SAAS,SAAS,SAAS,GAAG,GAAG,KAAK,KAAK,CAAC;AAC9F,UAAQ,OAAO,IAAI,SAAS,IAAI,MAAM;AACtC,UAAQ,QAAQ,IAAI,SAAS,IAAI,SAAS,SAAS,SAAS,SAAS,GAAG,KAAK,KAAK,GAAG,KAAK,EAAE;AAC5F,UAAQ,OAAO,GAAG,IAAI,OAAO;AAC7B,UAAQ,QAAQ,IAAI,SAAS,IAAI,SAAS,SAAS,SAAS,GAAG,KAAK,IAAI,KAAK,KAAK,GAAG;AACrF,UAAQ,UAAU;AACpB;AAEA,SAAS,YACP,SACA,QACA;AACA,UAAQ,UAAU;AAClB,UAAQ,OAAO,OAAO,CAAC,EAAG,CAAC,GAAG,OAAO,CAAC,EAAG,CAAC,CAAC;AAC3C,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,MAAM,CAAC,GAAG;AACpC,YAAQ,OAAO,GAAG,CAAC;AAAA,EACrB;AACA,UAAQ,UAAU;AACpB;AAEA,SAAS,UACP,SACA,SACA,MACA;AACA,MAAI,QAAQ,MAAM;AAChB,YAAQ,YAAY,QAAQ;AAC5B,WAAO,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK;AAAA,EAC3C;AACA,MAAI,QAAQ,QAAQ;AAClB,YAAQ,cAAc,QAAQ;AAC9B,YAAQ,YAAY,mBAAmB,QAAQ,WAAW;AAC1D,WAAO,QAAQ,OAAO,IAAI,IAAI,QAAQ,OAAO;AAAA,EAC/C;AACF;AAEA,SAAS,YACP,SACA,SACA,aACA,cACA;AACA,QAAM,UAAU,KAAK,IAAI,mBAAmB,QAAQ,WAAW,IAAI,IAAI,GAAG,CAAC;AAC3E,QAAM,eAAe,uBAAuB,UAAU;AAEtD,UAAQ,UAAU,GAAG,GAAG,sBAAsB,oBAAoB;AAClE,UAAQ,WAAW;AACnB,UAAQ,UAAU;AAElB,MAAI,QAAQ,SAAS,UAAU;AAC7B,YAAQ,UAAU;AAClB,YAAQ;AAAA,MACN,uBAAuB;AAAA,MACvB,uBAAuB;AAAA,MACvB,eAAe;AAAA,MACf;AAAA,MACA,KAAK,KAAK;AAAA,IACZ;AACA,cAAU,SAAS,OAAO;AAC1B;AAAA,EACF;AAEA,MAAI,QAAQ,SAAS,YAAY;AAC/B,UAAM,SAAS,uBAAuB;AACtC,gBAAY,SAAS;AAAA,MACnB,CAAC,QAAQ,OAAO;AAAA,MAChB,CAAC,UAAU,cAAc,UAAU,YAAY;AAAA,MAC/C,CAAC,SAAS,UAAU,YAAY;AAAA,IAClC,CAAC;AACD,cAAU,SAAS,OAAO;AAC1B;AAAA,EACF;AAEA,MAAI,QAAQ,SAAS,WAAW;AAC9B,UAAM,SAAS,uBAAuB;AACtC,gBAAY,SAAS;AAAA,MACnB,CAAC,QAAQ,OAAO;AAAA,MAChB,CAAC,UAAU,cAAc,MAAM;AAAA,MAC/B,CAAC,QAAQ,UAAU,YAAY;AAAA,MAC/B,CAAC,SAAS,MAAM;AAAA,IAClB,CAAC;AACD,cAAU,SAAS,OAAO;AAC1B;AAAA,EACF;AAEA,MAAI,QAAQ,SAAS,QAAQ;AAC3B,UAAM,SAAS,uBAAuB;AACtC,UAAM,cAAc,eAAe;AACnC,UAAM,cAAc,cAAc;AAClC,UAAM,SAAkC,CAAC;AACzC,aAAS,QAAQ,GAAG,QAAQ,IAAI,SAAS,GAAG;AAC1C,YAAM,QAAQ,CAAC,KAAK,KAAK,IAAK,QAAQ,KAAK,KAAM;AACjD,YAAM,SAAS,QAAQ,MAAM,IAAI,cAAc;AAC/C,aAAO,KAAK;AAAA,QACV,SAAS,KAAK,IAAI,KAAK,IAAI;AAAA,QAC3B,SAAS,KAAK,IAAI,KAAK,IAAI;AAAA,MAC7B,CAAC;AAAA,IACH;AACA,gBAAY,SAAS,MAAM;AAC3B,cAAU,SAAS,OAAO;AAC1B;AAAA,EACF;AAEA,MAAI,QAAQ,SAAS,SAAS;AAC5B,UAAM,SAAS,uBAAuB;AACtC,UAAM,MAAM;AACZ,UAAM,SAAS,UAAU;AACzB,UAAM,aAAa,MAAM,eAAe;AACxC,UAAM,gBAAgB,eAAe;AACrC,UAAM,gBAAgB,eAAe;AACrC,gBAAY,SAAS;AAAA,MACnB,CAAC,QAAQ,GAAG;AAAA,MACZ,CAAC,SAAS,eAAe,UAAU;AAAA,MACnC,CAAC,SAAS,eAAe,UAAU;AAAA,MACnC,CAAC,SAAS,eAAe,MAAM;AAAA,MAC/B,CAAC,SAAS,eAAe,MAAM;AAAA,MAC/B,CAAC,SAAS,eAAe,UAAU;AAAA,MACnC,CAAC,SAAS,eAAe,UAAU;AAAA,IACrC,CAAC;AACD,cAAU,SAAS,OAAO;AAC1B;AAAA,EACF;AAEA,MAAI,QAAQ,SAAS,aAAa;AAChC;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,gBAAgB;AAAA,MACxB;AAAA,MACA;AAAA,IACF;AACA,cAAU,SAAS,OAAO;AAC1B;AAAA,EACF;AAEA,MAAI,QAAQ,SAAS,QAAQ;AAC3B,UAAM,SAAS,uBAAuB;AACtC,UAAM,cAAc,eAAe;AACnC,UAAM,cAAc,KAAK;AAAA,MACvB;AAAA,MACA,KAAK,IAAI,cAAc,IAAI,QAAQ,eAAe,QAAQ,WAAW;AAAA,IACvE;AACA,YAAQ,UAAU;AAClB,YAAQ,IAAI,QAAQ,QAAQ,aAAa,GAAG,KAAK,KAAK,CAAC;AACvD,YAAQ,OAAO,SAAS,aAAa,MAAM;AAC3C,YAAQ,IAAI,QAAQ,QAAQ,aAAa,GAAG,KAAK,KAAK,GAAG,IAAI;AAC7D,QAAI,QAAQ,QAAQ,QAAQ,QAAQ;AAClC,cAAQ,YAAY,QAAQ,QAAQ,QAAQ,UAAU;AACtD,cAAQ,KAAK,SAAS;AAAA,IACxB;AACA,QAAI,QAAQ,QAAQ;AAClB,cAAQ,cAAc,QAAQ;AAC9B,cAAQ,YAAY,mBAAmB,QAAQ,WAAW;AAC1D,cAAQ,OAAO;AAAA,IACjB;AACA;AAAA,EACF;AAEA,QAAM,CAAC,GAAG,GAAG,OAAO,MAAM,IAAI,QAAQ;AACtC,MAAI,CAAC,OAAO,SAAS,KAAK,KAAK,CAAC,OAAO,SAAS,MAAM,KAAK,SAAS,KAAK,UAAU,GAAG;AACpF,UAAM,IAAI,MAAM,yDAAyD;AAAA,EAC3E;AACA,QAAM,OAAO,IAAI,OAAO,QAAQ,IAAI;AACpC,UAAQ,KAAK;AACb,UAAQ,UAAU,SAAS,OAAO;AAClC,UAAQ,MAAM,eAAe,OAAO,eAAe,MAAM;AACzD,UAAQ,UAAU,CAAC,GAAG,CAAC,CAAC;AACxB,YAAU,SAAS,SAAS,IAAI;AAChC,UAAQ,QAAQ;AAClB;AAEA,SAAS,qBACP,SACA,aACA,cACe;AACf,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,SAAO,QAAQ;AACf,SAAO,SAAS;AAChB,QAAM,UAAU,OAAO,WAAW,IAAI;AACtC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,oDAAoD;AAAA,EACtE;AACA,cAAY,SAAS,SAAS,aAAa,YAAY;AAEvD,QAAM,UAAU,IAAI,6BAAc,MAAM;AACxC,UAAQ,aAAa;AACrB,UAAQ,QAAQ;AAChB,UAAQ,QAAQ;AAChB,UAAQ,YAAY;AACpB,UAAQ,YAAY;AACpB,UAAQ,kBAAkB;AAC1B,UAAQ,cAAc;AACtB,SAAO;AACT;AAEA,SAAS,kBACP,SACA,aACA,cACA,QACA,SACA;AACA,QAAM,CAAC,SAAS,UAAU,QAAI,yBAA+B,IAAI;AACjE,QAAM,gBAAY,uBAAO,MAAM;AAC/B,QAAM,iBAAa,uBAAO,OAAO;AACjC,YAAU,UAAU;AACpB,aAAW,UAAU;AAErB,gCAAU,MAAM;AACd,QAAI,cAAoC;AACxC,QAAI;AACF,oBAAc,qBAAqB,SAAS,aAAa,YAAY;AACrE,iBAAW,WAAW;AACtB,gBAAU,UAAU,WAAW;AAAA,IACjC,SAAS,OAAO;AACd,iBAAW,IAAI;AACf,iBAAW,UAAU,KAAK;AAAA,IAC5B;AAEA,WAAO,MAAM;AACX,mBAAa,QAAQ;AAAA,IACvB;AAAA,EACF,GAAG,CAAC,cAAc,aAAa,OAAO,CAAC;AAEvC,SAAO;AACT;AAEA,SAAS,qBAAqB;AAAA,EAC5B;AAAA,EACA,QAAQ;AAAA,EACR,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAA8E;AAC5E,QAAM,UAAU,kBAAkB,SAAS,OAAO,QAAQ,QAAQ,OAAO;AAEzE,SACE,8CAAC,iBAAe,GAAG,aAAa,QAAgB,OAC9C,yDAAC,UACC;AAAA,kDAAC,mBAAc,MAAM,CAAC,GAAG,CAAC,GAAG;AAAA,IAC7B;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,SAAS,UAAUA,cAAa,OAAO,IAAI;AAAA,QAC3C,MAAM;AAAA,QACN,YAAY;AAAA,QACZ,aAAW;AAAA;AAAA,IACb;AAAA,KACF,GACF;AAEJ;AAEO,SAAS,eAAe,OAA4B;AACzD,QAAM,EAAE,SAAS,GAAG,UAAU,IAAI;AAClC,MAAI,QAAQ,SAAS,OAAO;AAC1B,UAAM,aAAa;AACnB,WAAO,8CAAC,gBAAc,GAAG,YAAY,KAAK,QAAQ,KAAK;AAAA,EACzD;AAEA,SAAO,8CAAC,wBAAsB,GAAG,WAAW,SAAkB;AAChE;;;AChYA,IAAAC,iBAAmC;AACnC,IAAAC,iBAA4C;AAC5C,IAAAC,iBAQO;AAoPD,IAAAC,uBAAA;AAhPN,IAAM,uBAAuB;AAyC7B,SAASC,cAAa,SAAqC;AACzD,MAAI,CAAC,OAAO,SAAS,OAAO,GAAG;AAC7B,WAAO;AAAA,EACT;AACA,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,SAAU,CAAC,CAAC;AAC1C;AAEA,SAAS,WAAW,OAAmC;AACrD,SAAO,OAAO,SAAS,KAAK,KAAK,QAAS,IAAI,QAAS;AACzD;AAEA,SAAS,kBAAkB,OAAuB;AAChD,SAAO,OAAO,SAAS,KAAK,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC,IAAI;AACnE;AAEA,SAAS,iBAAiB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA4E;AAC1E,QAAM,SAAK,yBAAS,CAAC,UAAU,MAAM,EAAE;AACvC,QAAM,CAAC,SAAS,UAAU,QAAI,yBAAyB,IAAI;AAC3D,QAAM,iBAAa,uBAAO,OAAO;AACjC,QAAM,wBAAoB,uBAAO,cAAc;AAC/C,aAAW,UAAU;AACrB,oBAAkB,UAAU;AAE5B,gCAAU,MAAM;AACd,QAAI,SAAS;AACb,eAAW,IAAI;AACf,QAAI,CAAC,KAAK;AACR,wBAAkB,UAAU,EAAE,IAAI,OAAO,GAAG,QAAQ,GAAG,QAAQ,EAAE,CAAC;AAClE,aAAO,MAAM;AACX,iBAAS;AAAA,MACX;AAAA,IACF;AAEA,UAAM,SAAS,IAAI,6BAAc;AACjC,WAAO;AAAA,MACL;AAAA,MACA,CAAC,kBAAkB;AACjB,YAAI,CAAC,QAAQ;AACX,wBAAc,QAAQ;AACtB;AAAA,QACF;AACA,sBAAc,aAAa;AAC3B,sBAAc,QAAQ;AACtB,sBAAc,QAAQ;AACtB,sBAAc,YAAY;AAC1B,sBAAc,YAAY;AAC1B,sBAAc,kBAAkB;AAChC,sBAAc,aAAa,GAAG,aAAa,iBAAiB;AAC5D,sBAAc,cAAc;AAC5B,0BAAkB,UAAU,EAAE,IAAI,OAAO,GAAG,QAAQ,GAAG,QAAQ,EAAE,CAAC;AAClE,mBAAW,aAAa;AAAA,MAC1B;AAAA,MACA;AAAA,MACA,CAAC,UAAU;AACT,YAAI,CAAC,QAAQ;AACX;AAAA,QACF;AACA,0BAAkB,UAAU,EAAE,IAAI,OAAO,GAAG,QAAQ,GAAG,QAAQ,EAAE,CAAC;AAClE,mBAAW,UAAU,EAAE,IAAI,KAAK,MAAM,CAAC;AAAA,MACzC;AAAA,IACF;AAEA,WAAO,MAAM;AACX,eAAS;AAAA,IACX;AAAA,EACF,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC;AAEhB;AAAA,IACE,MAAM,MAAM;AACV,eAAS,QAAQ;AAAA,IACnB;AAAA,IACA,CAAC,OAAO;AAAA,EACV;AAEA,SAAO;AACT;AAEO,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAyB;AACvB,QAAM,UAAU,iBAAiB,EAAE,IAAI,KAAK,SAAS,eAAe,CAAC;AACrE,QAAM,aAAa,kBAAkB,mBAAmB;AACxD,QAAM,UAAU,WAAW,GAAG;AAC9B,QAAM,CAAC,YAAY,aAAa,QAAI,yBAAS,CAAC;AAC9C,QAAM,iBAAa,uBAAO,CAAC;AAC3B,QAAM,oBAAgB,uBAAO,CAAC;AAC9B,QAAM,eAAW,uBAAO,KAAK;AAC7B,QAAM,2BAAuB,uBAAqC,IAAI;AACtE,QAAM,uBAAmB,uBAAO,aAAa;AAC7C,QAAM,+BAA2B,uBAAO,qBAAqB;AAC7D,QAAM,iBAAa,uBAAO,OAAO;AACjC,mBAAiB,UAAU;AAC3B,2BAAyB,UAAU;AACnC,aAAW,UAAU;AAErB,gCAAU,MAAM;AACd,eAAW,UAAU;AACrB,kBAAc,UAAU;AACxB,aAAS,UAAU;AACnB,kBAAc,CAAC;AAAA,EACjB,GAAG,CAAC,YAAY,gBAAgB,GAAG,CAAC;AAEpC,gCAAU,MAAM;AACd,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AACA,YAAQ,OAAO;AAAA,MACb,mBAAmB,eAAe,IAAI,aAAa;AAAA,MACnD,mBAAmB,aAAa,IAAI,aAAa;AAAA,IACnD;AACA,YAAQ,OAAO;AAAA,MACb,mBAAmB,eAAe,aAAa,aAAa;AAAA,MAC5D,mBAAmB,aAAa,KAAK,aAAa,KAAK,aAAa;AAAA,IACtE;AACA,YAAQ,cAAc;AAAA,EACxB,GAAG,CAAC,YAAY,gBAAgB,YAAY,OAAO,CAAC;AAEpD,gCAAU,MAAM;AACd,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AACA,qBAAiB,UAAU,EAAE,IAAI,OAAO,GAAG,IAAI,CAAC;AAAA,EAClD,GAAG,CAAC,IAAI,KAAK,OAAO,CAAC;AAErB,gCAAU,MAAM;AACd,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AACA,QAAI,WAAW,SAAS,SAAS;AAC/B,iBAAW,UAAU;AACrB,oBAAc,UAAU;AACxB,eAAS,UAAU;AACnB,oBAAc,CAAC;AAAA,IACjB;AACA,QAAI,CAAC,WAAW,SAAS,SAAS;AAChC;AAAA,IACF;AACA,UAAM,YAAmC,UAAU,YAAY;AAC/D,QAAI,qBAAqB,YAAY,WAAW;AAC9C,2BAAqB,UAAU;AAC/B,+BAAyB,UAAU,SAAS;AAAA,IAC9C;AAAA,EACF,GAAG,CAAC,SAAS,OAAO,CAAC;AAErB,+BAAS,CAAC,GAAG,iBAAiB;AAC5B,QAAI,CAAC,WAAW,CAAC,WAAW,SAAS,SAAS;AAC5C;AAAA,IACF;AACA,eAAW,WAAW;AACtB,UAAM,QAAQ,KAAK,MAAM,WAAW,UAAU,OAAO;AACrD,QAAI,UAAU,GAAG;AACf;AAAA,IACF;AACA,eAAW,WAAW,QAAQ;AAE9B,QAAI,YAAY,cAAc,UAAU;AACxC,QAAI,aAAa,YAAY;AAC3B,UAAI,MAAM;AACR,qBAAa;AAAA,MACf,OAAO;AACL,oBAAY,aAAa;AACzB,iBAAS,UAAU;AACnB,YAAI,qBAAqB,YAAY,SAAS;AAC5C,+BAAqB,UAAU;AAC/B,mCAAyB,UAAU,OAAO;AAC1C,qBAAW,UAAU;AAAA,QACvB;AAAA,MACF;AAAA,IACF;AAEA,QAAI,cAAc,cAAc,SAAS;AACvC,oBAAc,UAAU;AACxB,oBAAc,SAAS;AACvB,uBAAiB,UAAU,EAAE,IAAI,OAAO,WAAW,IAAI,CAAC;AAAA,IAC1D;AAAA,EACF,CAAC;AAED,SACE,8CAAC,iBAAe,GAAG,aAAa,IAAQ,QAAgB,OACtD,yDAAC,UACC;AAAA,kDAAC,mBAAc,MAAM,CAAC,GAAG,CAAC,GAAG;AAAA,IAC7B;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,SAAS,UAAUA,cAAa,OAAO,IAAI;AAAA,QAC3C,MAAM;AAAA,QACN,YAAY;AAAA,QACZ,aAAW;AAAA;AAAA,IACb;AAAA,KACF,GACF;AAEJ;;;AC1QA,IAAAC,iBAAyB;AACzB,IAAAC,iBAA4C;AAC5C,IAAAC,iBASO;AAgSD,IAAAC,uBAAA;AA9PN,SAASC,cAAa,SAAqC;AACzD,MAAI,CAAC,OAAO,SAAS,OAAO,GAAG;AAC7B,WAAO;AAAA,EACT;AACA,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,SAAU,CAAC,CAAC;AAC1C;AAEA,SAAS,YAAY,QAAoC;AACvD,MAAI,CAAC,OAAO,SAAS,MAAM,GAAG;AAC5B,WAAO;AAAA,EACT;AACA,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,QAAS,CAAC,CAAC;AACzC;AAEA,SAAS,iBACP,IACA,QACA,SACA;AACA,QAAM,SAAK,yBAAS,CAAC,UAAU,MAAM,EAAE;AACvC,QAAM,CAAC,SAAS,UAAU,QAAI,yBAAyB,IAAI;AAC3D,QAAM,iBAAa,uBAAO,OAAO;AACjC,aAAW,UAAU;AAErB,gCAAU,MAAM;AACd,QAAI,SAAS;AACb,eAAW,IAAI;AACf,QAAI,CAAC,QAAQ;AACX,aAAO,MAAM;AACX,iBAAS;AAAA,MACX;AAAA,IACF;AAEA,UAAM,SAAS,IAAI,6BAAc;AACjC,WAAO;AAAA,MACL;AAAA,MACA,CAAC,kBAAkB;AACjB,YAAI,CAAC,QAAQ;AACX,wBAAc,QAAQ;AACtB;AAAA,QACF;AACA,sBAAc,aAAa;AAC3B,sBAAc,QAAQ;AACtB,sBAAc,QAAQ;AACtB,sBAAc,YAAY;AAC1B,sBAAc,YAAY;AAC1B,sBAAc,kBAAkB;AAChC,sBAAc,aAAa,GAAG,aAAa,iBAAiB;AAC5D,sBAAc,cAAc;AAC5B,mBAAW,aAAa;AAAA,MAC1B;AAAA,MACA;AAAA,MACA,CAAC,UAAU;AACT,YAAI,QAAQ;AACV,qBAAW,UAAU,EAAE,IAAI,QAAQ,UAAU,MAAM,CAAC;AAAA,QACtD;AAAA,MACF;AAAA,IACF;AAEA,WAAO,MAAM;AACX,eAAS;AAAA,IACX;AAAA,EACF,GAAG,CAAC,IAAI,IAAI,MAAM,CAAC;AAEnB;AAAA,IACE,MAAM,MAAM;AACV,eAAS,QAAQ;AAAA,IACnB;AAAA,IACA,CAAC,OAAO;AAAA,EACV;AAEA,SAAO;AACT;AAEA,SAAS,iBAAiB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAUG;AACD,QAAM,CAAC,UAAU,WAAW,QAAI,yBAA+B,IAAI;AACnE,QAAM,iBAAa,uBAAO,OAAO;AACjC,QAAM,iBAAa,uBAAO,OAAO;AACjC,QAAM,+BAA2B,uBAAO,qBAAqB;AAC7D,aAAW,UAAU;AACrB,aAAW,UAAU;AACrB,2BAAyB,UAAU;AAEnC,gCAAU,MAAM;AACd,QAAI,CAAC,KAAK;AACR,kBAAY,IAAI;AAChB;AAAA,IACF;AAEA,QAAI,SAAS;AACb,UAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,QAAI,gBAAgB,QAAW;AAC7B,YAAM,cAAc;AAAA,IACtB;AACA,UAAM,cAAc,eAAe;AACnC,UAAM,SAAS,UAAU;AACzB,UAAM,UAAU,IAAI,4BAAa,KAAK;AACtC,YAAQ,aAAa;AACrB,YAAQ,QAAQ;AAChB,YAAQ,QAAQ;AAChB,YAAQ,YAAY;AACpB,YAAQ,YAAY;AACpB,YAAQ,kBAAkB;AAE1B,UAAM,cAAc,CAAC,UAA8B;AACjD,UAAI,QAAQ;AACV,iCAAyB,UAAU,KAAK;AAAA,MAC1C;AAAA,IACF;AACA,UAAM,YAAY,MAAM;AACtB,UAAI,CAAC,QAAQ;AACX;AAAA,MACF;AACA;AAAA,QAAY,CAAC,YACX,SAAS,UAAU,QAAQ,EAAE,GAAG,SAAS,OAAO,KAAK,IAAI;AAAA,MAC3D;AAAA,IACF;AACA,UAAM,cAAc,MAAM;AACxB,UAAI,QAAQ;AACV,mBAAW,UAAU;AAAA,UACnB;AAAA,UACA,QAAQ;AAAA,UACR,OAAO,MAAM,SAAS,IAAI,MAAM,gCAAgC,GAAG,EAAE;AAAA,QACvE,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,cAAc,MAAM;AACxB,kBAAY,OAAO;AACnB,iBAAW,UAAU;AAAA,IACvB;AACA,UAAM,cAAc,MAAM,YAAY,QAAQ;AAC9C,UAAM,aAAa,MAAM,YAAY,SAAS;AAC9C,UAAM,iBAAiB,WAAW,SAAS;AAC3C,UAAM,iBAAiB,SAAS,WAAW;AAC3C,UAAM,iBAAiB,SAAS,WAAW;AAC3C,UAAM,iBAAiB,SAAS,WAAW;AAC3C,UAAM,iBAAiB,QAAQ,UAAU;AACzC,gBAAY,EAAE,OAAO,SAAS,OAAO,MAAM,CAAC;AAC5C,UAAM,MAAM;AACZ,UAAM,KAAK;AAEX,WAAO,MAAM;AACX,eAAS;AACT,YAAM,oBAAoB,WAAW,SAAS;AAC9C,YAAM,oBAAoB,SAAS,WAAW;AAC9C,YAAM,oBAAoB,SAAS,WAAW;AAC9C,YAAM,oBAAoB,SAAS,WAAW;AAC9C,YAAM,oBAAoB,QAAQ,UAAU;AAC5C,YAAM,MAAM;AACZ,YAAM,gBAAgB,KAAK;AAC3B,YAAM,KAAK;AACX,cAAQ,QAAQ;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,aAAa,IAAI,aAAa,QAAQ,GAAG,CAAC;AAE9C,SAAO;AACT;AAEO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,cAAc;AAAA,EACd,UAAU;AAAA,EACV;AAAA,EACA,QAAQ;AAAA,EACR,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAsB;AACpB,QAAM,WAAW,iBAAiB;AAAA,IAChC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,gBAAgB,iBAAiB,IAAI,QAAQ,OAAO;AAC1D,QAAM,yBAAqB,uBAAO,eAAe;AACjD,QAAM,+BAA2B,uBAAO,qBAAqB;AAC7D,qBAAmB,UAAU;AAC7B,2BAAyB,UAAU;AAEnC,gCAAU,MAAM;AACd,QAAI,CAAC,UAAU;AACb;AAAA,IACF;AACA,aAAS,MAAM,OAAO;AACtB,aAAS,MAAM,QAAQ;AACvB,aAAS,MAAM,SAAS,YAAY,MAAM;AAC1C,aAAS,MAAM,cAAc;AAC7B,aAAS,MAAM,UAAU;AAAA,EAC3B,GAAG,CAAC,MAAM,OAAO,aAAa,SAAS,UAAU,MAAM,CAAC;AAExD,gCAAU,MAAM;AACd,QAAI,CAAC,UAAU;AACb;AAAA,IACF;AACA,QAAI,SAAS;AACb,QAAI,CAAC,SAAS;AACZ,eAAS,MAAM,MAAM;AACrB,aAAO,MAAM;AACX,iBAAS;AAAA,MACX;AAAA,IACF;AAEA,SAAK,SAAS,MAAM,KAAK,EAAE,MAAM,CAAC,UAAmB;AACnD,UAAI,CAAC,QAAQ;AACX;AAAA,MACF;AACA,+BAAyB,UAAU,SAAS;AAC5C,yBAAmB,UAAU,KAAK;AAAA,IACpC,CAAC;AAED,WAAO,MAAM;AACX,eAAS;AAAA,IACX;AAAA,EACF,GAAG,CAAC,SAAS,QAAQ,CAAC;AAEtB,QAAM,gBAAgB,UAAU,QAAQ,SAAS,UAAU;AAE3D,SACE,8CAAC,iBAAe,GAAG,aAAa,IAAQ,QAAgB,OACtD,yDAAC,UACC;AAAA,kDAAC,mBAAc,MAAM,CAAC,GAAG,CAAC,GAAG;AAAA,IAC7B;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,SAAS,gBAAgBA,cAAa,OAAO,IAAI;AAAA,QACjD,MAAM;AAAA,QACN,YAAY;AAAA,QACZ,aAAW;AAAA;AAAA,IACb;AAAA,KACF,GACF;AAEJ;","names":["import_fiber","import_react","import_fiber","import_react","import_react","PanoramaViewRuntime","zoomDamping","import_react","import_fiber","import_react","import_fiber","import_react","DEFAULT_ROTATE_SPEED","DEFAULT_ZOOM_SPEED","resolveSpeed","import_react","import_jsx_runtime","overlay","import_fiber","import_react","import_fiber","import_react","import_three","import_three","import_jsx_runtime","import_fiber","import_react","DEFAULT_ROTATE_SPEED","resolveSpeed","import_jsx_runtime","PanoView","import_fiber","import_react","import_three","import_jsx_runtime","import_fiber","import_react","import_three","import_fiber","import_react","import_three","import_jsx_runtime","import_fiber","import_react","import_three","import_three","tileSize","levels","import_jsx_runtime","TileMesh","TileLayerMeshes","import_jsx_runtime","import_fiber","import_react","import_three","import_fiber","import_react","import_three","import_jsx_runtime","orientation","surfaceQuaternion","import_jsx_runtime","import_fiber","import_react","import_three","import_jsx_runtime","import_fiber","import_react","import_three","import_Line2","import_LineGeometry","import_LineMaterial","import_jsx_runtime","cloneVertices","surfaceQuaternion","makeWorldToLocal","translateVertices","import_react","import_three","import_jsx_runtime","clampOpacity","import_fiber","import_react","import_three","import_jsx_runtime","clampOpacity","import_fiber","import_react","import_three","import_jsx_runtime","clampOpacity"]}
|