From bf7238468166aa2ebfed846dde7d8cfca504dd78 Mon Sep 17 00:00:00 2001 From: AEmotionStudio <163354043+AEmotionStudio@users.noreply.github.com> Date: Sat, 10 Jan 2026 05:35:48 -0800 Subject: [PATCH] chore: update .gitignore and remove tracked build artifacts --- .gitignore | 28 +++++++++++- js/aether-snow.js.map | 1 - js/background-themes.js.map | 1 - js/christmas-sidebar.js.map | 1 - js/link_animations.js.map | 1 - js/settings-cache.js.map | 1 - playwright-report/index.html | 85 ------------------------------------ test-results/.last-run.json | 4 -- 8 files changed, 27 insertions(+), 95 deletions(-) delete mode 100644 js/aether-snow.js.map delete mode 100644 js/background-themes.js.map delete mode 100644 js/christmas-sidebar.js.map delete mode 100644 js/link_animations.js.map delete mode 100644 js/settings-cache.js.map delete mode 100644 playwright-report/index.html delete mode 100644 test-results/.last-run.json diff --git a/.gitignore b/.gitignore index e35fd64..a41129d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ +# Python __pycache__/ -Browser_Console_Erros_2.md +*.py[cod] +*.egg-info/ # Node.js node_modules/ @@ -7,13 +9,37 @@ node_modules/ # TypeScript *.tsbuildinfo +# Source maps (generated during build) +*.js.map + # Build artifacts (generated from src/) web/ +dist/ # Testing test-results/ playwright-report/ coverage/ +# Environment files +.env +.env.* +!.env.example + +# OS files +.DS_Store +Thumbs.db + +# IDE settings (optional) +.vscode/ +.idea/ + +# Logs +*.log +npm-debug.log* + +# Project-specific +Browser_Console_Erros_2.md + # Lock files (optional - remove if you want to track) # pnpm-lock.yaml \ No newline at end of file diff --git a/js/aether-snow.js.map b/js/aether-snow.js.map deleted file mode 100644 index bbdb065..0000000 --- a/js/aether-snow.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"aether-snow.js","sources":["../src/aether-snow.ts"],"sourcesContent":["/**\n * aether-snow.ts - Foreground snowfall effect (DOM-based with JS animation)\n * Background snowflakes are rendered via canvas in background-themes.ts for proper depth\n */\n\n// @ts-ignore - ComfyUI external module\nimport { app } from \"../../scripts/app.js\";\nimport { getSetting, updateCache, loadSettingFromStorage, COLOR_SCHEMES } from \"./settings-cache\";\nimport { isPageVisible, isExecuting } from \"./background-themes\";\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\ninterface SnowflakeConfig {\n MIN_SIZE: number;\n MAX_SIZE: number;\n FLAKE_COUNTS: {\n high: number;\n medium: number;\n low: number;\n };\n BATCH_SIZE: number;\n}\n\ninterface FlakeEntity {\n x: number;\n y: number;\n size: number;\n opacity: number;\n color: string;\n speed: number;\n drift: number;\n driftSpeed: number;\n driftOffset: number;\n rotation: number;\n rotationSpeed: number;\n flakeType: string;\n element: HTMLDivElement | null;\n}\n\ntype PerformanceTier = 'high' | 'medium' | 'low';\ntype SnowflakeGenerator = (size: number) => string;\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst SNOWFLAKE_CONFIG: SnowflakeConfig = {\n MIN_SIZE: 8,\n MAX_SIZE: 18,\n FLAKE_COUNTS: {\n high: 50,\n medium: 35,\n low: 20\n },\n BATCH_SIZE: 5\n};\n\n// SVG snowflake path generators - 8 designs total\nconst SNOWFLAKE_TYPES: Record = {\n // Branched - 6 arms with side branches\n branched: (size: number): string => {\n let d = '';\n for (let i = 0; i < 6; i++) {\n const angle = (Math.PI / 3) * i;\n const cos = Math.cos(angle), sin = Math.sin(angle);\n d += `M ${size / 2} ${size / 2} L ${size / 2 + sin * size * 0.45} ${size / 2 - cos * size * 0.45} `;\n const bx = size / 2 + sin * size * 0.25, by = size / 2 - cos * size * 0.25;\n const bLen = size * 0.15;\n const bAngle = Math.PI / 5;\n d += `M ${bx} ${by} L ${bx + Math.sin(angle - bAngle) * bLen} ${by - Math.cos(angle - bAngle) * bLen} `;\n d += `M ${bx} ${by} L ${bx + Math.sin(angle + bAngle) * bLen} ${by - Math.cos(angle + bAngle) * bLen} `;\n }\n return d;\n },\n\n minimal: (size: number): string => {\n let d = '';\n for (let i = 0; i < 6; i++) {\n const angle = (Math.PI / 3) * i;\n const cos = Math.cos(angle), sin = Math.sin(angle);\n d += `M ${size / 2} ${size / 2} L ${size / 2 + sin * size * 0.45} ${size / 2 - cos * size * 0.45} `;\n const bx = size / 2 + sin * size * 0.25, by = size / 2 - cos * size * 0.25;\n const bLen = size * 0.12;\n d += `M ${bx} ${by} L ${bx + Math.sin(angle - Math.PI / 4) * bLen} ${by - Math.cos(angle - Math.PI / 4) * bLen} `;\n d += `M ${bx} ${by} L ${bx + Math.sin(angle + Math.PI / 4) * bLen} ${by - Math.cos(angle + Math.PI / 4) * bLen} `;\n }\n return d;\n },\n\n stellar: (size: number): string => {\n let d = '';\n for (let i = 0; i < 6; i++) {\n const angle = (Math.PI / 3) * i;\n const cos = Math.cos(angle), sin = Math.sin(angle);\n d += `M ${size / 2} ${size / 2} L ${size / 2 + sin * size * 0.45} ${size / 2 - cos * size * 0.45} `;\n [0.2, 0.32].forEach(pos => {\n const bx = size / 2 + sin * size * pos, by = size / 2 - cos * size * pos;\n const bLen = size * (0.18 - pos * 0.3);\n d += `M ${bx} ${by} L ${bx + Math.sin(angle - Math.PI / 4) * bLen} ${by - Math.cos(angle - Math.PI / 4) * bLen} `;\n d += `M ${bx} ${by} L ${bx + Math.sin(angle + Math.PI / 4) * bLen} ${by - Math.cos(angle + Math.PI / 4) * bLen} `;\n });\n }\n return d;\n },\n\n emoji1: (size: number): string => {\n let d = '';\n for (let i = 0; i < 6; i++) {\n const angle = (Math.PI / 3) * i;\n const cos = Math.cos(angle), sin = Math.sin(angle);\n const tipX = size / 2 + sin * size * 0.45, tipY = size / 2 - cos * size * 0.45;\n d += `M ${size / 2} ${size / 2} L ${tipX} ${tipY} `;\n const tip = size * 0.06;\n d += `M ${tipX - cos * tip} ${tipY - sin * tip} L ${tipX} ${tipY} L ${tipX + cos * tip} ${tipY + sin * tip} `;\n const bx = size / 2 + sin * size * 0.27, by = size / 2 - cos * size * 0.27;\n const bLen = size * 0.13;\n d += `M ${bx} ${by} L ${bx + Math.sin(angle - Math.PI / 4) * bLen} ${by - Math.cos(angle - Math.PI / 4) * bLen} `;\n d += `M ${bx} ${by} L ${bx + Math.sin(angle + Math.PI / 4) * bLen} ${by - Math.cos(angle + Math.PI / 4) * bLen} `;\n }\n return d;\n },\n\n emoji2: (size: number): string => {\n let d = '';\n for (let i = 0; i < 6; i++) {\n const angle = (Math.PI / 3) * i;\n const cos = Math.cos(angle), sin = Math.sin(angle);\n d += `M ${size / 2 + sin * size * 0.08} ${size / 2 - cos * size * 0.08} L ${size / 2 + sin * size * 0.45} ${size / 2 - cos * size * 0.45} `;\n const cx = size / 2 + sin * size * 0.3, cy = size / 2 - cos * size * 0.3;\n const cLen = size * 0.05;\n d += `M ${cx - cos * cLen} ${cy - sin * cLen} L ${cx + cos * cLen} ${cy + sin * cLen} `;\n }\n return d;\n },\n\n emoji3: (size: number): string => {\n let d = '';\n for (let i = 0; i < 6; i++) {\n const angle = (Math.PI / 3) * i;\n const cos = Math.cos(angle), sin = Math.sin(angle);\n d += `M ${size / 2} ${size / 2} L ${size / 2 + sin * size * 0.45} ${size / 2 - cos * size * 0.45} `;\n const cx = size / 2 + sin * size * 0.22, cy = size / 2 - cos * size * 0.22;\n const cLen = size * 0.12;\n const cAngle = Math.PI / 5;\n d += `M ${cx + Math.sin(angle - cAngle) * cLen} ${cy - Math.cos(angle - cAngle) * cLen * 0.7} L ${cx} ${cy} L ${cx + Math.sin(angle + cAngle) * cLen} ${cy - Math.cos(angle + cAngle) * cLen * 0.7} `;\n }\n return d;\n },\n\n // Dendrite - fernlike with multiple branch levels\n dendrite: (size: number): string => {\n let d = '';\n for (let i = 0; i < 6; i++) {\n const angle = (Math.PI / 3) * i;\n const cos = Math.cos(angle), sin = Math.sin(angle);\n d += `M ${size / 2} ${size / 2} L ${size / 2 + sin * size * 0.45} ${size / 2 - cos * size * 0.45} `;\n [0.18, 0.28, 0.38].forEach((pos, idx) => {\n const bx = size / 2 + sin * size * pos, by = size / 2 - cos * size * pos;\n const bLen = size * (0.14 - idx * 0.03);\n const bAngle = Math.PI / 4;\n d += `M ${bx} ${by} L ${bx + Math.sin(angle - bAngle) * bLen} ${by - Math.cos(angle - bAngle) * bLen} `;\n d += `M ${bx} ${by} L ${bx + Math.sin(angle + bAngle) * bLen} ${by - Math.cos(angle + bAngle) * bLen} `;\n });\n }\n return d;\n },\n\n // Ornate - decorative with diamond tips\n ornate: (size: number): string => {\n let d = '';\n for (let i = 0; i < 6; i++) {\n const angle = (Math.PI / 3) * i;\n const cos = Math.cos(angle), sin = Math.sin(angle);\n const tipX = size / 2 + sin * size * 0.42, tipY = size / 2 - cos * size * 0.42;\n d += `M ${size / 2} ${size / 2} L ${tipX} ${tipY} `;\n const dSize = size * 0.05;\n d += `M ${tipX} ${tipY - dSize} L ${tipX + dSize * 0.7} ${tipY} L ${tipX} ${tipY + dSize} L ${tipX - dSize * 0.7} ${tipY} Z `;\n const bx = size / 2 + sin * size * 0.22, by = size / 2 - cos * size * 0.22;\n const bLen = size * 0.14;\n d += `M ${bx} ${by} L ${bx + Math.sin(angle - Math.PI / 3) * bLen} ${by - Math.cos(angle - Math.PI / 3) * bLen} `;\n d += `M ${bx} ${by} L ${bx + Math.sin(angle + Math.PI / 3) * bLen} ${by - Math.cos(angle + Math.PI / 3) * bLen} `;\n }\n return d;\n }\n};\n\nconst FLAKE_TYPE_NAMES = Object.keys(SNOWFLAKE_TYPES);\nlet customSnowImageSrc: string | null = null;\n\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n// Extend Navigator interface for deviceMemory\ndeclare global {\n interface Navigator {\n deviceMemory?: number;\n }\n}\n\nfunction getPerformanceTier(): PerformanceTier {\n const isLowEnd = navigator.hardwareConcurrency <= 2 ||\n (navigator.deviceMemory !== undefined && navigator.deviceMemory <= 2) ||\n /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);\n if (isLowEnd) return 'low';\n const isHighEnd = navigator.hardwareConcurrency >= 8 &&\n (navigator.deviceMemory === undefined || navigator.deviceMemory >= 8);\n return isHighEnd ? 'high' : 'medium';\n}\n\nfunction createSVGSnowflake(size: number, color: string, flakeType: string): SVGSVGElement {\n const ns = 'http://www.w3.org/2000/svg';\n const svg = document.createElementNS(ns, 'svg');\n svg.setAttribute('width', String(size));\n svg.setAttribute('height', String(size));\n svg.setAttribute('viewBox', `0 0 ${size} ${size}`);\n svg.style.overflow = 'visible';\n\n const path = document.createElementNS(ns, 'path');\n path.setAttribute('d', SNOWFLAKE_TYPES[flakeType](size));\n path.setAttribute('stroke', color);\n path.setAttribute('stroke-width', String(Math.max(1, size * 0.06)));\n path.setAttribute('stroke-linecap', 'round');\n path.setAttribute('stroke-linejoin', 'round');\n path.setAttribute('fill', 'none');\n\n const dot = document.createElementNS(ns, 'circle');\n dot.setAttribute('cx', String(size / 2));\n dot.setAttribute('cy', String(size / 2));\n dot.setAttribute('r', String(size * 0.04));\n dot.setAttribute('fill', color);\n\n svg.appendChild(path);\n svg.appendChild(dot);\n\n return svg;\n}\n\n// ============================================================================\n// Extension Registration\n// ============================================================================\n\napp.registerExtension({\n name: \"Christmas.Theme.SnowEffect\",\n async setup() {\n console.log(\"✨ Initializing Premium Snow Effect with JS animation...\");\n\n try {\n const perfTier = getPerformanceTier();\n const totalFlakes = SNOWFLAKE_CONFIG.FLAKE_COUNTS[perfTier];\n console.log(`❄️ Performance tier: ${perfTier}, using ${totalFlakes} foreground snowflakes (8 designs)`);\n\n const container = document.createElement('div');\n container.id = 'comfy-aether-snow';\n Object.assign(container.style, {\n position: 'fixed',\n top: '0',\n left: '0',\n width: '100%',\n height: '100%',\n overflow: 'hidden'\n });\n container.style.pointerEvents = 'none';\n container.style.zIndex = '50'; // Above canvas (bg is usually -1 or 1), below ComfyUI menus (~100+)\n document.body.appendChild(container);\n\n const style = document.createElement('style');\n style.id = 'snowflake-styles';\n style.textContent = `\n .snowflake {\n position: absolute;\n pointer-events: none;\n user-select: none;\n will-change: transform, filter;\n }\n `;\n document.head.appendChild(style);\n\n let flakes: FlakeEntity[] = [];\n let animationId: number | null = null;\n let lastTime = performance.now();\n let snowAnimTime = 0; // Cumulative animation time that freezes during execution\n\n const getSnowflakeColor = (): string => {\n const colorScheme = getSetting(\"ChristmasTheme.Snowflake.ColorScheme\") as string;\n const christmasColors = getSetting(\"ChristmasTheme.ChristmasEffects.ColorScheme\") as string;\n\n switch (colorScheme) {\n case \"blue\":\n return ['#d4f1f9', '#c8e8f0', '#b8dce8'][Math.floor(Math.random() * 3)];\n case \"rainbow\":\n return ['#ffb3ba', '#bae1ff', '#baffc9', '#ffffba', '#ffdfba'][Math.floor(Math.random() * 5)];\n case \"match\":\n const palette = COLOR_SCHEMES[christmasColors] || COLOR_SCHEMES.traditional;\n return palette[Math.floor(Math.random() * palette.length)];\n case \"newyear\":\n return COLOR_SCHEMES.newyear[Math.floor(Math.random() * 5)];\n default:\n return ['#ffffff', '#f8f9fa', '#f1f3f5'][Math.floor(Math.random() * 3)];\n }\n };\n\n const getGlowFilter = (color: string): string => {\n const glowIntensity = (getSetting(\"ChristmasTheme.Snowflake.Glow\") as number) || 10;\n const glowAmount = Math.min(glowIntensity * 0.4, 8);\n if (glowAmount < 1) return 'none';\n return `drop-shadow(0 0 ${glowAmount}px ${color})`;\n };\n\n const createFlakeEntity = (): FlakeEntity => {\n const size = SNOWFLAKE_CONFIG.MIN_SIZE +\n Math.random() * (SNOWFLAKE_CONFIG.MAX_SIZE - SNOWFLAKE_CONFIG.MIN_SIZE);\n const sizeRatio = size / SNOWFLAKE_CONFIG.MAX_SIZE;\n const color = getSnowflakeColor();\n\n return {\n x: Math.random() * window.innerWidth,\n y: Math.random() * window.innerHeight,\n size: size,\n opacity: (0.3 + Math.random() * 0.2) + sizeRatio * 0.35, // Random base 0.3-0.5 plus size factor\n color: color,\n speed: 12 + Math.random() * 18, // Slightly slower\n drift: (Math.random() - 0.5) * 30,\n driftSpeed: 0.3 + Math.random() * 0.4,\n driftOffset: Math.random() * Math.PI * 2,\n rotation: Math.random() * Math.PI * 2,\n rotationSpeed: (Math.random() - 0.5) * 0.5,\n\n flakeType: (() => {\n const type = getSetting(\"ChristmasTheme.Snowflake.Type\") as string;\n if (type === 'custom') return 'custom';\n if (type === 'mix_custom') return Math.random() > 0.5 ? 'custom' : FLAKE_TYPE_NAMES[Math.floor(Math.random() * FLAKE_TYPE_NAMES.length)];\n if (type && type !== 'random' && FLAKE_TYPE_NAMES.includes(type)) return type;\n return FLAKE_TYPE_NAMES[Math.floor(Math.random() * FLAKE_TYPE_NAMES.length)];\n })(),\n element: null\n };\n };\n\n const updateFlakeGlow = (flake: FlakeEntity): void => {\n if (flake.element) {\n flake.element.style.filter = getGlowFilter(flake.color);\n }\n };\n\n const initFlakes = (): void => {\n container.innerHTML = '';\n flakes = [];\n\n for (let i = 0; i < totalFlakes; i++) {\n const flakeData = createFlakeEntity();\n\n const flake = document.createElement('div');\n flake.className = 'snowflake';\n\n // Handle Custom Image vs SVG\n if (flakeData.flakeType === 'custom') {\n const snowSrc = getSetting(\"ChristmasTheme.Snowflake.CustomImage\") as string;\n if (snowSrc) {\n flake.style.width = String(flakeData.size * 2) + 'px'; // Larger for images\n flake.style.height = String(flakeData.size * 2) + 'px';\n flake.style.backgroundImage = `url(${snowSrc})`;\n flake.style.backgroundSize = 'contain';\n flake.style.backgroundRepeat = 'no-repeat';\n flake.style.backgroundPosition = 'center';\n } else {\n // Fallback if no image\n const svg = createSVGSnowflake(flakeData.size, flakeData.color, 'minimal');\n flake.appendChild(svg);\n }\n } else {\n const svg = createSVGSnowflake(flakeData.size, flakeData.color, flakeData.flakeType);\n flake.appendChild(svg);\n }\n\n flake.style.opacity = String(flakeData.opacity);\n // Only apply glow to non-images or if desired? \n // Images might handle their own glow or look weird with drop-shadow filter on box\n if (flakeData.flakeType !== 'custom') {\n flake.style.filter = getGlowFilter(flakeData.color);\n }\n container.appendChild(flake);\n\n flakeData.element = flake;\n flakes.push(flakeData);\n }\n };\n\n const updateFlakeColor = (flake: FlakeEntity): void => {\n flake.color = getSnowflakeColor();\n const svg = flake.element?.querySelector('svg');\n if (svg) {\n const path = svg.querySelector('path');\n const dot = svg.querySelector('circle');\n if (path) path.setAttribute('stroke', flake.color);\n if (dot) dot.setAttribute('fill', flake.color);\n }\n updateFlakeGlow(flake);\n };\n\n const animate = (currentTime: number): void => {\n // When not visible, just keep the loop running but skip everything\n if (!isPageVisible) {\n animationId = requestAnimationFrame(animate);\n return;\n }\n\n // Check for resume from execution to prevent time jumps\n if (!isExecuting && (currentTime - lastTime) > 1000) {\n lastTime = currentTime;\n }\n\n // When executing, freeze in place (deltaTime = 0) but still render\n const deltaTime = isExecuting ? 0 : (currentTime - lastTime) / 1000;\n\n if (!isExecuting) {\n lastTime = currentTime;\n snowAnimTime += deltaTime; // Only advance animation time when not executing\n }\n\n const height = window.innerHeight;\n const width = window.innerWidth;\n\n for (const flake of flakes) {\n // Only update positions if not executing\n if (!isExecuting) {\n flake.y += flake.speed * deltaTime;\n flake.rotation += flake.rotationSpeed * deltaTime;\n\n if (flake.y > height + 30) {\n flake.y = -30;\n flake.x = Math.random() * width;\n // Re-roll type\n const type = getSetting(\"ChristmasTheme.Snowflake.Type\") as string;\n if (type === 'custom') flake.flakeType = 'custom';\n else if (type === 'mix_custom') flake.flakeType = Math.random() > 0.5 ? 'custom' : FLAKE_TYPE_NAMES[Math.floor(Math.random() * FLAKE_TYPE_NAMES.length)];\n else if (type && type !== 'random' && FLAKE_TYPE_NAMES.includes(type)) flake.flakeType = type;\n else flake.flakeType = FLAKE_TYPE_NAMES[Math.floor(Math.random() * FLAKE_TYPE_NAMES.length)];\n\n // Update visual content if type changed or it's custom (to catch new images)\n if (flake.element) {\n flake.element.innerHTML = '';\n flake.element.style.backgroundImage = '';\n\n if (flake.flakeType === 'custom') {\n const snowSrc = getSetting(\"ChristmasTheme.Snowflake.CustomImage\") as string;\n if (snowSrc) {\n flake.element.style.width = String(flake.size * 2) + 'px';\n flake.element.style.height = String(flake.size * 2) + 'px';\n flake.element.style.backgroundImage = `url(${snowSrc})`;\n flake.element.style.backgroundSize = 'contain';\n flake.element.style.backgroundRepeat = 'no-repeat';\n } else {\n const svg = createSVGSnowflake(flake.size, flake.color, 'minimal');\n flake.element.appendChild(svg);\n }\n } else {\n flake.element.style.width = ''; // Reset\n flake.element.style.height = '';\n const svg = createSVGSnowflake(flake.size, flake.color, flake.flakeType);\n flake.element.appendChild(svg);\n }\n }\n updateFlakeColor(flake);\n }\n }\n\n // Use frozen snowAnimTime for drift so it pauses during execution\n const driftX = Math.sin(snowAnimTime * flake.driftSpeed + flake.driftOffset) * flake.drift;\n if (flake.element) {\n flake.element.style.transform = `translate(${flake.x + driftX}px, ${flake.y}px) rotate(${flake.rotation}rad)`;\n }\n }\n\n animationId = requestAnimationFrame(animate);\n };\n\n const isEnabled = getSetting(\"ChristmasTheme.Snowflake.Enabled\");\n container.style.display = isEnabled ? 'block' : 'none';\n\n if (isEnabled) {\n initFlakes();\n animationId = requestAnimationFrame(animate);\n }\n\n const handleVisibility = (): void => {\n if (document.visibilityState !== 'hidden') {\n lastTime = performance.now();\n }\n };\n document.addEventListener('visibilitychange', handleVisibility);\n\n // Settings change detection - check all settings\n let lastColorScheme = getSetting(\"ChristmasTheme.Snowflake.ColorScheme\");\n let lastGlow = getSetting(\"ChristmasTheme.Snowflake.Glow\");\n let lastEnabled = getSetting(\"ChristmasTheme.Snowflake.Enabled\");\n\n const checkSettings = setInterval(() => {\n const currentEnabled = getSetting(\"ChristmasTheme.Snowflake.Enabled\");\n const currentColorScheme = getSetting(\"ChristmasTheme.Snowflake.ColorScheme\");\n const currentGlow = getSetting(\"ChristmasTheme.Snowflake.Glow\");\n\n // Handle enable/disable\n if (currentEnabled !== lastEnabled) {\n if (currentEnabled === 1 || (currentEnabled as any) === true) {\n container.style.display = 'block';\n if (flakes.length === 0) {\n initFlakes();\n if (!animationId) animationId = requestAnimationFrame(animate);\n }\n } else {\n container.style.display = 'none';\n }\n lastEnabled = currentEnabled;\n }\n\n // Handle color scheme change\n if (currentColorScheme !== lastColorScheme) {\n flakes.forEach(updateFlakeColor);\n lastColorScheme = currentColorScheme;\n }\n\n // Handle glow change\n if (currentGlow !== lastGlow) {\n flakes.forEach(updateFlakeGlow);\n lastGlow = currentGlow;\n }\n\n // Handle disable with cleanup\n if (!currentEnabled && flakes.length > 0) {\n flakes = [];\n container.innerHTML = '';\n }\n }, 500);\n\n return () => {\n clearInterval(checkSettings);\n document.removeEventListener('visibilitychange', handleVisibility);\n if (animationId) cancelAnimationFrame(animationId);\n container.remove();\n style.remove();\n };\n } catch (error) {\n console.error(\"❌ Failed to initialize Snow Effect:\", error);\n }\n }\n});\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/js/background-themes.js.map b/js/background-themes.js.map deleted file mode 100644 index 7e0bf06..0000000 --- a/js/background-themes.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"background-themes.js","sources":["../src/background-themes.ts"],"sourcesContent":["/**\n * Background Themes - Canvas-based background effects for ComfyUI\n * \n * Includes: Stars, shooting stars, snowflakes, fireworks, mouse effects,\n * New Year countdown, and finale celebrations.\n */\n\n// @ts-ignore - ComfyUI external module\nimport { app } from \"../../scripts/app.js\";\nimport { getSetting, updateCache, initSettingsCache, loadSettingFromStorage, BACKGROUND_THEMES, COLOR_SCHEMES } from \"./settings-cache\";\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\ninterface StarEntity {\n x: number;\n y: number;\n size?: number;\n brightness?: number;\n baseAlpha?: number;\n twinkleSpeed?: number;\n twinklePhase?: number;\n layer?: string;\n color?: string;\n // Extended properties\n twinkleOffset?: number;\n twinkleOffset2?: number;\n twinkleSpeedMod?: number;\n baseOpacity?: number;\n hasGlow?: boolean;\n hasSpikes?: boolean;\n}\n\ninterface ShootingStar {\n x: number;\n y: number;\n vx: number;\n vy: number;\n size?: number;\n trail?: Array<{ x: number; y: number; alpha?: number; size?: number }>;\n alpha?: number;\n color?: string;\n // Extended properties for enhanced drawing\n length?: number;\n life?: number;\n decay?: number;\n brightness?: number;\n fragments?: Array<{ x: number; y: number; vx?: number; vy?: number; alpha?: number; size: number; life?: number }>;\n lastFragmentTime?: number;\n fragmentInterval?: number;\n willFlare?: boolean;\n flareIntensity?: number;\n}\n\ninterface NebulaEntity {\n x: number;\n y: number;\n size?: number;\n color?: string;\n alpha?: number;\n rotation?: number;\n radius?: number;\n hue?: number;\n pulseSpeed?: number;\n pulseOffset?: number;\n opacity?: number;\n}\n\ninterface BgSnowflake {\n x: number;\n y: number;\n size: number;\n speed: number;\n wobble?: number;\n wobbleSpeed?: number;\n rotation: number;\n rotationSpeed: number;\n alpha?: number;\n color: string;\n type?: number;\n opacity?: number;\n drift?: number;\n driftSpeed?: number;\n driftOffset?: number;\n flakeType?: string;\n}\n\ninterface FireworkRocket {\n x: number;\n y: number;\n vx: number;\n vy: number;\n palette: string[];\n explosionType: string;\n trail: Array<{ x: number; y: number; alpha?: number; size?: number }>;\n trailTimer: number;\n age: number;\n exploded: boolean;\n size: number;\n}\n\ninterface FireworkParticle {\n x: number;\n y: number;\n vx: number;\n vy: number;\n color: string;\n alpha: number;\n size: number;\n decay: number;\n trail: Array<{ x: number; y: number; alpha?: number }>;\n hasTrail: boolean;\n gravity: number;\n crackle?: boolean;\n crackleTime?: number;\n}\n\ninterface FireworkSpark {\n x: number;\n y: number;\n vx: number;\n vy: number;\n alpha: number;\n size: number;\n decay: number;\n twinkle: number;\n}\n\ninterface MouseParticle {\n x: number;\n y: number;\n vx: number;\n vy: number;\n size: number;\n alpha: number;\n decay: number;\n color: string;\n rotation: number;\n rotationSpeed: number;\n trail: Array<{ x: number; y: number; alpha?: number }> | null;\n age: number;\n effect: string;\n // Effect-specific properties (all optional)\n gravity?: number;\n friction?: number;\n shape?: string;\n glow?: number;\n hasTrail?: boolean;\n trailLength?: number;\n twinkle?: number;\n drift?: number;\n wave?: number;\n flutter?: number;\n sway?: number;\n shimmer?: number;\n spin?: boolean;\n orbit?: boolean;\n spiral?: boolean;\n spiralAngle?: number | null;\n spiralRadius?: number;\n originX?: number;\n originY?: number;\n orbitAngle?: number | null;\n orbitRadius?: number;\n pulseGlow?: boolean;\n orbCenter?: { x: number; y: number };\n orbAngle?: number;\n orbPhase?: number;\n targetX?: number;\n targetY?: number;\n}\n\ninterface FinaleConfetti {\n x: number;\n y: number;\n vx: number;\n vy: number;\n rotation: number;\n rotationSpeed: number;\n alpha: number;\n decay: number;\n size: number;\n color: string;\n screenHeight?: number;\n}\n\ninterface FinaleStar {\n x: number;\n y: number;\n vy: number;\n alpha: number;\n size: number;\n color: string;\n trail: Array<{ x: number; y: number }>;\n screenHeight?: number;\n}\n\n// ============================================================================\n// State Variables\n// ============================================================================\n\n// Track if extension has been set up to prevent double registration\nlet extensionSetupComplete = false;\n\n// Flag to prevent onChange callbacks during initial setup\nlet isInitialSetup = true;\n\n// Page Visibility API - shared across modules\nlet isPageVisible = true;\ndocument.addEventListener('visibilitychange', () => {\n isPageVisible = document.visibilityState === 'visible';\n});\n\n// Workflow execution state - pauses animations during generation\nlet isExecuting = false;\nlet executionEndTime = 0; // Track when execution ended to add cooldown\n\n// Store original method for cleanup\nlet originalDrawBackCanvas: ((...args: unknown[]) => void) | null = null;\n\n// Star entities for the background effect\nlet starEntities: StarEntity[] = [];\nlet shootingStars: ShootingStar[] = [];\nlet nebulaEntities: NebulaEntity[] = [];\nlet starInitialized = false;\n\n// Background snowflake entities (canvas-based, drawn behind nodes)\nlet bgSnowflakeEntities: BgSnowflake[] = [];\n\nlet bgSnowflakesInitialized = false;\nlet lastBgColorScheme: string | null = null;\nlet lastBgSnowflakeColorScheme: string | null = null;\nlet customBgImage: HTMLImageElement | null = null;\nlet customBgImageSrc: string | null = null;\nlet customSnowImage: HTMLImageElement | null = null;\nlet customSnowImageSrc: string | null = null;\n\n\n// Firework entities\nlet fireworkRockets: FireworkRocket[] = [];\nlet fireworkParticles: FireworkParticle[] = [];\nlet fireworkSparks: FireworkSpark[] = []; // Secondary small particles\nlet lastFireworkTime = 0;\nlet animationLoopId: number | null = null;\n\n// Color palettes for different firework types\nconst FIREWORK_PALETTES = [\n ['#ff6b6b', '#ff8787', '#ffa8a8'], // Red gradient\n ['#ffd93d', '#ffe066', '#fff3bf'], // Gold gradient\n ['#6bcb77', '#8ce99a', '#b2f2bb'], // Green gradient\n ['#4d96ff', '#74c0fc', '#a5d8ff'], // Blue gradient\n ['#ff85c1', '#f783ac', '#faa2c1'], // Pink gradient\n ['#a855f7', '#c084fc', '#d8b4fe'], // Purple gradient\n ['#00d4ff', '#22d3ee', '#67e8f9'], // Cyan gradient\n ['#ffffff', '#f8f9fa', '#e9ecef'], // White/silver\n ['#ffd700', '#ffec99', '#fff9db'], // Bright gold\n];\n\n// Explosion types\nconst EXPLOSION_TYPES = ['chrysanthemum', 'willow', 'palm', 'ring', 'crackle', 'peony'];\n\n// Create a new firework rocket with enhanced properties\nfunction createFireworkRocket(width: number, height: number, _isFinale?: boolean): FireworkRocket {\n const palette = FIREWORK_PALETTES[Math.floor(Math.random() * FIREWORK_PALETTES.length)];\n const explosionType = EXPLOSION_TYPES[Math.floor(Math.random() * EXPLOSION_TYPES.length)];\n return {\n x: Math.random() * width * 0.8 + width * 0.1,\n y: height - 30,\n vx: (Math.random() - 0.5) * 3,\n vy: -12 - Math.random() * 6,\n palette: palette,\n explosionType: explosionType,\n trail: [],\n trailTimer: 0,\n age: 0,\n exploded: false,\n size: 2 + Math.random()\n };\n}\n\n// Create professional explosion particles based on type\nfunction createExplosionParticles(x: number, y: number, palette: string[], explosionType: string): FireworkParticle[] {\n const particles: FireworkParticle[] = [];\n const primaryColor = palette[0];\n const secondaryColor = palette[1];\n const tertiaryColor = palette[2];\n\n switch (explosionType) {\n case 'chrysanthemum': {\n // Dense spherical burst with long trails\n const count = 80 + Math.floor(Math.random() * 40);\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.2;\n const speed = 3 + Math.random() * 3;\n const colorChoice = Math.random();\n particles.push({\n x, y,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed,\n color: colorChoice < 0.5 ? primaryColor : (colorChoice < 0.8 ? secondaryColor : tertiaryColor),\n alpha: 1,\n size: 2 + Math.random() * 1.5,\n decay: 0.008 + Math.random() * 0.004,\n trail: [],\n hasTrail: true,\n gravity: 0.03\n });\n }\n break;\n }\n case 'willow': {\n // Drooping trails like a willow tree\n const count = 60 + Math.floor(Math.random() * 30);\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.15;\n const speed = 2 + Math.random() * 2;\n particles.push({\n x, y,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed - 1,\n color: palette[Math.floor(Math.random() * palette.length)],\n alpha: 1,\n size: 1.5 + Math.random(),\n decay: 0.005 + Math.random() * 0.003,\n trail: [],\n hasTrail: true,\n gravity: 0.08 // Heavy gravity for drooping effect\n });\n }\n break;\n }\n case 'palm': {\n // Thick center burst spreading outward\n const count = 50 + Math.floor(Math.random() * 20);\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count;\n const speed = 4 + Math.random() * 2;\n particles.push({\n x, y,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed - 2,\n color: primaryColor,\n alpha: 1,\n size: 3 + Math.random() * 2,\n decay: 0.012 + Math.random() * 0.005,\n trail: [],\n hasTrail: true,\n gravity: 0.04\n });\n }\n break;\n }\n case 'ring': {\n // Expanding ring shape\n const count = 40;\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count;\n const speed = 4;\n particles.push({\n x, y,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed,\n color: palette[i % palette.length],\n alpha: 1,\n size: 2.5,\n decay: 0.015,\n trail: [],\n hasTrail: false,\n gravity: 0.02\n });\n }\n break;\n }\n case 'crackle': {\n // Initial burst then secondary mini explosions\n const count = 30;\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.3;\n const speed = 2 + Math.random() * 2;\n particles.push({\n x, y,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed,\n color: primaryColor,\n alpha: 1,\n size: 2 + Math.random(),\n decay: 0.02,\n trail: [],\n hasTrail: true,\n gravity: 0.05,\n crackle: true,\n crackleTime: 0.3 + Math.random() * 0.3\n });\n }\n break;\n }\n case 'peony':\n default: {\n // Classic spherical burst\n const count = 70 + Math.floor(Math.random() * 30);\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.25;\n const speed = 2.5 + Math.random() * 2.5;\n particles.push({\n x, y,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed,\n color: palette[Math.floor(Math.random() * palette.length)],\n alpha: 1,\n size: 2 + Math.random() * 1.5,\n decay: 0.01 + Math.random() * 0.005,\n trail: [],\n hasTrail: Math.random() > 0.3,\n gravity: 0.04\n });\n }\n }\n }\n\n // Add glitter/sparks for all types\n const sparkCount = 20 + Math.floor(Math.random() * 15);\n for (let i = 0; i < sparkCount; i++) {\n const angle = Math.random() * Math.PI * 2;\n const speed = 1 + Math.random() * 5;\n fireworkSparks.push({\n x, y,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed,\n alpha: 1,\n size: 0.5 + Math.random() * 0.5,\n decay: 0.03 + Math.random() * 0.02,\n twinkle: Math.random() * Math.PI * 2\n });\n }\n\n return particles;\n}\n\n// Function to update all background snowflake colors when settings change\nfunction updateBgSnowflakeColors() {\n for (const flake of bgSnowflakeEntities) {\n flake.color = getBgSnowflakeColor();\n }\n}\n\n// New Year Countdown Timer\nlet countdownElement: HTMLDivElement | null = null;\nlet countdownInterval: ReturnType | null = null;\n\nfunction createCountdownElement() {\n if (countdownElement) return countdownElement;\n\n const now = new Date();\n let targetYear = now.getFullYear();\n // If we're past Jan 1, target next year\n if (now.getMonth() > 0 || (now.getMonth() === 0 && now.getDate() > 1)) {\n targetYear++;\n }\n\n const container = document.createElement('div');\n container.id = 'christmas-theme-countdown';\n container.innerHTML = `\n \n
\n \n New Year ${targetYear}\n \n
\n
\n
00Days
\n
:
\n
00Hrs
\n
:
\n
00Min
\n
:
\n
00Sec
\n
\n `;\n document.body.appendChild(container);\n countdownElement = container;\n return container;\n}\n\n// Finale state\nlet finaleActive = false;\nlet finaleStartTime = 0;\nlet finaleGracePeriod = false; // Keeps rendering particles after finale ends\nconst FINALE_DURATION = 22000; // 22 seconds of fireworks (extended for smooth wind-down)\nlet finaleConfetti: FinaleConfetti[] = [];\nlet finaleRings: unknown[] = [];\nlet finaleStars: FinaleStar[] = [];\n\nfunction triggerFinale() {\n if (finaleActive) return;\n finaleActive = true;\n finaleStartTime = performance.now();\n console.log(\"🎆 FINALE TRIGGERED!\");\n\n // 1. Screen Flash\n createScreenFlash();\n\n // 2. \"2026\" Text Overlay\n createYearText();\n\n // 3. Golden Ring Expansion (multiple waves)\n for (let i = 0; i < 3; i++) {\n setTimeout(() => createGoldenRing(), i * 500);\n }\n\n // 4. Confetti Shower\n createConfettiShower();\n\n // 5. Cascade Fireworks (rapid fire)\n triggerCascadeFireworks();\n}\n\nfunction createScreenFlash() {\n const flash = document.createElement('div');\n flash.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n background: radial-gradient(ellipse at center, rgba(255,255,255,0.9), rgba(255,215,0,0.6));\n pointer-events: none;\n z-index: 9999;\n animation: finaleFlash 0.8s ease-out forwards;\n `;\n\n const style = document.createElement('style');\n style.textContent = `\n @keyframes finaleFlash {\n 0% { opacity: 1; }\n 100% { opacity: 0; }\n }\n `;\n document.head.appendChild(style);\n document.body.appendChild(flash);\n\n setTimeout(() => {\n flash.remove();\n style.remove();\n }, 1000);\n}\n\nfunction createYearText() {\n const now = new Date();\n const year = now.getFullYear() + (now.getMonth() === 0 && now.getDate() === 1 ? 0 : 1);\n\n const text = document.createElement('div');\n text.innerHTML = `\n
${year}
\n
Happy New Year!
\n `;\n text.style.cssText = `\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n color: #ffd700;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n text-align: center;\n pointer-events: none;\n z-index: 9998;\n animation: yearTextAnim 5s ease-out forwards;\n `;\n\n const style = document.createElement('style');\n style.textContent = `\n @keyframes yearTextAnim {\n 0% { opacity: 0; transform: translate(-50%, -50%) scale(0.5); }\n 20% { opacity: 1; transform: translate(-50%, -50%) scale(1.1); }\n 30% { transform: translate(-50%, -50%) scale(1); }\n 80% { opacity: 1; }\n 100% { opacity: 0; transform: translate(-50%, -50%) scale(1.2); }\n }\n `;\n document.head.appendChild(style);\n document.body.appendChild(text);\n\n setTimeout(() => {\n text.remove();\n style.remove();\n }, 5500);\n}\n\nfunction createGoldenRing() {\n const ring = document.createElement('div');\n ring.style.cssText = `\n position: fixed;\n top: 50%;\n left: 50%;\n width: 10px;\n height: 10px;\n border: 4px solid #ffd700;\n border-radius: 50%;\n transform: translate(-50%, -50%);\n pointer-events: none;\n z-index: 9997;\n box-shadow: 0 0 20px #ffd700, 0 0 40px #ff8c00;\n animation: ringExpand 2s ease-out forwards;\n `;\n\n const style = document.createElement('style');\n style.textContent = `\n @keyframes ringExpand {\n 0% { width: 10px; height: 10px; opacity: 1; border-width: 4px; }\n 100% { width: 200vmax; height: 200vmax; opacity: 0; border-width: 2px; }\n }\n `;\n document.head.appendChild(style);\n document.body.appendChild(ring);\n\n setTimeout(() => {\n ring.remove();\n style.remove();\n }, 2500);\n}\n\nfunction createConfettiShower() {\n const colors = ['#ff6b6b', '#ffd93d', '#6bcb77', '#4d96ff', '#9d4edd', '#ff85a1', '#ffd700', '#00ffff'];\n\n // Create confetti container\n const container = document.createElement('div');\n container.id = 'finale-confetti-container';\n container.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n pointer-events: none;\n z-index: 9996;\n overflow: hidden;\n `;\n document.body.appendChild(container);\n\n // Add confetti animation style\n const style = document.createElement('style');\n style.id = 'confetti-style';\n style.textContent = `\n @keyframes confettiFall {\n 0% { transform: translateY(-20px) rotate(0deg); opacity: 1; }\n 85% { opacity: 0.8; }\n 100% { transform: translateY(120vh) rotate(720deg); opacity: 0; }\n }\n .finale-confetti {\n position: absolute;\n animation: confettiFall linear forwards;\n }\n `;\n document.head.appendChild(style);\n\n // Create 150 confetti pieces\n for (let i = 0; i < 150; i++) {\n setTimeout(() => {\n const confetti = document.createElement('div');\n confetti.className = 'finale-confetti';\n const size = 8 + Math.random() * 12;\n const x = Math.random() * 100;\n const duration = 3 + Math.random() * 4;\n const delay = Math.random() * 0.5;\n\n confetti.style.cssText = `\n left: ${x}%;\n top: -20px;\n width: ${size}px;\n height: ${size * 0.4}px;\n background: ${colors[Math.floor(Math.random() * colors.length)]};\n animation-duration: ${duration}s;\n animation-delay: ${delay}s;\n border-radius: 2px;\n `;\n container.appendChild(confetti);\n }, Math.random() * 2000);\n }\n\n // Cleanup after 10 seconds\n setTimeout(() => {\n container.remove();\n style.remove();\n }, 10000);\n}\n\nfunction createStarRain() {\n // Create star rain container\n const container = document.createElement('div');\n container.id = 'finale-star-container';\n container.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n pointer-events: none;\n z-index: 9995;\n overflow: hidden;\n `;\n document.body.appendChild(container);\n\n // Add star animation style\n const style = document.createElement('style');\n style.id = 'star-rain-style';\n style.textContent = `\n @keyframes starFall {\n 0% { transform: translateY(-20px); opacity: 1; }\n 80% { opacity: 1; }\n 100% { transform: translateY(100vh); opacity: 0; }\n }\n .finale-star {\n position: absolute;\n border-radius: 50%;\n animation: starFall linear forwards;\n box-shadow: 0 0 10px currentColor, 0 0 20px currentColor;\n }\n .finale-star::after {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, 0);\n width: 2px;\n height: 40px;\n background: linear-gradient(to bottom, currentColor, transparent);\n border-radius: 2px;\n }\n `;\n document.head.appendChild(style);\n\n // Create 40 falling stars\n for (let i = 0; i < 40; i++) {\n setTimeout(() => {\n const star = document.createElement('div');\n star.className = 'finale-star';\n const size = 4 + Math.random() * 6;\n const x = Math.random() * 100;\n const duration = 1 + Math.random() * 1.5;\n const color = Math.random() > 0.5 ? '#ffd700' : '#ffffff';\n\n star.style.cssText = `\n left: ${x}%;\n top: -40px;\n width: ${size}px;\n height: ${size}px;\n background: ${color};\n color: ${color};\n animation-duration: ${duration}s;\n `;\n container.appendChild(star);\n }, Math.random() * 2000);\n }\n\n // Cleanup after 6 seconds\n setTimeout(() => {\n container.remove();\n style.remove();\n }, 6000);\n}\n\nfunction triggerCascadeFireworks() {\n const canvas = document.getElementById('christmas-background') as HTMLCanvasElement | null;\n if (!canvas) return;\n\n // Phase 1: CLIMAX (0-4s) - Rapid-fire intense bursts\n for (let i = 0; i < 25; i++) {\n setTimeout(() => {\n const x = canvas.width * 0.1 + Math.random() * canvas.width * 0.8;\n fireworkRockets.push(createFireworkRocket(x, canvas.height, true));\n }, i * 160); // Fast pacing\n }\n\n // Phase 2: SUSTAINED (4-10s) - Moderate, steady pacing\n for (let i = 0; i < 15; i++) {\n setTimeout(() => {\n const x = canvas.width * 0.15 + Math.random() * canvas.width * 0.7;\n fireworkRockets.push(createFireworkRocket(x, canvas.height, true));\n }, 4000 + i * 400); // Medium pacing\n }\n\n // Phase 3: WIND-DOWN (10-18s) - Spaced-out bursts that gradually fade\n for (let i = 0; i < 10; i++) {\n setTimeout(() => {\n const x = canvas.width * 0.2 + Math.random() * canvas.width * 0.6;\n fireworkRockets.push(createFireworkRocket(x, canvas.height, true));\n }, 10000 + i * 800); // Slow pacing, longer gaps\n }\n\n // Phase 4: FINAL TRAILING (18-22s) - Very spaced single bursts\n for (let i = 0; i < 4; i++) {\n setTimeout(() => {\n const x = canvas.width * 0.25 + Math.random() * canvas.width * 0.5;\n fireworkRockets.push(createFireworkRocket(x, canvas.height, true));\n }, 18000 + i * 1000); // One per second\n }\n}\n\nfunction updateFinaleParticles(ctx, canvas) {\n // Update confetti\n for (let i = finaleConfetti.length - 1; i >= 0; i--) {\n const c = finaleConfetti[i];\n c.x += c.vx;\n c.y += c.vy;\n c.vy += 0.05; // gravity\n c.vx *= 0.99;\n c.rotation += c.rotationSpeed;\n c.alpha -= c.decay;\n\n const maxHeight = c.screenHeight || window.innerHeight;\n if (c.alpha <= 0 || c.y > maxHeight + 50) {\n finaleConfetti.splice(i, 1);\n }\n }\n\n // Update falling stars\n for (let i = finaleStars.length - 1; i >= 0; i--) {\n const s = finaleStars[i];\n s.trail.push({ x: s.x, y: s.y });\n if (s.trail.length > 15) s.trail.shift();\n\n s.y += s.vy;\n s.alpha -= 0.01;\n\n const maxHeight = s.screenHeight || window.innerHeight;\n if (s.alpha <= 0 || s.y > maxHeight + 50) {\n finaleStars.splice(i, 1);\n }\n }\n}\n\nfunction drawFinaleParticles(ctx) {\n // Draw confetti\n for (const c of finaleConfetti) {\n ctx.save();\n ctx.translate(c.x, c.y);\n ctx.rotate(c.rotation);\n ctx.globalAlpha = c.alpha;\n ctx.fillStyle = c.color;\n ctx.fillRect(-c.size / 2, -c.size / 4, c.size, c.size / 2);\n ctx.restore();\n }\n\n // Draw falling stars with trails\n for (const s of finaleStars) {\n // Trail\n for (let t = 0; t < s.trail.length; t++) {\n const tp = s.trail[t];\n ctx.globalAlpha = (t / s.trail.length) * s.alpha * 0.5;\n ctx.fillStyle = s.color;\n ctx.beginPath();\n ctx.arc(tp.x, tp.y, s.size * 0.5, 0, Math.PI * 2);\n ctx.fill();\n }\n\n // Star\n ctx.globalAlpha = s.alpha;\n ctx.shadowBlur = 15;\n ctx.shadowColor = s.color;\n ctx.fillStyle = s.color;\n ctx.beginPath();\n ctx.arc(s.x, s.y, s.size, 0, Math.PI * 2);\n ctx.fill();\n ctx.shadowBlur = 0;\n }\n\n ctx.globalAlpha = 1;\n}\n\nfunction updateCountdown() {\n const daysEl = document.getElementById('countdown-days');\n const hoursEl = document.getElementById('countdown-hours');\n const minsEl = document.getElementById('countdown-mins');\n const secsEl = document.getElementById('countdown-secs');\n if (!daysEl || !hoursEl || !minsEl || !secsEl) return;\n\n const now = new Date();\n let targetYear = now.getFullYear();\n // If we're past Jan 1, target next year\n if (now.getMonth() > 0 || (now.getMonth() === 0 && now.getDate() > 1)) {\n targetYear++;\n }\n const newYear = new Date(targetYear, 0, 1, 0, 0, 0);\n const diff = newYear.getTime() - now.getTime();\n\n if (diff <= 0) {\n daysEl.textContent = '00';\n hoursEl.textContent = '00';\n minsEl.textContent = '00';\n secsEl.textContent = '00';\n if (countdownElement) {\n countdownElement.classList.add('celebration');\n }\n // Show finale button instead of auto-triggering (easter egg)\n showFinaleButton();\n return;\n }\n\n const days = Math.floor(diff / (1000 * 60 * 60 * 24));\n const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));\n const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));\n const seconds = Math.floor((diff % (1000 * 60)) / 1000);\n\n daysEl.textContent = days.toString().padStart(2, '0');\n hoursEl.textContent = hours.toString().padStart(2, '0');\n minsEl.textContent = minutes.toString().padStart(2, '0');\n secsEl.textContent = seconds.toString().padStart(2, '0');\n\n // Hide finale button if time is not zero AND setting is off\n if (!getSetting(\"ChristmasTheme.Background.ShowFinaleButton\")) {\n hideFinaleButton();\n }\n}\n\nfunction toggleCountdownDisplay(enabled) {\n if (enabled) {\n createCountdownElement();\n countdownElement.style.display = 'block';\n updateCountdown();\n if (!countdownInterval) {\n countdownInterval = setInterval(updateCountdown, 1000);\n }\n // Show finale button if setting enabled\n if (getSetting(\"ChristmasTheme.Background.ShowFinaleButton\")) {\n showFinaleButton();\n }\n } else {\n if (countdownElement) {\n countdownElement.style.display = 'none';\n }\n if (countdownInterval) {\n clearInterval(countdownInterval);\n countdownInterval = null;\n }\n hideFinaleButton();\n }\n}\n\n// Finale button (appears at midnight as easter egg)\nlet finaleButtonElement: HTMLButtonElement | null = null;\nlet finaleButtonShown = false;\n\nfunction showFinaleButton() {\n if (finaleButtonShown || finaleActive) return;\n finaleButtonShown = true;\n\n if (finaleButtonElement) {\n finaleButtonElement.style.display = 'block';\n return;\n }\n\n const btn = document.createElement('button');\n btn.id = 'finale-trigger-btn';\n btn.innerHTML = `Happy New Year!`;\n btn.style.cssText = `\n position: fixed;\n bottom: 61px;\n right: 277px;\n padding: 6px 12px;\n background: rgba(35, 35, 35, 0.95);\n border: 1px solid #ffd700;\n border-radius: 6px;\n color: #ffd700;\n font-weight: 600;\n cursor: pointer;\n z-index: 10000;\n font-size: 11px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n `;\n btn.onmouseenter = () => {\n btn.style.background = 'rgba(50, 50, 50, 0.95)';\n btn.style.boxShadow = '0 0 15px rgba(255, 215, 0, 0.4)';\n };\n btn.onmouseleave = () => {\n btn.style.background = 'rgba(35, 35, 35, 0.95)';\n btn.style.boxShadow = '0 2px 8px rgba(0, 0, 0, 0.3)';\n };\n btn.onclick = () => {\n finaleActive = false; // Reset so it triggers fresh\n triggerFinale();\n };\n document.body.appendChild(btn);\n finaleButtonElement = btn;\n}\n\nfunction hideFinaleButton() {\n finaleButtonShown = false;\n if (finaleButtonElement) {\n finaleButtonElement.style.display = 'none';\n }\n}\n\n\n// ✨ Mouse Effects System (Modular)\nlet mouseParticles: MouseParticle[] = [];\nlet mouseX = 0;\nlet mouseY = 0;\nlet lastMouseX = 0;\nlet lastMouseY = 0;\nlet mouseEffectInitialized = false;\n\n// Effect configurations (DATA) - each effect defines its behavior\nconst MOUSE_EFFECTS = {\n none: null,\n sparkler: {\n colors: ['#ffd700', '#ffec99', '#fff9db', '#ffffff'],\n gravity: 0.08, decay: 0.015, size: [1, 3], spread: 4, friction: 0.98,\n shape: 'circle', glow: 10, hasTrail: true, twinkle: true,\n spawnMode: 'burst' // explodes outward from cursor\n },\n snowflake: {\n colors: ['#ffffff', '#e0f7ff', '#b8e6ff', '#d4f1f9'],\n gravity: 0.015, decay: 0.006, size: [3, 6], spread: 0.5, friction: 0.99,\n shape: 'snowflake', glow: 8, hasTrail: false, drift: true, rotation: true,\n spawnMode: 'drop' // drops gently from cursor position\n },\n confetti: {\n colors: ['#ff6b6b', '#ffd93d', '#6bcb77', '#4d96ff', '#9d4edd', '#ff85a1'],\n gravity: 0.05, decay: 0.008, size: [3, 5], spread: 6, friction: 0.97,\n shape: 'rectangle', glow: 0, spin: true,\n spawnMode: 'pop' // pops upward then falls\n },\n stardust: {\n colors: ['#fffacd', '#fff8dc', '#fffaf0', '#ffffff'],\n gravity: 0.005, decay: 0.01, size: [1, 2], spread: 2, friction: 0.995,\n shape: 'star', glow: 12, twinkle: true,\n spawnMode: 'float' // floats gently in place\n },\n comet: {\n colors: ['#87ceeb', '#add8e6', '#ffffff'],\n gravity: 0.0, decay: 0.025, size: [2, 4], spread: 0.2, friction: 0.92,\n shape: 'circle', glow: 15, hasTrail: true, trailLength: 15,\n spawnMode: 'follow' // tight follow, long trail\n },\n aurora: {\n colors: ['#00ff88', '#00ffcc', '#00ccff', '#8844ff'],\n gravity: -0.02, decay: 0.006, size: [2, 4], spread: 1, friction: 0.99,\n shape: 'circle', glow: 20, wave: true,\n spawnMode: 'rise' // floats upward with wave\n },\n ribbon: {\n colors: ['#ff69b4', '#ff1493', '#db7093', '#ffb6c1'],\n gravity: 0.0, decay: 0.02, size: [2, 3], spread: 0.1, friction: 0.85,\n shape: 'circle', glow: 5, hasTrail: true, trailLength: 10,\n spawnMode: 'follow' // smooth following ribbon\n },\n crystal: {\n colors: ['#e0ffff', '#afeeee', '#b0e0e6', '#ffffff'],\n gravity: 0.03, decay: 0.01, size: [3, 5], spread: 2, friction: 0.96,\n shape: 'diamond', glow: 15, shimmer: true,\n spawnMode: 'scatter' // scatters in random directions\n },\n petals: {\n colors: ['#ffb7c5', '#ffc0cb', '#ff69b4', '#fff0f5'],\n gravity: 0.02, decay: 0.008, size: [4, 6], spread: 3, friction: 0.98,\n shape: 'petal', glow: 5, flutter: true, rotation: true,\n spawnMode: 'flutter' // drifts with flutter motion\n },\n gifts: {\n colors: ['#ff6b6b', '#4ade80', '#ffd700', '#60a5fa'],\n gravity: 0.06, decay: 0.008, size: [5, 8], spread: 3, friction: 0.96,\n shape: 'box', glow: 0, rotation: true,\n spawnMode: 'toss' // tossed upward then tumbles\n },\n candy: {\n colors: ['#ff0000', '#ffffff'],\n gravity: 0.035, decay: 0.01, size: [3, 5], spread: 4, friction: 0.97,\n shape: 'candy', glow: 5, spin: true,\n spawnMode: 'bounce' // bouncy scatter\n },\n orb: {\n colors: ['#9d4edd', '#7b2cbf', '#c77dff', '#e0aaff'],\n gravity: 0.0, decay: 0.015, size: [3, 5], spread: 0.5, friction: 0.95,\n shape: 'circle', glow: 25, orbit: true, pulseGlow: true,\n spawnMode: 'orbit' // orbits around spawn point\n },\n magic: {\n colors: ['#ffd700', '#ff69b4', '#00ffff', '#ff6b6b', '#9d4edd'],\n gravity: 0.0, decay: 0.015, size: [1, 2], spread: 0.5, friction: 0.98,\n shape: 'star', glow: 15, spiral: true, twinkle: true,\n spawnMode: 'spiral' // spirals outward from cursor\n },\n nova: {\n colors: ['#ffffff', '#fffacd', '#ffd700', '#ff8c00'],\n gravity: 0.0, decay: 0.02, size: [2, 4], spread: 0, friction: 0.96,\n shape: 'star', glow: 20, twinkle: true,\n spawnMode: 'burst' // expanding starburst\n },\n bubbles: {\n colors: ['#87ceeb', '#b0e0e6', '#e0ffff', '#ffffff'],\n gravity: -0.03, decay: 0.008, size: [4, 8], spread: 2, friction: 0.99,\n shape: 'bubble', glow: 8, shimmer: true,\n spawnMode: 'rise' // floating upward\n },\n embers: {\n colors: ['#ff4500', '#ff6347', '#ffa500', '#ffd700', '#ffec99'],\n gravity: -0.02, decay: 0.012, size: [1, 3], spread: 2, friction: 0.98,\n shape: 'circle', glow: 12, twinkle: true,\n spawnMode: 'rise' // drifting upward like fire\n },\n lightning: {\n colors: ['#00ffff', '#87ceeb', '#ffffff', '#e0ffff'],\n gravity: 0.0, decay: 0.04, size: [1, 2], spread: 3, friction: 0.9,\n shape: 'circle', glow: 20, hasTrail: true, trailLength: 6,\n spawnMode: 'scatter' // quick electric sparks\n },\n leaves: {\n colors: ['#8b4513', '#d2691e', '#cd853f', '#f4a460', '#daa520'],\n gravity: 0.025, decay: 0.008, size: [4, 7], spread: 3, friction: 0.98,\n shape: 'leaf', glow: 0, flutter: true, rotation: true,\n spawnMode: 'flutter' // drifting down with spin\n },\n wishes: {\n colors: ['#ffffff', '#fffacd', '#ffd700'],\n gravity: 0.0, decay: 0.03, size: [1, 2], spread: 0.5, friction: 0.85,\n shape: 'circle', glow: 15, hasTrail: true, trailLength: 20,\n spawnMode: 'follow' // shooting star streaks\n },\n notes: {\n colors: ['#ff69b4', '#9d4edd', '#4d96ff', '#ffd700'],\n gravity: -0.015, decay: 0.01, size: [6, 10], spread: 3, friction: 0.98,\n shape: 'note', glow: 5, sway: true,\n spawnMode: 'rise' // floating musical notes\n },\n hearts: {\n colors: ['#ff69b4', '#ff1493', '#ff6b6b', '#ff85a1'],\n gravity: -0.01, decay: 0.01, size: [4, 7], spread: 2, friction: 0.98,\n shape: 'heart', glow: 8, sway: true,\n spawnMode: 'rise' // floating hearts\n }\n};\n\n// Shape renderers (DRAWING) - how each shape is drawn\nconst PARTICLE_SHAPES = {\n circle: (ctx, p) => {\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);\n ctx.fill();\n },\n star: (ctx, p) => {\n const spikes = 5, outerR = p.size, innerR = p.size * 0.5;\n ctx.beginPath();\n for (let i = 0; i < spikes * 2; i++) {\n const r = i % 2 === 0 ? outerR : innerR;\n const angle = (i * Math.PI / spikes) - Math.PI / 2 + (p.rotation || 0);\n const x = p.x + Math.cos(angle) * r;\n const y = p.y + Math.sin(angle) * r;\n i === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y);\n }\n ctx.closePath();\n ctx.fill();\n },\n diamond: (ctx, p) => {\n const s = p.size;\n ctx.beginPath();\n ctx.moveTo(p.x, p.y - s);\n ctx.lineTo(p.x + s * 0.6, p.y);\n ctx.lineTo(p.x, p.y + s);\n ctx.lineTo(p.x - s * 0.6, p.y);\n ctx.closePath();\n ctx.fill();\n },\n snowflake: (ctx, p) => {\n const s = p.size, arms = 6;\n ctx.save();\n ctx.translate(p.x, p.y);\n ctx.rotate(p.rotation || 0);\n ctx.lineWidth = 1;\n ctx.strokeStyle = ctx.fillStyle;\n for (let i = 0; i < arms; i++) {\n ctx.rotate(Math.PI / 3);\n ctx.beginPath();\n ctx.moveTo(0, 0);\n ctx.lineTo(0, -s);\n ctx.moveTo(0, -s * 0.5);\n ctx.lineTo(-s * 0.3, -s * 0.7);\n ctx.moveTo(0, -s * 0.5);\n ctx.lineTo(s * 0.3, -s * 0.7);\n ctx.stroke();\n }\n ctx.restore();\n },\n rectangle: (ctx, p) => {\n ctx.save();\n ctx.translate(p.x, p.y);\n ctx.rotate(p.rotation || 0);\n ctx.fillRect(-p.size / 2, -p.size / 4, p.size, p.size / 2);\n ctx.restore();\n },\n petal: (ctx, p) => {\n ctx.save();\n ctx.translate(p.x, p.y);\n ctx.rotate(p.rotation || 0);\n ctx.beginPath();\n ctx.ellipse(0, 0, p.size * 0.4, p.size, 0, 0, Math.PI * 2);\n ctx.fill();\n ctx.restore();\n },\n bell: (ctx, p) => {\n const s = p.size;\n ctx.beginPath();\n ctx.arc(p.x, p.y - s * 0.3, s * 0.7, Math.PI, 0);\n ctx.quadraticCurveTo(p.x + s * 0.8, p.y + s * 0.5, p.x, p.y + s * 0.6);\n ctx.quadraticCurveTo(p.x - s * 0.8, p.y + s * 0.5, p.x - s * 0.7, p.y - s * 0.3);\n ctx.fill();\n ctx.beginPath();\n ctx.arc(p.x, p.y + s * 0.7, s * 0.15, 0, Math.PI * 2);\n ctx.fill();\n },\n box: (ctx, p) => {\n const s = p.size;\n ctx.save();\n ctx.translate(p.x, p.y);\n ctx.rotate(p.rotation || 0);\n ctx.fillRect(-s / 2, -s / 2, s, s);\n // Ribbon\n ctx.fillStyle = '#ffffff';\n ctx.globalAlpha *= 0.8;\n ctx.fillRect(-s / 2, -s * 0.1, s, s * 0.2);\n ctx.fillRect(-s * 0.1, -s / 2, s * 0.2, s);\n ctx.restore();\n },\n candy: (ctx, p) => {\n const s = p.size;\n ctx.save();\n ctx.translate(p.x, p.y);\n ctx.rotate(p.rotation || 0);\n // Striped circle\n ctx.beginPath();\n ctx.arc(0, 0, s, 0, Math.PI * 2);\n ctx.fill();\n ctx.fillStyle = '#ffffff';\n for (let i = 0; i < 3; i++) {\n ctx.fillRect(-s, -s + i * s * 0.7, s * 2, s * 0.3);\n }\n ctx.restore();\n },\n bubble: (ctx, p) => {\n const s = p.size;\n // Outer bubble\n ctx.beginPath();\n ctx.arc(p.x, p.y, s, 0, Math.PI * 2);\n ctx.globalAlpha *= 0.4;\n ctx.fill();\n // Highlight shine\n ctx.globalAlpha *= 2;\n ctx.fillStyle = '#ffffff';\n ctx.beginPath();\n ctx.arc(p.x - s * 0.3, p.y - s * 0.3, s * 0.2, 0, Math.PI * 2);\n ctx.fill();\n },\n leaf: (ctx, p) => {\n const s = p.size;\n ctx.save();\n ctx.translate(p.x, p.y);\n ctx.rotate(p.rotation || 0);\n // Leaf shape\n ctx.beginPath();\n ctx.moveTo(0, -s);\n ctx.quadraticCurveTo(s * 0.8, -s * 0.3, 0, s);\n ctx.quadraticCurveTo(-s * 0.8, -s * 0.3, 0, -s);\n ctx.fill();\n // Vein\n ctx.strokeStyle = 'rgba(0,0,0,0.2)';\n ctx.lineWidth = 0.5;\n ctx.beginPath();\n ctx.moveTo(0, -s * 0.8);\n ctx.lineTo(0, s * 0.8);\n ctx.stroke();\n ctx.restore();\n },\n note: (ctx, p) => {\n const s = p.size;\n ctx.save();\n ctx.translate(p.x, p.y);\n // Note head (filled oval)\n ctx.beginPath();\n ctx.ellipse(0, 0, s * 0.5, s * 0.35, -0.3, 0, Math.PI * 2);\n ctx.fill();\n // Stem\n ctx.fillRect(s * 0.4, -s * 1.2, s * 0.12, s * 1.2);\n // Flag\n ctx.beginPath();\n ctx.moveTo(s * 0.52, -s * 1.2);\n ctx.quadraticCurveTo(s * 1.2, -s * 0.8, s * 0.52, -s * 0.4);\n ctx.fill();\n ctx.restore();\n },\n heart: (ctx, p) => {\n const s = p.size;\n ctx.save();\n ctx.translate(p.x, p.y);\n ctx.beginPath();\n ctx.moveTo(0, s * 0.3);\n // Left curve\n ctx.bezierCurveTo(-s * 0.5, -s * 0.3, -s, s * 0.1, 0, s);\n // Right curve\n ctx.bezierCurveTo(s, s * 0.1, s * 0.5, -s * 0.3, 0, s * 0.3);\n ctx.fill();\n ctx.restore();\n }\n};\n\nfunction initMouseEffect() {\n if (mouseEffectInitialized) return;\n mouseEffectInitialized = true;\n document.addEventListener('mousemove', (e) => {\n mouseX = e.clientX;\n mouseY = e.clientY;\n });\n console.log(\"✨ Mouse effects system initialized\");\n}\n\nfunction createMouseParticle(x, y, vx, vy, effect) {\n const config = MOUSE_EFFECTS[effect];\n if (!config) return null;\n\n const sizeRange = config.size;\n const size = sizeRange[0] + Math.random() * (sizeRange[1] - sizeRange[0]);\n\n // Spawn-mode-specific initial velocities\n let pVx, pVy;\n const spread = config.spread;\n const angle = Math.random() * Math.PI * 2;\n\n switch (config.spawnMode) {\n case 'burst': // Explodes outward in all directions\n pVx = Math.cos(angle) * (2 + Math.random() * 3);\n pVy = Math.sin(angle) * (2 + Math.random() * 3);\n break;\n case 'drop': // Falls gently downward\n pVx = (Math.random() - 0.5) * spread;\n pVy = Math.random() * 0.5;\n break;\n case 'pop': // Pops upward then falls\n pVx = (Math.random() - 0.5) * spread;\n pVy = -2 - Math.random() * 3;\n break;\n case 'float': // Drifts slowly in place\n pVx = (Math.random() - 0.5) * 0.5;\n pVy = (Math.random() - 0.5) * 0.5;\n break;\n case 'follow': // Tight follow - inherits cursor velocity\n pVx = vx * 0.3 + (Math.random() - 0.5) * spread;\n pVy = vy * 0.3 + (Math.random() - 0.5) * spread;\n break;\n case 'rise': // Floats upward\n pVx = (Math.random() - 0.5) * spread;\n pVy = -0.5 - Math.random();\n break;\n case 'scatter': // Random directions\n pVx = (Math.random() - 0.5) * 4;\n pVy = (Math.random() - 0.5) * 4;\n break;\n case 'flutter': // Gentle with horizontal drift\n pVx = (Math.random() - 0.5) * 2;\n pVy = Math.random() * 0.5;\n break;\n case 'toss': // Thrown upward with arc\n pVx = (Math.random() - 0.5) * spread + vx * 0.2;\n pVy = -1.5 - Math.random() * 2;\n break;\n case 'bounce': // Bouncy with some upward\n pVx = (Math.random() - 0.5) * spread;\n pVy = -1 - Math.random();\n break;\n case 'orbit': // Circular motion around spawn\n pVx = Math.cos(angle) * 2;\n pVy = Math.sin(angle) * 2;\n break;\n case 'spiral': // Spiraling outward\n pVx = Math.cos(angle) * 1.5;\n pVy = Math.sin(angle) * 1.5;\n break;\n default:\n pVx = vx + (Math.random() - 0.5) * spread;\n pVy = vy + (Math.random() - 0.5) * spread;\n }\n\n return {\n x, y,\n vx: pVx,\n vy: pVy,\n alpha: 1,\n size: size,\n color: config.colors[Math.floor(Math.random() * config.colors.length)],\n gravity: config.gravity + (Math.random() - 0.5) * 0.01,\n decay: config.decay + Math.random() * 0.003,\n friction: config.friction || 0.98,\n shape: config.shape,\n glow: config.glow,\n twinkle: config.twinkle ? Math.random() * Math.PI * 2 : 0,\n rotation: config.rotation ? Math.random() * Math.PI * 2 : 0,\n rotationSpeed: config.spin ? (Math.random() - 0.5) * 0.3 : (config.rotation ? 0.02 : 0),\n trail: config.hasTrail ? [] : null,\n trailLength: config.trailLength || 5,\n wave: config.wave ? Math.random() * Math.PI * 2 : 0,\n orbitAngle: config.orbit ? angle : null,\n orbitRadius: config.orbit ? 20 + Math.random() * 30 : 0,\n originX: x,\n originY: y,\n spiralAngle: config.spiral ? angle : null,\n spiralRadius: config.spiral ? 5 : 0,\n drift: config.drift ? (Math.random() - 0.5) * 1.5 : 0,\n flutter: config.flutter ? Math.random() * Math.PI * 2 : 0,\n sway: config.sway ? Math.random() * Math.PI * 2 : 0,\n shimmer: config.shimmer ? Math.random() * Math.PI * 2 : 0,\n pulseGlow: config.pulseGlow || false,\n age: 0,\n effect: effect\n };\n}\n\nfunction updateMouseParticles(deltaTime) {\n const effectType = getSetting(\"ChristmasTheme.Background.MouseEffect\");\n\n if (!effectType || effectType === \"none\") {\n mouseParticles = [];\n return;\n }\n\n if (!mouseEffectInitialized) {\n initMouseEffect();\n }\n\n const config = MOUSE_EFFECTS[effectType];\n if (!config) return;\n\n // Calculate mouse velocity\n const dx = mouseX - lastMouseX;\n const dy = mouseY - lastMouseY;\n const speed = Math.sqrt(dx * dx + dy * dy);\n\n // Spawn particles when mouse moves\n if (speed > 2) {\n const particleCount = Math.min(Math.floor(speed / 3), 5);\n for (let i = 0; i < particleCount; i++) {\n const t = i / particleCount;\n const px = lastMouseX + dx * t;\n const py = lastMouseY + dy * t;\n const particle = createMouseParticle(px, py, dx * 0.1, dy * 0.1, effectType);\n if (particle) mouseParticles.push(particle);\n }\n }\n\n lastMouseX = mouseX;\n lastMouseY = mouseY;\n\n // Update particles\n for (let i = mouseParticles.length - 1; i >= 0; i--) {\n const p = mouseParticles[i];\n\n // Store trail\n if (p.trail && p.trail.length < p.trailLength) {\n p.trail.push({ x: p.x, y: p.y, alpha: p.alpha });\n }\n\n // Physics\n p.vy += p.gravity;\n p.x += p.vx + (p.drift || 0) * Math.sin(p.flutter || 0);\n p.y += p.vy;\n p.vx *= p.friction;\n p.vy *= p.friction;\n p.alpha -= p.decay;\n\n // Effect-specific updates\n if (p.twinkle) p.twinkle += 0.2;\n if (p.rotationSpeed) p.rotation += p.rotationSpeed;\n if (p.wave) { p.wave += 0.1; p.x += Math.sin(p.wave) * 2; }\n if (p.flutter) p.flutter += 0.15;\n if (p.sway) { p.sway += 0.1; p.x += Math.sin(p.sway) * 1.5; }\n if (p.shimmer) p.shimmer += 0.3;\n\n // Spiral motion - expands outward while spinning\n if (p.spiralAngle !== null) {\n p.spiralAngle += 0.15;\n p.spiralRadius += 0.5;\n p.x = p.originX + Math.cos(p.spiralAngle) * p.spiralRadius;\n p.y = p.originY + Math.sin(p.spiralAngle) * p.spiralRadius;\n }\n\n // Orbit motion - circles around origin\n if (p.orbitAngle !== null) {\n p.orbitAngle += 0.08;\n p.x = p.originX + Math.cos(p.orbitAngle) * p.orbitRadius;\n p.y = p.originY + Math.sin(p.orbitAngle) * p.orbitRadius;\n }\n\n if (p.alpha <= 0) {\n mouseParticles.splice(i, 1);\n }\n }\n\n // Performance limit\n if (mouseParticles.length > 200) {\n mouseParticles.splice(0, mouseParticles.length - 200);\n }\n}\n\nfunction drawMouseParticles(ctx) {\n const effectType = getSetting(\"ChristmasTheme.Background.MouseEffect\");\n if (!effectType || effectType === \"none\" || mouseParticles.length === 0) return;\n\n ctx.save();\n\n for (const p of mouseParticles) {\n // Draw trail\n if (p.trail && p.trail.length > 0) {\n for (let t = 0; t < p.trail.length; t++) {\n const tp = p.trail[t];\n ctx.globalAlpha = (t / p.trail.length) * p.alpha * 0.4;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(tp.x, tp.y, p.size * 0.5, 0, Math.PI * 2);\n ctx.fill();\n }\n }\n\n // Calculate alpha with effects\n let finalAlpha = p.alpha;\n if (p.twinkle) finalAlpha *= (0.7 + Math.sin(p.twinkle) * 0.3);\n if (p.shimmer) finalAlpha *= (0.8 + Math.sin(p.shimmer) * 0.2);\n\n // Glow\n ctx.shadowBlur = p.pulseGlow ? p.glow * (0.7 + Math.sin(p.twinkle || 0) * 0.3) : p.glow;\n ctx.shadowColor = p.color;\n ctx.globalAlpha = finalAlpha;\n ctx.fillStyle = p.color;\n\n // Draw shape\n const shapeRenderer = PARTICLE_SHAPES[p.shape] || PARTICLE_SHAPES.circle;\n shapeRenderer(ctx, p);\n }\n\n ctx.shadowBlur = 0;\n ctx.restore();\n}\n\n// Gradient caching\nlet cachedGradient = null;\nlet cachedTheme = null;\nlet cachedWidth = 0;\nlet cachedHeight = 0;\n\n// Performance tracking\nlet frameCount = 0;\nlet lastFpsCheck = performance.now();\nlet currentFps = 60;\nlet lowPerfMode = false;\n\n// Animation timing\nlet lastAnimationTime = 0;\nlet animationTime = 0; // Cumulative time that freezes during execution\nlet lastShootingStarTime = 0;\n\n/**\n * Get a star color based on temperature (blue hot -> yellow cool)\n */\nfunction getStarColor() {\n const roll = Math.random();\n if (roll < 0.15) return '#aaccff'; // Blue-white (hot)\n if (roll < 0.50) return '#ffffff'; // White (common)\n if (roll < 0.75) return '#fffef0'; // Warm white\n if (roll < 0.90) return '#fff4e0'; // Yellow-white (sun-like)\n return '#ffe4c0'; // Orange-ish (cooler)\n}\n\n/**\n * Initialize star entities for background with depth layers\n */\nfunction initStars(width, height) {\n const area = width * height;\n const density = 0.0003; // slightly reduced density\n const count = Math.min(Math.floor(area * density), 800); // Cap at 800 stars\n\n starEntities = [];\n for (let i = 0; i < count; i++) {\n // Create 3 layers: distant (small, dim), normal, bright (rare, glow)\n const layerRoll = Math.random();\n let layer, size, baseOpacity, twinkleSpeed, hasGlow, hasSpikes;\n\n if (layerRoll < 0.6) {\n // Distant stars (60%) - tiny, dim, very slow twinkle\n layer = 'distant';\n size = 0.3 + Math.random() * 0.5;\n baseOpacity = 0.2 + Math.random() * 0.3;\n twinkleSpeed = 0.08 + Math.random() * 0.15; // Slower for calm feel\n hasGlow = false;\n hasSpikes = false;\n } else if (layerRoll < 0.92) {\n // Normal stars (32%) - medium, gentle twinkle\n layer = 'normal';\n size = 0.5 + Math.random() * 0.8;\n baseOpacity = 0.4 + Math.random() * 0.4;\n twinkleSpeed = 0.15 + Math.random() * 0.3; // Slower\n hasGlow = false;\n hasSpikes = false;\n } else {\n // Bright stars (8%) - larger, with glow and possible spikes\n layer = 'bright';\n size = 0.8 + Math.random() * 0.7;\n baseOpacity = 0.7 + Math.random() * 0.3;\n twinkleSpeed = 0.2 + Math.random() * 0.4; // Slower\n hasGlow = true;\n hasSpikes = Math.random() < 0.4; // 40% of bright stars get spikes\n }\n\n starEntities.push({\n x: Math.random() * width,\n y: Math.random() * height,\n size,\n // Use much larger offset range + secondary offset to prevent sync\n twinkleOffset: Math.random() * Math.PI * 20, // Larger range \n twinkleOffset2: Math.random() * Math.PI * 15, // Secondary offset\n twinkleSpeed,\n // Add slight speed variation per star\n twinkleSpeedMod: 0.85 + Math.random() * 0.3,\n baseOpacity,\n layer,\n hasGlow,\n hasSpikes,\n color: getStarColor()\n });\n }\n\n // Create nebula clouds (soft colored areas)\n nebulaEntities = [];\n const nebulaCount = Math.min(Math.floor(count * 0.01), 5); // Just a few nebulae\n for (let i = 0; i < nebulaCount; i++) {\n nebulaEntities.push({\n x: Math.random() * width,\n y: Math.random() * height * 0.6, // More in upper area\n radius: 100 + Math.random() * 150, // Larger but more diffuse\n hue: Math.random() * 60 - 30,\n opacity: 0.015 + Math.random() * 0.015, // Much more subtle\n pulseSpeed: 0.005 + Math.random() * 0.01, // Very slow\n pulseOffset: Math.random() * Math.PI * 10 // Large offset to prevent sync\n });\n }\n\n starInitialized = true;\n console.log(`⭐ Created ${starEntities.length} stars, ${nebulaEntities.length} nebulae`);\n}\n\n/**\n * Create a shooting star with realistic properties\n */\nfunction createShootingStar(width, height) {\n const angle = Math.PI * 0.2 + Math.random() * Math.PI * 0.3; // 35-75 degree angle\n const speed = 400 + Math.random() * 500;\n const isLong = Math.random() < 0.3; // 30% are longer, more dramatic\n\n return {\n x: Math.random() * width * 0.8, // Start more to the left\n y: Math.random() * height * 0.3, // Start in upper portion\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed,\n length: isLong ? 60 + Math.random() * 80 : 25 + Math.random() * 40,\n life: 1.0,\n decay: isLong ? 0.4 + Math.random() * 0.3 : 0.7 + Math.random() * 0.6,\n brightness: 0.8 + Math.random() * 0.2,\n // Trail fragments for realism\n fragments: [],\n lastFragmentTime: 0,\n fragmentInterval: 30 + Math.random() * 20,\n // Terminal flare (brightens before dying)\n willFlare: Math.random() < 0.4,\n flareIntensity: 1.5 + Math.random() * 1.0\n };\n}\n\n/**\n * Get or create cached gradient\n */\nfunction getGradient(ctx, height) {\n const colorTheme = getSetting(\"ChristmasTheme.Background.ColorTheme\") || \"classic\";\n\n if (cachedGradient && cachedTheme === colorTheme && cachedHeight === height) {\n return cachedGradient;\n }\n\n const theme = BACKGROUND_THEMES[colorTheme] || BACKGROUND_THEMES.classic;\n if (!theme) {\n console.warn(\"No theme found for\", colorTheme);\n return null;\n }\n\n const gradient = ctx.createLinearGradient(0, 0, 0, height);\n gradient.addColorStop(0, theme.top || '#05004c');\n gradient.addColorStop(0.5, theme.bottom || '#110E19');\n gradient.addColorStop(1, theme.bottom || '#110E19');\n\n cachedGradient = gradient;\n cachedTheme = colorTheme;\n cachedHeight = height;\n\n return gradient;\n}\n\n/**\n * Get a color for background snowflakes based on current settings\n */\nfunction getBgSnowflakeColor() {\n const colorScheme = getSetting(\"ChristmasTheme.Snowflake.ColorScheme\") as string;\n const christmasColors = getSetting(\"ChristmasTheme.ChristmasEffects.ColorScheme\") as string;\n\n switch (colorScheme) {\n case \"blue\":\n const blueVariants = ['#d4f1f9', '#c8e8f0', '#b8dce8'];\n return blueVariants[Math.floor(Math.random() * blueVariants.length)];\n case \"rainbow\":\n const rainbowPalette = ['#ffb3ba', '#bae1ff', '#baffc9', '#ffffba', '#ffdfba'];\n return rainbowPalette[Math.floor(Math.random() * rainbowPalette.length)];\n case \"match\":\n const selectedPalette = COLOR_SCHEMES[christmasColors] || COLOR_SCHEMES.traditional;\n return selectedPalette[Math.floor(Math.random() * selectedPalette.length)];\n case \"newyear\":\n return COLOR_SCHEMES.newyear[Math.floor(Math.random() * 5)];\n default:\n const whiteVariants = ['#ffffff', '#f8f9fa', '#f1f3f5'];\n return whiteVariants[Math.floor(Math.random() * whiteVariants.length)];\n }\n}\n\n/**\n * Initialize background snowflakes for depth effect (drawn on canvas behind nodes)\n */\nfunction initBgSnowflakes(width, height) {\n bgSnowflakeEntities = [];\n const count = 45; // Match approximate foreground count\n\n for (let i = 0; i < count; i++) {\n // Mix of sizes - some small (distant), some larger (closer but still behind)\n const sizeRoll = Math.random();\n let size, opacity;\n\n if (sizeRoll < 0.5) {\n // Smaller, more distant flakes (50%)\n size = 2 + Math.random() * 3;\n opacity = 0.25 + Math.random() * 0.2;\n } else if (sizeRoll < 0.85) {\n // Medium flakes (35%)\n size = 4 + Math.random() * 3;\n opacity = 0.35 + Math.random() * 0.25;\n } else {\n // Larger flakes, still behind nodes (15%)\n size = 6 + Math.random() * 3;\n opacity = 0.4 + Math.random() * 0.2;\n }\n\n bgSnowflakeEntities.push({\n x: Math.random() * width,\n y: Math.random() * height, // Distribute across full height initially\n size: size,\n opacity: opacity,\n color: getBgSnowflakeColor(), // Match color scheme\n speed: 8 + Math.random() * 10, // Pixels per second (slower)\n drift: (Math.random() - 0.5) * 25, // Horizontal drift amplitude\n driftSpeed: 0.1 + Math.random() * 0.15, // Drift oscillation speed\n driftOffset: Math.random() * Math.PI * 2, // Phase offset\n rotation: Math.random() * Math.PI * 2, // Initial rotation\n rotationSpeed: (Math.random() - 0.5) * 0.3, // Slow rotation\n flakeType: ['branched', 'minimal', 'stellar', 'emoji1', 'emoji2', 'emoji3', 'dendrite', 'ornate'][Math.floor(Math.random() * 8)] // Random type\n });\n }\n bgSnowflakesInitialized = true;\n console.log(`❄️ Created ${count} background canvas snowflakes`);\n}\n\n/**\n * Draw a 6-pointed snowflake shape at the given position\n */\nfunction drawSnowflake(ctx, x, y, size, rotation, glowAmount = 0, color = null) {\n ctx.save();\n ctx.translate(x, y);\n ctx.rotate(rotation);\n\n // Apply glow inside save/restore\n if (glowAmount > 0 && color) {\n ctx.shadowBlur = glowAmount;\n ctx.shadowColor = color;\n }\n\n // Draw 6 spokes\n for (let i = 0; i < 6; i++) {\n ctx.rotate(Math.PI / 3);\n\n // Main spoke\n ctx.beginPath();\n ctx.moveTo(0, 0);\n ctx.lineTo(0, -size);\n ctx.stroke();\n\n // Small branches on each spoke (if size is large enough)\n if (size > 4) {\n const branchLen = size * 0.35;\n const branchPos = size * 0.55;\n\n ctx.beginPath();\n ctx.moveTo(0, -branchPos);\n ctx.lineTo(-branchLen * 0.5, -branchPos - branchLen * 0.5);\n ctx.moveTo(0, -branchPos);\n ctx.lineTo(branchLen * 0.5, -branchPos - branchLen * 0.5);\n ctx.stroke();\n }\n }\n\n // Center dot\n ctx.beginPath();\n ctx.arc(0, 0, size * 0.15, 0, Math.PI * 2);\n ctx.fill();\n\n ctx.restore();\n}\n\n/**\n * Draw a minimal alternate snowflake - simple arms with single branch pair\n */\nfunction drawCrystalSnowflake(ctx, x, y, size, rotation) {\n ctx.save();\n ctx.translate(x, y);\n ctx.rotate(rotation);\n\n // Draw 6 main arms with single branch pair each\n for (let i = 0; i < 6; i++) {\n ctx.save();\n ctx.rotate((Math.PI / 3) * i);\n\n // Main arm\n ctx.beginPath();\n ctx.moveTo(0, 0);\n ctx.lineTo(0, -size);\n ctx.stroke();\n\n // Single pair of branches at 55% height\n if (size > 3) {\n const branchY = -size * 0.55;\n const branchLen = size * 0.35;\n const branchAngle = Math.PI / 5; // 36 degrees\n\n // Left branch\n ctx.beginPath();\n ctx.moveTo(0, branchY);\n ctx.lineTo(-Math.sin(branchAngle) * branchLen, branchY - Math.cos(branchAngle) * branchLen);\n ctx.stroke();\n\n // Right branch\n ctx.beginPath();\n ctx.moveTo(0, branchY);\n ctx.lineTo(Math.sin(branchAngle) * branchLen, branchY - Math.cos(branchAngle) * branchLen);\n ctx.stroke();\n }\n\n ctx.restore();\n }\n\n // Small center dot\n ctx.beginPath();\n ctx.arc(0, 0, size * 0.1, 0, Math.PI * 2);\n ctx.fill();\n\n ctx.restore();\n}\n\n/**\n * Draw a stellar dendrite snowflake - more complex with double branch layers\n */\nfunction drawStellarSnowflake(ctx, x, y, size, rotation) {\n ctx.save();\n ctx.translate(x, y);\n ctx.rotate(rotation);\n\n // Draw 6 main arms with double branch pairs\n for (let i = 0; i < 6; i++) {\n ctx.save();\n ctx.rotate((Math.PI / 3) * i);\n\n // Main arm\n ctx.beginPath();\n ctx.moveTo(0, 0);\n ctx.lineTo(0, -size);\n ctx.stroke();\n\n // Two pairs of branches at different heights\n const positions = [0.4, 0.7];\n for (const pos of positions) {\n const branchY = -size * pos;\n const branchLen = size * (0.45 - pos * 0.3);\n const branchAngle = Math.PI / 4;\n\n // Left branch\n ctx.beginPath();\n ctx.moveTo(0, branchY);\n ctx.lineTo(-Math.sin(branchAngle) * branchLen, branchY - Math.cos(branchAngle) * branchLen);\n ctx.stroke();\n\n // Right branch \n ctx.beginPath();\n ctx.moveTo(0, branchY);\n ctx.lineTo(Math.sin(branchAngle) * branchLen, branchY - Math.cos(branchAngle) * branchLen);\n ctx.stroke();\n }\n\n // Small tip accent\n if (size > 4) {\n ctx.beginPath();\n ctx.arc(0, -size, size * 0.08, 0, Math.PI * 2);\n ctx.fill();\n }\n\n ctx.restore();\n }\n\n // Center dot\n ctx.beginPath();\n ctx.arc(0, 0, size * 0.12, 0, Math.PI * 2);\n ctx.fill();\n\n ctx.restore();\n}\n\n/**\n * Draw emoji-style snowflake ❄ (U+2744) - Classic with serif tips and symmetric side branches\n */\nfunction drawEmoji2744(ctx, x, y, size, rotation) {\n ctx.save();\n ctx.translate(x, y);\n ctx.rotate(rotation);\n\n for (let i = 0; i < 6; i++) {\n ctx.save();\n ctx.rotate((Math.PI / 3) * i);\n\n // Main arm with slight thickening at base\n ctx.beginPath();\n ctx.moveTo(0, -size * 0.1);\n ctx.lineTo(0, -size);\n ctx.stroke();\n\n // Serif/arrow tip at end of arm (like the emoji)\n const tipSize = size * 0.15;\n ctx.beginPath();\n ctx.moveTo(-tipSize, -size + tipSize * 0.7);\n ctx.lineTo(0, -size);\n ctx.lineTo(tipSize, -size + tipSize * 0.7);\n ctx.stroke();\n\n // Side branches - single pair at 60% height, angled outward\n const branchY = -size * 0.6;\n const branchLen = size * 0.3;\n const angle = Math.PI / 4; // 45 degrees\n\n ctx.beginPath();\n ctx.moveTo(0, branchY);\n ctx.lineTo(-Math.sin(angle) * branchLen, branchY - Math.cos(angle) * branchLen);\n ctx.stroke();\n\n ctx.beginPath();\n ctx.moveTo(0, branchY);\n ctx.lineTo(Math.sin(angle) * branchLen, branchY - Math.cos(angle) * branchLen);\n ctx.stroke();\n\n ctx.restore();\n }\n\n // Center dot\n ctx.beginPath();\n ctx.arc(0, 0, size * 0.08, 0, Math.PI * 2);\n ctx.fill();\n\n ctx.restore();\n}\n\n/**\n * Draw emoji-style snowflake ❅ (U+2745) - Simple with pronounced center circle\n */\nfunction drawEmoji2745(ctx, x, y, size, rotation) {\n ctx.save();\n ctx.translate(x, y);\n ctx.rotate(rotation);\n\n // Pronounced center circle (like the emoji)\n ctx.beginPath();\n ctx.arc(0, 0, size * 0.18, 0, Math.PI * 2);\n ctx.stroke();\n\n // 6 straight arms extending from center circle\n for (let i = 0; i < 6; i++) {\n const angle = (Math.PI / 3) * i - Math.PI / 2;\n const startR = size * 0.18;\n const endR = size;\n\n ctx.beginPath();\n ctx.moveTo(Math.cos(angle) * startR, Math.sin(angle) * startR);\n ctx.lineTo(Math.cos(angle) * endR, Math.sin(angle) * endR);\n ctx.stroke();\n\n // Small perpendicular cross at 65% length\n const crossPos = size * 0.65;\n const crossLen = size * 0.12;\n const px = Math.cos(angle) * crossPos;\n const py = Math.sin(angle) * crossPos;\n const perpAngle = angle + Math.PI / 2;\n\n ctx.beginPath();\n ctx.moveTo(px - Math.cos(perpAngle) * crossLen, py - Math.sin(perpAngle) * crossLen);\n ctx.lineTo(px + Math.cos(perpAngle) * crossLen, py + Math.sin(perpAngle) * crossLen);\n ctx.stroke();\n\n // Small dot at tip\n ctx.beginPath();\n ctx.arc(Math.cos(angle) * endR, Math.sin(angle) * endR, size * 0.04, 0, Math.PI * 2);\n ctx.fill();\n }\n\n ctx.restore();\n}\n\n/**\n * Draw emoji-style snowflake ❆ (U+2746) - Heavy/bold with arrow-style arms\n */\nfunction drawEmoji2746(ctx, x, y, size, rotation) {\n ctx.save();\n ctx.translate(x, y);\n ctx.rotate(rotation);\n\n // Use slightly thicker lines for bold look\n const origWidth = ctx.lineWidth;\n ctx.lineWidth = origWidth * 1.3;\n\n for (let i = 0; i < 6; i++) {\n ctx.save();\n ctx.rotate((Math.PI / 3) * i);\n\n // Main arm\n ctx.beginPath();\n ctx.moveTo(0, -size * 0.12);\n ctx.lineTo(0, -size);\n ctx.stroke();\n\n // Bold arrow/chevron shape pointing outward (the distinctive feature of ❆)\n const chevY = -size * 0.5;\n const chevLen = size * 0.28;\n const chevAngle = Math.PI / 5; // ~36 degrees\n\n // Draw as connected chevron\n ctx.beginPath();\n ctx.moveTo(-Math.sin(chevAngle) * chevLen, chevY + Math.cos(chevAngle) * chevLen * 0.5);\n ctx.lineTo(0, chevY);\n ctx.lineTo(Math.sin(chevAngle) * chevLen, chevY + Math.cos(chevAngle) * chevLen * 0.5);\n ctx.stroke();\n\n // Small arrow tip at arm end\n const tipY = -size;\n const tipLen = size * 0.12;\n ctx.beginPath();\n ctx.moveTo(-tipLen * 0.6, tipY + tipLen);\n ctx.lineTo(0, tipY);\n ctx.lineTo(tipLen * 0.6, tipY + tipLen);\n ctx.stroke();\n\n ctx.restore();\n }\n\n ctx.lineWidth = origWidth;\n\n // Bold center dot\n ctx.beginPath();\n ctx.arc(0, 0, size * 0.1, 0, Math.PI * 2);\n ctx.fill();\n\n ctx.restore();\n}\n\n/**\n * Draw a dendrite-style snowflake - fernlike with multiple branch levels\n */\nfunction drawDendriteSnowflake(ctx, x, y, size, rotation) {\n ctx.save();\n ctx.translate(x, y);\n ctx.rotate(rotation);\n\n for (let i = 0; i < 6; i++) {\n ctx.save();\n ctx.rotate((Math.PI / 3) * i);\n\n // Main arm\n ctx.beginPath();\n ctx.moveTo(0, 0);\n ctx.lineTo(0, -size);\n ctx.stroke();\n\n // Three branch pairs at different heights\n const positions = [0.4, 0.6, 0.8];\n positions.forEach((pos, idx) => {\n const branchY = -size * pos;\n const branchLen = size * (0.3 - idx * 0.06);\n const branchAngle = Math.PI / 4;\n\n ctx.beginPath();\n ctx.moveTo(0, branchY);\n ctx.lineTo(-Math.sin(branchAngle) * branchLen, branchY - Math.cos(branchAngle) * branchLen);\n ctx.stroke();\n\n ctx.beginPath();\n ctx.moveTo(0, branchY);\n ctx.lineTo(Math.sin(branchAngle) * branchLen, branchY - Math.cos(branchAngle) * branchLen);\n ctx.stroke();\n });\n\n ctx.restore();\n }\n\n // Center dot\n ctx.beginPath();\n ctx.arc(0, 0, size * 0.08, 0, Math.PI * 2);\n ctx.fill();\n\n ctx.restore();\n}\n\n/**\n * Draw an ornate-style snowflake - decorative with diamond tips\n */\nfunction drawOrnateSnowflake(ctx, x, y, size, rotation) {\n ctx.save();\n ctx.translate(x, y);\n ctx.rotate(rotation);\n\n for (let i = 0; i < 6; i++) {\n ctx.save();\n ctx.rotate((Math.PI / 3) * i);\n\n // Main arm\n ctx.beginPath();\n ctx.moveTo(0, 0);\n ctx.lineTo(0, -size * 0.9);\n ctx.stroke();\n\n // Diamond tip\n const tipY = -size * 0.9;\n const dSize = size * 0.1;\n ctx.beginPath();\n ctx.moveTo(0, tipY - dSize);\n ctx.lineTo(dSize * 0.6, tipY);\n ctx.lineTo(0, tipY + dSize);\n ctx.lineTo(-dSize * 0.6, tipY);\n ctx.closePath();\n ctx.fill();\n\n // Branches at 50%\n const branchY = -size * 0.5;\n const branchLen = size * 0.3;\n const branchAngle = Math.PI / 3;\n\n ctx.beginPath();\n ctx.moveTo(0, branchY);\n ctx.lineTo(-Math.sin(branchAngle) * branchLen, branchY - Math.cos(branchAngle) * branchLen);\n ctx.stroke();\n\n ctx.beginPath();\n ctx.moveTo(0, branchY);\n ctx.lineTo(Math.sin(branchAngle) * branchLen, branchY - Math.cos(branchAngle) * branchLen);\n ctx.stroke();\n\n ctx.restore();\n }\n\n // Center dot\n ctx.beginPath();\n ctx.arc(0, 0, size * 0.1, 0, Math.PI * 2);\n ctx.fill();\n\n ctx.restore();\n}\n\n/**\n * Draw the enhanced background onto the canvas context\n */\nfunction drawEnhancedBackground(ctx, width, height) {\n if (!isPageVisible) return;\n if (!getSetting(\"ChristmasTheme.Background.Enabled\")) return;\n\n const now = performance.now();\n\n // Check for resume from execution to prevent time jumps\n // If we just finished executing (or cooldown), reset lastAnimationTime to now\n if (!isExecuting && (now - lastAnimationTime) > 1000) {\n lastAnimationTime = now;\n }\n\n // When executing, freeze deltaTime and animationTime to pause all animations\n const deltaTime = isExecuting ? 0 : (now - lastAnimationTime) / 1000;\n\n if (!isExecuting) {\n lastAnimationTime = now;\n animationTime += deltaTime; // Only advance animation time when not executing\n }\n\n // FPS tracking (skip during execution to preserve frame counters)\n if (!isExecuting) {\n frameCount++;\n if (now - lastFpsCheck >= 1000) {\n currentFps = frameCount;\n frameCount = 0;\n lastFpsCheck = now;\n\n // Hysteresis for low perf mode to prevent flickering\n if (currentFps < 28) lowPerfMode = true;\n if (currentFps > 32) lowPerfMode = false;\n }\n }\n\n // Ensure clean state\n ctx.shadowBlur = 0;\n\n // 500ms cooldown after execution ends to prevent reinitialization from canvas size changes\n const inCooldown = (now - executionEndTime) < 500;\n\n // Initialize stars if needed (but don't reinitialize during execution or cooldown)\n // CRITICAL FIX: Do NOT reinitialize stars on resize! Canvas resize happens BEFORE\n // execution_start event fires, causing stars to \"vanish\" momentarily.\n if (!isExecuting && !inCooldown && !starInitialized) {\n cachedWidth = width;\n cachedHeight = height;\n initStars(width, height);\n }\n\n // Initialize background snowflakes if snow is enabled\n // CRITICAL FIX: Do NOT reinitialize snowflakes on resize! They will just wrap naturally.\n // Reinitializing clears them, causing \"disappearing\" effect during resize storms.\n const snowEnabled = getSetting(\"ChristmasTheme.Snowflake.Enabled\");\n if (!isExecuting && !inCooldown && snowEnabled && (!bgSnowflakesInitialized)) {\n initBgSnowflakes(width, height);\n }\n\n // Check for color scheme changes and update all snowflake colors\n if (snowEnabled && bgSnowflakeEntities.length > 0) {\n const currentSnowflakeColorScheme = getSetting(\"ChristmasTheme.Snowflake.ColorScheme\") as string;\n const currentChristmasColorScheme = getSetting(\"ChristmasTheme.ChristmasEffects.ColorScheme\") as string;\n\n if (currentSnowflakeColorScheme !== lastBgSnowflakeColorScheme ||\n (currentSnowflakeColorScheme === \"match\" && currentChristmasColorScheme !== lastBgColorScheme)) {\n updateBgSnowflakeColors();\n lastBgSnowflakeColorScheme = currentSnowflakeColorScheme;\n lastBgColorScheme = currentChristmasColorScheme;\n }\n }\n\n // Draw gradient background\n ctx.save();\n const gradient = getGradient(ctx, height);\n if (gradient) {\n ctx.fillStyle = gradient;\n ctx.globalAlpha = 0.3; // Subtle overlay (restored to original value)\n ctx.fillRect(0, 0, width, height);\n }\n\n\n // Draw stars by layer for proper depth effect (if enabled)\n const starsEnabled = getSetting(\"ChristmasTheme.Background.Stars\");\n const partyMode = getSetting(\"ChristmasTheme.Background.PartyMode\");\n const colorTheme = getSetting(\"ChristmasTheme.Background.ColorTheme\") || \"classic\";\n const theme = BACKGROUND_THEMES[colorTheme] || BACKGROUND_THEMES.classic;\n const time = animationTime; // Use frozen animation time so effects pause during execution\n\n // Party mode color palette (vibrant rave colors)\n const partyColors = ['#ff0080', '#00ff80', '#8000ff', '#ff8000', '#00ffff', '#ff00ff', '#ffff00', '#00ff00'];\n\n if (starsEnabled) {\n for (let starIdx = 0; starIdx < starEntities.length; starIdx++) {\n const star = starEntities[starIdx];\n // Deterministic skip in low perf mode (skip based on index, not random)\n if (lowPerfMode) {\n if (star.layer === 'distant' && (starIdx % 3 !== 0)) continue;\n if (star.layer === 'normal' && (starIdx % 2 !== 0)) continue;\n }\n\n // Calculate twinkle with per-star variation to prevent sync\n let starSpeed = star.twinkleSpeed * star.twinkleSpeedMod;\n let opacity, starColor;\n\n if (partyMode) {\n // Party mode: rapid twinkle and color cycling\n starSpeed *= 8; // Much faster twinkle\n const fastTwinkle = Math.sin(time * starSpeed + star.twinkleOffset);\n const colorIndex = Math.floor((time * 3 + star.twinkleOffset) % partyColors.length);\n starColor = partyColors[colorIndex];\n opacity = star.baseOpacity * (0.4 + Math.abs(fastTwinkle) * 0.6);\n } else {\n // Normal mode\n const twinkle = Math.sin(time * starSpeed + star.twinkleOffset);\n const twinkle2 = Math.sin(time * starSpeed * 0.67 + star.twinkleOffset2);\n const combinedTwinkle = (twinkle * 0.6 + twinkle2 * 0.4);\n opacity = star.baseOpacity * (0.8 + combinedTwinkle * 0.2); // Subtle 20% variation\n starColor = star.color;\n }\n\n // Use star's color (or party color)\n ctx.fillStyle = starColor;\n\n // Apply layer-based rendering\n if (star.hasGlow && !lowPerfMode) {\n // Bright stars get a subtle glow (enhanced in party mode)\n ctx.shadowBlur = partyMode ? star.size * 10 : star.size * 5;\n ctx.shadowColor = starColor;\n ctx.globalAlpha = opacity * (partyMode ? 0.9 : 0.7);\n ctx.beginPath();\n ctx.arc(star.x, star.y, star.size * (partyMode ? 1.3 : 1), 0, Math.PI * 2);\n ctx.fill();\n\n // Draw diffraction spikes on some bright stars - subtle and thin (skip in party mode)\n if (star.hasSpikes && !partyMode) {\n const combinedTwinkle = Math.sin(time * starSpeed + star.twinkleOffset);\n ctx.shadowBlur = 0;\n const spikeLength = star.size * 4 * (0.6 + combinedTwinkle * 0.4);\n ctx.strokeStyle = starColor;\n ctx.lineWidth = 0.3; // Thinner spikes\n ctx.globalAlpha = opacity * 0.25; // More subtle\n\n // 4-point cross spikes\n ctx.beginPath();\n ctx.moveTo(star.x - spikeLength, star.y);\n ctx.lineTo(star.x + spikeLength, star.y);\n ctx.moveTo(star.x, star.y - spikeLength);\n ctx.lineTo(star.x, star.y + spikeLength);\n ctx.stroke();\n }\n ctx.shadowBlur = 0;\n } else {\n // Regular stars - simple circles\n ctx.globalAlpha = opacity * (partyMode ? 0.7 : 0.5);\n ctx.beginPath();\n ctx.arc(star.x, star.y, star.size * (partyMode ? 1.2 : 1), 0, Math.PI * 2);\n ctx.fill();\n }\n }\n }\n\n // Atmospheric glow at horizon (subtle light pollution effect)\n if (!lowPerfMode) {\n const horizonGlow = ctx.createLinearGradient(0, height * 0.7, 0, height);\n horizonGlow.addColorStop(0, 'rgba(0, 0, 0, 0)');\n horizonGlow.addColorStop(0.5, 'rgba(20, 30, 60, 0.05)');\n horizonGlow.addColorStop(1, 'rgba(40, 50, 80, 0.1)');\n ctx.globalAlpha = 1;\n ctx.fillStyle = horizonGlow;\n ctx.fillRect(0, height * 0.7, width, height * 0.3);\n }\n\n // Draw nebula clouds (soft glowing areas) - skip in low perf mode\n if (!lowPerfMode && nebulaEntities.length > 0) {\n for (const nebula of nebulaEntities) {\n // Static opacity to prevent quantization flicker at low alpha values\n const nebulaOpacity = nebula.opacity;\n\n // Create radial gradient for soft nebula effect\n const nebulaGradient = ctx.createRadialGradient(\n nebula.x, nebula.y, 0,\n nebula.x, nebula.y, nebula.radius\n );\n\n // More subtle, lower opacity nebula colors\n nebulaGradient.addColorStop(0, `rgba(80, 120, 200, ${nebulaOpacity * 0.6})`);\n nebulaGradient.addColorStop(0.4, `rgba(60, 100, 180, ${nebulaOpacity * 0.3})`);\n nebulaGradient.addColorStop(1, 'rgba(0, 0, 0, 0)');\n\n ctx.globalAlpha = 1;\n ctx.fillStyle = nebulaGradient;\n ctx.beginPath();\n ctx.arc(nebula.x, nebula.y, nebula.radius, 0, Math.PI * 2);\n ctx.fill();\n }\n }\n\n // Draw background snowflakes (canvas-based, behind nodes)\n if (snowEnabled && bgSnowflakeEntities.length > 0) {\n ctx.lineCap = 'round';\n const glowIntensity = getSetting(\"ChristmasTheme.Snowflake.Glow\") || 10;\n\n for (const flake of bgSnowflakeEntities) {\n // Update position\n flake.y += flake.speed * deltaTime;\n\n // Update rotation\n flake.rotation += flake.rotationSpeed * deltaTime;\n\n // Horizontal drift using sine wave\n const driftX = Math.sin(time * flake.driftSpeed + flake.driftOffset) * flake.drift;\n\n // Wrap around when off screen (only if not executing/frozen)\n if (!isExecuting && flake.y > height + 20) {\n flake.y = -20;\n flake.x = Math.random() * width;\n flake.color = getBgSnowflakeColor(); // Get new color on wrap\n flake.flakeType = ['branched', 'minimal', 'stellar', 'emoji1', 'emoji2', 'emoji3', 'dendrite', 'ornate'][Math.floor(Math.random() * 8)]; // Random new type\n }\n\n // Draw the snowflake shape with color and glow\n ctx.globalAlpha = flake.opacity;\n ctx.strokeStyle = flake.color;\n ctx.fillStyle = flake.color;\n ctx.lineWidth = Math.max(0.5, flake.size * 0.12);\n\n // Draw subtle glow (matching CSS drop-shadow appearance)\n const glowAmount = Math.min(glowIntensity * 0.4, 8);\n if (glowAmount > 0.5) {\n // Convert hex color to rgba for canvas compatibility\n const hexToRgba = (hex, alpha) => {\n const r = parseInt(hex.slice(1, 3), 16);\n const g = parseInt(hex.slice(3, 5), 16);\n const b = parseInt(hex.slice(5, 7), 16);\n return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n };\n\n const glowRadius = flake.size * 0.6 + glowAmount;\n const gradient = ctx.createRadialGradient(\n flake.x + driftX, flake.y, flake.size * 0.1,\n flake.x + driftX, flake.y, glowRadius\n );\n gradient.addColorStop(0, hexToRgba(flake.color, 0.4));\n gradient.addColorStop(0.5, hexToRgba(flake.color, 0.15));\n gradient.addColorStop(1, hexToRgba(flake.color, 0));\n ctx.globalAlpha = flake.opacity;\n ctx.fillStyle = gradient;\n ctx.beginPath();\n ctx.arc(flake.x + driftX, flake.y, glowRadius, 0, Math.PI * 2);\n ctx.fill();\n\n // Reset for snowflake\n ctx.fillStyle = flake.color;\n }\n\n // Draw snowflake using appropriate style\n const snowflakeType = getSetting(\"ChristmasTheme.Snowflake.Type\");\n\n // Check/Load custom snowflake if needed\n if (snowflakeType === 'custom' || snowflakeType === 'mix_custom') {\n const snowSrc = getSetting(\"ChristmasTheme.Snowflake.CustomImage\") as string;\n if (snowSrc && snowSrc !== customSnowImageSrc) {\n customSnowImageSrc = snowSrc;\n customSnowImage = new Image();\n customSnowImage.onload = () => {\n if (app.canvas) app.canvas.setDirty(true, true);\n };\n customSnowImage.src = snowSrc;\n }\n }\n\n // Determine effective type for this specific flake\n let effectiveType = snowflakeType;\n if (snowflakeType === 'mix_custom') {\n // 50% chance of being custom, otherwise leave as 'mix_custom' to fall through\n // Use flake.x as a stable seed to avoid flickering\n if (Math.floor(flake.x) % 2 === 0) {\n effectiveType = 'custom';\n }\n }\n\n if (effectiveType === 'custom') {\n if (customSnowImage && customSnowImage.complete && customSnowImage.naturalWidth > 0) {\n ctx.save();\n ctx.translate(flake.x + driftX, flake.y);\n ctx.rotate(flake.rotation);\n const size = flake.size * 2; // Slightly larger for images\n ctx.drawImage(customSnowImage, -size / 2, -size / 2, size, size);\n ctx.restore();\n } else {\n // Fallback to minimal\n drawCrystalSnowflake(ctx, flake.x + driftX, flake.y, flake.size, flake.rotation);\n }\n } else if (effectiveType && effectiveType !== 'random' && effectiveType !== 'mix_custom') {\n // Specific type selected (override random assignment)\n if (snowflakeType === 'classic') drawCrystalSnowflake(ctx, flake.x + driftX, flake.y, flake.size, flake.rotation);\n else if (snowflakeType === 'simple') drawEmoji2745(ctx, flake.x + driftX, flake.y, flake.size, flake.rotation);\n else if (snowflakeType === 'bold') drawEmoji2746(ctx, flake.x + driftX, flake.y, flake.size, flake.rotation);\n else drawCrystalSnowflake(ctx, flake.x + driftX, flake.y, flake.size, flake.rotation);\n } else {\n // Random mix (use type assigned to flake)\n if (flake.flakeType === 'minimal') {\n drawCrystalSnowflake(ctx, flake.x + driftX, flake.y, flake.size, flake.rotation);\n } else if (flake.flakeType === 'stellar') {\n drawStellarSnowflake(ctx, flake.x + driftX, flake.y, flake.size, flake.rotation);\n } else if (flake.flakeType === 'emoji1') {\n drawEmoji2744(ctx, flake.x + driftX, flake.y, flake.size, flake.rotation);\n } else if (flake.flakeType === 'emoji2') {\n drawEmoji2745(ctx, flake.x + driftX, flake.y, flake.size, flake.rotation);\n } else if (flake.flakeType === 'emoji3') {\n drawEmoji2746(ctx, flake.x + driftX, flake.y, flake.size, flake.rotation);\n } else if (flake.flakeType === 'dendrite') {\n drawDendriteSnowflake(ctx, flake.x + driftX, flake.y, flake.size, flake.rotation);\n } else if (flake.flakeType === 'ornate') {\n drawOrnateSnowflake(ctx, flake.x + driftX, flake.y, flake.size, flake.rotation);\n } else {\n drawSnowflake(ctx, flake.x + driftX, flake.y, flake.size, flake.rotation);\n }\n }\n }\n }\n\n // Shooting stars - occasional spectacular effect (when enabled)\n const shootingStarsEnabled = getSetting(\"ChristmasTheme.Background.ShootingStars\");\n if (!lowPerfMode && shootingStarsEnabled) {\n // Spawn new shooting star occasionally (average every 10 seconds for calmer feel)\n // Don't spawn new ones during execution to prevent accumulation\n if (!isExecuting && now - lastShootingStarTime > 10000 && Math.random() < 0.02) {\n shootingStars.push(createShootingStar(width, height));\n lastShootingStarTime = now;\n }\n\n // Update and draw shooting stars\n ctx.lineCap = 'round';\n for (let i = shootingStars.length - 1; i >= 0; i--) {\n const star = shootingStars[i];\n\n // Update position\n star.x += star.vx * deltaTime;\n star.y += star.vy * deltaTime;\n star.life -= star.decay * deltaTime;\n\n // Remove dead stars\n if (star.life <= 0 || star.x > width + 50 || star.y > height + 50) {\n shootingStars.splice(i, 1);\n continue;\n }\n\n // Calculate direction vector\n const speed = Math.sqrt(star.vx * star.vx + star.vy * star.vy);\n const dirX = star.vx / speed;\n const dirY = star.vy / speed;\n\n // Terminal flare effect\n let intensityMod = 1.0;\n if (star.willFlare && star.life < 0.3) {\n intensityMod = star.flareIntensity * (1 - star.life / 0.3) * star.life * 3;\n }\n\n // Draw trail fragments (small particles behind)\n if (now - star.lastFragmentTime > star.fragmentInterval && star.fragments.length < 8) {\n star.fragments.push({\n x: star.x - dirX * 3,\n y: star.y - dirY * 3,\n life: 0.5,\n size: 0.3 + Math.random() * 0.4\n });\n star.lastFragmentTime = now;\n }\n\n // Update and draw fragments\n for (let j = star.fragments.length - 1; j >= 0; j--) {\n const frag = star.fragments[j];\n frag.life -= deltaTime * 2;\n if (frag.life <= 0) {\n star.fragments.splice(j, 1);\n continue;\n }\n ctx.fillStyle = `rgba(255, 200, 150, ${frag.life * 0.4})`;\n ctx.globalAlpha = frag.life;\n ctx.beginPath();\n ctx.arc(frag.x, frag.y, frag.size, 0, Math.PI * 2);\n ctx.fill();\n }\n\n // Draw main trail with warm-to-white gradient\n const tailX = star.x - dirX * star.length * star.life;\n const tailY = star.y - dirY * star.length * star.life;\n\n const trailGradient = ctx.createLinearGradient(tailX, tailY, star.x, star.y);\n trailGradient.addColorStop(0, 'rgba(255, 180, 100, 0)');\n trailGradient.addColorStop(0.4, `rgba(255, 200, 150, ${star.life * star.brightness * 0.2 * intensityMod})`);\n trailGradient.addColorStop(0.8, `rgba(255, 240, 220, ${star.life * star.brightness * 0.5 * intensityMod})`);\n trailGradient.addColorStop(1, `rgba(255, 255, 255, ${star.life * star.brightness * 0.9 * intensityMod})`);\n\n ctx.strokeStyle = trailGradient;\n ctx.lineWidth = 1 + star.life * 1.5;\n ctx.globalAlpha = star.life;\n ctx.beginPath();\n ctx.moveTo(tailX, tailY);\n ctx.lineTo(star.x, star.y);\n ctx.stroke();\n\n // Glowing head with warm core\n const headSize = (1.2 + star.life) * intensityMod;\n ctx.shadowBlur = 10 * intensityMod;\n ctx.shadowColor = '#ffffcc';\n ctx.fillStyle = '#ffffff';\n ctx.globalAlpha = star.life * star.brightness * intensityMod;\n ctx.beginPath();\n ctx.arc(star.x, star.y, headSize, 0, Math.PI * 2);\n ctx.fill();\n ctx.shadowBlur = 0;\n }\n }\n\n // Fireworks effect (when enabled, during finale, OR during grace period with existing particles)\n const hasExistingParticles = fireworkRockets.length > 0 || fireworkParticles.length > 0 || fireworkSparks.length > 0;\n const fireworksEnabled = getSetting(\"ChristmasTheme.Background.Fireworks\") || finaleActive || (finaleGracePeriod && hasExistingParticles);\n if (fireworksEnabled) {\n // Check if finale is still active\n if (finaleActive && now - finaleStartTime > FINALE_DURATION) {\n finaleActive = false;\n finaleGracePeriod = true; // Enter grace period to let particles fade\n console.log(\"🎆 Finale ended, entering grace period\");\n }\n\n // End grace period when all particles have faded\n if (finaleGracePeriod && !hasExistingParticles) {\n finaleGracePeriod = false;\n console.log(\"🎆 Grace period complete\");\n }\n\n // Spawn rate depends on finale state - but DON'T spawn during grace period or execution\n const shouldSpawn = !isExecuting && (finaleActive || (getSetting(\"ChristmasTheme.Background.Fireworks\") && !finaleGracePeriod));\n if (shouldSpawn) {\n const spawnInterval = finaleActive ? 100 + Math.random() * 150 : 2000 + Math.random() * 2000;\n if (now - lastFireworkTime > spawnInterval) {\n const spawnCount = finaleActive ? 2 + Math.floor(Math.random() * 3) : 1;\n for (let s = 0; s < spawnCount; s++) {\n const rocket = createFireworkRocket(width, height);\n // Special golden fireworks during finale (30% chance)\n if (finaleActive && Math.random() < 0.3) {\n rocket.palette = ['#ffd700', '#ffec99', '#fff9db'];\n rocket.vy = -14 - Math.random() * 6;\n }\n fireworkRockets.push(rocket);\n }\n lastFireworkTime = now;\n }\n }\n\n // Update and draw rockets with enhanced trails\n for (let i = fireworkRockets.length - 1; i >= 0; i--) {\n const rocket = fireworkRockets[i];\n\n // Apply gravity\n rocket.vy += 0.12;\n rocket.x += rocket.vx;\n rocket.y += rocket.vy;\n rocket.age += deltaTime;\n rocket.trailTimer += deltaTime;\n\n // Add trail points more frequently\n if (rocket.trailTimer > 0.02) {\n rocket.trail.push({ x: rocket.x, y: rocket.y, alpha: 1, size: rocket.size });\n rocket.trailTimer = 0;\n }\n // Keep more trail points for longer trails\n if (rocket.trail.length > 20) rocket.trail.shift();\n\n // Explode when velocity slows\n if (rocket.vy > -2 && !rocket.exploded) {\n rocket.exploded = true;\n fireworkParticles.push(...createExplosionParticles(rocket.x, rocket.y, rocket.palette, rocket.explosionType));\n fireworkRockets.splice(i, 1);\n continue;\n }\n\n // Force explode if rocket is too old (simplified explosion for performance)\n if (rocket.age > 5 && !rocket.exploded) {\n rocket.exploded = true;\n // Create a simpler explosion with fewer particles for forced timeouts\n const simpleCount = 15 + Math.floor(Math.random() * 10); // 15-25 particles vs 50-120 normal\n for (let i = 0; i < simpleCount; i++) {\n const angle = (Math.PI * 2 * i) / simpleCount;\n const speed = 2 + Math.random() * 2;\n fireworkParticles.push({\n x: rocket.x,\n y: rocket.y,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed,\n color: rocket.palette[Math.floor(Math.random() * rocket.palette.length)],\n alpha: 1,\n size: 1.5 + Math.random(),\n decay: 0.025, // Faster fade than normal\n trail: [],\n hasTrail: false, // No trails for performance\n gravity: 0.05\n });\n }\n fireworkRockets.splice(i, 1);\n continue;\n }\n\n // Draw enhanced rocket trail with gradient\n const primaryColor = rocket.palette[0];\n for (let j = 0; j < rocket.trail.length; j++) {\n const point = rocket.trail[j];\n const progress = j / rocket.trail.length;\n const alpha = progress * 0.8;\n const size = point.size * progress * 0.8;\n\n ctx.globalAlpha = alpha;\n ctx.fillStyle = primaryColor;\n ctx.beginPath();\n ctx.arc(point.x, point.y, size, 0, Math.PI * 2);\n ctx.fill();\n }\n\n // Draw rocket head with bright glow\n ctx.shadowBlur = 15;\n ctx.shadowColor = primaryColor;\n ctx.fillStyle = '#ffffff';\n ctx.globalAlpha = 1;\n ctx.beginPath();\n ctx.arc(rocket.x, rocket.y, rocket.size + 1, 0, Math.PI * 2);\n ctx.fill();\n\n // Inner bright core\n ctx.fillStyle = primaryColor;\n ctx.beginPath();\n ctx.arc(rocket.x, rocket.y, rocket.size * 0.6, 0, Math.PI * 2);\n ctx.fill();\n ctx.shadowBlur = 0;\n }\n\n // Update and draw explosion particles with trails\n for (let i = fireworkParticles.length - 1; i >= 0; i--) {\n const p = fireworkParticles[i];\n\n // Store trail before updating position\n if (p.hasTrail && p.trail) {\n p.trail.push({ x: p.x, y: p.y, alpha: p.alpha });\n if (p.trail.length > 8) p.trail.shift();\n }\n\n // Apply physics\n p.vy += p.gravity || 0.04;\n p.x += p.vx;\n p.y += p.vy;\n p.vx *= 0.985;\n p.vy *= 0.985;\n p.alpha -= p.decay;\n\n // Handle crackle effect\n if (p.crackle && p.crackleTime !== undefined) {\n p.crackleTime -= deltaTime;\n if (p.crackleTime <= 0 && p.alpha > 0.3) {\n // Create mini explosion\n for (let c = 0; c < 5; c++) {\n const angle = Math.random() * Math.PI * 2;\n const speed = 1 + Math.random() * 2;\n fireworkSparks.push({\n x: p.x, y: p.y,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed,\n alpha: 0.8,\n size: 0.8,\n decay: 0.05,\n twinkle: Math.random() * Math.PI * 2\n });\n }\n p.crackle = false;\n }\n }\n\n // Remove faded\n if (p.alpha <= 0) {\n fireworkParticles.splice(i, 1);\n continue;\n }\n\n // Draw particle trail first (behind main particle)\n if (p.hasTrail && p.trail && p.trail.length > 0) {\n for (let t = 0; t < p.trail.length; t++) {\n const tp = p.trail[t];\n const trailAlpha = (t / p.trail.length) * p.alpha * 0.5;\n const trailSize = p.size * (t / p.trail.length) * 0.7;\n ctx.globalAlpha = trailAlpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(tp.x, tp.y, trailSize, 0, Math.PI * 2);\n ctx.fill();\n }\n }\n\n // Draw main particle with glow\n ctx.shadowBlur = 8;\n ctx.shadowColor = p.color;\n ctx.fillStyle = p.color;\n ctx.globalAlpha = p.alpha;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);\n ctx.fill();\n ctx.shadowBlur = 0;\n }\n\n // Update and draw sparks/glitter\n for (let i = fireworkSparks.length - 1; i >= 0; i--) {\n const s = fireworkSparks[i];\n\n s.vy += 0.03;\n s.x += s.vx;\n s.y += s.vy;\n s.alpha -= s.decay;\n s.twinkle += 0.3;\n\n if (s.alpha <= 0) {\n fireworkSparks.splice(i, 1);\n continue;\n }\n\n // Twinkle effect\n const twinkleAlpha = s.alpha * (0.5 + Math.sin(s.twinkle) * 0.5);\n\n ctx.fillStyle = '#ffffff';\n ctx.globalAlpha = twinkleAlpha;\n ctx.beginPath();\n ctx.arc(s.x, s.y, s.size, 0, Math.PI * 2);\n ctx.fill();\n }\n }\n\n // ✨ Mouse Effects\n updateMouseParticles(deltaTime);\n drawMouseParticles(ctx);\n\n // 🎆 Finale Particles (confetti & stars)\n if (finaleActive || finaleConfetti.length > 0 || finaleStars.length > 0) {\n updateFinaleParticles(ctx, ctx.canvas);\n drawFinaleParticles(ctx);\n }\n\n ctx.restore();\n}\n\n/**\n * Animation loop to keep background alive when no user interaction occours\n */\nfunction startAnimationLoop() {\n if (animationLoopId !== null) return;\n\n function loop() {\n if (isPageVisible && getSetting(\"ChristmasTheme.Background.Enabled\")) {\n // Check if we should pause during execution\n const pauseDuringRender = getSetting(\"ChristmasTheme.PauseDuringRender\");\n const shouldRender = !isExecuting || !pauseDuringRender;\n\n if (shouldRender && app.canvas) {\n // Force redraw to keep animations playing\n app.canvas.setDirty(true, true);\n }\n }\n animationLoopId = requestAnimationFrame(loop);\n }\n animationLoopId = requestAnimationFrame(loop);\n}\n\nfunction stopAnimationLoop() {\n if (animationLoopId !== null) {\n cancelAnimationFrame(animationLoopId);\n animationLoopId = null;\n }\n}\n\n/**\n * Hook into LGraphCanvas to draw our background\n */\nfunction installBackgroundHook() {\n if (!app.canvas) {\n console.log(\"Waiting for app.canvas to install background hook...\");\n setTimeout(installBackgroundHook, 100);\n return;\n }\n\n const canvas = app.canvas;\n\n // Store original method\n if (!originalDrawBackCanvas) {\n originalDrawBackCanvas = canvas.constructor.prototype.drawBackCanvas;\n }\n\n // Override drawBackCanvas to add our background\n canvas.constructor.prototype.drawBackCanvas = function () {\n // Call original first (clears background, draws grid)\n if (originalDrawBackCanvas) {\n originalDrawBackCanvas.apply(this, [...arguments]);\n }\n\n // Then draw our enhanced background on top (wrapped in try-catch to not break ComfyUI)\n try {\n if (getSetting(\"ChristmasTheme.Background.Enabled\") && this.bgctx) {\n drawEnhancedBackground(this.bgctx, this.bgcanvas.width, this.bgcanvas.height);\n }\n } catch (e) {\n console.error(\"Enhanced background error:\", e);\n }\n };\n\n // Force a redraw and start loop\n canvas.setDirty(true, true);\n startAnimationLoop();\n console.log(\"✨ Background hook installed successfully\");\n}\n\n/**\n * Remove background hook and restore original\n */\nfunction removeBackgroundHook() {\n stopAnimationLoop();\n if (originalDrawBackCanvas && app.canvas) {\n app.canvas.constructor.prototype.drawBackCanvas = originalDrawBackCanvas;\n app.canvas.setDirty(true, true);\n }\n starEntities = [];\n starInitialized = false;\n cachedGradient = null;\n}\n\napp.registerExtension({\n name: \"Comfy.EnhancedBackground\",\n async setup() {\n // Prevent double setup\n if (extensionSetupComplete) {\n return;\n }\n extensionSetupComplete = true;\n\n console.log(\"🎨 Setting up Enhanced Background extension...\");\n\n // Initialize settings cache\n initSettingsCache();\n\n // Listen for workflow execution to pause animations during generation\n app.api.addEventListener(\"execution_start\", () => {\n isExecuting = true;\n });\n app.api.addEventListener(\"execution_cached\", () => {\n // Cached execution also counts as executing\n isExecuting = true;\n });\n app.api.addEventListener(\"executed\", () => {\n isExecuting = false;\n executionEndTime = performance.now(); // Track when execution ended\n });\n app.api.addEventListener(\"execution_error\", () => {\n isExecuting = false;\n executionEndTime = performance.now();\n });\n\n // Add settings with onChange callbacks to update cache\n app.ui.settings.addSetting({\n id: \"ChristmasTheme.Background.Enabled\",\n name: \"🌟 Background Effect\",\n type: \"combo\",\n options: [\n { value: true, text: \"✨ On\" },\n { value: false, text: \"⭘ Off\" }\n ],\n defaultValue: true,\n section: \"Background Theme\",\n onChange: async (value) => {\n updateCache(\"ChristmasTheme.Background.Enabled\", value);\n if (isInitialSetup) return;\n\n if (value) {\n installBackgroundHook();\n } else {\n removeBackgroundHook();\n }\n\n // Force redraw\n if (app.canvas) {\n app.canvas.setDirty(true, true);\n }\n }\n });\n\n app.ui.settings.addSetting({\n id: \"ChristmasTheme.Background.ColorTheme\",\n name: \"🎨 Color Theme\",\n type: \"combo\",\n options: [\n { value: \"classic\", text: \"🌌 Classic Night\" },\n { value: \"christmas\", text: \"🎄 Christmas Forest\" },\n { value: \"candycane\", text: \"🍬 Candy Cane Red\" },\n { value: \"frostnight\", text: \"❄️ Frost Night\" },\n { value: \"gingerbread\", text: \"🍪 Gingerbread\" },\n { value: \"darknight\", text: \"🌑 Dark Night\" }\n ],\n defaultValue: \"frostnight\",\n section: \"Background Theme\",\n onChange: async (value) => {\n updateCache(\"ChristmasTheme.Background.ColorTheme\", value);\n if (isInitialSetup) return;\n\n // Invalidate gradient cache\n cachedGradient = null;\n\n // Force redraw\n if (app.canvas) {\n app.canvas.setDirty(true, true);\n }\n }\n });\n\n app.ui.settings.addSetting({\n id: \"ChristmasTheme.Background.ShootingStars\",\n name: \"☄️ Shooting Stars\",\n type: \"combo\",\n options: [\n { value: true, text: \"✨ On\" },\n { value: false, text: \"⭘ Off\" }\n ],\n defaultValue: true,\n section: \"Background Theme\",\n onChange: async (value) => {\n updateCache(\"ChristmasTheme.Background.ShootingStars\", value);\n if (isInitialSetup) return;\n\n // Clear existing shooting stars if disabled\n if (!value) {\n shootingStars = [];\n }\n\n // Force redraw\n if (app.canvas) {\n app.canvas.setDirty(true, true);\n }\n }\n });\n\n app.ui.settings.addSetting({\n id: \"ChristmasTheme.Background.Stars\",\n name: \"⭐ Background Stars\",\n type: \"combo\",\n options: [\n { value: true, text: \"✨ On\" },\n { value: false, text: \"⭘ Off\" }\n ],\n defaultValue: true,\n section: \"Background Theme\",\n onChange: async (value) => {\n updateCache(\"ChristmasTheme.Background.Stars\", value);\n if (isInitialSetup) return;\n if (app.canvas) {\n app.canvas.setDirty(true, true);\n }\n }\n });\n\n app.ui.settings.addSetting({\n id: \"ChristmasTheme.Background.PartyMode\",\n name: \"🪩 Party Mode (Rave Stars)\",\n type: \"combo\",\n options: [\n { value: true, text: \"🎉 On\" },\n { value: false, text: \"⭘ Off\" }\n ],\n defaultValue: false,\n section: \"Background Theme\",\n onChange: async (value) => {\n updateCache(\"ChristmasTheme.Background.PartyMode\", value);\n if (isInitialSetup) return;\n if (app.canvas) {\n app.canvas.setDirty(true, true);\n }\n }\n });\n\n app.ui.settings.addSetting({\n id: \"ChristmasTheme.Background.Fireworks\",\n name: \"🎆 Fireworks\",\n type: \"combo\",\n options: [\n { value: true, text: \"🎇 On\" },\n { value: false, text: \"⭘ Off\" }\n ],\n defaultValue: false,\n section: \"Background Theme\",\n onChange: async (value) => {\n updateCache(\"ChristmasTheme.Background.Fireworks\", value);\n if (isInitialSetup) return;\n // Clear existing fireworks when disabled\n if (!value) {\n fireworkRockets = [];\n fireworkParticles = [];\n }\n if (app.canvas) {\n app.canvas.setDirty(true, true);\n }\n }\n });\n\n app.ui.settings.addSetting({\n id: \"ChristmasTheme.Background.MouseEffect\",\n name: \"✨ Mouse Trail Effect\",\n type: \"combo\",\n options: [\n { value: \"none\", text: \"⭘ Off\" },\n { value: \"sparkler\", text: \"✨ Sparkler\" },\n { value: \"snowflake\", text: \"❄️ Snowflake\" },\n { value: \"confetti\", text: \"🎊 Confetti\" },\n { value: \"stardust\", text: \"⭐ Stardust\" },\n { value: \"comet\", text: \"☄️ Comet\" },\n { value: \"aurora\", text: \"🌌 Aurora\" },\n { value: \"ribbon\", text: \"🎀 Ribbon\" },\n { value: \"crystal\", text: \"💎 Crystal\" },\n { value: \"petals\", text: \"🌸 Petals\" },\n { value: \"gifts\", text: \"🎁 Gifts\" },\n { value: \"candy\", text: \"🍬 Candy\" },\n { value: \"orb\", text: \"🔮 Magic Orb\" },\n { value: \"magic\", text: \"✨ Magic Wand\" },\n { value: \"nova\", text: \"🌟 Nova\" },\n { value: \"bubbles\", text: \"💧 Bubbles\" },\n { value: \"embers\", text: \"🔥 Embers\" },\n { value: \"lightning\", text: \"⚡ Lightning\" },\n { value: \"leaves\", text: \"🍂 Leaves\" },\n { value: \"wishes\", text: \"💫 Wishes\" },\n { value: \"notes\", text: \"🎵 Notes\" },\n { value: \"hearts\", text: \"💖 Hearts\" }\n ],\n defaultValue: \"none\",\n section: \"Background Theme\",\n tooltip: \"Choose a mouse trail effect\",\n onChange: async (value) => {\n updateCache(\"ChristmasTheme.Background.MouseEffect\", value);\n if (isInitialSetup) return;\n if (!value || value === \"none\") {\n mouseParticles = [];\n }\n if (app.canvas) {\n app.canvas.setDirty(true, true);\n }\n }\n });\n\n app.ui.settings.addSetting({\n id: \"ChristmasTheme.Background.Countdown\",\n name: \"🎊 New Year Countdown\",\n type: \"combo\",\n options: [\n { value: true, text: \"🕐 On\" },\n { value: false, text: \"⭘ Off\" }\n ],\n defaultValue: true,\n section: \"Background Theme\",\n onChange: async (value) => {\n updateCache(\"ChristmasTheme.Background.Countdown\", value);\n if (isInitialSetup) return;\n toggleCountdownDisplay(value);\n }\n });\n\n // Temporarily hidden - uncomment to re-enable\n // app.ui.settings.addSetting({\n // id: \"ChristmasTheme.Background.ShowFinaleButton\",\n // name: \"🎆 Show Finale Button\",\n // tooltip: \"Turn on if you don't like surprises or wait till 00:00:00 for the show!\",\n // type: \"combo\",\n // options: [\n // { value: true, text: \"🎇 Show\" },\n // { value: false, text: \"🎁 Surprise\" }\n // ],\n // defaultValue: false,\n // section: \"Background Theme\",\n // onChange: async (value) => {\n // updateCache(\"ChristmasTheme.Background.ShowFinaleButton\", value);\n // if (isInitialSetup) return;\n // if (value && getSetting(\"ChristmasTheme.Background.Countdown\")) {\n // showFinaleButton();\n // } else {\n // hideFinaleButton();\n // }\n // }\n // });\n\n // Load stored values AFTER settings are registered\n loadSettingFromStorage(\"ChristmasTheme.Background.Enabled\");\n loadSettingFromStorage(\"ChristmasTheme.Background.ColorTheme\");\n loadSettingFromStorage(\"ChristmasTheme.Background.Stars\");\n loadSettingFromStorage(\"ChristmasTheme.Background.PartyMode\");\n loadSettingFromStorage(\"ChristmasTheme.Background.ShootingStars\");\n loadSettingFromStorage(\"ChristmasTheme.Background.Fireworks\");\n loadSettingFromStorage(\"ChristmasTheme.Background.MouseEffect\");\n loadSettingFromStorage(\"ChristmasTheme.Background.Countdown\");\n // loadSettingFromStorage(\"ChristmasTheme.Background.ShowFinaleButton\"); // Temporarily hidden\n\n // Mark initial setup complete\n isInitialSetup = false;\n\n // Install hook if enabled\n if (getSetting(\"ChristmasTheme.Background.Enabled\")) {\n installBackgroundHook();\n }\n\n // Initialize countdown if enabled\n if (getSetting(\"ChristmasTheme.Background.Countdown\")) {\n toggleCountdownDisplay(true);\n }\n\n // Return cleanup function\n return () => {\n removeBackgroundHook();\n if (countdownInterval) {\n clearInterval(countdownInterval);\n }\n if (countdownElement) {\n countdownElement.remove();\n }\n };\n }\n});\n\n// Export visibility and execution state for other modules\nexport { isPageVisible, isExecuting };"],"names":["gradient","i"],"mappings":"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"} \ No newline at end of file diff --git a/js/christmas-sidebar.js.map b/js/christmas-sidebar.js.map deleted file mode 100644 index 29b400f..0000000 --- a/js/christmas-sidebar.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"christmas-sidebar.js","sources":["../src/utils/dom.ts","../src/christmas-sidebar.ts"],"sourcesContent":["\ninterface ElementProps {\n className?: string;\n style?: Partial;\n dataset?: Record;\n [key: string]: any;\n}\n\n/**\n * Helper to create DOM elements with less boilerplate\n */\nexport function el(\n tag: K,\n props: ElementProps = {},\n children: (string | Node | (string | Node)[])[] = []\n): HTMLElementTagNameMap[K] {\n const element = document.createElement(tag);\n\n // Handle props\n for (const [key, value] of Object.entries(props)) {\n if (value === undefined) continue;\n\n if (key === 'style' && typeof value === 'object') {\n Object.assign(element.style, value);\n } else if (key === 'dataset' && typeof value === 'object') {\n Object.assign(element.dataset, value);\n } else if (key.startsWith('on') && typeof value === 'function') {\n const eventName = key.toLowerCase().substring(2);\n element.addEventListener(eventName, value as EventListener);\n } else {\n // @ts-ignore\n element[key] = value;\n }\n }\n\n // Handle children (flatten one level to allow passing arrays)\n children.flat().forEach(child => {\n if (child === null || child === undefined) return;\n\n if (typeof child === 'string' || typeof child === 'number') {\n element.appendChild(document.createTextNode(String(child)));\n } else if (child instanceof Node) {\n element.appendChild(child);\n }\n });\n\n return element;\n}\n","/**\n * Christmas Theme Sidebar Tab\n * Provides quick access to all Christmas Theme settings in the ComfyUI sidebar\n */\n\n// @ts-ignore - ComfyUI external module\nimport { app } from \"../../../scripts/app.js\";\nimport { getSetting, updateCache } from \"./settings-cache\";\n// @ts-ignore\nimport SIDEBAR_STYLES from './sidebar.css?inline';\nimport { el } from \"./utils/dom\";\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\ninterface SettingOption {\n value: string | number;\n text: string;\n}\n\ninterface SettingConfig {\n id: string;\n label: string;\n type: 'toggle' | 'select' | 'slider';\n tooltip?: string;\n trueValue?: number | boolean;\n falseValue?: number | boolean;\n options?: SettingOption[];\n min?: number;\n max?: number;\n step?: number;\n}\n\ninterface SectionConfig {\n title: string;\n settings: SettingConfig[];\n}\n\ntype SettingsConfigType = Record;\n\n// ============================================================================\n// Settings Configuration\n// ============================================================================\n\nconst SETTINGS_CONFIG: SettingsConfigType = {\n background: {\n title: \"🌌 Background\",\n settings: [\n {\n id: \"ChristmasTheme.Background.Enabled\",\n label: \"🌟 Background Effect\",\n type: \"toggle\"\n },\n {\n id: \"ChristmasTheme.Background.ColorTheme\",\n label: \"🎨 Color Theme\",\n type: \"select\",\n options: [\n { value: \"classic\", text: \"🌌 Classic Night\" },\n { value: \"christmas\", text: \"🎄 Christmas Forest\" },\n { value: \"candycane\", text: \"🍬 Candy Cane Red\" },\n { value: \"frostnight\", text: \"❄️ Frost Night\" },\n { value: \"gingerbread\", text: \"🍪 Gingerbread\" },\n { value: \"darknight\", text: \"🌑 Dark Night\" }\n ]\n },\n {\n id: \"ChristmasTheme.Background.Stars\",\n label: \"⭐ Background Stars\",\n type: \"toggle\"\n },\n {\n id: \"ChristmasTheme.Background.ShootingStars\",\n label: \"☄️ Shooting Stars\",\n type: \"toggle\"\n },\n {\n id: \"ChristmasTheme.Background.PartyMode\",\n label: \"🪩 Party Mode\",\n type: \"toggle\"\n },\n {\n id: \"ChristmasTheme.Background.Fireworks\",\n label: \"🎆 Fireworks\",\n type: \"toggle\"\n },\n {\n id: \"ChristmasTheme.Background.Countdown\",\n label: \"🎊 New Year Countdown\",\n type: \"toggle\"\n },\n {\n id: \"ChristmasTheme.Background.MouseEffect\",\n label: \"✨ Mouse Trail\",\n type: \"select\",\n options: [\n { value: \"none\", text: \"⭘ Off\" },\n { value: \"sparkler\", text: \"✨ Sparkler\" },\n { value: \"snowflake\", text: \"❄️ Snowflake\" },\n { value: \"confetti\", text: \"🎊 Confetti\" },\n { value: \"stardust\", text: \"⭐ Stardust\" },\n { value: \"comet\", text: \"☄️ Comet\" },\n { value: \"aurora\", text: \"🌌 Aurora\" },\n { value: \"ribbon\", text: \"🎀 Ribbon\" },\n { value: \"crystal\", text: \"💎 Crystal\" },\n { value: \"petals\", text: \"🌸 Petals\" },\n { value: \"gifts\", text: \"🎁 Gifts\" },\n { value: \"candy\", text: \"🍬 Candy\" },\n { value: \"orb\", text: \"🔮 Magic Orb\" },\n { value: \"magic\", text: \"✨ Magic Wand\" },\n { value: \"nova\", text: \"🌟 Nova\" },\n { value: \"bubbles\", text: \"💧 Bubbles\" },\n { value: \"embers\", text: \"🔥 Embers\" },\n { value: \"lightning\", text: \"⚡ Lightning\" },\n { value: \"leaves\", text: \"🍂 Leaves\" },\n { value: \"wishes\", text: \"💫 Wishes\" },\n { value: \"notes\", text: \"🎵 Notes\" },\n { value: \"hearts\", text: \"💖 Hearts\" }\n ]\n }\n ]\n },\n lights: {\n title: \"🎄 Christmas Lights\",\n settings: [\n {\n id: \"ChristmasTheme.ChristmasEffects.LightSwitch\",\n label: \"🎄 Christmas Lights\",\n type: \"toggle\",\n trueValue: 1,\n falseValue: 0\n },\n {\n id: \"ChristmasTheme.ChristmasEffects.ColorScheme\",\n label: \"🎨 Color Scheme\",\n type: \"select\",\n options: [\n { value: \"traditional\", text: \"🎄 Traditional\" },\n { value: \"warm\", text: \"🔆 Warm White\" },\n { value: \"cool\", text: \"❄️ Cool White\" },\n { value: \"multicolor\", text: \"🌈 Multicolor\" },\n { value: \"pastel\", text: \"🎀 Pastel\" },\n { value: \"newyear\", text: \"🎉 New Year's Eve\" }\n ]\n },\n {\n id: \"ChristmasTheme.ChristmasEffects.Twinkle\",\n label: \"✨ Light Effect\",\n type: \"select\",\n options: [\n { value: \"steady\", text: \"Steady\" },\n { value: \"gentle\", text: \"Gentle Twinkle\" },\n { value: \"sparkle\", text: \"Sparkle\" },\n { value: \"candycane\", text: \"🍬 Candy Cane\" },\n { value: \"frost\", text: \"❄️ Frost Trail\" },\n { value: \"aurora\", text: \"🌌 Aurora Flow\" }\n ]\n },\n {\n id: \"ChristmasTheme.ChristmasEffects.BulbShape\",\n label: \"💡 Bulb Shape\",\n type: \"select\",\n options: [\n { value: \"classic\", text: \"🔴 Classic Round\" },\n { value: \"icicle\", text: \"❄️ Icicle Point\" }\n ]\n },\n {\n id: \"ChristmasTheme.ChristmasEffects.Direction\",\n label: \"🔄 Flow Direction\",\n type: \"select\",\n tooltip: \"If not animating properly, refresh the page\",\n options: [\n { value: -1, text: \"Forward ➡️\" },\n { value: 1, text: \"Reverse ⬅️\" }\n ]\n },\n {\n id: \"ChristmasTheme.ChristmasEffects.Thickness\",\n label: \"💫 Light Size\",\n type: \"slider\",\n min: 1,\n max: 10,\n step: 0.5\n },\n {\n id: \"ChristmasTheme.ChristmasEffects.GlowIntensity\",\n label: \"✨ Glow Intensity\",\n type: \"slider\",\n min: 0,\n max: 30,\n step: 1\n },\n {\n id: \"ChristmasTheme.Link Style\",\n label: \"🔗 Link Style\",\n type: \"select\",\n options: [\n { value: \"spline\", text: \"Spline\" },\n { value: \"straight\", text: \"Straight\" },\n { value: \"linear\", text: \"Linear\" },\n { value: \"hidden\", text: \"Hidden\" }\n ]\n }\n ]\n },\n snow: {\n title: \"❄️ Snow Effect\",\n settings: [\n {\n id: \"ChristmasTheme.Snowflake.Enabled\",\n label: \"❄️ Snow Effect\",\n type: \"toggle\",\n trueValue: 1,\n falseValue: 0\n },\n {\n id: \"ChristmasTheme.Snowflake.ColorScheme\",\n label: \"🎨 Snowflake Color\",\n type: \"select\",\n options: [\n { value: \"white\", text: \"❄️ Classic White\" },\n { value: \"blue\", text: \"💠 Ice Blue\" },\n { value: \"rainbow\", text: \"🌈 Rainbow\" },\n { value: \"white\", text: \"❄️ Classic White\" },\n { value: \"blue\", text: \"💠 Ice Blue\" },\n { value: \"rainbow\", text: \"🌈 Rainbow\" },\n { value: \"match\", text: \"🎨 Match Lights\" },\n { value: \"newyear\", text: \"🎉 New Year's Eve\" }\n ]\n },\n {\n id: \"ChristmasTheme.Snowflake.Type\",\n label: \"💠 Snowflake Shape\",\n type: \"select\",\n options: [\n { value: \"random\", text: \"🎲 Random Mix\" },\n { value: \"classic\", text: \"❄️ Classic\" },\n { value: \"simple\", text: \"❅ Simple\" },\n { value: \"bold\", text: \"❆ Bold\" },\n { value: \"custom\", text: \"📁 Custom Image\" },\n { value: \"mix_custom\", text: \"🎲 Mix Custom + Standard\" }\n ]\n },\n {\n id: \"ChristmasTheme.Snowflake.Glow\",\n label: \"✨ Snowflake Glow\",\n type: \"slider\",\n min: 0,\n max: 20,\n step: 1\n }\n ]\n },\n performance: {\n title: \"⚡ Performance\",\n settings: [\n {\n id: \"ChristmasTheme.PauseDuringRender\",\n label: \"⏸️ Pause During Render\",\n type: \"toggle\"\n }\n ]\n }\n};\n\n// ============================================================================\n// CSS Styles\n// ============================================================================\n\n\n\n// ============================================================================\n// UI Element Creators\n// ============================================================================\n\n/**\n * Handle file upload for custom assets\n */\nfunction handleFileUpload(callback: (base64: string) => void) {\n const input = el('input', { type: 'file', accept: 'image/*' });\n input.onchange = (e) => {\n const file = (e.target as HTMLInputElement).files?.[0];\n if (!file) return;\n\n // Size check (max 2MB to be safe with localStorage quotas)\n if (file.size > 2 * 1024 * 1024) {\n alert(\"Image too large! Please select an image under 2MB.\");\n return;\n }\n\n const reader = new FileReader();\n reader.onload = (evt) => {\n const res = evt.target?.result as string;\n if (res) callback(res);\n };\n reader.readAsDataURL(file);\n };\n input.click();\n}\n\n/**\n * Create a toggle switch element\n */\nfunction createToggle(settingConfig: SettingConfig): HTMLDivElement {\n const trueValue = settingConfig.trueValue ?? true;\n const falseValue = settingConfig.falseValue ?? false;\n const currentValue = getSetting(settingConfig.id);\n const isActive = currentValue === trueValue || currentValue === true || currentValue === 1;\n\n return el('div', {\n className: `christmas-toggle ${isActive ? 'active' : ''}`,\n onClick: (e: MouseEvent) => {\n const t = e.currentTarget as HTMLElement;\n const wasActive = t.classList.contains('active');\n const newValue = wasActive ? falseValue : trueValue;\n\n t.classList.toggle('active');\n updateCache(settingConfig.id, newValue);\n\n // Also update the native ComfyUI setting\n app.ui?.settings?.setSettingValue(settingConfig.id, newValue);\n\n // Force canvas redraw\n app.canvas?.setDirty(true, true);\n }\n });\n}\n\n/**\n * Create a select dropdown element\n */\nfunction createSelect(settingConfig: SettingConfig): HTMLElement {\n const currentValue = getSetting(settingConfig.id);\n\n const options = (settingConfig.options || []).map(opt =>\n el('option', {\n value: String(opt.value),\n selected: String(opt.value) === String(currentValue)\n }, [opt.text])\n );\n\n const select = el('select', {\n className: 'christmas-select',\n title: settingConfig.tooltip || '',\n onChange: (e: Event) => {\n const sel = e.target as HTMLSelectElement;\n let value: string | number = sel.value;\n if (!isNaN(Number(value)) && value !== '') {\n value = Number(value);\n }\n\n updateCache(settingConfig.id, value);\n app.ui?.settings?.setSettingValue(settingConfig.id, value);\n app.canvas?.setDirty(true, true);\n\n // Trigger upload if switching to custom\n if (value === 'custom' || value === 'mix_custom') {\n const uploadBtn = sel.nextElementSibling as HTMLElement;\n if (uploadBtn) {\n uploadBtn.style.display = 'block';\n // Robust replace for both 'Type' and 'ColorTheme'\n const imageKey = settingConfig.id.replace(/(Type|ColorTheme)$/, 'CustomImage');\n if (!getSetting(imageKey)) {\n uploadBtn.click();\n }\n }\n } else {\n const uploadBtn = sel.nextElementSibling as HTMLElement;\n if (uploadBtn) uploadBtn.style.display = 'none';\n }\n }\n }, options) as HTMLSelectElement;\n\n // Special handling for Custom Image capable fields\n // Changed from Background.ColorTheme to Snowflake.Type\n if (settingConfig.id === 'ChristmasTheme.Snowflake.Type') {\n const uploadBtn = el('button', {\n textContent: '📁',\n className: 'christmas-upload-btn',\n title: 'Upload Custom Snowflake',\n style: { display: (currentValue === 'custom' || currentValue === 'mix_custom') ? 'block' : 'none' },\n onClick: () => handleFileUpload((b64) => {\n const imageKey = settingConfig.id.replace(/(Type|ColorTheme)$/, 'CustomImage');\n updateCache(imageKey, b64);\n app.ui?.settings?.setSettingValue(imageKey, b64);\n app.canvas?.setDirty(true, true);\n })\n });\n\n return el('div', { style: { display: 'flex', gap: '4px', alignItems: 'center', width: '100%' } }, [\n select,\n uploadBtn\n ]);\n }\n\n return select;\n}\n\n/**\n * Create a slider element\n */\nfunction createSlider(settingConfig: SettingConfig): HTMLDivElement {\n const currentVal = getSetting(settingConfig.id) || settingConfig.min || 0;\n\n const valueLabel = el('span', {\n className: 'christmas-slider-value'\n }, [String(currentVal)]);\n\n const slider = el('input', {\n type: 'range',\n className: 'christmas-slider',\n min: String(settingConfig.min || 0),\n max: String(settingConfig.max || 100),\n step: String(settingConfig.step || 1),\n value: String(currentVal)\n });\n\n slider.addEventListener('input', () => {\n const value = parseFloat(slider.value);\n valueLabel.textContent = String(value);\n\n updateCache(settingConfig.id, value);\n app.ui?.settings?.setSettingValue(settingConfig.id, value);\n app.canvas?.setDirty(true, true);\n });\n\n return el('div', { className: 'christmas-slider-container' }, [\n slider,\n valueLabel\n ]);\n}\n\n/**\n * Create a setting row\n */\nfunction createSettingRow(settingConfig: SettingConfig): HTMLDivElement {\n // Sliders get special stacked layout\n if (settingConfig.type === 'slider') {\n const currentVal = getSetting(settingConfig.id) || settingConfig.min || 0;\n const valueLabel = el('span', { className: 'christmas-slider-value' }, [String(currentVal)]);\n\n const slider = el('input', {\n type: 'range',\n className: 'christmas-slider',\n min: String(settingConfig.min || 0),\n max: String(settingConfig.max || 100),\n step: String(settingConfig.step || 1),\n value: String(currentVal),\n onInput: (e: Event) => {\n const val = parseFloat((e.target as HTMLInputElement).value);\n valueLabel.textContent = String(val);\n updateCache(settingConfig.id, val);\n app.ui?.settings?.setSettingValue(settingConfig.id, val);\n app.canvas?.setDirty(true, true);\n }\n });\n\n return el('div', { className: 'christmas-setting-row' }, [\n el('div', { className: 'christmas-slider-row' }, [\n el('div', { className: 'christmas-slider-header' }, [\n el('span', { className: 'christmas-setting-label' }, [settingConfig.label]),\n valueLabel\n ]),\n el('div', { className: 'christmas-slider-container' }, [slider])\n ])\n ]);\n }\n\n // Standard layout for toggles and selects\n let control: HTMLElement;\n switch (settingConfig.type) {\n case 'toggle':\n control = createToggle(settingConfig);\n break;\n case 'select':\n control = createSelect(settingConfig);\n break;\n default:\n control = el('span', {}, ['Unknown type']);\n }\n\n return el('div', { className: 'christmas-setting-row' }, [\n el('span', { className: 'christmas-setting-label' }, [settingConfig.label]),\n control\n ]);\n}\n\n/**\n * Create a section with its settings\n */\nfunction createSection(sectionKey: string, sectionConfig: SectionConfig): HTMLDivElement {\n const title = el('div', { className: 'christmas-sidebar-section-title' }, [sectionConfig.title]);\n const settings = sectionConfig.settings.map(s => createSettingRow(s));\n\n return el('div', { className: 'christmas-sidebar-section' }, [\n title,\n ...settings\n ]);\n}\n\n/**\n * Render the sidebar content\n */\nfunction renderSidebar(elRoot: HTMLElement): void {\n // Clear any existing content to prevent duplicates on re-render\n elRoot.innerHTML = '';\n\n // Add styles inside the main container (not as sibling)\n const styleEl = document.createElement('style');\n styleEl.textContent = SIDEBAR_STYLES;\n\n const sections = Object.entries(SETTINGS_CONFIG).map(([key, config]) =>\n createSection(key, config)\n );\n\n const footer = el('div', { className: 'christmas-footer' }, [\n el('a', {\n href: \"https://github.com/AEmotionStudio/ComfyUI-ChristmasTheme\",\n target: \"_blank\"\n }, [\"🎁 GitHub\"])\n ]);\n\n const container = el('div', { className: 'christmas-sidebar' }, [\n styleEl, // Styles inside container\n el('div', { className: 'christmas-sidebar-header' }, [\n el('h2', {}, [\"🎄 Christmas Theme\"])\n ]),\n ...sections,\n footer\n ]);\n\n elRoot.appendChild(container);\n}\n\n// ============================================================================\n// Extension Registration\n// ============================================================================\n\napp.registerExtension({\n name: \"Christmas.Theme.Sidebar\",\n async setup() {\n // Wait a bit for the extension manager to be ready\n setTimeout(() => {\n if (app.extensionManager && app.extensionManager.registerSidebarTab) {\n app.extensionManager.registerSidebarTab({\n id: \"christmas-theme\",\n icon: \"pi pi-gift\",\n title: \"Christmas\",\n tooltip: \"Christmas Theme Settings\",\n type: \"custom\",\n render: renderSidebar\n });\n console.log(\"🎄 Christmas Theme sidebar tab registered\");\n } else {\n console.warn(\"⚠️ Extension manager not available for sidebar registration\");\n }\n }, 100);\n }\n});\n"],"names":["_a"],"mappings":"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"} \ No newline at end of file diff --git a/js/link_animations.js.map b/js/link_animations.js.map deleted file mode 100644 index c92e8d2..0000000 --- a/js/link_animations.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"link_animations.js","sources":["../src/link-animations.ts"],"sourcesContent":["// @ts-ignore\nimport { app } from \"../../scripts/app.js\";\n// @ts-ignore\nimport { api } from \"../../scripts/api.js\";\nimport { getSetting, updateCache, initSettingsCache, loadSettingFromStorage, COLOR_SCHEMES } from \"./settings-cache\";\nimport { isPageVisible } from \"./background-themes\";\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\ninterface PerformanceSettings {\n lightSpacing: number;\n skipCaps: boolean;\n reducedGlow: boolean;\n}\n\ninterface PerformanceMonitorType {\n frameTimeHistory: Float32Array;\n currentIndex: number;\n sum: number;\n warningThreshold: number;\n criticalThreshold: number;\n _lastMode: 'normal' | 'warning' | 'critical';\n adaptiveSettings: Record<'normal' | 'warning' | 'critical', PerformanceSettings>;\n addFrameTime(time: number): 'normal' | 'warning' | 'critical';\n getSettings(): PerformanceSettings;\n}\n\ninterface ArrayPoolType {\n pool: Float32Array[];\n init(): void;\n get(): Float32Array;\n release(array: Float32Array): void;\n}\n\ninterface StateType {\n isRunning: boolean;\n phase: number;\n lastFrame: number;\n animationFrame: number | null;\n performanceMode: 'normal' | 'warning' | 'critical';\n isRendering: boolean;\n linkDataCache: { start: Float32Array; end: Float32Array; color: string | null }[];\n linkDataIndex: number;\n}\n\ninterface LinkData {\n start: Float32Array;\n end: Float32Array;\n color: string | null;\n}\n\ninterface LinkRenderer {\n getLength(start: Float32Array, end: Float32Array): number;\n getPoint(start: Float32Array, end: Float32Array, t: number, out: Float32Array): void;\n draw(ctx: CanvasRenderingContext2D, start: Float32Array, end: Float32Array, color: string, thickness: number): void;\n}\n\n// Extend Window interface for snowflake state\ndeclare global {\n interface Window {\n snowflakeState?: {\n flakes: any[];\n currentBatch: number;\n isInitializing: boolean;\n renderSnowflakes: () => void;\n addBatch: () => void;\n };\n }\n\n class LGraphCanvas {\n static link_type_colors: Record;\n\n graph: {\n links: Record;\n _nodes_by_id: Record;\n };\n default_connection_color: string;\n\n drawConnections(ctx: CanvasRenderingContext2D): void;\n renderChristmasLights(ctx: CanvasRenderingContext2D, items: LinkData[], phase: number): void;\n }\n}\n\n// ============================================================================\n// Core Implementation\n// ============================================================================\n\napp.registerExtension({\n name: \"Christmas.Theme.LightSwitch\",\n async setup() {\n // Initialize settings cache first\n initSettingsCache();\n\n // 🔮 Basic Constants\n const PHI = 1.618033988749895;\n\n // Enhanced Performance Monitoring with adaptive response\n const PerformanceMonitor: PerformanceMonitorType = {\n frameTimeHistory: new Float32Array(60),\n currentIndex: 0,\n sum: 0,\n warningThreshold: 8, // reduced threshold\n criticalThreshold: 16,\n _lastMode: 'normal',\n adaptiveSettings: {\n normal: { lightSpacing: 15, skipCaps: false, reducedGlow: false },\n warning: { lightSpacing: 25, skipCaps: true, reducedGlow: false },\n critical: { lightSpacing: 40, skipCaps: true, reducedGlow: true }\n },\n\n addFrameTime(time: number) {\n this.sum -= this.frameTimeHistory[this.currentIndex];\n this.frameTimeHistory[this.currentIndex] = time;\n this.sum += time;\n this.currentIndex = (this.currentIndex + 1) % 60;\n\n const avg = this.sum / 60;\n let mode: 'normal' | 'warning' | 'critical' = 'normal';\n\n if (avg > this.criticalThreshold) mode = 'critical';\n else if (avg > this.warningThreshold) mode = 'warning';\n\n if (mode !== this._lastMode) {\n console.log(`🎄 Christmas Lights: Switching to ${mode} mode (avg frame time: ${avg.toFixed(2)}ms)`);\n this._lastMode = mode;\n }\n return mode;\n },\n\n getSettings() {\n return this.adaptiveSettings[this._lastMode];\n }\n };\n\n // Preallocated memory pools to reduce GC\n const ArrayPool: ArrayPoolType = {\n pool: [],\n init() { for (let i = 0; i < 1000; i++) this.pool.push(new Float32Array(2)); },\n get() { return this.pool.pop() || new Float32Array(2); },\n release(arr) { if (this.pool.length < 2000) this.pool.push(arr); }\n };\n ArrayPool.init();\n\n // Shared State\n const State: StateType = {\n isRunning: true,\n phase: 0,\n lastFrame: 0,\n animationFrame: null,\n performanceMode: 'normal',\n isRendering: false,\n linkDataCache: new Array(1000).fill(null).map(() => ({\n start: new Float32Array(2),\n end: new Float32Array(2),\n color: null\n })),\n linkDataIndex: 0\n };\n\n // Optimized Rendering Helpers\n const LinkRenderer: LinkRenderer = {\n getLength(start, end) {\n const dx = end[0] - start[0];\n const dy = end[1] - start[1];\n return Math.sqrt(dx * dx + dy * dy);\n },\n getPoint(start, end, t, out) {\n out[0] = start[0] + (end[0] - start[0]) * t;\n out[1] = start[1] + (end[1] - start[1]) * t;\n },\n draw(ctx, start, end, color, thickness) {\n ctx.strokeStyle = color;\n ctx.lineWidth = thickness;\n ctx.beginPath();\n ctx.moveTo(start[0], start[1]);\n ctx.lineTo(end[0], end[1]);\n ctx.stroke();\n }\n };\n\n // Pre-calculated sin table for fast lookup\n const SIN_TABLE_SIZE = 1024;\n const SIN_TABLE = new Float32Array(SIN_TABLE_SIZE);\n for (let i = 0; i < SIN_TABLE_SIZE; i++) {\n SIN_TABLE[i] = Math.sin((i / SIN_TABLE_SIZE) * Math.PI * 2);\n }\n function fastSin(angle: number) {\n const index = Math.floor((angle / (Math.PI * 2) * SIN_TABLE_SIZE)) % SIN_TABLE_SIZE;\n return SIN_TABLE[index >= 0 ? index : index + SIN_TABLE_SIZE];\n }\n\n // Timing Manager\n const TimingManager = {\n lastTime: 0,\n update() {\n const now = performance.now();\n if (!this.lastTime) this.lastTime = now;\n const delta = (now - this.lastTime) / 1000;\n this.lastTime = now;\n return Math.min(delta, 0.05); // Cap delta to prevent huge jumps\n }\n };\n\n // Animation State Manager\n const AnimationState = {\n phase: 0,\n update(delta: number) {\n // Use setting speed\n const speed = (getSetting(\"ChristmasTheme.ChristmasEffects.AnimationSpeed\") as number) || 1.0;\n this.phase += delta * speed;\n return this.phase;\n }\n };\n\n // 🎨 Main Installation Trigger\n let retryCount = 0;\n const installChristmasLights = () => {\n // @ts-ignore\n if (!app.canvas || !app.graph) {\n if (retryCount < 20) {\n retryCount++;\n setTimeout(installChristmasLights, 200);\n }\n return;\n }\n\n const LGraphCanvas = app.canvas.constructor;\n const origDrawConnections = LGraphCanvas.prototype.drawConnections;\n\n console.log(\"🎄 Installing Christmas Lights (Optimized)...\");\n\n // Attach our renderer to the canvas class for easy access\n LGraphCanvas.prototype.renderChristmasLights = function (ctx: CanvasRenderingContext2D, items: LinkData[], phase: number) {\n const animStyle = getSetting(\"ChristmasTheme.ChristmasEffects.LightSwitch\");\n const currentSchemeName = getSetting(\"ChristmasTheme.ChristmasEffects.ColorScheme\") as string;\n // If \"match\", use the matched palette (Logic handled in cache or here? Assuming cache returns 'match' string, we need to resolve it)\n // Actually settings-cache helpers usually resolve it. Let's rely on COLOR_SCHEMES lookup.\n\n // Fix for 'match' scheme: if it's 'match', we need to check background theme but for links we usually just default to traditional or let user pick. \n // Wait, the cache update logic in background-themes handles sync. Here we just read.\n // If it is literally \"match\", we map to traditional or a default for now.\n const christmasColors = COLOR_SCHEMES[currentSchemeName] || COLOR_SCHEMES.traditional;\n\n const bulbShape = getSetting(\"ChristmasTheme.ChristmasEffects.BulbShape\");\n\n // Cache settings for this frame\n const settings = PerformanceMonitor.getSettings();\n const baseSpacing = settings.lightSpacing;\n const skipCaps = settings.skipCaps;\n const reducedGlow = settings.reducedGlow;\n\n const glowIntensity = getSetting(\"ChristmasTheme.ChristmasEffects.GlowIntensity\") as number;\n const steadyTwinkle = getSetting(\"ChristmasTheme.ChristmasEffects.SteadyStrands\");\n const sparkleMode = getSetting(\"ChristmasTheme.ChristmasEffects.SparkleMode\");\n const colorCount = christmasColors.length;\n\n // Get link style from settings (e.g. Spline, Linear, Hidden)\n // Note: The setting ID might need verification, typically \"ChristmasTheme.Link Style\"\n // but checking previous files or defaults. Assuming \"ChristmasTheme.LinkType\" or similar if not found.\n // Based on previous code in user context, it used `linkStyle` variable which implies it was defined.\n // We'll define it here.\n const linkStyle = getSetting(\"ChristmasTheme.LinkRenderMode\") || \"spline\"; // Fallback to spline if not set\n\n\n const renderer = LinkRenderer;\n const tempPoint = new Float32Array(2);\n\n // Common styles\n const Thickness = 2; // Link wire thickness used for bulbs too\n const Direction = -1; // Animation flow direction\n\n // Special Mode: Frost Trail\n if (animStyle === 4) { // Frost Trail\n for (let itemIdx = 0; itemIdx < items.length; itemIdx++) {\n const { start, end, color } = items[itemIdx];\n // Draw frosty core\n ctx.shadowBlur = 4;\n ctx.shadowColor = \"#aaddff\";\n ctx.strokeStyle = \"#ffffff\";\n ctx.lineWidth = 2.5;\n ctx.beginPath();\n ctx.moveTo(start[0], start[1]);\n ctx.lineTo(end[0], end[1]);\n ctx.stroke();\n\n // Flowing ice particles\n const length = renderer.getLength(start, end);\n const particleCount = Math.floor(length / 20);\n const time = performance.now() / 1000;\n\n ctx.shadowBlur = 8;\n ctx.fillStyle = \"#ffffff\";\n\n for (let i = 0; i < particleCount; i++) {\n const speed = 0.5 + (i % 3) * 0.2;\n let t = ((time * speed) + (i / particleCount)) % 1;\n\n renderer.getPoint(start, end, t, tempPoint);\n const x = tempPoint[0];\n const y = tempPoint[1];\n\n const size = 1.5 + Math.sin(time * 10 + i) * 1;\n ctx.globalAlpha = 0.6 + Math.sin(time * 5 + i) * 0.4;\n ctx.beginPath();\n ctx.arc(x, y, size, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n return;\n }\n\n // Special Mode: Candy Cane\n if (animStyle === 2) { // Candy Cane\n ctx.lineCap = \"round\";\n for (let itemIdx = 0; itemIdx < items.length; itemIdx++) {\n const { start, end } = items[itemIdx];\n\n // White base\n ctx.strokeStyle = \"#ffffff\";\n ctx.lineWidth = 5;\n ctx.beginPath();\n ctx.moveTo(start[0], start[1]);\n ctx.lineTo(end[0], end[1]);\n ctx.stroke();\n\n // Red stripes\n ctx.strokeStyle = \"#ff0000\";\n ctx.lineWidth = 5;\n ctx.setLineDash([15, 15]);\n ctx.lineDashOffset = -phase * 30; // Animate stripes\n ctx.beginPath();\n ctx.moveTo(start[0], start[1]);\n ctx.lineTo(end[0], end[1]);\n ctx.stroke();\n\n // Reset\n ctx.setLineDash([]);\n }\n return;\n }\n\n // Special Mode: Aurora Flow\n if (animStyle === 5) {\n ctx.lineCap = \"round\";\n const auroraColors = ['#00ffaa', '#00aaff', '#aa00ff', '#ff00aa'];\n\n for (let itemIdx = 0; itemIdx < items.length; itemIdx++) {\n const { start, end } = items[itemIdx];\n const length = renderer.getLength(start, end);\n\n // Multi-layered flow\n for (let layer = 0; layer < 3; layer++) {\n const offset = layer * 2;\n const t = (phase * 0.2 + (layer * 0.1)) % 1;\n\n // Draw segment\n // Actually just drawing the full line with gradient is better\n const grad = ctx.createLinearGradient(start[0], start[1], end[0], end[1]);\n for (let c = 0; c < auroraColors.length; c++) {\n const colorPos = (c / (auroraColors.length - 1) + phase * 0.2) % 1;\n grad.addColorStop(colorPos, auroraColors[c]);\n }\n // Need at least 2 stops for valid gradient if we cycle? \n // Simplified approach: moving particles of aurora color\n\n const particles = Math.floor(length / 10);\n for (let p = 0; p < particles; p++) {\n const t = (p / particles + phase * 0.1) % 1;\n renderer.getPoint(start, end, t, tempPoint);\n const x = tempPoint[0];\n const y = tempPoint[1] + Math.sin(t * Math.PI * 4 + phase) * 2;\n\n // Color cycling through aurora palette\n const colorT = (t - phase * 0.5 + 1) % 1;\n const colorIndex = Math.floor(colorT * auroraColors.length);\n // const nextColorIndex = (colorIndex + 1) % auroraColors.length; // Unused\n // const colorBlend = (colorT * auroraColors.length) % 1; // Unused\n\n // Blend between colors\n const auroraColor = auroraColors[colorIndex];\n\n // Pulsing intensity\n const pulse = 0.5 + fastSin(phase * 3 + t * Math.PI * 2) * 0.5;\n\n ctx.shadowBlur = 20 * pulse;\n ctx.shadowColor = auroraColor;\n ctx.fillStyle = auroraColor;\n ctx.globalAlpha = pulse * 0.7;\n\n ctx.beginPath();\n ctx.arc(x, y, Thickness * (1 + pulse * 0.5), 0, Math.PI * 2);\n ctx.fill();\n }\n }\n ctx.globalAlpha = 1;\n ctx.shadowBlur = 0;\n }\n return; // Skip normal bulb rendering for special modes\n }\n\n // Icicle bulb helper function\n const drawIcicleBulb = (ctx: CanvasRenderingContext2D, x: number, y: number, size: number) => {\n const bulbWidth = size * 1.2;\n const bulbHeight = size * 3;\n ctx.beginPath();\n // Start at top center\n ctx.moveTo(x, y - size * 0.5);\n // Curve to left side\n ctx.bezierCurveTo(\n x - bulbWidth, y,\n x - bulbWidth * 0.6, y + bulbHeight * 0.5,\n x, y + bulbHeight // Pointed tip at bottom\n );\n // Curve back to start\n ctx.bezierCurveTo(\n x + bulbWidth * 0.6, y + bulbHeight * 0.5,\n x + bulbWidth, y,\n x, y - size * 0.5\n );\n ctx.closePath();\n };\n\n for (let itemIdx = 0; itemIdx < items.length; itemIdx++) {\n const { start, end, color } = items[itemIdx];\n\n // Draw base wire\n if (linkStyle !== 'hidden') {\n ctx.globalAlpha = 0.8;\n ctx.shadowBlur = 0;\n renderer.draw(ctx, start, end, color || \"#888\", Thickness);\n ctx.globalAlpha = 1;\n }\n\n if (linkStyle === 'hidden' && !getSetting(\"ChristmasTheme.ChristmasEffects.LightSwitch\")) {\n continue;\n }\n\n const totalLength = renderer.getLength(start, end);\n const numLights = Math.floor(totalLength / baseSpacing);\n if (numLights < 1) continue;\n\n const effectiveGlow = reducedGlow ? glowIntensity * 0.5 : glowIntensity;\n\n // Draw lights in a single batch\n for (let i = 0; i <= numLights; i++) {\n const t = i / numLights;\n renderer.getPoint(start, end, t, tempPoint);\n\n const wobble = fastSin(t * Math.PI * 4) * 5;\n const x = tempPoint[0];\n const y = tempPoint[1] + wobble;\n\n // Color cycling\n const colorIndex = ((i - Math.floor(phase * 2 * Direction)) % colorCount + colorCount) % colorCount;\n const lightColor = christmasColors[colorIndex];\n\n // Twinkle calculation\n let flicker;\n if (steadyTwinkle) {\n flicker = 1;\n } else if (sparkleMode) {\n flicker = 0.7 + fastSin(-phase * 8 + i * 5) * 0.3 * Math.random();\n } else {\n flicker = 0.85 + fastSin(-phase * 5 + i * 3) * 0.15;\n }\n\n // Light bulb\n ctx.shadowBlur = effectiveGlow * 1.5 * flicker;\n ctx.fillStyle = lightColor;\n ctx.shadowColor = lightColor;\n ctx.globalAlpha = flicker;\n\n if (bulbShape === \"icicle\") {\n // Icicle/pointed bulb shape\n drawIcicleBulb(ctx, x, y, Thickness);\n ctx.fill();\n } else {\n // Classic round bulb\n ctx.beginPath();\n ctx.arc(x, y, Thickness * 1.5, 0, Math.PI * 2);\n ctx.fill();\n }\n\n // Light cap (skip in low performance mode)\n if (!skipCaps) {\n ctx.beginPath();\n ctx.shadowBlur = 0;\n const capY = bulbShape === \"icicle\" ? y - Thickness * 0.8 : y - Thickness;\n ctx.arc(x, capY, Thickness * 0.5, 0, Math.PI * 2);\n ctx.fillStyle = '#c0c0c0';\n ctx.globalAlpha = 1;\n ctx.fill();\n }\n }\n ctx.globalAlpha = 1;\n }\n };\n\n // Override drawConnections\n LGraphCanvas.prototype.drawConnections = function (ctx: CanvasRenderingContext2D) {\n try {\n // Skip if page not visible\n if (!isPageVisible) {\n return;\n }\n\n const startTime = performance.now();\n const animStyle = getSetting(\"ChristmasTheme.ChristmasEffects.LightSwitch\");\n\n if (animStyle === 0) {\n origDrawConnections.call(this, ctx);\n return;\n }\n\n const delta = TimingManager.update();\n const phase = AnimationState.update(delta);\n\n ctx.save();\n\n // Reset link data index for reuse\n State.linkDataIndex = 0;\n\n // Collect visible links\n for (const linkId in this.graph.links) {\n const linkData = this.graph.links[linkId];\n if (!linkData) continue;\n\n const originNode = this.graph._nodes_by_id[linkData.origin_id];\n const targetNode = this.graph._nodes_by_id[linkData.target_id];\n\n if (!originNode || !targetNode || originNode.flags.collapsed || targetNode.flags.collapsed) continue;\n\n // Reuse or create link data object\n let data = State.linkDataCache[State.linkDataIndex];\n if (!data) {\n data = {\n start: ArrayPool.get(),\n end: ArrayPool.get(),\n color: null\n };\n State.linkDataCache[State.linkDataIndex] = data;\n }\n\n originNode.getConnectionPos(false, linkData.origin_slot, data.start);\n targetNode.getConnectionPos(true, linkData.target_slot, data.end);\n data.color = linkData.type ?\n LGraphCanvas.link_type_colors[linkData.type] :\n this.default_connection_color;\n\n State.linkDataIndex++;\n }\n\n // Render all collected links\n if (State.linkDataIndex > 0) {\n const linksToRender = State.linkDataCache.slice(0, State.linkDataIndex);\n this.renderChristmasLights(ctx, linksToRender, phase);\n }\n\n ctx.restore();\n\n // Monitor performance\n const frameTime = performance.now() - startTime;\n State.performanceMode = PerformanceMonitor.addFrameTime(frameTime);\n\n } catch (error) {\n console.error(\"Error in drawConnections:\", error);\n origDrawConnections.call(this, ctx);\n }\n };\n\n // INDEPENDENT ANIMATION LOOP: Ensure we animate even if background is disabled\n // This fixes the startup issue where animations wait for background loop\n let linkAnimLoopId: number | null = null;\n function startLinkLoop() {\n if (linkAnimLoopId) return;\n const loop = () => {\n // Check if lights are enabled (style > 0)\n const lightsOn = getSetting(\"ChristmasTheme.ChristmasEffects.LightSwitch\") !== 0; // 0 is default/off\n\n if (isPageVisible && lightsOn && app.canvas) {\n // Force redraw to keep animations playing\n app.canvas.setDirty(true, true);\n }\n linkAnimLoopId = requestAnimationFrame(loop);\n };\n linkAnimLoopId = requestAnimationFrame(loop);\n }\n startLinkLoop();\n };\n\n // 🔄 Workflow State Management\n const WorkflowState = {\n isRendering: false,\n isExecuting: false,\n jobCount: 0,\n executionStartTime: 0,\n\n checkState() {\n // If ComfyUI app state says executing, pause effects\n // @ts-ignore\n if (app.ui && app.ui.status && app.ui.status.exec_info && app.ui.status.exec_info.queue_remaining > 0) {\n this.isExecuting = true;\n // @ts-ignore\n } else if (app.graph && app.graph._nodes_executing && Object.keys(app.graph._nodes_executing).length > 0) {\n this.isExecuting = true;\n } else {\n this.isExecuting = false;\n }\n return this.isExecuting;\n }\n };\n\n // Hook into graph execution\n api.addEventListener(\"execution_start\", () => {\n if (getSetting(\"ChristmasTheme.PauseDuringRender\")) {\n State.isRendering = true;\n }\n });\n\n api.addEventListener(\"execution_end\", () => {\n State.isRendering = false;\n // Force redraw to resume animations immediately\n if (app.canvas) {\n app.canvas.setDirty(true, true);\n }\n });\n\n installChristmasLights();\n }\n});\n"],"names":["t","ctx"],"mappings":"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"} \ No newline at end of file diff --git a/js/settings-cache.js.map b/js/settings-cache.js.map deleted file mode 100644 index 521f9bb..0000000 --- a/js/settings-cache.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"settings-cache.js","sources":["../src/settings-cache.ts"],"sourcesContent":["/**\n * Settings Cache - Centralized settings cache to avoid deprecated defaultValue warnings\n */\n\n// @ts-ignore - ComfyUI external module (loaded at runtime)\nimport { app } from \"../../scripts/app.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Setting key type for type safety */\ntype SettingKey = keyof typeof SETTING_DEFAULTS;\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Default values for all settings */\nconst SETTING_DEFAULTS = {\n // Christmas Effects\n \"ChristmasTheme.ChristmasEffects.LightSwitch\": 1,\n \"ChristmasTheme.ChristmasEffects.ColorScheme\": \"traditional\",\n \"ChristmasTheme.ChristmasEffects.Twinkle\": \"gentle\",\n \"ChristmasTheme.ChristmasEffects.Thickness\": 3,\n \"ChristmasTheme.ChristmasEffects.GlowIntensity\": 20,\n \"ChristmasTheme.ChristmasEffects.Direction\": 1,\n \"ChristmasTheme.ChristmasEffects.BulbShape\": \"classic\",\n \"ChristmasTheme.Link Style\": \"spline\",\n \"ChristmasTheme.ChristmasEffects.CustomImage\": \"\", // Unused for now\n\n\n // Snowflake\n \"ChristmasTheme.Snowflake.Enabled\": 1,\n \"ChristmasTheme.Snowflake.ColorScheme\": \"white\",\n \"ChristmasTheme.Snowflake.Glow\": 10,\n \"ChristmasTheme.Snowflake.Type\": \"random\",\n \"ChristmasTheme.Snowflake.CustomImage\": \"\",\n\n\n\n // Background\n \"ChristmasTheme.Background.Enabled\": true,\n \"ChristmasTheme.Background.ColorTheme\": \"classic\",\n\n\n \"ChristmasTheme.Background.Stars\": true,\n \"ChristmasTheme.Background.PartyMode\": false,\n \"ChristmasTheme.Background.ShootingStars\": true,\n \"ChristmasTheme.Background.Fireworks\": false,\n \"ChristmasTheme.Background.MouseEffect\": \"none\",\n \"ChristmasTheme.Background.Countdown\": false,\n \"ChristmasTheme.Background.ShowFinaleButton\": false,\n\n // Performance\n \"ChristmasTheme.PauseDuringRender\": true\n};\n\n/** Cache object - initialized with defaults */\nconst settingsCache: Record = { ...SETTING_DEFAULTS };\n\n/** Track if cache has been initialized */\nlet cacheInitialized = false;\n\n// ============================================================================\n// Functions\n// ============================================================================\n\n/**\n * Initialize the settings cache from stored values\n * Call this once AFTER settings are registered\n */\nexport function initSettingsCache(): void {\n if (cacheInitialized) return;\n cacheInitialized = true;\n console.log(\"🎄 Settings cache initialized\");\n}\n\n/**\n * Load a setting value from ComfyUI after settings are registered\n * This should be called from each setting's onChange during registration\n * to capture the initial value ComfyUI loads from storage\n */\nexport function loadSettingFromStorage(key: string): void {\n try {\n const storedValue = app.ui.settings.getSettingValue(key);\n if (storedValue !== undefined && storedValue !== null) {\n settingsCache[key] = storedValue;\n }\n } catch {\n // Setting not available yet, keep default\n }\n}\n\n/**\n * Get a setting value from cache (no console warnings!)\n */\nexport function getSetting(key: K): typeof SETTING_DEFAULTS[K];\nexport function getSetting(key: string): unknown;\nexport function getSetting(key: string): unknown {\n return settingsCache[key] ?? (SETTING_DEFAULTS as Record)[key];\n}\n\n/**\n * Update cache when setting changes\n * Call this from onChange callbacks\n */\nexport function updateCache(key: string, value: unknown): void {\n settingsCache[key] = value;\n}\n\n/**\n * Get all cached settings (for debugging)\n */\nexport function getAllSettings(): Record {\n return { ...settingsCache };\n}\n\n/**\n * Get all defaults (for reference)\n */\nexport function getDefaults(): typeof SETTING_DEFAULTS {\n return { ...SETTING_DEFAULTS };\n}\n\n// ============================================================================\n// Color Scheme Definitions\n// ============================================================================\n\n/** Color scheme definitions (shared across modules) */\nexport const COLOR_SCHEMES: Record = {\n traditional: ['#ff0000', '#00ff00', '#ffff00', '#0000ff', '#ffffff'],\n warm: ['#ffd700', '#ffb347', '#ffa07a', '#ff8c69', '#fff0f5'],\n cool: ['#f0ffff', '#e0ffff', '#b0e2ff', '#87cefa', '#b0c4de'],\n multicolor: ['#ff1493', '#00ff7f', '#ff4500', '#4169e1', '#9370db'],\n pastel: ['#ffb6c1', '#98fb98', '#87ceeb', '#dda0dd', '#f0e68c'],\n newyear: ['#00ffff', '#ff1493', '#ffd700', '#4b0082', '#7fff00']\n};\n\n/** Background theme color definitions */\nexport interface BackgroundTheme {\n top: string;\n bottom: string;\n star: string;\n}\n\n/** Background theme definitions */\nexport const BACKGROUND_THEMES: Record = {\n classic: { top: '#05004c', bottom: '#110E19', star: '#ffffff' },\n christmas: { top: '#1a472a', bottom: '#0d2115', star: '#ffffff' },\n candycane: { top: '#8b0000', bottom: '#4a0404', star: '#ffffff' },\n frostnight: { top: '#0a2351', bottom: '#051428', star: '#e0ffff' },\n gingerbread: { top: '#8b4513', bottom: '#3c1f0d', star: '#ffd700' },\n darknight: { top: '#000000', bottom: '#000000', star: '#808080' }\n};\n"],"names":[],"mappings":";AAmBA,MAAM,mBAAmB;AAAA;AAAA,EAErB,+CAA+C;AAAA,EAC/C,+CAA+C;AAAA,EAC/C,2CAA2C;AAAA,EAC3C,6CAA6C;AAAA,EAC7C,iDAAiD;AAAA,EACjD,6CAA6C;AAAA,EAC7C,6CAA6C;AAAA,EAC7C,6BAA6B;AAAA,EAC7B,+CAA+C;AAAA;AAAA;AAAA,EAI/C,oCAAoC;AAAA,EACpC,wCAAwC;AAAA,EACxC,iCAAiC;AAAA,EACjC,iCAAiC;AAAA,EACjC,wCAAwC;AAAA;AAAA,EAKxC,qCAAqC;AAAA,EACrC,wCAAwC;AAAA,EAGxC,mCAAmC;AAAA,EACnC,uCAAuC;AAAA,EACvC,2CAA2C;AAAA,EAC3C,uCAAuC;AAAA,EACvC,yCAAyC;AAAA,EACzC,uCAAuC;AAAA,EACvC,8CAA8C;AAAA;AAAA,EAG9C,oCAAoC;AACxC;AAGA,MAAM,gBAAyC,EAAE,GAAG,iBAAA;AAGpD,IAAI,mBAAmB;AAUhB,SAAS,oBAA0B;AACtC,MAAI,iBAAkB;AACtB,qBAAmB;AACnB,UAAQ,IAAI,+BAA+B;AAC/C;AAOO,SAAS,uBAAuB,KAAmB;AACtD,MAAI;AACA,UAAM,cAAc,IAAI,GAAG,SAAS,gBAAgB,GAAG;AACvD,QAAI,gBAAgB,UAAa,gBAAgB,MAAM;AACnD,oBAAc,GAAG,IAAI;AAAA,IACzB;AAAA,EACJ,QAAQ;AAAA,EAER;AACJ;AAOO,SAAS,WAAW,KAAsB;AAC7C,SAAO,cAAc,GAAG,KAAM,iBAA6C,GAAG;AAClF;AAMO,SAAS,YAAY,KAAa,OAAsB;AAC3D,gBAAc,GAAG,IAAI;AACzB;AAKO,SAAS,iBAA0C;AACtD,SAAO,EAAE,GAAG,cAAA;AAChB;AAKO,SAAS,cAAuC;AACnD,SAAO,EAAE,GAAG,iBAAA;AAChB;AAOO,MAAM,gBAA0C;AAAA,EACnD,aAAa,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACnE,MAAM,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EAC5D,MAAM,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EAC5D,YAAY,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EAClE,QAAQ,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EAC9D,SAAS,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AACnE;AAUO,MAAM,oBAAqD;AAAA,EAC9D,SAAS,EAAE,KAAK,WAAW,QAAQ,WAAW,MAAM,UAAA;AAAA,EACpD,WAAW,EAAE,KAAK,WAAW,QAAQ,WAAW,MAAM,UAAA;AAAA,EACtD,WAAW,EAAE,KAAK,WAAW,QAAQ,WAAW,MAAM,UAAA;AAAA,EACtD,YAAY,EAAE,KAAK,WAAW,QAAQ,WAAW,MAAM,UAAA;AAAA,EACvD,aAAa,EAAE,KAAK,WAAW,QAAQ,WAAW,MAAM,UAAA;AAAA,EACxD,WAAW,EAAE,KAAK,WAAW,QAAQ,WAAW,MAAM,UAAA;AAC1D;"} \ No newline at end of file diff --git a/playwright-report/index.html b/playwright-report/index.html deleted file mode 100644 index 91bfbee..0000000 --- a/playwright-report/index.html +++ /dev/null @@ -1,85 +0,0 @@ - - - - - - - - - Playwright Test Report - - - - -
- - - \ No newline at end of file diff --git a/test-results/.last-run.json b/test-results/.last-run.json deleted file mode 100644 index cbcc1fb..0000000 --- a/test-results/.last-run.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "status": "passed", - "failedTests": [] -} \ No newline at end of file