tactica 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +446 -0
- package/dist/index.d.ts +10803 -0
- package/dist/index.js +15820 -0
- package/dist/index.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/constants.ts","../src/core/engine/Engine.ts","../src/core/engine/Scene.ts","../src/core/engine/SceneManager.ts","../src/helpers.ts","../src/core/engine/Entity.ts","../src/core/engine/TimerManager.ts","../src/core/engine/TransitionManager.ts","../src/core/rendering/Camera.ts","../src/core/input/InputSystem.ts","../src/core/input/KeyboardManager.ts","../src/core/input/GamepadManager.ts","../src/core/input/InputActionSystem.ts","../src/core/audio/AudioManager.ts","../src/core/audio/MusicPlaylist.ts","../src/core/audio/SoundVariantPool.ts","../src/core/audio/AudioZoneManager.ts","../src/core/physics/PhysicsWorld.ts","../src/core/physics/CollisionSystem.ts","../src/core/animation/Tween.ts","../src/core/animation/TweenManager.ts","../src/core/animation/ParticleEmitter.ts","../src/core/animation/ParticleSystem.ts","../src/core/ui/Button.ts","../src/core/ui/Text.ts","../src/core/ui/Panel.ts","../src/core/ui/Slider.ts","../src/core/ui/Checkbox.ts","../src/core/ui/Toggle.ts","../src/core/ui/UIImage.ts","../src/core/ui/UIManager.ts","../src/core/storage/Store.ts","../src/core/storage/Computed.ts","../src/core/storage/StateManager.ts","../src/core/storage/Database.ts","../src/core/storage/Schema.ts","../src/core/storage/TabSyncManager.ts","../src/core/asset/AssetManager.ts","../src/core/platform/MobileManager.ts","../src/core/platform/AccessibilityManager.ts","../src/core/platform/PWAManager.ts","../src/core/network/NetworkManager.ts","../src/core/debug/PerformanceMonitor.ts","../src/core/debug/DebugTools.ts","../src/core/rendering/SpriteSheet.ts","../src/core/animation/AnimationPlayer.ts","../src/core/rendering/Renderer.ts","../src/core/rendering/Viewport.ts","../src/core/rendering/Tileset.ts","../src/core/rendering/TilemapLayer.ts","../src/core/rendering/Tilemap.ts","../src/core/rendering/LayerManager.ts","../src/core/rendering/TrailRenderer.ts","../src/core/rendering/ShapeRenderer.ts","../src/core/rendering/PostProcessManager.ts","../src/core/ui/ToastManager.ts","../src/core/ui/Modal.ts","../src/core/ui/ModalManager.ts","../src/core/debug/ScreenshotManager.ts","../src/core/debug/FrameBudget.ts","../src/core/ui/VirtualJoystick.ts","../src/core/ui/ActionButton.ts","../src/core/rendering/CameraEffects.ts","../src/core/ui/TextInput.ts","../src/core/ui/TooltipManager.ts","../src/core/debug/DebugOverlay.ts","../src/core/rendering/SpriteBatch.ts","../src/core/storage/LocalStorageBackend.ts","../src/core/storage/IndexedDBBackend.ts","../src/core/storage/MigrationRunner.ts","../src/core/gameplay/BuffSystem.ts","../src/core/gameplay/HealthSystem.ts","../src/core/gameplay/FloatingTextSystem.ts","../src/core/gameplay/CollectibleSystem.ts","../src/core/gameplay/SpawnerSystem.ts","../src/core/gameplay/EffectZoneSystem.ts","../src/core/gameplay/BackgroundSystem.ts","../src/core/gameplay/ExperienceSystem.ts","../src/core/gameplay/StatisticsSystem.ts","../src/core/gameplay/ObjectiveSystem.ts","../src/core/gameplay/StateMachine.ts","../src/core/gameplay/InventorySystem.ts","../src/core/gameplay/DialogueSystem.ts","../src/core/gameplay/QuestSystem.ts","../src/core/ui/RadialMenu.ts","../src/core/ui/Minimap.ts","../src/core/ui/NotificationManager.ts","../src/core/debug/EntityInspector.ts","../src/core/debug/CommandConsole.ts","../src/core/rendering/CullingSystem.ts","../src/core/rendering/LODSystem.ts","../src/core/gameplay/CrosshairSystem.ts","../src/core/gameplay/EntityRendererRegistry.ts","../src/factories.ts","../src/core/physics/Quadtree.ts","../src/core/physics/SpatialGrid.ts","../src/core/storage/TrackingContext.ts","../src/core/storage/Cache.ts","../src/core/storage/MetricsCollector.ts","../src/core/storage/StorageManager.ts","../src/core/asset/ObjectPool.ts","../src/core/asset/ResourceManager.ts","../src/core/components/ColliderComponent.ts","../src/core/components/TransformComponent.ts","../src/core/components/SpriteComponent.ts","../src/core/components/PhysicsComponent.ts","../src/core/components/ComponentFactory.ts","../src/core/ui/ProgressBar.ts","../src/schemas/PlayerState.ts","../src/schemas/WorldState.ts","../src/schemas/InventoryState.ts","../src/schemas/SettingsState.ts"],"sourcesContent":["/**\r\n * Immutable shared constants.\r\n */\r\nimport type { PlayerState, WorldState, InventoryState, SettingsState, LineStyle, FillStyle, EquipmentSlotType, ItemRarity } from './types.js'\r\n\r\n// ============================================================================\r\n// Storage Constants\r\n// ============================================================================\r\n\r\n/** Default DatabaseInterface name */\r\nexport const DEFAULT_DATABASE_NAME = 'tactica-game' as const\r\n\r\n/** Default DatabaseInterface version */\r\nexport const DEFAULT_DATABASE_VERSION = 1 as const\r\n\r\n/** StoreInterface names for game data */\r\nexport const STORE_NAMES = [\r\n\t'snapshots',\r\n\t'slots',\r\n] as const\r\n\r\n/** Snapshot StoreInterface name */\r\nexport const SNAPSHOT_STORE_NAME = 'snapshots' as const\r\n\r\n/** Slots StoreInterface name */\r\nexport const SLOTS_STORE_NAME = 'slots' as const\r\n\r\n/** Auto-save slot ID */\r\nexport const AUTOSAVE_SLOT_ID = '__autosave__' as const\r\n\r\n/** Default auto-save interval in ms */\r\nexport const DEFAULT_AUTO_SAVE_INTERVAL = 30000 as const\r\n\r\n/** Default StoreInterface history size */\r\nexport const DEFAULT_STORE_HISTORY_SIZE = 50 as const\r\n\r\n/** Default tab heartbeat interval in ms */\r\nexport const DEFAULT_TAB_HEARTBEAT_MS = 1000 as const\r\n\r\n/** Default leader timeout in ms */\r\nexport const DEFAULT_LEADER_TIMEOUT_MS = 3000 as const\r\n\r\n/** Cache strategies */\r\nexport const CACHE_STRATEGIES = [\r\n\t'memory-only',\r\n\t'storage-only',\r\n\t'memory-first',\r\n\t'storage-first',\r\n\t'write-through',\r\n\t'write-back',\r\n] as const\r\n\r\n// ============================================================================\r\n// EngineInterface Constants\r\n// ============================================================================\r\n\r\n/** Default target FPS */\r\nexport const DEFAULT_TARGET_FPS = 60 as const\r\n\r\n/** Default pixel ratio */\r\nexport const DEFAULT_PIXEL_RATIO = 1 as const\r\n\r\n/** Default background color */\r\nexport const DEFAULT_BACKGROUND_COLOR = '#000000' as const\r\n\r\n// ============================================================================\r\n// Input Constants\r\n// ============================================================================\r\n\r\n/** Default tap threshold in pixels */\r\nexport const DEFAULT_TAP_THRESHOLD = 10 as const\r\n\r\n/** Default double tap delay in ms */\r\nexport const DEFAULT_DOUBLE_TAP_DELAY = 300 as const\r\n\r\n/** Default press delay in ms */\r\nexport const DEFAULT_PRESS_DELAY = 500 as const\r\n\r\n/** Default swipe threshold in pixels */\r\nexport const DEFAULT_SWIPE_THRESHOLD = 50 as const\r\n\r\n/** Default swipe velocity threshold */\r\nexport const DEFAULT_SWIPE_VELOCITY = 0.3 as const\r\n\r\n/** Gesture types */\r\nexport const GESTURE_TYPES = ['tap', 'doubletap', 'press', 'pan', 'swipe', 'pinch', 'rotate'] as const\r\n\r\n/** Default keyboard repeat delay in ms */\r\nexport const DEFAULT_REPEAT_DELAY = 500 as const\r\n\r\n/** Default keyboard repeat rate in ms */\r\nexport const DEFAULT_REPEAT_RATE = 50 as const\r\n\r\n/** Default gamepad deadzone (0-1) */\r\nexport const DEFAULT_GAMEPAD_DEADZONE = 0.15 as const\r\n\r\n/** Default gamepad axis threshold for change events (0-1) */\r\nexport const DEFAULT_GAMEPAD_AXIS_THRESHOLD = 0.1 as const\r\n\r\n/** Standard gamepad ButtonInterface mapping (Xbox layout) */\r\nexport const STANDARD_BUTTON_MAPPING = {\r\n\t0: 'a',\r\n\t1: 'b',\r\n\t2: 'x',\r\n\t3: 'y',\r\n\t4: 'lb',\r\n\t5: 'rb',\r\n\t6: 'lt',\r\n\t7: 'rt',\r\n\t8: 'back',\r\n\t9: 'start',\r\n\t10: 'ls',\r\n\t11: 'rs',\r\n\t12: 'dpad-up',\r\n\t13: 'dpad-down',\r\n\t14: 'dpad-left',\r\n\t15: 'dpad-right',\r\n\t16: 'guide',\r\n} as const\r\n\r\n/** Standard gamepad axis mapping */\r\nexport const STANDARD_AXIS_MAPPING = {\r\n\t0: 'left-x',\r\n\t1: 'left-y',\r\n\t2: 'right-x',\r\n\t3: 'right-y',\r\n} as const\r\n\r\n/** All gamepad ButtonInterface names */\r\nexport const ALL_GAMEPAD_BUTTONS = [\r\n\t'a', 'b', 'x', 'y',\r\n\t'lb', 'rb', 'lt', 'rt',\r\n\t'back', 'start', 'guide',\r\n\t'ls', 'rs',\r\n\t'dpad-up', 'dpad-down', 'dpad-left', 'dpad-right',\r\n] as const\r\n\r\n/** All gamepad axis names */\r\nexport const ALL_GAMEPAD_AXES = ['left-x', 'left-y', 'right-x', 'right-y'] as const\r\n\r\n// ============================================================================\r\n// Rendering Constants\r\n// ============================================================================\r\n\r\n/** Default trail max points */\r\nexport const DEFAULT_TRAIL_MAX_POINTS = 50 as const\r\n\r\n/** Default trail start width */\r\nexport const DEFAULT_TRAIL_START_WIDTH = 10 as const\r\n\r\n/** Default trail end width */\r\nexport const DEFAULT_TRAIL_END_WIDTH = 1 as const\r\n\r\n/** Default trail fade time in ms */\r\nexport const DEFAULT_TRAIL_FADE_TIME = 500 as const\r\n\r\n/** Default trail minimum distance between points */\r\nexport const DEFAULT_TRAIL_MIN_DISTANCE = 5 as const\r\n\r\n// ============================================================================\r\n// Audio Constants\r\n// ============================================================================\r\n\r\n/** Default master volume */\r\nexport const DEFAULT_MASTER_VOLUME = 1.0 as const\r\n\r\n/** Default max concurrent sounds */\r\nexport const DEFAULT_MAX_CONCURRENT_SOUNDS = 32 as const\r\n\r\n/** Default playlist volume */\r\nexport const DEFAULT_PLAYLIST_VOLUME = 0.8 as const\r\n\r\n/** Default crossfade duration in ms */\r\nexport const DEFAULT_CROSSFADE_DURATION = 1000 as const\r\n\r\n/** Default sound variant cooldown in ms */\r\nexport const DEFAULT_VARIANT_COOLDOWN = 100 as const\r\n\r\n/** Default audio zone fade distance */\r\nexport const DEFAULT_AUDIO_ZONE_FADE_DISTANCE = 50 as const\r\n\r\n/**\r\n * Default transition duration in ms.\r\n */\r\nexport const DEFAULT_TRANSITION_DURATION = 500 as const\r\n\r\n// ============================================================================\r\n// Animation Constants\r\n// ============================================================================\r\n\r\n/** Easing types */\r\nexport const EASING_TYPES = [\r\n\t'linear',\r\n\t'easeIn',\r\n\t'easeOut',\r\n\t'easeInOut',\r\n\t'easeInQuad',\r\n\t'easeOutQuad',\r\n\t'easeInOutQuad',\r\n\t'easeInCubic',\r\n\t'easeOutCubic',\r\n\t'easeInOutCubic',\r\n\t'easeInElastic',\r\n\t'easeOutElastic',\r\n\t'easeInOutElastic',\r\n\t'easeInBounce',\r\n\t'easeOutBounce',\r\n\t'easeInOutBounce',\r\n] as const\r\n\r\n// ============================================================================\r\n// Physics Constants\r\n// ============================================================================\r\n\r\n/** Default gravity X */\r\nexport const DEFAULT_GRAVITY_X = 0 as const\r\n\r\n/** Default gravity Y */\r\nexport const DEFAULT_GRAVITY_Y = 9.8 as const\r\n\r\n/** Default physics time step (1/60 for 60fps) */\r\nexport const DEFAULT_PHYSICS_TIMESTEP = 0.016666666666666666\r\n\r\n/** Default max physics iterations */\r\nexport const DEFAULT_MAX_PHYSICS_ITERATIONS = 10 as const\r\n\r\n// ============================================================================\r\n// CameraInterface Constants\r\n// ============================================================================\r\n\r\n/** Default zoom level */\r\nexport const DEFAULT_ZOOM = 1.0 as const\r\n\r\n/** Default min zoom */\r\nexport const DEFAULT_MIN_ZOOM = 0.1 as const\r\n\r\n/** Default max zoom */\r\nexport const DEFAULT_MAX_ZOOM = 10.0 as const\r\n\r\n/** Default CameraInterface smoothing */\r\nexport const DEFAULT_CAMERA_SMOOTHING = 0.1 as const\r\n\r\n// ============================================================================\r\n// UI Constants\r\n// ============================================================================\r\n\r\n/** Default font size */\r\nexport const DEFAULT_FONT_SIZE = 16 as const\r\n\r\n/** Default font family */\r\nexport const DEFAULT_FONT_FAMILY = 'sans-serif' as const\r\n\r\n/** Default text color */\r\nexport const DEFAULT_TEXT_COLOR = '#ffffff' as const\r\n\r\n/** Default ButtonInterface border radius */\r\nexport const DEFAULT_BORDER_RADIUS = 4 as const\r\n\r\n// ============================================================================\r\n// Mobile Constants\r\n// ============================================================================\r\n\r\n/** Haptic patterns */\r\nexport const HAPTIC_PATTERNS = ['tap', 'impact', 'notification', 'selection', 'error', 'success', 'warning'] as const\r\n\r\n/** Haptic intensities */\r\nexport const HAPTIC_INTENSITIES = ['light', 'medium', 'heavy'] as const\r\n\r\n/** Orientation lock types */\r\nexport const ORIENTATION_LOCK_TYPES = [\r\n\t'any',\r\n\t'natural',\r\n\t'landscape',\r\n\t'landscape-primary',\r\n\t'landscape-secondary',\r\n\t'portrait',\r\n\t'portrait-primary',\r\n\t'portrait-secondary',\r\n] as const\r\n\r\n// ============================================================================\r\n// Network Constants\r\n// ============================================================================\r\n\r\n/** Default reconnect delay in ms */\r\nexport const DEFAULT_RECONNECT_DELAY = 1000 as const\r\n\r\n/** Default max reconnect attempts */\r\nexport const DEFAULT_MAX_RECONNECT_ATTEMPTS = 5 as const\r\n\r\n/** Default heartbeat interval in ms */\r\nexport const DEFAULT_HEARTBEAT_INTERVAL = 30000 as const\r\n\r\n// ============================================================================\r\n// Performance Constants\r\n// ============================================================================\r\n\r\n/** Default performance sample rate */\r\nexport const DEFAULT_SAMPLE_RATE = 60 as const\r\n\r\n/** Health status types */\r\nexport const HEALTH_STATUSES = ['healthy', 'degraded', 'critical', 'unknown'] as const\r\n\r\n// ============================================================================\r\n// Asset Types\r\n// ============================================================================\r\n\r\n/** Asset types */\r\nexport const ASSET_TYPES = ['ImageInterface', 'audio', 'json', 'text'] as const\r\n\r\n// ============================================================================\r\n// Game State Default Values\r\n// ============================================================================\r\n\r\n/** Default player state */\r\nexport const DEFAULT_PLAYER_STATE: PlayerState = {\r\n\thealth: 100,\r\n\tmaxHealth: 100,\r\n\tlevel: 1,\r\n\texperience: 0,\r\n\tposition: { x: 0, y: 0 },\r\n\tname: 'Player',\r\n} as const\r\n\r\n/** Default world state */\r\nexport const DEFAULT_WORLD_STATE: WorldState = {\r\n\tcurrentScene: 'start',\r\n\tunlockedAreas: ['start'],\r\n\tdiscoveredLocations: [],\r\n\ttimeElapsed: 0,\r\n\tdayNightCycle: 0,\r\n\tweather: 'clear',\r\n} as const\r\n\r\n/** Default inventory state */\r\nexport const DEFAULT_INVENTORY_STATE: InventoryState = {\r\n\titems: [],\r\n\tmaxSlots: 20,\r\n\tgold: 0,\r\n\tequippedWeapon: null,\r\n\tequippedArmor: null,\r\n} as const\r\n\r\n/** Default settings state */\r\nexport const DEFAULT_SETTINGS_STATE: SettingsState = {\r\n\tmasterVolume: 1.0,\r\n\tmusicVolume: 0.8,\r\n\tsfxVolume: 1.0,\r\n\tisMuted: false,\r\n\tshowTutorials: true,\r\n\tautoSaveEnabled: true,\r\n\tlanguage: 'en',\r\n\tscreenShake: true,\r\n\thapticFeedback: true,\r\n\treducedMotion: false,\r\n\thighContrast: false,\r\n} as const\r\n\r\n/** Inventory item types */\r\nexport const INVENTORY_ITEM_TYPES = ['weapon', 'armor', 'consumable', 'key', 'misc'] as const\r\n\r\n/**\r\n * Default line style.\r\n */\r\nexport const DEFAULT_LINE_STYLE: LineStyle = {\r\n\tcolor: '#ffffff',\r\n\twidth: 1,\r\n}\r\n\r\n/**\r\n * Default fill style.\r\n */\r\nexport const DEFAULT_FILL_STYLE: FillStyle = {\r\n\tcolor: '#ffffff',\r\n\topacity: 1,\r\n}\r\n\r\n// ============================================================================\r\n// Inventory Constants\r\n// ============================================================================\r\n\r\n/** Default inventory capacity */\r\nexport const DEFAULT_INVENTORY_CAPACITY = 20 as const\r\n\r\n/** Default starting gold */\r\nexport const DEFAULT_STARTING_GOLD = 0 as const\r\n\r\n/** Default equipment slots */\r\nexport const DEFAULT_EQUIPMENT_SLOTS: readonly EquipmentSlotType[] = [\r\n\t'weapon',\r\n\t'armor',\r\n\t'helmet',\r\n\t'boots',\r\n\t'accessory',\r\n\t'offhand',\r\n] as const\r\n\r\n/** Rarity order for sorting (lowest to highest) */\r\nexport const RARITY_ORDER: readonly ItemRarity[] = [\r\n\t'common',\r\n\t'uncommon',\r\n\t'rare',\r\n\t'epic',\r\n\t'legendary',\r\n] as const\r\n\r\n// ============================================================================\r\n// Dialogue Constants\r\n// ============================================================================\r\n\r\n/** Default typewriter speed (characters per second) */\r\nexport const DEFAULT_TYPEWRITER_SPEED = 30 as const\r\n\r\n/** Default auto-advance delay in ms */\r\nexport const DEFAULT_AUTO_ADVANCE_DELAY = 2000 as const\r\n\r\n// ============================================================================\r\n// Quest Constants\r\n// ============================================================================\r\n\r\n/** Default max active quests */\r\nexport const DEFAULT_MAX_ACTIVE_QUESTS = 10 as const\r\n\r\n// ============================================================================\r\n// UI Constants\r\n// ============================================================================\r\n\r\n/** Default radial menu inner radius */\r\nexport const DEFAULT_RADIAL_INNER_RADIUS = 40 as const\r\n\r\n/** Default radial menu outer radius */\r\nexport const DEFAULT_RADIAL_OUTER_RADIUS = 100 as const\r\n\r\n/** Default radial menu center deadzone */\r\nexport const DEFAULT_RADIAL_CENTER_DEADZONE = 20 as const\r\n\r\n/** Default MinimapInterface zoom */\r\nexport const DEFAULT_MINIMAP_ZOOM = 1 as const\r\n\r\n/** Default MinimapInterface min zoom */\r\nexport const DEFAULT_MINIMAP_MIN_ZOOM = 0.5 as const\r\n\r\n/** Default MinimapInterface max zoom */\r\nexport const DEFAULT_MINIMAP_MAX_ZOOM = 4 as const\r\n\r\n/** Default notification max visible */\r\nexport const DEFAULT_NOTIFICATION_MAX_VISIBLE = 5 as const\r\n\r\n/** Default notification max history */\r\nexport const DEFAULT_NOTIFICATION_MAX_HISTORY = 50 as const\r\n\r\n/** Default notification duration in ms */\r\nexport const DEFAULT_NOTIFICATION_DURATION = 5000 as const\r\n\r\n// ============================================================================\r\n// Debug Constants\r\n// ============================================================================\r\n\r\n/** Default console max command history */\r\nexport const DEFAULT_CONSOLE_MAX_HISTORY = 50 as const\r\n\r\n/** Default console max log entries */\r\nexport const DEFAULT_CONSOLE_MAX_LOG_ENTRIES = 100 as const\r\n\r\n/** Default console height */\r\nexport const DEFAULT_CONSOLE_HEIGHT = 300 as const\r\n","import type { EngineInterface, EngineOptions, EngineState, Unsubscribe } from '../../types.js'\r\nimport {\r\n\tDEFAULT_TARGET_FPS,\r\n\tDEFAULT_BACKGROUND_COLOR,\r\n} from '../../constants.js'\r\n\r\n/**\r\n * Core game engine implementation.\r\n * Manages the game loop, rendering context, and engine lifecycle.\r\n */\r\nexport class Engine implements EngineInterface {\r\n\treadonly #canvas: HTMLCanvasElement\r\n\treadonly #context: CanvasRenderingContext2D\r\n\t#width: number\r\n\t#height: number\r\n\t#targetFPS: number\r\n\t#pixelRatio: number\r\n\t#backgroundColor: string\r\n\t#isRunning = false\r\n\t#isPaused = false\r\n\t#currentFPS = 0\r\n\t#frameCount = 0\r\n\t#elapsedTime = 0\r\n\t#deltaTime = 0\r\n\t#lastFrameTime = 0\r\n\t#fpsAccumulator = 0\r\n\t#fpsFrameCount = 0\r\n\t#animationFrameId: number | null = null\r\n\r\n\t#listeners = {\r\n\t\tbeforeUpdate: new Set<(deltaTime: number) => void>(),\r\n\t\tafterUpdate: new Set<(deltaTime: number) => void>(),\r\n\t\tbeforeRender: new Set<(context: CanvasRenderingContext2D) => void>(),\r\n\t\tafterRender: new Set<(context: CanvasRenderingContext2D) => void>(),\r\n\t\tpause: new Set<() => void>(),\r\n\t\tresume: new Set<() => void>(),\r\n\t\tstop: new Set<() => void>(),\r\n\t\tresize: new Set<(width: number, height: number) => void>(),\r\n\t}\r\n\r\n\tconstructor(options: EngineOptions) {\r\n\t\tthis.#canvas = options.canvas\r\n\t\tthis.#width = options.width\r\n\t\tthis.#height = options.height\r\n\t\tthis.#targetFPS = options.targetFPS ?? DEFAULT_TARGET_FPS\r\n\t\tthis.#pixelRatio = options.pixelRatio ?? window.devicePixelRatio\r\n\t\tthis.#backgroundColor = options.backgroundColor ?? DEFAULT_BACKGROUND_COLOR\r\n\r\n\t\tconst ctx = this.#canvas.getContext('2d')\r\n\t\tif (!ctx) {\r\n\t\t\tthrow new Error('Failed to get 2D rendering context')\r\n\t\t}\r\n\t\tthis.#context = ctx\r\n\r\n\t\t// Setup canvas dimensions with pixel ratio\r\n\t\tthis.#setupCanvas()\r\n\r\n\t\t// Setup event listeners for mobile-first experience\r\n\t\tif (options.preventContextMenu !== false) {\r\n\t\t\tthis.#canvas.addEventListener('contextmenu', this.#handleContextMenu)\r\n\t\t}\r\n\r\n\t\tif (options.preventScrollBounce !== false) {\r\n\t\t\tthis.#canvas.addEventListener('touchmove', this.#handleTouchMove, { passive: false })\r\n\t\t}\r\n\r\n\t\tif (options.disableTextSelection !== false) {\r\n\t\t\tthis.#canvas.style.userSelect = 'none'\r\n\t\t\tthis.#canvas.style.webkitUserSelect = 'none'\r\n\t\t\tthis.#canvas.style.touchAction = 'none'\r\n\t\t}\r\n\r\n\t\t// Register hooks from options\r\n\t\tif (options.onBeforeUpdate) this.#listeners.beforeUpdate.add(options.onBeforeUpdate)\r\n\t\tif (options.onAfterUpdate) this.#listeners.afterUpdate.add(options.onAfterUpdate)\r\n\t\tif (options.onBeforeRender) this.#listeners.beforeRender.add(options.onBeforeRender)\r\n\t\tif (options.onAfterRender) this.#listeners.afterRender.add(options.onAfterRender)\r\n\t\tif (options.onPause) this.#listeners.pause.add(options.onPause)\r\n\t\tif (options.onResume) this.#listeners.resume.add(options.onResume)\r\n\t\tif (options.onStop) this.#listeners.stop.add(options.onStop)\r\n\t\tif (options.onResize) this.#listeners.resize.add(options.onResize)\r\n\t}\r\n\r\n\tgetState(): EngineState {\r\n\t\treturn {\r\n\t\t\tisRunning: this.#isRunning,\r\n\t\t\tisPaused: this.#isPaused,\r\n\t\t\tcurrentFPS: this.#currentFPS,\r\n\t\t\tframeCount: this.#frameCount,\r\n\t\t\telapsedTime: this.#elapsedTime,\r\n\t\t\tdeltaTime: this.#deltaTime,\r\n\t\t\tsize: { width: this.#width, height: this.#height },\r\n\t\t}\r\n\t}\r\n\r\n\tgetCanvas(): HTMLCanvasElement {\r\n\t\treturn this.#canvas\r\n\t}\r\n\r\n\tgetContext(): CanvasRenderingContext2D {\r\n\t\treturn this.#context\r\n\t}\r\n\r\n\tgetWidth(): number {\r\n\t\treturn this.#width\r\n\t}\r\n\r\n\tgetHeight(): number {\r\n\t\treturn this.#height\r\n\t}\r\n\r\n\tgetTargetFPS(): number {\r\n\t\treturn this.#targetFPS\r\n\t}\r\n\r\n\tgetPixelRatio(): number {\r\n\t\treturn this.#pixelRatio\r\n\t}\r\n\r\n\tisRunning(): boolean {\r\n\t\treturn this.#isRunning\r\n\t}\r\n\r\n\tisPaused(): boolean {\r\n\t\treturn this.#isPaused\r\n\t}\r\n\r\n\tstart(): void {\r\n\t\tif (this.#isRunning) return\r\n\r\n\t\tthis.#isRunning = true\r\n\t\tthis.#isPaused = false\r\n\t\tthis.#lastFrameTime = performance.now()\r\n\t\tthis.#fpsAccumulator = 0\r\n\t\tthis.#fpsFrameCount = 0\r\n\r\n\t\tthis.#loop(this.#lastFrameTime)\r\n\t}\r\n\r\n\tstop(): void {\r\n\t\tif (!this.#isRunning) return\r\n\r\n\t\tthis.#isRunning = false\r\n\t\tthis.#isPaused = false\r\n\r\n\t\tif (this.#animationFrameId !== null) {\r\n\t\t\tcancelAnimationFrame(this.#animationFrameId)\r\n\t\t\tthis.#animationFrameId = null\r\n\t\t}\r\n\r\n\t\t// Notify stop listeners\r\n\t\tthis.#listeners.stop.forEach(cb => cb())\r\n\t}\r\n\r\n\tpause(): void {\r\n\t\tif (!this.#isRunning || this.#isPaused) return\r\n\r\n\t\tthis.#isPaused = true\r\n\r\n\t\t// Notify pause listeners\r\n\t\tthis.#listeners.pause.forEach(cb => cb())\r\n\t}\r\n\r\n\tresume(): void {\r\n\t\tif (!this.#isRunning || !this.#isPaused) return\r\n\r\n\t\tthis.#isPaused = false\r\n\t\tthis.#lastFrameTime = performance.now()\r\n\r\n\t\t// Notify resume listeners\r\n\t\tthis.#listeners.resume.forEach(cb => cb())\r\n\t}\r\n\r\n\tresize(width: number, height: number): void {\r\n\t\tthis.#width = width\r\n\t\tthis.#height = height\r\n\t\tthis.#setupCanvas()\r\n\r\n\t\t// Notify resize listeners\r\n\t\tthis.#listeners.resize.forEach(cb => cb(width, height))\r\n\t}\r\n\r\n\tonBeforeUpdate(callback: (deltaTime: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.beforeUpdate.add(callback)\r\n\t\treturn () => this.#listeners.beforeUpdate.delete(callback)\r\n\t}\r\n\r\n\tonAfterUpdate(callback: (deltaTime: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.afterUpdate.add(callback)\r\n\t\treturn () => this.#listeners.afterUpdate.delete(callback)\r\n\t}\r\n\r\n\tonBeforeRender(callback: (context: CanvasRenderingContext2D) => void): Unsubscribe {\r\n\t\tthis.#listeners.beforeRender.add(callback)\r\n\t\treturn () => this.#listeners.beforeRender.delete(callback)\r\n\t}\r\n\r\n\tonAfterRender(callback: (context: CanvasRenderingContext2D) => void): Unsubscribe {\r\n\t\tthis.#listeners.afterRender.add(callback)\r\n\t\treturn () => this.#listeners.afterRender.delete(callback)\r\n\t}\r\n\r\n\tonPause(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.pause.add(callback)\r\n\t\treturn () => this.#listeners.pause.delete(callback)\r\n\t}\r\n\r\n\tonResume(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.resume.add(callback)\r\n\t\treturn () => this.#listeners.resume.delete(callback)\r\n\t}\r\n\r\n\tonStop(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.stop.add(callback)\r\n\t\treturn () => this.#listeners.stop.delete(callback)\r\n\t}\r\n\r\n\tonResize(callback: (width: number, height: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.resize.add(callback)\r\n\t\treturn () => this.#listeners.resize.delete(callback)\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.stop()\r\n\r\n\t\t// Remove event listeners\r\n\t\tthis.#canvas.removeEventListener('contextmenu', this.#handleContextMenu)\r\n\t\tthis.#canvas.removeEventListener('touchmove', this.#handleTouchMove)\r\n\r\n\t\t// Clear all listeners\r\n\t\tthis.#listeners.beforeUpdate.clear()\r\n\t\tthis.#listeners.afterUpdate.clear()\r\n\t\tthis.#listeners.beforeRender.clear()\r\n\t\tthis.#listeners.afterRender.clear()\r\n\t\tthis.#listeners.pause.clear()\r\n\t\tthis.#listeners.resume.clear()\r\n\t\tthis.#listeners.stop.clear()\r\n\t\tthis.#listeners.resize.clear()\r\n\t}\r\n\r\n\t// Private methods\r\n\r\n\t#setupCanvas(): void {\r\n\t\t// Set display size (CSS pixels)\r\n\t\tthis.#canvas.style.width = `${this.#width}px`\r\n\t\tthis.#canvas.style.height = `${this.#height}px`\r\n\r\n\t\t// Set actual size in memory (scaled for pixel ratio)\r\n\t\tthis.#canvas.width = Math.floor(this.#width * this.#pixelRatio)\r\n\t\tthis.#canvas.height = Math.floor(this.#height * this.#pixelRatio)\r\n\r\n\t\t// Scale context to counter the pixel ratio\r\n\t\tthis.#context.scale(this.#pixelRatio, this.#pixelRatio)\r\n\r\n\t\t// Enable image smoothing for pixel art (can be disabled if needed)\r\n\t\tthis.#context.imageSmoothingEnabled = false\r\n\t}\r\n\r\n\t#loop = (currentTime: number): void => {\r\n\t\tif (!this.#isRunning) return\r\n\r\n\t\tthis.#animationFrameId = requestAnimationFrame(this.#loop)\r\n\r\n\t\t// Calculate delta time in seconds\r\n\t\tthis.#deltaTime = (currentTime - this.#lastFrameTime) / 1000\r\n\t\tthis.#lastFrameTime = currentTime\r\n\r\n\t\t// Skip large delta times (e.g., when tab was inactive)\r\n\t\tif (this.#deltaTime > 0.25) {\r\n\t\t\tthis.#deltaTime = 1 / this.#targetFPS\r\n\t\t}\r\n\r\n\t\t// Update FPS counter\r\n\t\tthis.#fpsAccumulator += this.#deltaTime\r\n\t\tthis.#fpsFrameCount++\r\n\t\tif (this.#fpsAccumulator >= 1.0) {\r\n\t\t\tthis.#currentFPS = this.#fpsFrameCount\r\n\t\t\tthis.#fpsFrameCount = 0\r\n\t\t\tthis.#fpsAccumulator -= 1.0\r\n\t\t}\r\n\r\n\t\t// Skip update/render if paused\r\n\t\tif (this.#isPaused) return\r\n\r\n\t\t// Update elapsed time\r\n\t\tthis.#elapsedTime += this.#deltaTime\r\n\t\tthis.#frameCount++\r\n\r\n\t\t// Before update\r\n\t\tthis.#listeners.beforeUpdate.forEach(cb => cb(this.#deltaTime))\r\n\r\n\t\t// After update\r\n\t\tthis.#listeners.afterUpdate.forEach(cb => cb(this.#deltaTime))\r\n\r\n\t\t// Clear canvas\r\n\t\tthis.#context.fillStyle = this.#backgroundColor\r\n\t\tthis.#context.fillRect(0, 0, this.#width, this.#height)\r\n\r\n\t\t// Before render\r\n\t\tthis.#listeners.beforeRender.forEach(cb => cb(this.#context))\r\n\r\n\t\t// After render\r\n\t\tthis.#listeners.afterRender.forEach(cb => cb(this.#context))\r\n\t}\r\n\r\n\t#handleContextMenu = (e: Event): void => {\r\n\t\te.preventDefault()\r\n\t}\r\n\r\n\t#handleTouchMove = (e: TouchEvent): void => {\r\n\t\te.preventDefault()\r\n\t}\r\n}\r\n","import type { SceneInterface, SceneOptions, SceneState, EntityInterface, Unsubscribe } from '../../types.js'\r\nimport { DEFAULT_BACKGROUND_COLOR } from '../../constants.js'\r\n\r\n/**\r\n * Scene implementation for managing entities and lifecycle.\r\n * Scenes contain entities and manage their update/render cycle.\r\n */\r\nexport class Scene implements SceneInterface {\r\n\treadonly name: string\r\n\t#isActive = false\r\n\t#isLoaded = false\r\n\t#backgroundColor: string\r\n\t#persistent: boolean\r\n\t#entities: Map<string, EntityInterface> = new Map()\r\n\t#sortedEntities: EntityInterface[] = []\r\n\t#needsSort = false\r\n\r\n\t#listeners = {\r\n\t\tload: new Set<() => void | Promise<void>>(),\r\n\t\tunload: new Set<() => void>(),\r\n\t\tactivate: new Set<() => void>(),\r\n\t\tdeactivate: new Set<() => void>(),\r\n\t\tupdate: new Set<(deltaTime: number) => void>(),\r\n\t\trender: new Set<(context: CanvasRenderingContext2D) => void>(),\r\n\t}\r\n\r\n\tconstructor(options: SceneOptions) {\r\n\t\tthis.name = options.name\r\n\t\tthis.#backgroundColor = options.backgroundColor ?? DEFAULT_BACKGROUND_COLOR\r\n\t\tthis.#persistent = options.persistent ?? false\r\n\r\n\t\t// Register hooks from options\r\n\t\tif (options.onLoad) this.#listeners.load.add(options.onLoad)\r\n\t\tif (options.onUnload) this.#listeners.unload.add(options.onUnload)\r\n\t\tif (options.onActivate) this.#listeners.activate.add(options.onActivate)\r\n\t\tif (options.onDeactivate) this.#listeners.deactivate.add(options.onDeactivate)\r\n\t\tif (options.onUpdate) this.#listeners.update.add(options.onUpdate)\r\n\t\tif (options.onRender) this.#listeners.render.add(options.onRender)\r\n\t}\r\n\r\n\tgetState(): SceneState {\r\n\t\treturn {\r\n\t\t\tname: this.name,\r\n\t\t\tisActive: this.#isActive,\r\n\t\t\tisLoaded: this.#isLoaded,\r\n\t\t\tentityCount: this.#entities.size,\r\n\t\t}\r\n\t}\r\n\r\n\tisActive(): boolean {\r\n\t\treturn this.#isActive\r\n\t}\r\n\r\n\tisLoaded(): boolean {\r\n\t\treturn this.#isLoaded\r\n\t}\r\n\r\n\tgetEntityCount(): number {\r\n\t\treturn this.#entities.size\r\n\t}\r\n\r\n\tgetBackgroundColor(): string {\r\n\t\treturn this.#backgroundColor\r\n\t}\r\n\r\n\tisPersistent(): boolean {\r\n\t\treturn this.#persistent\r\n\t}\r\n\r\n\taddEntity(entity: EntityInterface): void {\r\n\t\tif (this.#entities.has(entity.id)) {\r\n\t\t\treturn // Entity already in scene\r\n\t\t}\r\n\t\tthis.#entities.set(entity.id, entity)\r\n\t\tthis.#sortedEntities.push(entity)\r\n\t\tthis.#needsSort = true\r\n\t}\r\n\r\n\tremoveEntity(entity: EntityInterface): void {\r\n\t\tthis.removeEntityById(entity.id)\r\n\t}\r\n\r\n\tremoveEntityById(id: string): void {\r\n\t\tconst entity = this.#entities.get(id)\r\n\t\tif (!entity) return\r\n\r\n\t\tthis.#entities.delete(id)\r\n\t\tconst index = this.#sortedEntities.indexOf(entity)\r\n\t\tif (index !== -1) {\r\n\t\t\tthis.#sortedEntities.splice(index, 1)\r\n\t\t}\r\n\t}\r\n\r\n\tgetEntity(id: string): EntityInterface | undefined {\r\n\t\treturn this.#entities.get(id)\r\n\t}\r\n\r\n\tgetAllEntities(): readonly EntityInterface[] {\r\n\t\tthis.#sortIfNeeded()\r\n\t\treturn this.#sortedEntities\r\n\t}\r\n\r\n\tclearEntities(): void {\r\n\t\t// Destroy all entities\r\n\t\tfor (const entity of this.#entities.values()) {\r\n\t\t\tentity.destroy()\r\n\t\t}\r\n\t\tthis.#entities.clear()\r\n\t\tthis.#sortedEntities.length = 0\r\n\t\tthis.#needsSort = false\r\n\t}\r\n\r\n\tasync load(): Promise<void> {\r\n\t\tif (this.#isLoaded) return\r\n\r\n\t\t// Call load listeners (may be async)\r\n\t\tfor (const listener of this.#listeners.load) {\r\n\t\t\tawait listener()\r\n\t\t}\r\n\r\n\t\tthis.#isLoaded = true\r\n\t}\r\n\r\n\tunload(): void {\r\n\t\tif (!this.#isLoaded) return\r\n\r\n\t\t// Deactivate first if active\r\n\t\tif (this.#isActive) {\r\n\t\t\tthis.deactivate()\r\n\t\t}\r\n\r\n\t\t// Clear entities unless persistent\r\n\t\tif (!this.#persistent) {\r\n\t\t\tthis.clearEntities()\r\n\t\t}\r\n\r\n\t\tthis.#isLoaded = false\r\n\t\tthis.#listeners.unload.forEach(cb => cb())\r\n\t}\r\n\r\n\tactivate(): void {\r\n\t\tif (this.#isActive) return\r\n\r\n\t\tthis.#isActive = true\r\n\t\tthis.#listeners.activate.forEach(cb => cb())\r\n\t}\r\n\r\n\tdeactivate(): void {\r\n\t\tif (!this.#isActive) return\r\n\r\n\t\tthis.#isActive = false\r\n\t\tthis.#listeners.deactivate.forEach(cb => cb())\r\n\t}\r\n\r\n\tupdate(deltaTime: number): void {\r\n\t\tif (!this.#isActive) return\r\n\r\n\t\t// Update all entities\r\n\t\tfor (const entity of this.#entities.values()) {\r\n\t\t\tif ('update' in entity && typeof entity.update === 'function') {\r\n\t\t\t\t(entity as { update(dt: number): void }).update(deltaTime)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Call update listeners\r\n\t\tthis.#listeners.update.forEach(cb => cb(deltaTime))\r\n\t}\r\n\r\n\trender(context: CanvasRenderingContext2D): void {\r\n\t\tif (!this.#isActive) return\r\n\r\n\t\t// Sort entities by z-index if needed\r\n\t\tthis.#sortIfNeeded()\r\n\r\n\t\t// Render all visible entities in z-order\r\n\t\tfor (const entity of this.#sortedEntities) {\r\n\t\t\tif (entity.isVisible() && 'render' in entity && typeof entity.render === 'function') {\r\n\t\t\t\t(entity as { render(ctx: CanvasRenderingContext2D): void }).render(context)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Call render listeners\r\n\t\tthis.#listeners.render.forEach(cb => cb(context))\r\n\t}\r\n\r\n\t/**\r\n\t * Mark that entities need re-sorting (call when z-index changes).\r\n\t */\r\n\tmarkDirty(): void {\r\n\t\tthis.#needsSort = true\r\n\t}\r\n\r\n\tonLoad(callback: () => void | Promise<void>): Unsubscribe {\r\n\t\tthis.#listeners.load.add(callback)\r\n\t\treturn () => this.#listeners.load.delete(callback)\r\n\t}\r\n\r\n\tonUnload(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.unload.add(callback)\r\n\t\treturn () => this.#listeners.unload.delete(callback)\r\n\t}\r\n\r\n\tonActivate(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.activate.add(callback)\r\n\t\treturn () => this.#listeners.activate.delete(callback)\r\n\t}\r\n\r\n\tonDeactivate(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.deactivate.add(callback)\r\n\t\treturn () => this.#listeners.deactivate.delete(callback)\r\n\t}\r\n\r\n\tonUpdate(callback: (deltaTime: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.update.add(callback)\r\n\t\treturn () => this.#listeners.update.delete(callback)\r\n\t}\r\n\r\n\tonRender(callback: (context: CanvasRenderingContext2D) => void): Unsubscribe {\r\n\t\tthis.#listeners.render.add(callback)\r\n\t\treturn () => this.#listeners.render.delete(callback)\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\t// Unload and clear\r\n\t\tthis.unload()\r\n\t\tthis.clearEntities()\r\n\r\n\t\t// Clear all listeners\r\n\t\tthis.#listeners.load.clear()\r\n\t\tthis.#listeners.unload.clear()\r\n\t\tthis.#listeners.activate.clear()\r\n\t\tthis.#listeners.deactivate.clear()\r\n\t\tthis.#listeners.update.clear()\r\n\t\tthis.#listeners.render.clear()\r\n\t}\r\n\r\n\t#sortIfNeeded(): void {\r\n\t\tif (!this.#needsSort) return\r\n\r\n\t\tthis.#sortedEntities.sort((a, b) => a.getZIndex() - b.getZIndex())\r\n\t\tthis.#needsSort = false\r\n\t}\r\n}\r\n","import type { SceneManagerInterface, SceneManagerOptions, SceneOptions } from '../../types.js'\r\nimport { Scene } from './Scene.js'\r\n\r\n/**\r\n * Scene manager for managing multiple scenes and scene transitions.\r\n * Handles scene lifecycle, transitions, and provides a single point of access\r\n * for scene management in the game.\r\n */\r\nexport class SceneManager implements SceneManagerInterface {\r\n\t#scenes: Map<string, Scene> = new Map()\r\n\t#activeScene: Scene | null = null\r\n\t#defaultScene: string\r\n\t#preloadAll: boolean\r\n\r\n\tconstructor(options?: SceneManagerOptions) {\r\n\t\tthis.#defaultScene = options?.defaultScene ?? ''\r\n\t\tthis.#preloadAll = options?.preloadAll ?? false\r\n\t}\r\n\r\n\tcreateScene(options: SceneOptions): Scene {\r\n\t\tconst scene = new Scene(options)\r\n\t\tthis.#scenes.set(scene.name, scene)\r\n\t\treturn scene\r\n\t}\r\n\r\n\taddScene(scene: Scene): void {\r\n\t\tif (this.#scenes.has(scene.name)) {\r\n\t\t\tthrow new Error(`Scene with name \"${scene.name}\" already exists`)\r\n\t\t}\r\n\t\tthis.#scenes.set(scene.name, scene)\r\n\t}\r\n\r\n\tremoveScene(name: string): void {\r\n\t\tconst scene = this.#scenes.get(name)\r\n\t\tif (!scene) return\r\n\r\n\t\tif (scene === this.#activeScene) {\r\n\t\t\tthis.#activeScene.deactivate()\r\n\t\t\tthis.#activeScene = null\r\n\t\t}\r\n\r\n\t\tscene.destroy()\r\n\t\tthis.#scenes.delete(name)\r\n\t}\r\n\r\n\tgetScene(name: string): Scene | undefined {\r\n\t\treturn this.#scenes.get(name)\r\n\t}\r\n\r\n\tgetAllScenes(): readonly Scene[] {\r\n\t\treturn Array.from(this.#scenes.values())\r\n\t}\r\n\r\n\tgetSceneCount(): number {\r\n\t\treturn this.#scenes.size\r\n\t}\r\n\r\n\thasScene(name: string): boolean {\r\n\t\treturn this.#scenes.has(name)\r\n\t}\r\n\r\n\tasync setActiveScene(name: string): Promise<void> {\r\n\t\tconst newScene = this.#scenes.get(name)\r\n\t\tif (!newScene) {\r\n\t\t\tthrow new Error(`Scene \"${name}\" not found`)\r\n\t\t}\r\n\r\n\t\t// Skip if already active\r\n\t\tif (this.#activeScene === newScene) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\t// Deactivate current scene\r\n\t\tif (this.#activeScene) {\r\n\t\t\tthis.#activeScene.deactivate()\r\n\t\t}\r\n\r\n\t\t// Load new scene if needed\r\n\t\tif (!newScene.isLoaded()) {\r\n\t\t\tawait newScene.load()\r\n\t\t}\r\n\r\n\t\t// Activate new scene\r\n\t\tnewScene.activate()\r\n\t\tthis.#activeScene = newScene\r\n\t}\r\n\r\n\tgetActiveScene(): Scene | undefined {\r\n\t\treturn this.#activeScene ?? undefined\r\n\t}\r\n\r\n\tgetActiveSceneName(): string | undefined {\r\n\t\treturn this.#activeScene?.name\r\n\t}\r\n\r\n\tgetDefaultSceneName(): string {\r\n\t\treturn this.#defaultScene\r\n\t}\r\n\r\n\tasync preloadScene(name: string): Promise<void> {\r\n\t\tconst scene = this.#scenes.get(name)\r\n\t\tif (!scene) {\r\n\t\t\tthrow new Error(`Scene \"${name}\" not found`)\r\n\t\t}\r\n\r\n\t\tif (!scene.isLoaded()) {\r\n\t\t\tawait scene.load()\r\n\t\t}\r\n\t}\r\n\r\n\tasync preloadAllScenes(): Promise<void> {\r\n\t\tconst loadPromises: Promise<void>[] = []\r\n\t\tfor (const scene of this.#scenes.values()) {\r\n\t\t\tif (!scene.isLoaded()) {\r\n\t\t\t\tloadPromises.push(scene.load())\r\n\t\t\t}\r\n\t\t}\r\n\t\tawait Promise.all(loadPromises)\r\n\t}\r\n\r\n\tunloadScene(name: string): void {\r\n\t\tconst scene = this.#scenes.get(name)\r\n\t\tif (!scene) return\r\n\r\n\t\t// Don't unload active scene\r\n\t\tif (scene === this.#activeScene) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\tif (scene.isLoaded()) {\r\n\t\t\tscene.unload()\r\n\t\t}\r\n\t}\r\n\r\n\tupdate(deltaTime: number): void {\r\n\t\tif (this.#activeScene) {\r\n\t\t\tthis.#activeScene.update(deltaTime)\r\n\t\t}\r\n\t}\r\n\r\n\trender(context: CanvasRenderingContext2D): void {\r\n\t\tif (this.#activeScene) {\r\n\t\t\tthis.#activeScene.render(context)\r\n\t\t}\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\t// Deactivate current scene first\r\n\t\tif (this.#activeScene) {\r\n\t\t\tthis.#activeScene.deactivate()\r\n\t\t\tthis.#activeScene = null\r\n\t\t}\r\n\r\n\t\t// Destroy all scenes\r\n\t\tfor (const scene of this.#scenes.values()) {\r\n\t\t\tscene.destroy()\r\n\t\t}\r\n\t\tthis.#scenes.clear()\r\n\t}\r\n}\r\n","/**\r\n * Type guards, utility functions, and math helpers for game development.\r\n */\r\n\r\nimport type {\r\n\tBatteryManager, FieldDefinition,\r\n\tNavigatorExtended,\r\n\tNetworkInformationAPI, SchemaError, SchemaErrorCode,\r\n\tUISpacing,\r\n\tVector2,\r\n} from './types.js'\r\n\r\n// ============================================================================\r\n// Primitive Type Guards\r\n// ============================================================================\r\n\r\n/** Check if value is a string */\r\nexport function isString(value: unknown): value is string {\r\n\treturn typeof value === 'string'\r\n}\r\n\r\n/** Check if value is a non-empty string */\r\nexport function isNonEmptyString(value: unknown): value is string {\r\n\treturn typeof value === 'string' && value.length > 0\r\n}\r\n\r\n/** Check if value is a number and not NaN */\r\nexport function isNumber(value: unknown): value is number {\r\n\treturn typeof value === 'number' && !Number.isNaN(value)\r\n}\r\n\r\n/** Check if value is a finite number */\r\nexport function isFiniteNumber(value: unknown): value is number {\r\n\treturn typeof value === 'number' && Number.isFinite(value)\r\n}\r\n\r\n/** Check if value is a boolean */\r\nexport function isBoolean(value: unknown): value is boolean {\r\n\treturn typeof value === 'boolean'\r\n}\r\n\r\n/** Check if value is null or undefined */\r\nexport function isNullish(value: unknown): value is null | undefined {\r\n\treturn value === null || value === undefined\r\n}\r\n\r\n/** Check if value is defined (not null or undefined) */\r\nexport function isDefined<T>(value: T | null | undefined): value is T {\r\n\treturn value !== null && value !== undefined\r\n}\r\n\r\n// ============================================================================\r\n// Object Type Guards\r\n// ============================================================================\r\n\r\n/** Check if value is a plain object */\r\nexport function isObject(value: unknown): value is Record<string, unknown> {\r\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value)\r\n}\r\n\r\n// ============================================================================\r\n// Extended Navigator Type Guards\r\n// ============================================================================\r\n\r\n/** Check if navigator has deviceMemory property */\r\nexport function hasDeviceMemory(nav: Navigator): nav is NavigatorExtended & { deviceMemory: number } {\r\n\treturn 'deviceMemory' in nav && typeof nav.deviceMemory === 'number'\r\n}\r\n\r\n/** Check if navigator has getBattery method */\r\nexport function hasGetBattery(nav: Navigator): nav is NavigatorExtended & { getBattery: () => Promise<BatteryManager> } {\r\n\treturn 'getBattery' in nav && typeof nav.getBattery === 'function'\r\n}\r\n\r\n/** Check if navigator has connection property */\r\nexport function hasNetworkConnection(nav: Navigator): nav is NavigatorExtended & { connection: NetworkInformationAPI } {\r\n\treturn 'connection' in nav && isObject(nav.connection)\r\n}\r\n\r\n/** Check if navigator has vibrate method */\r\nexport function hasVibrate(nav: Navigator): nav is Navigator & { vibrate: (pattern: number | number[]) => boolean } {\r\n\treturn 'vibrate' in nav && typeof nav.vibrate === 'function'\r\n}\r\n\r\n// ============================================================================\r\n// Function Type Guards\r\n// ============================================================================\r\n\r\n/** Check if value is a function */\r\nexport function isFunction(value: unknown): value is (...args: unknown[]) => unknown {\r\n\treturn typeof value === 'function'\r\n}\r\n\r\n// ============================================================================\r\n// Array Type Guards\r\n// ============================================================================\r\n\r\n/** Check if value is an array */\r\nexport function isArray(value: unknown): value is unknown[] {\r\n\treturn Array.isArray(value)\r\n}\r\n\r\n/** Check if value is a non-empty array */\r\nexport function isNonEmptyArray<T>(value: unknown): value is [T, ...T[]] {\r\n\treturn Array.isArray(value) && value.length > 0\r\n}\r\n\r\n// ============================================================================\r\n// Storage Type Guards\r\n// ============================================================================\r\n\r\n/** Check if IndexedDB is available */\r\nexport function hasIndexedDB(): boolean {\r\n\treturn typeof indexedDB !== 'undefined'\r\n}\r\n\r\n/** Check if value is a valid IDBValidKey */\r\nexport function isIDBValidKey(value: unknown): value is IDBValidKey {\r\n\treturn (\r\n\t\ttypeof value === 'string' ||\r\n\t\ttypeof value === 'number' ||\r\n\t\tvalue instanceof Date ||\r\n\t\t(value instanceof ArrayBuffer) ||\r\n\t\t(isArray(value) && value.every(isIDBValidKey))\r\n\t)\r\n}\r\n\r\n/** Check if object has id property (DTO-like) */\r\nexport function hasId(obj: unknown): obj is { id: string } {\r\n\treturn isObject(obj) && 'id' in obj && typeof obj.id === 'string'\r\n}\r\n\r\n/** Check if object has version property */\r\nexport function hasVersion(obj: unknown): obj is { version: number } {\r\n\treturn isObject(obj) && 'version' in obj && typeof obj.version === 'number'\r\n}\r\n\r\n/** Check if object has timestamp property */\r\nexport function hasTimestamp(obj: unknown): obj is { timestamp: number } {\r\n\treturn isObject(obj) && 'timestamp' in obj && typeof obj.timestamp === 'number'\r\n}\r\n\r\n// ============================================================================\r\n// Result Type Guards\r\n// ============================================================================\r\n\r\n/** Check if result is successful */\r\nexport function isOk<T>(result: { ok: boolean; value?: T }): result is { ok: true; value: T } {\r\n\treturn result.ok\r\n}\r\n\r\n/** Check if result is an error */\r\nexport function isErr(result: { ok: boolean; error?: string }): result is { ok: false; error: string } {\r\n\treturn !result.ok\r\n}\r\n\r\n// ============================================================================\r\n// Utility Functions\r\n// ============================================================================\r\n\r\n/** Generate a UUID v4 */\r\nexport function generateId(): string {\r\n\treturn crypto.randomUUID()\r\n}\r\n\r\n/** Get current timestamp in milliseconds */\r\nexport function now(): number {\r\n\treturn Date.now()\r\n}\r\n\r\n/** Clamp a number between min and max */\r\nexport function clamp(value: number, min: number, max: number): number {\r\n\treturn Math.max(min, Math.min(max, value))\r\n}\r\n\r\n/** Linear interpolation */\r\nexport function lerp(start: number, end: number, t: number): number {\r\n\treturn start + (end - start) * t\r\n}\r\n\r\n/** Deep clone an object (JSON-safe) */\r\nexport function deepClone<T>(obj: T): T {\r\n\treturn JSON.parse(JSON.stringify(obj))\r\n}\r\n\r\n/**\r\n * Shallow equality check for objects.\r\n * Compares object references and shallow properties using Object.is.\r\n */\r\nexport function shallowEqual<T>(a: T, b: T): boolean {\r\n\tif (Object.is(a, b)) return true\r\n\tif (typeof a !== 'object' || typeof b !== 'object') return false\r\n\tif (a === null || b === null) return false\r\n\r\n\tconst keysA = Object.keys(a)\r\n\tconst keysB = Object.keys(b)\r\n\r\n\tif (keysA.length !== keysB.length) return false\r\n\r\n\tfor (const key of keysA) {\r\n\t\tif (!Object.prototype.hasOwnProperty.call(b, key)) return false\r\n\t\tif (!Object.is((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key])) {\r\n\t\t\treturn false\r\n\t\t}\r\n\t}\r\n\r\n\treturn true\r\n}\r\n\r\n/** Debounce a function */\r\nexport function debounce<T extends(...args: Parameters<T>) => void>(\r\n\tfn: T,\r\n\tdelay: number,\r\n): (...args: Parameters<T>) => void {\r\n\tlet timeoutId: ReturnType<typeof setTimeout> | undefined\r\n\treturn (...args: Parameters<T>) => {\r\n\t\tif (timeoutId !== undefined) {\r\n\t\t\tclearTimeout(timeoutId)\r\n\t\t}\r\n\t\ttimeoutId = setTimeout(() => fn(...args), delay)\r\n\t}\r\n}\r\n\r\n/** Throttle a function */\r\nexport function throttle<T extends(...args: Parameters<T>) => void>(\r\n\tfn: T,\r\n\tlimit: number,\r\n): (...args: Parameters<T>) => void {\r\n\tlet lastCall = 0\r\n\treturn (...args: Parameters<T>) => {\r\n\t\tconst currentTime = now()\r\n\t\tif (currentTime - lastCall >= limit) {\r\n\t\t\tlastCall = currentTime\r\n\t\t\tfn(...args)\r\n\t\t}\r\n\t}\r\n}\r\n\r\n/**\r\n * Helper to normalize spacing input.\r\n * Accepts single number (all sides) or partial object.\r\n *\r\n * @param value - Number for uniform spacing or partial spacing object\r\n * @returns Fully populated UISpacing object\r\n *\r\n * @example\r\n * ```ts\r\n * createSpacing(8) // { top: 8, right: 8, bottom: 8, left: 8 }\r\n * createSpacing({ top: 10, left: 20 }) // { top: 10, right: 0, bottom: 0, left: 20 }\r\n * ```\r\n */\r\nexport function createSpacing(value: number | Partial<UISpacing>): UISpacing {\r\n\tif (typeof value === 'number') {\r\n\t\treturn { top: value, right: value, bottom: value, left: value }\r\n\t}\r\n\treturn {\r\n\t\ttop: value.top ?? 0,\r\n\t\tright: value.right ?? 0,\r\n\t\tbottom: value. bottom ?? 0,\r\n\t\tleft: value.left ?? 0,\r\n\t}\r\n}\r\n\r\n/**\r\n * Create a validation error.\r\n */\r\nexport function createError(\r\n\tpath: string,\r\n\tmessage: string,\r\n\tcode: SchemaErrorCode,\r\n\tvalue?: unknown,\r\n): SchemaError {\r\n\treturn { path, message, code, value }\r\n}\r\n\r\n/**\r\n * Validate a single field against its definition.\r\n */\r\nexport function validateField(\r\n\tfield: FieldDefinition,\r\n\tvalue: unknown,\r\n\tpath: string,\r\n): SchemaError | null {\r\n\t// Check for null/undefined\r\n\tif (value === null || value === undefined) {\r\n\t\tif (field.required && !field.nullable) {\r\n\t\t\treturn createError(path, `Field \"${field.name}\" is required`, 'REQUIRED')\r\n\t\t}\r\n\t\treturn null\r\n\t}\r\n\r\n\t// Check type\r\n\tconst actualType = Array.isArray(value) ? 'array' : typeof value\r\n\tif (field.type !== actualType) {\r\n\t\treturn createError(\r\n\t\t\tpath,\r\n\t\t\t`Expected ${field.type} but got ${actualType}`,\r\n\t\t\t'TYPE',\r\n\t\t\tvalue,\r\n\t\t)\r\n\t}\r\n\r\n\t// Custom validation\r\n\tif (field.validate && !field.validate(value)) {\r\n\t\treturn createError(\r\n\t\t\tpath,\r\n\t\t\t`Custom validation failed for \"${field.name}\"`,\r\n\t\t\t'CONSTRAINT',\r\n\t\t\tvalue,\r\n\t\t)\r\n\t}\r\n\r\n\treturn null\r\n}\r\n\r\n// ============================================================================\r\n// Math: Distance & Vectors\r\n// ============================================================================\r\n\r\n/** Calculate distance between two points */\r\nexport function distance(x1: number, y1: number, x2: number, y2: number): number {\r\n\tconst dx = x2 - x1\r\n\tconst dy = y2 - y1\r\n\treturn Math.sqrt(dx * dx + dy * dy)\r\n}\r\n\r\n/** Calculate squared distance between two points (faster, no sqrt) */\r\nexport function distanceSquared(x1: number, y1: number, x2: number, y2: number): number {\r\n\tconst dx = x2 - x1\r\n\tconst dy = y2 - y1\r\n\treturn dx * dx + dy * dy\r\n}\r\n\r\n/** Calculate distance between two vectors */\r\nexport function distanceVec(a: Readonly<Vector2>, b: Readonly<Vector2>): number {\r\n\treturn distance(a.x, a.y, b.x, b.y)\r\n}\r\n\r\n/** Calculate squared distance between two vectors */\r\nexport function distanceVecSquared(a: Readonly<Vector2>, b: Readonly<Vector2>): number {\r\n\treturn distanceSquared(a.x, a.y, b.x, b.y)\r\n}\r\n\r\n/** Normalize a vector (make it unit length) */\r\nexport function normalize(x: number, y: number): Vector2 {\r\n\tconst len = Math.sqrt(x * x + y * y)\r\n\tif (len === 0) return { x: 0, y: 0 }\r\n\treturn { x: x / len, y: y / len }\r\n}\r\n\r\n/** Normalize a vector object */\r\nexport function normalizeVec(v: Readonly<Vector2>): Vector2 {\r\n\treturn normalize(v.x, v.y)\r\n}\r\n\r\n/** Get the magnitude (length) of a vector */\r\nexport function magnitude(x: number, y: number): number {\r\n\treturn Math.sqrt(x * x + y * y)\r\n}\r\n\r\n/** Get the magnitude of a vector object */\r\nexport function magnitudeVec(v: Readonly<Vector2>): number {\r\n\treturn magnitude(v.x, v.y)\r\n}\r\n\r\n/** Get angle between two points in radians */\r\nexport function angleBetween(x1: number, y1: number, x2: number, y2: number): number {\r\n\treturn Math.atan2(y2 - y1, x2 - x1)\r\n}\r\n\r\n/** Get angle from origin to a point in radians */\r\nexport function angleOf(x: number, y: number): number {\r\n\treturn Math.atan2(y, x)\r\n}\r\n\r\n/** Get vector from angle and magnitude */\r\nexport function fromAngle(angle: number, length: number = 1): Vector2 {\r\n\treturn {\r\n\t\tx: Math.cos(angle) * length,\r\n\t\ty: Math.sin(angle) * length,\r\n\t}\r\n}\r\n\r\n/** Add two vectors */\r\nexport function addVec(a: Readonly<Vector2>, b: Readonly<Vector2>): Vector2 {\r\n\treturn { x: a.x + b.x, y: a.y + b.y }\r\n}\r\n\r\n/** Subtract vector b from vector a */\r\nexport function subVec(a: Readonly<Vector2>, b: Readonly<Vector2>): Vector2 {\r\n\treturn { x: a.x - b.x, y: a.y - b.y }\r\n}\r\n\r\n/** Scale a vector by a scalar */\r\nexport function scaleVec(v: Readonly<Vector2>, scalar: number): Vector2 {\r\n\treturn { x: v.x * scalar, y: v.y * scalar }\r\n}\r\n\r\n/** Dot product of two vectors */\r\nexport function dotVec(a: Readonly<Vector2>, b: Readonly<Vector2>): number {\r\n\treturn a.x * b.x + a.y * b.y\r\n}\r\n\r\n/** Cross product (z-component) of two 2D vectors */\r\nexport function crossVec(a: Readonly<Vector2>, b: Readonly<Vector2>): number {\r\n\treturn a.x * b.y - a.y * b.x\r\n}\r\n\r\n/** Rotate a vector by an angle in radians */\r\nexport function rotateVec(v: Readonly<Vector2>, angle: number): Vector2 {\r\n\tconst cos = Math.cos(angle)\r\n\tconst sin = Math.sin(angle)\r\n\treturn {\r\n\t\tx: v.x * cos - v.y * sin,\r\n\t\ty: v.x * sin + v.y * cos,\r\n\t}\r\n}\r\n\r\n/** Get the perpendicular vector (rotate 90 degrees counter-clockwise) */\r\nexport function perpVec(v: Readonly<Vector2>): Vector2 {\r\n\treturn { x: -v.y, y: v.x }\r\n}\r\n\r\n/** Reflect a vector off a surface with the given normal */\r\nexport function reflectVec(v: Readonly<Vector2>, normal: Readonly<Vector2>): Vector2 {\r\n\tconst d = 2 * dotVec(v, normal)\r\n\treturn { x: v.x - d * normal.x, y: v.y - d * normal.y }\r\n}\r\n\r\n// ============================================================================\r\n// Math: Clamping & Bounds\r\n// ============================================================================\r\n\r\n/** Clamp a position within rectangular bounds */\r\nexport function clampToRectangle(\r\n\tx: number,\r\n\ty: number,\r\n\tminX: number,\r\n\tminY: number,\r\n\tmaxX: number,\r\n\tmaxY: number,\r\n): Vector2 {\r\n\treturn {\r\n\t\tx: clamp(x, minX, maxX),\r\n\t\ty: clamp(y, minY, maxY),\r\n\t}\r\n}\r\n\r\n/** Clamp a position within world bounds accounting for EntityInterface size */\r\nexport function clampToWorld(\r\n\tx: number,\r\n\ty: number,\r\n\tentitySize: number,\r\n\tworldWidth: number,\r\n\tworldHeight: number,\r\n): Vector2 {\r\n\tconst halfSize = entitySize / 2\r\n\treturn {\r\n\t\tx: clamp(x, halfSize, worldWidth - halfSize),\r\n\t\ty: clamp(y, halfSize, worldHeight - halfSize),\r\n\t}\r\n}\r\n\r\n/** Wrap a value to stay within a range (e.g., for screen wrapping) */\r\nexport function wrap(value: number, min: number, max: number): number {\r\n\tconst range = max - min\r\n\tif (range === 0) return min\r\n\treturn ((((value - min) % range) + range) % range) + min\r\n}\r\n\r\n/** Wrap a position within world bounds */\r\nexport function wrapToWorld(\r\n\tx: number,\r\n\ty: number,\r\n\tworldWidth: number,\r\n\tworldHeight: number,\r\n): Vector2 {\r\n\treturn {\r\n\t\tx: wrap(x, 0, worldWidth),\r\n\t\ty: wrap(y, 0, worldHeight),\r\n\t}\r\n}\r\n\r\n// ============================================================================\r\n// Math: Interpolation & Easing\r\n// ============================================================================\r\n\r\n/** Linear interpolation between two vectors */\r\nexport function lerpVec(a: Readonly<Vector2>, b: Readonly<Vector2>, t: number): Vector2 {\r\n\treturn {\r\n\t\tx: lerp(a.x, b.x, t),\r\n\t\ty: lerp(a.y, b.y, t),\r\n\t}\r\n}\r\n\r\n/** Smooth step interpolation (ease in-out) */\r\nexport function smoothstep(t: number): number {\r\n\tconst clamped = clamp(t, 0, 1)\r\n\treturn clamped * clamped * (3 - 2 * clamped)\r\n}\r\n\r\n/** Smoother step interpolation (Ken Perlin's version) */\r\nexport function smootherstep(t: number): number {\r\n\tconst clamped = clamp(t, 0, 1)\r\n\treturn clamped * clamped * clamped * (clamped * (clamped * 6 - 15) + 10)\r\n}\r\n\r\n/** Inverse linear interpolation (find t given value between a and b) */\r\nexport function inverseLerp(a: number, b: number, value: number): number {\r\n\tif (a === b) return 0\r\n\treturn (value - a) / (b - a)\r\n}\r\n\r\n/** Remap a value from one range to another */\r\nexport function remap(\r\n\tvalue: number,\r\n\tinMin: number,\r\n\tinMax: number,\r\n\toutMin: number,\r\n\toutMax: number,\r\n): number {\r\n\tconst t = inverseLerp(inMin, inMax, value)\r\n\treturn lerp(outMin, outMax, t)\r\n}\r\n\r\n/** Approach a target value by a fixed step (for smooth movement) */\r\nexport function approach(current: number, target: number, step: number): number {\r\n\tif (current < target) {\r\n\t\treturn Math.min(current + step, target)\r\n\t} else {\r\n\t\treturn Math.max(current - step, target)\r\n\t}\r\n}\r\n\r\n/** Damped approach (exponential decay) */\r\nexport function damp(current: number, target: number, smoothing: number, deltaTime: number): number {\r\n\treturn lerp(current, target, 1 - Math.exp(-smoothing * deltaTime))\r\n}\r\n\r\n/** Damped approach for vectors */\r\nexport function dampVec(\r\n\tcurrent: Readonly<Vector2>,\r\n\ttarget: Readonly<Vector2>,\r\n\tsmoothing: number,\r\n\tdeltaTime: number,\r\n): Vector2 {\r\n\tconst t = 1 - Math.exp(-smoothing * deltaTime)\r\n\treturn lerpVec(current, target, t)\r\n}\r\n\r\n// ============================================================================\r\n// Math: Random\r\n// ============================================================================\r\n\r\n/** Random float between min and max */\r\nexport function randomRange(min: number, max: number): number {\r\n\treturn min + Math.random() * (max - min)\r\n}\r\n\r\n/** Random integer between min and max (inclusive) */\r\nexport function randomInt(min: number, max: number): number {\r\n\treturn Math.floor(randomRange(min, max + 1))\r\n}\r\n\r\n/** Random element from array */\r\nexport function randomElement<T>(array: readonly T[]): T | undefined {\r\n\tif (array.length === 0) return undefined\r\n\treturn array[Math.floor(Math.random() * array.length)]\r\n}\r\n\r\n/** Random position within rectangular bounds */\r\nexport function randomPosition(\r\n\tminX: number,\r\n\tmaxX: number,\r\n\tminY: number,\r\n\tmaxY: number,\r\n): Vector2 {\r\n\treturn {\r\n\t\tx: randomRange(minX, maxX),\r\n\t\ty: randomRange(minY, maxY),\r\n\t}\r\n}\r\n\r\n/** Random position on the edge of a rectangle (for spawning offscreen) */\r\nexport function randomEdgePosition(\r\n\twidth: number,\r\n\theight: number,\r\n\tmargin: number = 0,\r\n\toffset: number = -24,\r\n): Vector2 {\r\n\tconst side = randomInt(0, 3)\r\n\r\n\tswitch (side) {\r\n\t\tcase 0: // Top\r\n\t\t\treturn { x: randomRange(margin, width - margin), y: offset }\r\n\t\tcase 1: // Right\r\n\t\t\treturn { x: width - offset, y: randomRange(margin, height - margin) }\r\n\t\tcase 2: // Bottom\r\n\t\t\treturn { x: randomRange(margin, width - margin), y: height - offset }\r\n\t\tdefault: // Left\r\n\t\t\treturn { x: offset, y: randomRange(margin, height - margin) }\r\n\t}\r\n}\r\n\r\n/** Random point inside a circle */\r\nexport function randomInCircle(centerX: number, centerY: number, radius: number): Vector2 {\r\n\tconst angle = Math.random() * Math.PI * 2\r\n\tconst r = radius * Math.sqrt(Math.random())\r\n\treturn {\r\n\t\tx: centerX + r * Math.cos(angle),\r\n\t\ty: centerY + r * Math.sin(angle),\r\n\t}\r\n}\r\n\r\n/** Random point on the circumference of a circle */\r\nexport function randomOnCircle(centerX: number, centerY: number, radius: number): Vector2 {\r\n\tconst angle = Math.random() * Math.PI * 2\r\n\treturn {\r\n\t\tx: centerX + radius * Math.cos(angle),\r\n\t\ty: centerY + radius * Math.sin(angle),\r\n\t}\r\n}\r\n\r\n/** Random unit vector (direction) */\r\nexport function randomDirection(): Vector2 {\r\n\tconst angle = Math.random() * Math.PI * 2\r\n\treturn { x: Math.cos(angle), y: Math.sin(angle) }\r\n}\r\n\r\n/** Random sign (-1 or 1) */\r\nexport function randomSign(): number {\r\n\treturn Math.random() < 0.5 ? -1 : 1\r\n}\r\n\r\n/** Random boolean with optional probability */\r\nexport function randomBool(probability: number = 0.5): boolean {\r\n\treturn Math.random() < probability\r\n}\r\n\r\n// ============================================================================\r\n// Math: Collision Detection\r\n// ============================================================================\r\n\r\n/** Check if two circles overlap */\r\nexport function circlesOverlap(\r\n\tx1: number,\r\n\ty1: number,\r\n\tr1: number,\r\n\tx2: number,\r\n\ty2: number,\r\n\tr2: number,\r\n): boolean {\r\n\tconst combinedRadius = r1 + r2\r\n\treturn distanceSquared(x1, y1, x2, y2) < combinedRadius * combinedRadius\r\n}\r\n\r\n/** Check if a point is within a circle */\r\nexport function pointInCircle(\r\n\tpx: number,\r\n\tpy: number,\r\n\tcx: number,\r\n\tcy: number,\r\n\tradius: number,\r\n): boolean {\r\n\treturn distanceSquared(px, py, cx, cy) < radius * radius\r\n}\r\n\r\n/** Check if a point is within a rectangle */\r\nexport function pointInRectangle(\r\n\tpx: number,\r\n\tpy: number,\r\n\trx: number,\r\n\try: number,\r\n\trw: number,\r\n\trh: number,\r\n): boolean {\r\n\treturn px >= rx && px <= rx + rw && py >= ry && py <= ry + rh\r\n}\r\n\r\n/** Check if two rectangles overlap */\r\nexport function rectsOverlap(\r\n\tx1: number,\r\n\ty1: number,\r\n\tw1: number,\r\n\th1: number,\r\n\tx2: number,\r\n\ty2: number,\r\n\tw2: number,\r\n\th2: number,\r\n): boolean {\r\n\treturn x1 < x2 + w2 && x1 + w1 > x2 && y1 < y2 + h2 && y1 + h1 > y2\r\n}\r\n\r\n/** Check if a circle and rectangle overlap */\r\nexport function circleRectangleOverlap(\r\n\tcx: number,\r\n\tcy: number,\r\n\tradius: number,\r\n\trx: number,\r\n\try: number,\r\n\trw: number,\r\n\trh: number,\r\n): boolean {\r\n\tconst nearestX = clamp(cx, rx, rx + rw)\r\n\tconst nearestY = clamp(cy, ry, ry + rh)\r\n\treturn distanceSquared(cx, cy, nearestX, nearestY) < radius * radius\r\n}\r\n\r\n// ============================================================================\r\n// Math: Angle Utilities\r\n// ============================================================================\r\n\r\n/** Convert degrees to radians */\r\nexport function degToRad(degrees: number): number {\r\n\treturn degrees * (Math.PI / 180)\r\n}\r\n\r\n/** Convert radians to degrees */\r\nexport function radToDeg(radians: number): number {\r\n\treturn radians * (180 / Math.PI)\r\n}\r\n\r\n/** Normalize an angle to the range [-PI, PI] */\r\nexport function normalizeAngle(angle: number): number {\r\n\twhile (angle > Math.PI) angle -= Math.PI * 2\r\n\twhile (angle < -Math.PI) angle += Math.PI * 2\r\n\treturn angle\r\n}\r\n\r\n/** Get the shortest angular distance between two angles */\r\nexport function angleDifference(from: number, to: number): number {\r\n\treturn normalizeAngle(to - from)\r\n}\r\n\r\n/** Lerp between two angles taking the shortest path */\r\nexport function lerpAngle(from: number, to: number, t: number): number {\r\n\tconst diff = angleDifference(from, to)\r\n\treturn from + diff * t\r\n}\r\n\r\n/** Rotate toward a target angle by a maximum step */\r\nexport function rotateToward(current: number, target: number, maxStep: number): number {\r\n\tconst diff = angleDifference(current, target)\r\n\tif (Math.abs(diff) <= maxStep) return target\r\n\treturn current + Math.sign(diff) * maxStep\r\n}\r\n","import type {\r\n\tEntityInterface,\r\n\tEntityOptions,\r\n\tEntityBounds,\r\n\tEntityTransform,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\nimport { generateId, clamp } from '../../helpers.js'\r\n\r\n/**\r\n * Entity implementation for game objects.\r\n * Base class for all game entities with transform, visibility, and lifecycle.\r\n */\r\nexport class Entity implements EntityInterface {\r\n\treadonly id: string\r\n\t#x: number\r\n\t#y: number\r\n\t#width: number\r\n\t#height: number\r\n\t#rotation: number\r\n\t#scaleX: number\r\n\t#scaleY: number\r\n\t#opacity: number\r\n\t#zIndex: number\r\n\t#visible: boolean\r\n\t#interactive: boolean\r\n\t#created = false\r\n\r\n\t#listeners = {\r\n\t\tcreate: new Set<() => void>(),\r\n\t\tdestroy: new Set<() => void>(),\r\n\t\tupdate: new Set<(deltaTime: number) => void>(),\r\n\t\trender: new Set<(context: CanvasRenderingContext2D) => void>(),\r\n\t\tcollision: new Set<(other: Entity) => void>(),\r\n\t}\r\n\r\n\tconstructor(options: EntityOptions = {}) {\r\n\t\tthis.id = options.id ?? generateId()\r\n\t\tthis.#x = options.x ?? 0\r\n\t\tthis.#y = options.y ?? 0\r\n\t\tthis.#width = options.width ?? 0\r\n\t\tthis.#height = options.height ?? 0\r\n\t\tthis.#rotation = options.rotation ?? 0\r\n\t\tthis.#scaleX = options.scaleX ?? 1\r\n\t\tthis.#scaleY = options.scaleY ?? 1\r\n\t\tthis.#opacity = clamp(options.opacity ?? 1, 0, 1)\r\n\t\tthis.#visible = options.visible ?? true\r\n\t\tthis.#interactive = options.interactive ?? false\r\n\t\tthis.#zIndex = options.zIndex ?? 0\r\n\r\n\t\t// Register hooks from options\r\n\t\tif (options.onCreate) this.#listeners.create.add(options.onCreate)\r\n\t\tif (options.onDestroy) this.#listeners.destroy.add(options.onDestroy)\r\n\t\tif (options.onUpdate) this.#listeners.update.add(options.onUpdate)\r\n\t\tif (options.onRender) this.#listeners.render.add(options.onRender)\r\n\t\tif (options.onCollision) this.#listeners.collision.add(options.onCollision)\r\n\r\n\t\t// Trigger create callbacks\r\n\t\tthis.#triggerCreate()\r\n\t}\r\n\r\n\tgetX(): number {\r\n\t\treturn this.#x\r\n\t}\r\n\r\n\tgetY(): number {\r\n\t\treturn this.#y\r\n\t}\r\n\r\n\tgetWidth(): number {\r\n\t\treturn this.#width\r\n\t}\r\n\r\n\tgetHeight(): number {\r\n\t\treturn this.#height\r\n\t}\r\n\r\n\tgetRotation(): number {\r\n\t\treturn this.#rotation\r\n\t}\r\n\r\n\tgetScaleX(): number {\r\n\t\treturn this.#scaleX\r\n\t}\r\n\r\n\tgetScaleY(): number {\r\n\t\treturn this.#scaleY\r\n\t}\r\n\r\n\tgetOpacity(): number {\r\n\t\treturn this.#opacity\r\n\t}\r\n\r\n\tgetZIndex(): number {\r\n\t\treturn this.#zIndex\r\n\t}\r\n\r\n\tisVisible(): boolean {\r\n\t\treturn this.#visible\r\n\t}\r\n\r\n\tisInteractive(): boolean {\r\n\t\treturn this.#interactive\r\n\t}\r\n\r\n\tgetBounds(): EntityBounds {\r\n\t\t// Calculate scaled dimensions\r\n\t\tconst scaledWidth = this.#width * Math.abs(this.#scaleX)\r\n\t\tconst scaledHeight = this.#height * Math.abs(this.#scaleY)\r\n\r\n\t\treturn {\r\n\t\t\tleft: this.#x,\r\n\t\t\tright: this.#x + scaledWidth,\r\n\t\t\ttop: this.#y,\r\n\t\t\tbottom: this.#y + scaledHeight,\r\n\t\t\twidth: scaledWidth,\r\n\t\t\theight: scaledHeight,\r\n\t\t}\r\n\t}\r\n\r\n\tgetTransform(): EntityTransform {\r\n\t\treturn {\r\n\t\t\tposition: { x: this.#x, y: this.#y },\r\n\t\t\trotation: this.#rotation,\r\n\t\t\tscale: { x: this.#scaleX, y: this.#scaleY },\r\n\t\t\tx: this.#x,\r\n\t\t\ty: this.#y,\r\n\t\t\tscaleX: this.#scaleX,\r\n\t\t\tscaleY: this.#scaleY,\r\n\t\t}\r\n\t}\r\n\r\n\tsetX(x: number): void {\r\n\t\tthis.#x = x\r\n\t}\r\n\r\n\tsetY(y: number): void {\r\n\t\tthis.#y = y\r\n\t}\r\n\r\n\tsetPosition(x: number, y: number): void {\r\n\t\tthis.#x = x\r\n\t\tthis.#y = y\r\n\t}\r\n\r\n\tsetWidth(width: number): void {\r\n\t\tthis.#width = Math.max(0, width)\r\n\t}\r\n\r\n\tsetHeight(height: number): void {\r\n\t\tthis.#height = Math.max(0, height)\r\n\t}\r\n\r\n\tsetSize(width: number, height: number): void {\r\n\t\tthis.#width = Math.max(0, width)\r\n\t\tthis.#height = Math.max(0, height)\r\n\t}\r\n\r\n\tsetRotation(rotation: number): void {\r\n\t\tthis.#rotation = rotation\r\n\t}\r\n\r\n\tsetScaleX(scaleX: number): void {\r\n\t\tthis.#scaleX = scaleX\r\n\t}\r\n\r\n\tsetScaleY(scaleY: number): void {\r\n\t\tthis.#scaleY = scaleY\r\n\t}\r\n\r\n\tsetScale(scale: number): void {\r\n\t\tthis.#scaleX = scale\r\n\t\tthis.#scaleY = scale\r\n\t}\r\n\r\n\tsetOpacity(opacity: number): void {\r\n\t\tthis.#opacity = clamp(opacity, 0, 1)\r\n\t}\r\n\r\n\tsetZIndex(zIndex: number): void {\r\n\t\tthis.#zIndex = zIndex\r\n\t}\r\n\r\n\tsetVisible(visible: boolean): void {\r\n\t\tthis.#visible = visible\r\n\t}\r\n\r\n\tsetInteractive(interactive: boolean): void {\r\n\t\tthis.#interactive = interactive\r\n\t}\r\n\r\n\tmove(deltaX: number, deltaY: number): void {\r\n\t\tthis.#x += deltaX\r\n\t\tthis.#y += deltaY\r\n\t}\r\n\r\n\trotate(deltaRotation: number): void {\r\n\t\tthis.#rotation += deltaRotation\r\n\t}\r\n\r\n\tscale(deltaScale: number): void {\r\n\t\tthis.#scaleX += deltaScale\r\n\t\tthis.#scaleY += deltaScale\r\n\t}\r\n\r\n\tshow(): void {\r\n\t\tthis.#visible = true\r\n\t}\r\n\r\n\thide(): void {\r\n\t\tthis.#visible = false\r\n\t}\r\n\r\n\t/**\r\n\t * Called each frame to update entity state.\r\n\t * Override in subclasses or use onUpdate subscription.\r\n\t */\r\n\tupdate(deltaTime: number): void {\r\n\t\tthis.#listeners.update.forEach(cb => cb(deltaTime))\r\n\t}\r\n\r\n\t/**\r\n\t * Called each frame to render the entity.\r\n\t * Override in subclasses or use onRender subscription.\r\n\t */\r\n\trender(context: CanvasRenderingContext2D): void {\r\n\t\tif (!this.#visible || this.#opacity <= 0) return\r\n\r\n\t\tcontext.save()\r\n\r\n\t\t// Apply transform\r\n\t\tcontext.translate(this.#x, this.#y)\r\n\t\tcontext.rotate(this.#rotation)\r\n\t\tcontext.scale(this.#scaleX, this.#scaleY)\r\n\t\tcontext.globalAlpha = this.#opacity\r\n\r\n\t\t// Call render listeners\r\n\t\tthis.#listeners.render.forEach(cb => cb(context))\r\n\r\n\t\tcontext.restore()\r\n\t}\r\n\r\n\t/**\r\n\t * Called when a collision is detected with another entity.\r\n\t */\r\n\thandleCollision(other: Entity): void {\r\n\t\tthis.#listeners.collision.forEach(cb => cb(other))\r\n\t}\r\n\r\n\tonCreate(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.create.add(callback)\r\n\t\t// If already created, call immediately\r\n\t\tif (this.#created) {\r\n\t\t\tcallback()\r\n\t\t}\r\n\t\treturn () => this.#listeners.create.delete(callback)\r\n\t}\r\n\r\n\tonDestroy(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.destroy.add(callback)\r\n\t\treturn () => this.#listeners.destroy.delete(callback)\r\n\t}\r\n\r\n\tonUpdate(callback: (deltaTime: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.update.add(callback)\r\n\t\treturn () => this.#listeners.update.delete(callback)\r\n\t}\r\n\r\n\tonRender(callback: (context: CanvasRenderingContext2D) => void): Unsubscribe {\r\n\t\tthis.#listeners.render.add(callback)\r\n\t\treturn () => this.#listeners.render.delete(callback)\r\n\t}\r\n\r\n\tonCollision(callback: (other: Entity) => void): Unsubscribe {\r\n\t\tthis.#listeners.collision.add(callback)\r\n\t\treturn () => this.#listeners.collision.delete(callback)\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\t// Trigger destroy callbacks\r\n\t\tthis.#listeners.destroy.forEach(cb => cb())\r\n\r\n\t\t// Clear all listeners\r\n\t\tthis.#listeners.create.clear()\r\n\t\tthis.#listeners.destroy.clear()\r\n\t\tthis.#listeners.update.clear()\r\n\t\tthis.#listeners.render.clear()\r\n\t\tthis.#listeners.collision.clear()\r\n\t}\r\n\r\n\t#triggerCreate(): void {\r\n\t\tif (this.#created) return\r\n\t\tthis.#created = true\r\n\t\tthis.#listeners.create.forEach(cb => cb())\r\n\t}\r\n}\r\n","/**\r\n * TimerManager - Manages game-time-aware timers and delays.\r\n *\r\n * Features:\r\n * - Track timers in game-time (pauses with engine)\r\n * - Supports one-shot and repeating timers\r\n * - Provides promise-based delay() for async/await\r\n * - Named timers for easy cancellation\r\n */\r\nimport type {\r\n\tTimerManagerInterface,\r\n\tTimerManagerOptions,\r\n\tTimerEntry,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\n/** Internal timer entry with mutable state */\r\ninterface MutableTimerEntry extends TimerEntry {\r\n\tremaining: number\r\n\tpaused: boolean\r\n}\r\n\r\n/**\r\n * Game timer manager implementation.\r\n */\r\nexport class TimerManager implements TimerManagerInterface {\r\n\treadonly #timers = new Map<string, MutableTimerEntry>()\r\n\treadonly #fireListeners = new Set<(timerId: string) => void>()\r\n\treadonly #pauseWithEngine: boolean\r\n\t#nextId = 1\r\n\t#globalPaused = false\r\n\r\n\tconstructor(options?: TimerManagerOptions) {\r\n\t\tthis.#pauseWithEngine = options?.pauseWithEngine ?? true\r\n\r\n\t\tif (options?.onFire) {\r\n\t\t\tthis.#fireListeners.add(options.onFire)\r\n\t\t}\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Timer Creation\r\n\t// ============================================================================\r\n\r\n\tsetTimeout(callback: () => void, delayMs: number, id?: string): string {\r\n\t\tconst timerId = id ?? `timer-${this.#nextId++}`\r\n\r\n\t\tconst entry: MutableTimerEntry = {\r\n\t\t\tid: timerId,\r\n\t\t\tcallback,\r\n\t\t\tinterval: delayMs,\r\n\t\t\trepeat: false,\r\n\t\t\tremaining: delayMs,\r\n\t\t\tpaused: false,\r\n\t\t}\r\n\r\n\t\tthis.#timers.set(timerId, entry)\r\n\t\treturn timerId\r\n\t}\r\n\r\n\tsetInterval(callback: () => void, intervalMs: number, id?: string): string {\r\n\t\tconst timerId = id ?? `interval-${this.#nextId++}`\r\n\r\n\t\tconst entry: MutableTimerEntry = {\r\n\t\t\tid: timerId,\r\n\t\t\tcallback,\r\n\t\t\tinterval: intervalMs,\r\n\t\t\trepeat: true,\r\n\t\t\tremaining: intervalMs,\r\n\t\t\tpaused: false,\r\n\t\t}\r\n\r\n\t\tthis.#timers.set(timerId, entry)\r\n\t\treturn timerId\r\n\t}\r\n\r\n\tdelay(ms: number): Promise<void> {\r\n\t\treturn new Promise<void>((resolve) => {\r\n\t\t\tthis.setTimeout(resolve, ms)\r\n\t\t})\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Timer Control\r\n\t// ============================================================================\r\n\r\n\tclear(id: string): boolean {\r\n\t\treturn this.#timers.delete(id)\r\n\t}\r\n\r\n\tclearAll(): void {\r\n\t\tthis.#timers.clear()\r\n\t}\r\n\r\n\tpause(id?: string): void {\r\n\t\tif (id === undefined) {\r\n\t\t\tthis.#globalPaused = true\r\n\t\t} else {\r\n\t\t\tconst timer = this.#timers.get(id)\r\n\t\t\tif (timer) {\r\n\t\t\t\ttimer.paused = true\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tresume(id?: string): void {\r\n\t\tif (id === undefined) {\r\n\t\t\tthis.#globalPaused = false\r\n\t\t} else {\r\n\t\t\tconst timer = this.#timers.get(id)\r\n\t\t\tif (timer) {\r\n\t\t\t\ttimer.paused = false\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tisPaused(id: string): boolean {\r\n\t\tconst timer = this.#timers.get(id)\r\n\t\tif (!timer) return false\r\n\t\treturn timer.paused || this.#globalPaused\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Timer State\r\n\t// ============================================================================\r\n\r\n\tgetRemaining(id: string): number | undefined {\r\n\t\tconst timer = this.#timers.get(id)\r\n\t\treturn timer?.remaining\r\n\t}\r\n\r\n\thasTimer(id: string): boolean {\r\n\t\treturn this.#timers.has(id)\r\n\t}\r\n\r\n\tgetActiveCount(): number {\r\n\t\treturn this.#timers.size\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Update\r\n\t// ============================================================================\r\n\r\n\tupdate(deltaTime: number): void {\r\n\t\tif (this.#globalPaused) return\r\n\r\n\t\tconst deltaMs = deltaTime * 1000\r\n\t\tconst toRemove: string[] = []\r\n\r\n\t\tfor (const [id, timer] of this.#timers) {\r\n\t\t\tif (timer.paused) continue\r\n\r\n\t\t\ttimer.remaining -= deltaMs\r\n\r\n\t\t\tif (timer.remaining <= 0) {\r\n\t\t\t\t// Fire the callback\r\n\t\t\t\ttry {\r\n\t\t\t\t\ttimer.callback()\r\n\t\t\t\t} catch {\r\n\t\t\t\t\t// Ignore callback errors\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Notify listeners\r\n\t\t\t\tfor (const listener of this.#fireListeners) {\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tlistener(id)\r\n\t\t\t\t\t} catch {\r\n\t\t\t\t\t\t// Ignore listener errors\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (timer.repeat) {\r\n\t\t\t\t\t// Reset for next interval\r\n\t\t\t\t\ttimer.remaining = timer.interval + timer.remaining\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// Mark for removal\r\n\t\t\t\t\ttoRemove.push(id)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Clean up completed one-shot timers\r\n\t\tfor (const id of toRemove) {\r\n\t\t\tthis.#timers.delete(id)\r\n\t\t}\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Subscriptions\r\n\t// ============================================================================\r\n\r\n\tonFire(callback: (timerId: string) => void): Unsubscribe {\r\n\t\tthis.#fireListeners.add(callback)\r\n\t\treturn () => this.#fireListeners.delete(callback)\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Lifecycle\r\n\t// ============================================================================\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#timers.clear()\r\n\t\tthis.#fireListeners.clear()\r\n\t}\r\n}\r\n","/**\r\n * TransitionManager - Manages screen transitions between scenes.\r\n *\r\n * Features:\r\n * - Fade, slide, zoom transitions\r\n * - Scene transitions with promises\r\n * - Configurable duration and easing\r\n */\r\nimport type {\r\n\tTransitionManagerInterface,\r\n\tTransitionManagerOptions,\r\n\tTransitionOptions,\r\n\tTransitionState,\r\n\tTransitionType,\r\n\tSceneManagerInterface,\r\n\tSceneInterface,\r\n\tEasingType,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\n/** Easing function for smooth transitions */\r\nfunction easeInOutQuad(t: number): number {\r\n\treturn t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2\r\n}\r\n\r\n/**\r\n * Game transition manager implementation.\r\n */\r\nexport class TransitionManager implements TransitionManagerInterface {\r\n\treadonly #sceneManager: SceneManagerInterface\r\n\treadonly #startListeners = new Set<(type: TransitionType) => void>()\r\n\treadonly #halfwayListeners = new Set<() => void>()\r\n\treadonly #completeListeners = new Set<() => void>()\r\n\treadonly #defaultType: TransitionType\r\n\treadonly #defaultDuration: number\r\n\treadonly #defaultEasing: EasingType\r\n\r\n\t#isActive = false\r\n\t#currentType: TransitionType = 'fade'\r\n\t#progress = 0\r\n\t#phase: 'out' | 'in' = 'out'\r\n\t#duration = 0\r\n\t#elapsed = 0\r\n\t#color = '#000000'\r\n\t#halfwayFired = false\r\n\t#resolveTransition: (() => void) | undefined\r\n\r\n\tconstructor(sceneManager: SceneManagerInterface, options?: TransitionManagerOptions) {\r\n\t\tthis.#sceneManager = sceneManager\r\n\t\tthis.#defaultType = options?.defaultType ?? 'fade'\r\n\t\tthis.#defaultDuration = options?.defaultDuration ?? 500\r\n\t\tthis.#defaultEasing = options?.defaultEasing ?? 'linear'\r\n\r\n\t\tif (options?.onStart) {\r\n\t\t\tthis.#startListeners.add(options.onStart)\r\n\t\t}\r\n\t\tif (options?.onHalfway) {\r\n\t\t\tthis.#halfwayListeners.add(options.onHalfway)\r\n\t\t}\r\n\t\tif (options?.onComplete) {\r\n\t\t\tthis.#completeListeners.add(options.onComplete)\r\n\t\t}\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// State\r\n\t// ============================================================================\r\n\r\n\tgetState(): TransitionState {\r\n\t\treturn {\r\n\t\t\tisActive: this.#isActive,\r\n\t\t\ttype: this.#currentType,\r\n\t\t\tprogress: this.#progress,\r\n\t\t\tphase: this.#phase,\r\n\t\t}\r\n\t}\r\n\r\n\tisActive(): boolean {\r\n\t\treturn this.#isActive\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Transitions\r\n\t// ============================================================================\r\n\r\n\ttransition(options?: Partial<TransitionOptions>): Promise<void> {\r\n\t\treturn new Promise((resolve) => {\r\n\t\t\tthis.#startTransition({\r\n\t\t\t\ttype: options?.type ?? this.#defaultType,\r\n\t\t\t\tduration: options?.duration ?? this.#defaultDuration,\r\n\t\t\t\tcolor: options?.color ?? '#000000',\r\n\t\t\t}, resolve)\r\n\t\t})\r\n\t}\r\n\r\n\tasync transitionTo(scene: SceneInterface, options?: Partial<TransitionOptions>): Promise<void> {\r\n\t\tconst opts = {\r\n\t\t\ttype: options?.type ?? this.#defaultType,\r\n\t\t\tduration: options?.duration ?? this.#defaultDuration,\r\n\t\t\tcolor: options?.color ?? '#000000',\r\n\t\t}\r\n\r\n\t\treturn new Promise((resolve) => {\r\n\t\t\tthis.#startTransition(opts, async() => {\r\n\t\t\t\t// At halfway point, switch scenes\r\n\t\t\t\tawait this.#sceneManager.setActiveScene(scene.name)\r\n\t\t\t\tresolve()\r\n\t\t\t})\r\n\t\t})\r\n\t}\r\n\r\n\tfadeIn(duration?: number, color?: string): Promise<void> {\r\n\t\treturn this.transition({\r\n\t\t\ttype: 'fade',\r\n\t\t\tduration: duration ?? this.#defaultDuration,\r\n\t\t\tcolor: color ?? '#000000',\r\n\t\t})\r\n\t}\r\n\r\n\tfadeOut(duration?: number, color?: string): Promise<void> {\r\n\t\treturn this.transition({\r\n\t\t\ttype: 'fade',\r\n\t\t\tduration: duration ?? this.#defaultDuration,\r\n\t\t\tcolor: color ?? '#000000',\r\n\t\t})\r\n\t}\r\n\r\n\tfadeToBlack(duration?: number): Promise<void> {\r\n\t\treturn this.fadeOut(duration, '#000000')\r\n\t}\r\n\r\n\tfadeFromBlack(duration?: number): Promise<void> {\r\n\t\treturn this.fadeIn(duration, '#000000')\r\n\t}\r\n\r\n\tcancel(): void {\r\n\t\tif (this.#isActive) {\r\n\t\t\tthis.#isActive = false\r\n\t\t\tthis.#progress = 0\r\n\t\t\tthis.#resolveTransition?.()\r\n\t\t\tthis.#resolveTransition = undefined\r\n\t\t}\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Update\r\n\t// ============================================================================\r\n\r\n\tupdate(deltaTime: number): void {\r\n\t\tif (!this.#isActive) return\r\n\r\n\t\tconst deltaMs = deltaTime * 1000\r\n\t\tthis.#elapsed += deltaMs\r\n\r\n\t\tconst halfDuration = this.#duration / 2\r\n\r\n\t\tif (this.#phase === 'out') {\r\n\t\t\tthis.#progress = Math.min(1, this.#elapsed / halfDuration)\r\n\r\n\t\t\tif (this.#elapsed >= halfDuration) {\r\n\t\t\t\t// Halfway point\r\n\t\t\t\tif (!this.#halfwayFired) {\r\n\t\t\t\t\tthis.#halfwayFired = true\r\n\t\t\t\t\tthis.#notifyHalfway()\r\n\t\t\t\t}\r\n\t\t\t\tthis.#phase = 'in'\r\n\t\t\t\tthis.#elapsed = 0\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis.#progress = Math.max(0, 1 - this.#elapsed / halfDuration)\r\n\r\n\t\t\tif (this.#elapsed >= halfDuration) {\r\n\t\t\t\t// Complete\r\n\t\t\t\tthis.#isActive = false\r\n\t\t\t\tthis.#progress = 0\r\n\t\t\t\tthis.#notifyComplete()\r\n\t\t\t\tthis.#resolveTransition?.()\r\n\t\t\t\tthis.#resolveTransition = undefined\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Rendering\r\n\t// ============================================================================\r\n\r\n\trender(context: CanvasRenderingContext2D): void {\r\n\t\tif (!this.#isActive) return\r\n\r\n\t\tconst width = context.canvas.width\r\n\t\tconst height = context.canvas.height\r\n\t\tconst easedProgress = easeInOutQuad(this.#progress)\r\n\r\n\t\tcontext.save()\r\n\r\n\t\tswitch (this.#currentType) {\r\n\t\t\tcase 'fade':\r\n\t\t\t\tcontext.globalAlpha = easedProgress\r\n\t\t\t\tcontext.fillStyle = this.#color\r\n\t\t\t\tcontext.fillRect(0, 0, width, height)\r\n\t\t\t\tbreak\r\n\r\n\t\t\tcase 'slide-left':\r\n\t\t\t\tcontext.fillStyle = this.#color\r\n\t\t\t\tcontext.fillRect(0, 0, width * easedProgress, height)\r\n\t\t\t\tbreak\r\n\r\n\t\t\tcase 'slide-right':\r\n\t\t\t\tcontext.fillStyle = this.#color\r\n\t\t\t\tcontext.fillRect(width * (1 - easedProgress), 0, width * easedProgress, height)\r\n\t\t\t\tbreak\r\n\r\n\t\t\tcase 'slide-up':\r\n\t\t\t\tcontext.fillStyle = this.#color\r\n\t\t\t\tcontext.fillRect(0, 0, width, height * easedProgress)\r\n\t\t\t\tbreak\r\n\r\n\t\t\tcase 'slide-down':\r\n\t\t\t\tcontext.fillStyle = this.#color\r\n\t\t\t\tcontext.fillRect(0, height * (1 - easedProgress), width, height * easedProgress)\r\n\t\t\t\tbreak\r\n\r\n\t\t\tcase 'circle-in':\r\n\t\t\tcase 'circle-out': {\r\n\t\t\t\tconst maxRadius = Math.sqrt(width * width + height * height) / 2\r\n\t\t\t\tconst radius = this.#currentType === 'circle-in'\r\n\t\t\t\t\t? maxRadius * easedProgress\r\n\t\t\t\t\t: maxRadius * (1 - easedProgress)\r\n\r\n\t\t\t\tcontext.fillStyle = this.#color\r\n\t\t\t\tcontext.fillRect(0, 0, width, height)\r\n\r\n\t\t\t\tcontext.globalCompositeOperation = 'destination-out'\r\n\t\t\t\tcontext.beginPath()\r\n\t\t\t\tcontext.arc(width / 2, height / 2, radius, 0, Math.PI * 2)\r\n\t\t\t\tcontext.fill()\r\n\t\t\t\tbreak\r\n\t\t\t}\r\n\r\n\t\t\tcase 'zoom-in':\r\n\t\t\tcase 'zoom-out': {\r\n\t\t\t\tconst scale = this.#currentType === 'zoom-in'\r\n\t\t\t\t\t? 1 + easedProgress * 2\r\n\t\t\t\t\t: 1 + (1 - easedProgress) * 2\r\n\r\n\t\t\t\tcontext.translate(width / 2, height / 2)\r\n\t\t\t\tcontext.scale(scale, scale)\r\n\t\t\t\tcontext.translate(-width / 2, -height / 2)\r\n\t\t\t\tcontext.globalAlpha = easedProgress\r\n\t\t\t\tcontext.fillStyle = this.#color\r\n\t\t\t\tcontext.fillRect(0, 0, width, height)\r\n\t\t\t\tbreak\r\n\t\t\t}\r\n\r\n\t\t\tdefault:\r\n\t\t\t\tcontext.globalAlpha = easedProgress\r\n\t\t\t\tcontext.fillStyle = this.#color\r\n\t\t\t\tcontext.fillRect(0, 0, width, height)\r\n\t\t\t\tbreak\r\n\t\t}\r\n\r\n\t\tcontext.restore()\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Subscriptions\r\n\t// ============================================================================\r\n\r\n\tonStart(callback: (type: TransitionType) => void): Unsubscribe {\r\n\t\tthis.#startListeners.add(callback)\r\n\t\treturn () => this.#startListeners.delete(callback)\r\n\t}\r\n\r\n\tonHalfway(callback: () => void): Unsubscribe {\r\n\t\tthis.#halfwayListeners.add(callback)\r\n\t\treturn () => this.#halfwayListeners.delete(callback)\r\n\t}\r\n\r\n\tonComplete(callback: () => void): Unsubscribe {\r\n\t\tthis.#completeListeners.add(callback)\r\n\t\treturn () => this.#completeListeners.delete(callback)\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Private Methods\r\n\t// ============================================================================\r\n\r\n\t#startTransition(opts: { type: TransitionType; duration: number; color: string }, resolve: () => void): void {\r\n\t\tthis.#isActive = true\r\n\t\tthis.#currentType = opts.type\r\n\t\tthis.#duration = opts.duration\r\n\t\tthis.#color = opts.color\r\n\t\tthis.#phase = 'out'\r\n\t\tthis.#progress = 0\r\n\t\tthis.#elapsed = 0\r\n\t\tthis.#halfwayFired = false\r\n\t\tthis.#resolveTransition = resolve\r\n\r\n\t\tthis.#notifyStart(opts.type)\r\n\t}\r\n\r\n\t#notifyStart(type: TransitionType): void {\r\n\t\tfor (const listener of this.#startListeners) {\r\n\t\t\ttry {\r\n\t\t\t\tlistener(type)\r\n\t\t\t} catch {\r\n\t\t\t\t// Ignore listener errors\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t#notifyHalfway(): void {\r\n\t\tfor (const listener of this.#halfwayListeners) {\r\n\t\t\ttry {\r\n\t\t\t\tlistener()\r\n\t\t\t} catch {\r\n\t\t\t\t// Ignore listener errors\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t#notifyComplete(): void {\r\n\t\tfor (const listener of this.#completeListeners) {\r\n\t\t\ttry {\r\n\t\t\t\tlistener()\r\n\t\t\t} catch {\r\n\t\t\t\t// Ignore listener errors\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Lifecycle\r\n\t// ============================================================================\r\n\r\n\tdestroy(): void {\r\n\t\tthis.cancel()\r\n\t\tthis.#startListeners.clear()\r\n\t\tthis.#halfwayListeners.clear()\r\n\t\tthis.#completeListeners.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tCameraInterface,\r\n\tCameraOptions,\r\n\tCameraState,\r\n\tCameraBounds,\r\n\tEntityInterface,\r\n\tVector2,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Camera for viewport management and world-to-screen transformations.\r\n */\r\nexport class Camera implements CameraInterface {\r\n\t#x: number\r\n\t#y: number\r\n\t#width: number\r\n\t#height: number\r\n\t#zoom: number\r\n\t#rotation = 0\r\n\t#minZoom: number\r\n\t#maxZoom: number\r\n\t#smoothing: number\r\n\t#bounds: CameraBounds | null = null\r\n\t#followTarget: EntityInterface | null = null\r\n\r\n\t// Flash effect state\r\n\t#flashColor: string | null = null\r\n\t#flashDuration = 0\r\n\t#flashStartTime = 0\r\n\r\n\t// Fade effect state\r\n\t#fadeColor: string | null = null\r\n\t#fadeDuration = 0\r\n\t#fadeIn = false\r\n\t#fadeStartTime = 0\r\n\r\n\t#listeners = {\r\n\t\tmove: new Set<(x: number, y: number) => void>(),\r\n\t\tzoom: new Set<(zoom: number) => void>(),\r\n\t\trotate: new Set<(rotation: number) => void>(),\r\n\t\tshake: new Set<() => void>(),\r\n\t}\r\n\r\n\tconstructor(options: CameraOptions) {\r\n\t\tthis.#x = options.x ?? 0\r\n\t\tthis.#y = options.y ?? 0\r\n\t\tthis.#width = options.width\r\n\t\tthis.#height = options.height\r\n\t\tthis.#zoom = options.zoom ?? 1\r\n\t\tthis.#minZoom = options.minZoom ?? 0.1\r\n\t\tthis.#maxZoom = options.maxZoom ?? 10\r\n\t\tthis.#smoothing = options.smoothing ?? 0.1\r\n\r\n\t\t// Register hooks from options\r\n\t\tif (options.onMove) this.#listeners.move.add(options.onMove)\r\n\t\tif (options.onZoom) this.#listeners.zoom.add(options.onZoom)\r\n\t\tif (options.onRotate) this.#listeners.rotate.add(options.onRotate)\r\n\t\tif (options.onShake) this.#listeners.shake.add(options.onShake)\r\n\t}\r\n\r\n\tgetState(): CameraState {\r\n\t\treturn {\r\n\t\t\tx: this.#x,\r\n\t\t\ty: this.#y,\r\n\t\t\twidth: this.#width,\r\n\t\t\theight: this.#height,\r\n\t\t\tzoom: this.#zoom,\r\n\t\t\trotation: this.#rotation,\r\n\t\t}\r\n\t}\r\n\r\n\tgetX(): number {\r\n\t\treturn this.#x\r\n\t}\r\n\r\n\tgetY(): number {\r\n\t\treturn this.#y\r\n\t}\r\n\r\n\tgetWidth(): number {\r\n\t\treturn this.#width\r\n\t}\r\n\r\n\tgetHeight(): number {\r\n\t\treturn this.#height\r\n\t}\r\n\r\n\tgetZoom(): number {\r\n\t\treturn this.#zoom\r\n\t}\r\n\r\n\tgetRotation(): number {\r\n\t\treturn this.#rotation\r\n\t}\r\n\r\n\tgetBounds(): CameraBounds {\r\n\t\treturn this.#bounds ?? {\r\n\t\t\tminX: -Infinity,\r\n\t\t\tmaxX: Infinity,\r\n\t\t\tminY: -Infinity,\r\n\t\t\tmaxY: Infinity,\r\n\t\t}\r\n\t}\r\n\r\n\tsetX(x: number): void {\r\n\t\tthis.#x = x\r\n\t\tthis.#listeners.move.forEach(cb => cb(this.#x, this.#y))\r\n\t}\r\n\r\n\tsetY(y: number): void {\r\n\t\tthis.#y = y\r\n\t\tthis.#listeners.move.forEach(cb => cb(this.#x, this.#y))\r\n\t}\r\n\r\n\tsetPosition(x: number, y: number): void {\r\n\t\tthis.#x = x\r\n\t\tthis.#y = y\r\n\t\tthis.#listeners.move.forEach(cb => cb(x, y))\r\n\t}\r\n\r\n\tsetZoom(zoom: number): void {\r\n\t\tthis.#zoom = Math.max(this.#minZoom, Math.min(this.#maxZoom, zoom))\r\n\t\tthis.#listeners.zoom.forEach(cb => cb(this.#zoom))\r\n\t}\r\n\r\n\tsetRotation(rotation: number): void {\r\n\t\tthis.#rotation = rotation\r\n\t\tthis.#listeners.rotate.forEach(cb => cb(rotation))\r\n\t}\r\n\r\n\tsetBounds(bounds: CameraBounds): void {\r\n\t\tthis.#bounds = bounds\r\n\t}\r\n\r\n\tclearBounds(): void {\r\n\t\tthis.#bounds = null\r\n\t}\r\n\r\n\tmove(deltaX: number, deltaY: number): void {\r\n\t\tthis.#x += deltaX\r\n\t\tthis.#y += deltaY\r\n\t\tthis.#applyBounds()\r\n\t\tthis.#listeners.move.forEach(cb => cb(this.#x, this.#y))\r\n\t}\r\n\r\n\tzoom(deltaZoom: number): void {\r\n\t\tthis.setZoom(this.#zoom + deltaZoom)\r\n\t}\r\n\r\n\trotate(deltaRotation: number): void {\r\n\t\tthis.#rotation += deltaRotation\r\n\t\tthis.#listeners.rotate.forEach(cb => cb(this.#rotation))\r\n\t}\r\n\r\n\tupdate(deltaTime: number): void {\r\n\t\tif (this.#followTarget) {\r\n\t\t\tconst targetX = this.#followTarget.getX() + this.#followTarget.getWidth() / 2\r\n\t\t\tconst targetY = this.#followTarget.getY() + this.#followTarget.getHeight() / 2\r\n\t\t\t// Use deltaTime for frame-rate independent smoothing\r\n\t\t\tconst smoothFactor = 1 - Math.pow(1 - this.#smoothing, deltaTime * 60)\r\n\t\t\tthis.lerp(targetX, targetY, smoothFactor)\r\n\t\t}\r\n\t}\r\n\r\n\tfollow(entity: EntityInterface): void {\r\n\t\tthis.#followTarget = entity\r\n\t}\r\n\r\n\tstopFollow(): void {\r\n\t\tthis.#followTarget = null\r\n\t}\r\n\r\n\tisFollowing(): boolean {\r\n\t\treturn this.#followTarget !== null\r\n\t}\r\n\r\n\tshake(intensity: number, duration: number): void {\r\n\t\tconst startTime = Date.now()\r\n\t\tconst originalX = this.#x\r\n\t\tconst originalY = this.#y\r\n\r\n\t\tconst shakeFrame = (): void => {\r\n\t\t\tconst elapsed = Date.now() - startTime\r\n\t\t\tif (elapsed >= duration) {\r\n\t\t\t\tthis.#x = originalX\r\n\t\t\t\tthis.#y = originalY\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\r\n\t\t\tconst progress = elapsed / duration\r\n\t\t\tconst decay = 1 - progress\r\n\t\t\tconst offsetX = (Math.random() - 0.5) * 2 * intensity * decay\r\n\t\t\tconst offsetY = (Math.random() - 0.5) * 2 * intensity * decay\r\n\r\n\t\t\tthis.#x = originalX + offsetX\r\n\t\t\tthis.#y = originalY + offsetY\r\n\r\n\t\t\trequestAnimationFrame(shakeFrame)\r\n\t\t}\r\n\r\n\t\tthis.#listeners.shake.forEach(cb => cb())\r\n\t\trequestAnimationFrame(shakeFrame)\r\n\t}\r\n\r\n\tflash(color: string, duration: number): void {\r\n\t\t// Flash is handled by rendering layer - store flash state\r\n\t\tthis.#flashColor = color\r\n\t\tthis.#flashDuration = duration\r\n\t\tthis.#flashStartTime = Date.now()\r\n\t}\r\n\r\n\tfade(color: string, duration: number, fadeIn: boolean): void {\r\n\t\t// Fade is handled by rendering layer - store fade state\r\n\t\tthis.#fadeColor = color\r\n\t\tthis.#fadeDuration = duration\r\n\t\tthis.#fadeIn = fadeIn\r\n\t\tthis.#fadeStartTime = Date.now()\r\n\t}\r\n\r\n\tscreenToWorld(screenX: number, screenY: number): Vector2 {\r\n\t\t// Convert screen coordinates to world coordinates accounting for zoom, rotation, position\r\n\t\t// First translate to center origin\r\n\t\tlet x = screenX - this.#width / 2\r\n\t\tlet y = screenY - this.#height / 2\r\n\r\n\t\t// Apply inverse rotation if rotated\r\n\t\tif (this.#rotation !== 0) {\r\n\t\t\tconst cos = Math.cos(-this.#rotation)\r\n\t\t\tconst sin = Math.sin(-this.#rotation)\r\n\t\t\tconst rx = x * cos - y * sin\r\n\t\t\tconst ry = x * sin + y * cos\r\n\t\t\tx = rx\r\n\t\t\ty = ry\r\n\t\t}\r\n\r\n\t\t// Apply inverse zoom and translate to world position\r\n\t\treturn {\r\n\t\t\tx: x / this.#zoom + this.#x,\r\n\t\t\ty: y / this.#zoom + this.#y,\r\n\t\t}\r\n\t}\r\n\r\n\tworldToScreen(worldX: number, worldY: number): Vector2 {\r\n\t\t// Convert world coordinates to screen coordinates accounting for zoom, rotation, position\r\n\t\t// First translate relative to camera and apply zoom\r\n\t\tlet x = (worldX - this.#x) * this.#zoom\r\n\t\tlet y = (worldY - this.#y) * this.#zoom\r\n\r\n\t\t// Apply rotation if rotated\r\n\t\tif (this.#rotation !== 0) {\r\n\t\t\tconst cos = Math.cos(this.#rotation)\r\n\t\t\tconst sin = Math.sin(this.#rotation)\r\n\t\t\tconst rx = x * cos - y * sin\r\n\t\t\tconst ry = x * sin + y * cos\r\n\t\t\tx = rx\r\n\t\t\ty = ry\r\n\t\t}\r\n\r\n\t\t// Translate to screen center\r\n\t\treturn {\r\n\t\t\tx: x + this.#width / 2,\r\n\t\t\ty: y + this.#height / 2,\r\n\t\t}\r\n\t}\r\n\r\n\tcontains(entity: EntityInterface): boolean {\r\n\t\t// Check if entity is in camera view (AABB check, doesn't account for rotation)\r\n\t\tconst bounds = entity.getBounds()\r\n\t\tconst viewLeft = this.#x - this.#width / (2 * this.#zoom)\r\n\t\tconst viewRight = this.#x + this.#width / (2 * this.#zoom)\r\n\t\tconst viewTop = this.#y - this.#height / (2 * this.#zoom)\r\n\t\tconst viewBottom = this.#y + this.#height / (2 * this.#zoom)\r\n\r\n\t\treturn bounds.right > viewLeft &&\r\n\t\t\tbounds.left < viewRight &&\r\n\t\t\tbounds.bottom > viewTop &&\r\n\t\t\tbounds.top < viewBottom\r\n\t}\r\n\r\n\tcontainsPoint(x: number, y: number): boolean {\r\n\t\t// Check if point is in camera view\r\n\t\tconst viewLeft = this.#x - this.#width / (2 * this.#zoom)\r\n\t\tconst viewRight = this.#x + this.#width / (2 * this.#zoom)\r\n\t\tconst viewTop = this.#y - this.#height / (2 * this.#zoom)\r\n\t\tconst viewBottom = this.#y + this.#height / (2 * this.#zoom)\r\n\r\n\t\treturn x > viewLeft && x < viewRight && y > viewTop && y < viewBottom\r\n\t}\r\n\r\n\tlerp(targetX: number, targetY: number, alpha: number): void {\r\n\t\tthis.#x += (targetX - this.#x) * alpha\r\n\t\tthis.#y += (targetY - this.#y) * alpha\r\n\t\tthis.#applyBounds()\r\n\t\tthis.#listeners.move.forEach(cb => cb(this.#x, this.#y))\r\n\t}\r\n\r\n\treset(): void {\r\n\t\tthis.#x = 0\r\n\t\tthis.#y = 0\r\n\t\tthis.#zoom = 1\r\n\t\tthis.#rotation = 0\r\n\t}\r\n\r\n\t#applyBounds(): void {\r\n\t\tif (!this.#bounds) return\r\n\t\tthis.#x = Math.max(this.#bounds.minX, Math.min(this.#bounds.maxX, this.#x))\r\n\t\tthis.#y = Math.max(this.#bounds.minY, Math.min(this.#bounds.maxY, this.#y))\r\n\t}\r\n\r\n\tonMove(callback: (x: number, y: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.move.add(callback)\r\n\t\treturn () => this.#listeners.move.delete(callback)\r\n\t}\r\n\r\n\tonZoom(callback: (zoom: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.zoom.add(callback)\r\n\t\treturn () => this.#listeners.zoom.delete(callback)\r\n\t}\r\n\r\n\tonRotate(callback: (rotation: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.rotate.add(callback)\r\n\t\treturn () => this.#listeners.rotate.delete(callback)\r\n\t}\r\n\r\n\tonShake(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.shake.add(callback)\r\n\t\treturn () => this.#listeners.shake.delete(callback)\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#listeners.move.clear()\r\n\t\tthis.#listeners.zoom.clear()\r\n\t\tthis.#listeners.rotate.clear()\r\n\t\tthis.#listeners.shake.clear()\r\n\t\tthis.#followTarget = null\r\n\t}\r\n}\r\n","import type {\r\n\tInputSystemInterface,\r\n\tInputOptions,\r\n\tInputState,\r\n\tTouchPoint,\r\n\tPointerData,\r\n\tGestureData,\r\n\tGestureType,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\nimport { now } from '../../helpers.js'\r\nimport {\r\n\tDEFAULT_TAP_THRESHOLD,\r\n\tDEFAULT_DOUBLE_TAP_DELAY,\r\n\tDEFAULT_PRESS_DELAY,\r\n\tDEFAULT_SWIPE_THRESHOLD,\r\n\tDEFAULT_SWIPE_VELOCITY,\r\n} from '../../constants.js'\r\n\r\n/**\r\n * Input system for handling touch, mouse, and gesture input.\r\n * Mobile-first design with support for multi-touch gestures.\r\n */\r\nexport class InputSystem implements InputSystemInterface {\r\n\t#canvas: HTMLCanvasElement\r\n\t#pointerX = 0\r\n\t#pointerY = 0\r\n\t#isPointerDown = false\r\n\t#touches: Map<number, TouchPoint> = new Map()\r\n\t#enabled = true\r\n\r\n\t#tapThreshold: number\r\n\t#doubleTapDelay: number\r\n\t#pressDelay: number\r\n\t#swipeThreshold: number\r\n\t#swipeVelocity: number\r\n\t#preventDefaults: boolean\r\n\r\n\t// Gesture tracking\r\n\t#lastTapTime = 0\r\n\t#lastTapX = 0\r\n\t#lastTapY = 0\r\n\t#pointerStartX = 0\r\n\t#pointerStartY = 0\r\n\t#pointerStartTime = 0\r\n\t#pressTimer: ReturnType<typeof setTimeout> | null = null\r\n\r\n\t// Multi-touch gesture tracking (pinch/rotate)\r\n\t#initialPinchDistance = 0\r\n\t#initialPinchAngle = 0\r\n\t#lastPinchScale = 1\r\n\t#lastPinchRotation = 0\r\n\r\n\t#listeners = {\r\n\t\tpointerDown: new Set<(data: PointerData) => void>(),\r\n\t\tpointerUp: new Set<(data: PointerData) => void>(),\r\n\t\tpointerMove: new Set<(data: PointerData) => void>(),\r\n\t\ttouchStart: new Set<(touches: readonly TouchPoint[]) => void>(),\r\n\t\ttouchEnd: new Set<(touches: readonly TouchPoint[]) => void>(),\r\n\t\ttouchMove: new Set<(touches: readonly TouchPoint[]) => void>(),\r\n\t\tgesture: new Set<(gesture: GestureData) => void>(),\r\n\t\ttap: new Set<(x: number, y: number) => void>(),\r\n\t\tdoubleTap: new Set<(x: number, y: number) => void>(),\r\n\t\tpress: new Set<(x: number, y: number) => void>(),\r\n\t\tpan: new Set<(gesture: GestureData) => void>(),\r\n\t\tswipe: new Set<(gesture: GestureData) => void>(),\r\n\t\tpinch: new Set<(gesture: GestureData) => void>(),\r\n\t\trotate: new Set<(gesture: GestureData) => void>(),\r\n\t}\r\n\r\n\t// Bound event handlers for cleanup\r\n\t#boundPointerDown: (e: PointerEvent) => void\r\n\t#boundPointerUp: (e: PointerEvent) => void\r\n\t#boundPointerMove: (e: PointerEvent) => void\r\n\t#boundTouchStart: (e: TouchEvent) => void\r\n\t#boundTouchEnd: (e: TouchEvent) => void\r\n\t#boundTouchMove: (e: TouchEvent) => void\r\n\r\n\tconstructor(canvas: HTMLCanvasElement, options?: InputOptions) {\r\n\t\tthis.#canvas = canvas\r\n\t\tthis.#tapThreshold = options?.tapThreshold ?? DEFAULT_TAP_THRESHOLD\r\n\t\tthis.#doubleTapDelay = options?.doubleTapDelay ?? DEFAULT_DOUBLE_TAP_DELAY\r\n\t\tthis.#pressDelay = options?.pressDelay ?? DEFAULT_PRESS_DELAY\r\n\t\tthis.#swipeThreshold = options?.swipeThreshold ?? DEFAULT_SWIPE_THRESHOLD\r\n\t\tthis.#swipeVelocity = options?.swipeVelocity ?? DEFAULT_SWIPE_VELOCITY\r\n\t\tthis.#preventDefaults = options?.preventDefaults ?? true\r\n\r\n\t\t// Register hooks from options\r\n\t\tif (options?.onPointerDown) this.#listeners.pointerDown.add(options.onPointerDown)\r\n\t\tif (options?.onPointerUp) this.#listeners.pointerUp.add(options.onPointerUp)\r\n\t\tif (options?.onPointerMove) this.#listeners.pointerMove.add(options.onPointerMove)\r\n\t\tif (options?.onTouchStart) this.#listeners.touchStart.add(options.onTouchStart)\r\n\t\tif (options?.onTouchEnd) this.#listeners.touchEnd.add(options.onTouchEnd)\r\n\t\tif (options?.onTouchMove) this.#listeners.touchMove.add(options.onTouchMove)\r\n\t\tif (options?.onGesture) this.#listeners.gesture.add(options.onGesture)\r\n\t\tif (options?.onTap) this.#listeners.tap.add(options.onTap)\r\n\t\tif (options?.onDoubleTap) this.#listeners.doubleTap.add(options.onDoubleTap)\r\n\t\tif (options?.onPress) this.#listeners.press.add(options.onPress)\r\n\t\tif (options?.onPan) this.#listeners.pan.add(options.onPan)\r\n\t\tif (options?.onSwipe) this.#listeners.swipe.add(options.onSwipe)\r\n\t\tif (options?.onPinch) this.#listeners.pinch.add(options.onPinch)\r\n\t\tif (options?.onRotate) this.#listeners.rotate.add(options.onRotate)\r\n\r\n\t\t// Bind event handlers\r\n\t\tthis.#boundPointerDown = this.#handlePointerDown.bind(this)\r\n\t\tthis.#boundPointerUp = this.#handlePointerUp.bind(this)\r\n\t\tthis.#boundPointerMove = this.#handlePointerMove.bind(this)\r\n\t\tthis.#boundTouchStart = this.#handleTouchStart.bind(this)\r\n\t\tthis.#boundTouchEnd = this.#handleTouchEnd.bind(this)\r\n\t\tthis.#boundTouchMove = this.#handleTouchMove.bind(this)\r\n\r\n\t\t// Setup event listeners\r\n\t\tthis.#canvas.addEventListener('pointerdown', this.#boundPointerDown)\r\n\t\tthis.#canvas.addEventListener('pointerup', this.#boundPointerUp)\r\n\t\tthis.#canvas.addEventListener('pointermove', this.#boundPointerMove)\r\n\t\tthis.#canvas.addEventListener('pointercancel', this.#boundPointerUp)\r\n\t\tthis.#canvas.addEventListener('touchstart', this.#boundTouchStart, { passive: !this.#preventDefaults })\r\n\t\tthis.#canvas.addEventListener('touchend', this.#boundTouchEnd, { passive: !this.#preventDefaults })\r\n\t\tthis.#canvas.addEventListener('touchmove', this.#boundTouchMove, { passive: !this.#preventDefaults })\r\n\t\tthis.#canvas.addEventListener('touchcancel', this.#boundTouchEnd, { passive: !this.#preventDefaults })\r\n\t}\r\n\r\n\tgetState(): InputState {\r\n\t\treturn {\r\n\t\t\tpointerX: this.#pointerX,\r\n\t\t\tpointerY: this.#pointerY,\r\n\t\t\tisPointerDown: this.#isPointerDown,\r\n\t\t\ttouchCount: this.#touches.size,\r\n\t\t\ttouches: Array.from(this.#touches.values()),\r\n\t\t}\r\n\t}\r\n\r\n\tgetPointerX(): number { return this.#pointerX }\r\n\tgetPointerY(): number { return this.#pointerY }\r\n\tisPointerDown(): boolean { return this.#isPointerDown }\r\n\tgetTouchCount(): number { return this.#touches.size }\r\n\tgetTouches(): readonly TouchPoint[] { return Array.from(this.#touches.values()) }\r\n\tgetTouch(id: number): TouchPoint | undefined { return this.#touches.get(id) }\r\n\tenable(): void { this.#enabled = true }\r\n\tdisable(): void { this.#enabled = false }\r\n\tisEnabled(): boolean { return this.#enabled }\r\n\r\n\tonPointerDown(callback: (data: PointerData) => void): Unsubscribe {\r\n\t\tthis.#listeners.pointerDown.add(callback)\r\n\t\treturn () => this.#listeners.pointerDown.delete(callback)\r\n\t}\r\n\r\n\tonPointerUp(callback: (data: PointerData) => void): Unsubscribe {\r\n\t\tthis.#listeners.pointerUp.add(callback)\r\n\t\treturn () => this.#listeners.pointerUp.delete(callback)\r\n\t}\r\n\r\n\tonPointerMove(callback: (data: PointerData) => void): Unsubscribe {\r\n\t\tthis.#listeners.pointerMove.add(callback)\r\n\t\treturn () => this.#listeners.pointerMove.delete(callback)\r\n\t}\r\n\r\n\tonTouchStart(callback: (touches: readonly TouchPoint[]) => void): Unsubscribe {\r\n\t\tthis.#listeners.touchStart.add(callback)\r\n\t\treturn () => this.#listeners.touchStart.delete(callback)\r\n\t}\r\n\r\n\tonTouchEnd(callback: (touches: readonly TouchPoint[]) => void): Unsubscribe {\r\n\t\tthis.#listeners.touchEnd.add(callback)\r\n\t\treturn () => this.#listeners.touchEnd.delete(callback)\r\n\t}\r\n\r\n\tonTouchMove(callback: (touches: readonly TouchPoint[]) => void): Unsubscribe {\r\n\t\tthis.#listeners.touchMove.add(callback)\r\n\t\treturn () => this.#listeners.touchMove.delete(callback)\r\n\t}\r\n\r\n\tonGesture(callback: (gesture: GestureData) => void): Unsubscribe {\r\n\t\tthis.#listeners.gesture.add(callback)\r\n\t\treturn () => this.#listeners.gesture.delete(callback)\r\n\t}\r\n\r\n\tonTap(callback: (x: number, y: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.tap.add(callback)\r\n\t\treturn () => this.#listeners.tap.delete(callback)\r\n\t}\r\n\r\n\tonDoubleTap(callback: (x: number, y: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.doubleTap.add(callback)\r\n\t\treturn () => this.#listeners.doubleTap.delete(callback)\r\n\t}\r\n\r\n\tonPress(callback: (x: number, y: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.press.add(callback)\r\n\t\treturn () => this.#listeners.press.delete(callback)\r\n\t}\r\n\r\n\tonPan(callback: (gesture: GestureData) => void): Unsubscribe {\r\n\t\tthis.#listeners.pan.add(callback)\r\n\t\treturn () => this.#listeners.pan.delete(callback)\r\n\t}\r\n\r\n\tonSwipe(callback: (gesture: GestureData) => void): Unsubscribe {\r\n\t\tthis.#listeners.swipe.add(callback)\r\n\t\treturn () => this.#listeners.swipe.delete(callback)\r\n\t}\r\n\r\n\tonPinch(callback: (gesture: GestureData) => void): Unsubscribe {\r\n\t\tthis.#listeners.pinch.add(callback)\r\n\t\treturn () => this.#listeners.pinch.delete(callback)\r\n\t}\r\n\r\n\tonRotate(callback: (gesture: GestureData) => void): Unsubscribe {\r\n\t\tthis.#listeners.rotate.add(callback)\r\n\t\treturn () => this.#listeners.rotate.delete(callback)\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#canvas.removeEventListener('pointerdown', this.#boundPointerDown)\r\n\t\tthis.#canvas.removeEventListener('pointerup', this.#boundPointerUp)\r\n\t\tthis.#canvas.removeEventListener('pointermove', this.#boundPointerMove)\r\n\t\tthis.#canvas.removeEventListener('pointercancel', this.#boundPointerUp)\r\n\t\tthis.#canvas.removeEventListener('touchstart', this.#boundTouchStart)\r\n\t\tthis.#canvas.removeEventListener('touchend', this.#boundTouchEnd)\r\n\t\tthis.#canvas.removeEventListener('touchmove', this.#boundTouchMove)\r\n\t\tthis.#canvas.removeEventListener('touchcancel', this.#boundTouchEnd)\r\n\r\n\t\tif (this.#pressTimer) clearTimeout(this.#pressTimer)\r\n\r\n\t\tfor (const set of Object.values(this.#listeners)) set.clear()\r\n\t\tthis.#touches.clear()\r\n\t}\r\n\r\n\t// Private event handlers\r\n\r\n\t#getCanvasCoords(clientX: number, clientY: number): { x: number; y: number } {\r\n\t\tconst rect = this.#canvas.getBoundingClientRect()\r\n\t\treturn {\r\n\t\t\tx: clientX - rect.left,\r\n\t\t\ty: clientY - rect.top,\r\n\t\t}\r\n\t}\r\n\r\n\t#handlePointerDown(e: PointerEvent): void {\r\n\t\tif (!this.#enabled) return\r\n\t\tif (this.#preventDefaults) e.preventDefault()\r\n\r\n\t\tconst coords = this.#getCanvasCoords(e.clientX, e.clientY)\r\n\t\tthis.#pointerX = coords.x\r\n\t\tthis.#pointerY = coords.y\r\n\t\tthis.#isPointerDown = true\r\n\t\tthis.#pointerStartX = coords.x\r\n\t\tthis.#pointerStartY = coords.y\r\n\t\tthis.#pointerStartTime = now()\r\n\r\n\t\t// Start press timer\r\n\t\tif (this.#pressTimer) clearTimeout(this.#pressTimer)\r\n\t\tthis.#pressTimer = setTimeout(() => {\r\n\t\t\tthis.#emitPress(coords.x, coords.y)\r\n\t\t}, this.#pressDelay)\r\n\r\n\t\tconst data: PointerData = {\r\n\t\t\tx: coords.x,\r\n\t\t\ty: coords.y,\r\n\t\t\tisDown: true,\r\n\t\t\tbutton: e.button,\r\n\t\t\ttimestamp: now(),\r\n\t\t}\r\n\t\tthis.#listeners.pointerDown.forEach(cb => cb(data))\r\n\t}\r\n\r\n\t#handlePointerUp(e: PointerEvent): void {\r\n\t\tif (!this.#enabled) return\r\n\t\tif (this.#preventDefaults) e.preventDefault()\r\n\r\n\t\tif (this.#pressTimer) {\r\n\t\t\tclearTimeout(this.#pressTimer)\r\n\t\t\tthis.#pressTimer = null\r\n\t\t}\r\n\r\n\t\tconst coords = this.#getCanvasCoords(e.clientX, e.clientY)\r\n\t\tconst dx = coords.x - this.#pointerStartX\r\n\t\tconst dy = coords.y - this.#pointerStartY\r\n\t\tconst dist = Math.sqrt(dx * dx + dy * dy)\r\n\t\tconst duration = now() - this.#pointerStartTime\r\n\r\n\t\t// Detect tap\r\n\t\tif (dist < this.#tapThreshold && duration < this.#pressDelay) {\r\n\t\t\tthis.#handleTapGesture(coords.x, coords.y)\r\n\t\t}\r\n\r\n\t\t// Detect swipe\r\n\t\tif (dist >= this.#swipeThreshold) {\r\n\t\t\tconst velocity = dist / duration\r\n\t\t\tif (velocity >= this.#swipeVelocity) {\r\n\t\t\t\tthis.#emitSwipe(coords.x, coords.y, dx, dy, velocity)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tthis.#pointerX = coords.x\r\n\t\tthis.#pointerY = coords.y\r\n\t\tthis.#isPointerDown = false\r\n\r\n\t\tconst data: PointerData = {\r\n\t\t\tx: coords.x,\r\n\t\t\ty: coords.y,\r\n\t\t\tisDown: false,\r\n\t\t\tbutton: e.button,\r\n\t\t\ttimestamp: now(),\r\n\t\t}\r\n\t\tthis.#listeners.pointerUp.forEach(cb => cb(data))\r\n\t}\r\n\r\n\t#handlePointerMove(e: PointerEvent): void {\r\n\t\tif (!this.#enabled) return\r\n\t\tif (this.#preventDefaults && this.#isPointerDown) e.preventDefault()\r\n\r\n\t\tconst coords = this.#getCanvasCoords(e.clientX, e.clientY)\r\n\t\tthis.#pointerX = coords.x\r\n\t\tthis.#pointerY = coords.y\r\n\r\n\t\t// Cancel press if moved too far\r\n\t\tif (this.#pressTimer && this.#isPointerDown) {\r\n\t\t\tconst dx = coords.x - this.#pointerStartX\r\n\t\t\tconst dy = coords.y - this.#pointerStartY\r\n\t\t\tif (Math.sqrt(dx * dx + dy * dy) > this.#tapThreshold) {\r\n\t\t\t\tclearTimeout(this.#pressTimer)\r\n\t\t\t\tthis.#pressTimer = null\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Emit pan if pointer is down\r\n\t\tif (this.#isPointerDown) {\r\n\t\t\tconst dx = coords.x - this.#pointerStartX\r\n\t\t\tconst dy = coords.y - this.#pointerStartY\r\n\t\t\tthis.#emitPan(coords.x, coords.y, dx, dy)\r\n\t\t}\r\n\r\n\t\tconst data: PointerData = {\r\n\t\t\tx: coords.x,\r\n\t\t\ty: coords.y,\r\n\t\t\tisDown: this.#isPointerDown,\r\n\t\t\tbutton: e.button,\r\n\t\t\ttimestamp: now(),\r\n\t\t}\r\n\t\tthis.#listeners.pointerMove.forEach(cb => cb(data))\r\n\t}\r\n\r\n\t#handleTouchStart(e: TouchEvent): void {\r\n\t\tif (!this.#enabled) return\r\n\t\tif (this.#preventDefaults) e.preventDefault()\r\n\r\n\t\tfor (const touch of Array.from(e.changedTouches)) {\r\n\t\t\tconst coords = this.#getCanvasCoords(touch.clientX, touch.clientY)\r\n\t\t\tconst point: TouchPoint = {\r\n\t\t\t\tid: touch.identifier,\r\n\t\t\t\tx: coords.x,\r\n\t\t\t\ty: coords.y,\r\n\t\t\t\tstartX: coords.x,\r\n\t\t\t\tstartY: coords.y,\r\n\t\t\t\tdeltaX: 0,\r\n\t\t\t\tdeltaY: 0,\r\n\t\t\t\tforce: touch.force,\r\n\t\t\t\ttimestamp: now(),\r\n\t\t\t}\r\n\t\t\tthis.#touches.set(touch.identifier, point)\r\n\t\t}\r\n\r\n\t\t// Initialize pinch/rotate tracking when we have exactly 2 touches\r\n\t\tif (this.#touches.size === 2) {\r\n\t\t\tconst [touch1, touch2] = this.#getTwoTouchPoints()\r\n\t\t\tif (touch1 && touch2) {\r\n\t\t\t\tthis.#initialPinchDistance = this.#getDistance(touch1, touch2)\r\n\t\t\t\tthis.#initialPinchAngle = this.#getAngle(touch1, touch2)\r\n\t\t\t\tthis.#lastPinchScale = 1\r\n\t\t\t\tthis.#lastPinchRotation = 0\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tthis.#listeners.touchStart.forEach(cb => cb(this.getTouches()))\r\n\t}\r\n\r\n\t#handleTouchEnd(e: TouchEvent): void {\r\n\t\tif (!this.#enabled) return\r\n\t\tif (this.#preventDefaults) e.preventDefault()\r\n\r\n\t\tfor (const touch of Array.from(e.changedTouches)) {\r\n\t\t\tthis.#touches.delete(touch.identifier)\r\n\t\t}\r\n\r\n\t\t// Reset pinch/rotate tracking\r\n\t\tif (this.#touches.size < 2) {\r\n\t\t\tthis.#initialPinchDistance = 0\r\n\t\t\tthis.#initialPinchAngle = 0\r\n\t\t}\r\n\r\n\t\tthis.#listeners.touchEnd.forEach(cb => cb(this.getTouches()))\r\n\t}\r\n\r\n\t#handleTouchMove(e: TouchEvent): void {\r\n\t\tif (!this.#enabled) return\r\n\t\tif (this.#preventDefaults) e.preventDefault()\r\n\r\n\t\tfor (const touch of Array.from(e.changedTouches)) {\r\n\t\t\tconst existing = this.#touches.get(touch.identifier)\r\n\t\t\tif (existing) {\r\n\t\t\t\tconst coords = this.#getCanvasCoords(touch.clientX, touch.clientY)\r\n\t\t\t\tconst updated: TouchPoint = {\r\n\t\t\t\t\t...existing,\r\n\t\t\t\t\tx: coords.x,\r\n\t\t\t\t\ty: coords.y,\r\n\t\t\t\t\tdeltaX: coords.x - existing.startX,\r\n\t\t\t\t\tdeltaY: coords.y - existing.startY,\r\n\t\t\t\t\tforce: touch.force,\r\n\t\t\t\t\ttimestamp: now(),\r\n\t\t\t\t}\r\n\t\t\t\tthis.#touches.set(touch.identifier, updated)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Detect pinch and rotate gestures when we have 2 touches\r\n\t\tif (this.#touches.size === 2 && this.#initialPinchDistance > 0) {\r\n\t\t\tconst [touch1, touch2] = this.#getTwoTouchPoints()\r\n\t\t\tif (touch1 && touch2) {\r\n\t\t\t\tconst currentDistance = this.#getDistance(touch1, touch2)\r\n\t\t\t\tconst currentAngle = this.#getAngle(touch1, touch2)\r\n\r\n\t\t\t\tconst scale = currentDistance / this.#initialPinchDistance\r\n\t\t\t\tconst rotation = currentAngle - this.#initialPinchAngle\r\n\r\n\t\t\t\t// Calculate center point between two touches\r\n\t\t\t\tconst centerX = (touch1.x + touch2.x) / 2\r\n\t\t\t\tconst centerY = (touch1.y + touch2.y) / 2\r\n\r\n\t\t\t\t// Emit pinch gesture if scale changed significantly\r\n\t\t\t\tif (Math.abs(scale - this.#lastPinchScale) > 0.01) {\r\n\t\t\t\t\tthis.#lastPinchScale = scale\r\n\t\t\t\t\tthis.#emitPinch(centerX, centerY, scale)\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Emit rotate gesture if rotation changed significantly\r\n\t\t\t\tif (Math.abs(rotation - this.#lastPinchRotation) > 0.01) {\r\n\t\t\t\t\tthis.#lastPinchRotation = rotation\r\n\t\t\t\t\tthis.#emitRotate(centerX, centerY, rotation)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tthis.#listeners.touchMove.forEach(cb => cb(this.getTouches()))\r\n\t}\r\n\r\n\t#getTwoTouchPoints(): [TouchPoint | undefined, TouchPoint | undefined] {\r\n\t\tconst touches = Array.from(this.#touches.values())\r\n\t\treturn [touches[0], touches[1]]\r\n\t}\r\n\r\n\t#getDistance(p1: TouchPoint, p2: TouchPoint): number {\r\n\t\tconst dx = p2.x - p1.x\r\n\t\tconst dy = p2.y - p1.y\r\n\t\treturn Math.sqrt(dx * dx + dy * dy)\r\n\t}\r\n\r\n\t#getAngle(p1: TouchPoint, p2: TouchPoint): number {\r\n\t\treturn Math.atan2(p2.y - p1.y, p2.x - p1.x)\r\n\t}\r\n\r\n\t#emitPinch(x: number, y: number, scale: number): void {\r\n\t\tconst gesture: GestureData = {\r\n\t\t\ttype: 'pinch',\r\n\t\t\tx,\r\n\t\t\ty,\r\n\t\t\tdeltaX: 0,\r\n\t\t\tdeltaY: 0,\r\n\t\t\tdistance: 0,\r\n\t\t\tscale,\r\n\t\t\trotation: 0,\r\n\t\t\tvelocity: 0,\r\n\t\t\ttimestamp: now(),\r\n\t\t}\r\n\t\tthis.#listeners.pinch.forEach(cb => cb(gesture))\r\n\t\tthis.#listeners.gesture.forEach(cb => cb(gesture))\r\n\t}\r\n\r\n\t#emitRotate(x: number, y: number, rotation: number): void {\r\n\t\tconst gesture: GestureData = {\r\n\t\t\ttype: 'rotate',\r\n\t\t\tx,\r\n\t\t\ty,\r\n\t\t\tdeltaX: 0,\r\n\t\t\tdeltaY: 0,\r\n\t\t\tdistance: 0,\r\n\t\t\tscale: 1,\r\n\t\t\trotation,\r\n\t\t\tvelocity: 0,\r\n\t\t\ttimestamp: now(),\r\n\t\t}\r\n\t\tthis.#listeners.rotate.forEach(cb => cb(gesture))\r\n\t\tthis.#listeners.gesture.forEach(cb => cb(gesture))\r\n\t}\r\n\r\n\t#handleTapGesture(x: number, y: number): void {\r\n\t\tconst currentTime = now()\r\n\t\tconst dx = x - this.#lastTapX\r\n\t\tconst dy = y - this.#lastTapY\r\n\t\tconst dist = Math.sqrt(dx * dx + dy * dy)\r\n\r\n\t\tif (currentTime - this.#lastTapTime < this.#doubleTapDelay && dist < this.#tapThreshold) {\r\n\t\t\tthis.#listeners.doubleTap.forEach(cb => cb(x, y))\r\n\t\t\tthis.#emitGesture('doubletap', x, y)\r\n\t\t\tthis.#lastTapTime = 0\r\n\t\t} else {\r\n\t\t\tthis.#listeners.tap.forEach(cb => cb(x, y))\r\n\t\t\tthis.#emitGesture('tap', x, y)\r\n\t\t\tthis.#lastTapTime = currentTime\r\n\t\t\tthis.#lastTapX = x\r\n\t\t\tthis.#lastTapY = y\r\n\t\t}\r\n\t}\r\n\r\n\t#emitPress(x: number, y: number): void {\r\n\t\tthis.#listeners.press.forEach(cb => cb(x, y))\r\n\t\tthis.#emitGesture('press', x, y)\r\n\t}\r\n\r\n\t#emitPan(x: number, y: number, deltaX: number, deltaY: number): void {\r\n\t\tconst gesture: GestureData = {\r\n\t\t\ttype: 'pan',\r\n\t\t\tx,\r\n\t\t\ty,\r\n\t\t\tdeltaX,\r\n\t\t\tdeltaY,\r\n\t\t\tdistance: Math.sqrt(deltaX * deltaX + deltaY * deltaY),\r\n\t\t\tscale: 1,\r\n\t\t\trotation: 0,\r\n\t\t\tvelocity: 0,\r\n\t\t\ttimestamp: now(),\r\n\t\t}\r\n\t\tthis.#listeners.pan.forEach(cb => cb(gesture))\r\n\t\tthis.#listeners.gesture.forEach(cb => cb(gesture))\r\n\t}\r\n\r\n\t#emitSwipe(x: number, y: number, deltaX: number, deltaY: number, velocity: number): void {\r\n\t\tconst gesture: GestureData = {\r\n\t\t\ttype: 'swipe',\r\n\t\t\tx,\r\n\t\t\ty,\r\n\t\t\tdeltaX,\r\n\t\t\tdeltaY,\r\n\t\t\tdistance: Math.sqrt(deltaX * deltaX + deltaY * deltaY),\r\n\t\t\tscale: 1,\r\n\t\t\trotation: 0,\r\n\t\t\tvelocity,\r\n\t\t\ttimestamp: now(),\r\n\t\t}\r\n\t\tthis.#listeners.swipe.forEach(cb => cb(gesture))\r\n\t\tthis.#listeners.gesture.forEach(cb => cb(gesture))\r\n\t}\r\n\r\n\t#emitGesture(type: GestureType, x: number, y: number): void {\r\n\t\tconst gesture: GestureData = {\r\n\t\t\ttype,\r\n\t\t\tx,\r\n\t\t\ty,\r\n\t\t\tdeltaX: 0,\r\n\t\t\tdeltaY: 0,\r\n\t\t\tdistance: 0,\r\n\t\t\tscale: 1,\r\n\t\t\trotation: 0,\r\n\t\t\tvelocity: 0,\r\n\t\t\ttimestamp: now(),\r\n\t\t}\r\n\t\tthis.#listeners.gesture.forEach(cb => cb(gesture))\r\n\t}\r\n\r\n\t// TODO: Implement gesture direction detection\r\n\t#getDirection(dx: number, dy: number): 'left' | 'right' | 'up' | 'down' | undefined {\r\n\t\tif (Math.abs(dx) > Math.abs(dy)) {\r\n\t\t\treturn dx > 0 ? 'right' : 'left'\r\n\t\t} else if (Math.abs(dy) > Math.abs(dx)) {\r\n\t\t\treturn dy > 0 ? 'down' : 'up'\r\n\t\t}\r\n\t\treturn undefined\r\n\t}\r\n}\r\n","import type {\n\tKeyboardManagerInterface,\n\tKeyboardManagerOptions,\n\tKeyboardState,\n\tKeyState,\n\tKeyCombo,\n\tVector2,\n\tUnsubscribe, TrackedCombo,\n} from '../../types.js'\nimport { generateId, now } from '../../helpers.js'\nimport { DEFAULT_REPEAT_DELAY, DEFAULT_REPEAT_RATE } from '~/src'\n\n/**\n * Keyboard input manager for desktop input handling.\n * Tracks key states, supports combos, and provides virtual axes.\n *\n * @example\n * ```ts\n * const keyboard = createKeyboardManager({\n * preventDefaultKeys: ['ArrowUp', 'ArrowDown', 'Space'],\n * onKeyDown: (key) => console.log('Key down:', key),\n * })\n *\n * // In game loop\n * keyboard.update()\n *\n * // Check key states\n * if (keyboard.isKeyDown('Space')) {\n * player.jump()\n * }\n *\n * // Get movement vector from WASD\n * const movement = keyboard.getVector('KeyA', 'KeyD', 'KeyW', 'KeyS')\n * ```\n */\nexport class KeyboardManager implements KeyboardManagerInterface {\n\t#keysDown: Set<string> = new Set()\n\t#keysPressed: Set<string> = new Set()\n\t#keysReleased: Set<string> = new Set()\n\t#keysPressedThisFrame: Set<string> = new Set()\n\t#keysReleasedThisFrame: Set<string> = new Set()\n\n\t#modifiers = {\n\t\tctrl: false,\n\t\tshift: false,\n\t\talt: false,\n\t\tmeta: false,\n\t}\n\n\t#preventDefaultKeys: Set<string> = new Set()\n\t#allowBrowserShortcuts: boolean\n\t#repeatDelay: number\n\t#repeatRate: number\n\n\t#trackedCombos: Map<string, TrackedCombo> = new Map()\n\n\t#listeners = {\n\t\tkeyDown: new Set<(key: string, event: KeyboardEvent) => void>(),\n\t\tkeyUp: new Set<(key: string, event: KeyboardEvent) => void>(),\n\t\tkeyPress: new Set<(key: string, event: KeyboardEvent) => void>(),\n\t}\n\n\treadonly #boundKeyDown: (e: KeyboardEvent) => void\n\treadonly #boundKeyUp: (e: KeyboardEvent) => void\n\treadonly #boundBlur: () => void\n\n\tconstructor(options?: KeyboardManagerOptions) {\n\t\tthis.#allowBrowserShortcuts = options?.allowBrowserShortcuts ?? true\n\t\tthis.#repeatDelay = options?.repeatDelay ?? DEFAULT_REPEAT_DELAY\n\t\tthis.#repeatRate = options?.repeatRate ?? DEFAULT_REPEAT_RATE\n\n\t\t// Set prevent default keys\n\t\tif (options?.preventDefaultKeys) {\n\t\t\tfor (const key of options.preventDefaultKeys) {\n\t\t\t\tthis.#preventDefaultKeys.add(key)\n\t\t\t}\n\t\t}\n\n\t\t// Register hooks from options\n\t\tif (options?.onKeyDown) this.#listeners.keyDown.add(options.onKeyDown)\n\t\tif (options?.onKeyUp) this.#listeners.keyUp.add(options.onKeyUp)\n\t\tif (options?.onKeyPress) this.#listeners.keyPress.add(options.onKeyPress)\n\n\t\t// Bind event handlers\n\t\tthis.#boundKeyDown = this.#handleKeyDown.bind(this)\n\t\tthis.#boundKeyUp = this.#handleKeyUp.bind(this)\n\t\tthis.#boundBlur = this.#handleBlur.bind(this)\n\n\t\t// Add event listeners\n\t\twindow.addEventListener('keydown', this.#boundKeyDown)\n\t\twindow.addEventListener('keyup', this.#boundKeyUp)\n\t\twindow.addEventListener('blur', this.#boundBlur)\n\t}\n\n\t// =========================================================================\n\t// Event Handlers\n\t// =========================================================================\n\n\t#handleKeyDown(event: KeyboardEvent): void {\n\t\tconst key = event.code\n\n\t\t// Update modifiers\n\t\tthis.#modifiers.ctrl = event.ctrlKey\n\t\tthis.#modifiers.shift = event.shiftKey\n\t\tthis.#modifiers.alt = event.altKey\n\t\tthis.#modifiers.meta = event.metaKey\n\n\t\t// Check if we should allow browser shortcuts\n\t\tif (!this.#allowBrowserShortcuts && this.#isBrowserShortcut(event)) {\n\t\t\treturn\n\t\t}\n\n\t\t// Prevent default for configured keys\n\t\tif (this.#preventDefaultKeys.has(key) || this.#preventDefaultKeys.has(event.key)) {\n\t\t\tevent.preventDefault()\n\t\t}\n\n\t\t// Track key state\n\t\tif (!this.#keysDown.has(key)) {\n\t\t\tthis.#keysDown.add(key)\n\t\t\tthis.#keysPressedThisFrame.add(key)\n\n\t\t\t// Emit key down event\n\t\t\tfor (const callback of this.#listeners.keyDown) {\n\t\t\t\tcallback(key, event)\n\t\t\t}\n\n\t\t\t// Emit key press event (only on initial press)\n\t\t\tfor (const callback of this.#listeners.keyPress) {\n\t\t\t\tcallback(key, event)\n\t\t\t}\n\n\t\t\t// Check combos\n\t\t\tthis.#checkCombos(key)\n\t\t}\n\t}\n\n\t#handleKeyUp(event: KeyboardEvent): void {\n\t\tconst key = event.code\n\n\t\t// Update modifiers\n\t\tthis.#modifiers.ctrl = event.ctrlKey\n\t\tthis.#modifiers.shift = event.shiftKey\n\t\tthis.#modifiers.alt = event.altKey\n\t\tthis.#modifiers.meta = event.metaKey\n\n\t\t// Track key state\n\t\tif (this.#keysDown.has(key)) {\n\t\t\tthis.#keysDown.delete(key)\n\t\t\tthis.#keysReleasedThisFrame.add(key)\n\n\t\t\t// Emit key up event\n\t\t\tfor (const callback of this.#listeners.keyUp) {\n\t\t\t\tcallback(key, event)\n\t\t\t}\n\t\t}\n\t}\n\n\t#handleBlur(): void {\n\t\t// Clear all key states when window loses focus\n\t\tfor (const key of this.#keysDown) {\n\t\t\tthis.#keysReleasedThisFrame.add(key)\n\t\t}\n\t\tthis.#keysDown.clear()\n\t\tthis.#modifiers.ctrl = false\n\t\tthis.#modifiers.shift = false\n\t\tthis.#modifiers.alt = false\n\t\tthis.#modifiers.meta = false\n\t}\n\n\t#isBrowserShortcut(event: KeyboardEvent): boolean {\n\t\t// Common browser shortcuts\n\t\tif (event.ctrlKey || event.metaKey) {\n\t\t\tconst shortcuts = ['KeyC', 'KeyV', 'KeyX', 'KeyA', 'KeyZ', 'KeyY', 'KeyS', 'KeyF', 'KeyP', 'KeyR', 'KeyT', 'KeyW', 'KeyN']\n\t\t\tif (shortcuts.includes(event.code)) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\t// F5 (refresh), F12 (dev tools)\n\t\tif (['F5', 'F11', 'F12'].includes(event.code)) {\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\t}\n\n\t#checkCombos(key: string): void {\n\t\tconst currentTime = now()\n\n\t\tfor (const tracked of this.#trackedCombos.values()) {\n\t\t\tconst { combo, keysPressed, lastKeyTime } = tracked\n\n\t\t\t// Check if combo has expired\n\t\t\tif (keysPressed.length > 0 && currentTime - lastKeyTime > combo.maxDelay) {\n\t\t\t\ttracked.keysPressed = []\n\t\t\t}\n\n\t\t\t// For ordered combos, check if this key matches the next expected key\n\t\t\tif (combo.ordered) {\n\t\t\t\tconst nextIndex = keysPressed.length\n\t\t\t\tif (nextIndex < combo.keys.length && combo.keys[nextIndex] === key) {\n\t\t\t\t\ttracked.keysPressed.push(key)\n\t\t\t\t\ttracked.lastKeyTime = currentTime\n\n\t\t\t\t\t// Check if combo is complete\n\t\t\t\t\tif (tracked.keysPressed.length === combo.keys.length) {\n\t\t\t\t\t\ttracked.callback()\n\t\t\t\t\t\ttracked.keysPressed = []\n\t\t\t\t\t}\n\t\t\t\t} else if (nextIndex > 0) {\n\t\t\t\t\t// Wrong key, reset\n\t\t\t\t\ttracked.keysPressed = []\n\t\t\t\t\t// But check if this key starts the combo\n\t\t\t\t\tif (combo.keys[0] === key) {\n\t\t\t\t\t\ttracked.keysPressed.push(key)\n\t\t\t\t\t\ttracked.lastKeyTime = currentTime\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Unordered combo - just need all keys pressed\n\t\t\t\tif (combo.keys.includes(key) && !keysPressed.includes(key)) {\n\t\t\t\t\ttracked.keysPressed.push(key)\n\t\t\t\t\ttracked.lastKeyTime = currentTime\n\n\t\t\t\t\t// Check if all keys are pressed\n\t\t\t\t\tif (tracked.keysPressed.length === combo.keys.length) {\n\t\t\t\t\t\ttracked.callback()\n\t\t\t\t\t\ttracked.keysPressed = []\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// =========================================================================\n\t// Accessors (KeyboardManagerInterface interface)\n\t// =========================================================================\n\n\tgetState(): KeyboardState {\n\t\treturn {\n\t\t\tkeysDown: new Set(this.#keysDown),\n\t\t\tkeysPressed: new Set(this.#keysPressed),\n\t\t\tkeysReleased: new Set(this.#keysReleased),\n\t\t\tmodifiers: { ...this.#modifiers },\n\t\t}\n\t}\n\n\tisKeyDown(key: string): boolean {\n\t\treturn this.#keysDown.has(key)\n\t}\n\n\tisKeyPressed(key: string): boolean {\n\t\treturn this.#keysPressed.has(key)\n\t}\n\n\tisKeyReleased(key: string): boolean {\n\t\treturn this.#keysReleased.has(key)\n\t}\n\n\tisKeyHeld(key: string): boolean {\n\t\treturn this.#keysDown.has(key) && !this.#keysPressed.has(key)\n\t}\n\n\tgetKeyState(key: string): KeyState {\n\t\tif (this.#keysPressed.has(key)) return 'pressed'\n\t\tif (this.#keysReleased.has(key)) return 'released'\n\t\tif (this.#keysDown.has(key)) return 'held'\n\t\treturn 'up'\n\t}\n\n\tgetAxis(negative: string, positive: string): number {\n\t\tlet value = 0\n\t\tif (this.#keysDown.has(negative)) value -= 1\n\t\tif (this.#keysDown.has(positive)) value += 1\n\t\treturn value\n\t}\n\n\tgetVector(left: string, right: string, up: string, down: string): Vector2 {\n\t\tconst x = this.getAxis(left, right)\n\t\tconst y = this.getAxis(up, down)\n\n\t\t// Normalize diagonal movement\n\t\tif (x !== 0 && y !== 0) {\n\t\t\tconst magnitude = Math.sqrt(x * x + y * y)\n\t\t\treturn { x: x / magnitude, y: y / magnitude }\n\t\t}\n\n\t\treturn { x, y }\n\t}\n\n\t// =========================================================================\n\t// Mutators\n\t// =========================================================================\n\n\tsetPreventDefault(key: string, prevent: boolean): void {\n\t\tif (prevent) {\n\t\t\tthis.#preventDefaultKeys.add(key)\n\t\t} else {\n\t\t\tthis.#preventDefaultKeys.delete(key)\n\t\t}\n\t}\n\n\tclearPreventDefaults(): void {\n\t\tthis.#preventDefaultKeys.clear()\n\t}\n\n\t// =========================================================================\n\t// Event Subscriptions\n\t// =========================================================================\n\n\tonKeyDown(callback: (key: string, event: KeyboardEvent) => void): Unsubscribe {\n\t\tthis.#listeners.keyDown.add(callback)\n\t\treturn () => this.#listeners.keyDown.delete(callback)\n\t}\n\n\tonKeyUp(callback: (key: string, event: KeyboardEvent) => void): Unsubscribe {\n\t\tthis.#listeners.keyUp.add(callback)\n\t\treturn () => this.#listeners.keyUp.delete(callback)\n\t}\n\n\tonKeyPress(callback: (key: string, event: KeyboardEvent) => void): Unsubscribe {\n\t\tthis.#listeners.keyPress.add(callback)\n\t\treturn () => this.#listeners.keyPress.delete(callback)\n\t}\n\n\tonCombo(combo: KeyCombo, callback: () => void): Unsubscribe {\n\t\tconst id = generateId()\n\t\tconst tracked: TrackedCombo = {\n\t\t\tid,\n\t\t\tcombo,\n\t\t\tcallback,\n\t\t\tkeysPressed: [],\n\t\t\tlastKeyTime: 0,\n\t\t}\n\t\tthis.#trackedCombos.set(id, tracked)\n\t\treturn () => this.#trackedCombos.delete(id)\n\t}\n\n\t// =========================================================================\n\t// Lifecycle\n\t// =========================================================================\n\n\tupdate(): void {\n\t\t// Transfer this frame's presses/releases to the state sets\n\t\tthis.#keysPressed.clear()\n\t\tthis.#keysReleased.clear()\n\n\t\tfor (const key of this.#keysPressedThisFrame) {\n\t\t\tthis.#keysPressed.add(key)\n\t\t}\n\t\tfor (const key of this.#keysReleasedThisFrame) {\n\t\t\tthis.#keysReleased.add(key)\n\t\t}\n\n\t\t// Clear the frame sets\n\t\tthis.#keysPressedThisFrame.clear()\n\t\tthis.#keysReleasedThisFrame.clear()\n\t}\n\n\tdestroy(): void {\n\t\twindow.removeEventListener('keydown', this.#boundKeyDown)\n\t\twindow.removeEventListener('keyup', this.#boundKeyUp)\n\t\twindow.removeEventListener('blur', this.#boundBlur)\n\n\t\tthis.#keysDown.clear()\n\t\tthis.#keysPressed.clear()\n\t\tthis.#keysReleased.clear()\n\t\tthis.#keysPressedThisFrame.clear()\n\t\tthis.#keysReleasedThisFrame.clear()\n\t\tthis.#trackedCombos.clear()\n\t\tthis.#listeners.keyDown.clear()\n\t\tthis.#listeners.keyUp.clear()\n\t\tthis.#listeners.keyPress.clear()\n\t}\n}\n","import type {\n\tGamepadManagerInterface,\n\tGamepadManagerOptions,\n\tGamepadControllerState,\n\tGamepadMapping,\n\tGamepadButtonName,\n\tGamepadAxisName,\n\tVector2,\n\tUnsubscribe,\n} from '../../types.js'\nimport {\n\tDEFAULT_GAMEPAD_DEADZONE,\n\tDEFAULT_GAMEPAD_AXIS_THRESHOLD,\n\tSTANDARD_BUTTON_MAPPING,\n\tSTANDARD_AXIS_MAPPING,\n\tALL_GAMEPAD_BUTTONS,\n\tALL_GAMEPAD_AXES,\n} from '../../constants.js'\n\n/**\n * Gamepad input manager for controller support.\n * Supports ButtonInterface/axis tracking, deadzone, vibration, and custom mappings.\n *\n * @example\n * ```ts\n * const gamepad = createGamepadManager({\n * deadzone: 0.2,\n * onConnect: (index, id) => console.log('Controller connected:', id),\n * })\n *\n * // In game loop\n * gamepad.update()\n *\n * if (gamepad.hasGamepad()) {\n * if (gamepad.isButtonDown(0, 'a')) {\n * player.jump()\n * }\n * const stick = gamepad.getStick(0, 'left')\n * player.move(stick.x, stick.y)\n * }\n * ```\n */\nexport class GamepadManager implements GamepadManagerInterface {\n\t#gamepads: Map<number, GamepadControllerState> = new Map()\n\t#previousButtons: Map<number, Set<GamepadButtonName>> = new Map()\n\t#previousAxes: Map<number, Map<GamepadAxisName, number>> = new Map()\n\n\t#deadzone: number\n\t#axisThreshold: number\n\t#customMappings: Map<string, GamepadMapping> = new Map()\n\n\t#listeners = {\n\t\tconnect: new Set<(index: number, id: string) => void>(),\n\t\tdisconnect: new Set<(index: number) => void>(),\n\t\tbuttonDown: new Set<(index: number, ButtonInterface: GamepadButtonName) => void>(),\n\t\tbuttonUp: new Set<(index: number, ButtonInterface: GamepadButtonName) => void>(),\n\t\taxisChange: new Set<(index: number, axis: GamepadAxisName, value: number) => void>(),\n\t}\n\n\t#boundGamepadConnected: (e: GamepadEvent) => void\n\t#boundGamepadDisconnected: (e: GamepadEvent) => void\n\n\tconstructor(options?: GamepadManagerOptions) {\n\t\tthis.#deadzone = options?.deadzone ?? DEFAULT_GAMEPAD_DEADZONE\n\t\tthis.#axisThreshold = options?.axisThreshold ?? DEFAULT_GAMEPAD_AXIS_THRESHOLD\n\n\t\t// Register custom mappings\n\t\tif (options?.customMappings) {\n\t\t\tfor (const mapping of options.customMappings) {\n\t\t\t\tthis.#customMappings.set(mapping.name, mapping)\n\t\t\t}\n\t\t}\n\n\t\t// Register hooks from options\n\t\tif (options?.onConnect) this.#listeners.connect.add(options.onConnect)\n\t\tif (options?.onDisconnect) this.#listeners.disconnect.add(options.onDisconnect)\n\t\tif (options?.onButtonDown) this.#listeners.buttonDown.add(options.onButtonDown)\n\t\tif (options?.onButtonUp) this.#listeners.buttonUp.add(options.onButtonUp)\n\t\tif (options?.onAxisChange) this.#listeners.axisChange.add(options.onAxisChange)\n\n\t\t// Bind event handlers\n\t\tthis.#boundGamepadConnected = this.#handleGamepadConnected.bind(this)\n\t\tthis.#boundGamepadDisconnected = this.#handleGamepadDisconnected.bind(this)\n\n\t\t// Add event listeners\n\t\twindow.addEventListener('gamepadconnected', this.#boundGamepadConnected)\n\t\twindow.addEventListener('gamepaddisconnected', this.#boundGamepadDisconnected)\n\n\t\t// Check for already connected gamepads\n\t\tthis.#pollConnectedGamepads()\n\t}\n\n\t// =========================================================================\n\t// Event Handlers\n\t// =========================================================================\n\n\t#handleGamepadConnected(event: GamepadEvent): void {\n\t\tconst gamepad = event.gamepad\n\t\tthis.#initializeGamepad(gamepad)\n\n\t\tfor (const callback of this.#listeners.connect) {\n\t\t\tcallback(gamepad.index, gamepad.id)\n\t\t}\n\t}\n\n\t#handleGamepadDisconnected(event: GamepadEvent): void {\n\t\tconst index = event.gamepad.index\n\t\tthis.#gamepads.delete(index)\n\t\tthis.#previousButtons.delete(index)\n\t\tthis.#previousAxes.delete(index)\n\n\t\tfor (const callback of this.#listeners.disconnect) {\n\t\t\tcallback(index)\n\t\t}\n\t}\n\n\t#pollConnectedGamepads(): void {\n\t\tconst gamepads = navigator.getGamepads()\n\t\tfor (const gamepad of gamepads) {\n\t\t\tif (gamepad) {\n\t\t\t\tthis.#initializeGamepad(gamepad)\n\t\t\t}\n\t\t}\n\t}\n\n\t#initializeGamepad(gamepad: Gamepad): void {\n\t\tconst buttons = this.#createButtonState(gamepad)\n\t\tconst axes = this.#createAxisState(gamepad)\n\n\t\tconst state: GamepadControllerState = {\n\t\t\tindex: gamepad.index,\n\t\t\tid: gamepad.id,\n\t\t\tconnected: gamepad.connected,\n\t\t\tbuttons,\n\t\t\tbuttonsPressed: new Set(),\n\t\t\tbuttonsReleased: new Set(),\n\t\t\taxes,\n\t\t\ttimestamp: gamepad.timestamp,\n\t\t}\n\n\t\tthis.#gamepads.set(gamepad.index, state)\n\t\tthis.#previousButtons.set(gamepad.index, new Set())\n\t\tthis.#previousAxes.set(gamepad.index, new Map())\n\t}\n\n\t#createButtonState(gamepad: Gamepad): Readonly<Record<GamepadButtonName, boolean>> {\n\t\tconst mapping = this.#getMappingForGamepad(gamepad)\n\t\tconst buttons: Record<string, boolean> = {}\n\n\t\tfor (const name of ALL_GAMEPAD_BUTTONS) {\n\t\t\tbuttons[name] = false\n\t\t}\n\n\t\tfor (let i = 0; i < gamepad.buttons.length; i++) {\n\t\t\tconst buttonName = mapping.buttons[i]\n\t\t\tconst ButtonInterface = gamepad.buttons[i]\n\t\t\tif (buttonName && ButtonInterface) {\n\t\t\t\tbuttons[buttonName] = ButtonInterface.pressed\n\t\t\t}\n\t\t}\n\n\t\treturn buttons as Readonly<Record<GamepadButtonName, boolean>>\n\t}\n\n\t#createAxisState(gamepad: Gamepad): Readonly<Record<GamepadAxisName, number>> {\n\t\tconst mapping = this.#getMappingForGamepad(gamepad)\n\t\tconst axes: Record<string, number> = {}\n\n\t\tfor (const name of ALL_GAMEPAD_AXES) {\n\t\t\taxes[name] = 0\n\t\t}\n\n\t\tfor (let i = 0; i < gamepad.axes.length; i++) {\n\t\t\tconst axisName = mapping.axes[i]\n\t\t\tconst axisValue = gamepad.axes[i]\n\t\t\tif (axisName && axisValue !== undefined) {\n\t\t\t\taxes[axisName] = this.#applyDeadzone(axisValue)\n\t\t\t}\n\t\t}\n\n\t\treturn axes as Readonly<Record<GamepadAxisName, number>>\n\t}\n\n\t#getMappingForGamepad(gamepad: Gamepad): GamepadMapping {\n\t\t// Check custom mappings first\n\t\tfor (const mapping of this.#customMappings.values()) {\n\t\t\tif (gamepad.id.includes(mapping.name)) {\n\t\t\t\treturn mapping\n\t\t\t}\n\t\t}\n\n\t\t// Fall back to standard mapping\n\t\treturn {\n\t\t\tname: 'standard',\n\t\t\tbuttons: STANDARD_BUTTON_MAPPING,\n\t\t\taxes: STANDARD_AXIS_MAPPING,\n\t\t}\n\t}\n\n\t#applyDeadzone(value: number): number {\n\t\tif (Math.abs(value) < this.#deadzone) {\n\t\t\treturn 0\n\t\t}\n\t\t// Rescale value outside deadzone\n\t\tconst sign = value > 0 ? 1 : -1\n\t\treturn sign * (Math.abs(value) - this.#deadzone) / (1 - this.#deadzone)\n\t}\n\n\t// =========================================================================\n\t// Accessors (GamepadManagerInterface interface)\n\t// =========================================================================\n\n\tgetGamepads(): readonly GamepadControllerState[] {\n\t\treturn Array.from(this.#gamepads.values())\n\t}\n\n\tgetGamepad(index: number): GamepadControllerState | undefined {\n\t\treturn this.#gamepads.get(index)\n\t}\n\n\tgetConnectedCount(): number {\n\t\treturn this.#gamepads.size\n\t}\n\n\thasGamepad(): boolean {\n\t\treturn this.#gamepads.size > 0\n\t}\n\n\tisButtonDown(index: number, ButtonInterface: GamepadButtonName): boolean {\n\t\tconst state = this.#gamepads.get(index)\n\t\treturn state?.buttons[ButtonInterface] ?? false\n\t}\n\n\tisButtonPressed(index: number, ButtonInterface: GamepadButtonName): boolean {\n\t\tconst state = this.#gamepads.get(index)\n\t\treturn state?.buttonsPressed.has(ButtonInterface) ?? false\n\t}\n\n\tisButtonReleased(index: number, ButtonInterface: GamepadButtonName): boolean {\n\t\tconst state = this.#gamepads.get(index)\n\t\treturn state?.buttonsReleased.has(ButtonInterface) ?? false\n\t}\n\n\tgetAxis(index: number, axis: GamepadAxisName): number {\n\t\tconst state = this.#gamepads.get(index)\n\t\treturn state?.axes[axis] ?? 0\n\t}\n\n\tgetStick(index: number, stick: 'left' | 'right'): Vector2 {\n\t\tconst xAxis = stick === 'left' ? 'left-x' : 'right-x'\n\t\tconst yAxis = stick === 'left' ? 'left-y' : 'right-y'\n\n\t\treturn {\n\t\t\tx: this.getAxis(index, xAxis),\n\t\t\ty: this.getAxis(index, yAxis),\n\t\t}\n\t}\n\n\t// =========================================================================\n\t// Mutators\n\t// =========================================================================\n\n\tasync vibrate(\n\t\tindex: number,\n\t\tduration: number,\n\t\tweakMagnitude = 0.5,\n\t\tstrongMagnitude = 0.5,\n\t): Promise<void> {\n\t\tconst gamepads = navigator.getGamepads()\n\t\tconst gamepad = gamepads[index]\n\n\t\tif (!gamepad?.vibrationActuator) {\n\t\t\treturn\n\t\t}\n\n\t\ttry {\n\t\t\tawait gamepad.vibrationActuator.playEffect('dual-rumble', {\n\t\t\t\tstartDelay: 0,\n\t\t\t\tduration,\n\t\t\t\tweakMagnitude,\n\t\t\t\tstrongMagnitude,\n\t\t\t})\n\t\t} catch {\n\t\t\t// Vibration not supported\n\t\t}\n\t}\n\n\tsetDeadzone(deadzone: number): void {\n\t\tthis.#deadzone = Math.max(0, Math.min(1, deadzone))\n\t}\n\n\tsetAxisThreshold(threshold: number): void {\n\t\tthis.#axisThreshold = Math.max(0, Math.min(1, threshold))\n\t}\n\n\t// =========================================================================\n\t// Event Subscriptions\n\t// =========================================================================\n\n\tonConnect(callback: (index: number, id: string) => void): Unsubscribe {\n\t\tthis.#listeners.connect.add(callback)\n\t\treturn () => this.#listeners.connect.delete(callback)\n\t}\n\n\tonDisconnect(callback: (index: number) => void): Unsubscribe {\n\t\tthis.#listeners.disconnect.add(callback)\n\t\treturn () => this.#listeners.disconnect.delete(callback)\n\t}\n\n\tonButtonDown(callback: (index: number, ButtonInterface: GamepadButtonName) => void): Unsubscribe {\n\t\tthis.#listeners.buttonDown.add(callback)\n\t\treturn () => this.#listeners.buttonDown.delete(callback)\n\t}\n\n\tonButtonUp(callback: (index: number, ButtonInterface: GamepadButtonName) => void): Unsubscribe {\n\t\tthis.#listeners.buttonUp.add(callback)\n\t\treturn () => this.#listeners.buttonUp.delete(callback)\n\t}\n\n\tonAxisChange(callback: (index: number, axis: GamepadAxisName, value: number) => void): Unsubscribe {\n\t\tthis.#listeners.axisChange.add(callback)\n\t\treturn () => this.#listeners.axisChange.delete(callback)\n\t}\n\n\t// =========================================================================\n\t// Lifecycle\n\t// =========================================================================\n\n\tupdate(): void {\n\t\tconst gamepads = navigator.getGamepads()\n\n\t\tfor (const gamepad of gamepads) {\n\t\t\tif (!gamepad) continue\n\n\t\t\tconst previousState = this.#gamepads.get(gamepad.index)\n\t\t\tif (!previousState) {\n\t\t\t\tthis.#initializeGamepad(gamepad)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst buttons = this.#createButtonState(gamepad)\n\t\t\tconst axes = this.#createAxisState(gamepad)\n\n\t\t\tconst buttonsPressed = new Set<GamepadButtonName>()\n\t\t\tconst buttonsReleased = new Set<GamepadButtonName>()\n\n\t\t\t// Detect ButtonInterface changes\n\t\t\tfor (const buttonName of ALL_GAMEPAD_BUTTONS) {\n\t\t\t\tconst wasDown = previousState.buttons[buttonName]\n\t\t\t\tconst isDown = buttons[buttonName]\n\n\t\t\t\tif (isDown && !wasDown) {\n\t\t\t\t\tbuttonsPressed.add(buttonName)\n\t\t\t\t\tfor (const callback of this.#listeners.buttonDown) {\n\t\t\t\t\t\tcallback(gamepad.index, buttonName)\n\t\t\t\t\t}\n\t\t\t\t} else if (!isDown && wasDown) {\n\t\t\t\t\tbuttonsReleased.add(buttonName)\n\t\t\t\t\tfor (const callback of this.#listeners.buttonUp) {\n\t\t\t\t\t\tcallback(gamepad.index, buttonName)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Detect axis changes\n\t\t\tconst prevAxes = this.#previousAxes.get(gamepad.index) ?? new Map()\n\t\t\tfor (const axisName of ALL_GAMEPAD_AXES) {\n\t\t\t\tconst prevValue = prevAxes.get(axisName) ?? 0\n\t\t\t\tconst newValue = axes[axisName]\n\n\t\t\t\tif (Math.abs(newValue - prevValue) > this.#axisThreshold) {\n\t\t\t\t\tfor (const callback of this.#listeners.axisChange) {\n\t\t\t\t\t\tcallback(gamepad.index, axisName, newValue)\n\t\t\t\t\t}\n\t\t\t\t\tprevAxes.set(axisName, newValue)\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.#previousAxes.set(gamepad.index, prevAxes)\n\n\t\t\t// Update state\n\t\t\tconst newState: GamepadControllerState = {\n\t\t\t\tindex: gamepad.index,\n\t\t\t\tid: gamepad.id,\n\t\t\t\tconnected: gamepad.connected,\n\t\t\t\tbuttons,\n\t\t\t\tbuttonsPressed,\n\t\t\t\tbuttonsReleased,\n\t\t\t\taxes,\n\t\t\t\ttimestamp: gamepad.timestamp,\n\t\t\t}\n\n\t\t\tthis.#gamepads.set(gamepad.index, newState)\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\twindow.removeEventListener('gamepadconnected', this.#boundGamepadConnected)\n\t\twindow.removeEventListener('gamepaddisconnected', this.#boundGamepadDisconnected)\n\n\t\tthis.#gamepads.clear()\n\t\tthis.#previousButtons.clear()\n\t\tthis.#previousAxes.clear()\n\t\tthis.#customMappings.clear()\n\t\tthis.#listeners.connect.clear()\n\t\tthis.#listeners.disconnect.clear()\n\t\tthis.#listeners.buttonDown.clear()\n\t\tthis.#listeners.buttonUp.clear()\n\t\tthis.#listeners.axisChange.clear()\n\t}\n}\n","import type {\n\tInputActionSystemInterface,\n\tInputActionSystemOptions,\n\tInputAction,\n\tInputActionBinding,\n\tInputActionContext,\n\tInputActionState,\n\tInputSourceType,\n\tKeyboardState,\n\tGamepadControllerState,\n\tInputState,\n\tUnsubscribe,\n} from '../../types.js'\nimport { now } from '../../helpers.js'\n\n/**\n * Input action system for unified input handling across multiple sources.\n * Maps keyboard, gamepad, mouse, and touch inputs to named actions.\n *\n * @example\n * ```ts\n * const actions = createInputActionSystem({\n * contexts: [{\n * name: 'gameplay',\n * priority: 0,\n * actions: [\n * { name: 'jump', bindings: [{ source: 'keyboard', key: 'Space' }, { source: 'gamepad', ButtonInterface: 'a' }] },\n * { name: 'move', bindings: [{ source: 'keyboard', key: 'KeyA' }, { source: 'keyboard', key: 'KeyD' }] },\n * ],\n * }],\n * })\n *\n * actions.enableContext('gameplay')\n * actions.update(keyboard.getState(), gamepad.getGamepad(0))\n *\n * if (actions.isActionActive('jump')) {\n * player.jump()\n * }\n * ```\n */\nexport class InputActionSystem implements InputActionSystemInterface {\n\t#actions: Map<string, InputAction> = new Map()\n\t#contexts: Map<string, InputActionContext> = new Map()\n\t#enabledContexts: Set<string> = new Set()\n\t#actionStates: Map<string, InputActionState> = new Map()\n\t#previousActionStates: Map<string, InputActionState> = new Map()\n\t#defaultBindings: Map<string, readonly InputActionBinding[]> = new Map()\n\n\t#persistBindings: boolean\n\t#storageKey: string\n\n\t#listeners = {\n\t\tactionStart: new Set<(actionName: string) => void>(),\n\t\tactionEnd: new Set<(actionName: string, duration: number) => void>(),\n\t\tactionChange: new Set<(actionName: string, value: number) => void>(),\n\t\trebind: new Set<(actionName: string, oldBinding: InputActionBinding, newBinding: InputActionBinding) => void>(),\n\t}\n\n\tconstructor(options?: InputActionSystemOptions) {\n\t\tthis.#persistBindings = options?.persistBindings ?? false\n\t\tthis.#storageKey = options?.storageKey ?? 'tactica-input-bindings'\n\n\t\t// Register contexts and their actions\n\t\tif (options?.contexts) {\n\t\t\tfor (const context of options.contexts) {\n\t\t\t\tthis.addContext(context)\n\t\t\t}\n\t\t}\n\n\t\t// Register hooks from options\n\t\tif (options?.onActionStart) this.#listeners.actionStart.add(options.onActionStart)\n\t\tif (options?.onActionEnd) this.#listeners.actionEnd.add(options.onActionEnd)\n\t\tif (options?.onActionChange) this.#listeners.actionChange.add(options.onActionChange)\n\t\tif (options?.onRebind) this.#listeners.rebind.add(options.onRebind)\n\n\t\t// Load persisted bindings\n\t\tif (this.#persistBindings) {\n\t\t\tthis.#loadBindings()\n\t\t}\n\t}\n\n\t// =========================================================================\n\t// Accessors (InputActionSystemInterface interface)\n\t// =========================================================================\n\n\tgetActionState(name: string): InputActionState | undefined {\n\t\treturn this.#actionStates.get(name)\n\t}\n\n\tisActionActive(name: string): boolean {\n\t\treturn this.#actionStates.get(name)?.isActive ?? false\n\t}\n\n\twasActionActive(name: string): boolean {\n\t\treturn this.#previousActionStates.get(name)?.isActive ?? false\n\t}\n\n\tgetActionValue(name: string): number {\n\t\treturn this.#actionStates.get(name)?.value ?? 0\n\t}\n\n\tgetActionDuration(name: string): number {\n\t\tconst state = this.#actionStates.get(name)\n\t\tif (!state?.isActive) return 0\n\t\treturn now() - state.startTime\n\t}\n\n\tgetAction(name: string): InputAction | undefined {\n\t\treturn this.#actions.get(name)\n\t}\n\n\tgetAllActions(): readonly InputAction[] {\n\t\treturn Array.from(this.#actions.values())\n\t}\n\n\tgetActiveContexts(): readonly string[] {\n\t\treturn Array.from(this.#enabledContexts)\n\t}\n\n\tisContextEnabled(name: string): boolean {\n\t\treturn this.#enabledContexts.has(name)\n\t}\n\n\t// =========================================================================\n\t// Mutators\n\t// =========================================================================\n\n\taddAction(action: InputAction): void {\n\t\tthis.#actions.set(action.name, action)\n\t\tthis.#defaultBindings.set(action.name, [...action.bindings])\n\t\tthis.#actionStates.set(action.name, {\n\t\t\tisActive: false,\n\t\t\twasActive: false,\n\t\t\tvalue: 0,\n\t\t\tstartTime: 0,\n\t\t\tduration: 0,\n\t\t})\n\t}\n\n\tremoveAction(name: string): void {\n\t\tthis.#actions.delete(name)\n\t\tthis.#actionStates.delete(name)\n\t\tthis.#previousActionStates.delete(name)\n\t\tthis.#defaultBindings.delete(name)\n\t}\n\n\taddContext(context: InputActionContext): void {\n\t\tthis.#contexts.set(context.name, context)\n\n\t\t// Add all actions from this context\n\t\tfor (const action of context.actions) {\n\t\t\tthis.addAction(action)\n\t\t}\n\t}\n\n\tremoveContext(name: string): void {\n\t\tconst context = this.#contexts.get(name)\n\t\tif (context) {\n\t\t\t// Remove all actions from this context\n\t\t\tfor (const action of context.actions) {\n\t\t\t\tthis.removeAction(action.name)\n\t\t\t}\n\t\t\tthis.#contexts.delete(name)\n\t\t\tthis.#enabledContexts.delete(name)\n\t\t}\n\t}\n\n\tenableContext(name: string): void {\n\t\tif (this.#contexts.has(name)) {\n\t\t\tthis.#enabledContexts.add(name)\n\t\t}\n\t}\n\n\tdisableContext(name: string): void {\n\t\tthis.#enabledContexts.delete(name)\n\t}\n\n\trebind(actionName: string, bindingIndex: number, newBinding: InputActionBinding): boolean {\n\t\tconst action = this.#actions.get(actionName)\n\t\tif (!action || !action.rebindable) return false\n\t\tif (bindingIndex < 0 || bindingIndex >= action.bindings.length) return false\n\n\t\tconst oldBinding = action.bindings[bindingIndex]\n\t\tif (!oldBinding) return false\n\n\t\t// Create new bindings array with the updated binding\n\t\tconst newBindings = [...action.bindings]\n\t\tnewBindings[bindingIndex] = newBinding\n\n\t\t// Update action with new bindings\n\t\tconst updatedAction: InputAction = {\n\t\t\t...action,\n\t\t\tbindings: newBindings,\n\t\t}\n\t\tthis.#actions.set(actionName, updatedAction)\n\n\t\t// Emit rebind event\n\t\tfor (const callback of this.#listeners.rebind) {\n\t\t\tcallback(actionName, oldBinding, newBinding)\n\t\t}\n\n\t\t// Persist bindings\n\t\tif (this.#persistBindings) {\n\t\t\tthis.#saveBindings()\n\t\t}\n\n\t\treturn true\n\t}\n\n\tresetToDefaults(): void {\n\t\tfor (const [actionName, defaultBindings] of this.#defaultBindings) {\n\t\t\tconst action = this.#actions.get(actionName)\n\t\t\tif (action) {\n\t\t\t\tconst updatedAction: InputAction = {\n\t\t\t\t\t...action,\n\t\t\t\t\tbindings: defaultBindings,\n\t\t\t\t}\n\t\t\t\tthis.#actions.set(actionName, updatedAction)\n\t\t\t}\n\t\t}\n\n\t\tif (this.#persistBindings) {\n\t\t\tthis.#saveBindings()\n\t\t}\n\t}\n\n\texportBindings(): string {\n\t\tconst bindings: Record<string, readonly InputActionBinding[]> = {}\n\t\tfor (const [name, action] of this.#actions) {\n\t\t\tbindings[name] = action.bindings\n\t\t}\n\t\treturn JSON.stringify(bindings)\n\t}\n\n\timportBindings(data: string): boolean {\n\t\ttry {\n\t\t\tconst bindings = JSON.parse(data) as Record<string, readonly InputActionBinding[]>\n\t\t\tfor (const [actionName, actionBindings] of Object.entries(bindings)) {\n\t\t\t\tconst action = this.#actions.get(actionName)\n\t\t\t\tif (action && action.rebindable !== false) {\n\t\t\t\t\tconst updatedAction: InputAction = {\n\t\t\t\t\t\t...action,\n\t\t\t\t\t\tbindings: actionBindings,\n\t\t\t\t\t}\n\t\t\t\t\tthis.#actions.set(actionName, updatedAction)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (this.#persistBindings) {\n\t\t\t\tthis.#saveBindings()\n\t\t\t}\n\t\t\treturn true\n\t\t} catch {\n\t\t\treturn false\n\t\t}\n\t}\n\n\t// =========================================================================\n\t// Event Subscriptions\n\t// =========================================================================\n\n\tonActionStart(callback: (actionName: string) => void): Unsubscribe {\n\t\tthis.#listeners.actionStart.add(callback)\n\t\treturn () => this.#listeners.actionStart.delete(callback)\n\t}\n\n\tonActionEnd(callback: (actionName: string, duration: number) => void): Unsubscribe {\n\t\tthis.#listeners.actionEnd.add(callback)\n\t\treturn () => this.#listeners.actionEnd.delete(callback)\n\t}\n\n\tonActionChange(callback: (actionName: string, value: number) => void): Unsubscribe {\n\t\tthis.#listeners.actionChange.add(callback)\n\t\treturn () => this.#listeners.actionChange.delete(callback)\n\t}\n\n\tonRebind(callback: (actionName: string, oldBinding: InputActionBinding, newBinding: InputActionBinding) => void): Unsubscribe {\n\t\tthis.#listeners.rebind.add(callback)\n\t\treturn () => this.#listeners.rebind.delete(callback)\n\t}\n\n\t// =========================================================================\n\t// Lifecycle\n\t// =========================================================================\n\n\tupdate(keyboard: KeyboardState, gamepad?: GamepadControllerState, input?: InputState): void {\n\t\tconst currentTime = now()\n\n\t\t// Save previous states\n\t\tfor (const [name, state] of this.#actionStates) {\n\t\t\tthis.#previousActionStates.set(name, state)\n\t\t}\n\n\t\t// Check each enabled context (sorted by priority)\n\t\tconst sortedContexts = Array.from(this.#enabledContexts)\n\t\t\t.map(name => this.#contexts.get(name))\n\t\t\t.filter((ctx): ctx is InputActionContext => ctx !== undefined)\n\t\t\t.sort((a, b) => b.priority - a.priority)\n\n\t\tconst processedActions = new Set<string>()\n\n\t\tfor (const context of sortedContexts) {\n\t\t\tif (context.exclusive && processedActions.size > 0) continue\n\n\t\t\tfor (const action of context.actions) {\n\t\t\t\tif (processedActions.has(action.name)) continue\n\n\t\t\t\tconst value = this.#evaluateAction(action, keyboard, gamepad, input)\n\t\t\t\tconst isActive = value !== 0\n\t\t\t\tconst prevState = this.#previousActionStates.get(action.name)\n\t\t\t\tconst wasActive = prevState?.isActive ?? false\n\n\t\t\t\tconst newState: InputActionState = {\n\t\t\t\t\tisActive,\n\t\t\t\t\twasActive,\n\t\t\t\t\tvalue,\n\t\t\t\t\tstartTime: isActive && !wasActive ? currentTime : (prevState?.startTime ?? 0),\n\t\t\t\t\tduration: isActive ? currentTime - (prevState?.startTime ?? currentTime) : 0,\n\t\t\t\t}\n\n\t\t\t\tthis.#actionStates.set(action.name, newState)\n\t\t\t\tprocessedActions.add(action.name)\n\n\t\t\t\t// Emit events\n\t\t\t\tif (isActive && !wasActive) {\n\t\t\t\t\tfor (const callback of this.#listeners.actionStart) {\n\t\t\t\t\t\tcallback(action.name)\n\t\t\t\t\t}\n\t\t\t\t} else if (!isActive && wasActive) {\n\t\t\t\t\tconst duration = currentTime - (prevState?.startTime ?? currentTime)\n\t\t\t\t\tfor (const callback of this.#listeners.actionEnd) {\n\t\t\t\t\t\tcallback(action.name, duration)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (value !== (prevState?.value ?? 0)) {\n\t\t\t\t\tfor (const callback of this.#listeners.actionChange) {\n\t\t\t\t\t\tcallback(action.name, value)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.#actions.clear()\n\t\tthis.#contexts.clear()\n\t\tthis.#enabledContexts.clear()\n\t\tthis.#actionStates.clear()\n\t\tthis.#previousActionStates.clear()\n\t\tthis.#defaultBindings.clear()\n\t\tthis.#listeners.actionStart.clear()\n\t\tthis.#listeners.actionEnd.clear()\n\t\tthis.#listeners.actionChange.clear()\n\t\tthis.#listeners.rebind.clear()\n\t}\n\n\t// =========================================================================\n\t// Private Methods\n\t// =========================================================================\n\n\t#evaluateAction(\n\t\taction: InputAction,\n\t\tkeyboard: KeyboardState,\n\t\tgamepad?: GamepadControllerState,\n\t\tinput?: InputState,\n\t): number {\n\t\tlet maxValue = 0\n\n\t\tfor (const binding of action.bindings) {\n\t\t\tconst value = this.#evaluateBinding(binding, keyboard, gamepad, input)\n\t\t\tif (Math.abs(value) > Math.abs(maxValue)) {\n\t\t\t\tmaxValue = value\n\t\t\t}\n\t\t}\n\n\t\treturn maxValue\n\t}\n\n\t#evaluateBinding(\n\t\tbinding: InputActionBinding,\n\t\tkeyboard: KeyboardState,\n\t\tgamepad?: GamepadControllerState,\n\t\tinput?: InputState,\n\t): number {\n\t\t// Check modifiers first\n\t\tif (binding.modifiers) {\n\t\t\tif (binding.modifiers.ctrl && !keyboard.modifiers.ctrl) return 0\n\t\t\tif (binding.modifiers.shift && !keyboard.modifiers.shift) return 0\n\t\t\tif (binding.modifiers.alt && !keyboard.modifiers.alt) return 0\n\t\t}\n\n\t\tconst source = binding.source as InputSourceType\n\n\t\tswitch (source) {\n\t\t\tcase 'keyboard':\n\t\t\t\tif (binding.key && keyboard.keysDown.has(binding.key)) {\n\t\t\t\t\treturn 1\n\t\t\t\t}\n\t\t\t\tbreak\n\n\t\t\tcase 'gamepad':\n\t\t\t\tif (!gamepad) return 0\n\n\t\t\t\t// Check ButtonInterface\n\t\t\t\tif (binding.ButtonInterface !== undefined) {\n\t\t\t\t\tconst buttonName = binding.ButtonInterface\n\t\t\t\t\tif (typeof buttonName === 'string' && gamepad.buttons[buttonName]) {\n\t\t\t\t\t\treturn 1\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Check axis\n\t\t\t\tif (binding.axis !== undefined) {\n\t\t\t\t\tconst axisName = binding.axis as keyof typeof gamepad.axes\n\t\t\t\t\tconst value = gamepad.axes[axisName]\n\t\t\t\t\tif (value !== undefined) {\n\t\t\t\t\t\treturn value\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\n\t\t\tcase 'mouse':\n\t\t\t\tif (!input) return 0\n\t\t\t\tif (binding.ButtonInterface !== undefined && input.isPointerDown) {\n\t\t\t\t\treturn 1\n\t\t\t\t}\n\t\t\t\tbreak\n\n\t\t\tcase 'touch':\n\t\t\t\tif (!input) return 0\n\t\t\t\tif (input.touches.length > 0) {\n\t\t\t\t\treturn 1\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t}\n\n\t\treturn 0\n\t}\n\n\t#loadBindings(): void {\n\t\ttry {\n\t\t\tconst data = localStorage.getItem(this.#storageKey)\n\t\t\tif (data) {\n\t\t\t\tthis.importBindings(data)\n\t\t\t}\n\t\t} catch {\n\t\t\t// Storage not available\n\t\t}\n\t}\n\n\t#saveBindings(): void {\n\t\ttry {\n\t\t\tconst data = this.exportBindings()\n\t\t\tlocalStorage.setItem(this.#storageKey, data)\n\t\t} catch {\n\t\t\t// Storage not available\n\t\t}\n\t}\n}\n","import type {\r\n\tAudioManagerInterface,\r\n\tAudioManagerOptions,\r\n\tAudioPlayOptions,\r\n\tAudioState,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Audio manager for playing and controlling game audio.\r\n */\r\nexport class AudioManager implements AudioManagerInterface {\r\n\t#audioElements: Map<string, HTMLAudioElement> = new Map()\r\n\t#audioStates: Map<string, AudioState> = new Map()\r\n\t#masterVolume: number\r\n\t#muted: boolean\r\n\t#maxConcurrentSounds: number\r\n\r\n\t#listeners = {\r\n\t\tplay: new Set<(key: string) => void>(),\r\n\t\tpause: new Set<(key: string) => void>(),\r\n\t\tstop: new Set<(key: string) => void>(),\r\n\t\tcomplete: new Set<(key: string) => void>(),\r\n\t\tvolumeChange: new Set<(volume: number) => void>(),\r\n\t}\r\n\r\n\tconstructor(options?: AudioManagerOptions) {\r\n\t\tthis.#masterVolume = options?.masterVolume ?? 1\r\n\t\tthis.#muted = options?.muted ?? false\r\n\t\tthis.#maxConcurrentSounds = options?.maxConcurrentSounds ?? 32\r\n\r\n\t\t// Register hooks from options\r\n\t\tif (options?.onPlay) this.#listeners.play.add(options.onPlay)\r\n\t\tif (options?.onPause) this.#listeners.pause.add(options.onPause)\r\n\t\tif (options?.onStop) this.#listeners.stop.add(options.onStop)\r\n\t\tif (options?.onComplete) this.#listeners.complete.add(options.onComplete)\r\n\t\tif (options?.onVolumeChange) this.#listeners.volumeChange.add(options.onVolumeChange)\r\n\t}\r\n\r\n\tregister(key: string, audio: HTMLAudioElement): void {\r\n\t\tthis.#audioElements.set(key, audio)\r\n\t\taudio.addEventListener('ended', () => {\r\n\t\t\tif (!audio.loop) {\r\n\t\t\t\tthis.#listeners.complete.forEach(cb => cb(key))\r\n\t\t\t}\r\n\t\t})\r\n\t}\r\n\r\n\tunregister(key: string): void {\r\n\t\tconst audio = this.#audioElements.get(key)\r\n\t\tif (audio) {\r\n\t\t\taudio.pause()\r\n\t\t\tthis.#audioElements.delete(key)\r\n\t\t}\r\n\t}\r\n\r\n\thasAudio(key: string): boolean {\r\n\t\treturn this.#audioElements.has(key)\r\n\t}\r\n\r\n\tplay(key: string, options?: Partial<AudioPlayOptions>): void {\r\n\t\tconst audio = this.#audioElements.get(key)\r\n\t\tif (!audio) return\r\n\r\n\t\taudio.volume = (options?.volume ?? 1) * this.#masterVolume\r\n\t\taudio.loop = options?.loop ?? false\r\n\t\taudio.playbackRate = options?.playbackRate ?? 1\r\n\t\tif (options?.startTime !== undefined) {\r\n\t\t\taudio.currentTime = options.startTime\r\n\t\t}\r\n\r\n\t\taudio.play()\r\n\t\tthis.#listeners.play.forEach(cb => cb(key))\r\n\t}\r\n\r\n\tplayOneShot(key: string, volume?: number): void {\r\n\t\tconst audio = this.#audioElements.get(key)\r\n\t\tif (!audio) return\r\n\r\n\t\tconst clone = audio.cloneNode() as HTMLAudioElement\r\n\t\tclone.volume = (volume ?? 1) * this.#masterVolume\r\n\t\tclone.play()\r\n\t}\r\n\r\n\tpause(key: string): void {\r\n\t\tconst audio = this.#audioElements.get(key)\r\n\t\tif (!audio) return\r\n\r\n\t\taudio.pause()\r\n\t\tthis.#listeners.pause.forEach(cb => cb(key))\r\n\t}\r\n\r\n\tresume(key: string): void {\r\n\t\tconst audio = this.#audioElements.get(key)\r\n\t\tif (!audio) return\r\n\r\n\t\taudio.play()\r\n\t}\r\n\r\n\tstop(key: string): void {\r\n\t\tconst audio = this.#audioElements.get(key)\r\n\t\tif (!audio) return\r\n\r\n\t\taudio.pause()\r\n\t\taudio.currentTime = 0\r\n\t\tthis.#listeners.stop.forEach(cb => cb(key))\r\n\t}\r\n\r\n\tstopAll(): void {\r\n\t\tfor (const key of this.#audioElements.keys()) {\r\n\t\t\tthis.stop(key)\r\n\t\t}\r\n\t}\r\n\r\n\tgetState(key: string): AudioState | undefined {\r\n\t\treturn this.#audioStates.get(key)\r\n\t}\r\n\r\n\tisPlaying(key: string): boolean {\r\n\t\tconst audio = this.#audioElements.get(key)\r\n\t\treturn audio ? !audio.paused : false\r\n\t}\r\n\r\n\tisPaused(key: string): boolean {\r\n\t\tconst audio = this.#audioElements.get(key)\r\n\t\treturn audio ? audio.paused : false\r\n\t}\r\n\r\n\tsetVolume(key: string, volume: number): void {\r\n\t\tconst audio = this.#audioElements.get(key)\r\n\t\tif (!audio) return\r\n\r\n\t\taudio.volume = volume * this.#masterVolume\r\n\t}\r\n\r\n\tsetMasterVolume(volume: number): void {\r\n\t\tthis.#masterVolume = volume\r\n\t\tfor (const audio of this.#audioElements.values()) {\r\n\t\t\taudio.volume = this.#masterVolume\r\n\t\t}\r\n\t\tthis.#listeners.volumeChange.forEach(cb => cb(volume))\r\n\t}\r\n\r\n\tgetMasterVolume(): number {\r\n\t\treturn this.#masterVolume\r\n\t}\r\n\r\n\tsetPlaybackRate(key: string, rate: number): void {\r\n\t\tconst audio = this.#audioElements.get(key)\r\n\t\tif (!audio) return\r\n\r\n\t\taudio.playbackRate = rate\r\n\t}\r\n\r\n\tsetLoop(key: string, loop: boolean): void {\r\n\t\tconst audio = this.#audioElements.get(key)\r\n\t\tif (!audio) return\r\n\r\n\t\taudio.loop = loop\r\n\t}\r\n\r\n\tfadeIn(key: string, duration: number, targetVolume?: number): void {\r\n\t\tconst audio = this.#audioElements.get(key)\r\n\t\tif (!audio) return\r\n\r\n\t\tconst target = targetVolume ?? 1\r\n\t\tconst steps = 60\r\n\t\tconst increment = target / steps\r\n\t\tlet currentVolume = 0\r\n\r\n\t\tconst interval = setInterval(() => {\r\n\t\t\tcurrentVolume += increment\r\n\t\t\tif (currentVolume >= target) {\r\n\t\t\t\tcurrentVolume = target\r\n\t\t\t\tclearInterval(interval)\r\n\t\t\t}\r\n\t\t\taudio.volume = currentVolume * this.#masterVolume\r\n\t\t}, duration / steps)\r\n\t}\r\n\r\n\tfadeOut(key: string, duration: number): void {\r\n\t\tconst audio = this.#audioElements.get(key)\r\n\t\tif (!audio) return\r\n\r\n\t\tconst startVolume = audio.volume\r\n\t\tconst steps = 60\r\n\t\tconst decrement = startVolume / steps\r\n\r\n\t\tconst interval = setInterval(() => {\r\n\t\t\taudio.volume -= decrement\r\n\t\t\tif (audio.volume <= 0) {\r\n\t\t\t\taudio.volume = 0\r\n\t\t\t\taudio.pause()\r\n\t\t\t\tclearInterval(interval)\r\n\t\t\t}\r\n\t\t}, duration / steps)\r\n\t}\r\n\r\n\tcrossfade(fromKey: string, toKey: string, duration: number): void {\r\n\t\tthis.fadeOut(fromKey, duration)\r\n\t\tthis.fadeIn(toKey, duration)\r\n\t}\r\n\r\n\tmute(): void {\r\n\t\tthis.#muted = true\r\n\t\tfor (const audio of this.#audioElements.values()) {\r\n\t\t\taudio.muted = true\r\n\t\t}\r\n\t}\r\n\r\n\tunmute(): void {\r\n\t\tthis.#muted = false\r\n\t\tfor (const audio of this.#audioElements.values()) {\r\n\t\t\taudio.muted = false\r\n\t\t}\r\n\t}\r\n\r\n\tisMuted(): boolean {\r\n\t\treturn this.#muted\r\n\t}\r\n\r\n\tonPlay(callback: (key: string) => void): Unsubscribe {\r\n\t\tthis.#listeners.play.add(callback)\r\n\t\treturn () => this.#listeners.play.delete(callback)\r\n\t}\r\n\r\n\tonPause(callback: (key: string) => void): Unsubscribe {\r\n\t\tthis.#listeners.pause.add(callback)\r\n\t\treturn () => this.#listeners.pause.delete(callback)\r\n\t}\r\n\r\n\tonStop(callback: (key: string) => void): Unsubscribe {\r\n\t\tthis.#listeners.stop.add(callback)\r\n\t\treturn () => this.#listeners.stop.delete(callback)\r\n\t}\r\n\r\n\tonComplete(callback: (key: string) => void): Unsubscribe {\r\n\t\tthis.#listeners.complete.add(callback)\r\n\t\treturn () => this.#listeners.complete.delete(callback)\r\n\t}\r\n\r\n\tonVolumeChange(callback: (volume: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.volumeChange.add(callback)\r\n\t\treturn () => this.#listeners.volumeChange.delete(callback)\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.stopAll()\r\n\t\tthis.#audioElements.clear()\r\n\t\tthis.#audioStates.clear()\r\n\t\tthis.#listeners.play.clear()\r\n\t\tthis.#listeners.pause.clear()\r\n\t\tthis.#listeners.stop.clear()\r\n\t\tthis.#listeners.complete.clear()\r\n\t\tthis.#listeners.volumeChange.clear()\r\n\t}\r\n}\r\n","import type {\n\tMusicPlaylistInterface,\n\tMusicPlaylistOptions,\n\tMusicPlaylistState,\n\tMusicTrack,\n\tPlaylistMode,\n\tUnsubscribe,\n} from '../../types.js'\n\n/**\n * Music playlist for managing sequential/shuffled music playback.\n *\n * @example\n * ```ts\n * const playlist = createMusicPlaylist({\n * tracks: [\n * { key: 'menu', name: 'Menu Music' },\n * { key: 'gameplay', name: 'Gameplay Music' },\n * ],\n * mode: 'shuffle',\n * })\n * playlist.play()\n * ```\n */\nexport class MusicPlaylist implements MusicPlaylistInterface {\n\t#tracks: MusicTrack[] = []\n\t#currentIndex = -1\n\t#isPlaying = false\n\t#isPaused = false\n\t#mode: PlaylistMode\n\t#crossfadeDuration: number\n\t#volume = 1.0\n\t#progress = 0\n\n\t#listeners = {\n\t\ttrackStart: new Set<(track: MusicTrack) => void>(),\n\t\ttrackEnd: new Set<(track: MusicTrack) => void>(),\n\t\ttrackChange: new Set<(from: MusicTrack | undefined, to: MusicTrack) => void>(),\n\t\tplaylistEnd: new Set<() => void>(),\n\t\tmodeChange: new Set<(mode: PlaylistMode) => void>(),\n\t}\n\n\tconstructor(options?: MusicPlaylistOptions) {\n\t\tthis.#mode = options?.mode ?? 'sequential'\n\t\tthis.#crossfadeDuration = options?.crossfadeDuration ?? 0\n\t\tthis.#volume = options?.volume ?? 1.0\n\n\t\tif (options?.tracks) {\n\t\t\tthis.#tracks = [...options.tracks]\n\t\t}\n\n\t\t// Register hooks from options\n\t\tif (options?.onTrackStart) this.#listeners.trackStart.add(options.onTrackStart)\n\t\tif (options?.onTrackEnd) this.#listeners.trackEnd.add(options.onTrackEnd)\n\t\tif (options?.onTrackChange) this.#listeners.trackChange.add(options.onTrackChange)\n\t\tif (options?.onPlaylistEnd) this.#listeners.playlistEnd.add(options.onPlaylistEnd)\n\t\tif (options?.onModeChange) this.#listeners.modeChange.add(options.onModeChange)\n\n\t\tif (options?.autoPlay && this.#tracks.length > 0) {\n\t\t\tthis.play()\n\t\t}\n\t}\n\n\t// =========================================================================\n\t// Accessors\n\t// =========================================================================\n\n\tgetState(): MusicPlaylistState {\n\t\treturn {\n\t\t\tcurrentTrack: this.getCurrentTrack(),\n\t\t\tcurrentIndex: this.#currentIndex,\n\t\t\tisPlaying: this.#isPlaying,\n\t\t\tisPaused: this.#isPaused,\n\t\t\tmode: this.#mode,\n\t\t\tprogress: this.#progress,\n\t\t\tvolume: this.#volume,\n\t\t}\n\t}\n\n\tgetCurrentTrack(): MusicTrack | undefined {\n\t\tif (this.#currentIndex < 0 || this.#currentIndex >= this.#tracks.length) {\n\t\t\treturn undefined\n\t\t}\n\t\treturn this.#tracks[this.#currentIndex]\n\t}\n\n\tgetCurrentIndex(): number {\n\t\treturn this.#currentIndex\n\t}\n\n\tgetTracks(): readonly MusicTrack[] {\n\t\treturn this.#tracks\n\t}\n\n\tgetTrackCount(): number {\n\t\treturn this.#tracks.length\n\t}\n\n\tgetMode(): PlaylistMode {\n\t\treturn this.#mode\n\t}\n\n\t// =========================================================================\n\t// Mutators\n\t// =========================================================================\n\n\taddTrack(track: MusicTrack): void {\n\t\tthis.#tracks.push(track)\n\t}\n\n\tremoveTrack(key: string): void {\n\t\tconst index = this.#tracks.findIndex(t => t.key === key)\n\t\tif (index >= 0) {\n\t\t\tthis.#tracks.splice(index, 1)\n\t\t\t// Adjust current index if needed\n\t\t\tif (this.#currentIndex > index) {\n\t\t\t\tthis.#currentIndex--\n\t\t\t} else if (this.#currentIndex === index) {\n\t\t\t\tthis.#currentIndex = Math.min(this.#currentIndex, this.#tracks.length - 1)\n\t\t\t}\n\t\t}\n\t}\n\n\tclearTracks(): void {\n\t\tthis.#tracks = []\n\t\tthis.#currentIndex = -1\n\t\tthis.#isPlaying = false\n\t\tthis.#isPaused = false\n\t}\n\n\tsetTracks(tracks: readonly MusicTrack[]): void {\n\t\tthis.#tracks = [...tracks]\n\t\tthis.#currentIndex = -1\n\t\tthis.#isPlaying = false\n\t\tthis.#isPaused = false\n\t}\n\n\tsetMode(mode: PlaylistMode): void {\n\t\tif (this.#mode !== mode) {\n\t\t\tthis.#mode = mode\n\t\t\tfor (const callback of this.#listeners.modeChange) {\n\t\t\t\tcallback(mode)\n\t\t\t}\n\t\t}\n\t}\n\n\t// =========================================================================\n\t// Playback Controls\n\t// =========================================================================\n\n\tplay(): void {\n\t\tif (this.#tracks.length === 0) return\n\n\t\tif (this.#isPaused) {\n\t\t\tthis.#isPaused = false\n\t\t\tthis.#isPlaying = true\n\t\t\treturn\n\t\t}\n\n\t\tif (this.#currentIndex < 0) {\n\t\t\tthis.#currentIndex = 0\n\t\t}\n\n\t\tthis.#isPlaying = true\n\t\tthis.#isPaused = false\n\t\tthis.#emitTrackChange()\n\t}\n\n\tpause(): void {\n\t\tif (this.#isPlaying) {\n\t\t\tthis.#isPaused = true\n\t\t\tthis.#isPlaying = false\n\t\t}\n\t}\n\n\tstop(): void {\n\t\tthis.#isPlaying = false\n\t\tthis.#isPaused = false\n\t\tthis.#currentIndex = -1\n\t}\n\n\tnext(): void {\n\t\tif (this.#tracks.length === 0) return\n\n\t\tif (this.#mode === 'repeat-one') {\n\t\t\t// Stay on same track\n\t\t\tthis.#emitTrackChange()\n\t\t\treturn\n\t\t}\n\n\t\tif (this.#mode === 'shuffle') {\n\t\t\tthis.#currentIndex = Math.floor(Math.random() * this.#tracks.length)\n\t\t} else {\n\t\t\tthis.#currentIndex++\n\t\t}\n\n\t\tif (this.#currentIndex >= this.#tracks.length) {\n\t\t\tif (this.#mode === 'repeat-all') {\n\t\t\t\tthis.#currentIndex = 0\n\t\t\t} else {\n\t\t\t\tthis.#currentIndex = this.#tracks.length - 1\n\t\t\t\tthis.#isPlaying = false\n\t\t\t\tfor (const callback of this.#listeners.playlistEnd) {\n\t\t\t\t\tcallback()\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tthis.#emitTrackChange()\n\t}\n\n\tprevious(): void {\n\t\tif (this.#tracks.length === 0) return\n\n\t\tthis.#currentIndex--\n\t\tif (this.#currentIndex < 0) {\n\t\t\tthis.#currentIndex = this.#mode === 'repeat-all' ? this.#tracks.length - 1 : 0\n\t\t}\n\n\t\tthis.#emitTrackChange()\n\t}\n\n\tplayTrack(key: string): void {\n\t\tconst index = this.#tracks.findIndex(t => t.key === key)\n\t\tif (index >= 0) {\n\t\t\tthis.#currentIndex = index\n\t\t\tthis.#isPlaying = true\n\t\t\tthis.#isPaused = false\n\t\t\tthis.#emitTrackChange()\n\t\t}\n\t}\n\n\tskipTo(index: number): void {\n\t\tif (index >= 0 && index < this.#tracks.length) {\n\t\t\tthis.#currentIndex = index\n\t\t\tthis.#emitTrackChange()\n\t\t}\n\t}\n\n\tshuffle(): void {\n\t\t// Fisher-Yates shuffle\n\t\tfor (let i = this.#tracks.length - 1; i > 0; i--) {\n\t\t\tconst j = Math.floor(Math.random() * (i + 1))\n\t\t\tconst temp = this.#tracks[i]\n\t\t\tconst trackJ = this.#tracks[j]\n\t\t\tif (temp !== undefined && trackJ !== undefined) {\n\t\t\t\tthis.#tracks[i] = trackJ\n\t\t\t\tthis.#tracks[j] = temp\n\t\t\t}\n\t\t}\n\t}\n\n\t// =========================================================================\n\t// Event Subscriptions\n\t// =========================================================================\n\n\tonTrackStart(callback: (track: MusicTrack) => void): Unsubscribe {\n\t\tthis.#listeners.trackStart.add(callback)\n\t\treturn () => this.#listeners.trackStart.delete(callback)\n\t}\n\n\tonTrackEnd(callback: (track: MusicTrack) => void): Unsubscribe {\n\t\tthis.#listeners.trackEnd.add(callback)\n\t\treturn () => this.#listeners.trackEnd.delete(callback)\n\t}\n\n\tonTrackChange(callback: (from: MusicTrack | undefined, to: MusicTrack) => void): Unsubscribe {\n\t\tthis.#listeners.trackChange.add(callback)\n\t\treturn () => this.#listeners.trackChange.delete(callback)\n\t}\n\n\tonPlaylistEnd(callback: () => void): Unsubscribe {\n\t\tthis.#listeners.playlistEnd.add(callback)\n\t\treturn () => this.#listeners.playlistEnd.delete(callback)\n\t}\n\n\tonModeChange(callback: (mode: PlaylistMode) => void): Unsubscribe {\n\t\tthis.#listeners.modeChange.add(callback)\n\t\treturn () => this.#listeners.modeChange.delete(callback)\n\t}\n\n\t// =========================================================================\n\t// Volume and Progress\n\t// =========================================================================\n\n\tresume(): void {\n\t\tif (this.#isPaused) {\n\t\t\tthis.#isPaused = false\n\t\t\tthis.#isPlaying = true\n\t\t}\n\t}\n\n\tsetVolume(volume: number): void {\n\t\tthis.#volume = Math.max(0, Math.min(1, volume))\n\t}\n\n\tgetVolume(): number {\n\t\treturn this.#volume\n\t}\n\n\tfadeIn(_duration: number): void {\n\t\t// Implementation would gradually increase volume over duration\n\t\tthis.#volume = 1.0\n\t}\n\n\tfadeOut(_duration: number): void {\n\t\t// Implementation would gradually decrease volume over duration\n\t\tthis.#volume = 0\n\t}\n\n\tgetProgress(): number {\n\t\treturn this.#progress\n\t}\n\n\tseek(progress: number): void {\n\t\tthis.#progress = Math.max(0, Math.min(1, progress))\n\t}\n\n\t// =========================================================================\n\t// Lifecycle\n\t// =========================================================================\n\n\tdestroy(): void {\n\t\tthis.#tracks = []\n\t\tthis.#currentIndex = -1\n\t\tthis.#isPlaying = false\n\t\tthis.#isPaused = false\n\t\tthis.#listeners.trackStart.clear()\n\t\tthis.#listeners.trackEnd.clear()\n\t\tthis.#listeners.trackChange.clear()\n\t\tthis.#listeners.playlistEnd.clear()\n\t\tthis.#listeners.modeChange.clear()\n\t}\n\n\t// =========================================================================\n\t// Private Methods\n\t// =========================================================================\n\n\t#emitTrackChange(previousTrack: MusicTrack | undefined = undefined): void {\n\t\tconst currentTrack = this.getCurrentTrack()\n\t\tif (currentTrack) {\n\t\t\tfor (const callback of this.#listeners.trackChange) {\n\t\t\t\tcallback(previousTrack, currentTrack)\n\t\t\t}\n\t\t}\n\t}\n}\n","import type {\n\tSoundVariantPoolInterface,\n\tSoundVariantPoolOptions,\n\tSoundVariantPoolState,\n\tSoundVariant,\n\tAudioManagerInterface,\n} from '../../types.js'\n\n/**\n * Sound variant pool for playing random sound variations.\n * Useful for footsteps, gunshots, impacts, etc.\n *\n * @example\n * ```ts\n * const footsteps = createSoundVariantPool({\n * variants: [\n * { key: 'step-1', weight: 1 },\n * { key: 'step-2', weight: 1 },\n * { key: 'step-3', weight: 0.5 },\n * ],\n * cooldown: 100,\n * preventRepeat: true,\n * })\n * footsteps.play(audioManager, 0.8)\n * ```\n */\nexport class SoundVariantPool implements SoundVariantPoolInterface {\n\t#variants: SoundVariant[] = []\n\t#lastPlayedKey: string | undefined\n\t#cooldown: number\n\t#cooldownRemaining = 0\n\t#preventRepeat: boolean\n\t#totalWeight = 0\n\t#pitchVariation: { min: number; max: number } | undefined\n\t#volumeVariation: { min: number; max: number } | undefined\n\n\tconstructor(options: SoundVariantPoolOptions) {\n\t\tthis.#cooldown = options.cooldown ?? 0\n\t\tthis.#preventRepeat = options.preventRepeat ?? false\n\t\tthis.#pitchVariation = options.pitchVariation\n\t\tthis.#volumeVariation = options.volumeVariation\n\n\t\tif (options.variants) {\n\t\t\tfor (const variant of options.variants) {\n\t\t\t\tthis.#variants.push(variant)\n\t\t\t\tthis.#totalWeight += variant.weight\n\t\t\t}\n\t\t}\n\t}\n\n\t// =========================================================================\n\t// Accessors\n\t// =========================================================================\n\n\tgetState(): SoundVariantPoolState {\n\t\treturn {\n\t\t\tvariantCount: this.#variants.length,\n\t\t\tlastPlayedKey: this.#lastPlayedKey,\n\t\t\tcooldownRemaining: this.#cooldownRemaining,\n\t\t}\n\t}\n\n\tgetVariants(): readonly SoundVariant[] {\n\t\treturn this.#variants\n\t}\n\n\tgetVariantCount(): number {\n\t\treturn this.#variants.length\n\t}\n\n\tgetLastPlayedKey(): string | undefined {\n\t\treturn this.#lastPlayedKey\n\t}\n\n\tcanPlay(): boolean {\n\t\treturn this.#variants.length > 0 && this.#cooldownRemaining <= 0\n\t}\n\n\t// =========================================================================\n\t// Mutators\n\t// =========================================================================\n\n\taddVariant(variant: SoundVariant): void {\n\t\tthis.#variants.push(variant)\n\t\tthis.#totalWeight += variant.weight\n\t}\n\n\tremoveVariant(key: string): void {\n\t\tconst index = this.#variants.findIndex(v => v.key === key)\n\t\tif (index >= 0) {\n\t\t\tconst variant = this.#variants[index]\n\t\t\tif (variant) {\n\t\t\t\tthis.#totalWeight -= variant.weight\n\t\t\t}\n\t\t\tthis.#variants.splice(index, 1)\n\t\t}\n\t}\n\n\tclearVariants(): void {\n\t\tthis.#variants = []\n\t\tthis.#totalWeight = 0\n\t\tthis.#lastPlayedKey = undefined\n\t}\n\n\t// =========================================================================\n\t// Playback\n\t// =========================================================================\n\n\tplay(audioManager: AudioManagerInterface, volume?: number): string | undefined {\n\t\tif (this.#cooldownRemaining > 0) return undefined\n\t\tif (this.#variants.length === 0) return undefined\n\n\t\tconst variant = this.getRandomVariant()\n\t\tif (!variant) return undefined\n\n\t\t// Calculate pitch if specified\n\t\tlet playbackRate = 1\n\t\tif (variant.minPitch !== undefined && variant.maxPitch !== undefined) {\n\t\t\tplaybackRate = variant.minPitch + Math.random() * (variant.maxPitch - variant.minPitch)\n\t\t} else if (this.#pitchVariation) {\n\t\t\tplaybackRate = this.#pitchVariation.min + Math.random() * (this.#pitchVariation.max - this.#pitchVariation.min)\n\t\t}\n\n\t\t// Calculate volume variation\n\t\tlet finalVolume = volume ?? 1\n\t\tif (this.#volumeVariation) {\n\t\t\tfinalVolume *= this.#volumeVariation.min + Math.random() * (this.#volumeVariation.max - this.#volumeVariation.min)\n\t\t}\n\n\t\taudioManager.playOneShot(variant.key, finalVolume)\n\t\tif (playbackRate !== 1) {\n\t\t\taudioManager.setPlaybackRate(variant.key, playbackRate)\n\t\t}\n\n\t\tthis.#lastPlayedKey = variant.key\n\t\tthis.#cooldownRemaining = this.#cooldown\n\n\t\treturn variant.key\n\t}\n\n\tplayAt(audioManager: AudioManagerInterface, key: string, volume?: number): void {\n\t\taudioManager.playOneShot(key, volume)\n\t}\n\n\tsetPitchVariation(min: number, max: number): void {\n\t\tthis.#pitchVariation = { min, max }\n\t}\n\n\tsetVolumeVariation(min: number, max: number): void {\n\t\tthis.#volumeVariation = { min, max }\n\t}\n\n\tsetCooldown(cooldown: number): void {\n\t\tthis.#cooldown = Math.max(0, cooldown)\n\t}\n\n\tgetRandomVariant(): SoundVariant | undefined {\n\t\tif (this.#variants.length === 0) return undefined\n\t\tif (this.#variants.length === 1) return this.#variants[0]\n\n\t\t// Calculate available weight (excluding last played if preventRepeat)\n\t\tlet availableWeight = this.#totalWeight\n\t\tif (this.#preventRepeat && this.#lastPlayedKey) {\n\t\t\tconst lastVariant = this.#variants.find(v => v.key === this.#lastPlayedKey)\n\t\t\tif (lastVariant) {\n\t\t\t\tavailableWeight -= lastVariant.weight\n\t\t\t}\n\t\t}\n\n\t\tif (availableWeight <= 0) {\n\t\t\t// All variants filtered out, just pick first\n\t\t\treturn this.#variants[0]\n\t\t}\n\n\t\t// Weighted random selection\n\t\tlet random = Math.random() * availableWeight\n\t\tfor (const variant of this.#variants) {\n\t\t\tif (this.#preventRepeat && variant.key === this.#lastPlayedKey) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\trandom -= variant.weight\n\t\t\tif (random <= 0) {\n\t\t\t\treturn variant\n\t\t\t}\n\t\t}\n\n\t\t// Fallback\n\t\treturn this.#variants[0]\n\t}\n\n\t// =========================================================================\n\t// Lifecycle\n\t// =========================================================================\n\n\tupdate(deltaTime: number): void {\n\t\tif (this.#cooldownRemaining > 0) {\n\t\t\tthis.#cooldownRemaining = Math.max(0, this.#cooldownRemaining - deltaTime)\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.#variants = []\n\t\tthis.#totalWeight = 0\n\t\tthis.#lastPlayedKey = undefined\n\t\tthis.#cooldownRemaining = 0\n\t}\n}\n","import type {\n\tAudioZoneManagerInterface,\n\tAudioZoneManagerOptions,\n\tAudioZoneInterface,\n\tAudioZoneManagerState,\n\tAudioManagerInterface,\n\tRectangle,\n\tUnsubscribe,\n} from '../../types.js'\nimport { DEFAULT_TRANSITION_DURATION } from '~/src'\n\n/**\n * Audio zone manager for spatial audio effects.\n * Applies different audio effects based on player position.\n *\n * @example\n * ```ts\n * const zones = createAudioZoneManager({\n * zones: [\n * {\n * id: 'cave',\n * name: 'Cave',\n * bounds: { x: 100, y: 100, width: 200, height: 200 },\n * effect: { type: 'reverb', intensity: 0.7 },\n * enabled: true,\n * },\n * ],\n * })\n *\n * zones.update(player.x, player.y, deltaTime)\n * ```\n */\nexport class AudioZoneManager implements AudioZoneManagerInterface {\n\t#zones: Map<string, AudioZoneInterface> = new Map()\n\t#currentZone: AudioZoneInterface | undefined\n\t#previousZone: AudioZoneInterface | undefined\n\t#isTransitioning = false\n\t#transitionProgress = 0\n\t#transitionDuration: number\n\t#audioManager: AudioManagerInterface | undefined\n\n\t#listeners = {\n\t\tzoneEnter: new Set<(zone: AudioZoneInterface) => void>(),\n\t\tzoneExit: new Set<(zone: AudioZoneInterface) => void>(),\n\t\ttransitionStart: new Set<(from: AudioZoneInterface | undefined, to: AudioZoneInterface) => void>(),\n\t\ttransitionEnd: new Set<(zone: AudioZoneInterface) => void>(),\n\t}\n\n\tconstructor(options?: AudioZoneManagerOptions) {\n\t\tthis.#transitionDuration = options?.defaultTransitionDuration ?? DEFAULT_TRANSITION_DURATION\n\t\tthis.#audioManager = options?.audioManager\n\n\t\t// Add initial zones\n\t\tif (options?.zones) {\n\t\t\tfor (const zone of options.zones) {\n\t\t\t\tthis.#zones.set(zone.id, zone)\n\t\t\t}\n\t\t}\n\n\t\t// Register hooks from options\n\t\tif (options?.onZoneEnter) this.#listeners.zoneEnter.add(options.onZoneEnter)\n\t\tif (options?.onZoneExit) this.#listeners.zoneExit.add(options.onZoneExit)\n\t\tif (options?.onTransitionStart) this.#listeners.transitionStart.add(options.onTransitionStart)\n\t\tif (options?.onTransitionEnd) this.#listeners.transitionEnd.add(options.onTransitionEnd)\n\t}\n\n\t// =========================================================================\n\t// Accessors (AudioZoneManagerInterface interface)\n\t// =========================================================================\n\n\tgetState(): AudioZoneManagerState {\n\t\treturn {\n\t\t\tcurrentZone: this.#currentZone,\n\t\t\tpreviousZone: this.#previousZone,\n\t\t\tisTransitioning: this.#isTransitioning,\n\t\t\ttransitionProgress: this.#transitionProgress,\n\t\t}\n\t}\n\n\tgetCurrentZone(): AudioZoneInterface | undefined {\n\t\treturn this.#currentZone\n\t}\n\n\tgetZones(): readonly AudioZoneInterface[] {\n\t\treturn Array.from(this.#zones.values())\n\t}\n\n\tgetZone(id: string): AudioZoneInterface | undefined {\n\t\treturn this.#zones.get(id)\n\t}\n\n\t// =========================================================================\n\t// Mutators\n\t// =========================================================================\n\n\taddZone(zone: AudioZoneInterface): void {\n\t\tthis.#zones.set(zone.id, zone)\n\t}\n\n\tremoveZone(id: string): void {\n\t\tconst zone = this.#zones.get(id)\n\t\tif (zone) {\n\t\t\tif (this.#currentZone?.id === id) {\n\t\t\t\tthis.#exitZone(zone)\n\t\t\t}\n\t\t\tthis.#zones.delete(id)\n\t\t}\n\t}\n\n\tsetZoneEnabled(id: string, enabled: boolean): void {\n\t\tconst zone = this.#zones.get(id)\n\t\tif (zone) {\n\t\t\tconst updated: AudioZoneInterface = { ...zone, enabled }\n\t\t\tthis.#zones.set(id, updated)\n\n\t\t\t// If disabling current zone, exit it\n\t\t\tif (!enabled && this.#currentZone?.id === id) {\n\t\t\t\tthis.#exitZone(zone)\n\t\t\t}\n\t\t}\n\t}\n\n\tupdateZoneBounds(id: string, bounds: Rectangle): void {\n\t\tconst zone = this.#zones.get(id)\n\t\tif (zone) {\n\t\t\tconst updated: AudioZoneInterface = { ...zone, bounds }\n\t\t\tthis.#zones.set(id, updated)\n\t\t}\n\t}\n\n\tcheckPosition(x: number, y: number): AudioZoneInterface | undefined {\n\t\tfor (const zone of this.#zones.values()) {\n\t\t\tif (!zone.enabled) continue\n\t\t\tif (this.#isInsideBounds(x, y, zone.bounds)) {\n\t\t\t\treturn zone\n\t\t\t}\n\t\t}\n\t\treturn undefined\n\t}\n\n\tforceTransition(zoneId: string): void {\n\t\tconst zone = this.#zones.get(zoneId)\n\t\tif (zone && zone.enabled) {\n\t\t\tthis.#startTransition(zone)\n\t\t}\n\t}\n\n\tcancelTransition(): void {\n\t\tif (this.#isTransitioning) {\n\t\t\tthis.#isTransitioning = false\n\t\t\tthis.#transitionProgress = 0\n\t\t}\n\t}\n\n\t// =========================================================================\n\t// Event Subscriptions\n\t// =========================================================================\n\n\tonZoneEnter(callback: (zone: AudioZoneInterface) => void): Unsubscribe {\n\t\tthis.#listeners.zoneEnter.add(callback)\n\t\treturn () => this.#listeners.zoneEnter.delete(callback)\n\t}\n\n\tonZoneExit(callback: (zone: AudioZoneInterface) => void): Unsubscribe {\n\t\tthis.#listeners.zoneExit.add(callback)\n\t\treturn () => this.#listeners.zoneExit.delete(callback)\n\t}\n\n\tonTransitionStart(callback: (from: AudioZoneInterface | undefined, to: AudioZoneInterface) => void): Unsubscribe {\n\t\tthis.#listeners.transitionStart.add(callback)\n\t\treturn () => this.#listeners.transitionStart.delete(callback)\n\t}\n\n\tonTransitionEnd(callback: (zone: AudioZoneInterface) => void): Unsubscribe {\n\t\tthis.#listeners.transitionEnd.add(callback)\n\t\treturn () => this.#listeners.transitionEnd.delete(callback)\n\t}\n\n\t// =========================================================================\n\t// Lifecycle\n\t// =========================================================================\n\n\tupdate(listenerX: number, listenerY: number, deltaTime: number): void {\n\t\t// Update transition progress\n\t\tif (this.#isTransitioning) {\n\t\t\tthis.#transitionProgress += deltaTime / this.#transitionDuration\n\t\t\tif (this.#transitionProgress >= 1) {\n\t\t\t\tthis.#transitionProgress = 1\n\t\t\t\tthis.#isTransitioning = false\n\t\t\t\tif (this.#currentZone) {\n\t\t\t\t\tfor (const callback of this.#listeners.transitionEnd) {\n\t\t\t\t\t\tcallback(this.#currentZone)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Find zone containing listener\n\t\tconst foundZone = this.checkPosition(listenerX, listenerY)\n\n\t\t// Handle zone transitions\n\t\tif (foundZone !== this.#currentZone) {\n\t\t\tif (foundZone) {\n\t\t\t\tthis.#startTransition(foundZone)\n\t\t\t} else if (this.#currentZone) {\n\t\t\t\tthis.#exitZone(this.#currentZone)\n\t\t\t}\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.#zones.clear()\n\t\tthis.#currentZone = undefined\n\t\tthis.#previousZone = undefined\n\t\tthis.#isTransitioning = false\n\t\tthis.#listeners.zoneEnter.clear()\n\t\tthis.#listeners.zoneExit.clear()\n\t\tthis.#listeners.transitionStart.clear()\n\t\tthis.#listeners.transitionEnd.clear()\n\t}\n\n\t// =========================================================================\n\t// Private Methods\n\t// =========================================================================\n\n\t#isInsideBounds(x: number, y: number, bounds: Rectangle): boolean {\n\t\treturn x >= bounds.x && x <= bounds.x + bounds.width &&\n\t\t\ty >= bounds.y && y <= bounds.y + bounds.height\n\t}\n\n\t#startTransition(toZone: AudioZoneInterface): void {\n\t\tthis.#previousZone = this.#currentZone\n\t\tthis.#currentZone = toZone\n\t\tthis.#isTransitioning = true\n\t\tthis.#transitionProgress = 0\n\n\t\t// Start transition\n\t\tfor (const callback of this.#listeners.transitionStart) {\n\t\t\tcallback(this.#previousZone, toZone)\n\t\t}\n\n\t\t// Emit zone events\n\t\tif (this.#previousZone) {\n\t\t\tfor (const callback of this.#listeners.zoneExit) {\n\t\t\t\tcallback(this.#previousZone)\n\t\t\t}\n\t\t}\n\t\tfor (const callback of this.#listeners.zoneEnter) {\n\t\t\tcallback(toZone)\n\t\t}\n\t}\n\n\t#exitZone(zone: AudioZoneInterface): void {\n\t\tthis.#previousZone = zone\n\t\tthis.#currentZone = undefined\n\n\t\tfor (const callback of this.#listeners.zoneExit) {\n\t\t\tcallback(zone)\n\t\t}\n\t}\n}\n","import type {\r\n\tPhysicsWorldInterface,\r\n\tPhysicsWorldOptions,\r\n\tEntityInterface,\r\n\tPhysicsBodyOptions,\r\n\tPhysicsBodyState,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Physics world for simulating physics.\r\n */\r\nexport class PhysicsWorld implements PhysicsWorldInterface {\r\n\t#gravityX: number\r\n\t#gravityY: number\r\n\t#damping: number\r\n\t#iterations: number\r\n\t#bodies: Map<EntityInterface, {\r\n\t\tmass: number\r\n\t\tvelocityX: number\r\n\t\tvelocityY: number\r\n\t\taccelerationX: number\r\n\t\taccelerationY: number\r\n\t\tfriction: number\r\n\t\trestitution: number\r\n\t\tgravityScale: number\r\n\t\tisStatic: boolean\r\n\t}> = new Map()\r\n\r\n\tconstructor(options?: PhysicsWorldOptions) {\r\n\t\tthis.#gravityX = options?.gravityX ?? 0\r\n\t\tthis.#gravityY = options?.gravityY ?? 980\r\n\t\tthis.#damping = options?.damping ?? 0.99\r\n\t\tthis.#iterations = options?.iterations ?? 4\r\n\t}\r\n\r\n\tgetOptions(): PhysicsWorldOptions {\r\n\t\treturn {\r\n\t\t\tgravityX: this.#gravityX,\r\n\t\t\tgravityY: this.#gravityY,\r\n\t\t\tdamping: this.#damping,\r\n\t\t\titerations: this.#iterations,\r\n\t\t}\r\n\t}\r\n\r\n\tgetGravityX(): number {\r\n\t\treturn this.#gravityX\r\n\t}\r\n\r\n\tgetGravityY(): number {\r\n\t\treturn this.#gravityY\r\n\t}\r\n\r\n\tsetGravityX(x: number): void {\r\n\t\tthis.#gravityX = x\r\n\t}\r\n\r\n\tsetGravityY(y: number): void {\r\n\t\tthis.#gravityY = y\r\n\t}\r\n\r\n\tsetGravity(x: number, y: number): void {\r\n\t\tthis.#gravityX = x\r\n\t\tthis.#gravityY = y\r\n\t}\r\n\r\n\taddBody(entity: EntityInterface, options: PhysicsBodyOptions): void {\r\n\t\tconst state = {\r\n\t\t\tmass: options.mass ?? 1,\r\n\t\t\tvelocityX: options.velocityX ?? 0,\r\n\t\t\tvelocityY: options.velocityY ?? 0,\r\n\t\t\taccelerationX: options.accelerationX ?? 0,\r\n\t\t\taccelerationY: options.accelerationY ?? 0,\r\n\t\t\tfriction: options.friction ?? 0.1,\r\n\t\t\trestitution: options.restitution ?? 0.2,\r\n\t\t\tgravityScale: options.gravityScale ?? 1,\r\n\t\t\tisStatic: options.isStatic ?? false,\r\n\t\t}\r\n\t\tthis.#bodies.set(entity, state)\r\n\t}\r\n\r\n\tremoveBody(entity: EntityInterface): void {\r\n\t\tthis.#bodies.delete(entity)\r\n\t}\r\n\r\n\tgetBodyState(entity: EntityInterface): PhysicsBodyState | undefined {\r\n\t\treturn this.#bodies.get(entity)\r\n\t}\r\n\r\n\thasBody(entity: EntityInterface): boolean {\r\n\t\treturn this.#bodies.has(entity)\r\n\t}\r\n\r\n\tapplyForce(entity: EntityInterface, x: number, y: number): void {\r\n\t\tconst body = this.#bodies.get(entity)\r\n\t\tif (!body || body.isStatic) return\r\n\t\t// F = ma, so a = F / m\r\n\t\tbody.accelerationX += x / body.mass\r\n\t\tbody.accelerationY += y / body.mass\r\n\t}\r\n\r\n\tapplyImpulse(entity: EntityInterface, x: number, y: number): void {\r\n\t\tconst body = this.#bodies.get(entity)\r\n\t\tif (!body || body.isStatic) return\r\n\t\t// Impulse directly changes velocity\r\n\t\tbody.velocityX += x / body.mass\r\n\t\tbody.velocityY += y / body.mass\r\n\t}\r\n\r\n\tsetVelocity(entity: EntityInterface, x: number, y: number): void {\r\n\t\tconst body = this.#bodies.get(entity)\r\n\t\tif (!body || body.isStatic) return\r\n\t\tbody.velocityX = x\r\n\t\tbody.velocityY = y\r\n\t}\r\n\r\n\tstep(deltaTime: number): void {\r\n\t\tconst dt = deltaTime / 1000 // Convert to seconds\r\n\r\n\t\tfor (const [entity, body] of this.#bodies) {\r\n\t\t\tif (body.isStatic) continue\r\n\r\n\t\t\t// Apply gravity\r\n\t\t\tbody.accelerationY += this.#gravityY * body.gravityScale\r\n\r\n\t\t\t// Integrate velocity (v = v + a*dt)\r\n\t\t\tbody.velocityX += body.accelerationX * dt\r\n\t\t\tbody.velocityY += body.accelerationY * dt\r\n\r\n\t\t\t// Apply damping\r\n\t\t\tbody.velocityX *= this.#damping\r\n\t\t\tbody.velocityY *= this.#damping\r\n\r\n\t\t\t// Integrate position (p = p + v*dt)\r\n\t\t\tconst newX = entity.getX() + body.velocityX * dt\r\n\t\t\tconst newY = entity.getY() + body.velocityY * dt\r\n\r\n\t\t\tentity.setX(newX)\r\n\t\t\tentity.setY(newY)\r\n\r\n\t\t\t// Reset acceleration for next frame\r\n\t\t\tbody.accelerationX = 0\r\n\t\t\tbody.accelerationY = 0\r\n\t\t}\r\n\t}\r\n\r\n\tclear(): void {\r\n\t\tthis.#bodies.clear()\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tCollisionSystemInterface,\r\n\tEntityInterface,\r\n\tCollider,\r\n\tCollisionResult,\r\n\tEntityBounds,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Collision system for detecting collisions between entities.\r\n */\r\nexport class CollisionSystem implements CollisionSystemInterface {\r\n\t#entityColliders: Map<EntityInterface, Collider> = new Map()\r\n\t#layerCollisions: Map<string, boolean> = new Map()\r\n\r\n\taddEntity(entity: EntityInterface, collider: Collider): void {\r\n\t\tthis.#entityColliders.set(entity, collider)\r\n\t}\r\n\r\n\tremoveEntity(entity: EntityInterface): void {\r\n\t\tthis.#entityColliders.delete(entity)\r\n\t}\r\n\r\n\tupdateEntity(entity: EntityInterface, collider: Collider): void {\r\n\t\tthis.#entityColliders.set(entity, collider)\r\n\t}\r\n\r\n\thasEntity(entity: EntityInterface): boolean {\r\n\t\treturn this.#entityColliders.has(entity)\r\n\t}\r\n\r\n\tcheckCollision(entityA: EntityInterface, entityB: EntityInterface): CollisionResult | undefined {\r\n\t\tconst colliderA = this.#entityColliders.get(entityA)\r\n\t\tconst colliderB = this.#entityColliders.get(entityB)\r\n\t\tif (!colliderA || !colliderB) return undefined\r\n\r\n\t\tconst boundsA = entityA.getBounds()\r\n\t\tconst boundsB = entityB.getBounds()\r\n\r\n\t\t// AABB collision detection\r\n\t\tif (boundsA.left >= boundsB.right ||\r\n\t\t\tboundsA.right <= boundsB.left ||\r\n\t\t\tboundsA.top >= boundsB.bottom ||\r\n\t\t\tboundsA.bottom <= boundsB.top) {\r\n\t\t\treturn undefined\r\n\t\t}\r\n\r\n\t\t// Calculate overlap\r\n\t\tconst overlapX = Math.min(boundsA.right - boundsB.left, boundsB.right - boundsA.left)\r\n\t\tconst overlapY = Math.min(boundsA.bottom - boundsB.top, boundsB.bottom - boundsA.top)\r\n\r\n\t\t// Determine collision normal (smallest penetration axis)\r\n\t\tlet normalX = 0\r\n\t\tlet normalY = 0\r\n\t\tlet depth: number\r\n\r\n\t\tif (overlapX < overlapY) {\r\n\t\t\tdepth = overlapX\r\n\t\t\tnormalX = boundsA.left < boundsB.left ? -1 : 1\r\n\t\t} else {\r\n\t\t\tdepth = overlapY\r\n\t\t\tnormalY = boundsA.top < boundsB.top ? -1 : 1\r\n\t\t}\r\n\r\n\t\t// Calculate contact point at the overlap region center\r\n\t\tconst contactX = Math.max(boundsA.left, boundsB.left) +\r\n\t\t\t(Math.min(boundsA.right, boundsB.right) - Math.max(boundsA.left, boundsB.left)) / 2\r\n\t\tconst contactY = Math.max(boundsA.top, boundsB.top) +\r\n\t\t\t(Math.min(boundsA.bottom, boundsB.bottom) - Math.max(boundsA.top, boundsB.top)) / 2\r\n\r\n\t\treturn {\r\n\t\t\thasCollision: true,\r\n\t\t\tentityA,\r\n\t\t\tentityB,\r\n\t\t\tnormalX,\r\n\t\t\tnormalY,\r\n\t\t\tdepth,\r\n\t\t\tcontactX,\r\n\t\t\tcontactY,\r\n\t\t}\r\n\t}\r\n\r\n\tcheckPoint(x: number, y: number): readonly EntityInterface[] {\r\n\t\tconst results: EntityInterface[] = []\r\n\t\tfor (const entity of this.#entityColliders.keys()) {\r\n\t\t\tconst bounds = entity.getBounds()\r\n\t\t\tif (x >= bounds.left && x <= bounds.right && y >= bounds.top && y <= bounds.bottom) {\r\n\t\t\t\tresults.push(entity)\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn results\r\n\t}\r\n\r\n\tcheckArea(bounds: EntityBounds): readonly EntityInterface[] {\r\n\t\tconst results: EntityInterface[] = []\r\n\t\tfor (const entity of this.#entityColliders.keys()) {\r\n\t\t\tconst entityBounds = entity.getBounds()\r\n\t\t\tif (entityBounds.left < bounds.right &&\r\n\t\t\t\tentityBounds.right > bounds.left &&\r\n\t\t\t\tentityBounds.top < bounds.bottom &&\r\n\t\t\t\tentityBounds.bottom > bounds.top) {\r\n\t\t\t\tresults.push(entity)\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn results\r\n\t}\r\n\r\n\tcheckRay(startX: number, startY: number, endX: number, endY: number): readonly EntityInterface[] {\r\n\t\tconst results: EntityInterface[] = []\r\n\t\tconst dx = endX - startX\r\n\t\tconst dy = endY - startY\r\n\t\tconst length = Math.sqrt(dx * dx + dy * dy)\r\n\t\tconst dirX = dx / length\r\n\t\tconst dirY = dy / length\r\n\r\n\t\tfor (const entity of this.#entityColliders.keys()) {\r\n\t\t\tconst bounds = entity.getBounds()\r\n\r\n\t\t\t// Simple ray-AABB intersection\r\n\t\t\tconst tMinX = (bounds.left - startX) / (dirX || 0.00001)\r\n\t\t\tconst tMaxX = (bounds.right - startX) / (dirX || 0.00001)\r\n\t\t\tconst tMinY = (bounds.top - startY) / (dirY || 0.00001)\r\n\t\t\tconst tMaxY = (bounds.bottom - startY) / (dirY || 0.00001)\r\n\r\n\t\t\tconst tEnterX = Math.min(tMinX, tMaxX)\r\n\t\t\tconst tExitX = Math.max(tMinX, tMaxX)\r\n\t\t\tconst tEnterY = Math.min(tMinY, tMaxY)\r\n\t\t\tconst tExitY = Math.max(tMinY, tMaxY)\r\n\r\n\t\t\tconst tEnter = Math.max(tEnterX, tEnterY)\r\n\t\t\tconst tExit = Math.min(tExitX, tExitY)\r\n\r\n\t\t\tif (tEnter <= tExit && tEnter >= 0 && tEnter <= length) {\r\n\t\t\t\tresults.push(entity)\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn results\r\n\t}\r\n\r\n\tsetLayerCollision(layerA: number, layerB: number, canCollide: boolean): void {\r\n\t\tconst key = `${Math.min(layerA, layerB)}-${Math.max(layerA, layerB)}`\r\n\t\tthis.#layerCollisions.set(key, canCollide)\r\n\t}\r\n\r\n\tgetLayerCollision(layerA: number, layerB: number): boolean {\r\n\t\tconst key = `${Math.min(layerA, layerB)}-${Math.max(layerA, layerB)}`\r\n\t\treturn this.#layerCollisions.get(key) ?? true\r\n\t}\r\n\r\n\tupdate(): void {\r\n\t\t// Perform collision detection for all entity pairs using brute force\r\n\t\t// For optimization with many entities, use SpatialGrid or Quadtree\r\n\t\tconst entities = Array.from(this.#entityColliders.keys())\r\n\t\tconst count = entities.length\r\n\r\n\t\tfor (let i = 0; i < count; i++) {\r\n\t\t\tfor (let j = i + 1; j < count; j++) {\r\n\t\t\t\tconst entityA = entities[i]\r\n\t\t\t\tconst entityB = entities[j]\r\n\t\t\t\tif (!entityA || !entityB) continue\r\n\r\n\t\t\t\t// Check for collision - collision callbacks should be handled by the game logic\r\n\t\t\t\tthis.checkCollision(entityA, entityB)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tclear(): void {\r\n\t\tthis.#entityColliders.clear()\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.clear()\r\n\t\tthis.#layerCollisions.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tTweenInterface,\r\n\tTweenOptions,\r\n\tTweenState,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Tween for animating numeric properties.\r\n */\r\nexport class Tween implements TweenInterface {\r\n\treadonly id: string\r\n\t#target: Record<string, number>\r\n\t#properties: Partial<Record<string, number>>\r\n\t#duration: number\r\n\t#isPlaying = false\r\n\t#isPaused = false\r\n\t#elapsedTime = 0\r\n\t#progress = 0\r\n\r\n\t#listeners = {\r\n\t\tstart: new Set<() => void>(),\r\n\t\tupdate: new Set<(progress: number) => void>(),\r\n\t\tcomplete: new Set<() => void>(),\r\n\t\tstop: new Set<() => void>(),\r\n\t}\r\n\r\n\tconstructor(options: TweenOptions<Record<string, number>>) {\r\n\t\tthis.id = crypto.randomUUID()\r\n\t\tthis.#target = options.target\r\n\t\tthis.#properties = options.properties\r\n\t\tthis.#duration = options.duration\r\n\r\n\t\t// Register hooks from options\r\n\t\tif (options.onStart) this.#listeners.start.add(options.onStart)\r\n\t\tif (options.onUpdate) this.#listeners.update.add(options.onUpdate)\r\n\t\tif (options.onComplete) this.#listeners.complete.add(options.onComplete)\r\n\t\tif (options.onStop) this.#listeners.stop.add(options.onStop)\r\n\t}\r\n\r\n\tgetState(): TweenState {\r\n\t\treturn {\r\n\t\t\tisPlaying: this.#isPlaying,\r\n\t\t\tisPaused: this.#isPaused,\r\n\t\t\telapsedTime: this.#elapsedTime,\r\n\t\t\tduration: this.#duration,\r\n\t\t\tprogress: this.#progress,\r\n\t\t}\r\n\t}\r\n\r\n\tisPlaying(): boolean {\r\n\t\treturn this.#isPlaying\r\n\t}\r\n\r\n\tisPaused(): boolean {\r\n\t\treturn this.#isPaused\r\n\t}\r\n\r\n\tgetProgress(): number {\r\n\t\treturn this.#progress\r\n\t}\r\n\r\n\tgetElapsedTime(): number {\r\n\t\treturn this.#elapsedTime\r\n\t}\r\n\r\n\tplay(): void {\r\n\t\tthis.#isPlaying = true\r\n\t\tthis.#isPaused = false\r\n\t\tthis.#listeners.start.forEach(cb => cb())\r\n\t}\r\n\r\n\tpause(): void {\r\n\t\tthis.#isPaused = true\r\n\t}\r\n\r\n\tresume(): void {\r\n\t\tthis.#isPaused = false\r\n\t}\r\n\r\n\tstop(): void {\r\n\t\tthis.#isPlaying = false\r\n\t\tthis.#isPaused = false\r\n\t\tthis.#listeners.stop.forEach(cb => cb())\r\n\t}\r\n\r\n\treset(): void {\r\n\t\tthis.#elapsedTime = 0\r\n\t\tthis.#progress = 0\r\n\t}\r\n\r\n\trestart(): void {\r\n\t\tthis.reset()\r\n\t\tthis.play()\r\n\t}\r\n\r\n\tseek(progress: number): void {\r\n\t\tthis.#progress = Math.max(0, Math.min(1, progress))\r\n\t\tthis.#elapsedTime = this.#progress * this.#duration\r\n\t\tthis.#applyProgress()\r\n\t}\r\n\r\n\tupdate(deltaTime: number): void {\r\n\t\tif (!this.#isPlaying || this.#isPaused) return\r\n\r\n\t\tthis.#elapsedTime += deltaTime\r\n\t\tthis.#progress = Math.min(1, this.#elapsedTime / this.#duration)\r\n\r\n\t\tthis.#applyProgress()\r\n\t\tthis.#listeners.update.forEach(cb => cb(this.#progress))\r\n\r\n\t\tif (this.#progress >= 1) {\r\n\t\t\tthis.#isPlaying = false\r\n\t\t\tthis.#listeners.complete.forEach(cb => cb())\r\n\t\t}\r\n\t}\r\n\r\n\t#applyProgress(): void {\r\n\t\t// Apply eased progress to target properties\r\n\t\tconst easedProgress = this.#easeInOutQuad(this.#progress)\r\n\r\n\t\tfor (const prop in this.#properties) {\r\n\t\t\tconst endValue = this.#properties[prop]\r\n\t\t\tif (endValue === undefined) continue\r\n\r\n\t\t\t// Calculate start value (stored as __tween_start_[prop])\r\n\t\t\tconst startKey = `__tween_start_${prop}`\r\n\t\t\tif (!(startKey in this.#target)) {\r\n\t\t\t\t(this.#target as Record<string, number>)[startKey] = this.#target[prop] ?? 0\r\n\t\t\t}\r\n\t\t\tconst startValue = (this.#target as Record<string, number>)[startKey] ?? 0\r\n\r\n\t\t\t// Interpolate\r\n\t\t\tthis.#target[prop] = startValue + (endValue - startValue) * easedProgress\r\n\t\t}\r\n\t}\r\n\r\n\t#easeInOutQuad(t: number): number {\r\n\t\treturn t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2\r\n\t}\r\n\r\n\tonStart(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.start.add(callback)\r\n\t\treturn () => this.#listeners.start.delete(callback)\r\n\t}\r\n\r\n\tonUpdate(callback: (progress: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.update.add(callback)\r\n\t\treturn () => this.#listeners.update.delete(callback)\r\n\t}\r\n\r\n\tonComplete(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.complete.add(callback)\r\n\t\treturn () => this.#listeners.complete.delete(callback)\r\n\t}\r\n\r\n\tonStop(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.stop.add(callback)\r\n\t\treturn () => this.#listeners.stop.delete(callback)\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#listeners.start.clear()\r\n\t\tthis.#listeners.update.clear()\r\n\t\tthis.#listeners.complete.clear()\r\n\t\tthis.#listeners.stop.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tTweenManagerInterface,\r\n\tTweenManagerOptions,\r\n\tTweenOptions,\r\n\tEasingType,\r\n} from '../../types.js'\r\nimport { Tween } from './Tween.js'\r\n\r\n/**\r\n * Tween manager for managing animation tweens.\r\n */\r\nexport class TweenManager implements TweenManagerInterface {\r\n\t#tweens: Map<string, Tween> = new Map()\r\n\t#autoUpdate: boolean\r\n\t#defaultEasing: EasingType\r\n\r\n\tconstructor(options?: TweenManagerOptions) {\r\n\t\tthis.#autoUpdate = options?.autoUpdate ?? true\r\n\t\tthis.#defaultEasing = options?.defaultEasing ?? 'linear'\r\n\t}\r\n\r\n\tcreate<T extends Record<string, number>>(options: TweenOptions<T>): Tween {\r\n\t\tconst tween = new Tween(options)\r\n\t\tthis.#tweens.set(tween.id, tween)\r\n\t\treturn tween\r\n\t}\r\n\r\n\tget(id: string): Tween | undefined {\r\n\t\treturn this.#tweens.get(id)\r\n\t}\r\n\r\n\tgetAll(): readonly Tween[] {\r\n\t\treturn Array.from(this.#tweens.values())\r\n\t}\r\n\r\n\tpauseAll(): void {\r\n\t\tfor (const tween of this.#tweens.values()) {\r\n\t\t\ttween.pause()\r\n\t\t}\r\n\t}\r\n\r\n\tresumeAll(): void {\r\n\t\tfor (const tween of this.#tweens.values()) {\r\n\t\t\ttween.resume()\r\n\t\t}\r\n\t}\r\n\r\n\tstopAll(): void {\r\n\t\tfor (const tween of this.#tweens.values()) {\r\n\t\t\ttween.stop()\r\n\t\t}\r\n\t}\r\n\r\n\tclearAll(): void {\r\n\t\tfor (const tween of this.#tweens.values()) {\r\n\t\t\ttween.destroy()\r\n\t\t}\r\n\t\tthis.#tweens.clear()\r\n\t}\r\n\r\n\tupdate(deltaTime: number): void {\r\n\t\tconst toRemove: string[] = []\r\n\r\n\t\tfor (const [id, tween] of this.#tweens) {\r\n\t\t\tif (tween.isPlaying()) {\r\n\t\t\t\ttween.update(deltaTime)\r\n\r\n\t\t\t\t// Check if completed (not playing anymore after update)\r\n\t\t\t\tif (!tween.isPlaying() && tween.getProgress() >= 1) {\r\n\t\t\t\t\ttoRemove.push(id)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Remove completed tweens\r\n\t\tfor (const id of toRemove) {\r\n\t\t\tconst tween = this.#tweens.get(id)\r\n\t\t\tif (tween) {\r\n\t\t\t\ttween.destroy()\r\n\t\t\t\tthis.#tweens.delete(id)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.clearAll()\r\n\t}\r\n}\r\n","import type {\r\n\tMutableParticle,\r\n\tParticleEmitterInterface,\r\n\tParticleEmitterOptions,\r\n\tParticleState,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Particle emitter for creating particle effects.\r\n */\r\nexport class ParticleEmitter implements ParticleEmitterInterface {\r\n\treadonly id: string\r\n\t#x: number\r\n\t#y: number\r\n\t#maxParticles: number\r\n\t#emissionRate: number\r\n\t#lifespan: number\r\n\t#isEmitting = false\r\n\t#particles: MutableParticle[] = []\r\n\r\n\t#listeners = {\r\n\t\temit: new Set<(particle: ParticleState) => void>(),\r\n\t\tparticleDeath: new Set<(particle: ParticleState) => void>(),\r\n\t\tcomplete: new Set<() => void>(),\r\n\t}\r\n\r\n\tconstructor(options: ParticleEmitterOptions) {\r\n\t\tthis.id = crypto.randomUUID()\r\n\t\tthis.#x = options.x\r\n\t\tthis.#y = options.y\r\n\t\tthis.#maxParticles = options.maxParticles\r\n\t\tthis.#emissionRate = options.emissionRate\r\n\t\tthis.#lifespan = options.lifespan\r\n\r\n\t\t// Register hooks from options\r\n\t\tif (options.onEmit) this.#listeners.emit.add(options.onEmit)\r\n\t\tif (options.onParticleDeath) this.#listeners.particleDeath.add(options.onParticleDeath)\r\n\t\tif (options.onComplete) this.#listeners.complete.add(options.onComplete)\r\n\t}\r\n\r\n\tgetX(): number {\r\n\t\treturn this.#x\r\n\t}\r\n\r\n\tgetY(): number {\r\n\t\treturn this.#y\r\n\t}\r\n\r\n\tgetParticleCount(): number {\r\n\t\treturn this.#particles.length\r\n\t}\r\n\r\n\tisEmitting(): boolean {\r\n\t\treturn this.#isEmitting\r\n\t}\r\n\r\n\tsetPosition(x: number, y: number): void {\r\n\t\tthis.#x = x\r\n\t\tthis.#y = y\r\n\t}\r\n\r\n\tsetEmitting(emitting: boolean): void {\r\n\t\tthis.#isEmitting = emitting\r\n\t}\r\n\r\n\tstart(): void {\r\n\t\tthis.#isEmitting = true\r\n\t}\r\n\r\n\tstop(): void {\r\n\t\tthis.#isEmitting = false\r\n\t}\r\n\r\n\tpause(): void {\r\n\t\tthis.#isEmitting = false\r\n\t}\r\n\r\n\tresume(): void {\r\n\t\tthis.#isEmitting = true\r\n\t}\r\n\r\n\treset(): void {\r\n\t\tthis.#particles.length = 0\r\n\t}\r\n\r\n\t#toParticleState(p: MutableParticle): ParticleState {\r\n\t\treturn {\r\n\t\t\tx: p.x,\r\n\t\t\ty: p.y,\r\n\t\t\tvelocityX: p.velocityX,\r\n\t\t\tvelocityY: p.velocityY,\r\n\t\t\tscale: p.scale,\r\n\t\t\topacity: p.opacity,\r\n\t\t\trotation: p.rotation,\r\n\t\t\tage: p.age,\r\n\t\t\tlifespan: p.lifespan,\r\n\t\t\tisAlive: p.isAlive,\r\n\t\t}\r\n\t}\r\n\r\n\temit(count = 1): void {\r\n\t\tfor (let i = 0; i < count && this.#particles.length < this.#maxParticles; i++) {\r\n\t\t\tconst particle: MutableParticle = {\r\n\t\t\t\tx: this.#x,\r\n\t\t\t\ty: this.#y,\r\n\t\t\t\tvelocityX: (Math.random() - 0.5) * 100,\r\n\t\t\t\tvelocityY: (Math.random() - 0.5) * 100 - 50,\r\n\t\t\t\tage: 0,\r\n\t\t\t\tlifespan: this.#lifespan,\r\n\t\t\t\tscale: 1,\r\n\t\t\t\trotation: 0,\r\n\t\t\t\topacity: 1,\r\n\t\t\t\tisAlive: true,\r\n\t\t\t}\r\n\t\t\tthis.#particles.push(particle)\r\n\t\t\tthis.#listeners.emit.forEach(cb => cb(this.#toParticleState(particle)))\r\n\t\t}\r\n\t}\r\n\r\n\t#emitAccumulator = 0\r\n\r\n\tupdate(deltaTime: number): void {\r\n\t\t// Emit new particles based on emission rate\r\n\t\tif (this.#isEmitting) {\r\n\t\t\tthis.#emitAccumulator += deltaTime * this.#emissionRate\r\n\t\t\twhile (this.#emitAccumulator >= 1) {\r\n\t\t\t\tthis.emit(1)\r\n\t\t\t\tthis.#emitAccumulator--\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Update all particles\r\n\t\tfor (let i = this.#particles.length - 1; i >= 0; i--) {\r\n\t\t\tconst p = this.#particles[i]\r\n\t\t\tif (!p) continue\r\n\r\n\t\t\tp.age += deltaTime * 1000\r\n\t\t\tp.x += p.velocityX * deltaTime\r\n\t\t\tp.y += p.velocityY * deltaTime\r\n\t\t\tp.opacity = Math.max(0, 1 - (p.age / p.lifespan))\r\n\r\n\t\t\t// Remove dead particles\r\n\t\t\tif (p.age >= p.lifespan) {\r\n\t\t\t\tp.isAlive = false\r\n\t\t\t\tthis.#listeners.particleDeath.forEach(cb => cb(this.#toParticleState(p)))\r\n\t\t\t\tthis.#particles.splice(i, 1)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Check if complete (not emitting and no particles)\r\n\t\tif (!this.#isEmitting && this.#particles.length === 0) {\r\n\t\t\tthis.#listeners.complete.forEach(cb => cb())\r\n\t\t}\r\n\t}\r\n\r\n\trender(context: CanvasRenderingContext2D): void {\r\n\t\tfor (const p of this.#particles) {\r\n\t\t\tcontext.save()\r\n\t\t\tcontext.globalAlpha = p.opacity\r\n\t\t\tcontext.translate(p.x, p.y)\r\n\t\t\tcontext.rotate(p.rotation)\r\n\t\t\tcontext.scale(p.scale, p.scale)\r\n\r\n\t\t\t// Draw simple circle particle\r\n\t\t\tcontext.beginPath()\r\n\t\t\tcontext.arc(0, 0, 3, 0, Math.PI * 2)\r\n\t\t\tcontext.fillStyle = '#ffffff'\r\n\t\t\tcontext.fill()\r\n\r\n\t\t\tcontext.restore()\r\n\t\t}\r\n\t}\r\n\r\n\tonEmit(callback: (particle: ParticleState) => void): Unsubscribe {\r\n\t\tthis.#listeners.emit.add(callback)\r\n\t\treturn () => this.#listeners.emit.delete(callback)\r\n\t}\r\n\r\n\tonParticleDeath(callback: (particle: ParticleState) => void): Unsubscribe {\r\n\t\tthis.#listeners.particleDeath.add(callback)\r\n\t\treturn () => this.#listeners.particleDeath.delete(callback)\r\n\t}\r\n\r\n\tonComplete(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.complete.add(callback)\r\n\t\treturn () => this.#listeners.complete.delete(callback)\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#particles.length = 0\r\n\t\tthis.#listeners.emit.clear()\r\n\t\tthis.#listeners.particleDeath.clear()\r\n\t\tthis.#listeners.complete.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tParticleSystemInterface,\r\n\tParticleSystemOptions,\r\n\tParticleEmitterOptions,\r\n} from '../../types.js'\r\nimport { ParticleEmitter } from './ParticleEmitter.js'\r\n\r\n/**\r\n * Particle system for managing multiple particle emitters.\r\n */\r\nexport class ParticleSystem implements ParticleSystemInterface {\r\n\t#emitters: Map<string, ParticleEmitter> = new Map()\r\n\t#maxEmitters: number\r\n\t#autoUpdate: boolean\r\n\r\n\tconstructor(options?: ParticleSystemOptions) {\r\n\t\tthis.#maxEmitters = options?.maxEmitters ?? 100\r\n\t\tthis.#autoUpdate = options?.autoUpdate ?? true\r\n\t}\r\n\r\n\tcreateEmitter(options: ParticleEmitterOptions): ParticleEmitter {\r\n\t\tconst emitter = new ParticleEmitter(options)\r\n\t\tthis.#emitters.set(emitter.id, emitter)\r\n\t\treturn emitter\r\n\t}\r\n\r\n\taddEmitter(emitter: ParticleEmitter): void {\r\n\t\tif (this.#emitters.size >= this.#maxEmitters) {\r\n\t\t\tthrow new Error(`Maximum emitters reached: ${this.#maxEmitters}`)\r\n\t\t}\r\n\t\tthis.#emitters.set(emitter.id, emitter)\r\n\t}\r\n\r\n\tremoveEmitter(id: string): void {\r\n\t\tconst emitter = this.#emitters.get(id)\r\n\t\tif (emitter) {\r\n\t\t\temitter.destroy()\r\n\t\t\tthis.#emitters.delete(id)\r\n\t\t}\r\n\t}\r\n\r\n\tgetEmitter(id: string): ParticleEmitter | undefined {\r\n\t\treturn this.#emitters.get(id)\r\n\t}\r\n\r\n\tgetAllEmitters(): readonly ParticleEmitter[] {\r\n\t\treturn Array.from(this.#emitters.values())\r\n\t}\r\n\r\n\tstartAll(): void {\r\n\t\tfor (const emitter of this.#emitters.values()) {\r\n\t\t\temitter.start()\r\n\t\t}\r\n\t}\r\n\r\n\tstopAll(): void {\r\n\t\tfor (const emitter of this.#emitters.values()) {\r\n\t\t\temitter.stop()\r\n\t\t}\r\n\t}\r\n\r\n\tpauseAll(): void {\r\n\t\tfor (const emitter of this.#emitters.values()) {\r\n\t\t\temitter.pause()\r\n\t\t}\r\n\t}\r\n\r\n\tresumeAll(): void {\r\n\t\tfor (const emitter of this.#emitters.values()) {\r\n\t\t\temitter.resume()\r\n\t\t}\r\n\t}\r\n\r\n\tclearAll(): void {\r\n\t\tfor (const emitter of this.#emitters.values()) {\r\n\t\t\temitter.destroy()\r\n\t\t}\r\n\t\tthis.#emitters.clear()\r\n\t}\r\n\r\n\tupdate(deltaTime: number): void {\r\n\t\tif (!this.#autoUpdate) return\r\n\r\n\t\tfor (const emitter of this.#emitters.values()) {\r\n\t\t\temitter.update(deltaTime)\r\n\t\t}\r\n\t}\r\n\r\n\trender(context: CanvasRenderingContext2D): void {\r\n\t\tfor (const emitter of this.#emitters.values()) {\r\n\t\t\temitter.render(context)\r\n\t\t}\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.clearAll()\r\n\t}\r\n}\r\n","import type {\r\n\tButtonInterface,\r\n\tButtonOptions,\r\n\tButtonState,\r\n\tInputState,\r\n\tUIBounds,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Interactive button UI element.\r\n */\r\nexport class Button implements ButtonInterface {\r\n\treadonly id: string\r\n\t#x: number\r\n\t#y: number\r\n\t#width: number\r\n\t#height: number\r\n\t#visible: boolean\r\n\t#interactive: boolean\r\n\t#zIndex: number\r\n\t#opacity: number\r\n\t#text: string\r\n\t#isHovered = false\r\n\t#isPressed = false\r\n\t#isDisabled = false\r\n\r\n\t// Style properties\r\n\t#fontSize: number\r\n\t#fontFamily: string\r\n\t#textColor: string\r\n\t#disabledTextColor: string\r\n\t#backgroundColor: string\r\n\t#hoverColor: string\r\n\t#pressedColor: string\r\n\t#disabledColor: string\r\n\t#borderWidth: number\r\n\t#borderColor: string\r\n\t#borderRadius: number\r\n\r\n\t#listeners = {\r\n\t\tclick: new Set<() => void>(),\r\n\t\thoverStart: new Set<() => void>(),\r\n\t\thoverEnd: new Set<() => void>(),\r\n\t\tpressStart: new Set<() => void>(),\r\n\t\tpressEnd: new Set<() => void>(),\r\n\t}\r\n\r\n\tconstructor(options: ButtonOptions) {\r\n\t\tthis.id = crypto.randomUUID()\r\n\t\tthis.#x = options.x\r\n\t\tthis.#y = options.y\r\n\t\tthis.#width = options.width\r\n\t\tthis.#height = options.height\r\n\t\tthis.#visible = options.visible ?? true\r\n\t\tthis.#interactive = options.interactive ?? true\r\n\t\tthis.#zIndex = options.zIndex ?? 0\r\n\t\tthis.#opacity = options.opacity ?? 1\r\n\t\tthis.#text = options.text ?? ''\r\n\r\n\t\t// Initialize style properties with defaults\r\n\t\tthis.#fontSize = options.fontSize ?? 16\r\n\t\tthis.#fontFamily = options.fontFamily ?? 'sans-serif'\r\n\t\tthis.#textColor = options.textColor ?? '#ffffff'\r\n\t\tthis.#disabledTextColor = options.disabledTextColor ?? '#cccccc'\r\n\t\tthis.#backgroundColor = options.backgroundColor ?? '#4a90a4'\r\n\t\tthis.#hoverColor = options.hoverColor ?? '#5aa8c0'\r\n\t\tthis.#pressedColor = options.pressedColor ?? '#2d5a6e'\r\n\t\tthis.#disabledColor = options.disabledColor ?? '#888888'\r\n\t\tthis.#borderWidth = options.borderWidth ?? 0\r\n\t\tthis.#borderColor = options.borderColor ?? '#000000'\r\n\t\tthis.#borderRadius = options.borderRadius ?? 0\r\n\r\n\t\t// Register hooks from options\r\n\t\tif (options.onClick) this.#listeners.click.add(options.onClick)\r\n\t\tif (options.onHoverStart) this.#listeners.hoverStart.add(options.onHoverStart)\r\n\t\tif (options.onHoverEnd) this.#listeners.hoverEnd.add(options.onHoverEnd)\r\n\t\tif (options.onPressStart) this.#listeners.pressStart.add(options.onPressStart)\r\n\t\tif (options.onPressEnd) this.#listeners.pressEnd.add(options.onPressEnd)\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Visibility\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tisVisible(): boolean {\r\n\t\treturn this.#visible\r\n\t}\r\n\r\n\tsetVisible(visible: boolean): void {\r\n\t\tthis.#visible = visible\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Position accessors\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetX(): number {\r\n\t\treturn this.#x\r\n\t}\r\n\r\n\tgetY(): number {\r\n\t\treturn this.#y\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Position mutators\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetX(x: number): void {\r\n\t\tthis.#x = x\r\n\t}\r\n\r\n\tsetY(y: number): void {\r\n\t\tthis.#y = y\r\n\t}\r\n\r\n\tsetPosition(x: number, y: number): void {\r\n\t\tthis.#x = x\r\n\t\tthis.#y = y\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Size accessors\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetWidth(): number {\r\n\t\treturn this.#width\r\n\t}\r\n\r\n\tgetHeight(): number {\r\n\t\treturn this.#height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Size mutators\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetWidth(width: number): void {\r\n\t\tthis.#width = width\r\n\t}\r\n\r\n\tsetHeight(height: number): void {\r\n\t\tthis.#height = height\r\n\t}\r\n\r\n\tsetSize(width: number, height: number): void {\r\n\t\tthis.#width = width\r\n\t\tthis.#height = height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Bounds and hit testing\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetBounds(): UIBounds {\r\n\t\treturn {\r\n\t\t\tx: this.#x,\r\n\t\t\ty: this.#y,\r\n\t\t\twidth: this.#width,\r\n\t\t\theight: this.#height,\r\n\t\t}\r\n\t}\r\n\r\n\tcontains(x: number, y: number): boolean {\r\n\t\treturn x >= this.#x && x <= this.#x + this.#width &&\r\n\t\t\ty >= this.#y && y <= this.#y + this.#height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Z-Index\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetZIndex(): number {\r\n\t\treturn this.#zIndex\r\n\t}\r\n\r\n\tsetZIndex(zIndex: number): void {\r\n\t\tthis.#zIndex = zIndex\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Opacity\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetOpacity(): number {\r\n\t\treturn this.#opacity\r\n\t}\r\n\r\n\tsetOpacity(opacity: number): void {\r\n\t\tthis.#opacity = Math.max(0, Math.min(1, opacity))\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// InteractiveUIElement: Interactivity\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tisInteractive(): boolean {\r\n\t\treturn this.#interactive\r\n\t}\r\n\r\n\tsetInteractive(interactive: boolean): void {\r\n\t\tthis.#interactive = interactive\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Button: State accessors\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetState(): ButtonState {\r\n\t\treturn {\r\n\t\t\tisHovered: this.#isHovered,\r\n\t\t\tisPressed: this.#isPressed,\r\n\t\t\tisDisabled: this.#isDisabled,\r\n\t\t}\r\n\t}\r\n\r\n\tisHovered(): boolean {\r\n\t\treturn this.#isHovered\r\n\t}\r\n\r\n\tisPressed(): boolean {\r\n\t\treturn this.#isPressed\r\n\t}\r\n\r\n\tisDisabled(): boolean {\r\n\t\treturn this.#isDisabled\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Button: Content\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetText(): string {\r\n\t\treturn this.#text\r\n\t}\r\n\r\n\tsetText(text: string): void {\r\n\t\tthis.#text = text\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Button: Behavior\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetDisabled(disabled: boolean): void {\r\n\t\tthis.#isDisabled = disabled\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Button: Dynamic styling\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetTextColor(color: string): void {\r\n\t\tthis.#textColor = color\r\n\t}\r\n\r\n\tsetBackgroundColor(color: string): void {\r\n\t\tthis.#backgroundColor = color\r\n\t}\r\n\r\n\tsetHoverColor(color: string): void {\r\n\t\tthis.#hoverColor = color\r\n\t}\r\n\r\n\tsetPressedColor(color: string): void {\r\n\t\tthis.#pressedColor = color\r\n\t}\r\n\r\n\tsetDisabledColor(color: string): void {\r\n\t\tthis.#disabledColor = color\r\n\t}\r\n\r\n\tsetBorderColor(color: string): void {\r\n\t\tthis.#borderColor = color\r\n\t}\r\n\r\n\tsetBorderWidth(width: number): void {\r\n\t\tthis.#borderWidth = width\r\n\t}\r\n\r\n\tsetBorderRadius(radius: number): void {\r\n\t\tthis.#borderRadius = radius\r\n\t}\r\n\r\n\tsetFontSize(size: number): void {\r\n\t\tthis.#fontSize = size\r\n\t}\r\n\r\n\tsetFontFamily(family: string): void {\r\n\t\tthis.#fontFamily = family\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// InteractiveUIElement: Update\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tupdate(inputState: InputState): void {\r\n\t\tif (!this.#interactive || !this.#visible || this.#isDisabled) return\r\n\r\n\t\tconst wasHovered = this.#isHovered\r\n\t\tconst wasPressed = this.#isPressed\r\n\r\n\t\t// Check if pointer is over button\r\n\t\tthis.#isHovered = this.contains(inputState.pointerX, inputState.pointerY)\r\n\r\n\t\t// Check press state\r\n\t\tthis.#isPressed = this.#isHovered && inputState.isPointerDown\r\n\r\n\t\t// Handle hover transitions\r\n\t\tif (this.#isHovered && !wasHovered) {\r\n\t\t\tthis.#listeners.hoverStart.forEach(cb => cb())\r\n\t\t} else if (!this.#isHovered && wasHovered) {\r\n\t\t\tthis.#listeners.hoverEnd.forEach(cb => cb())\r\n\t\t}\r\n\r\n\t\t// Handle press transitions\r\n\t\tif (this.#isPressed && !wasPressed) {\r\n\t\t\tthis.#listeners.pressStart.forEach(cb => cb())\r\n\t\t} else if (!this.#isPressed && wasPressed) {\r\n\t\t\tthis.#listeners.pressEnd.forEach(cb => cb())\r\n\t\t\tif (this.#isHovered) {\r\n\t\t\t\tthis.#listeners.click.forEach(cb => cb())\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Rendering\r\n\t// -------------------------------------------------------------------------\r\n\r\n\trender(context: CanvasRenderingContext2D): void {\r\n\t\tif (!this.#visible) return\r\n\r\n\t\tconst previousAlpha = context.globalAlpha\r\n\t\tcontext.globalAlpha = previousAlpha * this.#opacity\r\n\r\n\t\t// Determine colors based on state\r\n\t\tlet bgColor = this.#backgroundColor\r\n\t\tlet textColor = this.#textColor\r\n\r\n\t\tif (this.#isDisabled) {\r\n\t\t\tbgColor = this.#disabledColor\r\n\t\t\ttextColor = this.#disabledTextColor\r\n\t\t} else if (this.#isPressed) {\r\n\t\t\tbgColor = this.#pressedColor\r\n\t\t} else if (this.#isHovered) {\r\n\t\t\tbgColor = this.#hoverColor\r\n\t\t}\r\n\r\n\t\t// Draw button background with optional border radius\r\n\t\tcontext.fillStyle = bgColor\r\n\t\tif (this.#borderRadius > 0) {\r\n\t\t\tthis.#roundRect(context, this.#x, this.#y, this.#width, this.#height, this.#borderRadius)\r\n\t\t\tcontext.fill()\r\n\t\t} else {\r\n\t\t\tcontext.fillRect(this.#x, this.#y, this.#width, this.#height)\r\n\t\t}\r\n\r\n\t\t// Draw border if width > 0\r\n\t\tif (this.#borderWidth > 0) {\r\n\t\t\tcontext.strokeStyle = this.#borderColor\r\n\t\t\tcontext.lineWidth = this.#borderWidth\r\n\t\t\tif (this.#borderRadius > 0) {\r\n\t\t\t\tthis.#roundRect(context, this.#x, this.#y, this.#width, this.#height, this.#borderRadius)\r\n\t\t\t\tcontext.stroke()\r\n\t\t\t} else {\r\n\t\t\t\tcontext.strokeRect(this.#x, this.#y, this.#width, this.#height)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Draw text\r\n\t\tcontext.fillStyle = textColor\r\n\t\tcontext.font = `${this.#fontSize}px ${this.#fontFamily}`\r\n\t\tcontext.textAlign = 'center'\r\n\t\tcontext.textBaseline = 'middle'\r\n\t\tcontext.fillText(\r\n\t\t\tthis.#text,\r\n\t\t\tthis.#x + this.#width / 2,\r\n\t\t\tthis.#y + this.#height / 2,\r\n\t\t)\r\n\r\n\t\tcontext.globalAlpha = previousAlpha\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Button: Event subscriptions\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tonClick(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.click.add(callback)\r\n\t\treturn () => this.#listeners.click.delete(callback)\r\n\t}\r\n\r\n\tonHoverStart(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.hoverStart.add(callback)\r\n\t\treturn () => this.#listeners.hoverStart.delete(callback)\r\n\t}\r\n\r\n\tonHoverEnd(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.hoverEnd.add(callback)\r\n\t\treturn () => this.#listeners.hoverEnd.delete(callback)\r\n\t}\r\n\r\n\tonPressStart(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.pressStart.add(callback)\r\n\t\treturn () => this.#listeners.pressStart.delete(callback)\r\n\t}\r\n\r\n\tonPressEnd(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.pressEnd.add(callback)\r\n\t\treturn () => this.#listeners.pressEnd.delete(callback)\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Lifecycle\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#listeners.click.clear()\r\n\t\tthis.#listeners.hoverStart.clear()\r\n\t\tthis.#listeners.hoverEnd.clear()\r\n\t\tthis.#listeners.pressStart.clear()\r\n\t\tthis.#listeners.pressEnd.clear()\r\n\t}\r\n\r\n\t#roundRect(ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, r: number): void {\r\n\t\tctx.beginPath()\r\n\t\tctx.moveTo(x + r, y)\r\n\t\tctx.lineTo(x + w - r, y)\r\n\t\tctx.quadraticCurveTo(x + w, y, x + w, y + r)\r\n\t\tctx.lineTo(x + w, y + h - r)\r\n\t\tctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h)\r\n\t\tctx.lineTo(x + r, y + h)\r\n\t\tctx.quadraticCurveTo(x, y + h, x, y + h - r)\r\n\t\tctx.lineTo(x, y + r)\r\n\t\tctx.quadraticCurveTo(x, y, x + r, y)\r\n\t\tctx.closePath()\r\n\t}\r\n}\r\n","import type { TextInterface, TextAlign, TextBaseline, TextOptions, UIBounds } from '../../types.js'\r\n\r\n/**\r\n * Text label UI element.\r\n */\r\nexport class Text implements TextInterface {\r\n\treadonly id: string\r\n\t#x: number\r\n\t#y: number\r\n\t#width: number\r\n\t#height: number\r\n\t#visible: boolean\r\n\t#zIndex: number\r\n\t#opacity: number\r\n\t#text: string\r\n\t#fontSize: number\r\n\t#fontFamily: string\r\n\t#color: string\r\n\t#align: TextAlign\r\n\t#baseline: TextBaseline\r\n\t#maxWidth: number | undefined\r\n\t#lineHeight: number\r\n\r\n\tconstructor(options: TextOptions) {\r\n\t\tthis.id = crypto.randomUUID()\r\n\t\tthis.#x = options.x\r\n\t\tthis.#y = options.y\r\n\t\tthis.#width = options.width\r\n\t\tthis.#height = options.height\r\n\t\tthis.#visible = options.visible ?? true\r\n\t\tthis.#zIndex = options.zIndex ?? 0\r\n\t\tthis.#opacity = options.opacity ?? 1\r\n\t\tthis.#text = options.text\r\n\t\tthis.#fontSize = options.fontSize ?? 16\r\n\t\tthis.#fontFamily = options.fontFamily ?? 'Arial'\r\n\t\tthis.#color = options.color ?? '#ffffff'\r\n\t\tthis.#align = options.align ?? 'left'\r\n\t\tthis.#baseline = options.baseline ?? 'top'\r\n\t\tthis.#maxWidth = options.maxWidth\r\n\t\tthis.#lineHeight = options.lineHeight ?? 1.2\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Visibility\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tisVisible(): boolean {\r\n\t\treturn this.#visible\r\n\t}\r\n\r\n\tsetVisible(visible: boolean): void {\r\n\t\tthis.#visible = visible\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Position accessors\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetX(): number {\r\n\t\treturn this.#x\r\n\t}\r\n\r\n\tgetY(): number {\r\n\t\treturn this.#y\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Position mutators\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetX(x: number): void {\r\n\t\tthis.#x = x\r\n\t}\r\n\r\n\tsetY(y: number): void {\r\n\t\tthis.#y = y\r\n\t}\r\n\r\n\tsetPosition(x: number, y: number): void {\r\n\t\tthis.#x = x\r\n\t\tthis.#y = y\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Size accessors\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetWidth(): number {\r\n\t\treturn this.#width\r\n\t}\r\n\r\n\tgetHeight(): number {\r\n\t\treturn this.#height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Size mutators\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetWidth(width: number): void {\r\n\t\tthis.#width = width\r\n\t}\r\n\r\n\tsetHeight(height: number): void {\r\n\t\tthis.#height = height\r\n\t}\r\n\r\n\tsetSize(width: number, height: number): void {\r\n\t\tthis.#width = width\r\n\t\tthis.#height = height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Bounds and hit testing\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetBounds(): UIBounds {\r\n\t\treturn {\r\n\t\t\tx: this.#x,\r\n\t\t\ty: this.#y,\r\n\t\t\twidth: this.#width,\r\n\t\t\theight: this.#height,\r\n\t\t}\r\n\t}\r\n\r\n\tcontains(x: number, y: number): boolean {\r\n\t\treturn x >= this.#x && x <= this.#x + this.#width &&\r\n\t\t\ty >= this.#y && y <= this.#y + this.#height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Z-Index\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetZIndex(): number {\r\n\t\treturn this.#zIndex\r\n\t}\r\n\r\n\tsetZIndex(zIndex: number): void {\r\n\t\tthis.#zIndex = zIndex\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Opacity\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetOpacity(): number {\r\n\t\treturn this.#opacity\r\n\t}\r\n\r\n\tsetOpacity(opacity: number): void {\r\n\t\tthis.#opacity = Math.max(0, Math.min(1, opacity))\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Text: Content\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetText(): string {\r\n\t\treturn this.#text\r\n\t}\r\n\r\n\tsetText(text: string): void {\r\n\t\tthis.#text = text\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Text: Dynamic styling\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetColor(color: string): void {\r\n\t\tthis.#color = color\r\n\t}\r\n\r\n\tsetFontSize(size: number): void {\r\n\t\tthis.#fontSize = size\r\n\t}\r\n\r\n\tsetFontFamily(family: string): void {\r\n\t\tthis.#fontFamily = family\r\n\t}\r\n\r\n\tsetAlign(align: TextAlign): void {\r\n\t\tthis.#align = align\r\n\t}\r\n\r\n\tsetBaseline(baseline: TextBaseline): void {\r\n\t\tthis.#baseline = baseline\r\n\t}\r\n\r\n\tsetMaxWidth(maxWidth: number | undefined): void {\r\n\t\tthis.#maxWidth = maxWidth\r\n\t}\r\n\r\n\tsetLineHeight(lineHeight: number): void {\r\n\t\tthis.#lineHeight = lineHeight\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Rendering\r\n\t// -------------------------------------------------------------------------\r\n\r\n\trender(context: CanvasRenderingContext2D): void {\r\n\t\tif (!this.#visible) return\r\n\r\n\t\tconst previousAlpha = context.globalAlpha\r\n\t\tcontext.globalAlpha = previousAlpha * this.#opacity\r\n\r\n\t\tcontext.fillStyle = this.#color\r\n\t\tcontext.font = `${this.#fontSize}px ${this.#fontFamily}`\r\n\t\tcontext.textAlign = this.#align as CanvasTextAlign\r\n\t\tcontext.textBaseline = this.#baseline as CanvasTextBaseline\r\n\r\n\t\tif (this.#maxWidth !== undefined && this.#maxWidth > 0) {\r\n\t\t\tcontext.fillText(this.#text, this.#x, this.#y, this.#maxWidth)\r\n\t\t} else {\r\n\t\t\tcontext.fillText(this.#text, this.#x, this.#y)\r\n\t\t}\r\n\r\n\t\tcontext.globalAlpha = previousAlpha\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Lifecycle\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tdestroy(): void {\r\n\t\t// No resources to clean up\r\n\t}\r\n}\r\n","import type {\r\n\tInputState,\r\n\tInteractiveUIElement,\r\n\tPanelInterface,\r\n\tPanelLayout,\r\n\tPanelOptions,\r\n\tUIBounds,\r\n\tUIElement,\r\n\tUISpacing,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Panel container for grouping UI elements.\r\n */\r\nexport class Panel implements PanelInterface {\r\n\treadonly id: string\r\n\t#x: number\r\n\t#y: number\r\n\t#width: number\r\n\t#height: number\r\n\t#visible: boolean\r\n\t#interactive: boolean\r\n\t#zIndex: number\r\n\t#opacity: number\r\n\t#backgroundColor: string\r\n\t#borderColor: string\r\n\t#borderWidth: number\r\n\t#borderRadius: number\r\n\t#padding: UISpacing\r\n\t#layout: PanelLayout | undefined\r\n\t#children: Map<string, UIElement> = new Map()\r\n\r\n\tconstructor(options: PanelOptions) {\r\n\t\tthis.id = crypto.randomUUID()\r\n\t\tthis.#x = options.x\r\n\t\tthis.#y = options.y\r\n\t\tthis.#width = options.width\r\n\t\tthis.#height = options.height\r\n\t\tthis.#visible = options.visible ?? true\r\n\t\tthis.#interactive = options.interactive ?? true\r\n\t\tthis.#zIndex = options.zIndex ?? 0\r\n\t\tthis.#opacity = options.opacity ?? 1\r\n\t\tthis.#backgroundColor = options.backgroundColor ?? '#2d3748'\r\n\t\tthis.#borderColor = options.borderColor ?? '#4a5568'\r\n\t\tthis.#borderWidth = options.borderWidth ?? 1\r\n\t\tthis.#borderRadius = options.borderRadius ?? 0\r\n\t\tthis.#padding = this.#normalizePadding(options.padding ?? 8)\r\n\t\tthis.#layout = options.layout\r\n\t}\r\n\r\n\t#normalizePadding(padding: number | UISpacing): UISpacing {\r\n\t\tif (typeof padding === 'number') {\r\n\t\t\treturn { top: padding, right: padding, bottom: padding, left: padding }\r\n\t\t}\r\n\t\treturn padding\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Visibility\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tisVisible(): boolean {\r\n\t\treturn this.#visible\r\n\t}\r\n\r\n\tsetVisible(visible: boolean): void {\r\n\t\tthis.#visible = visible\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Position accessors\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetX(): number {\r\n\t\treturn this.#x\r\n\t}\r\n\r\n\tgetY(): number {\r\n\t\treturn this.#y\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Position mutators\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetX(x: number): void {\r\n\t\tthis.#x = x\r\n\t}\r\n\r\n\tsetY(y: number): void {\r\n\t\tthis.#y = y\r\n\t}\r\n\r\n\tsetPosition(x: number, y: number): void {\r\n\t\tthis.#x = x\r\n\t\tthis.#y = y\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Size accessors\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetWidth(): number {\r\n\t\treturn this.#width\r\n\t}\r\n\r\n\tgetHeight(): number {\r\n\t\treturn this.#height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Size mutators\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetWidth(width: number): void {\r\n\t\tthis.#width = width\r\n\t}\r\n\r\n\tsetHeight(height: number): void {\r\n\t\tthis.#height = height\r\n\t}\r\n\r\n\tsetSize(width: number, height: number): void {\r\n\t\tthis.#width = width\r\n\t\tthis.#height = height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Bounds and hit testing\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetBounds(): UIBounds {\r\n\t\treturn {\r\n\t\t\tx: this.#x,\r\n\t\t\ty: this.#y,\r\n\t\t\twidth: this.#width,\r\n\t\t\theight: this.#height,\r\n\t\t}\r\n\t}\r\n\r\n\tcontains(x: number, y: number): boolean {\r\n\t\treturn x >= this.#x && x <= this.#x + this.#width &&\r\n\t\t\ty >= this.#y && y <= this.#y + this.#height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Z-Index\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetZIndex(): number {\r\n\t\treturn this.#zIndex\r\n\t}\r\n\r\n\tsetZIndex(zIndex: number): void {\r\n\t\tthis.#zIndex = zIndex\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Opacity\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetOpacity(): number {\r\n\t\treturn this.#opacity\r\n\t}\r\n\r\n\tsetOpacity(opacity: number): void {\r\n\t\tthis.#opacity = Math.max(0, Math.min(1, opacity))\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// InteractiveUIElement: Interactivity\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tisInteractive(): boolean {\r\n\t\treturn this.#interactive\r\n\t}\r\n\r\n\tsetInteractive(interactive: boolean): void {\r\n\t\tthis.#interactive = interactive\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Panel: Child management\r\n\t// -------------------------------------------------------------------------\r\n\r\n\taddChild(element: UIElement): void {\r\n\t\tthis.#children.set(element.id, element)\r\n\t}\r\n\r\n\tremoveChild(id: string): void {\r\n\t\tconst child = this.#children.get(id)\r\n\t\tif (child) {\r\n\t\t\tchild.destroy()\r\n\t\t\tthis.#children.delete(id)\r\n\t\t}\r\n\t}\r\n\r\n\tgetChild(id: string): UIElement | undefined {\r\n\t\treturn this.#children.get(id)\r\n\t}\r\n\r\n\tgetChildren(): readonly UIElement[] {\r\n\t\treturn Array.from(this.#children.values())\r\n\t}\r\n\r\n\tclearChildren(): void {\r\n\t\tfor (const child of this.#children.values()) {\r\n\t\t\tchild.destroy()\r\n\t\t}\r\n\t\tthis.#children.clear()\r\n\t}\r\n\r\n\thasChild(id: string): boolean {\r\n\t\treturn this.#children.has(id)\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Panel: Layout\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetLayout(): PanelLayout | undefined {\r\n\t\treturn this.#layout\r\n\t}\r\n\r\n\tsetLayout(layout: PanelLayout): void {\r\n\t\tthis.#layout = layout\r\n\t}\r\n\r\n\tsetPadding(padding: number | UISpacing): void {\r\n\t\tthis.#padding = this.#normalizePadding(padding)\r\n\t}\r\n\r\n\tsetGap(gap: number): void {\r\n\t\tthis.#layout = { ...this.#layout, gap }\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Panel: Dynamic styling\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetBackgroundColor(color: string): void {\r\n\t\tthis.#backgroundColor = color\r\n\t}\r\n\r\n\tsetBorderColor(color: string): void {\r\n\t\tthis.#borderColor = color\r\n\t}\r\n\r\n\tsetBorderWidth(width: number): void {\r\n\t\tthis.#borderWidth = width\r\n\t}\r\n\r\n\tsetBorderRadius(radius: number): void {\r\n\t\tthis.#borderRadius = radius\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// InteractiveUIElement: Update\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tupdate(inputState: InputState): void {\r\n\t\tif (!this.#interactive || !this.#visible) return\r\n\r\n\t\t// Update all children with adjusted input state (offset by panel position + padding)\r\n\t\tconst adjustedState: InputState = {\r\n\t\t\t...inputState,\r\n\t\t\tpointerX: inputState.pointerX - this.#x - this.#padding.left,\r\n\t\t\tpointerY: inputState.pointerY - this.#y - this.#padding.top,\r\n\t\t}\r\n\r\n\t\tfor (const child of this.#children.values()) {\r\n\t\t\tif (this.#isInteractive(child)) {\r\n\t\t\t\tchild.update(adjustedState)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t#isInteractive(element: UIElement): element is InteractiveUIElement {\r\n\t\treturn 'update' in element && typeof (element as InteractiveUIElement).update === 'function'\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Rendering\r\n\t// -------------------------------------------------------------------------\r\n\r\n\trender(context: CanvasRenderingContext2D): void {\r\n\t\tif (!this.#visible) return\r\n\r\n\t\tconst previousAlpha = context.globalAlpha\r\n\t\tcontext.globalAlpha = previousAlpha * this.#opacity\r\n\r\n\t\t// Render panel background with optional border radius\r\n\t\tcontext.fillStyle = this.#backgroundColor\r\n\t\tif (this.#borderRadius > 0) {\r\n\t\t\tcontext.beginPath()\r\n\t\t\tcontext.roundRect(this.#x, this.#y, this.#width, this.#height, this.#borderRadius)\r\n\t\t\tcontext.fill()\r\n\t\t} else {\r\n\t\t\tcontext.fillRect(this.#x, this.#y, this.#width, this.#height)\r\n\t\t}\r\n\r\n\t\t// Render border\r\n\t\tif (this.#borderWidth > 0) {\r\n\t\t\tcontext.strokeStyle = this.#borderColor\r\n\t\t\tcontext.lineWidth = this.#borderWidth\r\n\t\t\tif (this.#borderRadius > 0) {\r\n\t\t\t\tcontext.beginPath()\r\n\t\t\t\tcontext.roundRect(this.#x, this.#y, this.#width, this.#height, this.#borderRadius)\r\n\t\t\t\tcontext.stroke()\r\n\t\t\t} else {\r\n\t\t\t\tcontext.strokeRect(this.#x, this.#y, this.#width, this.#height)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Render all children\r\n\t\tcontext.save()\r\n\t\tcontext.translate(this.#x + this.#padding.left, this.#y + this.#padding.top)\r\n\t\tfor (const child of this.#children.values()) {\r\n\t\t\tchild.render(context)\r\n\t\t}\r\n\t\tcontext.restore()\r\n\r\n\t\tcontext.globalAlpha = previousAlpha\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Lifecycle\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tdestroy(): void {\r\n\t\tthis.clearChildren()\r\n\t}\r\n}\r\n","import type {\r\n\tSliderInterface,\r\n\tSliderOptions,\r\n\tInputState,\r\n\tUIBounds,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Slider UI component for numeric value selection.\r\n */\r\nexport class Slider implements SliderInterface {\r\n\treadonly id: string\r\n\t#x: number\r\n\t#y: number\r\n\t#width: number\r\n\t#height: number\r\n\t#visible: boolean\r\n\t#interactive: boolean\r\n\t#zIndex: number\r\n\t#opacity: number\r\n\t#min: number\r\n\t#max: number\r\n\t#value: number\r\n\t#step: number\r\n\t#isDragging = false\r\n\r\n\t// Style properties\r\n\t#trackColor: string\r\n\t#fillColor: string\r\n\t#thumbColor: string\r\n\t#thumbSize: number\r\n\r\n\t#listeners = {\r\n\t\tchange: new Set<(value: number) => void>(),\r\n\t\tdragStart: new Set<() => void>(),\r\n\t\tdragEnd: new Set<() => void>(),\r\n\t}\r\n\r\n\tconstructor(options: SliderOptions) {\r\n\t\tthis.id = crypto.randomUUID()\r\n\t\tthis.#x = options.x\r\n\t\tthis.#y = options.y\r\n\t\tthis.#width = options.width\r\n\t\tthis.#height = options.height\r\n\t\tthis.#visible = options.visible ?? true\r\n\t\tthis.#interactive = options.interactive ?? true\r\n\t\tthis.#zIndex = options.zIndex ?? 0\r\n\t\tthis.#opacity = options.opacity ?? 1\r\n\t\tthis.#min = options.min\r\n\t\tthis.#max = options.max\r\n\t\tthis.#value = options.value\r\n\t\tthis.#step = options.step ?? 1\r\n\r\n\t\t// Initialize style properties with defaults\r\n\t\tthis.#trackColor = options.trackColor ?? '#4a5568'\r\n\t\tthis.#fillColor = options.fillColor ?? '#4a90a4'\r\n\t\tthis.#thumbColor = options.thumbColor ?? '#ffffff'\r\n\t\tthis.#thumbSize = options.thumbSize ?? this.#height / 2\r\n\r\n\t\t// Register hooks from options\r\n\t\tif (options.onChange) this.#listeners.change.add(options.onChange)\r\n\t\tif (options.onDragStart) this.#listeners.dragStart.add(options.onDragStart)\r\n\t\tif (options.onDragEnd) this.#listeners.dragEnd.add(options.onDragEnd)\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Visibility\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tisVisible(): boolean {\r\n\t\treturn this.#visible\r\n\t}\r\n\r\n\tsetVisible(visible: boolean): void {\r\n\t\tthis.#visible = visible\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Position accessors\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetX(): number {\r\n\t\treturn this.#x\r\n\t}\r\n\r\n\tgetY(): number {\r\n\t\treturn this.#y\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Position mutators\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetX(x: number): void {\r\n\t\tthis.#x = x\r\n\t}\r\n\r\n\tsetY(y: number): void {\r\n\t\tthis.#y = y\r\n\t}\r\n\r\n\tsetPosition(x: number, y: number): void {\r\n\t\tthis.#x = x\r\n\t\tthis.#y = y\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Size accessors\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetWidth(): number {\r\n\t\treturn this.#width\r\n\t}\r\n\r\n\tgetHeight(): number {\r\n\t\treturn this.#height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Size mutators\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetWidth(width: number): void {\r\n\t\tthis.#width = width\r\n\t}\r\n\r\n\tsetHeight(height: number): void {\r\n\t\tthis.#height = height\r\n\t}\r\n\r\n\tsetSize(width: number, height: number): void {\r\n\t\tthis.#width = width\r\n\t\tthis.#height = height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Bounds and hit testing\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetBounds(): UIBounds {\r\n\t\treturn {\r\n\t\t\tx: this.#x,\r\n\t\t\ty: this.#y,\r\n\t\t\twidth: this.#width,\r\n\t\t\theight: this.#height,\r\n\t\t}\r\n\t}\r\n\r\n\tcontains(x: number, y: number): boolean {\r\n\t\treturn x >= this.#x && x <= this.#x + this.#width &&\r\n\t\t\ty >= this.#y && y <= this.#y + this.#height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Z-Index\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetZIndex(): number {\r\n\t\treturn this.#zIndex\r\n\t}\r\n\r\n\tsetZIndex(zIndex: number): void {\r\n\t\tthis.#zIndex = zIndex\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Opacity\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetOpacity(): number {\r\n\t\treturn this.#opacity\r\n\t}\r\n\r\n\tsetOpacity(opacity: number): void {\r\n\t\tthis.#opacity = Math.max(0, Math.min(1, opacity))\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// InteractiveUIElement: Interactivity\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tisInteractive(): boolean {\r\n\t\treturn this.#interactive\r\n\t}\r\n\r\n\tsetInteractive(interactive: boolean): void {\r\n\t\tthis.#interactive = interactive\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Slider: Value accessors\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetValue(): number {\r\n\t\treturn this.#value\r\n\t}\r\n\r\n\tgetMin(): number {\r\n\t\treturn this.#min\r\n\t}\r\n\r\n\tgetMax(): number {\r\n\t\treturn this.#max\r\n\t}\r\n\r\n\tgetStep(): number {\r\n\t\treturn this.#step\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Slider: Value mutators\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetValue(value: number): void {\r\n\t\tconst clamped = Math.max(this.#min, Math.min(this.#max, value))\r\n\t\tconst stepped = Math.round(clamped / this.#step) * this.#step\r\n\t\tif (stepped !== this.#value) {\r\n\t\t\tthis.#value = stepped\r\n\t\t\tthis.#listeners.change.forEach(cb => cb(this.#value))\r\n\t\t}\r\n\t}\r\n\r\n\tsetMin(min: number): void {\r\n\t\tthis.#min = min\r\n\t\tif (this.#value < min) this.setValue(min)\r\n\t}\r\n\r\n\tsetMax(max: number): void {\r\n\t\tthis.#max = max\r\n\t\tif (this.#value > max) this.setValue(max)\r\n\t}\r\n\r\n\tsetStep(step: number): void {\r\n\t\tthis.#step = step\r\n\t\t// Re-apply step to current value\r\n\t\tconst stepped = Math.round(this.#value / this.#step) * this.#step\r\n\t\tif (stepped !== this.#value) {\r\n\t\t\tthis.#value = stepped\r\n\t\t\tthis.#listeners.change.forEach(cb => cb(this.#value))\r\n\t\t}\r\n\t}\r\n\r\n\tsetRange(min: number, max: number, step?: number): void {\r\n\t\tthis.#min = min\r\n\t\tthis.#max = max\r\n\t\tif (step !== undefined) {\r\n\t\t\tthis.#step = step\r\n\t\t}\r\n\t\t// Re-clamp and step value\r\n\t\tconst clamped = Math.max(this.#min, Math.min(this.#max, this.#value))\r\n\t\tconst stepped = Math.round(clamped / this.#step) * this.#step\r\n\t\tif (stepped !== this.#value) {\r\n\t\t\tthis.#value = stepped\r\n\t\t\tthis.#listeners.change.forEach(cb => cb(this.#value))\r\n\t\t}\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Slider: State\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tisDragging(): boolean {\r\n\t\treturn this.#isDragging\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Slider: Dynamic styling\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetTrackColor(color: string): void {\r\n\t\tthis.#trackColor = color\r\n\t}\r\n\r\n\tsetFillColor(color: string): void {\r\n\t\tthis.#fillColor = color\r\n\t}\r\n\r\n\tsetThumbColor(color: string): void {\r\n\t\tthis.#thumbColor = color\r\n\t}\r\n\r\n\tsetThumbSize(size: number): void {\r\n\t\tthis.#thumbSize = size\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// InteractiveUIElement: Update\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tupdate(inputState: InputState): void {\r\n\t\tif (!this.#interactive || !this.#visible) return\r\n\r\n\t\tconst wasDragging = this.#isDragging\r\n\t\tconst inBounds = this.contains(inputState.pointerX, inputState.pointerY)\r\n\r\n\t\tif (inputState.isPointerDown) {\r\n\t\t\tif (inBounds || this.#isDragging) {\r\n\t\t\t\tif (!this.#isDragging) {\r\n\t\t\t\t\tthis.#isDragging = true\r\n\t\t\t\t\tthis.#listeners.dragStart.forEach(cb => cb())\r\n\t\t\t\t}\r\n\t\t\t\t// Update value based on pointer position\r\n\t\t\t\tconst relativeX = Math.max(0, Math.min(inputState.pointerX - this.#x, this.#width))\r\n\t\t\t\tconst ratio = relativeX / this.#width\r\n\t\t\t\tconst newValue = this.#min + ratio * (this.#max - this.#min)\r\n\t\t\t\tthis.setValue(newValue)\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tif (wasDragging) {\r\n\t\t\t\tthis.#isDragging = false\r\n\t\t\t\tthis.#listeners.dragEnd.forEach(cb => cb())\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Rendering\r\n\t// -------------------------------------------------------------------------\r\n\r\n\trender(context: CanvasRenderingContext2D): void {\r\n\t\tif (!this.#visible) return\r\n\r\n\t\tconst previousAlpha = context.globalAlpha\r\n\t\tcontext.globalAlpha = previousAlpha * this.#opacity\r\n\r\n\t\t// Calculate progress\r\n\t\tconst range = this.#max - this.#min\r\n\t\tconst progress = range > 0 ? (this.#value - this.#min) / range : 0\r\n\t\tconst trackHeight = 4\r\n\t\tconst thumbRadius = this.#thumbSize\r\n\r\n\t\t// Draw track background\r\n\t\tconst trackY = this.#y + (this.#height - trackHeight) / 2\r\n\t\tcontext.fillStyle = this.#trackColor\r\n\t\tcontext.beginPath()\r\n\t\tcontext.roundRect(this.#x, trackY, this.#width, trackHeight, trackHeight / 2)\r\n\t\tcontext.fill()\r\n\r\n\t\t// Draw filled portion\r\n\t\tconst fillWidth = this.#width * progress\r\n\t\tif (fillWidth > 0) {\r\n\t\t\tcontext.fillStyle = this.#fillColor\r\n\t\t\tcontext.beginPath()\r\n\t\t\tcontext.roundRect(this.#x, trackY, fillWidth, trackHeight, trackHeight / 2)\r\n\t\t\tcontext.fill()\r\n\t\t}\r\n\r\n\t\t// Draw thumb\r\n\t\tconst thumbX = this.#x + fillWidth\r\n\t\tconst thumbY = this.#y + this.#height / 2\r\n\t\tcontext.fillStyle = this.#thumbColor\r\n\t\tcontext.beginPath()\r\n\t\tcontext.arc(thumbX, thumbY, thumbRadius - 2, 0, Math.PI * 2)\r\n\t\tcontext.fill()\r\n\r\n\t\t// Draw thumb border\r\n\t\tcontext.strokeStyle = this.#fillColor\r\n\t\tcontext.lineWidth = 2\r\n\t\tcontext.stroke()\r\n\r\n\t\tcontext.globalAlpha = previousAlpha\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Slider: Event subscriptions\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tonChange(callback: (value: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.change.add(callback)\r\n\t\treturn () => this.#listeners.change.delete(callback)\r\n\t}\r\n\r\n\tonDragStart(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.dragStart.add(callback)\r\n\t\treturn () => this.#listeners.dragStart.delete(callback)\r\n\t}\r\n\r\n\tonDragEnd(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.dragEnd.add(callback)\r\n\t\treturn () => this.#listeners.dragEnd.delete(callback)\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Lifecycle\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#listeners.change.clear()\r\n\t\tthis.#listeners.dragStart.clear()\r\n\t\tthis.#listeners.dragEnd.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tCheckboxInterface,\r\n\tCheckboxOptions,\r\n\tInputState,\r\n\tUIBounds,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Checkbox UI component.\r\n */\r\nexport class Checkbox implements CheckboxInterface {\r\n\treadonly id: string\r\n\t#x: number\r\n\t#y: number\r\n\t#width: number\r\n\t#height: number\r\n\t#visible: boolean\r\n\t#interactive: boolean\r\n\t#zIndex: number\r\n\t#opacity: number\r\n\t#checked: boolean\r\n\t#boxSize: number\r\n\t#label: string\r\n\t#wasPressed = false\r\n\r\n\t// Style properties\r\n\t#labelColor: string\r\n\t#boxColor: string\r\n\t#checkColor: string\r\n\r\n\t#listeners = {\r\n\t\tchange: new Set<(checked: boolean) => void>(),\r\n\t}\r\n\r\n\tconstructor(options: CheckboxOptions) {\r\n\t\tthis.id = crypto.randomUUID()\r\n\t\tthis.#x = options.x\r\n\t\tthis.#y = options.y\r\n\t\tthis.#width = options.width\r\n\t\tthis.#height = options.height\r\n\t\tthis.#visible = options.visible ?? true\r\n\t\tthis.#interactive = options.interactive ?? true\r\n\t\tthis.#zIndex = options.zIndex ?? 0\r\n\t\tthis.#opacity = options.opacity ?? 1\r\n\t\tthis.#checked = options.checked ?? false\r\n\t\tthis.#boxSize = options.boxSize ?? Math.min(options.width, options.height)\r\n\t\tthis.#label = options.label ?? ''\r\n\r\n\t\t// Initialize style properties with defaults\r\n\t\tthis.#labelColor = options.labelColor ?? '#ffffff'\r\n\t\tthis.#boxColor = options.boxColor ?? '#48bb78'\r\n\t\tthis.#checkColor = options.checkColor ?? '#ffffff'\r\n\r\n\t\t// Register hooks from options\r\n\t\tif (options.onChange) this.#listeners.change.add(options.onChange)\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Visibility\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tisVisible(): boolean {\r\n\t\treturn this.#visible\r\n\t}\r\n\r\n\tsetVisible(visible: boolean): void {\r\n\t\tthis.#visible = visible\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Position accessors\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetX(): number {\r\n\t\treturn this.#x\r\n\t}\r\n\r\n\tgetY(): number {\r\n\t\treturn this.#y\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Position mutators\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetX(x: number): void {\r\n\t\tthis.#x = x\r\n\t}\r\n\r\n\tsetY(y: number): void {\r\n\t\tthis.#y = y\r\n\t}\r\n\r\n\tsetPosition(x: number, y: number): void {\r\n\t\tthis.#x = x\r\n\t\tthis.#y = y\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Size accessors\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetWidth(): number {\r\n\t\treturn this.#width\r\n\t}\r\n\r\n\tgetHeight(): number {\r\n\t\treturn this.#height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Size mutators\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetWidth(width: number): void {\r\n\t\tthis.#width = width\r\n\t}\r\n\r\n\tsetHeight(height: number): void {\r\n\t\tthis.#height = height\r\n\t}\r\n\r\n\tsetSize(width: number, height: number): void {\r\n\t\tthis.#width = width\r\n\t\tthis.#height = height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Bounds and hit testing\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetBounds(): UIBounds {\r\n\t\treturn {\r\n\t\t\tx: this.#x,\r\n\t\t\ty: this.#y,\r\n\t\t\twidth: this.#width,\r\n\t\t\theight: this.#height,\r\n\t\t}\r\n\t}\r\n\r\n\tcontains(x: number, y: number): boolean {\r\n\t\treturn x >= this.#x && x <= this.#x + this.#width &&\r\n\t\t\ty >= this.#y && y <= this.#y + this.#height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Z-Index\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetZIndex(): number {\r\n\t\treturn this.#zIndex\r\n\t}\r\n\r\n\tsetZIndex(zIndex: number): void {\r\n\t\tthis.#zIndex = zIndex\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Opacity\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetOpacity(): number {\r\n\t\treturn this.#opacity\r\n\t}\r\n\r\n\tsetOpacity(opacity: number): void {\r\n\t\tthis.#opacity = Math.max(0, Math.min(1, opacity))\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// InteractiveUIElement: Interactivity\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tisInteractive(): boolean {\r\n\t\treturn this.#interactive\r\n\t}\r\n\r\n\tsetInteractive(interactive: boolean): void {\r\n\t\tthis.#interactive = interactive\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Checkbox: State\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tisChecked(): boolean {\r\n\t\treturn this.#checked\r\n\t}\r\n\r\n\tsetChecked(checked: boolean): void {\r\n\t\tif (this.#checked !== checked) {\r\n\t\t\tthis.#checked = checked\r\n\t\t\tthis.#listeners.change.forEach(cb => cb(this.#checked))\r\n\t\t}\r\n\t}\r\n\r\n\ttoggle(): void {\r\n\t\tthis.setChecked(!this.#checked)\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Checkbox: Content\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetLabel(): string {\r\n\t\treturn this.#label\r\n\t}\r\n\r\n\tsetLabel(label: string): void {\r\n\t\tthis.#label = label\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Checkbox: Dynamic styling\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetLabelColor(color: string): void {\r\n\t\tthis.#labelColor = color\r\n\t}\r\n\r\n\tsetBoxColor(color: string): void {\r\n\t\tthis.#boxColor = color\r\n\t}\r\n\r\n\tsetCheckColor(color: string): void {\r\n\t\tthis.#checkColor = color\r\n\t}\r\n\r\n\tsetBoxSize(size: number): void {\r\n\t\tthis.#boxSize = size\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// InteractiveUIElement: Update\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tupdate(inputState: InputState): void {\r\n\t\tif (!this.#interactive || !this.#visible) return\r\n\r\n\t\t// Handle click interaction - toggle when pointer is released over checkbox\r\n\t\tif (inputState.isPointerDown) {\r\n\t\t\tconst inBounds = inputState.pointerX >= this.#x &&\r\n\t\t\t\tinputState.pointerX <= this.#x + this.#boxSize &&\r\n\t\t\t\tinputState.pointerY >= this.#y &&\r\n\t\t\t\tinputState.pointerY <= this.#y + this.#boxSize\r\n\t\t\tif (inBounds) {\r\n\t\t\t\tthis.#wasPressed = true\r\n\t\t\t}\r\n\t\t} else if (this.#wasPressed) {\r\n\t\t\tconst inBounds = inputState.pointerX >= this.#x &&\r\n\t\t\t\tinputState.pointerX <= this.#x + this.#boxSize &&\r\n\t\t\t\tinputState.pointerY >= this.#y &&\r\n\t\t\t\tinputState.pointerY <= this.#y + this.#boxSize\r\n\t\t\tif (inBounds) {\r\n\t\t\t\tthis.toggle()\r\n\t\t\t}\r\n\t\t\tthis.#wasPressed = false\r\n\t\t}\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Rendering\r\n\t// -------------------------------------------------------------------------\r\n\r\n\trender(context: CanvasRenderingContext2D): void {\r\n\t\tif (!this.#visible) return\r\n\r\n\t\tconst previousAlpha = context.globalAlpha\r\n\t\tcontext.globalAlpha = previousAlpha * this.#opacity\r\n\r\n\t\tconst size = this.#boxSize\r\n\r\n\t\t// Draw box with customizable color\r\n\t\tcontext.strokeStyle = this.#checked ? this.#boxColor : '#718096'\r\n\t\tcontext.lineWidth = 2\r\n\t\tcontext.strokeRect(this.#x, this.#y, size, size)\r\n\r\n\t\t// Draw fill if checked\r\n\t\tif (this.#checked) {\r\n\t\t\tcontext.fillStyle = this.#boxColor\r\n\t\t\tcontext.fillRect(this.#x + 2, this.#y + 2, size - 4, size - 4)\r\n\r\n\t\t\t// Draw checkmark\r\n\t\t\tcontext.strokeStyle = this.#checkColor\r\n\t\t\tcontext.lineWidth = 2\r\n\t\t\tcontext.beginPath()\r\n\t\t\tcontext.moveTo(this.#x + size * 0.2, this.#y + size * 0.5)\r\n\t\t\tcontext.lineTo(this.#x + size * 0.4, this.#y + size * 0.7)\r\n\t\t\tcontext.lineTo(this.#x + size * 0.8, this.#y + size * 0.3)\r\n\t\t\tcontext.stroke()\r\n\t\t}\r\n\r\n\t\t// Draw label\r\n\t\tif (this.#label) {\r\n\t\t\tcontext.fillStyle = this.#labelColor\r\n\t\t\tcontext.font = '14px sans-serif'\r\n\t\t\tcontext.textAlign = 'left'\r\n\t\t\tcontext.textBaseline = 'middle'\r\n\t\t\tcontext.fillText(this.#label, this.#x + size + 8, this.#y + size / 2)\r\n\t\t}\r\n\r\n\t\tcontext.globalAlpha = previousAlpha\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Checkbox: Event subscriptions\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tonChange(callback: (checked: boolean) => void): Unsubscribe {\r\n\t\tthis.#listeners.change.add(callback)\r\n\t\treturn () => this.#listeners.change.delete(callback)\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Lifecycle\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#listeners.change.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tToggleInterface,\r\n\tToggleOptions,\r\n\tInputState,\r\n\tUIBounds,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Toggle switch UI component.\r\n */\r\nexport class Toggle implements ToggleInterface {\r\n\treadonly id: string\r\n\t#x: number\r\n\t#y: number\r\n\t#width: number\r\n\t#height: number\r\n\t#visible: boolean\r\n\t#interactive: boolean\r\n\t#zIndex: number\r\n\t#opacity: number\r\n\t#enabled: boolean\r\n\t#wasPressed = false\r\n\r\n\t// Style properties\r\n\t#trackColorOff: string\r\n\t#trackColorOn: string\r\n\t#thumbColor: string\r\n\r\n\t#listeners = {\r\n\t\tchange: new Set<(enabled: boolean) => void>(),\r\n\t}\r\n\r\n\tconstructor(options: ToggleOptions) {\r\n\t\tthis.id = crypto.randomUUID()\r\n\t\tthis.#x = options.x\r\n\t\tthis.#y = options.y\r\n\t\tthis.#width = options.width\r\n\t\tthis.#height = options.height\r\n\t\tthis.#visible = options.visible ?? true\r\n\t\tthis.#interactive = options.interactive ?? true\r\n\t\tthis.#zIndex = options.zIndex ?? 0\r\n\t\tthis.#opacity = options.opacity ?? 1\r\n\t\tthis.#enabled = options.enabled ?? false\r\n\r\n\t\t// Initialize style properties with defaults\r\n\t\tthis.#trackColorOff = options.trackColorOff ?? '#718096'\r\n\t\tthis.#trackColorOn = options.trackColorOn ?? '#48bb78'\r\n\t\tthis.#thumbColor = options.thumbColor ?? '#ffffff'\r\n\r\n\t\t// Register hooks from options\r\n\t\tif (options.onChange) this.#listeners.change.add(options.onChange)\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Visibility\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tisVisible(): boolean {\r\n\t\treturn this.#visible\r\n\t}\r\n\r\n\tsetVisible(visible: boolean): void {\r\n\t\tthis.#visible = visible\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Position accessors\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetX(): number {\r\n\t\treturn this.#x\r\n\t}\r\n\r\n\tgetY(): number {\r\n\t\treturn this.#y\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Position mutators\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetX(x: number): void {\r\n\t\tthis.#x = x\r\n\t}\r\n\r\n\tsetY(y: number): void {\r\n\t\tthis.#y = y\r\n\t}\r\n\r\n\tsetPosition(x: number, y: number): void {\r\n\t\tthis.#x = x\r\n\t\tthis.#y = y\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Size accessors\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetWidth(): number {\r\n\t\treturn this.#width\r\n\t}\r\n\r\n\tgetHeight(): number {\r\n\t\treturn this.#height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Size mutators\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetWidth(width: number): void {\r\n\t\tthis.#width = width\r\n\t}\r\n\r\n\tsetHeight(height: number): void {\r\n\t\tthis.#height = height\r\n\t}\r\n\r\n\tsetSize(width: number, height: number): void {\r\n\t\tthis.#width = width\r\n\t\tthis.#height = height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Bounds and hit testing\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetBounds(): UIBounds {\r\n\t\treturn {\r\n\t\t\tx: this.#x,\r\n\t\t\ty: this.#y,\r\n\t\t\twidth: this.#width,\r\n\t\t\theight: this.#height,\r\n\t\t}\r\n\t}\r\n\r\n\tcontains(x: number, y: number): boolean {\r\n\t\treturn x >= this.#x && x <= this.#x + this.#width &&\r\n\t\t\ty >= this.#y && y <= this.#y + this.#height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Z-Index\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetZIndex(): number {\r\n\t\treturn this.#zIndex\r\n\t}\r\n\r\n\tsetZIndex(zIndex: number): void {\r\n\t\tthis.#zIndex = zIndex\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Opacity\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetOpacity(): number {\r\n\t\treturn this.#opacity\r\n\t}\r\n\r\n\tsetOpacity(opacity: number): void {\r\n\t\tthis.#opacity = Math.max(0, Math.min(1, opacity))\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// InteractiveUIElement: Interactivity\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tisInteractive(): boolean {\r\n\t\treturn this.#interactive\r\n\t}\r\n\r\n\tsetInteractive(interactive: boolean): void {\r\n\t\tthis.#interactive = interactive\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Toggle: State\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tisEnabled(): boolean {\r\n\t\treturn this.#enabled\r\n\t}\r\n\r\n\tsetEnabled(enabled: boolean): void {\r\n\t\tif (this.#enabled !== enabled) {\r\n\t\t\tthis.#enabled = enabled\r\n\t\t\tthis.#listeners.change.forEach(cb => cb(this.#enabled))\r\n\t\t}\r\n\t}\r\n\r\n\ttoggle(): void {\r\n\t\tthis.setEnabled(!this.#enabled)\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Toggle: Dynamic styling\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetTrackColorOff(color: string): void {\r\n\t\tthis.#trackColorOff = color\r\n\t}\r\n\r\n\tsetTrackColorOn(color: string): void {\r\n\t\tthis.#trackColorOn = color\r\n\t}\r\n\r\n\tsetThumbColor(color: string): void {\r\n\t\tthis.#thumbColor = color\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// InteractiveUIElement: Update\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tupdate(inputState: InputState): void {\r\n\t\tif (!this.#interactive || !this.#visible) return\r\n\r\n\t\tif (inputState.isPointerDown) {\r\n\t\t\tif (this.contains(inputState.pointerX, inputState.pointerY)) {\r\n\t\t\t\tthis.#wasPressed = true\r\n\t\t\t}\r\n\t\t} else if (this.#wasPressed) {\r\n\t\t\tif (this.contains(inputState.pointerX, inputState.pointerY)) {\r\n\t\t\t\tthis.toggle()\r\n\t\t\t}\r\n\t\t\tthis.#wasPressed = false\r\n\t\t}\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Rendering\r\n\t// -------------------------------------------------------------------------\r\n\r\n\trender(context: CanvasRenderingContext2D): void {\r\n\t\tif (!this.#visible) return\r\n\r\n\t\tconst previousAlpha = context.globalAlpha\r\n\t\tcontext.globalAlpha = previousAlpha * this.#opacity\r\n\r\n\t\tconst trackWidth = this.#width\r\n\t\tconst trackHeight = this.#height\r\n\t\tconst thumbRadius = trackHeight / 2 - 2\r\n\r\n\t\t// Draw track with customizable colors\r\n\t\tcontext.fillStyle = this.#enabled ? this.#trackColorOn : this.#trackColorOff\r\n\t\tcontext.beginPath()\r\n\t\tcontext.roundRect(this.#x, this.#y, trackWidth, trackHeight, trackHeight / 2)\r\n\t\tcontext.fill()\r\n\r\n\t\t// Draw thumb\r\n\t\tconst thumbX = this.#enabled\r\n\t\t\t? this.#x + trackWidth - thumbRadius - 2\r\n\t\t\t: this.#x + thumbRadius + 2\r\n\t\tconst thumbY = this.#y + trackHeight / 2\r\n\r\n\t\tcontext.fillStyle = this.#thumbColor\r\n\t\tcontext.beginPath()\r\n\t\tcontext.arc(thumbX, thumbY, thumbRadius, 0, Math.PI * 2)\r\n\t\tcontext.fill()\r\n\r\n\t\tcontext.globalAlpha = previousAlpha\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Toggle: Event subscriptions\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tonChange(callback: (enabled: boolean) => void): Unsubscribe {\r\n\t\tthis.#listeners.change.add(callback)\r\n\t\treturn () => this.#listeners.change.delete(callback)\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Lifecycle\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#listeners.change.clear()\r\n\t}\r\n}\r\n","import type { UIBounds, UIImageInterface, UIImageOptions, UIImageSourceRectangle } from '../../types.js'\r\n\r\n/**\r\n * UI Image component for displaying images.\r\n */\r\nexport class UIImage implements UIImageInterface {\r\n\treadonly id: string\r\n\t#x: number\r\n\t#y: number\r\n\t#width: number\r\n\t#height: number\r\n\t#visible: boolean\r\n\t#zIndex: number\r\n\t#opacity: number\r\n\t#imageKey: string\r\n\t#sourceX: number\r\n\t#sourceY: number\r\n\t#sourceWidth: number | undefined\r\n\t#sourceHeight: number | undefined\r\n\t#tint: string | undefined\r\n\r\n\tconstructor(options: UIImageOptions) {\r\n\t\tthis.id = crypto.randomUUID()\r\n\t\tthis.#x = options.x\r\n\t\tthis.#y = options.y\r\n\t\tthis.#width = options.width\r\n\t\tthis.#height = options.height\r\n\t\tthis.#visible = options.visible ?? true\r\n\t\tthis.#zIndex = options.zIndex ?? 0\r\n\t\tthis.#opacity = options.opacity ?? 1\r\n\t\tthis.#imageKey = options.imageKey\r\n\t\tthis.#sourceX = options.sourceX ?? 0\r\n\t\tthis.#sourceY = options.sourceY ?? 0\r\n\t\tthis.#sourceWidth = options.sourceWidth\r\n\t\tthis.#sourceHeight = options.sourceHeight\r\n\t\tthis.#tint = options.tint\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Visibility\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tisVisible(): boolean {\r\n\t\treturn this.#visible\r\n\t}\r\n\r\n\tsetVisible(visible: boolean): void {\r\n\t\tthis.#visible = visible\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Position accessors\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetX(): number {\r\n\t\treturn this.#x\r\n\t}\r\n\r\n\tgetY(): number {\r\n\t\treturn this.#y\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Position mutators\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetX(x: number): void {\r\n\t\tthis.#x = x\r\n\t}\r\n\r\n\tsetY(y: number): void {\r\n\t\tthis.#y = y\r\n\t}\r\n\r\n\tsetPosition(x: number, y: number): void {\r\n\t\tthis.#x = x\r\n\t\tthis.#y = y\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Size accessors\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetWidth(): number {\r\n\t\treturn this.#width\r\n\t}\r\n\r\n\tgetHeight(): number {\r\n\t\treturn this.#height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Size mutators\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetWidth(width: number): void {\r\n\t\tthis.#width = width\r\n\t}\r\n\r\n\tsetHeight(height: number): void {\r\n\t\tthis.#height = height\r\n\t}\r\n\r\n\tsetSize(width: number, height: number): void {\r\n\t\tthis.#width = width\r\n\t\tthis.#height = height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Bounds and hit testing\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetBounds(): UIBounds {\r\n\t\treturn {\r\n\t\t\tx: this.#x,\r\n\t\t\ty: this.#y,\r\n\t\t\twidth: this.#width,\r\n\t\t\theight: this.#height,\r\n\t\t}\r\n\t}\r\n\r\n\tcontains(x: number, y: number): boolean {\r\n\t\treturn x >= this.#x && x <= this.#x + this.#width &&\r\n\t\t\ty >= this.#y && y <= this.#y + this.#height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Z-Index\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetZIndex(): number {\r\n\t\treturn this.#zIndex\r\n\t}\r\n\r\n\tsetZIndex(zIndex: number): void {\r\n\t\tthis.#zIndex = zIndex\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Opacity\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetOpacity(): number {\r\n\t\treturn this.#opacity\r\n\t}\r\n\r\n\tsetOpacity(opacity: number): void {\r\n\t\tthis.#opacity = Math.max(0, Math.min(1, opacity))\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIImage: Image source\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetImageKey(): string {\r\n\t\treturn this.#imageKey\r\n\t}\r\n\r\n\tsetImageKey(key: string): void {\r\n\t\tthis.#imageKey = key\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIImage: Source rectangle\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetSourceRectangle(): UIImageSourceRectangle {\r\n\t\treturn {\r\n\t\t\tx: this.#sourceX,\r\n\t\t\ty: this.#sourceY,\r\n\t\t\twidth: this.#sourceWidth,\r\n\t\t\theight: this.#sourceHeight,\r\n\t\t}\r\n\t}\r\n\r\n\tsetSourceRectangle(x: number, y: number, width?: number, height?: number): void {\r\n\t\tthis.#sourceX = x\r\n\t\tthis.#sourceY = y\r\n\t\tthis.#sourceWidth = width\r\n\t\tthis.#sourceHeight = height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIImage: Styling\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetTint(tint: string | undefined): void {\r\n\t\tthis.#tint = tint\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Rendering\r\n\t// -------------------------------------------------------------------------\r\n\r\n\trender(context: CanvasRenderingContext2D): void {\r\n\t\tif (!this.#visible) return\r\n\r\n\t\tconst previousAlpha = context.globalAlpha\r\n\t\tcontext.globalAlpha = previousAlpha * this.#opacity\r\n\r\n\t\t// Draw placeholder border until image is loaded by asset manager\r\n\t\tcontext.strokeStyle = this.#tint ?? '#888888'\r\n\t\tcontext.lineWidth = 1\r\n\t\tcontext.strokeRect(this.#x, this.#y, this.#width, this.#height)\r\n\r\n\t\t// Draw image key text as placeholder with tint color\r\n\t\tcontext.fillStyle = this.#tint ?? '#888888'\r\n\t\tcontext.font = '12px sans-serif'\r\n\t\tcontext.textAlign = 'center'\r\n\t\tcontext.textBaseline = 'middle'\r\n\t\tcontext.fillText(\r\n\t\t\tthis.#imageKey || 'Image',\r\n\t\t\tthis.#x + this.#width / 2,\r\n\t\t\tthis.#y + this.#height / 2,\r\n\t\t)\r\n\r\n\t\tcontext.globalAlpha = previousAlpha\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Lifecycle\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tdestroy(): void {\r\n\t\t// No resources to clean up\r\n\t}\r\n}\r\n","import type {\r\n\tUIManagerInterface,\r\n\tUIManagerOptions,\r\n\tUIElement,\r\n\tButtonOptions,\r\n\tTextOptions,\r\n\tProgressBarOptions,\r\n\tPanelOptions,\r\n\tSliderOptions,\r\n\tCheckboxOptions,\r\n\tToggleOptions,\r\n\tUIImageOptions,\r\n\tInputState,\r\n\tInteractiveUIElement,\r\n\tUnsubscribe, TextInterface,\r\n} from '../../types.js'\r\nimport { Button } from './Button.js'\r\nimport { Text } from './Text.js'\r\nimport { ProgressBar } from '~/src'\r\nimport { Panel } from './Panel.js'\r\nimport { Slider } from './Slider.js'\r\nimport { Checkbox } from './Checkbox.js'\r\nimport { Toggle } from './Toggle.js'\r\nimport { UIImage } from './UIImage.js'\r\n\r\n/**\r\n * UI Manager for managing all UI elements.\r\n */\r\nexport class UIManager implements UIManagerInterface {\r\n\t#elements: Map<string, UIElement> = new Map()\r\n\t#focusedElementId: string | undefined\r\n\t#scale: number\r\n\t#debugDraw: boolean\r\n\t#wasPointerDown = false\r\n\r\n\t#listeners = {\r\n\t\tfocusChange: new Set<(element: UIElement | undefined) => void>(),\r\n\t}\r\n\r\n\tconstructor(options?: UIManagerOptions) {\r\n\t\tthis.#scale = options?.scale ?? 1\r\n\t\tthis.#debugDraw = options?.debugDraw ?? false\r\n\r\n\t\t// Register hooks from options\r\n\t\tif (options?.onFocusChange) this.#listeners.focusChange.add(options.onFocusChange)\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Factory methods\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tcreateButton(options: ButtonOptions): Button {\r\n\t\tconst button = new Button(options)\r\n\t\tthis.#elements.set(button.id, button)\r\n\t\treturn button\r\n\t}\r\n\r\n\tcreateText(options: TextOptions): TextInterface {\r\n\t\tconst text = new Text(options)\r\n\t\tthis.#elements.set(text.id, text)\r\n\t\treturn text\r\n\t}\r\n\r\n\tcreateProgressBar(options: ProgressBarOptions): ProgressBar {\r\n\t\tconst progressBar = new ProgressBar(options)\r\n\t\tthis.#elements.set(progressBar.id, progressBar)\r\n\t\treturn progressBar\r\n\t}\r\n\r\n\tcreatePanel(options: PanelOptions): Panel {\r\n\t\tconst panel = new Panel(options)\r\n\t\tthis.#elements.set(panel.id, panel)\r\n\t\treturn panel\r\n\t}\r\n\r\n\tcreateSlider(options: SliderOptions): Slider {\r\n\t\tconst slider = new Slider(options)\r\n\t\tthis.#elements.set(slider.id, slider)\r\n\t\treturn slider\r\n\t}\r\n\r\n\tcreateCheckbox(options: CheckboxOptions): Checkbox {\r\n\t\tconst checkbox = new Checkbox(options)\r\n\t\tthis.#elements.set(checkbox.id, checkbox)\r\n\t\treturn checkbox\r\n\t}\r\n\r\n\tcreateToggle(options: ToggleOptions): Toggle {\r\n\t\tconst toggle = new Toggle(options)\r\n\t\tthis.#elements.set(toggle.id, toggle)\r\n\t\treturn toggle\r\n\t}\r\n\r\n\tcreateImage(options: UIImageOptions): UIImage {\r\n\t\tconst image = new UIImage(options)\r\n\t\tthis.#elements.set(image.id, image)\r\n\t\treturn image\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Element management\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tadd(element: UIElement): void {\r\n\t\tthis.#elements.set(element.id, element)\r\n\t}\r\n\r\n\tremove(id: string): void {\r\n\t\tconst element = this.#elements.get(id)\r\n\t\tif (element) {\r\n\t\t\telement.destroy()\r\n\t\t\tthis.#elements.delete(id)\r\n\t\t\tif (this.#focusedElementId === id) {\r\n\t\t\t\tthis.clearFocus()\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tget(id: string): UIElement | undefined {\r\n\t\treturn this.#elements.get(id)\r\n\t}\r\n\r\n\tgetAll(): readonly UIElement[] {\r\n\t\treturn Array.from(this.#elements.values())\r\n\t}\r\n\r\n\tclear(): void {\r\n\t\tfor (const element of this.#elements.values()) {\r\n\t\t\telement.destroy()\r\n\t\t}\r\n\t\tthis.#elements.clear()\r\n\t\tthis.clearFocus()\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Focus management\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetFocusedElement(): UIElement | undefined {\r\n\t\tif (!this.#focusedElementId) return undefined\r\n\t\treturn this.#elements.get(this.#focusedElementId)\r\n\t}\r\n\r\n\tsetFocusedElement(id: string): void {\r\n\t\tif (this.#elements.has(id)) {\r\n\t\t\tthis.#focusedElementId = id\r\n\t\t\tthis.#listeners.focusChange.forEach(cb => cb(this.getFocusedElement()))\r\n\t\t}\r\n\t}\r\n\r\n\tclearFocus(): void {\r\n\t\tthis.#focusedElementId = undefined\r\n\t\tthis.#listeners.focusChange.forEach(cb => cb(undefined))\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Lifecycle\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tupdate(inputState: InputState): void {\r\n\t\t// Adjust input state for UI scale\r\n\t\tconst scaledInputState: InputState = {\r\n\t\t\t...inputState,\r\n\t\t\tpointerX: inputState.pointerX / this.#scale,\r\n\t\t\tpointerY: inputState.pointerY / this.#scale,\r\n\t\t}\r\n\r\n\t\t// Sort elements by z-index for proper update order\r\n\t\tconst sortedElements = this.#getSortedElements()\r\n\r\n\t\t// Update all visible interactive elements\r\n\t\tfor (const element of sortedElements) {\r\n\t\t\tif (element.isVisible() && this.#isInteractive(element)) {\r\n\t\t\t\telement.update(scaledInputState)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Handle focus management - focus on click\r\n\t\tif (inputState.isPointerDown && !this.#wasPointerDown) {\r\n\t\t\tlet focusedId: string | undefined\r\n\t\t\t// Reverse order so topmost element gets focus first\r\n\t\t\tfor (let i = sortedElements.length - 1; i >= 0; i--) {\r\n\t\t\t\tconst element = sortedElements[i]\r\n\t\t\t\tif (element !== undefined && element.isVisible() && element.contains(scaledInputState.pointerX, scaledInputState.pointerY)) {\r\n\t\t\t\t\tfocusedId = element.id\r\n\t\t\t\t\tbreak\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (focusedId) {\r\n\t\t\t\tthis.setFocusedElement(focusedId)\r\n\t\t\t} else {\r\n\t\t\t\tthis.clearFocus()\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.#wasPointerDown = inputState.isPointerDown\r\n\t}\r\n\r\n\trender(context: CanvasRenderingContext2D): void {\r\n\t\t// Apply scale transform\r\n\t\tcontext.save()\r\n\t\tcontext.scale(this.#scale, this.#scale)\r\n\r\n\t\t// Render all visible elements sorted by z-index\r\n\t\tconst sortedElements = this.#getSortedElements()\r\n\t\tfor (const element of sortedElements) {\r\n\t\t\tif (element.isVisible()) {\r\n\t\t\t\telement.render(context)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Draw debug bounds if enabled\r\n\t\tif (this.#debugDraw) {\r\n\t\t\tcontext.strokeStyle = '#ff0000'\r\n\t\t\tcontext.lineWidth = 1\r\n\t\t\tfor (const element of sortedElements) {\r\n\t\t\t\tif (element.isVisible()) {\r\n\t\t\t\t\tconst bounds = element.getBounds()\r\n\t\t\t\t\tcontext.strokeRect(bounds.x, bounds.y, bounds.width, bounds.height)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tcontext.restore()\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Event subscriptions\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tonFocusChange(callback: (element: UIElement | undefined) => void): Unsubscribe {\r\n\t\tthis.#listeners.focusChange.add(callback)\r\n\t\treturn () => this.#listeners.focusChange.delete(callback)\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Lifecycle\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tdestroy(): void {\r\n\t\tthis.clear()\r\n\t\tthis.#listeners.focusChange.clear()\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// Private helpers\r\n\t// -------------------------------------------------------------------------\r\n\r\n\t#getSortedElements(): UIElement[] {\r\n\t\treturn Array.from(this.#elements.values()).sort((a, b) => a.getZIndex() - b.getZIndex())\r\n\t}\r\n\r\n\t#isInteractive(element: UIElement): element is InteractiveUIElement {\r\n\t\treturn 'update' in element && typeof (element as InteractiveUIElement).update === 'function'\r\n\t}\r\n}\r\n","/**\r\n * Reactive store for in-memory game state.\r\n */\r\n\r\nimport type {\r\n\tStoreInterface,\r\n\tStoreOptions,\r\n\tStoreChangeCallback,\r\n\tEqualityFn,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\nimport { DEFAULT_STORE_HISTORY_SIZE } from '../../constants.js'\r\nimport { shallowEqual } from '../../helpers.js'\r\nimport { getCurrentSubscriber } from '~/src'\r\n\r\n/**\r\n * Implementation of reactive game store.\r\n */\r\nexport class Store<TState> implements StoreInterface<TState> {\r\n\treadonly #id: string\r\n\t#value: TState\r\n\treadonly #initialState: TState\r\n\t#revision = 0\r\n\t#cleanRevision = 0\r\n\treadonly #subscribers = new Set<StoreChangeCallback<TState>>()\r\n\treadonly #equals: EqualityFn<TState>\r\n\r\n\t// History (optional)\r\n\treadonly #enableHistory: boolean\r\n\t#history: TState[] = []\r\n\t#historyIndex = -1\r\n\treadonly #maxHistorySize: number\r\n\r\n\t#destroyed = false\r\n\r\n\tconstructor(options: StoreOptions<TState>) {\r\n\t\tthis.#id = options.id\r\n\t\tthis.#value = options.initialState\r\n\t\tthis.#initialState = options.initialState\r\n\t\tthis.#enableHistory = options.enableHistory ?? false\r\n\t\tthis.#maxHistorySize = options.maxHistorySize ?? DEFAULT_STORE_HISTORY_SIZE\r\n\t\tthis.#equals = options.equals ?? shallowEqual\r\n\r\n\t\tif (this.#enableHistory) {\r\n\t\t\tthis.#history.push(options.initialState)\r\n\t\t\tthis.#historyIndex = 0\r\n\t\t}\r\n\t}\r\n\r\n\t// === ACCESSORS ===\r\n\r\n\tget(): TState {\r\n\t\tconst subscriber = getCurrentSubscriber()\r\n\t\tif (subscriber) {\r\n\t\t\tsubscriber.addDependency(this)\r\n\t\t}\r\n\t\treturn this.#value\r\n\t}\r\n\r\n\tpeek(): TState {\r\n\t\treturn this.#value\r\n\t}\r\n\r\n\tgetId(): string {\r\n\t\treturn this.#id\r\n\t}\r\n\r\n\tisDirty(): boolean {\r\n\t\treturn this.#revision !== this.#cleanRevision\r\n\t}\r\n\r\n\tgetRevision(): number {\r\n\t\treturn this.#revision\r\n\t}\r\n\r\n\t// === MUTATORS ===\r\n\r\n\tset(state: TState): void {\r\n\t\tif (this.#destroyed) return\r\n\t\tif (this.#equals(this.#value, state)) return\r\n\r\n\t\tconst previous = this.#value\r\n\t\tthis.#value = state\r\n\t\tthis.#revision++\r\n\r\n\t\tif (this.#enableHistory) {\r\n\t\t\t// Truncate forward history on new change\r\n\t\t\tthis.#history = this.#history.slice(0, this.#historyIndex + 1)\r\n\t\t\tthis.#history.push(state)\r\n\t\t\tif (this.#history.length > this.#maxHistorySize) {\r\n\t\t\t\tthis.#history.shift()\r\n\t\t\t}\r\n\t\t\tthis.#historyIndex = this.#history.length - 1\r\n\t\t}\r\n\r\n\t\t// Notify subscribers\r\n\t\tfor (const callback of this.#subscribers) {\r\n\t\t\tcallback(state, previous)\r\n\t\t}\r\n\t}\r\n\r\n\tupdate(updater: (current: TState) => TState): void {\r\n\t\tthis.set(updater(this.peek()))\r\n\t}\r\n\r\n\tmarkClean(): void {\r\n\t\tthis.#cleanRevision = this.#revision\r\n\t}\r\n\r\n\treset(): void {\r\n\t\tif (this.#enableHistory) {\r\n\t\t\tthis.#history = [this.#initialState]\r\n\t\t\tthis.#historyIndex = 0\r\n\t\t}\r\n\t\tthis.set(this.#initialState)\r\n\t}\r\n\r\n\t// === SUBSCRIPTIONS ===\r\n\r\n\tonChange(callback: StoreChangeCallback<TState>): Unsubscribe {\r\n\t\tthis.#subscribers.add(callback)\r\n\t\treturn () => {\r\n\t\t\tthis.#subscribers.delete(callback)\r\n\t\t}\r\n\t}\r\n\r\n\t// === HISTORY ===\r\n\r\n\thasUndo(): boolean {\r\n\t\tif (!this.#enableHistory) return false\r\n\t\treturn this.#historyIndex > 0\r\n\t}\r\n\r\n\thasRedo(): boolean {\r\n\t\tif (!this.#enableHistory) return false\r\n\t\treturn this.#historyIndex < this.#history.length - 1\r\n\t}\r\n\r\n\tundo(): void {\r\n\t\tif (!this.hasUndo()) return\r\n\r\n\t\tthis.#historyIndex--\r\n\t\tconst state = this.#history[this.#historyIndex]\r\n\t\tif (state !== undefined) {\r\n\t\t\tconst previous = this.#value\r\n\t\t\tthis.#value = state\r\n\t\t\tthis.#revision++\r\n\r\n\t\t\tfor (const callback of this.#subscribers) {\r\n\t\t\t\tcallback(state, previous)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tredo(): void {\r\n\t\tif (!this.hasRedo()) return\r\n\r\n\t\tthis.#historyIndex++\r\n\t\tconst state = this.#history[this.#historyIndex]\r\n\t\tif (state !== undefined) {\r\n\t\t\tconst previous = this.#value\r\n\t\t\tthis.#value = state\r\n\t\t\tthis.#revision++\r\n\r\n\t\t\tfor (const callback of this.#subscribers) {\r\n\t\t\t\tcallback(state, previous)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tclearHistory(): void {\r\n\t\tthis.#history = []\r\n\t\tthis.#historyIndex = -1\r\n\t}\r\n\r\n\t// === LIFECYCLE ===\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#destroyed = true\r\n\t\tthis.#subscribers.clear()\r\n\t\tthis.clearHistory()\r\n\t}\r\n}\r\n","/**\r\n * Computed values derived from reactive stores.\r\n */\r\n\r\nimport type { ComputedInterface, Subscriber, Unsubscribe } from '../../types.js'\r\nimport { pushSubscriber, popSubscriber } from '~/src'\r\n\r\n/**\r\n * Implementation of computed values.\r\n */\r\nexport class Computed<TValue> implements ComputedInterface<TValue>, Subscriber {\r\n\treadonly #compute: () => TValue\r\n\t#value: TValue | undefined\r\n\t#dirty = true\r\n\treadonly #dependencies = new Map<string, Unsubscribe>()\r\n\treadonly #subscribers = new Set<(value: TValue, previousValue: TValue) => void>()\r\n\t#destroyed = false\r\n\t#notifying = false\r\n\r\n\tconstructor(compute: () => TValue) {\r\n\t\tthis.#compute = compute\r\n\t}\r\n\r\n\t// === Subscriber interface ===\r\n\r\n\taddDependency(store: { getId(): string; onChange(cb: () => void): Unsubscribe }): void {\r\n\t\tconst id = store.getId()\r\n\t\tif (this.#dependencies.has(id)) return\r\n\r\n\t\tconst unsubscribe = store.onChange(() => {\r\n\t\t\tthis.#markDirty()\r\n\t\t})\r\n\t\tthis.#dependencies.set(id, unsubscribe)\r\n\t}\r\n\r\n\t#markDirty(): void {\r\n\t\tif (this.#dirty || this.#notifying || this.#destroyed) return\r\n\t\tthis.#dirty = true\r\n\r\n\t\t// Notify subscribers when dependencies change\r\n\t\tif (this.#subscribers.size > 0) {\r\n\t\t\tconst previousValue = this.#value as TValue\r\n\t\t\tthis.#notifying = true\r\n\t\t\ttry {\r\n\t\t\t\t// Recompute WITHOUT clearing dependencies to avoid re-subscription loop\r\n\t\t\t\t// Dependencies are already set up from the initial computation\r\n\t\t\t\tthis.#value = this.#compute()\r\n\t\t\t\tthis.#dirty = false\r\n\t\t\t\tconst newValue = this.#value\r\n\t\t\t\tif (previousValue !== newValue) {\r\n\t\t\t\t\tfor (const callback of this.#subscribers) {\r\n\t\t\t\t\t\tcallback(newValue, previousValue)\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t} finally {\r\n\t\t\t\tthis.#notifying = false\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t#recompute(): TValue {\r\n\t\t// Clear old dependencies\r\n\t\tfor (const unsubscribe of this.#dependencies.values()) {\r\n\t\t\tunsubscribe()\r\n\t\t}\r\n\t\tthis.#dependencies.clear()\r\n\r\n\t\t// Track new dependencies during compute\r\n\t\tpushSubscriber(this)\r\n\t\ttry {\r\n\t\t\tthis.#value = this.#compute()\r\n\t\t\tthis.#dirty = false\r\n\t\t\treturn this.#value\r\n\t\t} finally {\r\n\t\t\tpopSubscriber()\r\n\t\t}\r\n\t}\r\n\r\n\t// === ACCESSORS ===\r\n\r\n\tget(): TValue {\r\n\t\tif (this.#dirty) {\r\n\t\t\treturn this.#recompute()\r\n\t\t}\r\n\t\treturn this.#value as TValue\r\n\t}\r\n\r\n\tpeek(): TValue {\r\n\t\tif (this.#dirty) {\r\n\t\t\treturn this.#recompute()\r\n\t\t}\r\n\t\treturn this.#value as TValue\r\n\t}\r\n\r\n\t// === SUBSCRIPTIONS ===\r\n\r\n\tonChange(callback: (value: TValue, previousValue: TValue) => void): Unsubscribe {\r\n\t\tthis.#subscribers.add(callback)\r\n\r\n\t\t// Ensure we have a value and are tracking dependencies\r\n\t\tif (this.#dirty) {\r\n\t\t\tthis.#recompute()\r\n\t\t}\r\n\r\n\t\treturn () => {\r\n\t\t\tthis.#subscribers.delete(callback)\r\n\t\t}\r\n\t}\r\n\r\n\t// === LIFECYCLE ===\r\n\r\n\tdestroy(): void {\r\n\t\tif (this.#destroyed) return\r\n\t\tthis.#destroyed = true\r\n\r\n\t\t// Unsubscribe from all dependencies\r\n\t\tfor (const unsubscribe of this.#dependencies.values()) {\r\n\t\t\tunsubscribe()\r\n\t\t}\r\n\t\tthis.#dependencies.clear()\r\n\t\tthis.#subscribers.clear()\r\n\t}\r\n}\r\n","/**\r\n * Game state manager coordinating stores and persistence.\r\n */\r\n\r\nimport {\r\n\tStateManagerInterface,\r\n\tStateManagerConfig,\r\n\tStoreConfig,\r\n\tStateError,\r\n\tStateErrorCode,\r\n\tSnapshot,\r\n\tSaveSlot,\r\n\tSavePreview,\r\n\tStore,\r\n\tDatabaseInterface,\r\n\tTabSyncManagerInterface,\r\n\tUnsubscribe,\r\n\tStoreInterface,\r\n\tSchemaInterface,\r\n} from '~/src'\r\nimport {\r\n\tDEFAULT_DATABASE_NAME,\r\n\tDEFAULT_DATABASE_VERSION,\r\n\tDEFAULT_AUTO_SAVE_INTERVAL,\r\n\tSNAPSHOT_STORE_NAME,\r\n\tSLOTS_STORE_NAME,\r\n\tAUTOSAVE_SLOT_ID,\r\n} from '../../constants.js'\r\nimport { createDatabase, createTabSyncManager, createStore } from '~/src'\r\n\r\n/**\r\n * Implementation of game state manager.\r\n */\r\nexport class StateManager implements StateManagerInterface {\r\n\treadonly #stores = new Map<string, StoreInterface<unknown>>()\r\n\treadonly #schemas = new Map<string, SchemaInterface<unknown>>()\r\n\t#database: DatabaseInterface | null = null\r\n\t#sync: TabSyncManagerInterface | null = null\r\n\treadonly #config: StateManagerConfig\r\n\t#currentSlotId: string | undefined\r\n\t#initialized = false\r\n\t#autoSaveTimer: ReturnType<typeof setInterval> | null = null\r\n\t#playtimeStart = 0\r\n\t#totalPlaytime = 0\r\n\r\n\treadonly #saveListeners = new Set<(slotId: string) => void>()\r\n\treadonly #loadListeners = new Set<(slotId: string) => void>()\r\n\treadonly #leaderListeners = new Set<(isLeader: boolean) => void>()\r\n\treadonly #remoteChangeListeners = new Set<(slotId: string) => void>()\r\n\treadonly #errorListeners = new Set<(error: StateError) => void>()\r\n\r\n\t#visibilityHandler: (() => void) | null = null\r\n\t#beforeUnloadHandler: ((e: BeforeUnloadEvent) => void) | null = null\r\n\r\n\tprivate constructor(config: StateManagerConfig) {\r\n\t\tthis.#config = config\r\n\t}\r\n\r\n\tstatic async create(config: StateManagerConfig): Promise<StateManager> {\r\n\t\tconst manager = new StateManager(config)\r\n\t\tawait manager.#initialize()\r\n\t\treturn manager\r\n\t}\r\n\r\n\tasync #initialize(): Promise<void> {\r\n\t\t// Open database\r\n\t\tthis.#database = await createDatabase({\r\n\t\t\tname: this.#config.databaseName ?? DEFAULT_DATABASE_NAME,\r\n\t\t\tversion: DEFAULT_DATABASE_VERSION,\r\n\t\t\tstores: [\r\n\t\t\t\t{ name: SNAPSHOT_STORE_NAME, keyPath: 'id' },\r\n\t\t\t\t{\r\n\t\t\t\t\tname: SLOTS_STORE_NAME,\r\n\t\t\t\t\tkeyPath: 'id',\r\n\t\t\t\t\tindexes: [\r\n\t\t\t\t\t\t{ name: 'updatedAt', keyPath: 'updatedAt' },\r\n\t\t\t\t\t],\r\n\t\t\t\t},\r\n\t\t\t],\r\n\t\t})\r\n\r\n\t\t// Create tab sync manager\r\n\t\tif (this.#config.sync?.enabled !== false) {\r\n\t\t\tthis.#sync = createTabSyncManager()\r\n\t\t\tif (this.#sync) {\r\n\t\t\t\tthis.#sync.onLeaderChange((isLeader) => {\r\n\t\t\t\t\tfor (const callback of this.#leaderListeners) {\r\n\t\t\t\t\t\tcallback(isLeader)\r\n\t\t\t\t\t}\r\n\t\t\t\t})\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Create stores from config\r\n\t\tfor (const [storeId, storeConfig] of Object.entries(this.#config.stores)) {\r\n\t\t\tconst storeConf = storeConfig as StoreConfig<unknown>\r\n\t\t\tthis.#schemas.set(storeId, storeConf.schema)\r\n\r\n\t\t\tconst store = createStore({\r\n\t\t\t\tid: storeId,\r\n\t\t\t\tinitialState: storeConf.schema.createDefault(),\r\n\t\t\t\t...(storeConf.enableHistory !== undefined ? { enableHistory: storeConf.enableHistory } : {}),\r\n\t\t\t\t...(storeConf.maxHistorySize !== undefined ? { maxHistorySize: storeConf.maxHistorySize } : {}),\r\n\t\t\t})\r\n\t\t\tthis.#stores.set(storeId, store)\r\n\t\t}\r\n\r\n\t\t// Setup auto-save\r\n\t\tif (this.#config.autoSave?.enabled !== false) {\r\n\t\t\tconst interval = this.#config.autoSave?.intervalMs ?? DEFAULT_AUTO_SAVE_INTERVAL\r\n\t\t\tthis.#autoSaveTimer = setInterval(() => {\r\n\t\t\t\tvoid this.#handleAutoSave()\r\n\t\t\t}, interval)\r\n\r\n\t\t\t// Visibility change handler\r\n\t\t\tif (this.#config.autoSave?.onVisibilityHidden !== false) {\r\n\t\t\t\tthis.#visibilityHandler = () => {\r\n\t\t\t\t\tif (document.visibilityState === 'hidden' && this.isDirty()) {\r\n\t\t\t\t\t\tvoid this.autoSave()\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tdocument.addEventListener('visibilitychange', this.#visibilityHandler)\r\n\t\t\t}\r\n\r\n\t\t\t// Before unload handler\r\n\t\t\tif (this.#config.autoSave?.onBeforeUnload !== false) {\r\n\t\t\t\tthis.#beforeUnloadHandler = () => {\r\n\t\t\t\t\tif (this.isDirty()) {\r\n\t\t\t\t\t\t// Sync save attempt - can't use async here\r\n\t\t\t\t\t\tthis.#syncSave()\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\twindow.addEventListener('beforeunload', this.#beforeUnloadHandler)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Listen for remote changes\r\n\t\tif (this.#database) {\r\n\t\t\tthis.#database.onRemoteChange((change) => {\r\n\t\t\t\tif (change.storeName === SNAPSHOT_STORE_NAME && this.#currentSlotId) {\r\n\t\t\t\t\tfor (const callback of this.#remoteChangeListeners) {\r\n\t\t\t\t\t\tcallback(this.#currentSlotId)\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t\t}\r\n\r\n\t\tthis.#playtimeStart = Date.now()\r\n\t\tthis.#initialized = true\r\n\t}\r\n\r\n\t// === STORE ACCESS ===\r\n\r\n\tgetStore<TState>(storeId: string): Store<TState> | undefined {\r\n\t\treturn this.#stores.get(storeId) as Store<TState> | undefined\r\n\t}\r\n\r\n\tgetStoreIds(): readonly string[] {\r\n\t\treturn Array.from(this.#stores.keys())\r\n\t}\r\n\r\n\thasStore(storeId: string): boolean {\r\n\t\treturn this.#stores.has(storeId)\r\n\t}\r\n\r\n\t// === ACCESSORS ===\r\n\r\n\tisDirty(): boolean {\r\n\t\tfor (const store of this.#stores.values()) {\r\n\t\t\tif (store.isDirty()) return true\r\n\t\t}\r\n\t\treturn false\r\n\t}\r\n\r\n\tisReady(): boolean {\r\n\t\treturn this.#initialized\r\n\t}\r\n\r\n\tisLeader(): boolean {\r\n\t\treturn this.#sync?.isLeader() ?? true\r\n\t}\r\n\r\n\tgetCurrentSlotId(): string | undefined {\r\n\t\treturn this.#currentSlotId\r\n\t}\r\n\r\n\t// === SAVE/LOAD ===\r\n\r\n\tasync save(slotId: string, name: string, preview?: Partial<SavePreview>): Promise<void> {\r\n\t\tif (!this.#database) {\r\n\t\t\tthis.#notifyError('STORAGE_ERROR', 'Database not initialized')\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\ttry {\r\n\t\t\t// Collect store states\r\n\t\t\tconst stores: Record<string, unknown> = {}\r\n\t\t\tfor (const [id, store] of this.#stores) {\r\n\t\t\t\tstores[id] = store.peek()\r\n\t\t\t}\r\n\r\n\t\t\t// Create snapshot\r\n\t\t\tconst snapshot: Snapshot = {\r\n\t\t\t\tversion: this.#config.formatVersion,\r\n\t\t\t\ttimestamp: Date.now(),\r\n\t\t\t\tformatVersion: this.#config.formatVersion,\r\n\t\t\t\tgameVersion: this.#config.gameVersion,\r\n\t\t\t\tstores,\r\n\t\t\t}\r\n\r\n\t\t\t// Create/update slot metadata\r\n\t\t\tconst existingSlot = await this.getSlot(slotId)\r\n\t\t\tconst now = Date.now()\r\n\t\t\tconst playtime = this.#totalPlaytime + (now - this.#playtimeStart)\r\n\r\n\t\t\tconst fullPreview: SavePreview = {\r\n\t\t\t\tlevel: preview?.level ?? 1,\r\n\t\t\t\tlocation: preview?.location ?? 'Unknown',\r\n\t\t\t\t...(preview?.thumbnail ? { thumbnail: preview.thumbnail } : {}),\r\n\t\t\t}\r\n\r\n\t\t\tconst slot: SaveSlot = {\r\n\t\t\t\tid: slotId,\r\n\t\t\t\ttimestamp: now,\r\n\t\t\t\tname,\r\n\t\t\t\tcreatedAt: existingSlot?.createdAt ?? now,\r\n\t\t\t\tupdatedAt: now,\r\n\t\t\t\tplaytime,\r\n\t\t\t\tpreview: this.#config.createPreview?.() ?? fullPreview,\r\n\t\t\t\tisAutoSave: slotId === AUTOSAVE_SLOT_ID,\r\n\t\t\t}\r\n\r\n\t\t\t// Persist to database\r\n\t\t\tawait this.#database.put(SNAPSHOT_STORE_NAME, [{ id: slotId, ...snapshot }])\r\n\t\t\tawait this.#database.put(SLOTS_STORE_NAME, [slot])\r\n\r\n\t\t\t// Mark stores clean\r\n\t\t\tfor (const store of this.#stores.values()) {\r\n\t\t\t\tstore.markClean()\r\n\t\t\t}\r\n\r\n\t\t\tthis.#currentSlotId = slotId\r\n\r\n\t\t\t// Notify listeners\r\n\t\t\tfor (const callback of this.#saveListeners) {\r\n\t\t\t\tcallback(slotId)\r\n\t\t\t}\r\n\t\t} catch (cause) {\r\n\t\t\tthis.#notifyError('STORAGE_ERROR', 'Failed to save game', cause, slotId)\r\n\t\t\tthrow cause\r\n\t\t}\r\n\t}\r\n\r\n\tasync load(slotId: string): Promise<void> {\r\n\t\tif (!this.#database) {\r\n\t\t\tthis.#notifyError('STORAGE_ERROR', 'Database not initialized')\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\ttry {\r\n\t\t\t// Get snapshot\r\n\t\t\tconst snapshot = await this.#database.get<Snapshot & { id: string }>(\r\n\t\t\t\tSNAPSHOT_STORE_NAME,\r\n\t\t\t\tslotId,\r\n\t\t\t)\r\n\r\n\t\t\tif (!snapshot) {\r\n\t\t\t\tthis.#notifyError('SLOT_NOT_FOUND', `Save slot \"${slotId}\" not found`, undefined, slotId)\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\r\n\t\t\t// Validate and migrate if needed\r\n\t\t\tfor (const [storeId, state] of Object.entries(snapshot.stores)) {\r\n\t\t\t\tconst schema = this.#schemas.get(storeId)\r\n\t\t\t\tif (!schema) continue\r\n\r\n\t\t\t\tlet data = state\r\n\r\n\t\t\t\t// Migrate if version mismatch\r\n\t\t\t\tif (snapshot.formatVersion < this.#config.formatVersion && schema.migrate) {\r\n\t\t\t\t\tdata = schema.migrate(state, snapshot.formatVersion)\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Validate\r\n\t\t\t\tconst result = schema.validate(data)\r\n\t\t\t\tif (!result.ok) {\r\n\t\t\t\t\tthis.#notifyError('VALIDATION_FAILED', `Validation failed for store \"${storeId}\"`, result.errors, slotId)\r\n\t\t\t\t\treturn\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Hydrate store\r\n\t\t\t\tconst store = this.#stores.get(storeId)\r\n\t\t\t\tif (store) {\r\n\t\t\t\t\tstore.set(result.value)\r\n\t\t\t\t\tstore.markClean()\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// Get slot metadata for playtime\r\n\t\t\tconst slot = await this.getSlot(slotId)\r\n\t\t\tif (slot) {\r\n\t\t\t\tthis.#totalPlaytime = slot.playtime\r\n\t\t\t\tthis.#playtimeStart = Date.now()\r\n\t\t\t}\r\n\r\n\t\t\tthis.#currentSlotId = slotId\r\n\r\n\t\t\t// Notify listeners\r\n\t\t\tfor (const callback of this.#loadListeners) {\r\n\t\t\t\tcallback(slotId)\r\n\t\t\t}\r\n\t\t} catch (cause) {\r\n\t\t\tthis.#notifyError('STORAGE_ERROR', 'Failed to load game', cause, slotId)\r\n\t\t\tthrow cause\r\n\t\t}\r\n\t}\r\n\r\n\tasync deleteSlot(slotId: string): Promise<void> {\r\n\t\tif (!this.#database) return\r\n\r\n\t\ttry {\r\n\t\t\tawait this.#database.delete(SNAPSHOT_STORE_NAME, slotId)\r\n\t\t\tawait this.#database.delete(SLOTS_STORE_NAME, slotId)\r\n\r\n\t\t\tif (this.#currentSlotId === slotId) {\r\n\t\t\t\tthis.#currentSlotId = undefined\r\n\t\t\t}\r\n\t\t} catch (cause) {\r\n\t\t\tthis.#notifyError('STORAGE_ERROR', 'Failed to delete slot', cause, slotId)\r\n\t\t\tthrow cause\r\n\t\t}\r\n\t}\r\n\r\n\tasync hasSlot(slotId: string): Promise<boolean> {\r\n\t\tif (!this.#database) return false\r\n\t\tconst slot = await this.#database.get(SLOTS_STORE_NAME, slotId)\r\n\t\treturn slot !== undefined\r\n\t}\r\n\r\n\tasync getSlot(slotId: string): Promise<SaveSlot | undefined> {\r\n\t\tif (!this.#database) return undefined\r\n\t\treturn this.#database.get<SaveSlot>(SLOTS_STORE_NAME, slotId)\r\n\t}\r\n\r\n\tasync getSlots(): Promise<readonly SaveSlot[]> {\r\n\t\tif (!this.#database) return []\r\n\t\tconst slots = await this.#database.getAll<SaveSlot>(SLOTS_STORE_NAME)\r\n\t\treturn slots.slice().sort((a, b) => b.updatedAt - a.updatedAt)\r\n\t}\r\n\r\n\t// === AUTO-SAVE ===\r\n\r\n\tasync autoSave(): Promise<void> {\r\n\t\tif (!this.isDirty() && this.#config.autoSave?.onlyIfDirty !== false) return\r\n\t\tawait this.save(AUTOSAVE_SLOT_ID, 'Auto Save')\r\n\t}\r\n\r\n\tasync hasAutoSave(): Promise<boolean> {\r\n\t\treturn this.hasSlot(AUTOSAVE_SLOT_ID)\r\n\t}\r\n\r\n\tasync loadAutoSave(): Promise<void> {\r\n\t\tawait this.load(AUTOSAVE_SLOT_ID)\r\n\t}\r\n\r\n\tasync clearAutoSave(): Promise<void> {\r\n\t\tawait this.deleteSlot(AUTOSAVE_SLOT_ID)\r\n\t}\r\n\r\n\t// === NEW GAME ===\r\n\r\n\tresetToDefaults(): void {\r\n\t\tfor (const store of this.#stores.values()) {\r\n\t\t\tstore.reset()\r\n\t\t}\r\n\t\tthis.#currentSlotId = undefined\r\n\t\tthis.#totalPlaytime = 0\r\n\t\tthis.#playtimeStart = Date.now()\r\n\t}\r\n\r\n\t// === EXPORT/IMPORT ===\r\n\r\n\tasync exportSlot(slotId: string): Promise<string> {\r\n\t\tif (!this.#database) {\r\n\t\t\tthrow new Error('Database not initialized')\r\n\t\t}\r\n\r\n\t\tconst snapshot = await this.#database.get<Snapshot & { id: string }>(\r\n\t\t\tSNAPSHOT_STORE_NAME,\r\n\t\t\tslotId,\r\n\t\t)\r\n\t\tconst slot = await this.#database.get<SaveSlot>(SLOTS_STORE_NAME, slotId)\r\n\r\n\t\tif (!snapshot || !slot) {\r\n\t\t\tthrow new Error(`Slot \"${slotId}\" not found`)\r\n\t\t}\r\n\r\n\t\treturn JSON.stringify({ snapshot, slot })\r\n\t}\r\n\r\n\tasync importSlot(data: string, name?: string): Promise<string> {\r\n\t\tif (!this.#database) {\r\n\t\t\tthrow new Error('Database not initialized')\r\n\t\t}\r\n\r\n\t\ttry {\r\n\t\t\tconst parsed = JSON.parse(data) as { snapshot: Snapshot; slot: SaveSlot }\r\n\t\t\tconst newId = crypto.randomUUID()\r\n\t\t\tconst now = Date.now()\r\n\r\n\t\t\t// Update IDs and timestamps\r\n\t\t\tconst snapshot: Snapshot & { id: string } = {\r\n\t\t\t\t...parsed.snapshot,\r\n\t\t\t\tid: newId,\r\n\t\t\t\ttimestamp: now,\r\n\t\t\t}\r\n\r\n\t\t\tconst slot: SaveSlot = {\r\n\t\t\t\t...parsed.slot,\r\n\t\t\t\tid: newId,\r\n\t\t\t\tname: name ?? parsed.slot.name,\r\n\t\t\t\tcreatedAt: now,\r\n\t\t\t\tupdatedAt: now,\r\n\t\t\t\tisAutoSave: false,\r\n\t\t\t}\r\n\r\n\t\t\tawait this.#database.put(SNAPSHOT_STORE_NAME, [snapshot])\r\n\t\t\tawait this.#database.put(SLOTS_STORE_NAME, [slot])\r\n\r\n\t\t\treturn newId\r\n\t\t} catch (cause) {\r\n\t\t\tthis.#notifyError('IMPORT_INVALID', 'Failed to import save data', cause)\r\n\t\t\tthrow cause\r\n\t\t}\r\n\t}\r\n\r\n\t// === CROSS-TAB SYNC ===\r\n\r\n\tasync requestLeadership(): Promise<boolean> {\r\n\t\treturn this.#sync?.requestLeadership() ?? true\r\n\t}\r\n\r\n\treleaseLeadership(): void {\r\n\t\tthis.#sync?.releaseLeadership()\r\n\t}\r\n\r\n\tasync refresh(): Promise<void> {\r\n\t\tif (this.#currentSlotId) {\r\n\t\t\tawait this.load(this.#currentSlotId)\r\n\t\t}\r\n\t}\r\n\r\n\t// === SUBSCRIPTIONS ===\r\n\r\n\tonSave(callback: (slotId: string) => void): Unsubscribe {\r\n\t\tthis.#saveListeners.add(callback)\r\n\t\treturn () => this.#saveListeners.delete(callback)\r\n\t}\r\n\r\n\tonLoad(callback: (slotId: string) => void): Unsubscribe {\r\n\t\tthis.#loadListeners.add(callback)\r\n\t\treturn () => this.#loadListeners.delete(callback)\r\n\t}\r\n\r\n\tonLeadershipChange(callback: (isLeader: boolean) => void): Unsubscribe {\r\n\t\tthis.#leaderListeners.add(callback)\r\n\t\treturn () => this.#leaderListeners.delete(callback)\r\n\t}\r\n\r\n\tonRemoteChange(callback: (slotId: string) => void): Unsubscribe {\r\n\t\tthis.#remoteChangeListeners.add(callback)\r\n\t\treturn () => this.#remoteChangeListeners.delete(callback)\r\n\t}\r\n\r\n\tonError(callback: (error: StateError) => void): Unsubscribe {\r\n\t\tthis.#errorListeners.add(callback)\r\n\t\treturn () => this.#errorListeners.delete(callback)\r\n\t}\r\n\r\n\t// === LIFECYCLE ===\r\n\r\n\tasync flush(): Promise<void> {\r\n\t\tif (this.isDirty()) {\r\n\t\t\tawait this.autoSave()\r\n\t\t}\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\t// Stop auto-save\r\n\t\tif (this.#autoSaveTimer) {\r\n\t\t\tclearInterval(this.#autoSaveTimer)\r\n\t\t\tthis.#autoSaveTimer = null\r\n\t\t}\r\n\r\n\t\t// Remove event listeners\r\n\t\tif (this.#visibilityHandler) {\r\n\t\t\tdocument.removeEventListener('visibilitychange', this.#visibilityHandler)\r\n\t\t\tthis.#visibilityHandler = null\r\n\t\t}\r\n\r\n\t\tif (this.#beforeUnloadHandler) {\r\n\t\t\twindow.removeEventListener('beforeunload', this.#beforeUnloadHandler)\r\n\t\t\tthis.#beforeUnloadHandler = null\r\n\t\t}\r\n\r\n\t\t// Destroy stores\r\n\t\tfor (const store of this.#stores.values()) {\r\n\t\t\tstore.destroy()\r\n\t\t}\r\n\t\tthis.#stores.clear()\r\n\r\n\t\t// Destroy sync manager\r\n\t\tthis.#sync?.destroy()\r\n\t\tthis.#sync = null\r\n\r\n\t\t// Close database\r\n\t\tthis.#database?.destroy()\r\n\t\tthis.#database = null\r\n\r\n\t\t// Clear listeners\r\n\t\tthis.#saveListeners.clear()\r\n\t\tthis.#loadListeners.clear()\r\n\t\tthis.#leaderListeners.clear()\r\n\t\tthis.#remoteChangeListeners.clear()\r\n\t\tthis.#errorListeners.clear()\r\n\r\n\t\tthis.#initialized = false\r\n\t}\r\n\r\n\t// === PRIVATE ===\r\n\r\n\tasync #handleAutoSave(): Promise<void> {\r\n\t\tif (!this.isDirty() && this.#config.autoSave?.onlyIfDirty !== false) return\r\n\r\n\t\ttry {\r\n\t\t\tawait this.autoSave()\r\n\t\t} catch {\r\n\t\t\t// Error already notified via #notifyError\r\n\t\t}\r\n\t}\r\n\r\n\t#syncSave(): void {\r\n\t\t// Attempt synchronous save using localStorage as fallback\r\n\t\t// This is a best-effort save during beforeunload\r\n\t\ttry {\r\n\t\t\tconst stores: Record<string, unknown> = {}\r\n\t\t\tfor (const [id, store] of this.#stores) {\r\n\t\t\t\tstores[id] = store.peek()\r\n\t\t\t}\r\n\r\n\t\t\tconst data = JSON.stringify({\r\n\t\t\t\ttimestamp: Date.now(),\r\n\t\t\t\tstores,\r\n\t\t\t})\r\n\r\n\t\t\tlocalStorage.setItem('tactica-emergency-save', data)\r\n\t\t} catch {\r\n\t\t\t// Ignore - best effort only\r\n\t\t}\r\n\t}\r\n\r\n\t#notifyError(\r\n\t\tcode: StateErrorCode,\r\n\t\tmessage: string,\r\n\t\tcause?: unknown,\r\n\t\tslotId?: string,\r\n\t): void {\r\n\t\tconst error: StateError = {\r\n\t\t\tcode,\r\n\t\t\tmessage,\r\n\t\t\t...(cause !== undefined ? { cause } : {}),\r\n\t\t\t...(slotId !== undefined ? { slotId } : {}),\r\n\t\t}\r\n\r\n\t\tfor (const callback of this.#errorListeners) {\r\n\t\t\tcallback(error)\r\n\t\t}\r\n\t}\r\n}\r\n","/**\r\n * IndexedDB database wrapper.\r\n */\r\n\r\nimport type {\r\n\tDatabaseInterface,\r\n\tDatabaseTransaction,\r\n\tDatabaseChangeEvent,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Implementation of IndexedDB database wrapper.\r\n */\r\nexport class Database implements DatabaseInterface {\r\n\treadonly name: string\r\n\treadonly version: number\r\n\r\n\t#db: IDBDatabase | null = null\r\n\treadonly #channel: BroadcastChannel\r\n\treadonly #tabId: string\r\n\treadonly #remoteChangeListeners = new Set<(change: DatabaseChangeEvent) => void>()\r\n\r\n\tconstructor(db: IDBDatabase, channelName: string) {\r\n\t\tthis.#db = db\r\n\t\tthis.name = db.name\r\n\t\tthis.version = db.version\r\n\t\tthis.#tabId = crypto.randomUUID()\r\n\t\tthis.#channel = new BroadcastChannel(channelName)\r\n\r\n\t\tthis.#channel.addEventListener('message', (event: MessageEvent<DatabaseChangeEvent>) => {\r\n\t\t\t// Ignore own messages\r\n\t\t\tif (event.data.sourceTabId === this.#tabId) return\r\n\r\n\t\t\tfor (const callback of this.#remoteChangeListeners) {\r\n\t\t\t\tcallback(event.data)\r\n\t\t\t}\r\n\t\t})\r\n\t}\r\n\r\n\t// === ACCESSORS ===\r\n\r\n\tisOpen(): boolean {\r\n\t\treturn this.#db !== null\r\n\t}\r\n\r\n\t// === READ OPERATIONS ===\r\n\r\n\tasync get<T>(storeName: string, key: IDBValidKey): Promise<T | undefined> {\r\n\t\tconst db = this.#requireDb()\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tconst tx = db.transaction(storeName, 'readonly')\r\n\t\t\tconst store = tx.objectStore(storeName)\r\n\t\t\tconst request = store.get(key)\r\n\r\n\t\t\trequest.onsuccess = () => resolve(request.result as T | undefined)\r\n\t\t\trequest.onerror = () => reject(request.error)\r\n\t\t})\r\n\t}\r\n\r\n\tasync getAll<T>(storeName: string): Promise<readonly T[]> {\r\n\t\tconst db = this.#requireDb()\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tconst tx = db.transaction(storeName, 'readonly')\r\n\t\t\tconst store = tx.objectStore(storeName)\r\n\t\t\tconst request = store.getAll()\r\n\r\n\t\t\trequest.onsuccess = () => resolve(request.result as T[])\r\n\t\t\trequest.onerror = () => reject(request.error)\r\n\t\t})\r\n\t}\r\n\r\n\tasync getByIndex<T>(\r\n\t\tstoreName: string,\r\n\t\tindexName: string,\r\n\t\tvalue: IDBValidKey,\r\n\t): Promise<readonly T[]> {\r\n\t\tconst db = this.#requireDb()\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tconst tx = db.transaction(storeName, 'readonly')\r\n\t\t\tconst store = tx.objectStore(storeName)\r\n\t\t\tconst index = store.index(indexName)\r\n\t\t\tconst request = index.getAll(value)\r\n\r\n\t\t\trequest.onsuccess = () => resolve(request.result as T[])\r\n\t\t\trequest.onerror = () => reject(request.error)\r\n\t\t})\r\n\t}\r\n\r\n\tasync getByRange<T>(storeName: string, range: IDBKeyRange): Promise<readonly T[]> {\r\n\t\tconst db = this.#requireDb()\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tconst tx = db.transaction(storeName, 'readonly')\r\n\t\t\tconst store = tx.objectStore(storeName)\r\n\t\t\tconst request = store.getAll(range)\r\n\r\n\t\t\trequest.onsuccess = () => resolve(request.result as T[])\r\n\t\t\trequest.onerror = () => reject(request.error)\r\n\t\t})\r\n\t}\r\n\r\n\tasync getCount(storeName: string, query?: IDBValidKey | IDBKeyRange): Promise<number> {\r\n\t\tconst db = this.#requireDb()\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tconst tx = db.transaction(storeName, 'readonly')\r\n\t\t\tconst store = tx.objectStore(storeName)\r\n\t\t\tconst request = query !== undefined ? store.count(query) : store.count()\r\n\r\n\t\t\trequest.onsuccess = () => resolve(request.result)\r\n\t\t\trequest.onerror = () => reject(request.error)\r\n\t\t})\r\n\t}\r\n\r\n\t// === WRITE OPERATIONS ===\r\n\r\n\tasync put<T>(storeName: string, values: readonly T[]): Promise<IDBValidKey[]> {\r\n\t\tconst db = this.#requireDb()\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tconst tx = db.transaction(storeName, 'readwrite')\r\n\t\t\tconst store = tx.objectStore(storeName)\r\n\t\t\tconst keys: IDBValidKey[] = []\r\n\t\t\tlet completed = 0\r\n\r\n\t\t\tfor (const value of values) {\r\n\t\t\t\tconst request = store.put(value)\r\n\t\t\t\trequest.onsuccess = () => {\r\n\t\t\t\t\tkeys.push(request.result)\r\n\t\t\t\t\tcompleted++\r\n\t\t\t\t\tif (completed === values.length) {\r\n\t\t\t\t\t\t// Broadcast change to other tabs\r\n\t\t\t\t\t\tthis.#broadcastChange(storeName, 'put', keys[0])\r\n\t\t\t\t\t\tresolve(keys)\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\trequest.onerror = () => reject(request.error)\r\n\t\t\t}\r\n\r\n\t\t\tif (values.length === 0) {\r\n\t\t\t\tresolve([])\r\n\t\t\t}\r\n\t\t})\r\n\t}\r\n\r\n\tasync delete(storeName: string, key: IDBValidKey): Promise<void> {\r\n\t\tconst db = this.#requireDb()\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tconst tx = db.transaction(storeName, 'readwrite')\r\n\t\t\tconst store = tx.objectStore(storeName)\r\n\t\t\tconst request = store.delete(key)\r\n\r\n\t\t\trequest.onsuccess = () => {\r\n\t\t\t\tthis.#broadcastChange(storeName, 'delete', key)\r\n\t\t\t\tresolve()\r\n\t\t\t}\r\n\t\t\trequest.onerror = () => reject(request.error)\r\n\t\t})\r\n\t}\r\n\r\n\tasync clear(storeName: string): Promise<void> {\r\n\t\tconst db = this.#requireDb()\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tconst tx = db.transaction(storeName, 'readwrite')\r\n\t\t\tconst store = tx.objectStore(storeName)\r\n\t\t\tconst request = store.clear()\r\n\r\n\t\t\trequest.onsuccess = () => {\r\n\t\t\t\tthis.#broadcastChange(storeName, 'clear')\r\n\t\t\t\tresolve()\r\n\t\t\t}\r\n\t\t\trequest.onerror = () => reject(request.error)\r\n\t\t})\r\n\t}\r\n\r\n\t// === TRANSACTIONS ===\r\n\r\n\tasync transaction<T>(\r\n\t\tstoreNames: readonly string[],\r\n\t\tmode: IDBTransactionMode,\r\n\t\texecutor: (stores: DatabaseTransaction) => T,\r\n\t): Promise<T> {\r\n\t\tconst db = this.#requireDb()\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tconst tx = db.transaction(storeNames as string[], mode)\r\n\t\t\tconst transaction: DatabaseTransaction = {\r\n\t\t\t\tgetStore(name: string): IDBObjectStore {\r\n\t\t\t\t\treturn tx.objectStore(name)\r\n\t\t\t\t},\r\n\t\t\t}\r\n\r\n\t\t\tlet result: T\r\n\t\t\ttry {\r\n\t\t\t\tresult = executor(transaction)\r\n\t\t\t} catch (error) {\r\n\t\t\t\treject(error)\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\r\n\t\t\ttx.oncomplete = () => resolve(result)\r\n\t\t\ttx.onerror = () => reject(tx.error)\r\n\t\t\ttx.onabort = () => reject(tx.error ?? new Error('Transaction aborted'))\r\n\t\t})\r\n\t}\r\n\r\n\t// === SUBSCRIPTIONS ===\r\n\r\n\tonRemoteChange(callback: (change: DatabaseChangeEvent) => void): Unsubscribe {\r\n\t\tthis.#remoteChangeListeners.add(callback)\r\n\t\treturn () => {\r\n\t\t\tthis.#remoteChangeListeners.delete(callback)\r\n\t\t}\r\n\t}\r\n\r\n\t// === LIFECYCLE ===\r\n\r\n\tclose(): void {\r\n\t\tif (this.#db) {\r\n\t\t\tthis.#db.close()\r\n\t\t\tthis.#db = null\r\n\t\t}\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.close()\r\n\t\tthis.#channel.close()\r\n\t\tthis.#remoteChangeListeners.clear()\r\n\t}\r\n\r\n\t// === PRIVATE ===\r\n\r\n\t#requireDb(): IDBDatabase {\r\n\t\tif (!this.#db) {\r\n\t\t\tthrow new Error('Database is not open')\r\n\t\t}\r\n\t\treturn this.#db\r\n\t}\r\n\r\n\t#broadcastChange(storeName: string, operation: 'put' | 'delete' | 'clear', key?: IDBValidKey): void {\r\n\t\tconst change: DatabaseChangeEvent = {\r\n\t\t\tstoreName,\r\n\t\t\toperation,\r\n\t\t\t...(key !== undefined ? { key } : {}),\r\n\t\t\ttimestamp: Date.now(),\r\n\t\t\tsourceTabId: this.#tabId,\r\n\t\t}\r\n\t\tthis.#channel.postMessage(change)\r\n\t}\r\n}\r\n","import type {\r\n\tSchemaInterface,\r\n\tSchemaResult,\r\n\tSchemaError,\r\n\tFieldDefinition,\r\n\tSchemaBuilderOptions,\r\n} from '../../types.js'\r\nimport { createError, validateField } from '~/src/helpers'\r\n\r\n/**\r\n * Schema implementation for data validation.\r\n */\r\nexport class Schema<T> implements SchemaInterface<T> {\r\n\treadonly version: number\r\n\treadonly #fields: readonly FieldDefinition[]\r\n\treadonly #defaultValue: T\r\n\treadonly #migrateFunc?: (data: unknown, fromVersion: number) => unknown\r\n\r\n\tconstructor(options: SchemaBuilderOptions<T>) {\r\n\t\tthis.version = options.version\r\n\t\tthis.#fields = options.fields\r\n\t\tthis.#defaultValue = options.defaultValue\r\n\t\tif (options.migrate) {\r\n\t\t\tthis.#migrateFunc = options.migrate\r\n\t\t}\r\n\t}\r\n\r\n\tvalidate(data: unknown): SchemaResult<T> {\r\n\t\tconst errors: SchemaError[] = []\r\n\r\n\t\t// Data must be an object\r\n\t\tif (typeof data !== 'object' || data === null) {\r\n\t\t\treturn {\r\n\t\t\t\tok: false,\r\n\t\t\t\terrors: [createError('', 'Data must be an object', 'TYPE', data)],\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst record = data as Record<string, unknown>\r\n\r\n\t\t// Validate each field\r\n\t\tfor (const field of this.#fields) {\r\n\t\t\tconst value = record[field.name]\r\n\t\t\tconst path = field.name\r\n\t\t\tconst error = validateField(field, value, path)\r\n\t\t\tif (error) {\r\n\t\t\t\terrors.push(error)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (errors.length > 0) {\r\n\t\t\treturn { ok: false, errors }\r\n\t\t}\r\n\r\n\t\treturn {\r\n\t\t\tok: true,\r\n\t\t\tvalue: data as T,\r\n\t\t\terrors: [],\r\n\t\t}\r\n\t}\r\n\r\n\tmigrate(data: unknown, fromVersion: number): unknown {\r\n\t\tif (!this.#migrateFunc) {\r\n\t\t\treturn data\r\n\t\t}\r\n\t\treturn this.#migrateFunc(data, fromVersion)\r\n\t}\r\n\r\n\tcreateDefault(): T {\r\n\t\t// Return a deep copy of the default value\r\n\t\treturn JSON.parse(JSON.stringify(this.#defaultValue)) as T\r\n\t}\r\n}\r\n","/**\r\n * Tab synchronization manager using leader-follower pattern.\r\n */\r\n\r\nimport type { TabSyncManagerInterface, TabMessage, LeaderHeartbeat, Unsubscribe } from '../../types.js'\r\nimport {\r\n\tDEFAULT_TAB_HEARTBEAT_MS,\r\n\tDEFAULT_LEADER_TIMEOUT_MS,\r\n} from '../../constants.js'\r\n\r\nconst HEARTBEAT_KEY = 'tactica-leader-heartbeat'\r\n\r\n/**\r\n * Implementation of tab synchronization manager.\r\n */\r\nexport class TabSyncManager implements TabSyncManagerInterface {\r\n\treadonly tabId: string\r\n\r\n\t#isLeader = false\r\n\t#channel: BroadcastChannel | null\r\n\treadonly #heartbeatMs: number\r\n\treadonly #leaderTimeoutMs: number\r\n\t#heartbeatInterval: ReturnType<typeof setInterval> | null = null\r\n\t#monitorInterval: ReturnType<typeof setInterval> | null = null\r\n\r\n\treadonly #leaderListeners = new Set<(isLeader: boolean) => void>()\r\n\treadonly #messageListeners = new Map<string, Set<(payload: unknown, sourceTabId: string) => void>>()\r\n\treadonly #tabCountListeners = new Set<(count: number) => void>()\r\n\r\n\treadonly #knownTabs = new Set<string>()\r\n\r\n\tconstructor(\r\n\t\tchannelName: string = 'tactica-sync',\r\n\t\theartbeatMs: number = DEFAULT_TAB_HEARTBEAT_MS,\r\n\t\tleaderTimeoutMs: number = DEFAULT_LEADER_TIMEOUT_MS,\r\n\t) {\r\n\t\tthis.tabId = crypto.randomUUID()\r\n\t\tthis.#heartbeatMs = heartbeatMs\r\n\t\tthis.#leaderTimeoutMs = leaderTimeoutMs\r\n\t\tthis.#channel = new BroadcastChannel(channelName)\r\n\r\n\t\tthis.#channel.addEventListener('message', this.#handleMessage.bind(this))\r\n\r\n\t\t// Register self\r\n\t\tthis.#knownTabs.add(this.tabId)\r\n\r\n\t\t// Announce presence\r\n\t\tthis.broadcast('tab-join', { tabId: this.tabId })\r\n\r\n\t\t// Start monitoring for leadership\r\n\t\tthis.#startMonitoring()\r\n\r\n\t\t// Try to claim leadership if none exists\r\n\t\tvoid this.#tryClaimLeadership()\r\n\t}\r\n\r\n\t// === ACCESSORS ===\r\n\r\n\tisLeader(): boolean {\r\n\t\treturn this.#isLeader\r\n\t}\r\n\r\n\tisConnected(): boolean {\r\n\t\treturn this.#channel !== null\r\n\t}\r\n\r\n\tgetTabCount(): number {\r\n\t\treturn this.#knownTabs.size\r\n\t}\r\n\r\n\t// === LEADERSHIP ===\r\n\r\n\tasync requestLeadership(): Promise<boolean> {\r\n\t\tif (this.#isLeader) return true\r\n\r\n\t\tconst heartbeat = this.#getHeartbeat()\r\n\t\tconst now = Date.now()\r\n\r\n\t\tif (heartbeat && now - heartbeat.timestamp < this.#leaderTimeoutMs) {\r\n\t\t\t// Active leader exists\r\n\t\t\treturn false\r\n\t\t}\r\n\r\n\t\t// Try to claim leadership\r\n\t\treturn this.#claimLeadership()\r\n\t}\r\n\r\n\treleaseLeadership(): void {\r\n\t\tif (!this.#isLeader) return\r\n\r\n\t\tthis.#isLeader = false\r\n\t\tthis.#stopHeartbeat()\r\n\r\n\t\t// Remove heartbeat\r\n\t\ttry {\r\n\t\t\tlocalStorage.removeItem(HEARTBEAT_KEY)\r\n\t\t} catch {\r\n\t\t\t// Ignore storage errors\r\n\t\t}\r\n\r\n\t\t// Notify listeners\r\n\t\tfor (const callback of this.#leaderListeners) {\r\n\t\t\tcallback(false)\r\n\t\t}\r\n\r\n\t\t// Broadcast release\r\n\t\tthis.broadcast('leader-release', { tabId: this.tabId })\r\n\t}\r\n\r\n\t// === MESSAGING ===\r\n\r\n\tbroadcast<T>(type: string, payload: T): void {\r\n\t\tif (!this.#channel) return\r\n\r\n\t\tconst message: TabMessage<T> = {\r\n\t\t\ttype,\r\n\t\t\tpayload,\r\n\t\t\tsourceTabId: this.tabId,\r\n\t\t\ttimestamp: Date.now(),\r\n\t\t}\r\n\r\n\t\tthis.#channel.postMessage(message)\r\n\t}\r\n\r\n\t// === SUBSCRIPTIONS ===\r\n\r\n\tonLeaderChange(callback: (isLeader: boolean) => void): Unsubscribe {\r\n\t\tthis.#leaderListeners.add(callback)\r\n\t\treturn () => {\r\n\t\t\tthis.#leaderListeners.delete(callback)\r\n\t\t}\r\n\t}\r\n\r\n\tonMessage<T>(type: string, callback: (payload: T, sourceTabId: string) => void): Unsubscribe {\r\n\t\tlet listeners = this.#messageListeners.get(type)\r\n\t\tif (!listeners) {\r\n\t\t\tlisteners = new Set()\r\n\t\t\tthis.#messageListeners.set(type, listeners)\r\n\t\t}\r\n\t\tlisteners.add(callback as (payload: unknown, sourceTabId: string) => void)\r\n\r\n\t\treturn () => {\r\n\t\t\tconst set = this.#messageListeners.get(type)\r\n\t\t\tif (set) {\r\n\t\t\t\tset.delete(callback as (payload: unknown, sourceTabId: string) => void)\r\n\t\t\t\tif (set.size === 0) {\r\n\t\t\t\t\tthis.#messageListeners.delete(type)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tonTabCountChange(callback: (count: number) => void): Unsubscribe {\r\n\t\tthis.#tabCountListeners.add(callback)\r\n\t\treturn () => {\r\n\t\t\tthis.#tabCountListeners.delete(callback)\r\n\t\t}\r\n\t}\r\n\r\n\t// === LIFECYCLE ===\r\n\r\n\tdestroy(): void {\r\n\t\tthis.releaseLeadership()\r\n\t\tthis.#stopMonitoring()\r\n\r\n\t\tif (this.#channel) {\r\n\t\t\tthis.broadcast('tab-leave', { tabId: this.tabId })\r\n\t\t\tthis.#channel.close()\r\n\t\t\tthis.#channel = null\r\n\t\t}\r\n\r\n\t\tthis.#leaderListeners.clear()\r\n\t\tthis.#messageListeners.clear()\r\n\t\tthis.#tabCountListeners.clear()\r\n\t\tthis.#knownTabs.clear()\r\n\t}\r\n\r\n\t// === PRIVATE ===\r\n\r\n\t#handleMessage(event: MessageEvent<TabMessage>): void {\r\n\t\tconst message = event.data\r\n\r\n\t\t// Ignore own messages\r\n\t\tif (message.sourceTabId === this.tabId) return\r\n\r\n\t\t// Track tabs\r\n\t\tconst previousCount = this.#knownTabs.size\r\n\r\n\t\tswitch (message.type) {\r\n\t\t\tcase 'tab-join':\r\n\t\t\t\tthis.#knownTabs.add(message.sourceTabId)\r\n\t\t\t\t// Respond with our presence\r\n\t\t\t\tthis.broadcast('tab-ack', { tabId: this.tabId })\r\n\t\t\t\tbreak\r\n\r\n\t\t\tcase 'tab-ack':\r\n\t\t\t\tthis.#knownTabs.add(message.sourceTabId)\r\n\t\t\t\tbreak\r\n\r\n\t\t\tcase 'tab-leave':\r\n\t\t\t\tthis.#knownTabs.delete(message.sourceTabId)\r\n\t\t\t\tbreak\r\n\r\n\t\t\tcase 'leader-release':\r\n\t\t\t\t// Another tab released leadership, try to claim\r\n\t\t\t\tvoid this.#tryClaimLeadership()\r\n\t\t\t\tbreak\r\n\t\t}\r\n\r\n\t\t// Notify tab count change\r\n\t\tif (this.#knownTabs.size !== previousCount) {\r\n\t\t\tfor (const callback of this.#tabCountListeners) {\r\n\t\t\t\tcallback(this.#knownTabs.size)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Notify message listeners\r\n\t\tconst listeners = this.#messageListeners.get(message.type)\r\n\t\tif (listeners) {\r\n\t\t\tfor (const callback of listeners) {\r\n\t\t\t\tcallback(message.payload, message.sourceTabId)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t#getHeartbeat(): LeaderHeartbeat | null {\r\n\t\ttry {\r\n\t\t\tconst data = localStorage.getItem(HEARTBEAT_KEY)\r\n\t\t\tif (!data) return null\r\n\t\t\treturn JSON.parse(data) as LeaderHeartbeat\r\n\t\t} catch {\r\n\t\t\treturn null\r\n\t\t}\r\n\t}\r\n\r\n\t#writeHeartbeat(): void {\r\n\t\ttry {\r\n\t\t\tconst heartbeat: LeaderHeartbeat = {\r\n\t\t\t\ttabId: this.tabId,\r\n\t\t\t\ttimestamp: Date.now(),\r\n\t\t\t}\r\n\t\t\tlocalStorage.setItem(HEARTBEAT_KEY, JSON.stringify(heartbeat))\r\n\t\t} catch {\r\n\t\t\t// Ignore storage errors\r\n\t\t}\r\n\t}\r\n\r\n\tasync #tryClaimLeadership(): Promise<void> {\r\n\t\tconst heartbeat = this.#getHeartbeat()\r\n\t\tconst now = Date.now()\r\n\r\n\t\t// Check if there's an active leader\r\n\t\tif (heartbeat && now - heartbeat.timestamp < this.#leaderTimeoutMs) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\t// Try to claim\r\n\t\tthis.#claimLeadership()\r\n\t}\r\n\r\n\t#claimLeadership(): boolean {\r\n\t\tthis.#isLeader = true\r\n\t\tthis.#writeHeartbeat()\r\n\t\tthis.#startHeartbeat()\r\n\r\n\t\t// Notify listeners\r\n\t\tfor (const callback of this.#leaderListeners) {\r\n\t\t\tcallback(true)\r\n\t\t}\r\n\r\n\t\t// Broadcast claim\r\n\t\tthis.broadcast('leader-claim', { tabId: this.tabId })\r\n\r\n\t\treturn true\r\n\t}\r\n\r\n\t#startHeartbeat(): void {\r\n\t\tthis.#stopHeartbeat()\r\n\t\tthis.#heartbeatInterval = setInterval(() => {\r\n\t\t\tif (this.#isLeader) {\r\n\t\t\t\tthis.#writeHeartbeat()\r\n\t\t\t}\r\n\t\t}, this.#heartbeatMs)\r\n\t}\r\n\r\n\t#stopHeartbeat(): void {\r\n\t\tif (this.#heartbeatInterval) {\r\n\t\t\tclearInterval(this.#heartbeatInterval)\r\n\t\t\tthis.#heartbeatInterval = null\r\n\t\t}\r\n\t}\r\n\r\n\t#startMonitoring(): void {\r\n\t\tthis.#monitorInterval = setInterval(() => {\r\n\t\t\tif (this.#isLeader) return\r\n\r\n\t\t\tconst heartbeat = this.#getHeartbeat()\r\n\t\t\tconst now = Date.now()\r\n\r\n\t\t\t// Check if leader is stale\r\n\t\t\tif (!heartbeat || now - heartbeat.timestamp >= this.#leaderTimeoutMs) {\r\n\t\t\t\tvoid this.#tryClaimLeadership()\r\n\t\t\t}\r\n\t\t}, this.#heartbeatMs * 2)\r\n\t}\r\n\r\n\t#stopMonitoring(): void {\r\n\t\tif (this.#monitorInterval) {\r\n\t\t\tclearInterval(this.#monitorInterval)\r\n\t\t\tthis.#monitorInterval = null\r\n\t\t}\r\n\t}\r\n}\r\n","import type {\r\n\tAssetManagerInterface,\r\n\tAssetManagerOptions,\r\n\tAssetLoadOptions,\r\n\tAssetState,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Asset manager for loading and managing game assets.\r\n */\r\nexport class AssetManager implements AssetManagerInterface {\r\n\t#images: Map<string, HTMLImageElement> = new Map()\r\n\t#audio: Map<string, HTMLAudioElement> = new Map()\r\n\t#json: Map<string, unknown> = new Map()\r\n\t#text: Map<string, string> = new Map()\r\n\t#assetStates: Map<string, AssetState> = new Map()\r\n\t#loadedCount = 0\r\n\t#totalCount = 0\r\n\r\n\t#basePath: string\r\n\t#crossOrigin: string\r\n\t#retryAttempts: number\r\n\t#retryDelay: number\r\n\r\n\t#listeners = {\r\n\t\tloadStart: new Set<(key: string) => void>(),\r\n\t\tloadComplete: new Set<(key: string) => void>(),\r\n\t\tloadError: new Set<(key: string, error: string) => void>(),\r\n\t\tloadProgress: new Set<(loaded: number, total: number) => void>(),\r\n\t}\r\n\r\n\tconstructor(options?: AssetManagerOptions) {\r\n\t\tthis.#basePath = options?.basePath ?? ''\r\n\t\tthis.#crossOrigin = options?.crossOrigin ?? ''\r\n\t\tthis.#retryAttempts = options?.retryAttempts ?? 3\r\n\t\tthis.#retryDelay = options?.retryDelay ?? 1000\r\n\r\n\t\t// Register hooks from options\r\n\t\tif (options?.onLoadStart) this.#listeners.loadStart.add(options.onLoadStart)\r\n\t\tif (options?.onLoadComplete) this.#listeners.loadComplete.add(options.onLoadComplete)\r\n\t\tif (options?.onLoadError) this.#listeners.loadError.add(options.onLoadError)\r\n\t\tif (options?.onLoadProgress) this.#listeners.loadProgress.add(options.onLoadProgress)\r\n\t}\r\n\r\n\tasync loadImage(key: string, url: string): Promise<void> {\r\n\t\tthis.#listeners.loadStart.forEach(cb => cb(key))\r\n\t\tthis.#totalCount++\r\n\r\n\t\ttry {\r\n\t\t\tconst img = new Image()\r\n\t\t\tif (this.#crossOrigin) {\r\n\t\t\t\timg.crossOrigin = this.#crossOrigin\r\n\t\t\t}\r\n\t\t\timg.src = this.#basePath + url\r\n\r\n\t\t\tawait new Promise<void>((resolve, reject) => {\r\n\t\t\t\timg.onload = () => resolve()\r\n\t\t\t\timg.onerror = () => reject(new Error(`Failed to load image: ${url}`))\r\n\t\t\t})\r\n\r\n\t\t\tthis.#images.set(key, img)\r\n\t\t\tthis.#loadedCount++\r\n\t\t\tthis.#listeners.loadComplete.forEach(cb => cb(key))\r\n\t\t\tthis.#listeners.loadProgress.forEach(cb => cb(this.#loadedCount, this.#totalCount))\r\n\t\t} catch (error) {\r\n\t\t\tconst message = error instanceof Error ? error.message : 'Unknown error'\r\n\t\t\tthis.#listeners.loadError.forEach(cb => cb(key, message))\r\n\t\t\tthrow error\r\n\t\t}\r\n\t}\r\n\r\n\tasync loadAudio(key: string, url: string): Promise<void> {\r\n\t\tthis.#listeners.loadStart.forEach(cb => cb(key))\r\n\t\tthis.#totalCount++\r\n\r\n\t\ttry {\r\n\t\t\tconst audio = new Audio(this.#basePath + url)\r\n\t\t\tif (this.#crossOrigin) {\r\n\t\t\t\taudio.crossOrigin = this.#crossOrigin\r\n\t\t\t}\r\n\r\n\t\t\tawait new Promise<void>((resolve, reject) => {\r\n\t\t\t\taudio.oncanplaythrough = () => resolve()\r\n\t\t\t\taudio.onerror = () => reject(new Error(`Failed to load audio: ${url}`))\r\n\t\t\t})\r\n\r\n\t\t\tthis.#audio.set(key, audio)\r\n\t\t\tthis.#loadedCount++\r\n\t\t\tthis.#listeners.loadComplete.forEach(cb => cb(key))\r\n\t\t\tthis.#listeners.loadProgress.forEach(cb => cb(this.#loadedCount, this.#totalCount))\r\n\t\t} catch (error) {\r\n\t\t\tconst message = error instanceof Error ? error.message : 'Unknown error'\r\n\t\t\tthis.#listeners.loadError.forEach(cb => cb(key, message))\r\n\t\t\tthrow error\r\n\t\t}\r\n\t}\r\n\r\n\tasync loadJSON(key: string, url: string): Promise<void> {\r\n\t\tthis.#listeners.loadStart.forEach(cb => cb(key))\r\n\t\tthis.#totalCount++\r\n\r\n\t\ttry {\r\n\t\t\tconst response = await fetch(this.#basePath + url)\r\n\t\t\tif (!response.ok) {\r\n\t\t\t\tthrow new Error(`Failed to load JSON: ${url}`)\r\n\t\t\t}\r\n\t\t\tconst data = await response.json()\r\n\t\t\tthis.#json.set(key, data)\r\n\t\t\tthis.#loadedCount++\r\n\t\t\tthis.#listeners.loadComplete.forEach(cb => cb(key))\r\n\t\t\tthis.#listeners.loadProgress.forEach(cb => cb(this.#loadedCount, this.#totalCount))\r\n\t\t} catch (error) {\r\n\t\t\tconst message = error instanceof Error ? error.message : 'Unknown error'\r\n\t\t\tthis.#listeners.loadError.forEach(cb => cb(key, message))\r\n\t\t\tthrow error\r\n\t\t}\r\n\t}\r\n\r\n\tasync loadText(key: string, url: string): Promise<void> {\r\n\t\tthis.#listeners.loadStart.forEach(cb => cb(key))\r\n\t\tthis.#totalCount++\r\n\r\n\t\ttry {\r\n\t\t\tconst response = await fetch(this.#basePath + url)\r\n\t\t\tif (!response.ok) {\r\n\t\t\t\tthrow new Error(`Failed to load text: ${url}`)\r\n\t\t\t}\r\n\t\t\tconst text = await response.text()\r\n\t\t\tthis.#text.set(key, text)\r\n\t\t\tthis.#loadedCount++\r\n\t\t\tthis.#listeners.loadComplete.forEach(cb => cb(key))\r\n\t\t\tthis.#listeners.loadProgress.forEach(cb => cb(this.#loadedCount, this.#totalCount))\r\n\t\t} catch (error) {\r\n\t\t\tconst message = error instanceof Error ? error.message : 'Unknown error'\r\n\t\t\tthis.#listeners.loadError.forEach(cb => cb(key, message))\r\n\t\t\tthrow error\r\n\t\t}\r\n\t}\r\n\r\n\tasync loadBatch(assets: readonly AssetLoadOptions[]): Promise<void> {\r\n\t\tconst promises = assets.map(async(asset) => {\r\n\t\t\tswitch (asset.type) {\r\n\t\t\t\tcase 'image':\r\n\t\t\t\t\treturn this.loadImage(asset.key, asset.url)\r\n\t\t\t\tcase 'audio':\r\n\t\t\t\t\treturn this.loadAudio(asset.key, asset.url)\r\n\t\t\t\tcase 'json':\r\n\t\t\t\t\treturn this.loadJSON(asset.key, asset.url)\r\n\t\t\t\tcase 'text':\r\n\t\t\t\t\treturn this.loadText(asset.key, asset.url)\r\n\t\t\t}\r\n\t\t})\r\n\r\n\t\tawait Promise.all(promises)\r\n\t}\r\n\r\n\tgetImage(key: string): HTMLImageElement | undefined {\r\n\t\treturn this.#images.get(key)\r\n\t}\r\n\r\n\tgetAudio(key: string): HTMLAudioElement | undefined {\r\n\t\treturn this.#audio.get(key)\r\n\t}\r\n\r\n\tgetJSON<T = unknown>(key: string): T | undefined {\r\n\t\treturn this.#json.get(key) as T | undefined\r\n\t}\r\n\r\n\tgetText(key: string): string | undefined {\r\n\t\treturn this.#text.get(key)\r\n\t}\r\n\r\n\thasAsset(key: string): boolean {\r\n\t\treturn this.#assetStates.has(key)\r\n\t}\r\n\r\n\tgetAssetState(key: string): AssetState | undefined {\r\n\t\treturn this.#assetStates.get(key)\r\n\t}\r\n\r\n\tisLoaded(key: string): boolean {\r\n\t\treturn this.#assetStates.get(key)?.isLoaded ?? false\r\n\t}\r\n\r\n\tisLoading(key: string): boolean {\r\n\t\treturn this.#assetStates.get(key)?.isLoading ?? false\r\n\t}\r\n\r\n\tunload(key: string): void {\r\n\t\tthis.#images.delete(key)\r\n\t\tthis.#audio.delete(key)\r\n\t\tthis.#json.delete(key)\r\n\t\tthis.#text.delete(key)\r\n\t\tthis.#assetStates.delete(key)\r\n\t}\r\n\r\n\tunloadAll(): void {\r\n\t\tthis.#images.clear()\r\n\t\tthis.#audio.clear()\r\n\t\tthis.#json.clear()\r\n\t\tthis.#text.clear()\r\n\t\tthis.#assetStates.clear()\r\n\t\tthis.#loadedCount = 0\r\n\t\tthis.#totalCount = 0\r\n\t}\r\n\r\n\tgetLoadedCount(): number {\r\n\t\treturn this.#loadedCount\r\n\t}\r\n\r\n\tgetTotalCount(): number {\r\n\t\treturn this.#totalCount\r\n\t}\r\n\r\n\tgetLoadProgress(): number {\r\n\t\tif (this.#totalCount === 0) return 0\r\n\t\treturn this.#loadedCount / this.#totalCount\r\n\t}\r\n\r\n\tonLoadStart(callback: (key: string) => void): Unsubscribe {\r\n\t\tthis.#listeners.loadStart.add(callback)\r\n\t\treturn () => this.#listeners.loadStart.delete(callback)\r\n\t}\r\n\r\n\tonLoadComplete(callback: (key: string) => void): Unsubscribe {\r\n\t\tthis.#listeners.loadComplete.add(callback)\r\n\t\treturn () => this.#listeners.loadComplete.delete(callback)\r\n\t}\r\n\r\n\tonLoadError(callback: (key: string, error: string) => void): Unsubscribe {\r\n\t\tthis.#listeners.loadError.add(callback)\r\n\t\treturn () => this.#listeners.loadError.delete(callback)\r\n\t}\r\n\r\n\tonLoadProgress(callback: (loaded: number, total: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.loadProgress.add(callback)\r\n\t\treturn () => this.#listeners.loadProgress.delete(callback)\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.unloadAll()\r\n\t\tthis.#listeners.loadStart.clear()\r\n\t\tthis.#listeners.loadComplete.clear()\r\n\t\tthis.#listeners.loadError.clear()\r\n\t\tthis.#listeners.loadProgress.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tMobileManagerInterface,\r\n\tMobileManagerOptions,\r\n\tDeviceCapabilities,\r\n\tSafeAreaInsets,\r\n\tScreenOrientation,\r\n\tOrientationLockType,\r\n\tBatteryStatus,\r\n\tNetworkInfo,\r\n\tDeviceMotion,\r\n\tDeviceOrientation,\r\n\tHapticOptions,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\nimport {\r\n\thasDeviceMemory,\r\n\thasGetBattery,\r\n\thasNetworkConnection,\r\n\thasVibrate,\r\n} from '../../helpers.js'\r\n\r\n/**\r\n * Mobile manager for device-specific features and capabilities.\r\n */\r\nexport class MobileManager implements MobileManagerInterface {\r\n\t#enableMotionSensors: boolean\r\n\t#enableBatteryMonitoring: boolean\r\n\t#enableNetworkMonitoring: boolean\r\n\t#wakeLock: WakeLockSentinel | null = null\r\n\r\n\t#listeners = {\r\n\t\torientationChange: new Set<(orientation: ScreenOrientation) => void>(),\r\n\t\tdeviceMotion: new Set<(motion: DeviceMotion) => void>(),\r\n\t\tdeviceOrientation: new Set<(orientation: DeviceOrientation) => void>(),\r\n\t\tbatteryChange: new Set<(status: BatteryStatus) => void>(),\r\n\t\tnetworkChange: new Set<(info: NetworkInfo) => void>(),\r\n\t}\r\n\r\n\t// Bound handlers for cleanup\r\n\t#boundOrientationChange: () => void\r\n\t#boundDeviceMotion: (e: DeviceMotionEvent) => void\r\n\t#boundDeviceOrientation: (e: DeviceOrientationEvent) => void\r\n\r\n\tconstructor(options?: MobileManagerOptions) {\r\n\t\tthis.#enableMotionSensors = options?.enableMotionSensors ?? false\r\n\t\tthis.#enableBatteryMonitoring = options?.enableBatteryMonitoring ?? false\r\n\t\tthis.#enableNetworkMonitoring = options?.enableNetworkMonitoring ?? false\r\n\r\n\t\t// Register hooks from options\r\n\t\tif (options?.onOrientationChange) this.#listeners.orientationChange.add(options.onOrientationChange)\r\n\t\tif (options?.onDeviceMotion) this.#listeners.deviceMotion.add(options.onDeviceMotion)\r\n\t\tif (options?.onDeviceOrientation) this.#listeners.deviceOrientation.add(options.onDeviceOrientation)\r\n\t\tif (options?.onBatteryChange) this.#listeners.batteryChange.add(options.onBatteryChange)\r\n\t\tif (options?.onNetworkChange) this.#listeners.networkChange.add(options.onNetworkChange)\r\n\r\n\t\t// Bind handlers\r\n\t\tthis.#boundOrientationChange = this.#handleOrientationChange.bind(this)\r\n\t\tthis.#boundDeviceMotion = this.#handleDeviceMotion.bind(this)\r\n\t\tthis.#boundDeviceOrientation = this.#handleDeviceOrientation.bind(this)\r\n\r\n\t\t// Setup event listeners based on enabled features\r\n\t\twindow.addEventListener('resize', this.#boundOrientationChange)\r\n\r\n\t\tif (this.#enableMotionSensors) {\r\n\t\t\twindow.addEventListener('devicemotion', this.#boundDeviceMotion)\r\n\t\t\twindow.addEventListener('deviceorientation', this.#boundDeviceOrientation)\r\n\t\t}\r\n\t}\r\n\r\n\t#handleOrientationChange(): void {\r\n\t\tconst orientation = this.getOrientation()\r\n\t\tthis.#listeners.orientationChange.forEach(cb => cb(orientation))\r\n\t}\r\n\r\n\t#handleDeviceMotion(e: DeviceMotionEvent): void {\r\n\t\tconst motion: DeviceMotion = {\r\n\t\t\taccelerationX: e.acceleration?.x ?? 0,\r\n\t\t\taccelerationY: e.acceleration?.y ?? 0,\r\n\t\t\taccelerationZ: e.acceleration?.z ?? 0,\r\n\t\t\trotationAlpha: e.rotationRate?.alpha ?? 0,\r\n\t\t\trotationBeta: e.rotationRate?.beta ?? 0,\r\n\t\t\trotationGamma: e.rotationRate?.gamma ?? 0,\r\n\t\t\tinterval: e.interval,\r\n\t\t}\r\n\t\tthis.#listeners.deviceMotion.forEach(cb => cb(motion))\r\n\t}\r\n\r\n\t#handleDeviceOrientation(e: DeviceOrientationEvent): void {\r\n\t\tconst orientation: DeviceOrientation = {\r\n\t\t\talpha: e.alpha ?? 0,\r\n\t\t\tbeta: e.beta ?? 0,\r\n\t\t\tgamma: e.gamma ?? 0,\r\n\t\t\tabsolute: e.absolute,\r\n\t\t}\r\n\t\tthis.#listeners.deviceOrientation.forEach(cb => cb(orientation))\r\n\t}\r\n\r\n\tgetCapabilities(): DeviceCapabilities {\r\n\t\tconst capabilities: DeviceCapabilities = {\r\n\t\t\thasTouch: 'ontouchstart' in window,\r\n\t\t\thasAccelerometer: 'DeviceMotionEvent' in window,\r\n\t\t\thasGyroscope: 'DeviceOrientationEvent' in window,\r\n\t\t\thasVibration: hasVibrate(navigator),\r\n\t\t\thasGeolocation: 'geolocation' in navigator,\r\n\t\t\thasBattery: hasGetBattery(navigator),\r\n\t\t\thasNetworkInfo: hasNetworkConnection(navigator),\r\n\t\t\tmaxTouchPoints: navigator.maxTouchPoints,\r\n\t\t\thardwareConcurrency: navigator.hardwareConcurrency,\r\n\t\t}\r\n\r\n\t\tif (hasDeviceMemory(navigator)) {\r\n\t\t\treturn { ...capabilities, deviceMemory: navigator.deviceMemory }\r\n\t\t}\r\n\r\n\t\treturn capabilities\r\n\t}\r\n\r\n\tisMobile(): boolean {\r\n\t\treturn /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)\r\n\t}\r\n\r\n\tisTablet(): boolean {\r\n\t\treturn /iPad|Android/i.test(navigator.userAgent) && 'ontouchstart' in window\r\n\t}\r\n\r\n\tisIOS(): boolean {\r\n\t\treturn /iPhone|iPad|iPod/i.test(navigator.userAgent)\r\n\t}\r\n\r\n\tisAndroid(): boolean {\r\n\t\treturn /Android/i.test(navigator.userAgent)\r\n\t}\r\n\r\n\tgetSafeAreaInsets(): SafeAreaInsets {\r\n\t\tconst style = getComputedStyle(document.documentElement)\r\n\t\treturn {\r\n\t\t\ttop: parseInt(style.getPropertyValue('env(safe-area-inset-top)')) || 0,\r\n\t\t\tright: parseInt(style.getPropertyValue('env(safe-area-inset-right)')) || 0,\r\n\t\t\tbottom: parseInt(style.getPropertyValue('env(safe-area-inset-bottom)')) || 0,\r\n\t\t\tleft: parseInt(style.getPropertyValue('env(safe-area-inset-left)')) || 0,\r\n\t\t}\r\n\t}\r\n\r\n\tvibrate(pattern: number | readonly number[]): void {\r\n\t\tif (hasVibrate(navigator)) {\r\n\t\t\tif (typeof pattern === 'number') {\r\n\t\t\t\tnavigator.vibrate(pattern)\r\n\t\t\t} else {\r\n\t\t\t\tnavigator.vibrate([...pattern])\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tvibrateHaptic(options: HapticOptions): void {\r\n\t\tconst patterns: Record<string, number[]> = {\r\n\t\t\ttap: [10],\r\n\t\t\timpact: [50],\r\n\t\t\tnotification: [25, 50, 25],\r\n\t\t\tselection: [5],\r\n\t\t\terror: [50, 100, 50],\r\n\t\t\tsuccess: [25, 50],\r\n\t\t\twarning: [50, 25, 50],\r\n\t\t}\r\n\r\n\t\tconst pattern = patterns[options.pattern] || [10]\r\n\t\tthis.vibrate(pattern)\r\n\t}\r\n\r\n\tcancelVibration(): void {\r\n\t\tif ('vibrate' in navigator) {\r\n\t\t\tnavigator.vibrate(0)\r\n\t\t}\r\n\t}\r\n\r\n\tasync lockOrientation(type: OrientationLockType): Promise<void> {\r\n\t\tif ('orientation' in screen && 'lock' in screen.orientation && typeof screen.orientation.lock === 'function') {\r\n\t\t\tawait screen.orientation.lock(type)\r\n\t\t}\r\n\t}\r\n\r\n\tunlockOrientation(): void {\r\n\t\tif ('orientation' in screen && 'unlock' in screen.orientation) {\r\n\t\t\tscreen.orientation.unlock()\r\n\t\t}\r\n\t}\r\n\r\n\tgetOrientation(): ScreenOrientation {\r\n\t\tif (window.innerWidth > window.innerHeight) {\r\n\t\t\treturn 'landscape'\r\n\t\t}\r\n\t\treturn 'portrait'\r\n\t}\r\n\r\n\tasync getBatteryStatus(): Promise<BatteryStatus | undefined> {\r\n\t\tif (hasGetBattery(navigator)) {\r\n\t\t\tconst battery = await navigator.getBattery()\r\n\t\t\treturn {\r\n\t\t\t\tlevel: battery.level,\r\n\t\t\t\tcharging: battery.charging,\r\n\t\t\t\tchargingTime: battery.chargingTime,\r\n\t\t\t\tdischargingTime: battery.dischargingTime,\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn undefined\r\n\t}\r\n\r\n\tgetNetworkInfo(): NetworkInfo | undefined {\r\n\t\tif (!hasNetworkConnection(navigator)) return undefined\r\n\r\n\t\tconst connection = navigator.connection\r\n\t\tconst type = connection.type as NetworkInfo['type'] ?? 'unknown'\r\n\t\tconst effectiveType = connection.effectiveType as NetworkInfo['effectiveType'] ?? '4g'\r\n\t\treturn {\r\n\t\t\ttype,\r\n\t\t\teffectiveType,\r\n\t\t\tdownlink: connection.downlink ?? 0,\r\n\t\t\trtt: connection.rtt ?? 0,\r\n\t\t\tsaveData: connection.saveData || false,\r\n\t\t}\r\n\t}\r\n\r\n\tasync requestWakeLock(): Promise<void> {\r\n\t\tif ('wakeLock' in navigator) {\r\n\t\t\tthis.#wakeLock = await navigator.wakeLock.request('screen')\r\n\t\t}\r\n\t}\r\n\r\n\treleaseWakeLock(): void {\r\n\t\tif (this.#wakeLock) {\r\n\t\t\tthis.#wakeLock.release()\r\n\t\t\tthis.#wakeLock = null\r\n\t\t}\r\n\t}\r\n\r\n\thasWakeLock(): boolean {\r\n\t\treturn this.#wakeLock !== null\r\n\t}\r\n\r\n\tonOrientationChange(callback: (orientation: ScreenOrientation) => void): Unsubscribe {\r\n\t\tthis.#listeners.orientationChange.add(callback)\r\n\t\treturn () => this.#listeners.orientationChange.delete(callback)\r\n\t}\r\n\r\n\tonDeviceMotion(callback: (motion: DeviceMotion) => void): Unsubscribe {\r\n\t\tthis.#listeners.deviceMotion.add(callback)\r\n\t\treturn () => this.#listeners.deviceMotion.delete(callback)\r\n\t}\r\n\r\n\tonDeviceOrientation(callback: (orientation: DeviceOrientation) => void): Unsubscribe {\r\n\t\tthis.#listeners.deviceOrientation.add(callback)\r\n\t\treturn () => this.#listeners.deviceOrientation.delete(callback)\r\n\t}\r\n\r\n\tonBatteryChange(callback: (status: BatteryStatus) => void): Unsubscribe {\r\n\t\tthis.#listeners.batteryChange.add(callback)\r\n\t\treturn () => this.#listeners.batteryChange.delete(callback)\r\n\t}\r\n\r\n\tonNetworkChange(callback: (info: NetworkInfo) => void): Unsubscribe {\r\n\t\tthis.#listeners.networkChange.add(callback)\r\n\t\treturn () => this.#listeners.networkChange.delete(callback)\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.releaseWakeLock()\r\n\r\n\t\t// Remove event listeners\r\n\t\twindow.removeEventListener('resize', this.#boundOrientationChange)\r\n\t\twindow.removeEventListener('devicemotion', this.#boundDeviceMotion)\r\n\t\twindow.removeEventListener('deviceorientation', this.#boundDeviceOrientation)\r\n\r\n\t\t// Clear listener sets\r\n\t\tthis.#listeners.orientationChange.clear()\r\n\t\tthis.#listeners.deviceMotion.clear()\r\n\t\tthis.#listeners.deviceOrientation.clear()\r\n\t\tthis.#listeners.batteryChange.clear()\r\n\t\tthis.#listeners.networkChange.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tAccessibilityManagerInterface,\r\n\tAccessibilityOptions,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\ntype AnnouncementPriority = 'polite' | 'assertive'\r\n\r\n/**\r\n * Accessibility manager for accessibility features.\r\n */\r\nexport class AccessibilityManager implements AccessibilityManagerInterface {\r\n\t#screenReaderEnabled: boolean\r\n\t#reducedMotionEnabled = false\r\n\t#highContrastEnabled = false\r\n\t#liveRegion: HTMLElement | null = null\r\n\r\n\t#listeners = {\r\n\t\treducedMotionChange: new Set<(enabled: boolean) => void>(),\r\n\t\thighContrastChange: new Set<(enabled: boolean) => void>(),\r\n\t}\r\n\r\n\t// Media query listeners for cleanup\r\n\t#reducedMotionQuery: MediaQueryList\r\n\t#highContrastQuery: MediaQueryList\r\n\t#boundReducedMotionHandler: (e: MediaQueryListEvent) => void\r\n\t#boundHighContrastHandler: (e: MediaQueryListEvent) => void\r\n\r\n\tconstructor(options?: AccessibilityOptions) {\r\n\t\tthis.#screenReaderEnabled = options?.enableScreenReader ?? false\r\n\r\n\t\t// Register hooks from options\r\n\t\tif (options?.onReducedMotionChange) this.#listeners.reducedMotionChange.add(options.onReducedMotionChange)\r\n\t\tif (options?.onHighContrastChange) this.#listeners.highContrastChange.add(options.onHighContrastChange)\r\n\r\n\t\t// Detect user preferences and listen for changes\r\n\t\tthis.#reducedMotionQuery = window.matchMedia('(prefers-reduced-motion: reduce)')\r\n\t\tthis.#highContrastQuery = window.matchMedia('(prefers-contrast: high)')\r\n\r\n\t\tthis.#reducedMotionEnabled = this.#reducedMotionQuery.matches\r\n\t\tthis.#highContrastEnabled = this.#highContrastQuery.matches\r\n\r\n\t\t// Bind handlers\r\n\t\tthis.#boundReducedMotionHandler = this.#handleReducedMotionChange.bind(this)\r\n\t\tthis.#boundHighContrastHandler = this.#handleHighContrastChange.bind(this)\r\n\r\n\t\t// Setup event listeners\r\n\t\tthis.#reducedMotionQuery.addEventListener('change', this.#boundReducedMotionHandler)\r\n\t\tthis.#highContrastQuery.addEventListener('change', this.#boundHighContrastHandler)\r\n\r\n\t\t// Create live region for screen reader announcements\r\n\t\tif (this.#screenReaderEnabled) {\r\n\t\t\tthis.#createLiveRegion()\r\n\t\t}\r\n\t}\r\n\r\n\t#handleReducedMotionChange(e: MediaQueryListEvent): void {\r\n\t\tthis.#reducedMotionEnabled = e.matches\r\n\t\tthis.#listeners.reducedMotionChange.forEach(cb => cb(e.matches))\r\n\t}\r\n\r\n\t#handleHighContrastChange(e: MediaQueryListEvent): void {\r\n\t\tthis.#highContrastEnabled = e.matches\r\n\t\tthis.#listeners.highContrastChange.forEach(cb => cb(e.matches))\r\n\t}\r\n\r\n\t#createLiveRegion(): void {\r\n\t\tthis.#liveRegion = document.createElement('div')\r\n\t\tthis.#liveRegion.setAttribute('aria-live', 'polite')\r\n\t\tthis.#liveRegion.setAttribute('aria-atomic', 'true')\r\n\t\tthis.#liveRegion.style.position = 'absolute'\r\n\t\tthis.#liveRegion.style.width = '1px'\r\n\t\tthis.#liveRegion.style.height = '1px'\r\n\t\tthis.#liveRegion.style.overflow = 'hidden'\r\n\t\tthis.#liveRegion.style.clip = 'rect(0, 0, 0, 0)'\r\n\t\tthis.#liveRegion.style.whiteSpace = 'nowrap'\r\n\t\tdocument.body.appendChild(this.#liveRegion)\r\n\t}\r\n\r\n\tisScreenReaderEnabled(): boolean {\r\n\t\treturn this.#screenReaderEnabled\r\n\t}\r\n\r\n\tisReducedMotionEnabled(): boolean {\r\n\t\treturn this.#reducedMotionEnabled\r\n\t}\r\n\r\n\tisHighContrastEnabled(): boolean {\r\n\t\treturn this.#highContrastEnabled\r\n\t}\r\n\r\n\tannounce(message: string, priority: AnnouncementPriority = 'polite'): void {\r\n\t\tif (!this.#liveRegion) {\r\n\t\t\tthis.#createLiveRegion()\r\n\t\t}\r\n\t\tif (this.#liveRegion) {\r\n\t\t\tthis.#liveRegion.setAttribute('aria-live', priority)\r\n\t\t\tthis.#liveRegion.textContent = ''\r\n\t\t\t// Use setTimeout to ensure the change is announced\r\n\t\t\tsetTimeout(() => {\r\n\t\t\t\tif (this.#liveRegion) {\r\n\t\t\t\t\tthis.#liveRegion.textContent = message\r\n\t\t\t\t}\r\n\t\t\t}, 50)\r\n\t\t}\r\n\t}\r\n\r\n\tsetFocusTarget(element: HTMLElement): void {\r\n\t\telement.setAttribute('tabindex', '-1')\r\n\t\telement.focus()\r\n\t}\r\n\r\n\tdescribeFocus(description: string): void {\r\n\t\tconst focused = document.activeElement as HTMLElement | null\r\n\t\tif (focused) {\r\n\t\t\tlet describer = document.getElementById('a11y-focus-description')\r\n\t\t\tif (!describer) {\r\n\t\t\t\tdescriber = document.createElement('div')\r\n\t\t\t\tdescriber.id = 'a11y-focus-description'\r\n\t\t\t\tdescriber.style.display = 'none'\r\n\t\t\t\tdocument.body.appendChild(describer)\r\n\t\t\t}\r\n\t\t\tdescriber.textContent = description\r\n\t\t\tfocused.setAttribute('aria-describedby', 'a11y-focus-description')\r\n\t\t}\r\n\t}\r\n\r\n\tenableKeyboardNavigation(): void {\r\n\t\tdocument.body.classList.add('keyboard-navigation')\r\n\t}\r\n\r\n\tdisableKeyboardNavigation(): void {\r\n\t\tdocument.body.classList.remove('keyboard-navigation')\r\n\t}\r\n\r\n\tonReducedMotionChange(callback: (enabled: boolean) => void): Unsubscribe {\r\n\t\tthis.#listeners.reducedMotionChange.add(callback)\r\n\t\treturn () => this.#listeners.reducedMotionChange.delete(callback)\r\n\t}\r\n\r\n\tonHighContrastChange(callback: (enabled: boolean) => void): Unsubscribe {\r\n\t\tthis.#listeners.highContrastChange.add(callback)\r\n\t\treturn () => this.#listeners.highContrastChange.delete(callback)\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\t// Remove media query listeners\r\n\t\tthis.#reducedMotionQuery.removeEventListener('change', this.#boundReducedMotionHandler)\r\n\t\tthis.#highContrastQuery.removeEventListener('change', this.#boundHighContrastHandler)\r\n\r\n\t\t// Remove live region\r\n\t\tif (this.#liveRegion && this.#liveRegion.parentNode) {\r\n\t\t\tthis.#liveRegion.parentNode.removeChild(this.#liveRegion)\r\n\t\t}\r\n\r\n\t\t// Clear listener sets\r\n\t\tthis.#listeners.reducedMotionChange.clear()\r\n\t\tthis.#listeners.highContrastChange.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tPWAManagerInterface,\r\n\tPWAOptions,\r\n\tInstallPromptResult,\r\n\tUpdateCheckResult,\r\n\tBeforeInstallPromptEvent,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\ntype ServiceWorkerState = 'installing' | 'installed' | 'activating' | 'activated' | 'redundant'\r\n\r\n/**\r\n * PWA manager for Progressive Web App features.\r\n */\r\nexport class PWAManager implements PWAManagerInterface {\r\n\t#serviceWorkerState?: ServiceWorkerState\r\n\t#deferredPrompt: BeforeInstallPromptEvent | null = null\r\n\t#registration: ServiceWorkerRegistration | null = null\r\n\r\n\t#listeners = {\r\n\t\tinstall: new Set<() => void>(),\r\n\t\tupdate: new Set<(result: UpdateCheckResult) => void>(),\r\n\t\toffline: new Set<() => void>(),\r\n\t\tonline: new Set<() => void>(),\r\n\t}\r\n\r\n\t// Bound handlers for cleanup\r\n\t#boundOnline: () => void\r\n\t#boundOffline: () => void\r\n\t#boundBeforeInstallPrompt: (e: Event) => void\r\n\r\n\tconstructor(options?: PWAOptions) {\r\n\t\t// Register hooks from options\r\n\t\tif (options?.onInstall) this.#listeners.install.add(options.onInstall)\r\n\t\tif (options?.onUpdate) this.#listeners.update.add(options.onUpdate)\r\n\t\tif (options?.onOffline) this.#listeners.offline.add(options.onOffline)\r\n\t\tif (options?.onOnline) this.#listeners.online.add(options.onOnline)\r\n\r\n\t\t// Bind handlers\r\n\t\tthis.#boundOnline = this.#handleOnline.bind(this)\r\n\t\tthis.#boundOffline = this.#handleOffline.bind(this)\r\n\t\tthis.#boundBeforeInstallPrompt = this.#handleBeforeInstallPrompt.bind(this)\r\n\r\n\t\t// Setup event listeners\r\n\t\twindow.addEventListener('online', this.#boundOnline)\r\n\t\twindow.addEventListener('offline', this.#boundOffline)\r\n\t\twindow.addEventListener('beforeinstallprompt', this.#boundBeforeInstallPrompt)\r\n\r\n\t\t// Auto-register service worker if configured\r\n\t\tif (options?.autoRegister && options?.serviceWorkerUrl) {\r\n\t\t\tthis.registerServiceWorker(options.serviceWorkerUrl)\r\n\t\t}\r\n\t}\r\n\r\n\t#handleOnline(): void {\r\n\t\tthis.#listeners.online.forEach(cb => cb())\r\n\t}\r\n\r\n\t#handleOffline(): void {\r\n\t\tthis.#listeners.offline.forEach(cb => cb())\r\n\t}\r\n\r\n\t#handleBeforeInstallPrompt(e: Event): void {\r\n\t\te.preventDefault()\r\n\t\tthis.#deferredPrompt = e as BeforeInstallPromptEvent\r\n\t}\r\n\r\n\tisInstalled(): boolean {\r\n\t\treturn window.matchMedia('(display-mode: standalone)').matches\r\n\t}\r\n\r\n\tisStandalone(): boolean {\r\n\t\treturn this.isInstalled()\r\n\t}\r\n\r\n\tcanInstall(): boolean {\r\n\t\treturn this.#deferredPrompt !== null\r\n\t}\r\n\r\n\tgetServiceWorkerState(): ServiceWorkerState | undefined {\r\n\t\treturn this.#serviceWorkerState\r\n\t}\r\n\r\n\tasync promptInstall(): Promise<InstallPromptResult | undefined> {\r\n\t\tif (!this.#deferredPrompt) return undefined\r\n\r\n\t\tthis.#deferredPrompt.prompt()\r\n\t\tconst result = await this.#deferredPrompt.userChoice\r\n\t\tthis.#deferredPrompt = null\r\n\r\n\t\tif (result.outcome === 'accepted') {\r\n\t\t\tthis.#listeners.install.forEach(cb => cb())\r\n\t\t}\r\n\r\n\t\treturn result\r\n\t}\r\n\r\n\tasync checkForUpdates(): Promise<UpdateCheckResult> {\r\n\t\tif (!this.#registration) {\r\n\t\t\treturn { available: false }\r\n\t\t}\r\n\r\n\t\tawait this.#registration.update()\r\n\t\tconst waiting = this.#registration.waiting\r\n\t\tconst result: UpdateCheckResult = {\r\n\t\t\tavailable: waiting !== null,\r\n\t\t}\r\n\r\n\t\tif (result.available) {\r\n\t\t\tthis.#listeners.update.forEach(cb => cb(result))\r\n\t\t}\r\n\r\n\t\treturn result\r\n\t}\r\n\r\n\tasync applyUpdate(): Promise<void> {\r\n\t\tif (this.#registration?.waiting) {\r\n\t\t\tthis.#registration.waiting.postMessage({ type: 'SKIP_WAITING' })\r\n\t\t}\r\n\t}\r\n\r\n\tasync registerServiceWorker(scriptURL: string): Promise<void> {\r\n\t\tif ('serviceWorker' in navigator) {\r\n\t\t\tthis.#registration = await navigator.serviceWorker.register(scriptURL)\r\n\t\t\tthis.#serviceWorkerState = this.#registration.active ? 'activated' : 'installing'\r\n\t\t}\r\n\t}\r\n\r\n\tasync unregisterServiceWorker(): Promise<void> {\r\n\t\tif ('serviceWorker' in navigator) {\r\n\t\t\tconst registrations = await navigator.serviceWorker.getRegistrations()\r\n\t\t\tfor (const registration of registrations) {\r\n\t\t\t\tawait registration.unregister()\r\n\t\t\t}\r\n\t\t\tthis.#registration = null\r\n\t\t}\r\n\t}\r\n\r\n\tasync precacheAssets(urls: readonly string[]): Promise<void> {\r\n\t\tif ('caches' in window) {\r\n\t\t\tconst cache = await caches.open('precache-v1')\r\n\t\t\tawait cache.addAll([...urls])\r\n\t\t}\r\n\t}\r\n\r\n\tasync clearCache(cacheName?: string): Promise<void> {\r\n\t\tif ('caches' in window) {\r\n\t\t\tif (cacheName) {\r\n\t\t\t\tawait caches.delete(cacheName)\r\n\t\t\t} else {\r\n\t\t\t\tconst names = await caches.keys()\r\n\t\t\t\tawait Promise.all(names.map(name => caches.delete(name)))\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tonInstall(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.install.add(callback)\r\n\t\treturn () => this.#listeners.install.delete(callback)\r\n\t}\r\n\r\n\tonUpdate(callback: (result: UpdateCheckResult) => void): Unsubscribe {\r\n\t\tthis.#listeners.update.add(callback)\r\n\t\treturn () => this.#listeners.update.delete(callback)\r\n\t}\r\n\r\n\tonOffline(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.offline.add(callback)\r\n\t\treturn () => this.#listeners.offline.delete(callback)\r\n\t}\r\n\r\n\tonOnline(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.online.add(callback)\r\n\t\treturn () => this.#listeners.online.delete(callback)\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\t// Remove event listeners\r\n\t\twindow.removeEventListener('online', this.#boundOnline)\r\n\t\twindow.removeEventListener('offline', this.#boundOffline)\r\n\t\twindow.removeEventListener('beforeinstallprompt', this.#boundBeforeInstallPrompt)\r\n\r\n\t\t// Clear listener sets\r\n\t\tthis.#listeners.install.clear()\r\n\t\tthis.#listeners.update.clear()\r\n\t\tthis.#listeners.offline.clear()\r\n\t\tthis.#listeners.online.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tNetworkManagerInterface,\r\n\tNetworkOptions,\r\n\tNetworkMessage,\r\n\tNetworkStats,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\ntype ConnectionState = 'disconnected' | 'connecting' | 'connected' | 'reconnecting' | 'error'\r\n\r\n/**\r\n * Network manager for multiplayer/networking.\r\n */\r\nexport class NetworkManager implements NetworkManagerInterface {\r\n\t#state: ConnectionState = 'disconnected'\r\n\t#socket: WebSocket | null = null\r\n\t#url: string\r\n\t#autoReconnect: boolean\r\n\t#reconnectDelay: number\r\n\t#maxReconnectAttempts: number\r\n\t#heartbeatInterval: number\r\n\t#timeout: number\r\n\t#heartbeatTimer: number | null = null\r\n\t#reconnectTimer: number | null = null\r\n\t#reconnectAttempts = 0\r\n\r\n\t#stats: {\r\n\t\tbytesSent: number\r\n\t\tbytesReceived: number\r\n\t\tmessagesSent: number\r\n\t\tmessagesReceived: number\r\n\t\tlatency: number\r\n\t\treconnectCount: number\r\n\t} = {\r\n\t\t\tbytesSent: 0,\r\n\t\t\tbytesReceived: 0,\r\n\t\t\tmessagesSent: 0,\r\n\t\t\tmessagesReceived: 0,\r\n\t\t\tlatency: 0,\r\n\t\t\treconnectCount: 0,\r\n\t\t}\r\n\r\n\t#listeners = {\r\n\t\tconnect: new Set<() => void>(),\r\n\t\tdisconnect: new Set<(reason: string) => void>(),\r\n\t\terror: new Set<(error: string) => void>(),\r\n\t\treconnect: new Set<() => void>(),\r\n\t\tmessage: new Map<string, Set<(message: NetworkMessage<unknown>) => void>>(),\r\n\t}\r\n\r\n\tconstructor(options: NetworkOptions) {\r\n\t\tthis.#url = options.url\r\n\t\tthis.#autoReconnect = options.autoReconnect ?? true\r\n\t\tthis.#reconnectDelay = options.reconnectDelay ?? 1000\r\n\t\tthis.#maxReconnectAttempts = options.maxReconnectAttempts ?? 5\r\n\t\tthis.#heartbeatInterval = options.heartbeatInterval ?? 30000\r\n\t\tthis.#timeout = options.timeout ?? 10000\r\n\r\n\t\t// Register hooks from options\r\n\t\tif (options.onConnect) this.#listeners.connect.add(options.onConnect)\r\n\t\tif (options.onDisconnect) this.#listeners.disconnect.add(options.onDisconnect)\r\n\t\tif (options.onError) this.#listeners.error.add(options.onError)\r\n\t\tif (options.onReconnect) this.#listeners.reconnect.add(options.onReconnect)\r\n\t}\r\n\r\n\t#setupSocketListeners(socket: WebSocket): void {\r\n\t\tsocket.onopen = () => {\r\n\t\t\tthis.#state = 'connected'\r\n\t\t\tthis.#reconnectAttempts = 0\r\n\t\t\tthis.#startHeartbeat()\r\n\t\t\tthis.#listeners.connect.forEach(cb => cb())\r\n\t\t}\r\n\r\n\t\tsocket.onclose = (event) => {\r\n\t\t\tthis.#state = 'disconnected'\r\n\t\t\tthis.#stopHeartbeat()\r\n\t\t\tthis.#listeners.disconnect.forEach(cb => cb(event.reason || 'Connection closed'))\r\n\r\n\t\t\tif (this.#autoReconnect && this.#reconnectAttempts < this.#maxReconnectAttempts) {\r\n\t\t\t\tthis.#scheduleReconnect()\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tsocket.onerror = () => {\r\n\t\t\tthis.#state = 'error'\r\n\t\t\tthis.#listeners.error.forEach(cb => cb('WebSocket error'))\r\n\t\t}\r\n\r\n\t\tsocket.onmessage = (event) => {\r\n\t\t\tthis.#stats.messagesReceived++\r\n\t\t\tthis.#stats.bytesReceived += (event.data as string).length\r\n\r\n\t\t\ttry {\r\n\t\t\t\tconst message = JSON.parse(event.data as string) as NetworkMessage<unknown>\r\n\t\t\t\tconst typeListeners = this.#listeners.message.get(message.type)\r\n\t\t\t\tif (typeListeners) {\r\n\t\t\t\t\ttypeListeners.forEach(cb => cb(message))\r\n\t\t\t\t}\r\n\t\t\t} catch {\r\n\t\t\t\tthis.#listeners.error.forEach(cb => cb('Failed to parse message'))\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t#startHeartbeat(): void {\r\n\t\tthis.#stopHeartbeat()\r\n\t\tthis.#heartbeatTimer = window.setInterval(() => {\r\n\t\t\tif (this.#socket?.readyState === WebSocket.OPEN) {\r\n\t\t\t\tconst start = performance.now()\r\n\t\t\t\tthis.send('heartbeat', { timestamp: start })\r\n\t\t\t}\r\n\t\t}, this.#heartbeatInterval)\r\n\t}\r\n\r\n\t#stopHeartbeat(): void {\r\n\t\tif (this.#heartbeatTimer !== null) {\r\n\t\t\tclearInterval(this.#heartbeatTimer)\r\n\t\t\tthis.#heartbeatTimer = null\r\n\t\t}\r\n\t}\r\n\r\n\t#scheduleReconnect(): void {\r\n\t\tif (this.#reconnectTimer !== null) return\r\n\r\n\t\tthis.#state = 'reconnecting'\r\n\t\tconst delay = this.#reconnectDelay * Math.pow(2, this.#reconnectAttempts)\r\n\r\n\t\tthis.#reconnectTimer = window.setTimeout(() => {\r\n\t\t\tthis.#reconnectTimer = null\r\n\t\t\tthis.#reconnectAttempts++\r\n\t\t\tthis.#stats.reconnectCount++\r\n\t\t\tthis.connect().then(() => {\r\n\t\t\t\tthis.#listeners.reconnect.forEach(cb => cb())\r\n\t\t\t})\r\n\t\t}, delay)\r\n\t}\r\n\r\n\tgetState(): ConnectionState {\r\n\t\treturn this.#state\r\n\t}\r\n\r\n\tgetStats(): NetworkStats {\r\n\t\treturn this.#stats\r\n\t}\r\n\r\n\tisConnected(): boolean {\r\n\t\treturn this.#state === 'connected'\r\n\t}\r\n\r\n\tgetLatency(): number {\r\n\t\treturn this.#stats.latency\r\n\t}\r\n\r\n\tasync connect(): Promise<void> {\r\n\t\tif (this.#socket) {\r\n\t\t\tthis.#socket.close()\r\n\t\t}\r\n\r\n\t\tthis.#state = 'connecting'\r\n\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tconst timeoutId = setTimeout(() => {\r\n\t\t\t\treject(new Error('Connection timeout'))\r\n\t\t\t}, this.#timeout)\r\n\r\n\t\t\tconst socket = new WebSocket(this.#url)\r\n\t\t\tthis.#socket = socket\r\n\t\t\tthis.#setupSocketListeners(socket)\r\n\r\n\t\t\tconst originalOnOpen = socket.onopen\r\n\t\t\tsocket.onopen = (event) => {\r\n\t\t\t\tclearTimeout(timeoutId)\r\n\t\t\t\tif (originalOnOpen) originalOnOpen.call(socket, event)\r\n\t\t\t\tresolve()\r\n\t\t\t}\r\n\r\n\t\t\tconst originalOnError = socket.onerror\r\n\t\t\tsocket.onerror = (event) => {\r\n\t\t\t\tclearTimeout(timeoutId)\r\n\t\t\t\tif (originalOnError) originalOnError.call(socket, event)\r\n\t\t\t\treject(new Error('Connection failed'))\r\n\t\t\t}\r\n\t\t})\r\n\t}\r\n\r\n\tdisconnect(): void {\r\n\t\tthis.#autoReconnect = false\r\n\t\tif (this.#reconnectTimer !== null) {\r\n\t\t\tclearTimeout(this.#reconnectTimer)\r\n\t\t\tthis.#reconnectTimer = null\r\n\t\t}\r\n\t\tthis.#stopHeartbeat()\r\n\t\tif (this.#socket) {\r\n\t\t\tthis.#socket.close()\r\n\t\t\tthis.#socket = null\r\n\t\t}\r\n\t\tthis.#state = 'disconnected'\r\n\t\tthis.#listeners.disconnect.forEach(cb => cb('Manual disconnect'))\r\n\t}\r\n\r\n\tasync reconnect(): Promise<void> {\r\n\t\tthis.#autoReconnect = true\r\n\t\tthis.#reconnectAttempts = 0\r\n\t\tawait this.connect()\r\n\t\tthis.#listeners.reconnect.forEach(cb => cb())\r\n\t}\r\n\r\n\tsend<T>(type: string, payload: T): void {\r\n\t\tif (this.#socket?.readyState === WebSocket.OPEN) {\r\n\t\t\tconst message = JSON.stringify({ type, payload, timestamp: Date.now() })\r\n\t\t\tthis.#socket.send(message)\r\n\t\t\tthis.#stats.messagesSent++\r\n\t\t\tthis.#stats.bytesSent += message.length\r\n\t\t}\r\n\t}\r\n\r\n\tasync sendReliable<T>(type: string, payload: T): Promise<void> {\r\n\t\t// For WebSocket, all messages are reliable\r\n\t\tthis.send(type, payload)\r\n\t}\r\n\r\n\tbroadcast<T>(type: string, payload: T): void {\r\n\t\t// In a client, broadcast is the same as send - server handles distribution\r\n\t\tthis.send(type, payload)\r\n\t}\r\n\r\n\tonConnect(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.connect.add(callback)\r\n\t\treturn () => this.#listeners.connect.delete(callback)\r\n\t}\r\n\r\n\tonDisconnect(callback: (reason: string) => void): Unsubscribe {\r\n\t\tthis.#listeners.disconnect.add(callback)\r\n\t\treturn () => this.#listeners.disconnect.delete(callback)\r\n\t}\r\n\r\n\tonError(callback: (error: string) => void): Unsubscribe {\r\n\t\tthis.#listeners.error.add(callback)\r\n\t\treturn () => this.#listeners.error.delete(callback)\r\n\t}\r\n\r\n\tonReconnect(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.reconnect.add(callback)\r\n\t\treturn () => this.#listeners.reconnect.delete(callback)\r\n\t}\r\n\r\n\tonMessage<T>(type: string, callback: (message: NetworkMessage<T>) => void): Unsubscribe {\r\n\t\tif (!this.#listeners.message.has(type)) {\r\n\t\t\tthis.#listeners.message.set(type, new Set())\r\n\t\t}\r\n\t\tconst typedCallback = callback as (message: NetworkMessage<unknown>) => void\r\n\t\tthis.#listeners.message.get(type)!.add(typedCallback)\r\n\t\treturn () => this.#listeners.message.get(type)?.delete(typedCallback)\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.disconnect()\r\n\t\tthis.#listeners.connect.clear()\r\n\t\tthis.#listeners.disconnect.clear()\r\n\t\tthis.#listeners.error.clear()\r\n\t\tthis.#listeners.reconnect.clear()\r\n\t\tthis.#listeners.message.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tPerformanceMonitorInterface,\r\n\tPerformanceOptions,\r\n\tPerformanceMetrics,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Performance monitor for tracking FPS and performance metrics.\r\n */\r\nexport class PerformanceMonitor implements PerformanceMonitorInterface {\r\n\t#enabled: boolean\r\n\t#sampleRate: number\r\n\t#trackMemory: boolean\r\n\t#historySize: number\r\n\t#history: PerformanceMetrics[] = []\r\n\t#currentMetrics: PerformanceMetrics\r\n\r\n\t#frameStartTime = 0\r\n\t#lastFrameTime = 0\r\n\t#frameCount = 0\r\n\t#fpsAccumulator = 0\r\n\t#updateTimeAccumulator = 0\r\n\t#renderTimeAccumulator = 0\r\n\r\n\tconstructor(options?: PerformanceOptions) {\r\n\t\tthis.#enabled = options?.enabled ?? true\r\n\t\tthis.#sampleRate = options?.sampleRate ?? 60\r\n\t\tthis.#trackMemory = options?.trackMemory ?? false\r\n\t\tthis.#historySize = options?.historySize ?? 300\r\n\r\n\t\tthis.#currentMetrics = {\r\n\t\t\tfps: 0,\r\n\t\t\tframeTime: 0,\r\n\t\t\tupdateTime: 0,\r\n\t\t\trenderTime: 0,\r\n\t\t\tentityCount: 0,\r\n\t\t\tdrawCalls: 0,\r\n\t\t\tmemoryUsed: 0,\r\n\t\t}\r\n\t}\r\n\r\n\tgetOptions(): PerformanceOptions {\r\n\t\treturn {\r\n\t\t\tenabled: this.#enabled,\r\n\t\t\tsampleRate: this.#sampleRate,\r\n\t\t\ttrackMemory: this.#trackMemory,\r\n\t\t\thistorySize: this.#historySize,\r\n\t\t}\r\n\t}\r\n\r\n\tgetMetrics(): PerformanceMetrics {\r\n\t\treturn this.#currentMetrics\r\n\t}\r\n\r\n\tisEnabled(): boolean {\r\n\t\treturn this.#enabled\r\n\t}\r\n\r\n\tenable(): void {\r\n\t\tthis.#enabled = true\r\n\t}\r\n\r\n\tdisable(): void {\r\n\t\tthis.#enabled = false\r\n\t}\r\n\r\n\tstartFrame(): void {\r\n\t\tif (!this.#enabled) return\r\n\t\tthis.#frameStartTime = performance.now()\r\n\t}\r\n\r\n\tendFrame(): void {\r\n\t\tif (!this.#enabled) return\r\n\r\n\t\tconst now = performance.now()\r\n\t\tconst frameTime = now - this.#frameStartTime\r\n\t\tconst deltaTime = now - this.#lastFrameTime\r\n\t\tthis.#lastFrameTime = now\r\n\r\n\t\tthis.#frameCount++\r\n\t\tthis.#fpsAccumulator += deltaTime\r\n\r\n\t\t// Update FPS every second\r\n\t\tif (this.#fpsAccumulator >= 1000) {\r\n\t\t\tthis.#currentMetrics = {\r\n\t\t\t\t...this.#currentMetrics,\r\n\t\t\t\tfps: Math.round((this.#frameCount * 1000) / this.#fpsAccumulator),\r\n\t\t\t\tframeTime,\r\n\t\t\t\tupdateTime: this.#updateTimeAccumulator / this.#frameCount,\r\n\t\t\t\trenderTime: this.#renderTimeAccumulator / this.#frameCount,\r\n\t\t\t}\r\n\r\n\t\t\t// Track memory if enabled and available\r\n\t\t\tif (this.#trackMemory && 'memory' in performance) {\r\n\t\t\t\tconst memory = (performance as { memory?: { usedJSHeapSize?: number } }).memory\r\n\t\t\t\tif (memory?.usedJSHeapSize) {\r\n\t\t\t\t\tthis.#currentMetrics = {\r\n\t\t\t\t\t\t...this.#currentMetrics,\r\n\t\t\t\t\t\tmemoryUsed: memory.usedJSHeapSize,\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// Add to history\r\n\t\t\tthis.#history.push({ ...this.#currentMetrics })\r\n\t\t\tif (this.#history.length > this.#historySize) {\r\n\t\t\t\tthis.#history.shift()\r\n\t\t\t}\r\n\r\n\t\t\t// Reset accumulators\r\n\t\t\tthis.#frameCount = 0\r\n\t\t\tthis.#fpsAccumulator = 0\r\n\t\t\tthis.#updateTimeAccumulator = 0\r\n\t\t\tthis.#renderTimeAccumulator = 0\r\n\t\t}\r\n\t}\r\n\r\n\trecordUpdateTime(time: number): void {\r\n\t\tif (!this.#enabled) return\r\n\t\tthis.#updateTimeAccumulator += time\r\n\t}\r\n\r\n\trecordRenderTime(time: number): void {\r\n\t\tif (!this.#enabled) return\r\n\t\tthis.#renderTimeAccumulator += time\r\n\t}\r\n\r\n\trecordDrawCalls(count: number): void {\r\n\t\tif (!this.#enabled) return\r\n\t\tthis.#currentMetrics = { ...this.#currentMetrics, drawCalls: count }\r\n\t}\r\n\r\n\trecordEntityCount(count: number): void {\r\n\t\tif (!this.#enabled) return\r\n\t\tthis.#currentMetrics = { ...this.#currentMetrics, entityCount: count }\r\n\t}\r\n\r\n\treset(): void {\r\n\t\tthis.#history.length = 0\r\n\t\tthis.#frameCount = 0\r\n\t\tthis.#fpsAccumulator = 0\r\n\t\tthis.#updateTimeAccumulator = 0\r\n\t\tthis.#renderTimeAccumulator = 0\r\n\t\tthis.#currentMetrics = {\r\n\t\t\tfps: 0,\r\n\t\t\tframeTime: 0,\r\n\t\t\tupdateTime: 0,\r\n\t\t\trenderTime: 0,\r\n\t\t\tentityCount: 0,\r\n\t\t\tdrawCalls: 0,\r\n\t\t\tmemoryUsed: 0,\r\n\t\t}\r\n\t}\r\n\r\n\tgetHistory(samples?: number): readonly PerformanceMetrics[] {\r\n\t\tif (samples !== undefined && samples < this.#history.length) {\r\n\t\t\treturn this.#history.slice(-samples)\r\n\t\t}\r\n\t\treturn this.#history\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.reset()\r\n\t}\r\n}\r\n","import type {\r\n\tDebugToolsInterface,\r\n\tDebugLogEntry,\r\n\tPerformanceTrace,\r\n\tStorageDiagnostics,\r\n\tChangeRecord,\r\n} from '../../types.js'\r\n\r\ntype LogLevel = 'debug' | 'info' | 'warn' | 'error'\r\n\r\n/**\r\n * Debug tools for debugging and diagnostics.\r\n */\r\nexport class DebugTools implements DebugToolsInterface {\r\n\t#logLevel: LogLevel = 'info'\r\n\t#logs: DebugLogEntry[] = []\r\n\t#traces: Map<string, {\r\n\t\toperation: string\r\n\t\tstartTime: number\r\n\t\tendTime: number\r\n\t\tduration: number\r\n\t\tsuccess: boolean\r\n\t\tmetadata?: Record<string, unknown>\r\n\t}> = new Map()\r\n\t#maxLogs = 1000\r\n\t#storeChanges: Map<string, ChangeRecord[]> = new Map()\r\n\r\n\t/**\r\n\t * Record a store change for debugging.\r\n\t */\r\n\trecordChange(change: ChangeRecord): void {\r\n\t\tconst changes = this.#storeChanges.get(change.storeId) ?? []\r\n\t\tchanges.push(change)\r\n\t\tthis.#storeChanges.set(change.storeId, changes)\r\n\t}\r\n\r\n\tgetLogLevel(): LogLevel {\r\n\t\treturn this.#logLevel\r\n\t}\r\n\r\n\tsetLogLevel(level: LogLevel): void {\r\n\t\tthis.#logLevel = level\r\n\t}\r\n\r\n\tlog(level: LogLevel, message: string, data?: Record<string, unknown>): void {\r\n\t\tconst entry: DebugLogEntry = {\r\n\t\t\tid: crypto.randomUUID(),\r\n\t\t\ttimestamp: Date.now(),\r\n\t\t\tlevel,\r\n\t\t\tsource: 'game',\r\n\t\t\tmessage,\r\n\t\t\t...(data !== undefined && { data }),\r\n\t\t}\r\n\t\tthis.#logs.push(entry)\r\n\r\n\t\t// Keep only recent logs\r\n\t\tif (this.#logs.length > this.#maxLogs) {\r\n\t\t\tthis.#logs.shift()\r\n\t\t}\r\n\r\n\t\t// Console output\r\n\t\tconsole[level](message, data)\r\n\t}\r\n\r\n\tdebug(message: string, data?: Record<string, unknown>): void {\r\n\t\tif (this.#logLevel === 'debug') {\r\n\t\t\tthis.log('debug', message, data)\r\n\t\t}\r\n\t}\r\n\r\n\tinfo(message: string, data?: Record<string, unknown>): void {\r\n\t\tif (this.#logLevel === 'debug' || this.#logLevel === 'info') {\r\n\t\t\tthis.log('info', message, data)\r\n\t\t}\r\n\t}\r\n\r\n\twarn(message: string, data?: Record<string, unknown>): void {\r\n\t\tif (this.#logLevel !== 'error') {\r\n\t\t\tthis.log('warn', message, data)\r\n\t\t}\r\n\t}\r\n\r\n\terror(message: string, data?: Record<string, unknown>): void {\r\n\t\tthis.log('error', message, data)\r\n\t}\r\n\r\n\tgetLogs(level?: LogLevel, limit?: number): readonly DebugLogEntry[] {\r\n\t\tlet filtered = level ? this.#logs.filter(log => log.level === level) : this.#logs\r\n\t\tif (limit) {\r\n\t\t\tfiltered = filtered.slice(-limit)\r\n\t\t}\r\n\t\treturn filtered\r\n\t}\r\n\r\n\tclearLogs(): void {\r\n\t\tthis.#logs.length = 0\r\n\t}\r\n\r\n\tasync exportLogs(): Promise<string> {\r\n\t\treturn JSON.stringify(this.#logs, null, 2)\r\n\t}\r\n\r\n\tstartTrace(operation: string): string {\r\n\t\tconst traceId = crypto.randomUUID()\r\n\t\tconst trace: PerformanceTrace = {\r\n\t\t\toperation,\r\n\t\t\tstartTime: Date.now(),\r\n\t\t\tendTime: 0,\r\n\t\t\tduration: 0,\r\n\t\t\tsuccess: false,\r\n\t\t}\r\n\t\tthis.#traces.set(traceId, trace)\r\n\t\treturn traceId\r\n\t}\r\n\r\n\tendTrace(traceId: string, success: boolean, metadata?: Record<string, unknown>): void {\r\n\t\tconst trace = this.#traces.get(traceId)\r\n\t\tif (!trace) return\r\n\r\n\t\tconst endTime = Date.now()\r\n\t\tconst updatedTrace = {\r\n\t\t\t...trace,\r\n\t\t\tendTime,\r\n\t\t\tduration: endTime - trace.startTime,\r\n\t\t\tsuccess,\r\n\t\t\t...(metadata !== undefined && { metadata }),\r\n\t\t}\r\n\t\tthis.#traces.set(traceId, updatedTrace)\r\n\t}\r\n\r\n\tgetTraces(operation?: string): readonly PerformanceTrace[] {\r\n\t\tconst traces = Array.from(this.#traces.values())\r\n\t\tif (operation) {\r\n\t\t\treturn traces.filter(t => t.operation === operation)\r\n\t\t}\r\n\t\treturn traces\r\n\t}\r\n\r\n\tasync getDiagnostics(): Promise<StorageDiagnostics> {\r\n\t\t// Calculate diagnostics from collected traces\r\n\t\tconst traces = Array.from(this.#traces.values())\r\n\t\tconst completedTraces = traces.filter(t => t.duration !== undefined && t.duration > 0)\r\n\r\n\t\tlet totalQueryTime = 0\r\n\t\tconst queryTimes: { operation: string; duration: number }[] = []\r\n\r\n\t\tfor (const trace of completedTraces) {\r\n\t\t\tif (trace.duration) {\r\n\t\t\t\ttotalQueryTime += trace.duration\r\n\t\t\t\tqueryTimes.push({ operation: trace.operation, duration: trace.duration })\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Sort to find slowest queries\r\n\t\tqueryTimes.sort((a, b) => b.duration - a.duration)\r\n\t\tconst slowestTraces = queryTimes.slice(0, 5)\r\n\t\t\t.map(q => completedTraces.find(t => t.operation === q.operation && t.duration === q.duration))\r\n\t\t\t.filter((t): t is PerformanceTrace => t !== undefined)\r\n\r\n\t\tconst errorTraces = traces.filter(t => !t.success)\r\n\t\tconst errorRate = traces.length > 0 ? errorTraces.length / traces.length : 0\r\n\r\n\t\t// Get recent error log entries\r\n\t\tconst recentErrorLogs = this.#logs\r\n\t\t\t.filter(log => log.level === 'error')\r\n\t\t\t.slice(-5)\r\n\r\n\t\treturn {\r\n\t\t\tdatabaseSize: 0, // Would need storage access to calculate\r\n\t\t\tfragmentationRatio: 0, // Would need IndexedDB inspection\r\n\t\t\taverageQueryTime: completedTraces.length > 0 ? totalQueryTime / completedTraces.length : 0,\r\n\t\t\tslowestQueries: slowestTraces,\r\n\t\t\terrorRate,\r\n\t\t\trecentErrors: recentErrorLogs,\r\n\t\t}\r\n\t}\r\n\r\n\tasync inspectStore(storeId: string): Promise<{\r\n\t\treadonly state: unknown\r\n\t\treadonly revision: number\r\n\t\treadonly isDirty: boolean\r\n\t\treadonly changes: readonly ChangeRecord[]\r\n\t}> {\r\n\t\tconst changes = this.#storeChanges.get(storeId) ?? []\r\n\t\tconst lastChange = changes.length > 0 ? changes[changes.length - 1] : undefined\r\n\r\n\t\treturn {\r\n\t\t\tstate: lastChange?.nextState ?? null,\r\n\t\t\trevision: changes.length,\r\n\t\t\tisDirty: false, // Would need store reference to check\r\n\t\t\tchanges,\r\n\t\t}\r\n\t}\r\n}\r\n","import type {\r\n\tSpriteSheetInterface,\r\n\tSpriteSheetOptions,\r\n\tSpriteFrame,\r\n\tSpriteAnimation,\r\n\tRectangle,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Sprite sheet for managing sprite frames and animations.\r\n */\r\nexport class SpriteSheet implements SpriteSheetInterface {\r\n\treadonly imageKey: string\r\n\treadonly frameWidth: number\r\n\treadonly frameHeight: number\r\n\r\n\t#frames: SpriteFrame[] = []\r\n\t#animations: Map<string, SpriteAnimation> = new Map()\r\n\t#columns: number\r\n\t#rows: number\r\n\t#margin: number\r\n\t#spacing: number\r\n\r\n\tconstructor(options: SpriteSheetOptions) {\r\n\t\tthis.imageKey = options.imageKey\r\n\t\tthis.frameWidth = options.frameWidth\r\n\t\tthis.frameHeight = options.frameHeight\r\n\t\tthis.#margin = options.margin ?? 0\r\n\t\tthis.#spacing = options.spacing ?? 0\r\n\t\tthis.#columns = options.columns ?? 0\r\n\t\tthis.#rows = options.rows ?? 0\r\n\r\n\t\t// Initialize frames\r\n\t\tif (options.frames && options.frames.length > 0) {\r\n\t\t\tthis.#frames = [...options.frames]\r\n\t\t} else {\r\n\t\t\t// Auto-generate frames based on grid\r\n\t\t\tthis.#generateFrames(options)\r\n\t\t}\r\n\r\n\t\t// Register animations\r\n\t\tif (options.animations) {\r\n\t\t\tfor (const anim of options.animations) {\r\n\t\t\t\tthis.#animations.set(anim.name, anim)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tgetFrameCount(): number {\r\n\t\treturn this.#frames.length\r\n\t}\r\n\r\n\tgetFrame(index: number): SpriteFrame | undefined {\r\n\t\tif (index < 0 || index >= this.#frames.length) {\r\n\t\t\treturn undefined\r\n\t\t}\r\n\t\treturn this.#frames[index]\r\n\t}\r\n\r\n\tgetFrameByName(name: string): SpriteFrame | undefined {\r\n\t\t// Lookup frame by name - frames can have optional names for direct access\r\n\t\treturn this.#frames.find(frame => frame.name === name)\r\n\t}\r\n\r\n\thasAnimation(name: string): boolean {\r\n\t\treturn this.#animations.has(name)\r\n\t}\r\n\r\n\tgetAnimation(name: string): SpriteAnimation | undefined {\r\n\t\treturn this.#animations.get(name)\r\n\t}\r\n\r\n\tgetAnimationNames(): readonly string[] {\r\n\t\treturn Array.from(this.#animations.keys())\r\n\t}\r\n\r\n\taddAnimation(animation: SpriteAnimation): void {\r\n\t\tthis.#animations.set(animation.name, animation)\r\n\t}\r\n\r\n\tremoveAnimation(name: string): void {\r\n\t\tthis.#animations.delete(name)\r\n\t}\r\n\r\n\tgetSourceRectangle(frameIndex: number): Rectangle {\r\n\t\tconst frame = this.getFrame(frameIndex)\r\n\t\tif (frame) {\r\n\t\t\treturn {\r\n\t\t\t\tx: frame.x,\r\n\t\t\t\ty: frame.y,\r\n\t\t\t\twidth: frame.width,\r\n\t\t\t\theight: frame.height,\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Calculate from grid if no explicit frame\r\n\t\tif (this.#columns > 0) {\r\n\t\t\tconst col = frameIndex % this.#columns\r\n\t\t\tconst row = Math.floor(frameIndex / this.#columns)\r\n\t\t\treturn {\r\n\t\t\t\tx: this.#margin + col * (this.frameWidth + this.#spacing),\r\n\t\t\t\ty: this.#margin + row * (this.frameHeight + this.#spacing),\r\n\t\t\t\twidth: this.frameWidth,\r\n\t\t\t\theight: this.frameHeight,\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn { x: 0, y: 0, width: this.frameWidth, height: this.frameHeight }\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#frames.length = 0\r\n\t\tthis.#animations.clear()\r\n\t}\r\n\r\n\t#generateFrames(options: SpriteSheetOptions): void {\r\n\t\tconst startFrame = options.startFrame ?? 0\r\n\t\tconst endFrame = options.endFrame ?? -1\r\n\r\n\t\tif (this.#columns > 0 && this.#rows > 0) {\r\n\t\t\tconst totalFrames = this.#columns * this.#rows\r\n\t\t\tconst actualEnd = endFrame >= 0 ? Math.min(endFrame, totalFrames - 1) : totalFrames - 1\r\n\r\n\t\t\tfor (let i = startFrame; i <= actualEnd; i++) {\r\n\t\t\t\tconst col = i % this.#columns\r\n\t\t\t\tconst row = Math.floor(i / this.#columns)\r\n\t\t\t\tthis.#frames.push({\r\n\t\t\t\t\tx: this.#margin + col * (this.frameWidth + this.#spacing),\r\n\t\t\t\t\ty: this.#margin + row * (this.frameHeight + this.#spacing),\r\n\t\t\t\t\twidth: this.frameWidth,\r\n\t\t\t\t\theight: this.frameHeight,\r\n\t\t\t\t})\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}\r\n","import type {\r\n\tAnimationPlayerInterface,\r\n\tAnimationPlayerOptions,\r\n\tAnimationState,\r\n\tSpriteSheetOptions,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Animation player for sprite sheet animations.\r\n */\r\nexport class AnimationPlayer implements AnimationPlayerInterface {\r\n\t#spriteSheet: SpriteSheetOptions\r\n\t#currentAnimation: string\r\n\t#currentFrame = 0\r\n\t#isPlaying = false\r\n\t#isPaused = false\r\n\t#elapsedTime = 0\r\n\t#speed = 1\r\n\r\n\t#listeners = {\r\n\t\tanimationStart: new Set<(name: string) => void>(),\r\n\t\tanimationComplete: new Set<(name: string) => void>(),\r\n\t\tanimationLoop: new Set<(name: string) => void>(),\r\n\t\tframeChange: new Set<(frame: number) => void>(),\r\n\t}\r\n\r\n\tconstructor(options: AnimationPlayerOptions) {\r\n\t\tthis.#spriteSheet = options.spriteSheet\r\n\t\tthis.#currentAnimation = options.defaultAnimation ?? ''\r\n\r\n\t\t// Register hooks from options\r\n\t\tif (options.onAnimationStart) this.#listeners.animationStart.add(options.onAnimationStart)\r\n\t\tif (options.onAnimationComplete) this.#listeners.animationComplete.add(options.onAnimationComplete)\r\n\t\tif (options.onAnimationLoop) this.#listeners.animationLoop.add(options.onAnimationLoop)\r\n\t\tif (options.onFrameChange) this.#listeners.frameChange.add(options.onFrameChange)\r\n\r\n\t\t// Auto play if enabled\r\n\t\tif (options.autoPlay && this.#currentAnimation) {\r\n\t\t\tthis.play(this.#currentAnimation)\r\n\t\t}\r\n\t}\r\n\r\n\tgetState(): AnimationState {\r\n\t\tconst animations = this.#spriteSheet.animations ?? []\r\n\t\tconst animation = animations.find(a => a.name === this.#currentAnimation)\r\n\t\tconst frameCount = animation?.frames.length ?? 1\r\n\t\tconst frameRate = animation?.frameRate ?? 10\r\n\t\tconst duration = (frameCount * 1000) / frameRate\r\n\t\tconst progress = duration > 0 ? Math.min(1, this.#elapsedTime / duration) : 0\r\n\r\n\t\treturn {\r\n\t\t\tcurrentAnimation: this.#currentAnimation,\r\n\t\t\tcurrentFrame: this.#currentFrame,\r\n\t\t\tframeIndex: this.#currentFrame,\r\n\t\t\tisPlaying: this.#isPlaying,\r\n\t\t\tisPaused: this.#isPaused,\r\n\t\t\telapsedTime: this.#elapsedTime,\r\n\t\t\tduration,\r\n\t\t\tprogress,\r\n\t\t\tloop: animation?.loop !== false,\r\n\t\t\tspeed: this.#speed,\r\n\t\t}\r\n\t}\r\n\r\n\tgetSpriteSheet(): SpriteSheetOptions {\r\n\t\treturn this.#spriteSheet\r\n\t}\r\n\r\n\tgetCurrentAnimation(): string {\r\n\t\treturn this.#currentAnimation\r\n\t}\r\n\r\n\tgetCurrentFrame(): number {\r\n\t\treturn this.#currentFrame\r\n\t}\r\n\r\n\tisPlaying(): boolean {\r\n\t\treturn this.#isPlaying\r\n\t}\r\n\r\n\tisPaused(): boolean {\r\n\t\treturn this.#isPaused\r\n\t}\r\n\r\n\tplay(animationName: string): void {\r\n\t\tthis.#currentAnimation = animationName\r\n\t\tthis.#isPlaying = true\r\n\t\tthis.#isPaused = false\r\n\t\tthis.#listeners.animationStart.forEach(cb => cb(animationName))\r\n\t}\r\n\r\n\tpause(): void {\r\n\t\tthis.#isPaused = true\r\n\t}\r\n\r\n\tresume(): void {\r\n\t\tthis.#isPaused = false\r\n\t}\r\n\r\n\tstop(): void {\r\n\t\tthis.#isPlaying = false\r\n\t\tthis.#isPaused = false\r\n\t\tthis.#currentFrame = 0\r\n\t\tthis.#elapsedTime = 0\r\n\t}\r\n\r\n\treset(): void {\r\n\t\tthis.#currentFrame = 0\r\n\t\tthis.#elapsedTime = 0\r\n\t}\r\n\r\n\tsetFrame(frame: number): void {\r\n\t\tthis.#currentFrame = frame\r\n\t\tthis.#listeners.frameChange.forEach(cb => cb(frame))\r\n\t}\r\n\r\n\tsetSpeed(speed: number): void {\r\n\t\tthis.#speed = speed\r\n\t}\r\n\r\n\tgetSpeed(): number {\r\n\t\treturn this.#speed\r\n\t}\r\n\r\n\tupdate(deltaTime: number): void {\r\n\t\tif (!this.#isPlaying || this.#isPaused) return\r\n\r\n\t\tthis.#elapsedTime += deltaTime * this.#speed\r\n\r\n\t\t// Find current animation\r\n\t\tconst animations = this.#spriteSheet.animations ?? []\r\n\t\tconst animation = animations.find(a => a.name === this.#currentAnimation)\r\n\t\tif (!animation) return\r\n\r\n\t\tconst frameDuration = 1000 / (animation.frameRate ?? 10)\r\n\t\tconst frameCount = animation.frames.length\r\n\r\n\t\t// Calculate new frame\r\n\t\tconst newFrame = Math.floor(this.#elapsedTime / frameDuration) % frameCount\r\n\r\n\t\tif (newFrame !== this.#currentFrame) {\r\n\t\t\tconst oldFrame = this.#currentFrame\r\n\t\t\tthis.#currentFrame = newFrame\r\n\t\t\tthis.#listeners.frameChange.forEach(cb => cb(this.#currentFrame))\r\n\r\n\t\t\t// Check for loop\r\n\t\t\tif (newFrame < oldFrame && animation.loop !== false) {\r\n\t\t\t\tthis.#listeners.animationLoop.forEach(cb => cb(this.#currentAnimation))\r\n\t\t\t}\r\n\r\n\t\t\t// Check for completion\r\n\t\t\tif (newFrame === frameCount - 1 && !animation.loop) {\r\n\t\t\t\tthis.#isPlaying = false\r\n\t\t\t\tthis.#listeners.animationComplete.forEach(cb => cb(this.#currentAnimation))\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tonAnimationStart(callback: (name: string) => void): Unsubscribe {\r\n\t\tthis.#listeners.animationStart.add(callback)\r\n\t\treturn () => this.#listeners.animationStart.delete(callback)\r\n\t}\r\n\r\n\tonAnimationComplete(callback: (name: string) => void): Unsubscribe {\r\n\t\tthis.#listeners.animationComplete.add(callback)\r\n\t\treturn () => this.#listeners.animationComplete.delete(callback)\r\n\t}\r\n\r\n\tonAnimationLoop(callback: (name: string) => void): Unsubscribe {\r\n\t\tthis.#listeners.animationLoop.add(callback)\r\n\t\treturn () => this.#listeners.animationLoop.delete(callback)\r\n\t}\r\n\r\n\tonFrameChange(callback: (frame: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.frameChange.add(callback)\r\n\t\treturn () => this.#listeners.frameChange.delete(callback)\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#listeners.animationStart.clear()\r\n\t\tthis.#listeners.animationComplete.clear()\r\n\t\tthis.#listeners.animationLoop.clear()\r\n\t\tthis.#listeners.frameChange.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tRendererInterface,\r\n\tRenderOptions,\r\n\tRenderStats,\r\n\tRenderLayer,\r\n\tEntityInterface,\r\n\tCameraInterface,\r\n} from '../../types.js'\r\n\r\ninterface MutableStats {\r\n\tdrawCalls: number\r\n\tbatchedDrawCalls: number\r\n\ttriangles: number\r\n\tentitiesRendered: number\r\n\tentitiesCulled: number\r\n\tlayersRendered: number\r\n}\r\n\r\n/**\r\n * Renderer for managing render pipeline.\r\n */\r\nexport class Renderer implements RendererInterface {\r\n\t#context: CanvasRenderingContext2D\r\n\t#options: RenderOptions\r\n\t#layers: Map<string, RenderLayer> = new Map()\r\n\t#stats: MutableStats\r\n\r\n\tconstructor(context: CanvasRenderingContext2D, options?: Partial<RenderOptions>) {\r\n\t\tthis.#context = context\r\n\t\tthis.#options = {\r\n\t\t\tenableBatching: options?.enableBatching ?? true,\r\n\t\t\tenableCulling: options?.enableCulling ?? true,\r\n\t\t\tcullingStrategy: options?.cullingStrategy ?? 'frustum',\r\n\t\t\tmaxBatchSize: options?.maxBatchSize ?? 1000,\r\n\t\t\tsortLayers: options?.sortLayers ?? true,\r\n\t\t}\r\n\t\tthis.#stats = {\r\n\t\t\tdrawCalls: 0,\r\n\t\t\tbatchedDrawCalls: 0,\r\n\t\t\ttriangles: 0,\r\n\t\t\tentitiesRendered: 0,\r\n\t\t\tentitiesCulled: 0,\r\n\t\t\tlayersRendered: 0,\r\n\t\t}\r\n\t}\r\n\r\n\tgetContext(): CanvasRenderingContext2D {\r\n\t\treturn this.#context\r\n\t}\r\n\r\n\tgetOptions(): RenderOptions {\r\n\t\treturn this.#options\r\n\t}\r\n\r\n\tgetStats(): RenderStats {\r\n\t\treturn this.#stats\r\n\t}\r\n\r\n\taddLayer(layer: RenderLayer): void {\r\n\t\tthis.#layers.set(layer.name, layer)\r\n\t}\r\n\r\n\tremoveLayer(name: string): void {\r\n\t\tthis.#layers.delete(name)\r\n\t}\r\n\r\n\tgetLayer(name: string): RenderLayer | undefined {\r\n\t\treturn this.#layers.get(name)\r\n\t}\r\n\r\n\tsetLayerVisible(name: string, visible: boolean): void {\r\n\t\tconst layer = this.#layers.get(name)\r\n\t\tif (layer) {\r\n\t\t\tthis.#layers.set(name, { ...layer, visible })\r\n\t\t}\r\n\t}\r\n\r\n\tsetLayerOpacity(name: string, opacity: number): void {\r\n\t\tconst layer = this.#layers.get(name)\r\n\t\tif (layer) {\r\n\t\t\tthis.#layers.set(name, { ...layer, opacity })\r\n\t\t}\r\n\t}\r\n\r\n\trender(entities: readonly EntityInterface[], camera: CameraInterface): void {\r\n\t\t// Reset stats\r\n\t\tthis.resetStats()\r\n\r\n\t\t// Get sorted layers\r\n\t\tconst sortedLayers = Array.from(this.#layers.values())\r\n\t\t\t.filter(l => l.visible)\r\n\t\t\t.sort((a, b) => a.zIndex - b.zIndex)\r\n\r\n\t\t// Apply camera transform\r\n\t\tthis.#context.save()\r\n\t\tconst state = camera.getState()\r\n\t\tthis.#context.translate(state.width / 2, state.height / 2)\r\n\t\tthis.#context.scale(state.zoom, state.zoom)\r\n\t\tthis.#context.rotate(state.rotation)\r\n\t\tthis.#context.translate(-state.x, -state.y)\r\n\r\n\t\t// Filter and cull entities\r\n\t\tlet entitiesToRender = [...entities]\r\n\t\tif (this.#options.enableCulling) {\r\n\t\t\tentitiesToRender = entitiesToRender.filter(e => {\r\n\t\t\t\tif (camera.contains(e)) {\r\n\t\t\t\t\treturn true\r\n\t\t\t\t}\r\n\t\t\t\tthis.#stats.entitiesCulled++\r\n\t\t\t\treturn false\r\n\t\t\t})\r\n\t\t}\r\n\r\n\t\t// Sort by z-index\r\n\t\tentitiesToRender.sort((a, b) => a.getZIndex() - b.getZIndex())\r\n\r\n\t\t// Render layers first\r\n\t\tfor (const layer of sortedLayers) {\r\n\t\t\tif (layer.opacity < 1) {\r\n\t\t\t\tthis.#context.globalAlpha = layer.opacity\r\n\t\t\t}\r\n\t\t\t// Layer rendering would go here\r\n\t\t\tthis.#stats.layersRendered++\r\n\t\t\tthis.#context.globalAlpha = 1\r\n\t\t}\r\n\r\n\t\t// Render entities\r\n\t\tfor (const entity of entitiesToRender) {\r\n\t\t\tif (!entity.isVisible()) continue\r\n\r\n\t\t\tif ('render' in entity && typeof entity.render === 'function') {\r\n\t\t\t\t(entity as { render(ctx: CanvasRenderingContext2D): void }).render(this.#context)\r\n\t\t\t\tthis.#stats.entitiesRendered++\r\n\t\t\t\tthis.#stats.drawCalls++\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tthis.#context.restore()\r\n\t}\r\n\r\n\tclear(color?: string): void {\r\n\t\tif (color) {\r\n\t\t\tthis.#context.fillStyle = color\r\n\t\t\tthis.#context.fillRect(0, 0, this.#context.canvas.width, this.#context.canvas.height)\r\n\t\t} else {\r\n\t\t\tthis.#context.clearRect(0, 0, this.#context.canvas.width, this.#context.canvas.height)\r\n\t\t}\r\n\t}\r\n\r\n\tresetStats(): void {\r\n\t\tthis.#stats = {\r\n\t\t\tdrawCalls: 0,\r\n\t\t\tbatchedDrawCalls: 0,\r\n\t\t\ttriangles: 0,\r\n\t\t\tentitiesRendered: 0,\r\n\t\t\tentitiesCulled: 0,\r\n\t\t\tlayersRendered: 0,\r\n\t\t}\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#layers.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tViewportInterface,\r\n\tViewportOptions,\r\n\tScreenState,\r\n\tScreenOrientation,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Viewport manager for screen and fullscreen management.\r\n */\r\nexport class Viewport implements ViewportInterface {\r\n\t#width: number\r\n\t#height: number\r\n\t#scaleMode: 'fit' | 'fill' | 'stretch' | 'none'\r\n\t#pixelRatio: number\r\n\t#targetElement: HTMLElement | null = null\r\n\t#resizeObserver: ResizeObserver | null = null\r\n\t#lastOrientation: ScreenOrientation\r\n\r\n\t#listeners = {\r\n\t\tresize: new Set<(width: number, height: number) => void>(),\r\n\t\torientationChange: new Set<(orientation: ScreenOrientation) => void>(),\r\n\t\tfullscreenChange: new Set<(isFullscreen: boolean) => void>(),\r\n\t}\r\n\r\n\t// Bound handlers for cleanup\r\n\t#boundFullscreenChange: () => void\r\n\t#boundWindowResize: () => void\r\n\r\n\tconstructor(options: ViewportOptions) {\r\n\t\tthis.#width = options.width\r\n\t\tthis.#height = options.height\r\n\t\tthis.#scaleMode = options.scaleMode ?? 'fit'\r\n\t\tthis.#pixelRatio = window.devicePixelRatio\r\n\t\tthis.#lastOrientation = this.getOrientation()\r\n\r\n\t\t// Register hooks from options\r\n\t\tif (options.onResize) this.#listeners.resize.add(options.onResize)\r\n\t\tif (options.onOrientationChange) this.#listeners.orientationChange.add(options.onOrientationChange)\r\n\t\tif (options.onFullscreenChange) this.#listeners.fullscreenChange.add(options.onFullscreenChange)\r\n\r\n\t\t// Bind handlers\r\n\t\tthis.#boundFullscreenChange = this.#handleFullscreenChange.bind(this)\r\n\t\tthis.#boundWindowResize = this.#handleWindowResize.bind(this)\r\n\r\n\t\t// Setup resize observers and event listeners\r\n\t\tdocument.addEventListener('fullscreenchange', this.#boundFullscreenChange)\r\n\t\twindow.addEventListener('resize', this.#boundWindowResize)\r\n\r\n\t\t// Setup ResizeObserver if target element is provided\r\n\t\tif (options.targetElement) {\r\n\t\t\tthis.#targetElement = options.targetElement\r\n\t\t\tthis.#resizeObserver = new ResizeObserver((entries) => {\r\n\t\t\t\tconst entry = entries[0]\r\n\t\t\t\tif (entry) {\r\n\t\t\t\t\tconst { width, height } = entry.contentRect\r\n\t\t\t\t\tthis.resize(width, height)\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t\t\tthis.#resizeObserver.observe(this.#targetElement)\r\n\t\t}\r\n\t}\r\n\r\n\t#handleFullscreenChange(): void {\r\n\t\tthis.#listeners.fullscreenChange.forEach(cb => cb(this.isFullscreen()))\r\n\t}\r\n\r\n\t#handleWindowResize(): void {\r\n\t\tconst newOrientation = this.getOrientation()\r\n\t\tif (newOrientation !== this.#lastOrientation) {\r\n\t\t\tthis.#lastOrientation = newOrientation\r\n\t\t\tthis.#listeners.orientationChange.forEach(cb => cb(newOrientation))\r\n\t\t}\r\n\t}\r\n\r\n\tgetState(): ScreenState {\r\n\t\treturn {\r\n\t\t\twidth: this.#width,\r\n\t\t\theight: this.#height,\r\n\t\t\torientation: this.getOrientation(),\r\n\t\t\tpixelRatio: this.#pixelRatio,\r\n\t\t\tisFullscreen: this.isFullscreen(),\r\n\t\t\tisMobile: this.isMobile(),\r\n\t\t\tisTouch: this.isTouch(),\r\n\t\t}\r\n\t}\r\n\r\n\tgetWidth(): number {\r\n\t\treturn this.#width\r\n\t}\r\n\r\n\tgetHeight(): number {\r\n\t\treturn this.#height\r\n\t}\r\n\r\n\tgetScaleFactor(): number {\r\n\t\t// Calculate scale factor based on scale mode\r\n\t\tconst containerWidth = this.#targetElement?.clientWidth ?? window.innerWidth\r\n\t\tconst containerHeight = this.#targetElement?.clientHeight ?? window.innerHeight\r\n\r\n\t\tswitch (this.#scaleMode) {\r\n\t\t\tcase 'fit': {\r\n\t\t\t\t// Scale to fit within container, maintaining aspect ratio\r\n\t\t\t\tconst scaleX = containerWidth / this.#width\r\n\t\t\t\tconst scaleY = containerHeight / this.#height\r\n\t\t\t\treturn Math.min(scaleX, scaleY)\r\n\t\t\t}\r\n\t\t\tcase 'fill': {\r\n\t\t\t\t// Scale to fill container, maintaining aspect ratio (may crop)\r\n\t\t\t\tconst scaleX = containerWidth / this.#width\r\n\t\t\t\tconst scaleY = containerHeight / this.#height\r\n\t\t\t\treturn Math.max(scaleX, scaleY)\r\n\t\t\t}\r\n\t\t\tcase 'stretch':\r\n\t\t\t\t// Don't maintain aspect ratio - return average of both scales\r\n\t\t\t\treturn (containerWidth / this.#width + containerHeight / this.#height) / 2\r\n\t\t\tcase 'none':\r\n\t\t\tdefault:\r\n\t\t\t\treturn 1\r\n\t\t}\r\n\t}\r\n\r\n\tgetOrientation(): ScreenOrientation {\r\n\t\treturn window.innerWidth > window.innerHeight ? 'landscape' : 'portrait'\r\n\t}\r\n\r\n\tisFullscreen(): boolean {\r\n\t\treturn document.fullscreenElement !== null\r\n\t}\r\n\r\n\tisMobile(): boolean {\r\n\t\treturn /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)\r\n\t}\r\n\r\n\tisTouch(): boolean {\r\n\t\treturn 'ontouchstart' in window\r\n\t}\r\n\r\n\tresize(width: number, height: number): void {\r\n\t\tthis.#width = width\r\n\t\tthis.#height = height\r\n\t\tthis.#listeners.resize.forEach(cb => cb(width, height))\r\n\t}\r\n\r\n\tasync requestFullscreen(): Promise<void> {\r\n\t\tif (document.documentElement.requestFullscreen) {\r\n\t\t\tawait document.documentElement.requestFullscreen()\r\n\t\t\tthis.#listeners.fullscreenChange.forEach(cb => cb(true))\r\n\t\t}\r\n\t}\r\n\r\n\tasync exitFullscreen(): Promise<void> {\r\n\t\tif (document.exitFullscreen) {\r\n\t\t\tawait document.exitFullscreen()\r\n\t\t\tthis.#listeners.fullscreenChange.forEach(cb => cb(false))\r\n\t\t}\r\n\t}\r\n\r\n\tasync toggleFullscreen(): Promise<void> {\r\n\t\tif (this.isFullscreen()) {\r\n\t\t\tawait this.exitFullscreen()\r\n\t\t} else {\r\n\t\t\tawait this.requestFullscreen()\r\n\t\t}\r\n\t}\r\n\r\n\tonResize(callback: (width: number, height: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.resize.add(callback)\r\n\t\treturn () => this.#listeners.resize.delete(callback)\r\n\t}\r\n\r\n\tonOrientationChange(callback: (orientation: ScreenOrientation) => void): Unsubscribe {\r\n\t\tthis.#listeners.orientationChange.add(callback)\r\n\t\treturn () => this.#listeners.orientationChange.delete(callback)\r\n\t}\r\n\r\n\tonFullscreenChange(callback: (isFullscreen: boolean) => void): Unsubscribe {\r\n\t\tthis.#listeners.fullscreenChange.add(callback)\r\n\t\treturn () => this.#listeners.fullscreenChange.delete(callback)\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\t// Remove event listeners\r\n\t\tdocument.removeEventListener('fullscreenchange', this.#boundFullscreenChange)\r\n\t\twindow.removeEventListener('resize', this.#boundWindowResize)\r\n\r\n\t\t// Disconnect resize observer\r\n\t\tif (this.#resizeObserver) {\r\n\t\t\tthis.#resizeObserver.disconnect()\r\n\t\t\tthis.#resizeObserver = null\r\n\t\t}\r\n\r\n\t\t// Clear listener sets\r\n\t\tthis.#listeners.resize.clear()\r\n\t\tthis.#listeners.orientationChange.clear()\r\n\t\tthis.#listeners.fullscreenChange.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tTilesetInterface,\r\n\tTilesetOptions,\r\n\tTileCollision,\r\n\tRectangle,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Tileset for managing tile graphics and properties.\r\n */\r\nexport class Tileset implements TilesetInterface {\r\n\treadonly name: string\r\n\treadonly imageKey: string\r\n\treadonly tileWidth: number\r\n\treadonly tileHeight: number\r\n\treadonly firstGid: number\r\n\r\n\t#tileCount: number\r\n\t#columns: number\r\n\t#margin: number\r\n\t#spacing: number\r\n\t#tileProperties: Map<number, Record<string, unknown>> = new Map()\r\n\t#tileCollisions: Map<number, TileCollision> = new Map()\r\n\r\n\tconstructor(options: TilesetOptions) {\r\n\t\tthis.name = options.name\r\n\t\tthis.imageKey = options.imageKey\r\n\t\tthis.tileWidth = options.tileWidth\r\n\t\tthis.tileHeight = options.tileHeight\r\n\t\tthis.firstGid = options.firstGid\r\n\t\tthis.#tileCount = options.tileCount ?? 0\r\n\t\tthis.#columns = options.columns ?? 0\r\n\t\tthis.#margin = options.margin ?? 0\r\n\t\tthis.#spacing = options.spacing ?? 0\r\n\r\n\t\t// Load tile properties\r\n\t\tif (options.tileProperties) {\r\n\t\t\tfor (const [id, props] of Object.entries(options.tileProperties)) {\r\n\t\t\t\tthis.#tileProperties.set(Number(id), props)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Load tile collisions\r\n\t\tif (options.tileCollisions) {\r\n\t\t\tfor (const [id, collision] of Object.entries(options.tileCollisions)) {\r\n\t\t\t\tthis.#tileCollisions.set(Number(id), collision)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tgetTileCount(): number {\r\n\t\treturn this.#tileCount\r\n\t}\r\n\r\n\tgetColumns(): number {\r\n\t\treturn this.#columns\r\n\t}\r\n\r\n\tcontainsGid(gid: number): boolean {\r\n\t\tconst localId = gid - this.firstGid\r\n\t\treturn localId >= 0 && localId < this.#tileCount\r\n\t}\r\n\r\n\tgetLocalId(gid: number): number {\r\n\t\treturn gid - this.firstGid\r\n\t}\r\n\r\n\tgetSourceRectangle(localId: number): Rectangle {\r\n\t\tif (this.#columns <= 0) {\r\n\t\t\treturn { x: 0, y: 0, width: this.tileWidth, height: this.tileHeight }\r\n\t\t}\r\n\r\n\t\tconst col = localId % this.#columns\r\n\t\tconst row = Math.floor(localId / this.#columns)\r\n\r\n\t\treturn {\r\n\t\t\tx: this.#margin + col * (this.tileWidth + this.#spacing),\r\n\t\t\ty: this.#margin + row * (this.tileHeight + this.#spacing),\r\n\t\t\twidth: this.tileWidth,\r\n\t\t\theight: this.tileHeight,\r\n\t\t}\r\n\t}\r\n\r\n\tgetTileProperties(localId: number): Record<string, unknown> | undefined {\r\n\t\treturn this.#tileProperties.get(localId)\r\n\t}\r\n\r\n\tgetTileCollision(localId: number): TileCollision | undefined {\r\n\t\treturn this.#tileCollisions.get(localId)\r\n\t}\r\n}\r\n","import type {\r\n\tTilemapLayerInterface,\r\n\tTilemapLayerOptions,\r\n\tTileData,\r\n\tRectangle,\r\n\tCameraInterface,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Tilemap layer for managing a single layer of tiles.\r\n */\r\nexport class TilemapLayer implements TilemapLayerInterface {\r\n\treadonly name: string\r\n\treadonly width: number\r\n\treadonly height: number\r\n\r\n\t#tileWidth: number\r\n\t#tileHeight: number\r\n\t#data: number[]\r\n\t#visible: boolean\r\n\t#opacity: number\r\n\t#offsetX: number\r\n\t#offsetY: number\r\n\t#parallaxX: number\r\n\t#parallaxY: number\r\n\t#properties: Record<string, unknown>\r\n\r\n\tconstructor(options: TilemapLayerOptions) {\r\n\t\tthis.name = options.name\r\n\t\tthis.width = options.width\r\n\t\tthis.height = options.height\r\n\t\tthis.#tileWidth = options.tileWidth\r\n\t\tthis.#tileHeight = options.tileHeight\r\n\t\tthis.#data = [...options.data]\r\n\t\tthis.#visible = options.visible ?? true\r\n\t\tthis.#opacity = options.opacity ?? 1\r\n\t\tthis.#offsetX = options.offsetX ?? 0\r\n\t\tthis.#offsetY = options.offsetY ?? 0\r\n\t\tthis.#parallaxX = options.parallaxX ?? 1\r\n\t\tthis.#parallaxY = options.parallaxY ?? 1\r\n\t\tthis.#properties = options.properties ?? {}\r\n\t}\r\n\r\n\tisVisible(): boolean {\r\n\t\treturn this.#visible\r\n\t}\r\n\r\n\tsetVisible(visible: boolean): void {\r\n\t\tthis.#visible = visible\r\n\t}\r\n\r\n\tgetOpacity(): number {\r\n\t\treturn this.#opacity\r\n\t}\r\n\r\n\tsetOpacity(opacity: number): void {\r\n\t\tthis.#opacity = Math.max(0, Math.min(1, opacity))\r\n\t}\r\n\r\n\tgetTile(x: number, y: number): TileData | undefined {\r\n\t\tif (x < 0 || x >= this.width || y < 0 || y >= this.height) {\r\n\t\t\treturn undefined\r\n\t\t}\r\n\r\n\t\tconst index = y * this.width + x\r\n\t\tconst gid = this.#data[index]\r\n\t\tif (gid === undefined || gid === 0) {\r\n\t\t\treturn undefined\r\n\t\t}\r\n\r\n\t\t// Extract flip flags from gid (Tiled format)\r\n\t\tconst FLIPPED_HORIZONTALLY_FLAG = 0x80000000\r\n\t\tconst FLIPPED_VERTICALLY_FLAG = 0x40000000\r\n\t\tconst FLIPPED_DIAGONALLY_FLAG = 0x20000000\r\n\r\n\t\tconst flippedHorizontal = (gid & FLIPPED_HORIZONTALLY_FLAG) !== 0\r\n\t\tconst flippedVertical = (gid & FLIPPED_VERTICALLY_FLAG) !== 0\r\n\t\tconst flippedDiagonal = (gid & FLIPPED_DIAGONALLY_FLAG) !== 0\r\n\r\n\t\tconst actualGid = gid & ~(FLIPPED_HORIZONTALLY_FLAG | FLIPPED_VERTICALLY_FLAG | FLIPPED_DIAGONALLY_FLAG)\r\n\r\n\t\treturn {\r\n\t\t\tid: index,\r\n\t\t\tx,\r\n\t\t\ty,\r\n\t\t\tgid: actualGid,\r\n\t\t\tflippedHorizontal,\r\n\t\t\tflippedVertical,\r\n\t\t\tflippedDiagonal,\r\n\t\t}\r\n\t}\r\n\r\n\tgetTileAt(worldX: number, worldY: number): TileData | undefined {\r\n\t\tconst tileX = Math.floor((worldX - this.#offsetX) / this.#tileWidth)\r\n\t\tconst tileY = Math.floor((worldY - this.#offsetY) / this.#tileHeight)\r\n\t\treturn this.getTile(tileX, tileY)\r\n\t}\r\n\r\n\tsetTile(x: number, y: number, gid: number): void {\r\n\t\tif (x < 0 || x >= this.width || y < 0 || y >= this.height) {\r\n\t\t\treturn\r\n\t\t}\r\n\t\tconst index = y * this.width + x\r\n\t\tthis.#data[index] = gid\r\n\t}\r\n\r\n\tgetTilesInRectangle(rect: Rectangle): readonly TileData[] {\r\n\t\tconst tiles: TileData[] = []\r\n\r\n\t\tconst startX = Math.max(0, Math.floor((rect.x - this.#offsetX) / this.#tileWidth))\r\n\t\tconst startY = Math.max(0, Math.floor((rect.y - this.#offsetY) / this.#tileHeight))\r\n\t\tconst endX = Math.min(this.width - 1, Math.floor((rect.x + rect.width - this.#offsetX) / this.#tileWidth))\r\n\t\tconst endY = Math.min(this.height - 1, Math.floor((rect.y + rect.height - this.#offsetY) / this.#tileHeight))\r\n\r\n\t\tfor (let y = startY; y <= endY; y++) {\r\n\t\t\tfor (let x = startX; x <= endX; x++) {\r\n\t\t\t\tconst tile = this.getTile(x, y)\r\n\t\t\t\tif (tile) {\r\n\t\t\t\t\ttiles.push(tile)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn tiles\r\n\t}\r\n\r\n\tforEachTile(callback: (tile: TileData, x: number, y: number) => void): void {\r\n\t\tfor (let y = 0; y < this.height; y++) {\r\n\t\t\tfor (let x = 0; x < this.width; x++) {\r\n\t\t\t\tconst tile = this.getTile(x, y)\r\n\t\t\t\tif (tile) {\r\n\t\t\t\t\tcallback(tile, x, y)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\trender(context: CanvasRenderingContext2D, camera: CameraInterface): void {\r\n\t\tif (!this.#visible || this.#opacity <= 0) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\tcontext.save()\r\n\t\tcontext.globalAlpha = this.#opacity\r\n\r\n\t\t// Apply parallax scrolling based on camera position\r\n\t\tconst cameraX = camera.getX()\r\n\t\tconst cameraY = camera.getY()\r\n\t\tconst offsetX = (this.#offsetX - cameraX) * (1 - this.#parallaxX)\r\n\t\tconst offsetY = (this.#offsetY - cameraY) * (1 - this.#parallaxY)\r\n\r\n\t\t// Calculate visible tile range (culling)\r\n\t\tconst viewWidth = camera.getWidth()\r\n\t\tconst viewHeight = camera.getHeight()\r\n\t\tconst startX = Math.max(0, Math.floor((cameraX - offsetX) / this.#tileWidth))\r\n\t\tconst startY = Math.max(0, Math.floor((cameraY - offsetY) / this.#tileHeight))\r\n\t\tconst endX = Math.min(this.width, Math.ceil((cameraX + viewWidth - offsetX) / this.#tileWidth))\r\n\t\tconst endY = Math.min(this.height, Math.ceil((cameraY + viewHeight - offsetY) / this.#tileHeight))\r\n\r\n\t\t// Render visible tiles\r\n\t\tfor (let y = startY; y < endY; y++) {\r\n\t\t\tfor (let x = startX; x < endX; x++) {\r\n\t\t\t\tconst tile = this.getTile(x, y)\r\n\t\t\t\tif (tile && tile.id !== 0) {\r\n\t\t\t\t\tconst screenX = x * this.#tileWidth + offsetX - cameraX\r\n\t\t\t\t\tconst screenY = y * this.#tileHeight + offsetY - cameraY\r\n\r\n\t\t\t\t\t// Draw placeholder for tile (tileset rendering handled elsewhere)\r\n\t\t\t\t\tcontext.fillStyle = `hsl(${tile.id * 30 % 360}, 50%, 50%)`\r\n\t\t\t\t\tcontext.fillRect(screenX, screenY, this.#tileWidth, this.#tileHeight)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tcontext.restore()\r\n\t}\r\n}\r\n","import type {\r\n\tTilemapInterface,\r\n\tTilemapOptions,\r\n\tTilemapLayerOptions,\r\n\tTilemapLayerInterface,\r\n\tTileData,\r\n\tVector2,\r\n\tRectangle,\r\n\tCameraInterface,\r\n\tTilesetInterface,\r\n} from '../../types.js'\r\nimport { Tileset } from './Tileset.js'\r\nimport { TilemapLayer } from './TilemapLayer.js'\r\n\r\n/**\r\n * Tilemap for managing tile-based game worlds.\r\n */\r\nexport class Tilemap implements TilemapInterface {\r\n\treadonly width: number\r\n\treadonly height: number\r\n\treadonly tileWidth: number\r\n\treadonly tileHeight: number\r\n\r\n\t#tilesets: Tileset[] = []\r\n\t#layers: Map<string, TilemapLayer> = new Map()\r\n\t#layerOrder: string[] = []\r\n\t#properties: Record<string, unknown>\r\n\r\n\tconstructor(options: TilemapOptions) {\r\n\t\tthis.width = options.width\r\n\t\tthis.height = options.height\r\n\t\tthis.tileWidth = options.tileWidth\r\n\t\tthis.tileHeight = options.tileHeight\r\n\t\tthis.#properties = options.properties ?? {}\r\n\r\n\t\t// Create tilesets\r\n\t\tfor (const tilesetOpts of options.tilesets) {\r\n\t\t\tthis.#tilesets.push(new Tileset(tilesetOpts))\r\n\t\t}\r\n\r\n\t\t// Sort tilesets by firstGid (descending for lookup)\r\n\t\tthis.#tilesets.sort((a, b) => b.firstGid - a.firstGid)\r\n\r\n\t\t// Create layers\r\n\t\tfor (const layerOpts of options.layers) {\r\n\t\t\tconst layer = new TilemapLayer(layerOpts)\r\n\t\t\tthis.#layers.set(layer.name, layer)\r\n\t\t\tthis.#layerOrder.push(layer.name)\r\n\t\t}\r\n\t}\r\n\r\n\tgetWidthInPixels(): number {\r\n\t\treturn this.width * this.tileWidth\r\n\t}\r\n\r\n\tgetHeightInPixels(): number {\r\n\t\treturn this.height * this.tileHeight\r\n\t}\r\n\r\n\tgetTileset(name: string): TilesetInterface | undefined {\r\n\t\treturn this.#tilesets.find(ts => ts.name === name)\r\n\t}\r\n\r\n\tgetTilesetForGid(gid: number): TilesetInterface | undefined {\r\n\t\t// Tilesets are sorted by firstGid descending\r\n\t\tfor (const tileset of this.#tilesets) {\r\n\t\t\tif (tileset.containsGid(gid)) {\r\n\t\t\t\treturn tileset\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn undefined\r\n\t}\r\n\r\n\tgetTilesets(): readonly TilesetInterface[] {\r\n\t\treturn this.#tilesets\r\n\t}\r\n\r\n\tgetLayer(name: string): TilemapLayerInterface | undefined {\r\n\t\treturn this.#layers.get(name)\r\n\t}\r\n\r\n\tgetLayers(): readonly TilemapLayerInterface[] {\r\n\t\treturn this.#layerOrder.map(name => this.#layers.get(name)!).filter(Boolean)\r\n\t}\r\n\r\n\taddLayer(options: TilemapLayerOptions): TilemapLayerInterface {\r\n\t\tconst layer = new TilemapLayer(options)\r\n\t\tthis.#layers.set(layer.name, layer)\r\n\t\tthis.#layerOrder.push(layer.name)\r\n\t\treturn layer\r\n\t}\r\n\r\n\tremoveLayer(name: string): void {\r\n\t\tthis.#layers.delete(name)\r\n\t\tconst index = this.#layerOrder.indexOf(name)\r\n\t\tif (index >= 0) {\r\n\t\t\tthis.#layerOrder.splice(index, 1)\r\n\t\t}\r\n\t}\r\n\r\n\tworldToTile(worldX: number, worldY: number): Vector2 {\r\n\t\treturn {\r\n\t\t\tx: Math.floor(worldX / this.tileWidth),\r\n\t\t\ty: Math.floor(worldY / this.tileHeight),\r\n\t\t}\r\n\t}\r\n\r\n\ttileToWorld(tileX: number, tileY: number): Vector2 {\r\n\t\treturn {\r\n\t\t\tx: tileX * this.tileWidth,\r\n\t\t\ty: tileY * this.tileHeight,\r\n\t\t}\r\n\t}\r\n\r\n\tgetTileAt(worldX: number, worldY: number, layerName?: string): TileData | undefined {\r\n\t\tif (layerName) {\r\n\t\t\tconst layer = this.#layers.get(layerName)\r\n\t\t\treturn layer?.getTileAt(worldX, worldY)\r\n\t\t}\r\n\r\n\t\t// Search all layers from top to bottom\r\n\t\tfor (let i = this.#layerOrder.length - 1; i >= 0; i--) {\r\n\t\t\tconst layer = this.#layers.get(this.#layerOrder[i]!)\r\n\t\t\tif (layer) {\r\n\t\t\t\tconst tile = layer.getTileAt(worldX, worldY)\r\n\t\t\t\tif (tile) {\r\n\t\t\t\t\treturn tile\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn undefined\r\n\t}\r\n\r\n\tgetTilesInRectangle(rect: Rectangle, layerName?: string): readonly TileData[] {\r\n\t\tif (layerName) {\r\n\t\t\tconst layer = this.#layers.get(layerName)\r\n\t\t\treturn layer?.getTilesInRectangle(rect) ?? []\r\n\t\t}\r\n\r\n\t\tconst tiles: TileData[] = []\r\n\t\tfor (const name of this.#layerOrder) {\r\n\t\t\tconst layer = this.#layers.get(name)\r\n\t\t\tif (layer) {\r\n\t\t\t\ttiles.push(...layer.getTilesInRectangle(rect))\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn tiles\r\n\t}\r\n\r\n\trender(context: CanvasRenderingContext2D, camera: CameraInterface): void {\r\n\t\tfor (const name of this.#layerOrder) {\r\n\t\t\tconst layer = this.#layers.get(name)\r\n\t\t\tlayer?.render(context, camera)\r\n\t\t}\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#layers.clear()\r\n\t\tthis.#layerOrder.length = 0\r\n\t\tthis.#tilesets.length = 0\r\n\t}\r\n}\r\n","/**\r\n * LayerManager - Manages render layers for z-ordering and effects.\r\n *\r\n * Features:\r\n * - Named layers with z-order\r\n * - Per-layer visibility, opacity, blend mode\r\n * - Automatic sorting\r\n * - Camera-per-layer support (for parallax)\r\n */\r\nimport type {\r\n\tLayerManagerInterface,\r\n\tLayerManagerOptions,\r\n\tLayerConfig,\r\n\tLayerState,\r\n\tCameraInterface,\r\n\tEntityInterface,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\n/** Internal layer data */\r\ninterface LayerData {\r\n\tname: string\r\n\tzIndex: number\r\n\tvisible: boolean\r\n\topacity: number\r\n\tblendMode: GlobalCompositeOperation\r\n\tparallaxX: number\r\n\tparallaxY: number\r\n\tcamera: CameraInterface | undefined\r\n\tentities: Set<EntityInterface>\r\n}\r\n\r\n/**\r\n * Game layer manager implementation.\r\n */\r\nexport class LayerManager implements LayerManagerInterface {\r\n\treadonly #layers = new Map<string, LayerData>()\r\n\treadonly #sortedLayers: LayerData[] = []\r\n\treadonly #visibilityListeners = new Set<(name: string, visible: boolean) => void>()\r\n\treadonly #orderListeners = new Set<(layers: readonly string[]) => void>()\r\n\treadonly #defaultLayerName: string\r\n\r\n\tconstructor(options?: LayerManagerOptions) {\r\n\t\tthis.#defaultLayerName = options?.defaultLayerName ?? 'default'\r\n\r\n\t\tif (options?.onVisibilityChange) {\r\n\t\t\tthis.#visibilityListeners.add(options.onVisibilityChange)\r\n\t\t}\r\n\t\tif (options?.onOrderChange) {\r\n\t\t\tthis.#orderListeners.add(options.onOrderChange)\r\n\t\t}\r\n\r\n\t\t// Create default layer\r\n\t\tthis.createLayer({\r\n\t\t\tname: this.#defaultLayerName,\r\n\t\t\tzIndex: 0,\r\n\t\t})\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Layer Management\r\n\t// ============================================================================\r\n\r\n\tcreateLayer(config: LayerConfig): void {\r\n\t\tif (this.#layers.has(config.name)) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\tconst layer: LayerData = {\r\n\t\t\tname: config.name,\r\n\t\t\tzIndex: config.zIndex,\r\n\t\t\tvisible: config.visible ?? true,\r\n\t\t\topacity: config.opacity ?? 1,\r\n\t\t\tblendMode: config.blendMode ?? 'source-over',\r\n\t\t\tparallaxX: config.parallaxX ?? 1,\r\n\t\t\tparallaxY: config.parallaxY ?? 1,\r\n\t\t\tcamera: config.camera,\r\n\t\t\tentities: new Set(),\r\n\t\t}\r\n\r\n\t\tthis.#layers.set(config.name, layer)\r\n\t\tthis.#sortedLayers.push(layer)\r\n\t\tthis.#sortLayers()\r\n\t\tthis.#notifyOrderChange()\r\n\t}\r\n\r\n\tremoveLayer(name: string): void {\r\n\t\tif (name === this.#defaultLayerName) {\r\n\t\t\treturn // Cannot remove default layer\r\n\t\t}\r\n\r\n\t\tconst layer = this.#layers.get(name)\r\n\t\tif (!layer) return\r\n\r\n\t\t// Move entities to default layer\r\n\t\tconst defaultLayer = this.#layers.get(this.#defaultLayerName)\r\n\t\tif (defaultLayer) {\r\n\t\t\tfor (const entity of layer.entities) {\r\n\t\t\t\tdefaultLayer.entities.add(entity)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tthis.#layers.delete(name)\r\n\t\tconst index = this.#sortedLayers.indexOf(layer)\r\n\t\tif (index >= 0) {\r\n\t\t\tthis.#sortedLayers.splice(index, 1)\r\n\t\t}\r\n\t\tthis.#notifyOrderChange()\r\n\t}\r\n\r\n\tgetLayer(name: string): LayerState | undefined {\r\n\t\tconst layer = this.#layers.get(name)\r\n\t\tif (!layer) return undefined\r\n\r\n\t\treturn {\r\n\t\t\tname: layer.name,\r\n\t\t\tzIndex: layer.zIndex,\r\n\t\t\tvisible: layer.visible,\r\n\t\t\topacity: layer.opacity,\r\n\t\t\tblendMode: layer.blendMode,\r\n\t\t\tentityCount: layer.entities.size,\r\n\t\t}\r\n\t}\r\n\r\n\tgetLayers(): readonly LayerState[] {\r\n\t\treturn this.#sortedLayers.map((layer) => ({\r\n\t\t\tname: layer.name,\r\n\t\t\tzIndex: layer.zIndex,\r\n\t\t\tvisible: layer.visible,\r\n\t\t\topacity: layer.opacity,\r\n\t\t\tblendMode: layer.blendMode,\r\n\t\t\tentityCount: layer.entities.size,\r\n\t\t}))\r\n\t}\r\n\r\n\thasLayer(name: string): boolean {\r\n\t\treturn this.#layers.has(name)\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Layer Properties\r\n\t// ============================================================================\r\n\r\n\tsetVisible(name: string, visible: boolean): void {\r\n\t\tconst layer = this.#layers.get(name)\r\n\t\tif (!layer || layer.visible === visible) return\r\n\r\n\t\tlayer.visible = visible\r\n\t\tthis.#notifyVisibilityChange(name, visible)\r\n\t}\r\n\r\n\tsetOpacity(name: string, opacity: number): void {\r\n\t\tconst layer = this.#layers.get(name)\r\n\t\tif (!layer) return\r\n\r\n\t\tlayer.opacity = Math.max(0, Math.min(1, opacity))\r\n\t}\r\n\r\n\tsetZIndex(name: string, zIndex: number): void {\r\n\t\tconst layer = this.#layers.get(name)\r\n\t\tif (!layer) return\r\n\r\n\t\tlayer.zIndex = zIndex\r\n\t\tthis.#sortLayers()\r\n\t\tthis.#notifyOrderChange()\r\n\t}\r\n\r\n\tsetBlendMode(name: string, blendMode: GlobalCompositeOperation): void {\r\n\t\tconst layer = this.#layers.get(name)\r\n\t\tif (!layer) return\r\n\r\n\t\tlayer.blendMode = blendMode\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Entity Management\r\n\t// ============================================================================\r\n\r\n\taddToLayer(name: string, entity: EntityInterface): void {\r\n\t\tconst layer = this.#layers.get(name) ?? this.#layers.get(this.#defaultLayerName)\r\n\t\tif (!layer) return\r\n\r\n\t\tlayer.entities.add(entity)\r\n\t}\r\n\r\n\tremoveFromLayer(name: string, entity: EntityInterface): void {\r\n\t\tconst layer = this.#layers.get(name)\r\n\t\tif (!layer) return\r\n\r\n\t\tlayer.entities.delete(entity)\r\n\t}\r\n\r\n\tgetEntitiesInLayer(name: string): readonly EntityInterface[] {\r\n\t\tconst layer = this.#layers.get(name)\r\n\t\tif (!layer) return []\r\n\r\n\t\treturn Array.from(layer.entities)\r\n\t}\r\n\r\n\tmoveToLayer(entity: EntityInterface, fromLayer: string, toLayer: string): void {\r\n\t\tthis.removeFromLayer(fromLayer, entity)\r\n\t\tthis.addToLayer(toLayer, entity)\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Layer Ordering\r\n\t// ============================================================================\r\n\r\n\tbringToFront(name: string): void {\r\n\t\tconst layer = this.#layers.get(name)\r\n\t\tif (!layer) return\r\n\r\n\t\tconst maxZ = Math.max(...this.#sortedLayers.map((l) => l.zIndex))\r\n\t\tlayer.zIndex = maxZ + 1\r\n\t\tthis.#sortLayers()\r\n\t\tthis.#notifyOrderChange()\r\n\t}\r\n\r\n\tsendToBack(name: string): void {\r\n\t\tconst layer = this.#layers.get(name)\r\n\t\tif (!layer) return\r\n\r\n\t\tconst minZ = Math.min(...this.#sortedLayers.map((l) => l.zIndex))\r\n\t\tlayer.zIndex = minZ - 1\r\n\t\tthis.#sortLayers()\r\n\t\tthis.#notifyOrderChange()\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Rendering\r\n\t// ============================================================================\r\n\r\n\trender(context: CanvasRenderingContext2D, camera: CameraInterface): void {\r\n\t\tfor (const layer of this.#sortedLayers) {\r\n\t\t\tif (!layer.visible) continue\r\n\r\n\t\t\tcontext.save()\r\n\t\t\tcontext.globalAlpha = layer.opacity\r\n\t\t\tcontext.globalCompositeOperation = layer.blendMode\r\n\r\n\t\t\t// Apply parallax if camera supports it\r\n\t\t\tconst layerCamera = layer.camera ?? camera\r\n\t\t\tconst parallaxOffsetX = (1 - layer.parallaxX) * layerCamera.getX()\r\n\t\t\tconst parallaxOffsetY = (1 - layer.parallaxY) * layerCamera.getY()\r\n\r\n\t\t\tcontext.translate(parallaxOffsetX, parallaxOffsetY)\r\n\r\n\t\t\t// Render entities in this layer\r\n\t\t\tfor (const entity of layer.entities) {\r\n\t\t\t\tif (entity.isVisible()) {\r\n\t\t\t\t\t// The entity should have its own render method or use a renderer\r\n\t\t\t\t\t// This is a basic implementation - entities render themselves\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tcontext.restore()\r\n\t\t}\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Subscriptions\r\n\t// ============================================================================\r\n\r\n\tonVisibilityChange(callback: (name: string, visible: boolean) => void): Unsubscribe {\r\n\t\tthis.#visibilityListeners.add(callback)\r\n\t\treturn () => this.#visibilityListeners.delete(callback)\r\n\t}\r\n\r\n\tonOrderChange(callback: (layers: readonly string[]) => void): Unsubscribe {\r\n\t\tthis.#orderListeners.add(callback)\r\n\t\treturn () => this.#orderListeners.delete(callback)\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Private Methods\r\n\t// ============================================================================\r\n\r\n\t#sortLayers(): void {\r\n\t\tthis.#sortedLayers.sort((a, b) => a.zIndex - b.zIndex)\r\n\t}\r\n\r\n\t#notifyVisibilityChange(name: string, visible: boolean): void {\r\n\t\tfor (const listener of this.#visibilityListeners) {\r\n\t\t\ttry {\r\n\t\t\t\tlistener(name, visible)\r\n\t\t\t} catch {\r\n\t\t\t\t// Ignore listener errors\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t#notifyOrderChange(): void {\r\n\t\tconst layerNames = this.#sortedLayers.map((l) => l.name)\r\n\t\tfor (const listener of this.#orderListeners) {\r\n\t\t\ttry {\r\n\t\t\t\tlistener(layerNames)\r\n\t\t\t} catch {\r\n\t\t\t\t// Ignore listener errors\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Lifecycle\r\n\t// ============================================================================\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#layers.clear()\r\n\t\tthis.#sortedLayers.length = 0\r\n\t\tthis.#visibilityListeners.clear()\r\n\t\tthis.#orderListeners.clear()\r\n\t}\r\n}\r\n","import type {\n\tTrailRendererInterface,\n\tTrailRendererOptions,\n\tTrailPoint,\n\tCameraInterface,\n\tUnsubscribe,\n} from '../../types.js'\nimport {\n\tDEFAULT_TRAIL_MAX_POINTS,\n\tDEFAULT_TRAIL_START_WIDTH,\n\tDEFAULT_TRAIL_END_WIDTH,\n\tDEFAULT_TRAIL_FADE_TIME,\n\tDEFAULT_TRAIL_MIN_DISTANCE,\n} from '../../constants.js'\n\n/**\n * Trail RendererInterface for creating visual trails behind moving objects.\n * Useful for bullets, missiles, player movement effects, etc.\n *\n * @example\n * ```ts\n * const trail = createTrailRenderer({\n * maxPoints: 50,\n * startWidth: 10,\n * endWidth: 1,\n * startColor: '#ff0000',\n * endColor: '#ff000000',\n * fadeTime: 500,\n * })\n *\n * trail.start()\n * // In game loop\n * trail.addPoint(player.x, player.y)\n * trail.update(deltaTime)\n * trail.render(ctx, CameraInterface)\n * ```\n */\nexport class TrailRenderer implements TrailRendererInterface {\n\t#points: TrailPoint[] = []\n\t#isActive = false\n\n\t#maxPoints: number\n\t#startWidth: number\n\t#endWidth: number\n\t#startColor: string\n\t#endColor: string\n\t#fadeTime: number\n\t#minDistance: number\n\t#textureKey: string | undefined\n\t#blendMode: GlobalCompositeOperation\n\n\t#listeners = {\n\t\ttrailStart: new Set<() => void>(),\n\t\ttrailEnd: new Set<() => void>(),\n\t}\n\n\tconstructor(options?: TrailRendererOptions) {\n\t\tthis.#maxPoints = options?.maxPoints ?? DEFAULT_TRAIL_MAX_POINTS\n\t\tthis.#startWidth = options?.startWidth ?? DEFAULT_TRAIL_START_WIDTH\n\t\tthis.#endWidth = options?.endWidth ?? DEFAULT_TRAIL_END_WIDTH\n\t\tthis.#startColor = options?.startColor ?? '#ffffff'\n\t\tthis.#endColor = options?.endColor ?? '#ffffff00'\n\t\tthis.#fadeTime = options?.fadeTime ?? DEFAULT_TRAIL_FADE_TIME\n\t\tthis.#minDistance = options?.minDistance ?? DEFAULT_TRAIL_MIN_DISTANCE\n\t\tthis.#textureKey = options?.textureKey\n\t\tthis.#blendMode = options?.blendMode ?? 'source-over'\n\n\t\t// Register hooks from options\n\t\tif (options?.onTrailStart) this.#listeners.trailStart.add(options.onTrailStart)\n\t\tif (options?.onTrailEnd) this.#listeners.trailEnd.add(options.onTrailEnd)\n\t}\n\n\t// =========================================================================\n\t// Accessors (TrailRendererInterface interface)\n\t// =========================================================================\n\n\tgetPoints(): readonly TrailPoint[] {\n\t\treturn this.#points\n\t}\n\n\tgetPointCount(): number {\n\t\treturn this.#points.length\n\t}\n\n\tisActive(): boolean {\n\t\treturn this.#isActive\n\t}\n\n\t// =========================================================================\n\t// Mutators\n\t// =========================================================================\n\n\tstart(): void {\n\t\tif (!this.#isActive) {\n\t\t\tthis.#isActive = true\n\t\t\tfor (const callback of this.#listeners.trailStart) {\n\t\t\t\tcallback()\n\t\t\t}\n\t\t}\n\t}\n\n\tstop(): void {\n\t\tif (this.#isActive) {\n\t\t\tthis.#isActive = false\n\t\t\tfor (const callback of this.#listeners.trailEnd) {\n\t\t\t\tcallback()\n\t\t\t}\n\t\t}\n\t}\n\n\tclear(): void {\n\t\tthis.#points = []\n\t}\n\n\taddPoint(x: number, y: number): void {\n\t\tif (!this.#isActive) return\n\n\t\t// Check minimum distance from last point\n\t\tif (this.#points.length > 0) {\n\t\t\tconst last = this.#points[this.#points.length - 1]\n\t\t\tif (last) {\n\t\t\t\tconst dx = x - last.x\n\t\t\t\tconst dy = y - last.y\n\t\t\t\tconst dist = Math.sqrt(dx * dx + dy * dy)\n\t\t\t\tif (dist < this.#minDistance) return\n\t\t\t}\n\t\t}\n\n\t\t// Add new point\n\t\tconst point: TrailPoint = {\n\t\t\tx,\n\t\t\ty,\n\t\t\twidth: this.#startWidth,\n\t\t\tage: 0,\n\t\t}\n\t\tthis.#points.push(point)\n\n\t\t// Remove old points if exceeding max\n\t\twhile (this.#points.length > this.#maxPoints) {\n\t\t\tthis.#points.shift()\n\t\t}\n\t}\n\n\tsetStartWidth(width: number): void {\n\t\tthis.#startWidth = width\n\t}\n\n\tsetEndWidth(width: number): void {\n\t\tthis.#endWidth = width\n\t}\n\n\tsetStartColor(color: string): void {\n\t\tthis.#startColor = color\n\t}\n\n\tsetEndColor(color: string): void {\n\t\tthis.#endColor = color\n\t}\n\n\tsetFadeTime(time: number): void {\n\t\tthis.#fadeTime = time\n\t}\n\n\t// =========================================================================\n\t// Event Subscriptions\n\t// =========================================================================\n\n\tonTrailStart(callback: () => void): Unsubscribe {\n\t\tthis.#listeners.trailStart.add(callback)\n\t\treturn () => this.#listeners.trailStart.delete(callback)\n\t}\n\n\tonTrailEnd(callback: () => void): Unsubscribe {\n\t\tthis.#listeners.trailEnd.add(callback)\n\t\treturn () => this.#listeners.trailEnd.delete(callback)\n\t}\n\n\t// =========================================================================\n\t// Lifecycle\n\t// =========================================================================\n\n\tupdate(deltaTime: number): void {\n\t\t// Age all points\n\t\tfor (let i = this.#points.length - 1; i >= 0; i--) {\n\t\t\tconst point = this.#points[i]\n\t\t\tif (!point) continue\n\n\t\t\tconst newAge = point.age + deltaTime\n\t\t\tif (newAge >= this.#fadeTime) {\n\t\t\t\t// Remove old points\n\t\t\t\tthis.#points.splice(i, 1)\n\t\t\t} else {\n\t\t\t\t// Update age\n\t\t\t\tthis.#points[i] = {\n\t\t\t\t\t...point,\n\t\t\t\t\tage: newAge,\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\trender(ctx: CanvasRenderingContext2D, CameraInterface: CameraInterface): void {\n\t\tif (this.#points.length < 2) return\n\n\t\tconst prevBlendMode = ctx.globalCompositeOperation\n\t\tctx.globalCompositeOperation = this.#blendMode\n\n\t\tctx.save()\n\n\t\t// Apply CameraInterface transform\n\t\tconst cameraX = CameraInterface.getX()\n\t\tconst cameraY = CameraInterface.getY()\n\t\tconst zoom = CameraInterface.getZoom()\n\t\tctx.translate(-cameraX * zoom, -cameraY * zoom)\n\t\tctx.scale(zoom, zoom)\n\n\t\t// Draw trail as connected line segments with varying width\n\t\tfor (let i = 0; i < this.#points.length - 1; i++) {\n\t\t\tconst p1 = this.#points[i]\n\t\t\tconst p2 = this.#points[i + 1]\n\t\t\tif (!p1 || !p2) continue\n\n\t\t\tconst t1 = p1.age / this.#fadeTime\n\t\t\tconst t2 = p2.age / this.#fadeTime\n\n\t\t\t// Interpolate width and color\n\t\t\tconst width1 = this.#lerpValue(this.#startWidth, this.#endWidth, t1)\n\t\t\tconst width2 = this.#lerpValue(this.#startWidth, this.#endWidth, t2)\n\t\t\tconst color1 = this.#lerpColor(this.#startColor, this.#endColor, t1)\n\t\t\tconst color2 = this.#lerpColor(this.#startColor, this.#endColor, t2)\n\n\t\t\t// Draw segment\n\t\t\tconst gradient = ctx.createLinearGradient(p1.x, p1.y, p2.x, p2.y)\n\t\t\tgradient.addColorStop(0, color1)\n\t\t\tgradient.addColorStop(1, color2)\n\n\t\t\tctx.beginPath()\n\t\t\tctx.moveTo(p1.x, p1.y)\n\t\t\tctx.lineTo(p2.x, p2.y)\n\t\t\tctx.strokeStyle = gradient\n\t\t\tctx.lineWidth = (width1 + width2) / 2\n\t\t\tctx.lineCap = 'round'\n\t\t\tctx.lineJoin = 'round'\n\t\t\tctx.stroke()\n\t\t}\n\n\t\tctx.restore()\n\t\tctx.globalCompositeOperation = prevBlendMode\n\t}\n\n\tdestroy(): void {\n\t\tthis.#points = []\n\t\tthis.#isActive = false\n\t\tthis.#listeners.trailStart.clear()\n\t\tthis.#listeners.trailEnd.clear()\n\t}\n\n\t// =========================================================================\n\t// Private Methods\n\t// =========================================================================\n\n\t#lerpValue(a: number, b: number, t: number): number {\n\t\treturn a + (b - a) * t\n\t}\n\n\t#lerpColor(startColor: string, endColor: string, t: number): string {\n\t\t// Parse hex colors\n\t\tconst start = this.#parseColor(startColor)\n\t\tconst end = this.#parseColor(endColor)\n\n\t\tconst r = Math.round(start.r + (end.r - start.r) * t)\n\t\tconst g = Math.round(start.g + (end.g - start.g) * t)\n\t\tconst b = Math.round(start.b + (end.b - start.b) * t)\n\t\tconst a = start.a + (end.a - start.a) * t\n\n\t\treturn `rgba(${r}, ${g}, ${b}, ${a})`\n\t}\n\n\t#parseColor(color: string): { r: number; g: number; b: number; a: number } {\n\t\t// Handle rgba\n\t\tconst rgbaMatch = color.match(/rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*([\\d.]+))?\\)/)\n\t\tif (rgbaMatch) {\n\t\t\treturn {\n\t\t\t\tr: parseInt(rgbaMatch[1] ?? '0', 10),\n\t\t\t\tg: parseInt(rgbaMatch[2] ?? '0', 10),\n\t\t\t\tb: parseInt(rgbaMatch[3] ?? '0', 10),\n\t\t\t\ta: parseFloat(rgbaMatch[4] ?? '1'),\n\t\t\t}\n\t\t}\n\n\t\t// Handle hex\n\t\tlet hex = color.replace('#', '')\n\t\tif (hex.length === 3) {\n\t\t\thex = hex.split('').map(c => c + c).join('')\n\t\t}\n\t\tif (hex.length === 6) {\n\t\t\thex = hex + 'ff'\n\t\t}\n\n\t\treturn {\n\t\t\tr: parseInt(hex.slice(0, 2), 16),\n\t\t\tg: parseInt(hex.slice(2, 4), 16),\n\t\t\tb: parseInt(hex.slice(4, 6), 16),\n\t\t\ta: parseInt(hex.slice(6, 8), 16) / 255,\n\t\t}\n\t}\n}\n","import type {\n\tShapeRendererInterface,\n\tShapeRendererOptions,\n\tLineStyle,\n\tFillStyle,\n\tVector2,\n} from '../../types.js'\nimport { DEFAULT_FILL_STYLE, DEFAULT_LINE_STYLE } from '../../constants.js'\n\n/**\n * Shape RendererInterface for drawing geometric primitives.\n * Provides a simplified API for common shape rendering operations.\n *\n * @example\n * ```ts\n * const shapes = createShapeRenderer()\n * shapes.setContext(ctx)\n *\n * shapes.setLineStyle({ color: '#ff0000', width: 2 })\n * shapes.circle(100, 100, 50)\n *\n * shapes.setFillStyle({ color: '#00ff00', opacity: 0.5 })\n * shapes.rect(200, 100, 80, 60, true)\n * ```\n */\nexport class ShapeRenderer implements ShapeRendererInterface {\n\t#ctx: CanvasRenderingContext2D | undefined\n\t#lineStyle: LineStyle = { ...DEFAULT_LINE_STYLE }\n\t#fillStyle: FillStyle = { ...DEFAULT_FILL_STYLE }\n\t#defaultLineStyle: LineStyle\n\t#defaultFillStyle: FillStyle\n\n\tconstructor(options?: ShapeRendererOptions) {\n\t\tthis.#defaultLineStyle = options?.defaultLineStyle ?? { ...DEFAULT_LINE_STYLE }\n\t\tthis.#defaultFillStyle = options?.defaultFillStyle ?? { ...DEFAULT_FILL_STYLE }\n\t\tthis.#lineStyle = { ...this.#defaultLineStyle }\n\t\tthis.#fillStyle = { ...this.#defaultFillStyle }\n\t}\n\n\t// =========================================================================\n\t// Accessors (ShapeRendererInterface interface)\n\t// =========================================================================\n\n\tgetContext(): CanvasRenderingContext2D | undefined {\n\t\treturn this.#ctx\n\t}\n\n\t// =========================================================================\n\t// Mutators\n\t// =========================================================================\n\n\tsetContext(ctx: CanvasRenderingContext2D): void {\n\t\tthis.#ctx = ctx\n\t}\n\n\tsetLineStyle(style: Partial<LineStyle>): void {\n\t\tthis.#lineStyle = { ...this.#lineStyle, ...style }\n\t}\n\n\tsetFillStyle(style: Partial<FillStyle>): void {\n\t\tthis.#fillStyle = { ...this.#fillStyle, ...style }\n\t}\n\n\tresetStyles(): void {\n\t\tthis.#lineStyle = { ...this.#defaultLineStyle }\n\t\tthis.#fillStyle = { ...this.#defaultFillStyle }\n\t}\n\n\t// =========================================================================\n\t// Shape Methods\n\t// =========================================================================\n\n\tline(x1: number, y1: number, x2: number, y2: number): void {\n\t\tif (!this.#ctx) return\n\n\t\tthis.#applyLineStyle()\n\t\tthis.#ctx.beginPath()\n\t\tthis.#ctx.moveTo(x1, y1)\n\t\tthis.#ctx.lineTo(x2, y2)\n\t\tthis.#ctx.stroke()\n\t}\n\n\tpolyline(points: readonly Vector2[], closed = false): void {\n\t\tif (!this.#ctx || points.length < 2) return\n\n\t\tthis.#applyLineStyle()\n\t\tthis.#ctx.beginPath()\n\n\t\tconst first = points[0]\n\t\tif (first) {\n\t\t\tthis.#ctx.moveTo(first.x, first.y)\n\t\t}\n\n\t\tfor (let i = 1; i < points.length; i++) {\n\t\t\tconst point = points[i]\n\t\t\tif (point) {\n\t\t\t\tthis.#ctx.lineTo(point.x, point.y)\n\t\t\t}\n\t\t}\n\n\t\tif (closed) {\n\t\t\tthis.#ctx.closePath()\n\t\t}\n\n\t\tthis.#ctx.stroke()\n\t}\n\n\trectangle(x: number, y: number, width: number, height: number, fill = false): void {\n\t\tif (!this.#ctx) return\n\n\t\tif (fill) {\n\t\t\tthis.#applyFillStyle()\n\t\t\tthis.#ctx.fillRect(x, y, width, height)\n\t\t} else {\n\t\t\tthis.#applyLineStyle()\n\t\t\tthis.#ctx.strokeRect(x, y, width, height)\n\t\t}\n\t}\n\n\troundRectangle(x: number, y: number, width: number, height: number, radius: number, fill = false): void {\n\t\tif (!this.#ctx) return\n\n\t\tthis.#ctx.beginPath()\n\t\tthis.#ctx.roundRect(x, y, width, height, radius)\n\n\t\tif (fill) {\n\t\t\tthis.#applyFillStyle()\n\t\t\tthis.#ctx.fill()\n\t\t} else {\n\t\t\tthis.#applyLineStyle()\n\t\t\tthis.#ctx.stroke()\n\t\t}\n\t}\n\n\tcircle(x: number, y: number, radius: number, fill = false): void {\n\t\tif (!this.#ctx) return\n\n\t\tthis.#ctx.beginPath()\n\t\tthis.#ctx.arc(x, y, radius, 0, Math.PI * 2)\n\n\t\tif (fill) {\n\t\t\tthis.#applyFillStyle()\n\t\t\tthis.#ctx.fill()\n\t\t} else {\n\t\t\tthis.#applyLineStyle()\n\t\t\tthis.#ctx.stroke()\n\t\t}\n\t}\n\n\tellipse(x: number, y: number, radiusX: number, radiusY: number, rotation = 0, fill = false): void {\n\t\tif (!this.#ctx) return\n\n\t\tthis.#ctx.beginPath()\n\t\tthis.#ctx.ellipse(x, y, radiusX, radiusY, rotation, 0, Math.PI * 2)\n\n\t\tif (fill) {\n\t\t\tthis.#applyFillStyle()\n\t\t\tthis.#ctx.fill()\n\t\t} else {\n\t\t\tthis.#applyLineStyle()\n\t\t\tthis.#ctx.stroke()\n\t\t}\n\t}\n\n\tarc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterClockwise = false): void {\n\t\tif (!this.#ctx) return\n\n\t\tthis.#applyLineStyle()\n\t\tthis.#ctx.beginPath()\n\t\tthis.#ctx.arc(x, y, radius, startAngle, endAngle, counterClockwise)\n\t\tthis.#ctx.stroke()\n\t}\n\n\tpolygon(points: readonly Vector2[], fill = false): void {\n\t\tif (!this.#ctx || points.length < 3) return\n\n\t\tthis.#ctx.beginPath()\n\n\t\tconst first = points[0]\n\t\tif (first) {\n\t\t\tthis.#ctx.moveTo(first.x, first.y)\n\t\t}\n\n\t\tfor (let i = 1; i < points.length; i++) {\n\t\t\tconst point = points[i]\n\t\t\tif (point) {\n\t\t\t\tthis.#ctx.lineTo(point.x, point.y)\n\t\t\t}\n\t\t}\n\n\t\tthis.#ctx.closePath()\n\n\t\tif (fill) {\n\t\t\tthis.#applyFillStyle()\n\t\t\tthis.#ctx.fill()\n\t\t} else {\n\t\t\tthis.#applyLineStyle()\n\t\t\tthis.#ctx.stroke()\n\t\t}\n\t}\n\n\tbezier(x1: number, y1: number, cp1x: number, cp1y: number, cp2x: number, cp2y: number, x2: number, y2: number): void {\n\t\tif (!this.#ctx) return\n\n\t\tthis.#applyLineStyle()\n\t\tthis.#ctx.beginPath()\n\t\tthis.#ctx.moveTo(x1, y1)\n\t\tthis.#ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x2, y2)\n\t\tthis.#ctx.stroke()\n\t}\n\n\tquadratic(x1: number, y1: number, cpx: number, cpy: number, x2: number, y2: number): void {\n\t\tif (!this.#ctx) return\n\n\t\tthis.#applyLineStyle()\n\t\tthis.#ctx.beginPath()\n\t\tthis.#ctx.moveTo(x1, y1)\n\t\tthis.#ctx.quadraticCurveTo(cpx, cpy, x2, y2)\n\t\tthis.#ctx.stroke()\n\t}\n\n\tarrow(x1: number, y1: number, x2: number, y2: number, headLength = 10, headAngle = Math.PI / 6): void {\n\t\tif (!this.#ctx) return\n\n\t\tthis.#applyLineStyle()\n\n\t\t// Draw line\n\t\tthis.#ctx.beginPath()\n\t\tthis.#ctx.moveTo(x1, y1)\n\t\tthis.#ctx.lineTo(x2, y2)\n\t\tthis.#ctx.stroke()\n\n\t\t// Calculate arrowhead\n\t\tconst angle = Math.atan2(y2 - y1, x2 - x1)\n\n\t\t// Draw arrowhead\n\t\tthis.#ctx.beginPath()\n\t\tthis.#ctx.moveTo(x2, y2)\n\t\tthis.#ctx.lineTo(\n\t\t\tx2 - headLength * Math.cos(angle - headAngle),\n\t\t\ty2 - headLength * Math.sin(angle - headAngle),\n\t\t)\n\t\tthis.#ctx.moveTo(x2, y2)\n\t\tthis.#ctx.lineTo(\n\t\t\tx2 - headLength * Math.cos(angle + headAngle),\n\t\t\ty2 - headLength * Math.sin(angle + headAngle),\n\t\t)\n\t\tthis.#ctx.stroke()\n\t}\n\n\tcross(x: number, y: number, size: number): void {\n\t\tif (!this.#ctx) return\n\n\t\tthis.#applyLineStyle()\n\t\tconst half = size / 2\n\n\t\tthis.#ctx.beginPath()\n\t\tthis.#ctx.moveTo(x - half, y)\n\t\tthis.#ctx.lineTo(x + half, y)\n\t\tthis.#ctx.moveTo(x, y - half)\n\t\tthis.#ctx.lineTo(x, y + half)\n\t\tthis.#ctx.stroke()\n\t}\n\n\tgrid(x: number, y: number, width: number, height: number, cellWidth: number, cellHeight: number): void {\n\t\tif (!this.#ctx) return\n\n\t\tthis.#applyLineStyle()\n\t\tthis.#ctx.beginPath()\n\n\t\t// Vertical lines\n\t\tfor (let px = x; px <= x + width; px += cellWidth) {\n\t\t\tthis.#ctx.moveTo(px, y)\n\t\t\tthis.#ctx.lineTo(px, y + height)\n\t\t}\n\n\t\t// Horizontal lines\n\t\tfor (let py = y; py <= y + height; py += cellHeight) {\n\t\t\tthis.#ctx.moveTo(x, py)\n\t\t\tthis.#ctx.lineTo(x + width, py)\n\t\t}\n\n\t\tthis.#ctx.stroke()\n\t}\n\n\t// =========================================================================\n\t// Lifecycle\n\t// =========================================================================\n\n\tdestroy(): void {\n\t\tthis.#ctx = undefined\n\t\tthis.resetStyles()\n\t}\n\n\t// =========================================================================\n\t// Private Methods\n\t// =========================================================================\n\n\t#applyLineStyle(): void {\n\t\tif (!this.#ctx) return\n\n\t\tthis.#ctx.strokeStyle = this.#lineStyle.color\n\t\tthis.#ctx.lineWidth = this.#lineStyle.width\n\n\t\tif (this.#lineStyle.dash) {\n\t\t\tthis.#ctx.setLineDash(this.#lineStyle.dash as number[])\n\t\t} else {\n\t\t\tthis.#ctx.setLineDash([])\n\t\t}\n\n\t\tif (this.#lineStyle.dashOffset !== undefined) {\n\t\t\tthis.#ctx.lineDashOffset = this.#lineStyle.dashOffset\n\t\t}\n\n\t\tif (this.#lineStyle.cap) {\n\t\t\tthis.#ctx.lineCap = this.#lineStyle.cap\n\t\t}\n\n\t\tif (this.#lineStyle.join) {\n\t\t\tthis.#ctx.lineJoin = this.#lineStyle.join\n\t\t}\n\t}\n\n\t#applyFillStyle(): void {\n\t\tif (!this.#ctx) return\n\n\t\tthis.#ctx.fillStyle = this.#fillStyle.color\n\t\tthis.#ctx.globalAlpha = this.#fillStyle.opacity ?? 1\n\t}\n}\n","import type {\n\tPostProcessManagerInterface,\n\tPostProcessManagerOptions,\n\tPostProcessEffect,\n\tPostProcessEffectType,\n\tPostProcessState,\n\tUnsubscribe,\n} from '../../types.js'\n\n/**\n * Post-processing manager for applying visual effects to the rendered canvas.\n * Supports vignette, color tint, brightness, contrast, and more.\n *\n * @example\n * ```ts\n * const postProcess = createPostProcessManager({\n * enabled: true,\n * effects: [\n * { type: 'vignette', intensity: 0.3, enabled: true },\n * { type: 'color-tint', intensity: 0.2, enabled: true, params: { r: 255, g: 200, b: 150 } },\n * ],\n * })\n *\n * // After rendering the SceneInterface\n * postProcess.apply(ctx, canvas)\n * ```\n */\nexport class PostProcessManager implements PostProcessManagerInterface {\n\t#effects: Map<PostProcessEffectType, PostProcessEffect> = new Map()\n\t#enabled: boolean\n\n\t#listeners = {\n\t\teffectAdd: new Set<(effect: PostProcessEffect) => void>(),\n\t\teffectRemove: new Set<(type: PostProcessEffectType) => void>(),\n\t\teffectChange: new Set<(effect: PostProcessEffect) => void>(),\n\t}\n\n\tconstructor(options?: PostProcessManagerOptions) {\n\t\tthis.#enabled = options?.enabled ?? true\n\n\t\t// Add initial effects\n\t\tif (options?.effects) {\n\t\t\tfor (const effect of options.effects) {\n\t\t\t\tthis.#effects.set(effect.type, effect)\n\t\t\t}\n\t\t}\n\n\t\t// Register hooks from options\n\t\tif (options?.onEffectAdd) this.#listeners.effectAdd.add(options.onEffectAdd)\n\t\tif (options?.onEffectRemove) this.#listeners.effectRemove.add(options.onEffectRemove)\n\t\tif (options?.onEffectChange) this.#listeners.effectChange.add(options.onEffectChange)\n\t}\n\n\t// =========================================================================\n\t// Accessors (PostProcessManagerInterface interface)\n\t// =========================================================================\n\n\tgetState(): PostProcessState {\n\t\treturn {\n\t\t\teffects: Array.from(this.#effects.values()),\n\t\t\tenabled: this.#enabled,\n\t\t}\n\t}\n\n\tisEnabled(): boolean {\n\t\treturn this.#enabled\n\t}\n\n\tgetEffect(type: PostProcessEffectType): PostProcessEffect | undefined {\n\t\treturn this.#effects.get(type)\n\t}\n\n\thasEffect(type: PostProcessEffectType): boolean {\n\t\treturn this.#effects.has(type)\n\t}\n\n\t// =========================================================================\n\t// Mutators\n\t// =========================================================================\n\n\tenable(): void {\n\t\tthis.#enabled = true\n\t}\n\n\tdisable(): void {\n\t\tthis.#enabled = false\n\t}\n\n\ttoggle(): void {\n\t\tthis.#enabled = !this.#enabled\n\t}\n\n\taddEffect(effect: PostProcessEffect): void {\n\t\tthis.#effects.set(effect.type, effect)\n\t\tfor (const callback of this.#listeners.effectAdd) {\n\t\t\tcallback(effect)\n\t\t}\n\t}\n\n\tremoveEffect(type: PostProcessEffectType): void {\n\t\tif (this.#effects.delete(type)) {\n\t\t\tfor (const callback of this.#listeners.effectRemove) {\n\t\t\t\tcallback(type)\n\t\t\t}\n\t\t}\n\t}\n\n\tsetEffectIntensity(type: PostProcessEffectType, intensity: number): void {\n\t\tconst effect = this.#effects.get(type)\n\t\tif (effect) {\n\t\t\tconst updated: PostProcessEffect = {\n\t\t\t\t...effect,\n\t\t\t\tintensity: Math.max(0, Math.min(1, intensity)),\n\t\t\t}\n\t\t\tthis.#effects.set(type, updated)\n\t\t\tfor (const callback of this.#listeners.effectChange) {\n\t\t\t\tcallback(updated)\n\t\t\t}\n\t\t}\n\t}\n\n\tsetEffectEnabled(type: PostProcessEffectType, enabled: boolean): void {\n\t\tconst effect = this.#effects.get(type)\n\t\tif (effect) {\n\t\t\tconst updated: PostProcessEffect = { ...effect, enabled }\n\t\t\tthis.#effects.set(type, updated)\n\t\t\tfor (const callback of this.#listeners.effectChange) {\n\t\t\t\tcallback(updated)\n\t\t\t}\n\t\t}\n\t}\n\n\tsetEffectParams(type: PostProcessEffectType, params: Record<string, unknown>): void {\n\t\tconst effect = this.#effects.get(type)\n\t\tif (effect) {\n\t\t\tconst updated: PostProcessEffect = {\n\t\t\t\t...effect,\n\t\t\t\tparams: { ...effect.params, ...params },\n\t\t\t}\n\t\t\tthis.#effects.set(type, updated)\n\t\t\tfor (const callback of this.#listeners.effectChange) {\n\t\t\t\tcallback(updated)\n\t\t\t}\n\t\t}\n\t}\n\n\tclearEffects(): void {\n\t\tthis.#effects.clear()\n\t}\n\n\t// =========================================================================\n\t// Event Subscriptions\n\t// =========================================================================\n\n\tonEffectAdd(callback: (effect: PostProcessEffect) => void): Unsubscribe {\n\t\tthis.#listeners.effectAdd.add(callback)\n\t\treturn () => this.#listeners.effectAdd.delete(callback)\n\t}\n\n\tonEffectRemove(callback: (type: PostProcessEffectType) => void): Unsubscribe {\n\t\tthis.#listeners.effectRemove.add(callback)\n\t\treturn () => this.#listeners.effectRemove.delete(callback)\n\t}\n\n\tonEffectChange(callback: (effect: PostProcessEffect) => void): Unsubscribe {\n\t\tthis.#listeners.effectChange.add(callback)\n\t\treturn () => this.#listeners.effectChange.delete(callback)\n\t}\n\n\t// =========================================================================\n\t// Rendering\n\t// =========================================================================\n\n\tapply(ctx: CanvasRenderingContext2D, canvas: HTMLCanvasElement): void {\n\t\tif (!this.#enabled) return\n\n\t\t// Apply each enabled effect in order\n\t\tfor (const effect of this.#effects.values()) {\n\t\t\tif (!effect.enabled || effect.intensity <= 0) continue\n\n\t\t\tswitch (effect.type) {\n\t\t\t\tcase 'vignette':\n\t\t\t\t\tthis.#applyVignette(ctx, canvas, effect.intensity)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'color-tint':\n\t\t\t\t\tthis.#applyColorTint(ctx, canvas, effect.intensity, effect.params)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'brightness':\n\t\t\t\t\tthis.#applyBrightness(ctx, canvas, effect.intensity, effect.params)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'contrast':\n\t\t\t\t\tthis.#applyContrast(ctx, canvas, effect.intensity, effect.params)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'saturation':\n\t\t\t\t\tthis.#applySaturation(ctx, canvas, effect.intensity, effect.params)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'pixelate':\n\t\t\t\t\tthis.#applyPixelate(ctx, canvas, effect.intensity, effect.params)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'scanlines':\n\t\t\t\t\tthis.#applyScanlines(ctx, canvas, effect.intensity)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'crt':\n\t\t\t\t\tthis.#applyCRT(ctx, canvas, effect.intensity)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'blur':\n\t\t\t\t\tthis.#applyBlur(ctx, effect.intensity, effect.params)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'glow':\n\t\t\t\t\tthis.#applyGlow(ctx, canvas, effect.intensity, effect.params)\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.#effects.clear()\n\t\tthis.#enabled = false\n\t\tthis.#listeners.effectAdd.clear()\n\t\tthis.#listeners.effectRemove.clear()\n\t\tthis.#listeners.effectChange.clear()\n\t}\n\n\t// =========================================================================\n\t// Private Effect Methods\n\t// =========================================================================\n\n\t#applyVignette(ctx: CanvasRenderingContext2D, canvas: HTMLCanvasElement, intensity: number): void {\n\t\tconst centerX = canvas.width / 2\n\t\tconst centerY = canvas.height / 2\n\t\tconst radius = Math.max(centerX, centerY) * 1.5\n\n\t\tconst gradient = ctx.createRadialGradient(centerX, centerY, 0, centerX, centerY, radius)\n\t\tgradient.addColorStop(0, 'rgba(0, 0, 0, 0)')\n\t\tgradient.addColorStop(0.5, 'rgba(0, 0, 0, 0)')\n\t\tgradient.addColorStop(1, `rgba(0, 0, 0, ${intensity})`)\n\n\t\tctx.fillStyle = gradient\n\t\tctx.fillRect(0, 0, canvas.width, canvas.height)\n\t}\n\n\t#applyColorTint(ctx: CanvasRenderingContext2D, canvas: HTMLCanvasElement, intensity: number, params?: Record<string, unknown>): void {\n\t\tconst r = (params?.r as number) ?? 255\n\t\tconst g = (params?.g as number) ?? 200\n\t\tconst b = (params?.b as number) ?? 150\n\n\t\tctx.globalCompositeOperation = 'overlay'\n\t\tctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${intensity})`\n\t\tctx.fillRect(0, 0, canvas.width, canvas.height)\n\t\tctx.globalCompositeOperation = 'source-over'\n\t}\n\n\t#applyBrightness(ctx: CanvasRenderingContext2D, canvas: HTMLCanvasElement, intensity: number, params?: Record<string, unknown>): void {\n\t\tconst brighten = (params?.brighten as boolean) ?? true\n\t\tctx.globalCompositeOperation = brighten ? 'lighter' : 'darken'\n\t\tctx.fillStyle = `rgba(255, 255, 255, ${intensity * 0.3})`\n\t\tctx.fillRect(0, 0, canvas.width, canvas.height)\n\t\tctx.globalCompositeOperation = 'source-over'\n\t}\n\n\t#applyContrast(ctx: CanvasRenderingContext2D, _canvas: HTMLCanvasElement, intensity: number, _params?: Record<string, unknown>): void {\n\t\t// Apply contrast using CSS filter\n\t\tconst contrastValue = 1 + intensity\n\t\tctx.filter = `contrast(${contrastValue})`\n\t\tctx.drawImage(ctx.canvas, 0, 0)\n\t\tctx.filter = 'none'\n\t}\n\n\t#applySaturation(ctx: CanvasRenderingContext2D, _canvas: HTMLCanvasElement, intensity: number, _params?: Record<string, unknown>): void {\n\t\t// Apply saturation using CSS filter\n\t\tconst saturationValue = 1 + intensity\n\t\tctx.filter = `saturate(${saturationValue})`\n\t\tctx.drawImage(ctx.canvas, 0, 0)\n\t\tctx.filter = 'none'\n\t}\n\n\t#applyPixelate(ctx: CanvasRenderingContext2D, canvas: HTMLCanvasElement, intensity: number, params?: Record<string, unknown>): void {\n\t\tconst pixelSize = Math.max(1, Math.floor(((params?.size as number) ?? 8) * intensity))\n\t\tconst w = canvas.width\n\t\tconst h = canvas.height\n\n\t\t// Get ImageInterface data\n\t\tconst imageData = ctx.getImageData(0, 0, w, h)\n\t\tconst data = imageData.data\n\n\t\t// Pixelate\n\t\tfor (let y = 0; y < h; y += pixelSize) {\n\t\t\tfor (let x = 0; x < w; x += pixelSize) {\n\t\t\t\t// Get average color of block\n\t\t\t\tlet r = 0, g = 0, b = 0, count = 0\n\n\t\t\t\tfor (let py = 0; py < pixelSize && y + py < h; py++) {\n\t\t\t\t\tfor (let px = 0; px < pixelSize && x + px < w; px++) {\n\t\t\t\t\t\tconst i = ((y + py) * w + (x + px)) * 4\n\t\t\t\t\t\tr += data[i] ?? 0\n\t\t\t\t\t\tg += data[i + 1] ?? 0\n\t\t\t\t\t\tb += data[i + 2] ?? 0\n\t\t\t\t\t\tcount++\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tr = Math.floor(r / count)\n\t\t\t\tg = Math.floor(g / count)\n\t\t\t\tb = Math.floor(b / count)\n\n\t\t\t\t// Set all pixels in block to average\n\t\t\t\tfor (let py = 0; py < pixelSize && y + py < h; py++) {\n\t\t\t\t\tfor (let px = 0; px < pixelSize && x + px < w; px++) {\n\t\t\t\t\t\tconst i = ((y + py) * w + (x + px)) * 4\n\t\t\t\t\t\tdata[i] = r\n\t\t\t\t\t\tdata[i + 1] = g\n\t\t\t\t\t\tdata[i + 2] = b\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tctx.putImageData(imageData, 0, 0)\n\t}\n\n\t#applyScanlines(ctx: CanvasRenderingContext2D, canvas: HTMLCanvasElement, intensity: number): void {\n\t\tctx.fillStyle = `rgba(0, 0, 0, ${intensity * 0.1})`\n\t\tfor (let y = 0; y < canvas.height; y += 4) {\n\t\t\tctx.fillRect(0, y, canvas.width, 2)\n\t\t}\n\t}\n\n\t#applyCRT(ctx: CanvasRenderingContext2D, canvas: HTMLCanvasElement, intensity: number): void {\n\t\t// Apply vignette\n\t\tthis.#applyVignette(ctx, canvas, intensity * 0.5)\n\n\t\t// Apply scanlines\n\t\tthis.#applyScanlines(ctx, canvas, intensity)\n\n\t\t// Apply subtle color shift (chromatic aberration simulation)\n\t\tconst offset = Math.floor(intensity * 2)\n\t\tif (offset > 0) {\n\t\t\tconst imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)\n\t\t\tconst data = imageData.data\n\n\t\t\tfor (let y = 0; y < canvas.height; y++) {\n\t\t\t\tfor (let x = 0; x < canvas.width; x++) {\n\t\t\t\t\tconst i = (y * canvas.width + x) * 4\n\n\t\t\t\t\t// Shift red channel left\n\t\t\t\t\tif (x >= offset) {\n\t\t\t\t\t\tconst ri = (y * canvas.width + (x - offset)) * 4\n\t\t\t\t\t\tdata[i] = data[ri] ?? data[i] ?? 0\n\t\t\t\t\t}\n\n\t\t\t\t\t// Shift blue channel right\n\t\t\t\t\tif (x < canvas.width - offset) {\n\t\t\t\t\t\tconst bi = (y * canvas.width + (x + offset)) * 4\n\t\t\t\t\t\tdata[i + 2] = data[bi + 2] ?? data[i + 2] ?? 0\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tctx.putImageData(imageData, 0, 0)\n\t\t}\n\t}\n\n\t#applyBlur(ctx: CanvasRenderingContext2D, intensity: number, params?: Record<string, unknown>): void {\n\t\tconst radius = ((params?.radius as number) ?? 5) * intensity\n\t\tctx.filter = `blur(${radius}px)`\n\t\tctx.drawImage(ctx.canvas, 0, 0)\n\t\tctx.filter = 'none'\n\t}\n\n\t#applyGlow(ctx: CanvasRenderingContext2D, canvas: HTMLCanvasElement, intensity: number, params?: Record<string, unknown>): void {\n\t\tconst color = (params?.color as string) ?? '#ffffff'\n\t\tconst size = ((params?.size as number) ?? 10) * intensity\n\n\t\tctx.shadowColor = color\n\t\tctx.shadowBlur = size\n\t\tctx.globalCompositeOperation = 'lighter'\n\t\tctx.drawImage(canvas, 0, 0)\n\t\tctx.globalCompositeOperation = 'source-over'\n\t\tctx.shadowBlur = 0\n\t}\n}\n","/**\r\n * ToastManager - Manages toast/notification displays.\r\n *\r\n * Features:\r\n * - Position (top, bottom, corners)\r\n * - Auto-dismiss with duration\r\n * - Queue management\r\n * - Icons and colors\r\n */\r\nimport type {\r\n\tToastManagerInterface,\r\n\tToastManagerOptions,\r\n\tToastOptions,\r\n\tToastState,\r\n\tToastType,\r\n\tToastPosition,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\n/** Internal toast data */\r\ninterface ToastData {\r\n\tid: string\r\n\tmessage: string\r\n\ttype: ToastType\r\n\tduration: number\r\n\tposition: ToastPosition\r\n\ticon: string | undefined\r\n\tdismissible: boolean\r\n\tage: number\r\n\tisVisible: boolean\r\n\topacity: number\r\n}\r\n\r\n/**\r\n * Game toast manager implementation.\r\n */\r\nexport class ToastManager implements ToastManagerInterface {\r\n\treadonly #toasts = new Map<string, ToastData>()\r\n\treadonly #queue: ToastData[] = []\r\n\treadonly #visible: ToastData[] = []\r\n\treadonly #showListeners = new Set<(toast: ToastState) => void>()\r\n\treadonly #dismissListeners = new Set<(toast: ToastState) => void>()\r\n\treadonly #defaultDuration: number\r\n\treadonly #defaultPosition: ToastPosition\r\n\treadonly #maxVisible: number\r\n\treadonly #spacing: number\r\n\treadonly #animation: 'slide' | 'fade' | 'none'\r\n\t#nextId = 1\r\n\r\n\tconstructor(options?: ToastManagerOptions) {\r\n\t\tthis.#defaultDuration = options?.defaultDuration ?? 3000\r\n\t\tthis.#defaultPosition = options?.defaultPosition ?? 'top'\r\n\t\tthis.#maxVisible = options?.maxVisible ?? 3\r\n\t\tthis.#spacing = options?.spacing ?? 10\r\n\t\tthis.#animation = options?.animation ?? 'slide'\r\n\r\n\t\tif (options?.onShow) {\r\n\t\t\tthis.#showListeners.add(options.onShow)\r\n\t\t}\r\n\t\tif (options?.onDismiss) {\r\n\t\t\tthis.#dismissListeners.add(options.onDismiss)\r\n\t\t}\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Toast Creation\r\n\t// ============================================================================\r\n\r\n\tshow(options: ToastOptions | string): string {\r\n\t\tconst opts = typeof options === 'string' ? { message: options } : options\r\n\r\n\t\tconst id = `toast-${this.#nextId++}`\r\n\t\tconst toast: ToastData = {\r\n\t\t\tid,\r\n\t\t\tmessage: opts.message,\r\n\t\t\ttype: opts.type ?? 'info',\r\n\t\t\tduration: opts.duration ?? this.#defaultDuration,\r\n\t\t\tposition: opts.position ?? this.#defaultPosition,\r\n\t\t\ticon: opts.icon,\r\n\t\t\tdismissible: opts.dismissible ?? true,\r\n\t\t\tage: 0,\r\n\t\t\tisVisible: false,\r\n\t\t\topacity: 0,\r\n\t\t}\r\n\r\n\t\tthis.#toasts.set(id, toast)\r\n\t\tthis.#queue.push(toast)\r\n\t\tthis.#processQueue()\r\n\r\n\t\treturn id\r\n\t}\r\n\r\n\tinfo(message: string, duration?: number): string {\r\n\t\tconst opts: ToastOptions = { message, type: 'info' }\r\n\t\tif (duration !== undefined) {\r\n\t\t\treturn this.show({ ...opts, duration })\r\n\t\t}\r\n\t\treturn this.show(opts)\r\n\t}\r\n\r\n\tsuccess(message: string, duration?: number): string {\r\n\t\tconst opts: ToastOptions = { message, type: 'success' }\r\n\t\tif (duration !== undefined) {\r\n\t\t\treturn this.show({ ...opts, duration })\r\n\t\t}\r\n\t\treturn this.show(opts)\r\n\t}\r\n\r\n\twarning(message: string, duration?: number): string {\r\n\t\tconst opts: ToastOptions = { message, type: 'warning' }\r\n\t\tif (duration !== undefined) {\r\n\t\t\treturn this.show({ ...opts, duration })\r\n\t\t}\r\n\t\treturn this.show(opts)\r\n\t}\r\n\r\n\terror(message: string, duration?: number): string {\r\n\t\tconst opts: ToastOptions = { message, type: 'error' }\r\n\t\tif (duration !== undefined) {\r\n\t\t\treturn this.show({ ...opts, duration })\r\n\t\t}\r\n\t\treturn this.show(opts)\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Toast Control\r\n\t// ============================================================================\r\n\r\n\tdismiss(id: string): void {\r\n\t\tconst toast = this.#toasts.get(id)\r\n\t\tif (!toast) return\r\n\r\n\t\tthis.#removeToast(toast)\r\n\t}\r\n\r\n\tdismissAll(): void {\r\n\t\tfor (const toast of this.#visible) {\r\n\t\t\tthis.#notifyDismiss(toast)\r\n\t\t}\r\n\t\tthis.#visible.length = 0\r\n\t\tthis.#queue.length = 0\r\n\t\tthis.#toasts.clear()\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Toast State\r\n\t// ============================================================================\r\n\r\n\tgetVisible(): readonly ToastState[] {\r\n\t\treturn this.#visible.map(this.#toToastState)\r\n\t}\r\n\r\n\tgetQueue(): readonly ToastState[] {\r\n\t\treturn this.#queue.map(this.#toToastState)\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Update\r\n\t// ============================================================================\r\n\r\n\tupdate(deltaTime: number): void {\r\n\t\tconst deltaMs = deltaTime * 1000\r\n\t\tconst toRemove: ToastData[] = []\r\n\r\n\t\t// Update visible toasts\r\n\t\tfor (const toast of this.#visible) {\r\n\t\t\ttoast.age += deltaMs\r\n\r\n\t\t\t// Animate opacity\r\n\t\t\tif (this.#animation === 'fade') {\r\n\t\t\t\tif (toast.age < 200) {\r\n\t\t\t\t\ttoast.opacity = toast.age / 200\r\n\t\t\t\t} else if (toast.age > toast.duration - 200) {\r\n\t\t\t\t\ttoast.opacity = Math.max(0, (toast.duration - toast.age) / 200)\r\n\t\t\t\t} else {\r\n\t\t\t\t\ttoast.opacity = 1\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\ttoast.opacity = 1\r\n\t\t\t}\r\n\r\n\t\t\t// Check if expired\r\n\t\t\tif (toast.age >= toast.duration) {\r\n\t\t\t\ttoRemove.push(toast)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Remove expired toasts\r\n\t\tfor (const toast of toRemove) {\r\n\t\t\tthis.#removeToast(toast)\r\n\t\t}\r\n\r\n\t\t// Process queue if there's room\r\n\t\tthis.#processQueue()\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Rendering\r\n\t// ============================================================================\r\n\r\n\trender(context: CanvasRenderingContext2D): void {\r\n\t\tconst canvasWidth = context.canvas.width\r\n\t\tconst canvasHeight = context.canvas.height\r\n\r\n\t\tlet yOffset = 20\r\n\r\n\t\tfor (const toast of this.#visible) {\r\n\t\t\tconst width = 300\r\n\t\t\tconst height = 50\r\n\t\t\tlet x = (canvasWidth - width) / 2\r\n\t\t\tlet y = yOffset\r\n\r\n\t\t\t// Position based on toast position\r\n\t\t\tswitch (toast.position) {\r\n\t\t\t\tcase 'top':\r\n\t\t\t\t\tx = (canvasWidth - width) / 2\r\n\t\t\t\t\tbreak\r\n\t\t\t\tcase 'top-left':\r\n\t\t\t\t\tx = 20\r\n\t\t\t\t\tbreak\r\n\t\t\t\tcase 'top-right':\r\n\t\t\t\t\tx = canvasWidth - width - 20\r\n\t\t\t\t\tbreak\r\n\t\t\t\tcase 'bottom':\r\n\t\t\t\t\tx = (canvasWidth - width) / 2\r\n\t\t\t\t\ty = canvasHeight - yOffset - height\r\n\t\t\t\t\tbreak\r\n\t\t\t\tcase 'bottom-left':\r\n\t\t\t\t\tx = 20\r\n\t\t\t\t\ty = canvasHeight - yOffset - height\r\n\t\t\t\t\tbreak\r\n\t\t\t\tcase 'bottom-right':\r\n\t\t\t\t\tx = canvasWidth - width - 20\r\n\t\t\t\t\ty = canvasHeight - yOffset - height\r\n\t\t\t\t\tbreak\r\n\t\t\t}\r\n\r\n\t\t\tcontext.save()\r\n\t\t\tcontext.globalAlpha = toast.opacity\r\n\r\n\t\t\t// Background color based on type\r\n\t\t\tlet bgColor = '#333'\r\n\t\t\tswitch (toast.type) {\r\n\t\t\t\tcase 'success':\r\n\t\t\t\t\tbgColor = '#4CAF50'\r\n\t\t\t\t\tbreak\r\n\t\t\t\tcase 'warning':\r\n\t\t\t\t\tbgColor = '#FF9800'\r\n\t\t\t\t\tbreak\r\n\t\t\t\tcase 'error':\r\n\t\t\t\t\tbgColor = '#F44336'\r\n\t\t\t\t\tbreak\r\n\t\t\t\tcase 'info':\r\n\t\t\t\t\tbgColor = '#2196F3'\r\n\t\t\t\t\tbreak\r\n\t\t\t}\r\n\r\n\t\t\t// Draw background\r\n\t\t\tcontext.fillStyle = bgColor\r\n\t\t\tcontext.beginPath()\r\n\t\t\tthis.#roundRect(context, x, y, width, height, 8)\r\n\t\t\tcontext.fill()\r\n\r\n\t\t\t// Draw text\r\n\t\t\tcontext.fillStyle = '#FFFFFF'\r\n\t\t\tcontext.font = '14px sans-serif'\r\n\t\t\tcontext.textAlign = 'center'\r\n\t\t\tcontext.textBaseline = 'middle'\r\n\t\t\tcontext.fillText(toast.message, x + width / 2, y + height / 2, width - 20)\r\n\r\n\t\t\tcontext.restore()\r\n\r\n\t\t\tyOffset += height + this.#spacing\r\n\t\t}\r\n\t}\r\n\r\n\t#roundRect(\r\n\t\tctx: CanvasRenderingContext2D,\r\n\t\tx: number,\r\n\t\ty: number,\r\n\t\twidth: number,\r\n\t\theight: number,\r\n\t\tradius: number,\r\n\t): void {\r\n\t\tctx.moveTo(x + radius, y)\r\n\t\tctx.lineTo(x + width - radius, y)\r\n\t\tctx.quadraticCurveTo(x + width, y, x + width, y + radius)\r\n\t\tctx.lineTo(x + width, y + height - radius)\r\n\t\tctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height)\r\n\t\tctx.lineTo(x + radius, y + height)\r\n\t\tctx.quadraticCurveTo(x, y + height, x, y + height - radius)\r\n\t\tctx.lineTo(x, y + radius)\r\n\t\tctx.quadraticCurveTo(x, y, x + radius, y)\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Subscriptions\r\n\t// ============================================================================\r\n\r\n\tonShow(callback: (toast: ToastState) => void): Unsubscribe {\r\n\t\tthis.#showListeners.add(callback)\r\n\t\treturn () => this.#showListeners.delete(callback)\r\n\t}\r\n\r\n\tonDismiss(callback: (toast: ToastState) => void): Unsubscribe {\r\n\t\tthis.#dismissListeners.add(callback)\r\n\t\treturn () => this.#dismissListeners.delete(callback)\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Private Methods\r\n\t// ============================================================================\r\n\r\n\t#processQueue(): void {\r\n\t\twhile (this.#visible.length < this.#maxVisible && this.#queue.length > 0) {\r\n\t\t\tconst toast = this.#queue.shift()\r\n\t\t\tif (toast) {\r\n\t\t\t\ttoast.isVisible = true\r\n\t\t\t\tthis.#visible.push(toast)\r\n\t\t\t\tthis.#notifyShow(toast)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t#removeToast(toast: ToastData): void {\r\n\t\tconst visibleIndex = this.#visible.indexOf(toast)\r\n\t\tif (visibleIndex >= 0) {\r\n\t\t\tthis.#visible.splice(visibleIndex, 1)\r\n\t\t}\r\n\r\n\t\tconst queueIndex = this.#queue.indexOf(toast)\r\n\t\tif (queueIndex >= 0) {\r\n\t\t\tthis.#queue.splice(queueIndex, 1)\r\n\t\t}\r\n\r\n\t\tthis.#toasts.delete(toast.id)\r\n\t\tthis.#notifyDismiss(toast)\r\n\t}\r\n\r\n\t#toToastState = (toast: ToastData): ToastState => ({\r\n\t\tid: toast.id,\r\n\t\tmessage: toast.message,\r\n\t\ttype: toast.type,\r\n\t\tisVisible: toast.isVisible,\r\n\t\tprogress: toast.age / toast.duration,\r\n\t\tage: toast.age,\r\n\t})\r\n\r\n\t#notifyShow(toast: ToastData): void {\r\n\t\tconst state = this.#toToastState(toast)\r\n\t\tfor (const listener of this.#showListeners) {\r\n\t\t\ttry {\r\n\t\t\t\tlistener(state)\r\n\t\t\t} catch {\r\n\t\t\t\t// Ignore listener errors\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t#notifyDismiss(toast: ToastData): void {\r\n\t\tconst state = this.#toToastState(toast)\r\n\t\tfor (const listener of this.#dismissListeners) {\r\n\t\t\ttry {\r\n\t\t\t\tlistener(state)\r\n\t\t\t} catch {\r\n\t\t\t\t// Ignore listener errors\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Lifecycle\r\n\t// ============================================================================\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#toasts.clear()\r\n\t\tthis.#queue.length = 0\r\n\t\tthis.#visible.length = 0\r\n\t\tthis.#showListeners.clear()\r\n\t\tthis.#dismissListeners.clear()\r\n\t}\r\n}\r\n","/**\n * Modal - Individual modal dialog component.\n *\n * Features:\n * - Open/close with animation\n * - Customizable title, content, and buttons\n * - Event subscriptions (onOpen, onClose, onButtonClick)\n * - Backdrop click handling\n * - Escape key handling\n */\nimport type {\n\tModalInterface,\n\tModalOptions,\n\tModalButtonConfig,\n\tModalState,\n\tInputState,\n\tUnsubscribe,\n} from '../../types.js'\nimport { generateId } from '../../helpers.js'\n\n/**\n * Modal dialog implementation.\n *\n * @example\n * ```ts\n * const modal = createModal({\n * title: 'Confirm Action',\n * content: 'Are you sure you want to proceed?',\n * buttons: [\n * { text: 'Cancel', value: false, style: 'secondary', closeOnClick: true },\n * { text: 'Confirm', value: true, style: 'primary', closeOnClick: true },\n * ],\n * })\n *\n * modal.onClose((value) => {\n * console.log('Modal closed with value:', value)\n * })\n *\n * modal.open()\n * ```\n */\nexport class Modal implements ModalInterface {\n\treadonly #id: string\n\t#title: string | undefined\n\t#content: string | undefined\n\t#buttons: readonly ModalButtonConfig[]\n\t#isOpen = false\n\t#isAnimating = false\n\t#animationProgress = 0\n\n\treadonly #options: ModalOptions\n\treadonly #listeners = {\n\t\topen: new Set<() => void>(),\n\t\tclose: new Set<(value: unknown) => void>(),\n\t\tbuttonClick: new Set<(value: unknown) => void>(),\n\t}\n\n\t#resolvePromise: ((value: unknown) => void) | undefined\n\n\tconstructor(options: ModalOptions) {\n\t\tthis.#id = generateId()\n\t\tthis.#options = options\n\t\tthis.#title = options.title\n\t\tthis.#content = options.content\n\t\tthis.#buttons = options.buttons ?? []\n\t}\n\n\t// =========================================================================\n\t// Accessors\n\t// =========================================================================\n\n\tgetId(): string {\n\t\treturn this.#id\n\t}\n\n\tgetState(): ModalState {\n\t\treturn {\n\t\t\tisOpen: this.#isOpen,\n\t\t\tisAnimating: this.#isAnimating,\n\t\t\ttitle: this.#title,\n\t\t\tcontent: this.#content,\n\t\t}\n\t}\n\n\tisOpen(): boolean {\n\t\treturn this.#isOpen\n\t}\n\n\tgetTitle(): string | undefined {\n\t\treturn this.#title\n\t}\n\n\tgetContent(): string | undefined {\n\t\treturn this.#content\n\t}\n\n\tgetButtons(): readonly ModalButtonConfig[] {\n\t\treturn this.#buttons\n\t}\n\n\t// =========================================================================\n\t// Mutators\n\t// =========================================================================\n\n\tsetTitle(title: string): void {\n\t\tthis.#title = title\n\t}\n\n\tsetContent(content: string): void {\n\t\tthis.#content = content\n\t}\n\n\tsetButtons(buttons: readonly ModalButtonConfig[]): void {\n\t\tthis.#buttons = buttons\n\t}\n\n\t// =========================================================================\n\t// Actions\n\t// =========================================================================\n\n\topen(): void {\n\t\tif (this.#isOpen) return\n\n\t\tthis.#isOpen = true\n\t\tthis.#isAnimating = true\n\t\tthis.#animationProgress = 0\n\n\t\tfor (const listener of this.#listeners.open) {\n\t\t\ttry {\n\t\t\t\tlistener()\n\t\t\t} catch {\n\t\t\t\t// Ignore errors in listeners\n\t\t\t}\n\t\t}\n\t}\n\n\tclose(value?: unknown): void {\n\t\tif (!this.#isOpen) return\n\n\t\tthis.#isOpen = false\n\t\tthis.#isAnimating = false\n\t\tthis.#animationProgress = 0\n\n\t\tfor (const listener of this.#listeners.close) {\n\t\t\ttry {\n\t\t\t\tlistener(value)\n\t\t\t} catch {\n\t\t\t\t// Ignore errors in listeners\n\t\t\t}\n\t\t}\n\n\t\tthis.#resolvePromise?.(value)\n\t\tthis.#resolvePromise = undefined\n\t}\n\n\tclickButton(buttonIndex: number): void {\n\t\tconst button = this.#buttons[buttonIndex]\n\t\tif (!button) return\n\n\t\tfor (const listener of this.#listeners.buttonClick) {\n\t\t\ttry {\n\t\t\t\tlistener(button.value)\n\t\t\t} catch {\n\t\t\t\t// Ignore errors in listeners\n\t\t\t}\n\t\t}\n\n\t\tif (button.closeOnClick) {\n\t\t\tthis.close(button.value)\n\t\t}\n\t}\n\n\t// =========================================================================\n\t// Update & Render\n\t// =========================================================================\n\n\tupdate(inputState: InputState): void {\n\t\tif (!this.#isOpen) return\n\n\t\t// Update animation\n\t\tif (this.#isAnimating) {\n\t\t\tconst animationSpeed = 1 / ((this.#options.animationDuration ?? 200) / 16.67)\n\t\t\tthis.#animationProgress = Math.min(1, this.#animationProgress + animationSpeed)\n\t\t\tif (this.#animationProgress >= 1) {\n\t\t\t\tthis.#isAnimating = false\n\t\t\t}\n\t\t}\n\n\t\t// Check for backdrop click (close when clicking outside modal)\n\t\tif (this.#options.closeOnBackdrop && inputState.isPointerDown && !this.#isAnimating) {\n\t\t\tconst modalWidth = this.#options.width ?? 400\n\t\t\tconst modalHeight = this.#options.height ?? 200\n\t\t\tconst canvasWidth = inputState.canvasWidth ?? 800\n\t\t\tconst canvasHeight = inputState.canvasHeight ?? 600\n\t\t\tconst modalX = canvasWidth / 2 - modalWidth / 2\n\t\t\tconst modalY = canvasHeight / 2 - modalHeight / 2\n\n\t\t\tconst isOutsideModal =\n\t\t\t\tinputState.pointerX < modalX ||\n\t\t\t\tinputState.pointerX > modalX + modalWidth ||\n\t\t\t\tinputState.pointerY < modalY ||\n\t\t\t\tinputState.pointerY > modalY + modalHeight\n\n\t\t\tif (isOutsideModal) {\n\t\t\t\tthis.close()\n\t\t\t}\n\t\t}\n\n\t\t// Check for button clicks\n\t\tif (inputState.isPointerDown && !inputState.wasPointerDown) {\n\t\t\tthis.#checkButtonClick(inputState)\n\t\t}\n\t}\n\n\t#checkButtonClick(inputState: InputState): void {\n\t\tconst canvasWidth = inputState.canvasWidth ?? 800\n\t\tconst canvasHeight = inputState.canvasHeight ?? 600\n\t\tconst modalHeight = this.#options.height ?? 200\n\t\tconst modalY = (canvasHeight - modalHeight) / 2\n\t\tconst buttonY = modalY + modalHeight - 60\n\t\tconst buttonWidth = 100\n\t\tconst buttonHeight = 40\n\t\tconst buttonSpacing = 20\n\n\t\tconst totalButtonWidth = this.#buttons.length * buttonWidth + (this.#buttons.length - 1) * buttonSpacing\n\t\tlet buttonX = (canvasWidth - totalButtonWidth) / 2\n\n\t\tfor (let i = 0; i < this.#buttons.length; i++) {\n\t\t\tif (\n\t\t\t\tinputState.pointerX >= buttonX &&\n\t\t\t\tinputState.pointerX <= buttonX + buttonWidth &&\n\t\t\t\tinputState.pointerY >= buttonY &&\n\t\t\t\tinputState.pointerY <= buttonY + buttonHeight\n\t\t\t) {\n\t\t\t\tthis.clickButton(i)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tbuttonX += buttonWidth + buttonSpacing\n\t\t}\n\t}\n\n\trender(context: CanvasRenderingContext2D): void {\n\t\tif (!this.#isOpen) return\n\n\t\tconst width = context.canvas.width\n\t\tconst height = context.canvas.height\n\t\tconst modalWidth = this.#options.width ?? 400\n\t\tconst modalHeight = this.#options.height ?? 200\n\t\tconst x = (width - modalWidth) / 2\n\t\tconst y = (height - modalHeight) / 2\n\n\t\tconst progress = this.#animationProgress\n\t\tconst scale = this.#options.animation === 'scale' ? 0.9 + progress * 0.1 : 1\n\t\tconst opacity = this.#options.animation === 'none' ? 1 : progress\n\n\t\tcontext.save()\n\n\t\t// Draw backdrop\n\t\tcontext.globalAlpha = opacity * 0.5\n\t\tcontext.fillStyle = this.#options.backdropColor ?? 'rgba(0,0,0,0.8)'\n\t\tcontext.fillRect(0, 0, width, height)\n\n\t\t// Draw modal\n\t\tcontext.globalAlpha = opacity\n\t\tcontext.translate(width / 2, height / 2)\n\t\tcontext.scale(scale, scale)\n\t\tcontext.translate(-width / 2, -height / 2)\n\n\t\t// Background\n\t\tcontext.fillStyle = this.#options.backgroundColor ?? '#ffffff'\n\t\tconst borderRadius = this.#options.borderRadius ?? 8\n\t\tthis.#roundRect(context, x, y, modalWidth, modalHeight, borderRadius)\n\t\tcontext.fill()\n\n\t\t// Title\n\t\tif (this.#title) {\n\t\t\tcontext.fillStyle = '#000000'\n\t\t\tcontext.font = 'bold 18px sans-serif'\n\t\t\tcontext.textAlign = 'center'\n\t\t\tcontext.textBaseline = 'top'\n\t\t\tcontext.fillText(this.#title, width / 2, y + 20)\n\t\t}\n\n\t\t// Content\n\t\tif (this.#content) {\n\t\t\tcontext.fillStyle = '#333333'\n\t\t\tcontext.font = '14px sans-serif'\n\t\t\tcontext.textAlign = 'center'\n\t\t\tcontext.textBaseline = 'top'\n\t\t\tcontext.fillText(this.#content, width / 2, y + 60, modalWidth - 40)\n\t\t}\n\n\t\t// Buttons\n\t\tthis.#renderButtons(context, x, y, modalWidth, modalHeight)\n\n\t\tcontext.restore()\n\t}\n\n\t#renderButtons(\n\t\tcontext: CanvasRenderingContext2D,\n\t\t_modalX: number,\n\t\tmodalY: number,\n\t\t_modalWidth: number,\n\t\tmodalHeight: number,\n\t): void {\n\t\tconst width = context.canvas.width\n\t\tconst buttonY = modalY + modalHeight - 60\n\t\tconst buttonWidth = 100\n\t\tconst buttonHeight = 40\n\t\tconst buttonSpacing = 20\n\n\t\tconst totalButtonWidth = this.#buttons.length * buttonWidth + (this.#buttons.length - 1) * buttonSpacing\n\t\tlet buttonX = (width - totalButtonWidth) / 2\n\n\t\tfor (const button of this.#buttons) {\n\t\t\tlet bgColor = '#4CAF50'\n\t\t\tif (button.style === 'secondary') bgColor = '#9E9E9E'\n\t\t\tif (button.style === 'danger') bgColor = '#F44336'\n\n\t\t\tcontext.fillStyle = bgColor\n\t\t\tthis.#roundRect(context, buttonX, buttonY, buttonWidth, buttonHeight, 4)\n\t\t\tcontext.fill()\n\n\t\t\tcontext.fillStyle = '#FFFFFF'\n\t\t\tcontext.font = '14px sans-serif'\n\t\t\tcontext.textAlign = 'center'\n\t\t\tcontext.textBaseline = 'middle'\n\t\t\tcontext.fillText(button.text, buttonX + buttonWidth / 2, buttonY + buttonHeight / 2)\n\n\t\t\tbuttonX += buttonWidth + buttonSpacing\n\t\t}\n\t}\n\n\t#roundRect(\n\t\tctx: CanvasRenderingContext2D,\n\t\tx: number,\n\t\ty: number,\n\t\tw: number,\n\t\th: number,\n\t\tr: number,\n\t): void {\n\t\tctx.beginPath()\n\t\tctx.moveTo(x + r, y)\n\t\tctx.lineTo(x + w - r, y)\n\t\tctx.quadraticCurveTo(x + w, y, x + w, y + r)\n\t\tctx.lineTo(x + w, y + h - r)\n\t\tctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h)\n\t\tctx.lineTo(x + r, y + h)\n\t\tctx.quadraticCurveTo(x, y + h, x, y + h - r)\n\t\tctx.lineTo(x, y + r)\n\t\tctx.quadraticCurveTo(x, y, x + r, y)\n\t\tctx.closePath()\n\t}\n\n\t// =========================================================================\n\t// Event Subscriptions\n\t// =========================================================================\n\n\tonOpen(callback: () => void): Unsubscribe {\n\t\tthis.#listeners.open.add(callback)\n\t\treturn () => this.#listeners.open.delete(callback)\n\t}\n\n\tonClose(callback: (value: unknown) => void): Unsubscribe {\n\t\tthis.#listeners.close.add(callback)\n\t\treturn () => this.#listeners.close.delete(callback)\n\t}\n\n\tonButtonClick(callback: (value: unknown) => void): Unsubscribe {\n\t\tthis.#listeners.buttonClick.add(callback)\n\t\treturn () => this.#listeners.buttonClick.delete(callback)\n\t}\n\n\t// =========================================================================\n\t// Internal Methods (for ModalManager)\n\t// =========================================================================\n\n\t/** @internal - Used by ModalManager for promise-based dialogs */\n\tsetResolvePromise(resolve: (value: unknown) => void): void {\n\t\tthis.#resolvePromise = resolve\n\t}\n\n\t// =========================================================================\n\t// Lifecycle\n\t// =========================================================================\n\n\tdestroy(): void {\n\t\tthis.close()\n\t\tthis.#listeners.open.clear()\n\t\tthis.#listeners.close.clear()\n\t\tthis.#listeners.buttonClick.clear()\n\t}\n}\n","/**\r\n * ModalManager - Manages modal dialogs for confirmations, alerts, and prompts.\r\n *\r\n * Features:\r\n * - Backdrop (dimmed, blocks interaction)\r\n * - Built-in alert/confirm/prompt\r\n * - Animation support\r\n * - Stacking (modal over modal)\r\n */\r\nimport type {\r\n\tModalManagerInterface,\r\n\tModalManagerOptions,\r\n\tModalInterface,\r\n\tModalOptions,\r\n\tInputState,\r\n} from '../../types.js'\r\nimport { Modal } from './Modal.js'\r\n\r\n/**\r\n * Modal manager implementation.\r\n *\r\n * @example\r\n * ```ts\r\n * const modals = createModalManager()\r\n *\r\n * // Create and show a modal\r\n * const modal = modals.createModal({\r\n * title: 'Hello',\r\n * content: 'Welcome to the game!',\r\n * buttons: [{ text: 'OK', value: true, style: 'primary', closeOnClick: true }],\r\n * })\r\n * modal.open()\r\n *\r\n * // Or use convenience methods\r\n * const confirmed = await modals.confirm('Are you sure?', 'Confirm Action')\r\n * ```\r\n */\r\nexport class ModalManager implements ModalManagerInterface {\r\n\treadonly #modals: Modal[] = []\r\n\treadonly #stack: Modal[] = []\r\n\treadonly #defaultBackdropColor: string\r\n\treadonly #defaultAnimation: 'fade' | 'scale' | 'slide-up' | 'none'\r\n\treadonly #stackModals: boolean\r\n\r\n\tconstructor(options?: ModalManagerOptions) {\r\n\t\tthis.#defaultBackdropColor = options?.defaultBackdropColor ?? 'rgba(0,0,0,0.8)'\r\n\t\tthis.#defaultAnimation = options?.defaultAnimation ?? 'scale'\r\n\t\tthis.#stackModals = options?.stackModals ?? true\r\n\t}\r\n\r\n\t// =========================================================================\r\n\t// Modal Creation\r\n\t// =========================================================================\r\n\r\n\tcreateModal(options: ModalOptions): ModalInterface {\r\n\t\tconst modal = new Modal({\r\n\t\t\t...options,\r\n\t\t\tbackdropColor: options.backdropColor ?? this.#defaultBackdropColor,\r\n\t\t\tanimation: options.animation ?? this.#defaultAnimation,\r\n\t\t})\r\n\t\tthis.#modals.push(modal)\r\n\r\n\t\t// Auto-add to stack when opened\r\n\t\tmodal.onOpen(() => {\r\n\t\t\tif (this.#stackModals || this.#stack.length === 0) {\r\n\t\t\t\tif (!this.#stack.includes(modal)) {\r\n\t\t\t\t\tthis.#stack.push(modal)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t})\r\n\r\n\t\t// Auto-remove from stack when closed\r\n\t\tmodal.onClose(() => {\r\n\t\t\tconst index = this.#stack.indexOf(modal)\r\n\t\t\tif (index >= 0) {\r\n\t\t\t\tthis.#stack.splice(index, 1)\r\n\t\t\t}\r\n\t\t})\r\n\r\n\t\treturn modal\r\n\t}\r\n\r\n\t// =========================================================================\r\n\t// Accessors\r\n\t// =========================================================================\r\n\r\n\tgetActiveModal(): ModalInterface | undefined {\r\n\t\treturn this.#stack[this.#stack.length - 1]\r\n\t}\r\n\r\n\tgetModalStack(): readonly ModalInterface[] {\r\n\t\treturn [...this.#stack]\r\n\t}\r\n\r\n\thasOpenModals(): boolean {\r\n\t\treturn this.#stack.length > 0\r\n\t}\r\n\r\n\t// =========================================================================\r\n\t// Convenience Methods\r\n\t// =========================================================================\r\n\r\n\tasync alert(message: string, title?: string): Promise<void> {\r\n\t\treturn new Promise((resolve) => {\r\n\t\t\tconst opts: ModalOptions = {\r\n\t\t\t\tcontent: message,\r\n\t\t\t\tbuttons: [{ text: 'OK', value: true, style: 'primary', closeOnClick: true }],\r\n\t\t\t}\r\n\t\t\tconst modal = this.createModal(\r\n\t\t\t\ttitle !== undefined ? { ...opts, title } : opts,\r\n\t\t\t) as Modal\r\n\r\n\t\t\tmodal.setResolvePromise(() => resolve())\r\n\t\t\tmodal.open()\r\n\t\t})\r\n\t}\r\n\r\n\tasync confirm(message: string, title?: string): Promise<boolean> {\r\n\t\treturn new Promise((resolve) => {\r\n\t\t\tconst opts: ModalOptions = {\r\n\t\t\t\tcontent: message,\r\n\t\t\t\tbuttons: [\r\n\t\t\t\t\t{ text: 'Cancel', value: false, style: 'secondary', closeOnClick: true },\r\n\t\t\t\t\t{ text: 'OK', value: true, style: 'primary', closeOnClick: true },\r\n\t\t\t\t],\r\n\t\t\t}\r\n\t\t\tconst modal = this.createModal(\r\n\t\t\t\ttitle !== undefined ? { ...opts, title } : opts,\r\n\t\t\t) as Modal\r\n\r\n\t\t\tmodal.setResolvePromise((value) => resolve(value === true))\r\n\t\t\tmodal.open()\r\n\t\t})\r\n\t}\r\n\r\n\tasync prompt(message: string, defaultValue?: string, title?: string): Promise<string | undefined> {\r\n\t\treturn new Promise((resolve) => {\r\n\t\t\tconst opts: ModalOptions = {\r\n\t\t\t\tcontent: message,\r\n\t\t\t\tbuttons: [\r\n\t\t\t\t\t{ text: 'Cancel', value: null, style: 'secondary', closeOnClick: true },\r\n\t\t\t\t\t{ text: 'OK', value: defaultValue ?? '', style: 'primary', closeOnClick: true },\r\n\t\t\t\t],\r\n\t\t\t}\r\n\t\t\tconst modal = this.createModal(\r\n\t\t\t\ttitle !== undefined ? { ...opts, title } : opts,\r\n\t\t\t) as Modal\r\n\r\n\t\t\tmodal.setResolvePromise((value) => resolve(value === null ? undefined : value as string))\r\n\t\t\tmodal.open()\r\n\t\t})\r\n\t}\r\n\r\n\t// =========================================================================\r\n\t// Actions\r\n\t// =========================================================================\r\n\r\n\tcloseAll(): void {\r\n\t\t// Close in reverse order (top to bottom)\r\n\t\tfor (let i = this.#stack.length - 1; i >= 0; i--) {\r\n\t\t\tthis.#stack[i]?.close()\r\n\t\t}\r\n\t}\r\n\r\n\t// =========================================================================\r\n\t// Update & Render\r\n\t// =========================================================================\r\n\r\n\tupdate(inputState: InputState): void {\r\n\t\t// Only update the topmost modal\r\n\t\tconst activeModal = this.#stack[this.#stack.length - 1]\r\n\t\tif (activeModal) {\r\n\t\t\tactiveModal.update(inputState)\r\n\t\t}\r\n\t}\r\n\r\n\trender(context: CanvasRenderingContext2D): void {\r\n\t\t// Render all modals in stack order (bottom to top)\r\n\t\tfor (const modal of this.#stack) {\r\n\t\t\tmodal.render(context)\r\n\t\t}\r\n\t}\r\n\r\n\t// =========================================================================\r\n\t// Lifecycle\r\n\t// =========================================================================\r\n\r\n\tdestroy(): void {\r\n\t\tfor (const modal of this.#modals) {\r\n\t\t\tmodal.destroy()\r\n\t\t}\r\n\t\tthis.#modals.length = 0\r\n\t\tthis.#stack.length = 0\r\n\t}\r\n}\r\n","/**\r\n * ScreenshotManager - Manages screenshot capture for save previews.\r\n *\r\n * Features:\r\n * - Capture canvas to data URL\r\n * - Resize to thumbnail\r\n * - Download and clipboard support\r\n */\r\nimport type {\r\n\tScreenshotManagerInterface,\r\n\tScreenshotOptions,\r\n\tScreenshotResult,\r\n\tScreenshotFormat,\r\n\tRectangle,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Game screenshot manager implementation.\r\n */\r\nexport class ScreenshotManager implements ScreenshotManagerInterface {\r\n\treadonly #canvas: HTMLCanvasElement\r\n\r\n\tconstructor(canvas: HTMLCanvasElement) {\r\n\t\tthis.#canvas = canvas\r\n\t}\r\n\r\n\tasync capture(options?: ScreenshotOptions): Promise<ScreenshotResult> {\r\n\t\tconst format = options?.format ?? 'png'\r\n\t\tconst quality = options?.quality ?? 0.92\r\n\t\tconst mimeType = this.#getMimeType(format)\r\n\r\n\t\tlet sourceCanvas = this.#canvas\r\n\t\tconst width = options?.width ?? this.#canvas.width\r\n\t\tconst height = options?.height ?? this.#canvas.height\r\n\r\n\t\t// Resize if needed\r\n\t\tif (width !== this.#canvas.width || height !== this.#canvas.height) {\r\n\t\t\tsourceCanvas = this.#resizeCanvas(this.#canvas, width, height)\r\n\t\t}\r\n\r\n\t\tconst dataUrl = sourceCanvas.toDataURL(mimeType, quality)\r\n\t\tconst size = this.#estimateSize(dataUrl)\r\n\r\n\t\treturn {\r\n\t\t\tdataUrl,\r\n\t\t\twidth,\r\n\t\t\theight,\r\n\t\t\tformat,\r\n\t\t\tsize,\r\n\t\t\ttimestamp: Date.now(),\r\n\t\t}\r\n\t}\r\n\r\n\tasync captureRegion(rect: Rectangle, options?: ScreenshotOptions): Promise<ScreenshotResult> {\r\n\t\tconst format = options?.format ?? 'png'\r\n\t\tconst quality = options?.quality ?? 0.92\r\n\t\tconst mimeType = this.#getMimeType(format)\r\n\r\n\t\tconst width = options?.width ?? rect.width\r\n\t\tconst height = options?.height ?? rect.height\r\n\r\n\t\t// Create a canvas for the region\r\n\t\tconst regionCanvas = document.createElement('canvas')\r\n\t\tregionCanvas.width = width\r\n\t\tregionCanvas.height = height\r\n\r\n\t\tconst ctx = regionCanvas.getContext('2d')\r\n\t\tif (!ctx) {\r\n\t\t\tthrow new Error('Failed to get canvas context')\r\n\t\t}\r\n\r\n\t\t// Draw the region\r\n\t\tctx.drawImage(\r\n\t\t\tthis.#canvas,\r\n\t\t\trect.x,\r\n\t\t\trect.y,\r\n\t\t\trect.width,\r\n\t\t\trect.height,\r\n\t\t\t0,\r\n\t\t\t0,\r\n\t\t\twidth,\r\n\t\t\theight,\r\n\t\t)\r\n\r\n\t\tconst dataUrl = regionCanvas.toDataURL(mimeType, quality)\r\n\t\tconst size = this.#estimateSize(dataUrl)\r\n\r\n\t\treturn {\r\n\t\t\tdataUrl,\r\n\t\t\twidth,\r\n\t\t\theight,\r\n\t\t\tformat,\r\n\t\t\tsize,\r\n\t\t\ttimestamp: Date.now(),\r\n\t\t}\r\n\t}\r\n\r\n\tasync captureThumbnail(width: number, height: number): Promise<string> {\r\n\t\tconst result = await this.capture({ width, height, format: 'jpeg', quality: 0.7 })\r\n\t\treturn result.dataUrl\r\n\t}\r\n\r\n\tasync download(filename: string, options?: ScreenshotOptions): Promise<void> {\r\n\t\tconst result = await this.capture(options)\r\n\r\n\t\tconst link = document.createElement('a')\r\n\t\tlink.download = filename\r\n\t\tlink.href = result.dataUrl\r\n\t\tlink.click()\r\n\t}\r\n\r\n\tasync copyToClipboard(options?: ScreenshotOptions): Promise<void> {\r\n\t\t// Only PNG is supported for clipboard\r\n\t\tconst result = await this.capture({ ...options, format: 'png' })\r\n\r\n\t\t// Convert data URL to blob\r\n\t\tconst response = await fetch(result.dataUrl)\r\n\t\tconst blob = await response.blob()\r\n\r\n\t\t// Use Clipboard API if available\r\n\t\tif (navigator.clipboard && typeof ClipboardItem !== 'undefined') {\r\n\t\t\tawait navigator.clipboard.write([\r\n\t\t\t\tnew ClipboardItem({\r\n\t\t\t\t\t[blob.type]: blob,\r\n\t\t\t\t}),\r\n\t\t\t])\r\n\t\t} else {\r\n\t\t\tthrow new Error('Clipboard API not supported')\r\n\t\t}\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\t// Nothing to clean up\r\n\t}\r\n\r\n\t#getMimeType(format: ScreenshotFormat): string {\r\n\t\tswitch (format) {\r\n\t\t\tcase 'jpeg':\r\n\t\t\t\treturn 'image/jpeg'\r\n\t\t\tcase 'webp':\r\n\t\t\t\treturn 'image/webp'\r\n\t\t\tcase 'png':\r\n\t\t\tdefault:\r\n\t\t\t\treturn 'image/png'\r\n\t\t}\r\n\t}\r\n\r\n\t#resizeCanvas(source: HTMLCanvasElement, width: number, height: number): HTMLCanvasElement {\r\n\t\tconst resized = document.createElement('canvas')\r\n\t\tresized.width = width\r\n\t\tresized.height = height\r\n\r\n\t\tconst ctx = resized.getContext('2d')\r\n\t\tif (ctx) {\r\n\t\t\tctx.drawImage(source, 0, 0, source.width, source.height, 0, 0, width, height)\r\n\t\t}\r\n\r\n\t\treturn resized\r\n\t}\r\n\r\n\t#estimateSize(dataUrl: string): number {\r\n\t\t// Data URL format: data:image/png;base64,....\r\n\t\t// Base64 increases size by ~33%\r\n\t\tconst base64Part = dataUrl.split(',')[1]\r\n\t\tif (!base64Part) return 0\r\n\r\n\t\treturn Math.round((base64Part.length * 3) / 4)\r\n\t}\r\n}\r\n","/**\r\n * FrameBudget - Tracks frame timing and budget for performance monitoring.\r\n *\r\n * Features:\r\n * - Track frame time vs target\r\n * - Phase-based timing breakdown\r\n * - Budget exceeded warnings\r\n */\r\nimport type {\r\n\tFrameBudgetInterface,\r\n\tFrameBudgetOptions,\r\n\tFrameBudgetState,\r\n\tFrameTiming,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Game frame budget implementation.\r\n */\r\nexport class FrameBudget implements FrameBudgetInterface {\r\n\treadonly #targetFPS: number\r\n\treadonly #targetMs: number\r\n\treadonly #warningThreshold: number\r\n\treadonly #criticalThreshold: number\r\n\treadonly #historySize: number\r\n\treadonly #history: number[] = []\r\n\treadonly #overBudgetListeners = new Set<(timing: FrameTiming) => void>()\r\n\treadonly #criticalListeners = new Set<(timing: FrameTiming) => void>()\r\n\treadonly #recoverListeners = new Set<() => void>()\r\n\r\n\t#frameStart = 0\r\n\t#phaseStarts: Record<string, number> = {}\r\n\t#phaseTimes: Record<string, number> = {\r\n\t\tupdate: 0,\r\n\t\tphysics: 0,\r\n\t\trender: 0,\r\n\t\tui: 0,\r\n\t}\r\n\t#lastFrameMs = 0\r\n\t#wasOverBudget = false\r\n\t#wasCritical = false\r\n\r\n\tconstructor(options?: FrameBudgetOptions) {\r\n\t\tthis.#targetFPS = options?.targetFPS ?? 60\r\n\t\tthis.#targetMs = 1000 / this.#targetFPS\r\n\t\tthis.#warningThreshold = options?.warningThreshold ?? 1.2\r\n\t\tthis.#criticalThreshold = options?.criticalThreshold ?? 1.5\r\n\t\tthis.#historySize = options?.trackHistory ?? 60\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// State\r\n\t// ============================================================================\r\n\r\n\tgetState(): FrameBudgetState {\r\n\t\treturn {\r\n\t\t\ttargetMs: this.#targetMs,\r\n\t\t\tlastFrameMs: this.#lastFrameMs,\r\n\t\t\taverageFrameMs: this.getAverageMs(),\r\n\t\t\tisOverBudget: this.isOverBudget(),\r\n\t\t\tisCritical: this.isCritical(),\r\n\t\t\ttiming: this.getTiming(),\r\n\t\t\thistory: [...this.#history],\r\n\t\t}\r\n\t}\r\n\r\n\tgetTargetMs(): number {\r\n\t\treturn this.#targetMs\r\n\t}\r\n\r\n\tgetAverageMs(): number {\r\n\t\tif (this.#history.length === 0) return 0\r\n\t\tconst sum = this.#history.reduce((a, b) => a + b, 0)\r\n\t\treturn sum / this.#history.length\r\n\t}\r\n\r\n\tisOverBudget(): boolean {\r\n\t\treturn this.#lastFrameMs > this.#targetMs * this.#warningThreshold\r\n\t}\r\n\r\n\tisCritical(): boolean {\r\n\t\treturn this.#lastFrameMs > this.#targetMs * this.#criticalThreshold\r\n\t}\r\n\r\n\tgetTiming(): FrameTiming {\r\n\t\tconst total = this.#lastFrameMs\r\n\t\tconst update = this.#phaseTimes['update'] ?? 0\r\n\t\tconst physics = this.#phaseTimes['physics'] ?? 0\r\n\t\tconst render = this.#phaseTimes['render'] ?? 0\r\n\t\tconst ui = this.#phaseTimes['ui'] ?? 0\r\n\t\tconst idle = Math.max(0, total - update - physics - render - ui)\r\n\r\n\t\treturn { total, update, physics, render, ui, idle }\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Frame Tracking\r\n\t// ============================================================================\r\n\r\n\tstartFrame(): void {\r\n\t\tthis.#frameStart = performance.now()\r\n\t\tthis.#phaseTimes = {\r\n\t\t\tupdate: 0,\r\n\t\t\tphysics: 0,\r\n\t\t\trender: 0,\r\n\t\t\tui: 0,\r\n\t\t}\r\n\t\tthis.#phaseStarts = {}\r\n\t}\r\n\r\n\tstartPhase(phase: keyof Omit<FrameTiming, 'total' | 'idle'>): void {\r\n\t\tthis.#phaseStarts[phase] = performance.now()\r\n\t}\r\n\r\n\tendPhase(phase: keyof Omit<FrameTiming, 'total' | 'idle'>): void {\r\n\t\tconst start = this.#phaseStarts[phase]\r\n\t\tif (start !== undefined) {\r\n\t\t\tthis.#phaseTimes[phase] = performance.now() - start\r\n\t\t}\r\n\t}\r\n\r\n\tendFrame(): void {\r\n\t\tthis.#lastFrameMs = performance.now() - this.#frameStart\r\n\r\n\t\t// Update history\r\n\t\tthis.#history.push(this.#lastFrameMs)\r\n\t\tif (this.#history.length > this.#historySize) {\r\n\t\t\tthis.#history.shift()\r\n\t\t}\r\n\r\n\t\t// Check thresholds\r\n\t\tconst isOverBudget = this.isOverBudget()\r\n\t\tconst isCritical = this.isCritical()\r\n\t\tconst timing = this.getTiming()\r\n\r\n\t\tif (isCritical && !this.#wasCritical) {\r\n\t\t\tthis.#notifyCritical(timing)\r\n\t\t} else if (isOverBudget && !this.#wasOverBudget && !isCritical) {\r\n\t\t\tthis.#notifyOverBudget(timing)\r\n\t\t} else if (!isOverBudget && (this.#wasOverBudget || this.#wasCritical)) {\r\n\t\t\tthis.#notifyRecover()\r\n\t\t}\r\n\r\n\t\tthis.#wasOverBudget = isOverBudget\r\n\t\tthis.#wasCritical = isCritical\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Reset\r\n\t// ============================================================================\r\n\r\n\treset(): void {\r\n\t\tthis.#history.length = 0\r\n\t\tthis.#lastFrameMs = 0\r\n\t\tthis.#wasOverBudget = false\r\n\t\tthis.#wasCritical = false\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Subscriptions\r\n\t// ============================================================================\r\n\r\n\tonOverBudget(callback: (timing: FrameTiming) => void): Unsubscribe {\r\n\t\tthis.#overBudgetListeners.add(callback)\r\n\t\treturn () => this.#overBudgetListeners.delete(callback)\r\n\t}\r\n\r\n\tonCritical(callback: (timing: FrameTiming) => void): Unsubscribe {\r\n\t\tthis.#criticalListeners.add(callback)\r\n\t\treturn () => this.#criticalListeners.delete(callback)\r\n\t}\r\n\r\n\tonRecover(callback: () => void): Unsubscribe {\r\n\t\tthis.#recoverListeners.add(callback)\r\n\t\treturn () => this.#recoverListeners.delete(callback)\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Private Methods\r\n\t// ============================================================================\r\n\r\n\t#notifyOverBudget(timing: FrameTiming): void {\r\n\t\tfor (const listener of this.#overBudgetListeners) {\r\n\t\t\ttry {\r\n\t\t\t\tlistener(timing)\r\n\t\t\t} catch {\r\n\t\t\t\t// Ignore\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t#notifyCritical(timing: FrameTiming): void {\r\n\t\tfor (const listener of this.#criticalListeners) {\r\n\t\t\ttry {\r\n\t\t\t\tlistener(timing)\r\n\t\t\t} catch {\r\n\t\t\t\t// Ignore\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t#notifyRecover(): void {\r\n\t\tfor (const listener of this.#recoverListeners) {\r\n\t\t\ttry {\r\n\t\t\t\tlistener()\r\n\t\t\t} catch {\r\n\t\t\t\t// Ignore\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Lifecycle\r\n\t// ============================================================================\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#overBudgetListeners.clear()\r\n\t\tthis.#criticalListeners.clear()\r\n\t\tthis.#recoverListeners.clear()\r\n\t\tthis.#history.length = 0\r\n\t}\r\n}\r\n","import type {\r\n\tVirtualJoystickInterface,\r\n\tVirtualJoystickOptions,\r\n\tVirtualJoystickState,\r\n\tVector2,\r\n\tUnsubscribe,\r\n\tInputState,\r\n\tUIBounds,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Canvas-based virtual joystick for mobile input.\r\n */\r\nexport class VirtualJoystick implements VirtualJoystickInterface {\r\n\treadonly id: string\r\n\r\n\t#x: number\r\n\t#y: number\r\n\t#width: number\r\n\t#height: number\r\n\t#visible: boolean\r\n\t#interactive: boolean\r\n\t#zIndex: number\r\n\t#opacity: number\r\n\r\n\t#innerRadius: number\r\n\t#outerRadius: number\r\n\t#deadZone: number\r\n\t#fixed: boolean\r\n\t#autoHide: boolean\r\n\t#hideDelay: number\r\n\t#innerColor: string\r\n\t#outerColor: string\r\n\t#borderColor: string\r\n\t#borderWidth: number\r\n\r\n\t#isActive = false\r\n\t#touchId: number | null = null\r\n\t#centerX: number\r\n\t#centerY: number\r\n\t#knobX: number\r\n\t#knobY: number\r\n\t#direction: Vector2 = { x: 0, y: 0 }\r\n\t#magnitude = 0\r\n\t#angle = 0\r\n\r\n\t#hideTimer = 0\r\n\t#displayOpacity = 1\r\n\r\n\t#moveListeners = new Set<(direction: Vector2, magnitude: number) => void>()\r\n\t#pressListeners = new Set<() => void>()\r\n\t#releaseListeners = new Set<() => void>()\r\n\r\n\tconstructor(options: VirtualJoystickOptions) {\r\n\t\tthis.id = crypto.randomUUID()\r\n\t\tthis.#x = options.x\r\n\t\tthis.#y = options.y\r\n\t\tthis.#width = options.width\r\n\t\tthis.#height = options.height\r\n\t\tthis.#visible = options.visible ?? true\r\n\t\tthis.#interactive = options.interactive ?? true\r\n\t\tthis.#zIndex = options.zIndex ?? 0\r\n\t\tthis.#opacity = options.opacity ?? 1\r\n\r\n\t\tthis.#innerRadius = options.innerRadius\r\n\t\tthis.#outerRadius = options.outerRadius\r\n\t\tthis.#deadZone = options.deadZone ?? 0.1\r\n\t\tthis.#fixed = options.fixed ?? true\r\n\t\tthis.#autoHide = options.autoHide ?? false\r\n\t\tthis.#hideDelay = options.hideDelay ?? 1000\r\n\t\tthis.#innerColor = options.innerColor ?? 'rgba(255, 255, 255, 0.8)'\r\n\t\tthis.#outerColor = options.outerColor ?? 'rgba(255, 255, 255, 0.3)'\r\n\t\tthis.#borderColor = options.borderColor ?? 'rgba(255, 255, 255, 0.5)'\r\n\t\tthis.#borderWidth = options.borderWidth ?? 2\r\n\r\n\t\tthis.#centerX = this.#x + this.#outerRadius\r\n\t\tthis.#centerY = this.#y + this.#outerRadius\r\n\t\tthis.#knobX = this.#centerX\r\n\t\tthis.#knobY = this.#centerY\r\n\r\n\t\t// Register hooks from options\r\n\t\tif (options.onMove) this.#moveListeners.add(options.onMove)\r\n\t\tif (options.onPress) this.#pressListeners.add(options.onPress)\r\n\t\tif (options.onRelease) this.#releaseListeners.add(options.onRelease)\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Visibility\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tisVisible(): boolean {\r\n\t\treturn this.#visible\r\n\t}\r\n\r\n\tsetVisible(visible: boolean): void {\r\n\t\tthis.#visible = visible\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Position accessors\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetX(): number {\r\n\t\treturn this.#x\r\n\t}\r\n\r\n\tgetY(): number {\r\n\t\treturn this.#y\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Position mutators\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetX(x: number): void {\r\n\t\tthis.#x = x\r\n\t\tthis.#centerX = this.#x + this.#outerRadius\r\n\t\tif (!this.#isActive) {\r\n\t\t\tthis.#knobX = this.#centerX\r\n\t\t}\r\n\t}\r\n\r\n\tsetY(y: number): void {\r\n\t\tthis.#y = y\r\n\t\tthis.#centerY = this.#y + this.#outerRadius\r\n\t\tif (!this.#isActive) {\r\n\t\t\tthis.#knobY = this.#centerY\r\n\t\t}\r\n\t}\r\n\r\n\tsetPosition(x: number, y: number): void {\r\n\t\tthis.#x = x\r\n\t\tthis.#y = y\r\n\t\tthis.#centerX = this.#x + this.#outerRadius\r\n\t\tthis.#centerY = this.#y + this.#outerRadius\r\n\t\tif (!this.#isActive) {\r\n\t\t\tthis.#knobX = this.#centerX\r\n\t\t\tthis.#knobY = this.#centerY\r\n\t\t}\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Size accessors\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetWidth(): number {\r\n\t\treturn this.#width\r\n\t}\r\n\r\n\tgetHeight(): number {\r\n\t\treturn this.#height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Size mutators\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetWidth(width: number): void {\r\n\t\tthis.#width = width\r\n\t}\r\n\r\n\tsetHeight(height: number): void {\r\n\t\tthis.#height = height\r\n\t}\r\n\r\n\tsetSize(width: number, height: number): void {\r\n\t\tthis.#width = width\r\n\t\tthis.#height = height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Bounds and hit testing\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetBounds(): UIBounds {\r\n\t\treturn {\r\n\t\t\tx: this.#x,\r\n\t\t\ty: this.#y,\r\n\t\t\twidth: this.#width,\r\n\t\t\theight: this.#height,\r\n\t\t}\r\n\t}\r\n\r\n\tcontains(x: number, y: number): boolean {\r\n\t\tconst dx = x - this.#centerX\r\n\t\tconst dy = y - this.#centerY\r\n\t\treturn Math.sqrt(dx * dx + dy * dy) <= this.#outerRadius\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Z-Index\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetZIndex(): number {\r\n\t\treturn this.#zIndex\r\n\t}\r\n\r\n\tsetZIndex(zIndex: number): void {\r\n\t\tthis.#zIndex = zIndex\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Opacity\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetOpacity(): number {\r\n\t\treturn this.#opacity\r\n\t}\r\n\r\n\tsetOpacity(opacity: number): void {\r\n\t\tthis.#opacity = Math.max(0, Math.min(1, opacity))\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// InteractiveUIElement: Interactivity\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tisInteractive(): boolean {\r\n\t\treturn this.#interactive\r\n\t}\r\n\r\n\tsetInteractive(interactive: boolean): void {\r\n\t\tthis.#interactive = interactive\r\n\t\tif (!interactive) {\r\n\t\t\tthis.reset()\r\n\t\t}\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// VirtualJoystickSubscriptions Implementation\r\n\t// ============================================================================\r\n\r\n\tonMove(callback: (direction: Vector2, magnitude: number) => void): Unsubscribe {\r\n\t\tthis.#moveListeners.add(callback)\r\n\t\treturn () => this.#moveListeners.delete(callback)\r\n\t}\r\n\r\n\tonPress(callback: () => void): Unsubscribe {\r\n\t\tthis.#pressListeners.add(callback)\r\n\t\treturn () => this.#pressListeners.delete(callback)\r\n\t}\r\n\r\n\tonRelease(callback: () => void): Unsubscribe {\r\n\t\tthis.#releaseListeners.add(callback)\r\n\t\treturn () => this.#releaseListeners.delete(callback)\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// VirtualJoystick Implementation\r\n\t// ============================================================================\r\n\r\n\tgetState(): VirtualJoystickState {\r\n\t\treturn {\r\n\t\t\tisActive: this.#isActive,\r\n\t\t\tdirection: { ...this.#direction },\r\n\t\t\tmagnitude: this.#magnitude,\r\n\t\t\tangle: this.#angle,\r\n\t\t}\r\n\t}\r\n\r\n\tgetDirection(): Vector2 {\r\n\t\treturn { ...this.#direction }\r\n\t}\r\n\r\n\tgetMagnitude(): number {\r\n\t\treturn this.#magnitude\r\n\t}\r\n\r\n\tgetAngle(): number {\r\n\t\treturn this.#angle\r\n\t}\r\n\r\n\tisActive(): boolean {\r\n\t\treturn this.#isActive\r\n\t}\r\n\r\n\tsetDeadZone(deadZone: number): void {\r\n\t\tthis.#deadZone = Math.max(0, Math.min(1, deadZone))\r\n\t}\r\n\r\n\tsetFixed(fixed: boolean): void {\r\n\t\tthis.#fixed = fixed\r\n\t}\r\n\r\n\tsetAutoHide(autoHide: boolean): void {\r\n\t\tthis.#autoHide = autoHide\r\n\t\tif (!autoHide) {\r\n\t\t\tthis.#displayOpacity = 1\r\n\t\t}\r\n\t}\r\n\r\n\tsetInnerColor(color: string): void {\r\n\t\tthis.#innerColor = color\r\n\t}\r\n\r\n\tsetOuterColor(color: string): void {\r\n\t\tthis.#outerColor = color\r\n\t}\r\n\r\n\tsetBorderColor(color: string): void {\r\n\t\tthis.#borderColor = color\r\n\t}\r\n\r\n\treset(): void {\r\n\t\tif (this.#isActive) {\r\n\t\t\tthis.#isActive = false\r\n\t\t\tthis.#touchId = null\r\n\t\t\tthis.#knobX = this.#centerX\r\n\t\t\tthis.#knobY = this.#centerY\r\n\t\t\tthis.#direction = { x: 0, y: 0 }\r\n\t\t\tthis.#magnitude = 0\r\n\t\t\tthis.#angle = 0\r\n\t\t\tthis.#releaseListeners.forEach((cb) => cb())\r\n\t\t}\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Update & Render\r\n\t// ============================================================================\r\n\r\n\tupdate(inputState: InputState): void {\r\n\t\tif (!this.#interactive || !this.#visible) return\r\n\r\n\t\t// Handle auto-hide (need deltaTime from somewhere - use fixed step)\r\n\t\tconst deltaTime = 1 / 60\r\n\t\tif (this.#autoHide) {\r\n\t\t\tif (this.#isActive) {\r\n\t\t\t\tthis.#displayOpacity = 1\r\n\t\t\t\tthis.#hideTimer = 0\r\n\t\t\t} else {\r\n\t\t\t\tthis.#hideTimer += deltaTime * 1000\r\n\t\t\t\tif (this.#hideTimer >= this.#hideDelay) {\r\n\t\t\t\t\tthis.#displayOpacity = Math.max(0, this.#displayOpacity - deltaTime * 2)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Handle touch input\r\n\t\tif (inputState.touches.length > 0) {\r\n\t\t\tfor (const touch of inputState.touches) {\r\n\t\t\t\t// Already tracking this touch\r\n\t\t\t\tif (this.#touchId !== null && touch.id === this.#touchId) {\r\n\t\t\t\t\tthis.#updateKnobPosition(touch.x, touch.y)\r\n\t\t\t\t\treturn\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// New touch in joystick area\r\n\t\t\t\tif (this.#touchId === null && this.contains(touch.x, touch.y)) {\r\n\t\t\t\t\tthis.#touchId = touch.id\r\n\t\t\t\t\tthis.#isActive = true\r\n\t\t\t\t\tthis.#pressListeners.forEach((cb) => cb())\r\n\r\n\t\t\t\t\t// For non-fixed joystick, move center to touch\r\n\t\t\t\t\tif (!this.#fixed) {\r\n\t\t\t\t\t\tthis.#centerX = touch.x\r\n\t\t\t\t\t\tthis.#centerY = touch.y\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tthis.#updateKnobPosition(touch.x, touch.y)\r\n\t\t\t\t\treturn\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// Check if tracked touch is still present\r\n\t\t\tif (this.#touchId !== null) {\r\n\t\t\t\tconst stillPresent = inputState.touches.some((t) => t.id === this.#touchId)\r\n\t\t\t\tif (!stillPresent) {\r\n\t\t\t\t\tthis.reset()\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t} else if (this.#touchId !== null) {\r\n\t\t\t// Touches became empty but we were tracking - reset\r\n\t\t\tthis.reset()\r\n\t\t} else if (inputState.isPointerDown) {\r\n\t\t\t// Mouse/pointer fallback\r\n\t\t\tif (this.contains(inputState.pointerX, inputState.pointerY)) {\r\n\t\t\t\tthis.#isActive = true\r\n\t\t\t\tthis.#pressListeners.forEach((cb) => cb())\r\n\t\t\t\tthis.#updateKnobPosition(inputState.pointerX, inputState.pointerY)\r\n\t\t\t} else if (this.#isActive) {\r\n\t\t\t\tthis.#updateKnobPosition(inputState.pointerX, inputState.pointerY)\r\n\t\t\t}\r\n\t\t} else if (!inputState.isPointerDown && this.#isActive && this.#touchId === null) {\r\n\t\t\tthis.reset()\r\n\t\t}\r\n\t}\r\n\r\n\t#updateKnobPosition(x: number, y: number): void {\r\n\t\tconst dx = x - this.#centerX\r\n\t\tconst dy = y - this.#centerY\r\n\t\tconst distance = Math.sqrt(dx * dx + dy * dy)\r\n\r\n\t\t// Calculate angle\r\n\t\tthis.#angle = Math.atan2(dy, dx)\r\n\r\n\t\t// Clamp to outer radius\r\n\t\tconst clampedDistance = Math.min(distance, this.#outerRadius - this.#innerRadius)\r\n\t\tconst normalizedMagnitude = clampedDistance / (this.#outerRadius - this.#innerRadius)\r\n\r\n\t\t// Update knob position\r\n\t\tif (distance > 0) {\r\n\t\t\tconst ratio = clampedDistance / distance\r\n\t\t\tthis.#knobX = this.#centerX + dx * ratio\r\n\t\t\tthis.#knobY = this.#centerY + dy * ratio\r\n\t\t}\r\n\r\n\t\t// Apply dead zone\r\n\t\tif (normalizedMagnitude < this.#deadZone) {\r\n\t\t\tthis.#direction = { x: 0, y: 0 }\r\n\t\t\tthis.#magnitude = 0\r\n\t\t} else {\r\n\t\t\t// Remap magnitude to 0-1 after dead zone\r\n\t\t\tconst remappedMagnitude = (normalizedMagnitude - this.#deadZone) / (1 - this.#deadZone)\r\n\t\t\tthis.#magnitude = remappedMagnitude\r\n\r\n\t\t\t// Normalize direction\r\n\t\t\tif (distance > 0) {\r\n\t\t\t\tthis.#direction = {\r\n\t\t\t\t\tx: dx / distance,\r\n\t\t\t\t\ty: dy / distance,\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Notify listeners\r\n\t\tthis.#moveListeners.forEach((cb) => cb(this.#direction, this.#magnitude))\r\n\t}\r\n\r\n\trender(context: CanvasRenderingContext2D): void {\r\n\t\tif (!this.#visible || this.#displayOpacity <= 0) return\r\n\r\n\t\tcontext.save()\r\n\t\tcontext.globalAlpha = this.#opacity * this.#displayOpacity\r\n\r\n\t\t// Draw outer circle\r\n\t\tcontext.beginPath()\r\n\t\tcontext.arc(this.#centerX, this.#centerY, this.#outerRadius, 0, Math.PI * 2)\r\n\t\tcontext.fillStyle = this.#outerColor\r\n\t\tcontext.fill()\r\n\t\tcontext.lineWidth = this.#borderWidth\r\n\t\tcontext.strokeStyle = this.#borderColor\r\n\t\tcontext.stroke()\r\n\r\n\t\t// Draw inner knob\r\n\t\tcontext.beginPath()\r\n\t\tcontext.arc(this.#knobX, this.#knobY, this.#innerRadius, 0, Math.PI * 2)\r\n\t\tcontext.fillStyle = this.#innerColor\r\n\t\tcontext.fill()\r\n\r\n\t\tcontext.restore()\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#moveListeners.clear()\r\n\t\tthis.#pressListeners.clear()\r\n\t\tthis.#releaseListeners.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tActionButtonInterface,\r\n\tActionButtonOptions,\r\n\tActionButtonState,\r\n\tUnsubscribe,\r\n\tInputState,\r\n\tUIBounds,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Touch-optimized action button with cooldown visualization.\r\n */\r\nexport class ActionButton implements ActionButtonInterface {\r\n\treadonly id: string\r\n\r\n\t#x: number\r\n\t#y: number\r\n\t#width: number\r\n\t#height: number\r\n\t#visible: boolean\r\n\t#interactive: boolean\r\n\t#zIndex: number\r\n\t#opacity: number\r\n\r\n\t#icon: string | undefined\r\n\t#iconKey: string | undefined\r\n\t#cooldown: number\r\n\t#size: number\r\n\t#backgroundColor: string\r\n\t#activeColor: string\r\n\t#disabledColor: string\r\n\t#cooldownColor: string\r\n\t#borderWidth: number\r\n\t#borderColor: string\r\n\t#hapticFeedback: boolean\r\n\r\n\t#isPressed = false\r\n\t#isHovered = false\r\n\t#isDisabled = false\r\n\t#isOnCooldown = false\r\n\t#cooldownRemaining = 0\r\n\t#cooldownDuration = 0\r\n\r\n\t#activateListeners = new Set<() => void>()\r\n\t#holdListeners = new Set<() => void>()\r\n\t#releaseListeners = new Set<() => void>()\r\n\t#cooldownStartListeners = new Set<(duration: number) => void>()\r\n\t#cooldownEndListeners = new Set<() => void>()\r\n\r\n\tconstructor(options: ActionButtonOptions) {\r\n\t\tthis.id = crypto.randomUUID()\r\n\t\tthis.#size = options.size ?? 60\r\n\t\tthis.#x = options.x\r\n\t\tthis.#y = options.y\r\n\t\tthis.#width = options.width\r\n\t\tthis.#height = options.height\r\n\t\tthis.#visible = options.visible ?? true\r\n\t\tthis.#interactive = options.interactive ?? true\r\n\t\tthis.#zIndex = options.zIndex ?? 0\r\n\t\tthis.#opacity = options.opacity ?? 1\r\n\r\n\t\tthis.#icon = options.icon\r\n\t\tthis.#iconKey = options.iconKey\r\n\t\tthis.#cooldown = options.cooldown ?? 0\r\n\t\tthis.#backgroundColor = options.backgroundColor ?? 'rgba(50, 50, 50, 0.8)'\r\n\t\tthis.#activeColor = options.activeColor ?? 'rgba(100, 150, 255, 0.9)'\r\n\t\tthis.#disabledColor = options.disabledColor ?? 'rgba(80, 80, 80, 0.5)'\r\n\t\tthis.#cooldownColor = options.cooldownColor ?? 'rgba(100, 100, 100, 0.7)'\r\n\t\tthis.#borderWidth = options.borderWidth ?? 3\r\n\t\tthis.#borderColor = options.borderColor ?? 'rgba(255, 255, 255, 0.6)'\r\n\t\tthis.#hapticFeedback = options.hapticFeedback ?? true\r\n\r\n\t\t// Register hooks from options\r\n\t\tif (options.onActivate) this.#activateListeners.add(options.onActivate)\r\n\t\tif (options.onHold) this.#holdListeners.add(options.onHold)\r\n\t\tif (options.onRelease) this.#releaseListeners.add(options.onRelease)\r\n\t\tif (options.onCooldownStart) this.#cooldownStartListeners.add(options.onCooldownStart)\r\n\t\tif (options.onCooldownEnd) this.#cooldownEndListeners.add(options.onCooldownEnd)\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Visibility\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tisVisible(): boolean {\r\n\t\treturn this.#visible\r\n\t}\r\n\r\n\tsetVisible(visible: boolean): void {\r\n\t\tthis.#visible = visible\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Position accessors\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetX(): number {\r\n\t\treturn this.#x\r\n\t}\r\n\r\n\tgetY(): number {\r\n\t\treturn this.#y\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Position mutators\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetX(x: number): void {\r\n\t\tthis.#x = x\r\n\t}\r\n\r\n\tsetY(y: number): void {\r\n\t\tthis.#y = y\r\n\t}\r\n\r\n\tsetPosition(x: number, y: number): void {\r\n\t\tthis.#x = x\r\n\t\tthis.#y = y\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Size accessors\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetWidth(): number {\r\n\t\treturn this.#width\r\n\t}\r\n\r\n\tgetHeight(): number {\r\n\t\treturn this.#height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Size mutators\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetWidth(width: number): void {\r\n\t\tthis.#width = width\r\n\t}\r\n\r\n\tsetHeight(height: number): void {\r\n\t\tthis.#height = height\r\n\t}\r\n\r\n\tsetSize(width: number, height: number): void {\r\n\t\tthis.#width = width\r\n\t\tthis.#height = height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Bounds and hit testing\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetBounds(): UIBounds {\r\n\t\treturn {\r\n\t\t\tx: this.#x,\r\n\t\t\ty: this.#y,\r\n\t\t\twidth: this.#width,\r\n\t\t\theight: this.#height,\r\n\t\t}\r\n\t}\r\n\r\n\tcontains(x: number, y: number): boolean {\r\n\t\t// Circular hit test for round buttons\r\n\t\tconst centerX = this.#x + this.#width / 2\r\n\t\tconst centerY = this.#y + this.#height / 2\r\n\t\tconst radius = Math.min(this.#width, this.#height) / 2\r\n\t\tconst dx = x - centerX\r\n\t\tconst dy = y - centerY\r\n\t\treturn Math.sqrt(dx * dx + dy * dy) <= radius\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Z-Index\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetZIndex(): number {\r\n\t\treturn this.#zIndex\r\n\t}\r\n\r\n\tsetZIndex(zIndex: number): void {\r\n\t\tthis.#zIndex = zIndex\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Opacity\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetOpacity(): number {\r\n\t\treturn this.#opacity\r\n\t}\r\n\r\n\tsetOpacity(opacity: number): void {\r\n\t\tthis.#opacity = Math.max(0, Math.min(1, opacity))\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// InteractiveUIElement: Interactivity\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tisInteractive(): boolean {\r\n\t\treturn this.#interactive\r\n\t}\r\n\r\n\tsetInteractive(interactive: boolean): void {\r\n\t\tthis.#interactive = interactive\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// ActionButtonSubscriptions Implementation\r\n\t// ============================================================================\r\n\r\n\tonActivate(callback: () => void): Unsubscribe {\r\n\t\tthis.#activateListeners.add(callback)\r\n\t\treturn () => this.#activateListeners.delete(callback)\r\n\t}\r\n\r\n\tonHold(callback: () => void): Unsubscribe {\r\n\t\tthis.#holdListeners.add(callback)\r\n\t\treturn () => this.#holdListeners.delete(callback)\r\n\t}\r\n\r\n\tonRelease(callback: () => void): Unsubscribe {\r\n\t\tthis.#releaseListeners.add(callback)\r\n\t\treturn () => this.#releaseListeners.delete(callback)\r\n\t}\r\n\r\n\tonCooldownStart(callback: (duration: number) => void): Unsubscribe {\r\n\t\tthis.#cooldownStartListeners.add(callback)\r\n\t\treturn () => this.#cooldownStartListeners.delete(callback)\r\n\t}\r\n\r\n\tonCooldownEnd(callback: () => void): Unsubscribe {\r\n\t\tthis.#cooldownEndListeners.add(callback)\r\n\t\treturn () => this.#cooldownEndListeners.delete(callback)\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// ActionButton Implementation\r\n\t// ============================================================================\r\n\r\n\tgetState(): ActionButtonState {\r\n\t\treturn {\r\n\t\t\tisPressed: this.#isPressed,\r\n\t\t\tisOnCooldown: this.#isOnCooldown,\r\n\t\t\tcooldownRemaining: this.#cooldownRemaining,\r\n\t\t\tcooldownProgress: this.getCooldownProgress(),\r\n\t\t\tisDisabled: this.#isDisabled,\r\n\t\t}\r\n\t}\r\n\r\n\tisPressed(): boolean {\r\n\t\treturn this.#isPressed\r\n\t}\r\n\r\n\tisOnCooldown(): boolean {\r\n\t\treturn this.#isOnCooldown\r\n\t}\r\n\r\n\tisDisabled(): boolean {\r\n\t\treturn this.#isDisabled\r\n\t}\r\n\r\n\tgetCooldownProgress(): number {\r\n\t\tif (!this.#isOnCooldown || this.#cooldownDuration === 0) return 0\r\n\t\treturn 1 - this.#cooldownRemaining / this.#cooldownDuration\r\n\t}\r\n\r\n\tactivate(): void {\r\n\t\tif (!this.#interactive || this.#isDisabled || this.#isOnCooldown) return\r\n\r\n\t\tthis.#activateListeners.forEach((cb) => cb())\r\n\r\n\t\tif (this.#cooldown > 0) {\r\n\t\t\tthis.startCooldown(this.#cooldown)\r\n\t\t}\r\n\t}\r\n\r\n\tstartCooldown(duration?: number): void {\r\n\t\tconst actualDuration = duration ?? this.#cooldown\r\n\t\tif (actualDuration <= 0) return\r\n\r\n\t\tthis.#isOnCooldown = true\r\n\t\tthis.#cooldownDuration = actualDuration\r\n\t\tthis.#cooldownRemaining = actualDuration\r\n\t\tthis.#cooldownStartListeners.forEach((cb) => cb(actualDuration))\r\n\t}\r\n\r\n\tresetCooldown(): void {\r\n\t\tconst wasOnCooldown = this.#isOnCooldown\r\n\t\tthis.#isOnCooldown = false\r\n\t\tthis.#cooldownRemaining = 0\r\n\t\tthis.#cooldownDuration = 0\r\n\t\tif (wasOnCooldown) {\r\n\t\t\tthis.#cooldownEndListeners.forEach((cb) => cb())\r\n\t\t}\r\n\t}\r\n\r\n\tsetDisabled(disabled: boolean): void {\r\n\t\tthis.#isDisabled = disabled\r\n\t}\r\n\r\n\tsetIcon(icon: string): void {\r\n\t\tthis.#icon = icon\r\n\t}\r\n\r\n\tsetIconKey(iconKey: string): void {\r\n\t\tthis.#iconKey = iconKey\r\n\t}\r\n\r\n\tsetCooldown(cooldown: number): void {\r\n\t\tthis.#cooldown = cooldown\r\n\t}\r\n\r\n\tupdateCooldown(deltaTime: number): void {\r\n\t\tif (this.#isOnCooldown) {\r\n\t\t\tthis.#cooldownRemaining -= deltaTime * 1000\r\n\t\t\tif (this.#cooldownRemaining <= 0) {\r\n\t\t\t\tthis.resetCooldown()\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Update & Render\r\n\t// ============================================================================\r\n\r\n\tupdate(inputState: InputState): void {\r\n\t\tif (!this.#interactive || !this.#visible) return\r\n\r\n\t\tconst wasPressed = this.#isPressed\r\n\r\n\t\t// Check if pointer is over button\r\n\t\tthis.#isHovered = this.contains(inputState.pointerX, inputState.pointerY)\r\n\r\n\t\t// Handle touch input\r\n\t\tlet touchOnButton = false\r\n\t\tfor (const touch of inputState.touches) {\r\n\t\t\tif (this.contains(touch.x, touch.y)) {\r\n\t\t\t\ttouchOnButton = true\r\n\t\t\t\tbreak\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Pressed state\r\n\t\tthis.#isPressed = (this.#isHovered && inputState.isPointerDown) || touchOnButton\r\n\r\n\t\t// Trigger activation on press (not release for responsive feel)\r\n\t\tif (this.#isPressed && !wasPressed) {\r\n\t\t\tthis.activate()\r\n\t\t}\r\n\r\n\t\t// Fire hold callback while pressed\r\n\t\tif (this.#isPressed) {\r\n\t\t\tthis.#holdListeners.forEach((cb) => cb())\r\n\t\t}\r\n\r\n\t\t// Fire release callback when released\r\n\t\tif (!this.#isPressed && wasPressed) {\r\n\t\t\tthis.#releaseListeners.forEach((cb) => cb())\r\n\t\t}\r\n\t}\r\n\r\n\trender(context: CanvasRenderingContext2D): void {\r\n\t\tif (!this.#visible) return\r\n\r\n\t\tconst centerX = this.#x + this.#width / 2\r\n\t\tconst centerY = this.#y + this.#height / 2\r\n\t\tconst radius = Math.min(this.#width, this.#height) / 2\r\n\r\n\t\tcontext.save()\r\n\t\tcontext.globalAlpha = this.#opacity\r\n\r\n\t\t// Draw button background\r\n\t\tcontext.beginPath()\r\n\t\tcontext.arc(centerX, centerY, radius, 0, Math.PI * 2)\r\n\r\n\t\tif (this.#isDisabled) {\r\n\t\t\tcontext.fillStyle = this.#disabledColor\r\n\t\t} else if (this.#isOnCooldown) {\r\n\t\t\tcontext.fillStyle = this.#cooldownColor\r\n\t\t} else if (this.#isPressed) {\r\n\t\t\tcontext.fillStyle = this.#activeColor\r\n\t\t} else {\r\n\t\t\tcontext.fillStyle = this.#backgroundColor\r\n\t\t}\r\n\r\n\t\tcontext.fill()\r\n\r\n\t\t// Draw cooldown overlay\r\n\t\tif (this.#isOnCooldown && this.#cooldownDuration > 0) {\r\n\t\t\tconst progress = this.getCooldownProgress()\r\n\t\t\tconst startAngle = -Math.PI / 2\r\n\t\t\tconst endAngle = startAngle + progress * Math.PI * 2\r\n\r\n\t\t\tcontext.beginPath()\r\n\t\t\tcontext.moveTo(centerX, centerY)\r\n\t\t\tcontext.arc(centerX, centerY, radius, startAngle, endAngle)\r\n\t\t\tcontext.closePath()\r\n\t\t\tcontext.fillStyle = 'rgba(255, 255, 255, 0.2)'\r\n\t\t\tcontext.fill()\r\n\t\t}\r\n\r\n\t\t// Draw border\r\n\t\tcontext.beginPath()\r\n\t\tcontext.arc(centerX, centerY, radius - this.#borderWidth / 2, 0, Math.PI * 2)\r\n\t\tcontext.lineWidth = this.#borderWidth\r\n\t\tcontext.strokeStyle = this.#borderColor\r\n\t\tcontext.stroke()\r\n\r\n\t\t// Draw icon text (simple text icon for now)\r\n\t\tif (this.#icon) {\r\n\t\t\tcontext.font = `${radius * 0.8}px sans-serif`\r\n\t\t\tcontext.textAlign = 'center'\r\n\t\t\tcontext.textBaseline = 'middle'\r\n\t\t\tcontext.fillStyle = this.#isDisabled ? 'rgba(255, 255, 255, 0.3)' : 'rgba(255, 255, 255, 0.9)'\r\n\t\t\tcontext.fillText(this.#icon, centerX, centerY)\r\n\t\t}\r\n\r\n\t\t// Scale effect when pressed\r\n\t\tif (this.#isPressed) {\r\n\t\t\tcontext.globalAlpha = 0.3\r\n\t\t\tcontext.beginPath()\r\n\t\t\tcontext.arc(centerX, centerY, radius * 1.1, 0, Math.PI * 2)\r\n\t\t\tcontext.strokeStyle = this.#activeColor\r\n\t\t\tcontext.lineWidth = 2\r\n\t\t\tcontext.stroke()\r\n\t\t}\r\n\r\n\t\tcontext.restore()\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#activateListeners.clear()\r\n\t\tthis.#holdListeners.clear()\r\n\t\tthis.#releaseListeners.clear()\r\n\t\tthis.#cooldownStartListeners.clear()\r\n\t\tthis.#cooldownEndListeners.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tCameraEffectsInterface,\r\n\tCameraEffectConfig,\r\n\tCameraEffectState,\r\n\tCameraEffectType,\r\n\tVector2,\r\n\tUnsubscribe,\r\n\tCameraInterface,\r\n} from '../../types.js'\r\n\r\ninterface ActiveEffect {\r\n\ttype: CameraEffectType\r\n\tduration: number\r\n\tremaining: number\r\n\tintensity: number\r\n\tcolor?: string\r\n\tpriority: number\r\n}\r\n\r\n/**\r\n * Camera effects system for visual feedback (shake, flash, fade, etc.).\r\n */\r\nexport class CameraEffects implements CameraEffectsInterface {\r\n\t#camera: CameraInterface\r\n\t#effects = new Map<CameraEffectType, ActiveEffect>()\r\n\t#shakeOffset: Vector2 = { x: 0, y: 0 }\r\n\t#traumaAmount = 0\r\n\t#flashColor: string | undefined\r\n\t#flashOpacity = 0\r\n\t#zoomModifier = 1\r\n\r\n\t#effectStartListeners = new Set<(type: CameraEffectType) => void>()\r\n\t#effectEndListeners = new Set<(type: CameraEffectType) => void>()\r\n\r\n\tconstructor(camera: CameraInterface) {\r\n\t\tthis.#camera = camera\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Subscriptions\r\n\t// ============================================================================\r\n\r\n\tonEffectStart(callback: (type: CameraEffectType) => void): Unsubscribe {\r\n\t\tthis.#effectStartListeners.add(callback)\r\n\t\treturn () => this.#effectStartListeners.delete(callback)\r\n\t}\r\n\r\n\tonEffectEnd(callback: (type: CameraEffectType) => void): Unsubscribe {\r\n\t\tthis.#effectEndListeners.add(callback)\r\n\t\treturn () => this.#effectEndListeners.delete(callback)\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// State Queries\r\n\t// ============================================================================\r\n\r\n\tgetActiveEffects(): readonly CameraEffectState[] {\r\n\t\tconst states: CameraEffectState[] = []\r\n\t\tfor (const effect of this.#effects.values()) {\r\n\t\t\tstates.push({\r\n\t\t\t\ttype: effect.type,\r\n\t\t\t\tprogress: 1 - effect.remaining / effect.duration,\r\n\t\t\t\tremaining: effect.remaining,\r\n\t\t\t\tintensity: effect.intensity,\r\n\t\t\t})\r\n\t\t}\r\n\t\treturn states\r\n\t}\r\n\r\n\thasActiveEffects(): boolean {\r\n\t\treturn this.#effects.size > 0 || this.#traumaAmount > 0\r\n\t}\r\n\r\n\tisEffectActive(type: CameraEffectType): boolean {\r\n\t\treturn this.#effects.has(type)\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Effect Methods\r\n\t// ============================================================================\r\n\r\n\tshake(intensity: number, duration: number): void {\r\n\t\tthis.addEffect({\r\n\t\t\ttype: 'shake',\r\n\t\t\tduration,\r\n\t\t\tintensity,\r\n\t\t})\r\n\t}\r\n\r\n\tflash(color: string, duration: number): void {\r\n\t\tthis.addEffect({\r\n\t\t\ttype: 'flash',\r\n\t\t\tduration,\r\n\t\t\tintensity: 1,\r\n\t\t\tcolor,\r\n\t\t})\r\n\t}\r\n\r\n\tfade(color: string, duration: number, fadeIn: boolean): void {\r\n\t\tthis.addEffect({\r\n\t\t\ttype: 'fade',\r\n\t\t\tduration,\r\n\t\t\tintensity: fadeIn ? 1 : -1,\r\n\t\t\tcolor,\r\n\t\t})\r\n\t}\r\n\r\n\tzoomPulse(scale: number, duration: number): void {\r\n\t\tthis.addEffect({\r\n\t\t\ttype: 'zoom-pulse',\r\n\t\t\tduration,\r\n\t\t\tintensity: scale,\r\n\t\t})\r\n\t}\r\n\r\n\ttrauma(amount: number): void {\r\n\t\tthis.#traumaAmount = Math.min(1, this.#traumaAmount + amount)\r\n\t}\r\n\r\n\taddEffect(config: CameraEffectConfig): void {\r\n\t\tconst effect: ActiveEffect = {\r\n\t\t\ttype: config.type,\r\n\t\t\tduration: config.duration,\r\n\t\t\tremaining: config.duration,\r\n\t\t\tintensity: config.intensity ?? 1,\r\n\t\t\tpriority: config.priority ?? 0,\r\n\t\t}\r\n\r\n\t\tif (config.color !== undefined) {\r\n\t\t\teffect.color = config.color\r\n\t\t}\r\n\r\n\t\tconst existing = this.#effects.get(config.type)\r\n\t\tif (!existing || existing.priority <= effect.priority) {\r\n\t\t\tthis.#effects.set(config.type, effect)\r\n\t\t\tthis.#effectStartListeners.forEach((cb) => cb(config.type))\r\n\t\t}\r\n\t}\r\n\r\n\tremoveEffect(type: CameraEffectType): void {\r\n\t\tif (this.#effects.delete(type)) {\r\n\t\t\tthis.#effectEndListeners.forEach((cb) => cb(type))\r\n\t\t}\r\n\t}\r\n\r\n\tclearEffects(): void {\r\n\t\tfor (const type of this.#effects.keys()) {\r\n\t\t\tthis.#effectEndListeners.forEach((cb) => cb(type))\r\n\t\t}\r\n\t\tthis.#effects.clear()\r\n\t\tthis.#traumaAmount = 0\r\n\t\tthis.#shakeOffset = { x: 0, y: 0 }\r\n\t\tthis.#flashOpacity = 0\r\n\t\tthis.#zoomModifier = 1\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Effect Getters\r\n\t// ============================================================================\r\n\r\n\tgetShakeOffset(): Vector2 {\r\n\t\treturn { ...this.#shakeOffset }\r\n\t}\r\n\r\n\tgetFlashColor(): string | undefined {\r\n\t\treturn this.#flashColor\r\n\t}\r\n\r\n\tgetFlashOpacity(): number {\r\n\t\treturn this.#flashOpacity\r\n\t}\r\n\r\n\tgetZoomModifier(): number {\r\n\t\treturn this.#zoomModifier\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Update\r\n\t// ============================================================================\r\n\r\n\tupdate(deltaTime: number): void {\r\n\t\tconst deltaMs = deltaTime * 1000\r\n\t\tconst effectsToRemove: CameraEffectType[] = []\r\n\r\n\t\t// Reset per-frame values\r\n\t\tthis.#shakeOffset = { x: 0, y: 0 }\r\n\t\tthis.#flashOpacity = 0\r\n\t\tthis.#zoomModifier = 1\r\n\r\n\t\t// Update trauma (decay over time)\r\n\t\tif (this.#traumaAmount > 0) {\r\n\t\t\tthis.#traumaAmount = Math.max(0, this.#traumaAmount - deltaTime * 2)\r\n\t\t\tconst traumaShake = this.#traumaAmount * this.#traumaAmount * 20\r\n\t\t\tthis.#shakeOffset = {\r\n\t\t\t\tx: (Math.random() * 2 - 1) * traumaShake,\r\n\t\t\t\ty: (Math.random() * 2 - 1) * traumaShake,\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Update effects\r\n\t\tfor (const [type, effect] of this.#effects) {\r\n\t\t\teffect.remaining -= deltaMs\r\n\r\n\t\t\tif (effect.remaining <= 0) {\r\n\t\t\t\teffectsToRemove.push(type)\r\n\t\t\t\tcontinue\r\n\t\t\t}\r\n\r\n\t\t\tconst progress = 1 - effect.remaining / effect.duration\r\n\t\t\tconst easedProgress = this.#easeOut(progress)\r\n\r\n\t\t\tswitch (type) {\r\n\t\t\t\tcase 'shake': {\r\n\t\t\t\t\tconst shakeIntensity = effect.intensity * (1 - easedProgress)\r\n\t\t\t\t\tthis.#shakeOffset = {\r\n\t\t\t\t\t\tx: this.#shakeOffset.x + (Math.random() * 2 - 1) * shakeIntensity,\r\n\t\t\t\t\t\ty: this.#shakeOffset.y + (Math.random() * 2 - 1) * shakeIntensity,\r\n\t\t\t\t\t}\r\n\t\t\t\t\tbreak\r\n\t\t\t\t}\r\n\r\n\t\t\t\tcase 'flash': {\r\n\t\t\t\t\tthis.#flashColor = effect.color ?? '#ffffff'\r\n\t\t\t\t\t// Flash peaks at middle, then fades\r\n\t\t\t\t\tconst flashProgress = progress < 0.5 ? progress * 2 : (1 - progress) * 2\r\n\t\t\t\t\tthis.#flashOpacity = effect.intensity * flashProgress\r\n\t\t\t\t\tbreak\r\n\t\t\t\t}\r\n\r\n\t\t\t\tcase 'fade': {\r\n\t\t\t\t\tthis.#flashColor = effect.color ?? '#000000'\r\n\t\t\t\t\t// Fade in or out based on intensity sign\r\n\t\t\t\t\tif (effect.intensity > 0) {\r\n\t\t\t\t\t\tthis.#flashOpacity = 1 - easedProgress\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tthis.#flashOpacity = easedProgress\r\n\t\t\t\t\t}\r\n\t\t\t\t\tbreak\r\n\t\t\t\t}\r\n\r\n\t\t\t\tcase 'zoom-pulse': {\r\n\t\t\t\t\t// Zoom in then back to normal\r\n\t\t\t\t\tconst zoomProgress = progress < 0.5 ? progress * 2 : (1 - progress) * 2\r\n\t\t\t\t\tconst zoomAmount = (effect.intensity - 1) * zoomProgress\r\n\t\t\t\t\tthis.#zoomModifier = 1 + zoomAmount\r\n\t\t\t\t\tbreak\r\n\t\t\t\t}\r\n\r\n\t\t\t\tcase 'vignette':\r\n\t\t\t\tcase 'chromatic':\r\n\t\t\t\t\t// These would need shader-like implementation\r\n\t\t\t\t\tbreak\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Remove completed effects\r\n\t\tfor (const type of effectsToRemove) {\r\n\t\t\tthis.#effects.delete(type)\r\n\t\t\tthis.#effectEndListeners.forEach((cb) => cb(type))\r\n\t\t}\r\n\t}\r\n\r\n\t#easeOut(t: number): number {\r\n\t\treturn 1 - Math.pow(1 - t, 3)\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Apply to Context\r\n\t// ============================================================================\r\n\r\n\tapply(context: CanvasRenderingContext2D): void {\r\n\t\t// Apply shake offset\r\n\t\tif (this.#shakeOffset.x !== 0 || this.#shakeOffset.y !== 0) {\r\n\t\t\tcontext.translate(this.#shakeOffset.x, this.#shakeOffset.y)\r\n\t\t}\r\n\r\n\t\t// Apply zoom modifier\r\n\t\tif (this.#zoomModifier !== 1) {\r\n\t\t\tconst centerX = context.canvas.width / 2\r\n\t\t\tconst centerY = context.canvas.height / 2\r\n\t\t\tcontext.translate(centerX, centerY)\r\n\t\t\tcontext.scale(this.#zoomModifier, this.#zoomModifier)\r\n\t\t\tcontext.translate(-centerX, -centerY)\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Render flash/fade overlay. Call after rendering scene.\r\n\t */\r\n\trenderOverlay(context: CanvasRenderingContext2D): void {\r\n\t\tif (this.#flashOpacity > 0 && this.#flashColor) {\r\n\t\t\tcontext.save()\r\n\t\t\tcontext.globalAlpha = this.#flashOpacity\r\n\t\t\tcontext.fillStyle = this.#flashColor\r\n\t\t\tcontext.fillRect(0, 0, context.canvas.width, context.canvas.height)\r\n\t\t\tcontext.restore()\r\n\t\t}\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#effects.clear()\r\n\t\tthis.#effectStartListeners.clear()\r\n\t\tthis.#effectEndListeners.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tTextInputInterface,\r\n\tTextInputOptions,\r\n\tTextInputState,\r\n\tTextInputType,\r\n\tUnsubscribe,\r\n\tInputState,\r\n\tUIBounds,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Canvas-rendered text input with cursor, selection, and mobile keyboard support.\r\n */\r\nexport class TextInput implements TextInputInterface {\r\n\treadonly id: string\r\n\r\n\t#x: number\r\n\t#y: number\r\n\t#width: number\r\n\t#height: number\r\n\t#visible: boolean\r\n\t#interactive: boolean\r\n\t#zIndex: number\r\n\t#opacity: number\r\n\r\n\t#value: string\r\n\t#placeholder: string\r\n\t#maxLength: number\r\n\t#inputType: TextInputType\r\n\t#fontSize: number\r\n\t#fontFamily: string\r\n\t#textColor: string\r\n\t#placeholderColor: string\r\n\t#backgroundColor: string\r\n\t#borderWidth: number\r\n\t#borderColor: string\r\n\t#focusBorderColor: string\r\n\t#borderRadius: number\r\n\t#padding: number\r\n\t#cursorColor: string\r\n\t#selectionColor: string\r\n\r\n\t#isFocused = false\r\n\t#cursorPosition = 0\r\n\t#selectionStart = 0\r\n\t#selectionEnd = 0\r\n\t#cursorBlink = 0\r\n\t#cursorVisible = true\r\n\r\n\t#hiddenInput: HTMLInputElement | null = null\r\n\r\n\t#inputListeners = new Set<(value: string) => void>()\r\n\t#changeListeners = new Set<(value: string) => void>()\r\n\t#submitListeners = new Set<(value: string) => void>()\r\n\t#focusListeners = new Set<() => void>()\r\n\t#blurListeners = new Set<() => void>()\r\n\r\n\tconstructor(options: TextInputOptions) {\r\n\t\tthis.id = crypto.randomUUID()\r\n\t\tthis.#x = options.x\r\n\t\tthis.#y = options.y\r\n\t\tthis.#width = options.width\r\n\t\tthis.#height = options.height\r\n\t\tthis.#visible = options.visible ?? true\r\n\t\tthis.#interactive = options.interactive ?? true\r\n\t\tthis.#zIndex = options.zIndex ?? 0\r\n\t\tthis.#opacity = options.opacity ?? 1\r\n\r\n\t\tthis.#value = options.value ?? ''\r\n\t\tthis.#placeholder = options.placeholder ?? ''\r\n\t\tthis.#maxLength = options.maxLength ?? 256\r\n\t\tthis.#inputType = options.inputType ?? 'text'\r\n\t\tthis.#fontSize = options.fontSize ?? 16\r\n\t\tthis.#fontFamily = options.fontFamily ?? 'sans-serif'\r\n\t\tthis.#textColor = options.textColor ?? '#ffffff'\r\n\t\tthis.#placeholderColor = options.placeholderColor ?? '#888888'\r\n\t\tthis.#backgroundColor = options.backgroundColor ?? 'rgba(30, 30, 30, 0.9)'\r\n\t\tthis.#borderWidth = options.borderWidth ?? 2\r\n\t\tthis.#borderColor = options.borderColor ?? 'rgba(100, 100, 100, 0.8)'\r\n\t\tthis.#focusBorderColor = options.focusBorderColor ?? 'rgba(100, 150, 255, 1)'\r\n\t\tthis.#borderRadius = options.borderRadius ?? 4\r\n\t\tthis.#padding = options.padding ?? 10\r\n\t\tthis.#cursorColor = options.cursorColor ?? '#ffffff'\r\n\t\tthis.#selectionColor = options.selectionColor ?? 'rgba(100, 150, 255, 0.4)'\r\n\r\n\t\tthis.#cursorPosition = this.#value.length\r\n\r\n\t\t// Register hooks from options\r\n\t\tif (options.onInput) this.#inputListeners.add(options.onInput)\r\n\t\tif (options.onChange) this.#changeListeners.add(options.onChange)\r\n\t\tif (options.onSubmit) this.#submitListeners.add(options.onSubmit)\r\n\t\tif (options.onFocus) this.#focusListeners.add(options.onFocus)\r\n\t\tif (options.onBlur) this.#blurListeners.add(options.onBlur)\r\n\r\n\t\tthis.#createHiddenInput()\r\n\t}\r\n\r\n\t#createHiddenInput(): void {\r\n\t\tthis.#hiddenInput = document.createElement('input')\r\n\t\tthis.#hiddenInput.type = this.#inputType === 'password' ? 'password' : 'text'\r\n\t\tthis.#hiddenInput.inputMode = this.#inputType === 'number' ? 'numeric' : 'text'\r\n\t\tthis.#hiddenInput.style.position = 'absolute'\r\n\t\tthis.#hiddenInput.style.opacity = '0'\r\n\t\tthis.#hiddenInput.style.pointerEvents = 'none'\r\n\t\tthis.#hiddenInput.style.left = '-9999px'\r\n\t\tthis.#hiddenInput.maxLength = this.#maxLength\r\n\t\tthis.#hiddenInput.value = this.#value\r\n\r\n\t\tthis.#hiddenInput.addEventListener('input', () => {\r\n\t\t\tif (this.#hiddenInput) {\r\n\t\t\t\tconst newValue = this.#hiddenInput.value.slice(0, this.#maxLength)\r\n\t\t\t\tif (newValue !== this.#value) {\r\n\t\t\t\t\tthis.#value = newValue\r\n\t\t\t\t\tthis.#cursorPosition = this.#hiddenInput.selectionStart ?? newValue.length\r\n\t\t\t\t\tthis.#inputListeners.forEach((cb) => cb(newValue))\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t})\r\n\r\n\t\tthis.#hiddenInput.addEventListener('keydown', (e) => {\r\n\t\t\tif (e.key === 'Enter') {\r\n\t\t\t\tthis.#submitListeners.forEach((cb) => cb(this.#value))\r\n\t\t\t}\r\n\t\t})\r\n\r\n\t\tthis.#hiddenInput.addEventListener('blur', () => {\r\n\t\t\tif (this.#isFocused) {\r\n\t\t\t\tthis.blur()\r\n\t\t\t}\r\n\t\t})\r\n\r\n\t\tdocument.body.appendChild(this.#hiddenInput)\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Visibility\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tisVisible(): boolean {\r\n\t\treturn this.#visible\r\n\t}\r\n\r\n\tsetVisible(visible: boolean): void {\r\n\t\tthis.#visible = visible\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Position accessors\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetX(): number {\r\n\t\treturn this.#x\r\n\t}\r\n\r\n\tgetY(): number {\r\n\t\treturn this.#y\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Position mutators\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetX(x: number): void {\r\n\t\tthis.#x = x\r\n\t}\r\n\r\n\tsetY(y: number): void {\r\n\t\tthis.#y = y\r\n\t}\r\n\r\n\tsetPosition(x: number, y: number): void {\r\n\t\tthis.#x = x\r\n\t\tthis.#y = y\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Size accessors\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetWidth(): number {\r\n\t\treturn this.#width\r\n\t}\r\n\r\n\tgetHeight(): number {\r\n\t\treturn this.#height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Size mutators\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetWidth(width: number): void {\r\n\t\tthis.#width = width\r\n\t}\r\n\r\n\tsetHeight(height: number): void {\r\n\t\tthis.#height = height\r\n\t}\r\n\r\n\tsetSize(width: number, height: number): void {\r\n\t\tthis.#width = width\r\n\t\tthis.#height = height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Bounds and hit testing\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetBounds(): UIBounds {\r\n\t\treturn {\r\n\t\t\tx: this.#x,\r\n\t\t\ty: this.#y,\r\n\t\t\twidth: this.#width,\r\n\t\t\theight: this.#height,\r\n\t\t}\r\n\t}\r\n\r\n\tcontains(x: number, y: number): boolean {\r\n\t\treturn (\r\n\t\t\tx >= this.#x &&\r\n\t\t\tx <= this.#x + this.#width &&\r\n\t\t\ty >= this.#y &&\r\n\t\t\ty <= this.#y + this.#height\r\n\t\t)\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Z-Index\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetZIndex(): number {\r\n\t\treturn this.#zIndex\r\n\t}\r\n\r\n\tsetZIndex(zIndex: number): void {\r\n\t\tthis.#zIndex = zIndex\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Opacity\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetOpacity(): number {\r\n\t\treturn this.#opacity\r\n\t}\r\n\r\n\tsetOpacity(opacity: number): void {\r\n\t\tthis.#opacity = Math.max(0, Math.min(1, opacity))\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// InteractiveUIElement: Interactivity\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tisInteractive(): boolean {\r\n\t\treturn this.#interactive\r\n\t}\r\n\r\n\tsetInteractive(interactive: boolean): void {\r\n\t\tthis.#interactive = interactive\r\n\t\tif (!interactive && this.#isFocused) {\r\n\t\t\tthis.blur()\r\n\t\t}\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// TextInputSubscriptions Implementation\r\n\t// ============================================================================\r\n\r\n\tonInput(callback: (value: string) => void): Unsubscribe {\r\n\t\tthis.#inputListeners.add(callback)\r\n\t\treturn () => this.#inputListeners.delete(callback)\r\n\t}\r\n\r\n\tonChange(callback: (value: string) => void): Unsubscribe {\r\n\t\tthis.#changeListeners.add(callback)\r\n\t\treturn () => this.#changeListeners.delete(callback)\r\n\t}\r\n\r\n\tonSubmit(callback: (value: string) => void): Unsubscribe {\r\n\t\tthis.#submitListeners.add(callback)\r\n\t\treturn () => this.#submitListeners.delete(callback)\r\n\t}\r\n\r\n\tonFocus(callback: () => void): Unsubscribe {\r\n\t\tthis.#focusListeners.add(callback)\r\n\t\treturn () => this.#focusListeners.delete(callback)\r\n\t}\r\n\r\n\tonBlur(callback: () => void): Unsubscribe {\r\n\t\tthis.#blurListeners.add(callback)\r\n\t\treturn () => this.#blurListeners.delete(callback)\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// TextInput Implementation\r\n\t// ============================================================================\r\n\r\n\tgetState(): TextInputState {\r\n\t\treturn {\r\n\t\t\tvalue: this.#value,\r\n\t\t\tcursorPosition: this.#cursorPosition,\r\n\t\t\tselectionStart: this.#selectionStart,\r\n\t\t\tselectionEnd: this.#selectionEnd,\r\n\t\t\tisFocused: this.#isFocused,\r\n\t\t\thasSelection: this.hasSelection(),\r\n\t\t}\r\n\t}\r\n\r\n\tgetValue(): string {\r\n\t\treturn this.#value\r\n\t}\r\n\r\n\tisFocused(): boolean {\r\n\t\treturn this.#isFocused\r\n\t}\r\n\r\n\tgetCursorPosition(): number {\r\n\t\treturn this.#cursorPosition\r\n\t}\r\n\r\n\thasSelection(): boolean {\r\n\t\treturn this.#selectionStart !== this.#selectionEnd\r\n\t}\r\n\r\n\tsetValue(value: string): void {\r\n\t\tthis.#value = value.slice(0, this.#maxLength)\r\n\t\tthis.#cursorPosition = Math.min(this.#cursorPosition, this.#value.length)\r\n\t\tif (this.#hiddenInput) {\r\n\t\t\tthis.#hiddenInput.value = this.#value\r\n\t\t}\r\n\t}\r\n\r\n\tclear(): void {\r\n\t\tthis.setValue('')\r\n\t\tthis.#cursorPosition = 0\r\n\t\tthis.clearSelection()\r\n\t}\r\n\r\n\tfocus(): void {\r\n\t\tif (!this.#isFocused && this.#interactive) {\r\n\t\t\tthis.#isFocused = true\r\n\t\t\tthis.#cursorBlink = 0\r\n\t\t\tthis.#cursorVisible = true\r\n\t\t\tthis.#focusListeners.forEach((cb) => cb())\r\n\r\n\t\t\tif (this.#hiddenInput) {\r\n\t\t\t\tthis.#hiddenInput.value = this.#value\r\n\t\t\t\tthis.#hiddenInput.focus()\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tblur(): void {\r\n\t\tif (this.#isFocused) {\r\n\t\t\tthis.#isFocused = false\r\n\t\t\tthis.clearSelection()\r\n\t\t\tthis.#blurListeners.forEach((cb) => cb())\r\n\t\t\tthis.#changeListeners.forEach((cb) => cb(this.#value))\r\n\r\n\t\t\tif (this.#hiddenInput) {\r\n\t\t\t\tthis.#hiddenInput.blur()\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tsetCursorPosition(position: number): void {\r\n\t\tthis.#cursorPosition = Math.max(0, Math.min(position, this.#value.length))\r\n\t\tthis.#cursorBlink = 0\r\n\t\tthis.#cursorVisible = true\r\n\t}\r\n\r\n\tsetSelection(start: number, end: number): void {\r\n\t\tthis.#selectionStart = Math.max(0, Math.min(start, this.#value.length))\r\n\t\tthis.#selectionEnd = Math.max(0, Math.min(end, this.#value.length))\r\n\t}\r\n\r\n\tselectAll(): void {\r\n\t\tthis.setSelection(0, this.#value.length)\r\n\t}\r\n\r\n\tclearSelection(): void {\r\n\t\tthis.#selectionStart = 0\r\n\t\tthis.#selectionEnd = 0\r\n\t}\r\n\r\n\tinsertText(text: string): void {\r\n\t\tif (this.hasSelection()) {\r\n\t\t\tthis.deleteSelection()\r\n\t\t}\r\n\r\n\t\tconst before = this.#value.slice(0, this.#cursorPosition)\r\n\t\tconst after = this.#value.slice(this.#cursorPosition)\r\n\t\tconst newValue = (before + text + after).slice(0, this.#maxLength)\r\n\r\n\t\tthis.#value = newValue\r\n\t\tthis.#cursorPosition = Math.min(before.length + text.length, newValue.length)\r\n\r\n\t\tif (this.#hiddenInput) {\r\n\t\t\tthis.#hiddenInput.value = this.#value\r\n\t\t}\r\n\r\n\t\tthis.#inputListeners.forEach((cb) => cb(this.#value))\r\n\t}\r\n\r\n\tdeleteSelection(): void {\r\n\t\tif (!this.hasSelection()) return\r\n\r\n\t\tconst start = Math.min(this.#selectionStart, this.#selectionEnd)\r\n\t\tconst end = Math.max(this.#selectionStart, this.#selectionEnd)\r\n\r\n\t\tthis.#value = this.#value.slice(0, start) + this.#value.slice(end)\r\n\t\tthis.#cursorPosition = start\r\n\t\tthis.clearSelection()\r\n\r\n\t\tif (this.#hiddenInput) {\r\n\t\t\tthis.#hiddenInput.value = this.#value\r\n\t\t}\r\n\t}\r\n\r\n\tdeleteCharacter(forward: boolean): void {\r\n\t\tif (this.hasSelection()) {\r\n\t\t\tthis.deleteSelection()\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\tif (forward) {\r\n\t\t\tif (this.#cursorPosition < this.#value.length) {\r\n\t\t\t\tthis.#value = this.#value.slice(0, this.#cursorPosition) + this.#value.slice(this.#cursorPosition + 1)\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tif (this.#cursorPosition > 0) {\r\n\t\t\t\tthis.#value = this.#value.slice(0, this.#cursorPosition - 1) + this.#value.slice(this.#cursorPosition)\r\n\t\t\t\tthis.#cursorPosition--\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (this.#hiddenInput) {\r\n\t\t\tthis.#hiddenInput.value = this.#value\r\n\t\t}\r\n\t}\r\n\r\n\tsetPlaceholder(placeholder: string): void {\r\n\t\tthis.#placeholder = placeholder\r\n\t}\r\n\r\n\tsetMaxLength(maxLength: number): void {\r\n\t\tthis.#maxLength = maxLength\r\n\t\tif (this.#value.length > maxLength) {\r\n\t\t\tthis.#value = this.#value.slice(0, maxLength)\r\n\t\t}\r\n\t\tif (this.#hiddenInput) {\r\n\t\t\tthis.#hiddenInput.maxLength = maxLength\r\n\t\t}\r\n\t}\r\n\r\n\tsetInputType(type: TextInputType): void {\r\n\t\tthis.#inputType = type\r\n\t\tif (this.#hiddenInput) {\r\n\t\t\tthis.#hiddenInput.type = type === 'password' ? 'password' : 'text'\r\n\t\t\tthis.#hiddenInput.inputMode = type === 'number' ? 'numeric' : 'text'\r\n\t\t}\r\n\t}\r\n\r\n\tsetTextColor(color: string): void {\r\n\t\tthis.#textColor = color\r\n\t}\r\n\r\n\tsetBackgroundColor(color: string): void {\r\n\t\tthis.#backgroundColor = color\r\n\t}\r\n\r\n\tsetBorderColor(color: string): void {\r\n\t\tthis.#borderColor = color\r\n\t}\r\n\r\n\tsetFocusBorderColor(color: string): void {\r\n\t\tthis.#focusBorderColor = color\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Update & Render\r\n\t// ============================================================================\r\n\r\n\tupdate(inputState: InputState): void {\r\n\t\tif (!this.#interactive || !this.#visible) return\r\n\r\n\t\t// Blink cursor (use fixed deltaTime)\r\n\t\tconst deltaTime = 1 / 60\r\n\t\tif (this.#isFocused) {\r\n\t\t\tthis.#cursorBlink += deltaTime * 1000\r\n\t\t\tif (this.#cursorBlink >= 530) {\r\n\t\t\t\tthis.#cursorBlink = 0\r\n\t\t\t\tthis.#cursorVisible = !this.#cursorVisible\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Handle click to focus\r\n\t\tif (inputState.isPointerDown) {\r\n\t\t\tif (this.contains(inputState.pointerX, inputState.pointerY)) {\r\n\t\t\t\tif (!this.#isFocused) {\r\n\t\t\t\t\tthis.focus()\r\n\t\t\t\t}\r\n\t\t\t} else if (this.#isFocused) {\r\n\t\t\t\tthis.blur()\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\trender(context: CanvasRenderingContext2D): void {\r\n\t\tif (!this.#visible) return\r\n\r\n\t\tcontext.save()\r\n\t\tcontext.globalAlpha = this.#opacity\r\n\r\n\t\t// Draw background with border radius\r\n\t\tthis.#drawRoundedRect(context, this.#x, this.#y, this.#width, this.#height, this.#borderRadius)\r\n\t\tcontext.fillStyle = this.#backgroundColor\r\n\t\tcontext.fill()\r\n\r\n\t\t// Draw border\r\n\t\tcontext.strokeStyle = this.#isFocused ? this.#focusBorderColor : this.#borderColor\r\n\t\tcontext.lineWidth = this.#borderWidth\r\n\t\tcontext.stroke()\r\n\r\n\t\t// Set up text rendering\r\n\t\tcontext.font = `${this.#fontSize}px ${this.#fontFamily}`\r\n\t\tcontext.textBaseline = 'middle'\r\n\r\n\t\tconst textX = this.#x + this.#padding\r\n\t\tconst textY = this.#y + this.#height / 2\r\n\r\n\t\t// Clip to text area\r\n\t\tcontext.beginPath()\r\n\t\tcontext.rect(\r\n\t\t\tthis.#x + this.#borderWidth,\r\n\t\t\tthis.#y + this.#borderWidth,\r\n\t\t\tthis.#width - this.#borderWidth * 2,\r\n\t\t\tthis.#height - this.#borderWidth * 2,\r\n\t\t)\r\n\t\tcontext.clip()\r\n\r\n\t\t// Draw text or placeholder\r\n\t\tconst displayValue = this.#inputType === 'password' ? '•'.repeat(this.#value.length) : this.#value\r\n\r\n\t\tif (displayValue) {\r\n\t\t\tcontext.fillStyle = this.#textColor\r\n\t\t\tcontext.fillText(displayValue, textX, textY)\r\n\t\t} else if (this.#placeholder && !this.#isFocused) {\r\n\t\t\tcontext.fillStyle = this.#placeholderColor\r\n\t\t\tcontext.fillText(this.#placeholder, textX, textY)\r\n\t\t}\r\n\r\n\t\t// Draw cursor\r\n\t\tif (this.#isFocused && this.#cursorVisible) {\r\n\t\t\tconst textBeforeCursor = displayValue.slice(0, this.#cursorPosition)\r\n\t\t\tconst cursorX = textX + context.measureText(textBeforeCursor).width\r\n\r\n\t\t\tcontext.strokeStyle = this.#cursorColor\r\n\t\t\tcontext.lineWidth = 2\r\n\t\t\tcontext.beginPath()\r\n\t\t\tcontext.moveTo(cursorX, this.#y + this.#padding)\r\n\t\t\tcontext.lineTo(cursorX, this.#y + this.#height - this.#padding)\r\n\t\t\tcontext.stroke()\r\n\t\t}\r\n\r\n\t\tcontext.restore()\r\n\t}\r\n\r\n\t#drawRoundedRect(\r\n\t\tctx: CanvasRenderingContext2D,\r\n\t\tx: number,\r\n\t\ty: number,\r\n\t\twidth: number,\r\n\t\theight: number,\r\n\t\tradius: number,\r\n\t): void {\r\n\t\tctx.beginPath()\r\n\t\tctx.moveTo(x + radius, y)\r\n\t\tctx.lineTo(x + width - radius, y)\r\n\t\tctx.quadraticCurveTo(x + width, y, x + width, y + radius)\r\n\t\tctx.lineTo(x + width, y + height - radius)\r\n\t\tctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height)\r\n\t\tctx.lineTo(x + radius, y + height)\r\n\t\tctx.quadraticCurveTo(x, y + height, x, y + height - radius)\r\n\t\tctx.lineTo(x, y + radius)\r\n\t\tctx.quadraticCurveTo(x, y, x + radius, y)\r\n\t\tctx.closePath()\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tif (this.#hiddenInput && this.#hiddenInput.parentNode) {\r\n\t\t\tthis.#hiddenInput.parentNode.removeChild(this.#hiddenInput)\r\n\t\t}\r\n\t\tthis.#hiddenInput = null\r\n\r\n\t\tthis.#inputListeners.clear()\r\n\t\tthis.#changeListeners.clear()\r\n\t\tthis.#submitListeners.clear()\r\n\t\tthis.#focusListeners.clear()\r\n\t\tthis.#blurListeners.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tTooltipManagerInterface,\r\n\tTooltipManagerOptions,\r\n\tTooltipOptions,\r\n\tTooltipState,\r\n\tTooltipPosition,\r\n\tUIElement,\r\n\tUnsubscribe,\r\n\tInputState, AttachedTooltip,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Tooltip manager for showing contextual help on hover/long-press.\r\n */\r\nexport class TooltipManager implements TooltipManagerInterface {\r\n\t#isVisible = false\r\n\t#content = ''\r\n\t#x = 0\r\n\t#y = 0\r\n\t#position: TooltipPosition = 'top'\r\n\t#currentOptions: Partial<TooltipOptions> = {}\r\n\r\n\t#defaultDelay: number\r\n\t#defaultPosition: TooltipPosition\r\n\t#touchHoldDuration: number\r\n\r\n\t#hoverTimer = 0\r\n\t#touchHoldTimer = 0\r\n\t#hoveredElement: UIElement | null = null\r\n\t#attachedElements = new Map<string, AttachedTooltip>()\r\n\r\n\t#showListeners = new Set<(content: string) => void>()\r\n\t#hideListeners = new Set<() => void>()\r\n\r\n\tconstructor(options?: TooltipManagerOptions) {\r\n\t\tthis.#defaultDelay = options?.defaultDelay ?? 500\r\n\t\tthis.#defaultPosition = options?.defaultPosition ?? 'top'\r\n\t\tthis.#touchHoldDuration = options?.touchHoldDuration ?? 800\r\n\r\n\t\tif (options?.onShow) this.#showListeners.add(options.onShow)\r\n\t\tif (options?.onHide) this.#hideListeners.add(options.onHide)\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Subscriptions\r\n\t// ============================================================================\r\n\r\n\tonShow(callback: (content: string) => void): Unsubscribe {\r\n\t\tthis.#showListeners.add(callback)\r\n\t\treturn () => this.#showListeners.delete(callback)\r\n\t}\r\n\r\n\tonHide(callback: () => void): Unsubscribe {\r\n\t\tthis.#hideListeners.add(callback)\r\n\t\treturn () => this.#hideListeners.delete(callback)\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// State\r\n\t// ============================================================================\r\n\r\n\tgetState(): TooltipState {\r\n\t\treturn {\r\n\t\t\tisVisible: this.#isVisible,\r\n\t\t\tcontent: this.#content,\r\n\t\t\tx: this.#x,\r\n\t\t\ty: this.#y,\r\n\t\t\tposition: this.#position,\r\n\t\t}\r\n\t}\r\n\r\n\tisVisible(): boolean {\r\n\t\treturn this.#isVisible\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Show/Hide\r\n\t// ============================================================================\r\n\r\n\tshow(x: number, y: number, content: string, options?: Partial<TooltipOptions>): void {\r\n\t\tthis.#isVisible = true\r\n\t\tthis.#content = content\r\n\t\tthis.#x = x\r\n\t\tthis.#y = y\r\n\t\tthis.#position = options?.position ?? this.#defaultPosition\r\n\t\tthis.#currentOptions = options ?? {}\r\n\r\n\t\tthis.#showListeners.forEach((cb) => cb(content))\r\n\t}\r\n\r\n\thide(): void {\r\n\t\tif (this.#isVisible) {\r\n\t\t\tthis.#isVisible = false\r\n\t\t\tthis.#hideListeners.forEach((cb) => cb())\r\n\t\t}\r\n\t\tthis.#hoverTimer = 0\r\n\t\tthis.#touchHoldTimer = 0\r\n\t\tthis.#hoveredElement = null\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Element Attachment\r\n\t// ============================================================================\r\n\r\n\tattachToElement(element: UIElement, content: string, options?: Partial<TooltipOptions>): Unsubscribe {\r\n\t\tconst attached: AttachedTooltip = { element, content }\r\n\t\tif (options !== undefined) {\r\n\t\t\tattached.options = options\r\n\t\t}\r\n\t\tthis.#attachedElements.set(element.id, attached)\r\n\t\treturn () => this.detachFromElement(element)\r\n\t}\r\n\r\n\tdetachFromElement(element: UIElement): void {\r\n\t\tthis.#attachedElements.delete(element.id)\r\n\t\tif (this.#hoveredElement === element) {\r\n\t\t\tthis.hide()\r\n\t\t}\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Update & Render\r\n\t// ============================================================================\r\n\r\n\tupdate(inputState: InputState, deltaTime: number): void {\r\n\t\tconst deltaMs = deltaTime * 1000\r\n\r\n\t\t// Check if hovering over any attached elements\r\n\t\tlet foundElement: AttachedTooltip | null = null\r\n\r\n\t\tfor (const attached of this.#attachedElements.values()) {\r\n\t\t\tif (\r\n\t\t\t\tattached.element.isVisible() &&\r\n\t\t\t\tattached.element.contains(inputState.pointerX, inputState.pointerY)\r\n\t\t\t) {\r\n\t\t\t\tfoundElement = attached\r\n\t\t\t\tbreak\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Handle touch hold\r\n\t\tif (inputState.touches.length > 0) {\r\n\t\t\tconst touch = inputState.touches[0]\r\n\t\t\tif (touch) {\r\n\t\t\t\tfor (const attached of this.#attachedElements.values()) {\r\n\t\t\t\t\tif (attached.element.isVisible() && attached.element.contains(touch.x, touch.y)) {\r\n\t\t\t\t\t\tthis.#touchHoldTimer += deltaMs\r\n\t\t\t\t\t\tif (this.#touchHoldTimer >= this.#touchHoldDuration && !this.#isVisible) {\r\n\t\t\t\t\t\t\tconst bounds = attached.element.getBounds()\r\n\t\t\t\t\t\t\tthis.#showForElement(attached, bounds.x + bounds.width / 2, bounds.y)\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\treturn\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tthis.#touchHoldTimer = 0\r\n\t\t\treturn\r\n\t\t} else {\r\n\t\t\tthis.#touchHoldTimer = 0\r\n\t\t}\r\n\r\n\t\t// Handle mouse hover\r\n\t\tif (foundElement) {\r\n\t\t\tif (this.#hoveredElement !== foundElement.element) {\r\n\t\t\t\tthis.#hoveredElement = foundElement.element\r\n\t\t\t\tthis.#hoverTimer = 0\r\n\t\t\t\tthis.hide()\r\n\t\t\t}\r\n\r\n\t\t\tif (!this.#isVisible) {\r\n\t\t\t\tthis.#hoverTimer += deltaMs\r\n\t\t\t\tconst delay = foundElement.options?.delay ?? this.#defaultDelay\r\n\r\n\t\t\t\tif (this.#hoverTimer >= delay) {\r\n\t\t\t\t\tconst bounds = foundElement.element.getBounds()\r\n\t\t\t\t\tthis.#showForElement(foundElement, bounds.x + bounds.width / 2, bounds.y)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tif (this.#hoveredElement !== null) {\r\n\t\t\t\tthis.hide()\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t#showForElement(attached: AttachedTooltip, x: number, y: number): void {\r\n\t\tconst position = attached.options?.position ?? this.#defaultPosition\r\n\t\tthis.show(x, y, attached.content, { ...attached.options, position })\r\n\t}\r\n\r\n\trender(context: CanvasRenderingContext2D): void {\r\n\t\tif (!this.#isVisible) return\r\n\r\n\t\tconst padding = this.#currentOptions.padding ?? 8\r\n\t\tconst fontSize = this.#currentOptions.fontSize ?? 12\r\n\t\tconst backgroundColor = this.#currentOptions.backgroundColor ?? 'rgba(30, 30, 30, 0.95)'\r\n\t\tconst textColor = this.#currentOptions.textColor ?? '#ffffff'\r\n\t\tconst borderColor = this.#currentOptions.borderColor ?? 'rgba(100, 100, 100, 0.5)'\r\n\t\tconst borderRadius = this.#currentOptions.borderRadius ?? 4\r\n\t\tconst maxWidth = this.#currentOptions.maxWidth ?? 200\r\n\t\tconst showArrow = this.#currentOptions.arrow ?? true\r\n\r\n\t\tcontext.save()\r\n\r\n\t\t// Measure text\r\n\t\tcontext.font = `${fontSize}px sans-serif`\r\n\t\tconst lines = this.#wrapText(context, this.#content, maxWidth - padding * 2)\r\n\t\tconst textWidth = Math.min(\r\n\t\t\tmaxWidth,\r\n\t\t\tMath.max(...lines.map((line) => context.measureText(line).width)) + padding * 2,\r\n\t\t)\r\n\t\tconst textHeight = lines.length * (fontSize + 4) + padding * 2\r\n\r\n\t\t// Calculate position\r\n\t\tlet tooltipX = this.#x - textWidth / 2\r\n\t\tlet tooltipY = this.#y\r\n\t\tconst arrowSize = 6\r\n\r\n\t\tswitch (this.#position) {\r\n\t\t\tcase 'top':\r\n\t\t\t\ttooltipY = this.#y - textHeight - arrowSize\r\n\t\t\t\tbreak\r\n\t\t\tcase 'bottom':\r\n\t\t\t\ttooltipY = this.#y + arrowSize\r\n\t\t\t\tbreak\r\n\t\t\tcase 'left':\r\n\t\t\t\ttooltipX = this.#x - textWidth - arrowSize\r\n\t\t\t\ttooltipY = this.#y - textHeight / 2\r\n\t\t\t\tbreak\r\n\t\t\tcase 'right':\r\n\t\t\t\ttooltipX = this.#x + arrowSize\r\n\t\t\t\ttooltipY = this.#y - textHeight / 2\r\n\t\t\t\tbreak\r\n\t\t\tcase 'auto':\r\n\t\t\t\ttooltipY = this.#y - textHeight - arrowSize\r\n\t\t\t\tbreak\r\n\t\t}\r\n\r\n\t\t// Keep on screen\r\n\t\ttooltipX = Math.max(4, Math.min(tooltipX, context.canvas.width - textWidth - 4))\r\n\t\ttooltipY = Math.max(4, Math.min(tooltipY, context.canvas.height - textHeight - 4))\r\n\r\n\t\t// Draw background\r\n\t\tthis.#drawRoundedRect(context, tooltipX, tooltipY, textWidth, textHeight, borderRadius)\r\n\t\tcontext.fillStyle = backgroundColor\r\n\t\tcontext.fill()\r\n\t\tcontext.strokeStyle = borderColor\r\n\t\tcontext.lineWidth = 1\r\n\t\tcontext.stroke()\r\n\r\n\t\t// Draw arrow\r\n\t\tif (showArrow) {\r\n\t\t\tcontext.beginPath()\r\n\t\t\tconst arrowX = this.#x\r\n\t\t\tconst arrowY = this.#position === 'top' ? tooltipY + textHeight : tooltipY\r\n\r\n\t\t\tif (this.#position === 'top') {\r\n\t\t\t\tcontext.moveTo(arrowX - arrowSize, arrowY)\r\n\t\t\t\tcontext.lineTo(arrowX, arrowY + arrowSize)\r\n\t\t\t\tcontext.lineTo(arrowX + arrowSize, arrowY)\r\n\t\t\t} else if (this.#position === 'bottom') {\r\n\t\t\t\tcontext.moveTo(arrowX - arrowSize, arrowY)\r\n\t\t\t\tcontext.lineTo(arrowX, arrowY - arrowSize)\r\n\t\t\t\tcontext.lineTo(arrowX + arrowSize, arrowY)\r\n\t\t\t}\r\n\r\n\t\t\tcontext.closePath()\r\n\t\t\tcontext.fillStyle = backgroundColor\r\n\t\t\tcontext.fill()\r\n\t\t}\r\n\r\n\t\t// Draw text\r\n\t\tcontext.fillStyle = textColor\r\n\t\tcontext.textBaseline = 'top'\r\n\r\n\t\tlet lineY = tooltipY + padding\r\n\t\tfor (const line of lines) {\r\n\t\t\tcontext.fillText(line, tooltipX + padding, lineY)\r\n\t\t\tlineY += fontSize + 4\r\n\t\t}\r\n\r\n\t\tcontext.restore()\r\n\t}\r\n\r\n\t#wrapText(context: CanvasRenderingContext2D, text: string, maxWidth: number): string[] {\r\n\t\tconst words = text.split(' ')\r\n\t\tconst lines: string[] = []\r\n\t\tlet currentLine = ''\r\n\r\n\t\tfor (const word of words) {\r\n\t\t\tconst testLine = currentLine ? `${currentLine} ${word}` : word\r\n\t\t\tconst metrics = context.measureText(testLine)\r\n\r\n\t\t\tif (metrics.width > maxWidth && currentLine) {\r\n\t\t\t\tlines.push(currentLine)\r\n\t\t\t\tcurrentLine = word\r\n\t\t\t} else {\r\n\t\t\t\tcurrentLine = testLine\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (currentLine) {\r\n\t\t\tlines.push(currentLine)\r\n\t\t}\r\n\r\n\t\treturn lines.length > 0 ? lines : ['']\r\n\t}\r\n\r\n\t#drawRoundedRect(\r\n\t\tctx: CanvasRenderingContext2D,\r\n\t\tx: number,\r\n\t\ty: number,\r\n\t\twidth: number,\r\n\t\theight: number,\r\n\t\tradius: number,\r\n\t): void {\r\n\t\tctx.beginPath()\r\n\t\tctx.moveTo(x + radius, y)\r\n\t\tctx.lineTo(x + width - radius, y)\r\n\t\tctx.quadraticCurveTo(x + width, y, x + width, y + radius)\r\n\t\tctx.lineTo(x + width, y + height - radius)\r\n\t\tctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height)\r\n\t\tctx.lineTo(x + radius, y + height)\r\n\t\tctx.quadraticCurveTo(x, y + height, x, y + height - radius)\r\n\t\tctx.lineTo(x, y + radius)\r\n\t\tctx.quadraticCurveTo(x, y, x + radius, y)\r\n\t\tctx.closePath()\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#attachedElements.clear()\r\n\t\tthis.#showListeners.clear()\r\n\t\tthis.#hideListeners.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tDebugOverlayInterface,\r\n\tDebugOverlayOptions,\r\n\tDebugMetric,\r\n\tDebugPanelConfig,\r\n\tPerformanceMetrics,\r\n\tInputState,\r\n\tLogLevel,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\ninterface LogEntry {\r\n\tmessage: string\r\n\tlevel: LogLevel\r\n\ttimestamp: number\r\n}\r\n\r\ninterface Panel {\r\n\tconfig: DebugPanelConfig\r\n\tcollapsed: boolean\r\n}\r\n\r\n/**\r\n * Visual debug overlay with FPS, metrics, and touch visualization.\r\n */\r\nexport class DebugOverlay implements DebugOverlayInterface {\r\n\t#enabled: boolean\r\n\t#position: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'\r\n\t#showFPS: boolean\r\n\t#showMemory: boolean\r\n\t#showEntityCount: boolean\r\n\t#showDrawCalls: boolean\r\n\t#showInputState: boolean\r\n\t#showColliders: boolean\r\n\t#showTouchPoints: boolean\r\n\t#backgroundColor: string\r\n\t#textColor: string\r\n\t#fontSize: number\r\n\t#opacity: number\r\n\t#graphHeight: number\r\n\t#graphHistory: number\r\n\r\n\t#metrics = new Map<string, DebugMetric>()\r\n\t#panels = new Map<string, Panel>()\r\n\t#logs: LogEntry[] = []\r\n\t#fpsHistory: number[] = []\r\n\t#lastMetrics: PerformanceMetrics | null = null\r\n\t#lastInputState: InputState | null = null\r\n\r\n\t#toggleListeners = new Set<(enabled: boolean) => void>()\r\n\t#metricClickListeners = new Set<(name: string) => void>()\r\n\r\n\tconstructor(options?: DebugOverlayOptions) {\r\n\t\tthis.#enabled = options?.enabled ?? false\r\n\t\tthis.#position = options?.position ?? 'top-left'\r\n\t\tthis.#showFPS = options?.showFPS ?? true\r\n\t\tthis.#showMemory = options?.showMemory ?? true\r\n\t\tthis.#showEntityCount = options?.showEntityCount ?? true\r\n\t\tthis.#showDrawCalls = options?.showDrawCalls ?? false\r\n\t\tthis.#showInputState = options?.showInputState ?? false\r\n\t\tthis.#showColliders = options?.showColliders ?? false\r\n\t\tthis.#showTouchPoints = options?.showTouchPoints ?? true\r\n\t\tthis.#backgroundColor = options?.backgroundColor ?? 'rgba(0, 0, 0, 0.75)'\r\n\t\tthis.#textColor = options?.textColor ?? '#00ff00'\r\n\t\tthis.#fontSize = options?.fontSize ?? 12\r\n\t\tthis.#opacity = options?.opacity ?? 1\r\n\t\tthis.#graphHeight = options?.graphHeight ?? 40\r\n\t\tthis.#graphHistory = options?.graphHistory ?? 60\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Subscriptions\r\n\t// ============================================================================\r\n\r\n\tonToggle(callback: (enabled: boolean) => void): Unsubscribe {\r\n\t\tthis.#toggleListeners.add(callback)\r\n\t\treturn () => this.#toggleListeners.delete(callback)\r\n\t}\r\n\r\n\tonMetricClick(callback: (name: string) => void): Unsubscribe {\r\n\t\tthis.#metricClickListeners.add(callback)\r\n\t\treturn () => this.#metricClickListeners.delete(callback)\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Enable/Disable\r\n\t// ============================================================================\r\n\r\n\tisEnabled(): boolean {\r\n\t\treturn this.#enabled\r\n\t}\r\n\r\n\tenable(): void {\r\n\t\tif (!this.#enabled) {\r\n\t\t\tthis.#enabled = true\r\n\t\t\tthis.#toggleListeners.forEach((cb) => cb(true))\r\n\t\t}\r\n\t}\r\n\r\n\tdisable(): void {\r\n\t\tif (this.#enabled) {\r\n\t\t\tthis.#enabled = false\r\n\t\t\tthis.#toggleListeners.forEach((cb) => cb(false))\r\n\t\t}\r\n\t}\r\n\r\n\ttoggle(): void {\r\n\t\tif (this.#enabled) {\r\n\t\t\tthis.disable()\r\n\t\t} else {\r\n\t\t\tthis.enable()\r\n\t\t}\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Metrics\r\n\t// ============================================================================\r\n\r\n\taddMetric(metric: DebugMetric): void {\r\n\t\tthis.#metrics.set(metric.name, metric)\r\n\t}\r\n\r\n\tremoveMetric(name: string): void {\r\n\t\tthis.#metrics.delete(name)\r\n\t}\r\n\r\n\tupdateMetric(name: string, value: string | number): void {\r\n\t\tconst existing = this.#metrics.get(name)\r\n\t\tif (existing) {\r\n\t\t\tthis.#metrics.set(name, { ...existing, value })\r\n\t\t} else {\r\n\t\t\tthis.#metrics.set(name, { name, value })\r\n\t\t}\r\n\t}\r\n\r\n\tclearMetrics(): void {\r\n\t\tthis.#metrics.clear()\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Panels\r\n\t// ============================================================================\r\n\r\n\taddPanel(config: DebugPanelConfig): void {\r\n\t\tthis.#panels.set(config.name, {\r\n\t\t\tconfig,\r\n\t\t\tcollapsed: config.collapsed ?? false,\r\n\t\t})\r\n\t}\r\n\r\n\tremovePanel(name: string): void {\r\n\t\tthis.#panels.delete(name)\r\n\t}\r\n\r\n\ttogglePanel(name: string): void {\r\n\t\tconst panel = this.#panels.get(name)\r\n\t\tif (panel) {\r\n\t\t\tpanel.collapsed = !panel.collapsed\r\n\t\t}\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Show/Hide Options\r\n\t// ============================================================================\r\n\r\n\tsetShowFPS(show: boolean): void {\r\n\t\tthis.#showFPS = show\r\n\t}\r\n\r\n\tsetShowMemory(show: boolean): void {\r\n\t\tthis.#showMemory = show\r\n\t}\r\n\r\n\tsetShowColliders(show: boolean): void {\r\n\t\tthis.#showColliders = show\r\n\t}\r\n\r\n\tsetShowTouchPoints(show: boolean): void {\r\n\t\tthis.#showTouchPoints = show\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Logging\r\n\t// ============================================================================\r\n\r\n\tlog(message: string, level: LogLevel = 'info'): void {\r\n\t\tthis.#logs.push({\r\n\t\t\tmessage,\r\n\t\t\tlevel,\r\n\t\t\ttimestamp: Date.now(),\r\n\t\t})\r\n\r\n\t\t// Keep last 50 logs\r\n\t\tif (this.#logs.length > 50) {\r\n\t\t\tthis.#logs.shift()\r\n\t\t}\r\n\t}\r\n\r\n\tclearLogs(): void {\r\n\t\tthis.#logs = []\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Update & Render\r\n\t// ============================================================================\r\n\r\n\tupdate(metrics: PerformanceMetrics, inputState: InputState): void {\r\n\t\tthis.#lastMetrics = metrics\r\n\t\tthis.#lastInputState = inputState\r\n\r\n\t\t// Track FPS history\r\n\t\tthis.#fpsHistory.push(metrics.fps)\r\n\t\tif (this.#fpsHistory.length > this.#graphHistory) {\r\n\t\t\tthis.#fpsHistory.shift()\r\n\t\t}\r\n\t}\r\n\r\n\trender(context: CanvasRenderingContext2D): void {\r\n\t\tif (!this.#enabled) return\r\n\r\n\t\tcontext.save()\r\n\t\tcontext.globalAlpha = this.#opacity\r\n\r\n\t\t// Render main panel\r\n\t\tthis.#renderMainPanel(context)\r\n\r\n\t\t// Render touch points\r\n\t\tif (this.#showTouchPoints && this.#lastInputState) {\r\n\t\t\tthis.#renderTouchPoints(context)\r\n\t\t}\r\n\r\n\t\tcontext.restore()\r\n\t}\r\n\r\n\t#renderMainPanel(context: CanvasRenderingContext2D): void {\r\n\t\tconst padding = 10\r\n\t\tconst lineHeight = this.#fontSize + 4\r\n\t\tlet y = padding\r\n\r\n\t\t// Calculate panel dimensions\r\n\t\tconst lines: { text: string; color: string }[] = []\r\n\r\n\t\tif (this.#showFPS && this.#lastMetrics) {\r\n\t\t\tconst fps = this.#lastMetrics.fps\r\n\t\t\tconst color = fps >= 55 ? '#00ff00' : fps >= 30 ? '#ffff00' : '#ff0000'\r\n\t\t\tlines.push({ text: `FPS: ${fps.toFixed(0)}`, color })\r\n\t\t}\r\n\r\n\t\tif (this.#showMemory && this.#lastMetrics) {\r\n\t\t\tconst mb = (this.#lastMetrics.memoryUsed ?? 0) / 1024 / 1024\r\n\t\t\tlines.push({ text: `Memory: ${mb.toFixed(1)}MB`, color: this.#textColor })\r\n\t\t}\r\n\r\n\t\tif (this.#showEntityCount && this.#lastMetrics) {\r\n\t\t\tlines.push({ text: `Entities: ${this.#lastMetrics.entityCount}`, color: this.#textColor })\r\n\t\t}\r\n\r\n\t\tif (this.#showDrawCalls && this.#lastMetrics) {\r\n\t\t\tlines.push({ text: `Draw Calls: ${this.#lastMetrics.drawCalls}`, color: this.#textColor })\r\n\t\t}\r\n\r\n\t\t// Add custom metrics\r\n\t\tfor (const metric of this.#metrics.values()) {\r\n\t\t\tlines.push({\r\n\t\t\t\ttext: `${metric.name}: ${metric.value}`,\r\n\t\t\t\tcolor: metric.color ?? this.#textColor,\r\n\t\t\t})\r\n\t\t}\r\n\r\n\t\t// Calculate width\r\n\t\tcontext.font = `${this.#fontSize}px monospace`\r\n\t\tconst maxWidth = Math.max(...lines.map((l) => context.measureText(l.text).width))\r\n\t\tconst panelWidth = maxWidth + padding * 2\r\n\t\tconst panelHeight = lines.length * lineHeight + this.#graphHeight + padding * 3\r\n\r\n\t\t// Position based on setting\r\n\t\tlet panelX = padding\r\n\t\tlet panelY = padding\r\n\r\n\t\tswitch (this.#position) {\r\n\t\t\tcase 'top-right':\r\n\t\t\t\tpanelX = context.canvas.width - panelWidth - padding\r\n\t\t\t\tbreak\r\n\t\t\tcase 'bottom-left':\r\n\t\t\t\tpanelY = context.canvas.height - panelHeight - padding\r\n\t\t\t\tbreak\r\n\t\t\tcase 'bottom-right':\r\n\t\t\t\tpanelX = context.canvas.width - panelWidth - padding\r\n\t\t\t\tpanelY = context.canvas.height - panelHeight - padding\r\n\t\t\t\tbreak\r\n\t\t}\r\n\r\n\t\t// Draw background\r\n\t\tcontext.fillStyle = this.#backgroundColor\r\n\t\tcontext.fillRect(panelX, panelY, panelWidth, panelHeight)\r\n\r\n\t\t// Draw border\r\n\t\tcontext.strokeStyle = this.#textColor\r\n\t\tcontext.lineWidth = 1\r\n\t\tcontext.strokeRect(panelX, panelY, panelWidth, panelHeight)\r\n\r\n\t\t// Draw text\r\n\t\tcontext.textBaseline = 'top'\r\n\t\ty = panelY + padding\r\n\r\n\t\tfor (const line of lines) {\r\n\t\t\tcontext.fillStyle = line.color\r\n\t\t\tcontext.fillText(line.text, panelX + padding, y)\r\n\t\t\ty += lineHeight\r\n\t\t}\r\n\r\n\t\t// Draw FPS graph\r\n\t\tif (this.#showFPS && this.#fpsHistory.length > 1) {\r\n\t\t\tthis.#renderFPSGraph(context, panelX + padding, y + padding, panelWidth - padding * 2, this.#graphHeight)\r\n\t\t}\r\n\t}\r\n\r\n\t#renderFPSGraph(context: CanvasRenderingContext2D, x: number, y: number, width: number, height: number): void {\r\n\t\t// Background\r\n\t\tcontext.fillStyle = 'rgba(0, 0, 0, 0.5)'\r\n\t\tcontext.fillRect(x, y, width, height)\r\n\r\n\t\t// Draw 60 FPS line\r\n\t\tcontext.strokeStyle = 'rgba(100, 100, 100, 0.5)'\r\n\t\tcontext.lineWidth = 1\r\n\t\tcontext.beginPath()\r\n\t\tcontext.moveTo(x, y + height * (1 - 60 / 120))\r\n\t\tcontext.lineTo(x + width, y + height * (1 - 60 / 120))\r\n\t\tcontext.stroke()\r\n\r\n\t\t// Draw graph\r\n\t\tif (this.#fpsHistory.length < 2) return\r\n\r\n\t\tcontext.beginPath()\r\n\t\tcontext.strokeStyle = '#00ff00'\r\n\t\tcontext.lineWidth = 1\r\n\r\n\t\tconst stepX = width / (this.#graphHistory - 1)\r\n\r\n\t\tfor (let i = 0; i < this.#fpsHistory.length; i++) {\r\n\t\t\tconst fps = this.#fpsHistory[i] ?? 0\r\n\t\t\tconst normalizedFPS = Math.min(fps / 120, 1)\r\n\t\t\tconst px = x + i * stepX\r\n\t\t\tconst py = y + height * (1 - normalizedFPS)\r\n\r\n\t\t\tif (i === 0) {\r\n\t\t\t\tcontext.moveTo(px, py)\r\n\t\t\t} else {\r\n\t\t\t\tcontext.lineTo(px, py)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tcontext.stroke()\r\n\t}\r\n\r\n\t#renderTouchPoints(context: CanvasRenderingContext2D): void {\r\n\t\tif (!this.#lastInputState) return\r\n\r\n\t\tfor (const touch of this.#lastInputState.touches) {\r\n\t\t\t// Outer ring\r\n\t\t\tcontext.beginPath()\r\n\t\t\tcontext.arc(touch.x, touch.y, 30, 0, Math.PI * 2)\r\n\t\t\tcontext.strokeStyle = 'rgba(255, 255, 255, 0.5)'\r\n\t\t\tcontext.lineWidth = 2\r\n\t\t\tcontext.stroke()\r\n\r\n\t\t\t// Inner circle\r\n\t\t\tcontext.beginPath()\r\n\t\t\tcontext.arc(touch.x, touch.y, 10, 0, Math.PI * 2)\r\n\t\t\tcontext.fillStyle = 'rgba(100, 150, 255, 0.8)'\r\n\t\t\tcontext.fill()\r\n\r\n\t\t\t// Touch ID\r\n\t\t\tcontext.fillStyle = '#ffffff'\r\n\t\t\tcontext.font = '10px monospace'\r\n\t\t\tcontext.textAlign = 'center'\r\n\t\t\tcontext.textBaseline = 'middle'\r\n\t\t\tcontext.fillText(String(touch.id), touch.x, touch.y)\r\n\t\t}\r\n\r\n\t\t// Pointer position\r\n\t\tcontext.beginPath()\r\n\t\tcontext.arc(this.#lastInputState.pointerX, this.#lastInputState.pointerY, 5, 0, Math.PI * 2)\r\n\t\tcontext.fillStyle = this.#lastInputState.isPointerDown ? 'rgba(255, 100, 100, 0.8)' : 'rgba(100, 255, 100, 0.8)'\r\n\t\tcontext.fill()\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#metrics.clear()\r\n\t\tthis.#panels.clear()\r\n\t\tthis.#logs = []\r\n\t\tthis.#fpsHistory = []\r\n\t\tthis.#toggleListeners.clear()\r\n\t\tthis.#metricClickListeners.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tSpriteBatchInterface,\r\n\tSpriteBatchOptions,\r\n\tBatchItem,\r\n\tBatchStats,\r\n\tSpriteRenderOptions,\r\n\tAssetManagerInterface,\r\n} from '../../types.js'\r\n\r\ninterface QueuedItem extends BatchItem {\r\n\tdepth: number\r\n}\r\n\r\ninterface MutableStats {\r\n\tbatchCount: number\r\n\tspriteCount: number\r\n\tdrawCalls: number\r\n\ttextureSwaps: number\r\n}\r\n\r\n/**\r\n * Sprite batch renderer for optimized sprite drawing.\r\n * Groups sprites by texture and draws them together to reduce draw calls.\r\n */\r\nexport class SpriteBatch implements SpriteBatchInterface {\r\n\t#context: CanvasRenderingContext2D\r\n\t#assets: AssetManagerInterface\r\n\t#maxBatchSize: number\r\n\t#sortByTexture: boolean\r\n\t#sortByDepth: boolean\r\n\r\n\t#queue: QueuedItem[] = []\r\n\t#isActive = false\r\n\t#depthCounter = 0\r\n\r\n\t#stats: MutableStats = {\r\n\t\tbatchCount: 0,\r\n\t\tspriteCount: 0,\r\n\t\tdrawCalls: 0,\r\n\t\ttextureSwaps: 0,\r\n\t}\r\n\r\n\tconstructor(context: CanvasRenderingContext2D, assets: AssetManagerInterface, options?: SpriteBatchOptions) {\r\n\t\tthis.#context = context\r\n\t\tthis.#assets = assets\r\n\t\tthis.#maxBatchSize = options?.maxBatchSize ?? 1000\r\n\t\tthis.#sortByTexture = options?.sortByTexture ?? true\r\n\t\tthis.#sortByDepth = options?.sortByDepth ?? false\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Stats\r\n\t// ============================================================================\r\n\r\n\tgetStats(): BatchStats {\r\n\t\treturn { ...this.#stats }\r\n\t}\r\n\r\n\t// ============================================================================\r\n\t// Batch Operations\r\n\t// ============================================================================\r\n\r\n\tbegin(): void {\r\n\t\tif (this.#isActive) {\r\n\t\t\tthrow new Error('SpriteBatch already active. Call end() before begin().')\r\n\t\t}\r\n\t\tthis.#isActive = true\r\n\t\tthis.#queue = []\r\n\t\tthis.#depthCounter = 0\r\n\t\tthis.#stats = {\r\n\t\t\tbatchCount: 0,\r\n\t\t\tspriteCount: 0,\r\n\t\t\tdrawCalls: 0,\r\n\t\t\ttextureSwaps: 0,\r\n\t\t}\r\n\t}\r\n\r\n\tdraw(item: BatchItem): void {\r\n\t\tif (!this.#isActive) {\r\n\t\t\tthrow new Error('SpriteBatch not active. Call begin() first.')\r\n\t\t}\r\n\r\n\t\tthis.#queue.push({\r\n\t\t\t...item,\r\n\t\t\tdepth: this.#depthCounter++,\r\n\t\t})\r\n\r\n\t\tif (this.#queue.length >= this.#maxBatchSize) {\r\n\t\t\tthis.flush()\r\n\t\t}\r\n\t}\r\n\r\n\tdrawSprite(sprite: SpriteRenderOptions, textureKey: string): void {\r\n\t\t// Get image dimensions from asset manager\r\n\t\tconst image = this.#assets.getImage(textureKey)\r\n\t\tconst width = image?.width ?? 32\r\n\t\tconst height = image?.height ?? 32\r\n\r\n\t\tthis.draw({\r\n\t\t\ttextureKey,\r\n\t\t\tx: sprite.x,\r\n\t\t\ty: sprite.y,\r\n\t\t\twidth,\r\n\t\t\theight,\r\n\t\t\tsourceX: 0,\r\n\t\t\tsourceY: 0,\r\n\t\t\tsourceWidth: width,\r\n\t\t\tsourceHeight: height,\r\n\t\t\trotation: sprite.rotation ?? 0,\r\n\t\t\tscaleX: sprite.scaleX ?? 1,\r\n\t\t\tscaleY: sprite.scaleY ?? 1,\r\n\t\t\topacity: sprite.alpha ?? 1,\r\n\t\t})\r\n\t}\r\n\r\n\tend(): void {\r\n\t\tif (!this.#isActive) {\r\n\t\t\tthrow new Error('SpriteBatch not active. Call begin() first.')\r\n\t\t}\r\n\r\n\t\tthis.flush()\r\n\t\tthis.#isActive = false\r\n\t}\r\n\r\n\tflush(): void {\r\n\t\tif (this.#queue.length === 0) return\r\n\r\n\t\t// Sort queue\r\n\t\tif (this.#sortByTexture) {\r\n\t\t\tthis.#queue.sort((a, b) => {\r\n\t\t\t\t// Primary sort by texture\r\n\t\t\t\tif (a.textureKey !== b.textureKey) {\r\n\t\t\t\t\treturn a.textureKey.localeCompare(b.textureKey)\r\n\t\t\t\t}\r\n\t\t\t\t// Secondary sort by depth\r\n\t\t\t\treturn a.depth - b.depth\r\n\t\t\t})\r\n\t\t} else if (this.#sortByDepth) {\r\n\t\t\tthis.#queue.sort((a, b) => a.depth - b.depth)\r\n\t\t}\r\n\r\n\t\t// Draw items in batches by texture\r\n\t\tlet currentTexture: string | null = null\r\n\t\tlet currentImage: HTMLImageElement | null = null\r\n\t\tlet batchStart = 0\r\n\r\n\t\tfor (let i = 0; i <= this.#queue.length; i++) {\r\n\t\t\tconst item = this.#queue[i]\r\n\t\t\tconst textureChanged = item === undefined || item.textureKey !== currentTexture\r\n\r\n\t\t\tif (textureChanged && batchStart < i) {\r\n\t\t\t\t// Draw the current batch\r\n\t\t\t\tthis.#drawBatch(this.#queue.slice(batchStart, i), currentImage)\r\n\t\t\t\tbatchStart = i\r\n\t\t\t}\r\n\r\n\t\t\tif (item) {\r\n\t\t\t\tif (item.textureKey !== currentTexture) {\r\n\t\t\t\t\tcurrentTexture = item.textureKey\r\n\t\t\t\t\tcurrentImage = this.#assets.getImage(item.textureKey) ?? null\r\n\t\t\t\t\tif (currentImage) {\r\n\t\t\t\t\t\tthis.#stats.textureSwaps++\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tthis.#stats.spriteCount += this.#queue.length\r\n\t\tthis.#queue = []\r\n\t}\r\n\r\n\t#drawBatch(items: QueuedItem[], image: HTMLImageElement | null): void {\r\n\t\tif (items.length === 0) return\r\n\r\n\t\tthis.#stats.batchCount++\r\n\r\n\t\tfor (const item of items) {\r\n\t\t\tthis.#drawItem(item, image)\r\n\t\t\tthis.#stats.drawCalls++\r\n\t\t}\r\n\t}\r\n\r\n\t#drawItem(item: QueuedItem, image: HTMLImageElement | null): void {\r\n\t\tconst ctx = this.#context\r\n\r\n\t\tctx.save()\r\n\r\n\t\t// Apply transformations\r\n\t\tctx.globalAlpha = item.opacity\r\n\r\n\t\t// Translate to position\r\n\t\tctx.translate(item.x + item.width / 2, item.y + item.height / 2)\r\n\r\n\t\t// Rotate\r\n\t\tif (item.rotation !== 0) {\r\n\t\t\tctx.rotate(item.rotation)\r\n\t\t}\r\n\r\n\t\t// Scale\r\n\t\tif (item.scaleX !== 1 || item.scaleY !== 1) {\r\n\t\t\tctx.scale(item.scaleX, item.scaleY)\r\n\t\t}\r\n\r\n\t\t// Draw\r\n\t\tconst drawX = -item.width / 2\r\n\t\tconst drawY = -item.height / 2\r\n\r\n\t\tif (image) {\r\n\t\t\tctx.drawImage(\r\n\t\t\t\timage,\r\n\t\t\t\titem.sourceX,\r\n\t\t\t\titem.sourceY,\r\n\t\t\t\titem.sourceWidth,\r\n\t\t\t\titem.sourceHeight,\r\n\t\t\t\tdrawX,\r\n\t\t\t\tdrawY,\r\n\t\t\t\titem.width,\r\n\t\t\t\titem.height,\r\n\t\t\t)\r\n\t\t} else {\r\n\t\t\t// Fallback: draw placeholder\r\n\t\t\tctx.fillStyle = item.tint ?? '#ff00ff'\r\n\t\t\tctx.fillRect(drawX, drawY, item.width, item.height)\r\n\t\t}\r\n\r\n\t\t// Apply tint (simple multiply approximation)\r\n\t\tif (item.tint && image) {\r\n\t\t\tctx.globalCompositeOperation = 'multiply'\r\n\t\t\tctx.fillStyle = item.tint\r\n\t\t\tctx.fillRect(drawX, drawY, item.width, item.height)\r\n\t\t\tctx.globalCompositeOperation = 'destination-in'\r\n\t\t\tctx.drawImage(\r\n\t\t\t\timage,\r\n\t\t\t\titem.sourceX,\r\n\t\t\t\titem.sourceY,\r\n\t\t\t\titem.sourceWidth,\r\n\t\t\t\titem.sourceHeight,\r\n\t\t\t\tdrawX,\r\n\t\t\t\tdrawY,\r\n\t\t\t\titem.width,\r\n\t\t\t\titem.height,\r\n\t\t\t)\r\n\t\t}\r\n\r\n\t\tctx.restore()\r\n\t}\r\n\r\n\tisActive(): boolean {\r\n\t\treturn this.#isActive\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#queue = []\r\n\t}\r\n}\r\n","import type {\r\n\tStorageBackendInterface,\r\n\tLocalStorageBackendOptions,\r\n} from '../../types.js'\r\n\r\n/**\r\n * LocalStorage-based storage backend.\r\n */\r\nexport class LocalStorageBackend implements StorageBackendInterface {\r\n\treadonly name = 'localStorage'\r\n\treadonly isLocal = true\r\n\r\n\t#prefix: string\r\n\t#serialize: (value: unknown) => string\r\n\t#deserialize: (value: string) => unknown\r\n\r\n\tconstructor(options?: LocalStorageBackendOptions) {\r\n\t\tthis.#prefix = options?.prefix ?? 'tactica:'\r\n\t\tthis.#serialize = options?.serialize ?? JSON.stringify\r\n\t\tthis.#deserialize = options?.deserialize ?? JSON.parse\r\n\t}\r\n\r\n\tasync isAvailable(): Promise<boolean> {\r\n\t\ttry {\r\n\t\t\tconst testKey = '__tactica_test__'\r\n\t\t\tlocalStorage.setItem(testKey, 'test')\r\n\t\t\tlocalStorage.removeItem(testKey)\r\n\t\t\treturn true\r\n\t\t} catch {\r\n\t\t\treturn false\r\n\t\t}\r\n\t}\r\n\r\n\tasync get<T>(key: string): Promise<T | undefined> {\r\n\t\tconst prefixedKey = this.#prefix + key\r\n\t\tconst value = localStorage.getItem(prefixedKey)\r\n\t\tif (value === null) return undefined\r\n\r\n\t\ttry {\r\n\t\t\treturn this.#deserialize(value) as T\r\n\t\t} catch {\r\n\t\t\treturn undefined\r\n\t\t}\r\n\t}\r\n\r\n\tasync set<T>(key: string, value: T): Promise<void> {\r\n\t\tconst prefixedKey = this.#prefix + key\r\n\t\tconst serialized = this.#serialize(value)\r\n\t\tlocalStorage.setItem(prefixedKey, serialized)\r\n\t}\r\n\r\n\tasync delete(key: string): Promise<void> {\r\n\t\tconst prefixedKey = this.#prefix + key\r\n\t\tlocalStorage.removeItem(prefixedKey)\r\n\t}\r\n\r\n\tasync clear(): Promise<void> {\r\n\t\tconst keysToRemove: string[] = []\r\n\t\tfor (let i = 0; i < localStorage.length; i++) {\r\n\t\t\tconst key = localStorage.key(i)\r\n\t\t\tif (key && key.startsWith(this.#prefix)) {\r\n\t\t\t\tkeysToRemove.push(key)\r\n\t\t\t}\r\n\t\t}\r\n\t\tfor (const key of keysToRemove) {\r\n\t\t\tlocalStorage.removeItem(key)\r\n\t\t}\r\n\t}\r\n\r\n\tasync keys(): Promise<readonly string[]> {\r\n\t\tconst result: string[] = []\r\n\t\tfor (let i = 0; i < localStorage.length; i++) {\r\n\t\t\tconst key = localStorage.key(i)\r\n\t\t\tif (key && key.startsWith(this.#prefix)) {\r\n\t\t\t\tresult.push(key.slice(this.#prefix.length))\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn result\r\n\t}\r\n\r\n\tasync has(key: string): Promise<boolean> {\r\n\t\tconst prefixedKey = this.#prefix + key\r\n\t\treturn localStorage.getItem(prefixedKey) !== null\r\n\t}\r\n\r\n\tasync getMany<T>(keys: readonly string[]): Promise<ReadonlyMap<string, T>> {\r\n\t\tconst result = new Map<string, T>()\r\n\t\tfor (const key of keys) {\r\n\t\t\tconst value = await this.get<T>(key)\r\n\t\t\tif (value !== undefined) {\r\n\t\t\t\tresult.set(key, value)\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn result\r\n\t}\r\n\r\n\tasync setMany<T>(entries: ReadonlyMap<string, T>): Promise<void> {\r\n\t\tfor (const [key, value] of entries) {\r\n\t\t\tawait this.set(key, value)\r\n\t\t}\r\n\t}\r\n\r\n\tasync deleteMany(keys: readonly string[]): Promise<void> {\r\n\t\tfor (const key of keys) {\r\n\t\t\tawait this.delete(key)\r\n\t\t}\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\t// No cleanup needed for localStorage\r\n\t}\r\n}\r\n","import type {\r\n\tStorageBackendInterface,\r\n\tIndexedDBBackendOptions,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\n/**\r\n * IndexedDB-based storage backend.\r\n */\r\nexport class IndexedDBBackend implements StorageBackendInterface {\r\n\treadonly name = 'indexedDB'\r\n\treadonly isLocal = true\r\n\r\n\t#db: IDBDatabase\r\n\t#storeName: string\r\n\t#syncChannel: BroadcastChannel | null = null\r\n\t#syncListeners = new Set<(keys: readonly string[]) => void>()\r\n\r\n\tprivate constructor(db: IDBDatabase, storeName: string, channelName?: string) {\r\n\t\tthis.#db = db\r\n\t\tthis.#storeName = storeName\r\n\r\n\t\t// Set up sync channel for cross-tab communication\r\n\t\tif (typeof BroadcastChannel !== 'undefined' && channelName) {\r\n\t\t\tthis.#syncChannel = new BroadcastChannel(channelName)\r\n\t\t\tthis.#syncChannel.onmessage = (event) => {\r\n\t\t\t\tconst keys = event.data?.keys\r\n\t\t\t\tif (Array.isArray(keys)) {\r\n\t\t\t\t\tthis.#syncListeners.forEach((cb) => cb(keys))\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Create and open an IndexedDB backend.\r\n\t */\r\n\tstatic async create(options: IndexedDBBackendOptions): Promise<IndexedDBBackend> {\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tconst request = indexedDB.open(options.databaseName, options.version ?? 1)\r\n\r\n\t\t\trequest.onupgradeneeded = (event) => {\r\n\t\t\t\tconst db = (event.target as IDBOpenDBRequest).result\r\n\t\t\t\tif (!db.objectStoreNames.contains(options.storeName)) {\r\n\t\t\t\t\tdb.createObjectStore(options.storeName)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\trequest.onsuccess = () => {\r\n\t\t\t\tconst db = request.result\r\n\t\t\t\tconst channelName = `${options.databaseName}-${options.storeName}-sync`\r\n\t\t\t\tresolve(new IndexedDBBackend(db, options.storeName, channelName))\r\n\t\t\t}\r\n\r\n\t\t\trequest.onerror = () => {\r\n\t\t\t\treject(request.error)\r\n\t\t\t}\r\n\t\t})\r\n\t}\r\n\r\n\tasync isAvailable(): Promise<boolean> {\r\n\t\ttry {\r\n\t\t\treturn typeof indexedDB !== 'undefined'\r\n\t\t} catch {\r\n\t\t\treturn false\r\n\t\t}\r\n\t}\r\n\r\n\tasync get<T>(key: string): Promise<T | undefined> {\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tconst transaction = this.#db.transaction(this.#storeName, 'readonly')\r\n\t\t\tconst store = transaction.objectStore(this.#storeName)\r\n\t\t\tconst request = store.get(key)\r\n\r\n\t\t\trequest.onsuccess = () => {\r\n\t\t\t\tresolve(request.result as T | undefined)\r\n\t\t\t}\r\n\r\n\t\t\trequest.onerror = () => {\r\n\t\t\t\treject(request.error)\r\n\t\t\t}\r\n\t\t})\r\n\t}\r\n\r\n\tasync set<T>(key: string, value: T): Promise<void> {\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tconst transaction = this.#db.transaction(this.#storeName, 'readwrite')\r\n\t\t\tconst store = transaction.objectStore(this.#storeName)\r\n\t\t\tconst request = store.put(value, key)\r\n\r\n\t\t\trequest.onsuccess = () => {\r\n\t\t\t\tthis.#notifySync([key])\r\n\t\t\t\tresolve()\r\n\t\t\t}\r\n\r\n\t\t\trequest.onerror = () => {\r\n\t\t\t\treject(request.error)\r\n\t\t\t}\r\n\t\t})\r\n\t}\r\n\r\n\tasync delete(key: string): Promise<void> {\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tconst transaction = this.#db.transaction(this.#storeName, 'readwrite')\r\n\t\t\tconst store = transaction.objectStore(this.#storeName)\r\n\t\t\tconst request = store.delete(key)\r\n\r\n\t\t\trequest.onsuccess = () => {\r\n\t\t\t\tthis.#notifySync([key])\r\n\t\t\t\tresolve()\r\n\t\t\t}\r\n\r\n\t\t\trequest.onerror = () => {\r\n\t\t\t\treject(request.error)\r\n\t\t\t}\r\n\t\t})\r\n\t}\r\n\r\n\tasync clear(): Promise<void> {\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tconst transaction = this.#db.transaction(this.#storeName, 'readwrite')\r\n\t\t\tconst store = transaction.objectStore(this.#storeName)\r\n\t\t\tconst request = store.clear()\r\n\r\n\t\t\trequest.onsuccess = () => {\r\n\t\t\t\tthis.#notifySync(['*'])\r\n\t\t\t\tresolve()\r\n\t\t\t}\r\n\r\n\t\t\trequest.onerror = () => {\r\n\t\t\t\treject(request.error)\r\n\t\t\t}\r\n\t\t})\r\n\t}\r\n\r\n\tasync keys(): Promise<readonly string[]> {\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tconst transaction = this.#db.transaction(this.#storeName, 'readonly')\r\n\t\t\tconst store = transaction.objectStore(this.#storeName)\r\n\t\t\tconst request = store.getAllKeys()\r\n\r\n\t\t\trequest.onsuccess = () => {\r\n\t\t\t\tresolve(request.result.map(String))\r\n\t\t\t}\r\n\r\n\t\t\trequest.onerror = () => {\r\n\t\t\t\treject(request.error)\r\n\t\t\t}\r\n\t\t})\r\n\t}\r\n\r\n\tasync has(key: string): Promise<boolean> {\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tconst transaction = this.#db.transaction(this.#storeName, 'readonly')\r\n\t\t\tconst store = transaction.objectStore(this.#storeName)\r\n\t\t\tconst request = store.count(key)\r\n\r\n\t\t\trequest.onsuccess = () => {\r\n\t\t\t\tresolve(request.result > 0)\r\n\t\t\t}\r\n\r\n\t\t\trequest.onerror = () => {\r\n\t\t\t\treject(request.error)\r\n\t\t\t}\r\n\t\t})\r\n\t}\r\n\r\n\tasync getMany<T>(keys: readonly string[]): Promise<ReadonlyMap<string, T>> {\r\n\t\tconst result = new Map<string, T>()\r\n\t\tconst transaction = this.#db.transaction(this.#storeName, 'readonly')\r\n\t\tconst store = transaction.objectStore(this.#storeName)\r\n\r\n\t\tconst promises = keys.map(\r\n\t\t\t(key) =>\r\n\t\t\t\tnew Promise<void>((resolve, reject) => {\r\n\t\t\t\t\tconst request = store.get(key)\r\n\t\t\t\t\trequest.onsuccess = () => {\r\n\t\t\t\t\t\tif (request.result !== undefined) {\r\n\t\t\t\t\t\t\tresult.set(key, request.result as T)\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tresolve()\r\n\t\t\t\t\t}\r\n\t\t\t\t\trequest.onerror = () => reject(request.error)\r\n\t\t\t\t}),\r\n\t\t)\r\n\r\n\t\tawait Promise.all(promises)\r\n\t\treturn result\r\n\t}\r\n\r\n\tasync setMany<T>(entries: ReadonlyMap<string, T>): Promise<void> {\r\n\t\tconst transaction = this.#db.transaction(this.#storeName, 'readwrite')\r\n\t\tconst store = transaction.objectStore(this.#storeName)\r\n\t\tconst keys: string[] = []\r\n\r\n\t\tconst promises = Array.from(entries).map(\r\n\t\t\t([key, value]) =>\r\n\t\t\t\tnew Promise<void>((resolve, reject) => {\r\n\t\t\t\t\tconst request = store.put(value, key)\r\n\t\t\t\t\trequest.onsuccess = () => {\r\n\t\t\t\t\t\tkeys.push(key)\r\n\t\t\t\t\t\tresolve()\r\n\t\t\t\t\t}\r\n\t\t\t\t\trequest.onerror = () => reject(request.error)\r\n\t\t\t\t}),\r\n\t\t)\r\n\r\n\t\tawait Promise.all(promises)\r\n\t\tthis.#notifySync(keys)\r\n\t}\r\n\r\n\tasync deleteMany(keys: readonly string[]): Promise<void> {\r\n\t\tconst transaction = this.#db.transaction(this.#storeName, 'readwrite')\r\n\t\tconst store = transaction.objectStore(this.#storeName)\r\n\r\n\t\tconst promises = keys.map(\r\n\t\t\t(key) =>\r\n\t\t\t\tnew Promise<void>((resolve, reject) => {\r\n\t\t\t\t\tconst request = store.delete(key)\r\n\t\t\t\t\trequest.onsuccess = () => resolve()\r\n\t\t\t\t\trequest.onerror = () => reject(request.error)\r\n\t\t\t\t}),\r\n\t\t)\r\n\r\n\t\tawait Promise.all(promises)\r\n\t\tthis.#notifySync([...keys])\r\n\t}\r\n\r\n\tonSync(callback: (keys: readonly string[]) => void): Unsubscribe {\r\n\t\tthis.#syncListeners.add(callback)\r\n\t\treturn () => this.#syncListeners.delete(callback)\r\n\t}\r\n\r\n\t#notifySync(keys: string[]): void {\r\n\t\tif (this.#syncChannel) {\r\n\t\t\tthis.#syncChannel.postMessage({ keys })\r\n\t\t}\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#db.close()\r\n\t\tif (this.#syncChannel) {\r\n\t\t\tthis.#syncChannel.close()\r\n\t\t}\r\n\t\tthis.#syncListeners.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tMigrationRunnerInterface,\r\n\tMigrationRunnerOptions,\r\n\tMigrationDefinition,\r\n\tMigrationResult,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Data migration runner for versioned data.\r\n */\r\nexport class MigrationRunner implements MigrationRunnerInterface {\r\n\t#migrations: readonly MigrationDefinition[]\r\n\t#validateAfterMigration: boolean\r\n\t#onProgress?: (migration: string, progress: number) => void\r\n\t#currentDataVersion = 0\r\n\r\n\tconstructor(options: MigrationRunnerOptions) {\r\n\t\t// Sort migrations by version\r\n\t\tthis.#migrations = [...options.migrations].sort((a, b) => a.version - b.version)\r\n\t\tthis.#validateAfterMigration = options.validateAfterMigration ?? true\r\n\t\tif (options.onProgress) {\r\n\t\t\tthis.#onProgress = options.onProgress\r\n\t\t}\r\n\t}\r\n\r\n\tgetCurrentVersion(): number {\r\n\t\treturn this.#currentDataVersion\r\n\t}\r\n\r\n\tgetTargetVersion(): number {\r\n\t\tconst lastMigration = this.#migrations[this.#migrations.length - 1]\r\n\t\treturn lastMigration?.version ?? 0\r\n\t}\r\n\r\n\tgetPendingMigrations(): readonly MigrationDefinition[] {\r\n\t\treturn this.#migrations.filter((m) => m.version > this.#currentDataVersion)\r\n\t}\r\n\r\n\thasPendingMigrations(): boolean {\r\n\t\treturn this.getPendingMigrations().length > 0\r\n\t}\r\n\r\n\tasync migrate(data: unknown, fromVersion: number): Promise<MigrationResult> {\r\n\t\treturn this.migrateToVersion(data, fromVersion, this.getTargetVersion())\r\n\t}\r\n\r\n\tasync migrateToVersion(data: unknown, fromVersion: number, toVersion: number): Promise<MigrationResult> {\r\n\t\tconst startTime = performance.now()\r\n\t\tconst migrationsRun: string[] = []\r\n\t\tconst errors: string[] = []\r\n\t\tlet currentData = data\r\n\t\tlet currentVersion = fromVersion\r\n\r\n\t\tthis.#currentDataVersion = fromVersion\r\n\r\n\t\t// Get migrations to run\r\n\t\tconst migrationsToRun = this.#migrations.filter(\r\n\t\t\t(m) => m.version > fromVersion && m.version <= toVersion,\r\n\t\t)\r\n\r\n\t\tif (migrationsToRun.length === 0) {\r\n\t\t\treturn {\r\n\t\t\t\tsuccess: true,\r\n\t\t\t\tfromVersion,\r\n\t\t\t\ttoVersion: fromVersion,\r\n\t\t\t\tmigrationsRun: [],\r\n\t\t\t\terrors: [],\r\n\t\t\t\tduration: performance.now() - startTime,\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst totalMigrations = migrationsToRun.length\r\n\r\n\t\tfor (const migration of migrationsToRun) {\r\n\t\t\ttry {\r\n\t\t\t\t// Report progress\r\n\t\t\t\tif (this.#onProgress) {\r\n\t\t\t\t\tconst progress = (migrationsRun.length + 1) / totalMigrations\r\n\t\t\t\t\tthis.#onProgress(migration.name, progress)\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Run migration\r\n\t\t\t\tcurrentData = await migration.up(currentData)\r\n\t\t\t\tcurrentVersion = migration.version\r\n\t\t\t\tthis.#currentDataVersion = currentVersion\r\n\t\t\t\tmigrationsRun.push(migration.name)\r\n\r\n\t\t\t\t// Validate if enabled\r\n\t\t\t\tif (this.#validateAfterMigration) {\r\n\t\t\t\t\tif (!this.validate(currentData, currentVersion)) {\r\n\t\t\t\t\t\terrors.push(`Validation failed after migration: ${migration.name}`)\r\n\t\t\t\t\t\tbreak\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t} catch (error) {\r\n\t\t\t\tconst message = error instanceof Error ? error.message : String(error)\r\n\t\t\t\terrors.push(`Migration \"${migration.name}\" failed: ${message}`)\r\n\t\t\t\tbreak\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn {\r\n\t\t\tsuccess: errors.length === 0,\r\n\t\t\tfromVersion,\r\n\t\t\ttoVersion: currentVersion,\r\n\t\t\tmigrationsRun,\r\n\t\t\terrors,\r\n\t\t\tduration: performance.now() - startTime,\r\n\t\t}\r\n\t}\r\n\r\n\tasync rollback(data: unknown, toVersion: number): Promise<MigrationResult> {\r\n\t\tconst startTime = performance.now()\r\n\t\tconst migrationsRun: string[] = []\r\n\t\tconst errors: string[] = []\r\n\t\tlet currentData = data\r\n\t\tconst fromVersion = this.#currentDataVersion\r\n\r\n\t\t// Get migrations to rollback (in reverse order)\r\n\t\tconst migrationsToRollback = this.#migrations\r\n\t\t\t.filter((m) => m.version > toVersion && m.version <= fromVersion)\r\n\t\t\t.reverse()\r\n\r\n\t\tif (migrationsToRollback.length === 0) {\r\n\t\t\treturn {\r\n\t\t\t\tsuccess: true,\r\n\t\t\t\tfromVersion,\r\n\t\t\t\ttoVersion,\r\n\t\t\t\tmigrationsRun: [],\r\n\t\t\t\terrors: [],\r\n\t\t\t\tduration: performance.now() - startTime,\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst totalMigrations = migrationsToRollback.length\r\n\r\n\t\tfor (const migration of migrationsToRollback) {\r\n\t\t\tif (!migration.down) {\r\n\t\t\t\terrors.push(`Migration \"${migration.name}\" does not support rollback`)\r\n\t\t\t\tbreak\r\n\t\t\t}\r\n\r\n\t\t\ttry {\r\n\t\t\t\t// Report progress\r\n\t\t\t\tif (this.#onProgress) {\r\n\t\t\t\t\tconst progress = (migrationsRun.length + 1) / totalMigrations\r\n\t\t\t\t\tthis.#onProgress(migration.name, progress)\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Run rollback\r\n\t\t\t\tcurrentData = await migration.down(currentData)\r\n\r\n\t\t\t\t// Set version to previous migration\r\n\t\t\t\tconst prevMigration = this.#migrations.find(\r\n\t\t\t\t\t(m) => m.version === migration.version - 1,\r\n\t\t\t\t)\r\n\t\t\t\tthis.#currentDataVersion = prevMigration?.version ?? 0\r\n\t\t\t\tmigrationsRun.push(migration.name)\r\n\t\t\t} catch (error) {\r\n\t\t\t\tconst message = error instanceof Error ? error.message : String(error)\r\n\t\t\t\terrors.push(`Rollback \"${migration.name}\" failed: ${message}`)\r\n\t\t\t\tbreak\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn {\r\n\t\t\tsuccess: errors.length === 0,\r\n\t\t\tfromVersion,\r\n\t\t\ttoVersion: this.#currentDataVersion,\r\n\t\t\tmigrationsRun,\r\n\t\t\terrors,\r\n\t\t\tduration: performance.now() - startTime,\r\n\t\t}\r\n\t}\r\n\r\n\tvalidate(_data: unknown, _version: number): boolean {\r\n\t\t// Default validation always passes\r\n\t\t// Override in subclass or provide custom validator\r\n\t\treturn true\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\t// No cleanup needed\r\n\t}\r\n}\r\n","import type {\r\n\tActiveBuff,\r\n\tBuffConfig,\r\n\tBuffSystemInterface,\r\n\tBuffSystemOptions,\r\n\tBuffSystemState,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\nimport { generateId } from '../../helpers.js'\r\n\r\n/**\r\n * BuffSystem implementation for managing stackable buffs and debuffs.\r\n *\r\n * @example\r\n * ```ts\r\n * type MyBuffs = 'speed' | 'damage' | 'shield'\r\n * const buffs = createBuffSystem<MyBuffs>({\r\n * configs: {\r\n * speed: { type: 'speed', maxStacks: 3, duration: 10, effectPerStack: 0.15 },\r\n * damage: { type: 'damage', maxStacks: 3, duration: 10, effectPerStack: 0.2 },\r\n * }\r\n * })\r\n * buffs.apply('speed', currentTime)\r\n * ```\r\n */\r\nexport class BuffSystem<TType extends string> implements BuffSystemInterface<TType> {\r\n\treadonly #configs: Readonly<Record<TType, BuffConfig<TType>>>\r\n\treadonly #activeBuffs: Map<string, ActiveBuff<TType>> = new Map()\r\n\treadonly #lastApplyTime: Map<TType, number> = new Map()\r\n\r\n\treadonly #listeners = {\r\n\t\tbuffAdded: new Set<(buff: ActiveBuff<TType>, newStackCount: number) => void>(),\r\n\t\tbuffExpired: new Set<(type: TType, remainingStacks: number) => void>(),\r\n\t\tbuffRemoved: new Set<(type: TType) => void>(),\r\n\t\tstackChange: new Set<(type: TType, oldCount: number, newCount: number) => void>(),\r\n\t}\r\n\r\n\tconstructor(options: BuffSystemOptions<TType>) {\r\n\t\tthis.#configs = options.configs\r\n\r\n\t\t// Register initial hooks\r\n\t\tif (options.onBuffAdded) this.#listeners.buffAdded.add(options.onBuffAdded)\r\n\t\tif (options.onBuffExpired) this.#listeners.buffExpired.add(options.onBuffExpired)\r\n\t\tif (options.onBuffRemoved) this.#listeners.buffRemoved.add(options.onBuffRemoved)\r\n\t\tif (options.onStackChange) this.#listeners.stackChange.add(options.onStackChange)\r\n\t}\r\n\r\n\t// === ACCESSORS ===\r\n\r\n\tgetState(): BuffSystemState<TType> {\r\n\t\tconst activeBuffs = Array.from(this.#activeBuffs.values())\r\n\t\tconst stackCounts = {} as Record<TType, number>\r\n\r\n\t\tfor (const type of Object.keys(this.#configs) as TType[]) {\r\n\t\t\tstackCounts[type] = this.getStacks(type)\r\n\t\t}\r\n\r\n\t\treturn { activeBuffs, stackCounts }\r\n\t}\r\n\r\n\tgetStacks(type: TType): number {\r\n\t\tlet count = 0\r\n\t\tfor (const buff of this.#activeBuffs.values()) {\r\n\t\t\tif (buff.type === type) {\r\n\t\t\t\tcount += buff.stacks\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn count\r\n\t}\r\n\r\n\tgetActiveBuffs(): readonly ActiveBuff<TType>[] {\r\n\t\treturn Array.from(this.#activeBuffs.values())\r\n\t}\r\n\r\n\thasBuff(type: TType): boolean {\r\n\t\tfor (const buff of this.#activeBuffs.values()) {\r\n\t\t\tif (buff.type === type) return true\r\n\t\t}\r\n\t\treturn false\r\n\t}\r\n\r\n\tcanApply(type: TType, currentTime: number): boolean {\r\n\t\tconst config = this.#configs[type]\r\n\t\tif (!config) return false\r\n\r\n\t\t// Check max stacks\r\n\t\tconst currentStacks = this.getStacks(type)\r\n\t\tif (currentStacks >= config.maxStacks) return false\r\n\r\n\t\t// Check cooldown between stacks\r\n\t\tif (config.cooldownBetweenStacks !== undefined) {\r\n\t\t\tconst lastApply = this.#lastApplyTime.get(type)\r\n\t\t\tif (lastApply !== undefined && currentTime - lastApply < config.cooldownBetweenStacks) {\r\n\t\t\t\treturn false\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn true\r\n\t}\r\n\r\n\t// === MUTATORS ===\r\n\r\n\tapply(type: TType, currentTime: number): boolean {\r\n\t\tif (!this.canApply(type, currentTime)) return false\r\n\r\n\t\tconst config = this.#configs[type]\r\n\t\tconst oldStacks = this.getStacks(type)\r\n\r\n\t\tconst buff: ActiveBuff<TType> = {\r\n\t\t\tid: generateId(),\r\n\t\t\ttype,\r\n\t\t\texpiresAt: currentTime + config.duration,\r\n\t\t\tstacks: 1,\r\n\t\t}\r\n\r\n\t\tthis.#activeBuffs.set(buff.id, buff)\r\n\t\tthis.#lastApplyTime.set(type, currentTime)\r\n\r\n\t\tconst newStacks = oldStacks + 1\r\n\r\n\t\t// Emit events\r\n\t\tthis.#listeners.buffAdded.forEach(cb => cb(buff, newStacks))\r\n\t\tthis.#listeners.stackChange.forEach(cb => cb(type, oldStacks, newStacks))\r\n\r\n\t\treturn true\r\n\t}\r\n\r\n\tremove(type: TType): void {\r\n\t\tconst toRemove: string[] = []\r\n\r\n\t\tfor (const [id, buff] of this.#activeBuffs) {\r\n\t\t\tif (buff.type === type) {\r\n\t\t\t\ttoRemove.push(id)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (toRemove.length === 0) return\r\n\r\n\t\tconst oldStacks = this.getStacks(type)\r\n\r\n\t\tfor (const id of toRemove) {\r\n\t\t\tthis.#activeBuffs.delete(id)\r\n\t\t}\r\n\r\n\t\tthis.#listeners.buffRemoved.forEach(cb => cb(type))\r\n\t\tthis.#listeners.stackChange.forEach(cb => cb(type, oldStacks, 0))\r\n\t}\r\n\r\n\tremoveById(id: string): void {\r\n\t\tconst buff = this.#activeBuffs.get(id)\r\n\t\tif (!buff) return\r\n\r\n\t\tconst oldStacks = this.getStacks(buff.type)\r\n\t\tthis.#activeBuffs.delete(id)\r\n\t\tconst newStacks = this.getStacks(buff.type)\r\n\r\n\t\tthis.#listeners.stackChange.forEach(cb => cb(buff.type, oldStacks, newStacks))\r\n\r\n\t\tif (newStacks === 0) {\r\n\t\t\tthis.#listeners.buffRemoved.forEach(cb => cb(buff.type))\r\n\t\t}\r\n\t}\r\n\r\n\tclearExpired(currentTime: number): number {\r\n\t\tconst toRemove: Array<{ id: string; buff: ActiveBuff<TType> }> = []\r\n\r\n\t\tfor (const [id, buff] of this.#activeBuffs) {\r\n\t\t\tif (buff.expiresAt <= currentTime) {\r\n\t\t\t\ttoRemove.push({ id, buff })\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (toRemove.length === 0) return 0\r\n\r\n\t\t// Group by type for proper event emission\r\n\t\tconst typeChanges = new Map<TType, { oldStacks: number; removed: number }>()\r\n\r\n\t\tfor (const { buff } of toRemove) {\r\n\t\t\tif (!typeChanges.has(buff.type)) {\r\n\t\t\t\ttypeChanges.set(buff.type, { oldStacks: this.getStacks(buff.type), removed: 0 })\r\n\t\t\t}\r\n\t\t\ttypeChanges.get(buff.type)!.removed += buff.stacks\r\n\t\t}\r\n\r\n\t\t// Remove buffs\r\n\t\tfor (const { id } of toRemove) {\r\n\t\t\tthis.#activeBuffs.delete(id)\r\n\t\t}\r\n\r\n\t\t// Emit events\r\n\t\tfor (const [type, changes] of typeChanges) {\r\n\t\t\tconst newStacks = changes.oldStacks - changes.removed\r\n\r\n\t\t\tthis.#listeners.buffExpired.forEach(cb => cb(type, newStacks))\r\n\t\t\tthis.#listeners.stackChange.forEach(cb => cb(type, changes.oldStacks, newStacks))\r\n\r\n\t\t\tif (newStacks === 0) {\r\n\t\t\t\tthis.#listeners.buffRemoved.forEach(cb => cb(type))\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn toRemove.length\r\n\t}\r\n\r\n\tclearAll(): void {\r\n\t\tconst types = new Set<TType>()\r\n\t\tconst oldStackCounts = new Map<TType, number>()\r\n\r\n\t\tfor (const buff of this.#activeBuffs.values()) {\r\n\t\t\ttypes.add(buff.type)\r\n\t\t\tif (!oldStackCounts.has(buff.type)) {\r\n\t\t\t\toldStackCounts.set(buff.type, this.getStacks(buff.type))\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tthis.#activeBuffs.clear()\r\n\t\tthis.#lastApplyTime.clear()\r\n\r\n\t\t// Emit events for all removed types\r\n\t\tfor (const type of types) {\r\n\t\t\tconst oldStacks = oldStackCounts.get(type) ?? 0\r\n\t\t\tthis.#listeners.buffRemoved.forEach(cb => cb(type))\r\n\t\t\tthis.#listeners.stackChange.forEach(cb => cb(type, oldStacks, 0))\r\n\t\t}\r\n\t}\r\n\r\n\t// === CALCULATIONS ===\r\n\r\n\tcalculateMultiplier(type: TType): number {\r\n\t\tconst config = this.#configs[type]\r\n\t\tif (!config) return 1\r\n\r\n\t\tconst stacks = this.getStacks(type)\r\n\t\treturn 1 + (stacks * config.effectPerStack)\r\n\t}\r\n\r\n\tcalculateAdditive(type: TType): number {\r\n\t\tconst config = this.#configs[type]\r\n\t\tif (!config) return 0\r\n\r\n\t\tconst stacks = this.getStacks(type)\r\n\t\treturn stacks * config.effectPerStack\r\n\t}\r\n\r\n\t// === SUBSCRIPTIONS ===\r\n\r\n\tonBuffAdded(callback: (buff: ActiveBuff<TType>, newStackCount: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.buffAdded.add(callback)\r\n\t\treturn () => this.#listeners.buffAdded.delete(callback)\r\n\t}\r\n\r\n\tonBuffExpired(callback: (type: TType, remainingStacks: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.buffExpired.add(callback)\r\n\t\treturn () => this.#listeners.buffExpired.delete(callback)\r\n\t}\r\n\r\n\tonBuffRemoved(callback: (type: TType) => void): Unsubscribe {\r\n\t\tthis.#listeners.buffRemoved.add(callback)\r\n\t\treturn () => this.#listeners.buffRemoved.delete(callback)\r\n\t}\r\n\r\n\tonStackChange(callback: (type: TType, oldCount: number, newCount: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.stackChange.add(callback)\r\n\t\treturn () => this.#listeners.stackChange.delete(callback)\r\n\t}\r\n\r\n\t// === LIFECYCLE ===\r\n\r\n\tupdate(currentTime: number): void {\r\n\t\tthis.clearExpired(currentTime)\r\n\t}\r\n\r\n\treset(): void {\r\n\t\tthis.clearAll()\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.clearAll()\r\n\t\tthis.#listeners.buffAdded.clear()\r\n\t\tthis.#listeners.buffExpired.clear()\r\n\t\tthis.#listeners.buffRemoved.clear()\r\n\t\tthis.#listeners.stackChange.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tDamageInfo,\r\n\tHealthEntityState,\r\n\tHealthSystemInterface,\r\n\tHealthSystemOptions,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\n/**\r\n * HealthSystem implementation for managing entity health, damage, and healing.\r\n */\r\nexport class HealthSystem<TDamageType extends string> implements HealthSystemInterface<TDamageType> {\r\n\treadonly #entities: Map<string, {\r\n\t\tcurrent: number\r\n\t\tmax: number\r\n\t\tinvincibilityRemaining: number\r\n\t}> = new Map()\r\n\r\n\treadonly #defaultInvincibilityDuration: number\r\n\treadonly #allowOverkill: boolean\r\n\treadonly #damageModifier: ((entityId: string, info: DamageInfo<TDamageType>) => number) | undefined\r\n\r\n\treadonly #listeners = {\r\n\t\tdamage: new Set<(entityId: string, info: DamageInfo<TDamageType>, actualDamage: number) => void>(),\r\n\t\theal: new Set<(entityId: string, amount: number, newHealth: number) => void>(),\r\n\t\tdeath: new Set<(entityId: string, lastDamage?: DamageInfo<TDamageType>) => void>(),\r\n\t\trevive: new Set<(entityId: string, newHealth: number) => void>(),\r\n\t\tinvincibilityStart: new Set<(entityId: string, duration: number) => void>(),\r\n\t\tinvincibilityEnd: new Set<(entityId: string) => void>(),\r\n\t\thealthChange: new Set<(entityId: string, oldHealth: number, newHealth: number) => void>(),\r\n\t}\r\n\r\n\tconstructor(options?: HealthSystemOptions<TDamageType>) {\r\n\t\tthis.#defaultInvincibilityDuration = options?.defaultInvincibilityDuration ?? 0\r\n\t\tthis.#allowOverkill = options?.allowOverkill ?? false\r\n\t\tthis.#damageModifier = options?.damageModifier ?? undefined\r\n\r\n\t\tif (options?.onDamage) this.#listeners.damage.add(options.onDamage)\r\n\t\tif (options?.onHeal) this.#listeners.heal.add(options.onHeal)\r\n\t\tif (options?.onDeath) this.#listeners.death.add(options.onDeath)\r\n\t\tif (options?.onRevive) this.#listeners.revive.add(options.onRevive)\r\n\t\tif (options?.onInvincibilityStart) this.#listeners.invincibilityStart.add(options.onInvincibilityStart)\r\n\t\tif (options?.onInvincibilityEnd) this.#listeners.invincibilityEnd.add(options.onInvincibilityEnd)\r\n\t\tif (options?.onHealthChange) this.#listeners.healthChange.add(options.onHealthChange)\r\n\t}\r\n\r\n\t// === ACCESSORS ===\r\n\r\n\tgetHealth(entityId: string): HealthEntityState | undefined {\r\n\t\tconst entity = this.#entities.get(entityId)\r\n\t\tif (!entity) return undefined\r\n\r\n\t\treturn {\r\n\t\t\tcurrent: entity.current,\r\n\t\t\tmax: entity.max,\r\n\t\t\tinvincibilityRemaining: entity.invincibilityRemaining,\r\n\t\t\tisInvincible: entity.invincibilityRemaining > 0,\r\n\t\t\tisDead: entity.current <= 0,\r\n\t\t}\r\n\t}\r\n\r\n\tgetCurrentHealth(entityId: string): number {\r\n\t\treturn this.#entities.get(entityId)?.current ?? 0\r\n\t}\r\n\r\n\tgetMaxHealth(entityId: string): number {\r\n\t\treturn this.#entities.get(entityId)?.max ?? 0\r\n\t}\r\n\r\n\tgetHealthPercent(entityId: string): number {\r\n\t\tconst entity = this.#entities.get(entityId)\r\n\t\tif (!entity || entity.max === 0) return 0\r\n\t\treturn entity.current / entity.max\r\n\t}\r\n\r\n\tisAlive(entityId: string): boolean {\r\n\t\tconst entity = this.#entities.get(entityId)\r\n\t\treturn entity !== undefined && entity.current > 0\r\n\t}\r\n\r\n\tisDead(entityId: string): boolean {\r\n\t\tconst entity = this.#entities.get(entityId)\r\n\t\treturn entity !== undefined && entity.current <= 0\r\n\t}\r\n\r\n\tisInvincible(entityId: string): boolean {\r\n\t\tconst entity = this.#entities.get(entityId)\r\n\t\treturn entity !== undefined && entity.invincibilityRemaining > 0\r\n\t}\r\n\r\n\thasEntity(entityId: string): boolean {\r\n\t\treturn this.#entities.has(entityId)\r\n\t}\r\n\r\n\t// === REGISTRATION ===\r\n\r\n\tregister(entityId: string, maxHealth: number, currentHealth?: number): void {\r\n\t\tthis.#entities.set(entityId, {\r\n\t\t\tcurrent: currentHealth ?? maxHealth,\r\n\t\t\tmax: maxHealth,\r\n\t\t\tinvincibilityRemaining: 0,\r\n\t\t})\r\n\t}\r\n\r\n\tunregister(entityId: string): void {\r\n\t\tthis.#entities.delete(entityId)\r\n\t}\r\n\r\n\t// === DAMAGE & HEALING ===\r\n\r\n\tdamage(entityId: string, info: DamageInfo<TDamageType>): number {\r\n\t\tconst entity = this.#entities.get(entityId)\r\n\t\tif (!entity) return 0\r\n\r\n\t\t// Check invincibility\r\n\t\tif (entity.invincibilityRemaining > 0) return 0\r\n\r\n\t\t// Calculate actual damage\r\n\t\tlet amount = info.amount\r\n\t\tif (this.#damageModifier) {\r\n\t\t\tamount = this.#damageModifier(entityId, info)\r\n\t\t}\r\n\r\n\t\tif (amount <= 0) return 0\r\n\r\n\t\tconst oldHealth = entity.current\r\n\t\tentity.current = this.#allowOverkill\r\n\t\t\t? entity.current - amount\r\n\t\t\t: Math.max(0, entity.current - amount)\r\n\r\n\t\tconst actualDamage = oldHealth - entity.current\r\n\r\n\t\t// Emit events\r\n\t\tthis.#listeners.damage.forEach(cb => cb(entityId, info, actualDamage))\r\n\t\tthis.#listeners.healthChange.forEach(cb => cb(entityId, oldHealth, entity.current))\r\n\r\n\t\t// Check for death\r\n\t\tif (entity.current <= 0 && oldHealth > 0) {\r\n\t\t\tthis.#listeners.death.forEach(cb => cb(entityId, info))\r\n\t\t}\r\n\r\n\t\treturn actualDamage\r\n\t}\r\n\r\n\theal(entityId: string, amount: number): number {\r\n\t\tconst entity = this.#entities.get(entityId)\r\n\t\tif (!entity || amount <= 0) return 0\r\n\r\n\t\tconst oldHealth = entity.current\r\n\t\tentity.current = Math.min(entity.max, entity.current + amount)\r\n\t\tconst actualHeal = entity.current - oldHealth\r\n\r\n\t\tif (actualHeal > 0) {\r\n\t\t\tthis.#listeners.heal.forEach(cb => cb(entityId, actualHeal, entity.current))\r\n\t\t\tthis.#listeners.healthChange.forEach(cb => cb(entityId, oldHealth, entity.current))\r\n\t\t}\r\n\r\n\t\treturn actualHeal\r\n\t}\r\n\r\n\tsetHealth(entityId: string, health: number): void {\r\n\t\tconst entity = this.#entities.get(entityId)\r\n\t\tif (!entity) return\r\n\r\n\t\tconst oldHealth = entity.current\r\n\t\tentity.current = Math.max(0, Math.min(entity.max, health))\r\n\r\n\t\tif (oldHealth !== entity.current) {\r\n\t\t\tthis.#listeners.healthChange.forEach(cb => cb(entityId, oldHealth, entity.current))\r\n\r\n\t\t\tif (entity.current <= 0 && oldHealth > 0) {\r\n\t\t\t\tthis.#listeners.death.forEach(cb => cb(entityId))\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tsetMaxHealth(entityId: string, maxHealth: number, scaleCurrentHealth?: boolean): void {\r\n\t\tconst entity = this.#entities.get(entityId)\r\n\t\tif (!entity) return\r\n\r\n\t\tconst oldMax = entity.max\r\n\t\tentity.max = Math.max(1, maxHealth)\r\n\r\n\t\tif (scaleCurrentHealth && oldMax > 0) {\r\n\t\t\tconst ratio = entity.current / oldMax\r\n\t\t\tconst oldHealth = entity.current\r\n\t\t\tentity.current = Math.round(ratio * entity.max)\r\n\t\t\tif (oldHealth !== entity.current) {\r\n\t\t\t\tthis.#listeners.healthChange.forEach(cb => cb(entityId, oldHealth, entity.current))\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\t// Clamp current health to new max\r\n\t\t\tif (entity.current > entity.max) {\r\n\t\t\t\tconst oldHealth = entity.current\r\n\t\t\t\tentity.current = entity.max\r\n\t\t\t\tthis.#listeners.healthChange.forEach(cb => cb(entityId, oldHealth, entity.current))\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tkill(entityId: string): void {\r\n\t\tconst entity = this.#entities.get(entityId)\r\n\t\tif (!entity || entity.current <= 0) return\r\n\r\n\t\tconst oldHealth = entity.current\r\n\t\tentity.current = 0\r\n\r\n\t\tthis.#listeners.healthChange.forEach(cb => cb(entityId, oldHealth, 0))\r\n\t\tthis.#listeners.death.forEach(cb => cb(entityId))\r\n\t}\r\n\r\n\trevive(entityId: string, healthPercent?: number): void {\r\n\t\tconst entity = this.#entities.get(entityId)\r\n\t\tif (!entity || entity.current > 0) return\r\n\r\n\t\tconst percent = healthPercent ?? 1\r\n\t\tconst oldHealth = entity.current\r\n\t\tentity.current = Math.round(entity.max * Math.max(0.01, Math.min(1, percent)))\r\n\r\n\t\tthis.#listeners.healthChange.forEach(cb => cb(entityId, oldHealth, entity.current))\r\n\t\tthis.#listeners.revive.forEach(cb => cb(entityId, entity.current))\r\n\t}\r\n\r\n\tsetInvincible(entityId: string, duration: number): void {\r\n\t\tconst entity = this.#entities.get(entityId)\r\n\t\tif (!entity) return\r\n\r\n\t\tconst wasInvincible = entity.invincibilityRemaining > 0\r\n\t\tentity.invincibilityRemaining = duration\r\n\r\n\t\tif (!wasInvincible && duration > 0) {\r\n\t\t\tthis.#listeners.invincibilityStart.forEach(cb => cb(entityId, duration))\r\n\t\t}\r\n\t}\r\n\r\n\tclearInvincibility(entityId: string): void {\r\n\t\tconst entity = this.#entities.get(entityId)\r\n\t\tif (!entity) return\r\n\r\n\t\tif (entity.invincibilityRemaining > 0) {\r\n\t\t\tentity.invincibilityRemaining = 0\r\n\t\t\tthis.#listeners.invincibilityEnd.forEach(cb => cb(entityId))\r\n\t\t}\r\n\t}\r\n\r\n\t// === SUBSCRIPTIONS ===\r\n\r\n\tonDamage(callback: (entityId: string, info: DamageInfo<TDamageType>, actualDamage: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.damage.add(callback)\r\n\t\treturn () => this.#listeners.damage.delete(callback)\r\n\t}\r\n\r\n\tonHeal(callback: (entityId: string, amount: number, newHealth: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.heal.add(callback)\r\n\t\treturn () => this.#listeners.heal.delete(callback)\r\n\t}\r\n\r\n\tonDeath(callback: (entityId: string, lastDamage?: DamageInfo<TDamageType>) => void): Unsubscribe {\r\n\t\tthis.#listeners.death.add(callback)\r\n\t\treturn () => this.#listeners.death.delete(callback)\r\n\t}\r\n\r\n\tonRevive(callback: (entityId: string, newHealth: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.revive.add(callback)\r\n\t\treturn () => this.#listeners.revive.delete(callback)\r\n\t}\r\n\r\n\tonInvincibilityStart(callback: (entityId: string, duration: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.invincibilityStart.add(callback)\r\n\t\treturn () => this.#listeners.invincibilityStart.delete(callback)\r\n\t}\r\n\r\n\tonInvincibilityEnd(callback: (entityId: string) => void): Unsubscribe {\r\n\t\tthis.#listeners.invincibilityEnd.add(callback)\r\n\t\treturn () => this.#listeners.invincibilityEnd.delete(callback)\r\n\t}\r\n\r\n\tonHealthChange(callback: (entityId: string, oldHealth: number, newHealth: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.healthChange.add(callback)\r\n\t\treturn () => this.#listeners.healthChange.delete(callback)\r\n\t}\r\n\r\n\t// === LIFECYCLE ===\r\n\r\n\tupdate(deltaTime: number): void {\r\n\t\tfor (const [entityId, entity] of this.#entities) {\r\n\t\t\tif (entity.invincibilityRemaining > 0) {\r\n\t\t\t\tentity.invincibilityRemaining -= deltaTime\r\n\t\t\t\tif (entity.invincibilityRemaining <= 0) {\r\n\t\t\t\t\tentity.invincibilityRemaining = 0\r\n\t\t\t\t\tthis.#listeners.invincibilityEnd.forEach(cb => cb(entityId))\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\treset(): void {\r\n\t\tthis.#entities.clear()\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#entities.clear()\r\n\t\tthis.#listeners.damage.clear()\r\n\t\tthis.#listeners.heal.clear()\r\n\t\tthis.#listeners.death.clear()\r\n\t\tthis.#listeners.revive.clear()\r\n\t\tthis.#listeners.invincibilityStart.clear()\r\n\t\tthis.#listeners.invincibilityEnd.clear()\r\n\t\tthis.#listeners.healthChange.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tCameraInterface,\r\n\tFloatingTextEntry,\r\n\tFloatingTextSpawnOptions,\r\n\tFloatingTextStyle,\r\n\tFloatingTextSystemInterface,\r\n\tFloatingTextSystemOptions,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\nimport { generateId } from '../../helpers.js'\r\n\r\n/**\r\n * FloatingTextSystem implementation for visual feedback like damage numbers.\r\n */\r\nexport class FloatingTextSystem implements FloatingTextSystemInterface {\r\n\treadonly #entries: Map<string, FloatingTextEntry> = new Map()\r\n\treadonly #maxVisible: number\r\n\treadonly #defaultDuration: number\r\n\treadonly #defaultStyle: FloatingTextStyle\r\n\treadonly #defaultFontSize: number\r\n\treadonly #defaultColor: string\r\n\r\n\treadonly #listeners = {\r\n\t\tspawn: new Set<(entry: FloatingTextEntry) => void>(),\r\n\t\tcomplete: new Set<(entry: FloatingTextEntry) => void>(),\r\n\t}\r\n\r\n\tconstructor(options?: FloatingTextSystemOptions) {\r\n\t\tthis.#maxVisible = options?.maxVisible ?? 50\r\n\t\tthis.#defaultDuration = options?.defaultDuration ?? 1.0\r\n\t\tthis.#defaultStyle = options?.defaultStyle ?? 'rise'\r\n\t\tthis.#defaultFontSize = options?.defaultFontSize ?? 16\r\n\t\tthis.#defaultColor = options?.defaultColor ?? '#ffffff'\r\n\r\n\t\tif (options?.onSpawn) this.#listeners.spawn.add(options.onSpawn)\r\n\t\tif (options?.onComplete) this.#listeners.complete.add(options.onComplete)\r\n\t}\r\n\r\n\t// === ACCESSORS ===\r\n\r\n\tgetVisible(): readonly FloatingTextEntry[] {\r\n\t\treturn Array.from(this.#entries.values())\r\n\t}\r\n\r\n\tgetCount(): number {\r\n\t\treturn this.#entries.size\r\n\t}\r\n\r\n\t// === MUTATORS ===\r\n\r\n\tspawn(options: FloatingTextSpawnOptions): string {\r\n\t\t// Remove oldest if at capacity\r\n\t\tif (this.#entries.size >= this.#maxVisible) {\r\n\t\t\tconst oldest = this.#entries.keys().next().value\r\n\t\t\tif (oldest) this.#entries.delete(oldest)\r\n\t\t}\r\n\r\n\t\tconst entry: FloatingTextEntry = {\r\n\t\t\tid: generateId(),\r\n\t\t\tx: options.x,\r\n\t\t\ty: options.y,\r\n\t\t\ttext: options.text,\r\n\t\t\tcolor: options.color ?? this.#defaultColor,\r\n\t\t\tfontSize: options.fontSize ?? this.#defaultFontSize,\r\n\t\t\topacity: 1,\r\n\t\t\tage: 0,\r\n\t\t\tduration: options.duration ?? this.#defaultDuration,\r\n\t\t\tscale: 1,\r\n\t\t\tstyle: options.style ?? this.#defaultStyle,\r\n\t\t\toutline: options.outline ?? false,\r\n\t\t\toutlineColor: options.outlineColor ?? '#000000',\r\n\t\t}\r\n\r\n\t\tthis.#entries.set(entry.id, entry)\r\n\t\tthis.#listeners.spawn.forEach(cb => cb(entry))\r\n\r\n\t\treturn entry.id\r\n\t}\r\n\r\n\tremove(id: string): void {\r\n\t\tthis.#entries.delete(id)\r\n\t}\r\n\r\n\tclear(): void {\r\n\t\tthis.#entries.clear()\r\n\t}\r\n\r\n\t// === SUBSCRIPTIONS ===\r\n\r\n\tonSpawn(callback: (entry: FloatingTextEntry) => void): Unsubscribe {\r\n\t\tthis.#listeners.spawn.add(callback)\r\n\t\treturn () => this.#listeners.spawn.delete(callback)\r\n\t}\r\n\r\n\tonComplete(callback: (entry: FloatingTextEntry) => void): Unsubscribe {\r\n\t\tthis.#listeners.complete.add(callback)\r\n\t\treturn () => this.#listeners.complete.delete(callback)\r\n\t}\r\n\r\n\t// === LIFECYCLE ===\r\n\r\n\tupdate(deltaTime: number): void {\r\n\t\tconst toRemove: string[] = []\r\n\r\n\t\tfor (const [id, entry] of this.#entries) {\r\n\t\t\t// Update age\r\n\t\t\tconst mutableEntry = entry as {\r\n\t\t\t\tage: number\r\n\t\t\t\ty: number\r\n\t\t\t\topacity: number\r\n\t\t\t\tscale: number\r\n\t\t\t\tx: number\r\n\t\t\t}\r\n\t\t\tmutableEntry.age += deltaTime\r\n\r\n\t\t\t// Calculate progress\r\n\t\t\tconst progress = Math.min(1, mutableEntry.age / entry.duration)\r\n\r\n\t\t\t// Apply style-specific animations\r\n\t\t\tswitch (entry.style) {\r\n\t\t\t\tcase 'rise':\r\n\t\t\t\t\tmutableEntry.y -= deltaTime * 30\r\n\t\t\t\t\tmutableEntry.opacity = 1 - progress\r\n\t\t\t\t\tbreak\r\n\r\n\t\t\t\tcase 'bounce':\r\n\t\t\t\t\tmutableEntry.y -= deltaTime * 40 * Math.cos(progress * Math.PI)\r\n\t\t\t\t\tmutableEntry.opacity = 1 - progress * progress\r\n\t\t\t\t\tbreak\r\n\r\n\t\t\t\tcase 'scale-fade':\r\n\t\t\t\t\tmutableEntry.scale = 1 + progress * 0.5\r\n\t\t\t\t\tmutableEntry.opacity = 1 - progress\r\n\t\t\t\t\tbreak\r\n\r\n\t\t\t\tcase 'shake':\r\n\t\t\t\t\tmutableEntry.x += (Math.random() - 0.5) * 4\r\n\t\t\t\t\tmutableEntry.opacity = 1 - progress\r\n\t\t\t\t\tbreak\r\n\r\n\t\t\t\tcase 'arc':\r\n\t\t\t\t\tmutableEntry.x += deltaTime * 20\r\n\t\t\t\t\tmutableEntry.y -= deltaTime * 30 * (1 - progress * 2)\r\n\t\t\t\t\tmutableEntry.opacity = 1 - progress\r\n\t\t\t\t\tbreak\r\n\r\n\t\t\t\tcase 'static':\r\n\t\t\t\t\tmutableEntry.opacity = 1 - progress\r\n\t\t\t\t\tbreak\r\n\t\t\t}\r\n\r\n\t\t\t// Check if complete\r\n\t\t\tif (mutableEntry.age >= entry.duration) {\r\n\t\t\t\ttoRemove.push(id)\r\n\t\t\t\tthis.#listeners.complete.forEach(cb => cb(entry))\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Remove completed entries\r\n\t\tfor (const id of toRemove) {\r\n\t\t\tthis.#entries.delete(id)\r\n\t\t}\r\n\t}\r\n\r\n\trender(ctx: CanvasRenderingContext2D, camera: CameraInterface): void {\r\n\t\tconst entries = Array.from(this.#entries.values())\r\n\r\n\t\tfor (const entry of entries) {\r\n\t\t\tconst screenPos = camera.worldToScreen(entry.x, entry.y)\r\n\r\n\t\t\tctx.save()\r\n\t\t\tctx.globalAlpha = entry.opacity\r\n\t\t\tctx.font = `bold ${Math.round(entry.fontSize * entry.scale)}px sans-serif`\r\n\t\t\tctx.textAlign = 'center'\r\n\t\t\tctx.textBaseline = 'middle'\r\n\r\n\t\t\t// Draw outline if enabled\r\n\t\t\tif (entry.outline) {\r\n\t\t\t\tctx.strokeStyle = entry.outlineColor\r\n\t\t\t\tctx.lineWidth = 2\r\n\t\t\t\tctx.strokeText(entry.text, screenPos.x, screenPos.y)\r\n\t\t\t}\r\n\r\n\t\t\t// Draw text\r\n\t\t\tctx.fillStyle = entry.color\r\n\t\t\tctx.fillText(entry.text, screenPos.x, screenPos.y)\r\n\r\n\t\t\tctx.restore()\r\n\t\t}\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#entries.clear()\r\n\t\tthis.#listeners.spawn.clear()\r\n\t\tthis.#listeners.complete.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tCameraInterface,\r\n\tCollectible,\r\n\tCollectibleSystemInterface,\r\n\tCollectibleSystemOptions,\r\n\tDropTableEntry,\r\n\tUnsubscribe,\r\n\tVector2,\r\n} from '../../types.js'\r\nimport { generateId } from '../../helpers.js'\r\n\r\n/**\r\n * CollectibleSystem implementation for managing pickups and loot.\r\n */\r\nexport class CollectibleSystem<TType extends string> implements CollectibleSystemInterface<TType> {\r\n\treadonly #collectibles: Map<string, Collectible<TType>> = new Map()\r\n\treadonly #dropTable: readonly DropTableEntry<TType>[]\r\n\treadonly #dropChance: number\r\n\treadonly #magnetRange: number\r\n\treadonly #magnetSpeed: number\r\n\treadonly #defaultLifetime: number\r\n\treadonly #collectRadius: number\r\n\treadonly #totalWeight: number\r\n\r\n\treadonly #listeners = {\r\n\t\tspawn: new Set<(collectible: Collectible<TType>) => void>(),\r\n\t\tcollect: new Set<(collectible: Collectible<TType>, collectorId: string) => void>(),\r\n\t\texpire: new Set<(collectible: Collectible<TType>) => void>(),\r\n\t}\r\n\r\n\tconstructor(options: CollectibleSystemOptions<TType>) {\r\n\t\tthis.#dropTable = options.dropTable\r\n\t\tthis.#dropChance = options.dropChance ?? 1.0\r\n\t\tthis.#magnetRange = options.magnetRange ?? 100\r\n\t\tthis.#magnetSpeed = options.magnetSpeed ?? 200\r\n\t\tthis.#defaultLifetime = options.defaultLifetime ?? 10\r\n\t\tthis.#collectRadius = options.collectRadius ?? 20\r\n\r\n\t\t// Pre-calculate total weight\r\n\t\tthis.#totalWeight = this.#dropTable.reduce((sum, entry) => sum + entry.weight, 0)\r\n\r\n\t\tif (options.onSpawn) this.#listeners.spawn.add(options.onSpawn)\r\n\t\tif (options.onCollect) this.#listeners.collect.add(options.onCollect)\r\n\t\tif (options.onExpire) this.#listeners.expire.add(options.onExpire)\r\n\t}\r\n\r\n\t// === ACCESSORS ===\r\n\r\n\tgetCollectibles(): readonly Collectible<TType>[] {\r\n\t\treturn Array.from(this.#collectibles.values())\r\n\t}\r\n\r\n\tgetActiveCount(): number {\r\n\t\treturn this.#collectibles.size\r\n\t}\r\n\r\n\t// === SPAWNING ===\r\n\r\n\tspawn(type: TType, position: Vector2, value?: number): Collectible<TType> {\r\n\t\tconst entry = this.#dropTable.find(e => e.type === type)\r\n\t\tlet finalValue = value ?? 1\r\n\r\n\t\tif (!value && entry) {\r\n\t\t\tif (typeof entry.value === 'number') {\r\n\t\t\t\tfinalValue = entry.value\r\n\t\t\t} else {\r\n\t\t\t\tfinalValue = entry.value.min + Math.random() * (entry.value.max - entry.value.min)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst collectible: Collectible<TType> = {\r\n\t\t\tid: generateId(),\r\n\t\t\tx: position.x,\r\n\t\t\ty: position.y,\r\n\t\t\tvx: 0,\r\n\t\t\tvy: 0,\r\n\t\t\trotation: 0,\r\n\t\t\tradius: this.#collectRadius,\r\n\t\t\ttype,\r\n\t\t\tvalue: Math.round(finalValue),\r\n\t\t\tlifetime: this.#defaultLifetime,\r\n\t\t\tage: 0,\r\n\t\t\tmagnetized: false,\r\n\t\t\tactive: true,\r\n\t\t}\r\n\r\n\t\tthis.#collectibles.set(collectible.id, collectible)\r\n\t\tthis.#listeners.spawn.forEach(cb => cb(collectible))\r\n\r\n\t\treturn collectible\r\n\t}\r\n\r\n\tspawnFromDropTable(position: Vector2): Collectible<TType> | undefined {\r\n\t\tif (Math.random() > this.#dropChance) return undefined\r\n\t\tif (this.#totalWeight <= 0) return undefined\r\n\r\n\t\t// Weighted random selection\r\n\t\tlet roll = Math.random() * this.#totalWeight\r\n\t\tfor (const entry of this.#dropTable) {\r\n\t\t\troll -= entry.weight\r\n\t\t\tif (roll <= 0) {\r\n\t\t\t\treturn this.spawn(entry.type, position)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn undefined\r\n\t}\r\n\r\n\tremove(id: string): void {\r\n\t\tthis.#collectibles.delete(id)\r\n\t}\r\n\r\n\tcollect(collectibleId: string, collectorId: string): Collectible<TType> | undefined {\r\n\t\tconst collectible = this.#collectibles.get(collectibleId)\r\n\t\tif (!collectible) return undefined\r\n\r\n\t\tthis.#collectibles.delete(collectibleId)\r\n\t\tthis.#listeners.collect.forEach(cb => cb(collectible, collectorId))\r\n\r\n\t\treturn collectible\r\n\t}\r\n\r\n\tclear(): void {\r\n\t\tthis.#collectibles.clear()\r\n\t}\r\n\r\n\t// === SUBSCRIPTIONS ===\r\n\r\n\tonSpawn(callback: (collectible: Collectible<TType>) => void): Unsubscribe {\r\n\t\tthis.#listeners.spawn.add(callback)\r\n\t\treturn () => this.#listeners.spawn.delete(callback)\r\n\t}\r\n\r\n\tonCollect(callback: (collectible: Collectible<TType>, collectorId: string) => void): Unsubscribe {\r\n\t\tthis.#listeners.collect.add(callback)\r\n\t\treturn () => this.#listeners.collect.delete(callback)\r\n\t}\r\n\r\n\tonExpire(callback: (collectible: Collectible<TType>) => void): Unsubscribe {\r\n\t\tthis.#listeners.expire.add(callback)\r\n\t\treturn () => this.#listeners.expire.delete(callback)\r\n\t}\r\n\r\n\t// === LIFECYCLE ===\r\n\r\n\tupdate(deltaTime: number, collectorPosition: Vector2): void {\r\n\t\tconst toRemove: string[] = []\r\n\r\n\t\tfor (const [id, collectible] of this.#collectibles) {\r\n\t\t\t// Update age\r\n\t\t\tcollectible.age += deltaTime\r\n\r\n\t\t\t// Check expiration\r\n\t\t\tif (collectible.age >= collectible.lifetime) {\r\n\t\t\t\ttoRemove.push(id)\r\n\t\t\t\tthis.#listeners.expire.forEach(cb => cb(collectible))\r\n\t\t\t\tcontinue\r\n\t\t\t}\r\n\r\n\t\t\t// Calculate distance to collector\r\n\t\t\tconst dx = collectorPosition.x - collectible.x\r\n\t\t\tconst dy = collectorPosition.y - collectible.y\r\n\t\t\tconst dist = Math.sqrt(dx * dx + dy * dy)\r\n\r\n\t\t\t// Check for magnetization\r\n\t\t\tif (dist <= this.#magnetRange) {\r\n\t\t\t\tcollectible.magnetized = true\r\n\t\t\t}\r\n\r\n\t\t\t// Move towards collector if magnetized\r\n\t\t\tif (collectible.magnetized && dist > 1) {\r\n\t\t\t\tconst speed = this.#magnetSpeed * deltaTime\r\n\t\t\t\tconst moveX = (dx / dist) * speed\r\n\t\t\t\tconst moveY = (dy / dist) * speed\r\n\r\n\t\t\t\tcollectible.x += moveX\r\n\t\t\t\tcollectible.y += moveY\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Remove expired collectibles\r\n\t\tfor (const id of toRemove) {\r\n\t\t\tthis.#collectibles.delete(id)\r\n\t\t}\r\n\t}\r\n\r\n\trender(ctx: CanvasRenderingContext2D, camera: CameraInterface): void {\r\n\t\tfor (const collectible of this.#collectibles.values()) {\r\n\t\t\tconst screenPos = camera.worldToScreen(collectible.x, collectible.y)\r\n\r\n\t\t\t// Calculate pulse effect based on age\r\n\t\t\tconst pulse = 1 + Math.sin(collectible.age * 5) * 0.1\r\n\r\n\t\t\tctx.save()\r\n\r\n\t\t\t// Draw glow\r\n\t\t\tctx.beginPath()\r\n\t\t\tctx.arc(screenPos.x, screenPos.y, collectible.radius * pulse * 1.5, 0, Math.PI * 2)\r\n\t\t\tctx.fillStyle = 'rgba(255, 255, 255, 0.2)'\r\n\t\t\tctx.fill()\r\n\r\n\t\t\t// Draw collectible\r\n\t\t\tctx.beginPath()\r\n\t\t\tctx.arc(screenPos.x, screenPos.y, collectible.radius * pulse, 0, Math.PI * 2)\r\n\t\t\tctx.fillStyle = '#ffdd00'\r\n\t\t\tctx.fill()\r\n\r\n\t\t\tctx.restore()\r\n\t\t}\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#collectibles.clear()\r\n\t\tthis.#listeners.spawn.clear()\r\n\t\tthis.#listeners.collect.clear()\r\n\t\tthis.#listeners.expire.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tSimpleEntityInterface,\r\n\tSpawnZone,\r\n\tSpawnerSystemInterface,\r\n\tSpawnerSystemOptions,\r\n\tSpawnerSystemState,\r\n\tUnsubscribe,\r\n\tVector2,\r\n\tWaveConfig,\r\n} from '../../types.js'\r\n\r\n/**\r\n * SpawnerSystem implementation for managing entity spawning with zones and waves.\r\n */\r\nexport class SpawnerSystem<TEntity extends SimpleEntityInterface, TType extends string = string>\r\nimplements SpawnerSystemInterface<TEntity> {\r\n\treadonly #zones: SpawnZone[] = []\r\n\treadonly #entityFactory: (type: TType, position: Vector2) => TEntity\r\n\treadonly #waves: readonly WaveConfig<TType>[]\r\n\treadonly #infiniteMode: boolean\r\n\r\n\t#baseInterval: number\r\n\t#minInterval: number\r\n\t#intervalDecayRate: number\r\n\t#currentSpawnInterval: number\r\n\t#spawnTimer = 0\r\n\t#currentWave = 0\r\n\t#totalSpawned = 0\r\n\t#isActive = false\r\n\t#isPaused = false\r\n\r\n\treadonly #listeners = {\r\n\t\tspawn: new Set<(entity: TEntity, type: string, zone: SpawnZone) => void>(),\r\n\t\twaveStart: new Set<(wave: number, config: WaveConfig) => void>(),\r\n\t\twaveComplete: new Set<(wave: number) => void>(),\r\n\t}\r\n\r\n\tconstructor(options: SpawnerSystemOptions<TEntity, TType>) {\r\n\t\t// Copy zones\r\n\t\tfor (const zone of options.zones) {\r\n\t\t\tthis.#zones.push({ ...zone })\r\n\t\t}\r\n\r\n\t\tthis.#entityFactory = options.entityFactory\r\n\t\tthis.#waves = options.waves ?? []\r\n\t\tthis.#infiniteMode = options.infiniteMode ?? true\r\n\r\n\t\tthis.#baseInterval = options.baseInterval\r\n\t\tthis.#minInterval = options.minInterval ?? 0.5\r\n\t\tthis.#intervalDecayRate = options.intervalDecayRate ?? 0\r\n\t\tthis.#currentSpawnInterval = this.#baseInterval\r\n\r\n\t\tif (options.onSpawn) this.#listeners.spawn.add(options.onSpawn)\r\n\t\tif (options.onWaveStart) this.#listeners.waveStart.add(options.onWaveStart)\r\n\t\tif (options.onWaveComplete) this.#listeners.waveComplete.add(options.onWaveComplete)\r\n\t}\r\n\r\n\t// === ACCESSORS ===\r\n\r\n\tgetState(): SpawnerSystemState {\r\n\t\treturn {\r\n\t\t\tcurrentWave: this.#currentWave,\r\n\t\t\tspawnTimer: this.#spawnTimer,\r\n\t\t\tcurrentSpawnInterval: this.#currentSpawnInterval,\r\n\t\t\ttotalSpawned: this.#totalSpawned,\r\n\t\t\tisActive: this.#isActive,\r\n\t\t\tisPaused: this.#isPaused,\r\n\t\t}\r\n\t}\r\n\r\n\tgetZones(): readonly SpawnZone[] {\r\n\t\treturn this.#zones\r\n\t}\r\n\r\n\tgetCurrentWave(): number {\r\n\t\treturn this.#currentWave\r\n\t}\r\n\r\n\tgetSpawnInterval(): number {\r\n\t\treturn this.#currentSpawnInterval\r\n\t}\r\n\r\n\t// === ZONE MANAGEMENT ===\r\n\r\n\tsetZoneEnabled(zoneId: string, enabled: boolean): void {\r\n\t\tconst zone = this.#zones.find(z => z.id === zoneId)\r\n\t\tif (zone) {\r\n\t\t\t(zone as { enabled: boolean }).enabled = enabled\r\n\t\t}\r\n\t}\r\n\r\n\taddZone(zone: SpawnZone): void {\r\n\t\tthis.#zones.push({ ...zone })\r\n\t}\r\n\r\n\tremoveZone(zoneId: string): void {\r\n\t\tconst index = this.#zones.findIndex(z => z.id === zoneId)\r\n\t\tif (index !== -1) {\r\n\t\t\tthis.#zones.splice(index, 1)\r\n\t\t}\r\n\t}\r\n\r\n\t#selectRandomZone(): SpawnZone | undefined {\r\n\t\tconst enabledZones = this.#zones.filter(z => z.enabled)\r\n\t\tif (enabledZones.length === 0) return undefined\r\n\r\n\t\tconst totalWeight = enabledZones.reduce((sum, z) => sum + z.weight, 0)\r\n\t\tif (totalWeight <= 0) return enabledZones[0]\r\n\r\n\t\tlet roll = Math.random() * totalWeight\r\n\t\tfor (const zone of enabledZones) {\r\n\t\t\troll -= zone.weight\r\n\t\t\tif (roll <= 0) return zone\r\n\t\t}\r\n\r\n\t\treturn enabledZones[0]\r\n\t}\r\n\r\n\t#getRandomPositionInZone(zone: SpawnZone): Vector2 {\r\n\t\treturn {\r\n\t\t\tx: zone.x + Math.random() * zone.width,\r\n\t\t\ty: zone.y + Math.random() * zone.height,\r\n\t\t}\r\n\t}\r\n\r\n\t// === SPAWNING ===\r\n\r\n\tspawn(type: string, position?: Vector2): TEntity | undefined {\r\n\t\tlet spawnPosition: Vector2\r\n\t\tlet selectedZone: SpawnZone | undefined\r\n\r\n\t\tif (position) {\r\n\t\t\tspawnPosition = position\r\n\t\t\tselectedZone = this.#zones[0]\r\n\t\t} else {\r\n\t\t\tselectedZone = this.#selectRandomZone()\r\n\t\t\tif (!selectedZone) return undefined\r\n\t\t\tspawnPosition = this.#getRandomPositionInZone(selectedZone)\r\n\t\t}\r\n\r\n\t\tconst entity = this.#entityFactory(type as TType, spawnPosition)\r\n\t\tthis.#totalSpawned++\r\n\r\n\t\tif (selectedZone) {\r\n\t\t\tthis.#listeners.spawn.forEach(cb => cb(entity, type, selectedZone))\r\n\t\t}\r\n\r\n\t\treturn entity\r\n\t}\r\n\r\n\t#selectRandomType(): string {\r\n\t\t// In wave mode, use wave entity types\r\n\t\tif (this.#waves.length > 0 && this.#currentWave < this.#waves.length) {\r\n\t\t\tconst wave = this.#waves[this.#currentWave]\r\n\t\t\tif (wave && wave.entityTypes && wave.entityTypes.length > 0) {\r\n\t\t\t\t// Use typeWeights if available, otherwise equal weight\r\n\t\t\t\tif (wave.typeWeights) {\r\n\t\t\t\t\tconst totalWeight = wave.entityTypes.reduce(\r\n\t\t\t\t\t\t(sum, t) => sum + (wave.typeWeights?.[t] ?? 1),\r\n\t\t\t\t\t\t0,\r\n\t\t\t\t\t)\r\n\t\t\t\t\tlet roll = Math.random() * totalWeight\r\n\t\t\t\t\tfor (const type of wave.entityTypes) {\r\n\t\t\t\t\t\troll -= wave.typeWeights[type] ?? 1\r\n\t\t\t\t\t\tif (roll <= 0) return type\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t// Random selection without weights\r\n\t\t\t\tconst index = Math.floor(Math.random() * wave.entityTypes.length)\r\n\t\t\t\treturn wave.entityTypes[index] ?? 'basic'\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn 'basic'\r\n\t}\r\n\r\n\t// === WAVE CONTROL ===\r\n\r\n\tstartWave(waveNumber: number): void {\r\n\t\tif (waveNumber >= this.#waves.length && !this.#infiniteMode) return\r\n\r\n\t\tthis.#currentWave = waveNumber\r\n\t\tthis.#isActive = true\r\n\t\tthis.#isPaused = false\r\n\r\n\t\tconst wave = this.#waves[this.#currentWave]\r\n\t\tif (wave) {\r\n\t\t\tthis.#listeners.waveStart.forEach(cb => cb(this.#currentWave, wave))\r\n\t\t}\r\n\t}\r\n\r\n\tnextWave(): void {\r\n\t\tthis.startWave(this.#currentWave + 1)\r\n\t}\r\n\r\n\tstart(): void {\r\n\t\tthis.#isActive = true\r\n\t\tthis.#isPaused = false\r\n\t}\r\n\r\n\tstop(): void {\r\n\t\tthis.#isActive = false\r\n\t\tthis.#isPaused = false\r\n\t}\r\n\r\n\tpause(): void {\r\n\t\tthis.#isPaused = true\r\n\t}\r\n\r\n\tresume(): void {\r\n\t\tthis.#isPaused = false\r\n\t}\r\n\r\n\t// === SUBSCRIPTIONS ===\r\n\r\n\tonSpawn(callback: (entity: TEntity, type: string, zone: SpawnZone) => void): Unsubscribe {\r\n\t\tthis.#listeners.spawn.add(callback)\r\n\t\treturn () => this.#listeners.spawn.delete(callback)\r\n\t}\r\n\r\n\tonWaveStart(callback: (wave: number, config: WaveConfig) => void): Unsubscribe {\r\n\t\tthis.#listeners.waveStart.add(callback)\r\n\t\treturn () => this.#listeners.waveStart.delete(callback)\r\n\t}\r\n\r\n\tonWaveComplete(callback: (wave: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.waveComplete.add(callback)\r\n\t\treturn () => this.#listeners.waveComplete.delete(callback)\r\n\t}\r\n\r\n\t// === LIFECYCLE ===\r\n\r\n\tupdate(deltaTime: number): void {\r\n\t\tif (!this.#isActive || this.#isPaused) return\r\n\r\n\t\tthis.#spawnTimer += deltaTime\r\n\r\n\t\t// Check if it's time to spawn\r\n\t\tif (this.#spawnTimer >= this.#currentSpawnInterval) {\r\n\t\t\tthis.#spawnTimer = 0\r\n\r\n\t\t\t// Select type and spawn\r\n\t\t\tconst type = this.#selectRandomType()\r\n\t\t\tthis.spawn(type)\r\n\r\n\t\t\t// Check wave completion\r\n\t\t\tif (this.#waves.length > 0 && this.#currentWave < this.#waves.length) {\r\n\t\t\t\tconst wave = this.#waves[this.#currentWave]\r\n\t\t\t\tif (wave && this.#totalSpawned >= wave.entityCount) {\r\n\t\t\t\t\tthis.#listeners.waveComplete.forEach(cb => cb(this.#currentWave))\r\n\r\n\t\t\t\t\tif (this.#currentWave + 1 < this.#waves.length) {\r\n\t\t\t\t\t\tthis.nextWave()\r\n\t\t\t\t\t} else if (!this.#infiniteMode) {\r\n\t\t\t\t\t\tthis.stop()\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// Apply interval decay\r\n\t\t\tif (this.#intervalDecayRate > 0) {\r\n\t\t\t\tthis.#currentSpawnInterval = Math.max(\r\n\t\t\t\t\tthis.#minInterval,\r\n\t\t\t\t\tthis.#currentSpawnInterval * (1 - this.#intervalDecayRate),\r\n\t\t\t\t)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\treset(): void {\r\n\t\tthis.#currentWave = 0\r\n\t\tthis.#totalSpawned = 0\r\n\t\tthis.#spawnTimer = 0\r\n\t\tthis.#currentSpawnInterval = this.#baseInterval\r\n\t\tthis.#isActive = false\r\n\t\tthis.#isPaused = false\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.reset()\r\n\t\tthis.#zones.length = 0\r\n\t\tthis.#listeners.spawn.clear()\r\n\t\tthis.#listeners.waveStart.clear()\r\n\t\tthis.#listeners.waveComplete.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tEffectZone,\r\n\tEffectZoneConfig,\r\n\tEffectZoneSystemInterface,\r\n\tEffectZoneSystemOptions,\r\n\tUnsubscribe,\r\n\tVector2,\r\n} from '../../types.js'\r\nimport { generateId } from '../../helpers.js'\r\n\r\n/**\r\n * EffectZoneSystem implementation for managing interactable zones.\r\n */\r\nexport class EffectZoneSystem<TEffect extends string> implements EffectZoneSystemInterface<TEffect> {\r\n\treadonly #zones: Map<string, EffectZone<TEffect>> = new Map()\r\n\treadonly #entitiesInZone: Map<string, Set<string>> = new Map()\r\n\treadonly #defaultCooldown: number\r\n\treadonly #configs: Map<string, EffectZoneConfig<TEffect>> = new Map()\r\n\r\n\treadonly #listeners = {\r\n\t\tzoneEnter: new Set<(zone: EffectZone<TEffect>, entityId: string) => void>(),\r\n\t\tzoneExit: new Set<(zone: EffectZone<TEffect>, entityId: string) => void>(),\r\n\t\tzoneActivate: new Set<(zone: EffectZone<TEffect>) => void>(),\r\n\t\tzoneCooldownEnd: new Set<(zone: EffectZone<TEffect>) => void>(),\r\n\t}\r\n\r\n\tconstructor(options?: EffectZoneSystemOptions<TEffect>) {\r\n\t\tthis.#defaultCooldown = options?.defaultCooldown ?? 1\r\n\r\n\t\tif (options?.onZoneEnter) this.#listeners.zoneEnter.add(options.onZoneEnter)\r\n\t\tif (options?.onZoneExit) this.#listeners.zoneExit.add(options.onZoneExit)\r\n\t\tif (options?.onZoneActivate) this.#listeners.zoneActivate.add(options.onZoneActivate)\r\n\t\tif (options?.onZoneCooldownEnd) this.#listeners.zoneCooldownEnd.add(options.onZoneCooldownEnd)\r\n\r\n\t\t// Create initial zones from config\r\n\t\tif (options?.zones) {\r\n\t\t\tfor (const config of options.zones) {\r\n\t\t\t\tthis.createZone(config.effectType, { x: 0, y: 0 }, config.radius)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// === ACCESSORS ===\r\n\r\n\tgetZones(): readonly EffectZone<TEffect>[] {\r\n\t\treturn Array.from(this.#zones.values())\r\n\t}\r\n\r\n\tgetActiveZones(): readonly EffectZone<TEffect>[] {\r\n\t\treturn Array.from(this.#zones.values()).filter(z => z.active)\r\n\t}\r\n\r\n\tgetZone(id: string): EffectZone<TEffect> | undefined {\r\n\t\treturn this.#zones.get(id)\r\n\t}\r\n\r\n\t// === ZONE MANAGEMENT ===\r\n\r\n\tcreateZone(effectType: TEffect, position: Vector2, radius?: number): EffectZone<TEffect> {\r\n\t\tconst zone: EffectZone<TEffect> = {\r\n\t\t\tid: generateId(),\r\n\t\t\tx: position.x,\r\n\t\t\ty: position.y,\r\n\t\t\tradius: radius ?? 50,\r\n\t\t\teffectType,\r\n\t\t\tactive: true,\r\n\t\t\tcooldownUntil: 0,\r\n\t\t\tpulsePhase: Math.random() * Math.PI * 2,\r\n\t\t}\r\n\r\n\t\tthis.#zones.set(zone.id, zone)\r\n\t\tthis.#entitiesInZone.set(zone.id, new Set())\r\n\t\tthis.#listeners.zoneActivate.forEach(cb => cb(zone))\r\n\r\n\t\treturn zone\r\n\t}\r\n\r\n\tremoveZone(zoneId: string): void {\r\n\t\tconst zone = this.#zones.get(zoneId)\r\n\t\tif (!zone) return\r\n\r\n\t\t// Emit exit events for all entities in zone\r\n\t\tconst entities = this.#entitiesInZone.get(zoneId)\r\n\t\tif (entities) {\r\n\t\t\tfor (const entityId of entities) {\r\n\t\t\t\tthis.#listeners.zoneExit.forEach(cb => cb(zone, entityId))\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tthis.#zones.delete(zoneId)\r\n\t\tthis.#entitiesInZone.delete(zoneId)\r\n\t\tthis.#configs.delete(zoneId)\r\n\t}\r\n\r\n\tdeactivateZone(zoneId: string, cooldownDuration: number, currentTime: number): void {\r\n\t\tconst zone = this.#zones.get(zoneId)\r\n\t\tif (zone) {\r\n\t\t\tzone.active = false\r\n\t\t\tzone.cooldownUntil = currentTime + cooldownDuration\r\n\t\t}\r\n\t}\r\n\r\n\tactivateZone(zoneId: string): void {\r\n\t\tconst zone = this.#zones.get(zoneId)\r\n\t\tif (zone) {\r\n\t\t\tzone.active = true\r\n\t\t\tzone.cooldownUntil = 0\r\n\t\t\tthis.#listeners.zoneActivate.forEach(cb => cb(zone))\r\n\t\t}\r\n\t}\r\n\r\n\t// === COLLISION CHECKING ===\r\n\r\n\t#circlesCollide(\r\n\t\tx1: number, y1: number, r1: number,\r\n\t\tx2: number, y2: number, r2: number,\r\n\t): boolean {\r\n\t\tconst dx = x2 - x1\r\n\t\tconst dy = y2 - y1\r\n\t\tconst distSq = dx * dx + dy * dy\r\n\t\tconst radiusSum = r1 + r2\r\n\t\treturn distSq <= radiusSum * radiusSum\r\n\t}\r\n\r\n\tcheckCollision(entityId: string, position: Vector2, entityRadius: number): EffectZone<TEffect> | undefined {\r\n\t\tfor (const zone of this.#zones.values()) {\r\n\t\t\tif (!zone.active) continue\r\n\r\n\t\t\tif (this.#circlesCollide(\r\n\t\t\t\tposition.x, position.y, entityRadius,\r\n\t\t\t\tzone.x, zone.y, zone.radius,\r\n\t\t\t)) {\r\n\t\t\t\t// Track entity in zone\r\n\t\t\t\tconst entities = this.#entitiesInZone.get(zone.id)\r\n\t\t\t\tif (entities && !entities.has(entityId)) {\r\n\t\t\t\t\tentities.add(entityId)\r\n\t\t\t\t\tthis.#listeners.zoneEnter.forEach(cb => cb(zone, entityId))\r\n\t\t\t\t}\r\n\t\t\t\treturn zone\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Check for zone exits\r\n\t\tfor (const [zoneId, entities] of this.#entitiesInZone) {\r\n\t\t\tif (entities.has(entityId)) {\r\n\t\t\t\tconst zone = this.#zones.get(zoneId)\r\n\t\t\t\tif (zone && !this.#circlesCollide(\r\n\t\t\t\t\tposition.x, position.y, entityRadius,\r\n\t\t\t\t\tzone.x, zone.y, zone.radius,\r\n\t\t\t\t)) {\r\n\t\t\t\t\tentities.delete(entityId)\r\n\t\t\t\t\tthis.#listeners.zoneExit.forEach(cb => cb(zone, entityId))\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn undefined\r\n\t}\r\n\r\n\tcheckAllCollisions(entityId: string, position: Vector2, entityRadius: number): readonly EffectZone<TEffect>[] {\r\n\t\tconst collisions: EffectZone<TEffect>[] = []\r\n\r\n\t\tfor (const zone of this.#zones.values()) {\r\n\t\t\tif (!zone.active) continue\r\n\r\n\t\t\tif (this.#circlesCollide(\r\n\t\t\t\tposition.x, position.y, entityRadius,\r\n\t\t\t\tzone.x, zone.y, zone.radius,\r\n\t\t\t)) {\r\n\t\t\t\t// Track entity in zone\r\n\t\t\t\tconst entities = this.#entitiesInZone.get(zone.id)\r\n\t\t\t\tif (entities && !entities.has(entityId)) {\r\n\t\t\t\t\tentities.add(entityId)\r\n\t\t\t\t\tthis.#listeners.zoneEnter.forEach(cb => cb(zone, entityId))\r\n\t\t\t\t}\r\n\t\t\t\tcollisions.push(zone)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Check for zone exits\r\n\t\tfor (const [zoneId, entities] of this.#entitiesInZone) {\r\n\t\t\tif (entities.has(entityId)) {\r\n\t\t\t\tconst zone = this.#zones.get(zoneId)\r\n\t\t\t\tif (zone && !collisions.includes(zone)) {\r\n\t\t\t\t\tentities.delete(entityId)\r\n\t\t\t\t\tthis.#listeners.zoneExit.forEach(cb => cb(zone, entityId))\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn collisions\r\n\t}\r\n\r\n\t// === SUBSCRIPTIONS ===\r\n\r\n\tonZoneEnter(callback: (zone: EffectZone<TEffect>, entityId: string) => void): Unsubscribe {\r\n\t\tthis.#listeners.zoneEnter.add(callback)\r\n\t\treturn () => this.#listeners.zoneEnter.delete(callback)\r\n\t}\r\n\r\n\tonZoneExit(callback: (zone: EffectZone<TEffect>, entityId: string) => void): Unsubscribe {\r\n\t\tthis.#listeners.zoneExit.add(callback)\r\n\t\treturn () => this.#listeners.zoneExit.delete(callback)\r\n\t}\r\n\r\n\tonZoneActivate(callback: (zone: EffectZone<TEffect>) => void): Unsubscribe {\r\n\t\tthis.#listeners.zoneActivate.add(callback)\r\n\t\treturn () => this.#listeners.zoneActivate.delete(callback)\r\n\t}\r\n\r\n\tonZoneCooldownEnd(callback: (zone: EffectZone<TEffect>) => void): Unsubscribe {\r\n\t\tthis.#listeners.zoneCooldownEnd.add(callback)\r\n\t\treturn () => this.#listeners.zoneCooldownEnd.delete(callback)\r\n\t}\r\n\r\n\t// === LIFECYCLE ===\r\n\r\n\tupdate(currentTime: number): void {\r\n\t\t// Handle zone cooldowns\r\n\t\tfor (const zone of this.#zones.values()) {\r\n\t\t\t// Update pulse phase\r\n\t\t\tzone.pulsePhase += 0.05\r\n\r\n\t\t\t// Check cooldown expiration\r\n\t\t\tif (!zone.active && zone.cooldownUntil > 0 && currentTime >= zone.cooldownUntil) {\r\n\t\t\t\tzone.active = true\r\n\t\t\t\tzone.cooldownUntil = 0\r\n\t\t\t\tthis.#listeners.zoneCooldownEnd.forEach(cb => cb(zone))\r\n\t\t\t\tthis.#listeners.zoneActivate.forEach(cb => cb(zone))\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\treset(): void {\r\n\t\t// Clear all entities from zones\r\n\t\tfor (const [zoneId, entities] of this.#entitiesInZone) {\r\n\t\t\tconst zone = this.#zones.get(zoneId)\r\n\t\t\tif (zone) {\r\n\t\t\t\tfor (const entityId of entities) {\r\n\t\t\t\t\tthis.#listeners.zoneExit.forEach(cb => cb(zone, entityId))\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tentities.clear()\r\n\t\t}\r\n\r\n\t\t// Reactivate all zones\r\n\t\tfor (const zone of this.#zones.values()) {\r\n\t\t\tzone.active = true\r\n\t\t\tzone.cooldownUntil = 0\r\n\t\t}\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.reset()\r\n\t\tthis.#zones.clear()\r\n\t\tthis.#entitiesInZone.clear()\r\n\t\tthis.#configs.clear()\r\n\t\tthis.#listeners.zoneEnter.clear()\r\n\t\tthis.#listeners.zoneExit.clear()\r\n\t\tthis.#listeners.zoneActivate.clear()\r\n\t\tthis.#listeners.zoneCooldownEnd.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tBackgroundLayer,\r\n\tBackgroundSystemInterface,\r\n\tBackgroundSystemOptions,\r\n\tCameraInterface,\r\n\tParallaxConfig,\r\n\tStarData,\r\n\tStarfieldConfig,\r\n\tStarfieldLayer,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\nimport { generateId } from '../../helpers.js'\r\n\r\n/**\r\n * BackgroundSystem implementation for parallax backgrounds and starfields.\r\n */\r\nexport class BackgroundSystem implements BackgroundSystemInterface {\r\n\treadonly #layers: Map<string, BackgroundLayer> = new Map()\r\n\treadonly #starData: Map<string, StarData[]> = new Map()\r\n\treadonly #parallaxConfigs: Map<string, ParallaxConfig> = new Map()\r\n\treadonly #solidColors: Map<string, string> = new Map()\r\n\treadonly #gradients: Map<string, CanvasGradient> = new Map()\r\n\treadonly #customRenderers: Map<string, (ctx: CanvasRenderingContext2D, camera: CameraInterface) => void> = new Map()\r\n\r\n\treadonly #clearColor: string\r\n\treadonly #worldWidth: number\r\n\treadonly #worldHeight: number\r\n\r\n\treadonly #listeners = {\r\n\t\tlayerAdd: new Set<(layer: BackgroundLayer) => void>(),\r\n\t\tlayerRemove: new Set<(layerName: string) => void>(),\r\n\t}\r\n\r\n\tconstructor(options?: BackgroundSystemOptions) {\r\n\t\tthis.#clearColor = options?.clearColor ?? '#000000'\r\n\t\tthis.#worldWidth = options?.worldWidth ?? 800\r\n\t\tthis.#worldHeight = options?.worldHeight ?? 600\r\n\r\n\t\tif (options?.onLayerAdd) this.#listeners.layerAdd.add(options.onLayerAdd)\r\n\t\tif (options?.onLayerRemove) this.#listeners.layerRemove.add(options.onLayerRemove)\r\n\t}\r\n\r\n\t// === ACCESSORS ===\r\n\r\n\tgetLayers(): readonly BackgroundLayer[] {\r\n\t\treturn Array.from(this.#layers.values()).sort((a, b) => a.zIndex - b.zIndex)\r\n\t}\r\n\r\n\tgetLayer(name: string): BackgroundLayer | undefined {\r\n\t\treturn this.#layers.get(name)\r\n\t}\r\n\r\n\t// === LAYER CREATION ===\r\n\r\n\taddSolidLayer(name: string, color: string, zIndex?: number): BackgroundLayer {\r\n\t\tconst layer: BackgroundLayer = {\r\n\t\t\tid: generateId(),\r\n\t\t\tname,\r\n\t\t\ttype: 'solid',\r\n\t\t\tzIndex: zIndex ?? this.#layers.size,\r\n\t\t\tvisible: true,\r\n\t\t\topacity: 1,\r\n\t\t}\r\n\r\n\t\tthis.#layers.set(name, layer)\r\n\t\tthis.#solidColors.set(name, color)\r\n\t\tthis.#listeners.layerAdd.forEach(cb => cb(layer))\r\n\r\n\t\treturn layer\r\n\t}\r\n\r\n\taddGradientLayer(name: string, gradient: CanvasGradient, zIndex?: number): BackgroundLayer {\r\n\t\tconst layer: BackgroundLayer = {\r\n\t\t\tid: generateId(),\r\n\t\t\tname,\r\n\t\t\ttype: 'gradient',\r\n\t\t\tzIndex: zIndex ?? this.#layers.size,\r\n\t\t\tvisible: true,\r\n\t\t\topacity: 1,\r\n\t\t}\r\n\r\n\t\tthis.#layers.set(name, layer)\r\n\t\tthis.#gradients.set(name, gradient)\r\n\t\tthis.#listeners.layerAdd.forEach(cb => cb(layer))\r\n\r\n\t\treturn layer\r\n\t}\r\n\r\n\taddStarfieldLayer(name: string, config: StarfieldConfig, zIndex?: number): StarfieldLayer {\r\n\t\tconst stars = this.#generateStars(config)\r\n\r\n\t\tconst layer: StarfieldLayer = {\r\n\t\t\tid: generateId(),\r\n\t\t\tname,\r\n\t\t\ttype: 'starfield',\r\n\t\t\tzIndex: zIndex ?? this.#layers.size,\r\n\t\t\tvisible: true,\r\n\t\t\topacity: 1,\r\n\t\t\tconfig,\r\n\t\t\tstars,\r\n\t\t}\r\n\r\n\t\tthis.#layers.set(name, layer)\r\n\t\tthis.#starData.set(name, [...stars])\r\n\t\tthis.#listeners.layerAdd.forEach(cb => cb(layer))\r\n\r\n\t\treturn layer\r\n\t}\r\n\r\n\taddParallaxLayer(name: string, config: ParallaxConfig, zIndex?: number): BackgroundLayer {\r\n\t\tconst layer: BackgroundLayer = {\r\n\t\t\tid: generateId(),\r\n\t\t\tname,\r\n\t\t\ttype: 'parallax',\r\n\t\t\tzIndex: zIndex ?? this.#layers.size,\r\n\t\t\tvisible: true,\r\n\t\t\topacity: config.opacity ?? 1,\r\n\t\t}\r\n\r\n\t\tthis.#layers.set(name, layer)\r\n\t\tthis.#parallaxConfigs.set(name, config)\r\n\t\tthis.#listeners.layerAdd.forEach(cb => cb(layer))\r\n\r\n\t\treturn layer\r\n\t}\r\n\r\n\taddCustomLayer(\r\n\t\tname: string,\r\n\t\trenderer: (ctx: CanvasRenderingContext2D, camera: CameraInterface) => void,\r\n\t\tzIndex?: number,\r\n\t): BackgroundLayer {\r\n\t\tconst layer: BackgroundLayer = {\r\n\t\t\tid: generateId(),\r\n\t\t\tname,\r\n\t\t\ttype: 'custom',\r\n\t\t\tzIndex: zIndex ?? this.#layers.size,\r\n\t\t\tvisible: true,\r\n\t\t\topacity: 1,\r\n\t\t}\r\n\r\n\t\tthis.#layers.set(name, layer)\r\n\t\tthis.#customRenderers.set(name, renderer)\r\n\t\tthis.#listeners.layerAdd.forEach(cb => cb(layer))\r\n\r\n\t\treturn layer\r\n\t}\r\n\r\n\t#generateStars(config: StarfieldConfig): StarData[] {\r\n\t\tconst stars: StarData[] = []\r\n\t\tconst width = this.#worldWidth * 2\r\n\t\tconst height = this.#worldHeight * 2\r\n\r\n\t\tfor (let i = 0; i < config.count; i++) {\r\n\t\t\tstars.push({\r\n\t\t\t\tx: Math.random() * width - width / 2,\r\n\t\t\t\ty: Math.random() * height - height / 2,\r\n\t\t\t\tsize: config.minSize + Math.random() * (config.maxSize - config.minSize),\r\n\t\t\t\tbrightness: config.minBrightness + Math.random() * (config.maxBrightness - config.minBrightness),\r\n\t\t\t\ttwinklePhase: Math.random() * Math.PI * 2,\r\n\t\t\t\ttwinkleSpeed: config.twinkleSpeed * (0.5 + Math.random()),\r\n\t\t\t})\r\n\t\t}\r\n\r\n\t\treturn stars\r\n\t}\r\n\r\n\t// === LAYER MANAGEMENT ===\r\n\r\n\tremoveLayer(name: string): void {\r\n\t\tif (this.#layers.has(name)) {\r\n\t\t\tthis.#layers.delete(name)\r\n\t\t\tthis.#solidColors.delete(name)\r\n\t\t\tthis.#gradients.delete(name)\r\n\t\t\tthis.#starData.delete(name)\r\n\t\t\tthis.#parallaxConfigs.delete(name)\r\n\t\t\tthis.#customRenderers.delete(name)\r\n\t\t\tthis.#listeners.layerRemove.forEach(cb => cb(name))\r\n\t\t}\r\n\t}\r\n\r\n\tsetLayerVisible(name: string, visible: boolean): void {\r\n\t\tconst layer = this.#layers.get(name)\r\n\t\tif (layer) {\r\n\t\t\tlayer.visible = visible\r\n\t\t}\r\n\t}\r\n\r\n\tsetLayerOpacity(name: string, opacity: number): void {\r\n\t\tconst layer = this.#layers.get(name)\r\n\t\tif (layer) {\r\n\t\t\tlayer.opacity = Math.max(0, Math.min(1, opacity))\r\n\t\t}\r\n\t}\r\n\r\n\treorderLayer(name: string, newZIndex: number): void {\r\n\t\tconst layer = this.#layers.get(name) as { zIndex: number } | undefined\r\n\t\tif (layer) {\r\n\t\t\tlayer.zIndex = newZIndex\r\n\t\t}\r\n\t}\r\n\r\n\t// === SUBSCRIPTIONS ===\r\n\r\n\tonLayerAdd(callback: (layer: BackgroundLayer) => void): Unsubscribe {\r\n\t\tthis.#listeners.layerAdd.add(callback)\r\n\t\treturn () => this.#listeners.layerAdd.delete(callback)\r\n\t}\r\n\r\n\tonLayerRemove(callback: (layerName: string) => void): Unsubscribe {\r\n\t\tthis.#listeners.layerRemove.add(callback)\r\n\t\treturn () => this.#listeners.layerRemove.delete(callback)\r\n\t}\r\n\r\n\t// === LIFECYCLE ===\r\n\r\n\tupdate(deltaTime: number, _cameraX: number, _cameraY: number): void {\r\n\t\t// Update starfield twinkle\r\n\t\tfor (const [name, stars] of this.#starData) {\r\n\t\t\tfor (const star of stars) {\r\n\t\t\t\tstar.twinklePhase += star.twinkleSpeed * deltaTime\r\n\t\t\t}\r\n\r\n\t\t\t// Update the layer's stars reference\r\n\t\t\tconst layer = this.#layers.get(name) as StarfieldLayer | undefined\r\n\t\t\tif (layer && layer.type === 'starfield') {\r\n\t\t\t\t(layer as { stars: readonly StarData[] }).stars = stars\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\trender(ctx: CanvasRenderingContext2D, camera: CameraInterface): void {\r\n\t\tconst sortedLayers = this.getLayers()\r\n\r\n\t\tfor (const layer of sortedLayers) {\r\n\t\t\tif (!layer.visible) continue\r\n\r\n\t\t\tctx.save()\r\n\t\t\tctx.globalAlpha = layer.opacity\r\n\r\n\t\t\tswitch (layer.type) {\r\n\t\t\t\tcase 'solid':\r\n\t\t\t\t\tthis.#renderSolidLayer(ctx, layer.name)\r\n\t\t\t\t\tbreak\r\n\r\n\t\t\t\tcase 'gradient':\r\n\t\t\t\t\tthis.#renderGradientLayer(ctx, layer.name)\r\n\t\t\t\t\tbreak\r\n\r\n\t\t\t\tcase 'starfield':\r\n\t\t\t\t\tthis.#renderStarfieldLayer(ctx, layer as StarfieldLayer, camera)\r\n\t\t\t\t\tbreak\r\n\r\n\t\t\t\tcase 'parallax':\r\n\t\t\t\t// Parallax rendering would need image loading\r\n\t\t\t\t\tbreak\r\n\r\n\t\t\t\tcase 'custom':\r\n\t\t\t\t\tthis.#renderCustomLayer(ctx, layer.name, camera)\r\n\t\t\t\t\tbreak\r\n\t\t\t}\r\n\r\n\t\t\tctx.restore()\r\n\t\t}\r\n\t}\r\n\r\n\t#renderSolidLayer(ctx: CanvasRenderingContext2D, name: string): void {\r\n\t\tconst color = this.#solidColors.get(name)\r\n\t\tif (color) {\r\n\t\t\tctx.fillStyle = color\r\n\t\t\tctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height)\r\n\t\t}\r\n\t}\r\n\r\n\t#renderGradientLayer(ctx: CanvasRenderingContext2D, name: string): void {\r\n\t\tconst gradient = this.#gradients.get(name)\r\n\t\tif (gradient) {\r\n\t\t\tctx.fillStyle = gradient\r\n\t\t\tctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height)\r\n\t\t}\r\n\t}\r\n\r\n\t#renderStarfieldLayer(ctx: CanvasRenderingContext2D, layer: StarfieldLayer, camera: CameraInterface): void {\r\n\t\tconst stars = this.#starData.get(layer.name)\r\n\t\tif (!stars) return\r\n\r\n\t\tconst cameraX = camera.getX()\r\n\t\tconst cameraY = camera.getY()\r\n\t\tconst config = layer.config\r\n\r\n\t\tfor (const star of stars) {\r\n\t\t\t// Calculate screen position with parallax\r\n\t\t\tlet screenX = star.x - cameraX * 0.3\r\n\t\t\tlet screenY = star.y - cameraY * 0.3\r\n\r\n\t\t\t// Wrap around\r\n\t\t\tconst width = ctx.canvas.width\r\n\t\t\tconst height = ctx.canvas.height\r\n\r\n\t\t\tscreenX = ((screenX % width) + width) % width\r\n\t\t\tscreenY = ((screenY % height) + height) % height\r\n\r\n\t\t\t// Calculate twinkle brightness\r\n\t\t\tconst twinkleFactor = 0.7 + 0.3 * Math.sin(star.twinklePhase)\r\n\t\t\tconst brightness = star.brightness * twinkleFactor\r\n\r\n\t\t\t// Draw star\r\n\t\t\tctx.beginPath()\r\n\t\t\tctx.arc(screenX, screenY, star.size, 0, Math.PI * 2)\r\n\t\t\tctx.fillStyle = config.color ?? `rgba(255, 255, 255, ${brightness})`\r\n\t\t\tif (!config.color) {\r\n\t\t\t\tctx.fillStyle = `rgba(255, 255, 255, ${brightness})`\r\n\t\t\t}\r\n\t\t\tctx.fill()\r\n\t\t}\r\n\t}\r\n\r\n\t#renderCustomLayer(ctx: CanvasRenderingContext2D, name: string, camera: CameraInterface): void {\r\n\t\tconst renderer = this.#customRenderers.get(name)\r\n\t\tif (renderer) {\r\n\t\t\trenderer(ctx, camera)\r\n\t\t}\r\n\t}\r\n\r\n\tclear(): void {\r\n\t\tfor (const name of this.#layers.keys()) {\r\n\t\t\tthis.#listeners.layerRemove.forEach(cb => cb(name))\r\n\t\t}\r\n\r\n\t\tthis.#layers.clear()\r\n\t\tthis.#solidColors.clear()\r\n\t\tthis.#gradients.clear()\r\n\t\tthis.#starData.clear()\r\n\t\tthis.#parallaxConfigs.clear()\r\n\t\tthis.#customRenderers.clear()\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.clear()\r\n\t\tthis.#listeners.layerAdd.clear()\r\n\t\tthis.#listeners.layerRemove.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tExperienceSystemInterface,\r\n\tExperienceSystemOptions,\r\n\tLevelReward,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\n/**\r\n * ExperienceSystem implementation for XP and leveling.\r\n */\r\nexport class ExperienceSystem<TReward = unknown> implements ExperienceSystemInterface<TReward> {\r\n\treadonly #levelRewards: readonly LevelReward<TReward>[]\r\n\treadonly #xpFormula: (level: number) => number\r\n\treadonly #maxLevel: number\r\n\r\n\t#currentLevel: number\r\n\t#currentXP: number\r\n\r\n\treadonly #listeners = {\r\n\t\txpGain: new Set<(amount: number, totalXP: number) => void>(),\r\n\t\txpLoss: new Set<(amount: number, totalXP: number) => void>(),\r\n\t\tlevelUp: new Set<(newLevel: number, rewards: TReward | undefined) => void>(),\r\n\t\tlevelDown: new Set<(newLevel: number) => void>(),\r\n\t}\r\n\r\n\tconstructor(options?: ExperienceSystemOptions<TReward>) {\r\n\t\tthis.#levelRewards = options?.levelRewards ?? []\r\n\t\tthis.#maxLevel = options?.maxLevel ?? 100\r\n\t\tthis.#currentLevel = options?.startingLevel ?? 1\r\n\t\tthis.#currentXP = options?.startingXP ?? 0\r\n\r\n\t\t// Default XP formula: 100 * level^1.5\r\n\t\tthis.#xpFormula = options?.xpFormula ?? ((level: number) =>\r\n\t\t\tMath.floor(100 * Math.pow(level, 1.5)))\r\n\r\n\t\tif (options?.onXPGain) this.#listeners.xpGain.add(options.onXPGain)\r\n\t\tif (options?.onXPLoss) this.#listeners.xpLoss.add(options.onXPLoss)\r\n\t\tif (options?.onLevelUp) this.#listeners.levelUp.add(options.onLevelUp)\r\n\t\tif (options?.onLevelDown) this.#listeners.levelDown.add(options.onLevelDown)\r\n\t}\r\n\r\n\t// === ACCESSORS ===\r\n\r\n\tgetLevel(): number {\r\n\t\treturn this.#currentLevel\r\n\t}\r\n\r\n\tgetXP(): number {\r\n\t\treturn this.#currentXP\r\n\t}\r\n\r\n\tgetXPForLevel(level: number): number {\r\n\t\tif (level <= 1) return 0\r\n\r\n\t\t// Check level rewards first\r\n\t\tconst reward = this.#levelRewards.find(r => r.level === level)\r\n\t\tif (reward) return reward.xpRequired\r\n\r\n\t\t// Use formula\r\n\t\treturn this.#xpFormula(level)\r\n\t}\r\n\r\n\tgetXPForCurrentLevel(): number {\r\n\t\treturn this.getXPForLevel(this.#currentLevel)\r\n\t}\r\n\r\n\tgetXPForNextLevel(): number {\r\n\t\tif (this.#currentLevel >= this.#maxLevel) return 0\r\n\t\treturn this.getXPForLevel(this.#currentLevel + 1)\r\n\t}\r\n\r\n\tgetXPProgress(): number {\r\n\t\tconst currentLevelXP = this.getXPForCurrentLevel()\r\n\t\tconst nextLevelXP = this.getXPForNextLevel()\r\n\r\n\t\tif (nextLevelXP === 0) return 1 // Max level\r\n\r\n\t\tconst xpInCurrentLevel = this.#currentXP - currentLevelXP\r\n\t\tconst xpNeededForLevel = nextLevelXP - currentLevelXP\r\n\r\n\t\treturn xpNeededForLevel > 0 ? xpInCurrentLevel / xpNeededForLevel : 1\r\n\t}\r\n\r\n\tgetMaxLevel(): number {\r\n\t\treturn this.#maxLevel\r\n\t}\r\n\r\n\tisMaxLevel(): boolean {\r\n\t\treturn this.#currentLevel >= this.#maxLevel\r\n\t}\r\n\r\n\t// === MUTATORS ===\r\n\r\n\taddXP(amount: number): void {\r\n\t\tif (amount <= 0) return\r\n\r\n\t\tthis.#currentXP += amount\r\n\t\tthis.#listeners.xpGain.forEach(cb => cb(amount, this.#currentXP))\r\n\r\n\t\t// Check for level ups\r\n\t\tthis.#checkLevelUp()\r\n\t}\r\n\r\n\tremoveXP(amount: number): void {\r\n\t\tif (amount <= 0) return\r\n\r\n\t\tconst previousXP = this.#currentXP\r\n\t\tthis.#currentXP = Math.max(0, this.#currentXP - amount)\r\n\r\n\t\tconst actualLoss = previousXP - this.#currentXP\r\n\t\tif (actualLoss > 0) {\r\n\t\t\tthis.#listeners.xpLoss.forEach(cb => cb(actualLoss, this.#currentXP))\r\n\t\t}\r\n\r\n\t\t// Check for level down\r\n\t\tthis.#checkLevelDown()\r\n\t}\r\n\r\n\tsetXP(amount: number): void {\r\n\t\tconst previousXP = this.#currentXP\r\n\t\tthis.#currentXP = Math.max(0, amount)\r\n\r\n\t\tif (this.#currentXP > previousXP) {\r\n\t\t\tthis.#checkLevelUp()\r\n\t\t} else if (this.#currentXP < previousXP) {\r\n\t\t\tthis.#checkLevelDown()\r\n\t\t}\r\n\t}\r\n\r\n\tsetLevel(level: number): void {\r\n\t\tconst newLevel = Math.max(1, Math.min(this.#maxLevel, level))\r\n\t\tconst oldLevel = this.#currentLevel\r\n\r\n\t\tif (newLevel === oldLevel) return\r\n\r\n\t\tthis.#currentLevel = newLevel\r\n\t\tthis.#currentXP = this.getXPForLevel(newLevel)\r\n\r\n\t\tif (newLevel > oldLevel) {\r\n\t\t\tconst reward = this.getLevelReward(newLevel)\r\n\t\t\tthis.#listeners.levelUp.forEach(cb => cb(newLevel, reward))\r\n\t\t} else {\r\n\t\t\tthis.#listeners.levelDown.forEach(cb => cb(newLevel))\r\n\t\t}\r\n\t}\r\n\r\n\t#checkLevelUp(): void {\r\n\t\twhile (this.#currentLevel < this.#maxLevel) {\r\n\t\t\tconst nextLevelXP = this.getXPForNextLevel()\r\n\t\t\tif (this.#currentXP >= nextLevelXP) {\r\n\t\t\t\tthis.#currentLevel++\r\n\t\t\t\tconst reward = this.getLevelReward(this.#currentLevel)\r\n\t\t\t\tthis.#listeners.levelUp.forEach(cb => cb(this.#currentLevel, reward))\r\n\t\t\t} else {\r\n\t\t\t\tbreak\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t#checkLevelDown(): void {\r\n\t\twhile (this.#currentLevel > 1) {\r\n\t\t\tconst currentLevelXP = this.getXPForCurrentLevel()\r\n\t\t\tif (this.#currentXP < currentLevelXP) {\r\n\t\t\t\tthis.#currentLevel--\r\n\t\t\t\tthis.#listeners.levelDown.forEach(cb => cb(this.#currentLevel))\r\n\t\t\t} else {\r\n\t\t\t\tbreak\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// === REWARDS ===\r\n\r\n\tgetLevelReward(level: number): TReward | undefined {\r\n\t\tconst reward = this.#levelRewards.find(r => r.level === level)\r\n\t\treturn reward?.rewards\r\n\t}\r\n\r\n\tgetCurrentLevelReward(): TReward | undefined {\r\n\t\treturn this.getLevelReward(this.#currentLevel)\r\n\t}\r\n\r\n\t// === SUBSCRIPTIONS ===\r\n\r\n\tonXPGain(callback: (amount: number, totalXP: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.xpGain.add(callback)\r\n\t\treturn () => this.#listeners.xpGain.delete(callback)\r\n\t}\r\n\r\n\tonXPLoss(callback: (amount: number, totalXP: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.xpLoss.add(callback)\r\n\t\treturn () => this.#listeners.xpLoss.delete(callback)\r\n\t}\r\n\r\n\tonLevelUp(callback: (newLevel: number, rewards: TReward | undefined) => void): Unsubscribe {\r\n\t\tthis.#listeners.levelUp.add(callback)\r\n\t\treturn () => this.#listeners.levelUp.delete(callback)\r\n\t}\r\n\r\n\tonLevelDown(callback: (newLevel: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.levelDown.add(callback)\r\n\t\treturn () => this.#listeners.levelDown.delete(callback)\r\n\t}\r\n\r\n\t// === LIFECYCLE ===\r\n\r\n\treset(): void {\r\n\t\tthis.#currentLevel = 1\r\n\t\tthis.#currentXP = 0\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.reset()\r\n\t\tthis.#listeners.xpGain.clear()\r\n\t\tthis.#listeners.xpLoss.clear()\r\n\t\tthis.#listeners.levelUp.clear()\r\n\t\tthis.#listeners.levelDown.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tMilestoneDef,\r\n\tStatisticDef,\r\n\tStatisticsSystemInterface,\r\n\tStatisticsSystemOptions,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\n/**\r\n * StatisticsSystem implementation for analytics and achievements.\r\n */\r\nexport class StatisticsSystem implements StatisticsSystemInterface {\r\n\treadonly #statistics: Map<string, StatisticDef> = new Map()\r\n\treadonly #milestones: MilestoneDef[] = []\r\n\treadonly #reachedMilestones: Set<string> = new Set()\r\n\treadonly #storageKey: string\r\n\r\n\treadonly #sessionStats: Map<string, number> = new Map()\r\n\treadonly #lifetimeStats: Map<string, number> = new Map()\r\n\treadonly #averageCounts: Map<string, number> = new Map()\r\n\r\n\t#sessionStartTime = 0\r\n\t#isInSession = false\r\n\r\n\treadonly #listeners = {\r\n\t\tstatChange: new Set<(key: string, oldValue: number, newValue: number) => void>(),\r\n\t\tmilestoneReached: new Set<(milestone: MilestoneDef, value: number) => void>(),\r\n\t\tsessionStart: new Set<() => void>(),\r\n\t\tsessionEnd: new Set<(duration: number) => void>(),\r\n\t}\r\n\r\n\tconstructor(options?: StatisticsSystemOptions) {\r\n\t\tthis.#storageKey = options?.storageKey ?? 'game-statistics'\r\n\r\n\t\t// Register statistics\r\n\t\tif (options?.statistics) {\r\n\t\t\tfor (const stat of options.statistics) {\r\n\t\t\t\tthis.#statistics.set(stat.key, stat)\r\n\t\t\t\tthis.#sessionStats.set(stat.key, 0)\r\n\t\t\t\tthis.#lifetimeStats.set(stat.key, 0)\r\n\t\t\t\tif (stat.type === 'average') {\r\n\t\t\t\t\tthis.#averageCounts.set(stat.key, 0)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Register milestones\r\n\t\tif (options?.milestones) {\r\n\t\t\tthis.#milestones.push(...options.milestones)\r\n\t\t}\r\n\r\n\t\tif (options?.onStatChange) this.#listeners.statChange.add(options.onStatChange)\r\n\t\tif (options?.onMilestoneReached) this.#listeners.milestoneReached.add(options.onMilestoneReached)\r\n\t\tif (options?.onSessionStart) this.#listeners.sessionStart.add(options.onSessionStart)\r\n\t\tif (options?.onSessionEnd) this.#listeners.sessionEnd.add(options.onSessionEnd)\r\n\t}\r\n\r\n\t// === ACCESSORS ===\r\n\r\n\tgetStat(key: string): number {\r\n\t\treturn this.#sessionStats.get(key) ?? 0\r\n\t}\r\n\r\n\tgetAllStats(): Readonly<Record<string, number>> {\r\n\t\tconst stats: Record<string, number> = {}\r\n\t\tfor (const [key, value] of this.#sessionStats) {\r\n\t\t\tstats[key] = value\r\n\t\t}\r\n\t\treturn stats\r\n\t}\r\n\r\n\tgetSessionStat(key: string): number {\r\n\t\treturn this.#sessionStats.get(key) ?? 0\r\n\t}\r\n\r\n\tgetLifetimeStat(key: string): number {\r\n\t\treturn this.#lifetimeStats.get(key) ?? 0\r\n\t}\r\n\r\n\tgetSessionDuration(): number {\r\n\t\tif (!this.#isInSession) return 0\r\n\t\treturn (Date.now() - this.#sessionStartTime) / 1000\r\n\t}\r\n\r\n\t// === MUTATORS ===\r\n\r\n\tincrement(key: string, amount?: number): void {\r\n\t\tconst increment = amount ?? 1\r\n\t\tconst stat = this.#statistics.get(key)\r\n\t\tif (!stat) return\r\n\r\n\t\tconst oldValue = this.#sessionStats.get(key) ?? 0\r\n\t\tconst newValue = oldValue + increment\r\n\r\n\t\tthis.#updateStat(key, newValue, stat)\r\n\t}\r\n\r\n\tdecrement(key: string, amount?: number): void {\r\n\t\tconst decrement = amount ?? 1\r\n\t\tconst stat = this.#statistics.get(key)\r\n\t\tif (!stat) return\r\n\r\n\t\tconst oldValue = this.#sessionStats.get(key) ?? 0\r\n\t\tconst newValue = Math.max(0, oldValue - decrement)\r\n\r\n\t\tthis.#updateStat(key, newValue, stat)\r\n\t}\r\n\r\n\tset(key: string, value: number): void {\r\n\t\tconst stat = this.#statistics.get(key)\r\n\t\tif (!stat) return\r\n\r\n\t\tthis.#updateStat(key, value, stat)\r\n\t}\r\n\r\n\tmax(key: string, value: number): void {\r\n\t\tconst stat = this.#statistics.get(key)\r\n\t\tif (!stat || stat.type !== 'max') return\r\n\r\n\t\tconst currentValue = this.#sessionStats.get(key) ?? 0\r\n\t\tif (value > currentValue) {\r\n\t\t\tthis.#updateStat(key, value, stat)\r\n\t\t}\r\n\t}\r\n\r\n\tmin(key: string, value: number): void {\r\n\t\tconst stat = this.#statistics.get(key)\r\n\t\tif (!stat || stat.type !== 'min') return\r\n\r\n\t\tconst currentValue = this.#sessionStats.get(key) ?? Number.MAX_VALUE\r\n\t\tif (value < currentValue) {\r\n\t\t\tthis.#updateStat(key, value, stat)\r\n\t\t}\r\n\t}\r\n\r\n\t#updateStat(key: string, newValue: number, stat: StatisticDef): void {\r\n\t\tconst oldValue = this.#sessionStats.get(key) ?? 0\r\n\t\tthis.#sessionStats.set(key, newValue)\r\n\r\n\t\t// Update lifetime stats based on type\r\n\t\tif (stat.type === 'counter') {\r\n\t\t\tconst lifetime = this.#lifetimeStats.get(key) ?? 0\r\n\t\t\tthis.#lifetimeStats.set(key, lifetime + (newValue - oldValue))\r\n\t\t} else if (stat.type === 'max') {\r\n\t\t\tconst lifetime = this.#lifetimeStats.get(key) ?? 0\r\n\t\t\tthis.#lifetimeStats.set(key, Math.max(lifetime, newValue))\r\n\t\t} else if (stat.type === 'min') {\r\n\t\t\tconst lifetime = this.#lifetimeStats.get(key) ?? Number.MAX_VALUE\r\n\t\t\tthis.#lifetimeStats.set(key, Math.min(lifetime, newValue))\r\n\t\t} else if (stat.type === 'average') {\r\n\t\t\tconst count = (this.#averageCounts.get(key) ?? 0) + 1\r\n\t\t\tthis.#averageCounts.set(key, count)\r\n\t\t\tconst oldAvg = this.#lifetimeStats.get(key) ?? 0\r\n\t\t\tconst newAvg = oldAvg + (newValue - oldAvg) / count\r\n\t\t\tthis.#lifetimeStats.set(key, newAvg)\r\n\t\t} else if (stat.type === 'timer') {\r\n\t\t\tconst lifetime = this.#lifetimeStats.get(key) ?? 0\r\n\t\t\tthis.#lifetimeStats.set(key, lifetime + newValue)\r\n\t\t}\r\n\r\n\t\t// Emit change event\r\n\t\tthis.#listeners.statChange.forEach(cb => cb(key, oldValue, newValue))\r\n\r\n\t\t// Check milestones\r\n\t\tthis.#checkMilestones(key, newValue)\r\n\t}\r\n\r\n\t#checkMilestones(key: string, value: number): void {\r\n\t\tfor (const milestone of this.#milestones) {\r\n\t\t\tif (milestone.statKey !== key) continue\r\n\t\t\tif (!milestone.repeatable && this.#reachedMilestones.has(milestone.id)) continue\r\n\r\n\t\t\tif (value >= milestone.threshold) {\r\n\t\t\t\tthis.#reachedMilestones.add(milestone.id)\r\n\t\t\t\tthis.#listeners.milestoneReached.forEach(cb => cb(milestone, value))\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// === SESSION MANAGEMENT ===\r\n\r\n\tstartSession(): void {\r\n\t\tif (this.#isInSession) return\r\n\r\n\t\tthis.#isInSession = true\r\n\t\tthis.#sessionStartTime = Date.now()\r\n\r\n\t\t// Reset session stats\r\n\t\tfor (const key of this.#sessionStats.keys()) {\r\n\t\t\tthis.#sessionStats.set(key, 0)\r\n\t\t}\r\n\r\n\t\tthis.#listeners.sessionStart.forEach(cb => cb())\r\n\t}\r\n\r\n\tendSession(): void {\r\n\t\tif (!this.#isInSession) return\r\n\r\n\t\tconst duration = this.getSessionDuration()\r\n\t\tthis.#isInSession = false\r\n\r\n\t\tthis.#listeners.sessionEnd.forEach(cb => cb(duration))\r\n\t}\r\n\r\n\t// === MILESTONES ===\r\n\r\n\tgetMilestones(): readonly MilestoneDef[] {\r\n\t\treturn this.#milestones\r\n\t}\r\n\r\n\tgetReachedMilestones(): readonly MilestoneDef[] {\r\n\t\treturn this.#milestones.filter(m => this.#reachedMilestones.has(m.id))\r\n\t}\r\n\r\n\thasMilestone(id: string): boolean {\r\n\t\treturn this.#reachedMilestones.has(id)\r\n\t}\r\n\r\n\t// === PERSISTENCE ===\r\n\r\n\tasync saveToStorage(): Promise<void> {\r\n\t\tconst data = {\r\n\t\t\tlifetimeStats: Object.fromEntries(this.#lifetimeStats),\r\n\t\t\treachedMilestones: Array.from(this.#reachedMilestones),\r\n\t\t\taverageCounts: Object.fromEntries(this.#averageCounts),\r\n\t\t}\r\n\r\n\t\ttry {\r\n\t\t\tlocalStorage.setItem(this.#storageKey, JSON.stringify(data))\r\n\t\t} catch {\r\n\t\t\t// Storage might be unavailable\r\n\t\t}\r\n\t}\r\n\r\n\tasync loadFromStorage(): Promise<void> {\r\n\t\ttry {\r\n\t\t\tconst raw = localStorage.getItem(this.#storageKey)\r\n\t\t\tif (!raw) return\r\n\r\n\t\t\tconst data = JSON.parse(raw) as {\r\n\t\t\t\tlifetimeStats: Record<string, number>\r\n\t\t\t\treachedMilestones: string[]\r\n\t\t\t\taverageCounts: Record<string, number>\r\n\t\t\t}\r\n\r\n\t\t\t// Restore lifetime stats\r\n\t\t\tfor (const [key, value] of Object.entries(data.lifetimeStats)) {\r\n\t\t\t\tthis.#lifetimeStats.set(key, value)\r\n\t\t\t}\r\n\r\n\t\t\t// Restore milestones\r\n\t\t\tfor (const id of data.reachedMilestones) {\r\n\t\t\t\tthis.#reachedMilestones.add(id)\r\n\t\t\t}\r\n\r\n\t\t\t// Restore average counts\r\n\t\t\tfor (const [key, value] of Object.entries(data.averageCounts)) {\r\n\t\t\t\tthis.#averageCounts.set(key, value)\r\n\t\t\t}\r\n\t\t} catch {\r\n\t\t\t// Invalid data\r\n\t\t}\r\n\t}\r\n\r\n\tasync clearStorage(): Promise<void> {\r\n\t\ttry {\r\n\t\t\tlocalStorage.removeItem(this.#storageKey)\r\n\t\t} catch {\r\n\t\t\t// Storage might be unavailable\r\n\t\t}\r\n\t}\r\n\r\n\t// === SUBSCRIPTIONS ===\r\n\r\n\tonStatChange(callback: (key: string, oldValue: number, newValue: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.statChange.add(callback)\r\n\t\treturn () => this.#listeners.statChange.delete(callback)\r\n\t}\r\n\r\n\tonMilestoneReached(callback: (milestone: MilestoneDef, value: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.milestoneReached.add(callback)\r\n\t\treturn () => this.#listeners.milestoneReached.delete(callback)\r\n\t}\r\n\r\n\tonSessionStart(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.sessionStart.add(callback)\r\n\t\treturn () => this.#listeners.sessionStart.delete(callback)\r\n\t}\r\n\r\n\tonSessionEnd(callback: (duration: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.sessionEnd.add(callback)\r\n\t\treturn () => this.#listeners.sessionEnd.delete(callback)\r\n\t}\r\n\r\n\t// === LIFECYCLE ===\r\n\r\n\treset(): void {\r\n\t\tthis.endSession()\r\n\r\n\t\tfor (const key of this.#sessionStats.keys()) {\r\n\t\t\tthis.#sessionStats.set(key, 0)\r\n\t\t}\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.reset()\r\n\t\tthis.#listeners.statChange.clear()\r\n\t\tthis.#listeners.milestoneReached.clear()\r\n\t\tthis.#listeners.sessionStart.clear()\r\n\t\tthis.#listeners.sessionEnd.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tObjectiveDef,\r\n\tObjectiveProgress,\r\n\tObjectiveStatus,\r\n\tObjectiveSystemInterface,\r\n\tObjectiveSystemOptions,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\n/**\r\n * ObjectiveSystem implementation for goals and progress tracking.\r\n */\r\nexport class ObjectiveSystem implements ObjectiveSystemInterface {\r\n\treadonly #objectives: Map<string, ObjectiveDef> = new Map()\r\n\treadonly #progress: Map<string, ObjectiveProgress> = new Map()\r\n\treadonly #failOnAnyFail: boolean\r\n\r\n\treadonly #listeners = {\r\n\t\tobjectiveStart: new Set<(objectiveId: string) => void>(),\r\n\t\tobjectiveProgress: new Set<(objectiveId: string, current: number, target: number) => void>(),\r\n\t\tobjectiveComplete: new Set<(objectiveId: string) => void>(),\r\n\t\tobjectiveFail: new Set<(objectiveId: string) => void>(),\r\n\t\tallObjectivesComplete: new Set<() => void>(),\r\n\t}\r\n\r\n\tconstructor(options?: ObjectiveSystemOptions) {\r\n\t\tthis.#failOnAnyFail = options?.failOnAnyFail ?? false\r\n\r\n\t\t// Register initial objectives\r\n\t\tif (options?.objectives) {\r\n\t\t\tfor (const objective of options.objectives) {\r\n\t\t\t\tthis.addObjective(objective)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (options?.onObjectiveStart) this.#listeners.objectiveStart.add(options.onObjectiveStart)\r\n\t\tif (options?.onObjectiveProgress) this.#listeners.objectiveProgress.add(options.onObjectiveProgress)\r\n\t\tif (options?.onObjectiveComplete) this.#listeners.objectiveComplete.add(options.onObjectiveComplete)\r\n\t\tif (options?.onObjectiveFail) this.#listeners.objectiveFail.add(options.onObjectiveFail)\r\n\t\tif (options?.onAllObjectivesComplete) this.#listeners.allObjectivesComplete.add(options.onAllObjectivesComplete)\r\n\t}\r\n\r\n\t// === ACCESSORS ===\r\n\r\n\tgetObjective(id: string): ObjectiveProgress | undefined {\r\n\t\treturn this.#progress.get(id)\r\n\t}\r\n\r\n\tgetAllObjectives(): readonly ObjectiveProgress[] {\r\n\t\treturn Array.from(this.#progress.values())\r\n\t}\r\n\r\n\tgetActiveObjectives(): readonly ObjectiveProgress[] {\r\n\t\treturn Array.from(this.#progress.values()).filter(p => p.status === 'active')\r\n\t}\r\n\r\n\tgetCompletedObjectives(): readonly ObjectiveProgress[] {\r\n\t\treturn Array.from(this.#progress.values()).filter(p => p.status === 'completed')\r\n\t}\r\n\r\n\t// === MUTATORS ===\r\n\r\n\taddObjective(def: ObjectiveDef): void {\r\n\t\tthis.#objectives.set(def.id, def)\r\n\r\n\t\tconst progress: ObjectiveProgress = {\r\n\t\t\tid: def.id,\r\n\t\t\tcurrent: 0,\r\n\t\t\ttarget: 1, // Default target, can be overridden\r\n\t\t\tstatus: 'locked' as ObjectiveStatus,\r\n\t\t}\r\n\r\n\t\tthis.#progress.set(def.id, progress)\r\n\t}\r\n\r\n\tremoveObjective(id: string): void {\r\n\t\tthis.#objectives.delete(id)\r\n\t\tthis.#progress.delete(id)\r\n\t}\r\n\r\n\tstartObjective(id: string): void {\r\n\t\tconst progress = this.#progress.get(id)\r\n\t\tif (!progress) return\r\n\r\n\t\tif (progress.status === 'locked') {\r\n\t\t\tthis.#updateProgress(id, { status: 'active' })\r\n\t\t\tthis.#listeners.objectiveStart.forEach(cb => cb(id))\r\n\t\t}\r\n\t}\r\n\r\n\tupdateProgress(id: string, current: number): void {\r\n\t\tconst progress = this.#progress.get(id)\r\n\t\tif (!progress || progress.status !== 'active') return\r\n\r\n\t\tconst oldCurrent = progress.current\r\n\t\tthis.#updateProgress(id, { current })\r\n\r\n\t\tif (current !== oldCurrent) {\r\n\t\t\tthis.#listeners.objectiveProgress.forEach(cb => cb(id, current, progress.target))\r\n\t\t}\r\n\r\n\t\t// Check for auto-complete\r\n\t\tif (current >= progress.target) {\r\n\t\t\tthis.completeObjective(id)\r\n\t\t}\r\n\t}\r\n\r\n\tincrementProgress(id: string, amount?: number): void {\r\n\t\tconst progress = this.#progress.get(id)\r\n\t\tif (!progress || progress.status !== 'active') return\r\n\r\n\t\tconst increment = amount ?? 1\r\n\t\tthis.updateProgress(id, progress.current + increment)\r\n\t}\r\n\r\n\tcompleteObjective(id: string): void {\r\n\t\tconst progress = this.#progress.get(id)\r\n\t\tif (!progress || progress.status === 'completed' || progress.status === 'failed') return\r\n\r\n\t\tthis.#updateProgress(id, {\r\n\t\t\tstatus: 'completed',\r\n\t\t\tcurrent: progress.target,\r\n\t\t\tcompletedAt: Date.now(),\r\n\t\t})\r\n\r\n\t\tthis.#listeners.objectiveComplete.forEach(cb => cb(id))\r\n\r\n\t\t// Check if all objectives complete\r\n\t\tif (this.isAllComplete()) {\r\n\t\t\tthis.#listeners.allObjectivesComplete.forEach(cb => cb())\r\n\t\t}\r\n\t}\r\n\r\n\tfailObjective(id: string): void {\r\n\t\tconst progress = this.#progress.get(id)\r\n\t\tif (!progress || progress.status === 'completed' || progress.status === 'failed') return\r\n\r\n\t\tthis.#updateProgress(id, { status: 'failed' })\r\n\t\tthis.#listeners.objectiveFail.forEach(cb => cb(id))\r\n\t}\r\n\r\n\t#updateProgress(id: string, update: Partial<ObjectiveProgress>): void {\r\n\t\tconst current = this.#progress.get(id)\r\n\t\tif (!current) return\r\n\r\n\t\tconst updated: ObjectiveProgress = {\r\n\t\t\tid: current.id,\r\n\t\t\tcurrent: update.current ?? current.current,\r\n\t\t\ttarget: update.target ?? current.target,\r\n\t\t\tstatus: update.status ?? current.status,\r\n\t\t}\r\n\r\n\t\t// Only add completedAt if it exists\r\n\t\tif (update.completedAt !== undefined) {\r\n\t\t\t(updated as { completedAt?: number }).completedAt = update.completedAt\r\n\t\t} else if (current.completedAt !== undefined) {\r\n\t\t\t(updated as { completedAt?: number }).completedAt = current.completedAt\r\n\t\t}\r\n\r\n\t\tthis.#progress.set(id, updated)\r\n\t}\r\n\r\n\t// === STATUS CHECKS ===\r\n\r\n\tisComplete(id: string): boolean {\r\n\t\treturn this.#progress.get(id)?.status === 'completed'\r\n\t}\r\n\r\n\tisFailed(id: string): boolean {\r\n\t\treturn this.#progress.get(id)?.status === 'failed'\r\n\t}\r\n\r\n\tisAllComplete(): boolean {\r\n\t\tfor (const progress of this.#progress.values()) {\r\n\t\t\tconst def = this.#objectives.get(progress.id)\r\n\t\t\tif (def?.optional) continue\r\n\r\n\t\t\tif (progress.status !== 'completed') {\r\n\t\t\t\treturn false\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn true\r\n\t}\r\n\r\n\tisAnyFailed(): boolean {\r\n\t\tfor (const progress of this.#progress.values()) {\r\n\t\t\tif (progress.status === 'failed') {\r\n\t\t\t\treturn true\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn false\r\n\t}\r\n\r\n\tgetCompletionPercent(): number {\r\n\t\tconst objectives = Array.from(this.#progress.values())\r\n\t\tconst required = objectives.filter(p => {\r\n\t\t\tconst def = this.#objectives.get(p.id)\r\n\t\t\treturn !def?.optional\r\n\t\t})\r\n\r\n\t\tif (required.length === 0) return 1\r\n\r\n\t\tconst completed = required.filter(p => p.status === 'completed').length\r\n\t\treturn completed / required.length\r\n\t}\r\n\r\n\t// === SUBSCRIPTIONS ===\r\n\r\n\tonObjectiveStart(callback: (objectiveId: string) => void): Unsubscribe {\r\n\t\tthis.#listeners.objectiveStart.add(callback)\r\n\t\treturn () => this.#listeners.objectiveStart.delete(callback)\r\n\t}\r\n\r\n\tonObjectiveProgress(callback: (objectiveId: string, current: number, target: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.objectiveProgress.add(callback)\r\n\t\treturn () => this.#listeners.objectiveProgress.delete(callback)\r\n\t}\r\n\r\n\tonObjectiveComplete(callback: (objectiveId: string) => void): Unsubscribe {\r\n\t\tthis.#listeners.objectiveComplete.add(callback)\r\n\t\treturn () => this.#listeners.objectiveComplete.delete(callback)\r\n\t}\r\n\r\n\tonObjectiveFail(callback: (objectiveId: string) => void): Unsubscribe {\r\n\t\tthis.#listeners.objectiveFail.add(callback)\r\n\t\treturn () => this.#listeners.objectiveFail.delete(callback)\r\n\t}\r\n\r\n\tonAllObjectivesComplete(callback: () => void): Unsubscribe {\r\n\t\tthis.#listeners.allObjectivesComplete.add(callback)\r\n\t\treturn () => this.#listeners.allObjectivesComplete.delete(callback)\r\n\t}\r\n\r\n\t// === LIFECYCLE ===\r\n\r\n\treset(): void {\r\n\t\t// Reset all progress\r\n\t\tfor (const id of this.#progress.keys()) {\r\n\t\t\tconst updated: ObjectiveProgress = {\r\n\t\t\t\tid,\r\n\t\t\t\tcurrent: 0,\r\n\t\t\t\ttarget: 1,\r\n\t\t\t\tstatus: 'locked',\r\n\t\t\t}\r\n\t\t\tthis.#progress.set(id, updated)\r\n\t\t}\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#objectives.clear()\r\n\t\tthis.#progress.clear()\r\n\t\tthis.#listeners.objectiveStart.clear()\r\n\t\tthis.#listeners.objectiveProgress.clear()\r\n\t\tthis.#listeners.objectiveComplete.clear()\r\n\t\tthis.#listeners.objectiveFail.clear()\r\n\t\tthis.#listeners.allObjectivesComplete.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tStateMachineInterface,\r\n\tStateMachineOptions,\r\n\tStateTransition,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\n/**\r\n * StateMachine implementation for game flow control.\r\n */\r\nexport class StateMachine<TState extends string> implements StateMachineInterface<TState> {\r\n\treadonly #transitions: readonly StateTransition<TState>[]\r\n\treadonly #states: readonly TState[]\r\n\r\n\t#currentState: TState\r\n\t#previousState: TState | undefined\r\n\t#history: TState[] = []\r\n\t#isTransitioning = false\r\n\r\n\treadonly #listeners = {\r\n\t\tstateChange: new Set<(from: TState, to: TState) => void>(),\r\n\t\ttransitionBlocked: new Set<(from: TState, to: TState) => void>(),\r\n\t}\r\n\r\n\treadonly #stateEnterListeners: Map<TState, Set<() => void>> = new Map()\r\n\treadonly #stateExitListeners: Map<TState, Set<() => void>> = new Map()\r\n\r\n\tconstructor(options: StateMachineOptions<TState>) {\r\n\t\tthis.#currentState = options.initialState\r\n\t\tthis.#transitions = options.transitions\r\n\t\tthis.#states = options.states ?? []\r\n\t\tthis.#history.push(options.initialState)\r\n\r\n\t\tif (options.onStateChange) this.#listeners.stateChange.add(options.onStateChange)\r\n\t\tif (options.onTransitionBlocked) this.#listeners.transitionBlocked.add(options.onTransitionBlocked)\r\n\t}\r\n\r\n\t// === ACCESSORS ===\r\n\r\n\tgetCurrentState(): TState {\r\n\t\treturn this.#currentState\r\n\t}\r\n\r\n\tgetPreviousState(): TState | undefined {\r\n\t\treturn this.#previousState\r\n\t}\r\n\r\n\tgetHistory(): readonly TState[] {\r\n\t\treturn [...this.#history]\r\n\t}\r\n\r\n\tcanTransitionTo(state: TState): boolean {\r\n\t\tif (this.#isTransitioning) return false\r\n\r\n\t\t// Find a valid transition\r\n\t\tconst transition = this.#findTransition(this.#currentState, state)\r\n\t\tif (!transition) return false\r\n\r\n\t\t// Check guard\r\n\t\tif (transition.guard && !transition.guard()) {\r\n\t\t\treturn false\r\n\t\t}\r\n\r\n\t\treturn true\r\n\t}\r\n\r\n\tisState(...states: readonly TState[]): boolean {\r\n\t\treturn states.includes(this.#currentState)\r\n\t}\r\n\r\n\t#findTransition(from: TState, to: TState): StateTransition<TState> | undefined {\r\n\t\treturn this.#transitions.find(t =>\r\n\t\t\t(t.from === from || t.from === '*') && t.to === to,\r\n\t\t)\r\n\t}\r\n\r\n\t// === MUTATORS ===\r\n\r\n\tasync transitionTo(state: TState): Promise<boolean> {\r\n\t\tif (this.#isTransitioning) return false\r\n\t\tif (state === this.#currentState) return true\r\n\r\n\t\tconst transition = this.#findTransition(this.#currentState, state)\r\n\t\tif (!transition) {\r\n\t\t\tthis.#listeners.transitionBlocked.forEach(cb => cb(this.#currentState, state))\r\n\t\t\treturn false\r\n\t\t}\r\n\r\n\t\t// Check guard\r\n\t\tif (transition.guard && !transition.guard()) {\r\n\t\t\tthis.#listeners.transitionBlocked.forEach(cb => cb(this.#currentState, state))\r\n\t\t\treturn false\r\n\t\t}\r\n\r\n\t\tawait this.#performTransition(state, transition)\r\n\t\treturn true\r\n\t}\r\n\r\n\tasync forceTransition(state: TState): Promise<void> {\r\n\t\tif (this.#isTransitioning) return\r\n\t\tif (state === this.#currentState) return\r\n\r\n\t\tconst transition = this.#findTransition(this.#currentState, state)\r\n\t\tawait this.#performTransition(state, transition ?? undefined)\r\n\t}\r\n\r\n\tasync #performTransition(to: TState, transition?: StateTransition<TState>): Promise<void> {\r\n\t\tthis.#isTransitioning = true\r\n\t\tconst from = this.#currentState\r\n\r\n\t\t// Exit callbacks\r\n\t\tconst exitListeners = this.#stateExitListeners.get(from)\r\n\t\tif (exitListeners) {\r\n\t\t\texitListeners.forEach(cb => cb())\r\n\t\t}\r\n\r\n\t\t// Update state\r\n\t\tthis.#previousState = from\r\n\t\tthis.#currentState = to\r\n\t\tthis.#history.push(to)\r\n\r\n\t\t// Transition callback\r\n\t\tif (transition?.onTransition) {\r\n\t\t\tawait transition.onTransition()\r\n\t\t}\r\n\r\n\t\t// Enter callbacks\r\n\t\tconst enterListeners = this.#stateEnterListeners.get(to)\r\n\t\tif (enterListeners) {\r\n\t\t\tenterListeners.forEach(cb => cb())\r\n\t\t}\r\n\r\n\t\t// State change callbacks\r\n\t\tthis.#listeners.stateChange.forEach(cb => cb(from, to))\r\n\r\n\t\tthis.#isTransitioning = false\r\n\t}\r\n\r\n\tasync goBack(): Promise<boolean> {\r\n\t\tif (this.#history.length < 2) return false\r\n\r\n\t\tconst previousState = this.#history[this.#history.length - 2]\r\n\t\tif (!previousState) return false\r\n\r\n\t\t// Pop current state\r\n\t\tthis.#history.pop()\r\n\t\t// Pop previous state (it will be re-added during transition)\r\n\t\tthis.#history.pop()\r\n\r\n\t\treturn this.transitionTo(previousState)\r\n\t}\r\n\r\n\t// === SUBSCRIPTIONS ===\r\n\r\n\tonStateChange(callback: (from: TState, to: TState) => void): Unsubscribe {\r\n\t\tthis.#listeners.stateChange.add(callback)\r\n\t\treturn () => this.#listeners.stateChange.delete(callback)\r\n\t}\r\n\r\n\tonStateEnter(state: TState, callback: () => void): Unsubscribe {\r\n\t\tif (!this.#stateEnterListeners.has(state)) {\r\n\t\t\tthis.#stateEnterListeners.set(state, new Set())\r\n\t\t}\r\n\t\tthis.#stateEnterListeners.get(state)?.add(callback)\r\n\r\n\t\treturn () => this.#stateEnterListeners.get(state)?.delete(callback)\r\n\t}\r\n\r\n\tonStateExit(state: TState, callback: () => void): Unsubscribe {\r\n\t\tif (!this.#stateExitListeners.has(state)) {\r\n\t\t\tthis.#stateExitListeners.set(state, new Set())\r\n\t\t}\r\n\t\tthis.#stateExitListeners.get(state)?.add(callback)\r\n\r\n\t\treturn () => this.#stateExitListeners.get(state)?.delete(callback)\r\n\t}\r\n\r\n\tonTransitionBlocked(callback: (from: TState, to: TState) => void): Unsubscribe {\r\n\t\tthis.#listeners.transitionBlocked.add(callback)\r\n\t\treturn () => this.#listeners.transitionBlocked.delete(callback)\r\n\t}\r\n\r\n\t// === LIFECYCLE ===\r\n\r\n\treset(): void {\r\n\t\tconst initial = this.#history[0]\r\n\t\tif (initial) {\r\n\t\t\tthis.#currentState = initial\r\n\t\t\tthis.#previousState = undefined\r\n\t\t\tthis.#history = [initial]\r\n\t\t}\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#listeners.stateChange.clear()\r\n\t\tthis.#listeners.transitionBlocked.clear()\r\n\t\tthis.#stateEnterListeners.clear()\r\n\t\tthis.#stateExitListeners.clear()\r\n\t\tthis.#history = []\r\n\t}\r\n}\r\n","import type {\n\tInventorySystemInterface,\n\tInventorySystemOptions,\n\tGameInventoryState,\n\tGameInventorySlot,\n\tGameEquipmentSlot,\n\tGameItem,\n\tGameItemStack,\n\tInventoryItemType,\n\tEquipmentSlotType,\n\tUnsubscribe,\n} from '../../types.js'\nimport {\n\tDEFAULT_INVENTORY_CAPACITY,\n\tDEFAULT_STARTING_GOLD,\n\tDEFAULT_EQUIPMENT_SLOTS,\n\tRARITY_ORDER,\n} from '../../constants.js'\n\n/**\n * Inventory system for managing items, equipment, and gold.\n *\n * @example\n * ```ts\n * const inventory = createInventorySystem({\n * capacity: 20,\n * startingGold: 100,\n * })\n *\n * const sword: GameItem = {\n * id: 'sword-1',\n * name: 'Iron Sword',\n * type: 'weapon',\n * rarity: 'common',\n * }\n *\n * inventory.addItem(sword, 1)\n * inventory.equip('sword-1', 'weapon')\n * ```\n */\nexport class InventorySystem implements InventorySystemInterface {\n\t#slots: GameInventorySlot[] = []\n\t#equipment: Map<EquipmentSlotType, GameEquipmentSlot> = new Map()\n\t#capacity: number\n\t#gold: number\n\t#items: Map<string, { item: GameItem; totalQuantity: number }> = new Map()\n\n\t#listeners = {\n\t\titemAdd: new Set<(item: GameItem, quantity: number, slotIndex: number) => void>(),\n\t\titemRemove: new Set<(item: GameItem, quantity: number, slotIndex: number) => void>(),\n\t\titemMove: new Set<(item: GameItem, fromSlot: number, toSlot: number) => void>(),\n\t\titemUse: new Set<(item: GameItem) => void>(),\n\t\tequip: new Set<(item: GameItem, slot: EquipmentSlotType) => void>(),\n\t\tunequip: new Set<(item: GameItem, slot: EquipmentSlotType) => void>(),\n\t\tgoldChange: new Set<(oldAmount: number, newAmount: number) => void>(),\n\t\tcapacityChange: new Set<(oldCapacity: number, newCapacity: number) => void>(),\n\t}\n\n\tconstructor(options?: InventorySystemOptions) {\n\t\tthis.#capacity = options?.capacity ?? DEFAULT_INVENTORY_CAPACITY\n\t\tthis.#gold = options?.startingGold ?? DEFAULT_STARTING_GOLD\n\n\t\t// Initialize slots\n\t\tfor (let i = 0; i < this.#capacity; i++) {\n\t\t\tthis.#slots.push({\n\t\t\t\tindex: i,\n\t\t\t\tstack: undefined,\n\t\t\t\tlocked: false,\n\t\t\t})\n\t\t}\n\n\t\t// Initialize equipment slots\n\t\tconst equipmentSlots = options?.equipmentSlots ?? DEFAULT_EQUIPMENT_SLOTS\n\t\tfor (const slotType of equipmentSlots) {\n\t\t\tthis.#equipment.set(slotType, {\n\t\t\t\ttype: slotType,\n\t\t\t\titem: undefined,\n\t\t\t\tallowedTypes: this.#getAllowedTypesForSlot(slotType),\n\t\t\t})\n\t\t}\n\n\t\t// Add starting items\n\t\tif (options?.startingItems) {\n\t\t\tfor (const { item, quantity } of options.startingItems) {\n\t\t\t\tthis.addItem(item, quantity)\n\t\t\t}\n\t\t}\n\n\t\t// Register hooks from options\n\t\tif (options?.onItemAdd) this.#listeners.itemAdd.add(options.onItemAdd)\n\t\tif (options?.onItemRemove) this.#listeners.itemRemove.add(options.onItemRemove)\n\t\tif (options?.onItemMove) this.#listeners.itemMove.add(options.onItemMove)\n\t\tif (options?.onItemUse) this.#listeners.itemUse.add(options.onItemUse)\n\t\tif (options?.onEquip) this.#listeners.equip.add(options.onEquip)\n\t\tif (options?.onUnequip) this.#listeners.unequip.add(options.onUnequip)\n\t\tif (options?.onGoldChange) this.#listeners.goldChange.add(options.onGoldChange)\n\t\tif (options?.onCapacityChange) this.#listeners.capacityChange.add(options.onCapacityChange)\n\t}\n\n\t// =========================================================================\n\t// Accessors\n\t// =========================================================================\n\n\tgetState(): GameInventoryState {\n\t\tconst equipment: Record<string, GameEquipmentSlot> = {}\n\t\tfor (const [type, slot] of this.#equipment) {\n\t\t\tequipment[type] = slot\n\t\t}\n\n\t\treturn {\n\t\t\tslots: [...this.#slots],\n\t\t\tequipment: equipment as Readonly<Record<EquipmentSlotType, GameEquipmentSlot>>,\n\t\t\tcapacity: this.#capacity,\n\t\t\tusedSlots: this.getUsedSlots(),\n\t\t\tgold: this.#gold,\n\t\t}\n\t}\n\n\tgetCapacity(): number {\n\t\treturn this.#capacity\n\t}\n\n\tgetUsedSlots(): number {\n\t\treturn this.#slots.filter(s => s.stack !== undefined).length\n\t}\n\n\tgetFreeSlots(): number {\n\t\treturn this.#slots.filter(s => s.stack === undefined && !s.locked).length\n\t}\n\n\tgetGold(): number {\n\t\treturn this.#gold\n\t}\n\n\tgetSlot(index: number): GameInventorySlot | undefined {\n\t\treturn this.#slots[index]\n\t}\n\n\tgetSlots(): readonly GameInventorySlot[] {\n\t\treturn this.#slots\n\t}\n\n\tgetItemsOfType(type: InventoryItemType): readonly GameItemStack[] {\n\t\tconst result: GameItemStack[] = []\n\t\tfor (const slot of this.#slots) {\n\t\t\tif (slot.stack?.item.type === type) {\n\t\t\t\tresult.push(slot.stack)\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n\n\tfindItem(itemId: string): GameItemStack | undefined {\n\t\tfor (const slot of this.#slots) {\n\t\t\tif (slot.stack?.item.id === itemId) {\n\t\t\t\treturn slot.stack\n\t\t\t}\n\t\t}\n\t\treturn undefined\n\t}\n\n\thasItem(itemId: string, quantity = 1): boolean {\n\t\treturn this.getItemQuantity(itemId) >= quantity\n\t}\n\n\tgetItemQuantity(itemId: string): number {\n\t\treturn this.#items.get(itemId)?.totalQuantity ?? 0\n\t}\n\n\tgetEquipment(slot: EquipmentSlotType): GameEquipmentSlot | undefined {\n\t\treturn this.#equipment.get(slot)\n\t}\n\n\tgetEquippedItem(slot: EquipmentSlotType): GameItem | undefined {\n\t\treturn this.#equipment.get(slot)?.item\n\t}\n\n\tisEquipped(itemId: string): boolean {\n\t\tfor (const slot of this.#equipment.values()) {\n\t\t\tif (slot.item?.id === itemId) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n\n\tcanAfford(amount: number): boolean {\n\t\treturn this.#gold >= amount\n\t}\n\n\t// =========================================================================\n\t// Item Management\n\t// =========================================================================\n\n\taddItem(item: GameItem, quantity = 1): boolean {\n\t\tif (quantity <= 0) return false\n\n\t\t// Try to stack with existing items\n\t\tif (item.stackable !== false) {\n\t\t\tfor (let i = 0; i < this.#slots.length; i++) {\n\t\t\t\tconst slot = this.#slots[i]\n\t\t\t\tif (!slot || slot.locked) continue\n\n\t\t\t\tif (slot.stack?.item.id === item.id) {\n\t\t\t\t\tconst maxStack = item.maxStack ?? 99\n\t\t\t\t\tconst canAdd = maxStack - slot.stack.quantity\n\t\t\t\t\tconst toAdd = Math.min(quantity, canAdd)\n\n\t\t\t\t\tif (toAdd > 0) {\n\t\t\t\t\t\tthis.#slots[i] = {\n\t\t\t\t\t\t\t...slot,\n\t\t\t\t\t\t\tstack: {\n\t\t\t\t\t\t\t\t...slot.stack,\n\t\t\t\t\t\t\t\tquantity: slot.stack.quantity + toAdd,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.#updateItemTotal(item.id, item, toAdd)\n\t\t\t\t\t\tthis.#emitItemAdd(item, toAdd, i)\n\t\t\t\t\t\tquantity -= toAdd\n\t\t\t\t\t}\n\n\t\t\t\t\tif (quantity === 0) return true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add to empty slots\n\t\twhile (quantity > 0) {\n\t\t\tconst freeSlotIndex = this.#slots.findIndex(s => s.stack === undefined && !s.locked)\n\t\t\tif (freeSlotIndex === -1) return false\n\n\t\t\tconst maxStack = item.stackable !== false ? (item.maxStack ?? 99) : 1\n\t\t\tconst toAdd = Math.min(quantity, maxStack)\n\n\t\t\tthis.#slots[freeSlotIndex] = {\n\t\t\t\t...this.#slots[freeSlotIndex]!,\n\t\t\t\tstack: {\n\t\t\t\t\titem,\n\t\t\t\t\tquantity: toAdd,\n\t\t\t\t\tslotIndex: freeSlotIndex,\n\t\t\t\t},\n\t\t\t}\n\n\t\t\tthis.#updateItemTotal(item.id, item, toAdd)\n\t\t\tthis.#emitItemAdd(item, toAdd, freeSlotIndex)\n\t\t\tquantity -= toAdd\n\t\t}\n\n\t\treturn true\n\t}\n\n\tremoveItem(itemId: string, quantity = 1): boolean {\n\t\tlet remaining = quantity\n\t\tconst itemData = this.#items.get(itemId)\n\t\tif (!itemData || itemData.totalQuantity < quantity) return false\n\n\t\tfor (let i = this.#slots.length - 1; i >= 0 && remaining > 0; i--) {\n\t\t\tconst slot = this.#slots[i]\n\t\t\tif (!slot || slot.stack?.item.id !== itemId) continue\n\n\t\t\tconst toRemove = Math.min(remaining, slot.stack.quantity)\n\t\t\tconst newQuantity = slot.stack.quantity - toRemove\n\n\t\t\tif (newQuantity === 0) {\n\t\t\t\tthis.#slots[i] = {\n\t\t\t\t\t...slot,\n\t\t\t\t\tstack: undefined,\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.#slots[i] = {\n\t\t\t\t\t...slot,\n\t\t\t\t\tstack: {\n\t\t\t\t\t\t...slot.stack,\n\t\t\t\t\t\tquantity: newQuantity,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.#updateItemTotal(itemId, slot.stack.item, -toRemove)\n\t\t\tthis.#emitItemRemove(slot.stack.item, toRemove, i)\n\t\t\tremaining -= toRemove\n\t\t}\n\n\t\treturn remaining === 0\n\t}\n\n\tmoveItem(fromSlot: number, toSlot: number): boolean {\n\t\tconst from = this.#slots[fromSlot]\n\t\tconst to = this.#slots[toSlot]\n\n\t\tif (!from?.stack || !to || to.locked) return false\n\n\t\t// If destination is empty, just move\n\t\tif (!to.stack) {\n\t\t\tthis.#slots[toSlot] = {\n\t\t\t\t...to,\n\t\t\t\tstack: { ...from.stack, slotIndex: toSlot },\n\t\t\t}\n\t\t\tthis.#slots[fromSlot] = {\n\t\t\t\t...from,\n\t\t\t\tstack: undefined,\n\t\t\t}\n\t\t\tthis.#emitItemMove(from.stack.item, fromSlot, toSlot)\n\t\t\treturn true\n\t\t}\n\n\t\t// If same item and stackable, try to merge\n\t\tif (to.stack.item.id === from.stack.item.id && from.stack.item.stackable !== false) {\n\t\t\tconst maxStack = from.stack.item.maxStack ?? 99\n\t\t\tconst canAdd = maxStack - to.stack.quantity\n\t\t\tconst toAdd = Math.min(from.stack.quantity, canAdd)\n\n\t\t\tif (toAdd > 0) {\n\t\t\t\tthis.#slots[toSlot] = {\n\t\t\t\t\t...to,\n\t\t\t\t\tstack: { ...to.stack, quantity: to.stack.quantity + toAdd },\n\t\t\t\t}\n\n\t\t\t\tif (toAdd === from.stack.quantity) {\n\t\t\t\t\tthis.#slots[fromSlot] = { ...from, stack: undefined }\n\t\t\t\t} else {\n\t\t\t\t\tthis.#slots[fromSlot] = {\n\t\t\t\t\t\t...from,\n\t\t\t\t\t\tstack: { ...from.stack, quantity: from.stack.quantity - toAdd },\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.#emitItemMove(from.stack.item, fromSlot, toSlot)\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\n\t\t// Otherwise swap\n\t\treturn this.swapItems(fromSlot, toSlot)\n\t}\n\n\tswapItems(slotA: number, slotB: number): boolean {\n\t\tconst a = this.#slots[slotA]\n\t\tconst b = this.#slots[slotB]\n\n\t\tif (!a || !b || a.locked || b.locked) return false\n\n\t\tconst stackA = a.stack\n\t\tconst stackB = b.stack\n\n\t\tthis.#slots[slotA] = {\n\t\t\t...a,\n\t\t\tstack: stackB ? { ...stackB, slotIndex: slotA } : undefined,\n\t\t}\n\t\tthis.#slots[slotB] = {\n\t\t\t...b,\n\t\t\tstack: stackA ? { ...stackA, slotIndex: slotB } : undefined,\n\t\t}\n\n\t\tif (stackA) this.#emitItemMove(stackA.item, slotA, slotB)\n\t\tif (stackB) this.#emitItemMove(stackB.item, slotB, slotA)\n\n\t\treturn true\n\t}\n\n\tuseItem(itemId: string): boolean {\n\t\tconst stack = this.findItem(itemId)\n\t\tif (!stack) return false\n\n\t\t// Emit use event\n\t\tfor (const callback of this.#listeners.itemUse) {\n\t\t\tcallback(stack.item)\n\t\t}\n\n\t\t// Remove one from stack (for consumables)\n\t\tif (stack.item.type === 'consumable') {\n\t\t\treturn this.removeItem(itemId, 1)\n\t\t}\n\n\t\treturn true\n\t}\n\n\tsplitStack(slotIndex: number, quantity: number): boolean {\n\t\tconst slot = this.#slots[slotIndex]\n\t\tif (!slot?.stack || slot.stack.quantity <= quantity) return false\n\n\t\tconst freeSlotIndex = this.#slots.findIndex(s => s.stack === undefined && !s.locked)\n\t\tif (freeSlotIndex === -1) return false\n\n\t\t// Split the stack\n\t\tthis.#slots[slotIndex] = {\n\t\t\t...slot,\n\t\t\tstack: { ...slot.stack, quantity: slot.stack.quantity - quantity },\n\t\t}\n\n\t\tthis.#slots[freeSlotIndex] = {\n\t\t\t...this.#slots[freeSlotIndex]!,\n\t\t\tstack: {\n\t\t\t\titem: slot.stack.item,\n\t\t\t\tquantity,\n\t\t\t\tslotIndex: freeSlotIndex,\n\t\t\t},\n\t\t}\n\n\t\treturn true\n\t}\n\n\t// =========================================================================\n\t// Equipment\n\t// =========================================================================\n\n\tequip(itemId: string, slot: EquipmentSlotType): boolean {\n\t\tconst stack = this.findItem(itemId)\n\t\tif (!stack) return false\n\n\t\tconst equipSlot = this.#equipment.get(slot)\n\t\tif (!equipSlot) return false\n\n\t\t// Check if item type is allowed\n\t\tif (!equipSlot.allowedTypes.includes(stack.item.type)) return false\n\n\t\t// Unequip current item if any\n\t\tif (equipSlot.item) {\n\t\t\tthis.unequip(slot)\n\t\t}\n\n\t\t// Remove from inventory\n\t\tthis.removeItem(itemId, 1)\n\n\t\t// Equip item\n\t\tthis.#equipment.set(slot, {\n\t\t\t...equipSlot,\n\t\t\titem: stack.item,\n\t\t})\n\n\t\tfor (const callback of this.#listeners.equip) {\n\t\t\tcallback(stack.item, slot)\n\t\t}\n\n\t\treturn true\n\t}\n\n\tunequip(slot: EquipmentSlotType): boolean {\n\t\tconst equipSlot = this.#equipment.get(slot)\n\t\tif (!equipSlot?.item) return false\n\n\t\t// Check if there's space in inventory\n\t\tif (this.getFreeSlots() === 0) return false\n\n\t\tconst item = equipSlot.item\n\n\t\t// Add back to inventory\n\t\tthis.addItem(item, 1)\n\n\t\t// Clear equipment slot\n\t\tthis.#equipment.set(slot, {\n\t\t\t...equipSlot,\n\t\t\titem: undefined,\n\t\t})\n\n\t\tfor (const callback of this.#listeners.unequip) {\n\t\t\tcallback(item, slot)\n\t\t}\n\n\t\treturn true\n\t}\n\n\t// =========================================================================\n\t// Gold Management\n\t// =========================================================================\n\n\taddGold(amount: number): void {\n\t\tif (amount <= 0) return\n\t\tconst oldAmount = this.#gold\n\t\tthis.#gold += amount\n\t\tthis.#emitGoldChange(oldAmount, this.#gold)\n\t}\n\n\tremoveGold(amount: number): boolean {\n\t\tif (!this.canAfford(amount)) return false\n\t\tconst oldAmount = this.#gold\n\t\tthis.#gold -= amount\n\t\tthis.#emitGoldChange(oldAmount, this.#gold)\n\t\treturn true\n\t}\n\n\tsetGold(amount: number): void {\n\t\tconst oldAmount = this.#gold\n\t\tthis.#gold = Math.max(0, amount)\n\t\tif (oldAmount !== this.#gold) {\n\t\t\tthis.#emitGoldChange(oldAmount, this.#gold)\n\t\t}\n\t}\n\n\t// =========================================================================\n\t// Slot Management\n\t// =========================================================================\n\n\tsetCapacity(capacity: number): void {\n\t\tif (capacity === this.#capacity) return\n\n\t\tconst oldCapacity = this.#capacity\n\t\tthis.#capacity = capacity\n\n\t\t// Add or remove slots\n\t\tif (capacity > oldCapacity) {\n\t\t\tfor (let i = oldCapacity; i < capacity; i++) {\n\t\t\t\tthis.#slots.push({ index: i, stack: undefined, locked: false })\n\t\t\t}\n\t\t} else {\n\t\t\t// Remove excess slots (items are lost)\n\t\t\tthis.#slots = this.#slots.slice(0, capacity)\n\t\t}\n\n\t\tfor (const callback of this.#listeners.capacityChange) {\n\t\t\tcallback(oldCapacity, capacity)\n\t\t}\n\t}\n\n\tlockSlot(index: number): void {\n\t\tconst slot = this.#slots[index]\n\t\tif (slot) {\n\t\t\tthis.#slots[index] = { ...slot, locked: true }\n\t\t}\n\t}\n\n\tunlockSlot(index: number): void {\n\t\tconst slot = this.#slots[index]\n\t\tif (slot) {\n\t\t\tthis.#slots[index] = { ...slot, locked: false }\n\t\t}\n\t}\n\n\tsortByType(): void {\n\t\tconst stacks = this.#slots\n\t\t\t.filter(s => s.stack !== undefined)\n\t\t\t.map(s => s.stack!)\n\t\t\t.sort((a, b) => a.item.type.localeCompare(b.item.type))\n\n\t\tthis.#rebuildSlots(stacks)\n\t}\n\n\tsortByRarity(): void {\n\t\tconst stacks = this.#slots\n\t\t\t.filter(s => s.stack !== undefined)\n\t\t\t.map(s => s.stack!)\n\t\t\t.sort((a, b) => {\n\t\t\t\tconst rarityA = RARITY_ORDER.indexOf(a.item.rarity ?? 'common')\n\t\t\t\tconst rarityB = RARITY_ORDER.indexOf(b.item.rarity ?? 'common')\n\t\t\t\treturn rarityB - rarityA // Higher rarity first\n\t\t\t})\n\n\t\tthis.#rebuildSlots(stacks)\n\t}\n\n\tsortByName(): void {\n\t\tconst stacks = this.#slots\n\t\t\t.filter(s => s.stack !== undefined)\n\t\t\t.map(s => s.stack!)\n\t\t\t.sort((a, b) => a.item.name.localeCompare(b.item.name))\n\n\t\tthis.#rebuildSlots(stacks)\n\t}\n\n\tclear(): void {\n\t\tthis.#slots = this.#slots.map(s => ({\n\t\t\t...s,\n\t\t\tstack: undefined,\n\t\t}))\n\t\tthis.#items.clear()\n\t}\n\n\t// =========================================================================\n\t// Event Subscriptions\n\t// =========================================================================\n\n\tonItemAdd(callback: (item: GameItem, quantity: number, slotIndex: number) => void): Unsubscribe {\n\t\tthis.#listeners.itemAdd.add(callback)\n\t\treturn () => this.#listeners.itemAdd.delete(callback)\n\t}\n\n\tonItemRemove(callback: (item: GameItem, quantity: number, slotIndex: number) => void): Unsubscribe {\n\t\tthis.#listeners.itemRemove.add(callback)\n\t\treturn () => this.#listeners.itemRemove.delete(callback)\n\t}\n\n\tonItemMove(callback: (item: GameItem, fromSlot: number, toSlot: number) => void): Unsubscribe {\n\t\tthis.#listeners.itemMove.add(callback)\n\t\treturn () => this.#listeners.itemMove.delete(callback)\n\t}\n\n\tonItemUse(callback: (item: GameItem) => void): Unsubscribe {\n\t\tthis.#listeners.itemUse.add(callback)\n\t\treturn () => this.#listeners.itemUse.delete(callback)\n\t}\n\n\tonEquip(callback: (item: GameItem, slot: EquipmentSlotType) => void): Unsubscribe {\n\t\tthis.#listeners.equip.add(callback)\n\t\treturn () => this.#listeners.equip.delete(callback)\n\t}\n\n\tonUnequip(callback: (item: GameItem, slot: EquipmentSlotType) => void): Unsubscribe {\n\t\tthis.#listeners.unequip.add(callback)\n\t\treturn () => this.#listeners.unequip.delete(callback)\n\t}\n\n\tonGoldChange(callback: (oldAmount: number, newAmount: number) => void): Unsubscribe {\n\t\tthis.#listeners.goldChange.add(callback)\n\t\treturn () => this.#listeners.goldChange.delete(callback)\n\t}\n\n\tonCapacityChange(callback: (oldCapacity: number, newCapacity: number) => void): Unsubscribe {\n\t\tthis.#listeners.capacityChange.add(callback)\n\t\treturn () => this.#listeners.capacityChange.delete(callback)\n\t}\n\n\t// =========================================================================\n\t// Lifecycle\n\t// =========================================================================\n\n\tdestroy(): void {\n\t\tthis.#slots = []\n\t\tthis.#equipment.clear()\n\t\tthis.#items.clear()\n\t\tthis.#listeners.itemAdd.clear()\n\t\tthis.#listeners.itemRemove.clear()\n\t\tthis.#listeners.itemMove.clear()\n\t\tthis.#listeners.itemUse.clear()\n\t\tthis.#listeners.equip.clear()\n\t\tthis.#listeners.unequip.clear()\n\t\tthis.#listeners.goldChange.clear()\n\t\tthis.#listeners.capacityChange.clear()\n\t}\n\n\t// =========================================================================\n\t// Private Methods\n\t// =========================================================================\n\n\t#getAllowedTypesForSlot(slot: EquipmentSlotType): readonly InventoryItemType[] {\n\t\tswitch (slot) {\n\t\t\tcase 'weapon':\n\t\t\tcase 'offhand':\n\t\t\t\treturn ['weapon']\n\t\t\tcase 'armor':\n\t\t\tcase 'helmet':\n\t\t\tcase 'boots':\n\t\t\t\treturn ['armor']\n\t\t\tcase 'accessory':\n\t\t\t\treturn ['misc'] // Accessories use misc type\n\t\t\tdefault:\n\t\t\t\treturn []\n\t\t}\n\t}\n\n\t#updateItemTotal(itemId: string, item: GameItem, delta: number): void {\n\t\tconst existing = this.#items.get(itemId)\n\t\tif (existing) {\n\t\t\tconst newTotal = existing.totalQuantity + delta\n\t\t\tif (newTotal <= 0) {\n\t\t\t\tthis.#items.delete(itemId)\n\t\t\t} else {\n\t\t\t\tthis.#items.set(itemId, { item, totalQuantity: newTotal })\n\t\t\t}\n\t\t} else if (delta > 0) {\n\t\t\tthis.#items.set(itemId, { item, totalQuantity: delta })\n\t\t}\n\t}\n\n\t#rebuildSlots(stacks: GameItemStack[]): void {\n\t\t// Clear all slots\n\t\tthis.#slots = this.#slots.map(s => ({\n\t\t\t...s,\n\t\t\tstack: undefined,\n\t\t}))\n\n\t\t// Re-add stacks in order\n\t\tlet slotIndex = 0\n\t\tfor (const stack of stacks) {\n\t\t\t// Skip locked slots\n\t\t\twhile (slotIndex < this.#slots.length && this.#slots[slotIndex]?.locked) {\n\t\t\t\tslotIndex++\n\t\t\t}\n\n\t\t\tif (slotIndex >= this.#slots.length) break\n\n\t\t\tthis.#slots[slotIndex] = {\n\t\t\t\t...this.#slots[slotIndex]!,\n\t\t\t\tstack: { ...stack, slotIndex },\n\t\t\t}\n\t\t\tslotIndex++\n\t\t}\n\t}\n\n\t#emitItemAdd(item: GameItem, quantity: number, slotIndex: number): void {\n\t\tfor (const callback of this.#listeners.itemAdd) {\n\t\t\tcallback(item, quantity, slotIndex)\n\t\t}\n\t}\n\n\t#emitItemRemove(item: GameItem, quantity: number, slotIndex: number): void {\n\t\tfor (const callback of this.#listeners.itemRemove) {\n\t\t\tcallback(item, quantity, slotIndex)\n\t\t}\n\t}\n\n\t#emitItemMove(item: GameItem, fromSlot: number, toSlot: number): void {\n\t\tfor (const callback of this.#listeners.itemMove) {\n\t\t\tcallback(item, fromSlot, toSlot)\n\t\t}\n\t}\n\n\t#emitGoldChange(oldAmount: number, newAmount: number): void {\n\t\tfor (const callback of this.#listeners.goldChange) {\n\t\t\tcallback(oldAmount, newAmount)\n\t\t}\n\t}\n}\n","import type {\n\tDialogueSystemInterface,\n\tDialogueSystemOptions,\n\tDialogueSystemState,\n\tDialogueTree,\n\tDialogueNode,\n\tDialogueChoice,\n\tDialogueCondition,\n\tDialogueAction,\n\tDialogueContext,\n\tUnsubscribe,\n} from '../../types.js'\nimport {\n\tDEFAULT_TYPEWRITER_SPEED,\n\tDEFAULT_AUTO_ADVANCE_DELAY,\n} from '../../constants.js'\n\n/**\n * Dialogue system for managing conversations and branching dialogue.\n *\n * @example\n * ```ts\n * const dialogue = createDialogueSystem({\n * typewriterSpeed: 50,\n * })\n *\n * const tree: DialogueTree = {\n * id: 'intro',\n * name: 'Introduction',\n * startNodeId: 'start',\n * nodes: {\n * start: {\n * id: 'start',\n * type: 'text',\n * speaker: 'NPC',\n * text: 'Hello, adventurer!',\n * nextNodeId: 'choice1',\n * },\n * },\n * }\n *\n * dialogue.loadTree(tree)\n * dialogue.start()\n * ```\n */\nexport class DialogueSystem implements DialogueSystemInterface {\n\t#trees: Map<string, DialogueTree> = new Map()\n\t#currentTree: DialogueTree | undefined\n\t#currentNode: DialogueNode | undefined\n\t#context: DialogueContext = { variables: {}, flags: new Set() }\n\t#history: string[] = []\n\n\t#isActive = false\n\t#isTyping = false\n\t#displayedText = ''\n\t#fullText = ''\n\t#typingProgress = 0\n\n\t#typewriterSpeed: number\n\t#autoAdvanceDelay: number\n\t#skipTypingOnInput: boolean\n\n\t#listeners = {\n\t\tstart: new Set<(tree: DialogueTree) => void>(),\n\t\tend: new Set<(tree: DialogueTree) => void>(),\n\t\tnodeEnter: new Set<(node: DialogueNode) => void>(),\n\t\tnodeExit: new Set<(node: DialogueNode) => void>(),\n\t\tchoice: new Set<(choice: DialogueChoice, node: DialogueNode) => void>(),\n\t\taction: new Set<(action: DialogueAction) => void>(),\n\t\ttypingComplete: new Set<(text: string) => void>(),\n\t\tvariableChange: new Set<(variable: string, oldValue: unknown, newValue: unknown) => void>(),\n\t}\n\n\tconstructor(options?: DialogueSystemOptions) {\n\t\tthis.#typewriterSpeed = options?.typewriterSpeed ?? DEFAULT_TYPEWRITER_SPEED\n\t\tthis.#autoAdvanceDelay = options?.autoAdvanceDelay ?? DEFAULT_AUTO_ADVANCE_DELAY\n\t\tthis.#skipTypingOnInput = options?.skipTypingOnInput ?? true\n\n\t\t// Initialize context with initial variables\n\t\tif (options?.initialVariables) {\n\t\t\tthis.#context = {\n\t\t\t\tvariables: { ...options.initialVariables },\n\t\t\t\tflags: new Set(),\n\t\t\t}\n\t\t}\n\n\t\t// Register hooks from options\n\t\tif (options?.onStart) this.#listeners.start.add(options.onStart)\n\t\tif (options?.onEnd) this.#listeners.end.add(options.onEnd)\n\t\tif (options?.onNodeEnter) this.#listeners.nodeEnter.add(options.onNodeEnter)\n\t\tif (options?.onNodeExit) this.#listeners.nodeExit.add(options.onNodeExit)\n\t\tif (options?.onChoice) this.#listeners.choice.add(options.onChoice)\n\t\tif (options?.onAction) this.#listeners.action.add(options.onAction)\n\t\tif (options?.onTypingComplete) this.#listeners.typingComplete.add(options.onTypingComplete)\n\t\tif (options?.onVariableChange) this.#listeners.variableChange.add(options.onVariableChange)\n\t}\n\n\t// =========================================================================\n\t// Accessors\n\t// =========================================================================\n\n\tgetState(): DialogueSystemState {\n\t\treturn {\n\t\t\tisActive: this.#isActive,\n\t\t\tcurrentTree: this.#currentTree,\n\t\t\tcurrentNode: this.#currentNode,\n\t\t\tavailableChoices: this.getAvailableChoices(),\n\t\t\tcontext: this.#context,\n\t\t\thistory: [...this.#history],\n\t\t\tisTyping: this.#isTyping,\n\t\t\tdisplayedText: this.#displayedText,\n\t\t}\n\t}\n\n\tisActive(): boolean {\n\t\treturn this.#isActive\n\t}\n\n\tgetCurrentNode(): DialogueNode | undefined {\n\t\treturn this.#currentNode\n\t}\n\n\tgetAvailableChoices(): readonly DialogueChoice[] {\n\t\tif (!this.#currentNode?.choices) return []\n\n\t\treturn this.#currentNode.choices.filter(choice => {\n\t\t\t// Filter hidden choices\n\t\t\tif (choice.hidden) return false\n\n\t\t\t// Check conditions\n\t\t\tif (choice.conditions) {\n\t\t\t\tfor (const condition of choice.conditions) {\n\t\t\t\t\tif (!this.evaluateCondition(condition)) {\n\t\t\t\t\t\treturn false\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true\n\t\t})\n\t}\n\n\tgetDisplayedText(): string {\n\t\treturn this.#displayedText\n\t}\n\n\tisTyping(): boolean {\n\t\treturn this.#isTyping\n\t}\n\n\tgetVariable(name: string): unknown {\n\t\treturn this.#context.variables[name]\n\t}\n\n\thasFlag(flag: string): boolean {\n\t\treturn this.#context.flags.has(flag)\n\t}\n\n\tgetHistory(): readonly string[] {\n\t\treturn this.#history\n\t}\n\n\t// =========================================================================\n\t// Tree Management\n\t// =========================================================================\n\n\tloadTree(tree: DialogueTree): void {\n\t\tthis.#trees.set(tree.id, tree)\n\n\t\t// Merge tree variables into context\n\t\tif (tree.variables) {\n\t\t\tthis.#context = {\n\t\t\t\tvariables: { ...this.#context.variables, ...tree.variables },\n\t\t\t\tflags: this.#context.flags,\n\t\t\t}\n\t\t}\n\t}\n\n\tunloadTree(): void {\n\t\tthis.end()\n\t\tthis.#currentTree = undefined\n\t}\n\n\tstart(treeId?: string, startNodeId?: string): void {\n\t\tconst tree = treeId ? this.#trees.get(treeId) : this.#currentTree ?? this.#trees.values().next().value\n\n\t\tif (!tree) return\n\n\t\tthis.#currentTree = tree\n\t\tthis.#isActive = true\n\t\tthis.#history = []\n\n\t\t// Emit start event\n\t\tfor (const callback of this.#listeners.start) {\n\t\t\tcallback(tree)\n\t\t}\n\n\t\t// Go to start node\n\t\tconst nodeId = startNodeId ?? tree.startNodeId\n\t\tthis.goToNode(nodeId)\n\t}\n\n\tend(): void {\n\t\tif (!this.#isActive || !this.#currentTree) return\n\n\t\tconst tree = this.#currentTree\n\n\t\t// Exit current node\n\t\tif (this.#currentNode) {\n\t\t\tfor (const callback of this.#listeners.nodeExit) {\n\t\t\t\tcallback(this.#currentNode)\n\t\t\t}\n\t\t}\n\n\t\tthis.#isActive = false\n\t\tthis.#currentNode = undefined\n\t\tthis.#isTyping = false\n\t\tthis.#displayedText = ''\n\n\t\t// Emit end event\n\t\tfor (const callback of this.#listeners.end) {\n\t\t\tcallback(tree)\n\t\t}\n\t}\n\n\t// =========================================================================\n\t// Navigation\n\t// =========================================================================\n\n\tadvance(): void {\n\t\tif (!this.#isActive || !this.#currentNode) return\n\n\t\t// If still typing, skip to end\n\t\tif (this.#isTyping && this.#skipTypingOnInput) {\n\t\t\tthis.skipTyping()\n\t\t\treturn\n\t\t}\n\n\t\t// If current node has choices, don't auto-advance\n\t\tif (this.#currentNode.type === 'choice' && this.#currentNode.choices?.length) {\n\t\t\treturn\n\t\t}\n\n\t\t// Check for next node\n\t\tif (this.#currentNode.nextNodeId) {\n\t\t\tthis.goToNode(this.#currentNode.nextNodeId)\n\t\t} else if (this.#currentNode.type === 'end') {\n\t\t\tthis.end()\n\t\t}\n\t}\n\n\tselectChoice(choiceIndex: number): void {\n\t\tif (!this.#isActive || !this.#currentNode) return\n\n\t\tconst choices = this.getAvailableChoices()\n\t\tconst choice = choices[choiceIndex]\n\n\t\tif (!choice || choice.disabled) return\n\n\t\t// Execute choice actions\n\t\tif (choice.actions) {\n\t\t\tfor (const action of choice.actions) {\n\t\t\t\tthis.#executeAction(action)\n\t\t\t}\n\t\t}\n\n\t\t// Emit choice event\n\t\tfor (const callback of this.#listeners.choice) {\n\t\t\tcallback(choice, this.#currentNode)\n\t\t}\n\n\t\t// Navigate to next node\n\t\tthis.goToNode(choice.nextNodeId)\n\t}\n\n\tskipTyping(): void {\n\t\tif (!this.#isTyping) return\n\n\t\tthis.#displayedText = this.#fullText\n\t\tthis.#isTyping = false\n\t\tthis.#typingProgress = this.#fullText.length\n\n\t\tfor (const callback of this.#listeners.typingComplete) {\n\t\t\tcallback(this.#fullText)\n\t\t}\n\t}\n\n\tgoToNode(nodeId: string): void {\n\t\tif (!this.#currentTree) return\n\n\t\tconst node = this.#currentTree.nodes[nodeId]\n\t\tif (!node) return\n\n\t\t// Exit current node\n\t\tif (this.#currentNode) {\n\t\t\tfor (const callback of this.#listeners.nodeExit) {\n\t\t\t\tcallback(this.#currentNode)\n\t\t\t}\n\t\t}\n\n\t\t// Enter new node\n\t\tthis.#currentNode = node\n\t\tthis.#history.push(nodeId)\n\n\t\t// Check node conditions\n\t\tif (node.conditions) {\n\t\t\tfor (const condition of node.conditions) {\n\t\t\t\tif (!this.evaluateCondition(condition)) {\n\t\t\t\t\t// Skip to next node if conditions not met\n\t\t\t\t\tif (node.nextNodeId) {\n\t\t\t\t\t\tthis.goToNode(node.nextNodeId)\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Execute node actions\n\t\tif (node.actions) {\n\t\t\tfor (const action of node.actions) {\n\t\t\t\tthis.#executeAction(action)\n\t\t\t}\n\t\t}\n\n\t\t// Handle node types\n\t\tswitch (node.type) {\n\t\t\tcase 'text':\n\t\t\tcase 'choice':\n\t\t\t\tthis.#startTyping(this.#substituteVariables(node.text ?? ''))\n\t\t\t\tbreak\n\n\t\t\tcase 'action':\n\t\t\t\t// Action node: execute and auto-advance\n\t\t\t\tif (node.nextNodeId) {\n\t\t\t\t\tthis.goToNode(node.nextNodeId)\n\t\t\t\t}\n\t\t\t\treturn\n\n\t\t\tcase 'branch':\n\t\t\t\t// Branch node: evaluate conditions and jump\n\t\t\t\tif (node.nextNodeId) {\n\t\t\t\t\tthis.goToNode(node.nextNodeId)\n\t\t\t\t}\n\t\t\t\treturn\n\n\t\t\tcase 'end':\n\t\t\t\tthis.end()\n\t\t\t\treturn\n\t\t}\n\n\t\t// Emit node enter event\n\t\tfor (const callback of this.#listeners.nodeEnter) {\n\t\t\tcallback(node)\n\t\t}\n\t}\n\n\t// =========================================================================\n\t// Variables and Flags\n\t// =========================================================================\n\n\tsetVariable(name: string, value: unknown): void {\n\t\tconst oldValue = this.#context.variables[name]\n\n\t\tthis.#context = {\n\t\t\tvariables: { ...this.#context.variables, [name]: value },\n\t\t\tflags: this.#context.flags,\n\t\t}\n\n\t\tfor (const callback of this.#listeners.variableChange) {\n\t\t\tcallback(name, oldValue, value)\n\t\t}\n\t}\n\n\tsetFlag(flag: string): void {\n\t\tconst newFlags = new Set(this.#context.flags)\n\t\tnewFlags.add(flag)\n\t\tthis.#context = {\n\t\t\tvariables: this.#context.variables,\n\t\t\tflags: newFlags,\n\t\t}\n\t}\n\n\tclearFlag(flag: string): void {\n\t\tconst newFlags = new Set(this.#context.flags)\n\t\tnewFlags.delete(flag)\n\t\tthis.#context = {\n\t\t\tvariables: this.#context.variables,\n\t\t\tflags: newFlags,\n\t\t}\n\t}\n\n\tevaluateCondition(condition: DialogueCondition): boolean {\n\t\tconst value = this.#context.variables[condition.variable]\n\t\tconst expected = condition.value\n\n\t\tswitch (condition.operator) {\n\t\t\tcase '==':\n\t\t\t\treturn value === expected\n\t\t\tcase '!=':\n\t\t\t\treturn value !== expected\n\t\t\tcase '>':\n\t\t\t\treturn typeof value === 'number' && typeof expected === 'number' && value > expected\n\t\t\tcase '<':\n\t\t\t\treturn typeof value === 'number' && typeof expected === 'number' && value < expected\n\t\t\tcase '>=':\n\t\t\t\treturn typeof value === 'number' && typeof expected === 'number' && value >= expected\n\t\t\tcase '<=':\n\t\t\t\treturn typeof value === 'number' && typeof expected === 'number' && value <= expected\n\t\t\tdefault:\n\t\t\t\treturn false\n\t\t}\n\t}\n\n\tclearHistory(): void {\n\t\tthis.#history = []\n\t}\n\n\t// =========================================================================\n\t// Event Subscriptions\n\t// =========================================================================\n\n\tonStart(callback: (tree: DialogueTree) => void): Unsubscribe {\n\t\tthis.#listeners.start.add(callback)\n\t\treturn () => this.#listeners.start.delete(callback)\n\t}\n\n\tonEnd(callback: (tree: DialogueTree) => void): Unsubscribe {\n\t\tthis.#listeners.end.add(callback)\n\t\treturn () => this.#listeners.end.delete(callback)\n\t}\n\n\tonNodeEnter(callback: (node: DialogueNode) => void): Unsubscribe {\n\t\tthis.#listeners.nodeEnter.add(callback)\n\t\treturn () => this.#listeners.nodeEnter.delete(callback)\n\t}\n\n\tonNodeExit(callback: (node: DialogueNode) => void): Unsubscribe {\n\t\tthis.#listeners.nodeExit.add(callback)\n\t\treturn () => this.#listeners.nodeExit.delete(callback)\n\t}\n\n\tonChoice(callback: (choice: DialogueChoice, node: DialogueNode) => void): Unsubscribe {\n\t\tthis.#listeners.choice.add(callback)\n\t\treturn () => this.#listeners.choice.delete(callback)\n\t}\n\n\tonAction(callback: (action: DialogueAction) => void): Unsubscribe {\n\t\tthis.#listeners.action.add(callback)\n\t\treturn () => this.#listeners.action.delete(callback)\n\t}\n\n\tonTypingComplete(callback: (text: string) => void): Unsubscribe {\n\t\tthis.#listeners.typingComplete.add(callback)\n\t\treturn () => this.#listeners.typingComplete.delete(callback)\n\t}\n\n\tonVariableChange(callback: (variable: string, oldValue: unknown, newValue: unknown) => void): Unsubscribe {\n\t\tthis.#listeners.variableChange.add(callback)\n\t\treturn () => this.#listeners.variableChange.delete(callback)\n\t}\n\n\t// =========================================================================\n\t// Lifecycle\n\t// =========================================================================\n\n\tupdate(deltaTime: number): void {\n\t\tif (!this.#isTyping) return\n\n\t\t// Update typewriter effect\n\t\tthis.#typingProgress += deltaTime * this.#typewriterSpeed / 1000\n\n\t\tconst targetLength = Math.floor(this.#typingProgress)\n\t\tif (targetLength >= this.#fullText.length) {\n\t\t\tthis.skipTyping()\n\t\t} else {\n\t\t\tthis.#displayedText = this.#fullText.slice(0, targetLength)\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.end()\n\t\tthis.#trees.clear()\n\t\tthis.#context = { variables: {}, flags: new Set() }\n\t\tthis.#history = []\n\t\tthis.#listeners.start.clear()\n\t\tthis.#listeners.end.clear()\n\t\tthis.#listeners.nodeEnter.clear()\n\t\tthis.#listeners.nodeExit.clear()\n\t\tthis.#listeners.choice.clear()\n\t\tthis.#listeners.action.clear()\n\t\tthis.#listeners.typingComplete.clear()\n\t\tthis.#listeners.variableChange.clear()\n\t}\n\n\t// =========================================================================\n\t// Private Methods\n\t// =========================================================================\n\n\t#startTyping(text: string): void {\n\t\tthis.#fullText = text\n\t\tthis.#displayedText = ''\n\t\tthis.#typingProgress = 0\n\t\tthis.#isTyping = true\n\t}\n\n\t#substituteVariables(text: string): string {\n\t\treturn text.replace(/\\{(\\w+)\\}/g, (_, name) => {\n\t\t\tconst value = this.#context.variables[name]\n\t\t\treturn value !== undefined ? String(value) : `{${name}}`\n\t\t})\n\t}\n\n\t#executeAction(action: DialogueAction): void {\n\t\tswitch (action.type) {\n\t\t\tcase 'set':\n\t\t\t\tthis.setVariable(action.target, action.value)\n\t\t\t\tbreak\n\t\t\tcase 'add':\n\t\t\t\tconst current = this.getVariable(action.target)\n\t\t\t\tif (typeof current === 'number' && typeof action.value === 'number') {\n\t\t\t\t\tthis.setVariable(action.target, current + action.value)\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\tcase 'remove':\n\t\t\t\tthis.setVariable(action.target, undefined)\n\t\t\t\tbreak\n\t\t\tcase 'trigger':\n\t\t\t\tthis.setFlag(action.target)\n\t\t\t\tbreak\n\t\t}\n\n\t\tfor (const callback of this.#listeners.action) {\n\t\t\tcallback(action)\n\t\t}\n\t}\n}\n","import type {\n\tQuestSystemInterface,\n\tQuestSystemOptions,\n\tQuestLogState,\n\tQuest,\n\tQuestInstance,\n\tQuestObjective,\n\tQuestReward,\n\tQuestPrerequisite,\n\tUnsubscribe,\n} from '../../types.js'\nimport { DEFAULT_MAX_ACTIVE_QUESTS } from '../../constants.js'\n\n/**\n * Quest system for managing quests, objectives, and rewards.\n *\n * @example\n * ```ts\n * const quests = createQuestSystem({\n * quests: [\n * {\n * id: 'collect-herbs',\n * name: 'Collect Herbs',\n * description: 'Collect 10 healing herbs.',\n * objectives: [{ id: 'herbs', description: 'Collect herbs', target: 10, current: 0, completed: false }],\n * rewards: [{ type: 'xp', amount: 100 }],\n * },\n * ],\n * })\n *\n * quests.start('collect-herbs')\n * quests.incrementObjective('collect-herbs', 'herbs', 1)\n * ```\n */\nexport class QuestSystem implements QuestSystemInterface {\n\t#quests: Map<string, Quest> = new Map()\n\t#instances: Map<string, QuestInstance> = new Map()\n\t#completedQuests: Set<string> = new Set()\n\t#failedQuests: Set<string> = new Set()\n\n\t#autoTrackActive: boolean\n\t#maxActiveQuests: number\n\n\t#listeners = {\n\t\tquestAvailable: new Set<(quest: Quest) => void>(),\n\t\tquestStart: new Set<(quest: Quest) => void>(),\n\t\tquestComplete: new Set<(quest: Quest, rewards: readonly QuestReward[]) => void>(),\n\t\tquestFail: new Set<(quest: Quest) => void>(),\n\t\tquestAbandon: new Set<(quest: Quest) => void>(),\n\t\tobjectiveProgress: new Set<(quest: Quest, objective: QuestObjective, current: number, target: number) => void>(),\n\t\tobjectiveComplete: new Set<(quest: Quest, objective: QuestObjective) => void>(),\n\t}\n\n\tconstructor(options?: QuestSystemOptions) {\n\t\tthis.#autoTrackActive = options?.autoTrackActive ?? true\n\t\tthis.#maxActiveQuests = options?.maxActiveQuests ?? DEFAULT_MAX_ACTIVE_QUESTS\n\n\t\t// Register initial quests\n\t\tif (options?.quests) {\n\t\t\tfor (const quest of options.quests) {\n\t\t\t\tthis.registerQuest(quest)\n\t\t\t}\n\t\t}\n\n\t\t// Register hooks from options\n\t\tif (options?.onQuestAvailable) this.#listeners.questAvailable.add(options.onQuestAvailable)\n\t\tif (options?.onQuestStart) this.#listeners.questStart.add(options.onQuestStart)\n\t\tif (options?.onQuestComplete) this.#listeners.questComplete.add(options.onQuestComplete)\n\t\tif (options?.onQuestFail) this.#listeners.questFail.add(options.onQuestFail)\n\t\tif (options?.onQuestAbandon) this.#listeners.questAbandon.add(options.onQuestAbandon)\n\t\tif (options?.onObjectiveProgress) this.#listeners.objectiveProgress.add(options.onObjectiveProgress)\n\t\tif (options?.onObjectiveComplete) this.#listeners.objectiveComplete.add(options.onObjectiveComplete)\n\t}\n\n\t// =========================================================================\n\t// Accessors\n\t// =========================================================================\n\n\tgetState(): QuestLogState {\n\t\treturn {\n\t\t\tactiveQuests: this.getActiveQuests(),\n\t\t\tcompletedQuests: [...this.#completedQuests],\n\t\t\tfailedQuests: [...this.#failedQuests],\n\t\t\tavailableQuests: this.getAvailableQuests().map(q => q.id),\n\t\t}\n\t}\n\n\tgetQuest(questId: string): Quest | undefined {\n\t\treturn this.#quests.get(questId)\n\t}\n\n\tgetQuestInstance(questId: string): QuestInstance | undefined {\n\t\treturn this.#instances.get(questId)\n\t}\n\n\tgetAllQuests(): readonly Quest[] {\n\t\treturn Array.from(this.#quests.values())\n\t}\n\n\tgetActiveQuests(): readonly QuestInstance[] {\n\t\treturn Array.from(this.#instances.values())\n\t\t\t.filter(i => i.state === 'active')\n\t}\n\n\tgetCompletedQuests(): readonly string[] {\n\t\treturn [...this.#completedQuests]\n\t}\n\n\tgetAvailableQuests(): readonly Quest[] {\n\t\treturn Array.from(this.#quests.values())\n\t\t\t.filter(q => this.isQuestAvailable(q.id))\n\t}\n\n\tisQuestActive(questId: string): boolean {\n\t\tconst instance = this.#instances.get(questId)\n\t\treturn instance?.state === 'active'\n\t}\n\n\tisQuestCompleted(questId: string): boolean {\n\t\treturn this.#completedQuests.has(questId)\n\t}\n\n\tisQuestFailed(questId: string): boolean {\n\t\treturn this.#failedQuests.has(questId)\n\t}\n\n\tisQuestAvailable(questId: string): boolean {\n\t\t// Already active, completed, or failed\n\t\tif (this.isQuestActive(questId)) return false\n\t\tif (this.isQuestCompleted(questId)) {\n\t\t\tconst quest = this.#quests.get(questId)\n\t\t\tif (!quest?.isRepeatable) return false\n\t\t}\n\n\t\treturn this.checkPrerequisites(questId)\n\t}\n\n\tisObjectiveComplete(questId: string, objectiveId: string): boolean {\n\t\tconst instance = this.#instances.get(questId)\n\t\tif (!instance) return false\n\n\t\tconst objective = instance.objectives.find(o => o.id === objectiveId)\n\t\treturn objective?.completed ?? false\n\t}\n\n\tgetQuestProgress(questId: string): number {\n\t\tconst instance = this.#instances.get(questId)\n\t\tif (!instance) return 0\n\n\t\tconst requiredObjectives = instance.objectives.filter(o => !o.optional)\n\t\tif (requiredObjectives.length === 0) return 1\n\n\t\tconst completedCount = requiredObjectives.filter(o => o.completed).length\n\t\treturn completedCount / requiredObjectives.length\n\t}\n\n\tcheckPrerequisites(questId: string): boolean {\n\t\tconst quest = this.#quests.get(questId)\n\t\tif (!quest?.prerequisites) return true\n\n\t\tfor (const prereq of quest.prerequisites) {\n\t\t\tif (!this.#checkPrerequisite(prereq)) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\n\t\treturn true\n\t}\n\n\t// =========================================================================\n\t// Quest Management\n\t// =========================================================================\n\n\tregisterQuest(quest: Quest): void {\n\t\tthis.#quests.set(quest.id, quest)\n\n\t\t// Check if quest becomes available\n\t\tif (this.checkPrerequisites(quest.id)) {\n\t\t\tfor (const callback of this.#listeners.questAvailable) {\n\t\t\t\tcallback(quest)\n\t\t\t}\n\t\t}\n\t}\n\n\tunregisterQuest(questId: string): void {\n\t\tthis.#quests.delete(questId)\n\t\tthis.#instances.delete(questId)\n\t}\n\n\tcanStart(questId: string): boolean {\n\t\tif (!this.isQuestAvailable(questId)) return false\n\t\tif (this.getActiveQuests().length >= this.#maxActiveQuests) return false\n\t\treturn true\n\t}\n\n\tstart(questId: string): boolean {\n\t\tif (!this.canStart(questId)) return false\n\n\t\tconst quest = this.#quests.get(questId)\n\t\tif (!quest) return false\n\n\t\t// Create instance with reset objectives\n\t\tconst instance: QuestInstance = {\n\t\t\tid: `${questId}-${Date.now()}`,\n\t\t\tquestId,\n\t\t\tstate: 'active',\n\t\t\tobjectives: quest.objectives.map(o => ({ ...o, current: 0, completed: false })),\n\t\t\tstartedAt: Date.now(),\n\t\t}\n\n\t\tthis.#instances.set(questId, instance)\n\n\t\t// If repeatable and was completed, remove from completed\n\t\tif (quest.isRepeatable) {\n\t\t\tthis.#completedQuests.delete(questId)\n\t\t}\n\n\t\tfor (const callback of this.#listeners.questStart) {\n\t\t\tcallback(quest)\n\t\t}\n\n\t\treturn true\n\t}\n\n\tcomplete(questId: string): boolean {\n\t\tconst instance = this.#instances.get(questId)\n\t\tconst quest = this.#quests.get(questId)\n\n\t\tif (!instance || !quest || instance.state !== 'active') return false\n\n\t\t// Check all required objectives are complete\n\t\tconst requiredObjectives = instance.objectives.filter(o => !o.optional)\n\t\tconst allComplete = requiredObjectives.every(o => o.completed)\n\n\t\tif (!allComplete) return false\n\n\t\t// Update instance\n\t\tconst completedInstance: QuestInstance = {\n\t\t\t...instance,\n\t\t\tstate: 'completed',\n\t\t\tcompletedAt: Date.now(),\n\t\t}\n\t\tthis.#instances.set(questId, completedInstance)\n\t\tthis.#completedQuests.add(questId)\n\n\t\t// Grant rewards\n\t\tconst rewards = quest.rewards ?? []\n\n\t\tfor (const callback of this.#listeners.questComplete) {\n\t\t\tcallback(quest, rewards)\n\t\t}\n\n\t\t// Check if other quests become available\n\t\tthis.#checkNewlyAvailableQuests()\n\n\t\treturn true\n\t}\n\n\tfail(questId: string): boolean {\n\t\tconst instance = this.#instances.get(questId)\n\t\tconst quest = this.#quests.get(questId)\n\n\t\tif (!instance || !quest || instance.state !== 'active') return false\n\n\t\tconst failedInstance: QuestInstance = {\n\t\t\t...instance,\n\t\t\tstate: 'failed',\n\t\t\tfailedAt: Date.now(),\n\t\t}\n\t\tthis.#instances.set(questId, failedInstance)\n\t\tthis.#failedQuests.add(questId)\n\n\t\tfor (const callback of this.#listeners.questFail) {\n\t\t\tcallback(quest)\n\t\t}\n\n\t\treturn true\n\t}\n\n\tabandon(questId: string): boolean {\n\t\tconst instance = this.#instances.get(questId)\n\t\tconst quest = this.#quests.get(questId)\n\n\t\tif (!instance || !quest || instance.state !== 'active') return false\n\n\t\tthis.#instances.delete(questId)\n\n\t\tfor (const callback of this.#listeners.questAbandon) {\n\t\t\tcallback(quest)\n\t\t}\n\n\t\treturn true\n\t}\n\n\treset(questId: string): boolean {\n\t\tthis.#instances.delete(questId)\n\t\tthis.#completedQuests.delete(questId)\n\t\tthis.#failedQuests.delete(questId)\n\t\treturn true\n\t}\n\n\t// =========================================================================\n\t// Objective Management\n\t// =========================================================================\n\n\tupdateObjective(questId: string, objectiveId: string, progress: number): boolean {\n\t\tconst instance = this.#instances.get(questId)\n\t\tconst quest = this.#quests.get(questId)\n\n\t\tif (!instance || !quest || instance.state !== 'active') return false\n\n\t\tconst objectiveIndex = instance.objectives.findIndex(o => o.id === objectiveId)\n\t\tif (objectiveIndex === -1) return false\n\n\t\tconst objective = instance.objectives[objectiveIndex]\n\t\tif (!objective || objective.completed) return false\n\n\t\tconst newCurrent = Math.min(progress, objective.target)\n\t\tconst newCompleted = newCurrent >= objective.target\n\n\t\tconst newObjectives = [...instance.objectives]\n\t\tnewObjectives[objectiveIndex] = {\n\t\t\t...objective,\n\t\t\tcurrent: newCurrent,\n\t\t\tcompleted: newCompleted,\n\t\t}\n\n\t\tthis.#instances.set(questId, { ...instance, objectives: newObjectives })\n\n\t\t// Emit progress event\n\t\tfor (const callback of this.#listeners.objectiveProgress) {\n\t\t\tcallback(quest, newObjectives[objectiveIndex]!, newCurrent, objective.target)\n\t\t}\n\n\t\t// Emit complete event\n\t\tif (newCompleted && !objective.completed) {\n\t\t\tfor (const callback of this.#listeners.objectiveComplete) {\n\t\t\t\tcallback(quest, newObjectives[objectiveIndex]!)\n\t\t\t}\n\n\t\t\t// Auto-complete quest if all objectives done\n\t\t\tif (this.#autoTrackActive) {\n\t\t\t\tconst requiredComplete = newObjectives\n\t\t\t\t\t.filter(o => !o.optional)\n\t\t\t\t\t.every(o => o.completed)\n\n\t\t\t\tif (requiredComplete) {\n\t\t\t\t\tthis.complete(questId)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn true\n\t}\n\n\tincrementObjective(questId: string, objectiveId: string, amount = 1): boolean {\n\t\tconst instance = this.#instances.get(questId)\n\t\tif (!instance) return false\n\n\t\tconst objective = instance.objectives.find(o => o.id === objectiveId)\n\t\tif (!objective) return false\n\n\t\treturn this.updateObjective(questId, objectiveId, objective.current + amount)\n\t}\n\n\tcompleteObjective(questId: string, objectiveId: string): boolean {\n\t\tconst instance = this.#instances.get(questId)\n\t\tif (!instance) return false\n\n\t\tconst objective = instance.objectives.find(o => o.id === objectiveId)\n\t\tif (!objective) return false\n\n\t\treturn this.updateObjective(questId, objectiveId, objective.target)\n\t}\n\n\t// =========================================================================\n\t// Event Subscriptions\n\t// =========================================================================\n\n\tonQuestAvailable(callback: (quest: Quest) => void): Unsubscribe {\n\t\tthis.#listeners.questAvailable.add(callback)\n\t\treturn () => this.#listeners.questAvailable.delete(callback)\n\t}\n\n\tonQuestStart(callback: (quest: Quest) => void): Unsubscribe {\n\t\tthis.#listeners.questStart.add(callback)\n\t\treturn () => this.#listeners.questStart.delete(callback)\n\t}\n\n\tonQuestComplete(callback: (quest: Quest, rewards: readonly QuestReward[]) => void): Unsubscribe {\n\t\tthis.#listeners.questComplete.add(callback)\n\t\treturn () => this.#listeners.questComplete.delete(callback)\n\t}\n\n\tonQuestFail(callback: (quest: Quest) => void): Unsubscribe {\n\t\tthis.#listeners.questFail.add(callback)\n\t\treturn () => this.#listeners.questFail.delete(callback)\n\t}\n\n\tonQuestAbandon(callback: (quest: Quest) => void): Unsubscribe {\n\t\tthis.#listeners.questAbandon.add(callback)\n\t\treturn () => this.#listeners.questAbandon.delete(callback)\n\t}\n\n\tonObjectiveProgress(callback: (quest: Quest, objective: QuestObjective, current: number, target: number) => void): Unsubscribe {\n\t\tthis.#listeners.objectiveProgress.add(callback)\n\t\treturn () => this.#listeners.objectiveProgress.delete(callback)\n\t}\n\n\tonObjectiveComplete(callback: (quest: Quest, objective: QuestObjective) => void): Unsubscribe {\n\t\tthis.#listeners.objectiveComplete.add(callback)\n\t\treturn () => this.#listeners.objectiveComplete.delete(callback)\n\t}\n\n\t// =========================================================================\n\t// Lifecycle\n\t// =========================================================================\n\n\tdestroy(): void {\n\t\tthis.#quests.clear()\n\t\tthis.#instances.clear()\n\t\tthis.#completedQuests.clear()\n\t\tthis.#failedQuests.clear()\n\t\tthis.#listeners.questAvailable.clear()\n\t\tthis.#listeners.questStart.clear()\n\t\tthis.#listeners.questComplete.clear()\n\t\tthis.#listeners.questFail.clear()\n\t\tthis.#listeners.questAbandon.clear()\n\t\tthis.#listeners.objectiveProgress.clear()\n\t\tthis.#listeners.objectiveComplete.clear()\n\t}\n\n\t// =========================================================================\n\t// Private Methods\n\t// =========================================================================\n\n\t#checkPrerequisite(prereq: QuestPrerequisite): boolean {\n\t\tswitch (prereq.type) {\n\t\t\tcase 'quest':\n\t\t\t\treturn this.#completedQuests.has(prereq.target)\n\t\t\tcase 'level':\n\t\t\t\t// Level check would need external context\n\t\t\t\treturn true\n\t\t\tcase 'item':\n\t\t\t\t// Item check would need inventory context\n\t\t\t\treturn true\n\t\t\tcase 'flag':\n\t\t\t\t// Flag check would need external context\n\t\t\t\treturn true\n\t\t\tdefault:\n\t\t\t\treturn false\n\t\t}\n\t}\n\n\t#checkNewlyAvailableQuests(): void {\n\t\tfor (const quest of this.#quests.values()) {\n\t\t\tif (!this.isQuestActive(quest.id) && !this.isQuestCompleted(quest.id)) {\n\t\t\t\tif (this.checkPrerequisites(quest.id)) {\n\t\t\t\t\tfor (const callback of this.#listeners.questAvailable) {\n\t\t\t\t\t\tcallback(quest)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n","import type {\n\tRadialMenuInterface,\n\tRadialMenuOptions,\n\tRadialMenuState,\n\tRadialMenuItem,\n\tInputState,\n\tUnsubscribe,\n} from '../../types.js'\nimport { generateId } from '../../helpers.js'\nimport {\n\tDEFAULT_RADIAL_INNER_RADIUS,\n\tDEFAULT_RADIAL_OUTER_RADIUS,\n\tDEFAULT_RADIAL_CENTER_DEADZONE,\n} from '../../constants.js'\n\n/**\n * Radial menu for circular selection interfaces.\n *\n * @example\n * ```ts\n * const menu = createRadialMenu({\n * x: 0, y: 0, width: 200, height: 200,\n * items: [\n * { id: 'attack', LabelInterface: 'Attack', icon: '⚔️' },\n * { id: 'defend', LabelInterface: 'Defend', icon: '🛡️' },\n * { id: 'magic', LabelInterface: 'Magic', icon: '✨' },\n * ],\n * onSelect: (item) => console.log('Selected:', item.LabelInterface),\n * })\n *\n * menu.open(400, 300)\n * ```\n */\nexport class RadialMenu implements RadialMenuInterface {\n\treadonly id: string\n\t#items: RadialMenuItem[] = []\n\t#itemStack: RadialMenuItem[][] = []\n\n\t#x: number\n\t#y: number\n\t#width: number\n\t#height: number\n\t#centerX = 0\n\t#centerY = 0\n\t#visible = false\n\t#interactive = true\n\t#zIndex = 100\n\t#opacity = 1\n\n\t#isOpen = false\n\t#selectedIndex = -1\n\t#hoveredIndex = -1\n\t#currentLevel = 0\n\n\t#innerRadius: number\n\t#outerRadius: number\n\t#startAngle: number\n\t#gap: number\n\t#backgroundColor: string\n\t#selectedColor: string\n\t#hoverColor: string\n\t#disabledColor: string\n\t#textColor: string\n\t#fontSize: number\n\t#iconSize: number\n\t#showLabels: boolean\n\t#centerDeadzone: number\n\n\t#listeners = {\n\t\topen: new Set<(x: number, y: number) => void>(),\n\t\tclose: new Set<() => void>(),\n\t\tselect: new Set<(item: RadialMenuItem, index: number) => void>(),\n\t\thover: new Set<(item: RadialMenuItem | undefined, index: number) => void>(),\n\t\tcancel: new Set<() => void>(),\n\t}\n\n\tconstructor(options: RadialMenuOptions) {\n\t\tthis.id = generateId()\n\t\tthis.#x = options.x\n\t\tthis.#y = options.y\n\t\tthis.#width = options.width\n\t\tthis.#height = options.height\n\t\tthis.#visible = options.visible ?? false\n\t\tthis.#interactive = options.interactive ?? true\n\t\tthis.#zIndex = options.zIndex ?? 100\n\t\tthis.#opacity = options.opacity ?? 1\n\n\t\tthis.#items = [...options.items]\n\t\tthis.#innerRadius = options.innerRadius ?? DEFAULT_RADIAL_INNER_RADIUS\n\t\tthis.#outerRadius = options.outerRadius ?? DEFAULT_RADIAL_OUTER_RADIUS\n\t\tthis.#startAngle = options.startAngle ?? -Math.PI / 2\n\t\tthis.#gap = options.gap ?? 2\n\t\tthis.#backgroundColor = options.backgroundColor ?? 'rgba(0, 0, 0, 0.8)'\n\t\tthis.#selectedColor = options.selectedColor ?? 'rgba(66, 153, 225, 0.9)'\n\t\tthis.#hoverColor = options.hoverColor ?? 'rgba(100, 100, 100, 0.8)'\n\t\tthis.#disabledColor = options.disabledColor ?? 'rgba(50, 50, 50, 0.6)'\n\t\tthis.#textColor = options.textColor ?? '#ffffff'\n\t\tthis.#fontSize = options.fontSize ?? 12\n\t\tthis.#iconSize = options.iconSize ?? 24\n\t\tthis.#showLabels = options.showLabels ?? true\n\t\tthis.#centerDeadzone = options.centerDeadzone ?? DEFAULT_RADIAL_CENTER_DEADZONE\n\n\t\t// Register hooks from options\n\t\tif (options.onOpen) this.#listeners.open.add(options.onOpen)\n\t\tif (options.onClose) this.#listeners.close.add(options.onClose)\n\t\tif (options.onSelect) this.#listeners.select.add(options.onSelect)\n\t\tif (options.onHover) this.#listeners.hover.add(options.onHover)\n\t\tif (options.onCancel) this.#listeners.cancel.add(options.onCancel)\n\t}\n\n\t// =========================================================================\n\t// UIElement Implementation\n\t// =========================================================================\n\n\tisVisible(): boolean {\n\t\treturn this.#visible\n\t}\n\n\tsetVisible(visible: boolean): void {\n\t\tthis.#visible = visible\n\t\tif (!visible) {\n\t\t\tthis.close()\n\t\t}\n\t}\n\n\tgetX(): number {\n\t\treturn this.#x\n\t}\n\n\tgetY(): number {\n\t\treturn this.#y\n\t}\n\n\tsetX(x: number): void {\n\t\tthis.#x = x\n\t}\n\n\tsetY(y: number): void {\n\t\tthis.#y = y\n\t}\n\n\tsetPosition(x: number, y: number): void {\n\t\tthis.#x = x\n\t\tthis.#y = y\n\t}\n\n\tgetWidth(): number {\n\t\treturn this.#width\n\t}\n\n\tgetHeight(): number {\n\t\treturn this.#height\n\t}\n\n\tsetWidth(width: number): void {\n\t\tthis.#width = width\n\t}\n\n\tsetHeight(height: number): void {\n\t\tthis.#height = height\n\t}\n\n\tsetSize(width: number, height: number): void {\n\t\tthis.#width = width\n\t\tthis.#height = height\n\t}\n\n\tgetBounds() {\n\t\treturn {\n\t\t\tx: this.#x,\n\t\t\ty: this.#y,\n\t\t\twidth: this.#width,\n\t\t\theight: this.#height,\n\t\t}\n\t}\n\n\tcontains(x: number, y: number): boolean {\n\t\treturn x >= this.#x && x <= this.#x + this.#width &&\n\t\t\ty >= this.#y && y <= this.#y + this.#height\n\t}\n\n\tgetZIndex(): number {\n\t\treturn this.#zIndex\n\t}\n\n\tsetZIndex(zIndex: number): void {\n\t\tthis.#zIndex = zIndex\n\t}\n\n\tgetOpacity(): number {\n\t\treturn this.#opacity\n\t}\n\n\tsetOpacity(opacity: number): void {\n\t\tthis.#opacity = Math.max(0, Math.min(1, opacity))\n\t}\n\n\tisInteractive(): boolean {\n\t\treturn this.#interactive\n\t}\n\n\tsetInteractive(interactive: boolean): void {\n\t\tthis.#interactive = interactive\n\t}\n\n\t// =========================================================================\n\t// RadialMenuInterface Implementation\n\t// =========================================================================\n\n\tgetState(): RadialMenuState {\n\t\treturn {\n\t\t\tisOpen: this.#isOpen,\n\t\t\tcenterX: this.#centerX,\n\t\t\tcenterY: this.#centerY,\n\t\t\tselectedIndex: this.#selectedIndex,\n\t\t\thoveredIndex: this.#hoveredIndex,\n\t\t\titems: [...this.#items],\n\t\t\tcurrentLevel: this.#currentLevel,\n\t\t}\n\t}\n\n\tisOpen(): boolean {\n\t\treturn this.#isOpen\n\t}\n\n\tgetSelectedIndex(): number {\n\t\treturn this.#selectedIndex\n\t}\n\n\tgetSelectedItem(): RadialMenuItem | undefined {\n\t\tif (this.#selectedIndex < 0) return undefined\n\t\treturn this.#items[this.#selectedIndex]\n\t}\n\n\tgetHoveredIndex(): number {\n\t\treturn this.#hoveredIndex\n\t}\n\n\tgetItems(): readonly RadialMenuItem[] {\n\t\treturn this.#items\n\t}\n\n\t// =========================================================================\n\t// Menu Control\n\t// =========================================================================\n\n\topen(x: number, y: number): void {\n\t\tif (this.#isOpen) return\n\n\t\tthis.#centerX = x\n\t\tthis.#centerY = y\n\t\tthis.#isOpen = true\n\t\tthis.#visible = true\n\t\tthis.#selectedIndex = -1\n\t\tthis.#hoveredIndex = -1\n\t\tthis.#currentLevel = 0\n\t\tthis.#itemStack = []\n\n\t\tfor (const callback of this.#listeners.open) {\n\t\t\tcallback(x, y)\n\t\t}\n\t}\n\n\tclose(): void {\n\t\tif (!this.#isOpen) return\n\n\t\tthis.#isOpen = false\n\t\tthis.#visible = false\n\t\tthis.#selectedIndex = -1\n\t\tthis.#hoveredIndex = -1\n\n\t\tfor (const callback of this.#listeners.close) {\n\t\t\tcallback()\n\t\t}\n\t}\n\n\ttoggle(x: number, y: number): void {\n\t\tif (this.#isOpen) {\n\t\t\tthis.close()\n\t\t} else {\n\t\t\tthis.open(x, y)\n\t\t}\n\t}\n\n\tcancel(): void {\n\t\tif (this.#currentLevel > 0) {\n\t\t\tthis.navigateToParent()\n\t\t} else {\n\t\t\tthis.close()\n\t\t\tfor (const callback of this.#listeners.cancel) {\n\t\t\t\tcallback()\n\t\t\t}\n\t\t}\n\t}\n\n\tsetItems(items: readonly RadialMenuItem[]): void {\n\t\tthis.#items = [...items]\n\t}\n\n\tsetItemEnabled(id: string, enabled: boolean): void {\n\t\tconst index = this.#items.findIndex(item => item.id === id)\n\t\tif (index !== -1) {\n\t\t\tconst item = this.#items[index]\n\t\t\tif (item) {\n\t\t\t\tthis.#items[index] = { ...item, disabled: !enabled }\n\t\t\t}\n\t\t}\n\t}\n\n\tsetItemHidden(id: string, hidden: boolean): void {\n\t\tconst index = this.#items.findIndex(item => item.id === id)\n\t\tif (index !== -1) {\n\t\t\tconst item = this.#items[index]\n\t\t\tif (item) {\n\t\t\t\tthis.#items[index] = { ...item, hidden }\n\t\t\t}\n\t\t}\n\t}\n\n\tselectIndex(index: number): void {\n\t\tconst visibleItems = this.#items.filter(i => !i.hidden)\n\t\tif (index < 0 || index >= visibleItems.length) return\n\n\t\tconst item = visibleItems[index]\n\t\tif (!item || item.disabled) return\n\n\t\tthis.#selectedIndex = index\n\n\t\t// Check for children\n\t\tif (item.children && item.children.length > 0) {\n\t\t\tthis.navigateToChild(index)\n\t\t\treturn\n\t\t}\n\n\t\tfor (const callback of this.#listeners.select) {\n\t\t\tcallback(item, index)\n\t\t}\n\n\t\tthis.close()\n\t}\n\n\tselectItem(id: string): void {\n\t\tconst index = this.#items.findIndex(item => item.id === id && !item.hidden)\n\t\tif (index !== -1) {\n\t\t\tthis.selectIndex(index)\n\t\t}\n\t}\n\n\tnavigateToParent(): void {\n\t\tif (this.#currentLevel <= 0) return\n\n\t\tconst parentItems = this.#itemStack.pop()\n\t\tif (parentItems) {\n\t\t\tthis.#items = parentItems\n\t\t\tthis.#currentLevel--\n\t\t\tthis.#hoveredIndex = -1\n\t\t}\n\t}\n\n\tnavigateToChild(index: number): void {\n\t\tconst item = this.#items[index]\n\t\tif (!item?.children?.length) return\n\n\t\tthis.#itemStack.push([...this.#items])\n\t\tthis.#items = [...item.children]\n\t\tthis.#currentLevel++\n\t\tthis.#hoveredIndex = -1\n\t}\n\n\t// =========================================================================\n\t// Event Subscriptions\n\t// =========================================================================\n\n\tonOpen(callback: (x: number, y: number) => void): Unsubscribe {\n\t\tthis.#listeners.open.add(callback)\n\t\treturn () => this.#listeners.open.delete(callback)\n\t}\n\n\tonClose(callback: () => void): Unsubscribe {\n\t\tthis.#listeners.close.add(callback)\n\t\treturn () => this.#listeners.close.delete(callback)\n\t}\n\n\tonSelect(callback: (item: RadialMenuItem, index: number) => void): Unsubscribe {\n\t\tthis.#listeners.select.add(callback)\n\t\treturn () => this.#listeners.select.delete(callback)\n\t}\n\n\tonHover(callback: (item: RadialMenuItem | undefined, index: number) => void): Unsubscribe {\n\t\tthis.#listeners.hover.add(callback)\n\t\treturn () => this.#listeners.hover.delete(callback)\n\t}\n\n\tonCancel(callback: () => void): Unsubscribe {\n\t\tthis.#listeners.cancel.add(callback)\n\t\treturn () => this.#listeners.cancel.delete(callback)\n\t}\n\n\t// =========================================================================\n\t// Lifecycle\n\t// =========================================================================\n\n\tupdate(inputState: InputState): void {\n\t\tif (!this.#isOpen || !this.#interactive) return\n\n\t\t// Calculate which segment the pointer is in\n\t\tconst dx = inputState.pointerX - this.#centerX\n\t\tconst dy = inputState.pointerY - this.#centerY\n\t\tconst distance = Math.sqrt(dx * dx + dy * dy)\n\n\t\tconst visibleItems = this.#items.filter(i => !i.hidden)\n\n\t\tif (distance < this.#centerDeadzone) {\n\t\t\t// In center deadzone\n\t\t\tif (this.#hoveredIndex !== -1) {\n\t\t\t\tthis.#hoveredIndex = -1\n\t\t\t\tfor (const callback of this.#listeners.hover) {\n\t\t\t\t\tcallback(undefined, -1)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\tif (distance > this.#outerRadius) {\n\t\t\t// Outside menu\n\t\t\treturn\n\t\t}\n\n\t\t// Calculate angle\n\t\tlet angle = Math.atan2(dy, dx)\n\t\tangle -= this.#startAngle\n\t\tif (angle < 0) angle += Math.PI * 2\n\n\t\t// Calculate segment\n\t\tconst segmentAngle = (Math.PI * 2) / visibleItems.length\n\t\tconst segmentIndex = Math.floor(angle / segmentAngle)\n\t\tconst clampedIndex = segmentIndex % visibleItems.length\n\n\t\tif (clampedIndex !== this.#hoveredIndex) {\n\t\t\tthis.#hoveredIndex = clampedIndex\n\t\t\tconst hoveredItem = visibleItems[clampedIndex]\n\t\t\tfor (const callback of this.#listeners.hover) {\n\t\t\t\tcallback(hoveredItem, clampedIndex)\n\t\t\t}\n\t\t}\n\n\t\t// Handle selection on click\n\t\tif (inputState.isPointerDown && !inputState.wasPointerDown) {\n\t\t\tif (this.#hoveredIndex >= 0) {\n\t\t\t\tthis.selectIndex(this.#hoveredIndex)\n\t\t\t}\n\t\t}\n\t}\n\n\trender(ctx: CanvasRenderingContext2D): void {\n\t\tif (!this.#isOpen || !this.#visible) return\n\n\t\tconst visibleItems = this.#items.filter(i => !i.hidden)\n\t\tif (visibleItems.length === 0) return\n\n\t\tctx.save()\n\t\tctx.globalAlpha = this.#opacity\n\n\t\tconst segmentAngle = (Math.PI * 2) / visibleItems.length\n\t\tconst gapAngle = (this.#gap / this.#outerRadius)\n\n\t\tfor (let i = 0; i < visibleItems.length; i++) {\n\t\t\tconst item = visibleItems[i]\n\t\t\tif (!item) continue\n\n\t\t\tconst startAngle = this.#startAngle + i * segmentAngle + gapAngle / 2\n\t\t\tconst endAngle = startAngle + segmentAngle - gapAngle\n\n\t\t\t// Determine color\n\t\t\tlet color = this.#backgroundColor\n\t\t\tif (item.disabled) {\n\t\t\t\tcolor = this.#disabledColor\n\t\t\t} else if (i === this.#selectedIndex) {\n\t\t\t\tcolor = this.#selectedColor\n\t\t\t} else if (i === this.#hoveredIndex) {\n\t\t\t\tcolor = this.#hoverColor\n\t\t\t}\n\n\t\t\t// Draw segment\n\t\t\tctx.beginPath()\n\t\t\tctx.arc(this.#centerX, this.#centerY, this.#outerRadius, startAngle, endAngle)\n\t\t\tctx.arc(this.#centerX, this.#centerY, this.#innerRadius, endAngle, startAngle, true)\n\t\t\tctx.closePath()\n\t\t\tctx.fillStyle = color\n\t\t\tctx.fill()\n\n\t\t\t// Draw icon/LabelInterface\n\t\t\tconst midAngle = (startAngle + endAngle) / 2\n\t\t\tconst midRadius = (this.#innerRadius + this.#outerRadius) / 2\n\t\t\tconst labelX = this.#centerX + Math.cos(midAngle) * midRadius\n\t\t\tconst labelY = this.#centerY + Math.sin(midAngle) * midRadius\n\n\t\t\tctx.fillStyle = item.disabled ? '#888888' : this.#textColor\n\t\t\tctx.textAlign = 'center'\n\t\t\tctx.textBaseline = 'middle'\n\n\t\t\tif (item.icon) {\n\t\t\t\tctx.font = `${this.#iconSize}px sans-serif`\n\t\t\t\tctx.fillText(item.icon, labelX, labelY - (this.#showLabels ? 8 : 0))\n\t\t\t}\n\n\t\t\tif (this.#showLabels) {\n\t\t\t\tctx.font = `${this.#fontSize}px sans-serif`\n\t\t\t\tctx.fillText(item.label, labelX, labelY + (item.icon ? 12 : 0))\n\t\t\t}\n\t\t}\n\n\t\tctx.restore()\n\t}\n\n\tdestroy(): void {\n\t\tthis.close()\n\t\tthis.#items = []\n\t\tthis.#itemStack = []\n\t\tthis.#listeners.open.clear()\n\t\tthis.#listeners.close.clear()\n\t\tthis.#listeners.select.clear()\n\t\tthis.#listeners.hover.clear()\n\t\tthis.#listeners.cancel.clear()\n\t}\n}\n","import type {\n\tMinimapInterface,\n\tMinimapOptions,\n\tMinimapState,\n\tMinimapMarkerDef,\n\tMinimapIconDef,\n\tVector2,\n\tInputState,\n\tUnsubscribe,\n} from '../../types.js'\nimport { generateId } from '../../helpers.js'\nimport {\n\tDEFAULT_MINIMAP_ZOOM,\n\tDEFAULT_MINIMAP_MIN_ZOOM,\n\tDEFAULT_MINIMAP_MAX_ZOOM,\n} from '../../constants.js'\n\n/**\n * MinimapInterface for displaying world overview and markers.\n *\n * @example\n * ```ts\n * const MinimapInterface = createMinimap({\n * x: 10, y: 10, width: 150, height: 150,\n * worldWidth: 2000,\n * worldHeight: 2000,\n * shape: 'circle',\n * })\n *\n * MinimapInterface.setPlayerPosition(100, 200, Math.PI / 4)\n * MinimapInterface.addMarker({ id: 'quest', x: 500, y: 300, icon: { id: 'q', type: 'quest', color: '#ffcc00' } })\n * ```\n */\nexport class Minimap implements MinimapInterface {\n\treadonly id: string\n\t#markers: Map<string, MinimapMarkerDef> = new Map()\n\n\t#x: number\n\t#y: number\n\t#width: number\n\t#height: number\n\t#visible = true\n\t#interactive = true\n\t#zIndex = 100\n\t#opacity = 1\n\n\t#worldWidth: number\n\t#worldHeight: number\n\t#shape: 'circle' | 'rectangle'\n\t#zoom: number\n\t#minZoom: number\n\t#maxZoom: number\n\t#showPlayer: boolean\n\t#playerIcon: MinimapIconDef | undefined\n\t#rotateWithPlayer: boolean\n\t#showNorth: boolean\n\t#fogOfWar: boolean\n\t#backgroundColor: string\n\t#borderColor: string\n\t#borderWidth: number\n\t#clickable: boolean\n\n\t#centerX = 0\n\t#centerY = 0\n\t#rotation = 0\n\t#playerX = 0\n\t#playerY = 0\n\t#playerRotation = 0\n\n\t#fogMap: Set<string> = new Set()\n\n\t#listeners = {\n\t\tmarkerClick: new Set<(marker: MinimapMarkerDef) => void>(),\n\t\tmapClick: new Set<(worldX: number, worldY: number) => void>(),\n\t\tzoomChange: new Set<(zoom: number) => void>(),\n\t}\n\n\tconstructor(options: MinimapOptions) {\n\t\tthis.id = generateId()\n\t\tthis.#x = options.x\n\t\tthis.#y = options.y\n\t\tthis.#width = options.width\n\t\tthis.#height = options.height\n\t\tthis.#visible = options.visible ?? true\n\t\tthis.#interactive = options.interactive ?? true\n\t\tthis.#zIndex = options.zIndex ?? 100\n\t\tthis.#opacity = options.opacity ?? 1\n\n\t\tthis.#worldWidth = options.worldWidth\n\t\tthis.#worldHeight = options.worldHeight\n\t\tthis.#shape = options.shape ?? 'rectangle'\n\t\tthis.#zoom = options.zoom ?? DEFAULT_MINIMAP_ZOOM\n\t\tthis.#minZoom = options.minZoom ?? DEFAULT_MINIMAP_MIN_ZOOM\n\t\tthis.#maxZoom = options.maxZoom ?? DEFAULT_MINIMAP_MAX_ZOOM\n\t\tthis.#showPlayer = options.showPlayer ?? true\n\t\tthis.#playerIcon = options.playerIcon\n\t\tthis.#rotateWithPlayer = options.rotateWithPlayer ?? false\n\t\tthis.#showNorth = options.showNorth ?? true\n\t\tthis.#fogOfWar = options.fogOfWar ?? false\n\t\tthis.#backgroundColor = options.backgroundColor ?? 'rgba(0, 0, 0, 0.7)'\n\t\tthis.#borderColor = options.borderColor ?? '#ffffff'\n\t\tthis.#borderWidth = options.borderWidth ?? 2\n\t\tthis.#clickable = options.clickable ?? true\n\n\t\t// Register hooks from options\n\t\tif (options.onMarkerClick) this.#listeners.markerClick.add(options.onMarkerClick)\n\t\tif (options.onMapClick) this.#listeners.mapClick.add(options.onMapClick)\n\t\tif (options.onZoomChange) this.#listeners.zoomChange.add(options.onZoomChange)\n\t}\n\n\t// =========================================================================\n\t// UIElement Implementation\n\t// =========================================================================\n\n\tisVisible(): boolean { return this.#visible }\n\tsetVisible(visible: boolean): void { this.#visible = visible }\n\tgetX(): number { return this.#x }\n\tgetY(): number { return this.#y }\n\tsetX(x: number): void { this.#x = x }\n\tsetY(y: number): void { this.#y = y }\n\tsetPosition(x: number, y: number): void { this.#x = x; this.#y = y }\n\tgetWidth(): number { return this.#width }\n\tgetHeight(): number { return this.#height }\n\tsetWidth(width: number): void { this.#width = width }\n\tsetHeight(height: number): void { this.#height = height }\n\tsetSize(width: number, height: number): void { this.#width = width; this.#height = height }\n\tgetBounds() { return { x: this.#x, y: this.#y, width: this.#width, height: this.#height } }\n\n\tcontains(x: number, y: number): boolean {\n\t\tif (this.#shape === 'circle') {\n\t\t\tconst cx = this.#x + this.#width / 2\n\t\t\tconst cy = this.#y + this.#height / 2\n\t\t\tconst r = Math.min(this.#width, this.#height) / 2\n\t\t\tconst dx = x - cx\n\t\t\tconst dy = y - cy\n\t\t\treturn dx * dx + dy * dy <= r * r\n\t\t}\n\t\treturn x >= this.#x && x <= this.#x + this.#width && y >= this.#y && y <= this.#y + this.#height\n\t}\n\n\tgetZIndex(): number { return this.#zIndex }\n\tsetZIndex(zIndex: number): void { this.#zIndex = zIndex }\n\tgetOpacity(): number { return this.#opacity }\n\tsetOpacity(opacity: number): void { this.#opacity = Math.max(0, Math.min(1, opacity)) }\n\tisInteractive(): boolean { return this.#interactive }\n\tsetInteractive(interactive: boolean): void { this.#interactive = interactive }\n\n\t// =========================================================================\n\t// MinimapInterface State\n\t// =========================================================================\n\n\tgetState(): MinimapState {\n\t\treturn {\n\t\t\tcenterX: this.#centerX,\n\t\t\tcenterY: this.#centerY,\n\t\t\tzoom: this.#zoom,\n\t\t\trotation: this.#rotation,\n\t\t\tmarkers: Array.from(this.#markers.values()),\n\t\t\tplayerX: this.#playerX,\n\t\t\tplayerY: this.#playerY,\n\t\t\tplayerRotation: this.#playerRotation,\n\t\t}\n\t}\n\n\tgetZoom(): number { return this.#zoom }\n\tgetRotation(): number { return this.#rotation }\n\n\t// =========================================================================\n\t// Position Control\n\t// =========================================================================\n\n\tsetPlayerPosition(x: number, y: number, rotation?: number): void {\n\t\tthis.#playerX = x\n\t\tthis.#playerY = y\n\t\tif (rotation !== undefined) {\n\t\t\tthis.#playerRotation = rotation\n\t\t}\n\t\t// Auto-center on player\n\t\tthis.#centerX = x\n\t\tthis.#centerY = y\n\t\tif (this.#rotateWithPlayer && rotation !== undefined) {\n\t\t\tthis.#rotation = -rotation\n\t\t}\n\t}\n\n\tsetCenter(x: number, y: number): void {\n\t\tthis.#centerX = x\n\t\tthis.#centerY = y\n\t}\n\n\tsetZoom(zoom: number): void {\n\t\tconst oldZoom = this.#zoom\n\t\tthis.#zoom = Math.max(this.#minZoom, Math.min(this.#maxZoom, zoom))\n\t\tif (oldZoom !== this.#zoom) {\n\t\t\tfor (const callback of this.#listeners.zoomChange) {\n\t\t\t\tcallback(this.#zoom)\n\t\t\t}\n\t\t}\n\t}\n\n\tsetRotation(rotation: number): void {\n\t\tthis.#rotation = rotation\n\t}\n\n\tzoomIn(amount = 0.1): void {\n\t\tthis.setZoom(this.#zoom + amount)\n\t}\n\n\tzoomOut(amount = 0.1): void {\n\t\tthis.setZoom(this.#zoom - amount)\n\t}\n\n\t// =========================================================================\n\t// Marker Management\n\t// =========================================================================\n\n\taddMarker(marker: MinimapMarkerDef): void {\n\t\tthis.#markers.set(marker.id, marker)\n\t}\n\n\tremoveMarker(id: string): void {\n\t\tthis.#markers.delete(id)\n\t}\n\n\tupdateMarker(id: string, updates: Partial<MinimapMarkerDef>): void {\n\t\tconst marker = this.#markers.get(id)\n\t\tif (marker) {\n\t\t\tthis.#markers.set(id, { ...marker, ...updates, id })\n\t\t}\n\t}\n\n\tgetMarker(id: string): MinimapMarkerDef | undefined {\n\t\treturn this.#markers.get(id)\n\t}\n\n\tgetMarkers(): readonly MinimapMarkerDef[] {\n\t\treturn Array.from(this.#markers.values())\n\t}\n\n\tclearMarkers(): void {\n\t\tthis.#markers.clear()\n\t}\n\n\tsetMarkerVisible(id: string, visible: boolean): void {\n\t\tthis.updateMarker(id, { visible })\n\t}\n\n\t// =========================================================================\n\t// Coordinate Conversion\n\t// =========================================================================\n\n\tworldToMinimap(worldX: number, worldY: number): Vector2 {\n\t\tconst scaleX = (this.#width * this.#zoom) / this.#worldWidth\n\t\tconst scaleY = (this.#height * this.#zoom) / this.#worldHeight\n\n\t\tlet localX = (worldX - this.#centerX) * scaleX\n\t\tlet localY = (worldY - this.#centerY) * scaleY\n\n\t\t// Apply rotation\n\t\tif (this.#rotation !== 0) {\n\t\t\tconst cos = Math.cos(this.#rotation)\n\t\t\tconst sin = Math.sin(this.#rotation)\n\t\t\tconst rx = localX * cos - localY * sin\n\t\t\tconst ry = localX * sin + localY * cos\n\t\t\tlocalX = rx\n\t\t\tlocalY = ry\n\t\t}\n\n\t\treturn {\n\t\t\tx: this.#x + this.#width / 2 + localX,\n\t\t\ty: this.#y + this.#height / 2 + localY,\n\t\t}\n\t}\n\n\tminimapToWorld(minimapX: number, minimapY: number): Vector2 {\n\t\tlet localX = minimapX - (this.#x + this.#width / 2)\n\t\tlet localY = minimapY - (this.#y + this.#height / 2)\n\n\t\t// Reverse rotation\n\t\tif (this.#rotation !== 0) {\n\t\t\tconst cos = Math.cos(-this.#rotation)\n\t\t\tconst sin = Math.sin(-this.#rotation)\n\t\t\tconst rx = localX * cos - localY * sin\n\t\t\tconst ry = localX * sin + localY * cos\n\t\t\tlocalX = rx\n\t\t\tlocalY = ry\n\t\t}\n\n\t\tconst scaleX = (this.#width * this.#zoom) / this.#worldWidth\n\t\tconst scaleY = (this.#height * this.#zoom) / this.#worldHeight\n\n\t\treturn {\n\t\t\tx: this.#centerX + localX / scaleX,\n\t\t\ty: this.#centerY + localY / scaleY,\n\t\t}\n\t}\n\n\t// =========================================================================\n\t// Fog of War\n\t// =========================================================================\n\n\trevealFog(x: number, y: number, radius: number): void {\n\t\tif (!this.#fogOfWar) return\n\t\tconst cellSize = 32\n\t\tconst minX = Math.floor((x - radius) / cellSize)\n\t\tconst maxX = Math.floor((x + radius) / cellSize)\n\t\tconst minY = Math.floor((y - radius) / cellSize)\n\t\tconst maxY = Math.floor((y + radius) / cellSize)\n\n\t\tfor (let cx = minX; cx <= maxX; cx++) {\n\t\t\tfor (let cy = minY; cy <= maxY; cy++) {\n\t\t\t\tconst dx = cx * cellSize - x\n\t\t\t\tconst dy = cy * cellSize - y\n\t\t\t\tif (dx * dx + dy * dy <= radius * radius) {\n\t\t\t\t\tthis.#fogMap.add(`${cx},${cy}`)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\thideFog(x: number, y: number, radius: number): void {\n\t\tif (!this.#fogOfWar) return\n\t\tconst cellSize = 32\n\t\tconst minX = Math.floor((x - radius) / cellSize)\n\t\tconst maxX = Math.floor((x + radius) / cellSize)\n\t\tconst minY = Math.floor((y - radius) / cellSize)\n\t\tconst maxY = Math.floor((y + radius) / cellSize)\n\n\t\tfor (let cx = minX; cx <= maxX; cx++) {\n\t\t\tfor (let cy = minY; cy <= maxY; cy++) {\n\t\t\t\tconst dx = cx * cellSize - x\n\t\t\t\tconst dy = cy * cellSize - y\n\t\t\t\tif (dx * dx + dy * dy <= radius * radius) {\n\t\t\t\t\tthis.#fogMap.delete(`${cx},${cy}`)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tclearFog(): void {\n\t\tthis.#fogMap.clear()\n\t}\n\n\tresetFog(): void {\n\t\tthis.#fogMap = new Set()\n\t}\n\n\t// =========================================================================\n\t// Event Subscriptions\n\t// =========================================================================\n\n\tonMarkerClick(callback: (marker: MinimapMarkerDef) => void): Unsubscribe {\n\t\tthis.#listeners.markerClick.add(callback)\n\t\treturn () => this.#listeners.markerClick.delete(callback)\n\t}\n\n\tonMapClick(callback: (worldX: number, worldY: number) => void): Unsubscribe {\n\t\tthis.#listeners.mapClick.add(callback)\n\t\treturn () => this.#listeners.mapClick.delete(callback)\n\t}\n\n\tonZoomChange(callback: (zoom: number) => void): Unsubscribe {\n\t\tthis.#listeners.zoomChange.add(callback)\n\t\treturn () => this.#listeners.zoomChange.delete(callback)\n\t}\n\n\t// =========================================================================\n\t// Lifecycle\n\t// =========================================================================\n\n\tupdate(inputState: InputState): void {\n\t\tif (!this.#visible || !this.#interactive || !this.#clickable) return\n\n\t\t// Handle click\n\t\tif (inputState.isPointerDown && !inputState.wasPointerDown) {\n\t\t\tif (this.contains(inputState.pointerX, inputState.pointerY)) {\n\t\t\t\t// Check for marker click\n\t\t\t\tfor (const marker of this.#markers.values()) {\n\t\t\t\t\tif (marker.visible === false) continue\n\n\t\t\t\t\tconst pos = this.worldToMinimap(marker.x, marker.y)\n\t\t\t\t\tconst dx = inputState.pointerX - pos.x\n\t\t\t\t\tconst dy = inputState.pointerY - pos.y\n\t\t\t\t\tconst iconSize = marker.icon?.size ?? 10\n\n\t\t\t\t\tif (dx * dx + dy * dy <= iconSize * iconSize) {\n\t\t\t\t\t\tfor (const callback of this.#listeners.markerClick) {\n\t\t\t\t\t\t\tcallback(marker)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Map click\n\t\t\t\tconst worldPos = this.minimapToWorld(inputState.pointerX, inputState.pointerY)\n\t\t\t\tfor (const callback of this.#listeners.mapClick) {\n\t\t\t\t\tcallback(worldPos.x, worldPos.y)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\trender(ctx: CanvasRenderingContext2D): void {\n\t\tif (!this.#visible) return\n\n\t\tctx.save()\n\t\tctx.globalAlpha = this.#opacity\n\n\t\tconst cx = this.#x + this.#width / 2\n\t\tconst cy = this.#y + this.#height / 2\n\n\t\t// Clip to shape\n\t\tctx.beginPath()\n\t\tif (this.#shape === 'circle') {\n\t\t\tconst r = Math.min(this.#width, this.#height) / 2\n\t\t\tctx.arc(cx, cy, r, 0, Math.PI * 2)\n\t\t} else {\n\t\t\tctx.rect(this.#x, this.#y, this.#width, this.#height)\n\t\t}\n\t\tctx.clip()\n\n\t\t// Background\n\t\tctx.fillStyle = this.#backgroundColor\n\t\tctx.fill()\n\n\t\t// Draw markers\n\t\tfor (const marker of this.#markers.values()) {\n\t\t\tif (marker.visible === false) continue\n\n\t\t\tconst pos = this.worldToMinimap(marker.x, marker.y)\n\t\t\tconst icon = marker.icon\n\t\t\tconst size = icon?.size ?? 8\n\n\t\t\tctx.fillStyle = icon?.color ?? '#ffffff'\n\t\t\tctx.beginPath()\n\t\t\tctx.arc(pos.x, pos.y, size / 2, 0, Math.PI * 2)\n\t\t\tctx.fill()\n\n\t\t\tif (icon?.icon) {\n\t\t\t\tctx.fillStyle = '#ffffff'\n\t\t\t\tctx.font = `${size}px sans-serif`\n\t\t\t\tctx.textAlign = 'center'\n\t\t\t\tctx.textBaseline = 'middle'\n\t\t\t\tctx.fillText(icon.icon, pos.x, pos.y)\n\t\t\t}\n\t\t}\n\n\t\t// Draw player\n\t\tif (this.#showPlayer) {\n\t\t\tconst playerPos = this.worldToMinimap(this.#playerX, this.#playerY)\n\n\t\t\tctx.save()\n\t\t\tctx.translate(playerPos.x, playerPos.y)\n\t\t\tctx.rotate(this.#playerRotation + this.#rotation)\n\n\t\t\tctx.fillStyle = this.#playerIcon?.color ?? '#00ff00'\n\t\t\tctx.beginPath()\n\t\t\tctx.moveTo(0, -8)\n\t\t\tctx.lineTo(-5, 8)\n\t\t\tctx.lineTo(5, 8)\n\t\t\tctx.closePath()\n\t\t\tctx.fill()\n\n\t\t\tctx.restore()\n\t\t}\n\n\t\tctx.restore()\n\n\t\t// Border\n\t\tctx.strokeStyle = this.#borderColor\n\t\tctx.lineWidth = this.#borderWidth\n\t\tctx.beginPath()\n\t\tif (this.#shape === 'circle') {\n\t\t\tconst r = Math.min(this.#width, this.#height) / 2\n\t\t\tctx.arc(cx, cy, r - this.#borderWidth / 2, 0, Math.PI * 2)\n\t\t} else {\n\t\t\tctx.rect(this.#x, this.#y, this.#width, this.#height)\n\t\t}\n\t\tctx.stroke()\n\n\t\t// North indicator\n\t\tif (this.#showNorth) {\n\t\t\tctx.fillStyle = '#ff0000'\n\t\t\tctx.font = '12px sans-serif'\n\t\t\tctx.textAlign = 'center'\n\t\t\tctx.fillText('N', cx, this.#y + 15)\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.#markers.clear()\n\t\tthis.#fogMap.clear()\n\t\tthis.#listeners.markerClick.clear()\n\t\tthis.#listeners.mapClick.clear()\n\t\tthis.#listeners.zoomChange.clear()\n\t}\n}\n","import type {\n\tNotificationManagerInterface,\n\tNotificationManagerOptions,\n\tNotificationManagerState,\n\tNotificationDef,\n\tNotificationCategoryType,\n\tNotificationPriorityType,\n\tInputState,\n\tUnsubscribe,\n} from '../../types.js'\nimport { generateId } from '../../helpers.js'\nimport {\n\tDEFAULT_NOTIFICATION_MAX_VISIBLE,\n\tDEFAULT_NOTIFICATION_MAX_HISTORY,\n\tDEFAULT_NOTIFICATION_DURATION,\n} from '../../constants.js'\n\n/**\n * Notification queue for displaying toast-like notifications.\n *\n * @example\n * ```ts\n * const notifications = createNotificationManager({\n * x: 10, y: 10, width: 300, height: 400,\n * position: 'top-right',\n * })\n *\n * notifications.achievement('Level Up!', 'You reached level 10!')\n * notifications.quest('New Quest', 'A new quest is available.')\n * ```\n */\nexport class NotificationManager implements NotificationManagerInterface {\n\treadonly id: string\n\t#notifications: NotificationDef[] = []\n\t#visibleNotifications: NotificationDef[] = []\n\n\t#x: number\n\t#y: number\n\t#width: number\n\t#height: number\n\t#visible = true\n\t#interactive = true\n\t#zIndex = 200\n\t#opacity = 1\n\t#isExpanded = false\n\n\t#maxVisible: number\n\t#maxHistory: number\n\t#defaultDuration: number\n\t#groupByCategory: boolean\n\t#position: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'\n\t#animation: 'slide' | 'fade' | 'none'\n\t#hapticFeedback: boolean\n\n\t#timers: Map<string, ReturnType<typeof setTimeout>> = new Map()\n\n\t#listeners = {\n\t\tnotification: new Set<(notification: NotificationDef) => void>(),\n\t\tdismiss: new Set<(notification: NotificationDef) => void>(),\n\t\tread: new Set<(notification: NotificationDef) => void>(),\n\t\tclick: new Set<(notification: NotificationDef) => void>(),\n\t\tclear: new Set<() => void>(),\n\t}\n\n\tconstructor(options: NotificationManagerOptions) {\n\t\tthis.id = generateId()\n\t\tthis.#x = options.x\n\t\tthis.#y = options.y\n\t\tthis.#width = options.width\n\t\tthis.#height = options.height\n\t\tthis.#visible = options.visible ?? true\n\t\tthis.#interactive = options.interactive ?? true\n\t\tthis.#zIndex = options.zIndex ?? 200\n\t\tthis.#opacity = options.opacity ?? 1\n\n\t\tthis.#maxVisible = options.maxVisible ?? DEFAULT_NOTIFICATION_MAX_VISIBLE\n\t\tthis.#maxHistory = options.maxHistory ?? DEFAULT_NOTIFICATION_MAX_HISTORY\n\t\tthis.#defaultDuration = options.defaultDuration ?? DEFAULT_NOTIFICATION_DURATION\n\t\tthis.#groupByCategory = options.groupByCategory ?? false\n\t\tthis.#position = options.position ?? 'top-right'\n\t\tthis.#animation = options.animation ?? 'slide'\n\t\tthis.#hapticFeedback = options.hapticFeedback ?? false\n\n\t\t// Register hooks\n\t\tif (options.onNotification) this.#listeners.notification.add(options.onNotification)\n\t\tif (options.onDismiss) this.#listeners.dismiss.add(options.onDismiss)\n\t\tif (options.onRead) this.#listeners.read.add(options.onRead)\n\t\tif (options.onClick) this.#listeners.click.add(options.onClick)\n\t\tif (options.onClear) this.#listeners.clear.add(options.onClear)\n\t}\n\n\t// =========================================================================\n\t// UIElement Implementation\n\t// =========================================================================\n\n\tisVisible(): boolean { return this.#visible }\n\tsetVisible(visible: boolean): void { this.#visible = visible }\n\tgetX(): number { return this.#x }\n\tgetY(): number { return this.#y }\n\tsetX(x: number): void { this.#x = x }\n\tsetY(y: number): void { this.#y = y }\n\tsetPosition(x: number, y: number): void { this.#x = x; this.#y = y }\n\tgetWidth(): number { return this.#width }\n\tgetHeight(): number { return this.#height }\n\tsetWidth(width: number): void { this.#width = width }\n\tsetHeight(height: number): void { this.#height = height }\n\tsetSize(width: number, height: number): void { this.#width = width; this.#height = height }\n\tgetBounds() { return { x: this.#x, y: this.#y, width: this.#width, height: this.#height } }\n\tcontains(x: number, y: number): boolean {\n\t\treturn x >= this.#x && x <= this.#x + this.#width && y >= this.#y && y <= this.#y + this.#height\n\t}\n\tgetZIndex(): number { return this.#zIndex }\n\tsetZIndex(zIndex: number): void { this.#zIndex = zIndex }\n\tgetOpacity(): number { return this.#opacity }\n\tsetOpacity(opacity: number): void { this.#opacity = Math.max(0, Math.min(1, opacity)) }\n\tisInteractive(): boolean { return this.#interactive }\n\tsetInteractive(interactive: boolean): void { this.#interactive = interactive }\n\n\t// =========================================================================\n\t// NotificationManagerInterface State\n\t// =========================================================================\n\n\tgetState(): NotificationManagerState {\n\t\treturn {\n\t\t\tnotifications: [...this.#notifications],\n\t\t\tunreadCount: this.getUnreadCount(),\n\t\t\tvisibleNotifications: [...this.#visibleNotifications],\n\t\t\tisExpanded: this.#isExpanded,\n\t\t}\n\t}\n\n\tgetNotifications(): readonly NotificationDef[] {\n\t\treturn this.#notifications\n\t}\n\n\tgetUnreadCount(): number {\n\t\treturn this.#notifications.filter(n => !n.read && !n.dismissed).length\n\t}\n\n\tgetByCategory(category: NotificationCategoryType): readonly NotificationDef[] {\n\t\treturn this.#notifications.filter(n => n.category === category)\n\t}\n\n\tisExpanded(): boolean {\n\t\treturn this.#isExpanded\n\t}\n\n\t// =========================================================================\n\t// Notification Management\n\t// =========================================================================\n\n\tpush(notification: Omit<NotificationDef, 'id' | 'timestamp' | 'read' | 'dismissed'>): string {\n\t\tconst id = generateId()\n\t\tconst fullNotification: NotificationDef = {\n\t\t\t...notification,\n\t\t\tid,\n\t\t\ttimestamp: Date.now(),\n\t\t\tread: false,\n\t\t\tdismissed: false,\n\t\t}\n\n\t\tthis.#notifications.unshift(fullNotification)\n\n\t\t// Trim history\n\t\tif (this.#notifications.length > this.#maxHistory) {\n\t\t\tthis.#notifications = this.#notifications.slice(0, this.#maxHistory)\n\t\t}\n\n\t\t// Add to visible\n\t\tthis.#visibleNotifications.unshift(fullNotification)\n\t\tif (this.#visibleNotifications.length > this.#maxVisible) {\n\t\t\tthis.#visibleNotifications = this.#visibleNotifications.slice(0, this.#maxVisible)\n\t\t}\n\n\t\t// Set auto-dismiss timer if not persistent\n\t\tif (!notification.persistent) {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tthis.dismiss(id)\n\t\t\t}, this.#defaultDuration)\n\t\t\tthis.#timers.set(id, timer)\n\t\t}\n\n\t\t// Emit event\n\t\tfor (const callback of this.#listeners.notification) {\n\t\t\tcallback(fullNotification)\n\t\t}\n\n\t\treturn id\n\t}\n\n\tdismiss(id: string): void {\n\t\tconst index = this.#notifications.findIndex(n => n.id === id)\n\t\tif (index === -1) return\n\n\t\tconst notification = this.#notifications[index]\n\t\tif (!notification) return\n\n\t\tthis.#notifications[index] = { ...notification, dismissed: true }\n\t\tthis.#visibleNotifications = this.#visibleNotifications.filter(n => n.id !== id)\n\n\t\t// Clear timer\n\t\tconst timer = this.#timers.get(id)\n\t\tif (timer) {\n\t\t\tclearTimeout(timer)\n\t\t\tthis.#timers.delete(id)\n\t\t}\n\n\t\tfor (const callback of this.#listeners.dismiss) {\n\t\t\tcallback(notification)\n\t\t}\n\t}\n\n\tdismissAll(): void {\n\t\tfor (const notification of this.#visibleNotifications) {\n\t\t\tthis.dismiss(notification.id)\n\t\t}\n\t}\n\n\tmarkRead(id: string): void {\n\t\tconst index = this.#notifications.findIndex(n => n.id === id)\n\t\tif (index === -1) return\n\n\t\tconst notification = this.#notifications[index]\n\t\tif (!notification || notification.read) return\n\n\t\tthis.#notifications[index] = { ...notification, read: true }\n\n\t\tfor (const callback of this.#listeners.read) {\n\t\t\tcallback(notification)\n\t\t}\n\t}\n\n\tmarkAllRead(): void {\n\t\tthis.#notifications = this.#notifications.map(n => ({ ...n, read: true }))\n\t}\n\n\tclear(): void {\n\t\t// Clear all timers\n\t\tfor (const timer of this.#timers.values()) {\n\t\t\tclearTimeout(timer)\n\t\t}\n\t\tthis.#timers.clear()\n\n\t\tthis.#notifications = []\n\t\tthis.#visibleNotifications = []\n\n\t\tfor (const callback of this.#listeners.clear) {\n\t\t\tcallback()\n\t\t}\n\t}\n\n\t// =========================================================================\n\t// Convenience Methods\n\t// =========================================================================\n\n\tachievement(title: string, message: string, icon?: string): string {\n\t\treturn this.push({ title, message, category: 'achievement', priority: 'high', ...(icon ? { icon } : {}) })\n\t}\n\n\tquest(title: string, message: string, icon?: string): string {\n\t\treturn this.push({ title, message, category: 'quest', priority: 'normal', ...(icon ? { icon } : {}) })\n\t}\n\n\tsystem(title: string, message: string, icon?: string): string {\n\t\treturn this.push({ title, message, category: 'system', priority: 'normal', ...(icon ? { icon } : {}) })\n\t}\n\n\treward(title: string, message: string, icon?: string): string {\n\t\treturn this.push({ title, message, category: 'reward', priority: 'high', ...(icon ? { icon } : {}) })\n\t}\n\n\t// =========================================================================\n\t// Expand/Collapse\n\t// =========================================================================\n\n\texpand(): void {\n\t\tthis.#isExpanded = true\n\t}\n\n\tcollapse(): void {\n\t\tthis.#isExpanded = false\n\t}\n\n\ttoggle(): void {\n\t\tthis.#isExpanded = !this.#isExpanded\n\t}\n\n\t// =========================================================================\n\t// Event Subscriptions\n\t// =========================================================================\n\n\tonNotification(callback: (notification: NotificationDef) => void): Unsubscribe {\n\t\tthis.#listeners.notification.add(callback)\n\t\treturn () => this.#listeners.notification.delete(callback)\n\t}\n\n\tonDismiss(callback: (notification: NotificationDef) => void): Unsubscribe {\n\t\tthis.#listeners.dismiss.add(callback)\n\t\treturn () => this.#listeners.dismiss.delete(callback)\n\t}\n\n\tonRead(callback: (notification: NotificationDef) => void): Unsubscribe {\n\t\tthis.#listeners.read.add(callback)\n\t\treturn () => this.#listeners.read.delete(callback)\n\t}\n\n\tonClick(callback: (notification: NotificationDef) => void): Unsubscribe {\n\t\tthis.#listeners.click.add(callback)\n\t\treturn () => this.#listeners.click.delete(callback)\n\t}\n\n\tonClear(callback: () => void): Unsubscribe {\n\t\tthis.#listeners.clear.add(callback)\n\t\treturn () => this.#listeners.clear.delete(callback)\n\t}\n\n\t// =========================================================================\n\t// Lifecycle\n\t// =========================================================================\n\n\tupdate(inputState: InputState): void {\n\t\tif (!this.#visible || !this.#interactive) return\n\n\t\t// Handle clicks on notifications\n\t\tif (inputState.isPointerDown && !inputState.wasPointerDown) {\n\t\t\tif (this.contains(inputState.pointerX, inputState.pointerY)) {\n\t\t\t\t// Find clicked notification\n\t\t\t\tconst notificationHeight = 60\n\t\t\t\tconst relativeY = inputState.pointerY - this.#y\n\t\t\t\tconst index = Math.floor(relativeY / notificationHeight)\n\n\t\t\t\tif (index >= 0 && index < this.#visibleNotifications.length) {\n\t\t\t\t\tconst notification = this.#visibleNotifications[index]\n\t\t\t\t\tif (notification) {\n\t\t\t\t\t\tthis.markRead(notification.id)\n\t\t\t\t\t\tif (notification.action) {\n\t\t\t\t\t\t\tnotification.action()\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (const callback of this.#listeners.click) {\n\t\t\t\t\t\t\tcallback(notification)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\trender(ctx: CanvasRenderingContext2D): void {\n\t\tif (!this.#visible || this.#visibleNotifications.length === 0) return\n\n\t\tctx.save()\n\t\tctx.globalAlpha = this.#opacity\n\n\t\tconst notificationHeight = 60\n\t\tconst padding = 10\n\t\tconst notifs = this.#isExpanded ? this.#notifications.filter(n => !n.dismissed) : this.#visibleNotifications\n\n\t\tfor (let i = 0; i < notifs.length; i++) {\n\t\t\tconst notification = notifs[i]\n\t\t\tif (!notification) continue\n\n\t\t\tconst y = this.#y + i * (notificationHeight + 5)\n\n\t\t\t// Background\n\t\t\tctx.fillStyle = notification.read ? 'rgba(50, 50, 50, 0.9)' : 'rgba(30, 30, 30, 0.95)'\n\t\t\tctx.beginPath()\n\t\t\tctx.roundRect(this.#x, y, this.#width, notificationHeight, 8)\n\t\t\tctx.fill()\n\n\t\t\t// Priority indicator\n\t\t\tconst priorityColors: Record<NotificationPriorityType, string> = {\n\t\t\t\tlow: '#888888',\n\t\t\t\tnormal: '#4299e1',\n\t\t\t\thigh: '#ed8936',\n\t\t\t\tcritical: '#f56565',\n\t\t\t}\n\t\t\tctx.fillStyle = priorityColors[notification.priority]\n\t\t\tctx.fillRect(this.#x, y, 4, notificationHeight)\n\n\t\t\t// Icon\n\t\t\tif (notification.icon) {\n\t\t\t\tctx.fillStyle = '#ffffff'\n\t\t\t\tctx.font = '20px sans-serif'\n\t\t\t\tctx.textAlign = 'left'\n\t\t\t\tctx.textBaseline = 'middle'\n\t\t\t\tctx.fillText(notification.icon, this.#x + padding + 5, y + notificationHeight / 2)\n\t\t\t}\n\n\t\t\t// Title\n\t\t\tctx.fillStyle = '#ffffff'\n\t\t\tctx.font = 'bold 14px sans-serif'\n\t\t\tctx.textAlign = 'left'\n\t\t\tctx.textBaseline = 'top'\n\t\t\tconst textX = this.#x + padding + (notification.icon ? 35 : 10)\n\t\t\tctx.fillText(notification.title, textX, y + 10)\n\n\t\t\t// Message\n\t\t\tctx.fillStyle = '#aaaaaa'\n\t\t\tctx.font = '12px sans-serif'\n\t\t\tctx.fillText(notification.message.slice(0, 40), textX, y + 32)\n\t\t}\n\n\t\tctx.restore()\n\t}\n\n\tdestroy(): void {\n\t\tfor (const timer of this.#timers.values()) {\n\t\t\tclearTimeout(timer)\n\t\t}\n\t\tthis.#timers.clear()\n\t\tthis.#notifications = []\n\t\tthis.#visibleNotifications = []\n\t\tthis.#listeners.notification.clear()\n\t\tthis.#listeners.dismiss.clear()\n\t\tthis.#listeners.read.clear()\n\t\tthis.#listeners.click.clear()\n\t\tthis.#listeners.clear.clear()\n\t}\n}\n","import type {\n\tEntityInspectorInterface,\n\tEntityInspectorOptions,\n\tInspectorPanelState,\n\tInspectableProperty,\n\tPropertyWatcher,\n\tEntityInterface,\n\tInputState,\n\tUnsubscribe,\n} from '../../types.js'\n\n/**\n * EntityInterface inspector for debugging and editing EntityInterface properties.\n *\n * @example\n * ```ts\n * const inspector = createEntityInspector({\n * position: 'right',\n * width: 300,\n * })\n *\n * inspector.selectEntity(player)\n * inspector.open()\n * ```\n */\nexport class EntityInspector implements EntityInspectorInterface {\n\t#selectedEntity: EntityInterface | undefined\n\t#properties: InspectableProperty[] = []\n\t#watchers: Map<string, Set<(value: unknown) => void>> = new Map()\n\t#expandedCategories: Set<string> = new Set()\n\n\t#isOpen = false\n\t#enabled: boolean\n\t#position: 'left' | 'right'\n\t#width: number\n\t#showComponents: boolean\n\t#showTransform: boolean\n\t#showBounds: boolean\n\t#editableProperties: Set<string>\n\n\t#listeners = {\n\t\tentitySelect: new Set<(EntityInterface: EntityInterface | undefined) => void>(),\n\t\tpropertyChange: new Set<(property: string, oldValue: unknown, newValue: unknown) => void>(),\n\t\topen: new Set<() => void>(),\n\t\tclose: new Set<() => void>(),\n\t}\n\n\tconstructor(options?: EntityInspectorOptions) {\n\t\tthis.#enabled = options?.enabled ?? true\n\t\tthis.#position = options?.position ?? 'right'\n\t\tthis.#width = options?.width ?? 300\n\t\tthis.#showComponents = options?.showComponents ?? true\n\t\tthis.#showTransform = options?.showTransform ?? true\n\t\tthis.#showBounds = options?.showBounds ?? true\n\t\tthis.#editableProperties = new Set(options?.editableProperties ?? [])\n\n\t\t// Register hooks\n\t\tif (options?.onEntitySelect) this.#listeners.entitySelect.add(options.onEntitySelect)\n\t\tif (options?.onPropertyChange) this.#listeners.propertyChange.add(options.onPropertyChange)\n\t\tif (options?.onOpen) this.#listeners.open.add(options.onOpen)\n\t\tif (options?.onClose) this.#listeners.close.add(options.onClose)\n\t}\n\n\t// =========================================================================\n\t// Accessors\n\t// =========================================================================\n\n\tgetState(): InspectorPanelState {\n\t\treturn {\n\t\t\tisOpen: this.#isOpen,\n\t\t\tselectedEntity: this.#selectedEntity,\n\t\t\tproperties: [...this.#properties],\n\t\t\texpandedCategories: new Set(this.#expandedCategories),\n\t\t}\n\t}\n\n\tisOpen(): boolean {\n\t\treturn this.#isOpen\n\t}\n\n\tgetSelectedEntity(): EntityInterface | undefined {\n\t\treturn this.#selectedEntity\n\t}\n\n\tgetProperties(): readonly InspectableProperty[] {\n\t\treturn this.#properties\n\t}\n\n\tgetProperty(name: string): InspectableProperty | undefined {\n\t\treturn this.#properties.find(p => p.name === name)\n\t}\n\n\t// =========================================================================\n\t// PanelInterface Control\n\t// =========================================================================\n\n\topen(): void {\n\t\tif (!this.#enabled || this.#isOpen) return\n\n\t\tthis.#isOpen = true\n\t\tfor (const callback of this.#listeners.open) {\n\t\t\tcallback()\n\t\t}\n\t}\n\n\tclose(): void {\n\t\tif (!this.#isOpen) return\n\n\t\tthis.#isOpen = false\n\t\tfor (const callback of this.#listeners.close) {\n\t\t\tcallback()\n\t\t}\n\t}\n\n\ttoggle(): void {\n\t\tif (this.#isOpen) {\n\t\t\tthis.close()\n\t\t} else {\n\t\t\tthis.open()\n\t\t}\n\t}\n\n\t// =========================================================================\n\t// EntityInterface Selection\n\t// =========================================================================\n\n\tselectEntity(EntityInterface: EntityInterface | undefined): void {\n\t\tif (this.#selectedEntity === EntityInterface) return\n\n\t\tthis.#selectedEntity = EntityInterface\n\t\tthis.refreshProperties()\n\n\t\tfor (const callback of this.#listeners.entitySelect) {\n\t\t\tcallback(EntityInterface)\n\t\t}\n\t}\n\n\tselectEntityById(id: string): void {\n\t\t// This would need access to EntityInterface manager to find by id\n\t\t// For now, just clear selection if id doesn't match\n\t\tif (this.#selectedEntity?.id !== id) {\n\t\t\tthis.selectEntity(undefined)\n\t\t}\n\t}\n\n\tclearSelection(): void {\n\t\tthis.selectEntity(undefined)\n\t}\n\n\t// =========================================================================\n\t// Property Management\n\t// =========================================================================\n\n\tsetProperty(name: string, value: unknown): boolean {\n\t\tconst property = this.#properties.find(p => p.name === name)\n\t\tif (!property || !property.editable) return false\n\n\t\tconst oldValue = property.value\n\t\tconst EntityInterface = this.#selectedEntity\n\n\t\tif (!EntityInterface) return false\n\n\t\t// Try to set the property on the EntityInterface\n\t\ttry {\n\t\t\tconst record = EntityInterface as unknown as Record<string, unknown>\n\t\t\tconst setter = record[`set${name.charAt(0).toUpperCase()}${name.slice(1)}`]\n\n\t\t\tif (typeof setter === 'function') {\n\t\t\t\t(setter as (v: unknown) => void).call(EntityInterface, value)\n\t\t\t} else {\n\t\t\t\trecord[name] = value\n\t\t\t}\n\n\t\t\t// Update property in list\n\t\t\tconst index = this.#properties.findIndex(p => p.name === name)\n\t\t\tif (index !== -1) {\n\t\t\t\tthis.#properties[index] = { ...property, value }\n\t\t\t}\n\n\t\t\t// Notify watchers\n\t\t\tconst watchers = this.#watchers.get(name)\n\t\t\tif (watchers) {\n\t\t\t\tfor (const watcher of watchers) {\n\t\t\t\t\twatcher(value)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Emit event\n\t\t\tfor (const callback of this.#listeners.propertyChange) {\n\t\t\t\tcallback(name, oldValue, value)\n\t\t\t}\n\n\t\t\treturn true\n\t\t} catch {\n\t\t\treturn false\n\t\t}\n\t}\n\n\trefreshProperties(): void {\n\t\tthis.#properties = []\n\n\t\tif (!this.#selectedEntity) return\n\n\t\tconst EntityInterface = this.#selectedEntity\n\n\t\t// Add basic EntityInterface properties\n\t\tthis.#addProperty('id', EntityInterface.id, 'string', 'EntityInterface', true)\n\n\t\t// Add transform properties if available\n\t\tif (this.#showTransform) {\n\t\t\tconst positionable = EntityInterface as unknown as { getX?: () => number; getY?: () => number }\n\t\t\tif (typeof positionable.getX === 'function' && typeof positionable.getY === 'function') {\n\t\t\t\tthis.#addProperty('x', positionable.getX(), 'number', 'Transform', false)\n\t\t\t\tthis.#addProperty('y', positionable.getY(), 'number', 'Transform', false)\n\t\t\t}\n\n\t\t\tconst rotatable = EntityInterface as unknown as { getRotation?: () => number }\n\t\t\tif (typeof rotatable.getRotation === 'function') {\n\t\t\t\tthis.#addProperty('rotation', rotatable.getRotation(), 'number', 'Transform', false)\n\t\t\t}\n\n\t\t\tconst scalable = EntityInterface as unknown as { getScaleX?: () => number; getScaleY?: () => number }\n\t\t\tif (typeof scalable.getScaleX === 'function' && typeof scalable.getScaleY === 'function') {\n\t\t\t\tthis.#addProperty('scaleX', scalable.getScaleX(), 'number', 'Transform', false)\n\t\t\t\tthis.#addProperty('scaleY', scalable.getScaleY(), 'number', 'Transform', false)\n\t\t\t}\n\t\t}\n\n\t\t// Add bounds if available\n\t\tif (this.#showBounds) {\n\t\t\tconst bounded = EntityInterface as unknown as { getWidth?: () => number; getHeight?: () => number }\n\t\t\tif (typeof bounded.getWidth === 'function' && typeof bounded.getHeight === 'function') {\n\t\t\t\tthis.#addProperty('width', bounded.getWidth(), 'number', 'Bounds', false)\n\t\t\t\tthis.#addProperty('height', bounded.getHeight(), 'number', 'Bounds', false)\n\t\t\t}\n\t\t}\n\n\t\t// Add active state\n\t\tconst activatable = EntityInterface as unknown as { isActive?: () => boolean }\n\t\tif (typeof activatable.isActive === 'function') {\n\t\t\tthis.#addProperty('active', activatable.isActive(), 'boolean', 'State', false)\n\t\t}\n\n\t\t// Add visible state\n\t\tconst visible = EntityInterface as unknown as { isVisible?: () => boolean }\n\t\tif (typeof visible.isVisible === 'function') {\n\t\t\tthis.#addProperty('visible', visible.isVisible(), 'boolean', 'State', false)\n\t\t}\n\t}\n\n\taddPropertyWatcher(watcher: PropertyWatcher): Unsubscribe {\n\t\tlet watchers = this.#watchers.get(watcher.property)\n\t\tif (!watchers) {\n\t\t\twatchers = new Set()\n\t\t\tthis.#watchers.set(watcher.property, watchers)\n\t\t}\n\t\twatchers.add(watcher.callback)\n\n\t\treturn () => {\n\t\t\tconst set = this.#watchers.get(watcher.property)\n\t\t\tset?.delete(watcher.callback)\n\t\t}\n\t}\n\n\t// =========================================================================\n\t// Category Management\n\t// =========================================================================\n\n\texpandCategory(category: string): void {\n\t\tthis.#expandedCategories.add(category)\n\t}\n\n\tcollapseCategory(category: string): void {\n\t\tthis.#expandedCategories.delete(category)\n\t}\n\n\ttoggleCategory(category: string): void {\n\t\tif (this.#expandedCategories.has(category)) {\n\t\t\tthis.collapseCategory(category)\n\t\t} else {\n\t\t\tthis.expandCategory(category)\n\t\t}\n\t}\n\n\t// =========================================================================\n\t// Event Subscriptions\n\t// =========================================================================\n\n\tonEntitySelect(callback: (EntityInterface: EntityInterface | undefined) => void): Unsubscribe {\n\t\tthis.#listeners.entitySelect.add(callback)\n\t\treturn () => this.#listeners.entitySelect.delete(callback)\n\t}\n\n\tonPropertyChange(callback: (property: string, oldValue: unknown, newValue: unknown) => void): Unsubscribe {\n\t\tthis.#listeners.propertyChange.add(callback)\n\t\treturn () => this.#listeners.propertyChange.delete(callback)\n\t}\n\n\tonOpen(callback: () => void): Unsubscribe {\n\t\tthis.#listeners.open.add(callback)\n\t\treturn () => this.#listeners.open.delete(callback)\n\t}\n\n\tonClose(callback: () => void): Unsubscribe {\n\t\tthis.#listeners.close.add(callback)\n\t\treturn () => this.#listeners.close.delete(callback)\n\t}\n\n\t// =========================================================================\n\t// Lifecycle\n\t// =========================================================================\n\n\tupdate(_inputState: InputState): void {\n\t\t// Update property values from EntityInterface\n\t\tif (this.#isOpen && this.#selectedEntity) {\n\t\t\tthis.refreshProperties()\n\t\t}\n\t}\n\n\trender(ctx: CanvasRenderingContext2D): void {\n\t\tif (!this.#isOpen || !this.#enabled) return\n\n\t\tconst x = this.#position === 'right' ? ctx.canvas.width - this.#width : 0\n\t\tconst y = 0\n\t\tconst height = ctx.canvas.height\n\n\t\tctx.save()\n\n\t\t// Background\n\t\tctx.fillStyle = 'rgba(30, 30, 30, 0.95)'\n\t\tctx.fillRect(x, y, this.#width, height)\n\n\t\t// Title\n\t\tctx.fillStyle = '#ffffff'\n\t\tctx.font = 'bold 14px sans-serif'\n\t\tctx.textAlign = 'left'\n\t\tctx.fillText('EntityInterface Inspector', x + 10, 25)\n\n\t\tif (this.#selectedEntity) {\n\t\t\tctx.font = '12px sans-serif'\n\t\t\tctx.fillStyle = '#aaaaaa'\n\t\t\tctx.fillText(`ID: ${this.#selectedEntity.id}`, x + 10, 45)\n\n\t\t\t// Group properties by category\n\t\t\tconst byCategory = new Map<string, InspectableProperty[]>()\n\t\t\tfor (const prop of this.#properties) {\n\t\t\t\tconst cat = prop.category ?? 'General'\n\t\t\t\tconst list = byCategory.get(cat) ?? []\n\t\t\t\tlist.push(prop)\n\t\t\t\tbyCategory.set(cat, list)\n\t\t\t}\n\n\t\t\tlet yOffset = 70\n\t\t\tfor (const [category, props] of byCategory) {\n\t\t\t\t// Category header\n\t\t\t\tctx.fillStyle = '#4299e1'\n\t\t\t\tctx.font = 'bold 11px sans-serif'\n\t\t\t\tctx.fillText(category, x + 10, yOffset)\n\t\t\t\tyOffset += 20\n\n\t\t\t\t// Properties\n\t\t\t\tctx.font = '11px sans-serif'\n\t\t\t\tfor (const prop of props) {\n\t\t\t\t\tctx.fillStyle = '#ffffff'\n\t\t\t\t\tctx.fillText(prop.name, x + 15, yOffset)\n\n\t\t\t\t\tctx.fillStyle = prop.editable ? '#00ff00' : '#888888'\n\t\t\t\t\tctx.textAlign = 'right'\n\t\t\t\t\tctx.fillText(String(prop.value), x + this.#width - 10, yOffset)\n\t\t\t\t\tctx.textAlign = 'left'\n\n\t\t\t\t\tyOffset += 18\n\t\t\t\t}\n\t\t\t\tyOffset += 10\n\t\t\t}\n\t\t} else {\n\t\t\tctx.fillStyle = '#888888'\n\t\t\tctx.font = '12px sans-serif'\n\t\t\tctx.fillText('No EntityInterface selected', x + 10, 50)\n\t\t}\n\n\t\tctx.restore()\n\t}\n\n\tdestroy(): void {\n\t\tthis.#selectedEntity = undefined\n\t\tthis.#properties = []\n\t\tthis.#watchers.clear()\n\t\tthis.#expandedCategories.clear()\n\t\tthis.#listeners.entitySelect.clear()\n\t\tthis.#listeners.propertyChange.clear()\n\t\tthis.#listeners.open.clear()\n\t\tthis.#listeners.close.clear()\n\t}\n\n\t// =========================================================================\n\t// Private Methods\n\t// =========================================================================\n\n\t#addProperty(\n\t\tname: string,\n\t\tvalue: unknown,\n\t\ttype: 'string' | 'number' | 'boolean' | 'object' | 'array',\n\t\tcategory: string,\n\t\treadonly: boolean,\n\t): void {\n\t\tconst editable = !readonly && (this.#editableProperties.size === 0 || this.#editableProperties.has(name))\n\n\t\tthis.#properties.push({\n\t\t\tname,\n\t\t\tvalue,\n\t\t\ttype,\n\t\t\tcategory,\n\t\t\teditable,\n\t\t})\n\t}\n}\n","import type {\n\tCommandConsoleInterface,\n\tCommandConsoleOptions,\n\tCommandConsoleState,\n\tCommandDef,\n\tCommandContextDef,\n\tConsoleLogEntryDef,\n\tInputState,\n\tUnsubscribe,\n} from '../../types.js'\nimport { now } from '../../helpers.js'\nimport {\n\tDEFAULT_CONSOLE_MAX_HISTORY,\n\tDEFAULT_CONSOLE_MAX_LOG_ENTRIES,\n\tDEFAULT_CONSOLE_HEIGHT,\n} from '../../constants.js'\n\n/**\n * Command console for developer debugging.\n *\n * @example\n * ```ts\n * const console = createCommandConsole({\n * toggleKey: '`',\n * })\n *\n * console.registerCommand({\n * id: 'teleport',\n * name: 'teleport',\n * description: 'Teleport player to position',\n * args: [{ name: 'x', type: 'number' }, { name: 'y', type: 'number' }],\n * execute: (args) => `Teleported to ${args.x}, ${args.y}`,\n * })\n *\n * console.ToggleInterface()\n * ```\n */\nexport class CommandConsole implements CommandConsoleInterface {\n\t#commands: Map<string, CommandDef> = new Map()\n\t#aliases: Map<string, string> = new Map()\n\t#log: ConsoleLogEntryDef[] = []\n\t#commandHistory: string[] = []\n\t#historyIndex = -1\n\t#inputValue = ''\n\t#suggestions: string[] = []\n\t#selectedSuggestionIndex = -1\n\t#context: Partial<CommandContextDef> = {}\n\n\t#isOpen = false\n\t#enabled: boolean\n\t#toggleKey: string\n\t#maxHistory: number\n\t#maxLogEntries: number\n\t#position: 'top' | 'bottom'\n\t#height: number\n\t#backgroundColor: string\n\t#textColor: string\n\t#fontSize: number\n\n\t#listeners = {\n\t\topen: new Set<() => void>(),\n\t\tclose: new Set<() => void>(),\n\t\tcommand: new Set<(command: string, args: Record<string, unknown>) => void>(),\n\t\tlog: new Set<(entry: ConsoleLogEntryDef) => void>(),\n\t}\n\n\tconstructor(options?: CommandConsoleOptions) {\n\t\tthis.#enabled = options?.enabled ?? true\n\t\tthis.#toggleKey = options?.toggleKey ?? '`'\n\t\tthis.#maxHistory = options?.maxHistory ?? DEFAULT_CONSOLE_MAX_HISTORY\n\t\tthis.#maxLogEntries = options?.maxLogEntries ?? DEFAULT_CONSOLE_MAX_LOG_ENTRIES\n\t\tthis.#position = options?.position ?? 'bottom'\n\t\tthis.#height = options?.height ?? DEFAULT_CONSOLE_HEIGHT\n\t\tthis.#backgroundColor = options?.backgroundColor ?? 'rgba(0, 0, 0, 0.9)'\n\t\tthis.#textColor = options?.textColor ?? '#00ff00'\n\t\tthis.#fontSize = options?.fontSize ?? 14\n\n\t\t// Register hooks\n\t\tif (options?.onOpen) this.#listeners.open.add(options.onOpen)\n\t\tif (options?.onClose) this.#listeners.close.add(options.onClose)\n\t\tif (options?.onCommand) this.#listeners.command.add(options.onCommand)\n\t\tif (options?.onLog) this.#listeners.log.add(options.onLog)\n\n\t\t// Register built-in commands\n\t\tthis.#registerBuiltinCommands()\n\t}\n\n\t// =========================================================================\n\t// Accessors\n\t// =========================================================================\n\n\tgetState(): CommandConsoleState {\n\t\treturn {\n\t\t\tisOpen: this.#isOpen,\n\t\t\tinputValue: this.#inputValue,\n\t\t\thistory: [...this.#log],\n\t\t\tcommandHistory: [...this.#commandHistory],\n\t\t\thistoryIndex: this.#historyIndex,\n\t\t\tsuggestions: [...this.#suggestions],\n\t\t\tselectedSuggestionIndex: this.#selectedSuggestionIndex,\n\t\t}\n\t}\n\n\tisOpen(): boolean {\n\t\treturn this.#isOpen\n\t}\n\n\tgetCommand(name: string): CommandDef | undefined {\n\t\treturn this.#commands.get(name) ?? this.#commands.get(this.#aliases.get(name) ?? '')\n\t}\n\n\tgetCommands(): readonly CommandDef[] {\n\t\treturn Array.from(this.#commands.values())\n\t}\n\n\tgetCommandsByCategory(category: string): readonly CommandDef[] {\n\t\treturn Array.from(this.#commands.values()).filter(c => c.category === category)\n\t}\n\n\tgetInput(): string {\n\t\treturn this.#inputValue\n\t}\n\n\t// =========================================================================\n\t// PanelInterface Control\n\t// =========================================================================\n\n\topen(): void {\n\t\tif (!this.#enabled || this.#isOpen) return\n\n\t\tthis.#isOpen = true\n\t\tfor (const callback of this.#listeners.open) {\n\t\t\tcallback()\n\t\t}\n\t}\n\n\tclose(): void {\n\t\tif (!this.#isOpen) return\n\n\t\tthis.#isOpen = false\n\t\tthis.#suggestions = []\n\t\tthis.#selectedSuggestionIndex = -1\n\n\t\tfor (const callback of this.#listeners.close) {\n\t\t\tcallback()\n\t\t}\n\t}\n\n\ttoggle(): void {\n\t\tif (this.#isOpen) {\n\t\t\tthis.close()\n\t\t} else {\n\t\t\tthis.open()\n\t\t}\n\t}\n\n\t// =========================================================================\n\t// Command Management\n\t// =========================================================================\n\n\tregisterCommand(command: CommandDef): void {\n\t\tthis.#commands.set(command.name, command)\n\n\t\t// Register aliases\n\t\tif (command.aliases) {\n\t\t\tfor (const alias of command.aliases) {\n\t\t\t\tthis.#aliases.set(alias, command.name)\n\t\t\t}\n\t\t}\n\t}\n\n\tunregisterCommand(name: string): void {\n\t\tconst command = this.#commands.get(name)\n\t\tif (command) {\n\t\t\t// Remove aliases\n\t\t\tif (command.aliases) {\n\t\t\t\tfor (const alias of command.aliases) {\n\t\t\t\t\tthis.#aliases.delete(alias)\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.#commands.delete(name)\n\t\t}\n\t}\n\n\t// =========================================================================\n\t// Execution\n\t// =========================================================================\n\n\texecute(input: string): void {\n\t\tif (!input.trim()) return\n\n\t\t// Log input\n\t\tthis.#addLog('input', `> ${input}`)\n\n\t\t// Add to history\n\t\tthis.#commandHistory.unshift(input)\n\t\tif (this.#commandHistory.length > this.#maxHistory) {\n\t\t\tthis.#commandHistory.pop()\n\t\t}\n\t\tthis.#historyIndex = -1\n\n\t\t// Parse command\n\t\tconst parts = input.trim().split(/\\s+/)\n\t\tconst commandName = parts[0]?.toLowerCase() ?? ''\n\t\tconst argStrings = parts.slice(1)\n\n\t\tconst command = this.getCommand(commandName)\n\n\t\tif (!command) {\n\t\t\tthis.log(`Unknown command: ${commandName}`, 'error')\n\t\t\treturn\n\t\t}\n\n\t\t// Parse arguments\n\t\tconst args: Record<string, unknown> = {}\n\t\tconst commandArgs = command.args ?? []\n\n\t\tfor (let i = 0; i < commandArgs.length; i++) {\n\t\t\tconst argDef = commandArgs[i]\n\t\t\tif (!argDef) continue\n\n\t\t\tconst argValue = argStrings[i]\n\n\t\t\tif (argValue === undefined) {\n\t\t\t\tif (argDef.required) {\n\t\t\t\t\tthis.log(`Missing required argument: ${argDef.name}`, 'error')\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\targs[argDef.name] = argDef.defaultValue\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Type conversion\n\t\t\tswitch (argDef.type) {\n\t\t\t\tcase 'number':\n\t\t\t\t\targs[argDef.name] = parseFloat(argValue)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'boolean':\n\t\t\t\t\targs[argDef.name] = argValue === 'true' || argValue === '1'\n\t\t\t\t\tbreak\n\t\t\t\tdefault:\n\t\t\t\t\targs[argDef.name] = argValue\n\t\t\t}\n\t\t}\n\n\t\t// Execute\n\t\ttry {\n\t\t\tconst context: CommandContextDef = {\n\t\t\t\tengine: this.#context.engine as CommandContextDef['engine'],\n\t\t\t\t...(this.#context.scene ? { scene: this.#context.scene } : {}),\n\t\t\t\t...(this.#context.store ? { store: this.#context.store } : {}),\n\t\t\t\tlog: (msg) => this.log(msg, 'output'),\n\t\t\t\twarn: (msg) => this.log(msg, 'warning'),\n\t\t\t\terror: (msg) => this.log(msg, 'error'),\n\t\t\t}\n\n\t\t\tconst result = command.execute(args, context)\n\n\t\t\tif (result) {\n\t\t\t\tthis.log(result, 'output')\n\t\t\t}\n\n\t\t\tfor (const callback of this.#listeners.command) {\n\t\t\t\tcallback(commandName, args)\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tthis.log(`Error: ${err instanceof Error ? err.message : String(err)}`, 'error')\n\t\t}\n\n\t\t// Clear input\n\t\tthis.#inputValue = ''\n\t\tthis.#suggestions = []\n\t}\n\n\tlog(message: string, type: 'output' | 'info' | 'warning' | 'error' = 'output'): void {\n\t\tthis.#addLog(type, message)\n\t}\n\n\tclear(): void {\n\t\tthis.#log = []\n\t}\n\n\t// =========================================================================\n\t// Input Control\n\t// =========================================================================\n\n\tsetInput(value: string): void {\n\t\tthis.#inputValue = value\n\t\tthis.#updateSuggestions()\n\t}\n\n\tautocomplete(): void {\n\t\tif (this.#suggestions.length === 0) return\n\n\t\tif (this.#selectedSuggestionIndex >= 0 && this.#selectedSuggestionIndex < this.#suggestions.length) {\n\t\t\tthis.#inputValue = this.#suggestions[this.#selectedSuggestionIndex] ?? ''\n\t\t} else if (this.#suggestions.length === 1) {\n\t\t\tthis.#inputValue = this.#suggestions[0] ?? ''\n\t\t}\n\n\t\tthis.#suggestions = []\n\t\tthis.#selectedSuggestionIndex = -1\n\t}\n\n\thistoryUp(): void {\n\t\tif (this.#commandHistory.length === 0) return\n\n\t\tthis.#historyIndex = Math.min(this.#historyIndex + 1, this.#commandHistory.length - 1)\n\t\tthis.#inputValue = this.#commandHistory[this.#historyIndex] ?? ''\n\t}\n\n\thistoryDown(): void {\n\t\tif (this.#historyIndex <= 0) {\n\t\t\tthis.#historyIndex = -1\n\t\t\tthis.#inputValue = ''\n\t\t\treturn\n\t\t}\n\n\t\tthis.#historyIndex--\n\t\tthis.#inputValue = this.#commandHistory[this.#historyIndex] ?? ''\n\t}\n\n\tselectSuggestion(index: number): void {\n\t\tthis.#selectedSuggestionIndex = index\n\t}\n\n\tsetContext(context: Partial<CommandContextDef>): void {\n\t\tthis.#context = { ...this.#context, ...context }\n\t}\n\n\t// =========================================================================\n\t// Event Subscriptions\n\t// =========================================================================\n\n\tonOpen(callback: () => void): Unsubscribe {\n\t\tthis.#listeners.open.add(callback)\n\t\treturn () => this.#listeners.open.delete(callback)\n\t}\n\n\tonClose(callback: () => void): Unsubscribe {\n\t\tthis.#listeners.close.add(callback)\n\t\treturn () => this.#listeners.close.delete(callback)\n\t}\n\n\tonCommand(callback: (command: string, args: Record<string, unknown>) => void): Unsubscribe {\n\t\tthis.#listeners.command.add(callback)\n\t\treturn () => this.#listeners.command.delete(callback)\n\t}\n\n\tonLog(callback: (entry: ConsoleLogEntryDef) => void): Unsubscribe {\n\t\tthis.#listeners.log.add(callback)\n\t\treturn () => this.#listeners.log.delete(callback)\n\t}\n\n\t// =========================================================================\n\t// Lifecycle\n\t// =========================================================================\n\n\tupdate(_inputState: InputState): void {\n\t\t// Note: ToggleInterface key detection is handled externally via KeyboardManagerInterface\n\t\t// The game loop should call ToggleInterface() when the ToggleInterface key is pressed\n\t\tif (!this.#enabled) return\n\t}\n\n\trender(ctx: CanvasRenderingContext2D): void {\n\t\tif (!this.#isOpen || !this.#enabled) return\n\n\t\tconst width = ctx.canvas.width\n\t\tconst y = this.#position === 'top' ? 0 : ctx.canvas.height - this.#height\n\n\t\tctx.save()\n\n\t\t// Background\n\t\tctx.fillStyle = this.#backgroundColor\n\t\tctx.fillRect(0, y, width, this.#height)\n\n\t\t// Log entries\n\t\tctx.fillStyle = this.#textColor\n\t\tctx.font = `${this.#fontSize}px monospace`\n\t\tctx.textAlign = 'left'\n\n\t\tconst lineHeight = this.#fontSize + 4\n\t\tconst maxLines = Math.floor((this.#height - 30) / lineHeight)\n\t\tconst visibleLog = this.#log.slice(-maxLines)\n\n\t\tfor (let i = 0; i < visibleLog.length; i++) {\n\t\t\tconst entry = visibleLog[i]\n\t\t\tif (!entry) continue\n\n\t\t\tswitch (entry.type) {\n\t\t\t\tcase 'error':\n\t\t\t\t\tctx.fillStyle = '#ff5555'\n\t\t\t\t\tbreak\n\t\t\t\tcase 'warning':\n\t\t\t\t\tctx.fillStyle = '#ffff55'\n\t\t\t\t\tbreak\n\t\t\t\tcase 'info':\n\t\t\t\t\tctx.fillStyle = '#5555ff'\n\t\t\t\t\tbreak\n\t\t\t\tcase 'input':\n\t\t\t\t\tctx.fillStyle = '#888888'\n\t\t\t\t\tbreak\n\t\t\t\tdefault:\n\t\t\t\t\tctx.fillStyle = this.#textColor\n\t\t\t}\n\n\t\t\tctx.fillText(entry.message, 10, y + 20 + i * lineHeight)\n\t\t}\n\n\t\t// Input line\n\t\tconst inputY = y + this.#height - 25\n\t\tctx.fillStyle = 'rgba(50, 50, 50, 0.8)'\n\t\tctx.fillRect(0, inputY - 5, width, 30)\n\n\t\tctx.fillStyle = this.#textColor\n\t\tctx.fillText(`> ${this.#inputValue}_`, 10, inputY + 12)\n\n\t\t// Suggestions\n\t\tif (this.#suggestions.length > 0) {\n\t\t\tconst sugY = inputY - 5 - this.#suggestions.length * lineHeight\n\t\t\tctx.fillStyle = 'rgba(40, 40, 40, 0.95)'\n\t\t\tctx.fillRect(10, sugY, 200, this.#suggestions.length * lineHeight)\n\n\t\t\tfor (let i = 0; i < this.#suggestions.length; i++) {\n\t\t\t\tctx.fillStyle = i === this.#selectedSuggestionIndex ? '#4299e1' : '#aaaaaa'\n\t\t\t\tctx.fillText(this.#suggestions[i] ?? '', 15, sugY + (i + 1) * lineHeight - 5)\n\t\t\t}\n\t\t}\n\n\t\tctx.restore()\n\t}\n\n\tdestroy(): void {\n\t\tthis.#commands.clear()\n\t\tthis.#aliases.clear()\n\t\tthis.#log = []\n\t\tthis.#commandHistory = []\n\t\tthis.#listeners.open.clear()\n\t\tthis.#listeners.close.clear()\n\t\tthis.#listeners.command.clear()\n\t\tthis.#listeners.log.clear()\n\t}\n\n\t// =========================================================================\n\t// Private Methods\n\t// =========================================================================\n\n\t#addLog(type: ConsoleLogEntryDef['type'], message: string, data?: unknown): void {\n\t\tconst entry: ConsoleLogEntryDef = {\n\t\t\ttype,\n\t\t\tmessage,\n\t\t\ttimestamp: now(),\n\t\t\tdata,\n\t\t}\n\n\t\tthis.#log.push(entry)\n\n\t\tif (this.#log.length > this.#maxLogEntries) {\n\t\t\tthis.#log.shift()\n\t\t}\n\n\t\tfor (const callback of this.#listeners.log) {\n\t\t\tcallback(entry)\n\t\t}\n\t}\n\n\t#updateSuggestions(): void {\n\t\tif (!this.#inputValue) {\n\t\t\tthis.#suggestions = []\n\t\t\tthis.#selectedSuggestionIndex = -1\n\t\t\treturn\n\t\t}\n\n\t\tconst input = this.#inputValue.toLowerCase()\n\t\tthis.#suggestions = Array.from(this.#commands.keys())\n\t\t\t.filter(name => name.toLowerCase().startsWith(input))\n\t\t\t.slice(0, 5)\n\t\tthis.#selectedSuggestionIndex = -1\n\t}\n\n\t#registerBuiltinCommands(): void {\n\t\tthis.registerCommand({\n\t\t\tid: 'help',\n\t\t\tname: 'help',\n\t\t\tdescription: 'List all commands',\n\t\t\texecute: () => {\n\t\t\t\tconst lines = ['Available commands:']\n\t\t\t\tfor (const cmd of this.#commands.values()) {\n\t\t\t\t\tlines.push(` ${cmd.name} - ${cmd.description}`)\n\t\t\t\t}\n\t\t\t\treturn lines.join('\\n')\n\t\t\t},\n\t\t})\n\n\t\tthis.registerCommand({\n\t\t\tid: 'clear',\n\t\t\tname: 'clear',\n\t\t\tdescription: 'Clear console output',\n\t\t\texecute: () => {\n\t\t\t\tthis.clear()\n\t\t\t},\n\t\t})\n\n\t\tthis.registerCommand({\n\t\t\tid: 'echo',\n\t\t\tname: 'echo',\n\t\t\tdescription: 'Echo a message',\n\t\t\targs: [{ name: 'message', type: 'string', required: true }],\n\t\t\texecute: (args) => String(args.message),\n\t\t})\n\t}\n}\n","import type {\n\tCullingSystemInterface,\n\tCullingOptions,\n\tCullingStats,\n\tCullingStrategy,\n\tEntityInterface,\n\tCameraInterface,\n} from '../../types.js'\nimport { now } from '../../helpers.js'\n\n/**\n * Culling system for optimizing rendering by excluding off-screen entities.\n *\n * @example\n * ```ts\n * const culling = createCullingSystem({\n * strategy: 'frustum',\n * margin: 50,\n * })\n *\n * const visible = culling.getVisibleEntities(entities, CameraInterface)\n * ```\n */\nexport class CullingSystem implements CullingSystemInterface {\n\t#enabled: boolean\n\t#strategy: CullingStrategy\n\t#margin: number\n\t#stats: CullingStats = {\n\t\ttotalEntities: 0,\n\t\tvisibleEntities: 0,\n\t\tculledEntities: 0,\n\t\tcullingRatio: 0,\n\t\tlastUpdateTime: 0,\n\t}\n\n\t#viewBounds = { x: 0, y: 0, width: 0, height: 0 }\n\n\tconstructor(options?: CullingOptions) {\n\t\tthis.#enabled = options?.enabled ?? true\n\t\tthis.#strategy = options?.strategy ?? 'frustum'\n\t\tthis.#margin = options?.margin ?? 0\n\t}\n\n\t// =========================================================================\n\t// Accessors\n\t// =========================================================================\n\n\tgetOptions(): CullingOptions {\n\t\treturn {\n\t\t\tenabled: this.#enabled,\n\t\t\tstrategy: this.#strategy,\n\t\t\tmargin: this.#margin,\n\t\t}\n\t}\n\n\tgetStats(): CullingStats {\n\t\treturn { ...this.#stats }\n\t}\n\n\tisEnabled(): boolean {\n\t\treturn this.#enabled\n\t}\n\n\t// =========================================================================\n\t// Control\n\t// =========================================================================\n\n\tenable(): void {\n\t\tthis.#enabled = true\n\t}\n\n\tdisable(): void {\n\t\tthis.#enabled = false\n\t}\n\n\tsetStrategy(strategy: CullingStrategy): void {\n\t\tthis.#strategy = strategy\n\t}\n\n\tsetMargin(margin: number): void {\n\t\tthis.#margin = Math.max(0, margin)\n\t}\n\n\t// =========================================================================\n\t// Culling Operations\n\t// =========================================================================\n\n\tisVisible(EntityInterface: EntityInterface): boolean {\n\t\tif (!this.#enabled) return true\n\n\t\tconst positionable = EntityInterface as unknown as {\n\t\t\tgetX?: () => number\n\t\t\tgetY?: () => number\n\t\t\tgetWidth?: () => number\n\t\t\tgetHeight?: () => number\n\t\t}\n\n\t\tif (typeof positionable.getX !== 'function' || typeof positionable.getY !== 'function') {\n\t\t\treturn true // Can't determine position, assume visible\n\t\t}\n\n\t\tconst x = positionable.getX()\n\t\tconst y = positionable.getY()\n\t\tconst width = typeof positionable.getWidth === 'function' ? positionable.getWidth() : 0\n\t\tconst height = typeof positionable.getHeight === 'function' ? positionable.getHeight() : 0\n\n\t\treturn this.#isInView(x, y, width, height)\n\t}\n\n\tgetVisibleEntities(entities: readonly EntityInterface[], CameraInterface: CameraInterface): readonly EntityInterface[] {\n\t\tthis.update(CameraInterface)\n\t\treturn this.cullEntities(entities, CameraInterface)\n\t}\n\n\tcullEntities(entities: readonly EntityInterface[], _camera: CameraInterface): readonly EntityInterface[] {\n\t\tconst startTime = now()\n\n\t\tif (!this.#enabled) {\n\t\t\tthis.#stats = {\n\t\t\t\ttotalEntities: entities.length,\n\t\t\t\tvisibleEntities: entities.length,\n\t\t\t\tculledEntities: 0,\n\t\t\t\tcullingRatio: 0,\n\t\t\t\tlastUpdateTime: now() - startTime,\n\t\t\t}\n\t\t\treturn entities\n\t\t}\n\n\t\tconst visible: EntityInterface[] = []\n\n\t\tfor (const EntityInterface of entities) {\n\t\t\tif (this.isVisible(EntityInterface)) {\n\t\t\t\tvisible.push(EntityInterface)\n\t\t\t}\n\t\t}\n\n\t\tthis.#stats = {\n\t\t\ttotalEntities: entities.length,\n\t\t\tvisibleEntities: visible.length,\n\t\t\tculledEntities: entities.length - visible.length,\n\t\t\tcullingRatio: entities.length > 0 ? (entities.length - visible.length) / entities.length : 0,\n\t\t\tlastUpdateTime: now() - startTime,\n\t\t}\n\n\t\treturn visible\n\t}\n\n\t// =========================================================================\n\t// Lifecycle\n\t// =========================================================================\n\n\tupdate(CameraInterface: CameraInterface): void {\n\t\t// Update view bounds from CameraInterface\n\t\tthis.#viewBounds = {\n\t\t\tx: CameraInterface.getX() - this.#margin,\n\t\t\ty: CameraInterface.getY() - this.#margin,\n\t\t\twidth: CameraInterface.getWidth() + this.#margin * 2,\n\t\t\theight: CameraInterface.getHeight() + this.#margin * 2,\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.#stats = {\n\t\t\ttotalEntities: 0,\n\t\t\tvisibleEntities: 0,\n\t\t\tculledEntities: 0,\n\t\t\tcullingRatio: 0,\n\t\t\tlastUpdateTime: 0,\n\t\t}\n\t}\n\n\t// =========================================================================\n\t// Private Methods\n\t// =========================================================================\n\n\t#isInView(x: number, y: number, width: number, height: number): boolean {\n\t\tswitch (this.#strategy) {\n\t\t\tcase 'none':\n\t\t\t\treturn true\n\t\t\tcase 'frustum':\n\t\t\t\treturn this.#frustumCheck(x, y, width, height)\n\t\t\tcase 'distance':\n\t\t\t\treturn this.#distanceCheck(x, y)\n\t\t\tcase 'occlusion':\n\t\t\t\t// Occlusion culling would require depth buffer\n\t\t\t\t// Fall back to frustum check\n\t\t\t\treturn this.#frustumCheck(x, y, width, height)\n\t\t\tdefault:\n\t\t\t\treturn true\n\t\t}\n\t}\n\n\t#frustumCheck(x: number, y: number, width: number, height: number): boolean {\n\t\t// For 2D, frustum check is essentially bounds check\n\t\treturn !(\n\t\t\tx + width < this.#viewBounds.x ||\n\t\t\tx > this.#viewBounds.x + this.#viewBounds.width ||\n\t\t\ty + height < this.#viewBounds.y ||\n\t\t\ty > this.#viewBounds.y + this.#viewBounds.height\n\t\t)\n\t}\n\n\t#distanceCheck(x: number, y: number): boolean {\n\t\tconst centerX = this.#viewBounds.x + this.#viewBounds.width / 2\n\t\tconst centerY = this.#viewBounds.y + this.#viewBounds.height / 2\n\t\tconst maxDistance = Math.max(this.#viewBounds.width, this.#viewBounds.height) / 2 + this.#margin\n\n\t\tconst dx = x - centerX\n\t\tconst dy = y - centerY\n\t\treturn dx * dx + dy * dy <= maxDistance * maxDistance\n\t}\n}\n","import type {\n\tLODSystemInterface,\n\tLODSystemOptions,\n\tLODConfig,\n\tLODLevel,\n\tEntityInterface,\n} from '../../types.js'\n\n/**\n * Level of Detail system for optimizing rendering at different distances.\n *\n * @example\n * ```ts\n * const lod = createLODSystem({\n * enabled: true,\n * updateInterval: 100,\n * })\n *\n * lod.registerConfig({\n * id: 'enemy-lod',\n * entityType: 'enemy',\n * levels: [\n * { level: 0, distance: 100, quality: 'high' },\n * { level: 1, distance: 300, quality: 'medium' },\n * { level: 2, distance: 500, quality: 'low' },\n * ],\n * })\n *\n * lod.update(player.x, player.y, entities)\n * ```\n */\nexport class LODSystem implements LODSystemInterface {\n\t#enabled: boolean\n\t#updateInterval: number\n\t#defaultLevels: readonly LODLevel[]\n\t#referencePoint: 'camera' | 'player'\n\n\t#configs: Map<string, LODConfig> = new Map()\n\t#entityLODs: Map<string, number> = new Map()\n\t#lastUpdateTime = 0\n\n\tconstructor(options?: LODSystemOptions) {\n\t\tthis.#enabled = options?.enabled ?? true\n\t\tthis.#updateInterval = options?.updateInterval ?? 100\n\t\tthis.#referencePoint = options?.referencePoint ?? 'camera'\n\t\tthis.#defaultLevels = options?.defaultLevels ?? [\n\t\t\t{ level: 0, distance: 200, quality: 'high' },\n\t\t\t{ level: 1, distance: 500, quality: 'medium' },\n\t\t\t{ level: 2, distance: 1000, quality: 'low' },\n\t\t\t{ level: 3, distance: Infinity, quality: 'minimal' },\n\t\t]\n\t}\n\n\t// =========================================================================\n\t// Accessors\n\t// =========================================================================\n\n\tgetOptions(): LODSystemOptions {\n\t\treturn {\n\t\t\tenabled: this.#enabled,\n\t\t\tupdateInterval: this.#updateInterval,\n\t\t\tdefaultLevels: this.#defaultLevels,\n\t\t\treferencePoint: this.#referencePoint,\n\t\t}\n\t}\n\n\tisEnabled(): boolean {\n\t\treturn this.#enabled\n\t}\n\n\tgetConfig(entityType: string): LODConfig | undefined {\n\t\treturn this.#configs.get(entityType)\n\t}\n\n\tgetEntityLOD(entityId: string): number {\n\t\treturn this.#entityLODs.get(entityId) ?? 0\n\t}\n\n\t// =========================================================================\n\t// Control\n\t// =========================================================================\n\n\tenable(): void {\n\t\tthis.#enabled = true\n\t}\n\n\tdisable(): void {\n\t\tthis.#enabled = false\n\t}\n\n\tsetReferencePoint(point: 'camera' | 'player'): void {\n\t\tthis.#referencePoint = point\n\t}\n\n\t// =========================================================================\n\t// Config Management\n\t// =========================================================================\n\n\tregisterConfig(config: LODConfig): void {\n\t\tthis.#configs.set(config.entityType, config)\n\t}\n\n\tunregisterConfig(entityType: string): void {\n\t\tthis.#configs.delete(entityType)\n\t}\n\n\t// =========================================================================\n\t// LOD Operations\n\t// =========================================================================\n\n\tgetCurrentLevel(EntityInterface: EntityInterface, distance: number): LODLevel | undefined {\n\t\t// Get EntityInterface type\n\t\tconst typed = EntityInterface as unknown as { type?: string }\n\t\tconst entityType = typed.type ?? 'default'\n\n\t\tconst config = this.#configs.get(entityType)\n\t\tconst levels = config?.levels ?? this.#defaultLevels\n\n\t\t// Find appropriate level based on distance\n\t\tfor (const level of levels) {\n\t\t\tif (distance <= level.distance) {\n\t\t\t\treturn level\n\t\t\t}\n\t\t}\n\n\t\t// Return last level if beyond all distances\n\t\treturn levels[levels.length - 1]\n\t}\n\n\tsetEntityLOD(entityId: string, level: number): void {\n\t\tthis.#entityLODs.set(entityId, level)\n\t}\n\n\t// =========================================================================\n\t// Lifecycle\n\t// =========================================================================\n\n\tupdate(referenceX: number, referenceY: number, entities: readonly EntityInterface[]): void {\n\t\tif (!this.#enabled) return\n\n\t\tconst currentTime = Date.now()\n\t\tif (currentTime - this.#lastUpdateTime < this.#updateInterval) {\n\t\t\treturn\n\t\t}\n\t\tthis.#lastUpdateTime = currentTime\n\n\t\tfor (const EntityInterface of entities) {\n\t\t\tconst positionable = EntityInterface as unknown as {\n\t\t\t\tgetX?: () => number\n\t\t\t\tgetY?: () => number\n\t\t\t}\n\n\t\t\tif (typeof positionable.getX !== 'function' || typeof positionable.getY !== 'function') {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst dx = positionable.getX() - referenceX\n\t\t\tconst dy = positionable.getY() - referenceY\n\t\t\tconst distance = Math.sqrt(dx * dx + dy * dy)\n\n\t\t\tconst level = this.getCurrentLevel(EntityInterface, distance)\n\t\t\tif (level) {\n\t\t\t\tthis.#entityLODs.set(EntityInterface.id, level.level)\n\t\t\t}\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.#configs.clear()\n\t\tthis.#entityLODs.clear()\n\t}\n}\n","import type {\r\n\tCrosshairState,\r\n\tCrosshairStyle,\r\n\tCrosshairSystemInterface,\r\n\tCrosshairSystemOptions,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\n/**\r\n * CrosshairSystem implementation for aiming cursor.\r\n */\r\nexport class CrosshairSystem implements CrosshairSystemInterface {\r\n\t#screenX = 0\r\n\t#screenY = 0\r\n\t#worldX = 0\r\n\t#worldY = 0\r\n\t#isActive = false\r\n\t#visible = true\r\n\r\n\t#style: CrosshairStyle\r\n\t#size: number\r\n\t#thickness: number\r\n\t#color: string\r\n\t#activeColor: string\r\n\t#gap: number\r\n\t#outline: boolean\r\n\t#outlineColor: string\r\n\t#pulseOnActive: boolean\r\n\t#hideOnMobile: boolean\r\n\treadonly #customRenderer: ((ctx: CanvasRenderingContext2D, state: CrosshairState) => void) | undefined\r\n\r\n\treadonly #listeners = {\r\n\t\tpositionChange: new Set<(screenX: number, screenY: number, worldX: number, worldY: number) => void>(),\r\n\t\tactiveChange: new Set<(isActive: boolean) => void>(),\r\n\t}\r\n\r\n\tconstructor(options?: CrosshairSystemOptions) {\r\n\t\tthis.#style = options?.style ?? 'cross'\r\n\t\tthis.#size = options?.size ?? 20\r\n\t\tthis.#thickness = options?.thickness ?? 2\r\n\t\tthis.#color = options?.color ?? '#ffffff'\r\n\t\tthis.#activeColor = options?.activeColor ?? '#ff4444'\r\n\t\tthis.#gap = options?.gap ?? 4\r\n\t\tthis.#outline = options?.outline ?? true\r\n\t\tthis.#outlineColor = options?.outlineColor ?? '#000000'\r\n\t\tthis.#pulseOnActive = options?.pulseOnActive ?? true\r\n\t\tthis.#hideOnMobile = options?.hideOnMobile ?? true\r\n\t\tthis.#customRenderer = options?.customRenderer\r\n\r\n\t\tif (options?.onPositionChange) this.#listeners.positionChange.add(options.onPositionChange)\r\n\t\tif (options?.onActiveChange) this.#listeners.activeChange.add(options.onActiveChange)\r\n\t}\r\n\r\n\t// === ACCESSORS ===\r\n\r\n\tgetState(): CrosshairState {\r\n\t\treturn {\r\n\t\t\tscreenX: this.#screenX,\r\n\t\t\tscreenY: this.#screenY,\r\n\t\t\tworldX: this.#worldX,\r\n\t\t\tworldY: this.#worldY,\r\n\t\t\tisActive: this.#isActive,\r\n\t\t\tvisible: this.#visible,\r\n\t\t}\r\n\t}\r\n\r\n\tisVisible(): boolean {\r\n\t\treturn this.#visible\r\n\t}\r\n\r\n\tisActive(): boolean {\r\n\t\treturn this.#isActive\r\n\t}\r\n\r\n\t// === MUTATORS ===\r\n\r\n\tsetPosition(screenX: number, screenY: number, worldX: number, worldY: number): void {\r\n\t\tconst changed =\r\n\t\t\tthis.#screenX !== screenX ||\r\n\t\t\tthis.#screenY !== screenY ||\r\n\t\t\tthis.#worldX !== worldX ||\r\n\t\t\tthis.#worldY !== worldY\r\n\r\n\t\tthis.#screenX = screenX\r\n\t\tthis.#screenY = screenY\r\n\t\tthis.#worldX = worldX\r\n\t\tthis.#worldY = worldY\r\n\r\n\t\tif (changed) {\r\n\t\t\tthis.#listeners.positionChange.forEach(cb => cb(screenX, screenY, worldX, worldY))\r\n\t\t}\r\n\t}\r\n\r\n\tsetActive(active: boolean): void {\r\n\t\tif (this.#isActive !== active) {\r\n\t\t\tthis.#isActive = active\r\n\t\t\tthis.#listeners.activeChange.forEach(cb => cb(active))\r\n\t\t}\r\n\t}\r\n\r\n\tsetVisible(visible: boolean): void {\r\n\t\tthis.#visible = visible\r\n\t}\r\n\r\n\tsetStyle(style: CrosshairStyle): void {\r\n\t\tthis.#style = style\r\n\t}\r\n\r\n\tsetColor(color: string): void {\r\n\t\tthis.#color = color\r\n\t}\r\n\r\n\tsetActiveColor(color: string): void {\r\n\t\tthis.#activeColor = color\r\n\t}\r\n\r\n\tsetSize(size: number): void {\r\n\t\tthis.#size = size\r\n\t}\r\n\r\n\t// === SUBSCRIPTIONS ===\r\n\r\n\tonPositionChange(callback: (screenX: number, screenY: number, worldX: number, worldY: number) => void): Unsubscribe {\r\n\t\tthis.#listeners.positionChange.add(callback)\r\n\t\treturn () => this.#listeners.positionChange.delete(callback)\r\n\t}\r\n\r\n\tonActiveChange(callback: (isActive: boolean) => void): Unsubscribe {\r\n\t\tthis.#listeners.activeChange.add(callback)\r\n\t\treturn () => this.#listeners.activeChange.delete(callback)\r\n\t}\r\n\r\n\t// === RENDERING ===\r\n\r\n\trender(ctx: CanvasRenderingContext2D): void {\r\n\t\tif (!this.#visible) return\r\n\r\n\t\tconst state = this.getState()\r\n\r\n\t\t// Use custom renderer if provided\r\n\t\tif (this.#customRenderer) {\r\n\t\t\tthis.#customRenderer(ctx, state)\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\tconst x = this.#screenX\r\n\t\tconst y = this.#screenY\r\n\t\tconst color = this.#isActive ? this.#activeColor : this.#color\r\n\t\tconst size = this.#size\r\n\t\tconst thickness = this.#thickness\r\n\t\tconst gap = this.#gap\r\n\r\n\t\t// Apply pulse effect when active\r\n\t\tlet scale = 1\r\n\t\tif (this.#pulseOnActive && this.#isActive) {\r\n\t\t\tscale = 1 + Math.sin(Date.now() / 100) * 0.1\r\n\t\t}\r\n\r\n\t\tctx.save()\r\n\t\tctx.translate(x, y)\r\n\t\tctx.scale(scale, scale)\r\n\t\tctx.lineCap = 'round'\r\n\t\tctx.lineJoin = 'round'\r\n\r\n\t\tswitch (this.#style) {\r\n\t\t\tcase 'cross':\r\n\t\t\t\tthis.#renderCross(ctx, color, size, thickness, gap)\r\n\t\t\t\tbreak\r\n\r\n\t\t\tcase 'dot':\r\n\t\t\t\tthis.#renderDot(ctx, color, thickness * 2)\r\n\t\t\t\tbreak\r\n\r\n\t\t\tcase 'circle':\r\n\t\t\t\tthis.#renderCircle(ctx, color, size / 2, thickness)\r\n\t\t\t\tbreak\r\n\r\n\t\t\tcase 'ring':\r\n\t\t\t\tthis.#renderRing(ctx, color, size / 2, thickness, gap)\r\n\t\t\t\tbreak\r\n\t\t}\r\n\r\n\t\tctx.restore()\r\n\t}\r\n\r\n\t#renderCross(ctx: CanvasRenderingContext2D, color: string, size: number, thickness: number, gap: number): void {\r\n\t\tconst halfSize = size / 2\r\n\r\n\t\t// Draw outline first\r\n\t\tif (this.#outline) {\r\n\t\t\tctx.strokeStyle = this.#outlineColor\r\n\t\t\tctx.lineWidth = thickness + 2\r\n\r\n\t\t\t// Horizontal lines\r\n\t\t\tctx.beginPath()\r\n\t\t\tctx.moveTo(-halfSize, 0)\r\n\t\t\tctx.lineTo(-gap, 0)\r\n\t\t\tctx.moveTo(gap, 0)\r\n\t\t\tctx.lineTo(halfSize, 0)\r\n\r\n\t\t\t// Vertical lines\r\n\t\t\tctx.moveTo(0, -halfSize)\r\n\t\t\tctx.lineTo(0, -gap)\r\n\t\t\tctx.moveTo(0, gap)\r\n\t\t\tctx.lineTo(0, halfSize)\r\n\t\t\tctx.stroke()\r\n\t\t}\r\n\r\n\t\t// Draw crosshair\r\n\t\tctx.strokeStyle = color\r\n\t\tctx.lineWidth = thickness\r\n\r\n\t\tctx.beginPath()\r\n\t\tctx.moveTo(-halfSize, 0)\r\n\t\tctx.lineTo(-gap, 0)\r\n\t\tctx.moveTo(gap, 0)\r\n\t\tctx.lineTo(halfSize, 0)\r\n\t\tctx.moveTo(0, -halfSize)\r\n\t\tctx.lineTo(0, -gap)\r\n\t\tctx.moveTo(0, gap)\r\n\t\tctx.lineTo(0, halfSize)\r\n\t\tctx.stroke()\r\n\t}\r\n\r\n\t#renderDot(ctx: CanvasRenderingContext2D, color: string, size: number): void {\r\n\t\t// Outline\r\n\t\tif (this.#outline) {\r\n\t\t\tctx.beginPath()\r\n\t\t\tctx.arc(0, 0, size / 2 + 1, 0, Math.PI * 2)\r\n\t\t\tctx.fillStyle = this.#outlineColor\r\n\t\t\tctx.fill()\r\n\t\t}\r\n\r\n\t\t// Dot\r\n\t\tctx.beginPath()\r\n\t\tctx.arc(0, 0, size / 2, 0, Math.PI * 2)\r\n\t\tctx.fillStyle = color\r\n\t\tctx.fill()\r\n\t}\r\n\r\n\t#renderCircle(ctx: CanvasRenderingContext2D, color: string, radius: number, thickness: number): void {\r\n\t\t// Outline\r\n\t\tif (this.#outline) {\r\n\t\t\tctx.beginPath()\r\n\t\t\tctx.arc(0, 0, radius, 0, Math.PI * 2)\r\n\t\t\tctx.strokeStyle = this.#outlineColor\r\n\t\t\tctx.lineWidth = thickness + 2\r\n\t\t\tctx.stroke()\r\n\t\t}\r\n\r\n\t\t// Circle\r\n\t\tctx.beginPath()\r\n\t\tctx.arc(0, 0, radius, 0, Math.PI * 2)\r\n\t\tctx.strokeStyle = color\r\n\t\tctx.lineWidth = thickness\r\n\t\tctx.stroke()\r\n\r\n\t\t// Center dot\r\n\t\tctx.beginPath()\r\n\t\tctx.arc(0, 0, 2, 0, Math.PI * 2)\r\n\t\tctx.fillStyle = color\r\n\t\tctx.fill()\r\n\t}\r\n\r\n\t#renderRing(ctx: CanvasRenderingContext2D, color: string, radius: number, thickness: number, gap: number): void {\r\n\t\t// Outline\r\n\t\tif (this.#outline) {\r\n\t\t\tctx.beginPath()\r\n\t\t\tctx.arc(0, 0, radius, 0, Math.PI * 2)\r\n\t\t\tctx.strokeStyle = this.#outlineColor\r\n\t\t\tctx.lineWidth = thickness + 2\r\n\t\t\tctx.stroke()\r\n\t\t}\r\n\r\n\t\t// Ring\r\n\t\tctx.beginPath()\r\n\t\tctx.arc(0, 0, radius, 0, Math.PI * 2)\r\n\t\tctx.strokeStyle = color\r\n\t\tctx.lineWidth = thickness\r\n\t\tctx.stroke()\r\n\r\n\t\t// Small inner gap\r\n\t\tctx.beginPath()\r\n\t\tctx.arc(0, 0, gap, 0, Math.PI * 2)\r\n\t\tctx.strokeStyle = color\r\n\t\tctx.lineWidth = 1\r\n\t\tctx.stroke()\r\n\t}\r\n\r\n\t// === LIFECYCLE ===\r\n\r\n\tdestroy(): void {\r\n\t\tthis.#listeners.positionChange.clear()\r\n\t\tthis.#listeners.activeChange.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tCameraInterface,\r\n\tEntityRenderer,\r\n\tEntityRendererRegistryInterface,\r\n\tSimpleEntityInterface,\r\n\tUnsubscribe,\r\n} from '../../types.js'\r\n\r\n/**\r\n * EntityRendererRegistry implementation for procedural entity drawing.\r\n */\r\nexport class EntityRendererRegistry<TType extends string, TEntity extends SimpleEntityInterface>\r\nimplements EntityRendererRegistryInterface<TType, TEntity> {\r\n\treadonly #renderers: Map<TType, EntityRenderer<TEntity>> = new Map()\r\n\t#currentTime = 0\r\n\r\n\treadonly #listeners = {\r\n\t\tregister: new Set<(type: string) => void>(),\r\n\t\tunregister: new Set<(type: string) => void>(),\r\n\t}\r\n\r\n\t// === REGISTRATION ===\r\n\r\n\tregister(type: TType, renderer: EntityRenderer<TEntity>): void {\r\n\t\tthis.#renderers.set(type, renderer)\r\n\t\tthis.#listeners.register.forEach(cb => cb(type))\r\n\t}\r\n\r\n\tunregister(type: TType): void {\r\n\t\tif (this.#renderers.has(type)) {\r\n\t\t\tthis.#renderers.delete(type)\r\n\t\t\tthis.#listeners.unregister.forEach(cb => cb(type))\r\n\t\t}\r\n\t}\r\n\r\n\tget(type: TType): EntityRenderer<TEntity> | undefined {\r\n\t\treturn this.#renderers.get(type)\r\n\t}\r\n\r\n\thas(type: TType): boolean {\r\n\t\treturn this.#renderers.has(type)\r\n\t}\r\n\r\n\tgetTypes(): readonly TType[] {\r\n\t\treturn Array.from(this.#renderers.keys())\r\n\t}\r\n\r\n\t// === RENDERING ===\r\n\r\n\trender(ctx: CanvasRenderingContext2D, type: TType, entity: TEntity, camera: CameraInterface): boolean {\r\n\t\tconst renderer = this.#renderers.get(type)\r\n\t\tif (!renderer) return false\r\n\r\n\t\trenderer(ctx, entity, this.#currentTime, camera)\r\n\t\treturn true\r\n\t}\r\n\r\n\trenderAll(\r\n\t\tctx: CanvasRenderingContext2D,\r\n\t\tentities: readonly (TEntity & { type: TType })[],\r\n\t\tcamera: CameraInterface,\r\n\t): void {\r\n\t\t// Update time\r\n\t\tthis.#currentTime = performance.now() / 1000\r\n\r\n\t\tfor (const entity of entities) {\r\n\t\t\tif (!entity.active) continue\r\n\r\n\t\t\tconst renderer = this.#renderers.get(entity.type)\r\n\t\t\tif (renderer) {\r\n\t\t\t\trenderer(ctx, entity, this.#currentTime, camera)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// === SUBSCRIPTIONS ===\r\n\r\n\tonRegister(callback: (type: string) => void): Unsubscribe {\r\n\t\tthis.#listeners.register.add(callback)\r\n\t\treturn () => this.#listeners.register.delete(callback)\r\n\t}\r\n\r\n\tonUnregister(callback: (type: string) => void): Unsubscribe {\r\n\t\tthis.#listeners.unregister.add(callback)\r\n\t\treturn () => this.#listeners.unregister.delete(callback)\r\n\t}\r\n\r\n\t// === LIFECYCLE ===\r\n\r\n\tclear(): void {\r\n\t\tfor (const type of this.#renderers.keys()) {\r\n\t\t\tthis.#listeners.unregister.forEach(cb => cb(type))\r\n\t\t}\r\n\t\tthis.#renderers.clear()\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.clear()\r\n\t\tthis.#listeners.register.clear()\r\n\t\tthis.#listeners.unregister.clear()\r\n\t}\r\n}\r\n","/**\r\n * Factory functions for creating Tactica engine components.\r\n *\r\n * These provide a convenient API for creating instances of all engine components.\r\n */\r\n\r\nimport type {\r\n\tEngineInterface,\r\n\tEngineOptions,\r\n\tSceneInterface,\r\n\tSceneOptions,\r\n\tSceneManagerInterface,\r\n\tSceneManagerOptions,\r\n\tEntityInterface,\r\n\tEntityOptions,\r\n\tCameraInterface,\r\n\tCameraOptions,\r\n\tInputSystemInterface,\r\n\tInputOptions,\r\n\tAudioManagerInterface,\r\n\tAudioManagerOptions,\r\n\tPhysicsWorldInterface,\r\n\tPhysicsWorldOptions,\r\n\tCollisionSystemInterface,\r\n\tTweenManagerInterface,\r\n\tTweenManagerOptions,\r\n\tParticleSystemInterface,\r\n\tParticleSystemOptions,\r\n\tUIManagerInterface,\r\n\tUIManagerOptions,\r\n\tStoreInterface,\r\n\tStoreOptions,\r\n\tComputedInterface,\r\n\tAssetManagerInterface,\r\n\tAssetManagerOptions,\r\n\tMobileManagerInterface,\r\n\tMobileManagerOptions,\r\n\tAccessibilityManagerInterface,\r\n\tAccessibilityOptions,\r\n\tPWAManagerInterface,\r\n\tPWAOptions,\r\n\tNetworkManagerInterface,\r\n\tNetworkOptions,\r\n\tPerformanceMonitorInterface,\r\n\tPerformanceOptions,\r\n\tDebugToolsInterface,\r\n\tSpriteSheetInterface,\r\n\tSpriteSheetOptions,\r\n\tAnimationPlayerInterface,\r\n\tAnimationPlayerOptions,\r\n\tRendererInterface,\r\n\tRenderOptions,\r\n\tViewportInterface,\r\n\tViewportOptions,\r\n\tTilemapInterface,\r\n\tTilemapOptions,\r\n\tSchemaBuilderOptions,\r\n\tSchemaInterface,\r\n\tStateManagerConfig,\r\n\tStateManagerInterface,\r\n\tDatabaseInterface,\r\n\tDatabaseConfig,\r\n\tTabSyncManagerInterface,\r\n\tTimerManagerInterface,\r\n\tTimerManagerOptions,\r\n\tLayerManagerInterface,\r\n\tLayerManagerOptions,\r\n\tTransitionManagerInterface,\r\n\tTransitionManagerOptions,\r\n\tToastManagerInterface,\r\n\tToastManagerOptions,\r\n\tModalManagerInterface,\r\n\tModalManagerOptions,\r\n\tModalInterface,\r\n\tModalOptions,\r\n\tScreenshotManagerInterface,\r\n\tFrameBudgetInterface,\r\n\tFrameBudgetOptions,\r\n\tVirtualJoystickInterface,\r\n\tVirtualJoystickOptions,\r\n\tActionButtonInterface,\r\n\tActionButtonOptions,\r\n\tCameraEffectsInterface,\r\n\tTextInputInterface,\r\n\tTextInputOptions,\r\n\tTooltipManagerInterface,\r\n\tTooltipManagerOptions,\r\n\tDebugOverlayInterface,\r\n\tDebugOverlayOptions,\r\n\tSpriteBatchInterface,\r\n\tSpriteBatchOptions,\r\n\tStorageBackendInterface,\r\n\tLocalStorageBackendOptions,\r\n\tIndexedDBBackendOptions,\r\n\tMigrationRunnerInterface,\r\n\tMigrationRunnerOptions,\r\n\tBuffSystemOptions,\r\n\tBuffSystemInterface,\r\n\tHealthSystemInterface,\r\n\tHealthSystemOptions,\r\n\tFloatingTextSystemInterface,\r\n\tFloatingTextSystemOptions,\r\n\tCollectibleSystemInterface,\r\n\tCollectibleSystemOptions,\r\n\tSpawnerSystemInterface,\r\n\tSpawnerSystemOptions,\r\n\tSimpleEntityInterface,\r\n\tEffectZoneSystemInterface,\r\n\tEffectZoneSystemOptions,\r\n\tBackgroundSystemInterface,\r\n\tBackgroundSystemOptions,\r\n\tExperienceSystemInterface,\r\n\tExperienceSystemOptions,\r\n\tStatisticsSystemInterface,\r\n\tStatisticsSystemOptions,\r\n\tObjectiveSystemInterface,\r\n\tObjectiveSystemOptions,\r\n\tStateMachineInterface,\r\n\tStateMachineOptions,\r\n\tCrosshairSystemInterface,\r\n\tCrosshairSystemOptions,\r\n\tEntityRendererRegistryInterface,\r\n\tKeyboardManagerInterface,\r\n\tKeyboardManagerOptions,\r\n\tGamepadManagerInterface,\r\n\tGamepadManagerOptions,\r\n\tInputActionSystemInterface,\r\n\tInputActionSystemOptions,\r\n\tTrailRendererInterface,\r\n\tTrailRendererOptions,\r\n\tShapeRendererInterface,\r\n\tShapeRendererOptions,\r\n\tPostProcessManagerInterface,\r\n\tPostProcessManagerOptions,\r\n\tMusicPlaylistInterface,\r\n\tMusicPlaylistOptions,\r\n\tSoundVariantPoolInterface,\r\n\tSoundVariantPoolOptions,\r\n\tAudioZoneManagerInterface,\r\n\tAudioZoneManagerOptions,\r\n\tInventorySystemInterface,\r\n\tInventorySystemOptions,\r\n\tDialogueSystemInterface,\r\n\tDialogueSystemOptions,\r\n\tQuestSystemInterface,\r\n\tQuestSystemOptions,\r\n\tRadialMenuInterface,\r\n\tRadialMenuOptions,\r\n\tMinimapInterface,\r\n\tMinimapOptions,\r\n\tNotificationManagerInterface,\r\n\tNotificationManagerOptions,\r\n\tEntityInspectorInterface,\r\n\tEntityInspectorOptions,\r\n\tCommandConsoleInterface,\r\n\tCommandConsoleOptions,\r\n\tCullingSystemInterface,\r\n\tCullingOptions,\r\n\tLODSystemInterface,\r\n\tLODSystemOptions,\r\n} from './types.js'\r\n\r\nimport { Engine } from './core/engine/Engine.js'\r\nimport { Scene } from './core/engine/Scene.js'\r\nimport { SceneManager } from './core/engine/SceneManager.js'\r\nimport { Entity } from './core/engine/Entity.js'\r\nimport { TimerManager } from './core/engine/TimerManager.js'\r\nimport { TransitionManager } from './core/engine/TransitionManager.js'\r\nimport { Camera } from './core/rendering/Camera.js'\r\nimport { InputSystem } from './core/input/InputSystem.js'\r\nimport { KeyboardManager } from './core/input/KeyboardManager.js'\r\nimport { GamepadManager } from './core/input/GamepadManager.js'\r\nimport { InputActionSystem } from './core/input/InputActionSystem.js'\r\nimport { AudioManager } from './core/audio/AudioManager.js'\r\nimport { MusicPlaylist } from './core/audio/MusicPlaylist.js'\r\nimport { SoundVariantPool } from './core/audio/SoundVariantPool.js'\r\nimport { AudioZoneManager } from './core/audio/AudioZoneManager.js'\r\nimport { PhysicsWorld } from './core/physics/PhysicsWorld.js'\r\nimport { CollisionSystem } from './core/physics/CollisionSystem.js'\r\nimport { TweenManager } from './core/animation/TweenManager.js'\r\nimport { ParticleSystem } from './core/animation/ParticleSystem.js'\r\nimport { UIManager } from './core/ui/UIManager.js'\r\nimport { Store } from './core/storage/Store.js'\r\nimport { Computed } from './core/storage/Computed.js'\r\nimport { StateManager } from './core/storage/StateManager.js'\r\nimport { Database } from './core/storage/Database.js'\r\nimport { Schema } from './core/storage/Schema.js'\r\nimport { TabSyncManager } from './core/storage/TabSyncManager.js'\r\nimport { AssetManager } from './core/asset/AssetManager.js'\r\nimport { MobileManager } from './core/platform/MobileManager.js'\r\nimport { AccessibilityManager } from './core/platform/AccessibilityManager.js'\r\nimport { PWAManager } from './core/platform/PWAManager.js'\r\nimport { NetworkManager } from './core/network/NetworkManager.js'\r\nimport { PerformanceMonitor } from './core/debug/PerformanceMonitor.js'\r\nimport { DebugTools } from './core/debug/DebugTools.js'\r\nimport { SpriteSheet } from './core/rendering/SpriteSheet.js'\r\nimport { AnimationPlayer } from './core/animation/AnimationPlayer.js'\r\nimport { Renderer } from './core/rendering/Renderer.js'\r\nimport { Viewport } from './core/rendering/Viewport.js'\r\nimport { Tilemap } from './core/rendering/Tilemap.js'\r\nimport { LayerManager } from './core/rendering/LayerManager.js'\r\nimport { TrailRenderer } from './core/rendering/TrailRenderer.js'\r\nimport { ShapeRenderer } from './core/rendering/ShapeRenderer.js'\r\nimport { PostProcessManager } from './core/rendering/PostProcessManager.js'\r\nimport { ToastManager } from './core/ui/ToastManager.js'\r\nimport { Modal } from './core/ui/Modal.js'\r\nimport { ModalManager } from './core/ui/ModalManager.js'\r\nimport { ScreenshotManager } from './core/debug/ScreenshotManager.js'\r\nimport { FrameBudget } from './core/debug/FrameBudget.js'\r\nimport { VirtualJoystick } from './core/ui/VirtualJoystick.js'\r\nimport { ActionButton } from './core/ui/ActionButton.js'\r\nimport { CameraEffects } from './core/rendering/CameraEffects.js'\r\nimport { TextInput } from './core/ui/TextInput.js'\r\nimport { TooltipManager } from './core/ui/TooltipManager.js'\r\nimport { DebugOverlay } from './core/debug/DebugOverlay.js'\r\nimport { SpriteBatch } from './core/rendering/SpriteBatch.js'\r\nimport { LocalStorageBackend } from './core/storage/LocalStorageBackend.js'\r\nimport { IndexedDBBackend } from './core/storage/IndexedDBBackend.js'\r\nimport { MigrationRunner } from './core/storage/MigrationRunner.js'\r\nimport { BuffSystem } from './core/gameplay/BuffSystem.js'\r\nimport { HealthSystem } from './core/gameplay/HealthSystem.js'\r\nimport { FloatingTextSystem } from './core/gameplay/FloatingTextSystem.js'\r\nimport { CollectibleSystem } from './core/gameplay/CollectibleSystem.js'\r\nimport { SpawnerSystem } from './core/gameplay/SpawnerSystem.js'\r\nimport { EffectZoneSystem } from './core/gameplay/EffectZoneSystem.js'\r\nimport { BackgroundSystem } from './core/gameplay/BackgroundSystem.js'\r\nimport { ExperienceSystem } from './core/gameplay/ExperienceSystem.js'\r\nimport { StatisticsSystem } from './core/gameplay/StatisticsSystem.js'\r\nimport { ObjectiveSystem } from './core/gameplay/ObjectiveSystem.js'\r\nimport { StateMachine } from './core/gameplay/StateMachine.js'\r\nimport { InventorySystem } from './core/gameplay/InventorySystem.js'\r\nimport { DialogueSystem } from './core/gameplay/DialogueSystem.js'\r\nimport { QuestSystem } from './core/gameplay/QuestSystem.js'\r\nimport { RadialMenu } from './core/ui/RadialMenu.js'\r\nimport { Minimap } from './core/ui/Minimap.js'\r\nimport { NotificationManager } from './core/ui/NotificationManager'\r\nimport { EntityInspector } from './core/debug/EntityInspector.js'\r\nimport { CommandConsole } from './core/debug/CommandConsole.js'\r\nimport { CullingSystem } from './core/rendering/CullingSystem.js'\r\nimport { LODSystem } from './core/rendering/LODSystem.js'\r\nimport { CrosshairSystem } from './core/gameplay/CrosshairSystem.js'\r\nimport { EntityRendererRegistry } from './core/gameplay/EntityRendererRegistry.js'\r\n\r\n// ============================================================================\r\n// Core Engine Factory Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Create a game engine instance.\r\n *\r\n * @param options - Engine configuration\r\n * @returns A new Engine instance\r\n *\r\n * @example\r\n * ```ts\r\n * const engine = createEngine({\r\n * canvas: document.getElementById('game') as HTMLCanvasElement,\r\n * width: 800,\r\n * height: 600,\r\n * targetFPS: 60,\r\n * })\r\n * engine.start()\r\n * ```\r\n */\r\nexport function createEngine(options: EngineOptions): EngineInterface {\r\n\treturn new Engine(options)\r\n}\r\n\r\n/**\r\n * Create a scene instance.\r\n *\r\n * @param options - Scene configuration\r\n * @returns A new Scene instance\r\n *\r\n * @example\r\n * ```ts\r\n * const mainScene = createScene({\r\n * name: 'main',\r\n * backgroundColor: '#1a1a2e',\r\n * })\r\n * ```\r\n */\r\nexport function createScene(options: SceneOptions): SceneInterface {\r\n\treturn new Scene(options)\r\n}\r\n\r\n/**\r\n * Create a scene manager instance.\r\n *\r\n * @param options - Scene manager configuration\r\n * @returns A new SceneManager instance\r\n *\r\n * @example\r\n * ```ts\r\n * const sceneManager = createSceneManager()\r\n * sceneManager.addScene(menuScene)\r\n * sceneManager.addScene(gameScene)\r\n * await sceneManager.setActiveScene('game')\r\n * ```\r\n */\r\nexport function createSceneManager(options?: SceneManagerOptions): SceneManagerInterface {\r\n\treturn new SceneManager(options)\r\n}\r\n\r\n/**\r\n * Create a game entity instance.\r\n *\r\n * @param options - Entity configuration\r\n * @returns A new Entity instance\r\n *\r\n * @example\r\n * ```ts\r\n * const player = createEntity({\r\n * id: 'player',\r\n * x: 100,\r\n * y: 200,\r\n * width: 32,\r\n * height: 32,\r\n * })\r\n * ```\r\n */\r\nexport function createEntity(options?: EntityOptions): EntityInterface {\r\n\treturn new Entity(options)\r\n}\r\n\r\n// ============================================================================\r\n// Rendering Factory Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Create a camera instance.\r\n *\r\n * @param options - Camera configuration\r\n * @returns A new Camera instance\r\n *\r\n * @example\r\n * ```ts\r\n * const camera = createCamera({\r\n * width: 800,\r\n * height: 600,\r\n * zoom: 1,\r\n * })\r\n * camera.follow(player)\r\n * ```\r\n */\r\nexport function createCamera(options: CameraOptions): CameraInterface {\r\n\treturn new Camera(options)\r\n}\r\n\r\n/**\r\n * Create a sprite sheet instance.\r\n *\r\n * @param options - Sprite sheet configuration\r\n * @returns A new SpriteSheet instance\r\n *\r\n * @example\r\n * ```ts\r\n * const playerSheet = createSpriteSheet({\r\n * imageKey: 'player',\r\n * frameWidth: 32,\r\n * frameHeight: 32,\r\n * columns: 8,\r\n * animations: [\r\n * { name: 'idle', frames: [0, 1, 2, 3], frameRate: 8, loop: true },\r\n * ],\r\n * })\r\n * ```\r\n */\r\nexport function createSpriteSheet(options: SpriteSheetOptions): SpriteSheetInterface {\r\n\treturn new SpriteSheet(options)\r\n}\r\n\r\n/**\r\n * Create an animation player instance.\r\n *\r\n * @param options - Animation player configuration\r\n * @returns A new AnimationPlayer instance\r\n *\r\n * @example\r\n * ```ts\r\n * const animator = createAnimationPlayer({\r\n * spriteSheet: playerSheet,\r\n * defaultAnimation: 'idle',\r\n * })\r\n * animator.play('walk')\r\n * ```\r\n */\r\nexport function createAnimationPlayer(options: AnimationPlayerOptions): AnimationPlayerInterface {\r\n\treturn new AnimationPlayer(options)\r\n}\r\n\r\n/**\r\n * Create a renderer instance.\r\n *\r\n * @param context - The canvas 2D rendering context\r\n * @param options - Renderer configuration\r\n * @returns A new Renderer instance\r\n */\r\nexport function createRenderer(context: CanvasRenderingContext2D, options?: Partial<RenderOptions>): RendererInterface {\r\n\treturn new Renderer(context, options)\r\n}\r\n\r\n/**\r\n * Create a viewport instance.\r\n *\r\n * @param options - Viewport configuration\r\n * @returns A new Viewport instance\r\n */\r\nexport function createViewport(options: ViewportOptions): ViewportInterface {\r\n\treturn new Viewport(options)\r\n}\r\n\r\n/**\r\n * Create a tilemap instance.\r\n *\r\n * @param options - Tilemap configuration\r\n * @returns A new Tilemap instance\r\n */\r\nexport function createTilemap(options: TilemapOptions): TilemapInterface {\r\n\treturn new Tilemap(options)\r\n}\r\n\r\n/**\r\n * Create a trail renderer for visual trails behind moving objects.\r\n *\r\n * @param options - Trail renderer configuration\r\n * @returns A new TrailRenderer instance\r\n *\r\n * @example\r\n * ```ts\r\n * const trail = createTrailRenderer({\r\n * maxPoints: 50,\r\n * startWidth: 10,\r\n * endWidth: 1,\r\n * fadeTime: 500,\r\n * })\r\n * trail.start()\r\n * trail.addPoint(entity.x, entity.y)\r\n * ```\r\n */\r\nexport function createTrailRenderer(options?: TrailRendererOptions): TrailRendererInterface {\r\n\treturn new TrailRenderer(options)\r\n}\r\n\r\n/**\r\n * Create a shape renderer for drawing geometric primitives.\r\n *\r\n * @param options - Shape renderer configuration\r\n * @returns A new ShapeRenderer instance\r\n *\r\n * @example\r\n * ```ts\r\n * const shapes = createShapeRenderer()\r\n * shapes.setContext(ctx)\r\n * shapes.setLineStyle({ color: '#ff0000', width: 2 })\r\n * shapes.circle(100, 100, 50)\r\n * ```\r\n */\r\nexport function createShapeRenderer(options?: ShapeRendererOptions): ShapeRendererInterface {\r\n\treturn new ShapeRenderer(options)\r\n}\r\n\r\n/**\r\n * Create a post-process manager for visual effects.\r\n *\r\n * @param options - Post-process manager configuration\r\n * @returns A new PostProcessManager instance\r\n *\r\n * @example\r\n * ```ts\r\n * const postProcess = createPostProcessManager({\r\n * effects: [\r\n * { type: 'vignette', intensity: 0.3, enabled: true },\r\n * ],\r\n * })\r\n * postProcess.apply(ctx, canvas)\r\n * ```\r\n */\r\nexport function createPostProcessManager(options?: PostProcessManagerOptions): PostProcessManagerInterface {\r\n\treturn new PostProcessManager(options)\r\n}\r\n\r\n// ============================================================================\r\n// Input Factory Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Create an input system instance.\r\n *\r\n * @param canvas - The canvas element to attach input listeners to\r\n * @param options - Input system configuration\r\n * @returns A new InputSystem instance\r\n *\r\n * @example\r\n * ```ts\r\n * const input = createInputSystem(canvas, {\r\n * tapThreshold: 10,\r\n * doubleTapDelay: 300,\r\n * })\r\n * input.onTap((x, y) => shoot(x, y))\r\n * ```\r\n */\r\nexport function createInputSystem(canvas: HTMLCanvasElement, options?: InputOptions): InputSystemInterface {\r\n\treturn new InputSystem(canvas, options)\r\n}\r\n\r\n/**\r\n * Create a keyboard input manager.\r\n *\r\n * @param options - Keyboard manager configuration\r\n * @returns A new KeyboardManager instance\r\n *\r\n * @example\r\n * ```ts\r\n * const keyboard = createKeyboardManager({\r\n * preventDefaultKeys: ['ArrowUp', 'ArrowDown', 'Space'],\r\n * })\r\n * keyboard.update()\r\n * const move = keyboard.getVector('KeyA', 'KeyD', 'KeyW', 'KeyS')\r\n * ```\r\n */\r\nexport function createKeyboardManager(options?: KeyboardManagerOptions): KeyboardManagerInterface {\r\n\treturn new KeyboardManager(options)\r\n}\r\n\r\n/**\r\n * Create a gamepad input manager.\r\n *\r\n * @param options - Gamepad manager configuration\r\n * @returns A new GamepadManager instance\r\n *\r\n * @example\r\n * ```ts\r\n * const gamepad = createGamepadManager({\r\n * deadzone: 0.2,\r\n * onConnect: (index, id) => console.log('Connected:', id),\r\n * })\r\n * gamepad.update()\r\n * const stick = gamepad.getStick(0, 'left')\r\n * ```\r\n */\r\nexport function createGamepadManager(options?: GamepadManagerOptions): GamepadManagerInterface {\r\n\treturn new GamepadManager(options)\r\n}\r\n\r\n/**\r\n * Create an input action system for unified input handling.\r\n *\r\n * @param options - Input action system configuration\r\n * @returns A new InputActionSystem instance\r\n *\r\n * @example\r\n * ```ts\r\n * const actions = createInputActionSystem({\r\n * contexts: [{\r\n * name: 'gameplay',\r\n * priority: 0,\r\n * actions: [\r\n * { name: 'jump', bindings: [{ source: 'keyboard', key: 'Space' }] },\r\n * ],\r\n * }],\r\n * })\r\n * actions.enableContext('gameplay')\r\n * actions.update(keyboard.getState())\r\n * ```\r\n */\r\nexport function createInputActionSystem(options?: InputActionSystemOptions): InputActionSystemInterface {\r\n\treturn new InputActionSystem(options)\r\n}\r\n\r\n/**\r\n * Create a mobile manager instance.\r\n *\r\n * @param options - Mobile manager configuration\r\n * @returns A new MobileManager instance\r\n *\r\n * @example\r\n * ```ts\r\n * const mobile = createMobileManager()\r\n * if (mobile.isMobile()) {\r\n * mobile.vibrateHaptic({ pattern: 'impact' })\r\n * }\r\n * ```\r\n */\r\nexport function createMobileManager(options?: MobileManagerOptions): MobileManagerInterface {\r\n\treturn new MobileManager(options)\r\n}\r\n\r\n// ============================================================================\r\n// Audio Factory Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Create an audio manager instance.\r\n *\r\n * @param options - Audio manager configuration\r\n * @returns A new AudioManager instance\r\n *\r\n * @example\r\n * ```ts\r\n * const audio = createAudioManager({\r\n * masterVolume: 1.0,\r\n * })\r\n * audio.play('bgm', { loop: true })\r\n * ```\r\n */\r\nexport function createAudioManager(options?: AudioManagerOptions): AudioManagerInterface {\r\n\treturn new AudioManager(options)\r\n}\r\n\r\n/**\r\n * Create a music playlist for sequential music playback.\r\n *\r\n * @param options - Playlist configuration\r\n * @returns A new MusicPlaylist instance\r\n *\r\n * @example\r\n * ```ts\r\n * const playlist = createMusicPlaylist({\r\n * tracks: [{ key: 'menu', name: 'Menu Music' }],\r\n * mode: 'shuffle',\r\n * })\r\n * playlist.play()\r\n * ```\r\n */\r\nexport function createMusicPlaylist(options?: MusicPlaylistOptions): MusicPlaylistInterface {\r\n\treturn new MusicPlaylist(options)\r\n}\r\n\r\n/**\r\n * Create a sound variant pool for playing random sound variations.\r\n *\r\n * @param options - Variant pool configuration\r\n * @returns A new SoundVariantPool instance\r\n *\r\n * @example\r\n * ```ts\r\n * const footsteps = createSoundVariantPool({\r\n * variants: [\r\n * { key: 'step-1', weight: 1 },\r\n * { key: 'step-2', weight: 1 },\r\n * ],\r\n * })\r\n * footsteps.play(audioManager)\r\n * ```\r\n */\r\nexport function createSoundVariantPool(options: SoundVariantPoolOptions): SoundVariantPoolInterface {\r\n\treturn new SoundVariantPool(options)\r\n}\r\n\r\n/**\r\n * Create an audio zone manager for spatial audio effects.\r\n *\r\n * @param options - Zone manager configuration\r\n * @returns A new AudioZoneManager instance\r\n *\r\n * @example\r\n * ```ts\r\n * const zones = createAudioZoneManager({\r\n * zones: [{\r\n * id: 'cave',\r\n * x: 100, y: 100, width: 200, height: 200,\r\n * effect: { type: 'reverb', intensity: 0.7 },\r\n * }],\r\n * })\r\n * zones.update(player.x, player.y)\r\n * ```\r\n */\r\nexport function createAudioZoneManager(options?: AudioZoneManagerOptions): AudioZoneManagerInterface {\r\n\treturn new AudioZoneManager(options)\r\n}\r\n\r\n// ============================================================================\r\n// Physics Factory Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Create a physics world instance.\r\n *\r\n * @param options - Physics world configuration\r\n * @returns A new PhysicsWorld instance\r\n *\r\n * @example\r\n * ```ts\r\n * const physics = createPhysicsWorld({\r\n * gravityX: 0,\r\n * gravityY: 9.8,\r\n * })\r\n * physics.addBody(player, { mass: 1 })\r\n * ```\r\n */\r\nexport function createPhysicsWorld(options?: PhysicsWorldOptions): PhysicsWorldInterface {\r\n\treturn new PhysicsWorld(options)\r\n}\r\n\r\n/**\r\n * Create a collision system instance.\r\n *\r\n * @returns A new CollisionSystem instance\r\n *\r\n * @example\r\n * ```ts\r\n * const collision = createCollisionSystem()\r\n * collision.addEntity(player, { shape: 'rectangle', ... })\r\n * ```\r\n */\r\nexport function createCollisionSystem(): CollisionSystemInterface {\r\n\treturn new CollisionSystem()\r\n}\r\n\r\n// ============================================================================\r\n// Animation Factory Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Create a tween manager instance.\r\n *\r\n * @param options - Tween manager configuration\r\n * @returns A new TweenManager instance\r\n *\r\n * @example\r\n * ```ts\r\n * const tweens = createTweenManager()\r\n * const tween = tweens.create({\r\n * target: player,\r\n * properties: { x: 500 },\r\n * duration: 1000,\r\n * easing: 'easeOutQuad',\r\n * })\r\n * tween.play()\r\n * ```\r\n */\r\nexport function createTweenManager(options?: TweenManagerOptions): TweenManagerInterface {\r\n\treturn new TweenManager(options)\r\n}\r\n\r\n/**\r\n * Create a particle system instance.\r\n *\r\n * @param options - Particle system configuration\r\n * @returns A new ParticleSystem instance\r\n *\r\n * @example\r\n * ```ts\r\n * const particles = createParticleSystem()\r\n * const emitter = particles.createEmitter({\r\n * x: 400,\r\n * y: 300,\r\n * maxParticles: 100,\r\n * emissionRate: 50,\r\n * lifespan: 1000,\r\n * })\r\n * emitter.emit(50)\r\n * ```\r\n */\r\nexport function createParticleSystem(options?: ParticleSystemOptions): ParticleSystemInterface {\r\n\treturn new ParticleSystem(options)\r\n}\r\n\r\n// ============================================================================\r\n// UI Factory Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Create a UI manager instance.\r\n *\r\n * @param options - UI manager configuration\r\n * @returns A new UIManager instance\r\n *\r\n * @example\r\n * ```ts\r\n * const ui = createUIManager()\r\n * const button = ui.createButton({\r\n * x: 100, y: 100,\r\n * width: 200, height: 60,\r\n * text: 'Play',\r\n * onClick: () => startGame(),\r\n * })\r\n * ```\r\n */\r\nexport function createUIManager(options?: UIManagerOptions): UIManagerInterface {\r\n\treturn new UIManager(options)\r\n}\r\n\r\n// ============================================================================\r\n// Storage Factory Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Create a new reactive store.\r\n *\r\n * @param options - Store configuration options\r\n * @returns A new Store instance\r\n *\r\n * @example\r\n * ```ts\r\n * const playerStore = createStore({\r\n * id: 'player',\r\n * initialState: { health: 100, position: { x: 0, y: 0 } },\r\n * enableHistory: true,\r\n * })\r\n *\r\n * playerStore.onChange((state, prev) => {\r\n * console.log('Player state changed:', state)\r\n * })\r\n *\r\n * playerStore.update(state => ({ ...state, health: 80 }))\r\n * ```\r\n */\r\nexport function createStore<TState>(options: StoreOptions<TState>): StoreInterface<TState> {\r\n\treturn new Store(options)\r\n}\r\n\r\n/**\r\n * Create a computed value derived from stores.\r\n *\r\n * @param compute - Function that computes the derived value\r\n * @returns A new Computed instance\r\n *\r\n * @example\r\n * ```ts\r\n * const playerStore = createStore({\r\n * id: 'player',\r\n * initialState: { health: 100, maxHealth: 100 }\r\n * })\r\n *\r\n * const healthPercent = createComputed(() => {\r\n * const { health, maxHealth } = playerStore.get()\r\n * return health / maxHealth\r\n * })\r\n *\r\n * console.log(healthPercent.get()) // 1\r\n *\r\n * playerStore.update(s => ({ ...s, health: 50 }))\r\n * console.log(healthPercent.get()) // 0.5\r\n * ```\r\n */\r\nexport function createComputed<TValue>(compute: () => TValue): ComputedInterface<TValue> {\r\n\treturn new Computed(compute)\r\n}\r\n\r\n/**\r\n * Create an IndexedDB database connection.\r\n *\r\n * @param config - Database configuration\r\n * @returns Promise resolving to a Database instance\r\n *\r\n * @example\r\n * ```ts\r\n * const db = await createDatabase({\r\n * name: 'my-game',\r\n * version: 1,\r\n * stores: [\r\n * { name: 'snapshots', keyPath: 'id' },\r\n * { name: 'slots', keyPath: 'id' }\r\n * ]\r\n * })\r\n *\r\n * await db.put('slots', [{ id: 'slot1', name: 'Save 1' }])\r\n * const slot = await db.get('slots', 'slot1')\r\n * ```\r\n */\r\nexport function createDatabase(config: DatabaseConfig): Promise<DatabaseInterface> {\r\n\treturn new Promise((resolve, reject) => {\r\n\t\tconst request = indexedDB.open(config.name, config.version)\r\n\r\n\t\trequest.onupgradeneeded = (event) => {\r\n\t\t\tconst db = (event.target as IDBOpenDBRequest).result\r\n\r\n\t\t\t// Create stores\r\n\t\t\tfor (const storeConfig of config.stores) {\r\n\t\t\t\tif (!db.objectStoreNames.contains(storeConfig.name)) {\r\n\t\t\t\t\tconst storeOptions: IDBObjectStoreParameters = {\r\n\t\t\t\t\t\tkeyPath: storeConfig.keyPath as string | string[],\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (storeConfig.autoIncrement !== undefined) {\r\n\t\t\t\t\t\tstoreOptions.autoIncrement = storeConfig.autoIncrement\r\n\t\t\t\t\t}\r\n\t\t\t\t\tconst store = db.createObjectStore(storeConfig.name, storeOptions)\r\n\r\n\t\t\t\t\t// Create indexes\r\n\t\t\t\t\tif (storeConfig.indexes) {\r\n\t\t\t\t\t\tfor (const indexConfig of storeConfig.indexes) {\r\n\t\t\t\t\t\t\tconst indexOptions: IDBIndexParameters = {}\r\n\t\t\t\t\t\t\tif (indexConfig.unique !== undefined) {\r\n\t\t\t\t\t\t\t\tindexOptions.unique = indexConfig.unique\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tif (indexConfig.multiEntry !== undefined) {\r\n\t\t\t\t\t\t\t\tindexOptions.multiEntry = indexConfig.multiEntry\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tstore.createIndex(indexConfig.name, indexConfig.keyPath as string | string[], indexOptions)\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\trequest.onsuccess = () => {\r\n\t\t\tconst db = request.result\r\n\t\t\tconst channelName = `${config.name}-changes`\r\n\t\t\tresolve(new Database(db, channelName))\r\n\t\t}\r\n\r\n\t\trequest.onerror = () => {\r\n\t\t\treject(request.error)\r\n\t\t}\r\n\t})\r\n}\r\n\r\n// ============================================================================\r\n// Manager Factory Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Create an asset manager instance.\r\n *\r\n * @param options - Asset manager configuration\r\n * @returns A new AssetManager instance\r\n *\r\n * @example\r\n * ```ts\r\n * const assets = createAssetManager({ basePath: 'assets/' })\r\n * await assets.loadImage('player', 'sprites/player.png')\r\n * ```\r\n */\r\nexport function createAssetManager(options?: AssetManagerOptions): AssetManagerInterface {\r\n\treturn new AssetManager(options)\r\n}\r\n\r\n/**\r\n * Create an accessibility manager instance.\r\n *\r\n * @param options - Accessibility manager configuration\r\n * @returns A new AccessibilityManager instance\r\n *\r\n * @example\r\n * ```ts\r\n * const a11y = createAccessibilityManager()\r\n * a11y.announce('Game started', 'polite')\r\n * ```\r\n */\r\nexport function createAccessibilityManager(options?: AccessibilityOptions): AccessibilityManagerInterface {\r\n\treturn new AccessibilityManager(options)\r\n}\r\n\r\n/**\r\n * Create a PWA manager instance.\r\n *\r\n * @param options - PWA manager configuration\r\n * @returns A new PWAManager instance\r\n *\r\n * @example\r\n * ```ts\r\n * const pwa = createPWAManager({ serviceWorkerUrl: '/sw.js' })\r\n * if (pwa.canInstall()) {\r\n * await pwa.promptInstall()\r\n * }\r\n * ```\r\n */\r\nexport function createPWAManager(options?: PWAOptions): PWAManagerInterface {\r\n\treturn new PWAManager(options)\r\n}\r\n\r\n/**\r\n * Create a network manager instance.\r\n *\r\n * @param options - Network manager configuration\r\n * @returns A new NetworkManager instance\r\n *\r\n * @example\r\n * ```ts\r\n * const network = createNetworkManager({\r\n * transport: 'websocket',\r\n * url: 'wss://game-server.example.com',\r\n * })\r\n * network.onMessage('player-moved', (msg) => { ... })\r\n * ```\r\n */\r\nexport function createNetworkManager(options: NetworkOptions): NetworkManagerInterface {\r\n\treturn new NetworkManager(options)\r\n}\r\n\r\n/**\r\n * Create a performance monitor instance.\r\n *\r\n * @param options - Performance monitor configuration\r\n * @returns A new PerformanceMonitor instance\r\n *\r\n * @example\r\n * ```ts\r\n * const perf = createPerformanceMonitor({ enabled: true })\r\n * const metrics = perf.getMetrics()\r\n * console.log(`FPS: ${metrics.fps}`)\r\n * ```\r\n */\r\nexport function createPerformanceMonitor(options?: PerformanceOptions): PerformanceMonitorInterface {\r\n\treturn new PerformanceMonitor(options)\r\n}\r\n\r\n/**\r\n * Create debug tools instance.\r\n *\r\n * @returns A new DebugTools instance\r\n *\r\n * @example\r\n * ```ts\r\n * const debug = createDebugTools()\r\n * debug.setLogLevel('debug')\r\n * debug.info('Game initialized')\r\n * ```\r\n */\r\nexport function createDebugTools(): DebugToolsInterface {\r\n\treturn new DebugTools()\r\n}\r\n\r\n/**\r\n * Create a schema for data validation.\r\n *\r\n * @param options - Schema configuration\r\n * @returns A new Schema instance\r\n *\r\n * @example\r\n * ```ts\r\n * interface PlayerState {\r\n * health: number\r\n * name: string\r\n * }\r\n *\r\n * const playerSchema = createSchema<PlayerState>({\r\n * version: 1,\r\n * fields: [\r\n * { name: 'health', type: 'number', required: true },\r\n * { name: 'name', type: 'string', required: true },\r\n * ],\r\n * defaultValue: { health: 100, name: 'Player' },\r\n * })\r\n *\r\n * const result = playerSchema.validate({ health: 50, name: 'Alice' })\r\n * if (result.ok) {\r\n * console.log('Valid:', result.value)\r\n * }\r\n * ```\r\n */\r\nexport function createSchema<T>(options: SchemaBuilderOptions<T>): SchemaInterface<T> {\r\n\treturn new Schema(options)\r\n}\r\n\r\n/**\r\n * Create a game state manager.\r\n *\r\n * @param config - Manager configuration\r\n * @returns Promise resolving to the manager instance\r\n *\r\n * @example\r\n * ```ts\r\n * const manager = await createStateManager({\r\n * gameVersion: '1.0.0',\r\n * formatVersion: 1,\r\n * stores: {\r\n * player: {\r\n * schema: playerSchema,\r\n * enableHistory: true,\r\n * },\r\n * world: {\r\n * schema: worldSchema,\r\n * },\r\n * },\r\n * })\r\n *\r\n * // Access stores\r\n * const playerStore = manager.getStore('player')\r\n * playerStore?.update(state => ({ ...state, health: 100 }))\r\n *\r\n * // Save/load\r\n * await manager.save('slot1', 'My Save')\r\n * await manager.load('slot1')\r\n * ```\r\n */\r\nexport async function createStateManager(\r\n\tconfig: StateManagerConfig,\r\n): Promise<StateManagerInterface> {\r\n\treturn StateManager.create(config)\r\n}\r\n\r\n/**\r\n * Create a tab synchronization manager.\r\n *\r\n * @param channelName - BroadcastChannel name for communication\r\n * @returns A new TabSyncManager instance\r\n *\r\n * @example\r\n * ```ts\r\n * const sync = createTabSyncManager('my-game-sync')\r\n *\r\n * sync.onLeaderChange((isLeader) => {\r\n * console.log('Leadership changed:', isLeader)\r\n * })\r\n *\r\n * if (!sync.isLeader()) {\r\n * await sync.requestLeadership()\r\n * }\r\n * ```\r\n */\r\nexport function createTabSyncManager(channelName?: string): TabSyncManagerInterface {\r\n\treturn new TabSyncManager(channelName)\r\n}\r\n\r\n// ============================================================================\r\n// New Factory Functions (Phase 1 - Core Infrastructure)\r\n// ============================================================================\r\n\r\n/**\r\n * Create a timer manager instance.\r\n *\r\n * @param options - Timer manager configuration\r\n * @returns A new TimerManager instance\r\n *\r\n * @example\r\n * ```ts\r\n * const timers = createTimerManager({ pauseWithEngine: true })\r\n * timers.setTimeout(() => console.log('Hello!'), 1000)\r\n *\r\n * // Promise-based delay\r\n * await timers.delay(2000)\r\n * console.log('2 seconds later')\r\n * ```\r\n */\r\nexport function createTimerManager(options?: TimerManagerOptions): TimerManagerInterface {\r\n\treturn new TimerManager(options)\r\n}\r\n\r\n/**\r\n * Create a layer manager instance.\r\n *\r\n * @param options - Layer manager configuration\r\n * @returns A new LayerManager instance\r\n *\r\n * @example\r\n * ```ts\r\n * const layers = createLayerManager()\r\n * layers.createLayer({ name: 'background', zIndex: 0 })\r\n * layers.createLayer({ name: 'entities', zIndex: 10 })\r\n * layers.createLayer({ name: 'ui', zIndex: 100 })\r\n *\r\n * layers.addToLayer('entities', player)\r\n * ```\r\n */\r\nexport function createLayerManager(options?: LayerManagerOptions): LayerManagerInterface {\r\n\treturn new LayerManager(options)\r\n}\r\n\r\n/**\r\n * Create a transition manager instance.\r\n *\r\n * @param sceneManager - Scene manager to transition between scenes\r\n * @param options - Transition manager configuration\r\n * @returns A new TransitionManager instance\r\n *\r\n * @example\r\n * ```ts\r\n * const transitions = createTransitionManager(sceneManager)\r\n * await transitions.fadeToBlack(500)\r\n * await transitions.fadeFromBlack(500)\r\n *\r\n * // Scene transition\r\n * await transitions.transitionTo(gameScene, { type: 'fade', duration: 1000 })\r\n * ```\r\n */\r\nexport function createTransitionManager(sceneManager: SceneManagerInterface, options?: TransitionManagerOptions): TransitionManagerInterface {\r\n\treturn new TransitionManager(sceneManager, options)\r\n}\r\n\r\n/**\r\n * Create a toast manager instance.\r\n *\r\n * @param options - Toast manager configuration\r\n * @returns A new ToastManager instance\r\n *\r\n * @example\r\n * ```ts\r\n * const toasts = createToastManager({ defaultPosition: 'top' })\r\n * toasts.success('Level Complete!')\r\n * toasts.error('Out of lives!')\r\n * toasts.info('New item acquired', 5000)\r\n * ```\r\n */\r\nexport function createToastManager(options?: ToastManagerOptions): ToastManagerInterface {\r\n\treturn new ToastManager(options)\r\n}\r\n\r\n/**\r\n * Create a modal manager instance.\r\n *\r\n * @param options - Modal manager configuration\r\n * @returns A new ModalManager instance\r\n *\r\n * @example\r\n * ```ts\r\n * const modals = createModalManager()\r\n * await modals.alert('Game Over!')\r\n * const confirmed = await modals.confirm('Restart?')\r\n * if (confirmed) restartGame()\r\n * ```\r\n */\r\nexport function createModalManager(options?: ModalManagerOptions): ModalManagerInterface {\r\n\treturn new ModalManager(options)\r\n}\r\n\r\n/**\r\n * Create a modal dialog instance.\r\n *\r\n * @param options - Modal configuration\r\n * @returns A new Modal instance\r\n *\r\n * @example\r\n * ```ts\r\n * const modal = createModal({\r\n * title: 'Confirm',\r\n * content: 'Are you sure?',\r\n * buttons: [\r\n * { text: 'No', value: false, style: 'secondary', closeOnClick: true },\r\n * { text: 'Yes', value: true, style: 'primary', closeOnClick: true },\r\n * ],\r\n * })\r\n * modal.onClose((value) => console.log('Result:', value))\r\n * modal.open()\r\n * ```\r\n */\r\nexport function createModal(options: ModalOptions): ModalInterface {\r\n\treturn new Modal(options)\r\n}\r\n\r\n/**\r\n * Create a screenshot manager instance.\r\n *\r\n * @param canvas - Canvas element to capture\r\n * @returns A new ScreenshotManager instance\r\n *\r\n * @example\r\n * ```ts\r\n * const screenshots = createScreenshotManager(canvas)\r\n * const thumbnail = await screenshots.captureThumbnail(200, 150)\r\n * await screenshots.download('screenshot.png')\r\n * ```\r\n */\r\nexport function createScreenshotManager(canvas: HTMLCanvasElement): ScreenshotManagerInterface {\r\n\treturn new ScreenshotManager(canvas)\r\n}\r\n\r\n/**\r\n * Create a frame budget tracker instance.\r\n *\r\n * @param options - Frame budget configuration\r\n * @returns A new FrameBudget instance\r\n *\r\n * @example\r\n * ```ts\r\n * const budget = createFrameBudget({ targetFPS: 60 })\r\n *\r\n * budget.onOverBudget((timing) => {\r\n * console.warn('Frame took too long:', timing.total, 'ms')\r\n * })\r\n *\r\n * // In game loop\r\n * budget.startFrame()\r\n * budget.startPhase('update')\r\n * update()\r\n * budget.endPhase('update')\r\n * budget.endFrame()\r\n * ```\r\n */\r\nexport function createFrameBudget(options?: FrameBudgetOptions): FrameBudgetInterface {\r\n\treturn new FrameBudget(options)\r\n}\r\n\r\n// ============================================================================\r\n// Phase 2: Mobile UX Factory Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Create a virtual joystick instance.\r\n *\r\n * @param options - Virtual joystick configuration\r\n * @returns A new VirtualJoystick instance\r\n *\r\n * @example\r\n * ```ts\r\n * const joystick = createVirtualJoystick({\r\n * x: 50,\r\n * y: window.innerHeight - 150,\r\n * innerRadius: 30,\r\n * outerRadius: 70,\r\n * deadZone: 0.15,\r\n * })\r\n *\r\n * joystick.onMove((direction, magnitude) => {\r\n * player.velocity.x = direction.x * magnitude * speed\r\n * player.velocity.y = direction.y * magnitude * speed\r\n * })\r\n * ```\r\n */\r\nexport function createVirtualJoystick(options: VirtualJoystickOptions): VirtualJoystickInterface {\r\n\treturn new VirtualJoystick(options)\r\n}\r\n\r\n/**\r\n * Create an action button instance.\r\n *\r\n * @param options - Action button configuration\r\n * @returns A new ActionButton instance\r\n *\r\n * @example\r\n * ```ts\r\n * const attackButton = createActionButton({\r\n * x: window.innerWidth - 100,\r\n * y: window.innerHeight - 100,\r\n * size: 60,\r\n * icon: '⚔',\r\n * cooldown: 500,\r\n * hapticFeedback: true,\r\n * })\r\n *\r\n * attackButton.onActivate(() => player.attack())\r\n * ```\r\n */\r\nexport function createActionButton(options: ActionButtonOptions): ActionButtonInterface {\r\n\treturn new ActionButton(options)\r\n}\r\n\r\n// ============================================================================\r\n// Phase 3: Visual Polish Factory Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Create a camera effects instance.\r\n *\r\n * @param camera - Camera to apply effects to\r\n * @returns A new CameraEffects instance\r\n *\r\n * @example\r\n * ```ts\r\n * const effects = createCameraEffects(camera)\r\n *\r\n * // Shake on hit\r\n * effects.shake(10, 200)\r\n *\r\n * // Flash on damage\r\n * effects.flash('#ff0000', 150)\r\n *\r\n * // Update in game loop\r\n * effects.update(deltaTime)\r\n * effects.apply(context)\r\n * ```\r\n */\r\nexport function createCameraEffects(camera: CameraInterface): CameraEffectsInterface {\r\n\treturn new CameraEffects(camera)\r\n}\r\n\r\n/**\r\n * Create a sprite batch renderer instance.\r\n *\r\n * @param context - Canvas rendering context\r\n * @param assets - Asset manager for texture lookup\r\n * @param options - Sprite batch configuration\r\n * @returns A new SpriteBatch instance\r\n *\r\n * @example\r\n * ```ts\r\n * const batch = createSpriteBatch(context, assets, { sortByTexture: true })\r\n *\r\n * batch.begin()\r\n * for (const sprite of sprites) {\r\n * batch.draw(sprite)\r\n * }\r\n * batch.end()\r\n *\r\n * console.log(batch.getStats())\r\n * ```\r\n */\r\nexport function createSpriteBatch(\r\n\tcontext: CanvasRenderingContext2D,\r\n\tassets: AssetManager,\r\n\toptions?: SpriteBatchOptions,\r\n): SpriteBatchInterface {\r\n\treturn new SpriteBatch(context, assets, options)\r\n}\r\n\r\n// ============================================================================\r\n// Phase 4: UI Expansion Factory Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Create a text input instance.\r\n *\r\n * @param options - Text input configuration\r\n * @returns A new TextInput instance\r\n *\r\n * @example\r\n * ```ts\r\n * const nameInput = createTextInput({\r\n * x: 100,\r\n * y: 200,\r\n * width: 250,\r\n * height: 40,\r\n * placeholder: 'Enter your name',\r\n * maxLength: 20,\r\n * })\r\n *\r\n * nameInput.onSubmit((value) => {\r\n * player.name = value\r\n * })\r\n * ```\r\n */\r\nexport function createTextInput(options: TextInputOptions): TextInputInterface {\r\n\treturn new TextInput(options)\r\n}\r\n\r\n/**\r\n * Create a tooltip manager instance.\r\n *\r\n * @param options - Tooltip manager configuration\r\n * @returns A new TooltipManager instance\r\n *\r\n * @example\r\n * ```ts\r\n * const tooltips = createTooltipManager({ defaultDelay: 300 })\r\n *\r\n * tooltips.attachToElement(healthBar, 'Current HP / Max HP')\r\n * tooltips.attachToElement(attackButton, 'Press to attack\\nCooldown: 0.5s')\r\n *\r\n * // In game loop\r\n * tooltips.update(inputState, deltaTime)\r\n * tooltips.render(context)\r\n * ```\r\n */\r\nexport function createTooltipManager(options?: TooltipManagerOptions): TooltipManagerInterface {\r\n\treturn new TooltipManager(options)\r\n}\r\n\r\n// ============================================================================\r\n// Phase 5: Developer Tools Factory Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Create a debug overlay instance.\r\n *\r\n * @param options - Debug overlay configuration\r\n * @returns A new DebugOverlay instance\r\n *\r\n * @example\r\n * ```ts\r\n * const debug = createDebugOverlay({\r\n * enabled: true,\r\n * position: 'top-left',\r\n * showFPS: true,\r\n * showMemory: true,\r\n * showTouchPoints: true,\r\n * })\r\n *\r\n * // Toggle with key\r\n * input.onKeyDown((key) => {\r\n * if (key === 'F3') debug.toggle()\r\n * })\r\n *\r\n * // In game loop\r\n * debug.update(metrics, inputState)\r\n * debug.render(context)\r\n * ```\r\n */\r\nexport function createDebugOverlay(options?: DebugOverlayOptions): DebugOverlayInterface {\r\n\treturn new DebugOverlay(options)\r\n}\r\n\r\n// ============================================================================\r\n// Phase 6: Persistence Factory Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Create a local storage backend instance.\r\n *\r\n * @param options - Local storage backend configuration\r\n * @returns A new StorageBackend instance\r\n *\r\n * @example\r\n * ```ts\r\n * const storage = createLocalStorageBackend({ prefix: 'mygame:' })\r\n *\r\n * await storage.set('player', playerData)\r\n * const data = await storage.get('player')\r\n * ```\r\n */\r\nexport function createLocalStorageBackend(options?: LocalStorageBackendOptions): StorageBackendInterface {\r\n\treturn new LocalStorageBackend(options)\r\n}\r\n\r\n/**\r\n * Create an IndexedDB storage backend instance.\r\n *\r\n * @param options - IndexedDB backend configuration\r\n * @returns A promise resolving to a new StorageBackend instance\r\n *\r\n * @example\r\n * ```ts\r\n * const storage = await createIndexedDBBackend({\r\n * databaseName: 'mygame',\r\n * storeName: 'saves',\r\n * })\r\n *\r\n * await storage.set('slot1', saveData)\r\n * const save = await storage.get('slot1')\r\n * ```\r\n */\r\nexport async function createIndexedDBBackend(options: IndexedDBBackendOptions): Promise<StorageBackendInterface> {\r\n\treturn IndexedDBBackend.create(options)\r\n}\r\n\r\n/**\r\n * Create a migration runner instance.\r\n *\r\n * @param options - Migration runner configuration\r\n * @returns A new MigrationRunner instance\r\n *\r\n * @example\r\n * ```ts\r\n * const runner = createMigrationRunner({\r\n * migrations: [\r\n * { version: 1, name: 'add-inventory', up: (data) => ({ ...data, inventory: [] }) },\r\n * { version: 2, name: 'add-stats', up: (data) => ({ ...data, stats: { strength: 10 } }) },\r\n * ],\r\n * })\r\n *\r\n * const result = await runner.migrate(oldData, 0)\r\n * if (result.success) {\r\n * console.log('Migrated to version', result.toVersion)\r\n * }\r\n * ```\r\n */\r\nexport function createMigrationRunner(options: MigrationRunnerOptions): MigrationRunnerInterface {\r\n\treturn new MigrationRunner(options)\r\n}\r\n\r\n/**\r\n * Creates a new BuffSystem for managing stackable buffs and debuffs.\r\n *\r\n * @param options - Buff system configuration including buff configs and hooks\r\n * @returns A BuffSystem instance\r\n *\r\n * @example\r\n * ```ts\r\n * const buffs = createBuffSystem({\r\n * configs: {\r\n * speed: { type: 'speed', maxStacks: 3, duration: 10, effectPerStack: 0.15 },\r\n * }\r\n * })\r\n * ```\r\n */\r\nexport function createBuffSystem<TType extends string>(\r\n\toptions: BuffSystemOptions<TType>,\r\n): BuffSystemInterface<TType> {\r\n\treturn new BuffSystem(options)\r\n}\r\n\r\n/**\r\n * Creates a new HealthSystem for managing entity health, damage, and healing.\r\n *\r\n * @param options - Health system configuration\r\n * @returns A HealthSystem instance\r\n */\r\nexport function createHealthSystem<TDamageType extends string>(\r\n\toptions?: HealthSystemOptions<TDamageType>,\r\n): HealthSystemInterface<TDamageType> {\r\n\treturn new HealthSystem(options)\r\n}\r\n\r\n/**\r\n * Creates an inventory system for managing items, equipment, and gold.\r\n *\r\n * @param options - Inventory system configuration\r\n * @returns An InventorySystemInterface instance\r\n *\r\n * @example\r\n * ```ts\r\n * const inventory = createInventorySystem({\r\n * capacity: 20,\r\n * startingGold: 100,\r\n * })\r\n * inventory.addItem(sword, 1)\r\n * inventory.equip('sword-1', 'weapon')\r\n * ```\r\n */\r\nexport function createInventorySystem(options?: InventorySystemOptions): InventorySystemInterface {\r\n\treturn new InventorySystem(options)\r\n}\r\n\r\n/**\r\n * Creates a dialogue system for managing conversations.\r\n *\r\n * @param options - Dialogue system configuration\r\n * @returns A DialogueSystemInterface instance\r\n *\r\n * @example\r\n * ```ts\r\n * const dialogue = createDialogueSystem({\r\n * typewriterSpeed: 50,\r\n * })\r\n * dialogue.loadTree(conversationTree)\r\n * dialogue.start()\r\n * ```\r\n */\r\nexport function createDialogueSystem(options?: DialogueSystemOptions): DialogueSystemInterface {\r\n\treturn new DialogueSystem(options)\r\n}\r\n\r\n/**\r\n * Creates a quest system for managing quests and objectives.\r\n *\r\n * @param options - Quest system configuration\r\n * @returns A QuestSystemInterface instance\r\n *\r\n * @example\r\n * ```ts\r\n * const quests = createQuestSystem({\r\n * maxActiveQuests: 10,\r\n * })\r\n * quests.registerQuest(myQuest)\r\n * quests.start('quest-id')\r\n * ```\r\n */\r\nexport function createQuestSystem(options?: QuestSystemOptions): QuestSystemInterface {\r\n\treturn new QuestSystem(options)\r\n}\r\n\r\n/**\r\n * Creates a radial menu for circular selection interfaces.\r\n *\r\n * @param options - Radial menu configuration\r\n * @returns A RadialMenu instance\r\n *\r\n * @example\r\n * ```ts\r\n * const menu = createRadialMenu({\r\n * x: 0, y: 0, width: 200, height: 200,\r\n * items: [{ id: 'attack', label: 'Attack' }],\r\n * })\r\n * menu.open(400, 300)\r\n * ```\r\n */\r\nexport function createRadialMenu(options: RadialMenuOptions): RadialMenuInterface {\r\n\treturn new RadialMenu(options)\r\n}\r\n\r\n/**\r\n * Creates a minimap for displaying world overview.\r\n *\r\n * @param options - Minimap configuration\r\n * @returns A MinimapInterface instance\r\n *\r\n * @example\r\n * ```ts\r\n * const minimap = createMinimap({\r\n * x: 10, y: 10, width: 150, height: 150,\r\n * worldWidth: 2000, worldHeight: 2000,\r\n * })\r\n * minimap.setPlayerPosition(100, 200)\r\n * ```\r\n */\r\nexport function createMinimap(options: MinimapOptions): MinimapInterface {\r\n\treturn new Minimap(options)\r\n}\r\n\r\n/**\r\n * Creates a notification queue for displaying toast notifications.\r\n *\r\n * @param options - Notification queue configuration\r\n * @returns A NotificationManager instance\r\n *\r\n * @example\r\n * ```ts\r\n * const notifications = createNotificationManager({\r\n * x: 10, y: 10, width: 300, height: 400,\r\n * })\r\n * notifications.achievement('Level Up!', 'You reached level 10!')\r\n * ```\r\n */\r\nexport function createNotificationManager(options: NotificationManagerOptions): NotificationManagerInterface {\r\n\treturn new NotificationManager(options)\r\n}\r\n\r\n/**\r\n * Creates an entity inspector for debugging entity properties.\r\n *\r\n * @param options - Entity inspector configuration\r\n * @returns An EntityInspector instance\r\n *\r\n * @example\r\n * ```ts\r\n * const inspector = createEntityInspector({\r\n * position: 'right',\r\n * width: 300,\r\n * })\r\n * inspector.selectEntity(player)\r\n * ```\r\n */\r\nexport function createEntityInspector(options?: EntityInspectorOptions): EntityInspectorInterface {\r\n\treturn new EntityInspector(options)\r\n}\r\n\r\n/**\r\n * Creates a command console for developer debugging.\r\n *\r\n * @param options - Command console configuration\r\n * @returns A CommandConsole instance\r\n *\r\n * @example\r\n * ```ts\r\n * const console = createCommandConsole({ toggleKey: '`' })\r\n * console.registerCommand({ name: 'test', ... })\r\n * ```\r\n */\r\nexport function createCommandConsole(options?: CommandConsoleOptions): CommandConsoleInterface {\r\n\treturn new CommandConsole(options)\r\n}\r\n\r\n/**\r\n * Creates a culling system for optimizing rendering.\r\n *\r\n * @param options - Culling system configuration\r\n * @returns A CullingSystem instance\r\n *\r\n * @example\r\n * ```ts\r\n * const culling = createCullingSystem({\r\n * strategy: 'frustum',\r\n * margin: 50,\r\n * })\r\n * const visible = culling.getVisibleEntities(entities, camera)\r\n * ```\r\n */\r\nexport function createCullingSystem(options?: CullingOptions): CullingSystemInterface {\r\n\treturn new CullingSystem(options)\r\n}\r\n\r\n/**\r\n * Creates a LOD system for distance-based rendering quality.\r\n *\r\n * @param options - LOD system configuration\r\n * @returns A LODSystem instance\r\n *\r\n * @example\r\n * ```ts\r\n * const lod = createLODSystem({\r\n * updateInterval: 100,\r\n * })\r\n * lod.update(player.x, player.y, entities)\r\n * ```\r\n */\r\nexport function createLODSystem(options?: LODSystemOptions): LODSystemInterface {\r\n\treturn new LODSystem(options)\r\n}\r\n\r\n/**\r\n * Creates a new FloatingTextSystem for visual feedback like damage numbers.\r\n *\r\n * @param options - Floating text system configuration\r\n * @returns A FloatingTextSystem instance\r\n */\r\nexport function createFloatingTextSystem(\r\n\toptions?: FloatingTextSystemOptions,\r\n): FloatingTextSystemInterface {\r\n\treturn new FloatingTextSystem(options)\r\n}\r\n\r\n/**\r\n * Creates a new CollectibleSystem for managing pickups and loot.\r\n *\r\n * @param options - Collectible system configuration including drop table\r\n * @returns A CollectibleSystem instance\r\n */\r\nexport function createCollectibleSystem<TType extends string>(\r\n\toptions: CollectibleSystemOptions<TType>,\r\n): CollectibleSystemInterface<TType> {\r\n\treturn new CollectibleSystem(options)\r\n}\r\n\r\n// ============================================================================\r\n// World Systems Factory Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Creates a new SpawnerSystem for managing entity spawning with zones and waves.\r\n *\r\n * @param options - Spawner system configuration\r\n * @returns A SpawnerSystem instance\r\n */\r\nexport function createSpawnerSystem<TEntity extends SimpleEntityInterface, TType extends string>(\r\n\toptions: SpawnerSystemOptions<TEntity, TType>,\r\n): SpawnerSystemInterface<TEntity> {\r\n\treturn new SpawnerSystem(options)\r\n}\r\n\r\n/**\r\n * Creates a new EffectZoneSystem for managing interactable zones.\r\n *\r\n * @param options - Effect zone system configuration\r\n * @returns An EffectZoneSystem instance\r\n */\r\nexport function createEffectZoneSystem<TEffect extends string>(\r\n\toptions?: EffectZoneSystemOptions<TEffect>,\r\n): EffectZoneSystemInterface<TEffect> {\r\n\treturn new EffectZoneSystem(options)\r\n}\r\n\r\n/**\r\n * Creates a new BackgroundSystem for parallax backgrounds and starfields.\r\n *\r\n * @param options - Background system configuration\r\n * @returns A BackgroundSystem instance\r\n */\r\nexport function createBackgroundSystem(\r\n\toptions?: BackgroundSystemOptions,\r\n): BackgroundSystemInterface {\r\n\treturn new BackgroundSystem(options)\r\n}\r\n\r\n// ============================================================================\r\n// Progression Systems Factory Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Creates a new ExperienceSystem for XP and leveling.\r\n *\r\n * @param options - Experience system configuration\r\n * @returns An ExperienceSystem instance\r\n */\r\nexport function createExperienceSystem<TReward = unknown>(\r\n\toptions?: ExperienceSystemOptions<TReward>,\r\n): ExperienceSystemInterface<TReward> {\r\n\treturn new ExperienceSystem(options)\r\n}\r\n\r\n/**\r\n * Creates a new StatisticsSystem for analytics and achievements.\r\n *\r\n * @param options - Statistics system configuration\r\n * @returns A StatisticsSystem instance\r\n */\r\nexport function createStatisticsSystem(\r\n\toptions?: StatisticsSystemOptions,\r\n): StatisticsSystemInterface {\r\n\treturn new StatisticsSystem(options)\r\n}\r\n\r\n/**\r\n * Creates a new ObjectiveSystem for goals and progress tracking.\r\n *\r\n * @param options - Objective system configuration\r\n * @returns An ObjectiveSystem instance\r\n */\r\nexport function createObjectiveSystem(\r\n\toptions?: ObjectiveSystemOptions,\r\n): ObjectiveSystemInterface {\r\n\treturn new ObjectiveSystem(options)\r\n}\r\n\r\n// ============================================================================\r\n// Control Systems Factory Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Creates a new StateMachine for game flow control.\r\n *\r\n * @param options - State machine configuration including initial state and transitions\r\n * @returns A StateMachine instance\r\n */\r\nexport function createStateMachine<TState extends string>(\r\n\toptions: StateMachineOptions<TState>,\r\n): StateMachineInterface<TState> {\r\n\treturn new StateMachine(options)\r\n}\r\n\r\n/**\r\n * Creates a new CrosshairSystem for aiming cursor.\r\n *\r\n * @param options - Crosshair system configuration\r\n * @returns A CrosshairSystem instance\r\n */\r\nexport function createCrosshairSystem(\r\n\toptions?: CrosshairSystemOptions,\r\n): CrosshairSystemInterface {\r\n\treturn new CrosshairSystem(options)\r\n}\r\n\r\n/**\r\n * Creates a new EntityRendererRegistry for procedural entity drawing.\r\n *\r\n * @returns An EntityRendererRegistry instance\r\n */\r\nexport function createEntityRendererRegistry<TType extends string, TEntity extends SimpleEntityInterface>(): EntityRendererRegistryInterface<TType, TEntity> {\r\n\treturn new EntityRendererRegistry()\r\n}\r\n","import type { QuadtreeInterface, EntityInterface, EntityBounds } from '../../types.js'\r\n\r\n/**\r\n * Quadtree for spatial partitioning.\r\n */\r\nexport class Quadtree implements QuadtreeInterface {\r\n\treadonly maxObjects: number\r\n\treadonly maxLevels: number\r\n\t#level: number\r\n\t#bounds: EntityBounds\r\n\t#entities: { entity: EntityInterface; bounds: EntityBounds }[] = []\r\n\t#nodes: Quadtree[] = []\r\n\r\n\tconstructor(bounds: EntityBounds, maxObjects = 10, maxLevels = 4, level = 0) {\r\n\t\tthis.maxObjects = maxObjects\r\n\t\tthis.maxLevels = maxLevels\r\n\t\tthis.#level = level\r\n\t\tthis.#bounds = bounds\r\n\t}\r\n\r\n\t#split(): void {\r\n\t\tconst halfWidth = this.#bounds.width / 2\r\n\t\tconst halfHeight = this.#bounds.height / 2\r\n\t\tconst x = this.#bounds.left\r\n\t\tconst y = this.#bounds.top\r\n\r\n\t\t// NW, NE, SW, SE\r\n\t\tthis.#nodes = [\r\n\t\t\tnew Quadtree({\r\n\t\t\t\tleft: x, top: y, right: x + halfWidth, bottom: y + halfHeight,\r\n\t\t\t\twidth: halfWidth, height: halfHeight,\r\n\t\t\t}, this.maxObjects, this.maxLevels, this.#level + 1),\r\n\t\t\tnew Quadtree({\r\n\t\t\t\tleft: x + halfWidth, top: y, right: x + this.#bounds.width, bottom: y + halfHeight,\r\n\t\t\t\twidth: halfWidth, height: halfHeight,\r\n\t\t\t}, this.maxObjects, this.maxLevels, this.#level + 1),\r\n\t\t\tnew Quadtree({\r\n\t\t\t\tleft: x, top: y + halfHeight, right: x + halfWidth, bottom: y + this.#bounds.height,\r\n\t\t\t\twidth: halfWidth, height: halfHeight,\r\n\t\t\t}, this.maxObjects, this.maxLevels, this.#level + 1),\r\n\t\t\tnew Quadtree({\r\n\t\t\t\tleft: x + halfWidth, top: y + halfHeight, right: x + this.#bounds.width, bottom: y + this.#bounds.height,\r\n\t\t\t\twidth: halfWidth, height: halfHeight,\r\n\t\t\t}, this.maxObjects, this.maxLevels, this.#level + 1),\r\n\t\t]\r\n\t}\r\n\r\n\t#getIndex(bounds: EntityBounds): number {\r\n\t\tconst midX = this.#bounds.left + this.#bounds.width / 2\r\n\t\tconst midY = this.#bounds.top + this.#bounds.height / 2\r\n\r\n\t\tconst fitsTop = bounds.bottom < midY\r\n\t\tconst fitsBottom = bounds.top > midY\r\n\t\tconst fitsLeft = bounds.right < midX\r\n\t\tconst fitsRight = bounds.left > midX\r\n\r\n\t\tif (fitsTop) {\r\n\t\t\tif (fitsLeft) return 0 // NW\r\n\t\t\tif (fitsRight) return 1 // NE\r\n\t\t} else if (fitsBottom) {\r\n\t\t\tif (fitsLeft) return 2 // SW\r\n\t\t\tif (fitsRight) return 3 // SE\r\n\t\t}\r\n\t\treturn -1 // Doesn't fit completely in a child\r\n\t}\r\n\r\n\tinsert(entity: EntityInterface, bounds: EntityBounds): void {\r\n\t\t// If has children, try to insert into appropriate child\r\n\t\tif (this.#nodes.length > 0) {\r\n\t\t\tconst index = this.#getIndex(bounds)\r\n\t\t\tif (index !== -1) {\r\n\t\t\t\tthis.#nodes[index]?.insert(entity, bounds)\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Add to this node\r\n\t\tthis.#entities.push({ entity, bounds })\r\n\r\n\t\t// Split if at capacity and not at max level\r\n\t\tif (this.#entities.length > this.maxObjects && this.#level < this.maxLevels && this.#nodes.length === 0) {\r\n\t\t\tthis.#split()\r\n\r\n\t\t\t// Redistribute entities to children\r\n\t\t\tconst entitiesToRedistribute = [...this.#entities]\r\n\t\t\tthis.#entities = []\r\n\r\n\t\t\tfor (const item of entitiesToRedistribute) {\r\n\t\t\t\tconst index = this.#getIndex(item.bounds)\r\n\t\t\t\tif (index !== -1) {\r\n\t\t\t\t\tthis.#nodes[index]?.insert(item.entity, item.bounds)\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.#entities.push(item)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tremove(entity: EntityInterface): void {\r\n\t\t// Check children first\r\n\t\tfor (const node of this.#nodes) {\r\n\t\t\tnode.remove(entity)\r\n\t\t}\r\n\r\n\t\t// Remove from this node\r\n\t\tconst index = this.#entities.findIndex(item => item.entity.id === entity.id)\r\n\t\tif (index !== -1) {\r\n\t\t\tthis.#entities.splice(index, 1)\r\n\t\t}\r\n\t}\r\n\r\n\tquery(bounds: EntityBounds): readonly EntityInterface[] {\r\n\t\tconst result: EntityInterface[] = []\r\n\r\n\t\t// Check if query bounds overlaps this node\r\n\t\tif (!this.#boundsOverlap(bounds, this.#bounds)) {\r\n\t\t\treturn result\r\n\t\t}\r\n\r\n\t\t// Add entities from this node that overlap\r\n\t\tfor (const item of this.#entities) {\r\n\t\t\tif (this.#boundsOverlap(bounds, item.bounds)) {\r\n\t\t\t\tresult.push(item.entity)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Query children\r\n\t\tfor (const node of this.#nodes) {\r\n\t\t\tresult.push(...node.query(bounds))\r\n\t\t}\r\n\r\n\t\treturn result\r\n\t}\r\n\r\n\t#boundsOverlap(a: EntityBounds, b: EntityBounds): boolean {\r\n\t\treturn a.left < b.right && a.right > b.left && a.top < b.bottom && a.bottom > b.top\r\n\t}\r\n\r\n\tclear(): void {\r\n\t\tthis.#entities.length = 0\r\n\t\tthis.#nodes.length = 0\r\n\t}\r\n\r\n\tgetEntityCount(): number {\r\n\t\tlet count = this.#entities.length\r\n\t\tfor (const node of this.#nodes) {\r\n\t\t\tcount += node.getEntityCount()\r\n\t\t}\r\n\t\treturn count\r\n\t}\r\n\r\n\tgetNodeCount(): number {\r\n\t\tlet count = 1\r\n\t\tfor (const node of this.#nodes) {\r\n\t\t\tcount += node.getNodeCount()\r\n\t\t}\r\n\t\treturn count\r\n\t}\r\n}\r\n","import type { SpatialGridInterface, EntityInterface, EntityBounds } from '../../types.js'\r\n\r\n/**\r\n * Spatial hash grid for broad-phase collision detection.\r\n */\r\nexport class SpatialGrid implements SpatialGridInterface {\r\n\treadonly cellSize: number\r\n\t#grid: Map<string, Set<EntityInterface>> = new Map()\r\n\t#entityCells: Map<string, Set<string>> = new Map() // Track which cells each entity is in\r\n\r\n\tconstructor(cellSize: number) {\r\n\t\tthis.cellSize = cellSize\r\n\t}\r\n\r\n\t#getCellKey(cellX: number, cellY: number): string {\r\n\t\treturn `${cellX},${cellY}`\r\n\t}\r\n\r\n\t#getCellsForBounds(bounds: EntityBounds): string[] {\r\n\t\tconst minCellX = Math.floor(bounds.left / this.cellSize)\r\n\t\tconst maxCellX = Math.floor(bounds.right / this.cellSize)\r\n\t\tconst minCellY = Math.floor(bounds.top / this.cellSize)\r\n\t\tconst maxCellY = Math.floor(bounds.bottom / this.cellSize)\r\n\r\n\t\tconst cells: string[] = []\r\n\t\tfor (let x = minCellX; x <= maxCellX; x++) {\r\n\t\t\tfor (let y = minCellY; y <= maxCellY; y++) {\r\n\t\t\t\tcells.push(this.#getCellKey(x, y))\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn cells\r\n\t}\r\n\r\n\tinsert(entity: EntityInterface, bounds: EntityBounds): void {\r\n\t\tconst cells = this.#getCellsForBounds(bounds)\r\n\t\tconst entityId = entity.id\r\n\r\n\t\t// Track cells for this entity\r\n\t\tif (!this.#entityCells.has(entityId)) {\r\n\t\t\tthis.#entityCells.set(entityId, new Set())\r\n\t\t}\r\n\t\tconst entityCellSet = this.#entityCells.get(entityId)!\r\n\r\n\t\t// Add entity to each overlapping cell\r\n\t\tfor (const cellKey of cells) {\r\n\t\t\tif (!this.#grid.has(cellKey)) {\r\n\t\t\t\tthis.#grid.set(cellKey, new Set())\r\n\t\t\t}\r\n\t\t\tthis.#grid.get(cellKey)!.add(entity)\r\n\t\t\tentityCellSet.add(cellKey)\r\n\t\t}\r\n\t}\r\n\r\n\tremove(entity: EntityInterface): void {\r\n\t\tconst entityId = entity.id\r\n\t\tconst cellKeys = this.#entityCells.get(entityId)\r\n\r\n\t\tif (cellKeys) {\r\n\t\t\tfor (const cellKey of cellKeys) {\r\n\t\t\t\tconst cell = this.#grid.get(cellKey)\r\n\t\t\t\tif (cell) {\r\n\t\t\t\t\tcell.delete(entity)\r\n\t\t\t\t\tif (cell.size === 0) {\r\n\t\t\t\t\t\tthis.#grid.delete(cellKey)\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tthis.#entityCells.delete(entityId)\r\n\t\t}\r\n\t}\r\n\r\n\tupdate(entity: EntityInterface, bounds: EntityBounds): void {\r\n\t\tthis.remove(entity)\r\n\t\tthis.insert(entity, bounds)\r\n\t}\r\n\r\n\tquery(bounds: EntityBounds): readonly EntityInterface[] {\r\n\t\tconst cells = this.#getCellsForBounds(bounds)\r\n\t\tconst result = new Set<EntityInterface>()\r\n\r\n\t\tfor (const cellKey of cells) {\r\n\t\t\tconst cell = this.#grid.get(cellKey)\r\n\t\t\tif (cell) {\r\n\t\t\t\tfor (const entity of cell) {\r\n\t\t\t\t\tresult.add(entity)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn Array.from(result)\r\n\t}\r\n\r\n\tqueryRadius(x: number, y: number, radius: number): readonly EntityInterface[] {\r\n\t\t// Create a bounding box around the radius\r\n\t\tconst bounds: EntityBounds = {\r\n\t\t\tleft: x - radius,\r\n\t\t\tright: x + radius,\r\n\t\t\ttop: y - radius,\r\n\t\t\tbottom: y + radius,\r\n\t\t\twidth: radius * 2,\r\n\t\t\theight: radius * 2,\r\n\t\t}\r\n\r\n\t\t// Query the bounding box and filter by actual distance\r\n\t\tconst candidates = this.query(bounds)\r\n\t\tconst radiusSq = radius * radius\r\n\r\n\t\treturn candidates.filter(entity => {\r\n\t\t\tconst ex = entity.getX() + entity.getWidth() / 2\r\n\t\t\tconst ey = entity.getY() + entity.getHeight() / 2\r\n\t\t\tconst dx = ex - x\r\n\t\t\tconst dy = ey - y\r\n\t\t\treturn (dx * dx + dy * dy) <= radiusSq\r\n\t\t})\r\n\t}\r\n\r\n\tclear(): void {\r\n\t\tthis.#grid.clear()\r\n\t\tthis.#entityCells.clear()\r\n\t}\r\n\r\n\tgetEntityCount(): number {\r\n\t\treturn this.#entityCells.size\r\n\t}\r\n\r\n\tgetCellCount(): number {\r\n\t\treturn this.#grid.size\r\n\t}\r\n}\r\n","/**\r\n * Dependency tracking context for reactive stores.\r\n *\r\n * Provides a global subscriber stack that enables computed values\r\n * to automatically track which stores they depend on.\r\n */\r\n\r\nimport type { Subscriber } from '../../types.js'\r\n\r\n/** Stack of active subscribers for dependency tracking */\r\nconst subscriberStack: Subscriber[] = []\r\n\r\n/**\r\n * Push a subscriber onto the tracking stack.\r\n *\r\n * @param subscriber - The subscriber to track dependencies for\r\n */\r\nexport function pushSubscriber(subscriber: Subscriber): void {\r\n\tsubscriberStack.push(subscriber)\r\n}\r\n\r\n/**\r\n * Pop the current subscriber from the tracking stack.\r\n *\r\n * @returns The popped subscriber or undefined if stack was empty\r\n */\r\nexport function popSubscriber(): Subscriber | undefined {\r\n\treturn subscriberStack.pop()\r\n}\r\n\r\n/**\r\n * Get the current active subscriber.\r\n *\r\n * @returns The current subscriber or undefined if none active\r\n */\r\nexport function getCurrentSubscriber(): Subscriber | undefined {\r\n\treturn subscriberStack.length > 0\r\n\t\t? subscriberStack[subscriberStack.length - 1]\r\n\t\t: undefined\r\n}\r\n\r\n/**\r\n * Check if dependency tracking is currently active.\r\n *\r\n * @returns True if there's an active subscriber\r\n */\r\nexport function isTracking(): boolean {\r\n\treturn subscriberStack.length > 0\r\n}\r\n","import type { CacheInterface, CacheOptions, CacheStats, CacheEntry, CacheStrategy, Unsubscribe } from '../../types.js'\r\nimport { now } from '../../helpers.js'\r\n\r\n/**\r\n * Cache implementation with LRU eviction and expiration support.\r\n */\r\nexport class Cache<T = unknown> implements CacheInterface<T> {\r\n\t#strategy: CacheStrategy\r\n\t#maxSize: number\r\n\t#maxAge: number\r\n\t#maxEntries: number\r\n\t#entries: Map<string, CacheEntry<T>> = new Map()\r\n\t#stats = { hitCount: 0, missCount: 0, evictionCount: 0 }\r\n\r\n\t#listeners = {\r\n\t\tevict: new Set<(entry: CacheEntry<T>) => void>(),\r\n\t\thit: new Set<(key: string, value: T) => void>(),\r\n\t\tmiss: new Set<(key: string) => void>(),\r\n\t}\r\n\r\n\tconstructor(options: CacheOptions<T>) {\r\n\t\tthis.#strategy = options.strategy\r\n\t\tthis.#maxSize = options.maxSize\r\n\t\tthis.#maxAge = options.maxAge\r\n\t\tthis.#maxEntries = options.maxEntries ?? 1000\r\n\r\n\t\tif (options.onEvict) this.#listeners.evict.add(options.onEvict)\r\n\t\tif (options.onHit) this.#listeners.hit.add(options.onHit)\r\n\t\tif (options.onMiss) this.#listeners.miss.add(options.onMiss)\r\n\t}\r\n\r\n\tgetStrategy(): CacheStrategy {\r\n\t\treturn this.#strategy\r\n\t}\r\n\r\n\tgetMaxSize(): number {\r\n\t\treturn this.#maxSize\r\n\t}\r\n\r\n\tgetSize(): number {\r\n\t\tlet totalSize = 0\r\n\t\tfor (const entry of this.#entries.values()) {\r\n\t\t\ttotalSize += entry.size\r\n\t\t}\r\n\t\treturn totalSize\r\n\t}\r\n\r\n\tgetEntryCount(): number {\r\n\t\treturn this.#entries.size\r\n\t}\r\n\r\n\tgetStats(): CacheStats {\r\n\t\tconst total = this.#stats.hitCount + this.#stats.missCount\r\n\t\treturn {\r\n\t\t\tsize: this.getSize(),\r\n\t\t\tentryCount: this.getEntryCount(),\r\n\t\t\thitCount: this.#stats.hitCount,\r\n\t\t\tmissCount: this.#stats.missCount,\r\n\t\t\thitRate: total > 0 ? this.#stats.hitCount / total : 0,\r\n\t\t\tevictionCount: this.#stats.evictionCount,\r\n\t\t}\r\n\t}\r\n\r\n\thas(key: string): boolean {\r\n\t\tconst entry = this.#entries.get(key)\r\n\t\tif (!entry) return false\r\n\t\tif (this.#isExpired(entry)) {\r\n\t\t\tthis.delete(key)\r\n\t\t\treturn false\r\n\t\t}\r\n\t\treturn true\r\n\t}\r\n\r\n\tget(key: string): T | undefined {\r\n\t\tconst entry = this.#entries.get(key)\r\n\t\tif (!entry) {\r\n\t\t\tthis.#stats.missCount++\r\n\t\t\tthis.#listeners.miss.forEach(cb => cb(key))\r\n\t\t\treturn undefined\r\n\t\t}\r\n\r\n\t\tif (this.#isExpired(entry)) {\r\n\t\t\tthis.delete(key)\r\n\t\t\tthis.#stats.missCount++\r\n\t\t\tthis.#listeners.miss.forEach(cb => cb(key))\r\n\t\t\treturn undefined\r\n\t\t}\r\n\r\n\t\t// Update for LRU\r\n\t\tconst updated: CacheEntry<T> = { ...entry, lastAccessedAt: now(), accessCount: entry.accessCount + 1 }\r\n\t\tthis.#entries.delete(key)\r\n\t\tthis.#entries.set(key, updated)\r\n\r\n\t\tthis.#stats.hitCount++\r\n\t\tthis.#listeners.hit.forEach(cb => cb(key, entry.value))\r\n\t\treturn entry.value\r\n\t}\r\n\r\n\tgetEntry(key: string): CacheEntry<T> | undefined {\r\n\t\treturn this.#entries.get(key)\r\n\t}\r\n\r\n\tset(key: string, value: T): void {\r\n\t\tconst expiresAt = this.#maxAge > 0 ? now() + this.#maxAge : undefined\r\n\t\tthis.setWithExpiry(key, value, expiresAt)\r\n\t}\r\n\r\n\tsetWithExpiry(key: string, value: T, expiresAt?: number): void {\r\n\t\tconst size = this.#estimateSize(value)\r\n\t\tthis.#evictIfNeeded(size)\r\n\r\n\t\tconst timestamp = now()\r\n\t\tconst entry: CacheEntry<T> = {\r\n\t\t\tkey,\r\n\t\t\tvalue,\r\n\t\t\tsize,\r\n\t\t\tcreatedAt: timestamp,\r\n\t\t\tlastAccessedAt: timestamp,\r\n\t\t\taccessCount: 0,\r\n\t\t}\r\n\t\tif (expiresAt !== undefined) {\r\n\t\t\t(entry as unknown as Record<string, unknown>).expiresAt = expiresAt\r\n\t\t}\r\n\r\n\t\tthis.#entries.delete(key)\r\n\t\tthis.#entries.set(key, entry)\r\n\t}\r\n\r\n\tdelete(key: string): boolean {\r\n\t\tconst entry = this.#entries.get(key)\r\n\t\tif (entry) {\r\n\t\t\tthis.#entries.delete(key)\r\n\t\t\treturn true\r\n\t\t}\r\n\t\treturn false\r\n\t}\r\n\r\n\tdeleteExpired(): number {\r\n\t\tconst timestamp = now()\r\n\t\tlet count = 0\r\n\t\tfor (const [key, entry] of this.#entries) {\r\n\t\t\tif (this.#isExpiredAt(entry, timestamp)) {\r\n\t\t\t\tthis.#evict(key)\r\n\t\t\t\tcount++\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn count\r\n\t}\r\n\r\n\tclear(): void {\r\n\t\tthis.#entries.clear()\r\n\t\tthis.#stats.hitCount = 0\r\n\t\tthis.#stats.missCount = 0\r\n\t\tthis.#stats.evictionCount = 0\r\n\t}\r\n\r\n\tkeys(): readonly string[] {\r\n\t\treturn Array.from(this.#entries.keys())\r\n\t}\r\n\r\n\tvalues(): readonly T[] {\r\n\t\treturn Array.from(this.#entries.values()).map(e => e.value)\r\n\t}\r\n\r\n\t/**\r\n\t * Preloads cache entries for the specified keys from a backing store.\r\n\t * For memory-only cache, this validates the keys are valid cache key strings.\r\n\t * Subclasses with storage backing should override this method to load from persistent storage.\r\n\t *\r\n\t * @param keys - Array of cache keys to preload\r\n\t * @remarks Key validation is synchronous but fast (type and length checks only).\r\n\t * For extremely large key arrays, consider batching at the call site.\r\n\t */\r\n\tasync preload(keys: readonly string[]): Promise<void> {\r\n\t\t// Memory-only cache has no backing store to preload from.\r\n\t\t// Validate that keys are valid cache key strings for consistent behavior.\r\n\t\t// This validation is fast (O(n) with simple checks) and ensures subclasses\r\n\t\t// can rely on validated input when they override this method.\r\n\t\tfor (const key of keys) {\r\n\t\t\tif (typeof key !== 'string' || key.length === 0) {\r\n\t\t\t\tthrow new Error(`Invalid cache key: ${String(key)}`)\r\n\t\t\t}\r\n\t\t}\r\n\t\t// No-op for memory-only cache - storage-backed implementations should override\r\n\t}\r\n\r\n\t/**\r\n\t * Flushes cached entries to a backing store.\r\n\t * For memory-only cache, this is a no-op since there's no backing store.\r\n\t * Subclasses with storage backing should override this method.\r\n\t */\r\n\tasync flush(): Promise<void> {\r\n\t\t// Memory-only cache has no backing store to flush to.\r\n\t\t// This is intentionally a no-op for the base implementation.\r\n\t\t// Storage-backed cache implementations should override this method\r\n\t\t// to persist entries to persistent storage (localStorage, IndexedDB, etc.)\r\n\t}\r\n\r\n\tonEvict(callback: (entry: CacheEntry<T>) => void): Unsubscribe {\r\n\t\tthis.#listeners.evict.add(callback)\r\n\t\treturn () => this.#listeners.evict.delete(callback)\r\n\t}\r\n\r\n\tonHit(callback: (key: string, value: T) => void): Unsubscribe {\r\n\t\tthis.#listeners.hit.add(callback)\r\n\t\treturn () => this.#listeners.hit.delete(callback)\r\n\t}\r\n\r\n\tonMiss(callback: (key: string) => void): Unsubscribe {\r\n\t\tthis.#listeners.miss.add(callback)\r\n\t\treturn () => this.#listeners.miss.delete(callback)\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.clear()\r\n\t\tthis.#listeners.evict.clear()\r\n\t\tthis.#listeners.hit.clear()\r\n\t\tthis.#listeners.miss.clear()\r\n\t}\r\n\r\n\t#isExpired(entry: CacheEntry<T>): boolean {\r\n\t\treturn this.#isExpiredAt(entry, now())\r\n\t}\r\n\r\n\t#isExpiredAt(entry: CacheEntry<T>, timestamp: number): boolean {\r\n\t\tconst expiresAt = (entry as unknown as Record<string, unknown>).expiresAt as number | undefined\r\n\t\treturn expiresAt !== undefined && timestamp > expiresAt\r\n\t}\r\n\r\n\t#estimateSize(value: T): number {\r\n\t\ttry { return JSON.stringify(value).length * 2 }\r\n\t\tcatch { return 1024 }\r\n\t}\r\n\r\n\t#evictIfNeeded(incomingSize: number): void {\r\n\t\twhile (this.#entries.size >= this.#maxEntries) this.#evictLRU()\r\n\t\twhile (this.getSize() + incomingSize > this.#maxSize && this.#entries.size > 0) this.#evictLRU()\r\n\t}\r\n\r\n\t#evictLRU(): void {\r\n\t\tconst firstKey = this.#entries.keys().next().value\r\n\t\tif (firstKey !== undefined) this.#evict(firstKey)\r\n\t}\r\n\r\n\t#evict(key: string): void {\r\n\t\tconst entry = this.#entries.get(key)\r\n\t\tif (entry) {\r\n\t\t\tthis.#entries.delete(key)\r\n\t\t\tthis.#stats.evictionCount++\r\n\t\t\tthis.#listeners.evict.forEach(cb => cb(entry))\r\n\t\t}\r\n\t}\r\n}\r\n","import type {\r\n\tMetricsCollectorInterface,\r\n\tStorageMetrics,\r\n\tStoreOperationStats,\r\n\tErrorRecord,\r\n} from '../../types.js'\r\n\r\n/**\r\n * Metrics collector for monitoring storage operations.\r\n */\r\nexport class MetricsCollector implements MetricsCollectorInterface {\r\n\t#operations = { total: 0, successful: 0, failed: 0, totalDuration: 0 }\r\n\t#stores: Map<string, StoreOperationStats> = new Map()\r\n\t#errors: ErrorRecord[] = []\r\n\t#maxErrors = 100\r\n\r\n\trecordOperation(operation: string, duration: number, success: boolean): void {\r\n\t\tthis.#operations.total++\r\n\t\tthis.#operations.totalDuration += duration\r\n\t\tif (success) {\r\n\t\t\tthis.#operations.successful++\r\n\t\t} else {\r\n\t\t\tthis.#operations.failed++\r\n\t\t}\r\n\t}\r\n\r\n\trecordSize(storeName: string, size: number): void {\r\n\t\tconst store = this.#getOrCreateStore(storeName)\r\n\t\tthis.#stores.set(storeName, { ...store, size })\r\n\t}\r\n\r\n\trecordError(operation: string, error: string): void {\r\n\t\tconst errorRecord: ErrorRecord = {\r\n\t\t\toperation,\r\n\t\t\terror,\r\n\t\t\ttimestamp: Date.now(),\r\n\t\t}\r\n\t\tthis.#errors.push(errorRecord)\r\n\t\t// Keep only recent errors\r\n\t\tif (this.#errors.length > this.#maxErrors) {\r\n\t\t\tthis.#errors.shift()\r\n\t\t}\r\n\t}\r\n\r\n\tgetMetrics(): StorageMetrics {\r\n\t\tconst stores: Record<string, StoreOperationStats> = {}\r\n\t\tfor (const [name, data] of this.#stores) {\r\n\t\t\tstores[name] = { ...data }\r\n\t\t}\r\n\r\n\t\treturn {\r\n\t\t\toperations: {\r\n\t\t\t\ttotal: this.#operations.total,\r\n\t\t\t\tsuccessful: this.#operations.successful,\r\n\t\t\t\tfailed: this.#operations.failed,\r\n\t\t\t\taverageDuration: this.#operations.total > 0\r\n\t\t\t\t\t? this.#operations.totalDuration / this.#operations.total\r\n\t\t\t\t\t: 0,\r\n\t\t\t},\r\n\t\t\tstores,\r\n\t\t\terrors: [...this.#errors],\r\n\t\t}\r\n\t}\r\n\r\n\treset(): void {\r\n\t\tthis.#operations = { total: 0, successful: 0, failed: 0, totalDuration: 0 }\r\n\t\tthis.#stores.clear()\r\n\t\tthis.#errors.length = 0\r\n\t}\r\n\r\n\t#getOrCreateStore(storeName: string): StoreOperationStats {\r\n\t\tif (!this.#stores.has(storeName)) {\r\n\t\t\tthis.#stores.set(storeName, { reads: 0, writes: 0, deletes: 0, size: 0 })\r\n\t\t}\r\n\t\treturn this.#stores.get(storeName)!\r\n\t}\r\n}\r\n","import type { StorageManagerInterface, StorageQuota } from '../../types.js'\r\n\r\n/**\r\n * Storage manager for quota and persistence.\r\n */\r\nexport class StorageManager implements StorageManagerInterface {\r\n\tasync getQuota(): Promise<StorageQuota> {\r\n\t\tif (!navigator.storage || !navigator.storage.estimate) {\r\n\t\t\treturn {\r\n\t\t\t\tusage: 0,\r\n\t\t\t\tquota: 0,\r\n\t\t\t\tusagePercent: 0,\r\n\t\t\t\tavailable: 0,\r\n\t\t\t\tisPersisted: false,\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst estimate = await navigator.storage.estimate()\r\n\t\tconst usage = estimate.usage ?? 0\r\n\t\tconst quota = estimate.quota ?? 0\r\n\r\n\t\treturn {\r\n\t\t\tusage,\r\n\t\t\tquota,\r\n\t\t\tusagePercent: quota > 0 ? (usage / quota) * 100 : 0,\r\n\t\t\tavailable: quota - usage,\r\n\t\t\tisPersisted: await this.isPersisted(),\r\n\t\t}\r\n\t}\r\n\r\n\tasync requestPersistence(): Promise<boolean> {\r\n\t\tif (!navigator.storage || !navigator.storage.persist) {\r\n\t\t\treturn false\r\n\t\t}\r\n\t\treturn await navigator.storage.persist()\r\n\t}\r\n\r\n\tasync isPersisted(): Promise<boolean> {\r\n\t\tif (!navigator.storage || !navigator.storage.persisted) {\r\n\t\t\treturn false\r\n\t\t}\r\n\t\treturn await navigator.storage.persisted()\r\n\t}\r\n\r\n\tasync estimateUsage(): Promise<StorageEstimate> {\r\n\t\tif (!navigator.storage || !navigator.storage.estimate) {\r\n\t\t\treturn { usage: 0, quota: 0 }\r\n\t\t}\r\n\t\treturn await navigator.storage.estimate()\r\n\t}\r\n}\r\n","import type { ObjectPoolInterface, PoolOptions } from '../../types.js'\r\n\r\n/**\r\n * Object pool for reusing objects.\r\n */\r\nexport class ObjectPool<T> implements ObjectPoolInterface<T> {\r\n\t#available: T[] = []\r\n\t#active: Set<T> = new Set()\r\n\t#factory: () => T\r\n\t#reset: ((obj: T) => void) | undefined\r\n\t#validate: ((obj: T) => boolean) | undefined\r\n\t#maxSize: number\r\n\r\n\tconstructor(options: PoolOptions<T>) {\r\n\t\tthis.#factory = options.factory\r\n\t\tthis.#reset = options.reset ?? undefined\r\n\t\tthis.#validate = options.validate ?? undefined\r\n\t\tthis.#maxSize = options.maxSize\r\n\r\n\t\t// Pre-populate pool\r\n\t\tfor (let i = 0; i < options.initialSize; i++) {\r\n\t\t\tthis.#available.push(this.#factory())\r\n\t\t}\r\n\t}\r\n\r\n\tacquire(): T {\r\n\t\tlet obj: T\r\n\r\n\t\tif (this.#available.length > 0) {\r\n\t\t\tobj = this.#available.pop()!\r\n\t\t} else if (this.#active.size < this.#maxSize) {\r\n\t\t\tobj = this.#factory()\r\n\t\t} else {\r\n\t\t\tthrow new Error('Object pool exhausted')\r\n\t\t}\r\n\r\n\t\tthis.#active.add(obj)\r\n\t\treturn obj\r\n\t}\r\n\r\n\trelease(obj: T): void {\r\n\t\tif (!this.#active.has(obj)) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\tthis.#active.delete(obj)\r\n\r\n\t\t// Validate object before returning to pool\r\n\t\tif (this.#validate && !this.#validate(obj)) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\t// Reset object state\r\n\t\tif (this.#reset) {\r\n\t\t\tthis.#reset(obj)\r\n\t\t}\r\n\r\n\t\t// Return to pool if under max size\r\n\t\tif (this.#available.length < this.#maxSize) {\r\n\t\t\tthis.#available.push(obj)\r\n\t\t}\r\n\t}\r\n\r\n\tgetSize(): number {\r\n\t\treturn this.#available.length + this.#active.size\r\n\t}\r\n\r\n\tgetAvailableCount(): number {\r\n\t\treturn this.#available.length\r\n\t}\r\n\r\n\tgetActiveCount(): number {\r\n\t\treturn this.#active.size\r\n\t}\r\n\r\n\tclear(): void {\r\n\t\tthis.#available.length = 0\r\n\t\tthis.#active.clear()\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tthis.clear()\r\n\t}\r\n}\r\n","import type {\r\n\tResourceManagerInterface,\r\n\tObjectPoolInterface,\r\n\tPoolOptions,\r\n\tPoolStats,\r\n} from '../../types.js'\r\nimport { ObjectPool } from './ObjectPool.js'\r\n\r\n/**\r\n * Resource manager for object pooling and memory management.\r\n */\r\nexport class ResourceManager implements ResourceManagerInterface {\r\n\t#pools: Map<string, ObjectPoolInterface<unknown>> = new Map()\r\n\r\n\tcreatePool<T>(name: string, options: PoolOptions<T>): ObjectPool<T> {\r\n\t\tconst pool = new ObjectPool(options)\r\n\t\tthis.#pools.set(name, pool)\r\n\t\treturn pool\r\n\t}\r\n\r\n\tgetPool<T>(name: string): ObjectPool<T> | undefined {\r\n\t\tconst pool = this.#pools.get(name)\r\n\t\tif (!pool) return undefined\r\n\t\t// The caller is responsible for ensuring the correct type\r\n\t\treturn pool as ObjectPool<T>\r\n\t}\r\n\r\n\tremovePool(name: string): void {\r\n\t\tconst pool = this.#pools.get(name)\r\n\t\tif (pool) {\r\n\t\t\tpool.destroy()\r\n\t\t\tthis.#pools.delete(name)\r\n\t\t}\r\n\t}\r\n\r\n\tgetMemoryUsage(): number {\r\n\t\t// Calculate total memory usage from all pools\r\n\t\t// Estimate based on pool size - actual object size would need to be tracked per pool\r\n\t\tlet totalBytes = 0\r\n\t\tfor (const pool of this.#pools.values()) {\r\n\t\t\t// Estimate ~1KB per object as baseline (actual size varies by object type)\r\n\t\t\ttotalBytes += pool.getSize() * 1024\r\n\t\t}\r\n\t\treturn totalBytes\r\n\t}\r\n\r\n\tgetTotalPools(): number {\r\n\t\treturn this.#pools.size\r\n\t}\r\n\r\n\tgetPoolStats(name: string): PoolStats | undefined {\r\n\t\tconst pool = this.#pools.get(name)\r\n\t\tif (!pool) return undefined\r\n\t\treturn {\r\n\t\t\tsize: pool.getSize(),\r\n\t\t\tavailable: pool.getAvailableCount(),\r\n\t\t\tactive: pool.getActiveCount(),\r\n\t\t}\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\tfor (const pool of this.#pools.values()) {\r\n\t\t\tpool.destroy()\r\n\t\t}\r\n\t\tthis.#pools.clear()\r\n\t}\r\n}\r\n","import type { ColliderComponentInterface, CollisionShape, Collider } from '../../types.js'\r\n\r\n/**\r\n * Collider component for collision detection.\r\n */\r\nexport class ColliderComponent implements ColliderComponentInterface {\r\n\treadonly type = 'collider' as const\r\n\treadonly entityId: string\r\n\t#enabled = true\r\n\t#shape: CollisionShape = 'rectangle'\r\n\t#collider: Collider\r\n\t#isTrigger = false\r\n\r\n\tconstructor(entityId: string, collider: Collider) {\r\n\t\tthis.entityId = entityId\r\n\t\tthis.#collider = collider\r\n\t\tthis.#shape = collider.shape\r\n\t}\r\n\r\n\tisEnabled(): boolean {\r\n\t\treturn this.#enabled\r\n\t}\r\n\r\n\tsetEnabled(enabled: boolean): void {\r\n\t\tthis.#enabled = enabled\r\n\t}\r\n\r\n\tgetShape(): CollisionShape {\r\n\t\treturn this.#shape\r\n\t}\r\n\r\n\tgetCollider(): Collider {\r\n\t\treturn this.#collider\r\n\t}\r\n\r\n\tsetShape(shape: CollisionShape): void {\r\n\t\tthis.#shape = shape\r\n\t}\r\n\r\n\tisTrigger(): boolean {\r\n\t\treturn this.#isTrigger\r\n\t}\r\n\r\n\tsetTrigger(trigger: boolean): void {\r\n\t\tthis.#isTrigger = trigger\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\t// Cleanup if needed\r\n\t}\r\n}\r\n","import type { TransformComponentInterface, Vector2 } from '../../types.js'\r\n\r\n/**\r\n * Transform component for entity positioning.\r\n */\r\nexport class TransformComponent implements TransformComponentInterface {\r\n\treadonly type = 'transform' as const\r\n\treadonly entityId: string\r\n\t#enabled = true\r\n\t#x = 0\r\n\t#y = 0\r\n\t#rotation = 0\r\n\t#scaleX = 1\r\n\t#scaleY = 1\r\n\r\n\tconstructor(entityId: string) {\r\n\t\tthis.entityId = entityId\r\n\t}\r\n\r\n\tisEnabled(): boolean {\r\n\t\treturn this.#enabled\r\n\t}\r\n\r\n\tsetEnabled(enabled: boolean): void {\r\n\t\tthis.#enabled = enabled\r\n\t}\r\n\r\n\tgetPosition(): Vector2 {\r\n\t\treturn { x: this.#x, y: this.#y }\r\n\t}\r\n\r\n\tgetRotation(): number {\r\n\t\treturn this.#rotation\r\n\t}\r\n\r\n\tgetScale(): Vector2 {\r\n\t\treturn { x: this.#scaleX, y: this.#scaleY }\r\n\t}\r\n\r\n\tsetPosition(x: number, y: number): void {\r\n\t\tthis.#x = x\r\n\t\tthis.#y = y\r\n\t}\r\n\r\n\tsetRotation(rotation: number): void {\r\n\t\tthis.#rotation = rotation\r\n\t}\r\n\r\n\tsetScale(x: number, y: number): void {\r\n\t\tthis.#scaleX = x\r\n\t\tthis.#scaleY = y\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\t// Cleanup if needed\r\n\t}\r\n}\r\n","import type { SpriteComponentInterface, SpriteSheetInterface } from '../../types.js'\r\n\r\n/**\r\n * Sprite component for rendering sprites.\r\n */\r\nexport class SpriteComponent implements SpriteComponentInterface {\r\n\treadonly type = 'sprite' as const\r\n\treadonly entityId: string\r\n\t#enabled = true\r\n\t#imageKey: string\r\n\t#frame = 0\r\n\t#currentFrame = 0\r\n\t#currentAnimation = ''\r\n\t#spriteSheet: SpriteSheetInterface | null = null\r\n\r\n\tconstructor(entityId: string, imageKey: string, spriteSheet?: SpriteSheetInterface) {\r\n\t\tthis.entityId = entityId\r\n\t\tthis.#imageKey = imageKey\r\n\t\tthis.#spriteSheet = spriteSheet ?? null\r\n\t}\r\n\r\n\tisEnabled(): boolean {\r\n\t\treturn this.#enabled\r\n\t}\r\n\r\n\tsetEnabled(enabled: boolean): void {\r\n\t\tthis.#enabled = enabled\r\n\t}\r\n\r\n\tgetImageKey(): string {\r\n\t\treturn this.#imageKey\r\n\t}\r\n\r\n\tgetFrame(): number {\r\n\t\treturn this.#frame\r\n\t}\r\n\r\n\tsetImageKey(key: string): void {\r\n\t\tthis.#imageKey = key\r\n\t}\r\n\r\n\tsetFrame(frame: number): void {\r\n\t\tthis.#frame = frame\r\n\t}\r\n\r\n\tplayAnimation(name: string): void {\r\n\t\t// Start animation playback - reset frame counter and set current animation\r\n\t\tif (this.#currentAnimation !== name) {\r\n\t\t\tthis.#currentAnimation = name\r\n\t\t\tthis.#currentFrame = 0\r\n\t\t}\r\n\t}\r\n\r\n\tstopAnimation(): void {\r\n\t\tthis.#currentAnimation = ''\r\n\t}\r\n\r\n\tupdate(deltaTime: number): void {\r\n\t\t// Update frame timing if animation is playing\r\n\t\tif (!this.#currentAnimation || !this.#spriteSheet) return\r\n\r\n\t\tconst animation = this.#spriteSheet.getAnimation(this.#currentAnimation)\r\n\t\tif (!animation) return\r\n\r\n\t\tconst frameDuration = 1000 / (animation.frameRate ?? 10)\r\n\t\tthis.#currentFrame += deltaTime * 1000 / frameDuration\r\n\r\n\t\tif (this.#currentFrame >= animation.frames.length) {\r\n\t\t\tif (animation.loop) {\r\n\t\t\t\tthis.#currentFrame = this.#currentFrame % animation.frames.length\r\n\t\t\t} else {\r\n\t\t\t\tthis.#currentFrame = animation.frames.length - 1\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\t// Cleanup if needed\r\n\t}\r\n}\r\n","import type { PhysicsComponentInterface, Vector2 } from '../../types.js'\r\n\r\n/**\r\n * Physics component for entity physics simulation.\r\n */\r\nexport class PhysicsComponent implements PhysicsComponentInterface {\r\n\treadonly type = 'physics' as const\r\n\treadonly entityId: string\r\n\t#enabled = true\r\n\t#velocityX = 0\r\n\t#velocityY = 0\r\n\t#accelerationX = 0\r\n\t#accelerationY = 0\r\n\t#mass = 1\r\n\t#drag = 0.01\r\n\t#useGravity = true\r\n\t#gravityScale = 1\r\n\r\n\tconstructor(entityId: string) {\r\n\t\tthis.entityId = entityId\r\n\t}\r\n\r\n\tisEnabled(): boolean {\r\n\t\treturn this.#enabled\r\n\t}\r\n\r\n\tsetEnabled(enabled: boolean): void {\r\n\t\tthis.#enabled = enabled\r\n\t}\r\n\r\n\tgetVelocity(): Vector2 {\r\n\t\treturn { x: this.#velocityX, y: this.#velocityY }\r\n\t}\r\n\r\n\tgetAcceleration(): Vector2 {\r\n\t\treturn { x: this.#accelerationX, y: this.#accelerationY }\r\n\t}\r\n\r\n\tgetMass(): number {\r\n\t\treturn this.#mass\r\n\t}\r\n\r\n\tsetVelocity(x: number, y: number): void {\r\n\t\tthis.#velocityX = x\r\n\t\tthis.#velocityY = y\r\n\t}\r\n\r\n\tsetAcceleration(x: number, y: number): void {\r\n\t\tthis.#accelerationX = x\r\n\t\tthis.#accelerationY = y\r\n\t}\r\n\r\n\tsetMass(mass: number): void {\r\n\t\tthis.#mass = mass\r\n\t}\r\n\r\n\tapplyForce(x: number, y: number): void {\r\n\t\t// F = ma, so a = F / m\r\n\t\tthis.#accelerationX += x / this.#mass\r\n\t\tthis.#accelerationY += y / this.#mass\r\n\t}\r\n\r\n\tapplyImpulse(x: number, y: number): void {\r\n\t\t// Impulse directly changes velocity\r\n\t\tthis.#velocityX += x / this.#mass\r\n\t\tthis.#velocityY += y / this.#mass\r\n\t}\r\n\r\n\tupdate(deltaTime: number): void {\r\n\t\t// Apply gravity\r\n\t\tif (this.#useGravity) {\r\n\t\t\tthis.#velocityY += this.#gravityScale * 9.8 * deltaTime\r\n\t\t}\r\n\r\n\t\t// Apply drag\r\n\t\tthis.#velocityX *= (1 - this.#drag * deltaTime)\r\n\t\tthis.#velocityY *= (1 - this.#drag * deltaTime)\r\n\r\n\t\t// Note: Position updates should be handled by Entity/PhysicsWorld\r\n\t\t// This component manages velocity state\r\n\t}\r\n\r\n\tdestroy(): void {\r\n\t\t// Cleanup if needed\r\n\t}\r\n}\r\n","import type {\r\n\tComponentFactoryInterface,\r\n\tTransformComponentInterface,\r\n\tSpriteComponentInterface,\r\n\tPhysicsComponentInterface,\r\n\tColliderComponentInterface,\r\n\tPhysicsBodyOptions,\r\n\tCollider,\r\n\tComponent,\r\n\tCustomComponentConstructor,\r\n} from '../../types.js'\r\nimport { TransformComponent } from './TransformComponent.js'\r\nimport { SpriteComponent } from './SpriteComponent.js'\r\nimport { PhysicsComponent } from './PhysicsComponent.js'\r\nimport { ColliderComponent } from './ColliderComponent.js'\r\n\r\n/**\r\n * Component factory for creating ECS components.\r\n */\r\nexport class ComponentFactory implements ComponentFactoryInterface {\r\n\t#customComponentRegistry: Map<string, CustomComponentConstructor<Component>> = new Map()\r\n\r\n\tcreateTransform(entityId: string): TransformComponentInterface {\r\n\t\treturn new TransformComponent(entityId)\r\n\t}\r\n\r\n\tcreateSprite(entityId: string, imageKey: string): SpriteComponentInterface {\r\n\t\treturn new SpriteComponent(entityId, imageKey)\r\n\t}\r\n\r\n\tcreatePhysics(entityId: string, options?: PhysicsBodyOptions): PhysicsComponentInterface {\r\n\t\tconst component = new PhysicsComponent(entityId)\r\n\t\t// Apply physics options if provided\r\n\t\tif (options) {\r\n\t\t\tif (options.velocityX !== undefined || options.velocityY !== undefined) {\r\n\t\t\t\tcomponent.setVelocity(options.velocityX ?? 0, options.velocityY ?? 0)\r\n\t\t\t}\r\n\t\t\tif (options.accelerationX !== undefined || options.accelerationY !== undefined) {\r\n\t\t\t\tcomponent.setAcceleration(options.accelerationX ?? 0, options.accelerationY ?? 0)\r\n\t\t\t}\r\n\t\t\tif (options.mass !== undefined) {\r\n\t\t\t\tcomponent.setMass(options.mass)\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn component\r\n\t}\r\n\r\n\tcreateCollider(entityId: string, collider: Collider): ColliderComponentInterface {\r\n\t\treturn new ColliderComponent(entityId, collider)\r\n\t}\r\n\r\n\t/**\r\n\t * Register a custom component constructor for a given type.\r\n\t */\r\n\tregisterCustomComponent<T extends Component>(type: string, constructor: CustomComponentConstructor<T>): void {\r\n\t\tthis.#customComponentRegistry.set(type, constructor as CustomComponentConstructor<Component>)\r\n\t}\r\n\r\n\tcreateCustom<T extends Component>(type: string, entityId: string, data: unknown): T {\r\n\t\tconst Constructor = this.#customComponentRegistry.get(type)\r\n\t\tif (!Constructor) {\r\n\t\t\tthrow new Error(`Custom component type '${type}' not registered. Use registerCustomComponent first.`)\r\n\t\t}\r\n\t\treturn new Constructor(entityId, data) as T\r\n\t}\r\n}\r\n","import type { ProgressBarInterface, ProgressBarOptions, UIBounds } from '../../types.js'\r\n\r\n/**\r\n * Progress bar UI element.\r\n */\r\nexport class ProgressBar implements ProgressBarInterface {\r\n\treadonly id: string\r\n\t#x: number\r\n\t#y: number\r\n\t#width: number\r\n\t#height: number\r\n\t#visible: boolean\r\n\t#zIndex: number\r\n\t#opacity: number\r\n\t#min: number\r\n\t#max: number\r\n\t#value: number\r\n\t#backgroundColor: string\r\n\t#foregroundColor: string\r\n\t#borderWidth: number\r\n\t#borderColor: string\r\n\t#borderRadius: number\r\n\t#showText: boolean\r\n\t#textColor: string\r\n\r\n\tconstructor(options: ProgressBarOptions) {\r\n\t\tthis.id = crypto.randomUUID()\r\n\t\tthis.#x = options.x\r\n\t\tthis.#y = options.y\r\n\t\tthis.#width = options.width\r\n\t\tthis.#height = options.height\r\n\t\tthis.#visible = options.visible ?? true\r\n\t\tthis.#zIndex = options.zIndex ?? 0\r\n\t\tthis.#opacity = options.opacity ?? 1\r\n\t\tthis.#min = options.min\r\n\t\tthis.#max = options.max\r\n\t\tthis.#value = Math.max(options.min, Math.min(options.max, options.value))\r\n\t\tthis.#backgroundColor = options.backgroundColor ?? '#4a5568'\r\n\t\tthis.#foregroundColor = options.foregroundColor ?? '#48bb78'\r\n\t\tthis.#borderWidth = options.borderWidth ?? 1\r\n\t\tthis.#borderColor = options.borderColor ?? '#ffffff'\r\n\t\tthis.#borderRadius = options.borderRadius ?? 0\r\n\t\tthis.#showText = options.showText ?? false\r\n\t\tthis.#textColor = options.textColor ?? '#ffffff'\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Visibility\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tisVisible(): boolean {\r\n\t\treturn this.#visible\r\n\t}\r\n\r\n\tsetVisible(visible: boolean): void {\r\n\t\tthis.#visible = visible\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Position accessors\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetX(): number {\r\n\t\treturn this.#x\r\n\t}\r\n\r\n\tgetY(): number {\r\n\t\treturn this.#y\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Position mutators\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetX(x: number): void {\r\n\t\tthis.#x = x\r\n\t}\r\n\r\n\tsetY(y: number): void {\r\n\t\tthis.#y = y\r\n\t}\r\n\r\n\tsetPosition(x: number, y: number): void {\r\n\t\tthis.#x = x\r\n\t\tthis.#y = y\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Size accessors\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetWidth(): number {\r\n\t\treturn this.#width\r\n\t}\r\n\r\n\tgetHeight(): number {\r\n\t\treturn this.#height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Size mutators\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetWidth(width: number): void {\r\n\t\tthis.#width = width\r\n\t}\r\n\r\n\tsetHeight(height: number): void {\r\n\t\tthis.#height = height\r\n\t}\r\n\r\n\tsetSize(width: number, height: number): void {\r\n\t\tthis.#width = width\r\n\t\tthis.#height = height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Bounds and hit testing\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetBounds(): UIBounds {\r\n\t\treturn {\r\n\t\t\tx: this.#x,\r\n\t\t\ty: this.#y,\r\n\t\t\twidth: this.#width,\r\n\t\t\theight: this.#height,\r\n\t\t}\r\n\t}\r\n\r\n\tcontains(x: number, y: number): boolean {\r\n\t\treturn x >= this.#x && x <= this.#x + this.#width &&\r\n\t\t\ty >= this.#y && y <= this.#y + this.#height\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Z-Index\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetZIndex(): number {\r\n\t\treturn this.#zIndex\r\n\t}\r\n\r\n\tsetZIndex(zIndex: number): void {\r\n\t\tthis.#zIndex = zIndex\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Opacity\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetOpacity(): number {\r\n\t\treturn this.#opacity\r\n\t}\r\n\r\n\tsetOpacity(opacity: number): void {\r\n\t\tthis.#opacity = Math.max(0, Math.min(1, opacity))\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// ProgressBar: Value accessors\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tgetValue(): number {\r\n\t\treturn this.#value\r\n\t}\r\n\r\n\tgetMin(): number {\r\n\t\treturn this.#min\r\n\t}\r\n\r\n\tgetMax(): number {\r\n\t\treturn this.#max\r\n\t}\r\n\r\n\tgetProgress(): number {\r\n\t\tconst range = this.#max - this.#min\r\n\t\treturn range > 0 ? (this.#value - this.#min) / range : 0\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// ProgressBar: Value mutators\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetValue(value: number): void {\r\n\t\tthis.#value = Math.max(this.#min, Math.min(this.#max, value))\r\n\t}\r\n\r\n\tsetMin(min: number): void {\r\n\t\tthis.#min = min\r\n\t\tthis.#value = Math.max(this.#min, Math.min(this.#max, this.#value))\r\n\t}\r\n\r\n\tsetMax(max: number): void {\r\n\t\tthis.#max = max\r\n\t\tthis.#value = Math.max(this.#min, Math.min(this.#max, this.#value))\r\n\t}\r\n\r\n\tsetRange(min: number, max: number): void {\r\n\t\tthis.#min = min\r\n\t\tthis.#max = max\r\n\t\tthis.#value = Math.max(this.#min, Math.min(this.#max, this.#value))\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// ProgressBar: Dynamic styling\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tsetBackgroundColor(color: string): void {\r\n\t\tthis.#backgroundColor = color\r\n\t}\r\n\r\n\tsetForegroundColor(color: string): void {\r\n\t\tthis.#foregroundColor = color\r\n\t}\r\n\r\n\tsetBorderWidth(width: number): void {\r\n\t\tthis.#borderWidth = width\r\n\t}\r\n\r\n\tsetBorderColor(color: string): void {\r\n\t\tthis.#borderColor = color\r\n\t}\r\n\r\n\tsetBorderRadius(radius: number): void {\r\n\t\tthis.#borderRadius = radius\r\n\t}\r\n\r\n\tsetTextColor(color: string): void {\r\n\t\tthis.#textColor = color\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Rendering\r\n\t// -------------------------------------------------------------------------\r\n\r\n\trender(context: CanvasRenderingContext2D): void {\r\n\t\tif (!this.#visible) return\r\n\r\n\t\tconst previousAlpha = context.globalAlpha\r\n\t\tcontext.globalAlpha = previousAlpha * this.#opacity\r\n\r\n\t\t// Calculate progress\r\n\t\tconst progress = this.getProgress()\r\n\t\tconst fillWidth = this.#width * progress\r\n\r\n\t\t// Render background with optional border radius\r\n\t\tcontext.fillStyle = this.#backgroundColor\r\n\t\tif (this.#borderRadius > 0) {\r\n\t\t\tcontext.beginPath()\r\n\t\t\tcontext.roundRect(this.#x, this.#y, this.#width, this.#height, this.#borderRadius)\r\n\t\t\tcontext.fill()\r\n\t\t} else {\r\n\t\t\tcontext.fillRect(this.#x, this.#y, this.#width, this.#height)\r\n\t\t}\r\n\r\n\t\t// Render foreground\r\n\t\tif (fillWidth > 0) {\r\n\t\t\tcontext.fillStyle = this.#foregroundColor\r\n\t\t\tif (this.#borderRadius > 0) {\r\n\t\t\t\tcontext.beginPath()\r\n\t\t\t\tconst innerRadius = Math.max(0, this.#borderRadius - this.#borderWidth)\r\n\t\t\t\tcontext.roundRect(this.#x, this.#y, fillWidth, this.#height, innerRadius)\r\n\t\t\t\tcontext.fill()\r\n\t\t\t} else {\r\n\t\t\t\tcontext.fillRect(this.#x, this.#y, fillWidth, this.#height)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Render border if width > 0\r\n\t\tif (this.#borderWidth > 0) {\r\n\t\t\tcontext.strokeStyle = this.#borderColor\r\n\t\t\tcontext.lineWidth = this.#borderWidth\r\n\t\t\tif (this.#borderRadius > 0) {\r\n\t\t\t\tcontext.beginPath()\r\n\t\t\t\tcontext.roundRect(this.#x, this.#y, this.#width, this.#height, this.#borderRadius)\r\n\t\t\t\tcontext.stroke()\r\n\t\t\t} else {\r\n\t\t\t\tcontext.strokeRect(this.#x, this.#y, this.#width, this.#height)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Render text if enabled\r\n\t\tif (this.#showText) {\r\n\t\t\tcontext.fillStyle = this.#textColor\r\n\t\t\tcontext.font = '12px sans-serif'\r\n\t\t\tcontext.textAlign = 'center'\r\n\t\t\tcontext.textBaseline = 'middle'\r\n\t\t\tcontext.fillText(\r\n\t\t\t\t`${Math.round(progress * 100)}%`,\r\n\t\t\t\tthis.#x + this.#width / 2,\r\n\t\t\t\tthis.#y + this.#height / 2,\r\n\t\t\t)\r\n\t\t}\r\n\r\n\t\tcontext.globalAlpha = previousAlpha\r\n\t}\r\n\r\n\t// -------------------------------------------------------------------------\r\n\t// UIElement: Lifecycle\r\n\t// -------------------------------------------------------------------------\r\n\r\n\tdestroy(): void {\r\n\t\t// No resources to clean up\r\n\t}\r\n}\r\n","/**\r\n * Player state SchemaInterface.\r\n */\r\n\r\nimport type { SchemaInterface, PlayerState } from '../types.js'\r\nimport { DEFAULT_PLAYER_STATE } from '../constants.js'\r\nimport { createSchema } from '../factories'\r\n\r\n/**\r\n * Player state SchemaInterface for validation and migration.\r\n *\r\n * @example\r\n * ```ts\r\n * const result = playerStateSchema.validate(data)\r\n * if (result.ok) {\r\n * console.log('Valid player state:', result.value)\r\n * }\r\n * ```\r\n */\r\nexport const playerStateSchema: SchemaInterface<PlayerState> = createSchema<PlayerState>({\r\n\tversion: 1,\r\n\tfields: [\r\n\t\t{ name: 'health', type: 'number', required: true },\r\n\t\t{ name: 'maxHealth', type: 'number', required: true },\r\n\t\t{ name: 'level', type: 'number', required: true },\r\n\t\t{ name: 'experience', type: 'number', required: true },\r\n\t\t{ name: 'position', type: 'object', required: true },\r\n\t\t{ name: 'name', type: 'string', required: true },\r\n\t],\r\n\tdefaultValue: DEFAULT_PLAYER_STATE,\r\n})\r\n","/**\r\n * World state SchemaInterface.\r\n */\r\n\r\nimport type { SchemaInterface, WorldState } from '../types.js'\r\nimport { DEFAULT_WORLD_STATE } from '../constants.js'\r\nimport { createSchema } from '../factories'\r\n\r\n/**\r\n * World state SchemaInterface for validation and migration.\r\n *\r\n * @example\r\n * ```ts\r\n * const result = worldStateSchema.validate(data)\r\n * if (result.ok) {\r\n * console.log('Valid world state:', result.value)\r\n * }\r\n * ```\r\n */\r\nexport const worldStateSchema: SchemaInterface<WorldState> = createSchema<WorldState>({\r\n\tversion: 1,\r\n\tfields: [\r\n\t\t{ name: 'currentScene', type: 'string', required: true },\r\n\t\t{ name: 'unlockedAreas', type: 'array', required: true },\r\n\t\t{ name: 'discoveredLocations', type: 'array', required: true },\r\n\t\t{ name: 'timeElapsed', type: 'number', required: true },\r\n\t\t{ name: 'dayNightCycle', type: 'number', required: true },\r\n\t\t{ name: 'weather', type: 'string', required: true },\r\n\t],\r\n\tdefaultValue: DEFAULT_WORLD_STATE,\r\n})\r\n","/**\r\n * Inventory state SchemaInterface.\r\n */\r\n\r\nimport type { SchemaInterface, InventoryState } from '../types.js'\r\nimport { DEFAULT_INVENTORY_STATE } from '../constants.js'\r\nimport { createSchema } from '../factories'\r\n\r\n/**\r\n * Inventory state SchemaInterface for validation and migration.\r\n *\r\n * @example\r\n * ```ts\r\n * const result = inventoryStateSchema.validate(data)\r\n * if (result.ok) {\r\n * console.log('Valid inventory state:', result.value)\r\n * }\r\n * ```\r\n */\r\nexport const inventoryStateSchema: SchemaInterface<InventoryState> = createSchema<InventoryState>({\r\n\tversion: 1,\r\n\tfields: [\r\n\t\t{ name: 'items', type: 'array', required: true },\r\n\t\t{ name: 'maxSlots', type: 'number', required: true },\r\n\t\t{ name: 'gold', type: 'number', required: true },\r\n\t\t{ name: 'equippedWeapon', type: 'string', nullable: true },\r\n\t\t{ name: 'equippedArmor', type: 'string', nullable: true },\r\n\t],\r\n\tdefaultValue: DEFAULT_INVENTORY_STATE,\r\n})\r\n","/**\r\n * Settings state SchemaInterface.\r\n */\r\n\r\nimport type { SchemaInterface, SettingsState } from '../types.js'\r\nimport { DEFAULT_SETTINGS_STATE } from '../constants.js'\r\nimport { createSchema } from '../factories'\r\n\r\n/**\r\n * Settings state SchemaInterface for validation and migration.\r\n *\r\n * @example\r\n * ```ts\r\n * const result = settingsStateSchema.validate(data)\r\n * if (result.ok) {\r\n * console.log('Valid settings state:', result.value)\r\n * }\r\n * ```\r\n */\r\nexport const settingsStateSchema: SchemaInterface<SettingsState> = createSchema<SettingsState>({\r\n\tversion: 1,\r\n\tfields: [\r\n\t\t{ name: 'masterVolume', type: 'number', required: true },\r\n\t\t{ name: 'musicVolume', type: 'number', required: true },\r\n\t\t{ name: 'sfxVolume', type: 'number', required: true },\r\n\t\t{ name: 'isMuted', type: 'boolean', required: true },\r\n\t\t{ name: 'showTutorials', type: 'boolean', required: true },\r\n\t\t{ name: 'autoSaveEnabled', type: 'boolean', required: true },\r\n\t\t{ name: 'language', type: 'string', required: true },\r\n\t\t{ name: 'screenShake', type: 'boolean', required: true },\r\n\t\t{ name: 'hapticFeedback', type: 'boolean', required: true },\r\n\t\t{ name: 'reducedMotion', type: 'boolean', required: true },\r\n\t\t{ name: 'highContrast', type: 'boolean', required: true },\r\n\t],\r\n\tdefaultValue: DEFAULT_SETTINGS_STATE,\r\n})\r\n"],"names":["DEFAULT_DATABASE_NAME","DEFAULT_DATABASE_VERSION","STORE_NAMES","SNAPSHOT_STORE_NAME","SLOTS_STORE_NAME","AUTOSAVE_SLOT_ID","DEFAULT_AUTO_SAVE_INTERVAL","DEFAULT_STORE_HISTORY_SIZE","DEFAULT_TAB_HEARTBEAT_MS","DEFAULT_LEADER_TIMEOUT_MS","CACHE_STRATEGIES","DEFAULT_TARGET_FPS","DEFAULT_PIXEL_RATIO","DEFAULT_BACKGROUND_COLOR","DEFAULT_TAP_THRESHOLD","DEFAULT_DOUBLE_TAP_DELAY","DEFAULT_PRESS_DELAY","DEFAULT_SWIPE_THRESHOLD","DEFAULT_SWIPE_VELOCITY","GESTURE_TYPES","DEFAULT_REPEAT_DELAY","DEFAULT_REPEAT_RATE","DEFAULT_GAMEPAD_DEADZONE","DEFAULT_GAMEPAD_AXIS_THRESHOLD","STANDARD_BUTTON_MAPPING","STANDARD_AXIS_MAPPING","ALL_GAMEPAD_BUTTONS","ALL_GAMEPAD_AXES","DEFAULT_TRAIL_MAX_POINTS","DEFAULT_TRAIL_START_WIDTH","DEFAULT_TRAIL_END_WIDTH","DEFAULT_TRAIL_FADE_TIME","DEFAULT_TRAIL_MIN_DISTANCE","DEFAULT_MASTER_VOLUME","DEFAULT_MAX_CONCURRENT_SOUNDS","DEFAULT_PLAYLIST_VOLUME","DEFAULT_CROSSFADE_DURATION","DEFAULT_VARIANT_COOLDOWN","DEFAULT_AUDIO_ZONE_FADE_DISTANCE","DEFAULT_TRANSITION_DURATION","EASING_TYPES","DEFAULT_GRAVITY_X","DEFAULT_GRAVITY_Y","DEFAULT_PHYSICS_TIMESTEP","DEFAULT_MAX_PHYSICS_ITERATIONS","DEFAULT_ZOOM","DEFAULT_MIN_ZOOM","DEFAULT_MAX_ZOOM","DEFAULT_CAMERA_SMOOTHING","DEFAULT_FONT_SIZE","DEFAULT_FONT_FAMILY","DEFAULT_TEXT_COLOR","DEFAULT_BORDER_RADIUS","HAPTIC_PATTERNS","HAPTIC_INTENSITIES","ORIENTATION_LOCK_TYPES","DEFAULT_RECONNECT_DELAY","DEFAULT_MAX_RECONNECT_ATTEMPTS","DEFAULT_HEARTBEAT_INTERVAL","DEFAULT_SAMPLE_RATE","HEALTH_STATUSES","ASSET_TYPES","DEFAULT_PLAYER_STATE","DEFAULT_WORLD_STATE","DEFAULT_INVENTORY_STATE","DEFAULT_SETTINGS_STATE","INVENTORY_ITEM_TYPES","DEFAULT_LINE_STYLE","DEFAULT_FILL_STYLE","DEFAULT_INVENTORY_CAPACITY","DEFAULT_STARTING_GOLD","DEFAULT_EQUIPMENT_SLOTS","RARITY_ORDER","DEFAULT_TYPEWRITER_SPEED","DEFAULT_AUTO_ADVANCE_DELAY","DEFAULT_MAX_ACTIVE_QUESTS","DEFAULT_RADIAL_INNER_RADIUS","DEFAULT_RADIAL_OUTER_RADIUS","DEFAULT_RADIAL_CENTER_DEADZONE","DEFAULT_MINIMAP_ZOOM","DEFAULT_MINIMAP_MIN_ZOOM","DEFAULT_MINIMAP_MAX_ZOOM","DEFAULT_NOTIFICATION_MAX_VISIBLE","DEFAULT_NOTIFICATION_MAX_HISTORY","DEFAULT_NOTIFICATION_DURATION","DEFAULT_CONSOLE_MAX_HISTORY","DEFAULT_CONSOLE_MAX_LOG_ENTRIES","DEFAULT_CONSOLE_HEIGHT","Engine","#canvas","#context","#width","#height","#targetFPS","#pixelRatio","#backgroundColor","#isRunning","#isPaused","#currentFPS","#frameCount","#elapsedTime","#deltaTime","#lastFrameTime","#fpsAccumulator","#fpsFrameCount","#animationFrameId","#listeners","options","ctx","#setupCanvas","#handleContextMenu","#handleTouchMove","#loop","cb","width","height","callback","currentTime","e","Scene","#isActive","#isLoaded","#persistent","#entities","#sortedEntities","#needsSort","entity","id","index","#sortIfNeeded","listener","deltaTime","context","a","b","SceneManager","#scenes","#activeScene","#defaultScene","#preloadAll","scene","name","newScene","loadPromises","isString","value","isNonEmptyString","isNumber","isFiniteNumber","isBoolean","isNullish","isDefined","isObject","hasDeviceMemory","nav","hasGetBattery","hasNetworkConnection","hasVibrate","isFunction","isArray","isNonEmptyArray","hasIndexedDB","isIDBValidKey","hasId","obj","hasVersion","hasTimestamp","isOk","result","isErr","generateId","now","clamp","min","max","lerp","start","end","t","deepClone","shallowEqual","keysA","keysB","key","debounce","fn","delay","timeoutId","args","throttle","limit","lastCall","createSpacing","createError","path","message","code","validateField","field","actualType","distance","x1","y1","x2","y2","dx","dy","distanceSquared","distanceVec","distanceVecSquared","normalize","x","y","len","normalizeVec","v","magnitude","magnitudeVec","angleBetween","angleOf","fromAngle","angle","length","addVec","subVec","scaleVec","scalar","dotVec","crossVec","rotateVec","cos","sin","perpVec","reflectVec","normal","d","clampToRectangle","minX","minY","maxX","maxY","clampToWorld","entitySize","worldWidth","worldHeight","halfSize","wrap","range","wrapToWorld","lerpVec","smoothstep","clamped","smootherstep","inverseLerp","remap","inMin","inMax","outMin","outMax","approach","current","target","step","damp","smoothing","dampVec","randomRange","randomInt","randomElement","array","randomPosition","randomEdgePosition","margin","offset","randomInCircle","centerX","centerY","radius","r","randomOnCircle","randomDirection","randomSign","randomBool","probability","circlesOverlap","r1","r2","combinedRadius","pointInCircle","px","py","cx","cy","pointInRectangle","rx","ry","rw","rh","rectsOverlap","w1","h1","w2","h2","circleRectangleOverlap","nearestX","nearestY","degToRad","degrees","radToDeg","radians","normalizeAngle","angleDifference","from","to","lerpAngle","diff","rotateToward","maxStep","Entity","#x","#y","#rotation","#scaleX","#scaleY","#opacity","#zIndex","#visible","#interactive","#created","#triggerCreate","scaledWidth","scaledHeight","rotation","scaleX","scaleY","scale","opacity","zIndex","visible","interactive","deltaX","deltaY","deltaRotation","deltaScale","other","TimerManager","#timers","#fireListeners","#pauseWithEngine","#nextId","#globalPaused","delayMs","timerId","entry","intervalMs","ms","resolve","timer","deltaMs","toRemove","easeInOutQuad","TransitionManager","#sceneManager","#startListeners","#halfwayListeners","#completeListeners","#defaultType","#defaultDuration","#defaultEasing","#currentType","#progress","#phase","#duration","#elapsed","#color","#halfwayFired","#resolveTransition","sceneManager","#startTransition","opts","duration","color","halfDuration","#notifyHalfway","#notifyComplete","easedProgress","maxRadius","#notifyStart","type","Camera","#zoom","#minZoom","#maxZoom","#smoothing","#bounds","#followTarget","#flashColor","#flashDuration","#flashStartTime","#fadeColor","#fadeDuration","#fadeIn","#fadeStartTime","zoom","bounds","#applyBounds","deltaZoom","targetX","targetY","smoothFactor","intensity","startTime","originalX","originalY","shakeFrame","elapsed","decay","offsetX","offsetY","fadeIn","screenX","screenY","worldX","worldY","viewLeft","viewRight","viewTop","viewBottom","alpha","InputSystem","#pointerX","#pointerY","#isPointerDown","#touches","#enabled","#tapThreshold","#doubleTapDelay","#pressDelay","#swipeThreshold","#swipeVelocity","#preventDefaults","#lastTapTime","#lastTapX","#lastTapY","#pointerStartX","#pointerStartY","#pointerStartTime","#pressTimer","#initialPinchDistance","#initialPinchAngle","#lastPinchScale","#lastPinchRotation","#boundPointerDown","#boundPointerUp","#boundPointerMove","#boundTouchStart","#boundTouchEnd","#boundTouchMove","canvas","#handlePointerDown","#handlePointerUp","#handlePointerMove","#handleTouchStart","#handleTouchEnd","set","#getCanvasCoords","clientX","clientY","rect","coords","#emitPress","data","dist","#handleTapGesture","velocity","#emitSwipe","#emitPan","touch","point","touch1","touch2","#getTwoTouchPoints","#getDistance","#getAngle","existing","updated","currentDistance","currentAngle","#emitPinch","#emitRotate","touches","p1","p2","gesture","#emitGesture","#getDirection","KeyboardManager","#keysDown","#keysPressed","#keysReleased","#keysPressedThisFrame","#keysReleasedThisFrame","#modifiers","#preventDefaultKeys","#allowBrowserShortcuts","#repeatDelay","#repeatRate","#trackedCombos","#boundKeyDown","#boundKeyUp","#boundBlur","#handleKeyDown","#handleKeyUp","#handleBlur","event","#isBrowserShortcut","#checkCombos","tracked","combo","keysPressed","lastKeyTime","nextIndex","negative","positive","left","right","up","down","prevent","GamepadManager","#gamepads","#previousButtons","#previousAxes","#deadzone","#axisThreshold","#customMappings","#boundGamepadConnected","#boundGamepadDisconnected","mapping","#handleGamepadConnected","#handleGamepadDisconnected","#pollConnectedGamepads","gamepad","#initializeGamepad","gamepads","buttons","#createButtonState","axes","#createAxisState","state","#getMappingForGamepad","i","buttonName","ButtonInterface","axisName","axisValue","#applyDeadzone","axis","stick","xAxis","yAxis","weakMagnitude","strongMagnitude","deadzone","threshold","previousState","buttonsPressed","buttonsReleased","wasDown","isDown","prevAxes","prevValue","newValue","newState","InputActionSystem","#actions","#contexts","#enabledContexts","#actionStates","#previousActionStates","#defaultBindings","#persistBindings","#storageKey","#loadBindings","action","actionName","bindingIndex","newBinding","oldBinding","newBindings","updatedAction","#saveBindings","defaultBindings","bindings","actionBindings","keyboard","input","sortedContexts","processedActions","#evaluateAction","isActive","prevState","wasActive","maxValue","binding","#evaluateBinding","AudioManager","#audioElements","#audioStates","#masterVolume","#muted","#maxConcurrentSounds","audio","volume","clone","rate","loop","targetVolume","steps","increment","currentVolume","interval","startVolume","decrement","fromKey","toKey","MusicPlaylist","#tracks","#currentIndex","#isPlaying","#mode","#crossfadeDuration","#volume","track","tracks","mode","#emitTrackChange","j","temp","trackJ","_duration","progress","previousTrack","currentTrack","SoundVariantPool","#variants","#lastPlayedKey","#cooldown","#cooldownRemaining","#preventRepeat","#totalWeight","#pitchVariation","#volumeVariation","variant","audioManager","playbackRate","finalVolume","cooldown","availableWeight","lastVariant","random","AudioZoneManager","#zones","#currentZone","#previousZone","#isTransitioning","#transitionProgress","#transitionDuration","#audioManager","zone","#exitZone","enabled","#isInsideBounds","zoneId","listenerX","listenerY","foundZone","toZone","PhysicsWorld","#gravityX","#gravityY","#damping","#iterations","#bodies","body","dt","newX","newY","CollisionSystem","#entityColliders","#layerCollisions","collider","entityA","entityB","colliderA","colliderB","boundsA","boundsB","overlapX","overlapY","normalX","normalY","depth","contactX","contactY","results","entityBounds","startX","startY","endX","endY","dirX","dirY","tMinX","tMaxX","tMinY","tMaxY","tEnterX","tExitX","tEnterY","tExitY","tEnter","tExit","layerA","layerB","canCollide","entities","count","Tween","#target","#properties","#applyProgress","#easeInOutQuad","prop","endValue","startKey","startValue","TweenManager","#tweens","#autoUpdate","tween","ParticleEmitter","#maxParticles","#emissionRate","#lifespan","#isEmitting","#particles","emitting","#toParticleState","p","particle","#emitAccumulator","ParticleSystem","#emitters","#maxEmitters","emitter","Button","#text","#isHovered","#isPressed","#isDisabled","#fontSize","#fontFamily","#textColor","#disabledTextColor","#hoverColor","#pressedColor","#disabledColor","#borderWidth","#borderColor","#borderRadius","text","disabled","size","family","inputState","wasHovered","wasPressed","previousAlpha","bgColor","textColor","#roundRect","w","h","Text","#align","#baseline","#maxWidth","#lineHeight","align","baseline","maxWidth","lineHeight","Panel","#padding","#layout","#children","#normalizePadding","padding","element","child","layout","gap","adjustedState","#isInteractive","Slider","#min","#max","#value","#step","#isDragging","#trackColor","#fillColor","#thumbColor","#thumbSize","stepped","wasDragging","inBounds","ratio","trackHeight","thumbRadius","trackY","fillWidth","thumbX","thumbY","Checkbox","#checked","#boxSize","#label","#wasPressed","#labelColor","#boxColor","#checkColor","checked","label","Toggle","#trackColorOff","#trackColorOn","trackWidth","UIImage","#imageKey","#sourceX","#sourceY","#sourceWidth","#sourceHeight","#tint","tint","UIManager","#elements","#focusedElementId","#scale","#debugDraw","#wasPointerDown","button","progressBar","ProgressBar","panel","slider","checkbox","toggle","image","scaledInputState","sortedElements","#getSortedElements","focusedId","Store","#id","#initialState","#revision","#cleanRevision","#subscribers","#equals","#enableHistory","#history","#historyIndex","#maxHistorySize","#destroyed","subscriber","getCurrentSubscriber","previous","updater","Computed","#compute","#dirty","#dependencies","#notifying","compute","store","unsubscribe","#markDirty","previousValue","#recompute","pushSubscriber","popSubscriber","StateManager","#stores","#schemas","#database","#sync","#config","#currentSlotId","#initialized","#autoSaveTimer","#playtimeStart","#totalPlaytime","#saveListeners","#loadListeners","#leaderListeners","#remoteChangeListeners","#errorListeners","#visibilityHandler","#beforeUnloadHandler","config","manager","#initialize","createDatabase","createTabSyncManager","isLeader","storeId","storeConfig","storeConf","createStore","#handleAutoSave","#syncSave","change","slotId","preview","#notifyError","stores","snapshot","existingSlot","playtime","fullPreview","slot","cause","schema","parsed","newId","error","Database","#db","#channel","#tabId","db","channelName","storeName","#requireDb","reject","request","indexName","query","values","keys","completed","#broadcastChange","storeNames","executor","tx","transaction","operation","Schema","#fields","#defaultValue","#migrateFunc","errors","record","fromVersion","HEARTBEAT_KEY","TabSyncManager","#isLeader","#heartbeatMs","#leaderTimeoutMs","#heartbeatInterval","#monitorInterval","#messageListeners","#tabCountListeners","#knownTabs","heartbeatMs","leaderTimeoutMs","#handleMessage","#startMonitoring","#tryClaimLeadership","heartbeat","#getHeartbeat","#claimLeadership","#stopHeartbeat","payload","listeners","#stopMonitoring","previousCount","#writeHeartbeat","#startHeartbeat","AssetManager","#images","#audio","#json","#assetStates","#loadedCount","#totalCount","#basePath","#crossOrigin","#retryAttempts","#retryDelay","url","img","response","assets","promises","asset","MobileManager","#enableMotionSensors","#enableBatteryMonitoring","#enableNetworkMonitoring","#wakeLock","#boundOrientationChange","#boundDeviceMotion","#boundDeviceOrientation","#handleOrientationChange","#handleDeviceMotion","#handleDeviceOrientation","orientation","motion","capabilities","style","pattern","battery","connection","effectiveType","AccessibilityManager","#screenReaderEnabled","#reducedMotionEnabled","#highContrastEnabled","#liveRegion","#reducedMotionQuery","#highContrastQuery","#boundReducedMotionHandler","#boundHighContrastHandler","#handleReducedMotionChange","#handleHighContrastChange","#createLiveRegion","priority","description","focused","describer","PWAManager","#serviceWorkerState","#deferredPrompt","#registration","#boundOnline","#boundOffline","#boundBeforeInstallPrompt","#handleOnline","#handleOffline","#handleBeforeInstallPrompt","scriptURL","registrations","registration","urls","cacheName","names","NetworkManager","#state","#socket","#url","#autoReconnect","#reconnectDelay","#maxReconnectAttempts","#timeout","#heartbeatTimer","#reconnectTimer","#reconnectAttempts","#stats","#setupSocketListeners","socket","#scheduleReconnect","typeListeners","originalOnOpen","originalOnError","typedCallback","PerformanceMonitor","#sampleRate","#trackMemory","#historySize","#currentMetrics","#frameStartTime","#updateTimeAccumulator","#renderTimeAccumulator","frameTime","memory","time","samples","DebugTools","#logLevel","#logs","#traces","#maxLogs","#storeChanges","changes","level","filtered","log","traceId","trace","success","metadata","endTime","updatedTrace","traces","completedTraces","totalQueryTime","queryTimes","slowestTraces","q","errorTraces","errorRate","recentErrorLogs","SpriteSheet","#frames","#animations","#columns","#rows","#margin","#spacing","#generateFrames","anim","frame","animation","frameIndex","col","row","startFrame","endFrame","totalFrames","actualEnd","AnimationPlayer","#spriteSheet","#currentAnimation","#currentFrame","#speed","frameCount","frameRate","animationName","speed","frameDuration","newFrame","oldFrame","Renderer","#options","#layers","layer","camera","sortedLayers","l","entitiesToRender","Viewport","#scaleMode","#targetElement","#resizeObserver","#lastOrientation","#boundFullscreenChange","#boundWindowResize","#handleFullscreenChange","#handleWindowResize","entries","newOrientation","containerWidth","containerHeight","Tileset","#tileCount","#tileProperties","#tileCollisions","props","collision","gid","localId","TilemapLayer","#tileWidth","#tileHeight","#data","#offsetX","#offsetY","#parallaxX","#parallaxY","FLIPPED_HORIZONTALLY_FLAG","FLIPPED_VERTICALLY_FLAG","FLIPPED_DIAGONALLY_FLAG","flippedHorizontal","flippedVertical","flippedDiagonal","actualGid","tileX","tileY","tiles","tile","cameraX","cameraY","viewWidth","viewHeight","Tilemap","#tilesets","#layerOrder","tilesetOpts","layerOpts","ts","tileset","layerName","LayerManager","#sortedLayers","#visibilityListeners","#orderListeners","#defaultLayerName","#sortLayers","#notifyOrderChange","defaultLayer","#notifyVisibilityChange","blendMode","fromLayer","toLayer","maxZ","minZ","layerCamera","parallaxOffsetX","parallaxOffsetY","layerNames","TrailRenderer","#points","#maxPoints","#startWidth","#endWidth","#startColor","#endColor","#fadeTime","#minDistance","#textureKey","#blendMode","last","newAge","CameraInterface","prevBlendMode","t1","t2","width1","#lerpValue","width2","color1","#lerpColor","color2","gradient","startColor","endColor","#parseColor","g","rgbaMatch","hex","c","ShapeRenderer","#ctx","#lineStyle","#fillStyle","#defaultLineStyle","#defaultFillStyle","#applyLineStyle","points","closed","first","fill","#applyFillStyle","radiusX","radiusY","startAngle","endAngle","counterClockwise","cp1x","cp1y","cp2x","cp2y","cpx","cpy","headLength","headAngle","half","cellWidth","cellHeight","PostProcessManager","#effects","effect","params","#applyVignette","#applyColorTint","#applyBrightness","#applyContrast","#applySaturation","#applyPixelate","#applyScanlines","#applyCRT","#applyBlur","#applyGlow","brighten","_canvas","_params","contrastValue","saturationValue","pixelSize","imageData","ri","bi","ToastManager","#toasts","#queue","#showListeners","#dismissListeners","#defaultPosition","#maxVisible","#animation","toast","#processQueue","#removeToast","#notifyDismiss","#toToastState","canvasWidth","canvasHeight","yOffset","#notifyShow","visibleIndex","queueIndex","Modal","#title","#content","#buttons","#isOpen","#isAnimating","#animationProgress","#resolvePromise","title","content","buttonIndex","animationSpeed","modalWidth","modalHeight","modalX","modalY","#checkButtonClick","buttonY","buttonWidth","buttonHeight","buttonSpacing","totalButtonWidth","buttonX","borderRadius","#renderButtons","_modalX","_modalWidth","ModalManager","#modals","#stack","#defaultBackdropColor","#defaultAnimation","#stackModals","modal","defaultValue","activeModal","ScreenshotManager","format","quality","mimeType","#getMimeType","sourceCanvas","#resizeCanvas","dataUrl","#estimateSize","regionCanvas","filename","link","blob","source","resized","base64Part","FrameBudget","#targetMs","#warningThreshold","#criticalThreshold","#overBudgetListeners","#criticalListeners","#recoverListeners","#frameStart","#phaseStarts","#phaseTimes","#lastFrameMs","#wasOverBudget","#wasCritical","total","update","physics","render","ui","idle","phase","isOverBudget","isCritical","timing","#notifyCritical","#notifyOverBudget","#notifyRecover","VirtualJoystick","#innerRadius","#outerRadius","#deadZone","#fixed","#autoHide","#hideDelay","#innerColor","#outerColor","#touchId","#centerX","#centerY","#knobX","#knobY","#direction","#magnitude","#angle","#hideTimer","#displayOpacity","#moveListeners","#pressListeners","#releaseListeners","deadZone","fixed","autoHide","#updateKnobPosition","clampedDistance","normalizedMagnitude","remappedMagnitude","ActionButton","#icon","#iconKey","#size","#activeColor","#cooldownColor","#hapticFeedback","#isOnCooldown","#cooldownDuration","#activateListeners","#holdListeners","#cooldownStartListeners","#cooldownEndListeners","actualDuration","wasOnCooldown","icon","iconKey","touchOnButton","CameraEffects","#camera","#shakeOffset","#traumaAmount","#flashOpacity","#zoomModifier","#effectStartListeners","#effectEndListeners","states","amount","effectsToRemove","traumaShake","#easeOut","shakeIntensity","flashProgress","zoomProgress","zoomAmount","TextInput","#placeholder","#maxLength","#inputType","#placeholderColor","#focusBorderColor","#cursorColor","#selectionColor","#isFocused","#cursorPosition","#selectionStart","#selectionEnd","#cursorBlink","#cursorVisible","#hiddenInput","#inputListeners","#changeListeners","#submitListeners","#focusListeners","#blurListeners","#createHiddenInput","position","before","after","forward","placeholder","maxLength","#drawRoundedRect","textX","textY","displayValue","textBeforeCursor","cursorX","TooltipManager","#isVisible","#position","#currentOptions","#defaultDelay","#touchHoldDuration","#hoverTimer","#touchHoldTimer","#hoveredElement","#attachedElements","#hideListeners","attached","foundElement","#showForElement","fontSize","backgroundColor","borderColor","showArrow","lines","#wrapText","textWidth","line","textHeight","tooltipX","tooltipY","arrowSize","arrowX","arrowY","lineY","words","currentLine","word","testLine","DebugOverlay","#showFPS","#showMemory","#showEntityCount","#showDrawCalls","#showInputState","#showColliders","#showTouchPoints","#graphHeight","#graphHistory","#metrics","#panels","#fpsHistory","#lastMetrics","#lastInputState","#toggleListeners","#metricClickListeners","metric","show","metrics","#renderMainPanel","#renderTouchPoints","fps","mb","panelWidth","panelHeight","panelX","panelY","#renderFPSGraph","stepX","normalizedFPS","SpriteBatch","#assets","#maxBatchSize","#sortByTexture","#sortByDepth","#depthCounter","item","sprite","textureKey","currentTexture","currentImage","batchStart","#drawBatch","items","#drawItem","drawX","drawY","LocalStorageBackend","#prefix","#serialize","#deserialize","testKey","prefixedKey","serialized","keysToRemove","IndexedDBBackend","#storeName","#syncChannel","#syncListeners","#notifySync","MigrationRunner","#migrations","#validateAfterMigration","#onProgress","#currentDataVersion","m","toVersion","migrationsRun","currentData","currentVersion","migrationsToRun","totalMigrations","migration","migrationsToRollback","prevMigration","_data","_version","BuffSystem","#configs","#activeBuffs","#lastApplyTime","activeBuffs","stackCounts","buff","lastApply","oldStacks","newStacks","typeChanges","types","oldStackCounts","HealthSystem","#defaultInvincibilityDuration","#allowOverkill","#damageModifier","entityId","maxHealth","currentHealth","info","oldHealth","actualDamage","actualHeal","health","scaleCurrentHealth","oldMax","healthPercent","percent","wasInvincible","FloatingTextSystem","#entries","#defaultStyle","#defaultFontSize","#defaultColor","oldest","mutableEntry","screenPos","CollectibleSystem","#collectibles","#dropTable","#dropChance","#magnetRange","#magnetSpeed","#defaultLifetime","#collectRadius","sum","finalValue","collectible","roll","collectibleId","collectorId","collectorPosition","moveX","moveY","pulse","SpawnerSystem","#entityFactory","#waves","#infiniteMode","#baseInterval","#minInterval","#intervalDecayRate","#currentSpawnInterval","#spawnTimer","#currentWave","#totalSpawned","z","#selectRandomZone","enabledZones","totalWeight","#getRandomPositionInZone","spawnPosition","selectedZone","#selectRandomType","wave","waveNumber","EffectZoneSystem","#entitiesInZone","#defaultCooldown","effectType","cooldownDuration","#circlesCollide","distSq","radiusSum","entityRadius","collisions","BackgroundSystem","#starData","#parallaxConfigs","#solidColors","#gradients","#customRenderers","#clearColor","#worldWidth","#worldHeight","stars","#generateStars","renderer","newZIndex","_cameraX","_cameraY","star","#renderSolidLayer","#renderGradientLayer","#renderStarfieldLayer","#renderCustomLayer","twinkleFactor","brightness","ExperienceSystem","#levelRewards","#xpFormula","#maxLevel","#currentLevel","#currentXP","reward","currentLevelXP","nextLevelXP","xpInCurrentLevel","xpNeededForLevel","#checkLevelUp","previousXP","actualLoss","#checkLevelDown","newLevel","oldLevel","StatisticsSystem","#statistics","#milestones","#reachedMilestones","#sessionStats","#lifetimeStats","#averageCounts","#sessionStartTime","#isInSession","stat","stats","#updateStat","oldValue","currentValue","lifetime","oldAvg","newAvg","#checkMilestones","milestone","raw","ObjectiveSystem","#objectives","#failOnAnyFail","objective","def","#updateProgress","oldCurrent","required","StateMachine","#transitions","#states","#currentState","#previousState","#stateEnterListeners","#stateExitListeners","transition","#findTransition","#performTransition","exitListeners","enterListeners","initial","InventorySystem","#slots","#equipment","#capacity","#gold","#items","equipmentSlots","slotType","#getAllowedTypesForSlot","quantity","equipment","s","itemId","canAdd","toAdd","#updateItemTotal","#emitItemAdd","freeSlotIndex","maxStack","remaining","itemData","newQuantity","#emitItemRemove","fromSlot","toSlot","#emitItemMove","slotA","slotB","stackA","stackB","stack","slotIndex","equipSlot","oldAmount","#emitGoldChange","capacity","oldCapacity","stacks","#rebuildSlots","rarityA","delta","newTotal","newAmount","DialogueSystem","#trees","#currentTree","#currentNode","#isTyping","#displayedText","#fullText","#typingProgress","#typewriterSpeed","#autoAdvanceDelay","#skipTypingOnInput","choice","condition","flag","tree","treeId","startNodeId","nodeId","choiceIndex","#executeAction","node","#startTyping","#substituteVariables","newFlags","expected","targetLength","_","QuestSystem","#quests","#instances","#completedQuests","#failedQuests","#autoTrackActive","#maxActiveQuests","quest","questId","objectiveId","instance","o","requiredObjectives","prereq","#checkPrerequisite","completedInstance","rewards","#checkNewlyAvailableQuests","failedInstance","objectiveIndex","newCurrent","newCompleted","newObjectives","RadialMenu","#itemStack","#selectedIndex","#hoveredIndex","#startAngle","#gap","#selectedColor","#iconSize","#showLabels","#centerDeadzone","hidden","visibleItems","parentItems","segmentAngle","clampedIndex","hoveredItem","gapAngle","midAngle","midRadius","labelX","labelY","Minimap","#markers","#shape","#showPlayer","#playerIcon","#rotateWithPlayer","#showNorth","#fogOfWar","#clickable","#playerX","#playerY","#playerRotation","#fogMap","oldZoom","marker","updates","localX","localY","minimapX","minimapY","cellSize","pos","iconSize","worldPos","playerPos","NotificationManager","#notifications","#visibleNotifications","#isExpanded","#maxHistory","#groupByCategory","n","category","notification","fullNotification","relativeY","notificationHeight","notifs","priorityColors","EntityInspector","#selectedEntity","#watchers","#expandedCategories","#showComponents","#showTransform","#showBounds","#editableProperties","EntityInterface","property","setter","watchers","watcher","#addProperty","positionable","rotatable","scalable","bounded","activatable","_inputState","byCategory","cat","list","readonly","editable","CommandConsole","#commands","#aliases","#log","#commandHistory","#inputValue","#suggestions","#selectedSuggestionIndex","#toggleKey","#maxLogEntries","#registerBuiltinCommands","command","alias","#addLog","parts","commandName","argStrings","commandArgs","argDef","argValue","msg","err","#updateSuggestions","maxLines","visibleLog","inputY","sugY","cmd","CullingSystem","#strategy","#viewBounds","strategy","#isInView","_camera","#frustumCheck","#distanceCheck","maxDistance","LODSystem","#updateInterval","#defaultLevels","#referencePoint","#entityLODs","#lastUpdateTime","entityType","levels","referenceX","referenceY","CrosshairSystem","#screenX","#screenY","#worldX","#worldY","#style","#thickness","#outline","#outlineColor","#pulseOnActive","#hideOnMobile","#customRenderer","changed","active","thickness","#renderCross","#renderDot","#renderCircle","#renderRing","EntityRendererRegistry","#renderers","#currentTime","createEngine","createScene","createSceneManager","createEntity","createCamera","createSpriteSheet","createAnimationPlayer","createRenderer","createViewport","createTilemap","createTrailRenderer","createShapeRenderer","createPostProcessManager","createInputSystem","createKeyboardManager","createGamepadManager","createInputActionSystem","createMobileManager","createAudioManager","createMusicPlaylist","createSoundVariantPool","createAudioZoneManager","createPhysicsWorld","createCollisionSystem","createTweenManager","createParticleSystem","createUIManager","createComputed","storeOptions","indexConfig","indexOptions","createAssetManager","createAccessibilityManager","createPWAManager","createNetworkManager","createPerformanceMonitor","createDebugTools","createSchema","createStateManager","createTimerManager","createLayerManager","createTransitionManager","createToastManager","createModalManager","createModal","createScreenshotManager","createFrameBudget","createVirtualJoystick","createActionButton","createCameraEffects","createSpriteBatch","createTextInput","createTooltipManager","createDebugOverlay","createLocalStorageBackend","createIndexedDBBackend","createMigrationRunner","createBuffSystem","createHealthSystem","createInventorySystem","createDialogueSystem","createQuestSystem","createRadialMenu","createMinimap","createNotificationManager","createEntityInspector","createCommandConsole","createCullingSystem","createLODSystem","createFloatingTextSystem","createCollectibleSystem","createSpawnerSystem","createEffectZoneSystem","createBackgroundSystem","createExperienceSystem","createStatisticsSystem","createObjectiveSystem","createStateMachine","createCrosshairSystem","createEntityRendererRegistry","Quadtree","#level","#nodes","maxObjects","maxLevels","#split","halfWidth","halfHeight","#getIndex","midX","midY","fitsTop","fitsBottom","fitsLeft","fitsRight","entitiesToRedistribute","#boundsOverlap","SpatialGrid","#grid","#entityCells","#getCellKey","cellX","cellY","#getCellsForBounds","minCellX","maxCellX","minCellY","maxCellY","cells","entityCellSet","cellKey","cellKeys","cell","candidates","radiusSq","ex","ey","subscriberStack","isTracking","Cache","#maxSize","#maxAge","#maxEntries","totalSize","#isExpired","expiresAt","#evictIfNeeded","timestamp","#isExpiredAt","#evict","incomingSize","#evictLRU","firstKey","MetricsCollector","#operations","#errors","#maxErrors","#getOrCreateStore","errorRecord","StorageManager","estimate","usage","quota","ObjectPool","#available","#active","#factory","#reset","#validate","ResourceManager","#pools","pool","totalBytes","ColliderComponent","#collider","#isTrigger","shape","trigger","TransformComponent","SpriteComponent","#frame","imageKey","spriteSheet","PhysicsComponent","#velocityX","#velocityY","#accelerationX","#accelerationY","#mass","#drag","#useGravity","#gravityScale","mass","ComponentFactory","#customComponentRegistry","component","constructor","Constructor","#foregroundColor","#showText","innerRadius","playerStateSchema","worldStateSchema","inventoryStateSchema","settingsStateSchema"],"mappings":"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"}
|