'use strict'; // Browser polyfill: makes Node.js CommonJS (module.exports / require) work in browser // Load this BEFORE all other scripts in index.html (function () { // Global `module` object - its exports setter mirrors to window var moduleObj = { exports: {} }; Object.defineProperty(moduleObj, 'exports', { set: function (val) { this._exports = val || {}; // Mirror all exported properties to window for cross-script access if (val && typeof val === 'object') { for (var key in val) { if (Object.prototype.hasOwnProperty.call(val, key)) { window[key] = val[key]; } } } }, get: function () { return this._exports || {}; }, }); moduleObj._exports = {}; window.module = moduleObj; // Module path -> exported keys mapping for require() lookups var moduleKeys = { 'src/core/constants': ['TILE', 'COLS', 'ROWS', 'TILE_TYPES', 'COLORS', 'T_FLOOR', 'T_WALL', 'T_SOFTWALL', 'T_LAVA', 'T_WATER', 'T_TORCH', 'T_DOOR', 'T_LEVER', 'T_SWITCH', 'T_TRAP', 'T_TARGET', 'T_CHEST', 'T_EXIT', 'T_ROCK', 'T_ITEM', 'MOVE_COOLDOWN', 'ATTACK_COOLDOWN', 'ATTACK_ANIM', 'ENEMY_MOVE_INTERVAL', 'ENEMY_ATTACK_INTERVAL', 'HIT_FLASH', 'MESSAGE_DURATION', 'TRANSITION_DURATION', 'DIRS', 'DIR_NAMES', 'OPPOSITE_DIR', 'SCREEN_TITLE', 'SCREEN_DUNGEON_SELECT', 'SCREEN_PLAYING', 'SCREEN_DEAD', 'SCREEN_DUNGEON_COMPLETE', 'SCREEN_GAME_COMPLETE', 'SCREEN_INVENTORY', 'CANVAS_W', 'CANVAS_H', 'MAX_HEARTS', 'MAX_INVENTORY_SLOTS', 'MAX_PARTICLES'], 'src/core/rng': ['createRNG', 'mulberry32', 'randInt', 'randFloat', 'randElement', 'shuffle', 'weightedChoice'], 'src/core/utils': ['createBorderLayout', 'createEmptyLayout', 'drawHeart', 'drawHeartContainer', 'manhattanDist', 'inBounds', 'cloneLayout', 'clamp', 'lerp', 'isPassable', 'isWall', 'isSoftWall', 'getFloorColor', 'getWallColors', 'formatNumber'], 'src/generator/dungeon': ['generateDungeon'], 'src/generator/rooms': ['generateRoomLayout', 'getRoomLayoutTemplate', 'applyThemeToRoom'], 'src/generator/puzzles': ['generatePuzzles'], 'src/generator/placement': ['generatePlacement', 'placeEnemies', 'placeItems', 'placeBoss', 'findFloorPosition', 'getEnemyPool', 'getRupeeType'], 'src/generator/index': ['generateDungeon', 'generateRoomLayout', 'generatePuzzles', 'generatePlacement'], 'src/data/themes': ['THEMES'], 'src/data/dungeons': ['DUNGEONS'], 'src/data/enemies': ['ENEMY_TYPES', 'getEnemyType'], 'src/data/weapons': ['WEAPONS', 'getWeapon'], 'src/data/bosses': ['BOSS_TYPES', 'getBossType'], 'src/data/items': ['ITEMS', 'getItem'], 'src/game/state': ['initGameState', 'loadDungeonRoom', 'showMessage', 'resetPlayer'], 'src/game/movement': ['tryMove', 'tryInteract', 'tryExit', 'completeDungeon'], 'src/game/combat': ['tryAttack', 'dealDamage', 'spawnProjectile', 'updateProjectiles'], 'src/game/ai': ['updateEnemies', 'updateEnemyMovement', 'moveToward', 'enemyAttack', 'bossAttack', 'createEnemyInstance'], 'src/game/items': ['openChest', 'collectFloorItem', 'useItem', 'switchWeapon'], 'src/game/transitions': ['startTransition', 'getTransitionAlpha', 'isTransitionComplete'], 'src/input/keyboard': ['initKeyboard', 'isKeyDown', 'isKeyJustPressed', 'setKeyHandlers', 'resetKeys'], 'src/input/actions': ['initActions', 'getActionState', 'getAction', 'getActiveActions'], 'src/rendering/renderer': ['renderFloor', 'renderWalls', 'renderTorches', 'renderDoors', 'renderSoftwalls', 'renderLava', 'renderWater', 'renderTraps', 'renderLevers', 'renderSwitches', 'renderTargets', 'renderRocks', 'renderChests', 'renderItems', 'renderExit', 'renderPlayer', 'renderAttackAnim', 'renderMessages'], 'src/rendering/draw-enemies': ['renderEnemies', 'drawEnemy', 'drawSlime', 'drawKeese', 'drawOctorok', 'drawMoblin', 'drawStalfos', 'drawGoriya', 'drawArmos', 'drawLynel'], 'src/rendering/draw-bosses': ['renderBoss', 'drawGenericBoss', 'drawGleeok', 'drawDarknut', 'drawWizzrobe'], 'src/rendering/draw-weapons': ['drawWeaponHeld', 'drawWeaponInHUD', 'drawSwordHeld', 'drawMasterSwordHeld', 'drawBowHeld', 'drawBoomerangHeld', 'drawBombHeld', 'drawHammerHeld', 'drawFireRodHeld', 'drawIceRodHeld', 'drawSlingshotHeld', 'drawHookshotHeld', 'drawWeaponIcon'], 'src/rendering/hud': ['renderHUD'], 'src/rendering/effects': ['spawnParticles', 'spawnHitParticles', 'spawnDefeatParticles', 'spawnExplosionParticles', 'renderParticles', 'renderProjectiles'], 'src/menu/title-screen': ['renderTitleScreen', 'createMenuButton'], 'src/menu/dungeon-select': ['renderDungeonSelect'], 'src/menu/hud-overlay': ['renderInventoryOverlay'], 'src/menu/screens': ['renderDeathScreen', 'renderDungeonCompleteScreen', 'renderGameCompleteScreen'], 'src/save/save': ['saveData', 'loadSaveData', 'saveProgress', 'markDungeonComplete', 'addWeapon', 'addHeartPiece', 'addStats', 'isDungeonCompleted', 'isDungeonUnlocked', 'getSaveSummary', 'clearSave'], }; // Resolve a require path to a canonical module key function resolvePath(req, callerPath) { // Strip leading / for consistency with moduleKeys if (callerPath && callerPath.startsWith('/')) callerPath = callerPath.substring(1); // Direct match if (moduleKeys.hasOwnProperty(req)) return req; if (req.startsWith('./') || req.startsWith('../')) { var dir = callerPath.substring(0, callerPath.lastIndexOf('/') + 1); var resolved; if (req.startsWith('./')) { resolved = dir + req.substring(2); } else { var segments = req.substring(2).split('/'); var baseSegments = dir.split('/').filter(Boolean); var dotDotCount = 0; for (var i = 0; i + 2 < req.length && req.substring(i, i + 3) === '../'; i += 3) dotDotCount++; for (var u = 0; u < dotDotCount; u++) baseSegments.pop(); var rest = req.substring(dotDotCount * 3); resolved = baseSegments.join('/') + '/' + rest; } // Normalize while (resolved.includes('/../')) { resolved = resolved.replace(/[^\/]+\/\.\.\//, ''); } if (moduleKeys.hasOwnProperty(resolved)) return resolved; } return null; } // Global `require` function window.require = function (reqPath) { var script = document.currentScript; var origin = window.location ? window.location.origin : ''; var callerPath = script ? (script.src || script.getAttribute('src') || '').replace(origin, '') : ''; var modKey = resolvePath(reqPath, callerPath); if (!modKey) { console.warn('[require] Module not found: "' + reqPath + '" from "' + callerPath + '"'); return {}; } var result = {}; var keys = moduleKeys[modKey]; for (var i = 0; i < keys.length; i++) { var key = keys[i]; result[key] = window[key] !== undefined ? window[key] : undefined; } return result; }; })();