{"version":3,"sources":["jsdelivr-header.js","/npm/dynamic-sky@0.0.7/dynamic-sky.js"],"names":[],"mappings":"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","file":"/npm/dynamic-sky@0.0.7/dynamic-sky.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/dynamic-sky@0.0.7/dynamic-sky.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","/**\n * DynamicSky - Dynamic sky background renderer with circular time slider control\n * \n * A vanilla JavaScript library for rendering realistic sky backgrounds with\n * atmospheric scattering, animated starfields, and an optional circular time slider.\n * \n * Usage:\n *   <script src=\"dynamic-sky.js\"></script>\n *   <script>\n *     const sky = new DynamicSky({\n *       skyContainer: '#background-sky',\n *       starsContainer: '#stars-container'\n *     });\n *     sky.init();\n *   </script>\n * \n * @version 1.0.0\n * @license MIT\n */\n\n(function (global) {\n  'use strict';\n\n  // ============================================================================\n  // Constants & Helpers for Physics\n  // ============================================================================\n\n  var PI = Math.PI;\n  var RAYLEIGH_SCATTER = [5.802e-6, 13.558e-6, 33.1e-6];\n  var MIE_SCATTER = 3.996e-6;\n  var MIE_ABSORB = 4.44e-6;\n  var OZONE_ABSORB = [0.65e-6, 1.881e-6, 0.085e-6];\n  var RAYLEIGH_SCALE_HEIGHT = 8e3;\n  var MIE_SCALE_HEIGHT = 1.2e3;\n  var GROUND_RADIUS = 6360000;\n  var TOP_RADIUS = 6460000;\n  var SUN_INTENSITY = 1.0;\n  var GRADIENT_SAMPLES = 32;\n  var INTEGRATION_SAMPLES = 8;\n  var FOV_DEG = 75;\n  var EXPOSURE = 25.0;\n  var GAMMA = 2.2;\n  var SUNSET_BIAS_STRENGTH = 0.1;\n\n  function rayleighPhase(cosAngle) {\n    return (3 * (1 + cosAngle * cosAngle)) / (16 * PI);\n  }\n\n  function miePhase(cosAngle) {\n    var g = 0.8;\n    var scale = 3 / (8 * PI);\n    var num = (1 - Math.pow(g, 2)) * (1 + cosAngle * cosAngle);\n    var denom = (2 + Math.pow(g, 2)) * Math.pow(1 + Math.pow(g, 2) - 2 * g * cosAngle, 3 / 2);\n    return (scale * num) / denom;\n  }\n\n  // Pre-allocate arrays to reduce garbage collection in hot loops\n  function computeTransmittance(height, angle) {\n    var rayOriginX = 0;\n    var rayOriginY = GROUND_RADIUS + height;\n    var rayOriginZ = 0;\n\n    var rayDirectionX = Math.sin(angle);\n    var rayDirectionY = Math.cos(angle);\n    var rayDirectionZ = 0;\n\n    var b = rayOriginX * rayDirectionX + rayOriginY * rayDirectionY + rayOriginZ * rayDirectionZ;\n    var c = (rayOriginX * rayOriginX + rayOriginY * rayOriginY + rayOriginZ * rayOriginZ) - (TOP_RADIUS * TOP_RADIUS);\n    var discr = b * b - c;\n\n    var distance;\n    if (discr < 0) distance = null;\n    else {\n      var sqrtDiscr = Math.sqrt(discr);\n      var t = -b - sqrtDiscr;\n      if (t < 0) distance = -b + sqrtDiscr;\n      else distance = t;\n    }\n\n    if (distance === null) return [1, 1, 1];\n\n    var segmentLength = distance / INTEGRATION_SAMPLES;\n    var tCurrent = 0.5 * segmentLength;\n\n    var odRayleigh = 0;\n    var odMie = 0;\n    var odOzone = 0;\n\n    for (var i = 0; i < INTEGRATION_SAMPLES; i++) {\n      // pos = rayOrigin + rayDirection * tCurrent\n      var posX = rayOriginX + rayDirectionX * tCurrent;\n      var posY = rayOriginY + rayDirectionY * tCurrent;\n      var posZ = rayOriginZ + rayDirectionZ * tCurrent;\n\n      var lenPos = Math.hypot(posX, posY, posZ);\n      var h = lenPos - GROUND_RADIUS;\n\n      var dR = Math.exp(-h / RAYLEIGH_SCALE_HEIGHT);\n      var dM = Math.exp(-h / MIE_SCALE_HEIGHT);\n      odRayleigh += dR * segmentLength;\n\n      var ozoneDensity = 1.0 - Math.min(Math.abs(h - 25e3) / 15e3, 1.0);\n      odOzone += ozoneDensity * segmentLength;\n      odMie += dM * segmentLength;\n\n      tCurrent += segmentLength;\n    }\n\n    var tauR0 = RAYLEIGH_SCATTER[0] * odRayleigh;\n    var tauR1 = RAYLEIGH_SCATTER[1] * odRayleigh;\n    var tauR2 = RAYLEIGH_SCATTER[2] * odRayleigh;\n\n    var tauM = MIE_ABSORB * odMie; // All components same\n\n    var tauO0 = OZONE_ABSORB[0] * odOzone;\n    var tauO1 = OZONE_ABSORB[1] * odOzone;\n    var tauO2 = OZONE_ABSORB[2] * odOzone;\n\n    // Return exp(-(tauR + tauM + tauO))\n    return [\n      Math.exp(-(tauR0 + tauM + tauO0)),\n      Math.exp(-(tauR1 + tauM + tauO1)),\n      Math.exp(-(tauR2 + tauM + tauO2))\n    ];\n  }\n\n  // ============================================================================\n  // Inject CSS Styles\n  // ============================================================================\n  \n  (function() {\n    // Only inject CSS once\n    if (document.getElementById('dynamic-sky-styles')) return;\n    \n    var css = [\n      '/* Sky Background Container */',\n      '#background-sky {',\n      '  position: fixed;',\n      '  top: 0;',\n      '  left: 0;',\n      '  width: 100vw;',\n      '  height: 100vh;',\n      '  height: 100dvh;',\n      '  z-index: -2;',\n      '  pointer-events: none;',\n      '  transition: opacity 0.5s ease-in-out;',\n      '  background-color: #121212;',\n      '  margin: 0;',\n      '  padding: 0;',\n      '}',\n      '',\n      '/* Stars Container */',\n      '#stars-container {',\n      '  position: fixed;',\n      '  top: 0;',\n      '  left: 0;',\n      '  width: 100%;',\n      '  height: 100vh;',\n      '  height: 100dvh;',\n      '  overflow: hidden;',\n      '  perspective: 100px;',\n      '  perspective-origin: 50% 50%;',\n      '  z-index: -1;',\n      '  pointer-events: none;',\n      '  transition: opacity 0.5s ease-in-out;',\n      '}',\n      '',\n      '.dynamic-sky-layer {',\n      '  position: absolute;',\n      '  top: 0;',\n      '  left: 0;',\n      '  width: 100%;',\n      '  height: 100%;',\n      '  transform: translateZ(0px);',\n      '}',\n      '',\n      '.dynamic-sky-star {',\n      '  position: absolute;',\n      '  width: 2px;',\n      '  height: 2px;',\n      '  background: #fff;',\n      '  border-radius: 1px;',\n      '}',\n      '',\n      '@media (max-width: 768px) {',\n      '  .dynamic-sky-star {',\n      '    opacity: 0.7;',\n      '  }',\n      '}'\n    ].join('\\n');\n    \n    var style = document.createElement('style');\n    style.id = 'dynamic-sky-styles';\n    style.type = 'text/css';\n    if (style.styleSheet) {\n      style.styleSheet.cssText = css;\n    } else {\n      style.appendChild(document.createTextNode(css));\n    }\n    document.head.appendChild(style);\n  })();\n\n  // ============================================================================\n  // SunCalc Auto-Loader\n  // ============================================================================\n  \n  // Promise that resolves when SunCalc is available\n  var sunCalcReadyPromise = null;\n  \n  // Function to ensure SunCalc is loaded\n  function ensureSunCalc() {\n    // If SunCalc is already available, return resolved promise\n    if (typeof global.SunCalc !== 'undefined') {\n      return Promise.resolve();\n    }\n    \n    // If we're already loading, return the existing promise\n    if (sunCalcReadyPromise) {\n      return sunCalcReadyPromise;\n    }\n    \n    // Check if we're in a browser environment\n    if (typeof document === 'undefined') {\n      return Promise.reject(new Error('SunCalc library not found and cannot be auto-loaded in this environment'));\n    }\n    \n    // Create promise for async loading\n    sunCalcReadyPromise = new Promise(function(resolve, reject) {\n      // Async script tag loading with Subresource Integrity (SRI)\n      var script = document.createElement('script');\n      // Use unminified version for stable SRI hash as per security policy\n      script.src = 'https://cdn.jsdelivr.net/npm/suncalc@1.9.0/suncalc.js';\n      script.integrity = 'sha384-oiKvfHOCwLd5BVeyS4Zc1WW9KNRFXyXCkijYVrNbvw6BzoPFC+HiHzZi8FlRAvQ3';\n      script.crossOrigin = 'anonymous';\n      script.async = true;\n      \n      script.onload = function() {\n        if (typeof global.SunCalc !== 'undefined') {\n          resolve();\n        } else {\n          reject(new Error('SunCalc script loaded but SunCalc object not found'));\n        }\n      };\n      \n      script.onerror = function() {\n        reject(new Error('Failed to load SunCalc from jsdelivr. Please check your network connection or include SunCalc manually.'));\n      };\n      \n      // Append to head or body\n      if (document.head) {\n        document.head.appendChild(script);\n      } else {\n        document.body.appendChild(script);\n      }\n    });\n    \n    return sunCalcReadyPromise;\n  }\n  \n  // Try to preload SunCalc immediately (non-blocking)\n  if (typeof document !== 'undefined' && typeof global.SunCalc === 'undefined') {\n    ensureSunCalc().catch(function(error) {\n      // Silently fail - will retry when init() is called\n      console.warn('DynamicSky: Could not preload SunCalc:', error.message);\n    });\n  }\n\n  // ============================================================================\n  // DynamicSky Library\n  // ============================================================================\n\n  // Utility functions\n  function clamp(x, min, max) {\n    return Math.max(min, Math.min(max, x));\n  }\n\n  // Note: add, scale, exp, dot, len, norm, intersectSphere removed as they are now inlined or unused.\n\n  /**\n   * DynamicSky Class\n   */\n  function DynamicSky(options) {\n    options = options || {};\n    \n    // Default configuration\n    this.config = {\n      // DOM selectors\n      skyContainer: options.skyContainer || '#background-sky',\n      starsContainer: options.starsContainer || '#stars-container',\n      \n      // Location\n      latitude: options.latitude || null,\n      longitude: options.longitude || null,\n      autoDetectLocation: options.autoDetectLocation !== false,\n      \n      // Sky rendering options\n      starLayers: options.starLayers || 3,\n      starDensity: options.starDensity || 5,\n      \n      // Callbacks\n      onUpdate: options.onUpdate || null,\n      onLocationDetected: options.onLocationDetected || null,\n      \n      // Location API\n      locationApiUrl: options.locationApiUrl || 'https://ipwho.is/'\n    };\n\n    // Internal state\n    this.skyElement = null;\n    this.starsElement = null;\n    this.starsCreated = false;\n    this.skyState = { diameter: 0 };\n    this.userLatitude = null;\n    this.userLongitude = null;\n    this.isInitialized = false;\n  }\n\n  DynamicSky.prototype.init = function() {\n    if (this.isInitialized) {\n      console.warn('DynamicSky already initialized');\n      return Promise.resolve(this);\n    }\n\n    // Get or create DOM elements\n    this.skyElement = document.querySelector(this.config.skyContainer);\n    this.starsElement = document.querySelector(this.config.starsContainer);\n\n    // Create containers if they don't exist\n    if (!this.skyElement) {\n      this.skyElement = document.createElement('div');\n      if (this.config.skyContainer.indexOf('#') === 0) {\n        // It's an ID selector\n        this.skyElement.id = this.config.skyContainer.substring(1);\n      } else if (this.config.skyContainer.indexOf('.') === 0) {\n        // It's a class selector\n        this.skyElement.className = this.config.skyContainer.substring(1);\n      }\n      document.body.appendChild(this.skyElement);\n    }\n\n    if (!this.starsElement) {\n      this.starsElement = document.createElement('div');\n      if (this.config.starsContainer.indexOf('#') === 0) {\n        // It's an ID selector\n        this.starsElement.id = this.config.starsContainer.substring(1);\n      } else if (this.config.starsContainer.indexOf('.') === 0) {\n        // It's a class selector\n        this.starsElement.className = this.config.starsContainer.substring(1);\n      }\n      document.body.appendChild(this.starsElement);\n    }\n    \n    // Detect if containers are inside another element (not direct children of body)\n    // If so, use absolute positioning instead of fixed\n    var skyParent = this.skyElement.parentElement;\n    var isContained = skyParent && skyParent !== document.body;\n    \n    if (isContained) {\n      // Ensure parent has relative positioning\n      var parentStyle = window.getComputedStyle(skyParent);\n      if (parentStyle.position === 'static') {\n        skyParent.style.position = 'relative';\n      }\n      \n      // Use absolute positioning for contained elements\n      this.skyElement.style.position = 'absolute';\n      this.skyElement.style.top = '0';\n      this.skyElement.style.left = '0';\n      this.skyElement.style.width = '100%';\n      this.skyElement.style.height = '100%';\n      this.skyElement.style.zIndex = '0';\n      this.skyElement.style.backgroundColor = '#121212';\n      this.skyElement.style.pointerEvents = 'none';\n      this.skyElement.style.margin = '0';\n      this.skyElement.style.padding = '0';\n      \n      this.starsElement.style.position = 'absolute';\n      this.starsElement.style.top = '0';\n      this.starsElement.style.left = '0';\n      this.starsElement.style.width = '100%';\n      this.starsElement.style.height = '100%';\n      this.starsElement.style.zIndex = '1';\n      this.starsElement.style.overflow = 'hidden';\n      this.starsElement.style.perspective = '100px';\n      this.starsElement.style.perspectiveOrigin = '50% 50%';\n    } else {\n      // Use fixed positioning for full-page backgrounds\n      this.skyElement.style.position = 'fixed';\n      this.skyElement.style.top = '0';\n      this.skyElement.style.left = '0';\n      this.skyElement.style.width = '100vw';\n      this.skyElement.style.height = '100dvh';\n      this.skyElement.style.zIndex = '-2';\n      \n      this.starsElement.style.position = 'fixed';\n      this.starsElement.style.top = '0';\n      this.starsElement.style.left = '0';\n      this.starsElement.style.width = '100%';\n      this.starsElement.style.height = '100%';\n      this.starsElement.style.height = '100dvh';\n      this.starsElement.style.zIndex = '-1';\n    }\n\n    var self = this;\n    \n    // Return a Promise that resolves after initialization\n    return new Promise(function(resolve, reject) {\n      // Ensure SunCalc is loaded before proceeding\n      ensureSunCalc().then(function() {\n        // Detect or use provided location\n        if (self.config.autoDetectLocation && (!self.config.latitude || !self.config.longitude)) {\n          self.detectLocation().then(function() {\n            self._initialRender();\n            resolve(self);\n          }).catch(function(error) {\n            // Even if location detection fails, use fallback and continue\n            self.userLatitude = 37.77;\n            self.userLongitude = -122.41;\n            self._initialRender();\n            resolve(self);\n          });\n        } else {\n          self.userLatitude = self.config.latitude || 37.77;\n          self.userLongitude = self.config.longitude || -122.41;\n          self._initialRender();\n          resolve(self);\n        }\n      }).catch(function(error) {\n        console.error('DynamicSky: Failed to load SunCalc:', error.message);\n        console.error('Please include SunCalc manually: <script src=\"https://cdn.jsdelivr.net/npm/suncalc@1.9.0/suncalc.min.js\"></script>');\n        reject(error);\n      });\n    });\n  };\n\n  DynamicSky.prototype._initialRender = function() {\n    // Initial render\n    this.updateSky();\n\n    this.isInitialized = true;\n    \n    // Dispatch event\n    var event = new CustomEvent('dynamic-sky-initialized', { \n      detail: { \n        latitude: this.userLatitude, \n        longitude: this.userLongitude \n      } \n    });\n    document.dispatchEvent(event);\n  };\n\n  DynamicSky.prototype.detectLocation = function() {\n    var self = this;\n    return fetch(this.config.locationApiUrl)\n      .then(function(response) {\n        if (!response.ok) {\n          throw new Error('API request failed with status ' + response.status);\n        }\n        return response.json();\n      })\n      .then(function(data) {\n        if (!data.success) {\n          throw new Error('API response indicates failure');\n        }\n        self.userLatitude = data.latitude;\n        self.userLongitude = data.longitude;\n        \n        if (self.config.onLocationDetected) {\n          self.config.onLocationDetected(self.userLatitude, self.userLongitude);\n        }\n      })\n      .catch(function(error) {\n        console.error('DynamicSky: Error getting location from IP API, using fallback:', error);\n        self.userLatitude = 37.77;\n        self.userLongitude = -122.41;\n      });\n  };\n\n  DynamicSky.prototype.updateSkyGeometry = function() {\n    // Check if container is inside another element\n    var skyParent = this.skyElement ? this.skyElement.parentElement : null;\n    var isContained = skyParent && skyParent !== document.body;\n    \n    if (isContained) {\n      // For contained elements, use the container's dimensions\n      var rect = skyParent.getBoundingClientRect();\n      var winW = rect.width;\n      var winH = rect.height;\n    } else {\n      // For full-page backgrounds, use viewport dimensions\n      var winW = window.innerWidth;\n      var winH = window.innerHeight;\n    }\n    \n    // Store dimensions for use in createSky\n    this.skyState.width = winW;\n    this.skyState.height = winH;\n    // Star field will be w*2 x h*2 centered on pivot point (10% below container)\n    this.skyState.starFieldWidth = winW * 2;\n    this.skyState.starFieldHeight = winH * 2;\n    // Use the larger dimension for diameter calculation\n    this.skyState.diameter = Math.max(this.skyState.starFieldWidth, this.skyState.starFieldHeight);\n  };\n\n  DynamicSky.prototype.createSky = function() {\n    if (this.starsCreated || !this.starsElement) {\n      return;\n    }\n\n    this.updateSkyGeometry();\n    var diameter = this.skyState.diameter;\n    \n    // Check if container is inside another element\n    var skyParent = this.skyElement ? this.skyElement.parentElement : null;\n    var isContained = skyParent && skyParent !== document.body;\n    \n    // Store these for use in nested functions\n    var self = this;\n\n    if (isContained) {\n      // For contained elements, use container dimensions for stars\n      var rect = skyParent.getBoundingClientRect();\n      var containerWidth = rect.width;\n      var containerHeight = rect.height;\n      \n      // Ensure container has dimensions, otherwise wait and retry\n      if (containerWidth === 0 || containerHeight === 0) {\n        var self = this;\n        setTimeout(function() {\n          self.createSky();\n        }, 100);\n        return;\n      }\n      \n      // Pivot point is at 10% of container height BELOW the container\n      // So pivot is at: (containerWidth/2, containerHeight + 0.1*containerHeight) = (w/2, 1.1*h)\n      // Star field should be w*2 x h*2 centered on this pivot point\n      var starFieldWidth = containerWidth * 2;\n      var starFieldHeight = containerHeight * 2;\n      diameter = Math.max(starFieldWidth, starFieldHeight);\n      // Store star field dimensions for star distribution\n      this.skyState.starFieldWidth = starFieldWidth;\n      this.skyState.starFieldHeight = starFieldHeight;\n      \n      // Position star field so pivot point is at its center\n      // Pivot point relative to container: (w/2, 1.1*h)\n      // Star field center should be at pivot, so star field top-left relative to container:\n      // left: w/2 - starFieldWidth/2 = w/2 - w = -w/2\n      // top: 1.1*h - starFieldHeight/2 = 1.1*h - h = 0.1*h\n      var pivotX = containerWidth / 2;\n      var pivotY = containerHeight * 1.1; // 10% below container\n      var starFieldLeft = pivotX - starFieldWidth / 2;\n      var starFieldTop = pivotY - starFieldHeight / 2;\n      \n      // Set stars container to calculated size and position it\n      this.starsElement.style.width = starFieldWidth + 'px';\n      this.starsElement.style.height = starFieldHeight + 'px';\n      this.starsElement.style.position = 'absolute';\n      this.starsElement.style.left = starFieldLeft + 'px';\n      this.starsElement.style.top = starFieldTop + 'px';\n      this.starsElement.style.transform = '';\n      this.starsElement.style.overflow = 'hidden';\n      this.starsElement.style.perspective = '100px';\n      this.starsElement.style.perspectiveOrigin = '50% 50%';\n      this.starsElement.style.pointerEvents = 'none';\n    } else {\n      // For full-page backgrounds, pivot point is at 10% of viewport height BELOW viewport\n      var viewportWidth = window.innerWidth;\n      var viewportHeight = window.innerHeight;\n      \n      // Star field should be w*2 x h*2 centered on pivot point\n      var starFieldWidth = viewportWidth * 2;\n      var starFieldHeight = viewportHeight * 2;\n      diameter = Math.max(starFieldWidth, starFieldHeight);\n      // Store star field dimensions for star distribution\n      this.skyState.starFieldWidth = starFieldWidth;\n      this.skyState.starFieldHeight = starFieldHeight;\n      \n      // Pivot point: (viewportWidth/2, viewportHeight * 1.1)\n      var pivotX = viewportWidth / 2;\n      var pivotY = viewportHeight * 1.1; // 10% below viewport\n      var starFieldLeft = pivotX - starFieldWidth / 2;\n      var starFieldTop = pivotY - starFieldHeight / 2;\n      \n      this.starsElement.style.width = starFieldWidth + 'px';\n      this.starsElement.style.height = starFieldHeight + 'px';\n      this.starsElement.style.position = 'fixed';\n      this.starsElement.style.left = starFieldLeft + 'px';\n      this.starsElement.style.top = starFieldTop + 'px';\n      this.starsElement.style.transform = '';\n      this.starsElement.style.overflow = 'hidden';\n    }\n\n    // Adjust density for mobile\n    var density = this.config.starDensity;\n    if (window.innerWidth <= 768) {\n      density = 2;\n    }\n\n    this.starsElement.dataset.allowbreathe = true;\n\n    // Calculate star density based on container type\n    // Keep star count the same as original (based on visible area w x h)\n    // Stars will be distributed across the larger star field (w*2 x h*2)\n    var screenArea, containerArea, areaScale;\n    if (isContained) {\n      // For contained elements, use container dimensions (original visible area)\n      var rect = skyParent.getBoundingClientRect();\n      screenArea = rect.width * rect.height;\n      // Use original visible area for star count calculation to keep count the same\n      containerArea = screenArea; // Same as visible area, not the larger star field\n      areaScale = containerArea / screenArea; // This will be 1.0, keeping original star count\n      // Scale down density for smaller containers\n      density = density * Math.min(1, screenArea / (800 * 600));\n    } else {\n      // For full-page backgrounds, use viewport dimensions (original visible area)\n      screenArea = window.innerWidth * window.innerHeight;\n      // Use original visible area for star count calculation to keep count the same\n      containerArea = screenArea; // Same as visible area, not the larger star field\n      areaScale = containerArea / screenArea; // This will be 1.0, keeping original star count\n    }\n\n    var layers = this.config.starLayers;\n    for (var i = 0; i < layers; i++) {\n      var newLayer = document.createElement(\"DIV\");\n      var baseStarsCount = density * (200 * (0.5 / (i + 1)));\n      var starsCount = Math.floor(baseStarsCount * areaScale);\n\n      var fracComplete = (i + 1) / layers;\n      var op = fracComplete + 0.1;\n\n      newLayer.className = \"dynamic-sky-layer dynamic-sky-layer\" + i;\n      newLayer.style.zIndex = i;\n      newLayer.style.opacity = op;\n      newLayer.dataset.stars = starsCount;\n      newLayer.dataset.zoom = 1 + 2 * Math.pow(1.5, i);\n      this.starsElement.appendChild(newLayer);\n    }\n\n    var layerNodes = this.starsElement.querySelectorAll(\".dynamic-sky-layer\");\n    var self = this;\n\n    function initStars(layer) {\n      var starsCount = parseInt(layer.dataset.stars);\n      \n      // Use the actual star field dimensions (w*2 x h*2) for star distribution\n      var w = self.skyState.starFieldWidth || diameter;\n      var h = self.skyState.starFieldHeight || diameter;\n\n      for (var i = 0; i < starsCount; i++) {\n        var star = document.createElement(\"DIV\");\n        var xVal = Math.random() * w;\n        var yVal = Math.random() * h;\n        var blue = \"rgb(255,\" + (255 - Math.ceil(10 * Math.random())) + \",\" + (255 - Math.ceil(20 * Math.random())) + \")\";\n        var red = \"rgb(\" + (255 - Math.ceil(20 * Math.random())) + \",255,255)\";\n\n        star.className = \"dynamic-sky-star\";\n        star.style.left = xVal + \"px\";\n        star.style.top = yVal + \"px\";\n\n        if (i % 2 == 0) {\n          star.style.backgroundColor = blue;\n        } else {\n          star.style.backgroundColor = red;\n        }\n\n        layer.appendChild(star);\n      }\n    }\n\n    for (var i = 0; i < layerNodes.length; i++) {\n      initStars(layerNodes[i]);\n    }\n\n    this.startBreathingAnimation();\n    this.starsCreated = true;\n  };\n\n  DynamicSky.prototype.startBreathingAnimation = function(speed) {\n    speed = speed || 10000;\n    if (!this.starsElement) return;\n\n    var layerNodes = this.starsElement.querySelectorAll(\".dynamic-sky-layer\");\n    var self = this;\n\n    for (var i = 0; i < layerNodes.length; i++) {\n      var layer = layerNodes[i];\n      var transition = \"transform \" + speed + \"ms ease-in-out\";\n      layer.style.transition = transition;\n      layer.style.WebkitTransition = \"-webkit-\" + transition;\n      layer.style.MozTransition = \"-moz-\" + transition;\n      layer.style.MsTransition = \"-ms-\" + transition;\n      layer.style.OTransition = \"-o-\" + transition;\n\n      var transform = \"translateZ(0.1px)\";\n      layer.style.transform = transform;\n      layer.style.WebkitTransform = transform;\n      layer.style.MozTransform = transform;\n      layer.style.MsTransform = transform;\n      layer.style.OTransform = transform;\n\n      this.breatheIn(layer, speed);\n    }\n  };\n\n  DynamicSky.prototype.breatheIn = function(layer, speed) {\n    var self = this;\n    if (this.starsElement.dataset.allowbreathe === 'false') { return; }\n    layer.style.transform = \"translateZ(\" + layer.dataset.zoom + \"px)\";\n    setTimeout(function() {\n      self.breatheOut(layer, speed);\n    }, speed);\n  };\n\n  DynamicSky.prototype.breatheOut = function(layer, speed) {\n    var self = this;\n    if (this.starsElement.dataset.allowbreathe === 'false') { return; }\n    layer.style.transform = \"translateZ(0px)\";\n    setTimeout(function() {\n      self.breatheIn(layer, speed);\n    }, speed);\n  };\n\n  DynamicSky.prototype.renderGradient = function(altitude) {\n    var cameraPositionX = 0;\n    var cameraPositionY = GROUND_RADIUS;\n    var cameraPositionZ = 0;\n\n    // norm([Math.cos(altitude), Math.sin(altitude), 0])\n    // The vector is already normalized as cos^2 + sin^2 = 1.\n    var sunDirectionX = Math.cos(altitude);\n    var sunDirectionY = Math.sin(altitude);\n    var sunDirectionZ = 0;\n\n    var focalZ = 1.0 / Math.tan((FOV_DEG * 0.5 * PI) / 180.0);\n\n    var stops = [];\n\n    // Helper to clamp values in stops\n    function clampVal(x) {\n      return x < 0 ? 0 : (x > 1 ? 1 : x);\n    }\n\n    for (var i = 0; i < GRADIENT_SAMPLES; i++) {\n      var s = i / (GRADIENT_SAMPLES - 1);\n\n      // viewDirection = norm([0, s, focalZ])\n      var vdX = 0;\n      var vdY = s;\n      var vdZ = focalZ;\n      var vdLen = Math.hypot(vdX, vdY, vdZ) || 1;\n      vdX /= vdLen;\n      vdY /= vdLen;\n      vdZ /= vdLen;\n\n      var inscatteredX = 0;\n      var inscatteredY = 0;\n      var inscatteredZ = 0;\n\n      // intersectSphere(cameraPosition, viewDirection, TOP_RADIUS)\n      // cameraPosition is 0, GROUND_RADIUS, 0\n      var b = cameraPositionY * vdY; // other terms are 0\n      var c = (cameraPositionY * cameraPositionY) - (TOP_RADIUS * TOP_RADIUS);\n      var discr = b * b - c;\n\n      var tExitTop = null;\n      if (discr >= 0) {\n        var sqrtDiscr = Math.sqrt(discr);\n        var t = -b - sqrtDiscr;\n        if (t < 0) t = -b + sqrtDiscr;\n        tExitTop = t;\n      }\n\n      if (tExitTop !== null && tExitTop > 0) {\n        var rayOriginX = cameraPositionX;\n        var rayOriginY = cameraPositionY;\n        var rayOriginZ = cameraPositionZ;\n\n        var segmentLength = tExitTop / INTEGRATION_SAMPLES;\n        var tRay = segmentLength * 0.5;\n\n        // rayOriginRadius is just cameraPositionY because x and z are 0\n        var rayOriginRadius = cameraPositionY;\n\n        // dot(rayOrigin, viewDirection) -> rayOriginY * vdY\n        var isRayPointingDownwardAtStart = (rayOriginY * vdY) / rayOriginRadius < 0.0;\n\n        var startHeight = rayOriginRadius - GROUND_RADIUS;\n\n        // startRayCos = clamp(dot(rayOrigin/radius, viewDirection), -1, 1)\n        // rayOrigin/radius is [0, 1, 0]\n        // dot is vdY\n        var startRayCos = vdY;\n        if (startRayCos < -1) startRayCos = -1;\n        if (startRayCos > 1) startRayCos = 1;\n\n        var startRayAngle = Math.acos(Math.abs(startRayCos));\n        var transmittanceCameraToSpace = computeTransmittance(\n          startHeight,\n          startRayAngle\n        );\n\n        // sunViewCos = clamp(dot(sunDirection, viewDirection), -1, 1)\n        var sunViewCos = sunDirectionX * vdX + sunDirectionY * vdY + sunDirectionZ * vdZ;\n        if (sunViewCos < -1) sunViewCos = -1;\n        if (sunViewCos > 1) sunViewCos = 1;\n\n        var phaseR = rayleighPhase(sunViewCos);\n        var phaseM = miePhase(sunViewCos);\n\n        for (var j = 0; j < INTEGRATION_SAMPLES; j++) {\n          // samplePos = rayOrigin + viewDirection * tRay\n          var samplePosX = rayOriginX + vdX * tRay;\n          var samplePosY = rayOriginY + vdY * tRay;\n          var samplePosZ = rayOriginZ + vdZ * tRay;\n\n          var sampleRadius = Math.hypot(samplePosX, samplePosY, samplePosZ);\n\n          var upUnitX = samplePosX / sampleRadius;\n          var upUnitY = samplePosY / sampleRadius;\n          var upUnitZ = samplePosZ / sampleRadius;\n\n          var sampleHeight = sampleRadius - GROUND_RADIUS;\n\n          // viewCos = clamp(dot(upUnit, viewDirection), -1, 1)\n          var viewCos = upUnitX * vdX + upUnitY * vdY + upUnitZ * vdZ;\n          if (viewCos < -1) viewCos = -1;\n          if (viewCos > 1) viewCos = 1;\n\n          // sunCos = clamp(dot(upUnit, sunDirection), -1, 1)\n          var sunCos = upUnitX * sunDirectionX + upUnitY * sunDirectionY + upUnitZ * sunDirectionZ;\n          if (sunCos < -1) sunCos = -1;\n          if (sunCos > 1) sunCos = 1;\n\n          var viewAngle = Math.acos(Math.abs(viewCos));\n          var sunAngle = Math.acos(sunCos);\n\n          var transmittanceToSpace = computeTransmittance(\n            sampleHeight,\n            viewAngle\n          );\n\n          var transmittanceCameraToSample0, transmittanceCameraToSample1, transmittanceCameraToSample2;\n\n          if (isRayPointingDownwardAtStart) {\n            transmittanceCameraToSample0 = transmittanceToSpace[0] / transmittanceCameraToSpace[0];\n            transmittanceCameraToSample1 = transmittanceToSpace[1] / transmittanceCameraToSpace[1];\n            transmittanceCameraToSample2 = transmittanceToSpace[2] / transmittanceCameraToSpace[2];\n          } else {\n            transmittanceCameraToSample0 = transmittanceCameraToSpace[0] / transmittanceToSpace[0];\n            transmittanceCameraToSample1 = transmittanceCameraToSpace[1] / transmittanceToSpace[1];\n            transmittanceCameraToSample2 = transmittanceCameraToSpace[2] / transmittanceToSpace[2];\n          }\n\n          var transmittanceLight = computeTransmittance(sampleHeight, sunAngle);\n          var opticalDensityRay = Math.exp(\n            -sampleHeight / RAYLEIGH_SCALE_HEIGHT\n          );\n          var opticalDensityMie = Math.exp(-sampleHeight / MIE_SCALE_HEIGHT);\n\n          // Rayleigh and Mie terms\n          // rayleighTerm[k] = RAYLEIGH_SCATTER[k] * opticalDensityRay * phaseR\n          // mieTerm = MIE_SCATTER * opticalDensityMie * phaseM (same for all channels)\n\n          var mieTerm = MIE_SCATTER * opticalDensityMie * phaseM;\n\n          var rayleighTerm0 = RAYLEIGH_SCATTER[0] * opticalDensityRay * phaseR;\n          var scatteredRgb0 = transmittanceLight[0] * (rayleighTerm0 + mieTerm);\n\n          var rayleighTerm1 = RAYLEIGH_SCATTER[1] * opticalDensityRay * phaseR;\n          var scatteredRgb1 = transmittanceLight[1] * (rayleighTerm1 + mieTerm);\n\n          var rayleighTerm2 = RAYLEIGH_SCATTER[2] * opticalDensityRay * phaseR;\n          var scatteredRgb2 = transmittanceLight[2] * (rayleighTerm2 + mieTerm);\n\n          inscatteredX += transmittanceCameraToSample0 * scatteredRgb0 * segmentLength;\n          inscatteredY += transmittanceCameraToSample1 * scatteredRgb1 * segmentLength;\n          inscatteredZ += transmittanceCameraToSample2 * scatteredRgb2 * segmentLength;\n\n          tRay += segmentLength;\n        }\n\n        inscatteredX *= SUN_INTENSITY;\n        inscatteredY *= SUN_INTENSITY;\n        inscatteredZ *= SUN_INTENSITY;\n      }\n\n      // Exposure\n      var c0 = inscatteredX * EXPOSURE;\n      var c1 = inscatteredY * EXPOSURE;\n      var c2 = inscatteredZ * EXPOSURE;\n\n      // Apply Sunset Bias\n      var lum = 0.2126 * c0 + 0.7152 * c1 + 0.0722 * c2;\n      var w = 1.0 / (1.0 + 2.0 * lum);\n      var k = SUNSET_BIAS_STRENGTH;\n      var rb = 1.0 + 0.5 * k * w;\n      var gb = 1.0 - 0.5 * k * w;\n      var bb = 1.0 + 1.0 * k * w;\n\n      c0 = Math.max(0, c0 * rb);\n      c1 = Math.max(0, c1 * gb);\n      c2 = Math.max(0, c2 * bb);\n\n      // ACES Tone Mapping (inlined)\n      // n = c * (2.51 * c + 0.03)\n      // d = c * (2.43 * c + 0.59) + 0.14\n      // val = n / d\n\n      var n0 = c0 * (2.51 * c0 + 0.03);\n      var d0 = c0 * (2.43 * c0 + 0.59) + 0.14;\n      c0 = Math.max(0, Math.min(1, n0 / d0));\n\n      var n1 = c1 * (2.51 * c1 + 0.03);\n      var d1 = c1 * (2.43 * c1 + 0.59) + 0.14;\n      c1 = Math.max(0, Math.min(1, n1 / d1));\n\n      var n2 = c2 * (2.51 * c2 + 0.03);\n      var d2 = c2 * (2.43 * c2 + 0.59) + 0.14;\n      c2 = Math.max(0, Math.min(1, n2 / d2));\n\n      // Gamma Correction\n      var invGamma = 1.0 / GAMMA;\n      c0 = Math.pow(c0, invGamma);\n      c1 = Math.pow(c1, invGamma);\n      c2 = Math.pow(c2, invGamma);\n\n      var r = Math.round(clampVal(c0) * 255);\n      var g = Math.round(clampVal(c1) * 255);\n      var b = Math.round(clampVal(c2) * 255);\n\n      var percent = (1 - s) * 100;\n      stops.push({ percent: percent, rgb: [r, g, b] });\n    }\n\n    stops.sort(function(a, b) { return a.percent - b.percent; });\n    var colorStops = stops\n      .map(function(stop) {\n        return \"rgb(\" + stop.rgb[0] + \", \" + stop.rgb[1] + \", \" + stop.rgb[2] + \") \" +\n               (Math.round(stop.percent * 100) / 100) + \"%\";\n      })\n      .join(\", \");\n    return [\n      \"linear-gradient(to bottom, \" + colorStops + \")\",\n      stops[0].rgb,\n      stops[stops.length - 1].rgb,\n    ];\n  };\n\n  /**\n   * Update the sky background for a specific date/time\n   * This is the main method that sliders should call\n   * \n   * @param {Date} date - The date/time to render the sky for. If not provided, uses current time.\n   */\n  DynamicSky.prototype.updateSky = function(date) {\n    if (!this.userLatitude || !this.userLongitude) {\n      console.warn('DynamicSky: Location not set. Call init() first or provide latitude/longitude.');\n      return;\n    }\n    \n    // Ensure SunCalc is available\n    if (typeof global.SunCalc === 'undefined') {\n      console.error('DynamicSky: SunCalc is not available. Please ensure SunCalc is loaded.');\n      return;\n    }\n\n    this.createSky();\n\n    var now = date || new Date();\n    var times = SunCalc.getTimes(now, this.userLatitude, this.userLongitude);\n    var sunPos = SunCalc.getPosition(now, this.userLatitude, this.userLongitude);\n\n    var renderAltitude = sunPos.altitude;\n\n    var sunsetAltitude = -0.833 * (Math.PI / 180);\n    var duskAltitude = -6 * (Math.PI / 180);\n    var dawnAltitude = -6 * (Math.PI / 180);\n    var sunriseAltitude = -0.833 * (Math.PI / 180);\n    var visualTwilightBottomAltitude = -3 * (Math.PI / 180);\n\n    if (now > times.sunset && now < times.dusk) {\n      var twilightProgress = (now - times.sunset) / (times.dusk - times.sunset);\n      renderAltitude = sunsetAltitude + twilightProgress * (visualTwilightBottomAltitude - sunsetAltitude);\n    }\n\n    if (now > times.dawn && now < times.sunrise) {\n      var twilightProgress = (now - times.dawn) / (times.sunrise - times.dawn);\n      renderAltitude = visualTwilightBottomAltitude + twilightProgress * (sunriseAltitude - visualTwilightBottomAltitude);\n    }\n\n    var gradient = this.renderGradient(renderAltitude)[0];\n\n    if (this.skyElement) {\n      this.skyElement.style.backgroundImage = gradient;\n    }\n\n    // Handle stars visibility\n    if (this.starsElement) {\n      var twilightBeginsAltitude = 0;\n      var fullNightAltitude = -6 * (Math.PI / 180);\n      var nightIntensity = 0;\n\n      if (sunPos.altitude < twilightBeginsAltitude) {\n        var transitionRange = fullNightAltitude - twilightBeginsAltitude;\n        var progress = (sunPos.altitude - twilightBeginsAltitude) / transitionRange;\n        nightIntensity = clamp(progress, 0, 1.0);\n      }\n\n      this.starsElement.style.opacity = nightIntensity;\n      if (this.starsElement.dataset) {\n        this.starsElement.dataset.allowbreathe = nightIntensity > 0;\n      }\n\n      // Star rotation\n      // Rotate around the pivot point (center of star field, which is 10% below container)\n      var msInDay = 86400000;\n      var currentMs = (now.getHours() * 3600000) + (now.getMinutes() * 60000) + (now.getSeconds() * 1000) + now.getMilliseconds();\n      var rotationDegrees = (currentMs / msInDay) * 360;\n      \n      // Set transform-origin to center of star field (50% 50%)\n      // The star field is positioned so its center is at the pivot point (10% below container)\n      // This creates an arc effect as stars rotate around this lower pivot point\n      this.starsElement.style.transformOrigin = '50% 50%';\n      \n      // Apply rotation - positioning is already handled in createSky()\n      this.starsElement.style.transform = \"rotate(\" + rotationDegrees + \"deg)\";\n    }\n\n    // Callback\n    if (this.config.onUpdate) {\n      this.config.onUpdate({\n        date: now,\n        sunPosition: sunPos,\n        sunTimes: times\n      });\n    }\n  };\n\n\n  /**\n   * Set the location coordinates manually\n   * \n   * @param {number} latitude - Latitude coordinate\n   * @param {number} longitude - Longitude coordinate\n   */\n  DynamicSky.prototype.setLocation = function(latitude, longitude) {\n    this.userLatitude = latitude;\n    this.userLongitude = longitude;\n    this.updateSky();\n  };\n\n  /**\n   * Convert minutes of day (0-1440) to a Date object for today\n   * Useful for sliders that work with minutes\n   * \n   * @param {number} minutes - Minutes since midnight (0-1440)\n   * @returns {Date} Date object for today at the specified minutes\n   */\n  DynamicSky.prototype.minutesToDate = function(minutes) {\n    var now = new Date();\n    return new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, minutes);\n  };\n\n  /**\n   * Convert a percentage (0-1) to a Date object for today\n   * Useful for sliders that work with percentages\n   * \n   * @param {number} percent - Percentage of day (0 = midnight, 1 = next midnight)\n   * @returns {Date} Date object for today at the specified percentage\n   */\n  DynamicSky.prototype.percentToDate = function(percent) {\n    var minutes = Math.round(percent * 1440) % 1440;\n    return this.minutesToDate(minutes);\n  };\n\n  /**\n   * Convert hours (0-24) to a Date object for today\n   * Useful for sliders that work with hours\n   * \n   * @param {number} hours - Hours since midnight (0-24)\n   * @returns {Date} Date object for today at the specified hours\n   */\n  DynamicSky.prototype.hoursToDate = function(hours) {\n    var minutes = Math.round(hours * 60) % 1440;\n    return this.minutesToDate(minutes);\n  };\n\n  /**\n   * Convert a Date object to minutes of day (0-1440)\n   * Useful for getting current time in slider-friendly format\n   * \n   * @param {Date} date - Date object (defaults to current time)\n   * @returns {number} Minutes since midnight\n   */\n  DynamicSky.prototype.dateToMinutes = function(date) {\n    date = date || new Date();\n    var startOfDay = new Date(date.getFullYear(), date.getMonth(), date.getDate());\n    return Math.round((date - startOfDay) / 60000);\n  };\n\n  /**\n   * Convert a Date object to percentage of day (0-1)\n   * Useful for getting current time in slider-friendly format\n   * \n   * @param {Date} date - Date object (defaults to current time)\n   * @returns {number} Percentage of day (0-1)\n   */\n  DynamicSky.prototype.dateToPercent = function(date) {\n    return this.dateToMinutes(date) / 1440;\n  };\n\n  /**\n   * Clean up and destroy the instance\n   */\n  DynamicSky.prototype.destroy = function() {\n    this.isInitialized = false;\n  };\n\n  // Export to global scope\n  global.DynamicSky = DynamicSky;\n\n})(typeof window !== 'undefined' ? window : this);\n"]}