{"version":3,"file":"index.cjs","sources":["../src/hooks/useWebgazer.ts","../src/context/WebgazerContext.ts","../src/hooks/useGazeTracking.ts","../src/hooks/useCalibration.ts","../src/hooks/useGazeElement.ts","../src/hooks/useGazeHeatmap.ts","../src/hooks/useGazeRecording.ts","../src/components/WebgazerProvider.tsx","../src/components/CalibrationScreen.tsx","../src/components/GazeElement.tsx","../src/components/HeatmapOverlay.tsx"],"sourcesContent":["/**\n * useWebgazer Hook\n * Main hook for initializing and controlling Webgazer eye tracking\n */\n\nimport { useState, useEffect, useCallback, useRef } from 'react';\nimport webgazer from '@webgazer-ts/core';\nimport type { \n  UseWebgazerOptions, \n  UseWebgazerReturn, \n  GazePrediction,\n  WebgazerInstance,\n  GazeCallback\n} from '../types';\n\nexport function useWebgazer(options: UseWebgazerOptions = {}): UseWebgazerReturn {\n  const {\n    autoStart = false,\n    tracker = 'TFFacemesh',\n    regression = 'ridge',\n    saveDataAcrossSessions = true,\n    showVideoPreview = false,\n    showFaceOverlay = false,\n    showFaceFeedbackBox = false,\n    showGazeDot = false,\n    applyKalmanFilter: useKalmanFilter = true,\n    onGaze,\n  } = options;\n\n  const [gazeData, setGazeData] = useState<GazePrediction | null>(null);\n  const [isRunning, setIsRunning] = useState(false);\n  const [calibrationCount, setCalibrationCount] = useState(0);\n  const webgazerRef = useRef<WebgazerInstance | null>(null);\n  const gazeListenerRef = useRef<GazeCallback | null>(null);\n\n  // Initialize Webgazer\n  useEffect(() => {\n    let mounted = true;\n\n    async function initialize() {\n      try {\n        if (!mounted) return;\n\n        webgazerRef.current = webgazer;\n\n        // Configure Webgazer\n        webgazer\n          .setTracker(tracker)\n          .setRegression(regression)\n          .saveDataAcrossSessions(saveDataAcrossSessions);\n\n        if (useKalmanFilter) {\n          webgazer.applyKalmanFilter(true);\n        }\n\n        // Set up gaze listener\n        gazeListenerRef.current = (data: GazePrediction | null, timestamp: number) => {\n          if (mounted) {\n            setGazeData(data);\n            if (onGaze) {\n              onGaze(data, timestamp);\n            }\n          }\n        };\n\n        webgazer.setGazeListener(gazeListenerRef.current);\n\n        // Update calibration count periodically\n        const intervalId = setInterval(() => {\n          if (mounted && webgazerRef.current) {\n            const points = webgazer.getStoredPoints();\n            // getStoredPoints returns [xArray, yArray], so count is length of either array\n            setCalibrationCount(points && points[0] ? points[0].length : 0);\n          }\n        }, 1000);\n\n        // Auto-start if requested\n        if (autoStart) {\n          await webgazer.begin();\n          setIsRunning(true);\n\n          // Apply video preview settings\n          if (showVideoPreview) {\n            webgazer.showVideoPreview(true);\n          }\n          if (showFaceOverlay) {\n            webgazer.showFaceOverlay(true);\n          }\n          if (showFaceFeedbackBox) {\n            webgazer.showFaceFeedbackBox(true);\n          }\n          if (showGazeDot) {\n            webgazer.showPredictionPoints(true);\n          }\n        }\n\n        return () => {\n          clearInterval(intervalId);\n        };\n      } catch (error) {\n        console.error('Failed to initialize Webgazer:', error);\n      }\n    }\n\n    initialize();\n\n    return () => {\n      mounted = false;\n      if (webgazerRef.current) {\n        webgazerRef.current.end();\n      }\n    };\n  }, []); // Only run once on mount\n\n  // Start tracking\n  const start = useCallback(async () => {\n    if (!webgazerRef.current) return;\n    \n    try {\n      await webgazerRef.current.begin();\n      setIsRunning(true);\n\n      if (showVideoPreview) {\n        webgazerRef.current.showVideoPreview(true);\n      }\n      if (showFaceOverlay) {\n        webgazerRef.current.showFaceOverlay(true);\n      }\n      if (showFaceFeedbackBox) {\n        webgazerRef.current.showFaceFeedbackBox(true);\n      }\n      if (showGazeDot) {\n        webgazerRef.current.showPredictionPoints(true);\n      }\n    } catch (error) {\n      console.error('Failed to start Webgazer:', error);\n    }\n  }, [showVideoPreview, showFaceOverlay, showFaceFeedbackBox, showGazeDot]);\n\n  // Stop tracking\n  const stop = useCallback(async () => {\n    if (!webgazerRef.current) return;\n    \n    try {\n      await webgazerRef.current.end();\n      setIsRunning(false);\n      setGazeData(null);\n    } catch (error) {\n      console.error('Failed to stop Webgazer:', error);\n    }\n  }, []);\n\n  // Pause tracking\n  const pause = useCallback(async () => {\n    if (!webgazerRef.current) return;\n    \n    try {\n      await webgazerRef.current.pause();\n      setIsRunning(false);\n    } catch (error) {\n      console.error('Failed to pause Webgazer:', error);\n    }\n  }, []);\n\n  // Resume tracking\n  const resume = useCallback(async () => {\n    if (!webgazerRef.current) return;\n    \n    try {\n      await webgazerRef.current.resume();\n      setIsRunning(true);\n    } catch (error) {\n      console.error('Failed to resume Webgazer:', error);\n    }\n  }, []);\n\n  // Clear calibration data\n  const clearData = useCallback(() => {\n    if (!webgazerRef.current) return;\n    \n    try {\n      webgazerRef.current.clearData();\n      setCalibrationCount(0);\n    } catch (error) {\n      console.error('Failed to clear data:', error);\n    }\n  }, []);\n\n  // Show video preview\n  const showVideo = useCallback(() => {\n    if (!webgazerRef.current) return;\n    \n    try {\n      webgazerRef.current.showVideoPreview(true);\n    } catch (error) {\n      console.error('Failed to show video:', error);\n    }\n  }, []);\n\n  // Hide video preview\n  const hideVideo = useCallback(() => {\n    if (!webgazerRef.current) return;\n    \n    try {\n      webgazerRef.current.showVideoPreview(false);\n    } catch (error) {\n      console.error('Failed to hide video:', error);\n    }\n  }, []);\n\n  // Configuration methods - expose Webgazer configuration API\n  const setTracker = useCallback((trackerName: string) => {\n    if (!webgazerRef.current) return;\n    try {\n      webgazerRef.current.setTracker(trackerName);\n    } catch (error) {\n      console.error('Failed to set tracker:', error);\n    }\n  }, []);\n\n  const setRegression = useCallback((regressionName: string) => {\n    if (!webgazerRef.current) return;\n    try {\n      webgazerRef.current.setRegression(regressionName);\n    } catch (error) {\n      console.error('Failed to set regression:', error);\n    }\n  }, []);\n\n  const showFaceOverlayToggle = useCallback((show: boolean) => {\n    if (!webgazerRef.current) return;\n    try {\n      webgazerRef.current.showFaceOverlay(show);\n    } catch (error) {\n      console.error('Failed to toggle face overlay:', error);\n    }\n  }, []);\n\n  const showFaceFeedbackBoxToggle = useCallback((show: boolean) => {\n    if (!webgazerRef.current) return;\n    try {\n      webgazerRef.current.showFaceFeedbackBox(show);\n    } catch (error) {\n      console.error('Failed to toggle face feedback box:', error);\n    }\n  }, []);\n\n  const showPredictionPoints = useCallback((show: boolean) => {\n    if (!webgazerRef.current) return;\n    try {\n      webgazerRef.current.showPredictionPoints(show);\n    } catch (error) {\n      console.error('Failed to toggle prediction points:', error);\n    }\n  }, []);\n\n  const setVideoViewerSize = useCallback((width: number, height: number) => {\n    if (!webgazerRef.current) return;\n    try {\n      webgazerRef.current.setVideoViewerSize(width, height);\n    } catch (error) {\n      console.error('Failed to set video viewer size:', error);\n    }\n  }, []);\n\n  const applyKalmanFilter = useCallback((apply: boolean) => {\n    if (!webgazerRef.current) return;\n    try {\n      webgazerRef.current.applyKalmanFilter(apply);\n    } catch (error) {\n      console.error('Failed to apply Kalman filter:', error);\n    }\n  }, []);\n\n  const recordScreenPosition = useCallback((x: number, y: number, eventType: 'click' | 'move' = 'click') => {\n    if (!webgazerRef.current) return;\n    try {\n      webgazerRef.current.recordScreenPosition(x, y, eventType);\n    } catch (error) {\n      console.error('Failed to record screen position:', error);\n    }\n  }, []);\n\n  const addMouseEventListeners = useCallback(() => {\n    if (!webgazerRef.current) return;\n    try {\n      webgazerRef.current.addMouseEventListeners();\n    } catch (error) {\n      console.error('Failed to add mouse event listeners:', error);\n    }\n  }, []);\n\n  const removeMouseEventListeners = useCallback(() => {\n    if (!webgazerRef.current) return;\n    try {\n      webgazerRef.current.removeMouseEventListeners();\n    } catch (error) {\n      console.error('Failed to remove mouse event listeners:', error);\n    }\n  }, []);\n\n  return {\n    // State\n    gazeData,\n    isRunning,\n    calibrationCount,\n    \n    // Core controls\n    start,\n    stop,\n    pause,\n    resume,\n    clearData,\n    \n    // Video controls\n    showVideo,\n    hideVideo,\n    \n    // Configuration\n    setTracker,\n    setRegression,\n    showFaceOverlay: showFaceOverlayToggle,\n    showFaceFeedbackBox: showFaceFeedbackBoxToggle,\n    showPredictionPoints,\n    setVideoViewerSize,\n    applyKalmanFilter,\n    \n    // Calibration controls\n    recordScreenPosition,\n    addMouseEventListeners,\n    removeMouseEventListeners,\n    \n    // Direct instance access for advanced use cases\n    webgazer: webgazerRef.current,\n  };\n}\n","/**\n * Webgazer React Context\n * Provides Webgazer instance and state across the component tree\n */\n\nimport { createContext, useContext } from 'react';\nimport type { GazePrediction } from '../types';\n\nexport interface WebgazerContextValue {\n  gazeData: GazePrediction | null;\n  isRunning: boolean;\n  calibrationCount: number;\n  isInitialized: boolean;\n}\n\nexport const WebgazerContext = createContext<WebgazerContextValue | null>(null);\n\nexport function useWebgazerContext() {\n  const context = useContext(WebgazerContext);\n  if (!context) {\n    throw new Error('useWebgazerContext must be used within WebgazerProvider');\n  }\n  return context;\n}\n","/**\n * useGazeTracking Hook\n * Simplified hook that just returns the current gaze data\n * Can be used within a WebgazerProvider\n */\n\nimport { useWebgazerContext } from '../context/WebgazerContext';\nimport type { GazePrediction } from '../types';\n\nexport function useGazeTracking(): GazePrediction | null {\n  const { gazeData } = useWebgazerContext();\n  return gazeData;\n}\n","/**\n * useCalibration Hook\n * Programmatic control over calibration process\n */\n\nimport { useState, useCallback, useRef, useEffect } from 'react';\nimport type { \n  UseCalibrationOptions, \n  UseCalibrationReturn,\n  CalibrationPoint,\n  CalibrationResult \n} from '../types';\n\nexport function useCalibration(options: UseCalibrationOptions = {}): UseCalibrationReturn {\n  const {\n    pointCount = 9,\n    pointDuration = 1000,\n    autoAdvance = true,\n    onComplete,\n    onPointComplete,\n  } = options;\n\n  const [isCalibrating, setIsCalibrating] = useState(false);\n  const [currentPointIndex, setCurrentPointIndex] = useState(-1);\n  const [points, setPoints] = useState<CalibrationPoint[]>([]);\n  // Use ReturnType<typeof setTimeout> for cross-platform compatibility\n  const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n  // Generate calibration points\n  const generatePoints = useCallback(() => {\n    const newPoints: CalibrationPoint[] = [];\n    const margin = 100;\n    const cols = 3;\n    const rows = Math.ceil(pointCount / cols);\n    \n    const width = window.innerWidth - margin * 2;\n    const height = window.innerHeight - margin * 2;\n    \n    for (let i = 0; i < pointCount; i++) {\n      const col = i % cols;\n      const row = Math.floor(i / cols);\n      \n      const x = margin + (width / (cols - 1)) * col;\n      const y = margin + (height / (rows - 1)) * row;\n      \n      newPoints.push({ x, y, index: i });\n    }\n    \n    return newPoints;\n  }, [pointCount]);\n\n  // Start calibration\n  const startCalibration = useCallback(() => {\n    setIsCalibrating(true);\n    setCurrentPointIndex(0);\n    setPoints(generatePoints());\n  }, [generatePoints]);\n\n  // Stop calibration\n  const stopCalibration = useCallback(() => {\n    setIsCalibrating(false);\n    setCurrentPointIndex(-1);\n    \n    if (timeoutRef.current) {\n      clearTimeout(timeoutRef.current);\n      timeoutRef.current = null;\n    }\n\n    const result: CalibrationResult = {\n      success: currentPointIndex >= pointCount,\n      pointsCalibrated: currentPointIndex + 1,\n    };\n\n    if (onComplete) {\n      onComplete(result);\n    }\n  }, [currentPointIndex, pointCount, onComplete]);\n\n  // Advance to next point\n  const nextPoint = useCallback(() => {\n    if (onPointComplete) {\n      onPointComplete(currentPointIndex);\n    }\n\n    if (currentPointIndex + 1 >= pointCount) {\n      // Calibration complete\n      stopCalibration();\n    } else {\n      setCurrentPointIndex(prev => prev + 1);\n    }\n  }, [currentPointIndex, pointCount, onPointComplete, stopCalibration]);\n\n  // Auto-advance after duration\n  useEffect(() => {\n    if (!isCalibrating || !autoAdvance || currentPointIndex < 0) {\n      return;\n    }\n\n    timeoutRef.current = setTimeout(() => {\n      nextPoint();\n    }, pointDuration);\n\n    return () => {\n      if (timeoutRef.current) {\n        clearTimeout(timeoutRef.current);\n      }\n    };\n  }, [isCalibrating, autoAdvance, currentPointIndex, pointDuration, nextPoint]);\n\n  const currentPoint = currentPointIndex >= 0 && currentPointIndex < points.length\n    ? points[currentPointIndex]\n    : null;\n\n  const progress = pointCount > 0 \n    ? Math.round(((currentPointIndex + 1) / pointCount) * 100)\n    : 0;\n\n  return {\n    isCalibrating,\n    progress,\n    currentPoint,\n    startCalibration,\n    stopCalibration,\n    nextPoint,\n  };\n}\n","/**\n * useGazeElement Hook\n * Track when user is looking at a specific element\n */\n\nimport { useRef, useState, useEffect } from 'react';\nimport { useWebgazerContext } from '../context/WebgazerContext';\nimport type { UseGazeElementOptions, UseGazeElementReturn } from '../types';\n\nexport function useGazeElement<T extends HTMLElement = HTMLElement>(\n  options: UseGazeElementOptions = {}\n): UseGazeElementReturn<T> {\n  const {\n    threshold = 50,\n    minDwellTime = 0,\n    onEnter,\n    onLeave,\n    onDwell,\n  } = options;\n\n  const { gazeData } = useWebgazerContext();\n  const ref = useRef<T>(null);\n  const [isLooking, setIsLooking] = useState(false);\n  const [dwellTime, setDwellTime] = useState(0);\n  const dwellStartRef = useRef<number | null>(null);\n  const hasDwelledRef = useRef(false);\n\n  useEffect(() => {\n    if (!gazeData || !ref.current) {\n      if (isLooking) {\n        setIsLooking(false);\n        setDwellTime(0);\n        dwellStartRef.current = null;\n        hasDwelledRef.current = false;\n        \n        if (onLeave) {\n          onLeave();\n        }\n      }\n      return;\n    }\n\n    const element = ref.current;\n    const rect = element.getBoundingClientRect();\n\n    // Check if gaze is within element bounds (with threshold)\n    const looking = (\n      gazeData.x >= rect.left - threshold &&\n      gazeData.x <= rect.right + threshold &&\n      gazeData.y >= rect.top - threshold &&\n      gazeData.y <= rect.bottom + threshold\n    );\n\n    if (looking && !isLooking) {\n      // Just entered\n      setIsLooking(true);\n      dwellStartRef.current = Date.now();\n      hasDwelledRef.current = false;\n      \n      if (onEnter) {\n        onEnter();\n      }\n    } else if (!looking && isLooking) {\n      // Just left\n      setIsLooking(false);\n      setDwellTime(0);\n      dwellStartRef.current = null;\n      hasDwelledRef.current = false;\n      \n      if (onLeave) {\n        onLeave();\n      }\n    } else if (looking && isLooking && dwellStartRef.current) {\n      // Still looking - update dwell time\n      const currentDwell = Date.now() - dwellStartRef.current;\n      setDwellTime(currentDwell);\n\n      // Check if dwell threshold reached\n      if (!hasDwelledRef.current && currentDwell >= minDwellTime && onDwell) {\n        hasDwelledRef.current = true;\n        onDwell();\n      }\n    }\n  }, [gazeData, isLooking, threshold, minDwellTime, onEnter, onLeave, onDwell]);\n\n  return {\n    ref,\n    isLooking,\n    dwellTime,\n  };\n}\n","/**\n * useGazeHeatmap Hook\n * Generate and visualize gaze heatmap data\n */\n\nimport { useRef, useState, useEffect, useCallback } from 'react';\nimport { useWebgazerContext } from '../context/WebgazerContext';\n\nexport interface HeatmapPoint {\n  x: number;\n  y: number;\n  timestamp: number;\n}\n\nexport interface UseGazeHeatmapOptions {\n  width?: number;\n  height?: number;\n  radius?: number;\n  maxOpacity?: number;\n  blur?: number;\n  gradient?: Record<number, string>;\n}\n\nexport interface UseGazeHeatmapReturn {\n  canvasRef: React.RefObject<HTMLCanvasElement>;\n  points: HeatmapPoint[];\n  clear: () => void;\n  exportData: () => string;\n  exportImage: () => string | null;\n}\n\nexport function useGazeHeatmap(options: UseGazeHeatmapOptions = {}): UseGazeHeatmapReturn {\n  const {\n    width = window.innerWidth,\n    height = window.innerHeight,\n    radius = 30,\n    maxOpacity = 0.8,\n    blur = 15,\n    gradient = {\n      0.0: 'blue',\n      0.25: 'cyan',\n      0.5: 'lime',\n      0.75: 'yellow',\n      1.0: 'red',\n    },\n  } = options;\n\n  const { gazeData } = useWebgazerContext();\n  const canvasRef = useRef<HTMLCanvasElement>(null);\n  const [points, setPoints] = useState<HeatmapPoint[]>([]);\n\n  // Collect gaze points\n  useEffect(() => {\n    if (gazeData) {\n      setPoints(prev => [\n        ...prev,\n        {\n          x: gazeData.x,\n          y: gazeData.y,\n          timestamp: Date.now(),\n        },\n      ]);\n    }\n  }, [gazeData]);\n\n  // Draw heatmap\n  useEffect(() => {\n    const canvas = canvasRef.current;\n    if (!canvas || points.length === 0) return;\n\n    const ctx = canvas.getContext('2d');\n    if (!ctx) return;\n\n    // Set canvas size\n    canvas.width = width;\n    canvas.height = height;\n\n    // Clear canvas\n    ctx.clearRect(0, 0, width, height);\n\n    // Create gradient for coloring\n    const colorGradient = ctx.createLinearGradient(0, 0, 0, radius * 2);\n    Object.entries(gradient).forEach(([stop, color]) => {\n      colorGradient.addColorStop(parseFloat(stop), color);\n    });\n\n    // Draw each point\n    points.forEach(point => {\n      // Create radial gradient for each point\n      const pointGradient = ctx.createRadialGradient(\n        point.x, point.y, 0,\n        point.x, point.y, radius\n      );\n      \n      pointGradient.addColorStop(0, `rgba(255, 0, 0, ${maxOpacity})`);\n      pointGradient.addColorStop(1, 'rgba(255, 0, 0, 0)');\n\n      ctx.fillStyle = pointGradient;\n      ctx.fillRect(\n        point.x - radius,\n        point.y - radius,\n        radius * 2,\n        radius * 2\n      );\n    });\n\n    // Apply blur\n    ctx.filter = `blur(${blur}px)`;\n    ctx.drawImage(canvas, 0, 0);\n    ctx.filter = 'none';\n  }, [points, width, height, radius, maxOpacity, blur, gradient]);\n\n  // Clear heatmap\n  const clear = useCallback(() => {\n    setPoints([]);\n    \n    const canvas = canvasRef.current;\n    if (canvas) {\n      const ctx = canvas.getContext('2d');\n      if (ctx) {\n        ctx.clearRect(0, 0, canvas.width, canvas.height);\n      }\n    }\n  }, []);\n\n  // Export data as CSV\n  const exportData = useCallback(() => {\n    const headers = ['x', 'y', 'timestamp'];\n    const rows = points.map(p => `${p.x},${p.y},${p.timestamp}`);\n    return [headers.join(','), ...rows].join('\\n');\n  }, [points]);\n\n  // Export as image\n  const exportImage = useCallback(() => {\n    const canvas = canvasRef.current;\n    if (!canvas) return null;\n    \n    return canvas.toDataURL('image/png');\n  }, []);\n\n  return {\n    canvasRef,\n    points,\n    clear,\n    exportData,\n    exportImage,\n  };\n}\n","/**\n * useGazeRecording Hook\n * Record gaze sessions for analysis\n */\n\nimport { useState, useCallback, useRef, useEffect } from 'react';\nimport { useWebgazerContext } from '../context/WebgazerContext';\n\nexport interface GazeRecordingEntry {\n  x: number;\n  y: number;\n  timestamp: number;\n  relativeTime: number;\n}\n\nexport interface UseGazeRecordingReturn {\n  isRecording: boolean;\n  data: GazeRecordingEntry[];\n  startRecording: () => void;\n  stopRecording: () => void;\n  clearData: () => void;\n  exportCSV: () => void;\n  exportJSON: () => void;\n}\n\nexport function useGazeRecording(): UseGazeRecordingReturn {\n  const { gazeData } = useWebgazerContext();\n  const [isRecording, setIsRecording] = useState(false);\n  const [data, setData] = useState<GazeRecordingEntry[]>([]);\n  const startTimeRef = useRef<number | null>(null);\n\n  // Record gaze data\n  useEffect(() => {\n    if (!isRecording || !gazeData) return;\n\n    if (!startTimeRef.current) {\n      startTimeRef.current = Date.now();\n    }\n\n    const entry: GazeRecordingEntry = {\n      x: gazeData.x,\n      y: gazeData.y,\n      timestamp: Date.now(),\n      relativeTime: Date.now() - startTimeRef.current,\n    };\n\n    setData(prev => [...prev, entry]);\n  }, [gazeData, isRecording]);\n\n  const startRecording = useCallback(() => {\n    setIsRecording(true);\n    startTimeRef.current = Date.now();\n  }, []);\n\n  const stopRecording = useCallback(() => {\n    setIsRecording(false);\n  }, []);\n\n  const clearData = useCallback(() => {\n    setData([]);\n    startTimeRef.current = null;\n  }, []);\n\n  const exportCSV = useCallback(() => {\n    const headers = ['x', 'y', 'timestamp', 'relativeTime'];\n    const rows = data.map(entry => \n      `${entry.x},${entry.y},${entry.timestamp},${entry.relativeTime}`\n    );\n    const csv = [headers.join(','), ...rows].join('\\n');\n\n    // Download\n    const blob = new Blob([csv], { type: 'text/csv' });\n    const url = URL.createObjectURL(blob);\n    const a = document.createElement('a');\n    a.href = url;\n    a.download = `gaze-recording-${Date.now()}.csv`;\n    a.click();\n    URL.revokeObjectURL(url);\n  }, [data]);\n\n  const exportJSON = useCallback(() => {\n    const json = JSON.stringify(data, null, 2);\n\n    // Download\n    const blob = new Blob([json], { type: 'application/json' });\n    const url = URL.createObjectURL(blob);\n    const a = document.createElement('a');\n    a.href = url;\n    a.download = `gaze-recording-${Date.now()}.json`;\n    a.click();\n    URL.revokeObjectURL(url);\n  }, [data]);\n\n  return {\n    isRecording,\n    data,\n    startRecording,\n    stopRecording,\n    clearData,\n    exportCSV,\n    exportJSON,\n  };\n}\n","/**\n * WebgazerProvider Component\n * Provides Webgazer context to child components\n */\n\nimport React from 'react';\nimport { WebgazerContext } from '../context/WebgazerContext';\nimport { useWebgazer } from '../hooks/useWebgazer';\nimport type { UseWebgazerOptions } from '../types';\n\nexport interface WebgazerProviderProps extends UseWebgazerOptions {\n  children: React.ReactNode;\n}\n\nexport function WebgazerProvider({ children, ...options }: WebgazerProviderProps) {\n  const webgazer = useWebgazer(options);\n\n  const contextValue = {\n    gazeData: webgazer.gazeData,\n    isRunning: webgazer.isRunning,\n    calibrationCount: webgazer.calibrationCount,\n    isInitialized: true,\n  };\n\n  return (\n    <WebgazerContext.Provider value={contextValue}>\n      {children}\n    </WebgazerContext.Provider>\n  );\n}\n","/**\n * CalibrationScreen Component\n * Full-screen calibration UI with animated points\n */\n\nimport { useEffect } from 'react';\nimport { useCalibration } from '../hooks/useCalibration';\nimport type { CalibrationResult } from '../types';\n\nexport interface CalibrationScreenProps {\n  pointCount?: number;\n  pointDuration?: number;\n  autoAdvance?: boolean;\n  onComplete?: (result: CalibrationResult) => void;\n  onCancel?: () => void;\n  theme?: {\n    backgroundColor?: string;\n    pointColor?: string;\n    progressColor?: string;\n    textColor?: string;\n  };\n}\n\nexport function CalibrationScreen({\n  pointCount = 9,\n  pointDuration = 1000,\n  autoAdvance = true,\n  onComplete,\n  onCancel,\n  theme = {},\n}: CalibrationScreenProps) {\n  const {\n    backgroundColor = 'rgba(0, 0, 0, 0.95)',\n    pointColor = '#ff0000',\n    progressColor = '#00ff00',\n    textColor = '#ffffff',\n  } = theme;\n\n  const {\n    isCalibrating,\n    progress,\n    currentPoint,\n    startCalibration,\n    stopCalibration,\n  } = useCalibration({\n    pointCount,\n    pointDuration,\n    autoAdvance,\n    onComplete: (result) => {\n      if (onComplete) {\n        onComplete(result);\n      }\n    },\n  });\n\n  // Auto-start calibration\n  useEffect(() => {\n    if (!isCalibrating) {\n      startCalibration();\n    }\n  }, []);\n\n  const handleCancel = () => {\n    stopCalibration();\n    if (onCancel) {\n      onCancel();\n    }\n  };\n\n  return (\n    <div\n      style={{\n        position: 'fixed',\n        top: 0,\n        left: 0,\n        width: '100%',\n        height: '100%',\n        backgroundColor,\n        display: 'flex',\n        flexDirection: 'column',\n        alignItems: 'center',\n        justifyContent: 'center',\n        zIndex: 9999,\n      }}\n    >\n      {/* Instructions */}\n      <div\n        style={{\n          position: 'absolute',\n          top: '20px',\n          left: '50%',\n          transform: 'translateX(-50%)',\n          textAlign: 'center',\n          color: textColor,\n        }}\n      >\n        <h2 style={{ margin: 0, fontSize: '32px' }}>Calibration</h2>\n        <p style={{ margin: '10px 0', fontSize: '18px' }}>\n          {autoAdvance \n            ? 'Look at each point as it appears'\n            : 'Click on each red dot'}\n        </p>\n        <div\n          style={{\n            width: '300px',\n            height: '20px',\n            backgroundColor: 'rgba(255, 255, 255, 0.2)',\n            borderRadius: '10px',\n            overflow: 'hidden',\n            margin: '20px auto',\n          }}\n        >\n          <div\n            style={{\n              width: `${progress}%`,\n              height: '100%',\n              backgroundColor: progressColor,\n              transition: 'width 0.3s ease',\n            }}\n          />\n        </div>\n        <p style={{ margin: 0, fontSize: '14px', opacity: 0.8 }}>\n          Progress: {progress}%\n        </p>\n      </div>\n\n      {/* Calibration Point */}\n      {currentPoint && (\n        <CalibrationPoint\n          x={currentPoint.x}\n          y={currentPoint.y}\n          color={pointColor}\n          duration={pointDuration}\n        />\n      )}\n\n      {/* Cancel Button */}\n      <button\n        onClick={handleCancel}\n        style={{\n          position: 'absolute',\n          bottom: '40px',\n          padding: '12px 24px',\n          fontSize: '16px',\n          backgroundColor: 'rgba(255, 255, 255, 0.1)',\n          color: textColor,\n          border: `2px solid ${textColor}`,\n          borderRadius: '5px',\n          cursor: 'pointer',\n          transition: 'all 0.2s',\n        }}\n        onMouseEnter={(e) => {\n          e.currentTarget.style.backgroundColor = 'rgba(255, 255, 255, 0.2)';\n        }}\n        onMouseLeave={(e) => {\n          e.currentTarget.style.backgroundColor = 'rgba(255, 255, 255, 0.1)';\n        }}\n      >\n        Cancel\n      </button>\n    </div>\n  );\n}\n\ninterface CalibrationPointProps {\n  x: number;\n  y: number;\n  color: string;\n  duration: number;\n}\n\nfunction CalibrationPoint({ x, y, color, duration }: CalibrationPointProps) {\n  return (\n    <div\n      style={{\n        position: 'absolute',\n        left: x,\n        top: y,\n        transform: 'translate(-50%, -50%)',\n        pointerEvents: 'none',\n      }}\n    >\n      {/* Outer ring animation */}\n      <div\n        style={{\n          position: 'absolute',\n          width: '60px',\n          height: '60px',\n          left: '50%',\n          top: '50%',\n          transform: 'translate(-50%, -50%)',\n          border: `2px solid ${color}`,\n          borderRadius: '50%',\n          animation: `calibration-pulse ${duration}ms ease-out`,\n          opacity: 0,\n        }}\n      />\n      \n      {/* Main point */}\n      <div\n        style={{\n          width: '20px',\n          height: '20px',\n          backgroundColor: color,\n          borderRadius: '50%',\n          boxShadow: `0 0 20px ${color}`,\n          animation: 'calibration-bounce 0.5s ease-out',\n        }}\n      />\n      \n      {/* Center dot */}\n      <div\n        style={{\n          position: 'absolute',\n          width: '6px',\n          height: '6px',\n          top: '50%',\n          left: '50%',\n          transform: 'translate(-50%, -50%)',\n          backgroundColor: 'white',\n          borderRadius: '50%',\n        }}\n      />\n\n      <style>{`\n        @keyframes calibration-pulse {\n          0% {\n            transform: translate(-50%, -50%) scale(0);\n            opacity: 1;\n          }\n          100% {\n            transform: translate(-50%, -50%) scale(1);\n            opacity: 0;\n          }\n        }\n        \n        @keyframes calibration-bounce {\n          0% {\n            transform: scale(0);\n          }\n          50% {\n            transform: scale(1.2);\n          }\n          100% {\n            transform: scale(1);\n          }\n        }\n      `}</style>\n    </div>\n  );\n}\n","/**\n * GazeElement Component\n * Wrapper component that responds to gaze\n */\n\nimport { ReactNode, CSSProperties } from 'react';\nimport { useGazeElement } from '../hooks/useGazeElement';\nimport type { UseGazeElementOptions } from '../types';\n\nexport interface GazeElementProps extends UseGazeElementOptions {\n  children: ReactNode;\n  className?: string;\n  style?: CSSProperties;\n  lookingStyle?: CSSProperties;\n  onDwellStyle?: CSSProperties;\n}\n\nexport function GazeElement({\n  children,\n  className,\n  style = {},\n  lookingStyle = {},\n  onDwellStyle = {},\n  ...gazeOptions\n}: GazeElementProps) {\n  // Use HTMLDivElement as the generic type since we're rendering a div\n  const { ref, isLooking, dwellTime } = useGazeElement<HTMLDivElement>(gazeOptions);\n  \n  const isDwelling = dwellTime >= (gazeOptions.minDwellTime || 0);\n\n  // Merge styles based on state\n  const mergedStyle: CSSProperties = {\n    ...style,\n    ...(isLooking ? lookingStyle : {}),\n    ...(isDwelling ? onDwellStyle : {}),\n  };\n\n  return (\n    <div ref={ref} className={className} style={mergedStyle}>\n      {children}\n    </div>\n  );\n}\n","/**\n * HeatmapOverlay Component\n * Visual overlay showing gaze heatmap\n */\n\nimport { CSSProperties } from 'react';\nimport { useGazeHeatmap } from '../hooks/useGazeHeatmap';\nimport type { UseGazeHeatmapOptions } from '../hooks/useGazeHeatmap';\n\nexport interface HeatmapOverlayProps extends UseGazeHeatmapOptions {\n  style?: CSSProperties;\n  showControls?: boolean;\n  onClear?: () => void;\n}\n\nexport function HeatmapOverlay({\n  style = {},\n  showControls = false,\n  onClear,\n  ...heatmapOptions\n}: HeatmapOverlayProps) {\n  const { canvasRef, points, clear, exportData, exportImage } = useGazeHeatmap(heatmapOptions);\n\n  const handleClear = () => {\n    clear();\n    if (onClear) {\n      onClear();\n    }\n  };\n\n  const handleExportCSV = () => {\n    const csv = exportData();\n    const blob = new Blob([csv], { type: 'text/csv' });\n    const url = URL.createObjectURL(blob);\n    const a = document.createElement('a');\n    a.href = url;\n    a.download = `heatmap-${Date.now()}.csv`;\n    a.click();\n    URL.revokeObjectURL(url);\n  };\n\n  const handleExportImage = () => {\n    const dataUrl = exportImage();\n    if (dataUrl) {\n      const a = document.createElement('a');\n      a.href = dataUrl;\n      a.download = `heatmap-${Date.now()}.png`;\n      a.click();\n    }\n  };\n\n  const defaultStyle: CSSProperties = {\n    position: 'fixed',\n    top: 0,\n    left: 0,\n    width: '100%',\n    height: '100%',\n    pointerEvents: 'none',\n    zIndex: 9998,\n    ...style,\n  };\n\n  return (\n    <>\n      <canvas ref={canvasRef} style={defaultStyle} />\n      \n      {showControls && (\n        <div\n          style={{\n            position: 'fixed',\n            bottom: '20px',\n            right: '20px',\n            display: 'flex',\n            gap: '10px',\n            zIndex: 9999,\n            pointerEvents: 'auto',\n          }}\n        >\n          <ControlButton onClick={handleClear}>\n            Clear ({points.length})\n          </ControlButton>\n          <ControlButton onClick={handleExportCSV} disabled={points.length === 0}>\n            Export CSV\n          </ControlButton>\n          <ControlButton onClick={handleExportImage} disabled={points.length === 0}>\n            Export PNG\n          </ControlButton>\n        </div>\n      )}\n    </>\n  );\n}\n\ninterface ControlButtonProps {\n  onClick: () => void;\n  disabled?: boolean;\n  children: React.ReactNode;\n}\n\nfunction ControlButton({ onClick, disabled, children }: ControlButtonProps) {\n  return (\n    <button\n      onClick={onClick}\n      disabled={disabled}\n      style={{\n        padding: '8px 16px',\n        fontSize: '14px',\n        backgroundColor: disabled ? '#ccc' : '#007bff',\n        color: 'white',\n        border: 'none',\n        borderRadius: '4px',\n        cursor: disabled ? 'not-allowed' : 'pointer',\n        opacity: disabled ? 0.5 : 1,\n        transition: 'all 0.2s',\n      }}\n      onMouseEnter={(e) => {\n        if (!disabled) {\n          e.currentTarget.style.backgroundColor = '#0056b3';\n        }\n      }}\n      onMouseLeave={(e) => {\n        if (!disabled) {\n          e.currentTarget.style.backgroundColor = '#007bff';\n        }\n      }}\n    >\n      {children}\n    </button>\n  );\n}\n"],"names":["useWebgazer","options","autoStart","tracker","regression","saveDataAcrossSessions","showVideoPreview","showFaceOverlay","showFaceFeedbackBox","showGazeDot","useKalmanFilter","onGaze","gazeData","setGazeData","useState","isRunning","setIsRunning","calibrationCount","setCalibrationCount","webgazerRef","useRef","gazeListenerRef","useEffect","mounted","initialize","webgazer","data","timestamp","intervalId","points","error","start","useCallback","stop","pause","resume","clearData","showVideo","hideVideo","setTracker","trackerName","setRegression","regressionName","showFaceOverlayToggle","show","showFaceFeedbackBoxToggle","showPredictionPoints","setVideoViewerSize","width","height","applyKalmanFilter","apply","recordScreenPosition","x","y","eventType","addMouseEventListeners","removeMouseEventListeners","WebgazerContext","createContext","useWebgazerContext","context","useContext","useGazeTracking","useCalibration","pointCount","pointDuration","autoAdvance","onComplete","onPointComplete","isCalibrating","setIsCalibrating","currentPointIndex","setCurrentPointIndex","setPoints","timeoutRef","generatePoints","newPoints","rows","i","col","row","startCalibration","stopCalibration","result","nextPoint","prev","currentPoint","progress","useGazeElement","threshold","minDwellTime","onEnter","onLeave","onDwell","ref","isLooking","setIsLooking","dwellTime","setDwellTime","dwellStartRef","hasDwelledRef","rect","looking","currentDwell","useGazeHeatmap","radius","maxOpacity","blur","gradient","canvasRef","canvas","ctx","colorGradient","color","point","pointGradient","clear","exportData","headers","p","exportImage","useGazeRecording","isRecording","setIsRecording","setData","startTimeRef","entry","startRecording","stopRecording","exportCSV","csv","blob","url","a","exportJSON","json","WebgazerProvider","children","contextValue","CalibrationScreen","onCancel","theme","backgroundColor","pointColor","progressColor","textColor","handleCancel","jsxs","jsx","CalibrationPoint","e","duration","GazeElement","className","style","lookingStyle","onDwellStyle","gazeOptions","isDwelling","mergedStyle","HeatmapOverlay","showControls","onClear","heatmapOptions","handleClear","handleExportCSV","handleExportImage","dataUrl","defaultStyle","Fragment","ControlButton","onClick","disabled"],"mappings":"uKAeO,SAASA,EAAYC,EAA8B,GAAuB,CAC/E,KAAM,CACJ,UAAAC,EAAY,GACZ,QAAAC,EAAU,aACV,WAAAC,EAAa,QACb,uBAAAC,EAAyB,GACzB,iBAAAC,EAAmB,GACnB,gBAAAC,EAAkB,GAClB,oBAAAC,EAAsB,GACtB,YAAAC,EAAc,GACd,kBAAmBC,EAAkB,GACrC,OAAAC,CAAA,EACEV,EAEE,CAACW,EAAUC,CAAW,EAAIC,EAAAA,SAAgC,IAAI,EAC9D,CAACC,EAAWC,CAAY,EAAIF,EAAAA,SAAS,EAAK,EAC1C,CAACG,EAAkBC,CAAmB,EAAIJ,EAAAA,SAAS,CAAC,EACpDK,EAAcC,EAAAA,OAAgC,IAAI,EAClDC,EAAkBD,EAAAA,OAA4B,IAAI,EAGxDE,EAAAA,UAAU,IAAM,CACd,IAAIC,EAAU,GAEd,eAAeC,GAAa,CAC1B,GAAI,CACF,GAAI,CAACD,EAAS,OAEdJ,EAAY,QAAUM,EAGtBA,EACG,WAAWtB,CAAO,EAClB,cAAcC,CAAU,EACxB,uBAAuBC,CAAsB,EAE5CK,GACFe,EAAS,kBAAkB,EAAI,EAIjCJ,EAAgB,QAAU,CAACK,EAA6BC,IAAsB,CACxEJ,IACFV,EAAYa,CAAI,EACZf,GACFA,EAAOe,EAAMC,CAAS,EAG5B,EAEAF,EAAS,gBAAgBJ,EAAgB,OAAO,EAGhD,MAAMO,EAAa,YAAY,IAAM,CACnC,GAAIL,GAAWJ,EAAY,QAAS,CAClC,MAAMU,EAASJ,EAAS,gBAAA,EAExBP,EAAoBW,GAAUA,EAAO,CAAC,EAAIA,EAAO,CAAC,EAAE,OAAS,CAAC,CAChE,CACF,EAAG,GAAI,EAGP,OAAI3B,IACF,MAAMuB,EAAS,MAAA,EACfT,EAAa,EAAI,EAGbV,GACFmB,EAAS,iBAAiB,EAAI,EAE5BlB,GACFkB,EAAS,gBAAgB,EAAI,EAE3BjB,GACFiB,EAAS,oBAAoB,EAAI,EAE/BhB,GACFgB,EAAS,qBAAqB,EAAI,GAI/B,IAAM,CACX,cAAcG,CAAU,CAC1B,CACF,OAASE,EAAO,CACd,QAAQ,MAAM,iCAAkCA,CAAK,CACvD,CACF,CAEA,OAAAN,EAAA,EAEO,IAAM,CACXD,EAAU,GACNJ,EAAY,SACdA,EAAY,QAAQ,IAAA,CAExB,CACF,EAAG,CAAA,CAAE,EAGL,MAAMY,EAAQC,EAAAA,YAAY,SAAY,CACpC,GAAKb,EAAY,QAEjB,GAAI,CACF,MAAMA,EAAY,QAAQ,MAAA,EAC1BH,EAAa,EAAI,EAEbV,GACFa,EAAY,QAAQ,iBAAiB,EAAI,EAEvCZ,GACFY,EAAY,QAAQ,gBAAgB,EAAI,EAEtCX,GACFW,EAAY,QAAQ,oBAAoB,EAAI,EAE1CV,GACFU,EAAY,QAAQ,qBAAqB,EAAI,CAEjD,OAASW,EAAO,CACd,QAAQ,MAAM,4BAA6BA,CAAK,CAClD,CACF,EAAG,CAACxB,EAAkBC,EAAiBC,EAAqBC,CAAW,CAAC,EAGlEwB,EAAOD,EAAAA,YAAY,SAAY,CACnC,GAAKb,EAAY,QAEjB,GAAI,CACF,MAAMA,EAAY,QAAQ,IAAA,EAC1BH,EAAa,EAAK,EAClBH,EAAY,IAAI,CAClB,OAASiB,EAAO,CACd,QAAQ,MAAM,2BAA4BA,CAAK,CACjD,CACF,EAAG,CAAA,CAAE,EAGCI,EAAQF,EAAAA,YAAY,SAAY,CACpC,GAAKb,EAAY,QAEjB,GAAI,CACF,MAAMA,EAAY,QAAQ,MAAA,EAC1BH,EAAa,EAAK,CACpB,OAASc,EAAO,CACd,QAAQ,MAAM,4BAA6BA,CAAK,CAClD,CACF,EAAG,CAAA,CAAE,EAGCK,EAASH,EAAAA,YAAY,SAAY,CACrC,GAAKb,EAAY,QAEjB,GAAI,CACF,MAAMA,EAAY,QAAQ,OAAA,EAC1BH,EAAa,EAAI,CACnB,OAASc,EAAO,CACd,QAAQ,MAAM,6BAA8BA,CAAK,CACnD,CACF,EAAG,CAAA,CAAE,EAGCM,EAAYJ,EAAAA,YAAY,IAAM,CAClC,GAAKb,EAAY,QAEjB,GAAI,CACFA,EAAY,QAAQ,UAAA,EACpBD,EAAoB,CAAC,CACvB,OAASY,EAAO,CACd,QAAQ,MAAM,wBAAyBA,CAAK,CAC9C,CACF,EAAG,CAAA,CAAE,EAGCO,EAAYL,EAAAA,YAAY,IAAM,CAClC,GAAKb,EAAY,QAEjB,GAAI,CACFA,EAAY,QAAQ,iBAAiB,EAAI,CAC3C,OAASW,EAAO,CACd,QAAQ,MAAM,wBAAyBA,CAAK,CAC9C,CACF,EAAG,CAAA,CAAE,EAGCQ,EAAYN,EAAAA,YAAY,IAAM,CAClC,GAAKb,EAAY,QAEjB,GAAI,CACFA,EAAY,QAAQ,iBAAiB,EAAK,CAC5C,OAASW,EAAO,CACd,QAAQ,MAAM,wBAAyBA,CAAK,CAC9C,CACF,EAAG,CAAA,CAAE,EAGCS,EAAaP,cAAaQ,GAAwB,CACtD,GAAKrB,EAAY,QACjB,GAAI,CACFA,EAAY,QAAQ,WAAWqB,CAAW,CAC5C,OAASV,EAAO,CACd,QAAQ,MAAM,yBAA0BA,CAAK,CAC/C,CACF,EAAG,CAAA,CAAE,EAECW,EAAgBT,cAAaU,GAA2B,CAC5D,GAAKvB,EAAY,QACjB,GAAI,CACFA,EAAY,QAAQ,cAAcuB,CAAc,CAClD,OAASZ,EAAO,CACd,QAAQ,MAAM,4BAA6BA,CAAK,CAClD,CACF,EAAG,CAAA,CAAE,EAECa,EAAwBX,cAAaY,GAAkB,CAC3D,GAAKzB,EAAY,QACjB,GAAI,CACFA,EAAY,QAAQ,gBAAgByB,CAAI,CAC1C,OAASd,EAAO,CACd,QAAQ,MAAM,iCAAkCA,CAAK,CACvD,CACF,EAAG,CAAA,CAAE,EAECe,EAA4Bb,cAAaY,GAAkB,CAC/D,GAAKzB,EAAY,QACjB,GAAI,CACFA,EAAY,QAAQ,oBAAoByB,CAAI,CAC9C,OAASd,EAAO,CACd,QAAQ,MAAM,sCAAuCA,CAAK,CAC5D,CACF,EAAG,CAAA,CAAE,EAECgB,EAAuBd,cAAaY,GAAkB,CAC1D,GAAKzB,EAAY,QACjB,GAAI,CACFA,EAAY,QAAQ,qBAAqByB,CAAI,CAC/C,OAASd,EAAO,CACd,QAAQ,MAAM,sCAAuCA,CAAK,CAC5D,CACF,EAAG,CAAA,CAAE,EAECiB,EAAqBf,EAAAA,YAAY,CAACgB,EAAeC,IAAmB,CACxE,GAAK9B,EAAY,QACjB,GAAI,CACFA,EAAY,QAAQ,mBAAmB6B,EAAOC,CAAM,CACtD,OAASnB,EAAO,CACd,QAAQ,MAAM,mCAAoCA,CAAK,CACzD,CACF,EAAG,CAAA,CAAE,EAECoB,EAAoBlB,cAAamB,GAAmB,CACxD,GAAKhC,EAAY,QACjB,GAAI,CACFA,EAAY,QAAQ,kBAAkBgC,CAAK,CAC7C,OAASrB,EAAO,CACd,QAAQ,MAAM,iCAAkCA,CAAK,CACvD,CACF,EAAG,CAAA,CAAE,EAECsB,EAAuBpB,EAAAA,YAAY,CAACqB,EAAWC,EAAWC,EAA8B,UAAY,CACxG,GAAKpC,EAAY,QACjB,GAAI,CACFA,EAAY,QAAQ,qBAAqBkC,EAAGC,EAAGC,CAAS,CAC1D,OAASzB,EAAO,CACd,QAAQ,MAAM,oCAAqCA,CAAK,CAC1D,CACF,EAAG,CAAA,CAAE,EAEC0B,EAAyBxB,EAAAA,YAAY,IAAM,CAC/C,GAAKb,EAAY,QACjB,GAAI,CACFA,EAAY,QAAQ,uBAAA,CACtB,OAASW,EAAO,CACd,QAAQ,MAAM,uCAAwCA,CAAK,CAC7D,CACF,EAAG,CAAA,CAAE,EAEC2B,EAA4BzB,EAAAA,YAAY,IAAM,CAClD,GAAKb,EAAY,QACjB,GAAI,CACFA,EAAY,QAAQ,0BAAA,CACtB,OAASW,EAAO,CACd,QAAQ,MAAM,0CAA2CA,CAAK,CAChE,CACF,EAAG,CAAA,CAAE,EAEL,MAAO,CAEL,SAAAlB,EACA,UAAAG,EACA,iBAAAE,EAGA,MAAAc,EACA,KAAAE,EACA,MAAAC,EACA,OAAAC,EACA,UAAAC,EAGA,UAAAC,EACA,UAAAC,EAGA,WAAAC,EACA,cAAAE,EACA,gBAAiBE,EACjB,oBAAqBE,EACrB,qBAAAC,EACA,mBAAAC,EACA,kBAAAG,EAGA,qBAAAE,EACA,uBAAAI,EACA,0BAAAC,EAGA,SAAUtC,EAAY,OAAA,CAE1B,CChUO,MAAMuC,EAAkBC,EAAAA,cAA2C,IAAI,EAEvE,SAASC,GAAqB,CACnC,MAAMC,EAAUC,EAAAA,WAAWJ,CAAe,EAC1C,GAAI,CAACG,EACH,MAAM,IAAI,MAAM,yDAAyD,EAE3E,OAAOA,CACT,CCdO,SAASE,GAAyC,CACvD,KAAM,CAAE,SAAAnD,CAAA,EAAagD,EAAA,EACrB,OAAOhD,CACT,CCCO,SAASoD,EAAe/D,EAAiC,GAA0B,CACxF,KAAM,CACJ,WAAAgE,EAAa,EACb,cAAAC,EAAgB,IAChB,YAAAC,EAAc,GACd,WAAAC,EACA,gBAAAC,CAAA,EACEpE,EAEE,CAACqE,EAAeC,CAAgB,EAAIzD,EAAAA,SAAS,EAAK,EAClD,CAAC0D,EAAmBC,CAAoB,EAAI3D,EAAAA,SAAS,EAAE,EACvD,CAACe,EAAQ6C,CAAS,EAAI5D,EAAAA,SAA6B,CAAA,CAAE,EAErD6D,EAAavD,EAAAA,OAA6C,IAAI,EAG9DwD,EAAiB5C,EAAAA,YAAY,IAAM,CACvC,MAAM6C,EAAgC,CAAA,EAGhCC,EAAO,KAAK,KAAKb,EAAa,CAAI,EAElCjB,EAAQ,OAAO,WAAa,IAAS,EACrCC,EAAS,OAAO,YAAc,IAAS,EAE7C,QAAS8B,EAAI,EAAGA,EAAId,EAAYc,IAAK,CACnC,MAAMC,EAAMD,EAAI,EACVE,EAAM,KAAK,MAAMF,EAAI,CAAI,EAEzB1B,EAAI,IAAUL,EAAS,EAAagC,EACpC1B,EAAI,IAAUL,GAAU6B,EAAO,GAAMG,EAE3CJ,EAAU,KAAK,CAAE,EAAAxB,EAAG,EAAAC,EAAG,MAAOyB,EAAG,CACnC,CAEA,OAAOF,CACT,EAAG,CAACZ,CAAU,CAAC,EAGTiB,EAAmBlD,EAAAA,YAAY,IAAM,CACzCuC,EAAiB,EAAI,EACrBE,EAAqB,CAAC,EACtBC,EAAUE,GAAgB,CAC5B,EAAG,CAACA,CAAc,CAAC,EAGbO,EAAkBnD,EAAAA,YAAY,IAAM,CACxCuC,EAAiB,EAAK,EACtBE,EAAqB,EAAE,EAEnBE,EAAW,UACb,aAAaA,EAAW,OAAO,EAC/BA,EAAW,QAAU,MAGvB,MAAMS,EAA4B,CAChC,QAASZ,GAAqBP,EAC9B,iBAAkBO,EAAoB,CAAA,EAGpCJ,GACFA,EAAWgB,CAAM,CAErB,EAAG,CAACZ,EAAmBP,EAAYG,CAAU,CAAC,EAGxCiB,EAAYrD,EAAAA,YAAY,IAAM,CAC9BqC,GACFA,EAAgBG,CAAiB,EAG/BA,EAAoB,GAAKP,EAE3BkB,EAAA,EAEAV,EAAqBa,GAAQA,EAAO,CAAC,CAEzC,EAAG,CAACd,EAAmBP,EAAYI,EAAiBc,CAAe,CAAC,EAGpE7D,EAAAA,UAAU,IAAM,CACd,GAAI,GAACgD,GAAiB,CAACH,GAAeK,EAAoB,GAI1D,OAAAG,EAAW,QAAU,WAAW,IAAM,CACpCU,EAAA,CACF,EAAGnB,CAAa,EAET,IAAM,CACPS,EAAW,SACb,aAAaA,EAAW,OAAO,CAEnC,CACF,EAAG,CAACL,EAAeH,EAAaK,EAAmBN,EAAemB,CAAS,CAAC,EAE5E,MAAME,EAAef,GAAqB,GAAKA,EAAoB3C,EAAO,OACtEA,EAAO2C,CAAiB,EACxB,KAEEgB,EAAWvB,EAAa,EAC1B,KAAK,OAAQO,EAAoB,GAAKP,EAAc,GAAG,EACvD,EAEJ,MAAO,CACL,cAAAK,EACA,SAAAkB,EACA,aAAAD,EACA,iBAAAL,EACA,gBAAAC,EACA,UAAAE,CAAA,CAEJ,CCpHO,SAASI,EACdxF,EAAiC,GACR,CACzB,KAAM,CACJ,UAAAyF,EAAY,GACZ,aAAAC,EAAe,EACf,QAAAC,EACA,QAAAC,EACA,QAAAC,CAAA,EACE7F,EAEE,CAAE,SAAAW,CAAA,EAAagD,EAAA,EACfmC,EAAM3E,EAAAA,OAAU,IAAI,EACpB,CAAC4E,EAAWC,CAAY,EAAInF,EAAAA,SAAS,EAAK,EAC1C,CAACoF,EAAWC,CAAY,EAAIrF,EAAAA,SAAS,CAAC,EACtCsF,EAAgBhF,EAAAA,OAAsB,IAAI,EAC1CiF,EAAgBjF,EAAAA,OAAO,EAAK,EAElCE,OAAAA,EAAAA,UAAU,IAAM,CACd,GAAI,CAACV,GAAY,CAACmF,EAAI,QAAS,CACzBC,IACFC,EAAa,EAAK,EAClBE,EAAa,CAAC,EACdC,EAAc,QAAU,KACxBC,EAAc,QAAU,GAEpBR,GACFA,EAAA,GAGJ,MACF,CAGA,MAAMS,EADUP,EAAI,QACC,sBAAA,EAGfQ,EACJ3F,EAAS,GAAK0F,EAAK,KAAOZ,GAC1B9E,EAAS,GAAK0F,EAAK,MAAQZ,GAC3B9E,EAAS,GAAK0F,EAAK,IAAMZ,GACzB9E,EAAS,GAAK0F,EAAK,OAASZ,EAG9B,GAAIa,GAAW,CAACP,EAEdC,EAAa,EAAI,EACjBG,EAAc,QAAU,KAAK,IAAA,EAC7BC,EAAc,QAAU,GAEpBT,GACFA,EAAA,UAEO,CAACW,GAAWP,EAErBC,EAAa,EAAK,EAClBE,EAAa,CAAC,EACdC,EAAc,QAAU,KACxBC,EAAc,QAAU,GAEpBR,GACFA,EAAA,UAEOU,GAAWP,GAAaI,EAAc,QAAS,CAExD,MAAMI,EAAe,KAAK,IAAA,EAAQJ,EAAc,QAChDD,EAAaK,CAAY,EAGrB,CAACH,EAAc,SAAWG,GAAgBb,GAAgBG,IAC5DO,EAAc,QAAU,GACxBP,EAAA,EAEJ,CACF,EAAG,CAAClF,EAAUoF,EAAWN,EAAWC,EAAcC,EAASC,EAASC,CAAO,CAAC,EAErE,CACL,IAAAC,EACA,UAAAC,EACA,UAAAE,CAAA,CAEJ,CC3DO,SAASO,EAAexG,EAAiC,GAA0B,CACxF,KAAM,CACJ,MAAA+C,EAAQ,OAAO,WACf,OAAAC,EAAS,OAAO,YAChB,OAAAyD,EAAS,GACT,WAAAC,EAAa,GACb,KAAAC,EAAO,GACP,SAAAC,EAAW,CACT,EAAK,OACL,IAAM,OACN,GAAK,OACL,IAAM,SACN,EAAK,KAAA,CACP,EACE5G,EAEE,CAAE,SAAAW,CAAA,EAAagD,EAAA,EACfkD,EAAY1F,EAAAA,OAA0B,IAAI,EAC1C,CAACS,EAAQ6C,CAAS,EAAI5D,EAAAA,SAAyB,CAAA,CAAE,EAGvDQ,EAAAA,UAAU,IAAM,CACVV,GACF8D,EAAUY,GAAQ,CAChB,GAAGA,EACH,CACE,EAAG1E,EAAS,EACZ,EAAGA,EAAS,EACZ,UAAW,KAAK,IAAA,CAAI,CACtB,CACD,CAEL,EAAG,CAACA,CAAQ,CAAC,EAGbU,EAAAA,UAAU,IAAM,CACd,MAAMyF,EAASD,EAAU,QACzB,GAAI,CAACC,GAAUlF,EAAO,SAAW,EAAG,OAEpC,MAAMmF,EAAMD,EAAO,WAAW,IAAI,EAClC,GAAI,CAACC,EAAK,OAGVD,EAAO,MAAQ/D,EACf+D,EAAO,OAAS9D,EAGhB+D,EAAI,UAAU,EAAG,EAAGhE,EAAOC,CAAM,EAGjC,MAAMgE,EAAgBD,EAAI,qBAAqB,EAAG,EAAG,EAAGN,EAAS,CAAC,EAClE,OAAO,QAAQG,CAAQ,EAAE,QAAQ,CAAC,CAAC5E,EAAMiF,CAAK,IAAM,CAClDD,EAAc,aAAa,WAAWhF,CAAI,EAAGiF,CAAK,CACpD,CAAC,EAGDrF,EAAO,QAAQsF,GAAS,CAEtB,MAAMC,EAAgBJ,EAAI,qBACxBG,EAAM,EAAGA,EAAM,EAAG,EAClBA,EAAM,EAAGA,EAAM,EAAGT,CAAA,EAGpBU,EAAc,aAAa,EAAG,mBAAmBT,CAAU,GAAG,EAC9DS,EAAc,aAAa,EAAG,oBAAoB,EAElDJ,EAAI,UAAYI,EAChBJ,EAAI,SACFG,EAAM,EAAIT,EACVS,EAAM,EAAIT,EACVA,EAAS,EACTA,EAAS,CAAA,CAEb,CAAC,EAGDM,EAAI,OAAS,QAAQJ,CAAI,MACzBI,EAAI,UAAUD,EAAQ,EAAG,CAAC,EAC1BC,EAAI,OAAS,MACf,EAAG,CAACnF,EAAQmB,EAAOC,EAAQyD,EAAQC,EAAYC,EAAMC,CAAQ,CAAC,EAG9D,MAAMQ,EAAQrF,EAAAA,YAAY,IAAM,CAC9B0C,EAAU,CAAA,CAAE,EAEZ,MAAMqC,EAASD,EAAU,QACzB,GAAIC,EAAQ,CACV,MAAMC,EAAMD,EAAO,WAAW,IAAI,EAC9BC,GACFA,EAAI,UAAU,EAAG,EAAGD,EAAO,MAAOA,EAAO,MAAM,CAEnD,CACF,EAAG,CAAA,CAAE,EAGCO,EAAatF,EAAAA,YAAY,IAAM,CACnC,MAAMuF,EAAU,CAAC,IAAK,IAAK,WAAW,EAChCzC,EAAOjD,EAAO,IAAI2F,GAAK,GAAGA,EAAE,CAAC,IAAIA,EAAE,CAAC,IAAIA,EAAE,SAAS,EAAE,EAC3D,MAAO,CAACD,EAAQ,KAAK,GAAG,EAAG,GAAGzC,CAAI,EAAE,KAAK;AAAA,CAAI,CAC/C,EAAG,CAACjD,CAAM,CAAC,EAGL4F,EAAczF,EAAAA,YAAY,IAAM,CACpC,MAAM+E,EAASD,EAAU,QACzB,OAAKC,EAEEA,EAAO,UAAU,WAAW,EAFf,IAGtB,EAAG,CAAA,CAAE,EAEL,MAAO,CACL,UAAAD,EACA,OAAAjF,EACA,MAAAwF,EACA,WAAAC,EACA,YAAAG,CAAA,CAEJ,CC1HO,SAASC,GAA2C,CACzD,KAAM,CAAE,SAAA9G,CAAA,EAAagD,EAAA,EACf,CAAC+D,EAAaC,CAAc,EAAI9G,EAAAA,SAAS,EAAK,EAC9C,CAACY,EAAMmG,CAAO,EAAI/G,EAAAA,SAA+B,CAAA,CAAE,EACnDgH,EAAe1G,EAAAA,OAAsB,IAAI,EAG/CE,EAAAA,UAAU,IAAM,CACd,GAAI,CAACqG,GAAe,CAAC/G,EAAU,OAE1BkH,EAAa,UAChBA,EAAa,QAAU,KAAK,IAAA,GAG9B,MAAMC,EAA4B,CAChC,EAAGnH,EAAS,EACZ,EAAGA,EAAS,EACZ,UAAW,KAAK,IAAA,EAChB,aAAc,KAAK,IAAA,EAAQkH,EAAa,OAAA,EAG1CD,EAAQvC,GAAQ,CAAC,GAAGA,EAAMyC,CAAK,CAAC,CAClC,EAAG,CAACnH,EAAU+G,CAAW,CAAC,EAE1B,MAAMK,EAAiBhG,EAAAA,YAAY,IAAM,CACvC4F,EAAe,EAAI,EACnBE,EAAa,QAAU,KAAK,IAAA,CAC9B,EAAG,CAAA,CAAE,EAECG,EAAgBjG,EAAAA,YAAY,IAAM,CACtC4F,EAAe,EAAK,CACtB,EAAG,CAAA,CAAE,EAECxF,EAAYJ,EAAAA,YAAY,IAAM,CAClC6F,EAAQ,CAAA,CAAE,EACVC,EAAa,QAAU,IACzB,EAAG,CAAA,CAAE,EAECI,EAAYlG,EAAAA,YAAY,IAAM,CAClC,MAAMuF,EAAU,CAAC,IAAK,IAAK,YAAa,cAAc,EAChDzC,EAAOpD,EAAK,IAAIqG,GACpB,GAAGA,EAAM,CAAC,IAAIA,EAAM,CAAC,IAAIA,EAAM,SAAS,IAAIA,EAAM,YAAY,EAAA,EAE1DI,EAAM,CAACZ,EAAQ,KAAK,GAAG,EAAG,GAAGzC,CAAI,EAAE,KAAK;AAAA,CAAI,EAG5CsD,EAAO,IAAI,KAAK,CAACD,CAAG,EAAG,CAAE,KAAM,WAAY,EAC3CE,EAAM,IAAI,gBAAgBD,CAAI,EAC9BE,EAAI,SAAS,cAAc,GAAG,EACpCA,EAAE,KAAOD,EACTC,EAAE,SAAW,kBAAkB,KAAK,IAAA,CAAK,OACzCA,EAAE,MAAA,EACF,IAAI,gBAAgBD,CAAG,CACzB,EAAG,CAAC3G,CAAI,CAAC,EAEH6G,EAAavG,EAAAA,YAAY,IAAM,CACnC,MAAMwG,EAAO,KAAK,UAAU9G,EAAM,KAAM,CAAC,EAGnC0G,EAAO,IAAI,KAAK,CAACI,CAAI,EAAG,CAAE,KAAM,mBAAoB,EACpDH,EAAM,IAAI,gBAAgBD,CAAI,EAC9BE,EAAI,SAAS,cAAc,GAAG,EACpCA,EAAE,KAAOD,EACTC,EAAE,SAAW,kBAAkB,KAAK,IAAA,CAAK,QACzCA,EAAE,MAAA,EACF,IAAI,gBAAgBD,CAAG,CACzB,EAAG,CAAC3G,CAAI,CAAC,EAET,MAAO,CACL,YAAAiG,EACA,KAAAjG,EACA,eAAAsG,EACA,cAAAC,EACA,UAAA7F,EACA,UAAA8F,EACA,WAAAK,CAAA,CAEJ,CCxFO,SAASE,EAAiB,CAAE,SAAAC,EAAU,GAAGzI,GAAkC,CAChF,MAAMwB,EAAWzB,EAAYC,CAAO,EAE9B0I,EAAe,CACnB,SAAUlH,EAAS,SACnB,UAAWA,EAAS,UACpB,iBAAkBA,EAAS,iBAC3B,cAAe,EAAA,EAGjB,aACGiC,EAAgB,SAAhB,CAAyB,MAAOiF,EAC9B,SAAAD,EACH,CAEJ,CCNO,SAASE,GAAkB,CAChC,WAAA3E,EAAa,EACb,cAAAC,EAAgB,IAChB,YAAAC,EAAc,GACd,WAAAC,EACA,SAAAyE,EACA,MAAAC,EAAQ,CAAA,CACV,EAA2B,CACzB,KAAM,CACJ,gBAAAC,EAAkB,sBAClB,WAAAC,EAAa,UACb,cAAAC,EAAgB,UAChB,UAAAC,EAAY,SAAA,EACVJ,EAEE,CACJ,cAAAxE,EACA,SAAAkB,EACA,aAAAD,EACA,iBAAAL,EACA,gBAAAC,CAAA,EACEnB,EAAe,CACjB,WAAAC,EACA,cAAAC,EACA,YAAAC,EACA,WAAaiB,GAAW,CAClBhB,GACFA,EAAWgB,CAAM,CAErB,CAAA,CACD,EAGD9D,EAAAA,UAAU,IAAM,CACTgD,GACHY,EAAA,CAEJ,EAAG,CAAA,CAAE,EAEL,MAAMiE,EAAe,IAAM,CACzBhE,EAAA,EACI0D,GACFA,EAAA,CAEJ,EAEA,OACEO,EAAAA,KAAC,MAAA,CACC,MAAO,CACL,SAAU,QACV,IAAK,EACL,KAAM,EACN,MAAO,OACP,OAAQ,OACR,gBAAAL,EACA,QAAS,OACT,cAAe,SACf,WAAY,SACZ,eAAgB,SAChB,OAAQ,IAAA,EAIV,SAAA,CAAAK,EAAAA,KAAC,MAAA,CACC,MAAO,CACL,SAAU,WACV,IAAK,OACL,KAAM,MACN,UAAW,mBACX,UAAW,SACX,MAAOF,CAAA,EAGT,SAAA,CAAAG,EAAAA,IAAC,KAAA,CAAG,MAAO,CAAE,OAAQ,EAAG,SAAU,MAAA,EAAU,SAAA,aAAA,CAAW,EACvDA,EAAAA,IAAC,IAAA,CAAE,MAAO,CAAE,OAAQ,SAAU,SAAU,MAAA,EACrC,SAAAlF,EACG,mCACA,uBAAA,CACN,EACAkF,EAAAA,IAAC,MAAA,CACC,MAAO,CACL,MAAO,QACP,OAAQ,OACR,gBAAiB,2BACjB,aAAc,OACd,SAAU,SACV,OAAQ,WAAA,EAGV,SAAAA,EAAAA,IAAC,MAAA,CACC,MAAO,CACL,MAAO,GAAG7D,CAAQ,IAClB,OAAQ,OACR,gBAAiByD,EACjB,WAAY,iBAAA,CACd,CAAA,CACF,CAAA,EAEFG,EAAAA,KAAC,IAAA,CAAE,MAAO,CAAE,OAAQ,EAAG,SAAU,OAAQ,QAAS,EAAA,EAAO,SAAA,CAAA,aAC5C5D,EAAS,GAAA,CAAA,CACtB,CAAA,CAAA,CAAA,EAIDD,GACC8D,EAAAA,IAACC,GAAA,CACC,EAAG/D,EAAa,EAChB,EAAGA,EAAa,EAChB,MAAOyD,EACP,SAAU9E,CAAA,CAAA,EAKdmF,EAAAA,IAAC,SAAA,CACC,QAASF,EACT,MAAO,CACL,SAAU,WACV,OAAQ,OACR,QAAS,YACT,SAAU,OACV,gBAAiB,2BACjB,MAAOD,EACP,OAAQ,aAAaA,CAAS,GAC9B,aAAc,MACd,OAAQ,UACR,WAAY,UAAA,EAEd,aAAeK,GAAM,CACnBA,EAAE,cAAc,MAAM,gBAAkB,0BAC1C,EACA,aAAeA,GAAM,CACnBA,EAAE,cAAc,MAAM,gBAAkB,0BAC1C,EACD,SAAA,QAAA,CAAA,CAED,CAAA,CAAA,CAGN,CASA,SAASD,GAAiB,CAAE,EAAAjG,EAAG,EAAAC,EAAG,MAAA4D,EAAO,SAAAsC,GAAmC,CAC1E,OACEJ,EAAAA,KAAC,MAAA,CACC,MAAO,CACL,SAAU,WACV,KAAM/F,EACN,IAAKC,EACL,UAAW,wBACX,cAAe,MAAA,EAIjB,SAAA,CAAA+F,EAAAA,IAAC,MAAA,CACC,MAAO,CACL,SAAU,WACV,MAAO,OACP,OAAQ,OACR,KAAM,MACN,IAAK,MACL,UAAW,wBACX,OAAQ,aAAanC,CAAK,GAC1B,aAAc,MACd,UAAW,qBAAqBsC,CAAQ,cACxC,QAAS,CAAA,CACX,CAAA,EAIFH,EAAAA,IAAC,MAAA,CACC,MAAO,CACL,MAAO,OACP,OAAQ,OACR,gBAAiBnC,EACjB,aAAc,MACd,UAAW,YAAYA,CAAK,GAC5B,UAAW,kCAAA,CACb,CAAA,EAIFmC,EAAAA,IAAC,MAAA,CACC,MAAO,CACL,SAAU,WACV,MAAO,MACP,OAAQ,MACR,IAAK,MACL,KAAM,MACN,UAAW,wBACX,gBAAiB,QACjB,aAAc,KAAA,CAChB,CAAA,QAGD,QAAA,CAAO,SAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAAA,CAuBN,CAAA,CAAA,CAAA,CAGR,CCzOO,SAASI,GAAY,CAC1B,SAAAf,EACA,UAAAgB,EACA,MAAAC,EAAQ,CAAA,EACR,aAAAC,EAAe,CAAA,EACf,aAAAC,EAAe,CAAA,EACf,GAAGC,CACL,EAAqB,CAEnB,KAAM,CAAE,IAAA/D,EAAK,UAAAC,EAAW,UAAAE,CAAA,EAAcT,EAA+BqE,CAAW,EAE1EC,EAAa7D,IAAc4D,EAAY,cAAgB,GAGvDE,EAA6B,CACjC,GAAGL,EACH,GAAI3D,EAAY4D,EAAe,CAAA,EAC/B,GAAIG,EAAaF,EAAe,CAAA,CAAC,EAGnC,aACG,MAAA,CAAI,IAAA9D,EAAU,UAAA2D,EAAsB,MAAOM,EACzC,SAAAtB,EACH,CAEJ,CC3BO,SAASuB,GAAe,CAC7B,MAAAN,EAAQ,CAAA,EACR,aAAAO,EAAe,GACf,QAAAC,EACA,GAAGC,CACL,EAAwB,CACtB,KAAM,CAAE,UAAAtD,EAAW,OAAAjF,EAAQ,MAAAwF,EAAO,WAAAC,EAAY,YAAAG,CAAA,EAAgBhB,EAAe2D,CAAc,EAErFC,EAAc,IAAM,CACxBhD,EAAA,EACI8C,GACFA,EAAA,CAEJ,EAEMG,EAAkB,IAAM,CAC5B,MAAMnC,EAAMb,EAAA,EACNc,EAAO,IAAI,KAAK,CAACD,CAAG,EAAG,CAAE,KAAM,WAAY,EAC3CE,EAAM,IAAI,gBAAgBD,CAAI,EAC9BE,EAAI,SAAS,cAAc,GAAG,EACpCA,EAAE,KAAOD,EACTC,EAAE,SAAW,WAAW,KAAK,IAAA,CAAK,OAClCA,EAAE,MAAA,EACF,IAAI,gBAAgBD,CAAG,CACzB,EAEMkC,EAAoB,IAAM,CAC9B,MAAMC,EAAU/C,EAAA,EAChB,GAAI+C,EAAS,CACX,MAAMlC,EAAI,SAAS,cAAc,GAAG,EACpCA,EAAE,KAAOkC,EACTlC,EAAE,SAAW,WAAW,KAAK,IAAA,CAAK,OAClCA,EAAE,MAAA,CACJ,CACF,EAEMmC,EAA8B,CAClC,SAAU,QACV,IAAK,EACL,KAAM,EACN,MAAO,OACP,OAAQ,OACR,cAAe,OACf,OAAQ,KACR,GAAGd,CAAA,EAGL,OACEP,EAAAA,KAAAsB,WAAA,CACE,SAAA,CAAArB,EAAAA,IAAC,SAAA,CAAO,IAAKvC,EAAW,MAAO2D,EAAc,EAE5CP,GACCd,EAAAA,KAAC,MAAA,CACC,MAAO,CACL,SAAU,QACV,OAAQ,OACR,MAAO,OACP,QAAS,OACT,IAAK,OACL,OAAQ,KACR,cAAe,MAAA,EAGjB,SAAA,CAAAA,EAAAA,KAACuB,EAAA,CAAc,QAASN,EAAa,SAAA,CAAA,UAC3BxI,EAAO,OAAO,GAAA,EACxB,EACAwH,EAAAA,IAACsB,GAAc,QAASL,EAAiB,SAAUzI,EAAO,SAAW,EAAG,SAAA,YAAA,CAExE,EACAwH,EAAAA,IAACsB,GAAc,QAASJ,EAAmB,SAAU1I,EAAO,SAAW,EAAG,SAAA,YAAA,CAE1E,CAAA,CAAA,CAAA,CACF,EAEJ,CAEJ,CAQA,SAAS8I,EAAc,CAAE,QAAAC,EAAS,SAAAC,EAAU,SAAAnC,GAAgC,CAC1E,OACEW,EAAAA,IAAC,SAAA,CACC,QAAAuB,EACA,SAAAC,EACA,MAAO,CACL,QAAS,WACT,SAAU,OACV,gBAAiBA,EAAW,OAAS,UACrC,MAAO,QACP,OAAQ,OACR,aAAc,MACd,OAAQA,EAAW,cAAgB,UACnC,QAASA,EAAW,GAAM,EAC1B,WAAY,UAAA,EAEd,aAAetB,GAAM,CACdsB,IACHtB,EAAE,cAAc,MAAM,gBAAkB,UAE5C,EACA,aAAeA,GAAM,CACdsB,IACHtB,EAAE,cAAc,MAAM,gBAAkB,UAE5C,EAEC,SAAAb,CAAA,CAAA,CAGP"}