{"version":3,"file":"useDisplacementEffects.cjs","sources":["../../../src/hooks/useDisplacementEffects.ts"],"sourcesContent":["import { useEffect, useRef, useCallback } from 'react';\nimport { Sprite, DisplacementFilter, Assets, Texture } from 'pixi.js';\nimport { gsap } from 'gsap';\nimport { AtlasManager } from '../managers/AtlasManager';\nimport { type UseDisplacementEffectsProps, type CursorDisplacementSizingMode } from '../types';\nimport RenderScheduler from '../managers/RenderScheduler';\nimport { UpdateType } from '../managers/UpdateTypes';\n\n// Development environment check\nconst isDevelopment = import.meta.env?.MODE === 'development';\n\n// Default filter scales\nconst DEFAULT_BG_FILTER_SCALE = 20;\nconst DEFAULT_CURSOR_FILTER_SCALE = 10;\n\n/**\n * Custom hook that manages displacement effects with consistent behavior\n * for both atlas textures and individual images.\n *\n * @param {UseDisplacementEffectsProps} props - Hook properties\n * @returns {Object} Functions to control displacement effects\n * @property {Function} showDisplacementEffects - Animates in displacement effects\n * @property {Function} hideDisplacementEffects - Animates out displacement effects\n * @property {number} DEFAULT_BG_FILTER_SCALE - Default background filter scale\n * @property {number} DEFAULT_CURSOR_FILTER_SCALE - Default cursor filter scale\n */\nexport const useDisplacementEffects = ({\n                                           sliderRef,\n                                           bgDispFilterRef,\n                                           cursorDispFilterRef,\n                                           backgroundDisplacementSpriteRef,\n                                           cursorDisplacementSpriteRef,\n                                           appRef,\n                                           backgroundDisplacementSpriteLocation,\n                                           cursorDisplacementSpriteLocation,\n                                           cursorImgEffect,\n                                           cursorScaleIntensity = 0.65,\n                                           cursorDisplacementSizing = 'natural',\n                                           cursorDisplacementWidth,\n                                           cursorDisplacementHeight,\n                                           resourceManager,\n                                           atlasManager,\n                                           effectsAtlas,\n                                           useEffectsAtlas\n                                       }: UseDisplacementEffectsProps) => {\n    /**\n     * Tracks the initialization state of displacement effects.\n     * @type {React.MutableRefObject<{isInitializing: boolean, isInitialized: boolean}>}\n     */\n    const initializationStateRef = useRef({\n        isInitializing: false,\n        isInitialized: false\n    });\n\n    /**\n     * Helper function to check if useEffectsAtlas is enabled (similar to useSlides)\n     */\n    const isUseEffectsAtlasEnabled = (): boolean => {\n        // Handle all possible representations of \"true\"\n        if (useEffectsAtlas === true) return true;\n        if (typeof useEffectsAtlas === 'string' && useEffectsAtlas === 'true') return true;\n\n        // Handle numeric representations (needs type checking)\n        if (typeof useEffectsAtlas === 'number' && useEffectsAtlas === 1) return true;\n        if (typeof useEffectsAtlas === 'string' && useEffectsAtlas === '1') return true;\n\n        // Default to false for all other cases\n        return false;\n    };\n\n    /**\n     * Validates and sanitizes dimensions for displacement textures.\n     * Handles negative or unusually large values, returning appropriate fallbacks.\n     *\n     * @param {number | undefined} width - Requested width or undefined\n     * @param {number | undefined} height - Requested height or undefined\n     * @param {number} textureWidth - Original texture width as fallback\n     * @param {number} textureHeight - Original texture height as fallback\n     * @returns {{width: number, height: number, isValid: boolean}} Validated dimensions and validity flag\n     */\n    const validateDimensions = useCallback((\n        width: number | undefined,\n        height: number | undefined,\n        textureWidth: number,\n        textureHeight: number\n    ): { width: number, height: number, isValid: boolean } => {\n        let result = {\n            width: width || textureWidth,\n            height: height || textureHeight,\n            isValid: true\n        };\n\n        // Check for negative or zero values\n        if ((width !== undefined && width <= 0) || (height !== undefined && height <= 0)) {\n            if (isDevelopment) {\n                console.warn(`Invalid dimensions detected: width=${width}, height=${height}. Using texture dimensions instead.`);\n            }\n            result = { width: textureWidth, height: textureHeight, isValid: false };\n        }\n\n        // Check for unusually large values (more than 10x the canvas)\n        const app = appRef.current;\n        if (app && (\n            (width && width > app.screen.width * 10) ||\n            (height && height > app.screen.height * 10)\n        )) {\n            if (isDevelopment) {\n                console.warn(`Unusually large dimensions detected: width=${width}, height=${height}. This may cause performance issues.`);\n            }\n            // Still valid but warned\n        }\n\n        return result;\n    }, [appRef]);\n\n    /**\n     * Loads a texture from either atlas or individual file with consistent handling.\n     * Attempts multiple loading strategies with fallbacks.\n     *\n     * @param {string} imagePath - Path to the image to load\n     * @returns {Promise<Texture>} The loaded texture\n     * @throws {Error} If texture loading fails\n     */\n    const loadTexture = useCallback(async (imagePath: string): Promise<Texture> => {\n        if (!imagePath || typeof imagePath !== 'string' || imagePath.trim() === '') {\n            if (isDevelopment) {\n                console.error('Invalid image path provided', { imagePath });\n            }\n            throw new Error('Invalid image path');\n        }\n\n        try {\n            let texture: Texture | null = null;\n            let loadingMethod = '';\n\n            // Try from cache first\n            if (Assets.cache.has(imagePath)) {\n                texture = Assets.cache.get(imagePath);\n                loadingMethod = 'cache';\n            }\n            // Then try from atlas if enabled\n            else if (atlasManager && effectsAtlas && useEffectsAtlas) {\n                const frameName = imagePath.split('/').pop() || '';\n                if (atlasManager.hasFrame(frameName)) {\n                    const atlasTexture = atlasManager.getFrameTexture(frameName, effectsAtlas);\n                    if (atlasTexture) {\n                        texture = atlasTexture;\n                        loadingMethod = 'atlas';\n                    }\n                }\n            }\n\n            // Fallback to direct loading if not found\n            if (!texture) {\n                try {\n                    texture = await Assets.load(imagePath);\n                    loadingMethod = 'direct-load';\n                } catch (loadError) {\n                    if (isDevelopment) {\n                        console.error(`Failed to load texture directly: ${imagePath}`, loadError);\n                    }\n\n                    // Try one last fallback with a stripped path\n                    const fallbackPath = imagePath.split('/').pop();\n                    if (fallbackPath && fallbackPath !== imagePath) {\n                        try {\n                            texture = await Assets.load(fallbackPath);\n                            loadingMethod = 'fallback-path';\n                        } catch (fallbackError) {\n                            throw loadError;\n                        }\n                    } else {\n                        throw loadError;\n                    }\n                }\n            }\n\n            if (!texture) {\n                throw new Error(`Failed to load texture: ${imagePath}`);\n            }\n\n            if (isDevelopment) {\n                console.log(`Loaded texture from ${loadingMethod}: ${imagePath} (${texture.width}x${texture.height})`);\n            }\n\n            return texture;\n        } catch (error) {\n            // Enhanced error with more context\n            const enhancedError = new Error(`Failed to load texture: ${imagePath}. ${error}`);\n            if (isDevelopment) {\n                console.error('Texture loading failed with detailed error:', enhancedError);\n                console.error('Atlas status:', {\n                    atlasManagerAvailable: !!atlasManager,\n                    effectsAtlasName: effectsAtlas,\n                    useEffectsAtlasEnabled: useEffectsAtlas\n                });\n            }\n            throw enhancedError;\n        }\n    }, [atlasManager, effectsAtlas, useEffectsAtlas]);\n\n    /**\n     * Sets up displacement effects with consistent sizing regardless of texture source.\n     * This multi-step process loads textures, creates sprites and filters, and configures\n     * them based on the chosen sizing mode.\n     *\n     * @returns {Promise<void>}\n     */\n    const setupDisplacementEffects = useCallback(async () => {\n        // Prevent multiple initializations\n        if (initializationStateRef.current.isInitializing || initializationStateRef.current.isInitialized) {\n            return;\n        }\n\n        // Mark as initializing\n        initializationStateRef.current.isInitializing = true;\n\n        try {\n            // Get stage reference\n            const stage = appRef.current?.stage;\n            if (!stage) {\n                throw new Error('Stage not available');\n            }\n\n            // Get canvas dimensions\n            const canvasWidth = appRef.current?.screen.width ?? 0;\n            const canvasHeight = appRef.current?.screen.height ?? 0;\n\n            if (canvasWidth === 0 || canvasHeight === 0) {\n                throw new Error('Invalid canvas dimensions');\n            }\n\n            // 1. Load background displacement sprite\n            const bgTexture = await loadTexture(backgroundDisplacementSpriteLocation);\n\n            // 2. Create background displacement sprite\n            const bgSprite = new Sprite(bgTexture);\n\n            // CRITICAL: Force sprite to cover the full canvas\n            const bgScaleX = canvasWidth / bgTexture.width;\n            const bgScaleY = canvasHeight / bgTexture.height;\n            bgSprite.scale.set(bgScaleX, bgScaleY);\n\n            // Center the sprite on the canvas\n            bgSprite.anchor.set(0.5);\n            bgSprite.position.set(canvasWidth / 2, canvasHeight / 2);\n\n            // Sprite should not be rendered directly\n            bgSprite.renderable = false;\n            bgSprite.visible = true;\n            bgSprite.alpha = 0; // Start invisible\n\n            // 3. Create background displacement filter\n            const bgFilter = new DisplacementFilter(bgSprite);\n            bgFilter.scale.set(0); // Start with zero effect\n            bgFilter.padding = 0;\n\n            // 4. Store references to sprite and filter\n            backgroundDisplacementSpriteRef.current = bgSprite;\n            bgDispFilterRef.current = bgFilter;\n\n            // 5. Add to stage\n            stage.addChild(bgSprite);\n\n            // IMPORTANT: Attach the background displacement filter to the stage\n            if (!stage.filters) {\n                stage.filters = [bgFilter];\n            } else if (!Array.isArray(stage.filters)) {\n                stage.filters = [stage.filters, bgFilter];\n            } else {\n                stage.filters = [...stage.filters, bgFilter];\n            }\n\n            if (isDevelopment) {\n                console.log(`[KineticSlider] Background displacement sprite created with scale: ${bgScaleX.toFixed(2)}x${bgScaleY.toFixed(2)}`);\n            }\n\n            // 6. Track resources\n            if (resourceManager) {\n                resourceManager.trackDisplayObject(bgSprite);\n                resourceManager.trackFilter(bgFilter);\n            }\n\n            // Only set up cursor displacement if enabled\n            if (cursorImgEffect) {\n                // 7. Load cursor displacement sprite\n                const cursorTexture = await loadTexture(cursorDisplacementSpriteLocation);\n\n                // 8. Create cursor displacement sprite\n                const cursorSprite = new Sprite(cursorTexture);\n\n                // 9. Set cursor sprite scale based on sizing mode\n                let cursorScaleX = 1;\n                let cursorScaleY = 1;\n\n                if (cursorDisplacementSizing) {\n                    // Validate dimensions if custom sizing is used\n                    const validatedDimensions = validateDimensions(\n                        cursorDisplacementWidth,\n                        cursorDisplacementHeight,\n                        cursorTexture.width,\n                        cursorTexture.height\n                    );\n\n                    if (cursorDisplacementSizing === 'fullscreen') {\n                        // Scale to viewport dimensions\n                        cursorScaleX = canvasWidth / cursorTexture.width;\n                        cursorScaleY = canvasHeight / cursorTexture.height;\n\n                        // Center the sprite on the canvas\n                        cursorSprite.anchor.set(0.5);\n                        cursorSprite.position.set(canvasWidth / 2, canvasHeight / 2);\n\n                        if (isDevelopment) {\n                            console.log(`[KineticSlider] Using fullscreen dimensions (${canvasWidth}x${canvasHeight})`);\n                        }\n                    } else if (validatedDimensions.width && validatedDimensions.height) {\n                        // Both dimensions specified\n                        cursorScaleX = validatedDimensions.width / cursorTexture.width;\n                        cursorScaleY = validatedDimensions.height / cursorTexture.height;\n\n                        // Center the sprite\n                        cursorSprite.anchor.set(0.5);\n                        cursorSprite.position.set(\n                            validatedDimensions.width / 2,\n                            validatedDimensions.height / 2\n                        );\n\n                        if (isDevelopment) {\n                            console.log(`[KineticSlider] Using custom dimensions (${validatedDimensions.width}x${validatedDimensions.height})`);\n                        }\n                    } else {\n                        // Fallback to natural size (should not reach here with validation)\n                        cursorScaleX = 1;\n                        cursorScaleY = 1;\n\n                        if (isDevelopment) {\n                            console.log('[KineticSlider] Falling back to natural dimensions');\n                        }\n                    }\n                } else {\n                    // Natural dimensions (just apply intensity)\n                    cursorScaleX = 1;\n                    cursorScaleY = 1;\n\n                    if (isDevelopment) {\n                        console.log(`[KineticSlider] Using natural dimensions (${cursorTexture.width}x${cursorTexture.height})`);\n                    }\n                }\n\n                // Apply scale intensity\n                cursorSprite.scale.set(\n                    cursorScaleX * cursorScaleIntensity,\n                    cursorScaleY * cursorScaleIntensity\n                );\n\n                // 10. Set sprite properties\n                cursorSprite.renderable = false;\n                cursorSprite.visible = true;\n                cursorSprite.alpha = 0; // Start invisible\n\n                // 11. Create cursor displacement filter\n                const cursorFilter = new DisplacementFilter(cursorSprite);\n                cursorFilter.scale.set(0); // Start with zero effect\n                cursorFilter.padding = 0;\n\n                // 12. Store references\n                cursorDisplacementSpriteRef.current = cursorSprite;\n                cursorDispFilterRef.current = cursorFilter;\n\n                // 13. Add to stage\n                stage.addChild(cursorSprite);\n\n                // IMPORTANT: Attach the cursor displacement filter to the stage\n                if (!stage.filters) {\n                    stage.filters = [cursorFilter];\n                } else if (!Array.isArray(stage.filters)) {\n                    stage.filters = [stage.filters, cursorFilter];\n                } else {\n                    stage.filters = [...stage.filters, cursorFilter];\n                }\n\n                if (isDevelopment) {\n                    console.log(`[KineticSlider] Cursor displacement sprite created with scale: ${cursorScaleX.toFixed(2)}x${cursorScaleY.toFixed(2)}`);\n                }\n\n                // 14. Track resources\n                if (resourceManager) {\n                    resourceManager.trackDisplayObject(cursorSprite);\n                    resourceManager.trackFilter(cursorFilter);\n                }\n            }\n\n            // Mark as initialized\n            initializationStateRef.current = {\n                isInitializing: false,\n                isInitialized: true\n            };\n\n            if (isDevelopment) {\n                console.log('[KineticSlider] Displacement effects initialized successfully');\n            }\n        } catch (error) {\n            // Reset initialization state on error\n            initializationStateRef.current = {\n                isInitializing: false,\n                isInitialized: false\n            };\n\n            if (isDevelopment) {\n                console.error('[KineticSlider] Error setting up displacement effects:', error);\n            }\n\n            throw error; // Re-throw to allow caller to handle\n        }\n    }, [\n        appRef,\n        backgroundDisplacementSpriteLocation,\n        cursorDisplacementSpriteLocation,\n        cursorImgEffect,\n        cursorScaleIntensity,\n        cursorDisplacementSizing,\n        cursorDisplacementWidth,\n        cursorDisplacementHeight,\n        resourceManager,\n        atlasManager,\n        effectsAtlas,\n        useEffectsAtlas,\n        validateDimensions,\n        loadTexture\n    ]);\n\n    /**\n     * Handles window resize events to keep displacement effects properly sized and positioned.\n     * Always updates background sprite, and updates cursor sprite if using fullscreen mode.\n     */\n    useEffect(() => {\n        if (typeof window === 'undefined') return;\n\n        /**\n         * Resize handler function to update sprite positions and scales.\n         */\n        const handleResize = () => {\n            const app = appRef.current;\n            if (!app) return;\n\n            const canvasWidth = app.screen.width;\n            const canvasHeight = app.screen.height;\n\n            // Update background sprite position and scale\n            const bgSprite = backgroundDisplacementSpriteRef.current;\n            if (bgSprite && bgSprite.texture) {\n                // Update position to new center\n                bgSprite.position.set(canvasWidth / 2, canvasHeight / 2);\n\n                // Always scale background to fill canvas\n                const bgScaleX = canvasWidth / bgSprite.texture.width;\n                const bgScaleY = canvasHeight / bgSprite.texture.height;\n                bgSprite.scale.set(bgScaleX, bgScaleY);\n\n                if (isDevelopment) {\n                    console.log(`[KineticSlider] Resized background displacement to match canvas: ${canvasWidth}x${canvasHeight}`);\n                }\n            }\n\n            // Update cursor sprite if using fullscreen mode\n            if (cursorImgEffect && cursorDisplacementSizing === 'fullscreen') {\n                const cursorSprite = cursorDisplacementSpriteRef.current;\n                if (cursorSprite && cursorSprite.texture) {\n                    // Update position to new center\n                    cursorSprite.position.set(canvasWidth / 2, canvasHeight / 2);\n\n                    // Update scale to maintain fullscreen coverage\n                    const scaleX = canvasWidth / cursorSprite.texture.width;\n                    const scaleY = canvasHeight / cursorSprite.texture.height;\n\n                    cursorSprite.scale.set(\n                        scaleX * cursorScaleIntensity,\n                        scaleY * cursorScaleIntensity\n                    );\n\n                    if (isDevelopment) {\n                        console.log(`[KineticSlider] Resized cursor displacement to match canvas: ${canvasWidth}x${canvasHeight}`);\n                    }\n                }\n            }\n        };\n\n        // Always listen for resize to update background sprite\n        window.addEventListener('resize', handleResize);\n\n        return () => {\n            window.removeEventListener('resize', handleResize);\n        };\n    }, [\n        appRef,\n        backgroundDisplacementSpriteRef,\n        cursorDisplacementSpriteRef,\n        cursorDisplacementSizing,\n        cursorImgEffect,\n        cursorScaleIntensity\n    ]);\n\n    /**\n     * Shows displacement effects by animating sprite alpha and filter scale.\n     * Refactored to support scheduled updates.\n     *\n     * @returns {gsap.core.Tween[]} Array of GSAP animations\n     */\n    const showDisplacementEffects = useCallback(() => {\n        if (!initializationStateRef.current.isInitialized) return [];\n\n        // Get the scheduler instance\n        const scheduler = RenderScheduler.getInstance();\n\n        // Create a function that performs the actual animation\n        const animate = () => {\n            const animations: gsap.core.Tween[] = [];\n\n            // Background effect\n            const bgSprite = backgroundDisplacementSpriteRef.current;\n            const bgFilter = bgDispFilterRef.current;\n\n            if (bgSprite && bgFilter) {\n                // Ensure sprite is properly set up\n                bgSprite.visible = true;\n                bgSprite.renderable = false; // Important: keep this false\n\n                // Apply immediate scale to ensure filter is visible right away\n                bgFilter.scale.x = DEFAULT_BG_FILTER_SCALE;\n                bgFilter.scale.y = DEFAULT_BG_FILTER_SCALE;\n\n                if (isDevelopment) {\n                    console.log(`[KineticSlider] Immediately set background filter scale to ${DEFAULT_BG_FILTER_SCALE}`);\n                }\n\n                // Animate sprite alpha\n                const bgAlphaAnim = gsap.to(bgSprite, {\n                    alpha: 1,\n                    duration: 0.5\n                });\n\n                // Animate filter scale (still needed for smooth transitions)\n                const bgFilterAnim = gsap.to(bgFilter.scale, {\n                    x: DEFAULT_BG_FILTER_SCALE,\n                    y: DEFAULT_BG_FILTER_SCALE,\n                    duration: 0.5\n                });\n\n                animations.push(bgAlphaAnim, bgFilterAnim);\n\n                if (isDevelopment) {\n                    console.log(`[KineticSlider] Showing background displacement effect (scale: ${DEFAULT_BG_FILTER_SCALE})`);\n                }\n            }\n\n            // Cursor effect if enabled\n            if (cursorImgEffect) {\n                const cursorSprite = cursorDisplacementSpriteRef.current;\n                const cursorFilter = cursorDispFilterRef.current;\n\n                if (cursorSprite && cursorFilter) {\n                    // Ensure sprite is properly set up\n                    cursorSprite.visible = true;\n                    cursorSprite.renderable = false; // Important: keep this false\n\n                    // Apply immediate scale to ensure filter is visible right away\n                    cursorFilter.scale.x = DEFAULT_CURSOR_FILTER_SCALE;\n                    cursorFilter.scale.y = DEFAULT_CURSOR_FILTER_SCALE;\n\n                    if (isDevelopment) {\n                        console.log(`[KineticSlider] Immediately set cursor filter scale to ${DEFAULT_CURSOR_FILTER_SCALE}`);\n                    }\n\n                    // Animate sprite alpha\n                    const cursorAlphaAnim = gsap.to(cursorSprite, {\n                        alpha: 1,\n                        duration: 0.5\n                    });\n\n                    // Animate filter scale (still needed for smooth transitions)\n                    const cursorFilterAnim = gsap.to(cursorFilter.scale, {\n                        x: DEFAULT_CURSOR_FILTER_SCALE,\n                        y: DEFAULT_CURSOR_FILTER_SCALE,\n                        duration: 0.5\n                    });\n\n                    animations.push(cursorAlphaAnim, cursorFilterAnim);\n\n                    if (isDevelopment) {\n                        console.log(`[KineticSlider] Showing cursor displacement effect (scale: ${DEFAULT_CURSOR_FILTER_SCALE})`);\n                    }\n                }\n            }\n\n            // Schedule an immediate render update to ensure changes are visible\n            scheduler.scheduleTypedUpdate(\n                'displacementEffects',\n                UpdateType.DISPLACEMENT_EFFECT,\n                () => {\n                    if (isDevelopment) {\n                        console.log('[KineticSlider] Immediate render update for displacement effects');\n                    }\n                },\n                'critical'\n            );\n\n            // Track animations\n            if (resourceManager && animations.length) {\n                resourceManager.trackAnimationBatch(animations);\n            }\n\n            return animations;\n        };\n\n        // We can either schedule the effect or run it immediately depending on the context\n        // If called directly from an event handler, it might already be part of a scheduled update\n        return animate();\n    }, [\n        backgroundDisplacementSpriteRef,\n        bgDispFilterRef,\n        cursorDisplacementSpriteRef,\n        cursorDispFilterRef,\n        cursorImgEffect,\n        resourceManager\n    ]);\n\n    /**\n     * Hides displacement effects by animating sprite alpha and filter scale to zero.\n     * Refactored to support scheduled updates.\n     *\n     * @returns {gsap.core.Tween[]} Array of GSAP animations\n     */\n    const hideDisplacementEffects = useCallback(() => {\n        if (!initializationStateRef.current.isInitialized) return [];\n\n        // Get the scheduler instance\n        const scheduler = RenderScheduler.getInstance();\n\n        // Create a function that performs the actual animation\n        const animate = () => {\n            const animations: gsap.core.Tween[] = [];\n\n            // Background effect\n            const bgSprite = backgroundDisplacementSpriteRef.current;\n            const bgFilter = bgDispFilterRef.current;\n\n            if (bgSprite && bgFilter) {\n                const bgAlphaAnim = gsap.to(bgSprite, {\n                    alpha: 0,\n                    duration: 0.5\n                });\n\n                const bgFilterAnim = gsap.to(bgFilter.scale, {\n                    x: 0,\n                    y: 0,\n                    duration: 0.5\n                });\n\n                animations.push(bgAlphaAnim, bgFilterAnim);\n\n                if (isDevelopment) {\n                    console.log('[KineticSlider] Hiding background displacement effect');\n                }\n            }\n\n            // Cursor effect if enabled\n            if (cursorImgEffect) {\n                const cursorSprite = cursorDisplacementSpriteRef.current;\n                const cursorFilter = cursorDispFilterRef.current;\n\n                if (cursorSprite && cursorFilter) {\n                    const cursorAlphaAnim = gsap.to(cursorSprite, {\n                        alpha: 0,\n                        duration: 0.5\n                    });\n\n                    const cursorFilterAnim = gsap.to(cursorFilter.scale, {\n                        x: 0,\n                        y: 0,\n                        duration: 0.5\n                    });\n\n                    animations.push(cursorAlphaAnim, cursorFilterAnim);\n\n                    if (isDevelopment) {\n                        console.log('[KineticSlider] Hiding cursor displacement effect');\n                    }\n                }\n            }\n\n            // Track animations\n            if (resourceManager && animations.length) {\n                resourceManager.trackAnimationBatch(animations);\n            }\n\n            return animations;\n        };\n\n        // We can either schedule the effect or run it immediately depending on the context\n        // If called directly from an event handler, it might already be part of a scheduled update\n        return animate();\n    }, [\n        backgroundDisplacementSpriteRef,\n        bgDispFilterRef,\n        cursorDisplacementSpriteRef,\n        cursorDispFilterRef,\n        cursorImgEffect,\n        resourceManager\n    ]);\n\n    /**\n     * Initializes the displacement effects when the app is ready.\n     * Handles errors and provides cleanup.\n     */\n    useEffect(() => {\n        if (typeof window === 'undefined') return;\n\n        // Check if app is ready\n        if (appRef.current?.stage) {\n            try {\n                setupDisplacementEffects().catch(error => {\n                    // Handle initialization errors\n                    if (isDevelopment) {\n                        console.error('[KineticSlider] Failed to set up displacement effects:', error);\n                    }\n                    // Reset initialization state to allow retry\n                    initializationStateRef.current = {\n                        isInitializing: false,\n                        isInitialized: false\n                    };\n                });\n            } catch (error) {\n                if (isDevelopment) {\n                    console.error('[KineticSlider] Exception during displacement effects setup:', error);\n                }\n            }\n        }\n\n        // Cleanup on unmount\n        return () => {\n            initializationStateRef.current = {\n                isInitializing: false,\n                isInitialized: false\n            };\n        };\n    }, [appRef.current?.stage, setupDisplacementEffects]);\n\n    // Return public methods and constants\n    return {\n        showDisplacementEffects,\n        hideDisplacementEffects,\n        DEFAULT_BG_FILTER_SCALE,\n        DEFAULT_CURSOR_FILTER_SCALE\n    };\n};"],"names":["useRef","useCallback","Assets","Sprite","DisplacementFilter","useEffect","RenderScheduler","gsap","UpdateType"],"mappings":"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"}