UNPKG

kinetic-slider

Version:

A WebGL-powered kinetic slider component using PIXI.js

1 lines 43.1 kB
{"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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"}