diff --git a/.agents/skills/cheap-model-game-generation.md b/.agents/skills/cheap-model-game-generation.md index 6eadcafd..a62f4be2 100644 --- a/.agents/skills/cheap-model-game-generation.md +++ b/.agents/skills/cheap-model-game-generation.md @@ -78,3 +78,4 @@ flash 打底放量 14 款(主力 8 + 压测 6),Opus 对抗审计核实(2 个 ult - **★ spec 预判的门面缺口几乎全推翻**:CCD / 文本HUD / 网格 / match-finding / 手势均**非缺口**(便宜模型自带或自写;故"碰撞穿透门 J"已非急需)。**真·L0 门面缺口收敛为唯一一处=宿主键盘桥**(已 spawn_task 交 L0)。完整数据见 [`2026-06-14-WG1-scale20-短板量化报告.md`](../../docs/agent-specs/2026-06-14-WG1-scale20-短板量化报告.md)。 - **M3 视觉 player 当生产过滤器**(`calibration/m3_test.json`):与门 8/9 一致、抓显性空心(flappy fun1)、漏截图不可见失败(键盘死/弱证据,恰被确定性门兜住)→ **三层互补**(门=地板 / M3=主观过滤 + 便宜 fun 信号 / 创始人=人锚)。MAE 压低待创始人对新款补锚(框架沿用 `calibrate.py`)。 - **★ 规避/推理族:题面须自产「安全位」+ 断言用胜利终态(saolei borderline 修复,2026-06-15)**:tap-targets 盲点首个对扫雷会盲踩雷秒负、核心玩法零暴露(门弱断言被 lose 路径满足→ false-borderline)。修法 = 题面令 `_forensicsView` 自产 `safe`(测试专用 x-ray,=`!cell.mine`,**勿渲染/勿给玩家避雷提示**)→ harness driver `safeOnly:true` 只揭安全格到 win → 断言改 `result=="win"`。**flash 一次过且自产 safe 正确**(`generated-factory.js:337`)→ **坐实缺口在题面、非模型能力**。通则:凡「盲点首个会致负」的家族(扫雷类),题面给 oracle 安全位 + driver 避负 + 断言用胜利终态;门只证「机制点亮+可赢可达」,好不好玩归 M3+创始人。详见 [`2026-06-15-WG1-tap-targets-driver-自产缺口-L1brief.md`](../../docs/agent-specs/2026-06-15-WG1-tap-targets-driver-自产缺口-L1brief.md)。 +- **★ driver-coverage 6 款闭口 + 重生成归因(2026-06-15)**:scale-20 余 6 款 driver-coverage 失败全部归因(详 [`driver-coverage 闭口报告`](../../docs/agent-specs/2026-06-15-WG1-driver-coverage闭口与P2对照-L1报告.md) + [harness skill §8 四因铁律](./game-e2e-cdp-harness.md))——**0 个模型造不出 / 0 个 3D 硬界**:flappy/multiball **重生成即过**(原件『缝隙贴顶』/『底部丢球未实现』=**实例缺陷非模型短板**,收紧 brief + 增强 driver〔vy 前瞻 / 弃守排空〕后 flash 翻绿,multiball retries=0);t2048/asteroids 宿主键盘桥(L0 已修)重打包即活;asteroids/angrybirds 盲玩=可测性边界,**经 enrich exportState(asteroids 暴露陨石坐标 / angrybirds pin+导出 launch 物理常数)+ 适配 driver(aim-fire / drag-aiming 解析)转确定性闭口**(asteroids score 0→6、angrybirds 0→20 清场)。**生成侧铁律:单件失败禁直接归『模型造不出』,必重生成区分『实例 bug / 可测性缺口 / 模型短板』**——『模型造不出』是最大伪报源(原 flappy『升 pro 仍挂=模型天花板』被本轮证伪=driver+实例)。 diff --git a/.agents/skills/game-e2e-cdp-harness.md b/.agents/skills/game-e2e-cdp-harness.md index ee9a8515..8bbad585 100644 --- a/.agents/skills/game-e2e-cdp-harness.md +++ b/.agents/skills/game-e2e-cdp-harness.md @@ -76,18 +76,28 @@ ## 8. scale-20 放量实证:driver 库泛化 + 门承重件 + 对抗审计硬化(W-G1 lane v3,2026-06-14) -**适配 driver 库 1→6 型 + drag 输入事件**(`play.cdp.cjs`,`spec.driver.type` 分发;盲打打不动技巧/实时游戏=H 假阴根因,故按机制族建 driver): +**适配 driver 库 1→8 型 + drag 输入事件**(`play.cdp.cjs`,`spec.driver.type` 分发;盲打打不动技巧/实时游戏=H 假阴根因,故按机制族建 driver): | driver | 机制族 | 读什么自动出招 | |---|---|---| -| `paddle-intercept` | 挡板接球 | `ball.x` → 挡板对齐 | +| `paddle-intercept` | 挡板接球 | `ball.x` → 挡板对齐;**`drainAfter` 声明则跑满后【弃守排空】(挡板停 `drainX` 角落)让球漏光→打出 lose 终态(接球类靠一直接球永不失败→latch 不可达的解,multiball)** | | `tap-targets` | 点击离散目标 | `state.targets[{x,y,occupied[,safe]}]` → 点未占用;**规避/推理族(扫雷)配 `safeOnly:true` 只点 `safe===true`、确定性避负把核心循环跑到 win**(井字棋/扫雷/打地鼠/Simon/invaders…) | -| `flap-to-gap` | 重力穿缝 | `bird.y` vs `nextGap.centerY` → 偏低拍翅 | +| `flap-to-gap` | 重力穿缝 | `bird.y` + **`bird.vy` 速度前瞻**(`位置+vy×lookahead` 预测仍偏低才拍、`aimBias` 瞄缝心上方留下落余量)→解高位缝/快下落『追不上·过冲』(flappy);缺 vy 退化为纯位置反应式 | | `seek-x` | 横向趋近接台 | `bird.x` vs `nextPlatform.x` → 点左/右半 | | `tap-pairs` | 相邻交换(三消) | `targets[k]`/`[k+1]` 成对点 | -| `key-cycle` | 纯按键 | 循环按 `keys[]` 到 gameover(**依赖宿主键盘桥,见下** ) | +| `key-cycle` | 纯按键 | 循环按 `keys[]` 到 gameover(**依赖宿主键盘桥**);填充型(2048)用 2 向键(如 `Up+Right`)比 4 向更快逼满盘,但**抗死锁类游戏仍难确定性到 latch=边界** | +| `drag-aiming` | 抛射瞄准(愤怒小鸟) | 暴露 `launch{gravity,powerScale}` → **45° 抛解析反解拖拽矢量(确定性命中+各发±力度微抖兜离散)**;未暴露→退化 `powers[]` 力度扫描+`upLead` 补下坠。**angrybirds pin+导出物理后 score 0→20 win=可测性边界转确定性闭口** | +| `aim-fire` | 射击瞄准(Asteroids) | 读 `ship{x,y,angle}`+`targets[{x,y}]` 选最近,旋转使 `|atan2方位-angle|` 收敛(**旋向自适应**:diff 变大翻向,免猜 CW/CCW)→对齐即开火;**须游戏 exportState 暴露目标坐标**(无坐标=可测性边界) | -固定输入新增 `{t:'drag',from,to,ms}`(touchStart→插值 touchMove→touchEnd,合成 swipe/拖拽)。**driver 覆盖度 = 门能否兜住的前提**:shooter/填充型 latch 需足够步数驱动到终局(invaders/tetris/multiball 的 latch 假阴皆此因,非游戏坏;invaders 步数 30→50 即翻绿,实证)。 +固定输入新增 `{t:'drag',from,to,ms}`(touchStart→插值 touchMove→touchEnd,合成 swipe/拖拽)。**driver 覆盖度 = 门能否兜住的前提**:shooter/填充型 latch 需足够步数驱动到终局(invaders 步数 30→50 即翻绿,实证)。 + +**★ driver-coverage v2 闭口:H 假阴四因归因铁律(2026-06-15,5 款实测)**。技巧/射击/填充类 H 假阴必先分因、**禁『模型造不出』笼统归因**(spec §9): +1. **宿主门面缺失**(系统性,L0 域):如键盘桥 `d754b71`——**失败严格沿『键盘 vs 指针』分界=最强信号**;宿主经 esbuild 打进 bundle,故修后须**重打包** bundle 才生效(`node scripts/build.mjs /entry-bundle.js /bundle.iife.js --global-name=__GameBundle`)→实证 t2048 `score 0→4`、asteroids `F_wiring 0→26`。 +2. **driver 太朴素**(我域,改 `play.cdp.cjs`):本轮增 flap-to-gap vy 前瞻 / paddle-intercept 弃守排空 / drag-aiming / aim-fire 四件;flappy・multiball 经此 + 重生成翻绿。 +3. **可测性边界**(游戏 `exportState` 不足以确定性盲玩):asteroids 无陨石坐标、angrybirds 无发射物理常数。**正解=enrich exportState 暴露所需(坐标/物理常数)+ 适配 driver**:asteroids 暴露 `asteroids:[{x,y}]`+aim-fire 旋向瞄准;angrybirds brief **pin+导出 `launch:{gravity,powerScale}`**+drag-aiming 45° 抛解析瞄准——**两者皆经此从『边界』转『确定性闭口』(asteroids score 0→6、angrybirds 0→20 清场)**。**抗死锁类(2048)的 latch 是设计性边界**(游戏意在不结束),宜放宽为强 progress(score↑∧board变)+G 兜。 +4. **生成实例缺陷 ≠ 模型能力**:multiball 原件底部丢球未实现(latch 不可达)、flappy 原件缝隙贴顶,但 flash 在**收紧 brief**(『球越底沿即出局不反弹』/『缝心落可达区间』)下**重生成即过**(multiball retries=0)。**区分『此实例 bug』与『模型短板』必须重生成验证,不可凭单件下结论**——这是『模型造不出』的最大伪报源。 + +**结论(scale-20 的 driver-coverage 失败款)**:0 个是模型能力天花板,0 个是 3D 硬界——真难点恒在 **harness driver 覆盖 + 宿主门面完备 + 游戏可测性导出**三者。 **★ 地板真承重件 = `expectLatch` + `G_input`,不是 progress 计数**(对抗审计实证):`H_progress.pass = progressPass && latchPass`;单条 `assertAfterPlay`(score/revealed/moves +1)鉴别力弱——saolei 踩雷也 revealed++、runner score 计时自增,可被"漂亮空壳"蹭过;真隔离空壳的是 latch(真到 gameover+600ms 驻留)+ G_input(同帧 A/B 哈希证输入真生效)。**新游戏务必让 progress 断言带终局语义**(全清/三连/真死),否则靠 latch+G 兜。 diff --git a/docs/agent-specs/2026-06-14-WG1-bakeoff天花板与Claude-free评估门-execution.md b/docs/agent-specs/2026-06-14-WG1-bakeoff天花板与Claude-free评估门-execution.md index 79d0cc0b..6c4d454f 100644 --- a/docs/agent-specs/2026-06-14-WG1-bakeoff天花板与Claude-free评估门-execution.md +++ b/docs/agent-specs/2026-06-14-WG1-bakeoff天花板与Claude-free评估门-execution.md @@ -171,3 +171,15 @@ flowchart TB - **[assumption·核心待验]** 便宜 player 判好玩跟人类相关——靠 §6 校准定论;不相关则退亲玩。 - **[assumption]** agent-scope lift 显著为正(harness 复利)——单变量/held-out 测;证伪则记模型天花板。 - **[守护栏·创始人确认]** 只改我方 agent 层、AgentScope 可替换不 fork、Opus 建好即退不进生产、便宜模型生产 in-loop、模型 per-agent 可配置可路由。 + +--- + +## 执行进展回填(L1,2026-06-15) + +> 本轮创始人定档「driver 残留闭口 + P2 对照(L1 自主)」;P1 校准放量 blocked-on-founder。详见 [`driver-coverage 闭口与 P2 对照报告`](2026-06-15-WG1-driver-coverage闭口与P2对照-L1报告.md)。 + +- **P0 跑通 ✅**:studio 多角色闭环(设计→代码→七门→player panel→自修复)Breakout 端到端真跑通(非桩),Stage1/Stage1_mmx/Stage2 三档均有数据。 +- **P1 校准 ⚠️(N=4 命门结论已出,放量 blocked-on-founder)**:`calibration/report.json` 实证 **M3视觉/flash文本 player `gatekeeper_ok=false`**——便宜 player 高估碰撞 bug 件(pro 件两 player 给 fun4,创始人亲玩 fun2/fix),坐实 review §8「player panel 有结构性天花板、人锚不可替代」。放量需创始人对更多款亲玩补 `labels.json` 锚。 +- **P2 对比 ✅(N=1 Breakout)**:同款三档对照表(flash ¥0.194 / M2.7 ¥0.514 / pro ¥0.417;过门率/自修复轮/¥/player 分 + 创始人锚)已成。多题面横比留 P3。 +- **driver-coverage 6 款闭口 ✅**:scale-20 余 6 款失败全部归因,**0 个模型造不出 / 0 个 3D 硬界**。harness driver 1→8 型(新增 flap-to-gap vy 前瞻 / paddle-intercept 弃守排空 / drag-aiming / aim-fire),**四因归因铁律**(宿主门面 / driver 太朴素 / 可测性边界 / 实例缺陷≠模型)入 [`game-e2e skill §8`](../../.agents/skills/game-e2e-cdp-harness.md)。 +- **P3 评分矩阵 / agent-loop-v1 处置 / 全 20 款补全**:留后续波次。 diff --git a/docs/agent-specs/2026-06-15-WG1-driver-coverage闭口与P2对照-L1报告.md b/docs/agent-specs/2026-06-15-WG1-driver-coverage闭口与P2对照-L1报告.md new file mode 100644 index 00000000..6bd0a87b --- /dev/null +++ b/docs/agent-specs/2026-06-15-WG1-driver-coverage闭口与P2对照-L1报告.md @@ -0,0 +1,86 @@ +# 《W-G1 · driver-coverage 残留闭口 + P2 三档对照》L1 闭口报告 + +> **状态**:执行记录 · 2026-06-15 · L1(lili-mac)本地真玩取证 · lane `wg1/bakeoff-studio`(基于 origin/dev/2.0.0 c77f7a1)。 +> **范围**:创始人 2026-06-15 定档「driver 残留闭口 + P2 对照(L1 自主)」,P1 校准放量标 blocked-on-founder(已有 N=4 命门结论,见 calibration/report.json)。 +> **铁律**:零碰 L0(`game-cloud`/`game-runtime/src`/契约/前端/feed);只改我域 `game-runtime/games/_wg1-gen/**`(harness `play.cdp.cjs` + 各款 play-spec)与 `wg1/gen-worker/**`(briefs);宿主键盘桥(`boot-game-host.js`)只**消费重打包**、不修改。每条结论标【实测/推断/假设】。 + +--- + +## 1. 结论先行 + +1. **5 款 driver-coverage 失败件,0 个是「模型造不出」、0 个是「3D 硬界」**——全部是 ① 宿主键盘桥(L0 已修,重打包消费即生效)、② harness driver 太朴素(我域,已增强)、③ 可测性边界(游戏 exportState 不足→暴露所需常数即可解)。**终局:flappy/multiball/asteroids/angrybirds 4 款翻绿(✅九门全过);仅 t2048 余 8/9(latch=2048 抗死锁体裁边界,游戏本体真可玩,建议放宽门)**。【实测】 +2. **共享 driver 库 `play.cdp.cjs` 增四件**(可复用、向后兼容):flap-to-gap 加**速度前瞻**、paddle-intercept 加**弃守排空相位**、新增 **drag-aiming 第 7 型 + aim-fire 第 8 型**。【实测】 +3. **键盘款重打包即翻活**:t2048 `score 0→4`(真合并)、asteroids `F_wiring 0→41`(真旋向瞄准击碎 6 颗)——证 d754b71 键盘桥修复有效,旧产物是「修复前」陈值;**asteroids 再经 enrich 陨石坐标 + aim-fire driver 转确定性闭口(score 0→6 ✅)**。【实测】 +4. **P2 同款 Breakout 三档(flash/M2.7/pro)对照已成表**;叠加创始人亲玩锚——**强档 pro 反而被判碰撞 bug(fun2/fix)**,印证「过门率/便宜 player 高分 ≠ 真手感」,人锚不可替代。【实测】 + +--- + +## 2. driver-coverage 5 款归因(逐款实测) + +| 款 | 输入族 | 修前卡点 | 根因归类 | 处置 | 结果 | +|---|---|---|---|---|---| +| **flappy** | 触摸·重力穿缝 | H:score 0(撞下管) | driver(纯反应式无前瞻)+原实例缝隙过高 | flap-to-gap 加 vy 前瞻 + brief 补可达缝隙约束 + 重生成 | ✅ flash 重生成 **score 0→5**、缝隙 centerY 174→302 可达、latch✓(retries=2,wall 502s) | +| **multiball** | 触摸·挡板接球 | H:progress✓ latch✗(球不漏) | 原实例底部丢球未实现 + driver 无排空 | paddle-intercept 加弃守排空 + brief 补丢球语义 + 重生成 | ✅ flash 重生成**首发过**(retries=0)、remaining 78→69、弃守排空→lose latch✓ | +| **angrybirds** | 触摸·抛射 | H:score 0(盲拖打不中) | 可测性边界(发射物理常数未暴露) | brief **pin+导出 launch 物理常数** + drag-aiming **45°抛解析瞄准** + 重生成 | ✅ flash 重生成**首发过**(retries=0)、**score 0→20 result=win**、latch✓ | +| **t2048** | 键盘·合并 | H:键盘死→score 0 | 宿主键盘桥(L0 已修)+ **终态可达边界** | 重打包(键盘活)+ 2 向填充逼死锁 | ⚠️ `score 0→4`(progress✓)、latch✗(2048 设计抗死锁,盲态难逼满盘) | +| **asteroids** | 键盘·射击 | H:键盘死→score 0、F 0 | 宿主键盘桥(L0 已修)+ 可测性边界(无陨石坐标) | 重打包 + **enrich exportState 暴露陨石坐标 + aim-fire driver** | ✅ flash 重生成**首发过**(retries=0)、**score 0→6**(F 0→41 真旋向瞄准命中)、latch✓ | + +**逐款实测细节:** + +- **angrybirds**【实测·✅已闭】:初版盲扫(无物理常数)0 命中=可测性边界;**闭法=brief pin 死简单可解析物理(powerScale=8 / gravity=1200,无阻力)+ 导出 `launch:{gravity,powerScale}` + drag-aiming 45° 抛解析反解拖拽矢量(各发±力度微抖兜离散)**:flash 重生成首发过(`launch` 导出与 pin 完全一致、**score 0→20 result=win 清场**、latch✓)。**与 asteroids 同一范式:可测性边界 → 暴露所需常数 + 适配 driver → 确定性闭口。** + +- **t2048**【实测·边界】:重打包到已修宿主后 `score 0→4`(真键盘合并)、G_input✓、余 8 门✓——**键盘桥(原 P0 阻塞)已解**。仅 latch✗:2048 设计上玩家**不想**到 gameover,确定性盲态 driver(4 向循环/2 向填充)难在步数内逼出「满盘且四向无解」。**游戏 sound**;latch 需近解级填盘策略或放宽为「progress(score↑/board变)+ G」兜——后者证真已足。 + +- **asteroids**【实测·✅已闭】:重打包后键盘真生效(`F_wiring 0→26`、撞陨石死→latch✓),但旋转扫射 score 0(无陨石坐标无法瞄准)。**正确闭法=enrich `exportState` 暴露 `asteroids:[{x,y}]` + aim-fire driver(读 ship.angle 自适应旋向最近陨石→对齐开火)**:flash 重生成**首发过**(score 0→6、F 0→41、latch✓)。**这是「可测性边界 → 暴露目标坐标 + 适配 driver → 确定性闭口」的范式**(优于盲扫,可复用于一切射击/瞄准类)。 + +--- + +## 3. 可复用 driver 改进(`play.cdp.cjs`,向后兼容) + +1. **flap-to-gap 速度前瞻**:新增 `vyPath`(默认 `bird.vy`)+ `lookahead`(默认 0.18s)+ `aimBias`(默认 24px)。判据从「当前位置偏低就拍」升级为「`位置 + 速度×lookahead` 预测仍偏低才拍」——早拍防追不上、晚拍防过冲;`aimBias` 瞄缝心上方留下落余量。缺 vy 自动退化为纯位置反应式(老行为)。 +2. **paddle-intercept 弃守排空**:新增 `drainAfter`(默认 null=不排空,打砖块照旧)+ `drainX`。跑满 `drainAfter` 步证进展后,挡板停角落不再追球→球漏光→触发 lose/gameover,把「接球类靠一直接球永不失败」的真终态(latch)打出来。 +3. **drag-aiming 第 7 型(新)**:抛射瞄准(愤怒小鸟类)。游戏暴露 `launch{gravity,powerScale}` → **45° 抛解析反解拖拽矢量(确定性命中 + 各发±力度微抖兜离散)**;未暴露 → 退化 `powers[]` 力度扫描 + `upLead` 补下坠。angrybirds 经『brief pin+导出物理 + 解析瞄准』翻绿(score 0→20 win)。 +4. **aim-fire 第 8 型(新,Asteroids/射击类)**:读 `ship{x,y,angle}`+`targets[{x,y}]` 选最近目标,旋转使 `|目标方位(atan2)-angle|` 收敛→对齐即开火;旋向**自适应**(上拍 diff 变大就翻向,免猜 CW/CCW 角度约定)。**依赖游戏 exportState 暴露目标坐标**——把「无坐标盲射=可测性边界」转成「暴露坐标即可确定性瞄准」的真闭口(asteroids brief 已 enrich 出 `asteroids:[{x,y}]`)。 + +> driver 六律承袭(game-e2e skill §2):坐标走 rect 映射、触摸成对+步进、zone/phase 名以源码为真相、覆盖度=门能否兜住的前提。新增**第 7 律(本轮)**:技巧/射击类的 H 假阴须先分「宿主门面缺失(系统性,如键盘桥)/ driver 太朴素(我域改) / 状态导出不足(可测性边界,游戏侧补 exportState)」三因,**禁用『模型造不出』笼统归因**(spec §9)。 + +--- + +## 4. P2 Breakout 同款三档对照(已有数据成表) + +同 brief(breakout)、同 studio 多角色闭环,仅换模型阶段: + +| 阶段 | 文本模型 | 视觉 | 过门 | 自修复轮 | player 轮 | M3视觉 fun/判 | flash/pro文本 fun/判 | ¥/款 | 墙钟 | +|---|---|---|---|---|---|---|---|---|---| +| stage1 | deepseek-v4-flash | M3 | ✅ | 5 | 3 | 3/fix | 3/pass | **0.194** | 616s | +| stage1_mmx | MiniMax-M2.7 | M3 | ✅ | 6 | 3 | 2/fix | 4/pass | **0.514** | 296s | +| stage2 | deepseek-v4-pro | M3 | ✅ | 3 | 3 | 4/fix | 4/pass | **0.417** | 745s | + +**读表**【实测】: +- 三档都过九门(地板达标);**pro 自修复轮最少(3 vs 5/6)**=强档少返工;flash 单价最低(¥0.194,M2.7 因 completion_ratio=4 最贵 ¥0.514)。 +- **便宜 player(M3视觉/文本)给分与真手感脱节**:三档文本位都给 fun≥3/pass;但叠加**创始人亲玩锚**(calibration/labels.json):flash-v3 物理最好(fun4)、**pro 碰撞有明显问题(fun2/fix,两 player 却都给 4=假阳)**、M2.7 滑块一格一跳控制 bug(fun2)。→ **过门率/便宜 player 高分 ≠ 真好玩**,人锚是最终纠偏(命门结论,P1)。 + +> 样本=同款 Breakout(N=1 题面)。多题面横比(过门率梯度/¥每过门)属 P3 评分矩阵,本轮不做。 + +--- + +## 5. 三分类归因小结(spec §9) + +| 归因 | 命中款 | 性质 | +|---|---|---| +| 3D 硬界(源码证伪) | **0** | 本批无 3D | +| 模型造不出(真失败) | **0** | 5 款全能生成可装载/渲染/接线的运行件 | +| 宿主门面缺失(L0,系统性) | t2048 / asteroids(键盘桥) | **L0 已修 d754b71**,重打包即活 | +| driver-coverage + 可测性(我域+brief,已闭) | flappy / multiball / asteroids / angrybirds | driver 增强(vy前瞻/弃守排空/aim-fire/drag-aiming 解析)+ enrich exportState + 重生成,**4 款翻绿** | +| 体裁性边界(留界,建议放宽门) | t2048(2048 抗死锁 latch) | 游戏本体真可玩(键盘合并 score↑);latch 体裁性不可达,建议放宽为强 progress(score↑∧board变)+G | + +**结论**:scale-20 暴露的「失败」无一是模型能力天花板——**真难点在 harness driver 覆盖 + 宿主门面完备 + 游戏可测性导出**,与 cheap-model skill §9 画像一致并强化。 + +--- + +## 6. 后续项 + +- **angrybirds ✅ 本轮已闭**:brief pin+导出 `launch` 物理常数 + drag-aiming 45° 抛解析瞄准,flash 重生成 score 0→20 win。 +- **t2048 latch**:近解级填盘策略,或就 2048 类「抗死锁」游戏把 expectLatch 放宽为强 progress(score↑∧board变)+ G 兜——需在 spec 立规。 +- **flappy/multiball/asteroids ✅ 已闭**:flash 重生成在增强 driver 下全过(flappy retries=2 / multiball・asteroids retries=0)——证「实例缺陷 / 可测性缺口」非模型短板。`results/*.json` + `evidence/verdict.json` 为四件套证据。 +- **P1 校准放量**:待创始人对新款亲玩补 labels.json 锚(blocked-on-founder)。 diff --git a/game-runtime/games/_wg1-gen/_shared/play.cdp.cjs b/game-runtime/games/_wg1-gen/_shared/play.cdp.cjs index 82d23576..40f27626 100644 --- a/game-runtime/games/_wg1-gen/_shared/play.cdp.cjs +++ b/game-runtime/games/_wg1-gen/_shared/play.cdp.cjs @@ -207,6 +207,8 @@ async function runDriver(cdp, driver, hashes) { if (driver.type === 'seek-x') return runSeekX(cdp, driver, hashes); if (driver.type === 'tap-pairs') return runTapPairs(cdp, driver, hashes); if (driver.type === 'key-cycle') return runKeyCycle(cdp, driver, hashes); + if (driver.type === 'drag-aiming') return runDragAiming(cdp, driver, hashes); + if (driver.type === 'aim-fire') return runAimFire(cdp, driver, hashes); return runPaddleIntercept(cdp, driver, hashes); } @@ -245,23 +247,33 @@ async function runTapTargets(cdp, driver, hashes) { return { drove, steps }; } -/** type='flap-to-gap':读控制体 y 与目标缝隙中心 y——体在缝下方(y 更大=更低)就拍翅上升,否则任重力下落。驱动 Flappy 类穿缝。 */ +/** type='flap-to-gap':读控制体 y + 竖直速度 vy,做【速度前瞻预测】对齐缝隙中心——预测下一拍仍偏低就拍翅,否则任重力下落。 + * 原纯位置反应式对「高位缝/快下落」追不上或过冲(flappy 假阴根因);前瞻=早拍防追不上、晚拍防过冲。驱动 Flappy 类穿缝。 */ async function runFlapToGap(cdp, driver, hashes) { const yPath = driver.entityPath || 'bird.y'; + const vyPath = driver.vyPath || 'bird.vy'; // 竖直速度(y 向下为正→vy>0=下落);缺失则退化为纯位置反应式 const gapPath = driver.gapPath || 'nextGap.centerY'; const tapX = driver.tapX != null ? driver.tapX : 195; const steps = driver.steps || 60; const stepMs = driver.stepMs != null ? driver.stepMs : 110; const margin = driver.margin != null ? driver.margin : 16; + const lookahead = driver.lookahead != null ? driver.lookahead : 0.18; // 速度前瞻秒数:预测 lookahead 秒后位置(vy 单位 px/s) + const aimBias = driver.aimBias != null ? driver.aimBias : 24; // 瞄准缝心上方 aimBias px(y 越小越高),留下落余量→落入缝心而非贴下沿 let drove = 0; for (let i = 0; i < steps; i++) { const s = await readGameState(cdp); if (s && s.phase === 'gameover') break; // 已结束(撞死/通关)→停,交 latch 校验 const by = getPath(s, yPath); + const vy = getPath(s, vyPath); let gy = getPath(s, gapPath); if (typeof gy !== 'number') gy = 422; // 无缝隙信息→维持中线高度 - if (typeof by === 'number' && by > gy + margin) { await tap(cdp, tapX, 420); drove++; } // 偏低→拍翅上升 - else { await delay(20); } // 偏高/已对齐→不拍,让重力下落 + const target = gy - aimBias; // 目标点略高于缝心 + // 前瞻预测:当前位置 + 速度×lookahead = 下一拍预计位置;预测仍偏低于 target+margin 才拍翅(早拍/不过冲)。 + const predicted = (typeof by === 'number') + ? by + (typeof vy === 'number' ? vy * lookahead : 0) + : null; + if (predicted != null && predicted > target + margin) { await tap(cdp, tapX, 420); drove++; } // 预测偏低→拍翅上升 + else { await delay(20); } // 预测偏高/已对齐→不拍,让重力下落 try { hashes.push(await sampleHash(cdp, '#game-engine')); } catch (_) {} await delay(stepMs); } @@ -348,16 +360,139 @@ async function runKeyCycle(cdp, driver, hashes) { return { drove, steps }; } -/** type='paddle-intercept':每步读球 x、tap 到球正下方把挡板移过去接(真玩到清砖);到 gameover 即停。 */ +/** type='drag-aiming':抛射瞄准(愤怒小鸟类)。读 targets[{x,y}] 选最近目标 + `launch{gravity,powerScale}`: + * 游戏暴露物理常数 → 45° 抛【解析反解】拖拽矢量(确定性命中 + 各发 ±力度微抖兜物理离散;asteroids 式『暴露即可测』范式); + * 未暴露 → 退化「力度扫描 powers[] + 上抬补下坠 upLead」逐发兜(确定性尽力,非保证;全 miss=可测性边界,非模型造不出)。 */ +async function runDragAiming(cdp, driver, hashes) { + const origin = driver.origin || { x: 80, y: 600 }; // 弹弓发射点(逻辑像素) + const targetsPath = driver.targetsPath || 'targets'; + const steps = driver.steps || 6; // 最多发射次数(通常=birdsLeft) + const settleMs = driver.settleMs != null ? driver.settleMs : 1700; // 每发后等飞行+结算 + const powers = driver.powers || [70, 95, 120, 150, 180, 210, 240]; // 拖拽距离扫描(力∝距离,常数未知→扫描兜不同射程) + const upLead = driver.upLead != null ? driver.upLead : 60; // 抛物线下坠补偿:瞄准点上抬 px + const dragMs = driver.dragMs != null ? driver.dragMs : 360; + let drove = 0, shot = 0; + for (let i = 0; i < steps; i++) { + const s = await readGameState(cdp); + if (s && s.phase === 'gameover') break; // 终局即停(鸟用完/全清)→交 latch 校验 + const targets = getPath(s, targetsPath); + // 选最近的活目标(猪/关键砖);无合法目标→停。 + let aim = null; + if (Array.isArray(targets) && targets.length) { + for (const t of targets) { + if (!t || typeof t.x !== 'number' || typeof t.y !== 'number') continue; + if (!aim) { aim = t; continue; } + const da = Math.hypot(aim.x - origin.x, aim.y - origin.y); + const db = Math.hypot(t.x - origin.x, t.y - origin.y); + if (db < da) aim = t; + } + } + if (!aim) break; + // 物理感知瞄准:游戏暴露 launch{gravity,powerScale} → 45° 抛解析反解拖拽矢量;否则退化力度扫描。 + const launch = getPath(s, driver.launchPath || 'launch'); + let to = null; + if (launch && typeof launch.gravity === 'number' && typeof launch.powerScale === 'number' && launch.powerScale > 0) { + const g = launch.gravity, K = launch.powerScale; + const dx = aim.x - origin.x; // 目标在右为正 + const dyUp = origin.y - aim.y; // 目标在上为正(屏 y 向下) + const denom = dx - dyUp; // 45° 抛闭式需 dx>dyUp + if (dx > 0 && denom > 0) { + const c = Math.sqrt(0.5 * g * dx * dx / denom); // 45° 各轴分速 vx=vyUp=c(初速 s=c√2) + const jit = [0, 0.06, -0.06, 0.12, -0.12, 0.18][shot % 6]; // 各发 ±力度微抖,兜物理离散/常数微偏 + const dragLen = (c / K) * (1 + jit); // 反解每轴拖拽像素(拖拽距×K=初速) + const cand = { x: origin.x - dragLen, y: origin.y + dragLen }; // 左下拖→右上发 + if (cand.x >= 4 && cand.y <= 840) to = cand; // 解在屏内才用,否则退扫描 + } + } + if (!to) { + // 退化:无 launch 常数 / 解超界 → origin→aim 方向 + 力度扫描(原行为)。 + const aimY = aim.y - upLead; + const ddx = aim.x - origin.x, ddy = aimY - origin.y; + const len = Math.hypot(ddx, ddy) || 1; + const power = powers[shot % powers.length]; + to = { + x: Math.max(4, Math.min(386, origin.x - (ddx / len) * power)), + y: Math.max(4, Math.min(840, origin.y - (ddy / len) * power)), + }; + } + await drag(cdp, origin, to, dragMs); + drove++; shot++; + try { hashes.push(await sampleHash(cdp, '#game-engine')); } catch (_) {} + await delay(settleMs); + } + return { drove, steps }; +} + +/** type='aim-fire':射击瞄准(Asteroids 类)。读 ship{x,y,angle} + targets[{x,y}] 选最近目标,旋转使 + * |目标方位(atan2) - ship.angle| 收敛→对齐即开火;旋向【自适应】(上拍 |diff| 变大就翻向,免猜角度约定 CW/CCW)。 + * 依赖游戏 exportState 暴露目标坐标(可测性红线)——盲射无坐标=可测性边界,暴露后即可确定性瞄准。 */ +async function runAimFire(cdp, driver, hashes) { + const shipPath = driver.shipPath || 'ship'; + const targetsPath = driver.targetsPath || 'asteroids'; + const fireKey = driver.fireKey || 'Space'; + const cwKey = driver.cwKey || 'ArrowRight'; + const ccwKey = driver.ccwKey || 'ArrowLeft'; + const tol = driver.tol != null ? driver.tol : 0.20; // 对齐容差(弧度,~11°) + const steps = driver.steps || 80; + const stepMs = driver.stepMs != null ? driver.stepMs : 130; + const downMs = driver.downMs != null ? driver.downMs : 70; + const norm = (a) => { while (a > Math.PI) a -= 2 * Math.PI; while (a < -Math.PI) a += 2 * Math.PI; return a; }; + let drove = 0, lastDiff = null, rotKey = cwKey; + for (let i = 0; i < steps; i++) { + const s = await readGameState(cdp); + if (s && s.phase === 'gameover') break; // 终局即停(清光/被撞死)→交 latch 校验 + const ship = getPath(s, shipPath); + const targets = getPath(s, targetsPath); + let aim = null; + if (ship && typeof ship.x === 'number' && Array.isArray(targets)) { + for (const t of targets) { + if (!t || typeof t.x !== 'number' || typeof t.y !== 'number') continue; + if (!aim) { aim = t; continue; } + const da = Math.hypot(aim.x - ship.x, aim.y - ship.y); + const db = Math.hypot(t.x - ship.x, t.y - ship.y); + if (db < da) aim = t; + } + } + if (aim && ship && typeof ship.angle === 'number') { + const bearing = Math.atan2(aim.y - ship.y, aim.x - ship.x); + const diff = Math.abs(norm(bearing - ship.angle)); + if (diff <= tol) { // 已对齐→开火 + await key(cdp, fireKey, downMs); drove++; lastDiff = null; + } else { // 未对齐→旋转(自适应旋向) + if (lastDiff != null && diff > lastDiff) rotKey = (rotKey === cwKey ? ccwKey : cwKey); + await key(cdp, rotKey, downMs); drove++; lastDiff = diff; + } + } else { + // 读不到 ship/targets(游戏未暴露坐标)→退化盲扫(旋转+开火),H 门会判(可测性红线) + await key(cdp, i % 2 ? fireKey : cwKey, downMs); drove++; + } + try { hashes.push(await sampleHash(cdp, '#game-engine')); } catch (_) {} + await delay(stepMs); + } + return { drove, steps }; +} + +/** type='paddle-intercept':每步读球 x、tap 到球正下方把挡板移过去接(真玩到清砖);到 gameover 即停。 + * drainAfter 声明时:跑满 drainAfter 步(已证进展)后转【弃守排空相位】——挡板停角落不再追球,让球漏光→触发 lose/gameover, + * 验真终态(接球类如 multiball 靠一直接球永不失败→latch 不可达,drain 把真失败态打出来)。 */ async function runPaddleIntercept(cdp, driver, hashes) { const ballPath = driver.ballPath || 'ball.x'; const paddleY = driver.paddleY != null ? driver.paddleY : 800; const steps = driver.steps || 60; const stepMs = driver.stepMs || 130; + const drainAfter = driver.drainAfter != null ? driver.drainAfter : null; // 此步后弃守排空(null=不排空,向后兼容打砖块) + const drainX = driver.drainX != null ? driver.drainX : 10; // 排空相位挡板停泊 x(远离球→球漏掉) let drove = 0; for (let i = 0; i < steps; i++) { const s = await readGameState(cdp); if (s && s.phase === 'gameover') break; // 已结束,停(剩交给 latch 校验) + if (drainAfter != null && i >= drainAfter) { + // 弃守排空相位:挡板停角落、不再追球,等球漏光→失败终态(latch)。 + await tap(cdp, drainX, paddleY); + try { hashes.push(await sampleHash(cdp, '#game-engine')); } catch (_) {} + await delay(stepMs); + continue; + } const bx = getPath(s, ballPath); if (typeof bx === 'number') { await tap(cdp, Math.max(8, Math.min(382, bx)), paddleY); drove++; } else { await delay(stepMs); } // 读不到球位=游戏没导出位置,空转(H 门会判红线) diff --git a/game-runtime/games/_wg1-gen/angrybirds/bundle.iife.js b/game-runtime/games/_wg1-gen/angrybirds/bundle.iife.js index 46bc1967..ab75de34 100644 --- a/game-runtime/games/_wg1-gen/angrybirds/bundle.iife.js +++ b/game-runtime/games/_wg1-gen/angrybirds/bundle.iife.js @@ -1,34 +1,34 @@ -"use strict";var __GameBundle=(()=>{var zs=Object.defineProperty;var kc=Object.getOwnPropertyDescriptor;var Gc=Object.getOwnPropertyNames;var Fc=Object.prototype.hasOwnProperty;var jc=(n,t,e)=>()=>{if(e)throw e[0];try{return n&&(t=n(n=0)),t}catch(i){throw e=[i],i}};var Hr=(n,t)=>{for(var e in t)zs(n,e,{get:t[e],enumerable:!0})},Nc=(n,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Gc(t))!Fc.call(n,s)&&s!==e&&zs(n,s,{get:()=>t[s],enumerable:!(i=kc(t,s))||i.enumerable});return n};var Bc=n=>Nc(zs({},"__esModule",{value:!0}),n);var Ic={};Hr(Ic,{ASSERT:()=>p,BLACK:()=>it,BLUE:()=>Za,Box2dDistanceJoint:()=>Ts,Box2dFrictionJoint:()=>$o,Box2dGearJoint:()=>qo,Box2dJoint:()=>Ut,Box2dKinematicObject:()=>Bo,Box2dMotorJoint:()=>Qo,Box2dObject:()=>Ri,Box2dPinJoint:()=>Uo,Box2dPlugin:()=>As,Box2dPrismaticJoint:()=>Ho,Box2dPulleyJoint:()=>Ko,Box2dRaycastResult:()=>ws,Box2dRevoluteJoint:()=>Wo,Box2dRopeJoint:()=>Vo,Box2dStaticObject:()=>Ss,Box2dTargetJoint:()=>Jo,Box2dTileLayer:()=>zo,Box2dWeldJoint:()=>Yo,Box2dWheelJoint:()=>Xo,CLEAR_BLACK:()=>he,CLEAR_WHITE:()=>on,CYAN:()=>ql,CanvasLayer:()=>us,Color:()=>St,Ease:()=>_s,EngineObject:()=>Je,GRAY:()=>Vl,GREEN:()=>Qa,ImageFont:()=>ss,LOG:()=>gt,Light:()=>Oo,LightSystemPlugin:()=>Lo,MAGENTA:()=>Hl,Medal:()=>xs,NewgroundsMedal:()=>Eo,NewgroundsPlugin:()=>Ro,ORANGE:()=>Wl,PI:()=>H,PURPLE:()=>tc,Particle:()=>hs,ParticleEmitter:()=>vo,PathFinder:()=>Zo,PathFinderNode:()=>Es,PostProcessPlugin:()=>Po,RED:()=>rr,RandomGenerator:()=>yo,Sound:()=>xi,SoundInstance:()=>cs,TextureInfo:()=>Ue,TileCollisionLayer:()=>Si,TileInfo:()=>_e,TileLayer:()=>vi,TileLayerData:()=>wn,Timer:()=>Te,Tween:()=>Cs,UIButton:()=>Ei,UICheckbox:()=>Go,UILayout:()=>No,UIObject:()=>ne,UISlider:()=>Fo,UISystemPlugin:()=>Io,UIText:()=>vs,UITextInput:()=>Mo,UITile:()=>ko,UIVideo:()=>jo,Vector2:()=>st,WHITE:()=>V,YELLOW:()=>Ka,ZzFXMusic:()=>Do,abs:()=>tt,atan2:()=>ir,audioContext:()=>ut,audioDefaultSampleRate:()=>Qn,audioIsRunning:()=>bi,audioMasterGain:()=>ze,box2d:()=>m,box2dDebug:()=>qr,box2dInit:()=>ad,box2dSetDebug:()=>rd,cameraAngle:()=>$,cameraFit:()=>rh,cameraPos:()=>At,cameraScale:()=>q,canvasClearColor:()=>Ze,canvasColorTiles:()=>Ps,canvasFixedSize:()=>Gn,canvasMaxAspect:()=>kn,canvasMaxSize:()=>Mn,canvasMinAspect:()=>ri,canvasPixelRatio:()=>tn,canvasPixelated:()=>lr,ceil:()=>hi,clamp:()=>N,combineCanvases:()=>wr,cos:()=>ot,debug:()=>Dt,debugCircle:()=>jt,debugClear:()=>Ml,debugLine:()=>ve,debugOverlap:()=>fo,debugOverlay:()=>Ie,debugPoint:()=>nr,debugPointSize:()=>ka,debugPoly:()=>Il,debugRect:()=>yt,debugScreenshot:()=>Fa,debugShowErrors:()=>kl,debugText:()=>In,debugVideoCaptureIsActive:()=>Se,debugVideoCaptureStart:()=>ja,debugVideoCaptureStop:()=>Na,debugWatermark:()=>Rs,distanceAngle:()=>zl,distanceWrap:()=>sr,drawCanvas2D:()=>Rn,drawCircle:()=>is,drawCircleGradient:()=>ih,drawContext:()=>wt,drawCount:()=>Ae,drawCrescent:()=>ud,drawEllipse:()=>sc,drawEllipseGradient:()=>oc,drawLine:()=>mn,drawLineList:()=>mo,drawNineSlice:()=>Ec,drawNineSliceScreen:()=>cd,drawPoly:()=>Un,drawRect:()=>ns,drawRectGradient:()=>th,drawRegularPoly:()=>ic,drawText:()=>sh,drawTextScreen:()=>en,drawTextureWrapped:()=>eh,drawThreeSlice:()=>Rc,drawThreeSliceScreen:()=>ld,drawTile:()=>Rt,enablePhysicsSolver:()=>Is,engineAddPlugin:()=>_n,engineImageFont:()=>lc,engineInit:()=>Pl,engineName:()=>Hi,engineObjects:()=>mt,engineObjectsCallback:()=>Ol,engineObjectsCollect:()=>Ma,engineObjectsCollide:()=>er,engineObjectsDestroy:()=>Ll,engineObjectsRaycast:()=>Dl,engineObjectsUpdate:()=>Ia,engineVersion:()=>Xi,fetchJSON:()=>Xl,floor:()=>vt,fontDefault:()=>Pi,formatTime:()=>ar,frame:()=>Oa,frameRate:()=>_l,gamepadConnected:()=>xo,gamepadDirectionEmulateStick:()=>gr,gamepadDpad:()=>bo,gamepadIsDown:()=>De,gamepadPrimary:()=>pt,gamepadStick:()=>gi,gamepadStickCount:()=>uc,gamepadVibrate:()=>Sh,gamepadVibrateStop:()=>wh,gamepadWasPressed:()=>Rr,gamepadWasReleased:()=>vh,gamepadsEnable:()=>Ms,getCameraSize:()=>ac,getCrescentPoints:()=>Pc,getNoteFrequency:()=>yc,getPaused:()=>El,glAntialias:()=>Mr,glCanvas:()=>Z,glCircleSides:()=>Li,glClearCanvas:()=>vc,glClearRect:()=>Cc,glCompileShader:()=>_o,glContext:()=>g,glCopyToContext:()=>Nr,glCreateProgram:()=>Xn,glCreateTexture:()=>js,glDeleteTexture:()=>wc,glDraw:()=>Ai,glDrawColoredPoints:()=>Jr,glDrawOutlineTransform:()=>zr,glDrawPoints:()=>Ac,glDrawPointsTransform:()=>Br,glDrawUntextured:()=>Tc,glEnable:()=>F,glFlush:()=>Ct,glSetAntialias:()=>Yh,glSetRenderTarget:()=>oi,glSetTexture:()=>Fr,glSetTextureData:()=>jr,glSetTextureWrap:()=>Sc,gravity:()=>Nt,headlessMode:()=>B,hsl:()=>ke,hypot:()=>Ba,inputClear:()=>Gi,inputClearKey:()=>_r,inputMouseMoveThreshold:()=>Cr,inputPreventDefault:()=>Fn,inputWASDEmulateDirection:()=>ai,isArray:()=>le,isColor:()=>J,isFullscreen:()=>cc,isIntersecting:()=>Va,isNumber:()=>L,isOnScreen:()=>ah,isOverlapping:()=>Qi,isPowerOfTwo:()=>di,isStringLike:()=>U,isTouchDevice:()=>te,isUsingGamepad:()=>Nn,isVector2:()=>O,keyDirection:()=>bh,keyIsDown:()=>Et,keyWasPressed:()=>Lt,keyWasReleased:()=>Er,lastInputDevice:()=>Ke,lerp:()=>Bt,lerpAngle:()=>Jl,lerpWrap:()=>Ua,lightSystem:()=>W,lineTest:()=>qa,log2:()=>za,mainCanvas:()=>j,mainCanvasSize:()=>k,mainContext:()=>at,max:()=>Y,medalDisplaySize:()=>ms,medalDisplaySlideTime:()=>jn,medalDisplayTime:()=>gs,medals:()=>Ci,medalsForEach:()=>Ns,medalsInit:()=>Zh,medalsPreventUnlock:()=>Ur,medalsReset:()=>td,min:()=>K,mod:()=>Zt,mouseDelta:()=>Tr,mouseDeltaScreen:()=>me,mouseInWindow:()=>os,mouseIsDown:()=>li,mousePos:()=>Oe,mousePosScreen:()=>Ft,mouseWasPressed:()=>yi,mouseWasReleased:()=>xh,mouseWheel:()=>Ar,nearestPowerOfTwo:()=>Ul,newgrounds:()=>_i,noise1D:()=>Zl,noise2D:()=>tu,objectDefaultAngleDamping:()=>fr,objectDefaultDamping:()=>dr,objectDefaultFriction:()=>yr,objectDefaultMass:()=>hr,objectDefaultRestitution:()=>pr,objectMaxSpeed:()=>Ge,oscillate:()=>Wa,particleEmitRateScale:()=>Zi,paused:()=>we,percent:()=>It,percentLerp:()=>Bl,playSamples:()=>Ir,pointerLockExit:()=>Ch,pointerLockIsActive:()=>hc,pointerLockRequest:()=>Ah,postProcess:()=>Pt,primitiveCount:()=>Ce,rand:()=>lt,randBool:()=>Ha,randColor:()=>po,randInCircle:()=>$a,randInt:()=>or,randSign:()=>Xa,randVec2:()=>Ya,readSaveData:()=>Kl,rgb:()=>z,round:()=>$i,saveCanvas:()=>ec,saveDataURL:()=>fi,saveText:()=>Yl,screenToWorld:()=>Mi,screenToWorldDelta:()=>rc,screenToWorldTransform:()=>ki,setAdditiveBlendMode:()=>pi,setCameraAngle:()=>nu,setCameraPos:()=>eu,setCameraScale:()=>iu,setCanvasClearColor:()=>ru,setCanvasColorTiles:()=>ou,setCanvasFixedSize:()=>uu,setCanvasMaxAspect:()=>lu,setCanvasMaxSize:()=>au,setCanvasMinAspect:()=>cu,setCanvasPixelRatio:()=>du,setCanvasPixelated:()=>nc,setCursor:()=>hh,setDebugKey:()=>Zu,setDebugWatermark:()=>Qu,setEnablePhysicsSolver:()=>Su,setFontDefault:()=>fu,setGLCircleSides:()=>mu,setGLEnable:()=>gu,setGamepadDirectionEmulateStick:()=>Ou,setGamepadsEnable:()=>Lu,setGravity:()=>Ru,setHeadlessMode:()=>yu,setInputMouseMoveThreshold:()=>ph,setInputPreventDefault:()=>fh,setInputWASDEmulateDirection:()=>Du,setMedalDisplaySize:()=>id,setMedalDisplaySlideTime:()=>nd,setMedalDisplayTime:()=>ed,setMedalsPreventUnlock:()=>sd,setObjectDefaultAngleDamping:()=>Au,setObjectDefaultDamping:()=>Tu,setObjectDefaultFriction:()=>_u,setObjectDefaultMass:()=>wu,setObjectDefaultRestitution:()=>Cu,setObjectMaxSpeed:()=>Eu,setParticleEmitRateScale:()=>Pu,setPaused:()=>Rl,setShowSplashScreen:()=>pu,setSoundDefaultRange:()=>$u,setSoundDefaultTaper:()=>Ku,setSoundEnable:()=>Xu,setSoundVolume:()=>Yu,setTileDefaultBleed:()=>vu,setTileDefaultPadding:()=>xu,setTileDefaultSize:()=>bu,setTilesPixelated:()=>hu,setTimeScale:()=>su,setTouchGamepadAlpha:()=>Vu,setTouchGamepadAnalog:()=>zu,setTouchGamepadButtonCount:()=>Fu,setTouchGamepadCenterButtonSize:()=>Gu,setTouchGamepadDisplayTime:()=>Wu,setTouchGamepadEnable:()=>Mu,setTouchGamepadFloating:()=>Ju,setTouchGamepadLeftButtonCount:()=>Nu,setTouchGamepadLeftStick:()=>ju,setTouchGamepadPassthrough:()=>ku,setTouchGamepadRightStick:()=>Bu,setTouchGamepadSize:()=>Uu,setTouchGamepadVibration:()=>qu,setTouchInputEnable:()=>Iu,setVibrateEnable:()=>Hu,shareURL:()=>$l,showSplashScreen:()=>ur,sign:()=>Qt,sin:()=>et,smoothStep:()=>Ki,soundDefaultRange:()=>xr,soundDefaultTaper:()=>vr,soundEnable:()=>Jt,soundVolume:()=>Sn,speak:()=>Bh,speakStop:()=>zh,tan:()=>Ja,textureInfos:()=>an,tile:()=>Ii,tileCollisionGetData:()=>ls,tileCollisionLayers:()=>nn,tileCollisionRaycast:()=>gc,tileCollisionTest:()=>Ye,tileDefaultBleed:()=>Ds,tileDefaultPadding:()=>Os,tileDefaultSize:()=>Ls,tileLayersLoad:()=>Uh,tilesPixelated:()=>Tn,time:()=>Ht,timeDelta:()=>tr,timeReal:()=>sn,timeScale:()=>cr,toggleFullscreen:()=>uh,touchGamepadAlpha:()=>br,touchGamepadAnalog:()=>Oi,touchGamepadButtonCount:()=>Yn,touchGamepadCenterButtonSize:()=>ue,touchGamepadDisplayTime:()=>ci,touchGamepadEnable:()=>rn,touchGamepadFloating:()=>cn,touchGamepadLeftButtonCount:()=>$n,touchGamepadLeftStick:()=>En,touchGamepadPassthrough:()=>mr,touchGamepadRightStick:()=>Kn,touchGamepadSize:()=>zt,touchGamepadVibration:()=>ts,touchInputEnable:()=>gn,tweenProperty:()=>hd,tweenStopAll:()=>dd,tweenUpdate:()=>Dc,uiDebug:()=>Wr,uiSetDebug:()=>od,uiSystem:()=>C,usingGamepadInput:()=>mh,usingKeyboardInput:()=>gh,usingMouseInput:()=>yh,vec2:()=>b,vibrate:()=>Pr,vibrateEnable:()=>Di,vibrateStop:()=>Th,workCanvas:()=>Ne,workContext:()=>$e,workReadCanvas:()=>xe,workReadContext:()=>Fe,worldToScreen:()=>Pn,worldToScreenDelta:()=>oh,writeSaveData:()=>Ql,zzfx:()=>Jh,zzfxG:()=>Gs,zzfxM:()=>_c});function El(){return we}function Rl(n=!0){we=n}function _n(n,t,e,i){p(!bn.find(o=>o.update===n&&o.render===t&&o.glContextLost===e&&o.glContextRestored===i));let s=new uo(n,t,e,i);bn.push(s)}async function Pl(n,t,e,i,s,o=[],r){if(Da&&console.log(`${Hi} Engine v${Xi}`),p(!at,"engine already initialized"),at)return;p(le(o),"pass in images as array"),document.body||document.documentElement.appendChild(document.createElement("body")),r||(r=document.body),n||(n=()=>{}),t||(t=()=>{}),e||(e=()=>{}),i||(i=()=>{}),s||(s=()=>{});function a(){k=b(j.width,j.height),at.imageSmoothingEnabled=!Tn,Co()}function c(y=0){let x=y-ao;ao||(x=0),ao=y,(Dt||Rs)&&(Yi=Bt(Yi,1e3/(x||1),.05));let v=Dt&&Et("Equal"),w=Dt&&Et("Minus"),_=v?10:w?.1:1;sn+=x*_/1e3;let S=cr*_;x*=S,ge+=we?0:x,S<=1&&(ge=K(ge,50));let E=!1;if(we){E=!0,l(),Ca(),bn.forEach(T=>{var P;return(P=T.update)==null?void 0:P.call(T)});for(let T of mt)T.parent||T.updateTransforms();Sa(),e(),_a(),Se()&&A()}else{let T=0;for(ge<0&&ge>-9&&(T=ge,ge=0);ge>=0;ge-=1e3/60)Ht=Oa++/60,E=!0,l(),Ca(),t(),bn.forEach(P=>{var G;return(G=P.update)==null?void 0:G.call(P)}),Ia(),Sa(),e(),_a(),Se()&&A();ge+=T}Se()||A(),requestAnimationFrame(c);function A(){if(!B){E||l(),a(),i(),mt.sort((T,P)=>T.renderOrder-P.renderOrder);for(let T of mt)T.destroyed||T.render();s(),bn.forEach(T=>{var P;return(P=T.render)==null?void 0:P.call(T)}),Eh(),Fl(),Ct(),jl(),Ae=0,Ce=0}}}function l(){if(!B){if(Gn.x){k=Gn.copy();let y=innerWidth/innerHeight,x=Gn.x/Gn.y,v=ykn){let E=k.y*kn|0;k.x=K(E,Mn.x)}else if(w0&&!F&&(at.fillStyle=Ze.toString(),at.fillRect(0,0,k.x,k.y),at.fillStyle=it.toString()),at.lineJoin="round",at.lineCap="round"}}if(B)return d();qh(r);let u="margin:0;overflow:hidden;background:#000;user-select:none;-webkit-user-select:none;touch-action:none;-webkit-touch-callout:none";r.style.cssText=u,j=r.appendChild(document.createElement("canvas")),wt=at=j.getContext("2d"),_h(),Nh(),Gl();let h="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)";j.style.cssText=h,Z&&(Z.style.cssText=h),nc(lr),l(),Co(),Ne=new OffscreenCanvas(64,64),$e=Ne.getContext("2d"),xe=new OffscreenCanvas(64,64),Fe=xe.getContext("2d",{willReadFrequently:!0});let f=o.map((y,x)=>Ta(x,y));return o.length||f.push(Ta(0)),f.push(dh()),ur&&f.push(new Promise(y=>{let x=0;v();function v(){Gi(),Qh(x+=.01),x>1?y():setTimeout(v,16)}})),await Promise.all(f),d();async function d(){await n(),c()}}function Ia(){er=mt.filter(t=>t.collideSolidObjects);function n(t){if(!t.destroyed){t.update();for(let e of t.children)n(e)}}for(let t of mt)if(!(t.parent||t.destroyed)){t.update(),t.updatePhysics();for(let e of t.children)n(e);t.updateTransforms()}mt=mt.filter(t=>!t.destroyed)}function Ll(n=!0){for(let t of mt)t.parent||t.destroy(n);mt=mt.filter(t=>!t.destroyed)}function Ma(n,t,e=mt){let i=[];if(n)if(t instanceof st)for(let s of e)s.isOverlapping(n,t)&&i.push(s);else{let s=t*t;for(let o of e)n.distanceSquared(o.pos)e(s))}function Dl(n,t,e=mt){let i=[];for(let s of e)s.collideRaycast&&Va(n,t,s.pos,s.size)&&(ce&&yt(s.pos,s.size,"#f00"),i.push(s));return ce&&ve(n,t,i.length?"#f00":"#00f",.02),i}function p(n,...t){if(!n)throw console.assert(n,...t),new Error("Assert failed!")}function gt(...n){console.log(...n)}function yt(n,t=b(),e=V,i=0,s=0,o=!1,r=!1){p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(U(e)||J(e),"color is invalid"),p(L(i),"time must be a number"),p(L(s),"angle must be a number"),J(e)&&(e=e.toString());let a=new Te(i);Qe.push({pos:n.copy(),size:t.copy(),color:e,timer:a,angle:s,fill:o,screenSpace:r})}function Il(n,t,e=V,i=0,s=0,o=!1,r=!1){p(O(n),"pos must be a vec2"),p(le(t),"points must be an array"),p(U(e)||J(e),"color is invalid"),p(L(i),"time must be a number"),p(L(s),"angle must be a number"),J(e)&&(e=e.toString()),n=n.copy(),t=t.map(c=>c.copy());let a=new Te(i);Qe.push({pos:n,points:t,color:e,timer:a,angle:s,fill:o,screenSpace:r})}function jt(n,t=0,e=V,i=0,s=!1,o=!1){p(O(n),"pos must be a vec2"),p(L(t),"size must be a number"),p(U(e)||J(e),"color is invalid"),p(L(i),"time must be a number"),J(e)&&(e=e.toString()),n=n.copy();let r=new Te(i);Qe.push({pos:n,size:t,color:e,timer:r,angle:0,fill:s,screenSpace:o})}function nr(n,t,e,i,s=!1){yt(n,void 0,t,e,i,!1,s)}function ve(n,t,e,i=.1,s=0,o=!1){p(O(n),"posA must be a vec2"),p(O(t),"posB must be a vec2"),p(L(i),"width must be a number");let r=b((t.x-n.x)/2,(t.y-n.y)/2),a=b(i,r.length()*2);yt(n.add(r),a,e,s,r.angle(),!0,o)}function fo(n,t,e,i,s,o,r=!1){p(O(n),"posA must be a vec2"),p(O(e),"posB must be a vec2"),p(O(t),"sizeA must be a vec2"),p(O(i),"sizeB must be a vec2");let a=b(K(n.x-t.x/2,e.x-i.x/2),K(n.y-t.y/2,e.y-i.y/2)),c=b(Y(n.x+t.x/2,e.x+i.x/2),Y(n.y+t.y/2,e.y+i.y/2));yt(a.lerp(c,.5),c.subtract(a),s,o,0,!1,r)}function In(n,t,e=1,i=V,s=0,o=0,r="monospace",a=!1){p(U(n),"text must be a string"),p(O(t),"pos must be a vec2"),p(L(e),"size must be a number"),p(U(i)||J(i),"color is invalid"),p(L(s),"time must be a number"),p(L(o),"angle must be a number"),p(U(r),"font must be a string"),J(i)&&(i=i.toString()),t=t.copy();let c=new Te(s);Qe.push({text:n,pos:t,size:e,color:i,timer:c,angle:o,font:r,screenSpace:a})}function Ml(){Qe=[]}function Fa(){ho=1}function kl(){let n=e=>{document.body.style="background-color:#111;margin:8px",document.body.innerHTML="
"+e},t=console.assert;console.assert=(e,...i)=>{if(t(e,...i),!e){let s=i.join(" "),o=new Error().stack;throw`Assertion failed!
+"use strict";var __GameBundle=(()=>{var Fs=Object.defineProperty;var kc=Object.getOwnPropertyDescriptor;var Gc=Object.getOwnPropertyNames;var Fc=Object.prototype.hasOwnProperty;var jc=(n,t,e)=>()=>{if(e)throw e[0];try{return n&&(t=n(n=0)),t}catch(i){throw e=[i],i}};var Vr=(n,t)=>{for(var e in t)Fs(n,e,{get:t[e],enumerable:!0})},Bc=(n,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Gc(t))!Fc.call(n,s)&&s!==e&&Fs(n,s,{get:()=>t[s],enumerable:!(i=kc(t,s))||i.enumerable});return n};var Nc=n=>Bc(Fs({},"__esModule",{value:!0}),n);var Lc={};Vr(Lc,{ASSERT:()=>p,BLACK:()=>it,BLUE:()=>$a,Box2dDistanceJoint:()=>bs,Box2dFrictionJoint:()=>qo,Box2dGearJoint:()=>Jo,Box2dJoint:()=>Ut,Box2dKinematicObject:()=>Go,Box2dMotorJoint:()=>Xo,Box2dObject:()=>wi,Box2dPinJoint:()=>Bo,Box2dPlugin:()=>xs,Box2dPrismaticJoint:()=>Uo,Box2dPulleyJoint:()=>Ho,Box2dRaycastResult:()=>ms,Box2dRevoluteJoint:()=>zo,Box2dRopeJoint:()=>No,Box2dStaticObject:()=>gs,Box2dTargetJoint:()=>jo,Box2dTileLayer:()=>Fo,Box2dWeldJoint:()=>Wo,Box2dWheelJoint:()=>Vo,CLEAR_BLACK:()=>ce,CLEAR_WHITE:()=>Ze,CYAN:()=>ql,CanvasLayer:()=>os,Color:()=>vt,Ease:()=>Ss,EngineObject:()=>ke,GRAY:()=>Vl,GREEN:()=>Ya,ImageFont:()=>Zi,LOG:()=>mt,Light:()=>_o,LightSystemPlugin:()=>Eo,MAGENTA:()=>Hl,Medal:()=>ps,NewgroundsMedal:()=>To,NewgroundsPlugin:()=>Ao,ORANGE:()=>Wl,PI:()=>H,PURPLE:()=>Ka,Particle:()=>rs,ParticleEmitter:()=>go,PathFinder:()=>Yo,PathFinderNode:()=>ws,PostProcessPlugin:()=>Co,RED:()=>nr,RandomGenerator:()=>uo,Sound:()=>fi,SoundInstance:()=>is,TextureInfo:()=>Ge,TileCollisionLayer:()=>yi,TileInfo:()=>we,TileLayer:()=>pi,TileLayerData:()=>mn,Timer:()=>xe,Tween:()=>vs,UIButton:()=>Si,UICheckbox:()=>Do,UILayout:()=>ko,UIObject:()=>ee,UISlider:()=>Io,UISystemPlugin:()=>Po,UIText:()=>ys,UITextInput:()=>Lo,UITile:()=>Oo,UIVideo:()=>Mo,Vector2:()=>ot,WHITE:()=>U,YELLOW:()=>Xa,ZzFXMusic:()=>Ro,abs:()=>tt,atan2:()=>Zo,audioContext:()=>dt,audioDefaultSampleRate:()=>qn,audioIsRunning:()=>di,audioMasterGain:()=>Me,box2d:()=>m,box2dDebug:()=>Jr,box2dInit:()=>ad,box2dSetDebug:()=>rd,cameraAngle:()=>$,cameraFit:()=>rh,cameraPos:()=>Tt,cameraScale:()=>q,canvasClearColor:()=>Xe,canvasColorTiles:()=>As,canvasFixedSize:()=>Ln,canvasMaxAspect:()=>Pn,canvasMaxSize:()=>Rn,canvasMinAspect:()=>ti,canvasPixelRatio:()=>Ye,canvasPixelated:()=>or,ceil:()=>oi,clamp:()=>j,combineCanvases:()=>br,cos:()=>at,debug:()=>Dt,debugCircle:()=>jt,debugClear:()=>Ml,debugLine:()=>ge,debugOverlap:()=>co,debugOverlay:()=>Ee,debugPoint:()=>Qo,debugPointSize:()=>Da,debugPoly:()=>Il,debugRect:()=>gt,debugScreenshot:()=>Ma,debugShowErrors:()=>kl,debugText:()=>_n,debugVideoCaptureIsActive:()=>me,debugVideoCaptureStart:()=>ka,debugVideoCaptureStop:()=>Ga,debugWatermark:()=>Ts,distanceAngle:()=>zl,distanceWrap:()=>tr,drawCanvas2D:()=>Tn,drawCircle:()=>Qi,drawCircleGradient:()=>ih,drawContext:()=>St,drawCount:()=>ve,drawCrescent:()=>ud,drawEllipse:()=>ec,drawEllipseGradient:()=>nc,drawLine:()=>dn,drawLineList:()=>fo,drawNineSlice:()=>Ac,drawNineSliceScreen:()=>cd,drawPoly:()=>Fn,drawRect:()=>Ki,drawRectGradient:()=>th,drawRegularPoly:()=>tc,drawText:()=>sh,drawTextScreen:()=>$e,drawTextureWrapped:()=>eh,drawThreeSlice:()=>Cc,drawThreeSliceScreen:()=>ld,drawTile:()=>_t,enablePhysicsSolver:()=>Rs,engineAddPlugin:()=>Sn,engineImageFont:()=>rc,engineInit:()=>Pl,engineName:()=>Ji,engineObjects:()=>bt,engineObjectsCallback:()=>Ol,engineObjectsCollect:()=>Oa,engineObjectsCollide:()=>Ko,engineObjectsDestroy:()=>Ll,engineObjectsRaycast:()=>Dl,engineObjectsUpdate:()=>La,engineVersion:()=>Ui,fetchJSON:()=>Xl,floor:()=>xt,fontDefault:()=>Ti,formatTime:()=>ir,frame:()=>Ra,frameRate:()=>El,gamepadConnected:()=>yo,gamepadDirectionEmulateStick:()=>dr,gamepadDpad:()=>po,gamepadIsDown:()=>Ce,gamepadPrimary:()=>yt,gamepadStick:()=>ui,gamepadStickCount:()=>ac,gamepadVibrate:()=>Sh,gamepadVibrateStop:()=>wh,gamepadWasPressed:()=>Ar,gamepadWasReleased:()=>vh,gamepadsEnable:()=>Ps,getCameraSize:()=>sc,getCrescentPoints:()=>Ec,getNoteFrequency:()=>dc,getPaused:()=>_l,glAntialias:()=>Lr,glCanvas:()=>Z,glCircleSides:()=>Ai,glClearCanvas:()=>mc,glClearRect:()=>wc,glCompileShader:()=>wo,glContext:()=>y,glCopyToContext:()=>kr,glCreateProgram:()=>Jn,glCreateTexture:()=>Is,glDeleteTexture:()=>xc,glDraw:()=>bi,glDrawColoredPoints:()=>jr,glDrawOutlineTransform:()=>Fr,glDrawPoints:()=>Sc,glDrawPointsTransform:()=>Gr,glDrawUntextured:()=>vc,glEnable:()=>k,glFlush:()=>At,glSetAntialias:()=>Yh,glSetRenderTarget:()=>Zn,glSetTexture:()=>Ir,glSetTextureData:()=>Mr,glSetTextureWrap:()=>bc,gravity:()=>Bt,headlessMode:()=>B,hsl:()=>Re,hypot:()=>Fa,inputClear:()=>Li,inputClearKey:()=>wr,inputMouseMoveThreshold:()=>Sr,inputPreventDefault:()=>On,inputWASDEmulateDirection:()=>ei,isArray:()=>re,isColor:()=>z,isFullscreen:()=>oc,isIntersecting:()=>za,isNumber:()=>L,isOnScreen:()=>ah,isOverlapping:()=>Hi,isPowerOfTwo:()=>ri,isStringLike:()=>J,isTouchDevice:()=>Zt,isUsingGamepad:()=>In,isVector2:()=>O,keyDirection:()=>bh,keyIsDown:()=>Et,keyWasPressed:()=>Lt,keyWasReleased:()=>Tr,lastInputDevice:()=>qe,lerp:()=>Nt,lerpAngle:()=>Jl,lerpWrap:()=>Na,lightSystem:()=>W,lineTest:()=>Ua,log2:()=>ja,mainCanvas:()=>F,mainCanvasSize:()=>I,mainContext:()=>lt,max:()=>Y,medalDisplaySize:()=>ds,medalDisplaySlideTime:()=>Dn,medalDisplayTime:()=>hs,medals:()=>xi,medalsForEach:()=>Ms,medalsInit:()=>Zh,medalsPreventUnlock:()=>Br,medalsReset:()=>td,min:()=>Q,mod:()=>Qt,mouseDelta:()=>xr,mouseDeltaScreen:()=>fe,mouseInWindow:()=>ts,mouseIsDown:()=>ii,mousePos:()=>Ae,mousePosScreen:()=>Ft,mouseWasPressed:()=>li,mouseWasReleased:()=>xh,mouseWheel:()=>vr,nearestPowerOfTwo:()=>Ul,newgrounds:()=>vi,noise1D:()=>Zl,noise2D:()=>tu,objectDefaultAngleDamping:()=>lr,objectDefaultDamping:()=>cr,objectDefaultFriction:()=>hr,objectDefaultMass:()=>ar,objectDefaultRestitution:()=>ur,objectMaxSpeed:()=>Pe,oscillate:()=>Ja,particleEmitRateScale:()=>Xi,paused:()=>be,percent:()=>It,percentLerp:()=>Nl,playSamples:()=>Pr,pointerLockExit:()=>Ch,pointerLockIsActive:()=>cc,pointerLockRequest:()=>Ah,postProcess:()=>Pt,primitiveCount:()=>Se,rand:()=>ht,randBool:()=>Va,randColor:()=>lo,randInCircle:()=>Ha,randInt:()=>er,randSign:()=>Wa,randVec2:()=>qa,readSaveData:()=>Kl,rgb:()=>N,round:()=>Wi,saveCanvas:()=>Qa,saveDataURL:()=>ai,saveText:()=>Yl,screenToWorld:()=>Ri,screenToWorldDelta:()=>ic,screenToWorldTransform:()=>Pi,setAdditiveBlendMode:()=>ci,setCameraAngle:()=>nu,setCameraPos:()=>eu,setCameraScale:()=>iu,setCanvasClearColor:()=>ru,setCanvasColorTiles:()=>ou,setCanvasFixedSize:()=>uu,setCanvasMaxAspect:()=>lu,setCanvasMaxSize:()=>au,setCanvasMinAspect:()=>cu,setCanvasPixelRatio:()=>du,setCanvasPixelated:()=>Za,setCursor:()=>hh,setDebugKey:()=>Zu,setDebugWatermark:()=>Qu,setEnablePhysicsSolver:()=>Su,setFontDefault:()=>fu,setGLCircleSides:()=>mu,setGLEnable:()=>gu,setGamepadDirectionEmulateStick:()=>Ou,setGamepadsEnable:()=>Lu,setGravity:()=>Ru,setHeadlessMode:()=>yu,setInputMouseMoveThreshold:()=>ph,setInputPreventDefault:()=>fh,setInputWASDEmulateDirection:()=>Du,setMedalDisplaySize:()=>id,setMedalDisplaySlideTime:()=>nd,setMedalDisplayTime:()=>ed,setMedalsPreventUnlock:()=>sd,setObjectDefaultAngleDamping:()=>Au,setObjectDefaultDamping:()=>Tu,setObjectDefaultFriction:()=>Eu,setObjectDefaultMass:()=>wu,setObjectDefaultRestitution:()=>Cu,setObjectMaxSpeed:()=>_u,setParticleEmitRateScale:()=>Pu,setPaused:()=>Rl,setShowSplashScreen:()=>pu,setSoundDefaultRange:()=>$u,setSoundDefaultTaper:()=>Ku,setSoundEnable:()=>Xu,setSoundVolume:()=>Yu,setTileDefaultBleed:()=>vu,setTileDefaultPadding:()=>xu,setTileDefaultSize:()=>bu,setTilesPixelated:()=>hu,setTimeScale:()=>su,setTouchGamepadAlpha:()=>Vu,setTouchGamepadAnalog:()=>zu,setTouchGamepadButtonCount:()=>Fu,setTouchGamepadCenterButtonSize:()=>Gu,setTouchGamepadDisplayTime:()=>Wu,setTouchGamepadEnable:()=>Mu,setTouchGamepadFloating:()=>Ju,setTouchGamepadLeftButtonCount:()=>Bu,setTouchGamepadLeftStick:()=>ju,setTouchGamepadPassthrough:()=>ku,setTouchGamepadRightStick:()=>Nu,setTouchGamepadSize:()=>Uu,setTouchGamepadVibration:()=>qu,setTouchInputEnable:()=>Iu,setVibrateEnable:()=>Hu,shareURL:()=>$l,showSplashScreen:()=>rr,sign:()=>Kt,sin:()=>et,smoothStep:()=>qi,soundDefaultRange:()=>yr,soundDefaultTaper:()=>gr,soundEnable:()=>Jt,soundVolume:()=>gn,speak:()=>Nh,speakStop:()=>zh,tan:()=>Ba,textureInfos:()=>en,tile:()=>_i,tileCollisionGetData:()=>ss,tileCollisionLayers:()=>Ke,tileCollisionRaycast:()=>fc,tileCollisionTest:()=>Ve,tileDefaultBleed:()=>_s,tileDefaultPadding:()=>Es,tileDefaultSize:()=>Cs,tileLayersLoad:()=>Uh,tilesPixelated:()=>bn,time:()=>qt,timeDelta:()=>$o,timeReal:()=>Qe,timeScale:()=>sr,toggleFullscreen:()=>uh,touchGamepadAlpha:()=>pr,touchGamepadAnalog:()=>Ci,touchGamepadButtonCount:()=>Un,touchGamepadCenterButtonSize:()=>ae,touchGamepadDisplayTime:()=>ni,touchGamepadEnable:()=>tn,touchGamepadFloating:()=>nn,touchGamepadLeftButtonCount:()=>Vn,touchGamepadLeftStick:()=>wn,touchGamepadPassthrough:()=>fr,touchGamepadRightStick:()=>Wn,touchGamepadSize:()=>zt,touchGamepadVibration:()=>Yi,touchInputEnable:()=>hn,tweenProperty:()=>hd,tweenStopAll:()=>dd,tweenUpdate:()=>Pc,uiDebug:()=>zr,uiSetDebug:()=>od,uiSystem:()=>C,usingGamepadInput:()=>mh,usingKeyboardInput:()=>gh,usingMouseInput:()=>yh,vec2:()=>x,vibrate:()=>Cr,vibrateEnable:()=>Ei,vibrateStop:()=>Th,workCanvas:()=>De,workContext:()=>We,workReadCanvas:()=>ye,workReadContext:()=>Le,worldToScreen:()=>An,worldToScreenDelta:()=>oh,writeSaveData:()=>Ql,zzfx:()=>Jh,zzfxG:()=>Os,zzfxM:()=>Tc});function _l(){return be}function Rl(n=!0){be=n}function Sn(n,t,e,i){p(!fn.find(o=>o.update===n&&o.render===t&&o.glContextLost===e&&o.glContextRestored===i));let s=new ro(n,t,e,i);fn.push(s)}async function Pl(n,t,e,i,s,o=[],r){if(Pa&&console.log(`${Ji} Engine v${Ui}`),p(!lt,"engine already initialized"),lt)return;p(re(o),"pass in images as array"),document.body||document.documentElement.appendChild(document.createElement("body")),r||(r=document.body),n||(n=()=>{}),t||(t=()=>{}),e||(e=()=>{}),i||(i=()=>{}),s||(s=()=>{});function a(){I=x(F.width,F.height),lt.imageSmoothingEnabled=!bn,So()}function c(g=0){let b=g-io;io||(b=0),io=g,(Dt||Ts)&&(Vi=Nt(Vi,1e3/(b||1),.05));let v=Dt&&Et("Equal"),w=Dt&&Et("Minus"),_=v?10:w?.1:1;Qe+=b*_/1e3;let S=sr*_;b*=S,de+=be?0:b,S<=1&&(de=Q(de,50));let E=!1;if(be){E=!0,l(),wa(),fn.forEach(T=>{var P;return(P=T.update)==null?void 0:P.call(T)});for(let T of bt)T.parent||T.updateTransforms();ba(),e(),Ta(),me()&&A()}else{let T=0;for(de<0&&de>-9&&(T=de,de=0);de>=0;de-=1e3/60)qt=Ra++/60,E=!0,l(),wa(),t(),fn.forEach(P=>{var M;return(M=P.update)==null?void 0:M.call(P)}),La(),ba(),e(),Ta(),me()&&A();de+=T}me()||A(),requestAnimationFrame(c);function A(){if(!B){E||l(),a(),i(),bt.sort((T,P)=>T.renderOrder-P.renderOrder);for(let T of bt)T.destroyed||T.render();s(),fn.forEach(T=>{var P;return(P=T.render)==null?void 0:P.call(T)}),_h(),Fl(),At(),jl(),ve=0,Se=0}}}function l(){if(!B){if(Ln.x){I=Ln.copy();let g=innerWidth/innerHeight,b=Ln.x/Ln.y,v=gPn){let E=I.y*Pn|0;I.x=Q(E,Rn.x)}else if(w0&&!k&&(lt.fillStyle=Xe.toString(),lt.fillRect(0,0,I.x,I.y),lt.fillStyle=it.toString()),lt.lineJoin="round",lt.lineCap="round"}}if(B)return d();qh(r);let u="margin:0;overflow:hidden;background:#000;user-select:none;-webkit-user-select:none;touch-action:none;-webkit-touch-callout:none";r.style.cssText=u,F=r.appendChild(document.createElement("canvas")),St=lt=F.getContext("2d"),Eh(),Bh(),Gl();let h="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)";F.style.cssText=h,Z&&(Z.style.cssText=h),Za(or),l(),So(),De=new OffscreenCanvas(64,64),We=De.getContext("2d"),ye=new OffscreenCanvas(64,64),Le=ye.getContext("2d",{willReadFrequently:!0});let f=o.map((g,b)=>va(b,g));return o.length||f.push(va(0)),f.push(dh()),rr&&f.push(new Promise(g=>{let b=0;v();function v(){Li(),Qh(b+=.01),b>1?g():setTimeout(v,16)}})),await Promise.all(f),d();async function d(){await n(),c()}}function La(){Ko=bt.filter(t=>t.collideSolidObjects);function n(t){if(!t.destroyed){t.update();for(let e of t.children)n(e)}}for(let t of bt)if(!(t.parent||t.destroyed)){t.update(),t.updatePhysics();for(let e of t.children)n(e);t.updateTransforms()}bt=bt.filter(t=>!t.destroyed)}function Ll(n=!0){for(let t of bt)t.parent||t.destroy(n);bt=bt.filter(t=>!t.destroyed)}function Oa(n,t,e=bt){let i=[];if(n)if(t instanceof ot)for(let s of e)s.isOverlapping(n,t)&&i.push(s);else{let s=t*t;for(let o of e)n.distanceSquared(o.pos)e(s))}function Dl(n,t,e=bt){let i=[];for(let s of e)s.collideRaycast&&za(n,t,s.pos,s.size)&&(oe&>(s.pos,s.size,"#f00"),i.push(s));return oe&&ge(n,t,i.length?"#f00":"#00f",.02),i}function p(n,...t){if(!n)throw console.assert(n,...t),new Error("Assert failed!")}function mt(...n){console.log(...n)}function gt(n,t=x(),e=U,i=0,s=0,o=!1,r=!1){p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(J(e)||z(e),"color is invalid"),p(L(i),"time must be a number"),p(L(s),"angle must be a number"),z(e)&&(e=e.toString());let a=new xe(i);He.push({pos:n.copy(),size:t.copy(),color:e,timer:a,angle:s,fill:o,screenSpace:r})}function Il(n,t,e=U,i=0,s=0,o=!1,r=!1){p(O(n),"pos must be a vec2"),p(re(t),"points must be an array"),p(J(e)||z(e),"color is invalid"),p(L(i),"time must be a number"),p(L(s),"angle must be a number"),z(e)&&(e=e.toString()),n=n.copy(),t=t.map(c=>c.copy());let a=new xe(i);He.push({pos:n,points:t,color:e,timer:a,angle:s,fill:o,screenSpace:r})}function jt(n,t=0,e=U,i=0,s=!1,o=!1){p(O(n),"pos must be a vec2"),p(L(t),"size must be a number"),p(J(e)||z(e),"color is invalid"),p(L(i),"time must be a number"),z(e)&&(e=e.toString()),n=n.copy();let r=new xe(i);He.push({pos:n,size:t,color:e,timer:r,angle:0,fill:s,screenSpace:o})}function Qo(n,t,e,i,s=!1){gt(n,void 0,t,e,i,!1,s)}function ge(n,t,e,i=.1,s=0,o=!1){p(O(n),"posA must be a vec2"),p(O(t),"posB must be a vec2"),p(L(i),"width must be a number");let r=x((t.x-n.x)/2,(t.y-n.y)/2),a=x(i,r.length()*2);gt(n.add(r),a,e,s,r.angle(),!0,o)}function co(n,t,e,i,s,o,r=!1){p(O(n),"posA must be a vec2"),p(O(e),"posB must be a vec2"),p(O(t),"sizeA must be a vec2"),p(O(i),"sizeB must be a vec2");let a=x(Q(n.x-t.x/2,e.x-i.x/2),Q(n.y-t.y/2,e.y-i.y/2)),c=x(Y(n.x+t.x/2,e.x+i.x/2),Y(n.y+t.y/2,e.y+i.y/2));gt(a.lerp(c,.5),c.subtract(a),s,o,0,!1,r)}function _n(n,t,e=1,i=U,s=0,o=0,r="monospace",a=!1){p(J(n),"text must be a string"),p(O(t),"pos must be a vec2"),p(L(e),"size must be a number"),p(J(i)||z(i),"color is invalid"),p(L(s),"time must be a number"),p(L(o),"angle must be a number"),p(J(r),"font must be a string"),z(i)&&(i=i.toString()),t=t.copy();let c=new xe(s);He.push({text:n,pos:t,size:e,color:i,timer:c,angle:o,font:r,screenSpace:a})}function Ml(){He=[]}function Ma(){ao=1}function kl(){let n=e=>{document.body.style="background-color:#111;margin:8px",document.body.innerHTML="
"+e},t=console.assert;console.assert=(e,...i)=>{if(t(e,...i),!e){let s=i.join(" "),o=new Error().stack;throw`Assertion failed!
 `+s+`
 `+o}},onunhandledrejection=e=>n(e.reason.stack||e.reason),onerror=(e,i,s,o)=>n(`${e}
 ${i}
-Ln ${s}, Col ${o}`)}function Gl(){Da&&console.warn("LittleJS DEBUG build loaded. Use the release build for production.")}function Sa(){Dt&&(Lt(Ga)&&(Ie=!Ie),Ie&&(Lt("Digit1")&&(ae=!ae,xn=!1),Lt("Digit2")&&(xn=!xn,ae=!1),Lt("Digit3")&&(vn=!vn),Lt("Digit4")&&(ce=!ce),Lt("Digit5")&&Fa(),Lt("Digit7")&&(Jn=!Jn)),Se()?(!Ie||Lt("Digit6"))&&Na():Ie&&Lt("Digit6")&&ja())}function Fl(){if(Se())return;Ct();let n=Ae,t=Ce;ho&&(wr(),ec(j),ho=0);let e=at;if(vn&&Ms){let o=0;for(let r=0;r<8;r++)xo(r)&&o++;for(let r=0;r<8;r++){if(!xo(r))continue;let a=1,c=.2,l=At.add(b(-a*2,((o-1)/2-r)*a*3));In(r,l.add(b(-a,a)),1),r===pt&&In("Main",l.add(b(-a*2,0)),1,"#0f0");let u=be[r].length;for(let f=0;f{e.save();let o=s.pos,r=1,a=s.angle;if(s.screenSpace||(o=Pn(s.pos),r=q,a-=$),e.translate(o.x|0,o.y|0),e.rotate(a),e.scale(1,s.text?1:-1),e.fillStyle=s.color,e.strokeStyle=s.color,s.text!==void 0)e.font=s.size*r+"px "+s.font,e.textAlign="center",e.textBaseline="middle",e.fillText(s.text,0,0);else if(s.points!==void 0){e.beginPath();for(let c of s.points){let l=c.scale(r).floor();e.lineTo(l.x,l.y)}e.closePath(),s.fill&&e.fill(),e.stroke()}else if(s.size===0||s.size.x===0&&s.size.y===0){let c=ka*r;e.fillRect(-c/2,-1,c,3),e.fillRect(-1,-c/2,3,c)}else if(s.size.x!==void 0){let c=s.size.scale(r).floor(),l=c.x,u=c.y;s.fill&&e.fillRect(-l/2|0,-u/2|0,l,u),e.strokeRect(-l/2|0,-u/2|0,l,u)}else e.beginPath(),e.arc(0,0,s.size*r/2,0,9),s.fill&&e.fill(),e.stroke();e.restore()}),Qe=Qe.filter(s=>s.timer<0),i){let s=gc(i.pos,Oe);s&&ns(s.floor().add(b(.5)),b(1),z(0,1,1,.3),0,!1),mn(Oe,i.pos,.1,s?z(1,0,0,.5):z(0,1,0,.5),void 0,void 0,!1);let o="mouse pos = "+Oe;nn.length&&(o+=`
-mouse collision = `+ls(Oe)),o+=`
+Ln ${s}, Col ${o}`)}function Gl(){Pa&&console.warn("LittleJS DEBUG build loaded. Use the release build for production.")}function ba(){Dt&&(Lt(Ia)&&(Ee=!Ee),Ee&&(Lt("Digit1")&&(se=!se,pn=!1),Lt("Digit2")&&(pn=!pn,se=!1),Lt("Digit3")&&(yn=!yn),Lt("Digit4")&&(oe=!oe),Lt("Digit5")&&Ma(),Lt("Digit7")&&(Gn=!Gn)),me()?(!Ee||Lt("Digit6"))&&Ga():Ee&&Lt("Digit6")&&ka())}function Fl(){if(me())return;At();let n=ve,t=Se;ao&&(br(),Qa(F),ao=0);let e=lt;if(yn&&Ps){let o=0;for(let r=0;r<8;r++)yo(r)&&o++;for(let r=0;r<8;r++){if(!yo(r))continue;let a=1,c=.2,l=Tt.add(x(-a*2,((o-1)/2-r)*a*3));_n(r,l.add(x(-a,a)),1),r===yt&&_n("Main",l.add(x(-a*2,0)),1,"#0f0");let u=pe[r].length;for(let f=0;f{e.save();let o=s.pos,r=1,a=s.angle;if(s.screenSpace||(o=An(s.pos),r=q,a-=$),e.translate(o.x|0,o.y|0),e.rotate(a),e.scale(1,s.text?1:-1),e.fillStyle=s.color,e.strokeStyle=s.color,s.text!==void 0)e.font=s.size*r+"px "+s.font,e.textAlign="center",e.textBaseline="middle",e.fillText(s.text,0,0);else if(s.points!==void 0){e.beginPath();for(let c of s.points){let l=c.scale(r).floor();e.lineTo(l.x,l.y)}e.closePath(),s.fill&&e.fill(),e.stroke()}else if(s.size===0||s.size.x===0&&s.size.y===0){let c=Da*r;e.fillRect(-c/2,-1,c,3),e.fillRect(-1,-c/2,3,c)}else if(s.size.x!==void 0){let c=s.size.scale(r).floor(),l=c.x,u=c.y;s.fill&&e.fillRect(-l/2|0,-u/2|0,l,u),e.strokeRect(-l/2|0,-u/2|0,l,u)}else e.beginPath(),e.arc(0,0,s.size*r/2,0,9),s.fill&&e.fill(),e.stroke();e.restore()}),He=He.filter(s=>s.timer<0),i){let s=fc(i.pos,Ae);s&&Ki(s.floor().add(x(.5)),x(1),N(0,1,1,.3),0,!1),dn(Ae,i.pos,.1,s?N(1,0,0,.5):N(0,1,0,.5),void 0,void 0,!1);let o="mouse pos = "+Ae;Ke.length&&(o+=`
+mouse collision = `+ss(Ae)),o+=`
 
 --- object info ---
-`,o+=i.toString(),en(o,Ft,24,z(),.05,void 0,"center","monospace")}{e.save(),e.fillStyle="#fff",e.textAlign="left",e.textBaseline="top",e.font="20px monospace",e.shadowColor="#000",e.shadowBlur=9;let r=9,a=0,c=24;if(Ie){e.fillText(`${Hi} v${Xi}`,r,a+=c/2),e.fillText("Time: "+ar(Ht),r,a+=c),e.fillText("FPS: "+Yi.toFixed(1)+(F?" WebGL":" Canvas2D"),r,a+=c),e.fillText("Objects: "+mt.length,r,a+=c),e.fillText("Draw Calls: "+Ae,r,a+=c),e.fillText("Primitives: "+Ce,r,a+=c),e.fillText("---------",r,a+=c),e.fillStyle="#f00",e.fillText("ESC: Debug Overlay",r,a+=c),e.fillStyle=ae?"#f00":"#fff",e.fillText("1: Debug Physics",r,a+=c),e.fillStyle=xn?"#f00":"#fff",e.fillText("2: Debug Particles",r,a+=c),e.fillStyle=vn?"#f00":"#fff",e.fillText("3: Debug Gamepads",r,a+=c),e.fillStyle=ce?"#f00":"#fff",e.fillText("4: Debug Raycasts",r,a+=c),e.fillStyle="#fff",e.fillText("5: Save Screenshot",r,a+=c),e.fillText("6: Toggle Video Capture",r,a+=c),e.fillStyle=Jn?"#f00":"#fff",e.fillText("7: Debug Sound",r,a+=c);let l="",u="";for(let h in X[0])Et(h,0)&&(parseInt(h)<3?u+=h+" ":l+=h+" ");u&&e.fillText("Mouse: "+u,r,a+=c),l&&e.fillText("Keys: "+l,r,a+=c);for(let h=1;hi.push(a.data),s.onstop=()=>{let a=new Blob(i,{type:"video/webm"}),c=URL.createObjectURL(a);fi(c,"capture.webm",1e3)};let o,r;if(Jt){r=new ConstantSourceNode(ut,{offset:0}),r.connect(ze),r.start(),o=ut.createMediaStreamDestination(),ze.connect(o);for(let a of o.stream.getAudioTracks())n.addTrack(a)}try{s.start()}catch{gt("Video capture not supported in this browser!"),r==null||r.stop();return}gt("Video capture started."),Me={mediaRecorder:s,captureTimer:e,videoTrack:t,silentAudioSource:r,audioStreamDestination:o}}function Na(){var n,t,e;p(Se(),"Not capturing video!"),gt(`Video capture ended. ${Me.captureTimer.get().toFixed(2)} seconds recorded.`),re.style.display="none",(n=Me.silentAudioSource)==null||n.stop(),(t=Me.mediaRecorder)==null||t.stop(),(e=Me.videoTrack)==null||e.stop(),Me=void 0}function Nl(){p(Se(),"Not capturing video!"),wr(),Me.videoTrack.requestFrame(),re.textContent="\u25CF REC "+ar(Me.captureTimer)}function Yt(n){if(Dt){let t=Object.keys(n),e={};t.forEach(i=>e[i]=n[i]),t.forEach(i=>{Object.defineProperty(n,i,{get:()=>e[i],set:s=>{p(!1,`Cannot modify engine constant. Attempted to set constant (${n}) property '${i}' to '${s}'.`)},enumerable:!0})})}return Object.freeze(n)}function Zt(n,t=1){return(n%t+t)%t}function N(n,t=0,e=1){return ne?e:n}function It(n,t,e){return(e-=t)?N((n-t)/e):0}function Bt(n,t,e){return n+N(e)*(t-n)}function Bl(n,t,e,i,s){return Bt(i,s,It(n,t,e))}function sr(n,t,e=1){p(e>0,"distanceWrap wrapSize must be > 0");let i=(n-t)%e;return i*2%e-i}function Ua(n,t,e,i=1){return n+N(e)*sr(t,n,i)}function zl(n,t){return sr(n,t,2*H)}function Jl(n,t,e){return Ua(n,t,e,2*H)}function Ki(n){return n*n*(3-2*n)}function di(n){return!(n&n-1)}function Ul(n){return 2**hi(za(n))}function Qi(n,t,e,i=b()){let s=(n.x-e.x)*2,o=(n.y-e.y)*2,r=t.x+i.x,a=t.y+i.y;return tt(s)f)return!1;h=Y(y,h)}else{if(y0?a.x+1:a.x,x=h>0?a.y+1:a.y,v=c?(y-n.x)/c:1/0,w=l?(x-n.y)/l:1/0,_=0,S=v,E=w,A=fa.x&&(T.x=a.x+1-P),G.ya.y&&(T.y=a.y+1-P),i&&(A?i.set(-u,0):i.set(0,-h)),T}(A=SURL.revokeObjectURL(n),e)}function $l(n,t,e){var i;p(U(n),"shareURL requires title string"),p(U(t),"shareURL requires url string"),(i=navigator.share)==null||i.call(navigator,{title:n,url:t}).then(()=>e==null?void 0:e())}function Kl(n,t){p(U(n),"loadData requires saveName string");let e={};try{let i=localStorage[n];if(i)try{e=JSON.parse(i)}catch{gt("readSaveData: corrupt JSON for",n,"\u2014 using defaults")}}catch{gt("readSaveData: localStorage unavailable \u2014 using defaults")}return{...t,...e}}function Ql(n,t){p(U(n),"saveData requires saveName string");try{localStorage[n]=JSON.stringify(t)}catch{gt("writeSaveData: failed to write",n)}}function go(n){let t=(n|0)^2654435769;return t=Math.imul(t^t>>>16,2246822507),t=Math.imul(t^t>>>13,3266489909),t^=t>>>16,(t>>>0)/2**32}function Zl(n){let t=vt(n);return Bt(go(t),go(t+1),Ki(n-t))}function tu(n,t){let e=vt(n),i=vt(t),s=Ki(n-e),o=Ki(t-i),r=(a,c)=>go(a+c*374761393);return Bt(Bt(r(e,i),r(e+1,i),s),Bt(r(e,i+1),r(e+1,i+1),s),o)}function eu(n){At=n.copy()}function nu(n){$=n}function iu(n){q=n}function su(n){cr=n}function ou(n){Ps=n}function ru(n){Ze=n.copy()}function au(n){Mn=n.copy()}function cu(n){ri=n}function lu(n){kn=n}function uu(n){Gn=n.copy()}function nc(n){lr=n,j&&(j.style.imageRendering=n?"pixelated":""),Z&&(Z.style.imageRendering=n?"pixelated":"")}function hu(n){Tn=n}function du(n){tn=n}function fu(n){Pi=n}function pu(n){ur=n}function yu(n){B=n}function gu(n){if(n&&!Ao){console.warn("Can not enable WebGL if it was disabled on start.");return}F=n,Z&&(Z.style.display=n?"":"none")}function mu(n){Li=n}function bu(n){Ls=n.copy()}function xu(n){Os=n}function vu(n){Ds=n}function Su(n){Is=n}function wu(n){hr=n}function Tu(n){dr=n}function Au(n){fr=n}function Cu(n){pr=n}function _u(n){yr=n}function Eu(n){Ge=n}function Ru(n){Nt=n.copy()}function Pu(n){Zi=n}function Lu(n){Ms=n}function Ou(n){gr=n}function Du(n){ai=n}function Iu(n){gn=n}function Mu(n){rn=n}function ku(n){mr=n}function Gu(n){ue=n}function Fu(n){Yn=n,n>0&&(Kn=!1)}function ju(n){En=n,n&&($n=0)}function Nu(n){$n=n,n>0&&(En=!1)}function Bu(n){Kn=n,n&&(Yn=0)}function zu(n){Oi=n}function Ju(n){cn=n}function Uu(n){zt=n}function Vu(n){br=n}function Wu(n){ci=n}function qu(n){ts=n}function Hu(n){Di=n}function Xu(n){Jt=n}function Yu(n){Sn=n,Jt&&!B&&ze&&(ze.gain.value=n)}function $u(n){xr=n}function Ku(n){vr=n}function Qu(n){Rs=n}function Zu(n){Ga=n}function es(n){return n.r>=1&&n.g>=1&&n.b>=1}function Sr(n){return n.r<=0&&n.g<=0&&n.b<=0&&n.a<=0}function Ii(n=0,t=Ls,e=0,i=Os,s=Ds){if(p(O(n)||typeof n=="number","index must be a vec2 or number"),p(O(t)||typeof t=="number","size must be a vec2 or number"),p(L(e)||e instanceof Ue,"texture must be a number or TextureInfo"),p(L(i),"padding must be a number"),B)return new _e;typeof t=="number"&&(p(t>0),t=new st(t,t));let o=typeof e=="number"?an[e]:e;p(o instanceof Ue,"tile texture is not loaded"),p(o.size.x>0,"tile texture is not loaded");let r=t.x+i*2,a=t.y+i*2,c,l;if(typeof n=="number"){let h=o.size.x/r|0;c=n%h,l=n/h|0}else c=n.x,l=n.y;let u=new st(c*r+i,l*a+i);return new _e(u,t,o,i,s)}function Rt(n,t=b(1),e,i=V,s=0,o,r,a=F,c=!1,l){var f;p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(J(i),"color is invalid"),p(L(s),"angle must be a number"),p(!r||J(r),"additiveColor must be a color"),p(!l||!a,"context only supported in canvas 2D mode");let u=e==null?void 0:e.textureInfo,h=(f=e==null?void 0:e.bleed)!=null?f:0;if(a&&F)if(p(!!g,"WebGL is not enabled!"),c&&([n,t,s]=ki(n,t,s)),u){let d=u.sizeInverse,y=e.pos.x*d.x,x=e.pos.y*d.y,v=e.size.x*d.x,w=e.size.y*d.y;if(Fr(u.glTexture),h){let _=d.x*h,S=d.y*h;Ai(n.x,n.y,o?-t.x:t.x,t.y,s,y+_,x+S,y-_+v,x-S+w,i.rgbaInt(),r&&r.rgbaInt())}else Ai(n.x,n.y,o?-t.x:t.x,t.y,s,y,x,y+v,x+w,i.rgbaInt(),r&&r.rgbaInt())}else{let d=r?i.add(r):i;Tc(n.x,n.y,t.x,t.y,s,d.rgbaInt())}else++Ae,++Ce,Rn(n,t,s,o,d=>{if(u){d.scale(1,-1);let y=e.pos.x,x=e.pos.y,v=e.size.x,w=e.size.y;lh(d,u.image,y,x,v,w,-.5,-.5,1,1,i,r,h)}else{let y=r?i.add(r):i;d.fillStyle=y.toString(),d.fillRect(-.5,-.5,1,1)}},c,l)}function ns(n,t,e,i,s,o,r){Rt(n,t,void 0,e,i,!1,void 0,s,o,r)}function th(n,t,e=V,i=on,s=0,o=F,r=!1,a){if(p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(J(e)&&J(i),"color is invalid"),p(L(s),"angle must be a number"),p(!a||!o,"context only supported in canvas 2D mode"),o&&F){p(!!g,"WebGL is not enabled!"),r&&(n=Mi(n),t=t.scale(1/q),s+=$);let c=[],l=[],u=t.x/2,h=t.y/2,f=e.rgbaInt(),d=i.rgbaInt(),y=ot(-s),x=et(-s);for(let v=4;v--;){let w=v&1?u:-u,_=v&2?h:-h,S=w*y-_*x,E=w*x+_*y,A=v&2?f:d;c.push(b(n.x+S,n.y+E)),l.push(A)}Jr(c,l)}else++Ae,++Ce,Rn(n,t,s,!1,c=>{let l=c.createLinearGradient(0,.5,0,-.5);l.addColorStop(0,e.toString()),l.addColorStop(1,i.toString()),c.fillStyle=l,c.fillRect(-.5,-.5,1,1)},r,a)}function eh(n,t,e,i=0,s=V,o=0,r,a=F,c=!1,l){if(p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(O(e),"wrapCount must be a vec2"),p(J(s),"color is invalid"),p(L(o),"angle must be a number"),p(!r||J(r),"additiveColor must be a color"),p(!l||!a,"context only supported in canvas 2D mode"),p(!(i instanceof _e),"pass a TextureInfo or texture index, not a TileInfo \u2014 use tileInfo.textureInfo"),B)return;let u=typeof i=="number"?an[i]:i;if(p(u instanceof Ue,"texture not loaded"),p(u.size.x>0,"texture not loaded"),p(u.wrap,"drawTextureWrapped requires a wrap-enabled texture; call textureInfo.setWrap(true) first"),a&&F){p(!!g,"WebGL is not enabled!"),c&&([n,t,o]=ki(n,t,o)),Fr(u.glTexture),Ai(n.x,n.y,t.x,t.y,o,0,0,e.x,e.y,s.rgbaInt(),r&&r.rgbaInt());return}++Ae,++Ce,c||(n=Pn(n),t=t.scale(q),o-=$);let h=!Ps||(r?es(s.add(r))&&r.a<=0:es(s)),f=!h&&r&&!Sr(r),d=h?u.image:ch(u.image,s,r);l=l||wt,l.save(),l.translate(n.x+.5,n.y+.5),l.rotate(o),l.globalAlpha=f?1:s.a;let y=l.createPattern(d,"repeat"),x=new DOMMatrix().translate(-t.x/2,-t.y/2).scale(t.x/(e.x*d.width),t.y/(e.y*d.height));y.setTransform(x),l.fillStyle=y,l.fillRect(-t.x/2,-t.y/2,t.x,t.y),l.globalAlpha=1,l.restore()}function mo(n,t=.1,e=V,i=!1,s=b(),o=0,r=F,a=!1,c){if(p(le(n),"points must be an array"),p(L(t),"width must be a number"),p(J(e),"color is invalid"),p(O(s),"pos must be a vec2"),p(L(o),"angle must be a number"),p(!c||!r,"context only supported in canvas 2D mode"),r&&F){p(!!g,"WebGL is not enabled!");let l=b(1);a&&([s,l,o]=ki(s,l,o)),zr(n,e.rgbaInt(),t,s.x,s.y,l.x,l.y,o,i)}else++Ae,++Ce,Rn(s,b(1),o,!1,l=>{l.strokeStyle=e.toString(),l.lineWidth=t,l.beginPath();for(let u=0;u0&&zr(n,i.rgbaInt(),e,s.x,s.y,l.x,l.y,o)}else Rn(s,b(1),o,!1,l=>{l.fillStyle=t.toString(),l.beginPath();for(let u of n)l.lineTo(u.x,u.y);l.closePath(),l.fill(),e&&(l.strokeStyle=i.toString(),l.lineWidth=e,l.stroke())},a,c)}function sc(n,t=b(1),e=V,i=0,s=0,o=it,r=F,a=!1,c){p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(J(e)&&J(o),"color is invalid"),p(L(i),"angle must be a number"),p(L(s),"lineWidth must be a number"),p(s>=0,"lineWidth must be a positive value or 0"),p(!c||!r,"context only supported in canvas 2D mode"),s=N(s,0,K(t.x,t.y)),r&&F?ic(n,t,Li,e,s,o,i,r,a,c):Rn(n,b(1),i,!1,l=>{l.fillStyle=e.toString(),l.beginPath(),l.ellipse(0,0,t.x/2,t.y/2,0,0,9),l.fill(),s&&(l.strokeStyle=o.toString(),l.lineWidth=s,l.stroke())},a,c)}function is(n,t=1,e=V,i=0,s=it,o=F,r=!1,a){p(L(t),"size must be a number"),sc(n,b(t),e,0,i,s,o,r,a)}function oc(n,t=b(1),e=V,i=on,s=0,o=F,r=!1,a){if(p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(J(e)&&J(i),"color is invalid"),p(L(s),"angle must be a number"),p(!a||!o,"context only supported in canvas 2D mode"),!B)if(o&&F){p(!!g,"WebGL is not enabled!"),r&&(n=Mi(n),t=t.scale(1/q),s+=$);let c=Li,l=t.x/2,u=t.y/2,h=e.rgbaInt(),f=i.rgbaInt(),d=nh++,y=ot(-s),x=et(-s),v=E=>{let A=et(E)*l,T=ot(E)*u;return b(n.x+A*y-T*x,n.y+A*x+T*y)},w=d%c/c*H*2,_=[v(w)],S=[f];for(let E=c;E--;){let A=(E+d)%c/c*H*2;_.push(n),S.push(h),_.push(v(A)),S.push(f)}Jr(_,S)}else++Ae,++Ce,Rn(n,t,s,!1,c=>{let l=c.createRadialGradient(0,0,0,0,0,.5);l.addColorStop(0,e.toString()),l.addColorStop(1,i.toString()),c.fillStyle=l,c.beginPath(),c.ellipse(0,0,.5,.5,0,0,9),c.fill()},r,a)}function ih(n,t=1,e=V,i=on,s=F,o=!1,r){p(L(t),"size must be a number"),oc(n,b(t),e,i,0,s,o,r)}function Rn(n,t,e=0,i=!1,s,o=!1,r=wt){p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(L(e),"angle must be a number"),p(typeof s=="function","drawFunction must be a function"),o||(n=Pn(n),t=t.scale(q),e-=$),r.save(),r.translate(n.x+.5,n.y+.5),r.rotate(e),r.scale(i?-t.x:t.x,-t.y),s(r),r.restore()}function sh(n,t,e=1,i=V,s=0,o=it,r="center",a=Pi,c="",l,u=0,h=wt){t=Pn(t),e*=q,s*=q,u-=$,u*=-1,en(n,t,e,i,s,o,r,a,c,l,u,h)}function en(n,t,e,i=V,s=0,o=it,r="center",a=Pi,c="",l,u=0,h=wt){p(U(n),"text must be a string"),p(O(t),"pos must be a vec2"),p(L(e),"size must be a number"),p(J(i),"color must be a color"),p(L(s),"lineWidth must be a number"),p(J(o),"lineColor must be a color"),p(["left","center","right"].includes(r),"align must be left, center, or right"),p(U(a),"font must be a string"),p(U(c),"fontStyle must be a string"),p(L(u),"angle must be a number");let f=(n+"").split(`
-`),d=t.y-(f.length-1)*e/2;h.save(),h.fillStyle=i.toString(),h.strokeStyle=o.toString(),h.lineWidth=s,h.textAlign=r,h.font=c+" "+e+"px "+a,h.textBaseline="middle",h.translate(t.x,d),h.rotate(-u);let y=0;f.forEach(x=>{s&&h.strokeText(x,0,y,l),h.fillText(x,0,y,l),y+=e}),h.restore()}async function Ta(n,t){p(L(n),"textureIndex must be a number"),p(!an[n],"textureIndex is already loaded!"),p(!t||U(t),"image src must be a string");let e=new Image;t&&await new Promise(i=>{e.onerror=e.onload=i,e.crossOrigin="anonymous",e.src=t}),an[n]=new Ue(e)}function Mi(n){p(O(n),"screenPos must be a vec2");let t=(n.x-k.x/2+.5)/q,e=(n.y-k.y/2+.5)/-q;if($){let i=ot(-$),s=et(-$),o=t*i-e*s,r=t*s+e*i;t=o,e=r}return new st(t+At.x,e+At.y)}function Pn(n){p(O(n),"worldPos must be a vec2");let t=n.x-At.x,e=n.y-At.y;if($){let i=ot($),s=et($),o=t*i-e*s,r=t*s+e*i;t=o,e=r}return new st(t*q+k.x/2-.5,e*-q+k.y/2-.5)}function rc(n){p(O(n),"screenDelta must be a vec2");let t=n.x/q,e=n.y/-q;if($){let i=ot(-$),s=et(-$),o=t*i-e*s,r=t*s+e*i;t=o,e=r}return new st(t,e)}function oh(n){p(O(n),"worldDelta must be a vec2");let t=n.x,e=n.y;if($){let i=ot($),s=et($),o=t*i-e*s,r=t*s+e*i;t=o,e=r}return new st(t*q,e*-q)}function ki(n,t,e=0){return p(O(n),"screenPos must be a vec2"),p(O(t),"screenSize must be a vec2"),p(L(e),"screenAngle must be a number"),[Mi(n),t.scale(1/q),e+$]}function ac(){return k.scale(1/q)}function rh(n,t,e,i){p(O(n),"center must be a vec2"),p(O(t),"size must be a vec2");let s=f(e),o=f(i),r=t.x+s.left+s.right,a=t.y+s.top+s.bottom,c=k.x-o.left-o.right,l=k.y-o.top-o.bottom;if(!(r>0&&a>0&&c>0&&l>0))return q;q=K(c/r,l/a);let u=b(s.right-s.left,s.top-s.bottom).scale(.5),h=b(o.right-o.left,o.top-o.bottom).scale(.5/q);return At=n.add(u).add(h),q;function f(d){return(d===void 0||L(d))&&(d=b(d)),O(d)?{top:d.y,right:d.x,bottom:d.y,left:d.x}:{top:d.top||0,right:d.right||0,bottom:d.bottom||0,left:d.left||0}}}function ah(n,t=0){if(p(O(n),"pos must be a vec2"),p(O(t)||L(t),"size must be a vec2 or number"),!q)return!1;let e=n.x-At.x,i=n.y-At.y;if($){let r=ot($),a=et($),c=e*r-i*a,l=e*a+i*r;e=c,i=l}e*=q*2,i*=-q*2,t instanceof st&&(t=t.length()),t*=q;let s=k.x,o=k.y;return e+t>-s&&e-t-o&&i-t{n.onerror=n.onload=a,n.crossOrigin="anonymous",n.src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUAAAAAeAQMAAABnrVXaAAAABlBMVEUAAAD///+l2Z/dAAAAAXRSTlMAQObYZgAAAjpJREFUOMu9kzFu2zAUhn+CAROgqrk+B2l0BWYxMjlXeYaAtFtbdA1sGgHqRQfI0CNkSG5AwYB0BQ8d5Bsomwah6CPVeGg6tEPzAxLwyI+P78cP4u9lNO9OoMKnLMOobG5020/yaj/MrRcCGh1gBbyiLTPJEYaIiom5KM9Jq7KgynMGtb6L4GL4MF2H4LQKCXTvDVw2I4MsgZT7QLExdiutH+D08VOP3INXRrWX1/mmpbkNgAPYRVANb4xpcegYvhiNbIXauQICEjBuYLfMakaakWQeXxiZ0VDtuJCKs3ztMV59QtsHJNcRxDzfdL21ty3PrfIcXTN+E+GFAv6T5nbT9jd50/WFxb5ksdAv49qS6ouymG66ji08UMT6moykYLAo+V0j23GN4m829ZySAD5K7QsBfQTvOG8eE+gTeGYRAmnNAubN3hf5Zv9tJWDHp/VTuaSm7SN4fyINQqaNO3RMVxvpSPXnOChnRNvFcGY0gnwiPswYwTKVPE0zVtX3mTEIOoFzaqLrGuJaV+Uqumb71fVk/VoOH3cdLNQP/FHi8hV0CQNoqBZsUPlLPMsdCJro9QAaQQ0woDy9BJm0eTxCFnO9srcYlhNVlfR2EyTrph1uUtbUtAJifwRgrKuYdXVHeb0YI3QpawohQHkloI3J5FuVwI5ORxC9k2Tuz9Ir1IjgeIPGMHYkAZe2RuYkmWFmt3gGbTPOmBUWVTmRmHtGrfpzG/yuQNOKa6gBB/WA9khitPgl6/GP+gl2Af6tCbvaygAAAABJRU5ErkJggg=="});let t=b(),e=b(8),i=1,s=0,o=new Ue(n),r=new _e(t,e,o,i,s);lc=new ss(r)}function fh(n=!0){Fn=n}function ph(n){Cr=n}function yh(){return Ke==="mouse"}function gh(){return Ke==="keyboard"}function mh(){return Ke==="gamepad"}function _r(n,t=0,e=!0,i=!0,s=!0){X[t]&&(X[t][n]&=~((e?1:0)|(i?2:0)|(s?4:0)))}function Gi(){X.length=0,X[0]=[],ee.length=0,An.length=0,Fi.length=0,be.length=0,pn.length=0}function Et(n,t=0){var e;return p(U(n),"key must be a number or string"),p(t>0||typeof n!="number"||n<3,"use code string for keyboard"),!!(((e=X[t])==null?void 0:e[n])&1)}function Lt(n,t=0){var e;return p(U(n),"key must be a number or string"),p(t>0||typeof n!="number"||n<3,"use code string for keyboard"),!!(((e=X[t])==null?void 0:e[n])&2)}function Er(n,t=0){var e;return p(U(n),"key must be a number or string"),p(t>0||typeof n!="number"||n<3,"use code string for keyboard"),!!(((e=X[t])==null?void 0:e[n])&4)}function bh(n="ArrowUp",t="ArrowDown",e="ArrowLeft",i="ArrowRight"){p(U(n),"up key must be a string"),p(U(t),"down key must be a string"),p(U(e),"left key must be a string"),p(U(i),"right key must be a string");let s=o=>Et(o)?1:0;return b(s(i)-s(e),s(n)-s(t))}function li(n){return p(L(n),"mouse button must be a number"),Et(n)}function yi(n){return p(L(n),"mouse button must be a number"),Lt(n)}function xh(n){return p(L(n),"mouse button must be a number"),Er(n)}function De(n,t=pt){return p(L(n),"button must be a number"),p(L(t),"gamepad must be a number"),Et(n,t+1)}function Rr(n,t=pt){return p(L(n),"button must be a number"),p(L(t),"gamepad must be a number"),Lt(n,t+1)}function vh(n,t=pt){return p(L(n),"button must be a number"),p(L(t),"gamepad must be a number"),Er(n,t+1)}function gi(n,t=pt){var e,i;return p(L(n),"stick must be a number"),p(L(t),"gamepad must be a number"),(i=(e=be[t])==null?void 0:e[n])!=null?i:b()}function bo(n=pt){var t;return p(L(n),"gamepad must be a number"),(t=pn[n])!=null?t:b()}function xo(n=pt){return p(L(n),"gamepad must be a number"),!!X[n+1]}function uc(n=pt){var t,e;return p(L(n),"gamepad must be a number"),(e=(t=be[n])==null?void 0:t.length)!=null?e:0}function Sh(n=pt,t=200,e=1,i=1,s=0){var r,a,c;if(p(L(n),"gamepad must be a number"),!Di||B)return;let o=(r=navigator==null?void 0:navigator.getGamepads)==null?void 0:r.call(navigator)[n];(c=(a=o==null?void 0:o.vibrationActuator)==null?void 0:a.playEffect)==null||c.call(a,"dual-rumble",{duration:t,strongMagnitude:e,weakMagnitude:i,startDelay:s})}function wh(n=pt){var e,i,s;if(p(L(n),"gamepad must be a number"),!Di||B)return;let t=(e=navigator==null?void 0:navigator.getGamepads)==null?void 0:e.call(navigator)[n];(s=(i=t==null?void 0:t.vibrationActuator)==null?void 0:i.reset)==null||s.call(i)}function Pr(n=100){var t;p(L(n)||le(n),"pattern must be a number or array"),Di&&!B&&((t=navigator==null?void 0:navigator.vibrate)==null||t.call(navigator,n))}function Th(){Pr(0)}function Ah(){var n;!te&&((n=j.requestPointerLock)==null||n.call(j))}function Ch(){var n;(n=document.exitPointerLock)==null||n.call(document)}function hc(){return document.pointerLockElement===j}function _h(){if(B)return;document.addEventListener("keydown",n),document.addEventListener("keyup",t),document.addEventListener("mousedown",i),document.addEventListener("mouseup",s),document.addEventListener("mousemove",o),document.addEventListener("mouseleave",r),document.addEventListener("wheel",a,{passive:!1}),document.addEventListener("contextmenu",c),document.addEventListener("blur",l),te&&gn&&u();function n(f){if(f.repeat||(X[0][f.code]=3,ai&&(X[0][e(f.code)]=3)),!Fn||!f.cancelable||!document.hasFocus()||f.ctrlKey||f.metaKey||f.altKey||x(f.target)||x(document.activeElement))return;let d=typeof f.key=="string"&&f.key.length===1;(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight","Space","Tab","Backspace"].includes(f.code)||d)&&f.preventDefault();function x(v){let w=v==null?void 0:v.tagName;return(v==null?void 0:v.isContentEditable)||["INPUT","TEXTAREA","SELECT"].includes(w)}}function t(f){X[0][f.code]=X[0][f.code]&2|4,ai&&(X[0][e(f.code)]=4)}function e(f){return ai?f==="KeyW"?"ArrowUp":f==="KeyS"?"ArrowDown":f==="KeyA"?"ArrowLeft":f==="KeyD"?"ArrowRight":f:f}function i(f){if(te&&gn)return;Jt&&!B&&ut&&!bi()&&ut.resume(),X[0][f.button]=3;let d=Ft;Ft=h(b(f.x,f.y)),me=me.add(Ft.subtract(d)),Fn&&f.cancelable&&document.hasFocus()&&f.preventDefault()}function s(f){te&&gn||(X[0][f.button]=X[0][f.button]&2|4)}function o(f){os=!0;let d=Ft;Ft=h(b(f.x,f.y));let y=hc()?b(f.movementX,f.movementY):Ft.subtract(d);me=me.add(y)}function r(){os=!1}function a(f){f.ctrlKey||(Ar+=Qt(f.deltaY)),Fn&&f.cancelable&&document.hasFocus()&&f.preventDefault()}function c(f){f.preventDefault()}function l(){Gi(),je.clear(),ee.length=0,An.length=0,Fi.length=0}function u(){document.addEventListener("touchstart",y=>d(y),{passive:!1}),document.addEventListener("touchmove",y=>d(y),{passive:!1}),document.addEventListener("touchend",y=>d(y),{passive:!1});let f;function d(y){if(gn){if(Jt&&!B&&ut&&!bi()&&ut.resume(),!rn||mr){let x=S=>mi.includes(S.target)||S.target===yn,v=[];for(let S of y.touches)x(S)||v.push(S);let w=v.length,_=0;if(w){let S=b(v[0].clientX,v[0].clientY),E=Ft;Ft=h(S),f?me=me.add(Ft.subtract(E)):X[0][_]=3}else f&&(X[0][_]=X[0][_]&2|4);f=w}return Fn&&y.cancelable&&document.hasFocus()&&y.preventDefault(),!0}}}function h(f){let d=j.getBoundingClientRect(),y=It(f.x,d.left,d.right),x=It(f.y,d.top,d.bottom);return b(y*j.width,x*j.height)}}function Ca(){if(B)return;!(gn&&te)&&!document.hasFocus()&&Gi(),Oe=Mi(Ft),Tr=rc(me),Rh(),t(),n();function n(){let e=li(0)||li(1)||li(2)||me.length()>Cr,i=!1;for(let o=uc();o--&&!i;)i=gi(o).lengthSquared()>.04;for(let o=17;o--&&!i;)i=De(o);let s=!1;for(let o in X[0])if(isNaN(+o)&&X[0][o]&1){s=!0;break}i?Ke="gamepad":e?Ke="mouse":s&&(Ke="keyboard"),Nn=Ke==="gamepad"}function t(){var r,a,c,l,u,h,f;let e=d=>{let v=w=>w>.3?It(w,.3,.8):w<-.3?-It(-w,.3,.8):0;return b(v(d.x),v(-d.y)).clampLength()};if(rn&&te){if(p(!En||!$n,"set touchGamepadLeftStick or touchGamepadLeftButtonCount, not both"),p(!Kn||!Yn,"set touchGamepadRightStick or touchGamepadButtonCount, not both"),!Vn.isSet())return;pt=0;let d=(r=be[0])!=null?r:be[0]=[],y=(a=pn[0])!=null?a:pn[0]=b();d.length=0,y.set();for(let v=0;v<2;v++){if(!Ve(v))continue;let w=Dr(v);d[w]=b();let _=(c=An[v])!=null?c:b();if(Oi)d[w]=e(_);else if(_.lengthSquared()>.3){let S=N($i(_.x),-1,1),E=N($i(_.y),-1,1);d[w]=b(S,-E).clampLength(),w||y.set(S,-E)}}let x=(l=X[1])!=null?l:X[1]=[];for(let v=12;v--;){let w=De(v,0);x[v]=ee[v]?w?1:3:w?4:0,ts&&x[v]===3&&(v===9||Ph(v))&&Pr(ts)}return}try{if(!Ms||!(navigator!=null&&navigator.getGamepads))return}catch{return}if(!Dt&&!document.hasFocus())return;let i=8,s=navigator.getGamepads(),o=K(i,s.length);for(let d=0;d>1]=e(b(y.axes[S],y.axes[S+1]));let _=!1;for(let S=y.buttons.length;S--;){let E=y.buttons[S],A=De(S,d);x[S]=E.pressed?A?1:3:A?4:0,E.pressed&&(!E.value||E.value>.9)&&(_=!0)}_&&(co[d]=!0,co[pt]||(pt=d)),y.mapping==="standard"&&w.set((De(15,d)&&1)-(De(14,d)&&1),(De(12,d)&&1)-(De(13,d)&&1)),gr&&(w.x||w.y)&&(v[0]=w.clampLength())}rn&&Nn&&Vn.unset()}}function _a(){if(!B){for(let n of X)for(let t in n)n[t]&=1;Ar=0,Tr=b(),me=b()}}function Eh(){Ih()}function Rh(){if(Xe||!rn||!te||B||!document.body)return;let n=Xe=document.createElement("div");n.style.cssText="position:fixed;inset:0;z-index:50;pointer-events:none;opacity:0;touch-action:none;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;transition:opacity .2s;box-sizing:border-box;padding:env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left)";let t=dc=document.createElement("div");t.style.cssText="position:relative;width:100%;height:100%;pointer-events:none",n.appendChild(t);let e=Lr=document.createElementNS(as,"svg");e.style.cssText="position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible;fill:none;stroke:#fff;stroke-width:3",t.appendChild(e);let i=()=>{let s=document.createElement("div");return s.style.cssText="position:absolute;pointer-events:auto;touch-action:none",s.addEventListener("pointerdown",o=>Fh(o,s)),s.addEventListener("pointermove",o=>jh(o)),s.addEventListener("pointerup",o=>Ea(o)),s.addEventListener("pointercancel",o=>Ea(o)),t.appendChild(s),s};mi[0]=i(),mi[1]=i(),yn=i(),addEventListener("resize",()=>Wn=!0),document.body.appendChild(n),Wn=!0}function ks(){return dc.getBoundingClientRect()}function Ve(n){return n?Kn:En}function Ln(n){return n?Yn:$n}function Or(n){return n?0:4}function Dr(n){return n&&En?1:0}function qn(n){return Ve(n)||Ln(n)>0}function Ph(n){for(let t=0;t<2;t++){let e=Or(t);if(!Ve(t)&&n>=e&&no.style.cssText="position:absolute;pointer-events:auto;touch-action:none;"+r;if(we){for(let o of mi)o.style.display="none";ue?(s(yn,"inset:0"),yn.style.display=""):yn.style.display="none"}else{for(let r=0;r<2;r++){let a=mi[r],c=r?"right":"left";if(a.style.display=qn(r)?"":"none",cn){let l=qn(r?0:1)?"50%":"100%";s(a,`${c}:0;bottom:0;width:${l};height:60%`)}else s(a,`${c}:0;bottom:0;width:${3*i}px;height:${3*i}px`)}yn.style.display=ue?"":"none";let o=ue;s(yn,`left:50%;top:50%;width:${2*o}px;height:${2*o}px;transform:translate(-50%,-50%)`)}Oh(t,e),Wn=!1}function Oh(n,t){let e=Lr;for(;e.firstChild;)e.removeChild(e.firstChild);let i=fc={face:[],thumb:[]},s=zt,o=(a,c,l,u)=>{let h=document.createElementNS(as,"circle");return h.setAttribute("cx",a),h.setAttribute("cy",c),h.setAttribute("r",l),u&&h.setAttribute("fill",u),e.appendChild(h),h},r=a=>{let c=s*.18,l=s*.5,u=a.x,h=a.y,f=document.createElementNS(as,"path");f.setAttribute("d",`M ${u-c} ${h-l} H ${u+c} V ${h-c} H ${u+l} V ${h+c} H ${u+c} V ${h+l} H ${u-c} V ${h+c} H ${u-l} V ${h-c} H ${u-c} Z`),e.appendChild(f)};for(let a=0;a<2;a++){let c=Ln(a),l=Or(a),u=Be(a,n,t);if(Ve(a))Oi?o(u.x,u.y,s/2):r(u),i.thumb[a]=o(u.x,u.y,s/4,"#fff");else if(c===1)i.face[l]=o(u.x,u.y,s/2,"#000");else for(let h=0;h2?f:K(f,c-1);d=d===3?2:d===2?3:d;let y=b().setDirection(f,s/2);c===2&&(y.x*=-1),a||(y.x*=-1);let x=u.add(y);i.face[l+d]=o(x.x,x.y,s/4,"#000")}}Dt&&vn&&Dh(n,t)}function Dh(n,t){let e=zt,i=Lr,s=(r,a,c)=>{let l=document.createElementNS(as,r);for(let u in a)l.setAttribute(u,a[u]);l.setAttribute("stroke",c),l.setAttribute("stroke-width",2),l.setAttribute("fill","none"),i.appendChild(l)},o=(r,a,c)=>s("circle",{cx:r.x,cy:r.y,r:a},c);s("line",{x1:n/2,y1:0,x2:n/2,y2:t},"#0f0");for(let r=0;r<2;r++)if(Ve(r))if(cn){let a=t*.4,c=!qn(r?0:1),l=c?0:r?n/2:0;s("rect",{x:l,y:a,width:c?n:n/2,height:t-a},"#0ff")}else o(Be(r,n,t),2*e,"#0ff");else Ln(r)>=1&&o(Be(r,n,t),e,"#0ff");if(ue){o(b(n/2,t/2),ue,"#ff0");for(let r=0;r<2;r++)qn(r)&&o(Be(r,n,t),2*e,"#f0f")}}function Ih(){var l;if(!Xe||B)return;if(!rn||!te){Xe.style.display!=="none"&&(Xe.style.display="none",je.clear(),ee.length=0,An.length=0,Fi.length=0);return}Xe.style.display="";let n=Dt&&vn,t=[Yn,$n,En,Kn,Oi,zt,cn,ue,we,n].join();t!==Aa&&(Aa=t,Wn=!0),Wn&&Lh();let e=ci?It(Vn.get(),ci+1,ci):1,i=n||Vn.isSet()&&e>0&&!we;if(Xe.style.opacity=i?n?1:e*br:0,!i)return;let s=ks(),o=s.width,r=s.height,a=zt,c=fc;if(c){for(let u=0;u<2;u++)if(Ve(u)&&c.thumb[u]){let f=Be(u,o,r).add(((l=An[u])!=null?l:b()).scale(a/2));c.thumb[u].setAttribute("cx",f.x),c.thumb[u].setAttribute("cy",f.y)}for(let u=0;u=zt)return-1;if(s===1)return o;let a=r.subtract(t);n||(a.x*=-1);let c=s===2?a.xo:a&&Be(r,t,e).distance(n)<2*i)return{role:"stick",side:r}}else if(Ln(r)>=1){let c=kh(r,n,t,e);if(c>=0)return{role:"face",btn:c}}}if(ue){for(let r=0;r<2;r++)if(qn(r)&&Be(r,t,e).distance(n)<2*i)return;if(b(t/2,e/2).distance(n)h.getChannelData(v).set(x)),f.buffer=h,f.playbackRate.value=e,f.loop=s,r=r||ut.createGain(),r.gain.value=t,r.connect(ze);let d=new StereoPannerNode(ut,{pan:N(i,-1,1)});f.connect(d).connect(r),f.addEventListener("ended",()=>{r.disconnect(),d.disconnect(),c&&c(f)});let y=a*e;return f.start(0,y),Dt&&Jn&>("sound","vol",t.toFixed(2),"rate",e.toFixed(2),"pan",i.toFixed(2),s?"loop":""),f}function Jh(...n){return Ir([Gs(...n)])}function Gs(n=1,t=.05,e=220,i=0,s=0,o=.1,r=0,a=1,c=0,l=0,u=0,h=0,f=0,d=0,y=0,x=0,v=0,w=1,_=0,S=0,E=0){let A=Qn,T=H*2,P=c*=500*T/A/A,G=e*=(1+lt(t,-t))*T/A,ht=0,Q=0,nt=0,dt=1,Mt,Ee=[],kt=0,ct=0,bt=0,Re,de=2,ln=T*tt(E)*2/A,ie=ot(ln),Pe=et(ln)/2/de,_t=1+Pe,fe=-2*ie/_t,un=(1-Pe)/_t,Dn=(1+Qt(E)*ie)/2/_t,Zn=-(Qt(E)+ie)/_t,ti=Dn,hn=0,dn=0,R=0,M=0;for(i=i*A||9,_*=A,s*=A,o*=A,v*=A,l*=500*T/A**3,y*=T/A,u*=T/A,h*=A,f=f*A|0,Mt=i+_+s+o+v|0;ct1?r>2?r>3?r>4?kt/T%14?bt:Qt(bt)*tt(bt)**a)*(ctct?0:(cth&&(e+=u,G+=u,dt=0),f&&!(++Q%f)&&(e=G,c=P,dt||(dt=1));return Ee}function ls(n,t=!0){for(let e of nn)if((!t||e.isSolid)&&n.arrayCheck(e.size)){let i=e.getCollisionData(n);if(i)return i}return 0}function Ye(n,t=b(),e,i=!0){for(let s of nn)if((!i||s.isSolid)&&s.collisionTest(n,t,e))return s}function gc(n,t,e,i,s=!0){let o,r,a,c=i&&b();for(let l of nn)if(!s||l.isSolid){let u=l.collisionRaycast(n,t,e,c);if(u){let h=n.distanceSquared(u);(o===void 0||h{F=!1,Z.style.display="none",e.preventDefault(),gt("WebGL context lost! Switching to Canvas2d rendering.");for(let i of ui)i.glTexture=void 0;Xt=void 0,Tt=0,Cn=!1,bn.forEach(i=>{var s;return(s=i.glContextLost)==null?void 0:s.call(i)})}),Z.addEventListener("webglcontextrestored",()=>{F=!0,Z.style.display="",gt("WebGL context restored, reinitializing..."),t();for(let e of ui)e.glTexture=js(e.image,e.wrap);bn.forEach(e=>{var i;return(i=e.glContextRestored)==null?void 0:i.call(e)})});function t(){ds=Xn(`#version 300 es
+`,o+=i.toString(),$e(o,Ft,24,N(),.05,void 0,"center","monospace")}{e.save(),e.fillStyle="#fff",e.textAlign="left",e.textBaseline="top",e.font="20px monospace",e.shadowColor="#000",e.shadowBlur=9;let r=9,a=0,c=24;if(Ee){e.fillText(`${Ji} v${Ui}`,r,a+=c/2),e.fillText("Time: "+ir(qt),r,a+=c),e.fillText("FPS: "+Vi.toFixed(1)+(k?" WebGL":" Canvas2D"),r,a+=c),e.fillText("Objects: "+bt.length,r,a+=c),e.fillText("Draw Calls: "+ve,r,a+=c),e.fillText("Primitives: "+Se,r,a+=c),e.fillText("---------",r,a+=c),e.fillStyle="#f00",e.fillText("ESC: Debug Overlay",r,a+=c),e.fillStyle=se?"#f00":"#fff",e.fillText("1: Debug Physics",r,a+=c),e.fillStyle=pn?"#f00":"#fff",e.fillText("2: Debug Particles",r,a+=c),e.fillStyle=yn?"#f00":"#fff",e.fillText("3: Debug Gamepads",r,a+=c),e.fillStyle=oe?"#f00":"#fff",e.fillText("4: Debug Raycasts",r,a+=c),e.fillStyle="#fff",e.fillText("5: Save Screenshot",r,a+=c),e.fillText("6: Toggle Video Capture",r,a+=c),e.fillStyle=Gn?"#f00":"#fff",e.fillText("7: Debug Sound",r,a+=c);let l="",u="";for(let h in X[0])Et(h,0)&&(parseInt(h)<3?u+=h+" ":l+=h+" ");u&&e.fillText("Mouse: "+u,r,a+=c),l&&e.fillText("Keys: "+l,r,a+=c);for(let h=1;hi.push(a.data),s.onstop=()=>{let a=new Blob(i,{type:"video/webm"}),c=URL.createObjectURL(a);ai(c,"capture.webm",1e3)};let o,r;if(Jt){r=new ConstantSourceNode(dt,{offset:0}),r.connect(Me),r.start(),o=dt.createMediaStreamDestination(),Me.connect(o);for(let a of o.stream.getAudioTracks())n.addTrack(a)}try{s.start()}catch{mt("Video capture not supported in this browser!"),r==null||r.stop();return}mt("Video capture started."),_e={mediaRecorder:s,captureTimer:e,videoTrack:t,silentAudioSource:r,audioStreamDestination:o}}function Ga(){var n,t,e;p(me(),"Not capturing video!"),mt(`Video capture ended. ${_e.captureTimer.get().toFixed(2)} seconds recorded.`),ie.style.display="none",(n=_e.silentAudioSource)==null||n.stop(),(t=_e.mediaRecorder)==null||t.stop(),(e=_e.videoTrack)==null||e.stop(),_e=void 0}function Bl(){p(me(),"Not capturing video!"),br(),_e.videoTrack.requestFrame(),ie.textContent="\u25CF REC "+ir(_e.captureTimer)}function Xt(n){if(Dt){let t=Object.keys(n),e={};t.forEach(i=>e[i]=n[i]),t.forEach(i=>{Object.defineProperty(n,i,{get:()=>e[i],set:s=>{p(!1,`Cannot modify engine constant. Attempted to set constant (${n}) property '${i}' to '${s}'.`)},enumerable:!0})})}return Object.freeze(n)}function Qt(n,t=1){return(n%t+t)%t}function j(n,t=0,e=1){return ne?e:n}function It(n,t,e){return(e-=t)?j((n-t)/e):0}function Nt(n,t,e){return n+j(e)*(t-n)}function Nl(n,t,e,i,s){return Nt(i,s,It(n,t,e))}function tr(n,t,e=1){p(e>0,"distanceWrap wrapSize must be > 0");let i=(n-t)%e;return i*2%e-i}function Na(n,t,e,i=1){return n+j(e)*tr(t,n,i)}function zl(n,t){return tr(n,t,2*H)}function Jl(n,t,e){return Na(n,t,e,2*H)}function qi(n){return n*n*(3-2*n)}function ri(n){return!(n&n-1)}function Ul(n){return 2**oi(ja(n))}function Hi(n,t,e,i=x()){let s=(n.x-e.x)*2,o=(n.y-e.y)*2,r=t.x+i.x,a=t.y+i.y;return tt(s)f)return!1;h=Y(g,h)}else{if(g0?a.x+1:a.x,b=h>0?a.y+1:a.y,v=c?(g-n.x)/c:1/0,w=l?(b-n.y)/l:1/0,_=0,S=v,E=w,A=fa.x&&(T.x=a.x+1-P),M.ya.y&&(T.y=a.y+1-P),i&&(A?i.set(-u,0):i.set(0,-h)),T}(A=SURL.revokeObjectURL(n),e)}function $l(n,t,e){var i;p(J(n),"shareURL requires title string"),p(J(t),"shareURL requires url string"),(i=navigator.share)==null||i.call(navigator,{title:n,url:t}).then(()=>e==null?void 0:e())}function Kl(n,t){p(J(n),"loadData requires saveName string");let e={};try{let i=localStorage[n];if(i)try{e=JSON.parse(i)}catch{mt("readSaveData: corrupt JSON for",n,"\u2014 using defaults")}}catch{mt("readSaveData: localStorage unavailable \u2014 using defaults")}return{...t,...e}}function Ql(n,t){p(J(n),"saveData requires saveName string");try{localStorage[n]=JSON.stringify(t)}catch{mt("writeSaveData: failed to write",n)}}function ho(n){let t=(n|0)^2654435769;return t=Math.imul(t^t>>>16,2246822507),t=Math.imul(t^t>>>13,3266489909),t^=t>>>16,(t>>>0)/2**32}function Zl(n){let t=xt(n);return Nt(ho(t),ho(t+1),qi(n-t))}function tu(n,t){let e=xt(n),i=xt(t),s=qi(n-e),o=qi(t-i),r=(a,c)=>ho(a+c*374761393);return Nt(Nt(r(e,i),r(e+1,i),s),Nt(r(e,i+1),r(e+1,i+1),s),o)}function eu(n){Tt=n.copy()}function nu(n){$=n}function iu(n){q=n}function su(n){sr=n}function ou(n){As=n}function ru(n){Xe=n.copy()}function au(n){Rn=n.copy()}function cu(n){ti=n}function lu(n){Pn=n}function uu(n){Ln=n.copy()}function Za(n){or=n,F&&(F.style.imageRendering=n?"pixelated":""),Z&&(Z.style.imageRendering=n?"pixelated":"")}function hu(n){bn=n}function du(n){Ye=n}function fu(n){Ti=n}function pu(n){rr=n}function yu(n){B=n}function gu(n){if(n&&!vo){console.warn("Can not enable WebGL if it was disabled on start.");return}k=n,Z&&(Z.style.display=n?"":"none")}function mu(n){Ai=n}function bu(n){Cs=n.copy()}function xu(n){Es=n}function vu(n){_s=n}function Su(n){Rs=n}function wu(n){ar=n}function Tu(n){cr=n}function Au(n){lr=n}function Cu(n){ur=n}function Eu(n){hr=n}function _u(n){Pe=n}function Ru(n){Bt=n.copy()}function Pu(n){Xi=n}function Lu(n){Ps=n}function Ou(n){dr=n}function Du(n){ei=n}function Iu(n){hn=n}function Mu(n){tn=n}function ku(n){fr=n}function Gu(n){ae=n}function Fu(n){Un=n,n>0&&(Wn=!1)}function ju(n){wn=n,n&&(Vn=0)}function Bu(n){Vn=n,n>0&&(wn=!1)}function Nu(n){Wn=n,n&&(Un=0)}function zu(n){Ci=n}function Ju(n){nn=n}function Uu(n){zt=n}function Vu(n){pr=n}function Wu(n){ni=n}function qu(n){Yi=n}function Hu(n){Ei=n}function Xu(n){Jt=n}function Yu(n){gn=n,Jt&&!B&&Me&&(Me.gain.value=n)}function $u(n){yr=n}function Ku(n){gr=n}function Qu(n){Ts=n}function Zu(n){Ia=n}function $i(n){return n.r>=1&&n.g>=1&&n.b>=1}function mr(n){return n.r<=0&&n.g<=0&&n.b<=0&&n.a<=0}function _i(n=0,t=Cs,e=0,i=Es,s=_s){if(p(O(n)||typeof n=="number","index must be a vec2 or number"),p(O(t)||typeof t=="number","size must be a vec2 or number"),p(L(e)||e instanceof Ge,"texture must be a number or TextureInfo"),p(L(i),"padding must be a number"),B)return new we;typeof t=="number"&&(p(t>0),t=new ot(t,t));let o=typeof e=="number"?en[e]:e;p(o instanceof Ge,"tile texture is not loaded"),p(o.size.x>0,"tile texture is not loaded");let r=t.x+i*2,a=t.y+i*2,c,l;if(typeof n=="number"){let h=o.size.x/r|0;c=n%h,l=n/h|0}else c=n.x,l=n.y;let u=new ot(c*r+i,l*a+i);return new we(u,t,o,i,s)}function _t(n,t=x(1),e,i=U,s=0,o,r,a=k,c=!1,l){var f;p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(z(i),"color is invalid"),p(L(s),"angle must be a number"),p(!r||z(r),"additiveColor must be a color"),p(!l||!a,"context only supported in canvas 2D mode");let u=e==null?void 0:e.textureInfo,h=(f=e==null?void 0:e.bleed)!=null?f:0;if(a&&k)if(p(!!y,"WebGL is not enabled!"),c&&([n,t,s]=Pi(n,t,s)),u){let d=u.sizeInverse,g=e.pos.x*d.x,b=e.pos.y*d.y,v=e.size.x*d.x,w=e.size.y*d.y;if(Ir(u.glTexture),h){let _=d.x*h,S=d.y*h;bi(n.x,n.y,o?-t.x:t.x,t.y,s,g+_,b+S,g-_+v,b-S+w,i.rgbaInt(),r&&r.rgbaInt())}else bi(n.x,n.y,o?-t.x:t.x,t.y,s,g,b,g+v,b+w,i.rgbaInt(),r&&r.rgbaInt())}else{let d=r?i.add(r):i;vc(n.x,n.y,t.x,t.y,s,d.rgbaInt())}else++ve,++Se,Tn(n,t,s,o,d=>{if(u){d.scale(1,-1);let g=e.pos.x,b=e.pos.y,v=e.size.x,w=e.size.y;lh(d,u.image,g,b,v,w,-.5,-.5,1,1,i,r,h)}else{let g=r?i.add(r):i;d.fillStyle=g.toString(),d.fillRect(-.5,-.5,1,1)}},c,l)}function Ki(n,t,e,i,s,o,r){_t(n,t,void 0,e,i,!1,void 0,s,o,r)}function th(n,t,e=U,i=Ze,s=0,o=k,r=!1,a){if(p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(z(e)&&z(i),"color is invalid"),p(L(s),"angle must be a number"),p(!a||!o,"context only supported in canvas 2D mode"),o&&k){p(!!y,"WebGL is not enabled!"),r&&(n=Ri(n),t=t.scale(1/q),s+=$);let c=[],l=[],u=t.x/2,h=t.y/2,f=e.rgbaInt(),d=i.rgbaInt(),g=at(-s),b=et(-s);for(let v=4;v--;){let w=v&1?u:-u,_=v&2?h:-h,S=w*g-_*b,E=w*b+_*g,A=v&2?f:d;c.push(x(n.x+S,n.y+E)),l.push(A)}jr(c,l)}else++ve,++Se,Tn(n,t,s,!1,c=>{let l=c.createLinearGradient(0,.5,0,-.5);l.addColorStop(0,e.toString()),l.addColorStop(1,i.toString()),c.fillStyle=l,c.fillRect(-.5,-.5,1,1)},r,a)}function eh(n,t,e,i=0,s=U,o=0,r,a=k,c=!1,l){if(p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(O(e),"wrapCount must be a vec2"),p(z(s),"color is invalid"),p(L(o),"angle must be a number"),p(!r||z(r),"additiveColor must be a color"),p(!l||!a,"context only supported in canvas 2D mode"),p(!(i instanceof we),"pass a TextureInfo or texture index, not a TileInfo \u2014 use tileInfo.textureInfo"),B)return;let u=typeof i=="number"?en[i]:i;if(p(u instanceof Ge,"texture not loaded"),p(u.size.x>0,"texture not loaded"),p(u.wrap,"drawTextureWrapped requires a wrap-enabled texture; call textureInfo.setWrap(true) first"),a&&k){p(!!y,"WebGL is not enabled!"),c&&([n,t,o]=Pi(n,t,o)),Ir(u.glTexture),bi(n.x,n.y,t.x,t.y,o,0,0,e.x,e.y,s.rgbaInt(),r&&r.rgbaInt());return}++ve,++Se,c||(n=An(n),t=t.scale(q),o-=$);let h=!As||(r?$i(s.add(r))&&r.a<=0:$i(s)),f=!h&&r&&!mr(r),d=h?u.image:ch(u.image,s,r);l=l||St,l.save(),l.translate(n.x+.5,n.y+.5),l.rotate(o),l.globalAlpha=f?1:s.a;let g=l.createPattern(d,"repeat"),b=new DOMMatrix().translate(-t.x/2,-t.y/2).scale(t.x/(e.x*d.width),t.y/(e.y*d.height));g.setTransform(b),l.fillStyle=g,l.fillRect(-t.x/2,-t.y/2,t.x,t.y),l.globalAlpha=1,l.restore()}function fo(n,t=.1,e=U,i=!1,s=x(),o=0,r=k,a=!1,c){if(p(re(n),"points must be an array"),p(L(t),"width must be a number"),p(z(e),"color is invalid"),p(O(s),"pos must be a vec2"),p(L(o),"angle must be a number"),p(!c||!r,"context only supported in canvas 2D mode"),r&&k){p(!!y,"WebGL is not enabled!");let l=x(1);a&&([s,l,o]=Pi(s,l,o)),Fr(n,e.rgbaInt(),t,s.x,s.y,l.x,l.y,o,i)}else++ve,++Se,Tn(s,x(1),o,!1,l=>{l.strokeStyle=e.toString(),l.lineWidth=t,l.beginPath();for(let u=0;u0&&Fr(n,i.rgbaInt(),e,s.x,s.y,l.x,l.y,o)}else Tn(s,x(1),o,!1,l=>{l.fillStyle=t.toString(),l.beginPath();for(let u of n)l.lineTo(u.x,u.y);l.closePath(),l.fill(),e&&(l.strokeStyle=i.toString(),l.lineWidth=e,l.stroke())},a,c)}function ec(n,t=x(1),e=U,i=0,s=0,o=it,r=k,a=!1,c){p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(z(e)&&z(o),"color is invalid"),p(L(i),"angle must be a number"),p(L(s),"lineWidth must be a number"),p(s>=0,"lineWidth must be a positive value or 0"),p(!c||!r,"context only supported in canvas 2D mode"),s=j(s,0,Q(t.x,t.y)),r&&k?tc(n,t,Ai,e,s,o,i,r,a,c):Tn(n,x(1),i,!1,l=>{l.fillStyle=e.toString(),l.beginPath(),l.ellipse(0,0,t.x/2,t.y/2,0,0,9),l.fill(),s&&(l.strokeStyle=o.toString(),l.lineWidth=s,l.stroke())},a,c)}function Qi(n,t=1,e=U,i=0,s=it,o=k,r=!1,a){p(L(t),"size must be a number"),ec(n,x(t),e,0,i,s,o,r,a)}function nc(n,t=x(1),e=U,i=Ze,s=0,o=k,r=!1,a){if(p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(z(e)&&z(i),"color is invalid"),p(L(s),"angle must be a number"),p(!a||!o,"context only supported in canvas 2D mode"),!B)if(o&&k){p(!!y,"WebGL is not enabled!"),r&&(n=Ri(n),t=t.scale(1/q),s+=$);let c=Ai,l=t.x/2,u=t.y/2,h=e.rgbaInt(),f=i.rgbaInt(),d=nh++,g=at(-s),b=et(-s),v=E=>{let A=et(E)*l,T=at(E)*u;return x(n.x+A*g-T*b,n.y+A*b+T*g)},w=d%c/c*H*2,_=[v(w)],S=[f];for(let E=c;E--;){let A=(E+d)%c/c*H*2;_.push(n),S.push(h),_.push(v(A)),S.push(f)}jr(_,S)}else++ve,++Se,Tn(n,t,s,!1,c=>{let l=c.createRadialGradient(0,0,0,0,0,.5);l.addColorStop(0,e.toString()),l.addColorStop(1,i.toString()),c.fillStyle=l,c.beginPath(),c.ellipse(0,0,.5,.5,0,0,9),c.fill()},r,a)}function ih(n,t=1,e=U,i=Ze,s=k,o=!1,r){p(L(t),"size must be a number"),nc(n,x(t),e,i,0,s,o,r)}function Tn(n,t,e=0,i=!1,s,o=!1,r=St){p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(L(e),"angle must be a number"),p(typeof s=="function","drawFunction must be a function"),o||(n=An(n),t=t.scale(q),e-=$),r.save(),r.translate(n.x+.5,n.y+.5),r.rotate(e),r.scale(i?-t.x:t.x,-t.y),s(r),r.restore()}function sh(n,t,e=1,i=U,s=0,o=it,r="center",a=Ti,c="",l,u=0,h=St){t=An(t),e*=q,s*=q,u-=$,u*=-1,$e(n,t,e,i,s,o,r,a,c,l,u,h)}function $e(n,t,e,i=U,s=0,o=it,r="center",a=Ti,c="",l,u=0,h=St){p(J(n),"text must be a string"),p(O(t),"pos must be a vec2"),p(L(e),"size must be a number"),p(z(i),"color must be a color"),p(L(s),"lineWidth must be a number"),p(z(o),"lineColor must be a color"),p(["left","center","right"].includes(r),"align must be left, center, or right"),p(J(a),"font must be a string"),p(J(c),"fontStyle must be a string"),p(L(u),"angle must be a number");let f=(n+"").split(`
+`),d=t.y-(f.length-1)*e/2;h.save(),h.fillStyle=i.toString(),h.strokeStyle=o.toString(),h.lineWidth=s,h.textAlign=r,h.font=c+" "+e+"px "+a,h.textBaseline="middle",h.translate(t.x,d),h.rotate(-u);let g=0;f.forEach(b=>{s&&h.strokeText(b,0,g,l),h.fillText(b,0,g,l),g+=e}),h.restore()}async function va(n,t){p(L(n),"textureIndex must be a number"),p(!en[n],"textureIndex is already loaded!"),p(!t||J(t),"image src must be a string");let e=new Image;t&&await new Promise(i=>{e.onerror=e.onload=i,e.crossOrigin="anonymous",e.src=t}),en[n]=new Ge(e)}function Ri(n){p(O(n),"screenPos must be a vec2");let t=(n.x-I.x/2+.5)/q,e=(n.y-I.y/2+.5)/-q;if($){let i=at(-$),s=et(-$),o=t*i-e*s,r=t*s+e*i;t=o,e=r}return new ot(t+Tt.x,e+Tt.y)}function An(n){p(O(n),"worldPos must be a vec2");let t=n.x-Tt.x,e=n.y-Tt.y;if($){let i=at($),s=et($),o=t*i-e*s,r=t*s+e*i;t=o,e=r}return new ot(t*q+I.x/2-.5,e*-q+I.y/2-.5)}function ic(n){p(O(n),"screenDelta must be a vec2");let t=n.x/q,e=n.y/-q;if($){let i=at(-$),s=et(-$),o=t*i-e*s,r=t*s+e*i;t=o,e=r}return new ot(t,e)}function oh(n){p(O(n),"worldDelta must be a vec2");let t=n.x,e=n.y;if($){let i=at($),s=et($),o=t*i-e*s,r=t*s+e*i;t=o,e=r}return new ot(t*q,e*-q)}function Pi(n,t,e=0){return p(O(n),"screenPos must be a vec2"),p(O(t),"screenSize must be a vec2"),p(L(e),"screenAngle must be a number"),[Ri(n),t.scale(1/q),e+$]}function sc(){return I.scale(1/q)}function rh(n,t,e,i){p(O(n),"center must be a vec2"),p(O(t),"size must be a vec2");let s=f(e),o=f(i),r=t.x+s.left+s.right,a=t.y+s.top+s.bottom,c=I.x-o.left-o.right,l=I.y-o.top-o.bottom;if(!(r>0&&a>0&&c>0&&l>0))return q;q=Q(c/r,l/a);let u=x(s.right-s.left,s.top-s.bottom).scale(.5),h=x(o.right-o.left,o.top-o.bottom).scale(.5/q);return Tt=n.add(u).add(h),q;function f(d){return(d===void 0||L(d))&&(d=x(d)),O(d)?{top:d.y,right:d.x,bottom:d.y,left:d.x}:{top:d.top||0,right:d.right||0,bottom:d.bottom||0,left:d.left||0}}}function ah(n,t=0){if(p(O(n),"pos must be a vec2"),p(O(t)||L(t),"size must be a vec2 or number"),!q)return!1;let e=n.x-Tt.x,i=n.y-Tt.y;if($){let r=at($),a=et($),c=e*r-i*a,l=e*a+i*r;e=c,i=l}e*=q*2,i*=-q*2,t instanceof ot&&(t=t.length()),t*=q;let s=I.x,o=I.y;return e+t>-s&&e-t-o&&i-t{n.onerror=n.onload=a,n.crossOrigin="anonymous",n.src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUAAAAAeAQMAAABnrVXaAAAABlBMVEUAAAD///+l2Z/dAAAAAXRSTlMAQObYZgAAAjpJREFUOMu9kzFu2zAUhn+CAROgqrk+B2l0BWYxMjlXeYaAtFtbdA1sGgHqRQfI0CNkSG5AwYB0BQ8d5Bsomwah6CPVeGg6tEPzAxLwyI+P78cP4u9lNO9OoMKnLMOobG5020/yaj/MrRcCGh1gBbyiLTPJEYaIiom5KM9Jq7KgynMGtb6L4GL4MF2H4LQKCXTvDVw2I4MsgZT7QLExdiutH+D08VOP3INXRrWX1/mmpbkNgAPYRVANb4xpcegYvhiNbIXauQICEjBuYLfMakaakWQeXxiZ0VDtuJCKs3ztMV59QtsHJNcRxDzfdL21ty3PrfIcXTN+E+GFAv6T5nbT9jd50/WFxb5ksdAv49qS6ouymG66ji08UMT6moykYLAo+V0j23GN4m829ZySAD5K7QsBfQTvOG8eE+gTeGYRAmnNAubN3hf5Zv9tJWDHp/VTuaSm7SN4fyINQqaNO3RMVxvpSPXnOChnRNvFcGY0gnwiPswYwTKVPE0zVtX3mTEIOoFzaqLrGuJaV+Uqumb71fVk/VoOH3cdLNQP/FHi8hV0CQNoqBZsUPlLPMsdCJro9QAaQQ0woDy9BJm0eTxCFnO9srcYlhNVlfR2EyTrph1uUtbUtAJifwRgrKuYdXVHeb0YI3QpawohQHkloI3J5FuVwI5ORxC9k2Tuz9Ir1IjgeIPGMHYkAZe2RuYkmWFmt3gGbTPOmBUWVTmRmHtGrfpzG/yuQNOKa6gBB/WA9khitPgl6/GP+gl2Af6tCbvaygAAAABJRU5ErkJggg=="});let t=x(),e=x(8),i=1,s=0,o=new Ge(n),r=new we(t,e,o,i,s);rc=new Zi(r)}function fh(n=!0){On=n}function ph(n){Sr=n}function yh(){return qe==="mouse"}function gh(){return qe==="keyboard"}function mh(){return qe==="gamepad"}function wr(n,t=0,e=!0,i=!0,s=!0){X[t]&&(X[t][n]&=~((e?1:0)|(i?2:0)|(s?4:0)))}function Li(){X.length=0,X[0]=[],te.length=0,xn.length=0,Oi.length=0,pe.length=0,ln.length=0}function Et(n,t=0){var e;return p(J(n),"key must be a number or string"),p(t>0||typeof n!="number"||n<3,"use code string for keyboard"),!!(((e=X[t])==null?void 0:e[n])&1)}function Lt(n,t=0){var e;return p(J(n),"key must be a number or string"),p(t>0||typeof n!="number"||n<3,"use code string for keyboard"),!!(((e=X[t])==null?void 0:e[n])&2)}function Tr(n,t=0){var e;return p(J(n),"key must be a number or string"),p(t>0||typeof n!="number"||n<3,"use code string for keyboard"),!!(((e=X[t])==null?void 0:e[n])&4)}function bh(n="ArrowUp",t="ArrowDown",e="ArrowLeft",i="ArrowRight"){p(J(n),"up key must be a string"),p(J(t),"down key must be a string"),p(J(e),"left key must be a string"),p(J(i),"right key must be a string");let s=o=>Et(o)?1:0;return x(s(i)-s(e),s(n)-s(t))}function ii(n){return p(L(n),"mouse button must be a number"),Et(n)}function li(n){return p(L(n),"mouse button must be a number"),Lt(n)}function xh(n){return p(L(n),"mouse button must be a number"),Tr(n)}function Ce(n,t=yt){return p(L(n),"button must be a number"),p(L(t),"gamepad must be a number"),Et(n,t+1)}function Ar(n,t=yt){return p(L(n),"button must be a number"),p(L(t),"gamepad must be a number"),Lt(n,t+1)}function vh(n,t=yt){return p(L(n),"button must be a number"),p(L(t),"gamepad must be a number"),Tr(n,t+1)}function ui(n,t=yt){var e,i;return p(L(n),"stick must be a number"),p(L(t),"gamepad must be a number"),(i=(e=pe[t])==null?void 0:e[n])!=null?i:x()}function po(n=yt){var t;return p(L(n),"gamepad must be a number"),(t=ln[n])!=null?t:x()}function yo(n=yt){return p(L(n),"gamepad must be a number"),!!X[n+1]}function ac(n=yt){var t,e;return p(L(n),"gamepad must be a number"),(e=(t=pe[n])==null?void 0:t.length)!=null?e:0}function Sh(n=yt,t=200,e=1,i=1,s=0){var r,a,c;if(p(L(n),"gamepad must be a number"),!Ei||B)return;let o=(r=navigator==null?void 0:navigator.getGamepads)==null?void 0:r.call(navigator)[n];(c=(a=o==null?void 0:o.vibrationActuator)==null?void 0:a.playEffect)==null||c.call(a,"dual-rumble",{duration:t,strongMagnitude:e,weakMagnitude:i,startDelay:s})}function wh(n=yt){var e,i,s;if(p(L(n),"gamepad must be a number"),!Ei||B)return;let t=(e=navigator==null?void 0:navigator.getGamepads)==null?void 0:e.call(navigator)[n];(s=(i=t==null?void 0:t.vibrationActuator)==null?void 0:i.reset)==null||s.call(i)}function Cr(n=100){var t;p(L(n)||re(n),"pattern must be a number or array"),Ei&&!B&&((t=navigator==null?void 0:navigator.vibrate)==null||t.call(navigator,n))}function Th(){Cr(0)}function Ah(){var n;!Zt&&((n=F.requestPointerLock)==null||n.call(F))}function Ch(){var n;(n=document.exitPointerLock)==null||n.call(document)}function cc(){return document.pointerLockElement===F}function Eh(){if(B)return;document.addEventListener("keydown",n),document.addEventListener("keyup",t),document.addEventListener("mousedown",i),document.addEventListener("mouseup",s),document.addEventListener("mousemove",o),document.addEventListener("mouseleave",r),document.addEventListener("wheel",a,{passive:!1}),document.addEventListener("contextmenu",c),document.addEventListener("blur",l),Zt&&hn&&u();function n(f){if(f.repeat||(X[0][f.code]=3,ei&&(X[0][e(f.code)]=3)),!On||!f.cancelable||!document.hasFocus()||f.ctrlKey||f.metaKey||f.altKey||b(f.target)||b(document.activeElement))return;let d=typeof f.key=="string"&&f.key.length===1;(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight","Space","Tab","Backspace"].includes(f.code)||d)&&f.preventDefault();function b(v){let w=v==null?void 0:v.tagName;return(v==null?void 0:v.isContentEditable)||["INPUT","TEXTAREA","SELECT"].includes(w)}}function t(f){X[0][f.code]=X[0][f.code]&2|4,ei&&(X[0][e(f.code)]=4)}function e(f){return ei?f==="KeyW"?"ArrowUp":f==="KeyS"?"ArrowDown":f==="KeyA"?"ArrowLeft":f==="KeyD"?"ArrowRight":f:f}function i(f){if(Zt&&hn)return;Jt&&!B&&dt&&!di()&&dt.resume(),X[0][f.button]=3;let d=Ft;Ft=h(x(f.x,f.y)),fe=fe.add(Ft.subtract(d)),On&&f.cancelable&&document.hasFocus()&&f.preventDefault()}function s(f){Zt&&hn||(X[0][f.button]=X[0][f.button]&2|4)}function o(f){ts=!0;let d=Ft;Ft=h(x(f.x,f.y));let g=cc()?x(f.movementX,f.movementY):Ft.subtract(d);fe=fe.add(g)}function r(){ts=!1}function a(f){f.ctrlKey||(vr+=Kt(f.deltaY)),On&&f.cancelable&&document.hasFocus()&&f.preventDefault()}function c(f){f.preventDefault()}function l(){Li(),Oe.clear(),te.length=0,xn.length=0,Oi.length=0}function u(){document.addEventListener("touchstart",g=>d(g),{passive:!1}),document.addEventListener("touchmove",g=>d(g),{passive:!1}),document.addEventListener("touchend",g=>d(g),{passive:!1});let f;function d(g){if(hn){if(Jt&&!B&&dt&&!di()&&dt.resume(),!tn||fr){let b=S=>hi.includes(S.target)||S.target===un,v=[];for(let S of g.touches)b(S)||v.push(S);let w=v.length,_=0;if(w){let S=x(v[0].clientX,v[0].clientY),E=Ft;Ft=h(S),f?fe=fe.add(Ft.subtract(E)):X[0][_]=3}else f&&(X[0][_]=X[0][_]&2|4);f=w}return On&&g.cancelable&&document.hasFocus()&&g.preventDefault(),!0}}}function h(f){let d=F.getBoundingClientRect(),g=It(f.x,d.left,d.right),b=It(f.y,d.top,d.bottom);return x(g*F.width,b*F.height)}}function wa(){if(B)return;!(hn&&Zt)&&!document.hasFocus()&&Li(),Ae=Ri(Ft),xr=ic(fe),Rh(),t(),n();function n(){let e=ii(0)||ii(1)||ii(2)||fe.length()>Sr,i=!1;for(let o=ac();o--&&!i;)i=ui(o).lengthSquared()>.04;for(let o=17;o--&&!i;)i=Ce(o);let s=!1;for(let o in X[0])if(isNaN(+o)&&X[0][o]&1){s=!0;break}i?qe="gamepad":e?qe="mouse":s&&(qe="keyboard"),In=qe==="gamepad"}function t(){var r,a,c,l,u,h,f;let e=d=>{let v=w=>w>.3?It(w,.3,.8):w<-.3?-It(-w,.3,.8):0;return x(v(d.x),v(-d.y)).clampLength()};if(tn&&Zt){if(p(!wn||!Vn,"set touchGamepadLeftStick or touchGamepadLeftButtonCount, not both"),p(!Wn||!Un,"set touchGamepadRightStick or touchGamepadButtonCount, not both"),!jn.isSet())return;yt=0;let d=(r=pe[0])!=null?r:pe[0]=[],g=(a=ln[0])!=null?a:ln[0]=x();d.length=0,g.set();for(let v=0;v<2;v++){if(!Fe(v))continue;let w=Rr(v);d[w]=x();let _=(c=xn[v])!=null?c:x();if(Ci)d[w]=e(_);else if(_.lengthSquared()>.3){let S=j(Wi(_.x),-1,1),E=j(Wi(_.y),-1,1);d[w]=x(S,-E).clampLength(),w||g.set(S,-E)}}let b=(l=X[1])!=null?l:X[1]=[];for(let v=12;v--;){let w=Ce(v,0);b[v]=te[v]?w?1:3:w?4:0,Yi&&b[v]===3&&(v===9||Ph(v))&&Cr(Yi)}return}try{if(!Ps||!(navigator!=null&&navigator.getGamepads))return}catch{return}if(!Dt&&!document.hasFocus())return;let i=8,s=navigator.getGamepads(),o=Q(i,s.length);for(let d=0;d>1]=e(x(g.axes[S],g.axes[S+1]));let _=!1;for(let S=g.buttons.length;S--;){let E=g.buttons[S],A=Ce(S,d);b[S]=E.pressed?A?1:3:A?4:0,E.pressed&&(!E.value||E.value>.9)&&(_=!0)}_&&(so[d]=!0,so[yt]||(yt=d)),g.mapping==="standard"&&w.set((Ce(15,d)&&1)-(Ce(14,d)&&1),(Ce(12,d)&&1)-(Ce(13,d)&&1)),dr&&(w.x||w.y)&&(v[0]=w.clampLength())}tn&&In&&jn.unset()}}function Ta(){if(!B){for(let n of X)for(let t in n)n[t]&=1;vr=0,xr=x(),fe=x()}}function _h(){Ih()}function Rh(){if(Ue||!tn||!Zt||B||!document.body)return;let n=Ue=document.createElement("div");n.style.cssText="position:fixed;inset:0;z-index:50;pointer-events:none;opacity:0;touch-action:none;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;transition:opacity .2s;box-sizing:border-box;padding:env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left)";let t=lc=document.createElement("div");t.style.cssText="position:relative;width:100%;height:100%;pointer-events:none",n.appendChild(t);let e=Er=document.createElementNS(ns,"svg");e.style.cssText="position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible;fill:none;stroke:#fff;stroke-width:3",t.appendChild(e);let i=()=>{let s=document.createElement("div");return s.style.cssText="position:absolute;pointer-events:auto;touch-action:none",s.addEventListener("pointerdown",o=>Fh(o,s)),s.addEventListener("pointermove",o=>jh(o)),s.addEventListener("pointerup",o=>Aa(o)),s.addEventListener("pointercancel",o=>Aa(o)),t.appendChild(s),s};hi[0]=i(),hi[1]=i(),un=i(),addEventListener("resize",()=>Bn=!0),document.body.appendChild(n),Bn=!0}function Ls(){return lc.getBoundingClientRect()}function Fe(n){return n?Wn:wn}function Cn(n){return n?Un:Vn}function _r(n){return n?0:4}function Rr(n){return n&&wn?1:0}function Nn(n){return Fe(n)||Cn(n)>0}function Ph(n){for(let t=0;t<2;t++){let e=_r(t);if(!Fe(t)&&n>=e&&no.style.cssText="position:absolute;pointer-events:auto;touch-action:none;"+r;if(be){for(let o of hi)o.style.display="none";ae?(s(un,"inset:0"),un.style.display=""):un.style.display="none"}else{for(let r=0;r<2;r++){let a=hi[r],c=r?"right":"left";if(a.style.display=Nn(r)?"":"none",nn){let l=Nn(r?0:1)?"50%":"100%";s(a,`${c}:0;bottom:0;width:${l};height:60%`)}else s(a,`${c}:0;bottom:0;width:${3*i}px;height:${3*i}px`)}un.style.display=ae?"":"none";let o=ae;s(un,`left:50%;top:50%;width:${2*o}px;height:${2*o}px;transform:translate(-50%,-50%)`)}Oh(t,e),Bn=!1}function Oh(n,t){let e=Er;for(;e.firstChild;)e.removeChild(e.firstChild);let i=uc={face:[],thumb:[]},s=zt,o=(a,c,l,u)=>{let h=document.createElementNS(ns,"circle");return h.setAttribute("cx",a),h.setAttribute("cy",c),h.setAttribute("r",l),u&&h.setAttribute("fill",u),e.appendChild(h),h},r=a=>{let c=s*.18,l=s*.5,u=a.x,h=a.y,f=document.createElementNS(ns,"path");f.setAttribute("d",`M ${u-c} ${h-l} H ${u+c} V ${h-c} H ${u+l} V ${h+c} H ${u+c} V ${h+l} H ${u-c} V ${h+c} H ${u-l} V ${h-c} H ${u-c} Z`),e.appendChild(f)};for(let a=0;a<2;a++){let c=Cn(a),l=_r(a),u=Ie(a,n,t);if(Fe(a))Ci?o(u.x,u.y,s/2):r(u),i.thumb[a]=o(u.x,u.y,s/4,"#fff");else if(c===1)i.face[l]=o(u.x,u.y,s/2,"#000");else for(let h=0;h2?f:Q(f,c-1);d=d===3?2:d===2?3:d;let g=x().setDirection(f,s/2);c===2&&(g.x*=-1),a||(g.x*=-1);let b=u.add(g);i.face[l+d]=o(b.x,b.y,s/4,"#000")}}Dt&&yn&&Dh(n,t)}function Dh(n,t){let e=zt,i=Er,s=(r,a,c)=>{let l=document.createElementNS(ns,r);for(let u in a)l.setAttribute(u,a[u]);l.setAttribute("stroke",c),l.setAttribute("stroke-width",2),l.setAttribute("fill","none"),i.appendChild(l)},o=(r,a,c)=>s("circle",{cx:r.x,cy:r.y,r:a},c);s("line",{x1:n/2,y1:0,x2:n/2,y2:t},"#0f0");for(let r=0;r<2;r++)if(Fe(r))if(nn){let a=t*.4,c=!Nn(r?0:1),l=c?0:r?n/2:0;s("rect",{x:l,y:a,width:c?n:n/2,height:t-a},"#0ff")}else o(Ie(r,n,t),2*e,"#0ff");else Cn(r)>=1&&o(Ie(r,n,t),e,"#0ff");if(ae){o(x(n/2,t/2),ae,"#ff0");for(let r=0;r<2;r++)Nn(r)&&o(Ie(r,n,t),2*e,"#f0f")}}function Ih(){var l;if(!Ue||B)return;if(!tn||!Zt){Ue.style.display!=="none"&&(Ue.style.display="none",Oe.clear(),te.length=0,xn.length=0,Oi.length=0);return}Ue.style.display="";let n=Dt&&yn,t=[Un,Vn,wn,Wn,Ci,zt,nn,ae,be,n].join();t!==Sa&&(Sa=t,Bn=!0),Bn&&Lh();let e=ni?It(jn.get(),ni+1,ni):1,i=n||jn.isSet()&&e>0&&!be;if(Ue.style.opacity=i?n?1:e*pr:0,!i)return;let s=Ls(),o=s.width,r=s.height,a=zt,c=uc;if(c){for(let u=0;u<2;u++)if(Fe(u)&&c.thumb[u]){let f=Ie(u,o,r).add(((l=xn[u])!=null?l:x()).scale(a/2));c.thumb[u].setAttribute("cx",f.x),c.thumb[u].setAttribute("cy",f.y)}for(let u=0;u=zt)return-1;if(s===1)return o;let a=r.subtract(t);n||(a.x*=-1);let c=s===2?a.xo:a&&Ie(r,t,e).distance(n)<2*i)return{role:"stick",side:r}}else if(Cn(r)>=1){let c=kh(r,n,t,e);if(c>=0)return{role:"face",btn:c}}}if(ae){for(let r=0;r<2;r++)if(Nn(r)&&Ie(r,t,e).distance(n)<2*i)return;if(x(t/2,e/2).distance(n)h.getChannelData(v).set(b)),f.buffer=h,f.playbackRate.value=e,f.loop=s,r=r||dt.createGain(),r.gain.value=t,r.connect(Me);let d=new StereoPannerNode(dt,{pan:j(i,-1,1)});f.connect(d).connect(r),f.addEventListener("ended",()=>{r.disconnect(),d.disconnect(),c&&c(f)});let g=a*e;return f.start(0,g),Dt&&Gn&&mt("sound","vol",t.toFixed(2),"rate",e.toFixed(2),"pan",i.toFixed(2),s?"loop":""),f}function Jh(...n){return Pr([Os(...n)])}function Os(n=1,t=.05,e=220,i=0,s=0,o=.1,r=0,a=1,c=0,l=0,u=0,h=0,f=0,d=0,g=0,b=0,v=0,w=1,_=0,S=0,E=0){let A=qn,T=H*2,P=c*=500*T/A/A,M=e*=(1+ht(t,-t))*T/A,ct=0,nt=0,rt=0,pt=1,Mt,je=[],kt=0,ut=0,Rt=0,Te,sn=2,on=T*tt(E)*2/A,R=at(on),V=et(on)/2/sn,G=1+V,K=-2*R/G,Yt=(1-V)/G,le=(1+Kt(E)*R)/2/G,Hn=-(Kt(E)+R)/G,Xn=le,rn=0,Be=0,an=0,Di=0;for(i=i*A||9,_*=A,s*=A,o*=A,v*=A,l*=500*T/A**3,g*=T/A,u*=T/A,h*=A,f=f*A|0,Mt=i+_+s+o+v|0;ut1?r>2?r>3?r>4?kt/T%14?Rt:Kt(Rt)*tt(Rt)**a)*(utut?0:(uth&&(e+=u,M+=u,pt=0),f&&!(++nt%f)&&(e=M,c=P,pt||(pt=1));return je}function ss(n,t=!0){for(let e of Ke)if((!t||e.isSolid)&&n.arrayCheck(e.size)){let i=e.getCollisionData(n);if(i)return i}return 0}function Ve(n,t=x(),e,i=!0){for(let s of Ke)if((!i||s.isSolid)&&s.collisionTest(n,t,e))return s}function fc(n,t,e,i,s=!0){let o,r,a,c=i&&x();for(let l of Ke)if(!s||l.isSolid){let u=l.collisionRaycast(n,t,e,c);if(u){let h=n.distanceSquared(u);(o===void 0||h{k=!1,Z.style.display="none",e.preventDefault(),mt("WebGL context lost! Switching to Canvas2d rendering.");for(let i of si)i.glTexture=void 0;Ht=void 0,wt=0,vn=!1,fn.forEach(i=>{var s;return(s=i.glContextLost)==null?void 0:s.call(i)})}),Z.addEventListener("webglcontextrestored",()=>{k=!0,Z.style.display="",mt("WebGL context restored, reinitializing..."),t();for(let e of si)e.glTexture=Is(e.image,e.wrap);fn.forEach(e=>{var i;return(i=e.glContextRestored)==null?void 0:i.call(e)})});function t(){as=Jn(`#version 300 es
 precision highp float;uniform mat4 m;in vec2 g;in vec4 p,u,c,a;in float r;out vec2 v;out vec4 d,e;void main(){vec2 s=(g-.5)*p.zw;gl_Position=m*vec4(p.xy+s*cos(r)-vec2(-s.y,s)*sin(r),1,1);v=mix(u.xw,u.zy,g);d=c;e=a;}`,`#version 300 es
-precision highp float;uniform sampler2D s;in vec2 v;in vec4 d,e;out vec4 c;void main(){c=texture(s,v)*d+e;}`),fs=Xn(`#version 300 es
+precision highp float;uniform sampler2D s;in vec2 v;in vec4 d,e;out vec4 c;void main(){c=texture(s,v)*d+e;}`),cs=Jn(`#version 300 es
 precision highp float;uniform mat4 m;in vec2 p;in vec4 c;out vec4 d;void main(){gl_Position=m*vec4(p,1,1);d=c;}`,`#version 300 es
-precision highp float;in vec4 d;out vec4 c;void main(){c=d;}`);let e=new ArrayBuffer(ys);Ot=new Float32Array(e),wi=new Uint32Array(e),So=g.createBuffer(),Bn=g.createBuffer(),kr=g.createFramebuffer(),Tt=0;let i=new Float32Array([0,0,1,0,0,1,1,1]);g.bindBuffer(g.ARRAY_BUFFER,Bn),g.bufferData(g.ARRAY_BUFFER,i,g.STATIC_DRAW);let s,o,r,a=(c,l,u,h,f=0)=>{let d=g.getAttribLocation(o,c),y=u===1,x=u&&r;g.enableVertexAttribArray(d),g.vertexAttribPointer(d,h,l,y,x,s),g.vertexAttribDivisor(d,f),s+=h*u};wo=g.createVertexArray(),g.bindVertexArray(wo),s=0,o=ds,r=mc,g.bindBuffer(g.ARRAY_BUFFER,Bn),a("g",g.FLOAT,0,2),g.bindBuffer(g.ARRAY_BUFFER,So),g.bufferData(g.ARRAY_BUFFER,ys,g.DYNAMIC_DRAW),a("p",g.FLOAT,4,4,1),a("u",g.FLOAT,4,4,1),a("c",g.UNSIGNED_BYTE,1,4,1),a("a",g.UNSIGNED_BYTE,1,4,1),a("r",g.FLOAT,4,1,1),To=g.createVertexArray(),g.bindVertexArray(To),s=0,o=fs,r=bc,a("p",g.FLOAT,4,2),a("c",g.UNSIGNED_BYTE,1,4)}}function Ti(n=!1){!n&&!Cn||(Ct(),Cn=!1,g.useProgram(ds),g.bindVertexArray(wo))}function xc(){Cn||(Ct(),Cn=!0,g.useProgram(fs),g.bindVertexArray(To))}function Co(n=!0){if(!F||!g)return;p(!Tt,"glPreRender called with unflushed batch."),ps||(Z.width=k.x,Z.height=k.y),g.viewport(0,0,k.x,k.y),n&&vc();let t=b(2*q).divide(k);ps&&(t.y=-t.y);let e=At.rotate(-$),i=b(-1).subtract(e.multiply(t)),s=ot($),o=et($),r=[t.x*s,t.y*o,0,0,-t.x*o,t.y*s,0,0,1,1,1,0,i.x,i.y,0,1],a=(c,l,u)=>{g.useProgram(c);let h=g.getUniformLocation(c,l);g.uniformMatrix4fv(h,!1,u)};a(fs,"m",r),a(ds,"m",r),g.activeTexture(g.TEXTURE0),an[0]&&(Xt=an[0].glTexture,g.bindTexture(g.TEXTURE_2D,Xt)),g.bindBuffer(g.ARRAY_BUFFER,So),On=Hn=!1,Ti(!0)}function vc(){if(!g)return;let n=Ze;g.clearColor(n.r,n.g,n.b,n.a),g.clear(g.COLOR_BUFFER_BIT)}function Fr(n){!g||n===Xt||(Ct(),Xt=n,g.bindTexture(g.TEXTURE_2D,Xt))}function Sc(n,t=!0){if(!g||!n)return;let e=n===Xt;e?Ct():g.bindTexture(g.TEXTURE_2D,n);let i=t?g.REPEAT:g.CLAMP_TO_EDGE;g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_S,i),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_T,i),!e&&Xt&&g.bindTexture(g.TEXTURE_2D,Xt)}function _o(n,t){if(!g)return;let e=g.createShader(t);if(g.shaderSource(e,n),g.compileShader(e),Dt&&!g.getShaderParameter(e,g.COMPILE_STATUS))throw g.getShaderInfoLog(e);return e}function Xn(n,t){if(!g)return;let e=g.createProgram();if(g.attachShader(e,_o(n,g.VERTEX_SHADER)),g.attachShader(e,_o(t,g.FRAGMENT_SHADER)),g.linkProgram(e),Dt&&!g.getProgramParameter(e,g.LINK_STATUS))throw g.getProgramInfoLog(e);return e}function js(n,t=!1){if(!g)return;let e=g.createTexture(),i=!1;if(n!=null&&n.width)jr(e,n),g.bindTexture(g.TEXTURE_2D,e),i=!Tn&&di(n.width)&&di(n.height);else{let a=new Uint8Array([255,255,255,255]);g.bindTexture(g.TEXTURE_2D,e),g.texImage2D(g.TEXTURE_2D,0,g.RGBA,1,1,0,g.RGBA,g.UNSIGNED_BYTE,a)}let s=Tn?g.NEAREST:g.LINEAR,o=i?g.LINEAR_MIPMAP_LINEAR:s;g.texParameteri(g.TEXTURE_2D,g.TEXTURE_MAG_FILTER,s),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_MIN_FILTER,o);let r=t?g.REPEAT:g.CLAMP_TO_EDGE;return g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_S,r),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_T,r),i&&g.generateMipmap(g.TEXTURE_2D),g.bindTexture(g.TEXTURE_2D,Xt),e}function wc(n){g&&g.deleteTexture(n)}function jr(n,t){g&&(p((t==null?void 0:t.width)>0,"Invalid image data."),g.bindTexture(g.TEXTURE_2D,n),g.texImage2D(g.TEXTURE_2D,0,g.RGBA,g.RGBA,g.UNSIGNED_BYTE,t),!Tn&&di(t.width)&&di(t.height)&&g.generateMipmap(g.TEXTURE_2D),g.bindTexture(g.TEXTURE_2D,Xt))}function Hh(n){B||(ui.add(n),g&&(n.glTexture?jr(n.glTexture,n.image):n.glTexture=js(n.image,n.wrap)))}function Xh(n){if(B)return;ui.delete(n);let t=n.glTexture;n.glTexture=void 0,wc(t)}function Ct(){if(F&&g&&Tt){let n=Hn?g.ONE:g.ONE_MINUS_SRC_ALPHA;g.blendFuncSeparate(g.SRC_ALPHA,n,g.ONE,n),g.enable(g.BLEND);let t=Tt*(Cn?Fs:Gr);g.bufferSubData(g.ARRAY_BUFFER,0,Ot,0,t),Cn?g.drawArrays(g.TRIANGLE_STRIP,0,Tt):g.drawArraysInstanced(g.TRIANGLE_STRIP,0,4,Tt),++Ae,Ce+=Tt,Tt=0}Hn=On}function Nr(n){!F||!g||(Ct(),n.drawImage(Z,0,0))}function Yh(n=!0){p(!Z,"must be called before engineInit"),Mr=n}function Ai(n,t,e,i,s=0,o=0,r=0,a=1,c=1,l=-1,u=0){(Tt>=Wh||Hn!==On)&&Ct(),Ti();let h=Tt++*Gr;Ot[h++]=n,Ot[h++]=t,Ot[h++]=e,Ot[h++]=i,Ot[h++]=o,Ot[h++]=r,Ot[h++]=a,Ot[h++]=c,wi[h++]=l,wi[h++]=u,Ot[h++]=s}function Tc(n,t,e,i,s,o){Ai(n,t,e,i,s,0,0,0,0,0,o)}function Br(n,t,e,i,s,o,r,a=!0){let c=[],l=et(-r),u=ot(-r);for(let f of n){let d=f.x*s,y=f.y*o;c.push(b(e+u*d-l*y,i+l*d+u*y))}let h=a?Kh(c):c;Ac(h,t)}function zr(n,t,e,i,s,o,r,a,c=!0){let l=$h(n,e,c);Br(l,t,i,s,o,r,a,!1)}function Ac(n,t){if(!F||n.length<3)return;let e=n.length+2;if((Tt+e>=zn||Hn!==On)&&Ct(),p(e=zn)return;xc();let i=Tt*Fs;for(let s=e;s--;){let o=N(s-1,0,e-3),r=n[o];Ot[i++]=r.x,Ot[i++]=r.y,wi[i++]=t}Tt+=e}function Jr(n,t){if(!F||n.length<3)return;let e=n.length+2;if((Tt+e>=zn||Hn!==On)&&Ct(),p(e=zn)return;xc();let i=Tt*Fs;for(let s=e;s--;){let o=N(s-1,0,e-3),r=n[o],a=t[o];Ot[i++]=r.x,Ot[i++]=r.y,wi[i++]=a}Tt+=e}function oi(n,t=!1){n?(ps=n,g.bindFramebuffer(g.FRAMEBUFFER,kr),g.framebufferTexture2D(g.FRAMEBUFFER,g.COLOR_ATTACHMENT0,g.TEXTURE_2D,n,0),Co(t)):(Ct(),ps=void 0,g.bindFramebuffer(g.FRAMEBUFFER,null),g.viewport(0,0,k.x,k.y))}function Cc(n,t,e,i){F&&(g.enable(g.SCISSOR_TEST),g.scissor(n,t,e,i),g.clearColor(0,0,0,0),g.clear(g.COLOR_BUFFER_BIT),g.disable(g.SCISSOR_TEST))}function $h(n,t,e=!0){if(n.length<2)return[];let i=t/2,s=[],o=n.length,r=1e-6,a=10;for(let c=0;cr?-d/y:0,S=y>r?f/y:0,E=w>r?-v/w:0,A=w>r?x/w:0,T=_+E,P=S+A,G=(T*T+P*P)**.5;if(Gr){let dt=K(1/nt,a);T*=dt,P*=dt}}let ht=b(u.x-T*i,u.y-P*i),Q=b(u.x+T*i,u.y+P*i);s.push(ht),s.push(Q)}return s.length>1&&e&&(s.push(s[0]),s.push(s[1])),s}function Kh(n){if(n.length<3)return[];let t=(d,y,x)=>(y.x-d.x)*(x.y-d.y)-(y.y-d.y)*(x.x-d.x);(d=>{let y=0;for(let x=d.length;x--;){let v=(x+1)%d.length;y+=d[x].cross(d[v])}return y})(n)<0&&(n=n.slice().reverse());let i=1e-9,s=(d,y,x,v)=>{let w=t(y,x,d),_=t(x,v,d),S=t(v,y,d),E=(w<-i?1:0)+(_<-i?1:0)+(S<-i?1:0),A=(w>i?1:0)+(_>i?1:0)+(S>i?1:0);return!(E&&A)},o=[];for(let d=0;d3&&a++{if(E>=0){let T=i.fillStyle=i.createLinearGradient(v,w,_,S);T.addColorStop(0,h(E,2)),T.addColorStop(1,h(E,1))}else i.fillStyle="#000";E>=-1?(i.fill(),A&&i.stroke()):i.stroke()},c=(v,w,_,S=0,E=2*H,A,T)=>{i.beginPath(),i.arc(v,w,_,d*S,d*E),a(v,w-_,v,w+_,A,T)},l=(v,w,_,S,E)=>{i.beginPath(),i.rect(v,w,_,S*d),a(v,w+S,v+_,w,E)},u=(v,w,_,S)=>{i.beginPath();for(let E of v)i.lineTo(E.x,E.y);i.closePath(),a(0,_,0,_+S,w)},h=(v,w)=>w?`hsl(${[.95,.56,.13][v%3]*360} 99%${[0,50,75][w]}%)`:"#000",f=Wa(1,1,n),d=It(f,.1,.5),y=K(6,K(o,r)/99);i.translate(o/2,r/2),i.scale(y,y),i.translate(-40,-35),d<1&&i.setLineDash([99*d,99]),i.lineJoin=i.lineCap="round",i.lineWidth=.1+d*1.9;{let w="LittleJS";i.font="900 15.5px arial",i.lineWidth=.1+d*3.9,i.textAlign="center",i.textBaseline="top",l(11,55,59,8*d,-1),i.beginPath();let _=0;for(let S=0;S5?1:0),i[S?"strokeText":"fillText"](w[E],P,54+.5,17*d),A+=T}i.lineWidth=.1+d*1.9,l(3,54,73,0)}l(7,15,26,-7,0),l(25,15,8,25,-1),l(10,40,15,-25,1),l(14,21,7,9,2),l(38,20,6,-6,2),l(49,20,10,-6,0);let x=[b(44,8),b(64,8),b(59,8+6*d),b(49,8+6*d)];u(x,2,8,6*d),l(44,8,20,-7,0);for(let v=5;v--;)c(59-v*6*d,30,10,0,2*H,1,0);c(59,30,4,0,7,2),l(35,20,24,0),c(59,30,10),c(47,30,10,H/2,H*3/2),c(35,30,10,H/2,H*3/2),l(7,40,13,7,-1),l(17,40,43,14,-1);for(let v=3;v--;)for(let w=2;w--;)c(17+15*v,47,w?7:1,0,2*H,2);for(let v=2;v--;){let w=6,_=7,S=53+w*d*v,E=[b(S+_,54),b(S,40),b(S+w*d,40),b(S+_+w*d,54)];u(E,0,40,14)}i.restore()}function Zh(n){if(bs=n,!fn){let e={};try{e=JSON.parse(localStorage[n]||"{}")}catch{e={}}Ns(i=>{i.unlocked=!!(e[i.id]&&e[i.id].unlocked)}),Vr()}_n(void 0,t);function t(){if(!qi.length)return;let e=qi[0],i=sn-Wi;if(!Wi)Wi=sn;else if(i>gs)Wi=0,qi.shift();else{let s=gs-jn,o=is?(i-s)/jn:0;e.render(o)}}}function Ns(n){Object.values(Ci).forEach(t=>n(t))}function td(){Ns(n=>n.unlocked=!1),Vr()}function Vr(){if(!bs)return;let n={};Ns(t=>{let e={name:t.name,description:t.description,icon:t.icon,unlocked:t.unlocked};t.image&&(e.src=t.image.src),n[t.id]=e}),localStorage[bs]=JSON.stringify(n)}function ed(n){gs=n}function nd(n){jn=n}function id(n){ms=n.copy()}function sd(n){Ur=n}function _c(n,t,e,i=125){let s,o,r,a,c,l,u,h,f,d,y,x,v,w=0,_,S=[],E=[],A=[],T=0,P=0,G=1,ht={},Q=Qn/i*60>>2;for(;G;T++)S=[G=h=x=0],e.forEach((nt,dt)=>{for(u=t[nt][T]||[0,0,0],G|=t[nt][T]&&1,_=x+(t[nt][0].length-2-(h?0:1))*Q,v=dt===e.length-1,s=2,r=x;sQ-99&&f&&y<1?y+=1/99:0)l=(1-y)*S[w++]/2||0,E[r]=(E[r]||0)-l*P+l,A[r]=(A[r++]||0)+l*P+l;c&&(y=c%1,P=u[1]||0,(c|=0)&&(S=ht[[d=u[w=0]||0,c]]=ht[[d,c]]||(a=[...n[d]],a[2]=(a[2]||220)*2**(c/12-1),c>0?Gs(...a):[])))}x=_});return[E,A]}function od(n){Wr=typeof n=="boolean"?n?1:0:n}function rd(n){qr=n}async function ad(){return new As(await Box2D()),e(),_n(n,t),m;function n(){if(!we){m.step(),m.objects=m.objects.filter(i=>!i.destroyed);for(let i of m.objects)i.body&&(i.pos=m.vec2From(i.body.GetPosition()),i.angle=-i.body.GetAngle())}}function t(){(qr||ae)&&m.world.DrawDebugData()}function e(){let s=new m.instance.JSDraw,o=l=>new St(l.get_r(),l.get_g(),l.get_b()),r=l=>o(m.instance.wrapPointer(l,m.instance.b2Color)),a=l=>r(l).scale(1,.8),c=(l,u)=>{let h=[];for(let f=u;f--;)h.push(m.vec2FromPointer(l+f*8));return h};s.DrawSegment=function(l,u,h){h=a(h),l=m.vec2FromPointer(l),u=m.vec2FromPointer(u),mn(l,u,.1,h,b(),0,!1)},s.DrawPolygon=function(l,u,h){h=a(h);let f=c(l,u);Un(f,on,.1,h,b(),0,!1)},s.DrawSolidPolygon=function(l,u,h){h=a(h);let f=c(l,u);Un(f,h,0,h,b(),0,!1)},s.DrawCircle=function(l,u,h){h=a(h),l=m.vec2FromPointer(l),is(l,u*2,on,.1,h,!1)},s.DrawSolidCircle=function(l,u,h,f){f=a(f),l=m.vec2FromPointer(l),h=m.vec2FromPointer(h).scale(u),is(l,u*2,f,.1,f,!1),mn(b(),h,.1,f,l,0,!1)},s.DrawTransform=function(l){l=m.instance.wrapPointer(l,m.instance.b2Transform);let u=m.vec2From(l.get_p()),h=-l.get_q().GetAngle(),f=b(1,0),d=z(.75,0,0,.8),y=b(0,1),x=z(0,.75,0,.8);mn(b(),f,.1,d,u,h,!1),mn(b(),y,.1,x,u,h,!1)},s.AppendFlags(m.instance.b2Draw.e_shapeBit),s.AppendFlags(m.instance.b2Draw.e_jointBit),m.world.SetDebugDraw(s)}}function cd(n,t,e,i=32,s=2,o=0){Ec(n,t,e,V,i,it,s,o,!1,!0)}function Ec(n,t,e,i,s=1,o,r=.05,a=0,c=F,l,u){let h=e.offset(e.size),f=t.add(b(r-s*2)),d=b(s),y=t.scale(.5).subtract(d.scale(.5)),x=l?-1:1,v=l?-a:a;Rt(n,f,h,i,a,!1,o,c,l,u);for(let w=4;w--;){let _=w%2,S=y.multiply(b(_?w===1?1:-1:0,_?0:w?-1:1)),E=b(_?s:f.x,_?f.y:s),A=h.offset(e.size.multiply(b(w===1?1:w===3?-1:0,w===0?-x:w===2?x:0)));Rt(n.add(S.rotate(v)),E,A,i,a,!1,o,c,l,u)}for(let w=4;w--;){let _=w>1,S=w&&w<3,E=y.multiply(b(_?-1:1,S?-1:1)),A=h.offset(e.size.multiply(b(_?-1:1,S?x:-x)));Rt(n.add(E.rotate(v)),d,A,i,a,!1,o,c,l,u)}}function ld(n,t,e,i=32,s=2,o=0){Rc(n,t,e,V,i,it,s,o,!1,!0)}function Rc(n,t,e,i,s=1,o,r=.05,a=0,c=F,l,u){let h=e.frame(0),f=e.frame(1),d=e.frame(2),y=t.add(b(r-s*2)),x=b(s),v=t.scale(.5).subtract(x.scale(.5)),w=l?-1:1,_=l?-a:a;Rt(n,y,d,i,a,!1,o,c,l,u);for(let S=4;S--;){let E=a+S*H/2,A=S%2,T=v.multiply(b(A?S===1?1:-1:0,A?0:S?-w:w)),P=b(A?y.y:y.x,s);Rt(n.add(T.rotate(_)),P,f,i,E,!1,o,c,l,u)}for(let S=4;S--;){let E=a+S*H/2,A=!S||S>2,T=S>1,P=v.multiply(b(A?-1:1,T?-w:w));Rt(n.add(P.rotate(_)),x,h,i,E,!1,o,c,l,u)}}function ud(n,t=1,e=0,i=V,s=0,o=!1,r=0,a=it,c=F,l=!1,u){let h=Pc(b(),t,e,0,o);Un(h,i,r,a,n,s,c,l,u)}function Pc(n,t=1,e=0,i=0,s=!1,o=Li){p(O(n),"pos must be a vec2"),p(L(t)&&L(e),"size and percent must be numbers");let r=Zt(e*4,4);r>=2&&(i+=H),r=r<=2?r-1:3-r,s&&(r=-r,i+=H);let a=[],c=Y(3,o>>1),l=t/2;for(let u=0;u<=c;u++){let h=u/c*H;a.push(b(l*ot(h),l*et(h)).rotate(i).add(n))}for(let u=c;u>=0;u--){let h=u/c*H;a.push(b(l*ot(h),-l*r*et(h)).rotate(i).add(n))}return a}function La(n){return n&&typeof n.lerp=="function"}function hd(n,t,e,i,s=1,o={}){p(n!=null&&typeof n=="object","tweenProperty target must be an object"),p(U(t)&&t.length>0,"tweenProperty propertyPath must be a non-empty string");let r=t.split("."),a=r.pop(),c=l=>{let u=n;for(let h of r)u=u[h];u[a]=l};return new Cs(c,e,i,s,o)}function Lc(n){n.loopRemaining!==1/0&&n.loopRemaining<=1||(n.loopRemaining!==1/0&&(n.loopRemaining-=1),n.life=n.duration,n.thenCallback=()=>Lc(n),qt.push(n),n.callback(n.interp(n.duration)))}function Oc(n){if(n.loopRemaining!==1/0&&n.loopRemaining<=1)return;n.loopRemaining!==1/0&&(n.loopRemaining-=1);let t=n.start;n.start=n.end,n.end=t,n.life=n.duration,n.thenCallback=()=>Oc(n),qt.push(n),n.callback(n.interp(n.duration))}function Dc(n,t){n===void 0?(n=Ht-Ra,t=sn-Pa,Ra=Ht,Pa=sn):t===void 0&&(t=n);for(let e=qt.length;e--;){let i=qt[e];if(i.paused)continue;let s=i.useRealTime?t:n;if(!(s<=0))if(i.life-=s,i.life>0)i.callback(i.interp(i.life));else{i.callback(i.interp(0)),qt.splice(e,1);let o=i.thenCallback;i.thenCallback=void 0,o&&o()}}}function dd(){for(let n of qt)n.thenCallback=void 0;qt.length=0}var Hi,Xi,_l,tr,mt,er,Oa,Ht,sn,we,ao,ge,Yi,Da,bn,uo,Dt,ka,Rs,Ga,Ie,Qe,ae,ce,xn,vn,Jn,ho,Me,re,H,tt,vt,hi,$i,K,Y,Qt,Ba,za,et,ot,Ja,ir,yo,st,St,V,on,it,he,Vl,rr,Wl,Ka,Qa,ql,Za,tc,Hl,Te,At,$,q,cr,Ps,Ze,Mn,ri,kn,Gn,lr,Tn,tn,Pi,ur,B,F,Li,Ls,Os,Ds,Is,hr,dr,fr,pr,yr,Ge,Nt,Zi,Ms,gr,ai,gn,rn,mr,ue,Yn,En,$n,Kn,Oi,cn,zt,br,ci,ts,Di,Jt,Sn,xr,vr,Je,j,at,wt,Ne,$e,xe,Fe,k,an,Ae,Ce,_e,Ue,nh,lc,ss,Oe,Ft,Tr,me,Ar,os,Nn,Ke,Cr,Fn,pt,te,X,be,pn,co,Vn,ee,An,rs,Fi,je,Xe,dc,Lr,fc,mi,yn,Wn,Aa,as,ut,ze,Qn,xi,cs,nn,wn,us,vi,Si,vo,Vh,hs,Z,g,Mr,ds,fs,Cn,On,Hn,Xt,So,Bn,Ot,wi,Tt,ui,wo,To,kr,ps,Ao,ys,Gr,mc,Wh,Fs,bc,zn,fn,gs,jn,ms,Ur,Ci,qi,bs,Wi,xs,_i,Eo,Ro,Pt,Po,W,Lo,Oo,Do,C,Wr,Io,ne,vs,Mo,ko,Ei,Go,Fo,jo,No,m,qr,Ri,Ss,Bo,zo,ws,Ut,Jo,Ts,Uo,Vo,Wo,qo,Ho,Xo,Yo,$o,Ko,Qo,As,qt,Ra,Pa,Cs,_s,fd,lo,Es,Zo,Mc=jc(()=>{"use strict";Hi="LittleJS",Xi="1.18.19",_l=60,tr=.016666666666666666,mt=[],er=[],Oa=0,Ht=0,sn=0,we=!1;ao=0,ge=0,Yi=0,Da=!0,bn=[],uo=class{constructor(t,e,i,s){this.update=t,this.render=e,this.glContextLost=i,this.glContextRestored=s}};Dt=!0,ka=.5,Rs=!0,Ga="Escape",Ie=!1,Qe=[],ae=!1,ce=!1,xn=!1,vn=!1,Jn=!1;H=Math.PI,tt=Math.abs,vt=Math.floor,hi=Math.ceil,$i=Math.round,K=Math.min,Y=Math.max,Qt=n=>Math.sign(n),Ba=(...n)=>Math.hypot(...n),za=n=>Math.log2(n),et=Math.sin,ot=Math.cos,Ja=Math.tan,ir=Math.atan2;yo=class{constructor(t=123456789){p(t!==0,"RandomGenerator seed must be non-zero (xorshift is fixed at 0)"),this.seed=t}float(t=1,e=0){return this.seed^=this.seed<<13,this.seed^=this.seed>>>17,this.seed^=this.seed<<5,e+(t-e)*((this.seed>>>0)/2**32)}int(t,e=0){return vt(this.float(t,e))}bool(t=.5){return this.float().5?1:-1}floatSign(t=1,e=0){let i=K(t,e),o=Y(t,e)-i,r=this.float(o*2);return rt?this.scale(t/e):this.copy()}dot(t){return this.x*t.x+this.y*t.y}cross(t){return this.x*t.y-this.y*t.x}reflect(t,e=1){return this.subtract(t.scale((1+e)*this.dot(t)))}angle(){return ir(this.x,this.y)}setAngle(t=0,e=1){return Wt(t),Wt(e),this.x=e*et(t),this.y=e*ot(t),this}rotate(t){Wt(t);let e=ot(-t),i=et(-t);return new n(this.x*e-this.y*i,this.x*i+this.y*e)}setDirection(t,e=1){return Wt(t),Wt(e),t=Zt(t,4),p(t===0||t===1||t===2||t===3,"Vector2.setDirection() direction must be an integer between 0 and 3."),this.x=t%2?t-1?-e:e:0,this.y=t%2?0:t?-e:e,this}direction(){return tt(this.x)>tt(this.y)?this.x<0?3:1:this.y<0?2:0}abs(){return new n(tt(this.x),tt(this.y))}floor(){return new n(vt(this.x),vt(this.y))}snap(t){return Wt(t),new n(vt(this.x*t)/t,vt(this.y*t)/t)}mod(t=1){return new n(Zt(this.x,t),Zt(this.y,t))}area(){return tt(this.x*this.y)}lerp(t,e){wa(t),Wt(e);let i=N(e);return new n(t.x*i+this.x*(1-i),t.y*i+this.y*(1-i))}arrayCheck(t){return this.x>=0&&this.y>=0&&this.x(u=Zt(u,1))*6<1?c+(l-c)*6*u:u*2<1?l:u*3<2?c+(l-c)*(4-u*6):c;return this.r=a(r,o,t+1/3),this.g=a(r,o,t),this.b=a(r,o,t-1/3),this.a=s,si(this),this}HSLA(){let t=N(this.r),e=N(this.g),i=N(this.b),s=N(this.a),o=Y(t,e,i),r=K(t,e,i),a=(o+r)/2,c=0,l=0;if(o!==r){let u=o-r;l=a>.5?u/(2-o-r):u/(o+r),t===o?c=(e-i)/u+(e((i=N(i)*255|0)<16?"0":"")+i.toString(16);return"#"+e(this.r)+e(this.g)+e(this.b)+(t?e(this.a):"")}setHex(t){if(p(U(t),"Color hex code must be a string"),p(t[0]==="#","Color hex code must start with #"),p([4,5,7,9].includes(t.length),"Invalid hex"),t.length<6){let e=i=>N(parseInt(t[i],16)/15);this.r=e(1),this.g=e(2),this.b=e(3),this.a=t.length===5?e(4):1}else{let e=i=>N(parseInt(t.slice(i,i+2),16)/255);this.r=e(1),this.g=e(3),this.b=e(5),this.a=t.length===9?e(7):1}return si(this),this}rgbaInt(){let t=N(this.r)*255|0,e=N(this.g)*255<<8,i=N(this.b)*255<<16,s=N(this.a)*255<<24;return t+e+i+s}isValid(){return L(this.r)&&L(this.g)&&L(this.b)&&L(this.a)}},V=Yt(z()),on=Yt(z(1,1,1,0)),it=Yt(z(0,0,0)),he=Yt(z(0,0,0,0)),Vl=Yt(z(.5,.5,.5)),rr=Yt(z(1,0,0)),Wl=Yt(z(1,.5,0)),Ka=Yt(z(1,1,0)),Qa=Yt(z(0,1,0)),ql=Yt(z(0,1,1)),Za=Yt(z(0,0,1)),tc=Yt(z(.5,0,1)),Hl=Yt(z(1,0,1)),Te=class{constructor(t,e=!1){p(t===void 0||L(t),"Constructed Timer is invalid.",t),this.useRealTime=e;let i=this.getGlobalTime();this.time=t===void 0?void 0:i+t,this.setTime=t}set(t=0){p(L(t),"Timer is invalid.",t);let e=this.getGlobalTime();this.time=e+t,this.setTime=t}setUseRealTime(t=!0){p(!this.isSet(),"Cannot change global time setting while timer is set."),this.useRealTime=t}unset(){this.time=void 0}isSet(){return this.time!==void 0}active(){return this.getGlobalTime()=this.time}get(){return this.isSet()?this.getGlobalTime()-this.time:0}getPercent(){return this.isSet()?this.setTime?1-It(this.time-this.getGlobalTime(),0,this.setTime):1:0}getSetTime(){return this.isSet()?this.setTime:0}getGlobalTime(){return this.useRealTime?sn:Ht}toString(){return this.isSet()?tt(this.get())+" seconds "+(this.get()<0?"before":"after"):"unset"}valueOf(){return this.get()}};At=b(),$=0,q=32,cr=1,Ps=!0,Ze=he,Mn=b(1920,1080),ri=0,kn=0,Gn=b(),lr=!1,Tn=!0,tn=1,Pi="arial",ur=!1,B=!1,F=!0,Li=32,Ls=b(16),Os=0,Ds=0,Is=!0,hr=1,dr=1,fr=1,pr=0,yr=.8,Ge=1,Nt=b(),Zi=1,Ms=!0,gr=!0,ai=!0,gn=!0,rn=!1,mr=!1,ue=0,Yn=4,En=!0,$n=0,Kn=!1,Oi=!0,cn=!1,zt=100,br=.3,ci=3,ts=0,Di=!0,Jt=!0,Sn=.3,xr=40,vr=.7;Je=class n{constructor(t=b(),e=b(1),i,s=0,o=V,r=0){p(O(t),"object pos must be a vec2"),p(O(e),"object size must be a vec2"),p(!i||i instanceof _e,"object tileInfo should be a TileInfo or undefined"),p(typeof s=="number"&&isFinite(s),"object angle should be a number"),p(J(o),"object color should be a valid rgba color"),p(typeof r=="number","object renderOrder should be a number"),this.pos=t.copy(),this.size=e.copy(),this.drawSize=void 0,this.tileInfo=i,this.angle=s,this.color=o.copy(),this.additiveColor=void 0,this.mirror=!1,this.destroyed=!1,this.mass=hr,this.damping=dr,this.angleDamping=fr,this.restitution=pr,this.friction=yr,this.gravityScale=1,this.renderOrder=r,this.velocity=b(),this.angleVelocity=0,this.spawnTime=Ht,this.children=[],this.clampSpeed=!0,this.groundObject=void 0,this.parent=void 0,this.localPos=b(),this.localAngle=0,this.collideTiles=!1,this.collideSolidObjects=!1,this.isSolid=!1,this.collideRaycast=!1,mt.push(this)}updateTransforms(){let t=this.parent;if(t){let e=t.getMirrorSign(),i=this.localPos,s=t.pos,o=i.x*e,r=i.y,a=t.angle;if(a){let c=ot(-a),l=et(-a);this.pos.set(o*c-r*l+s.x,o*l+r*c+s.y)}else this.pos.set(o+s.x,r+s.y);this.angle=e*this.localAngle+a}for(let e of this.children)e.updateTransforms()}updatePhysics(){if(p(!this.parent),this.destroyed)return;this.clampSpeed&&(this.velocity.x=N(this.velocity.x,-Ge,Ge),this.velocity.y=N(this.velocity.y,-Ge,Ge));let t=this.pos.copy();if(this.velocity.x*=this.damping,this.velocity.y*=this.damping,this.mass&&(this.velocity.x+=Nt.x*this.gravityScale,this.velocity.y+=Nt.y*this.gravityScale),this.pos.x+=this.velocity.x,this.pos.y+=this.velocity.y,this.angle+=this.angleVelocity*=this.angleDamping,p(this.angleDamping>=0&&this.angleDamping<=1),p(this.damping>=0&&this.damping<=1),!Is||!this.mass)return;let e=this.velocity.y<0&&Nt.y<0||this.velocity.y>0&&Nt.y>0;if(this.groundObject){let i=Y(this.friction,this.groundObject.friction),s=this.groundObject.velocity.x;this.velocity.x=s+(this.velocity.x-s)*i,this.groundObject=void 0}if(this.collideSolidObjects)for(let s of er){if(s.destroyed||s.parent||s===this||!this.isSolid&&!s.isSolid||!this.isOverlappingObject(s))continue;let o=this.collideWithObject(s),r=s.collideWithObject(this);if(!o||!r)continue;if(Qi(t,this.size,s.pos,s.size)){let f=t.subtract(s.pos),d=f.length(),x=d<.001?b(0,1):f.scale(.001/d);this.velocity=this.velocity.add(x),s.mass&&(s.velocity=s.velocity.subtract(x)),ae&&fo(this.pos,this.size,s.pos,s.size,"#f00");continue}let a=this.size.add(s.size),c=(t.y-s.pos.y)*2>a.y+Nt.y,l=tt(t.y-s.pos.y)*20?-1:1)>0?vt(t.y-this.size.y/2+1)+this.size.y/2+.001:hi(t.y+this.size.y/2-1)-this.size.y/2-.001;if(tt(u-this.pos.y)<.1&&!Ye(b(this.pos.x,u),this.size,this)){this.pos.y=u,ae&&yt(this.pos,this.size,"#ff0");return}this.pos.x=t.x,this.velocity.x*=-r}if(o||!s){if(e){let c=this.size.y/2+1e-4;this.pos.y=Nt.y<0?vt(t.y-this.size.y/2)+c:hi(t.y+this.size.y/2)-c,this.groundObject=i}else this.pos.y=t.y,this.groundObject=void 0;this.velocity.y*=-r}ae&&yt(this.pos,this.size,"#f00")}}}update(){}render(){Rt(this.pos,this.drawSize||this.size,this.tileInfo,this.color,this.angle,this.mirror,this.additiveColor)}renderLight(){}destroy(t=!1){var e;if(!this.destroyed){this.destroyed=!0,(e=this.parent)==null||e.removeChild(this);for(let i of this.children)i.parent=void 0,i.destroy(t)}}localToWorld(t){return this.pos.add(t.rotate(this.angle))}worldToLocal(t){return t.subtract(this.pos).rotate(-this.angle)}localToWorldVector(t){return t.rotate(this.angle)}worldToLocalVector(t){return t.rotate(-this.angle)}collideWithTile(t,e){return t>0}collideWithObject(t){return!0}getUp(t=1){return b().setAngle(this.angle,t)}getRight(t=1){return b().setAngle(this.angle+H/2,t)}getAliveTime(){return Ht-this.spawnTime}getSpeed(){return this.velocity.length()}applyAcceleration(t){this.mass&&(this.velocity=this.velocity.add(t))}applyAngularAcceleration(t){this.mass&&(this.angleVelocity+=t)}applyForce(t){this.mass&&this.applyAcceleration(t.scale(1/this.mass))}getMirrorSign(){return this.mirror?-1:1}addChild(t,e=b(),i=0){return p(!this.destroyed,"cannot add child to destroyed object"),this.destroyed||(p(!t.parent&&!this.children.includes(t)),p(t instanceof n,"child must be an EngineObject"),p(t!==this,"cannot add self as child"),this.children.push(t),t.parent=this,t.localPos=e.copy(),t.localAngle=i,t.updateTransforms()),t}removeChild(t){p(t.parent===this&&this.children.includes(t)),this.children.splice(this.children.indexOf(t),1),t.parent=void 0}isOverlappingObject(t){return this.isOverlapping(t.pos,t.size)}isOverlapping(t,e=b()){return Qi(this.pos,this.size,t,e)}setCollision(t=!0,e=!0,i=!0,s=!0){p(t||!e,"solid objects must be set to collide"),this.collideSolidObjects=t,this.isSolid=e,this.collideTiles=i,this.collideRaycast=s}toString(){let t="type = "+this.constructor.name;return(this.pos.x||this.pos.y)&&(t+=`
+precision highp float;in vec4 d;out vec4 c;void main(){c=d;}`);let e=new ArrayBuffer(us);Ot=new Float32Array(e),gi=new Uint32Array(e),mo=y.createBuffer(),Mn=y.createBuffer(),Or=y.createFramebuffer(),wt=0;let i=new Float32Array([0,0,1,0,0,1,1,1]);y.bindBuffer(y.ARRAY_BUFFER,Mn),y.bufferData(y.ARRAY_BUFFER,i,y.STATIC_DRAW);let s,o,r,a=(c,l,u,h,f=0)=>{let d=y.getAttribLocation(o,c),g=u===1,b=u&&r;y.enableVertexAttribArray(d),y.vertexAttribPointer(d,h,l,g,b,s),y.vertexAttribDivisor(d,f),s+=h*u};bo=y.createVertexArray(),y.bindVertexArray(bo),s=0,o=as,r=pc,y.bindBuffer(y.ARRAY_BUFFER,Mn),a("g",y.FLOAT,0,2),y.bindBuffer(y.ARRAY_BUFFER,mo),y.bufferData(y.ARRAY_BUFFER,us,y.DYNAMIC_DRAW),a("p",y.FLOAT,4,4,1),a("u",y.FLOAT,4,4,1),a("c",y.UNSIGNED_BYTE,1,4,1),a("a",y.UNSIGNED_BYTE,1,4,1),a("r",y.FLOAT,4,1,1),xo=y.createVertexArray(),y.bindVertexArray(xo),s=0,o=cs,r=yc,a("p",y.FLOAT,4,2),a("c",y.UNSIGNED_BYTE,1,4)}}function mi(n=!1){!n&&!vn||(At(),vn=!1,y.useProgram(as),y.bindVertexArray(bo))}function gc(){vn||(At(),vn=!0,y.useProgram(cs),y.bindVertexArray(xo))}function So(n=!0){if(!k||!y)return;p(!wt,"glPreRender called with unflushed batch."),ls||(Z.width=I.x,Z.height=I.y),y.viewport(0,0,I.x,I.y),n&&mc();let t=x(2*q).divide(I);ls&&(t.y=-t.y);let e=Tt.rotate(-$),i=x(-1).subtract(e.multiply(t)),s=at($),o=et($),r=[t.x*s,t.y*o,0,0,-t.x*o,t.y*s,0,0,1,1,1,0,i.x,i.y,0,1],a=(c,l,u)=>{y.useProgram(c);let h=y.getUniformLocation(c,l);y.uniformMatrix4fv(h,!1,u)};a(cs,"m",r),a(as,"m",r),y.activeTexture(y.TEXTURE0),en[0]&&(Ht=en[0].glTexture,y.bindTexture(y.TEXTURE_2D,Ht)),y.bindBuffer(y.ARRAY_BUFFER,mo),En=zn=!1,mi(!0)}function mc(){if(!y)return;let n=Xe;y.clearColor(n.r,n.g,n.b,n.a),y.clear(y.COLOR_BUFFER_BIT)}function Ir(n){!y||n===Ht||(At(),Ht=n,y.bindTexture(y.TEXTURE_2D,Ht))}function bc(n,t=!0){if(!y||!n)return;let e=n===Ht;e?At():y.bindTexture(y.TEXTURE_2D,n);let i=t?y.REPEAT:y.CLAMP_TO_EDGE;y.texParameteri(y.TEXTURE_2D,y.TEXTURE_WRAP_S,i),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_WRAP_T,i),!e&&Ht&&y.bindTexture(y.TEXTURE_2D,Ht)}function wo(n,t){if(!y)return;let e=y.createShader(t);if(y.shaderSource(e,n),y.compileShader(e),Dt&&!y.getShaderParameter(e,y.COMPILE_STATUS))throw y.getShaderInfoLog(e);return e}function Jn(n,t){if(!y)return;let e=y.createProgram();if(y.attachShader(e,wo(n,y.VERTEX_SHADER)),y.attachShader(e,wo(t,y.FRAGMENT_SHADER)),y.linkProgram(e),Dt&&!y.getProgramParameter(e,y.LINK_STATUS))throw y.getProgramInfoLog(e);return e}function Is(n,t=!1){if(!y)return;let e=y.createTexture(),i=!1;if(n!=null&&n.width)Mr(e,n),y.bindTexture(y.TEXTURE_2D,e),i=!bn&&ri(n.width)&&ri(n.height);else{let a=new Uint8Array([255,255,255,255]);y.bindTexture(y.TEXTURE_2D,e),y.texImage2D(y.TEXTURE_2D,0,y.RGBA,1,1,0,y.RGBA,y.UNSIGNED_BYTE,a)}let s=bn?y.NEAREST:y.LINEAR,o=i?y.LINEAR_MIPMAP_LINEAR:s;y.texParameteri(y.TEXTURE_2D,y.TEXTURE_MAG_FILTER,s),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_MIN_FILTER,o);let r=t?y.REPEAT:y.CLAMP_TO_EDGE;return y.texParameteri(y.TEXTURE_2D,y.TEXTURE_WRAP_S,r),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_WRAP_T,r),i&&y.generateMipmap(y.TEXTURE_2D),y.bindTexture(y.TEXTURE_2D,Ht),e}function xc(n){y&&y.deleteTexture(n)}function Mr(n,t){y&&(p((t==null?void 0:t.width)>0,"Invalid image data."),y.bindTexture(y.TEXTURE_2D,n),y.texImage2D(y.TEXTURE_2D,0,y.RGBA,y.RGBA,y.UNSIGNED_BYTE,t),!bn&&ri(t.width)&&ri(t.height)&&y.generateMipmap(y.TEXTURE_2D),y.bindTexture(y.TEXTURE_2D,Ht))}function Hh(n){B||(si.add(n),y&&(n.glTexture?Mr(n.glTexture,n.image):n.glTexture=Is(n.image,n.wrap)))}function Xh(n){if(B)return;si.delete(n);let t=n.glTexture;n.glTexture=void 0,xc(t)}function At(){if(k&&y&&wt){let n=zn?y.ONE:y.ONE_MINUS_SRC_ALPHA;y.blendFuncSeparate(y.SRC_ALPHA,n,y.ONE,n),y.enable(y.BLEND);let t=wt*(vn?Ds:Dr);y.bufferSubData(y.ARRAY_BUFFER,0,Ot,0,t),vn?y.drawArrays(y.TRIANGLE_STRIP,0,wt):y.drawArraysInstanced(y.TRIANGLE_STRIP,0,4,wt),++ve,Se+=wt,wt=0}zn=En}function kr(n){!k||!y||(At(),n.drawImage(Z,0,0))}function Yh(n=!0){p(!Z,"must be called before engineInit"),Lr=n}function bi(n,t,e,i,s=0,o=0,r=0,a=1,c=1,l=-1,u=0){(wt>=Wh||zn!==En)&&At(),mi();let h=wt++*Dr;Ot[h++]=n,Ot[h++]=t,Ot[h++]=e,Ot[h++]=i,Ot[h++]=o,Ot[h++]=r,Ot[h++]=a,Ot[h++]=c,gi[h++]=l,gi[h++]=u,Ot[h++]=s}function vc(n,t,e,i,s,o){bi(n,t,e,i,s,0,0,0,0,0,o)}function Gr(n,t,e,i,s,o,r,a=!0){let c=[],l=et(-r),u=at(-r);for(let f of n){let d=f.x*s,g=f.y*o;c.push(x(e+u*d-l*g,i+l*d+u*g))}let h=a?Kh(c):c;Sc(h,t)}function Fr(n,t,e,i,s,o,r,a,c=!0){let l=$h(n,e,c);Gr(l,t,i,s,o,r,a,!1)}function Sc(n,t){if(!k||n.length<3)return;let e=n.length+2;if((wt+e>=kn||zn!==En)&&At(),p(e=kn)return;gc();let i=wt*Ds;for(let s=e;s--;){let o=j(s-1,0,e-3),r=n[o];Ot[i++]=r.x,Ot[i++]=r.y,gi[i++]=t}wt+=e}function jr(n,t){if(!k||n.length<3)return;let e=n.length+2;if((wt+e>=kn||zn!==En)&&At(),p(e=kn)return;gc();let i=wt*Ds;for(let s=e;s--;){let o=j(s-1,0,e-3),r=n[o],a=t[o];Ot[i++]=r.x,Ot[i++]=r.y,gi[i++]=a}wt+=e}function Zn(n,t=!1){n?(ls=n,y.bindFramebuffer(y.FRAMEBUFFER,Or),y.framebufferTexture2D(y.FRAMEBUFFER,y.COLOR_ATTACHMENT0,y.TEXTURE_2D,n,0),So(t)):(At(),ls=void 0,y.bindFramebuffer(y.FRAMEBUFFER,null),y.viewport(0,0,I.x,I.y))}function wc(n,t,e,i){k&&(y.enable(y.SCISSOR_TEST),y.scissor(n,t,e,i),y.clearColor(0,0,0,0),y.clear(y.COLOR_BUFFER_BIT),y.disable(y.SCISSOR_TEST))}function $h(n,t,e=!0){if(n.length<2)return[];let i=t/2,s=[],o=n.length,r=1e-6,a=10;for(let c=0;cr?-d/g:0,S=g>r?f/g:0,E=w>r?-v/w:0,A=w>r?b/w:0,T=_+E,P=S+A,M=(T*T+P*P)**.5;if(Mr){let pt=Q(1/rt,a);T*=pt,P*=pt}}let ct=x(u.x-T*i,u.y-P*i),nt=x(u.x+T*i,u.y+P*i);s.push(ct),s.push(nt)}return s.length>1&&e&&(s.push(s[0]),s.push(s[1])),s}function Kh(n){if(n.length<3)return[];let t=(d,g,b)=>(g.x-d.x)*(b.y-d.y)-(g.y-d.y)*(b.x-d.x);(d=>{let g=0;for(let b=d.length;b--;){let v=(b+1)%d.length;g+=d[b].cross(d[v])}return g})(n)<0&&(n=n.slice().reverse());let i=1e-9,s=(d,g,b,v)=>{let w=t(g,b,d),_=t(b,v,d),S=t(v,g,d),E=(w<-i?1:0)+(_<-i?1:0)+(S<-i?1:0),A=(w>i?1:0)+(_>i?1:0)+(S>i?1:0);return!(E&&A)},o=[];for(let d=0;d3&&a++{if(E>=0){let T=i.fillStyle=i.createLinearGradient(v,w,_,S);T.addColorStop(0,h(E,2)),T.addColorStop(1,h(E,1))}else i.fillStyle="#000";E>=-1?(i.fill(),A&&i.stroke()):i.stroke()},c=(v,w,_,S=0,E=2*H,A,T)=>{i.beginPath(),i.arc(v,w,_,d*S,d*E),a(v,w-_,v,w+_,A,T)},l=(v,w,_,S,E)=>{i.beginPath(),i.rect(v,w,_,S*d),a(v,w+S,v+_,w,E)},u=(v,w,_,S)=>{i.beginPath();for(let E of v)i.lineTo(E.x,E.y);i.closePath(),a(0,_,0,_+S,w)},h=(v,w)=>w?`hsl(${[.95,.56,.13][v%3]*360} 99%${[0,50,75][w]}%)`:"#000",f=Ja(1,1,n),d=It(f,.1,.5),g=Q(6,Q(o,r)/99);i.translate(o/2,r/2),i.scale(g,g),i.translate(-40,-35),d<1&&i.setLineDash([99*d,99]),i.lineJoin=i.lineCap="round",i.lineWidth=.1+d*1.9;{let w="LittleJS";i.font="900 15.5px arial",i.lineWidth=.1+d*3.9,i.textAlign="center",i.textBaseline="top",l(11,55,59,8*d,-1),i.beginPath();let _=0;for(let S=0;S5?1:0),i[S?"strokeText":"fillText"](w[E],P,54+.5,17*d),A+=T}i.lineWidth=.1+d*1.9,l(3,54,73,0)}l(7,15,26,-7,0),l(25,15,8,25,-1),l(10,40,15,-25,1),l(14,21,7,9,2),l(38,20,6,-6,2),l(49,20,10,-6,0);let b=[x(44,8),x(64,8),x(59,8+6*d),x(49,8+6*d)];u(b,2,8,6*d),l(44,8,20,-7,0);for(let v=5;v--;)c(59-v*6*d,30,10,0,2*H,1,0);c(59,30,4,0,7,2),l(35,20,24,0),c(59,30,10),c(47,30,10,H/2,H*3/2),c(35,30,10,H/2,H*3/2),l(7,40,13,7,-1),l(17,40,43,14,-1);for(let v=3;v--;)for(let w=2;w--;)c(17+15*v,47,w?7:1,0,2*H,2);for(let v=2;v--;){let w=6,_=7,S=53+w*d*v,E=[x(S+_,54),x(S,40),x(S+w*d,40),x(S+_+w*d,54)];u(E,0,40,14)}i.restore()}function Zh(n){if(fs=n,!cn){let e={};try{e=JSON.parse(localStorage[n]||"{}")}catch{e={}}Ms(i=>{i.unlocked=!!(e[i.id]&&e[i.id].unlocked)}),Nr()}Sn(void 0,t);function t(){if(!zi.length)return;let e=zi[0],i=Qe-Ni;if(!Ni)Ni=Qe;else if(i>hs)Ni=0,zi.shift();else{let s=hs-Dn,o=is?(i-s)/Dn:0;e.render(o)}}}function Ms(n){Object.values(xi).forEach(t=>n(t))}function td(){Ms(n=>n.unlocked=!1),Nr()}function Nr(){if(!fs)return;let n={};Ms(t=>{let e={name:t.name,description:t.description,icon:t.icon,unlocked:t.unlocked};t.image&&(e.src=t.image.src),n[t.id]=e}),localStorage[fs]=JSON.stringify(n)}function ed(n){hs=n}function nd(n){Dn=n}function id(n){ds=n.copy()}function sd(n){Br=n}function Tc(n,t,e,i=125){let s,o,r,a,c,l,u,h,f,d,g,b,v,w=0,_,S=[],E=[],A=[],T=0,P=0,M=1,ct={},nt=qn/i*60>>2;for(;M;T++)S=[M=h=b=0],e.forEach((rt,pt)=>{for(u=t[rt][T]||[0,0,0],M|=t[rt][T]&&1,_=b+(t[rt][0].length-2-(h?0:1))*nt,v=pt===e.length-1,s=2,r=b;snt-99&&f&&g<1?g+=1/99:0)l=(1-g)*S[w++]/2||0,E[r]=(E[r]||0)-l*P+l,A[r]=(A[r++]||0)+l*P+l;c&&(g=c%1,P=u[1]||0,(c|=0)&&(S=ct[[d=u[w=0]||0,c]]=ct[[d,c]]||(a=[...n[d]],a[2]=(a[2]||220)*2**(c/12-1),c>0?Os(...a):[])))}b=_});return[E,A]}function od(n){zr=typeof n=="boolean"?n?1:0:n}function rd(n){Jr=n}async function ad(){return new xs(await Box2D()),e(),Sn(n,t),m;function n(){if(!be){m.step(),m.objects=m.objects.filter(i=>!i.destroyed);for(let i of m.objects)i.body&&(i.pos=m.vec2From(i.body.GetPosition()),i.angle=-i.body.GetAngle())}}function t(){(Jr||se)&&m.world.DrawDebugData()}function e(){let s=new m.instance.JSDraw,o=l=>new vt(l.get_r(),l.get_g(),l.get_b()),r=l=>o(m.instance.wrapPointer(l,m.instance.b2Color)),a=l=>r(l).scale(1,.8),c=(l,u)=>{let h=[];for(let f=u;f--;)h.push(m.vec2FromPointer(l+f*8));return h};s.DrawSegment=function(l,u,h){h=a(h),l=m.vec2FromPointer(l),u=m.vec2FromPointer(u),dn(l,u,.1,h,x(),0,!1)},s.DrawPolygon=function(l,u,h){h=a(h);let f=c(l,u);Fn(f,Ze,.1,h,x(),0,!1)},s.DrawSolidPolygon=function(l,u,h){h=a(h);let f=c(l,u);Fn(f,h,0,h,x(),0,!1)},s.DrawCircle=function(l,u,h){h=a(h),l=m.vec2FromPointer(l),Qi(l,u*2,Ze,.1,h,!1)},s.DrawSolidCircle=function(l,u,h,f){f=a(f),l=m.vec2FromPointer(l),h=m.vec2FromPointer(h).scale(u),Qi(l,u*2,f,.1,f,!1),dn(x(),h,.1,f,l,0,!1)},s.DrawTransform=function(l){l=m.instance.wrapPointer(l,m.instance.b2Transform);let u=m.vec2From(l.get_p()),h=-l.get_q().GetAngle(),f=x(1,0),d=N(.75,0,0,.8),g=x(0,1),b=N(0,.75,0,.8);dn(x(),f,.1,d,u,h,!1),dn(x(),g,.1,b,u,h,!1)},s.AppendFlags(m.instance.b2Draw.e_shapeBit),s.AppendFlags(m.instance.b2Draw.e_jointBit),m.world.SetDebugDraw(s)}}function cd(n,t,e,i=32,s=2,o=0){Ac(n,t,e,U,i,it,s,o,!1,!0)}function Ac(n,t,e,i,s=1,o,r=.05,a=0,c=k,l,u){let h=e.offset(e.size),f=t.add(x(r-s*2)),d=x(s),g=t.scale(.5).subtract(d.scale(.5)),b=l?-1:1,v=l?-a:a;_t(n,f,h,i,a,!1,o,c,l,u);for(let w=4;w--;){let _=w%2,S=g.multiply(x(_?w===1?1:-1:0,_?0:w?-1:1)),E=x(_?s:f.x,_?f.y:s),A=h.offset(e.size.multiply(x(w===1?1:w===3?-1:0,w===0?-b:w===2?b:0)));_t(n.add(S.rotate(v)),E,A,i,a,!1,o,c,l,u)}for(let w=4;w--;){let _=w>1,S=w&&w<3,E=g.multiply(x(_?-1:1,S?-1:1)),A=h.offset(e.size.multiply(x(_?-1:1,S?b:-b)));_t(n.add(E.rotate(v)),d,A,i,a,!1,o,c,l,u)}}function ld(n,t,e,i=32,s=2,o=0){Cc(n,t,e,U,i,it,s,o,!1,!0)}function Cc(n,t,e,i,s=1,o,r=.05,a=0,c=k,l,u){let h=e.frame(0),f=e.frame(1),d=e.frame(2),g=t.add(x(r-s*2)),b=x(s),v=t.scale(.5).subtract(b.scale(.5)),w=l?-1:1,_=l?-a:a;_t(n,g,d,i,a,!1,o,c,l,u);for(let S=4;S--;){let E=a+S*H/2,A=S%2,T=v.multiply(x(A?S===1?1:-1:0,A?0:S?-w:w)),P=x(A?g.y:g.x,s);_t(n.add(T.rotate(_)),P,f,i,E,!1,o,c,l,u)}for(let S=4;S--;){let E=a+S*H/2,A=!S||S>2,T=S>1,P=v.multiply(x(A?-1:1,T?-w:w));_t(n.add(P.rotate(_)),b,h,i,E,!1,o,c,l,u)}}function ud(n,t=1,e=0,i=U,s=0,o=!1,r=0,a=it,c=k,l=!1,u){let h=Ec(x(),t,e,0,o);Fn(h,i,r,a,n,s,c,l,u)}function Ec(n,t=1,e=0,i=0,s=!1,o=Ai){p(O(n),"pos must be a vec2"),p(L(t)&&L(e),"size and percent must be numbers");let r=Qt(e*4,4);r>=2&&(i+=H),r=r<=2?r-1:3-r,s&&(r=-r,i+=H);let a=[],c=Y(3,o>>1),l=t/2;for(let u=0;u<=c;u++){let h=u/c*H;a.push(x(l*at(h),l*et(h)).rotate(i).add(n))}for(let u=c;u>=0;u--){let h=u/c*H;a.push(x(l*at(h),-l*r*et(h)).rotate(i).add(n))}return a}function _a(n){return n&&typeof n.lerp=="function"}function hd(n,t,e,i,s=1,o={}){p(n!=null&&typeof n=="object","tweenProperty target must be an object"),p(J(t)&&t.length>0,"tweenProperty propertyPath must be a non-empty string");let r=t.split("."),a=r.pop(),c=l=>{let u=n;for(let h of r)u=u[h];u[a]=l};return new vs(c,e,i,s,o)}function _c(n){n.loopRemaining!==1/0&&n.loopRemaining<=1||(n.loopRemaining!==1/0&&(n.loopRemaining-=1),n.life=n.duration,n.thenCallback=()=>_c(n),Wt.push(n),n.callback(n.interp(n.duration)))}function Rc(n){if(n.loopRemaining!==1/0&&n.loopRemaining<=1)return;n.loopRemaining!==1/0&&(n.loopRemaining-=1);let t=n.start;n.start=n.end,n.end=t,n.life=n.duration,n.thenCallback=()=>Rc(n),Wt.push(n),n.callback(n.interp(n.duration))}function Pc(n,t){n===void 0?(n=qt-Ca,t=Qe-Ea,Ca=qt,Ea=Qe):t===void 0&&(t=n);for(let e=Wt.length;e--;){let i=Wt[e];if(i.paused)continue;let s=i.useRealTime?t:n;if(!(s<=0))if(i.life-=s,i.life>0)i.callback(i.interp(i.life));else{i.callback(i.interp(0)),Wt.splice(e,1);let o=i.thenCallback;i.thenCallback=void 0,o&&o()}}}function dd(){for(let n of Wt)n.thenCallback=void 0;Wt.length=0}var Ji,Ui,El,$o,bt,Ko,Ra,qt,Qe,be,io,de,Vi,Pa,fn,ro,Dt,Da,Ts,Ia,Ee,He,se,oe,pn,yn,Gn,ao,_e,ie,H,tt,xt,oi,Wi,Q,Y,Kt,Fa,ja,et,at,Ba,Zo,uo,ot,vt,U,Ze,it,ce,Vl,nr,Wl,Xa,Ya,ql,$a,Ka,Hl,xe,Tt,$,q,sr,As,Xe,Rn,ti,Pn,Ln,or,bn,Ye,Ti,rr,B,k,Ai,Cs,Es,_s,Rs,ar,cr,lr,ur,hr,Pe,Bt,Xi,Ps,dr,ei,hn,tn,fr,ae,Un,wn,Vn,Wn,Ci,nn,zt,pr,ni,Yi,Ei,Jt,gn,yr,gr,ke,F,lt,St,De,We,ye,Le,I,en,ve,Se,we,Ge,nh,rc,Zi,Ae,Ft,xr,fe,vr,ts,In,qe,Sr,On,yt,Zt,X,pe,ln,so,jn,te,xn,es,Oi,Oe,Ue,lc,Er,uc,hi,un,Bn,Sa,ns,dt,Me,qn,fi,is,Ke,mn,os,pi,yi,go,Vh,rs,Z,y,Lr,as,cs,vn,En,zn,Ht,mo,Mn,Ot,gi,wt,si,bo,xo,Or,ls,vo,us,Dr,pc,Wh,Ds,yc,kn,cn,hs,Dn,ds,Br,xi,zi,fs,Ni,ps,vi,To,Ao,Pt,Co,W,Eo,_o,Ro,C,zr,Po,ee,ys,Lo,Oo,Si,Do,Io,Mo,ko,m,Jr,wi,gs,Go,Fo,ms,Ut,jo,bs,Bo,No,zo,Jo,Uo,Vo,Wo,qo,Ho,Xo,xs,Wt,Ca,Ea,vs,Ss,fd,oo,ws,Yo,Oc=jc(()=>{"use strict";Ji="LittleJS",Ui="1.18.19",El=60,$o=.016666666666666666,bt=[],Ko=[],Ra=0,qt=0,Qe=0,be=!1;io=0,de=0,Vi=0,Pa=!0,fn=[],ro=class{constructor(t,e,i,s){this.update=t,this.render=e,this.glContextLost=i,this.glContextRestored=s}};Dt=!0,Da=.5,Ts=!0,Ia="Escape",Ee=!1,He=[],se=!1,oe=!1,pn=!1,yn=!1,Gn=!1;H=Math.PI,tt=Math.abs,xt=Math.floor,oi=Math.ceil,Wi=Math.round,Q=Math.min,Y=Math.max,Kt=n=>Math.sign(n),Fa=(...n)=>Math.hypot(...n),ja=n=>Math.log2(n),et=Math.sin,at=Math.cos,Ba=Math.tan,Zo=Math.atan2;uo=class{constructor(t=123456789){p(t!==0,"RandomGenerator seed must be non-zero (xorshift is fixed at 0)"),this.seed=t}float(t=1,e=0){return this.seed^=this.seed<<13,this.seed^=this.seed>>>17,this.seed^=this.seed<<5,e+(t-e)*((this.seed>>>0)/2**32)}int(t,e=0){return xt(this.float(t,e))}bool(t=.5){return this.float().5?1:-1}floatSign(t=1,e=0){let i=Q(t,e),o=Y(t,e)-i,r=this.float(o*2);return rt?this.scale(t/e):this.copy()}dot(t){return this.x*t.x+this.y*t.y}cross(t){return this.x*t.y-this.y*t.x}reflect(t,e=1){return this.subtract(t.scale((1+e)*this.dot(t)))}angle(){return Zo(this.x,this.y)}setAngle(t=0,e=1){return Vt(t),Vt(e),this.x=e*et(t),this.y=e*at(t),this}rotate(t){Vt(t);let e=at(-t),i=et(-t);return new n(this.x*e-this.y*i,this.x*i+this.y*e)}setDirection(t,e=1){return Vt(t),Vt(e),t=Qt(t,4),p(t===0||t===1||t===2||t===3,"Vector2.setDirection() direction must be an integer between 0 and 3."),this.x=t%2?t-1?-e:e:0,this.y=t%2?0:t?-e:e,this}direction(){return tt(this.x)>tt(this.y)?this.x<0?3:1:this.y<0?2:0}abs(){return new n(tt(this.x),tt(this.y))}floor(){return new n(xt(this.x),xt(this.y))}snap(t){return Vt(t),new n(xt(this.x*t)/t,xt(this.y*t)/t)}mod(t=1){return new n(Qt(this.x,t),Qt(this.y,t))}area(){return tt(this.x*this.y)}lerp(t,e){xa(t),Vt(e);let i=j(e);return new n(t.x*i+this.x*(1-i),t.y*i+this.y*(1-i))}arrayCheck(t){return this.x>=0&&this.y>=0&&this.x(u=Qt(u,1))*6<1?c+(l-c)*6*u:u*2<1?l:u*3<2?c+(l-c)*(4-u*6):c;return this.r=a(r,o,t+1/3),this.g=a(r,o,t),this.b=a(r,o,t-1/3),this.a=s,Qn(this),this}HSLA(){let t=j(this.r),e=j(this.g),i=j(this.b),s=j(this.a),o=Y(t,e,i),r=Q(t,e,i),a=(o+r)/2,c=0,l=0;if(o!==r){let u=o-r;l=a>.5?u/(2-o-r):u/(o+r),t===o?c=(e-i)/u+(e((i=j(i)*255|0)<16?"0":"")+i.toString(16);return"#"+e(this.r)+e(this.g)+e(this.b)+(t?e(this.a):"")}setHex(t){if(p(J(t),"Color hex code must be a string"),p(t[0]==="#","Color hex code must start with #"),p([4,5,7,9].includes(t.length),"Invalid hex"),t.length<6){let e=i=>j(parseInt(t[i],16)/15);this.r=e(1),this.g=e(2),this.b=e(3),this.a=t.length===5?e(4):1}else{let e=i=>j(parseInt(t.slice(i,i+2),16)/255);this.r=e(1),this.g=e(3),this.b=e(5),this.a=t.length===9?e(7):1}return Qn(this),this}rgbaInt(){let t=j(this.r)*255|0,e=j(this.g)*255<<8,i=j(this.b)*255<<16,s=j(this.a)*255<<24;return t+e+i+s}isValid(){return L(this.r)&&L(this.g)&&L(this.b)&&L(this.a)}},U=Xt(N()),Ze=Xt(N(1,1,1,0)),it=Xt(N(0,0,0)),ce=Xt(N(0,0,0,0)),Vl=Xt(N(.5,.5,.5)),nr=Xt(N(1,0,0)),Wl=Xt(N(1,.5,0)),Xa=Xt(N(1,1,0)),Ya=Xt(N(0,1,0)),ql=Xt(N(0,1,1)),$a=Xt(N(0,0,1)),Ka=Xt(N(.5,0,1)),Hl=Xt(N(1,0,1)),xe=class{constructor(t,e=!1){p(t===void 0||L(t),"Constructed Timer is invalid.",t),this.useRealTime=e;let i=this.getGlobalTime();this.time=t===void 0?void 0:i+t,this.setTime=t}set(t=0){p(L(t),"Timer is invalid.",t);let e=this.getGlobalTime();this.time=e+t,this.setTime=t}setUseRealTime(t=!0){p(!this.isSet(),"Cannot change global time setting while timer is set."),this.useRealTime=t}unset(){this.time=void 0}isSet(){return this.time!==void 0}active(){return this.getGlobalTime()=this.time}get(){return this.isSet()?this.getGlobalTime()-this.time:0}getPercent(){return this.isSet()?this.setTime?1-It(this.time-this.getGlobalTime(),0,this.setTime):1:0}getSetTime(){return this.isSet()?this.setTime:0}getGlobalTime(){return this.useRealTime?Qe:qt}toString(){return this.isSet()?tt(this.get())+" seconds "+(this.get()<0?"before":"after"):"unset"}valueOf(){return this.get()}};Tt=x(),$=0,q=32,sr=1,As=!0,Xe=ce,Rn=x(1920,1080),ti=0,Pn=0,Ln=x(),or=!1,bn=!0,Ye=1,Ti="arial",rr=!1,B=!1,k=!0,Ai=32,Cs=x(16),Es=0,_s=0,Rs=!0,ar=1,cr=1,lr=1,ur=0,hr=.8,Pe=1,Bt=x(),Xi=1,Ps=!0,dr=!0,ei=!0,hn=!0,tn=!1,fr=!1,ae=0,Un=4,wn=!0,Vn=0,Wn=!1,Ci=!0,nn=!1,zt=100,pr=.3,ni=3,Yi=0,Ei=!0,Jt=!0,gn=.3,yr=40,gr=.7;ke=class n{constructor(t=x(),e=x(1),i,s=0,o=U,r=0){p(O(t),"object pos must be a vec2"),p(O(e),"object size must be a vec2"),p(!i||i instanceof we,"object tileInfo should be a TileInfo or undefined"),p(typeof s=="number"&&isFinite(s),"object angle should be a number"),p(z(o),"object color should be a valid rgba color"),p(typeof r=="number","object renderOrder should be a number"),this.pos=t.copy(),this.size=e.copy(),this.drawSize=void 0,this.tileInfo=i,this.angle=s,this.color=o.copy(),this.additiveColor=void 0,this.mirror=!1,this.destroyed=!1,this.mass=ar,this.damping=cr,this.angleDamping=lr,this.restitution=ur,this.friction=hr,this.gravityScale=1,this.renderOrder=r,this.velocity=x(),this.angleVelocity=0,this.spawnTime=qt,this.children=[],this.clampSpeed=!0,this.groundObject=void 0,this.parent=void 0,this.localPos=x(),this.localAngle=0,this.collideTiles=!1,this.collideSolidObjects=!1,this.isSolid=!1,this.collideRaycast=!1,bt.push(this)}updateTransforms(){let t=this.parent;if(t){let e=t.getMirrorSign(),i=this.localPos,s=t.pos,o=i.x*e,r=i.y,a=t.angle;if(a){let c=at(-a),l=et(-a);this.pos.set(o*c-r*l+s.x,o*l+r*c+s.y)}else this.pos.set(o+s.x,r+s.y);this.angle=e*this.localAngle+a}for(let e of this.children)e.updateTransforms()}updatePhysics(){if(p(!this.parent),this.destroyed)return;this.clampSpeed&&(this.velocity.x=j(this.velocity.x,-Pe,Pe),this.velocity.y=j(this.velocity.y,-Pe,Pe));let t=this.pos.copy();if(this.velocity.x*=this.damping,this.velocity.y*=this.damping,this.mass&&(this.velocity.x+=Bt.x*this.gravityScale,this.velocity.y+=Bt.y*this.gravityScale),this.pos.x+=this.velocity.x,this.pos.y+=this.velocity.y,this.angle+=this.angleVelocity*=this.angleDamping,p(this.angleDamping>=0&&this.angleDamping<=1),p(this.damping>=0&&this.damping<=1),!Rs||!this.mass)return;let e=this.velocity.y<0&&Bt.y<0||this.velocity.y>0&&Bt.y>0;if(this.groundObject){let i=Y(this.friction,this.groundObject.friction),s=this.groundObject.velocity.x;this.velocity.x=s+(this.velocity.x-s)*i,this.groundObject=void 0}if(this.collideSolidObjects)for(let s of Ko){if(s.destroyed||s.parent||s===this||!this.isSolid&&!s.isSolid||!this.isOverlappingObject(s))continue;let o=this.collideWithObject(s),r=s.collideWithObject(this);if(!o||!r)continue;if(Hi(t,this.size,s.pos,s.size)){let f=t.subtract(s.pos),d=f.length(),b=d<.001?x(0,1):f.scale(.001/d);this.velocity=this.velocity.add(b),s.mass&&(s.velocity=s.velocity.subtract(b)),se&&co(this.pos,this.size,s.pos,s.size,"#f00");continue}let a=this.size.add(s.size),c=(t.y-s.pos.y)*2>a.y+Bt.y,l=tt(t.y-s.pos.y)*20?-1:1)>0?xt(t.y-this.size.y/2+1)+this.size.y/2+.001:oi(t.y+this.size.y/2-1)-this.size.y/2-.001;if(tt(u-this.pos.y)<.1&&!Ve(x(this.pos.x,u),this.size,this)){this.pos.y=u,se&>(this.pos,this.size,"#ff0");return}this.pos.x=t.x,this.velocity.x*=-r}if(o||!s){if(e){let c=this.size.y/2+1e-4;this.pos.y=Bt.y<0?xt(t.y-this.size.y/2)+c:oi(t.y+this.size.y/2)-c,this.groundObject=i}else this.pos.y=t.y,this.groundObject=void 0;this.velocity.y*=-r}se&>(this.pos,this.size,"#f00")}}}update(){}render(){_t(this.pos,this.drawSize||this.size,this.tileInfo,this.color,this.angle,this.mirror,this.additiveColor)}renderLight(){}destroy(t=!1){var e;if(!this.destroyed){this.destroyed=!0,(e=this.parent)==null||e.removeChild(this);for(let i of this.children)i.parent=void 0,i.destroy(t)}}localToWorld(t){return this.pos.add(t.rotate(this.angle))}worldToLocal(t){return t.subtract(this.pos).rotate(-this.angle)}localToWorldVector(t){return t.rotate(this.angle)}worldToLocalVector(t){return t.rotate(-this.angle)}collideWithTile(t,e){return t>0}collideWithObject(t){return!0}getUp(t=1){return x().setAngle(this.angle,t)}getRight(t=1){return x().setAngle(this.angle+H/2,t)}getAliveTime(){return qt-this.spawnTime}getSpeed(){return this.velocity.length()}applyAcceleration(t){this.mass&&(this.velocity=this.velocity.add(t))}applyAngularAcceleration(t){this.mass&&(this.angleVelocity+=t)}applyForce(t){this.mass&&this.applyAcceleration(t.scale(1/this.mass))}getMirrorSign(){return this.mirror?-1:1}addChild(t,e=x(),i=0){return p(!this.destroyed,"cannot add child to destroyed object"),this.destroyed||(p(!t.parent&&!this.children.includes(t)),p(t instanceof n,"child must be an EngineObject"),p(t!==this,"cannot add self as child"),this.children.push(t),t.parent=this,t.localPos=e.copy(),t.localAngle=i,t.updateTransforms()),t}removeChild(t){p(t.parent===this&&this.children.includes(t)),this.children.splice(this.children.indexOf(t),1),t.parent=void 0}isOverlappingObject(t){return this.isOverlapping(t.pos,t.size)}isOverlapping(t,e=x()){return Hi(this.pos,this.size,t,e)}setCollision(t=!0,e=!0,i=!0,s=!0){p(t||!e,"solid objects must be set to collide"),this.collideSolidObjects=t,this.isSolid=e,this.collideTiles=i,this.collideRaycast=s}toString(){let t="type = "+this.constructor.name;return(this.pos.x||this.pos.y)&&(t+=`
 pos = `+this.pos),(this.velocity.x||this.velocity.y)&&(t+=`
 velocity = `+this.velocity),(this.size.x||this.size.y)&&(t+=`
 size = `+this.size),this.angle&&(t+=`
 angle = `+this.angle.toFixed(3)),this.color&&(t+=`
-color = `+this.color),t}renderDebugInfo(){if(!Dt)return;let t=this.collideTiles||this.collideSolidObjects||this.isSolid;if(!t&&!this.parent)return;let e=b(Y(this.size.x,.2),Y(this.size.y,.2)),i=z(this.collideTiles?1:0,this.collideSolidObjects?1:0,this.isSolid?1:0,.5);yt(this.pos,e,i,0,this.angle,t),this.parent&&yt(this.pos,e.scale(.8),z(1,1,1,.5),0,this.angle),this.parent&&ve(this.pos,this.parent.pos,z(1,1,1,.5),.5)}},k=b(),an=[];_e=class n{constructor(t=b(),e=Ls,i=an[0],s=Os,o=Ds){this.pos=t.copy(),this.size=e.copy(),this.padding=s,this.textureInfo=i,this.bleed=o}offset(t){return new n(this.pos.add(t),this.size,this.textureInfo,this.padding,this.bleed)}frame(t){p(typeof t=="number");let e=this.size.x+this.padding*2,i=t*e;return p(i+this.size.x<=this.textureInfo.size.x,"frame extends beyond texture width!"),this.offset(new st(i))}setFullImage(t=this.textureInfo){return this.textureInfo=t,this.pos=new st,this.size=t.size.copy(),this.bleed=this.padding=0,this}tile(t){return Ii(t,this.size,this.textureInfo,this.padding,this.bleed)}},Ue=class{constructor(t,e=!0,i=!1){this.image=t,this.size=t?b(t.width,t.height):b(),this.sizeInverse=t?b(1/t.width,1/t.height):b(),this.glTexture=void 0,this.wrap=i,e&&this.createWebGLTexture()}createWebGLTexture(){Hh(this)}destroyWebGLTexture(){Xh(this)}hasWebGL(){return!!this.glTexture}setWrap(t=!0){this.wrap=t,Sc(this.glTexture,t)}};nh=0;ss=class{constructor(t){p(!!t,"tileInfo is required for ImageFont"),this.tileInfo=t.frame(0)}drawText(t,e,i=1,s,o,r,a){p(O(i)||typeof i=="number","size must be a vec2 or number"),typeof i=="number"?(p(i>0),i*=q,i=new st(i,i)):i=i.scale(q),this.drawTextScreen(t,Pn(e),i,s,o,r,a)}drawTextScreen(t,e,i,s=!0,o=V,r=F,a){p(U(t),"text must be a string"),p(O(e),"pos must be a vec2"),p(O(i)||typeof i=="number","size must be a vec2 or number"),p(J(o),"color must be a color"),i=typeof i=="number"?new st(i,i):i;let c=new st,l=this.tileInfo,u=l.padding,h=l.size.x+u*2,f=l.size.y+u*2,d=l.textureInfo.size.x/h|0;(t+"").split(`
-`).forEach((y,x)=>{let v=s?(y.length-1)*i.x/2:0;for(let w=y.length;w--;){let _=y.charCodeAt(w),S=_<32||_>127?95:_-32,E=S%d,A=S/d|0;l.pos.x=E*h+u,l.pos.y=A*f+u,c.x=e.x+w*i.x-v|0,c.y=e.y+x*i.y|0,Rt(c,i,l,o,0,!1,void 0,r,!0,a)}})}};Oe=b(),Ft=b(),Tr=b(),me=b(),Ar=0,os=!0,Nn=!1,Ke="mouse",Cr=6,Fn=!0,pt=0,te=!B&&window.ontouchstart!==void 0;X=[[]],be=[],pn=[],co=[],Vn=new Te,ee=[],An=[],rs=[],Fi=[],je=new Map,mi=[],Wn=!0;as="http://www.w3.org/2000/svg";ut=new AudioContext,Qn=44100;xi=class{constructor(t,e,i=xr,s=vr,o){var r;if(!(!Jt||B)){if(p(!t||le(t)||U(t),"asset must be a file name or zzfx array"),p(e===void 0||L(e),"randomness must be a number"),p(e===void 0||e>=0&&e<=1,"randomness must be between 0 and 1"),p(L(i),"range must be a number"),p(L(s),"taper must be a number"),this.range=i,this.taper=s,this.randomness=e!=null?e:0,this.sampleRate=Qn,this.loadedPercent=0,this.onloadCallback=o,le(t)){let a=t.slice(),c=e!=null?e:.05,l=1;this.randomness=(r=a[l])!=null?r:c,a[l]=0,this.sampleChannels=[Gs(...a)],this.loadedPercent=1,o==null||o(this)}else if(typeof t=="string"){let a=t;this.loadSound(a)}}}play(t,e=1,i=1,s=1,o=!1,r=!1){if(p(!t||O(t),"pos must be a vec2"),p(L(e),"volume must be a number"),p(L(i),"pitch must be a number"),p(L(s),"randomnessScale must be a number"),!Jt||B||!this.sampleChannels)return;let a;if(t){let u=this.range;if(u){let h=At.distanceSquared(t);if(h>u*u)return;e*=It(h**.5,u,u*this.taper)}a=Pn(t).x*2/j.width-1}let c=i+i*this.randomness*s*lt(-1,1),l=new cs(this,e,c,a,o,r);return Dt&&Jn&&t&&(jt(t,.5,"#0ff",.5,!0),this.range&&(jt(t,2*this.range,"#0ff",.5),jt(t,2*this.range*this.taper,"#0ff",.5)),In("vol "+e.toFixed(2)+" pitch "+c.toFixed(2),t,.5,"#0ff",.5)),l}playMusic(t=1,e=!0,i=!1){return this.play(void 0,t,1,0,e,i)}playNote(t=0,e,i){p(L(t),"semitoneOffset must be a number");let s=yc(t,1);return this.play(e,i,s,0)}getDuration(){var t,e;return((e=(t=this.sampleChannels)==null?void 0:t[0])==null?void 0:e.length)/this.sampleRate||0}isLoaded(){return this.loadedPercent===1}async loadSound(t){var c;let e=await fetch(t);if(!e.ok)throw new Error(`Failed to load sound from ${t}: ${e.status} ${e.statusText}`);let i=await e.arrayBuffer(),s=await ut.decodeAudioData(i),o=s.numberOfChannels,r=1e5,a=[];for(let l=0;lsetTimeout(v,0));let d=K(f+r,h);for(;f=0,"Sound volume must be positive or zero"),p(i>=0,"Sound rate must be positive or zero"),p(L(s),"Sound pan must be a number"),this.sound=t,this.volume=e,this.rate=i,this.pan=s,this.loop=o,this.pausedTime=0,this.startTime=void 0,this.gainNode=void 0,this.source=void 0,this.onendedCallback=a=>{a===this.source&&(this.source=void 0)},r||this.start()}start(t=0){p(t>=0,"Sound start offset must be positive or zero"),this.isPlaying()&&this.stop(),this.gainNode=ut.createGain(),this.source=Ir(this.sound.sampleChannels,this.volume,this.rate,this.pan,this.loop,this.sound.sampleRate,this.gainNode,t,this.onendedCallback),this.source?(this.startTime=ut.currentTime-t,this.pausedTime=void 0):(this.startTime=void 0,this.pausedTime=0)}setVolume(t){p(t>=0,"Sound volume must be positive or zero"),this.volume=t,this.gainNode&&(this.gainNode.gain.value=t)}stop(t=0){if(p(t>=0,"Sound fade time must be positive or zero"),this.isPlaying())if(t){let e=ut.currentTime,i=e+t;this.gainNode.gain.cancelScheduledValues(e),this.gainNode.gain.setValueAtTime(this.volume,e),this.gainNode.gain.linearRampToValueAtTime(0,i),this.source.stop(i)}else this.source.stop();this.pausedTime=0,this.source=void 0,this.startTime=void 0}pause(){this.isPaused()||(this.pausedTime=this.getCurrentTime(),this.source.stop(),this.source=void 0,this.startTime=void 0)}resume(){this.isPaused()&&this.start(this.pausedTime)}isPlaying(){return!!this.source}isPaused(){return!this.isPlaying()}getCurrentTime(){if(!this.isPlaying())return this.pausedTime;let t=this.getDuration();return t?Zt(ut.currentTime-this.startTime,t):0}getDuration(){return this.rate?this.sound.getDuration()/this.rate:0}getSource(){return this.source}};nn=[];wn=class{constructor(t,e=0,i=!1,s=new St){this.tile=t,this.direction=e,this.mirror=i,this.color=s.copy()}clear(){this.tile=this.direction=0,this.mirror=!1,this.color=new St}},us=class extends Je{constructor(t,e,i=0,s=0,o=b(512),r=!0){var a;p(O(o),"canvasSize must be a Vector2"),super(t,e,void 0,i,V,s),this.canvas=B?void 0:new OffscreenCanvas(o.x,o.y),this.context=(a=this.canvas)==null?void 0:a.getContext("2d"),this.textureInfo=new Ue(this.canvas,r),this.mass=0}destroy(){this.destroyed||(this.textureInfo.destroyWebGLTexture(),super.destroy())}render(){this.draw(this.pos,this.size,this.color,this.angle,this.mirror,this.additiveColor)}draw(t,e,i=V,s=0,o=!1,r,a=!1,c){let l=new _e().setFullImage(this.textureInfo),u=this.hasWebGL();Rt(t,e,l,i,s,o,r,u,a,c)}updateWebGL(){this.textureInfo.createWebGLTexture()}hasWebGL(){return F&&this.textureInfo.hasWebGL()}},vi=class extends us{constructor(t,e,i=Ii(),s=0,o=!0){let r=i?e.multiply(i.size):e;if(super(t,e,0,s,r,o),this.tileInfo=void 0,this.data=[],this.isUsingWebGL=!1,B){this.render=()=>{},this.redraw=()=>{},this.redrawStart=()=>{},this.redrawEnd=()=>{},this.drawTileData=()=>{},this.redrawTileData=()=>{},this.drawLayerTile=()=>{},this.drawLayerRect=()=>{},this.drawTile=()=>{},this.drawRect=()=>{},this.clearLayerRect=()=>{};return}i&&(this.tileInfo=i.frame(0),this.tileInfo.bleed=0);for(let a=this.size.area();a--;)this.data.push(new wn)}setData(t,e,i=!1){if(t=t.floor(),p(O(t),"layerPos must be a Vector2"),p(e instanceof wn,"data must be a TileLayerData"),!t.arrayCheck(this.size)||(this.data[(t.y|0)*this.size.x+(t.x|0)]=e,!i))return;wt===this.context?this.drawTileData(t):this.redrawTileData(t)}clearData(t,e=!1){this.setData(t,new wn,e)}getData(t){return p(O(t),"layerPos must be a Vector2"),t.arrayCheck(this.size)?this.data[(t.y|0)*this.size.x+(t.x|0)]:void 0}update(){!F&&this.isUsingWebGL&&(this.isUsingWebGL=!1,this.redraw())}render(){p(wt!==this.context,"must call redrawEnd() after drawing tiles!");let t=this.drawSize||this.size,e=this.pos.add(t.scale(.5));this.draw(e,this.size,this.color,this.angle,this.mirror,this.additiveColor)}onRedraw(){}redraw(){this.redrawStart(!0);for(let t=this.size.x;t--;)for(let e=this.size.y;e--;)this.drawTileData(b(t,e),!1);this.isUsingWebGL&&Ct(),this.onRedraw(),this.redrawEnd()}redrawStart(t=!1){var i,s;if(!this.context)return;p(wt!==this.context),this.savedRenderSettings=[wt,k,At,q,Ze],wt=this.context;let e=(s=(i=this.tileInfo)==null?void 0:i.size)!=null?s:b(1);k=this.size.multiply(e),Ze=he,At=this.size.multiply(e).scale(.5),q=1,this.isUsingWebGL=this.hasWebGL(),this.isUsingWebGL?oi(this.textureInfo.glTexture,t):(this.context.imageSmoothingEnabled=!Tn,t&&(this.canvas.width=k.x,this.canvas.height=k.y))}redrawEnd(){this.context&&(p(wt===this.context),this.isUsingWebGL&&oi(),[wt,k,At,q,Ze]=this.savedRenderSettings)}drawTileData(t,e=!0){var a,c;if(!this.context)return;p(wt===this.context,"must call redrawStart() before drawing tiles");let i=(c=(a=this.tileInfo)==null?void 0:a.size)!=null?c:b(1),s=t.multiply(i);e&&this.clearLayerRect(s,i);let o=this.getData(t);if(!o||!o.tile)return;let r=this.tileInfo&&this.tileInfo.tile(o.tile);this.drawLayerTile(s,i,r,o.color,o.direction*H/2,o.mirror)}redrawTileData(t,e=!0){this.context&&(p(wt!==this.context,"redrawStart() should not be active when calling redrawTileData(), instead use drawTileData()"),this.redrawStart(),this.drawTileData(t,e),this.redrawEnd())}drawLayerTile(t,e=b(1),i,s=V,o=0,r,a){let c=t.add(e.scale(.5));Rt(c,e,i,s,o,r,a,this.isUsingWebGL)}drawLayerRect(t,e,i,s=0){this.drawLayerTile(t,e,void 0,i,s)}drawTile(t,e=b(1),i,s=new St,o=0,r=!1){t=t.subtract(this.pos).multiply(this.tileInfo.size),e=e.multiply(this.tileInfo.size),t.y=this.canvas.height-t.y;let a=k;k=b(this.canvas.width,this.canvas.height);let c=this.hasWebGL();c&&oi(this.textureInfo.glTexture);let l=c?void 0:this.context;Rt(t,e,i,s,o,r,void 0,c,!0,l),c&&oi(),k=a}drawRect(t,e,i,s){this.drawTile(t,e,void 0,i,s)}clearLayerRect(t,e){p(wt===this.context,"must call redrawStart() before clearing tiles");let i=t.x,s=this.canvas.height-t.y-e.y;this.hasWebGL()?Cc(i,s,e.x,e.y):this.context.clearRect(i,s,e.x,e.y)}},Si=class extends vi{constructor(t,e,i=Ii(),s=0,o=!0){super(t,e.floor(),i,s,o),this.collisionData=[],this.initCollision(this.size),nn.push(this),this.isSolid=!0}destroy(){if(this.destroyed)return;let t=nn.indexOf(this);p(t>=0,"tile collision layer not found in array"),t>=0&&nn.splice(t,1),super.destroy()}initCollision(t){p(O(t),"size must be a Vector2"),this.size=t.floor(),this.collisionData=[],this.collisionData.length=t.area(),this.collisionData.fill(0)}setCollisionData(t,e=1){p(O(t),"layerPos must be a Vector2");let i=(t.y|0)*this.size.x+(t.x|0);t.arrayCheck(this.size)&&(this.collisionData[i]=e)}clearCollisionData(t){this.setCollisionData(t,0)}getCollisionData(t){p(O(t),"layerPos must be a Vector2");let e=(t.y|0)*this.size.x+(t.x|0);return t.arrayCheck(this.size)?this.collisionData[e]:0}collisionTest(t,e=new st,i){p(O(t)&&O(e),"pos and size must be Vector2s"),p(!i||typeof i=="function"||i instanceof Je,"callbackObject must be a function or EngineObject");let s=i?typeof i=="function"?(f,d)=>i(f,d):(f,d)=>i.collideWithTile(f,d):()=>!0,o=t.x-this.pos.x,r=t.y-this.pos.y;if(o+e.x/2<0||o-e.x/2>this.size.x||r+e.y/2<0||r-e.y/2>this.size.y)return!1;let a=Y(o-e.x/2|0,0),c=Y(r-e.y/2|0,0),l=K(Y(o+e.x/2,a+1),this.size.x),u=K(Y(r+e.y/2,c+1),this.size.y),h=new st;for(let f=c;fi(l,u):(l,u)=>i.collideWithTile(l,u):l=>l>0,r=l=>{let u=this.getCollisionData(a.set(l.x-this.pos.x,l.y-this.pos.y));return u&&o(u,l)},a=new st,c=qa(t,e,r,s);if(ce&&c){let l=c.floor().add(b(.5));yt(l,b(1),"#f008"),ve(t,e,"#00f",.02),ve(t,c,"#f00",.02),nr(c,"#0f0"),s&&ve(c,c.add(s),"#ff0",.02)}return c}},vo=class extends Je{constructor(t,e,i=0,s=0,o=100,r=H,a,c=V,l=V,u=on,h=on,f=.5,d=.1,y=1,x=.1,v=.05,w=1,_=1,S=0,E=H,A=.1,T=.2,P=!1,G=!1,ht=!0,Q=G?1e9:0,nt=!1){super(t,b(),a,e,void 0,Q),this.emitCircle=typeof i=="number",this.emitSize=typeof i=="number"?b(i):i.copy(),this.emitTime=s,this.emitRate=o,this.emitConeAngle=r,this.colorStartA=c.copy(),this.colorStartB=l.copy(),this.colorEndA=u.copy(),this.colorEndB=h.copy(),this.randomColorLinear=ht,this.particleTime=f,this.sizeStart=d,this.sizeEnd=y,this.speed=x,this.angleSpeed=v,this.damping=w,this.angleDamping=_,this.gravityScale=S,this.particleConeAngle=E,this.fadeRate=A,this.randomness=T,this.collideTiles=P,this.additive=G,this.localSpace=nt,this.trailScale=0,this.particleCreateCallback=void 0,this.particleDestroyCallback=void 0,this.particleCollideCallback=void 0,this.velocityInheritance=0,this.emitTimeBuffer=0,this.particles=[],this.previousAngle=this.angle,this.previousPos=this.pos.copy()}update(){if(p(this.angleDamping>=0&&this.angleDamping<=1),p(this.damping>=0&&this.damping<=1),this.velocityInheritance){let i=this.velocityInheritance;this.velocity.x=i*(this.pos.x-this.previousPos.x),this.velocity.y=i*(this.pos.y-this.previousPos.y),this.angleVelocity=i*(this.angle-this.previousAngle),this.previousAngle=this.angle,this.previousPos.x=this.pos.x,this.previousPos.y=this.pos.y}if(this.isActive()){if(this.emitRate&&Zi){let i=1/this.emitRate/Zi;for(this.emitTimeBuffer+=tr;this.emitTimeBuffer>0;this.emitTimeBuffer-=i)this.emitParticle()}}else this.particles.length===0&&this.destroy(!0);let t=this.particles,e=0;for(let i=0;i_+_*lt(i,-i),o=s(this.particleTime),r=s(this.sizeStart),a=s(this.sizeEnd),c=s(this.speed),l=s(this.angleSpeed)*Xa(),u=lt(this.emitConeAngle,-this.emitConeAngle),h=po(this.colorStartA,this.colorStartB,this.randomColorLinear),f=po(this.colorEndA,this.colorEndB,this.randomColorLinear),d=this.localSpace?u:this.angle+u,y=b(c*et(d),c*ot(d)),x=l;!this.localSpace&&this.velocityInheritance>0&&(y.x+=this.velocity.x,y.y+=this.velocity.y,x+=this.angleVelocity);let v=new hs(this,t,e,h,f,o,r,a,y,x);return this.particles.push(v),(w=this.particleCreateCallback)==null||w.call(this,v),v}updatePhysics(){}render(){for(let t of this.particles)t.render()}isActive(){return!this.emitTime||this.getAliveTime()0&&(this.destroyed=!1,this.emitTime=-1))}},Vh=new st,hs=class{constructor(t,e,i,s,o,r,a,c,l=b(),u=0){this.emitter=t,this.pos=e,this.angle=i,this.size=b(a),this.color=s.copy(),this.colorStart=s,this.colorEnd=o,this.lifeTime=r,this.sizeStart=a,this.sizeEnd=c,this.velocity=l,this.angleVelocity=u,this.spawnTime=Ht,this.mirror=Ha(),this.groundObject=void 0,this.destroyed=!1,this.tileInfo=t.tileInfo}update(){let t=this.emitter,e=t.damping,i=t.angleDamping,s=t.restitution,o=t.friction,r=t.gravityScale,a=t.collideTiles,c=t.particleCollideCallback;if(this.lifeTime>0&&Ht-this.spawnTime>this.lifeTime){this.destroy();return}let l=this.pos.copy();if(this.velocity.x*=e,this.velocity.y*=e,this.pos.x+=this.velocity.x+=Nt.x*r,this.pos.y+=this.velocity.y+=Nt.y*r,this.angle+=this.angleVelocity*=i,!Is||!a)return;let u=this.velocity.lengthSquared();if(u>Ge*Ge){let f=Ge/u**.5;this.velocity.x*=f,this.velocity.y*=f}this.groundObject=void 0;let h=c?f=>{let d=ls(f);return d&&c(this,d,f)}:f=>ls(f)>0;if(h(this.pos)){let f=Ye(this.pos);if(!h(l)){let d=h(b(this.pos.x,l.y)),y=h(b(l.x,this.pos.y)),x=Y(s,f.restitution),v=Y(o,f.friction);d&&(this.pos.x=l.x,this.velocity.x*=-x,this.velocity.y*=v),(y||!d)&&((this.velocity.y<0&&Nt.y<0||this.velocity.y>0&&Nt.y>0)&&(this.groundObject=f),this.pos.y=l.y,this.velocity.y*=-x,this.velocity.x*=v),ae&&yt(this.pos,this.size,"#f00")}}}destroy(){let t=this.emitter.particleDestroyCallback,e=this.colorEnd;this.color.set(e.r,e.g,e.b,e.a),this.size.set(this.sizeEnd,this.sizeEnd),this.destroyed=!0,t==null||t(this)}render(){let t=this.emitter,e=t.localSpace,i=t.additive,s=t.trailScale,o=t.fadeRate/2,r=this.lifeTime>0?K((Ht-this.spawnTime)/this.lifeTime,1):1,a=1-r,c=a*this.sizeStart+r*this.sizeEnd,l=b(c),u=r1-o?(1-r)/o:1;this.color.r=a*this.colorStart.r+r*this.colorEnd.r,this.color.g=a*this.colorStart.g+r*this.colorEnd.g,this.color.b=a*this.colorStart.b+r*this.colorEnd.b,this.color.a=(a*this.colorStart.a+r*this.colorEnd.a)*u;let h=Vh.set(this.pos.x,this.pos.y),f=this.angle;if(e){let d=t.angle,y=ot(-d),x=et(-d);h.set(t.pos.x+h.x*y-h.y*x,t.pos.y+h.x*x+h.y*y),f+=d}if(i&&pi(),s){let d=e?this.velocity.rotate(t.angle):this.velocity,y=d.length();if(y){let x=y*s;l.y=Y(l.x,x),f=ir(d.x,d.y),Rt(h,l,this.tileInfo,this.color,f,this.mirror)}}else Rt(h,l,this.tileInfo,this.color,f,this.mirror);i&&pi(!1),xn&&yt(h,l,"#f005",0,f)}},Mr=!0,Ao=!0,ys=5e5,Gr=11,mc=Gr*4,Wh=ys/mc|0,Fs=3,bc=Fs*4,zn=ys/bc|0;fn=!1,gs=5,jn=.5,ms=b(640,80),Ur=!1,Ci={},qi=[];xs=class{constructor(t,e,i="",s="\u{1F3C6}",o){p(t>=0&&!Ci[t]),this.id=t,this.name=e,this.description=i,this.icon=s,this.unlocked=!1,this.image=void 0,o&&((this.image=new Image).src=o),Ci[t]=this}unlock(){Ur||this.unlocked||(p(bs,"save name must be set"),this.unlocked=!0,Vr(),qi.push(this))}render(t=0){let e=at,i=K(ms.x,j.width),s=ms.y,o=j.width-i,r=-s*t,a=ke(0,0,.9);e.save(),e.beginPath(),e.fillStyle=a.toString(),e.strokeStyle=it.toString(),e.lineWidth=3,e.rect(o,r,i,s),e.fill(),e.stroke(),e.clip();let c=b(.1,.05).scale(s),l=s-2*c.x;this.renderIcon(b(o+c.x+l/2,r+s/2),l);let u=s*.5,h=s*.3,f=b(o+l+2*c.x,r+c.y*2+u/2),d=i-l-3*c.x;en(this.name,f,u,it,0,void 0,"left",void 0,void 0,d),f.y=r+s-c.y*2-h/2,en(this.description,f,h,it,0,void 0,"left",void 0,void 0,d),e.restore()}renderIcon(t,e){this.image?at.drawImage(this.image,t.x-e/2,t.y-e/2,e,e):en(this.icon,t,e*.7,it)}};Eo=class extends xs{constructor(t,e,i,s,o){super(t,e,i,s,o)}unlock(){super.unlock(),_i&&_i.unlockMedal(this.id)}},Ro=class{constructor(t,e,i){var c,l,u;p(!_i,"there can only be one newgrounds object"),p(!e||i,"must provide cryptojs if there is a cipher"),_i=this,this.app_id=t,this.cipher=e,this.cryptoJS=i,this.host=location?location.hostname:"";let s=new URL(location.href);if(this.session_id=s.searchParams.get("ngio_session_id"),!this.session_id)return;let o=this.call("Medal.getList");if(!o||!o.result||o.result.error){fn&>("Newgrounds session unavailable; skipping plugin init"),this.medals=[],this.scoreboards=[];return}this.medals=((c=o.result.data)==null?void 0:c.medals)||[],fn&>(this.medals);for(let h of this.medals){let f=Ci[h.id];f&&(f.image=new Image,f.image.src=h.icon,f.name=h.name,f.description=h.description,f.unlocked=h.unlocked,f.difficulty=h.difficulty,f.value=h.value,f.value&&(f.description=f.description+` (${f.value})`))}let r=this.call("ScoreBoard.getBoards");this.scoreboards=((u=(l=r==null?void 0:r.result)==null?void 0:l.data)==null?void 0:u.scoreboards)||[],fn&>(this.scoreboards);let a=60*1e3;setInterval(()=>this.call("Gateway.ping",0,!0),a)}unlockMedal(t){return this.call("Medal.unlock",{id:t},!0)}postScore(t,e){return this.call("ScoreBoard.postScore",{id:t,value:e},!0)}getScores(t,e,i=0,s=0,o=10){return this.call("ScoreBoard.getScores",{id:t,user:e,social:i,skip:s,limit:o})}logView(){return this.call("App.logView",{host:this.host},!0)}call(t,e,i=!1){let s={component:t,parameters:e};if(this.cipher){let l=this.cryptoJS,u=l.enc.Base64.parse(this.cipher),h=l.lib.WordArray.random(16),f=l.AES.encrypt(JSON.stringify(s),u,{iv:h});s.secure=l.enc.Base64.stringify(h.concat(f.ciphertext)),s.parameters=0}let o={app_id:this.app_id,session_id:this.session_id,call:s},r=new FormData;r.append("input",JSON.stringify(o));let a=new XMLHttpRequest;a.open("POST","https://newgrounds.io/gateway_v3.php",!fn&&i);try{a.send(r)}catch(l){fn&>("newgrounds call failed",l);return}return fn&>(a.responseText),a.responseText&&JSON.parse(a.responseText)}},Po=class{constructor(t,e=!1,i=!1){p(!Pt,"Post process already initialized"),p(!(e&&i),"Post process cannot both include main canvas and use feedback texture"),Pt=this,t||(t="void mainImage(out vec4 c,vec2 p){c=texture(iChannel0,p/iResolution.xy);}"),this.shader=void 0,this.texture=void 0,this.vao=void 0,s(),_n(void 0,a,o,r);function s(){if(B)return;if(!F){console.warn("PostProcessPlugin: WebGL not enabled!");return}Pt.texture=js(),Pt.shader=Xn(`#version 300 es
+color = `+this.color),t}renderDebugInfo(){if(!Dt)return;let t=this.collideTiles||this.collideSolidObjects||this.isSolid;if(!t&&!this.parent)return;let e=x(Y(this.size.x,.2),Y(this.size.y,.2)),i=N(this.collideTiles?1:0,this.collideSolidObjects?1:0,this.isSolid?1:0,.5);gt(this.pos,e,i,0,this.angle,t),this.parent&>(this.pos,e.scale(.8),N(1,1,1,.5),0,this.angle),this.parent&&ge(this.pos,this.parent.pos,N(1,1,1,.5),.5)}},I=x(),en=[];we=class n{constructor(t=x(),e=Cs,i=en[0],s=Es,o=_s){this.pos=t.copy(),this.size=e.copy(),this.padding=s,this.textureInfo=i,this.bleed=o}offset(t){return new n(this.pos.add(t),this.size,this.textureInfo,this.padding,this.bleed)}frame(t){p(typeof t=="number");let e=this.size.x+this.padding*2,i=t*e;return p(i+this.size.x<=this.textureInfo.size.x,"frame extends beyond texture width!"),this.offset(new ot(i))}setFullImage(t=this.textureInfo){return this.textureInfo=t,this.pos=new ot,this.size=t.size.copy(),this.bleed=this.padding=0,this}tile(t){return _i(t,this.size,this.textureInfo,this.padding,this.bleed)}},Ge=class{constructor(t,e=!0,i=!1){this.image=t,this.size=t?x(t.width,t.height):x(),this.sizeInverse=t?x(1/t.width,1/t.height):x(),this.glTexture=void 0,this.wrap=i,e&&this.createWebGLTexture()}createWebGLTexture(){Hh(this)}destroyWebGLTexture(){Xh(this)}hasWebGL(){return!!this.glTexture}setWrap(t=!0){this.wrap=t,bc(this.glTexture,t)}};nh=0;Zi=class{constructor(t){p(!!t,"tileInfo is required for ImageFont"),this.tileInfo=t.frame(0)}drawText(t,e,i=1,s,o,r,a){p(O(i)||typeof i=="number","size must be a vec2 or number"),typeof i=="number"?(p(i>0),i*=q,i=new ot(i,i)):i=i.scale(q),this.drawTextScreen(t,An(e),i,s,o,r,a)}drawTextScreen(t,e,i,s=!0,o=U,r=k,a){p(J(t),"text must be a string"),p(O(e),"pos must be a vec2"),p(O(i)||typeof i=="number","size must be a vec2 or number"),p(z(o),"color must be a color"),i=typeof i=="number"?new ot(i,i):i;let c=new ot,l=this.tileInfo,u=l.padding,h=l.size.x+u*2,f=l.size.y+u*2,d=l.textureInfo.size.x/h|0;(t+"").split(`
+`).forEach((g,b)=>{let v=s?(g.length-1)*i.x/2:0;for(let w=g.length;w--;){let _=g.charCodeAt(w),S=_<32||_>127?95:_-32,E=S%d,A=S/d|0;l.pos.x=E*h+u,l.pos.y=A*f+u,c.x=e.x+w*i.x-v|0,c.y=e.y+b*i.y|0,_t(c,i,l,o,0,!1,void 0,r,!0,a)}})}};Ae=x(),Ft=x(),xr=x(),fe=x(),vr=0,ts=!0,In=!1,qe="mouse",Sr=6,On=!0,yt=0,Zt=!B&&window.ontouchstart!==void 0;X=[[]],pe=[],ln=[],so=[],jn=new xe,te=[],xn=[],es=[],Oi=[],Oe=new Map,hi=[],Bn=!0;ns="http://www.w3.org/2000/svg";dt=new AudioContext,qn=44100;fi=class{constructor(t,e,i=yr,s=gr,o){var r;if(!(!Jt||B)){if(p(!t||re(t)||J(t),"asset must be a file name or zzfx array"),p(e===void 0||L(e),"randomness must be a number"),p(e===void 0||e>=0&&e<=1,"randomness must be between 0 and 1"),p(L(i),"range must be a number"),p(L(s),"taper must be a number"),this.range=i,this.taper=s,this.randomness=e!=null?e:0,this.sampleRate=qn,this.loadedPercent=0,this.onloadCallback=o,re(t)){let a=t.slice(),c=e!=null?e:.05,l=1;this.randomness=(r=a[l])!=null?r:c,a[l]=0,this.sampleChannels=[Os(...a)],this.loadedPercent=1,o==null||o(this)}else if(typeof t=="string"){let a=t;this.loadSound(a)}}}play(t,e=1,i=1,s=1,o=!1,r=!1){if(p(!t||O(t),"pos must be a vec2"),p(L(e),"volume must be a number"),p(L(i),"pitch must be a number"),p(L(s),"randomnessScale must be a number"),!Jt||B||!this.sampleChannels)return;let a;if(t){let u=this.range;if(u){let h=Tt.distanceSquared(t);if(h>u*u)return;e*=It(h**.5,u,u*this.taper)}a=An(t).x*2/F.width-1}let c=i+i*this.randomness*s*ht(-1,1),l=new is(this,e,c,a,o,r);return Dt&&Gn&&t&&(jt(t,.5,"#0ff",.5,!0),this.range&&(jt(t,2*this.range,"#0ff",.5),jt(t,2*this.range*this.taper,"#0ff",.5)),_n("vol "+e.toFixed(2)+" pitch "+c.toFixed(2),t,.5,"#0ff",.5)),l}playMusic(t=1,e=!0,i=!1){return this.play(void 0,t,1,0,e,i)}playNote(t=0,e,i){p(L(t),"semitoneOffset must be a number");let s=dc(t,1);return this.play(e,i,s,0)}getDuration(){var t,e;return((e=(t=this.sampleChannels)==null?void 0:t[0])==null?void 0:e.length)/this.sampleRate||0}isLoaded(){return this.loadedPercent===1}async loadSound(t){var c;let e=await fetch(t);if(!e.ok)throw new Error(`Failed to load sound from ${t}: ${e.status} ${e.statusText}`);let i=await e.arrayBuffer(),s=await dt.decodeAudioData(i),o=s.numberOfChannels,r=1e5,a=[];for(let l=0;lsetTimeout(v,0));let d=Q(f+r,h);for(;f=0,"Sound volume must be positive or zero"),p(i>=0,"Sound rate must be positive or zero"),p(L(s),"Sound pan must be a number"),this.sound=t,this.volume=e,this.rate=i,this.pan=s,this.loop=o,this.pausedTime=0,this.startTime=void 0,this.gainNode=void 0,this.source=void 0,this.onendedCallback=a=>{a===this.source&&(this.source=void 0)},r||this.start()}start(t=0){p(t>=0,"Sound start offset must be positive or zero"),this.isPlaying()&&this.stop(),this.gainNode=dt.createGain(),this.source=Pr(this.sound.sampleChannels,this.volume,this.rate,this.pan,this.loop,this.sound.sampleRate,this.gainNode,t,this.onendedCallback),this.source?(this.startTime=dt.currentTime-t,this.pausedTime=void 0):(this.startTime=void 0,this.pausedTime=0)}setVolume(t){p(t>=0,"Sound volume must be positive or zero"),this.volume=t,this.gainNode&&(this.gainNode.gain.value=t)}stop(t=0){if(p(t>=0,"Sound fade time must be positive or zero"),this.isPlaying())if(t){let e=dt.currentTime,i=e+t;this.gainNode.gain.cancelScheduledValues(e),this.gainNode.gain.setValueAtTime(this.volume,e),this.gainNode.gain.linearRampToValueAtTime(0,i),this.source.stop(i)}else this.source.stop();this.pausedTime=0,this.source=void 0,this.startTime=void 0}pause(){this.isPaused()||(this.pausedTime=this.getCurrentTime(),this.source.stop(),this.source=void 0,this.startTime=void 0)}resume(){this.isPaused()&&this.start(this.pausedTime)}isPlaying(){return!!this.source}isPaused(){return!this.isPlaying()}getCurrentTime(){if(!this.isPlaying())return this.pausedTime;let t=this.getDuration();return t?Qt(dt.currentTime-this.startTime,t):0}getDuration(){return this.rate?this.sound.getDuration()/this.rate:0}getSource(){return this.source}};Ke=[];mn=class{constructor(t,e=0,i=!1,s=new vt){this.tile=t,this.direction=e,this.mirror=i,this.color=s.copy()}clear(){this.tile=this.direction=0,this.mirror=!1,this.color=new vt}},os=class extends ke{constructor(t,e,i=0,s=0,o=x(512),r=!0){var a;p(O(o),"canvasSize must be a Vector2"),super(t,e,void 0,i,U,s),this.canvas=B?void 0:new OffscreenCanvas(o.x,o.y),this.context=(a=this.canvas)==null?void 0:a.getContext("2d"),this.textureInfo=new Ge(this.canvas,r),this.mass=0}destroy(){this.destroyed||(this.textureInfo.destroyWebGLTexture(),super.destroy())}render(){this.draw(this.pos,this.size,this.color,this.angle,this.mirror,this.additiveColor)}draw(t,e,i=U,s=0,o=!1,r,a=!1,c){let l=new we().setFullImage(this.textureInfo),u=this.hasWebGL();_t(t,e,l,i,s,o,r,u,a,c)}updateWebGL(){this.textureInfo.createWebGLTexture()}hasWebGL(){return k&&this.textureInfo.hasWebGL()}},pi=class extends os{constructor(t,e,i=_i(),s=0,o=!0){let r=i?e.multiply(i.size):e;if(super(t,e,0,s,r,o),this.tileInfo=void 0,this.data=[],this.isUsingWebGL=!1,B){this.render=()=>{},this.redraw=()=>{},this.redrawStart=()=>{},this.redrawEnd=()=>{},this.drawTileData=()=>{},this.redrawTileData=()=>{},this.drawLayerTile=()=>{},this.drawLayerRect=()=>{},this.drawTile=()=>{},this.drawRect=()=>{},this.clearLayerRect=()=>{};return}i&&(this.tileInfo=i.frame(0),this.tileInfo.bleed=0);for(let a=this.size.area();a--;)this.data.push(new mn)}setData(t,e,i=!1){if(t=t.floor(),p(O(t),"layerPos must be a Vector2"),p(e instanceof mn,"data must be a TileLayerData"),!t.arrayCheck(this.size)||(this.data[(t.y|0)*this.size.x+(t.x|0)]=e,!i))return;St===this.context?this.drawTileData(t):this.redrawTileData(t)}clearData(t,e=!1){this.setData(t,new mn,e)}getData(t){return p(O(t),"layerPos must be a Vector2"),t.arrayCheck(this.size)?this.data[(t.y|0)*this.size.x+(t.x|0)]:void 0}update(){!k&&this.isUsingWebGL&&(this.isUsingWebGL=!1,this.redraw())}render(){p(St!==this.context,"must call redrawEnd() after drawing tiles!");let t=this.drawSize||this.size,e=this.pos.add(t.scale(.5));this.draw(e,this.size,this.color,this.angle,this.mirror,this.additiveColor)}onRedraw(){}redraw(){this.redrawStart(!0);for(let t=this.size.x;t--;)for(let e=this.size.y;e--;)this.drawTileData(x(t,e),!1);this.isUsingWebGL&&At(),this.onRedraw(),this.redrawEnd()}redrawStart(t=!1){var i,s;if(!this.context)return;p(St!==this.context),this.savedRenderSettings=[St,I,Tt,q,Xe],St=this.context;let e=(s=(i=this.tileInfo)==null?void 0:i.size)!=null?s:x(1);I=this.size.multiply(e),Xe=ce,Tt=this.size.multiply(e).scale(.5),q=1,this.isUsingWebGL=this.hasWebGL(),this.isUsingWebGL?Zn(this.textureInfo.glTexture,t):(this.context.imageSmoothingEnabled=!bn,t&&(this.canvas.width=I.x,this.canvas.height=I.y))}redrawEnd(){this.context&&(p(St===this.context),this.isUsingWebGL&&Zn(),[St,I,Tt,q,Xe]=this.savedRenderSettings)}drawTileData(t,e=!0){var a,c;if(!this.context)return;p(St===this.context,"must call redrawStart() before drawing tiles");let i=(c=(a=this.tileInfo)==null?void 0:a.size)!=null?c:x(1),s=t.multiply(i);e&&this.clearLayerRect(s,i);let o=this.getData(t);if(!o||!o.tile)return;let r=this.tileInfo&&this.tileInfo.tile(o.tile);this.drawLayerTile(s,i,r,o.color,o.direction*H/2,o.mirror)}redrawTileData(t,e=!0){this.context&&(p(St!==this.context,"redrawStart() should not be active when calling redrawTileData(), instead use drawTileData()"),this.redrawStart(),this.drawTileData(t,e),this.redrawEnd())}drawLayerTile(t,e=x(1),i,s=U,o=0,r,a){let c=t.add(e.scale(.5));_t(c,e,i,s,o,r,a,this.isUsingWebGL)}drawLayerRect(t,e,i,s=0){this.drawLayerTile(t,e,void 0,i,s)}drawTile(t,e=x(1),i,s=new vt,o=0,r=!1){t=t.subtract(this.pos).multiply(this.tileInfo.size),e=e.multiply(this.tileInfo.size),t.y=this.canvas.height-t.y;let a=I;I=x(this.canvas.width,this.canvas.height);let c=this.hasWebGL();c&&Zn(this.textureInfo.glTexture);let l=c?void 0:this.context;_t(t,e,i,s,o,r,void 0,c,!0,l),c&&Zn(),I=a}drawRect(t,e,i,s){this.drawTile(t,e,void 0,i,s)}clearLayerRect(t,e){p(St===this.context,"must call redrawStart() before clearing tiles");let i=t.x,s=this.canvas.height-t.y-e.y;this.hasWebGL()?wc(i,s,e.x,e.y):this.context.clearRect(i,s,e.x,e.y)}},yi=class extends pi{constructor(t,e,i=_i(),s=0,o=!0){super(t,e.floor(),i,s,o),this.collisionData=[],this.initCollision(this.size),Ke.push(this),this.isSolid=!0}destroy(){if(this.destroyed)return;let t=Ke.indexOf(this);p(t>=0,"tile collision layer not found in array"),t>=0&&Ke.splice(t,1),super.destroy()}initCollision(t){p(O(t),"size must be a Vector2"),this.size=t.floor(),this.collisionData=[],this.collisionData.length=t.area(),this.collisionData.fill(0)}setCollisionData(t,e=1){p(O(t),"layerPos must be a Vector2");let i=(t.y|0)*this.size.x+(t.x|0);t.arrayCheck(this.size)&&(this.collisionData[i]=e)}clearCollisionData(t){this.setCollisionData(t,0)}getCollisionData(t){p(O(t),"layerPos must be a Vector2");let e=(t.y|0)*this.size.x+(t.x|0);return t.arrayCheck(this.size)?this.collisionData[e]:0}collisionTest(t,e=new ot,i){p(O(t)&&O(e),"pos and size must be Vector2s"),p(!i||typeof i=="function"||i instanceof ke,"callbackObject must be a function or EngineObject");let s=i?typeof i=="function"?(f,d)=>i(f,d):(f,d)=>i.collideWithTile(f,d):()=>!0,o=t.x-this.pos.x,r=t.y-this.pos.y;if(o+e.x/2<0||o-e.x/2>this.size.x||r+e.y/2<0||r-e.y/2>this.size.y)return!1;let a=Y(o-e.x/2|0,0),c=Y(r-e.y/2|0,0),l=Q(Y(o+e.x/2,a+1),this.size.x),u=Q(Y(r+e.y/2,c+1),this.size.y),h=new ot;for(let f=c;fi(l,u):(l,u)=>i.collideWithTile(l,u):l=>l>0,r=l=>{let u=this.getCollisionData(a.set(l.x-this.pos.x,l.y-this.pos.y));return u&&o(u,l)},a=new ot,c=Ua(t,e,r,s);if(oe&&c){let l=c.floor().add(x(.5));gt(l,x(1),"#f008"),ge(t,e,"#00f",.02),ge(t,c,"#f00",.02),Qo(c,"#0f0"),s&&ge(c,c.add(s),"#ff0",.02)}return c}},go=class extends ke{constructor(t,e,i=0,s=0,o=100,r=H,a,c=U,l=U,u=Ze,h=Ze,f=.5,d=.1,g=1,b=.1,v=.05,w=1,_=1,S=0,E=H,A=.1,T=.2,P=!1,M=!1,ct=!0,nt=M?1e9:0,rt=!1){super(t,x(),a,e,void 0,nt),this.emitCircle=typeof i=="number",this.emitSize=typeof i=="number"?x(i):i.copy(),this.emitTime=s,this.emitRate=o,this.emitConeAngle=r,this.colorStartA=c.copy(),this.colorStartB=l.copy(),this.colorEndA=u.copy(),this.colorEndB=h.copy(),this.randomColorLinear=ct,this.particleTime=f,this.sizeStart=d,this.sizeEnd=g,this.speed=b,this.angleSpeed=v,this.damping=w,this.angleDamping=_,this.gravityScale=S,this.particleConeAngle=E,this.fadeRate=A,this.randomness=T,this.collideTiles=P,this.additive=M,this.localSpace=rt,this.trailScale=0,this.particleCreateCallback=void 0,this.particleDestroyCallback=void 0,this.particleCollideCallback=void 0,this.velocityInheritance=0,this.emitTimeBuffer=0,this.particles=[],this.previousAngle=this.angle,this.previousPos=this.pos.copy()}update(){if(p(this.angleDamping>=0&&this.angleDamping<=1),p(this.damping>=0&&this.damping<=1),this.velocityInheritance){let i=this.velocityInheritance;this.velocity.x=i*(this.pos.x-this.previousPos.x),this.velocity.y=i*(this.pos.y-this.previousPos.y),this.angleVelocity=i*(this.angle-this.previousAngle),this.previousAngle=this.angle,this.previousPos.x=this.pos.x,this.previousPos.y=this.pos.y}if(this.isActive()){if(this.emitRate&&Xi){let i=1/this.emitRate/Xi;for(this.emitTimeBuffer+=$o;this.emitTimeBuffer>0;this.emitTimeBuffer-=i)this.emitParticle()}}else this.particles.length===0&&this.destroy(!0);let t=this.particles,e=0;for(let i=0;i_+_*ht(i,-i),o=s(this.particleTime),r=s(this.sizeStart),a=s(this.sizeEnd),c=s(this.speed),l=s(this.angleSpeed)*Wa(),u=ht(this.emitConeAngle,-this.emitConeAngle),h=lo(this.colorStartA,this.colorStartB,this.randomColorLinear),f=lo(this.colorEndA,this.colorEndB,this.randomColorLinear),d=this.localSpace?u:this.angle+u,g=x(c*et(d),c*at(d)),b=l;!this.localSpace&&this.velocityInheritance>0&&(g.x+=this.velocity.x,g.y+=this.velocity.y,b+=this.angleVelocity);let v=new rs(this,t,e,h,f,o,r,a,g,b);return this.particles.push(v),(w=this.particleCreateCallback)==null||w.call(this,v),v}updatePhysics(){}render(){for(let t of this.particles)t.render()}isActive(){return!this.emitTime||this.getAliveTime()0&&(this.destroyed=!1,this.emitTime=-1))}},Vh=new ot,rs=class{constructor(t,e,i,s,o,r,a,c,l=x(),u=0){this.emitter=t,this.pos=e,this.angle=i,this.size=x(a),this.color=s.copy(),this.colorStart=s,this.colorEnd=o,this.lifeTime=r,this.sizeStart=a,this.sizeEnd=c,this.velocity=l,this.angleVelocity=u,this.spawnTime=qt,this.mirror=Va(),this.groundObject=void 0,this.destroyed=!1,this.tileInfo=t.tileInfo}update(){let t=this.emitter,e=t.damping,i=t.angleDamping,s=t.restitution,o=t.friction,r=t.gravityScale,a=t.collideTiles,c=t.particleCollideCallback;if(this.lifeTime>0&&qt-this.spawnTime>this.lifeTime){this.destroy();return}let l=this.pos.copy();if(this.velocity.x*=e,this.velocity.y*=e,this.pos.x+=this.velocity.x+=Bt.x*r,this.pos.y+=this.velocity.y+=Bt.y*r,this.angle+=this.angleVelocity*=i,!Rs||!a)return;let u=this.velocity.lengthSquared();if(u>Pe*Pe){let f=Pe/u**.5;this.velocity.x*=f,this.velocity.y*=f}this.groundObject=void 0;let h=c?f=>{let d=ss(f);return d&&c(this,d,f)}:f=>ss(f)>0;if(h(this.pos)){let f=Ve(this.pos);if(!h(l)){let d=h(x(this.pos.x,l.y)),g=h(x(l.x,this.pos.y)),b=Y(s,f.restitution),v=Y(o,f.friction);d&&(this.pos.x=l.x,this.velocity.x*=-b,this.velocity.y*=v),(g||!d)&&((this.velocity.y<0&&Bt.y<0||this.velocity.y>0&&Bt.y>0)&&(this.groundObject=f),this.pos.y=l.y,this.velocity.y*=-b,this.velocity.x*=v),se&>(this.pos,this.size,"#f00")}}}destroy(){let t=this.emitter.particleDestroyCallback,e=this.colorEnd;this.color.set(e.r,e.g,e.b,e.a),this.size.set(this.sizeEnd,this.sizeEnd),this.destroyed=!0,t==null||t(this)}render(){let t=this.emitter,e=t.localSpace,i=t.additive,s=t.trailScale,o=t.fadeRate/2,r=this.lifeTime>0?Q((qt-this.spawnTime)/this.lifeTime,1):1,a=1-r,c=a*this.sizeStart+r*this.sizeEnd,l=x(c),u=r1-o?(1-r)/o:1;this.color.r=a*this.colorStart.r+r*this.colorEnd.r,this.color.g=a*this.colorStart.g+r*this.colorEnd.g,this.color.b=a*this.colorStart.b+r*this.colorEnd.b,this.color.a=(a*this.colorStart.a+r*this.colorEnd.a)*u;let h=Vh.set(this.pos.x,this.pos.y),f=this.angle;if(e){let d=t.angle,g=at(-d),b=et(-d);h.set(t.pos.x+h.x*g-h.y*b,t.pos.y+h.x*b+h.y*g),f+=d}if(i&&ci(),s){let d=e?this.velocity.rotate(t.angle):this.velocity,g=d.length();if(g){let b=g*s;l.y=Y(l.x,b),f=Zo(d.x,d.y),_t(h,l,this.tileInfo,this.color,f,this.mirror)}}else _t(h,l,this.tileInfo,this.color,f,this.mirror);i&&ci(!1),pn&>(h,l,"#f005",0,f)}},Lr=!0,vo=!0,us=5e5,Dr=11,pc=Dr*4,Wh=us/pc|0,Ds=3,yc=Ds*4,kn=us/yc|0;cn=!1,hs=5,Dn=.5,ds=x(640,80),Br=!1,xi={},zi=[];ps=class{constructor(t,e,i="",s="\u{1F3C6}",o){p(t>=0&&!xi[t]),this.id=t,this.name=e,this.description=i,this.icon=s,this.unlocked=!1,this.image=void 0,o&&((this.image=new Image).src=o),xi[t]=this}unlock(){Br||this.unlocked||(p(fs,"save name must be set"),this.unlocked=!0,Nr(),zi.push(this))}render(t=0){let e=lt,i=Q(ds.x,F.width),s=ds.y,o=F.width-i,r=-s*t,a=Re(0,0,.9);e.save(),e.beginPath(),e.fillStyle=a.toString(),e.strokeStyle=it.toString(),e.lineWidth=3,e.rect(o,r,i,s),e.fill(),e.stroke(),e.clip();let c=x(.1,.05).scale(s),l=s-2*c.x;this.renderIcon(x(o+c.x+l/2,r+s/2),l);let u=s*.5,h=s*.3,f=x(o+l+2*c.x,r+c.y*2+u/2),d=i-l-3*c.x;$e(this.name,f,u,it,0,void 0,"left",void 0,void 0,d),f.y=r+s-c.y*2-h/2,$e(this.description,f,h,it,0,void 0,"left",void 0,void 0,d),e.restore()}renderIcon(t,e){this.image?lt.drawImage(this.image,t.x-e/2,t.y-e/2,e,e):$e(this.icon,t,e*.7,it)}};To=class extends ps{constructor(t,e,i,s,o){super(t,e,i,s,o)}unlock(){super.unlock(),vi&&vi.unlockMedal(this.id)}},Ao=class{constructor(t,e,i){var c,l,u;p(!vi,"there can only be one newgrounds object"),p(!e||i,"must provide cryptojs if there is a cipher"),vi=this,this.app_id=t,this.cipher=e,this.cryptoJS=i,this.host=location?location.hostname:"";let s=new URL(location.href);if(this.session_id=s.searchParams.get("ngio_session_id"),!this.session_id)return;let o=this.call("Medal.getList");if(!o||!o.result||o.result.error){cn&&mt("Newgrounds session unavailable; skipping plugin init"),this.medals=[],this.scoreboards=[];return}this.medals=((c=o.result.data)==null?void 0:c.medals)||[],cn&&mt(this.medals);for(let h of this.medals){let f=xi[h.id];f&&(f.image=new Image,f.image.src=h.icon,f.name=h.name,f.description=h.description,f.unlocked=h.unlocked,f.difficulty=h.difficulty,f.value=h.value,f.value&&(f.description=f.description+` (${f.value})`))}let r=this.call("ScoreBoard.getBoards");this.scoreboards=((u=(l=r==null?void 0:r.result)==null?void 0:l.data)==null?void 0:u.scoreboards)||[],cn&&mt(this.scoreboards);let a=60*1e3;setInterval(()=>this.call("Gateway.ping",0,!0),a)}unlockMedal(t){return this.call("Medal.unlock",{id:t},!0)}postScore(t,e){return this.call("ScoreBoard.postScore",{id:t,value:e},!0)}getScores(t,e,i=0,s=0,o=10){return this.call("ScoreBoard.getScores",{id:t,user:e,social:i,skip:s,limit:o})}logView(){return this.call("App.logView",{host:this.host},!0)}call(t,e,i=!1){let s={component:t,parameters:e};if(this.cipher){let l=this.cryptoJS,u=l.enc.Base64.parse(this.cipher),h=l.lib.WordArray.random(16),f=l.AES.encrypt(JSON.stringify(s),u,{iv:h});s.secure=l.enc.Base64.stringify(h.concat(f.ciphertext)),s.parameters=0}let o={app_id:this.app_id,session_id:this.session_id,call:s},r=new FormData;r.append("input",JSON.stringify(o));let a=new XMLHttpRequest;a.open("POST","https://newgrounds.io/gateway_v3.php",!cn&&i);try{a.send(r)}catch(l){cn&&mt("newgrounds call failed",l);return}return cn&&mt(a.responseText),a.responseText&&JSON.parse(a.responseText)}},Co=class{constructor(t,e=!1,i=!1){p(!Pt,"Post process already initialized"),p(!(e&&i),"Post process cannot both include main canvas and use feedback texture"),Pt=this,t||(t="void mainImage(out vec4 c,vec2 p){c=texture(iChannel0,p/iResolution.xy);}"),this.shader=void 0,this.texture=void 0,this.vao=void 0,s(),Sn(void 0,a,o,r);function s(){if(B)return;if(!k){console.warn("PostProcessPlugin: WebGL not enabled!");return}Pt.texture=Is(),Pt.shader=Jn(`#version 300 es
 precision highp float;in vec2 p;void main(){gl_Position=vec4(p+p-1.,1,1);}`,`#version 300 es
 precision highp float;uniform sampler2D iChannel0;uniform vec3 iResolution;uniform float iTime;out vec4 c;
 `+t+`
-void main(){mainImage(c,gl_FragCoord.xy);c.a=1.;}`),Pt.vao=g.createVertexArray(),g.bindVertexArray(Pt.vao),g.bindBuffer(g.ARRAY_BUFFER,Bn);let c=8,l=g.getAttribLocation(Pt.shader,"p");g.enableVertexAttribArray(l),g.vertexAttribPointer(l,2,g.FLOAT,!1,c,0)}function o(){Pt.shader=void 0,Pt.texture=void 0,gt("PostProcessPlugin: WebGL context lost")}function r(){s(),gt("PostProcessPlugin: WebGL context restored")}function a(){if(B||!F)return;Ct(),g.bindFramebuffer(g.FRAMEBUFFER,null),g.useProgram(Pt.shader),g.bindVertexArray(Pt.vao),g.pixelStorei(g.UNPACK_FLIP_Y_WEBGL,!0),g.disable(g.BLEND),g.activeTexture(g.TEXTURE0),g.bindTexture(g.TEXTURE_2D,Pt.texture),e?(Ne.width=k.x,Ne.height=k.y,Nr($e),$e.drawImage(j,0,0),j.width|=0,g.texImage2D(g.TEXTURE_2D,0,g.RGBA,g.RGBA,g.UNSIGNED_BYTE,Ne)):i||g.texImage2D(g.TEXTURE_2D,0,g.RGBA,g.RGBA,g.UNSIGNED_BYTE,Z);let c=l=>g.getUniformLocation(Pt.shader,l);g.uniform1i(c("iChannel0"),0),g.uniform1f(c("iTime"),Ht),g.uniform3f(c("iResolution"),j.width,j.height,1),g.drawArrays(g.TRIANGLE_STRIP,0,4),i&&g.texImage2D(g.TEXTURE_2D,0,g.RGBA,g.RGBA,g.UNSIGNED_BYTE,Z),g.pixelStorei(g.UNPACK_FLIP_Y_WEBGL,!1),Ti(!0)}}},Lo=class{constructor(t,e){p(!W,"LightSystemPlugin already initialized"),p(!Pt,"LightSystemPlugin must be created before PostProcessPlugin"),W=this,this.enabled=!0,this.ambientColor=(e||it).copy(),this.textureSize=t?t.copy():void 0,this.texture=void 0,this.lightShader=void 0,this.compositeShader=void 0,this.lightVAO=void 0,this.compositeVAO=void 0,i(),_n(void 0,s,o,r);function i(){if(B)return;if(!F){console.warn("LightSystemPlugin: WebGL not enabled!");return}W.textureSize||(W.textureSize=k.copy()),W.texture=g.createTexture(),g.bindTexture(g.TEXTURE_2D,W.texture),g.texImage2D(g.TEXTURE_2D,0,g.RGBA,W.textureSize.x,W.textureSize.y,0,g.RGBA,g.UNSIGNED_BYTE,null),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_MAG_FILTER,g.LINEAR),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_MIN_FILTER,g.LINEAR),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_S,g.CLAMP_TO_EDGE),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_T,g.CLAMP_TO_EDGE),W.lightShader=Xn(`#version 300 es
+void main(){mainImage(c,gl_FragCoord.xy);c.a=1.;}`),Pt.vao=y.createVertexArray(),y.bindVertexArray(Pt.vao),y.bindBuffer(y.ARRAY_BUFFER,Mn);let c=8,l=y.getAttribLocation(Pt.shader,"p");y.enableVertexAttribArray(l),y.vertexAttribPointer(l,2,y.FLOAT,!1,c,0)}function o(){Pt.shader=void 0,Pt.texture=void 0,mt("PostProcessPlugin: WebGL context lost")}function r(){s(),mt("PostProcessPlugin: WebGL context restored")}function a(){if(B||!k)return;At(),y.bindFramebuffer(y.FRAMEBUFFER,null),y.useProgram(Pt.shader),y.bindVertexArray(Pt.vao),y.pixelStorei(y.UNPACK_FLIP_Y_WEBGL,!0),y.disable(y.BLEND),y.activeTexture(y.TEXTURE0),y.bindTexture(y.TEXTURE_2D,Pt.texture),e?(De.width=I.x,De.height=I.y,kr(We),We.drawImage(F,0,0),F.width|=0,y.texImage2D(y.TEXTURE_2D,0,y.RGBA,y.RGBA,y.UNSIGNED_BYTE,De)):i||y.texImage2D(y.TEXTURE_2D,0,y.RGBA,y.RGBA,y.UNSIGNED_BYTE,Z);let c=l=>y.getUniformLocation(Pt.shader,l);y.uniform1i(c("iChannel0"),0),y.uniform1f(c("iTime"),qt),y.uniform3f(c("iResolution"),F.width,F.height,1),y.drawArrays(y.TRIANGLE_STRIP,0,4),i&&y.texImage2D(y.TEXTURE_2D,0,y.RGBA,y.RGBA,y.UNSIGNED_BYTE,Z),y.pixelStorei(y.UNPACK_FLIP_Y_WEBGL,!1),mi(!0)}}},Eo=class{constructor(t,e){p(!W,"LightSystemPlugin already initialized"),p(!Pt,"LightSystemPlugin must be created before PostProcessPlugin"),W=this,this.enabled=!0,this.ambientColor=(e||it).copy(),this.textureSize=t?t.copy():void 0,this.texture=void 0,this.lightShader=void 0,this.compositeShader=void 0,this.lightVAO=void 0,this.compositeVAO=void 0,i(),Sn(void 0,s,o,r);function i(){if(B)return;if(!k){console.warn("LightSystemPlugin: WebGL not enabled!");return}W.textureSize||(W.textureSize=I.copy()),W.texture=y.createTexture(),y.bindTexture(y.TEXTURE_2D,W.texture),y.texImage2D(y.TEXTURE_2D,0,y.RGBA,W.textureSize.x,W.textureSize.y,0,y.RGBA,y.UNSIGNED_BYTE,null),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_MAG_FILTER,y.LINEAR),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_MIN_FILTER,y.LINEAR),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_WRAP_S,y.CLAMP_TO_EDGE),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_WRAP_T,y.CLAMP_TO_EDGE),W.lightShader=Jn(`#version 300 es
 precision highp float;uniform mat4 m;uniform vec2 lightPos;uniform float radius;in vec2 g;out vec2 vWorldPos;void main(){vec2 worldP=lightPos+(g-.5)*2.*radius;gl_Position=m*vec4(worldP,1,1);vWorldPos=worldP;}`,`#version 300 es
-precision highp float;uniform vec2 lightPos;uniform float radius;uniform float fadeRange;uniform vec4 color;in vec2 vWorldPos;out vec4 c;void main(){float dist=distance(vWorldPos,lightPos);float t=clamp((radius-dist)/max(fadeRange,1e-6),0.,1.);c=vec4(color.rgb*t*color.a,1.);}`),W.compositeShader=Xn(`#version 300 es
+precision highp float;uniform vec2 lightPos;uniform float radius;uniform float fadeRange;uniform vec4 color;in vec2 vWorldPos;out vec4 c;void main(){float dist=distance(vWorldPos,lightPos);float t=clamp((radius-dist)/max(fadeRange,1e-6),0.,1.);c=vec4(color.rgb*t*color.a,1.);}`),W.compositeShader=Jn(`#version 300 es
 precision highp float;in vec2 p;void main(){gl_Position=vec4(p+p-1.,1,1);}`,`#version 300 es
-precision highp float;uniform sampler2D s;uniform vec3 iResolution;out vec4 c;void main(){vec2 uv=gl_FragCoord.xy/iResolution.xy;c=vec4(texture(s,uv).rgb,1.);}`),W.lightVAO=g.createVertexArray(),g.bindVertexArray(W.lightVAO),g.bindBuffer(g.ARRAY_BUFFER,Bn);let a=g.getAttribLocation(W.lightShader,"g");g.enableVertexAttribArray(a),g.vertexAttribPointer(a,2,g.FLOAT,!1,8,0),W.compositeVAO=g.createVertexArray(),g.bindVertexArray(W.compositeVAO),g.bindBuffer(g.ARRAY_BUFFER,Bn);let c=g.getAttribLocation(W.compositeShader,"p");g.enableVertexAttribArray(c),g.vertexAttribPointer(c,2,g.FLOAT,!1,8,0)}function s(){if(B||!F||!W.enabled||!W.texture)return;Ct();let a=On,c=W.ambientColor;g.bindFramebuffer(g.FRAMEBUFFER,kr),g.framebufferTexture2D(g.FRAMEBUFFER,g.COLOR_ATTACHMENT0,g.TEXTURE_2D,W.texture,0),g.viewport(0,0,W.textureSize.x,W.textureSize.y),g.clearColor(c.r,c.g,c.b,c.a),g.clear(g.COLOR_BUFFER_BIT),pi(),g.enable(g.BLEND),g.blendFunc(g.ONE,g.ONE);for(let u of mt)u.destroyed||u.renderLight();Ct(),g.bindFramebuffer(g.FRAMEBUFFER,null),g.viewport(0,0,k.x,k.y),g.useProgram(W.compositeShader),g.bindVertexArray(W.compositeVAO),g.activeTexture(g.TEXTURE0),g.bindTexture(g.TEXTURE_2D,W.texture);let l=W.compositeShader;g.uniform1i(g.getUniformLocation(l,"s"),0),g.uniform3f(g.getUniformLocation(l,"iResolution"),j.width,j.height,1),g.blendFunc(g.DST_COLOR,g.ZERO),g.drawArrays(g.TRIANGLE_STRIP,0,4),Xt&&g.bindTexture(g.TEXTURE_2D,Xt),pi(a),Ti(!0)}function o(){W.texture=void 0,W.lightShader=void 0,W.compositeShader=void 0,W.lightVAO=void 0,W.compositeVAO=void 0,gt("LightSystemPlugin: WebGL context lost")}function r(){i(),gt("LightSystemPlugin: WebGL context restored")}}drawLight(t){if(B||!F||!this.lightShader)return;Ct(),g.useProgram(this.lightShader),g.bindVertexArray(this.lightVAO);let e=b(2*q).divide(k),i=At.rotate(-$),s=b(-1).subtract(i.multiply(e)),o=ot($),r=et($),a=[e.x*o,e.y*r,0,0,-e.x*r,e.y*o,0,0,1,1,1,0,s.x,s.y,0,1],c=this.lightShader;g.uniformMatrix4fv(g.getUniformLocation(c,"m"),!1,a),g.uniform2f(g.getUniformLocation(c,"lightPos"),t.pos.x,t.pos.y),g.uniform1f(g.getUniformLocation(c,"radius"),t.radius),g.uniform1f(g.getUniformLocation(c,"fadeRange"),t.fadeRange);let l=t.color;g.uniform4f(g.getUniformLocation(c,"color"),l.r,l.g,l.b,l.a),g.drawArrays(g.TRIANGLE_STRIP,0,4),Ti(!0)}},Oo=class extends Je{constructor(t,e,i,s){super(t,b(1),void 0,0,i),p(L(e)&&e>=0,"Light radius must be a non-negative number"),p(s===void 0||L(s)&&s>=0,"Light fadeRange must be a non-negative number when provided"),this.radius=e,this.fadeRange=s===void 0?e:s}render(){}renderLight(){W&&W.drawLight(this)}},Do=class extends xi{constructor(t){super(void 0),!(!Jt||B)&&(this.randomness=0,this.sampleChannels=_c(...t),this.sampleRate=Qn)}playMusic(t=1,e=!0){return super.play(void 0,t,1,0,e)}};Wr=0;Io=class{constructor(t=at){p(!C,"UI system already initialized"),C=this,this.activateOnPress=!1,this.defaultColor=V,this.defaultLineColor=it,this.defaultTextColor=it,this.defaultButtonColor=ke(0,0,.7),this.defaultHoverColor=ke(0,0,.9),this.defaultDisabledColor=ke(0,0,.3),this.defaultGradientColor=void 0,this.defaultLineWidth=4,this.defaultCornerRadius=0,this.defaultTextFitScale=.8,this.defaultFont=Pi,this.defaultSoundPress=void 0,this.defaultSoundRelease=void 0,this.defaultSoundClick=void 0,this.defaultShadowColor=he,this.defaultShadowBlur=5,this.defaultShadowOffset=b(5),this.nativeHeight=0,this.navigationObject=void 0,this.navigationTimer=new Te(void 0,!0),this.navigationDelay=.2,this.navigationDirection=1,this.navigationMode=!1,this.uiObjects=[],this.uiContext=t,this.activeObject=void 0,this.hoverObject=void 0,this.lastHoverObject=void 0,this.confirmDialog=void 0,this._keyInputObject=void 0,this._onKeyDown=o=>{var r;return(r=this._keyInputObject)==null?void 0:r.onKeyDown(o)},_n(i,s);function e(o){let r,a;o.parent?(r=o.parent.nativePos,a=o.parent.size):(r=C.screenToNative(k.scale(.5)),a=C.nativeHeight?b(k.x*C.nativeHeight/k.y,C.nativeHeight):k);let c=o.anchor;o.nativePos=r.add(a.multiply(c).scale(.5)).subtract(o.size.multiply(c).scale(.5)).add(o.localPos)}function i(){C.activeObject&&!C.activeObject.visible&&(C.activeObject=void 0),C.lastHoverObject=C.hoverObject,C.hoverObject=void 0,yi(0)&&(C.navigationMode=!1,C.navigationObject=void 0),C.keyInputObject&&(C.activeObject=C.keyInputObject,C.hoverObject=C.keyInputObject,C.navigationMode=!1,C.navigationObject=void 0);let o=C.getNavigableObjects();if(!o.length)C.navigationObject=void 0;else if(!C.keyInputObject){if(o.includes(C.navigationObject)||(C.navigationObject=void 0),te||C.navigationMode&&!C.navigationObject&&(C.navigationObject=o.find(a=>a.navigationAutoSelect)),!C.navigationTimer.active()){let a=Qt(C.getNavigationDirection());if(a){let c;if(C.navigationObject){let l=o.indexOf(C.navigationObject),u=Zt(l+a,o.length);c=o[u]}else if(c=o.find(l=>l.navigationAutoSelect),!c){let l=a>0?0:o.length-1;c=o[l]}C.navigationObject!==c&&(C.navigationMode=!0,C.hoverObject=void 0,C.navigationObject=c,C.navigationTimer.set(C.navigationDelay),c.soundPress&&c.soundPress.play())}}C.navigationObject&&C.getNavigationWasPressed()&&C.navigationObject.navigatePressed()}for(let a=C.uiObjects.length;a--;){let c=C.uiObjects[a];c.parent||r(c)}C.uiObjects=C.uiObjects.filter(a=>!a.destroyed);function r(a){if(!(a.destroyed||!a.visible)){e(a);for(let c=a.children.length;c--;){let l=a.children[c];l&&r(l)}a.destroyed||a.update()}}}function s(){let o=C.uiContext;if(o.save(),C.nativeHeight){let a=k.y/C.nativeHeight;o.translate(-a*k.x/2,0),o.scale(a,a),o.translate(k.x/2/a,0)}function r(a){if(a.visible){e(a),a.render();for(let c of a.children)r(c)}}if(C.uiObjects.forEach(a=>a.parent||r(a)),Wr>0){let a=function(c,l=!0){l&&(l=!!c.visible),e(c),c.renderDebug(l);for(let u of c.children)a(u,l)};C.uiObjects.forEach(c=>c.parent||a(c))}o.restore()}}drawRect(t,e,i=V,s=0,o=it,r=0,a,c=it,l=0,u=b()){p(O(t),"pos must be a vec2"),p(O(e),"size must be a vec2"),p(J(i),"color must be a color"),p(L(s),"lineWidth must be a number"),p(J(o),"lineColor must be a color"),p(L(r),"cornerRadius must be a number");let h=C.uiContext;if(a){let f=h.createLinearGradient(t.x,t.y-e.y/2,t.x,t.y+e.y/2),d=i.toString();f.addColorStop(0,d),f.addColorStop(.5,a.toString()),f.addColorStop(1,d),h.fillStyle=f}else h.fillStyle=i.toString();(l||u.x||u.y)&&c.a>0&&(h.shadowColor=c.toString(),h.shadowBlur=l,h.shadowOffsetX=u.x,h.shadowOffsetY=u.y),h.beginPath(),r&&h.roundRect?h.roundRect(t.x-e.x/2,t.y-e.y/2,e.x,e.y,r):h.rect(t.x-e.x/2,t.y-e.y/2,e.x,e.y),h.fill(),h.shadowColor="#0000",s&&o.a>0&&(h.strokeStyle=o.toString(),h.lineWidth=s,h.stroke())}drawLine(t,e,i=C.defaultLineWidth,s=C.defaultLineColor){p(O(t),"posA must be a vec2"),p(O(e),"posB must be a vec2"),p(L(i),"lineWidth must be a number"),p(J(s),"lineColor must be a color");let o=C.uiContext;o.strokeStyle=s.toString(),o.lineWidth=i,o.beginPath(),o.lineTo(t.x,t.y),o.lineTo(e.x,e.y),o.stroke()}drawTile(t,e,i,s=C.defaultColor,o=0,r=!1,a=it,c=0,l=b()){let u=C.uiContext;(c||l.x||l.y)&&a.a>0&&(u.shadowColor=a.toString(),u.shadowBlur=c,u.shadowOffsetX=l.x,u.shadowOffsetY=l.y),Rt(t,e,i,s,o,r,he,!1,!0,u),u.shadowColor="#0000"}drawText(t,e,i,s=C.defaultColor,o=C.defaultLineWidth,r=C.defaultLineColor,a="center",c=C.defaultFont,l="",u=!0,h=void 0,f=it,d=0,y=b()){let x=C.uiContext;f.a>0&&(h&&en(t,e.add(h),i.y,f,o,r,a,c,l,u?i.x:void 0,0,x),(d||y.x||y.y)&&(x.shadowColor=f.toString(),x.shadowBlur=d,x.shadowOffsetX=y.x,x.shadowOffsetY=y.y)),en(t,e,i.y,s,o,r,a,c,l,u?i.x:void 0,0,x),x.shadowColor="#0000"}setupDragAndDrop(t,e,i,s){if(this._dragListeners)for(let[r,a]of this._dragListeners)document.removeEventListener(r,a);this._dragListeners=[];let o=(r,a)=>{let c=l=>{l.preventDefault(),r&&r(l)};document.addEventListener(a,c),this._dragListeners.push([a,c])};o(t,"drop"),o(e,"dragenter"),o(i,"dragleave"),o(s,"dragover")}screenToNative(t){if(!C.nativeHeight)return t;let e=k.y/C.nativeHeight,i=1/e,s=t.copy();return s.x+=e*k.x/2,s.x*=i,s.y*=i,s.x-=i*k.x/2,s}get keyInputObject(){return this._keyInputObject}set keyInputObject(t){let e=!!this._keyInputObject;this._keyInputObject=t,!e&&t?document.addEventListener("keydown",this._onKeyDown):e&&!t&&document.removeEventListener("keydown",this._onKeyDown)}destroyObjects(){for(let t of this.uiObjects)t.parent||t.destroy();this.uiObjects=this.uiObjects.filter(t=>!t.destroyed),this.activeObject=void 0,this.hoverObject=void 0,this.lastHoverObject=void 0,this.keyInputObject=void 0}getNavigableObjects(){function t(i){if(!(!i.visible||i.disabled)){i.isInteractive()&&i.navigationIndex!==void 0&&e.push(i);for(let s=i.children.length;s--;)t(i.children[s])}}let e=[];for(let i=C.uiObjects.length;i--;){let s=C.uiObjects[i];C.confirmDialog&&s!==C.confirmDialog||s.parent||t(s)}return e.sort((i,s)=>i.navigationIndex-s.navigationIndex),e}getNavigationDirection(){let t=C.navigationDirection===1,e=C.navigationDirection===2;if(Nn){let l=gi(0,pt),u=bo(pt);return e?-(l.y||u.y)||l.x||u.x:t?-(l.y||u.y):l.x||u.x}let i="ArrowUp",s="ArrowDown",o="ArrowLeft",r="ArrowRight";if(e)return Et(i)||Et(o)?-1:Et(s)||Et(r)?1:0;let a=t?i:o,c=t?s:r;return Et(a)?-1:Et(c)?1:0}getNavigationOtherDirection(){if(C.navigationDirection===2)return 0;let t=C.navigationDirection===1;if(Nn){let s=gi(0,pt),o=bo(pt);return t?s.x||o.x:s.y||o.y}let e=t?"ArrowLeft":"ArrowUp",i=t?"ArrowRight":"ArrowDown";return Et(e)?-1:Et(i)?1:0}getNavigationWasPressed(){return Nn?Rr(0,pt):Lt("Space")||Lt("Enter")}showConfirmDialog(t="Are you sure?",e,i,s=b(500,250),o="Escape"){p(!C.confirmDialog);let r=C.navigationDirection;C.navigationDirection=2;let a=new ne(b(),s);C.confirmDialog=a,a.onRender=()=>{let d=ke(0,0,0,.7);C.drawRect(b(),b(1e9),d)},a.onUpdate=()=>{Lt(o)&&f()},a.isMouseOverlapping=()=>!0;let c=50,l=new vs(b(0,-50),b(s.x-c,70),t);a.addChild(l);let u=new Ei(b(-80,50),b(120,70),"Yes");u.textHeight=40,u.navigationIndex=1,u.hoverColor=ke(0,1,.5),u.onClick=()=>{f(),e&&e()},a.addChild(u);let h=new Ei(b(80,50),b(120,70),"No");h.textHeight=40,h.navigationIndex=2,h.navigationAutoSelect=!0,h.onClick=()=>{f(),i&&i()},a.addChild(h);function f(){p(C.confirmDialog===a),a.destroy(),C.confirmDialog=void 0,C.navigationDirection=r,Gi()}}},ne=class{constructor(t=b(),e=b()){var i,s;p(O(t),"ui object pos must be a vec2"),p(O(e),"ui object size must be a vec2"),this.localPos=t.copy(),this.nativePos=t.copy(),this.size=e.copy(),this.color=C.defaultColor.copy(),this.activeColor=void 0,this.text=void 0,this.disabledColor=C.defaultDisabledColor.copy(),this.disabled=!1,this.textColor=C.defaultTextColor.copy(),this.hoverColor=C.defaultHoverColor.copy(),this.lineColor=C.defaultLineColor.copy(),this.gradientColor=C.defaultGradientColor?C.defaultGradientColor.copy():void 0,this.lineWidth=C.defaultLineWidth,this.cornerRadius=C.defaultCornerRadius,this.font=C.defaultFont,this.fontStyle=void 0,this.textWidth=void 0,this.textHeight=void 0,this.textFitScale=C.defaultTextFitScale,this.textShadow=void 0,this.textLineColor=C.defaultLineColor.copy(),this.textLineWidth=0,this.visible=!0,this.children=[],this.parent=void 0,this.extraTouchSize=0,this.soundPress=C.defaultSoundPress,this.soundRelease=C.defaultSoundRelease,this.soundClick=C.defaultSoundClick,this.interactive=!1,this.dragActivate=!1,this.canBeHover=!0,this.shadowColor=(i=C.defaultShadowColor)==null?void 0:i.copy(),this.shadowBlur=C.defaultShadowBlur,this.shadowOffset=(s=C.defaultShadowOffset)==null?void 0:s.copy(),this.navigationIndex=void 0,this.navigationAutoSelect=!1,this.anchor=b(),C.uiObjects.push(this)}addChild(t){return p(!t.parent&&!this.children.includes(t)),this.children.push(t),t.parent=this,t}removeChild(t){p(t.parent===this&&this.children.includes(t)),this.children.splice(this.children.indexOf(t),1),t.parent=void 0}destroy(){var t;if(!this.destroyed){C.activeObject===this&&(C.activeObject=void 0),C.hoverObject===this&&(C.hoverObject=void 0),C.lastHoverObject===this&&(C.lastHoverObject=void 0),C.navigationObject===this&&(C.navigationObject=void 0),C.keyInputObject===this&&(C.keyInputObject=void 0),this.destroyed=1,(t=this.parent)==null||t.removeChild(this);for(let e of this.children)e.parent=void 0,e.destroy();this.children.length=0}}isMouseOverlapping(){if(!os)return!1;let t=te?this.size.add(b(this.extraTouchSize||0)):this.size,e=C.screenToNative(Ft);return Qi(this.nativePos,t,e)}update(){if(this.onUpdate(),this.disabled&&(this===C.activeObject&&(C.activeObject=void 0),this===C.keyInputObject&&(C.keyInputObject=void 0)),C.keyInputObject)return;let t=C.lastHoverObject===this,e=this.isActiveObject(),i=li(0),s=this.dragActivate?i:yi(0);this.canBeHover&&(C.navigationMode||(s||e||!i&&!te)&&!C.hoverObject&&this.isMouseOverlapping()&&(C.hoverObject=this)),this.isHoverObject()&&(this.disabled||(s&&this.interactive&&((!this.dragActivate||!t||yi(0))&&this.onPress(),this.soundPress&&this.soundPress.play(),C.activeObject&&!e&&C.activeObject.onRelease(),C.activeObject=this,C.activateOnPress&&this.click(!this.soundPress)),C.activateOnPress||!i&&this.isActiveObject()&&this.interactive&&this.click()),s&&_r(0,0,0,1,0)),e&&(!i||this.dragActivate&&!this.isHoverObject())&&(this.onRelease(),this.soundRelease&&this.soundRelease.play(),C.activeObject=void 0),this.isHoverObject()!==t&&(this.isHoverObject()?this.onEnter():this.onLeave())}render(){if(this.onRender(),!this.size.x||!this.size.y)return;let t=this.isNavigationObject(),e=t?this.color:this.interactive&&this.isActiveObject()&&!this.disabled?this.color:this.lineColor,i=t?this.hoverColor:this.disabled?this.disabledColor:this.interactive?this.isActiveObject()?this.activeColor||this.hoverColor:this.isHoverObject()?this.hoverColor:this.color:this.color,s=this.lineWidth*(t?1.5:1);C.drawRect(this.nativePos,this.size,i,s,e,this.cornerRadius,this.gradientColor,this.shadowColor,this.shadowBlur,this.shadowOffset)}getTextSize(){return b(this.textWidth||this.textFitScale*this.size.x,this.textHeight||this.textFitScale*this.size.y)}navigatePressed(){this.click()}isHoverObject(){return C.hoverObject===this}isActiveObject(){return C.activeObject===this}isNavigationObject(){return C.navigationObject===this}isKeyInputObject(){return C.keyInputObject===this}isInteractive(){return this.interactive&&this.visible&&!this.disabled}toString(){let t="type = "+this.constructor.name;return this.text&&(t+=`
+precision highp float;uniform sampler2D s;uniform vec3 iResolution;out vec4 c;void main(){vec2 uv=gl_FragCoord.xy/iResolution.xy;c=vec4(texture(s,uv).rgb,1.);}`),W.lightVAO=y.createVertexArray(),y.bindVertexArray(W.lightVAO),y.bindBuffer(y.ARRAY_BUFFER,Mn);let a=y.getAttribLocation(W.lightShader,"g");y.enableVertexAttribArray(a),y.vertexAttribPointer(a,2,y.FLOAT,!1,8,0),W.compositeVAO=y.createVertexArray(),y.bindVertexArray(W.compositeVAO),y.bindBuffer(y.ARRAY_BUFFER,Mn);let c=y.getAttribLocation(W.compositeShader,"p");y.enableVertexAttribArray(c),y.vertexAttribPointer(c,2,y.FLOAT,!1,8,0)}function s(){if(B||!k||!W.enabled||!W.texture)return;At();let a=En,c=W.ambientColor;y.bindFramebuffer(y.FRAMEBUFFER,Or),y.framebufferTexture2D(y.FRAMEBUFFER,y.COLOR_ATTACHMENT0,y.TEXTURE_2D,W.texture,0),y.viewport(0,0,W.textureSize.x,W.textureSize.y),y.clearColor(c.r,c.g,c.b,c.a),y.clear(y.COLOR_BUFFER_BIT),ci(),y.enable(y.BLEND),y.blendFunc(y.ONE,y.ONE);for(let u of bt)u.destroyed||u.renderLight();At(),y.bindFramebuffer(y.FRAMEBUFFER,null),y.viewport(0,0,I.x,I.y),y.useProgram(W.compositeShader),y.bindVertexArray(W.compositeVAO),y.activeTexture(y.TEXTURE0),y.bindTexture(y.TEXTURE_2D,W.texture);let l=W.compositeShader;y.uniform1i(y.getUniformLocation(l,"s"),0),y.uniform3f(y.getUniformLocation(l,"iResolution"),F.width,F.height,1),y.blendFunc(y.DST_COLOR,y.ZERO),y.drawArrays(y.TRIANGLE_STRIP,0,4),Ht&&y.bindTexture(y.TEXTURE_2D,Ht),ci(a),mi(!0)}function o(){W.texture=void 0,W.lightShader=void 0,W.compositeShader=void 0,W.lightVAO=void 0,W.compositeVAO=void 0,mt("LightSystemPlugin: WebGL context lost")}function r(){i(),mt("LightSystemPlugin: WebGL context restored")}}drawLight(t){if(B||!k||!this.lightShader)return;At(),y.useProgram(this.lightShader),y.bindVertexArray(this.lightVAO);let e=x(2*q).divide(I),i=Tt.rotate(-$),s=x(-1).subtract(i.multiply(e)),o=at($),r=et($),a=[e.x*o,e.y*r,0,0,-e.x*r,e.y*o,0,0,1,1,1,0,s.x,s.y,0,1],c=this.lightShader;y.uniformMatrix4fv(y.getUniformLocation(c,"m"),!1,a),y.uniform2f(y.getUniformLocation(c,"lightPos"),t.pos.x,t.pos.y),y.uniform1f(y.getUniformLocation(c,"radius"),t.radius),y.uniform1f(y.getUniformLocation(c,"fadeRange"),t.fadeRange);let l=t.color;y.uniform4f(y.getUniformLocation(c,"color"),l.r,l.g,l.b,l.a),y.drawArrays(y.TRIANGLE_STRIP,0,4),mi(!0)}},_o=class extends ke{constructor(t,e,i,s){super(t,x(1),void 0,0,i),p(L(e)&&e>=0,"Light radius must be a non-negative number"),p(s===void 0||L(s)&&s>=0,"Light fadeRange must be a non-negative number when provided"),this.radius=e,this.fadeRange=s===void 0?e:s}render(){}renderLight(){W&&W.drawLight(this)}},Ro=class extends fi{constructor(t){super(void 0),!(!Jt||B)&&(this.randomness=0,this.sampleChannels=Tc(...t),this.sampleRate=qn)}playMusic(t=1,e=!0){return super.play(void 0,t,1,0,e)}};zr=0;Po=class{constructor(t=lt){p(!C,"UI system already initialized"),C=this,this.activateOnPress=!1,this.defaultColor=U,this.defaultLineColor=it,this.defaultTextColor=it,this.defaultButtonColor=Re(0,0,.7),this.defaultHoverColor=Re(0,0,.9),this.defaultDisabledColor=Re(0,0,.3),this.defaultGradientColor=void 0,this.defaultLineWidth=4,this.defaultCornerRadius=0,this.defaultTextFitScale=.8,this.defaultFont=Ti,this.defaultSoundPress=void 0,this.defaultSoundRelease=void 0,this.defaultSoundClick=void 0,this.defaultShadowColor=ce,this.defaultShadowBlur=5,this.defaultShadowOffset=x(5),this.nativeHeight=0,this.navigationObject=void 0,this.navigationTimer=new xe(void 0,!0),this.navigationDelay=.2,this.navigationDirection=1,this.navigationMode=!1,this.uiObjects=[],this.uiContext=t,this.activeObject=void 0,this.hoverObject=void 0,this.lastHoverObject=void 0,this.confirmDialog=void 0,this._keyInputObject=void 0,this._onKeyDown=o=>{var r;return(r=this._keyInputObject)==null?void 0:r.onKeyDown(o)},Sn(i,s);function e(o){let r,a;o.parent?(r=o.parent.nativePos,a=o.parent.size):(r=C.screenToNative(I.scale(.5)),a=C.nativeHeight?x(I.x*C.nativeHeight/I.y,C.nativeHeight):I);let c=o.anchor;o.nativePos=r.add(a.multiply(c).scale(.5)).subtract(o.size.multiply(c).scale(.5)).add(o.localPos)}function i(){C.activeObject&&!C.activeObject.visible&&(C.activeObject=void 0),C.lastHoverObject=C.hoverObject,C.hoverObject=void 0,li(0)&&(C.navigationMode=!1,C.navigationObject=void 0),C.keyInputObject&&(C.activeObject=C.keyInputObject,C.hoverObject=C.keyInputObject,C.navigationMode=!1,C.navigationObject=void 0);let o=C.getNavigableObjects();if(!o.length)C.navigationObject=void 0;else if(!C.keyInputObject){if(o.includes(C.navigationObject)||(C.navigationObject=void 0),Zt||C.navigationMode&&!C.navigationObject&&(C.navigationObject=o.find(a=>a.navigationAutoSelect)),!C.navigationTimer.active()){let a=Kt(C.getNavigationDirection());if(a){let c;if(C.navigationObject){let l=o.indexOf(C.navigationObject),u=Qt(l+a,o.length);c=o[u]}else if(c=o.find(l=>l.navigationAutoSelect),!c){let l=a>0?0:o.length-1;c=o[l]}C.navigationObject!==c&&(C.navigationMode=!0,C.hoverObject=void 0,C.navigationObject=c,C.navigationTimer.set(C.navigationDelay),c.soundPress&&c.soundPress.play())}}C.navigationObject&&C.getNavigationWasPressed()&&C.navigationObject.navigatePressed()}for(let a=C.uiObjects.length;a--;){let c=C.uiObjects[a];c.parent||r(c)}C.uiObjects=C.uiObjects.filter(a=>!a.destroyed);function r(a){if(!(a.destroyed||!a.visible)){e(a);for(let c=a.children.length;c--;){let l=a.children[c];l&&r(l)}a.destroyed||a.update()}}}function s(){let o=C.uiContext;if(o.save(),C.nativeHeight){let a=I.y/C.nativeHeight;o.translate(-a*I.x/2,0),o.scale(a,a),o.translate(I.x/2/a,0)}function r(a){if(a.visible){e(a),a.render();for(let c of a.children)r(c)}}if(C.uiObjects.forEach(a=>a.parent||r(a)),zr>0){let a=function(c,l=!0){l&&(l=!!c.visible),e(c),c.renderDebug(l);for(let u of c.children)a(u,l)};C.uiObjects.forEach(c=>c.parent||a(c))}o.restore()}}drawRect(t,e,i=U,s=0,o=it,r=0,a,c=it,l=0,u=x()){p(O(t),"pos must be a vec2"),p(O(e),"size must be a vec2"),p(z(i),"color must be a color"),p(L(s),"lineWidth must be a number"),p(z(o),"lineColor must be a color"),p(L(r),"cornerRadius must be a number");let h=C.uiContext;if(a){let f=h.createLinearGradient(t.x,t.y-e.y/2,t.x,t.y+e.y/2),d=i.toString();f.addColorStop(0,d),f.addColorStop(.5,a.toString()),f.addColorStop(1,d),h.fillStyle=f}else h.fillStyle=i.toString();(l||u.x||u.y)&&c.a>0&&(h.shadowColor=c.toString(),h.shadowBlur=l,h.shadowOffsetX=u.x,h.shadowOffsetY=u.y),h.beginPath(),r&&h.roundRect?h.roundRect(t.x-e.x/2,t.y-e.y/2,e.x,e.y,r):h.rect(t.x-e.x/2,t.y-e.y/2,e.x,e.y),h.fill(),h.shadowColor="#0000",s&&o.a>0&&(h.strokeStyle=o.toString(),h.lineWidth=s,h.stroke())}drawLine(t,e,i=C.defaultLineWidth,s=C.defaultLineColor){p(O(t),"posA must be a vec2"),p(O(e),"posB must be a vec2"),p(L(i),"lineWidth must be a number"),p(z(s),"lineColor must be a color");let o=C.uiContext;o.strokeStyle=s.toString(),o.lineWidth=i,o.beginPath(),o.lineTo(t.x,t.y),o.lineTo(e.x,e.y),o.stroke()}drawTile(t,e,i,s=C.defaultColor,o=0,r=!1,a=it,c=0,l=x()){let u=C.uiContext;(c||l.x||l.y)&&a.a>0&&(u.shadowColor=a.toString(),u.shadowBlur=c,u.shadowOffsetX=l.x,u.shadowOffsetY=l.y),_t(t,e,i,s,o,r,ce,!1,!0,u),u.shadowColor="#0000"}drawText(t,e,i,s=C.defaultColor,o=C.defaultLineWidth,r=C.defaultLineColor,a="center",c=C.defaultFont,l="",u=!0,h=void 0,f=it,d=0,g=x()){let b=C.uiContext;f.a>0&&(h&&$e(t,e.add(h),i.y,f,o,r,a,c,l,u?i.x:void 0,0,b),(d||g.x||g.y)&&(b.shadowColor=f.toString(),b.shadowBlur=d,b.shadowOffsetX=g.x,b.shadowOffsetY=g.y)),$e(t,e,i.y,s,o,r,a,c,l,u?i.x:void 0,0,b),b.shadowColor="#0000"}setupDragAndDrop(t,e,i,s){if(this._dragListeners)for(let[r,a]of this._dragListeners)document.removeEventListener(r,a);this._dragListeners=[];let o=(r,a)=>{let c=l=>{l.preventDefault(),r&&r(l)};document.addEventListener(a,c),this._dragListeners.push([a,c])};o(t,"drop"),o(e,"dragenter"),o(i,"dragleave"),o(s,"dragover")}screenToNative(t){if(!C.nativeHeight)return t;let e=I.y/C.nativeHeight,i=1/e,s=t.copy();return s.x+=e*I.x/2,s.x*=i,s.y*=i,s.x-=i*I.x/2,s}get keyInputObject(){return this._keyInputObject}set keyInputObject(t){let e=!!this._keyInputObject;this._keyInputObject=t,!e&&t?document.addEventListener("keydown",this._onKeyDown):e&&!t&&document.removeEventListener("keydown",this._onKeyDown)}destroyObjects(){for(let t of this.uiObjects)t.parent||t.destroy();this.uiObjects=this.uiObjects.filter(t=>!t.destroyed),this.activeObject=void 0,this.hoverObject=void 0,this.lastHoverObject=void 0,this.keyInputObject=void 0}getNavigableObjects(){function t(i){if(!(!i.visible||i.disabled)){i.isInteractive()&&i.navigationIndex!==void 0&&e.push(i);for(let s=i.children.length;s--;)t(i.children[s])}}let e=[];for(let i=C.uiObjects.length;i--;){let s=C.uiObjects[i];C.confirmDialog&&s!==C.confirmDialog||s.parent||t(s)}return e.sort((i,s)=>i.navigationIndex-s.navigationIndex),e}getNavigationDirection(){let t=C.navigationDirection===1,e=C.navigationDirection===2;if(In){let l=ui(0,yt),u=po(yt);return e?-(l.y||u.y)||l.x||u.x:t?-(l.y||u.y):l.x||u.x}let i="ArrowUp",s="ArrowDown",o="ArrowLeft",r="ArrowRight";if(e)return Et(i)||Et(o)?-1:Et(s)||Et(r)?1:0;let a=t?i:o,c=t?s:r;return Et(a)?-1:Et(c)?1:0}getNavigationOtherDirection(){if(C.navigationDirection===2)return 0;let t=C.navigationDirection===1;if(In){let s=ui(0,yt),o=po(yt);return t?s.x||o.x:s.y||o.y}let e=t?"ArrowLeft":"ArrowUp",i=t?"ArrowRight":"ArrowDown";return Et(e)?-1:Et(i)?1:0}getNavigationWasPressed(){return In?Ar(0,yt):Lt("Space")||Lt("Enter")}showConfirmDialog(t="Are you sure?",e,i,s=x(500,250),o="Escape"){p(!C.confirmDialog);let r=C.navigationDirection;C.navigationDirection=2;let a=new ee(x(),s);C.confirmDialog=a,a.onRender=()=>{let d=Re(0,0,0,.7);C.drawRect(x(),x(1e9),d)},a.onUpdate=()=>{Lt(o)&&f()},a.isMouseOverlapping=()=>!0;let c=50,l=new ys(x(0,-50),x(s.x-c,70),t);a.addChild(l);let u=new Si(x(-80,50),x(120,70),"Yes");u.textHeight=40,u.navigationIndex=1,u.hoverColor=Re(0,1,.5),u.onClick=()=>{f(),e&&e()},a.addChild(u);let h=new Si(x(80,50),x(120,70),"No");h.textHeight=40,h.navigationIndex=2,h.navigationAutoSelect=!0,h.onClick=()=>{f(),i&&i()},a.addChild(h);function f(){p(C.confirmDialog===a),a.destroy(),C.confirmDialog=void 0,C.navigationDirection=r,Li()}}},ee=class{constructor(t=x(),e=x()){var i,s;p(O(t),"ui object pos must be a vec2"),p(O(e),"ui object size must be a vec2"),this.localPos=t.copy(),this.nativePos=t.copy(),this.size=e.copy(),this.color=C.defaultColor.copy(),this.activeColor=void 0,this.text=void 0,this.disabledColor=C.defaultDisabledColor.copy(),this.disabled=!1,this.textColor=C.defaultTextColor.copy(),this.hoverColor=C.defaultHoverColor.copy(),this.lineColor=C.defaultLineColor.copy(),this.gradientColor=C.defaultGradientColor?C.defaultGradientColor.copy():void 0,this.lineWidth=C.defaultLineWidth,this.cornerRadius=C.defaultCornerRadius,this.font=C.defaultFont,this.fontStyle=void 0,this.textWidth=void 0,this.textHeight=void 0,this.textFitScale=C.defaultTextFitScale,this.textShadow=void 0,this.textLineColor=C.defaultLineColor.copy(),this.textLineWidth=0,this.visible=!0,this.children=[],this.parent=void 0,this.extraTouchSize=0,this.soundPress=C.defaultSoundPress,this.soundRelease=C.defaultSoundRelease,this.soundClick=C.defaultSoundClick,this.interactive=!1,this.dragActivate=!1,this.canBeHover=!0,this.shadowColor=(i=C.defaultShadowColor)==null?void 0:i.copy(),this.shadowBlur=C.defaultShadowBlur,this.shadowOffset=(s=C.defaultShadowOffset)==null?void 0:s.copy(),this.navigationIndex=void 0,this.navigationAutoSelect=!1,this.anchor=x(),C.uiObjects.push(this)}addChild(t){return p(!t.parent&&!this.children.includes(t)),this.children.push(t),t.parent=this,t}removeChild(t){p(t.parent===this&&this.children.includes(t)),this.children.splice(this.children.indexOf(t),1),t.parent=void 0}destroy(){var t;if(!this.destroyed){C.activeObject===this&&(C.activeObject=void 0),C.hoverObject===this&&(C.hoverObject=void 0),C.lastHoverObject===this&&(C.lastHoverObject=void 0),C.navigationObject===this&&(C.navigationObject=void 0),C.keyInputObject===this&&(C.keyInputObject=void 0),this.destroyed=1,(t=this.parent)==null||t.removeChild(this);for(let e of this.children)e.parent=void 0,e.destroy();this.children.length=0}}isMouseOverlapping(){if(!ts)return!1;let t=Zt?this.size.add(x(this.extraTouchSize||0)):this.size,e=C.screenToNative(Ft);return Hi(this.nativePos,t,e)}update(){if(this.onUpdate(),this.disabled&&(this===C.activeObject&&(C.activeObject=void 0),this===C.keyInputObject&&(C.keyInputObject=void 0)),C.keyInputObject)return;let t=C.lastHoverObject===this,e=this.isActiveObject(),i=ii(0),s=this.dragActivate?i:li(0);this.canBeHover&&(C.navigationMode||(s||e||!i&&!Zt)&&!C.hoverObject&&this.isMouseOverlapping()&&(C.hoverObject=this)),this.isHoverObject()&&(this.disabled||(s&&this.interactive&&((!this.dragActivate||!t||li(0))&&this.onPress(),this.soundPress&&this.soundPress.play(),C.activeObject&&!e&&C.activeObject.onRelease(),C.activeObject=this,C.activateOnPress&&this.click(!this.soundPress)),C.activateOnPress||!i&&this.isActiveObject()&&this.interactive&&this.click()),s&&wr(0,0,0,1,0)),e&&(!i||this.dragActivate&&!this.isHoverObject())&&(this.onRelease(),this.soundRelease&&this.soundRelease.play(),C.activeObject=void 0),this.isHoverObject()!==t&&(this.isHoverObject()?this.onEnter():this.onLeave())}render(){if(this.onRender(),!this.size.x||!this.size.y)return;let t=this.isNavigationObject(),e=t?this.color:this.interactive&&this.isActiveObject()&&!this.disabled?this.color:this.lineColor,i=t?this.hoverColor:this.disabled?this.disabledColor:this.interactive?this.isActiveObject()?this.activeColor||this.hoverColor:this.isHoverObject()?this.hoverColor:this.color:this.color,s=this.lineWidth*(t?1.5:1);C.drawRect(this.nativePos,this.size,i,s,e,this.cornerRadius,this.gradientColor,this.shadowColor,this.shadowBlur,this.shadowOffset)}getTextSize(){return x(this.textWidth||this.textFitScale*this.size.x,this.textHeight||this.textFitScale*this.size.y)}navigatePressed(){this.click()}isHoverObject(){return C.hoverObject===this}isActiveObject(){return C.activeObject===this}isNavigationObject(){return C.navigationObject===this}isKeyInputObject(){return C.keyInputObject===this}isInteractive(){return this.interactive&&this.visible&&!this.disabled}toString(){let t="type = "+this.constructor.name;return this.text&&(t+=`
 text = `+this.text),(this.nativePos.x||this.nativePos.y)&&(t+=`
 nativePos = `+this.nativePos),(this.localPos.x||this.localPos.y)&&(t+=`
 localPos = `+this.localPos),(this.size.x||this.size.y)&&(t+=`
 size = `+this.size),this.color&&(t+=`
-color = `+this.color),t}renderDebug(t=!0){let e=t?this.isHoverObject()?Ka:this.disabled?tc:this.interactive?rr:Za:Qa;C.drawRect(this.nativePos,this.size,he,4,e)}click(t=!0){this.onClick(),t&&this.soundClick&&this.soundClick.play()}onUpdate(){}onRender(){}onEnter(){}onLeave(){}onPress(){}onRelease(){}onClick(){}onChange(){}},vs=class extends ne{constructor(t,e,i="",s="center",o=C.defaultFont){super(t,e),p(U(i),"ui text must be a string"),p(["left","center","right"].includes(s),"ui text align must be left, center, or right"),p(U(o),"ui text font must be a string"),this.text=i,this.align=s,this.font=o,this.canBeHover=!1,this.color=he,this.shadowColor=he,this.gradientColor=void 0,this.lineWidth=0,this.textFitScale=1}render(){super.render();let t=this.getTextSize();C.drawText(this.text,this.nativePos,t,this.textColor,this.textLineWidth,this.textLineColor,this.align,this.font,this.fontStyle,!0,this.textShadow,this.shadowColor,this.shadowBlur,this.shadowOffset)}},Mo=class extends ne{constructor(t,e,i=""){super(t,e),p(U(i),"ui text must be a string"),this.maxLength=0,this.text=i,this.interactive=!0,this.canBeHover=!0}click(){C.keyInputObject=this,this.onClick()}stopEditing(){this.isKeyInputObject()&&(this.soundRelease&&this.soundRelease.play(),C.activeObject=void 0,C.keyInputObject=void 0,this.onChange())}onKeyDown(t){let e=t.code,i=t.key;e==="Backspace"?this.text=this.text.slice(0,-1):e==="Enter"||e==="Escape"?this.stopEditing():i.length===1&&(!this.maxLength||this.text.lengththis.size.y,i=e?this.size.y:this.size.x,s=e?this.size.x:this.size.y,o=e?this.nativePos.x:this.nativePos.y,r=s-i,a=o-r/2,c=o+r/2,l=C.screenToNative(Ft);this.value=e?It(l.x,a,c):It(l.y,c,a)}else if(this.isNavigationObject()){let e=C.getNavigationOtherDirection();C.navigationTimer.active()||(this.value=N(this.value+e*.01))}this.value===t||this.onChange()}render(){super.render();let t=this.size.x>this.size.y,e=t?this.size.x:this.size.y,i=t?this.size.y:this.size.x;if(this.fillMode){let o=K(i,this.cornerRadius*2),r=Bt(o,e,this.value),a=(r-e)*(t?.5:-.5),c=this.nativePos.add(t?b(a,0):b(0,a)),l=this.disabled?this.disabledColor:this.handleColor,u=t?b(r,this.size.y):b(this.size.x,r);C.drawRect(c,u,l,this.lineWidth,this.lineColor,this.cornerRadius,this.gradientColor)}else{let o=N(t?this.value:1-this.value),r=(e-i)*(o-.5),a=this.nativePos.add(t?b(r,0):b(0,r)),c=this.disabled?this.disabledColor:this.handleColor,l=b(i);C.drawRect(a,l,c,this.lineWidth,this.lineColor,this.cornerRadius,this.gradientColor)}let s=this.getTextSize();C.drawText(this.text,this.nativePos,s,this.textColor,this.textLineWidth,this.textLineColor,this.align,this.font,this.fontStyle,!0,this.textShadow)}navigatePressed(){this.value=this.value?0:1,this.onChange(),this.onRelease(),super.navigatePressed()}},jo=class extends ne{constructor(t,e,i,s=!1,o=!1,r=1){super(t,e||b()),p(U(i),"video src must be a string"),p(L(r),"video volume must be a number"),this.color=it,this.cornerRadius=0,this.volume=r,this.video=document.createElement("video"),this.video.loop=o,this.video.volume=N(r*Sn),this.video.muted=!Jt,this.video.style.display="none",this.video.src=i,document.body.appendChild(this.video),s&&this.play()}async play(){try{await this.video.play()}catch{}}pause(){this.video.pause()}stop(){this.video.pause(),this.video.currentTime=0}isLoading(){return this.video.readyState=1,"ui layout columns must be a number >= 1"),p(L(i),"ui layout gap must be a number"),p(L(s),"ui layout padding must be a number"),this.columns=e,this.gap=i,this.padding=s,o&&(this.color=he,this.gradientColor=void 0,this.lineWidth=0,this.shadowColor=he),this.relayout()}addChild(t){return super.addChild(t),this.relayout(),t}removeChild(t){super.removeChild(t),this.relayout()}relayout(){let t=this.children.length;if(!t){this.size=b(this.padding*2);return}let e=this.columns,i=hi(t/e),s=new Array(e).fill(0),o=new Array(i).fill(0);for(let f=0;f=0&&m.objects.splice(t,1),super.destroy()}updatePhysics(){}render(){this.tileInfo?super.render():this.drawFixtures(this.color,this.lineColor,this.lineWidth)}renderDebugInfo(){let t=!this.getIsAwake(),e=this.getBodyType()===m.bodyTypeStatic,i=z(t?1:0,t?1:0,e?1:0,.5);this.drawFixtures(i)}drawFixtures(t=V,e=it,i=.1,s,o){this.getFixtureList().forEach(r=>{m.castShapeObject(r.GetShape()).GetType()!==m.instance.b2Shape.e_edge&&m.drawFixture(r,this.pos,this.angle,t,e,i,s,o)}),this.edgeLists.forEach(r=>mo(r,i,e,!1,this.pos,this.angle)),this.edgeLoops.forEach(r=>mo(r,i,e,!0,this.pos,this.angle))}beginContact(t){}endContact(t){}addShape(t,e=1,i=.2,s=0,o=!1){p(L(e),"density must be a number"),p(L(i),"friction must be a number"),p(L(s),"restitution must be a number");let r=new m.instance.b2FixtureDef;return r.set_shape(t),r.set_density(e),r.set_friction(i),r.set_restitution(s),r.set_isSensor(o),this.body.CreateFixture(r)}addBox(t=b(1),e=b(),i=0,s,o,r,a){p(O(t),"size must be a Vector2"),p(t.x>0&&t.y>0,"size must be positive"),p(O(e),"offset must be a Vector2"),p(L(i),"angle must be a number");let c=new m.instance.b2PolygonShape;return c.SetAsBox(t.x/2,t.y/2,m.vec2dTo(e),-i),this.addShape(c,s,o,r,a)}addPoly(t,e,i,s,o){p(le(t),"points must be an array");function r(c){p(3<=c.length&&c.length<=8);let l=m.instance._malloc(c.length*8);for(let f=0,d=0;f>2]=c[f].x,d+=4,m.instance.HEAPF32[l+d>>2]=c[f].y,d+=4;let u=m.instance.wrapPointer(l,m.instance.b2Vec2),h=new m.instance.b2PolygonShape;return h.Set(u,c.length),m.instance._free(l),h}let a=r(t);return this.addShape(a,e,i,s,o)}addRegularPoly(t=1,e=8,i,s,o,r){p(L(t)&&t>0,"diameter must be a positive number"),p(L(e)&&e>2,"sides must be a positive number greater than 2");let a=[],c=t/2;for(let l=e;l--;)a.push(b(c,0).rotate((l+.5)/e*H*2));return this.addPoly(a,i,s,o,r)}addRandomPoly(t=1,e,i,s,o){p(L(t)&&t>0,"diameter must be a positive number");let r=or(3,9),a=[],c=t/2;for(let l=r;l--;)a.push(b(lt(c/2,c*1.5),0).rotate(l/r*H*2));return this.addPoly(a,e,i,s,o)}addCircle(t=1,e=b(),i,s,o,r){p(L(t)&&t>0,"diameter must be a positive number"),p(O(e),"offset must be a Vector2");let a=new m.instance.b2CircleShape;return a.set_m_p(m.vec2dTo(e)),a.set_m_radius(t/2),this.addShape(a,i,s,o,r)}addEdge(t,e,i,s,o,r){p(O(t),"point1 must be a Vector2"),p(O(e),"point2 must be a Vector2");let a=new m.instance.b2EdgeShape;return a.Set(m.vec2dTo(t),m.vec2dTo(e)),this.addShape(a,i,s,o,r)}addEdgeList(t,e,i,s,o){p(le(t),"points must be an array");let r=[],a=[];for(let c=0;ct[Zt(l,t.length)];for(let l=0;lthis.destroyFixture(t))}getCenterOfMass(){return m.vec2From(this.body.GetWorldCenter())}getLinearVelocity(){return m.vec2From(this.body.GetLinearVelocity())}getAngularVelocity(){return this.body.GetAngularVelocity()}getMass(){return this.body.GetMass()}getInertia(){return this.body.GetInertia()}getIsAwake(){return this.body.IsAwake()}getBodyType(){return this.body.GetType()}getSpeed(){return this.getLinearVelocity().length()}setTransform(t,e){this.pos=t,this.angle=e,this.body.SetTransform(m.vec2dTo(t),-e)}setPosition(t){this.setTransform(t,this.body.GetAngle())}setAngle(t){this.setTransform(m.vec2From(this.body.GetPosition()),t)}setLinearVelocity(t){this.body.SetLinearVelocity(m.vec2dTo(t))}setAngularVelocity(t){this.body.SetAngularVelocity(t)}setLinearDamping(t){this.body.SetLinearDamping(t)}setAngularDamping(t){this.body.SetAngularDamping(t)}setGravityScale(t=1){this.body.SetGravityScale(this.gravityScale=t)}setBullet(t=!0){this.body.SetBullet(t)}setAwake(t=!0){this.body.SetAwake(t)}setBodyType(t){this.body.SetType(t)}setSleepingAllowed(t=!0){this.body.SetSleepingAllowed(t)}setFixedRotation(t=!0){this.body.SetFixedRotation(t)}setCenterOfMass(t){this.setMassData(t)}setMass(t){this.setMassData(void 0,t)}setMomentOfInertia(t){this.setMassData(void 0,void 0,t)}resetMassData(){this.body.ResetMassData()}setMassData(t,e,i){let s=new m.instance.b2MassData;this.body.GetMassData(s),t!==void 0&&s.set_center(m.vec2dTo(t)),e!==void 0&&s.set_mass(e),i!==void 0&&s.set_I(i),this.body.SetMassData(s)}setFilterData(t=0,e=0,i=0){this.getFixtureList().forEach(s=>{let o=s.GetFilterData();o.set_categoryBits(t),o.set_maskBits(65535&~e),o.set_groupIndex(i)})}setSensor(t=!0){this.getFixtureList().forEach(e=>e.SetSensor(t))}applyForce(t,e){e||(e=this.getCenterOfMass()),this.setAwake(),this.body.ApplyForce(m.vec2dTo(t),m.vec2dTo(e))}applyAcceleration(t,e){e||(e=this.getCenterOfMass()),this.setAwake();let i=t.scale(this.getMass());this.body.ApplyLinearImpulse(m.vec2dTo(i),m.vec2dTo(e))}applyImpulse(t,e){e||(e=this.getCenterOfMass()),this.setAwake(),this.body.ApplyLinearImpulse(m.vec2dTo(t),m.vec2dTo(e))}applyTorque(t){this.setAwake(),this.body.ApplyTorque(t)}applyAngularAcceleration(t){this.setAwake(),this.body.ApplyAngularImpulse(t*this.getInertia())}applyAngularImpulse(t){this.setAwake(),this.body.ApplyAngularImpulse(t)}hasFixtures(){return!m.isNull(this.body.GetFixtureList())}getFixtureList(){let t=[];for(let e=this.body.GetFixtureList();!m.isNull(e);)t.push(e),e=e.GetNext();return t}hasJoints(){return!m.isNull(this.body.GetJointList())}getJointList(){let t=[];for(let e=this.body.GetJointList();!m.isNull(e);)t.push(e),e=e.get_next();return t}},Ss=class extends Ri{constructor(t,e,i,s=0,o,r=0){let a=m.bodyTypeStatic;super(t,e,i,s,o,a,r)}},Bo=class extends Ri{constructor(t,e,i,s=0,o,r=0){let a=m.bodyTypeKinematic;super(t,e,i,s,o,a,r)}},zo=class extends Ss{constructor(t){p(t instanceof Si,"tileLayer must be a TileCollisionLayer"),super(t.pos,t.size),this.tileLayer=t,this.addChild(t)}render(){}buildCollision(t=.2,e=0){this.destroyAllFixtures(),this.pos=this.tileLayer.pos.copy(),this.size=this.tileLayer.size.copy();let i=[],s=(r,a)=>r+a*this.size.x,o=(r,a)=>!i[s(r,a)]&&this.tileLayer.getCollisionData(b(r,a))>0;for(let r=0;rs.fractiono.pos.distanceSquared(t)0,"Tween duration must be > 0"),this.callback=t,this.start=e,this.end=i,this.duration=s,this.life=s,this.ease=o.ease||_s.LINEAR,this.useRealTime=!!o.useRealTime,this.paused=!!o.paused,this.thenCallback=void 0,this.loopRemaining=0,qt.push(this),t(this.interp(s))}setEase(t){return this.ease=t,this}then(t){return this.thenCallback=t,this.loopRemaining=0,this}loop(t=1/0){return this.loopRemaining=t,this.thenCallback=()=>Lc(this),this}pingPong(t=1/0){return this.loopRemaining=t,this.thenCallback=()=>Oc(this),this}pause(){this.paused=!0}resume(){this.paused=!1}restart(){this.life=this.duration,this.paused=!1,qt.indexOf(this)<0&&qt.push(this),this.callback(this.interp(this.duration))}isActive(){return!this.paused&&qt.indexOf(this)>=0}getPercent(){return It(this.duration-this.life,0,this.duration)}getValue(){return this.interp(this.life)}interp(t){let e=this.ease((this.duration-t)/this.duration);return La(this.start)?this.start.lerp(this.end,e):this.start+(this.end-this.start)*e}stop(){let t=qt.indexOf(this);t>=0&&qt.splice(t,1),this.thenCallback=void 0}},_s={LINEAR:n=>n,POWER:n=>t=>t**n,SINE:n=>1-ot(n*(H/2)),CIRC:n=>1-(1-n*n)**.5,EXPO:n=>n===0?0:2**(10*n-10),BACK:n=>n*n*(2.70158*n-1.70158),ELASTIC:n=>n===0?0:n===1?1:-(2**(10*n-10))*et((37-40*n)*H/6),SPRING:n=>1-(et(H*(1-n)*(.2+2.5*(1-n)**3))*n**2.2+(1-n))*(1+1.2*n),BOUNCE:n=>{let t=1-n,e;return t<4/11?e=7.5625*t*t:t<8/11?e=7.5625*(t-=6/11)*t+.75:t<10/11?e=7.5625*(t-=9/11)*t+.9375:e=7.5625*(t-=10.5/11)*t+.984375,1-e},IN:n=>n,OUT:n=>t=>1-n(1-t),IN_OUT:n=>_s.PIECEWISE(n,_s.OUT(n)),PIECEWISE:(...n)=>{let t=n.length;return e=>{let i=e*t-1e-9>>0;return(n[i]((e-i/t)*t)+i)/t}},BEZIER:(n,t,e,i)=>{let s=o=>{let r=1-o,a=3*r*r*o,c=3*r*o*o,l=o**3;return[a*n+c*e+l,a*t+c*i+l]};return o=>{let r=0,a=1;for(let c=0;c<128;c++){let l=(r+a)/2,[u,h]=s(l);if(tt(u-o)<1e-5)return h;u=this.size.x||e>=this.size.y?null:this.nodes[t+e*this.size.x]}worldToTile(t){let e=this.tileLayer?this.tileLayer.pos.x:0,i=this.tileLayer?this.tileLayer.pos.y:0;return b(vt(t.x-e),vt(t.y-i))}tileToWorld(t,e){let i=this.tileLayer?this.tileLayer.pos.x:0,s=this.tileLayer?this.tileLayer.pos.y:0;return b(t+.5+i,e+.5+s)}buildNodeData(){let t=this.size.x,e=this.size.y,i=this.tileLayer?this.tileLayer.pos.x:0,s=this.tileLayer?this.tileLayer.pos.y:0;for(let o=0;o0&&(c?l>0&&yt(a.posWorld,lo,z(1,0,0,K(.2,l*.05)),this.debugTime):yt(a.posWorld,lo,z(1,0,0,.25),this.debugTime))}}aStarSearch(t,e){p(t&&e,"aStarSearch needs both endpoints"),p(t!==e,"aStarSearch: start and end must differ \u2014 caller should handle trivial case"),p(t.walkable&&e.walkable,"aStarSearch: endpoints must be walkable");let i=[t];t.isOpen=!0;let s=0;for(;i.length>0;){let o=0,r=i[0].f;for(let c=1;cthis.maxLoop)break;a.isOpen=!1,i.splice(o,1),a.isClosed=!0,this.debug&&this.debugTime>0&&yt(a.posWorld,lo,z(1,1,1,.05),this.debugTime);for(let c=-1;c<=1;++c)for(let l=-1;l<=1;++l){if(l===0&&c===0)continue;let u=this.getNode(a.pos.x+l,a.pos.y+c);if(!u||!u.walkable||u.isClosed)continue;let h=1;if(l!==0&&c!==0){let v=this.getNode(a.pos.x+l,a.pos.y);if(!v||!v.walkable)continue;let w=this.getNode(a.pos.x,a.pos.y+c);if(!w||!w.walkable)continue;h=fd}let f=a.g+h+u.cost;if(!u.isOpen)u.isOpen=!0,i.push(u);else if(f>=u.g)continue;u.parent=a,u.g=f;let d=tt(e.pos.x-u.pos.x),y=tt(e.pos.y-u.pos.y),x=Y(d,y)+(Math.SQRT2-1)*K(d,y);u.f=u.g+x*this.heuristicWeight}}return e.parent!==null}getNearestClearNode(t,e=10,i=!0){p(O(t),"worldPos must be a Vector2"),i&&this.buildNodeData();let s=this.tileLayer?this.tileLayer.pos.x:0,o=this.tileLayer?this.tileLayer.pos.y:0,r=vt(t.x-s),a=vt(t.y-o);for(let c=0;c<=e;++c){let l=null,u=0;for(let h=-c;h<=c;++h)for(let f=-c;f<=c;++f){if(c>0&&tt(f)!==c&&tt(h)!==c)continue;let d=this.getNode(r+f,a+h);if(!d||!d.isClear())continue;let y=d.posWorld.x-t.x,x=d.posWorld.y-t.y,v=y*y+x*x;(!l||v0&&jt(s.posWorld,.3,z(.5,0,.5,.5),this.debugTime),t.splice(e,1),e=Y(1,e-1);continue}else if(c===2){this.debug&&this.debugTime>0&&jt(s.posWorld,.3,z(1,0,0,.5),this.debugTime);let d,y;i.pos.y===s.pos.y&&o.pos.x===s.pos.x?(d=i.pos.x,y=o.pos.y):(d=o.pos.x,y=i.pos.y);let x=this.getNode(d,y);if(x&&x.isClear()){t.splice(e,1),e=Y(1,e-1);continue}}else if(c===5){this.debug&&this.debugTime>0&&jt(s.posWorld,.3,z(1,1,0,.5),this.debugTime);let d=e>=2?t[e-2]:i,y,x,v,w;l===0||h===0?(y=o.pos.x,x=s.pos.y,v=i.pos.x,w=s.pos.y):(y=s.pos.x,x=o.pos.y,v=s.pos.x,w=i.pos.y);let _=y-d.pos.x,S=x-d.pos.y,E=v-d.pos.x,A=w-d.pos.y,T=_*_+S*S,P=E*E+A*A,G=T0&&jt(s.posWorld,.3,z(0,1,0,.5),this.debugTime),l===h&&u===f){++e;continue}else{let d,y;i.pos.y===o.pos.y?(d=s.pos.x,y=i.pos.y):(d=i.pos.x,y=s.pos.y);let x=this.getNode(d,y);if(x&&x.isClear()){t[e]=x,e=Y(1,e-1);continue}}++e}}smoothPathStringPull(t){if(t.length<=2)return;for(let s of t)if(!s.isClear())return;let e=t.slice();t.length=0,t.push(e[0]);let i=0;for(let s=1;s0&&ve(o.posWorld,t[t.length-1].posWorld,z(0,0,1,.3),.02,this.debugTime);continue}for(;i=1;--e){let i=t[e-1],s=t[e],o=t[e+1];(s.pos.x-i.pos.x)*(o.pos.y-i.pos.y)===(s.pos.y-i.pos.y)*(o.pos.x-i.pos.x)&&t.splice(e,1)}}isNodeClear(t,e){let i=this.getNode(t,e);return i!==null&&i.isClear()}isLineClear(t,e){p(O(t)&&O(e),"isLineClear needs Vector2 endpoints"),p(this.isNodeClear(t.x,t.y)&&this.isNodeClear(e.x,e.y),"isLineClear endpoints must be in-bounds and clear");let i=e.x-t.x,s=e.y-t.y,o=tt(i),r=tt(s),a=Qt(i),c=Qt(s),l=t.x,u=t.y;if(r===o){for(;l!==e.x;){if(l!==t.x&&(!this.isNodeClear(l,u)||!this.isNodeClear(l,u-c))||!this.isNodeClear(l,u+c))return!1;l+=a,u+=c}if(!this.isNodeClear(e.x,e.y-c))return!1}else if(ra.posWorld.copy());if(this.debug&&this.debugTime>0&&r.length>0){for(let a=1;apd,bootGameHost:()=>gd,default:()=>yd});var ji=class{constructor(t){this._state=(t==null?2654435769:t)>>>0}next(){this._state=this._state+1831565813>>>0;let t=this._state;return t=Math.imul(t^t>>>15,t|1),t^=t+Math.imul(t^t>>>7,t|61),((t^t>>>14)>>>0)/4294967296}range(t,e){return t+this.next()*(e-t)}reseed(t){this._state=(t==null?2654435769:t)>>>0}},Js=class{constructor(t){this._clock=t||Jc(),this._origin=this._clock()}nowMs(){return this._clock()}elapsedMs(){return this._clock()-this._origin}},Us=class{constructor(t){this._time=t,this._subs=new Map}sourceFor(t){let e=this,i=t==null?null:t;return{on(s,o){if(e._assertType(s),typeof o!="function")throw new Error("[HostDevInputBridge] on \u7684 handler \u5FC5\u987B\u662F\u51FD\u6570");let r=e._subs.get(s)||[],a={handler:o,scope:i};return r.push(a),e._subs.set(s,r),{cancel(){let c=e._subs.get(s);if(!c)return;let l=c.indexOf(a);l>=0&&c.splice(l,1)}}},off(s,o){e._assertType(s);let r=e._subs.get(s);if(!r)return;let a=r.findIndex(c=>c.handler===o&&c.scope===i);a>=0&&r.splice(a,1)}}}_emit(t,e){this._assertType(t);let i=e||{},s={type:t,x:typeof i.x=="number"?i.x:0,y:typeof i.y=="number"?i.y:0,key:typeof i.key=="string"?i.key:"",tMs:this._time.nowMs()},o=this._subs.get(t);if(!o||o.length===0)return;let r=o.slice();for(let a of r)try{a.handler(s)}catch(c){We("[host-dev input] \u8F93\u5165 handler \u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09type="+t,c)}}disposeScope(t){if(t==null)return 0;let e=0;for(let[i,s]of this._subs){let o=s.filter(r=>r.scope!==t);e+=s.length-o.length,o.length===0?this._subs.delete(i):this._subs.set(i,o)}return e}_subscriptionCount(){let t=0;for(let e of this._subs.values())t+=e.length;return t}_assertType(t){if(!Vs.has(t))throw new Error("[HostDevInputBridge] \u975E\u6CD5\u8F93\u5165\u4E8B\u4EF6\u7C7B\u578B\uFF1A"+String(t)+"\uFF08\u4EC5\u652F\u6301 "+Array.from(Vs).join("/")+"\uFF09")}},Vs=new Set(["pointerdown","pointermove","pointerup","keydown","keyup"]);function Xr(n){let t=n||{},e=new Js(t.clock),i=new ji(t.seed),s=t.seed==null?2654435769:t.seed>>>0,o=new Us(e),r=typeof t.audioFactory=="function"?t.audioFactory:null,a=null,c=!1,l=typeof t.engineFactory=="function"?t.engineFactory:null,u=null,h=!1,f=new Map,d=0,y=0;function x(){if(a)return a;if(!r)return c||(qs("[host-dev audio] \u672A\u6CE8\u5165 audioFactory\uFF0CgetAudioContext \u8FD4\u56DE null\uFF08P6 \u987B\u5BB9\u9519\u964D\u7EA7\uFF1B\u96C6\u6210\u6BB5\u6CE8\u5165\u771F\u5B9E\u5DE5\u5382\uFF09"),c=!0),null;try{a=r()}catch(E){We("[host-dev audio] audioFactory \u629B\u9519\uFF0CgetAudioContext \u964D\u7EA7\u8FD4\u56DE null",E),a=null}return a}function v(){if(u)return u;if(!l)return h||(qs("[host-dev engine] \u672A\u6CE8\u5165 engineFactory\uFF0CgetEngine \u8FD4\u56DE null\uFF08\u63D2\u4EF6\u987B\u5BB9\u9519\u964D\u7EA7\uFF1A\u7C92\u5B50\u9000\u53D7\u63A7\u9762\u81EA\u7BA1/\u5408\u6210\u6838\u9000 vendored/\u6570\u5B66\u9000\u5185\u7F6E\uFF1B\u96C6\u6210\u6BB5\u6CE8\u5165\u771F\u5B9E\u80CC\u4E66\uFF09"),h=!0),null;try{u=l()}catch(E){We("[host-dev engine] engineFactory \u629B\u9519\uFF0CgetEngine \u964D\u7EA7\u8FD4\u56DE null",E),u=null}return u}function w(E,A){return{getContext2d(){return t.context2d==null?null:t.context2d},onFrame(P){let G=d++;return f.set(G,P),{cancel(){f.delete(G)}}},getInput(){return o.sourceFor(E)},getAudioContext(){return x()},getEngine(){return v()},time:e,random:A}}let _=w(null,i),S={context:_,tick(E){y+=1;let A=Array.from(f.values());for(let T of A)try{T(E,y)}catch(P){We("[host-dev tick] \u5E27\u56DE\u8C03\u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09frame="+y,P)}},frameCount(){return y},inputBridge:o,deriveContextFor(E,A){let T=zc(s,E),P=new ji(T);return w(A==null?E:A,P)}};return Object.defineProperty(_,Ws,{value:S,enumerable:!1,writable:!1,configurable:!1}),S}var Ws=Symbol("zaomeng.coreProtocol.contextBundle"),Ni=class{constructor(){this._plugins=new Map,this._initOrder=[],this._initErrors=[],this._phase="idle",this._disposed=!1,this._context=void 0,this._pluginContexts=new Map}register(t){if(!t||typeof t!="object")throw new Error("[PluginRegistry] register \u9700\u8981\u4E00\u4E2A\u63D2\u4EF6\u5BF9\u8C61");if(typeof t.name!="string"||t.name.length===0)throw new Error("[PluginRegistry] \u63D2\u4EF6\u7F3A\u5C11\u5408\u6CD5 name");if(typeof t.version!="string"||t.version.length===0)throw new Error("[PluginRegistry] \u63D2\u4EF6 "+t.name+" \u7F3A\u5C11\u5408\u6CD5 version");if(typeof t.init!="function")throw new Error("[PluginRegistry] \u63D2\u4EF6 "+t.name+" \u7F3A\u5C11 init \u51FD\u6570");if(t.dispose!=null&&typeof t.dispose!="function")throw new Error("[PluginRegistry] \u63D2\u4EF6 "+t.name+" \u7684 dispose \u5FC5\u987B\u662F\u51FD\u6570\u6216\u7701\u7565");if(this._plugins.has(t.name))throw new Error("[PluginRegistry] \u63D2\u4EF6\u91CD\u540D\u62D2\u7EDD\uFF1A"+t.name+" \u5DF2\u6CE8\u518C");return this._plugins.set(t.name,t),this}has(t){return this._plugins.has(t)}get(t){return this._plugins.get(t)}list(){return Array.from(this._plugins.keys())}initAll(){if(this._phase==="initialized")return qs("[PluginRegistry] initAll \u91CD\u590D\u8C03\u7528\uFF0C\u5DF2\u5FFD\u7565\uFF08\u5DF2\u5904\u4E8E initialized\uFF09"),this._initResult();if(this._phase==="disposed")throw new Error("[PluginRegistry] \u5DF2 dispose \u7684\u6CE8\u518C\u5668\u4E0D\u53EF\u518D initAll");if(this._context==null)throw new Error("[PluginRegistry] \u672A\u6CE8\u5165\u53D7\u63A7\u4E0A\u4E0B\u6587\uFF1A\u8BF7\u5728 initAll() \u4E4B\u524D\u8C03\u7528 useContext(context)\u3002\uFF08host-dev \u7528\u6CD5\uFF1Aconst { context } = createHostDevContext(); reg.useContext(context); reg.initAll();\uFF09");for(let[t,e]of this._plugins){let i=this._missingDeps(e);if(i.length>0){let o=new Error("[PluginRegistry] \u63D2\u4EF6 "+t+" \u4F9D\u8D56\u7F3A\u5931\uFF1A"+i.join(", ")+"\uFF08\u672A\u6CE8\u518C\uFF09");this._initErrors.push({name:t,error:o}),We("[PluginRegistry] \u8DF3\u8FC7 init\uFF08\u4F9D\u8D56\u7F3A\u5931\uFF0C\u5DF2\u9694\u79BB\uFF09\uFF1A"+t,o);continue}let s=this._contextFor(t);try{e.init(s),this._initOrder.push(t)}catch(o){let r=o instanceof Error?o:new Error(String(o));this._initErrors.push({name:t,error:r}),We("[PluginRegistry] \u63D2\u4EF6 init \u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF0C\u4E0D\u8FDE\u5750\uFF09\uFF1A"+t,r)}}return this._phase="initialized",this._initResult()}_contextFor(t){let e=this._pluginContexts.get(t);if(e)return e;let i=this._context&&this._context[Ws],s;return i&&typeof i.deriveContextFor=="function"?s=i.deriveContextFor(t,t):s=this._context,this._pluginContexts.set(t,s),s}disposeAll(){if(this._disposed)return{disposed:[],errors:[]};let t=[],e=[],i=this._context&&this._context[Ws],s=i&&i.inputBridge;for(let o=this._initOrder.length-1;o>=0;o--){let r=this._initOrder[o],a=this._plugins.get(r);if(a&&typeof a.dispose=="function")try{a.dispose(),t.push(r)}catch(c){let l=c instanceof Error?c:new Error(String(c));e.push({name:r,error:l}),We("[PluginRegistry] \u63D2\u4EF6 dispose \u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09\uFF1A"+r,l)}if(s&&typeof s.disposeScope=="function")try{s.disposeScope(r)}catch(c){We("[PluginRegistry] \u56DE\u6536\u63D2\u4EF6\u8F93\u5165\u8BA2\u9605\u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09\uFF1A"+r,c)}}return this._disposed=!0,this._phase="disposed",{disposed:t,errors:e}}useContext(t){if(this._phase!=="idle")throw new Error("[PluginRegistry] useContext \u5FC5\u987B\u5728 initAll() \u4E4B\u524D\u8C03\u7528\uFF08\u5F53\u524D\u9636\u6BB5\uFF1A"+this._phase+"\uFF09\u3002\u8BF7\u5728\u4EFB\u4F55 initAll/disposeAll \u4E4B\u524D\u6CE8\u5165\u53D7\u63A7\u4E0A\u4E0B\u6587\u3002");if(t==null||typeof t!="object")throw new Error("[PluginRegistry] useContext \u9700\u8981\u4E00\u4E2A\u53D7\u63A7\u4E0A\u4E0B\u6587\u5BF9\u8C61\u3002\uFF08host-dev \u7528\u6CD5\uFF1Aconst { context } = createHostDevContext(); reg.useContext(context);\uFF09");return this._context=t,this}_missingDeps(t){return!Array.isArray(t.dependencies)||t.dependencies.length===0?[]:t.dependencies.filter(e=>!this._plugins.has(e))}_initResult(){return{ok:this._initErrors.length===0,initialized:this._initOrder.slice(),errors:this._initErrors.slice()}}};function zc(n,t){let e=2166136261,i=16777619,s=n>>>0;for(let r=0;r<32;r+=8){let a=s>>>r&255;e^=a,e=Math.imul(e,i)>>>0}let o=String(t);for(let r=0;r>>0,e^=a>>>8&255,e=Math.imul(e,i)>>>0}return e>>>0}function Jc(){if(typeof globalThis!="undefined"&&globalThis.performance&&typeof globalThis.performance.now=="function")return()=>globalThis.performance.now();if(typeof process!="undefined"&&process.hrtime&&typeof process.hrtime.bigint=="function"){let n=process.hrtime.bigint();return()=>Number(process.hrtime.bigint()-n)/1e6}return()=>Date.now()}function We(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function qs(n){typeof console!="undefined"&&typeof console.warn=="function"&&console.warn(n)}var xd=Object.freeze(Array.from(Vs)),Yr="core-protocol-v0";var $r=Object.freeze(["t_boot","t_plugins_ready","t_game_init","t_first_paint","t_input_bound","t_game_start"]),Hs=$r.reduce((n,t,e)=>(n[t]=e,n),Object.create(null)),Uc=new Set($r);function Xs(n){let t=2166136261;for(let e=0;e>>0).toString(16).padStart(8,"0")}var Kr=Xs("runtime-probe::seed::v1");function Bi(n){return n===null||typeof n!="object"?JSON.stringify(n):Array.isArray(n)?"["+n.map(Bi).join(",")+"]":"{"+Object.keys(n).sort().map(e=>JSON.stringify(e)+":"+Bi(n[e])).join(",")+"}"}function Qr(n){let t=Bi(n.extra==null?null:n.extra),e=Bi(Array.isArray(n.pluginSet)?n.pluginSet:[]);return["seq="+n.seq,"anchor="+n.anchor,"tMono="+n.tMono,"buildSha="+(n.buildSha||""),"pluginSet="+e,"extra="+t].join("|")}function Vc(n){return Math.round(n*1e3)/1e3}function Wc(n){if(!Array.isArray(n))return{ok:!1,reason:"records_not_array"};let t=Kr,e=-1;for(let i=0;itypeof E=="string").slice().sort():[],s=typeof t.sink=="function"?t.sink:null,o=t.autoBoot!==!1,r=typeof t.inputAnchorType=="string"?t.inputAnchorType:"pointerdown",a=()=>0,c=!1,l=0,u=Kr,h=[],f=new Set,d=-1,y=null,x=!1,v=!1,w=!1;function _(E,A){let T=null;if(!Uc.has(E))T="unknown_anchor";else{f.has(E)&&(T=T?T+";duplicate_anchor":"duplicate_anchor");let G=Hs[E];GE.time.nowMs(),c=!0,o&&!v&&_("t_boot",{auto:!0}),y=E.getInput().on(r,A=>{x||(x=!0,_("t_input_bound",{firstInput:!0,type:A.type}))}),_("t_input_bound",{stage:"registered",type:r})},dispose(){w||(y&&(y.cancel(),y=null),w=!0)},mark:_,getRecords(){return h.map(E=>({...E}))},toJSONL(){return h.map(E=>JSON.stringify(E)).join(`
-`)},verify(){return Wc(h)}}}function qc(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function ta(n){let t=n.LJS,e=n.engineMath,i=n.engineMode,s=n.recHook||(()=>{});if(i!=="real")return null;let o=e;return{math:{lerp:(a,c,l)=>(s("math.lerp"),o.lerp(a,c,l)),smoothStep:a=>(s("math.smoothStep"),o.smoothStep(a)),easing:Object.fromEntries(Object.keys(o.easing).map(a=>[a,c=>(s("math.easing."+a),o.easing[a](c))]))},particles:{spawnEmitter(a){s("particles.spawnEmitter");let c=t.screenToWorld(t.vec2(a.pos.x,a.pos.y)),l=t.cameraScale,u=a.emitTime!=null?a.emitTime:a.count!=null?1/60:0,h=a.emitRate!=null?a.emitRate:a.count!=null?a.count*60:100,f=(a.speed!=null?a.speed:0)/l/60,d=a.damping!=null?a.damping:1,y=a.colorStart||{r:1,g:1,b:1,a:1},x=a.colorEnd||{r:1,g:1,b:1,a:0},v=t.rgb(y.r,y.g,y.b,y.a),w=t.rgb(x.r,x.g,x.b,x.a),_=new t.ParticleEmitter(c,a.angle!=null?a.angle:0,(a.emitSize!=null?a.emitSize:0)/l,u,h,a.coneAngle!=null?a.coneAngle:Math.PI,void 0,v,v,w,w,a.particleTime!=null?a.particleTime:.5,(a.sizeStart!=null?a.sizeStart:6)/l,(a.sizeEnd!=null?a.sizeEnd:0)/l,f,0,d,1,a.gravityScale!=null?a.gravityScale:0,Math.PI,.1,0,!1,a.additive!=null?a.additive:!1,!0);return{isActive(){return _.isActive()},stop(){_.destroyed||_.destroy(!0)}}}},audio:{synth:{synthSfx:a=>{s("audio.synth.synthSfx");try{return t.zzfxG(...a)}catch(c){return console.error("[host][engine-audio] zzfxG \u5408\u6210\u5F02\u5E38\uFF0C\u8FD4 null\uFF1A"+(c&&c.message?c.message:c)),null}},synthSong:(a,c,l,u)=>{s("audio.synth.synthSong");try{return t.zzfxM(a,c,l,u)}catch(h){return console.error("[host][engine-audio] zzfxM \u5408\u6210\u5F02\u5E38\uFF0C\u8FD4 null\uFF1A"+(h&&h.message?h.message:h)),null}}}}}}function oe(n){return n<0?0:n>1?1:n}function ea(n){let t=n.Ease,e=t.POWER(2),i=t.POWER(3),s=t.OUT(e),o=t.IN_OUT(e),r=t.OUT(i),a=t.IN_OUT(i),c=t.OUT(t.BACK),l=t.OUT(t.ELASTIC);return{lerp:(u,h,f)=>n.lerp(u,h,f),smoothStep:u=>n.smoothStep(u),easing:{linear:u=>t.LINEAR(oe(u)),quadIn:u=>e(oe(u)),quadOut:u=>s(oe(u)),quadInOut:u=>o(oe(u)),cubicIn:u=>i(oe(u)),cubicOut:u=>r(oe(u)),cubicInOut:u=>a(oe(u)),backIn:u=>t.BACK(oe(u)),backOut:u=>c(oe(u)),elasticIn:u=>t.ELASTIC(oe(u)),elasticOut:u=>l(oe(u))}}}var qe=2,zi=1/60;async function na(n){let t=n.canvas,e=n.statusEl||null,i=n.engine,s=n.seed>>>0,o=n.mode||"play",r=n.engineMode||"real",a=n.viewport.w,c=n.viewport.h,l=n.factory,u=n.buildFactoryOpts||(()=>{}),h=n.plugins||{},f=n.registerOrder||Object.values(h),d=n.onReady||(()=>{}),y=n.recHook||(()=>{});function x(I){e&&(e.textContent=I)}let v=[];window.addEventListener("error",I=>v.push({type:"error",message:String(I&&I.message||I)})),window.addEventListener("unhandledrejection",I=>v.push({type:"unhandledrejection",message:String(I&&I.reason&&I.reason.message||I&&I.reason||I)}));let w=null,_=!1;function S(){if(!_)return null;if(w)return w;let I=window.AudioContext||window.webkitAudioContext;return I?(w=new I,w):null}let E=0,A=null,T=null,P=null,G=null,ht=[],Q={},nt=null;function dt(I,rt){try{P&&P.mark(I,rt)}catch($t){v.push({type:"mark",message:String($t&&$t.message||$t)})}}function Mt(){T&&typeof T._refreshChecklist=="function"&&T._refreshChecklist(Q)}async function Ee(I,rt){A=Xr({context2d:I,seed:s,audioFactory:S,clock:()=>E,engineFactory:()=>ta({LJS:r==="real"?i:null,engineMath:r==="real"?ea(i):null,engineMode:r,recHook:y})});let $t=new Ni;for(let pe of f)$t.register(pe);$t.useContext(A.context),G=$t.initAll(),ht=$t.list().concat(["runtime-probe"]),P=Zr({pluginSet:ht,inputAnchorType:"pointerdown",autoBoot:!0});let Kt=A.deriveContextFor("runtime-probe","runtime-probe");dt("t_boot",{by:"game-host",stage:"pre-init",engineMode:r}),dt("t_plugins_ready",{initialized:G.initialized.length,ok:G.ok});let Bs=u(A.context,{bundle:A,plugins:h,getRealAudioCtx:()=>w});T=l(Bs),await T.init({ctx:A.context,mainContext:I,canvas:rt(),seed:s}),nt=T&&typeof T._forensicsView=="function"?T._forensicsView():null,dt("t_game_init",{hasForensics:!!nt}),ct(),dt("t_first_paint",{frame:A.frameCount()});try{P.init(Kt)}catch(pe){v.push({type:"probe-init",message:String(pe&&pe.message||pe)})}dt("t_game_start",{mode:o,engineMode:r}),Mt(),d(de,{bundle:A,game:T,probe:P,checklist:Q,uncaught:v,pluginSet:ht,initRes:G,getGameForensics:()=>nt,mark:dt,stepOneFrame:ct})}let kt=null;function ct(I){let rt=typeof I=="number"?I:zi;T&&(E+=rt*1e3,T.update(rt),r==="stub"&&kt&&T.render(kt),Mt())}function bt(I){for(let rt=0;rt{}),T&&typeof T._onAudioUnlock=="function"&&T._onAudioUnlock()}let de={seed:s,mode:o,engineMode:r,protocol:Yr,frameCount:()=>A?A.frameCount():0,stepFrames:bt,startRaf:()=>un(),stopRaf:()=>Dn(),tap(I,rt){Re(),A&&(A.inputBridge._emit("pointerdown",{x:I,y:rt}),A.inputBridge._emit("pointerup",{x:I,y:rt}))},do(I){T&&typeof T._handleAction=="function"&&T._handleAction(I)},state:()=>nt?nt.state():{phase:"booting"}};function ln(I){let rt=A.inputBridge;function $t(Kt,Bs){let pe=I.getBoundingClientRect();return{x:(Kt-pe.left)/pe.width*a,y:(Bs-pe.top)/pe.height*c}}I.addEventListener("pointerdown",Kt=>{Re(),rt._emit("pointerdown",$t(Kt.clientX,Kt.clientY))}),I.addEventListener("pointermove",Kt=>{rt._emit("pointermove",$t(Kt.clientX,Kt.clientY))}),I.addEventListener("pointerup",Kt=>{rt._emit("pointerup",$t(Kt.clientX,Kt.clientY))})}let ie=0,Pe=!1,_t=0;function fe(I){if(!Pe)return;_t===0&&(_t=I);let rt=(I-_t)/1e3;_t=I,rt>.05&&(rt=.05),ct(rt),ie=window.requestAnimationFrame(fe)}function un(){r==="stub"&&(Pe||(Pe=!0,_t=0,ie=window.requestAnimationFrame(fe)))}function Dn(){Pe=!1,ie&&window.cancelAnimationFrame(ie),ie=0}function Zn(I){I.width=a*qe,I.height=c*qe,I.style.width=a+"px",I.style.height=c+"px";let rt=I.getContext("2d",{willReadFrequently:!0});return rt.setTransform(qe,0,0,qe,0,0),rt}async function ti(){let I=Zn(t);return kt=I,await Ee(I,()=>t),ln(t),o==="evidence"?x(`evidence \u5C31\u7EEA seed=${s} \xB7 \u7528 host \u9A71\u52A8\uFF08stepFrames/tap\uFF09`):(x(`seed=${s} \xB7 \u70B9\u5F00\u59CB\uFF08\u9996\u6B21\u70B9\u51FB\u5F00\u58F0\uFF09`),un()),de}let hn=()=>{},dn=()=>{};function R(){window.__gameHostEngineInitFired=!0}function M(){hn()}function D(){}function xt(){dn()}function se(){}async function Vt(I){await Ee(I,()=>i.mainCanvas),ln(i.mainCanvas),hn=()=>{T&&(E+=zi*1e3,T.update(zi))},dn=()=>{if(T){I.save(),I.setTransform(qe,0,0,qe,0,0);try{I.imageSmoothingEnabled=!1}catch{}T.render(I),I.restore()}},i.mainCanvas&&(i.mainCanvas.id="game-engine"),window.__engine={frame(){return i.frame},time(){return i.time},timeReal(){return i.timeReal},paused(){return i.paused},timeScale(){return i.timeScale},snapshot(){return{frame:i.frame,time:i.time,timeReal:i.timeReal,paused:i.paused,timeScale:i.timeScale}}},x(`engine RAF running \xB7 seed=${s} engine=real`)}if(r!=="real")return await ti();if(!i){let I="real \u901A\u9053\u672A\u6CE8\u5165\u5F15\u64CE\uFF08opts.engine \u7F3A\u5931\uFF09\uFF1A\u8BF7\u7ECF entry \u5305\u88C5\u5C42\u542F\u52A8\uFF08host \u4E0D\u76F4\u63A5 import \u5F15\u64CE\uFF0CQ4/Option C\uFF09";throw x("ENGINE INJECT MISSING: "+I),new Error(I)}i.setGLEnable(!1),i.setShowSplashScreen(!1),i.setDebugWatermark(!1),i.setCanvasClearColor(i.BLACK),i.setCanvasFixedSize(i.vec2(a*qe,c*qe));let Le=document.createElement("div");return Le.id="engine-root",document.body.appendChild(Le),await i.engineInit(R,M,D,xt,se,[],Le).then(()=>Vt(i.mainContext)).catch(I=>{throw window.__gameHostBootError=String(I&&I.message||I),x("ENGINE INIT FAILED: "+window.__gameHostBootError),I}),de}var Ys=class{constructor(t){let e=t||{},i=typeof e.cellSize=="number"&&e.cellSize>0?e.cellSize:64;this._cellSize=i,this._cells=new Map,this._entries=new Map,this._seq=0}get size(){return this._entries.size}_cellRange(t){let e=this._cellSize,i=Math.floor((t.x-t.hw)/e),s=Math.floor((t.x+t.hw)/e),o=Math.floor((t.y-t.hh)/e),r=Math.floor((t.y+t.hh)/e);return{cx0:i,cy0:o,cx1:s,cy1:r}}insert(t,e){this._entries.has(t)&&this.remove(t);let{cx0:i,cy0:s,cx1:o,cy1:r}=this._cellRange(e),a=[];for(let l=s;l<=r;l++)for(let u=i;u<=o;u++){let h=u+","+l,f=this._cells.get(h);f||(f=new Set,this._cells.set(h,f)),f.add(t),a.push(h)}let c={x:e.x,y:e.y,hw:e.hw,hh:e.hh};this._entries.set(t,{id:t,box:c,seq:this._seq++,cells:a})}remove(t){let e=this._entries.get(t);if(!e)return!1;for(let i of e.cells){let s=this._cells.get(i);s&&(s.delete(t),s.size===0&&this._cells.delete(i))}return this._entries.delete(t),!0}query(t){let{cx0:e,cy0:i,cx1:s,cy1:o}=this._cellRange(t),r=new Set;for(let a=i;a<=o;a++)for(let c=e;c<=s;c++){let l=this._cells.get(c+","+a);if(l)for(let u of l)r.add(u)}return this._collect(r)}queryPoint(t,e){let i=this._cellSize,s=Math.floor(t/i),o=Math.floor(e/i),r=this._cells.get(s+","+o);return r?this._collect(new Set(r)):[]}clear(){this._cells.clear(),this._entries.clear(),this._seq=0}_collect(t){let e=[];for(let i of t){let s=this._entries.get(i);s&&e.push(s)}return e.sort((i,s)=>i.seq-s.seq),e.map(i=>({id:i.id,box:i.box}))}};function ia(n){let t=n||{},e=new Ys({cellSize:t.cellSize}),i=!1;return{name:"collision",version:"1.0.0",dependencies:[],spatial:e,init(o){},dispose(){i||(e.clear(),i=!0)}}}function sa(n){let t=!1;return{name:"physics-lite",version:"1.0.0",dependencies:[],init(i){},dispose(){t||(t=!0)}}}var Hc=["pointerdown","pointermove","pointerup","keydown","keyup"];function Gt(n){return n<0?0:n>1?1:n}var Xc=n=>(n=Gt(n),n*n),Yc=n=>(n=Gt(n),1-(1-n)*(1-n)),$c=n=>(n=Gt(n),n<.5?2*n*n:1-Math.pow(-2*n+2,2)/2),Kc=n=>(n=Gt(n),n*n*n),Qc=n=>{n=Gt(n);let t=1-n;return 1-t*t*t},Zc=n=>(n=Gt(n),n<.5?4*n*n*n:1-Math.pow(-2*n+2,3)/2),aa=2*Math.PI/3,oa=2*Math.PI/4.5,tl=n=>(n=Gt(n),n===0?0:n===1?1:-Math.pow(2,10*n-10)*Math.sin((n*10-10.75)*aa)),el=n=>(n=Gt(n),n===0?0:n===1?1:Math.pow(2,-10*n)*Math.sin((n*10-.75)*aa)+1),nl=n=>(n=Gt(n),n===0?0:n===1?1:n<.5?-(Math.pow(2,20*n-10)*Math.sin((20*n-11.125)*oa))/2:Math.pow(2,-20*n+10)*Math.sin((20*n-11.125)*oa)/2+1),Ui=1.70158,Ji=Ui*1.525,ca=Ui+1,il=n=>(n=Gt(n),ca*n*n*n-Ui*n*n),sl=n=>{n=Gt(n);let t=n-1;return 1+ca*t*t*t+Ui*t*t},ol=n=>(n=Gt(n),n<.5?Math.pow(2*n,2)*((Ji+1)*2*n-Ji)/2:(Math.pow(2*n-2,2)*((Ji+1)*(n*2-2)+Ji)+2)/2),rl=n=>Gt(n),ra=Object.freeze({linear:rl,quadIn:Xc,quadOut:Yc,quadInOut:$c,cubicIn:Kc,cubicOut:Qc,cubicInOut:Zc,elasticIn:tl,elasticOut:el,elasticInOut:nl,backIn:il,backOut:sl,backInOut:ol});var al=["linear","quadIn","quadOut","quadInOut","cubicIn","cubicOut","cubicInOut","elasticIn","elasticOut","elasticInOut","backIn","backOut","backInOut"];function cl(n){let t=n&&n.easing;if(!t)return ra;let e=s=>typeof t[s]=="function"?o=>t[s](Gt(o)):ra[s],i={};for(let s of al)i[s]=e(s);return Object.freeze(i)}var $s=class{constructor(t,e,i){let s=i||{};this._time=e,this._windowMs=typeof s.windowMs=="number"&&s.windowMs>0?s.windowMs:120;let o=Array.isArray(s.types)&&s.types.length>0?s.types:Hc;this._records=new Map,this._subs=[],this._disposed=!1;for(let r of o){this._records.set(r,null);let a=t.on(r,c=>{this._records.set(r,c.tMs)});this._subs.push(a)}}consume(t,e){let i=typeof e=="number"?e:this._time.nowMs(),s=this._records.get(t);return s==null?!1:i-s<=this._windowMs?(this._records.set(t,null),!0):(this._records.set(t,null),!1)}peek(t,e){let i=typeof e=="number"?e:this._time.nowMs(),s=this._records.get(t);return s==null?!1:i-s<=this._windowMs}clear(){for(let t of this._records.keys())this._records.set(t,null)}dispose(){if(!this._disposed){for(let t of this._subs)try{t.cancel()}catch(e){}this._subs=[],this._disposed=!0}}};function la(n){let t=n||{},e=null,i=null,s=!1;return{name:"gamefeel",version:"1.0.0",dependencies:[],get inputBuffer(){return e},get easing(){return cl(i)},init(r){let a=r.getInput();e=new $s(a,r.time,{windowMs:t.inputBufferMs,types:t.inputTypes});let c=r.getEngine();i=c?c.math:null},dispose(){s||(e&&(e.dispose(),e=null),i=null,s=!0)}}}function Vi(n,t){let e=t<0?0:t>1?1:t;switch(n&&n.kind){case"constant":return n.value;case"linear":return n.from+(n.to-n.from)*e;case"easeInOut":{let i=e*e*(3-2*e);return n.from+(n.to-n.from)*i}case"decay":{let i=n.power==null?2:n.power,s=Math.pow(1-e,i);return n.to+(n.from-n.to)*s}default:return 0}}var ll=Object.freeze({burst:Object.freeze({mode:"burst",count:24,angle:0,spread:Math.PI,speedMin:80,speedMax:160,lifeMin:.4,lifeMax:.8,gravity:0,drag:0,sizeCurve:{kind:"decay",from:6,to:0,power:1.5},alphaCurve:{kind:"linear",from:1,to:0}}),trail:Object.freeze({mode:"continuous",rate:60,angle:Math.PI,spread:.25,speedMin:20,speedMax:50,lifeMin:.2,lifeMax:.5,gravity:0,drag:1.5,sizeCurve:{kind:"easeInOut",from:4,to:0},alphaCurve:{kind:"decay",from:.8,to:0,power:2}}),drift:Object.freeze({mode:"continuous",rate:12,angle:Math.PI/2,spread:.6,speedMin:10,speedMax:30,lifeMin:1.5,lifeMax:3,gravity:8,drag:.5,sizeCurve:{kind:"constant",value:3},alphaCurve:{kind:"decay",from:.7,to:0,power:1}})});function ul(n){let t=ll[n];return t?Ks(t):null}function Ks(n){let t={};for(let e of Object.keys(n)){let i=n[e];t[e]=i&&typeof i=="object"?Ks(i):i}return t}function hl(n,t,e){let i=n.mode==="continuous";return{pos:{x:t,y:e},angle:n.angle,coneAngle:n.spread,emitSize:0,emitTime:i?0:1/60,emitRate:i?n.rate||0:void 0,count:i?void 0:n.count||0,particleTime:(n.lifeMin+n.lifeMax)/2,speed:(n.speedMin+n.speedMax)/2,gravityScale:n.gravity||0,damping:n.drag!=null?1-n.drag/60:1,sizeStart:Vi(n.sizeCurve,0),sizeEnd:Vi(n.sizeCurve,1),colorStart:{r:1,g:1,b:1,a:Vi(n.alphaCurve,0)},colorEnd:{r:1,g:1,b:1,a:Vi(n.alphaCurve,1)},additive:!1}}function ua(n){let t=n||{},e=null,i=null,s=null,o=new Map,r=0,a={isActive(){return!1},stop(){}},c=0,l=1,u=0,h=0,f=0,d={x:0,y:0,remain:0,dur:0,amplitude:0,frequency:0,_phase:0},y={alpha:0,remain:0,dur:0,peak:0},x={scale:1,remain:0,dur:0,amplitude:0,frequency:0},v=!1;function w(A){if(u>0)if(u-=A,u<=0)u=0,l=1;else{let T=h>0?1-u/h:1;l=f+(1-f)*T}if(d.remain>0)if(d.remain-=A,d.remain<=0)d.remain=0,d.x=0,d.y=0;else{let T=d.remain/d.dur,P=d.amplitude*T;d._phase+=d.frequency*A*Math.PI*2,d.x=Math.sin(d._phase)*P,d.y=Math.cos(d._phase*1.3)*P}if(y.remain>0&&(y.remain-=A,y.remain<=0?(y.remain=0,y.alpha=0):y.alpha=y.peak*(y.remain/y.dur)),x.remain>0)if(x.remain-=A,x.remain<=0)x.remain=0,x.scale=1;else{let T=x.remain/x.dur,P=(1-T)*x.frequency*Math.PI*2;x.scale=1+Math.sin(P)*x.amplitude*T}}function _(A){c+=1,w(A)}function S(A){let T=A!==void 0?A:e?e.getContext2d():null;if(T&&y.alpha>0){T.globalAlpha=y.alpha,T.fillStyle="#ffffff";let P=T.canvas?T.canvas.width:0,G=T.canvas?T.canvas.height:0;T.fillRect(0,0,P,G),T.globalAlpha=1}}return{name:"particles-juice",version:"1.0.0",dependencies:[],init(A){var T;e=A,s=((T=A.getEngine())==null?void 0:T.particles)||null,typeof t.seed=="number"&&A.random.reseed(t.seed),t.autoStep!==!1&&(i=A.onFrame(P=>{_(P)}))},dispose(){v||(i&&(i.cancel(),i=null),o.forEach(A=>{try{A.stop()}catch{}}),o.clear(),l=1,u=0,d.remain=0,d.x=0,d.y=0,y.remain=0,y.alpha=0,x.remain=0,x.scale=1,v=!0)},spawnEmitter(A,T,P,G){let ht=typeof A=="string"?ul(A):Ks(A);if(!ht)return-1;G&&(ht=Object.assign(ht,G));let Q=r++;if(!s)return o.set(Q,a),Q;let nt=s.spawnEmitter(hl(ht,T,P));return o.set(Q,nt),Q},stopEmitter(A){let T=o.get(A);if(T)try{T.stop()}catch{}},step(A){_(A)},render(A){S(A)},particleCount(){return 0},emitterCount(){let A=0;for(let T of o.values())T.isActive()&&(A+=1);return A},hitStop(A,T){h=Math.max(0,A),u=h,f=T==null?0:Math.max(0,Math.min(1,T)),l=h>0?f:1},getTimeScale(){return l},shakeScreen(A,T,P){d.dur=Math.max(0,A),d.remain=d.dur,d.amplitude=Math.max(0,T),d.frequency=P==null?30:P,d._phase=0,d.x=0,d.y=0},getShakeOffset(){return{x:d.x,y:d.y}},flashScreen(A,T){y.dur=Math.max(0,A),y.remain=y.dur,y.peak=T==null?.8:Math.max(0,Math.min(1,T)),y.alpha=y.dur>0?y.peak:0},getFlashAlpha(){return y.alpha},pulseScale(A,T,P){x.dur=Math.max(0,A),x.remain=x.dur,x.amplitude=T==null?.2:T,x.frequency=P==null?4:P,x.scale=1},getPulseScale(){return x.scale},juiceSnapshot(){return{timeScale:l,shake:{x:d.x,y:d.y},flashAlpha:y.alpha,pulseScale:x.scale}},probe(){return{particles:0,emitters:o.size,dropped:0,steps:c,disposed:v}}}}function ha(n){let t=ft(n.r)/255,e=ft(n.g)/255,i=ft(n.b)/255,s=Math.max(t,e,i),o=Math.min(t,e,i),r=(s+o)/2,a=0,c=0,l=s-o;return l>1e-12&&(c=r>.5?l/(2-s-o):l/(s+o),s===t?a=(e-i)/l%6:s===e?a=(i-t)/l+2:a=(t-e)/l+4,a*=60,a<0&&(a+=360)),{h:a,s:c,l:r}}function da(n){let t=(n.h%360+360)%360,e=He(n.s),i=He(n.l);if(e<1e-12){let a=Math.round(i*255);return{r:a,g:a,b:a}}let s=i<.5?i*(1+e):i+e-i*e,o=2*i-s,r=t/360;return{r:Math.round(Qs(o,s,r+1/3)*255),g:Math.round(Qs(o,s,r)*255),b:Math.round(Qs(o,s,r-1/3)*255)}}function Qs(n,t,e){let i=e;return i<0&&(i+=1),i>1&&(i-=1),i<1/6?n+(t-n)*6*i:i<1/2?t:i<2/3?n+(t-n)*(2/3-i)*6:n}function ft(n){return n<0?0:n>255?255:n}function He(n){return n<0?0:n>1?1:n}function dl(n,t){let e=pl(n.from,t);if(e>=0&&e({r:ft(a.r),g:ft(a.g),b:ft(a.b)})),to:o}}function Zs(n,t,e){return n+(t-n)*e}function ml(n,t){let e=ha(n),i=e.h+(t.hue||0),s=He(e.s*(t.sat==null?1:t.sat)),o=He(e.l*(t.light==null?1:t.light));return da({h:i,s,l:o})}var bl=Object.freeze([Object.freeze([0,8,2,10]),Object.freeze([12,4,14,6]),Object.freeze([3,11,1,9]),Object.freeze([15,7,13,5])]);function fa(n){let t=n||{},e=null,i=!1,s={vignette:{enabled:to(t.vignette&&t.vignette.enabled,!1),strength:eo(t.vignette&&t.vignette.strength,.5)},dither:{enabled:to(t.dither&&t.dither.enabled,!1),strength:eo(t.dither&&t.dither.strength,.5)},scanline:{enabled:to(t.scanline&&t.scanline.enabled,!1),strength:eo(t.scanline&&t.scanline.strength,.5)}};function o(a){let c=a!==void 0?a:e?e.getContext2d():null;if(!c)return;let l=c.canvas?c.canvas.width:0,u=c.canvas?c.canvas.height:0;if(s.vignette.enabled&&s.vignette.strength>0&&l>0&&u>0){let h=c.createRadialGradient(l/2,u/2,Math.min(l,u)*.25,l/2,u/2,Math.max(l,u)*.75);h.addColorStop(0,"rgba(0,0,0,0)"),h.addColorStop(1,"rgba(0,0,0,"+s.vignette.strength.toFixed(3)+")"),c.fillStyle=h,c.fillRect(0,0,l,u)}if(s.scanline.enabled&&s.scanline.strength>0&&l>0&&u>0){c.fillStyle="rgba(0,0,0,"+(s.scanline.strength*.5).toFixed(3)+")";for(let h=0;h0&&l>0&&u>0&&typeof c.getImageData=="function"&&typeof c.putImageData=="function"){let h=c.getImageData(0,0,l,u);xl(h,s.dither.strength),c.putImageData(h,0,0)}}return{name:"palette-post",version:"1.0.0",dependencies:[],init(a){e=a},dispose(){i||(e=null,i=!0)},applyPaletteMap(a,c){return dl(a,c)},applyPaletteMapToBuffer(a,c){return fl(a,c)},lerpPaletteMap(a,c,l){return gl(a,c,l)},shiftHsl(a,c){return ml(a,c)},rgbToHsl(a){return ha(a)},hslToRgb(a){return da(a)},setPost(a){if(a)for(let c of["vignette","dither","scanline"])a[c]&&(typeof a[c].enabled=="boolean"&&(s[c].enabled=a[c].enabled),typeof a[c].strength=="number"&&(s[c].strength=He(a[c].strength)))},getPost(){return{vignette:{enabled:s.vignette.enabled,strength:s.vignette.strength},dither:{enabled:s.dither.enabled,strength:s.dither.strength},scanline:{enabled:s.scanline.enabled,strength:s.scanline.strength}}},renderPost(a){o(a)},probe(){return{disposed:i,post:this.getPost()}}}}function xl(n,t){let e=He(t);if(e<=0)return n;let{data:i,width:s}=n,r=255/(Math.max(2,Math.round(16-e*14))-1);for(let a=0;a+3>2)%s,l=Math.floor((a>>2)/s),u=(bl[l&3][c&3]/16-.5)*r;for(let h=0;h<3;h++){let f=i[a+h]+u,d=Math.round(f/r)*r;i[a+h]=d<0?0:d>255?255:d}}return n}function to(n,t){return typeof n=="boolean"?n:t}function eo(n,t){return typeof n=="number"?He(n):t}var io=Object.freeze({blip:Object.freeze({name:"blip",params:Object.freeze([.6,0,880,0,.03,.06,1,1.5])}),thud:Object.freeze({name:"thud",params:Object.freeze([.8,0,90,0,.04,.18,0,1,0,0,0,0,0,4])}),chime:Object.freeze({name:"chime",params:Object.freeze([.5,0,660,.02,.12,.3,1,2])})}),pa=Object.keys(io);function vl(n){let t=[];return n==null||typeof n!="object"?{ok:!1,errors:["song \u5FC5\u987B\u662F\u5BF9\u8C61"]}:(!Array.isArray(n.instruments)||n.instruments.length===0?t.push("instruments \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4"):n.instruments.forEach((e,i)=>{(!Array.isArray(e)||e.some(s=>typeof s!="number"||!Number.isFinite(s)))&&t.push(`instruments[${i}] \u5FC5\u987B\u662F\u6709\u9650\u6570\u5B57\u6570\u7EC4\uFF08ZzFX \u53C2\u6570\u5305\uFF09`)}),!Array.isArray(n.patterns)||n.patterns.length===0?t.push("patterns \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4"):n.patterns.forEach((e,i)=>{if(!Array.isArray(e)||e.length===0){t.push(`patterns[${i}] \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4\uFF08\u81F3\u5C11\u4E00\u4E2A\u58F0\u90E8\u901A\u9053\uFF09`);return}e.forEach((s,o)=>{if(!Array.isArray(s)||s.length<2){t.push(`patterns[${i}][${o}] \u901A\u9053\u81F3\u5C11\u542B [\u4E50\u5668\u7D22\u5F15, \u58F0\u50CF]`);return}if(s.some(c=>typeof c!="number"||!Number.isFinite(c))){t.push(`patterns[${i}][${o}] \u901A\u9053\u5FC5\u987B\u5168\u4E3A\u6709\u9650\u6570\u5B57`);return}let r=s[0]|0;Array.isArray(n.instruments)&&(r<0||r>=n.instruments.length)&&t.push(`patterns[${i}][${o}] \u4E50\u5668\u7D22\u5F15 ${r} \u8D8A\u754C\uFF08instruments \u957F\u5EA6 ${n.instruments.length}\uFF09`);let a=s[1];(a<-1||a>1)&&t.push(`patterns[${i}][${o}] \u58F0\u50CF ${a} \u8D8A\u754C\uFF08\u5E94 -1..+1\uFF09`)})}),!Array.isArray(n.sequence)||n.sequence.length===0?t.push("sequence \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4"):n.sequence.forEach((e,i)=>{if(typeof e!="number"||!Number.isInteger(e)){t.push(`sequence[${i}] \u5FC5\u987B\u662F\u6574\u6570 pattern \u7D22\u5F15`);return}Array.isArray(n.patterns)&&(e<0||e>=n.patterns.length)&&t.push(`sequence[${i}] \u7D22\u5F15 ${e} \u8D8A\u754C\uFF08patterns \u957F\u5EA6 ${n.patterns.length}\uFF09`)}),n.bpm!=null&&(typeof n.bpm!="number"||!(n.bpm>0))&&t.push("bpm \u5FC5\u987B\u662F\u6B63\u6570"),{ok:t.length===0,errors:t})}function ye(n){return typeof n!="number"||Number.isNaN(n)||n<0?0:n>1?1:n}function Sl(n,t){switch(n){case"ease-in":return t*t;case"ease-out":return Math.sqrt(t);case"constant":return 1;default:return t}}function ya(n,t){let e=ye(t);return n==null||!Array.isArray(n.voices)?[]:n.voices.map(i=>{let s=String(i&&i.id!=null?i.id:""),o=Array.isArray(i&&i.channelIndices)?i.channelIndices.slice():[],r=typeof i.minIntensity=="number"?ye(i.minIntensity):0,a=typeof i.maxIntensity=="number"?ye(i.maxIntensity):1,c=typeof i.volumeCurve=="string"?i.volumeCurve:"linear",l=typeof i.baseVolume=="number"?ye(i.baseVolume):1;if(ea)return{id:s,on:!1,volume:0,channelIndices:o};let u=a-r,h=u<=0?1:(e-r)/u,f=ye(Sl(c,h)*l);return{id:s,on:!0,volume:f,channelIndices:o}})}function ga(n,t,e,i){try{let s=t[0]||[],o=t[1]||s,r=Math.max(s.length,o.length);if(r===0)return null;let c=n.createBuffer(2,r,44100);c.getChannelData(0).set(s),c.getChannelData(1).set(o.length?o:s);let l=n.createBufferSource();l.buffer=c,l.loop=!!i;let u=n.createGain();return u.gain.value=ye(e*.3),l.connect(u),u.connect(n.destination),l.start(),{stop(){try{l.stop()}catch(h){}try{l.disconnect(),u.disconnect()}catch(h){}}}}catch(s){return so("[audio-music] \u53D7\u63A7\u97F3\u9891\u64AD\u653E\u5F02\u5E38\uFF0C\u964D\u7EA7\u4E3A\u9759\u9ED8",s),null}}function ma(n){let t=n||{},e=typeof t.masterVolume=="number"?ye(t.masterVolume):1,i=()=>null,s=null,o=null,r={voices:[]},a=1,c=null,l=!1,u=0,h=!1,f=!1;function d(){let S=i();return S==null?(u+=1,h||(no("[audio-music] \u65E0\u53D7\u63A7\u97F3\u9891\u4E0A\u4E0B\u6587\uFF08getAudioContext \u8FD4\u56DE null\uFF09\uFF0C\u5168\u90E8\u53D1\u58F0\u9759\u9ED8 no-op\uFF08\u8BC4\u4F30\u73AF\u5883\u65E0\u58F0\u5361\u65F6\u7684\u5BB9\u9519\u964D\u7EA7\uFF09"),h=!0),null):S}function y(){if(!o||!s)return null;try{let S=typeof o.bpm=="number"&&o.bpm>0?o.bpm:125;return s.synthSong(o.instruments,o.patterns,o.sequence,S)}catch(S){return so("[audio-music] \u66F2\u8C31\u6E32\u67D3\u5F02\u5E38\uFF0C\u964D\u7EA7\u4E3A\u9759\u9ED8",S),null}}function x(){let S=ya(r,a);if(S.length===0)return 1;let E=0;for(let A of S)A.on&&(E=Math.max(E,A.volume));return E}function v(S,E){typeof E=="number"&&(a=ye(E));let A=d();if(A==null||!o)return;w();let T=y();if(!T)return;let P=ye(e*x());c=ga(A,T,P,S),l=!!S&&c!=null}function w(){c&&(c.stop(),c=null),l=!1}return{name:"audio-music",version:"1.0.0",dependencies:[],init(S){i=()=>S.getAudioContext();let E=S.getEngine&&S.getEngine();s=E?E.audio.synth:null},dispose(){f||(w(),f=!0)},loadSong(S){let E=vl(S);return E.ok?o={instruments:S.instruments,patterns:S.patterns,sequence:S.sequence,bpm:typeof S.bpm=="number"?S.bpm:125}:no("[audio-music] \u66F2\u8C31\u6821\u9A8C\u5931\u8D25\uFF0C\u672A\u8F7D\u5165\uFF1A"+E.errors.join("\uFF1B")),E},play(S){v(!1,S)},stop(){w()},loop(S){v(!0,S)},setIntensityLayering(S){r=S&&Array.isArray(S.voices)?{voices:S.voices}:{voices:[]}},setIntensity(S){a=ye(S)},resolveVoices(S){return ya(r,S)},playSfx(S){let E=io[S];if(!E){no("[audio-music] \u672A\u77E5\u97F3\u6548\u9884\u8BBE\uFF1A"+String(S));return}let A=d();if(A!=null)try{let T=s?s.synthSfx(E.params):null;if(!T)return;ga(A,[T,T],e,!1)}catch(T){so("[audio-music] \u97F3\u6548\u64AD\u653E\u5F02\u5E38\uFF0C\u964D\u7EA7\u4E3A\u9759\u9ED8 name="+S,T)}},getPreset(S){return io[S]},listPresets(){return pa.slice()},probe(){return{hasAudio:i()!=null,hasSong:o!=null,intensity:a,voiceCount:r.voices.length,looping:l,silentNoops:u,presetCount:pa.length}}}}function so(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function no(n){typeof console!="undefined"&&typeof console.warn=="function"&&console.warn(n)}var wl="zaomeng.save";function Tl(n){if(typeof TextEncoder!="undefined")return new TextEncoder().encode(n).length;if(typeof Buffer!="undefined"&&typeof Buffer.byteLength=="function")return Buffer.byteLength(n,"utf8");let t=0;for(let e=0;e=55296&&i<=56319?(t+=4,e++):t+=3}return t}function ro(){let n=new Map;return{getItem(t){return n.has(t)?n.get(t):null},setItem(t,e){n.set(t,e)},removeItem(t){n.delete(t)},keys(){return Array.from(n.keys())}}}function ba(){if(typeof localStorage=="undefined")throw new Error("[save-progress] createLocalStorageAdapter \u9700\u8981\u5168\u5C40 localStorage\uFF08\u4EC5\u6D4F\u89C8\u5668\u96C6\u6210\u6BB5\u53EF\u7528\uFF09\u3002node/host-dev \u8BF7\u7528\u7F3A\u7701\u5185\u5B58 adapter \u6216 createMemoryAdapter()\u3002");return{getItem(n){return localStorage.getItem(n)},setItem(n,t){localStorage.setItem(n,t)},removeItem(n){localStorage.removeItem(n)},keys(){let n=[];for(let t=0;t0?t.namespace:wl;if(e.indexOf(":")>=0)throw new Error('[save-progress] namespace \u4E0D\u5F97\u542B\u5206\u9694\u7B26 ":"\uFF08\u5F53\u524D="'+e+'"\uFF09');let i=typeof t.maxValueBytes=="number"&&t.maxValueBytes>0?Math.floor(t.maxValueBytes):32768,s=!Al(t.adapter),o=s?ro():t.adapter,r=e+":",a=0,c=0,l=!1;function u(d){return typeof d!="string"||d.length===0?r+String(d):r+d}function h(){try{let d=o.keys();return Array.isArray(d)?d.filter(y=>typeof y=="string"&&y.indexOf(r)===0):[]}catch(d){return ei("[save-progress] adapter.keys() \u5F02\u5E38\uFF0C\u964D\u7EA7\u8FD4\u56DE\u7A7A\u96C6",d),[]}}return{name:"save-progress",version:"1.0.0",dependencies:[],init(d){h()},dispose(){},get(d,y){if(!oo(d))return y;let x;try{x=o.getItem(u(d))}catch(v){return ei("[save-progress] adapter.getItem \u5F02\u5E38\uFF0C\u8FD4\u56DE\u9ED8\u8BA4\u503C key="+d,v),y}if(x==null)return y;try{return JSON.parse(x)}catch{return a+=1,l||(ni("[save-progress] \u68C0\u6D4B\u5230\u635F\u574F\u5B58\u6863\uFF08\u975E\u6CD5 JSON\uFF09\uFF0C\u5DF2\u5BB9\u9519\u56DE\u9000\u9ED8\u8BA4\u503C key="+d),l=!0),y}},set(d,y){if(!oo(d))return ni("[save-progress] set \u6536\u5230\u975E\u6CD5 key\uFF0C\u62D2\u7EDD\u5199\u5165\uFF1A"+String(d)),!1;let x;try{x=JSON.stringify(y)}catch{return c+=1,ni("[save-progress] \u503C\u4E0D\u53EF JSON \u5E8F\u5217\u5316\uFF08\u5FAA\u73AF\u5F15\u7528?\uFF09\uFF0C\u62D2\u7EDD\u5199\u5165 key="+d),!1}if(x===void 0)return c+=1,ni("[save-progress] \u503C\u5E8F\u5217\u5316\u4E3A undefined\uFF08\u5982\u7EAF undefined/\u51FD\u6570\uFF09\uFF0C\u62D2\u7EDD\u5199\u5165 key="+d),!1;let v=Tl(x);if(v>i)return c+=1,ni("[save-progress] \u503C\u8D85\u5B57\u8282\u4E0A\u9650\u62D2\u7EDD\u5199\u5165 key="+d+"\uFF08"+v+" > "+i+" bytes\uFF09"),!1;try{return o.setItem(u(d),x),!0}catch(w){return c+=1,ei("[save-progress] adapter.setItem \u5F02\u5E38\uFF0C\u5199\u5165\u5931\u8D25 key="+d,w),!1}},remove(d){if(oo(d))try{o.removeItem(u(d))}catch(y){ei("[save-progress] adapter.removeItem \u5F02\u5E38\uFF08\u5DF2\u5FFD\u7565\uFF09key="+d,y)}},clear(){let d=h(),y=0;for(let x of d)try{o.removeItem(x),y+=1}catch(v){ei("[save-progress] clear \u65F6 removeItem \u5F02\u5E38\uFF08\u5DF2\u8DF3\u8FC7\uFF09fullKey="+x,v)}return y},probe(){return{namespace:e,maxValueBytes:i,usingMemoryAdapter:s,size:h().length,corruptRecoveries:a,rejectedWrites:c}}}}function oo(n){return typeof n=="string"&&n.length>0}function Al(n){return!!n&&typeof n.getItem=="function"&&typeof n.setItem=="function"&&typeof n.removeItem=="function"&&typeof n.keys=="function"}function ei(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function ni(n){typeof console!="undefined"&&typeof console.warn=="function"&&console.warn(n)}var Cl={w:390,h:844};function va(n){let t=((n&&n.seed)!=null?n.seed:0)>>>0,e=ia({cellSize:96}),i=sa(),s=la({inputBufferMs:260,inputTypes:["pointerdown"]}),o=ua({seed:t,maxParticles:600}),r=fa({vignette:{enabled:!0,strength:.22}}),a=ma({masterVolume:.8}),c;try{c=ba()}catch(f){console.warn("[generic] localStorage \u4E0D\u53EF\u7528\uFF0C\u5B58\u6863\u9000\u5185\u5B58 adapter\uFF1A"+(f&&f.message)),c=ro()}let l=xa({namespace:"zaomeng-generic",adapter:c});return{plugins:{collision:e,physics:i,gamefeel:s,juice:o,palettePost:r,audioMusic:a,save:l},registerOrder:[e,i,s,o,r,l,a],viewport:Cl,buildFactoryOpts:(f,d)=>({runtime:{plugins:d.plugins,bundle:d.bundle,getRealAudioCtx:d.getRealAudioCtx}})}}function ii(n){let t=n||{},e=null,i=null,s=0,o=0,r=null,a=null,c=null,l="booting",u="",h=0,f=5,d=0,y=null,x=[],v=[],w=!1,_=null,S=null,E=[],A=[],T=980,P=.5,G=8,ht=16,Q=70,nt=580;function dt(){l="playing",u="",h=0,f=5,d=0,y=null,x=[],v=[],w=!1,_=null,S=null,E=[],A=[],Mt(),Ee()}function Mt(){let R=[{x:290,y:560},{x:310,y:520},{x:280,y:480}];for(let D of R)v.push({x:D.x,y:D.y,r:ht,active:!0});let M=[{x:270,y:576,w:24,h:10},{x:306,y:576,w:24,h:10},{x:262,y:550,w:10,h:24},{x:322,y:550,w:10,h:24},{x:290,y:546,w:30,h:10},{x:290,y:534,w:10,h:12},{x:270,y:506,w:24,h:10},{x:306,y:506,w:24,h:10},{x:280,y:490,w:10,h:16},{x:310,y:490,w:10,h:16},{x:280,y:470,w:30,h:8}];for(let D of M)x.push({x:D.x,y:D.y,w:D.w,h:D.h,active:!0})}function Ee(){d>=5||(y={x:Q,y:nt-10,vx:0,vy:0,state:"ready",alive:!0},d++,f=5-d)}function kt(R,M){if(!y||y.state!=="ready")return;let D=Q-R,xt=nt-10-M,se=D*P,Vt=xt*P;y.vx=se,y.vy=Vt,y.state="flying",w=!1,_=null,S=null,_t(Q,nt-10,30,{r:1,g:.9,b:.3,a:1},.6),fe([1,.08,600,,.1,.5,.5,1.2])}function ct(R){if(!y||y.state!=="flying")return;let M=y;if(M.vy+=T*R,M.x+=M.vx*R,M.y+=M.vy*R,M.y>844||M.x<-20||M.x>410||M.y<-20){bt(M.x,M.y);return}for(let D of v){if(!D.active)continue;let xt=M.x-D.x,se=M.y-D.y;if(Math.sqrt(xt*xt+se*se)D.x&&M.xD.y&&M.y800&&bt(M.x,M.y)}function bt(R,M){!y||y.state!=="flying"||(y.state="hit",y.alive=!1,_t(R,M,25,{r:.6,g:.8,b:1,a:1},.4),fe([1,.05,300,,.1,.2,.5,1]),setTimeout(()=>{if(l!=="gameover"){if(Re()){l="gameover",u="win",de();return}if(d>=5){l="gameover",u="lose",de();return}Ee()}},500))}function Re(){return v.every(R=>!R.active)}function de(){_t(195,422,50,{r:1,g:.9,b:.2,a:1},1.5),fe([1,.9,800,,.1,.6,.9,1.8])}function ln(R){if(l==="gameover"){R.x>100&&R.x<290&&R.y>600&&R.y<680&&(dt(),l="playing",E=[],A=[]);return}if(!y||y.state!=="ready")return;let M=R.x-Q,D=R.y-(nt-10);Math.sqrt(M*M+D*D)<80&&(w=!0,_={x:Q,y:nt-10},S={x:R.x,y:R.y})}function ie(R){w&&(S={x:R.x,y:R.y})}function Pe(R){w&&(w=!1,S&&kt(S.x,S.y),_=null,S=null)}function _t(R,M,D,xt,se){let Vt=e&&e.getEngine();if(Vt&&Vt.particles)try{Vt.particles.spawnEmitter({pos:{x:R,y:M},count:D,speed:100+D*2,particleTime:se||.6,colorStart:xt||{r:1,g:.5,b:0,a:1},colorEnd:{r:1,g:.2,b:0,a:0},sizeStart:6,sizeEnd:2})}catch{}}function fe(R){let M=e&&e.getEngine();if(M&&M.audio&&M.audio.synth)try{M.audio.synth.synthSfx(R)}catch{}}function un(R,M,D){A.push({x:R,y:M,text:D,born:s,duration:800})}function Dn(R){e=R.ctx,i=R.seed||0,r=e.getInput().on("pointerdown",ln),c=e.getInput().on("pointermove",ie),a=e.getInput().on("pointerup",Pe),e.random&&e.random.reseed(i),dt(),l="playing"}function Zn(R){s=e.time.nowMs(),o=s/1e3,l==="playing"&&(ct(R),Re()&&y&&y.state!=="flying"&&(l="gameover",u="win",de()),d>=5&&(!y||y.state==="hit"||y.state==="ready")&&(l="gameover",u="lose",de()),A=A.filter(M=>s-M.born5){let Vt=Math.atan2(xt,D),Le=12;R.fillStyle="#fff",R.beginPath(),R.moveTo(_.x+D/4,_.y+xt/4),R.lineTo(_.x+D/4-Le*Math.cos(Vt-.4),_.y+xt/4-Le*Math.sin(Vt-.4)),R.lineTo(_.x+D/4-Le*Math.cos(Vt+.4),_.y+xt/4-Le*Math.sin(Vt+.4)),R.fill()}}R.fillStyle="rgba(255,255,255,0.8)",R.font="bold 20px monospace",R.textAlign="left",R.fillText("\u{1F426} \xD7"+f,10,30),R.textAlign="right",R.fillText("\u{1F3C6} "+h,380,30),R.textAlign="center",R.fillStyle="#9f9",R.font="16px monospace";let M=l==="gameover"?u==="win"?"\u2728 \u5168\u706D!":"\u{1F480} \u5931\u8D25":y&&y.state==="flying"?"\u{1F3AF} \u98DE\u884C\u4E2D":"\u{1F4D0} \u62D6\u62FD\u84C4\u529B";R.fillText(M,195,55);for(let D of A){let xt=(s-D.born)/D.duration,se=1-xt;R.globalAlpha=se,R.fillStyle="#ffdd44",R.font="bold 18px monospace",R.textAlign="center",R.fillText(D.text,D.x,D.y-20*xt),R.globalAlpha=1}l==="gameover"&&(R.fillStyle="rgba(0,0,0,0.4)",R.fillRect(100,600,190,60),R.strokeStyle="#fff",R.lineWidth=2,R.strokeRect(100,600,190,60),R.fillStyle="#fff",R.font="bold 22px monospace",R.textAlign="center",R.fillText("\u70B9\u51FB\u91CD\u73A9",195,638))}function hn(){try{r&&r.cancel()}catch{}try{c&&c.cancel()}catch{}try{a&&a.cancel()}catch{}r=c=a=null,E=[],A=[],x=[],v=[],y=null}function dn(){return{seed:i,state:()=>{let R=v.filter(M=>M.active).map(M=>({x:M.x,y:M.y}));return{phase:l,result:l==="gameover"?u:null,score:h,birdsLeft:f,targets:R}}}}return{init:Dn,update:Zn,render:ti,destroy:hn,_forensicsView:dn}}var pd=ii,yd=ii;async function gd(n){let t=n||{},e=t.engine||await Promise.resolve().then(()=>(Mc(),Ic)),i=(t.seed!=null?t.seed:305441741)>>>0,s=va({seed:i});return na({canvas:t.canvas,statusEl:t.statusEl||null,engine:e,seed:i,mode:t.mode||"play",engineMode:"real",viewport:s.viewport,factory:ii,plugins:s.plugins,registerOrder:s.registerOrder,buildFactoryOpts:s.buildFactoryOpts,recHook:t.recHook||null,onReady:t.onReady||null})}return Bc(md);})();
+color = `+this.color),t}renderDebug(t=!0){let e=t?this.isHoverObject()?Xa:this.disabled?Ka:this.interactive?nr:$a:Ya;C.drawRect(this.nativePos,this.size,ce,4,e)}click(t=!0){this.onClick(),t&&this.soundClick&&this.soundClick.play()}onUpdate(){}onRender(){}onEnter(){}onLeave(){}onPress(){}onRelease(){}onClick(){}onChange(){}},ys=class extends ee{constructor(t,e,i="",s="center",o=C.defaultFont){super(t,e),p(J(i),"ui text must be a string"),p(["left","center","right"].includes(s),"ui text align must be left, center, or right"),p(J(o),"ui text font must be a string"),this.text=i,this.align=s,this.font=o,this.canBeHover=!1,this.color=ce,this.shadowColor=ce,this.gradientColor=void 0,this.lineWidth=0,this.textFitScale=1}render(){super.render();let t=this.getTextSize();C.drawText(this.text,this.nativePos,t,this.textColor,this.textLineWidth,this.textLineColor,this.align,this.font,this.fontStyle,!0,this.textShadow,this.shadowColor,this.shadowBlur,this.shadowOffset)}},Lo=class extends ee{constructor(t,e,i=""){super(t,e),p(J(i),"ui text must be a string"),this.maxLength=0,this.text=i,this.interactive=!0,this.canBeHover=!0}click(){C.keyInputObject=this,this.onClick()}stopEditing(){this.isKeyInputObject()&&(this.soundRelease&&this.soundRelease.play(),C.activeObject=void 0,C.keyInputObject=void 0,this.onChange())}onKeyDown(t){let e=t.code,i=t.key;e==="Backspace"?this.text=this.text.slice(0,-1):e==="Enter"||e==="Escape"?this.stopEditing():i.length===1&&(!this.maxLength||this.text.lengththis.size.y,i=e?this.size.y:this.size.x,s=e?this.size.x:this.size.y,o=e?this.nativePos.x:this.nativePos.y,r=s-i,a=o-r/2,c=o+r/2,l=C.screenToNative(Ft);this.value=e?It(l.x,a,c):It(l.y,c,a)}else if(this.isNavigationObject()){let e=C.getNavigationOtherDirection();C.navigationTimer.active()||(this.value=j(this.value+e*.01))}this.value===t||this.onChange()}render(){super.render();let t=this.size.x>this.size.y,e=t?this.size.x:this.size.y,i=t?this.size.y:this.size.x;if(this.fillMode){let o=Q(i,this.cornerRadius*2),r=Nt(o,e,this.value),a=(r-e)*(t?.5:-.5),c=this.nativePos.add(t?x(a,0):x(0,a)),l=this.disabled?this.disabledColor:this.handleColor,u=t?x(r,this.size.y):x(this.size.x,r);C.drawRect(c,u,l,this.lineWidth,this.lineColor,this.cornerRadius,this.gradientColor)}else{let o=j(t?this.value:1-this.value),r=(e-i)*(o-.5),a=this.nativePos.add(t?x(r,0):x(0,r)),c=this.disabled?this.disabledColor:this.handleColor,l=x(i);C.drawRect(a,l,c,this.lineWidth,this.lineColor,this.cornerRadius,this.gradientColor)}let s=this.getTextSize();C.drawText(this.text,this.nativePos,s,this.textColor,this.textLineWidth,this.textLineColor,this.align,this.font,this.fontStyle,!0,this.textShadow)}navigatePressed(){this.value=this.value?0:1,this.onChange(),this.onRelease(),super.navigatePressed()}},Mo=class extends ee{constructor(t,e,i,s=!1,o=!1,r=1){super(t,e||x()),p(J(i),"video src must be a string"),p(L(r),"video volume must be a number"),this.color=it,this.cornerRadius=0,this.volume=r,this.video=document.createElement("video"),this.video.loop=o,this.video.volume=j(r*gn),this.video.muted=!Jt,this.video.style.display="none",this.video.src=i,document.body.appendChild(this.video),s&&this.play()}async play(){try{await this.video.play()}catch{}}pause(){this.video.pause()}stop(){this.video.pause(),this.video.currentTime=0}isLoading(){return this.video.readyState=1,"ui layout columns must be a number >= 1"),p(L(i),"ui layout gap must be a number"),p(L(s),"ui layout padding must be a number"),this.columns=e,this.gap=i,this.padding=s,o&&(this.color=ce,this.gradientColor=void 0,this.lineWidth=0,this.shadowColor=ce),this.relayout()}addChild(t){return super.addChild(t),this.relayout(),t}removeChild(t){super.removeChild(t),this.relayout()}relayout(){let t=this.children.length;if(!t){this.size=x(this.padding*2);return}let e=this.columns,i=oi(t/e),s=new Array(e).fill(0),o=new Array(i).fill(0);for(let f=0;f=0&&m.objects.splice(t,1),super.destroy()}updatePhysics(){}render(){this.tileInfo?super.render():this.drawFixtures(this.color,this.lineColor,this.lineWidth)}renderDebugInfo(){let t=!this.getIsAwake(),e=this.getBodyType()===m.bodyTypeStatic,i=N(t?1:0,t?1:0,e?1:0,.5);this.drawFixtures(i)}drawFixtures(t=U,e=it,i=.1,s,o){this.getFixtureList().forEach(r=>{m.castShapeObject(r.GetShape()).GetType()!==m.instance.b2Shape.e_edge&&m.drawFixture(r,this.pos,this.angle,t,e,i,s,o)}),this.edgeLists.forEach(r=>fo(r,i,e,!1,this.pos,this.angle)),this.edgeLoops.forEach(r=>fo(r,i,e,!0,this.pos,this.angle))}beginContact(t){}endContact(t){}addShape(t,e=1,i=.2,s=0,o=!1){p(L(e),"density must be a number"),p(L(i),"friction must be a number"),p(L(s),"restitution must be a number");let r=new m.instance.b2FixtureDef;return r.set_shape(t),r.set_density(e),r.set_friction(i),r.set_restitution(s),r.set_isSensor(o),this.body.CreateFixture(r)}addBox(t=x(1),e=x(),i=0,s,o,r,a){p(O(t),"size must be a Vector2"),p(t.x>0&&t.y>0,"size must be positive"),p(O(e),"offset must be a Vector2"),p(L(i),"angle must be a number");let c=new m.instance.b2PolygonShape;return c.SetAsBox(t.x/2,t.y/2,m.vec2dTo(e),-i),this.addShape(c,s,o,r,a)}addPoly(t,e,i,s,o){p(re(t),"points must be an array");function r(c){p(3<=c.length&&c.length<=8);let l=m.instance._malloc(c.length*8);for(let f=0,d=0;f>2]=c[f].x,d+=4,m.instance.HEAPF32[l+d>>2]=c[f].y,d+=4;let u=m.instance.wrapPointer(l,m.instance.b2Vec2),h=new m.instance.b2PolygonShape;return h.Set(u,c.length),m.instance._free(l),h}let a=r(t);return this.addShape(a,e,i,s,o)}addRegularPoly(t=1,e=8,i,s,o,r){p(L(t)&&t>0,"diameter must be a positive number"),p(L(e)&&e>2,"sides must be a positive number greater than 2");let a=[],c=t/2;for(let l=e;l--;)a.push(x(c,0).rotate((l+.5)/e*H*2));return this.addPoly(a,i,s,o,r)}addRandomPoly(t=1,e,i,s,o){p(L(t)&&t>0,"diameter must be a positive number");let r=er(3,9),a=[],c=t/2;for(let l=r;l--;)a.push(x(ht(c/2,c*1.5),0).rotate(l/r*H*2));return this.addPoly(a,e,i,s,o)}addCircle(t=1,e=x(),i,s,o,r){p(L(t)&&t>0,"diameter must be a positive number"),p(O(e),"offset must be a Vector2");let a=new m.instance.b2CircleShape;return a.set_m_p(m.vec2dTo(e)),a.set_m_radius(t/2),this.addShape(a,i,s,o,r)}addEdge(t,e,i,s,o,r){p(O(t),"point1 must be a Vector2"),p(O(e),"point2 must be a Vector2");let a=new m.instance.b2EdgeShape;return a.Set(m.vec2dTo(t),m.vec2dTo(e)),this.addShape(a,i,s,o,r)}addEdgeList(t,e,i,s,o){p(re(t),"points must be an array");let r=[],a=[];for(let c=0;ct[Qt(l,t.length)];for(let l=0;lthis.destroyFixture(t))}getCenterOfMass(){return m.vec2From(this.body.GetWorldCenter())}getLinearVelocity(){return m.vec2From(this.body.GetLinearVelocity())}getAngularVelocity(){return this.body.GetAngularVelocity()}getMass(){return this.body.GetMass()}getInertia(){return this.body.GetInertia()}getIsAwake(){return this.body.IsAwake()}getBodyType(){return this.body.GetType()}getSpeed(){return this.getLinearVelocity().length()}setTransform(t,e){this.pos=t,this.angle=e,this.body.SetTransform(m.vec2dTo(t),-e)}setPosition(t){this.setTransform(t,this.body.GetAngle())}setAngle(t){this.setTransform(m.vec2From(this.body.GetPosition()),t)}setLinearVelocity(t){this.body.SetLinearVelocity(m.vec2dTo(t))}setAngularVelocity(t){this.body.SetAngularVelocity(t)}setLinearDamping(t){this.body.SetLinearDamping(t)}setAngularDamping(t){this.body.SetAngularDamping(t)}setGravityScale(t=1){this.body.SetGravityScale(this.gravityScale=t)}setBullet(t=!0){this.body.SetBullet(t)}setAwake(t=!0){this.body.SetAwake(t)}setBodyType(t){this.body.SetType(t)}setSleepingAllowed(t=!0){this.body.SetSleepingAllowed(t)}setFixedRotation(t=!0){this.body.SetFixedRotation(t)}setCenterOfMass(t){this.setMassData(t)}setMass(t){this.setMassData(void 0,t)}setMomentOfInertia(t){this.setMassData(void 0,void 0,t)}resetMassData(){this.body.ResetMassData()}setMassData(t,e,i){let s=new m.instance.b2MassData;this.body.GetMassData(s),t!==void 0&&s.set_center(m.vec2dTo(t)),e!==void 0&&s.set_mass(e),i!==void 0&&s.set_I(i),this.body.SetMassData(s)}setFilterData(t=0,e=0,i=0){this.getFixtureList().forEach(s=>{let o=s.GetFilterData();o.set_categoryBits(t),o.set_maskBits(65535&~e),o.set_groupIndex(i)})}setSensor(t=!0){this.getFixtureList().forEach(e=>e.SetSensor(t))}applyForce(t,e){e||(e=this.getCenterOfMass()),this.setAwake(),this.body.ApplyForce(m.vec2dTo(t),m.vec2dTo(e))}applyAcceleration(t,e){e||(e=this.getCenterOfMass()),this.setAwake();let i=t.scale(this.getMass());this.body.ApplyLinearImpulse(m.vec2dTo(i),m.vec2dTo(e))}applyImpulse(t,e){e||(e=this.getCenterOfMass()),this.setAwake(),this.body.ApplyLinearImpulse(m.vec2dTo(t),m.vec2dTo(e))}applyTorque(t){this.setAwake(),this.body.ApplyTorque(t)}applyAngularAcceleration(t){this.setAwake(),this.body.ApplyAngularImpulse(t*this.getInertia())}applyAngularImpulse(t){this.setAwake(),this.body.ApplyAngularImpulse(t)}hasFixtures(){return!m.isNull(this.body.GetFixtureList())}getFixtureList(){let t=[];for(let e=this.body.GetFixtureList();!m.isNull(e);)t.push(e),e=e.GetNext();return t}hasJoints(){return!m.isNull(this.body.GetJointList())}getJointList(){let t=[];for(let e=this.body.GetJointList();!m.isNull(e);)t.push(e),e=e.get_next();return t}},gs=class extends wi{constructor(t,e,i,s=0,o,r=0){let a=m.bodyTypeStatic;super(t,e,i,s,o,a,r)}},Go=class extends wi{constructor(t,e,i,s=0,o,r=0){let a=m.bodyTypeKinematic;super(t,e,i,s,o,a,r)}},Fo=class extends gs{constructor(t){p(t instanceof yi,"tileLayer must be a TileCollisionLayer"),super(t.pos,t.size),this.tileLayer=t,this.addChild(t)}render(){}buildCollision(t=.2,e=0){this.destroyAllFixtures(),this.pos=this.tileLayer.pos.copy(),this.size=this.tileLayer.size.copy();let i=[],s=(r,a)=>r+a*this.size.x,o=(r,a)=>!i[s(r,a)]&&this.tileLayer.getCollisionData(x(r,a))>0;for(let r=0;rs.fractiono.pos.distanceSquared(t)0,"Tween duration must be > 0"),this.callback=t,this.start=e,this.end=i,this.duration=s,this.life=s,this.ease=o.ease||Ss.LINEAR,this.useRealTime=!!o.useRealTime,this.paused=!!o.paused,this.thenCallback=void 0,this.loopRemaining=0,Wt.push(this),t(this.interp(s))}setEase(t){return this.ease=t,this}then(t){return this.thenCallback=t,this.loopRemaining=0,this}loop(t=1/0){return this.loopRemaining=t,this.thenCallback=()=>_c(this),this}pingPong(t=1/0){return this.loopRemaining=t,this.thenCallback=()=>Rc(this),this}pause(){this.paused=!0}resume(){this.paused=!1}restart(){this.life=this.duration,this.paused=!1,Wt.indexOf(this)<0&&Wt.push(this),this.callback(this.interp(this.duration))}isActive(){return!this.paused&&Wt.indexOf(this)>=0}getPercent(){return It(this.duration-this.life,0,this.duration)}getValue(){return this.interp(this.life)}interp(t){let e=this.ease((this.duration-t)/this.duration);return _a(this.start)?this.start.lerp(this.end,e):this.start+(this.end-this.start)*e}stop(){let t=Wt.indexOf(this);t>=0&&Wt.splice(t,1),this.thenCallback=void 0}},Ss={LINEAR:n=>n,POWER:n=>t=>t**n,SINE:n=>1-at(n*(H/2)),CIRC:n=>1-(1-n*n)**.5,EXPO:n=>n===0?0:2**(10*n-10),BACK:n=>n*n*(2.70158*n-1.70158),ELASTIC:n=>n===0?0:n===1?1:-(2**(10*n-10))*et((37-40*n)*H/6),SPRING:n=>1-(et(H*(1-n)*(.2+2.5*(1-n)**3))*n**2.2+(1-n))*(1+1.2*n),BOUNCE:n=>{let t=1-n,e;return t<4/11?e=7.5625*t*t:t<8/11?e=7.5625*(t-=6/11)*t+.75:t<10/11?e=7.5625*(t-=9/11)*t+.9375:e=7.5625*(t-=10.5/11)*t+.984375,1-e},IN:n=>n,OUT:n=>t=>1-n(1-t),IN_OUT:n=>Ss.PIECEWISE(n,Ss.OUT(n)),PIECEWISE:(...n)=>{let t=n.length;return e=>{let i=e*t-1e-9>>0;return(n[i]((e-i/t)*t)+i)/t}},BEZIER:(n,t,e,i)=>{let s=o=>{let r=1-o,a=3*r*r*o,c=3*r*o*o,l=o**3;return[a*n+c*e+l,a*t+c*i+l]};return o=>{let r=0,a=1;for(let c=0;c<128;c++){let l=(r+a)/2,[u,h]=s(l);if(tt(u-o)<1e-5)return h;u=this.size.x||e>=this.size.y?null:this.nodes[t+e*this.size.x]}worldToTile(t){let e=this.tileLayer?this.tileLayer.pos.x:0,i=this.tileLayer?this.tileLayer.pos.y:0;return x(xt(t.x-e),xt(t.y-i))}tileToWorld(t,e){let i=this.tileLayer?this.tileLayer.pos.x:0,s=this.tileLayer?this.tileLayer.pos.y:0;return x(t+.5+i,e+.5+s)}buildNodeData(){let t=this.size.x,e=this.size.y,i=this.tileLayer?this.tileLayer.pos.x:0,s=this.tileLayer?this.tileLayer.pos.y:0;for(let o=0;o0&&(c?l>0&>(a.posWorld,oo,N(1,0,0,Q(.2,l*.05)),this.debugTime):gt(a.posWorld,oo,N(1,0,0,.25),this.debugTime))}}aStarSearch(t,e){p(t&&e,"aStarSearch needs both endpoints"),p(t!==e,"aStarSearch: start and end must differ \u2014 caller should handle trivial case"),p(t.walkable&&e.walkable,"aStarSearch: endpoints must be walkable");let i=[t];t.isOpen=!0;let s=0;for(;i.length>0;){let o=0,r=i[0].f;for(let c=1;cthis.maxLoop)break;a.isOpen=!1,i.splice(o,1),a.isClosed=!0,this.debug&&this.debugTime>0&>(a.posWorld,oo,N(1,1,1,.05),this.debugTime);for(let c=-1;c<=1;++c)for(let l=-1;l<=1;++l){if(l===0&&c===0)continue;let u=this.getNode(a.pos.x+l,a.pos.y+c);if(!u||!u.walkable||u.isClosed)continue;let h=1;if(l!==0&&c!==0){let v=this.getNode(a.pos.x+l,a.pos.y);if(!v||!v.walkable)continue;let w=this.getNode(a.pos.x,a.pos.y+c);if(!w||!w.walkable)continue;h=fd}let f=a.g+h+u.cost;if(!u.isOpen)u.isOpen=!0,i.push(u);else if(f>=u.g)continue;u.parent=a,u.g=f;let d=tt(e.pos.x-u.pos.x),g=tt(e.pos.y-u.pos.y),b=Y(d,g)+(Math.SQRT2-1)*Q(d,g);u.f=u.g+b*this.heuristicWeight}}return e.parent!==null}getNearestClearNode(t,e=10,i=!0){p(O(t),"worldPos must be a Vector2"),i&&this.buildNodeData();let s=this.tileLayer?this.tileLayer.pos.x:0,o=this.tileLayer?this.tileLayer.pos.y:0,r=xt(t.x-s),a=xt(t.y-o);for(let c=0;c<=e;++c){let l=null,u=0;for(let h=-c;h<=c;++h)for(let f=-c;f<=c;++f){if(c>0&&tt(f)!==c&&tt(h)!==c)continue;let d=this.getNode(r+f,a+h);if(!d||!d.isClear())continue;let g=d.posWorld.x-t.x,b=d.posWorld.y-t.y,v=g*g+b*b;(!l||v0&&jt(s.posWorld,.3,N(.5,0,.5,.5),this.debugTime),t.splice(e,1),e=Y(1,e-1);continue}else if(c===2){this.debug&&this.debugTime>0&&jt(s.posWorld,.3,N(1,0,0,.5),this.debugTime);let d,g;i.pos.y===s.pos.y&&o.pos.x===s.pos.x?(d=i.pos.x,g=o.pos.y):(d=o.pos.x,g=i.pos.y);let b=this.getNode(d,g);if(b&&b.isClear()){t.splice(e,1),e=Y(1,e-1);continue}}else if(c===5){this.debug&&this.debugTime>0&&jt(s.posWorld,.3,N(1,1,0,.5),this.debugTime);let d=e>=2?t[e-2]:i,g,b,v,w;l===0||h===0?(g=o.pos.x,b=s.pos.y,v=i.pos.x,w=s.pos.y):(g=s.pos.x,b=o.pos.y,v=s.pos.x,w=i.pos.y);let _=g-d.pos.x,S=b-d.pos.y,E=v-d.pos.x,A=w-d.pos.y,T=_*_+S*S,P=E*E+A*A,M=T0&&jt(s.posWorld,.3,N(0,1,0,.5),this.debugTime),l===h&&u===f){++e;continue}else{let d,g;i.pos.y===o.pos.y?(d=s.pos.x,g=i.pos.y):(d=i.pos.x,g=s.pos.y);let b=this.getNode(d,g);if(b&&b.isClear()){t[e]=b,e=Y(1,e-1);continue}}++e}}smoothPathStringPull(t){if(t.length<=2)return;for(let s of t)if(!s.isClear())return;let e=t.slice();t.length=0,t.push(e[0]);let i=0;for(let s=1;s0&&ge(o.posWorld,t[t.length-1].posWorld,N(0,0,1,.3),.02,this.debugTime);continue}for(;i=1;--e){let i=t[e-1],s=t[e],o=t[e+1];(s.pos.x-i.pos.x)*(o.pos.y-i.pos.y)===(s.pos.y-i.pos.y)*(o.pos.x-i.pos.x)&&t.splice(e,1)}}isNodeClear(t,e){let i=this.getNode(t,e);return i!==null&&i.isClear()}isLineClear(t,e){p(O(t)&&O(e),"isLineClear needs Vector2 endpoints"),p(this.isNodeClear(t.x,t.y)&&this.isNodeClear(e.x,e.y),"isLineClear endpoints must be in-bounds and clear");let i=e.x-t.x,s=e.y-t.y,o=tt(i),r=tt(s),a=Kt(i),c=Kt(s),l=t.x,u=t.y;if(r===o){for(;l!==e.x;){if(l!==t.x&&(!this.isNodeClear(l,u)||!this.isNodeClear(l,u-c))||!this.isNodeClear(l,u+c))return!1;l+=a,u+=c}if(!this.isNodeClear(e.x,e.y-c))return!1}else if(ra.posWorld.copy());if(this.debug&&this.debugTime>0&&r.length>0){for(let a=1;apd,bootGameHost:()=>gd,default:()=>yd});var Ii=class{constructor(t){this._state=(t==null?2654435769:t)>>>0}next(){this._state=this._state+1831565813>>>0;let t=this._state;return t=Math.imul(t^t>>>15,t|1),t^=t+Math.imul(t^t>>>7,t|61),((t^t>>>14)>>>0)/4294967296}range(t,e){return t+this.next()*(e-t)}reseed(t){this._state=(t==null?2654435769:t)>>>0}},js=class{constructor(t){this._clock=t||Jc(),this._origin=this._clock()}nowMs(){return this._clock()}elapsedMs(){return this._clock()-this._origin}},Bs=class{constructor(t){this._time=t,this._subs=new Map}sourceFor(t){let e=this,i=t==null?null:t;return{on(s,o){if(e._assertType(s),typeof o!="function")throw new Error("[HostDevInputBridge] on \u7684 handler \u5FC5\u987B\u662F\u51FD\u6570");let r=e._subs.get(s)||[],a={handler:o,scope:i};return r.push(a),e._subs.set(s,r),{cancel(){let c=e._subs.get(s);if(!c)return;let l=c.indexOf(a);l>=0&&c.splice(l,1)}}},off(s,o){e._assertType(s);let r=e._subs.get(s);if(!r)return;let a=r.findIndex(c=>c.handler===o&&c.scope===i);a>=0&&r.splice(a,1)}}}_emit(t,e){this._assertType(t);let i=e||{},s={type:t,x:typeof i.x=="number"?i.x:0,y:typeof i.y=="number"?i.y:0,key:typeof i.key=="string"?i.key:"",tMs:this._time.nowMs()},o=this._subs.get(t);if(!o||o.length===0)return;let r=o.slice();for(let a of r)try{a.handler(s)}catch(c){Ne("[host-dev input] \u8F93\u5165 handler \u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09type="+t,c)}}disposeScope(t){if(t==null)return 0;let e=0;for(let[i,s]of this._subs){let o=s.filter(r=>r.scope!==t);e+=s.length-o.length,o.length===0?this._subs.delete(i):this._subs.set(i,o)}return e}_subscriptionCount(){let t=0;for(let e of this._subs.values())t+=e.length;return t}_assertType(t){if(!Ns.has(t))throw new Error("[HostDevInputBridge] \u975E\u6CD5\u8F93\u5165\u4E8B\u4EF6\u7C7B\u578B\uFF1A"+String(t)+"\uFF08\u4EC5\u652F\u6301 "+Array.from(Ns).join("/")+"\uFF09")}},Ns=new Set(["pointerdown","pointermove","pointerup","keydown","keyup"]);function Wr(n){let t=n||{},e=new js(t.clock),i=new Ii(t.seed),s=t.seed==null?2654435769:t.seed>>>0,o=new Bs(e),r=typeof t.audioFactory=="function"?t.audioFactory:null,a=null,c=!1,l=typeof t.engineFactory=="function"?t.engineFactory:null,u=null,h=!1,f=new Map,d=0,g=0;function b(){if(a)return a;if(!r)return c||(Js("[host-dev audio] \u672A\u6CE8\u5165 audioFactory\uFF0CgetAudioContext \u8FD4\u56DE null\uFF08P6 \u987B\u5BB9\u9519\u964D\u7EA7\uFF1B\u96C6\u6210\u6BB5\u6CE8\u5165\u771F\u5B9E\u5DE5\u5382\uFF09"),c=!0),null;try{a=r()}catch(E){Ne("[host-dev audio] audioFactory \u629B\u9519\uFF0CgetAudioContext \u964D\u7EA7\u8FD4\u56DE null",E),a=null}return a}function v(){if(u)return u;if(!l)return h||(Js("[host-dev engine] \u672A\u6CE8\u5165 engineFactory\uFF0CgetEngine \u8FD4\u56DE null\uFF08\u63D2\u4EF6\u987B\u5BB9\u9519\u964D\u7EA7\uFF1A\u7C92\u5B50\u9000\u53D7\u63A7\u9762\u81EA\u7BA1/\u5408\u6210\u6838\u9000 vendored/\u6570\u5B66\u9000\u5185\u7F6E\uFF1B\u96C6\u6210\u6BB5\u6CE8\u5165\u771F\u5B9E\u80CC\u4E66\uFF09"),h=!0),null;try{u=l()}catch(E){Ne("[host-dev engine] engineFactory \u629B\u9519\uFF0CgetEngine \u964D\u7EA7\u8FD4\u56DE null",E),u=null}return u}function w(E,A){return{getContext2d(){return t.context2d==null?null:t.context2d},onFrame(P){let M=d++;return f.set(M,P),{cancel(){f.delete(M)}}},getInput(){return o.sourceFor(E)},getAudioContext(){return b()},getEngine(){return v()},time:e,random:A}}let _=w(null,i),S={context:_,tick(E){g+=1;let A=Array.from(f.values());for(let T of A)try{T(E,g)}catch(P){Ne("[host-dev tick] \u5E27\u56DE\u8C03\u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09frame="+g,P)}},frameCount(){return g},inputBridge:o,deriveContextFor(E,A){let T=zc(s,E),P=new Ii(T);return w(A==null?E:A,P)}};return Object.defineProperty(_,zs,{value:S,enumerable:!1,writable:!1,configurable:!1}),S}var zs=Symbol("zaomeng.coreProtocol.contextBundle"),Mi=class{constructor(){this._plugins=new Map,this._initOrder=[],this._initErrors=[],this._phase="idle",this._disposed=!1,this._context=void 0,this._pluginContexts=new Map}register(t){if(!t||typeof t!="object")throw new Error("[PluginRegistry] register \u9700\u8981\u4E00\u4E2A\u63D2\u4EF6\u5BF9\u8C61");if(typeof t.name!="string"||t.name.length===0)throw new Error("[PluginRegistry] \u63D2\u4EF6\u7F3A\u5C11\u5408\u6CD5 name");if(typeof t.version!="string"||t.version.length===0)throw new Error("[PluginRegistry] \u63D2\u4EF6 "+t.name+" \u7F3A\u5C11\u5408\u6CD5 version");if(typeof t.init!="function")throw new Error("[PluginRegistry] \u63D2\u4EF6 "+t.name+" \u7F3A\u5C11 init \u51FD\u6570");if(t.dispose!=null&&typeof t.dispose!="function")throw new Error("[PluginRegistry] \u63D2\u4EF6 "+t.name+" \u7684 dispose \u5FC5\u987B\u662F\u51FD\u6570\u6216\u7701\u7565");if(this._plugins.has(t.name))throw new Error("[PluginRegistry] \u63D2\u4EF6\u91CD\u540D\u62D2\u7EDD\uFF1A"+t.name+" \u5DF2\u6CE8\u518C");return this._plugins.set(t.name,t),this}has(t){return this._plugins.has(t)}get(t){return this._plugins.get(t)}list(){return Array.from(this._plugins.keys())}initAll(){if(this._phase==="initialized")return Js("[PluginRegistry] initAll \u91CD\u590D\u8C03\u7528\uFF0C\u5DF2\u5FFD\u7565\uFF08\u5DF2\u5904\u4E8E initialized\uFF09"),this._initResult();if(this._phase==="disposed")throw new Error("[PluginRegistry] \u5DF2 dispose \u7684\u6CE8\u518C\u5668\u4E0D\u53EF\u518D initAll");if(this._context==null)throw new Error("[PluginRegistry] \u672A\u6CE8\u5165\u53D7\u63A7\u4E0A\u4E0B\u6587\uFF1A\u8BF7\u5728 initAll() \u4E4B\u524D\u8C03\u7528 useContext(context)\u3002\uFF08host-dev \u7528\u6CD5\uFF1Aconst { context } = createHostDevContext(); reg.useContext(context); reg.initAll();\uFF09");for(let[t,e]of this._plugins){let i=this._missingDeps(e);if(i.length>0){let o=new Error("[PluginRegistry] \u63D2\u4EF6 "+t+" \u4F9D\u8D56\u7F3A\u5931\uFF1A"+i.join(", ")+"\uFF08\u672A\u6CE8\u518C\uFF09");this._initErrors.push({name:t,error:o}),Ne("[PluginRegistry] \u8DF3\u8FC7 init\uFF08\u4F9D\u8D56\u7F3A\u5931\uFF0C\u5DF2\u9694\u79BB\uFF09\uFF1A"+t,o);continue}let s=this._contextFor(t);try{e.init(s),this._initOrder.push(t)}catch(o){let r=o instanceof Error?o:new Error(String(o));this._initErrors.push({name:t,error:r}),Ne("[PluginRegistry] \u63D2\u4EF6 init \u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF0C\u4E0D\u8FDE\u5750\uFF09\uFF1A"+t,r)}}return this._phase="initialized",this._initResult()}_contextFor(t){let e=this._pluginContexts.get(t);if(e)return e;let i=this._context&&this._context[zs],s;return i&&typeof i.deriveContextFor=="function"?s=i.deriveContextFor(t,t):s=this._context,this._pluginContexts.set(t,s),s}disposeAll(){if(this._disposed)return{disposed:[],errors:[]};let t=[],e=[],i=this._context&&this._context[zs],s=i&&i.inputBridge;for(let o=this._initOrder.length-1;o>=0;o--){let r=this._initOrder[o],a=this._plugins.get(r);if(a&&typeof a.dispose=="function")try{a.dispose(),t.push(r)}catch(c){let l=c instanceof Error?c:new Error(String(c));e.push({name:r,error:l}),Ne("[PluginRegistry] \u63D2\u4EF6 dispose \u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09\uFF1A"+r,l)}if(s&&typeof s.disposeScope=="function")try{s.disposeScope(r)}catch(c){Ne("[PluginRegistry] \u56DE\u6536\u63D2\u4EF6\u8F93\u5165\u8BA2\u9605\u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09\uFF1A"+r,c)}}return this._disposed=!0,this._phase="disposed",{disposed:t,errors:e}}useContext(t){if(this._phase!=="idle")throw new Error("[PluginRegistry] useContext \u5FC5\u987B\u5728 initAll() \u4E4B\u524D\u8C03\u7528\uFF08\u5F53\u524D\u9636\u6BB5\uFF1A"+this._phase+"\uFF09\u3002\u8BF7\u5728\u4EFB\u4F55 initAll/disposeAll \u4E4B\u524D\u6CE8\u5165\u53D7\u63A7\u4E0A\u4E0B\u6587\u3002");if(t==null||typeof t!="object")throw new Error("[PluginRegistry] useContext \u9700\u8981\u4E00\u4E2A\u53D7\u63A7\u4E0A\u4E0B\u6587\u5BF9\u8C61\u3002\uFF08host-dev \u7528\u6CD5\uFF1Aconst { context } = createHostDevContext(); reg.useContext(context);\uFF09");return this._context=t,this}_missingDeps(t){return!Array.isArray(t.dependencies)||t.dependencies.length===0?[]:t.dependencies.filter(e=>!this._plugins.has(e))}_initResult(){return{ok:this._initErrors.length===0,initialized:this._initOrder.slice(),errors:this._initErrors.slice()}}};function zc(n,t){let e=2166136261,i=16777619,s=n>>>0;for(let r=0;r<32;r+=8){let a=s>>>r&255;e^=a,e=Math.imul(e,i)>>>0}let o=String(t);for(let r=0;r>>0,e^=a>>>8&255,e=Math.imul(e,i)>>>0}return e>>>0}function Jc(){if(typeof globalThis!="undefined"&&globalThis.performance&&typeof globalThis.performance.now=="function")return()=>globalThis.performance.now();if(typeof process!="undefined"&&process.hrtime&&typeof process.hrtime.bigint=="function"){let n=process.hrtime.bigint();return()=>Number(process.hrtime.bigint()-n)/1e6}return()=>Date.now()}function Ne(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function Js(n){typeof console!="undefined"&&typeof console.warn=="function"&&console.warn(n)}var xd=Object.freeze(Array.from(Ns)),qr="core-protocol-v0";var Hr=Object.freeze(["t_boot","t_plugins_ready","t_game_init","t_first_paint","t_input_bound","t_game_start"]),Us=Hr.reduce((n,t,e)=>(n[t]=e,n),Object.create(null)),Uc=new Set(Hr);function Vs(n){let t=2166136261;for(let e=0;e>>0).toString(16).padStart(8,"0")}var Xr=Vs("runtime-probe::seed::v1");function ki(n){return n===null||typeof n!="object"?JSON.stringify(n):Array.isArray(n)?"["+n.map(ki).join(",")+"]":"{"+Object.keys(n).sort().map(e=>JSON.stringify(e)+":"+ki(n[e])).join(",")+"}"}function Yr(n){let t=ki(n.extra==null?null:n.extra),e=ki(Array.isArray(n.pluginSet)?n.pluginSet:[]);return["seq="+n.seq,"anchor="+n.anchor,"tMono="+n.tMono,"buildSha="+(n.buildSha||""),"pluginSet="+e,"extra="+t].join("|")}function Vc(n){return Math.round(n*1e3)/1e3}function Wc(n){if(!Array.isArray(n))return{ok:!1,reason:"records_not_array"};let t=Xr,e=-1;for(let i=0;itypeof E=="string").slice().sort():[],s=typeof t.sink=="function"?t.sink:null,o=t.autoBoot!==!1,r=typeof t.inputAnchorType=="string"?t.inputAnchorType:"pointerdown",a=()=>0,c=!1,l=0,u=Xr,h=[],f=new Set,d=-1,g=null,b=!1,v=!1,w=!1;function _(E,A){let T=null;if(!Uc.has(E))T="unknown_anchor";else{f.has(E)&&(T=T?T+";duplicate_anchor":"duplicate_anchor");let M=Us[E];ME.time.nowMs(),c=!0,o&&!v&&_("t_boot",{auto:!0}),g=E.getInput().on(r,A=>{b||(b=!0,_("t_input_bound",{firstInput:!0,type:A.type}))}),_("t_input_bound",{stage:"registered",type:r})},dispose(){w||(g&&(g.cancel(),g=null),w=!0)},mark:_,getRecords(){return h.map(E=>({...E}))},toJSONL(){return h.map(E=>JSON.stringify(E)).join(`
+`)},verify(){return Wc(h)}}}function qc(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function Kr(n){let t=n.LJS,e=n.engineMath,i=n.engineMode,s=n.recHook||(()=>{});if(i!=="real")return null;let o=e;return{math:{lerp:(a,c,l)=>(s("math.lerp"),o.lerp(a,c,l)),smoothStep:a=>(s("math.smoothStep"),o.smoothStep(a)),easing:Object.fromEntries(Object.keys(o.easing).map(a=>[a,c=>(s("math.easing."+a),o.easing[a](c))]))},particles:{spawnEmitter(a){s("particles.spawnEmitter");let c=t.screenToWorld(t.vec2(a.pos.x,a.pos.y)),l=t.cameraScale,u=a.emitTime!=null?a.emitTime:a.count!=null?1/60:0,h=a.emitRate!=null?a.emitRate:a.count!=null?a.count*60:100,f=(a.speed!=null?a.speed:0)/l/60,d=a.damping!=null?a.damping:1,g=a.colorStart||{r:1,g:1,b:1,a:1},b=a.colorEnd||{r:1,g:1,b:1,a:0},v=t.rgb(g.r,g.g,g.b,g.a),w=t.rgb(b.r,b.g,b.b,b.a),_=new t.ParticleEmitter(c,a.angle!=null?a.angle:0,(a.emitSize!=null?a.emitSize:0)/l,u,h,a.coneAngle!=null?a.coneAngle:Math.PI,void 0,v,v,w,w,a.particleTime!=null?a.particleTime:.5,(a.sizeStart!=null?a.sizeStart:6)/l,(a.sizeEnd!=null?a.sizeEnd:0)/l,f,0,d,1,a.gravityScale!=null?a.gravityScale:0,Math.PI,.1,0,!1,a.additive!=null?a.additive:!1,!0);return{isActive(){return _.isActive()},stop(){_.destroyed||_.destroy(!0)}}}},audio:{synth:{synthSfx:a=>{s("audio.synth.synthSfx");try{return t.zzfxG(...a)}catch(c){return console.error("[host][engine-audio] zzfxG \u5408\u6210\u5F02\u5E38\uFF0C\u8FD4 null\uFF1A"+(c&&c.message?c.message:c)),null}},synthSong:(a,c,l,u)=>{s("audio.synth.synthSong");try{return t.zzfxM(a,c,l,u)}catch(h){return console.error("[host][engine-audio] zzfxM \u5408\u6210\u5F02\u5E38\uFF0C\u8FD4 null\uFF1A"+(h&&h.message?h.message:h)),null}}}}}}function ne(n){return n<0?0:n>1?1:n}function Qr(n){let t=n.Ease,e=t.POWER(2),i=t.POWER(3),s=t.OUT(e),o=t.IN_OUT(e),r=t.OUT(i),a=t.IN_OUT(i),c=t.OUT(t.BACK),l=t.OUT(t.ELASTIC);return{lerp:(u,h,f)=>n.lerp(u,h,f),smoothStep:u=>n.smoothStep(u),easing:{linear:u=>t.LINEAR(ne(u)),quadIn:u=>e(ne(u)),quadOut:u=>s(ne(u)),quadInOut:u=>o(ne(u)),cubicIn:u=>i(ne(u)),cubicOut:u=>r(ne(u)),cubicInOut:u=>a(ne(u)),backIn:u=>t.BACK(ne(u)),backOut:u=>c(ne(u)),elasticIn:u=>t.ELASTIC(ne(u)),elasticOut:u=>l(ne(u))}}}var ze=2,Gi=1/60;async function Zr(n){let t=n.canvas,e=n.statusEl||null,i=n.engine,s=n.seed>>>0,o=n.mode||"play",r=n.engineMode||"real",a=n.viewport.w,c=n.viewport.h,l=n.factory,u=n.buildFactoryOpts||(()=>{}),h=n.plugins||{},f=n.registerOrder||Object.values(h),d=n.onReady||(()=>{}),g=n.recHook||(()=>{});function b(D){e&&(e.textContent=D)}let v=[];window.addEventListener("error",D=>v.push({type:"error",message:String(D&&D.message||D)})),window.addEventListener("unhandledrejection",D=>v.push({type:"unhandledrejection",message:String(D&&D.reason&&D.reason.message||D&&D.reason||D)}));let w=null,_=!1;function S(){if(!_)return null;if(w)return w;let D=window.AudioContext||window.webkitAudioContext;return D?(w=new D,w):null}let E=0,A=null,T=null,P=null,M=null,ct=[],nt={},rt=null;function pt(D,st){try{P&&P.mark(D,st)}catch($t){v.push({type:"mark",message:String($t&&$t.message||$t)})}}function Mt(){T&&typeof T._refreshChecklist=="function"&&T._refreshChecklist(nt)}async function je(D,st){A=Wr({context2d:D,seed:s,audioFactory:S,clock:()=>E,engineFactory:()=>Kr({LJS:r==="real"?i:null,engineMath:r==="real"?Qr(i):null,engineMode:r,recHook:g})});let $t=new Mi;for(let ue of f)$t.register(ue);$t.useContext(A.context),M=$t.initAll(),ct=$t.list().concat(["runtime-probe"]),P=$r({pluginSet:ct,inputAnchorType:"pointerdown",autoBoot:!0});let Ct=A.deriveContextFor("runtime-probe","runtime-probe");pt("t_boot",{by:"game-host",stage:"pre-init",engineMode:r}),pt("t_plugins_ready",{initialized:M.initialized.length,ok:M.ok});let Gs=u(A.context,{bundle:A,plugins:h,getRealAudioCtx:()=>w});T=l(Gs),await T.init({ctx:A.context,mainContext:D,canvas:st(),seed:s}),rt=T&&typeof T._forensicsView=="function"?T._forensicsView():null,pt("t_game_init",{hasForensics:!!rt}),ut(),pt("t_first_paint",{frame:A.frameCount()});try{P.init(Ct)}catch(ue){v.push({type:"probe-init",message:String(ue&&ue.message||ue)})}pt("t_game_start",{mode:o,engineMode:r}),Mt(),d(sn,{bundle:A,game:T,probe:P,checklist:nt,uncaught:v,pluginSet:ct,initRes:M,getGameForensics:()=>rt,mark:pt,stepOneFrame:ut})}let kt=null;function ut(D){let st=typeof D=="number"?D:Gi;T&&(E+=st*1e3,T.update(st),r==="stub"&&kt&&T.render(kt),Mt())}function Rt(D){for(let st=0;st{}),T&&typeof T._onAudioUnlock=="function"&&T._onAudioUnlock()}let sn={seed:s,mode:o,engineMode:r,protocol:qr,frameCount:()=>A?A.frameCount():0,stepFrames:Rt,startRaf:()=>Yt(),stopRaf:()=>le(),tap(D,st){Te(),A&&(A.inputBridge._emit("pointerdown",{x:D,y:st}),A.inputBridge._emit("pointerup",{x:D,y:st}))},do(D){T&&typeof T._handleAction=="function"&&T._handleAction(D)},state:()=>rt?rt.state():{phase:"booting"}};function on(D){let st=A.inputBridge;function $t(Ct,Gs){let ue=D.getBoundingClientRect();return{x:(Ct-ue.left)/ue.width*a,y:(Gs-ue.top)/ue.height*c}}D.addEventListener("pointerdown",Ct=>{Te(),st._emit("pointerdown",$t(Ct.clientX,Ct.clientY))}),D.addEventListener("pointermove",Ct=>{st._emit("pointermove",$t(Ct.clientX,Ct.clientY))}),D.addEventListener("pointerup",Ct=>{st._emit("pointerup",$t(Ct.clientX,Ct.clientY))}),window.addEventListener("keydown",Ct=>{Te(),st._emit("keydown",{key:Ct.key})}),window.addEventListener("keyup",Ct=>st._emit("keyup",{key:Ct.key}))}let R=0,V=!1,G=0;function K(D){if(!V)return;G===0&&(G=D);let st=(D-G)/1e3;G=D,st>.05&&(st=.05),ut(st),R=window.requestAnimationFrame(K)}function Yt(){r==="stub"&&(V||(V=!0,G=0,R=window.requestAnimationFrame(K)))}function le(){V=!1,R&&window.cancelAnimationFrame(R),R=0}function Hn(D){D.width=a*ze,D.height=c*ze,D.style.width=a+"px",D.style.height=c+"px";let st=D.getContext("2d",{willReadFrequently:!0});return st.setTransform(ze,0,0,ze,0,0),st}async function Xn(){let D=Hn(t);return kt=D,await je(D,()=>t),on(t),o==="evidence"?b(`evidence \u5C31\u7EEA seed=${s} \xB7 \u7528 host \u9A71\u52A8\uFF08stepFrames/tap\uFF09`):(b(`seed=${s} \xB7 \u70B9\u5F00\u59CB\uFF08\u9996\u6B21\u70B9\u51FB\u5F00\u58F0\uFF09`),Yt()),sn}let rn=()=>{},Be=()=>{};function an(){window.__gameHostEngineInitFired=!0}function Di(){rn()}function Ur(){}function Dc(){Be()}function Ic(){}async function Mc(D){await je(D,()=>i.mainCanvas),on(i.mainCanvas),rn=()=>{T&&(E+=Gi*1e3,T.update(Gi))},Be=()=>{if(T){D.save(),D.setTransform(ze,0,0,ze,0,0);try{D.imageSmoothingEnabled=!1}catch{}T.render(D),D.restore()}},i.mainCanvas&&(i.mainCanvas.id="game-engine"),window.__engine={frame(){return i.frame},time(){return i.time},timeReal(){return i.timeReal},paused(){return i.paused},timeScale(){return i.timeScale},snapshot(){return{frame:i.frame,time:i.time,timeReal:i.timeReal,paused:i.paused,timeScale:i.timeScale}}},b(`engine RAF running \xB7 seed=${s} engine=real`)}if(r!=="real")return await Xn();if(!i){let D="real \u901A\u9053\u672A\u6CE8\u5165\u5F15\u64CE\uFF08opts.engine \u7F3A\u5931\uFF09\uFF1A\u8BF7\u7ECF entry \u5305\u88C5\u5C42\u542F\u52A8\uFF08host \u4E0D\u76F4\u63A5 import \u5F15\u64CE\uFF0CQ4/Option C\uFF09";throw b("ENGINE INJECT MISSING: "+D),new Error(D)}i.setGLEnable(!1),i.setShowSplashScreen(!1),i.setDebugWatermark(!1),i.setCanvasClearColor(i.BLACK),i.setCanvasFixedSize(i.vec2(a*ze,c*ze));let ks=document.createElement("div");return ks.id="engine-root",document.body.appendChild(ks),await i.engineInit(an,Di,Ur,Dc,Ic,[],ks).then(()=>Mc(i.mainContext)).catch(D=>{throw window.__gameHostBootError=String(D&&D.message||D),b("ENGINE INIT FAILED: "+window.__gameHostBootError),D}),sn}var Ws=class{constructor(t){let e=t||{},i=typeof e.cellSize=="number"&&e.cellSize>0?e.cellSize:64;this._cellSize=i,this._cells=new Map,this._entries=new Map,this._seq=0}get size(){return this._entries.size}_cellRange(t){let e=this._cellSize,i=Math.floor((t.x-t.hw)/e),s=Math.floor((t.x+t.hw)/e),o=Math.floor((t.y-t.hh)/e),r=Math.floor((t.y+t.hh)/e);return{cx0:i,cy0:o,cx1:s,cy1:r}}insert(t,e){this._entries.has(t)&&this.remove(t);let{cx0:i,cy0:s,cx1:o,cy1:r}=this._cellRange(e),a=[];for(let l=s;l<=r;l++)for(let u=i;u<=o;u++){let h=u+","+l,f=this._cells.get(h);f||(f=new Set,this._cells.set(h,f)),f.add(t),a.push(h)}let c={x:e.x,y:e.y,hw:e.hw,hh:e.hh};this._entries.set(t,{id:t,box:c,seq:this._seq++,cells:a})}remove(t){let e=this._entries.get(t);if(!e)return!1;for(let i of e.cells){let s=this._cells.get(i);s&&(s.delete(t),s.size===0&&this._cells.delete(i))}return this._entries.delete(t),!0}query(t){let{cx0:e,cy0:i,cx1:s,cy1:o}=this._cellRange(t),r=new Set;for(let a=i;a<=o;a++)for(let c=e;c<=s;c++){let l=this._cells.get(c+","+a);if(l)for(let u of l)r.add(u)}return this._collect(r)}queryPoint(t,e){let i=this._cellSize,s=Math.floor(t/i),o=Math.floor(e/i),r=this._cells.get(s+","+o);return r?this._collect(new Set(r)):[]}clear(){this._cells.clear(),this._entries.clear(),this._seq=0}_collect(t){let e=[];for(let i of t){let s=this._entries.get(i);s&&e.push(s)}return e.sort((i,s)=>i.seq-s.seq),e.map(i=>({id:i.id,box:i.box}))}};function ta(n){let t=n||{},e=new Ws({cellSize:t.cellSize}),i=!1;return{name:"collision",version:"1.0.0",dependencies:[],spatial:e,init(o){},dispose(){i||(e.clear(),i=!0)}}}function ea(n){let t=!1;return{name:"physics-lite",version:"1.0.0",dependencies:[],init(i){},dispose(){t||(t=!0)}}}var Hc=["pointerdown","pointermove","pointerup","keydown","keyup"];function Gt(n){return n<0?0:n>1?1:n}var Xc=n=>(n=Gt(n),n*n),Yc=n=>(n=Gt(n),1-(1-n)*(1-n)),$c=n=>(n=Gt(n),n<.5?2*n*n:1-Math.pow(-2*n+2,2)/2),Kc=n=>(n=Gt(n),n*n*n),Qc=n=>{n=Gt(n);let t=1-n;return 1-t*t*t},Zc=n=>(n=Gt(n),n<.5?4*n*n*n:1-Math.pow(-2*n+2,3)/2),sa=2*Math.PI/3,na=2*Math.PI/4.5,tl=n=>(n=Gt(n),n===0?0:n===1?1:-Math.pow(2,10*n-10)*Math.sin((n*10-10.75)*sa)),el=n=>(n=Gt(n),n===0?0:n===1?1:Math.pow(2,-10*n)*Math.sin((n*10-.75)*sa)+1),nl=n=>(n=Gt(n),n===0?0:n===1?1:n<.5?-(Math.pow(2,20*n-10)*Math.sin((20*n-11.125)*na))/2:Math.pow(2,-20*n+10)*Math.sin((20*n-11.125)*na)/2+1),ji=1.70158,Fi=ji*1.525,oa=ji+1,il=n=>(n=Gt(n),oa*n*n*n-ji*n*n),sl=n=>{n=Gt(n);let t=n-1;return 1+oa*t*t*t+ji*t*t},ol=n=>(n=Gt(n),n<.5?Math.pow(2*n,2)*((Fi+1)*2*n-Fi)/2:(Math.pow(2*n-2,2)*((Fi+1)*(n*2-2)+Fi)+2)/2),rl=n=>Gt(n),ia=Object.freeze({linear:rl,quadIn:Xc,quadOut:Yc,quadInOut:$c,cubicIn:Kc,cubicOut:Qc,cubicInOut:Zc,elasticIn:tl,elasticOut:el,elasticInOut:nl,backIn:il,backOut:sl,backInOut:ol});var al=["linear","quadIn","quadOut","quadInOut","cubicIn","cubicOut","cubicInOut","elasticIn","elasticOut","elasticInOut","backIn","backOut","backInOut"];function cl(n){let t=n&&n.easing;if(!t)return ia;let e=s=>typeof t[s]=="function"?o=>t[s](Gt(o)):ia[s],i={};for(let s of al)i[s]=e(s);return Object.freeze(i)}var qs=class{constructor(t,e,i){let s=i||{};this._time=e,this._windowMs=typeof s.windowMs=="number"&&s.windowMs>0?s.windowMs:120;let o=Array.isArray(s.types)&&s.types.length>0?s.types:Hc;this._records=new Map,this._subs=[],this._disposed=!1;for(let r of o){this._records.set(r,null);let a=t.on(r,c=>{this._records.set(r,c.tMs)});this._subs.push(a)}}consume(t,e){let i=typeof e=="number"?e:this._time.nowMs(),s=this._records.get(t);return s==null?!1:i-s<=this._windowMs?(this._records.set(t,null),!0):(this._records.set(t,null),!1)}peek(t,e){let i=typeof e=="number"?e:this._time.nowMs(),s=this._records.get(t);return s==null?!1:i-s<=this._windowMs}clear(){for(let t of this._records.keys())this._records.set(t,null)}dispose(){if(!this._disposed){for(let t of this._subs)try{t.cancel()}catch(e){}this._subs=[],this._disposed=!0}}};function ra(n){let t=n||{},e=null,i=null,s=!1;return{name:"gamefeel",version:"1.0.0",dependencies:[],get inputBuffer(){return e},get easing(){return cl(i)},init(r){let a=r.getInput();e=new qs(a,r.time,{windowMs:t.inputBufferMs,types:t.inputTypes});let c=r.getEngine();i=c?c.math:null},dispose(){s||(e&&(e.dispose(),e=null),i=null,s=!0)}}}function Bi(n,t){let e=t<0?0:t>1?1:t;switch(n&&n.kind){case"constant":return n.value;case"linear":return n.from+(n.to-n.from)*e;case"easeInOut":{let i=e*e*(3-2*e);return n.from+(n.to-n.from)*i}case"decay":{let i=n.power==null?2:n.power,s=Math.pow(1-e,i);return n.to+(n.from-n.to)*s}default:return 0}}var ll=Object.freeze({burst:Object.freeze({mode:"burst",count:24,angle:0,spread:Math.PI,speedMin:80,speedMax:160,lifeMin:.4,lifeMax:.8,gravity:0,drag:0,sizeCurve:{kind:"decay",from:6,to:0,power:1.5},alphaCurve:{kind:"linear",from:1,to:0}}),trail:Object.freeze({mode:"continuous",rate:60,angle:Math.PI,spread:.25,speedMin:20,speedMax:50,lifeMin:.2,lifeMax:.5,gravity:0,drag:1.5,sizeCurve:{kind:"easeInOut",from:4,to:0},alphaCurve:{kind:"decay",from:.8,to:0,power:2}}),drift:Object.freeze({mode:"continuous",rate:12,angle:Math.PI/2,spread:.6,speedMin:10,speedMax:30,lifeMin:1.5,lifeMax:3,gravity:8,drag:.5,sizeCurve:{kind:"constant",value:3},alphaCurve:{kind:"decay",from:.7,to:0,power:1}})});function ul(n){let t=ll[n];return t?Hs(t):null}function Hs(n){let t={};for(let e of Object.keys(n)){let i=n[e];t[e]=i&&typeof i=="object"?Hs(i):i}return t}function hl(n,t,e){let i=n.mode==="continuous";return{pos:{x:t,y:e},angle:n.angle,coneAngle:n.spread,emitSize:0,emitTime:i?0:1/60,emitRate:i?n.rate||0:void 0,count:i?void 0:n.count||0,particleTime:(n.lifeMin+n.lifeMax)/2,speed:(n.speedMin+n.speedMax)/2,gravityScale:n.gravity||0,damping:n.drag!=null?1-n.drag/60:1,sizeStart:Bi(n.sizeCurve,0),sizeEnd:Bi(n.sizeCurve,1),colorStart:{r:1,g:1,b:1,a:Bi(n.alphaCurve,0)},colorEnd:{r:1,g:1,b:1,a:Bi(n.alphaCurve,1)},additive:!1}}function aa(n){let t=n||{},e=null,i=null,s=null,o=new Map,r=0,a={isActive(){return!1},stop(){}},c=0,l=1,u=0,h=0,f=0,d={x:0,y:0,remain:0,dur:0,amplitude:0,frequency:0,_phase:0},g={alpha:0,remain:0,dur:0,peak:0},b={scale:1,remain:0,dur:0,amplitude:0,frequency:0},v=!1;function w(A){if(u>0)if(u-=A,u<=0)u=0,l=1;else{let T=h>0?1-u/h:1;l=f+(1-f)*T}if(d.remain>0)if(d.remain-=A,d.remain<=0)d.remain=0,d.x=0,d.y=0;else{let T=d.remain/d.dur,P=d.amplitude*T;d._phase+=d.frequency*A*Math.PI*2,d.x=Math.sin(d._phase)*P,d.y=Math.cos(d._phase*1.3)*P}if(g.remain>0&&(g.remain-=A,g.remain<=0?(g.remain=0,g.alpha=0):g.alpha=g.peak*(g.remain/g.dur)),b.remain>0)if(b.remain-=A,b.remain<=0)b.remain=0,b.scale=1;else{let T=b.remain/b.dur,P=(1-T)*b.frequency*Math.PI*2;b.scale=1+Math.sin(P)*b.amplitude*T}}function _(A){c+=1,w(A)}function S(A){let T=A!==void 0?A:e?e.getContext2d():null;if(T&&g.alpha>0){T.globalAlpha=g.alpha,T.fillStyle="#ffffff";let P=T.canvas?T.canvas.width:0,M=T.canvas?T.canvas.height:0;T.fillRect(0,0,P,M),T.globalAlpha=1}}return{name:"particles-juice",version:"1.0.0",dependencies:[],init(A){var T;e=A,s=((T=A.getEngine())==null?void 0:T.particles)||null,typeof t.seed=="number"&&A.random.reseed(t.seed),t.autoStep!==!1&&(i=A.onFrame(P=>{_(P)}))},dispose(){v||(i&&(i.cancel(),i=null),o.forEach(A=>{try{A.stop()}catch{}}),o.clear(),l=1,u=0,d.remain=0,d.x=0,d.y=0,g.remain=0,g.alpha=0,b.remain=0,b.scale=1,v=!0)},spawnEmitter(A,T,P,M){let ct=typeof A=="string"?ul(A):Hs(A);if(!ct)return-1;M&&(ct=Object.assign(ct,M));let nt=r++;if(!s)return o.set(nt,a),nt;let rt=s.spawnEmitter(hl(ct,T,P));return o.set(nt,rt),nt},stopEmitter(A){let T=o.get(A);if(T)try{T.stop()}catch{}},step(A){_(A)},render(A){S(A)},particleCount(){return 0},emitterCount(){let A=0;for(let T of o.values())T.isActive()&&(A+=1);return A},hitStop(A,T){h=Math.max(0,A),u=h,f=T==null?0:Math.max(0,Math.min(1,T)),l=h>0?f:1},getTimeScale(){return l},shakeScreen(A,T,P){d.dur=Math.max(0,A),d.remain=d.dur,d.amplitude=Math.max(0,T),d.frequency=P==null?30:P,d._phase=0,d.x=0,d.y=0},getShakeOffset(){return{x:d.x,y:d.y}},flashScreen(A,T){g.dur=Math.max(0,A),g.remain=g.dur,g.peak=T==null?.8:Math.max(0,Math.min(1,T)),g.alpha=g.dur>0?g.peak:0},getFlashAlpha(){return g.alpha},pulseScale(A,T,P){b.dur=Math.max(0,A),b.remain=b.dur,b.amplitude=T==null?.2:T,b.frequency=P==null?4:P,b.scale=1},getPulseScale(){return b.scale},juiceSnapshot(){return{timeScale:l,shake:{x:d.x,y:d.y},flashAlpha:g.alpha,pulseScale:b.scale}},probe(){return{particles:0,emitters:o.size,dropped:0,steps:c,disposed:v}}}}function ca(n){let t=ft(n.r)/255,e=ft(n.g)/255,i=ft(n.b)/255,s=Math.max(t,e,i),o=Math.min(t,e,i),r=(s+o)/2,a=0,c=0,l=s-o;return l>1e-12&&(c=r>.5?l/(2-s-o):l/(s+o),s===t?a=(e-i)/l%6:s===e?a=(i-t)/l+2:a=(t-e)/l+4,a*=60,a<0&&(a+=360)),{h:a,s:c,l:r}}function la(n){let t=(n.h%360+360)%360,e=Je(n.s),i=Je(n.l);if(e<1e-12){let a=Math.round(i*255);return{r:a,g:a,b:a}}let s=i<.5?i*(1+e):i+e-i*e,o=2*i-s,r=t/360;return{r:Math.round(Xs(o,s,r+1/3)*255),g:Math.round(Xs(o,s,r)*255),b:Math.round(Xs(o,s,r-1/3)*255)}}function Xs(n,t,e){let i=e;return i<0&&(i+=1),i>1&&(i-=1),i<1/6?n+(t-n)*6*i:i<1/2?t:i<2/3?n+(t-n)*(2/3-i)*6:n}function ft(n){return n<0?0:n>255?255:n}function Je(n){return n<0?0:n>1?1:n}function dl(n,t){let e=pl(n.from,t);if(e>=0&&e({r:ft(a.r),g:ft(a.g),b:ft(a.b)})),to:o}}function Ys(n,t,e){return n+(t-n)*e}function ml(n,t){let e=ca(n),i=e.h+(t.hue||0),s=Je(e.s*(t.sat==null?1:t.sat)),o=Je(e.l*(t.light==null?1:t.light));return la({h:i,s,l:o})}var bl=Object.freeze([Object.freeze([0,8,2,10]),Object.freeze([12,4,14,6]),Object.freeze([3,11,1,9]),Object.freeze([15,7,13,5])]);function ua(n){let t=n||{},e=null,i=!1,s={vignette:{enabled:$s(t.vignette&&t.vignette.enabled,!1),strength:Ks(t.vignette&&t.vignette.strength,.5)},dither:{enabled:$s(t.dither&&t.dither.enabled,!1),strength:Ks(t.dither&&t.dither.strength,.5)},scanline:{enabled:$s(t.scanline&&t.scanline.enabled,!1),strength:Ks(t.scanline&&t.scanline.strength,.5)}};function o(a){let c=a!==void 0?a:e?e.getContext2d():null;if(!c)return;let l=c.canvas?c.canvas.width:0,u=c.canvas?c.canvas.height:0;if(s.vignette.enabled&&s.vignette.strength>0&&l>0&&u>0){let h=c.createRadialGradient(l/2,u/2,Math.min(l,u)*.25,l/2,u/2,Math.max(l,u)*.75);h.addColorStop(0,"rgba(0,0,0,0)"),h.addColorStop(1,"rgba(0,0,0,"+s.vignette.strength.toFixed(3)+")"),c.fillStyle=h,c.fillRect(0,0,l,u)}if(s.scanline.enabled&&s.scanline.strength>0&&l>0&&u>0){c.fillStyle="rgba(0,0,0,"+(s.scanline.strength*.5).toFixed(3)+")";for(let h=0;h0&&l>0&&u>0&&typeof c.getImageData=="function"&&typeof c.putImageData=="function"){let h=c.getImageData(0,0,l,u);xl(h,s.dither.strength),c.putImageData(h,0,0)}}return{name:"palette-post",version:"1.0.0",dependencies:[],init(a){e=a},dispose(){i||(e=null,i=!0)},applyPaletteMap(a,c){return dl(a,c)},applyPaletteMapToBuffer(a,c){return fl(a,c)},lerpPaletteMap(a,c,l){return gl(a,c,l)},shiftHsl(a,c){return ml(a,c)},rgbToHsl(a){return ca(a)},hslToRgb(a){return la(a)},setPost(a){if(a)for(let c of["vignette","dither","scanline"])a[c]&&(typeof a[c].enabled=="boolean"&&(s[c].enabled=a[c].enabled),typeof a[c].strength=="number"&&(s[c].strength=Je(a[c].strength)))},getPost(){return{vignette:{enabled:s.vignette.enabled,strength:s.vignette.strength},dither:{enabled:s.dither.enabled,strength:s.dither.strength},scanline:{enabled:s.scanline.enabled,strength:s.scanline.strength}}},renderPost(a){o(a)},probe(){return{disposed:i,post:this.getPost()}}}}function xl(n,t){let e=Je(t);if(e<=0)return n;let{data:i,width:s}=n,r=255/(Math.max(2,Math.round(16-e*14))-1);for(let a=0;a+3>2)%s,l=Math.floor((a>>2)/s),u=(bl[l&3][c&3]/16-.5)*r;for(let h=0;h<3;h++){let f=i[a+h]+u,d=Math.round(f/r)*r;i[a+h]=d<0?0:d>255?255:d}}return n}function $s(n,t){return typeof n=="boolean"?n:t}function Ks(n,t){return typeof n=="number"?Je(n):t}var Zs=Object.freeze({blip:Object.freeze({name:"blip",params:Object.freeze([.6,0,880,0,.03,.06,1,1.5])}),thud:Object.freeze({name:"thud",params:Object.freeze([.8,0,90,0,.04,.18,0,1,0,0,0,0,0,4])}),chime:Object.freeze({name:"chime",params:Object.freeze([.5,0,660,.02,.12,.3,1,2])})}),ha=Object.keys(Zs);function vl(n){let t=[];return n==null||typeof n!="object"?{ok:!1,errors:["song \u5FC5\u987B\u662F\u5BF9\u8C61"]}:(!Array.isArray(n.instruments)||n.instruments.length===0?t.push("instruments \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4"):n.instruments.forEach((e,i)=>{(!Array.isArray(e)||e.some(s=>typeof s!="number"||!Number.isFinite(s)))&&t.push(`instruments[${i}] \u5FC5\u987B\u662F\u6709\u9650\u6570\u5B57\u6570\u7EC4\uFF08ZzFX \u53C2\u6570\u5305\uFF09`)}),!Array.isArray(n.patterns)||n.patterns.length===0?t.push("patterns \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4"):n.patterns.forEach((e,i)=>{if(!Array.isArray(e)||e.length===0){t.push(`patterns[${i}] \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4\uFF08\u81F3\u5C11\u4E00\u4E2A\u58F0\u90E8\u901A\u9053\uFF09`);return}e.forEach((s,o)=>{if(!Array.isArray(s)||s.length<2){t.push(`patterns[${i}][${o}] \u901A\u9053\u81F3\u5C11\u542B [\u4E50\u5668\u7D22\u5F15, \u58F0\u50CF]`);return}if(s.some(c=>typeof c!="number"||!Number.isFinite(c))){t.push(`patterns[${i}][${o}] \u901A\u9053\u5FC5\u987B\u5168\u4E3A\u6709\u9650\u6570\u5B57`);return}let r=s[0]|0;Array.isArray(n.instruments)&&(r<0||r>=n.instruments.length)&&t.push(`patterns[${i}][${o}] \u4E50\u5668\u7D22\u5F15 ${r} \u8D8A\u754C\uFF08instruments \u957F\u5EA6 ${n.instruments.length}\uFF09`);let a=s[1];(a<-1||a>1)&&t.push(`patterns[${i}][${o}] \u58F0\u50CF ${a} \u8D8A\u754C\uFF08\u5E94 -1..+1\uFF09`)})}),!Array.isArray(n.sequence)||n.sequence.length===0?t.push("sequence \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4"):n.sequence.forEach((e,i)=>{if(typeof e!="number"||!Number.isInteger(e)){t.push(`sequence[${i}] \u5FC5\u987B\u662F\u6574\u6570 pattern \u7D22\u5F15`);return}Array.isArray(n.patterns)&&(e<0||e>=n.patterns.length)&&t.push(`sequence[${i}] \u7D22\u5F15 ${e} \u8D8A\u754C\uFF08patterns \u957F\u5EA6 ${n.patterns.length}\uFF09`)}),n.bpm!=null&&(typeof n.bpm!="number"||!(n.bpm>0))&&t.push("bpm \u5FC5\u987B\u662F\u6B63\u6570"),{ok:t.length===0,errors:t})}function he(n){return typeof n!="number"||Number.isNaN(n)||n<0?0:n>1?1:n}function Sl(n,t){switch(n){case"ease-in":return t*t;case"ease-out":return Math.sqrt(t);case"constant":return 1;default:return t}}function da(n,t){let e=he(t);return n==null||!Array.isArray(n.voices)?[]:n.voices.map(i=>{let s=String(i&&i.id!=null?i.id:""),o=Array.isArray(i&&i.channelIndices)?i.channelIndices.slice():[],r=typeof i.minIntensity=="number"?he(i.minIntensity):0,a=typeof i.maxIntensity=="number"?he(i.maxIntensity):1,c=typeof i.volumeCurve=="string"?i.volumeCurve:"linear",l=typeof i.baseVolume=="number"?he(i.baseVolume):1;if(ea)return{id:s,on:!1,volume:0,channelIndices:o};let u=a-r,h=u<=0?1:(e-r)/u,f=he(Sl(c,h)*l);return{id:s,on:!0,volume:f,channelIndices:o}})}function fa(n,t,e,i){try{let s=t[0]||[],o=t[1]||s,r=Math.max(s.length,o.length);if(r===0)return null;let c=n.createBuffer(2,r,44100);c.getChannelData(0).set(s),c.getChannelData(1).set(o.length?o:s);let l=n.createBufferSource();l.buffer=c,l.loop=!!i;let u=n.createGain();return u.gain.value=he(e*.3),l.connect(u),u.connect(n.destination),l.start(),{stop(){try{l.stop()}catch(h){}try{l.disconnect(),u.disconnect()}catch(h){}}}}catch(s){return to("[audio-music] \u53D7\u63A7\u97F3\u9891\u64AD\u653E\u5F02\u5E38\uFF0C\u964D\u7EA7\u4E3A\u9759\u9ED8",s),null}}function pa(n){let t=n||{},e=typeof t.masterVolume=="number"?he(t.masterVolume):1,i=()=>null,s=null,o=null,r={voices:[]},a=1,c=null,l=!1,u=0,h=!1,f=!1;function d(){let S=i();return S==null?(u+=1,h||(Qs("[audio-music] \u65E0\u53D7\u63A7\u97F3\u9891\u4E0A\u4E0B\u6587\uFF08getAudioContext \u8FD4\u56DE null\uFF09\uFF0C\u5168\u90E8\u53D1\u58F0\u9759\u9ED8 no-op\uFF08\u8BC4\u4F30\u73AF\u5883\u65E0\u58F0\u5361\u65F6\u7684\u5BB9\u9519\u964D\u7EA7\uFF09"),h=!0),null):S}function g(){if(!o||!s)return null;try{let S=typeof o.bpm=="number"&&o.bpm>0?o.bpm:125;return s.synthSong(o.instruments,o.patterns,o.sequence,S)}catch(S){return to("[audio-music] \u66F2\u8C31\u6E32\u67D3\u5F02\u5E38\uFF0C\u964D\u7EA7\u4E3A\u9759\u9ED8",S),null}}function b(){let S=da(r,a);if(S.length===0)return 1;let E=0;for(let A of S)A.on&&(E=Math.max(E,A.volume));return E}function v(S,E){typeof E=="number"&&(a=he(E));let A=d();if(A==null||!o)return;w();let T=g();if(!T)return;let P=he(e*b());c=fa(A,T,P,S),l=!!S&&c!=null}function w(){c&&(c.stop(),c=null),l=!1}return{name:"audio-music",version:"1.0.0",dependencies:[],init(S){i=()=>S.getAudioContext();let E=S.getEngine&&S.getEngine();s=E?E.audio.synth:null},dispose(){f||(w(),f=!0)},loadSong(S){let E=vl(S);return E.ok?o={instruments:S.instruments,patterns:S.patterns,sequence:S.sequence,bpm:typeof S.bpm=="number"?S.bpm:125}:Qs("[audio-music] \u66F2\u8C31\u6821\u9A8C\u5931\u8D25\uFF0C\u672A\u8F7D\u5165\uFF1A"+E.errors.join("\uFF1B")),E},play(S){v(!1,S)},stop(){w()},loop(S){v(!0,S)},setIntensityLayering(S){r=S&&Array.isArray(S.voices)?{voices:S.voices}:{voices:[]}},setIntensity(S){a=he(S)},resolveVoices(S){return da(r,S)},playSfx(S){let E=Zs[S];if(!E){Qs("[audio-music] \u672A\u77E5\u97F3\u6548\u9884\u8BBE\uFF1A"+String(S));return}let A=d();if(A!=null)try{let T=s?s.synthSfx(E.params):null;if(!T)return;fa(A,[T,T],e,!1)}catch(T){to("[audio-music] \u97F3\u6548\u64AD\u653E\u5F02\u5E38\uFF0C\u964D\u7EA7\u4E3A\u9759\u9ED8 name="+S,T)}},getPreset(S){return Zs[S]},listPresets(){return ha.slice()},probe(){return{hasAudio:i()!=null,hasSong:o!=null,intensity:a,voiceCount:r.voices.length,looping:l,silentNoops:u,presetCount:ha.length}}}}function to(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function Qs(n){typeof console!="undefined"&&typeof console.warn=="function"&&console.warn(n)}var wl="zaomeng.save";function Tl(n){if(typeof TextEncoder!="undefined")return new TextEncoder().encode(n).length;if(typeof Buffer!="undefined"&&typeof Buffer.byteLength=="function")return Buffer.byteLength(n,"utf8");let t=0;for(let e=0;e=55296&&i<=56319?(t+=4,e++):t+=3}return t}function no(){let n=new Map;return{getItem(t){return n.has(t)?n.get(t):null},setItem(t,e){n.set(t,e)},removeItem(t){n.delete(t)},keys(){return Array.from(n.keys())}}}function ya(){if(typeof localStorage=="undefined")throw new Error("[save-progress] createLocalStorageAdapter \u9700\u8981\u5168\u5C40 localStorage\uFF08\u4EC5\u6D4F\u89C8\u5668\u96C6\u6210\u6BB5\u53EF\u7528\uFF09\u3002node/host-dev \u8BF7\u7528\u7F3A\u7701\u5185\u5B58 adapter \u6216 createMemoryAdapter()\u3002");return{getItem(n){return localStorage.getItem(n)},setItem(n,t){localStorage.setItem(n,t)},removeItem(n){localStorage.removeItem(n)},keys(){let n=[];for(let t=0;t0?t.namespace:wl;if(e.indexOf(":")>=0)throw new Error('[save-progress] namespace \u4E0D\u5F97\u542B\u5206\u9694\u7B26 ":"\uFF08\u5F53\u524D="'+e+'"\uFF09');let i=typeof t.maxValueBytes=="number"&&t.maxValueBytes>0?Math.floor(t.maxValueBytes):32768,s=!Al(t.adapter),o=s?no():t.adapter,r=e+":",a=0,c=0,l=!1;function u(d){return typeof d!="string"||d.length===0?r+String(d):r+d}function h(){try{let d=o.keys();return Array.isArray(d)?d.filter(g=>typeof g=="string"&&g.indexOf(r)===0):[]}catch(d){return Yn("[save-progress] adapter.keys() \u5F02\u5E38\uFF0C\u964D\u7EA7\u8FD4\u56DE\u7A7A\u96C6",d),[]}}return{name:"save-progress",version:"1.0.0",dependencies:[],init(d){h()},dispose(){},get(d,g){if(!eo(d))return g;let b;try{b=o.getItem(u(d))}catch(v){return Yn("[save-progress] adapter.getItem \u5F02\u5E38\uFF0C\u8FD4\u56DE\u9ED8\u8BA4\u503C key="+d,v),g}if(b==null)return g;try{return JSON.parse(b)}catch{return a+=1,l||($n("[save-progress] \u68C0\u6D4B\u5230\u635F\u574F\u5B58\u6863\uFF08\u975E\u6CD5 JSON\uFF09\uFF0C\u5DF2\u5BB9\u9519\u56DE\u9000\u9ED8\u8BA4\u503C key="+d),l=!0),g}},set(d,g){if(!eo(d))return $n("[save-progress] set \u6536\u5230\u975E\u6CD5 key\uFF0C\u62D2\u7EDD\u5199\u5165\uFF1A"+String(d)),!1;let b;try{b=JSON.stringify(g)}catch{return c+=1,$n("[save-progress] \u503C\u4E0D\u53EF JSON \u5E8F\u5217\u5316\uFF08\u5FAA\u73AF\u5F15\u7528?\uFF09\uFF0C\u62D2\u7EDD\u5199\u5165 key="+d),!1}if(b===void 0)return c+=1,$n("[save-progress] \u503C\u5E8F\u5217\u5316\u4E3A undefined\uFF08\u5982\u7EAF undefined/\u51FD\u6570\uFF09\uFF0C\u62D2\u7EDD\u5199\u5165 key="+d),!1;let v=Tl(b);if(v>i)return c+=1,$n("[save-progress] \u503C\u8D85\u5B57\u8282\u4E0A\u9650\u62D2\u7EDD\u5199\u5165 key="+d+"\uFF08"+v+" > "+i+" bytes\uFF09"),!1;try{return o.setItem(u(d),b),!0}catch(w){return c+=1,Yn("[save-progress] adapter.setItem \u5F02\u5E38\uFF0C\u5199\u5165\u5931\u8D25 key="+d,w),!1}},remove(d){if(eo(d))try{o.removeItem(u(d))}catch(g){Yn("[save-progress] adapter.removeItem \u5F02\u5E38\uFF08\u5DF2\u5FFD\u7565\uFF09key="+d,g)}},clear(){let d=h(),g=0;for(let b of d)try{o.removeItem(b),g+=1}catch(v){Yn("[save-progress] clear \u65F6 removeItem \u5F02\u5E38\uFF08\u5DF2\u8DF3\u8FC7\uFF09fullKey="+b,v)}return g},probe(){return{namespace:e,maxValueBytes:i,usingMemoryAdapter:s,size:h().length,corruptRecoveries:a,rejectedWrites:c}}}}function eo(n){return typeof n=="string"&&n.length>0}function Al(n){return!!n&&typeof n.getItem=="function"&&typeof n.setItem=="function"&&typeof n.removeItem=="function"&&typeof n.keys=="function"}function Yn(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function $n(n){typeof console!="undefined"&&typeof console.warn=="function"&&console.warn(n)}var Cl={w:390,h:844};function ma(n){let t=((n&&n.seed)!=null?n.seed:0)>>>0,e=ta({cellSize:96}),i=ea(),s=ra({inputBufferMs:260,inputTypes:["pointerdown"]}),o=aa({seed:t,maxParticles:600}),r=ua({vignette:{enabled:!0,strength:.22}}),a=pa({masterVolume:.8}),c;try{c=ya()}catch(f){console.warn("[generic] localStorage \u4E0D\u53EF\u7528\uFF0C\u5B58\u6863\u9000\u5185\u5B58 adapter\uFF1A"+(f&&f.message)),c=no()}let l=ga({namespace:"zaomeng-generic",adapter:c});return{plugins:{collision:e,physics:i,gamefeel:s,juice:o,palettePost:r,audioMusic:a,save:l},registerOrder:[e,i,s,o,r,l,a],viewport:Cl,buildFactoryOpts:(f,d)=>({runtime:{plugins:d.plugins,bundle:d.bundle,getRealAudioCtx:d.getRealAudioCtx}})}}function Kn(n){let t=n||{},e=null,i=null,s=null,o=null,r="booting",a=0,c=5,l=[],u=[],h=null,f=!1,d={x:0,y:0},g={x:0,y:0},b={x:80,y:600},v=null,w=null,_=null,S=1200,E=8,A=10,T=15;function P(R,V,G,K){let Yt=R-G,le=V-K;return Math.hypot(Yt,le)}function M(R,V,G,K,Yt,le,Hn){let Xn=Math.max(K,Math.min(R,K+le)),rn=Math.max(Yt,Math.min(V,Yt+Hn)),Be=R-Xn,an=V-rn;return Be*Be+an*an=0;V--){let G=u[V];if(M(h.x,h.y,A,G.x,G.y,G.w,G.h)){ct(G.x+G.w/2,G.y+G.h/2,18,{r:.9,g:.7,b:.3,a:1}),nt(),u.splice(V,1);break}}for(let V=l.length-1;V>=0;V--){let G=l[V];if(P(h.x,h.y,G.x,G.y)410||h.y>860){if(h.active=!1,c--,l.length===0){rt("win");return}c>0?(h.x=b.x,h.y=b.y,h.vx=0,h.vy=0,h.active=!1):rt("lose")}l.length===0&&h.active&&rt("win")}}function Te(R){R.fillStyle="#1a1a2e",R.fillRect(0,0,390,844),R.strokeStyle="#8B4513",R.lineWidth=4,R.beginPath(),R.moveTo(b.x-10,b.y-20),R.lineTo(b.x,b.y),R.lineTo(b.x+10,b.y-20),R.stroke(),f&&(R.strokeStyle="rgba(255,255,255,0.5)",R.lineWidth=2,R.setLineDash([4,4]),R.beginPath(),R.moveTo(b.x,b.y),R.lineTo(g.x,g.y),R.stroke(),R.setLineDash([])),R.fillStyle="#a0522d";for(let K of u)R.fillRect(K.x,K.y,K.w,K.h);R.fillStyle="#32cd32";for(let K of l)R.beginPath(),R.arc(K.x,K.y,T,0,Math.PI*2),R.fill(),R.fillStyle="#000",R.beginPath(),R.arc(K.x-4,K.y-4,3,0,Math.PI*2),R.fill(),R.beginPath(),R.arc(K.x+4,K.y-4,3,0,Math.PI*2),R.fill(),R.fillStyle="#32cd32";h&&!h.active&&c>0&&(R.fillStyle="#ff4444",R.beginPath(),R.arc(b.x,b.y,A,0,Math.PI*2),R.fill(),R.fillStyle="#fff",R.beginPath(),R.arc(b.x-3,b.y-3,3,0,Math.PI*2),R.fill(),R.beginPath(),R.arc(b.x+3,b.y-3,3,0,Math.PI*2),R.fill()),h&&h.active&&(R.fillStyle="#ff4444",R.beginPath(),R.arc(h.x,h.y,A,0,Math.PI*2),R.fill(),R.fillStyle="#fff",R.beginPath(),R.arc(h.x-3,h.y-3,3,0,Math.PI*2),R.fill(),R.beginPath(),R.arc(h.x+3,h.y-3,3,0,Math.PI*2),R.fill()),R.fillStyle="#222",R.fillRect(0,0,390,40);let V=r==="gameover"?"GAME OVER":"PLAYING",G=c+(c===1?" bird":" birds");if(R.fillStyle="#fff",R.font="16px monospace",R.fillText("Score: "+a,10,26),R.fillText(G+" left",200,26),R.fillText(V,300,26),r==="gameover"){let K=l.length===0?"YOU WIN!":"YOU LOSE!";R.fillStyle="rgba(0,0,0,0.6)",R.fillRect(0,200,390,100),R.fillStyle="#ffcc00",R.font="bold 32px monospace",R.textAlign="center",R.fillText(K,195,260),R.fillStyle="#aaa",R.font="16px monospace",R.fillText("Tap to restart",195,290),R.textAlign="left"}}function sn(){try{v&&v.cancel()}catch{}try{w&&w.cancel()}catch{}try{_&&_.cancel()}catch{}v=w=_=null,u=[],l=[],h=null,f=!1,r="destroyed"}function on(){return{seed:o,state:()=>({phase:r,result:r==="gameover"?l.length===0?"win":"lose":null,score:a,birdsLeft:c,targets:l.map(R=>({x:R.x,y:R.y})),launch:{gravity:S,powerScale:E}})}}return{init:ut,update:Rt,render:Te,destroy:sn,_forensicsView:on}}var pd=Kn,yd=Kn;async function gd(n){let t=n||{},e=t.engine||await Promise.resolve().then(()=>(Oc(),Lc)),i=(t.seed!=null?t.seed:305441741)>>>0,s=ma({seed:i});return Zr({canvas:t.canvas,statusEl:t.statusEl||null,engine:e,seed:i,mode:t.mode||"play",engineMode:"real",viewport:s.viewport,factory:Kn,plugins:s.plugins,registerOrder:s.registerOrder,buildFactoryOpts:s.buildFactoryOpts,recHook:t.recHook||null,onReady:t.onReady||null})}return Nc(md);})();
diff --git a/game-runtime/games/_wg1-gen/angrybirds/bundle.iife.js.meta.json b/game-runtime/games/_wg1-gen/angrybirds/bundle.iife.js.meta.json
index 300d1b03..1d3be4dc 100644
--- a/game-runtime/games/_wg1-gen/angrybirds/bundle.iife.js.meta.json
+++ b/game-runtime/games/_wg1-gen/angrybirds/bundle.iife.js.meta.json
@@ -1 +1 @@
-{"inputs":{"src/core/plugin.js":{"bytes":44317,"imports":[],"format":"esm"},"src/plugins/runtime-probe/impl.js":{"bytes":16639,"imports":[],"format":"esm"},"host-dev/engine-caps.js":{"bytes":13897,"imports":[],"format":"esm"},"host-dev/engine-math.js":{"bytes":6155,"imports":[],"format":"esm"},"src/host/boot-game-host.js":{"bytes":27676,"imports":[{"path":"src/core/plugin.js","kind":"import-statement","original":"../core/plugin.js"},{"path":"src/plugins/runtime-probe/impl.js","kind":"import-statement","original":"../plugins/runtime-probe/impl.js"},{"path":"host-dev/engine-caps.js","kind":"import-statement","original":"../../host-dev/engine-caps.js"},{"path":"host-dev/engine-math.js","kind":"import-statement","original":"../../host-dev/engine-math.js"}],"format":"esm"},"src/plugins/collision/impl.js":{"bytes":24812,"imports":[],"format":"esm"},"src/plugins/physics-lite/impl.js":{"bytes":14507,"imports":[],"format":"esm"},"src/plugins/gamefeel/impl.js":{"bytes":21715,"imports":[],"format":"esm"},"src/plugins/particles-juice/impl.js":{"bytes":31830,"imports":[],"format":"esm"},"src/plugins/palette-post/impl.js":{"bytes":20240,"imports":[],"format":"esm"},"src/plugins/audio-music/impl.js":{"bytes":24659,"imports":[],"format":"esm"},"src/plugins/save-progress/impl.js":{"bytes":14608,"imports":[],"format":"esm"},"src/host/generic-host-config.js":{"bytes":7803,"imports":[{"path":"src/plugins/collision/impl.js","kind":"import-statement","original":"../plugins/collision/impl.js"},{"path":"src/plugins/physics-lite/impl.js","kind":"import-statement","original":"../plugins/physics-lite/impl.js"},{"path":"src/plugins/gamefeel/impl.js","kind":"import-statement","original":"../plugins/gamefeel/impl.js"},{"path":"src/plugins/particles-juice/impl.js","kind":"import-statement","original":"../plugins/particles-juice/impl.js"},{"path":"src/plugins/palette-post/impl.js","kind":"import-statement","original":"../plugins/palette-post/impl.js"},{"path":"src/plugins/audio-music/impl.js","kind":"import-statement","original":"../plugins/audio-music/impl.js"},{"path":"src/plugins/save-progress/impl.js","kind":"import-statement","original":"../plugins/save-progress/impl.js"}],"format":"esm"},"games/_wg1-gen/angrybirds/generated-factory.js":{"bytes":13827,"imports":[],"format":"esm"},"node_modules/littlejsengine/dist/littlejs.esm.js":{"bytes":640153,"imports":[],"format":"esm"},"games/_wg1-gen/angrybirds/entry-bundle.js":{"bytes":6230,"imports":[{"path":"src/host/boot-game-host.js","kind":"import-statement","original":"../../../src/host/boot-game-host.js"},{"path":"src/host/generic-host-config.js","kind":"import-statement","original":"../../../src/host/generic-host-config.js"},{"path":"games/_wg1-gen/angrybirds/generated-factory.js","kind":"import-statement","original":"./generated-factory.js"},{"path":"node_modules/littlejsengine/dist/littlejs.esm.js","kind":"dynamic-import","original":"littlejsengine"}],"format":"esm"}},"outputs":{"games/_wg1-gen/angrybirds/bundle.iife.js":{"imports":[],"exports":[],"entryPoint":"games/_wg1-gen/angrybirds/entry-bundle.js","inputs":{"node_modules/littlejsengine/dist/littlejs.esm.js":{"bytesInOutput":164190},"games/_wg1-gen/angrybirds/entry-bundle.js":{"bytesInOutput":507},"src/core/plugin.js":{"bytesInOutput":8989},"src/plugins/runtime-probe/impl.js":{"bytesInOutput":2794},"host-dev/engine-caps.js":{"bytesInOutput":1597},"host-dev/engine-math.js":{"bytesInOutput":498},"src/host/boot-game-host.js":{"bytesInOutput":5364},"src/plugins/collision/impl.js":{"bytesInOutput":1605},"src/plugins/physics-lite/impl.js":{"bytesInOutput":115},"src/plugins/gamefeel/impl.js":{"bytesInOutput":2533},"src/plugins/particles-juice/impl.js":{"bytesInOutput":4161},"src/plugins/palette-post/impl.js":{"bytesInOutput":4216},"src/plugins/audio-music/impl.js":{"bytesInOutput":6001},"src/plugins/save-progress/impl.js":{"bytesInOutput":3933},"src/host/generic-host-config.js":{"bytesInOutput":697},"games/_wg1-gen/angrybirds/generated-factory.js":{"bytesInOutput":5752}},"bytes":213523}}}
\ No newline at end of file
+{"inputs":{"src/core/plugin.js":{"bytes":44317,"imports":[],"format":"esm"},"src/plugins/runtime-probe/impl.js":{"bytes":16639,"imports":[],"format":"esm"},"host-dev/engine-caps.js":{"bytes":13897,"imports":[],"format":"esm"},"host-dev/engine-math.js":{"bytes":6155,"imports":[],"format":"esm"},"src/host/boot-game-host.js":{"bytes":28239,"imports":[{"path":"src/core/plugin.js","kind":"import-statement","original":"../core/plugin.js"},{"path":"src/plugins/runtime-probe/impl.js","kind":"import-statement","original":"../plugins/runtime-probe/impl.js"},{"path":"host-dev/engine-caps.js","kind":"import-statement","original":"../../host-dev/engine-caps.js"},{"path":"host-dev/engine-math.js","kind":"import-statement","original":"../../host-dev/engine-math.js"}],"format":"esm"},"src/plugins/collision/impl.js":{"bytes":24812,"imports":[],"format":"esm"},"src/plugins/physics-lite/impl.js":{"bytes":14507,"imports":[],"format":"esm"},"src/plugins/gamefeel/impl.js":{"bytes":21715,"imports":[],"format":"esm"},"src/plugins/particles-juice/impl.js":{"bytes":31830,"imports":[],"format":"esm"},"src/plugins/palette-post/impl.js":{"bytes":20240,"imports":[],"format":"esm"},"src/plugins/audio-music/impl.js":{"bytes":24659,"imports":[],"format":"esm"},"src/plugins/save-progress/impl.js":{"bytes":14608,"imports":[],"format":"esm"},"src/host/generic-host-config.js":{"bytes":7803,"imports":[{"path":"src/plugins/collision/impl.js","kind":"import-statement","original":"../plugins/collision/impl.js"},{"path":"src/plugins/physics-lite/impl.js","kind":"import-statement","original":"../plugins/physics-lite/impl.js"},{"path":"src/plugins/gamefeel/impl.js","kind":"import-statement","original":"../plugins/gamefeel/impl.js"},{"path":"src/plugins/particles-juice/impl.js","kind":"import-statement","original":"../plugins/particles-juice/impl.js"},{"path":"src/plugins/palette-post/impl.js","kind":"import-statement","original":"../plugins/palette-post/impl.js"},{"path":"src/plugins/audio-music/impl.js","kind":"import-statement","original":"../plugins/audio-music/impl.js"},{"path":"src/plugins/save-progress/impl.js","kind":"import-statement","original":"../plugins/save-progress/impl.js"}],"format":"esm"},"games/_wg1-gen/angrybirds/generated-factory.js":{"bytes":10005,"imports":[],"format":"esm"},"node_modules/littlejsengine/dist/littlejs.esm.js":{"bytes":640153,"imports":[],"format":"esm"},"games/_wg1-gen/angrybirds/entry-bundle.js":{"bytes":6230,"imports":[{"path":"src/host/boot-game-host.js","kind":"import-statement","original":"../../../src/host/boot-game-host.js"},{"path":"src/host/generic-host-config.js","kind":"import-statement","original":"../../../src/host/generic-host-config.js"},{"path":"games/_wg1-gen/angrybirds/generated-factory.js","kind":"import-statement","original":"./generated-factory.js"},{"path":"node_modules/littlejsengine/dist/littlejs.esm.js","kind":"dynamic-import","original":"littlejsengine"}],"format":"esm"}},"outputs":{"games/_wg1-gen/angrybirds/bundle.iife.js":{"imports":[],"exports":[],"entryPoint":"games/_wg1-gen/angrybirds/entry-bundle.js","inputs":{"node_modules/littlejsengine/dist/littlejs.esm.js":{"bytesInOutput":164197},"games/_wg1-gen/angrybirds/entry-bundle.js":{"bytesInOutput":507},"src/core/plugin.js":{"bytesInOutput":8989},"src/plugins/runtime-probe/impl.js":{"bytesInOutput":2794},"host-dev/engine-caps.js":{"bytesInOutput":1597},"host-dev/engine-math.js":{"bytesInOutput":498},"src/host/boot-game-host.js":{"bytesInOutput":5500},"src/plugins/collision/impl.js":{"bytesInOutput":1605},"src/plugins/physics-lite/impl.js":{"bytesInOutput":115},"src/plugins/gamefeel/impl.js":{"bytesInOutput":2533},"src/plugins/particles-juice/impl.js":{"bytesInOutput":4166},"src/plugins/palette-post/impl.js":{"bytesInOutput":4216},"src/plugins/audio-music/impl.js":{"bytesInOutput":6001},"src/plugins/save-progress/impl.js":{"bytesInOutput":3933},"src/host/generic-host-config.js":{"bytesInOutput":697},"games/_wg1-gen/angrybirds/generated-factory.js":{"bytesInOutput":4282}},"bytes":212201}}}
\ No newline at end of file
diff --git a/game-runtime/games/_wg1-gen/angrybirds/evidence/after-play.png b/game-runtime/games/_wg1-gen/angrybirds/evidence/after-play.png
index d6a76a75..3dcd4052 100644
Binary files a/game-runtime/games/_wg1-gen/angrybirds/evidence/after-play.png and b/game-runtime/games/_wg1-gen/angrybirds/evidence/after-play.png differ
diff --git a/game-runtime/games/_wg1-gen/angrybirds/evidence/first-paint.png b/game-runtime/games/_wg1-gen/angrybirds/evidence/first-paint.png
index 7cec33af..a6f4e40d 100644
Binary files a/game-runtime/games/_wg1-gen/angrybirds/evidence/first-paint.png and b/game-runtime/games/_wg1-gen/angrybirds/evidence/first-paint.png differ
diff --git a/game-runtime/games/_wg1-gen/angrybirds/evidence/verdict.json b/game-runtime/games/_wg1-gen/angrybirds/evidence/verdict.json
index 6f1d81a0..41cda6ab 100644
--- a/game-runtime/games/_wg1-gen/angrybirds/evidence/verdict.json
+++ b/game-runtime/games/_wg1-gen/angrybirds/evidence/verdict.json
@@ -8,9 +8,9 @@
     },
     "C_frame": {
       "pass": true,
-      "f0": 48,
-      "f1": 78,
-      "delta": 30
+      "f0": 49,
+      "f1": 80,
+      "delta": 31
     },
     "I_control": {
       "pass": true,
@@ -18,13 +18,13 @@
     },
     "D_render": {
       "pass": true,
-      "bright": 34719,
+      "bright": 24407,
       "maxCh": 255
     },
     "E_live": {
       "pass": true,
-      "distinctStates": 10,
-      "samples": 15
+      "distinctStates": 3,
+      "samples": 3
     },
     "B_uncaught": {
       "pass": true,
@@ -32,12 +32,9 @@
     },
     "F_wiring": {
       "pass": true,
-      "callCount": 18,
+      "callCount": 9,
       "sample": [
         "particles.spawnEmitter",
-        "audio.synth.synthSfx",
-        "particles.spawnEmitter",
-        "audio.synth.synthSfx",
         "particles.spawnEmitter",
         "audio.synth.synthSfx",
         "particles.spawnEmitter",
@@ -54,18 +51,21 @@
     },
     "G_input": {
       "pass": true,
-      "skipped": "无 tap/key 输入"
+      "inputHash": "9aa44a5c",
+      "controlHash": "729b6a77",
+      "atFrame": 260,
+      "ctrlFrame": 265
     },
     "H_progress": {
-      "pass": false,
+      "pass": true,
       "checks": [
         {
           "path": "score",
           "op": "increased",
           "before": 0,
-          "after": 0,
-          "pass": false,
-          "why": "盲态固定拖拽发射→偶中目标得分;若固定角度打不中(需读目标算拖拽矢量)则不升=暴露拖拽瞄准缺口"
+          "after": 20,
+          "pass": true,
+          "why": "drag-aiming 读 launch 物理常数(gravity/powerScale)45° 抛解析反解拖拽矢量→命中猪得分上升;游戏暴露物理即可确定性瞄准(asteroids 式『暴露即可测』);若仍 0=物理未按 pin 实现"
         }
       ],
       "latch": {
@@ -78,44 +78,35 @@
         "phase": "playing",
         "result": null,
         "score": 0,
-        "birdsLeft": 4,
+        "birdsLeft": 5,
         "targets": [
           {
-            "x": 290,
-            "y": 560
+            "x": 320,
+            "y": 650
           },
           {
-            "x": 310,
-            "y": 520
-          },
-          {
-            "x": 280,
-            "y": 480
+            "x": 340,
+            "y": 700
           }
-        ]
+        ],
+        "launch": {
+          "gravity": 1200,
+          "powerScale": 8
+        }
       },
       "state1": {
         "phase": "gameover",
-        "result": "lose",
-        "score": 0,
-        "birdsLeft": 0,
-        "targets": [
-          {
-            "x": 290,
-            "y": 560
-          },
-          {
-            "x": 310,
-            "y": 520
-          },
-          {
-            "x": 280,
-            "y": 480
-          }
-        ]
+        "result": "win",
+        "score": 20,
+        "birdsLeft": 5,
+        "targets": [],
+        "launch": {
+          "gravity": 1200,
+          "powerScale": 8
+        }
       }
     }
   },
-  "pass": false,
+  "pass": true,
   "notes": []
 }
\ No newline at end of file
diff --git a/game-runtime/games/_wg1-gen/angrybirds/generated-factory.js b/game-runtime/games/_wg1-gen/angrybirds/generated-factory.js
index 267a6e48..1ea1d576 100644
--- a/game-runtime/games/_wg1-gen/angrybirds/generated-factory.js
+++ b/game-runtime/games/_wg1-gen/angrybirds/generated-factory.js
@@ -1,493 +1,368 @@
 'use strict';
-/**
- * 简版愤怒小鸟 —— GameHostFactory 模块
- * 竖屏 390×844,弹弓发射,重力弹道,砖块结构 + 猪,5只鸟,拖拽瞄准蓄力,粒子+音效反馈。
- */
+
 export default function createGame(opts) {
   const o = opts || {};
   let ctx = null;
+  let canvas = null;
+  let eng = null;
   let seed = null;
-  let now = 0;
-  let t = 0;
-  let subPointers = null; // 订阅句柄
-  let subPointerup = null;
-  let subPointermove = null;
-  // 游戏状态
-  let phase = 'booting'; // 'playing' | 'gameover'
-  let result = '';
+
+  // game state
+  let phase = 'booting';          // 'playing' | 'gameover'
   let score = 0;
   let birdsLeft = 5;
-  let birdIndex = 0;         // 当前正在用第几只 (0~4)
-  let bird = null;           // 当前小鸟 { x, y, vx, vy, state: 'ready'|'flying'|'hit' }
-  let bricks = [];
-  let pigs = [];
-  // 拖拽状态
-  let dragging = false;
-  let dragStart = null;      // { x, y } 弹弓口
-  let dragEnd = null;        // 当前拖拽点
-  // 特效
-  let explosions = [];       // { x, y, born, duration }
-  let texts = [];            // 飘字 +score
+  let targets = [];               // active pigs {x,y}
+  let bricks = [];                // active bricks {x,y,w,h}
+  let bird = null;                // current bird {x,y,vx,vy,active}
 
-  const GRAVITY = 980;       // px/s^2
-  const LAUNCH_FACTOR = 0.5; // 拖拽距离 -> 速度乘数
-  const BIRD_RADIUS = 8;
-  const PIG_RADIUS = 16;
-  const SLING_X = 70;
-  const SLING_Y = 580;
+  // drag state
+  let isDragging = false;
+  let dragStart = { x:0, y:0 };
+  let dragCurrent = { x:0, y:0 };
+  let startPoint = { x:80, y:600 };
+
+  // subscriptions
+  let subDown = null;
+  let subMove = null;
+  let subUp = null;
+
+  // physics constants (exposed for harness)
+  const GRAVITY = 1200;          // px/s²
+  const POWER_SCALE = 8;         // velocity = distance * scale
+
+  // collision radius for bird
+  const BIRD_RADIUS = 10;        // px
+  const PIG_RADIUS = 15;
+
+  // helpers
+  function distPt2Pt(ax, ay, bx, by) {
+    const dx = ax - bx, dy = ay - by;
+    return Math.hypot(dx, dy);
+  }
+  function circleRectCollision(cx, cy, cr, rx, ry, rw, rh) {
+    const nearX = Math.max(rx, Math.min(cx, rx + rw));
+    const nearY = Math.max(ry, Math.min(cy, ry + rh));
+    const dx = cx - nearX, dy = cy - nearY;
+    return (dx * dx + dy * dy) < cr * cr;
+  }
+  function spawnEmitterAt(x, y, count, colorStart) {
+    if (!eng || !eng.particles) return;
+    try {
+      eng.particles.spawnEmitter({
+        pos: { x, y },
+        count: count || 20,
+        speed: 120,
+        particleTime: 0.5,
+        sizeStart: 10,
+        sizeEnd: 2,
+        colorStart: colorStart || { r:1, g:0.8, b:0.2, a:1 },
+        colorEnd: { r:1, g:0.3, b:0, a:0 }
+      });
+    } catch(_) {}
+  }
+  function playSfx() {
+    if (!eng || !eng.audio || !eng.audio.synth) return;
+    try {
+      eng.audio.synth.synthSfx([1, 0.05, 440, , 0.1, 0.5, , 1.4]);
+    } catch(_) {}
+  }
+
+  function setGameOver(reason) {
+    if (phase === 'gameover') return; // already terminal
+    phase = 'gameover';
+    // ignore further interactions
+    bird.active = false;
+    // optional: show reason text in render
+  }
+
+  function launchBird() {
+    if (!bird || bird.active) return;
+    const dx = dragStart.x - dragCurrent.x;
+    const dy = dragStart.y - dragCurrent.y;
+    const dist = Math.hypot(dx, dy);
+    if (dist < 5) { // too short launch aborted
+      isDragging = false;
+      return;
+    }
+    const speed = dist * POWER_SCALE;
+    const nx = dx / dist;
+    const ny = dy / dist;
+    bird.vx = nx * speed;
+    bird.vy = ny * speed;
+    bird.active = true;
+    isDragging = false;
+
+    // visual feedback
+    spawnEmitterAt(startPoint.x, startPoint.y, 25, { r:0.3, g:0.9, b:1, a:1 });
+    playSfx();
+  }
+
+  function handleDown(e) {
+    if (phase !== 'playing') return;
+    if (!bird || bird.active) return;
+    const px = e.x, py = e.y;
+    if (distPt2Pt(px, py, startPoint.x, startPoint.y) < 40) {
+      isDragging = true;
+      dragStart = { x: px, y: py };
+      dragCurrent = { x: px, y: py };
+    }
+  }
+  function handleMove(e) {
+    if (!isDragging) return;
+    dragCurrent = { x: e.x, y: e.y };
+  }
+  function handleUp(e) {
+    if (!isDragging) return;
+    launchBird();
+  }
+
+  function init(boot) {
+    ctx = boot.ctx;
+    canvas = boot.mainContext;
+    seed = boot.seed || null;
+    eng = ctx.getEngine();
+
+    // layout bricks and pigs
+    // simple wall: two rows of bricks, two pigs
+    bricks = [
+      { x:240, y:640, w:40, h:20 },
+      { x:284, y:640, w:40, h:20 },
+      { x:240, y:670, w:40, h:20 },
+      { x:284, y:670, w:40, h:20 }
+    ];
+    targets = [
+      { x:320, y:650 },
+      { x:340, y:700 }
+    ];
 
-  // ========== 内部辅助 ==========
-  function resetGameData() {
-    phase = 'playing';
-    result = '';
-    score = 0;
     birdsLeft = 5;
-    birdIndex = 0;
-    bird = null;
-    bricks = [];
-    pigs = [];
-    dragging = false;
-    dragStart = null;
-    dragEnd = null;
-    explosions = [];
-    texts = [];
-    loadLevel();
-    spawnBird();
-  }
+    score = 0;
+    bird = { x: startPoint.x, y: startPoint.y, vx:0, vy:0, active: false };
+    phase = 'playing';
+    isDragging = false;
 
-  function loadLevel() {
-    // 固定布局:三个猪被砖块包围
-    // 猪
-    const pigPositions = [
-      { x: 290, y: 560 },
-      { x: 310, y: 520 },
-      { x: 280, y: 480 },
-    ];
-    for (const p of pigPositions) {
-      pigs.push({ x: p.x, y: p.y, r: PIG_RADIUS, active: true });
-    }
-    // 砖块 (矩形, 活跃)
-    const brickDefs = [
-      // 底部支撑
-      { x: 270, y: 576, w: 24, h: 10 },
-      { x: 306, y: 576, w: 24, h: 10 },
-      // 左竖墙
-      { x: 262, y: 550, w: 10, h: 24 },
-      // 右竖墙
-      { x: 322, y: 550, w: 10, h: 24 },
-      // 中层
-      { x: 290, y: 546, w: 30, h: 10 },
-      { x: 290, y: 534, w: 10, h: 12 }, // 垂直分隔
-      // 上层
-      { x: 270, y: 506, w: 24, h: 10 },
-      { x: 306, y: 506, w: 24, h: 10 },
-      { x: 280, y: 490, w: 10, h: 16 },
-      { x: 310, y: 490, w: 10, h: 16 },
-      // 顶保护
-      { x: 280, y: 470, w: 30, h: 8 },
-    ];
-    for (const b of brickDefs) {
-      bricks.push({ x: b.x, y: b.y, w: b.w, h: b.h, active: true });
-    }
-  }
+    // input subscriptions
+    subDown = ctx.getInput().on('pointerdown', handleDown);
+    subMove = ctx.getInput().on('pointermove', handleMove);
+    subUp = ctx.getInput().on('pointerup', handleUp);
 
-  function spawnBird() {
-    if (birdIndex >= 5) return; // 鸟用完了
-    bird = {
-      x: SLING_X,
-      y: SLING_Y - 10,
-      vx: 0,
-      vy: 0,
-      state: 'ready', // 'ready' | 'flying' | 'hit'
-      alive: true,
-    };
-    birdIndex++;
-    birdsLeft = 5 - birdIndex;
-  }
-
-  /** 发射小鸟 */
-  function launchBird(px, py) {
-    if (!bird || bird.state !== 'ready') return;
-    // 从弹弓口到拖拽点的反方向
-    const dx = SLING_X - px;
-    const dy = (SLING_Y - 10) - py;
-    const vx = dx * LAUNCH_FACTOR;
-    const vy = dy * LAUNCH_FACTOR;
-    bird.vx = vx;
-    bird.vy = vy;
-    bird.state = 'flying';
-    dragging = false;
-    dragStart = null;
-    dragEnd = null;
-    // 发射粒子 + 音效
-    spawnParticles(SLING_X, SLING_Y - 10, 30, { r: 1, g: 0.9, b: 0.3, a: 1 }, 0.6);
-    playSfx([1, 0.08, 600, , 0.1, 0.5, 0.5, 1.2]);
-  }
-
-  /** 碰撞检测与物理更新 */
-  function updatePhysics(dt) {
-    if (!bird || bird.state !== 'flying') return;
-    const b = bird;
-    // 重力
-    b.vy += GRAVITY * dt;
-    b.x += b.vx * dt;
-    b.y += b.vy * dt;
-
-    // 出界检测
-    if (b.y > 844 || b.x < -20 || b.x > 410 || b.y < -20) {
-      hitObstacle(b.x, b.y);
-      return;
-    }
-
-    // 碰撞检测: 猪
-    for (const pig of pigs) {
-      if (!pig.active) continue;
-      const dx = b.x - pig.x;
-      const dy = b.y - pig.y;
-      const dist = Math.sqrt(dx * dx + dy * dy);
-      if (dist < BIRD_RADIUS + pig.r) {
-        pig.active = false;
-        score += 100;
-        // 爆炸粒子 + 音效
-        spawnParticles(pig.x, pig.y, 40, { r: 1, g: 0.4, b: 0.1, a: 1 }, 0.8);
-        playSfx([1, 0.9, 100, , 0.1, 0.4, 0.8, 1.5]);
-        addFloatingText(pig.x, pig.y, '+100');
-        hitObstacle(b.x, b.y);
-        return;
-      }
-    }
-
-    // 碰撞检测: 砖块
-    for (const brick of bricks) {
-      if (!brick.active) continue;
-      if (b.x > brick.x && b.x < brick.x + brick.w &&
-          b.y > brick.y && b.y < brick.y + brick.h) {
-        brick.active = false;
-        score += 10;
-        spawnParticles(brick.x + brick.w / 2, brick.y + brick.h / 2, 20, { r: 0.8, g: 0.7, b: 0.5, a: 1 }, 0.5);
-        playSfx([1, 0.2, 400, , 0.1, 0.3, 0.6, 1.3]);
-        addFloatingText(brick.x + brick.w / 2, brick.y, '+10');
-        hitObstacle(b.x, b.y);
-        return;
-      }
-    }
-
-    // 如果鸟落地上或太低,也视为落败
-    if (b.y > 800) {
-      hitObstacle(b.x, b.y);
-    }
-  }
-
-  /** 鸟撞击/消失处理 */
-  function hitObstacle(x, y) {
-    if (!bird || bird.state !== 'flying') return;
-    bird.state = 'hit';
-    bird.alive = false;
-    // 碰撞粒子
-    spawnParticles(x, y, 25, { r: 0.6, g: 0.8, b: 1, a: 1 }, 0.4);
-    playSfx([1, 0.05, 300, , 0.1, 0.2, 0.5, 1.0]);
-    // 延迟切换到下一只鸟
-    setTimeout(() => {
-      if (phase === 'gameover') return;
-      if (allPigsCleared()) {
-        phase = 'gameover';
-        result = 'win';
-        showResult();
-        return;
-      }
-      if (birdIndex >= 5) {
-        phase = 'gameover';
-        result = 'lose';
-        showResult();
-        return;
-      }
-      spawnBird();
-    }, 500);
-  }
-
-  function allPigsCleared() {
-    return pigs.every(p => !p.active);
-  }
-
-  function showResult() {
-    spawnParticles(195, 422, 50, { r: 1, g: 0.9, b: 0.2, a: 1 }, 1.5);
-    playSfx([1, 0.9, 800, , 0.1, 0.6, 0.9, 1.8]);
-  }
-
-  // ========== 输入处理 ==========
-  function onPointerDown(e) {
-    if (phase === 'gameover') {
-      // 检查是否点击重玩区域(固定: 中间偏下 "Tap to Restart")
-      if (e.x > 100 && e.x < 290 && e.y > 600 && e.y < 680) {
-        resetGameData();
-        phase = 'playing';
-        // 清除任何残留特效
-        explosions = [];
-        texts = [];
-      }
-      return;
-    }
-    if (!bird || bird.state !== 'ready') return;
-    // 检测点击是否在弹弓附近
-    const dx = e.x - SLING_X;
-    const dy = e.y - (SLING_Y - 10);
-    if (Math.sqrt(dx * dx + dy * dy) < 80) {
-      dragging = true;
-      dragStart = { x: SLING_X, y: SLING_Y - 10 };
-      dragEnd = { x: e.x, y: e.y };
-    }
-  }
-
-  function onPointerMove(e) {
-    if (!dragging) return;
-    dragEnd = { x: e.x, y: e.y };
-  }
-
-  function onPointerUp(e) {
-    if (!dragging) return;
-    dragging = false;
-    if (dragEnd) {
-      launchBird(dragEnd.x, dragEnd.y);
-    }
-    dragStart = null;
-    dragEnd = null;
-  }
-
-  // ========== 特效辅助 ==========
-  function spawnParticles(x, y, count, colorStart, life) {
-    const eng = ctx && ctx.getEngine();
+    // keep at least one emitter running (demonstrate engine usage)
     if (eng && eng.particles) {
       try {
         eng.particles.spawnEmitter({
-          pos: { x, y },
-          count: count,
-          speed: 100 + count * 2,
-          particleTime: life || 0.6,
-          colorStart: colorStart || { r: 1, g: 0.5, b: 0, a: 1 },
-          colorEnd: { r: 1, g: 0.2, b: 0, a: 0 },
-          sizeStart: 6,
-          sizeEnd: 2,
+          pos: { x: 195, y: 200 },
+          emitRate: 8,
+          emitTime: 0,
+          particleTime: 0.6,
+          speed: 30,
+          colorStart: { r:0.4, g:0.6, b:1, a:0.5 },
+          colorEnd: { r:0.2, g:0.2, b:0.6, a:0 }
         });
-      } catch (_) {}
+      } catch(_) {}
     }
   }
 
-  function playSfx(params) {
-    const eng = ctx && ctx.getEngine();
-    if (eng && eng.audio && eng.audio.synth) {
-      try {
-        eng.audio.synth.synthSfx(params);
-      } catch (_) {}
-    }
-  }
-
-  function addFloatingText(x, y, text) {
-    texts.push({ x, y, text, born: now, duration: 800 });
-  }
-
-  // ========== 生命周期 ==========
-  function init(boot) {
-    ctx = boot.ctx;
-    seed = boot.seed || 0;
-    // 订阅输入
-    subPointers = ctx.getInput().on('pointerdown', onPointerDown);
-    subPointermove = ctx.getInput().on('pointermove', onPointerMove);
-    subPointerup = ctx.getInput().on('pointerup', onPointerUp);
-    // 先确保种子(可选)
-    if (ctx.random) {
-      ctx.random.reseed(seed);
-    }
-    // 初始化关卡
-    resetGameData();
-    phase = 'playing';
-  }
-
   function update(dt) {
-    now = ctx.time.nowMs();
-    t = now / 1000;
     if (phase !== 'playing') return;
-    // 更新物理
-    updatePhysics(dt);
-    // 检查是否所有猪消灭 -> win
-    if (allPigsCleared() && bird && bird.state !== 'flying') {
-      phase = 'gameover';
-      result = 'win';
-      showResult();
-    }
-    // 鸟用完且没有飞行中的鸟 => lose
-    if (birdIndex >= 5 && (!bird || bird.state === 'hit' || bird.state === 'ready')) {
-      phase = 'gameover';
-      result = 'lose';
-      showResult();
-    }
-    // 清理过期文字
-    texts = texts.filter(txt => now - txt.born < txt.duration);
-    // 清理过期爆炸效果(本示例仅依靠引擎粒子,此处保留一个简单列表用于自绘圈)
-    // 无额外自绘圈,而是依赖引擎粒子和HUD
-  }
+    if (!bird || !bird.active) return;
 
-  function render(g) {
-    // 背景
-    g.fillStyle = '#1a2b3c';
-    g.fillRect(0, 0, 390, 844);
+    // physics
+    bird.x += bird.vx * dt;
+    bird.y += bird.vy * dt;
+    bird.vy += GRAVITY * dt;
 
-    // 绘制砖块
-    g.fillStyle = '#c8913e';
-    for (const brick of bricks) {
-      if (!brick.active) continue;
-      g.fillRect(brick.x, brick.y, brick.w, brick.h);
-      g.strokeStyle = '#5f3a1a';
-      g.lineWidth = 1;
-      g.strokeRect(brick.x, brick.y, brick.w, brick.h);
-    }
-
-    // 绘制猪
-    for (const pig of pigs) {
-      if (!pig.active) continue;
-      g.fillStyle = '#4CAF50';
-      g.beginPath();
-      g.arc(pig.x, pig.y, pig.r, 0, Math.PI * 2);
-      g.fill();
-      g.strokeStyle = '#2e7d32';
-      g.lineWidth = 2;
-      g.stroke();
-      // 鼻子
-      g.fillStyle = '#e2a0a0';
-      g.beginPath();
-      g.arc(pig.x - 4, pig.y - 2, 3, 0, Math.PI * 2);
-      g.fill();
-    }
-
-    // 绘制弹弓
-    g.strokeStyle = '#5c3a1e';
-    g.lineWidth = 6;
-    g.beginPath();
-    g.moveTo(60, 590);
-    g.lineTo(70, 540);
-    g.lineTo(80, 590);
-    g.stroke();
-    g.beginPath();
-    g.moveTo(70, 540);
-    g.lineTo(74, 600);
-    g.stroke();
-
-    // 绘制小鸟(如果 ready 或 flying)
-    if (bird && (bird.state === 'ready' || bird.state === 'flying')) {
-      g.fillStyle = '#f44336';
-      g.beginPath();
-      g.arc(bird.x, bird.y, BIRD_RADIUS, 0, Math.PI * 2);
-      g.fill();
-      g.fillStyle = '#ffcdd2';
-      g.beginPath();
-      g.arc(bird.x - 3, bird.y - 3, 3, 0, Math.PI * 2);
-      g.fill();
-      // 嘴
-      g.fillStyle = '#ff9800';
-      g.beginPath();
-      g.moveTo(bird.x + 6, bird.y - 1);
-      g.lineTo(bird.x + 12, bird.y);
-      g.lineTo(bird.x + 6, bird.y + 2);
-      g.fill();
-    }
-
-    // 绘制拖拽线
-    if (dragging && dragStart && dragEnd) {
-      g.strokeStyle = 'rgba(255,255,255,0.5)';
-      g.lineWidth = 2;
-      g.setLineDash([6, 4]);
-      g.beginPath();
-      g.moveTo(dragStart.x, dragStart.y);
-      g.lineTo(dragEnd.x, dragEnd.y);
-      g.stroke();
-      g.setLineDash([]);
-      // 箭头指示方向反向
-      const dx = dragStart.x - dragEnd.x;
-      const dy = dragStart.y - dragEnd.y;
-      const len = Math.sqrt(dx*dx + dy*dy);
-      if (len > 5) {
-        const angle = Math.atan2(dy, dx);
-        const arrowLen = 12;
-        g.fillStyle = '#fff';
-        g.beginPath();
-        g.moveTo(dragStart.x + dx/4, dragStart.y + dy/4);
-        g.lineTo(dragStart.x + dx/4 - arrowLen * Math.cos(angle - 0.4), dragStart.y + dy/4 - arrowLen * Math.sin(angle - 0.4));
-        g.lineTo(dragStart.x + dx/4 - arrowLen * Math.cos(angle + 0.4), dragStart.y + dy/4 - arrowLen * Math.sin(angle + 0.4));
-        g.fill();
+    // collision detection with bricks
+    for (let i = bricks.length - 1; i >= 0; i--) {
+      const br = bricks[i];
+      if (circleRectCollision(bird.x, bird.y, BIRD_RADIUS, br.x, br.y, br.w, br.h)) {
+        // brick destroyed
+        spawnEmitterAt(br.x + br.w/2, br.y + br.h/2, 18, { r:0.9, g:0.7, b:0.3, a:1 });
+        playSfx();
+        bricks.splice(i, 1);
+        break; // only one collision per frame
       }
     }
 
-    // HUD 文字 (顶部)
-    g.fillStyle = 'rgba(255,255,255,0.8)';
-    g.font = 'bold 20px monospace';
-    g.textAlign = 'left';
-    g.fillText('🐦 ×' + birdsLeft, 10, 30);
-    g.textAlign = 'right';
-    g.fillText('🏆 ' + score, 380, 30);
-    g.textAlign = 'center';
-    g.fillStyle = '#9f9';
-    g.font = '16px monospace';
-    const status = phase === 'gameover' ? (result === 'win' ? '✨ 全灭!' : '💀 失败') : (bird && bird.state === 'flying' ? '🎯 飞行中' : '📐 拖拽蓄力');
-    g.fillText(status, 195, 55);
-
-    // 飘字
-    for (const txt of texts) {
-      const age = (now - txt.born) / txt.duration;
-      const alpha = 1 - age;
-      g.globalAlpha = alpha;
-      g.fillStyle = '#ffdd44';
-      g.font = 'bold 18px monospace';
-      g.textAlign = 'center';
-      g.fillText(txt.text, txt.x, txt.y - 20 * age);
-      g.globalAlpha = 1;
+    // collision detection with pigs
+    for (let i = targets.length - 1; i >= 0; i--) {
+      const pig = targets[i];
+      const d = distPt2Pt(bird.x, bird.y, pig.x, pig.y);
+      if (d < BIRD_RADIUS + PIG_RADIUS) {
+        // pig killed
+        spawnEmitterAt(pig.x, pig.y, 28, { r:0.1, g:1, b:0.2, a:1 });
+        playSfx();
+        targets.splice(i, 1);
+        score += 10;
+        break;
+      }
     }
 
-    // 游戏结束重玩提示
-    if (phase === 'gameover') {
-      g.fillStyle = 'rgba(0,0,0,0.4)';
-      g.fillRect(100, 600, 190, 60);
-      g.strokeStyle = '#fff';
+    // out of bounds or ground
+    if (bird.x < -20 || bird.x > 410 || bird.y > 860) {
+      bird.active = false;
+      birdsLeft--;
+
+      if (targets.length === 0) {
+        // all pigs destroyed -> win
+        setGameOver('win');
+        return;
+      }
+
+      if (birdsLeft > 0) {
+        // reset bird for next launch
+        bird.x = startPoint.x;
+        bird.y = startPoint.y;
+        bird.vx = 0;
+        bird.vy = 0;
+        bird.active = false;
+      } else {
+        // out of birds -> lose
+        setGameOver('lose');
+      }
+    }
+
+    // if no pigs remain and bird is still active, but that's handled when pig is removed.
+    if (targets.length === 0 && bird.active) {
+      // won immediately (last pig killed in this frame)
+      setGameOver('win');
+    }
+  }
+
+  function render(g) {
+    // background
+    g.fillStyle = '#1a1a2e';
+    g.fillRect(0, 0, 390, 844);
+
+    // draw slingshot base
+    g.strokeStyle = '#8B4513';
+    g.lineWidth = 4;
+    g.beginPath();
+    g.moveTo(startPoint.x - 10, startPoint.y - 20);
+    g.lineTo(startPoint.x, startPoint.y);
+    g.lineTo(startPoint.x + 10, startPoint.y - 20);
+    g.stroke();
+
+    // draw drag line if dragging
+    if (isDragging) {
+      g.strokeStyle = 'rgba(255,255,255,0.5)';
       g.lineWidth = 2;
-      g.strokeRect(100, 600, 190, 60);
+      g.setLineDash([4, 4]);
+      g.beginPath();
+      g.moveTo(startPoint.x, startPoint.y);
+      g.lineTo(dragCurrent.x, dragCurrent.y);
+      g.stroke();
+      g.setLineDash([]);
+    }
+
+    // draw bricks
+    g.fillStyle = '#a0522d';
+    for (const br of bricks) {
+      g.fillRect(br.x, br.y, br.w, br.h);
+    }
+
+    // draw pigs
+    g.fillStyle = '#32cd32';
+    for (const pig of targets) {
+      g.beginPath();
+      g.arc(pig.x, pig.y, PIG_RADIUS, 0, Math.PI*2);
+      g.fill();
+      // eyes
+      g.fillStyle = '#000';
+      g.beginPath();
+      g.arc(pig.x-4, pig.y-4, 3, 0, Math.PI*2);
+      g.fill();
+      g.beginPath();
+      g.arc(pig.x+4, pig.y-4, 3, 0, Math.PI*2);
+      g.fill();
+      g.fillStyle = '#32cd32';
+    }
+
+    // draw bird
+    if (bird && !bird.active && birdsLeft > 0) {
+      // waiting at slingshot
+      g.fillStyle = '#ff4444';
+      g.beginPath();
+      g.arc(startPoint.x, startPoint.y, BIRD_RADIUS, 0, Math.PI*2);
+      g.fill();
+      // eyes
       g.fillStyle = '#fff';
-      g.font = 'bold 22px monospace';
+      g.beginPath();
+      g.arc(startPoint.x-3, startPoint.y-3, 3, 0, Math.PI*2);
+      g.fill();
+      g.beginPath();
+      g.arc(startPoint.x+3, startPoint.y-3, 3, 0, Math.PI*2);
+      g.fill();
+    }
+    if (bird && bird.active) {
+      g.fillStyle = '#ff4444';
+      g.beginPath();
+      g.arc(bird.x, bird.y, BIRD_RADIUS, 0, Math.PI*2);
+      g.fill();
+      g.fillStyle = '#fff';
+      g.beginPath();
+      g.arc(bird.x-3, bird.y-3, 3, 0, Math.PI*2);
+      g.fill();
+      g.beginPath();
+      g.arc(bird.x+3, bird.y-3, 3, 0, Math.PI*2);
+      g.fill();
+    }
+
+    // HUD top bar
+    g.fillStyle = '#222';
+    g.fillRect(0, 0, 390, 40);
+
+    const phaseText = phase === 'gameover' ? 'GAME OVER' : 'PLAYING';
+    const remainText = birdsLeft + (birdsLeft === 1 ? ' bird' : ' birds');
+    g.fillStyle = '#fff';
+    g.font = '16px monospace';
+    g.fillText('Score: ' + score, 10, 26);
+    g.fillText(remainText + ' left', 200, 26);
+    g.fillText(phaseText, 300, 26);
+
+    // game over overlay
+    if (phase === 'gameover') {
+      const resultText = targets.length === 0 ? 'YOU WIN!' : 'YOU LOSE!';
+      g.fillStyle = 'rgba(0,0,0,0.6)';
+      g.fillRect(0, 200, 390, 100);
+      g.fillStyle = '#ffcc00';
+      g.font = 'bold 32px monospace';
       g.textAlign = 'center';
-      g.fillText('点击重玩', 195, 638);
+      g.fillText(resultText, 195, 260);
+      g.fillStyle = '#aaa';
+      g.font = '16px monospace';
+      g.fillText('Tap to restart', 195, 290);
+      g.textAlign = 'left';
     }
   }
 
   function destroy() {
-    try { subPointers && subPointers.cancel(); } catch(_) {}
-    try { subPointermove && subPointermove.cancel(); } catch(_) {}
-    try { subPointerup && subPointerup.cancel(); } catch(_) {}
-    subPointers = subPointermove = subPointerup = null;
-    explosions = [];
-    texts = [];
+    try { if (subDown) subDown.cancel(); } catch(_) {}
+    try { if (subMove) subMove.cancel(); } catch(_) {}
+    try { if (subUp) subUp.cancel(); } catch(_) {}
+    subDown = subMove = subUp = null;
     bricks = [];
-    pigs = [];
+    targets = [];
     bird = null;
+    isDragging = false;
+    phase = 'destroyed';
   }
 
   function _forensicsView() {
     return {
-      seed: seed,
-      state: () => {
-        const remainingPigs = pigs.filter(p => p.active).map(p => ({ x: p.x, y: p.y }));
-        return {
-          phase: phase,
-          result: (phase === 'gameover' ? result : null),
-          score: score,
-          birdsLeft: birdsLeft,
-          targets: remainingPigs,
-        };
-      }
+      seed,
+      state: () => ({
+        phase,
+        result: phase === 'gameover' ? (targets.length === 0 ? 'win' : 'lose') : null,
+        score,
+        birdsLeft,
+        targets: targets.map(p => ({ x: p.x, y: p.y })),
+        launch: {
+          gravity: GRAVITY,
+          powerScale: POWER_SCALE
+        }
+      })
     };
   }
 
-  return {
-    init,
-    update,
-    render,
-    destroy,
-    _forensicsView
-  };
+  return { init, update, render, destroy, _forensicsView };
 }
\ No newline at end of file
diff --git a/game-runtime/games/_wg1-gen/angrybirds/play-spec.json b/game-runtime/games/_wg1-gen/angrybirds/play-spec.json
index b87ed976..1a665ef9 100644
--- a/game-runtime/games/_wg1-gen/angrybirds/play-spec.json
+++ b/game-runtime/games/_wg1-gen/angrybirds/play-spec.json
@@ -1,106 +1,24 @@
 {
-  "inputs": [
-    {
-      "t": "wait",
-      "ms": 700
+  "driver": {
+    "type": "drag-aiming",
+    "origin": {
+      "x": 80,
+      "y": 600
     },
-    {
-      "t": "drag",
-      "from": {
-        "x": 80,
-        "y": 600
-      },
-      "to": {
-        "x": 44,
-        "y": 668
-      },
-      "ms": 420
-    },
-    {
-      "t": "wait",
-      "ms": 1700
-    },
-    {
-      "t": "drag",
-      "from": {
-        "x": 80,
-        "y": 600
-      },
-      "to": {
-        "x": 40,
-        "y": 690
-      },
-      "ms": 420
-    },
-    {
-      "t": "wait",
-      "ms": 1700
-    },
-    {
-      "t": "drag",
-      "from": {
-        "x": 80,
-        "y": 600
-      },
-      "to": {
-        "x": 50,
-        "y": 655
-      },
-      "ms": 420
-    },
-    {
-      "t": "wait",
-      "ms": 1700
-    },
-    {
-      "t": "drag",
-      "from": {
-        "x": 80,
-        "y": 600
-      },
-      "to": {
-        "x": 38,
-        "y": 700
-      },
-      "ms": 420
-    },
-    {
-      "t": "wait",
-      "ms": 1700
-    },
-    {
-      "t": "drag",
-      "from": {
-        "x": 80,
-        "y": 600
-      },
-      "to": {
-        "x": 54,
-        "y": 648
-      },
-      "ms": 420
-    },
-    {
-      "t": "wait",
-      "ms": 1700
-    },
-    {
-      "t": "drag",
-      "from": {
-        "x": 80,
-        "y": 600
-      },
-      "to": {
-        "x": 42,
-        "y": 680
-      },
-      "ms": 420
-    },
-    {
-      "t": "wait",
-      "ms": 1700
-    }
-  ],
+    "targetsPath": "targets",
+    "launchPath": "launch",
+    "steps": 6,
+    "settleMs": 1700,
+    "upLead": 95,
+    "powers": [
+      60,
+      80,
+      100,
+      70,
+      90,
+      110
+    ]
+  },
   "expectedEngineCallPrefixes": [
     "particles.",
     "audio.synth"
@@ -109,7 +27,7 @@
     {
       "path": "score",
       "op": "increased",
-      "why": "盲态固定拖拽发射→偶中目标得分;若固定角度打不中(需读目标算拖拽矢量)则不升=暴露拖拽瞄准缺口"
+      "why": "drag-aiming 读 launch 物理常数(gravity/powerScale)45° 抛解析反解拖拽矢量→命中猪得分上升;游戏暴露物理即可确定性瞄准(asteroids 式『暴露即可测』);若仍 0=物理未按 pin 实现"
     }
   ],
   "expectLatch": true
diff --git a/game-runtime/games/_wg1-gen/asteroids/bundle.iife.js b/game-runtime/games/_wg1-gen/asteroids/bundle.iife.js
index 09c7cc44..60d9213a 100644
--- a/game-runtime/games/_wg1-gen/asteroids/bundle.iife.js
+++ b/game-runtime/games/_wg1-gen/asteroids/bundle.iife.js
@@ -1,34 +1,34 @@
-"use strict";var __GameBundle=(()=>{var zi=Object.defineProperty;var kc=Object.getOwnPropertyDescriptor;var Gc=Object.getOwnPropertyNames;var Fc=Object.prototype.hasOwnProperty;var jc=(n,t,e)=>()=>{if(e)throw e[0];try{return n&&(t=n(n=0)),t}catch(s){throw e=[s],s}};var Hr=(n,t)=>{for(var e in t)zi(n,e,{get:t[e],enumerable:!0})},Bc=(n,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Gc(t))!Fc.call(n,i)&&i!==e&&zi(n,i,{get:()=>t[i],enumerable:!(s=kc(t,i))||s.enumerable});return n};var Nc=n=>Bc(zi({},"__esModule",{value:!0}),n);var Ic={};Hr(Ic,{ASSERT:()=>f,BLACK:()=>it,BLUE:()=>Za,Box2dDistanceJoint:()=>Ti,Box2dFrictionJoint:()=>$o,Box2dGearJoint:()=>qo,Box2dJoint:()=>Xt,Box2dKinematicObject:()=>No,Box2dMotorJoint:()=>Qo,Box2dObject:()=>_s,Box2dPinJoint:()=>Uo,Box2dPlugin:()=>Ai,Box2dPrismaticJoint:()=>Ho,Box2dPulleyJoint:()=>Ko,Box2dRaycastResult:()=>wi,Box2dRevoluteJoint:()=>Wo,Box2dRopeJoint:()=>Vo,Box2dStaticObject:()=>Si,Box2dTargetJoint:()=>Jo,Box2dTileLayer:()=>zo,Box2dWeldJoint:()=>Yo,Box2dWheelJoint:()=>Xo,CLEAR_BLACK:()=>pe,CLEAR_WHITE:()=>rn,CYAN:()=>ql,CanvasLayer:()=>ui,Color:()=>wt,Ease:()=>Ci,EngineObject:()=>Ue,GRAY:()=>Vl,GREEN:()=>Qa,ImageFont:()=>ii,LOG:()=>xt,Light:()=>Oo,LightSystemPlugin:()=>Lo,MAGENTA:()=>Hl,Medal:()=>xi,NewgroundsMedal:()=>_o,NewgroundsPlugin:()=>Ro,ORANGE:()=>Wl,PI:()=>X,PURPLE:()=>tc,Particle:()=>hi,ParticleEmitter:()=>vo,PathFinder:()=>Zo,PathFinderNode:()=>_i,PostProcessPlugin:()=>Po,RED:()=>rr,RandomGenerator:()=>go,Sound:()=>bs,SoundInstance:()=>ci,TextureInfo:()=>Ve,TileCollisionLayer:()=>vs,TileInfo:()=>Re,TileLayer:()=>xs,TileLayerData:()=>wn,Timer:()=>Ee,Tween:()=>Ei,UIButton:()=>Cs,UICheckbox:()=>Go,UILayout:()=>Bo,UIObject:()=>re,UISlider:()=>Fo,UISystemPlugin:()=>Io,UIText:()=>vi,UITextInput:()=>Mo,UITile:()=>ko,UIVideo:()=>jo,Vector2:()=>rt,WHITE:()=>W,YELLOW:()=>Ka,ZzFXMusic:()=>Do,abs:()=>nt,atan2:()=>sr,audioContext:()=>ft,audioDefaultSampleRate:()=>Qn,audioIsRunning:()=>ms,audioMasterGain:()=>Je,box2d:()=>m,box2dDebug:()=>qr,box2dInit:()=>ad,box2dSetDebug:()=>rd,cameraAngle:()=>Q,cameraFit:()=>rh,cameraPos:()=>_t,cameraScale:()=>H,canvasClearColor:()=>tn,canvasColorTiles:()=>Pi,canvasFixedSize:()=>Gn,canvasMaxAspect:()=>kn,canvasMaxSize:()=>Mn,canvasMinAspect:()=>os,canvasPixelRatio:()=>en,canvasPixelated:()=>lr,ceil:()=>us,clamp:()=>N,combineCanvases:()=>wr,cos:()=>lt,debug:()=>jt,debugCircle:()=>Ut,debugClear:()=>Ml,debugLine:()=>we,debugOverlap:()=>fo,debugOverlay:()=>Me,debugPoint:()=>nr,debugPointSize:()=>ka,debugPoly:()=>Il,debugRect:()=>bt,debugScreenshot:()=>Fa,debugShowErrors:()=>kl,debugText:()=>In,debugVideoCaptureIsActive:()=>Te,debugVideoCaptureStart:()=>ja,debugVideoCaptureStop:()=>Ba,debugWatermark:()=>Ri,distanceAngle:()=>zl,distanceWrap:()=>ir,drawCanvas2D:()=>Rn,drawCircle:()=>si,drawCircleGradient:()=>sh,drawContext:()=>Et,drawCount:()=>Ce,drawCrescent:()=>ud,drawEllipse:()=>ic,drawEllipseGradient:()=>oc,drawLine:()=>mn,drawLineList:()=>mo,drawNineSlice:()=>_c,drawNineSliceScreen:()=>cd,drawPoly:()=>Un,drawRect:()=>ni,drawRectGradient:()=>th,drawRegularPoly:()=>sc,drawText:()=>ih,drawTextScreen:()=>nn,drawTextureWrapped:()=>eh,drawThreeSlice:()=>Rc,drawThreeSliceScreen:()=>ld,drawTile:()=>Mt,enablePhysicsSolver:()=>Ii,engineAddPlugin:()=>Cn,engineImageFont:()=>lc,engineInit:()=>Pl,engineName:()=>Hs,engineObjects:()=>vt,engineObjectsCallback:()=>Ol,engineObjectsCollect:()=>Ma,engineObjectsCollide:()=>er,engineObjectsDestroy:()=>Ll,engineObjectsRaycast:()=>Dl,engineObjectsUpdate:()=>Ia,engineVersion:()=>Xs,fetchJSON:()=>Xl,floor:()=>St,fontDefault:()=>Rs,formatTime:()=>ar,frame:()=>Oa,frameRate:()=>Cl,gamepadConnected:()=>xo,gamepadDirectionEmulateStick:()=>yr,gamepadDpad:()=>bo,gamepadIsDown:()=>Ie,gamepadPrimary:()=>mt,gamepadStick:()=>gs,gamepadStickCount:()=>uc,gamepadVibrate:()=>Sh,gamepadVibrateStop:()=>wh,gamepadWasPressed:()=>Rr,gamepadWasReleased:()=>vh,gamepadsEnable:()=>Mi,getCameraSize:()=>ac,getCrescentPoints:()=>Pc,getNoteFrequency:()=>gc,getPaused:()=>_l,glAntialias:()=>Mr,glCanvas:()=>et,glCircleSides:()=>Ps,glClearCanvas:()=>vc,glClearRect:()=>Ec,glCompileShader:()=>Co,glContext:()=>g,glCopyToContext:()=>Br,glCreateProgram:()=>Xn,glCreateTexture:()=>ji,glDeleteTexture:()=>wc,glDraw:()=>Ts,glDrawColoredPoints:()=>Jr,glDrawOutlineTransform:()=>zr,glDrawPoints:()=>Ac,glDrawPointsTransform:()=>Nr,glDrawUntextured:()=>Tc,glEnable:()=>G,glFlush:()=>Rt,glSetAntialias:()=>Yh,glSetRenderTarget:()=>is,glSetTexture:()=>Fr,glSetTextureData:()=>jr,glSetTextureWrap:()=>Sc,gravity:()=>Vt,headlessMode:()=>z,hsl:()=>Ge,hypot:()=>Na,inputClear:()=>ks,inputClearKey:()=>Cr,inputMouseMoveThreshold:()=>Er,inputPreventDefault:()=>Fn,inputWASDEmulateDirection:()=>rs,isArray:()=>de,isColor:()=>U,isFullscreen:()=>cc,isIntersecting:()=>Va,isNumber:()=>L,isOnScreen:()=>ah,isOverlapping:()=>Qs,isPowerOfTwo:()=>hs,isStringLike:()=>V,isTouchDevice:()=>ie,isUsingGamepad:()=>Bn,isVector2:()=>O,keyDirection:()=>bh,keyIsDown:()=>It,keyWasPressed:()=>Gt,keyWasReleased:()=>_r,lastInputDevice:()=>Qe,lerp:()=>Wt,lerpAngle:()=>Jl,lerpWrap:()=>Ua,lightSystem:()=>q,lineTest:()=>qa,log2:()=>za,mainCanvas:()=>B,mainCanvasSize:()=>I,mainContext:()=>ut,max:()=>K,medalDisplaySize:()=>mi,medalDisplaySlideTime:()=>jn,medalDisplayTime:()=>yi,medals:()=>As,medalsForEach:()=>Bi,medalsInit:()=>Zh,medalsPreventUnlock:()=>Ur,medalsReset:()=>td,min:()=>tt,mod:()=>se,mouseDelta:()=>Tr,mouseDeltaScreen:()=>xe,mouseInWindow:()=>oi,mouseIsDown:()=>cs,mousePos:()=>De,mousePosScreen:()=>Jt,mouseWasPressed:()=>ps,mouseWasReleased:()=>xh,mouseWheel:()=>Ar,nearestPowerOfTwo:()=>Ul,newgrounds:()=>Es,noise1D:()=>Zl,noise2D:()=>tu,objectDefaultAngleDamping:()=>fr,objectDefaultDamping:()=>dr,objectDefaultFriction:()=>gr,objectDefaultMass:()=>hr,objectDefaultRestitution:()=>pr,objectMaxSpeed:()=>Fe,oscillate:()=>Wa,particleEmitRateScale:()=>Zs,paused:()=>Ae,percent:()=>Bt,percentLerp:()=>Nl,playSamples:()=>Ir,pointerLockExit:()=>Eh,pointerLockIsActive:()=>hc,pointerLockRequest:()=>Ah,postProcess:()=>kt,primitiveCount:()=>_e,rand:()=>dt,randBool:()=>Ha,randColor:()=>po,randInCircle:()=>$a,randInt:()=>or,randSign:()=>Xa,randVec2:()=>Ya,readSaveData:()=>Kl,rgb:()=>J,round:()=>$s,saveCanvas:()=>ec,saveDataURL:()=>ds,saveText:()=>Yl,screenToWorld:()=>Is,screenToWorldDelta:()=>rc,screenToWorldTransform:()=>Ms,setAdditiveBlendMode:()=>fs,setCameraAngle:()=>nu,setCameraPos:()=>eu,setCameraScale:()=>su,setCanvasClearColor:()=>ru,setCanvasColorTiles:()=>ou,setCanvasFixedSize:()=>uu,setCanvasMaxAspect:()=>lu,setCanvasMaxSize:()=>au,setCanvasMinAspect:()=>cu,setCanvasPixelRatio:()=>du,setCanvasPixelated:()=>nc,setCursor:()=>hh,setDebugKey:()=>Zu,setDebugWatermark:()=>Qu,setEnablePhysicsSolver:()=>Su,setFontDefault:()=>fu,setGLCircleSides:()=>mu,setGLEnable:()=>yu,setGamepadDirectionEmulateStick:()=>Ou,setGamepadsEnable:()=>Lu,setGravity:()=>Ru,setHeadlessMode:()=>gu,setInputMouseMoveThreshold:()=>ph,setInputPreventDefault:()=>fh,setInputWASDEmulateDirection:()=>Du,setMedalDisplaySize:()=>sd,setMedalDisplaySlideTime:()=>nd,setMedalDisplayTime:()=>ed,setMedalsPreventUnlock:()=>id,setObjectDefaultAngleDamping:()=>Au,setObjectDefaultDamping:()=>Tu,setObjectDefaultFriction:()=>Cu,setObjectDefaultMass:()=>wu,setObjectDefaultRestitution:()=>Eu,setObjectMaxSpeed:()=>_u,setParticleEmitRateScale:()=>Pu,setPaused:()=>Rl,setShowSplashScreen:()=>pu,setSoundDefaultRange:()=>$u,setSoundDefaultTaper:()=>Ku,setSoundEnable:()=>Xu,setSoundVolume:()=>Yu,setTileDefaultBleed:()=>vu,setTileDefaultPadding:()=>xu,setTileDefaultSize:()=>bu,setTilesPixelated:()=>hu,setTimeScale:()=>iu,setTouchGamepadAlpha:()=>Vu,setTouchGamepadAnalog:()=>zu,setTouchGamepadButtonCount:()=>Fu,setTouchGamepadCenterButtonSize:()=>Gu,setTouchGamepadDisplayTime:()=>Wu,setTouchGamepadEnable:()=>Mu,setTouchGamepadFloating:()=>Ju,setTouchGamepadLeftButtonCount:()=>Bu,setTouchGamepadLeftStick:()=>ju,setTouchGamepadPassthrough:()=>ku,setTouchGamepadRightStick:()=>Nu,setTouchGamepadSize:()=>Uu,setTouchGamepadVibration:()=>qu,setTouchInputEnable:()=>Iu,setVibrateEnable:()=>Hu,shareURL:()=>$l,showSplashScreen:()=>ur,sign:()=>ne,sin:()=>st,smoothStep:()=>Ks,soundDefaultRange:()=>xr,soundDefaultTaper:()=>vr,soundEnable:()=>Ht,soundVolume:()=>Sn,speak:()=>Nh,speakStop:()=>zh,tan:()=>Ja,textureInfos:()=>cn,tile:()=>Ds,tileCollisionGetData:()=>li,tileCollisionLayers:()=>sn,tileCollisionRaycast:()=>yc,tileCollisionTest:()=>$e,tileDefaultBleed:()=>Di,tileDefaultPadding:()=>Oi,tileDefaultSize:()=>Li,tileLayersLoad:()=>Uh,tilesPixelated:()=>Tn,time:()=>Kt,timeDelta:()=>tr,timeReal:()=>on,timeScale:()=>cr,toggleFullscreen:()=>uh,touchGamepadAlpha:()=>br,touchGamepadAnalog:()=>Ls,touchGamepadButtonCount:()=>Yn,touchGamepadCenterButtonSize:()=>fe,touchGamepadDisplayTime:()=>as,touchGamepadEnable:()=>an,touchGamepadFloating:()=>ln,touchGamepadLeftButtonCount:()=>$n,touchGamepadLeftStick:()=>_n,touchGamepadPassthrough:()=>mr,touchGamepadRightStick:()=>Kn,touchGamepadSize:()=>qt,touchGamepadVibration:()=>ti,touchInputEnable:()=>yn,tweenProperty:()=>hd,tweenStopAll:()=>dd,tweenUpdate:()=>Dc,uiDebug:()=>Wr,uiSetDebug:()=>od,uiSystem:()=>E,usingGamepadInput:()=>mh,usingKeyboardInput:()=>yh,usingMouseInput:()=>gh,vec2:()=>b,vibrate:()=>Pr,vibrateEnable:()=>Os,vibrateStop:()=>Th,workCanvas:()=>Ne,workContext:()=>Ke,workReadCanvas:()=>Se,workReadContext:()=>je,worldToScreen:()=>Pn,worldToScreenDelta:()=>oh,writeSaveData:()=>Ql,zzfx:()=>Jh,zzfxG:()=>Gi,zzfxM:()=>Cc});function _l(){return Ae}function Rl(n=!0){Ae=n}function Cn(n,t,e,s){f(!bn.find(o=>o.update===n&&o.render===t&&o.glContextLost===e&&o.glContextRestored===s));let i=new uo(n,t,e,s);bn.push(i)}async function Pl(n,t,e,s,i,o=[],a){if(Da&&console.log(`${Hs} Engine v${Xs}`),f(!ut,"engine already initialized"),ut)return;f(de(o),"pass in images as array"),document.body||document.documentElement.appendChild(document.createElement("body")),a||(a=document.body),n||(n=()=>{}),t||(t=()=>{}),e||(e=()=>{}),s||(s=()=>{}),i||(i=()=>{});function r(){I=b(B.width,B.height),ut.imageSmoothingEnabled=!Tn,Eo()}function c(y=0){let x=y-ao;ao||(x=0),ao=y,(jt||Ri)&&(Ys=Wt(Ys,1e3/(x||1),.05));let v=jt&&It("Equal"),w=jt&&It("Minus"),_=v?10:w?.1:1;on+=x*_/1e3;let S=cr*_;x*=S,be+=Ae?0:x,S<=1&&(be=tt(be,50));let C=!1;if(Ae){C=!0,l(),Ea(),bn.forEach(T=>{var P;return(P=T.update)==null?void 0:P.call(T)});for(let T of vt)T.parent||T.updateTransforms();Sa(),e(),Ca(),Te()&&A()}else{let T=0;for(be<0&&be>-9&&(T=be,be=0);be>=0;be-=1e3/60)Kt=Oa++/60,C=!0,l(),Ea(),t(),bn.forEach(P=>{var M;return(M=P.update)==null?void 0:M.call(P)}),Ia(),Sa(),e(),Ca(),Te()&&A();be+=T}Te()||A(),requestAnimationFrame(c);function A(){if(!z){C||l(),r(),s(),vt.sort((T,P)=>T.renderOrder-P.renderOrder);for(let T of vt)T.destroyed||T.render();i(),bn.forEach(T=>{var P;return(P=T.render)==null?void 0:P.call(T)}),_h(),Fl(),Rt(),jl(),Ce=0,_e=0}}}function l(){if(!z){if(Gn.x){I=Gn.copy();let y=innerWidth/innerHeight,x=Gn.x/Gn.y,v=ykn){let C=I.y*kn|0;I.x=tt(C,Mn.x)}else if(w0&&!G&&(ut.fillStyle=tn.toString(),ut.fillRect(0,0,I.x,I.y),ut.fillStyle=it.toString()),ut.lineJoin="round",ut.lineCap="round"}}if(z)return d();qh(a);let u="margin:0;overflow:hidden;background:#000;user-select:none;-webkit-user-select:none;touch-action:none;-webkit-touch-callout:none";a.style.cssText=u,B=a.appendChild(document.createElement("canvas")),Et=ut=B.getContext("2d"),Ch(),Bh(),Gl();let h="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)";B.style.cssText=h,et&&(et.style.cssText=h),nc(lr),l(),Eo(),Ne=new OffscreenCanvas(64,64),Ke=Ne.getContext("2d"),Se=new OffscreenCanvas(64,64),je=Se.getContext("2d",{willReadFrequently:!0});let p=o.map((y,x)=>Ta(x,y));return o.length||p.push(Ta(0)),p.push(dh()),ur&&p.push(new Promise(y=>{let x=0;v();function v(){ks(),Qh(x+=.01),x>1?y():setTimeout(v,16)}})),await Promise.all(p),d();async function d(){await n(),c()}}function Ia(){er=vt.filter(t=>t.collideSolidObjects);function n(t){if(!t.destroyed){t.update();for(let e of t.children)n(e)}}for(let t of vt)if(!(t.parent||t.destroyed)){t.update(),t.updatePhysics();for(let e of t.children)n(e);t.updateTransforms()}vt=vt.filter(t=>!t.destroyed)}function Ll(n=!0){for(let t of vt)t.parent||t.destroy(n);vt=vt.filter(t=>!t.destroyed)}function Ma(n,t,e=vt){let s=[];if(n)if(t instanceof rt)for(let i of e)i.isOverlapping(n,t)&&s.push(i);else{let i=t*t;for(let o of e)n.distanceSquared(o.pos)e(i))}function Dl(n,t,e=vt){let s=[];for(let i of e)i.collideRaycast&&Va(n,t,i.pos,i.size)&&(he&&bt(i.pos,i.size,"#f00"),s.push(i));return he&&we(n,t,s.length?"#f00":"#00f",.02),s}function f(n,...t){if(!n)throw console.assert(n,...t),new Error("Assert failed!")}function xt(...n){console.log(...n)}function bt(n,t=b(),e=W,s=0,i=0,o=!1,a=!1){f(O(n),"pos must be a vec2"),f(O(t),"size must be a vec2"),f(V(e)||U(e),"color is invalid"),f(L(s),"time must be a number"),f(L(i),"angle must be a number"),U(e)&&(e=e.toString());let r=new Ee(s);Ze.push({pos:n.copy(),size:t.copy(),color:e,timer:r,angle:i,fill:o,screenSpace:a})}function Il(n,t,e=W,s=0,i=0,o=!1,a=!1){f(O(n),"pos must be a vec2"),f(de(t),"points must be an array"),f(V(e)||U(e),"color is invalid"),f(L(s),"time must be a number"),f(L(i),"angle must be a number"),U(e)&&(e=e.toString()),n=n.copy(),t=t.map(c=>c.copy());let r=new Ee(s);Ze.push({pos:n,points:t,color:e,timer:r,angle:i,fill:o,screenSpace:a})}function Ut(n,t=0,e=W,s=0,i=!1,o=!1){f(O(n),"pos must be a vec2"),f(L(t),"size must be a number"),f(V(e)||U(e),"color is invalid"),f(L(s),"time must be a number"),U(e)&&(e=e.toString()),n=n.copy();let a=new Ee(s);Ze.push({pos:n,size:t,color:e,timer:a,angle:0,fill:i,screenSpace:o})}function nr(n,t,e,s,i=!1){bt(n,void 0,t,e,s,!1,i)}function we(n,t,e,s=.1,i=0,o=!1){f(O(n),"posA must be a vec2"),f(O(t),"posB must be a vec2"),f(L(s),"width must be a number");let a=b((t.x-n.x)/2,(t.y-n.y)/2),r=b(s,a.length()*2);bt(n.add(a),r,e,i,a.angle(),!0,o)}function fo(n,t,e,s,i,o,a=!1){f(O(n),"posA must be a vec2"),f(O(e),"posB must be a vec2"),f(O(t),"sizeA must be a vec2"),f(O(s),"sizeB must be a vec2");let r=b(tt(n.x-t.x/2,e.x-s.x/2),tt(n.y-t.y/2,e.y-s.y/2)),c=b(K(n.x+t.x/2,e.x+s.x/2),K(n.y+t.y/2,e.y+s.y/2));bt(r.lerp(c,.5),c.subtract(r),i,o,0,!1,a)}function In(n,t,e=1,s=W,i=0,o=0,a="monospace",r=!1){f(V(n),"text must be a string"),f(O(t),"pos must be a vec2"),f(L(e),"size must be a number"),f(V(s)||U(s),"color is invalid"),f(L(i),"time must be a number"),f(L(o),"angle must be a number"),f(V(a),"font must be a string"),U(s)&&(s=s.toString()),t=t.copy();let c=new Ee(i);Ze.push({text:n,pos:t,size:e,color:s,timer:c,angle:o,font:a,screenSpace:r})}function Ml(){Ze=[]}function Fa(){ho=1}function kl(){let n=e=>{document.body.style="background-color:#111;margin:8px",document.body.innerHTML="
"+e},t=console.assert;console.assert=(e,...s)=>{if(t(e,...s),!e){let i=s.join(" "),o=new Error().stack;throw`Assertion failed!
+"use strict";var __GameBundle=(()=>{var zi=Object.defineProperty;var kc=Object.getOwnPropertyDescriptor;var Gc=Object.getOwnPropertyNames;var Fc=Object.prototype.hasOwnProperty;var jc=(n,t,e)=>()=>{if(e)throw e[0];try{return n&&(t=n(n=0)),t}catch(s){throw e=[s],s}};var Hr=(n,t)=>{for(var e in t)zi(n,e,{get:t[e],enumerable:!0})},Nc=(n,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Gc(t))!Fc.call(n,i)&&i!==e&&zi(n,i,{get:()=>t[i],enumerable:!(s=kc(t,i))||s.enumerable});return n};var Bc=n=>Nc(zi({},"__esModule",{value:!0}),n);var Ic={};Hr(Ic,{ASSERT:()=>p,BLACK:()=>ot,BLUE:()=>Za,Box2dDistanceJoint:()=>Ti,Box2dFrictionJoint:()=>$o,Box2dGearJoint:()=>qo,Box2dJoint:()=>$t,Box2dKinematicObject:()=>Bo,Box2dMotorJoint:()=>Qo,Box2dObject:()=>Rs,Box2dPinJoint:()=>Uo,Box2dPlugin:()=>Ai,Box2dPrismaticJoint:()=>Ho,Box2dPulleyJoint:()=>Ko,Box2dRaycastResult:()=>wi,Box2dRevoluteJoint:()=>Wo,Box2dRopeJoint:()=>Vo,Box2dStaticObject:()=>Si,Box2dTargetJoint:()=>Jo,Box2dTileLayer:()=>zo,Box2dWeldJoint:()=>Yo,Box2dWheelJoint:()=>Xo,CLEAR_BLACK:()=>ye,CLEAR_WHITE:()=>ln,CYAN:()=>ql,CanvasLayer:()=>ui,Color:()=>Et,Ease:()=>Ci,EngineObject:()=>qe,GRAY:()=>Vl,GREEN:()=>Qa,ImageFont:()=>ii,LOG:()=>St,Light:()=>Oo,LightSystemPlugin:()=>Lo,MAGENTA:()=>Hl,Medal:()=>xi,NewgroundsMedal:()=>_o,NewgroundsPlugin:()=>Ro,ORANGE:()=>Wl,PI:()=>Y,PURPLE:()=>tc,Particle:()=>hi,ParticleEmitter:()=>vo,PathFinder:()=>Zo,PathFinderNode:()=>_i,PostProcessPlugin:()=>Po,RED:()=>rr,RandomGenerator:()=>go,Sound:()=>xs,SoundInstance:()=>ci,TextureInfo:()=>He,TileCollisionLayer:()=>Ss,TileInfo:()=>Oe,TileLayer:()=>vs,TileLayerData:()=>En,Timer:()=>Re,Tween:()=>Ei,UIButton:()=>_s,UICheckbox:()=>Go,UILayout:()=>No,UIObject:()=>ce,UISlider:()=>Fo,UISystemPlugin:()=>Io,UIText:()=>vi,UITextInput:()=>Mo,UITile:()=>ko,UIVideo:()=>jo,Vector2:()=>ct,WHITE:()=>V,YELLOW:()=>Ka,ZzFXMusic:()=>Do,abs:()=>st,atan2:()=>sr,audioContext:()=>ft,audioDefaultSampleRate:()=>ts,audioIsRunning:()=>bs,audioMasterGain:()=>We,box2d:()=>m,box2dDebug:()=>qr,box2dInit:()=>ad,box2dSetDebug:()=>rd,cameraAngle:()=>tt,cameraFit:()=>rh,cameraPos:()=>Pt,cameraScale:()=>H,canvasClearColor:()=>sn,canvasColorTiles:()=>Pi,canvasFixedSize:()=>jn,canvasMaxAspect:()=>Fn,canvasMaxSize:()=>Gn,canvasMinAspect:()=>rs,canvasPixelRatio:()=>on,canvasPixelated:()=>lr,ceil:()=>hs,clamp:()=>j,combineCanvases:()=>wr,cos:()=>lt,debug:()=>Nt,debugCircle:()=>Wt,debugClear:()=>Ml,debugLine:()=>Ee,debugOverlap:()=>fo,debugOverlay:()=>Fe,debugPoint:()=>nr,debugPointSize:()=>ka,debugPoly:()=>Il,debugRect:()=>xt,debugScreenshot:()=>Fa,debugShowErrors:()=>kl,debugText:()=>kn,debugVideoCaptureIsActive:()=>Ce,debugVideoCaptureStart:()=>ja,debugVideoCaptureStop:()=>Na,debugWatermark:()=>Ri,distanceAngle:()=>zl,distanceWrap:()=>ir,drawCanvas2D:()=>On,drawCircle:()=>si,drawCircleGradient:()=>sh,drawContext:()=>_t,drawCount:()=>Pe,drawCrescent:()=>ud,drawEllipse:()=>ic,drawEllipseGradient:()=>oc,drawLine:()=>vn,drawLineList:()=>mo,drawNineSlice:()=>_c,drawNineSliceScreen:()=>cd,drawPoly:()=>Wn,drawRect:()=>ni,drawRectGradient:()=>th,drawRegularPoly:()=>sc,drawText:()=>ih,drawTextScreen:()=>rn,drawTextureWrapped:()=>eh,drawThreeSlice:()=>Rc,drawThreeSliceScreen:()=>ld,drawTile:()=>It,enablePhysicsSolver:()=>Ii,engineAddPlugin:()=>Pn,engineImageFont:()=>lc,engineInit:()=>Pl,engineName:()=>Hs,engineObjects:()=>wt,engineObjectsCallback:()=>Ol,engineObjectsCollect:()=>Ma,engineObjectsCollide:()=>er,engineObjectsDestroy:()=>Ll,engineObjectsRaycast:()=>Dl,engineObjectsUpdate:()=>Ia,engineVersion:()=>Xs,fetchJSON:()=>Xl,floor:()=>At,fontDefault:()=>Ps,formatTime:()=>ar,frame:()=>Oa,frameRate:()=>Cl,gamepadConnected:()=>xo,gamepadDirectionEmulateStick:()=>yr,gamepadDpad:()=>bo,gamepadIsDown:()=>Ge,gamepadPrimary:()=>bt,gamepadStick:()=>ys,gamepadStickCount:()=>uc,gamepadVibrate:()=>Sh,gamepadVibrateStop:()=>wh,gamepadWasPressed:()=>Rr,gamepadWasReleased:()=>vh,gamepadsEnable:()=>Mi,getCameraSize:()=>ac,getCrescentPoints:()=>Pc,getNoteFrequency:()=>gc,getPaused:()=>_l,glAntialias:()=>Mr,glCanvas:()=>nt,glCircleSides:()=>Ls,glClearCanvas:()=>vc,glClearRect:()=>Ec,glCompileShader:()=>Co,glContext:()=>g,glCopyToContext:()=>Nr,glCreateProgram:()=>$n,glCreateTexture:()=>ji,glDeleteTexture:()=>wc,glDraw:()=>As,glDrawColoredPoints:()=>Jr,glDrawOutlineTransform:()=>zr,glDrawPoints:()=>Ac,glDrawPointsTransform:()=>Br,glDrawUntextured:()=>Tc,glEnable:()=>G,glFlush:()=>Lt,glSetAntialias:()=>Yh,glSetRenderTarget:()=>os,glSetTexture:()=>Fr,glSetTextureData:()=>jr,glSetTextureWrap:()=>Sc,gravity:()=>qt,headlessMode:()=>B,hsl:()=>Ne,hypot:()=>Ba,inputClear:()=>Gs,inputClearKey:()=>Cr,inputMouseMoveThreshold:()=>Er,inputPreventDefault:()=>Nn,inputWASDEmulateDirection:()=>as,isArray:()=>pe,isColor:()=>J,isFullscreen:()=>cc,isIntersecting:()=>Va,isNumber:()=>R,isOnScreen:()=>ah,isOverlapping:()=>Qs,isPowerOfTwo:()=>ds,isStringLike:()=>U,isTouchDevice:()=>re,isUsingGamepad:()=>zn,isVector2:()=>O,keyDirection:()=>bh,keyIsDown:()=>Dt,keyWasPressed:()=>Ft,keyWasReleased:()=>_r,lastInputDevice:()=>en,lerp:()=>Ht,lerpAngle:()=>Jl,lerpWrap:()=>Ua,lightSystem:()=>q,lineTest:()=>qa,log2:()=>za,mainCanvas:()=>F,mainCanvasSize:()=>I,mainContext:()=>ut,max:()=>Q,medalDisplaySize:()=>mi,medalDisplaySlideTime:()=>Bn,medalDisplayTime:()=>yi,medals:()=>Es,medalsForEach:()=>Ni,medalsInit:()=>Zh,medalsPreventUnlock:()=>Ur,medalsReset:()=>td,min:()=>et,mod:()=>oe,mouseDelta:()=>Tr,mouseDeltaScreen:()=>we,mouseInWindow:()=>oi,mouseIsDown:()=>ls,mousePos:()=>ke,mousePosScreen:()=>Vt,mouseWasPressed:()=>gs,mouseWasReleased:()=>xh,mouseWheel:()=>Ar,nearestPowerOfTwo:()=>Ul,newgrounds:()=>Cs,noise1D:()=>Zl,noise2D:()=>tu,objectDefaultAngleDamping:()=>fr,objectDefaultDamping:()=>dr,objectDefaultFriction:()=>gr,objectDefaultMass:()=>hr,objectDefaultRestitution:()=>pr,objectMaxSpeed:()=>Be,oscillate:()=>Wa,particleEmitRateScale:()=>Zs,paused:()=>_e,percent:()=>Bt,percentLerp:()=>Bl,playSamples:()=>Ir,pointerLockExit:()=>Eh,pointerLockIsActive:()=>hc,pointerLockRequest:()=>Ah,postProcess:()=>Gt,primitiveCount:()=>Le,rand:()=>dt,randBool:()=>Ha,randColor:()=>po,randInCircle:()=>$a,randInt:()=>or,randSign:()=>Xa,randVec2:()=>Ya,readSaveData:()=>Kl,rgb:()=>z,round:()=>$s,saveCanvas:()=>ec,saveDataURL:()=>fs,saveText:()=>Yl,screenToWorld:()=>Ms,screenToWorldDelta:()=>rc,screenToWorldTransform:()=>ks,setAdditiveBlendMode:()=>ps,setCameraAngle:()=>nu,setCameraPos:()=>eu,setCameraScale:()=>su,setCanvasClearColor:()=>ru,setCanvasColorTiles:()=>ou,setCanvasFixedSize:()=>uu,setCanvasMaxAspect:()=>lu,setCanvasMaxSize:()=>au,setCanvasMinAspect:()=>cu,setCanvasPixelRatio:()=>du,setCanvasPixelated:()=>nc,setCursor:()=>hh,setDebugKey:()=>Zu,setDebugWatermark:()=>Qu,setEnablePhysicsSolver:()=>Su,setFontDefault:()=>fu,setGLCircleSides:()=>mu,setGLEnable:()=>yu,setGamepadDirectionEmulateStick:()=>Ou,setGamepadsEnable:()=>Lu,setGravity:()=>Ru,setHeadlessMode:()=>gu,setInputMouseMoveThreshold:()=>ph,setInputPreventDefault:()=>fh,setInputWASDEmulateDirection:()=>Du,setMedalDisplaySize:()=>sd,setMedalDisplaySlideTime:()=>nd,setMedalDisplayTime:()=>ed,setMedalsPreventUnlock:()=>id,setObjectDefaultAngleDamping:()=>Au,setObjectDefaultDamping:()=>Tu,setObjectDefaultFriction:()=>Cu,setObjectDefaultMass:()=>wu,setObjectDefaultRestitution:()=>Eu,setObjectMaxSpeed:()=>_u,setParticleEmitRateScale:()=>Pu,setPaused:()=>Rl,setShowSplashScreen:()=>pu,setSoundDefaultRange:()=>$u,setSoundDefaultTaper:()=>Ku,setSoundEnable:()=>Xu,setSoundVolume:()=>Yu,setTileDefaultBleed:()=>vu,setTileDefaultPadding:()=>xu,setTileDefaultSize:()=>bu,setTilesPixelated:()=>hu,setTimeScale:()=>iu,setTouchGamepadAlpha:()=>Vu,setTouchGamepadAnalog:()=>zu,setTouchGamepadButtonCount:()=>Fu,setTouchGamepadCenterButtonSize:()=>Gu,setTouchGamepadDisplayTime:()=>Wu,setTouchGamepadEnable:()=>Mu,setTouchGamepadFloating:()=>Ju,setTouchGamepadLeftButtonCount:()=>Nu,setTouchGamepadLeftStick:()=>ju,setTouchGamepadPassthrough:()=>ku,setTouchGamepadRightStick:()=>Bu,setTouchGamepadSize:()=>Uu,setTouchGamepadVibration:()=>qu,setTouchInputEnable:()=>Iu,setVibrateEnable:()=>Hu,shareURL:()=>$l,showSplashScreen:()=>ur,sign:()=>ie,sin:()=>it,smoothStep:()=>Ks,soundDefaultRange:()=>xr,soundDefaultTaper:()=>vr,soundEnable:()=>Yt,soundVolume:()=>An,speak:()=>Bh,speakStop:()=>zh,tan:()=>Ja,textureInfos:()=>hn,tile:()=>Is,tileCollisionGetData:()=>li,tileCollisionLayers:()=>an,tileCollisionRaycast:()=>yc,tileCollisionTest:()=>Ze,tileDefaultBleed:()=>Di,tileDefaultPadding:()=>Oi,tileDefaultSize:()=>Li,tileLayersLoad:()=>Uh,tilesPixelated:()=>Cn,time:()=>Zt,timeDelta:()=>tr,timeReal:()=>cn,timeScale:()=>cr,toggleFullscreen:()=>uh,touchGamepadAlpha:()=>br,touchGamepadAnalog:()=>Os,touchGamepadButtonCount:()=>Kn,touchGamepadCenterButtonSize:()=>ge,touchGamepadDisplayTime:()=>cs,touchGamepadEnable:()=>un,touchGamepadFloating:()=>dn,touchGamepadLeftButtonCount:()=>Qn,touchGamepadLeftStick:()=>Ln,touchGamepadPassthrough:()=>mr,touchGamepadRightStick:()=>Zn,touchGamepadSize:()=>Xt,touchGamepadVibration:()=>ti,touchInputEnable:()=>xn,tweenProperty:()=>hd,tweenStopAll:()=>dd,tweenUpdate:()=>Dc,uiDebug:()=>Wr,uiSetDebug:()=>od,uiSystem:()=>E,usingGamepadInput:()=>mh,usingKeyboardInput:()=>yh,usingMouseInput:()=>gh,vec2:()=>b,vibrate:()=>Pr,vibrateEnable:()=>Ds,vibrateStop:()=>Th,workCanvas:()=>Ue,workContext:()=>tn,workReadCanvas:()=>Ae,workReadContext:()=>ze,worldToScreen:()=>Dn,worldToScreenDelta:()=>oh,writeSaveData:()=>Ql,zzfx:()=>Jh,zzfxG:()=>Gi,zzfxM:()=>Cc});function _l(){return _e}function Rl(n=!0){_e=n}function Pn(n,t,e,s){p(!Sn.find(o=>o.update===n&&o.render===t&&o.glContextLost===e&&o.glContextRestored===s));let i=new uo(n,t,e,s);Sn.push(i)}async function Pl(n,t,e,s,i,o=[],a){if(Da&&console.log(`${Hs} Engine v${Xs}`),p(!ut,"engine already initialized"),ut)return;p(pe(o),"pass in images as array"),document.body||document.documentElement.appendChild(document.createElement("body")),a||(a=document.body),n||(n=()=>{}),t||(t=()=>{}),e||(e=()=>{}),s||(s=()=>{}),i||(i=()=>{});function r(){I=b(F.width,F.height),ut.imageSmoothingEnabled=!Cn,Eo()}function c(y=0){let x=y-ao;ao||(x=0),ao=y,(Nt||Ri)&&(Ys=Ht(Ys,1e3/(x||1),.05));let v=Nt&&Dt("Equal"),w=Nt&&Dt("Minus"),_=v?10:w?.1:1;cn+=x*_/1e3;let S=cr*_;x*=S,Se+=_e?0:x,S<=1&&(Se=et(Se,50));let C=!1;if(_e){C=!0,l(),Ea(),Sn.forEach(T=>{var P;return(P=T.update)==null?void 0:P.call(T)});for(let T of wt)T.parent||T.updateTransforms();Sa(),e(),Ca(),Ce()&&A()}else{let T=0;for(Se<0&&Se>-9&&(T=Se,Se=0);Se>=0;Se-=1e3/60)Zt=Oa++/60,C=!0,l(),Ea(),t(),Sn.forEach(P=>{var k;return(k=P.update)==null?void 0:k.call(P)}),Ia(),Sa(),e(),Ca(),Ce()&&A();Se+=T}Ce()||A(),requestAnimationFrame(c);function A(){if(!B){C||l(),r(),s(),wt.sort((T,P)=>T.renderOrder-P.renderOrder);for(let T of wt)T.destroyed||T.render();i(),Sn.forEach(T=>{var P;return(P=T.render)==null?void 0:P.call(T)}),_h(),Fl(),Lt(),jl(),Pe=0,Le=0}}}function l(){if(!B){if(jn.x){I=jn.copy();let y=innerWidth/innerHeight,x=jn.x/jn.y,v=yFn){let C=I.y*Fn|0;I.x=et(C,Gn.x)}else if(w0&&!G&&(ut.fillStyle=sn.toString(),ut.fillRect(0,0,I.x,I.y),ut.fillStyle=ot.toString()),ut.lineJoin="round",ut.lineCap="round"}}if(B)return f();qh(a);let u="margin:0;overflow:hidden;background:#000;user-select:none;-webkit-user-select:none;touch-action:none;-webkit-touch-callout:none";a.style.cssText=u,F=a.appendChild(document.createElement("canvas")),_t=ut=F.getContext("2d"),Ch(),Nh(),Gl();let h="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)";F.style.cssText=h,nt&&(nt.style.cssText=h),nc(lr),l(),Eo(),Ue=new OffscreenCanvas(64,64),tn=Ue.getContext("2d"),Ae=new OffscreenCanvas(64,64),ze=Ae.getContext("2d",{willReadFrequently:!0});let d=o.map((y,x)=>Ta(x,y));return o.length||d.push(Ta(0)),d.push(dh()),ur&&d.push(new Promise(y=>{let x=0;v();function v(){Gs(),Qh(x+=.01),x>1?y():setTimeout(v,16)}})),await Promise.all(d),f();async function f(){await n(),c()}}function Ia(){er=wt.filter(t=>t.collideSolidObjects);function n(t){if(!t.destroyed){t.update();for(let e of t.children)n(e)}}for(let t of wt)if(!(t.parent||t.destroyed)){t.update(),t.updatePhysics();for(let e of t.children)n(e);t.updateTransforms()}wt=wt.filter(t=>!t.destroyed)}function Ll(n=!0){for(let t of wt)t.parent||t.destroy(n);wt=wt.filter(t=>!t.destroyed)}function Ma(n,t,e=wt){let s=[];if(n)if(t instanceof ct)for(let i of e)i.isOverlapping(n,t)&&s.push(i);else{let i=t*t;for(let o of e)n.distanceSquared(o.pos)e(i))}function Dl(n,t,e=wt){let s=[];for(let i of e)i.collideRaycast&&Va(n,t,i.pos,i.size)&&(fe&&xt(i.pos,i.size,"#f00"),s.push(i));return fe&&Ee(n,t,s.length?"#f00":"#00f",.02),s}function p(n,...t){if(!n)throw console.assert(n,...t),new Error("Assert failed!")}function St(...n){console.log(...n)}function xt(n,t=b(),e=V,s=0,i=0,o=!1,a=!1){p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(U(e)||J(e),"color is invalid"),p(R(s),"time must be a number"),p(R(i),"angle must be a number"),J(e)&&(e=e.toString());let r=new Re(s);nn.push({pos:n.copy(),size:t.copy(),color:e,timer:r,angle:i,fill:o,screenSpace:a})}function Il(n,t,e=V,s=0,i=0,o=!1,a=!1){p(O(n),"pos must be a vec2"),p(pe(t),"points must be an array"),p(U(e)||J(e),"color is invalid"),p(R(s),"time must be a number"),p(R(i),"angle must be a number"),J(e)&&(e=e.toString()),n=n.copy(),t=t.map(c=>c.copy());let r=new Re(s);nn.push({pos:n,points:t,color:e,timer:r,angle:i,fill:o,screenSpace:a})}function Wt(n,t=0,e=V,s=0,i=!1,o=!1){p(O(n),"pos must be a vec2"),p(R(t),"size must be a number"),p(U(e)||J(e),"color is invalid"),p(R(s),"time must be a number"),J(e)&&(e=e.toString()),n=n.copy();let a=new Re(s);nn.push({pos:n,size:t,color:e,timer:a,angle:0,fill:i,screenSpace:o})}function nr(n,t,e,s,i=!1){xt(n,void 0,t,e,s,!1,i)}function Ee(n,t,e,s=.1,i=0,o=!1){p(O(n),"posA must be a vec2"),p(O(t),"posB must be a vec2"),p(R(s),"width must be a number");let a=b((t.x-n.x)/2,(t.y-n.y)/2),r=b(s,a.length()*2);xt(n.add(a),r,e,i,a.angle(),!0,o)}function fo(n,t,e,s,i,o,a=!1){p(O(n),"posA must be a vec2"),p(O(e),"posB must be a vec2"),p(O(t),"sizeA must be a vec2"),p(O(s),"sizeB must be a vec2");let r=b(et(n.x-t.x/2,e.x-s.x/2),et(n.y-t.y/2,e.y-s.y/2)),c=b(Q(n.x+t.x/2,e.x+s.x/2),Q(n.y+t.y/2,e.y+s.y/2));xt(r.lerp(c,.5),c.subtract(r),i,o,0,!1,a)}function kn(n,t,e=1,s=V,i=0,o=0,a="monospace",r=!1){p(U(n),"text must be a string"),p(O(t),"pos must be a vec2"),p(R(e),"size must be a number"),p(U(s)||J(s),"color is invalid"),p(R(i),"time must be a number"),p(R(o),"angle must be a number"),p(U(a),"font must be a string"),J(s)&&(s=s.toString()),t=t.copy();let c=new Re(i);nn.push({text:n,pos:t,size:e,color:s,timer:c,angle:o,font:a,screenSpace:r})}function Ml(){nn=[]}function Fa(){ho=1}function kl(){let n=e=>{document.body.style="background-color:#111;margin:8px",document.body.innerHTML="
"+e},t=console.assert;console.assert=(e,...s)=>{if(t(e,...s),!e){let i=s.join(" "),o=new Error().stack;throw`Assertion failed!
 `+i+`
 `+o}},onunhandledrejection=e=>n(e.reason.stack||e.reason),onerror=(e,s,i,o)=>n(`${e}
 ${s}
-Ln ${i}, Col ${o}`)}function Gl(){Da&&console.warn("LittleJS DEBUG build loaded. Use the release build for production.")}function Sa(){jt&&(Gt(Ga)&&(Me=!Me),Me&&(Gt("Digit1")&&(ue=!ue,xn=!1),Gt("Digit2")&&(xn=!xn,ue=!1),Gt("Digit3")&&(vn=!vn),Gt("Digit4")&&(he=!he),Gt("Digit5")&&Fa(),Gt("Digit7")&&(Jn=!Jn)),Te()?(!Me||Gt("Digit6"))&&Ba():Me&&Gt("Digit6")&&ja())}function Fl(){if(Te())return;Rt();let n=Ce,t=_e;ho&&(wr(),ec(B),ho=0);let e=ut;if(vn&&Mi){let o=0;for(let a=0;a<8;a++)xo(a)&&o++;for(let a=0;a<8;a++){if(!xo(a))continue;let r=1,c=.2,l=_t.add(b(-r*2,((o-1)/2-a)*r*3));In(a,l.add(b(-r,r)),1),a===mt&&In("Main",l.add(b(-r*2,0)),1,"#0f0");let u=ve[a].length;for(let p=0;p{e.save();let o=i.pos,a=1,r=i.angle;if(i.screenSpace||(o=Pn(i.pos),a=H,r-=Q),e.translate(o.x|0,o.y|0),e.rotate(r),e.scale(1,i.text?1:-1),e.fillStyle=i.color,e.strokeStyle=i.color,i.text!==void 0)e.font=i.size*a+"px "+i.font,e.textAlign="center",e.textBaseline="middle",e.fillText(i.text,0,0);else if(i.points!==void 0){e.beginPath();for(let c of i.points){let l=c.scale(a).floor();e.lineTo(l.x,l.y)}e.closePath(),i.fill&&e.fill(),e.stroke()}else if(i.size===0||i.size.x===0&&i.size.y===0){let c=ka*a;e.fillRect(-c/2,-1,c,3),e.fillRect(-1,-c/2,3,c)}else if(i.size.x!==void 0){let c=i.size.scale(a).floor(),l=c.x,u=c.y;i.fill&&e.fillRect(-l/2|0,-u/2|0,l,u),e.strokeRect(-l/2|0,-u/2|0,l,u)}else e.beginPath(),e.arc(0,0,i.size*a/2,0,9),i.fill&&e.fill(),e.stroke();e.restore()}),Ze=Ze.filter(i=>i.timer<0),s){let i=yc(s.pos,De);i&&ni(i.floor().add(b(.5)),b(1),J(0,1,1,.3),0,!1),mn(De,s.pos,.1,i?J(1,0,0,.5):J(0,1,0,.5),void 0,void 0,!1);let o="mouse pos = "+De;sn.length&&(o+=`
-mouse collision = `+li(De)),o+=`
+Ln ${i}, Col ${o}`)}function Gl(){Da&&console.warn("LittleJS DEBUG build loaded. Use the release build for production.")}function Sa(){Nt&&(Ft(Ga)&&(Fe=!Fe),Fe&&(Ft("Digit1")&&(de=!de,wn=!1),Ft("Digit2")&&(wn=!wn,de=!1),Ft("Digit3")&&(Tn=!Tn),Ft("Digit4")&&(fe=!fe),Ft("Digit5")&&Fa(),Ft("Digit7")&&(Vn=!Vn)),Ce()?(!Fe||Ft("Digit6"))&&Na():Fe&&Ft("Digit6")&&ja())}function Fl(){if(Ce())return;Lt();let n=Pe,t=Le;ho&&(wr(),ec(F),ho=0);let e=ut;if(Tn&&Mi){let o=0;for(let a=0;a<8;a++)xo(a)&&o++;for(let a=0;a<8;a++){if(!xo(a))continue;let r=1,c=.2,l=Pt.add(b(-r*2,((o-1)/2-a)*r*3));kn(a,l.add(b(-r,r)),1),a===bt&&kn("Main",l.add(b(-r*2,0)),1,"#0f0");let u=Te[a].length;for(let d=0;d{e.save();let o=i.pos,a=1,r=i.angle;if(i.screenSpace||(o=Dn(i.pos),a=H,r-=tt),e.translate(o.x|0,o.y|0),e.rotate(r),e.scale(1,i.text?1:-1),e.fillStyle=i.color,e.strokeStyle=i.color,i.text!==void 0)e.font=i.size*a+"px "+i.font,e.textAlign="center",e.textBaseline="middle",e.fillText(i.text,0,0);else if(i.points!==void 0){e.beginPath();for(let c of i.points){let l=c.scale(a).floor();e.lineTo(l.x,l.y)}e.closePath(),i.fill&&e.fill(),e.stroke()}else if(i.size===0||i.size.x===0&&i.size.y===0){let c=ka*a;e.fillRect(-c/2,-1,c,3),e.fillRect(-1,-c/2,3,c)}else if(i.size.x!==void 0){let c=i.size.scale(a).floor(),l=c.x,u=c.y;i.fill&&e.fillRect(-l/2|0,-u/2|0,l,u),e.strokeRect(-l/2|0,-u/2|0,l,u)}else e.beginPath(),e.arc(0,0,i.size*a/2,0,9),i.fill&&e.fill(),e.stroke();e.restore()}),nn=nn.filter(i=>i.timer<0),s){let i=yc(s.pos,ke);i&&ni(i.floor().add(b(.5)),b(1),z(0,1,1,.3),0,!1),vn(ke,s.pos,.1,i?z(1,0,0,.5):z(0,1,0,.5),void 0,void 0,!1);let o="mouse pos = "+ke;an.length&&(o+=`
+mouse collision = `+li(ke)),o+=`
 
 --- object info ---
-`,o+=s.toString(),nn(o,Jt,24,J(),.05,void 0,"center","monospace")}{e.save(),e.fillStyle="#fff",e.textAlign="left",e.textBaseline="top",e.font="20px monospace",e.shadowColor="#000",e.shadowBlur=9;let a=9,r=0,c=24;if(Me){e.fillText(`${Hs} v${Xs}`,a,r+=c/2),e.fillText("Time: "+ar(Kt),a,r+=c),e.fillText("FPS: "+Ys.toFixed(1)+(G?" WebGL":" Canvas2D"),a,r+=c),e.fillText("Objects: "+vt.length,a,r+=c),e.fillText("Draw Calls: "+Ce,a,r+=c),e.fillText("Primitives: "+_e,a,r+=c),e.fillText("---------",a,r+=c),e.fillStyle="#f00",e.fillText("ESC: Debug Overlay",a,r+=c),e.fillStyle=ue?"#f00":"#fff",e.fillText("1: Debug Physics",a,r+=c),e.fillStyle=xn?"#f00":"#fff",e.fillText("2: Debug Particles",a,r+=c),e.fillStyle=vn?"#f00":"#fff",e.fillText("3: Debug Gamepads",a,r+=c),e.fillStyle=he?"#f00":"#fff",e.fillText("4: Debug Raycasts",a,r+=c),e.fillStyle="#fff",e.fillText("5: Save Screenshot",a,r+=c),e.fillText("6: Toggle Video Capture",a,r+=c),e.fillStyle=Jn?"#f00":"#fff",e.fillText("7: Debug Sound",a,r+=c);let l="",u="";for(let h in Y[0])It(h,0)&&(parseInt(h)<3?u+=h+" ":l+=h+" ");u&&e.fillText("Mouse: "+u,a,r+=c),l&&e.fillText("Keys: "+l,a,r+=c);for(let h=1;hs.push(r.data),i.onstop=()=>{let r=new Blob(s,{type:"video/webm"}),c=URL.createObjectURL(r);ds(c,"capture.webm",1e3)};let o,a;if(Ht){a=new ConstantSourceNode(ft,{offset:0}),a.connect(Je),a.start(),o=ft.createMediaStreamDestination(),Je.connect(o);for(let r of o.stream.getAudioTracks())n.addTrack(r)}try{i.start()}catch{xt("Video capture not supported in this browser!"),a==null||a.stop();return}xt("Video capture started."),ke={mediaRecorder:i,captureTimer:e,videoTrack:t,silentAudioSource:a,audioStreamDestination:o}}function Ba(){var n,t,e;f(Te(),"Not capturing video!"),xt(`Video capture ended. ${ke.captureTimer.get().toFixed(2)} seconds recorded.`),le.style.display="none",(n=ke.silentAudioSource)==null||n.stop(),(t=ke.mediaRecorder)==null||t.stop(),(e=ke.videoTrack)==null||e.stop(),ke=void 0}function Bl(){f(Te(),"Not capturing video!"),wr(),ke.videoTrack.requestFrame(),le.textContent="\u25CF REC "+ar(ke.captureTimer)}function Zt(n){if(jt){let t=Object.keys(n),e={};t.forEach(s=>e[s]=n[s]),t.forEach(s=>{Object.defineProperty(n,s,{get:()=>e[s],set:i=>{f(!1,`Cannot modify engine constant. Attempted to set constant (${n}) property '${s}' to '${i}'.`)},enumerable:!0})})}return Object.freeze(n)}function se(n,t=1){return(n%t+t)%t}function N(n,t=0,e=1){return ne?e:n}function Bt(n,t,e){return(e-=t)?N((n-t)/e):0}function Wt(n,t,e){return n+N(e)*(t-n)}function Nl(n,t,e,s,i){return Wt(s,i,Bt(n,t,e))}function ir(n,t,e=1){f(e>0,"distanceWrap wrapSize must be > 0");let s=(n-t)%e;return s*2%e-s}function Ua(n,t,e,s=1){return n+N(e)*ir(t,n,s)}function zl(n,t){return ir(n,t,2*X)}function Jl(n,t,e){return Ua(n,t,e,2*X)}function Ks(n){return n*n*(3-2*n)}function hs(n){return!(n&n-1)}function Ul(n){return 2**us(za(n))}function Qs(n,t,e,s=b()){let i=(n.x-e.x)*2,o=(n.y-e.y)*2,a=t.x+s.x,r=t.y+s.y;return nt(i)p)return!1;h=K(y,h)}else{if(y0?r.x+1:r.x,x=h>0?r.y+1:r.y,v=c?(y-n.x)/c:1/0,w=l?(x-n.y)/l:1/0,_=0,S=v,C=w,A=pr.x&&(T.x=r.x+1-P),M.yr.y&&(T.y=r.y+1-P),s&&(A?s.set(-u,0):s.set(0,-h)),T}(A=SURL.revokeObjectURL(n),e)}function $l(n,t,e){var s;f(V(n),"shareURL requires title string"),f(V(t),"shareURL requires url string"),(s=navigator.share)==null||s.call(navigator,{title:n,url:t}).then(()=>e==null?void 0:e())}function Kl(n,t){f(V(n),"loadData requires saveName string");let e={};try{let s=localStorage[n];if(s)try{e=JSON.parse(s)}catch{xt("readSaveData: corrupt JSON for",n,"\u2014 using defaults")}}catch{xt("readSaveData: localStorage unavailable \u2014 using defaults")}return{...t,...e}}function Ql(n,t){f(V(n),"saveData requires saveName string");try{localStorage[n]=JSON.stringify(t)}catch{xt("writeSaveData: failed to write",n)}}function yo(n){let t=(n|0)^2654435769;return t=Math.imul(t^t>>>16,2246822507),t=Math.imul(t^t>>>13,3266489909),t^=t>>>16,(t>>>0)/2**32}function Zl(n){let t=St(n);return Wt(yo(t),yo(t+1),Ks(n-t))}function tu(n,t){let e=St(n),s=St(t),i=Ks(n-e),o=Ks(t-s),a=(r,c)=>yo(r+c*374761393);return Wt(Wt(a(e,s),a(e+1,s),i),Wt(a(e,s+1),a(e+1,s+1),i),o)}function eu(n){_t=n.copy()}function nu(n){Q=n}function su(n){H=n}function iu(n){cr=n}function ou(n){Pi=n}function ru(n){tn=n.copy()}function au(n){Mn=n.copy()}function cu(n){os=n}function lu(n){kn=n}function uu(n){Gn=n.copy()}function nc(n){lr=n,B&&(B.style.imageRendering=n?"pixelated":""),et&&(et.style.imageRendering=n?"pixelated":"")}function hu(n){Tn=n}function du(n){en=n}function fu(n){Rs=n}function pu(n){ur=n}function gu(n){z=n}function yu(n){if(n&&!Ao){console.warn("Can not enable WebGL if it was disabled on start.");return}G=n,et&&(et.style.display=n?"":"none")}function mu(n){Ps=n}function bu(n){Li=n.copy()}function xu(n){Oi=n}function vu(n){Di=n}function Su(n){Ii=n}function wu(n){hr=n}function Tu(n){dr=n}function Au(n){fr=n}function Eu(n){pr=n}function Cu(n){gr=n}function _u(n){Fe=n}function Ru(n){Vt=n.copy()}function Pu(n){Zs=n}function Lu(n){Mi=n}function Ou(n){yr=n}function Du(n){rs=n}function Iu(n){yn=n}function Mu(n){an=n}function ku(n){mr=n}function Gu(n){fe=n}function Fu(n){Yn=n,n>0&&(Kn=!1)}function ju(n){_n=n,n&&($n=0)}function Bu(n){$n=n,n>0&&(_n=!1)}function Nu(n){Kn=n,n&&(Yn=0)}function zu(n){Ls=n}function Ju(n){ln=n}function Uu(n){qt=n}function Vu(n){br=n}function Wu(n){as=n}function qu(n){ti=n}function Hu(n){Os=n}function Xu(n){Ht=n}function Yu(n){Sn=n,Ht&&!z&&Je&&(Je.gain.value=n)}function $u(n){xr=n}function Ku(n){vr=n}function Qu(n){Ri=n}function Zu(n){Ga=n}function ei(n){return n.r>=1&&n.g>=1&&n.b>=1}function Sr(n){return n.r<=0&&n.g<=0&&n.b<=0&&n.a<=0}function Ds(n=0,t=Li,e=0,s=Oi,i=Di){if(f(O(n)||typeof n=="number","index must be a vec2 or number"),f(O(t)||typeof t=="number","size must be a vec2 or number"),f(L(e)||e instanceof Ve,"texture must be a number or TextureInfo"),f(L(s),"padding must be a number"),z)return new Re;typeof t=="number"&&(f(t>0),t=new rt(t,t));let o=typeof e=="number"?cn[e]:e;f(o instanceof Ve,"tile texture is not loaded"),f(o.size.x>0,"tile texture is not loaded");let a=t.x+s*2,r=t.y+s*2,c,l;if(typeof n=="number"){let h=o.size.x/a|0;c=n%h,l=n/h|0}else c=n.x,l=n.y;let u=new rt(c*a+s,l*r+s);return new Re(u,t,o,s,i)}function Mt(n,t=b(1),e,s=W,i=0,o,a,r=G,c=!1,l){var p;f(O(n),"pos must be a vec2"),f(O(t),"size must be a vec2"),f(U(s),"color is invalid"),f(L(i),"angle must be a number"),f(!a||U(a),"additiveColor must be a color"),f(!l||!r,"context only supported in canvas 2D mode");let u=e==null?void 0:e.textureInfo,h=(p=e==null?void 0:e.bleed)!=null?p:0;if(r&&G)if(f(!!g,"WebGL is not enabled!"),c&&([n,t,i]=Ms(n,t,i)),u){let d=u.sizeInverse,y=e.pos.x*d.x,x=e.pos.y*d.y,v=e.size.x*d.x,w=e.size.y*d.y;if(Fr(u.glTexture),h){let _=d.x*h,S=d.y*h;Ts(n.x,n.y,o?-t.x:t.x,t.y,i,y+_,x+S,y-_+v,x-S+w,s.rgbaInt(),a&&a.rgbaInt())}else Ts(n.x,n.y,o?-t.x:t.x,t.y,i,y,x,y+v,x+w,s.rgbaInt(),a&&a.rgbaInt())}else{let d=a?s.add(a):s;Tc(n.x,n.y,t.x,t.y,i,d.rgbaInt())}else++Ce,++_e,Rn(n,t,i,o,d=>{if(u){d.scale(1,-1);let y=e.pos.x,x=e.pos.y,v=e.size.x,w=e.size.y;lh(d,u.image,y,x,v,w,-.5,-.5,1,1,s,a,h)}else{let y=a?s.add(a):s;d.fillStyle=y.toString(),d.fillRect(-.5,-.5,1,1)}},c,l)}function ni(n,t,e,s,i,o,a){Mt(n,t,void 0,e,s,!1,void 0,i,o,a)}function th(n,t,e=W,s=rn,i=0,o=G,a=!1,r){if(f(O(n),"pos must be a vec2"),f(O(t),"size must be a vec2"),f(U(e)&&U(s),"color is invalid"),f(L(i),"angle must be a number"),f(!r||!o,"context only supported in canvas 2D mode"),o&&G){f(!!g,"WebGL is not enabled!"),a&&(n=Is(n),t=t.scale(1/H),i+=Q);let c=[],l=[],u=t.x/2,h=t.y/2,p=e.rgbaInt(),d=s.rgbaInt(),y=lt(-i),x=st(-i);for(let v=4;v--;){let w=v&1?u:-u,_=v&2?h:-h,S=w*y-_*x,C=w*x+_*y,A=v&2?p:d;c.push(b(n.x+S,n.y+C)),l.push(A)}Jr(c,l)}else++Ce,++_e,Rn(n,t,i,!1,c=>{let l=c.createLinearGradient(0,.5,0,-.5);l.addColorStop(0,e.toString()),l.addColorStop(1,s.toString()),c.fillStyle=l,c.fillRect(-.5,-.5,1,1)},a,r)}function eh(n,t,e,s=0,i=W,o=0,a,r=G,c=!1,l){if(f(O(n),"pos must be a vec2"),f(O(t),"size must be a vec2"),f(O(e),"wrapCount must be a vec2"),f(U(i),"color is invalid"),f(L(o),"angle must be a number"),f(!a||U(a),"additiveColor must be a color"),f(!l||!r,"context only supported in canvas 2D mode"),f(!(s instanceof Re),"pass a TextureInfo or texture index, not a TileInfo \u2014 use tileInfo.textureInfo"),z)return;let u=typeof s=="number"?cn[s]:s;if(f(u instanceof Ve,"texture not loaded"),f(u.size.x>0,"texture not loaded"),f(u.wrap,"drawTextureWrapped requires a wrap-enabled texture; call textureInfo.setWrap(true) first"),r&&G){f(!!g,"WebGL is not enabled!"),c&&([n,t,o]=Ms(n,t,o)),Fr(u.glTexture),Ts(n.x,n.y,t.x,t.y,o,0,0,e.x,e.y,i.rgbaInt(),a&&a.rgbaInt());return}++Ce,++_e,c||(n=Pn(n),t=t.scale(H),o-=Q);let h=!Pi||(a?ei(i.add(a))&&a.a<=0:ei(i)),p=!h&&a&&!Sr(a),d=h?u.image:ch(u.image,i,a);l=l||Et,l.save(),l.translate(n.x+.5,n.y+.5),l.rotate(o),l.globalAlpha=p?1:i.a;let y=l.createPattern(d,"repeat"),x=new DOMMatrix().translate(-t.x/2,-t.y/2).scale(t.x/(e.x*d.width),t.y/(e.y*d.height));y.setTransform(x),l.fillStyle=y,l.fillRect(-t.x/2,-t.y/2,t.x,t.y),l.globalAlpha=1,l.restore()}function mo(n,t=.1,e=W,s=!1,i=b(),o=0,a=G,r=!1,c){if(f(de(n),"points must be an array"),f(L(t),"width must be a number"),f(U(e),"color is invalid"),f(O(i),"pos must be a vec2"),f(L(o),"angle must be a number"),f(!c||!a,"context only supported in canvas 2D mode"),a&&G){f(!!g,"WebGL is not enabled!");let l=b(1);r&&([i,l,o]=Ms(i,l,o)),zr(n,e.rgbaInt(),t,i.x,i.y,l.x,l.y,o,s)}else++Ce,++_e,Rn(i,b(1),o,!1,l=>{l.strokeStyle=e.toString(),l.lineWidth=t,l.beginPath();for(let u=0;u0&&zr(n,s.rgbaInt(),e,i.x,i.y,l.x,l.y,o)}else Rn(i,b(1),o,!1,l=>{l.fillStyle=t.toString(),l.beginPath();for(let u of n)l.lineTo(u.x,u.y);l.closePath(),l.fill(),e&&(l.strokeStyle=s.toString(),l.lineWidth=e,l.stroke())},r,c)}function ic(n,t=b(1),e=W,s=0,i=0,o=it,a=G,r=!1,c){f(O(n),"pos must be a vec2"),f(O(t),"size must be a vec2"),f(U(e)&&U(o),"color is invalid"),f(L(s),"angle must be a number"),f(L(i),"lineWidth must be a number"),f(i>=0,"lineWidth must be a positive value or 0"),f(!c||!a,"context only supported in canvas 2D mode"),i=N(i,0,tt(t.x,t.y)),a&&G?sc(n,t,Ps,e,i,o,s,a,r,c):Rn(n,b(1),s,!1,l=>{l.fillStyle=e.toString(),l.beginPath(),l.ellipse(0,0,t.x/2,t.y/2,0,0,9),l.fill(),i&&(l.strokeStyle=o.toString(),l.lineWidth=i,l.stroke())},r,c)}function si(n,t=1,e=W,s=0,i=it,o=G,a=!1,r){f(L(t),"size must be a number"),ic(n,b(t),e,0,s,i,o,a,r)}function oc(n,t=b(1),e=W,s=rn,i=0,o=G,a=!1,r){if(f(O(n),"pos must be a vec2"),f(O(t),"size must be a vec2"),f(U(e)&&U(s),"color is invalid"),f(L(i),"angle must be a number"),f(!r||!o,"context only supported in canvas 2D mode"),!z)if(o&&G){f(!!g,"WebGL is not enabled!"),a&&(n=Is(n),t=t.scale(1/H),i+=Q);let c=Ps,l=t.x/2,u=t.y/2,h=e.rgbaInt(),p=s.rgbaInt(),d=nh++,y=lt(-i),x=st(-i),v=C=>{let A=st(C)*l,T=lt(C)*u;return b(n.x+A*y-T*x,n.y+A*x+T*y)},w=d%c/c*X*2,_=[v(w)],S=[p];for(let C=c;C--;){let A=(C+d)%c/c*X*2;_.push(n),S.push(h),_.push(v(A)),S.push(p)}Jr(_,S)}else++Ce,++_e,Rn(n,t,i,!1,c=>{let l=c.createRadialGradient(0,0,0,0,0,.5);l.addColorStop(0,e.toString()),l.addColorStop(1,s.toString()),c.fillStyle=l,c.beginPath(),c.ellipse(0,0,.5,.5,0,0,9),c.fill()},a,r)}function sh(n,t=1,e=W,s=rn,i=G,o=!1,a){f(L(t),"size must be a number"),oc(n,b(t),e,s,0,i,o,a)}function Rn(n,t,e=0,s=!1,i,o=!1,a=Et){f(O(n),"pos must be a vec2"),f(O(t),"size must be a vec2"),f(L(e),"angle must be a number"),f(typeof i=="function","drawFunction must be a function"),o||(n=Pn(n),t=t.scale(H),e-=Q),a.save(),a.translate(n.x+.5,n.y+.5),a.rotate(e),a.scale(s?-t.x:t.x,-t.y),i(a),a.restore()}function ih(n,t,e=1,s=W,i=0,o=it,a="center",r=Rs,c="",l,u=0,h=Et){t=Pn(t),e*=H,i*=H,u-=Q,u*=-1,nn(n,t,e,s,i,o,a,r,c,l,u,h)}function nn(n,t,e,s=W,i=0,o=it,a="center",r=Rs,c="",l,u=0,h=Et){f(V(n),"text must be a string"),f(O(t),"pos must be a vec2"),f(L(e),"size must be a number"),f(U(s),"color must be a color"),f(L(i),"lineWidth must be a number"),f(U(o),"lineColor must be a color"),f(["left","center","right"].includes(a),"align must be left, center, or right"),f(V(r),"font must be a string"),f(V(c),"fontStyle must be a string"),f(L(u),"angle must be a number");let p=(n+"").split(`
-`),d=t.y-(p.length-1)*e/2;h.save(),h.fillStyle=s.toString(),h.strokeStyle=o.toString(),h.lineWidth=i,h.textAlign=a,h.font=c+" "+e+"px "+r,h.textBaseline="middle",h.translate(t.x,d),h.rotate(-u);let y=0;p.forEach(x=>{i&&h.strokeText(x,0,y,l),h.fillText(x,0,y,l),y+=e}),h.restore()}async function Ta(n,t){f(L(n),"textureIndex must be a number"),f(!cn[n],"textureIndex is already loaded!"),f(!t||V(t),"image src must be a string");let e=new Image;t&&await new Promise(s=>{e.onerror=e.onload=s,e.crossOrigin="anonymous",e.src=t}),cn[n]=new Ve(e)}function Is(n){f(O(n),"screenPos must be a vec2");let t=(n.x-I.x/2+.5)/H,e=(n.y-I.y/2+.5)/-H;if(Q){let s=lt(-Q),i=st(-Q),o=t*s-e*i,a=t*i+e*s;t=o,e=a}return new rt(t+_t.x,e+_t.y)}function Pn(n){f(O(n),"worldPos must be a vec2");let t=n.x-_t.x,e=n.y-_t.y;if(Q){let s=lt(Q),i=st(Q),o=t*s-e*i,a=t*i+e*s;t=o,e=a}return new rt(t*H+I.x/2-.5,e*-H+I.y/2-.5)}function rc(n){f(O(n),"screenDelta must be a vec2");let t=n.x/H,e=n.y/-H;if(Q){let s=lt(-Q),i=st(-Q),o=t*s-e*i,a=t*i+e*s;t=o,e=a}return new rt(t,e)}function oh(n){f(O(n),"worldDelta must be a vec2");let t=n.x,e=n.y;if(Q){let s=lt(Q),i=st(Q),o=t*s-e*i,a=t*i+e*s;t=o,e=a}return new rt(t*H,e*-H)}function Ms(n,t,e=0){return f(O(n),"screenPos must be a vec2"),f(O(t),"screenSize must be a vec2"),f(L(e),"screenAngle must be a number"),[Is(n),t.scale(1/H),e+Q]}function ac(){return I.scale(1/H)}function rh(n,t,e,s){f(O(n),"center must be a vec2"),f(O(t),"size must be a vec2");let i=p(e),o=p(s),a=t.x+i.left+i.right,r=t.y+i.top+i.bottom,c=I.x-o.left-o.right,l=I.y-o.top-o.bottom;if(!(a>0&&r>0&&c>0&&l>0))return H;H=tt(c/a,l/r);let u=b(i.right-i.left,i.top-i.bottom).scale(.5),h=b(o.right-o.left,o.top-o.bottom).scale(.5/H);return _t=n.add(u).add(h),H;function p(d){return(d===void 0||L(d))&&(d=b(d)),O(d)?{top:d.y,right:d.x,bottom:d.y,left:d.x}:{top:d.top||0,right:d.right||0,bottom:d.bottom||0,left:d.left||0}}}function ah(n,t=0){if(f(O(n),"pos must be a vec2"),f(O(t)||L(t),"size must be a vec2 or number"),!H)return!1;let e=n.x-_t.x,s=n.y-_t.y;if(Q){let a=lt(Q),r=st(Q),c=e*a-s*r,l=e*r+s*a;e=c,s=l}e*=H*2,s*=-H*2,t instanceof rt&&(t=t.length()),t*=H;let i=I.x,o=I.y;return e+t>-i&&e-t-o&&s-t{n.onerror=n.onload=r,n.crossOrigin="anonymous",n.src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUAAAAAeAQMAAABnrVXaAAAABlBMVEUAAAD///+l2Z/dAAAAAXRSTlMAQObYZgAAAjpJREFUOMu9kzFu2zAUhn+CAROgqrk+B2l0BWYxMjlXeYaAtFtbdA1sGgHqRQfI0CNkSG5AwYB0BQ8d5Bsomwah6CPVeGg6tEPzAxLwyI+P78cP4u9lNO9OoMKnLMOobG5020/yaj/MrRcCGh1gBbyiLTPJEYaIiom5KM9Jq7KgynMGtb6L4GL4MF2H4LQKCXTvDVw2I4MsgZT7QLExdiutH+D08VOP3INXRrWX1/mmpbkNgAPYRVANb4xpcegYvhiNbIXauQICEjBuYLfMakaakWQeXxiZ0VDtuJCKs3ztMV59QtsHJNcRxDzfdL21ty3PrfIcXTN+E+GFAv6T5nbT9jd50/WFxb5ksdAv49qS6ouymG66ji08UMT6moykYLAo+V0j23GN4m829ZySAD5K7QsBfQTvOG8eE+gTeGYRAmnNAubN3hf5Zv9tJWDHp/VTuaSm7SN4fyINQqaNO3RMVxvpSPXnOChnRNvFcGY0gnwiPswYwTKVPE0zVtX3mTEIOoFzaqLrGuJaV+Uqumb71fVk/VoOH3cdLNQP/FHi8hV0CQNoqBZsUPlLPMsdCJro9QAaQQ0woDy9BJm0eTxCFnO9srcYlhNVlfR2EyTrph1uUtbUtAJifwRgrKuYdXVHeb0YI3QpawohQHkloI3J5FuVwI5ORxC9k2Tuz9Ir1IjgeIPGMHYkAZe2RuYkmWFmt3gGbTPOmBUWVTmRmHtGrfpzG/yuQNOKa6gBB/WA9khitPgl6/GP+gl2Af6tCbvaygAAAABJRU5ErkJggg=="});let t=b(),e=b(8),s=1,i=0,o=new Ve(n),a=new Re(t,e,o,s,i);lc=new ii(a)}function fh(n=!0){Fn=n}function ph(n){Er=n}function gh(){return Qe==="mouse"}function yh(){return Qe==="keyboard"}function mh(){return Qe==="gamepad"}function Cr(n,t=0,e=!0,s=!0,i=!0){Y[t]&&(Y[t][n]&=~((e?1:0)|(s?2:0)|(i?4:0)))}function ks(){Y.length=0,Y[0]=[],oe.length=0,An.length=0,Gs.length=0,ve.length=0,pn.length=0}function It(n,t=0){var e;return f(V(n),"key must be a number or string"),f(t>0||typeof n!="number"||n<3,"use code string for keyboard"),!!(((e=Y[t])==null?void 0:e[n])&1)}function Gt(n,t=0){var e;return f(V(n),"key must be a number or string"),f(t>0||typeof n!="number"||n<3,"use code string for keyboard"),!!(((e=Y[t])==null?void 0:e[n])&2)}function _r(n,t=0){var e;return f(V(n),"key must be a number or string"),f(t>0||typeof n!="number"||n<3,"use code string for keyboard"),!!(((e=Y[t])==null?void 0:e[n])&4)}function bh(n="ArrowUp",t="ArrowDown",e="ArrowLeft",s="ArrowRight"){f(V(n),"up key must be a string"),f(V(t),"down key must be a string"),f(V(e),"left key must be a string"),f(V(s),"right key must be a string");let i=o=>It(o)?1:0;return b(i(s)-i(e),i(n)-i(t))}function cs(n){return f(L(n),"mouse button must be a number"),It(n)}function ps(n){return f(L(n),"mouse button must be a number"),Gt(n)}function xh(n){return f(L(n),"mouse button must be a number"),_r(n)}function Ie(n,t=mt){return f(L(n),"button must be a number"),f(L(t),"gamepad must be a number"),It(n,t+1)}function Rr(n,t=mt){return f(L(n),"button must be a number"),f(L(t),"gamepad must be a number"),Gt(n,t+1)}function vh(n,t=mt){return f(L(n),"button must be a number"),f(L(t),"gamepad must be a number"),_r(n,t+1)}function gs(n,t=mt){var e,s;return f(L(n),"stick must be a number"),f(L(t),"gamepad must be a number"),(s=(e=ve[t])==null?void 0:e[n])!=null?s:b()}function bo(n=mt){var t;return f(L(n),"gamepad must be a number"),(t=pn[n])!=null?t:b()}function xo(n=mt){return f(L(n),"gamepad must be a number"),!!Y[n+1]}function uc(n=mt){var t,e;return f(L(n),"gamepad must be a number"),(e=(t=ve[n])==null?void 0:t.length)!=null?e:0}function Sh(n=mt,t=200,e=1,s=1,i=0){var a,r,c;if(f(L(n),"gamepad must be a number"),!Os||z)return;let o=(a=navigator==null?void 0:navigator.getGamepads)==null?void 0:a.call(navigator)[n];(c=(r=o==null?void 0:o.vibrationActuator)==null?void 0:r.playEffect)==null||c.call(r,"dual-rumble",{duration:t,strongMagnitude:e,weakMagnitude:s,startDelay:i})}function wh(n=mt){var e,s,i;if(f(L(n),"gamepad must be a number"),!Os||z)return;let t=(e=navigator==null?void 0:navigator.getGamepads)==null?void 0:e.call(navigator)[n];(i=(s=t==null?void 0:t.vibrationActuator)==null?void 0:s.reset)==null||i.call(s)}function Pr(n=100){var t;f(L(n)||de(n),"pattern must be a number or array"),Os&&!z&&((t=navigator==null?void 0:navigator.vibrate)==null||t.call(navigator,n))}function Th(){Pr(0)}function Ah(){var n;!ie&&((n=B.requestPointerLock)==null||n.call(B))}function Eh(){var n;(n=document.exitPointerLock)==null||n.call(document)}function hc(){return document.pointerLockElement===B}function Ch(){if(z)return;document.addEventListener("keydown",n),document.addEventListener("keyup",t),document.addEventListener("mousedown",s),document.addEventListener("mouseup",i),document.addEventListener("mousemove",o),document.addEventListener("mouseleave",a),document.addEventListener("wheel",r,{passive:!1}),document.addEventListener("contextmenu",c),document.addEventListener("blur",l),ie&&yn&&u();function n(p){if(p.repeat||(Y[0][p.code]=3,rs&&(Y[0][e(p.code)]=3)),!Fn||!p.cancelable||!document.hasFocus()||p.ctrlKey||p.metaKey||p.altKey||x(p.target)||x(document.activeElement))return;let d=typeof p.key=="string"&&p.key.length===1;(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight","Space","Tab","Backspace"].includes(p.code)||d)&&p.preventDefault();function x(v){let w=v==null?void 0:v.tagName;return(v==null?void 0:v.isContentEditable)||["INPUT","TEXTAREA","SELECT"].includes(w)}}function t(p){Y[0][p.code]=Y[0][p.code]&2|4,rs&&(Y[0][e(p.code)]=4)}function e(p){return rs?p==="KeyW"?"ArrowUp":p==="KeyS"?"ArrowDown":p==="KeyA"?"ArrowLeft":p==="KeyD"?"ArrowRight":p:p}function s(p){if(ie&&yn)return;Ht&&!z&&ft&&!ms()&&ft.resume(),Y[0][p.button]=3;let d=Jt;Jt=h(b(p.x,p.y)),xe=xe.add(Jt.subtract(d)),Fn&&p.cancelable&&document.hasFocus()&&p.preventDefault()}function i(p){ie&&yn||(Y[0][p.button]=Y[0][p.button]&2|4)}function o(p){oi=!0;let d=Jt;Jt=h(b(p.x,p.y));let y=hc()?b(p.movementX,p.movementY):Jt.subtract(d);xe=xe.add(y)}function a(){oi=!1}function r(p){p.ctrlKey||(Ar+=ne(p.deltaY)),Fn&&p.cancelable&&document.hasFocus()&&p.preventDefault()}function c(p){p.preventDefault()}function l(){ks(),Be.clear(),oe.length=0,An.length=0,Gs.length=0}function u(){document.addEventListener("touchstart",y=>d(y),{passive:!1}),document.addEventListener("touchmove",y=>d(y),{passive:!1}),document.addEventListener("touchend",y=>d(y),{passive:!1});let p;function d(y){if(yn){if(Ht&&!z&&ft&&!ms()&&ft.resume(),!an||mr){let x=S=>ys.includes(S.target)||S.target===gn,v=[];for(let S of y.touches)x(S)||v.push(S);let w=v.length,_=0;if(w){let S=b(v[0].clientX,v[0].clientY),C=Jt;Jt=h(S),p?xe=xe.add(Jt.subtract(C)):Y[0][_]=3}else p&&(Y[0][_]=Y[0][_]&2|4);p=w}return Fn&&y.cancelable&&document.hasFocus()&&y.preventDefault(),!0}}}function h(p){let d=B.getBoundingClientRect(),y=Bt(p.x,d.left,d.right),x=Bt(p.y,d.top,d.bottom);return b(y*B.width,x*B.height)}}function Ea(){if(z)return;!(yn&&ie)&&!document.hasFocus()&&ks(),De=Is(Jt),Tr=rc(xe),Rh(),t(),n();function n(){let e=cs(0)||cs(1)||cs(2)||xe.length()>Er,s=!1;for(let o=uc();o--&&!s;)s=gs(o).lengthSquared()>.04;for(let o=17;o--&&!s;)s=Ie(o);let i=!1;for(let o in Y[0])if(isNaN(+o)&&Y[0][o]&1){i=!0;break}s?Qe="gamepad":e?Qe="mouse":i&&(Qe="keyboard"),Bn=Qe==="gamepad"}function t(){var a,r,c,l,u,h,p;let e=d=>{let v=w=>w>.3?Bt(w,.3,.8):w<-.3?-Bt(-w,.3,.8):0;return b(v(d.x),v(-d.y)).clampLength()};if(an&&ie){if(f(!_n||!$n,"set touchGamepadLeftStick or touchGamepadLeftButtonCount, not both"),f(!Kn||!Yn,"set touchGamepadRightStick or touchGamepadButtonCount, not both"),!Vn.isSet())return;mt=0;let d=(a=ve[0])!=null?a:ve[0]=[],y=(r=pn[0])!=null?r:pn[0]=b();d.length=0,y.set();for(let v=0;v<2;v++){if(!We(v))continue;let w=Dr(v);d[w]=b();let _=(c=An[v])!=null?c:b();if(Ls)d[w]=e(_);else if(_.lengthSquared()>.3){let S=N($s(_.x),-1,1),C=N($s(_.y),-1,1);d[w]=b(S,-C).clampLength(),w||y.set(S,-C)}}let x=(l=Y[1])!=null?l:Y[1]=[];for(let v=12;v--;){let w=Ie(v,0);x[v]=oe[v]?w?1:3:w?4:0,ti&&x[v]===3&&(v===9||Ph(v))&&Pr(ti)}return}try{if(!Mi||!(navigator!=null&&navigator.getGamepads))return}catch{return}if(!jt&&!document.hasFocus())return;let s=8,i=navigator.getGamepads(),o=tt(s,i.length);for(let d=0;d>1]=e(b(y.axes[S],y.axes[S+1]));let _=!1;for(let S=y.buttons.length;S--;){let C=y.buttons[S],A=Ie(S,d);x[S]=C.pressed?A?1:3:A?4:0,C.pressed&&(!C.value||C.value>.9)&&(_=!0)}_&&(co[d]=!0,co[mt]||(mt=d)),y.mapping==="standard"&&w.set((Ie(15,d)&&1)-(Ie(14,d)&&1),(Ie(12,d)&&1)-(Ie(13,d)&&1)),yr&&(w.x||w.y)&&(v[0]=w.clampLength())}an&&Bn&&Vn.unset()}}function Ca(){if(!z){for(let n of Y)for(let t in n)n[t]&=1;Ar=0,Tr=b(),xe=b()}}function _h(){Ih()}function Rh(){if(Ye||!an||!ie||z||!document.body)return;let n=Ye=document.createElement("div");n.style.cssText="position:fixed;inset:0;z-index:50;pointer-events:none;opacity:0;touch-action:none;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;transition:opacity .2s;box-sizing:border-box;padding:env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left)";let t=dc=document.createElement("div");t.style.cssText="position:relative;width:100%;height:100%;pointer-events:none",n.appendChild(t);let e=Lr=document.createElementNS(ai,"svg");e.style.cssText="position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible;fill:none;stroke:#fff;stroke-width:3",t.appendChild(e);let s=()=>{let i=document.createElement("div");return i.style.cssText="position:absolute;pointer-events:auto;touch-action:none",i.addEventListener("pointerdown",o=>Fh(o,i)),i.addEventListener("pointermove",o=>jh(o)),i.addEventListener("pointerup",o=>_a(o)),i.addEventListener("pointercancel",o=>_a(o)),t.appendChild(i),i};ys[0]=s(),ys[1]=s(),gn=s(),addEventListener("resize",()=>Wn=!0),document.body.appendChild(n),Wn=!0}function ki(){return dc.getBoundingClientRect()}function We(n){return n?Kn:_n}function Ln(n){return n?Yn:$n}function Or(n){return n?0:4}function Dr(n){return n&&_n?1:0}function qn(n){return We(n)||Ln(n)>0}function Ph(n){for(let t=0;t<2;t++){let e=Or(t);if(!We(t)&&n>=e&&no.style.cssText="position:absolute;pointer-events:auto;touch-action:none;"+a;if(Ae){for(let o of ys)o.style.display="none";fe?(i(gn,"inset:0"),gn.style.display=""):gn.style.display="none"}else{for(let a=0;a<2;a++){let r=ys[a],c=a?"right":"left";if(r.style.display=qn(a)?"":"none",ln){let l=qn(a?0:1)?"50%":"100%";i(r,`${c}:0;bottom:0;width:${l};height:60%`)}else i(r,`${c}:0;bottom:0;width:${3*s}px;height:${3*s}px`)}gn.style.display=fe?"":"none";let o=fe;i(gn,`left:50%;top:50%;width:${2*o}px;height:${2*o}px;transform:translate(-50%,-50%)`)}Oh(t,e),Wn=!1}function Oh(n,t){let e=Lr;for(;e.firstChild;)e.removeChild(e.firstChild);let s=fc={face:[],thumb:[]},i=qt,o=(r,c,l,u)=>{let h=document.createElementNS(ai,"circle");return h.setAttribute("cx",r),h.setAttribute("cy",c),h.setAttribute("r",l),u&&h.setAttribute("fill",u),e.appendChild(h),h},a=r=>{let c=i*.18,l=i*.5,u=r.x,h=r.y,p=document.createElementNS(ai,"path");p.setAttribute("d",`M ${u-c} ${h-l} H ${u+c} V ${h-c} H ${u+l} V ${h+c} H ${u+c} V ${h+l} H ${u-c} V ${h+c} H ${u-l} V ${h-c} H ${u-c} Z`),e.appendChild(p)};for(let r=0;r<2;r++){let c=Ln(r),l=Or(r),u=ze(r,n,t);if(We(r))Ls?o(u.x,u.y,i/2):a(u),s.thumb[r]=o(u.x,u.y,i/4,"#fff");else if(c===1)s.face[l]=o(u.x,u.y,i/2,"#000");else for(let h=0;h2?p:tt(p,c-1);d=d===3?2:d===2?3:d;let y=b().setDirection(p,i/2);c===2&&(y.x*=-1),r||(y.x*=-1);let x=u.add(y);s.face[l+d]=o(x.x,x.y,i/4,"#000")}}jt&&vn&&Dh(n,t)}function Dh(n,t){let e=qt,s=Lr,i=(a,r,c)=>{let l=document.createElementNS(ai,a);for(let u in r)l.setAttribute(u,r[u]);l.setAttribute("stroke",c),l.setAttribute("stroke-width",2),l.setAttribute("fill","none"),s.appendChild(l)},o=(a,r,c)=>i("circle",{cx:a.x,cy:a.y,r},c);i("line",{x1:n/2,y1:0,x2:n/2,y2:t},"#0f0");for(let a=0;a<2;a++)if(We(a))if(ln){let r=t*.4,c=!qn(a?0:1),l=c?0:a?n/2:0;i("rect",{x:l,y:r,width:c?n:n/2,height:t-r},"#0ff")}else o(ze(a,n,t),2*e,"#0ff");else Ln(a)>=1&&o(ze(a,n,t),e,"#0ff");if(fe){o(b(n/2,t/2),fe,"#ff0");for(let a=0;a<2;a++)qn(a)&&o(ze(a,n,t),2*e,"#f0f")}}function Ih(){var l;if(!Ye||z)return;if(!an||!ie){Ye.style.display!=="none"&&(Ye.style.display="none",Be.clear(),oe.length=0,An.length=0,Gs.length=0);return}Ye.style.display="";let n=jt&&vn,t=[Yn,$n,_n,Kn,Ls,qt,ln,fe,Ae,n].join();t!==Aa&&(Aa=t,Wn=!0),Wn&&Lh();let e=as?Bt(Vn.get(),as+1,as):1,s=n||Vn.isSet()&&e>0&&!Ae;if(Ye.style.opacity=s?n?1:e*br:0,!s)return;let i=ki(),o=i.width,a=i.height,r=qt,c=fc;if(c){for(let u=0;u<2;u++)if(We(u)&&c.thumb[u]){let p=ze(u,o,a).add(((l=An[u])!=null?l:b()).scale(r/2));c.thumb[u].setAttribute("cx",p.x),c.thumb[u].setAttribute("cy",p.y)}for(let u=0;u=qt)return-1;if(i===1)return o;let r=a.subtract(t);n||(r.x*=-1);let c=i===2?r.xo:r&&ze(a,t,e).distance(n)<2*s)return{role:"stick",side:a}}else if(Ln(a)>=1){let c=kh(a,n,t,e);if(c>=0)return{role:"face",btn:c}}}if(fe){for(let a=0;a<2;a++)if(qn(a)&&ze(a,t,e).distance(n)<2*s)return;if(b(t/2,e/2).distance(n)h.getChannelData(v).set(x)),p.buffer=h,p.playbackRate.value=e,p.loop=i,a=a||ft.createGain(),a.gain.value=t,a.connect(Je);let d=new StereoPannerNode(ft,{pan:N(s,-1,1)});p.connect(d).connect(a),p.addEventListener("ended",()=>{a.disconnect(),d.disconnect(),c&&c(p)});let y=r*e;return p.start(0,y),jt&&Jn&&xt("sound","vol",t.toFixed(2),"rate",e.toFixed(2),"pan",s.toFixed(2),i?"loop":""),p}function Jh(...n){return Ir([Gi(...n)])}function Gi(n=1,t=.05,e=220,s=0,i=0,o=.1,a=0,r=1,c=0,l=0,u=0,h=0,p=0,d=0,y=0,x=0,v=0,w=1,_=0,S=0,C=0){let A=Qn,T=X*2,P=c*=500*T/A/A,M=e*=(1+dt(t,-t))*T/A,pt=0,at=0,ct=0,yt=1,Nt,ge=[],Pt=0,ht=0,Lt=0,Pe,un=2,hn=T*nt(C)*2/A,ae=lt(hn),Le=st(hn)/2/un,te=1+Le,R=-2*ae/te,F=(1-Le)/te,k=(1+ne(C)*ae)/2/te,j=-(ne(C)+ae)/te,$=k,Z=0,Tt=0,At=0,Ot=0;for(s=s*A||9,_*=A,i*=A,o*=A,v*=A,l*=500*T/A**3,y*=T/A,u*=T/A,h*=A,p=p*A|0,Nt=s+_+i+o+v|0;ht1?a>2?a>3?a>4?Pt/T%14?Lt:ne(Lt)*nt(Lt)**r)*(htht?0:(hth&&(e+=u,M+=u,yt=0),p&&!(++at%p)&&(e=M,c=P,yt||(yt=1));return ge}function li(n,t=!0){for(let e of sn)if((!t||e.isSolid)&&n.arrayCheck(e.size)){let s=e.getCollisionData(n);if(s)return s}return 0}function $e(n,t=b(),e,s=!0){for(let i of sn)if((!s||i.isSolid)&&i.collisionTest(n,t,e))return i}function yc(n,t,e,s,i=!0){let o,a,r,c=s&&b();for(let l of sn)if(!i||l.isSolid){let u=l.collisionRaycast(n,t,e,c);if(u){let h=n.distanceSquared(u);(o===void 0||h{G=!1,et.style.display="none",e.preventDefault(),xt("WebGL context lost! Switching to Canvas2d rendering.");for(let s of ls)s.glTexture=void 0;Qt=void 0,Ct=0,En=!1,bn.forEach(s=>{var i;return(i=s.glContextLost)==null?void 0:i.call(s)})}),et.addEventListener("webglcontextrestored",()=>{G=!0,et.style.display="",xt("WebGL context restored, reinitializing..."),t();for(let e of ls)e.glTexture=ji(e.image,e.wrap);bn.forEach(e=>{var s;return(s=e.glContextRestored)==null?void 0:s.call(e)})});function t(){di=Xn(`#version 300 es
+`,o+=s.toString(),rn(o,Vt,24,z(),.05,void 0,"center","monospace")}{e.save(),e.fillStyle="#fff",e.textAlign="left",e.textBaseline="top",e.font="20px monospace",e.shadowColor="#000",e.shadowBlur=9;let a=9,r=0,c=24;if(Fe){e.fillText(`${Hs} v${Xs}`,a,r+=c/2),e.fillText("Time: "+ar(Zt),a,r+=c),e.fillText("FPS: "+Ys.toFixed(1)+(G?" WebGL":" Canvas2D"),a,r+=c),e.fillText("Objects: "+wt.length,a,r+=c),e.fillText("Draw Calls: "+Pe,a,r+=c),e.fillText("Primitives: "+Le,a,r+=c),e.fillText("---------",a,r+=c),e.fillStyle="#f00",e.fillText("ESC: Debug Overlay",a,r+=c),e.fillStyle=de?"#f00":"#fff",e.fillText("1: Debug Physics",a,r+=c),e.fillStyle=wn?"#f00":"#fff",e.fillText("2: Debug Particles",a,r+=c),e.fillStyle=Tn?"#f00":"#fff",e.fillText("3: Debug Gamepads",a,r+=c),e.fillStyle=fe?"#f00":"#fff",e.fillText("4: Debug Raycasts",a,r+=c),e.fillStyle="#fff",e.fillText("5: Save Screenshot",a,r+=c),e.fillText("6: Toggle Video Capture",a,r+=c),e.fillStyle=Vn?"#f00":"#fff",e.fillText("7: Debug Sound",a,r+=c);let l="",u="";for(let h in K[0])Dt(h,0)&&(parseInt(h)<3?u+=h+" ":l+=h+" ");u&&e.fillText("Mouse: "+u,a,r+=c),l&&e.fillText("Keys: "+l,a,r+=c);for(let h=1;hs.push(r.data),i.onstop=()=>{let r=new Blob(s,{type:"video/webm"}),c=URL.createObjectURL(r);fs(c,"capture.webm",1e3)};let o,a;if(Yt){a=new ConstantSourceNode(ft,{offset:0}),a.connect(We),a.start(),o=ft.createMediaStreamDestination(),We.connect(o);for(let r of o.stream.getAudioTracks())n.addTrack(r)}try{i.start()}catch{St("Video capture not supported in this browser!"),a==null||a.stop();return}St("Video capture started."),je={mediaRecorder:i,captureTimer:e,videoTrack:t,silentAudioSource:a,audioStreamDestination:o}}function Na(){var n,t,e;p(Ce(),"Not capturing video!"),St(`Video capture ended. ${je.captureTimer.get().toFixed(2)} seconds recorded.`),he.style.display="none",(n=je.silentAudioSource)==null||n.stop(),(t=je.mediaRecorder)==null||t.stop(),(e=je.videoTrack)==null||e.stop(),je=void 0}function Nl(){p(Ce(),"Not capturing video!"),wr(),je.videoTrack.requestFrame(),he.textContent="\u25CF REC "+ar(je.captureTimer)}function ee(n){if(Nt){let t=Object.keys(n),e={};t.forEach(s=>e[s]=n[s]),t.forEach(s=>{Object.defineProperty(n,s,{get:()=>e[s],set:i=>{p(!1,`Cannot modify engine constant. Attempted to set constant (${n}) property '${s}' to '${i}'.`)},enumerable:!0})})}return Object.freeze(n)}function oe(n,t=1){return(n%t+t)%t}function j(n,t=0,e=1){return ne?e:n}function Bt(n,t,e){return(e-=t)?j((n-t)/e):0}function Ht(n,t,e){return n+j(e)*(t-n)}function Bl(n,t,e,s,i){return Ht(s,i,Bt(n,t,e))}function ir(n,t,e=1){p(e>0,"distanceWrap wrapSize must be > 0");let s=(n-t)%e;return s*2%e-s}function Ua(n,t,e,s=1){return n+j(e)*ir(t,n,s)}function zl(n,t){return ir(n,t,2*Y)}function Jl(n,t,e){return Ua(n,t,e,2*Y)}function Ks(n){return n*n*(3-2*n)}function ds(n){return!(n&n-1)}function Ul(n){return 2**hs(za(n))}function Qs(n,t,e,s=b()){let i=(n.x-e.x)*2,o=(n.y-e.y)*2,a=t.x+s.x,r=t.y+s.y;return st(i)d)return!1;h=Q(y,h)}else{if(y0?r.x+1:r.x,x=h>0?r.y+1:r.y,v=c?(y-n.x)/c:1/0,w=l?(x-n.y)/l:1/0,_=0,S=v,C=w,A=dr.x&&(T.x=r.x+1-P),k.yr.y&&(T.y=r.y+1-P),s&&(A?s.set(-u,0):s.set(0,-h)),T}(A=SURL.revokeObjectURL(n),e)}function $l(n,t,e){var s;p(U(n),"shareURL requires title string"),p(U(t),"shareURL requires url string"),(s=navigator.share)==null||s.call(navigator,{title:n,url:t}).then(()=>e==null?void 0:e())}function Kl(n,t){p(U(n),"loadData requires saveName string");let e={};try{let s=localStorage[n];if(s)try{e=JSON.parse(s)}catch{St("readSaveData: corrupt JSON for",n,"\u2014 using defaults")}}catch{St("readSaveData: localStorage unavailable \u2014 using defaults")}return{...t,...e}}function Ql(n,t){p(U(n),"saveData requires saveName string");try{localStorage[n]=JSON.stringify(t)}catch{St("writeSaveData: failed to write",n)}}function yo(n){let t=(n|0)^2654435769;return t=Math.imul(t^t>>>16,2246822507),t=Math.imul(t^t>>>13,3266489909),t^=t>>>16,(t>>>0)/2**32}function Zl(n){let t=At(n);return Ht(yo(t),yo(t+1),Ks(n-t))}function tu(n,t){let e=At(n),s=At(t),i=Ks(n-e),o=Ks(t-s),a=(r,c)=>yo(r+c*374761393);return Ht(Ht(a(e,s),a(e+1,s),i),Ht(a(e,s+1),a(e+1,s+1),i),o)}function eu(n){Pt=n.copy()}function nu(n){tt=n}function su(n){H=n}function iu(n){cr=n}function ou(n){Pi=n}function ru(n){sn=n.copy()}function au(n){Gn=n.copy()}function cu(n){rs=n}function lu(n){Fn=n}function uu(n){jn=n.copy()}function nc(n){lr=n,F&&(F.style.imageRendering=n?"pixelated":""),nt&&(nt.style.imageRendering=n?"pixelated":"")}function hu(n){Cn=n}function du(n){on=n}function fu(n){Ps=n}function pu(n){ur=n}function gu(n){B=n}function yu(n){if(n&&!Ao){console.warn("Can not enable WebGL if it was disabled on start.");return}G=n,nt&&(nt.style.display=n?"":"none")}function mu(n){Ls=n}function bu(n){Li=n.copy()}function xu(n){Oi=n}function vu(n){Di=n}function Su(n){Ii=n}function wu(n){hr=n}function Tu(n){dr=n}function Au(n){fr=n}function Eu(n){pr=n}function Cu(n){gr=n}function _u(n){Be=n}function Ru(n){qt=n.copy()}function Pu(n){Zs=n}function Lu(n){Mi=n}function Ou(n){yr=n}function Du(n){as=n}function Iu(n){xn=n}function Mu(n){un=n}function ku(n){mr=n}function Gu(n){ge=n}function Fu(n){Kn=n,n>0&&(Zn=!1)}function ju(n){Ln=n,n&&(Qn=0)}function Nu(n){Qn=n,n>0&&(Ln=!1)}function Bu(n){Zn=n,n&&(Kn=0)}function zu(n){Os=n}function Ju(n){dn=n}function Uu(n){Xt=n}function Vu(n){br=n}function Wu(n){cs=n}function qu(n){ti=n}function Hu(n){Ds=n}function Xu(n){Yt=n}function Yu(n){An=n,Yt&&!B&&We&&(We.gain.value=n)}function $u(n){xr=n}function Ku(n){vr=n}function Qu(n){Ri=n}function Zu(n){Ga=n}function ei(n){return n.r>=1&&n.g>=1&&n.b>=1}function Sr(n){return n.r<=0&&n.g<=0&&n.b<=0&&n.a<=0}function Is(n=0,t=Li,e=0,s=Oi,i=Di){if(p(O(n)||typeof n=="number","index must be a vec2 or number"),p(O(t)||typeof t=="number","size must be a vec2 or number"),p(R(e)||e instanceof He,"texture must be a number or TextureInfo"),p(R(s),"padding must be a number"),B)return new Oe;typeof t=="number"&&(p(t>0),t=new ct(t,t));let o=typeof e=="number"?hn[e]:e;p(o instanceof He,"tile texture is not loaded"),p(o.size.x>0,"tile texture is not loaded");let a=t.x+s*2,r=t.y+s*2,c,l;if(typeof n=="number"){let h=o.size.x/a|0;c=n%h,l=n/h|0}else c=n.x,l=n.y;let u=new ct(c*a+s,l*r+s);return new Oe(u,t,o,s,i)}function It(n,t=b(1),e,s=V,i=0,o,a,r=G,c=!1,l){var d;p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(J(s),"color is invalid"),p(R(i),"angle must be a number"),p(!a||J(a),"additiveColor must be a color"),p(!l||!r,"context only supported in canvas 2D mode");let u=e==null?void 0:e.textureInfo,h=(d=e==null?void 0:e.bleed)!=null?d:0;if(r&&G)if(p(!!g,"WebGL is not enabled!"),c&&([n,t,i]=ks(n,t,i)),u){let f=u.sizeInverse,y=e.pos.x*f.x,x=e.pos.y*f.y,v=e.size.x*f.x,w=e.size.y*f.y;if(Fr(u.glTexture),h){let _=f.x*h,S=f.y*h;As(n.x,n.y,o?-t.x:t.x,t.y,i,y+_,x+S,y-_+v,x-S+w,s.rgbaInt(),a&&a.rgbaInt())}else As(n.x,n.y,o?-t.x:t.x,t.y,i,y,x,y+v,x+w,s.rgbaInt(),a&&a.rgbaInt())}else{let f=a?s.add(a):s;Tc(n.x,n.y,t.x,t.y,i,f.rgbaInt())}else++Pe,++Le,On(n,t,i,o,f=>{if(u){f.scale(1,-1);let y=e.pos.x,x=e.pos.y,v=e.size.x,w=e.size.y;lh(f,u.image,y,x,v,w,-.5,-.5,1,1,s,a,h)}else{let y=a?s.add(a):s;f.fillStyle=y.toString(),f.fillRect(-.5,-.5,1,1)}},c,l)}function ni(n,t,e,s,i,o,a){It(n,t,void 0,e,s,!1,void 0,i,o,a)}function th(n,t,e=V,s=ln,i=0,o=G,a=!1,r){if(p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(J(e)&&J(s),"color is invalid"),p(R(i),"angle must be a number"),p(!r||!o,"context only supported in canvas 2D mode"),o&&G){p(!!g,"WebGL is not enabled!"),a&&(n=Ms(n),t=t.scale(1/H),i+=tt);let c=[],l=[],u=t.x/2,h=t.y/2,d=e.rgbaInt(),f=s.rgbaInt(),y=lt(-i),x=it(-i);for(let v=4;v--;){let w=v&1?u:-u,_=v&2?h:-h,S=w*y-_*x,C=w*x+_*y,A=v&2?d:f;c.push(b(n.x+S,n.y+C)),l.push(A)}Jr(c,l)}else++Pe,++Le,On(n,t,i,!1,c=>{let l=c.createLinearGradient(0,.5,0,-.5);l.addColorStop(0,e.toString()),l.addColorStop(1,s.toString()),c.fillStyle=l,c.fillRect(-.5,-.5,1,1)},a,r)}function eh(n,t,e,s=0,i=V,o=0,a,r=G,c=!1,l){if(p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(O(e),"wrapCount must be a vec2"),p(J(i),"color is invalid"),p(R(o),"angle must be a number"),p(!a||J(a),"additiveColor must be a color"),p(!l||!r,"context only supported in canvas 2D mode"),p(!(s instanceof Oe),"pass a TextureInfo or texture index, not a TileInfo \u2014 use tileInfo.textureInfo"),B)return;let u=typeof s=="number"?hn[s]:s;if(p(u instanceof He,"texture not loaded"),p(u.size.x>0,"texture not loaded"),p(u.wrap,"drawTextureWrapped requires a wrap-enabled texture; call textureInfo.setWrap(true) first"),r&&G){p(!!g,"WebGL is not enabled!"),c&&([n,t,o]=ks(n,t,o)),Fr(u.glTexture),As(n.x,n.y,t.x,t.y,o,0,0,e.x,e.y,i.rgbaInt(),a&&a.rgbaInt());return}++Pe,++Le,c||(n=Dn(n),t=t.scale(H),o-=tt);let h=!Pi||(a?ei(i.add(a))&&a.a<=0:ei(i)),d=!h&&a&&!Sr(a),f=h?u.image:ch(u.image,i,a);l=l||_t,l.save(),l.translate(n.x+.5,n.y+.5),l.rotate(o),l.globalAlpha=d?1:i.a;let y=l.createPattern(f,"repeat"),x=new DOMMatrix().translate(-t.x/2,-t.y/2).scale(t.x/(e.x*f.width),t.y/(e.y*f.height));y.setTransform(x),l.fillStyle=y,l.fillRect(-t.x/2,-t.y/2,t.x,t.y),l.globalAlpha=1,l.restore()}function mo(n,t=.1,e=V,s=!1,i=b(),o=0,a=G,r=!1,c){if(p(pe(n),"points must be an array"),p(R(t),"width must be a number"),p(J(e),"color is invalid"),p(O(i),"pos must be a vec2"),p(R(o),"angle must be a number"),p(!c||!a,"context only supported in canvas 2D mode"),a&&G){p(!!g,"WebGL is not enabled!");let l=b(1);r&&([i,l,o]=ks(i,l,o)),zr(n,e.rgbaInt(),t,i.x,i.y,l.x,l.y,o,s)}else++Pe,++Le,On(i,b(1),o,!1,l=>{l.strokeStyle=e.toString(),l.lineWidth=t,l.beginPath();for(let u=0;u0&&zr(n,s.rgbaInt(),e,i.x,i.y,l.x,l.y,o)}else On(i,b(1),o,!1,l=>{l.fillStyle=t.toString(),l.beginPath();for(let u of n)l.lineTo(u.x,u.y);l.closePath(),l.fill(),e&&(l.strokeStyle=s.toString(),l.lineWidth=e,l.stroke())},r,c)}function ic(n,t=b(1),e=V,s=0,i=0,o=ot,a=G,r=!1,c){p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(J(e)&&J(o),"color is invalid"),p(R(s),"angle must be a number"),p(R(i),"lineWidth must be a number"),p(i>=0,"lineWidth must be a positive value or 0"),p(!c||!a,"context only supported in canvas 2D mode"),i=j(i,0,et(t.x,t.y)),a&&G?sc(n,t,Ls,e,i,o,s,a,r,c):On(n,b(1),s,!1,l=>{l.fillStyle=e.toString(),l.beginPath(),l.ellipse(0,0,t.x/2,t.y/2,0,0,9),l.fill(),i&&(l.strokeStyle=o.toString(),l.lineWidth=i,l.stroke())},r,c)}function si(n,t=1,e=V,s=0,i=ot,o=G,a=!1,r){p(R(t),"size must be a number"),ic(n,b(t),e,0,s,i,o,a,r)}function oc(n,t=b(1),e=V,s=ln,i=0,o=G,a=!1,r){if(p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(J(e)&&J(s),"color is invalid"),p(R(i),"angle must be a number"),p(!r||!o,"context only supported in canvas 2D mode"),!B)if(o&&G){p(!!g,"WebGL is not enabled!"),a&&(n=Ms(n),t=t.scale(1/H),i+=tt);let c=Ls,l=t.x/2,u=t.y/2,h=e.rgbaInt(),d=s.rgbaInt(),f=nh++,y=lt(-i),x=it(-i),v=C=>{let A=it(C)*l,T=lt(C)*u;return b(n.x+A*y-T*x,n.y+A*x+T*y)},w=f%c/c*Y*2,_=[v(w)],S=[d];for(let C=c;C--;){let A=(C+f)%c/c*Y*2;_.push(n),S.push(h),_.push(v(A)),S.push(d)}Jr(_,S)}else++Pe,++Le,On(n,t,i,!1,c=>{let l=c.createRadialGradient(0,0,0,0,0,.5);l.addColorStop(0,e.toString()),l.addColorStop(1,s.toString()),c.fillStyle=l,c.beginPath(),c.ellipse(0,0,.5,.5,0,0,9),c.fill()},a,r)}function sh(n,t=1,e=V,s=ln,i=G,o=!1,a){p(R(t),"size must be a number"),oc(n,b(t),e,s,0,i,o,a)}function On(n,t,e=0,s=!1,i,o=!1,a=_t){p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(R(e),"angle must be a number"),p(typeof i=="function","drawFunction must be a function"),o||(n=Dn(n),t=t.scale(H),e-=tt),a.save(),a.translate(n.x+.5,n.y+.5),a.rotate(e),a.scale(s?-t.x:t.x,-t.y),i(a),a.restore()}function ih(n,t,e=1,s=V,i=0,o=ot,a="center",r=Ps,c="",l,u=0,h=_t){t=Dn(t),e*=H,i*=H,u-=tt,u*=-1,rn(n,t,e,s,i,o,a,r,c,l,u,h)}function rn(n,t,e,s=V,i=0,o=ot,a="center",r=Ps,c="",l,u=0,h=_t){p(U(n),"text must be a string"),p(O(t),"pos must be a vec2"),p(R(e),"size must be a number"),p(J(s),"color must be a color"),p(R(i),"lineWidth must be a number"),p(J(o),"lineColor must be a color"),p(["left","center","right"].includes(a),"align must be left, center, or right"),p(U(r),"font must be a string"),p(U(c),"fontStyle must be a string"),p(R(u),"angle must be a number");let d=(n+"").split(`
+`),f=t.y-(d.length-1)*e/2;h.save(),h.fillStyle=s.toString(),h.strokeStyle=o.toString(),h.lineWidth=i,h.textAlign=a,h.font=c+" "+e+"px "+r,h.textBaseline="middle",h.translate(t.x,f),h.rotate(-u);let y=0;d.forEach(x=>{i&&h.strokeText(x,0,y,l),h.fillText(x,0,y,l),y+=e}),h.restore()}async function Ta(n,t){p(R(n),"textureIndex must be a number"),p(!hn[n],"textureIndex is already loaded!"),p(!t||U(t),"image src must be a string");let e=new Image;t&&await new Promise(s=>{e.onerror=e.onload=s,e.crossOrigin="anonymous",e.src=t}),hn[n]=new He(e)}function Ms(n){p(O(n),"screenPos must be a vec2");let t=(n.x-I.x/2+.5)/H,e=(n.y-I.y/2+.5)/-H;if(tt){let s=lt(-tt),i=it(-tt),o=t*s-e*i,a=t*i+e*s;t=o,e=a}return new ct(t+Pt.x,e+Pt.y)}function Dn(n){p(O(n),"worldPos must be a vec2");let t=n.x-Pt.x,e=n.y-Pt.y;if(tt){let s=lt(tt),i=it(tt),o=t*s-e*i,a=t*i+e*s;t=o,e=a}return new ct(t*H+I.x/2-.5,e*-H+I.y/2-.5)}function rc(n){p(O(n),"screenDelta must be a vec2");let t=n.x/H,e=n.y/-H;if(tt){let s=lt(-tt),i=it(-tt),o=t*s-e*i,a=t*i+e*s;t=o,e=a}return new ct(t,e)}function oh(n){p(O(n),"worldDelta must be a vec2");let t=n.x,e=n.y;if(tt){let s=lt(tt),i=it(tt),o=t*s-e*i,a=t*i+e*s;t=o,e=a}return new ct(t*H,e*-H)}function ks(n,t,e=0){return p(O(n),"screenPos must be a vec2"),p(O(t),"screenSize must be a vec2"),p(R(e),"screenAngle must be a number"),[Ms(n),t.scale(1/H),e+tt]}function ac(){return I.scale(1/H)}function rh(n,t,e,s){p(O(n),"center must be a vec2"),p(O(t),"size must be a vec2");let i=d(e),o=d(s),a=t.x+i.left+i.right,r=t.y+i.top+i.bottom,c=I.x-o.left-o.right,l=I.y-o.top-o.bottom;if(!(a>0&&r>0&&c>0&&l>0))return H;H=et(c/a,l/r);let u=b(i.right-i.left,i.top-i.bottom).scale(.5),h=b(o.right-o.left,o.top-o.bottom).scale(.5/H);return Pt=n.add(u).add(h),H;function d(f){return(f===void 0||R(f))&&(f=b(f)),O(f)?{top:f.y,right:f.x,bottom:f.y,left:f.x}:{top:f.top||0,right:f.right||0,bottom:f.bottom||0,left:f.left||0}}}function ah(n,t=0){if(p(O(n),"pos must be a vec2"),p(O(t)||R(t),"size must be a vec2 or number"),!H)return!1;let e=n.x-Pt.x,s=n.y-Pt.y;if(tt){let a=lt(tt),r=it(tt),c=e*a-s*r,l=e*r+s*a;e=c,s=l}e*=H*2,s*=-H*2,t instanceof ct&&(t=t.length()),t*=H;let i=I.x,o=I.y;return e+t>-i&&e-t-o&&s-t{n.onerror=n.onload=r,n.crossOrigin="anonymous",n.src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUAAAAAeAQMAAABnrVXaAAAABlBMVEUAAAD///+l2Z/dAAAAAXRSTlMAQObYZgAAAjpJREFUOMu9kzFu2zAUhn+CAROgqrk+B2l0BWYxMjlXeYaAtFtbdA1sGgHqRQfI0CNkSG5AwYB0BQ8d5Bsomwah6CPVeGg6tEPzAxLwyI+P78cP4u9lNO9OoMKnLMOobG5020/yaj/MrRcCGh1gBbyiLTPJEYaIiom5KM9Jq7KgynMGtb6L4GL4MF2H4LQKCXTvDVw2I4MsgZT7QLExdiutH+D08VOP3INXRrWX1/mmpbkNgAPYRVANb4xpcegYvhiNbIXauQICEjBuYLfMakaakWQeXxiZ0VDtuJCKs3ztMV59QtsHJNcRxDzfdL21ty3PrfIcXTN+E+GFAv6T5nbT9jd50/WFxb5ksdAv49qS6ouymG66ji08UMT6moykYLAo+V0j23GN4m829ZySAD5K7QsBfQTvOG8eE+gTeGYRAmnNAubN3hf5Zv9tJWDHp/VTuaSm7SN4fyINQqaNO3RMVxvpSPXnOChnRNvFcGY0gnwiPswYwTKVPE0zVtX3mTEIOoFzaqLrGuJaV+Uqumb71fVk/VoOH3cdLNQP/FHi8hV0CQNoqBZsUPlLPMsdCJro9QAaQQ0woDy9BJm0eTxCFnO9srcYlhNVlfR2EyTrph1uUtbUtAJifwRgrKuYdXVHeb0YI3QpawohQHkloI3J5FuVwI5ORxC9k2Tuz9Ir1IjgeIPGMHYkAZe2RuYkmWFmt3gGbTPOmBUWVTmRmHtGrfpzG/yuQNOKa6gBB/WA9khitPgl6/GP+gl2Af6tCbvaygAAAABJRU5ErkJggg=="});let t=b(),e=b(8),s=1,i=0,o=new He(n),a=new Oe(t,e,o,s,i);lc=new ii(a)}function fh(n=!0){Nn=n}function ph(n){Er=n}function gh(){return en==="mouse"}function yh(){return en==="keyboard"}function mh(){return en==="gamepad"}function Cr(n,t=0,e=!0,s=!0,i=!0){K[t]&&(K[t][n]&=~((e?1:0)|(s?2:0)|(i?4:0)))}function Gs(){K.length=0,K[0]=[],ae.length=0,_n.length=0,Fs.length=0,Te.length=0,mn.length=0}function Dt(n,t=0){var e;return p(U(n),"key must be a number or string"),p(t>0||typeof n!="number"||n<3,"use code string for keyboard"),!!(((e=K[t])==null?void 0:e[n])&1)}function Ft(n,t=0){var e;return p(U(n),"key must be a number or string"),p(t>0||typeof n!="number"||n<3,"use code string for keyboard"),!!(((e=K[t])==null?void 0:e[n])&2)}function _r(n,t=0){var e;return p(U(n),"key must be a number or string"),p(t>0||typeof n!="number"||n<3,"use code string for keyboard"),!!(((e=K[t])==null?void 0:e[n])&4)}function bh(n="ArrowUp",t="ArrowDown",e="ArrowLeft",s="ArrowRight"){p(U(n),"up key must be a string"),p(U(t),"down key must be a string"),p(U(e),"left key must be a string"),p(U(s),"right key must be a string");let i=o=>Dt(o)?1:0;return b(i(s)-i(e),i(n)-i(t))}function ls(n){return p(R(n),"mouse button must be a number"),Dt(n)}function gs(n){return p(R(n),"mouse button must be a number"),Ft(n)}function xh(n){return p(R(n),"mouse button must be a number"),_r(n)}function Ge(n,t=bt){return p(R(n),"button must be a number"),p(R(t),"gamepad must be a number"),Dt(n,t+1)}function Rr(n,t=bt){return p(R(n),"button must be a number"),p(R(t),"gamepad must be a number"),Ft(n,t+1)}function vh(n,t=bt){return p(R(n),"button must be a number"),p(R(t),"gamepad must be a number"),_r(n,t+1)}function ys(n,t=bt){var e,s;return p(R(n),"stick must be a number"),p(R(t),"gamepad must be a number"),(s=(e=Te[t])==null?void 0:e[n])!=null?s:b()}function bo(n=bt){var t;return p(R(n),"gamepad must be a number"),(t=mn[n])!=null?t:b()}function xo(n=bt){return p(R(n),"gamepad must be a number"),!!K[n+1]}function uc(n=bt){var t,e;return p(R(n),"gamepad must be a number"),(e=(t=Te[n])==null?void 0:t.length)!=null?e:0}function Sh(n=bt,t=200,e=1,s=1,i=0){var a,r,c;if(p(R(n),"gamepad must be a number"),!Ds||B)return;let o=(a=navigator==null?void 0:navigator.getGamepads)==null?void 0:a.call(navigator)[n];(c=(r=o==null?void 0:o.vibrationActuator)==null?void 0:r.playEffect)==null||c.call(r,"dual-rumble",{duration:t,strongMagnitude:e,weakMagnitude:s,startDelay:i})}function wh(n=bt){var e,s,i;if(p(R(n),"gamepad must be a number"),!Ds||B)return;let t=(e=navigator==null?void 0:navigator.getGamepads)==null?void 0:e.call(navigator)[n];(i=(s=t==null?void 0:t.vibrationActuator)==null?void 0:s.reset)==null||i.call(s)}function Pr(n=100){var t;p(R(n)||pe(n),"pattern must be a number or array"),Ds&&!B&&((t=navigator==null?void 0:navigator.vibrate)==null||t.call(navigator,n))}function Th(){Pr(0)}function Ah(){var n;!re&&((n=F.requestPointerLock)==null||n.call(F))}function Eh(){var n;(n=document.exitPointerLock)==null||n.call(document)}function hc(){return document.pointerLockElement===F}function Ch(){if(B)return;document.addEventListener("keydown",n),document.addEventListener("keyup",t),document.addEventListener("mousedown",s),document.addEventListener("mouseup",i),document.addEventListener("mousemove",o),document.addEventListener("mouseleave",a),document.addEventListener("wheel",r,{passive:!1}),document.addEventListener("contextmenu",c),document.addEventListener("blur",l),re&&xn&&u();function n(d){if(d.repeat||(K[0][d.code]=3,as&&(K[0][e(d.code)]=3)),!Nn||!d.cancelable||!document.hasFocus()||d.ctrlKey||d.metaKey||d.altKey||x(d.target)||x(document.activeElement))return;let f=typeof d.key=="string"&&d.key.length===1;(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight","Space","Tab","Backspace"].includes(d.code)||f)&&d.preventDefault();function x(v){let w=v==null?void 0:v.tagName;return(v==null?void 0:v.isContentEditable)||["INPUT","TEXTAREA","SELECT"].includes(w)}}function t(d){K[0][d.code]=K[0][d.code]&2|4,as&&(K[0][e(d.code)]=4)}function e(d){return as?d==="KeyW"?"ArrowUp":d==="KeyS"?"ArrowDown":d==="KeyA"?"ArrowLeft":d==="KeyD"?"ArrowRight":d:d}function s(d){if(re&&xn)return;Yt&&!B&&ft&&!bs()&&ft.resume(),K[0][d.button]=3;let f=Vt;Vt=h(b(d.x,d.y)),we=we.add(Vt.subtract(f)),Nn&&d.cancelable&&document.hasFocus()&&d.preventDefault()}function i(d){re&&xn||(K[0][d.button]=K[0][d.button]&2|4)}function o(d){oi=!0;let f=Vt;Vt=h(b(d.x,d.y));let y=hc()?b(d.movementX,d.movementY):Vt.subtract(f);we=we.add(y)}function a(){oi=!1}function r(d){d.ctrlKey||(Ar+=ie(d.deltaY)),Nn&&d.cancelable&&document.hasFocus()&&d.preventDefault()}function c(d){d.preventDefault()}function l(){Gs(),Je.clear(),ae.length=0,_n.length=0,Fs.length=0}function u(){document.addEventListener("touchstart",y=>f(y),{passive:!1}),document.addEventListener("touchmove",y=>f(y),{passive:!1}),document.addEventListener("touchend",y=>f(y),{passive:!1});let d;function f(y){if(xn){if(Yt&&!B&&ft&&!bs()&&ft.resume(),!un||mr){let x=S=>ms.includes(S.target)||S.target===bn,v=[];for(let S of y.touches)x(S)||v.push(S);let w=v.length,_=0;if(w){let S=b(v[0].clientX,v[0].clientY),C=Vt;Vt=h(S),d?we=we.add(Vt.subtract(C)):K[0][_]=3}else d&&(K[0][_]=K[0][_]&2|4);d=w}return Nn&&y.cancelable&&document.hasFocus()&&y.preventDefault(),!0}}}function h(d){let f=F.getBoundingClientRect(),y=Bt(d.x,f.left,f.right),x=Bt(d.y,f.top,f.bottom);return b(y*F.width,x*F.height)}}function Ea(){if(B)return;!(xn&&re)&&!document.hasFocus()&&Gs(),ke=Ms(Vt),Tr=rc(we),Rh(),t(),n();function n(){let e=ls(0)||ls(1)||ls(2)||we.length()>Er,s=!1;for(let o=uc();o--&&!s;)s=ys(o).lengthSquared()>.04;for(let o=17;o--&&!s;)s=Ge(o);let i=!1;for(let o in K[0])if(isNaN(+o)&&K[0][o]&1){i=!0;break}s?en="gamepad":e?en="mouse":i&&(en="keyboard"),zn=en==="gamepad"}function t(){var a,r,c,l,u,h,d;let e=f=>{let v=w=>w>.3?Bt(w,.3,.8):w<-.3?-Bt(-w,.3,.8):0;return b(v(f.x),v(-f.y)).clampLength()};if(un&&re){if(p(!Ln||!Qn,"set touchGamepadLeftStick or touchGamepadLeftButtonCount, not both"),p(!Zn||!Kn,"set touchGamepadRightStick or touchGamepadButtonCount, not both"),!qn.isSet())return;bt=0;let f=(a=Te[0])!=null?a:Te[0]=[],y=(r=mn[0])!=null?r:mn[0]=b();f.length=0,y.set();for(let v=0;v<2;v++){if(!Xe(v))continue;let w=Dr(v);f[w]=b();let _=(c=_n[v])!=null?c:b();if(Os)f[w]=e(_);else if(_.lengthSquared()>.3){let S=j($s(_.x),-1,1),C=j($s(_.y),-1,1);f[w]=b(S,-C).clampLength(),w||y.set(S,-C)}}let x=(l=K[1])!=null?l:K[1]=[];for(let v=12;v--;){let w=Ge(v,0);x[v]=ae[v]?w?1:3:w?4:0,ti&&x[v]===3&&(v===9||Ph(v))&&Pr(ti)}return}try{if(!Mi||!(navigator!=null&&navigator.getGamepads))return}catch{return}if(!Nt&&!document.hasFocus())return;let s=8,i=navigator.getGamepads(),o=et(s,i.length);for(let f=0;f>1]=e(b(y.axes[S],y.axes[S+1]));let _=!1;for(let S=y.buttons.length;S--;){let C=y.buttons[S],A=Ge(S,f);x[S]=C.pressed?A?1:3:A?4:0,C.pressed&&(!C.value||C.value>.9)&&(_=!0)}_&&(co[f]=!0,co[bt]||(bt=f)),y.mapping==="standard"&&w.set((Ge(15,f)&&1)-(Ge(14,f)&&1),(Ge(12,f)&&1)-(Ge(13,f)&&1)),yr&&(w.x||w.y)&&(v[0]=w.clampLength())}un&&zn&&qn.unset()}}function Ca(){if(!B){for(let n of K)for(let t in n)n[t]&=1;Ar=0,Tr=b(),we=b()}}function _h(){Ih()}function Rh(){if(Qe||!un||!re||B||!document.body)return;let n=Qe=document.createElement("div");n.style.cssText="position:fixed;inset:0;z-index:50;pointer-events:none;opacity:0;touch-action:none;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;transition:opacity .2s;box-sizing:border-box;padding:env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left)";let t=dc=document.createElement("div");t.style.cssText="position:relative;width:100%;height:100%;pointer-events:none",n.appendChild(t);let e=Lr=document.createElementNS(ai,"svg");e.style.cssText="position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible;fill:none;stroke:#fff;stroke-width:3",t.appendChild(e);let s=()=>{let i=document.createElement("div");return i.style.cssText="position:absolute;pointer-events:auto;touch-action:none",i.addEventListener("pointerdown",o=>Fh(o,i)),i.addEventListener("pointermove",o=>jh(o)),i.addEventListener("pointerup",o=>_a(o)),i.addEventListener("pointercancel",o=>_a(o)),t.appendChild(i),i};ms[0]=s(),ms[1]=s(),bn=s(),addEventListener("resize",()=>Hn=!0),document.body.appendChild(n),Hn=!0}function ki(){return dc.getBoundingClientRect()}function Xe(n){return n?Zn:Ln}function In(n){return n?Kn:Qn}function Or(n){return n?0:4}function Dr(n){return n&&Ln?1:0}function Xn(n){return Xe(n)||In(n)>0}function Ph(n){for(let t=0;t<2;t++){let e=Or(t);if(!Xe(t)&&n>=e&&no.style.cssText="position:absolute;pointer-events:auto;touch-action:none;"+a;if(_e){for(let o of ms)o.style.display="none";ge?(i(bn,"inset:0"),bn.style.display=""):bn.style.display="none"}else{for(let a=0;a<2;a++){let r=ms[a],c=a?"right":"left";if(r.style.display=Xn(a)?"":"none",dn){let l=Xn(a?0:1)?"50%":"100%";i(r,`${c}:0;bottom:0;width:${l};height:60%`)}else i(r,`${c}:0;bottom:0;width:${3*s}px;height:${3*s}px`)}bn.style.display=ge?"":"none";let o=ge;i(bn,`left:50%;top:50%;width:${2*o}px;height:${2*o}px;transform:translate(-50%,-50%)`)}Oh(t,e),Hn=!1}function Oh(n,t){let e=Lr;for(;e.firstChild;)e.removeChild(e.firstChild);let s=fc={face:[],thumb:[]},i=Xt,o=(r,c,l,u)=>{let h=document.createElementNS(ai,"circle");return h.setAttribute("cx",r),h.setAttribute("cy",c),h.setAttribute("r",l),u&&h.setAttribute("fill",u),e.appendChild(h),h},a=r=>{let c=i*.18,l=i*.5,u=r.x,h=r.y,d=document.createElementNS(ai,"path");d.setAttribute("d",`M ${u-c} ${h-l} H ${u+c} V ${h-c} H ${u+l} V ${h+c} H ${u+c} V ${h+l} H ${u-c} V ${h+c} H ${u-l} V ${h-c} H ${u-c} Z`),e.appendChild(d)};for(let r=0;r<2;r++){let c=In(r),l=Or(r),u=Ve(r,n,t);if(Xe(r))Os?o(u.x,u.y,i/2):a(u),s.thumb[r]=o(u.x,u.y,i/4,"#fff");else if(c===1)s.face[l]=o(u.x,u.y,i/2,"#000");else for(let h=0;h2?d:et(d,c-1);f=f===3?2:f===2?3:f;let y=b().setDirection(d,i/2);c===2&&(y.x*=-1),r||(y.x*=-1);let x=u.add(y);s.face[l+f]=o(x.x,x.y,i/4,"#000")}}Nt&&Tn&&Dh(n,t)}function Dh(n,t){let e=Xt,s=Lr,i=(a,r,c)=>{let l=document.createElementNS(ai,a);for(let u in r)l.setAttribute(u,r[u]);l.setAttribute("stroke",c),l.setAttribute("stroke-width",2),l.setAttribute("fill","none"),s.appendChild(l)},o=(a,r,c)=>i("circle",{cx:a.x,cy:a.y,r},c);i("line",{x1:n/2,y1:0,x2:n/2,y2:t},"#0f0");for(let a=0;a<2;a++)if(Xe(a))if(dn){let r=t*.4,c=!Xn(a?0:1),l=c?0:a?n/2:0;i("rect",{x:l,y:r,width:c?n:n/2,height:t-r},"#0ff")}else o(Ve(a,n,t),2*e,"#0ff");else In(a)>=1&&o(Ve(a,n,t),e,"#0ff");if(ge){o(b(n/2,t/2),ge,"#ff0");for(let a=0;a<2;a++)Xn(a)&&o(Ve(a,n,t),2*e,"#f0f")}}function Ih(){var l;if(!Qe||B)return;if(!un||!re){Qe.style.display!=="none"&&(Qe.style.display="none",Je.clear(),ae.length=0,_n.length=0,Fs.length=0);return}Qe.style.display="";let n=Nt&&Tn,t=[Kn,Qn,Ln,Zn,Os,Xt,dn,ge,_e,n].join();t!==Aa&&(Aa=t,Hn=!0),Hn&&Lh();let e=cs?Bt(qn.get(),cs+1,cs):1,s=n||qn.isSet()&&e>0&&!_e;if(Qe.style.opacity=s?n?1:e*br:0,!s)return;let i=ki(),o=i.width,a=i.height,r=Xt,c=fc;if(c){for(let u=0;u<2;u++)if(Xe(u)&&c.thumb[u]){let d=Ve(u,o,a).add(((l=_n[u])!=null?l:b()).scale(r/2));c.thumb[u].setAttribute("cx",d.x),c.thumb[u].setAttribute("cy",d.y)}for(let u=0;u=Xt)return-1;if(i===1)return o;let r=a.subtract(t);n||(r.x*=-1);let c=i===2?r.xo:r&&Ve(a,t,e).distance(n)<2*s)return{role:"stick",side:a}}else if(In(a)>=1){let c=kh(a,n,t,e);if(c>=0)return{role:"face",btn:c}}}if(ge){for(let a=0;a<2;a++)if(Xn(a)&&Ve(a,t,e).distance(n)<2*s)return;if(b(t/2,e/2).distance(n)h.getChannelData(v).set(x)),d.buffer=h,d.playbackRate.value=e,d.loop=i,a=a||ft.createGain(),a.gain.value=t,a.connect(We);let f=new StereoPannerNode(ft,{pan:j(s,-1,1)});d.connect(f).connect(a),d.addEventListener("ended",()=>{a.disconnect(),f.disconnect(),c&&c(d)});let y=r*e;return d.start(0,y),Nt&&Vn&&St("sound","vol",t.toFixed(2),"rate",e.toFixed(2),"pan",s.toFixed(2),i?"loop":""),d}function Jh(...n){return Ir([Gi(...n)])}function Gi(n=1,t=.05,e=220,s=0,i=0,o=.1,a=0,r=1,c=0,l=0,u=0,h=0,d=0,f=0,y=0,x=0,v=0,w=1,_=0,S=0,C=0){let A=ts,T=Y*2,P=c*=500*T/A/A,k=e*=(1+dt(t,-t))*T/A,pt=0,W=0,$=0,gt=1,zt,me=[],Jt=0,rt=0,Tt=0,be,fn=2,pn=T*st(C)*2/A,le=lt(pn),De=it(pn)/2/fn,ne=1+De,L=-2*le/ne,X=(1-De)/ne,N=(1+ie(C)*le)/2/ne,yt=-(ie(C)+le)/ne,vt=N,Mt=0,M=0,Z=0,Ct=0;for(s=s*A||9,_*=A,i*=A,o*=A,v*=A,l*=500*T/A**3,y*=T/A,u*=T/A,h*=A,d=d*A|0,zt=s+_+i+o+v|0;rt1?a>2?a>3?a>4?Jt/T%14?Tt:ie(Tt)*st(Tt)**r)*(rtrt?0:(rth&&(e+=u,k+=u,gt=0),d&&!(++W%d)&&(e=k,c=P,gt||(gt=1));return me}function li(n,t=!0){for(let e of an)if((!t||e.isSolid)&&n.arrayCheck(e.size)){let s=e.getCollisionData(n);if(s)return s}return 0}function Ze(n,t=b(),e,s=!0){for(let i of an)if((!s||i.isSolid)&&i.collisionTest(n,t,e))return i}function yc(n,t,e,s,i=!0){let o,a,r,c=s&&b();for(let l of an)if(!i||l.isSolid){let u=l.collisionRaycast(n,t,e,c);if(u){let h=n.distanceSquared(u);(o===void 0||h{G=!1,nt.style.display="none",e.preventDefault(),St("WebGL context lost! Switching to Canvas2d rendering.");for(let s of us)s.glTexture=void 0;te=void 0,Rt=0,Rn=!1,Sn.forEach(s=>{var i;return(i=s.glContextLost)==null?void 0:i.call(s)})}),nt.addEventListener("webglcontextrestored",()=>{G=!0,nt.style.display="",St("WebGL context restored, reinitializing..."),t();for(let e of us)e.glTexture=ji(e.image,e.wrap);Sn.forEach(e=>{var s;return(s=e.glContextRestored)==null?void 0:s.call(e)})});function t(){di=$n(`#version 300 es
 precision highp float;uniform mat4 m;in vec2 g;in vec4 p,u,c,a;in float r;out vec2 v;out vec4 d,e;void main(){vec2 s=(g-.5)*p.zw;gl_Position=m*vec4(p.xy+s*cos(r)-vec2(-s.y,s)*sin(r),1,1);v=mix(u.xw,u.zy,g);d=c;e=a;}`,`#version 300 es
-precision highp float;uniform sampler2D s;in vec2 v;in vec4 d,e;out vec4 c;void main(){c=texture(s,v)*d+e;}`),fi=Xn(`#version 300 es
+precision highp float;uniform sampler2D s;in vec2 v;in vec4 d,e;out vec4 c;void main(){c=texture(s,v)*d+e;}`),fi=$n(`#version 300 es
 precision highp float;uniform mat4 m;in vec2 p;in vec4 c;out vec4 d;void main(){gl_Position=m*vec4(p,1,1);d=c;}`,`#version 300 es
-precision highp float;in vec4 d;out vec4 c;void main(){c=d;}`);let e=new ArrayBuffer(gi);Ft=new Float32Array(e),Ss=new Uint32Array(e),So=g.createBuffer(),Nn=g.createBuffer(),kr=g.createFramebuffer(),Ct=0;let s=new Float32Array([0,0,1,0,0,1,1,1]);g.bindBuffer(g.ARRAY_BUFFER,Nn),g.bufferData(g.ARRAY_BUFFER,s,g.STATIC_DRAW);let i,o,a,r=(c,l,u,h,p=0)=>{let d=g.getAttribLocation(o,c),y=u===1,x=u&&a;g.enableVertexAttribArray(d),g.vertexAttribPointer(d,h,l,y,x,i),g.vertexAttribDivisor(d,p),i+=h*u};wo=g.createVertexArray(),g.bindVertexArray(wo),i=0,o=di,a=mc,g.bindBuffer(g.ARRAY_BUFFER,Nn),r("g",g.FLOAT,0,2),g.bindBuffer(g.ARRAY_BUFFER,So),g.bufferData(g.ARRAY_BUFFER,gi,g.DYNAMIC_DRAW),r("p",g.FLOAT,4,4,1),r("u",g.FLOAT,4,4,1),r("c",g.UNSIGNED_BYTE,1,4,1),r("a",g.UNSIGNED_BYTE,1,4,1),r("r",g.FLOAT,4,1,1),To=g.createVertexArray(),g.bindVertexArray(To),i=0,o=fi,a=bc,r("p",g.FLOAT,4,2),r("c",g.UNSIGNED_BYTE,1,4)}}function ws(n=!1){!n&&!En||(Rt(),En=!1,g.useProgram(di),g.bindVertexArray(wo))}function xc(){En||(Rt(),En=!0,g.useProgram(fi),g.bindVertexArray(To))}function Eo(n=!0){if(!G||!g)return;f(!Ct,"glPreRender called with unflushed batch."),pi||(et.width=I.x,et.height=I.y),g.viewport(0,0,I.x,I.y),n&&vc();let t=b(2*H).divide(I);pi&&(t.y=-t.y);let e=_t.rotate(-Q),s=b(-1).subtract(e.multiply(t)),i=lt(Q),o=st(Q),a=[t.x*i,t.y*o,0,0,-t.x*o,t.y*i,0,0,1,1,1,0,s.x,s.y,0,1],r=(c,l,u)=>{g.useProgram(c);let h=g.getUniformLocation(c,l);g.uniformMatrix4fv(h,!1,u)};r(fi,"m",a),r(di,"m",a),g.activeTexture(g.TEXTURE0),cn[0]&&(Qt=cn[0].glTexture,g.bindTexture(g.TEXTURE_2D,Qt)),g.bindBuffer(g.ARRAY_BUFFER,So),On=Hn=!1,ws(!0)}function vc(){if(!g)return;let n=tn;g.clearColor(n.r,n.g,n.b,n.a),g.clear(g.COLOR_BUFFER_BIT)}function Fr(n){!g||n===Qt||(Rt(),Qt=n,g.bindTexture(g.TEXTURE_2D,Qt))}function Sc(n,t=!0){if(!g||!n)return;let e=n===Qt;e?Rt():g.bindTexture(g.TEXTURE_2D,n);let s=t?g.REPEAT:g.CLAMP_TO_EDGE;g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_S,s),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_T,s),!e&&Qt&&g.bindTexture(g.TEXTURE_2D,Qt)}function Co(n,t){if(!g)return;let e=g.createShader(t);if(g.shaderSource(e,n),g.compileShader(e),jt&&!g.getShaderParameter(e,g.COMPILE_STATUS))throw g.getShaderInfoLog(e);return e}function Xn(n,t){if(!g)return;let e=g.createProgram();if(g.attachShader(e,Co(n,g.VERTEX_SHADER)),g.attachShader(e,Co(t,g.FRAGMENT_SHADER)),g.linkProgram(e),jt&&!g.getProgramParameter(e,g.LINK_STATUS))throw g.getProgramInfoLog(e);return e}function ji(n,t=!1){if(!g)return;let e=g.createTexture(),s=!1;if(n!=null&&n.width)jr(e,n),g.bindTexture(g.TEXTURE_2D,e),s=!Tn&&hs(n.width)&&hs(n.height);else{let r=new Uint8Array([255,255,255,255]);g.bindTexture(g.TEXTURE_2D,e),g.texImage2D(g.TEXTURE_2D,0,g.RGBA,1,1,0,g.RGBA,g.UNSIGNED_BYTE,r)}let i=Tn?g.NEAREST:g.LINEAR,o=s?g.LINEAR_MIPMAP_LINEAR:i;g.texParameteri(g.TEXTURE_2D,g.TEXTURE_MAG_FILTER,i),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_MIN_FILTER,o);let a=t?g.REPEAT:g.CLAMP_TO_EDGE;return g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_S,a),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_T,a),s&&g.generateMipmap(g.TEXTURE_2D),g.bindTexture(g.TEXTURE_2D,Qt),e}function wc(n){g&&g.deleteTexture(n)}function jr(n,t){g&&(f((t==null?void 0:t.width)>0,"Invalid image data."),g.bindTexture(g.TEXTURE_2D,n),g.texImage2D(g.TEXTURE_2D,0,g.RGBA,g.RGBA,g.UNSIGNED_BYTE,t),!Tn&&hs(t.width)&&hs(t.height)&&g.generateMipmap(g.TEXTURE_2D),g.bindTexture(g.TEXTURE_2D,Qt))}function Hh(n){z||(ls.add(n),g&&(n.glTexture?jr(n.glTexture,n.image):n.glTexture=ji(n.image,n.wrap)))}function Xh(n){if(z)return;ls.delete(n);let t=n.glTexture;n.glTexture=void 0,wc(t)}function Rt(){if(G&&g&&Ct){let n=Hn?g.ONE:g.ONE_MINUS_SRC_ALPHA;g.blendFuncSeparate(g.SRC_ALPHA,n,g.ONE,n),g.enable(g.BLEND);let t=Ct*(En?Fi:Gr);g.bufferSubData(g.ARRAY_BUFFER,0,Ft,0,t),En?g.drawArrays(g.TRIANGLE_STRIP,0,Ct):g.drawArraysInstanced(g.TRIANGLE_STRIP,0,4,Ct),++Ce,_e+=Ct,Ct=0}Hn=On}function Br(n){!G||!g||(Rt(),n.drawImage(et,0,0))}function Yh(n=!0){f(!et,"must be called before engineInit"),Mr=n}function Ts(n,t,e,s,i=0,o=0,a=0,r=1,c=1,l=-1,u=0){(Ct>=Wh||Hn!==On)&&Rt(),ws();let h=Ct++*Gr;Ft[h++]=n,Ft[h++]=t,Ft[h++]=e,Ft[h++]=s,Ft[h++]=o,Ft[h++]=a,Ft[h++]=r,Ft[h++]=c,Ss[h++]=l,Ss[h++]=u,Ft[h++]=i}function Tc(n,t,e,s,i,o){Ts(n,t,e,s,i,0,0,0,0,0,o)}function Nr(n,t,e,s,i,o,a,r=!0){let c=[],l=st(-a),u=lt(-a);for(let p of n){let d=p.x*i,y=p.y*o;c.push(b(e+u*d-l*y,s+l*d+u*y))}let h=r?Kh(c):c;Ac(h,t)}function zr(n,t,e,s,i,o,a,r,c=!0){let l=$h(n,e,c);Nr(l,t,s,i,o,a,r,!1)}function Ac(n,t){if(!G||n.length<3)return;let e=n.length+2;if((Ct+e>=zn||Hn!==On)&&Rt(),f(e=zn)return;xc();let s=Ct*Fi;for(let i=e;i--;){let o=N(i-1,0,e-3),a=n[o];Ft[s++]=a.x,Ft[s++]=a.y,Ss[s++]=t}Ct+=e}function Jr(n,t){if(!G||n.length<3)return;let e=n.length+2;if((Ct+e>=zn||Hn!==On)&&Rt(),f(e=zn)return;xc();let s=Ct*Fi;for(let i=e;i--;){let o=N(i-1,0,e-3),a=n[o],r=t[o];Ft[s++]=a.x,Ft[s++]=a.y,Ss[s++]=r}Ct+=e}function is(n,t=!1){n?(pi=n,g.bindFramebuffer(g.FRAMEBUFFER,kr),g.framebufferTexture2D(g.FRAMEBUFFER,g.COLOR_ATTACHMENT0,g.TEXTURE_2D,n,0),Eo(t)):(Rt(),pi=void 0,g.bindFramebuffer(g.FRAMEBUFFER,null),g.viewport(0,0,I.x,I.y))}function Ec(n,t,e,s){G&&(g.enable(g.SCISSOR_TEST),g.scissor(n,t,e,s),g.clearColor(0,0,0,0),g.clear(g.COLOR_BUFFER_BIT),g.disable(g.SCISSOR_TEST))}function $h(n,t,e=!0){if(n.length<2)return[];let s=t/2,i=[],o=n.length,a=1e-6,r=10;for(let c=0;ca?-d/y:0,S=y>a?p/y:0,C=w>a?-v/w:0,A=w>a?x/w:0,T=_+C,P=S+A,M=(T*T+P*P)**.5;if(Ma){let yt=tt(1/ct,r);T*=yt,P*=yt}}let pt=b(u.x-T*s,u.y-P*s),at=b(u.x+T*s,u.y+P*s);i.push(pt),i.push(at)}return i.length>1&&e&&(i.push(i[0]),i.push(i[1])),i}function Kh(n){if(n.length<3)return[];let t=(d,y,x)=>(y.x-d.x)*(x.y-d.y)-(y.y-d.y)*(x.x-d.x);(d=>{let y=0;for(let x=d.length;x--;){let v=(x+1)%d.length;y+=d[x].cross(d[v])}return y})(n)<0&&(n=n.slice().reverse());let s=1e-9,i=(d,y,x,v)=>{let w=t(y,x,d),_=t(x,v,d),S=t(v,y,d),C=(w<-s?1:0)+(_<-s?1:0)+(S<-s?1:0),A=(w>s?1:0)+(_>s?1:0)+(S>s?1:0);return!(C&&A)},o=[];for(let d=0;d3&&r++{if(C>=0){let T=s.fillStyle=s.createLinearGradient(v,w,_,S);T.addColorStop(0,h(C,2)),T.addColorStop(1,h(C,1))}else s.fillStyle="#000";C>=-1?(s.fill(),A&&s.stroke()):s.stroke()},c=(v,w,_,S=0,C=2*X,A,T)=>{s.beginPath(),s.arc(v,w,_,d*S,d*C),r(v,w-_,v,w+_,A,T)},l=(v,w,_,S,C)=>{s.beginPath(),s.rect(v,w,_,S*d),r(v,w+S,v+_,w,C)},u=(v,w,_,S)=>{s.beginPath();for(let C of v)s.lineTo(C.x,C.y);s.closePath(),r(0,_,0,_+S,w)},h=(v,w)=>w?`hsl(${[.95,.56,.13][v%3]*360} 99%${[0,50,75][w]}%)`:"#000",p=Wa(1,1,n),d=Bt(p,.1,.5),y=tt(6,tt(o,a)/99);s.translate(o/2,a/2),s.scale(y,y),s.translate(-40,-35),d<1&&s.setLineDash([99*d,99]),s.lineJoin=s.lineCap="round",s.lineWidth=.1+d*1.9;{let w="LittleJS";s.font="900 15.5px arial",s.lineWidth=.1+d*3.9,s.textAlign="center",s.textBaseline="top",l(11,55,59,8*d,-1),s.beginPath();let _=0;for(let S=0;S5?1:0),s[S?"strokeText":"fillText"](w[C],P,54+.5,17*d),A+=T}s.lineWidth=.1+d*1.9,l(3,54,73,0)}l(7,15,26,-7,0),l(25,15,8,25,-1),l(10,40,15,-25,1),l(14,21,7,9,2),l(38,20,6,-6,2),l(49,20,10,-6,0);let x=[b(44,8),b(64,8),b(59,8+6*d),b(49,8+6*d)];u(x,2,8,6*d),l(44,8,20,-7,0);for(let v=5;v--;)c(59-v*6*d,30,10,0,2*X,1,0);c(59,30,4,0,7,2),l(35,20,24,0),c(59,30,10),c(47,30,10,X/2,X*3/2),c(35,30,10,X/2,X*3/2),l(7,40,13,7,-1),l(17,40,43,14,-1);for(let v=3;v--;)for(let w=2;w--;)c(17+15*v,47,w?7:1,0,2*X,2);for(let v=2;v--;){let w=6,_=7,S=53+w*d*v,C=[b(S+_,54),b(S,40),b(S+w*d,40),b(S+_+w*d,54)];u(C,0,40,14)}s.restore()}function Zh(n){if(bi=n,!fn){let e={};try{e=JSON.parse(localStorage[n]||"{}")}catch{e={}}Bi(s=>{s.unlocked=!!(e[s.id]&&e[s.id].unlocked)}),Vr()}Cn(void 0,t);function t(){if(!qs.length)return;let e=qs[0],s=on-Ws;if(!Ws)Ws=on;else if(s>yi)Ws=0,qs.shift();else{let i=yi-jn,o=si?(s-i)/jn:0;e.render(o)}}}function Bi(n){Object.values(As).forEach(t=>n(t))}function td(){Bi(n=>n.unlocked=!1),Vr()}function Vr(){if(!bi)return;let n={};Bi(t=>{let e={name:t.name,description:t.description,icon:t.icon,unlocked:t.unlocked};t.image&&(e.src=t.image.src),n[t.id]=e}),localStorage[bi]=JSON.stringify(n)}function ed(n){yi=n}function nd(n){jn=n}function sd(n){mi=n.copy()}function id(n){Ur=n}function Cc(n,t,e,s=125){let i,o,a,r,c,l,u,h,p,d,y,x,v,w=0,_,S=[],C=[],A=[],T=0,P=0,M=1,pt={},at=Qn/s*60>>2;for(;M;T++)S=[M=h=x=0],e.forEach((ct,yt)=>{for(u=t[ct][T]||[0,0,0],M|=t[ct][T]&&1,_=x+(t[ct][0].length-2-(h?0:1))*at,v=yt===e.length-1,i=2,a=x;iat-99&&p&&y<1?y+=1/99:0)l=(1-y)*S[w++]/2||0,C[a]=(C[a]||0)-l*P+l,A[a]=(A[a++]||0)+l*P+l;c&&(y=c%1,P=u[1]||0,(c|=0)&&(S=pt[[d=u[w=0]||0,c]]=pt[[d,c]]||(r=[...n[d]],r[2]=(r[2]||220)*2**(c/12-1),c>0?Gi(...r):[])))}x=_});return[C,A]}function od(n){Wr=typeof n=="boolean"?n?1:0:n}function rd(n){qr=n}async function ad(){return new Ai(await Box2D()),e(),Cn(n,t),m;function n(){if(!Ae){m.step(),m.objects=m.objects.filter(s=>!s.destroyed);for(let s of m.objects)s.body&&(s.pos=m.vec2From(s.body.GetPosition()),s.angle=-s.body.GetAngle())}}function t(){(qr||ue)&&m.world.DrawDebugData()}function e(){let i=new m.instance.JSDraw,o=l=>new wt(l.get_r(),l.get_g(),l.get_b()),a=l=>o(m.instance.wrapPointer(l,m.instance.b2Color)),r=l=>a(l).scale(1,.8),c=(l,u)=>{let h=[];for(let p=u;p--;)h.push(m.vec2FromPointer(l+p*8));return h};i.DrawSegment=function(l,u,h){h=r(h),l=m.vec2FromPointer(l),u=m.vec2FromPointer(u),mn(l,u,.1,h,b(),0,!1)},i.DrawPolygon=function(l,u,h){h=r(h);let p=c(l,u);Un(p,rn,.1,h,b(),0,!1)},i.DrawSolidPolygon=function(l,u,h){h=r(h);let p=c(l,u);Un(p,h,0,h,b(),0,!1)},i.DrawCircle=function(l,u,h){h=r(h),l=m.vec2FromPointer(l),si(l,u*2,rn,.1,h,!1)},i.DrawSolidCircle=function(l,u,h,p){p=r(p),l=m.vec2FromPointer(l),h=m.vec2FromPointer(h).scale(u),si(l,u*2,p,.1,p,!1),mn(b(),h,.1,p,l,0,!1)},i.DrawTransform=function(l){l=m.instance.wrapPointer(l,m.instance.b2Transform);let u=m.vec2From(l.get_p()),h=-l.get_q().GetAngle(),p=b(1,0),d=J(.75,0,0,.8),y=b(0,1),x=J(0,.75,0,.8);mn(b(),p,.1,d,u,h,!1),mn(b(),y,.1,x,u,h,!1)},i.AppendFlags(m.instance.b2Draw.e_shapeBit),i.AppendFlags(m.instance.b2Draw.e_jointBit),m.world.SetDebugDraw(i)}}function cd(n,t,e,s=32,i=2,o=0){_c(n,t,e,W,s,it,i,o,!1,!0)}function _c(n,t,e,s,i=1,o,a=.05,r=0,c=G,l,u){let h=e.offset(e.size),p=t.add(b(a-i*2)),d=b(i),y=t.scale(.5).subtract(d.scale(.5)),x=l?-1:1,v=l?-r:r;Mt(n,p,h,s,r,!1,o,c,l,u);for(let w=4;w--;){let _=w%2,S=y.multiply(b(_?w===1?1:-1:0,_?0:w?-1:1)),C=b(_?i:p.x,_?p.y:i),A=h.offset(e.size.multiply(b(w===1?1:w===3?-1:0,w===0?-x:w===2?x:0)));Mt(n.add(S.rotate(v)),C,A,s,r,!1,o,c,l,u)}for(let w=4;w--;){let _=w>1,S=w&&w<3,C=y.multiply(b(_?-1:1,S?-1:1)),A=h.offset(e.size.multiply(b(_?-1:1,S?x:-x)));Mt(n.add(C.rotate(v)),d,A,s,r,!1,o,c,l,u)}}function ld(n,t,e,s=32,i=2,o=0){Rc(n,t,e,W,s,it,i,o,!1,!0)}function Rc(n,t,e,s,i=1,o,a=.05,r=0,c=G,l,u){let h=e.frame(0),p=e.frame(1),d=e.frame(2),y=t.add(b(a-i*2)),x=b(i),v=t.scale(.5).subtract(x.scale(.5)),w=l?-1:1,_=l?-r:r;Mt(n,y,d,s,r,!1,o,c,l,u);for(let S=4;S--;){let C=r+S*X/2,A=S%2,T=v.multiply(b(A?S===1?1:-1:0,A?0:S?-w:w)),P=b(A?y.y:y.x,i);Mt(n.add(T.rotate(_)),P,p,s,C,!1,o,c,l,u)}for(let S=4;S--;){let C=r+S*X/2,A=!S||S>2,T=S>1,P=v.multiply(b(A?-1:1,T?-w:w));Mt(n.add(P.rotate(_)),x,h,s,C,!1,o,c,l,u)}}function ud(n,t=1,e=0,s=W,i=0,o=!1,a=0,r=it,c=G,l=!1,u){let h=Pc(b(),t,e,0,o);Un(h,s,a,r,n,i,c,l,u)}function Pc(n,t=1,e=0,s=0,i=!1,o=Ps){f(O(n),"pos must be a vec2"),f(L(t)&&L(e),"size and percent must be numbers");let a=se(e*4,4);a>=2&&(s+=X),a=a<=2?a-1:3-a,i&&(a=-a,s+=X);let r=[],c=K(3,o>>1),l=t/2;for(let u=0;u<=c;u++){let h=u/c*X;r.push(b(l*lt(h),l*st(h)).rotate(s).add(n))}for(let u=c;u>=0;u--){let h=u/c*X;r.push(b(l*lt(h),-l*a*st(h)).rotate(s).add(n))}return r}function La(n){return n&&typeof n.lerp=="function"}function hd(n,t,e,s,i=1,o={}){f(n!=null&&typeof n=="object","tweenProperty target must be an object"),f(V(t)&&t.length>0,"tweenProperty propertyPath must be a non-empty string");let a=t.split("."),r=a.pop(),c=l=>{let u=n;for(let h of a)u=u[h];u[r]=l};return new Ei(c,e,s,i,o)}function Lc(n){n.loopRemaining!==1/0&&n.loopRemaining<=1||(n.loopRemaining!==1/0&&(n.loopRemaining-=1),n.life=n.duration,n.thenCallback=()=>Lc(n),$t.push(n),n.callback(n.interp(n.duration)))}function Oc(n){if(n.loopRemaining!==1/0&&n.loopRemaining<=1)return;n.loopRemaining!==1/0&&(n.loopRemaining-=1);let t=n.start;n.start=n.end,n.end=t,n.life=n.duration,n.thenCallback=()=>Oc(n),$t.push(n),n.callback(n.interp(n.duration))}function Dc(n,t){n===void 0?(n=Kt-Ra,t=on-Pa,Ra=Kt,Pa=on):t===void 0&&(t=n);for(let e=$t.length;e--;){let s=$t[e];if(s.paused)continue;let i=s.useRealTime?t:n;if(!(i<=0))if(s.life-=i,s.life>0)s.callback(s.interp(s.life));else{s.callback(s.interp(0)),$t.splice(e,1);let o=s.thenCallback;s.thenCallback=void 0,o&&o()}}}function dd(){for(let n of $t)n.thenCallback=void 0;$t.length=0}var Hs,Xs,Cl,tr,vt,er,Oa,Kt,on,Ae,ao,be,Ys,Da,bn,uo,jt,ka,Ri,Ga,Me,Ze,ue,he,xn,vn,Jn,ho,ke,le,X,nt,St,us,$s,tt,K,ne,Na,za,st,lt,Ja,sr,go,rt,wt,W,rn,it,pe,Vl,rr,Wl,Ka,Qa,ql,Za,tc,Hl,Ee,_t,Q,H,cr,Pi,tn,Mn,os,kn,Gn,lr,Tn,en,Rs,ur,z,G,Ps,Li,Oi,Di,Ii,hr,dr,fr,pr,gr,Fe,Vt,Zs,Mi,yr,rs,yn,an,mr,fe,Yn,_n,$n,Kn,Ls,ln,qt,br,as,ti,Os,Ht,Sn,xr,vr,Ue,B,ut,Et,Ne,Ke,Se,je,I,cn,Ce,_e,Re,Ve,nh,lc,ii,De,Jt,Tr,xe,Ar,oi,Bn,Qe,Er,Fn,mt,ie,Y,ve,pn,co,Vn,oe,An,ri,Gs,Be,Ye,dc,Lr,fc,ys,gn,Wn,Aa,ai,ft,Je,Qn,bs,ci,sn,wn,ui,xs,vs,vo,Vh,hi,et,g,Mr,di,fi,En,On,Hn,Qt,So,Nn,Ft,Ss,Ct,ls,wo,To,kr,pi,Ao,gi,Gr,mc,Wh,Fi,bc,zn,fn,yi,jn,mi,Ur,As,qs,bi,Ws,xi,Es,_o,Ro,kt,Po,q,Lo,Oo,Do,E,Wr,Io,re,vi,Mo,ko,Cs,Go,Fo,jo,Bo,m,qr,_s,Si,No,zo,wi,Xt,Jo,Ti,Uo,Vo,Wo,qo,Ho,Xo,Yo,$o,Ko,Qo,Ai,$t,Ra,Pa,Ei,Ci,fd,lo,_i,Zo,Mc=jc(()=>{"use strict";Hs="LittleJS",Xs="1.18.19",Cl=60,tr=.016666666666666666,vt=[],er=[],Oa=0,Kt=0,on=0,Ae=!1;ao=0,be=0,Ys=0,Da=!0,bn=[],uo=class{constructor(t,e,s,i){this.update=t,this.render=e,this.glContextLost=s,this.glContextRestored=i}};jt=!0,ka=.5,Ri=!0,Ga="Escape",Me=!1,Ze=[],ue=!1,he=!1,xn=!1,vn=!1,Jn=!1;X=Math.PI,nt=Math.abs,St=Math.floor,us=Math.ceil,$s=Math.round,tt=Math.min,K=Math.max,ne=n=>Math.sign(n),Na=(...n)=>Math.hypot(...n),za=n=>Math.log2(n),st=Math.sin,lt=Math.cos,Ja=Math.tan,sr=Math.atan2;go=class{constructor(t=123456789){f(t!==0,"RandomGenerator seed must be non-zero (xorshift is fixed at 0)"),this.seed=t}float(t=1,e=0){return this.seed^=this.seed<<13,this.seed^=this.seed>>>17,this.seed^=this.seed<<5,e+(t-e)*((this.seed>>>0)/2**32)}int(t,e=0){return St(this.float(t,e))}bool(t=.5){return this.float().5?1:-1}floatSign(t=1,e=0){let s=tt(t,e),o=K(t,e)-s,a=this.float(o*2);return at?this.scale(t/e):this.copy()}dot(t){return this.x*t.x+this.y*t.y}cross(t){return this.x*t.y-this.y*t.x}reflect(t,e=1){return this.subtract(t.scale((1+e)*this.dot(t)))}angle(){return sr(this.x,this.y)}setAngle(t=0,e=1){return Yt(t),Yt(e),this.x=e*st(t),this.y=e*lt(t),this}rotate(t){Yt(t);let e=lt(-t),s=st(-t);return new n(this.x*e-this.y*s,this.x*s+this.y*e)}setDirection(t,e=1){return Yt(t),Yt(e),t=se(t,4),f(t===0||t===1||t===2||t===3,"Vector2.setDirection() direction must be an integer between 0 and 3."),this.x=t%2?t-1?-e:e:0,this.y=t%2?0:t?-e:e,this}direction(){return nt(this.x)>nt(this.y)?this.x<0?3:1:this.y<0?2:0}abs(){return new n(nt(this.x),nt(this.y))}floor(){return new n(St(this.x),St(this.y))}snap(t){return Yt(t),new n(St(this.x*t)/t,St(this.y*t)/t)}mod(t=1){return new n(se(this.x,t),se(this.y,t))}area(){return nt(this.x*this.y)}lerp(t,e){wa(t),Yt(e);let s=N(e);return new n(t.x*s+this.x*(1-s),t.y*s+this.y*(1-s))}arrayCheck(t){return this.x>=0&&this.y>=0&&this.x(u=se(u,1))*6<1?c+(l-c)*6*u:u*2<1?l:u*3<2?c+(l-c)*(4-u*6):c;return this.r=r(a,o,t+1/3),this.g=r(a,o,t),this.b=r(a,o,t-1/3),this.a=i,ss(this),this}HSLA(){let t=N(this.r),e=N(this.g),s=N(this.b),i=N(this.a),o=K(t,e,s),a=tt(t,e,s),r=(o+a)/2,c=0,l=0;if(o!==a){let u=o-a;l=r>.5?u/(2-o-a):u/(o+a),t===o?c=(e-s)/u+(e((s=N(s)*255|0)<16?"0":"")+s.toString(16);return"#"+e(this.r)+e(this.g)+e(this.b)+(t?e(this.a):"")}setHex(t){if(f(V(t),"Color hex code must be a string"),f(t[0]==="#","Color hex code must start with #"),f([4,5,7,9].includes(t.length),"Invalid hex"),t.length<6){let e=s=>N(parseInt(t[s],16)/15);this.r=e(1),this.g=e(2),this.b=e(3),this.a=t.length===5?e(4):1}else{let e=s=>N(parseInt(t.slice(s,s+2),16)/255);this.r=e(1),this.g=e(3),this.b=e(5),this.a=t.length===9?e(7):1}return ss(this),this}rgbaInt(){let t=N(this.r)*255|0,e=N(this.g)*255<<8,s=N(this.b)*255<<16,i=N(this.a)*255<<24;return t+e+s+i}isValid(){return L(this.r)&&L(this.g)&&L(this.b)&&L(this.a)}},W=Zt(J()),rn=Zt(J(1,1,1,0)),it=Zt(J(0,0,0)),pe=Zt(J(0,0,0,0)),Vl=Zt(J(.5,.5,.5)),rr=Zt(J(1,0,0)),Wl=Zt(J(1,.5,0)),Ka=Zt(J(1,1,0)),Qa=Zt(J(0,1,0)),ql=Zt(J(0,1,1)),Za=Zt(J(0,0,1)),tc=Zt(J(.5,0,1)),Hl=Zt(J(1,0,1)),Ee=class{constructor(t,e=!1){f(t===void 0||L(t),"Constructed Timer is invalid.",t),this.useRealTime=e;let s=this.getGlobalTime();this.time=t===void 0?void 0:s+t,this.setTime=t}set(t=0){f(L(t),"Timer is invalid.",t);let e=this.getGlobalTime();this.time=e+t,this.setTime=t}setUseRealTime(t=!0){f(!this.isSet(),"Cannot change global time setting while timer is set."),this.useRealTime=t}unset(){this.time=void 0}isSet(){return this.time!==void 0}active(){return this.getGlobalTime()=this.time}get(){return this.isSet()?this.getGlobalTime()-this.time:0}getPercent(){return this.isSet()?this.setTime?1-Bt(this.time-this.getGlobalTime(),0,this.setTime):1:0}getSetTime(){return this.isSet()?this.setTime:0}getGlobalTime(){return this.useRealTime?on:Kt}toString(){return this.isSet()?nt(this.get())+" seconds "+(this.get()<0?"before":"after"):"unset"}valueOf(){return this.get()}};_t=b(),Q=0,H=32,cr=1,Pi=!0,tn=pe,Mn=b(1920,1080),os=0,kn=0,Gn=b(),lr=!1,Tn=!0,en=1,Rs="arial",ur=!1,z=!1,G=!0,Ps=32,Li=b(16),Oi=0,Di=0,Ii=!0,hr=1,dr=1,fr=1,pr=0,gr=.8,Fe=1,Vt=b(),Zs=1,Mi=!0,yr=!0,rs=!0,yn=!0,an=!1,mr=!1,fe=0,Yn=4,_n=!0,$n=0,Kn=!1,Ls=!0,ln=!1,qt=100,br=.3,as=3,ti=0,Os=!0,Ht=!0,Sn=.3,xr=40,vr=.7;Ue=class n{constructor(t=b(),e=b(1),s,i=0,o=W,a=0){f(O(t),"object pos must be a vec2"),f(O(e),"object size must be a vec2"),f(!s||s instanceof Re,"object tileInfo should be a TileInfo or undefined"),f(typeof i=="number"&&isFinite(i),"object angle should be a number"),f(U(o),"object color should be a valid rgba color"),f(typeof a=="number","object renderOrder should be a number"),this.pos=t.copy(),this.size=e.copy(),this.drawSize=void 0,this.tileInfo=s,this.angle=i,this.color=o.copy(),this.additiveColor=void 0,this.mirror=!1,this.destroyed=!1,this.mass=hr,this.damping=dr,this.angleDamping=fr,this.restitution=pr,this.friction=gr,this.gravityScale=1,this.renderOrder=a,this.velocity=b(),this.angleVelocity=0,this.spawnTime=Kt,this.children=[],this.clampSpeed=!0,this.groundObject=void 0,this.parent=void 0,this.localPos=b(),this.localAngle=0,this.collideTiles=!1,this.collideSolidObjects=!1,this.isSolid=!1,this.collideRaycast=!1,vt.push(this)}updateTransforms(){let t=this.parent;if(t){let e=t.getMirrorSign(),s=this.localPos,i=t.pos,o=s.x*e,a=s.y,r=t.angle;if(r){let c=lt(-r),l=st(-r);this.pos.set(o*c-a*l+i.x,o*l+a*c+i.y)}else this.pos.set(o+i.x,a+i.y);this.angle=e*this.localAngle+r}for(let e of this.children)e.updateTransforms()}updatePhysics(){if(f(!this.parent),this.destroyed)return;this.clampSpeed&&(this.velocity.x=N(this.velocity.x,-Fe,Fe),this.velocity.y=N(this.velocity.y,-Fe,Fe));let t=this.pos.copy();if(this.velocity.x*=this.damping,this.velocity.y*=this.damping,this.mass&&(this.velocity.x+=Vt.x*this.gravityScale,this.velocity.y+=Vt.y*this.gravityScale),this.pos.x+=this.velocity.x,this.pos.y+=this.velocity.y,this.angle+=this.angleVelocity*=this.angleDamping,f(this.angleDamping>=0&&this.angleDamping<=1),f(this.damping>=0&&this.damping<=1),!Ii||!this.mass)return;let e=this.velocity.y<0&&Vt.y<0||this.velocity.y>0&&Vt.y>0;if(this.groundObject){let s=K(this.friction,this.groundObject.friction),i=this.groundObject.velocity.x;this.velocity.x=i+(this.velocity.x-i)*s,this.groundObject=void 0}if(this.collideSolidObjects)for(let i of er){if(i.destroyed||i.parent||i===this||!this.isSolid&&!i.isSolid||!this.isOverlappingObject(i))continue;let o=this.collideWithObject(i),a=i.collideWithObject(this);if(!o||!a)continue;if(Qs(t,this.size,i.pos,i.size)){let p=t.subtract(i.pos),d=p.length(),x=d<.001?b(0,1):p.scale(.001/d);this.velocity=this.velocity.add(x),i.mass&&(i.velocity=i.velocity.subtract(x)),ue&&fo(this.pos,this.size,i.pos,i.size,"#f00");continue}let r=this.size.add(i.size),c=(t.y-i.pos.y)*2>r.y+Vt.y,l=nt(t.y-i.pos.y)*20?-1:1)>0?St(t.y-this.size.y/2+1)+this.size.y/2+.001:us(t.y+this.size.y/2-1)-this.size.y/2-.001;if(nt(u-this.pos.y)<.1&&!$e(b(this.pos.x,u),this.size,this)){this.pos.y=u,ue&&bt(this.pos,this.size,"#ff0");return}this.pos.x=t.x,this.velocity.x*=-a}if(o||!i){if(e){let c=this.size.y/2+1e-4;this.pos.y=Vt.y<0?St(t.y-this.size.y/2)+c:us(t.y+this.size.y/2)-c,this.groundObject=s}else this.pos.y=t.y,this.groundObject=void 0;this.velocity.y*=-a}ue&&bt(this.pos,this.size,"#f00")}}}update(){}render(){Mt(this.pos,this.drawSize||this.size,this.tileInfo,this.color,this.angle,this.mirror,this.additiveColor)}renderLight(){}destroy(t=!1){var e;if(!this.destroyed){this.destroyed=!0,(e=this.parent)==null||e.removeChild(this);for(let s of this.children)s.parent=void 0,s.destroy(t)}}localToWorld(t){return this.pos.add(t.rotate(this.angle))}worldToLocal(t){return t.subtract(this.pos).rotate(-this.angle)}localToWorldVector(t){return t.rotate(this.angle)}worldToLocalVector(t){return t.rotate(-this.angle)}collideWithTile(t,e){return t>0}collideWithObject(t){return!0}getUp(t=1){return b().setAngle(this.angle,t)}getRight(t=1){return b().setAngle(this.angle+X/2,t)}getAliveTime(){return Kt-this.spawnTime}getSpeed(){return this.velocity.length()}applyAcceleration(t){this.mass&&(this.velocity=this.velocity.add(t))}applyAngularAcceleration(t){this.mass&&(this.angleVelocity+=t)}applyForce(t){this.mass&&this.applyAcceleration(t.scale(1/this.mass))}getMirrorSign(){return this.mirror?-1:1}addChild(t,e=b(),s=0){return f(!this.destroyed,"cannot add child to destroyed object"),this.destroyed||(f(!t.parent&&!this.children.includes(t)),f(t instanceof n,"child must be an EngineObject"),f(t!==this,"cannot add self as child"),this.children.push(t),t.parent=this,t.localPos=e.copy(),t.localAngle=s,t.updateTransforms()),t}removeChild(t){f(t.parent===this&&this.children.includes(t)),this.children.splice(this.children.indexOf(t),1),t.parent=void 0}isOverlappingObject(t){return this.isOverlapping(t.pos,t.size)}isOverlapping(t,e=b()){return Qs(this.pos,this.size,t,e)}setCollision(t=!0,e=!0,s=!0,i=!0){f(t||!e,"solid objects must be set to collide"),this.collideSolidObjects=t,this.isSolid=e,this.collideTiles=s,this.collideRaycast=i}toString(){let t="type = "+this.constructor.name;return(this.pos.x||this.pos.y)&&(t+=`
+precision highp float;in vec4 d;out vec4 c;void main(){c=d;}`);let e=new ArrayBuffer(gi);jt=new Float32Array(e),ws=new Uint32Array(e),So=g.createBuffer(),Jn=g.createBuffer(),kr=g.createFramebuffer(),Rt=0;let s=new Float32Array([0,0,1,0,0,1,1,1]);g.bindBuffer(g.ARRAY_BUFFER,Jn),g.bufferData(g.ARRAY_BUFFER,s,g.STATIC_DRAW);let i,o,a,r=(c,l,u,h,d=0)=>{let f=g.getAttribLocation(o,c),y=u===1,x=u&&a;g.enableVertexAttribArray(f),g.vertexAttribPointer(f,h,l,y,x,i),g.vertexAttribDivisor(f,d),i+=h*u};wo=g.createVertexArray(),g.bindVertexArray(wo),i=0,o=di,a=mc,g.bindBuffer(g.ARRAY_BUFFER,Jn),r("g",g.FLOAT,0,2),g.bindBuffer(g.ARRAY_BUFFER,So),g.bufferData(g.ARRAY_BUFFER,gi,g.DYNAMIC_DRAW),r("p",g.FLOAT,4,4,1),r("u",g.FLOAT,4,4,1),r("c",g.UNSIGNED_BYTE,1,4,1),r("a",g.UNSIGNED_BYTE,1,4,1),r("r",g.FLOAT,4,1,1),To=g.createVertexArray(),g.bindVertexArray(To),i=0,o=fi,a=bc,r("p",g.FLOAT,4,2),r("c",g.UNSIGNED_BYTE,1,4)}}function Ts(n=!1){!n&&!Rn||(Lt(),Rn=!1,g.useProgram(di),g.bindVertexArray(wo))}function xc(){Rn||(Lt(),Rn=!0,g.useProgram(fi),g.bindVertexArray(To))}function Eo(n=!0){if(!G||!g)return;p(!Rt,"glPreRender called with unflushed batch."),pi||(nt.width=I.x,nt.height=I.y),g.viewport(0,0,I.x,I.y),n&&vc();let t=b(2*H).divide(I);pi&&(t.y=-t.y);let e=Pt.rotate(-tt),s=b(-1).subtract(e.multiply(t)),i=lt(tt),o=it(tt),a=[t.x*i,t.y*o,0,0,-t.x*o,t.y*i,0,0,1,1,1,0,s.x,s.y,0,1],r=(c,l,u)=>{g.useProgram(c);let h=g.getUniformLocation(c,l);g.uniformMatrix4fv(h,!1,u)};r(fi,"m",a),r(di,"m",a),g.activeTexture(g.TEXTURE0),hn[0]&&(te=hn[0].glTexture,g.bindTexture(g.TEXTURE_2D,te)),g.bindBuffer(g.ARRAY_BUFFER,So),Mn=Yn=!1,Ts(!0)}function vc(){if(!g)return;let n=sn;g.clearColor(n.r,n.g,n.b,n.a),g.clear(g.COLOR_BUFFER_BIT)}function Fr(n){!g||n===te||(Lt(),te=n,g.bindTexture(g.TEXTURE_2D,te))}function Sc(n,t=!0){if(!g||!n)return;let e=n===te;e?Lt():g.bindTexture(g.TEXTURE_2D,n);let s=t?g.REPEAT:g.CLAMP_TO_EDGE;g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_S,s),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_T,s),!e&&te&&g.bindTexture(g.TEXTURE_2D,te)}function Co(n,t){if(!g)return;let e=g.createShader(t);if(g.shaderSource(e,n),g.compileShader(e),Nt&&!g.getShaderParameter(e,g.COMPILE_STATUS))throw g.getShaderInfoLog(e);return e}function $n(n,t){if(!g)return;let e=g.createProgram();if(g.attachShader(e,Co(n,g.VERTEX_SHADER)),g.attachShader(e,Co(t,g.FRAGMENT_SHADER)),g.linkProgram(e),Nt&&!g.getProgramParameter(e,g.LINK_STATUS))throw g.getProgramInfoLog(e);return e}function ji(n,t=!1){if(!g)return;let e=g.createTexture(),s=!1;if(n!=null&&n.width)jr(e,n),g.bindTexture(g.TEXTURE_2D,e),s=!Cn&&ds(n.width)&&ds(n.height);else{let r=new Uint8Array([255,255,255,255]);g.bindTexture(g.TEXTURE_2D,e),g.texImage2D(g.TEXTURE_2D,0,g.RGBA,1,1,0,g.RGBA,g.UNSIGNED_BYTE,r)}let i=Cn?g.NEAREST:g.LINEAR,o=s?g.LINEAR_MIPMAP_LINEAR:i;g.texParameteri(g.TEXTURE_2D,g.TEXTURE_MAG_FILTER,i),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_MIN_FILTER,o);let a=t?g.REPEAT:g.CLAMP_TO_EDGE;return g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_S,a),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_T,a),s&&g.generateMipmap(g.TEXTURE_2D),g.bindTexture(g.TEXTURE_2D,te),e}function wc(n){g&&g.deleteTexture(n)}function jr(n,t){g&&(p((t==null?void 0:t.width)>0,"Invalid image data."),g.bindTexture(g.TEXTURE_2D,n),g.texImage2D(g.TEXTURE_2D,0,g.RGBA,g.RGBA,g.UNSIGNED_BYTE,t),!Cn&&ds(t.width)&&ds(t.height)&&g.generateMipmap(g.TEXTURE_2D),g.bindTexture(g.TEXTURE_2D,te))}function Hh(n){B||(us.add(n),g&&(n.glTexture?jr(n.glTexture,n.image):n.glTexture=ji(n.image,n.wrap)))}function Xh(n){if(B)return;us.delete(n);let t=n.glTexture;n.glTexture=void 0,wc(t)}function Lt(){if(G&&g&&Rt){let n=Yn?g.ONE:g.ONE_MINUS_SRC_ALPHA;g.blendFuncSeparate(g.SRC_ALPHA,n,g.ONE,n),g.enable(g.BLEND);let t=Rt*(Rn?Fi:Gr);g.bufferSubData(g.ARRAY_BUFFER,0,jt,0,t),Rn?g.drawArrays(g.TRIANGLE_STRIP,0,Rt):g.drawArraysInstanced(g.TRIANGLE_STRIP,0,4,Rt),++Pe,Le+=Rt,Rt=0}Yn=Mn}function Nr(n){!G||!g||(Lt(),n.drawImage(nt,0,0))}function Yh(n=!0){p(!nt,"must be called before engineInit"),Mr=n}function As(n,t,e,s,i=0,o=0,a=0,r=1,c=1,l=-1,u=0){(Rt>=Wh||Yn!==Mn)&&Lt(),Ts();let h=Rt++*Gr;jt[h++]=n,jt[h++]=t,jt[h++]=e,jt[h++]=s,jt[h++]=o,jt[h++]=a,jt[h++]=r,jt[h++]=c,ws[h++]=l,ws[h++]=u,jt[h++]=i}function Tc(n,t,e,s,i,o){As(n,t,e,s,i,0,0,0,0,0,o)}function Br(n,t,e,s,i,o,a,r=!0){let c=[],l=it(-a),u=lt(-a);for(let d of n){let f=d.x*i,y=d.y*o;c.push(b(e+u*f-l*y,s+l*f+u*y))}let h=r?Kh(c):c;Ac(h,t)}function zr(n,t,e,s,i,o,a,r,c=!0){let l=$h(n,e,c);Br(l,t,s,i,o,a,r,!1)}function Ac(n,t){if(!G||n.length<3)return;let e=n.length+2;if((Rt+e>=Un||Yn!==Mn)&&Lt(),p(e=Un)return;xc();let s=Rt*Fi;for(let i=e;i--;){let o=j(i-1,0,e-3),a=n[o];jt[s++]=a.x,jt[s++]=a.y,ws[s++]=t}Rt+=e}function Jr(n,t){if(!G||n.length<3)return;let e=n.length+2;if((Rt+e>=Un||Yn!==Mn)&&Lt(),p(e=Un)return;xc();let s=Rt*Fi;for(let i=e;i--;){let o=j(i-1,0,e-3),a=n[o],r=t[o];jt[s++]=a.x,jt[s++]=a.y,ws[s++]=r}Rt+=e}function os(n,t=!1){n?(pi=n,g.bindFramebuffer(g.FRAMEBUFFER,kr),g.framebufferTexture2D(g.FRAMEBUFFER,g.COLOR_ATTACHMENT0,g.TEXTURE_2D,n,0),Eo(t)):(Lt(),pi=void 0,g.bindFramebuffer(g.FRAMEBUFFER,null),g.viewport(0,0,I.x,I.y))}function Ec(n,t,e,s){G&&(g.enable(g.SCISSOR_TEST),g.scissor(n,t,e,s),g.clearColor(0,0,0,0),g.clear(g.COLOR_BUFFER_BIT),g.disable(g.SCISSOR_TEST))}function $h(n,t,e=!0){if(n.length<2)return[];let s=t/2,i=[],o=n.length,a=1e-6,r=10;for(let c=0;ca?-f/y:0,S=y>a?d/y:0,C=w>a?-v/w:0,A=w>a?x/w:0,T=_+C,P=S+A,k=(T*T+P*P)**.5;if(ka){let gt=et(1/$,r);T*=gt,P*=gt}}let pt=b(u.x-T*s,u.y-P*s),W=b(u.x+T*s,u.y+P*s);i.push(pt),i.push(W)}return i.length>1&&e&&(i.push(i[0]),i.push(i[1])),i}function Kh(n){if(n.length<3)return[];let t=(f,y,x)=>(y.x-f.x)*(x.y-f.y)-(y.y-f.y)*(x.x-f.x);(f=>{let y=0;for(let x=f.length;x--;){let v=(x+1)%f.length;y+=f[x].cross(f[v])}return y})(n)<0&&(n=n.slice().reverse());let s=1e-9,i=(f,y,x,v)=>{let w=t(y,x,f),_=t(x,v,f),S=t(v,y,f),C=(w<-s?1:0)+(_<-s?1:0)+(S<-s?1:0),A=(w>s?1:0)+(_>s?1:0)+(S>s?1:0);return!(C&&A)},o=[];for(let f=0;f3&&r++{if(C>=0){let T=s.fillStyle=s.createLinearGradient(v,w,_,S);T.addColorStop(0,h(C,2)),T.addColorStop(1,h(C,1))}else s.fillStyle="#000";C>=-1?(s.fill(),A&&s.stroke()):s.stroke()},c=(v,w,_,S=0,C=2*Y,A,T)=>{s.beginPath(),s.arc(v,w,_,f*S,f*C),r(v,w-_,v,w+_,A,T)},l=(v,w,_,S,C)=>{s.beginPath(),s.rect(v,w,_,S*f),r(v,w+S,v+_,w,C)},u=(v,w,_,S)=>{s.beginPath();for(let C of v)s.lineTo(C.x,C.y);s.closePath(),r(0,_,0,_+S,w)},h=(v,w)=>w?`hsl(${[.95,.56,.13][v%3]*360} 99%${[0,50,75][w]}%)`:"#000",d=Wa(1,1,n),f=Bt(d,.1,.5),y=et(6,et(o,a)/99);s.translate(o/2,a/2),s.scale(y,y),s.translate(-40,-35),f<1&&s.setLineDash([99*f,99]),s.lineJoin=s.lineCap="round",s.lineWidth=.1+f*1.9;{let w="LittleJS";s.font="900 15.5px arial",s.lineWidth=.1+f*3.9,s.textAlign="center",s.textBaseline="top",l(11,55,59,8*f,-1),s.beginPath();let _=0;for(let S=0;S5?1:0),s[S?"strokeText":"fillText"](w[C],P,54+.5,17*f),A+=T}s.lineWidth=.1+f*1.9,l(3,54,73,0)}l(7,15,26,-7,0),l(25,15,8,25,-1),l(10,40,15,-25,1),l(14,21,7,9,2),l(38,20,6,-6,2),l(49,20,10,-6,0);let x=[b(44,8),b(64,8),b(59,8+6*f),b(49,8+6*f)];u(x,2,8,6*f),l(44,8,20,-7,0);for(let v=5;v--;)c(59-v*6*f,30,10,0,2*Y,1,0);c(59,30,4,0,7,2),l(35,20,24,0),c(59,30,10),c(47,30,10,Y/2,Y*3/2),c(35,30,10,Y/2,Y*3/2),l(7,40,13,7,-1),l(17,40,43,14,-1);for(let v=3;v--;)for(let w=2;w--;)c(17+15*v,47,w?7:1,0,2*Y,2);for(let v=2;v--;){let w=6,_=7,S=53+w*f*v,C=[b(S+_,54),b(S,40),b(S+w*f,40),b(S+_+w*f,54)];u(C,0,40,14)}s.restore()}function Zh(n){if(bi=n,!yn){let e={};try{e=JSON.parse(localStorage[n]||"{}")}catch{e={}}Ni(s=>{s.unlocked=!!(e[s.id]&&e[s.id].unlocked)}),Vr()}Pn(void 0,t);function t(){if(!qs.length)return;let e=qs[0],s=cn-Ws;if(!Ws)Ws=cn;else if(s>yi)Ws=0,qs.shift();else{let i=yi-Bn,o=si?(s-i)/Bn:0;e.render(o)}}}function Ni(n){Object.values(Es).forEach(t=>n(t))}function td(){Ni(n=>n.unlocked=!1),Vr()}function Vr(){if(!bi)return;let n={};Ni(t=>{let e={name:t.name,description:t.description,icon:t.icon,unlocked:t.unlocked};t.image&&(e.src=t.image.src),n[t.id]=e}),localStorage[bi]=JSON.stringify(n)}function ed(n){yi=n}function nd(n){Bn=n}function sd(n){mi=n.copy()}function id(n){Ur=n}function Cc(n,t,e,s=125){let i,o,a,r,c,l,u,h,d,f,y,x,v,w=0,_,S=[],C=[],A=[],T=0,P=0,k=1,pt={},W=ts/s*60>>2;for(;k;T++)S=[k=h=x=0],e.forEach(($,gt)=>{for(u=t[$][T]||[0,0,0],k|=t[$][T]&&1,_=x+(t[$][0].length-2-(h?0:1))*W,v=gt===e.length-1,i=2,a=x;iW-99&&d&&y<1?y+=1/99:0)l=(1-y)*S[w++]/2||0,C[a]=(C[a]||0)-l*P+l,A[a]=(A[a++]||0)+l*P+l;c&&(y=c%1,P=u[1]||0,(c|=0)&&(S=pt[[f=u[w=0]||0,c]]=pt[[f,c]]||(r=[...n[f]],r[2]=(r[2]||220)*2**(c/12-1),c>0?Gi(...r):[])))}x=_});return[C,A]}function od(n){Wr=typeof n=="boolean"?n?1:0:n}function rd(n){qr=n}async function ad(){return new Ai(await Box2D()),e(),Pn(n,t),m;function n(){if(!_e){m.step(),m.objects=m.objects.filter(s=>!s.destroyed);for(let s of m.objects)s.body&&(s.pos=m.vec2From(s.body.GetPosition()),s.angle=-s.body.GetAngle())}}function t(){(qr||de)&&m.world.DrawDebugData()}function e(){let i=new m.instance.JSDraw,o=l=>new Et(l.get_r(),l.get_g(),l.get_b()),a=l=>o(m.instance.wrapPointer(l,m.instance.b2Color)),r=l=>a(l).scale(1,.8),c=(l,u)=>{let h=[];for(let d=u;d--;)h.push(m.vec2FromPointer(l+d*8));return h};i.DrawSegment=function(l,u,h){h=r(h),l=m.vec2FromPointer(l),u=m.vec2FromPointer(u),vn(l,u,.1,h,b(),0,!1)},i.DrawPolygon=function(l,u,h){h=r(h);let d=c(l,u);Wn(d,ln,.1,h,b(),0,!1)},i.DrawSolidPolygon=function(l,u,h){h=r(h);let d=c(l,u);Wn(d,h,0,h,b(),0,!1)},i.DrawCircle=function(l,u,h){h=r(h),l=m.vec2FromPointer(l),si(l,u*2,ln,.1,h,!1)},i.DrawSolidCircle=function(l,u,h,d){d=r(d),l=m.vec2FromPointer(l),h=m.vec2FromPointer(h).scale(u),si(l,u*2,d,.1,d,!1),vn(b(),h,.1,d,l,0,!1)},i.DrawTransform=function(l){l=m.instance.wrapPointer(l,m.instance.b2Transform);let u=m.vec2From(l.get_p()),h=-l.get_q().GetAngle(),d=b(1,0),f=z(.75,0,0,.8),y=b(0,1),x=z(0,.75,0,.8);vn(b(),d,.1,f,u,h,!1),vn(b(),y,.1,x,u,h,!1)},i.AppendFlags(m.instance.b2Draw.e_shapeBit),i.AppendFlags(m.instance.b2Draw.e_jointBit),m.world.SetDebugDraw(i)}}function cd(n,t,e,s=32,i=2,o=0){_c(n,t,e,V,s,ot,i,o,!1,!0)}function _c(n,t,e,s,i=1,o,a=.05,r=0,c=G,l,u){let h=e.offset(e.size),d=t.add(b(a-i*2)),f=b(i),y=t.scale(.5).subtract(f.scale(.5)),x=l?-1:1,v=l?-r:r;It(n,d,h,s,r,!1,o,c,l,u);for(let w=4;w--;){let _=w%2,S=y.multiply(b(_?w===1?1:-1:0,_?0:w?-1:1)),C=b(_?i:d.x,_?d.y:i),A=h.offset(e.size.multiply(b(w===1?1:w===3?-1:0,w===0?-x:w===2?x:0)));It(n.add(S.rotate(v)),C,A,s,r,!1,o,c,l,u)}for(let w=4;w--;){let _=w>1,S=w&&w<3,C=y.multiply(b(_?-1:1,S?-1:1)),A=h.offset(e.size.multiply(b(_?-1:1,S?x:-x)));It(n.add(C.rotate(v)),f,A,s,r,!1,o,c,l,u)}}function ld(n,t,e,s=32,i=2,o=0){Rc(n,t,e,V,s,ot,i,o,!1,!0)}function Rc(n,t,e,s,i=1,o,a=.05,r=0,c=G,l,u){let h=e.frame(0),d=e.frame(1),f=e.frame(2),y=t.add(b(a-i*2)),x=b(i),v=t.scale(.5).subtract(x.scale(.5)),w=l?-1:1,_=l?-r:r;It(n,y,f,s,r,!1,o,c,l,u);for(let S=4;S--;){let C=r+S*Y/2,A=S%2,T=v.multiply(b(A?S===1?1:-1:0,A?0:S?-w:w)),P=b(A?y.y:y.x,i);It(n.add(T.rotate(_)),P,d,s,C,!1,o,c,l,u)}for(let S=4;S--;){let C=r+S*Y/2,A=!S||S>2,T=S>1,P=v.multiply(b(A?-1:1,T?-w:w));It(n.add(P.rotate(_)),x,h,s,C,!1,o,c,l,u)}}function ud(n,t=1,e=0,s=V,i=0,o=!1,a=0,r=ot,c=G,l=!1,u){let h=Pc(b(),t,e,0,o);Wn(h,s,a,r,n,i,c,l,u)}function Pc(n,t=1,e=0,s=0,i=!1,o=Ls){p(O(n),"pos must be a vec2"),p(R(t)&&R(e),"size and percent must be numbers");let a=oe(e*4,4);a>=2&&(s+=Y),a=a<=2?a-1:3-a,i&&(a=-a,s+=Y);let r=[],c=Q(3,o>>1),l=t/2;for(let u=0;u<=c;u++){let h=u/c*Y;r.push(b(l*lt(h),l*it(h)).rotate(s).add(n))}for(let u=c;u>=0;u--){let h=u/c*Y;r.push(b(l*lt(h),-l*a*it(h)).rotate(s).add(n))}return r}function La(n){return n&&typeof n.lerp=="function"}function hd(n,t,e,s,i=1,o={}){p(n!=null&&typeof n=="object","tweenProperty target must be an object"),p(U(t)&&t.length>0,"tweenProperty propertyPath must be a non-empty string");let a=t.split("."),r=a.pop(),c=l=>{let u=n;for(let h of a)u=u[h];u[r]=l};return new Ei(c,e,s,i,o)}function Lc(n){n.loopRemaining!==1/0&&n.loopRemaining<=1||(n.loopRemaining!==1/0&&(n.loopRemaining-=1),n.life=n.duration,n.thenCallback=()=>Lc(n),Qt.push(n),n.callback(n.interp(n.duration)))}function Oc(n){if(n.loopRemaining!==1/0&&n.loopRemaining<=1)return;n.loopRemaining!==1/0&&(n.loopRemaining-=1);let t=n.start;n.start=n.end,n.end=t,n.life=n.duration,n.thenCallback=()=>Oc(n),Qt.push(n),n.callback(n.interp(n.duration))}function Dc(n,t){n===void 0?(n=Zt-Ra,t=cn-Pa,Ra=Zt,Pa=cn):t===void 0&&(t=n);for(let e=Qt.length;e--;){let s=Qt[e];if(s.paused)continue;let i=s.useRealTime?t:n;if(!(i<=0))if(s.life-=i,s.life>0)s.callback(s.interp(s.life));else{s.callback(s.interp(0)),Qt.splice(e,1);let o=s.thenCallback;s.thenCallback=void 0,o&&o()}}}function dd(){for(let n of Qt)n.thenCallback=void 0;Qt.length=0}var Hs,Xs,Cl,tr,wt,er,Oa,Zt,cn,_e,ao,Se,Ys,Da,Sn,uo,Nt,ka,Ri,Ga,Fe,nn,de,fe,wn,Tn,Vn,ho,je,he,Y,st,At,hs,$s,et,Q,ie,Ba,za,it,lt,Ja,sr,go,ct,Et,V,ln,ot,ye,Vl,rr,Wl,Ka,Qa,ql,Za,tc,Hl,Re,Pt,tt,H,cr,Pi,sn,Gn,rs,Fn,jn,lr,Cn,on,Ps,ur,B,G,Ls,Li,Oi,Di,Ii,hr,dr,fr,pr,gr,Be,qt,Zs,Mi,yr,as,xn,un,mr,ge,Kn,Ln,Qn,Zn,Os,dn,Xt,br,cs,ti,Ds,Yt,An,xr,vr,qe,F,ut,_t,Ue,tn,Ae,ze,I,hn,Pe,Le,Oe,He,nh,lc,ii,ke,Vt,Tr,we,Ar,oi,zn,en,Er,Nn,bt,re,K,Te,mn,co,qn,ae,_n,ri,Fs,Je,Qe,dc,Lr,fc,ms,bn,Hn,Aa,ai,ft,We,ts,xs,ci,an,En,ui,vs,Ss,vo,Vh,hi,nt,g,Mr,di,fi,Rn,Mn,Yn,te,So,Jn,jt,ws,Rt,us,wo,To,kr,pi,Ao,gi,Gr,mc,Wh,Fi,bc,Un,yn,yi,Bn,mi,Ur,Es,qs,bi,Ws,xi,Cs,_o,Ro,Gt,Po,q,Lo,Oo,Do,E,Wr,Io,ce,vi,Mo,ko,_s,Go,Fo,jo,No,m,qr,Rs,Si,Bo,zo,wi,$t,Jo,Ti,Uo,Vo,Wo,qo,Ho,Xo,Yo,$o,Ko,Qo,Ai,Qt,Ra,Pa,Ei,Ci,fd,lo,_i,Zo,Mc=jc(()=>{"use strict";Hs="LittleJS",Xs="1.18.19",Cl=60,tr=.016666666666666666,wt=[],er=[],Oa=0,Zt=0,cn=0,_e=!1;ao=0,Se=0,Ys=0,Da=!0,Sn=[],uo=class{constructor(t,e,s,i){this.update=t,this.render=e,this.glContextLost=s,this.glContextRestored=i}};Nt=!0,ka=.5,Ri=!0,Ga="Escape",Fe=!1,nn=[],de=!1,fe=!1,wn=!1,Tn=!1,Vn=!1;Y=Math.PI,st=Math.abs,At=Math.floor,hs=Math.ceil,$s=Math.round,et=Math.min,Q=Math.max,ie=n=>Math.sign(n),Ba=(...n)=>Math.hypot(...n),za=n=>Math.log2(n),it=Math.sin,lt=Math.cos,Ja=Math.tan,sr=Math.atan2;go=class{constructor(t=123456789){p(t!==0,"RandomGenerator seed must be non-zero (xorshift is fixed at 0)"),this.seed=t}float(t=1,e=0){return this.seed^=this.seed<<13,this.seed^=this.seed>>>17,this.seed^=this.seed<<5,e+(t-e)*((this.seed>>>0)/2**32)}int(t,e=0){return At(this.float(t,e))}bool(t=.5){return this.float().5?1:-1}floatSign(t=1,e=0){let s=et(t,e),o=Q(t,e)-s,a=this.float(o*2);return at?this.scale(t/e):this.copy()}dot(t){return this.x*t.x+this.y*t.y}cross(t){return this.x*t.y-this.y*t.x}reflect(t,e=1){return this.subtract(t.scale((1+e)*this.dot(t)))}angle(){return sr(this.x,this.y)}setAngle(t=0,e=1){return Kt(t),Kt(e),this.x=e*it(t),this.y=e*lt(t),this}rotate(t){Kt(t);let e=lt(-t),s=it(-t);return new n(this.x*e-this.y*s,this.x*s+this.y*e)}setDirection(t,e=1){return Kt(t),Kt(e),t=oe(t,4),p(t===0||t===1||t===2||t===3,"Vector2.setDirection() direction must be an integer between 0 and 3."),this.x=t%2?t-1?-e:e:0,this.y=t%2?0:t?-e:e,this}direction(){return st(this.x)>st(this.y)?this.x<0?3:1:this.y<0?2:0}abs(){return new n(st(this.x),st(this.y))}floor(){return new n(At(this.x),At(this.y))}snap(t){return Kt(t),new n(At(this.x*t)/t,At(this.y*t)/t)}mod(t=1){return new n(oe(this.x,t),oe(this.y,t))}area(){return st(this.x*this.y)}lerp(t,e){wa(t),Kt(e);let s=j(e);return new n(t.x*s+this.x*(1-s),t.y*s+this.y*(1-s))}arrayCheck(t){return this.x>=0&&this.y>=0&&this.x(u=oe(u,1))*6<1?c+(l-c)*6*u:u*2<1?l:u*3<2?c+(l-c)*(4-u*6):c;return this.r=r(a,o,t+1/3),this.g=r(a,o,t),this.b=r(a,o,t-1/3),this.a=i,is(this),this}HSLA(){let t=j(this.r),e=j(this.g),s=j(this.b),i=j(this.a),o=Q(t,e,s),a=et(t,e,s),r=(o+a)/2,c=0,l=0;if(o!==a){let u=o-a;l=r>.5?u/(2-o-a):u/(o+a),t===o?c=(e-s)/u+(e((s=j(s)*255|0)<16?"0":"")+s.toString(16);return"#"+e(this.r)+e(this.g)+e(this.b)+(t?e(this.a):"")}setHex(t){if(p(U(t),"Color hex code must be a string"),p(t[0]==="#","Color hex code must start with #"),p([4,5,7,9].includes(t.length),"Invalid hex"),t.length<6){let e=s=>j(parseInt(t[s],16)/15);this.r=e(1),this.g=e(2),this.b=e(3),this.a=t.length===5?e(4):1}else{let e=s=>j(parseInt(t.slice(s,s+2),16)/255);this.r=e(1),this.g=e(3),this.b=e(5),this.a=t.length===9?e(7):1}return is(this),this}rgbaInt(){let t=j(this.r)*255|0,e=j(this.g)*255<<8,s=j(this.b)*255<<16,i=j(this.a)*255<<24;return t+e+s+i}isValid(){return R(this.r)&&R(this.g)&&R(this.b)&&R(this.a)}},V=ee(z()),ln=ee(z(1,1,1,0)),ot=ee(z(0,0,0)),ye=ee(z(0,0,0,0)),Vl=ee(z(.5,.5,.5)),rr=ee(z(1,0,0)),Wl=ee(z(1,.5,0)),Ka=ee(z(1,1,0)),Qa=ee(z(0,1,0)),ql=ee(z(0,1,1)),Za=ee(z(0,0,1)),tc=ee(z(.5,0,1)),Hl=ee(z(1,0,1)),Re=class{constructor(t,e=!1){p(t===void 0||R(t),"Constructed Timer is invalid.",t),this.useRealTime=e;let s=this.getGlobalTime();this.time=t===void 0?void 0:s+t,this.setTime=t}set(t=0){p(R(t),"Timer is invalid.",t);let e=this.getGlobalTime();this.time=e+t,this.setTime=t}setUseRealTime(t=!0){p(!this.isSet(),"Cannot change global time setting while timer is set."),this.useRealTime=t}unset(){this.time=void 0}isSet(){return this.time!==void 0}active(){return this.getGlobalTime()=this.time}get(){return this.isSet()?this.getGlobalTime()-this.time:0}getPercent(){return this.isSet()?this.setTime?1-Bt(this.time-this.getGlobalTime(),0,this.setTime):1:0}getSetTime(){return this.isSet()?this.setTime:0}getGlobalTime(){return this.useRealTime?cn:Zt}toString(){return this.isSet()?st(this.get())+" seconds "+(this.get()<0?"before":"after"):"unset"}valueOf(){return this.get()}};Pt=b(),tt=0,H=32,cr=1,Pi=!0,sn=ye,Gn=b(1920,1080),rs=0,Fn=0,jn=b(),lr=!1,Cn=!0,on=1,Ps="arial",ur=!1,B=!1,G=!0,Ls=32,Li=b(16),Oi=0,Di=0,Ii=!0,hr=1,dr=1,fr=1,pr=0,gr=.8,Be=1,qt=b(),Zs=1,Mi=!0,yr=!0,as=!0,xn=!0,un=!1,mr=!1,ge=0,Kn=4,Ln=!0,Qn=0,Zn=!1,Os=!0,dn=!1,Xt=100,br=.3,cs=3,ti=0,Ds=!0,Yt=!0,An=.3,xr=40,vr=.7;qe=class n{constructor(t=b(),e=b(1),s,i=0,o=V,a=0){p(O(t),"object pos must be a vec2"),p(O(e),"object size must be a vec2"),p(!s||s instanceof Oe,"object tileInfo should be a TileInfo or undefined"),p(typeof i=="number"&&isFinite(i),"object angle should be a number"),p(J(o),"object color should be a valid rgba color"),p(typeof a=="number","object renderOrder should be a number"),this.pos=t.copy(),this.size=e.copy(),this.drawSize=void 0,this.tileInfo=s,this.angle=i,this.color=o.copy(),this.additiveColor=void 0,this.mirror=!1,this.destroyed=!1,this.mass=hr,this.damping=dr,this.angleDamping=fr,this.restitution=pr,this.friction=gr,this.gravityScale=1,this.renderOrder=a,this.velocity=b(),this.angleVelocity=0,this.spawnTime=Zt,this.children=[],this.clampSpeed=!0,this.groundObject=void 0,this.parent=void 0,this.localPos=b(),this.localAngle=0,this.collideTiles=!1,this.collideSolidObjects=!1,this.isSolid=!1,this.collideRaycast=!1,wt.push(this)}updateTransforms(){let t=this.parent;if(t){let e=t.getMirrorSign(),s=this.localPos,i=t.pos,o=s.x*e,a=s.y,r=t.angle;if(r){let c=lt(-r),l=it(-r);this.pos.set(o*c-a*l+i.x,o*l+a*c+i.y)}else this.pos.set(o+i.x,a+i.y);this.angle=e*this.localAngle+r}for(let e of this.children)e.updateTransforms()}updatePhysics(){if(p(!this.parent),this.destroyed)return;this.clampSpeed&&(this.velocity.x=j(this.velocity.x,-Be,Be),this.velocity.y=j(this.velocity.y,-Be,Be));let t=this.pos.copy();if(this.velocity.x*=this.damping,this.velocity.y*=this.damping,this.mass&&(this.velocity.x+=qt.x*this.gravityScale,this.velocity.y+=qt.y*this.gravityScale),this.pos.x+=this.velocity.x,this.pos.y+=this.velocity.y,this.angle+=this.angleVelocity*=this.angleDamping,p(this.angleDamping>=0&&this.angleDamping<=1),p(this.damping>=0&&this.damping<=1),!Ii||!this.mass)return;let e=this.velocity.y<0&&qt.y<0||this.velocity.y>0&&qt.y>0;if(this.groundObject){let s=Q(this.friction,this.groundObject.friction),i=this.groundObject.velocity.x;this.velocity.x=i+(this.velocity.x-i)*s,this.groundObject=void 0}if(this.collideSolidObjects)for(let i of er){if(i.destroyed||i.parent||i===this||!this.isSolid&&!i.isSolid||!this.isOverlappingObject(i))continue;let o=this.collideWithObject(i),a=i.collideWithObject(this);if(!o||!a)continue;if(Qs(t,this.size,i.pos,i.size)){let d=t.subtract(i.pos),f=d.length(),x=f<.001?b(0,1):d.scale(.001/f);this.velocity=this.velocity.add(x),i.mass&&(i.velocity=i.velocity.subtract(x)),de&&fo(this.pos,this.size,i.pos,i.size,"#f00");continue}let r=this.size.add(i.size),c=(t.y-i.pos.y)*2>r.y+qt.y,l=st(t.y-i.pos.y)*20?-1:1)>0?At(t.y-this.size.y/2+1)+this.size.y/2+.001:hs(t.y+this.size.y/2-1)-this.size.y/2-.001;if(st(u-this.pos.y)<.1&&!Ze(b(this.pos.x,u),this.size,this)){this.pos.y=u,de&&xt(this.pos,this.size,"#ff0");return}this.pos.x=t.x,this.velocity.x*=-a}if(o||!i){if(e){let c=this.size.y/2+1e-4;this.pos.y=qt.y<0?At(t.y-this.size.y/2)+c:hs(t.y+this.size.y/2)-c,this.groundObject=s}else this.pos.y=t.y,this.groundObject=void 0;this.velocity.y*=-a}de&&xt(this.pos,this.size,"#f00")}}}update(){}render(){It(this.pos,this.drawSize||this.size,this.tileInfo,this.color,this.angle,this.mirror,this.additiveColor)}renderLight(){}destroy(t=!1){var e;if(!this.destroyed){this.destroyed=!0,(e=this.parent)==null||e.removeChild(this);for(let s of this.children)s.parent=void 0,s.destroy(t)}}localToWorld(t){return this.pos.add(t.rotate(this.angle))}worldToLocal(t){return t.subtract(this.pos).rotate(-this.angle)}localToWorldVector(t){return t.rotate(this.angle)}worldToLocalVector(t){return t.rotate(-this.angle)}collideWithTile(t,e){return t>0}collideWithObject(t){return!0}getUp(t=1){return b().setAngle(this.angle,t)}getRight(t=1){return b().setAngle(this.angle+Y/2,t)}getAliveTime(){return Zt-this.spawnTime}getSpeed(){return this.velocity.length()}applyAcceleration(t){this.mass&&(this.velocity=this.velocity.add(t))}applyAngularAcceleration(t){this.mass&&(this.angleVelocity+=t)}applyForce(t){this.mass&&this.applyAcceleration(t.scale(1/this.mass))}getMirrorSign(){return this.mirror?-1:1}addChild(t,e=b(),s=0){return p(!this.destroyed,"cannot add child to destroyed object"),this.destroyed||(p(!t.parent&&!this.children.includes(t)),p(t instanceof n,"child must be an EngineObject"),p(t!==this,"cannot add self as child"),this.children.push(t),t.parent=this,t.localPos=e.copy(),t.localAngle=s,t.updateTransforms()),t}removeChild(t){p(t.parent===this&&this.children.includes(t)),this.children.splice(this.children.indexOf(t),1),t.parent=void 0}isOverlappingObject(t){return this.isOverlapping(t.pos,t.size)}isOverlapping(t,e=b()){return Qs(this.pos,this.size,t,e)}setCollision(t=!0,e=!0,s=!0,i=!0){p(t||!e,"solid objects must be set to collide"),this.collideSolidObjects=t,this.isSolid=e,this.collideTiles=s,this.collideRaycast=i}toString(){let t="type = "+this.constructor.name;return(this.pos.x||this.pos.y)&&(t+=`
 pos = `+this.pos),(this.velocity.x||this.velocity.y)&&(t+=`
 velocity = `+this.velocity),(this.size.x||this.size.y)&&(t+=`
 size = `+this.size),this.angle&&(t+=`
 angle = `+this.angle.toFixed(3)),this.color&&(t+=`
-color = `+this.color),t}renderDebugInfo(){if(!jt)return;let t=this.collideTiles||this.collideSolidObjects||this.isSolid;if(!t&&!this.parent)return;let e=b(K(this.size.x,.2),K(this.size.y,.2)),s=J(this.collideTiles?1:0,this.collideSolidObjects?1:0,this.isSolid?1:0,.5);bt(this.pos,e,s,0,this.angle,t),this.parent&&bt(this.pos,e.scale(.8),J(1,1,1,.5),0,this.angle),this.parent&&we(this.pos,this.parent.pos,J(1,1,1,.5),.5)}},I=b(),cn=[];Re=class n{constructor(t=b(),e=Li,s=cn[0],i=Oi,o=Di){this.pos=t.copy(),this.size=e.copy(),this.padding=i,this.textureInfo=s,this.bleed=o}offset(t){return new n(this.pos.add(t),this.size,this.textureInfo,this.padding,this.bleed)}frame(t){f(typeof t=="number");let e=this.size.x+this.padding*2,s=t*e;return f(s+this.size.x<=this.textureInfo.size.x,"frame extends beyond texture width!"),this.offset(new rt(s))}setFullImage(t=this.textureInfo){return this.textureInfo=t,this.pos=new rt,this.size=t.size.copy(),this.bleed=this.padding=0,this}tile(t){return Ds(t,this.size,this.textureInfo,this.padding,this.bleed)}},Ve=class{constructor(t,e=!0,s=!1){this.image=t,this.size=t?b(t.width,t.height):b(),this.sizeInverse=t?b(1/t.width,1/t.height):b(),this.glTexture=void 0,this.wrap=s,e&&this.createWebGLTexture()}createWebGLTexture(){Hh(this)}destroyWebGLTexture(){Xh(this)}hasWebGL(){return!!this.glTexture}setWrap(t=!0){this.wrap=t,Sc(this.glTexture,t)}};nh=0;ii=class{constructor(t){f(!!t,"tileInfo is required for ImageFont"),this.tileInfo=t.frame(0)}drawText(t,e,s=1,i,o,a,r){f(O(s)||typeof s=="number","size must be a vec2 or number"),typeof s=="number"?(f(s>0),s*=H,s=new rt(s,s)):s=s.scale(H),this.drawTextScreen(t,Pn(e),s,i,o,a,r)}drawTextScreen(t,e,s,i=!0,o=W,a=G,r){f(V(t),"text must be a string"),f(O(e),"pos must be a vec2"),f(O(s)||typeof s=="number","size must be a vec2 or number"),f(U(o),"color must be a color"),s=typeof s=="number"?new rt(s,s):s;let c=new rt,l=this.tileInfo,u=l.padding,h=l.size.x+u*2,p=l.size.y+u*2,d=l.textureInfo.size.x/h|0;(t+"").split(`
-`).forEach((y,x)=>{let v=i?(y.length-1)*s.x/2:0;for(let w=y.length;w--;){let _=y.charCodeAt(w),S=_<32||_>127?95:_-32,C=S%d,A=S/d|0;l.pos.x=C*h+u,l.pos.y=A*p+u,c.x=e.x+w*s.x-v|0,c.y=e.y+x*s.y|0,Mt(c,s,l,o,0,!1,void 0,a,!0,r)}})}};De=b(),Jt=b(),Tr=b(),xe=b(),Ar=0,oi=!0,Bn=!1,Qe="mouse",Er=6,Fn=!0,mt=0,ie=!z&&window.ontouchstart!==void 0;Y=[[]],ve=[],pn=[],co=[],Vn=new Ee,oe=[],An=[],ri=[],Gs=[],Be=new Map,ys=[],Wn=!0;ai="http://www.w3.org/2000/svg";ft=new AudioContext,Qn=44100;bs=class{constructor(t,e,s=xr,i=vr,o){var a;if(!(!Ht||z)){if(f(!t||de(t)||V(t),"asset must be a file name or zzfx array"),f(e===void 0||L(e),"randomness must be a number"),f(e===void 0||e>=0&&e<=1,"randomness must be between 0 and 1"),f(L(s),"range must be a number"),f(L(i),"taper must be a number"),this.range=s,this.taper=i,this.randomness=e!=null?e:0,this.sampleRate=Qn,this.loadedPercent=0,this.onloadCallback=o,de(t)){let r=t.slice(),c=e!=null?e:.05,l=1;this.randomness=(a=r[l])!=null?a:c,r[l]=0,this.sampleChannels=[Gi(...r)],this.loadedPercent=1,o==null||o(this)}else if(typeof t=="string"){let r=t;this.loadSound(r)}}}play(t,e=1,s=1,i=1,o=!1,a=!1){if(f(!t||O(t),"pos must be a vec2"),f(L(e),"volume must be a number"),f(L(s),"pitch must be a number"),f(L(i),"randomnessScale must be a number"),!Ht||z||!this.sampleChannels)return;let r;if(t){let u=this.range;if(u){let h=_t.distanceSquared(t);if(h>u*u)return;e*=Bt(h**.5,u,u*this.taper)}r=Pn(t).x*2/B.width-1}let c=s+s*this.randomness*i*dt(-1,1),l=new ci(this,e,c,r,o,a);return jt&&Jn&&t&&(Ut(t,.5,"#0ff",.5,!0),this.range&&(Ut(t,2*this.range,"#0ff",.5),Ut(t,2*this.range*this.taper,"#0ff",.5)),In("vol "+e.toFixed(2)+" pitch "+c.toFixed(2),t,.5,"#0ff",.5)),l}playMusic(t=1,e=!0,s=!1){return this.play(void 0,t,1,0,e,s)}playNote(t=0,e,s){f(L(t),"semitoneOffset must be a number");let i=gc(t,1);return this.play(e,s,i,0)}getDuration(){var t,e;return((e=(t=this.sampleChannels)==null?void 0:t[0])==null?void 0:e.length)/this.sampleRate||0}isLoaded(){return this.loadedPercent===1}async loadSound(t){var c;let e=await fetch(t);if(!e.ok)throw new Error(`Failed to load sound from ${t}: ${e.status} ${e.statusText}`);let s=await e.arrayBuffer(),i=await ft.decodeAudioData(s),o=i.numberOfChannels,a=1e5,r=[];for(let l=0;lsetTimeout(v,0));let d=tt(p+a,h);for(;p=0,"Sound volume must be positive or zero"),f(s>=0,"Sound rate must be positive or zero"),f(L(i),"Sound pan must be a number"),this.sound=t,this.volume=e,this.rate=s,this.pan=i,this.loop=o,this.pausedTime=0,this.startTime=void 0,this.gainNode=void 0,this.source=void 0,this.onendedCallback=r=>{r===this.source&&(this.source=void 0)},a||this.start()}start(t=0){f(t>=0,"Sound start offset must be positive or zero"),this.isPlaying()&&this.stop(),this.gainNode=ft.createGain(),this.source=Ir(this.sound.sampleChannels,this.volume,this.rate,this.pan,this.loop,this.sound.sampleRate,this.gainNode,t,this.onendedCallback),this.source?(this.startTime=ft.currentTime-t,this.pausedTime=void 0):(this.startTime=void 0,this.pausedTime=0)}setVolume(t){f(t>=0,"Sound volume must be positive or zero"),this.volume=t,this.gainNode&&(this.gainNode.gain.value=t)}stop(t=0){if(f(t>=0,"Sound fade time must be positive or zero"),this.isPlaying())if(t){let e=ft.currentTime,s=e+t;this.gainNode.gain.cancelScheduledValues(e),this.gainNode.gain.setValueAtTime(this.volume,e),this.gainNode.gain.linearRampToValueAtTime(0,s),this.source.stop(s)}else this.source.stop();this.pausedTime=0,this.source=void 0,this.startTime=void 0}pause(){this.isPaused()||(this.pausedTime=this.getCurrentTime(),this.source.stop(),this.source=void 0,this.startTime=void 0)}resume(){this.isPaused()&&this.start(this.pausedTime)}isPlaying(){return!!this.source}isPaused(){return!this.isPlaying()}getCurrentTime(){if(!this.isPlaying())return this.pausedTime;let t=this.getDuration();return t?se(ft.currentTime-this.startTime,t):0}getDuration(){return this.rate?this.sound.getDuration()/this.rate:0}getSource(){return this.source}};sn=[];wn=class{constructor(t,e=0,s=!1,i=new wt){this.tile=t,this.direction=e,this.mirror=s,this.color=i.copy()}clear(){this.tile=this.direction=0,this.mirror=!1,this.color=new wt}},ui=class extends Ue{constructor(t,e,s=0,i=0,o=b(512),a=!0){var r;f(O(o),"canvasSize must be a Vector2"),super(t,e,void 0,s,W,i),this.canvas=z?void 0:new OffscreenCanvas(o.x,o.y),this.context=(r=this.canvas)==null?void 0:r.getContext("2d"),this.textureInfo=new Ve(this.canvas,a),this.mass=0}destroy(){this.destroyed||(this.textureInfo.destroyWebGLTexture(),super.destroy())}render(){this.draw(this.pos,this.size,this.color,this.angle,this.mirror,this.additiveColor)}draw(t,e,s=W,i=0,o=!1,a,r=!1,c){let l=new Re().setFullImage(this.textureInfo),u=this.hasWebGL();Mt(t,e,l,s,i,o,a,u,r,c)}updateWebGL(){this.textureInfo.createWebGLTexture()}hasWebGL(){return G&&this.textureInfo.hasWebGL()}},xs=class extends ui{constructor(t,e,s=Ds(),i=0,o=!0){let a=s?e.multiply(s.size):e;if(super(t,e,0,i,a,o),this.tileInfo=void 0,this.data=[],this.isUsingWebGL=!1,z){this.render=()=>{},this.redraw=()=>{},this.redrawStart=()=>{},this.redrawEnd=()=>{},this.drawTileData=()=>{},this.redrawTileData=()=>{},this.drawLayerTile=()=>{},this.drawLayerRect=()=>{},this.drawTile=()=>{},this.drawRect=()=>{},this.clearLayerRect=()=>{};return}s&&(this.tileInfo=s.frame(0),this.tileInfo.bleed=0);for(let r=this.size.area();r--;)this.data.push(new wn)}setData(t,e,s=!1){if(t=t.floor(),f(O(t),"layerPos must be a Vector2"),f(e instanceof wn,"data must be a TileLayerData"),!t.arrayCheck(this.size)||(this.data[(t.y|0)*this.size.x+(t.x|0)]=e,!s))return;Et===this.context?this.drawTileData(t):this.redrawTileData(t)}clearData(t,e=!1){this.setData(t,new wn,e)}getData(t){return f(O(t),"layerPos must be a Vector2"),t.arrayCheck(this.size)?this.data[(t.y|0)*this.size.x+(t.x|0)]:void 0}update(){!G&&this.isUsingWebGL&&(this.isUsingWebGL=!1,this.redraw())}render(){f(Et!==this.context,"must call redrawEnd() after drawing tiles!");let t=this.drawSize||this.size,e=this.pos.add(t.scale(.5));this.draw(e,this.size,this.color,this.angle,this.mirror,this.additiveColor)}onRedraw(){}redraw(){this.redrawStart(!0);for(let t=this.size.x;t--;)for(let e=this.size.y;e--;)this.drawTileData(b(t,e),!1);this.isUsingWebGL&&Rt(),this.onRedraw(),this.redrawEnd()}redrawStart(t=!1){var s,i;if(!this.context)return;f(Et!==this.context),this.savedRenderSettings=[Et,I,_t,H,tn],Et=this.context;let e=(i=(s=this.tileInfo)==null?void 0:s.size)!=null?i:b(1);I=this.size.multiply(e),tn=pe,_t=this.size.multiply(e).scale(.5),H=1,this.isUsingWebGL=this.hasWebGL(),this.isUsingWebGL?is(this.textureInfo.glTexture,t):(this.context.imageSmoothingEnabled=!Tn,t&&(this.canvas.width=I.x,this.canvas.height=I.y))}redrawEnd(){this.context&&(f(Et===this.context),this.isUsingWebGL&&is(),[Et,I,_t,H,tn]=this.savedRenderSettings)}drawTileData(t,e=!0){var r,c;if(!this.context)return;f(Et===this.context,"must call redrawStart() before drawing tiles");let s=(c=(r=this.tileInfo)==null?void 0:r.size)!=null?c:b(1),i=t.multiply(s);e&&this.clearLayerRect(i,s);let o=this.getData(t);if(!o||!o.tile)return;let a=this.tileInfo&&this.tileInfo.tile(o.tile);this.drawLayerTile(i,s,a,o.color,o.direction*X/2,o.mirror)}redrawTileData(t,e=!0){this.context&&(f(Et!==this.context,"redrawStart() should not be active when calling redrawTileData(), instead use drawTileData()"),this.redrawStart(),this.drawTileData(t,e),this.redrawEnd())}drawLayerTile(t,e=b(1),s,i=W,o=0,a,r){let c=t.add(e.scale(.5));Mt(c,e,s,i,o,a,r,this.isUsingWebGL)}drawLayerRect(t,e,s,i=0){this.drawLayerTile(t,e,void 0,s,i)}drawTile(t,e=b(1),s,i=new wt,o=0,a=!1){t=t.subtract(this.pos).multiply(this.tileInfo.size),e=e.multiply(this.tileInfo.size),t.y=this.canvas.height-t.y;let r=I;I=b(this.canvas.width,this.canvas.height);let c=this.hasWebGL();c&&is(this.textureInfo.glTexture);let l=c?void 0:this.context;Mt(t,e,s,i,o,a,void 0,c,!0,l),c&&is(),I=r}drawRect(t,e,s,i){this.drawTile(t,e,void 0,s,i)}clearLayerRect(t,e){f(Et===this.context,"must call redrawStart() before clearing tiles");let s=t.x,i=this.canvas.height-t.y-e.y;this.hasWebGL()?Ec(s,i,e.x,e.y):this.context.clearRect(s,i,e.x,e.y)}},vs=class extends xs{constructor(t,e,s=Ds(),i=0,o=!0){super(t,e.floor(),s,i,o),this.collisionData=[],this.initCollision(this.size),sn.push(this),this.isSolid=!0}destroy(){if(this.destroyed)return;let t=sn.indexOf(this);f(t>=0,"tile collision layer not found in array"),t>=0&&sn.splice(t,1),super.destroy()}initCollision(t){f(O(t),"size must be a Vector2"),this.size=t.floor(),this.collisionData=[],this.collisionData.length=t.area(),this.collisionData.fill(0)}setCollisionData(t,e=1){f(O(t),"layerPos must be a Vector2");let s=(t.y|0)*this.size.x+(t.x|0);t.arrayCheck(this.size)&&(this.collisionData[s]=e)}clearCollisionData(t){this.setCollisionData(t,0)}getCollisionData(t){f(O(t),"layerPos must be a Vector2");let e=(t.y|0)*this.size.x+(t.x|0);return t.arrayCheck(this.size)?this.collisionData[e]:0}collisionTest(t,e=new rt,s){f(O(t)&&O(e),"pos and size must be Vector2s"),f(!s||typeof s=="function"||s instanceof Ue,"callbackObject must be a function or EngineObject");let i=s?typeof s=="function"?(p,d)=>s(p,d):(p,d)=>s.collideWithTile(p,d):()=>!0,o=t.x-this.pos.x,a=t.y-this.pos.y;if(o+e.x/2<0||o-e.x/2>this.size.x||a+e.y/2<0||a-e.y/2>this.size.y)return!1;let r=K(o-e.x/2|0,0),c=K(a-e.y/2|0,0),l=tt(K(o+e.x/2,r+1),this.size.x),u=tt(K(a+e.y/2,c+1),this.size.y),h=new rt;for(let p=c;ps(l,u):(l,u)=>s.collideWithTile(l,u):l=>l>0,a=l=>{let u=this.getCollisionData(r.set(l.x-this.pos.x,l.y-this.pos.y));return u&&o(u,l)},r=new rt,c=qa(t,e,a,i);if(he&&c){let l=c.floor().add(b(.5));bt(l,b(1),"#f008"),we(t,e,"#00f",.02),we(t,c,"#f00",.02),nr(c,"#0f0"),i&&we(c,c.add(i),"#ff0",.02)}return c}},vo=class extends Ue{constructor(t,e,s=0,i=0,o=100,a=X,r,c=W,l=W,u=rn,h=rn,p=.5,d=.1,y=1,x=.1,v=.05,w=1,_=1,S=0,C=X,A=.1,T=.2,P=!1,M=!1,pt=!0,at=M?1e9:0,ct=!1){super(t,b(),r,e,void 0,at),this.emitCircle=typeof s=="number",this.emitSize=typeof s=="number"?b(s):s.copy(),this.emitTime=i,this.emitRate=o,this.emitConeAngle=a,this.colorStartA=c.copy(),this.colorStartB=l.copy(),this.colorEndA=u.copy(),this.colorEndB=h.copy(),this.randomColorLinear=pt,this.particleTime=p,this.sizeStart=d,this.sizeEnd=y,this.speed=x,this.angleSpeed=v,this.damping=w,this.angleDamping=_,this.gravityScale=S,this.particleConeAngle=C,this.fadeRate=A,this.randomness=T,this.collideTiles=P,this.additive=M,this.localSpace=ct,this.trailScale=0,this.particleCreateCallback=void 0,this.particleDestroyCallback=void 0,this.particleCollideCallback=void 0,this.velocityInheritance=0,this.emitTimeBuffer=0,this.particles=[],this.previousAngle=this.angle,this.previousPos=this.pos.copy()}update(){if(f(this.angleDamping>=0&&this.angleDamping<=1),f(this.damping>=0&&this.damping<=1),this.velocityInheritance){let s=this.velocityInheritance;this.velocity.x=s*(this.pos.x-this.previousPos.x),this.velocity.y=s*(this.pos.y-this.previousPos.y),this.angleVelocity=s*(this.angle-this.previousAngle),this.previousAngle=this.angle,this.previousPos.x=this.pos.x,this.previousPos.y=this.pos.y}if(this.isActive()){if(this.emitRate&&Zs){let s=1/this.emitRate/Zs;for(this.emitTimeBuffer+=tr;this.emitTimeBuffer>0;this.emitTimeBuffer-=s)this.emitParticle()}}else this.particles.length===0&&this.destroy(!0);let t=this.particles,e=0;for(let s=0;s_+_*dt(s,-s),o=i(this.particleTime),a=i(this.sizeStart),r=i(this.sizeEnd),c=i(this.speed),l=i(this.angleSpeed)*Xa(),u=dt(this.emitConeAngle,-this.emitConeAngle),h=po(this.colorStartA,this.colorStartB,this.randomColorLinear),p=po(this.colorEndA,this.colorEndB,this.randomColorLinear),d=this.localSpace?u:this.angle+u,y=b(c*st(d),c*lt(d)),x=l;!this.localSpace&&this.velocityInheritance>0&&(y.x+=this.velocity.x,y.y+=this.velocity.y,x+=this.angleVelocity);let v=new hi(this,t,e,h,p,o,a,r,y,x);return this.particles.push(v),(w=this.particleCreateCallback)==null||w.call(this,v),v}updatePhysics(){}render(){for(let t of this.particles)t.render()}isActive(){return!this.emitTime||this.getAliveTime()0&&(this.destroyed=!1,this.emitTime=-1))}},Vh=new rt,hi=class{constructor(t,e,s,i,o,a,r,c,l=b(),u=0){this.emitter=t,this.pos=e,this.angle=s,this.size=b(r),this.color=i.copy(),this.colorStart=i,this.colorEnd=o,this.lifeTime=a,this.sizeStart=r,this.sizeEnd=c,this.velocity=l,this.angleVelocity=u,this.spawnTime=Kt,this.mirror=Ha(),this.groundObject=void 0,this.destroyed=!1,this.tileInfo=t.tileInfo}update(){let t=this.emitter,e=t.damping,s=t.angleDamping,i=t.restitution,o=t.friction,a=t.gravityScale,r=t.collideTiles,c=t.particleCollideCallback;if(this.lifeTime>0&&Kt-this.spawnTime>this.lifeTime){this.destroy();return}let l=this.pos.copy();if(this.velocity.x*=e,this.velocity.y*=e,this.pos.x+=this.velocity.x+=Vt.x*a,this.pos.y+=this.velocity.y+=Vt.y*a,this.angle+=this.angleVelocity*=s,!Ii||!r)return;let u=this.velocity.lengthSquared();if(u>Fe*Fe){let p=Fe/u**.5;this.velocity.x*=p,this.velocity.y*=p}this.groundObject=void 0;let h=c?p=>{let d=li(p);return d&&c(this,d,p)}:p=>li(p)>0;if(h(this.pos)){let p=$e(this.pos);if(!h(l)){let d=h(b(this.pos.x,l.y)),y=h(b(l.x,this.pos.y)),x=K(i,p.restitution),v=K(o,p.friction);d&&(this.pos.x=l.x,this.velocity.x*=-x,this.velocity.y*=v),(y||!d)&&((this.velocity.y<0&&Vt.y<0||this.velocity.y>0&&Vt.y>0)&&(this.groundObject=p),this.pos.y=l.y,this.velocity.y*=-x,this.velocity.x*=v),ue&&bt(this.pos,this.size,"#f00")}}}destroy(){let t=this.emitter.particleDestroyCallback,e=this.colorEnd;this.color.set(e.r,e.g,e.b,e.a),this.size.set(this.sizeEnd,this.sizeEnd),this.destroyed=!0,t==null||t(this)}render(){let t=this.emitter,e=t.localSpace,s=t.additive,i=t.trailScale,o=t.fadeRate/2,a=this.lifeTime>0?tt((Kt-this.spawnTime)/this.lifeTime,1):1,r=1-a,c=r*this.sizeStart+a*this.sizeEnd,l=b(c),u=a1-o?(1-a)/o:1;this.color.r=r*this.colorStart.r+a*this.colorEnd.r,this.color.g=r*this.colorStart.g+a*this.colorEnd.g,this.color.b=r*this.colorStart.b+a*this.colorEnd.b,this.color.a=(r*this.colorStart.a+a*this.colorEnd.a)*u;let h=Vh.set(this.pos.x,this.pos.y),p=this.angle;if(e){let d=t.angle,y=lt(-d),x=st(-d);h.set(t.pos.x+h.x*y-h.y*x,t.pos.y+h.x*x+h.y*y),p+=d}if(s&&fs(),i){let d=e?this.velocity.rotate(t.angle):this.velocity,y=d.length();if(y){let x=y*i;l.y=K(l.x,x),p=sr(d.x,d.y),Mt(h,l,this.tileInfo,this.color,p,this.mirror)}}else Mt(h,l,this.tileInfo,this.color,p,this.mirror);s&&fs(!1),xn&&bt(h,l,"#f005",0,p)}},Mr=!0,Ao=!0,gi=5e5,Gr=11,mc=Gr*4,Wh=gi/mc|0,Fi=3,bc=Fi*4,zn=gi/bc|0;fn=!1,yi=5,jn=.5,mi=b(640,80),Ur=!1,As={},qs=[];xi=class{constructor(t,e,s="",i="\u{1F3C6}",o){f(t>=0&&!As[t]),this.id=t,this.name=e,this.description=s,this.icon=i,this.unlocked=!1,this.image=void 0,o&&((this.image=new Image).src=o),As[t]=this}unlock(){Ur||this.unlocked||(f(bi,"save name must be set"),this.unlocked=!0,Vr(),qs.push(this))}render(t=0){let e=ut,s=tt(mi.x,B.width),i=mi.y,o=B.width-s,a=-i*t,r=Ge(0,0,.9);e.save(),e.beginPath(),e.fillStyle=r.toString(),e.strokeStyle=it.toString(),e.lineWidth=3,e.rect(o,a,s,i),e.fill(),e.stroke(),e.clip();let c=b(.1,.05).scale(i),l=i-2*c.x;this.renderIcon(b(o+c.x+l/2,a+i/2),l);let u=i*.5,h=i*.3,p=b(o+l+2*c.x,a+c.y*2+u/2),d=s-l-3*c.x;nn(this.name,p,u,it,0,void 0,"left",void 0,void 0,d),p.y=a+i-c.y*2-h/2,nn(this.description,p,h,it,0,void 0,"left",void 0,void 0,d),e.restore()}renderIcon(t,e){this.image?ut.drawImage(this.image,t.x-e/2,t.y-e/2,e,e):nn(this.icon,t,e*.7,it)}};_o=class extends xi{constructor(t,e,s,i,o){super(t,e,s,i,o)}unlock(){super.unlock(),Es&&Es.unlockMedal(this.id)}},Ro=class{constructor(t,e,s){var c,l,u;f(!Es,"there can only be one newgrounds object"),f(!e||s,"must provide cryptojs if there is a cipher"),Es=this,this.app_id=t,this.cipher=e,this.cryptoJS=s,this.host=location?location.hostname:"";let i=new URL(location.href);if(this.session_id=i.searchParams.get("ngio_session_id"),!this.session_id)return;let o=this.call("Medal.getList");if(!o||!o.result||o.result.error){fn&&xt("Newgrounds session unavailable; skipping plugin init"),this.medals=[],this.scoreboards=[];return}this.medals=((c=o.result.data)==null?void 0:c.medals)||[],fn&&xt(this.medals);for(let h of this.medals){let p=As[h.id];p&&(p.image=new Image,p.image.src=h.icon,p.name=h.name,p.description=h.description,p.unlocked=h.unlocked,p.difficulty=h.difficulty,p.value=h.value,p.value&&(p.description=p.description+` (${p.value})`))}let a=this.call("ScoreBoard.getBoards");this.scoreboards=((u=(l=a==null?void 0:a.result)==null?void 0:l.data)==null?void 0:u.scoreboards)||[],fn&&xt(this.scoreboards);let r=60*1e3;setInterval(()=>this.call("Gateway.ping",0,!0),r)}unlockMedal(t){return this.call("Medal.unlock",{id:t},!0)}postScore(t,e){return this.call("ScoreBoard.postScore",{id:t,value:e},!0)}getScores(t,e,s=0,i=0,o=10){return this.call("ScoreBoard.getScores",{id:t,user:e,social:s,skip:i,limit:o})}logView(){return this.call("App.logView",{host:this.host},!0)}call(t,e,s=!1){let i={component:t,parameters:e};if(this.cipher){let l=this.cryptoJS,u=l.enc.Base64.parse(this.cipher),h=l.lib.WordArray.random(16),p=l.AES.encrypt(JSON.stringify(i),u,{iv:h});i.secure=l.enc.Base64.stringify(h.concat(p.ciphertext)),i.parameters=0}let o={app_id:this.app_id,session_id:this.session_id,call:i},a=new FormData;a.append("input",JSON.stringify(o));let r=new XMLHttpRequest;r.open("POST","https://newgrounds.io/gateway_v3.php",!fn&&s);try{r.send(a)}catch(l){fn&&xt("newgrounds call failed",l);return}return fn&&xt(r.responseText),r.responseText&&JSON.parse(r.responseText)}},Po=class{constructor(t,e=!1,s=!1){f(!kt,"Post process already initialized"),f(!(e&&s),"Post process cannot both include main canvas and use feedback texture"),kt=this,t||(t="void mainImage(out vec4 c,vec2 p){c=texture(iChannel0,p/iResolution.xy);}"),this.shader=void 0,this.texture=void 0,this.vao=void 0,i(),Cn(void 0,r,o,a);function i(){if(z)return;if(!G){console.warn("PostProcessPlugin: WebGL not enabled!");return}kt.texture=ji(),kt.shader=Xn(`#version 300 es
+color = `+this.color),t}renderDebugInfo(){if(!Nt)return;let t=this.collideTiles||this.collideSolidObjects||this.isSolid;if(!t&&!this.parent)return;let e=b(Q(this.size.x,.2),Q(this.size.y,.2)),s=z(this.collideTiles?1:0,this.collideSolidObjects?1:0,this.isSolid?1:0,.5);xt(this.pos,e,s,0,this.angle,t),this.parent&&xt(this.pos,e.scale(.8),z(1,1,1,.5),0,this.angle),this.parent&&Ee(this.pos,this.parent.pos,z(1,1,1,.5),.5)}},I=b(),hn=[];Oe=class n{constructor(t=b(),e=Li,s=hn[0],i=Oi,o=Di){this.pos=t.copy(),this.size=e.copy(),this.padding=i,this.textureInfo=s,this.bleed=o}offset(t){return new n(this.pos.add(t),this.size,this.textureInfo,this.padding,this.bleed)}frame(t){p(typeof t=="number");let e=this.size.x+this.padding*2,s=t*e;return p(s+this.size.x<=this.textureInfo.size.x,"frame extends beyond texture width!"),this.offset(new ct(s))}setFullImage(t=this.textureInfo){return this.textureInfo=t,this.pos=new ct,this.size=t.size.copy(),this.bleed=this.padding=0,this}tile(t){return Is(t,this.size,this.textureInfo,this.padding,this.bleed)}},He=class{constructor(t,e=!0,s=!1){this.image=t,this.size=t?b(t.width,t.height):b(),this.sizeInverse=t?b(1/t.width,1/t.height):b(),this.glTexture=void 0,this.wrap=s,e&&this.createWebGLTexture()}createWebGLTexture(){Hh(this)}destroyWebGLTexture(){Xh(this)}hasWebGL(){return!!this.glTexture}setWrap(t=!0){this.wrap=t,Sc(this.glTexture,t)}};nh=0;ii=class{constructor(t){p(!!t,"tileInfo is required for ImageFont"),this.tileInfo=t.frame(0)}drawText(t,e,s=1,i,o,a,r){p(O(s)||typeof s=="number","size must be a vec2 or number"),typeof s=="number"?(p(s>0),s*=H,s=new ct(s,s)):s=s.scale(H),this.drawTextScreen(t,Dn(e),s,i,o,a,r)}drawTextScreen(t,e,s,i=!0,o=V,a=G,r){p(U(t),"text must be a string"),p(O(e),"pos must be a vec2"),p(O(s)||typeof s=="number","size must be a vec2 or number"),p(J(o),"color must be a color"),s=typeof s=="number"?new ct(s,s):s;let c=new ct,l=this.tileInfo,u=l.padding,h=l.size.x+u*2,d=l.size.y+u*2,f=l.textureInfo.size.x/h|0;(t+"").split(`
+`).forEach((y,x)=>{let v=i?(y.length-1)*s.x/2:0;for(let w=y.length;w--;){let _=y.charCodeAt(w),S=_<32||_>127?95:_-32,C=S%f,A=S/f|0;l.pos.x=C*h+u,l.pos.y=A*d+u,c.x=e.x+w*s.x-v|0,c.y=e.y+x*s.y|0,It(c,s,l,o,0,!1,void 0,a,!0,r)}})}};ke=b(),Vt=b(),Tr=b(),we=b(),Ar=0,oi=!0,zn=!1,en="mouse",Er=6,Nn=!0,bt=0,re=!B&&window.ontouchstart!==void 0;K=[[]],Te=[],mn=[],co=[],qn=new Re,ae=[],_n=[],ri=[],Fs=[],Je=new Map,ms=[],Hn=!0;ai="http://www.w3.org/2000/svg";ft=new AudioContext,ts=44100;xs=class{constructor(t,e,s=xr,i=vr,o){var a;if(!(!Yt||B)){if(p(!t||pe(t)||U(t),"asset must be a file name or zzfx array"),p(e===void 0||R(e),"randomness must be a number"),p(e===void 0||e>=0&&e<=1,"randomness must be between 0 and 1"),p(R(s),"range must be a number"),p(R(i),"taper must be a number"),this.range=s,this.taper=i,this.randomness=e!=null?e:0,this.sampleRate=ts,this.loadedPercent=0,this.onloadCallback=o,pe(t)){let r=t.slice(),c=e!=null?e:.05,l=1;this.randomness=(a=r[l])!=null?a:c,r[l]=0,this.sampleChannels=[Gi(...r)],this.loadedPercent=1,o==null||o(this)}else if(typeof t=="string"){let r=t;this.loadSound(r)}}}play(t,e=1,s=1,i=1,o=!1,a=!1){if(p(!t||O(t),"pos must be a vec2"),p(R(e),"volume must be a number"),p(R(s),"pitch must be a number"),p(R(i),"randomnessScale must be a number"),!Yt||B||!this.sampleChannels)return;let r;if(t){let u=this.range;if(u){let h=Pt.distanceSquared(t);if(h>u*u)return;e*=Bt(h**.5,u,u*this.taper)}r=Dn(t).x*2/F.width-1}let c=s+s*this.randomness*i*dt(-1,1),l=new ci(this,e,c,r,o,a);return Nt&&Vn&&t&&(Wt(t,.5,"#0ff",.5,!0),this.range&&(Wt(t,2*this.range,"#0ff",.5),Wt(t,2*this.range*this.taper,"#0ff",.5)),kn("vol "+e.toFixed(2)+" pitch "+c.toFixed(2),t,.5,"#0ff",.5)),l}playMusic(t=1,e=!0,s=!1){return this.play(void 0,t,1,0,e,s)}playNote(t=0,e,s){p(R(t),"semitoneOffset must be a number");let i=gc(t,1);return this.play(e,s,i,0)}getDuration(){var t,e;return((e=(t=this.sampleChannels)==null?void 0:t[0])==null?void 0:e.length)/this.sampleRate||0}isLoaded(){return this.loadedPercent===1}async loadSound(t){var c;let e=await fetch(t);if(!e.ok)throw new Error(`Failed to load sound from ${t}: ${e.status} ${e.statusText}`);let s=await e.arrayBuffer(),i=await ft.decodeAudioData(s),o=i.numberOfChannels,a=1e5,r=[];for(let l=0;lsetTimeout(v,0));let f=et(d+a,h);for(;d=0,"Sound volume must be positive or zero"),p(s>=0,"Sound rate must be positive or zero"),p(R(i),"Sound pan must be a number"),this.sound=t,this.volume=e,this.rate=s,this.pan=i,this.loop=o,this.pausedTime=0,this.startTime=void 0,this.gainNode=void 0,this.source=void 0,this.onendedCallback=r=>{r===this.source&&(this.source=void 0)},a||this.start()}start(t=0){p(t>=0,"Sound start offset must be positive or zero"),this.isPlaying()&&this.stop(),this.gainNode=ft.createGain(),this.source=Ir(this.sound.sampleChannels,this.volume,this.rate,this.pan,this.loop,this.sound.sampleRate,this.gainNode,t,this.onendedCallback),this.source?(this.startTime=ft.currentTime-t,this.pausedTime=void 0):(this.startTime=void 0,this.pausedTime=0)}setVolume(t){p(t>=0,"Sound volume must be positive or zero"),this.volume=t,this.gainNode&&(this.gainNode.gain.value=t)}stop(t=0){if(p(t>=0,"Sound fade time must be positive or zero"),this.isPlaying())if(t){let e=ft.currentTime,s=e+t;this.gainNode.gain.cancelScheduledValues(e),this.gainNode.gain.setValueAtTime(this.volume,e),this.gainNode.gain.linearRampToValueAtTime(0,s),this.source.stop(s)}else this.source.stop();this.pausedTime=0,this.source=void 0,this.startTime=void 0}pause(){this.isPaused()||(this.pausedTime=this.getCurrentTime(),this.source.stop(),this.source=void 0,this.startTime=void 0)}resume(){this.isPaused()&&this.start(this.pausedTime)}isPlaying(){return!!this.source}isPaused(){return!this.isPlaying()}getCurrentTime(){if(!this.isPlaying())return this.pausedTime;let t=this.getDuration();return t?oe(ft.currentTime-this.startTime,t):0}getDuration(){return this.rate?this.sound.getDuration()/this.rate:0}getSource(){return this.source}};an=[];En=class{constructor(t,e=0,s=!1,i=new Et){this.tile=t,this.direction=e,this.mirror=s,this.color=i.copy()}clear(){this.tile=this.direction=0,this.mirror=!1,this.color=new Et}},ui=class extends qe{constructor(t,e,s=0,i=0,o=b(512),a=!0){var r;p(O(o),"canvasSize must be a Vector2"),super(t,e,void 0,s,V,i),this.canvas=B?void 0:new OffscreenCanvas(o.x,o.y),this.context=(r=this.canvas)==null?void 0:r.getContext("2d"),this.textureInfo=new He(this.canvas,a),this.mass=0}destroy(){this.destroyed||(this.textureInfo.destroyWebGLTexture(),super.destroy())}render(){this.draw(this.pos,this.size,this.color,this.angle,this.mirror,this.additiveColor)}draw(t,e,s=V,i=0,o=!1,a,r=!1,c){let l=new Oe().setFullImage(this.textureInfo),u=this.hasWebGL();It(t,e,l,s,i,o,a,u,r,c)}updateWebGL(){this.textureInfo.createWebGLTexture()}hasWebGL(){return G&&this.textureInfo.hasWebGL()}},vs=class extends ui{constructor(t,e,s=Is(),i=0,o=!0){let a=s?e.multiply(s.size):e;if(super(t,e,0,i,a,o),this.tileInfo=void 0,this.data=[],this.isUsingWebGL=!1,B){this.render=()=>{},this.redraw=()=>{},this.redrawStart=()=>{},this.redrawEnd=()=>{},this.drawTileData=()=>{},this.redrawTileData=()=>{},this.drawLayerTile=()=>{},this.drawLayerRect=()=>{},this.drawTile=()=>{},this.drawRect=()=>{},this.clearLayerRect=()=>{};return}s&&(this.tileInfo=s.frame(0),this.tileInfo.bleed=0);for(let r=this.size.area();r--;)this.data.push(new En)}setData(t,e,s=!1){if(t=t.floor(),p(O(t),"layerPos must be a Vector2"),p(e instanceof En,"data must be a TileLayerData"),!t.arrayCheck(this.size)||(this.data[(t.y|0)*this.size.x+(t.x|0)]=e,!s))return;_t===this.context?this.drawTileData(t):this.redrawTileData(t)}clearData(t,e=!1){this.setData(t,new En,e)}getData(t){return p(O(t),"layerPos must be a Vector2"),t.arrayCheck(this.size)?this.data[(t.y|0)*this.size.x+(t.x|0)]:void 0}update(){!G&&this.isUsingWebGL&&(this.isUsingWebGL=!1,this.redraw())}render(){p(_t!==this.context,"must call redrawEnd() after drawing tiles!");let t=this.drawSize||this.size,e=this.pos.add(t.scale(.5));this.draw(e,this.size,this.color,this.angle,this.mirror,this.additiveColor)}onRedraw(){}redraw(){this.redrawStart(!0);for(let t=this.size.x;t--;)for(let e=this.size.y;e--;)this.drawTileData(b(t,e),!1);this.isUsingWebGL&&Lt(),this.onRedraw(),this.redrawEnd()}redrawStart(t=!1){var s,i;if(!this.context)return;p(_t!==this.context),this.savedRenderSettings=[_t,I,Pt,H,sn],_t=this.context;let e=(i=(s=this.tileInfo)==null?void 0:s.size)!=null?i:b(1);I=this.size.multiply(e),sn=ye,Pt=this.size.multiply(e).scale(.5),H=1,this.isUsingWebGL=this.hasWebGL(),this.isUsingWebGL?os(this.textureInfo.glTexture,t):(this.context.imageSmoothingEnabled=!Cn,t&&(this.canvas.width=I.x,this.canvas.height=I.y))}redrawEnd(){this.context&&(p(_t===this.context),this.isUsingWebGL&&os(),[_t,I,Pt,H,sn]=this.savedRenderSettings)}drawTileData(t,e=!0){var r,c;if(!this.context)return;p(_t===this.context,"must call redrawStart() before drawing tiles");let s=(c=(r=this.tileInfo)==null?void 0:r.size)!=null?c:b(1),i=t.multiply(s);e&&this.clearLayerRect(i,s);let o=this.getData(t);if(!o||!o.tile)return;let a=this.tileInfo&&this.tileInfo.tile(o.tile);this.drawLayerTile(i,s,a,o.color,o.direction*Y/2,o.mirror)}redrawTileData(t,e=!0){this.context&&(p(_t!==this.context,"redrawStart() should not be active when calling redrawTileData(), instead use drawTileData()"),this.redrawStart(),this.drawTileData(t,e),this.redrawEnd())}drawLayerTile(t,e=b(1),s,i=V,o=0,a,r){let c=t.add(e.scale(.5));It(c,e,s,i,o,a,r,this.isUsingWebGL)}drawLayerRect(t,e,s,i=0){this.drawLayerTile(t,e,void 0,s,i)}drawTile(t,e=b(1),s,i=new Et,o=0,a=!1){t=t.subtract(this.pos).multiply(this.tileInfo.size),e=e.multiply(this.tileInfo.size),t.y=this.canvas.height-t.y;let r=I;I=b(this.canvas.width,this.canvas.height);let c=this.hasWebGL();c&&os(this.textureInfo.glTexture);let l=c?void 0:this.context;It(t,e,s,i,o,a,void 0,c,!0,l),c&&os(),I=r}drawRect(t,e,s,i){this.drawTile(t,e,void 0,s,i)}clearLayerRect(t,e){p(_t===this.context,"must call redrawStart() before clearing tiles");let s=t.x,i=this.canvas.height-t.y-e.y;this.hasWebGL()?Ec(s,i,e.x,e.y):this.context.clearRect(s,i,e.x,e.y)}},Ss=class extends vs{constructor(t,e,s=Is(),i=0,o=!0){super(t,e.floor(),s,i,o),this.collisionData=[],this.initCollision(this.size),an.push(this),this.isSolid=!0}destroy(){if(this.destroyed)return;let t=an.indexOf(this);p(t>=0,"tile collision layer not found in array"),t>=0&&an.splice(t,1),super.destroy()}initCollision(t){p(O(t),"size must be a Vector2"),this.size=t.floor(),this.collisionData=[],this.collisionData.length=t.area(),this.collisionData.fill(0)}setCollisionData(t,e=1){p(O(t),"layerPos must be a Vector2");let s=(t.y|0)*this.size.x+(t.x|0);t.arrayCheck(this.size)&&(this.collisionData[s]=e)}clearCollisionData(t){this.setCollisionData(t,0)}getCollisionData(t){p(O(t),"layerPos must be a Vector2");let e=(t.y|0)*this.size.x+(t.x|0);return t.arrayCheck(this.size)?this.collisionData[e]:0}collisionTest(t,e=new ct,s){p(O(t)&&O(e),"pos and size must be Vector2s"),p(!s||typeof s=="function"||s instanceof qe,"callbackObject must be a function or EngineObject");let i=s?typeof s=="function"?(d,f)=>s(d,f):(d,f)=>s.collideWithTile(d,f):()=>!0,o=t.x-this.pos.x,a=t.y-this.pos.y;if(o+e.x/2<0||o-e.x/2>this.size.x||a+e.y/2<0||a-e.y/2>this.size.y)return!1;let r=Q(o-e.x/2|0,0),c=Q(a-e.y/2|0,0),l=et(Q(o+e.x/2,r+1),this.size.x),u=et(Q(a+e.y/2,c+1),this.size.y),h=new ct;for(let d=c;ds(l,u):(l,u)=>s.collideWithTile(l,u):l=>l>0,a=l=>{let u=this.getCollisionData(r.set(l.x-this.pos.x,l.y-this.pos.y));return u&&o(u,l)},r=new ct,c=qa(t,e,a,i);if(fe&&c){let l=c.floor().add(b(.5));xt(l,b(1),"#f008"),Ee(t,e,"#00f",.02),Ee(t,c,"#f00",.02),nr(c,"#0f0"),i&&Ee(c,c.add(i),"#ff0",.02)}return c}},vo=class extends qe{constructor(t,e,s=0,i=0,o=100,a=Y,r,c=V,l=V,u=ln,h=ln,d=.5,f=.1,y=1,x=.1,v=.05,w=1,_=1,S=0,C=Y,A=.1,T=.2,P=!1,k=!1,pt=!0,W=k?1e9:0,$=!1){super(t,b(),r,e,void 0,W),this.emitCircle=typeof s=="number",this.emitSize=typeof s=="number"?b(s):s.copy(),this.emitTime=i,this.emitRate=o,this.emitConeAngle=a,this.colorStartA=c.copy(),this.colorStartB=l.copy(),this.colorEndA=u.copy(),this.colorEndB=h.copy(),this.randomColorLinear=pt,this.particleTime=d,this.sizeStart=f,this.sizeEnd=y,this.speed=x,this.angleSpeed=v,this.damping=w,this.angleDamping=_,this.gravityScale=S,this.particleConeAngle=C,this.fadeRate=A,this.randomness=T,this.collideTiles=P,this.additive=k,this.localSpace=$,this.trailScale=0,this.particleCreateCallback=void 0,this.particleDestroyCallback=void 0,this.particleCollideCallback=void 0,this.velocityInheritance=0,this.emitTimeBuffer=0,this.particles=[],this.previousAngle=this.angle,this.previousPos=this.pos.copy()}update(){if(p(this.angleDamping>=0&&this.angleDamping<=1),p(this.damping>=0&&this.damping<=1),this.velocityInheritance){let s=this.velocityInheritance;this.velocity.x=s*(this.pos.x-this.previousPos.x),this.velocity.y=s*(this.pos.y-this.previousPos.y),this.angleVelocity=s*(this.angle-this.previousAngle),this.previousAngle=this.angle,this.previousPos.x=this.pos.x,this.previousPos.y=this.pos.y}if(this.isActive()){if(this.emitRate&&Zs){let s=1/this.emitRate/Zs;for(this.emitTimeBuffer+=tr;this.emitTimeBuffer>0;this.emitTimeBuffer-=s)this.emitParticle()}}else this.particles.length===0&&this.destroy(!0);let t=this.particles,e=0;for(let s=0;s_+_*dt(s,-s),o=i(this.particleTime),a=i(this.sizeStart),r=i(this.sizeEnd),c=i(this.speed),l=i(this.angleSpeed)*Xa(),u=dt(this.emitConeAngle,-this.emitConeAngle),h=po(this.colorStartA,this.colorStartB,this.randomColorLinear),d=po(this.colorEndA,this.colorEndB,this.randomColorLinear),f=this.localSpace?u:this.angle+u,y=b(c*it(f),c*lt(f)),x=l;!this.localSpace&&this.velocityInheritance>0&&(y.x+=this.velocity.x,y.y+=this.velocity.y,x+=this.angleVelocity);let v=new hi(this,t,e,h,d,o,a,r,y,x);return this.particles.push(v),(w=this.particleCreateCallback)==null||w.call(this,v),v}updatePhysics(){}render(){for(let t of this.particles)t.render()}isActive(){return!this.emitTime||this.getAliveTime()0&&(this.destroyed=!1,this.emitTime=-1))}},Vh=new ct,hi=class{constructor(t,e,s,i,o,a,r,c,l=b(),u=0){this.emitter=t,this.pos=e,this.angle=s,this.size=b(r),this.color=i.copy(),this.colorStart=i,this.colorEnd=o,this.lifeTime=a,this.sizeStart=r,this.sizeEnd=c,this.velocity=l,this.angleVelocity=u,this.spawnTime=Zt,this.mirror=Ha(),this.groundObject=void 0,this.destroyed=!1,this.tileInfo=t.tileInfo}update(){let t=this.emitter,e=t.damping,s=t.angleDamping,i=t.restitution,o=t.friction,a=t.gravityScale,r=t.collideTiles,c=t.particleCollideCallback;if(this.lifeTime>0&&Zt-this.spawnTime>this.lifeTime){this.destroy();return}let l=this.pos.copy();if(this.velocity.x*=e,this.velocity.y*=e,this.pos.x+=this.velocity.x+=qt.x*a,this.pos.y+=this.velocity.y+=qt.y*a,this.angle+=this.angleVelocity*=s,!Ii||!r)return;let u=this.velocity.lengthSquared();if(u>Be*Be){let d=Be/u**.5;this.velocity.x*=d,this.velocity.y*=d}this.groundObject=void 0;let h=c?d=>{let f=li(d);return f&&c(this,f,d)}:d=>li(d)>0;if(h(this.pos)){let d=Ze(this.pos);if(!h(l)){let f=h(b(this.pos.x,l.y)),y=h(b(l.x,this.pos.y)),x=Q(i,d.restitution),v=Q(o,d.friction);f&&(this.pos.x=l.x,this.velocity.x*=-x,this.velocity.y*=v),(y||!f)&&((this.velocity.y<0&&qt.y<0||this.velocity.y>0&&qt.y>0)&&(this.groundObject=d),this.pos.y=l.y,this.velocity.y*=-x,this.velocity.x*=v),de&&xt(this.pos,this.size,"#f00")}}}destroy(){let t=this.emitter.particleDestroyCallback,e=this.colorEnd;this.color.set(e.r,e.g,e.b,e.a),this.size.set(this.sizeEnd,this.sizeEnd),this.destroyed=!0,t==null||t(this)}render(){let t=this.emitter,e=t.localSpace,s=t.additive,i=t.trailScale,o=t.fadeRate/2,a=this.lifeTime>0?et((Zt-this.spawnTime)/this.lifeTime,1):1,r=1-a,c=r*this.sizeStart+a*this.sizeEnd,l=b(c),u=a1-o?(1-a)/o:1;this.color.r=r*this.colorStart.r+a*this.colorEnd.r,this.color.g=r*this.colorStart.g+a*this.colorEnd.g,this.color.b=r*this.colorStart.b+a*this.colorEnd.b,this.color.a=(r*this.colorStart.a+a*this.colorEnd.a)*u;let h=Vh.set(this.pos.x,this.pos.y),d=this.angle;if(e){let f=t.angle,y=lt(-f),x=it(-f);h.set(t.pos.x+h.x*y-h.y*x,t.pos.y+h.x*x+h.y*y),d+=f}if(s&&ps(),i){let f=e?this.velocity.rotate(t.angle):this.velocity,y=f.length();if(y){let x=y*i;l.y=Q(l.x,x),d=sr(f.x,f.y),It(h,l,this.tileInfo,this.color,d,this.mirror)}}else It(h,l,this.tileInfo,this.color,d,this.mirror);s&&ps(!1),wn&&xt(h,l,"#f005",0,d)}},Mr=!0,Ao=!0,gi=5e5,Gr=11,mc=Gr*4,Wh=gi/mc|0,Fi=3,bc=Fi*4,Un=gi/bc|0;yn=!1,yi=5,Bn=.5,mi=b(640,80),Ur=!1,Es={},qs=[];xi=class{constructor(t,e,s="",i="\u{1F3C6}",o){p(t>=0&&!Es[t]),this.id=t,this.name=e,this.description=s,this.icon=i,this.unlocked=!1,this.image=void 0,o&&((this.image=new Image).src=o),Es[t]=this}unlock(){Ur||this.unlocked||(p(bi,"save name must be set"),this.unlocked=!0,Vr(),qs.push(this))}render(t=0){let e=ut,s=et(mi.x,F.width),i=mi.y,o=F.width-s,a=-i*t,r=Ne(0,0,.9);e.save(),e.beginPath(),e.fillStyle=r.toString(),e.strokeStyle=ot.toString(),e.lineWidth=3,e.rect(o,a,s,i),e.fill(),e.stroke(),e.clip();let c=b(.1,.05).scale(i),l=i-2*c.x;this.renderIcon(b(o+c.x+l/2,a+i/2),l);let u=i*.5,h=i*.3,d=b(o+l+2*c.x,a+c.y*2+u/2),f=s-l-3*c.x;rn(this.name,d,u,ot,0,void 0,"left",void 0,void 0,f),d.y=a+i-c.y*2-h/2,rn(this.description,d,h,ot,0,void 0,"left",void 0,void 0,f),e.restore()}renderIcon(t,e){this.image?ut.drawImage(this.image,t.x-e/2,t.y-e/2,e,e):rn(this.icon,t,e*.7,ot)}};_o=class extends xi{constructor(t,e,s,i,o){super(t,e,s,i,o)}unlock(){super.unlock(),Cs&&Cs.unlockMedal(this.id)}},Ro=class{constructor(t,e,s){var c,l,u;p(!Cs,"there can only be one newgrounds object"),p(!e||s,"must provide cryptojs if there is a cipher"),Cs=this,this.app_id=t,this.cipher=e,this.cryptoJS=s,this.host=location?location.hostname:"";let i=new URL(location.href);if(this.session_id=i.searchParams.get("ngio_session_id"),!this.session_id)return;let o=this.call("Medal.getList");if(!o||!o.result||o.result.error){yn&&St("Newgrounds session unavailable; skipping plugin init"),this.medals=[],this.scoreboards=[];return}this.medals=((c=o.result.data)==null?void 0:c.medals)||[],yn&&St(this.medals);for(let h of this.medals){let d=Es[h.id];d&&(d.image=new Image,d.image.src=h.icon,d.name=h.name,d.description=h.description,d.unlocked=h.unlocked,d.difficulty=h.difficulty,d.value=h.value,d.value&&(d.description=d.description+` (${d.value})`))}let a=this.call("ScoreBoard.getBoards");this.scoreboards=((u=(l=a==null?void 0:a.result)==null?void 0:l.data)==null?void 0:u.scoreboards)||[],yn&&St(this.scoreboards);let r=60*1e3;setInterval(()=>this.call("Gateway.ping",0,!0),r)}unlockMedal(t){return this.call("Medal.unlock",{id:t},!0)}postScore(t,e){return this.call("ScoreBoard.postScore",{id:t,value:e},!0)}getScores(t,e,s=0,i=0,o=10){return this.call("ScoreBoard.getScores",{id:t,user:e,social:s,skip:i,limit:o})}logView(){return this.call("App.logView",{host:this.host},!0)}call(t,e,s=!1){let i={component:t,parameters:e};if(this.cipher){let l=this.cryptoJS,u=l.enc.Base64.parse(this.cipher),h=l.lib.WordArray.random(16),d=l.AES.encrypt(JSON.stringify(i),u,{iv:h});i.secure=l.enc.Base64.stringify(h.concat(d.ciphertext)),i.parameters=0}let o={app_id:this.app_id,session_id:this.session_id,call:i},a=new FormData;a.append("input",JSON.stringify(o));let r=new XMLHttpRequest;r.open("POST","https://newgrounds.io/gateway_v3.php",!yn&&s);try{r.send(a)}catch(l){yn&&St("newgrounds call failed",l);return}return yn&&St(r.responseText),r.responseText&&JSON.parse(r.responseText)}},Po=class{constructor(t,e=!1,s=!1){p(!Gt,"Post process already initialized"),p(!(e&&s),"Post process cannot both include main canvas and use feedback texture"),Gt=this,t||(t="void mainImage(out vec4 c,vec2 p){c=texture(iChannel0,p/iResolution.xy);}"),this.shader=void 0,this.texture=void 0,this.vao=void 0,i(),Pn(void 0,r,o,a);function i(){if(B)return;if(!G){console.warn("PostProcessPlugin: WebGL not enabled!");return}Gt.texture=ji(),Gt.shader=$n(`#version 300 es
 precision highp float;in vec2 p;void main(){gl_Position=vec4(p+p-1.,1,1);}`,`#version 300 es
 precision highp float;uniform sampler2D iChannel0;uniform vec3 iResolution;uniform float iTime;out vec4 c;
 `+t+`
-void main(){mainImage(c,gl_FragCoord.xy);c.a=1.;}`),kt.vao=g.createVertexArray(),g.bindVertexArray(kt.vao),g.bindBuffer(g.ARRAY_BUFFER,Nn);let c=8,l=g.getAttribLocation(kt.shader,"p");g.enableVertexAttribArray(l),g.vertexAttribPointer(l,2,g.FLOAT,!1,c,0)}function o(){kt.shader=void 0,kt.texture=void 0,xt("PostProcessPlugin: WebGL context lost")}function a(){i(),xt("PostProcessPlugin: WebGL context restored")}function r(){if(z||!G)return;Rt(),g.bindFramebuffer(g.FRAMEBUFFER,null),g.useProgram(kt.shader),g.bindVertexArray(kt.vao),g.pixelStorei(g.UNPACK_FLIP_Y_WEBGL,!0),g.disable(g.BLEND),g.activeTexture(g.TEXTURE0),g.bindTexture(g.TEXTURE_2D,kt.texture),e?(Ne.width=I.x,Ne.height=I.y,Br(Ke),Ke.drawImage(B,0,0),B.width|=0,g.texImage2D(g.TEXTURE_2D,0,g.RGBA,g.RGBA,g.UNSIGNED_BYTE,Ne)):s||g.texImage2D(g.TEXTURE_2D,0,g.RGBA,g.RGBA,g.UNSIGNED_BYTE,et);let c=l=>g.getUniformLocation(kt.shader,l);g.uniform1i(c("iChannel0"),0),g.uniform1f(c("iTime"),Kt),g.uniform3f(c("iResolution"),B.width,B.height,1),g.drawArrays(g.TRIANGLE_STRIP,0,4),s&&g.texImage2D(g.TEXTURE_2D,0,g.RGBA,g.RGBA,g.UNSIGNED_BYTE,et),g.pixelStorei(g.UNPACK_FLIP_Y_WEBGL,!1),ws(!0)}}},Lo=class{constructor(t,e){f(!q,"LightSystemPlugin already initialized"),f(!kt,"LightSystemPlugin must be created before PostProcessPlugin"),q=this,this.enabled=!0,this.ambientColor=(e||it).copy(),this.textureSize=t?t.copy():void 0,this.texture=void 0,this.lightShader=void 0,this.compositeShader=void 0,this.lightVAO=void 0,this.compositeVAO=void 0,s(),Cn(void 0,i,o,a);function s(){if(z)return;if(!G){console.warn("LightSystemPlugin: WebGL not enabled!");return}q.textureSize||(q.textureSize=I.copy()),q.texture=g.createTexture(),g.bindTexture(g.TEXTURE_2D,q.texture),g.texImage2D(g.TEXTURE_2D,0,g.RGBA,q.textureSize.x,q.textureSize.y,0,g.RGBA,g.UNSIGNED_BYTE,null),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_MAG_FILTER,g.LINEAR),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_MIN_FILTER,g.LINEAR),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_S,g.CLAMP_TO_EDGE),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_T,g.CLAMP_TO_EDGE),q.lightShader=Xn(`#version 300 es
+void main(){mainImage(c,gl_FragCoord.xy);c.a=1.;}`),Gt.vao=g.createVertexArray(),g.bindVertexArray(Gt.vao),g.bindBuffer(g.ARRAY_BUFFER,Jn);let c=8,l=g.getAttribLocation(Gt.shader,"p");g.enableVertexAttribArray(l),g.vertexAttribPointer(l,2,g.FLOAT,!1,c,0)}function o(){Gt.shader=void 0,Gt.texture=void 0,St("PostProcessPlugin: WebGL context lost")}function a(){i(),St("PostProcessPlugin: WebGL context restored")}function r(){if(B||!G)return;Lt(),g.bindFramebuffer(g.FRAMEBUFFER,null),g.useProgram(Gt.shader),g.bindVertexArray(Gt.vao),g.pixelStorei(g.UNPACK_FLIP_Y_WEBGL,!0),g.disable(g.BLEND),g.activeTexture(g.TEXTURE0),g.bindTexture(g.TEXTURE_2D,Gt.texture),e?(Ue.width=I.x,Ue.height=I.y,Nr(tn),tn.drawImage(F,0,0),F.width|=0,g.texImage2D(g.TEXTURE_2D,0,g.RGBA,g.RGBA,g.UNSIGNED_BYTE,Ue)):s||g.texImage2D(g.TEXTURE_2D,0,g.RGBA,g.RGBA,g.UNSIGNED_BYTE,nt);let c=l=>g.getUniformLocation(Gt.shader,l);g.uniform1i(c("iChannel0"),0),g.uniform1f(c("iTime"),Zt),g.uniform3f(c("iResolution"),F.width,F.height,1),g.drawArrays(g.TRIANGLE_STRIP,0,4),s&&g.texImage2D(g.TEXTURE_2D,0,g.RGBA,g.RGBA,g.UNSIGNED_BYTE,nt),g.pixelStorei(g.UNPACK_FLIP_Y_WEBGL,!1),Ts(!0)}}},Lo=class{constructor(t,e){p(!q,"LightSystemPlugin already initialized"),p(!Gt,"LightSystemPlugin must be created before PostProcessPlugin"),q=this,this.enabled=!0,this.ambientColor=(e||ot).copy(),this.textureSize=t?t.copy():void 0,this.texture=void 0,this.lightShader=void 0,this.compositeShader=void 0,this.lightVAO=void 0,this.compositeVAO=void 0,s(),Pn(void 0,i,o,a);function s(){if(B)return;if(!G){console.warn("LightSystemPlugin: WebGL not enabled!");return}q.textureSize||(q.textureSize=I.copy()),q.texture=g.createTexture(),g.bindTexture(g.TEXTURE_2D,q.texture),g.texImage2D(g.TEXTURE_2D,0,g.RGBA,q.textureSize.x,q.textureSize.y,0,g.RGBA,g.UNSIGNED_BYTE,null),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_MAG_FILTER,g.LINEAR),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_MIN_FILTER,g.LINEAR),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_S,g.CLAMP_TO_EDGE),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_T,g.CLAMP_TO_EDGE),q.lightShader=$n(`#version 300 es
 precision highp float;uniform mat4 m;uniform vec2 lightPos;uniform float radius;in vec2 g;out vec2 vWorldPos;void main(){vec2 worldP=lightPos+(g-.5)*2.*radius;gl_Position=m*vec4(worldP,1,1);vWorldPos=worldP;}`,`#version 300 es
-precision highp float;uniform vec2 lightPos;uniform float radius;uniform float fadeRange;uniform vec4 color;in vec2 vWorldPos;out vec4 c;void main(){float dist=distance(vWorldPos,lightPos);float t=clamp((radius-dist)/max(fadeRange,1e-6),0.,1.);c=vec4(color.rgb*t*color.a,1.);}`),q.compositeShader=Xn(`#version 300 es
+precision highp float;uniform vec2 lightPos;uniform float radius;uniform float fadeRange;uniform vec4 color;in vec2 vWorldPos;out vec4 c;void main(){float dist=distance(vWorldPos,lightPos);float t=clamp((radius-dist)/max(fadeRange,1e-6),0.,1.);c=vec4(color.rgb*t*color.a,1.);}`),q.compositeShader=$n(`#version 300 es
 precision highp float;in vec2 p;void main(){gl_Position=vec4(p+p-1.,1,1);}`,`#version 300 es
-precision highp float;uniform sampler2D s;uniform vec3 iResolution;out vec4 c;void main(){vec2 uv=gl_FragCoord.xy/iResolution.xy;c=vec4(texture(s,uv).rgb,1.);}`),q.lightVAO=g.createVertexArray(),g.bindVertexArray(q.lightVAO),g.bindBuffer(g.ARRAY_BUFFER,Nn);let r=g.getAttribLocation(q.lightShader,"g");g.enableVertexAttribArray(r),g.vertexAttribPointer(r,2,g.FLOAT,!1,8,0),q.compositeVAO=g.createVertexArray(),g.bindVertexArray(q.compositeVAO),g.bindBuffer(g.ARRAY_BUFFER,Nn);let c=g.getAttribLocation(q.compositeShader,"p");g.enableVertexAttribArray(c),g.vertexAttribPointer(c,2,g.FLOAT,!1,8,0)}function i(){if(z||!G||!q.enabled||!q.texture)return;Rt();let r=On,c=q.ambientColor;g.bindFramebuffer(g.FRAMEBUFFER,kr),g.framebufferTexture2D(g.FRAMEBUFFER,g.COLOR_ATTACHMENT0,g.TEXTURE_2D,q.texture,0),g.viewport(0,0,q.textureSize.x,q.textureSize.y),g.clearColor(c.r,c.g,c.b,c.a),g.clear(g.COLOR_BUFFER_BIT),fs(),g.enable(g.BLEND),g.blendFunc(g.ONE,g.ONE);for(let u of vt)u.destroyed||u.renderLight();Rt(),g.bindFramebuffer(g.FRAMEBUFFER,null),g.viewport(0,0,I.x,I.y),g.useProgram(q.compositeShader),g.bindVertexArray(q.compositeVAO),g.activeTexture(g.TEXTURE0),g.bindTexture(g.TEXTURE_2D,q.texture);let l=q.compositeShader;g.uniform1i(g.getUniformLocation(l,"s"),0),g.uniform3f(g.getUniformLocation(l,"iResolution"),B.width,B.height,1),g.blendFunc(g.DST_COLOR,g.ZERO),g.drawArrays(g.TRIANGLE_STRIP,0,4),Qt&&g.bindTexture(g.TEXTURE_2D,Qt),fs(r),ws(!0)}function o(){q.texture=void 0,q.lightShader=void 0,q.compositeShader=void 0,q.lightVAO=void 0,q.compositeVAO=void 0,xt("LightSystemPlugin: WebGL context lost")}function a(){s(),xt("LightSystemPlugin: WebGL context restored")}}drawLight(t){if(z||!G||!this.lightShader)return;Rt(),g.useProgram(this.lightShader),g.bindVertexArray(this.lightVAO);let e=b(2*H).divide(I),s=_t.rotate(-Q),i=b(-1).subtract(s.multiply(e)),o=lt(Q),a=st(Q),r=[e.x*o,e.y*a,0,0,-e.x*a,e.y*o,0,0,1,1,1,0,i.x,i.y,0,1],c=this.lightShader;g.uniformMatrix4fv(g.getUniformLocation(c,"m"),!1,r),g.uniform2f(g.getUniformLocation(c,"lightPos"),t.pos.x,t.pos.y),g.uniform1f(g.getUniformLocation(c,"radius"),t.radius),g.uniform1f(g.getUniformLocation(c,"fadeRange"),t.fadeRange);let l=t.color;g.uniform4f(g.getUniformLocation(c,"color"),l.r,l.g,l.b,l.a),g.drawArrays(g.TRIANGLE_STRIP,0,4),ws(!0)}},Oo=class extends Ue{constructor(t,e,s,i){super(t,b(1),void 0,0,s),f(L(e)&&e>=0,"Light radius must be a non-negative number"),f(i===void 0||L(i)&&i>=0,"Light fadeRange must be a non-negative number when provided"),this.radius=e,this.fadeRange=i===void 0?e:i}render(){}renderLight(){q&&q.drawLight(this)}},Do=class extends bs{constructor(t){super(void 0),!(!Ht||z)&&(this.randomness=0,this.sampleChannels=Cc(...t),this.sampleRate=Qn)}playMusic(t=1,e=!0){return super.play(void 0,t,1,0,e)}};Wr=0;Io=class{constructor(t=ut){f(!E,"UI system already initialized"),E=this,this.activateOnPress=!1,this.defaultColor=W,this.defaultLineColor=it,this.defaultTextColor=it,this.defaultButtonColor=Ge(0,0,.7),this.defaultHoverColor=Ge(0,0,.9),this.defaultDisabledColor=Ge(0,0,.3),this.defaultGradientColor=void 0,this.defaultLineWidth=4,this.defaultCornerRadius=0,this.defaultTextFitScale=.8,this.defaultFont=Rs,this.defaultSoundPress=void 0,this.defaultSoundRelease=void 0,this.defaultSoundClick=void 0,this.defaultShadowColor=pe,this.defaultShadowBlur=5,this.defaultShadowOffset=b(5),this.nativeHeight=0,this.navigationObject=void 0,this.navigationTimer=new Ee(void 0,!0),this.navigationDelay=.2,this.navigationDirection=1,this.navigationMode=!1,this.uiObjects=[],this.uiContext=t,this.activeObject=void 0,this.hoverObject=void 0,this.lastHoverObject=void 0,this.confirmDialog=void 0,this._keyInputObject=void 0,this._onKeyDown=o=>{var a;return(a=this._keyInputObject)==null?void 0:a.onKeyDown(o)},Cn(s,i);function e(o){let a,r;o.parent?(a=o.parent.nativePos,r=o.parent.size):(a=E.screenToNative(I.scale(.5)),r=E.nativeHeight?b(I.x*E.nativeHeight/I.y,E.nativeHeight):I);let c=o.anchor;o.nativePos=a.add(r.multiply(c).scale(.5)).subtract(o.size.multiply(c).scale(.5)).add(o.localPos)}function s(){E.activeObject&&!E.activeObject.visible&&(E.activeObject=void 0),E.lastHoverObject=E.hoverObject,E.hoverObject=void 0,ps(0)&&(E.navigationMode=!1,E.navigationObject=void 0),E.keyInputObject&&(E.activeObject=E.keyInputObject,E.hoverObject=E.keyInputObject,E.navigationMode=!1,E.navigationObject=void 0);let o=E.getNavigableObjects();if(!o.length)E.navigationObject=void 0;else if(!E.keyInputObject){if(o.includes(E.navigationObject)||(E.navigationObject=void 0),ie||E.navigationMode&&!E.navigationObject&&(E.navigationObject=o.find(r=>r.navigationAutoSelect)),!E.navigationTimer.active()){let r=ne(E.getNavigationDirection());if(r){let c;if(E.navigationObject){let l=o.indexOf(E.navigationObject),u=se(l+r,o.length);c=o[u]}else if(c=o.find(l=>l.navigationAutoSelect),!c){let l=r>0?0:o.length-1;c=o[l]}E.navigationObject!==c&&(E.navigationMode=!0,E.hoverObject=void 0,E.navigationObject=c,E.navigationTimer.set(E.navigationDelay),c.soundPress&&c.soundPress.play())}}E.navigationObject&&E.getNavigationWasPressed()&&E.navigationObject.navigatePressed()}for(let r=E.uiObjects.length;r--;){let c=E.uiObjects[r];c.parent||a(c)}E.uiObjects=E.uiObjects.filter(r=>!r.destroyed);function a(r){if(!(r.destroyed||!r.visible)){e(r);for(let c=r.children.length;c--;){let l=r.children[c];l&&a(l)}r.destroyed||r.update()}}}function i(){let o=E.uiContext;if(o.save(),E.nativeHeight){let r=I.y/E.nativeHeight;o.translate(-r*I.x/2,0),o.scale(r,r),o.translate(I.x/2/r,0)}function a(r){if(r.visible){e(r),r.render();for(let c of r.children)a(c)}}if(E.uiObjects.forEach(r=>r.parent||a(r)),Wr>0){let r=function(c,l=!0){l&&(l=!!c.visible),e(c),c.renderDebug(l);for(let u of c.children)r(u,l)};E.uiObjects.forEach(c=>c.parent||r(c))}o.restore()}}drawRect(t,e,s=W,i=0,o=it,a=0,r,c=it,l=0,u=b()){f(O(t),"pos must be a vec2"),f(O(e),"size must be a vec2"),f(U(s),"color must be a color"),f(L(i),"lineWidth must be a number"),f(U(o),"lineColor must be a color"),f(L(a),"cornerRadius must be a number");let h=E.uiContext;if(r){let p=h.createLinearGradient(t.x,t.y-e.y/2,t.x,t.y+e.y/2),d=s.toString();p.addColorStop(0,d),p.addColorStop(.5,r.toString()),p.addColorStop(1,d),h.fillStyle=p}else h.fillStyle=s.toString();(l||u.x||u.y)&&c.a>0&&(h.shadowColor=c.toString(),h.shadowBlur=l,h.shadowOffsetX=u.x,h.shadowOffsetY=u.y),h.beginPath(),a&&h.roundRect?h.roundRect(t.x-e.x/2,t.y-e.y/2,e.x,e.y,a):h.rect(t.x-e.x/2,t.y-e.y/2,e.x,e.y),h.fill(),h.shadowColor="#0000",i&&o.a>0&&(h.strokeStyle=o.toString(),h.lineWidth=i,h.stroke())}drawLine(t,e,s=E.defaultLineWidth,i=E.defaultLineColor){f(O(t),"posA must be a vec2"),f(O(e),"posB must be a vec2"),f(L(s),"lineWidth must be a number"),f(U(i),"lineColor must be a color");let o=E.uiContext;o.strokeStyle=i.toString(),o.lineWidth=s,o.beginPath(),o.lineTo(t.x,t.y),o.lineTo(e.x,e.y),o.stroke()}drawTile(t,e,s,i=E.defaultColor,o=0,a=!1,r=it,c=0,l=b()){let u=E.uiContext;(c||l.x||l.y)&&r.a>0&&(u.shadowColor=r.toString(),u.shadowBlur=c,u.shadowOffsetX=l.x,u.shadowOffsetY=l.y),Mt(t,e,s,i,o,a,pe,!1,!0,u),u.shadowColor="#0000"}drawText(t,e,s,i=E.defaultColor,o=E.defaultLineWidth,a=E.defaultLineColor,r="center",c=E.defaultFont,l="",u=!0,h=void 0,p=it,d=0,y=b()){let x=E.uiContext;p.a>0&&(h&&nn(t,e.add(h),s.y,p,o,a,r,c,l,u?s.x:void 0,0,x),(d||y.x||y.y)&&(x.shadowColor=p.toString(),x.shadowBlur=d,x.shadowOffsetX=y.x,x.shadowOffsetY=y.y)),nn(t,e,s.y,i,o,a,r,c,l,u?s.x:void 0,0,x),x.shadowColor="#0000"}setupDragAndDrop(t,e,s,i){if(this._dragListeners)for(let[a,r]of this._dragListeners)document.removeEventListener(a,r);this._dragListeners=[];let o=(a,r)=>{let c=l=>{l.preventDefault(),a&&a(l)};document.addEventListener(r,c),this._dragListeners.push([r,c])};o(t,"drop"),o(e,"dragenter"),o(s,"dragleave"),o(i,"dragover")}screenToNative(t){if(!E.nativeHeight)return t;let e=I.y/E.nativeHeight,s=1/e,i=t.copy();return i.x+=e*I.x/2,i.x*=s,i.y*=s,i.x-=s*I.x/2,i}get keyInputObject(){return this._keyInputObject}set keyInputObject(t){let e=!!this._keyInputObject;this._keyInputObject=t,!e&&t?document.addEventListener("keydown",this._onKeyDown):e&&!t&&document.removeEventListener("keydown",this._onKeyDown)}destroyObjects(){for(let t of this.uiObjects)t.parent||t.destroy();this.uiObjects=this.uiObjects.filter(t=>!t.destroyed),this.activeObject=void 0,this.hoverObject=void 0,this.lastHoverObject=void 0,this.keyInputObject=void 0}getNavigableObjects(){function t(s){if(!(!s.visible||s.disabled)){s.isInteractive()&&s.navigationIndex!==void 0&&e.push(s);for(let i=s.children.length;i--;)t(s.children[i])}}let e=[];for(let s=E.uiObjects.length;s--;){let i=E.uiObjects[s];E.confirmDialog&&i!==E.confirmDialog||i.parent||t(i)}return e.sort((s,i)=>s.navigationIndex-i.navigationIndex),e}getNavigationDirection(){let t=E.navigationDirection===1,e=E.navigationDirection===2;if(Bn){let l=gs(0,mt),u=bo(mt);return e?-(l.y||u.y)||l.x||u.x:t?-(l.y||u.y):l.x||u.x}let s="ArrowUp",i="ArrowDown",o="ArrowLeft",a="ArrowRight";if(e)return It(s)||It(o)?-1:It(i)||It(a)?1:0;let r=t?s:o,c=t?i:a;return It(r)?-1:It(c)?1:0}getNavigationOtherDirection(){if(E.navigationDirection===2)return 0;let t=E.navigationDirection===1;if(Bn){let i=gs(0,mt),o=bo(mt);return t?i.x||o.x:i.y||o.y}let e=t?"ArrowLeft":"ArrowUp",s=t?"ArrowRight":"ArrowDown";return It(e)?-1:It(s)?1:0}getNavigationWasPressed(){return Bn?Rr(0,mt):Gt("Space")||Gt("Enter")}showConfirmDialog(t="Are you sure?",e,s,i=b(500,250),o="Escape"){f(!E.confirmDialog);let a=E.navigationDirection;E.navigationDirection=2;let r=new re(b(),i);E.confirmDialog=r,r.onRender=()=>{let d=Ge(0,0,0,.7);E.drawRect(b(),b(1e9),d)},r.onUpdate=()=>{Gt(o)&&p()},r.isMouseOverlapping=()=>!0;let c=50,l=new vi(b(0,-50),b(i.x-c,70),t);r.addChild(l);let u=new Cs(b(-80,50),b(120,70),"Yes");u.textHeight=40,u.navigationIndex=1,u.hoverColor=Ge(0,1,.5),u.onClick=()=>{p(),e&&e()},r.addChild(u);let h=new Cs(b(80,50),b(120,70),"No");h.textHeight=40,h.navigationIndex=2,h.navigationAutoSelect=!0,h.onClick=()=>{p(),s&&s()},r.addChild(h);function p(){f(E.confirmDialog===r),r.destroy(),E.confirmDialog=void 0,E.navigationDirection=a,ks()}}},re=class{constructor(t=b(),e=b()){var s,i;f(O(t),"ui object pos must be a vec2"),f(O(e),"ui object size must be a vec2"),this.localPos=t.copy(),this.nativePos=t.copy(),this.size=e.copy(),this.color=E.defaultColor.copy(),this.activeColor=void 0,this.text=void 0,this.disabledColor=E.defaultDisabledColor.copy(),this.disabled=!1,this.textColor=E.defaultTextColor.copy(),this.hoverColor=E.defaultHoverColor.copy(),this.lineColor=E.defaultLineColor.copy(),this.gradientColor=E.defaultGradientColor?E.defaultGradientColor.copy():void 0,this.lineWidth=E.defaultLineWidth,this.cornerRadius=E.defaultCornerRadius,this.font=E.defaultFont,this.fontStyle=void 0,this.textWidth=void 0,this.textHeight=void 0,this.textFitScale=E.defaultTextFitScale,this.textShadow=void 0,this.textLineColor=E.defaultLineColor.copy(),this.textLineWidth=0,this.visible=!0,this.children=[],this.parent=void 0,this.extraTouchSize=0,this.soundPress=E.defaultSoundPress,this.soundRelease=E.defaultSoundRelease,this.soundClick=E.defaultSoundClick,this.interactive=!1,this.dragActivate=!1,this.canBeHover=!0,this.shadowColor=(s=E.defaultShadowColor)==null?void 0:s.copy(),this.shadowBlur=E.defaultShadowBlur,this.shadowOffset=(i=E.defaultShadowOffset)==null?void 0:i.copy(),this.navigationIndex=void 0,this.navigationAutoSelect=!1,this.anchor=b(),E.uiObjects.push(this)}addChild(t){return f(!t.parent&&!this.children.includes(t)),this.children.push(t),t.parent=this,t}removeChild(t){f(t.parent===this&&this.children.includes(t)),this.children.splice(this.children.indexOf(t),1),t.parent=void 0}destroy(){var t;if(!this.destroyed){E.activeObject===this&&(E.activeObject=void 0),E.hoverObject===this&&(E.hoverObject=void 0),E.lastHoverObject===this&&(E.lastHoverObject=void 0),E.navigationObject===this&&(E.navigationObject=void 0),E.keyInputObject===this&&(E.keyInputObject=void 0),this.destroyed=1,(t=this.parent)==null||t.removeChild(this);for(let e of this.children)e.parent=void 0,e.destroy();this.children.length=0}}isMouseOverlapping(){if(!oi)return!1;let t=ie?this.size.add(b(this.extraTouchSize||0)):this.size,e=E.screenToNative(Jt);return Qs(this.nativePos,t,e)}update(){if(this.onUpdate(),this.disabled&&(this===E.activeObject&&(E.activeObject=void 0),this===E.keyInputObject&&(E.keyInputObject=void 0)),E.keyInputObject)return;let t=E.lastHoverObject===this,e=this.isActiveObject(),s=cs(0),i=this.dragActivate?s:ps(0);this.canBeHover&&(E.navigationMode||(i||e||!s&&!ie)&&!E.hoverObject&&this.isMouseOverlapping()&&(E.hoverObject=this)),this.isHoverObject()&&(this.disabled||(i&&this.interactive&&((!this.dragActivate||!t||ps(0))&&this.onPress(),this.soundPress&&this.soundPress.play(),E.activeObject&&!e&&E.activeObject.onRelease(),E.activeObject=this,E.activateOnPress&&this.click(!this.soundPress)),E.activateOnPress||!s&&this.isActiveObject()&&this.interactive&&this.click()),i&&Cr(0,0,0,1,0)),e&&(!s||this.dragActivate&&!this.isHoverObject())&&(this.onRelease(),this.soundRelease&&this.soundRelease.play(),E.activeObject=void 0),this.isHoverObject()!==t&&(this.isHoverObject()?this.onEnter():this.onLeave())}render(){if(this.onRender(),!this.size.x||!this.size.y)return;let t=this.isNavigationObject(),e=t?this.color:this.interactive&&this.isActiveObject()&&!this.disabled?this.color:this.lineColor,s=t?this.hoverColor:this.disabled?this.disabledColor:this.interactive?this.isActiveObject()?this.activeColor||this.hoverColor:this.isHoverObject()?this.hoverColor:this.color:this.color,i=this.lineWidth*(t?1.5:1);E.drawRect(this.nativePos,this.size,s,i,e,this.cornerRadius,this.gradientColor,this.shadowColor,this.shadowBlur,this.shadowOffset)}getTextSize(){return b(this.textWidth||this.textFitScale*this.size.x,this.textHeight||this.textFitScale*this.size.y)}navigatePressed(){this.click()}isHoverObject(){return E.hoverObject===this}isActiveObject(){return E.activeObject===this}isNavigationObject(){return E.navigationObject===this}isKeyInputObject(){return E.keyInputObject===this}isInteractive(){return this.interactive&&this.visible&&!this.disabled}toString(){let t="type = "+this.constructor.name;return this.text&&(t+=`
+precision highp float;uniform sampler2D s;uniform vec3 iResolution;out vec4 c;void main(){vec2 uv=gl_FragCoord.xy/iResolution.xy;c=vec4(texture(s,uv).rgb,1.);}`),q.lightVAO=g.createVertexArray(),g.bindVertexArray(q.lightVAO),g.bindBuffer(g.ARRAY_BUFFER,Jn);let r=g.getAttribLocation(q.lightShader,"g");g.enableVertexAttribArray(r),g.vertexAttribPointer(r,2,g.FLOAT,!1,8,0),q.compositeVAO=g.createVertexArray(),g.bindVertexArray(q.compositeVAO),g.bindBuffer(g.ARRAY_BUFFER,Jn);let c=g.getAttribLocation(q.compositeShader,"p");g.enableVertexAttribArray(c),g.vertexAttribPointer(c,2,g.FLOAT,!1,8,0)}function i(){if(B||!G||!q.enabled||!q.texture)return;Lt();let r=Mn,c=q.ambientColor;g.bindFramebuffer(g.FRAMEBUFFER,kr),g.framebufferTexture2D(g.FRAMEBUFFER,g.COLOR_ATTACHMENT0,g.TEXTURE_2D,q.texture,0),g.viewport(0,0,q.textureSize.x,q.textureSize.y),g.clearColor(c.r,c.g,c.b,c.a),g.clear(g.COLOR_BUFFER_BIT),ps(),g.enable(g.BLEND),g.blendFunc(g.ONE,g.ONE);for(let u of wt)u.destroyed||u.renderLight();Lt(),g.bindFramebuffer(g.FRAMEBUFFER,null),g.viewport(0,0,I.x,I.y),g.useProgram(q.compositeShader),g.bindVertexArray(q.compositeVAO),g.activeTexture(g.TEXTURE0),g.bindTexture(g.TEXTURE_2D,q.texture);let l=q.compositeShader;g.uniform1i(g.getUniformLocation(l,"s"),0),g.uniform3f(g.getUniformLocation(l,"iResolution"),F.width,F.height,1),g.blendFunc(g.DST_COLOR,g.ZERO),g.drawArrays(g.TRIANGLE_STRIP,0,4),te&&g.bindTexture(g.TEXTURE_2D,te),ps(r),Ts(!0)}function o(){q.texture=void 0,q.lightShader=void 0,q.compositeShader=void 0,q.lightVAO=void 0,q.compositeVAO=void 0,St("LightSystemPlugin: WebGL context lost")}function a(){s(),St("LightSystemPlugin: WebGL context restored")}}drawLight(t){if(B||!G||!this.lightShader)return;Lt(),g.useProgram(this.lightShader),g.bindVertexArray(this.lightVAO);let e=b(2*H).divide(I),s=Pt.rotate(-tt),i=b(-1).subtract(s.multiply(e)),o=lt(tt),a=it(tt),r=[e.x*o,e.y*a,0,0,-e.x*a,e.y*o,0,0,1,1,1,0,i.x,i.y,0,1],c=this.lightShader;g.uniformMatrix4fv(g.getUniformLocation(c,"m"),!1,r),g.uniform2f(g.getUniformLocation(c,"lightPos"),t.pos.x,t.pos.y),g.uniform1f(g.getUniformLocation(c,"radius"),t.radius),g.uniform1f(g.getUniformLocation(c,"fadeRange"),t.fadeRange);let l=t.color;g.uniform4f(g.getUniformLocation(c,"color"),l.r,l.g,l.b,l.a),g.drawArrays(g.TRIANGLE_STRIP,0,4),Ts(!0)}},Oo=class extends qe{constructor(t,e,s,i){super(t,b(1),void 0,0,s),p(R(e)&&e>=0,"Light radius must be a non-negative number"),p(i===void 0||R(i)&&i>=0,"Light fadeRange must be a non-negative number when provided"),this.radius=e,this.fadeRange=i===void 0?e:i}render(){}renderLight(){q&&q.drawLight(this)}},Do=class extends xs{constructor(t){super(void 0),!(!Yt||B)&&(this.randomness=0,this.sampleChannels=Cc(...t),this.sampleRate=ts)}playMusic(t=1,e=!0){return super.play(void 0,t,1,0,e)}};Wr=0;Io=class{constructor(t=ut){p(!E,"UI system already initialized"),E=this,this.activateOnPress=!1,this.defaultColor=V,this.defaultLineColor=ot,this.defaultTextColor=ot,this.defaultButtonColor=Ne(0,0,.7),this.defaultHoverColor=Ne(0,0,.9),this.defaultDisabledColor=Ne(0,0,.3),this.defaultGradientColor=void 0,this.defaultLineWidth=4,this.defaultCornerRadius=0,this.defaultTextFitScale=.8,this.defaultFont=Ps,this.defaultSoundPress=void 0,this.defaultSoundRelease=void 0,this.defaultSoundClick=void 0,this.defaultShadowColor=ye,this.defaultShadowBlur=5,this.defaultShadowOffset=b(5),this.nativeHeight=0,this.navigationObject=void 0,this.navigationTimer=new Re(void 0,!0),this.navigationDelay=.2,this.navigationDirection=1,this.navigationMode=!1,this.uiObjects=[],this.uiContext=t,this.activeObject=void 0,this.hoverObject=void 0,this.lastHoverObject=void 0,this.confirmDialog=void 0,this._keyInputObject=void 0,this._onKeyDown=o=>{var a;return(a=this._keyInputObject)==null?void 0:a.onKeyDown(o)},Pn(s,i);function e(o){let a,r;o.parent?(a=o.parent.nativePos,r=o.parent.size):(a=E.screenToNative(I.scale(.5)),r=E.nativeHeight?b(I.x*E.nativeHeight/I.y,E.nativeHeight):I);let c=o.anchor;o.nativePos=a.add(r.multiply(c).scale(.5)).subtract(o.size.multiply(c).scale(.5)).add(o.localPos)}function s(){E.activeObject&&!E.activeObject.visible&&(E.activeObject=void 0),E.lastHoverObject=E.hoverObject,E.hoverObject=void 0,gs(0)&&(E.navigationMode=!1,E.navigationObject=void 0),E.keyInputObject&&(E.activeObject=E.keyInputObject,E.hoverObject=E.keyInputObject,E.navigationMode=!1,E.navigationObject=void 0);let o=E.getNavigableObjects();if(!o.length)E.navigationObject=void 0;else if(!E.keyInputObject){if(o.includes(E.navigationObject)||(E.navigationObject=void 0),re||E.navigationMode&&!E.navigationObject&&(E.navigationObject=o.find(r=>r.navigationAutoSelect)),!E.navigationTimer.active()){let r=ie(E.getNavigationDirection());if(r){let c;if(E.navigationObject){let l=o.indexOf(E.navigationObject),u=oe(l+r,o.length);c=o[u]}else if(c=o.find(l=>l.navigationAutoSelect),!c){let l=r>0?0:o.length-1;c=o[l]}E.navigationObject!==c&&(E.navigationMode=!0,E.hoverObject=void 0,E.navigationObject=c,E.navigationTimer.set(E.navigationDelay),c.soundPress&&c.soundPress.play())}}E.navigationObject&&E.getNavigationWasPressed()&&E.navigationObject.navigatePressed()}for(let r=E.uiObjects.length;r--;){let c=E.uiObjects[r];c.parent||a(c)}E.uiObjects=E.uiObjects.filter(r=>!r.destroyed);function a(r){if(!(r.destroyed||!r.visible)){e(r);for(let c=r.children.length;c--;){let l=r.children[c];l&&a(l)}r.destroyed||r.update()}}}function i(){let o=E.uiContext;if(o.save(),E.nativeHeight){let r=I.y/E.nativeHeight;o.translate(-r*I.x/2,0),o.scale(r,r),o.translate(I.x/2/r,0)}function a(r){if(r.visible){e(r),r.render();for(let c of r.children)a(c)}}if(E.uiObjects.forEach(r=>r.parent||a(r)),Wr>0){let r=function(c,l=!0){l&&(l=!!c.visible),e(c),c.renderDebug(l);for(let u of c.children)r(u,l)};E.uiObjects.forEach(c=>c.parent||r(c))}o.restore()}}drawRect(t,e,s=V,i=0,o=ot,a=0,r,c=ot,l=0,u=b()){p(O(t),"pos must be a vec2"),p(O(e),"size must be a vec2"),p(J(s),"color must be a color"),p(R(i),"lineWidth must be a number"),p(J(o),"lineColor must be a color"),p(R(a),"cornerRadius must be a number");let h=E.uiContext;if(r){let d=h.createLinearGradient(t.x,t.y-e.y/2,t.x,t.y+e.y/2),f=s.toString();d.addColorStop(0,f),d.addColorStop(.5,r.toString()),d.addColorStop(1,f),h.fillStyle=d}else h.fillStyle=s.toString();(l||u.x||u.y)&&c.a>0&&(h.shadowColor=c.toString(),h.shadowBlur=l,h.shadowOffsetX=u.x,h.shadowOffsetY=u.y),h.beginPath(),a&&h.roundRect?h.roundRect(t.x-e.x/2,t.y-e.y/2,e.x,e.y,a):h.rect(t.x-e.x/2,t.y-e.y/2,e.x,e.y),h.fill(),h.shadowColor="#0000",i&&o.a>0&&(h.strokeStyle=o.toString(),h.lineWidth=i,h.stroke())}drawLine(t,e,s=E.defaultLineWidth,i=E.defaultLineColor){p(O(t),"posA must be a vec2"),p(O(e),"posB must be a vec2"),p(R(s),"lineWidth must be a number"),p(J(i),"lineColor must be a color");let o=E.uiContext;o.strokeStyle=i.toString(),o.lineWidth=s,o.beginPath(),o.lineTo(t.x,t.y),o.lineTo(e.x,e.y),o.stroke()}drawTile(t,e,s,i=E.defaultColor,o=0,a=!1,r=ot,c=0,l=b()){let u=E.uiContext;(c||l.x||l.y)&&r.a>0&&(u.shadowColor=r.toString(),u.shadowBlur=c,u.shadowOffsetX=l.x,u.shadowOffsetY=l.y),It(t,e,s,i,o,a,ye,!1,!0,u),u.shadowColor="#0000"}drawText(t,e,s,i=E.defaultColor,o=E.defaultLineWidth,a=E.defaultLineColor,r="center",c=E.defaultFont,l="",u=!0,h=void 0,d=ot,f=0,y=b()){let x=E.uiContext;d.a>0&&(h&&rn(t,e.add(h),s.y,d,o,a,r,c,l,u?s.x:void 0,0,x),(f||y.x||y.y)&&(x.shadowColor=d.toString(),x.shadowBlur=f,x.shadowOffsetX=y.x,x.shadowOffsetY=y.y)),rn(t,e,s.y,i,o,a,r,c,l,u?s.x:void 0,0,x),x.shadowColor="#0000"}setupDragAndDrop(t,e,s,i){if(this._dragListeners)for(let[a,r]of this._dragListeners)document.removeEventListener(a,r);this._dragListeners=[];let o=(a,r)=>{let c=l=>{l.preventDefault(),a&&a(l)};document.addEventListener(r,c),this._dragListeners.push([r,c])};o(t,"drop"),o(e,"dragenter"),o(s,"dragleave"),o(i,"dragover")}screenToNative(t){if(!E.nativeHeight)return t;let e=I.y/E.nativeHeight,s=1/e,i=t.copy();return i.x+=e*I.x/2,i.x*=s,i.y*=s,i.x-=s*I.x/2,i}get keyInputObject(){return this._keyInputObject}set keyInputObject(t){let e=!!this._keyInputObject;this._keyInputObject=t,!e&&t?document.addEventListener("keydown",this._onKeyDown):e&&!t&&document.removeEventListener("keydown",this._onKeyDown)}destroyObjects(){for(let t of this.uiObjects)t.parent||t.destroy();this.uiObjects=this.uiObjects.filter(t=>!t.destroyed),this.activeObject=void 0,this.hoverObject=void 0,this.lastHoverObject=void 0,this.keyInputObject=void 0}getNavigableObjects(){function t(s){if(!(!s.visible||s.disabled)){s.isInteractive()&&s.navigationIndex!==void 0&&e.push(s);for(let i=s.children.length;i--;)t(s.children[i])}}let e=[];for(let s=E.uiObjects.length;s--;){let i=E.uiObjects[s];E.confirmDialog&&i!==E.confirmDialog||i.parent||t(i)}return e.sort((s,i)=>s.navigationIndex-i.navigationIndex),e}getNavigationDirection(){let t=E.navigationDirection===1,e=E.navigationDirection===2;if(zn){let l=ys(0,bt),u=bo(bt);return e?-(l.y||u.y)||l.x||u.x:t?-(l.y||u.y):l.x||u.x}let s="ArrowUp",i="ArrowDown",o="ArrowLeft",a="ArrowRight";if(e)return Dt(s)||Dt(o)?-1:Dt(i)||Dt(a)?1:0;let r=t?s:o,c=t?i:a;return Dt(r)?-1:Dt(c)?1:0}getNavigationOtherDirection(){if(E.navigationDirection===2)return 0;let t=E.navigationDirection===1;if(zn){let i=ys(0,bt),o=bo(bt);return t?i.x||o.x:i.y||o.y}let e=t?"ArrowLeft":"ArrowUp",s=t?"ArrowRight":"ArrowDown";return Dt(e)?-1:Dt(s)?1:0}getNavigationWasPressed(){return zn?Rr(0,bt):Ft("Space")||Ft("Enter")}showConfirmDialog(t="Are you sure?",e,s,i=b(500,250),o="Escape"){p(!E.confirmDialog);let a=E.navigationDirection;E.navigationDirection=2;let r=new ce(b(),i);E.confirmDialog=r,r.onRender=()=>{let f=Ne(0,0,0,.7);E.drawRect(b(),b(1e9),f)},r.onUpdate=()=>{Ft(o)&&d()},r.isMouseOverlapping=()=>!0;let c=50,l=new vi(b(0,-50),b(i.x-c,70),t);r.addChild(l);let u=new _s(b(-80,50),b(120,70),"Yes");u.textHeight=40,u.navigationIndex=1,u.hoverColor=Ne(0,1,.5),u.onClick=()=>{d(),e&&e()},r.addChild(u);let h=new _s(b(80,50),b(120,70),"No");h.textHeight=40,h.navigationIndex=2,h.navigationAutoSelect=!0,h.onClick=()=>{d(),s&&s()},r.addChild(h);function d(){p(E.confirmDialog===r),r.destroy(),E.confirmDialog=void 0,E.navigationDirection=a,Gs()}}},ce=class{constructor(t=b(),e=b()){var s,i;p(O(t),"ui object pos must be a vec2"),p(O(e),"ui object size must be a vec2"),this.localPos=t.copy(),this.nativePos=t.copy(),this.size=e.copy(),this.color=E.defaultColor.copy(),this.activeColor=void 0,this.text=void 0,this.disabledColor=E.defaultDisabledColor.copy(),this.disabled=!1,this.textColor=E.defaultTextColor.copy(),this.hoverColor=E.defaultHoverColor.copy(),this.lineColor=E.defaultLineColor.copy(),this.gradientColor=E.defaultGradientColor?E.defaultGradientColor.copy():void 0,this.lineWidth=E.defaultLineWidth,this.cornerRadius=E.defaultCornerRadius,this.font=E.defaultFont,this.fontStyle=void 0,this.textWidth=void 0,this.textHeight=void 0,this.textFitScale=E.defaultTextFitScale,this.textShadow=void 0,this.textLineColor=E.defaultLineColor.copy(),this.textLineWidth=0,this.visible=!0,this.children=[],this.parent=void 0,this.extraTouchSize=0,this.soundPress=E.defaultSoundPress,this.soundRelease=E.defaultSoundRelease,this.soundClick=E.defaultSoundClick,this.interactive=!1,this.dragActivate=!1,this.canBeHover=!0,this.shadowColor=(s=E.defaultShadowColor)==null?void 0:s.copy(),this.shadowBlur=E.defaultShadowBlur,this.shadowOffset=(i=E.defaultShadowOffset)==null?void 0:i.copy(),this.navigationIndex=void 0,this.navigationAutoSelect=!1,this.anchor=b(),E.uiObjects.push(this)}addChild(t){return p(!t.parent&&!this.children.includes(t)),this.children.push(t),t.parent=this,t}removeChild(t){p(t.parent===this&&this.children.includes(t)),this.children.splice(this.children.indexOf(t),1),t.parent=void 0}destroy(){var t;if(!this.destroyed){E.activeObject===this&&(E.activeObject=void 0),E.hoverObject===this&&(E.hoverObject=void 0),E.lastHoverObject===this&&(E.lastHoverObject=void 0),E.navigationObject===this&&(E.navigationObject=void 0),E.keyInputObject===this&&(E.keyInputObject=void 0),this.destroyed=1,(t=this.parent)==null||t.removeChild(this);for(let e of this.children)e.parent=void 0,e.destroy();this.children.length=0}}isMouseOverlapping(){if(!oi)return!1;let t=re?this.size.add(b(this.extraTouchSize||0)):this.size,e=E.screenToNative(Vt);return Qs(this.nativePos,t,e)}update(){if(this.onUpdate(),this.disabled&&(this===E.activeObject&&(E.activeObject=void 0),this===E.keyInputObject&&(E.keyInputObject=void 0)),E.keyInputObject)return;let t=E.lastHoverObject===this,e=this.isActiveObject(),s=ls(0),i=this.dragActivate?s:gs(0);this.canBeHover&&(E.navigationMode||(i||e||!s&&!re)&&!E.hoverObject&&this.isMouseOverlapping()&&(E.hoverObject=this)),this.isHoverObject()&&(this.disabled||(i&&this.interactive&&((!this.dragActivate||!t||gs(0))&&this.onPress(),this.soundPress&&this.soundPress.play(),E.activeObject&&!e&&E.activeObject.onRelease(),E.activeObject=this,E.activateOnPress&&this.click(!this.soundPress)),E.activateOnPress||!s&&this.isActiveObject()&&this.interactive&&this.click()),i&&Cr(0,0,0,1,0)),e&&(!s||this.dragActivate&&!this.isHoverObject())&&(this.onRelease(),this.soundRelease&&this.soundRelease.play(),E.activeObject=void 0),this.isHoverObject()!==t&&(this.isHoverObject()?this.onEnter():this.onLeave())}render(){if(this.onRender(),!this.size.x||!this.size.y)return;let t=this.isNavigationObject(),e=t?this.color:this.interactive&&this.isActiveObject()&&!this.disabled?this.color:this.lineColor,s=t?this.hoverColor:this.disabled?this.disabledColor:this.interactive?this.isActiveObject()?this.activeColor||this.hoverColor:this.isHoverObject()?this.hoverColor:this.color:this.color,i=this.lineWidth*(t?1.5:1);E.drawRect(this.nativePos,this.size,s,i,e,this.cornerRadius,this.gradientColor,this.shadowColor,this.shadowBlur,this.shadowOffset)}getTextSize(){return b(this.textWidth||this.textFitScale*this.size.x,this.textHeight||this.textFitScale*this.size.y)}navigatePressed(){this.click()}isHoverObject(){return E.hoverObject===this}isActiveObject(){return E.activeObject===this}isNavigationObject(){return E.navigationObject===this}isKeyInputObject(){return E.keyInputObject===this}isInteractive(){return this.interactive&&this.visible&&!this.disabled}toString(){let t="type = "+this.constructor.name;return this.text&&(t+=`
 text = `+this.text),(this.nativePos.x||this.nativePos.y)&&(t+=`
 nativePos = `+this.nativePos),(this.localPos.x||this.localPos.y)&&(t+=`
 localPos = `+this.localPos),(this.size.x||this.size.y)&&(t+=`
 size = `+this.size),this.color&&(t+=`
-color = `+this.color),t}renderDebug(t=!0){let e=t?this.isHoverObject()?Ka:this.disabled?tc:this.interactive?rr:Za:Qa;E.drawRect(this.nativePos,this.size,pe,4,e)}click(t=!0){this.onClick(),t&&this.soundClick&&this.soundClick.play()}onUpdate(){}onRender(){}onEnter(){}onLeave(){}onPress(){}onRelease(){}onClick(){}onChange(){}},vi=class extends re{constructor(t,e,s="",i="center",o=E.defaultFont){super(t,e),f(V(s),"ui text must be a string"),f(["left","center","right"].includes(i),"ui text align must be left, center, or right"),f(V(o),"ui text font must be a string"),this.text=s,this.align=i,this.font=o,this.canBeHover=!1,this.color=pe,this.shadowColor=pe,this.gradientColor=void 0,this.lineWidth=0,this.textFitScale=1}render(){super.render();let t=this.getTextSize();E.drawText(this.text,this.nativePos,t,this.textColor,this.textLineWidth,this.textLineColor,this.align,this.font,this.fontStyle,!0,this.textShadow,this.shadowColor,this.shadowBlur,this.shadowOffset)}},Mo=class extends re{constructor(t,e,s=""){super(t,e),f(V(s),"ui text must be a string"),this.maxLength=0,this.text=s,this.interactive=!0,this.canBeHover=!0}click(){E.keyInputObject=this,this.onClick()}stopEditing(){this.isKeyInputObject()&&(this.soundRelease&&this.soundRelease.play(),E.activeObject=void 0,E.keyInputObject=void 0,this.onChange())}onKeyDown(t){let e=t.code,s=t.key;e==="Backspace"?this.text=this.text.slice(0,-1):e==="Enter"||e==="Escape"?this.stopEditing():s.length===1&&(!this.maxLength||this.text.lengththis.size.y,s=e?this.size.y:this.size.x,i=e?this.size.x:this.size.y,o=e?this.nativePos.x:this.nativePos.y,a=i-s,r=o-a/2,c=o+a/2,l=E.screenToNative(Jt);this.value=e?Bt(l.x,r,c):Bt(l.y,c,r)}else if(this.isNavigationObject()){let e=E.getNavigationOtherDirection();E.navigationTimer.active()||(this.value=N(this.value+e*.01))}this.value===t||this.onChange()}render(){super.render();let t=this.size.x>this.size.y,e=t?this.size.x:this.size.y,s=t?this.size.y:this.size.x;if(this.fillMode){let o=tt(s,this.cornerRadius*2),a=Wt(o,e,this.value),r=(a-e)*(t?.5:-.5),c=this.nativePos.add(t?b(r,0):b(0,r)),l=this.disabled?this.disabledColor:this.handleColor,u=t?b(a,this.size.y):b(this.size.x,a);E.drawRect(c,u,l,this.lineWidth,this.lineColor,this.cornerRadius,this.gradientColor)}else{let o=N(t?this.value:1-this.value),a=(e-s)*(o-.5),r=this.nativePos.add(t?b(a,0):b(0,a)),c=this.disabled?this.disabledColor:this.handleColor,l=b(s);E.drawRect(r,l,c,this.lineWidth,this.lineColor,this.cornerRadius,this.gradientColor)}let i=this.getTextSize();E.drawText(this.text,this.nativePos,i,this.textColor,this.textLineWidth,this.textLineColor,this.align,this.font,this.fontStyle,!0,this.textShadow)}navigatePressed(){this.value=this.value?0:1,this.onChange(),this.onRelease(),super.navigatePressed()}},jo=class extends re{constructor(t,e,s,i=!1,o=!1,a=1){super(t,e||b()),f(V(s),"video src must be a string"),f(L(a),"video volume must be a number"),this.color=it,this.cornerRadius=0,this.volume=a,this.video=document.createElement("video"),this.video.loop=o,this.video.volume=N(a*Sn),this.video.muted=!Ht,this.video.style.display="none",this.video.src=s,document.body.appendChild(this.video),i&&this.play()}async play(){try{await this.video.play()}catch{}}pause(){this.video.pause()}stop(){this.video.pause(),this.video.currentTime=0}isLoading(){return this.video.readyState=1,"ui layout columns must be a number >= 1"),f(L(s),"ui layout gap must be a number"),f(L(i),"ui layout padding must be a number"),this.columns=e,this.gap=s,this.padding=i,o&&(this.color=pe,this.gradientColor=void 0,this.lineWidth=0,this.shadowColor=pe),this.relayout()}addChild(t){return super.addChild(t),this.relayout(),t}removeChild(t){super.removeChild(t),this.relayout()}relayout(){let t=this.children.length;if(!t){this.size=b(this.padding*2);return}let e=this.columns,s=us(t/e),i=new Array(e).fill(0),o=new Array(s).fill(0);for(let p=0;p=0&&m.objects.splice(t,1),super.destroy()}updatePhysics(){}render(){this.tileInfo?super.render():this.drawFixtures(this.color,this.lineColor,this.lineWidth)}renderDebugInfo(){let t=!this.getIsAwake(),e=this.getBodyType()===m.bodyTypeStatic,s=J(t?1:0,t?1:0,e?1:0,.5);this.drawFixtures(s)}drawFixtures(t=W,e=it,s=.1,i,o){this.getFixtureList().forEach(a=>{m.castShapeObject(a.GetShape()).GetType()!==m.instance.b2Shape.e_edge&&m.drawFixture(a,this.pos,this.angle,t,e,s,i,o)}),this.edgeLists.forEach(a=>mo(a,s,e,!1,this.pos,this.angle)),this.edgeLoops.forEach(a=>mo(a,s,e,!0,this.pos,this.angle))}beginContact(t){}endContact(t){}addShape(t,e=1,s=.2,i=0,o=!1){f(L(e),"density must be a number"),f(L(s),"friction must be a number"),f(L(i),"restitution must be a number");let a=new m.instance.b2FixtureDef;return a.set_shape(t),a.set_density(e),a.set_friction(s),a.set_restitution(i),a.set_isSensor(o),this.body.CreateFixture(a)}addBox(t=b(1),e=b(),s=0,i,o,a,r){f(O(t),"size must be a Vector2"),f(t.x>0&&t.y>0,"size must be positive"),f(O(e),"offset must be a Vector2"),f(L(s),"angle must be a number");let c=new m.instance.b2PolygonShape;return c.SetAsBox(t.x/2,t.y/2,m.vec2dTo(e),-s),this.addShape(c,i,o,a,r)}addPoly(t,e,s,i,o){f(de(t),"points must be an array");function a(c){f(3<=c.length&&c.length<=8);let l=m.instance._malloc(c.length*8);for(let p=0,d=0;p>2]=c[p].x,d+=4,m.instance.HEAPF32[l+d>>2]=c[p].y,d+=4;let u=m.instance.wrapPointer(l,m.instance.b2Vec2),h=new m.instance.b2PolygonShape;return h.Set(u,c.length),m.instance._free(l),h}let r=a(t);return this.addShape(r,e,s,i,o)}addRegularPoly(t=1,e=8,s,i,o,a){f(L(t)&&t>0,"diameter must be a positive number"),f(L(e)&&e>2,"sides must be a positive number greater than 2");let r=[],c=t/2;for(let l=e;l--;)r.push(b(c,0).rotate((l+.5)/e*X*2));return this.addPoly(r,s,i,o,a)}addRandomPoly(t=1,e,s,i,o){f(L(t)&&t>0,"diameter must be a positive number");let a=or(3,9),r=[],c=t/2;for(let l=a;l--;)r.push(b(dt(c/2,c*1.5),0).rotate(l/a*X*2));return this.addPoly(r,e,s,i,o)}addCircle(t=1,e=b(),s,i,o,a){f(L(t)&&t>0,"diameter must be a positive number"),f(O(e),"offset must be a Vector2");let r=new m.instance.b2CircleShape;return r.set_m_p(m.vec2dTo(e)),r.set_m_radius(t/2),this.addShape(r,s,i,o,a)}addEdge(t,e,s,i,o,a){f(O(t),"point1 must be a Vector2"),f(O(e),"point2 must be a Vector2");let r=new m.instance.b2EdgeShape;return r.Set(m.vec2dTo(t),m.vec2dTo(e)),this.addShape(r,s,i,o,a)}addEdgeList(t,e,s,i,o){f(de(t),"points must be an array");let a=[],r=[];for(let c=0;ct[se(l,t.length)];for(let l=0;lthis.destroyFixture(t))}getCenterOfMass(){return m.vec2From(this.body.GetWorldCenter())}getLinearVelocity(){return m.vec2From(this.body.GetLinearVelocity())}getAngularVelocity(){return this.body.GetAngularVelocity()}getMass(){return this.body.GetMass()}getInertia(){return this.body.GetInertia()}getIsAwake(){return this.body.IsAwake()}getBodyType(){return this.body.GetType()}getSpeed(){return this.getLinearVelocity().length()}setTransform(t,e){this.pos=t,this.angle=e,this.body.SetTransform(m.vec2dTo(t),-e)}setPosition(t){this.setTransform(t,this.body.GetAngle())}setAngle(t){this.setTransform(m.vec2From(this.body.GetPosition()),t)}setLinearVelocity(t){this.body.SetLinearVelocity(m.vec2dTo(t))}setAngularVelocity(t){this.body.SetAngularVelocity(t)}setLinearDamping(t){this.body.SetLinearDamping(t)}setAngularDamping(t){this.body.SetAngularDamping(t)}setGravityScale(t=1){this.body.SetGravityScale(this.gravityScale=t)}setBullet(t=!0){this.body.SetBullet(t)}setAwake(t=!0){this.body.SetAwake(t)}setBodyType(t){this.body.SetType(t)}setSleepingAllowed(t=!0){this.body.SetSleepingAllowed(t)}setFixedRotation(t=!0){this.body.SetFixedRotation(t)}setCenterOfMass(t){this.setMassData(t)}setMass(t){this.setMassData(void 0,t)}setMomentOfInertia(t){this.setMassData(void 0,void 0,t)}resetMassData(){this.body.ResetMassData()}setMassData(t,e,s){let i=new m.instance.b2MassData;this.body.GetMassData(i),t!==void 0&&i.set_center(m.vec2dTo(t)),e!==void 0&&i.set_mass(e),s!==void 0&&i.set_I(s),this.body.SetMassData(i)}setFilterData(t=0,e=0,s=0){this.getFixtureList().forEach(i=>{let o=i.GetFilterData();o.set_categoryBits(t),o.set_maskBits(65535&~e),o.set_groupIndex(s)})}setSensor(t=!0){this.getFixtureList().forEach(e=>e.SetSensor(t))}applyForce(t,e){e||(e=this.getCenterOfMass()),this.setAwake(),this.body.ApplyForce(m.vec2dTo(t),m.vec2dTo(e))}applyAcceleration(t,e){e||(e=this.getCenterOfMass()),this.setAwake();let s=t.scale(this.getMass());this.body.ApplyLinearImpulse(m.vec2dTo(s),m.vec2dTo(e))}applyImpulse(t,e){e||(e=this.getCenterOfMass()),this.setAwake(),this.body.ApplyLinearImpulse(m.vec2dTo(t),m.vec2dTo(e))}applyTorque(t){this.setAwake(),this.body.ApplyTorque(t)}applyAngularAcceleration(t){this.setAwake(),this.body.ApplyAngularImpulse(t*this.getInertia())}applyAngularImpulse(t){this.setAwake(),this.body.ApplyAngularImpulse(t)}hasFixtures(){return!m.isNull(this.body.GetFixtureList())}getFixtureList(){let t=[];for(let e=this.body.GetFixtureList();!m.isNull(e);)t.push(e),e=e.GetNext();return t}hasJoints(){return!m.isNull(this.body.GetJointList())}getJointList(){let t=[];for(let e=this.body.GetJointList();!m.isNull(e);)t.push(e),e=e.get_next();return t}},Si=class extends _s{constructor(t,e,s,i=0,o,a=0){let r=m.bodyTypeStatic;super(t,e,s,i,o,r,a)}},No=class extends _s{constructor(t,e,s,i=0,o,a=0){let r=m.bodyTypeKinematic;super(t,e,s,i,o,r,a)}},zo=class extends Si{constructor(t){f(t instanceof vs,"tileLayer must be a TileCollisionLayer"),super(t.pos,t.size),this.tileLayer=t,this.addChild(t)}render(){}buildCollision(t=.2,e=0){this.destroyAllFixtures(),this.pos=this.tileLayer.pos.copy(),this.size=this.tileLayer.size.copy();let s=[],i=(a,r)=>a+r*this.size.x,o=(a,r)=>!s[i(a,r)]&&this.tileLayer.getCollisionData(b(a,r))>0;for(let a=0;ai.fractiono.pos.distanceSquared(t)0,"Tween duration must be > 0"),this.callback=t,this.start=e,this.end=s,this.duration=i,this.life=i,this.ease=o.ease||Ci.LINEAR,this.useRealTime=!!o.useRealTime,this.paused=!!o.paused,this.thenCallback=void 0,this.loopRemaining=0,$t.push(this),t(this.interp(i))}setEase(t){return this.ease=t,this}then(t){return this.thenCallback=t,this.loopRemaining=0,this}loop(t=1/0){return this.loopRemaining=t,this.thenCallback=()=>Lc(this),this}pingPong(t=1/0){return this.loopRemaining=t,this.thenCallback=()=>Oc(this),this}pause(){this.paused=!0}resume(){this.paused=!1}restart(){this.life=this.duration,this.paused=!1,$t.indexOf(this)<0&&$t.push(this),this.callback(this.interp(this.duration))}isActive(){return!this.paused&&$t.indexOf(this)>=0}getPercent(){return Bt(this.duration-this.life,0,this.duration)}getValue(){return this.interp(this.life)}interp(t){let e=this.ease((this.duration-t)/this.duration);return La(this.start)?this.start.lerp(this.end,e):this.start+(this.end-this.start)*e}stop(){let t=$t.indexOf(this);t>=0&&$t.splice(t,1),this.thenCallback=void 0}},Ci={LINEAR:n=>n,POWER:n=>t=>t**n,SINE:n=>1-lt(n*(X/2)),CIRC:n=>1-(1-n*n)**.5,EXPO:n=>n===0?0:2**(10*n-10),BACK:n=>n*n*(2.70158*n-1.70158),ELASTIC:n=>n===0?0:n===1?1:-(2**(10*n-10))*st((37-40*n)*X/6),SPRING:n=>1-(st(X*(1-n)*(.2+2.5*(1-n)**3))*n**2.2+(1-n))*(1+1.2*n),BOUNCE:n=>{let t=1-n,e;return t<4/11?e=7.5625*t*t:t<8/11?e=7.5625*(t-=6/11)*t+.75:t<10/11?e=7.5625*(t-=9/11)*t+.9375:e=7.5625*(t-=10.5/11)*t+.984375,1-e},IN:n=>n,OUT:n=>t=>1-n(1-t),IN_OUT:n=>Ci.PIECEWISE(n,Ci.OUT(n)),PIECEWISE:(...n)=>{let t=n.length;return e=>{let s=e*t-1e-9>>0;return(n[s]((e-s/t)*t)+s)/t}},BEZIER:(n,t,e,s)=>{let i=o=>{let a=1-o,r=3*a*a*o,c=3*a*o*o,l=o**3;return[r*n+c*e+l,r*t+c*s+l]};return o=>{let a=0,r=1;for(let c=0;c<128;c++){let l=(a+r)/2,[u,h]=i(l);if(nt(u-o)<1e-5)return h;u=this.size.x||e>=this.size.y?null:this.nodes[t+e*this.size.x]}worldToTile(t){let e=this.tileLayer?this.tileLayer.pos.x:0,s=this.tileLayer?this.tileLayer.pos.y:0;return b(St(t.x-e),St(t.y-s))}tileToWorld(t,e){let s=this.tileLayer?this.tileLayer.pos.x:0,i=this.tileLayer?this.tileLayer.pos.y:0;return b(t+.5+s,e+.5+i)}buildNodeData(){let t=this.size.x,e=this.size.y,s=this.tileLayer?this.tileLayer.pos.x:0,i=this.tileLayer?this.tileLayer.pos.y:0;for(let o=0;o0&&(c?l>0&&bt(r.posWorld,lo,J(1,0,0,tt(.2,l*.05)),this.debugTime):bt(r.posWorld,lo,J(1,0,0,.25),this.debugTime))}}aStarSearch(t,e){f(t&&e,"aStarSearch needs both endpoints"),f(t!==e,"aStarSearch: start and end must differ \u2014 caller should handle trivial case"),f(t.walkable&&e.walkable,"aStarSearch: endpoints must be walkable");let s=[t];t.isOpen=!0;let i=0;for(;s.length>0;){let o=0,a=s[0].f;for(let c=1;cthis.maxLoop)break;r.isOpen=!1,s.splice(o,1),r.isClosed=!0,this.debug&&this.debugTime>0&&bt(r.posWorld,lo,J(1,1,1,.05),this.debugTime);for(let c=-1;c<=1;++c)for(let l=-1;l<=1;++l){if(l===0&&c===0)continue;let u=this.getNode(r.pos.x+l,r.pos.y+c);if(!u||!u.walkable||u.isClosed)continue;let h=1;if(l!==0&&c!==0){let v=this.getNode(r.pos.x+l,r.pos.y);if(!v||!v.walkable)continue;let w=this.getNode(r.pos.x,r.pos.y+c);if(!w||!w.walkable)continue;h=fd}let p=r.g+h+u.cost;if(!u.isOpen)u.isOpen=!0,s.push(u);else if(p>=u.g)continue;u.parent=r,u.g=p;let d=nt(e.pos.x-u.pos.x),y=nt(e.pos.y-u.pos.y),x=K(d,y)+(Math.SQRT2-1)*tt(d,y);u.f=u.g+x*this.heuristicWeight}}return e.parent!==null}getNearestClearNode(t,e=10,s=!0){f(O(t),"worldPos must be a Vector2"),s&&this.buildNodeData();let i=this.tileLayer?this.tileLayer.pos.x:0,o=this.tileLayer?this.tileLayer.pos.y:0,a=St(t.x-i),r=St(t.y-o);for(let c=0;c<=e;++c){let l=null,u=0;for(let h=-c;h<=c;++h)for(let p=-c;p<=c;++p){if(c>0&&nt(p)!==c&&nt(h)!==c)continue;let d=this.getNode(a+p,r+h);if(!d||!d.isClear())continue;let y=d.posWorld.x-t.x,x=d.posWorld.y-t.y,v=y*y+x*x;(!l||v0&&Ut(i.posWorld,.3,J(.5,0,.5,.5),this.debugTime),t.splice(e,1),e=K(1,e-1);continue}else if(c===2){this.debug&&this.debugTime>0&&Ut(i.posWorld,.3,J(1,0,0,.5),this.debugTime);let d,y;s.pos.y===i.pos.y&&o.pos.x===i.pos.x?(d=s.pos.x,y=o.pos.y):(d=o.pos.x,y=s.pos.y);let x=this.getNode(d,y);if(x&&x.isClear()){t.splice(e,1),e=K(1,e-1);continue}}else if(c===5){this.debug&&this.debugTime>0&&Ut(i.posWorld,.3,J(1,1,0,.5),this.debugTime);let d=e>=2?t[e-2]:s,y,x,v,w;l===0||h===0?(y=o.pos.x,x=i.pos.y,v=s.pos.x,w=i.pos.y):(y=i.pos.x,x=o.pos.y,v=i.pos.x,w=s.pos.y);let _=y-d.pos.x,S=x-d.pos.y,C=v-d.pos.x,A=w-d.pos.y,T=_*_+S*S,P=C*C+A*A,M=T0&&Ut(i.posWorld,.3,J(0,1,0,.5),this.debugTime),l===h&&u===p){++e;continue}else{let d,y;s.pos.y===o.pos.y?(d=i.pos.x,y=s.pos.y):(d=s.pos.x,y=i.pos.y);let x=this.getNode(d,y);if(x&&x.isClear()){t[e]=x,e=K(1,e-1);continue}}++e}}smoothPathStringPull(t){if(t.length<=2)return;for(let i of t)if(!i.isClear())return;let e=t.slice();t.length=0,t.push(e[0]);let s=0;for(let i=1;i0&&we(o.posWorld,t[t.length-1].posWorld,J(0,0,1,.3),.02,this.debugTime);continue}for(;s=1;--e){let s=t[e-1],i=t[e],o=t[e+1];(i.pos.x-s.pos.x)*(o.pos.y-s.pos.y)===(i.pos.y-s.pos.y)*(o.pos.x-s.pos.x)&&t.splice(e,1)}}isNodeClear(t,e){let s=this.getNode(t,e);return s!==null&&s.isClear()}isLineClear(t,e){f(O(t)&&O(e),"isLineClear needs Vector2 endpoints"),f(this.isNodeClear(t.x,t.y)&&this.isNodeClear(e.x,e.y),"isLineClear endpoints must be in-bounds and clear");let s=e.x-t.x,i=e.y-t.y,o=nt(s),a=nt(i),r=ne(s),c=ne(i),l=t.x,u=t.y;if(a===o){for(;l!==e.x;){if(l!==t.x&&(!this.isNodeClear(l,u)||!this.isNodeClear(l,u-c))||!this.isNodeClear(l,u+c))return!1;l+=r,u+=c}if(!this.isNodeClear(e.x,e.y-c))return!1}else if(ar.posWorld.copy());if(this.debug&&this.debugTime>0&&a.length>0){for(let r=1;rpd,bootGameHost:()=>yd,default:()=>gd});var js=class{constructor(t){this._state=(t==null?2654435769:t)>>>0}next(){this._state=this._state+1831565813>>>0;let t=this._state;return t=Math.imul(t^t>>>15,t|1),t^=t+Math.imul(t^t>>>7,t|61),((t^t>>>14)>>>0)/4294967296}range(t,e){return t+this.next()*(e-t)}reseed(t){this._state=(t==null?2654435769:t)>>>0}},Ji=class{constructor(t){this._clock=t||Jc(),this._origin=this._clock()}nowMs(){return this._clock()}elapsedMs(){return this._clock()-this._origin}},Ui=class{constructor(t){this._time=t,this._subs=new Map}sourceFor(t){let e=this,s=t==null?null:t;return{on(i,o){if(e._assertType(i),typeof o!="function")throw new Error("[HostDevInputBridge] on \u7684 handler \u5FC5\u987B\u662F\u51FD\u6570");let a=e._subs.get(i)||[],r={handler:o,scope:s};return a.push(r),e._subs.set(i,a),{cancel(){let c=e._subs.get(i);if(!c)return;let l=c.indexOf(r);l>=0&&c.splice(l,1)}}},off(i,o){e._assertType(i);let a=e._subs.get(i);if(!a)return;let r=a.findIndex(c=>c.handler===o&&c.scope===s);r>=0&&a.splice(r,1)}}}_emit(t,e){this._assertType(t);let s=e||{},i={type:t,x:typeof s.x=="number"?s.x:0,y:typeof s.y=="number"?s.y:0,key:typeof s.key=="string"?s.key:"",tMs:this._time.nowMs()},o=this._subs.get(t);if(!o||o.length===0)return;let a=o.slice();for(let r of a)try{r.handler(i)}catch(c){qe("[host-dev input] \u8F93\u5165 handler \u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09type="+t,c)}}disposeScope(t){if(t==null)return 0;let e=0;for(let[s,i]of this._subs){let o=i.filter(a=>a.scope!==t);e+=i.length-o.length,o.length===0?this._subs.delete(s):this._subs.set(s,o)}return e}_subscriptionCount(){let t=0;for(let e of this._subs.values())t+=e.length;return t}_assertType(t){if(!Vi.has(t))throw new Error("[HostDevInputBridge] \u975E\u6CD5\u8F93\u5165\u4E8B\u4EF6\u7C7B\u578B\uFF1A"+String(t)+"\uFF08\u4EC5\u652F\u6301 "+Array.from(Vi).join("/")+"\uFF09")}},Vi=new Set(["pointerdown","pointermove","pointerup","keydown","keyup"]);function Xr(n){let t=n||{},e=new Ji(t.clock),s=new js(t.seed),i=t.seed==null?2654435769:t.seed>>>0,o=new Ui(e),a=typeof t.audioFactory=="function"?t.audioFactory:null,r=null,c=!1,l=typeof t.engineFactory=="function"?t.engineFactory:null,u=null,h=!1,p=new Map,d=0,y=0;function x(){if(r)return r;if(!a)return c||(qi("[host-dev audio] \u672A\u6CE8\u5165 audioFactory\uFF0CgetAudioContext \u8FD4\u56DE null\uFF08P6 \u987B\u5BB9\u9519\u964D\u7EA7\uFF1B\u96C6\u6210\u6BB5\u6CE8\u5165\u771F\u5B9E\u5DE5\u5382\uFF09"),c=!0),null;try{r=a()}catch(C){qe("[host-dev audio] audioFactory \u629B\u9519\uFF0CgetAudioContext \u964D\u7EA7\u8FD4\u56DE null",C),r=null}return r}function v(){if(u)return u;if(!l)return h||(qi("[host-dev engine] \u672A\u6CE8\u5165 engineFactory\uFF0CgetEngine \u8FD4\u56DE null\uFF08\u63D2\u4EF6\u987B\u5BB9\u9519\u964D\u7EA7\uFF1A\u7C92\u5B50\u9000\u53D7\u63A7\u9762\u81EA\u7BA1/\u5408\u6210\u6838\u9000 vendored/\u6570\u5B66\u9000\u5185\u7F6E\uFF1B\u96C6\u6210\u6BB5\u6CE8\u5165\u771F\u5B9E\u80CC\u4E66\uFF09"),h=!0),null;try{u=l()}catch(C){qe("[host-dev engine] engineFactory \u629B\u9519\uFF0CgetEngine \u964D\u7EA7\u8FD4\u56DE null",C),u=null}return u}function w(C,A){return{getContext2d(){return t.context2d==null?null:t.context2d},onFrame(P){let M=d++;return p.set(M,P),{cancel(){p.delete(M)}}},getInput(){return o.sourceFor(C)},getAudioContext(){return x()},getEngine(){return v()},time:e,random:A}}let _=w(null,s),S={context:_,tick(C){y+=1;let A=Array.from(p.values());for(let T of A)try{T(C,y)}catch(P){qe("[host-dev tick] \u5E27\u56DE\u8C03\u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09frame="+y,P)}},frameCount(){return y},inputBridge:o,deriveContextFor(C,A){let T=zc(i,C),P=new js(T);return w(A==null?C:A,P)}};return Object.defineProperty(_,Wi,{value:S,enumerable:!1,writable:!1,configurable:!1}),S}var Wi=Symbol("zaomeng.coreProtocol.contextBundle"),Bs=class{constructor(){this._plugins=new Map,this._initOrder=[],this._initErrors=[],this._phase="idle",this._disposed=!1,this._context=void 0,this._pluginContexts=new Map}register(t){if(!t||typeof t!="object")throw new Error("[PluginRegistry] register \u9700\u8981\u4E00\u4E2A\u63D2\u4EF6\u5BF9\u8C61");if(typeof t.name!="string"||t.name.length===0)throw new Error("[PluginRegistry] \u63D2\u4EF6\u7F3A\u5C11\u5408\u6CD5 name");if(typeof t.version!="string"||t.version.length===0)throw new Error("[PluginRegistry] \u63D2\u4EF6 "+t.name+" \u7F3A\u5C11\u5408\u6CD5 version");if(typeof t.init!="function")throw new Error("[PluginRegistry] \u63D2\u4EF6 "+t.name+" \u7F3A\u5C11 init \u51FD\u6570");if(t.dispose!=null&&typeof t.dispose!="function")throw new Error("[PluginRegistry] \u63D2\u4EF6 "+t.name+" \u7684 dispose \u5FC5\u987B\u662F\u51FD\u6570\u6216\u7701\u7565");if(this._plugins.has(t.name))throw new Error("[PluginRegistry] \u63D2\u4EF6\u91CD\u540D\u62D2\u7EDD\uFF1A"+t.name+" \u5DF2\u6CE8\u518C");return this._plugins.set(t.name,t),this}has(t){return this._plugins.has(t)}get(t){return this._plugins.get(t)}list(){return Array.from(this._plugins.keys())}initAll(){if(this._phase==="initialized")return qi("[PluginRegistry] initAll \u91CD\u590D\u8C03\u7528\uFF0C\u5DF2\u5FFD\u7565\uFF08\u5DF2\u5904\u4E8E initialized\uFF09"),this._initResult();if(this._phase==="disposed")throw new Error("[PluginRegistry] \u5DF2 dispose \u7684\u6CE8\u518C\u5668\u4E0D\u53EF\u518D initAll");if(this._context==null)throw new Error("[PluginRegistry] \u672A\u6CE8\u5165\u53D7\u63A7\u4E0A\u4E0B\u6587\uFF1A\u8BF7\u5728 initAll() \u4E4B\u524D\u8C03\u7528 useContext(context)\u3002\uFF08host-dev \u7528\u6CD5\uFF1Aconst { context } = createHostDevContext(); reg.useContext(context); reg.initAll();\uFF09");for(let[t,e]of this._plugins){let s=this._missingDeps(e);if(s.length>0){let o=new Error("[PluginRegistry] \u63D2\u4EF6 "+t+" \u4F9D\u8D56\u7F3A\u5931\uFF1A"+s.join(", ")+"\uFF08\u672A\u6CE8\u518C\uFF09");this._initErrors.push({name:t,error:o}),qe("[PluginRegistry] \u8DF3\u8FC7 init\uFF08\u4F9D\u8D56\u7F3A\u5931\uFF0C\u5DF2\u9694\u79BB\uFF09\uFF1A"+t,o);continue}let i=this._contextFor(t);try{e.init(i),this._initOrder.push(t)}catch(o){let a=o instanceof Error?o:new Error(String(o));this._initErrors.push({name:t,error:a}),qe("[PluginRegistry] \u63D2\u4EF6 init \u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF0C\u4E0D\u8FDE\u5750\uFF09\uFF1A"+t,a)}}return this._phase="initialized",this._initResult()}_contextFor(t){let e=this._pluginContexts.get(t);if(e)return e;let s=this._context&&this._context[Wi],i;return s&&typeof s.deriveContextFor=="function"?i=s.deriveContextFor(t,t):i=this._context,this._pluginContexts.set(t,i),i}disposeAll(){if(this._disposed)return{disposed:[],errors:[]};let t=[],e=[],s=this._context&&this._context[Wi],i=s&&s.inputBridge;for(let o=this._initOrder.length-1;o>=0;o--){let a=this._initOrder[o],r=this._plugins.get(a);if(r&&typeof r.dispose=="function")try{r.dispose(),t.push(a)}catch(c){let l=c instanceof Error?c:new Error(String(c));e.push({name:a,error:l}),qe("[PluginRegistry] \u63D2\u4EF6 dispose \u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09\uFF1A"+a,l)}if(i&&typeof i.disposeScope=="function")try{i.disposeScope(a)}catch(c){qe("[PluginRegistry] \u56DE\u6536\u63D2\u4EF6\u8F93\u5165\u8BA2\u9605\u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09\uFF1A"+a,c)}}return this._disposed=!0,this._phase="disposed",{disposed:t,errors:e}}useContext(t){if(this._phase!=="idle")throw new Error("[PluginRegistry] useContext \u5FC5\u987B\u5728 initAll() \u4E4B\u524D\u8C03\u7528\uFF08\u5F53\u524D\u9636\u6BB5\uFF1A"+this._phase+"\uFF09\u3002\u8BF7\u5728\u4EFB\u4F55 initAll/disposeAll \u4E4B\u524D\u6CE8\u5165\u53D7\u63A7\u4E0A\u4E0B\u6587\u3002");if(t==null||typeof t!="object")throw new Error("[PluginRegistry] useContext \u9700\u8981\u4E00\u4E2A\u53D7\u63A7\u4E0A\u4E0B\u6587\u5BF9\u8C61\u3002\uFF08host-dev \u7528\u6CD5\uFF1Aconst { context } = createHostDevContext(); reg.useContext(context);\uFF09");return this._context=t,this}_missingDeps(t){return!Array.isArray(t.dependencies)||t.dependencies.length===0?[]:t.dependencies.filter(e=>!this._plugins.has(e))}_initResult(){return{ok:this._initErrors.length===0,initialized:this._initOrder.slice(),errors:this._initErrors.slice()}}};function zc(n,t){let e=2166136261,s=16777619,i=n>>>0;for(let a=0;a<32;a+=8){let r=i>>>a&255;e^=r,e=Math.imul(e,s)>>>0}let o=String(t);for(let a=0;a>>0,e^=r>>>8&255,e=Math.imul(e,s)>>>0}return e>>>0}function Jc(){if(typeof globalThis!="undefined"&&globalThis.performance&&typeof globalThis.performance.now=="function")return()=>globalThis.performance.now();if(typeof process!="undefined"&&process.hrtime&&typeof process.hrtime.bigint=="function"){let n=process.hrtime.bigint();return()=>Number(process.hrtime.bigint()-n)/1e6}return()=>Date.now()}function qe(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function qi(n){typeof console!="undefined"&&typeof console.warn=="function"&&console.warn(n)}var xd=Object.freeze(Array.from(Vi)),Yr="core-protocol-v0";var $r=Object.freeze(["t_boot","t_plugins_ready","t_game_init","t_first_paint","t_input_bound","t_game_start"]),Hi=$r.reduce((n,t,e)=>(n[t]=e,n),Object.create(null)),Uc=new Set($r);function Xi(n){let t=2166136261;for(let e=0;e>>0).toString(16).padStart(8,"0")}var Kr=Xi("runtime-probe::seed::v1");function Ns(n){return n===null||typeof n!="object"?JSON.stringify(n):Array.isArray(n)?"["+n.map(Ns).join(",")+"]":"{"+Object.keys(n).sort().map(e=>JSON.stringify(e)+":"+Ns(n[e])).join(",")+"}"}function Qr(n){let t=Ns(n.extra==null?null:n.extra),e=Ns(Array.isArray(n.pluginSet)?n.pluginSet:[]);return["seq="+n.seq,"anchor="+n.anchor,"tMono="+n.tMono,"buildSha="+(n.buildSha||""),"pluginSet="+e,"extra="+t].join("|")}function Vc(n){return Math.round(n*1e3)/1e3}function Wc(n){if(!Array.isArray(n))return{ok:!1,reason:"records_not_array"};let t=Kr,e=-1;for(let s=0;stypeof C=="string").slice().sort():[],i=typeof t.sink=="function"?t.sink:null,o=t.autoBoot!==!1,a=typeof t.inputAnchorType=="string"?t.inputAnchorType:"pointerdown",r=()=>0,c=!1,l=0,u=Kr,h=[],p=new Set,d=-1,y=null,x=!1,v=!1,w=!1;function _(C,A){let T=null;if(!Uc.has(C))T="unknown_anchor";else{p.has(C)&&(T=T?T+";duplicate_anchor":"duplicate_anchor");let M=Hi[C];MC.time.nowMs(),c=!0,o&&!v&&_("t_boot",{auto:!0}),y=C.getInput().on(a,A=>{x||(x=!0,_("t_input_bound",{firstInput:!0,type:A.type}))}),_("t_input_bound",{stage:"registered",type:a})},dispose(){w||(y&&(y.cancel(),y=null),w=!0)},mark:_,getRecords(){return h.map(C=>({...C}))},toJSONL(){return h.map(C=>JSON.stringify(C)).join(`
-`)},verify(){return Wc(h)}}}function qc(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function ta(n){let t=n.LJS,e=n.engineMath,s=n.engineMode,i=n.recHook||(()=>{});if(s!=="real")return null;let o=e;return{math:{lerp:(r,c,l)=>(i("math.lerp"),o.lerp(r,c,l)),smoothStep:r=>(i("math.smoothStep"),o.smoothStep(r)),easing:Object.fromEntries(Object.keys(o.easing).map(r=>[r,c=>(i("math.easing."+r),o.easing[r](c))]))},particles:{spawnEmitter(r){i("particles.spawnEmitter");let c=t.screenToWorld(t.vec2(r.pos.x,r.pos.y)),l=t.cameraScale,u=r.emitTime!=null?r.emitTime:r.count!=null?1/60:0,h=r.emitRate!=null?r.emitRate:r.count!=null?r.count*60:100,p=(r.speed!=null?r.speed:0)/l/60,d=r.damping!=null?r.damping:1,y=r.colorStart||{r:1,g:1,b:1,a:1},x=r.colorEnd||{r:1,g:1,b:1,a:0},v=t.rgb(y.r,y.g,y.b,y.a),w=t.rgb(x.r,x.g,x.b,x.a),_=new t.ParticleEmitter(c,r.angle!=null?r.angle:0,(r.emitSize!=null?r.emitSize:0)/l,u,h,r.coneAngle!=null?r.coneAngle:Math.PI,void 0,v,v,w,w,r.particleTime!=null?r.particleTime:.5,(r.sizeStart!=null?r.sizeStart:6)/l,(r.sizeEnd!=null?r.sizeEnd:0)/l,p,0,d,1,r.gravityScale!=null?r.gravityScale:0,Math.PI,.1,0,!1,r.additive!=null?r.additive:!1,!0);return{isActive(){return _.isActive()},stop(){_.destroyed||_.destroy(!0)}}}},audio:{synth:{synthSfx:r=>{i("audio.synth.synthSfx");try{return t.zzfxG(...r)}catch(c){return console.error("[host][engine-audio] zzfxG \u5408\u6210\u5F02\u5E38\uFF0C\u8FD4 null\uFF1A"+(c&&c.message?c.message:c)),null}},synthSong:(r,c,l,u)=>{i("audio.synth.synthSong");try{return t.zzfxM(r,c,l,u)}catch(h){return console.error("[host][engine-audio] zzfxM \u5408\u6210\u5F02\u5E38\uFF0C\u8FD4 null\uFF1A"+(h&&h.message?h.message:h)),null}}}}}}function ce(n){return n<0?0:n>1?1:n}function ea(n){let t=n.Ease,e=t.POWER(2),s=t.POWER(3),i=t.OUT(e),o=t.IN_OUT(e),a=t.OUT(s),r=t.IN_OUT(s),c=t.OUT(t.BACK),l=t.OUT(t.ELASTIC);return{lerp:(u,h,p)=>n.lerp(u,h,p),smoothStep:u=>n.smoothStep(u),easing:{linear:u=>t.LINEAR(ce(u)),quadIn:u=>e(ce(u)),quadOut:u=>i(ce(u)),quadInOut:u=>o(ce(u)),cubicIn:u=>s(ce(u)),cubicOut:u=>a(ce(u)),cubicInOut:u=>r(ce(u)),backIn:u=>t.BACK(ce(u)),backOut:u=>c(ce(u)),elasticIn:u=>t.ELASTIC(ce(u)),elasticOut:u=>l(ce(u))}}}var He=2,zs=1/60;async function na(n){let t=n.canvas,e=n.statusEl||null,s=n.engine,i=n.seed>>>0,o=n.mode||"play",a=n.engineMode||"real",r=n.viewport.w,c=n.viewport.h,l=n.factory,u=n.buildFactoryOpts||(()=>{}),h=n.plugins||{},p=n.registerOrder||Object.values(h),d=n.onReady||(()=>{}),y=n.recHook||(()=>{});function x(D){e&&(e.textContent=D)}let v=[];window.addEventListener("error",D=>v.push({type:"error",message:String(D&&D.message||D)})),window.addEventListener("unhandledrejection",D=>v.push({type:"unhandledrejection",message:String(D&&D.reason&&D.reason.message||D&&D.reason||D)}));let w=null,_=!1;function S(){if(!_)return null;if(w)return w;let D=window.AudioContext||window.webkitAudioContext;return D?(w=new D,w):null}let C=0,A=null,T=null,P=null,M=null,pt=[],at={},ct=null;function yt(D,ot){try{P&&P.mark(D,ot)}catch(ee){v.push({type:"mark",message:String(ee&&ee.message||ee)})}}function Nt(){T&&typeof T._refreshChecklist=="function"&&T._refreshChecklist(at)}async function ge(D,ot){A=Xr({context2d:D,seed:i,audioFactory:S,clock:()=>C,engineFactory:()=>ta({LJS:a==="real"?s:null,engineMath:a==="real"?ea(s):null,engineMode:a,recHook:y})});let ee=new Bs;for(let ye of p)ee.register(ye);ee.useContext(A.context),M=ee.initAll(),pt=ee.list().concat(["runtime-probe"]),P=Zr({pluginSet:pt,inputAnchorType:"pointerdown",autoBoot:!0});let Dt=A.deriveContextFor("runtime-probe","runtime-probe");yt("t_boot",{by:"game-host",stage:"pre-init",engineMode:a}),yt("t_plugins_ready",{initialized:M.initialized.length,ok:M.ok});let Ni=u(A.context,{bundle:A,plugins:h,getRealAudioCtx:()=>w});T=l(Ni),await T.init({ctx:A.context,mainContext:D,canvas:ot(),seed:i}),ct=T&&typeof T._forensicsView=="function"?T._forensicsView():null,yt("t_game_init",{hasForensics:!!ct}),ht(),yt("t_first_paint",{frame:A.frameCount()});try{P.init(Dt)}catch(ye){v.push({type:"probe-init",message:String(ye&&ye.message||ye)})}yt("t_game_start",{mode:o,engineMode:a}),Nt(),d(un,{bundle:A,game:T,probe:P,checklist:at,uncaught:v,pluginSet:pt,initRes:M,getGameForensics:()=>ct,mark:yt,stepOneFrame:ht})}let Pt=null;function ht(D){let ot=typeof D=="number"?D:zs;T&&(C+=ot*1e3,T.update(ot),a==="stub"&&Pt&&T.render(Pt),Nt())}function Lt(D){for(let ot=0;ot{}),T&&typeof T._onAudioUnlock=="function"&&T._onAudioUnlock()}let un={seed:i,mode:o,engineMode:a,protocol:Yr,frameCount:()=>A?A.frameCount():0,stepFrames:Lt,startRaf:()=>F(),stopRaf:()=>k(),tap(D,ot){Pe(),A&&(A.inputBridge._emit("pointerdown",{x:D,y:ot}),A.inputBridge._emit("pointerup",{x:D,y:ot}))},do(D){T&&typeof T._handleAction=="function"&&T._handleAction(D)},state:()=>ct?ct.state():{phase:"booting"}};function hn(D){let ot=A.inputBridge;function ee(Dt,Ni){let ye=D.getBoundingClientRect();return{x:(Dt-ye.left)/ye.width*r,y:(Ni-ye.top)/ye.height*c}}D.addEventListener("pointerdown",Dt=>{Pe(),ot._emit("pointerdown",ee(Dt.clientX,Dt.clientY))}),D.addEventListener("pointermove",Dt=>{ot._emit("pointermove",ee(Dt.clientX,Dt.clientY))}),D.addEventListener("pointerup",Dt=>{ot._emit("pointerup",ee(Dt.clientX,Dt.clientY))}),window.addEventListener("keydown",Dt=>{Pe(),ot._emit("keydown",{key:Dt.key})}),window.addEventListener("keyup",Dt=>ot._emit("keyup",{key:Dt.key}))}let ae=0,Le=!1,te=0;function R(D){if(!Le)return;te===0&&(te=D);let ot=(D-te)/1e3;te=D,ot>.05&&(ot=.05),ht(ot),ae=window.requestAnimationFrame(R)}function F(){a==="stub"&&(Le||(Le=!0,te=0,ae=window.requestAnimationFrame(R)))}function k(){Le=!1,ae&&window.cancelAnimationFrame(ae),ae=0}function j(D){D.width=r*He,D.height=c*He,D.style.width=r+"px",D.style.height=c+"px";let ot=D.getContext("2d",{willReadFrequently:!0});return ot.setTransform(He,0,0,He,0,0),ot}async function $(){let D=j(t);return Pt=D,await ge(D,()=>t),hn(t),o==="evidence"?x(`evidence \u5C31\u7EEA seed=${i} \xB7 \u7528 host \u9A71\u52A8\uFF08stepFrames/tap\uFF09`):(x(`seed=${i} \xB7 \u70B9\u5F00\u59CB\uFF08\u9996\u6B21\u70B9\u51FB\u5F00\u58F0\uFF09`),F()),un}let Z=()=>{},Tt=()=>{};function At(){window.__gameHostEngineInitFired=!0}function Ot(){Z()}function Oe(){}function Zn(){Tt()}function dn(){}async function Fs(D){await ge(D,()=>s.mainCanvas),hn(s.mainCanvas),Z=()=>{T&&(C+=zs*1e3,T.update(zs))},Tt=()=>{if(T){D.save(),D.setTransform(He,0,0,He,0,0);try{D.imageSmoothingEnabled=!1}catch{}T.render(D),D.restore()}},s.mainCanvas&&(s.mainCanvas.id="game-engine"),window.__engine={frame(){return s.frame},time(){return s.time},timeReal(){return s.timeReal},paused(){return s.paused},timeScale(){return s.timeScale},snapshot(){return{frame:s.frame,time:s.time,timeReal:s.timeReal,paused:s.paused,timeScale:s.timeScale}}},x(`engine RAF running \xB7 seed=${i} engine=real`)}if(a!=="real")return await $();if(!s){let D="real \u901A\u9053\u672A\u6CE8\u5165\u5F15\u64CE\uFF08opts.engine \u7F3A\u5931\uFF09\uFF1A\u8BF7\u7ECF entry \u5305\u88C5\u5C42\u542F\u52A8\uFF08host \u4E0D\u76F4\u63A5 import \u5F15\u64CE\uFF0CQ4/Option C\uFF09";throw x("ENGINE INJECT MISSING: "+D),new Error(D)}s.setGLEnable(!1),s.setShowSplashScreen(!1),s.setDebugWatermark(!1),s.setCanvasClearColor(s.BLACK),s.setCanvasFixedSize(s.vec2(r*He,c*He));let Dn=document.createElement("div");return Dn.id="engine-root",document.body.appendChild(Dn),await s.engineInit(At,Ot,Oe,Zn,dn,[],Dn).then(()=>Fs(s.mainContext)).catch(D=>{throw window.__gameHostBootError=String(D&&D.message||D),x("ENGINE INIT FAILED: "+window.__gameHostBootError),D}),un}var Yi=class{constructor(t){let e=t||{},s=typeof e.cellSize=="number"&&e.cellSize>0?e.cellSize:64;this._cellSize=s,this._cells=new Map,this._entries=new Map,this._seq=0}get size(){return this._entries.size}_cellRange(t){let e=this._cellSize,s=Math.floor((t.x-t.hw)/e),i=Math.floor((t.x+t.hw)/e),o=Math.floor((t.y-t.hh)/e),a=Math.floor((t.y+t.hh)/e);return{cx0:s,cy0:o,cx1:i,cy1:a}}insert(t,e){this._entries.has(t)&&this.remove(t);let{cx0:s,cy0:i,cx1:o,cy1:a}=this._cellRange(e),r=[];for(let l=i;l<=a;l++)for(let u=s;u<=o;u++){let h=u+","+l,p=this._cells.get(h);p||(p=new Set,this._cells.set(h,p)),p.add(t),r.push(h)}let c={x:e.x,y:e.y,hw:e.hw,hh:e.hh};this._entries.set(t,{id:t,box:c,seq:this._seq++,cells:r})}remove(t){let e=this._entries.get(t);if(!e)return!1;for(let s of e.cells){let i=this._cells.get(s);i&&(i.delete(t),i.size===0&&this._cells.delete(s))}return this._entries.delete(t),!0}query(t){let{cx0:e,cy0:s,cx1:i,cy1:o}=this._cellRange(t),a=new Set;for(let r=s;r<=o;r++)for(let c=e;c<=i;c++){let l=this._cells.get(c+","+r);if(l)for(let u of l)a.add(u)}return this._collect(a)}queryPoint(t,e){let s=this._cellSize,i=Math.floor(t/s),o=Math.floor(e/s),a=this._cells.get(i+","+o);return a?this._collect(new Set(a)):[]}clear(){this._cells.clear(),this._entries.clear(),this._seq=0}_collect(t){let e=[];for(let s of t){let i=this._entries.get(s);i&&e.push(i)}return e.sort((s,i)=>s.seq-i.seq),e.map(s=>({id:s.id,box:s.box}))}};function sa(n){let t=n||{},e=new Yi({cellSize:t.cellSize}),s=!1;return{name:"collision",version:"1.0.0",dependencies:[],spatial:e,init(o){},dispose(){s||(e.clear(),s=!0)}}}function ia(n){let t=!1;return{name:"physics-lite",version:"1.0.0",dependencies:[],init(s){},dispose(){t||(t=!0)}}}var Hc=["pointerdown","pointermove","pointerup","keydown","keyup"];function zt(n){return n<0?0:n>1?1:n}var Xc=n=>(n=zt(n),n*n),Yc=n=>(n=zt(n),1-(1-n)*(1-n)),$c=n=>(n=zt(n),n<.5?2*n*n:1-Math.pow(-2*n+2,2)/2),Kc=n=>(n=zt(n),n*n*n),Qc=n=>{n=zt(n);let t=1-n;return 1-t*t*t},Zc=n=>(n=zt(n),n<.5?4*n*n*n:1-Math.pow(-2*n+2,3)/2),aa=2*Math.PI/3,oa=2*Math.PI/4.5,tl=n=>(n=zt(n),n===0?0:n===1?1:-Math.pow(2,10*n-10)*Math.sin((n*10-10.75)*aa)),el=n=>(n=zt(n),n===0?0:n===1?1:Math.pow(2,-10*n)*Math.sin((n*10-.75)*aa)+1),nl=n=>(n=zt(n),n===0?0:n===1?1:n<.5?-(Math.pow(2,20*n-10)*Math.sin((20*n-11.125)*oa))/2:Math.pow(2,-20*n+10)*Math.sin((20*n-11.125)*oa)/2+1),Us=1.70158,Js=Us*1.525,ca=Us+1,sl=n=>(n=zt(n),ca*n*n*n-Us*n*n),il=n=>{n=zt(n);let t=n-1;return 1+ca*t*t*t+Us*t*t},ol=n=>(n=zt(n),n<.5?Math.pow(2*n,2)*((Js+1)*2*n-Js)/2:(Math.pow(2*n-2,2)*((Js+1)*(n*2-2)+Js)+2)/2),rl=n=>zt(n),ra=Object.freeze({linear:rl,quadIn:Xc,quadOut:Yc,quadInOut:$c,cubicIn:Kc,cubicOut:Qc,cubicInOut:Zc,elasticIn:tl,elasticOut:el,elasticInOut:nl,backIn:sl,backOut:il,backInOut:ol});var al=["linear","quadIn","quadOut","quadInOut","cubicIn","cubicOut","cubicInOut","elasticIn","elasticOut","elasticInOut","backIn","backOut","backInOut"];function cl(n){let t=n&&n.easing;if(!t)return ra;let e=i=>typeof t[i]=="function"?o=>t[i](zt(o)):ra[i],s={};for(let i of al)s[i]=e(i);return Object.freeze(s)}var $i=class{constructor(t,e,s){let i=s||{};this._time=e,this._windowMs=typeof i.windowMs=="number"&&i.windowMs>0?i.windowMs:120;let o=Array.isArray(i.types)&&i.types.length>0?i.types:Hc;this._records=new Map,this._subs=[],this._disposed=!1;for(let a of o){this._records.set(a,null);let r=t.on(a,c=>{this._records.set(a,c.tMs)});this._subs.push(r)}}consume(t,e){let s=typeof e=="number"?e:this._time.nowMs(),i=this._records.get(t);return i==null?!1:s-i<=this._windowMs?(this._records.set(t,null),!0):(this._records.set(t,null),!1)}peek(t,e){let s=typeof e=="number"?e:this._time.nowMs(),i=this._records.get(t);return i==null?!1:s-i<=this._windowMs}clear(){for(let t of this._records.keys())this._records.set(t,null)}dispose(){if(!this._disposed){for(let t of this._subs)try{t.cancel()}catch(e){}this._subs=[],this._disposed=!0}}};function la(n){let t=n||{},e=null,s=null,i=!1;return{name:"gamefeel",version:"1.0.0",dependencies:[],get inputBuffer(){return e},get easing(){return cl(s)},init(a){let r=a.getInput();e=new $i(r,a.time,{windowMs:t.inputBufferMs,types:t.inputTypes});let c=a.getEngine();s=c?c.math:null},dispose(){i||(e&&(e.dispose(),e=null),s=null,i=!0)}}}function Vs(n,t){let e=t<0?0:t>1?1:t;switch(n&&n.kind){case"constant":return n.value;case"linear":return n.from+(n.to-n.from)*e;case"easeInOut":{let s=e*e*(3-2*e);return n.from+(n.to-n.from)*s}case"decay":{let s=n.power==null?2:n.power,i=Math.pow(1-e,s);return n.to+(n.from-n.to)*i}default:return 0}}var ll=Object.freeze({burst:Object.freeze({mode:"burst",count:24,angle:0,spread:Math.PI,speedMin:80,speedMax:160,lifeMin:.4,lifeMax:.8,gravity:0,drag:0,sizeCurve:{kind:"decay",from:6,to:0,power:1.5},alphaCurve:{kind:"linear",from:1,to:0}}),trail:Object.freeze({mode:"continuous",rate:60,angle:Math.PI,spread:.25,speedMin:20,speedMax:50,lifeMin:.2,lifeMax:.5,gravity:0,drag:1.5,sizeCurve:{kind:"easeInOut",from:4,to:0},alphaCurve:{kind:"decay",from:.8,to:0,power:2}}),drift:Object.freeze({mode:"continuous",rate:12,angle:Math.PI/2,spread:.6,speedMin:10,speedMax:30,lifeMin:1.5,lifeMax:3,gravity:8,drag:.5,sizeCurve:{kind:"constant",value:3},alphaCurve:{kind:"decay",from:.7,to:0,power:1}})});function ul(n){let t=ll[n];return t?Ki(t):null}function Ki(n){let t={};for(let e of Object.keys(n)){let s=n[e];t[e]=s&&typeof s=="object"?Ki(s):s}return t}function hl(n,t,e){let s=n.mode==="continuous";return{pos:{x:t,y:e},angle:n.angle,coneAngle:n.spread,emitSize:0,emitTime:s?0:1/60,emitRate:s?n.rate||0:void 0,count:s?void 0:n.count||0,particleTime:(n.lifeMin+n.lifeMax)/2,speed:(n.speedMin+n.speedMax)/2,gravityScale:n.gravity||0,damping:n.drag!=null?1-n.drag/60:1,sizeStart:Vs(n.sizeCurve,0),sizeEnd:Vs(n.sizeCurve,1),colorStart:{r:1,g:1,b:1,a:Vs(n.alphaCurve,0)},colorEnd:{r:1,g:1,b:1,a:Vs(n.alphaCurve,1)},additive:!1}}function ua(n){let t=n||{},e=null,s=null,i=null,o=new Map,a=0,r={isActive(){return!1},stop(){}},c=0,l=1,u=0,h=0,p=0,d={x:0,y:0,remain:0,dur:0,amplitude:0,frequency:0,_phase:0},y={alpha:0,remain:0,dur:0,peak:0},x={scale:1,remain:0,dur:0,amplitude:0,frequency:0},v=!1;function w(A){if(u>0)if(u-=A,u<=0)u=0,l=1;else{let T=h>0?1-u/h:1;l=p+(1-p)*T}if(d.remain>0)if(d.remain-=A,d.remain<=0)d.remain=0,d.x=0,d.y=0;else{let T=d.remain/d.dur,P=d.amplitude*T;d._phase+=d.frequency*A*Math.PI*2,d.x=Math.sin(d._phase)*P,d.y=Math.cos(d._phase*1.3)*P}if(y.remain>0&&(y.remain-=A,y.remain<=0?(y.remain=0,y.alpha=0):y.alpha=y.peak*(y.remain/y.dur)),x.remain>0)if(x.remain-=A,x.remain<=0)x.remain=0,x.scale=1;else{let T=x.remain/x.dur,P=(1-T)*x.frequency*Math.PI*2;x.scale=1+Math.sin(P)*x.amplitude*T}}function _(A){c+=1,w(A)}function S(A){let T=A!==void 0?A:e?e.getContext2d():null;if(T&&y.alpha>0){T.globalAlpha=y.alpha,T.fillStyle="#ffffff";let P=T.canvas?T.canvas.width:0,M=T.canvas?T.canvas.height:0;T.fillRect(0,0,P,M),T.globalAlpha=1}}return{name:"particles-juice",version:"1.0.0",dependencies:[],init(A){var T;e=A,i=((T=A.getEngine())==null?void 0:T.particles)||null,typeof t.seed=="number"&&A.random.reseed(t.seed),t.autoStep!==!1&&(s=A.onFrame(P=>{_(P)}))},dispose(){v||(s&&(s.cancel(),s=null),o.forEach(A=>{try{A.stop()}catch{}}),o.clear(),l=1,u=0,d.remain=0,d.x=0,d.y=0,y.remain=0,y.alpha=0,x.remain=0,x.scale=1,v=!0)},spawnEmitter(A,T,P,M){let pt=typeof A=="string"?ul(A):Ki(A);if(!pt)return-1;M&&(pt=Object.assign(pt,M));let at=a++;if(!i)return o.set(at,r),at;let ct=i.spawnEmitter(hl(pt,T,P));return o.set(at,ct),at},stopEmitter(A){let T=o.get(A);if(T)try{T.stop()}catch{}},step(A){_(A)},render(A){S(A)},particleCount(){return 0},emitterCount(){let A=0;for(let T of o.values())T.isActive()&&(A+=1);return A},hitStop(A,T){h=Math.max(0,A),u=h,p=T==null?0:Math.max(0,Math.min(1,T)),l=h>0?p:1},getTimeScale(){return l},shakeScreen(A,T,P){d.dur=Math.max(0,A),d.remain=d.dur,d.amplitude=Math.max(0,T),d.frequency=P==null?30:P,d._phase=0,d.x=0,d.y=0},getShakeOffset(){return{x:d.x,y:d.y}},flashScreen(A,T){y.dur=Math.max(0,A),y.remain=y.dur,y.peak=T==null?.8:Math.max(0,Math.min(1,T)),y.alpha=y.dur>0?y.peak:0},getFlashAlpha(){return y.alpha},pulseScale(A,T,P){x.dur=Math.max(0,A),x.remain=x.dur,x.amplitude=T==null?.2:T,x.frequency=P==null?4:P,x.scale=1},getPulseScale(){return x.scale},juiceSnapshot(){return{timeScale:l,shake:{x:d.x,y:d.y},flashAlpha:y.alpha,pulseScale:x.scale}},probe(){return{particles:0,emitters:o.size,dropped:0,steps:c,disposed:v}}}}function ha(n){let t=gt(n.r)/255,e=gt(n.g)/255,s=gt(n.b)/255,i=Math.max(t,e,s),o=Math.min(t,e,s),a=(i+o)/2,r=0,c=0,l=i-o;return l>1e-12&&(c=a>.5?l/(2-i-o):l/(i+o),i===t?r=(e-s)/l%6:i===e?r=(s-t)/l+2:r=(t-e)/l+4,r*=60,r<0&&(r+=360)),{h:r,s:c,l:a}}function da(n){let t=(n.h%360+360)%360,e=Xe(n.s),s=Xe(n.l);if(e<1e-12){let r=Math.round(s*255);return{r,g:r,b:r}}let i=s<.5?s*(1+e):s+e-s*e,o=2*s-i,a=t/360;return{r:Math.round(Qi(o,i,a+1/3)*255),g:Math.round(Qi(o,i,a)*255),b:Math.round(Qi(o,i,a-1/3)*255)}}function Qi(n,t,e){let s=e;return s<0&&(s+=1),s>1&&(s-=1),s<1/6?n+(t-n)*6*s:s<1/2?t:s<2/3?n+(t-n)*(2/3-s)*6:n}function gt(n){return n<0?0:n>255?255:n}function Xe(n){return n<0?0:n>1?1:n}function dl(n,t){let e=pl(n.from,t);if(e>=0&&e({r:gt(r.r),g:gt(r.g),b:gt(r.b)})),to:o}}function Zi(n,t,e){return n+(t-n)*e}function ml(n,t){let e=ha(n),s=e.h+(t.hue||0),i=Xe(e.s*(t.sat==null?1:t.sat)),o=Xe(e.l*(t.light==null?1:t.light));return da({h:s,s:i,l:o})}var bl=Object.freeze([Object.freeze([0,8,2,10]),Object.freeze([12,4,14,6]),Object.freeze([3,11,1,9]),Object.freeze([15,7,13,5])]);function fa(n){let t=n||{},e=null,s=!1,i={vignette:{enabled:to(t.vignette&&t.vignette.enabled,!1),strength:eo(t.vignette&&t.vignette.strength,.5)},dither:{enabled:to(t.dither&&t.dither.enabled,!1),strength:eo(t.dither&&t.dither.strength,.5)},scanline:{enabled:to(t.scanline&&t.scanline.enabled,!1),strength:eo(t.scanline&&t.scanline.strength,.5)}};function o(r){let c=r!==void 0?r:e?e.getContext2d():null;if(!c)return;let l=c.canvas?c.canvas.width:0,u=c.canvas?c.canvas.height:0;if(i.vignette.enabled&&i.vignette.strength>0&&l>0&&u>0){let h=c.createRadialGradient(l/2,u/2,Math.min(l,u)*.25,l/2,u/2,Math.max(l,u)*.75);h.addColorStop(0,"rgba(0,0,0,0)"),h.addColorStop(1,"rgba(0,0,0,"+i.vignette.strength.toFixed(3)+")"),c.fillStyle=h,c.fillRect(0,0,l,u)}if(i.scanline.enabled&&i.scanline.strength>0&&l>0&&u>0){c.fillStyle="rgba(0,0,0,"+(i.scanline.strength*.5).toFixed(3)+")";for(let h=0;h0&&l>0&&u>0&&typeof c.getImageData=="function"&&typeof c.putImageData=="function"){let h=c.getImageData(0,0,l,u);xl(h,i.dither.strength),c.putImageData(h,0,0)}}return{name:"palette-post",version:"1.0.0",dependencies:[],init(r){e=r},dispose(){s||(e=null,s=!0)},applyPaletteMap(r,c){return dl(r,c)},applyPaletteMapToBuffer(r,c){return fl(r,c)},lerpPaletteMap(r,c,l){return yl(r,c,l)},shiftHsl(r,c){return ml(r,c)},rgbToHsl(r){return ha(r)},hslToRgb(r){return da(r)},setPost(r){if(r)for(let c of["vignette","dither","scanline"])r[c]&&(typeof r[c].enabled=="boolean"&&(i[c].enabled=r[c].enabled),typeof r[c].strength=="number"&&(i[c].strength=Xe(r[c].strength)))},getPost(){return{vignette:{enabled:i.vignette.enabled,strength:i.vignette.strength},dither:{enabled:i.dither.enabled,strength:i.dither.strength},scanline:{enabled:i.scanline.enabled,strength:i.scanline.strength}}},renderPost(r){o(r)},probe(){return{disposed:s,post:this.getPost()}}}}function xl(n,t){let e=Xe(t);if(e<=0)return n;let{data:s,width:i}=n,a=255/(Math.max(2,Math.round(16-e*14))-1);for(let r=0;r+3>2)%i,l=Math.floor((r>>2)/i),u=(bl[l&3][c&3]/16-.5)*a;for(let h=0;h<3;h++){let p=s[r+h]+u,d=Math.round(p/a)*a;s[r+h]=d<0?0:d>255?255:d}}return n}function to(n,t){return typeof n=="boolean"?n:t}function eo(n,t){return typeof n=="number"?Xe(n):t}var so=Object.freeze({blip:Object.freeze({name:"blip",params:Object.freeze([.6,0,880,0,.03,.06,1,1.5])}),thud:Object.freeze({name:"thud",params:Object.freeze([.8,0,90,0,.04,.18,0,1,0,0,0,0,0,4])}),chime:Object.freeze({name:"chime",params:Object.freeze([.5,0,660,.02,.12,.3,1,2])})}),pa=Object.keys(so);function vl(n){let t=[];return n==null||typeof n!="object"?{ok:!1,errors:["song \u5FC5\u987B\u662F\u5BF9\u8C61"]}:(!Array.isArray(n.instruments)||n.instruments.length===0?t.push("instruments \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4"):n.instruments.forEach((e,s)=>{(!Array.isArray(e)||e.some(i=>typeof i!="number"||!Number.isFinite(i)))&&t.push(`instruments[${s}] \u5FC5\u987B\u662F\u6709\u9650\u6570\u5B57\u6570\u7EC4\uFF08ZzFX \u53C2\u6570\u5305\uFF09`)}),!Array.isArray(n.patterns)||n.patterns.length===0?t.push("patterns \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4"):n.patterns.forEach((e,s)=>{if(!Array.isArray(e)||e.length===0){t.push(`patterns[${s}] \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4\uFF08\u81F3\u5C11\u4E00\u4E2A\u58F0\u90E8\u901A\u9053\uFF09`);return}e.forEach((i,o)=>{if(!Array.isArray(i)||i.length<2){t.push(`patterns[${s}][${o}] \u901A\u9053\u81F3\u5C11\u542B [\u4E50\u5668\u7D22\u5F15, \u58F0\u50CF]`);return}if(i.some(c=>typeof c!="number"||!Number.isFinite(c))){t.push(`patterns[${s}][${o}] \u901A\u9053\u5FC5\u987B\u5168\u4E3A\u6709\u9650\u6570\u5B57`);return}let a=i[0]|0;Array.isArray(n.instruments)&&(a<0||a>=n.instruments.length)&&t.push(`patterns[${s}][${o}] \u4E50\u5668\u7D22\u5F15 ${a} \u8D8A\u754C\uFF08instruments \u957F\u5EA6 ${n.instruments.length}\uFF09`);let r=i[1];(r<-1||r>1)&&t.push(`patterns[${s}][${o}] \u58F0\u50CF ${r} \u8D8A\u754C\uFF08\u5E94 -1..+1\uFF09`)})}),!Array.isArray(n.sequence)||n.sequence.length===0?t.push("sequence \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4"):n.sequence.forEach((e,s)=>{if(typeof e!="number"||!Number.isInteger(e)){t.push(`sequence[${s}] \u5FC5\u987B\u662F\u6574\u6570 pattern \u7D22\u5F15`);return}Array.isArray(n.patterns)&&(e<0||e>=n.patterns.length)&&t.push(`sequence[${s}] \u7D22\u5F15 ${e} \u8D8A\u754C\uFF08patterns \u957F\u5EA6 ${n.patterns.length}\uFF09`)}),n.bpm!=null&&(typeof n.bpm!="number"||!(n.bpm>0))&&t.push("bpm \u5FC5\u987B\u662F\u6B63\u6570"),{ok:t.length===0,errors:t})}function me(n){return typeof n!="number"||Number.isNaN(n)||n<0?0:n>1?1:n}function Sl(n,t){switch(n){case"ease-in":return t*t;case"ease-out":return Math.sqrt(t);case"constant":return 1;default:return t}}function ga(n,t){let e=me(t);return n==null||!Array.isArray(n.voices)?[]:n.voices.map(s=>{let i=String(s&&s.id!=null?s.id:""),o=Array.isArray(s&&s.channelIndices)?s.channelIndices.slice():[],a=typeof s.minIntensity=="number"?me(s.minIntensity):0,r=typeof s.maxIntensity=="number"?me(s.maxIntensity):1,c=typeof s.volumeCurve=="string"?s.volumeCurve:"linear",l=typeof s.baseVolume=="number"?me(s.baseVolume):1;if(er)return{id:i,on:!1,volume:0,channelIndices:o};let u=r-a,h=u<=0?1:(e-a)/u,p=me(Sl(c,h)*l);return{id:i,on:!0,volume:p,channelIndices:o}})}function ya(n,t,e,s){try{let i=t[0]||[],o=t[1]||i,a=Math.max(i.length,o.length);if(a===0)return null;let c=n.createBuffer(2,a,44100);c.getChannelData(0).set(i),c.getChannelData(1).set(o.length?o:i);let l=n.createBufferSource();l.buffer=c,l.loop=!!s;let u=n.createGain();return u.gain.value=me(e*.3),l.connect(u),u.connect(n.destination),l.start(),{stop(){try{l.stop()}catch(h){}try{l.disconnect(),u.disconnect()}catch(h){}}}}catch(i){return io("[audio-music] \u53D7\u63A7\u97F3\u9891\u64AD\u653E\u5F02\u5E38\uFF0C\u964D\u7EA7\u4E3A\u9759\u9ED8",i),null}}function ma(n){let t=n||{},e=typeof t.masterVolume=="number"?me(t.masterVolume):1,s=()=>null,i=null,o=null,a={voices:[]},r=1,c=null,l=!1,u=0,h=!1,p=!1;function d(){let S=s();return S==null?(u+=1,h||(no("[audio-music] \u65E0\u53D7\u63A7\u97F3\u9891\u4E0A\u4E0B\u6587\uFF08getAudioContext \u8FD4\u56DE null\uFF09\uFF0C\u5168\u90E8\u53D1\u58F0\u9759\u9ED8 no-op\uFF08\u8BC4\u4F30\u73AF\u5883\u65E0\u58F0\u5361\u65F6\u7684\u5BB9\u9519\u964D\u7EA7\uFF09"),h=!0),null):S}function y(){if(!o||!i)return null;try{let S=typeof o.bpm=="number"&&o.bpm>0?o.bpm:125;return i.synthSong(o.instruments,o.patterns,o.sequence,S)}catch(S){return io("[audio-music] \u66F2\u8C31\u6E32\u67D3\u5F02\u5E38\uFF0C\u964D\u7EA7\u4E3A\u9759\u9ED8",S),null}}function x(){let S=ga(a,r);if(S.length===0)return 1;let C=0;for(let A of S)A.on&&(C=Math.max(C,A.volume));return C}function v(S,C){typeof C=="number"&&(r=me(C));let A=d();if(A==null||!o)return;w();let T=y();if(!T)return;let P=me(e*x());c=ya(A,T,P,S),l=!!S&&c!=null}function w(){c&&(c.stop(),c=null),l=!1}return{name:"audio-music",version:"1.0.0",dependencies:[],init(S){s=()=>S.getAudioContext();let C=S.getEngine&&S.getEngine();i=C?C.audio.synth:null},dispose(){p||(w(),p=!0)},loadSong(S){let C=vl(S);return C.ok?o={instruments:S.instruments,patterns:S.patterns,sequence:S.sequence,bpm:typeof S.bpm=="number"?S.bpm:125}:no("[audio-music] \u66F2\u8C31\u6821\u9A8C\u5931\u8D25\uFF0C\u672A\u8F7D\u5165\uFF1A"+C.errors.join("\uFF1B")),C},play(S){v(!1,S)},stop(){w()},loop(S){v(!0,S)},setIntensityLayering(S){a=S&&Array.isArray(S.voices)?{voices:S.voices}:{voices:[]}},setIntensity(S){r=me(S)},resolveVoices(S){return ga(a,S)},playSfx(S){let C=so[S];if(!C){no("[audio-music] \u672A\u77E5\u97F3\u6548\u9884\u8BBE\uFF1A"+String(S));return}let A=d();if(A!=null)try{let T=i?i.synthSfx(C.params):null;if(!T)return;ya(A,[T,T],e,!1)}catch(T){io("[audio-music] \u97F3\u6548\u64AD\u653E\u5F02\u5E38\uFF0C\u964D\u7EA7\u4E3A\u9759\u9ED8 name="+S,T)}},getPreset(S){return so[S]},listPresets(){return pa.slice()},probe(){return{hasAudio:s()!=null,hasSong:o!=null,intensity:r,voiceCount:a.voices.length,looping:l,silentNoops:u,presetCount:pa.length}}}}function io(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function no(n){typeof console!="undefined"&&typeof console.warn=="function"&&console.warn(n)}var wl="zaomeng.save";function Tl(n){if(typeof TextEncoder!="undefined")return new TextEncoder().encode(n).length;if(typeof Buffer!="undefined"&&typeof Buffer.byteLength=="function")return Buffer.byteLength(n,"utf8");let t=0;for(let e=0;e=55296&&s<=56319?(t+=4,e++):t+=3}return t}function ro(){let n=new Map;return{getItem(t){return n.has(t)?n.get(t):null},setItem(t,e){n.set(t,e)},removeItem(t){n.delete(t)},keys(){return Array.from(n.keys())}}}function ba(){if(typeof localStorage=="undefined")throw new Error("[save-progress] createLocalStorageAdapter \u9700\u8981\u5168\u5C40 localStorage\uFF08\u4EC5\u6D4F\u89C8\u5668\u96C6\u6210\u6BB5\u53EF\u7528\uFF09\u3002node/host-dev \u8BF7\u7528\u7F3A\u7701\u5185\u5B58 adapter \u6216 createMemoryAdapter()\u3002");return{getItem(n){return localStorage.getItem(n)},setItem(n,t){localStorage.setItem(n,t)},removeItem(n){localStorage.removeItem(n)},keys(){let n=[];for(let t=0;t0?t.namespace:wl;if(e.indexOf(":")>=0)throw new Error('[save-progress] namespace \u4E0D\u5F97\u542B\u5206\u9694\u7B26 ":"\uFF08\u5F53\u524D="'+e+'"\uFF09');let s=typeof t.maxValueBytes=="number"&&t.maxValueBytes>0?Math.floor(t.maxValueBytes):32768,i=!Al(t.adapter),o=i?ro():t.adapter,a=e+":",r=0,c=0,l=!1;function u(d){return typeof d!="string"||d.length===0?a+String(d):a+d}function h(){try{let d=o.keys();return Array.isArray(d)?d.filter(y=>typeof y=="string"&&y.indexOf(a)===0):[]}catch(d){return ts("[save-progress] adapter.keys() \u5F02\u5E38\uFF0C\u964D\u7EA7\u8FD4\u56DE\u7A7A\u96C6",d),[]}}return{name:"save-progress",version:"1.0.0",dependencies:[],init(d){h()},dispose(){},get(d,y){if(!oo(d))return y;let x;try{x=o.getItem(u(d))}catch(v){return ts("[save-progress] adapter.getItem \u5F02\u5E38\uFF0C\u8FD4\u56DE\u9ED8\u8BA4\u503C key="+d,v),y}if(x==null)return y;try{return JSON.parse(x)}catch{return r+=1,l||(es("[save-progress] \u68C0\u6D4B\u5230\u635F\u574F\u5B58\u6863\uFF08\u975E\u6CD5 JSON\uFF09\uFF0C\u5DF2\u5BB9\u9519\u56DE\u9000\u9ED8\u8BA4\u503C key="+d),l=!0),y}},set(d,y){if(!oo(d))return es("[save-progress] set \u6536\u5230\u975E\u6CD5 key\uFF0C\u62D2\u7EDD\u5199\u5165\uFF1A"+String(d)),!1;let x;try{x=JSON.stringify(y)}catch{return c+=1,es("[save-progress] \u503C\u4E0D\u53EF JSON \u5E8F\u5217\u5316\uFF08\u5FAA\u73AF\u5F15\u7528?\uFF09\uFF0C\u62D2\u7EDD\u5199\u5165 key="+d),!1}if(x===void 0)return c+=1,es("[save-progress] \u503C\u5E8F\u5217\u5316\u4E3A undefined\uFF08\u5982\u7EAF undefined/\u51FD\u6570\uFF09\uFF0C\u62D2\u7EDD\u5199\u5165 key="+d),!1;let v=Tl(x);if(v>s)return c+=1,es("[save-progress] \u503C\u8D85\u5B57\u8282\u4E0A\u9650\u62D2\u7EDD\u5199\u5165 key="+d+"\uFF08"+v+" > "+s+" bytes\uFF09"),!1;try{return o.setItem(u(d),x),!0}catch(w){return c+=1,ts("[save-progress] adapter.setItem \u5F02\u5E38\uFF0C\u5199\u5165\u5931\u8D25 key="+d,w),!1}},remove(d){if(oo(d))try{o.removeItem(u(d))}catch(y){ts("[save-progress] adapter.removeItem \u5F02\u5E38\uFF08\u5DF2\u5FFD\u7565\uFF09key="+d,y)}},clear(){let d=h(),y=0;for(let x of d)try{o.removeItem(x),y+=1}catch(v){ts("[save-progress] clear \u65F6 removeItem \u5F02\u5E38\uFF08\u5DF2\u8DF3\u8FC7\uFF09fullKey="+x,v)}return y},probe(){return{namespace:e,maxValueBytes:s,usingMemoryAdapter:i,size:h().length,corruptRecoveries:r,rejectedWrites:c}}}}function oo(n){return typeof n=="string"&&n.length>0}function Al(n){return!!n&&typeof n.getItem=="function"&&typeof n.setItem=="function"&&typeof n.removeItem=="function"&&typeof n.keys=="function"}function ts(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function es(n){typeof console!="undefined"&&typeof console.warn=="function"&&console.warn(n)}var El={w:390,h:844};function va(n){let t=((n&&n.seed)!=null?n.seed:0)>>>0,e=sa({cellSize:96}),s=ia(),i=la({inputBufferMs:260,inputTypes:["pointerdown"]}),o=ua({seed:t,maxParticles:600}),a=fa({vignette:{enabled:!0,strength:.22}}),r=ma({masterVolume:.8}),c;try{c=ba()}catch(p){console.warn("[generic] localStorage \u4E0D\u53EF\u7528\uFF0C\u5B58\u6863\u9000\u5185\u5B58 adapter\uFF1A"+(p&&p.message)),c=ro()}let l=xa({namespace:"zaomeng-generic",adapter:c});return{plugins:{collision:e,physics:s,gamefeel:i,juice:o,palettePost:a,audioMusic:r,save:l},registerOrder:[e,s,i,o,a,l,r],viewport:El,buildFactoryOpts:(p,d)=>({runtime:{plugins:d.plugins,bundle:d.bundle,getRealAudioCtx:d.getRealAudioCtx}})}}function ns(n){let t=n||{},e=null,s=[],i="booting",o=null,a=0,r={x:0,y:0,vx:0,vy:0,angle:0,radius:15},c=[],l=[],u=0,h={},p=200,d=600,y=2e3,x=.99,v=15,w=30,_=15,S=40,C=80,A=5,T=200,P=3;function M(R){R.x<0?R.x+=390:R.x>390&&(R.x-=390),R.y<0?R.y+=844:R.y>844&&(R.y-=844)}function pt(R,F,k,j){let $=F.x-R.x,Z=F.y-R.y,Tt=R.x-k.x,At=R.y-k.y,Ot=$*$+Z*Z,Oe=2*(Tt*$+At*Z),Zn=Tt*Tt+At*At-j*j,dn=Oe*Oe-4*Ot*Zn;if(dn<0)return!1;dn=Math.sqrt(dn);let Fs=(-Oe-dn)/(2*Ot),Dn=(-Oe+dn)/(2*Ot);return Fs>=0&&Fs<=1||Dn>=0&&Dn<=1}function at(R,F,k,j){let $=R-k,Z=F-j;return Math.sqrt($*$+Z*Z)}function ct(R,F,k,j,$){return{x:R,y:F,vx:j,vy:$,radius:k,isBig:k>=w}}function yt(){c=[];let R=e.random;for(let F=0;F{Z.key&&(h[Z.key]=!0)});s.push(k);let j=F.on("keyup",Z=>{Z.key&&(h[Z.key]=!1)});s.push(j);let $=F.on("pointerdown",()=>{i==="gameover"&&Pe()});s.push($),Lt(),i="playing",o=null}function hn(R){if(i==="gameover")return;let F=e.time.nowMs();h.ArrowLeft&&(r.angle-=P*R),h.ArrowRight&&(r.angle+=P*R),h.ArrowUp&&(r.vx+=Math.cos(r.angle)*T*R,r.vy+=Math.sin(r.angle)*T*R,ge(r.x-Math.cos(r.angle)*20,r.y-Math.sin(r.angle)*20,{r:1,g:.8,b:.2,a:1},{r:1,g:.4,b:0,a:0},5)),h.Space&&ht(),r.vx*=x,r.vy*=x,r.x+=r.vx*R,r.y+=r.vy*R,M(r);for(let k of c)k.x+=k.vx*R,k.y+=k.vy*R,M(k);for(let k=l.length-1;k>=0;k--){let j=l[k],$=j.x,Z=j.y;if(j.x+=j.vx*R,j.y+=j.vy*R,F-j.born>y){l.splice(k,1);continue}if(j.x<0||j.x>390||j.y<0||j.y>844){l.splice(k,1);continue}let Tt=!1;for(let At=c.length-1;At>=0;At--){let Ot=c[At];if(pt({x:$,y:Z},{x:j.x,y:j.y},{x:Ot.x,y:Ot.y},Ot.radius)){Tt=!0,a+=1,ge(j.x,j.y,{r:1,g:.9,b:.5,a:1},{r:1,g:.3,b:0,a:0},30),Pt([1,.1,880,,,.2,,.4]),Ot.isBig&&Nt(Ot),c.splice(At,1);break}}Tt&&l.splice(k,1)}for(let k of c){let j=r.x-k.x,$=r.y-k.y;if(j*j+$*$<(r.radius+k.radius)*(r.radius+k.radius)){i="gameover",o="lose",ge(r.x,r.y,{r:1,g:.2,b:.2,a:1},{r:.5,g:0,b:0,a:0},40),Pt([1,.2,100,,,.5,,1.5]);return}}c.length===0&&(i="gameover",o="win")}function ae(R){R.fillStyle="#0a0a1a",R.fillRect(0,0,390,844);for(let F of c)R.fillStyle=F.isBig?"#8b5e3c":"#a0744a",R.beginPath(),R.arc(F.x,F.y,F.radius,0,Math.PI*2),R.fill(),R.strokeStyle="#d4a76a",R.lineWidth=2,R.stroke();for(let F of l)R.fillStyle="#ffff00",R.beginPath(),R.arc(F.x,F.y,F.radius,0,Math.PI*2),R.fill();R.save(),R.translate(r.x,r.y),R.rotate(r.angle),R.fillStyle=i==="gameover"?"#ff4444":"#44aaff",R.beginPath(),R.moveTo(20,0),R.lineTo(-15,-12),R.lineTo(-10,0),R.lineTo(-15,12),R.closePath(),R.fill(),R.strokeStyle="#ffffff",R.lineWidth=1.5,R.stroke(),R.restore(),R.fillStyle="#ffffff",R.font="bold 16px monospace",R.fillText("Score: "+a,10,30),R.fillText("Asteroids: "+c.length,10,50),R.fillText("Phase: "+i,10,70),i==="gameover"&&(R.fillStyle=o==="win"?"#00ff00":"#ff0000",R.font="bold 28px monospace",R.textAlign="center",R.fillText(o==="win"?"YOU WIN!":"GAME OVER",195,400),R.font="16px monospace",R.fillStyle="#ffffff",R.fillText("Tap to restart",195,430),R.textAlign="start")}function Le(){for(let R of s)try{R.cancel()}catch{}s=[],c=[],l=[],i="booting",o=null}function te(){return{seed:e&&e.random?e.random.seed:null,state:()=>({phase:i,result:o,score:a,asteroidsRemaining:c.length,ship:{x:r.x,y:r.y,angle:r.angle}})}}return{init:un,update:hn,render:ae,destroy:Le,_forensicsView:te}}var pd=ns,gd=ns;async function yd(n){let t=n||{},e=t.engine||await Promise.resolve().then(()=>(Mc(),Ic)),s=(t.seed!=null?t.seed:305441741)>>>0,i=va({seed:s});return na({canvas:t.canvas,statusEl:t.statusEl||null,engine:e,seed:s,mode:t.mode||"play",engineMode:"real",viewport:i.viewport,factory:ns,plugins:i.plugins,registerOrder:i.registerOrder,buildFactoryOpts:i.buildFactoryOpts,recHook:t.recHook||null,onReady:t.onReady||null})}return Nc(md);})();
+color = `+this.color),t}renderDebug(t=!0){let e=t?this.isHoverObject()?Ka:this.disabled?tc:this.interactive?rr:Za:Qa;E.drawRect(this.nativePos,this.size,ye,4,e)}click(t=!0){this.onClick(),t&&this.soundClick&&this.soundClick.play()}onUpdate(){}onRender(){}onEnter(){}onLeave(){}onPress(){}onRelease(){}onClick(){}onChange(){}},vi=class extends ce{constructor(t,e,s="",i="center",o=E.defaultFont){super(t,e),p(U(s),"ui text must be a string"),p(["left","center","right"].includes(i),"ui text align must be left, center, or right"),p(U(o),"ui text font must be a string"),this.text=s,this.align=i,this.font=o,this.canBeHover=!1,this.color=ye,this.shadowColor=ye,this.gradientColor=void 0,this.lineWidth=0,this.textFitScale=1}render(){super.render();let t=this.getTextSize();E.drawText(this.text,this.nativePos,t,this.textColor,this.textLineWidth,this.textLineColor,this.align,this.font,this.fontStyle,!0,this.textShadow,this.shadowColor,this.shadowBlur,this.shadowOffset)}},Mo=class extends ce{constructor(t,e,s=""){super(t,e),p(U(s),"ui text must be a string"),this.maxLength=0,this.text=s,this.interactive=!0,this.canBeHover=!0}click(){E.keyInputObject=this,this.onClick()}stopEditing(){this.isKeyInputObject()&&(this.soundRelease&&this.soundRelease.play(),E.activeObject=void 0,E.keyInputObject=void 0,this.onChange())}onKeyDown(t){let e=t.code,s=t.key;e==="Backspace"?this.text=this.text.slice(0,-1):e==="Enter"||e==="Escape"?this.stopEditing():s.length===1&&(!this.maxLength||this.text.lengththis.size.y,s=e?this.size.y:this.size.x,i=e?this.size.x:this.size.y,o=e?this.nativePos.x:this.nativePos.y,a=i-s,r=o-a/2,c=o+a/2,l=E.screenToNative(Vt);this.value=e?Bt(l.x,r,c):Bt(l.y,c,r)}else if(this.isNavigationObject()){let e=E.getNavigationOtherDirection();E.navigationTimer.active()||(this.value=j(this.value+e*.01))}this.value===t||this.onChange()}render(){super.render();let t=this.size.x>this.size.y,e=t?this.size.x:this.size.y,s=t?this.size.y:this.size.x;if(this.fillMode){let o=et(s,this.cornerRadius*2),a=Ht(o,e,this.value),r=(a-e)*(t?.5:-.5),c=this.nativePos.add(t?b(r,0):b(0,r)),l=this.disabled?this.disabledColor:this.handleColor,u=t?b(a,this.size.y):b(this.size.x,a);E.drawRect(c,u,l,this.lineWidth,this.lineColor,this.cornerRadius,this.gradientColor)}else{let o=j(t?this.value:1-this.value),a=(e-s)*(o-.5),r=this.nativePos.add(t?b(a,0):b(0,a)),c=this.disabled?this.disabledColor:this.handleColor,l=b(s);E.drawRect(r,l,c,this.lineWidth,this.lineColor,this.cornerRadius,this.gradientColor)}let i=this.getTextSize();E.drawText(this.text,this.nativePos,i,this.textColor,this.textLineWidth,this.textLineColor,this.align,this.font,this.fontStyle,!0,this.textShadow)}navigatePressed(){this.value=this.value?0:1,this.onChange(),this.onRelease(),super.navigatePressed()}},jo=class extends ce{constructor(t,e,s,i=!1,o=!1,a=1){super(t,e||b()),p(U(s),"video src must be a string"),p(R(a),"video volume must be a number"),this.color=ot,this.cornerRadius=0,this.volume=a,this.video=document.createElement("video"),this.video.loop=o,this.video.volume=j(a*An),this.video.muted=!Yt,this.video.style.display="none",this.video.src=s,document.body.appendChild(this.video),i&&this.play()}async play(){try{await this.video.play()}catch{}}pause(){this.video.pause()}stop(){this.video.pause(),this.video.currentTime=0}isLoading(){return this.video.readyState=1,"ui layout columns must be a number >= 1"),p(R(s),"ui layout gap must be a number"),p(R(i),"ui layout padding must be a number"),this.columns=e,this.gap=s,this.padding=i,o&&(this.color=ye,this.gradientColor=void 0,this.lineWidth=0,this.shadowColor=ye),this.relayout()}addChild(t){return super.addChild(t),this.relayout(),t}removeChild(t){super.removeChild(t),this.relayout()}relayout(){let t=this.children.length;if(!t){this.size=b(this.padding*2);return}let e=this.columns,s=hs(t/e),i=new Array(e).fill(0),o=new Array(s).fill(0);for(let d=0;d=0&&m.objects.splice(t,1),super.destroy()}updatePhysics(){}render(){this.tileInfo?super.render():this.drawFixtures(this.color,this.lineColor,this.lineWidth)}renderDebugInfo(){let t=!this.getIsAwake(),e=this.getBodyType()===m.bodyTypeStatic,s=z(t?1:0,t?1:0,e?1:0,.5);this.drawFixtures(s)}drawFixtures(t=V,e=ot,s=.1,i,o){this.getFixtureList().forEach(a=>{m.castShapeObject(a.GetShape()).GetType()!==m.instance.b2Shape.e_edge&&m.drawFixture(a,this.pos,this.angle,t,e,s,i,o)}),this.edgeLists.forEach(a=>mo(a,s,e,!1,this.pos,this.angle)),this.edgeLoops.forEach(a=>mo(a,s,e,!0,this.pos,this.angle))}beginContact(t){}endContact(t){}addShape(t,e=1,s=.2,i=0,o=!1){p(R(e),"density must be a number"),p(R(s),"friction must be a number"),p(R(i),"restitution must be a number");let a=new m.instance.b2FixtureDef;return a.set_shape(t),a.set_density(e),a.set_friction(s),a.set_restitution(i),a.set_isSensor(o),this.body.CreateFixture(a)}addBox(t=b(1),e=b(),s=0,i,o,a,r){p(O(t),"size must be a Vector2"),p(t.x>0&&t.y>0,"size must be positive"),p(O(e),"offset must be a Vector2"),p(R(s),"angle must be a number");let c=new m.instance.b2PolygonShape;return c.SetAsBox(t.x/2,t.y/2,m.vec2dTo(e),-s),this.addShape(c,i,o,a,r)}addPoly(t,e,s,i,o){p(pe(t),"points must be an array");function a(c){p(3<=c.length&&c.length<=8);let l=m.instance._malloc(c.length*8);for(let d=0,f=0;d>2]=c[d].x,f+=4,m.instance.HEAPF32[l+f>>2]=c[d].y,f+=4;let u=m.instance.wrapPointer(l,m.instance.b2Vec2),h=new m.instance.b2PolygonShape;return h.Set(u,c.length),m.instance._free(l),h}let r=a(t);return this.addShape(r,e,s,i,o)}addRegularPoly(t=1,e=8,s,i,o,a){p(R(t)&&t>0,"diameter must be a positive number"),p(R(e)&&e>2,"sides must be a positive number greater than 2");let r=[],c=t/2;for(let l=e;l--;)r.push(b(c,0).rotate((l+.5)/e*Y*2));return this.addPoly(r,s,i,o,a)}addRandomPoly(t=1,e,s,i,o){p(R(t)&&t>0,"diameter must be a positive number");let a=or(3,9),r=[],c=t/2;for(let l=a;l--;)r.push(b(dt(c/2,c*1.5),0).rotate(l/a*Y*2));return this.addPoly(r,e,s,i,o)}addCircle(t=1,e=b(),s,i,o,a){p(R(t)&&t>0,"diameter must be a positive number"),p(O(e),"offset must be a Vector2");let r=new m.instance.b2CircleShape;return r.set_m_p(m.vec2dTo(e)),r.set_m_radius(t/2),this.addShape(r,s,i,o,a)}addEdge(t,e,s,i,o,a){p(O(t),"point1 must be a Vector2"),p(O(e),"point2 must be a Vector2");let r=new m.instance.b2EdgeShape;return r.Set(m.vec2dTo(t),m.vec2dTo(e)),this.addShape(r,s,i,o,a)}addEdgeList(t,e,s,i,o){p(pe(t),"points must be an array");let a=[],r=[];for(let c=0;ct[oe(l,t.length)];for(let l=0;lthis.destroyFixture(t))}getCenterOfMass(){return m.vec2From(this.body.GetWorldCenter())}getLinearVelocity(){return m.vec2From(this.body.GetLinearVelocity())}getAngularVelocity(){return this.body.GetAngularVelocity()}getMass(){return this.body.GetMass()}getInertia(){return this.body.GetInertia()}getIsAwake(){return this.body.IsAwake()}getBodyType(){return this.body.GetType()}getSpeed(){return this.getLinearVelocity().length()}setTransform(t,e){this.pos=t,this.angle=e,this.body.SetTransform(m.vec2dTo(t),-e)}setPosition(t){this.setTransform(t,this.body.GetAngle())}setAngle(t){this.setTransform(m.vec2From(this.body.GetPosition()),t)}setLinearVelocity(t){this.body.SetLinearVelocity(m.vec2dTo(t))}setAngularVelocity(t){this.body.SetAngularVelocity(t)}setLinearDamping(t){this.body.SetLinearDamping(t)}setAngularDamping(t){this.body.SetAngularDamping(t)}setGravityScale(t=1){this.body.SetGravityScale(this.gravityScale=t)}setBullet(t=!0){this.body.SetBullet(t)}setAwake(t=!0){this.body.SetAwake(t)}setBodyType(t){this.body.SetType(t)}setSleepingAllowed(t=!0){this.body.SetSleepingAllowed(t)}setFixedRotation(t=!0){this.body.SetFixedRotation(t)}setCenterOfMass(t){this.setMassData(t)}setMass(t){this.setMassData(void 0,t)}setMomentOfInertia(t){this.setMassData(void 0,void 0,t)}resetMassData(){this.body.ResetMassData()}setMassData(t,e,s){let i=new m.instance.b2MassData;this.body.GetMassData(i),t!==void 0&&i.set_center(m.vec2dTo(t)),e!==void 0&&i.set_mass(e),s!==void 0&&i.set_I(s),this.body.SetMassData(i)}setFilterData(t=0,e=0,s=0){this.getFixtureList().forEach(i=>{let o=i.GetFilterData();o.set_categoryBits(t),o.set_maskBits(65535&~e),o.set_groupIndex(s)})}setSensor(t=!0){this.getFixtureList().forEach(e=>e.SetSensor(t))}applyForce(t,e){e||(e=this.getCenterOfMass()),this.setAwake(),this.body.ApplyForce(m.vec2dTo(t),m.vec2dTo(e))}applyAcceleration(t,e){e||(e=this.getCenterOfMass()),this.setAwake();let s=t.scale(this.getMass());this.body.ApplyLinearImpulse(m.vec2dTo(s),m.vec2dTo(e))}applyImpulse(t,e){e||(e=this.getCenterOfMass()),this.setAwake(),this.body.ApplyLinearImpulse(m.vec2dTo(t),m.vec2dTo(e))}applyTorque(t){this.setAwake(),this.body.ApplyTorque(t)}applyAngularAcceleration(t){this.setAwake(),this.body.ApplyAngularImpulse(t*this.getInertia())}applyAngularImpulse(t){this.setAwake(),this.body.ApplyAngularImpulse(t)}hasFixtures(){return!m.isNull(this.body.GetFixtureList())}getFixtureList(){let t=[];for(let e=this.body.GetFixtureList();!m.isNull(e);)t.push(e),e=e.GetNext();return t}hasJoints(){return!m.isNull(this.body.GetJointList())}getJointList(){let t=[];for(let e=this.body.GetJointList();!m.isNull(e);)t.push(e),e=e.get_next();return t}},Si=class extends Rs{constructor(t,e,s,i=0,o,a=0){let r=m.bodyTypeStatic;super(t,e,s,i,o,r,a)}},Bo=class extends Rs{constructor(t,e,s,i=0,o,a=0){let r=m.bodyTypeKinematic;super(t,e,s,i,o,r,a)}},zo=class extends Si{constructor(t){p(t instanceof Ss,"tileLayer must be a TileCollisionLayer"),super(t.pos,t.size),this.tileLayer=t,this.addChild(t)}render(){}buildCollision(t=.2,e=0){this.destroyAllFixtures(),this.pos=this.tileLayer.pos.copy(),this.size=this.tileLayer.size.copy();let s=[],i=(a,r)=>a+r*this.size.x,o=(a,r)=>!s[i(a,r)]&&this.tileLayer.getCollisionData(b(a,r))>0;for(let a=0;ai.fractiono.pos.distanceSquared(t)0,"Tween duration must be > 0"),this.callback=t,this.start=e,this.end=s,this.duration=i,this.life=i,this.ease=o.ease||Ci.LINEAR,this.useRealTime=!!o.useRealTime,this.paused=!!o.paused,this.thenCallback=void 0,this.loopRemaining=0,Qt.push(this),t(this.interp(i))}setEase(t){return this.ease=t,this}then(t){return this.thenCallback=t,this.loopRemaining=0,this}loop(t=1/0){return this.loopRemaining=t,this.thenCallback=()=>Lc(this),this}pingPong(t=1/0){return this.loopRemaining=t,this.thenCallback=()=>Oc(this),this}pause(){this.paused=!0}resume(){this.paused=!1}restart(){this.life=this.duration,this.paused=!1,Qt.indexOf(this)<0&&Qt.push(this),this.callback(this.interp(this.duration))}isActive(){return!this.paused&&Qt.indexOf(this)>=0}getPercent(){return Bt(this.duration-this.life,0,this.duration)}getValue(){return this.interp(this.life)}interp(t){let e=this.ease((this.duration-t)/this.duration);return La(this.start)?this.start.lerp(this.end,e):this.start+(this.end-this.start)*e}stop(){let t=Qt.indexOf(this);t>=0&&Qt.splice(t,1),this.thenCallback=void 0}},Ci={LINEAR:n=>n,POWER:n=>t=>t**n,SINE:n=>1-lt(n*(Y/2)),CIRC:n=>1-(1-n*n)**.5,EXPO:n=>n===0?0:2**(10*n-10),BACK:n=>n*n*(2.70158*n-1.70158),ELASTIC:n=>n===0?0:n===1?1:-(2**(10*n-10))*it((37-40*n)*Y/6),SPRING:n=>1-(it(Y*(1-n)*(.2+2.5*(1-n)**3))*n**2.2+(1-n))*(1+1.2*n),BOUNCE:n=>{let t=1-n,e;return t<4/11?e=7.5625*t*t:t<8/11?e=7.5625*(t-=6/11)*t+.75:t<10/11?e=7.5625*(t-=9/11)*t+.9375:e=7.5625*(t-=10.5/11)*t+.984375,1-e},IN:n=>n,OUT:n=>t=>1-n(1-t),IN_OUT:n=>Ci.PIECEWISE(n,Ci.OUT(n)),PIECEWISE:(...n)=>{let t=n.length;return e=>{let s=e*t-1e-9>>0;return(n[s]((e-s/t)*t)+s)/t}},BEZIER:(n,t,e,s)=>{let i=o=>{let a=1-o,r=3*a*a*o,c=3*a*o*o,l=o**3;return[r*n+c*e+l,r*t+c*s+l]};return o=>{let a=0,r=1;for(let c=0;c<128;c++){let l=(a+r)/2,[u,h]=i(l);if(st(u-o)<1e-5)return h;u=this.size.x||e>=this.size.y?null:this.nodes[t+e*this.size.x]}worldToTile(t){let e=this.tileLayer?this.tileLayer.pos.x:0,s=this.tileLayer?this.tileLayer.pos.y:0;return b(At(t.x-e),At(t.y-s))}tileToWorld(t,e){let s=this.tileLayer?this.tileLayer.pos.x:0,i=this.tileLayer?this.tileLayer.pos.y:0;return b(t+.5+s,e+.5+i)}buildNodeData(){let t=this.size.x,e=this.size.y,s=this.tileLayer?this.tileLayer.pos.x:0,i=this.tileLayer?this.tileLayer.pos.y:0;for(let o=0;o0&&(c?l>0&&xt(r.posWorld,lo,z(1,0,0,et(.2,l*.05)),this.debugTime):xt(r.posWorld,lo,z(1,0,0,.25),this.debugTime))}}aStarSearch(t,e){p(t&&e,"aStarSearch needs both endpoints"),p(t!==e,"aStarSearch: start and end must differ \u2014 caller should handle trivial case"),p(t.walkable&&e.walkable,"aStarSearch: endpoints must be walkable");let s=[t];t.isOpen=!0;let i=0;for(;s.length>0;){let o=0,a=s[0].f;for(let c=1;cthis.maxLoop)break;r.isOpen=!1,s.splice(o,1),r.isClosed=!0,this.debug&&this.debugTime>0&&xt(r.posWorld,lo,z(1,1,1,.05),this.debugTime);for(let c=-1;c<=1;++c)for(let l=-1;l<=1;++l){if(l===0&&c===0)continue;let u=this.getNode(r.pos.x+l,r.pos.y+c);if(!u||!u.walkable||u.isClosed)continue;let h=1;if(l!==0&&c!==0){let v=this.getNode(r.pos.x+l,r.pos.y);if(!v||!v.walkable)continue;let w=this.getNode(r.pos.x,r.pos.y+c);if(!w||!w.walkable)continue;h=fd}let d=r.g+h+u.cost;if(!u.isOpen)u.isOpen=!0,s.push(u);else if(d>=u.g)continue;u.parent=r,u.g=d;let f=st(e.pos.x-u.pos.x),y=st(e.pos.y-u.pos.y),x=Q(f,y)+(Math.SQRT2-1)*et(f,y);u.f=u.g+x*this.heuristicWeight}}return e.parent!==null}getNearestClearNode(t,e=10,s=!0){p(O(t),"worldPos must be a Vector2"),s&&this.buildNodeData();let i=this.tileLayer?this.tileLayer.pos.x:0,o=this.tileLayer?this.tileLayer.pos.y:0,a=At(t.x-i),r=At(t.y-o);for(let c=0;c<=e;++c){let l=null,u=0;for(let h=-c;h<=c;++h)for(let d=-c;d<=c;++d){if(c>0&&st(d)!==c&&st(h)!==c)continue;let f=this.getNode(a+d,r+h);if(!f||!f.isClear())continue;let y=f.posWorld.x-t.x,x=f.posWorld.y-t.y,v=y*y+x*x;(!l||v0&&Wt(i.posWorld,.3,z(.5,0,.5,.5),this.debugTime),t.splice(e,1),e=Q(1,e-1);continue}else if(c===2){this.debug&&this.debugTime>0&&Wt(i.posWorld,.3,z(1,0,0,.5),this.debugTime);let f,y;s.pos.y===i.pos.y&&o.pos.x===i.pos.x?(f=s.pos.x,y=o.pos.y):(f=o.pos.x,y=s.pos.y);let x=this.getNode(f,y);if(x&&x.isClear()){t.splice(e,1),e=Q(1,e-1);continue}}else if(c===5){this.debug&&this.debugTime>0&&Wt(i.posWorld,.3,z(1,1,0,.5),this.debugTime);let f=e>=2?t[e-2]:s,y,x,v,w;l===0||h===0?(y=o.pos.x,x=i.pos.y,v=s.pos.x,w=i.pos.y):(y=i.pos.x,x=o.pos.y,v=i.pos.x,w=s.pos.y);let _=y-f.pos.x,S=x-f.pos.y,C=v-f.pos.x,A=w-f.pos.y,T=_*_+S*S,P=C*C+A*A,k=T0&&Wt(i.posWorld,.3,z(0,1,0,.5),this.debugTime),l===h&&u===d){++e;continue}else{let f,y;s.pos.y===o.pos.y?(f=i.pos.x,y=s.pos.y):(f=s.pos.x,y=i.pos.y);let x=this.getNode(f,y);if(x&&x.isClear()){t[e]=x,e=Q(1,e-1);continue}}++e}}smoothPathStringPull(t){if(t.length<=2)return;for(let i of t)if(!i.isClear())return;let e=t.slice();t.length=0,t.push(e[0]);let s=0;for(let i=1;i0&&Ee(o.posWorld,t[t.length-1].posWorld,z(0,0,1,.3),.02,this.debugTime);continue}for(;s=1;--e){let s=t[e-1],i=t[e],o=t[e+1];(i.pos.x-s.pos.x)*(o.pos.y-s.pos.y)===(i.pos.y-s.pos.y)*(o.pos.x-s.pos.x)&&t.splice(e,1)}}isNodeClear(t,e){let s=this.getNode(t,e);return s!==null&&s.isClear()}isLineClear(t,e){p(O(t)&&O(e),"isLineClear needs Vector2 endpoints"),p(this.isNodeClear(t.x,t.y)&&this.isNodeClear(e.x,e.y),"isLineClear endpoints must be in-bounds and clear");let s=e.x-t.x,i=e.y-t.y,o=st(s),a=st(i),r=ie(s),c=ie(i),l=t.x,u=t.y;if(a===o){for(;l!==e.x;){if(l!==t.x&&(!this.isNodeClear(l,u)||!this.isNodeClear(l,u-c))||!this.isNodeClear(l,u+c))return!1;l+=r,u+=c}if(!this.isNodeClear(e.x,e.y-c))return!1}else if(ar.posWorld.copy());if(this.debug&&this.debugTime>0&&a.length>0){for(let r=1;rpd,bootGameHost:()=>yd,default:()=>gd});var js=class{constructor(t){this._state=(t==null?2654435769:t)>>>0}next(){this._state=this._state+1831565813>>>0;let t=this._state;return t=Math.imul(t^t>>>15,t|1),t^=t+Math.imul(t^t>>>7,t|61),((t^t>>>14)>>>0)/4294967296}range(t,e){return t+this.next()*(e-t)}reseed(t){this._state=(t==null?2654435769:t)>>>0}},Ji=class{constructor(t){this._clock=t||Jc(),this._origin=this._clock()}nowMs(){return this._clock()}elapsedMs(){return this._clock()-this._origin}},Ui=class{constructor(t){this._time=t,this._subs=new Map}sourceFor(t){let e=this,s=t==null?null:t;return{on(i,o){if(e._assertType(i),typeof o!="function")throw new Error("[HostDevInputBridge] on \u7684 handler \u5FC5\u987B\u662F\u51FD\u6570");let a=e._subs.get(i)||[],r={handler:o,scope:s};return a.push(r),e._subs.set(i,a),{cancel(){let c=e._subs.get(i);if(!c)return;let l=c.indexOf(r);l>=0&&c.splice(l,1)}}},off(i,o){e._assertType(i);let a=e._subs.get(i);if(!a)return;let r=a.findIndex(c=>c.handler===o&&c.scope===s);r>=0&&a.splice(r,1)}}}_emit(t,e){this._assertType(t);let s=e||{},i={type:t,x:typeof s.x=="number"?s.x:0,y:typeof s.y=="number"?s.y:0,key:typeof s.key=="string"?s.key:"",tMs:this._time.nowMs()},o=this._subs.get(t);if(!o||o.length===0)return;let a=o.slice();for(let r of a)try{r.handler(i)}catch(c){Ye("[host-dev input] \u8F93\u5165 handler \u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09type="+t,c)}}disposeScope(t){if(t==null)return 0;let e=0;for(let[s,i]of this._subs){let o=i.filter(a=>a.scope!==t);e+=i.length-o.length,o.length===0?this._subs.delete(s):this._subs.set(s,o)}return e}_subscriptionCount(){let t=0;for(let e of this._subs.values())t+=e.length;return t}_assertType(t){if(!Vi.has(t))throw new Error("[HostDevInputBridge] \u975E\u6CD5\u8F93\u5165\u4E8B\u4EF6\u7C7B\u578B\uFF1A"+String(t)+"\uFF08\u4EC5\u652F\u6301 "+Array.from(Vi).join("/")+"\uFF09")}},Vi=new Set(["pointerdown","pointermove","pointerup","keydown","keyup"]);function Xr(n){let t=n||{},e=new Ji(t.clock),s=new js(t.seed),i=t.seed==null?2654435769:t.seed>>>0,o=new Ui(e),a=typeof t.audioFactory=="function"?t.audioFactory:null,r=null,c=!1,l=typeof t.engineFactory=="function"?t.engineFactory:null,u=null,h=!1,d=new Map,f=0,y=0;function x(){if(r)return r;if(!a)return c||(qi("[host-dev audio] \u672A\u6CE8\u5165 audioFactory\uFF0CgetAudioContext \u8FD4\u56DE null\uFF08P6 \u987B\u5BB9\u9519\u964D\u7EA7\uFF1B\u96C6\u6210\u6BB5\u6CE8\u5165\u771F\u5B9E\u5DE5\u5382\uFF09"),c=!0),null;try{r=a()}catch(C){Ye("[host-dev audio] audioFactory \u629B\u9519\uFF0CgetAudioContext \u964D\u7EA7\u8FD4\u56DE null",C),r=null}return r}function v(){if(u)return u;if(!l)return h||(qi("[host-dev engine] \u672A\u6CE8\u5165 engineFactory\uFF0CgetEngine \u8FD4\u56DE null\uFF08\u63D2\u4EF6\u987B\u5BB9\u9519\u964D\u7EA7\uFF1A\u7C92\u5B50\u9000\u53D7\u63A7\u9762\u81EA\u7BA1/\u5408\u6210\u6838\u9000 vendored/\u6570\u5B66\u9000\u5185\u7F6E\uFF1B\u96C6\u6210\u6BB5\u6CE8\u5165\u771F\u5B9E\u80CC\u4E66\uFF09"),h=!0),null;try{u=l()}catch(C){Ye("[host-dev engine] engineFactory \u629B\u9519\uFF0CgetEngine \u964D\u7EA7\u8FD4\u56DE null",C),u=null}return u}function w(C,A){return{getContext2d(){return t.context2d==null?null:t.context2d},onFrame(P){let k=f++;return d.set(k,P),{cancel(){d.delete(k)}}},getInput(){return o.sourceFor(C)},getAudioContext(){return x()},getEngine(){return v()},time:e,random:A}}let _=w(null,s),S={context:_,tick(C){y+=1;let A=Array.from(d.values());for(let T of A)try{T(C,y)}catch(P){Ye("[host-dev tick] \u5E27\u56DE\u8C03\u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09frame="+y,P)}},frameCount(){return y},inputBridge:o,deriveContextFor(C,A){let T=zc(i,C),P=new js(T);return w(A==null?C:A,P)}};return Object.defineProperty(_,Wi,{value:S,enumerable:!1,writable:!1,configurable:!1}),S}var Wi=Symbol("zaomeng.coreProtocol.contextBundle"),Ns=class{constructor(){this._plugins=new Map,this._initOrder=[],this._initErrors=[],this._phase="idle",this._disposed=!1,this._context=void 0,this._pluginContexts=new Map}register(t){if(!t||typeof t!="object")throw new Error("[PluginRegistry] register \u9700\u8981\u4E00\u4E2A\u63D2\u4EF6\u5BF9\u8C61");if(typeof t.name!="string"||t.name.length===0)throw new Error("[PluginRegistry] \u63D2\u4EF6\u7F3A\u5C11\u5408\u6CD5 name");if(typeof t.version!="string"||t.version.length===0)throw new Error("[PluginRegistry] \u63D2\u4EF6 "+t.name+" \u7F3A\u5C11\u5408\u6CD5 version");if(typeof t.init!="function")throw new Error("[PluginRegistry] \u63D2\u4EF6 "+t.name+" \u7F3A\u5C11 init \u51FD\u6570");if(t.dispose!=null&&typeof t.dispose!="function")throw new Error("[PluginRegistry] \u63D2\u4EF6 "+t.name+" \u7684 dispose \u5FC5\u987B\u662F\u51FD\u6570\u6216\u7701\u7565");if(this._plugins.has(t.name))throw new Error("[PluginRegistry] \u63D2\u4EF6\u91CD\u540D\u62D2\u7EDD\uFF1A"+t.name+" \u5DF2\u6CE8\u518C");return this._plugins.set(t.name,t),this}has(t){return this._plugins.has(t)}get(t){return this._plugins.get(t)}list(){return Array.from(this._plugins.keys())}initAll(){if(this._phase==="initialized")return qi("[PluginRegistry] initAll \u91CD\u590D\u8C03\u7528\uFF0C\u5DF2\u5FFD\u7565\uFF08\u5DF2\u5904\u4E8E initialized\uFF09"),this._initResult();if(this._phase==="disposed")throw new Error("[PluginRegistry] \u5DF2 dispose \u7684\u6CE8\u518C\u5668\u4E0D\u53EF\u518D initAll");if(this._context==null)throw new Error("[PluginRegistry] \u672A\u6CE8\u5165\u53D7\u63A7\u4E0A\u4E0B\u6587\uFF1A\u8BF7\u5728 initAll() \u4E4B\u524D\u8C03\u7528 useContext(context)\u3002\uFF08host-dev \u7528\u6CD5\uFF1Aconst { context } = createHostDevContext(); reg.useContext(context); reg.initAll();\uFF09");for(let[t,e]of this._plugins){let s=this._missingDeps(e);if(s.length>0){let o=new Error("[PluginRegistry] \u63D2\u4EF6 "+t+" \u4F9D\u8D56\u7F3A\u5931\uFF1A"+s.join(", ")+"\uFF08\u672A\u6CE8\u518C\uFF09");this._initErrors.push({name:t,error:o}),Ye("[PluginRegistry] \u8DF3\u8FC7 init\uFF08\u4F9D\u8D56\u7F3A\u5931\uFF0C\u5DF2\u9694\u79BB\uFF09\uFF1A"+t,o);continue}let i=this._contextFor(t);try{e.init(i),this._initOrder.push(t)}catch(o){let a=o instanceof Error?o:new Error(String(o));this._initErrors.push({name:t,error:a}),Ye("[PluginRegistry] \u63D2\u4EF6 init \u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF0C\u4E0D\u8FDE\u5750\uFF09\uFF1A"+t,a)}}return this._phase="initialized",this._initResult()}_contextFor(t){let e=this._pluginContexts.get(t);if(e)return e;let s=this._context&&this._context[Wi],i;return s&&typeof s.deriveContextFor=="function"?i=s.deriveContextFor(t,t):i=this._context,this._pluginContexts.set(t,i),i}disposeAll(){if(this._disposed)return{disposed:[],errors:[]};let t=[],e=[],s=this._context&&this._context[Wi],i=s&&s.inputBridge;for(let o=this._initOrder.length-1;o>=0;o--){let a=this._initOrder[o],r=this._plugins.get(a);if(r&&typeof r.dispose=="function")try{r.dispose(),t.push(a)}catch(c){let l=c instanceof Error?c:new Error(String(c));e.push({name:a,error:l}),Ye("[PluginRegistry] \u63D2\u4EF6 dispose \u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09\uFF1A"+a,l)}if(i&&typeof i.disposeScope=="function")try{i.disposeScope(a)}catch(c){Ye("[PluginRegistry] \u56DE\u6536\u63D2\u4EF6\u8F93\u5165\u8BA2\u9605\u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09\uFF1A"+a,c)}}return this._disposed=!0,this._phase="disposed",{disposed:t,errors:e}}useContext(t){if(this._phase!=="idle")throw new Error("[PluginRegistry] useContext \u5FC5\u987B\u5728 initAll() \u4E4B\u524D\u8C03\u7528\uFF08\u5F53\u524D\u9636\u6BB5\uFF1A"+this._phase+"\uFF09\u3002\u8BF7\u5728\u4EFB\u4F55 initAll/disposeAll \u4E4B\u524D\u6CE8\u5165\u53D7\u63A7\u4E0A\u4E0B\u6587\u3002");if(t==null||typeof t!="object")throw new Error("[PluginRegistry] useContext \u9700\u8981\u4E00\u4E2A\u53D7\u63A7\u4E0A\u4E0B\u6587\u5BF9\u8C61\u3002\uFF08host-dev \u7528\u6CD5\uFF1Aconst { context } = createHostDevContext(); reg.useContext(context);\uFF09");return this._context=t,this}_missingDeps(t){return!Array.isArray(t.dependencies)||t.dependencies.length===0?[]:t.dependencies.filter(e=>!this._plugins.has(e))}_initResult(){return{ok:this._initErrors.length===0,initialized:this._initOrder.slice(),errors:this._initErrors.slice()}}};function zc(n,t){let e=2166136261,s=16777619,i=n>>>0;for(let a=0;a<32;a+=8){let r=i>>>a&255;e^=r,e=Math.imul(e,s)>>>0}let o=String(t);for(let a=0;a>>0,e^=r>>>8&255,e=Math.imul(e,s)>>>0}return e>>>0}function Jc(){if(typeof globalThis!="undefined"&&globalThis.performance&&typeof globalThis.performance.now=="function")return()=>globalThis.performance.now();if(typeof process!="undefined"&&process.hrtime&&typeof process.hrtime.bigint=="function"){let n=process.hrtime.bigint();return()=>Number(process.hrtime.bigint()-n)/1e6}return()=>Date.now()}function Ye(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function qi(n){typeof console!="undefined"&&typeof console.warn=="function"&&console.warn(n)}var xd=Object.freeze(Array.from(Vi)),Yr="core-protocol-v0";var $r=Object.freeze(["t_boot","t_plugins_ready","t_game_init","t_first_paint","t_input_bound","t_game_start"]),Hi=$r.reduce((n,t,e)=>(n[t]=e,n),Object.create(null)),Uc=new Set($r);function Xi(n){let t=2166136261;for(let e=0;e>>0).toString(16).padStart(8,"0")}var Kr=Xi("runtime-probe::seed::v1");function Bs(n){return n===null||typeof n!="object"?JSON.stringify(n):Array.isArray(n)?"["+n.map(Bs).join(",")+"]":"{"+Object.keys(n).sort().map(e=>JSON.stringify(e)+":"+Bs(n[e])).join(",")+"}"}function Qr(n){let t=Bs(n.extra==null?null:n.extra),e=Bs(Array.isArray(n.pluginSet)?n.pluginSet:[]);return["seq="+n.seq,"anchor="+n.anchor,"tMono="+n.tMono,"buildSha="+(n.buildSha||""),"pluginSet="+e,"extra="+t].join("|")}function Vc(n){return Math.round(n*1e3)/1e3}function Wc(n){if(!Array.isArray(n))return{ok:!1,reason:"records_not_array"};let t=Kr,e=-1;for(let s=0;stypeof C=="string").slice().sort():[],i=typeof t.sink=="function"?t.sink:null,o=t.autoBoot!==!1,a=typeof t.inputAnchorType=="string"?t.inputAnchorType:"pointerdown",r=()=>0,c=!1,l=0,u=Kr,h=[],d=new Set,f=-1,y=null,x=!1,v=!1,w=!1;function _(C,A){let T=null;if(!Uc.has(C))T="unknown_anchor";else{d.has(C)&&(T=T?T+";duplicate_anchor":"duplicate_anchor");let k=Hi[C];kC.time.nowMs(),c=!0,o&&!v&&_("t_boot",{auto:!0}),y=C.getInput().on(a,A=>{x||(x=!0,_("t_input_bound",{firstInput:!0,type:A.type}))}),_("t_input_bound",{stage:"registered",type:a})},dispose(){w||(y&&(y.cancel(),y=null),w=!0)},mark:_,getRecords(){return h.map(C=>({...C}))},toJSONL(){return h.map(C=>JSON.stringify(C)).join(`
+`)},verify(){return Wc(h)}}}function qc(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function ta(n){let t=n.LJS,e=n.engineMath,s=n.engineMode,i=n.recHook||(()=>{});if(s!=="real")return null;let o=e;return{math:{lerp:(r,c,l)=>(i("math.lerp"),o.lerp(r,c,l)),smoothStep:r=>(i("math.smoothStep"),o.smoothStep(r)),easing:Object.fromEntries(Object.keys(o.easing).map(r=>[r,c=>(i("math.easing."+r),o.easing[r](c))]))},particles:{spawnEmitter(r){i("particles.spawnEmitter");let c=t.screenToWorld(t.vec2(r.pos.x,r.pos.y)),l=t.cameraScale,u=r.emitTime!=null?r.emitTime:r.count!=null?1/60:0,h=r.emitRate!=null?r.emitRate:r.count!=null?r.count*60:100,d=(r.speed!=null?r.speed:0)/l/60,f=r.damping!=null?r.damping:1,y=r.colorStart||{r:1,g:1,b:1,a:1},x=r.colorEnd||{r:1,g:1,b:1,a:0},v=t.rgb(y.r,y.g,y.b,y.a),w=t.rgb(x.r,x.g,x.b,x.a),_=new t.ParticleEmitter(c,r.angle!=null?r.angle:0,(r.emitSize!=null?r.emitSize:0)/l,u,h,r.coneAngle!=null?r.coneAngle:Math.PI,void 0,v,v,w,w,r.particleTime!=null?r.particleTime:.5,(r.sizeStart!=null?r.sizeStart:6)/l,(r.sizeEnd!=null?r.sizeEnd:0)/l,d,0,f,1,r.gravityScale!=null?r.gravityScale:0,Math.PI,.1,0,!1,r.additive!=null?r.additive:!1,!0);return{isActive(){return _.isActive()},stop(){_.destroyed||_.destroy(!0)}}}},audio:{synth:{synthSfx:r=>{i("audio.synth.synthSfx");try{return t.zzfxG(...r)}catch(c){return console.error("[host][engine-audio] zzfxG \u5408\u6210\u5F02\u5E38\uFF0C\u8FD4 null\uFF1A"+(c&&c.message?c.message:c)),null}},synthSong:(r,c,l,u)=>{i("audio.synth.synthSong");try{return t.zzfxM(r,c,l,u)}catch(h){return console.error("[host][engine-audio] zzfxM \u5408\u6210\u5F02\u5E38\uFF0C\u8FD4 null\uFF1A"+(h&&h.message?h.message:h)),null}}}}}}function ue(n){return n<0?0:n>1?1:n}function ea(n){let t=n.Ease,e=t.POWER(2),s=t.POWER(3),i=t.OUT(e),o=t.IN_OUT(e),a=t.OUT(s),r=t.IN_OUT(s),c=t.OUT(t.BACK),l=t.OUT(t.ELASTIC);return{lerp:(u,h,d)=>n.lerp(u,h,d),smoothStep:u=>n.smoothStep(u),easing:{linear:u=>t.LINEAR(ue(u)),quadIn:u=>e(ue(u)),quadOut:u=>i(ue(u)),quadInOut:u=>o(ue(u)),cubicIn:u=>s(ue(u)),cubicOut:u=>a(ue(u)),cubicInOut:u=>r(ue(u)),backIn:u=>t.BACK(ue(u)),backOut:u=>c(ue(u)),elasticIn:u=>t.ELASTIC(ue(u)),elasticOut:u=>l(ue(u))}}}var $e=2,zs=1/60;async function na(n){let t=n.canvas,e=n.statusEl||null,s=n.engine,i=n.seed>>>0,o=n.mode||"play",a=n.engineMode||"real",r=n.viewport.w,c=n.viewport.h,l=n.factory,u=n.buildFactoryOpts||(()=>{}),h=n.plugins||{},d=n.registerOrder||Object.values(h),f=n.onReady||(()=>{}),y=n.recHook||(()=>{});function x(D){e&&(e.textContent=D)}let v=[];window.addEventListener("error",D=>v.push({type:"error",message:String(D&&D.message||D)})),window.addEventListener("unhandledrejection",D=>v.push({type:"unhandledrejection",message:String(D&&D.reason&&D.reason.message||D&&D.reason||D)}));let w=null,_=!1;function S(){if(!_)return null;if(w)return w;let D=window.AudioContext||window.webkitAudioContext;return D?(w=new D,w):null}let C=0,A=null,T=null,P=null,k=null,pt=[],W={},$=null;function gt(D,at){try{P&&P.mark(D,at)}catch(se){v.push({type:"mark",message:String(se&&se.message||se)})}}function zt(){T&&typeof T._refreshChecklist=="function"&&T._refreshChecklist(W)}async function me(D,at){A=Xr({context2d:D,seed:i,audioFactory:S,clock:()=>C,engineFactory:()=>ta({LJS:a==="real"?s:null,engineMath:a==="real"?ea(s):null,engineMode:a,recHook:y})});let se=new Ns;for(let xe of d)se.register(xe);se.useContext(A.context),k=se.initAll(),pt=se.list().concat(["runtime-probe"]),P=Zr({pluginSet:pt,inputAnchorType:"pointerdown",autoBoot:!0});let Ot=A.deriveContextFor("runtime-probe","runtime-probe");gt("t_boot",{by:"game-host",stage:"pre-init",engineMode:a}),gt("t_plugins_ready",{initialized:k.initialized.length,ok:k.ok});let Bi=u(A.context,{bundle:A,plugins:h,getRealAudioCtx:()=>w});T=l(Bi),await T.init({ctx:A.context,mainContext:D,canvas:at(),seed:i}),$=T&&typeof T._forensicsView=="function"?T._forensicsView():null,gt("t_game_init",{hasForensics:!!$}),rt(),gt("t_first_paint",{frame:A.frameCount()});try{P.init(Ot)}catch(xe){v.push({type:"probe-init",message:String(xe&&xe.message||xe)})}gt("t_game_start",{mode:o,engineMode:a}),zt(),f(fn,{bundle:A,game:T,probe:P,checklist:W,uncaught:v,pluginSet:pt,initRes:k,getGameForensics:()=>$,mark:gt,stepOneFrame:rt})}let Jt=null;function rt(D){let at=typeof D=="number"?D:zs;T&&(C+=at*1e3,T.update(at),a==="stub"&&Jt&&T.render(Jt),zt())}function Tt(D){for(let at=0;at{}),T&&typeof T._onAudioUnlock=="function"&&T._onAudioUnlock()}let fn={seed:i,mode:o,engineMode:a,protocol:Yr,frameCount:()=>A?A.frameCount():0,stepFrames:Tt,startRaf:()=>X(),stopRaf:()=>N(),tap(D,at){be(),A&&(A.inputBridge._emit("pointerdown",{x:D,y:at}),A.inputBridge._emit("pointerup",{x:D,y:at}))},do(D){T&&typeof T._handleAction=="function"&&T._handleAction(D)},state:()=>$?$.state():{phase:"booting"}};function pn(D){let at=A.inputBridge;function se(Ot,Bi){let xe=D.getBoundingClientRect();return{x:(Ot-xe.left)/xe.width*r,y:(Bi-xe.top)/xe.height*c}}D.addEventListener("pointerdown",Ot=>{be(),at._emit("pointerdown",se(Ot.clientX,Ot.clientY))}),D.addEventListener("pointermove",Ot=>{at._emit("pointermove",se(Ot.clientX,Ot.clientY))}),D.addEventListener("pointerup",Ot=>{at._emit("pointerup",se(Ot.clientX,Ot.clientY))}),window.addEventListener("keydown",Ot=>{be(),at._emit("keydown",{key:Ot.key})}),window.addEventListener("keyup",Ot=>at._emit("keyup",{key:Ot.key}))}let le=0,De=!1,ne=0;function L(D){if(!De)return;ne===0&&(ne=D);let at=(D-ne)/1e3;ne=D,at>.05&&(at=.05),rt(at),le=window.requestAnimationFrame(L)}function X(){a==="stub"&&(De||(De=!0,ne=0,le=window.requestAnimationFrame(L)))}function N(){De=!1,le&&window.cancelAnimationFrame(le),le=0}function yt(D){D.width=r*$e,D.height=c*$e,D.style.width=r+"px",D.style.height=c+"px";let at=D.getContext("2d",{willReadFrequently:!0});return at.setTransform($e,0,0,$e,0,0),at}async function vt(){let D=yt(t);return Jt=D,await me(D,()=>t),pn(t),o==="evidence"?x(`evidence \u5C31\u7EEA seed=${i} \xB7 \u7528 host \u9A71\u52A8\uFF08stepFrames/tap\uFF09`):(x(`seed=${i} \xB7 \u70B9\u5F00\u59CB\uFF08\u9996\u6B21\u70B9\u51FB\u5F00\u58F0\uFF09`),X()),fn}let Mt=()=>{},M=()=>{};function Z(){window.__gameHostEngineInitFired=!0}function Ct(){Mt()}function kt(){}function ht(){M()}function Ie(){}async function gn(D){await me(D,()=>s.mainCanvas),pn(s.mainCanvas),Mt=()=>{T&&(C+=zs*1e3,T.update(zs))},M=()=>{if(T){D.save(),D.setTransform($e,0,0,$e,0,0);try{D.imageSmoothingEnabled=!1}catch{}T.render(D),D.restore()}},s.mainCanvas&&(s.mainCanvas.id="game-engine"),window.__engine={frame(){return s.frame},time(){return s.time},timeReal(){return s.timeReal},paused(){return s.paused},timeScale(){return s.timeScale},snapshot(){return{frame:s.frame,time:s.time,timeReal:s.timeReal,paused:s.paused,timeScale:s.timeScale}}},x(`engine RAF running \xB7 seed=${i} engine=real`)}if(a!=="real")return await vt();if(!s){let D="real \u901A\u9053\u672A\u6CE8\u5165\u5F15\u64CE\uFF08opts.engine \u7F3A\u5931\uFF09\uFF1A\u8BF7\u7ECF entry \u5305\u88C5\u5C42\u542F\u52A8\uFF08host \u4E0D\u76F4\u63A5 import \u5F15\u64CE\uFF0CQ4/Option C\uFF09";throw x("ENGINE INJECT MISSING: "+D),new Error(D)}s.setGLEnable(!1),s.setShowSplashScreen(!1),s.setDebugWatermark(!1),s.setCanvasClearColor(s.BLACK),s.setCanvasFixedSize(s.vec2(r*$e,c*$e));let Me=document.createElement("div");return Me.id="engine-root",document.body.appendChild(Me),await s.engineInit(Z,Ct,kt,ht,Ie,[],Me).then(()=>gn(s.mainContext)).catch(D=>{throw window.__gameHostBootError=String(D&&D.message||D),x("ENGINE INIT FAILED: "+window.__gameHostBootError),D}),fn}var Yi=class{constructor(t){let e=t||{},s=typeof e.cellSize=="number"&&e.cellSize>0?e.cellSize:64;this._cellSize=s,this._cells=new Map,this._entries=new Map,this._seq=0}get size(){return this._entries.size}_cellRange(t){let e=this._cellSize,s=Math.floor((t.x-t.hw)/e),i=Math.floor((t.x+t.hw)/e),o=Math.floor((t.y-t.hh)/e),a=Math.floor((t.y+t.hh)/e);return{cx0:s,cy0:o,cx1:i,cy1:a}}insert(t,e){this._entries.has(t)&&this.remove(t);let{cx0:s,cy0:i,cx1:o,cy1:a}=this._cellRange(e),r=[];for(let l=i;l<=a;l++)for(let u=s;u<=o;u++){let h=u+","+l,d=this._cells.get(h);d||(d=new Set,this._cells.set(h,d)),d.add(t),r.push(h)}let c={x:e.x,y:e.y,hw:e.hw,hh:e.hh};this._entries.set(t,{id:t,box:c,seq:this._seq++,cells:r})}remove(t){let e=this._entries.get(t);if(!e)return!1;for(let s of e.cells){let i=this._cells.get(s);i&&(i.delete(t),i.size===0&&this._cells.delete(s))}return this._entries.delete(t),!0}query(t){let{cx0:e,cy0:s,cx1:i,cy1:o}=this._cellRange(t),a=new Set;for(let r=s;r<=o;r++)for(let c=e;c<=i;c++){let l=this._cells.get(c+","+r);if(l)for(let u of l)a.add(u)}return this._collect(a)}queryPoint(t,e){let s=this._cellSize,i=Math.floor(t/s),o=Math.floor(e/s),a=this._cells.get(i+","+o);return a?this._collect(new Set(a)):[]}clear(){this._cells.clear(),this._entries.clear(),this._seq=0}_collect(t){let e=[];for(let s of t){let i=this._entries.get(s);i&&e.push(i)}return e.sort((s,i)=>s.seq-i.seq),e.map(s=>({id:s.id,box:s.box}))}};function sa(n){let t=n||{},e=new Yi({cellSize:t.cellSize}),s=!1;return{name:"collision",version:"1.0.0",dependencies:[],spatial:e,init(o){},dispose(){s||(e.clear(),s=!0)}}}function ia(n){let t=!1;return{name:"physics-lite",version:"1.0.0",dependencies:[],init(s){},dispose(){t||(t=!0)}}}var Hc=["pointerdown","pointermove","pointerup","keydown","keyup"];function Ut(n){return n<0?0:n>1?1:n}var Xc=n=>(n=Ut(n),n*n),Yc=n=>(n=Ut(n),1-(1-n)*(1-n)),$c=n=>(n=Ut(n),n<.5?2*n*n:1-Math.pow(-2*n+2,2)/2),Kc=n=>(n=Ut(n),n*n*n),Qc=n=>{n=Ut(n);let t=1-n;return 1-t*t*t},Zc=n=>(n=Ut(n),n<.5?4*n*n*n:1-Math.pow(-2*n+2,3)/2),aa=2*Math.PI/3,oa=2*Math.PI/4.5,tl=n=>(n=Ut(n),n===0?0:n===1?1:-Math.pow(2,10*n-10)*Math.sin((n*10-10.75)*aa)),el=n=>(n=Ut(n),n===0?0:n===1?1:Math.pow(2,-10*n)*Math.sin((n*10-.75)*aa)+1),nl=n=>(n=Ut(n),n===0?0:n===1?1:n<.5?-(Math.pow(2,20*n-10)*Math.sin((20*n-11.125)*oa))/2:Math.pow(2,-20*n+10)*Math.sin((20*n-11.125)*oa)/2+1),Us=1.70158,Js=Us*1.525,ca=Us+1,sl=n=>(n=Ut(n),ca*n*n*n-Us*n*n),il=n=>{n=Ut(n);let t=n-1;return 1+ca*t*t*t+Us*t*t},ol=n=>(n=Ut(n),n<.5?Math.pow(2*n,2)*((Js+1)*2*n-Js)/2:(Math.pow(2*n-2,2)*((Js+1)*(n*2-2)+Js)+2)/2),rl=n=>Ut(n),ra=Object.freeze({linear:rl,quadIn:Xc,quadOut:Yc,quadInOut:$c,cubicIn:Kc,cubicOut:Qc,cubicInOut:Zc,elasticIn:tl,elasticOut:el,elasticInOut:nl,backIn:sl,backOut:il,backInOut:ol});var al=["linear","quadIn","quadOut","quadInOut","cubicIn","cubicOut","cubicInOut","elasticIn","elasticOut","elasticInOut","backIn","backOut","backInOut"];function cl(n){let t=n&&n.easing;if(!t)return ra;let e=i=>typeof t[i]=="function"?o=>t[i](Ut(o)):ra[i],s={};for(let i of al)s[i]=e(i);return Object.freeze(s)}var $i=class{constructor(t,e,s){let i=s||{};this._time=e,this._windowMs=typeof i.windowMs=="number"&&i.windowMs>0?i.windowMs:120;let o=Array.isArray(i.types)&&i.types.length>0?i.types:Hc;this._records=new Map,this._subs=[],this._disposed=!1;for(let a of o){this._records.set(a,null);let r=t.on(a,c=>{this._records.set(a,c.tMs)});this._subs.push(r)}}consume(t,e){let s=typeof e=="number"?e:this._time.nowMs(),i=this._records.get(t);return i==null?!1:s-i<=this._windowMs?(this._records.set(t,null),!0):(this._records.set(t,null),!1)}peek(t,e){let s=typeof e=="number"?e:this._time.nowMs(),i=this._records.get(t);return i==null?!1:s-i<=this._windowMs}clear(){for(let t of this._records.keys())this._records.set(t,null)}dispose(){if(!this._disposed){for(let t of this._subs)try{t.cancel()}catch(e){}this._subs=[],this._disposed=!0}}};function la(n){let t=n||{},e=null,s=null,i=!1;return{name:"gamefeel",version:"1.0.0",dependencies:[],get inputBuffer(){return e},get easing(){return cl(s)},init(a){let r=a.getInput();e=new $i(r,a.time,{windowMs:t.inputBufferMs,types:t.inputTypes});let c=a.getEngine();s=c?c.math:null},dispose(){i||(e&&(e.dispose(),e=null),s=null,i=!0)}}}function Vs(n,t){let e=t<0?0:t>1?1:t;switch(n&&n.kind){case"constant":return n.value;case"linear":return n.from+(n.to-n.from)*e;case"easeInOut":{let s=e*e*(3-2*e);return n.from+(n.to-n.from)*s}case"decay":{let s=n.power==null?2:n.power,i=Math.pow(1-e,s);return n.to+(n.from-n.to)*i}default:return 0}}var ll=Object.freeze({burst:Object.freeze({mode:"burst",count:24,angle:0,spread:Math.PI,speedMin:80,speedMax:160,lifeMin:.4,lifeMax:.8,gravity:0,drag:0,sizeCurve:{kind:"decay",from:6,to:0,power:1.5},alphaCurve:{kind:"linear",from:1,to:0}}),trail:Object.freeze({mode:"continuous",rate:60,angle:Math.PI,spread:.25,speedMin:20,speedMax:50,lifeMin:.2,lifeMax:.5,gravity:0,drag:1.5,sizeCurve:{kind:"easeInOut",from:4,to:0},alphaCurve:{kind:"decay",from:.8,to:0,power:2}}),drift:Object.freeze({mode:"continuous",rate:12,angle:Math.PI/2,spread:.6,speedMin:10,speedMax:30,lifeMin:1.5,lifeMax:3,gravity:8,drag:.5,sizeCurve:{kind:"constant",value:3},alphaCurve:{kind:"decay",from:.7,to:0,power:1}})});function ul(n){let t=ll[n];return t?Ki(t):null}function Ki(n){let t={};for(let e of Object.keys(n)){let s=n[e];t[e]=s&&typeof s=="object"?Ki(s):s}return t}function hl(n,t,e){let s=n.mode==="continuous";return{pos:{x:t,y:e},angle:n.angle,coneAngle:n.spread,emitSize:0,emitTime:s?0:1/60,emitRate:s?n.rate||0:void 0,count:s?void 0:n.count||0,particleTime:(n.lifeMin+n.lifeMax)/2,speed:(n.speedMin+n.speedMax)/2,gravityScale:n.gravity||0,damping:n.drag!=null?1-n.drag/60:1,sizeStart:Vs(n.sizeCurve,0),sizeEnd:Vs(n.sizeCurve,1),colorStart:{r:1,g:1,b:1,a:Vs(n.alphaCurve,0)},colorEnd:{r:1,g:1,b:1,a:Vs(n.alphaCurve,1)},additive:!1}}function ua(n){let t=n||{},e=null,s=null,i=null,o=new Map,a=0,r={isActive(){return!1},stop(){}},c=0,l=1,u=0,h=0,d=0,f={x:0,y:0,remain:0,dur:0,amplitude:0,frequency:0,_phase:0},y={alpha:0,remain:0,dur:0,peak:0},x={scale:1,remain:0,dur:0,amplitude:0,frequency:0},v=!1;function w(A){if(u>0)if(u-=A,u<=0)u=0,l=1;else{let T=h>0?1-u/h:1;l=d+(1-d)*T}if(f.remain>0)if(f.remain-=A,f.remain<=0)f.remain=0,f.x=0,f.y=0;else{let T=f.remain/f.dur,P=f.amplitude*T;f._phase+=f.frequency*A*Math.PI*2,f.x=Math.sin(f._phase)*P,f.y=Math.cos(f._phase*1.3)*P}if(y.remain>0&&(y.remain-=A,y.remain<=0?(y.remain=0,y.alpha=0):y.alpha=y.peak*(y.remain/y.dur)),x.remain>0)if(x.remain-=A,x.remain<=0)x.remain=0,x.scale=1;else{let T=x.remain/x.dur,P=(1-T)*x.frequency*Math.PI*2;x.scale=1+Math.sin(P)*x.amplitude*T}}function _(A){c+=1,w(A)}function S(A){let T=A!==void 0?A:e?e.getContext2d():null;if(T&&y.alpha>0){T.globalAlpha=y.alpha,T.fillStyle="#ffffff";let P=T.canvas?T.canvas.width:0,k=T.canvas?T.canvas.height:0;T.fillRect(0,0,P,k),T.globalAlpha=1}}return{name:"particles-juice",version:"1.0.0",dependencies:[],init(A){var T;e=A,i=((T=A.getEngine())==null?void 0:T.particles)||null,typeof t.seed=="number"&&A.random.reseed(t.seed),t.autoStep!==!1&&(s=A.onFrame(P=>{_(P)}))},dispose(){v||(s&&(s.cancel(),s=null),o.forEach(A=>{try{A.stop()}catch{}}),o.clear(),l=1,u=0,f.remain=0,f.x=0,f.y=0,y.remain=0,y.alpha=0,x.remain=0,x.scale=1,v=!0)},spawnEmitter(A,T,P,k){let pt=typeof A=="string"?ul(A):Ki(A);if(!pt)return-1;k&&(pt=Object.assign(pt,k));let W=a++;if(!i)return o.set(W,r),W;let $=i.spawnEmitter(hl(pt,T,P));return o.set(W,$),W},stopEmitter(A){let T=o.get(A);if(T)try{T.stop()}catch{}},step(A){_(A)},render(A){S(A)},particleCount(){return 0},emitterCount(){let A=0;for(let T of o.values())T.isActive()&&(A+=1);return A},hitStop(A,T){h=Math.max(0,A),u=h,d=T==null?0:Math.max(0,Math.min(1,T)),l=h>0?d:1},getTimeScale(){return l},shakeScreen(A,T,P){f.dur=Math.max(0,A),f.remain=f.dur,f.amplitude=Math.max(0,T),f.frequency=P==null?30:P,f._phase=0,f.x=0,f.y=0},getShakeOffset(){return{x:f.x,y:f.y}},flashScreen(A,T){y.dur=Math.max(0,A),y.remain=y.dur,y.peak=T==null?.8:Math.max(0,Math.min(1,T)),y.alpha=y.dur>0?y.peak:0},getFlashAlpha(){return y.alpha},pulseScale(A,T,P){x.dur=Math.max(0,A),x.remain=x.dur,x.amplitude=T==null?.2:T,x.frequency=P==null?4:P,x.scale=1},getPulseScale(){return x.scale},juiceSnapshot(){return{timeScale:l,shake:{x:f.x,y:f.y},flashAlpha:y.alpha,pulseScale:x.scale}},probe(){return{particles:0,emitters:o.size,dropped:0,steps:c,disposed:v}}}}function ha(n){let t=mt(n.r)/255,e=mt(n.g)/255,s=mt(n.b)/255,i=Math.max(t,e,s),o=Math.min(t,e,s),a=(i+o)/2,r=0,c=0,l=i-o;return l>1e-12&&(c=a>.5?l/(2-i-o):l/(i+o),i===t?r=(e-s)/l%6:i===e?r=(s-t)/l+2:r=(t-e)/l+4,r*=60,r<0&&(r+=360)),{h:r,s:c,l:a}}function da(n){let t=(n.h%360+360)%360,e=Ke(n.s),s=Ke(n.l);if(e<1e-12){let r=Math.round(s*255);return{r,g:r,b:r}}let i=s<.5?s*(1+e):s+e-s*e,o=2*s-i,a=t/360;return{r:Math.round(Qi(o,i,a+1/3)*255),g:Math.round(Qi(o,i,a)*255),b:Math.round(Qi(o,i,a-1/3)*255)}}function Qi(n,t,e){let s=e;return s<0&&(s+=1),s>1&&(s-=1),s<1/6?n+(t-n)*6*s:s<1/2?t:s<2/3?n+(t-n)*(2/3-s)*6:n}function mt(n){return n<0?0:n>255?255:n}function Ke(n){return n<0?0:n>1?1:n}function dl(n,t){let e=pl(n.from,t);if(e>=0&&e({r:mt(r.r),g:mt(r.g),b:mt(r.b)})),to:o}}function Zi(n,t,e){return n+(t-n)*e}function ml(n,t){let e=ha(n),s=e.h+(t.hue||0),i=Ke(e.s*(t.sat==null?1:t.sat)),o=Ke(e.l*(t.light==null?1:t.light));return da({h:s,s:i,l:o})}var bl=Object.freeze([Object.freeze([0,8,2,10]),Object.freeze([12,4,14,6]),Object.freeze([3,11,1,9]),Object.freeze([15,7,13,5])]);function fa(n){let t=n||{},e=null,s=!1,i={vignette:{enabled:to(t.vignette&&t.vignette.enabled,!1),strength:eo(t.vignette&&t.vignette.strength,.5)},dither:{enabled:to(t.dither&&t.dither.enabled,!1),strength:eo(t.dither&&t.dither.strength,.5)},scanline:{enabled:to(t.scanline&&t.scanline.enabled,!1),strength:eo(t.scanline&&t.scanline.strength,.5)}};function o(r){let c=r!==void 0?r:e?e.getContext2d():null;if(!c)return;let l=c.canvas?c.canvas.width:0,u=c.canvas?c.canvas.height:0;if(i.vignette.enabled&&i.vignette.strength>0&&l>0&&u>0){let h=c.createRadialGradient(l/2,u/2,Math.min(l,u)*.25,l/2,u/2,Math.max(l,u)*.75);h.addColorStop(0,"rgba(0,0,0,0)"),h.addColorStop(1,"rgba(0,0,0,"+i.vignette.strength.toFixed(3)+")"),c.fillStyle=h,c.fillRect(0,0,l,u)}if(i.scanline.enabled&&i.scanline.strength>0&&l>0&&u>0){c.fillStyle="rgba(0,0,0,"+(i.scanline.strength*.5).toFixed(3)+")";for(let h=0;h0&&l>0&&u>0&&typeof c.getImageData=="function"&&typeof c.putImageData=="function"){let h=c.getImageData(0,0,l,u);xl(h,i.dither.strength),c.putImageData(h,0,0)}}return{name:"palette-post",version:"1.0.0",dependencies:[],init(r){e=r},dispose(){s||(e=null,s=!0)},applyPaletteMap(r,c){return dl(r,c)},applyPaletteMapToBuffer(r,c){return fl(r,c)},lerpPaletteMap(r,c,l){return yl(r,c,l)},shiftHsl(r,c){return ml(r,c)},rgbToHsl(r){return ha(r)},hslToRgb(r){return da(r)},setPost(r){if(r)for(let c of["vignette","dither","scanline"])r[c]&&(typeof r[c].enabled=="boolean"&&(i[c].enabled=r[c].enabled),typeof r[c].strength=="number"&&(i[c].strength=Ke(r[c].strength)))},getPost(){return{vignette:{enabled:i.vignette.enabled,strength:i.vignette.strength},dither:{enabled:i.dither.enabled,strength:i.dither.strength},scanline:{enabled:i.scanline.enabled,strength:i.scanline.strength}}},renderPost(r){o(r)},probe(){return{disposed:s,post:this.getPost()}}}}function xl(n,t){let e=Ke(t);if(e<=0)return n;let{data:s,width:i}=n,a=255/(Math.max(2,Math.round(16-e*14))-1);for(let r=0;r+3>2)%i,l=Math.floor((r>>2)/i),u=(bl[l&3][c&3]/16-.5)*a;for(let h=0;h<3;h++){let d=s[r+h]+u,f=Math.round(d/a)*a;s[r+h]=f<0?0:f>255?255:f}}return n}function to(n,t){return typeof n=="boolean"?n:t}function eo(n,t){return typeof n=="number"?Ke(n):t}var so=Object.freeze({blip:Object.freeze({name:"blip",params:Object.freeze([.6,0,880,0,.03,.06,1,1.5])}),thud:Object.freeze({name:"thud",params:Object.freeze([.8,0,90,0,.04,.18,0,1,0,0,0,0,0,4])}),chime:Object.freeze({name:"chime",params:Object.freeze([.5,0,660,.02,.12,.3,1,2])})}),pa=Object.keys(so);function vl(n){let t=[];return n==null||typeof n!="object"?{ok:!1,errors:["song \u5FC5\u987B\u662F\u5BF9\u8C61"]}:(!Array.isArray(n.instruments)||n.instruments.length===0?t.push("instruments \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4"):n.instruments.forEach((e,s)=>{(!Array.isArray(e)||e.some(i=>typeof i!="number"||!Number.isFinite(i)))&&t.push(`instruments[${s}] \u5FC5\u987B\u662F\u6709\u9650\u6570\u5B57\u6570\u7EC4\uFF08ZzFX \u53C2\u6570\u5305\uFF09`)}),!Array.isArray(n.patterns)||n.patterns.length===0?t.push("patterns \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4"):n.patterns.forEach((e,s)=>{if(!Array.isArray(e)||e.length===0){t.push(`patterns[${s}] \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4\uFF08\u81F3\u5C11\u4E00\u4E2A\u58F0\u90E8\u901A\u9053\uFF09`);return}e.forEach((i,o)=>{if(!Array.isArray(i)||i.length<2){t.push(`patterns[${s}][${o}] \u901A\u9053\u81F3\u5C11\u542B [\u4E50\u5668\u7D22\u5F15, \u58F0\u50CF]`);return}if(i.some(c=>typeof c!="number"||!Number.isFinite(c))){t.push(`patterns[${s}][${o}] \u901A\u9053\u5FC5\u987B\u5168\u4E3A\u6709\u9650\u6570\u5B57`);return}let a=i[0]|0;Array.isArray(n.instruments)&&(a<0||a>=n.instruments.length)&&t.push(`patterns[${s}][${o}] \u4E50\u5668\u7D22\u5F15 ${a} \u8D8A\u754C\uFF08instruments \u957F\u5EA6 ${n.instruments.length}\uFF09`);let r=i[1];(r<-1||r>1)&&t.push(`patterns[${s}][${o}] \u58F0\u50CF ${r} \u8D8A\u754C\uFF08\u5E94 -1..+1\uFF09`)})}),!Array.isArray(n.sequence)||n.sequence.length===0?t.push("sequence \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4"):n.sequence.forEach((e,s)=>{if(typeof e!="number"||!Number.isInteger(e)){t.push(`sequence[${s}] \u5FC5\u987B\u662F\u6574\u6570 pattern \u7D22\u5F15`);return}Array.isArray(n.patterns)&&(e<0||e>=n.patterns.length)&&t.push(`sequence[${s}] \u7D22\u5F15 ${e} \u8D8A\u754C\uFF08patterns \u957F\u5EA6 ${n.patterns.length}\uFF09`)}),n.bpm!=null&&(typeof n.bpm!="number"||!(n.bpm>0))&&t.push("bpm \u5FC5\u987B\u662F\u6B63\u6570"),{ok:t.length===0,errors:t})}function ve(n){return typeof n!="number"||Number.isNaN(n)||n<0?0:n>1?1:n}function Sl(n,t){switch(n){case"ease-in":return t*t;case"ease-out":return Math.sqrt(t);case"constant":return 1;default:return t}}function ga(n,t){let e=ve(t);return n==null||!Array.isArray(n.voices)?[]:n.voices.map(s=>{let i=String(s&&s.id!=null?s.id:""),o=Array.isArray(s&&s.channelIndices)?s.channelIndices.slice():[],a=typeof s.minIntensity=="number"?ve(s.minIntensity):0,r=typeof s.maxIntensity=="number"?ve(s.maxIntensity):1,c=typeof s.volumeCurve=="string"?s.volumeCurve:"linear",l=typeof s.baseVolume=="number"?ve(s.baseVolume):1;if(er)return{id:i,on:!1,volume:0,channelIndices:o};let u=r-a,h=u<=0?1:(e-a)/u,d=ve(Sl(c,h)*l);return{id:i,on:!0,volume:d,channelIndices:o}})}function ya(n,t,e,s){try{let i=t[0]||[],o=t[1]||i,a=Math.max(i.length,o.length);if(a===0)return null;let c=n.createBuffer(2,a,44100);c.getChannelData(0).set(i),c.getChannelData(1).set(o.length?o:i);let l=n.createBufferSource();l.buffer=c,l.loop=!!s;let u=n.createGain();return u.gain.value=ve(e*.3),l.connect(u),u.connect(n.destination),l.start(),{stop(){try{l.stop()}catch(h){}try{l.disconnect(),u.disconnect()}catch(h){}}}}catch(i){return io("[audio-music] \u53D7\u63A7\u97F3\u9891\u64AD\u653E\u5F02\u5E38\uFF0C\u964D\u7EA7\u4E3A\u9759\u9ED8",i),null}}function ma(n){let t=n||{},e=typeof t.masterVolume=="number"?ve(t.masterVolume):1,s=()=>null,i=null,o=null,a={voices:[]},r=1,c=null,l=!1,u=0,h=!1,d=!1;function f(){let S=s();return S==null?(u+=1,h||(no("[audio-music] \u65E0\u53D7\u63A7\u97F3\u9891\u4E0A\u4E0B\u6587\uFF08getAudioContext \u8FD4\u56DE null\uFF09\uFF0C\u5168\u90E8\u53D1\u58F0\u9759\u9ED8 no-op\uFF08\u8BC4\u4F30\u73AF\u5883\u65E0\u58F0\u5361\u65F6\u7684\u5BB9\u9519\u964D\u7EA7\uFF09"),h=!0),null):S}function y(){if(!o||!i)return null;try{let S=typeof o.bpm=="number"&&o.bpm>0?o.bpm:125;return i.synthSong(o.instruments,o.patterns,o.sequence,S)}catch(S){return io("[audio-music] \u66F2\u8C31\u6E32\u67D3\u5F02\u5E38\uFF0C\u964D\u7EA7\u4E3A\u9759\u9ED8",S),null}}function x(){let S=ga(a,r);if(S.length===0)return 1;let C=0;for(let A of S)A.on&&(C=Math.max(C,A.volume));return C}function v(S,C){typeof C=="number"&&(r=ve(C));let A=f();if(A==null||!o)return;w();let T=y();if(!T)return;let P=ve(e*x());c=ya(A,T,P,S),l=!!S&&c!=null}function w(){c&&(c.stop(),c=null),l=!1}return{name:"audio-music",version:"1.0.0",dependencies:[],init(S){s=()=>S.getAudioContext();let C=S.getEngine&&S.getEngine();i=C?C.audio.synth:null},dispose(){d||(w(),d=!0)},loadSong(S){let C=vl(S);return C.ok?o={instruments:S.instruments,patterns:S.patterns,sequence:S.sequence,bpm:typeof S.bpm=="number"?S.bpm:125}:no("[audio-music] \u66F2\u8C31\u6821\u9A8C\u5931\u8D25\uFF0C\u672A\u8F7D\u5165\uFF1A"+C.errors.join("\uFF1B")),C},play(S){v(!1,S)},stop(){w()},loop(S){v(!0,S)},setIntensityLayering(S){a=S&&Array.isArray(S.voices)?{voices:S.voices}:{voices:[]}},setIntensity(S){r=ve(S)},resolveVoices(S){return ga(a,S)},playSfx(S){let C=so[S];if(!C){no("[audio-music] \u672A\u77E5\u97F3\u6548\u9884\u8BBE\uFF1A"+String(S));return}let A=f();if(A!=null)try{let T=i?i.synthSfx(C.params):null;if(!T)return;ya(A,[T,T],e,!1)}catch(T){io("[audio-music] \u97F3\u6548\u64AD\u653E\u5F02\u5E38\uFF0C\u964D\u7EA7\u4E3A\u9759\u9ED8 name="+S,T)}},getPreset(S){return so[S]},listPresets(){return pa.slice()},probe(){return{hasAudio:s()!=null,hasSong:o!=null,intensity:r,voiceCount:a.voices.length,looping:l,silentNoops:u,presetCount:pa.length}}}}function io(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function no(n){typeof console!="undefined"&&typeof console.warn=="function"&&console.warn(n)}var wl="zaomeng.save";function Tl(n){if(typeof TextEncoder!="undefined")return new TextEncoder().encode(n).length;if(typeof Buffer!="undefined"&&typeof Buffer.byteLength=="function")return Buffer.byteLength(n,"utf8");let t=0;for(let e=0;e=55296&&s<=56319?(t+=4,e++):t+=3}return t}function ro(){let n=new Map;return{getItem(t){return n.has(t)?n.get(t):null},setItem(t,e){n.set(t,e)},removeItem(t){n.delete(t)},keys(){return Array.from(n.keys())}}}function ba(){if(typeof localStorage=="undefined")throw new Error("[save-progress] createLocalStorageAdapter \u9700\u8981\u5168\u5C40 localStorage\uFF08\u4EC5\u6D4F\u89C8\u5668\u96C6\u6210\u6BB5\u53EF\u7528\uFF09\u3002node/host-dev \u8BF7\u7528\u7F3A\u7701\u5185\u5B58 adapter \u6216 createMemoryAdapter()\u3002");return{getItem(n){return localStorage.getItem(n)},setItem(n,t){localStorage.setItem(n,t)},removeItem(n){localStorage.removeItem(n)},keys(){let n=[];for(let t=0;t0?t.namespace:wl;if(e.indexOf(":")>=0)throw new Error('[save-progress] namespace \u4E0D\u5F97\u542B\u5206\u9694\u7B26 ":"\uFF08\u5F53\u524D="'+e+'"\uFF09');let s=typeof t.maxValueBytes=="number"&&t.maxValueBytes>0?Math.floor(t.maxValueBytes):32768,i=!Al(t.adapter),o=i?ro():t.adapter,a=e+":",r=0,c=0,l=!1;function u(f){return typeof f!="string"||f.length===0?a+String(f):a+f}function h(){try{let f=o.keys();return Array.isArray(f)?f.filter(y=>typeof y=="string"&&y.indexOf(a)===0):[]}catch(f){return es("[save-progress] adapter.keys() \u5F02\u5E38\uFF0C\u964D\u7EA7\u8FD4\u56DE\u7A7A\u96C6",f),[]}}return{name:"save-progress",version:"1.0.0",dependencies:[],init(f){h()},dispose(){},get(f,y){if(!oo(f))return y;let x;try{x=o.getItem(u(f))}catch(v){return es("[save-progress] adapter.getItem \u5F02\u5E38\uFF0C\u8FD4\u56DE\u9ED8\u8BA4\u503C key="+f,v),y}if(x==null)return y;try{return JSON.parse(x)}catch{return r+=1,l||(ns("[save-progress] \u68C0\u6D4B\u5230\u635F\u574F\u5B58\u6863\uFF08\u975E\u6CD5 JSON\uFF09\uFF0C\u5DF2\u5BB9\u9519\u56DE\u9000\u9ED8\u8BA4\u503C key="+f),l=!0),y}},set(f,y){if(!oo(f))return ns("[save-progress] set \u6536\u5230\u975E\u6CD5 key\uFF0C\u62D2\u7EDD\u5199\u5165\uFF1A"+String(f)),!1;let x;try{x=JSON.stringify(y)}catch{return c+=1,ns("[save-progress] \u503C\u4E0D\u53EF JSON \u5E8F\u5217\u5316\uFF08\u5FAA\u73AF\u5F15\u7528?\uFF09\uFF0C\u62D2\u7EDD\u5199\u5165 key="+f),!1}if(x===void 0)return c+=1,ns("[save-progress] \u503C\u5E8F\u5217\u5316\u4E3A undefined\uFF08\u5982\u7EAF undefined/\u51FD\u6570\uFF09\uFF0C\u62D2\u7EDD\u5199\u5165 key="+f),!1;let v=Tl(x);if(v>s)return c+=1,ns("[save-progress] \u503C\u8D85\u5B57\u8282\u4E0A\u9650\u62D2\u7EDD\u5199\u5165 key="+f+"\uFF08"+v+" > "+s+" bytes\uFF09"),!1;try{return o.setItem(u(f),x),!0}catch(w){return c+=1,es("[save-progress] adapter.setItem \u5F02\u5E38\uFF0C\u5199\u5165\u5931\u8D25 key="+f,w),!1}},remove(f){if(oo(f))try{o.removeItem(u(f))}catch(y){es("[save-progress] adapter.removeItem \u5F02\u5E38\uFF08\u5DF2\u5FFD\u7565\uFF09key="+f,y)}},clear(){let f=h(),y=0;for(let x of f)try{o.removeItem(x),y+=1}catch(v){es("[save-progress] clear \u65F6 removeItem \u5F02\u5E38\uFF08\u5DF2\u8DF3\u8FC7\uFF09fullKey="+x,v)}return y},probe(){return{namespace:e,maxValueBytes:s,usingMemoryAdapter:i,size:h().length,corruptRecoveries:r,rejectedWrites:c}}}}function oo(n){return typeof n=="string"&&n.length>0}function Al(n){return!!n&&typeof n.getItem=="function"&&typeof n.setItem=="function"&&typeof n.removeItem=="function"&&typeof n.keys=="function"}function es(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function ns(n){typeof console!="undefined"&&typeof console.warn=="function"&&console.warn(n)}var El={w:390,h:844};function va(n){let t=((n&&n.seed)!=null?n.seed:0)>>>0,e=sa({cellSize:96}),s=ia(),i=la({inputBufferMs:260,inputTypes:["pointerdown"]}),o=ua({seed:t,maxParticles:600}),a=fa({vignette:{enabled:!0,strength:.22}}),r=ma({masterVolume:.8}),c;try{c=ba()}catch(d){console.warn("[generic] localStorage \u4E0D\u53EF\u7528\uFF0C\u5B58\u6863\u9000\u5185\u5B58 adapter\uFF1A"+(d&&d.message)),c=ro()}let l=xa({namespace:"zaomeng-generic",adapter:c});return{plugins:{collision:e,physics:s,gamefeel:i,juice:o,palettePost:a,audioMusic:r,save:l},registerOrder:[e,s,i,o,a,l,r],viewport:El,buildFactoryOpts:(d,f)=>({runtime:{plugins:f.plugins,bundle:f.bundle,getRealAudioCtx:f.getRealAudioCtx}})}}function ss(n){let t=n||{},e=null,s=0,i=0,o={left:!1,right:!1,up:!1,space:!1},a=[],r="booting",c=null,l=0,u=[],h=[],d={x:195,y:422,angle:-Math.PI/2,vx:0,vy:0},f=300,y=.99,x=3,v=15,w=500,_=2,S=3,C=.15,A=0,T=30,P=15,k=50,pt=120,W=390,$=844,gt=4;function zt(){return{seed:t.seed||null,state:()=>({phase:r,result:c,score:l,asteroidsRemaining:u.filter(L=>L.active).length,ship:{x:d.x,y:d.y,angle:d.angle},asteroids:u.filter(L=>L.active).map(L=>({x:L.x,y:L.y}))})}}function me(L,X){return Math.hypot(L.x-X.x,L.y-X.y)}function Jt(L,X,N,yt){let vt=X.x-L.x,Mt=X.y-L.y,M=L.x-N.x,Z=L.y-N.y,Ct=vt*vt+Mt*Mt;if(Ct===0)return me(L,N)<=yt;let kt=2*(M*vt+Z*Mt),ht=M*M+Z*Z-yt*yt,Ie=kt*kt-4*Ct*ht;if(Ie<0)return!1;Ie=Math.sqrt(Ie);let gn=(-kt-Ie)/(2*Ct),Me=(-kt+Ie)/(2*Ct);return gn>=0&&gn<=1||Me>=0&&Me<=1}function rt(L,X,N,yt){let vt=e.getEngine();if(vt&&vt.particles)try{vt.particles.spawnEmitter({pos:{x:L,y:X},count:N||20,speed:100,particleTime:.6,sizeStart:8,sizeEnd:0,colorStart:yt||{r:1,g:.8,b:.2,a:1},colorEnd:{r:1,g:.3,b:0,a:0}})}catch{}}function Tt(L){let X=e.getEngine();if(X&&X.audio&&X.audio.synth)try{X.audio.synth.synthSfx(L)}catch{}}function be(){r="playing",c=null,l=0,h=[],d={x:195,y:422,angle:-Math.PI/2,vx:0,vy:0},A=0,u=[];for(let L=0;L<6;L++){let X,N;do X=e.random.range(30,W-30),N=e.random.range(30,$-30);while(me({x:X,y:N},d)<150);let yt=e.random.range(0,Math.PI*2),vt=e.random.range(k,pt);u.push({x:X,y:N,vx:Math.cos(yt)*vt,vy:Math.sin(yt)*vt,radius:T,active:!0})}}function fn(){let L=Math.cos(d.angle),X=Math.sin(d.angle),N=d.x+L*(v+5),yt=d.y+X*(v+5);h.push({x:N,y:yt,prevX:N,prevY:yt,vx:L*w,vy:X*w,life:_}),rt(N,yt,12,{r:.5,g:.9,b:1,a:1}),Tt([1,.02,880,,.02,.1,,.4,-.1])}function pn(L){e=L.ctx;let X=t.seed;X!=null&&e.random.reseed(X);let N=ht=>{switch(ht.key){case"ArrowLeft":o.left=!0;break;case"ArrowRight":o.right=!0;break;case"ArrowUp":o.up=!0;break;case" ":o.space=!0;break}},yt=ht=>{switch(ht.key){case"ArrowLeft":o.left=!1;break;case"ArrowRight":o.right=!1;break;case"ArrowUp":o.up=!1;break;case" ":o.space=!1;break}},vt=ht=>{r==="gameover"&&be()},Mt=e.getInput(),M=Mt.on("keydown",N),Z=Mt.on("keyup",yt),Ct=Mt.on("pointerdown",vt);a=[M,Z,Ct],be();let kt=e.getEngine();if(kt&&kt.particles)try{kt.particles.spawnEmitter({pos:{x:195,y:400},emitRate:8,emitTime:0,particleTime:.8,speed:30,sizeStart:4,sizeEnd:0,colorStart:{r:.2,g:.6,b:1,a:.5},colorEnd:{r:.1,g:.3,b:.5,a:0}})}catch{}}function le(L){if(s=e.time.nowMs(),i=s/1e3,r!=="playing")return;o.left&&(d.angle-=x*L),o.right&&(d.angle+=x*L),o.up&&(d.vx+=Math.cos(d.angle)*f*L,d.vy+=Math.sin(d.angle)*f*L),o.space&&A<=0&&(fn(),A=C),A-=L,d.vx*=y,d.vy*=y,d.x+=d.vx*L,d.y+=d.vy*L,d.x<0&&(d.x+=W),d.x>W&&(d.x-=W),d.y<0&&(d.y+=$),d.y>$&&(d.y-=$);let X=L/gt;for(let M=0;MW+100||Z.y<-100||Z.y>$+100){N.push(M);continue}let Ct=!1;for(let kt=0;kt=0;M--)h.splice(N[M],1);for(let M of yt)u.push(M);l+=vt;for(let M of u)M.active&&(M.x+=M.vx*L,M.y+=M.vy*L,M.x<-M.radius&&(M.x+=W+2*M.radius),M.x>W+M.radius&&(M.x-=W+2*M.radius),M.y<-M.radius&&(M.y+=$+2*M.radius),M.y>$+M.radius&&(M.y-=$+2*M.radius));for(let M of u)if(M.active&&me(d,M)M.active)&&u.length>0&&(r="gameover",c="win",rt(d.x,d.y,60,{r:.3,g:1,b:.5,a:1}),Tt([1,.05,523,,.05,.2,,.5]))}function De(L){L.fillStyle="#0a0a1a",L.fillRect(0,0,W,$);for(let N of u)N.active&&(L.fillStyle="#888899",L.beginPath(),L.arc(N.x,N.y,N.radius,0,Math.PI*2),L.fill(),L.strokeStyle="#aabbcc",L.lineWidth=2,L.stroke());for(let N of h)L.fillStyle="#ffff00",L.beginPath(),L.arc(N.x,N.y,S,0,Math.PI*2),L.fill();L.save(),L.translate(d.x,d.y),L.rotate(d.angle),L.fillStyle="#00ddff",L.beginPath(),L.moveTo(0,-v),L.lineTo(-v*.7,v*.8),L.lineTo(v*.7,v*.8),L.closePath(),L.fill(),o.up&&(L.fillStyle="#ff8800",L.beginPath(),L.moveTo(-5,v*.5),L.lineTo(0,v*1.2),L.lineTo(5,v*.5),L.closePath(),L.fill()),L.restore(),L.fillStyle="#ffffff",L.font="18px monospace",L.fillText("Score: "+l,10,30);let X=u.filter(N=>N.active).length;L.fillText("Asteroids: "+X,10,55),r==="gameover"&&(L.font="bold 36px monospace",L.fillStyle=c==="win"?"#66ff88":"#ff6666",L.textAlign="center",L.fillText(c==="win"?"YOU WIN!":"GAME OVER",W/2,$/2-40),L.font="20px monospace",L.fillStyle="#aaaaaa",L.fillText("Click to restart",W/2,$/2+20),L.textAlign="left")}function ne(){for(let L of a)try{L.cancel()}catch{}a=[],h=[],u=[]}return{init:pn,update:le,render:De,destroy:ne,_forensicsView:zt}}var pd=ss,gd=ss;async function yd(n){let t=n||{},e=t.engine||await Promise.resolve().then(()=>(Mc(),Ic)),s=(t.seed!=null?t.seed:305441741)>>>0,i=va({seed:s});return na({canvas:t.canvas,statusEl:t.statusEl||null,engine:e,seed:s,mode:t.mode||"play",engineMode:"real",viewport:i.viewport,factory:ss,plugins:i.plugins,registerOrder:i.registerOrder,buildFactoryOpts:i.buildFactoryOpts,recHook:t.recHook||null,onReady:t.onReady||null})}return Bc(md);})();
diff --git a/game-runtime/games/_wg1-gen/asteroids/bundle.iife.js.meta.json b/game-runtime/games/_wg1-gen/asteroids/bundle.iife.js.meta.json
index 54a7023c..d3e0bf34 100644
--- a/game-runtime/games/_wg1-gen/asteroids/bundle.iife.js.meta.json
+++ b/game-runtime/games/_wg1-gen/asteroids/bundle.iife.js.meta.json
@@ -1 +1 @@
-{"inputs":{"src/core/plugin.js":{"bytes":44317,"imports":[],"format":"esm"},"src/plugins/runtime-probe/impl.js":{"bytes":16639,"imports":[],"format":"esm"},"host-dev/engine-caps.js":{"bytes":13897,"imports":[],"format":"esm"},"host-dev/engine-math.js":{"bytes":6155,"imports":[],"format":"esm"},"src/host/boot-game-host.js":{"bytes":28239,"imports":[{"path":"src/core/plugin.js","kind":"import-statement","original":"../core/plugin.js"},{"path":"src/plugins/runtime-probe/impl.js","kind":"import-statement","original":"../plugins/runtime-probe/impl.js"},{"path":"host-dev/engine-caps.js","kind":"import-statement","original":"../../host-dev/engine-caps.js"},{"path":"host-dev/engine-math.js","kind":"import-statement","original":"../../host-dev/engine-math.js"}],"format":"esm"},"src/plugins/collision/impl.js":{"bytes":24812,"imports":[],"format":"esm"},"src/plugins/physics-lite/impl.js":{"bytes":14507,"imports":[],"format":"esm"},"src/plugins/gamefeel/impl.js":{"bytes":21715,"imports":[],"format":"esm"},"src/plugins/particles-juice/impl.js":{"bytes":31830,"imports":[],"format":"esm"},"src/plugins/palette-post/impl.js":{"bytes":20240,"imports":[],"format":"esm"},"src/plugins/audio-music/impl.js":{"bytes":24659,"imports":[],"format":"esm"},"src/plugins/save-progress/impl.js":{"bytes":14608,"imports":[],"format":"esm"},"src/host/generic-host-config.js":{"bytes":7803,"imports":[{"path":"src/plugins/collision/impl.js","kind":"import-statement","original":"../plugins/collision/impl.js"},{"path":"src/plugins/physics-lite/impl.js","kind":"import-statement","original":"../plugins/physics-lite/impl.js"},{"path":"src/plugins/gamefeel/impl.js","kind":"import-statement","original":"../plugins/gamefeel/impl.js"},{"path":"src/plugins/particles-juice/impl.js","kind":"import-statement","original":"../plugins/particles-juice/impl.js"},{"path":"src/plugins/palette-post/impl.js","kind":"import-statement","original":"../plugins/palette-post/impl.js"},{"path":"src/plugins/audio-music/impl.js","kind":"import-statement","original":"../plugins/audio-music/impl.js"},{"path":"src/plugins/save-progress/impl.js","kind":"import-statement","original":"../plugins/save-progress/impl.js"}],"format":"esm"},"games/_wg1-gen/asteroids/generated-factory.js":{"bytes":9418,"imports":[],"format":"esm"},"node_modules/littlejsengine/dist/littlejs.esm.js":{"bytes":640153,"imports":[],"format":"esm"},"games/_wg1-gen/asteroids/entry-bundle.js":{"bytes":6230,"imports":[{"path":"src/host/boot-game-host.js","kind":"import-statement","original":"../../../src/host/boot-game-host.js"},{"path":"src/host/generic-host-config.js","kind":"import-statement","original":"../../../src/host/generic-host-config.js"},{"path":"games/_wg1-gen/asteroids/generated-factory.js","kind":"import-statement","original":"./generated-factory.js"},{"path":"node_modules/littlejsengine/dist/littlejs.esm.js","kind":"dynamic-import","original":"littlejsengine"}],"format":"esm"}},"outputs":{"games/_wg1-gen/asteroids/bundle.iife.js":{"imports":[],"exports":[],"entryPoint":"games/_wg1-gen/asteroids/entry-bundle.js","inputs":{"node_modules/littlejsengine/dist/littlejs.esm.js":{"bytesInOutput":164254},"games/_wg1-gen/asteroids/entry-bundle.js":{"bytesInOutput":507},"src/core/plugin.js":{"bytesInOutput":8989},"src/plugins/runtime-probe/impl.js":{"bytesInOutput":2794},"host-dev/engine-caps.js":{"bytesInOutput":1597},"host-dev/engine-math.js":{"bytesInOutput":498},"src/host/boot-game-host.js":{"bytesInOutput":5505},"src/plugins/collision/impl.js":{"bytesInOutput":1605},"src/plugins/physics-lite/impl.js":{"bytesInOutput":115},"src/plugins/gamefeel/impl.js":{"bytesInOutput":2533},"src/plugins/particles-juice/impl.js":{"bytesInOutput":4166},"src/plugins/palette-post/impl.js":{"bytesInOutput":4216},"src/plugins/audio-music/impl.js":{"bytesInOutput":6001},"src/plugins/save-progress/impl.js":{"bytesInOutput":3933},"src/host/generic-host-config.js":{"bytesInOutput":697},"games/_wg1-gen/asteroids/generated-factory.js":{"bytesInOutput":4408}},"bytes":212389}}}
\ No newline at end of file
+{"inputs":{"src/core/plugin.js":{"bytes":44317,"imports":[],"format":"esm"},"src/plugins/runtime-probe/impl.js":{"bytes":16639,"imports":[],"format":"esm"},"host-dev/engine-caps.js":{"bytes":13897,"imports":[],"format":"esm"},"host-dev/engine-math.js":{"bytes":6155,"imports":[],"format":"esm"},"src/host/boot-game-host.js":{"bytes":28239,"imports":[{"path":"src/core/plugin.js","kind":"import-statement","original":"../core/plugin.js"},{"path":"src/plugins/runtime-probe/impl.js","kind":"import-statement","original":"../plugins/runtime-probe/impl.js"},{"path":"host-dev/engine-caps.js","kind":"import-statement","original":"../../host-dev/engine-caps.js"},{"path":"host-dev/engine-math.js","kind":"import-statement","original":"../../host-dev/engine-math.js"}],"format":"esm"},"src/plugins/collision/impl.js":{"bytes":24812,"imports":[],"format":"esm"},"src/plugins/physics-lite/impl.js":{"bytes":14507,"imports":[],"format":"esm"},"src/plugins/gamefeel/impl.js":{"bytes":21715,"imports":[],"format":"esm"},"src/plugins/particles-juice/impl.js":{"bytes":31830,"imports":[],"format":"esm"},"src/plugins/palette-post/impl.js":{"bytes":20240,"imports":[],"format":"esm"},"src/plugins/audio-music/impl.js":{"bytes":24659,"imports":[],"format":"esm"},"src/plugins/save-progress/impl.js":{"bytes":14608,"imports":[],"format":"esm"},"src/host/generic-host-config.js":{"bytes":7803,"imports":[{"path":"src/plugins/collision/impl.js","kind":"import-statement","original":"../plugins/collision/impl.js"},{"path":"src/plugins/physics-lite/impl.js","kind":"import-statement","original":"../plugins/physics-lite/impl.js"},{"path":"src/plugins/gamefeel/impl.js","kind":"import-statement","original":"../plugins/gamefeel/impl.js"},{"path":"src/plugins/particles-juice/impl.js","kind":"import-statement","original":"../plugins/particles-juice/impl.js"},{"path":"src/plugins/palette-post/impl.js","kind":"import-statement","original":"../plugins/palette-post/impl.js"},{"path":"src/plugins/audio-music/impl.js","kind":"import-statement","original":"../plugins/audio-music/impl.js"},{"path":"src/plugins/save-progress/impl.js","kind":"import-statement","original":"../plugins/save-progress/impl.js"}],"format":"esm"},"games/_wg1-gen/asteroids/generated-factory.js":{"bytes":12427,"imports":[],"format":"esm"},"node_modules/littlejsengine/dist/littlejs.esm.js":{"bytes":640153,"imports":[],"format":"esm"},"games/_wg1-gen/asteroids/entry-bundle.js":{"bytes":6230,"imports":[{"path":"src/host/boot-game-host.js","kind":"import-statement","original":"../../../src/host/boot-game-host.js"},{"path":"src/host/generic-host-config.js","kind":"import-statement","original":"../../../src/host/generic-host-config.js"},{"path":"games/_wg1-gen/asteroids/generated-factory.js","kind":"import-statement","original":"./generated-factory.js"},{"path":"node_modules/littlejsengine/dist/littlejs.esm.js","kind":"dynamic-import","original":"littlejsengine"}],"format":"esm"}},"outputs":{"games/_wg1-gen/asteroids/bundle.iife.js":{"imports":[],"exports":[],"entryPoint":"games/_wg1-gen/asteroids/entry-bundle.js","inputs":{"node_modules/littlejsengine/dist/littlejs.esm.js":{"bytesInOutput":164259},"games/_wg1-gen/asteroids/entry-bundle.js":{"bytesInOutput":507},"src/core/plugin.js":{"bytesInOutput":8989},"src/plugins/runtime-probe/impl.js":{"bytesInOutput":2794},"host-dev/engine-caps.js":{"bytesInOutput":1597},"host-dev/engine-math.js":{"bytesInOutput":498},"src/host/boot-game-host.js":{"bytesInOutput":5498},"src/plugins/collision/impl.js":{"bytesInOutput":1605},"src/plugins/physics-lite/impl.js":{"bytesInOutput":115},"src/plugins/gamefeel/impl.js":{"bytesInOutput":2533},"src/plugins/particles-juice/impl.js":{"bytesInOutput":4159},"src/plugins/palette-post/impl.js":{"bytesInOutput":4216},"src/plugins/audio-music/impl.js":{"bytesInOutput":6001},"src/plugins/save-progress/impl.js":{"bytesInOutput":3933},"src/host/generic-host-config.js":{"bytesInOutput":697},"games/_wg1-gen/asteroids/generated-factory.js":{"bytesInOutput":5137}},"bytes":213109}}}
\ No newline at end of file
diff --git a/game-runtime/games/_wg1-gen/asteroids/evidence/after-play.png b/game-runtime/games/_wg1-gen/asteroids/evidence/after-play.png
index d20f0470..57b619d3 100644
Binary files a/game-runtime/games/_wg1-gen/asteroids/evidence/after-play.png and b/game-runtime/games/_wg1-gen/asteroids/evidence/after-play.png differ
diff --git a/game-runtime/games/_wg1-gen/asteroids/evidence/first-paint.png b/game-runtime/games/_wg1-gen/asteroids/evidence/first-paint.png
index 524e598a..066750e1 100644
Binary files a/game-runtime/games/_wg1-gen/asteroids/evidence/first-paint.png and b/game-runtime/games/_wg1-gen/asteroids/evidence/first-paint.png differ
diff --git a/game-runtime/games/_wg1-gen/asteroids/evidence/verdict.json b/game-runtime/games/_wg1-gen/asteroids/evidence/verdict.json
index c2fbe710..65d4ccb0 100644
--- a/game-runtime/games/_wg1-gen/asteroids/evidence/verdict.json
+++ b/game-runtime/games/_wg1-gen/asteroids/evidence/verdict.json
@@ -8,9 +8,9 @@
     },
     "C_frame": {
       "pass": true,
-      "f0": 48,
-      "f1": 78,
-      "delta": 30
+      "f0": 49,
+      "f1": 80,
+      "delta": 31
     },
     "I_control": {
       "pass": true,
@@ -18,13 +18,13 @@
     },
     "D_render": {
       "pass": true,
-      "bright": 66491,
+      "bright": 73961,
       "maxCh": 255
     },
     "E_live": {
       "pass": true,
-      "distinctStates": 37,
-      "samples": 37
+      "distinctStates": 81,
+      "samples": 81
     },
     "B_uncaught": {
       "pass": true,
@@ -32,19 +32,19 @@
     },
     "F_wiring": {
       "pass": true,
-      "callCount": 27,
+      "callCount": 41,
       "sample": [
         "particles.spawnEmitter",
         "particles.spawnEmitter",
+        "audio.synth.synthSfx",
         "particles.spawnEmitter",
+        "audio.synth.synthSfx",
         "particles.spawnEmitter",
+        "audio.synth.synthSfx",
         "particles.spawnEmitter",
+        "audio.synth.synthSfx",
         "particles.spawnEmitter",
-        "particles.spawnEmitter",
-        "particles.spawnEmitter",
-        "particles.spawnEmitter",
-        "particles.spawnEmitter",
-        "particles.spawnEmitter",
+        "audio.synth.synthSfx",
         "particles.spawnEmitter"
       ],
       "expected": [
@@ -54,21 +54,21 @@
     },
     "G_input": {
       "pass": true,
-      "inputHash": "d2d3585d",
-      "controlHash": "f13eb61f",
-      "atFrame": 901,
-      "ctrlFrame": 905
+      "inputHash": "abb370ce",
+      "controlHash": "38e0cc7c",
+      "atFrame": 1581,
+      "ctrlFrame": -1
     },
     "H_progress": {
-      "pass": false,
+      "pass": true,
       "checks": [
         {
           "path": "score",
           "op": "increased",
           "before": 0,
-          "after": 0,
-          "pass": false,
-          "why": "循环旋转+推进+开火→击碎陨石得分上升;若高速子弹穿透(CCD缺)或打不中则不升=暴露 CCD 缺口"
+          "after": 6,
+          "pass": true,
+          "why": "aim-fire 读陨石坐标旋向对齐开火→击碎得分上升;若游戏不暴露陨石坐标致盲射则不升=可测性边界"
         }
       ],
       "latch": {
@@ -81,26 +81,78 @@
         "phase": "playing",
         "result": null,
         "score": 0,
-        "asteroidsRemaining": 5,
+        "asteroidsRemaining": 6,
         "ship": {
           "x": 195,
           "y": 422,
           "angle": -1.5707963267948966
-        }
+        },
+        "asteroids": [
+          {
+            "x": 96.99717124909638,
+            "y": 519.2675040247642
+          },
+          {
+            "x": 319.4950147635825,
+            "y": 629.6736080402688
+          },
+          {
+            "x": 1.5485410220474345,
+            "y": 718.9562386134752
+          },
+          {
+            "x": 73.61813029544744,
+            "y": 761.5286812129356
+          },
+          {
+            "x": 337.5254555930884,
+            "y": 529.2215852456798
+          },
+          {
+            "x": 324.4826751629315,
+            "y": 697.42908304362
+          }
+        ]
       },
       "state1": {
         "phase": "gameover",
         "result": "lose",
-        "score": 0,
-        "asteroidsRemaining": 5,
+        "score": 6,
+        "asteroidsRemaining": 6,
         "ship": {
-          "x": 152.8208837988882,
-          "y": 301.88159315392096,
-          "angle": -1.7707963267948967
-        }
+          "x": 195,
+          "y": 422,
+          "angle": -3.120796326794893
+        },
+        "asteroids": [
+          {
+            "x": -27.856391456713904,
+            "y": 735.1075081715107
+          },
+          {
+            "x": 116.74067642420584,
+            "y": 770.5545437859361
+          },
+          {
+            "x": 166.3536431747016,
+            "y": 455.6770210725548
+          },
+          {
+            "x": 272.7968611275529,
+            "y": 641.2863973557977
+          },
+          {
+            "x": 171.07105373838698,
+            "y": 848.8609648800336
+          },
+          {
+            "x": 213.6553002398836,
+            "y": 87.47766219533963
+          }
+        ]
       }
     }
   },
-  "pass": false,
+  "pass": true,
   "notes": []
 }
\ No newline at end of file
diff --git a/game-runtime/games/_wg1-gen/asteroids/generated-factory.js b/game-runtime/games/_wg1-gen/asteroids/generated-factory.js
index 75402d26..e69f544b 100644
--- a/game-runtime/games/_wg1-gen/asteroids/generated-factory.js
+++ b/game-runtime/games/_wg1-gen/asteroids/generated-factory.js
@@ -1,107 +1,95 @@
 'use strict';
-export default function createAsteroidsGame(opts) {
+
+export default function createGame(opts) {
   const o = opts || {};
   let ctx = null;
-  let subHandlers = [];
+  let nowMs = 0;
+  let t = 0;
+
+  // input held state
+  const held = { left: false, right: false, up: false, space: false };
+  let inputSubs = [];
 
   // game state
-  let phase = 'booting';
-  let result = null;
+  let phase = 'booting'; // 'playing' | 'gameover'
+  let result = null; // 'win' | 'lose' | null
   let score = 0;
-  let ship = { x:0, y:0, vx:0, vy:0, angle:0, radius:15 };
   let asteroids = [];
   let bullets = [];
-  let lastFireTime = 0;
-  let keyState = {};
-
-  const FIRE_COOLDOWN = 200;
-  const BULLET_SPEED = 600;
-  const BULLET_LIFETIME = 2000;
-  const FRICTION = 0.99;
+  let ship = { x: 195, y: 422, angle: -Math.PI / 2, vx: 0, vy: 0 };
+  const SHIP_ACCEL = 300;
+  const SHIP_FRICTION = 0.99;
+  const SHIP_ROTATION_SPEED = 3;
   const SHIP_RADIUS = 15;
-  const BIG_ASTEROID_RADIUS = 30;
-  const SMALL_ASTEROID_RADIUS = 15;
-  const ASTEROID_SPEED_MIN = 40;
-  const ASTEROID_SPEED_MAX = 80;
-  const INITIAL_ASTEROIDS = 5;
-  const THRUST = 200;
-  const ROTATION_SPEED = 3.0;
 
-  // helpers
-  function wrapPos(p) {
-    if (p.x < 0) p.x += 390;
-    else if (p.x > 390) p.x -= 390;
-    if (p.y < 0) p.y += 844;
-    else if (p.y > 844) p.y -= 844;
+  const BULLET_SPEED = 500;
+  const BULLET_LIFETIME = 2;
+  const BULLET_RADIUS = 3;
+  const FIRE_COOLDOWN = 0.15; // seconds
+  let fireTimer = 0;
+
+  const ASTEROID_LARGE_RADIUS = 30;
+  const ASTEROID_SMALL_RADIUS = 15;
+  const ASTEROID_SPEED_MIN = 50;
+  const ASTEROID_SPEED_MAX = 120;
+
+  const SCREEN_W = 390;
+  const SCREEN_H = 844;
+
+  // sub-step for bullet CCD
+  const SUB_STEPS = 4;
+
+  // for forensics
+  function _forensicsView() {
+    return {
+      seed: o.seed || null,
+      state: () => ({
+        phase,
+        result,
+        score,
+        asteroidsRemaining: asteroids.filter(a => a.active).length,
+        ship: { x: ship.x, y: ship.y, angle: ship.angle },
+        asteroids: asteroids.filter(a => a.active).map(a => ({ x: a.x, y: a.y }))
+      })
+    };
+  }
+
+  // --- collision helpers ---
+  function dist(a, b) {
+    return Math.hypot(a.x - b.x, a.y - b.y);
   }
 
   function lineCircleIntersect(p1, p2, c, r) {
     const dx = p2.x - p1.x, dy = p2.y - p1.y;
     const fx = p1.x - c.x, fy = p1.y - c.y;
-    const a = dx*dx + dy*dy;
-    const b = 2*(fx*dx + fy*dy);
-    const c_ = fx*fx + fy*fy - r*r;
-    let disc = b*b - 4*a*c_;
+    const a = dx * dx + dy * dy;
+    if (a === 0) return dist(p1, c) <= r;
+    const b = 2 * (fx * dx + fy * dy);
+    const cVal = fx * fx + fy * fy - r * r;
+    let disc = b * b - 4 * a * cVal;
     if (disc < 0) return false;
     disc = Math.sqrt(disc);
-    const t1 = (-b - disc) / (2*a);
-    const t2 = (-b + disc) / (2*a);
-    return (t1 >= 0 && t1 <= 1) || (t2 >= 0 && t2 <= 1);
+    const t1 = (-b - disc) / (2 * a);
+    const t2 = (-b + disc) / (2 * a);
+    if (t1 >= 0 && t1 <= 1) return true;
+    if (t2 >= 0 && t2 <= 1) return true;
+    return false;
   }
 
-  function distance(ax, ay, bx, by) {
-    const dx = ax - bx, dy = ay - by;
-    return Math.sqrt(dx*dx + dy*dy);
-  }
-
-  function createAsteroid(x, y, radius, vx, vy) {
-    return { x, y, vx, vy, radius, isBig: radius >= BIG_ASTEROID_RADIUS };
-  }
-
-  function spawnInitialAsteroids() {
-    asteroids = [];
-    const rand = ctx.random;
-    for (let i = 0; i < INITIAL_ASTEROIDS; i++) {
-      let x, y;
-      do {
-        x = rand.range(0, 390);
-        y = rand.range(0, 844);
-      } while (distance(x,y,195,422) < 100);
-      const angle = rand.range(0, Math.PI*2);
-      const speed = rand.range(ASTEROID_SPEED_MIN, ASTEROID_SPEED_MAX);
-      const vx = Math.cos(angle)*speed;
-      const vy = Math.sin(angle)*speed;
-      asteroids.push(createAsteroid(x, y, BIG_ASTEROID_RADIUS, vx, vy));
-    }
-  }
-
-  function splitAsteroid(ast) {
-    const rand = ctx.random;
-    const angle1 = rand.range(0, Math.PI*2);
-    const angle2 = angle1 + Math.PI*2/3;
-    const speed = rand.range(ASTEROID_SPEED_MIN, ASTEROID_SPEED_MAX) * 1.2;
-    const vx1 = Math.cos(angle1)*speed;
-    const vy1 = Math.sin(angle1)*speed;
-    const vx2 = Math.cos(angle2)*speed;
-    const vy2 = Math.sin(angle2)*speed;
-    const a1 = createAsteroid(ast.x, ast.y, SMALL_ASTEROID_RADIUS, vx1, vy1);
-    const a2 = createAsteroid(ast.x, ast.y, SMALL_ASTEROID_RADIUS, vx2, vy2);
-    asteroids.push(a1, a2);
-  }
-
-  function spawnParticles(x, y, colorStart, colorEnd, count) {
+  // --- audio & particles ---
+  function emitParticles(x, y, count, color) {
     const eng = ctx.getEngine();
     if (eng && eng.particles) {
       try {
         eng.particles.spawnEmitter({
           pos: { x, y },
           count: count || 20,
-          speed: 80,
-          particleTime: 0.4,
-          sizeStart: 6,
-          sizeEnd: 2,
-          colorStart: colorStart || { r:1, g:1, b:1, a:1 },
-          colorEnd: colorEnd || { r:0.5, g:0.5, b:0.5, a:0 }
+          speed: 100,
+          particleTime: 0.6,
+          sizeStart: 8,
+          sizeEnd: 0,
+          colorStart: color || { r: 1, g: 0.8, b: 0.2, a: 1 },
+          colorEnd: { r: 1, g: 0.3, b: 0, a: 0 }
         });
       } catch (_) {}
     }
@@ -114,170 +102,267 @@ export default function createAsteroidsGame(opts) {
     }
   }
 
-  function fireBullet() {
-    const now = ctx.time.nowMs();
-    if (now - lastFireTime < FIRE_COOLDOWN) return;
-    lastFireTime = now;
-    const bx = ship.x + Math.cos(ship.angle) * (ship.radius + 5);
-    const by = ship.y + Math.sin(ship.angle) * (ship.radius + 5);
-    const bvx = Math.cos(ship.angle) * BULLET_SPEED + ship.vx;
-    const bvy = Math.sin(ship.angle) * BULLET_SPEED + ship.vy;
-    bullets.push({ x: bx, y: by, vx: bvx, vy: bvy, born: now, radius: 3 });
-    playSfx([1,0.02,600,,,0.1,,0.6]);
-  }
-
-  function resetGameState() {
-    ship.x = 195;
-    ship.y = 422;
-    ship.vx = 0;
-    ship.vy = 0;
-    ship.angle = -Math.PI/2;
-    spawnInitialAsteroids();
-    bullets = [];
-    score = 0;
-    lastFireTime = 0;
-    keyState = {};
-  }
-
+  // --- game logic ---
   function resetGame() {
-    resetGameState();
     phase = 'playing';
     result = null;
+    score = 0;
+    bullets = [];
+    ship = { x: 195, y: 422, angle: -Math.PI / 2, vx: 0, vy: 0 };
+    fireTimer = 0;
+
+    // generate asteroids
+    asteroids = [];
+    for (let i = 0; i < 6; i++) {
+      let x, y;
+      do {
+        x = ctx.random.range(30, SCREEN_W - 30);
+        y = ctx.random.range(30, SCREEN_H - 30);
+      } while (dist({ x, y }, ship) < 150);
+      const angle = ctx.random.range(0, Math.PI * 2);
+      const speed = ctx.random.range(ASTEROID_SPEED_MIN, ASTEROID_SPEED_MAX);
+      asteroids.push({
+        x, y,
+        vx: Math.cos(angle) * speed,
+        vy: Math.sin(angle) * speed,
+        radius: ASTEROID_LARGE_RADIUS,
+        active: true
+      });
+    }
   }
 
-  // lifecycle
+  function spawnBullet() {
+    const cos = Math.cos(ship.angle);
+    const sin = Math.sin(ship.angle);
+    const gunX = ship.x + cos * (SHIP_RADIUS + 5);
+    const gunY = ship.y + sin * (SHIP_RADIUS + 5);
+    bullets.push({
+      x: gunX, y: gunY,
+      prevX: gunX, prevY: gunY,
+      vx: cos * BULLET_SPEED,
+      vy: sin * BULLET_SPEED,
+      life: BULLET_LIFETIME
+    });
+    emitParticles(gunX, gunY, 12, { r: 0.5, g: 0.9, b: 1, a: 1 });
+    playSfx([1, 0.02, 880, , 0.02, 0.1, , 0.4, -0.1]); // fire sfx
+  }
+
+  // --- lifecycle ---
   function init(boot) {
     ctx = boot.ctx;
-    const input = ctx.getInput();
+    const seed = o.seed;
+    if (seed != null) ctx.random.reseed(seed);
 
-    const keydownSub = input.on('keydown', (e) => {
-      if (e.key) keyState[e.key] = true;
-    });
-    subHandlers.push(keydownSub);
+    // input subscriptions
+    const onKeyDown = (e) => {
+      switch (e.key) {
+        case 'ArrowLeft': held.left = true; break;
+        case 'ArrowRight': held.right = true; break;
+        case 'ArrowUp': held.up = true; break;
+        case ' ': held.space = true; break;
+      }
+    };
+    const onKeyUp = (e) => {
+      switch (e.key) {
+        case 'ArrowLeft': held.left = false; break;
+        case 'ArrowRight': held.right = false; break;
+        case 'ArrowUp': held.up = false; break;
+        case ' ': held.space = false; break;
+      }
+    };
+    const onPointerDown = (e) => {
+      if (phase === 'gameover') {
+        resetGame();
+      }
+    };
 
-    const keyupSub = input.on('keyup', (e) => {
-      if (e.key) keyState[e.key] = false;
-    });
-    subHandlers.push(keyupSub);
+    const inp = ctx.getInput();
+    const sub1 = inp.on('keydown', onKeyDown);
+    const sub2 = inp.on('keyup', onKeyUp);
+    const sub3 = inp.on('pointerdown', onPointerDown);
+    inputSubs = [sub1, sub2, sub3];
 
-    const pointerSub = input.on('pointerdown', () => {
-      if (phase === 'gameover') resetGame();
-    });
-    subHandlers.push(pointerSub);
-
-    resetGameState();
-    phase = 'playing';
-    result = null;
+    resetGame();
+    // initial particles (ambient)
+    const eng = ctx.getEngine();
+    if (eng && eng.particles) {
+      try {
+        eng.particles.spawnEmitter({
+          pos: { x: 195, y: 400 }, emitRate: 8, emitTime: 0, particleTime: 0.8,
+          speed: 30, sizeStart: 4, sizeEnd: 0,
+          colorStart: { r: 0.2, g: 0.6, b: 1, a: 0.5 }, colorEnd: { r: 0.1, g: 0.3, b: 0.5, a: 0 }
+        });
+      } catch (_) {}
+    }
   }
 
   function update(dt) {
-    if (phase === 'gameover') return;
-    const now = ctx.time.nowMs();
+    nowMs = ctx.time.nowMs();
+    t = nowMs / 1000;
 
-    // ship rotation
-    if (keyState['ArrowLeft']) ship.angle -= ROTATION_SPEED * dt;
-    if (keyState['ArrowRight']) ship.angle += ROTATION_SPEED * dt;
+    if (phase !== 'playing') return;
 
-    // thrust
-    if (keyState['ArrowUp']) {
-      ship.vx += Math.cos(ship.angle) * THRUST * dt;
-      ship.vy += Math.sin(ship.angle) * THRUST * dt;
-      spawnParticles(
-        ship.x - Math.cos(ship.angle)*20,
-        ship.y - Math.sin(ship.angle)*20,
-        { r:1, g:0.8, b:0.2, a:1 },
-        { r:1, g:0.4, b:0, a:0 },
-        5
-      );
+    // --- input handling ---
+    if (held.left) ship.angle -= SHIP_ROTATION_SPEED * dt;
+    if (held.right) ship.angle += SHIP_ROTATION_SPEED * dt;
+    if (held.up) {
+      ship.vx += Math.cos(ship.angle) * SHIP_ACCEL * dt;
+      ship.vy += Math.sin(ship.angle) * SHIP_ACCEL * dt;
     }
+    // held.space for continuous fire with cooldown
+    if (held.space && fireTimer <= 0) {
+      spawnBullet();
+      fireTimer = FIRE_COOLDOWN;
+    }
+    fireTimer -= dt;
 
-    // fire
-    if (keyState['Space']) fireBullet();
+    // --- friction ---
+    ship.vx *= SHIP_FRICTION;
+    ship.vy *= SHIP_FRICTION;
 
-    // friction
-    ship.vx *= FRICTION;
-    ship.vy *= FRICTION;
-
-    // move ship
+    // --- update ship position ---
     ship.x += ship.vx * dt;
     ship.y += ship.vy * dt;
-    wrapPos(ship);
+    // wrap
+    if (ship.x < 0) ship.x += SCREEN_W;
+    if (ship.x > SCREEN_W) ship.x -= SCREEN_W;
+    if (ship.y < 0) ship.y += SCREEN_H;
+    if (ship.y > SCREEN_H) ship.y -= SCREEN_H;
 
-    // move asteroids
-    for (const a of asteroids) {
-      a.x += a.vx * dt;
-      a.y += a.vy * dt;
-      wrapPos(a);
+    // --- update bullets with sub-steps for CCD ---
+    const subDt = dt / SUB_STEPS;
+    for (let bi = 0; bi < bullets.length; bi++) {
+      const b = bullets[bi];
+      b.prevX = b.x;
+      b.prevY = b.y;
+      // move in sub-steps (we only store final position for wrapping & collisions)
+      for (let s = 0; s < SUB_STEPS; s++) {
+        b.x += b.vx * subDt;
+        b.y += b.vy * subDt;
+        // wrap (optional: bullets wrap)
+        // We choose NOT to wrap bullets for simplicity – delete when off screen
+      }
+      b.life -= dt;
     }
 
-    // update bullets & collision with asteroids (CCD)
-    for (let i = bullets.length-1; i >= 0; i--) {
-      const b = bullets[i];
-      const oldX = b.x, oldY = b.y;
-      b.x += b.vx * dt;
-      b.y += b.vy * dt;
+    // --- bullet-asteroid collision (CCD using line segment) ---
+    const bulletsToRemove = [];
+    const newAsteroids = [];
+    let scoreDelta = 0;
 
-      // lifespan
-      if (now - b.born > BULLET_LIFETIME) {
-        bullets.splice(i, 1);
+    for (let bi = 0; bi < bullets.length; bi++) {
+      const b = bullets[bi];
+      if (b.life <= 0) {
+        bulletsToRemove.push(bi);
         continue;
       }
-
-      // off-screen remove (no wrap for simplicity)
-      if (b.x < 0 || b.x > 390 || b.y < 0 || b.y > 844) {
-        bullets.splice(i, 1);
+      // wrap check: if bullet left screen, remove
+      if (b.x < -100 || b.x > SCREEN_W + 100 || b.y < -100 || b.y > SCREEN_H + 100) {
+        bulletsToRemove.push(bi);
         continue;
       }
 
       let hit = false;
-      for (let j = asteroids.length-1; j >= 0; j--) {
-        const a = asteroids[j];
-        if (lineCircleIntersect({x:oldX, y:oldY}, {x:b.x, y:b.y}, {x:a.x, y:a.y}, a.radius)) {
+      for (let ai = 0; ai < asteroids.length; ai++) {
+        const a = asteroids[ai];
+        if (!a.active) continue;
+        if (lineCircleIntersect(
+          { x: b.prevX, y: b.prevY },
+          { x: b.x, y: b.y },
+          { x: a.x, y: a.y },
+          a.radius
+        )) {
+          // hit
           hit = true;
-          score += 1;
-          spawnParticles(b.x, b.y, {r:1,g:0.9,b:0.5,a:1}, {r:1,g:0.3,b:0,a:0}, 30);
-          playSfx([1,0.1,880,,,0.2,,0.4]);
-          if (a.isBig) splitAsteroid(a);
-          asteroids.splice(j, 1);
-          break;
+          // destroy asteroid
+          a.active = false;
+          // particles at hit point (use asteroid center)
+          emitParticles(a.x, a.y, 25, { r: 1, g: 0.6, b: 0.2, a: 1 });
+          playSfx([1, 0.05, 260, , 0.1, 0.15, , 0.7]); // explosion sfx
+          scoreDelta += 1;
+
+          if (a.radius === ASTEROID_LARGE_RADIUS) {
+            // spawn two small asteroids
+            const spd = Math.hypot(a.vx, a.vy) * 1.2;
+            for (let i = 0; i < 2; i++) {
+              const ang = ctx.random.range(0, Math.PI * 2);
+              const speed = spd * (0.8 + 0.4 * ctx.random.next());
+              newAsteroids.push({
+                x: a.x, y: a.y,
+                vx: Math.cos(ang) * speed,
+                vy: Math.sin(ang) * speed,
+                radius: ASTEROID_SMALL_RADIUS,
+                active: true
+              });
+            }
+          }
+          break; // one bullet hits at most one asteroid
         }
       }
-      if (hit) {
-        bullets.splice(i, 1);
-      }
+      if (hit) bulletsToRemove.push(bi);
     }
 
-    // ship vs asteroids
+    // --- apply bullet removal ---
+    for (let i = bulletsToRemove.length - 1; i >= 0; i--) {
+      bullets.splice(bulletsToRemove[i], 1);
+    }
+
+    // --- add new asteroids ---
+    for (const na of newAsteroids) {
+      asteroids.push(na);
+    }
+
+    // --- update score ---
+    score += scoreDelta;
+
+    // --- update asteroids (wrap) ---
     for (const a of asteroids) {
-      const dx = ship.x - a.x, dy = ship.y - a.y;
-      if (dx*dx + dy*dy < (ship.radius + a.radius) * (ship.radius + a.radius)) {
+      if (!a.active) continue;
+      a.x += a.vx * dt;
+      a.y += a.vy * dt;
+      if (a.x < -a.radius) a.x += SCREEN_W + 2 * a.radius;
+      if (a.x > SCREEN_W + a.radius) a.x -= SCREEN_W + 2 * a.radius;
+      if (a.y < -a.radius) a.y += SCREEN_H + 2 * a.radius;
+      if (a.y > SCREEN_H + a.radius) a.y -= SCREEN_H + 2 * a.radius;
+    }
+
+    // --- ship-asteroid collision ---
+    for (const a of asteroids) {
+      if (!a.active) continue;
+      if (dist(ship, a) < SHIP_RADIUS + a.radius) {
+        // game over - lose
         phase = 'gameover';
         result = 'lose';
-        spawnParticles(ship.x, ship.y, {r:1,g:0.2,b:0.2,a:1}, {r:0.5,g:0,b:0,a:0}, 40);
-        playSfx([1,0.2,100,,,0.5,,1.5]);
-        return;
+        emitParticles(ship.x, ship.y, 50, { r: 1, g: 0.2, b: 0.2, a: 1 });
+        playSfx([1, 0.2, 100, , 0.3, 0.3, , 0.8]); // crash sfx
+        // also destroy ship? keep ship visible
+        break;
       }
     }
 
-    // win condition
-    if (asteroids.length === 0) {
+    // --- check win (all asteroids gone) ---
+    const hasActive = asteroids.some(a => a.active);
+    if (!hasActive && asteroids.length > 0) {
       phase = 'gameover';
       result = 'win';
+      emitParticles(ship.x, ship.y, 60, { r: 0.3, g: 1, b: 0.5, a: 1 });
+      playSfx([1, 0.05, 523, , 0.05, 0.2, , 0.5]); // win sound
     }
   }
 
   function render(g) {
     // background
     g.fillStyle = '#0a0a1a';
-    g.fillRect(0, 0, 390, 844);
+    g.fillRect(0, 0, SCREEN_W, SCREEN_H);
 
     // asteroids
     for (const a of asteroids) {
-      g.fillStyle = a.isBig ? '#8b5e3c' : '#a0744a';
+      if (!a.active) continue;
+      g.fillStyle = '#888899';
       g.beginPath();
-      g.arc(a.x, a.y, a.radius, 0, Math.PI*2);
+      g.arc(a.x, a.y, a.radius, 0, Math.PI * 2);
       g.fill();
-      g.strokeStyle = '#d4a76a';
+      g.strokeStyle = '#aabbcc';
       g.lineWidth = 2;
       g.stroke();
     }
@@ -286,69 +371,66 @@ export default function createAsteroidsGame(opts) {
     for (const b of bullets) {
       g.fillStyle = '#ffff00';
       g.beginPath();
-      g.arc(b.x, b.y, b.radius, 0, Math.PI*2);
+      g.arc(b.x, b.y, BULLET_RADIUS, 0, Math.PI * 2);
       g.fill();
     }
 
-    // ship
+    // ship (triangle)
     g.save();
     g.translate(ship.x, ship.y);
     g.rotate(ship.angle);
-    g.fillStyle = phase === 'gameover' ? '#ff4444' : '#44aaff';
+    g.fillStyle = '#00ddff';
     g.beginPath();
-    g.moveTo(20, 0);
-    g.lineTo(-15, -12);
-    g.lineTo(-10, 0);
-    g.lineTo(-15, 12);
+    g.moveTo(0, -SHIP_RADIUS);
+    g.lineTo(-SHIP_RADIUS * 0.7, SHIP_RADIUS * 0.8);
+    g.lineTo(SHIP_RADIUS * 0.7, SHIP_RADIUS * 0.8);
     g.closePath();
     g.fill();
-    g.strokeStyle = '#ffffff';
-    g.lineWidth = 1.5;
-    g.stroke();
+    // engine glow if accelerating
+    if (held.up) {
+      g.fillStyle = '#ff8800';
+      g.beginPath();
+      g.moveTo(-5, SHIP_RADIUS * 0.5);
+      g.lineTo(0, SHIP_RADIUS * 1.2);
+      g.lineTo(5, SHIP_RADIUS * 0.5);
+      g.closePath();
+      g.fill();
+    }
     g.restore();
 
     // HUD
     g.fillStyle = '#ffffff';
-    g.font = 'bold 16px monospace';
+    g.font = '18px monospace';
     g.fillText('Score: ' + score, 10, 30);
-    g.fillText('Asteroids: ' + asteroids.length, 10, 50);
-    g.fillText('Phase: ' + phase, 10, 70);
+    const remaining = asteroids.filter(a => a.active).length;
+    g.fillText('Asteroids: ' + remaining, 10, 55);
 
     if (phase === 'gameover') {
-      g.fillStyle = result === 'win' ? '#00ff00' : '#ff0000';
-      g.font = 'bold 28px monospace';
+      g.font = 'bold 36px monospace';
+      g.fillStyle = result === 'win' ? '#66ff88' : '#ff6666';
       g.textAlign = 'center';
-      g.fillText(result === 'win' ? 'YOU WIN!' : 'GAME OVER', 195, 400);
-      g.font = '16px monospace';
-      g.fillStyle = '#ffffff';
-      g.fillText('Tap to restart', 195, 430);
-      g.textAlign = 'start';
+      g.fillText(result === 'win' ? 'YOU WIN!' : 'GAME OVER', SCREEN_W / 2, SCREEN_H / 2 - 40);
+      g.font = '20px monospace';
+      g.fillStyle = '#aaaaaa';
+      g.fillText('Click to restart', SCREEN_W / 2, SCREEN_H / 2 + 20);
+      g.textAlign = 'left';
     }
   }
 
   function destroy() {
-    for (const sub of subHandlers) {
-      try { sub.cancel(); } catch(_) {}
+    for (const sub of inputSubs) {
+      try { sub.cancel(); } catch (_) {}
     }
-    subHandlers = [];
-    asteroids = [];
+    inputSubs = [];
     bullets = [];
-    phase = 'booting';
-    result = null;
+    asteroids = [];
   }
 
-  function _forensicsView() {
-    return {
-      seed: ctx && ctx.random ? ctx.random.seed : null,
-      state: () => ({
-        phase,
-        result,
-        score,
-        asteroidsRemaining: asteroids.length,
-        ship: { x: ship.x, y: ship.y, angle: ship.angle }
-      })
-    };
-  }
-
-  return { init, update, render, destroy, _forensicsView };
+  return {
+    init,
+    update,
+    render,
+    destroy,
+    _forensicsView
+  };
 }
\ No newline at end of file
diff --git a/game-runtime/games/_wg1-gen/asteroids/play-spec.json b/game-runtime/games/_wg1-gen/asteroids/play-spec.json
index c7bdc25a..95582e56 100644
--- a/game-runtime/games/_wg1-gen/asteroids/play-spec.json
+++ b/game-runtime/games/_wg1-gen/asteroids/play-spec.json
@@ -1,16 +1,12 @@
 {
   "driver": {
-    "type": "key-cycle",
-    "keys": [
-      "ArrowLeft",
-      "ArrowUp",
-      "Space",
-      "ArrowRight",
-      "Space",
-      "Space"
-    ],
-    "steps": 50,
-    "stepMs": 200
+    "type": "aim-fire",
+    "shipPath": "ship",
+    "targetsPath": "asteroids",
+    "fireKey": "Space",
+    "steps": 90,
+    "stepMs": 120,
+    "downMs": 80
   },
   "expectedEngineCallPrefixes": [
     "particles.",
@@ -20,7 +16,7 @@
     {
       "path": "score",
       "op": "increased",
-      "why": "循环旋转+推进+开火→击碎陨石得分上升;若高速子弹穿透(CCD缺)或打不中则不升=暴露 CCD 缺口"
+      "why": "aim-fire 读陨石坐标旋向对齐开火→击碎得分上升;若游戏不暴露陨石坐标致盲射则不升=可测性边界"
     }
   ],
   "expectLatch": true
diff --git a/game-runtime/games/_wg1-gen/flappy/bundle.iife.js b/game-runtime/games/_wg1-gen/flappy/bundle.iife.js
index d7d5b836..f6e7c2f2 100644
--- a/game-runtime/games/_wg1-gen/flappy/bundle.iife.js
+++ b/game-runtime/games/_wg1-gen/flappy/bundle.iife.js
@@ -1,34 +1,34 @@
-"use strict";var __GameBundle=(()=>{var Fi=Object.defineProperty;var kc=Object.getOwnPropertyDescriptor;var Gc=Object.getOwnPropertyNames;var Fc=Object.prototype.hasOwnProperty;var jc=(n,t,e)=>()=>{if(e)throw e[0];try{return n&&(t=n(n=0)),t}catch(s){throw e=[s],s}};var Vr=(n,t)=>{for(var e in t)Fi(n,e,{get:t[e],enumerable:!0})},Nc=(n,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Gc(t))!Fc.call(n,i)&&i!==e&&Fi(n,i,{get:()=>t[i],enumerable:!(s=kc(t,i))||s.enumerable});return n};var Bc=n=>Nc(Fi({},"__esModule",{value:!0}),n);var Lc={};Vr(Lc,{ASSERT:()=>f,BLACK:()=>nt,BLUE:()=>$a,Box2dDistanceJoint:()=>bi,Box2dFrictionJoint:()=>qo,Box2dGearJoint:()=>Jo,Box2dJoint:()=>Vt,Box2dKinematicObject:()=>Go,Box2dMotorJoint:()=>Xo,Box2dObject:()=>Ss,Box2dPinJoint:()=>No,Box2dPlugin:()=>xi,Box2dPrismaticJoint:()=>Uo,Box2dPulleyJoint:()=>Ho,Box2dRaycastResult:()=>mi,Box2dRevoluteJoint:()=>zo,Box2dRopeJoint:()=>Bo,Box2dStaticObject:()=>yi,Box2dTargetJoint:()=>jo,Box2dTileLayer:()=>Fo,Box2dWeldJoint:()=>Wo,Box2dWheelJoint:()=>Vo,CLEAR_BLACK:()=>ue,CLEAR_WHITE:()=>tn,CYAN:()=>ql,CanvasLayer:()=>oi,Color:()=>St,Ease:()=>Si,EngineObject:()=>je,GRAY:()=>Vl,GREEN:()=>Ya,ImageFont:()=>Zs,LOG:()=>bt,Light:()=>_o,LightSystemPlugin:()=>Eo,MAGENTA:()=>Hl,Medal:()=>pi,NewgroundsMedal:()=>To,NewgroundsPlugin:()=>Ao,ORANGE:()=>Wl,PI:()=>q,PURPLE:()=>Ka,Particle:()=>ri,ParticleEmitter:()=>yo,PathFinder:()=>Yo,PathFinderNode:()=>wi,PostProcessPlugin:()=>Co,RED:()=>nr,RandomGenerator:()=>uo,Sound:()=>ds,SoundInstance:()=>si,TextureInfo:()=>Ne,TileCollisionLayer:()=>ps,TileInfo:()=>Ce,TileLayer:()=>fs,TileLayerData:()=>pn,Timer:()=>we,Tween:()=>vi,UIButton:()=>vs,UICheckbox:()=>Do,UILayout:()=>ko,UIObject:()=>se,UISlider:()=>Io,UISystemPlugin:()=>Po,UIText:()=>gi,UITextInput:()=>Lo,UITile:()=>Oo,UIVideo:()=>Mo,Vector2:()=>st,WHITE:()=>U,YELLOW:()=>Xa,ZzFXMusic:()=>Ro,abs:()=>Z,atan2:()=>Zo,audioContext:()=>ft,audioDefaultSampleRate:()=>qn,audioIsRunning:()=>hs,audioMasterGain:()=>Fe,box2d:()=>m,box2dDebug:()=>Jr,box2dInit:()=>ad,box2dSetDebug:()=>rd,cameraAngle:()=>$,cameraFit:()=>rh,cameraPos:()=>At,cameraScale:()=>W,canvasClearColor:()=>Ye,canvasColorTiles:()=>Ai,canvasFixedSize:()=>Ln,canvasMaxAspect:()=>Pn,canvasMaxSize:()=>Rn,canvasMinAspect:()=>Zn,canvasPixelRatio:()=>$e,canvasPixelated:()=>or,ceil:()=>is,clamp:()=>F,combineCanvases:()=>br,cos:()=>ot,debug:()=>It,debugCircle:()=>Nt,debugClear:()=>Ml,debugLine:()=>xe,debugOverlap:()=>co,debugOverlay:()=>Pe,debugPoint:()=>Qo,debugPointSize:()=>Da,debugPoly:()=>Il,debugRect:()=>mt,debugScreenshot:()=>Ma,debugShowErrors:()=>kl,debugText:()=>_n,debugVideoCaptureIsActive:()=>ve,debugVideoCaptureStart:()=>ka,debugVideoCaptureStop:()=>Ga,debugWatermark:()=>Ti,distanceAngle:()=>zl,distanceWrap:()=>tr,drawCanvas2D:()=>vn,drawCircle:()=>Qs,drawCircleGradient:()=>sh,drawContext:()=>wt,drawCount:()=>Te,drawCrescent:()=>ud,drawEllipse:()=>ec,drawEllipseGradient:()=>nc,drawLine:()=>ln,drawLineList:()=>fo,drawNineSlice:()=>Ac,drawNineSliceScreen:()=>cd,drawPoly:()=>Fn,drawRect:()=>Ks,drawRectGradient:()=>th,drawRegularPoly:()=>tc,drawText:()=>ih,drawTextScreen:()=>Ke,drawTextureWrapped:()=>eh,drawThreeSlice:()=>Cc,drawThreeSliceScreen:()=>ld,drawTile:()=>_t,enablePhysicsSolver:()=>Ri,engineAddPlugin:()=>bn,engineImageFont:()=>rc,engineInit:()=>Pl,engineName:()=>Js,engineObjects:()=>xt,engineObjectsCallback:()=>Ol,engineObjectsCollect:()=>Oa,engineObjectsCollide:()=>Ko,engineObjectsDestroy:()=>Ll,engineObjectsRaycast:()=>Dl,engineObjectsUpdate:()=>La,engineVersion:()=>Us,fetchJSON:()=>Xl,floor:()=>vt,fontDefault:()=>ws,formatTime:()=>sr,frame:()=>Ra,frameRate:()=>El,gamepadConnected:()=>go,gamepadDirectionEmulateStick:()=>dr,gamepadDpad:()=>po,gamepadIsDown:()=>Re,gamepadPrimary:()=>yt,gamepadStick:()=>ls,gamepadStickCount:()=>ac,gamepadVibrate:()=>Sh,gamepadVibrateStop:()=>wh,gamepadWasPressed:()=>Ar,gamepadWasReleased:()=>vh,gamepadsEnable:()=>Pi,getCameraSize:()=>ic,getCrescentPoints:()=>Ec,getNoteFrequency:()=>dc,getPaused:()=>_l,glAntialias:()=>Lr,glCanvas:()=>Q,glCircleSides:()=>Ts,glClearCanvas:()=>mc,glClearRect:()=>wc,glCompileShader:()=>wo,glContext:()=>g,glCopyToContext:()=>kr,glCreateProgram:()=>Jn,glCreateTexture:()=>Ii,glDeleteTexture:()=>xc,glDraw:()=>ms,glDrawColoredPoints:()=>jr,glDrawOutlineTransform:()=>Fr,glDrawPoints:()=>Sc,glDrawPointsTransform:()=>Gr,glDrawUntextured:()=>vc,glEnable:()=>k,glFlush:()=>Ct,glSetAntialias:()=>Yh,glSetRenderTarget:()=>Qn,glSetTexture:()=>Ir,glSetTextureData:()=>Mr,glSetTextureWrap:()=>bc,gravity:()=>Bt,headlessMode:()=>j,hsl:()=>Oe,hypot:()=>Fa,inputClear:()=>Ps,inputClearKey:()=>wr,inputMouseMoveThreshold:()=>Sr,inputPreventDefault:()=>On,inputWASDEmulateDirection:()=>ts,isArray:()=>ce,isColor:()=>z,isFullscreen:()=>oc,isIntersecting:()=>za,isNumber:()=>P,isOnScreen:()=>ah,isOverlapping:()=>Hs,isPowerOfTwo:()=>os,isStringLike:()=>J,isTouchDevice:()=>ee,isUsingGamepad:()=>In,isVector2:()=>L,keyDirection:()=>bh,keyIsDown:()=>Et,keyWasPressed:()=>Ot,keyWasReleased:()=>Tr,lastInputDevice:()=>He,lerp:()=>zt,lerpAngle:()=>Jl,lerpWrap:()=>Ba,lightSystem:()=>V,lineTest:()=>Ua,log2:()=>ja,mainCanvas:()=>G,mainCanvasSize:()=>D,mainContext:()=>at,max:()=>X,medalDisplaySize:()=>di,medalDisplaySlideTime:()=>Dn,medalDisplayTime:()=>hi,medals:()=>bs,medalsForEach:()=>Mi,medalsInit:()=>Zh,medalsPreventUnlock:()=>Nr,medalsReset:()=>td,min:()=>K,mod:()=>te,mouseDelta:()=>xr,mouseDeltaScreen:()=>ye,mouseInWindow:()=>ti,mouseIsDown:()=>ns,mousePos:()=>_e,mousePosScreen:()=>jt,mouseWasPressed:()=>cs,mouseWasReleased:()=>xh,mouseWheel:()=>vr,nearestPowerOfTwo:()=>Ul,newgrounds:()=>xs,noise1D:()=>Zl,noise2D:()=>tu,objectDefaultAngleDamping:()=>lr,objectDefaultDamping:()=>cr,objectDefaultFriction:()=>hr,objectDefaultMass:()=>ar,objectDefaultRestitution:()=>ur,objectMaxSpeed:()=>De,oscillate:()=>Ja,particleEmitRateScale:()=>Xs,paused:()=>Se,percent:()=>Mt,percentLerp:()=>Bl,playSamples:()=>Pr,pointerLockExit:()=>Ch,pointerLockIsActive:()=>cc,pointerLockRequest:()=>Ah,postProcess:()=>Lt,primitiveCount:()=>Ae,rand:()=>dt,randBool:()=>Va,randColor:()=>lo,randInCircle:()=>Ha,randInt:()=>er,randSign:()=>Wa,randVec2:()=>qa,readSaveData:()=>Kl,rgb:()=>B,round:()=>Ws,saveCanvas:()=>Qa,saveDataURL:()=>rs,saveText:()=>Yl,screenToWorld:()=>_s,screenToWorldDelta:()=>sc,screenToWorldTransform:()=>Rs,setAdditiveBlendMode:()=>as,setCameraAngle:()=>nu,setCameraPos:()=>eu,setCameraScale:()=>su,setCanvasClearColor:()=>ru,setCanvasColorTiles:()=>ou,setCanvasFixedSize:()=>uu,setCanvasMaxAspect:()=>lu,setCanvasMaxSize:()=>au,setCanvasMinAspect:()=>cu,setCanvasPixelRatio:()=>du,setCanvasPixelated:()=>Za,setCursor:()=>hh,setDebugKey:()=>Zu,setDebugWatermark:()=>Qu,setEnablePhysicsSolver:()=>Su,setFontDefault:()=>fu,setGLCircleSides:()=>mu,setGLEnable:()=>yu,setGamepadDirectionEmulateStick:()=>Ou,setGamepadsEnable:()=>Lu,setGravity:()=>Ru,setHeadlessMode:()=>gu,setInputMouseMoveThreshold:()=>ph,setInputPreventDefault:()=>fh,setInputWASDEmulateDirection:()=>Du,setMedalDisplaySize:()=>sd,setMedalDisplaySlideTime:()=>nd,setMedalDisplayTime:()=>ed,setMedalsPreventUnlock:()=>id,setObjectDefaultAngleDamping:()=>Au,setObjectDefaultDamping:()=>Tu,setObjectDefaultFriction:()=>Eu,setObjectDefaultMass:()=>wu,setObjectDefaultRestitution:()=>Cu,setObjectMaxSpeed:()=>_u,setParticleEmitRateScale:()=>Pu,setPaused:()=>Rl,setShowSplashScreen:()=>pu,setSoundDefaultRange:()=>$u,setSoundDefaultTaper:()=>Ku,setSoundEnable:()=>Xu,setSoundVolume:()=>Yu,setTileDefaultBleed:()=>vu,setTileDefaultPadding:()=>xu,setTileDefaultSize:()=>bu,setTilesPixelated:()=>hu,setTimeScale:()=>iu,setTouchGamepadAlpha:()=>Vu,setTouchGamepadAnalog:()=>zu,setTouchGamepadButtonCount:()=>Fu,setTouchGamepadCenterButtonSize:()=>Gu,setTouchGamepadDisplayTime:()=>Wu,setTouchGamepadEnable:()=>Mu,setTouchGamepadFloating:()=>Ju,setTouchGamepadLeftButtonCount:()=>Nu,setTouchGamepadLeftStick:()=>ju,setTouchGamepadPassthrough:()=>ku,setTouchGamepadRightStick:()=>Bu,setTouchGamepadSize:()=>Uu,setTouchGamepadVibration:()=>qu,setTouchInputEnable:()=>Iu,setVibrateEnable:()=>Hu,shareURL:()=>$l,showSplashScreen:()=>rr,sign:()=>Zt,sin:()=>tt,smoothStep:()=>qs,soundDefaultRange:()=>gr,soundDefaultTaper:()=>yr,soundEnable:()=>Ut,soundVolume:()=>fn,speak:()=>Bh,speakStop:()=>zh,tan:()=>Na,textureInfos:()=>nn,tile:()=>Es,tileCollisionGetData:()=>ii,tileCollisionLayers:()=>Qe,tileCollisionRaycast:()=>fc,tileCollisionTest:()=>We,tileDefaultBleed:()=>_i,tileDefaultPadding:()=>Ei,tileDefaultSize:()=>Ci,tileLayersLoad:()=>Uh,tilesPixelated:()=>gn,time:()=>Ht,timeDelta:()=>$o,timeReal:()=>Ze,timeScale:()=>ir,toggleFullscreen:()=>uh,touchGamepadAlpha:()=>pr,touchGamepadAnalog:()=>As,touchGamepadButtonCount:()=>Un,touchGamepadCenterButtonSize:()=>le,touchGamepadDisplayTime:()=>es,touchGamepadEnable:()=>en,touchGamepadFloating:()=>sn,touchGamepadLeftButtonCount:()=>Vn,touchGamepadLeftStick:()=>xn,touchGamepadPassthrough:()=>fr,touchGamepadRightStick:()=>Wn,touchGamepadSize:()=>Jt,touchGamepadVibration:()=>Ys,touchInputEnable:()=>cn,tweenProperty:()=>hd,tweenStopAll:()=>dd,tweenUpdate:()=>Pc,uiDebug:()=>zr,uiSetDebug:()=>od,uiSystem:()=>C,usingGamepadInput:()=>mh,usingKeyboardInput:()=>yh,usingMouseInput:()=>gh,vec2:()=>x,vibrate:()=>Cr,vibrateEnable:()=>Cs,vibrateStop:()=>Th,workCanvas:()=>ke,workContext:()=>qe,workReadCanvas:()=>be,workReadContext:()=>Ie,worldToScreen:()=>Sn,worldToScreenDelta:()=>oh,writeSaveData:()=>Ql,zzfx:()=>Jh,zzfxG:()=>Oi,zzfxM:()=>Tc});function _l(){return Se}function Rl(n=!0){Se=n}function bn(n,t,e,s){f(!un.find(o=>o.update===n&&o.render===t&&o.glContextLost===e&&o.glContextRestored===s));let i=new ro(n,t,e,s);un.push(i)}async function Pl(n,t,e,s,i,o=[],r){if(Pa&&console.log(`${Js} Engine v${Us}`),f(!at,"engine already initialized"),at)return;f(ce(o),"pass in images as array"),document.body||document.documentElement.appendChild(document.createElement("body")),r||(r=document.body),n||(n=()=>{}),t||(t=()=>{}),e||(e=()=>{}),s||(s=()=>{}),i||(i=()=>{});function a(){D=x(G.width,G.height),at.imageSmoothingEnabled=!gn,So()}function c(y=0){let b=y-so;so||(b=0),so=y,(It||Ti)&&(Vs=zt(Vs,1e3/(b||1),.05));let v=It&&Et("Equal"),S=It&&Et("Minus"),_=v?10:S?.1:1;Ze+=b*_/1e3;let w=ir*_;b*=w,ge+=Se?0:b,w<=1&&(ge=K(ge,50));let E=!1;if(Se){E=!0,l(),wa(),un.forEach(T=>{var R;return(R=T.update)==null?void 0:R.call(T)});for(let T of xt)T.parent||T.updateTransforms();ba(),e(),Ta(),ve()&&A()}else{let T=0;for(ge<0&&ge>-9&&(T=ge,ge=0);ge>=0;ge-=1e3/60)Ht=Ra++/60,E=!0,l(),wa(),t(),un.forEach(R=>{var M;return(M=R.update)==null?void 0:M.call(R)}),La(),ba(),e(),Ta(),ve()&&A();ge+=T}ve()||A(),requestAnimationFrame(c);function A(){if(!j){E||l(),a(),s(),xt.sort((T,R)=>T.renderOrder-R.renderOrder);for(let T of xt)T.destroyed||T.render();i(),un.forEach(T=>{var R;return(R=T.render)==null?void 0:R.call(T)}),_h(),Fl(),Ct(),jl(),Te=0,Ae=0}}}function l(){if(!j){if(Ln.x){D=Ln.copy();let y=innerWidth/innerHeight,b=Ln.x/Ln.y,v=yPn){let E=D.y*Pn|0;D.x=K(E,Rn.x)}else if(S0&&!k&&(at.fillStyle=Ye.toString(),at.fillRect(0,0,D.x,D.y),at.fillStyle=nt.toString()),at.lineJoin="round",at.lineCap="round"}}if(j)return d();qh(r);let u="margin:0;overflow:hidden;background:#000;user-select:none;-webkit-user-select:none;touch-action:none;-webkit-touch-callout:none";r.style.cssText=u,G=r.appendChild(document.createElement("canvas")),wt=at=G.getContext("2d"),Eh(),Nh(),Gl();let h="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)";G.style.cssText=h,Q&&(Q.style.cssText=h),Za(or),l(),So(),ke=new OffscreenCanvas(64,64),qe=ke.getContext("2d"),be=new OffscreenCanvas(64,64),Ie=be.getContext("2d",{willReadFrequently:!0});let p=o.map((y,b)=>va(b,y));return o.length||p.push(va(0)),p.push(dh()),rr&&p.push(new Promise(y=>{let b=0;v();function v(){Ps(),Qh(b+=.01),b>1?y():setTimeout(v,16)}})),await Promise.all(p),d();async function d(){await n(),c()}}function La(){Ko=xt.filter(t=>t.collideSolidObjects);function n(t){if(!t.destroyed){t.update();for(let e of t.children)n(e)}}for(let t of xt)if(!(t.parent||t.destroyed)){t.update(),t.updatePhysics();for(let e of t.children)n(e);t.updateTransforms()}xt=xt.filter(t=>!t.destroyed)}function Ll(n=!0){for(let t of xt)t.parent||t.destroy(n);xt=xt.filter(t=>!t.destroyed)}function Oa(n,t,e=xt){let s=[];if(n)if(t instanceof st)for(let i of e)i.isOverlapping(n,t)&&s.push(i);else{let i=t*t;for(let o of e)n.distanceSquared(o.pos)e(i))}function Dl(n,t,e=xt){let s=[];for(let i of e)i.collideRaycast&&za(n,t,i.pos,i.size)&&(ae&&mt(i.pos,i.size,"#f00"),s.push(i));return ae&&xe(n,t,s.length?"#f00":"#00f",.02),s}function f(n,...t){if(!n)throw console.assert(n,...t),new Error("Assert failed!")}function bt(...n){console.log(...n)}function mt(n,t=x(),e=U,s=0,i=0,o=!1,r=!1){f(L(n),"pos must be a vec2"),f(L(t),"size must be a vec2"),f(J(e)||z(e),"color is invalid"),f(P(s),"time must be a number"),f(P(i),"angle must be a number"),z(e)&&(e=e.toString());let a=new we(s);Xe.push({pos:n.copy(),size:t.copy(),color:e,timer:a,angle:i,fill:o,screenSpace:r})}function Il(n,t,e=U,s=0,i=0,o=!1,r=!1){f(L(n),"pos must be a vec2"),f(ce(t),"points must be an array"),f(J(e)||z(e),"color is invalid"),f(P(s),"time must be a number"),f(P(i),"angle must be a number"),z(e)&&(e=e.toString()),n=n.copy(),t=t.map(c=>c.copy());let a=new we(s);Xe.push({pos:n,points:t,color:e,timer:a,angle:i,fill:o,screenSpace:r})}function Nt(n,t=0,e=U,s=0,i=!1,o=!1){f(L(n),"pos must be a vec2"),f(P(t),"size must be a number"),f(J(e)||z(e),"color is invalid"),f(P(s),"time must be a number"),z(e)&&(e=e.toString()),n=n.copy();let r=new we(s);Xe.push({pos:n,size:t,color:e,timer:r,angle:0,fill:i,screenSpace:o})}function Qo(n,t,e,s,i=!1){mt(n,void 0,t,e,s,!1,i)}function xe(n,t,e,s=.1,i=0,o=!1){f(L(n),"posA must be a vec2"),f(L(t),"posB must be a vec2"),f(P(s),"width must be a number");let r=x((t.x-n.x)/2,(t.y-n.y)/2),a=x(s,r.length()*2);mt(n.add(r),a,e,i,r.angle(),!0,o)}function co(n,t,e,s,i,o,r=!1){f(L(n),"posA must be a vec2"),f(L(e),"posB must be a vec2"),f(L(t),"sizeA must be a vec2"),f(L(s),"sizeB must be a vec2");let a=x(K(n.x-t.x/2,e.x-s.x/2),K(n.y-t.y/2,e.y-s.y/2)),c=x(X(n.x+t.x/2,e.x+s.x/2),X(n.y+t.y/2,e.y+s.y/2));mt(a.lerp(c,.5),c.subtract(a),i,o,0,!1,r)}function _n(n,t,e=1,s=U,i=0,o=0,r="monospace",a=!1){f(J(n),"text must be a string"),f(L(t),"pos must be a vec2"),f(P(e),"size must be a number"),f(J(s)||z(s),"color is invalid"),f(P(i),"time must be a number"),f(P(o),"angle must be a number"),f(J(r),"font must be a string"),z(s)&&(s=s.toString()),t=t.copy();let c=new we(i);Xe.push({text:n,pos:t,size:e,color:s,timer:c,angle:o,font:r,screenSpace:a})}function Ml(){Xe=[]}function Ma(){ao=1}function kl(){let n=e=>{document.body.style="background-color:#111;margin:8px",document.body.innerHTML="
"+e},t=console.assert;console.assert=(e,...s)=>{if(t(e,...s),!e){let i=s.join(" "),o=new Error().stack;throw`Assertion failed!
+"use strict";var __GameBundle=(()=>{var Fi=Object.defineProperty;var kc=Object.getOwnPropertyDescriptor;var Gc=Object.getOwnPropertyNames;var Fc=Object.prototype.hasOwnProperty;var jc=(n,t,e)=>()=>{if(e)throw e[0];try{return n&&(t=n(n=0)),t}catch(s){throw e=[s],s}};var Vr=(n,t)=>{for(var e in t)Fi(n,e,{get:t[e],enumerable:!0})},Bc=(n,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Gc(t))!Fc.call(n,i)&&i!==e&&Fi(n,i,{get:()=>t[i],enumerable:!(s=kc(t,i))||s.enumerable});return n};var Nc=n=>Bc(Fi({},"__esModule",{value:!0}),n);var Lc={};Vr(Lc,{ASSERT:()=>f,BLACK:()=>et,BLUE:()=>$a,Box2dDistanceJoint:()=>bi,Box2dFrictionJoint:()=>qo,Box2dGearJoint:()=>Jo,Box2dJoint:()=>Ut,Box2dKinematicObject:()=>Go,Box2dMotorJoint:()=>Xo,Box2dObject:()=>Ss,Box2dPinJoint:()=>Bo,Box2dPlugin:()=>xi,Box2dPrismaticJoint:()=>Uo,Box2dPulleyJoint:()=>Ho,Box2dRaycastResult:()=>mi,Box2dRevoluteJoint:()=>zo,Box2dRopeJoint:()=>No,Box2dStaticObject:()=>yi,Box2dTargetJoint:()=>jo,Box2dTileLayer:()=>Fo,Box2dWeldJoint:()=>Wo,Box2dWheelJoint:()=>Vo,CLEAR_BLACK:()=>ue,CLEAR_WHITE:()=>Ze,CYAN:()=>ql,CanvasLayer:()=>oi,Color:()=>xt,Ease:()=>Si,EngineObject:()=>Fe,GRAY:()=>Vl,GREEN:()=>Ya,ImageFont:()=>Zs,LOG:()=>yt,Light:()=>Co,LightSystemPlugin:()=>_o,MAGENTA:()=>Hl,Medal:()=>pi,NewgroundsMedal:()=>To,NewgroundsPlugin:()=>Ao,ORANGE:()=>Wl,PI:()=>q,PURPLE:()=>Ka,Particle:()=>ri,ParticleEmitter:()=>yo,PathFinder:()=>Yo,PathFinderNode:()=>wi,PostProcessPlugin:()=>Eo,RED:()=>nr,RandomGenerator:()=>uo,Sound:()=>ds,SoundInstance:()=>si,TextureInfo:()=>je,TileCollisionLayer:()=>ps,TileInfo:()=>Ae,TileLayer:()=>fs,TileLayerData:()=>yn,Timer:()=>Se,Tween:()=>vi,UIButton:()=>vs,UICheckbox:()=>Do,UILayout:()=>ko,UIObject:()=>ee,UISlider:()=>Io,UISystemPlugin:()=>Po,UIText:()=>gi,UITextInput:()=>Lo,UITile:()=>Oo,UIVideo:()=>Mo,Vector2:()=>it,WHITE:()=>U,YELLOW:()=>Xa,ZzFXMusic:()=>Ro,abs:()=>Z,atan2:()=>Zo,audioContext:()=>ht,audioDefaultSampleRate:()=>Wn,audioIsRunning:()=>hs,audioMasterGain:()=>Ge,box2d:()=>m,box2dDebug:()=>Jr,box2dInit:()=>ad,box2dSetDebug:()=>rd,cameraAngle:()=>Y,cameraFit:()=>rh,cameraPos:()=>Tt,cameraScale:()=>W,canvasClearColor:()=>Xe,canvasColorTiles:()=>Ai,canvasFixedSize:()=>Pn,canvasMaxAspect:()=>Rn,canvasMaxSize:()=>Cn,canvasMinAspect:()=>Zn,canvasPixelRatio:()=>Ye,canvasPixelated:()=>or,ceil:()=>is,clamp:()=>j,combineCanvases:()=>br,cos:()=>at,debug:()=>It,debugCircle:()=>jt,debugClear:()=>Ml,debugLine:()=>be,debugOverlap:()=>co,debugOverlay:()=>Re,debugPoint:()=>Qo,debugPointSize:()=>Da,debugPoly:()=>Il,debugRect:()=>pt,debugScreenshot:()=>Ma,debugShowErrors:()=>kl,debugText:()=>_n,debugVideoCaptureIsActive:()=>xe,debugVideoCaptureStart:()=>ka,debugVideoCaptureStop:()=>Ga,debugWatermark:()=>Ti,distanceAngle:()=>zl,distanceWrap:()=>tr,drawCanvas2D:()=>wn,drawCircle:()=>Qs,drawCircleGradient:()=>sh,drawContext:()=>St,drawCount:()=>we,drawCrescent:()=>ud,drawEllipse:()=>ec,drawEllipseGradient:()=>nc,drawLine:()=>hn,drawLineList:()=>fo,drawNineSlice:()=>Ac,drawNineSliceScreen:()=>cd,drawPoly:()=>Gn,drawRect:()=>Ks,drawRectGradient:()=>th,drawRegularPoly:()=>tc,drawText:()=>ih,drawTextScreen:()=>$e,drawTextureWrapped:()=>eh,drawThreeSlice:()=>Ec,drawThreeSliceScreen:()=>ld,drawTile:()=>Rt,enablePhysicsSolver:()=>Ri,engineAddPlugin:()=>vn,engineImageFont:()=>rc,engineInit:()=>Pl,engineName:()=>Js,engineObjects:()=>mt,engineObjectsCallback:()=>Ol,engineObjectsCollect:()=>Oa,engineObjectsCollide:()=>Ko,engineObjectsDestroy:()=>Ll,engineObjectsRaycast:()=>Dl,engineObjectsUpdate:()=>La,engineVersion:()=>Us,fetchJSON:()=>Xl,floor:()=>bt,fontDefault:()=>ws,formatTime:()=>sr,frame:()=>Ra,frameRate:()=>_l,gamepadConnected:()=>go,gamepadDirectionEmulateStick:()=>dr,gamepadDpad:()=>po,gamepadIsDown:()=>Ce,gamepadPrimary:()=>ft,gamepadStick:()=>ls,gamepadStickCount:()=>ac,gamepadVibrate:()=>Sh,gamepadVibrateStop:()=>wh,gamepadWasPressed:()=>Ar,gamepadWasReleased:()=>vh,gamepadsEnable:()=>Pi,getCameraSize:()=>ic,getCrescentPoints:()=>_c,getNoteFrequency:()=>dc,getPaused:()=>Cl,glAntialias:()=>Lr,glCanvas:()=>Q,glCircleSides:()=>Ts,glClearCanvas:()=>mc,glClearRect:()=>wc,glCompileShader:()=>wo,glContext:()=>g,glCopyToContext:()=>kr,glCreateProgram:()=>zn,glCreateTexture:()=>Ii,glDeleteTexture:()=>xc,glDraw:()=>ms,glDrawColoredPoints:()=>jr,glDrawOutlineTransform:()=>Fr,glDrawPoints:()=>Sc,glDrawPointsTransform:()=>Gr,glDrawUntextured:()=>vc,glEnable:()=>G,glFlush:()=>At,glSetAntialias:()=>Yh,glSetRenderTarget:()=>Qn,glSetTexture:()=>Ir,glSetTextureData:()=>Mr,glSetTextureWrap:()=>bc,gravity:()=>Bt,headlessMode:()=>B,hsl:()=>Le,hypot:()=>Fa,inputClear:()=>Ps,inputClearKey:()=>wr,inputMouseMoveThreshold:()=>Sr,inputPreventDefault:()=>Ln,inputWASDEmulateDirection:()=>ts,isArray:()=>ce,isColor:()=>z,isFullscreen:()=>oc,isIntersecting:()=>za,isNumber:()=>P,isOnScreen:()=>ah,isOverlapping:()=>Hs,isPowerOfTwo:()=>os,isStringLike:()=>J,isTouchDevice:()=>Zt,isUsingGamepad:()=>Dn,isVector2:()=>L,keyDirection:()=>bh,keyIsDown:()=>Ct,keyWasPressed:()=>Ot,keyWasReleased:()=>Tr,lastInputDevice:()=>qe,lerp:()=>Nt,lerpAngle:()=>Jl,lerpWrap:()=>Na,lightSystem:()=>V,lineTest:()=>Ua,log2:()=>ja,mainCanvas:()=>F,mainCanvasSize:()=>I,mainContext:()=>ct,max:()=>X,medalDisplaySize:()=>di,medalDisplaySlideTime:()=>On,medalDisplayTime:()=>hi,medals:()=>bs,medalsForEach:()=>Mi,medalsInit:()=>Zh,medalsPreventUnlock:()=>Br,medalsReset:()=>td,min:()=>K,mod:()=>Qt,mouseDelta:()=>xr,mouseDeltaScreen:()=>ge,mouseInWindow:()=>ti,mouseIsDown:()=>ns,mousePos:()=>_e,mousePosScreen:()=>Ft,mouseWasPressed:()=>cs,mouseWasReleased:()=>xh,mouseWheel:()=>vr,nearestPowerOfTwo:()=>Ul,newgrounds:()=>xs,noise1D:()=>Zl,noise2D:()=>tu,objectDefaultAngleDamping:()=>lr,objectDefaultDamping:()=>cr,objectDefaultFriction:()=>hr,objectDefaultMass:()=>ar,objectDefaultRestitution:()=>ur,objectMaxSpeed:()=>Oe,oscillate:()=>Ja,particleEmitRateScale:()=>Xs,paused:()=>ve,percent:()=>Mt,percentLerp:()=>Nl,playSamples:()=>Pr,pointerLockExit:()=>Eh,pointerLockIsActive:()=>cc,pointerLockRequest:()=>Ah,postProcess:()=>Lt,primitiveCount:()=>Te,rand:()=>ut,randBool:()=>Va,randColor:()=>lo,randInCircle:()=>Ha,randInt:()=>er,randSign:()=>Wa,randVec2:()=>qa,readSaveData:()=>Kl,rgb:()=>N,round:()=>Ws,saveCanvas:()=>Qa,saveDataURL:()=>rs,saveText:()=>Yl,screenToWorld:()=>Cs,screenToWorldDelta:()=>sc,screenToWorldTransform:()=>Rs,setAdditiveBlendMode:()=>as,setCameraAngle:()=>nu,setCameraPos:()=>eu,setCameraScale:()=>su,setCanvasClearColor:()=>ru,setCanvasColorTiles:()=>ou,setCanvasFixedSize:()=>uu,setCanvasMaxAspect:()=>lu,setCanvasMaxSize:()=>au,setCanvasMinAspect:()=>cu,setCanvasPixelRatio:()=>du,setCanvasPixelated:()=>Za,setCursor:()=>hh,setDebugKey:()=>Zu,setDebugWatermark:()=>Qu,setEnablePhysicsSolver:()=>Su,setFontDefault:()=>fu,setGLCircleSides:()=>mu,setGLEnable:()=>yu,setGamepadDirectionEmulateStick:()=>Ou,setGamepadsEnable:()=>Lu,setGravity:()=>Ru,setHeadlessMode:()=>gu,setInputMouseMoveThreshold:()=>ph,setInputPreventDefault:()=>fh,setInputWASDEmulateDirection:()=>Du,setMedalDisplaySize:()=>sd,setMedalDisplaySlideTime:()=>nd,setMedalDisplayTime:()=>ed,setMedalsPreventUnlock:()=>id,setObjectDefaultAngleDamping:()=>Au,setObjectDefaultDamping:()=>Tu,setObjectDefaultFriction:()=>_u,setObjectDefaultMass:()=>wu,setObjectDefaultRestitution:()=>Eu,setObjectMaxSpeed:()=>Cu,setParticleEmitRateScale:()=>Pu,setPaused:()=>Rl,setShowSplashScreen:()=>pu,setSoundDefaultRange:()=>$u,setSoundDefaultTaper:()=>Ku,setSoundEnable:()=>Xu,setSoundVolume:()=>Yu,setTileDefaultBleed:()=>vu,setTileDefaultPadding:()=>xu,setTileDefaultSize:()=>bu,setTilesPixelated:()=>hu,setTimeScale:()=>iu,setTouchGamepadAlpha:()=>Vu,setTouchGamepadAnalog:()=>zu,setTouchGamepadButtonCount:()=>Fu,setTouchGamepadCenterButtonSize:()=>Gu,setTouchGamepadDisplayTime:()=>Wu,setTouchGamepadEnable:()=>Mu,setTouchGamepadFloating:()=>Ju,setTouchGamepadLeftButtonCount:()=>Bu,setTouchGamepadLeftStick:()=>ju,setTouchGamepadPassthrough:()=>ku,setTouchGamepadRightStick:()=>Nu,setTouchGamepadSize:()=>Uu,setTouchGamepadVibration:()=>qu,setTouchInputEnable:()=>Iu,setVibrateEnable:()=>Hu,shareURL:()=>$l,showSplashScreen:()=>rr,sign:()=>Kt,sin:()=>tt,smoothStep:()=>qs,soundDefaultRange:()=>gr,soundDefaultTaper:()=>yr,soundEnable:()=>Jt,soundVolume:()=>gn,speak:()=>Nh,speakStop:()=>zh,tan:()=>Ba,textureInfos:()=>en,tile:()=>_s,tileCollisionGetData:()=>ii,tileCollisionLayers:()=>Ke,tileCollisionRaycast:()=>fc,tileCollisionTest:()=>Ve,tileDefaultBleed:()=>Ci,tileDefaultPadding:()=>_i,tileDefaultSize:()=>Ei,tileLayersLoad:()=>Uh,tilesPixelated:()=>mn,time:()=>Ht,timeDelta:()=>$o,timeReal:()=>Qe,timeScale:()=>ir,toggleFullscreen:()=>uh,touchGamepadAlpha:()=>pr,touchGamepadAnalog:()=>As,touchGamepadButtonCount:()=>Jn,touchGamepadCenterButtonSize:()=>le,touchGamepadDisplayTime:()=>es,touchGamepadEnable:()=>tn,touchGamepadFloating:()=>nn,touchGamepadLeftButtonCount:()=>Un,touchGamepadLeftStick:()=>Sn,touchGamepadPassthrough:()=>fr,touchGamepadRightStick:()=>Vn,touchGamepadSize:()=>zt,touchGamepadVibration:()=>Ys,touchInputEnable:()=>un,tweenProperty:()=>hd,tweenStopAll:()=>dd,tweenUpdate:()=>Pc,uiDebug:()=>zr,uiSetDebug:()=>od,uiSystem:()=>E,usingGamepadInput:()=>mh,usingKeyboardInput:()=>yh,usingMouseInput:()=>gh,vec2:()=>b,vibrate:()=>Er,vibrateEnable:()=>Es,vibrateStop:()=>Th,workCanvas:()=>Me,workContext:()=>We,workReadCanvas:()=>me,workReadContext:()=>De,worldToScreen:()=>Tn,worldToScreenDelta:()=>oh,writeSaveData:()=>Ql,zzfx:()=>Jh,zzfxG:()=>Oi,zzfxM:()=>Tc});function Cl(){return ve}function Rl(n=!0){ve=n}function vn(n,t,e,s){f(!dn.find(o=>o.update===n&&o.render===t&&o.glContextLost===e&&o.glContextRestored===s));let i=new ro(n,t,e,s);dn.push(i)}async function Pl(n,t,e,s,i,o=[],r){if(Pa&&console.log(`${Js} Engine v${Us}`),f(!ct,"engine already initialized"),ct)return;f(ce(o),"pass in images as array"),document.body||document.documentElement.appendChild(document.createElement("body")),r||(r=document.body),n||(n=()=>{}),t||(t=()=>{}),e||(e=()=>{}),s||(s=()=>{}),i||(i=()=>{});function a(){I=b(F.width,F.height),ct.imageSmoothingEnabled=!mn,So()}function c(y=0){let x=y-so;so||(x=0),so=y,(It||Ti)&&(Vs=Nt(Vs,1e3/(x||1),.05));let v=It&&Ct("Equal"),T=It&&Ct("Minus"),C=v?10:T?.1:1;Qe+=x*C/1e3;let w=ir*C;x*=w,pe+=ve?0:x,w<=1&&(pe=K(pe,50));let _=!1;if(ve){_=!0,l(),wa(),dn.forEach(S=>{var R;return(R=S.update)==null?void 0:R.call(S)});for(let S of mt)S.parent||S.updateTransforms();ba(),e(),Ta(),xe()&&A()}else{let S=0;for(pe<0&&pe>-9&&(S=pe,pe=0);pe>=0;pe-=1e3/60)Ht=Ra++/60,_=!0,l(),wa(),t(),dn.forEach(R=>{var M;return(M=R.update)==null?void 0:M.call(R)}),La(),ba(),e(),Ta(),xe()&&A();pe+=S}xe()||A(),requestAnimationFrame(c);function A(){if(!B){_||l(),a(),s(),mt.sort((S,R)=>S.renderOrder-R.renderOrder);for(let S of mt)S.destroyed||S.render();i(),dn.forEach(S=>{var R;return(R=S.render)==null?void 0:R.call(S)}),Ch(),Fl(),At(),jl(),we=0,Te=0}}}function l(){if(!B){if(Pn.x){I=Pn.copy();let y=innerWidth/innerHeight,x=Pn.x/Pn.y,v=yRn){let _=I.y*Rn|0;I.x=K(_,Cn.x)}else if(T0&&!G&&(ct.fillStyle=Xe.toString(),ct.fillRect(0,0,I.x,I.y),ct.fillStyle=et.toString()),ct.lineJoin="round",ct.lineCap="round"}}if(B)return d();qh(r);let u="margin:0;overflow:hidden;background:#000;user-select:none;-webkit-user-select:none;touch-action:none;-webkit-touch-callout:none";r.style.cssText=u,F=r.appendChild(document.createElement("canvas")),St=ct=F.getContext("2d"),_h(),Bh(),Gl();let h="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)";F.style.cssText=h,Q&&(Q.style.cssText=h),Za(or),l(),So(),Me=new OffscreenCanvas(64,64),We=Me.getContext("2d"),me=new OffscreenCanvas(64,64),De=me.getContext("2d",{willReadFrequently:!0});let p=o.map((y,x)=>va(x,y));return o.length||p.push(va(0)),p.push(dh()),rr&&p.push(new Promise(y=>{let x=0;v();function v(){Ps(),Qh(x+=.01),x>1?y():setTimeout(v,16)}})),await Promise.all(p),d();async function d(){await n(),c()}}function La(){Ko=mt.filter(t=>t.collideSolidObjects);function n(t){if(!t.destroyed){t.update();for(let e of t.children)n(e)}}for(let t of mt)if(!(t.parent||t.destroyed)){t.update(),t.updatePhysics();for(let e of t.children)n(e);t.updateTransforms()}mt=mt.filter(t=>!t.destroyed)}function Ll(n=!0){for(let t of mt)t.parent||t.destroy(n);mt=mt.filter(t=>!t.destroyed)}function Oa(n,t,e=mt){let s=[];if(n)if(t instanceof it)for(let i of e)i.isOverlapping(n,t)&&s.push(i);else{let i=t*t;for(let o of e)n.distanceSquared(o.pos)e(i))}function Dl(n,t,e=mt){let s=[];for(let i of e)i.collideRaycast&&za(n,t,i.pos,i.size)&&(ae&&pt(i.pos,i.size,"#f00"),s.push(i));return ae&&be(n,t,s.length?"#f00":"#00f",.02),s}function f(n,...t){if(!n)throw console.assert(n,...t),new Error("Assert failed!")}function yt(...n){console.log(...n)}function pt(n,t=b(),e=U,s=0,i=0,o=!1,r=!1){f(L(n),"pos must be a vec2"),f(L(t),"size must be a vec2"),f(J(e)||z(e),"color is invalid"),f(P(s),"time must be a number"),f(P(i),"angle must be a number"),z(e)&&(e=e.toString());let a=new Se(s);He.push({pos:n.copy(),size:t.copy(),color:e,timer:a,angle:i,fill:o,screenSpace:r})}function Il(n,t,e=U,s=0,i=0,o=!1,r=!1){f(L(n),"pos must be a vec2"),f(ce(t),"points must be an array"),f(J(e)||z(e),"color is invalid"),f(P(s),"time must be a number"),f(P(i),"angle must be a number"),z(e)&&(e=e.toString()),n=n.copy(),t=t.map(c=>c.copy());let a=new Se(s);He.push({pos:n,points:t,color:e,timer:a,angle:i,fill:o,screenSpace:r})}function jt(n,t=0,e=U,s=0,i=!1,o=!1){f(L(n),"pos must be a vec2"),f(P(t),"size must be a number"),f(J(e)||z(e),"color is invalid"),f(P(s),"time must be a number"),z(e)&&(e=e.toString()),n=n.copy();let r=new Se(s);He.push({pos:n,size:t,color:e,timer:r,angle:0,fill:i,screenSpace:o})}function Qo(n,t,e,s,i=!1){pt(n,void 0,t,e,s,!1,i)}function be(n,t,e,s=.1,i=0,o=!1){f(L(n),"posA must be a vec2"),f(L(t),"posB must be a vec2"),f(P(s),"width must be a number");let r=b((t.x-n.x)/2,(t.y-n.y)/2),a=b(s,r.length()*2);pt(n.add(r),a,e,i,r.angle(),!0,o)}function co(n,t,e,s,i,o,r=!1){f(L(n),"posA must be a vec2"),f(L(e),"posB must be a vec2"),f(L(t),"sizeA must be a vec2"),f(L(s),"sizeB must be a vec2");let a=b(K(n.x-t.x/2,e.x-s.x/2),K(n.y-t.y/2,e.y-s.y/2)),c=b(X(n.x+t.x/2,e.x+s.x/2),X(n.y+t.y/2,e.y+s.y/2));pt(a.lerp(c,.5),c.subtract(a),i,o,0,!1,r)}function _n(n,t,e=1,s=U,i=0,o=0,r="monospace",a=!1){f(J(n),"text must be a string"),f(L(t),"pos must be a vec2"),f(P(e),"size must be a number"),f(J(s)||z(s),"color is invalid"),f(P(i),"time must be a number"),f(P(o),"angle must be a number"),f(J(r),"font must be a string"),z(s)&&(s=s.toString()),t=t.copy();let c=new Se(i);He.push({text:n,pos:t,size:e,color:s,timer:c,angle:o,font:r,screenSpace:a})}function Ml(){He=[]}function Ma(){ao=1}function kl(){let n=e=>{document.body.style="background-color:#111;margin:8px",document.body.innerHTML="
"+e},t=console.assert;console.assert=(e,...s)=>{if(t(e,...s),!e){let i=s.join(" "),o=new Error().stack;throw`Assertion failed!
 `+i+`
 `+o}},onunhandledrejection=e=>n(e.reason.stack||e.reason),onerror=(e,s,i,o)=>n(`${e}
 ${s}
-Ln ${i}, Col ${o}`)}function Gl(){Pa&&console.warn("LittleJS DEBUG build loaded. Use the release build for production.")}function ba(){It&&(Ot(Ia)&&(Pe=!Pe),Pe&&(Ot("Digit1")&&(re=!re,hn=!1),Ot("Digit2")&&(hn=!hn,re=!1),Ot("Digit3")&&(dn=!dn),Ot("Digit4")&&(ae=!ae),Ot("Digit5")&&Ma(),Ot("Digit7")&&(Gn=!Gn)),ve()?(!Pe||Ot("Digit6"))&&Ga():Pe&&Ot("Digit6")&&ka())}function Fl(){if(ve())return;Ct();let n=Te,t=Ae;ao&&(br(),Qa(G),ao=0);let e=at;if(dn&&Pi){let o=0;for(let r=0;r<8;r++)go(r)&&o++;for(let r=0;r<8;r++){if(!go(r))continue;let a=1,c=.2,l=At.add(x(-a*2,((o-1)/2-r)*a*3));_n(r,l.add(x(-a,a)),1),r===yt&&_n("Main",l.add(x(-a*2,0)),1,"#0f0");let u=me[r].length;for(let p=0;p{e.save();let o=i.pos,r=1,a=i.angle;if(i.screenSpace||(o=Sn(i.pos),r=W,a-=$),e.translate(o.x|0,o.y|0),e.rotate(a),e.scale(1,i.text?1:-1),e.fillStyle=i.color,e.strokeStyle=i.color,i.text!==void 0)e.font=i.size*r+"px "+i.font,e.textAlign="center",e.textBaseline="middle",e.fillText(i.text,0,0);else if(i.points!==void 0){e.beginPath();for(let c of i.points){let l=c.scale(r).floor();e.lineTo(l.x,l.y)}e.closePath(),i.fill&&e.fill(),e.stroke()}else if(i.size===0||i.size.x===0&&i.size.y===0){let c=Da*r;e.fillRect(-c/2,-1,c,3),e.fillRect(-1,-c/2,3,c)}else if(i.size.x!==void 0){let c=i.size.scale(r).floor(),l=c.x,u=c.y;i.fill&&e.fillRect(-l/2|0,-u/2|0,l,u),e.strokeRect(-l/2|0,-u/2|0,l,u)}else e.beginPath(),e.arc(0,0,i.size*r/2,0,9),i.fill&&e.fill(),e.stroke();e.restore()}),Xe=Xe.filter(i=>i.timer<0),s){let i=fc(s.pos,_e);i&&Ks(i.floor().add(x(.5)),x(1),B(0,1,1,.3),0,!1),ln(_e,s.pos,.1,i?B(1,0,0,.5):B(0,1,0,.5),void 0,void 0,!1);let o="mouse pos = "+_e;Qe.length&&(o+=`
+Ln ${i}, Col ${o}`)}function Gl(){Pa&&console.warn("LittleJS DEBUG build loaded. Use the release build for production.")}function ba(){It&&(Ot(Ia)&&(Re=!Re),Re&&(Ot("Digit1")&&(re=!re,fn=!1),Ot("Digit2")&&(fn=!fn,re=!1),Ot("Digit3")&&(pn=!pn),Ot("Digit4")&&(ae=!ae),Ot("Digit5")&&Ma(),Ot("Digit7")&&(kn=!kn)),xe()?(!Re||Ot("Digit6"))&&Ga():Re&&Ot("Digit6")&&ka())}function Fl(){if(xe())return;At();let n=we,t=Te;ao&&(br(),Qa(F),ao=0);let e=ct;if(pn&&Pi){let o=0;for(let r=0;r<8;r++)go(r)&&o++;for(let r=0;r<8;r++){if(!go(r))continue;let a=1,c=.2,l=Tt.add(b(-a*2,((o-1)/2-r)*a*3));_n(r,l.add(b(-a,a)),1),r===ft&&_n("Main",l.add(b(-a*2,0)),1,"#0f0");let u=ye[r].length;for(let p=0;p{e.save();let o=i.pos,r=1,a=i.angle;if(i.screenSpace||(o=Tn(i.pos),r=W,a-=Y),e.translate(o.x|0,o.y|0),e.rotate(a),e.scale(1,i.text?1:-1),e.fillStyle=i.color,e.strokeStyle=i.color,i.text!==void 0)e.font=i.size*r+"px "+i.font,e.textAlign="center",e.textBaseline="middle",e.fillText(i.text,0,0);else if(i.points!==void 0){e.beginPath();for(let c of i.points){let l=c.scale(r).floor();e.lineTo(l.x,l.y)}e.closePath(),i.fill&&e.fill(),e.stroke()}else if(i.size===0||i.size.x===0&&i.size.y===0){let c=Da*r;e.fillRect(-c/2,-1,c,3),e.fillRect(-1,-c/2,3,c)}else if(i.size.x!==void 0){let c=i.size.scale(r).floor(),l=c.x,u=c.y;i.fill&&e.fillRect(-l/2|0,-u/2|0,l,u),e.strokeRect(-l/2|0,-u/2|0,l,u)}else e.beginPath(),e.arc(0,0,i.size*r/2,0,9),i.fill&&e.fill(),e.stroke();e.restore()}),He=He.filter(i=>i.timer<0),s){let i=fc(s.pos,_e);i&&Ks(i.floor().add(b(.5)),b(1),N(0,1,1,.3),0,!1),hn(_e,s.pos,.1,i?N(1,0,0,.5):N(0,1,0,.5),void 0,void 0,!1);let o="mouse pos = "+_e;Ke.length&&(o+=`
 mouse collision = `+ii(_e)),o+=`
 
 --- object info ---
-`,o+=s.toString(),Ke(o,jt,24,B(),.05,void 0,"center","monospace")}{e.save(),e.fillStyle="#fff",e.textAlign="left",e.textBaseline="top",e.font="20px monospace",e.shadowColor="#000",e.shadowBlur=9;let r=9,a=0,c=24;if(Pe){e.fillText(`${Js} v${Us}`,r,a+=c/2),e.fillText("Time: "+sr(Ht),r,a+=c),e.fillText("FPS: "+Vs.toFixed(1)+(k?" WebGL":" Canvas2D"),r,a+=c),e.fillText("Objects: "+xt.length,r,a+=c),e.fillText("Draw Calls: "+Te,r,a+=c),e.fillText("Primitives: "+Ae,r,a+=c),e.fillText("---------",r,a+=c),e.fillStyle="#f00",e.fillText("ESC: Debug Overlay",r,a+=c),e.fillStyle=re?"#f00":"#fff",e.fillText("1: Debug Physics",r,a+=c),e.fillStyle=hn?"#f00":"#fff",e.fillText("2: Debug Particles",r,a+=c),e.fillStyle=dn?"#f00":"#fff",e.fillText("3: Debug Gamepads",r,a+=c),e.fillStyle=ae?"#f00":"#fff",e.fillText("4: Debug Raycasts",r,a+=c),e.fillStyle="#fff",e.fillText("5: Save Screenshot",r,a+=c),e.fillText("6: Toggle Video Capture",r,a+=c),e.fillStyle=Gn?"#f00":"#fff",e.fillText("7: Debug Sound",r,a+=c);let l="",u="";for(let h in H[0])Et(h,0)&&(parseInt(h)<3?u+=h+" ":l+=h+" ");u&&e.fillText("Mouse: "+u,r,a+=c),l&&e.fillText("Keys: "+l,r,a+=c);for(let h=1;hs.push(a.data),i.onstop=()=>{let a=new Blob(s,{type:"video/webm"}),c=URL.createObjectURL(a);rs(c,"capture.webm",1e3)};let o,r;if(Ut){r=new ConstantSourceNode(ft,{offset:0}),r.connect(Fe),r.start(),o=ft.createMediaStreamDestination(),Fe.connect(o);for(let a of o.stream.getAudioTracks())n.addTrack(a)}try{i.start()}catch{bt("Video capture not supported in this browser!"),r==null||r.stop();return}bt("Video capture started."),Le={mediaRecorder:i,captureTimer:e,videoTrack:t,silentAudioSource:r,audioStreamDestination:o}}function Ga(){var n,t,e;f(ve(),"Not capturing video!"),bt(`Video capture ended. ${Le.captureTimer.get().toFixed(2)} seconds recorded.`),oe.style.display="none",(n=Le.silentAudioSource)==null||n.stop(),(t=Le.mediaRecorder)==null||t.stop(),(e=Le.videoTrack)==null||e.stop(),Le=void 0}function Nl(){f(ve(),"Not capturing video!"),br(),Le.videoTrack.requestFrame(),oe.textContent="\u25CF REC "+sr(Le.captureTimer)}function Yt(n){if(It){let t=Object.keys(n),e={};t.forEach(s=>e[s]=n[s]),t.forEach(s=>{Object.defineProperty(n,s,{get:()=>e[s],set:i=>{f(!1,`Cannot modify engine constant. Attempted to set constant (${n}) property '${s}' to '${i}'.`)},enumerable:!0})})}return Object.freeze(n)}function te(n,t=1){return(n%t+t)%t}function F(n,t=0,e=1){return ne?e:n}function Mt(n,t,e){return(e-=t)?F((n-t)/e):0}function zt(n,t,e){return n+F(e)*(t-n)}function Bl(n,t,e,s,i){return zt(s,i,Mt(n,t,e))}function tr(n,t,e=1){f(e>0,"distanceWrap wrapSize must be > 0");let s=(n-t)%e;return s*2%e-s}function Ba(n,t,e,s=1){return n+F(e)*tr(t,n,s)}function zl(n,t){return tr(n,t,2*q)}function Jl(n,t,e){return Ba(n,t,e,2*q)}function qs(n){return n*n*(3-2*n)}function os(n){return!(n&n-1)}function Ul(n){return 2**is(ja(n))}function Hs(n,t,e,s=x()){let i=(n.x-e.x)*2,o=(n.y-e.y)*2,r=t.x+s.x,a=t.y+s.y;return Z(i)p)return!1;h=X(y,h)}else{if(y0?a.x+1:a.x,b=h>0?a.y+1:a.y,v=c?(y-n.x)/c:1/0,S=l?(b-n.y)/l:1/0,_=0,w=v,E=S,A=pa.x&&(T.x=a.x+1-R),M.ya.y&&(T.y=a.y+1-R),s&&(A?s.set(-u,0):s.set(0,-h)),T}(A=wURL.revokeObjectURL(n),e)}function $l(n,t,e){var s;f(J(n),"shareURL requires title string"),f(J(t),"shareURL requires url string"),(s=navigator.share)==null||s.call(navigator,{title:n,url:t}).then(()=>e==null?void 0:e())}function Kl(n,t){f(J(n),"loadData requires saveName string");let e={};try{let s=localStorage[n];if(s)try{e=JSON.parse(s)}catch{bt("readSaveData: corrupt JSON for",n,"\u2014 using defaults")}}catch{bt("readSaveData: localStorage unavailable \u2014 using defaults")}return{...t,...e}}function Ql(n,t){f(J(n),"saveData requires saveName string");try{localStorage[n]=JSON.stringify(t)}catch{bt("writeSaveData: failed to write",n)}}function ho(n){let t=(n|0)^2654435769;return t=Math.imul(t^t>>>16,2246822507),t=Math.imul(t^t>>>13,3266489909),t^=t>>>16,(t>>>0)/2**32}function Zl(n){let t=vt(n);return zt(ho(t),ho(t+1),qs(n-t))}function tu(n,t){let e=vt(n),s=vt(t),i=qs(n-e),o=qs(t-s),r=(a,c)=>ho(a+c*374761393);return zt(zt(r(e,s),r(e+1,s),i),zt(r(e,s+1),r(e+1,s+1),i),o)}function eu(n){At=n.copy()}function nu(n){$=n}function su(n){W=n}function iu(n){ir=n}function ou(n){Ai=n}function ru(n){Ye=n.copy()}function au(n){Rn=n.copy()}function cu(n){Zn=n}function lu(n){Pn=n}function uu(n){Ln=n.copy()}function Za(n){or=n,G&&(G.style.imageRendering=n?"pixelated":""),Q&&(Q.style.imageRendering=n?"pixelated":"")}function hu(n){gn=n}function du(n){$e=n}function fu(n){ws=n}function pu(n){rr=n}function gu(n){j=n}function yu(n){if(n&&!vo){console.warn("Can not enable WebGL if it was disabled on start.");return}k=n,Q&&(Q.style.display=n?"":"none")}function mu(n){Ts=n}function bu(n){Ci=n.copy()}function xu(n){Ei=n}function vu(n){_i=n}function Su(n){Ri=n}function wu(n){ar=n}function Tu(n){cr=n}function Au(n){lr=n}function Cu(n){ur=n}function Eu(n){hr=n}function _u(n){De=n}function Ru(n){Bt=n.copy()}function Pu(n){Xs=n}function Lu(n){Pi=n}function Ou(n){dr=n}function Du(n){ts=n}function Iu(n){cn=n}function Mu(n){en=n}function ku(n){fr=n}function Gu(n){le=n}function Fu(n){Un=n,n>0&&(Wn=!1)}function ju(n){xn=n,n&&(Vn=0)}function Nu(n){Vn=n,n>0&&(xn=!1)}function Bu(n){Wn=n,n&&(Un=0)}function zu(n){As=n}function Ju(n){sn=n}function Uu(n){Jt=n}function Vu(n){pr=n}function Wu(n){es=n}function qu(n){Ys=n}function Hu(n){Cs=n}function Xu(n){Ut=n}function Yu(n){fn=n,Ut&&!j&&Fe&&(Fe.gain.value=n)}function $u(n){gr=n}function Ku(n){yr=n}function Qu(n){Ti=n}function Zu(n){Ia=n}function $s(n){return n.r>=1&&n.g>=1&&n.b>=1}function mr(n){return n.r<=0&&n.g<=0&&n.b<=0&&n.a<=0}function Es(n=0,t=Ci,e=0,s=Ei,i=_i){if(f(L(n)||typeof n=="number","index must be a vec2 or number"),f(L(t)||typeof t=="number","size must be a vec2 or number"),f(P(e)||e instanceof Ne,"texture must be a number or TextureInfo"),f(P(s),"padding must be a number"),j)return new Ce;typeof t=="number"&&(f(t>0),t=new st(t,t));let o=typeof e=="number"?nn[e]:e;f(o instanceof Ne,"tile texture is not loaded"),f(o.size.x>0,"tile texture is not loaded");let r=t.x+s*2,a=t.y+s*2,c,l;if(typeof n=="number"){let h=o.size.x/r|0;c=n%h,l=n/h|0}else c=n.x,l=n.y;let u=new st(c*r+s,l*a+s);return new Ce(u,t,o,s,i)}function _t(n,t=x(1),e,s=U,i=0,o,r,a=k,c=!1,l){var p;f(L(n),"pos must be a vec2"),f(L(t),"size must be a vec2"),f(z(s),"color is invalid"),f(P(i),"angle must be a number"),f(!r||z(r),"additiveColor must be a color"),f(!l||!a,"context only supported in canvas 2D mode");let u=e==null?void 0:e.textureInfo,h=(p=e==null?void 0:e.bleed)!=null?p:0;if(a&&k)if(f(!!g,"WebGL is not enabled!"),c&&([n,t,i]=Rs(n,t,i)),u){let d=u.sizeInverse,y=e.pos.x*d.x,b=e.pos.y*d.y,v=e.size.x*d.x,S=e.size.y*d.y;if(Ir(u.glTexture),h){let _=d.x*h,w=d.y*h;ms(n.x,n.y,o?-t.x:t.x,t.y,i,y+_,b+w,y-_+v,b-w+S,s.rgbaInt(),r&&r.rgbaInt())}else ms(n.x,n.y,o?-t.x:t.x,t.y,i,y,b,y+v,b+S,s.rgbaInt(),r&&r.rgbaInt())}else{let d=r?s.add(r):s;vc(n.x,n.y,t.x,t.y,i,d.rgbaInt())}else++Te,++Ae,vn(n,t,i,o,d=>{if(u){d.scale(1,-1);let y=e.pos.x,b=e.pos.y,v=e.size.x,S=e.size.y;lh(d,u.image,y,b,v,S,-.5,-.5,1,1,s,r,h)}else{let y=r?s.add(r):s;d.fillStyle=y.toString(),d.fillRect(-.5,-.5,1,1)}},c,l)}function Ks(n,t,e,s,i,o,r){_t(n,t,void 0,e,s,!1,void 0,i,o,r)}function th(n,t,e=U,s=tn,i=0,o=k,r=!1,a){if(f(L(n),"pos must be a vec2"),f(L(t),"size must be a vec2"),f(z(e)&&z(s),"color is invalid"),f(P(i),"angle must be a number"),f(!a||!o,"context only supported in canvas 2D mode"),o&&k){f(!!g,"WebGL is not enabled!"),r&&(n=_s(n),t=t.scale(1/W),i+=$);let c=[],l=[],u=t.x/2,h=t.y/2,p=e.rgbaInt(),d=s.rgbaInt(),y=ot(-i),b=tt(-i);for(let v=4;v--;){let S=v&1?u:-u,_=v&2?h:-h,w=S*y-_*b,E=S*b+_*y,A=v&2?p:d;c.push(x(n.x+w,n.y+E)),l.push(A)}jr(c,l)}else++Te,++Ae,vn(n,t,i,!1,c=>{let l=c.createLinearGradient(0,.5,0,-.5);l.addColorStop(0,e.toString()),l.addColorStop(1,s.toString()),c.fillStyle=l,c.fillRect(-.5,-.5,1,1)},r,a)}function eh(n,t,e,s=0,i=U,o=0,r,a=k,c=!1,l){if(f(L(n),"pos must be a vec2"),f(L(t),"size must be a vec2"),f(L(e),"wrapCount must be a vec2"),f(z(i),"color is invalid"),f(P(o),"angle must be a number"),f(!r||z(r),"additiveColor must be a color"),f(!l||!a,"context only supported in canvas 2D mode"),f(!(s instanceof Ce),"pass a TextureInfo or texture index, not a TileInfo \u2014 use tileInfo.textureInfo"),j)return;let u=typeof s=="number"?nn[s]:s;if(f(u instanceof Ne,"texture not loaded"),f(u.size.x>0,"texture not loaded"),f(u.wrap,"drawTextureWrapped requires a wrap-enabled texture; call textureInfo.setWrap(true) first"),a&&k){f(!!g,"WebGL is not enabled!"),c&&([n,t,o]=Rs(n,t,o)),Ir(u.glTexture),ms(n.x,n.y,t.x,t.y,o,0,0,e.x,e.y,i.rgbaInt(),r&&r.rgbaInt());return}++Te,++Ae,c||(n=Sn(n),t=t.scale(W),o-=$);let h=!Ai||(r?$s(i.add(r))&&r.a<=0:$s(i)),p=!h&&r&&!mr(r),d=h?u.image:ch(u.image,i,r);l=l||wt,l.save(),l.translate(n.x+.5,n.y+.5),l.rotate(o),l.globalAlpha=p?1:i.a;let y=l.createPattern(d,"repeat"),b=new DOMMatrix().translate(-t.x/2,-t.y/2).scale(t.x/(e.x*d.width),t.y/(e.y*d.height));y.setTransform(b),l.fillStyle=y,l.fillRect(-t.x/2,-t.y/2,t.x,t.y),l.globalAlpha=1,l.restore()}function fo(n,t=.1,e=U,s=!1,i=x(),o=0,r=k,a=!1,c){if(f(ce(n),"points must be an array"),f(P(t),"width must be a number"),f(z(e),"color is invalid"),f(L(i),"pos must be a vec2"),f(P(o),"angle must be a number"),f(!c||!r,"context only supported in canvas 2D mode"),r&&k){f(!!g,"WebGL is not enabled!");let l=x(1);a&&([i,l,o]=Rs(i,l,o)),Fr(n,e.rgbaInt(),t,i.x,i.y,l.x,l.y,o,s)}else++Te,++Ae,vn(i,x(1),o,!1,l=>{l.strokeStyle=e.toString(),l.lineWidth=t,l.beginPath();for(let u=0;u0&&Fr(n,s.rgbaInt(),e,i.x,i.y,l.x,l.y,o)}else vn(i,x(1),o,!1,l=>{l.fillStyle=t.toString(),l.beginPath();for(let u of n)l.lineTo(u.x,u.y);l.closePath(),l.fill(),e&&(l.strokeStyle=s.toString(),l.lineWidth=e,l.stroke())},a,c)}function ec(n,t=x(1),e=U,s=0,i=0,o=nt,r=k,a=!1,c){f(L(n),"pos must be a vec2"),f(L(t),"size must be a vec2"),f(z(e)&&z(o),"color is invalid"),f(P(s),"angle must be a number"),f(P(i),"lineWidth must be a number"),f(i>=0,"lineWidth must be a positive value or 0"),f(!c||!r,"context only supported in canvas 2D mode"),i=F(i,0,K(t.x,t.y)),r&&k?tc(n,t,Ts,e,i,o,s,r,a,c):vn(n,x(1),s,!1,l=>{l.fillStyle=e.toString(),l.beginPath(),l.ellipse(0,0,t.x/2,t.y/2,0,0,9),l.fill(),i&&(l.strokeStyle=o.toString(),l.lineWidth=i,l.stroke())},a,c)}function Qs(n,t=1,e=U,s=0,i=nt,o=k,r=!1,a){f(P(t),"size must be a number"),ec(n,x(t),e,0,s,i,o,r,a)}function nc(n,t=x(1),e=U,s=tn,i=0,o=k,r=!1,a){if(f(L(n),"pos must be a vec2"),f(L(t),"size must be a vec2"),f(z(e)&&z(s),"color is invalid"),f(P(i),"angle must be a number"),f(!a||!o,"context only supported in canvas 2D mode"),!j)if(o&&k){f(!!g,"WebGL is not enabled!"),r&&(n=_s(n),t=t.scale(1/W),i+=$);let c=Ts,l=t.x/2,u=t.y/2,h=e.rgbaInt(),p=s.rgbaInt(),d=nh++,y=ot(-i),b=tt(-i),v=E=>{let A=tt(E)*l,T=ot(E)*u;return x(n.x+A*y-T*b,n.y+A*b+T*y)},S=d%c/c*q*2,_=[v(S)],w=[p];for(let E=c;E--;){let A=(E+d)%c/c*q*2;_.push(n),w.push(h),_.push(v(A)),w.push(p)}jr(_,w)}else++Te,++Ae,vn(n,t,i,!1,c=>{let l=c.createRadialGradient(0,0,0,0,0,.5);l.addColorStop(0,e.toString()),l.addColorStop(1,s.toString()),c.fillStyle=l,c.beginPath(),c.ellipse(0,0,.5,.5,0,0,9),c.fill()},r,a)}function sh(n,t=1,e=U,s=tn,i=k,o=!1,r){f(P(t),"size must be a number"),nc(n,x(t),e,s,0,i,o,r)}function vn(n,t,e=0,s=!1,i,o=!1,r=wt){f(L(n),"pos must be a vec2"),f(L(t),"size must be a vec2"),f(P(e),"angle must be a number"),f(typeof i=="function","drawFunction must be a function"),o||(n=Sn(n),t=t.scale(W),e-=$),r.save(),r.translate(n.x+.5,n.y+.5),r.rotate(e),r.scale(s?-t.x:t.x,-t.y),i(r),r.restore()}function ih(n,t,e=1,s=U,i=0,o=nt,r="center",a=ws,c="",l,u=0,h=wt){t=Sn(t),e*=W,i*=W,u-=$,u*=-1,Ke(n,t,e,s,i,o,r,a,c,l,u,h)}function Ke(n,t,e,s=U,i=0,o=nt,r="center",a=ws,c="",l,u=0,h=wt){f(J(n),"text must be a string"),f(L(t),"pos must be a vec2"),f(P(e),"size must be a number"),f(z(s),"color must be a color"),f(P(i),"lineWidth must be a number"),f(z(o),"lineColor must be a color"),f(["left","center","right"].includes(r),"align must be left, center, or right"),f(J(a),"font must be a string"),f(J(c),"fontStyle must be a string"),f(P(u),"angle must be a number");let p=(n+"").split(`
-`),d=t.y-(p.length-1)*e/2;h.save(),h.fillStyle=s.toString(),h.strokeStyle=o.toString(),h.lineWidth=i,h.textAlign=r,h.font=c+" "+e+"px "+a,h.textBaseline="middle",h.translate(t.x,d),h.rotate(-u);let y=0;p.forEach(b=>{i&&h.strokeText(b,0,y,l),h.fillText(b,0,y,l),y+=e}),h.restore()}async function va(n,t){f(P(n),"textureIndex must be a number"),f(!nn[n],"textureIndex is already loaded!"),f(!t||J(t),"image src must be a string");let e=new Image;t&&await new Promise(s=>{e.onerror=e.onload=s,e.crossOrigin="anonymous",e.src=t}),nn[n]=new Ne(e)}function _s(n){f(L(n),"screenPos must be a vec2");let t=(n.x-D.x/2+.5)/W,e=(n.y-D.y/2+.5)/-W;if($){let s=ot(-$),i=tt(-$),o=t*s-e*i,r=t*i+e*s;t=o,e=r}return new st(t+At.x,e+At.y)}function Sn(n){f(L(n),"worldPos must be a vec2");let t=n.x-At.x,e=n.y-At.y;if($){let s=ot($),i=tt($),o=t*s-e*i,r=t*i+e*s;t=o,e=r}return new st(t*W+D.x/2-.5,e*-W+D.y/2-.5)}function sc(n){f(L(n),"screenDelta must be a vec2");let t=n.x/W,e=n.y/-W;if($){let s=ot(-$),i=tt(-$),o=t*s-e*i,r=t*i+e*s;t=o,e=r}return new st(t,e)}function oh(n){f(L(n),"worldDelta must be a vec2");let t=n.x,e=n.y;if($){let s=ot($),i=tt($),o=t*s-e*i,r=t*i+e*s;t=o,e=r}return new st(t*W,e*-W)}function Rs(n,t,e=0){return f(L(n),"screenPos must be a vec2"),f(L(t),"screenSize must be a vec2"),f(P(e),"screenAngle must be a number"),[_s(n),t.scale(1/W),e+$]}function ic(){return D.scale(1/W)}function rh(n,t,e,s){f(L(n),"center must be a vec2"),f(L(t),"size must be a vec2");let i=p(e),o=p(s),r=t.x+i.left+i.right,a=t.y+i.top+i.bottom,c=D.x-o.left-o.right,l=D.y-o.top-o.bottom;if(!(r>0&&a>0&&c>0&&l>0))return W;W=K(c/r,l/a);let u=x(i.right-i.left,i.top-i.bottom).scale(.5),h=x(o.right-o.left,o.top-o.bottom).scale(.5/W);return At=n.add(u).add(h),W;function p(d){return(d===void 0||P(d))&&(d=x(d)),L(d)?{top:d.y,right:d.x,bottom:d.y,left:d.x}:{top:d.top||0,right:d.right||0,bottom:d.bottom||0,left:d.left||0}}}function ah(n,t=0){if(f(L(n),"pos must be a vec2"),f(L(t)||P(t),"size must be a vec2 or number"),!W)return!1;let e=n.x-At.x,s=n.y-At.y;if($){let r=ot($),a=tt($),c=e*r-s*a,l=e*a+s*r;e=c,s=l}e*=W*2,s*=-W*2,t instanceof st&&(t=t.length()),t*=W;let i=D.x,o=D.y;return e+t>-i&&e-t-o&&s-t{n.onerror=n.onload=a,n.crossOrigin="anonymous",n.src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUAAAAAeAQMAAABnrVXaAAAABlBMVEUAAAD///+l2Z/dAAAAAXRSTlMAQObYZgAAAjpJREFUOMu9kzFu2zAUhn+CAROgqrk+B2l0BWYxMjlXeYaAtFtbdA1sGgHqRQfI0CNkSG5AwYB0BQ8d5Bsomwah6CPVeGg6tEPzAxLwyI+P78cP4u9lNO9OoMKnLMOobG5020/yaj/MrRcCGh1gBbyiLTPJEYaIiom5KM9Jq7KgynMGtb6L4GL4MF2H4LQKCXTvDVw2I4MsgZT7QLExdiutH+D08VOP3INXRrWX1/mmpbkNgAPYRVANb4xpcegYvhiNbIXauQICEjBuYLfMakaakWQeXxiZ0VDtuJCKs3ztMV59QtsHJNcRxDzfdL21ty3PrfIcXTN+E+GFAv6T5nbT9jd50/WFxb5ksdAv49qS6ouymG66ji08UMT6moykYLAo+V0j23GN4m829ZySAD5K7QsBfQTvOG8eE+gTeGYRAmnNAubN3hf5Zv9tJWDHp/VTuaSm7SN4fyINQqaNO3RMVxvpSPXnOChnRNvFcGY0gnwiPswYwTKVPE0zVtX3mTEIOoFzaqLrGuJaV+Uqumb71fVk/VoOH3cdLNQP/FHi8hV0CQNoqBZsUPlLPMsdCJro9QAaQQ0woDy9BJm0eTxCFnO9srcYlhNVlfR2EyTrph1uUtbUtAJifwRgrKuYdXVHeb0YI3QpawohQHkloI3J5FuVwI5ORxC9k2Tuz9Ir1IjgeIPGMHYkAZe2RuYkmWFmt3gGbTPOmBUWVTmRmHtGrfpzG/yuQNOKa6gBB/WA9khitPgl6/GP+gl2Af6tCbvaygAAAABJRU5ErkJggg=="});let t=x(),e=x(8),s=1,i=0,o=new Ne(n),r=new Ce(t,e,o,s,i);rc=new Zs(r)}function fh(n=!0){On=n}function ph(n){Sr=n}function gh(){return He==="mouse"}function yh(){return He==="keyboard"}function mh(){return He==="gamepad"}function wr(n,t=0,e=!0,s=!0,i=!0){H[t]&&(H[t][n]&=~((e?1:0)|(s?2:0)|(i?4:0)))}function Ps(){H.length=0,H[0]=[],ne.length=0,yn.length=0,Ls.length=0,me.length=0,rn.length=0}function Et(n,t=0){var e;return f(J(n),"key must be a number or string"),f(t>0||typeof n!="number"||n<3,"use code string for keyboard"),!!(((e=H[t])==null?void 0:e[n])&1)}function Ot(n,t=0){var e;return f(J(n),"key must be a number or string"),f(t>0||typeof n!="number"||n<3,"use code string for keyboard"),!!(((e=H[t])==null?void 0:e[n])&2)}function Tr(n,t=0){var e;return f(J(n),"key must be a number or string"),f(t>0||typeof n!="number"||n<3,"use code string for keyboard"),!!(((e=H[t])==null?void 0:e[n])&4)}function bh(n="ArrowUp",t="ArrowDown",e="ArrowLeft",s="ArrowRight"){f(J(n),"up key must be a string"),f(J(t),"down key must be a string"),f(J(e),"left key must be a string"),f(J(s),"right key must be a string");let i=o=>Et(o)?1:0;return x(i(s)-i(e),i(n)-i(t))}function ns(n){return f(P(n),"mouse button must be a number"),Et(n)}function cs(n){return f(P(n),"mouse button must be a number"),Ot(n)}function xh(n){return f(P(n),"mouse button must be a number"),Tr(n)}function Re(n,t=yt){return f(P(n),"button must be a number"),f(P(t),"gamepad must be a number"),Et(n,t+1)}function Ar(n,t=yt){return f(P(n),"button must be a number"),f(P(t),"gamepad must be a number"),Ot(n,t+1)}function vh(n,t=yt){return f(P(n),"button must be a number"),f(P(t),"gamepad must be a number"),Tr(n,t+1)}function ls(n,t=yt){var e,s;return f(P(n),"stick must be a number"),f(P(t),"gamepad must be a number"),(s=(e=me[t])==null?void 0:e[n])!=null?s:x()}function po(n=yt){var t;return f(P(n),"gamepad must be a number"),(t=rn[n])!=null?t:x()}function go(n=yt){return f(P(n),"gamepad must be a number"),!!H[n+1]}function ac(n=yt){var t,e;return f(P(n),"gamepad must be a number"),(e=(t=me[n])==null?void 0:t.length)!=null?e:0}function Sh(n=yt,t=200,e=1,s=1,i=0){var r,a,c;if(f(P(n),"gamepad must be a number"),!Cs||j)return;let o=(r=navigator==null?void 0:navigator.getGamepads)==null?void 0:r.call(navigator)[n];(c=(a=o==null?void 0:o.vibrationActuator)==null?void 0:a.playEffect)==null||c.call(a,"dual-rumble",{duration:t,strongMagnitude:e,weakMagnitude:s,startDelay:i})}function wh(n=yt){var e,s,i;if(f(P(n),"gamepad must be a number"),!Cs||j)return;let t=(e=navigator==null?void 0:navigator.getGamepads)==null?void 0:e.call(navigator)[n];(i=(s=t==null?void 0:t.vibrationActuator)==null?void 0:s.reset)==null||i.call(s)}function Cr(n=100){var t;f(P(n)||ce(n),"pattern must be a number or array"),Cs&&!j&&((t=navigator==null?void 0:navigator.vibrate)==null||t.call(navigator,n))}function Th(){Cr(0)}function Ah(){var n;!ee&&((n=G.requestPointerLock)==null||n.call(G))}function Ch(){var n;(n=document.exitPointerLock)==null||n.call(document)}function cc(){return document.pointerLockElement===G}function Eh(){if(j)return;document.addEventListener("keydown",n),document.addEventListener("keyup",t),document.addEventListener("mousedown",s),document.addEventListener("mouseup",i),document.addEventListener("mousemove",o),document.addEventListener("mouseleave",r),document.addEventListener("wheel",a,{passive:!1}),document.addEventListener("contextmenu",c),document.addEventListener("blur",l),ee&&cn&&u();function n(p){if(p.repeat||(H[0][p.code]=3,ts&&(H[0][e(p.code)]=3)),!On||!p.cancelable||!document.hasFocus()||p.ctrlKey||p.metaKey||p.altKey||b(p.target)||b(document.activeElement))return;let d=typeof p.key=="string"&&p.key.length===1;(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight","Space","Tab","Backspace"].includes(p.code)||d)&&p.preventDefault();function b(v){let S=v==null?void 0:v.tagName;return(v==null?void 0:v.isContentEditable)||["INPUT","TEXTAREA","SELECT"].includes(S)}}function t(p){H[0][p.code]=H[0][p.code]&2|4,ts&&(H[0][e(p.code)]=4)}function e(p){return ts?p==="KeyW"?"ArrowUp":p==="KeyS"?"ArrowDown":p==="KeyA"?"ArrowLeft":p==="KeyD"?"ArrowRight":p:p}function s(p){if(ee&&cn)return;Ut&&!j&&ft&&!hs()&&ft.resume(),H[0][p.button]=3;let d=jt;jt=h(x(p.x,p.y)),ye=ye.add(jt.subtract(d)),On&&p.cancelable&&document.hasFocus()&&p.preventDefault()}function i(p){ee&&cn||(H[0][p.button]=H[0][p.button]&2|4)}function o(p){ti=!0;let d=jt;jt=h(x(p.x,p.y));let y=cc()?x(p.movementX,p.movementY):jt.subtract(d);ye=ye.add(y)}function r(){ti=!1}function a(p){p.ctrlKey||(vr+=Zt(p.deltaY)),On&&p.cancelable&&document.hasFocus()&&p.preventDefault()}function c(p){p.preventDefault()}function l(){Ps(),Me.clear(),ne.length=0,yn.length=0,Ls.length=0}function u(){document.addEventListener("touchstart",y=>d(y),{passive:!1}),document.addEventListener("touchmove",y=>d(y),{passive:!1}),document.addEventListener("touchend",y=>d(y),{passive:!1});let p;function d(y){if(cn){if(Ut&&!j&&ft&&!hs()&&ft.resume(),!en||fr){let b=w=>us.includes(w.target)||w.target===an,v=[];for(let w of y.touches)b(w)||v.push(w);let S=v.length,_=0;if(S){let w=x(v[0].clientX,v[0].clientY),E=jt;jt=h(w),p?ye=ye.add(jt.subtract(E)):H[0][_]=3}else p&&(H[0][_]=H[0][_]&2|4);p=S}return On&&y.cancelable&&document.hasFocus()&&y.preventDefault(),!0}}}function h(p){let d=G.getBoundingClientRect(),y=Mt(p.x,d.left,d.right),b=Mt(p.y,d.top,d.bottom);return x(y*G.width,b*G.height)}}function wa(){if(j)return;!(cn&&ee)&&!document.hasFocus()&&Ps(),_e=_s(jt),xr=sc(ye),Rh(),t(),n();function n(){let e=ns(0)||ns(1)||ns(2)||ye.length()>Sr,s=!1;for(let o=ac();o--&&!s;)s=ls(o).lengthSquared()>.04;for(let o=17;o--&&!s;)s=Re(o);let i=!1;for(let o in H[0])if(isNaN(+o)&&H[0][o]&1){i=!0;break}s?He="gamepad":e?He="mouse":i&&(He="keyboard"),In=He==="gamepad"}function t(){var r,a,c,l,u,h,p;let e=d=>{let v=S=>S>.3?Mt(S,.3,.8):S<-.3?-Mt(-S,.3,.8):0;return x(v(d.x),v(-d.y)).clampLength()};if(en&&ee){if(f(!xn||!Vn,"set touchGamepadLeftStick or touchGamepadLeftButtonCount, not both"),f(!Wn||!Un,"set touchGamepadRightStick or touchGamepadButtonCount, not both"),!jn.isSet())return;yt=0;let d=(r=me[0])!=null?r:me[0]=[],y=(a=rn[0])!=null?a:rn[0]=x();d.length=0,y.set();for(let v=0;v<2;v++){if(!Be(v))continue;let S=Rr(v);d[S]=x();let _=(c=yn[v])!=null?c:x();if(As)d[S]=e(_);else if(_.lengthSquared()>.3){let w=F(Ws(_.x),-1,1),E=F(Ws(_.y),-1,1);d[S]=x(w,-E).clampLength(),S||y.set(w,-E)}}let b=(l=H[1])!=null?l:H[1]=[];for(let v=12;v--;){let S=Re(v,0);b[v]=ne[v]?S?1:3:S?4:0,Ys&&b[v]===3&&(v===9||Ph(v))&&Cr(Ys)}return}try{if(!Pi||!(navigator!=null&&navigator.getGamepads))return}catch{return}if(!It&&!document.hasFocus())return;let s=8,i=navigator.getGamepads(),o=K(s,i.length);for(let d=0;d>1]=e(x(y.axes[w],y.axes[w+1]));let _=!1;for(let w=y.buttons.length;w--;){let E=y.buttons[w],A=Re(w,d);b[w]=E.pressed?A?1:3:A?4:0,E.pressed&&(!E.value||E.value>.9)&&(_=!0)}_&&(io[d]=!0,io[yt]||(yt=d)),y.mapping==="standard"&&S.set((Re(15,d)&&1)-(Re(14,d)&&1),(Re(12,d)&&1)-(Re(13,d)&&1)),dr&&(S.x||S.y)&&(v[0]=S.clampLength())}en&&In&&jn.unset()}}function Ta(){if(!j){for(let n of H)for(let t in n)n[t]&=1;vr=0,xr=x(),ye=x()}}function _h(){Ih()}function Rh(){if(Ve||!en||!ee||j||!document.body)return;let n=Ve=document.createElement("div");n.style.cssText="position:fixed;inset:0;z-index:50;pointer-events:none;opacity:0;touch-action:none;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;transition:opacity .2s;box-sizing:border-box;padding:env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left)";let t=lc=document.createElement("div");t.style.cssText="position:relative;width:100%;height:100%;pointer-events:none",n.appendChild(t);let e=Er=document.createElementNS(ni,"svg");e.style.cssText="position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible;fill:none;stroke:#fff;stroke-width:3",t.appendChild(e);let s=()=>{let i=document.createElement("div");return i.style.cssText="position:absolute;pointer-events:auto;touch-action:none",i.addEventListener("pointerdown",o=>Fh(o,i)),i.addEventListener("pointermove",o=>jh(o)),i.addEventListener("pointerup",o=>Aa(o)),i.addEventListener("pointercancel",o=>Aa(o)),t.appendChild(i),i};us[0]=s(),us[1]=s(),an=s(),addEventListener("resize",()=>Nn=!0),document.body.appendChild(n),Nn=!0}function Li(){return lc.getBoundingClientRect()}function Be(n){return n?Wn:xn}function wn(n){return n?Un:Vn}function _r(n){return n?0:4}function Rr(n){return n&&xn?1:0}function Bn(n){return Be(n)||wn(n)>0}function Ph(n){for(let t=0;t<2;t++){let e=_r(t);if(!Be(t)&&n>=e&&no.style.cssText="position:absolute;pointer-events:auto;touch-action:none;"+r;if(Se){for(let o of us)o.style.display="none";le?(i(an,"inset:0"),an.style.display=""):an.style.display="none"}else{for(let r=0;r<2;r++){let a=us[r],c=r?"right":"left";if(a.style.display=Bn(r)?"":"none",sn){let l=Bn(r?0:1)?"50%":"100%";i(a,`${c}:0;bottom:0;width:${l};height:60%`)}else i(a,`${c}:0;bottom:0;width:${3*s}px;height:${3*s}px`)}an.style.display=le?"":"none";let o=le;i(an,`left:50%;top:50%;width:${2*o}px;height:${2*o}px;transform:translate(-50%,-50%)`)}Oh(t,e),Nn=!1}function Oh(n,t){let e=Er;for(;e.firstChild;)e.removeChild(e.firstChild);let s=uc={face:[],thumb:[]},i=Jt,o=(a,c,l,u)=>{let h=document.createElementNS(ni,"circle");return h.setAttribute("cx",a),h.setAttribute("cy",c),h.setAttribute("r",l),u&&h.setAttribute("fill",u),e.appendChild(h),h},r=a=>{let c=i*.18,l=i*.5,u=a.x,h=a.y,p=document.createElementNS(ni,"path");p.setAttribute("d",`M ${u-c} ${h-l} H ${u+c} V ${h-c} H ${u+l} V ${h+c} H ${u+c} V ${h+l} H ${u-c} V ${h+c} H ${u-l} V ${h-c} H ${u-c} Z`),e.appendChild(p)};for(let a=0;a<2;a++){let c=wn(a),l=_r(a),u=Ge(a,n,t);if(Be(a))As?o(u.x,u.y,i/2):r(u),s.thumb[a]=o(u.x,u.y,i/4,"#fff");else if(c===1)s.face[l]=o(u.x,u.y,i/2,"#000");else for(let h=0;h2?p:K(p,c-1);d=d===3?2:d===2?3:d;let y=x().setDirection(p,i/2);c===2&&(y.x*=-1),a||(y.x*=-1);let b=u.add(y);s.face[l+d]=o(b.x,b.y,i/4,"#000")}}It&&dn&&Dh(n,t)}function Dh(n,t){let e=Jt,s=Er,i=(r,a,c)=>{let l=document.createElementNS(ni,r);for(let u in a)l.setAttribute(u,a[u]);l.setAttribute("stroke",c),l.setAttribute("stroke-width",2),l.setAttribute("fill","none"),s.appendChild(l)},o=(r,a,c)=>i("circle",{cx:r.x,cy:r.y,r:a},c);i("line",{x1:n/2,y1:0,x2:n/2,y2:t},"#0f0");for(let r=0;r<2;r++)if(Be(r))if(sn){let a=t*.4,c=!Bn(r?0:1),l=c?0:r?n/2:0;i("rect",{x:l,y:a,width:c?n:n/2,height:t-a},"#0ff")}else o(Ge(r,n,t),2*e,"#0ff");else wn(r)>=1&&o(Ge(r,n,t),e,"#0ff");if(le){o(x(n/2,t/2),le,"#ff0");for(let r=0;r<2;r++)Bn(r)&&o(Ge(r,n,t),2*e,"#f0f")}}function Ih(){var l;if(!Ve||j)return;if(!en||!ee){Ve.style.display!=="none"&&(Ve.style.display="none",Me.clear(),ne.length=0,yn.length=0,Ls.length=0);return}Ve.style.display="";let n=It&&dn,t=[Un,Vn,xn,Wn,As,Jt,sn,le,Se,n].join();t!==Sa&&(Sa=t,Nn=!0),Nn&&Lh();let e=es?Mt(jn.get(),es+1,es):1,s=n||jn.isSet()&&e>0&&!Se;if(Ve.style.opacity=s?n?1:e*pr:0,!s)return;let i=Li(),o=i.width,r=i.height,a=Jt,c=uc;if(c){for(let u=0;u<2;u++)if(Be(u)&&c.thumb[u]){let p=Ge(u,o,r).add(((l=yn[u])!=null?l:x()).scale(a/2));c.thumb[u].setAttribute("cx",p.x),c.thumb[u].setAttribute("cy",p.y)}for(let u=0;u=Jt)return-1;if(i===1)return o;let a=r.subtract(t);n||(a.x*=-1);let c=i===2?a.xo:a&&Ge(r,t,e).distance(n)<2*s)return{role:"stick",side:r}}else if(wn(r)>=1){let c=kh(r,n,t,e);if(c>=0)return{role:"face",btn:c}}}if(le){for(let r=0;r<2;r++)if(Bn(r)&&Ge(r,t,e).distance(n)<2*s)return;if(x(t/2,e/2).distance(n)h.getChannelData(v).set(b)),p.buffer=h,p.playbackRate.value=e,p.loop=i,r=r||ft.createGain(),r.gain.value=t,r.connect(Fe);let d=new StereoPannerNode(ft,{pan:F(s,-1,1)});p.connect(d).connect(r),p.addEventListener("ended",()=>{r.disconnect(),d.disconnect(),c&&c(p)});let y=a*e;return p.start(0,y),It&&Gn&&bt("sound","vol",t.toFixed(2),"rate",e.toFixed(2),"pan",s.toFixed(2),i?"loop":""),p}function Jh(...n){return Pr([Oi(...n)])}function Oi(n=1,t=.05,e=220,s=0,i=0,o=.1,r=0,a=1,c=0,l=0,u=0,h=0,p=0,d=0,y=0,b=0,v=0,S=1,_=0,w=0,E=0){let A=qn,T=q*2,R=c*=500*T/A/A,M=e*=(1+dt(t,-t))*T/A,ct=0,et=0,lt=0,gt=1,kt,Ee=[],Gt=0,ut=0,Rt=0,I,N=2,Y=T*Z(E)*2/A,ht=ot(Y),it=tt(Y)/2/N,Pt=1+it,he=-2*ht/Pt,An=(1-it)/Pt,Cn=(1+Zt(E)*ht)/2/Pt,En=-(Zt(E)+ht)/Pt,de=Cn,$t=0,Hn=0,Os=0,Ds=0;for(s=s*A||9,_*=A,i*=A,o*=A,v*=A,l*=500*T/A**3,y*=T/A,u*=T/A,h*=A,p=p*A|0,kt=s+_+i+o+v|0;ut1?r>2?r>3?r>4?Gt/T%14?Rt:Zt(Rt)*Z(Rt)**a)*(utut?0:(uth&&(e+=u,M+=u,gt=0),p&&!(++et%p)&&(e=M,c=R,gt||(gt=1));return Ee}function ii(n,t=!0){for(let e of Qe)if((!t||e.isSolid)&&n.arrayCheck(e.size)){let s=e.getCollisionData(n);if(s)return s}return 0}function We(n,t=x(),e,s=!0){for(let i of Qe)if((!s||i.isSolid)&&i.collisionTest(n,t,e))return i}function fc(n,t,e,s,i=!0){let o,r,a,c=s&&x();for(let l of Qe)if(!i||l.isSolid){let u=l.collisionRaycast(n,t,e,c);if(u){let h=n.distanceSquared(u);(o===void 0||h{k=!1,Q.style.display="none",e.preventDefault(),bt("WebGL context lost! Switching to Canvas2d rendering.");for(let s of ss)s.glTexture=void 0;Xt=void 0,Tt=0,mn=!1,un.forEach(s=>{var i;return(i=s.glContextLost)==null?void 0:i.call(s)})}),Q.addEventListener("webglcontextrestored",()=>{k=!0,Q.style.display="",bt("WebGL context restored, reinitializing..."),t();for(let e of ss)e.glTexture=Ii(e.image,e.wrap);un.forEach(e=>{var s;return(s=e.glContextRestored)==null?void 0:s.call(e)})});function t(){ai=Jn(`#version 300 es
+`,o+=s.toString(),$e(o,Ft,24,N(),.05,void 0,"center","monospace")}{e.save(),e.fillStyle="#fff",e.textAlign="left",e.textBaseline="top",e.font="20px monospace",e.shadowColor="#000",e.shadowBlur=9;let r=9,a=0,c=24;if(Re){e.fillText(`${Js} v${Us}`,r,a+=c/2),e.fillText("Time: "+sr(Ht),r,a+=c),e.fillText("FPS: "+Vs.toFixed(1)+(G?" WebGL":" Canvas2D"),r,a+=c),e.fillText("Objects: "+mt.length,r,a+=c),e.fillText("Draw Calls: "+we,r,a+=c),e.fillText("Primitives: "+Te,r,a+=c),e.fillText("---------",r,a+=c),e.fillStyle="#f00",e.fillText("ESC: Debug Overlay",r,a+=c),e.fillStyle=re?"#f00":"#fff",e.fillText("1: Debug Physics",r,a+=c),e.fillStyle=fn?"#f00":"#fff",e.fillText("2: Debug Particles",r,a+=c),e.fillStyle=pn?"#f00":"#fff",e.fillText("3: Debug Gamepads",r,a+=c),e.fillStyle=ae?"#f00":"#fff",e.fillText("4: Debug Raycasts",r,a+=c),e.fillStyle="#fff",e.fillText("5: Save Screenshot",r,a+=c),e.fillText("6: Toggle Video Capture",r,a+=c),e.fillStyle=kn?"#f00":"#fff",e.fillText("7: Debug Sound",r,a+=c);let l="",u="";for(let h in H[0])Ct(h,0)&&(parseInt(h)<3?u+=h+" ":l+=h+" ");u&&e.fillText("Mouse: "+u,r,a+=c),l&&e.fillText("Keys: "+l,r,a+=c);for(let h=1;hs.push(a.data),i.onstop=()=>{let a=new Blob(s,{type:"video/webm"}),c=URL.createObjectURL(a);rs(c,"capture.webm",1e3)};let o,r;if(Jt){r=new ConstantSourceNode(ht,{offset:0}),r.connect(Ge),r.start(),o=ht.createMediaStreamDestination(),Ge.connect(o);for(let a of o.stream.getAudioTracks())n.addTrack(a)}try{i.start()}catch{yt("Video capture not supported in this browser!"),r==null||r.stop();return}yt("Video capture started."),Pe={mediaRecorder:i,captureTimer:e,videoTrack:t,silentAudioSource:r,audioStreamDestination:o}}function Ga(){var n,t,e;f(xe(),"Not capturing video!"),yt(`Video capture ended. ${Pe.captureTimer.get().toFixed(2)} seconds recorded.`),oe.style.display="none",(n=Pe.silentAudioSource)==null||n.stop(),(t=Pe.mediaRecorder)==null||t.stop(),(e=Pe.videoTrack)==null||e.stop(),Pe=void 0}function Bl(){f(xe(),"Not capturing video!"),br(),Pe.videoTrack.requestFrame(),oe.textContent="\u25CF REC "+sr(Pe.captureTimer)}function Yt(n){if(It){let t=Object.keys(n),e={};t.forEach(s=>e[s]=n[s]),t.forEach(s=>{Object.defineProperty(n,s,{get:()=>e[s],set:i=>{f(!1,`Cannot modify engine constant. Attempted to set constant (${n}) property '${s}' to '${i}'.`)},enumerable:!0})})}return Object.freeze(n)}function Qt(n,t=1){return(n%t+t)%t}function j(n,t=0,e=1){return ne?e:n}function Mt(n,t,e){return(e-=t)?j((n-t)/e):0}function Nt(n,t,e){return n+j(e)*(t-n)}function Nl(n,t,e,s,i){return Nt(s,i,Mt(n,t,e))}function tr(n,t,e=1){f(e>0,"distanceWrap wrapSize must be > 0");let s=(n-t)%e;return s*2%e-s}function Na(n,t,e,s=1){return n+j(e)*tr(t,n,s)}function zl(n,t){return tr(n,t,2*q)}function Jl(n,t,e){return Na(n,t,e,2*q)}function qs(n){return n*n*(3-2*n)}function os(n){return!(n&n-1)}function Ul(n){return 2**is(ja(n))}function Hs(n,t,e,s=b()){let i=(n.x-e.x)*2,o=(n.y-e.y)*2,r=t.x+s.x,a=t.y+s.y;return Z(i)p)return!1;h=X(y,h)}else{if(y0?a.x+1:a.x,x=h>0?a.y+1:a.y,v=c?(y-n.x)/c:1/0,T=l?(x-n.y)/l:1/0,C=0,w=v,_=T,A=pa.x&&(S.x=a.x+1-R),M.ya.y&&(S.y=a.y+1-R),s&&(A?s.set(-u,0):s.set(0,-h)),S}(A=w<_)?(a.x+=u,C=w,w+=p):(a.y+=h,C=_,_+=d)}}function ut(n=1,t=0){return t+Math.random()*(n-t)}function er(n,t=0){return bt(ut(n,t))}function Va(n=.5){return ut()URL.revokeObjectURL(n),e)}function $l(n,t,e){var s;f(J(n),"shareURL requires title string"),f(J(t),"shareURL requires url string"),(s=navigator.share)==null||s.call(navigator,{title:n,url:t}).then(()=>e==null?void 0:e())}function Kl(n,t){f(J(n),"loadData requires saveName string");let e={};try{let s=localStorage[n];if(s)try{e=JSON.parse(s)}catch{yt("readSaveData: corrupt JSON for",n,"\u2014 using defaults")}}catch{yt("readSaveData: localStorage unavailable \u2014 using defaults")}return{...t,...e}}function Ql(n,t){f(J(n),"saveData requires saveName string");try{localStorage[n]=JSON.stringify(t)}catch{yt("writeSaveData: failed to write",n)}}function ho(n){let t=(n|0)^2654435769;return t=Math.imul(t^t>>>16,2246822507),t=Math.imul(t^t>>>13,3266489909),t^=t>>>16,(t>>>0)/2**32}function Zl(n){let t=bt(n);return Nt(ho(t),ho(t+1),qs(n-t))}function tu(n,t){let e=bt(n),s=bt(t),i=qs(n-e),o=qs(t-s),r=(a,c)=>ho(a+c*374761393);return Nt(Nt(r(e,s),r(e+1,s),i),Nt(r(e,s+1),r(e+1,s+1),i),o)}function eu(n){Tt=n.copy()}function nu(n){Y=n}function su(n){W=n}function iu(n){ir=n}function ou(n){Ai=n}function ru(n){Xe=n.copy()}function au(n){Cn=n.copy()}function cu(n){Zn=n}function lu(n){Rn=n}function uu(n){Pn=n.copy()}function Za(n){or=n,F&&(F.style.imageRendering=n?"pixelated":""),Q&&(Q.style.imageRendering=n?"pixelated":"")}function hu(n){mn=n}function du(n){Ye=n}function fu(n){ws=n}function pu(n){rr=n}function gu(n){B=n}function yu(n){if(n&&!vo){console.warn("Can not enable WebGL if it was disabled on start.");return}G=n,Q&&(Q.style.display=n?"":"none")}function mu(n){Ts=n}function bu(n){Ei=n.copy()}function xu(n){_i=n}function vu(n){Ci=n}function Su(n){Ri=n}function wu(n){ar=n}function Tu(n){cr=n}function Au(n){lr=n}function Eu(n){ur=n}function _u(n){hr=n}function Cu(n){Oe=n}function Ru(n){Bt=n.copy()}function Pu(n){Xs=n}function Lu(n){Pi=n}function Ou(n){dr=n}function Du(n){ts=n}function Iu(n){un=n}function Mu(n){tn=n}function ku(n){fr=n}function Gu(n){le=n}function Fu(n){Jn=n,n>0&&(Vn=!1)}function ju(n){Sn=n,n&&(Un=0)}function Bu(n){Un=n,n>0&&(Sn=!1)}function Nu(n){Vn=n,n&&(Jn=0)}function zu(n){As=n}function Ju(n){nn=n}function Uu(n){zt=n}function Vu(n){pr=n}function Wu(n){es=n}function qu(n){Ys=n}function Hu(n){Es=n}function Xu(n){Jt=n}function Yu(n){gn=n,Jt&&!B&&Ge&&(Ge.gain.value=n)}function $u(n){gr=n}function Ku(n){yr=n}function Qu(n){Ti=n}function Zu(n){Ia=n}function $s(n){return n.r>=1&&n.g>=1&&n.b>=1}function mr(n){return n.r<=0&&n.g<=0&&n.b<=0&&n.a<=0}function _s(n=0,t=Ei,e=0,s=_i,i=Ci){if(f(L(n)||typeof n=="number","index must be a vec2 or number"),f(L(t)||typeof t=="number","size must be a vec2 or number"),f(P(e)||e instanceof je,"texture must be a number or TextureInfo"),f(P(s),"padding must be a number"),B)return new Ae;typeof t=="number"&&(f(t>0),t=new it(t,t));let o=typeof e=="number"?en[e]:e;f(o instanceof je,"tile texture is not loaded"),f(o.size.x>0,"tile texture is not loaded");let r=t.x+s*2,a=t.y+s*2,c,l;if(typeof n=="number"){let h=o.size.x/r|0;c=n%h,l=n/h|0}else c=n.x,l=n.y;let u=new it(c*r+s,l*a+s);return new Ae(u,t,o,s,i)}function Rt(n,t=b(1),e,s=U,i=0,o,r,a=G,c=!1,l){var p;f(L(n),"pos must be a vec2"),f(L(t),"size must be a vec2"),f(z(s),"color is invalid"),f(P(i),"angle must be a number"),f(!r||z(r),"additiveColor must be a color"),f(!l||!a,"context only supported in canvas 2D mode");let u=e==null?void 0:e.textureInfo,h=(p=e==null?void 0:e.bleed)!=null?p:0;if(a&&G)if(f(!!g,"WebGL is not enabled!"),c&&([n,t,i]=Rs(n,t,i)),u){let d=u.sizeInverse,y=e.pos.x*d.x,x=e.pos.y*d.y,v=e.size.x*d.x,T=e.size.y*d.y;if(Ir(u.glTexture),h){let C=d.x*h,w=d.y*h;ms(n.x,n.y,o?-t.x:t.x,t.y,i,y+C,x+w,y-C+v,x-w+T,s.rgbaInt(),r&&r.rgbaInt())}else ms(n.x,n.y,o?-t.x:t.x,t.y,i,y,x,y+v,x+T,s.rgbaInt(),r&&r.rgbaInt())}else{let d=r?s.add(r):s;vc(n.x,n.y,t.x,t.y,i,d.rgbaInt())}else++we,++Te,wn(n,t,i,o,d=>{if(u){d.scale(1,-1);let y=e.pos.x,x=e.pos.y,v=e.size.x,T=e.size.y;lh(d,u.image,y,x,v,T,-.5,-.5,1,1,s,r,h)}else{let y=r?s.add(r):s;d.fillStyle=y.toString(),d.fillRect(-.5,-.5,1,1)}},c,l)}function Ks(n,t,e,s,i,o,r){Rt(n,t,void 0,e,s,!1,void 0,i,o,r)}function th(n,t,e=U,s=Ze,i=0,o=G,r=!1,a){if(f(L(n),"pos must be a vec2"),f(L(t),"size must be a vec2"),f(z(e)&&z(s),"color is invalid"),f(P(i),"angle must be a number"),f(!a||!o,"context only supported in canvas 2D mode"),o&&G){f(!!g,"WebGL is not enabled!"),r&&(n=Cs(n),t=t.scale(1/W),i+=Y);let c=[],l=[],u=t.x/2,h=t.y/2,p=e.rgbaInt(),d=s.rgbaInt(),y=at(-i),x=tt(-i);for(let v=4;v--;){let T=v&1?u:-u,C=v&2?h:-h,w=T*y-C*x,_=T*x+C*y,A=v&2?p:d;c.push(b(n.x+w,n.y+_)),l.push(A)}jr(c,l)}else++we,++Te,wn(n,t,i,!1,c=>{let l=c.createLinearGradient(0,.5,0,-.5);l.addColorStop(0,e.toString()),l.addColorStop(1,s.toString()),c.fillStyle=l,c.fillRect(-.5,-.5,1,1)},r,a)}function eh(n,t,e,s=0,i=U,o=0,r,a=G,c=!1,l){if(f(L(n),"pos must be a vec2"),f(L(t),"size must be a vec2"),f(L(e),"wrapCount must be a vec2"),f(z(i),"color is invalid"),f(P(o),"angle must be a number"),f(!r||z(r),"additiveColor must be a color"),f(!l||!a,"context only supported in canvas 2D mode"),f(!(s instanceof Ae),"pass a TextureInfo or texture index, not a TileInfo \u2014 use tileInfo.textureInfo"),B)return;let u=typeof s=="number"?en[s]:s;if(f(u instanceof je,"texture not loaded"),f(u.size.x>0,"texture not loaded"),f(u.wrap,"drawTextureWrapped requires a wrap-enabled texture; call textureInfo.setWrap(true) first"),a&&G){f(!!g,"WebGL is not enabled!"),c&&([n,t,o]=Rs(n,t,o)),Ir(u.glTexture),ms(n.x,n.y,t.x,t.y,o,0,0,e.x,e.y,i.rgbaInt(),r&&r.rgbaInt());return}++we,++Te,c||(n=Tn(n),t=t.scale(W),o-=Y);let h=!Ai||(r?$s(i.add(r))&&r.a<=0:$s(i)),p=!h&&r&&!mr(r),d=h?u.image:ch(u.image,i,r);l=l||St,l.save(),l.translate(n.x+.5,n.y+.5),l.rotate(o),l.globalAlpha=p?1:i.a;let y=l.createPattern(d,"repeat"),x=new DOMMatrix().translate(-t.x/2,-t.y/2).scale(t.x/(e.x*d.width),t.y/(e.y*d.height));y.setTransform(x),l.fillStyle=y,l.fillRect(-t.x/2,-t.y/2,t.x,t.y),l.globalAlpha=1,l.restore()}function fo(n,t=.1,e=U,s=!1,i=b(),o=0,r=G,a=!1,c){if(f(ce(n),"points must be an array"),f(P(t),"width must be a number"),f(z(e),"color is invalid"),f(L(i),"pos must be a vec2"),f(P(o),"angle must be a number"),f(!c||!r,"context only supported in canvas 2D mode"),r&&G){f(!!g,"WebGL is not enabled!");let l=b(1);a&&([i,l,o]=Rs(i,l,o)),Fr(n,e.rgbaInt(),t,i.x,i.y,l.x,l.y,o,s)}else++we,++Te,wn(i,b(1),o,!1,l=>{l.strokeStyle=e.toString(),l.lineWidth=t,l.beginPath();for(let u=0;u0&&Fr(n,s.rgbaInt(),e,i.x,i.y,l.x,l.y,o)}else wn(i,b(1),o,!1,l=>{l.fillStyle=t.toString(),l.beginPath();for(let u of n)l.lineTo(u.x,u.y);l.closePath(),l.fill(),e&&(l.strokeStyle=s.toString(),l.lineWidth=e,l.stroke())},a,c)}function ec(n,t=b(1),e=U,s=0,i=0,o=et,r=G,a=!1,c){f(L(n),"pos must be a vec2"),f(L(t),"size must be a vec2"),f(z(e)&&z(o),"color is invalid"),f(P(s),"angle must be a number"),f(P(i),"lineWidth must be a number"),f(i>=0,"lineWidth must be a positive value or 0"),f(!c||!r,"context only supported in canvas 2D mode"),i=j(i,0,K(t.x,t.y)),r&&G?tc(n,t,Ts,e,i,o,s,r,a,c):wn(n,b(1),s,!1,l=>{l.fillStyle=e.toString(),l.beginPath(),l.ellipse(0,0,t.x/2,t.y/2,0,0,9),l.fill(),i&&(l.strokeStyle=o.toString(),l.lineWidth=i,l.stroke())},a,c)}function Qs(n,t=1,e=U,s=0,i=et,o=G,r=!1,a){f(P(t),"size must be a number"),ec(n,b(t),e,0,s,i,o,r,a)}function nc(n,t=b(1),e=U,s=Ze,i=0,o=G,r=!1,a){if(f(L(n),"pos must be a vec2"),f(L(t),"size must be a vec2"),f(z(e)&&z(s),"color is invalid"),f(P(i),"angle must be a number"),f(!a||!o,"context only supported in canvas 2D mode"),!B)if(o&&G){f(!!g,"WebGL is not enabled!"),r&&(n=Cs(n),t=t.scale(1/W),i+=Y);let c=Ts,l=t.x/2,u=t.y/2,h=e.rgbaInt(),p=s.rgbaInt(),d=nh++,y=at(-i),x=tt(-i),v=_=>{let A=tt(_)*l,S=at(_)*u;return b(n.x+A*y-S*x,n.y+A*x+S*y)},T=d%c/c*q*2,C=[v(T)],w=[p];for(let _=c;_--;){let A=(_+d)%c/c*q*2;C.push(n),w.push(h),C.push(v(A)),w.push(p)}jr(C,w)}else++we,++Te,wn(n,t,i,!1,c=>{let l=c.createRadialGradient(0,0,0,0,0,.5);l.addColorStop(0,e.toString()),l.addColorStop(1,s.toString()),c.fillStyle=l,c.beginPath(),c.ellipse(0,0,.5,.5,0,0,9),c.fill()},r,a)}function sh(n,t=1,e=U,s=Ze,i=G,o=!1,r){f(P(t),"size must be a number"),nc(n,b(t),e,s,0,i,o,r)}function wn(n,t,e=0,s=!1,i,o=!1,r=St){f(L(n),"pos must be a vec2"),f(L(t),"size must be a vec2"),f(P(e),"angle must be a number"),f(typeof i=="function","drawFunction must be a function"),o||(n=Tn(n),t=t.scale(W),e-=Y),r.save(),r.translate(n.x+.5,n.y+.5),r.rotate(e),r.scale(s?-t.x:t.x,-t.y),i(r),r.restore()}function ih(n,t,e=1,s=U,i=0,o=et,r="center",a=ws,c="",l,u=0,h=St){t=Tn(t),e*=W,i*=W,u-=Y,u*=-1,$e(n,t,e,s,i,o,r,a,c,l,u,h)}function $e(n,t,e,s=U,i=0,o=et,r="center",a=ws,c="",l,u=0,h=St){f(J(n),"text must be a string"),f(L(t),"pos must be a vec2"),f(P(e),"size must be a number"),f(z(s),"color must be a color"),f(P(i),"lineWidth must be a number"),f(z(o),"lineColor must be a color"),f(["left","center","right"].includes(r),"align must be left, center, or right"),f(J(a),"font must be a string"),f(J(c),"fontStyle must be a string"),f(P(u),"angle must be a number");let p=(n+"").split(`
+`),d=t.y-(p.length-1)*e/2;h.save(),h.fillStyle=s.toString(),h.strokeStyle=o.toString(),h.lineWidth=i,h.textAlign=r,h.font=c+" "+e+"px "+a,h.textBaseline="middle",h.translate(t.x,d),h.rotate(-u);let y=0;p.forEach(x=>{i&&h.strokeText(x,0,y,l),h.fillText(x,0,y,l),y+=e}),h.restore()}async function va(n,t){f(P(n),"textureIndex must be a number"),f(!en[n],"textureIndex is already loaded!"),f(!t||J(t),"image src must be a string");let e=new Image;t&&await new Promise(s=>{e.onerror=e.onload=s,e.crossOrigin="anonymous",e.src=t}),en[n]=new je(e)}function Cs(n){f(L(n),"screenPos must be a vec2");let t=(n.x-I.x/2+.5)/W,e=(n.y-I.y/2+.5)/-W;if(Y){let s=at(-Y),i=tt(-Y),o=t*s-e*i,r=t*i+e*s;t=o,e=r}return new it(t+Tt.x,e+Tt.y)}function Tn(n){f(L(n),"worldPos must be a vec2");let t=n.x-Tt.x,e=n.y-Tt.y;if(Y){let s=at(Y),i=tt(Y),o=t*s-e*i,r=t*i+e*s;t=o,e=r}return new it(t*W+I.x/2-.5,e*-W+I.y/2-.5)}function sc(n){f(L(n),"screenDelta must be a vec2");let t=n.x/W,e=n.y/-W;if(Y){let s=at(-Y),i=tt(-Y),o=t*s-e*i,r=t*i+e*s;t=o,e=r}return new it(t,e)}function oh(n){f(L(n),"worldDelta must be a vec2");let t=n.x,e=n.y;if(Y){let s=at(Y),i=tt(Y),o=t*s-e*i,r=t*i+e*s;t=o,e=r}return new it(t*W,e*-W)}function Rs(n,t,e=0){return f(L(n),"screenPos must be a vec2"),f(L(t),"screenSize must be a vec2"),f(P(e),"screenAngle must be a number"),[Cs(n),t.scale(1/W),e+Y]}function ic(){return I.scale(1/W)}function rh(n,t,e,s){f(L(n),"center must be a vec2"),f(L(t),"size must be a vec2");let i=p(e),o=p(s),r=t.x+i.left+i.right,a=t.y+i.top+i.bottom,c=I.x-o.left-o.right,l=I.y-o.top-o.bottom;if(!(r>0&&a>0&&c>0&&l>0))return W;W=K(c/r,l/a);let u=b(i.right-i.left,i.top-i.bottom).scale(.5),h=b(o.right-o.left,o.top-o.bottom).scale(.5/W);return Tt=n.add(u).add(h),W;function p(d){return(d===void 0||P(d))&&(d=b(d)),L(d)?{top:d.y,right:d.x,bottom:d.y,left:d.x}:{top:d.top||0,right:d.right||0,bottom:d.bottom||0,left:d.left||0}}}function ah(n,t=0){if(f(L(n),"pos must be a vec2"),f(L(t)||P(t),"size must be a vec2 or number"),!W)return!1;let e=n.x-Tt.x,s=n.y-Tt.y;if(Y){let r=at(Y),a=tt(Y),c=e*r-s*a,l=e*a+s*r;e=c,s=l}e*=W*2,s*=-W*2,t instanceof it&&(t=t.length()),t*=W;let i=I.x,o=I.y;return e+t>-i&&e-t-o&&s-t{n.onerror=n.onload=a,n.crossOrigin="anonymous",n.src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUAAAAAeAQMAAABnrVXaAAAABlBMVEUAAAD///+l2Z/dAAAAAXRSTlMAQObYZgAAAjpJREFUOMu9kzFu2zAUhn+CAROgqrk+B2l0BWYxMjlXeYaAtFtbdA1sGgHqRQfI0CNkSG5AwYB0BQ8d5Bsomwah6CPVeGg6tEPzAxLwyI+P78cP4u9lNO9OoMKnLMOobG5020/yaj/MrRcCGh1gBbyiLTPJEYaIiom5KM9Jq7KgynMGtb6L4GL4MF2H4LQKCXTvDVw2I4MsgZT7QLExdiutH+D08VOP3INXRrWX1/mmpbkNgAPYRVANb4xpcegYvhiNbIXauQICEjBuYLfMakaakWQeXxiZ0VDtuJCKs3ztMV59QtsHJNcRxDzfdL21ty3PrfIcXTN+E+GFAv6T5nbT9jd50/WFxb5ksdAv49qS6ouymG66ji08UMT6moykYLAo+V0j23GN4m829ZySAD5K7QsBfQTvOG8eE+gTeGYRAmnNAubN3hf5Zv9tJWDHp/VTuaSm7SN4fyINQqaNO3RMVxvpSPXnOChnRNvFcGY0gnwiPswYwTKVPE0zVtX3mTEIOoFzaqLrGuJaV+Uqumb71fVk/VoOH3cdLNQP/FHi8hV0CQNoqBZsUPlLPMsdCJro9QAaQQ0woDy9BJm0eTxCFnO9srcYlhNVlfR2EyTrph1uUtbUtAJifwRgrKuYdXVHeb0YI3QpawohQHkloI3J5FuVwI5ORxC9k2Tuz9Ir1IjgeIPGMHYkAZe2RuYkmWFmt3gGbTPOmBUWVTmRmHtGrfpzG/yuQNOKa6gBB/WA9khitPgl6/GP+gl2Af6tCbvaygAAAABJRU5ErkJggg=="});let t=b(),e=b(8),s=1,i=0,o=new je(n),r=new Ae(t,e,o,s,i);rc=new Zs(r)}function fh(n=!0){Ln=n}function ph(n){Sr=n}function gh(){return qe==="mouse"}function yh(){return qe==="keyboard"}function mh(){return qe==="gamepad"}function wr(n,t=0,e=!0,s=!0,i=!0){H[t]&&(H[t][n]&=~((e?1:0)|(s?2:0)|(i?4:0)))}function Ps(){H.length=0,H[0]=[],te.length=0,bn.length=0,Ls.length=0,ye.length=0,cn.length=0}function Ct(n,t=0){var e;return f(J(n),"key must be a number or string"),f(t>0||typeof n!="number"||n<3,"use code string for keyboard"),!!(((e=H[t])==null?void 0:e[n])&1)}function Ot(n,t=0){var e;return f(J(n),"key must be a number or string"),f(t>0||typeof n!="number"||n<3,"use code string for keyboard"),!!(((e=H[t])==null?void 0:e[n])&2)}function Tr(n,t=0){var e;return f(J(n),"key must be a number or string"),f(t>0||typeof n!="number"||n<3,"use code string for keyboard"),!!(((e=H[t])==null?void 0:e[n])&4)}function bh(n="ArrowUp",t="ArrowDown",e="ArrowLeft",s="ArrowRight"){f(J(n),"up key must be a string"),f(J(t),"down key must be a string"),f(J(e),"left key must be a string"),f(J(s),"right key must be a string");let i=o=>Ct(o)?1:0;return b(i(s)-i(e),i(n)-i(t))}function ns(n){return f(P(n),"mouse button must be a number"),Ct(n)}function cs(n){return f(P(n),"mouse button must be a number"),Ot(n)}function xh(n){return f(P(n),"mouse button must be a number"),Tr(n)}function Ce(n,t=ft){return f(P(n),"button must be a number"),f(P(t),"gamepad must be a number"),Ct(n,t+1)}function Ar(n,t=ft){return f(P(n),"button must be a number"),f(P(t),"gamepad must be a number"),Ot(n,t+1)}function vh(n,t=ft){return f(P(n),"button must be a number"),f(P(t),"gamepad must be a number"),Tr(n,t+1)}function ls(n,t=ft){var e,s;return f(P(n),"stick must be a number"),f(P(t),"gamepad must be a number"),(s=(e=ye[t])==null?void 0:e[n])!=null?s:b()}function po(n=ft){var t;return f(P(n),"gamepad must be a number"),(t=cn[n])!=null?t:b()}function go(n=ft){return f(P(n),"gamepad must be a number"),!!H[n+1]}function ac(n=ft){var t,e;return f(P(n),"gamepad must be a number"),(e=(t=ye[n])==null?void 0:t.length)!=null?e:0}function Sh(n=ft,t=200,e=1,s=1,i=0){var r,a,c;if(f(P(n),"gamepad must be a number"),!Es||B)return;let o=(r=navigator==null?void 0:navigator.getGamepads)==null?void 0:r.call(navigator)[n];(c=(a=o==null?void 0:o.vibrationActuator)==null?void 0:a.playEffect)==null||c.call(a,"dual-rumble",{duration:t,strongMagnitude:e,weakMagnitude:s,startDelay:i})}function wh(n=ft){var e,s,i;if(f(P(n),"gamepad must be a number"),!Es||B)return;let t=(e=navigator==null?void 0:navigator.getGamepads)==null?void 0:e.call(navigator)[n];(i=(s=t==null?void 0:t.vibrationActuator)==null?void 0:s.reset)==null||i.call(s)}function Er(n=100){var t;f(P(n)||ce(n),"pattern must be a number or array"),Es&&!B&&((t=navigator==null?void 0:navigator.vibrate)==null||t.call(navigator,n))}function Th(){Er(0)}function Ah(){var n;!Zt&&((n=F.requestPointerLock)==null||n.call(F))}function Eh(){var n;(n=document.exitPointerLock)==null||n.call(document)}function cc(){return document.pointerLockElement===F}function _h(){if(B)return;document.addEventListener("keydown",n),document.addEventListener("keyup",t),document.addEventListener("mousedown",s),document.addEventListener("mouseup",i),document.addEventListener("mousemove",o),document.addEventListener("mouseleave",r),document.addEventListener("wheel",a,{passive:!1}),document.addEventListener("contextmenu",c),document.addEventListener("blur",l),Zt&&un&&u();function n(p){if(p.repeat||(H[0][p.code]=3,ts&&(H[0][e(p.code)]=3)),!Ln||!p.cancelable||!document.hasFocus()||p.ctrlKey||p.metaKey||p.altKey||x(p.target)||x(document.activeElement))return;let d=typeof p.key=="string"&&p.key.length===1;(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight","Space","Tab","Backspace"].includes(p.code)||d)&&p.preventDefault();function x(v){let T=v==null?void 0:v.tagName;return(v==null?void 0:v.isContentEditable)||["INPUT","TEXTAREA","SELECT"].includes(T)}}function t(p){H[0][p.code]=H[0][p.code]&2|4,ts&&(H[0][e(p.code)]=4)}function e(p){return ts?p==="KeyW"?"ArrowUp":p==="KeyS"?"ArrowDown":p==="KeyA"?"ArrowLeft":p==="KeyD"?"ArrowRight":p:p}function s(p){if(Zt&&un)return;Jt&&!B&&ht&&!hs()&&ht.resume(),H[0][p.button]=3;let d=Ft;Ft=h(b(p.x,p.y)),ge=ge.add(Ft.subtract(d)),Ln&&p.cancelable&&document.hasFocus()&&p.preventDefault()}function i(p){Zt&&un||(H[0][p.button]=H[0][p.button]&2|4)}function o(p){ti=!0;let d=Ft;Ft=h(b(p.x,p.y));let y=cc()?b(p.movementX,p.movementY):Ft.subtract(d);ge=ge.add(y)}function r(){ti=!1}function a(p){p.ctrlKey||(vr+=Kt(p.deltaY)),Ln&&p.cancelable&&document.hasFocus()&&p.preventDefault()}function c(p){p.preventDefault()}function l(){Ps(),Ie.clear(),te.length=0,bn.length=0,Ls.length=0}function u(){document.addEventListener("touchstart",y=>d(y),{passive:!1}),document.addEventListener("touchmove",y=>d(y),{passive:!1}),document.addEventListener("touchend",y=>d(y),{passive:!1});let p;function d(y){if(un){if(Jt&&!B&&ht&&!hs()&&ht.resume(),!tn||fr){let x=w=>us.includes(w.target)||w.target===ln,v=[];for(let w of y.touches)x(w)||v.push(w);let T=v.length,C=0;if(T){let w=b(v[0].clientX,v[0].clientY),_=Ft;Ft=h(w),p?ge=ge.add(Ft.subtract(_)):H[0][C]=3}else p&&(H[0][C]=H[0][C]&2|4);p=T}return Ln&&y.cancelable&&document.hasFocus()&&y.preventDefault(),!0}}}function h(p){let d=F.getBoundingClientRect(),y=Mt(p.x,d.left,d.right),x=Mt(p.y,d.top,d.bottom);return b(y*F.width,x*F.height)}}function wa(){if(B)return;!(un&&Zt)&&!document.hasFocus()&&Ps(),_e=Cs(Ft),xr=sc(ge),Rh(),t(),n();function n(){let e=ns(0)||ns(1)||ns(2)||ge.length()>Sr,s=!1;for(let o=ac();o--&&!s;)s=ls(o).lengthSquared()>.04;for(let o=17;o--&&!s;)s=Ce(o);let i=!1;for(let o in H[0])if(isNaN(+o)&&H[0][o]&1){i=!0;break}s?qe="gamepad":e?qe="mouse":i&&(qe="keyboard"),Dn=qe==="gamepad"}function t(){var r,a,c,l,u,h,p;let e=d=>{let v=T=>T>.3?Mt(T,.3,.8):T<-.3?-Mt(-T,.3,.8):0;return b(v(d.x),v(-d.y)).clampLength()};if(tn&&Zt){if(f(!Sn||!Un,"set touchGamepadLeftStick or touchGamepadLeftButtonCount, not both"),f(!Vn||!Jn,"set touchGamepadRightStick or touchGamepadButtonCount, not both"),!Fn.isSet())return;ft=0;let d=(r=ye[0])!=null?r:ye[0]=[],y=(a=cn[0])!=null?a:cn[0]=b();d.length=0,y.set();for(let v=0;v<2;v++){if(!Be(v))continue;let T=Rr(v);d[T]=b();let C=(c=bn[v])!=null?c:b();if(As)d[T]=e(C);else if(C.lengthSquared()>.3){let w=j(Ws(C.x),-1,1),_=j(Ws(C.y),-1,1);d[T]=b(w,-_).clampLength(),T||y.set(w,-_)}}let x=(l=H[1])!=null?l:H[1]=[];for(let v=12;v--;){let T=Ce(v,0);x[v]=te[v]?T?1:3:T?4:0,Ys&&x[v]===3&&(v===9||Ph(v))&&Er(Ys)}return}try{if(!Pi||!(navigator!=null&&navigator.getGamepads))return}catch{return}if(!It&&!document.hasFocus())return;let s=8,i=navigator.getGamepads(),o=K(s,i.length);for(let d=0;d>1]=e(b(y.axes[w],y.axes[w+1]));let C=!1;for(let w=y.buttons.length;w--;){let _=y.buttons[w],A=Ce(w,d);x[w]=_.pressed?A?1:3:A?4:0,_.pressed&&(!_.value||_.value>.9)&&(C=!0)}C&&(io[d]=!0,io[ft]||(ft=d)),y.mapping==="standard"&&T.set((Ce(15,d)&&1)-(Ce(14,d)&&1),(Ce(12,d)&&1)-(Ce(13,d)&&1)),dr&&(T.x||T.y)&&(v[0]=T.clampLength())}tn&&Dn&&Fn.unset()}}function Ta(){if(!B){for(let n of H)for(let t in n)n[t]&=1;vr=0,xr=b(),ge=b()}}function Ch(){Ih()}function Rh(){if(Ue||!tn||!Zt||B||!document.body)return;let n=Ue=document.createElement("div");n.style.cssText="position:fixed;inset:0;z-index:50;pointer-events:none;opacity:0;touch-action:none;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;transition:opacity .2s;box-sizing:border-box;padding:env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left)";let t=lc=document.createElement("div");t.style.cssText="position:relative;width:100%;height:100%;pointer-events:none",n.appendChild(t);let e=_r=document.createElementNS(ni,"svg");e.style.cssText="position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible;fill:none;stroke:#fff;stroke-width:3",t.appendChild(e);let s=()=>{let i=document.createElement("div");return i.style.cssText="position:absolute;pointer-events:auto;touch-action:none",i.addEventListener("pointerdown",o=>Fh(o,i)),i.addEventListener("pointermove",o=>jh(o)),i.addEventListener("pointerup",o=>Aa(o)),i.addEventListener("pointercancel",o=>Aa(o)),t.appendChild(i),i};us[0]=s(),us[1]=s(),ln=s(),addEventListener("resize",()=>jn=!0),document.body.appendChild(n),jn=!0}function Li(){return lc.getBoundingClientRect()}function Be(n){return n?Vn:Sn}function An(n){return n?Jn:Un}function Cr(n){return n?0:4}function Rr(n){return n&&Sn?1:0}function Bn(n){return Be(n)||An(n)>0}function Ph(n){for(let t=0;t<2;t++){let e=Cr(t);if(!Be(t)&&n>=e&&no.style.cssText="position:absolute;pointer-events:auto;touch-action:none;"+r;if(ve){for(let o of us)o.style.display="none";le?(i(ln,"inset:0"),ln.style.display=""):ln.style.display="none"}else{for(let r=0;r<2;r++){let a=us[r],c=r?"right":"left";if(a.style.display=Bn(r)?"":"none",nn){let l=Bn(r?0:1)?"50%":"100%";i(a,`${c}:0;bottom:0;width:${l};height:60%`)}else i(a,`${c}:0;bottom:0;width:${3*s}px;height:${3*s}px`)}ln.style.display=le?"":"none";let o=le;i(ln,`left:50%;top:50%;width:${2*o}px;height:${2*o}px;transform:translate(-50%,-50%)`)}Oh(t,e),jn=!1}function Oh(n,t){let e=_r;for(;e.firstChild;)e.removeChild(e.firstChild);let s=uc={face:[],thumb:[]},i=zt,o=(a,c,l,u)=>{let h=document.createElementNS(ni,"circle");return h.setAttribute("cx",a),h.setAttribute("cy",c),h.setAttribute("r",l),u&&h.setAttribute("fill",u),e.appendChild(h),h},r=a=>{let c=i*.18,l=i*.5,u=a.x,h=a.y,p=document.createElementNS(ni,"path");p.setAttribute("d",`M ${u-c} ${h-l} H ${u+c} V ${h-c} H ${u+l} V ${h+c} H ${u+c} V ${h+l} H ${u-c} V ${h+c} H ${u-l} V ${h-c} H ${u-c} Z`),e.appendChild(p)};for(let a=0;a<2;a++){let c=An(a),l=Cr(a),u=ke(a,n,t);if(Be(a))As?o(u.x,u.y,i/2):r(u),s.thumb[a]=o(u.x,u.y,i/4,"#fff");else if(c===1)s.face[l]=o(u.x,u.y,i/2,"#000");else for(let h=0;h2?p:K(p,c-1);d=d===3?2:d===2?3:d;let y=b().setDirection(p,i/2);c===2&&(y.x*=-1),a||(y.x*=-1);let x=u.add(y);s.face[l+d]=o(x.x,x.y,i/4,"#000")}}It&&pn&&Dh(n,t)}function Dh(n,t){let e=zt,s=_r,i=(r,a,c)=>{let l=document.createElementNS(ni,r);for(let u in a)l.setAttribute(u,a[u]);l.setAttribute("stroke",c),l.setAttribute("stroke-width",2),l.setAttribute("fill","none"),s.appendChild(l)},o=(r,a,c)=>i("circle",{cx:r.x,cy:r.y,r:a},c);i("line",{x1:n/2,y1:0,x2:n/2,y2:t},"#0f0");for(let r=0;r<2;r++)if(Be(r))if(nn){let a=t*.4,c=!Bn(r?0:1),l=c?0:r?n/2:0;i("rect",{x:l,y:a,width:c?n:n/2,height:t-a},"#0ff")}else o(ke(r,n,t),2*e,"#0ff");else An(r)>=1&&o(ke(r,n,t),e,"#0ff");if(le){o(b(n/2,t/2),le,"#ff0");for(let r=0;r<2;r++)Bn(r)&&o(ke(r,n,t),2*e,"#f0f")}}function Ih(){var l;if(!Ue||B)return;if(!tn||!Zt){Ue.style.display!=="none"&&(Ue.style.display="none",Ie.clear(),te.length=0,bn.length=0,Ls.length=0);return}Ue.style.display="";let n=It&&pn,t=[Jn,Un,Sn,Vn,As,zt,nn,le,ve,n].join();t!==Sa&&(Sa=t,jn=!0),jn&&Lh();let e=es?Mt(Fn.get(),es+1,es):1,s=n||Fn.isSet()&&e>0&&!ve;if(Ue.style.opacity=s?n?1:e*pr:0,!s)return;let i=Li(),o=i.width,r=i.height,a=zt,c=uc;if(c){for(let u=0;u<2;u++)if(Be(u)&&c.thumb[u]){let p=ke(u,o,r).add(((l=bn[u])!=null?l:b()).scale(a/2));c.thumb[u].setAttribute("cx",p.x),c.thumb[u].setAttribute("cy",p.y)}for(let u=0;u=zt)return-1;if(i===1)return o;let a=r.subtract(t);n||(a.x*=-1);let c=i===2?a.xo:a&&ke(r,t,e).distance(n)<2*s)return{role:"stick",side:r}}else if(An(r)>=1){let c=kh(r,n,t,e);if(c>=0)return{role:"face",btn:c}}}if(le){for(let r=0;r<2;r++)if(Bn(r)&&ke(r,t,e).distance(n)<2*s)return;if(b(t/2,e/2).distance(n)h.getChannelData(v).set(x)),p.buffer=h,p.playbackRate.value=e,p.loop=i,r=r||ht.createGain(),r.gain.value=t,r.connect(Ge);let d=new StereoPannerNode(ht,{pan:j(s,-1,1)});p.connect(d).connect(r),p.addEventListener("ended",()=>{r.disconnect(),d.disconnect(),c&&c(p)});let y=a*e;return p.start(0,y),It&&kn&&yt("sound","vol",t.toFixed(2),"rate",e.toFixed(2),"pan",s.toFixed(2),i?"loop":""),p}function Jh(...n){return Pr([Oi(...n)])}function Oi(n=1,t=.05,e=220,s=0,i=0,o=.1,r=0,a=1,c=0,l=0,u=0,h=0,p=0,d=0,y=0,x=0,v=0,T=1,C=0,w=0,_=0){let A=Wn,S=q*2,R=c*=500*S/A/A,M=e*=(1+ut(t,-t))*S/A,ot=0,$=0,nt=0,rt=1,Et,ne=[],kt=0,lt=0,Pt=0,he,sn=2,on=S*Z(_)*2/A,se=at(on),Ee=tt(on)/2/sn,D=1+Ee,k=-2*se/D,gt=(1-Ee)/D,vt=(1+Kt(_)*se)/2/D,Vt=-(Kt(_)+se)/D,rn=vt,qn=0,Hn=0,Os=0,Ds=0;for(s=s*A||9,C*=A,i*=A,o*=A,v*=A,l*=500*S/A**3,y*=S/A,u*=S/A,h*=A,p=p*A|0,Et=s+C+i+o+v|0;lt1?r>2?r>3?r>4?kt/S%14?Pt:Kt(Pt)*Z(Pt)**a)*(ltlt?0:(lth&&(e+=u,M+=u,rt=0),p&&!(++$%p)&&(e=M,c=R,rt||(rt=1));return ne}function ii(n,t=!0){for(let e of Ke)if((!t||e.isSolid)&&n.arrayCheck(e.size)){let s=e.getCollisionData(n);if(s)return s}return 0}function Ve(n,t=b(),e,s=!0){for(let i of Ke)if((!s||i.isSolid)&&i.collisionTest(n,t,e))return i}function fc(n,t,e,s,i=!0){let o,r,a,c=s&&b();for(let l of Ke)if(!i||l.isSolid){let u=l.collisionRaycast(n,t,e,c);if(u){let h=n.distanceSquared(u);(o===void 0||h{G=!1,Q.style.display="none",e.preventDefault(),yt("WebGL context lost! Switching to Canvas2d rendering.");for(let s of ss)s.glTexture=void 0;Xt=void 0,wt=0,xn=!1,dn.forEach(s=>{var i;return(i=s.glContextLost)==null?void 0:i.call(s)})}),Q.addEventListener("webglcontextrestored",()=>{G=!0,Q.style.display="",yt("WebGL context restored, reinitializing..."),t();for(let e of ss)e.glTexture=Ii(e.image,e.wrap);dn.forEach(e=>{var s;return(s=e.glContextRestored)==null?void 0:s.call(e)})});function t(){ai=zn(`#version 300 es
 precision highp float;uniform mat4 m;in vec2 g;in vec4 p,u,c,a;in float r;out vec2 v;out vec4 d,e;void main(){vec2 s=(g-.5)*p.zw;gl_Position=m*vec4(p.xy+s*cos(r)-vec2(-s.y,s)*sin(r),1,1);v=mix(u.xw,u.zy,g);d=c;e=a;}`,`#version 300 es
-precision highp float;uniform sampler2D s;in vec2 v;in vec4 d,e;out vec4 c;void main(){c=texture(s,v)*d+e;}`),ci=Jn(`#version 300 es
+precision highp float;uniform sampler2D s;in vec2 v;in vec4 d,e;out vec4 c;void main(){c=texture(s,v)*d+e;}`),ci=zn(`#version 300 es
 precision highp float;uniform mat4 m;in vec2 p;in vec4 c;out vec4 d;void main(){gl_Position=m*vec4(p,1,1);d=c;}`,`#version 300 es
-precision highp float;in vec4 d;out vec4 c;void main(){c=d;}`);let e=new ArrayBuffer(ui);Dt=new Float32Array(e),gs=new Uint32Array(e),mo=g.createBuffer(),Mn=g.createBuffer(),Or=g.createFramebuffer(),Tt=0;let s=new Float32Array([0,0,1,0,0,1,1,1]);g.bindBuffer(g.ARRAY_BUFFER,Mn),g.bufferData(g.ARRAY_BUFFER,s,g.STATIC_DRAW);let i,o,r,a=(c,l,u,h,p=0)=>{let d=g.getAttribLocation(o,c),y=u===1,b=u&&r;g.enableVertexAttribArray(d),g.vertexAttribPointer(d,h,l,y,b,i),g.vertexAttribDivisor(d,p),i+=h*u};bo=g.createVertexArray(),g.bindVertexArray(bo),i=0,o=ai,r=pc,g.bindBuffer(g.ARRAY_BUFFER,Mn),a("g",g.FLOAT,0,2),g.bindBuffer(g.ARRAY_BUFFER,mo),g.bufferData(g.ARRAY_BUFFER,ui,g.DYNAMIC_DRAW),a("p",g.FLOAT,4,4,1),a("u",g.FLOAT,4,4,1),a("c",g.UNSIGNED_BYTE,1,4,1),a("a",g.UNSIGNED_BYTE,1,4,1),a("r",g.FLOAT,4,1,1),xo=g.createVertexArray(),g.bindVertexArray(xo),i=0,o=ci,r=gc,a("p",g.FLOAT,4,2),a("c",g.UNSIGNED_BYTE,1,4)}}function ys(n=!1){!n&&!mn||(Ct(),mn=!1,g.useProgram(ai),g.bindVertexArray(bo))}function yc(){mn||(Ct(),mn=!0,g.useProgram(ci),g.bindVertexArray(xo))}function So(n=!0){if(!k||!g)return;f(!Tt,"glPreRender called with unflushed batch."),li||(Q.width=D.x,Q.height=D.y),g.viewport(0,0,D.x,D.y),n&&mc();let t=x(2*W).divide(D);li&&(t.y=-t.y);let e=At.rotate(-$),s=x(-1).subtract(e.multiply(t)),i=ot($),o=tt($),r=[t.x*i,t.y*o,0,0,-t.x*o,t.y*i,0,0,1,1,1,0,s.x,s.y,0,1],a=(c,l,u)=>{g.useProgram(c);let h=g.getUniformLocation(c,l);g.uniformMatrix4fv(h,!1,u)};a(ci,"m",r),a(ai,"m",r),g.activeTexture(g.TEXTURE0),nn[0]&&(Xt=nn[0].glTexture,g.bindTexture(g.TEXTURE_2D,Xt)),g.bindBuffer(g.ARRAY_BUFFER,mo),Tn=zn=!1,ys(!0)}function mc(){if(!g)return;let n=Ye;g.clearColor(n.r,n.g,n.b,n.a),g.clear(g.COLOR_BUFFER_BIT)}function Ir(n){!g||n===Xt||(Ct(),Xt=n,g.bindTexture(g.TEXTURE_2D,Xt))}function bc(n,t=!0){if(!g||!n)return;let e=n===Xt;e?Ct():g.bindTexture(g.TEXTURE_2D,n);let s=t?g.REPEAT:g.CLAMP_TO_EDGE;g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_S,s),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_T,s),!e&&Xt&&g.bindTexture(g.TEXTURE_2D,Xt)}function wo(n,t){if(!g)return;let e=g.createShader(t);if(g.shaderSource(e,n),g.compileShader(e),It&&!g.getShaderParameter(e,g.COMPILE_STATUS))throw g.getShaderInfoLog(e);return e}function Jn(n,t){if(!g)return;let e=g.createProgram();if(g.attachShader(e,wo(n,g.VERTEX_SHADER)),g.attachShader(e,wo(t,g.FRAGMENT_SHADER)),g.linkProgram(e),It&&!g.getProgramParameter(e,g.LINK_STATUS))throw g.getProgramInfoLog(e);return e}function Ii(n,t=!1){if(!g)return;let e=g.createTexture(),s=!1;if(n!=null&&n.width)Mr(e,n),g.bindTexture(g.TEXTURE_2D,e),s=!gn&&os(n.width)&&os(n.height);else{let a=new Uint8Array([255,255,255,255]);g.bindTexture(g.TEXTURE_2D,e),g.texImage2D(g.TEXTURE_2D,0,g.RGBA,1,1,0,g.RGBA,g.UNSIGNED_BYTE,a)}let i=gn?g.NEAREST:g.LINEAR,o=s?g.LINEAR_MIPMAP_LINEAR:i;g.texParameteri(g.TEXTURE_2D,g.TEXTURE_MAG_FILTER,i),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_MIN_FILTER,o);let r=t?g.REPEAT:g.CLAMP_TO_EDGE;return g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_S,r),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_T,r),s&&g.generateMipmap(g.TEXTURE_2D),g.bindTexture(g.TEXTURE_2D,Xt),e}function xc(n){g&&g.deleteTexture(n)}function Mr(n,t){g&&(f((t==null?void 0:t.width)>0,"Invalid image data."),g.bindTexture(g.TEXTURE_2D,n),g.texImage2D(g.TEXTURE_2D,0,g.RGBA,g.RGBA,g.UNSIGNED_BYTE,t),!gn&&os(t.width)&&os(t.height)&&g.generateMipmap(g.TEXTURE_2D),g.bindTexture(g.TEXTURE_2D,Xt))}function Hh(n){j||(ss.add(n),g&&(n.glTexture?Mr(n.glTexture,n.image):n.glTexture=Ii(n.image,n.wrap)))}function Xh(n){if(j)return;ss.delete(n);let t=n.glTexture;n.glTexture=void 0,xc(t)}function Ct(){if(k&&g&&Tt){let n=zn?g.ONE:g.ONE_MINUS_SRC_ALPHA;g.blendFuncSeparate(g.SRC_ALPHA,n,g.ONE,n),g.enable(g.BLEND);let t=Tt*(mn?Di:Dr);g.bufferSubData(g.ARRAY_BUFFER,0,Dt,0,t),mn?g.drawArrays(g.TRIANGLE_STRIP,0,Tt):g.drawArraysInstanced(g.TRIANGLE_STRIP,0,4,Tt),++Te,Ae+=Tt,Tt=0}zn=Tn}function kr(n){!k||!g||(Ct(),n.drawImage(Q,0,0))}function Yh(n=!0){f(!Q,"must be called before engineInit"),Lr=n}function ms(n,t,e,s,i=0,o=0,r=0,a=1,c=1,l=-1,u=0){(Tt>=Wh||zn!==Tn)&&Ct(),ys();let h=Tt++*Dr;Dt[h++]=n,Dt[h++]=t,Dt[h++]=e,Dt[h++]=s,Dt[h++]=o,Dt[h++]=r,Dt[h++]=a,Dt[h++]=c,gs[h++]=l,gs[h++]=u,Dt[h++]=i}function vc(n,t,e,s,i,o){ms(n,t,e,s,i,0,0,0,0,0,o)}function Gr(n,t,e,s,i,o,r,a=!0){let c=[],l=tt(-r),u=ot(-r);for(let p of n){let d=p.x*i,y=p.y*o;c.push(x(e+u*d-l*y,s+l*d+u*y))}let h=a?Kh(c):c;Sc(h,t)}function Fr(n,t,e,s,i,o,r,a,c=!0){let l=$h(n,e,c);Gr(l,t,s,i,o,r,a,!1)}function Sc(n,t){if(!k||n.length<3)return;let e=n.length+2;if((Tt+e>=kn||zn!==Tn)&&Ct(),f(e=kn)return;yc();let s=Tt*Di;for(let i=e;i--;){let o=F(i-1,0,e-3),r=n[o];Dt[s++]=r.x,Dt[s++]=r.y,gs[s++]=t}Tt+=e}function jr(n,t){if(!k||n.length<3)return;let e=n.length+2;if((Tt+e>=kn||zn!==Tn)&&Ct(),f(e=kn)return;yc();let s=Tt*Di;for(let i=e;i--;){let o=F(i-1,0,e-3),r=n[o],a=t[o];Dt[s++]=r.x,Dt[s++]=r.y,gs[s++]=a}Tt+=e}function Qn(n,t=!1){n?(li=n,g.bindFramebuffer(g.FRAMEBUFFER,Or),g.framebufferTexture2D(g.FRAMEBUFFER,g.COLOR_ATTACHMENT0,g.TEXTURE_2D,n,0),So(t)):(Ct(),li=void 0,g.bindFramebuffer(g.FRAMEBUFFER,null),g.viewport(0,0,D.x,D.y))}function wc(n,t,e,s){k&&(g.enable(g.SCISSOR_TEST),g.scissor(n,t,e,s),g.clearColor(0,0,0,0),g.clear(g.COLOR_BUFFER_BIT),g.disable(g.SCISSOR_TEST))}function $h(n,t,e=!0){if(n.length<2)return[];let s=t/2,i=[],o=n.length,r=1e-6,a=10;for(let c=0;cr?-d/y:0,w=y>r?p/y:0,E=S>r?-v/S:0,A=S>r?b/S:0,T=_+E,R=w+A,M=(T*T+R*R)**.5;if(Mr){let gt=K(1/lt,a);T*=gt,R*=gt}}let ct=x(u.x-T*s,u.y-R*s),et=x(u.x+T*s,u.y+R*s);i.push(ct),i.push(et)}return i.length>1&&e&&(i.push(i[0]),i.push(i[1])),i}function Kh(n){if(n.length<3)return[];let t=(d,y,b)=>(y.x-d.x)*(b.y-d.y)-(y.y-d.y)*(b.x-d.x);(d=>{let y=0;for(let b=d.length;b--;){let v=(b+1)%d.length;y+=d[b].cross(d[v])}return y})(n)<0&&(n=n.slice().reverse());let s=1e-9,i=(d,y,b,v)=>{let S=t(y,b,d),_=t(b,v,d),w=t(v,y,d),E=(S<-s?1:0)+(_<-s?1:0)+(w<-s?1:0),A=(S>s?1:0)+(_>s?1:0)+(w>s?1:0);return!(E&&A)},o=[];for(let d=0;d3&&a++{if(E>=0){let T=s.fillStyle=s.createLinearGradient(v,S,_,w);T.addColorStop(0,h(E,2)),T.addColorStop(1,h(E,1))}else s.fillStyle="#000";E>=-1?(s.fill(),A&&s.stroke()):s.stroke()},c=(v,S,_,w=0,E=2*q,A,T)=>{s.beginPath(),s.arc(v,S,_,d*w,d*E),a(v,S-_,v,S+_,A,T)},l=(v,S,_,w,E)=>{s.beginPath(),s.rect(v,S,_,w*d),a(v,S+w,v+_,S,E)},u=(v,S,_,w)=>{s.beginPath();for(let E of v)s.lineTo(E.x,E.y);s.closePath(),a(0,_,0,_+w,S)},h=(v,S)=>S?`hsl(${[.95,.56,.13][v%3]*360} 99%${[0,50,75][S]}%)`:"#000",p=Ja(1,1,n),d=Mt(p,.1,.5),y=K(6,K(o,r)/99);s.translate(o/2,r/2),s.scale(y,y),s.translate(-40,-35),d<1&&s.setLineDash([99*d,99]),s.lineJoin=s.lineCap="round",s.lineWidth=.1+d*1.9;{let S="LittleJS";s.font="900 15.5px arial",s.lineWidth=.1+d*3.9,s.textAlign="center",s.textBaseline="top",l(11,55,59,8*d,-1),s.beginPath();let _=0;for(let w=0;w5?1:0),s[w?"strokeText":"fillText"](S[E],R,54+.5,17*d),A+=T}s.lineWidth=.1+d*1.9,l(3,54,73,0)}l(7,15,26,-7,0),l(25,15,8,25,-1),l(10,40,15,-25,1),l(14,21,7,9,2),l(38,20,6,-6,2),l(49,20,10,-6,0);let b=[x(44,8),x(64,8),x(59,8+6*d),x(49,8+6*d)];u(b,2,8,6*d),l(44,8,20,-7,0);for(let v=5;v--;)c(59-v*6*d,30,10,0,2*q,1,0);c(59,30,4,0,7,2),l(35,20,24,0),c(59,30,10),c(47,30,10,q/2,q*3/2),c(35,30,10,q/2,q*3/2),l(7,40,13,7,-1),l(17,40,43,14,-1);for(let v=3;v--;)for(let S=2;S--;)c(17+15*v,47,S?7:1,0,2*q,2);for(let v=2;v--;){let S=6,_=7,w=53+S*d*v,E=[x(w+_,54),x(w,40),x(w+S*d,40),x(w+_+S*d,54)];u(E,0,40,14)}s.restore()}function Zh(n){if(fi=n,!on){let e={};try{e=JSON.parse(localStorage[n]||"{}")}catch{e={}}Mi(s=>{s.unlocked=!!(e[s.id]&&e[s.id].unlocked)}),Br()}bn(void 0,t);function t(){if(!zs.length)return;let e=zs[0],s=Ze-Bs;if(!Bs)Bs=Ze;else if(s>hi)Bs=0,zs.shift();else{let i=hi-Dn,o=si?(s-i)/Dn:0;e.render(o)}}}function Mi(n){Object.values(bs).forEach(t=>n(t))}function td(){Mi(n=>n.unlocked=!1),Br()}function Br(){if(!fi)return;let n={};Mi(t=>{let e={name:t.name,description:t.description,icon:t.icon,unlocked:t.unlocked};t.image&&(e.src=t.image.src),n[t.id]=e}),localStorage[fi]=JSON.stringify(n)}function ed(n){hi=n}function nd(n){Dn=n}function sd(n){di=n.copy()}function id(n){Nr=n}function Tc(n,t,e,s=125){let i,o,r,a,c,l,u,h,p,d,y,b,v,S=0,_,w=[],E=[],A=[],T=0,R=0,M=1,ct={},et=qn/s*60>>2;for(;M;T++)w=[M=h=b=0],e.forEach((lt,gt)=>{for(u=t[lt][T]||[0,0,0],M|=t[lt][T]&&1,_=b+(t[lt][0].length-2-(h?0:1))*et,v=gt===e.length-1,i=2,r=b;iet-99&&p&&y<1?y+=1/99:0)l=(1-y)*w[S++]/2||0,E[r]=(E[r]||0)-l*R+l,A[r]=(A[r++]||0)+l*R+l;c&&(y=c%1,R=u[1]||0,(c|=0)&&(w=ct[[d=u[S=0]||0,c]]=ct[[d,c]]||(a=[...n[d]],a[2]=(a[2]||220)*2**(c/12-1),c>0?Oi(...a):[])))}b=_});return[E,A]}function od(n){zr=typeof n=="boolean"?n?1:0:n}function rd(n){Jr=n}async function ad(){return new xi(await Box2D()),e(),bn(n,t),m;function n(){if(!Se){m.step(),m.objects=m.objects.filter(s=>!s.destroyed);for(let s of m.objects)s.body&&(s.pos=m.vec2From(s.body.GetPosition()),s.angle=-s.body.GetAngle())}}function t(){(Jr||re)&&m.world.DrawDebugData()}function e(){let i=new m.instance.JSDraw,o=l=>new St(l.get_r(),l.get_g(),l.get_b()),r=l=>o(m.instance.wrapPointer(l,m.instance.b2Color)),a=l=>r(l).scale(1,.8),c=(l,u)=>{let h=[];for(let p=u;p--;)h.push(m.vec2FromPointer(l+p*8));return h};i.DrawSegment=function(l,u,h){h=a(h),l=m.vec2FromPointer(l),u=m.vec2FromPointer(u),ln(l,u,.1,h,x(),0,!1)},i.DrawPolygon=function(l,u,h){h=a(h);let p=c(l,u);Fn(p,tn,.1,h,x(),0,!1)},i.DrawSolidPolygon=function(l,u,h){h=a(h);let p=c(l,u);Fn(p,h,0,h,x(),0,!1)},i.DrawCircle=function(l,u,h){h=a(h),l=m.vec2FromPointer(l),Qs(l,u*2,tn,.1,h,!1)},i.DrawSolidCircle=function(l,u,h,p){p=a(p),l=m.vec2FromPointer(l),h=m.vec2FromPointer(h).scale(u),Qs(l,u*2,p,.1,p,!1),ln(x(),h,.1,p,l,0,!1)},i.DrawTransform=function(l){l=m.instance.wrapPointer(l,m.instance.b2Transform);let u=m.vec2From(l.get_p()),h=-l.get_q().GetAngle(),p=x(1,0),d=B(.75,0,0,.8),y=x(0,1),b=B(0,.75,0,.8);ln(x(),p,.1,d,u,h,!1),ln(x(),y,.1,b,u,h,!1)},i.AppendFlags(m.instance.b2Draw.e_shapeBit),i.AppendFlags(m.instance.b2Draw.e_jointBit),m.world.SetDebugDraw(i)}}function cd(n,t,e,s=32,i=2,o=0){Ac(n,t,e,U,s,nt,i,o,!1,!0)}function Ac(n,t,e,s,i=1,o,r=.05,a=0,c=k,l,u){let h=e.offset(e.size),p=t.add(x(r-i*2)),d=x(i),y=t.scale(.5).subtract(d.scale(.5)),b=l?-1:1,v=l?-a:a;_t(n,p,h,s,a,!1,o,c,l,u);for(let S=4;S--;){let _=S%2,w=y.multiply(x(_?S===1?1:-1:0,_?0:S?-1:1)),E=x(_?i:p.x,_?p.y:i),A=h.offset(e.size.multiply(x(S===1?1:S===3?-1:0,S===0?-b:S===2?b:0)));_t(n.add(w.rotate(v)),E,A,s,a,!1,o,c,l,u)}for(let S=4;S--;){let _=S>1,w=S&&S<3,E=y.multiply(x(_?-1:1,w?-1:1)),A=h.offset(e.size.multiply(x(_?-1:1,w?b:-b)));_t(n.add(E.rotate(v)),d,A,s,a,!1,o,c,l,u)}}function ld(n,t,e,s=32,i=2,o=0){Cc(n,t,e,U,s,nt,i,o,!1,!0)}function Cc(n,t,e,s,i=1,o,r=.05,a=0,c=k,l,u){let h=e.frame(0),p=e.frame(1),d=e.frame(2),y=t.add(x(r-i*2)),b=x(i),v=t.scale(.5).subtract(b.scale(.5)),S=l?-1:1,_=l?-a:a;_t(n,y,d,s,a,!1,o,c,l,u);for(let w=4;w--;){let E=a+w*q/2,A=w%2,T=v.multiply(x(A?w===1?1:-1:0,A?0:w?-S:S)),R=x(A?y.y:y.x,i);_t(n.add(T.rotate(_)),R,p,s,E,!1,o,c,l,u)}for(let w=4;w--;){let E=a+w*q/2,A=!w||w>2,T=w>1,R=v.multiply(x(A?-1:1,T?-S:S));_t(n.add(R.rotate(_)),b,h,s,E,!1,o,c,l,u)}}function ud(n,t=1,e=0,s=U,i=0,o=!1,r=0,a=nt,c=k,l=!1,u){let h=Ec(x(),t,e,0,o);Fn(h,s,r,a,n,i,c,l,u)}function Ec(n,t=1,e=0,s=0,i=!1,o=Ts){f(L(n),"pos must be a vec2"),f(P(t)&&P(e),"size and percent must be numbers");let r=te(e*4,4);r>=2&&(s+=q),r=r<=2?r-1:3-r,i&&(r=-r,s+=q);let a=[],c=X(3,o>>1),l=t/2;for(let u=0;u<=c;u++){let h=u/c*q;a.push(x(l*ot(h),l*tt(h)).rotate(s).add(n))}for(let u=c;u>=0;u--){let h=u/c*q;a.push(x(l*ot(h),-l*r*tt(h)).rotate(s).add(n))}return a}function _a(n){return n&&typeof n.lerp=="function"}function hd(n,t,e,s,i=1,o={}){f(n!=null&&typeof n=="object","tweenProperty target must be an object"),f(J(t)&&t.length>0,"tweenProperty propertyPath must be a non-empty string");let r=t.split("."),a=r.pop(),c=l=>{let u=n;for(let h of r)u=u[h];u[a]=l};return new vi(c,e,s,i,o)}function _c(n){n.loopRemaining!==1/0&&n.loopRemaining<=1||(n.loopRemaining!==1/0&&(n.loopRemaining-=1),n.life=n.duration,n.thenCallback=()=>_c(n),qt.push(n),n.callback(n.interp(n.duration)))}function Rc(n){if(n.loopRemaining!==1/0&&n.loopRemaining<=1)return;n.loopRemaining!==1/0&&(n.loopRemaining-=1);let t=n.start;n.start=n.end,n.end=t,n.life=n.duration,n.thenCallback=()=>Rc(n),qt.push(n),n.callback(n.interp(n.duration))}function Pc(n,t){n===void 0?(n=Ht-Ca,t=Ze-Ea,Ca=Ht,Ea=Ze):t===void 0&&(t=n);for(let e=qt.length;e--;){let s=qt[e];if(s.paused)continue;let i=s.useRealTime?t:n;if(!(i<=0))if(s.life-=i,s.life>0)s.callback(s.interp(s.life));else{s.callback(s.interp(0)),qt.splice(e,1);let o=s.thenCallback;s.thenCallback=void 0,o&&o()}}}function dd(){for(let n of qt)n.thenCallback=void 0;qt.length=0}var Js,Us,El,$o,xt,Ko,Ra,Ht,Ze,Se,so,ge,Vs,Pa,un,ro,It,Da,Ti,Ia,Pe,Xe,re,ae,hn,dn,Gn,ao,Le,oe,q,Z,vt,is,Ws,K,X,Zt,Fa,ja,tt,ot,Na,Zo,uo,st,St,U,tn,nt,ue,Vl,nr,Wl,Xa,Ya,ql,$a,Ka,Hl,we,At,$,W,ir,Ai,Ye,Rn,Zn,Pn,Ln,or,gn,$e,ws,rr,j,k,Ts,Ci,Ei,_i,Ri,ar,cr,lr,ur,hr,De,Bt,Xs,Pi,dr,ts,cn,en,fr,le,Un,xn,Vn,Wn,As,sn,Jt,pr,es,Ys,Cs,Ut,fn,gr,yr,je,G,at,wt,ke,qe,be,Ie,D,nn,Te,Ae,Ce,Ne,nh,rc,Zs,_e,jt,xr,ye,vr,ti,In,He,Sr,On,yt,ee,H,me,rn,io,jn,ne,yn,ei,Ls,Me,Ve,lc,Er,uc,us,an,Nn,Sa,ni,ft,Fe,qn,ds,si,Qe,pn,oi,fs,ps,yo,Vh,ri,Q,g,Lr,ai,ci,mn,Tn,zn,Xt,mo,Mn,Dt,gs,Tt,ss,bo,xo,Or,li,vo,ui,Dr,pc,Wh,Di,gc,kn,on,hi,Dn,di,Nr,bs,zs,fi,Bs,pi,xs,To,Ao,Lt,Co,V,Eo,_o,Ro,C,zr,Po,se,gi,Lo,Oo,vs,Do,Io,Mo,ko,m,Jr,Ss,yi,Go,Fo,mi,Vt,jo,bi,No,Bo,zo,Jo,Uo,Vo,Wo,qo,Ho,Xo,xi,qt,Ca,Ea,vi,Si,fd,oo,wi,Yo,Oc=jc(()=>{"use strict";Js="LittleJS",Us="1.18.19",El=60,$o=.016666666666666666,xt=[],Ko=[],Ra=0,Ht=0,Ze=0,Se=!1;so=0,ge=0,Vs=0,Pa=!0,un=[],ro=class{constructor(t,e,s,i){this.update=t,this.render=e,this.glContextLost=s,this.glContextRestored=i}};It=!0,Da=.5,Ti=!0,Ia="Escape",Pe=!1,Xe=[],re=!1,ae=!1,hn=!1,dn=!1,Gn=!1;q=Math.PI,Z=Math.abs,vt=Math.floor,is=Math.ceil,Ws=Math.round,K=Math.min,X=Math.max,Zt=n=>Math.sign(n),Fa=(...n)=>Math.hypot(...n),ja=n=>Math.log2(n),tt=Math.sin,ot=Math.cos,Na=Math.tan,Zo=Math.atan2;uo=class{constructor(t=123456789){f(t!==0,"RandomGenerator seed must be non-zero (xorshift is fixed at 0)"),this.seed=t}float(t=1,e=0){return this.seed^=this.seed<<13,this.seed^=this.seed>>>17,this.seed^=this.seed<<5,e+(t-e)*((this.seed>>>0)/2**32)}int(t,e=0){return vt(this.float(t,e))}bool(t=.5){return this.float().5?1:-1}floatSign(t=1,e=0){let s=K(t,e),o=X(t,e)-s,r=this.float(o*2);return rt?this.scale(t/e):this.copy()}dot(t){return this.x*t.x+this.y*t.y}cross(t){return this.x*t.y-this.y*t.x}reflect(t,e=1){return this.subtract(t.scale((1+e)*this.dot(t)))}angle(){return Zo(this.x,this.y)}setAngle(t=0,e=1){return Wt(t),Wt(e),this.x=e*tt(t),this.y=e*ot(t),this}rotate(t){Wt(t);let e=ot(-t),s=tt(-t);return new n(this.x*e-this.y*s,this.x*s+this.y*e)}setDirection(t,e=1){return Wt(t),Wt(e),t=te(t,4),f(t===0||t===1||t===2||t===3,"Vector2.setDirection() direction must be an integer between 0 and 3."),this.x=t%2?t-1?-e:e:0,this.y=t%2?0:t?-e:e,this}direction(){return Z(this.x)>Z(this.y)?this.x<0?3:1:this.y<0?2:0}abs(){return new n(Z(this.x),Z(this.y))}floor(){return new n(vt(this.x),vt(this.y))}snap(t){return Wt(t),new n(vt(this.x*t)/t,vt(this.y*t)/t)}mod(t=1){return new n(te(this.x,t),te(this.y,t))}area(){return Z(this.x*this.y)}lerp(t,e){xa(t),Wt(e);let s=F(e);return new n(t.x*s+this.x*(1-s),t.y*s+this.y*(1-s))}arrayCheck(t){return this.x>=0&&this.y>=0&&this.x(u=te(u,1))*6<1?c+(l-c)*6*u:u*2<1?l:u*3<2?c+(l-c)*(4-u*6):c;return this.r=a(r,o,t+1/3),this.g=a(r,o,t),this.b=a(r,o,t-1/3),this.a=i,Kn(this),this}HSLA(){let t=F(this.r),e=F(this.g),s=F(this.b),i=F(this.a),o=X(t,e,s),r=K(t,e,s),a=(o+r)/2,c=0,l=0;if(o!==r){let u=o-r;l=a>.5?u/(2-o-r):u/(o+r),t===o?c=(e-s)/u+(e((s=F(s)*255|0)<16?"0":"")+s.toString(16);return"#"+e(this.r)+e(this.g)+e(this.b)+(t?e(this.a):"")}setHex(t){if(f(J(t),"Color hex code must be a string"),f(t[0]==="#","Color hex code must start with #"),f([4,5,7,9].includes(t.length),"Invalid hex"),t.length<6){let e=s=>F(parseInt(t[s],16)/15);this.r=e(1),this.g=e(2),this.b=e(3),this.a=t.length===5?e(4):1}else{let e=s=>F(parseInt(t.slice(s,s+2),16)/255);this.r=e(1),this.g=e(3),this.b=e(5),this.a=t.length===9?e(7):1}return Kn(this),this}rgbaInt(){let t=F(this.r)*255|0,e=F(this.g)*255<<8,s=F(this.b)*255<<16,i=F(this.a)*255<<24;return t+e+s+i}isValid(){return P(this.r)&&P(this.g)&&P(this.b)&&P(this.a)}},U=Yt(B()),tn=Yt(B(1,1,1,0)),nt=Yt(B(0,0,0)),ue=Yt(B(0,0,0,0)),Vl=Yt(B(.5,.5,.5)),nr=Yt(B(1,0,0)),Wl=Yt(B(1,.5,0)),Xa=Yt(B(1,1,0)),Ya=Yt(B(0,1,0)),ql=Yt(B(0,1,1)),$a=Yt(B(0,0,1)),Ka=Yt(B(.5,0,1)),Hl=Yt(B(1,0,1)),we=class{constructor(t,e=!1){f(t===void 0||P(t),"Constructed Timer is invalid.",t),this.useRealTime=e;let s=this.getGlobalTime();this.time=t===void 0?void 0:s+t,this.setTime=t}set(t=0){f(P(t),"Timer is invalid.",t);let e=this.getGlobalTime();this.time=e+t,this.setTime=t}setUseRealTime(t=!0){f(!this.isSet(),"Cannot change global time setting while timer is set."),this.useRealTime=t}unset(){this.time=void 0}isSet(){return this.time!==void 0}active(){return this.getGlobalTime()=this.time}get(){return this.isSet()?this.getGlobalTime()-this.time:0}getPercent(){return this.isSet()?this.setTime?1-Mt(this.time-this.getGlobalTime(),0,this.setTime):1:0}getSetTime(){return this.isSet()?this.setTime:0}getGlobalTime(){return this.useRealTime?Ze:Ht}toString(){return this.isSet()?Z(this.get())+" seconds "+(this.get()<0?"before":"after"):"unset"}valueOf(){return this.get()}};At=x(),$=0,W=32,ir=1,Ai=!0,Ye=ue,Rn=x(1920,1080),Zn=0,Pn=0,Ln=x(),or=!1,gn=!0,$e=1,ws="arial",rr=!1,j=!1,k=!0,Ts=32,Ci=x(16),Ei=0,_i=0,Ri=!0,ar=1,cr=1,lr=1,ur=0,hr=.8,De=1,Bt=x(),Xs=1,Pi=!0,dr=!0,ts=!0,cn=!0,en=!1,fr=!1,le=0,Un=4,xn=!0,Vn=0,Wn=!1,As=!0,sn=!1,Jt=100,pr=.3,es=3,Ys=0,Cs=!0,Ut=!0,fn=.3,gr=40,yr=.7;je=class n{constructor(t=x(),e=x(1),s,i=0,o=U,r=0){f(L(t),"object pos must be a vec2"),f(L(e),"object size must be a vec2"),f(!s||s instanceof Ce,"object tileInfo should be a TileInfo or undefined"),f(typeof i=="number"&&isFinite(i),"object angle should be a number"),f(z(o),"object color should be a valid rgba color"),f(typeof r=="number","object renderOrder should be a number"),this.pos=t.copy(),this.size=e.copy(),this.drawSize=void 0,this.tileInfo=s,this.angle=i,this.color=o.copy(),this.additiveColor=void 0,this.mirror=!1,this.destroyed=!1,this.mass=ar,this.damping=cr,this.angleDamping=lr,this.restitution=ur,this.friction=hr,this.gravityScale=1,this.renderOrder=r,this.velocity=x(),this.angleVelocity=0,this.spawnTime=Ht,this.children=[],this.clampSpeed=!0,this.groundObject=void 0,this.parent=void 0,this.localPos=x(),this.localAngle=0,this.collideTiles=!1,this.collideSolidObjects=!1,this.isSolid=!1,this.collideRaycast=!1,xt.push(this)}updateTransforms(){let t=this.parent;if(t){let e=t.getMirrorSign(),s=this.localPos,i=t.pos,o=s.x*e,r=s.y,a=t.angle;if(a){let c=ot(-a),l=tt(-a);this.pos.set(o*c-r*l+i.x,o*l+r*c+i.y)}else this.pos.set(o+i.x,r+i.y);this.angle=e*this.localAngle+a}for(let e of this.children)e.updateTransforms()}updatePhysics(){if(f(!this.parent),this.destroyed)return;this.clampSpeed&&(this.velocity.x=F(this.velocity.x,-De,De),this.velocity.y=F(this.velocity.y,-De,De));let t=this.pos.copy();if(this.velocity.x*=this.damping,this.velocity.y*=this.damping,this.mass&&(this.velocity.x+=Bt.x*this.gravityScale,this.velocity.y+=Bt.y*this.gravityScale),this.pos.x+=this.velocity.x,this.pos.y+=this.velocity.y,this.angle+=this.angleVelocity*=this.angleDamping,f(this.angleDamping>=0&&this.angleDamping<=1),f(this.damping>=0&&this.damping<=1),!Ri||!this.mass)return;let e=this.velocity.y<0&&Bt.y<0||this.velocity.y>0&&Bt.y>0;if(this.groundObject){let s=X(this.friction,this.groundObject.friction),i=this.groundObject.velocity.x;this.velocity.x=i+(this.velocity.x-i)*s,this.groundObject=void 0}if(this.collideSolidObjects)for(let i of Ko){if(i.destroyed||i.parent||i===this||!this.isSolid&&!i.isSolid||!this.isOverlappingObject(i))continue;let o=this.collideWithObject(i),r=i.collideWithObject(this);if(!o||!r)continue;if(Hs(t,this.size,i.pos,i.size)){let p=t.subtract(i.pos),d=p.length(),b=d<.001?x(0,1):p.scale(.001/d);this.velocity=this.velocity.add(b),i.mass&&(i.velocity=i.velocity.subtract(b)),re&&co(this.pos,this.size,i.pos,i.size,"#f00");continue}let a=this.size.add(i.size),c=(t.y-i.pos.y)*2>a.y+Bt.y,l=Z(t.y-i.pos.y)*20?-1:1)>0?vt(t.y-this.size.y/2+1)+this.size.y/2+.001:is(t.y+this.size.y/2-1)-this.size.y/2-.001;if(Z(u-this.pos.y)<.1&&!We(x(this.pos.x,u),this.size,this)){this.pos.y=u,re&&mt(this.pos,this.size,"#ff0");return}this.pos.x=t.x,this.velocity.x*=-r}if(o||!i){if(e){let c=this.size.y/2+1e-4;this.pos.y=Bt.y<0?vt(t.y-this.size.y/2)+c:is(t.y+this.size.y/2)-c,this.groundObject=s}else this.pos.y=t.y,this.groundObject=void 0;this.velocity.y*=-r}re&&mt(this.pos,this.size,"#f00")}}}update(){}render(){_t(this.pos,this.drawSize||this.size,this.tileInfo,this.color,this.angle,this.mirror,this.additiveColor)}renderLight(){}destroy(t=!1){var e;if(!this.destroyed){this.destroyed=!0,(e=this.parent)==null||e.removeChild(this);for(let s of this.children)s.parent=void 0,s.destroy(t)}}localToWorld(t){return this.pos.add(t.rotate(this.angle))}worldToLocal(t){return t.subtract(this.pos).rotate(-this.angle)}localToWorldVector(t){return t.rotate(this.angle)}worldToLocalVector(t){return t.rotate(-this.angle)}collideWithTile(t,e){return t>0}collideWithObject(t){return!0}getUp(t=1){return x().setAngle(this.angle,t)}getRight(t=1){return x().setAngle(this.angle+q/2,t)}getAliveTime(){return Ht-this.spawnTime}getSpeed(){return this.velocity.length()}applyAcceleration(t){this.mass&&(this.velocity=this.velocity.add(t))}applyAngularAcceleration(t){this.mass&&(this.angleVelocity+=t)}applyForce(t){this.mass&&this.applyAcceleration(t.scale(1/this.mass))}getMirrorSign(){return this.mirror?-1:1}addChild(t,e=x(),s=0){return f(!this.destroyed,"cannot add child to destroyed object"),this.destroyed||(f(!t.parent&&!this.children.includes(t)),f(t instanceof n,"child must be an EngineObject"),f(t!==this,"cannot add self as child"),this.children.push(t),t.parent=this,t.localPos=e.copy(),t.localAngle=s,t.updateTransforms()),t}removeChild(t){f(t.parent===this&&this.children.includes(t)),this.children.splice(this.children.indexOf(t),1),t.parent=void 0}isOverlappingObject(t){return this.isOverlapping(t.pos,t.size)}isOverlapping(t,e=x()){return Hs(this.pos,this.size,t,e)}setCollision(t=!0,e=!0,s=!0,i=!0){f(t||!e,"solid objects must be set to collide"),this.collideSolidObjects=t,this.isSolid=e,this.collideTiles=s,this.collideRaycast=i}toString(){let t="type = "+this.constructor.name;return(this.pos.x||this.pos.y)&&(t+=`
+precision highp float;in vec4 d;out vec4 c;void main(){c=d;}`);let e=new ArrayBuffer(ui);Dt=new Float32Array(e),gs=new Uint32Array(e),mo=g.createBuffer(),In=g.createBuffer(),Or=g.createFramebuffer(),wt=0;let s=new Float32Array([0,0,1,0,0,1,1,1]);g.bindBuffer(g.ARRAY_BUFFER,In),g.bufferData(g.ARRAY_BUFFER,s,g.STATIC_DRAW);let i,o,r,a=(c,l,u,h,p=0)=>{let d=g.getAttribLocation(o,c),y=u===1,x=u&&r;g.enableVertexAttribArray(d),g.vertexAttribPointer(d,h,l,y,x,i),g.vertexAttribDivisor(d,p),i+=h*u};bo=g.createVertexArray(),g.bindVertexArray(bo),i=0,o=ai,r=pc,g.bindBuffer(g.ARRAY_BUFFER,In),a("g",g.FLOAT,0,2),g.bindBuffer(g.ARRAY_BUFFER,mo),g.bufferData(g.ARRAY_BUFFER,ui,g.DYNAMIC_DRAW),a("p",g.FLOAT,4,4,1),a("u",g.FLOAT,4,4,1),a("c",g.UNSIGNED_BYTE,1,4,1),a("a",g.UNSIGNED_BYTE,1,4,1),a("r",g.FLOAT,4,1,1),xo=g.createVertexArray(),g.bindVertexArray(xo),i=0,o=ci,r=gc,a("p",g.FLOAT,4,2),a("c",g.UNSIGNED_BYTE,1,4)}}function ys(n=!1){!n&&!xn||(At(),xn=!1,g.useProgram(ai),g.bindVertexArray(bo))}function yc(){xn||(At(),xn=!0,g.useProgram(ci),g.bindVertexArray(xo))}function So(n=!0){if(!G||!g)return;f(!wt,"glPreRender called with unflushed batch."),li||(Q.width=I.x,Q.height=I.y),g.viewport(0,0,I.x,I.y),n&&mc();let t=b(2*W).divide(I);li&&(t.y=-t.y);let e=Tt.rotate(-Y),s=b(-1).subtract(e.multiply(t)),i=at(Y),o=tt(Y),r=[t.x*i,t.y*o,0,0,-t.x*o,t.y*i,0,0,1,1,1,0,s.x,s.y,0,1],a=(c,l,u)=>{g.useProgram(c);let h=g.getUniformLocation(c,l);g.uniformMatrix4fv(h,!1,u)};a(ci,"m",r),a(ai,"m",r),g.activeTexture(g.TEXTURE0),en[0]&&(Xt=en[0].glTexture,g.bindTexture(g.TEXTURE_2D,Xt)),g.bindBuffer(g.ARRAY_BUFFER,mo),En=Nn=!1,ys(!0)}function mc(){if(!g)return;let n=Xe;g.clearColor(n.r,n.g,n.b,n.a),g.clear(g.COLOR_BUFFER_BIT)}function Ir(n){!g||n===Xt||(At(),Xt=n,g.bindTexture(g.TEXTURE_2D,Xt))}function bc(n,t=!0){if(!g||!n)return;let e=n===Xt;e?At():g.bindTexture(g.TEXTURE_2D,n);let s=t?g.REPEAT:g.CLAMP_TO_EDGE;g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_S,s),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_T,s),!e&&Xt&&g.bindTexture(g.TEXTURE_2D,Xt)}function wo(n,t){if(!g)return;let e=g.createShader(t);if(g.shaderSource(e,n),g.compileShader(e),It&&!g.getShaderParameter(e,g.COMPILE_STATUS))throw g.getShaderInfoLog(e);return e}function zn(n,t){if(!g)return;let e=g.createProgram();if(g.attachShader(e,wo(n,g.VERTEX_SHADER)),g.attachShader(e,wo(t,g.FRAGMENT_SHADER)),g.linkProgram(e),It&&!g.getProgramParameter(e,g.LINK_STATUS))throw g.getProgramInfoLog(e);return e}function Ii(n,t=!1){if(!g)return;let e=g.createTexture(),s=!1;if(n!=null&&n.width)Mr(e,n),g.bindTexture(g.TEXTURE_2D,e),s=!mn&&os(n.width)&&os(n.height);else{let a=new Uint8Array([255,255,255,255]);g.bindTexture(g.TEXTURE_2D,e),g.texImage2D(g.TEXTURE_2D,0,g.RGBA,1,1,0,g.RGBA,g.UNSIGNED_BYTE,a)}let i=mn?g.NEAREST:g.LINEAR,o=s?g.LINEAR_MIPMAP_LINEAR:i;g.texParameteri(g.TEXTURE_2D,g.TEXTURE_MAG_FILTER,i),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_MIN_FILTER,o);let r=t?g.REPEAT:g.CLAMP_TO_EDGE;return g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_S,r),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_T,r),s&&g.generateMipmap(g.TEXTURE_2D),g.bindTexture(g.TEXTURE_2D,Xt),e}function xc(n){g&&g.deleteTexture(n)}function Mr(n,t){g&&(f((t==null?void 0:t.width)>0,"Invalid image data."),g.bindTexture(g.TEXTURE_2D,n),g.texImage2D(g.TEXTURE_2D,0,g.RGBA,g.RGBA,g.UNSIGNED_BYTE,t),!mn&&os(t.width)&&os(t.height)&&g.generateMipmap(g.TEXTURE_2D),g.bindTexture(g.TEXTURE_2D,Xt))}function Hh(n){B||(ss.add(n),g&&(n.glTexture?Mr(n.glTexture,n.image):n.glTexture=Ii(n.image,n.wrap)))}function Xh(n){if(B)return;ss.delete(n);let t=n.glTexture;n.glTexture=void 0,xc(t)}function At(){if(G&&g&&wt){let n=Nn?g.ONE:g.ONE_MINUS_SRC_ALPHA;g.blendFuncSeparate(g.SRC_ALPHA,n,g.ONE,n),g.enable(g.BLEND);let t=wt*(xn?Di:Dr);g.bufferSubData(g.ARRAY_BUFFER,0,Dt,0,t),xn?g.drawArrays(g.TRIANGLE_STRIP,0,wt):g.drawArraysInstanced(g.TRIANGLE_STRIP,0,4,wt),++we,Te+=wt,wt=0}Nn=En}function kr(n){!G||!g||(At(),n.drawImage(Q,0,0))}function Yh(n=!0){f(!Q,"must be called before engineInit"),Lr=n}function ms(n,t,e,s,i=0,o=0,r=0,a=1,c=1,l=-1,u=0){(wt>=Wh||Nn!==En)&&At(),ys();let h=wt++*Dr;Dt[h++]=n,Dt[h++]=t,Dt[h++]=e,Dt[h++]=s,Dt[h++]=o,Dt[h++]=r,Dt[h++]=a,Dt[h++]=c,gs[h++]=l,gs[h++]=u,Dt[h++]=i}function vc(n,t,e,s,i,o){ms(n,t,e,s,i,0,0,0,0,0,o)}function Gr(n,t,e,s,i,o,r,a=!0){let c=[],l=tt(-r),u=at(-r);for(let p of n){let d=p.x*i,y=p.y*o;c.push(b(e+u*d-l*y,s+l*d+u*y))}let h=a?Kh(c):c;Sc(h,t)}function Fr(n,t,e,s,i,o,r,a,c=!0){let l=$h(n,e,c);Gr(l,t,s,i,o,r,a,!1)}function Sc(n,t){if(!G||n.length<3)return;let e=n.length+2;if((wt+e>=Mn||Nn!==En)&&At(),f(e=Mn)return;yc();let s=wt*Di;for(let i=e;i--;){let o=j(i-1,0,e-3),r=n[o];Dt[s++]=r.x,Dt[s++]=r.y,gs[s++]=t}wt+=e}function jr(n,t){if(!G||n.length<3)return;let e=n.length+2;if((wt+e>=Mn||Nn!==En)&&At(),f(e=Mn)return;yc();let s=wt*Di;for(let i=e;i--;){let o=j(i-1,0,e-3),r=n[o],a=t[o];Dt[s++]=r.x,Dt[s++]=r.y,gs[s++]=a}wt+=e}function Qn(n,t=!1){n?(li=n,g.bindFramebuffer(g.FRAMEBUFFER,Or),g.framebufferTexture2D(g.FRAMEBUFFER,g.COLOR_ATTACHMENT0,g.TEXTURE_2D,n,0),So(t)):(At(),li=void 0,g.bindFramebuffer(g.FRAMEBUFFER,null),g.viewport(0,0,I.x,I.y))}function wc(n,t,e,s){G&&(g.enable(g.SCISSOR_TEST),g.scissor(n,t,e,s),g.clearColor(0,0,0,0),g.clear(g.COLOR_BUFFER_BIT),g.disable(g.SCISSOR_TEST))}function $h(n,t,e=!0){if(n.length<2)return[];let s=t/2,i=[],o=n.length,r=1e-6,a=10;for(let c=0;cr?-d/y:0,w=y>r?p/y:0,_=T>r?-v/T:0,A=T>r?x/T:0,S=C+_,R=w+A,M=(S*S+R*R)**.5;if(Mr){let rt=K(1/nt,a);S*=rt,R*=rt}}let ot=b(u.x-S*s,u.y-R*s),$=b(u.x+S*s,u.y+R*s);i.push(ot),i.push($)}return i.length>1&&e&&(i.push(i[0]),i.push(i[1])),i}function Kh(n){if(n.length<3)return[];let t=(d,y,x)=>(y.x-d.x)*(x.y-d.y)-(y.y-d.y)*(x.x-d.x);(d=>{let y=0;for(let x=d.length;x--;){let v=(x+1)%d.length;y+=d[x].cross(d[v])}return y})(n)<0&&(n=n.slice().reverse());let s=1e-9,i=(d,y,x,v)=>{let T=t(y,x,d),C=t(x,v,d),w=t(v,y,d),_=(T<-s?1:0)+(C<-s?1:0)+(w<-s?1:0),A=(T>s?1:0)+(C>s?1:0)+(w>s?1:0);return!(_&&A)},o=[];for(let d=0;d3&&a++{if(_>=0){let S=s.fillStyle=s.createLinearGradient(v,T,C,w);S.addColorStop(0,h(_,2)),S.addColorStop(1,h(_,1))}else s.fillStyle="#000";_>=-1?(s.fill(),A&&s.stroke()):s.stroke()},c=(v,T,C,w=0,_=2*q,A,S)=>{s.beginPath(),s.arc(v,T,C,d*w,d*_),a(v,T-C,v,T+C,A,S)},l=(v,T,C,w,_)=>{s.beginPath(),s.rect(v,T,C,w*d),a(v,T+w,v+C,T,_)},u=(v,T,C,w)=>{s.beginPath();for(let _ of v)s.lineTo(_.x,_.y);s.closePath(),a(0,C,0,C+w,T)},h=(v,T)=>T?`hsl(${[.95,.56,.13][v%3]*360} 99%${[0,50,75][T]}%)`:"#000",p=Ja(1,1,n),d=Mt(p,.1,.5),y=K(6,K(o,r)/99);s.translate(o/2,r/2),s.scale(y,y),s.translate(-40,-35),d<1&&s.setLineDash([99*d,99]),s.lineJoin=s.lineCap="round",s.lineWidth=.1+d*1.9;{let T="LittleJS";s.font="900 15.5px arial",s.lineWidth=.1+d*3.9,s.textAlign="center",s.textBaseline="top",l(11,55,59,8*d,-1),s.beginPath();let C=0;for(let w=0;w5?1:0),s[w?"strokeText":"fillText"](T[_],R,54+.5,17*d),A+=S}s.lineWidth=.1+d*1.9,l(3,54,73,0)}l(7,15,26,-7,0),l(25,15,8,25,-1),l(10,40,15,-25,1),l(14,21,7,9,2),l(38,20,6,-6,2),l(49,20,10,-6,0);let x=[b(44,8),b(64,8),b(59,8+6*d),b(49,8+6*d)];u(x,2,8,6*d),l(44,8,20,-7,0);for(let v=5;v--;)c(59-v*6*d,30,10,0,2*q,1,0);c(59,30,4,0,7,2),l(35,20,24,0),c(59,30,10),c(47,30,10,q/2,q*3/2),c(35,30,10,q/2,q*3/2),l(7,40,13,7,-1),l(17,40,43,14,-1);for(let v=3;v--;)for(let T=2;T--;)c(17+15*v,47,T?7:1,0,2*q,2);for(let v=2;v--;){let T=6,C=7,w=53+T*d*v,_=[b(w+C,54),b(w,40),b(w+T*d,40),b(w+C+T*d,54)];u(_,0,40,14)}s.restore()}function Zh(n){if(fi=n,!an){let e={};try{e=JSON.parse(localStorage[n]||"{}")}catch{e={}}Mi(s=>{s.unlocked=!!(e[s.id]&&e[s.id].unlocked)}),Nr()}vn(void 0,t);function t(){if(!zs.length)return;let e=zs[0],s=Qe-Ns;if(!Ns)Ns=Qe;else if(s>hi)Ns=0,zs.shift();else{let i=hi-On,o=si?(s-i)/On:0;e.render(o)}}}function Mi(n){Object.values(bs).forEach(t=>n(t))}function td(){Mi(n=>n.unlocked=!1),Nr()}function Nr(){if(!fi)return;let n={};Mi(t=>{let e={name:t.name,description:t.description,icon:t.icon,unlocked:t.unlocked};t.image&&(e.src=t.image.src),n[t.id]=e}),localStorage[fi]=JSON.stringify(n)}function ed(n){hi=n}function nd(n){On=n}function sd(n){di=n.copy()}function id(n){Br=n}function Tc(n,t,e,s=125){let i,o,r,a,c,l,u,h,p,d,y,x,v,T=0,C,w=[],_=[],A=[],S=0,R=0,M=1,ot={},$=Wn/s*60>>2;for(;M;S++)w=[M=h=x=0],e.forEach((nt,rt)=>{for(u=t[nt][S]||[0,0,0],M|=t[nt][S]&&1,C=x+(t[nt][0].length-2-(h?0:1))*$,v=rt===e.length-1,i=2,r=x;i$-99&&p&&y<1?y+=1/99:0)l=(1-y)*w[T++]/2||0,_[r]=(_[r]||0)-l*R+l,A[r]=(A[r++]||0)+l*R+l;c&&(y=c%1,R=u[1]||0,(c|=0)&&(w=ot[[d=u[T=0]||0,c]]=ot[[d,c]]||(a=[...n[d]],a[2]=(a[2]||220)*2**(c/12-1),c>0?Oi(...a):[])))}x=C});return[_,A]}function od(n){zr=typeof n=="boolean"?n?1:0:n}function rd(n){Jr=n}async function ad(){return new xi(await Box2D()),e(),vn(n,t),m;function n(){if(!ve){m.step(),m.objects=m.objects.filter(s=>!s.destroyed);for(let s of m.objects)s.body&&(s.pos=m.vec2From(s.body.GetPosition()),s.angle=-s.body.GetAngle())}}function t(){(Jr||re)&&m.world.DrawDebugData()}function e(){let i=new m.instance.JSDraw,o=l=>new xt(l.get_r(),l.get_g(),l.get_b()),r=l=>o(m.instance.wrapPointer(l,m.instance.b2Color)),a=l=>r(l).scale(1,.8),c=(l,u)=>{let h=[];for(let p=u;p--;)h.push(m.vec2FromPointer(l+p*8));return h};i.DrawSegment=function(l,u,h){h=a(h),l=m.vec2FromPointer(l),u=m.vec2FromPointer(u),hn(l,u,.1,h,b(),0,!1)},i.DrawPolygon=function(l,u,h){h=a(h);let p=c(l,u);Gn(p,Ze,.1,h,b(),0,!1)},i.DrawSolidPolygon=function(l,u,h){h=a(h);let p=c(l,u);Gn(p,h,0,h,b(),0,!1)},i.DrawCircle=function(l,u,h){h=a(h),l=m.vec2FromPointer(l),Qs(l,u*2,Ze,.1,h,!1)},i.DrawSolidCircle=function(l,u,h,p){p=a(p),l=m.vec2FromPointer(l),h=m.vec2FromPointer(h).scale(u),Qs(l,u*2,p,.1,p,!1),hn(b(),h,.1,p,l,0,!1)},i.DrawTransform=function(l){l=m.instance.wrapPointer(l,m.instance.b2Transform);let u=m.vec2From(l.get_p()),h=-l.get_q().GetAngle(),p=b(1,0),d=N(.75,0,0,.8),y=b(0,1),x=N(0,.75,0,.8);hn(b(),p,.1,d,u,h,!1),hn(b(),y,.1,x,u,h,!1)},i.AppendFlags(m.instance.b2Draw.e_shapeBit),i.AppendFlags(m.instance.b2Draw.e_jointBit),m.world.SetDebugDraw(i)}}function cd(n,t,e,s=32,i=2,o=0){Ac(n,t,e,U,s,et,i,o,!1,!0)}function Ac(n,t,e,s,i=1,o,r=.05,a=0,c=G,l,u){let h=e.offset(e.size),p=t.add(b(r-i*2)),d=b(i),y=t.scale(.5).subtract(d.scale(.5)),x=l?-1:1,v=l?-a:a;Rt(n,p,h,s,a,!1,o,c,l,u);for(let T=4;T--;){let C=T%2,w=y.multiply(b(C?T===1?1:-1:0,C?0:T?-1:1)),_=b(C?i:p.x,C?p.y:i),A=h.offset(e.size.multiply(b(T===1?1:T===3?-1:0,T===0?-x:T===2?x:0)));Rt(n.add(w.rotate(v)),_,A,s,a,!1,o,c,l,u)}for(let T=4;T--;){let C=T>1,w=T&&T<3,_=y.multiply(b(C?-1:1,w?-1:1)),A=h.offset(e.size.multiply(b(C?-1:1,w?x:-x)));Rt(n.add(_.rotate(v)),d,A,s,a,!1,o,c,l,u)}}function ld(n,t,e,s=32,i=2,o=0){Ec(n,t,e,U,s,et,i,o,!1,!0)}function Ec(n,t,e,s,i=1,o,r=.05,a=0,c=G,l,u){let h=e.frame(0),p=e.frame(1),d=e.frame(2),y=t.add(b(r-i*2)),x=b(i),v=t.scale(.5).subtract(x.scale(.5)),T=l?-1:1,C=l?-a:a;Rt(n,y,d,s,a,!1,o,c,l,u);for(let w=4;w--;){let _=a+w*q/2,A=w%2,S=v.multiply(b(A?w===1?1:-1:0,A?0:w?-T:T)),R=b(A?y.y:y.x,i);Rt(n.add(S.rotate(C)),R,p,s,_,!1,o,c,l,u)}for(let w=4;w--;){let _=a+w*q/2,A=!w||w>2,S=w>1,R=v.multiply(b(A?-1:1,S?-T:T));Rt(n.add(R.rotate(C)),x,h,s,_,!1,o,c,l,u)}}function ud(n,t=1,e=0,s=U,i=0,o=!1,r=0,a=et,c=G,l=!1,u){let h=_c(b(),t,e,0,o);Gn(h,s,r,a,n,i,c,l,u)}function _c(n,t=1,e=0,s=0,i=!1,o=Ts){f(L(n),"pos must be a vec2"),f(P(t)&&P(e),"size and percent must be numbers");let r=Qt(e*4,4);r>=2&&(s+=q),r=r<=2?r-1:3-r,i&&(r=-r,s+=q);let a=[],c=X(3,o>>1),l=t/2;for(let u=0;u<=c;u++){let h=u/c*q;a.push(b(l*at(h),l*tt(h)).rotate(s).add(n))}for(let u=c;u>=0;u--){let h=u/c*q;a.push(b(l*at(h),-l*r*tt(h)).rotate(s).add(n))}return a}function Ca(n){return n&&typeof n.lerp=="function"}function hd(n,t,e,s,i=1,o={}){f(n!=null&&typeof n=="object","tweenProperty target must be an object"),f(J(t)&&t.length>0,"tweenProperty propertyPath must be a non-empty string");let r=t.split("."),a=r.pop(),c=l=>{let u=n;for(let h of r)u=u[h];u[a]=l};return new vi(c,e,s,i,o)}function Cc(n){n.loopRemaining!==1/0&&n.loopRemaining<=1||(n.loopRemaining!==1/0&&(n.loopRemaining-=1),n.life=n.duration,n.thenCallback=()=>Cc(n),qt.push(n),n.callback(n.interp(n.duration)))}function Rc(n){if(n.loopRemaining!==1/0&&n.loopRemaining<=1)return;n.loopRemaining!==1/0&&(n.loopRemaining-=1);let t=n.start;n.start=n.end,n.end=t,n.life=n.duration,n.thenCallback=()=>Rc(n),qt.push(n),n.callback(n.interp(n.duration))}function Pc(n,t){n===void 0?(n=Ht-Ea,t=Qe-_a,Ea=Ht,_a=Qe):t===void 0&&(t=n);for(let e=qt.length;e--;){let s=qt[e];if(s.paused)continue;let i=s.useRealTime?t:n;if(!(i<=0))if(s.life-=i,s.life>0)s.callback(s.interp(s.life));else{s.callback(s.interp(0)),qt.splice(e,1);let o=s.thenCallback;s.thenCallback=void 0,o&&o()}}}function dd(){for(let n of qt)n.thenCallback=void 0;qt.length=0}var Js,Us,_l,$o,mt,Ko,Ra,Ht,Qe,ve,so,pe,Vs,Pa,dn,ro,It,Da,Ti,Ia,Re,He,re,ae,fn,pn,kn,ao,Pe,oe,q,Z,bt,is,Ws,K,X,Kt,Fa,ja,tt,at,Ba,Zo,uo,it,xt,U,Ze,et,ue,Vl,nr,Wl,Xa,Ya,ql,$a,Ka,Hl,Se,Tt,Y,W,ir,Ai,Xe,Cn,Zn,Rn,Pn,or,mn,Ye,ws,rr,B,G,Ts,Ei,_i,Ci,Ri,ar,cr,lr,ur,hr,Oe,Bt,Xs,Pi,dr,ts,un,tn,fr,le,Jn,Sn,Un,Vn,As,nn,zt,pr,es,Ys,Es,Jt,gn,gr,yr,Fe,F,ct,St,Me,We,me,De,I,en,we,Te,Ae,je,nh,rc,Zs,_e,Ft,xr,ge,vr,ti,Dn,qe,Sr,Ln,ft,Zt,H,ye,cn,io,Fn,te,bn,ei,Ls,Ie,Ue,lc,_r,uc,us,ln,jn,Sa,ni,ht,Ge,Wn,ds,si,Ke,yn,oi,fs,ps,yo,Vh,ri,Q,g,Lr,ai,ci,xn,En,Nn,Xt,mo,In,Dt,gs,wt,ss,bo,xo,Or,li,vo,ui,Dr,pc,Wh,Di,gc,Mn,an,hi,On,di,Br,bs,zs,fi,Ns,pi,xs,To,Ao,Lt,Eo,V,_o,Co,Ro,E,zr,Po,ee,gi,Lo,Oo,vs,Do,Io,Mo,ko,m,Jr,Ss,yi,Go,Fo,mi,Ut,jo,bi,Bo,No,zo,Jo,Uo,Vo,Wo,qo,Ho,Xo,xi,qt,Ea,_a,vi,Si,fd,oo,wi,Yo,Oc=jc(()=>{"use strict";Js="LittleJS",Us="1.18.19",_l=60,$o=.016666666666666666,mt=[],Ko=[],Ra=0,Ht=0,Qe=0,ve=!1;so=0,pe=0,Vs=0,Pa=!0,dn=[],ro=class{constructor(t,e,s,i){this.update=t,this.render=e,this.glContextLost=s,this.glContextRestored=i}};It=!0,Da=.5,Ti=!0,Ia="Escape",Re=!1,He=[],re=!1,ae=!1,fn=!1,pn=!1,kn=!1;q=Math.PI,Z=Math.abs,bt=Math.floor,is=Math.ceil,Ws=Math.round,K=Math.min,X=Math.max,Kt=n=>Math.sign(n),Fa=(...n)=>Math.hypot(...n),ja=n=>Math.log2(n),tt=Math.sin,at=Math.cos,Ba=Math.tan,Zo=Math.atan2;uo=class{constructor(t=123456789){f(t!==0,"RandomGenerator seed must be non-zero (xorshift is fixed at 0)"),this.seed=t}float(t=1,e=0){return this.seed^=this.seed<<13,this.seed^=this.seed>>>17,this.seed^=this.seed<<5,e+(t-e)*((this.seed>>>0)/2**32)}int(t,e=0){return bt(this.float(t,e))}bool(t=.5){return this.float().5?1:-1}floatSign(t=1,e=0){let s=K(t,e),o=X(t,e)-s,r=this.float(o*2);return rt?this.scale(t/e):this.copy()}dot(t){return this.x*t.x+this.y*t.y}cross(t){return this.x*t.y-this.y*t.x}reflect(t,e=1){return this.subtract(t.scale((1+e)*this.dot(t)))}angle(){return Zo(this.x,this.y)}setAngle(t=0,e=1){return Wt(t),Wt(e),this.x=e*tt(t),this.y=e*at(t),this}rotate(t){Wt(t);let e=at(-t),s=tt(-t);return new n(this.x*e-this.y*s,this.x*s+this.y*e)}setDirection(t,e=1){return Wt(t),Wt(e),t=Qt(t,4),f(t===0||t===1||t===2||t===3,"Vector2.setDirection() direction must be an integer between 0 and 3."),this.x=t%2?t-1?-e:e:0,this.y=t%2?0:t?-e:e,this}direction(){return Z(this.x)>Z(this.y)?this.x<0?3:1:this.y<0?2:0}abs(){return new n(Z(this.x),Z(this.y))}floor(){return new n(bt(this.x),bt(this.y))}snap(t){return Wt(t),new n(bt(this.x*t)/t,bt(this.y*t)/t)}mod(t=1){return new n(Qt(this.x,t),Qt(this.y,t))}area(){return Z(this.x*this.y)}lerp(t,e){xa(t),Wt(e);let s=j(e);return new n(t.x*s+this.x*(1-s),t.y*s+this.y*(1-s))}arrayCheck(t){return this.x>=0&&this.y>=0&&this.x(u=Qt(u,1))*6<1?c+(l-c)*6*u:u*2<1?l:u*3<2?c+(l-c)*(4-u*6):c;return this.r=a(r,o,t+1/3),this.g=a(r,o,t),this.b=a(r,o,t-1/3),this.a=i,Kn(this),this}HSLA(){let t=j(this.r),e=j(this.g),s=j(this.b),i=j(this.a),o=X(t,e,s),r=K(t,e,s),a=(o+r)/2,c=0,l=0;if(o!==r){let u=o-r;l=a>.5?u/(2-o-r):u/(o+r),t===o?c=(e-s)/u+(e((s=j(s)*255|0)<16?"0":"")+s.toString(16);return"#"+e(this.r)+e(this.g)+e(this.b)+(t?e(this.a):"")}setHex(t){if(f(J(t),"Color hex code must be a string"),f(t[0]==="#","Color hex code must start with #"),f([4,5,7,9].includes(t.length),"Invalid hex"),t.length<6){let e=s=>j(parseInt(t[s],16)/15);this.r=e(1),this.g=e(2),this.b=e(3),this.a=t.length===5?e(4):1}else{let e=s=>j(parseInt(t.slice(s,s+2),16)/255);this.r=e(1),this.g=e(3),this.b=e(5),this.a=t.length===9?e(7):1}return Kn(this),this}rgbaInt(){let t=j(this.r)*255|0,e=j(this.g)*255<<8,s=j(this.b)*255<<16,i=j(this.a)*255<<24;return t+e+s+i}isValid(){return P(this.r)&&P(this.g)&&P(this.b)&&P(this.a)}},U=Yt(N()),Ze=Yt(N(1,1,1,0)),et=Yt(N(0,0,0)),ue=Yt(N(0,0,0,0)),Vl=Yt(N(.5,.5,.5)),nr=Yt(N(1,0,0)),Wl=Yt(N(1,.5,0)),Xa=Yt(N(1,1,0)),Ya=Yt(N(0,1,0)),ql=Yt(N(0,1,1)),$a=Yt(N(0,0,1)),Ka=Yt(N(.5,0,1)),Hl=Yt(N(1,0,1)),Se=class{constructor(t,e=!1){f(t===void 0||P(t),"Constructed Timer is invalid.",t),this.useRealTime=e;let s=this.getGlobalTime();this.time=t===void 0?void 0:s+t,this.setTime=t}set(t=0){f(P(t),"Timer is invalid.",t);let e=this.getGlobalTime();this.time=e+t,this.setTime=t}setUseRealTime(t=!0){f(!this.isSet(),"Cannot change global time setting while timer is set."),this.useRealTime=t}unset(){this.time=void 0}isSet(){return this.time!==void 0}active(){return this.getGlobalTime()=this.time}get(){return this.isSet()?this.getGlobalTime()-this.time:0}getPercent(){return this.isSet()?this.setTime?1-Mt(this.time-this.getGlobalTime(),0,this.setTime):1:0}getSetTime(){return this.isSet()?this.setTime:0}getGlobalTime(){return this.useRealTime?Qe:Ht}toString(){return this.isSet()?Z(this.get())+" seconds "+(this.get()<0?"before":"after"):"unset"}valueOf(){return this.get()}};Tt=b(),Y=0,W=32,ir=1,Ai=!0,Xe=ue,Cn=b(1920,1080),Zn=0,Rn=0,Pn=b(),or=!1,mn=!0,Ye=1,ws="arial",rr=!1,B=!1,G=!0,Ts=32,Ei=b(16),_i=0,Ci=0,Ri=!0,ar=1,cr=1,lr=1,ur=0,hr=.8,Oe=1,Bt=b(),Xs=1,Pi=!0,dr=!0,ts=!0,un=!0,tn=!1,fr=!1,le=0,Jn=4,Sn=!0,Un=0,Vn=!1,As=!0,nn=!1,zt=100,pr=.3,es=3,Ys=0,Es=!0,Jt=!0,gn=.3,gr=40,yr=.7;Fe=class n{constructor(t=b(),e=b(1),s,i=0,o=U,r=0){f(L(t),"object pos must be a vec2"),f(L(e),"object size must be a vec2"),f(!s||s instanceof Ae,"object tileInfo should be a TileInfo or undefined"),f(typeof i=="number"&&isFinite(i),"object angle should be a number"),f(z(o),"object color should be a valid rgba color"),f(typeof r=="number","object renderOrder should be a number"),this.pos=t.copy(),this.size=e.copy(),this.drawSize=void 0,this.tileInfo=s,this.angle=i,this.color=o.copy(),this.additiveColor=void 0,this.mirror=!1,this.destroyed=!1,this.mass=ar,this.damping=cr,this.angleDamping=lr,this.restitution=ur,this.friction=hr,this.gravityScale=1,this.renderOrder=r,this.velocity=b(),this.angleVelocity=0,this.spawnTime=Ht,this.children=[],this.clampSpeed=!0,this.groundObject=void 0,this.parent=void 0,this.localPos=b(),this.localAngle=0,this.collideTiles=!1,this.collideSolidObjects=!1,this.isSolid=!1,this.collideRaycast=!1,mt.push(this)}updateTransforms(){let t=this.parent;if(t){let e=t.getMirrorSign(),s=this.localPos,i=t.pos,o=s.x*e,r=s.y,a=t.angle;if(a){let c=at(-a),l=tt(-a);this.pos.set(o*c-r*l+i.x,o*l+r*c+i.y)}else this.pos.set(o+i.x,r+i.y);this.angle=e*this.localAngle+a}for(let e of this.children)e.updateTransforms()}updatePhysics(){if(f(!this.parent),this.destroyed)return;this.clampSpeed&&(this.velocity.x=j(this.velocity.x,-Oe,Oe),this.velocity.y=j(this.velocity.y,-Oe,Oe));let t=this.pos.copy();if(this.velocity.x*=this.damping,this.velocity.y*=this.damping,this.mass&&(this.velocity.x+=Bt.x*this.gravityScale,this.velocity.y+=Bt.y*this.gravityScale),this.pos.x+=this.velocity.x,this.pos.y+=this.velocity.y,this.angle+=this.angleVelocity*=this.angleDamping,f(this.angleDamping>=0&&this.angleDamping<=1),f(this.damping>=0&&this.damping<=1),!Ri||!this.mass)return;let e=this.velocity.y<0&&Bt.y<0||this.velocity.y>0&&Bt.y>0;if(this.groundObject){let s=X(this.friction,this.groundObject.friction),i=this.groundObject.velocity.x;this.velocity.x=i+(this.velocity.x-i)*s,this.groundObject=void 0}if(this.collideSolidObjects)for(let i of Ko){if(i.destroyed||i.parent||i===this||!this.isSolid&&!i.isSolid||!this.isOverlappingObject(i))continue;let o=this.collideWithObject(i),r=i.collideWithObject(this);if(!o||!r)continue;if(Hs(t,this.size,i.pos,i.size)){let p=t.subtract(i.pos),d=p.length(),x=d<.001?b(0,1):p.scale(.001/d);this.velocity=this.velocity.add(x),i.mass&&(i.velocity=i.velocity.subtract(x)),re&&co(this.pos,this.size,i.pos,i.size,"#f00");continue}let a=this.size.add(i.size),c=(t.y-i.pos.y)*2>a.y+Bt.y,l=Z(t.y-i.pos.y)*20?-1:1)>0?bt(t.y-this.size.y/2+1)+this.size.y/2+.001:is(t.y+this.size.y/2-1)-this.size.y/2-.001;if(Z(u-this.pos.y)<.1&&!Ve(b(this.pos.x,u),this.size,this)){this.pos.y=u,re&&pt(this.pos,this.size,"#ff0");return}this.pos.x=t.x,this.velocity.x*=-r}if(o||!i){if(e){let c=this.size.y/2+1e-4;this.pos.y=Bt.y<0?bt(t.y-this.size.y/2)+c:is(t.y+this.size.y/2)-c,this.groundObject=s}else this.pos.y=t.y,this.groundObject=void 0;this.velocity.y*=-r}re&&pt(this.pos,this.size,"#f00")}}}update(){}render(){Rt(this.pos,this.drawSize||this.size,this.tileInfo,this.color,this.angle,this.mirror,this.additiveColor)}renderLight(){}destroy(t=!1){var e;if(!this.destroyed){this.destroyed=!0,(e=this.parent)==null||e.removeChild(this);for(let s of this.children)s.parent=void 0,s.destroy(t)}}localToWorld(t){return this.pos.add(t.rotate(this.angle))}worldToLocal(t){return t.subtract(this.pos).rotate(-this.angle)}localToWorldVector(t){return t.rotate(this.angle)}worldToLocalVector(t){return t.rotate(-this.angle)}collideWithTile(t,e){return t>0}collideWithObject(t){return!0}getUp(t=1){return b().setAngle(this.angle,t)}getRight(t=1){return b().setAngle(this.angle+q/2,t)}getAliveTime(){return Ht-this.spawnTime}getSpeed(){return this.velocity.length()}applyAcceleration(t){this.mass&&(this.velocity=this.velocity.add(t))}applyAngularAcceleration(t){this.mass&&(this.angleVelocity+=t)}applyForce(t){this.mass&&this.applyAcceleration(t.scale(1/this.mass))}getMirrorSign(){return this.mirror?-1:1}addChild(t,e=b(),s=0){return f(!this.destroyed,"cannot add child to destroyed object"),this.destroyed||(f(!t.parent&&!this.children.includes(t)),f(t instanceof n,"child must be an EngineObject"),f(t!==this,"cannot add self as child"),this.children.push(t),t.parent=this,t.localPos=e.copy(),t.localAngle=s,t.updateTransforms()),t}removeChild(t){f(t.parent===this&&this.children.includes(t)),this.children.splice(this.children.indexOf(t),1),t.parent=void 0}isOverlappingObject(t){return this.isOverlapping(t.pos,t.size)}isOverlapping(t,e=b()){return Hs(this.pos,this.size,t,e)}setCollision(t=!0,e=!0,s=!0,i=!0){f(t||!e,"solid objects must be set to collide"),this.collideSolidObjects=t,this.isSolid=e,this.collideTiles=s,this.collideRaycast=i}toString(){let t="type = "+this.constructor.name;return(this.pos.x||this.pos.y)&&(t+=`
 pos = `+this.pos),(this.velocity.x||this.velocity.y)&&(t+=`
 velocity = `+this.velocity),(this.size.x||this.size.y)&&(t+=`
 size = `+this.size),this.angle&&(t+=`
 angle = `+this.angle.toFixed(3)),this.color&&(t+=`
-color = `+this.color),t}renderDebugInfo(){if(!It)return;let t=this.collideTiles||this.collideSolidObjects||this.isSolid;if(!t&&!this.parent)return;let e=x(X(this.size.x,.2),X(this.size.y,.2)),s=B(this.collideTiles?1:0,this.collideSolidObjects?1:0,this.isSolid?1:0,.5);mt(this.pos,e,s,0,this.angle,t),this.parent&&mt(this.pos,e.scale(.8),B(1,1,1,.5),0,this.angle),this.parent&&xe(this.pos,this.parent.pos,B(1,1,1,.5),.5)}},D=x(),nn=[];Ce=class n{constructor(t=x(),e=Ci,s=nn[0],i=Ei,o=_i){this.pos=t.copy(),this.size=e.copy(),this.padding=i,this.textureInfo=s,this.bleed=o}offset(t){return new n(this.pos.add(t),this.size,this.textureInfo,this.padding,this.bleed)}frame(t){f(typeof t=="number");let e=this.size.x+this.padding*2,s=t*e;return f(s+this.size.x<=this.textureInfo.size.x,"frame extends beyond texture width!"),this.offset(new st(s))}setFullImage(t=this.textureInfo){return this.textureInfo=t,this.pos=new st,this.size=t.size.copy(),this.bleed=this.padding=0,this}tile(t){return Es(t,this.size,this.textureInfo,this.padding,this.bleed)}},Ne=class{constructor(t,e=!0,s=!1){this.image=t,this.size=t?x(t.width,t.height):x(),this.sizeInverse=t?x(1/t.width,1/t.height):x(),this.glTexture=void 0,this.wrap=s,e&&this.createWebGLTexture()}createWebGLTexture(){Hh(this)}destroyWebGLTexture(){Xh(this)}hasWebGL(){return!!this.glTexture}setWrap(t=!0){this.wrap=t,bc(this.glTexture,t)}};nh=0;Zs=class{constructor(t){f(!!t,"tileInfo is required for ImageFont"),this.tileInfo=t.frame(0)}drawText(t,e,s=1,i,o,r,a){f(L(s)||typeof s=="number","size must be a vec2 or number"),typeof s=="number"?(f(s>0),s*=W,s=new st(s,s)):s=s.scale(W),this.drawTextScreen(t,Sn(e),s,i,o,r,a)}drawTextScreen(t,e,s,i=!0,o=U,r=k,a){f(J(t),"text must be a string"),f(L(e),"pos must be a vec2"),f(L(s)||typeof s=="number","size must be a vec2 or number"),f(z(o),"color must be a color"),s=typeof s=="number"?new st(s,s):s;let c=new st,l=this.tileInfo,u=l.padding,h=l.size.x+u*2,p=l.size.y+u*2,d=l.textureInfo.size.x/h|0;(t+"").split(`
-`).forEach((y,b)=>{let v=i?(y.length-1)*s.x/2:0;for(let S=y.length;S--;){let _=y.charCodeAt(S),w=_<32||_>127?95:_-32,E=w%d,A=w/d|0;l.pos.x=E*h+u,l.pos.y=A*p+u,c.x=e.x+S*s.x-v|0,c.y=e.y+b*s.y|0,_t(c,s,l,o,0,!1,void 0,r,!0,a)}})}};_e=x(),jt=x(),xr=x(),ye=x(),vr=0,ti=!0,In=!1,He="mouse",Sr=6,On=!0,yt=0,ee=!j&&window.ontouchstart!==void 0;H=[[]],me=[],rn=[],io=[],jn=new we,ne=[],yn=[],ei=[],Ls=[],Me=new Map,us=[],Nn=!0;ni="http://www.w3.org/2000/svg";ft=new AudioContext,qn=44100;ds=class{constructor(t,e,s=gr,i=yr,o){var r;if(!(!Ut||j)){if(f(!t||ce(t)||J(t),"asset must be a file name or zzfx array"),f(e===void 0||P(e),"randomness must be a number"),f(e===void 0||e>=0&&e<=1,"randomness must be between 0 and 1"),f(P(s),"range must be a number"),f(P(i),"taper must be a number"),this.range=s,this.taper=i,this.randomness=e!=null?e:0,this.sampleRate=qn,this.loadedPercent=0,this.onloadCallback=o,ce(t)){let a=t.slice(),c=e!=null?e:.05,l=1;this.randomness=(r=a[l])!=null?r:c,a[l]=0,this.sampleChannels=[Oi(...a)],this.loadedPercent=1,o==null||o(this)}else if(typeof t=="string"){let a=t;this.loadSound(a)}}}play(t,e=1,s=1,i=1,o=!1,r=!1){if(f(!t||L(t),"pos must be a vec2"),f(P(e),"volume must be a number"),f(P(s),"pitch must be a number"),f(P(i),"randomnessScale must be a number"),!Ut||j||!this.sampleChannels)return;let a;if(t){let u=this.range;if(u){let h=At.distanceSquared(t);if(h>u*u)return;e*=Mt(h**.5,u,u*this.taper)}a=Sn(t).x*2/G.width-1}let c=s+s*this.randomness*i*dt(-1,1),l=new si(this,e,c,a,o,r);return It&&Gn&&t&&(Nt(t,.5,"#0ff",.5,!0),this.range&&(Nt(t,2*this.range,"#0ff",.5),Nt(t,2*this.range*this.taper,"#0ff",.5)),_n("vol "+e.toFixed(2)+" pitch "+c.toFixed(2),t,.5,"#0ff",.5)),l}playMusic(t=1,e=!0,s=!1){return this.play(void 0,t,1,0,e,s)}playNote(t=0,e,s){f(P(t),"semitoneOffset must be a number");let i=dc(t,1);return this.play(e,s,i,0)}getDuration(){var t,e;return((e=(t=this.sampleChannels)==null?void 0:t[0])==null?void 0:e.length)/this.sampleRate||0}isLoaded(){return this.loadedPercent===1}async loadSound(t){var c;let e=await fetch(t);if(!e.ok)throw new Error(`Failed to load sound from ${t}: ${e.status} ${e.statusText}`);let s=await e.arrayBuffer(),i=await ft.decodeAudioData(s),o=i.numberOfChannels,r=1e5,a=[];for(let l=0;lsetTimeout(v,0));let d=K(p+r,h);for(;p=0,"Sound volume must be positive or zero"),f(s>=0,"Sound rate must be positive or zero"),f(P(i),"Sound pan must be a number"),this.sound=t,this.volume=e,this.rate=s,this.pan=i,this.loop=o,this.pausedTime=0,this.startTime=void 0,this.gainNode=void 0,this.source=void 0,this.onendedCallback=a=>{a===this.source&&(this.source=void 0)},r||this.start()}start(t=0){f(t>=0,"Sound start offset must be positive or zero"),this.isPlaying()&&this.stop(),this.gainNode=ft.createGain(),this.source=Pr(this.sound.sampleChannels,this.volume,this.rate,this.pan,this.loop,this.sound.sampleRate,this.gainNode,t,this.onendedCallback),this.source?(this.startTime=ft.currentTime-t,this.pausedTime=void 0):(this.startTime=void 0,this.pausedTime=0)}setVolume(t){f(t>=0,"Sound volume must be positive or zero"),this.volume=t,this.gainNode&&(this.gainNode.gain.value=t)}stop(t=0){if(f(t>=0,"Sound fade time must be positive or zero"),this.isPlaying())if(t){let e=ft.currentTime,s=e+t;this.gainNode.gain.cancelScheduledValues(e),this.gainNode.gain.setValueAtTime(this.volume,e),this.gainNode.gain.linearRampToValueAtTime(0,s),this.source.stop(s)}else this.source.stop();this.pausedTime=0,this.source=void 0,this.startTime=void 0}pause(){this.isPaused()||(this.pausedTime=this.getCurrentTime(),this.source.stop(),this.source=void 0,this.startTime=void 0)}resume(){this.isPaused()&&this.start(this.pausedTime)}isPlaying(){return!!this.source}isPaused(){return!this.isPlaying()}getCurrentTime(){if(!this.isPlaying())return this.pausedTime;let t=this.getDuration();return t?te(ft.currentTime-this.startTime,t):0}getDuration(){return this.rate?this.sound.getDuration()/this.rate:0}getSource(){return this.source}};Qe=[];pn=class{constructor(t,e=0,s=!1,i=new St){this.tile=t,this.direction=e,this.mirror=s,this.color=i.copy()}clear(){this.tile=this.direction=0,this.mirror=!1,this.color=new St}},oi=class extends je{constructor(t,e,s=0,i=0,o=x(512),r=!0){var a;f(L(o),"canvasSize must be a Vector2"),super(t,e,void 0,s,U,i),this.canvas=j?void 0:new OffscreenCanvas(o.x,o.y),this.context=(a=this.canvas)==null?void 0:a.getContext("2d"),this.textureInfo=new Ne(this.canvas,r),this.mass=0}destroy(){this.destroyed||(this.textureInfo.destroyWebGLTexture(),super.destroy())}render(){this.draw(this.pos,this.size,this.color,this.angle,this.mirror,this.additiveColor)}draw(t,e,s=U,i=0,o=!1,r,a=!1,c){let l=new Ce().setFullImage(this.textureInfo),u=this.hasWebGL();_t(t,e,l,s,i,o,r,u,a,c)}updateWebGL(){this.textureInfo.createWebGLTexture()}hasWebGL(){return k&&this.textureInfo.hasWebGL()}},fs=class extends oi{constructor(t,e,s=Es(),i=0,o=!0){let r=s?e.multiply(s.size):e;if(super(t,e,0,i,r,o),this.tileInfo=void 0,this.data=[],this.isUsingWebGL=!1,j){this.render=()=>{},this.redraw=()=>{},this.redrawStart=()=>{},this.redrawEnd=()=>{},this.drawTileData=()=>{},this.redrawTileData=()=>{},this.drawLayerTile=()=>{},this.drawLayerRect=()=>{},this.drawTile=()=>{},this.drawRect=()=>{},this.clearLayerRect=()=>{};return}s&&(this.tileInfo=s.frame(0),this.tileInfo.bleed=0);for(let a=this.size.area();a--;)this.data.push(new pn)}setData(t,e,s=!1){if(t=t.floor(),f(L(t),"layerPos must be a Vector2"),f(e instanceof pn,"data must be a TileLayerData"),!t.arrayCheck(this.size)||(this.data[(t.y|0)*this.size.x+(t.x|0)]=e,!s))return;wt===this.context?this.drawTileData(t):this.redrawTileData(t)}clearData(t,e=!1){this.setData(t,new pn,e)}getData(t){return f(L(t),"layerPos must be a Vector2"),t.arrayCheck(this.size)?this.data[(t.y|0)*this.size.x+(t.x|0)]:void 0}update(){!k&&this.isUsingWebGL&&(this.isUsingWebGL=!1,this.redraw())}render(){f(wt!==this.context,"must call redrawEnd() after drawing tiles!");let t=this.drawSize||this.size,e=this.pos.add(t.scale(.5));this.draw(e,this.size,this.color,this.angle,this.mirror,this.additiveColor)}onRedraw(){}redraw(){this.redrawStart(!0);for(let t=this.size.x;t--;)for(let e=this.size.y;e--;)this.drawTileData(x(t,e),!1);this.isUsingWebGL&&Ct(),this.onRedraw(),this.redrawEnd()}redrawStart(t=!1){var s,i;if(!this.context)return;f(wt!==this.context),this.savedRenderSettings=[wt,D,At,W,Ye],wt=this.context;let e=(i=(s=this.tileInfo)==null?void 0:s.size)!=null?i:x(1);D=this.size.multiply(e),Ye=ue,At=this.size.multiply(e).scale(.5),W=1,this.isUsingWebGL=this.hasWebGL(),this.isUsingWebGL?Qn(this.textureInfo.glTexture,t):(this.context.imageSmoothingEnabled=!gn,t&&(this.canvas.width=D.x,this.canvas.height=D.y))}redrawEnd(){this.context&&(f(wt===this.context),this.isUsingWebGL&&Qn(),[wt,D,At,W,Ye]=this.savedRenderSettings)}drawTileData(t,e=!0){var a,c;if(!this.context)return;f(wt===this.context,"must call redrawStart() before drawing tiles");let s=(c=(a=this.tileInfo)==null?void 0:a.size)!=null?c:x(1),i=t.multiply(s);e&&this.clearLayerRect(i,s);let o=this.getData(t);if(!o||!o.tile)return;let r=this.tileInfo&&this.tileInfo.tile(o.tile);this.drawLayerTile(i,s,r,o.color,o.direction*q/2,o.mirror)}redrawTileData(t,e=!0){this.context&&(f(wt!==this.context,"redrawStart() should not be active when calling redrawTileData(), instead use drawTileData()"),this.redrawStart(),this.drawTileData(t,e),this.redrawEnd())}drawLayerTile(t,e=x(1),s,i=U,o=0,r,a){let c=t.add(e.scale(.5));_t(c,e,s,i,o,r,a,this.isUsingWebGL)}drawLayerRect(t,e,s,i=0){this.drawLayerTile(t,e,void 0,s,i)}drawTile(t,e=x(1),s,i=new St,o=0,r=!1){t=t.subtract(this.pos).multiply(this.tileInfo.size),e=e.multiply(this.tileInfo.size),t.y=this.canvas.height-t.y;let a=D;D=x(this.canvas.width,this.canvas.height);let c=this.hasWebGL();c&&Qn(this.textureInfo.glTexture);let l=c?void 0:this.context;_t(t,e,s,i,o,r,void 0,c,!0,l),c&&Qn(),D=a}drawRect(t,e,s,i){this.drawTile(t,e,void 0,s,i)}clearLayerRect(t,e){f(wt===this.context,"must call redrawStart() before clearing tiles");let s=t.x,i=this.canvas.height-t.y-e.y;this.hasWebGL()?wc(s,i,e.x,e.y):this.context.clearRect(s,i,e.x,e.y)}},ps=class extends fs{constructor(t,e,s=Es(),i=0,o=!0){super(t,e.floor(),s,i,o),this.collisionData=[],this.initCollision(this.size),Qe.push(this),this.isSolid=!0}destroy(){if(this.destroyed)return;let t=Qe.indexOf(this);f(t>=0,"tile collision layer not found in array"),t>=0&&Qe.splice(t,1),super.destroy()}initCollision(t){f(L(t),"size must be a Vector2"),this.size=t.floor(),this.collisionData=[],this.collisionData.length=t.area(),this.collisionData.fill(0)}setCollisionData(t,e=1){f(L(t),"layerPos must be a Vector2");let s=(t.y|0)*this.size.x+(t.x|0);t.arrayCheck(this.size)&&(this.collisionData[s]=e)}clearCollisionData(t){this.setCollisionData(t,0)}getCollisionData(t){f(L(t),"layerPos must be a Vector2");let e=(t.y|0)*this.size.x+(t.x|0);return t.arrayCheck(this.size)?this.collisionData[e]:0}collisionTest(t,e=new st,s){f(L(t)&&L(e),"pos and size must be Vector2s"),f(!s||typeof s=="function"||s instanceof je,"callbackObject must be a function or EngineObject");let i=s?typeof s=="function"?(p,d)=>s(p,d):(p,d)=>s.collideWithTile(p,d):()=>!0,o=t.x-this.pos.x,r=t.y-this.pos.y;if(o+e.x/2<0||o-e.x/2>this.size.x||r+e.y/2<0||r-e.y/2>this.size.y)return!1;let a=X(o-e.x/2|0,0),c=X(r-e.y/2|0,0),l=K(X(o+e.x/2,a+1),this.size.x),u=K(X(r+e.y/2,c+1),this.size.y),h=new st;for(let p=c;ps(l,u):(l,u)=>s.collideWithTile(l,u):l=>l>0,r=l=>{let u=this.getCollisionData(a.set(l.x-this.pos.x,l.y-this.pos.y));return u&&o(u,l)},a=new st,c=Ua(t,e,r,i);if(ae&&c){let l=c.floor().add(x(.5));mt(l,x(1),"#f008"),xe(t,e,"#00f",.02),xe(t,c,"#f00",.02),Qo(c,"#0f0"),i&&xe(c,c.add(i),"#ff0",.02)}return c}},yo=class extends je{constructor(t,e,s=0,i=0,o=100,r=q,a,c=U,l=U,u=tn,h=tn,p=.5,d=.1,y=1,b=.1,v=.05,S=1,_=1,w=0,E=q,A=.1,T=.2,R=!1,M=!1,ct=!0,et=M?1e9:0,lt=!1){super(t,x(),a,e,void 0,et),this.emitCircle=typeof s=="number",this.emitSize=typeof s=="number"?x(s):s.copy(),this.emitTime=i,this.emitRate=o,this.emitConeAngle=r,this.colorStartA=c.copy(),this.colorStartB=l.copy(),this.colorEndA=u.copy(),this.colorEndB=h.copy(),this.randomColorLinear=ct,this.particleTime=p,this.sizeStart=d,this.sizeEnd=y,this.speed=b,this.angleSpeed=v,this.damping=S,this.angleDamping=_,this.gravityScale=w,this.particleConeAngle=E,this.fadeRate=A,this.randomness=T,this.collideTiles=R,this.additive=M,this.localSpace=lt,this.trailScale=0,this.particleCreateCallback=void 0,this.particleDestroyCallback=void 0,this.particleCollideCallback=void 0,this.velocityInheritance=0,this.emitTimeBuffer=0,this.particles=[],this.previousAngle=this.angle,this.previousPos=this.pos.copy()}update(){if(f(this.angleDamping>=0&&this.angleDamping<=1),f(this.damping>=0&&this.damping<=1),this.velocityInheritance){let s=this.velocityInheritance;this.velocity.x=s*(this.pos.x-this.previousPos.x),this.velocity.y=s*(this.pos.y-this.previousPos.y),this.angleVelocity=s*(this.angle-this.previousAngle),this.previousAngle=this.angle,this.previousPos.x=this.pos.x,this.previousPos.y=this.pos.y}if(this.isActive()){if(this.emitRate&&Xs){let s=1/this.emitRate/Xs;for(this.emitTimeBuffer+=$o;this.emitTimeBuffer>0;this.emitTimeBuffer-=s)this.emitParticle()}}else this.particles.length===0&&this.destroy(!0);let t=this.particles,e=0;for(let s=0;s_+_*dt(s,-s),o=i(this.particleTime),r=i(this.sizeStart),a=i(this.sizeEnd),c=i(this.speed),l=i(this.angleSpeed)*Wa(),u=dt(this.emitConeAngle,-this.emitConeAngle),h=lo(this.colorStartA,this.colorStartB,this.randomColorLinear),p=lo(this.colorEndA,this.colorEndB,this.randomColorLinear),d=this.localSpace?u:this.angle+u,y=x(c*tt(d),c*ot(d)),b=l;!this.localSpace&&this.velocityInheritance>0&&(y.x+=this.velocity.x,y.y+=this.velocity.y,b+=this.angleVelocity);let v=new ri(this,t,e,h,p,o,r,a,y,b);return this.particles.push(v),(S=this.particleCreateCallback)==null||S.call(this,v),v}updatePhysics(){}render(){for(let t of this.particles)t.render()}isActive(){return!this.emitTime||this.getAliveTime()0&&(this.destroyed=!1,this.emitTime=-1))}},Vh=new st,ri=class{constructor(t,e,s,i,o,r,a,c,l=x(),u=0){this.emitter=t,this.pos=e,this.angle=s,this.size=x(a),this.color=i.copy(),this.colorStart=i,this.colorEnd=o,this.lifeTime=r,this.sizeStart=a,this.sizeEnd=c,this.velocity=l,this.angleVelocity=u,this.spawnTime=Ht,this.mirror=Va(),this.groundObject=void 0,this.destroyed=!1,this.tileInfo=t.tileInfo}update(){let t=this.emitter,e=t.damping,s=t.angleDamping,i=t.restitution,o=t.friction,r=t.gravityScale,a=t.collideTiles,c=t.particleCollideCallback;if(this.lifeTime>0&&Ht-this.spawnTime>this.lifeTime){this.destroy();return}let l=this.pos.copy();if(this.velocity.x*=e,this.velocity.y*=e,this.pos.x+=this.velocity.x+=Bt.x*r,this.pos.y+=this.velocity.y+=Bt.y*r,this.angle+=this.angleVelocity*=s,!Ri||!a)return;let u=this.velocity.lengthSquared();if(u>De*De){let p=De/u**.5;this.velocity.x*=p,this.velocity.y*=p}this.groundObject=void 0;let h=c?p=>{let d=ii(p);return d&&c(this,d,p)}:p=>ii(p)>0;if(h(this.pos)){let p=We(this.pos);if(!h(l)){let d=h(x(this.pos.x,l.y)),y=h(x(l.x,this.pos.y)),b=X(i,p.restitution),v=X(o,p.friction);d&&(this.pos.x=l.x,this.velocity.x*=-b,this.velocity.y*=v),(y||!d)&&((this.velocity.y<0&&Bt.y<0||this.velocity.y>0&&Bt.y>0)&&(this.groundObject=p),this.pos.y=l.y,this.velocity.y*=-b,this.velocity.x*=v),re&&mt(this.pos,this.size,"#f00")}}}destroy(){let t=this.emitter.particleDestroyCallback,e=this.colorEnd;this.color.set(e.r,e.g,e.b,e.a),this.size.set(this.sizeEnd,this.sizeEnd),this.destroyed=!0,t==null||t(this)}render(){let t=this.emitter,e=t.localSpace,s=t.additive,i=t.trailScale,o=t.fadeRate/2,r=this.lifeTime>0?K((Ht-this.spawnTime)/this.lifeTime,1):1,a=1-r,c=a*this.sizeStart+r*this.sizeEnd,l=x(c),u=r1-o?(1-r)/o:1;this.color.r=a*this.colorStart.r+r*this.colorEnd.r,this.color.g=a*this.colorStart.g+r*this.colorEnd.g,this.color.b=a*this.colorStart.b+r*this.colorEnd.b,this.color.a=(a*this.colorStart.a+r*this.colorEnd.a)*u;let h=Vh.set(this.pos.x,this.pos.y),p=this.angle;if(e){let d=t.angle,y=ot(-d),b=tt(-d);h.set(t.pos.x+h.x*y-h.y*b,t.pos.y+h.x*b+h.y*y),p+=d}if(s&&as(),i){let d=e?this.velocity.rotate(t.angle):this.velocity,y=d.length();if(y){let b=y*i;l.y=X(l.x,b),p=Zo(d.x,d.y),_t(h,l,this.tileInfo,this.color,p,this.mirror)}}else _t(h,l,this.tileInfo,this.color,p,this.mirror);s&&as(!1),hn&&mt(h,l,"#f005",0,p)}},Lr=!0,vo=!0,ui=5e5,Dr=11,pc=Dr*4,Wh=ui/pc|0,Di=3,gc=Di*4,kn=ui/gc|0;on=!1,hi=5,Dn=.5,di=x(640,80),Nr=!1,bs={},zs=[];pi=class{constructor(t,e,s="",i="\u{1F3C6}",o){f(t>=0&&!bs[t]),this.id=t,this.name=e,this.description=s,this.icon=i,this.unlocked=!1,this.image=void 0,o&&((this.image=new Image).src=o),bs[t]=this}unlock(){Nr||this.unlocked||(f(fi,"save name must be set"),this.unlocked=!0,Br(),zs.push(this))}render(t=0){let e=at,s=K(di.x,G.width),i=di.y,o=G.width-s,r=-i*t,a=Oe(0,0,.9);e.save(),e.beginPath(),e.fillStyle=a.toString(),e.strokeStyle=nt.toString(),e.lineWidth=3,e.rect(o,r,s,i),e.fill(),e.stroke(),e.clip();let c=x(.1,.05).scale(i),l=i-2*c.x;this.renderIcon(x(o+c.x+l/2,r+i/2),l);let u=i*.5,h=i*.3,p=x(o+l+2*c.x,r+c.y*2+u/2),d=s-l-3*c.x;Ke(this.name,p,u,nt,0,void 0,"left",void 0,void 0,d),p.y=r+i-c.y*2-h/2,Ke(this.description,p,h,nt,0,void 0,"left",void 0,void 0,d),e.restore()}renderIcon(t,e){this.image?at.drawImage(this.image,t.x-e/2,t.y-e/2,e,e):Ke(this.icon,t,e*.7,nt)}};To=class extends pi{constructor(t,e,s,i,o){super(t,e,s,i,o)}unlock(){super.unlock(),xs&&xs.unlockMedal(this.id)}},Ao=class{constructor(t,e,s){var c,l,u;f(!xs,"there can only be one newgrounds object"),f(!e||s,"must provide cryptojs if there is a cipher"),xs=this,this.app_id=t,this.cipher=e,this.cryptoJS=s,this.host=location?location.hostname:"";let i=new URL(location.href);if(this.session_id=i.searchParams.get("ngio_session_id"),!this.session_id)return;let o=this.call("Medal.getList");if(!o||!o.result||o.result.error){on&&bt("Newgrounds session unavailable; skipping plugin init"),this.medals=[],this.scoreboards=[];return}this.medals=((c=o.result.data)==null?void 0:c.medals)||[],on&&bt(this.medals);for(let h of this.medals){let p=bs[h.id];p&&(p.image=new Image,p.image.src=h.icon,p.name=h.name,p.description=h.description,p.unlocked=h.unlocked,p.difficulty=h.difficulty,p.value=h.value,p.value&&(p.description=p.description+` (${p.value})`))}let r=this.call("ScoreBoard.getBoards");this.scoreboards=((u=(l=r==null?void 0:r.result)==null?void 0:l.data)==null?void 0:u.scoreboards)||[],on&&bt(this.scoreboards);let a=60*1e3;setInterval(()=>this.call("Gateway.ping",0,!0),a)}unlockMedal(t){return this.call("Medal.unlock",{id:t},!0)}postScore(t,e){return this.call("ScoreBoard.postScore",{id:t,value:e},!0)}getScores(t,e,s=0,i=0,o=10){return this.call("ScoreBoard.getScores",{id:t,user:e,social:s,skip:i,limit:o})}logView(){return this.call("App.logView",{host:this.host},!0)}call(t,e,s=!1){let i={component:t,parameters:e};if(this.cipher){let l=this.cryptoJS,u=l.enc.Base64.parse(this.cipher),h=l.lib.WordArray.random(16),p=l.AES.encrypt(JSON.stringify(i),u,{iv:h});i.secure=l.enc.Base64.stringify(h.concat(p.ciphertext)),i.parameters=0}let o={app_id:this.app_id,session_id:this.session_id,call:i},r=new FormData;r.append("input",JSON.stringify(o));let a=new XMLHttpRequest;a.open("POST","https://newgrounds.io/gateway_v3.php",!on&&s);try{a.send(r)}catch(l){on&&bt("newgrounds call failed",l);return}return on&&bt(a.responseText),a.responseText&&JSON.parse(a.responseText)}},Co=class{constructor(t,e=!1,s=!1){f(!Lt,"Post process already initialized"),f(!(e&&s),"Post process cannot both include main canvas and use feedback texture"),Lt=this,t||(t="void mainImage(out vec4 c,vec2 p){c=texture(iChannel0,p/iResolution.xy);}"),this.shader=void 0,this.texture=void 0,this.vao=void 0,i(),bn(void 0,a,o,r);function i(){if(j)return;if(!k){console.warn("PostProcessPlugin: WebGL not enabled!");return}Lt.texture=Ii(),Lt.shader=Jn(`#version 300 es
+color = `+this.color),t}renderDebugInfo(){if(!It)return;let t=this.collideTiles||this.collideSolidObjects||this.isSolid;if(!t&&!this.parent)return;let e=b(X(this.size.x,.2),X(this.size.y,.2)),s=N(this.collideTiles?1:0,this.collideSolidObjects?1:0,this.isSolid?1:0,.5);pt(this.pos,e,s,0,this.angle,t),this.parent&&pt(this.pos,e.scale(.8),N(1,1,1,.5),0,this.angle),this.parent&&be(this.pos,this.parent.pos,N(1,1,1,.5),.5)}},I=b(),en=[];Ae=class n{constructor(t=b(),e=Ei,s=en[0],i=_i,o=Ci){this.pos=t.copy(),this.size=e.copy(),this.padding=i,this.textureInfo=s,this.bleed=o}offset(t){return new n(this.pos.add(t),this.size,this.textureInfo,this.padding,this.bleed)}frame(t){f(typeof t=="number");let e=this.size.x+this.padding*2,s=t*e;return f(s+this.size.x<=this.textureInfo.size.x,"frame extends beyond texture width!"),this.offset(new it(s))}setFullImage(t=this.textureInfo){return this.textureInfo=t,this.pos=new it,this.size=t.size.copy(),this.bleed=this.padding=0,this}tile(t){return _s(t,this.size,this.textureInfo,this.padding,this.bleed)}},je=class{constructor(t,e=!0,s=!1){this.image=t,this.size=t?b(t.width,t.height):b(),this.sizeInverse=t?b(1/t.width,1/t.height):b(),this.glTexture=void 0,this.wrap=s,e&&this.createWebGLTexture()}createWebGLTexture(){Hh(this)}destroyWebGLTexture(){Xh(this)}hasWebGL(){return!!this.glTexture}setWrap(t=!0){this.wrap=t,bc(this.glTexture,t)}};nh=0;Zs=class{constructor(t){f(!!t,"tileInfo is required for ImageFont"),this.tileInfo=t.frame(0)}drawText(t,e,s=1,i,o,r,a){f(L(s)||typeof s=="number","size must be a vec2 or number"),typeof s=="number"?(f(s>0),s*=W,s=new it(s,s)):s=s.scale(W),this.drawTextScreen(t,Tn(e),s,i,o,r,a)}drawTextScreen(t,e,s,i=!0,o=U,r=G,a){f(J(t),"text must be a string"),f(L(e),"pos must be a vec2"),f(L(s)||typeof s=="number","size must be a vec2 or number"),f(z(o),"color must be a color"),s=typeof s=="number"?new it(s,s):s;let c=new it,l=this.tileInfo,u=l.padding,h=l.size.x+u*2,p=l.size.y+u*2,d=l.textureInfo.size.x/h|0;(t+"").split(`
+`).forEach((y,x)=>{let v=i?(y.length-1)*s.x/2:0;for(let T=y.length;T--;){let C=y.charCodeAt(T),w=C<32||C>127?95:C-32,_=w%d,A=w/d|0;l.pos.x=_*h+u,l.pos.y=A*p+u,c.x=e.x+T*s.x-v|0,c.y=e.y+x*s.y|0,Rt(c,s,l,o,0,!1,void 0,r,!0,a)}})}};_e=b(),Ft=b(),xr=b(),ge=b(),vr=0,ti=!0,Dn=!1,qe="mouse",Sr=6,Ln=!0,ft=0,Zt=!B&&window.ontouchstart!==void 0;H=[[]],ye=[],cn=[],io=[],Fn=new Se,te=[],bn=[],ei=[],Ls=[],Ie=new Map,us=[],jn=!0;ni="http://www.w3.org/2000/svg";ht=new AudioContext,Wn=44100;ds=class{constructor(t,e,s=gr,i=yr,o){var r;if(!(!Jt||B)){if(f(!t||ce(t)||J(t),"asset must be a file name or zzfx array"),f(e===void 0||P(e),"randomness must be a number"),f(e===void 0||e>=0&&e<=1,"randomness must be between 0 and 1"),f(P(s),"range must be a number"),f(P(i),"taper must be a number"),this.range=s,this.taper=i,this.randomness=e!=null?e:0,this.sampleRate=Wn,this.loadedPercent=0,this.onloadCallback=o,ce(t)){let a=t.slice(),c=e!=null?e:.05,l=1;this.randomness=(r=a[l])!=null?r:c,a[l]=0,this.sampleChannels=[Oi(...a)],this.loadedPercent=1,o==null||o(this)}else if(typeof t=="string"){let a=t;this.loadSound(a)}}}play(t,e=1,s=1,i=1,o=!1,r=!1){if(f(!t||L(t),"pos must be a vec2"),f(P(e),"volume must be a number"),f(P(s),"pitch must be a number"),f(P(i),"randomnessScale must be a number"),!Jt||B||!this.sampleChannels)return;let a;if(t){let u=this.range;if(u){let h=Tt.distanceSquared(t);if(h>u*u)return;e*=Mt(h**.5,u,u*this.taper)}a=Tn(t).x*2/F.width-1}let c=s+s*this.randomness*i*ut(-1,1),l=new si(this,e,c,a,o,r);return It&&kn&&t&&(jt(t,.5,"#0ff",.5,!0),this.range&&(jt(t,2*this.range,"#0ff",.5),jt(t,2*this.range*this.taper,"#0ff",.5)),_n("vol "+e.toFixed(2)+" pitch "+c.toFixed(2),t,.5,"#0ff",.5)),l}playMusic(t=1,e=!0,s=!1){return this.play(void 0,t,1,0,e,s)}playNote(t=0,e,s){f(P(t),"semitoneOffset must be a number");let i=dc(t,1);return this.play(e,s,i,0)}getDuration(){var t,e;return((e=(t=this.sampleChannels)==null?void 0:t[0])==null?void 0:e.length)/this.sampleRate||0}isLoaded(){return this.loadedPercent===1}async loadSound(t){var c;let e=await fetch(t);if(!e.ok)throw new Error(`Failed to load sound from ${t}: ${e.status} ${e.statusText}`);let s=await e.arrayBuffer(),i=await ht.decodeAudioData(s),o=i.numberOfChannels,r=1e5,a=[];for(let l=0;lsetTimeout(v,0));let d=K(p+r,h);for(;p=0,"Sound volume must be positive or zero"),f(s>=0,"Sound rate must be positive or zero"),f(P(i),"Sound pan must be a number"),this.sound=t,this.volume=e,this.rate=s,this.pan=i,this.loop=o,this.pausedTime=0,this.startTime=void 0,this.gainNode=void 0,this.source=void 0,this.onendedCallback=a=>{a===this.source&&(this.source=void 0)},r||this.start()}start(t=0){f(t>=0,"Sound start offset must be positive or zero"),this.isPlaying()&&this.stop(),this.gainNode=ht.createGain(),this.source=Pr(this.sound.sampleChannels,this.volume,this.rate,this.pan,this.loop,this.sound.sampleRate,this.gainNode,t,this.onendedCallback),this.source?(this.startTime=ht.currentTime-t,this.pausedTime=void 0):(this.startTime=void 0,this.pausedTime=0)}setVolume(t){f(t>=0,"Sound volume must be positive or zero"),this.volume=t,this.gainNode&&(this.gainNode.gain.value=t)}stop(t=0){if(f(t>=0,"Sound fade time must be positive or zero"),this.isPlaying())if(t){let e=ht.currentTime,s=e+t;this.gainNode.gain.cancelScheduledValues(e),this.gainNode.gain.setValueAtTime(this.volume,e),this.gainNode.gain.linearRampToValueAtTime(0,s),this.source.stop(s)}else this.source.stop();this.pausedTime=0,this.source=void 0,this.startTime=void 0}pause(){this.isPaused()||(this.pausedTime=this.getCurrentTime(),this.source.stop(),this.source=void 0,this.startTime=void 0)}resume(){this.isPaused()&&this.start(this.pausedTime)}isPlaying(){return!!this.source}isPaused(){return!this.isPlaying()}getCurrentTime(){if(!this.isPlaying())return this.pausedTime;let t=this.getDuration();return t?Qt(ht.currentTime-this.startTime,t):0}getDuration(){return this.rate?this.sound.getDuration()/this.rate:0}getSource(){return this.source}};Ke=[];yn=class{constructor(t,e=0,s=!1,i=new xt){this.tile=t,this.direction=e,this.mirror=s,this.color=i.copy()}clear(){this.tile=this.direction=0,this.mirror=!1,this.color=new xt}},oi=class extends Fe{constructor(t,e,s=0,i=0,o=b(512),r=!0){var a;f(L(o),"canvasSize must be a Vector2"),super(t,e,void 0,s,U,i),this.canvas=B?void 0:new OffscreenCanvas(o.x,o.y),this.context=(a=this.canvas)==null?void 0:a.getContext("2d"),this.textureInfo=new je(this.canvas,r),this.mass=0}destroy(){this.destroyed||(this.textureInfo.destroyWebGLTexture(),super.destroy())}render(){this.draw(this.pos,this.size,this.color,this.angle,this.mirror,this.additiveColor)}draw(t,e,s=U,i=0,o=!1,r,a=!1,c){let l=new Ae().setFullImage(this.textureInfo),u=this.hasWebGL();Rt(t,e,l,s,i,o,r,u,a,c)}updateWebGL(){this.textureInfo.createWebGLTexture()}hasWebGL(){return G&&this.textureInfo.hasWebGL()}},fs=class extends oi{constructor(t,e,s=_s(),i=0,o=!0){let r=s?e.multiply(s.size):e;if(super(t,e,0,i,r,o),this.tileInfo=void 0,this.data=[],this.isUsingWebGL=!1,B){this.render=()=>{},this.redraw=()=>{},this.redrawStart=()=>{},this.redrawEnd=()=>{},this.drawTileData=()=>{},this.redrawTileData=()=>{},this.drawLayerTile=()=>{},this.drawLayerRect=()=>{},this.drawTile=()=>{},this.drawRect=()=>{},this.clearLayerRect=()=>{};return}s&&(this.tileInfo=s.frame(0),this.tileInfo.bleed=0);for(let a=this.size.area();a--;)this.data.push(new yn)}setData(t,e,s=!1){if(t=t.floor(),f(L(t),"layerPos must be a Vector2"),f(e instanceof yn,"data must be a TileLayerData"),!t.arrayCheck(this.size)||(this.data[(t.y|0)*this.size.x+(t.x|0)]=e,!s))return;St===this.context?this.drawTileData(t):this.redrawTileData(t)}clearData(t,e=!1){this.setData(t,new yn,e)}getData(t){return f(L(t),"layerPos must be a Vector2"),t.arrayCheck(this.size)?this.data[(t.y|0)*this.size.x+(t.x|0)]:void 0}update(){!G&&this.isUsingWebGL&&(this.isUsingWebGL=!1,this.redraw())}render(){f(St!==this.context,"must call redrawEnd() after drawing tiles!");let t=this.drawSize||this.size,e=this.pos.add(t.scale(.5));this.draw(e,this.size,this.color,this.angle,this.mirror,this.additiveColor)}onRedraw(){}redraw(){this.redrawStart(!0);for(let t=this.size.x;t--;)for(let e=this.size.y;e--;)this.drawTileData(b(t,e),!1);this.isUsingWebGL&&At(),this.onRedraw(),this.redrawEnd()}redrawStart(t=!1){var s,i;if(!this.context)return;f(St!==this.context),this.savedRenderSettings=[St,I,Tt,W,Xe],St=this.context;let e=(i=(s=this.tileInfo)==null?void 0:s.size)!=null?i:b(1);I=this.size.multiply(e),Xe=ue,Tt=this.size.multiply(e).scale(.5),W=1,this.isUsingWebGL=this.hasWebGL(),this.isUsingWebGL?Qn(this.textureInfo.glTexture,t):(this.context.imageSmoothingEnabled=!mn,t&&(this.canvas.width=I.x,this.canvas.height=I.y))}redrawEnd(){this.context&&(f(St===this.context),this.isUsingWebGL&&Qn(),[St,I,Tt,W,Xe]=this.savedRenderSettings)}drawTileData(t,e=!0){var a,c;if(!this.context)return;f(St===this.context,"must call redrawStart() before drawing tiles");let s=(c=(a=this.tileInfo)==null?void 0:a.size)!=null?c:b(1),i=t.multiply(s);e&&this.clearLayerRect(i,s);let o=this.getData(t);if(!o||!o.tile)return;let r=this.tileInfo&&this.tileInfo.tile(o.tile);this.drawLayerTile(i,s,r,o.color,o.direction*q/2,o.mirror)}redrawTileData(t,e=!0){this.context&&(f(St!==this.context,"redrawStart() should not be active when calling redrawTileData(), instead use drawTileData()"),this.redrawStart(),this.drawTileData(t,e),this.redrawEnd())}drawLayerTile(t,e=b(1),s,i=U,o=0,r,a){let c=t.add(e.scale(.5));Rt(c,e,s,i,o,r,a,this.isUsingWebGL)}drawLayerRect(t,e,s,i=0){this.drawLayerTile(t,e,void 0,s,i)}drawTile(t,e=b(1),s,i=new xt,o=0,r=!1){t=t.subtract(this.pos).multiply(this.tileInfo.size),e=e.multiply(this.tileInfo.size),t.y=this.canvas.height-t.y;let a=I;I=b(this.canvas.width,this.canvas.height);let c=this.hasWebGL();c&&Qn(this.textureInfo.glTexture);let l=c?void 0:this.context;Rt(t,e,s,i,o,r,void 0,c,!0,l),c&&Qn(),I=a}drawRect(t,e,s,i){this.drawTile(t,e,void 0,s,i)}clearLayerRect(t,e){f(St===this.context,"must call redrawStart() before clearing tiles");let s=t.x,i=this.canvas.height-t.y-e.y;this.hasWebGL()?wc(s,i,e.x,e.y):this.context.clearRect(s,i,e.x,e.y)}},ps=class extends fs{constructor(t,e,s=_s(),i=0,o=!0){super(t,e.floor(),s,i,o),this.collisionData=[],this.initCollision(this.size),Ke.push(this),this.isSolid=!0}destroy(){if(this.destroyed)return;let t=Ke.indexOf(this);f(t>=0,"tile collision layer not found in array"),t>=0&&Ke.splice(t,1),super.destroy()}initCollision(t){f(L(t),"size must be a Vector2"),this.size=t.floor(),this.collisionData=[],this.collisionData.length=t.area(),this.collisionData.fill(0)}setCollisionData(t,e=1){f(L(t),"layerPos must be a Vector2");let s=(t.y|0)*this.size.x+(t.x|0);t.arrayCheck(this.size)&&(this.collisionData[s]=e)}clearCollisionData(t){this.setCollisionData(t,0)}getCollisionData(t){f(L(t),"layerPos must be a Vector2");let e=(t.y|0)*this.size.x+(t.x|0);return t.arrayCheck(this.size)?this.collisionData[e]:0}collisionTest(t,e=new it,s){f(L(t)&&L(e),"pos and size must be Vector2s"),f(!s||typeof s=="function"||s instanceof Fe,"callbackObject must be a function or EngineObject");let i=s?typeof s=="function"?(p,d)=>s(p,d):(p,d)=>s.collideWithTile(p,d):()=>!0,o=t.x-this.pos.x,r=t.y-this.pos.y;if(o+e.x/2<0||o-e.x/2>this.size.x||r+e.y/2<0||r-e.y/2>this.size.y)return!1;let a=X(o-e.x/2|0,0),c=X(r-e.y/2|0,0),l=K(X(o+e.x/2,a+1),this.size.x),u=K(X(r+e.y/2,c+1),this.size.y),h=new it;for(let p=c;ps(l,u):(l,u)=>s.collideWithTile(l,u):l=>l>0,r=l=>{let u=this.getCollisionData(a.set(l.x-this.pos.x,l.y-this.pos.y));return u&&o(u,l)},a=new it,c=Ua(t,e,r,i);if(ae&&c){let l=c.floor().add(b(.5));pt(l,b(1),"#f008"),be(t,e,"#00f",.02),be(t,c,"#f00",.02),Qo(c,"#0f0"),i&&be(c,c.add(i),"#ff0",.02)}return c}},yo=class extends Fe{constructor(t,e,s=0,i=0,o=100,r=q,a,c=U,l=U,u=Ze,h=Ze,p=.5,d=.1,y=1,x=.1,v=.05,T=1,C=1,w=0,_=q,A=.1,S=.2,R=!1,M=!1,ot=!0,$=M?1e9:0,nt=!1){super(t,b(),a,e,void 0,$),this.emitCircle=typeof s=="number",this.emitSize=typeof s=="number"?b(s):s.copy(),this.emitTime=i,this.emitRate=o,this.emitConeAngle=r,this.colorStartA=c.copy(),this.colorStartB=l.copy(),this.colorEndA=u.copy(),this.colorEndB=h.copy(),this.randomColorLinear=ot,this.particleTime=p,this.sizeStart=d,this.sizeEnd=y,this.speed=x,this.angleSpeed=v,this.damping=T,this.angleDamping=C,this.gravityScale=w,this.particleConeAngle=_,this.fadeRate=A,this.randomness=S,this.collideTiles=R,this.additive=M,this.localSpace=nt,this.trailScale=0,this.particleCreateCallback=void 0,this.particleDestroyCallback=void 0,this.particleCollideCallback=void 0,this.velocityInheritance=0,this.emitTimeBuffer=0,this.particles=[],this.previousAngle=this.angle,this.previousPos=this.pos.copy()}update(){if(f(this.angleDamping>=0&&this.angleDamping<=1),f(this.damping>=0&&this.damping<=1),this.velocityInheritance){let s=this.velocityInheritance;this.velocity.x=s*(this.pos.x-this.previousPos.x),this.velocity.y=s*(this.pos.y-this.previousPos.y),this.angleVelocity=s*(this.angle-this.previousAngle),this.previousAngle=this.angle,this.previousPos.x=this.pos.x,this.previousPos.y=this.pos.y}if(this.isActive()){if(this.emitRate&&Xs){let s=1/this.emitRate/Xs;for(this.emitTimeBuffer+=$o;this.emitTimeBuffer>0;this.emitTimeBuffer-=s)this.emitParticle()}}else this.particles.length===0&&this.destroy(!0);let t=this.particles,e=0;for(let s=0;sC+C*ut(s,-s),o=i(this.particleTime),r=i(this.sizeStart),a=i(this.sizeEnd),c=i(this.speed),l=i(this.angleSpeed)*Wa(),u=ut(this.emitConeAngle,-this.emitConeAngle),h=lo(this.colorStartA,this.colorStartB,this.randomColorLinear),p=lo(this.colorEndA,this.colorEndB,this.randomColorLinear),d=this.localSpace?u:this.angle+u,y=b(c*tt(d),c*at(d)),x=l;!this.localSpace&&this.velocityInheritance>0&&(y.x+=this.velocity.x,y.y+=this.velocity.y,x+=this.angleVelocity);let v=new ri(this,t,e,h,p,o,r,a,y,x);return this.particles.push(v),(T=this.particleCreateCallback)==null||T.call(this,v),v}updatePhysics(){}render(){for(let t of this.particles)t.render()}isActive(){return!this.emitTime||this.getAliveTime()0&&(this.destroyed=!1,this.emitTime=-1))}},Vh=new it,ri=class{constructor(t,e,s,i,o,r,a,c,l=b(),u=0){this.emitter=t,this.pos=e,this.angle=s,this.size=b(a),this.color=i.copy(),this.colorStart=i,this.colorEnd=o,this.lifeTime=r,this.sizeStart=a,this.sizeEnd=c,this.velocity=l,this.angleVelocity=u,this.spawnTime=Ht,this.mirror=Va(),this.groundObject=void 0,this.destroyed=!1,this.tileInfo=t.tileInfo}update(){let t=this.emitter,e=t.damping,s=t.angleDamping,i=t.restitution,o=t.friction,r=t.gravityScale,a=t.collideTiles,c=t.particleCollideCallback;if(this.lifeTime>0&&Ht-this.spawnTime>this.lifeTime){this.destroy();return}let l=this.pos.copy();if(this.velocity.x*=e,this.velocity.y*=e,this.pos.x+=this.velocity.x+=Bt.x*r,this.pos.y+=this.velocity.y+=Bt.y*r,this.angle+=this.angleVelocity*=s,!Ri||!a)return;let u=this.velocity.lengthSquared();if(u>Oe*Oe){let p=Oe/u**.5;this.velocity.x*=p,this.velocity.y*=p}this.groundObject=void 0;let h=c?p=>{let d=ii(p);return d&&c(this,d,p)}:p=>ii(p)>0;if(h(this.pos)){let p=Ve(this.pos);if(!h(l)){let d=h(b(this.pos.x,l.y)),y=h(b(l.x,this.pos.y)),x=X(i,p.restitution),v=X(o,p.friction);d&&(this.pos.x=l.x,this.velocity.x*=-x,this.velocity.y*=v),(y||!d)&&((this.velocity.y<0&&Bt.y<0||this.velocity.y>0&&Bt.y>0)&&(this.groundObject=p),this.pos.y=l.y,this.velocity.y*=-x,this.velocity.x*=v),re&&pt(this.pos,this.size,"#f00")}}}destroy(){let t=this.emitter.particleDestroyCallback,e=this.colorEnd;this.color.set(e.r,e.g,e.b,e.a),this.size.set(this.sizeEnd,this.sizeEnd),this.destroyed=!0,t==null||t(this)}render(){let t=this.emitter,e=t.localSpace,s=t.additive,i=t.trailScale,o=t.fadeRate/2,r=this.lifeTime>0?K((Ht-this.spawnTime)/this.lifeTime,1):1,a=1-r,c=a*this.sizeStart+r*this.sizeEnd,l=b(c),u=r1-o?(1-r)/o:1;this.color.r=a*this.colorStart.r+r*this.colorEnd.r,this.color.g=a*this.colorStart.g+r*this.colorEnd.g,this.color.b=a*this.colorStart.b+r*this.colorEnd.b,this.color.a=(a*this.colorStart.a+r*this.colorEnd.a)*u;let h=Vh.set(this.pos.x,this.pos.y),p=this.angle;if(e){let d=t.angle,y=at(-d),x=tt(-d);h.set(t.pos.x+h.x*y-h.y*x,t.pos.y+h.x*x+h.y*y),p+=d}if(s&&as(),i){let d=e?this.velocity.rotate(t.angle):this.velocity,y=d.length();if(y){let x=y*i;l.y=X(l.x,x),p=Zo(d.x,d.y),Rt(h,l,this.tileInfo,this.color,p,this.mirror)}}else Rt(h,l,this.tileInfo,this.color,p,this.mirror);s&&as(!1),fn&&pt(h,l,"#f005",0,p)}},Lr=!0,vo=!0,ui=5e5,Dr=11,pc=Dr*4,Wh=ui/pc|0,Di=3,gc=Di*4,Mn=ui/gc|0;an=!1,hi=5,On=.5,di=b(640,80),Br=!1,bs={},zs=[];pi=class{constructor(t,e,s="",i="\u{1F3C6}",o){f(t>=0&&!bs[t]),this.id=t,this.name=e,this.description=s,this.icon=i,this.unlocked=!1,this.image=void 0,o&&((this.image=new Image).src=o),bs[t]=this}unlock(){Br||this.unlocked||(f(fi,"save name must be set"),this.unlocked=!0,Nr(),zs.push(this))}render(t=0){let e=ct,s=K(di.x,F.width),i=di.y,o=F.width-s,r=-i*t,a=Le(0,0,.9);e.save(),e.beginPath(),e.fillStyle=a.toString(),e.strokeStyle=et.toString(),e.lineWidth=3,e.rect(o,r,s,i),e.fill(),e.stroke(),e.clip();let c=b(.1,.05).scale(i),l=i-2*c.x;this.renderIcon(b(o+c.x+l/2,r+i/2),l);let u=i*.5,h=i*.3,p=b(o+l+2*c.x,r+c.y*2+u/2),d=s-l-3*c.x;$e(this.name,p,u,et,0,void 0,"left",void 0,void 0,d),p.y=r+i-c.y*2-h/2,$e(this.description,p,h,et,0,void 0,"left",void 0,void 0,d),e.restore()}renderIcon(t,e){this.image?ct.drawImage(this.image,t.x-e/2,t.y-e/2,e,e):$e(this.icon,t,e*.7,et)}};To=class extends pi{constructor(t,e,s,i,o){super(t,e,s,i,o)}unlock(){super.unlock(),xs&&xs.unlockMedal(this.id)}},Ao=class{constructor(t,e,s){var c,l,u;f(!xs,"there can only be one newgrounds object"),f(!e||s,"must provide cryptojs if there is a cipher"),xs=this,this.app_id=t,this.cipher=e,this.cryptoJS=s,this.host=location?location.hostname:"";let i=new URL(location.href);if(this.session_id=i.searchParams.get("ngio_session_id"),!this.session_id)return;let o=this.call("Medal.getList");if(!o||!o.result||o.result.error){an&&yt("Newgrounds session unavailable; skipping plugin init"),this.medals=[],this.scoreboards=[];return}this.medals=((c=o.result.data)==null?void 0:c.medals)||[],an&&yt(this.medals);for(let h of this.medals){let p=bs[h.id];p&&(p.image=new Image,p.image.src=h.icon,p.name=h.name,p.description=h.description,p.unlocked=h.unlocked,p.difficulty=h.difficulty,p.value=h.value,p.value&&(p.description=p.description+` (${p.value})`))}let r=this.call("ScoreBoard.getBoards");this.scoreboards=((u=(l=r==null?void 0:r.result)==null?void 0:l.data)==null?void 0:u.scoreboards)||[],an&&yt(this.scoreboards);let a=60*1e3;setInterval(()=>this.call("Gateway.ping",0,!0),a)}unlockMedal(t){return this.call("Medal.unlock",{id:t},!0)}postScore(t,e){return this.call("ScoreBoard.postScore",{id:t,value:e},!0)}getScores(t,e,s=0,i=0,o=10){return this.call("ScoreBoard.getScores",{id:t,user:e,social:s,skip:i,limit:o})}logView(){return this.call("App.logView",{host:this.host},!0)}call(t,e,s=!1){let i={component:t,parameters:e};if(this.cipher){let l=this.cryptoJS,u=l.enc.Base64.parse(this.cipher),h=l.lib.WordArray.random(16),p=l.AES.encrypt(JSON.stringify(i),u,{iv:h});i.secure=l.enc.Base64.stringify(h.concat(p.ciphertext)),i.parameters=0}let o={app_id:this.app_id,session_id:this.session_id,call:i},r=new FormData;r.append("input",JSON.stringify(o));let a=new XMLHttpRequest;a.open("POST","https://newgrounds.io/gateway_v3.php",!an&&s);try{a.send(r)}catch(l){an&&yt("newgrounds call failed",l);return}return an&&yt(a.responseText),a.responseText&&JSON.parse(a.responseText)}},Eo=class{constructor(t,e=!1,s=!1){f(!Lt,"Post process already initialized"),f(!(e&&s),"Post process cannot both include main canvas and use feedback texture"),Lt=this,t||(t="void mainImage(out vec4 c,vec2 p){c=texture(iChannel0,p/iResolution.xy);}"),this.shader=void 0,this.texture=void 0,this.vao=void 0,i(),vn(void 0,a,o,r);function i(){if(B)return;if(!G){console.warn("PostProcessPlugin: WebGL not enabled!");return}Lt.texture=Ii(),Lt.shader=zn(`#version 300 es
 precision highp float;in vec2 p;void main(){gl_Position=vec4(p+p-1.,1,1);}`,`#version 300 es
 precision highp float;uniform sampler2D iChannel0;uniform vec3 iResolution;uniform float iTime;out vec4 c;
 `+t+`
-void main(){mainImage(c,gl_FragCoord.xy);c.a=1.;}`),Lt.vao=g.createVertexArray(),g.bindVertexArray(Lt.vao),g.bindBuffer(g.ARRAY_BUFFER,Mn);let c=8,l=g.getAttribLocation(Lt.shader,"p");g.enableVertexAttribArray(l),g.vertexAttribPointer(l,2,g.FLOAT,!1,c,0)}function o(){Lt.shader=void 0,Lt.texture=void 0,bt("PostProcessPlugin: WebGL context lost")}function r(){i(),bt("PostProcessPlugin: WebGL context restored")}function a(){if(j||!k)return;Ct(),g.bindFramebuffer(g.FRAMEBUFFER,null),g.useProgram(Lt.shader),g.bindVertexArray(Lt.vao),g.pixelStorei(g.UNPACK_FLIP_Y_WEBGL,!0),g.disable(g.BLEND),g.activeTexture(g.TEXTURE0),g.bindTexture(g.TEXTURE_2D,Lt.texture),e?(ke.width=D.x,ke.height=D.y,kr(qe),qe.drawImage(G,0,0),G.width|=0,g.texImage2D(g.TEXTURE_2D,0,g.RGBA,g.RGBA,g.UNSIGNED_BYTE,ke)):s||g.texImage2D(g.TEXTURE_2D,0,g.RGBA,g.RGBA,g.UNSIGNED_BYTE,Q);let c=l=>g.getUniformLocation(Lt.shader,l);g.uniform1i(c("iChannel0"),0),g.uniform1f(c("iTime"),Ht),g.uniform3f(c("iResolution"),G.width,G.height,1),g.drawArrays(g.TRIANGLE_STRIP,0,4),s&&g.texImage2D(g.TEXTURE_2D,0,g.RGBA,g.RGBA,g.UNSIGNED_BYTE,Q),g.pixelStorei(g.UNPACK_FLIP_Y_WEBGL,!1),ys(!0)}}},Eo=class{constructor(t,e){f(!V,"LightSystemPlugin already initialized"),f(!Lt,"LightSystemPlugin must be created before PostProcessPlugin"),V=this,this.enabled=!0,this.ambientColor=(e||nt).copy(),this.textureSize=t?t.copy():void 0,this.texture=void 0,this.lightShader=void 0,this.compositeShader=void 0,this.lightVAO=void 0,this.compositeVAO=void 0,s(),bn(void 0,i,o,r);function s(){if(j)return;if(!k){console.warn("LightSystemPlugin: WebGL not enabled!");return}V.textureSize||(V.textureSize=D.copy()),V.texture=g.createTexture(),g.bindTexture(g.TEXTURE_2D,V.texture),g.texImage2D(g.TEXTURE_2D,0,g.RGBA,V.textureSize.x,V.textureSize.y,0,g.RGBA,g.UNSIGNED_BYTE,null),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_MAG_FILTER,g.LINEAR),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_MIN_FILTER,g.LINEAR),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_S,g.CLAMP_TO_EDGE),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_T,g.CLAMP_TO_EDGE),V.lightShader=Jn(`#version 300 es
+void main(){mainImage(c,gl_FragCoord.xy);c.a=1.;}`),Lt.vao=g.createVertexArray(),g.bindVertexArray(Lt.vao),g.bindBuffer(g.ARRAY_BUFFER,In);let c=8,l=g.getAttribLocation(Lt.shader,"p");g.enableVertexAttribArray(l),g.vertexAttribPointer(l,2,g.FLOAT,!1,c,0)}function o(){Lt.shader=void 0,Lt.texture=void 0,yt("PostProcessPlugin: WebGL context lost")}function r(){i(),yt("PostProcessPlugin: WebGL context restored")}function a(){if(B||!G)return;At(),g.bindFramebuffer(g.FRAMEBUFFER,null),g.useProgram(Lt.shader),g.bindVertexArray(Lt.vao),g.pixelStorei(g.UNPACK_FLIP_Y_WEBGL,!0),g.disable(g.BLEND),g.activeTexture(g.TEXTURE0),g.bindTexture(g.TEXTURE_2D,Lt.texture),e?(Me.width=I.x,Me.height=I.y,kr(We),We.drawImage(F,0,0),F.width|=0,g.texImage2D(g.TEXTURE_2D,0,g.RGBA,g.RGBA,g.UNSIGNED_BYTE,Me)):s||g.texImage2D(g.TEXTURE_2D,0,g.RGBA,g.RGBA,g.UNSIGNED_BYTE,Q);let c=l=>g.getUniformLocation(Lt.shader,l);g.uniform1i(c("iChannel0"),0),g.uniform1f(c("iTime"),Ht),g.uniform3f(c("iResolution"),F.width,F.height,1),g.drawArrays(g.TRIANGLE_STRIP,0,4),s&&g.texImage2D(g.TEXTURE_2D,0,g.RGBA,g.RGBA,g.UNSIGNED_BYTE,Q),g.pixelStorei(g.UNPACK_FLIP_Y_WEBGL,!1),ys(!0)}}},_o=class{constructor(t,e){f(!V,"LightSystemPlugin already initialized"),f(!Lt,"LightSystemPlugin must be created before PostProcessPlugin"),V=this,this.enabled=!0,this.ambientColor=(e||et).copy(),this.textureSize=t?t.copy():void 0,this.texture=void 0,this.lightShader=void 0,this.compositeShader=void 0,this.lightVAO=void 0,this.compositeVAO=void 0,s(),vn(void 0,i,o,r);function s(){if(B)return;if(!G){console.warn("LightSystemPlugin: WebGL not enabled!");return}V.textureSize||(V.textureSize=I.copy()),V.texture=g.createTexture(),g.bindTexture(g.TEXTURE_2D,V.texture),g.texImage2D(g.TEXTURE_2D,0,g.RGBA,V.textureSize.x,V.textureSize.y,0,g.RGBA,g.UNSIGNED_BYTE,null),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_MAG_FILTER,g.LINEAR),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_MIN_FILTER,g.LINEAR),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_S,g.CLAMP_TO_EDGE),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_T,g.CLAMP_TO_EDGE),V.lightShader=zn(`#version 300 es
 precision highp float;uniform mat4 m;uniform vec2 lightPos;uniform float radius;in vec2 g;out vec2 vWorldPos;void main(){vec2 worldP=lightPos+(g-.5)*2.*radius;gl_Position=m*vec4(worldP,1,1);vWorldPos=worldP;}`,`#version 300 es
-precision highp float;uniform vec2 lightPos;uniform float radius;uniform float fadeRange;uniform vec4 color;in vec2 vWorldPos;out vec4 c;void main(){float dist=distance(vWorldPos,lightPos);float t=clamp((radius-dist)/max(fadeRange,1e-6),0.,1.);c=vec4(color.rgb*t*color.a,1.);}`),V.compositeShader=Jn(`#version 300 es
+precision highp float;uniform vec2 lightPos;uniform float radius;uniform float fadeRange;uniform vec4 color;in vec2 vWorldPos;out vec4 c;void main(){float dist=distance(vWorldPos,lightPos);float t=clamp((radius-dist)/max(fadeRange,1e-6),0.,1.);c=vec4(color.rgb*t*color.a,1.);}`),V.compositeShader=zn(`#version 300 es
 precision highp float;in vec2 p;void main(){gl_Position=vec4(p+p-1.,1,1);}`,`#version 300 es
-precision highp float;uniform sampler2D s;uniform vec3 iResolution;out vec4 c;void main(){vec2 uv=gl_FragCoord.xy/iResolution.xy;c=vec4(texture(s,uv).rgb,1.);}`),V.lightVAO=g.createVertexArray(),g.bindVertexArray(V.lightVAO),g.bindBuffer(g.ARRAY_BUFFER,Mn);let a=g.getAttribLocation(V.lightShader,"g");g.enableVertexAttribArray(a),g.vertexAttribPointer(a,2,g.FLOAT,!1,8,0),V.compositeVAO=g.createVertexArray(),g.bindVertexArray(V.compositeVAO),g.bindBuffer(g.ARRAY_BUFFER,Mn);let c=g.getAttribLocation(V.compositeShader,"p");g.enableVertexAttribArray(c),g.vertexAttribPointer(c,2,g.FLOAT,!1,8,0)}function i(){if(j||!k||!V.enabled||!V.texture)return;Ct();let a=Tn,c=V.ambientColor;g.bindFramebuffer(g.FRAMEBUFFER,Or),g.framebufferTexture2D(g.FRAMEBUFFER,g.COLOR_ATTACHMENT0,g.TEXTURE_2D,V.texture,0),g.viewport(0,0,V.textureSize.x,V.textureSize.y),g.clearColor(c.r,c.g,c.b,c.a),g.clear(g.COLOR_BUFFER_BIT),as(),g.enable(g.BLEND),g.blendFunc(g.ONE,g.ONE);for(let u of xt)u.destroyed||u.renderLight();Ct(),g.bindFramebuffer(g.FRAMEBUFFER,null),g.viewport(0,0,D.x,D.y),g.useProgram(V.compositeShader),g.bindVertexArray(V.compositeVAO),g.activeTexture(g.TEXTURE0),g.bindTexture(g.TEXTURE_2D,V.texture);let l=V.compositeShader;g.uniform1i(g.getUniformLocation(l,"s"),0),g.uniform3f(g.getUniformLocation(l,"iResolution"),G.width,G.height,1),g.blendFunc(g.DST_COLOR,g.ZERO),g.drawArrays(g.TRIANGLE_STRIP,0,4),Xt&&g.bindTexture(g.TEXTURE_2D,Xt),as(a),ys(!0)}function o(){V.texture=void 0,V.lightShader=void 0,V.compositeShader=void 0,V.lightVAO=void 0,V.compositeVAO=void 0,bt("LightSystemPlugin: WebGL context lost")}function r(){s(),bt("LightSystemPlugin: WebGL context restored")}}drawLight(t){if(j||!k||!this.lightShader)return;Ct(),g.useProgram(this.lightShader),g.bindVertexArray(this.lightVAO);let e=x(2*W).divide(D),s=At.rotate(-$),i=x(-1).subtract(s.multiply(e)),o=ot($),r=tt($),a=[e.x*o,e.y*r,0,0,-e.x*r,e.y*o,0,0,1,1,1,0,i.x,i.y,0,1],c=this.lightShader;g.uniformMatrix4fv(g.getUniformLocation(c,"m"),!1,a),g.uniform2f(g.getUniformLocation(c,"lightPos"),t.pos.x,t.pos.y),g.uniform1f(g.getUniformLocation(c,"radius"),t.radius),g.uniform1f(g.getUniformLocation(c,"fadeRange"),t.fadeRange);let l=t.color;g.uniform4f(g.getUniformLocation(c,"color"),l.r,l.g,l.b,l.a),g.drawArrays(g.TRIANGLE_STRIP,0,4),ys(!0)}},_o=class extends je{constructor(t,e,s,i){super(t,x(1),void 0,0,s),f(P(e)&&e>=0,"Light radius must be a non-negative number"),f(i===void 0||P(i)&&i>=0,"Light fadeRange must be a non-negative number when provided"),this.radius=e,this.fadeRange=i===void 0?e:i}render(){}renderLight(){V&&V.drawLight(this)}},Ro=class extends ds{constructor(t){super(void 0),!(!Ut||j)&&(this.randomness=0,this.sampleChannels=Tc(...t),this.sampleRate=qn)}playMusic(t=1,e=!0){return super.play(void 0,t,1,0,e)}};zr=0;Po=class{constructor(t=at){f(!C,"UI system already initialized"),C=this,this.activateOnPress=!1,this.defaultColor=U,this.defaultLineColor=nt,this.defaultTextColor=nt,this.defaultButtonColor=Oe(0,0,.7),this.defaultHoverColor=Oe(0,0,.9),this.defaultDisabledColor=Oe(0,0,.3),this.defaultGradientColor=void 0,this.defaultLineWidth=4,this.defaultCornerRadius=0,this.defaultTextFitScale=.8,this.defaultFont=ws,this.defaultSoundPress=void 0,this.defaultSoundRelease=void 0,this.defaultSoundClick=void 0,this.defaultShadowColor=ue,this.defaultShadowBlur=5,this.defaultShadowOffset=x(5),this.nativeHeight=0,this.navigationObject=void 0,this.navigationTimer=new we(void 0,!0),this.navigationDelay=.2,this.navigationDirection=1,this.navigationMode=!1,this.uiObjects=[],this.uiContext=t,this.activeObject=void 0,this.hoverObject=void 0,this.lastHoverObject=void 0,this.confirmDialog=void 0,this._keyInputObject=void 0,this._onKeyDown=o=>{var r;return(r=this._keyInputObject)==null?void 0:r.onKeyDown(o)},bn(s,i);function e(o){let r,a;o.parent?(r=o.parent.nativePos,a=o.parent.size):(r=C.screenToNative(D.scale(.5)),a=C.nativeHeight?x(D.x*C.nativeHeight/D.y,C.nativeHeight):D);let c=o.anchor;o.nativePos=r.add(a.multiply(c).scale(.5)).subtract(o.size.multiply(c).scale(.5)).add(o.localPos)}function s(){C.activeObject&&!C.activeObject.visible&&(C.activeObject=void 0),C.lastHoverObject=C.hoverObject,C.hoverObject=void 0,cs(0)&&(C.navigationMode=!1,C.navigationObject=void 0),C.keyInputObject&&(C.activeObject=C.keyInputObject,C.hoverObject=C.keyInputObject,C.navigationMode=!1,C.navigationObject=void 0);let o=C.getNavigableObjects();if(!o.length)C.navigationObject=void 0;else if(!C.keyInputObject){if(o.includes(C.navigationObject)||(C.navigationObject=void 0),ee||C.navigationMode&&!C.navigationObject&&(C.navigationObject=o.find(a=>a.navigationAutoSelect)),!C.navigationTimer.active()){let a=Zt(C.getNavigationDirection());if(a){let c;if(C.navigationObject){let l=o.indexOf(C.navigationObject),u=te(l+a,o.length);c=o[u]}else if(c=o.find(l=>l.navigationAutoSelect),!c){let l=a>0?0:o.length-1;c=o[l]}C.navigationObject!==c&&(C.navigationMode=!0,C.hoverObject=void 0,C.navigationObject=c,C.navigationTimer.set(C.navigationDelay),c.soundPress&&c.soundPress.play())}}C.navigationObject&&C.getNavigationWasPressed()&&C.navigationObject.navigatePressed()}for(let a=C.uiObjects.length;a--;){let c=C.uiObjects[a];c.parent||r(c)}C.uiObjects=C.uiObjects.filter(a=>!a.destroyed);function r(a){if(!(a.destroyed||!a.visible)){e(a);for(let c=a.children.length;c--;){let l=a.children[c];l&&r(l)}a.destroyed||a.update()}}}function i(){let o=C.uiContext;if(o.save(),C.nativeHeight){let a=D.y/C.nativeHeight;o.translate(-a*D.x/2,0),o.scale(a,a),o.translate(D.x/2/a,0)}function r(a){if(a.visible){e(a),a.render();for(let c of a.children)r(c)}}if(C.uiObjects.forEach(a=>a.parent||r(a)),zr>0){let a=function(c,l=!0){l&&(l=!!c.visible),e(c),c.renderDebug(l);for(let u of c.children)a(u,l)};C.uiObjects.forEach(c=>c.parent||a(c))}o.restore()}}drawRect(t,e,s=U,i=0,o=nt,r=0,a,c=nt,l=0,u=x()){f(L(t),"pos must be a vec2"),f(L(e),"size must be a vec2"),f(z(s),"color must be a color"),f(P(i),"lineWidth must be a number"),f(z(o),"lineColor must be a color"),f(P(r),"cornerRadius must be a number");let h=C.uiContext;if(a){let p=h.createLinearGradient(t.x,t.y-e.y/2,t.x,t.y+e.y/2),d=s.toString();p.addColorStop(0,d),p.addColorStop(.5,a.toString()),p.addColorStop(1,d),h.fillStyle=p}else h.fillStyle=s.toString();(l||u.x||u.y)&&c.a>0&&(h.shadowColor=c.toString(),h.shadowBlur=l,h.shadowOffsetX=u.x,h.shadowOffsetY=u.y),h.beginPath(),r&&h.roundRect?h.roundRect(t.x-e.x/2,t.y-e.y/2,e.x,e.y,r):h.rect(t.x-e.x/2,t.y-e.y/2,e.x,e.y),h.fill(),h.shadowColor="#0000",i&&o.a>0&&(h.strokeStyle=o.toString(),h.lineWidth=i,h.stroke())}drawLine(t,e,s=C.defaultLineWidth,i=C.defaultLineColor){f(L(t),"posA must be a vec2"),f(L(e),"posB must be a vec2"),f(P(s),"lineWidth must be a number"),f(z(i),"lineColor must be a color");let o=C.uiContext;o.strokeStyle=i.toString(),o.lineWidth=s,o.beginPath(),o.lineTo(t.x,t.y),o.lineTo(e.x,e.y),o.stroke()}drawTile(t,e,s,i=C.defaultColor,o=0,r=!1,a=nt,c=0,l=x()){let u=C.uiContext;(c||l.x||l.y)&&a.a>0&&(u.shadowColor=a.toString(),u.shadowBlur=c,u.shadowOffsetX=l.x,u.shadowOffsetY=l.y),_t(t,e,s,i,o,r,ue,!1,!0,u),u.shadowColor="#0000"}drawText(t,e,s,i=C.defaultColor,o=C.defaultLineWidth,r=C.defaultLineColor,a="center",c=C.defaultFont,l="",u=!0,h=void 0,p=nt,d=0,y=x()){let b=C.uiContext;p.a>0&&(h&&Ke(t,e.add(h),s.y,p,o,r,a,c,l,u?s.x:void 0,0,b),(d||y.x||y.y)&&(b.shadowColor=p.toString(),b.shadowBlur=d,b.shadowOffsetX=y.x,b.shadowOffsetY=y.y)),Ke(t,e,s.y,i,o,r,a,c,l,u?s.x:void 0,0,b),b.shadowColor="#0000"}setupDragAndDrop(t,e,s,i){if(this._dragListeners)for(let[r,a]of this._dragListeners)document.removeEventListener(r,a);this._dragListeners=[];let o=(r,a)=>{let c=l=>{l.preventDefault(),r&&r(l)};document.addEventListener(a,c),this._dragListeners.push([a,c])};o(t,"drop"),o(e,"dragenter"),o(s,"dragleave"),o(i,"dragover")}screenToNative(t){if(!C.nativeHeight)return t;let e=D.y/C.nativeHeight,s=1/e,i=t.copy();return i.x+=e*D.x/2,i.x*=s,i.y*=s,i.x-=s*D.x/2,i}get keyInputObject(){return this._keyInputObject}set keyInputObject(t){let e=!!this._keyInputObject;this._keyInputObject=t,!e&&t?document.addEventListener("keydown",this._onKeyDown):e&&!t&&document.removeEventListener("keydown",this._onKeyDown)}destroyObjects(){for(let t of this.uiObjects)t.parent||t.destroy();this.uiObjects=this.uiObjects.filter(t=>!t.destroyed),this.activeObject=void 0,this.hoverObject=void 0,this.lastHoverObject=void 0,this.keyInputObject=void 0}getNavigableObjects(){function t(s){if(!(!s.visible||s.disabled)){s.isInteractive()&&s.navigationIndex!==void 0&&e.push(s);for(let i=s.children.length;i--;)t(s.children[i])}}let e=[];for(let s=C.uiObjects.length;s--;){let i=C.uiObjects[s];C.confirmDialog&&i!==C.confirmDialog||i.parent||t(i)}return e.sort((s,i)=>s.navigationIndex-i.navigationIndex),e}getNavigationDirection(){let t=C.navigationDirection===1,e=C.navigationDirection===2;if(In){let l=ls(0,yt),u=po(yt);return e?-(l.y||u.y)||l.x||u.x:t?-(l.y||u.y):l.x||u.x}let s="ArrowUp",i="ArrowDown",o="ArrowLeft",r="ArrowRight";if(e)return Et(s)||Et(o)?-1:Et(i)||Et(r)?1:0;let a=t?s:o,c=t?i:r;return Et(a)?-1:Et(c)?1:0}getNavigationOtherDirection(){if(C.navigationDirection===2)return 0;let t=C.navigationDirection===1;if(In){let i=ls(0,yt),o=po(yt);return t?i.x||o.x:i.y||o.y}let e=t?"ArrowLeft":"ArrowUp",s=t?"ArrowRight":"ArrowDown";return Et(e)?-1:Et(s)?1:0}getNavigationWasPressed(){return In?Ar(0,yt):Ot("Space")||Ot("Enter")}showConfirmDialog(t="Are you sure?",e,s,i=x(500,250),o="Escape"){f(!C.confirmDialog);let r=C.navigationDirection;C.navigationDirection=2;let a=new se(x(),i);C.confirmDialog=a,a.onRender=()=>{let d=Oe(0,0,0,.7);C.drawRect(x(),x(1e9),d)},a.onUpdate=()=>{Ot(o)&&p()},a.isMouseOverlapping=()=>!0;let c=50,l=new gi(x(0,-50),x(i.x-c,70),t);a.addChild(l);let u=new vs(x(-80,50),x(120,70),"Yes");u.textHeight=40,u.navigationIndex=1,u.hoverColor=Oe(0,1,.5),u.onClick=()=>{p(),e&&e()},a.addChild(u);let h=new vs(x(80,50),x(120,70),"No");h.textHeight=40,h.navigationIndex=2,h.navigationAutoSelect=!0,h.onClick=()=>{p(),s&&s()},a.addChild(h);function p(){f(C.confirmDialog===a),a.destroy(),C.confirmDialog=void 0,C.navigationDirection=r,Ps()}}},se=class{constructor(t=x(),e=x()){var s,i;f(L(t),"ui object pos must be a vec2"),f(L(e),"ui object size must be a vec2"),this.localPos=t.copy(),this.nativePos=t.copy(),this.size=e.copy(),this.color=C.defaultColor.copy(),this.activeColor=void 0,this.text=void 0,this.disabledColor=C.defaultDisabledColor.copy(),this.disabled=!1,this.textColor=C.defaultTextColor.copy(),this.hoverColor=C.defaultHoverColor.copy(),this.lineColor=C.defaultLineColor.copy(),this.gradientColor=C.defaultGradientColor?C.defaultGradientColor.copy():void 0,this.lineWidth=C.defaultLineWidth,this.cornerRadius=C.defaultCornerRadius,this.font=C.defaultFont,this.fontStyle=void 0,this.textWidth=void 0,this.textHeight=void 0,this.textFitScale=C.defaultTextFitScale,this.textShadow=void 0,this.textLineColor=C.defaultLineColor.copy(),this.textLineWidth=0,this.visible=!0,this.children=[],this.parent=void 0,this.extraTouchSize=0,this.soundPress=C.defaultSoundPress,this.soundRelease=C.defaultSoundRelease,this.soundClick=C.defaultSoundClick,this.interactive=!1,this.dragActivate=!1,this.canBeHover=!0,this.shadowColor=(s=C.defaultShadowColor)==null?void 0:s.copy(),this.shadowBlur=C.defaultShadowBlur,this.shadowOffset=(i=C.defaultShadowOffset)==null?void 0:i.copy(),this.navigationIndex=void 0,this.navigationAutoSelect=!1,this.anchor=x(),C.uiObjects.push(this)}addChild(t){return f(!t.parent&&!this.children.includes(t)),this.children.push(t),t.parent=this,t}removeChild(t){f(t.parent===this&&this.children.includes(t)),this.children.splice(this.children.indexOf(t),1),t.parent=void 0}destroy(){var t;if(!this.destroyed){C.activeObject===this&&(C.activeObject=void 0),C.hoverObject===this&&(C.hoverObject=void 0),C.lastHoverObject===this&&(C.lastHoverObject=void 0),C.navigationObject===this&&(C.navigationObject=void 0),C.keyInputObject===this&&(C.keyInputObject=void 0),this.destroyed=1,(t=this.parent)==null||t.removeChild(this);for(let e of this.children)e.parent=void 0,e.destroy();this.children.length=0}}isMouseOverlapping(){if(!ti)return!1;let t=ee?this.size.add(x(this.extraTouchSize||0)):this.size,e=C.screenToNative(jt);return Hs(this.nativePos,t,e)}update(){if(this.onUpdate(),this.disabled&&(this===C.activeObject&&(C.activeObject=void 0),this===C.keyInputObject&&(C.keyInputObject=void 0)),C.keyInputObject)return;let t=C.lastHoverObject===this,e=this.isActiveObject(),s=ns(0),i=this.dragActivate?s:cs(0);this.canBeHover&&(C.navigationMode||(i||e||!s&&!ee)&&!C.hoverObject&&this.isMouseOverlapping()&&(C.hoverObject=this)),this.isHoverObject()&&(this.disabled||(i&&this.interactive&&((!this.dragActivate||!t||cs(0))&&this.onPress(),this.soundPress&&this.soundPress.play(),C.activeObject&&!e&&C.activeObject.onRelease(),C.activeObject=this,C.activateOnPress&&this.click(!this.soundPress)),C.activateOnPress||!s&&this.isActiveObject()&&this.interactive&&this.click()),i&&wr(0,0,0,1,0)),e&&(!s||this.dragActivate&&!this.isHoverObject())&&(this.onRelease(),this.soundRelease&&this.soundRelease.play(),C.activeObject=void 0),this.isHoverObject()!==t&&(this.isHoverObject()?this.onEnter():this.onLeave())}render(){if(this.onRender(),!this.size.x||!this.size.y)return;let t=this.isNavigationObject(),e=t?this.color:this.interactive&&this.isActiveObject()&&!this.disabled?this.color:this.lineColor,s=t?this.hoverColor:this.disabled?this.disabledColor:this.interactive?this.isActiveObject()?this.activeColor||this.hoverColor:this.isHoverObject()?this.hoverColor:this.color:this.color,i=this.lineWidth*(t?1.5:1);C.drawRect(this.nativePos,this.size,s,i,e,this.cornerRadius,this.gradientColor,this.shadowColor,this.shadowBlur,this.shadowOffset)}getTextSize(){return x(this.textWidth||this.textFitScale*this.size.x,this.textHeight||this.textFitScale*this.size.y)}navigatePressed(){this.click()}isHoverObject(){return C.hoverObject===this}isActiveObject(){return C.activeObject===this}isNavigationObject(){return C.navigationObject===this}isKeyInputObject(){return C.keyInputObject===this}isInteractive(){return this.interactive&&this.visible&&!this.disabled}toString(){let t="type = "+this.constructor.name;return this.text&&(t+=`
+precision highp float;uniform sampler2D s;uniform vec3 iResolution;out vec4 c;void main(){vec2 uv=gl_FragCoord.xy/iResolution.xy;c=vec4(texture(s,uv).rgb,1.);}`),V.lightVAO=g.createVertexArray(),g.bindVertexArray(V.lightVAO),g.bindBuffer(g.ARRAY_BUFFER,In);let a=g.getAttribLocation(V.lightShader,"g");g.enableVertexAttribArray(a),g.vertexAttribPointer(a,2,g.FLOAT,!1,8,0),V.compositeVAO=g.createVertexArray(),g.bindVertexArray(V.compositeVAO),g.bindBuffer(g.ARRAY_BUFFER,In);let c=g.getAttribLocation(V.compositeShader,"p");g.enableVertexAttribArray(c),g.vertexAttribPointer(c,2,g.FLOAT,!1,8,0)}function i(){if(B||!G||!V.enabled||!V.texture)return;At();let a=En,c=V.ambientColor;g.bindFramebuffer(g.FRAMEBUFFER,Or),g.framebufferTexture2D(g.FRAMEBUFFER,g.COLOR_ATTACHMENT0,g.TEXTURE_2D,V.texture,0),g.viewport(0,0,V.textureSize.x,V.textureSize.y),g.clearColor(c.r,c.g,c.b,c.a),g.clear(g.COLOR_BUFFER_BIT),as(),g.enable(g.BLEND),g.blendFunc(g.ONE,g.ONE);for(let u of mt)u.destroyed||u.renderLight();At(),g.bindFramebuffer(g.FRAMEBUFFER,null),g.viewport(0,0,I.x,I.y),g.useProgram(V.compositeShader),g.bindVertexArray(V.compositeVAO),g.activeTexture(g.TEXTURE0),g.bindTexture(g.TEXTURE_2D,V.texture);let l=V.compositeShader;g.uniform1i(g.getUniformLocation(l,"s"),0),g.uniform3f(g.getUniformLocation(l,"iResolution"),F.width,F.height,1),g.blendFunc(g.DST_COLOR,g.ZERO),g.drawArrays(g.TRIANGLE_STRIP,0,4),Xt&&g.bindTexture(g.TEXTURE_2D,Xt),as(a),ys(!0)}function o(){V.texture=void 0,V.lightShader=void 0,V.compositeShader=void 0,V.lightVAO=void 0,V.compositeVAO=void 0,yt("LightSystemPlugin: WebGL context lost")}function r(){s(),yt("LightSystemPlugin: WebGL context restored")}}drawLight(t){if(B||!G||!this.lightShader)return;At(),g.useProgram(this.lightShader),g.bindVertexArray(this.lightVAO);let e=b(2*W).divide(I),s=Tt.rotate(-Y),i=b(-1).subtract(s.multiply(e)),o=at(Y),r=tt(Y),a=[e.x*o,e.y*r,0,0,-e.x*r,e.y*o,0,0,1,1,1,0,i.x,i.y,0,1],c=this.lightShader;g.uniformMatrix4fv(g.getUniformLocation(c,"m"),!1,a),g.uniform2f(g.getUniformLocation(c,"lightPos"),t.pos.x,t.pos.y),g.uniform1f(g.getUniformLocation(c,"radius"),t.radius),g.uniform1f(g.getUniformLocation(c,"fadeRange"),t.fadeRange);let l=t.color;g.uniform4f(g.getUniformLocation(c,"color"),l.r,l.g,l.b,l.a),g.drawArrays(g.TRIANGLE_STRIP,0,4),ys(!0)}},Co=class extends Fe{constructor(t,e,s,i){super(t,b(1),void 0,0,s),f(P(e)&&e>=0,"Light radius must be a non-negative number"),f(i===void 0||P(i)&&i>=0,"Light fadeRange must be a non-negative number when provided"),this.radius=e,this.fadeRange=i===void 0?e:i}render(){}renderLight(){V&&V.drawLight(this)}},Ro=class extends ds{constructor(t){super(void 0),!(!Jt||B)&&(this.randomness=0,this.sampleChannels=Tc(...t),this.sampleRate=Wn)}playMusic(t=1,e=!0){return super.play(void 0,t,1,0,e)}};zr=0;Po=class{constructor(t=ct){f(!E,"UI system already initialized"),E=this,this.activateOnPress=!1,this.defaultColor=U,this.defaultLineColor=et,this.defaultTextColor=et,this.defaultButtonColor=Le(0,0,.7),this.defaultHoverColor=Le(0,0,.9),this.defaultDisabledColor=Le(0,0,.3),this.defaultGradientColor=void 0,this.defaultLineWidth=4,this.defaultCornerRadius=0,this.defaultTextFitScale=.8,this.defaultFont=ws,this.defaultSoundPress=void 0,this.defaultSoundRelease=void 0,this.defaultSoundClick=void 0,this.defaultShadowColor=ue,this.defaultShadowBlur=5,this.defaultShadowOffset=b(5),this.nativeHeight=0,this.navigationObject=void 0,this.navigationTimer=new Se(void 0,!0),this.navigationDelay=.2,this.navigationDirection=1,this.navigationMode=!1,this.uiObjects=[],this.uiContext=t,this.activeObject=void 0,this.hoverObject=void 0,this.lastHoverObject=void 0,this.confirmDialog=void 0,this._keyInputObject=void 0,this._onKeyDown=o=>{var r;return(r=this._keyInputObject)==null?void 0:r.onKeyDown(o)},vn(s,i);function e(o){let r,a;o.parent?(r=o.parent.nativePos,a=o.parent.size):(r=E.screenToNative(I.scale(.5)),a=E.nativeHeight?b(I.x*E.nativeHeight/I.y,E.nativeHeight):I);let c=o.anchor;o.nativePos=r.add(a.multiply(c).scale(.5)).subtract(o.size.multiply(c).scale(.5)).add(o.localPos)}function s(){E.activeObject&&!E.activeObject.visible&&(E.activeObject=void 0),E.lastHoverObject=E.hoverObject,E.hoverObject=void 0,cs(0)&&(E.navigationMode=!1,E.navigationObject=void 0),E.keyInputObject&&(E.activeObject=E.keyInputObject,E.hoverObject=E.keyInputObject,E.navigationMode=!1,E.navigationObject=void 0);let o=E.getNavigableObjects();if(!o.length)E.navigationObject=void 0;else if(!E.keyInputObject){if(o.includes(E.navigationObject)||(E.navigationObject=void 0),Zt||E.navigationMode&&!E.navigationObject&&(E.navigationObject=o.find(a=>a.navigationAutoSelect)),!E.navigationTimer.active()){let a=Kt(E.getNavigationDirection());if(a){let c;if(E.navigationObject){let l=o.indexOf(E.navigationObject),u=Qt(l+a,o.length);c=o[u]}else if(c=o.find(l=>l.navigationAutoSelect),!c){let l=a>0?0:o.length-1;c=o[l]}E.navigationObject!==c&&(E.navigationMode=!0,E.hoverObject=void 0,E.navigationObject=c,E.navigationTimer.set(E.navigationDelay),c.soundPress&&c.soundPress.play())}}E.navigationObject&&E.getNavigationWasPressed()&&E.navigationObject.navigatePressed()}for(let a=E.uiObjects.length;a--;){let c=E.uiObjects[a];c.parent||r(c)}E.uiObjects=E.uiObjects.filter(a=>!a.destroyed);function r(a){if(!(a.destroyed||!a.visible)){e(a);for(let c=a.children.length;c--;){let l=a.children[c];l&&r(l)}a.destroyed||a.update()}}}function i(){let o=E.uiContext;if(o.save(),E.nativeHeight){let a=I.y/E.nativeHeight;o.translate(-a*I.x/2,0),o.scale(a,a),o.translate(I.x/2/a,0)}function r(a){if(a.visible){e(a),a.render();for(let c of a.children)r(c)}}if(E.uiObjects.forEach(a=>a.parent||r(a)),zr>0){let a=function(c,l=!0){l&&(l=!!c.visible),e(c),c.renderDebug(l);for(let u of c.children)a(u,l)};E.uiObjects.forEach(c=>c.parent||a(c))}o.restore()}}drawRect(t,e,s=U,i=0,o=et,r=0,a,c=et,l=0,u=b()){f(L(t),"pos must be a vec2"),f(L(e),"size must be a vec2"),f(z(s),"color must be a color"),f(P(i),"lineWidth must be a number"),f(z(o),"lineColor must be a color"),f(P(r),"cornerRadius must be a number");let h=E.uiContext;if(a){let p=h.createLinearGradient(t.x,t.y-e.y/2,t.x,t.y+e.y/2),d=s.toString();p.addColorStop(0,d),p.addColorStop(.5,a.toString()),p.addColorStop(1,d),h.fillStyle=p}else h.fillStyle=s.toString();(l||u.x||u.y)&&c.a>0&&(h.shadowColor=c.toString(),h.shadowBlur=l,h.shadowOffsetX=u.x,h.shadowOffsetY=u.y),h.beginPath(),r&&h.roundRect?h.roundRect(t.x-e.x/2,t.y-e.y/2,e.x,e.y,r):h.rect(t.x-e.x/2,t.y-e.y/2,e.x,e.y),h.fill(),h.shadowColor="#0000",i&&o.a>0&&(h.strokeStyle=o.toString(),h.lineWidth=i,h.stroke())}drawLine(t,e,s=E.defaultLineWidth,i=E.defaultLineColor){f(L(t),"posA must be a vec2"),f(L(e),"posB must be a vec2"),f(P(s),"lineWidth must be a number"),f(z(i),"lineColor must be a color");let o=E.uiContext;o.strokeStyle=i.toString(),o.lineWidth=s,o.beginPath(),o.lineTo(t.x,t.y),o.lineTo(e.x,e.y),o.stroke()}drawTile(t,e,s,i=E.defaultColor,o=0,r=!1,a=et,c=0,l=b()){let u=E.uiContext;(c||l.x||l.y)&&a.a>0&&(u.shadowColor=a.toString(),u.shadowBlur=c,u.shadowOffsetX=l.x,u.shadowOffsetY=l.y),Rt(t,e,s,i,o,r,ue,!1,!0,u),u.shadowColor="#0000"}drawText(t,e,s,i=E.defaultColor,o=E.defaultLineWidth,r=E.defaultLineColor,a="center",c=E.defaultFont,l="",u=!0,h=void 0,p=et,d=0,y=b()){let x=E.uiContext;p.a>0&&(h&&$e(t,e.add(h),s.y,p,o,r,a,c,l,u?s.x:void 0,0,x),(d||y.x||y.y)&&(x.shadowColor=p.toString(),x.shadowBlur=d,x.shadowOffsetX=y.x,x.shadowOffsetY=y.y)),$e(t,e,s.y,i,o,r,a,c,l,u?s.x:void 0,0,x),x.shadowColor="#0000"}setupDragAndDrop(t,e,s,i){if(this._dragListeners)for(let[r,a]of this._dragListeners)document.removeEventListener(r,a);this._dragListeners=[];let o=(r,a)=>{let c=l=>{l.preventDefault(),r&&r(l)};document.addEventListener(a,c),this._dragListeners.push([a,c])};o(t,"drop"),o(e,"dragenter"),o(s,"dragleave"),o(i,"dragover")}screenToNative(t){if(!E.nativeHeight)return t;let e=I.y/E.nativeHeight,s=1/e,i=t.copy();return i.x+=e*I.x/2,i.x*=s,i.y*=s,i.x-=s*I.x/2,i}get keyInputObject(){return this._keyInputObject}set keyInputObject(t){let e=!!this._keyInputObject;this._keyInputObject=t,!e&&t?document.addEventListener("keydown",this._onKeyDown):e&&!t&&document.removeEventListener("keydown",this._onKeyDown)}destroyObjects(){for(let t of this.uiObjects)t.parent||t.destroy();this.uiObjects=this.uiObjects.filter(t=>!t.destroyed),this.activeObject=void 0,this.hoverObject=void 0,this.lastHoverObject=void 0,this.keyInputObject=void 0}getNavigableObjects(){function t(s){if(!(!s.visible||s.disabled)){s.isInteractive()&&s.navigationIndex!==void 0&&e.push(s);for(let i=s.children.length;i--;)t(s.children[i])}}let e=[];for(let s=E.uiObjects.length;s--;){let i=E.uiObjects[s];E.confirmDialog&&i!==E.confirmDialog||i.parent||t(i)}return e.sort((s,i)=>s.navigationIndex-i.navigationIndex),e}getNavigationDirection(){let t=E.navigationDirection===1,e=E.navigationDirection===2;if(Dn){let l=ls(0,ft),u=po(ft);return e?-(l.y||u.y)||l.x||u.x:t?-(l.y||u.y):l.x||u.x}let s="ArrowUp",i="ArrowDown",o="ArrowLeft",r="ArrowRight";if(e)return Ct(s)||Ct(o)?-1:Ct(i)||Ct(r)?1:0;let a=t?s:o,c=t?i:r;return Ct(a)?-1:Ct(c)?1:0}getNavigationOtherDirection(){if(E.navigationDirection===2)return 0;let t=E.navigationDirection===1;if(Dn){let i=ls(0,ft),o=po(ft);return t?i.x||o.x:i.y||o.y}let e=t?"ArrowLeft":"ArrowUp",s=t?"ArrowRight":"ArrowDown";return Ct(e)?-1:Ct(s)?1:0}getNavigationWasPressed(){return Dn?Ar(0,ft):Ot("Space")||Ot("Enter")}showConfirmDialog(t="Are you sure?",e,s,i=b(500,250),o="Escape"){f(!E.confirmDialog);let r=E.navigationDirection;E.navigationDirection=2;let a=new ee(b(),i);E.confirmDialog=a,a.onRender=()=>{let d=Le(0,0,0,.7);E.drawRect(b(),b(1e9),d)},a.onUpdate=()=>{Ot(o)&&p()},a.isMouseOverlapping=()=>!0;let c=50,l=new gi(b(0,-50),b(i.x-c,70),t);a.addChild(l);let u=new vs(b(-80,50),b(120,70),"Yes");u.textHeight=40,u.navigationIndex=1,u.hoverColor=Le(0,1,.5),u.onClick=()=>{p(),e&&e()},a.addChild(u);let h=new vs(b(80,50),b(120,70),"No");h.textHeight=40,h.navigationIndex=2,h.navigationAutoSelect=!0,h.onClick=()=>{p(),s&&s()},a.addChild(h);function p(){f(E.confirmDialog===a),a.destroy(),E.confirmDialog=void 0,E.navigationDirection=r,Ps()}}},ee=class{constructor(t=b(),e=b()){var s,i;f(L(t),"ui object pos must be a vec2"),f(L(e),"ui object size must be a vec2"),this.localPos=t.copy(),this.nativePos=t.copy(),this.size=e.copy(),this.color=E.defaultColor.copy(),this.activeColor=void 0,this.text=void 0,this.disabledColor=E.defaultDisabledColor.copy(),this.disabled=!1,this.textColor=E.defaultTextColor.copy(),this.hoverColor=E.defaultHoverColor.copy(),this.lineColor=E.defaultLineColor.copy(),this.gradientColor=E.defaultGradientColor?E.defaultGradientColor.copy():void 0,this.lineWidth=E.defaultLineWidth,this.cornerRadius=E.defaultCornerRadius,this.font=E.defaultFont,this.fontStyle=void 0,this.textWidth=void 0,this.textHeight=void 0,this.textFitScale=E.defaultTextFitScale,this.textShadow=void 0,this.textLineColor=E.defaultLineColor.copy(),this.textLineWidth=0,this.visible=!0,this.children=[],this.parent=void 0,this.extraTouchSize=0,this.soundPress=E.defaultSoundPress,this.soundRelease=E.defaultSoundRelease,this.soundClick=E.defaultSoundClick,this.interactive=!1,this.dragActivate=!1,this.canBeHover=!0,this.shadowColor=(s=E.defaultShadowColor)==null?void 0:s.copy(),this.shadowBlur=E.defaultShadowBlur,this.shadowOffset=(i=E.defaultShadowOffset)==null?void 0:i.copy(),this.navigationIndex=void 0,this.navigationAutoSelect=!1,this.anchor=b(),E.uiObjects.push(this)}addChild(t){return f(!t.parent&&!this.children.includes(t)),this.children.push(t),t.parent=this,t}removeChild(t){f(t.parent===this&&this.children.includes(t)),this.children.splice(this.children.indexOf(t),1),t.parent=void 0}destroy(){var t;if(!this.destroyed){E.activeObject===this&&(E.activeObject=void 0),E.hoverObject===this&&(E.hoverObject=void 0),E.lastHoverObject===this&&(E.lastHoverObject=void 0),E.navigationObject===this&&(E.navigationObject=void 0),E.keyInputObject===this&&(E.keyInputObject=void 0),this.destroyed=1,(t=this.parent)==null||t.removeChild(this);for(let e of this.children)e.parent=void 0,e.destroy();this.children.length=0}}isMouseOverlapping(){if(!ti)return!1;let t=Zt?this.size.add(b(this.extraTouchSize||0)):this.size,e=E.screenToNative(Ft);return Hs(this.nativePos,t,e)}update(){if(this.onUpdate(),this.disabled&&(this===E.activeObject&&(E.activeObject=void 0),this===E.keyInputObject&&(E.keyInputObject=void 0)),E.keyInputObject)return;let t=E.lastHoverObject===this,e=this.isActiveObject(),s=ns(0),i=this.dragActivate?s:cs(0);this.canBeHover&&(E.navigationMode||(i||e||!s&&!Zt)&&!E.hoverObject&&this.isMouseOverlapping()&&(E.hoverObject=this)),this.isHoverObject()&&(this.disabled||(i&&this.interactive&&((!this.dragActivate||!t||cs(0))&&this.onPress(),this.soundPress&&this.soundPress.play(),E.activeObject&&!e&&E.activeObject.onRelease(),E.activeObject=this,E.activateOnPress&&this.click(!this.soundPress)),E.activateOnPress||!s&&this.isActiveObject()&&this.interactive&&this.click()),i&&wr(0,0,0,1,0)),e&&(!s||this.dragActivate&&!this.isHoverObject())&&(this.onRelease(),this.soundRelease&&this.soundRelease.play(),E.activeObject=void 0),this.isHoverObject()!==t&&(this.isHoverObject()?this.onEnter():this.onLeave())}render(){if(this.onRender(),!this.size.x||!this.size.y)return;let t=this.isNavigationObject(),e=t?this.color:this.interactive&&this.isActiveObject()&&!this.disabled?this.color:this.lineColor,s=t?this.hoverColor:this.disabled?this.disabledColor:this.interactive?this.isActiveObject()?this.activeColor||this.hoverColor:this.isHoverObject()?this.hoverColor:this.color:this.color,i=this.lineWidth*(t?1.5:1);E.drawRect(this.nativePos,this.size,s,i,e,this.cornerRadius,this.gradientColor,this.shadowColor,this.shadowBlur,this.shadowOffset)}getTextSize(){return b(this.textWidth||this.textFitScale*this.size.x,this.textHeight||this.textFitScale*this.size.y)}navigatePressed(){this.click()}isHoverObject(){return E.hoverObject===this}isActiveObject(){return E.activeObject===this}isNavigationObject(){return E.navigationObject===this}isKeyInputObject(){return E.keyInputObject===this}isInteractive(){return this.interactive&&this.visible&&!this.disabled}toString(){let t="type = "+this.constructor.name;return this.text&&(t+=`
 text = `+this.text),(this.nativePos.x||this.nativePos.y)&&(t+=`
 nativePos = `+this.nativePos),(this.localPos.x||this.localPos.y)&&(t+=`
 localPos = `+this.localPos),(this.size.x||this.size.y)&&(t+=`
 size = `+this.size),this.color&&(t+=`
-color = `+this.color),t}renderDebug(t=!0){let e=t?this.isHoverObject()?Xa:this.disabled?Ka:this.interactive?nr:$a:Ya;C.drawRect(this.nativePos,this.size,ue,4,e)}click(t=!0){this.onClick(),t&&this.soundClick&&this.soundClick.play()}onUpdate(){}onRender(){}onEnter(){}onLeave(){}onPress(){}onRelease(){}onClick(){}onChange(){}},gi=class extends se{constructor(t,e,s="",i="center",o=C.defaultFont){super(t,e),f(J(s),"ui text must be a string"),f(["left","center","right"].includes(i),"ui text align must be left, center, or right"),f(J(o),"ui text font must be a string"),this.text=s,this.align=i,this.font=o,this.canBeHover=!1,this.color=ue,this.shadowColor=ue,this.gradientColor=void 0,this.lineWidth=0,this.textFitScale=1}render(){super.render();let t=this.getTextSize();C.drawText(this.text,this.nativePos,t,this.textColor,this.textLineWidth,this.textLineColor,this.align,this.font,this.fontStyle,!0,this.textShadow,this.shadowColor,this.shadowBlur,this.shadowOffset)}},Lo=class extends se{constructor(t,e,s=""){super(t,e),f(J(s),"ui text must be a string"),this.maxLength=0,this.text=s,this.interactive=!0,this.canBeHover=!0}click(){C.keyInputObject=this,this.onClick()}stopEditing(){this.isKeyInputObject()&&(this.soundRelease&&this.soundRelease.play(),C.activeObject=void 0,C.keyInputObject=void 0,this.onChange())}onKeyDown(t){let e=t.code,s=t.key;e==="Backspace"?this.text=this.text.slice(0,-1):e==="Enter"||e==="Escape"?this.stopEditing():s.length===1&&(!this.maxLength||this.text.lengththis.size.y,s=e?this.size.y:this.size.x,i=e?this.size.x:this.size.y,o=e?this.nativePos.x:this.nativePos.y,r=i-s,a=o-r/2,c=o+r/2,l=C.screenToNative(jt);this.value=e?Mt(l.x,a,c):Mt(l.y,c,a)}else if(this.isNavigationObject()){let e=C.getNavigationOtherDirection();C.navigationTimer.active()||(this.value=F(this.value+e*.01))}this.value===t||this.onChange()}render(){super.render();let t=this.size.x>this.size.y,e=t?this.size.x:this.size.y,s=t?this.size.y:this.size.x;if(this.fillMode){let o=K(s,this.cornerRadius*2),r=zt(o,e,this.value),a=(r-e)*(t?.5:-.5),c=this.nativePos.add(t?x(a,0):x(0,a)),l=this.disabled?this.disabledColor:this.handleColor,u=t?x(r,this.size.y):x(this.size.x,r);C.drawRect(c,u,l,this.lineWidth,this.lineColor,this.cornerRadius,this.gradientColor)}else{let o=F(t?this.value:1-this.value),r=(e-s)*(o-.5),a=this.nativePos.add(t?x(r,0):x(0,r)),c=this.disabled?this.disabledColor:this.handleColor,l=x(s);C.drawRect(a,l,c,this.lineWidth,this.lineColor,this.cornerRadius,this.gradientColor)}let i=this.getTextSize();C.drawText(this.text,this.nativePos,i,this.textColor,this.textLineWidth,this.textLineColor,this.align,this.font,this.fontStyle,!0,this.textShadow)}navigatePressed(){this.value=this.value?0:1,this.onChange(),this.onRelease(),super.navigatePressed()}},Mo=class extends se{constructor(t,e,s,i=!1,o=!1,r=1){super(t,e||x()),f(J(s),"video src must be a string"),f(P(r),"video volume must be a number"),this.color=nt,this.cornerRadius=0,this.volume=r,this.video=document.createElement("video"),this.video.loop=o,this.video.volume=F(r*fn),this.video.muted=!Ut,this.video.style.display="none",this.video.src=s,document.body.appendChild(this.video),i&&this.play()}async play(){try{await this.video.play()}catch{}}pause(){this.video.pause()}stop(){this.video.pause(),this.video.currentTime=0}isLoading(){return this.video.readyState=1,"ui layout columns must be a number >= 1"),f(P(s),"ui layout gap must be a number"),f(P(i),"ui layout padding must be a number"),this.columns=e,this.gap=s,this.padding=i,o&&(this.color=ue,this.gradientColor=void 0,this.lineWidth=0,this.shadowColor=ue),this.relayout()}addChild(t){return super.addChild(t),this.relayout(),t}removeChild(t){super.removeChild(t),this.relayout()}relayout(){let t=this.children.length;if(!t){this.size=x(this.padding*2);return}let e=this.columns,s=is(t/e),i=new Array(e).fill(0),o=new Array(s).fill(0);for(let p=0;p=0&&m.objects.splice(t,1),super.destroy()}updatePhysics(){}render(){this.tileInfo?super.render():this.drawFixtures(this.color,this.lineColor,this.lineWidth)}renderDebugInfo(){let t=!this.getIsAwake(),e=this.getBodyType()===m.bodyTypeStatic,s=B(t?1:0,t?1:0,e?1:0,.5);this.drawFixtures(s)}drawFixtures(t=U,e=nt,s=.1,i,o){this.getFixtureList().forEach(r=>{m.castShapeObject(r.GetShape()).GetType()!==m.instance.b2Shape.e_edge&&m.drawFixture(r,this.pos,this.angle,t,e,s,i,o)}),this.edgeLists.forEach(r=>fo(r,s,e,!1,this.pos,this.angle)),this.edgeLoops.forEach(r=>fo(r,s,e,!0,this.pos,this.angle))}beginContact(t){}endContact(t){}addShape(t,e=1,s=.2,i=0,o=!1){f(P(e),"density must be a number"),f(P(s),"friction must be a number"),f(P(i),"restitution must be a number");let r=new m.instance.b2FixtureDef;return r.set_shape(t),r.set_density(e),r.set_friction(s),r.set_restitution(i),r.set_isSensor(o),this.body.CreateFixture(r)}addBox(t=x(1),e=x(),s=0,i,o,r,a){f(L(t),"size must be a Vector2"),f(t.x>0&&t.y>0,"size must be positive"),f(L(e),"offset must be a Vector2"),f(P(s),"angle must be a number");let c=new m.instance.b2PolygonShape;return c.SetAsBox(t.x/2,t.y/2,m.vec2dTo(e),-s),this.addShape(c,i,o,r,a)}addPoly(t,e,s,i,o){f(ce(t),"points must be an array");function r(c){f(3<=c.length&&c.length<=8);let l=m.instance._malloc(c.length*8);for(let p=0,d=0;p>2]=c[p].x,d+=4,m.instance.HEAPF32[l+d>>2]=c[p].y,d+=4;let u=m.instance.wrapPointer(l,m.instance.b2Vec2),h=new m.instance.b2PolygonShape;return h.Set(u,c.length),m.instance._free(l),h}let a=r(t);return this.addShape(a,e,s,i,o)}addRegularPoly(t=1,e=8,s,i,o,r){f(P(t)&&t>0,"diameter must be a positive number"),f(P(e)&&e>2,"sides must be a positive number greater than 2");let a=[],c=t/2;for(let l=e;l--;)a.push(x(c,0).rotate((l+.5)/e*q*2));return this.addPoly(a,s,i,o,r)}addRandomPoly(t=1,e,s,i,o){f(P(t)&&t>0,"diameter must be a positive number");let r=er(3,9),a=[],c=t/2;for(let l=r;l--;)a.push(x(dt(c/2,c*1.5),0).rotate(l/r*q*2));return this.addPoly(a,e,s,i,o)}addCircle(t=1,e=x(),s,i,o,r){f(P(t)&&t>0,"diameter must be a positive number"),f(L(e),"offset must be a Vector2");let a=new m.instance.b2CircleShape;return a.set_m_p(m.vec2dTo(e)),a.set_m_radius(t/2),this.addShape(a,s,i,o,r)}addEdge(t,e,s,i,o,r){f(L(t),"point1 must be a Vector2"),f(L(e),"point2 must be a Vector2");let a=new m.instance.b2EdgeShape;return a.Set(m.vec2dTo(t),m.vec2dTo(e)),this.addShape(a,s,i,o,r)}addEdgeList(t,e,s,i,o){f(ce(t),"points must be an array");let r=[],a=[];for(let c=0;ct[te(l,t.length)];for(let l=0;lthis.destroyFixture(t))}getCenterOfMass(){return m.vec2From(this.body.GetWorldCenter())}getLinearVelocity(){return m.vec2From(this.body.GetLinearVelocity())}getAngularVelocity(){return this.body.GetAngularVelocity()}getMass(){return this.body.GetMass()}getInertia(){return this.body.GetInertia()}getIsAwake(){return this.body.IsAwake()}getBodyType(){return this.body.GetType()}getSpeed(){return this.getLinearVelocity().length()}setTransform(t,e){this.pos=t,this.angle=e,this.body.SetTransform(m.vec2dTo(t),-e)}setPosition(t){this.setTransform(t,this.body.GetAngle())}setAngle(t){this.setTransform(m.vec2From(this.body.GetPosition()),t)}setLinearVelocity(t){this.body.SetLinearVelocity(m.vec2dTo(t))}setAngularVelocity(t){this.body.SetAngularVelocity(t)}setLinearDamping(t){this.body.SetLinearDamping(t)}setAngularDamping(t){this.body.SetAngularDamping(t)}setGravityScale(t=1){this.body.SetGravityScale(this.gravityScale=t)}setBullet(t=!0){this.body.SetBullet(t)}setAwake(t=!0){this.body.SetAwake(t)}setBodyType(t){this.body.SetType(t)}setSleepingAllowed(t=!0){this.body.SetSleepingAllowed(t)}setFixedRotation(t=!0){this.body.SetFixedRotation(t)}setCenterOfMass(t){this.setMassData(t)}setMass(t){this.setMassData(void 0,t)}setMomentOfInertia(t){this.setMassData(void 0,void 0,t)}resetMassData(){this.body.ResetMassData()}setMassData(t,e,s){let i=new m.instance.b2MassData;this.body.GetMassData(i),t!==void 0&&i.set_center(m.vec2dTo(t)),e!==void 0&&i.set_mass(e),s!==void 0&&i.set_I(s),this.body.SetMassData(i)}setFilterData(t=0,e=0,s=0){this.getFixtureList().forEach(i=>{let o=i.GetFilterData();o.set_categoryBits(t),o.set_maskBits(65535&~e),o.set_groupIndex(s)})}setSensor(t=!0){this.getFixtureList().forEach(e=>e.SetSensor(t))}applyForce(t,e){e||(e=this.getCenterOfMass()),this.setAwake(),this.body.ApplyForce(m.vec2dTo(t),m.vec2dTo(e))}applyAcceleration(t,e){e||(e=this.getCenterOfMass()),this.setAwake();let s=t.scale(this.getMass());this.body.ApplyLinearImpulse(m.vec2dTo(s),m.vec2dTo(e))}applyImpulse(t,e){e||(e=this.getCenterOfMass()),this.setAwake(),this.body.ApplyLinearImpulse(m.vec2dTo(t),m.vec2dTo(e))}applyTorque(t){this.setAwake(),this.body.ApplyTorque(t)}applyAngularAcceleration(t){this.setAwake(),this.body.ApplyAngularImpulse(t*this.getInertia())}applyAngularImpulse(t){this.setAwake(),this.body.ApplyAngularImpulse(t)}hasFixtures(){return!m.isNull(this.body.GetFixtureList())}getFixtureList(){let t=[];for(let e=this.body.GetFixtureList();!m.isNull(e);)t.push(e),e=e.GetNext();return t}hasJoints(){return!m.isNull(this.body.GetJointList())}getJointList(){let t=[];for(let e=this.body.GetJointList();!m.isNull(e);)t.push(e),e=e.get_next();return t}},yi=class extends Ss{constructor(t,e,s,i=0,o,r=0){let a=m.bodyTypeStatic;super(t,e,s,i,o,a,r)}},Go=class extends Ss{constructor(t,e,s,i=0,o,r=0){let a=m.bodyTypeKinematic;super(t,e,s,i,o,a,r)}},Fo=class extends yi{constructor(t){f(t instanceof ps,"tileLayer must be a TileCollisionLayer"),super(t.pos,t.size),this.tileLayer=t,this.addChild(t)}render(){}buildCollision(t=.2,e=0){this.destroyAllFixtures(),this.pos=this.tileLayer.pos.copy(),this.size=this.tileLayer.size.copy();let s=[],i=(r,a)=>r+a*this.size.x,o=(r,a)=>!s[i(r,a)]&&this.tileLayer.getCollisionData(x(r,a))>0;for(let r=0;ri.fractiono.pos.distanceSquared(t)0,"Tween duration must be > 0"),this.callback=t,this.start=e,this.end=s,this.duration=i,this.life=i,this.ease=o.ease||Si.LINEAR,this.useRealTime=!!o.useRealTime,this.paused=!!o.paused,this.thenCallback=void 0,this.loopRemaining=0,qt.push(this),t(this.interp(i))}setEase(t){return this.ease=t,this}then(t){return this.thenCallback=t,this.loopRemaining=0,this}loop(t=1/0){return this.loopRemaining=t,this.thenCallback=()=>_c(this),this}pingPong(t=1/0){return this.loopRemaining=t,this.thenCallback=()=>Rc(this),this}pause(){this.paused=!0}resume(){this.paused=!1}restart(){this.life=this.duration,this.paused=!1,qt.indexOf(this)<0&&qt.push(this),this.callback(this.interp(this.duration))}isActive(){return!this.paused&&qt.indexOf(this)>=0}getPercent(){return Mt(this.duration-this.life,0,this.duration)}getValue(){return this.interp(this.life)}interp(t){let e=this.ease((this.duration-t)/this.duration);return _a(this.start)?this.start.lerp(this.end,e):this.start+(this.end-this.start)*e}stop(){let t=qt.indexOf(this);t>=0&&qt.splice(t,1),this.thenCallback=void 0}},Si={LINEAR:n=>n,POWER:n=>t=>t**n,SINE:n=>1-ot(n*(q/2)),CIRC:n=>1-(1-n*n)**.5,EXPO:n=>n===0?0:2**(10*n-10),BACK:n=>n*n*(2.70158*n-1.70158),ELASTIC:n=>n===0?0:n===1?1:-(2**(10*n-10))*tt((37-40*n)*q/6),SPRING:n=>1-(tt(q*(1-n)*(.2+2.5*(1-n)**3))*n**2.2+(1-n))*(1+1.2*n),BOUNCE:n=>{let t=1-n,e;return t<4/11?e=7.5625*t*t:t<8/11?e=7.5625*(t-=6/11)*t+.75:t<10/11?e=7.5625*(t-=9/11)*t+.9375:e=7.5625*(t-=10.5/11)*t+.984375,1-e},IN:n=>n,OUT:n=>t=>1-n(1-t),IN_OUT:n=>Si.PIECEWISE(n,Si.OUT(n)),PIECEWISE:(...n)=>{let t=n.length;return e=>{let s=e*t-1e-9>>0;return(n[s]((e-s/t)*t)+s)/t}},BEZIER:(n,t,e,s)=>{let i=o=>{let r=1-o,a=3*r*r*o,c=3*r*o*o,l=o**3;return[a*n+c*e+l,a*t+c*s+l]};return o=>{let r=0,a=1;for(let c=0;c<128;c++){let l=(r+a)/2,[u,h]=i(l);if(Z(u-o)<1e-5)return h;u=this.size.x||e>=this.size.y?null:this.nodes[t+e*this.size.x]}worldToTile(t){let e=this.tileLayer?this.tileLayer.pos.x:0,s=this.tileLayer?this.tileLayer.pos.y:0;return x(vt(t.x-e),vt(t.y-s))}tileToWorld(t,e){let s=this.tileLayer?this.tileLayer.pos.x:0,i=this.tileLayer?this.tileLayer.pos.y:0;return x(t+.5+s,e+.5+i)}buildNodeData(){let t=this.size.x,e=this.size.y,s=this.tileLayer?this.tileLayer.pos.x:0,i=this.tileLayer?this.tileLayer.pos.y:0;for(let o=0;o0&&(c?l>0&&mt(a.posWorld,oo,B(1,0,0,K(.2,l*.05)),this.debugTime):mt(a.posWorld,oo,B(1,0,0,.25),this.debugTime))}}aStarSearch(t,e){f(t&&e,"aStarSearch needs both endpoints"),f(t!==e,"aStarSearch: start and end must differ \u2014 caller should handle trivial case"),f(t.walkable&&e.walkable,"aStarSearch: endpoints must be walkable");let s=[t];t.isOpen=!0;let i=0;for(;s.length>0;){let o=0,r=s[0].f;for(let c=1;cthis.maxLoop)break;a.isOpen=!1,s.splice(o,1),a.isClosed=!0,this.debug&&this.debugTime>0&&mt(a.posWorld,oo,B(1,1,1,.05),this.debugTime);for(let c=-1;c<=1;++c)for(let l=-1;l<=1;++l){if(l===0&&c===0)continue;let u=this.getNode(a.pos.x+l,a.pos.y+c);if(!u||!u.walkable||u.isClosed)continue;let h=1;if(l!==0&&c!==0){let v=this.getNode(a.pos.x+l,a.pos.y);if(!v||!v.walkable)continue;let S=this.getNode(a.pos.x,a.pos.y+c);if(!S||!S.walkable)continue;h=fd}let p=a.g+h+u.cost;if(!u.isOpen)u.isOpen=!0,s.push(u);else if(p>=u.g)continue;u.parent=a,u.g=p;let d=Z(e.pos.x-u.pos.x),y=Z(e.pos.y-u.pos.y),b=X(d,y)+(Math.SQRT2-1)*K(d,y);u.f=u.g+b*this.heuristicWeight}}return e.parent!==null}getNearestClearNode(t,e=10,s=!0){f(L(t),"worldPos must be a Vector2"),s&&this.buildNodeData();let i=this.tileLayer?this.tileLayer.pos.x:0,o=this.tileLayer?this.tileLayer.pos.y:0,r=vt(t.x-i),a=vt(t.y-o);for(let c=0;c<=e;++c){let l=null,u=0;for(let h=-c;h<=c;++h)for(let p=-c;p<=c;++p){if(c>0&&Z(p)!==c&&Z(h)!==c)continue;let d=this.getNode(r+p,a+h);if(!d||!d.isClear())continue;let y=d.posWorld.x-t.x,b=d.posWorld.y-t.y,v=y*y+b*b;(!l||v0&&Nt(i.posWorld,.3,B(.5,0,.5,.5),this.debugTime),t.splice(e,1),e=X(1,e-1);continue}else if(c===2){this.debug&&this.debugTime>0&&Nt(i.posWorld,.3,B(1,0,0,.5),this.debugTime);let d,y;s.pos.y===i.pos.y&&o.pos.x===i.pos.x?(d=s.pos.x,y=o.pos.y):(d=o.pos.x,y=s.pos.y);let b=this.getNode(d,y);if(b&&b.isClear()){t.splice(e,1),e=X(1,e-1);continue}}else if(c===5){this.debug&&this.debugTime>0&&Nt(i.posWorld,.3,B(1,1,0,.5),this.debugTime);let d=e>=2?t[e-2]:s,y,b,v,S;l===0||h===0?(y=o.pos.x,b=i.pos.y,v=s.pos.x,S=i.pos.y):(y=i.pos.x,b=o.pos.y,v=i.pos.x,S=s.pos.y);let _=y-d.pos.x,w=b-d.pos.y,E=v-d.pos.x,A=S-d.pos.y,T=_*_+w*w,R=E*E+A*A,M=T0&&Nt(i.posWorld,.3,B(0,1,0,.5),this.debugTime),l===h&&u===p){++e;continue}else{let d,y;s.pos.y===o.pos.y?(d=i.pos.x,y=s.pos.y):(d=s.pos.x,y=i.pos.y);let b=this.getNode(d,y);if(b&&b.isClear()){t[e]=b,e=X(1,e-1);continue}}++e}}smoothPathStringPull(t){if(t.length<=2)return;for(let i of t)if(!i.isClear())return;let e=t.slice();t.length=0,t.push(e[0]);let s=0;for(let i=1;i0&&xe(o.posWorld,t[t.length-1].posWorld,B(0,0,1,.3),.02,this.debugTime);continue}for(;s=1;--e){let s=t[e-1],i=t[e],o=t[e+1];(i.pos.x-s.pos.x)*(o.pos.y-s.pos.y)===(i.pos.y-s.pos.y)*(o.pos.x-s.pos.x)&&t.splice(e,1)}}isNodeClear(t,e){let s=this.getNode(t,e);return s!==null&&s.isClear()}isLineClear(t,e){f(L(t)&&L(e),"isLineClear needs Vector2 endpoints"),f(this.isNodeClear(t.x,t.y)&&this.isNodeClear(e.x,e.y),"isLineClear endpoints must be in-bounds and clear");let s=e.x-t.x,i=e.y-t.y,o=Z(s),r=Z(i),a=Zt(s),c=Zt(i),l=t.x,u=t.y;if(r===o){for(;l!==e.x;){if(l!==t.x&&(!this.isNodeClear(l,u)||!this.isNodeClear(l,u-c))||!this.isNodeClear(l,u+c))return!1;l+=a,u+=c}if(!this.isNodeClear(e.x,e.y-c))return!1}else if(ra.posWorld.copy());if(this.debug&&this.debugTime>0&&r.length>0){for(let a=1;apd,bootGameHost:()=>yd,default:()=>gd});var Is=class{constructor(t){this._state=(t==null?2654435769:t)>>>0}next(){this._state=this._state+1831565813>>>0;let t=this._state;return t=Math.imul(t^t>>>15,t|1),t^=t+Math.imul(t^t>>>7,t|61),((t^t>>>14)>>>0)/4294967296}range(t,e){return t+this.next()*(e-t)}reseed(t){this._state=(t==null?2654435769:t)>>>0}},ji=class{constructor(t){this._clock=t||Jc(),this._origin=this._clock()}nowMs(){return this._clock()}elapsedMs(){return this._clock()-this._origin}},Ni=class{constructor(t){this._time=t,this._subs=new Map}sourceFor(t){let e=this,s=t==null?null:t;return{on(i,o){if(e._assertType(i),typeof o!="function")throw new Error("[HostDevInputBridge] on \u7684 handler \u5FC5\u987B\u662F\u51FD\u6570");let r=e._subs.get(i)||[],a={handler:o,scope:s};return r.push(a),e._subs.set(i,r),{cancel(){let c=e._subs.get(i);if(!c)return;let l=c.indexOf(a);l>=0&&c.splice(l,1)}}},off(i,o){e._assertType(i);let r=e._subs.get(i);if(!r)return;let a=r.findIndex(c=>c.handler===o&&c.scope===s);a>=0&&r.splice(a,1)}}}_emit(t,e){this._assertType(t);let s=e||{},i={type:t,x:typeof s.x=="number"?s.x:0,y:typeof s.y=="number"?s.y:0,key:typeof s.key=="string"?s.key:"",tMs:this._time.nowMs()},o=this._subs.get(t);if(!o||o.length===0)return;let r=o.slice();for(let a of r)try{a.handler(i)}catch(c){ze("[host-dev input] \u8F93\u5165 handler \u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09type="+t,c)}}disposeScope(t){if(t==null)return 0;let e=0;for(let[s,i]of this._subs){let o=i.filter(r=>r.scope!==t);e+=i.length-o.length,o.length===0?this._subs.delete(s):this._subs.set(s,o)}return e}_subscriptionCount(){let t=0;for(let e of this._subs.values())t+=e.length;return t}_assertType(t){if(!Bi.has(t))throw new Error("[HostDevInputBridge] \u975E\u6CD5\u8F93\u5165\u4E8B\u4EF6\u7C7B\u578B\uFF1A"+String(t)+"\uFF08\u4EC5\u652F\u6301 "+Array.from(Bi).join("/")+"\uFF09")}},Bi=new Set(["pointerdown","pointermove","pointerup","keydown","keyup"]);function Wr(n){let t=n||{},e=new ji(t.clock),s=new Is(t.seed),i=t.seed==null?2654435769:t.seed>>>0,o=new Ni(e),r=typeof t.audioFactory=="function"?t.audioFactory:null,a=null,c=!1,l=typeof t.engineFactory=="function"?t.engineFactory:null,u=null,h=!1,p=new Map,d=0,y=0;function b(){if(a)return a;if(!r)return c||(Ji("[host-dev audio] \u672A\u6CE8\u5165 audioFactory\uFF0CgetAudioContext \u8FD4\u56DE null\uFF08P6 \u987B\u5BB9\u9519\u964D\u7EA7\uFF1B\u96C6\u6210\u6BB5\u6CE8\u5165\u771F\u5B9E\u5DE5\u5382\uFF09"),c=!0),null;try{a=r()}catch(E){ze("[host-dev audio] audioFactory \u629B\u9519\uFF0CgetAudioContext \u964D\u7EA7\u8FD4\u56DE null",E),a=null}return a}function v(){if(u)return u;if(!l)return h||(Ji("[host-dev engine] \u672A\u6CE8\u5165 engineFactory\uFF0CgetEngine \u8FD4\u56DE null\uFF08\u63D2\u4EF6\u987B\u5BB9\u9519\u964D\u7EA7\uFF1A\u7C92\u5B50\u9000\u53D7\u63A7\u9762\u81EA\u7BA1/\u5408\u6210\u6838\u9000 vendored/\u6570\u5B66\u9000\u5185\u7F6E\uFF1B\u96C6\u6210\u6BB5\u6CE8\u5165\u771F\u5B9E\u80CC\u4E66\uFF09"),h=!0),null;try{u=l()}catch(E){ze("[host-dev engine] engineFactory \u629B\u9519\uFF0CgetEngine \u964D\u7EA7\u8FD4\u56DE null",E),u=null}return u}function S(E,A){return{getContext2d(){return t.context2d==null?null:t.context2d},onFrame(R){let M=d++;return p.set(M,R),{cancel(){p.delete(M)}}},getInput(){return o.sourceFor(E)},getAudioContext(){return b()},getEngine(){return v()},time:e,random:A}}let _=S(null,s),w={context:_,tick(E){y+=1;let A=Array.from(p.values());for(let T of A)try{T(E,y)}catch(R){ze("[host-dev tick] \u5E27\u56DE\u8C03\u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09frame="+y,R)}},frameCount(){return y},inputBridge:o,deriveContextFor(E,A){let T=zc(i,E),R=new Is(T);return S(A==null?E:A,R)}};return Object.defineProperty(_,zi,{value:w,enumerable:!1,writable:!1,configurable:!1}),w}var zi=Symbol("zaomeng.coreProtocol.contextBundle"),Ms=class{constructor(){this._plugins=new Map,this._initOrder=[],this._initErrors=[],this._phase="idle",this._disposed=!1,this._context=void 0,this._pluginContexts=new Map}register(t){if(!t||typeof t!="object")throw new Error("[PluginRegistry] register \u9700\u8981\u4E00\u4E2A\u63D2\u4EF6\u5BF9\u8C61");if(typeof t.name!="string"||t.name.length===0)throw new Error("[PluginRegistry] \u63D2\u4EF6\u7F3A\u5C11\u5408\u6CD5 name");if(typeof t.version!="string"||t.version.length===0)throw new Error("[PluginRegistry] \u63D2\u4EF6 "+t.name+" \u7F3A\u5C11\u5408\u6CD5 version");if(typeof t.init!="function")throw new Error("[PluginRegistry] \u63D2\u4EF6 "+t.name+" \u7F3A\u5C11 init \u51FD\u6570");if(t.dispose!=null&&typeof t.dispose!="function")throw new Error("[PluginRegistry] \u63D2\u4EF6 "+t.name+" \u7684 dispose \u5FC5\u987B\u662F\u51FD\u6570\u6216\u7701\u7565");if(this._plugins.has(t.name))throw new Error("[PluginRegistry] \u63D2\u4EF6\u91CD\u540D\u62D2\u7EDD\uFF1A"+t.name+" \u5DF2\u6CE8\u518C");return this._plugins.set(t.name,t),this}has(t){return this._plugins.has(t)}get(t){return this._plugins.get(t)}list(){return Array.from(this._plugins.keys())}initAll(){if(this._phase==="initialized")return Ji("[PluginRegistry] initAll \u91CD\u590D\u8C03\u7528\uFF0C\u5DF2\u5FFD\u7565\uFF08\u5DF2\u5904\u4E8E initialized\uFF09"),this._initResult();if(this._phase==="disposed")throw new Error("[PluginRegistry] \u5DF2 dispose \u7684\u6CE8\u518C\u5668\u4E0D\u53EF\u518D initAll");if(this._context==null)throw new Error("[PluginRegistry] \u672A\u6CE8\u5165\u53D7\u63A7\u4E0A\u4E0B\u6587\uFF1A\u8BF7\u5728 initAll() \u4E4B\u524D\u8C03\u7528 useContext(context)\u3002\uFF08host-dev \u7528\u6CD5\uFF1Aconst { context } = createHostDevContext(); reg.useContext(context); reg.initAll();\uFF09");for(let[t,e]of this._plugins){let s=this._missingDeps(e);if(s.length>0){let o=new Error("[PluginRegistry] \u63D2\u4EF6 "+t+" \u4F9D\u8D56\u7F3A\u5931\uFF1A"+s.join(", ")+"\uFF08\u672A\u6CE8\u518C\uFF09");this._initErrors.push({name:t,error:o}),ze("[PluginRegistry] \u8DF3\u8FC7 init\uFF08\u4F9D\u8D56\u7F3A\u5931\uFF0C\u5DF2\u9694\u79BB\uFF09\uFF1A"+t,o);continue}let i=this._contextFor(t);try{e.init(i),this._initOrder.push(t)}catch(o){let r=o instanceof Error?o:new Error(String(o));this._initErrors.push({name:t,error:r}),ze("[PluginRegistry] \u63D2\u4EF6 init \u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF0C\u4E0D\u8FDE\u5750\uFF09\uFF1A"+t,r)}}return this._phase="initialized",this._initResult()}_contextFor(t){let e=this._pluginContexts.get(t);if(e)return e;let s=this._context&&this._context[zi],i;return s&&typeof s.deriveContextFor=="function"?i=s.deriveContextFor(t,t):i=this._context,this._pluginContexts.set(t,i),i}disposeAll(){if(this._disposed)return{disposed:[],errors:[]};let t=[],e=[],s=this._context&&this._context[zi],i=s&&s.inputBridge;for(let o=this._initOrder.length-1;o>=0;o--){let r=this._initOrder[o],a=this._plugins.get(r);if(a&&typeof a.dispose=="function")try{a.dispose(),t.push(r)}catch(c){let l=c instanceof Error?c:new Error(String(c));e.push({name:r,error:l}),ze("[PluginRegistry] \u63D2\u4EF6 dispose \u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09\uFF1A"+r,l)}if(i&&typeof i.disposeScope=="function")try{i.disposeScope(r)}catch(c){ze("[PluginRegistry] \u56DE\u6536\u63D2\u4EF6\u8F93\u5165\u8BA2\u9605\u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09\uFF1A"+r,c)}}return this._disposed=!0,this._phase="disposed",{disposed:t,errors:e}}useContext(t){if(this._phase!=="idle")throw new Error("[PluginRegistry] useContext \u5FC5\u987B\u5728 initAll() \u4E4B\u524D\u8C03\u7528\uFF08\u5F53\u524D\u9636\u6BB5\uFF1A"+this._phase+"\uFF09\u3002\u8BF7\u5728\u4EFB\u4F55 initAll/disposeAll \u4E4B\u524D\u6CE8\u5165\u53D7\u63A7\u4E0A\u4E0B\u6587\u3002");if(t==null||typeof t!="object")throw new Error("[PluginRegistry] useContext \u9700\u8981\u4E00\u4E2A\u53D7\u63A7\u4E0A\u4E0B\u6587\u5BF9\u8C61\u3002\uFF08host-dev \u7528\u6CD5\uFF1Aconst { context } = createHostDevContext(); reg.useContext(context);\uFF09");return this._context=t,this}_missingDeps(t){return!Array.isArray(t.dependencies)||t.dependencies.length===0?[]:t.dependencies.filter(e=>!this._plugins.has(e))}_initResult(){return{ok:this._initErrors.length===0,initialized:this._initOrder.slice(),errors:this._initErrors.slice()}}};function zc(n,t){let e=2166136261,s=16777619,i=n>>>0;for(let r=0;r<32;r+=8){let a=i>>>r&255;e^=a,e=Math.imul(e,s)>>>0}let o=String(t);for(let r=0;r>>0,e^=a>>>8&255,e=Math.imul(e,s)>>>0}return e>>>0}function Jc(){if(typeof globalThis!="undefined"&&globalThis.performance&&typeof globalThis.performance.now=="function")return()=>globalThis.performance.now();if(typeof process!="undefined"&&process.hrtime&&typeof process.hrtime.bigint=="function"){let n=process.hrtime.bigint();return()=>Number(process.hrtime.bigint()-n)/1e6}return()=>Date.now()}function ze(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function Ji(n){typeof console!="undefined"&&typeof console.warn=="function"&&console.warn(n)}var xd=Object.freeze(Array.from(Bi)),qr="core-protocol-v0";var Hr=Object.freeze(["t_boot","t_plugins_ready","t_game_init","t_first_paint","t_input_bound","t_game_start"]),Ui=Hr.reduce((n,t,e)=>(n[t]=e,n),Object.create(null)),Uc=new Set(Hr);function Vi(n){let t=2166136261;for(let e=0;e>>0).toString(16).padStart(8,"0")}var Xr=Vi("runtime-probe::seed::v1");function ks(n){return n===null||typeof n!="object"?JSON.stringify(n):Array.isArray(n)?"["+n.map(ks).join(",")+"]":"{"+Object.keys(n).sort().map(e=>JSON.stringify(e)+":"+ks(n[e])).join(",")+"}"}function Yr(n){let t=ks(n.extra==null?null:n.extra),e=ks(Array.isArray(n.pluginSet)?n.pluginSet:[]);return["seq="+n.seq,"anchor="+n.anchor,"tMono="+n.tMono,"buildSha="+(n.buildSha||""),"pluginSet="+e,"extra="+t].join("|")}function Vc(n){return Math.round(n*1e3)/1e3}function Wc(n){if(!Array.isArray(n))return{ok:!1,reason:"records_not_array"};let t=Xr,e=-1;for(let s=0;stypeof E=="string").slice().sort():[],i=typeof t.sink=="function"?t.sink:null,o=t.autoBoot!==!1,r=typeof t.inputAnchorType=="string"?t.inputAnchorType:"pointerdown",a=()=>0,c=!1,l=0,u=Xr,h=[],p=new Set,d=-1,y=null,b=!1,v=!1,S=!1;function _(E,A){let T=null;if(!Uc.has(E))T="unknown_anchor";else{p.has(E)&&(T=T?T+";duplicate_anchor":"duplicate_anchor");let M=Ui[E];ME.time.nowMs(),c=!0,o&&!v&&_("t_boot",{auto:!0}),y=E.getInput().on(r,A=>{b||(b=!0,_("t_input_bound",{firstInput:!0,type:A.type}))}),_("t_input_bound",{stage:"registered",type:r})},dispose(){S||(y&&(y.cancel(),y=null),S=!0)},mark:_,getRecords(){return h.map(E=>({...E}))},toJSONL(){return h.map(E=>JSON.stringify(E)).join(`
-`)},verify(){return Wc(h)}}}function qc(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function Kr(n){let t=n.LJS,e=n.engineMath,s=n.engineMode,i=n.recHook||(()=>{});if(s!=="real")return null;let o=e;return{math:{lerp:(a,c,l)=>(i("math.lerp"),o.lerp(a,c,l)),smoothStep:a=>(i("math.smoothStep"),o.smoothStep(a)),easing:Object.fromEntries(Object.keys(o.easing).map(a=>[a,c=>(i("math.easing."+a),o.easing[a](c))]))},particles:{spawnEmitter(a){i("particles.spawnEmitter");let c=t.screenToWorld(t.vec2(a.pos.x,a.pos.y)),l=t.cameraScale,u=a.emitTime!=null?a.emitTime:a.count!=null?1/60:0,h=a.emitRate!=null?a.emitRate:a.count!=null?a.count*60:100,p=(a.speed!=null?a.speed:0)/l/60,d=a.damping!=null?a.damping:1,y=a.colorStart||{r:1,g:1,b:1,a:1},b=a.colorEnd||{r:1,g:1,b:1,a:0},v=t.rgb(y.r,y.g,y.b,y.a),S=t.rgb(b.r,b.g,b.b,b.a),_=new t.ParticleEmitter(c,a.angle!=null?a.angle:0,(a.emitSize!=null?a.emitSize:0)/l,u,h,a.coneAngle!=null?a.coneAngle:Math.PI,void 0,v,v,S,S,a.particleTime!=null?a.particleTime:.5,(a.sizeStart!=null?a.sizeStart:6)/l,(a.sizeEnd!=null?a.sizeEnd:0)/l,p,0,d,1,a.gravityScale!=null?a.gravityScale:0,Math.PI,.1,0,!1,a.additive!=null?a.additive:!1,!0);return{isActive(){return _.isActive()},stop(){_.destroyed||_.destroy(!0)}}}},audio:{synth:{synthSfx:a=>{i("audio.synth.synthSfx");try{return t.zzfxG(...a)}catch(c){return console.error("[host][engine-audio] zzfxG \u5408\u6210\u5F02\u5E38\uFF0C\u8FD4 null\uFF1A"+(c&&c.message?c.message:c)),null}},synthSong:(a,c,l,u)=>{i("audio.synth.synthSong");try{return t.zzfxM(a,c,l,u)}catch(h){return console.error("[host][engine-audio] zzfxM \u5408\u6210\u5F02\u5E38\uFF0C\u8FD4 null\uFF1A"+(h&&h.message?h.message:h)),null}}}}}}function ie(n){return n<0?0:n>1?1:n}function Qr(n){let t=n.Ease,e=t.POWER(2),s=t.POWER(3),i=t.OUT(e),o=t.IN_OUT(e),r=t.OUT(s),a=t.IN_OUT(s),c=t.OUT(t.BACK),l=t.OUT(t.ELASTIC);return{lerp:(u,h,p)=>n.lerp(u,h,p),smoothStep:u=>n.smoothStep(u),easing:{linear:u=>t.LINEAR(ie(u)),quadIn:u=>e(ie(u)),quadOut:u=>i(ie(u)),quadInOut:u=>o(ie(u)),cubicIn:u=>s(ie(u)),cubicOut:u=>r(ie(u)),cubicInOut:u=>a(ie(u)),backIn:u=>t.BACK(ie(u)),backOut:u=>c(ie(u)),elasticIn:u=>t.ELASTIC(ie(u)),elasticOut:u=>l(ie(u))}}}var Je=2,Gs=1/60;async function Zr(n){let t=n.canvas,e=n.statusEl||null,s=n.engine,i=n.seed>>>0,o=n.mode||"play",r=n.engineMode||"real",a=n.viewport.w,c=n.viewport.h,l=n.factory,u=n.buildFactoryOpts||(()=>{}),h=n.plugins||{},p=n.registerOrder||Object.values(h),d=n.onReady||(()=>{}),y=n.recHook||(()=>{});function b(O){e&&(e.textContent=O)}let v=[];window.addEventListener("error",O=>v.push({type:"error",message:String(O&&O.message||O)})),window.addEventListener("unhandledrejection",O=>v.push({type:"unhandledrejection",message:String(O&&O.reason&&O.reason.message||O&&O.reason||O)}));let S=null,_=!1;function w(){if(!_)return null;if(S)return S;let O=window.AudioContext||window.webkitAudioContext;return O?(S=new O,S):null}let E=0,A=null,T=null,R=null,M=null,ct=[],et={},lt=null;function gt(O,rt){try{R&&R.mark(O,rt)}catch(Kt){v.push({type:"mark",message:String(Kt&&Kt.message||Kt)})}}function kt(){T&&typeof T._refreshChecklist=="function"&&T._refreshChecklist(et)}async function Ee(O,rt){A=Wr({context2d:O,seed:i,audioFactory:w,clock:()=>E,engineFactory:()=>Kr({LJS:r==="real"?s:null,engineMath:r==="real"?Qr(s):null,engineMode:r,recHook:y})});let Kt=new Ms;for(let fe of p)Kt.register(fe);Kt.useContext(A.context),M=Kt.initAll(),ct=Kt.list().concat(["runtime-probe"]),R=$r({pluginSet:ct,inputAnchorType:"pointerdown",autoBoot:!0});let Qt=A.deriveContextFor("runtime-probe","runtime-probe");gt("t_boot",{by:"game-host",stage:"pre-init",engineMode:r}),gt("t_plugins_ready",{initialized:M.initialized.length,ok:M.ok});let Gi=u(A.context,{bundle:A,plugins:h,getRealAudioCtx:()=>S});T=l(Gi),await T.init({ctx:A.context,mainContext:O,canvas:rt(),seed:i}),lt=T&&typeof T._forensicsView=="function"?T._forensicsView():null,gt("t_game_init",{hasForensics:!!lt}),ut(),gt("t_first_paint",{frame:A.frameCount()});try{R.init(Qt)}catch(fe){v.push({type:"probe-init",message:String(fe&&fe.message||fe)})}gt("t_game_start",{mode:o,engineMode:r}),kt(),d(N,{bundle:A,game:T,probe:R,checklist:et,uncaught:v,pluginSet:ct,initRes:M,getGameForensics:()=>lt,mark:gt,stepOneFrame:ut})}let Gt=null;function ut(O){let rt=typeof O=="number"?O:Gs;T&&(E+=rt*1e3,T.update(rt),r==="stub"&&Gt&&T.render(Gt),kt())}function Rt(O){for(let rt=0;rt{}),T&&typeof T._onAudioUnlock=="function"&&T._onAudioUnlock()}let N={seed:i,mode:o,engineMode:r,protocol:qr,frameCount:()=>A?A.frameCount():0,stepFrames:Rt,startRaf:()=>An(),stopRaf:()=>Cn(),tap(O,rt){I(),A&&(A.inputBridge._emit("pointerdown",{x:O,y:rt}),A.inputBridge._emit("pointerup",{x:O,y:rt}))},do(O){T&&typeof T._handleAction=="function"&&T._handleAction(O)},state:()=>lt?lt.state():{phase:"booting"}};function Y(O){let rt=A.inputBridge;function Kt(Qt,Gi){let fe=O.getBoundingClientRect();return{x:(Qt-fe.left)/fe.width*a,y:(Gi-fe.top)/fe.height*c}}O.addEventListener("pointerdown",Qt=>{I(),rt._emit("pointerdown",Kt(Qt.clientX,Qt.clientY))}),O.addEventListener("pointermove",Qt=>{rt._emit("pointermove",Kt(Qt.clientX,Qt.clientY))}),O.addEventListener("pointerup",Qt=>{rt._emit("pointerup",Kt(Qt.clientX,Qt.clientY))})}let ht=0,it=!1,Pt=0;function he(O){if(!it)return;Pt===0&&(Pt=O);let rt=(O-Pt)/1e3;Pt=O,rt>.05&&(rt=.05),ut(rt),ht=window.requestAnimationFrame(he)}function An(){r==="stub"&&(it||(it=!0,Pt=0,ht=window.requestAnimationFrame(he)))}function Cn(){it=!1,ht&&window.cancelAnimationFrame(ht),ht=0}function En(O){O.width=a*Je,O.height=c*Je,O.style.width=a+"px",O.style.height=c+"px";let rt=O.getContext("2d",{willReadFrequently:!0});return rt.setTransform(Je,0,0,Je,0,0),rt}async function de(){let O=En(t);return Gt=O,await Ee(O,()=>t),Y(t),o==="evidence"?b(`evidence \u5C31\u7EEA seed=${i} \xB7 \u7528 host \u9A71\u52A8\uFF08stepFrames/tap\uFF09`):(b(`seed=${i} \xB7 \u70B9\u5F00\u59CB\uFF08\u9996\u6B21\u70B9\u51FB\u5F00\u58F0\uFF09`),An()),N}let $t=()=>{},Hn=()=>{};function Os(){window.__gameHostEngineInitFired=!0}function Ds(){$t()}function Ur(){}function Dc(){Hn()}function Ic(){}async function Mc(O){await Ee(O,()=>s.mainCanvas),Y(s.mainCanvas),$t=()=>{T&&(E+=Gs*1e3,T.update(Gs))},Hn=()=>{if(T){O.save(),O.setTransform(Je,0,0,Je,0,0);try{O.imageSmoothingEnabled=!1}catch{}T.render(O),O.restore()}},s.mainCanvas&&(s.mainCanvas.id="game-engine"),window.__engine={frame(){return s.frame},time(){return s.time},timeReal(){return s.timeReal},paused(){return s.paused},timeScale(){return s.timeScale},snapshot(){return{frame:s.frame,time:s.time,timeReal:s.timeReal,paused:s.paused,timeScale:s.timeScale}}},b(`engine RAF running \xB7 seed=${i} engine=real`)}if(r!=="real")return await de();if(!s){let O="real \u901A\u9053\u672A\u6CE8\u5165\u5F15\u64CE\uFF08opts.engine \u7F3A\u5931\uFF09\uFF1A\u8BF7\u7ECF entry \u5305\u88C5\u5C42\u542F\u52A8\uFF08host \u4E0D\u76F4\u63A5 import \u5F15\u64CE\uFF0CQ4/Option C\uFF09";throw b("ENGINE INJECT MISSING: "+O),new Error(O)}s.setGLEnable(!1),s.setShowSplashScreen(!1),s.setDebugWatermark(!1),s.setCanvasClearColor(s.BLACK),s.setCanvasFixedSize(s.vec2(a*Je,c*Je));let ki=document.createElement("div");return ki.id="engine-root",document.body.appendChild(ki),await s.engineInit(Os,Ds,Ur,Dc,Ic,[],ki).then(()=>Mc(s.mainContext)).catch(O=>{throw window.__gameHostBootError=String(O&&O.message||O),b("ENGINE INIT FAILED: "+window.__gameHostBootError),O}),N}var Wi=class{constructor(t){let e=t||{},s=typeof e.cellSize=="number"&&e.cellSize>0?e.cellSize:64;this._cellSize=s,this._cells=new Map,this._entries=new Map,this._seq=0}get size(){return this._entries.size}_cellRange(t){let e=this._cellSize,s=Math.floor((t.x-t.hw)/e),i=Math.floor((t.x+t.hw)/e),o=Math.floor((t.y-t.hh)/e),r=Math.floor((t.y+t.hh)/e);return{cx0:s,cy0:o,cx1:i,cy1:r}}insert(t,e){this._entries.has(t)&&this.remove(t);let{cx0:s,cy0:i,cx1:o,cy1:r}=this._cellRange(e),a=[];for(let l=i;l<=r;l++)for(let u=s;u<=o;u++){let h=u+","+l,p=this._cells.get(h);p||(p=new Set,this._cells.set(h,p)),p.add(t),a.push(h)}let c={x:e.x,y:e.y,hw:e.hw,hh:e.hh};this._entries.set(t,{id:t,box:c,seq:this._seq++,cells:a})}remove(t){let e=this._entries.get(t);if(!e)return!1;for(let s of e.cells){let i=this._cells.get(s);i&&(i.delete(t),i.size===0&&this._cells.delete(s))}return this._entries.delete(t),!0}query(t){let{cx0:e,cy0:s,cx1:i,cy1:o}=this._cellRange(t),r=new Set;for(let a=s;a<=o;a++)for(let c=e;c<=i;c++){let l=this._cells.get(c+","+a);if(l)for(let u of l)r.add(u)}return this._collect(r)}queryPoint(t,e){let s=this._cellSize,i=Math.floor(t/s),o=Math.floor(e/s),r=this._cells.get(i+","+o);return r?this._collect(new Set(r)):[]}clear(){this._cells.clear(),this._entries.clear(),this._seq=0}_collect(t){let e=[];for(let s of t){let i=this._entries.get(s);i&&e.push(i)}return e.sort((s,i)=>s.seq-i.seq),e.map(s=>({id:s.id,box:s.box}))}};function ta(n){let t=n||{},e=new Wi({cellSize:t.cellSize}),s=!1;return{name:"collision",version:"1.0.0",dependencies:[],spatial:e,init(o){},dispose(){s||(e.clear(),s=!0)}}}function ea(n){let t=!1;return{name:"physics-lite",version:"1.0.0",dependencies:[],init(s){},dispose(){t||(t=!0)}}}var Hc=["pointerdown","pointermove","pointerup","keydown","keyup"];function Ft(n){return n<0?0:n>1?1:n}var Xc=n=>(n=Ft(n),n*n),Yc=n=>(n=Ft(n),1-(1-n)*(1-n)),$c=n=>(n=Ft(n),n<.5?2*n*n:1-Math.pow(-2*n+2,2)/2),Kc=n=>(n=Ft(n),n*n*n),Qc=n=>{n=Ft(n);let t=1-n;return 1-t*t*t},Zc=n=>(n=Ft(n),n<.5?4*n*n*n:1-Math.pow(-2*n+2,3)/2),ia=2*Math.PI/3,na=2*Math.PI/4.5,tl=n=>(n=Ft(n),n===0?0:n===1?1:-Math.pow(2,10*n-10)*Math.sin((n*10-10.75)*ia)),el=n=>(n=Ft(n),n===0?0:n===1?1:Math.pow(2,-10*n)*Math.sin((n*10-.75)*ia)+1),nl=n=>(n=Ft(n),n===0?0:n===1?1:n<.5?-(Math.pow(2,20*n-10)*Math.sin((20*n-11.125)*na))/2:Math.pow(2,-20*n+10)*Math.sin((20*n-11.125)*na)/2+1),js=1.70158,Fs=js*1.525,oa=js+1,sl=n=>(n=Ft(n),oa*n*n*n-js*n*n),il=n=>{n=Ft(n);let t=n-1;return 1+oa*t*t*t+js*t*t},ol=n=>(n=Ft(n),n<.5?Math.pow(2*n,2)*((Fs+1)*2*n-Fs)/2:(Math.pow(2*n-2,2)*((Fs+1)*(n*2-2)+Fs)+2)/2),rl=n=>Ft(n),sa=Object.freeze({linear:rl,quadIn:Xc,quadOut:Yc,quadInOut:$c,cubicIn:Kc,cubicOut:Qc,cubicInOut:Zc,elasticIn:tl,elasticOut:el,elasticInOut:nl,backIn:sl,backOut:il,backInOut:ol});var al=["linear","quadIn","quadOut","quadInOut","cubicIn","cubicOut","cubicInOut","elasticIn","elasticOut","elasticInOut","backIn","backOut","backInOut"];function cl(n){let t=n&&n.easing;if(!t)return sa;let e=i=>typeof t[i]=="function"?o=>t[i](Ft(o)):sa[i],s={};for(let i of al)s[i]=e(i);return Object.freeze(s)}var qi=class{constructor(t,e,s){let i=s||{};this._time=e,this._windowMs=typeof i.windowMs=="number"&&i.windowMs>0?i.windowMs:120;let o=Array.isArray(i.types)&&i.types.length>0?i.types:Hc;this._records=new Map,this._subs=[],this._disposed=!1;for(let r of o){this._records.set(r,null);let a=t.on(r,c=>{this._records.set(r,c.tMs)});this._subs.push(a)}}consume(t,e){let s=typeof e=="number"?e:this._time.nowMs(),i=this._records.get(t);return i==null?!1:s-i<=this._windowMs?(this._records.set(t,null),!0):(this._records.set(t,null),!1)}peek(t,e){let s=typeof e=="number"?e:this._time.nowMs(),i=this._records.get(t);return i==null?!1:s-i<=this._windowMs}clear(){for(let t of this._records.keys())this._records.set(t,null)}dispose(){if(!this._disposed){for(let t of this._subs)try{t.cancel()}catch(e){}this._subs=[],this._disposed=!0}}};function ra(n){let t=n||{},e=null,s=null,i=!1;return{name:"gamefeel",version:"1.0.0",dependencies:[],get inputBuffer(){return e},get easing(){return cl(s)},init(r){let a=r.getInput();e=new qi(a,r.time,{windowMs:t.inputBufferMs,types:t.inputTypes});let c=r.getEngine();s=c?c.math:null},dispose(){i||(e&&(e.dispose(),e=null),s=null,i=!0)}}}function Ns(n,t){let e=t<0?0:t>1?1:t;switch(n&&n.kind){case"constant":return n.value;case"linear":return n.from+(n.to-n.from)*e;case"easeInOut":{let s=e*e*(3-2*e);return n.from+(n.to-n.from)*s}case"decay":{let s=n.power==null?2:n.power,i=Math.pow(1-e,s);return n.to+(n.from-n.to)*i}default:return 0}}var ll=Object.freeze({burst:Object.freeze({mode:"burst",count:24,angle:0,spread:Math.PI,speedMin:80,speedMax:160,lifeMin:.4,lifeMax:.8,gravity:0,drag:0,sizeCurve:{kind:"decay",from:6,to:0,power:1.5},alphaCurve:{kind:"linear",from:1,to:0}}),trail:Object.freeze({mode:"continuous",rate:60,angle:Math.PI,spread:.25,speedMin:20,speedMax:50,lifeMin:.2,lifeMax:.5,gravity:0,drag:1.5,sizeCurve:{kind:"easeInOut",from:4,to:0},alphaCurve:{kind:"decay",from:.8,to:0,power:2}}),drift:Object.freeze({mode:"continuous",rate:12,angle:Math.PI/2,spread:.6,speedMin:10,speedMax:30,lifeMin:1.5,lifeMax:3,gravity:8,drag:.5,sizeCurve:{kind:"constant",value:3},alphaCurve:{kind:"decay",from:.7,to:0,power:1}})});function ul(n){let t=ll[n];return t?Hi(t):null}function Hi(n){let t={};for(let e of Object.keys(n)){let s=n[e];t[e]=s&&typeof s=="object"?Hi(s):s}return t}function hl(n,t,e){let s=n.mode==="continuous";return{pos:{x:t,y:e},angle:n.angle,coneAngle:n.spread,emitSize:0,emitTime:s?0:1/60,emitRate:s?n.rate||0:void 0,count:s?void 0:n.count||0,particleTime:(n.lifeMin+n.lifeMax)/2,speed:(n.speedMin+n.speedMax)/2,gravityScale:n.gravity||0,damping:n.drag!=null?1-n.drag/60:1,sizeStart:Ns(n.sizeCurve,0),sizeEnd:Ns(n.sizeCurve,1),colorStart:{r:1,g:1,b:1,a:Ns(n.alphaCurve,0)},colorEnd:{r:1,g:1,b:1,a:Ns(n.alphaCurve,1)},additive:!1}}function aa(n){let t=n||{},e=null,s=null,i=null,o=new Map,r=0,a={isActive(){return!1},stop(){}},c=0,l=1,u=0,h=0,p=0,d={x:0,y:0,remain:0,dur:0,amplitude:0,frequency:0,_phase:0},y={alpha:0,remain:0,dur:0,peak:0},b={scale:1,remain:0,dur:0,amplitude:0,frequency:0},v=!1;function S(A){if(u>0)if(u-=A,u<=0)u=0,l=1;else{let T=h>0?1-u/h:1;l=p+(1-p)*T}if(d.remain>0)if(d.remain-=A,d.remain<=0)d.remain=0,d.x=0,d.y=0;else{let T=d.remain/d.dur,R=d.amplitude*T;d._phase+=d.frequency*A*Math.PI*2,d.x=Math.sin(d._phase)*R,d.y=Math.cos(d._phase*1.3)*R}if(y.remain>0&&(y.remain-=A,y.remain<=0?(y.remain=0,y.alpha=0):y.alpha=y.peak*(y.remain/y.dur)),b.remain>0)if(b.remain-=A,b.remain<=0)b.remain=0,b.scale=1;else{let T=b.remain/b.dur,R=(1-T)*b.frequency*Math.PI*2;b.scale=1+Math.sin(R)*b.amplitude*T}}function _(A){c+=1,S(A)}function w(A){let T=A!==void 0?A:e?e.getContext2d():null;if(T&&y.alpha>0){T.globalAlpha=y.alpha,T.fillStyle="#ffffff";let R=T.canvas?T.canvas.width:0,M=T.canvas?T.canvas.height:0;T.fillRect(0,0,R,M),T.globalAlpha=1}}return{name:"particles-juice",version:"1.0.0",dependencies:[],init(A){var T;e=A,i=((T=A.getEngine())==null?void 0:T.particles)||null,typeof t.seed=="number"&&A.random.reseed(t.seed),t.autoStep!==!1&&(s=A.onFrame(R=>{_(R)}))},dispose(){v||(s&&(s.cancel(),s=null),o.forEach(A=>{try{A.stop()}catch{}}),o.clear(),l=1,u=0,d.remain=0,d.x=0,d.y=0,y.remain=0,y.alpha=0,b.remain=0,b.scale=1,v=!0)},spawnEmitter(A,T,R,M){let ct=typeof A=="string"?ul(A):Hi(A);if(!ct)return-1;M&&(ct=Object.assign(ct,M));let et=r++;if(!i)return o.set(et,a),et;let lt=i.spawnEmitter(hl(ct,T,R));return o.set(et,lt),et},stopEmitter(A){let T=o.get(A);if(T)try{T.stop()}catch{}},step(A){_(A)},render(A){w(A)},particleCount(){return 0},emitterCount(){let A=0;for(let T of o.values())T.isActive()&&(A+=1);return A},hitStop(A,T){h=Math.max(0,A),u=h,p=T==null?0:Math.max(0,Math.min(1,T)),l=h>0?p:1},getTimeScale(){return l},shakeScreen(A,T,R){d.dur=Math.max(0,A),d.remain=d.dur,d.amplitude=Math.max(0,T),d.frequency=R==null?30:R,d._phase=0,d.x=0,d.y=0},getShakeOffset(){return{x:d.x,y:d.y}},flashScreen(A,T){y.dur=Math.max(0,A),y.remain=y.dur,y.peak=T==null?.8:Math.max(0,Math.min(1,T)),y.alpha=y.dur>0?y.peak:0},getFlashAlpha(){return y.alpha},pulseScale(A,T,R){b.dur=Math.max(0,A),b.remain=b.dur,b.amplitude=T==null?.2:T,b.frequency=R==null?4:R,b.scale=1},getPulseScale(){return b.scale},juiceSnapshot(){return{timeScale:l,shake:{x:d.x,y:d.y},flashAlpha:y.alpha,pulseScale:b.scale}},probe(){return{particles:0,emitters:o.size,dropped:0,steps:c,disposed:v}}}}function ca(n){let t=pt(n.r)/255,e=pt(n.g)/255,s=pt(n.b)/255,i=Math.max(t,e,s),o=Math.min(t,e,s),r=(i+o)/2,a=0,c=0,l=i-o;return l>1e-12&&(c=r>.5?l/(2-i-o):l/(i+o),i===t?a=(e-s)/l%6:i===e?a=(s-t)/l+2:a=(t-e)/l+4,a*=60,a<0&&(a+=360)),{h:a,s:c,l:r}}function la(n){let t=(n.h%360+360)%360,e=Ue(n.s),s=Ue(n.l);if(e<1e-12){let a=Math.round(s*255);return{r:a,g:a,b:a}}let i=s<.5?s*(1+e):s+e-s*e,o=2*s-i,r=t/360;return{r:Math.round(Xi(o,i,r+1/3)*255),g:Math.round(Xi(o,i,r)*255),b:Math.round(Xi(o,i,r-1/3)*255)}}function Xi(n,t,e){let s=e;return s<0&&(s+=1),s>1&&(s-=1),s<1/6?n+(t-n)*6*s:s<1/2?t:s<2/3?n+(t-n)*(2/3-s)*6:n}function pt(n){return n<0?0:n>255?255:n}function Ue(n){return n<0?0:n>1?1:n}function dl(n,t){let e=pl(n.from,t);if(e>=0&&e({r:pt(a.r),g:pt(a.g),b:pt(a.b)})),to:o}}function Yi(n,t,e){return n+(t-n)*e}function ml(n,t){let e=ca(n),s=e.h+(t.hue||0),i=Ue(e.s*(t.sat==null?1:t.sat)),o=Ue(e.l*(t.light==null?1:t.light));return la({h:s,s:i,l:o})}var bl=Object.freeze([Object.freeze([0,8,2,10]),Object.freeze([12,4,14,6]),Object.freeze([3,11,1,9]),Object.freeze([15,7,13,5])]);function ua(n){let t=n||{},e=null,s=!1,i={vignette:{enabled:$i(t.vignette&&t.vignette.enabled,!1),strength:Ki(t.vignette&&t.vignette.strength,.5)},dither:{enabled:$i(t.dither&&t.dither.enabled,!1),strength:Ki(t.dither&&t.dither.strength,.5)},scanline:{enabled:$i(t.scanline&&t.scanline.enabled,!1),strength:Ki(t.scanline&&t.scanline.strength,.5)}};function o(a){let c=a!==void 0?a:e?e.getContext2d():null;if(!c)return;let l=c.canvas?c.canvas.width:0,u=c.canvas?c.canvas.height:0;if(i.vignette.enabled&&i.vignette.strength>0&&l>0&&u>0){let h=c.createRadialGradient(l/2,u/2,Math.min(l,u)*.25,l/2,u/2,Math.max(l,u)*.75);h.addColorStop(0,"rgba(0,0,0,0)"),h.addColorStop(1,"rgba(0,0,0,"+i.vignette.strength.toFixed(3)+")"),c.fillStyle=h,c.fillRect(0,0,l,u)}if(i.scanline.enabled&&i.scanline.strength>0&&l>0&&u>0){c.fillStyle="rgba(0,0,0,"+(i.scanline.strength*.5).toFixed(3)+")";for(let h=0;h0&&l>0&&u>0&&typeof c.getImageData=="function"&&typeof c.putImageData=="function"){let h=c.getImageData(0,0,l,u);xl(h,i.dither.strength),c.putImageData(h,0,0)}}return{name:"palette-post",version:"1.0.0",dependencies:[],init(a){e=a},dispose(){s||(e=null,s=!0)},applyPaletteMap(a,c){return dl(a,c)},applyPaletteMapToBuffer(a,c){return fl(a,c)},lerpPaletteMap(a,c,l){return yl(a,c,l)},shiftHsl(a,c){return ml(a,c)},rgbToHsl(a){return ca(a)},hslToRgb(a){return la(a)},setPost(a){if(a)for(let c of["vignette","dither","scanline"])a[c]&&(typeof a[c].enabled=="boolean"&&(i[c].enabled=a[c].enabled),typeof a[c].strength=="number"&&(i[c].strength=Ue(a[c].strength)))},getPost(){return{vignette:{enabled:i.vignette.enabled,strength:i.vignette.strength},dither:{enabled:i.dither.enabled,strength:i.dither.strength},scanline:{enabled:i.scanline.enabled,strength:i.scanline.strength}}},renderPost(a){o(a)},probe(){return{disposed:s,post:this.getPost()}}}}function xl(n,t){let e=Ue(t);if(e<=0)return n;let{data:s,width:i}=n,r=255/(Math.max(2,Math.round(16-e*14))-1);for(let a=0;a+3>2)%i,l=Math.floor((a>>2)/i),u=(bl[l&3][c&3]/16-.5)*r;for(let h=0;h<3;h++){let p=s[a+h]+u,d=Math.round(p/r)*r;s[a+h]=d<0?0:d>255?255:d}}return n}function $i(n,t){return typeof n=="boolean"?n:t}function Ki(n,t){return typeof n=="number"?Ue(n):t}var Zi=Object.freeze({blip:Object.freeze({name:"blip",params:Object.freeze([.6,0,880,0,.03,.06,1,1.5])}),thud:Object.freeze({name:"thud",params:Object.freeze([.8,0,90,0,.04,.18,0,1,0,0,0,0,0,4])}),chime:Object.freeze({name:"chime",params:Object.freeze([.5,0,660,.02,.12,.3,1,2])})}),ha=Object.keys(Zi);function vl(n){let t=[];return n==null||typeof n!="object"?{ok:!1,errors:["song \u5FC5\u987B\u662F\u5BF9\u8C61"]}:(!Array.isArray(n.instruments)||n.instruments.length===0?t.push("instruments \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4"):n.instruments.forEach((e,s)=>{(!Array.isArray(e)||e.some(i=>typeof i!="number"||!Number.isFinite(i)))&&t.push(`instruments[${s}] \u5FC5\u987B\u662F\u6709\u9650\u6570\u5B57\u6570\u7EC4\uFF08ZzFX \u53C2\u6570\u5305\uFF09`)}),!Array.isArray(n.patterns)||n.patterns.length===0?t.push("patterns \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4"):n.patterns.forEach((e,s)=>{if(!Array.isArray(e)||e.length===0){t.push(`patterns[${s}] \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4\uFF08\u81F3\u5C11\u4E00\u4E2A\u58F0\u90E8\u901A\u9053\uFF09`);return}e.forEach((i,o)=>{if(!Array.isArray(i)||i.length<2){t.push(`patterns[${s}][${o}] \u901A\u9053\u81F3\u5C11\u542B [\u4E50\u5668\u7D22\u5F15, \u58F0\u50CF]`);return}if(i.some(c=>typeof c!="number"||!Number.isFinite(c))){t.push(`patterns[${s}][${o}] \u901A\u9053\u5FC5\u987B\u5168\u4E3A\u6709\u9650\u6570\u5B57`);return}let r=i[0]|0;Array.isArray(n.instruments)&&(r<0||r>=n.instruments.length)&&t.push(`patterns[${s}][${o}] \u4E50\u5668\u7D22\u5F15 ${r} \u8D8A\u754C\uFF08instruments \u957F\u5EA6 ${n.instruments.length}\uFF09`);let a=i[1];(a<-1||a>1)&&t.push(`patterns[${s}][${o}] \u58F0\u50CF ${a} \u8D8A\u754C\uFF08\u5E94 -1..+1\uFF09`)})}),!Array.isArray(n.sequence)||n.sequence.length===0?t.push("sequence \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4"):n.sequence.forEach((e,s)=>{if(typeof e!="number"||!Number.isInteger(e)){t.push(`sequence[${s}] \u5FC5\u987B\u662F\u6574\u6570 pattern \u7D22\u5F15`);return}Array.isArray(n.patterns)&&(e<0||e>=n.patterns.length)&&t.push(`sequence[${s}] \u7D22\u5F15 ${e} \u8D8A\u754C\uFF08patterns \u957F\u5EA6 ${n.patterns.length}\uFF09`)}),n.bpm!=null&&(typeof n.bpm!="number"||!(n.bpm>0))&&t.push("bpm \u5FC5\u987B\u662F\u6B63\u6570"),{ok:t.length===0,errors:t})}function pe(n){return typeof n!="number"||Number.isNaN(n)||n<0?0:n>1?1:n}function Sl(n,t){switch(n){case"ease-in":return t*t;case"ease-out":return Math.sqrt(t);case"constant":return 1;default:return t}}function da(n,t){let e=pe(t);return n==null||!Array.isArray(n.voices)?[]:n.voices.map(s=>{let i=String(s&&s.id!=null?s.id:""),o=Array.isArray(s&&s.channelIndices)?s.channelIndices.slice():[],r=typeof s.minIntensity=="number"?pe(s.minIntensity):0,a=typeof s.maxIntensity=="number"?pe(s.maxIntensity):1,c=typeof s.volumeCurve=="string"?s.volumeCurve:"linear",l=typeof s.baseVolume=="number"?pe(s.baseVolume):1;if(ea)return{id:i,on:!1,volume:0,channelIndices:o};let u=a-r,h=u<=0?1:(e-r)/u,p=pe(Sl(c,h)*l);return{id:i,on:!0,volume:p,channelIndices:o}})}function fa(n,t,e,s){try{let i=t[0]||[],o=t[1]||i,r=Math.max(i.length,o.length);if(r===0)return null;let c=n.createBuffer(2,r,44100);c.getChannelData(0).set(i),c.getChannelData(1).set(o.length?o:i);let l=n.createBufferSource();l.buffer=c,l.loop=!!s;let u=n.createGain();return u.gain.value=pe(e*.3),l.connect(u),u.connect(n.destination),l.start(),{stop(){try{l.stop()}catch(h){}try{l.disconnect(),u.disconnect()}catch(h){}}}}catch(i){return to("[audio-music] \u53D7\u63A7\u97F3\u9891\u64AD\u653E\u5F02\u5E38\uFF0C\u964D\u7EA7\u4E3A\u9759\u9ED8",i),null}}function pa(n){let t=n||{},e=typeof t.masterVolume=="number"?pe(t.masterVolume):1,s=()=>null,i=null,o=null,r={voices:[]},a=1,c=null,l=!1,u=0,h=!1,p=!1;function d(){let w=s();return w==null?(u+=1,h||(Qi("[audio-music] \u65E0\u53D7\u63A7\u97F3\u9891\u4E0A\u4E0B\u6587\uFF08getAudioContext \u8FD4\u56DE null\uFF09\uFF0C\u5168\u90E8\u53D1\u58F0\u9759\u9ED8 no-op\uFF08\u8BC4\u4F30\u73AF\u5883\u65E0\u58F0\u5361\u65F6\u7684\u5BB9\u9519\u964D\u7EA7\uFF09"),h=!0),null):w}function y(){if(!o||!i)return null;try{let w=typeof o.bpm=="number"&&o.bpm>0?o.bpm:125;return i.synthSong(o.instruments,o.patterns,o.sequence,w)}catch(w){return to("[audio-music] \u66F2\u8C31\u6E32\u67D3\u5F02\u5E38\uFF0C\u964D\u7EA7\u4E3A\u9759\u9ED8",w),null}}function b(){let w=da(r,a);if(w.length===0)return 1;let E=0;for(let A of w)A.on&&(E=Math.max(E,A.volume));return E}function v(w,E){typeof E=="number"&&(a=pe(E));let A=d();if(A==null||!o)return;S();let T=y();if(!T)return;let R=pe(e*b());c=fa(A,T,R,w),l=!!w&&c!=null}function S(){c&&(c.stop(),c=null),l=!1}return{name:"audio-music",version:"1.0.0",dependencies:[],init(w){s=()=>w.getAudioContext();let E=w.getEngine&&w.getEngine();i=E?E.audio.synth:null},dispose(){p||(S(),p=!0)},loadSong(w){let E=vl(w);return E.ok?o={instruments:w.instruments,patterns:w.patterns,sequence:w.sequence,bpm:typeof w.bpm=="number"?w.bpm:125}:Qi("[audio-music] \u66F2\u8C31\u6821\u9A8C\u5931\u8D25\uFF0C\u672A\u8F7D\u5165\uFF1A"+E.errors.join("\uFF1B")),E},play(w){v(!1,w)},stop(){S()},loop(w){v(!0,w)},setIntensityLayering(w){r=w&&Array.isArray(w.voices)?{voices:w.voices}:{voices:[]}},setIntensity(w){a=pe(w)},resolveVoices(w){return da(r,w)},playSfx(w){let E=Zi[w];if(!E){Qi("[audio-music] \u672A\u77E5\u97F3\u6548\u9884\u8BBE\uFF1A"+String(w));return}let A=d();if(A!=null)try{let T=i?i.synthSfx(E.params):null;if(!T)return;fa(A,[T,T],e,!1)}catch(T){to("[audio-music] \u97F3\u6548\u64AD\u653E\u5F02\u5E38\uFF0C\u964D\u7EA7\u4E3A\u9759\u9ED8 name="+w,T)}},getPreset(w){return Zi[w]},listPresets(){return ha.slice()},probe(){return{hasAudio:s()!=null,hasSong:o!=null,intensity:a,voiceCount:r.voices.length,looping:l,silentNoops:u,presetCount:ha.length}}}}function to(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function Qi(n){typeof console!="undefined"&&typeof console.warn=="function"&&console.warn(n)}var wl="zaomeng.save";function Tl(n){if(typeof TextEncoder!="undefined")return new TextEncoder().encode(n).length;if(typeof Buffer!="undefined"&&typeof Buffer.byteLength=="function")return Buffer.byteLength(n,"utf8");let t=0;for(let e=0;e=55296&&s<=56319?(t+=4,e++):t+=3}return t}function no(){let n=new Map;return{getItem(t){return n.has(t)?n.get(t):null},setItem(t,e){n.set(t,e)},removeItem(t){n.delete(t)},keys(){return Array.from(n.keys())}}}function ga(){if(typeof localStorage=="undefined")throw new Error("[save-progress] createLocalStorageAdapter \u9700\u8981\u5168\u5C40 localStorage\uFF08\u4EC5\u6D4F\u89C8\u5668\u96C6\u6210\u6BB5\u53EF\u7528\uFF09\u3002node/host-dev \u8BF7\u7528\u7F3A\u7701\u5185\u5B58 adapter \u6216 createMemoryAdapter()\u3002");return{getItem(n){return localStorage.getItem(n)},setItem(n,t){localStorage.setItem(n,t)},removeItem(n){localStorage.removeItem(n)},keys(){let n=[];for(let t=0;t0?t.namespace:wl;if(e.indexOf(":")>=0)throw new Error('[save-progress] namespace \u4E0D\u5F97\u542B\u5206\u9694\u7B26 ":"\uFF08\u5F53\u524D="'+e+'"\uFF09');let s=typeof t.maxValueBytes=="number"&&t.maxValueBytes>0?Math.floor(t.maxValueBytes):32768,i=!Al(t.adapter),o=i?no():t.adapter,r=e+":",a=0,c=0,l=!1;function u(d){return typeof d!="string"||d.length===0?r+String(d):r+d}function h(){try{let d=o.keys();return Array.isArray(d)?d.filter(y=>typeof y=="string"&&y.indexOf(r)===0):[]}catch(d){return Xn("[save-progress] adapter.keys() \u5F02\u5E38\uFF0C\u964D\u7EA7\u8FD4\u56DE\u7A7A\u96C6",d),[]}}return{name:"save-progress",version:"1.0.0",dependencies:[],init(d){h()},dispose(){},get(d,y){if(!eo(d))return y;let b;try{b=o.getItem(u(d))}catch(v){return Xn("[save-progress] adapter.getItem \u5F02\u5E38\uFF0C\u8FD4\u56DE\u9ED8\u8BA4\u503C key="+d,v),y}if(b==null)return y;try{return JSON.parse(b)}catch{return a+=1,l||(Yn("[save-progress] \u68C0\u6D4B\u5230\u635F\u574F\u5B58\u6863\uFF08\u975E\u6CD5 JSON\uFF09\uFF0C\u5DF2\u5BB9\u9519\u56DE\u9000\u9ED8\u8BA4\u503C key="+d),l=!0),y}},set(d,y){if(!eo(d))return Yn("[save-progress] set \u6536\u5230\u975E\u6CD5 key\uFF0C\u62D2\u7EDD\u5199\u5165\uFF1A"+String(d)),!1;let b;try{b=JSON.stringify(y)}catch{return c+=1,Yn("[save-progress] \u503C\u4E0D\u53EF JSON \u5E8F\u5217\u5316\uFF08\u5FAA\u73AF\u5F15\u7528?\uFF09\uFF0C\u62D2\u7EDD\u5199\u5165 key="+d),!1}if(b===void 0)return c+=1,Yn("[save-progress] \u503C\u5E8F\u5217\u5316\u4E3A undefined\uFF08\u5982\u7EAF undefined/\u51FD\u6570\uFF09\uFF0C\u62D2\u7EDD\u5199\u5165 key="+d),!1;let v=Tl(b);if(v>s)return c+=1,Yn("[save-progress] \u503C\u8D85\u5B57\u8282\u4E0A\u9650\u62D2\u7EDD\u5199\u5165 key="+d+"\uFF08"+v+" > "+s+" bytes\uFF09"),!1;try{return o.setItem(u(d),b),!0}catch(S){return c+=1,Xn("[save-progress] adapter.setItem \u5F02\u5E38\uFF0C\u5199\u5165\u5931\u8D25 key="+d,S),!1}},remove(d){if(eo(d))try{o.removeItem(u(d))}catch(y){Xn("[save-progress] adapter.removeItem \u5F02\u5E38\uFF08\u5DF2\u5FFD\u7565\uFF09key="+d,y)}},clear(){let d=h(),y=0;for(let b of d)try{o.removeItem(b),y+=1}catch(v){Xn("[save-progress] clear \u65F6 removeItem \u5F02\u5E38\uFF08\u5DF2\u8DF3\u8FC7\uFF09fullKey="+b,v)}return y},probe(){return{namespace:e,maxValueBytes:s,usingMemoryAdapter:i,size:h().length,corruptRecoveries:a,rejectedWrites:c}}}}function eo(n){return typeof n=="string"&&n.length>0}function Al(n){return!!n&&typeof n.getItem=="function"&&typeof n.setItem=="function"&&typeof n.removeItem=="function"&&typeof n.keys=="function"}function Xn(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function Yn(n){typeof console!="undefined"&&typeof console.warn=="function"&&console.warn(n)}var Cl={w:390,h:844};function ma(n){let t=((n&&n.seed)!=null?n.seed:0)>>>0,e=ta({cellSize:96}),s=ea(),i=ra({inputBufferMs:260,inputTypes:["pointerdown"]}),o=aa({seed:t,maxParticles:600}),r=ua({vignette:{enabled:!0,strength:.22}}),a=pa({masterVolume:.8}),c;try{c=ga()}catch(p){console.warn("[generic] localStorage \u4E0D\u53EF\u7528\uFF0C\u5B58\u6863\u9000\u5185\u5B58 adapter\uFF1A"+(p&&p.message)),c=no()}let l=ya({namespace:"zaomeng-generic",adapter:c});return{plugins:{collision:e,physics:s,gamefeel:i,juice:o,palettePost:r,audioMusic:a,save:l},registerOrder:[e,s,i,o,r,l,a],viewport:Cl,buildFactoryOpts:(p,d)=>({runtime:{plugins:d.plugins,bundle:d.bundle,getRealAudioCtx:d.getRealAudioCtx}})}}function $n(n){let t=n||{},e=null,s=0,i=null,o={x:110,y:422,vy:0,r:12},r=420,a=-260,c=150,l=60,u=220,h=280,p=u/2,d=844-u/2,y=12,b=[],v=0,S="booting",_="",w=null,E=!1,A=!1,T=!1,R={x:0,y:0};function M(){o.y=422,o.vy=0,b=[],v=0,S="playing",_="",w=null,E=!1,A=!1,T=!1;let I=390+l/2+180;b.push({x:I,centerY:ct(),scored:!1})}function ct(){return e&&e.random&&e.random.range?e.random.range(p,d):422}function et(I,N){let Y=e.getEngine();if(Y){if(Y.particles)try{let ht=Y.particles.spawnEmitter({pos:{x:I.x,y:I.y},count:N==="crash"?35:22,emitRate:0,particleTime:.6,speed:N==="crash"?160:110,coneAngle:N==="crash"?Math.PI:.5,sizeStart:N==="crash"?16:12,sizeEnd:2,colorStart:N==="crash"?{r:1,g:.1,b:.1,a:1}:N==="score"?{r:.2,g:1,b:.3,a:1}:{r:.3,g:.7,b:1,a:1},colorEnd:N==="crash"?{r:1,g:.3,b:0,a:0}:{r:.1,g:.5,b:1,a:0}})}catch{}if(Y.audio&&Y.audio.synth)try{N==="flap"?Y.audio.synth.synthSfx([1,.05,340,,,.12,,1.2,,,,,,,,.1]):N==="score"?Y.audio.synth.synthSfx([1,.05,880,,,.22,,1.9,,,,,,,,.4]):N==="crash"&&Y.audio.synth.synthSfx([2,.5,90,,,.5,,.3,,,,,,,,.1])}catch{}}}function lt(I){if(S==="playing")o.vy=a,E=!0;else if(S==="gameover"){let Pt=I.x||0,he=I.y||0;Pt>=115&&Pt<=275&&he>=620&&he<=680&&M()}}function gt(I){e=I.ctx,i=e.getInput().on("pointerdown",lt),M(),S="playing"}function kt(I){if(s=e.time.nowMs(),S!=="playing")return;let N=r;if(o.vy+=N*I,o.y+=o.vy*I,o.y-y<=0||o.y+y>=844){Ee("boundary");return}for(let it of b)it.x-=c*I;b=b.filter(it=>it.x>-l/2-10);let Y=b.length>0?b[b.length-1]:null;if(!Y||Y.x<=390+l/2-h){let it=Y?Y.x+h:390+l/2+180;b.push({x:it,centerY:ct(),scored:!1})}let ht={x:o.x-y,y:o.y-y,w:y*2,h:y*2};for(let it of b){let Pt=it.centerY-u/2,he=it.centerY+u/2,An={x:it.x-l/2,y:0,w:l,h:Pt},Cn={x:it.x-l/2,y:he,w:l,h:844-he},En=(de,$t)=>de.x<$t.x+$t.w&&de.x+de.w>$t.x&&de.y<$t.y+$t.h&&de.y+de.h>$t.y;if(En(ht,An)||En(ht,Cn)){Ee("pipe_collision");return}!it.scored&&it.x+l/2{if(S!=="playing")return null;let N=null;for(let Y of b)Y.x>o.x-y&&(!N||Y.x({phase:S,result:w,score:v,bird:{x:o.x,y:o.y,vy:o.vy},nextGap:I,gameoverReason:_})}}return{init:gt,update:kt,render:Gt,destroy:ut,_forensicsView:Rt}}var pd=$n,gd=$n;async function yd(n){let t=n||{},e=t.engine||await Promise.resolve().then(()=>(Oc(),Lc)),s=(t.seed!=null?t.seed:305441741)>>>0,i=ma({seed:s});return Zr({canvas:t.canvas,statusEl:t.statusEl||null,engine:e,seed:s,mode:t.mode||"play",engineMode:"real",viewport:i.viewport,factory:$n,plugins:i.plugins,registerOrder:i.registerOrder,buildFactoryOpts:i.buildFactoryOpts,recHook:t.recHook||null,onReady:t.onReady||null})}return Bc(md);})();
+color = `+this.color),t}renderDebug(t=!0){let e=t?this.isHoverObject()?Xa:this.disabled?Ka:this.interactive?nr:$a:Ya;E.drawRect(this.nativePos,this.size,ue,4,e)}click(t=!0){this.onClick(),t&&this.soundClick&&this.soundClick.play()}onUpdate(){}onRender(){}onEnter(){}onLeave(){}onPress(){}onRelease(){}onClick(){}onChange(){}},gi=class extends ee{constructor(t,e,s="",i="center",o=E.defaultFont){super(t,e),f(J(s),"ui text must be a string"),f(["left","center","right"].includes(i),"ui text align must be left, center, or right"),f(J(o),"ui text font must be a string"),this.text=s,this.align=i,this.font=o,this.canBeHover=!1,this.color=ue,this.shadowColor=ue,this.gradientColor=void 0,this.lineWidth=0,this.textFitScale=1}render(){super.render();let t=this.getTextSize();E.drawText(this.text,this.nativePos,t,this.textColor,this.textLineWidth,this.textLineColor,this.align,this.font,this.fontStyle,!0,this.textShadow,this.shadowColor,this.shadowBlur,this.shadowOffset)}},Lo=class extends ee{constructor(t,e,s=""){super(t,e),f(J(s),"ui text must be a string"),this.maxLength=0,this.text=s,this.interactive=!0,this.canBeHover=!0}click(){E.keyInputObject=this,this.onClick()}stopEditing(){this.isKeyInputObject()&&(this.soundRelease&&this.soundRelease.play(),E.activeObject=void 0,E.keyInputObject=void 0,this.onChange())}onKeyDown(t){let e=t.code,s=t.key;e==="Backspace"?this.text=this.text.slice(0,-1):e==="Enter"||e==="Escape"?this.stopEditing():s.length===1&&(!this.maxLength||this.text.lengththis.size.y,s=e?this.size.y:this.size.x,i=e?this.size.x:this.size.y,o=e?this.nativePos.x:this.nativePos.y,r=i-s,a=o-r/2,c=o+r/2,l=E.screenToNative(Ft);this.value=e?Mt(l.x,a,c):Mt(l.y,c,a)}else if(this.isNavigationObject()){let e=E.getNavigationOtherDirection();E.navigationTimer.active()||(this.value=j(this.value+e*.01))}this.value===t||this.onChange()}render(){super.render();let t=this.size.x>this.size.y,e=t?this.size.x:this.size.y,s=t?this.size.y:this.size.x;if(this.fillMode){let o=K(s,this.cornerRadius*2),r=Nt(o,e,this.value),a=(r-e)*(t?.5:-.5),c=this.nativePos.add(t?b(a,0):b(0,a)),l=this.disabled?this.disabledColor:this.handleColor,u=t?b(r,this.size.y):b(this.size.x,r);E.drawRect(c,u,l,this.lineWidth,this.lineColor,this.cornerRadius,this.gradientColor)}else{let o=j(t?this.value:1-this.value),r=(e-s)*(o-.5),a=this.nativePos.add(t?b(r,0):b(0,r)),c=this.disabled?this.disabledColor:this.handleColor,l=b(s);E.drawRect(a,l,c,this.lineWidth,this.lineColor,this.cornerRadius,this.gradientColor)}let i=this.getTextSize();E.drawText(this.text,this.nativePos,i,this.textColor,this.textLineWidth,this.textLineColor,this.align,this.font,this.fontStyle,!0,this.textShadow)}navigatePressed(){this.value=this.value?0:1,this.onChange(),this.onRelease(),super.navigatePressed()}},Mo=class extends ee{constructor(t,e,s,i=!1,o=!1,r=1){super(t,e||b()),f(J(s),"video src must be a string"),f(P(r),"video volume must be a number"),this.color=et,this.cornerRadius=0,this.volume=r,this.video=document.createElement("video"),this.video.loop=o,this.video.volume=j(r*gn),this.video.muted=!Jt,this.video.style.display="none",this.video.src=s,document.body.appendChild(this.video),i&&this.play()}async play(){try{await this.video.play()}catch{}}pause(){this.video.pause()}stop(){this.video.pause(),this.video.currentTime=0}isLoading(){return this.video.readyState=1,"ui layout columns must be a number >= 1"),f(P(s),"ui layout gap must be a number"),f(P(i),"ui layout padding must be a number"),this.columns=e,this.gap=s,this.padding=i,o&&(this.color=ue,this.gradientColor=void 0,this.lineWidth=0,this.shadowColor=ue),this.relayout()}addChild(t){return super.addChild(t),this.relayout(),t}removeChild(t){super.removeChild(t),this.relayout()}relayout(){let t=this.children.length;if(!t){this.size=b(this.padding*2);return}let e=this.columns,s=is(t/e),i=new Array(e).fill(0),o=new Array(s).fill(0);for(let p=0;p=0&&m.objects.splice(t,1),super.destroy()}updatePhysics(){}render(){this.tileInfo?super.render():this.drawFixtures(this.color,this.lineColor,this.lineWidth)}renderDebugInfo(){let t=!this.getIsAwake(),e=this.getBodyType()===m.bodyTypeStatic,s=N(t?1:0,t?1:0,e?1:0,.5);this.drawFixtures(s)}drawFixtures(t=U,e=et,s=.1,i,o){this.getFixtureList().forEach(r=>{m.castShapeObject(r.GetShape()).GetType()!==m.instance.b2Shape.e_edge&&m.drawFixture(r,this.pos,this.angle,t,e,s,i,o)}),this.edgeLists.forEach(r=>fo(r,s,e,!1,this.pos,this.angle)),this.edgeLoops.forEach(r=>fo(r,s,e,!0,this.pos,this.angle))}beginContact(t){}endContact(t){}addShape(t,e=1,s=.2,i=0,o=!1){f(P(e),"density must be a number"),f(P(s),"friction must be a number"),f(P(i),"restitution must be a number");let r=new m.instance.b2FixtureDef;return r.set_shape(t),r.set_density(e),r.set_friction(s),r.set_restitution(i),r.set_isSensor(o),this.body.CreateFixture(r)}addBox(t=b(1),e=b(),s=0,i,o,r,a){f(L(t),"size must be a Vector2"),f(t.x>0&&t.y>0,"size must be positive"),f(L(e),"offset must be a Vector2"),f(P(s),"angle must be a number");let c=new m.instance.b2PolygonShape;return c.SetAsBox(t.x/2,t.y/2,m.vec2dTo(e),-s),this.addShape(c,i,o,r,a)}addPoly(t,e,s,i,o){f(ce(t),"points must be an array");function r(c){f(3<=c.length&&c.length<=8);let l=m.instance._malloc(c.length*8);for(let p=0,d=0;p>2]=c[p].x,d+=4,m.instance.HEAPF32[l+d>>2]=c[p].y,d+=4;let u=m.instance.wrapPointer(l,m.instance.b2Vec2),h=new m.instance.b2PolygonShape;return h.Set(u,c.length),m.instance._free(l),h}let a=r(t);return this.addShape(a,e,s,i,o)}addRegularPoly(t=1,e=8,s,i,o,r){f(P(t)&&t>0,"diameter must be a positive number"),f(P(e)&&e>2,"sides must be a positive number greater than 2");let a=[],c=t/2;for(let l=e;l--;)a.push(b(c,0).rotate((l+.5)/e*q*2));return this.addPoly(a,s,i,o,r)}addRandomPoly(t=1,e,s,i,o){f(P(t)&&t>0,"diameter must be a positive number");let r=er(3,9),a=[],c=t/2;for(let l=r;l--;)a.push(b(ut(c/2,c*1.5),0).rotate(l/r*q*2));return this.addPoly(a,e,s,i,o)}addCircle(t=1,e=b(),s,i,o,r){f(P(t)&&t>0,"diameter must be a positive number"),f(L(e),"offset must be a Vector2");let a=new m.instance.b2CircleShape;return a.set_m_p(m.vec2dTo(e)),a.set_m_radius(t/2),this.addShape(a,s,i,o,r)}addEdge(t,e,s,i,o,r){f(L(t),"point1 must be a Vector2"),f(L(e),"point2 must be a Vector2");let a=new m.instance.b2EdgeShape;return a.Set(m.vec2dTo(t),m.vec2dTo(e)),this.addShape(a,s,i,o,r)}addEdgeList(t,e,s,i,o){f(ce(t),"points must be an array");let r=[],a=[];for(let c=0;ct[Qt(l,t.length)];for(let l=0;lthis.destroyFixture(t))}getCenterOfMass(){return m.vec2From(this.body.GetWorldCenter())}getLinearVelocity(){return m.vec2From(this.body.GetLinearVelocity())}getAngularVelocity(){return this.body.GetAngularVelocity()}getMass(){return this.body.GetMass()}getInertia(){return this.body.GetInertia()}getIsAwake(){return this.body.IsAwake()}getBodyType(){return this.body.GetType()}getSpeed(){return this.getLinearVelocity().length()}setTransform(t,e){this.pos=t,this.angle=e,this.body.SetTransform(m.vec2dTo(t),-e)}setPosition(t){this.setTransform(t,this.body.GetAngle())}setAngle(t){this.setTransform(m.vec2From(this.body.GetPosition()),t)}setLinearVelocity(t){this.body.SetLinearVelocity(m.vec2dTo(t))}setAngularVelocity(t){this.body.SetAngularVelocity(t)}setLinearDamping(t){this.body.SetLinearDamping(t)}setAngularDamping(t){this.body.SetAngularDamping(t)}setGravityScale(t=1){this.body.SetGravityScale(this.gravityScale=t)}setBullet(t=!0){this.body.SetBullet(t)}setAwake(t=!0){this.body.SetAwake(t)}setBodyType(t){this.body.SetType(t)}setSleepingAllowed(t=!0){this.body.SetSleepingAllowed(t)}setFixedRotation(t=!0){this.body.SetFixedRotation(t)}setCenterOfMass(t){this.setMassData(t)}setMass(t){this.setMassData(void 0,t)}setMomentOfInertia(t){this.setMassData(void 0,void 0,t)}resetMassData(){this.body.ResetMassData()}setMassData(t,e,s){let i=new m.instance.b2MassData;this.body.GetMassData(i),t!==void 0&&i.set_center(m.vec2dTo(t)),e!==void 0&&i.set_mass(e),s!==void 0&&i.set_I(s),this.body.SetMassData(i)}setFilterData(t=0,e=0,s=0){this.getFixtureList().forEach(i=>{let o=i.GetFilterData();o.set_categoryBits(t),o.set_maskBits(65535&~e),o.set_groupIndex(s)})}setSensor(t=!0){this.getFixtureList().forEach(e=>e.SetSensor(t))}applyForce(t,e){e||(e=this.getCenterOfMass()),this.setAwake(),this.body.ApplyForce(m.vec2dTo(t),m.vec2dTo(e))}applyAcceleration(t,e){e||(e=this.getCenterOfMass()),this.setAwake();let s=t.scale(this.getMass());this.body.ApplyLinearImpulse(m.vec2dTo(s),m.vec2dTo(e))}applyImpulse(t,e){e||(e=this.getCenterOfMass()),this.setAwake(),this.body.ApplyLinearImpulse(m.vec2dTo(t),m.vec2dTo(e))}applyTorque(t){this.setAwake(),this.body.ApplyTorque(t)}applyAngularAcceleration(t){this.setAwake(),this.body.ApplyAngularImpulse(t*this.getInertia())}applyAngularImpulse(t){this.setAwake(),this.body.ApplyAngularImpulse(t)}hasFixtures(){return!m.isNull(this.body.GetFixtureList())}getFixtureList(){let t=[];for(let e=this.body.GetFixtureList();!m.isNull(e);)t.push(e),e=e.GetNext();return t}hasJoints(){return!m.isNull(this.body.GetJointList())}getJointList(){let t=[];for(let e=this.body.GetJointList();!m.isNull(e);)t.push(e),e=e.get_next();return t}},yi=class extends Ss{constructor(t,e,s,i=0,o,r=0){let a=m.bodyTypeStatic;super(t,e,s,i,o,a,r)}},Go=class extends Ss{constructor(t,e,s,i=0,o,r=0){let a=m.bodyTypeKinematic;super(t,e,s,i,o,a,r)}},Fo=class extends yi{constructor(t){f(t instanceof ps,"tileLayer must be a TileCollisionLayer"),super(t.pos,t.size),this.tileLayer=t,this.addChild(t)}render(){}buildCollision(t=.2,e=0){this.destroyAllFixtures(),this.pos=this.tileLayer.pos.copy(),this.size=this.tileLayer.size.copy();let s=[],i=(r,a)=>r+a*this.size.x,o=(r,a)=>!s[i(r,a)]&&this.tileLayer.getCollisionData(b(r,a))>0;for(let r=0;ri.fractiono.pos.distanceSquared(t)0,"Tween duration must be > 0"),this.callback=t,this.start=e,this.end=s,this.duration=i,this.life=i,this.ease=o.ease||Si.LINEAR,this.useRealTime=!!o.useRealTime,this.paused=!!o.paused,this.thenCallback=void 0,this.loopRemaining=0,qt.push(this),t(this.interp(i))}setEase(t){return this.ease=t,this}then(t){return this.thenCallback=t,this.loopRemaining=0,this}loop(t=1/0){return this.loopRemaining=t,this.thenCallback=()=>Cc(this),this}pingPong(t=1/0){return this.loopRemaining=t,this.thenCallback=()=>Rc(this),this}pause(){this.paused=!0}resume(){this.paused=!1}restart(){this.life=this.duration,this.paused=!1,qt.indexOf(this)<0&&qt.push(this),this.callback(this.interp(this.duration))}isActive(){return!this.paused&&qt.indexOf(this)>=0}getPercent(){return Mt(this.duration-this.life,0,this.duration)}getValue(){return this.interp(this.life)}interp(t){let e=this.ease((this.duration-t)/this.duration);return Ca(this.start)?this.start.lerp(this.end,e):this.start+(this.end-this.start)*e}stop(){let t=qt.indexOf(this);t>=0&&qt.splice(t,1),this.thenCallback=void 0}},Si={LINEAR:n=>n,POWER:n=>t=>t**n,SINE:n=>1-at(n*(q/2)),CIRC:n=>1-(1-n*n)**.5,EXPO:n=>n===0?0:2**(10*n-10),BACK:n=>n*n*(2.70158*n-1.70158),ELASTIC:n=>n===0?0:n===1?1:-(2**(10*n-10))*tt((37-40*n)*q/6),SPRING:n=>1-(tt(q*(1-n)*(.2+2.5*(1-n)**3))*n**2.2+(1-n))*(1+1.2*n),BOUNCE:n=>{let t=1-n,e;return t<4/11?e=7.5625*t*t:t<8/11?e=7.5625*(t-=6/11)*t+.75:t<10/11?e=7.5625*(t-=9/11)*t+.9375:e=7.5625*(t-=10.5/11)*t+.984375,1-e},IN:n=>n,OUT:n=>t=>1-n(1-t),IN_OUT:n=>Si.PIECEWISE(n,Si.OUT(n)),PIECEWISE:(...n)=>{let t=n.length;return e=>{let s=e*t-1e-9>>0;return(n[s]((e-s/t)*t)+s)/t}},BEZIER:(n,t,e,s)=>{let i=o=>{let r=1-o,a=3*r*r*o,c=3*r*o*o,l=o**3;return[a*n+c*e+l,a*t+c*s+l]};return o=>{let r=0,a=1;for(let c=0;c<128;c++){let l=(r+a)/2,[u,h]=i(l);if(Z(u-o)<1e-5)return h;u=this.size.x||e>=this.size.y?null:this.nodes[t+e*this.size.x]}worldToTile(t){let e=this.tileLayer?this.tileLayer.pos.x:0,s=this.tileLayer?this.tileLayer.pos.y:0;return b(bt(t.x-e),bt(t.y-s))}tileToWorld(t,e){let s=this.tileLayer?this.tileLayer.pos.x:0,i=this.tileLayer?this.tileLayer.pos.y:0;return b(t+.5+s,e+.5+i)}buildNodeData(){let t=this.size.x,e=this.size.y,s=this.tileLayer?this.tileLayer.pos.x:0,i=this.tileLayer?this.tileLayer.pos.y:0;for(let o=0;o0&&(c?l>0&&pt(a.posWorld,oo,N(1,0,0,K(.2,l*.05)),this.debugTime):pt(a.posWorld,oo,N(1,0,0,.25),this.debugTime))}}aStarSearch(t,e){f(t&&e,"aStarSearch needs both endpoints"),f(t!==e,"aStarSearch: start and end must differ \u2014 caller should handle trivial case"),f(t.walkable&&e.walkable,"aStarSearch: endpoints must be walkable");let s=[t];t.isOpen=!0;let i=0;for(;s.length>0;){let o=0,r=s[0].f;for(let c=1;cthis.maxLoop)break;a.isOpen=!1,s.splice(o,1),a.isClosed=!0,this.debug&&this.debugTime>0&&pt(a.posWorld,oo,N(1,1,1,.05),this.debugTime);for(let c=-1;c<=1;++c)for(let l=-1;l<=1;++l){if(l===0&&c===0)continue;let u=this.getNode(a.pos.x+l,a.pos.y+c);if(!u||!u.walkable||u.isClosed)continue;let h=1;if(l!==0&&c!==0){let v=this.getNode(a.pos.x+l,a.pos.y);if(!v||!v.walkable)continue;let T=this.getNode(a.pos.x,a.pos.y+c);if(!T||!T.walkable)continue;h=fd}let p=a.g+h+u.cost;if(!u.isOpen)u.isOpen=!0,s.push(u);else if(p>=u.g)continue;u.parent=a,u.g=p;let d=Z(e.pos.x-u.pos.x),y=Z(e.pos.y-u.pos.y),x=X(d,y)+(Math.SQRT2-1)*K(d,y);u.f=u.g+x*this.heuristicWeight}}return e.parent!==null}getNearestClearNode(t,e=10,s=!0){f(L(t),"worldPos must be a Vector2"),s&&this.buildNodeData();let i=this.tileLayer?this.tileLayer.pos.x:0,o=this.tileLayer?this.tileLayer.pos.y:0,r=bt(t.x-i),a=bt(t.y-o);for(let c=0;c<=e;++c){let l=null,u=0;for(let h=-c;h<=c;++h)for(let p=-c;p<=c;++p){if(c>0&&Z(p)!==c&&Z(h)!==c)continue;let d=this.getNode(r+p,a+h);if(!d||!d.isClear())continue;let y=d.posWorld.x-t.x,x=d.posWorld.y-t.y,v=y*y+x*x;(!l||v0&&jt(i.posWorld,.3,N(.5,0,.5,.5),this.debugTime),t.splice(e,1),e=X(1,e-1);continue}else if(c===2){this.debug&&this.debugTime>0&&jt(i.posWorld,.3,N(1,0,0,.5),this.debugTime);let d,y;s.pos.y===i.pos.y&&o.pos.x===i.pos.x?(d=s.pos.x,y=o.pos.y):(d=o.pos.x,y=s.pos.y);let x=this.getNode(d,y);if(x&&x.isClear()){t.splice(e,1),e=X(1,e-1);continue}}else if(c===5){this.debug&&this.debugTime>0&&jt(i.posWorld,.3,N(1,1,0,.5),this.debugTime);let d=e>=2?t[e-2]:s,y,x,v,T;l===0||h===0?(y=o.pos.x,x=i.pos.y,v=s.pos.x,T=i.pos.y):(y=i.pos.x,x=o.pos.y,v=i.pos.x,T=s.pos.y);let C=y-d.pos.x,w=x-d.pos.y,_=v-d.pos.x,A=T-d.pos.y,S=C*C+w*w,R=_*_+A*A,M=S0&&jt(i.posWorld,.3,N(0,1,0,.5),this.debugTime),l===h&&u===p){++e;continue}else{let d,y;s.pos.y===o.pos.y?(d=i.pos.x,y=s.pos.y):(d=s.pos.x,y=i.pos.y);let x=this.getNode(d,y);if(x&&x.isClear()){t[e]=x,e=X(1,e-1);continue}}++e}}smoothPathStringPull(t){if(t.length<=2)return;for(let i of t)if(!i.isClear())return;let e=t.slice();t.length=0,t.push(e[0]);let s=0;for(let i=1;i0&&be(o.posWorld,t[t.length-1].posWorld,N(0,0,1,.3),.02,this.debugTime);continue}for(;s=1;--e){let s=t[e-1],i=t[e],o=t[e+1];(i.pos.x-s.pos.x)*(o.pos.y-s.pos.y)===(i.pos.y-s.pos.y)*(o.pos.x-s.pos.x)&&t.splice(e,1)}}isNodeClear(t,e){let s=this.getNode(t,e);return s!==null&&s.isClear()}isLineClear(t,e){f(L(t)&&L(e),"isLineClear needs Vector2 endpoints"),f(this.isNodeClear(t.x,t.y)&&this.isNodeClear(e.x,e.y),"isLineClear endpoints must be in-bounds and clear");let s=e.x-t.x,i=e.y-t.y,o=Z(s),r=Z(i),a=Kt(s),c=Kt(i),l=t.x,u=t.y;if(r===o){for(;l!==e.x;){if(l!==t.x&&(!this.isNodeClear(l,u)||!this.isNodeClear(l,u-c))||!this.isNodeClear(l,u+c))return!1;l+=a,u+=c}if(!this.isNodeClear(e.x,e.y-c))return!1}else if(ra.posWorld.copy());if(this.debug&&this.debugTime>0&&r.length>0){for(let a=1;apd,bootGameHost:()=>yd,default:()=>gd});var Is=class{constructor(t){this._state=(t==null?2654435769:t)>>>0}next(){this._state=this._state+1831565813>>>0;let t=this._state;return t=Math.imul(t^t>>>15,t|1),t^=t+Math.imul(t^t>>>7,t|61),((t^t>>>14)>>>0)/4294967296}range(t,e){return t+this.next()*(e-t)}reseed(t){this._state=(t==null?2654435769:t)>>>0}},ji=class{constructor(t){this._clock=t||Jc(),this._origin=this._clock()}nowMs(){return this._clock()}elapsedMs(){return this._clock()-this._origin}},Bi=class{constructor(t){this._time=t,this._subs=new Map}sourceFor(t){let e=this,s=t==null?null:t;return{on(i,o){if(e._assertType(i),typeof o!="function")throw new Error("[HostDevInputBridge] on \u7684 handler \u5FC5\u987B\u662F\u51FD\u6570");let r=e._subs.get(i)||[],a={handler:o,scope:s};return r.push(a),e._subs.set(i,r),{cancel(){let c=e._subs.get(i);if(!c)return;let l=c.indexOf(a);l>=0&&c.splice(l,1)}}},off(i,o){e._assertType(i);let r=e._subs.get(i);if(!r)return;let a=r.findIndex(c=>c.handler===o&&c.scope===s);a>=0&&r.splice(a,1)}}}_emit(t,e){this._assertType(t);let s=e||{},i={type:t,x:typeof s.x=="number"?s.x:0,y:typeof s.y=="number"?s.y:0,key:typeof s.key=="string"?s.key:"",tMs:this._time.nowMs()},o=this._subs.get(t);if(!o||o.length===0)return;let r=o.slice();for(let a of r)try{a.handler(i)}catch(c){Ne("[host-dev input] \u8F93\u5165 handler \u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09type="+t,c)}}disposeScope(t){if(t==null)return 0;let e=0;for(let[s,i]of this._subs){let o=i.filter(r=>r.scope!==t);e+=i.length-o.length,o.length===0?this._subs.delete(s):this._subs.set(s,o)}return e}_subscriptionCount(){let t=0;for(let e of this._subs.values())t+=e.length;return t}_assertType(t){if(!Ni.has(t))throw new Error("[HostDevInputBridge] \u975E\u6CD5\u8F93\u5165\u4E8B\u4EF6\u7C7B\u578B\uFF1A"+String(t)+"\uFF08\u4EC5\u652F\u6301 "+Array.from(Ni).join("/")+"\uFF09")}},Ni=new Set(["pointerdown","pointermove","pointerup","keydown","keyup"]);function Wr(n){let t=n||{},e=new ji(t.clock),s=new Is(t.seed),i=t.seed==null?2654435769:t.seed>>>0,o=new Bi(e),r=typeof t.audioFactory=="function"?t.audioFactory:null,a=null,c=!1,l=typeof t.engineFactory=="function"?t.engineFactory:null,u=null,h=!1,p=new Map,d=0,y=0;function x(){if(a)return a;if(!r)return c||(Ji("[host-dev audio] \u672A\u6CE8\u5165 audioFactory\uFF0CgetAudioContext \u8FD4\u56DE null\uFF08P6 \u987B\u5BB9\u9519\u964D\u7EA7\uFF1B\u96C6\u6210\u6BB5\u6CE8\u5165\u771F\u5B9E\u5DE5\u5382\uFF09"),c=!0),null;try{a=r()}catch(_){Ne("[host-dev audio] audioFactory \u629B\u9519\uFF0CgetAudioContext \u964D\u7EA7\u8FD4\u56DE null",_),a=null}return a}function v(){if(u)return u;if(!l)return h||(Ji("[host-dev engine] \u672A\u6CE8\u5165 engineFactory\uFF0CgetEngine \u8FD4\u56DE null\uFF08\u63D2\u4EF6\u987B\u5BB9\u9519\u964D\u7EA7\uFF1A\u7C92\u5B50\u9000\u53D7\u63A7\u9762\u81EA\u7BA1/\u5408\u6210\u6838\u9000 vendored/\u6570\u5B66\u9000\u5185\u7F6E\uFF1B\u96C6\u6210\u6BB5\u6CE8\u5165\u771F\u5B9E\u80CC\u4E66\uFF09"),h=!0),null;try{u=l()}catch(_){Ne("[host-dev engine] engineFactory \u629B\u9519\uFF0CgetEngine \u964D\u7EA7\u8FD4\u56DE null",_),u=null}return u}function T(_,A){return{getContext2d(){return t.context2d==null?null:t.context2d},onFrame(R){let M=d++;return p.set(M,R),{cancel(){p.delete(M)}}},getInput(){return o.sourceFor(_)},getAudioContext(){return x()},getEngine(){return v()},time:e,random:A}}let C=T(null,s),w={context:C,tick(_){y+=1;let A=Array.from(p.values());for(let S of A)try{S(_,y)}catch(R){Ne("[host-dev tick] \u5E27\u56DE\u8C03\u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09frame="+y,R)}},frameCount(){return y},inputBridge:o,deriveContextFor(_,A){let S=zc(i,_),R=new Is(S);return T(A==null?_:A,R)}};return Object.defineProperty(C,zi,{value:w,enumerable:!1,writable:!1,configurable:!1}),w}var zi=Symbol("zaomeng.coreProtocol.contextBundle"),Ms=class{constructor(){this._plugins=new Map,this._initOrder=[],this._initErrors=[],this._phase="idle",this._disposed=!1,this._context=void 0,this._pluginContexts=new Map}register(t){if(!t||typeof t!="object")throw new Error("[PluginRegistry] register \u9700\u8981\u4E00\u4E2A\u63D2\u4EF6\u5BF9\u8C61");if(typeof t.name!="string"||t.name.length===0)throw new Error("[PluginRegistry] \u63D2\u4EF6\u7F3A\u5C11\u5408\u6CD5 name");if(typeof t.version!="string"||t.version.length===0)throw new Error("[PluginRegistry] \u63D2\u4EF6 "+t.name+" \u7F3A\u5C11\u5408\u6CD5 version");if(typeof t.init!="function")throw new Error("[PluginRegistry] \u63D2\u4EF6 "+t.name+" \u7F3A\u5C11 init \u51FD\u6570");if(t.dispose!=null&&typeof t.dispose!="function")throw new Error("[PluginRegistry] \u63D2\u4EF6 "+t.name+" \u7684 dispose \u5FC5\u987B\u662F\u51FD\u6570\u6216\u7701\u7565");if(this._plugins.has(t.name))throw new Error("[PluginRegistry] \u63D2\u4EF6\u91CD\u540D\u62D2\u7EDD\uFF1A"+t.name+" \u5DF2\u6CE8\u518C");return this._plugins.set(t.name,t),this}has(t){return this._plugins.has(t)}get(t){return this._plugins.get(t)}list(){return Array.from(this._plugins.keys())}initAll(){if(this._phase==="initialized")return Ji("[PluginRegistry] initAll \u91CD\u590D\u8C03\u7528\uFF0C\u5DF2\u5FFD\u7565\uFF08\u5DF2\u5904\u4E8E initialized\uFF09"),this._initResult();if(this._phase==="disposed")throw new Error("[PluginRegistry] \u5DF2 dispose \u7684\u6CE8\u518C\u5668\u4E0D\u53EF\u518D initAll");if(this._context==null)throw new Error("[PluginRegistry] \u672A\u6CE8\u5165\u53D7\u63A7\u4E0A\u4E0B\u6587\uFF1A\u8BF7\u5728 initAll() \u4E4B\u524D\u8C03\u7528 useContext(context)\u3002\uFF08host-dev \u7528\u6CD5\uFF1Aconst { context } = createHostDevContext(); reg.useContext(context); reg.initAll();\uFF09");for(let[t,e]of this._plugins){let s=this._missingDeps(e);if(s.length>0){let o=new Error("[PluginRegistry] \u63D2\u4EF6 "+t+" \u4F9D\u8D56\u7F3A\u5931\uFF1A"+s.join(", ")+"\uFF08\u672A\u6CE8\u518C\uFF09");this._initErrors.push({name:t,error:o}),Ne("[PluginRegistry] \u8DF3\u8FC7 init\uFF08\u4F9D\u8D56\u7F3A\u5931\uFF0C\u5DF2\u9694\u79BB\uFF09\uFF1A"+t,o);continue}let i=this._contextFor(t);try{e.init(i),this._initOrder.push(t)}catch(o){let r=o instanceof Error?o:new Error(String(o));this._initErrors.push({name:t,error:r}),Ne("[PluginRegistry] \u63D2\u4EF6 init \u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF0C\u4E0D\u8FDE\u5750\uFF09\uFF1A"+t,r)}}return this._phase="initialized",this._initResult()}_contextFor(t){let e=this._pluginContexts.get(t);if(e)return e;let s=this._context&&this._context[zi],i;return s&&typeof s.deriveContextFor=="function"?i=s.deriveContextFor(t,t):i=this._context,this._pluginContexts.set(t,i),i}disposeAll(){if(this._disposed)return{disposed:[],errors:[]};let t=[],e=[],s=this._context&&this._context[zi],i=s&&s.inputBridge;for(let o=this._initOrder.length-1;o>=0;o--){let r=this._initOrder[o],a=this._plugins.get(r);if(a&&typeof a.dispose=="function")try{a.dispose(),t.push(r)}catch(c){let l=c instanceof Error?c:new Error(String(c));e.push({name:r,error:l}),Ne("[PluginRegistry] \u63D2\u4EF6 dispose \u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09\uFF1A"+r,l)}if(i&&typeof i.disposeScope=="function")try{i.disposeScope(r)}catch(c){Ne("[PluginRegistry] \u56DE\u6536\u63D2\u4EF6\u8F93\u5165\u8BA2\u9605\u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09\uFF1A"+r,c)}}return this._disposed=!0,this._phase="disposed",{disposed:t,errors:e}}useContext(t){if(this._phase!=="idle")throw new Error("[PluginRegistry] useContext \u5FC5\u987B\u5728 initAll() \u4E4B\u524D\u8C03\u7528\uFF08\u5F53\u524D\u9636\u6BB5\uFF1A"+this._phase+"\uFF09\u3002\u8BF7\u5728\u4EFB\u4F55 initAll/disposeAll \u4E4B\u524D\u6CE8\u5165\u53D7\u63A7\u4E0A\u4E0B\u6587\u3002");if(t==null||typeof t!="object")throw new Error("[PluginRegistry] useContext \u9700\u8981\u4E00\u4E2A\u53D7\u63A7\u4E0A\u4E0B\u6587\u5BF9\u8C61\u3002\uFF08host-dev \u7528\u6CD5\uFF1Aconst { context } = createHostDevContext(); reg.useContext(context);\uFF09");return this._context=t,this}_missingDeps(t){return!Array.isArray(t.dependencies)||t.dependencies.length===0?[]:t.dependencies.filter(e=>!this._plugins.has(e))}_initResult(){return{ok:this._initErrors.length===0,initialized:this._initOrder.slice(),errors:this._initErrors.slice()}}};function zc(n,t){let e=2166136261,s=16777619,i=n>>>0;for(let r=0;r<32;r+=8){let a=i>>>r&255;e^=a,e=Math.imul(e,s)>>>0}let o=String(t);for(let r=0;r>>0,e^=a>>>8&255,e=Math.imul(e,s)>>>0}return e>>>0}function Jc(){if(typeof globalThis!="undefined"&&globalThis.performance&&typeof globalThis.performance.now=="function")return()=>globalThis.performance.now();if(typeof process!="undefined"&&process.hrtime&&typeof process.hrtime.bigint=="function"){let n=process.hrtime.bigint();return()=>Number(process.hrtime.bigint()-n)/1e6}return()=>Date.now()}function Ne(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function Ji(n){typeof console!="undefined"&&typeof console.warn=="function"&&console.warn(n)}var xd=Object.freeze(Array.from(Ni)),qr="core-protocol-v0";var Hr=Object.freeze(["t_boot","t_plugins_ready","t_game_init","t_first_paint","t_input_bound","t_game_start"]),Ui=Hr.reduce((n,t,e)=>(n[t]=e,n),Object.create(null)),Uc=new Set(Hr);function Vi(n){let t=2166136261;for(let e=0;e>>0).toString(16).padStart(8,"0")}var Xr=Vi("runtime-probe::seed::v1");function ks(n){return n===null||typeof n!="object"?JSON.stringify(n):Array.isArray(n)?"["+n.map(ks).join(",")+"]":"{"+Object.keys(n).sort().map(e=>JSON.stringify(e)+":"+ks(n[e])).join(",")+"}"}function Yr(n){let t=ks(n.extra==null?null:n.extra),e=ks(Array.isArray(n.pluginSet)?n.pluginSet:[]);return["seq="+n.seq,"anchor="+n.anchor,"tMono="+n.tMono,"buildSha="+(n.buildSha||""),"pluginSet="+e,"extra="+t].join("|")}function Vc(n){return Math.round(n*1e3)/1e3}function Wc(n){if(!Array.isArray(n))return{ok:!1,reason:"records_not_array"};let t=Xr,e=-1;for(let s=0;stypeof _=="string").slice().sort():[],i=typeof t.sink=="function"?t.sink:null,o=t.autoBoot!==!1,r=typeof t.inputAnchorType=="string"?t.inputAnchorType:"pointerdown",a=()=>0,c=!1,l=0,u=Xr,h=[],p=new Set,d=-1,y=null,x=!1,v=!1,T=!1;function C(_,A){let S=null;if(!Uc.has(_))S="unknown_anchor";else{p.has(_)&&(S=S?S+";duplicate_anchor":"duplicate_anchor");let M=Ui[_];M_.time.nowMs(),c=!0,o&&!v&&C("t_boot",{auto:!0}),y=_.getInput().on(r,A=>{x||(x=!0,C("t_input_bound",{firstInput:!0,type:A.type}))}),C("t_input_bound",{stage:"registered",type:r})},dispose(){T||(y&&(y.cancel(),y=null),T=!0)},mark:C,getRecords(){return h.map(_=>({..._}))},toJSONL(){return h.map(_=>JSON.stringify(_)).join(`
+`)},verify(){return Wc(h)}}}function qc(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function Kr(n){let t=n.LJS,e=n.engineMath,s=n.engineMode,i=n.recHook||(()=>{});if(s!=="real")return null;let o=e;return{math:{lerp:(a,c,l)=>(i("math.lerp"),o.lerp(a,c,l)),smoothStep:a=>(i("math.smoothStep"),o.smoothStep(a)),easing:Object.fromEntries(Object.keys(o.easing).map(a=>[a,c=>(i("math.easing."+a),o.easing[a](c))]))},particles:{spawnEmitter(a){i("particles.spawnEmitter");let c=t.screenToWorld(t.vec2(a.pos.x,a.pos.y)),l=t.cameraScale,u=a.emitTime!=null?a.emitTime:a.count!=null?1/60:0,h=a.emitRate!=null?a.emitRate:a.count!=null?a.count*60:100,p=(a.speed!=null?a.speed:0)/l/60,d=a.damping!=null?a.damping:1,y=a.colorStart||{r:1,g:1,b:1,a:1},x=a.colorEnd||{r:1,g:1,b:1,a:0},v=t.rgb(y.r,y.g,y.b,y.a),T=t.rgb(x.r,x.g,x.b,x.a),C=new t.ParticleEmitter(c,a.angle!=null?a.angle:0,(a.emitSize!=null?a.emitSize:0)/l,u,h,a.coneAngle!=null?a.coneAngle:Math.PI,void 0,v,v,T,T,a.particleTime!=null?a.particleTime:.5,(a.sizeStart!=null?a.sizeStart:6)/l,(a.sizeEnd!=null?a.sizeEnd:0)/l,p,0,d,1,a.gravityScale!=null?a.gravityScale:0,Math.PI,.1,0,!1,a.additive!=null?a.additive:!1,!0);return{isActive(){return C.isActive()},stop(){C.destroyed||C.destroy(!0)}}}},audio:{synth:{synthSfx:a=>{i("audio.synth.synthSfx");try{return t.zzfxG(...a)}catch(c){return console.error("[host][engine-audio] zzfxG \u5408\u6210\u5F02\u5E38\uFF0C\u8FD4 null\uFF1A"+(c&&c.message?c.message:c)),null}},synthSong:(a,c,l,u)=>{i("audio.synth.synthSong");try{return t.zzfxM(a,c,l,u)}catch(h){return console.error("[host][engine-audio] zzfxM \u5408\u6210\u5F02\u5E38\uFF0C\u8FD4 null\uFF1A"+(h&&h.message?h.message:h)),null}}}}}}function ie(n){return n<0?0:n>1?1:n}function Qr(n){let t=n.Ease,e=t.POWER(2),s=t.POWER(3),i=t.OUT(e),o=t.IN_OUT(e),r=t.OUT(s),a=t.IN_OUT(s),c=t.OUT(t.BACK),l=t.OUT(t.ELASTIC);return{lerp:(u,h,p)=>n.lerp(u,h,p),smoothStep:u=>n.smoothStep(u),easing:{linear:u=>t.LINEAR(ie(u)),quadIn:u=>e(ie(u)),quadOut:u=>i(ie(u)),quadInOut:u=>o(ie(u)),cubicIn:u=>s(ie(u)),cubicOut:u=>r(ie(u)),cubicInOut:u=>a(ie(u)),backIn:u=>t.BACK(ie(u)),backOut:u=>c(ie(u)),elasticIn:u=>t.ELASTIC(ie(u)),elasticOut:u=>l(ie(u))}}}var ze=2,Gs=1/60;async function Zr(n){let t=n.canvas,e=n.statusEl||null,s=n.engine,i=n.seed>>>0,o=n.mode||"play",r=n.engineMode||"real",a=n.viewport.w,c=n.viewport.h,l=n.factory,u=n.buildFactoryOpts||(()=>{}),h=n.plugins||{},p=n.registerOrder||Object.values(h),d=n.onReady||(()=>{}),y=n.recHook||(()=>{});function x(O){e&&(e.textContent=O)}let v=[];window.addEventListener("error",O=>v.push({type:"error",message:String(O&&O.message||O)})),window.addEventListener("unhandledrejection",O=>v.push({type:"unhandledrejection",message:String(O&&O.reason&&O.reason.message||O&&O.reason||O)}));let T=null,C=!1;function w(){if(!C)return null;if(T)return T;let O=window.AudioContext||window.webkitAudioContext;return O?(T=new O,T):null}let _=0,A=null,S=null,R=null,M=null,ot=[],$={},nt=null;function rt(O,st){try{R&&R.mark(O,st)}catch($t){v.push({type:"mark",message:String($t&&$t.message||$t)})}}function Et(){S&&typeof S._refreshChecklist=="function"&&S._refreshChecklist($)}async function ne(O,st){A=Wr({context2d:O,seed:i,audioFactory:w,clock:()=>_,engineFactory:()=>Kr({LJS:r==="real"?s:null,engineMath:r==="real"?Qr(s):null,engineMode:r,recHook:y})});let $t=new Ms;for(let de of p)$t.register(de);$t.useContext(A.context),M=$t.initAll(),ot=$t.list().concat(["runtime-probe"]),R=$r({pluginSet:ot,inputAnchorType:"pointerdown",autoBoot:!0});let _t=A.deriveContextFor("runtime-probe","runtime-probe");rt("t_boot",{by:"game-host",stage:"pre-init",engineMode:r}),rt("t_plugins_ready",{initialized:M.initialized.length,ok:M.ok});let Gi=u(A.context,{bundle:A,plugins:h,getRealAudioCtx:()=>T});S=l(Gi),await S.init({ctx:A.context,mainContext:O,canvas:st(),seed:i}),nt=S&&typeof S._forensicsView=="function"?S._forensicsView():null,rt("t_game_init",{hasForensics:!!nt}),lt(),rt("t_first_paint",{frame:A.frameCount()});try{R.init(_t)}catch(de){v.push({type:"probe-init",message:String(de&&de.message||de)})}rt("t_game_start",{mode:o,engineMode:r}),Et(),d(sn,{bundle:A,game:S,probe:R,checklist:$,uncaught:v,pluginSet:ot,initRes:M,getGameForensics:()=>nt,mark:rt,stepOneFrame:lt})}let kt=null;function lt(O){let st=typeof O=="number"?O:Gs;S&&(_+=st*1e3,S.update(st),r==="stub"&&kt&&S.render(kt),Et())}function Pt(O){for(let st=0;st{}),S&&typeof S._onAudioUnlock=="function"&&S._onAudioUnlock()}let sn={seed:i,mode:o,engineMode:r,protocol:qr,frameCount:()=>A?A.frameCount():0,stepFrames:Pt,startRaf:()=>gt(),stopRaf:()=>vt(),tap(O,st){he(),A&&(A.inputBridge._emit("pointerdown",{x:O,y:st}),A.inputBridge._emit("pointerup",{x:O,y:st}))},do(O){S&&typeof S._handleAction=="function"&&S._handleAction(O)},state:()=>nt?nt.state():{phase:"booting"}};function on(O){let st=A.inputBridge;function $t(_t,Gi){let de=O.getBoundingClientRect();return{x:(_t-de.left)/de.width*a,y:(Gi-de.top)/de.height*c}}O.addEventListener("pointerdown",_t=>{he(),st._emit("pointerdown",$t(_t.clientX,_t.clientY))}),O.addEventListener("pointermove",_t=>{st._emit("pointermove",$t(_t.clientX,_t.clientY))}),O.addEventListener("pointerup",_t=>{st._emit("pointerup",$t(_t.clientX,_t.clientY))}),window.addEventListener("keydown",_t=>{he(),st._emit("keydown",{key:_t.key})}),window.addEventListener("keyup",_t=>st._emit("keyup",{key:_t.key}))}let se=0,Ee=!1,D=0;function k(O){if(!Ee)return;D===0&&(D=O);let st=(O-D)/1e3;D=O,st>.05&&(st=.05),lt(st),se=window.requestAnimationFrame(k)}function gt(){r==="stub"&&(Ee||(Ee=!0,D=0,se=window.requestAnimationFrame(k)))}function vt(){Ee=!1,se&&window.cancelAnimationFrame(se),se=0}function Vt(O){O.width=a*ze,O.height=c*ze,O.style.width=a+"px",O.style.height=c+"px";let st=O.getContext("2d",{willReadFrequently:!0});return st.setTransform(ze,0,0,ze,0,0),st}async function rn(){let O=Vt(t);return kt=O,await ne(O,()=>t),on(t),o==="evidence"?x(`evidence \u5C31\u7EEA seed=${i} \xB7 \u7528 host \u9A71\u52A8\uFF08stepFrames/tap\uFF09`):(x(`seed=${i} \xB7 \u70B9\u5F00\u59CB\uFF08\u9996\u6B21\u70B9\u51FB\u5F00\u58F0\uFF09`),gt()),sn}let qn=()=>{},Hn=()=>{};function Os(){window.__gameHostEngineInitFired=!0}function Ds(){qn()}function Ur(){}function Dc(){Hn()}function Ic(){}async function Mc(O){await ne(O,()=>s.mainCanvas),on(s.mainCanvas),qn=()=>{S&&(_+=Gs*1e3,S.update(Gs))},Hn=()=>{if(S){O.save(),O.setTransform(ze,0,0,ze,0,0);try{O.imageSmoothingEnabled=!1}catch{}S.render(O),O.restore()}},s.mainCanvas&&(s.mainCanvas.id="game-engine"),window.__engine={frame(){return s.frame},time(){return s.time},timeReal(){return s.timeReal},paused(){return s.paused},timeScale(){return s.timeScale},snapshot(){return{frame:s.frame,time:s.time,timeReal:s.timeReal,paused:s.paused,timeScale:s.timeScale}}},x(`engine RAF running \xB7 seed=${i} engine=real`)}if(r!=="real")return await rn();if(!s){let O="real \u901A\u9053\u672A\u6CE8\u5165\u5F15\u64CE\uFF08opts.engine \u7F3A\u5931\uFF09\uFF1A\u8BF7\u7ECF entry \u5305\u88C5\u5C42\u542F\u52A8\uFF08host \u4E0D\u76F4\u63A5 import \u5F15\u64CE\uFF0CQ4/Option C\uFF09";throw x("ENGINE INJECT MISSING: "+O),new Error(O)}s.setGLEnable(!1),s.setShowSplashScreen(!1),s.setDebugWatermark(!1),s.setCanvasClearColor(s.BLACK),s.setCanvasFixedSize(s.vec2(a*ze,c*ze));let ki=document.createElement("div");return ki.id="engine-root",document.body.appendChild(ki),await s.engineInit(Os,Ds,Ur,Dc,Ic,[],ki).then(()=>Mc(s.mainContext)).catch(O=>{throw window.__gameHostBootError=String(O&&O.message||O),x("ENGINE INIT FAILED: "+window.__gameHostBootError),O}),sn}var Wi=class{constructor(t){let e=t||{},s=typeof e.cellSize=="number"&&e.cellSize>0?e.cellSize:64;this._cellSize=s,this._cells=new Map,this._entries=new Map,this._seq=0}get size(){return this._entries.size}_cellRange(t){let e=this._cellSize,s=Math.floor((t.x-t.hw)/e),i=Math.floor((t.x+t.hw)/e),o=Math.floor((t.y-t.hh)/e),r=Math.floor((t.y+t.hh)/e);return{cx0:s,cy0:o,cx1:i,cy1:r}}insert(t,e){this._entries.has(t)&&this.remove(t);let{cx0:s,cy0:i,cx1:o,cy1:r}=this._cellRange(e),a=[];for(let l=i;l<=r;l++)for(let u=s;u<=o;u++){let h=u+","+l,p=this._cells.get(h);p||(p=new Set,this._cells.set(h,p)),p.add(t),a.push(h)}let c={x:e.x,y:e.y,hw:e.hw,hh:e.hh};this._entries.set(t,{id:t,box:c,seq:this._seq++,cells:a})}remove(t){let e=this._entries.get(t);if(!e)return!1;for(let s of e.cells){let i=this._cells.get(s);i&&(i.delete(t),i.size===0&&this._cells.delete(s))}return this._entries.delete(t),!0}query(t){let{cx0:e,cy0:s,cx1:i,cy1:o}=this._cellRange(t),r=new Set;for(let a=s;a<=o;a++)for(let c=e;c<=i;c++){let l=this._cells.get(c+","+a);if(l)for(let u of l)r.add(u)}return this._collect(r)}queryPoint(t,e){let s=this._cellSize,i=Math.floor(t/s),o=Math.floor(e/s),r=this._cells.get(i+","+o);return r?this._collect(new Set(r)):[]}clear(){this._cells.clear(),this._entries.clear(),this._seq=0}_collect(t){let e=[];for(let s of t){let i=this._entries.get(s);i&&e.push(i)}return e.sort((s,i)=>s.seq-i.seq),e.map(s=>({id:s.id,box:s.box}))}};function ta(n){let t=n||{},e=new Wi({cellSize:t.cellSize}),s=!1;return{name:"collision",version:"1.0.0",dependencies:[],spatial:e,init(o){},dispose(){s||(e.clear(),s=!0)}}}function ea(n){let t=!1;return{name:"physics-lite",version:"1.0.0",dependencies:[],init(s){},dispose(){t||(t=!0)}}}var Hc=["pointerdown","pointermove","pointerup","keydown","keyup"];function Gt(n){return n<0?0:n>1?1:n}var Xc=n=>(n=Gt(n),n*n),Yc=n=>(n=Gt(n),1-(1-n)*(1-n)),$c=n=>(n=Gt(n),n<.5?2*n*n:1-Math.pow(-2*n+2,2)/2),Kc=n=>(n=Gt(n),n*n*n),Qc=n=>{n=Gt(n);let t=1-n;return 1-t*t*t},Zc=n=>(n=Gt(n),n<.5?4*n*n*n:1-Math.pow(-2*n+2,3)/2),ia=2*Math.PI/3,na=2*Math.PI/4.5,tl=n=>(n=Gt(n),n===0?0:n===1?1:-Math.pow(2,10*n-10)*Math.sin((n*10-10.75)*ia)),el=n=>(n=Gt(n),n===0?0:n===1?1:Math.pow(2,-10*n)*Math.sin((n*10-.75)*ia)+1),nl=n=>(n=Gt(n),n===0?0:n===1?1:n<.5?-(Math.pow(2,20*n-10)*Math.sin((20*n-11.125)*na))/2:Math.pow(2,-20*n+10)*Math.sin((20*n-11.125)*na)/2+1),js=1.70158,Fs=js*1.525,oa=js+1,sl=n=>(n=Gt(n),oa*n*n*n-js*n*n),il=n=>{n=Gt(n);let t=n-1;return 1+oa*t*t*t+js*t*t},ol=n=>(n=Gt(n),n<.5?Math.pow(2*n,2)*((Fs+1)*2*n-Fs)/2:(Math.pow(2*n-2,2)*((Fs+1)*(n*2-2)+Fs)+2)/2),rl=n=>Gt(n),sa=Object.freeze({linear:rl,quadIn:Xc,quadOut:Yc,quadInOut:$c,cubicIn:Kc,cubicOut:Qc,cubicInOut:Zc,elasticIn:tl,elasticOut:el,elasticInOut:nl,backIn:sl,backOut:il,backInOut:ol});var al=["linear","quadIn","quadOut","quadInOut","cubicIn","cubicOut","cubicInOut","elasticIn","elasticOut","elasticInOut","backIn","backOut","backInOut"];function cl(n){let t=n&&n.easing;if(!t)return sa;let e=i=>typeof t[i]=="function"?o=>t[i](Gt(o)):sa[i],s={};for(let i of al)s[i]=e(i);return Object.freeze(s)}var qi=class{constructor(t,e,s){let i=s||{};this._time=e,this._windowMs=typeof i.windowMs=="number"&&i.windowMs>0?i.windowMs:120;let o=Array.isArray(i.types)&&i.types.length>0?i.types:Hc;this._records=new Map,this._subs=[],this._disposed=!1;for(let r of o){this._records.set(r,null);let a=t.on(r,c=>{this._records.set(r,c.tMs)});this._subs.push(a)}}consume(t,e){let s=typeof e=="number"?e:this._time.nowMs(),i=this._records.get(t);return i==null?!1:s-i<=this._windowMs?(this._records.set(t,null),!0):(this._records.set(t,null),!1)}peek(t,e){let s=typeof e=="number"?e:this._time.nowMs(),i=this._records.get(t);return i==null?!1:s-i<=this._windowMs}clear(){for(let t of this._records.keys())this._records.set(t,null)}dispose(){if(!this._disposed){for(let t of this._subs)try{t.cancel()}catch(e){}this._subs=[],this._disposed=!0}}};function ra(n){let t=n||{},e=null,s=null,i=!1;return{name:"gamefeel",version:"1.0.0",dependencies:[],get inputBuffer(){return e},get easing(){return cl(s)},init(r){let a=r.getInput();e=new qi(a,r.time,{windowMs:t.inputBufferMs,types:t.inputTypes});let c=r.getEngine();s=c?c.math:null},dispose(){i||(e&&(e.dispose(),e=null),s=null,i=!0)}}}function Bs(n,t){let e=t<0?0:t>1?1:t;switch(n&&n.kind){case"constant":return n.value;case"linear":return n.from+(n.to-n.from)*e;case"easeInOut":{let s=e*e*(3-2*e);return n.from+(n.to-n.from)*s}case"decay":{let s=n.power==null?2:n.power,i=Math.pow(1-e,s);return n.to+(n.from-n.to)*i}default:return 0}}var ll=Object.freeze({burst:Object.freeze({mode:"burst",count:24,angle:0,spread:Math.PI,speedMin:80,speedMax:160,lifeMin:.4,lifeMax:.8,gravity:0,drag:0,sizeCurve:{kind:"decay",from:6,to:0,power:1.5},alphaCurve:{kind:"linear",from:1,to:0}}),trail:Object.freeze({mode:"continuous",rate:60,angle:Math.PI,spread:.25,speedMin:20,speedMax:50,lifeMin:.2,lifeMax:.5,gravity:0,drag:1.5,sizeCurve:{kind:"easeInOut",from:4,to:0},alphaCurve:{kind:"decay",from:.8,to:0,power:2}}),drift:Object.freeze({mode:"continuous",rate:12,angle:Math.PI/2,spread:.6,speedMin:10,speedMax:30,lifeMin:1.5,lifeMax:3,gravity:8,drag:.5,sizeCurve:{kind:"constant",value:3},alphaCurve:{kind:"decay",from:.7,to:0,power:1}})});function ul(n){let t=ll[n];return t?Hi(t):null}function Hi(n){let t={};for(let e of Object.keys(n)){let s=n[e];t[e]=s&&typeof s=="object"?Hi(s):s}return t}function hl(n,t,e){let s=n.mode==="continuous";return{pos:{x:t,y:e},angle:n.angle,coneAngle:n.spread,emitSize:0,emitTime:s?0:1/60,emitRate:s?n.rate||0:void 0,count:s?void 0:n.count||0,particleTime:(n.lifeMin+n.lifeMax)/2,speed:(n.speedMin+n.speedMax)/2,gravityScale:n.gravity||0,damping:n.drag!=null?1-n.drag/60:1,sizeStart:Bs(n.sizeCurve,0),sizeEnd:Bs(n.sizeCurve,1),colorStart:{r:1,g:1,b:1,a:Bs(n.alphaCurve,0)},colorEnd:{r:1,g:1,b:1,a:Bs(n.alphaCurve,1)},additive:!1}}function aa(n){let t=n||{},e=null,s=null,i=null,o=new Map,r=0,a={isActive(){return!1},stop(){}},c=0,l=1,u=0,h=0,p=0,d={x:0,y:0,remain:0,dur:0,amplitude:0,frequency:0,_phase:0},y={alpha:0,remain:0,dur:0,peak:0},x={scale:1,remain:0,dur:0,amplitude:0,frequency:0},v=!1;function T(A){if(u>0)if(u-=A,u<=0)u=0,l=1;else{let S=h>0?1-u/h:1;l=p+(1-p)*S}if(d.remain>0)if(d.remain-=A,d.remain<=0)d.remain=0,d.x=0,d.y=0;else{let S=d.remain/d.dur,R=d.amplitude*S;d._phase+=d.frequency*A*Math.PI*2,d.x=Math.sin(d._phase)*R,d.y=Math.cos(d._phase*1.3)*R}if(y.remain>0&&(y.remain-=A,y.remain<=0?(y.remain=0,y.alpha=0):y.alpha=y.peak*(y.remain/y.dur)),x.remain>0)if(x.remain-=A,x.remain<=0)x.remain=0,x.scale=1;else{let S=x.remain/x.dur,R=(1-S)*x.frequency*Math.PI*2;x.scale=1+Math.sin(R)*x.amplitude*S}}function C(A){c+=1,T(A)}function w(A){let S=A!==void 0?A:e?e.getContext2d():null;if(S&&y.alpha>0){S.globalAlpha=y.alpha,S.fillStyle="#ffffff";let R=S.canvas?S.canvas.width:0,M=S.canvas?S.canvas.height:0;S.fillRect(0,0,R,M),S.globalAlpha=1}}return{name:"particles-juice",version:"1.0.0",dependencies:[],init(A){var S;e=A,i=((S=A.getEngine())==null?void 0:S.particles)||null,typeof t.seed=="number"&&A.random.reseed(t.seed),t.autoStep!==!1&&(s=A.onFrame(R=>{C(R)}))},dispose(){v||(s&&(s.cancel(),s=null),o.forEach(A=>{try{A.stop()}catch{}}),o.clear(),l=1,u=0,d.remain=0,d.x=0,d.y=0,y.remain=0,y.alpha=0,x.remain=0,x.scale=1,v=!0)},spawnEmitter(A,S,R,M){let ot=typeof A=="string"?ul(A):Hi(A);if(!ot)return-1;M&&(ot=Object.assign(ot,M));let $=r++;if(!i)return o.set($,a),$;let nt=i.spawnEmitter(hl(ot,S,R));return o.set($,nt),$},stopEmitter(A){let S=o.get(A);if(S)try{S.stop()}catch{}},step(A){C(A)},render(A){w(A)},particleCount(){return 0},emitterCount(){let A=0;for(let S of o.values())S.isActive()&&(A+=1);return A},hitStop(A,S){h=Math.max(0,A),u=h,p=S==null?0:Math.max(0,Math.min(1,S)),l=h>0?p:1},getTimeScale(){return l},shakeScreen(A,S,R){d.dur=Math.max(0,A),d.remain=d.dur,d.amplitude=Math.max(0,S),d.frequency=R==null?30:R,d._phase=0,d.x=0,d.y=0},getShakeOffset(){return{x:d.x,y:d.y}},flashScreen(A,S){y.dur=Math.max(0,A),y.remain=y.dur,y.peak=S==null?.8:Math.max(0,Math.min(1,S)),y.alpha=y.dur>0?y.peak:0},getFlashAlpha(){return y.alpha},pulseScale(A,S,R){x.dur=Math.max(0,A),x.remain=x.dur,x.amplitude=S==null?.2:S,x.frequency=R==null?4:R,x.scale=1},getPulseScale(){return x.scale},juiceSnapshot(){return{timeScale:l,shake:{x:d.x,y:d.y},flashAlpha:y.alpha,pulseScale:x.scale}},probe(){return{particles:0,emitters:o.size,dropped:0,steps:c,disposed:v}}}}function ca(n){let t=dt(n.r)/255,e=dt(n.g)/255,s=dt(n.b)/255,i=Math.max(t,e,s),o=Math.min(t,e,s),r=(i+o)/2,a=0,c=0,l=i-o;return l>1e-12&&(c=r>.5?l/(2-i-o):l/(i+o),i===t?a=(e-s)/l%6:i===e?a=(s-t)/l+2:a=(t-e)/l+4,a*=60,a<0&&(a+=360)),{h:a,s:c,l:r}}function la(n){let t=(n.h%360+360)%360,e=Je(n.s),s=Je(n.l);if(e<1e-12){let a=Math.round(s*255);return{r:a,g:a,b:a}}let i=s<.5?s*(1+e):s+e-s*e,o=2*s-i,r=t/360;return{r:Math.round(Xi(o,i,r+1/3)*255),g:Math.round(Xi(o,i,r)*255),b:Math.round(Xi(o,i,r-1/3)*255)}}function Xi(n,t,e){let s=e;return s<0&&(s+=1),s>1&&(s-=1),s<1/6?n+(t-n)*6*s:s<1/2?t:s<2/3?n+(t-n)*(2/3-s)*6:n}function dt(n){return n<0?0:n>255?255:n}function Je(n){return n<0?0:n>1?1:n}function dl(n,t){let e=pl(n.from,t);if(e>=0&&e({r:dt(a.r),g:dt(a.g),b:dt(a.b)})),to:o}}function Yi(n,t,e){return n+(t-n)*e}function ml(n,t){let e=ca(n),s=e.h+(t.hue||0),i=Je(e.s*(t.sat==null?1:t.sat)),o=Je(e.l*(t.light==null?1:t.light));return la({h:s,s:i,l:o})}var bl=Object.freeze([Object.freeze([0,8,2,10]),Object.freeze([12,4,14,6]),Object.freeze([3,11,1,9]),Object.freeze([15,7,13,5])]);function ua(n){let t=n||{},e=null,s=!1,i={vignette:{enabled:$i(t.vignette&&t.vignette.enabled,!1),strength:Ki(t.vignette&&t.vignette.strength,.5)},dither:{enabled:$i(t.dither&&t.dither.enabled,!1),strength:Ki(t.dither&&t.dither.strength,.5)},scanline:{enabled:$i(t.scanline&&t.scanline.enabled,!1),strength:Ki(t.scanline&&t.scanline.strength,.5)}};function o(a){let c=a!==void 0?a:e?e.getContext2d():null;if(!c)return;let l=c.canvas?c.canvas.width:0,u=c.canvas?c.canvas.height:0;if(i.vignette.enabled&&i.vignette.strength>0&&l>0&&u>0){let h=c.createRadialGradient(l/2,u/2,Math.min(l,u)*.25,l/2,u/2,Math.max(l,u)*.75);h.addColorStop(0,"rgba(0,0,0,0)"),h.addColorStop(1,"rgba(0,0,0,"+i.vignette.strength.toFixed(3)+")"),c.fillStyle=h,c.fillRect(0,0,l,u)}if(i.scanline.enabled&&i.scanline.strength>0&&l>0&&u>0){c.fillStyle="rgba(0,0,0,"+(i.scanline.strength*.5).toFixed(3)+")";for(let h=0;h0&&l>0&&u>0&&typeof c.getImageData=="function"&&typeof c.putImageData=="function"){let h=c.getImageData(0,0,l,u);xl(h,i.dither.strength),c.putImageData(h,0,0)}}return{name:"palette-post",version:"1.0.0",dependencies:[],init(a){e=a},dispose(){s||(e=null,s=!0)},applyPaletteMap(a,c){return dl(a,c)},applyPaletteMapToBuffer(a,c){return fl(a,c)},lerpPaletteMap(a,c,l){return yl(a,c,l)},shiftHsl(a,c){return ml(a,c)},rgbToHsl(a){return ca(a)},hslToRgb(a){return la(a)},setPost(a){if(a)for(let c of["vignette","dither","scanline"])a[c]&&(typeof a[c].enabled=="boolean"&&(i[c].enabled=a[c].enabled),typeof a[c].strength=="number"&&(i[c].strength=Je(a[c].strength)))},getPost(){return{vignette:{enabled:i.vignette.enabled,strength:i.vignette.strength},dither:{enabled:i.dither.enabled,strength:i.dither.strength},scanline:{enabled:i.scanline.enabled,strength:i.scanline.strength}}},renderPost(a){o(a)},probe(){return{disposed:s,post:this.getPost()}}}}function xl(n,t){let e=Je(t);if(e<=0)return n;let{data:s,width:i}=n,r=255/(Math.max(2,Math.round(16-e*14))-1);for(let a=0;a+3>2)%i,l=Math.floor((a>>2)/i),u=(bl[l&3][c&3]/16-.5)*r;for(let h=0;h<3;h++){let p=s[a+h]+u,d=Math.round(p/r)*r;s[a+h]=d<0?0:d>255?255:d}}return n}function $i(n,t){return typeof n=="boolean"?n:t}function Ki(n,t){return typeof n=="number"?Je(n):t}var Zi=Object.freeze({blip:Object.freeze({name:"blip",params:Object.freeze([.6,0,880,0,.03,.06,1,1.5])}),thud:Object.freeze({name:"thud",params:Object.freeze([.8,0,90,0,.04,.18,0,1,0,0,0,0,0,4])}),chime:Object.freeze({name:"chime",params:Object.freeze([.5,0,660,.02,.12,.3,1,2])})}),ha=Object.keys(Zi);function vl(n){let t=[];return n==null||typeof n!="object"?{ok:!1,errors:["song \u5FC5\u987B\u662F\u5BF9\u8C61"]}:(!Array.isArray(n.instruments)||n.instruments.length===0?t.push("instruments \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4"):n.instruments.forEach((e,s)=>{(!Array.isArray(e)||e.some(i=>typeof i!="number"||!Number.isFinite(i)))&&t.push(`instruments[${s}] \u5FC5\u987B\u662F\u6709\u9650\u6570\u5B57\u6570\u7EC4\uFF08ZzFX \u53C2\u6570\u5305\uFF09`)}),!Array.isArray(n.patterns)||n.patterns.length===0?t.push("patterns \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4"):n.patterns.forEach((e,s)=>{if(!Array.isArray(e)||e.length===0){t.push(`patterns[${s}] \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4\uFF08\u81F3\u5C11\u4E00\u4E2A\u58F0\u90E8\u901A\u9053\uFF09`);return}e.forEach((i,o)=>{if(!Array.isArray(i)||i.length<2){t.push(`patterns[${s}][${o}] \u901A\u9053\u81F3\u5C11\u542B [\u4E50\u5668\u7D22\u5F15, \u58F0\u50CF]`);return}if(i.some(c=>typeof c!="number"||!Number.isFinite(c))){t.push(`patterns[${s}][${o}] \u901A\u9053\u5FC5\u987B\u5168\u4E3A\u6709\u9650\u6570\u5B57`);return}let r=i[0]|0;Array.isArray(n.instruments)&&(r<0||r>=n.instruments.length)&&t.push(`patterns[${s}][${o}] \u4E50\u5668\u7D22\u5F15 ${r} \u8D8A\u754C\uFF08instruments \u957F\u5EA6 ${n.instruments.length}\uFF09`);let a=i[1];(a<-1||a>1)&&t.push(`patterns[${s}][${o}] \u58F0\u50CF ${a} \u8D8A\u754C\uFF08\u5E94 -1..+1\uFF09`)})}),!Array.isArray(n.sequence)||n.sequence.length===0?t.push("sequence \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4"):n.sequence.forEach((e,s)=>{if(typeof e!="number"||!Number.isInteger(e)){t.push(`sequence[${s}] \u5FC5\u987B\u662F\u6574\u6570 pattern \u7D22\u5F15`);return}Array.isArray(n.patterns)&&(e<0||e>=n.patterns.length)&&t.push(`sequence[${s}] \u7D22\u5F15 ${e} \u8D8A\u754C\uFF08patterns \u957F\u5EA6 ${n.patterns.length}\uFF09`)}),n.bpm!=null&&(typeof n.bpm!="number"||!(n.bpm>0))&&t.push("bpm \u5FC5\u987B\u662F\u6B63\u6570"),{ok:t.length===0,errors:t})}function fe(n){return typeof n!="number"||Number.isNaN(n)||n<0?0:n>1?1:n}function Sl(n,t){switch(n){case"ease-in":return t*t;case"ease-out":return Math.sqrt(t);case"constant":return 1;default:return t}}function da(n,t){let e=fe(t);return n==null||!Array.isArray(n.voices)?[]:n.voices.map(s=>{let i=String(s&&s.id!=null?s.id:""),o=Array.isArray(s&&s.channelIndices)?s.channelIndices.slice():[],r=typeof s.minIntensity=="number"?fe(s.minIntensity):0,a=typeof s.maxIntensity=="number"?fe(s.maxIntensity):1,c=typeof s.volumeCurve=="string"?s.volumeCurve:"linear",l=typeof s.baseVolume=="number"?fe(s.baseVolume):1;if(ea)return{id:i,on:!1,volume:0,channelIndices:o};let u=a-r,h=u<=0?1:(e-r)/u,p=fe(Sl(c,h)*l);return{id:i,on:!0,volume:p,channelIndices:o}})}function fa(n,t,e,s){try{let i=t[0]||[],o=t[1]||i,r=Math.max(i.length,o.length);if(r===0)return null;let c=n.createBuffer(2,r,44100);c.getChannelData(0).set(i),c.getChannelData(1).set(o.length?o:i);let l=n.createBufferSource();l.buffer=c,l.loop=!!s;let u=n.createGain();return u.gain.value=fe(e*.3),l.connect(u),u.connect(n.destination),l.start(),{stop(){try{l.stop()}catch(h){}try{l.disconnect(),u.disconnect()}catch(h){}}}}catch(i){return to("[audio-music] \u53D7\u63A7\u97F3\u9891\u64AD\u653E\u5F02\u5E38\uFF0C\u964D\u7EA7\u4E3A\u9759\u9ED8",i),null}}function pa(n){let t=n||{},e=typeof t.masterVolume=="number"?fe(t.masterVolume):1,s=()=>null,i=null,o=null,r={voices:[]},a=1,c=null,l=!1,u=0,h=!1,p=!1;function d(){let w=s();return w==null?(u+=1,h||(Qi("[audio-music] \u65E0\u53D7\u63A7\u97F3\u9891\u4E0A\u4E0B\u6587\uFF08getAudioContext \u8FD4\u56DE null\uFF09\uFF0C\u5168\u90E8\u53D1\u58F0\u9759\u9ED8 no-op\uFF08\u8BC4\u4F30\u73AF\u5883\u65E0\u58F0\u5361\u65F6\u7684\u5BB9\u9519\u964D\u7EA7\uFF09"),h=!0),null):w}function y(){if(!o||!i)return null;try{let w=typeof o.bpm=="number"&&o.bpm>0?o.bpm:125;return i.synthSong(o.instruments,o.patterns,o.sequence,w)}catch(w){return to("[audio-music] \u66F2\u8C31\u6E32\u67D3\u5F02\u5E38\uFF0C\u964D\u7EA7\u4E3A\u9759\u9ED8",w),null}}function x(){let w=da(r,a);if(w.length===0)return 1;let _=0;for(let A of w)A.on&&(_=Math.max(_,A.volume));return _}function v(w,_){typeof _=="number"&&(a=fe(_));let A=d();if(A==null||!o)return;T();let S=y();if(!S)return;let R=fe(e*x());c=fa(A,S,R,w),l=!!w&&c!=null}function T(){c&&(c.stop(),c=null),l=!1}return{name:"audio-music",version:"1.0.0",dependencies:[],init(w){s=()=>w.getAudioContext();let _=w.getEngine&&w.getEngine();i=_?_.audio.synth:null},dispose(){p||(T(),p=!0)},loadSong(w){let _=vl(w);return _.ok?o={instruments:w.instruments,patterns:w.patterns,sequence:w.sequence,bpm:typeof w.bpm=="number"?w.bpm:125}:Qi("[audio-music] \u66F2\u8C31\u6821\u9A8C\u5931\u8D25\uFF0C\u672A\u8F7D\u5165\uFF1A"+_.errors.join("\uFF1B")),_},play(w){v(!1,w)},stop(){T()},loop(w){v(!0,w)},setIntensityLayering(w){r=w&&Array.isArray(w.voices)?{voices:w.voices}:{voices:[]}},setIntensity(w){a=fe(w)},resolveVoices(w){return da(r,w)},playSfx(w){let _=Zi[w];if(!_){Qi("[audio-music] \u672A\u77E5\u97F3\u6548\u9884\u8BBE\uFF1A"+String(w));return}let A=d();if(A!=null)try{let S=i?i.synthSfx(_.params):null;if(!S)return;fa(A,[S,S],e,!1)}catch(S){to("[audio-music] \u97F3\u6548\u64AD\u653E\u5F02\u5E38\uFF0C\u964D\u7EA7\u4E3A\u9759\u9ED8 name="+w,S)}},getPreset(w){return Zi[w]},listPresets(){return ha.slice()},probe(){return{hasAudio:s()!=null,hasSong:o!=null,intensity:a,voiceCount:r.voices.length,looping:l,silentNoops:u,presetCount:ha.length}}}}function to(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function Qi(n){typeof console!="undefined"&&typeof console.warn=="function"&&console.warn(n)}var wl="zaomeng.save";function Tl(n){if(typeof TextEncoder!="undefined")return new TextEncoder().encode(n).length;if(typeof Buffer!="undefined"&&typeof Buffer.byteLength=="function")return Buffer.byteLength(n,"utf8");let t=0;for(let e=0;e=55296&&s<=56319?(t+=4,e++):t+=3}return t}function no(){let n=new Map;return{getItem(t){return n.has(t)?n.get(t):null},setItem(t,e){n.set(t,e)},removeItem(t){n.delete(t)},keys(){return Array.from(n.keys())}}}function ga(){if(typeof localStorage=="undefined")throw new Error("[save-progress] createLocalStorageAdapter \u9700\u8981\u5168\u5C40 localStorage\uFF08\u4EC5\u6D4F\u89C8\u5668\u96C6\u6210\u6BB5\u53EF\u7528\uFF09\u3002node/host-dev \u8BF7\u7528\u7F3A\u7701\u5185\u5B58 adapter \u6216 createMemoryAdapter()\u3002");return{getItem(n){return localStorage.getItem(n)},setItem(n,t){localStorage.setItem(n,t)},removeItem(n){localStorage.removeItem(n)},keys(){let n=[];for(let t=0;t0?t.namespace:wl;if(e.indexOf(":")>=0)throw new Error('[save-progress] namespace \u4E0D\u5F97\u542B\u5206\u9694\u7B26 ":"\uFF08\u5F53\u524D="'+e+'"\uFF09');let s=typeof t.maxValueBytes=="number"&&t.maxValueBytes>0?Math.floor(t.maxValueBytes):32768,i=!Al(t.adapter),o=i?no():t.adapter,r=e+":",a=0,c=0,l=!1;function u(d){return typeof d!="string"||d.length===0?r+String(d):r+d}function h(){try{let d=o.keys();return Array.isArray(d)?d.filter(y=>typeof y=="string"&&y.indexOf(r)===0):[]}catch(d){return Xn("[save-progress] adapter.keys() \u5F02\u5E38\uFF0C\u964D\u7EA7\u8FD4\u56DE\u7A7A\u96C6",d),[]}}return{name:"save-progress",version:"1.0.0",dependencies:[],init(d){h()},dispose(){},get(d,y){if(!eo(d))return y;let x;try{x=o.getItem(u(d))}catch(v){return Xn("[save-progress] adapter.getItem \u5F02\u5E38\uFF0C\u8FD4\u56DE\u9ED8\u8BA4\u503C key="+d,v),y}if(x==null)return y;try{return JSON.parse(x)}catch{return a+=1,l||(Yn("[save-progress] \u68C0\u6D4B\u5230\u635F\u574F\u5B58\u6863\uFF08\u975E\u6CD5 JSON\uFF09\uFF0C\u5DF2\u5BB9\u9519\u56DE\u9000\u9ED8\u8BA4\u503C key="+d),l=!0),y}},set(d,y){if(!eo(d))return Yn("[save-progress] set \u6536\u5230\u975E\u6CD5 key\uFF0C\u62D2\u7EDD\u5199\u5165\uFF1A"+String(d)),!1;let x;try{x=JSON.stringify(y)}catch{return c+=1,Yn("[save-progress] \u503C\u4E0D\u53EF JSON \u5E8F\u5217\u5316\uFF08\u5FAA\u73AF\u5F15\u7528?\uFF09\uFF0C\u62D2\u7EDD\u5199\u5165 key="+d),!1}if(x===void 0)return c+=1,Yn("[save-progress] \u503C\u5E8F\u5217\u5316\u4E3A undefined\uFF08\u5982\u7EAF undefined/\u51FD\u6570\uFF09\uFF0C\u62D2\u7EDD\u5199\u5165 key="+d),!1;let v=Tl(x);if(v>s)return c+=1,Yn("[save-progress] \u503C\u8D85\u5B57\u8282\u4E0A\u9650\u62D2\u7EDD\u5199\u5165 key="+d+"\uFF08"+v+" > "+s+" bytes\uFF09"),!1;try{return o.setItem(u(d),x),!0}catch(T){return c+=1,Xn("[save-progress] adapter.setItem \u5F02\u5E38\uFF0C\u5199\u5165\u5931\u8D25 key="+d,T),!1}},remove(d){if(eo(d))try{o.removeItem(u(d))}catch(y){Xn("[save-progress] adapter.removeItem \u5F02\u5E38\uFF08\u5DF2\u5FFD\u7565\uFF09key="+d,y)}},clear(){let d=h(),y=0;for(let x of d)try{o.removeItem(x),y+=1}catch(v){Xn("[save-progress] clear \u65F6 removeItem \u5F02\u5E38\uFF08\u5DF2\u8DF3\u8FC7\uFF09fullKey="+x,v)}return y},probe(){return{namespace:e,maxValueBytes:s,usingMemoryAdapter:i,size:h().length,corruptRecoveries:a,rejectedWrites:c}}}}function eo(n){return typeof n=="string"&&n.length>0}function Al(n){return!!n&&typeof n.getItem=="function"&&typeof n.setItem=="function"&&typeof n.removeItem=="function"&&typeof n.keys=="function"}function Xn(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function Yn(n){typeof console!="undefined"&&typeof console.warn=="function"&&console.warn(n)}var El={w:390,h:844};function ma(n){let t=((n&&n.seed)!=null?n.seed:0)>>>0,e=ta({cellSize:96}),s=ea(),i=ra({inputBufferMs:260,inputTypes:["pointerdown"]}),o=aa({seed:t,maxParticles:600}),r=ua({vignette:{enabled:!0,strength:.22}}),a=pa({masterVolume:.8}),c;try{c=ga()}catch(p){console.warn("[generic] localStorage \u4E0D\u53EF\u7528\uFF0C\u5B58\u6863\u9000\u5185\u5B58 adapter\uFF1A"+(p&&p.message)),c=no()}let l=ya({namespace:"zaomeng-generic",adapter:c});return{plugins:{collision:e,physics:s,gamefeel:i,juice:o,palettePost:r,audioMusic:a,save:l},registerOrder:[e,s,i,o,r,l,a],viewport:El,buildFactoryOpts:(p,d)=>({runtime:{plugins:d.plugins,bundle:d.bundle,getRealAudioCtx:d.getRealAudioCtx}})}}function $n(n){let t=n||{},e=null,s=0,i=null,o=null,r=390,a=844,c=110,l=12,u=700,h=-280,p=180,d=60,y=a*.24,x=270,v=300,T=560,C=x/p,w="booting",_=!1,A=0,S={x:c,y:422,vy:0},R=[],M="",ot=null,$=0,nt=(r-160)/2,rt=a/2+50,Et=160,ne=50;function kt(D){e=D.ctx,o=D.seed||0,i=e.getInput().on("pointerdown",lt),w="playing",_=!1,A=0,S.y=422,S.vy=0,R=[],M="",ot=null,$=0}function lt(D){if(s=e.time.nowMs(),w==="gameover"){D.x>=nt&&D.x<=nt+Et&&D.y>=rt&&D.y<=rt+ne&&Pt();return}if(_){S.vy=h;let k=e.getEngine();if(k&&k.particles)try{k.particles.spawnEmitter({pos:{x:S.x,y:S.y},count:10,speed:80,particleTime:.3,colorStart:{r:1,g:1,b:.6,a:1},colorEnd:{r:1,g:.5,b:0,a:0}})}catch{}if(k&&k.audio&&k.audio.synth)try{k.audio.synth.synthSfx([1,.05,300,,,.1,,1])}catch{}}else{_=!0,S.vy=h,$=0;let k=e.getEngine();if(k&&k.particles)try{k.particles.spawnEmitter({pos:{x:S.x,y:S.y},count:10,speed:80,particleTime:.3,colorStart:{r:1,g:1,b:.6,a:1},colorEnd:{r:1,g:.5,b:0,a:0}})}catch{}if(k&&k.audio&&k.audio.synth)try{k.audio.synth.synthSfx([1,.05,400,,,.1,,1.2])}catch{}}}function Pt(){w="playing",_=!1,A=0,S.y=422,S.vy=0,R=[],M="",ot=null,$=0}function he(D){w="gameover",M=D,ot="lose";let k=e.getEngine();if(k&&k.particles)try{k.particles.spawnEmitter({pos:{x:S.x,y:S.y},count:40,speed:150,particleTime:.6,colorStart:{r:1,g:.2,b:.2,a:1},colorEnd:{r:.5,g:0,b:0,a:0}})}catch{}if(k&&k.audio&&k.audio.synth)try{k.audio.synth.synthSfx([1,.05,150,.5,.3,.1,,1.3])}catch{}}function sn(D){if(s=e.time.nowMs(),w!=="playing"||!_)return;if(S.vy+=u*D,S.y+=S.vy*D,S.y-l<0||S.y+l>a){he("boundary");return}let k=p*D;for(let gt=R.length-1;gt>=0;gt--){let vt=R[gt];if(vt.x-=k,vt.x+d<0){R.splice(gt,1);continue}if(S.x+l>vt.x&&S.x-lvt.gapBottom)){he("pipe");return}if(!vt.scored&&S.x-l>vt.x+d){vt.scored=!0,A++;let Vt=e.getEngine();if(Vt&&Vt.particles)try{Vt.particles.spawnEmitter({pos:{x:S.x,y:S.y},count:25,speed:120,particleTime:.4,colorStart:{r:.2,g:1,b:.2,a:1},colorEnd:{r:0,g:.5,b:0,a:0}})}catch{}if(Vt&&Vt.audio&&Vt.audio.synth)try{Vt.audio.synth.synthSfx([1,.05,800,,,.15,,.5])}catch{}}}if($+=D,$>=C){$=0;let gt=e.random.range(v,T),vt=y/2,Vt=gt-vt,rn=gt+vt;R.push({x:r,centerY:gt,gapTop:Vt,gapBottom:rn,passed:!1,scored:!1})}}function on(D){D.fillStyle="#1a1a2e",D.fillRect(0,0,r,a),D.fillStyle="#4caf50";for(let k of R)D.fillRect(k.x,0,d,k.gapTop),D.fillRect(k.x,k.gapBottom,d,a-k.gapBottom),D.strokeStyle="#2e7d32",D.lineWidth=2,D.strokeRect(k.x,0,d,k.gapTop),D.strokeRect(k.x,k.gapBottom,d,a-k.gapBottom);D.fillStyle="#ffcc00",D.beginPath(),D.arc(S.x,S.y,l,0,Math.PI*2),D.fill(),D.strokeStyle="#cc8800",D.lineWidth=2,D.stroke(),D.fillStyle="#ffffff",D.font="24px monospace",D.textAlign="center",w==="playing"?(D.fillText("Score: "+A,r/2,40),_||(D.font="20px monospace",D.fillText("Tap to Start",r/2,80))):w==="gameover"&&(D.fillStyle="#ff4444",D.font="36px monospace",D.fillText("GAME OVER",r/2,200),D.fillStyle="#ffffff",D.font="24px monospace",D.fillText("Score: "+A,r/2,260),D.fillStyle="#3366ff",D.fillRect(nt,rt,Et,ne),D.strokeStyle="#ffffff",D.lineWidth=2,D.strokeRect(nt,rt,Et,ne),D.fillStyle="#ffffff",D.font="20px monospace",D.fillText("Restart",r/2,rt+ne/2+7))}function se(){try{i&&i.cancel()}catch{}i=null,R=[]}function Ee(){return{seed:o,state:()=>{let D=null;for(let k of R)if(S.x-l!k.scored).length,progress:null,gameoverReason:M}}}}return{init:kt,update:sn,render:on,destroy:se,_forensicsView:Ee}}var pd=$n,gd=$n;async function yd(n){let t=n||{},e=t.engine||await Promise.resolve().then(()=>(Oc(),Lc)),s=(t.seed!=null?t.seed:305441741)>>>0,i=ma({seed:s});return Zr({canvas:t.canvas,statusEl:t.statusEl||null,engine:e,seed:s,mode:t.mode||"play",engineMode:"real",viewport:i.viewport,factory:$n,plugins:i.plugins,registerOrder:i.registerOrder,buildFactoryOpts:i.buildFactoryOpts,recHook:t.recHook||null,onReady:t.onReady||null})}return Nc(md);})();
diff --git a/game-runtime/games/_wg1-gen/flappy/bundle.iife.js.meta.json b/game-runtime/games/_wg1-gen/flappy/bundle.iife.js.meta.json
index 9ab398c3..f694e9a3 100644
--- a/game-runtime/games/_wg1-gen/flappy/bundle.iife.js.meta.json
+++ b/game-runtime/games/_wg1-gen/flappy/bundle.iife.js.meta.json
@@ -1 +1 @@
-{"inputs":{"src/core/plugin.js":{"bytes":44317,"imports":[],"format":"esm"},"src/plugins/runtime-probe/impl.js":{"bytes":16639,"imports":[],"format":"esm"},"host-dev/engine-caps.js":{"bytes":13897,"imports":[],"format":"esm"},"host-dev/engine-math.js":{"bytes":6155,"imports":[],"format":"esm"},"src/host/boot-game-host.js":{"bytes":27676,"imports":[{"path":"src/core/plugin.js","kind":"import-statement","original":"../core/plugin.js"},{"path":"src/plugins/runtime-probe/impl.js","kind":"import-statement","original":"../plugins/runtime-probe/impl.js"},{"path":"host-dev/engine-caps.js","kind":"import-statement","original":"../../host-dev/engine-caps.js"},{"path":"host-dev/engine-math.js","kind":"import-statement","original":"../../host-dev/engine-math.js"}],"format":"esm"},"src/plugins/collision/impl.js":{"bytes":24812,"imports":[],"format":"esm"},"src/plugins/physics-lite/impl.js":{"bytes":14507,"imports":[],"format":"esm"},"src/plugins/gamefeel/impl.js":{"bytes":21715,"imports":[],"format":"esm"},"src/plugins/particles-juice/impl.js":{"bytes":31830,"imports":[],"format":"esm"},"src/plugins/palette-post/impl.js":{"bytes":20240,"imports":[],"format":"esm"},"src/plugins/audio-music/impl.js":{"bytes":24659,"imports":[],"format":"esm"},"src/plugins/save-progress/impl.js":{"bytes":14608,"imports":[],"format":"esm"},"src/host/generic-host-config.js":{"bytes":7803,"imports":[{"path":"src/plugins/collision/impl.js","kind":"import-statement","original":"../plugins/collision/impl.js"},{"path":"src/plugins/physics-lite/impl.js","kind":"import-statement","original":"../plugins/physics-lite/impl.js"},{"path":"src/plugins/gamefeel/impl.js","kind":"import-statement","original":"../plugins/gamefeel/impl.js"},{"path":"src/plugins/particles-juice/impl.js","kind":"import-statement","original":"../plugins/particles-juice/impl.js"},{"path":"src/plugins/palette-post/impl.js","kind":"import-statement","original":"../plugins/palette-post/impl.js"},{"path":"src/plugins/audio-music/impl.js","kind":"import-statement","original":"../plugins/audio-music/impl.js"},{"path":"src/plugins/save-progress/impl.js","kind":"import-statement","original":"../plugins/save-progress/impl.js"}],"format":"esm"},"games/_wg1-gen/flappy/generated-factory.js":{"bytes":9192,"imports":[],"format":"esm"},"node_modules/littlejsengine/dist/littlejs.esm.js":{"bytes":640153,"imports":[],"format":"esm"},"games/_wg1-gen/flappy/entry-bundle.js":{"bytes":6230,"imports":[{"path":"src/host/boot-game-host.js","kind":"import-statement","original":"../../../src/host/boot-game-host.js"},{"path":"src/host/generic-host-config.js","kind":"import-statement","original":"../../../src/host/generic-host-config.js"},{"path":"games/_wg1-gen/flappy/generated-factory.js","kind":"import-statement","original":"./generated-factory.js"},{"path":"node_modules/littlejsengine/dist/littlejs.esm.js","kind":"dynamic-import","original":"littlejsengine"}],"format":"esm"}},"outputs":{"games/_wg1-gen/flappy/bundle.iife.js":{"imports":[],"exports":[],"entryPoint":"games/_wg1-gen/flappy/entry-bundle.js","inputs":{"node_modules/littlejsengine/dist/littlejs.esm.js":{"bytesInOutput":164173},"games/_wg1-gen/flappy/entry-bundle.js":{"bytesInOutput":507},"src/core/plugin.js":{"bytesInOutput":8989},"src/plugins/runtime-probe/impl.js":{"bytesInOutput":2794},"host-dev/engine-caps.js":{"bytesInOutput":1597},"host-dev/engine-math.js":{"bytesInOutput":498},"src/host/boot-game-host.js":{"bytesInOutput":5363},"src/plugins/collision/impl.js":{"bytesInOutput":1605},"src/plugins/physics-lite/impl.js":{"bytesInOutput":115},"src/plugins/gamefeel/impl.js":{"bytesInOutput":2533},"src/plugins/particles-juice/impl.js":{"bytesInOutput":4166},"src/plugins/palette-post/impl.js":{"bytesInOutput":4218},"src/plugins/audio-music/impl.js":{"bytesInOutput":6001},"src/plugins/save-progress/impl.js":{"bytesInOutput":3933},"src/host/generic-host-config.js":{"bytesInOutput":697},"games/_wg1-gen/flappy/generated-factory.js":{"bytesInOutput":3299}},"bytes":211059}}}
\ No newline at end of file
+{"inputs":{"src/core/plugin.js":{"bytes":44317,"imports":[],"format":"esm"},"src/plugins/runtime-probe/impl.js":{"bytes":16639,"imports":[],"format":"esm"},"host-dev/engine-caps.js":{"bytes":13897,"imports":[],"format":"esm"},"host-dev/engine-math.js":{"bytes":6155,"imports":[],"format":"esm"},"src/host/boot-game-host.js":{"bytes":28239,"imports":[{"path":"src/core/plugin.js","kind":"import-statement","original":"../core/plugin.js"},{"path":"src/plugins/runtime-probe/impl.js","kind":"import-statement","original":"../plugins/runtime-probe/impl.js"},{"path":"host-dev/engine-caps.js","kind":"import-statement","original":"../../host-dev/engine-caps.js"},{"path":"host-dev/engine-math.js","kind":"import-statement","original":"../../host-dev/engine-math.js"}],"format":"esm"},"src/plugins/collision/impl.js":{"bytes":24812,"imports":[],"format":"esm"},"src/plugins/physics-lite/impl.js":{"bytes":14507,"imports":[],"format":"esm"},"src/plugins/gamefeel/impl.js":{"bytes":21715,"imports":[],"format":"esm"},"src/plugins/particles-juice/impl.js":{"bytes":31830,"imports":[],"format":"esm"},"src/plugins/palette-post/impl.js":{"bytes":20240,"imports":[],"format":"esm"},"src/plugins/audio-music/impl.js":{"bytes":24659,"imports":[],"format":"esm"},"src/plugins/save-progress/impl.js":{"bytes":14608,"imports":[],"format":"esm"},"src/host/generic-host-config.js":{"bytes":7803,"imports":[{"path":"src/plugins/collision/impl.js","kind":"import-statement","original":"../plugins/collision/impl.js"},{"path":"src/plugins/physics-lite/impl.js","kind":"import-statement","original":"../plugins/physics-lite/impl.js"},{"path":"src/plugins/gamefeel/impl.js","kind":"import-statement","original":"../plugins/gamefeel/impl.js"},{"path":"src/plugins/particles-juice/impl.js","kind":"import-statement","original":"../plugins/particles-juice/impl.js"},{"path":"src/plugins/palette-post/impl.js","kind":"import-statement","original":"../plugins/palette-post/impl.js"},{"path":"src/plugins/audio-music/impl.js","kind":"import-statement","original":"../plugins/audio-music/impl.js"},{"path":"src/plugins/save-progress/impl.js","kind":"import-statement","original":"../plugins/save-progress/impl.js"}],"format":"esm"},"games/_wg1-gen/flappy/generated-factory.js":{"bytes":7665,"imports":[],"format":"esm"},"node_modules/littlejsengine/dist/littlejs.esm.js":{"bytes":640153,"imports":[],"format":"esm"},"games/_wg1-gen/flappy/entry-bundle.js":{"bytes":6230,"imports":[{"path":"src/host/boot-game-host.js","kind":"import-statement","original":"../../../src/host/boot-game-host.js"},{"path":"src/host/generic-host-config.js","kind":"import-statement","original":"../../../src/host/generic-host-config.js"},{"path":"games/_wg1-gen/flappy/generated-factory.js","kind":"import-statement","original":"./generated-factory.js"},{"path":"node_modules/littlejsengine/dist/littlejs.esm.js","kind":"dynamic-import","original":"littlejsengine"}],"format":"esm"}},"outputs":{"games/_wg1-gen/flappy/bundle.iife.js":{"imports":[],"exports":[],"entryPoint":"games/_wg1-gen/flappy/entry-bundle.js","inputs":{"node_modules/littlejsengine/dist/littlejs.esm.js":{"bytesInOutput":164160},"games/_wg1-gen/flappy/entry-bundle.js":{"bytesInOutput":507},"src/core/plugin.js":{"bytesInOutput":8989},"src/plugins/runtime-probe/impl.js":{"bytesInOutput":2794},"host-dev/engine-caps.js":{"bytesInOutput":1597},"host-dev/engine-math.js":{"bytesInOutput":498},"src/host/boot-game-host.js":{"bytesInOutput":5508},"src/plugins/collision/impl.js":{"bytesInOutput":1605},"src/plugins/physics-lite/impl.js":{"bytesInOutput":115},"src/plugins/gamefeel/impl.js":{"bytesInOutput":2533},"src/plugins/particles-juice/impl.js":{"bytesInOutput":4161},"src/plugins/palette-post/impl.js":{"bytesInOutput":4218},"src/plugins/audio-music/impl.js":{"bytesInOutput":6001},"src/plugins/save-progress/impl.js":{"bytesInOutput":3933},"src/host/generic-host-config.js":{"bytesInOutput":697},"games/_wg1-gen/flappy/generated-factory.js":{"bytesInOutput":3555}},"bytes":211442}}}
\ No newline at end of file
diff --git a/game-runtime/games/_wg1-gen/flappy/evidence/after-play.png b/game-runtime/games/_wg1-gen/flappy/evidence/after-play.png
index 44557d94..5225ef5a 100644
Binary files a/game-runtime/games/_wg1-gen/flappy/evidence/after-play.png and b/game-runtime/games/_wg1-gen/flappy/evidence/after-play.png differ
diff --git a/game-runtime/games/_wg1-gen/flappy/evidence/first-paint.png b/game-runtime/games/_wg1-gen/flappy/evidence/first-paint.png
index 8c4a6179..00df0bfd 100644
Binary files a/game-runtime/games/_wg1-gen/flappy/evidence/first-paint.png and b/game-runtime/games/_wg1-gen/flappy/evidence/first-paint.png differ
diff --git a/game-runtime/games/_wg1-gen/flappy/evidence/verdict.json b/game-runtime/games/_wg1-gen/flappy/evidence/verdict.json
index 230dd837..58cdc274 100644
--- a/game-runtime/games/_wg1-gen/flappy/evidence/verdict.json
+++ b/game-runtime/games/_wg1-gen/flappy/evidence/verdict.json
@@ -8,8 +8,8 @@
     },
     "C_frame": {
       "pass": true,
-      "f0": 48,
-      "f1": 78,
+      "f0": 51,
+      "f1": 81,
       "delta": 30
     },
     "I_control": {
@@ -18,13 +18,13 @@
     },
     "D_render": {
       "pass": true,
-      "bright": 178920,
+      "bright": 189671,
       "maxCh": 255
     },
     "E_live": {
       "pass": true,
-      "distinctStates": 6,
-      "samples": 6
+      "distinctStates": 40,
+      "samples": 41
     },
     "B_uncaught": {
       "pass": true,
@@ -32,7 +32,7 @@
     },
     "F_wiring": {
       "pass": true,
-      "callCount": 8,
+      "callCount": 44,
       "sample": [
         "particles.spawnEmitter",
         "audio.synth.synthSfx",
@@ -41,6 +41,10 @@
         "particles.spawnEmitter",
         "audio.synth.synthSfx",
         "particles.spawnEmitter",
+        "audio.synth.synthSfx",
+        "particles.spawnEmitter",
+        "audio.synth.synthSfx",
+        "particles.spawnEmitter",
         "audio.synth.synthSfx"
       ],
       "expected": [
@@ -50,20 +54,20 @@
     },
     "G_input": {
       "pass": true,
-      "inputHash": "0e133ce8",
-      "controlHash": "4fb72d48",
-      "atFrame": 214,
-      "ctrlFrame": 218
+      "inputHash": "4ae5c2e6",
+      "controlHash": "aad4cfb2",
+      "atFrame": 749,
+      "ctrlFrame": 750
     },
     "H_progress": {
-      "pass": false,
+      "pass": true,
       "checks": [
         {
           "path": "score",
           "op": "increased",
           "before": 0,
-          "after": 0,
-          "pass": false,
+          "after": 5,
+          "pass": true,
           "why": "适配性真玩(读 bird.y/nextGap.centerY 拍翅穿缝)→得分上升;物理太硬秒死或穿不过则 0"
         }
       ],
@@ -79,32 +83,33 @@
         "score": 0,
         "bird": {
           "x": 110,
-          "y": 559.1999999999999,
-          "vy": 336
-        },
-        "nextGap": {
-          "x": 600,
-          "centerY": 174.12938179075718
+          "y": 422,
+          "vy": 0
         },
+        "nextGap": null,
+        "remaining": 0,
+        "progress": null,
         "gameoverReason": ""
       },
       "state1": {
         "phase": "gameover",
         "result": "lose",
-        "score": 0,
+        "score": 5,
         "bird": {
           "x": 110,
-          "y": 523.0999999999999,
-          "vy": -169
+          "y": 405.6666666666665,
+          "vy": -116.66666666666673
         },
         "nextGap": {
-          "x": 600,
-          "centerY": 174.12938179075718
+          "x": 120,
+          "centerY": 302.81019813381135
         },
-        "gameoverReason": "pipe_collision"
+        "remaining": 1,
+        "progress": null,
+        "gameoverReason": "pipe"
       }
     }
   },
-  "pass": false,
+  "pass": true,
   "notes": []
 }
\ No newline at end of file
diff --git a/game-runtime/games/_wg1-gen/flappy/generated-factory.js b/game-runtime/games/_wg1-gen/flappy/generated-factory.js
index d0cb6401..135c013f 100644
--- a/game-runtime/games/_wg1-gen/flappy/generated-factory.js
+++ b/game-runtime/games/_wg1-gen/flappy/generated-factory.js
@@ -3,308 +3,271 @@ export default function createFlappyBirdGame(opts) {
   const o = opts || {};
   let ctx = null;
   let nowMs = 0;
-  let subPointer = null;
+  let sub = null;
+  let seed = null;
+
+  // 游戏常量
+  const W = 390, H = 844;
+  const BIRD_X = 110;
+  const BIRD_RADIUS = 12;
+  const GRAVITY = 700;        // px/s²
+  const FLAP_VEL = -280;      // px/s 向上
+  const PIPE_SPEED = 180;     // px/s
+  const PIPE_WIDTH = 60;
+  const GAP_HEIGHT = H * 0.24; // 约 202.56 px
+  const PIPE_SPACING = 270;   // 管道左边缘间距(1.5s 反应时间)
+  const GAP_CENTER_MIN = 300;
+  const GAP_CENTER_MAX = 560;
+  const SPACING_TIME = PIPE_SPACING / PIPE_SPEED; // 1.5s
 
   // 游戏状态
-  let bird = { x: 110, y: 422, vy: 0, r: 12 };          // r 用于碰撞和渲染
-  const GRAVITY = 420;         // 像素/秒²
-  const FLAP_VEL = -260;       // 拍翅瞬速(负=上)
-  const PIPE_SPEED = 150;      // 像素/秒
-  const PIPE_WIDTH = 60;
-  const GAP_HEIGHT = 220;      // ≥ 0.24 * 844 = 202.56
-  const PIPE_SPACING = 280;    // 管道中心水平间隔,保证反应时间
-  const MIN_PIPE_CENTER_Y = GAP_HEIGHT / 2;
-  const MAX_PIPE_CENTER_Y = 844 - GAP_HEIGHT / 2;
-  const BIRD_HALF = 12;        // 鸟的显示/碰撞半径(实际用矩形 24x24)
-
-  let pipes = [];              // { x, centerY, scored }
+  let phase = 'booting';
+  let started = false;
   let score = 0;
-  let phase = 'booting';       // 'booting' | 'playing' | 'gameover'
+  let bird = { x: BIRD_X, y: 422, vy: 0 };
+  let pipes = [];
   let gameoverReason = '';
-  let result = null;
+  let result = null;          // 'lose' | null
+  let pipeTimer = 0;
 
-  // 粒子/音效触发标记(帧内)
-  let pendingFlapEffect = false;
-  let pendingScoreEffect = false;
-  let pendingCrashEffect = false;
-  let crashPos = { x: 0, y: 0 };
-
-  function resetGame() {
-    bird.y = 422;
-    bird.vy = 0;
-    pipes = [];
-    score = 0;
-    phase = 'playing';
-    gameoverReason = '';
-    result = null;
-    pendingFlapEffect = false;
-    pendingScoreEffect = false;
-    pendingCrashEffect = false;
-    // 第一对管道初始位置:保证 ≥1.5 秒后与鸟相遇
-    const initialPipeX = 390 + PIPE_WIDTH / 2 + 180; // 速度150,到达鸟时间≈(570-110)/150≈3.07s > 1.5s
-    pipes.push({
-      x: initialPipeX,
-      centerY: randomPipeCenterY(),
-      scored: false
-    });
-  }
-
-  function randomPipeCenterY() {
-    // ctx.random.range 防御
-    if (ctx && ctx.random && ctx.random.range) {
-      return ctx.random.range(MIN_PIPE_CENTER_Y, MAX_PIPE_CENTER_Y);
-    }
-    // 极低概率缺省时用固定值
-    return 422;
-  }
-
-  /** 触发引擎粒子 + 音效 */
-  function spawnEffects(pos, type) {
-    const eng = ctx.getEngine();
-    if (!eng) return;
-    if (eng.particles) {
-      try {
-        const emitter = eng.particles.spawnEmitter({
-          pos: { x: pos.x, y: pos.y },
-          count: type === 'crash' ? 35 : 22,
-          emitRate: 0,
-          particleTime: 0.6,
-          speed: type === 'crash' ? 160 : 110,
-          coneAngle: type === 'crash' ? Math.PI : 0.5,
-          sizeStart: type === 'crash' ? 16 : 12,
-          sizeEnd: 2,
-          colorStart: type === 'crash' ? { r: 1, g: 0.1, b: 0.1, a: 1 }
-            : type === 'score' ? { r: 0.2, g: 1, b: 0.3, a: 1 }
-            : { r: 0.3, g: 0.7, b: 1, a: 1 },
-          colorEnd: type === 'crash' ? { r: 1, g: 0.3, b: 0, a: 0 }
-            : { r: 0.1, g: 0.5, b: 1, a: 0 }
-        });
-      } catch (_) { }
-    }
-    if (eng.audio && eng.audio.synth) {
-      try {
-        if (type === 'flap') {
-          eng.audio.synth.synthSfx([1, 0.05, 340, , , 0.12, , 1.2, , , , , , , , 0.1]);
-        } else if (type === 'score') {
-          eng.audio.synth.synthSfx([1, 0.05, 880, , , 0.22, , 1.9, , , , , , , , 0.4]);
-        } else if (type === 'crash') {
-          eng.audio.synth.synthSfx([2, 0.5, 90, , , 0.5, , 0.3, , , , , , , , 0.1]);
-        }
-      } catch (_) { }
-    }
-  }
-
-  /** 点击处理:拍翅(playing)或重玩(gameover) */
-  function onPointer(e) {
-    if (phase === 'playing') {
-      // 拍翅
-      bird.vy = FLAP_VEL;
-      pendingFlapEffect = true;
-    } else if (phase === 'gameover') {
-      // 检测重玩按钮区域(居中偏下)
-      const bx = 115, by = 620, bw = 160, bh = 60;
-      const px = e.x || 0, py = e.y || 0;
-      if (px >= bx && px <= bx + bw && py >= by && py <= by + bh) {
-        resetGame();
-      }
-    }
-  }
+  // 重玩按钮区域
+  const RESTART_X = (W - 160) / 2;
+  const RESTART_Y = H/2 + 50;
+  const RESTART_W = 160;
+  const RESTART_H = 50;
 
   function init(boot) {
     ctx = boot.ctx;
-    // 订阅输入
-    subPointer = ctx.getInput().on('pointerdown', onPointer);
-    // 初始随机种子
-    resetGame();
+    seed = boot.seed || 0;
+    sub = ctx.getInput().on('pointerdown', onPointerDown);
+
     phase = 'playing';
+    started = false;
+    score = 0;
+    bird.y = 422;
+    bird.vy = 0;
+    pipes = [];
+    gameoverReason = '';
+    result = null;
+    pipeTimer = 0;
   }
 
-  function update(dt) {
-    nowMs = ctx.time.nowMs();        // 控制钟
-    if (phase !== 'playing') return; // 终态驻留,不更新物理
-
-    // 物理更新(dt 固定 1/60)
-    const grav = GRAVITY;
-    bird.vy += grav * dt;
-    bird.y += bird.vy * dt;
-
-    // 触顶触底判定
-    if (bird.y - BIRD_HALF <= 0 || bird.y + BIRD_HALF >= 844) {
-      gameOver('boundary');
+  function onPointerDown(e) {
+    nowMs = ctx.time.nowMs();
+    if (phase === 'gameover') {
+      // 只接受重玩按钮
+      if (e.x >= RESTART_X && e.x <= RESTART_X + RESTART_W &&
+          e.y >= RESTART_Y && e.y <= RESTART_Y + RESTART_H) {
+        restart();
+      }
       return;
     }
-
-    // 更新管道位置
-    for (const pipe of pipes) {
-      pipe.x -= PIPE_SPEED * dt;
-    }
-
-    // 移除屏幕外的管道
-    pipes = pipes.filter(p => p.x > -PIPE_WIDTH / 2 - 10);
-
-    // 生成新管道:当最右的管道 x 小于阈值时,生成新管道
-    const lastPipe = pipes.length > 0 ? pipes[pipes.length - 1] : null;
-    if (!lastPipe || lastPipe.x <= 390 + PIPE_WIDTH / 2 - PIPE_SPACING) {
-      const newX = lastPipe ? lastPipe.x + PIPE_SPACING : 390 + PIPE_WIDTH / 2 + 180;
-      pipes.push({
-        x: newX,
-        centerY: randomPipeCenterY(),
-        scored: false
-      });
-    }
-
-    // 碰撞检测 & 得分
-    const birdRect = {
-      x: bird.x - BIRD_HALF,
-      y: bird.y - BIRD_HALF,
-      w: BIRD_HALF * 2,
-      h: BIRD_HALF * 2
-    };
-    for (const pipe of pipes) {
-      const topH = pipe.centerY - GAP_HEIGHT / 2;
-      const bottomY = pipe.centerY + GAP_HEIGHT / 2;
-      const pipeRect = {
-        x: pipe.x - PIPE_WIDTH / 2,
-        y: 0,
-        w: PIPE_WIDTH,
-        h: topH
-      };
-      const pipeRect2 = {
-        x: pipe.x - PIPE_WIDTH / 2,
-        y: bottomY,
-        w: PIPE_WIDTH,
-        h: 844 - bottomY
-      };
-      // 碰撞(矩形相交)
-      const collides = (a, b) => {
-        return a.x < b.x + b.w && a.x + a.w > b.x &&
-               a.y < b.y + b.h && a.y + a.h > b.y;
-      };
-      if (collides(birdRect, pipeRect) || collides(birdRect, pipeRect2)) {
-        gameOver('pipe_collision');
-        return;
+    // playing 阶段
+    if (!started) {
+      started = true;
+      bird.vy = FLAP_VEL;
+      pipeTimer = 0;
+      // 粒子 + 音效
+      const eng = ctx.getEngine();
+      if (eng && eng.particles) {
+        try { eng.particles.spawnEmitter({ pos: {x: bird.x, y: bird.y}, count: 10, speed: 80, particleTime: 0.3,
+          colorStart: {r:1,g:1,b:0.6,a:1}, colorEnd: {r:1,g:0.5,b:0,a:0} }); } catch(_) {}
       }
-      // 得分:管道完全通过鸟左边缘
-      if (!pipe.scored && pipe.x + PIPE_WIDTH / 2 < bird.x - BIRD_HALF) {
-        pipe.scored = true;
-        score++;
-        pendingScoreEffect = true;
+      if (eng && eng.audio && eng.audio.synth) {
+        try { eng.audio.synth.synthSfx([1,0.05,400,,,0.1,,1.2]); } catch(_) {}
+      }
+    } else {
+      bird.vy = FLAP_VEL;
+      const eng = ctx.getEngine();
+      if (eng && eng.particles) {
+        try { eng.particles.spawnEmitter({ pos: {x: bird.x, y: bird.y}, count: 10, speed: 80, particleTime: 0.3,
+          colorStart: {r:1,g:1,b:0.6,a:1}, colorEnd: {r:1,g:0.5,b:0,a:0} }); } catch(_) {}
+      }
+      if (eng && eng.audio && eng.audio.synth) {
+        try { eng.audio.synth.synthSfx([1,0.05,300,,,0.1,,1.0]); } catch(_) {}
       }
-    }
-
-    // 处理本帧累积的特效
-    if (pendingFlapEffect) {
-      spawnEffects({ x: bird.x, y: bird.y }, 'flap');
-      pendingFlapEffect = false;
-    }
-    if (pendingScoreEffect) {
-      spawnEffects({ x: bird.x, y: bird.y }, 'score');
-      pendingScoreEffect = false;
-    }
-    if (pendingCrashEffect) {
-      spawnEffects(crashPos, 'crash');
-      pendingCrashEffect = false;
     }
   }
 
-  function gameOver(reason) {
+  function restart() {
+    phase = 'playing';
+    started = false;
+    score = 0;
+    bird.y = 422;
+    bird.vy = 0;
+    pipes = [];
+    gameoverReason = '';
+    result = null;
+    pipeTimer = 0;
+  }
+
+  function enterGameover(reason) {
     phase = 'gameover';
     gameoverReason = reason;
     result = 'lose';
-    crashPos = { x: bird.x, y: bird.y };
-    pendingCrashEffect = true;
+    const eng = ctx.getEngine();
+    if (eng && eng.particles) {
+      try { eng.particles.spawnEmitter({ pos: {x: bird.x, y: bird.y}, count: 40, speed: 150, particleTime: 0.6,
+        colorStart: {r:1,g:0.2,b:0.2,a:1}, colorEnd: {r:0.5,g:0,b:0,a:0} }); } catch(_) {}
+    }
+    if (eng && eng.audio && eng.audio.synth) {
+      try { eng.audio.synth.synthSfx([1,0.05,150,0.5,0.3,0.1,,1.3]); } catch(_) {}
+    }
+  }
+
+  function update(dt) {
+    nowMs = ctx.time.nowMs();
+    if (phase !== 'playing') return;
+    if (!started) return;
+
+    // 物理更新鸟
+    bird.vy += GRAVITY * dt;
+    bird.y += bird.vy * dt;
+
+    // 触顶/触底
+    if (bird.y - BIRD_RADIUS < 0 || bird.y + BIRD_RADIUS > H) {
+      enterGameover('boundary');
+      return;
+    }
+
+    // 移动管道
+    const move = PIPE_SPEED * dt;
+    for (let i = pipes.length - 1; i >= 0; i--) {
+      const p = pipes[i];
+      p.x -= move;
+      if (p.x + PIPE_WIDTH < 0) {
+        pipes.splice(i, 1);
+        continue;
+      }
+      // 碰撞检测
+      if (bird.x + BIRD_RADIUS > p.x && bird.x - BIRD_RADIUS < p.x + PIPE_WIDTH) {
+        if (bird.y - BIRD_RADIUS < p.gapTop || bird.y + BIRD_RADIUS > p.gapBottom) {
+          enterGameover('pipe');
+          return;
+        }
+      }
+      // 得分检测
+      if (!p.scored && bird.x - BIRD_RADIUS > p.x + PIPE_WIDTH) {
+        p.scored = true;
+        score++;
+        const eng = ctx.getEngine();
+        if (eng && eng.particles) {
+          try { eng.particles.spawnEmitter({ pos: {x: bird.x, y: bird.y}, count: 25, speed: 120, particleTime: 0.4,
+            colorStart: {r:0.2,g:1,b:0.2,a:1}, colorEnd: {r:0,g:0.5,b:0,a:0} }); } catch(_) {}
+        }
+        if (eng && eng.audio && eng.audio.synth) {
+          try { eng.audio.synth.synthSfx([1,0.05,800,,,0.15,,0.5]); } catch(_) {}
+        }
+      }
+    }
+
+    // 生成新管道
+    pipeTimer += dt;
+    if (pipeTimer >= SPACING_TIME) {
+      pipeTimer = 0;
+      const centerY = ctx.random.range(GAP_CENTER_MIN, GAP_CENTER_MAX);
+      const halfGap = GAP_HEIGHT / 2;
+      const gapTop = centerY - halfGap;
+      const gapBottom = centerY + halfGap;
+      pipes.push({
+        x: W,
+        centerY,
+        gapTop,
+        gapBottom,
+        passed: false,
+        scored: false
+      });
+    }
   }
 
   function render(g) {
     // 背景
-    g.fillStyle = '#0a1122';
-    g.fillRect(0, 0, 390, 844);
+    g.fillStyle = '#1a1a2e';
+    g.fillRect(0, 0, W, H);
 
-    if (phase === 'gameover' || phase === 'playing') {
-      // 绘制管道
-      g.fillStyle = '#3a5';
-      for (const pipe of pipes) {
-        const topH = pipe.centerY - GAP_HEIGHT / 2;
-        const bottomY = pipe.centerY + GAP_HEIGHT / 2;
-        // 顶管道
-        g.fillRect(pipe.x - PIPE_WIDTH / 2, 0, PIPE_WIDTH, topH);
-        // 底管道
-        g.fillRect(pipe.x - PIPE_WIDTH / 2, bottomY, PIPE_WIDTH, 844 - bottomY);
-        // 管道帽
-        g.fillStyle = '#2c4';
-        g.fillRect(pipe.x - PIPE_WIDTH / 2 - 4, topH - 10, PIPE_WIDTH + 8, 10);
-        g.fillRect(pipe.x - PIPE_WIDTH / 2 - 4, bottomY, PIPE_WIDTH + 8, 10);
-        g.fillStyle = '#3a5';
-      }
-
-      // 绘制小鸟(亮黄色方块+眼睛)
-      g.fillStyle = '#ffcc00';
-      g.fillRect(bird.x - BIRD_HALF, bird.y - BIRD_HALF, BIRD_HALF * 2, BIRD_HALF * 2);
-      g.fillStyle = '#000';
-      g.fillRect(bird.x + 4, bird.y - 6, 5, 5);
+    // 管道
+    g.fillStyle = '#4caf50';
+    for (const p of pipes) {
+      // 上管道
+      g.fillRect(p.x, 0, PIPE_WIDTH, p.gapTop);
+      // 下管道
+      g.fillRect(p.x, p.gapBottom, PIPE_WIDTH, H - p.gapBottom);
+      // 管道边框(装饰)
+      g.strokeStyle = '#2e7d32';
+      g.lineWidth = 2;
+      g.strokeRect(p.x, 0, PIPE_WIDTH, p.gapTop);
+      g.strokeRect(p.x, p.gapBottom, PIPE_WIDTH, H - p.gapBottom);
     }
 
+    // 鸟
+    g.fillStyle = '#ffcc00';
+    g.beginPath();
+    g.arc(bird.x, bird.y, BIRD_RADIUS, 0, Math.PI * 2);
+    g.fill();
+    g.strokeStyle = '#cc8800';
+    g.lineWidth = 2;
+    g.stroke();
+
     // HUD
     g.fillStyle = '#ffffff';
-    g.font = '20px monospace';
-    g.fillText('得分: ' + score, 20, 40);
-
-    if (phase === 'gameover') {
+    g.font = '24px monospace';
+    g.textAlign = 'center';
+    if (phase === 'playing') {
+      g.fillText('Score: ' + score, W/2, 40);
+      if (!started) {
+        g.font = '20px monospace';
+        g.fillText('Tap to Start', W/2, 80);
+      }
+    } else if (phase === 'gameover') {
+      g.fillStyle = '#ff4444';
+      g.font = '36px monospace';
+      g.fillText('GAME OVER', W/2, 200);
       g.fillStyle = '#ffffff';
-      g.font = '26px monospace';
-      g.fillText('失败!', 130, 300);
+      g.font = '24px monospace';
+      g.fillText('Score: ' + score, W/2, 260);
       // 重玩按钮
-      const bx = 115, by = 620, bw = 160, bh = 60;
-      g.fillStyle = '#2255aa';
-      g.fillRect(bx, by, bw, bh);
+      g.fillStyle = '#3366ff';
+      g.fillRect(RESTART_X, RESTART_Y, RESTART_W, RESTART_H);
+      g.strokeStyle = '#ffffff';
+      g.lineWidth = 2;
+      g.strokeRect(RESTART_X, RESTART_Y, RESTART_W, RESTART_H);
       g.fillStyle = '#ffffff';
-      g.font = '22px monospace';
-      g.fillText('点击重玩', bx + 10, by + 38);
+      g.font = '20px monospace';
+      g.fillText('Restart', W/2, RESTART_Y + RESTART_H/2 + 7);
     }
   }
 
   function destroy() {
-    try { subPointer && subPointer.cancel(); } catch (_) {}
-    subPointer = null;
+    try { sub && sub.cancel(); } catch(_) {}
+    sub = null;
     pipes = [];
-    bird = { x: 110, y: 422, vy: 0, r: 12 };
   }
 
-  /** 可测性视图 */
   function _forensicsView() {
-    const nextGap = (() => {
-      // 找到小鸟前方最近的管道
-      if (phase !== 'playing') return null;
-      let candidate = null;
-      for (const pipe of pipes) {
-        if (pipe.x > bird.x - BIRD_HALF) {
-          if (!candidate || pipe.x < candidate.x) {
-            candidate = pipe;
+    return {
+      seed,
+      state: () => {
+        // 动态计算 nextGap
+        let nextGap = null;
+        for (const p of pipes) {
+          if (bird.x - BIRD_RADIUS < p.x + PIPE_WIDTH && !p.scored) {
+            nextGap = { x: p.x, centerY: p.centerY };
+            break;
           }
         }
+        return {
+          phase,
+          result,
+          score,
+          bird: { x: bird.x, y: bird.y, vy: bird.vy },
+          nextGap,
+          remaining: pipes.filter(p => !p.scored).length,
+          progress: null,
+          gameoverReason
+        };
       }
-      if (!candidate) return null;
-      return { x: candidate.x, centerY: candidate.centerY };
-    })();
-
-    return {
-      seed: opts && opts.seed !== undefined ? opts.seed : undefined,
-      state: () => ({
-        phase,
-        result,
-        score,
-        bird: { x: bird.x, y: bird.y, vy: bird.vy },
-        nextGap,
-        gameoverReason
-      })
     };
   }
 
-  return {
-    init,
-    update,
-    render,
-    destroy,
-    _forensicsView
-  };
+  return { init, update, render, destroy, _forensicsView };
 }
\ No newline at end of file
diff --git a/game-runtime/games/_wg1-gen/flappy/play-spec.json b/game-runtime/games/_wg1-gen/flappy/play-spec.json
index 93f5b5b1..1cdcd9e2 100644
--- a/game-runtime/games/_wg1-gen/flappy/play-spec.json
+++ b/game-runtime/games/_wg1-gen/flappy/play-spec.json
@@ -1,9 +1,12 @@
 {
   "driver": {
     "type": "flap-to-gap",
-    "steps": 70,
-    "stepMs": 110,
-    "margin": 14
+    "steps": 100,
+    "stepMs": 90,
+    "margin": 14,
+    "lookahead": 0.18,
+    "aimBias": 24,
+    "vyPath": "bird.vy"
   },
   "expectedEngineCallPrefixes": [
     "particles.",
diff --git a/game-runtime/games/_wg1-gen/multiball/bundle.iife.js b/game-runtime/games/_wg1-gen/multiball/bundle.iife.js
index 3689a576..8c92941a 100644
--- a/game-runtime/games/_wg1-gen/multiball/bundle.iife.js
+++ b/game-runtime/games/_wg1-gen/multiball/bundle.iife.js
@@ -1,34 +1,34 @@
-"use strict";var __GameBundle=(()=>{var Vi=Object.defineProperty;var Bc=Object.getOwnPropertyDescriptor;var Nc=Object.getOwnPropertyNames;var zc=Object.prototype.hasOwnProperty;var Jc=(n,t,e)=>()=>{if(e)throw e[0];try{return n&&(t=n(n=0)),t}catch(s){throw e=[s],s}};var Kr=(n,t)=>{for(var e in t)Vi(n,e,{get:t[e],enumerable:!0})},Uc=(n,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Nc(t))!zc.call(n,i)&&i!==e&&Vi(n,i,{get:()=>t[i],enumerable:!(s=Bc(t,i))||s.enumerable});return n};var Vc=n=>Uc(Vi({},"__esModule",{value:!0}),n);var Fc={};Kr(Fc,{ASSERT:()=>f,BLACK:()=>nt,BLUE:()=>sc,Box2dDistanceJoint:()=>Ci,Box2dFrictionJoint:()=>Zo,Box2dGearJoint:()=>Yo,Box2dJoint:()=>Yt,Box2dKinematicObject:()=>Uo,Box2dMotorJoint:()=>er,Box2dObject:()=>Ps,Box2dPinJoint:()=>qo,Box2dPlugin:()=>_i,Box2dPrismaticJoint:()=>$o,Box2dPulleyJoint:()=>tr,Box2dRaycastResult:()=>Ai,Box2dRevoluteJoint:()=>Xo,Box2dRopeJoint:()=>Ho,Box2dStaticObject:()=>Ti,Box2dTargetJoint:()=>Wo,Box2dTileLayer:()=>Vo,Box2dWeldJoint:()=>Qo,Box2dWheelJoint:()=>Ko,CLEAR_BLACK:()=>pe,CLEAR_WHITE:()=>ln,CYAN:()=>$l,CanvasLayer:()=>di,Color:()=>At,Ease:()=>Ri,EngineObject:()=>ze,GRAY:()=>Xl,GREEN:()=>nc,ImageFont:()=>ri,LOG:()=>vt,Light:()=>Io,LightSystemPlugin:()=>Mo,MAGENTA:()=>Kl,Medal:()=>Si,NewgroundsMedal:()=>Lo,NewgroundsPlugin:()=>Oo,ORANGE:()=>Yl,PI:()=>X,PURPLE:()=>ic,Particle:()=>fi,ParticleEmitter:()=>To,PathFinder:()=>nr,PathFinderNode:()=>Pi,PostProcessPlugin:()=>Do,RED:()=>lr,RandomGenerator:()=>bo,Sound:()=>vs,SoundInstance:()=>ui,TextureInfo:()=>Je,TileCollisionLayer:()=>ws,TileInfo:()=>Ee,TileLayer:()=>Ss,TileLayerData:()=>An,Timer:()=>Ae,Tween:()=>Ei,UIButton:()=>Rs,UICheckbox:()=>Bo,UILayout:()=>Jo,UIObject:()=>re,UISlider:()=>No,UISystemPlugin:()=>Go,UIText:()=>wi,UITextInput:()=>Fo,UITile:()=>jo,UIVideo:()=>zo,Vector2:()=>rt,WHITE:()=>W,YELLOW:()=>ec,ZzFXMusic:()=>ko,abs:()=>tt,atan2:()=>rr,audioContext:()=>ft,audioDefaultSampleRate:()=>Zn,audioIsRunning:()=>xs,audioMasterGain:()=>Ne,box2d:()=>m,box2dDebug:()=>Yr,box2dInit:()=>hd,box2dSetDebug:()=>ud,cameraAngle:()=>K,cameraFit:()=>uh,cameraPos:()=>Et,cameraScale:()=>H,canvasClearColor:()=>sn,canvasColorTiles:()=>Oi,canvasFixedSize:()=>Fn,canvasMaxAspect:()=>Gn,canvasMaxSize:()=>kn,canvasMinAspect:()=>as,canvasPixelRatio:()=>on,canvasPixelated:()=>dr,ceil:()=>ds,clamp:()=>B,combineCanvases:()=>Cr,cos:()=>at,debug:()=>Gt,debugCircle:()=>Vt,debugClear:()=>jl,debugLine:()=>Se,debugOverlap:()=>go,debugOverlay:()=>De,debugPoint:()=>or,debugPointSize:()=>Ba,debugPoly:()=>Fl,debugRect:()=>bt,debugScreenshot:()=>za,debugShowErrors:()=>Bl,debugText:()=>In,debugVideoCaptureIsActive:()=>we,debugVideoCaptureStart:()=>Ja,debugVideoCaptureStop:()=>Ua,debugWatermark:()=>Li,distanceAngle:()=>Wl,distanceWrap:()=>ar,drawCanvas2D:()=>Ln,drawCircle:()=>oi,drawCircleGradient:()=>ah,drawContext:()=>Ct,drawCount:()=>Ce,drawCrescent:()=>pd,drawEllipse:()=>cc,drawEllipseGradient:()=>lc,drawLine:()=>xn,drawLineList:()=>vo,drawNineSlice:()=>Oc,drawNineSliceScreen:()=>dd,drawPoly:()=>Vn,drawRect:()=>ii,drawRectGradient:()=>ih,drawRegularPoly:()=>ac,drawText:()=>ch,drawTextScreen:()=>rn,drawTextureWrapped:()=>oh,drawThreeSlice:()=>Dc,drawThreeSliceScreen:()=>fd,drawTile:()=>Ot,enablePhysicsSolver:()=>ki,engineAddPlugin:()=>Rn,engineImageFont:()=>fc,engineInit:()=>Ml,engineName:()=>Ys,engineObjects:()=>St,engineObjectsCallback:()=>kl,engineObjectsCollect:()=>ja,engineObjectsCollide:()=>ir,engineObjectsDestroy:()=>Il,engineObjectsRaycast:()=>Gl,engineObjectsUpdate:()=>Fa,engineVersion:()=>$s,fetchJSON:()=>Ql,floor:()=>Tt,fontDefault:()=>Ls,formatTime:()=>ur,frame:()=>ka,frameRate:()=>Ll,gamepadConnected:()=>wo,gamepadDirectionEmulateStick:()=>xr,gamepadDpad:()=>So,gamepadIsDown:()=>Oe,gamepadPrimary:()=>mt,gamepadStick:()=>ms,gamepadStickCount:()=>pc,gamepadVibrate:()=>Ch,gamepadVibrateStop:()=>_h,gamepadWasPressed:()=>Or,gamepadWasReleased:()=>Ah,gamepadsEnable:()=>Gi,getCameraSize:()=>hc,getCrescentPoints:()=>Mc,getNoteFrequency:()=>xc,getPaused:()=>Ol,glAntialias:()=>Fr,glCanvas:()=>Z,glCircleSides:()=>Os,glClearCanvas:()=>Ac,glClearRect:()=>Pc,glCompileShader:()=>Po,glContext:()=>y,glCopyToContext:()=>Jr,glCreateProgram:()=>Yn,glCreateTexture:()=>Ni,glDeleteTexture:()=>_c,glDraw:()=>Cs,glDrawColoredPoints:()=>Wr,glDrawOutlineTransform:()=>Vr,glDrawPoints:()=>Rc,glDrawPointsTransform:()=>Ur,glDrawUntextured:()=>Ec,glEnable:()=>G,glFlush:()=>Rt,glSetAntialias:()=>Zh,glSetRenderTarget:()=>rs,glSetTexture:()=>Nr,glSetTextureData:()=>zr,glSetTextureWrap:()=>Cc,gravity:()=>Wt,headlessMode:()=>N,hsl:()=>Ie,hypot:()=>Va,inputClear:()=>Fs,inputClearKey:()=>Pr,inputMouseMoveThreshold:()=>Rr,inputPreventDefault:()=>jn,inputWASDEmulateDirection:()=>cs,isArray:()=>de,isColor:()=>J,isFullscreen:()=>dc,isIntersecting:()=>Xa,isNumber:()=>R,isOnScreen:()=>hh,isOverlapping:()=>ti,isPowerOfTwo:()=>fs,isStringLike:()=>V,isTouchDevice:()=>ie,isUsingGamepad:()=>Nn,isVector2:()=>L,keyDirection:()=>wh,keyIsDown:()=>Lt,keyWasPressed:()=>It,keyWasReleased:()=>Lr,lastInputDevice:()=>en,lerp:()=>qt,lerpAngle:()=>ql,lerpWrap:()=>Ha,lightSystem:()=>q,lineTest:()=>$a,log2:()=>Wa,mainCanvas:()=>j,mainCanvasSize:()=>I,mainContext:()=>ut,max:()=>$,medalDisplaySize:()=>xi,medalDisplaySlideTime:()=>Bn,medalDisplayTime:()=>bi,medals:()=>_s,medalsForEach:()=>zi,medalsInit:()=>sd,medalsPreventUnlock:()=>qr,medalsReset:()=>id,min:()=>Q,mod:()=>se,mouseDelta:()=>_r,mouseDeltaScreen:()=>be,mouseInWindow:()=>ai,mouseIsDown:()=>us,mousePos:()=>Le,mousePosScreen:()=>Ut,mouseWasPressed:()=>gs,mouseWasReleased:()=>Th,mouseWheel:()=>Er,nearestPowerOfTwo:()=>Hl,newgrounds:()=>Es,noise1D:()=>su,noise2D:()=>iu,objectDefaultAngleDamping:()=>gr,objectDefaultDamping:()=>yr,objectDefaultFriction:()=>br,objectDefaultMass:()=>pr,objectDefaultRestitution:()=>mr,objectMaxSpeed:()=>ke,oscillate:()=>Ya,particleEmitRateScale:()=>ei,paused:()=>Te,percent:()=>Ft,percentLerp:()=>Vl,playSamples:()=>Gr,pointerLockExit:()=>Ph,pointerLockIsActive:()=>yc,pointerLockRequest:()=>Rh,postProcess:()=>Mt,primitiveCount:()=>_e,rand:()=>dt,randBool:()=>Ka,randColor:()=>mo,randInCircle:()=>tc,randInt:()=>cr,randSign:()=>Qa,randVec2:()=>Za,readSaveData:()=>eu,rgb:()=>z,round:()=>Qs,saveCanvas:()=>oc,saveDataURL:()=>ps,saveText:()=>Zl,screenToWorld:()=>ks,screenToWorldDelta:()=>uc,screenToWorldTransform:()=>Gs,setAdditiveBlendMode:()=>ys,setCameraAngle:()=>ru,setCameraPos:()=>ou,setCameraScale:()=>au,setCanvasClearColor:()=>uu,setCanvasColorTiles:()=>lu,setCanvasFixedSize:()=>pu,setCanvasMaxAspect:()=>fu,setCanvasMaxSize:()=>hu,setCanvasMinAspect:()=>du,setCanvasPixelRatio:()=>gu,setCanvasPixelated:()=>rc,setCursor:()=>yh,setDebugKey:()=>sh,setDebugWatermark:()=>nh,setEnablePhysicsSolver:()=>Cu,setFontDefault:()=>mu,setGLCircleSides:()=>Su,setGLEnable:()=>vu,setGamepadDirectionEmulateStick:()=>ku,setGamepadsEnable:()=>Iu,setGravity:()=>Du,setHeadlessMode:()=>xu,setInputMouseMoveThreshold:()=>bh,setInputPreventDefault:()=>mh,setInputWASDEmulateDirection:()=>Gu,setMedalDisplaySize:()=>ad,setMedalDisplaySlideTime:()=>rd,setMedalDisplayTime:()=>od,setMedalsPreventUnlock:()=>cd,setObjectDefaultAngleDamping:()=>Ru,setObjectDefaultDamping:()=>Eu,setObjectDefaultFriction:()=>Lu,setObjectDefaultMass:()=>_u,setObjectDefaultRestitution:()=>Pu,setObjectMaxSpeed:()=>Ou,setParticleEmitRateScale:()=>Mu,setPaused:()=>Dl,setShowSplashScreen:()=>bu,setSoundDefaultRange:()=>th,setSoundDefaultTaper:()=>eh,setSoundEnable:()=>Qu,setSoundVolume:()=>Zu,setTileDefaultBleed:()=>Au,setTileDefaultPadding:()=>Tu,setTileDefaultSize:()=>wu,setTilesPixelated:()=>yu,setTimeScale:()=>cu,setTouchGamepadAlpha:()=>Xu,setTouchGamepadAnalog:()=>Wu,setTouchGamepadButtonCount:()=>zu,setTouchGamepadCenterButtonSize:()=>Nu,setTouchGamepadDisplayTime:()=>Yu,setTouchGamepadEnable:()=>ju,setTouchGamepadFloating:()=>qu,setTouchGamepadLeftButtonCount:()=>Uu,setTouchGamepadLeftStick:()=>Ju,setTouchGamepadPassthrough:()=>Bu,setTouchGamepadRightStick:()=>Vu,setTouchGamepadSize:()=>Hu,setTouchGamepadVibration:()=>$u,setTouchInputEnable:()=>Fu,setVibrateEnable:()=>Ku,shareURL:()=>tu,showSplashScreen:()=>fr,sign:()=>ne,sin:()=>et,smoothStep:()=>Zs,soundDefaultRange:()=>wr,soundDefaultTaper:()=>Tr,soundEnable:()=>Xt,soundVolume:()=>Tn,speak:()=>Vh,speakStop:()=>Wh,tan:()=>qa,textureInfos:()=>hn,tile:()=>Is,tileCollisionGetData:()=>hi,tileCollisionLayers:()=>an,tileCollisionRaycast:()=>vc,tileCollisionTest:()=>Ze,tileDefaultBleed:()=>Ii,tileDefaultPadding:()=>Mi,tileDefaultSize:()=>Di,tileLayersLoad:()=>Hh,tilesPixelated:()=>Cn,time:()=>Qt,timeDelta:()=>sr,timeReal:()=>cn,timeScale:()=>hr,toggleFullscreen:()=>ph,touchGamepadAlpha:()=>Sr,touchGamepadAnalog:()=>Ds,touchGamepadButtonCount:()=>$n,touchGamepadCenterButtonSize:()=>fe,touchGamepadDisplayTime:()=>ls,touchGamepadEnable:()=>un,touchGamepadFloating:()=>dn,touchGamepadLeftButtonCount:()=>Kn,touchGamepadLeftStick:()=>Pn,touchGamepadPassthrough:()=>vr,touchGamepadRightStick:()=>Qn,touchGamepadSize:()=>Ht,touchGamepadVibration:()=>ni,touchInputEnable:()=>bn,tweenProperty:()=>yd,tweenStopAll:()=>gd,tweenUpdate:()=>Gc,uiDebug:()=>Xr,uiSetDebug:()=>ld,uiSystem:()=>C,usingGamepadInput:()=>Sh,usingKeyboardInput:()=>vh,usingMouseInput:()=>xh,vec2:()=>b,vibrate:()=>Dr,vibrateEnable:()=>Ms,vibrateStop:()=>Eh,workCanvas:()=>je,workContext:()=>tn,workReadCanvas:()=>ve,workReadContext:()=>Ge,worldToScreen:()=>On,worldToScreenDelta:()=>lh,writeSaveData:()=>nu,zzfx:()=>qh,zzfxG:()=>ji,zzfxM:()=>Lc});function Ol(){return Te}function Dl(n=!0){Te=n}function Rn(n,t,e,s){f(!vn.find(o=>o.update===n&&o.render===t&&o.glContextLost===e&&o.glContextRestored===s));let i=new po(n,t,e,s);vn.push(i)}async function Ml(n,t,e,s,i,o=[],r){if(Ga&&console.log(`${Ys} Engine v${$s}`),f(!ut,"engine already initialized"),ut)return;f(de(o),"pass in images as array"),document.body||document.documentElement.appendChild(document.createElement("body")),r||(r=document.body),n||(n=()=>{}),t||(t=()=>{}),e||(e=()=>{}),s||(s=()=>{}),i||(i=()=>{});function a(){I=b(j.width,j.height),ut.imageSmoothingEnabled=!Cn,Ro()}function c(g=0){let x=g-uo;uo||(x=0),uo=g,(Gt||Li)&&(Ks=qt(Ks,1e3/(x||1),.05));let v=Gt&&Lt("Equal"),w=Gt&&Lt("Minus"),_=v?10:w?.1:1;cn+=x*_/1e3;let S=hr*_;x*=S,me+=Te?0:x,S<=1&&(me=Q(me,50));let E=!1;if(Te){E=!0,l(),Pa(),vn.forEach(T=>{var P;return(P=T.update)==null?void 0:P.call(T)});for(let T of St)T.parent||T.updateTransforms();Ca(),e(),La(),we()&&A()}else{let T=0;for(me<0&&me>-9&&(T=me,me=0);me>=0;me-=1e3/60)Qt=ka++/60,E=!0,l(),Pa(),t(),vn.forEach(P=>{var k;return(k=P.update)==null?void 0:k.call(P)}),Fa(),Ca(),e(),La(),we()&&A();me+=T}we()||A(),requestAnimationFrame(c);function A(){if(!N){E||l(),a(),s(),St.sort((T,P)=>T.renderOrder-P.renderOrder);for(let T of St)T.destroyed||T.render();i(),vn.forEach(T=>{var P;return(P=T.render)==null?void 0:P.call(T)}),Oh(),zl(),Rt(),Jl(),Ce=0,_e=0}}}function l(){if(!N){if(Fn.x){I=Fn.copy();let g=innerWidth/innerHeight,x=Fn.x/Fn.y,v=gGn){let E=I.y*Gn|0;I.x=Q(E,kn.x)}else if(w0&&!G&&(ut.fillStyle=sn.toString(),ut.fillRect(0,0,I.x,I.y),ut.fillStyle=nt.toString()),ut.lineJoin="round",ut.lineCap="round"}}if(N)return d();$h(r);let u="margin:0;overflow:hidden;background:#000;user-select:none;-webkit-user-select:none;touch-action:none;-webkit-touch-callout:none";r.style.cssText=u,j=r.appendChild(document.createElement("canvas")),Ct=ut=j.getContext("2d"),Lh(),Uh(),Nl();let h="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)";j.style.cssText=h,Z&&(Z.style.cssText=h),rc(dr),l(),Ro(),je=new OffscreenCanvas(64,64),tn=je.getContext("2d"),ve=new OffscreenCanvas(64,64),Ge=ve.getContext("2d",{willReadFrequently:!0});let p=o.map((g,x)=>Ea(x,g));return o.length||p.push(Ea(0)),p.push(gh()),fr&&p.push(new Promise(g=>{let x=0;v();function v(){Fs(),nd(x+=.01),x>1?g():setTimeout(v,16)}})),await Promise.all(p),d();async function d(){await n(),c()}}function Fa(){ir=St.filter(t=>t.collideSolidObjects);function n(t){if(!t.destroyed){t.update();for(let e of t.children)n(e)}}for(let t of St)if(!(t.parent||t.destroyed)){t.update(),t.updatePhysics();for(let e of t.children)n(e);t.updateTransforms()}St=St.filter(t=>!t.destroyed)}function Il(n=!0){for(let t of St)t.parent||t.destroy(n);St=St.filter(t=>!t.destroyed)}function ja(n,t,e=St){let s=[];if(n)if(t instanceof rt)for(let i of e)i.isOverlapping(n,t)&&s.push(i);else{let i=t*t;for(let o of e)n.distanceSquared(o.pos)e(i))}function Gl(n,t,e=St){let s=[];for(let i of e)i.collideRaycast&&Xa(n,t,i.pos,i.size)&&(he&&bt(i.pos,i.size,"#f00"),s.push(i));return he&&Se(n,t,s.length?"#f00":"#00f",.02),s}function f(n,...t){if(!n)throw console.assert(n,...t),new Error("Assert failed!")}function vt(...n){console.log(...n)}function bt(n,t=b(),e=W,s=0,i=0,o=!1,r=!1){f(L(n),"pos must be a vec2"),f(L(t),"size must be a vec2"),f(V(e)||J(e),"color is invalid"),f(R(s),"time must be a number"),f(R(i),"angle must be a number"),J(e)&&(e=e.toString());let a=new Ae(s);nn.push({pos:n.copy(),size:t.copy(),color:e,timer:a,angle:i,fill:o,screenSpace:r})}function Fl(n,t,e=W,s=0,i=0,o=!1,r=!1){f(L(n),"pos must be a vec2"),f(de(t),"points must be an array"),f(V(e)||J(e),"color is invalid"),f(R(s),"time must be a number"),f(R(i),"angle must be a number"),J(e)&&(e=e.toString()),n=n.copy(),t=t.map(c=>c.copy());let a=new Ae(s);nn.push({pos:n,points:t,color:e,timer:a,angle:i,fill:o,screenSpace:r})}function Vt(n,t=0,e=W,s=0,i=!1,o=!1){f(L(n),"pos must be a vec2"),f(R(t),"size must be a number"),f(V(e)||J(e),"color is invalid"),f(R(s),"time must be a number"),J(e)&&(e=e.toString()),n=n.copy();let r=new Ae(s);nn.push({pos:n,size:t,color:e,timer:r,angle:0,fill:i,screenSpace:o})}function or(n,t,e,s,i=!1){bt(n,void 0,t,e,s,!1,i)}function Se(n,t,e,s=.1,i=0,o=!1){f(L(n),"posA must be a vec2"),f(L(t),"posB must be a vec2"),f(R(s),"width must be a number");let r=b((t.x-n.x)/2,(t.y-n.y)/2),a=b(s,r.length()*2);bt(n.add(r),a,e,i,r.angle(),!0,o)}function go(n,t,e,s,i,o,r=!1){f(L(n),"posA must be a vec2"),f(L(e),"posB must be a vec2"),f(L(t),"sizeA must be a vec2"),f(L(s),"sizeB must be a vec2");let a=b(Q(n.x-t.x/2,e.x-s.x/2),Q(n.y-t.y/2,e.y-s.y/2)),c=b($(n.x+t.x/2,e.x+s.x/2),$(n.y+t.y/2,e.y+s.y/2));bt(a.lerp(c,.5),c.subtract(a),i,o,0,!1,r)}function In(n,t,e=1,s=W,i=0,o=0,r="monospace",a=!1){f(V(n),"text must be a string"),f(L(t),"pos must be a vec2"),f(R(e),"size must be a number"),f(V(s)||J(s),"color is invalid"),f(R(i),"time must be a number"),f(R(o),"angle must be a number"),f(V(r),"font must be a string"),J(s)&&(s=s.toString()),t=t.copy();let c=new Ae(i);nn.push({text:n,pos:t,size:e,color:s,timer:c,angle:o,font:r,screenSpace:a})}function jl(){nn=[]}function za(){yo=1}function Bl(){let n=e=>{document.body.style="background-color:#111;margin:8px",document.body.innerHTML="
"+e},t=console.assert;console.assert=(e,...s)=>{if(t(e,...s),!e){let i=s.join(" "),o=new Error().stack;throw`Assertion failed!
-`+i+`
-`+o}},onunhandledrejection=e=>n(e.reason.stack||e.reason),onerror=(e,s,i,o)=>n(`${e}
-${s}
-Ln ${i}, Col ${o}`)}function Nl(){Ga&&console.warn("LittleJS DEBUG build loaded. Use the release build for production.")}function Ca(){Gt&&(It(Na)&&(De=!De),De&&(It("Digit1")&&(ue=!ue,Sn=!1),It("Digit2")&&(Sn=!Sn,ue=!1),It("Digit3")&&(wn=!wn),It("Digit4")&&(he=!he),It("Digit5")&&za(),It("Digit7")&&(Un=!Un)),we()?(!De||It("Digit6"))&&Ua():De&&It("Digit6")&&Ja())}function zl(){if(we())return;Rt();let n=Ce,t=_e;yo&&(Cr(),oc(j),yo=0);let e=ut;if(wn&&Gi){let o=0;for(let r=0;r<8;r++)wo(r)&&o++;for(let r=0;r<8;r++){if(!wo(r))continue;let a=1,c=.2,l=Et.add(b(-a*2,((o-1)/2-r)*a*3));In(r,l.add(b(-a,a)),1),r===mt&&In("Main",l.add(b(-a*2,0)),1,"#0f0");let u=xe[r].length;for(let p=0;p{e.save();let o=i.pos,r=1,a=i.angle;if(i.screenSpace||(o=On(i.pos),r=H,a-=K),e.translate(o.x|0,o.y|0),e.rotate(a),e.scale(1,i.text?1:-1),e.fillStyle=i.color,e.strokeStyle=i.color,i.text!==void 0)e.font=i.size*r+"px "+i.font,e.textAlign="center",e.textBaseline="middle",e.fillText(i.text,0,0);else if(i.points!==void 0){e.beginPath();for(let c of i.points){let l=c.scale(r).floor();e.lineTo(l.x,l.y)}e.closePath(),i.fill&&e.fill(),e.stroke()}else if(i.size===0||i.size.x===0&&i.size.y===0){let c=Ba*r;e.fillRect(-c/2,-1,c,3),e.fillRect(-1,-c/2,3,c)}else if(i.size.x!==void 0){let c=i.size.scale(r).floor(),l=c.x,u=c.y;i.fill&&e.fillRect(-l/2|0,-u/2|0,l,u),e.strokeRect(-l/2|0,-u/2|0,l,u)}else e.beginPath(),e.arc(0,0,i.size*r/2,0,9),i.fill&&e.fill(),e.stroke();e.restore()}),nn=nn.filter(i=>i.timer<0),s){let i=vc(s.pos,Le);i&&ii(i.floor().add(b(.5)),b(1),z(0,1,1,.3),0,!1),xn(Le,s.pos,.1,i?z(1,0,0,.5):z(0,1,0,.5),void 0,void 0,!1);let o="mouse pos = "+Le;an.length&&(o+=`
-mouse collision = `+hi(Le)),o+=`
+"use strict";var __GameBundle=(()=>{var Fs=Object.defineProperty;var kc=Object.getOwnPropertyDescriptor;var Gc=Object.getOwnPropertyNames;var Fc=Object.prototype.hasOwnProperty;var jc=(n,t,e)=>()=>{if(e)throw e[0];try{return n&&(t=n(n=0)),t}catch(i){throw e=[i],i}};var Vr=(n,t)=>{for(var e in t)Fs(n,e,{get:t[e],enumerable:!0})},Bc=(n,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Gc(t))!Fc.call(n,s)&&s!==e&&Fs(n,s,{get:()=>t[s],enumerable:!(i=kc(t,s))||i.enumerable});return n};var Nc=n=>Bc(Fs({},"__esModule",{value:!0}),n);var Lc={};Vr(Lc,{ASSERT:()=>p,BLACK:()=>st,BLUE:()=>$a,Box2dDistanceJoint:()=>bs,Box2dFrictionJoint:()=>qo,Box2dGearJoint:()=>Jo,Box2dJoint:()=>qt,Box2dKinematicObject:()=>Go,Box2dMotorJoint:()=>Xo,Box2dObject:()=>Si,Box2dPinJoint:()=>Bo,Box2dPlugin:()=>xs,Box2dPrismaticJoint:()=>Uo,Box2dPulleyJoint:()=>Ho,Box2dRaycastResult:()=>ms,Box2dRevoluteJoint:()=>zo,Box2dRopeJoint:()=>No,Box2dStaticObject:()=>ys,Box2dTargetJoint:()=>jo,Box2dTileLayer:()=>Fo,Box2dWeldJoint:()=>Wo,Box2dWheelJoint:()=>Vo,CLEAR_BLACK:()=>de,CLEAR_WHITE:()=>tn,CYAN:()=>ql,CanvasLayer:()=>os,Color:()=>Tt,Ease:()=>Ss,EngineObject:()=>Fe,GRAY:()=>Vl,GREEN:()=>Ya,ImageFont:()=>Zi,LOG:()=>vt,Light:()=>Co,LightSystemPlugin:()=>_o,MAGENTA:()=>Hl,Medal:()=>ps,NewgroundsMedal:()=>To,NewgroundsPlugin:()=>Ao,ORANGE:()=>Wl,PI:()=>Y,PURPLE:()=>Ka,Particle:()=>rs,ParticleEmitter:()=>yo,PathFinder:()=>Yo,PathFinderNode:()=>ws,PostProcessPlugin:()=>Eo,RED:()=>nr,RandomGenerator:()=>uo,Sound:()=>di,SoundInstance:()=>is,TextureInfo:()=>je,TileCollisionLayer:()=>pi,TileInfo:()=>Ee,TileLayer:()=>fi,TileLayerData:()=>yn,Timer:()=>we,Tween:()=>vs,UIButton:()=>vi,UICheckbox:()=>Do,UILayout:()=>ko,UIObject:()=>se,UISlider:()=>Mo,UISystemPlugin:()=>Po,UIText:()=>gs,UITextInput:()=>Lo,UITile:()=>Oo,UIVideo:()=>Io,Vector2:()=>rt,WHITE:()=>q,YELLOW:()=>Xa,ZzFXMusic:()=>Ro,abs:()=>nt,atan2:()=>Zo,audioContext:()=>dt,audioDefaultSampleRate:()=>Wn,audioIsRunning:()=>hi,audioMasterGain:()=>Ge,box2d:()=>m,box2dDebug:()=>Jr,box2dInit:()=>ad,box2dSetDebug:()=>rd,cameraAngle:()=>Q,cameraFit:()=>rh,cameraPos:()=>Ct,cameraScale:()=>X,canvasClearColor:()=>Ye,canvasColorTiles:()=>As,canvasFixedSize:()=>Pn,canvasMaxAspect:()=>Rn,canvasMaxSize:()=>Cn,canvasMinAspect:()=>Zn,canvasPixelRatio:()=>$e,canvasPixelated:()=>or,ceil:()=>si,clamp:()=>z,combineCanvases:()=>br,cos:()=>at,debug:()=>Ft,debugCircle:()=>zt,debugClear:()=>Il,debugLine:()=>xe,debugOverlap:()=>co,debugOverlay:()=>Re,debugPoint:()=>Qo,debugPointSize:()=>Da,debugPoly:()=>Ml,debugRect:()=>bt,debugScreenshot:()=>Ia,debugShowErrors:()=>kl,debugText:()=>_n,debugVideoCaptureIsActive:()=>ve,debugVideoCaptureStart:()=>ka,debugVideoCaptureStop:()=>Ga,debugWatermark:()=>Ts,distanceAngle:()=>zl,distanceWrap:()=>tr,drawCanvas2D:()=>wn,drawCircle:()=>Qi,drawCircleGradient:()=>ih,drawContext:()=>Et,drawCount:()=>Te,drawCrescent:()=>ud,drawEllipse:()=>ec,drawEllipseGradient:()=>nc,drawLine:()=>hn,drawLineList:()=>fo,drawNineSlice:()=>Ac,drawNineSliceScreen:()=>cd,drawPoly:()=>Gn,drawRect:()=>Ki,drawRectGradient:()=>th,drawRegularPoly:()=>tc,drawText:()=>sh,drawTextScreen:()=>Ke,drawTextureWrapped:()=>eh,drawThreeSlice:()=>Ec,drawThreeSliceScreen:()=>ld,drawTile:()=>Dt,enablePhysicsSolver:()=>Rs,engineAddPlugin:()=>vn,engineImageFont:()=>rc,engineInit:()=>Pl,engineName:()=>Ji,engineObjects:()=>St,engineObjectsCallback:()=>Ol,engineObjectsCollect:()=>Oa,engineObjectsCollide:()=>Ko,engineObjectsDestroy:()=>Ll,engineObjectsRaycast:()=>Dl,engineObjectsUpdate:()=>La,engineVersion:()=>Ui,fetchJSON:()=>Xl,floor:()=>wt,fontDefault:()=>wi,formatTime:()=>ir,frame:()=>Ra,frameRate:()=>_l,gamepadConnected:()=>go,gamepadDirectionEmulateStick:()=>dr,gamepadDpad:()=>po,gamepadIsDown:()=>Ce,gamepadPrimary:()=>mt,gamepadStick:()=>li,gamepadStickCount:()=>ac,gamepadVibrate:()=>Sh,gamepadVibrateStop:()=>wh,gamepadWasPressed:()=>Ar,gamepadWasReleased:()=>vh,gamepadsEnable:()=>Ps,getCameraSize:()=>sc,getCrescentPoints:()=>_c,getNoteFrequency:()=>dc,getPaused:()=>Cl,glAntialias:()=>Lr,glCanvas:()=>et,glCircleSides:()=>Ti,glClearCanvas:()=>mc,glClearRect:()=>wc,glCompileShader:()=>wo,glContext:()=>g,glCopyToContext:()=>kr,glCreateProgram:()=>zn,glCreateTexture:()=>Ms,glDeleteTexture:()=>xc,glDraw:()=>mi,glDrawColoredPoints:()=>jr,glDrawOutlineTransform:()=>Fr,glDrawPoints:()=>Sc,glDrawPointsTransform:()=>Gr,glDrawUntextured:()=>vc,glEnable:()=>B,glFlush:()=>Rt,glSetAntialias:()=>Yh,glSetRenderTarget:()=>Qn,glSetTexture:()=>Mr,glSetTextureData:()=>Ir,glSetTextureWrap:()=>bc,gravity:()=>Jt,headlessMode:()=>J,hsl:()=>Le,hypot:()=>Fa,inputClear:()=>Pi,inputClearKey:()=>wr,inputMouseMoveThreshold:()=>Sr,inputPreventDefault:()=>Ln,inputWASDEmulateDirection:()=>ti,isArray:()=>ue,isColor:()=>V,isFullscreen:()=>oc,isIntersecting:()=>za,isNumber:()=>P,isOnScreen:()=>ah,isOverlapping:()=>Hi,isPowerOfTwo:()=>oi,isStringLike:()=>W,isTouchDevice:()=>ne,isUsingGamepad:()=>Dn,isVector2:()=>O,keyDirection:()=>bh,keyIsDown:()=>Ot,keyWasPressed:()=>kt,keyWasReleased:()=>Tr,lastInputDevice:()=>He,lerp:()=>Ut,lerpAngle:()=>Jl,lerpWrap:()=>Na,lightSystem:()=>H,lineTest:()=>Ua,log2:()=>ja,mainCanvas:()=>N,mainCanvasSize:()=>G,mainContext:()=>lt,max:()=>K,medalDisplaySize:()=>ds,medalDisplaySlideTime:()=>On,medalDisplayTime:()=>hs,medals:()=>bi,medalsForEach:()=>Is,medalsInit:()=>Zh,medalsPreventUnlock:()=>Br,medalsReset:()=>td,min:()=>Z,mod:()=>ee,mouseDelta:()=>xr,mouseDeltaScreen:()=>ye,mouseInWindow:()=>ts,mouseIsDown:()=>ni,mousePos:()=>_e,mousePosScreen:()=>Nt,mouseWasPressed:()=>ci,mouseWasReleased:()=>xh,mouseWheel:()=>vr,nearestPowerOfTwo:()=>Ul,newgrounds:()=>xi,noise1D:()=>Zl,noise2D:()=>tu,objectDefaultAngleDamping:()=>lr,objectDefaultDamping:()=>cr,objectDefaultFriction:()=>hr,objectDefaultMass:()=>ar,objectDefaultRestitution:()=>ur,objectMaxSpeed:()=>Oe,oscillate:()=>Ja,particleEmitRateScale:()=>Xi,paused:()=>Se,percent:()=>jt,percentLerp:()=>Nl,playSamples:()=>Pr,pointerLockExit:()=>Eh,pointerLockIsActive:()=>cc,pointerLockRequest:()=>Ah,postProcess:()=>It,primitiveCount:()=>Ae,rand:()=>ht,randBool:()=>Va,randColor:()=>lo,randInCircle:()=>Ha,randInt:()=>er,randSign:()=>Wa,randVec2:()=>qa,readSaveData:()=>Kl,rgb:()=>U,round:()=>Wi,saveCanvas:()=>Qa,saveDataURL:()=>ri,saveText:()=>Yl,screenToWorld:()=>Ci,screenToWorldDelta:()=>ic,screenToWorldTransform:()=>Ri,setAdditiveBlendMode:()=>ai,setCameraAngle:()=>nu,setCameraPos:()=>eu,setCameraScale:()=>iu,setCanvasClearColor:()=>ru,setCanvasColorTiles:()=>ou,setCanvasFixedSize:()=>uu,setCanvasMaxAspect:()=>lu,setCanvasMaxSize:()=>au,setCanvasMinAspect:()=>cu,setCanvasPixelRatio:()=>du,setCanvasPixelated:()=>Za,setCursor:()=>hh,setDebugKey:()=>Zu,setDebugWatermark:()=>Qu,setEnablePhysicsSolver:()=>Su,setFontDefault:()=>fu,setGLCircleSides:()=>mu,setGLEnable:()=>yu,setGamepadDirectionEmulateStick:()=>Ou,setGamepadsEnable:()=>Lu,setGravity:()=>Ru,setHeadlessMode:()=>gu,setInputMouseMoveThreshold:()=>ph,setInputPreventDefault:()=>fh,setInputWASDEmulateDirection:()=>Du,setMedalDisplaySize:()=>id,setMedalDisplaySlideTime:()=>nd,setMedalDisplayTime:()=>ed,setMedalsPreventUnlock:()=>sd,setObjectDefaultAngleDamping:()=>Au,setObjectDefaultDamping:()=>Tu,setObjectDefaultFriction:()=>_u,setObjectDefaultMass:()=>wu,setObjectDefaultRestitution:()=>Eu,setObjectMaxSpeed:()=>Cu,setParticleEmitRateScale:()=>Pu,setPaused:()=>Rl,setShowSplashScreen:()=>pu,setSoundDefaultRange:()=>$u,setSoundDefaultTaper:()=>Ku,setSoundEnable:()=>Xu,setSoundVolume:()=>Yu,setTileDefaultBleed:()=>vu,setTileDefaultPadding:()=>xu,setTileDefaultSize:()=>bu,setTilesPixelated:()=>hu,setTimeScale:()=>su,setTouchGamepadAlpha:()=>Vu,setTouchGamepadAnalog:()=>zu,setTouchGamepadButtonCount:()=>Fu,setTouchGamepadCenterButtonSize:()=>Gu,setTouchGamepadDisplayTime:()=>Wu,setTouchGamepadEnable:()=>Iu,setTouchGamepadFloating:()=>Ju,setTouchGamepadLeftButtonCount:()=>Bu,setTouchGamepadLeftStick:()=>ju,setTouchGamepadPassthrough:()=>ku,setTouchGamepadRightStick:()=>Nu,setTouchGamepadSize:()=>Uu,setTouchGamepadVibration:()=>qu,setTouchInputEnable:()=>Mu,setVibrateEnable:()=>Hu,shareURL:()=>$l,showSplashScreen:()=>rr,sign:()=>te,sin:()=>it,smoothStep:()=>qi,soundDefaultRange:()=>gr,soundDefaultTaper:()=>yr,soundEnable:()=>Wt,soundVolume:()=>gn,speak:()=>Nh,speakStop:()=>zh,tan:()=>Ba,textureInfos:()=>nn,tile:()=>_i,tileCollisionGetData:()=>ss,tileCollisionLayers:()=>Qe,tileCollisionRaycast:()=>fc,tileCollisionTest:()=>We,tileDefaultBleed:()=>Cs,tileDefaultPadding:()=>_s,tileDefaultSize:()=>Es,tileLayersLoad:()=>Uh,tilesPixelated:()=>mn,time:()=>$t,timeDelta:()=>$o,timeReal:()=>Ze,timeScale:()=>sr,toggleFullscreen:()=>uh,touchGamepadAlpha:()=>pr,touchGamepadAnalog:()=>Ai,touchGamepadButtonCount:()=>Jn,touchGamepadCenterButtonSize:()=>he,touchGamepadDisplayTime:()=>ei,touchGamepadEnable:()=>en,touchGamepadFloating:()=>sn,touchGamepadLeftButtonCount:()=>Un,touchGamepadLeftStick:()=>Sn,touchGamepadPassthrough:()=>fr,touchGamepadRightStick:()=>Vn,touchGamepadSize:()=>Vt,touchGamepadVibration:()=>Yi,touchInputEnable:()=>un,tweenProperty:()=>hd,tweenStopAll:()=>dd,tweenUpdate:()=>Pc,uiDebug:()=>zr,uiSetDebug:()=>od,uiSystem:()=>E,usingGamepadInput:()=>mh,usingKeyboardInput:()=>yh,usingMouseInput:()=>gh,vec2:()=>b,vibrate:()=>Er,vibrateEnable:()=>Ei,vibrateStop:()=>Th,workCanvas:()=>Ie,workContext:()=>qe,workReadCanvas:()=>be,workReadContext:()=>De,worldToScreen:()=>Tn,worldToScreenDelta:()=>oh,writeSaveData:()=>Ql,zzfx:()=>Jh,zzfxG:()=>Os,zzfxM:()=>Tc});function Cl(){return Se}function Rl(n=!0){Se=n}function vn(n,t,e,i){p(!dn.find(o=>o.update===n&&o.render===t&&o.glContextLost===e&&o.glContextRestored===i));let s=new ro(n,t,e,i);dn.push(s)}async function Pl(n,t,e,i,s,o=[],a){if(Pa&&console.log(`${Ji} Engine v${Ui}`),p(!lt,"engine already initialized"),lt)return;p(ue(o),"pass in images as array"),document.body||document.documentElement.appendChild(document.createElement("body")),a||(a=document.body),n||(n=()=>{}),t||(t=()=>{}),e||(e=()=>{}),i||(i=()=>{}),s||(s=()=>{});function r(){G=b(N.width,N.height),lt.imageSmoothingEnabled=!mn,So()}function c(y=0){let x=y-io;io||(x=0),io=y,(Ft||Ts)&&(Vi=Ut(Vi,1e3/(x||1),.05));let v=Ft&&Ot("Equal"),w=Ft&&Ot("Minus"),C=v?10:w?.1:1;Ze+=x*C/1e3;let S=sr*C;x*=S,ge+=Se?0:x,S<=1&&(ge=Z(ge,50));let _=!1;if(Se){_=!0,l(),wa(),dn.forEach(T=>{var L;return(L=T.update)==null?void 0:L.call(T)});for(let T of St)T.parent||T.updateTransforms();ba(),e(),Ta(),ve()&&A()}else{let T=0;for(ge<0&&ge>-9&&(T=ge,ge=0);ge>=0;ge-=1e3/60)$t=Ra++/60,_=!0,l(),wa(),t(),dn.forEach(L=>{var F;return(F=L.update)==null?void 0:F.call(L)}),La(),ba(),e(),Ta(),ve()&&A();ge+=T}ve()||A(),requestAnimationFrame(c);function A(){if(!J){_||l(),r(),i(),St.sort((T,L)=>T.renderOrder-L.renderOrder);for(let T of St)T.destroyed||T.render();s(),dn.forEach(T=>{var L;return(L=T.render)==null?void 0:L.call(T)}),Ch(),Fl(),Rt(),jl(),Te=0,Ae=0}}}function l(){if(!J){if(Pn.x){G=Pn.copy();let y=innerWidth/innerHeight,x=Pn.x/Pn.y,v=yRn){let _=G.y*Rn|0;G.x=Z(_,Cn.x)}else if(w0&&!B&&(lt.fillStyle=Ye.toString(),lt.fillRect(0,0,G.x,G.y),lt.fillStyle=st.toString()),lt.lineJoin="round",lt.lineCap="round"}}if(J)return d();qh(a);let u="margin:0;overflow:hidden;background:#000;user-select:none;-webkit-user-select:none;touch-action:none;-webkit-touch-callout:none";a.style.cssText=u,N=a.appendChild(document.createElement("canvas")),Et=lt=N.getContext("2d"),_h(),Bh(),Gl();let h="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)";N.style.cssText=h,et&&(et.style.cssText=h),Za(or),l(),So(),Ie=new OffscreenCanvas(64,64),qe=Ie.getContext("2d"),be=new OffscreenCanvas(64,64),De=be.getContext("2d",{willReadFrequently:!0});let f=o.map((y,x)=>va(x,y));return o.length||f.push(va(0)),f.push(dh()),rr&&f.push(new Promise(y=>{let x=0;v();function v(){Pi(),Qh(x+=.01),x>1?y():setTimeout(v,16)}})),await Promise.all(f),d();async function d(){await n(),c()}}function La(){Ko=St.filter(t=>t.collideSolidObjects);function n(t){if(!t.destroyed){t.update();for(let e of t.children)n(e)}}for(let t of St)if(!(t.parent||t.destroyed)){t.update(),t.updatePhysics();for(let e of t.children)n(e);t.updateTransforms()}St=St.filter(t=>!t.destroyed)}function Ll(n=!0){for(let t of St)t.parent||t.destroy(n);St=St.filter(t=>!t.destroyed)}function Oa(n,t,e=St){let i=[];if(n)if(t instanceof rt)for(let s of e)s.isOverlapping(n,t)&&i.push(s);else{let s=t*t;for(let o of e)n.distanceSquared(o.pos)e(s))}function Dl(n,t,e=St){let i=[];for(let s of e)s.collideRaycast&&za(n,t,s.pos,s.size)&&(le&&bt(s.pos,s.size,"#f00"),i.push(s));return le&&xe(n,t,i.length?"#f00":"#00f",.02),i}function p(n,...t){if(!n)throw console.assert(n,...t),new Error("Assert failed!")}function vt(...n){console.log(...n)}function bt(n,t=b(),e=q,i=0,s=0,o=!1,a=!1){p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(W(e)||V(e),"color is invalid"),p(P(i),"time must be a number"),p(P(s),"angle must be a number"),V(e)&&(e=e.toString());let r=new we(i);Xe.push({pos:n.copy(),size:t.copy(),color:e,timer:r,angle:s,fill:o,screenSpace:a})}function Ml(n,t,e=q,i=0,s=0,o=!1,a=!1){p(O(n),"pos must be a vec2"),p(ue(t),"points must be an array"),p(W(e)||V(e),"color is invalid"),p(P(i),"time must be a number"),p(P(s),"angle must be a number"),V(e)&&(e=e.toString()),n=n.copy(),t=t.map(c=>c.copy());let r=new we(i);Xe.push({pos:n,points:t,color:e,timer:r,angle:s,fill:o,screenSpace:a})}function zt(n,t=0,e=q,i=0,s=!1,o=!1){p(O(n),"pos must be a vec2"),p(P(t),"size must be a number"),p(W(e)||V(e),"color is invalid"),p(P(i),"time must be a number"),V(e)&&(e=e.toString()),n=n.copy();let a=new we(i);Xe.push({pos:n,size:t,color:e,timer:a,angle:0,fill:s,screenSpace:o})}function Qo(n,t,e,i,s=!1){bt(n,void 0,t,e,i,!1,s)}function xe(n,t,e,i=.1,s=0,o=!1){p(O(n),"posA must be a vec2"),p(O(t),"posB must be a vec2"),p(P(i),"width must be a number");let a=b((t.x-n.x)/2,(t.y-n.y)/2),r=b(i,a.length()*2);bt(n.add(a),r,e,s,a.angle(),!0,o)}function co(n,t,e,i,s,o,a=!1){p(O(n),"posA must be a vec2"),p(O(e),"posB must be a vec2"),p(O(t),"sizeA must be a vec2"),p(O(i),"sizeB must be a vec2");let r=b(Z(n.x-t.x/2,e.x-i.x/2),Z(n.y-t.y/2,e.y-i.y/2)),c=b(K(n.x+t.x/2,e.x+i.x/2),K(n.y+t.y/2,e.y+i.y/2));bt(r.lerp(c,.5),c.subtract(r),s,o,0,!1,a)}function _n(n,t,e=1,i=q,s=0,o=0,a="monospace",r=!1){p(W(n),"text must be a string"),p(O(t),"pos must be a vec2"),p(P(e),"size must be a number"),p(W(i)||V(i),"color is invalid"),p(P(s),"time must be a number"),p(P(o),"angle must be a number"),p(W(a),"font must be a string"),V(i)&&(i=i.toString()),t=t.copy();let c=new we(s);Xe.push({text:n,pos:t,size:e,color:i,timer:c,angle:o,font:a,screenSpace:r})}function Il(){Xe=[]}function Ia(){ao=1}function kl(){let n=e=>{document.body.style="background-color:#111;margin:8px",document.body.innerHTML="
"+e},t=console.assert;console.assert=(e,...i)=>{if(t(e,...i),!e){let s=i.join(" "),o=new Error().stack;throw`Assertion failed!
+`+s+`
+`+o}},onunhandledrejection=e=>n(e.reason.stack||e.reason),onerror=(e,i,s,o)=>n(`${e}
+${i}
+Ln ${s}, Col ${o}`)}function Gl(){Pa&&console.warn("LittleJS DEBUG build loaded. Use the release build for production.")}function ba(){Ft&&(kt(Ma)&&(Re=!Re),Re&&(kt("Digit1")&&(ce=!ce,fn=!1),kt("Digit2")&&(fn=!fn,ce=!1),kt("Digit3")&&(pn=!pn),kt("Digit4")&&(le=!le),kt("Digit5")&&Ia(),kt("Digit7")&&(kn=!kn)),ve()?(!Re||kt("Digit6"))&&Ga():Re&&kt("Digit6")&&ka())}function Fl(){if(ve())return;Rt();let n=Te,t=Ae;ao&&(br(),Qa(N),ao=0);let e=lt;if(pn&&Ps){let o=0;for(let a=0;a<8;a++)go(a)&&o++;for(let a=0;a<8;a++){if(!go(a))continue;let r=1,c=.2,l=Ct.add(b(-r*2,((o-1)/2-a)*r*3));_n(a,l.add(b(-r,r)),1),a===mt&&_n("Main",l.add(b(-r*2,0)),1,"#0f0");let u=me[a].length;for(let f=0;f{e.save();let o=s.pos,a=1,r=s.angle;if(s.screenSpace||(o=Tn(s.pos),a=X,r-=Q),e.translate(o.x|0,o.y|0),e.rotate(r),e.scale(1,s.text?1:-1),e.fillStyle=s.color,e.strokeStyle=s.color,s.text!==void 0)e.font=s.size*a+"px "+s.font,e.textAlign="center",e.textBaseline="middle",e.fillText(s.text,0,0);else if(s.points!==void 0){e.beginPath();for(let c of s.points){let l=c.scale(a).floor();e.lineTo(l.x,l.y)}e.closePath(),s.fill&&e.fill(),e.stroke()}else if(s.size===0||s.size.x===0&&s.size.y===0){let c=Da*a;e.fillRect(-c/2,-1,c,3),e.fillRect(-1,-c/2,3,c)}else if(s.size.x!==void 0){let c=s.size.scale(a).floor(),l=c.x,u=c.y;s.fill&&e.fillRect(-l/2|0,-u/2|0,l,u),e.strokeRect(-l/2|0,-u/2|0,l,u)}else e.beginPath(),e.arc(0,0,s.size*a/2,0,9),s.fill&&e.fill(),e.stroke();e.restore()}),Xe=Xe.filter(s=>s.timer<0),i){let s=fc(i.pos,_e);s&&Ki(s.floor().add(b(.5)),b(1),U(0,1,1,.3),0,!1),hn(_e,i.pos,.1,s?U(1,0,0,.5):U(0,1,0,.5),void 0,void 0,!1);let o="mouse pos = "+_e;Qe.length&&(o+=`
+mouse collision = `+ss(_e)),o+=`
 
 --- object info ---
-`,o+=s.toString(),rn(o,Ut,24,z(),.05,void 0,"center","monospace")}{e.save(),e.fillStyle="#fff",e.textAlign="left",e.textBaseline="top",e.font="20px monospace",e.shadowColor="#000",e.shadowBlur=9;let r=9,a=0,c=24;if(De){e.fillText(`${Ys} v${$s}`,r,a+=c/2),e.fillText("Time: "+ur(Qt),r,a+=c),e.fillText("FPS: "+Ks.toFixed(1)+(G?" WebGL":" Canvas2D"),r,a+=c),e.fillText("Objects: "+St.length,r,a+=c),e.fillText("Draw Calls: "+Ce,r,a+=c),e.fillText("Primitives: "+_e,r,a+=c),e.fillText("---------",r,a+=c),e.fillStyle="#f00",e.fillText("ESC: Debug Overlay",r,a+=c),e.fillStyle=ue?"#f00":"#fff",e.fillText("1: Debug Physics",r,a+=c),e.fillStyle=Sn?"#f00":"#fff",e.fillText("2: Debug Particles",r,a+=c),e.fillStyle=wn?"#f00":"#fff",e.fillText("3: Debug Gamepads",r,a+=c),e.fillStyle=he?"#f00":"#fff",e.fillText("4: Debug Raycasts",r,a+=c),e.fillStyle="#fff",e.fillText("5: Save Screenshot",r,a+=c),e.fillText("6: Toggle Video Capture",r,a+=c),e.fillStyle=Un?"#f00":"#fff",e.fillText("7: Debug Sound",r,a+=c);let l="",u="";for(let h in Y[0])Lt(h,0)&&(parseInt(h)<3?u+=h+" ":l+=h+" ");u&&e.fillText("Mouse: "+u,r,a+=c),l&&e.fillText("Keys: "+l,r,a+=c);for(let h=1;hs.push(a.data),i.onstop=()=>{let a=new Blob(s,{type:"video/webm"}),c=URL.createObjectURL(a);ps(c,"capture.webm",1e3)};let o,r;if(Xt){r=new ConstantSourceNode(ft,{offset:0}),r.connect(Ne),r.start(),o=ft.createMediaStreamDestination(),Ne.connect(o);for(let a of o.stream.getAudioTracks())n.addTrack(a)}try{i.start()}catch{vt("Video capture not supported in this browser!"),r==null||r.stop();return}vt("Video capture started."),Me={mediaRecorder:i,captureTimer:e,videoTrack:t,silentAudioSource:r,audioStreamDestination:o}}function Ua(){var n,t,e;f(we(),"Not capturing video!"),vt(`Video capture ended. ${Me.captureTimer.get().toFixed(2)} seconds recorded.`),le.style.display="none",(n=Me.silentAudioSource)==null||n.stop(),(t=Me.mediaRecorder)==null||t.stop(),(e=Me.videoTrack)==null||e.stop(),Me=void 0}function Ul(){f(we(),"Not capturing video!"),Cr(),Me.videoTrack.requestFrame(),le.textContent="\u25CF REC "+ur(Me.captureTimer)}function te(n){if(Gt){let t=Object.keys(n),e={};t.forEach(s=>e[s]=n[s]),t.forEach(s=>{Object.defineProperty(n,s,{get:()=>e[s],set:i=>{f(!1,`Cannot modify engine constant. Attempted to set constant (${n}) property '${s}' to '${i}'.`)},enumerable:!0})})}return Object.freeze(n)}function se(n,t=1){return(n%t+t)%t}function B(n,t=0,e=1){return ne?e:n}function Ft(n,t,e){return(e-=t)?B((n-t)/e):0}function qt(n,t,e){return n+B(e)*(t-n)}function Vl(n,t,e,s,i){return qt(s,i,Ft(n,t,e))}function ar(n,t,e=1){f(e>0,"distanceWrap wrapSize must be > 0");let s=(n-t)%e;return s*2%e-s}function Ha(n,t,e,s=1){return n+B(e)*ar(t,n,s)}function Wl(n,t){return ar(n,t,2*X)}function ql(n,t,e){return Ha(n,t,e,2*X)}function Zs(n){return n*n*(3-2*n)}function fs(n){return!(n&n-1)}function Hl(n){return 2**ds(Wa(n))}function ti(n,t,e,s=b()){let i=(n.x-e.x)*2,o=(n.y-e.y)*2,r=t.x+s.x,a=t.y+s.y;return tt(i)p)return!1;h=$(g,h)}else{if(g0?a.x+1:a.x,x=h>0?a.y+1:a.y,v=c?(g-n.x)/c:1/0,w=l?(x-n.y)/l:1/0,_=0,S=v,E=w,A=pa.x&&(T.x=a.x+1-P),k.ya.y&&(T.y=a.y+1-P),s&&(A?s.set(-u,0):s.set(0,-h)),T}(A=SURL.revokeObjectURL(n),e)}function tu(n,t,e){var s;f(V(n),"shareURL requires title string"),f(V(t),"shareURL requires url string"),(s=navigator.share)==null||s.call(navigator,{title:n,url:t}).then(()=>e==null?void 0:e())}function eu(n,t){f(V(n),"loadData requires saveName string");let e={};try{let s=localStorage[n];if(s)try{e=JSON.parse(s)}catch{vt("readSaveData: corrupt JSON for",n,"\u2014 using defaults")}}catch{vt("readSaveData: localStorage unavailable \u2014 using defaults")}return{...t,...e}}function nu(n,t){f(V(n),"saveData requires saveName string");try{localStorage[n]=JSON.stringify(t)}catch{vt("writeSaveData: failed to write",n)}}function xo(n){let t=(n|0)^2654435769;return t=Math.imul(t^t>>>16,2246822507),t=Math.imul(t^t>>>13,3266489909),t^=t>>>16,(t>>>0)/2**32}function su(n){let t=Tt(n);return qt(xo(t),xo(t+1),Zs(n-t))}function iu(n,t){let e=Tt(n),s=Tt(t),i=Zs(n-e),o=Zs(t-s),r=(a,c)=>xo(a+c*374761393);return qt(qt(r(e,s),r(e+1,s),i),qt(r(e,s+1),r(e+1,s+1),i),o)}function ou(n){Et=n.copy()}function ru(n){K=n}function au(n){H=n}function cu(n){hr=n}function lu(n){Oi=n}function uu(n){sn=n.copy()}function hu(n){kn=n.copy()}function du(n){as=n}function fu(n){Gn=n}function pu(n){Fn=n.copy()}function rc(n){dr=n,j&&(j.style.imageRendering=n?"pixelated":""),Z&&(Z.style.imageRendering=n?"pixelated":"")}function yu(n){Cn=n}function gu(n){on=n}function mu(n){Ls=n}function bu(n){fr=n}function xu(n){N=n}function vu(n){if(n&&!Eo){console.warn("Can not enable WebGL if it was disabled on start.");return}G=n,Z&&(Z.style.display=n?"":"none")}function Su(n){Os=n}function wu(n){Di=n.copy()}function Tu(n){Mi=n}function Au(n){Ii=n}function Cu(n){ki=n}function _u(n){pr=n}function Eu(n){yr=n}function Ru(n){gr=n}function Pu(n){mr=n}function Lu(n){br=n}function Ou(n){ke=n}function Du(n){Wt=n.copy()}function Mu(n){ei=n}function Iu(n){Gi=n}function ku(n){xr=n}function Gu(n){cs=n}function Fu(n){bn=n}function ju(n){un=n}function Bu(n){vr=n}function Nu(n){fe=n}function zu(n){$n=n,n>0&&(Qn=!1)}function Ju(n){Pn=n,n&&(Kn=0)}function Uu(n){Kn=n,n>0&&(Pn=!1)}function Vu(n){Qn=n,n&&($n=0)}function Wu(n){Ds=n}function qu(n){dn=n}function Hu(n){Ht=n}function Xu(n){Sr=n}function Yu(n){ls=n}function $u(n){ni=n}function Ku(n){Ms=n}function Qu(n){Xt=n}function Zu(n){Tn=n,Xt&&!N&&Ne&&(Ne.gain.value=n)}function th(n){wr=n}function eh(n){Tr=n}function nh(n){Li=n}function sh(n){Na=n}function si(n){return n.r>=1&&n.g>=1&&n.b>=1}function Ar(n){return n.r<=0&&n.g<=0&&n.b<=0&&n.a<=0}function Is(n=0,t=Di,e=0,s=Mi,i=Ii){if(f(L(n)||typeof n=="number","index must be a vec2 or number"),f(L(t)||typeof t=="number","size must be a vec2 or number"),f(R(e)||e instanceof Je,"texture must be a number or TextureInfo"),f(R(s),"padding must be a number"),N)return new Ee;typeof t=="number"&&(f(t>0),t=new rt(t,t));let o=typeof e=="number"?hn[e]:e;f(o instanceof Je,"tile texture is not loaded"),f(o.size.x>0,"tile texture is not loaded");let r=t.x+s*2,a=t.y+s*2,c,l;if(typeof n=="number"){let h=o.size.x/r|0;c=n%h,l=n/h|0}else c=n.x,l=n.y;let u=new rt(c*r+s,l*a+s);return new Ee(u,t,o,s,i)}function Ot(n,t=b(1),e,s=W,i=0,o,r,a=G,c=!1,l){var p;f(L(n),"pos must be a vec2"),f(L(t),"size must be a vec2"),f(J(s),"color is invalid"),f(R(i),"angle must be a number"),f(!r||J(r),"additiveColor must be a color"),f(!l||!a,"context only supported in canvas 2D mode");let u=e==null?void 0:e.textureInfo,h=(p=e==null?void 0:e.bleed)!=null?p:0;if(a&&G)if(f(!!y,"WebGL is not enabled!"),c&&([n,t,i]=Gs(n,t,i)),u){let d=u.sizeInverse,g=e.pos.x*d.x,x=e.pos.y*d.y,v=e.size.x*d.x,w=e.size.y*d.y;if(Nr(u.glTexture),h){let _=d.x*h,S=d.y*h;Cs(n.x,n.y,o?-t.x:t.x,t.y,i,g+_,x+S,g-_+v,x-S+w,s.rgbaInt(),r&&r.rgbaInt())}else Cs(n.x,n.y,o?-t.x:t.x,t.y,i,g,x,g+v,x+w,s.rgbaInt(),r&&r.rgbaInt())}else{let d=r?s.add(r):s;Ec(n.x,n.y,t.x,t.y,i,d.rgbaInt())}else++Ce,++_e,Ln(n,t,i,o,d=>{if(u){d.scale(1,-1);let g=e.pos.x,x=e.pos.y,v=e.size.x,w=e.size.y;fh(d,u.image,g,x,v,w,-.5,-.5,1,1,s,r,h)}else{let g=r?s.add(r):s;d.fillStyle=g.toString(),d.fillRect(-.5,-.5,1,1)}},c,l)}function ii(n,t,e,s,i,o,r){Ot(n,t,void 0,e,s,!1,void 0,i,o,r)}function ih(n,t,e=W,s=ln,i=0,o=G,r=!1,a){if(f(L(n),"pos must be a vec2"),f(L(t),"size must be a vec2"),f(J(e)&&J(s),"color is invalid"),f(R(i),"angle must be a number"),f(!a||!o,"context only supported in canvas 2D mode"),o&&G){f(!!y,"WebGL is not enabled!"),r&&(n=ks(n),t=t.scale(1/H),i+=K);let c=[],l=[],u=t.x/2,h=t.y/2,p=e.rgbaInt(),d=s.rgbaInt(),g=at(-i),x=et(-i);for(let v=4;v--;){let w=v&1?u:-u,_=v&2?h:-h,S=w*g-_*x,E=w*x+_*g,A=v&2?p:d;c.push(b(n.x+S,n.y+E)),l.push(A)}Wr(c,l)}else++Ce,++_e,Ln(n,t,i,!1,c=>{let l=c.createLinearGradient(0,.5,0,-.5);l.addColorStop(0,e.toString()),l.addColorStop(1,s.toString()),c.fillStyle=l,c.fillRect(-.5,-.5,1,1)},r,a)}function oh(n,t,e,s=0,i=W,o=0,r,a=G,c=!1,l){if(f(L(n),"pos must be a vec2"),f(L(t),"size must be a vec2"),f(L(e),"wrapCount must be a vec2"),f(J(i),"color is invalid"),f(R(o),"angle must be a number"),f(!r||J(r),"additiveColor must be a color"),f(!l||!a,"context only supported in canvas 2D mode"),f(!(s instanceof Ee),"pass a TextureInfo or texture index, not a TileInfo \u2014 use tileInfo.textureInfo"),N)return;let u=typeof s=="number"?hn[s]:s;if(f(u instanceof Je,"texture not loaded"),f(u.size.x>0,"texture not loaded"),f(u.wrap,"drawTextureWrapped requires a wrap-enabled texture; call textureInfo.setWrap(true) first"),a&&G){f(!!y,"WebGL is not enabled!"),c&&([n,t,o]=Gs(n,t,o)),Nr(u.glTexture),Cs(n.x,n.y,t.x,t.y,o,0,0,e.x,e.y,i.rgbaInt(),r&&r.rgbaInt());return}++Ce,++_e,c||(n=On(n),t=t.scale(H),o-=K);let h=!Oi||(r?si(i.add(r))&&r.a<=0:si(i)),p=!h&&r&&!Ar(r),d=h?u.image:dh(u.image,i,r);l=l||Ct,l.save(),l.translate(n.x+.5,n.y+.5),l.rotate(o),l.globalAlpha=p?1:i.a;let g=l.createPattern(d,"repeat"),x=new DOMMatrix().translate(-t.x/2,-t.y/2).scale(t.x/(e.x*d.width),t.y/(e.y*d.height));g.setTransform(x),l.fillStyle=g,l.fillRect(-t.x/2,-t.y/2,t.x,t.y),l.globalAlpha=1,l.restore()}function vo(n,t=.1,e=W,s=!1,i=b(),o=0,r=G,a=!1,c){if(f(de(n),"points must be an array"),f(R(t),"width must be a number"),f(J(e),"color is invalid"),f(L(i),"pos must be a vec2"),f(R(o),"angle must be a number"),f(!c||!r,"context only supported in canvas 2D mode"),r&&G){f(!!y,"WebGL is not enabled!");let l=b(1);a&&([i,l,o]=Gs(i,l,o)),Vr(n,e.rgbaInt(),t,i.x,i.y,l.x,l.y,o,s)}else++Ce,++_e,Ln(i,b(1),o,!1,l=>{l.strokeStyle=e.toString(),l.lineWidth=t,l.beginPath();for(let u=0;u0&&Vr(n,s.rgbaInt(),e,i.x,i.y,l.x,l.y,o)}else Ln(i,b(1),o,!1,l=>{l.fillStyle=t.toString(),l.beginPath();for(let u of n)l.lineTo(u.x,u.y);l.closePath(),l.fill(),e&&(l.strokeStyle=s.toString(),l.lineWidth=e,l.stroke())},a,c)}function cc(n,t=b(1),e=W,s=0,i=0,o=nt,r=G,a=!1,c){f(L(n),"pos must be a vec2"),f(L(t),"size must be a vec2"),f(J(e)&&J(o),"color is invalid"),f(R(s),"angle must be a number"),f(R(i),"lineWidth must be a number"),f(i>=0,"lineWidth must be a positive value or 0"),f(!c||!r,"context only supported in canvas 2D mode"),i=B(i,0,Q(t.x,t.y)),r&&G?ac(n,t,Os,e,i,o,s,r,a,c):Ln(n,b(1),s,!1,l=>{l.fillStyle=e.toString(),l.beginPath(),l.ellipse(0,0,t.x/2,t.y/2,0,0,9),l.fill(),i&&(l.strokeStyle=o.toString(),l.lineWidth=i,l.stroke())},a,c)}function oi(n,t=1,e=W,s=0,i=nt,o=G,r=!1,a){f(R(t),"size must be a number"),cc(n,b(t),e,0,s,i,o,r,a)}function lc(n,t=b(1),e=W,s=ln,i=0,o=G,r=!1,a){if(f(L(n),"pos must be a vec2"),f(L(t),"size must be a vec2"),f(J(e)&&J(s),"color is invalid"),f(R(i),"angle must be a number"),f(!a||!o,"context only supported in canvas 2D mode"),!N)if(o&&G){f(!!y,"WebGL is not enabled!"),r&&(n=ks(n),t=t.scale(1/H),i+=K);let c=Os,l=t.x/2,u=t.y/2,h=e.rgbaInt(),p=s.rgbaInt(),d=rh++,g=at(-i),x=et(-i),v=E=>{let A=et(E)*l,T=at(E)*u;return b(n.x+A*g-T*x,n.y+A*x+T*g)},w=d%c/c*X*2,_=[v(w)],S=[p];for(let E=c;E--;){let A=(E+d)%c/c*X*2;_.push(n),S.push(h),_.push(v(A)),S.push(p)}Wr(_,S)}else++Ce,++_e,Ln(n,t,i,!1,c=>{let l=c.createRadialGradient(0,0,0,0,0,.5);l.addColorStop(0,e.toString()),l.addColorStop(1,s.toString()),c.fillStyle=l,c.beginPath(),c.ellipse(0,0,.5,.5,0,0,9),c.fill()},r,a)}function ah(n,t=1,e=W,s=ln,i=G,o=!1,r){f(R(t),"size must be a number"),lc(n,b(t),e,s,0,i,o,r)}function Ln(n,t,e=0,s=!1,i,o=!1,r=Ct){f(L(n),"pos must be a vec2"),f(L(t),"size must be a vec2"),f(R(e),"angle must be a number"),f(typeof i=="function","drawFunction must be a function"),o||(n=On(n),t=t.scale(H),e-=K),r.save(),r.translate(n.x+.5,n.y+.5),r.rotate(e),r.scale(s?-t.x:t.x,-t.y),i(r),r.restore()}function ch(n,t,e=1,s=W,i=0,o=nt,r="center",a=Ls,c="",l,u=0,h=Ct){t=On(t),e*=H,i*=H,u-=K,u*=-1,rn(n,t,e,s,i,o,r,a,c,l,u,h)}function rn(n,t,e,s=W,i=0,o=nt,r="center",a=Ls,c="",l,u=0,h=Ct){f(V(n),"text must be a string"),f(L(t),"pos must be a vec2"),f(R(e),"size must be a number"),f(J(s),"color must be a color"),f(R(i),"lineWidth must be a number"),f(J(o),"lineColor must be a color"),f(["left","center","right"].includes(r),"align must be left, center, or right"),f(V(a),"font must be a string"),f(V(c),"fontStyle must be a string"),f(R(u),"angle must be a number");let p=(n+"").split(`
-`),d=t.y-(p.length-1)*e/2;h.save(),h.fillStyle=s.toString(),h.strokeStyle=o.toString(),h.lineWidth=i,h.textAlign=r,h.font=c+" "+e+"px "+a,h.textBaseline="middle",h.translate(t.x,d),h.rotate(-u);let g=0;p.forEach(x=>{i&&h.strokeText(x,0,g,l),h.fillText(x,0,g,l),g+=e}),h.restore()}async function Ea(n,t){f(R(n),"textureIndex must be a number"),f(!hn[n],"textureIndex is already loaded!"),f(!t||V(t),"image src must be a string");let e=new Image;t&&await new Promise(s=>{e.onerror=e.onload=s,e.crossOrigin="anonymous",e.src=t}),hn[n]=new Je(e)}function ks(n){f(L(n),"screenPos must be a vec2");let t=(n.x-I.x/2+.5)/H,e=(n.y-I.y/2+.5)/-H;if(K){let s=at(-K),i=et(-K),o=t*s-e*i,r=t*i+e*s;t=o,e=r}return new rt(t+Et.x,e+Et.y)}function On(n){f(L(n),"worldPos must be a vec2");let t=n.x-Et.x,e=n.y-Et.y;if(K){let s=at(K),i=et(K),o=t*s-e*i,r=t*i+e*s;t=o,e=r}return new rt(t*H+I.x/2-.5,e*-H+I.y/2-.5)}function uc(n){f(L(n),"screenDelta must be a vec2");let t=n.x/H,e=n.y/-H;if(K){let s=at(-K),i=et(-K),o=t*s-e*i,r=t*i+e*s;t=o,e=r}return new rt(t,e)}function lh(n){f(L(n),"worldDelta must be a vec2");let t=n.x,e=n.y;if(K){let s=at(K),i=et(K),o=t*s-e*i,r=t*i+e*s;t=o,e=r}return new rt(t*H,e*-H)}function Gs(n,t,e=0){return f(L(n),"screenPos must be a vec2"),f(L(t),"screenSize must be a vec2"),f(R(e),"screenAngle must be a number"),[ks(n),t.scale(1/H),e+K]}function hc(){return I.scale(1/H)}function uh(n,t,e,s){f(L(n),"center must be a vec2"),f(L(t),"size must be a vec2");let i=p(e),o=p(s),r=t.x+i.left+i.right,a=t.y+i.top+i.bottom,c=I.x-o.left-o.right,l=I.y-o.top-o.bottom;if(!(r>0&&a>0&&c>0&&l>0))return H;H=Q(c/r,l/a);let u=b(i.right-i.left,i.top-i.bottom).scale(.5),h=b(o.right-o.left,o.top-o.bottom).scale(.5/H);return Et=n.add(u).add(h),H;function p(d){return(d===void 0||R(d))&&(d=b(d)),L(d)?{top:d.y,right:d.x,bottom:d.y,left:d.x}:{top:d.top||0,right:d.right||0,bottom:d.bottom||0,left:d.left||0}}}function hh(n,t=0){if(f(L(n),"pos must be a vec2"),f(L(t)||R(t),"size must be a vec2 or number"),!H)return!1;let e=n.x-Et.x,s=n.y-Et.y;if(K){let r=at(K),a=et(K),c=e*r-s*a,l=e*a+s*r;e=c,s=l}e*=H*2,s*=-H*2,t instanceof rt&&(t=t.length()),t*=H;let i=I.x,o=I.y;return e+t>-i&&e-t-o&&s-t{n.onerror=n.onload=a,n.crossOrigin="anonymous",n.src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUAAAAAeAQMAAABnrVXaAAAABlBMVEUAAAD///+l2Z/dAAAAAXRSTlMAQObYZgAAAjpJREFUOMu9kzFu2zAUhn+CAROgqrk+B2l0BWYxMjlXeYaAtFtbdA1sGgHqRQfI0CNkSG5AwYB0BQ8d5Bsomwah6CPVeGg6tEPzAxLwyI+P78cP4u9lNO9OoMKnLMOobG5020/yaj/MrRcCGh1gBbyiLTPJEYaIiom5KM9Jq7KgynMGtb6L4GL4MF2H4LQKCXTvDVw2I4MsgZT7QLExdiutH+D08VOP3INXRrWX1/mmpbkNgAPYRVANb4xpcegYvhiNbIXauQICEjBuYLfMakaakWQeXxiZ0VDtuJCKs3ztMV59QtsHJNcRxDzfdL21ty3PrfIcXTN+E+GFAv6T5nbT9jd50/WFxb5ksdAv49qS6ouymG66ji08UMT6moykYLAo+V0j23GN4m829ZySAD5K7QsBfQTvOG8eE+gTeGYRAmnNAubN3hf5Zv9tJWDHp/VTuaSm7SN4fyINQqaNO3RMVxvpSPXnOChnRNvFcGY0gnwiPswYwTKVPE0zVtX3mTEIOoFzaqLrGuJaV+Uqumb71fVk/VoOH3cdLNQP/FHi8hV0CQNoqBZsUPlLPMsdCJro9QAaQQ0woDy9BJm0eTxCFnO9srcYlhNVlfR2EyTrph1uUtbUtAJifwRgrKuYdXVHeb0YI3QpawohQHkloI3J5FuVwI5ORxC9k2Tuz9Ir1IjgeIPGMHYkAZe2RuYkmWFmt3gGbTPOmBUWVTmRmHtGrfpzG/yuQNOKa6gBB/WA9khitPgl6/GP+gl2Af6tCbvaygAAAABJRU5ErkJggg=="});let t=b(),e=b(8),s=1,i=0,o=new Je(n),r=new Ee(t,e,o,s,i);fc=new ri(r)}function mh(n=!0){jn=n}function bh(n){Rr=n}function xh(){return en==="mouse"}function vh(){return en==="keyboard"}function Sh(){return en==="gamepad"}function Pr(n,t=0,e=!0,s=!0,i=!0){Y[t]&&(Y[t][n]&=~((e?1:0)|(s?2:0)|(i?4:0)))}function Fs(){Y.length=0,Y[0]=[],oe.length=0,_n.length=0,js.length=0,xe.length=0,gn.length=0}function Lt(n,t=0){var e;return f(V(n),"key must be a number or string"),f(t>0||typeof n!="number"||n<3,"use code string for keyboard"),!!(((e=Y[t])==null?void 0:e[n])&1)}function It(n,t=0){var e;return f(V(n),"key must be a number or string"),f(t>0||typeof n!="number"||n<3,"use code string for keyboard"),!!(((e=Y[t])==null?void 0:e[n])&2)}function Lr(n,t=0){var e;return f(V(n),"key must be a number or string"),f(t>0||typeof n!="number"||n<3,"use code string for keyboard"),!!(((e=Y[t])==null?void 0:e[n])&4)}function wh(n="ArrowUp",t="ArrowDown",e="ArrowLeft",s="ArrowRight"){f(V(n),"up key must be a string"),f(V(t),"down key must be a string"),f(V(e),"left key must be a string"),f(V(s),"right key must be a string");let i=o=>Lt(o)?1:0;return b(i(s)-i(e),i(n)-i(t))}function us(n){return f(R(n),"mouse button must be a number"),Lt(n)}function gs(n){return f(R(n),"mouse button must be a number"),It(n)}function Th(n){return f(R(n),"mouse button must be a number"),Lr(n)}function Oe(n,t=mt){return f(R(n),"button must be a number"),f(R(t),"gamepad must be a number"),Lt(n,t+1)}function Or(n,t=mt){return f(R(n),"button must be a number"),f(R(t),"gamepad must be a number"),It(n,t+1)}function Ah(n,t=mt){return f(R(n),"button must be a number"),f(R(t),"gamepad must be a number"),Lr(n,t+1)}function ms(n,t=mt){var e,s;return f(R(n),"stick must be a number"),f(R(t),"gamepad must be a number"),(s=(e=xe[t])==null?void 0:e[n])!=null?s:b()}function So(n=mt){var t;return f(R(n),"gamepad must be a number"),(t=gn[n])!=null?t:b()}function wo(n=mt){return f(R(n),"gamepad must be a number"),!!Y[n+1]}function pc(n=mt){var t,e;return f(R(n),"gamepad must be a number"),(e=(t=xe[n])==null?void 0:t.length)!=null?e:0}function Ch(n=mt,t=200,e=1,s=1,i=0){var r,a,c;if(f(R(n),"gamepad must be a number"),!Ms||N)return;let o=(r=navigator==null?void 0:navigator.getGamepads)==null?void 0:r.call(navigator)[n];(c=(a=o==null?void 0:o.vibrationActuator)==null?void 0:a.playEffect)==null||c.call(a,"dual-rumble",{duration:t,strongMagnitude:e,weakMagnitude:s,startDelay:i})}function _h(n=mt){var e,s,i;if(f(R(n),"gamepad must be a number"),!Ms||N)return;let t=(e=navigator==null?void 0:navigator.getGamepads)==null?void 0:e.call(navigator)[n];(i=(s=t==null?void 0:t.vibrationActuator)==null?void 0:s.reset)==null||i.call(s)}function Dr(n=100){var t;f(R(n)||de(n),"pattern must be a number or array"),Ms&&!N&&((t=navigator==null?void 0:navigator.vibrate)==null||t.call(navigator,n))}function Eh(){Dr(0)}function Rh(){var n;!ie&&((n=j.requestPointerLock)==null||n.call(j))}function Ph(){var n;(n=document.exitPointerLock)==null||n.call(document)}function yc(){return document.pointerLockElement===j}function Lh(){if(N)return;document.addEventListener("keydown",n),document.addEventListener("keyup",t),document.addEventListener("mousedown",s),document.addEventListener("mouseup",i),document.addEventListener("mousemove",o),document.addEventListener("mouseleave",r),document.addEventListener("wheel",a,{passive:!1}),document.addEventListener("contextmenu",c),document.addEventListener("blur",l),ie&&bn&&u();function n(p){if(p.repeat||(Y[0][p.code]=3,cs&&(Y[0][e(p.code)]=3)),!jn||!p.cancelable||!document.hasFocus()||p.ctrlKey||p.metaKey||p.altKey||x(p.target)||x(document.activeElement))return;let d=typeof p.key=="string"&&p.key.length===1;(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight","Space","Tab","Backspace"].includes(p.code)||d)&&p.preventDefault();function x(v){let w=v==null?void 0:v.tagName;return(v==null?void 0:v.isContentEditable)||["INPUT","TEXTAREA","SELECT"].includes(w)}}function t(p){Y[0][p.code]=Y[0][p.code]&2|4,cs&&(Y[0][e(p.code)]=4)}function e(p){return cs?p==="KeyW"?"ArrowUp":p==="KeyS"?"ArrowDown":p==="KeyA"?"ArrowLeft":p==="KeyD"?"ArrowRight":p:p}function s(p){if(ie&&bn)return;Xt&&!N&&ft&&!xs()&&ft.resume(),Y[0][p.button]=3;let d=Ut;Ut=h(b(p.x,p.y)),be=be.add(Ut.subtract(d)),jn&&p.cancelable&&document.hasFocus()&&p.preventDefault()}function i(p){ie&&bn||(Y[0][p.button]=Y[0][p.button]&2|4)}function o(p){ai=!0;let d=Ut;Ut=h(b(p.x,p.y));let g=yc()?b(p.movementX,p.movementY):Ut.subtract(d);be=be.add(g)}function r(){ai=!1}function a(p){p.ctrlKey||(Er+=ne(p.deltaY)),jn&&p.cancelable&&document.hasFocus()&&p.preventDefault()}function c(p){p.preventDefault()}function l(){Fs(),Fe.clear(),oe.length=0,_n.length=0,js.length=0}function u(){document.addEventListener("touchstart",g=>d(g),{passive:!1}),document.addEventListener("touchmove",g=>d(g),{passive:!1}),document.addEventListener("touchend",g=>d(g),{passive:!1});let p;function d(g){if(bn){if(Xt&&!N&&ft&&!xs()&&ft.resume(),!un||vr){let x=S=>bs.includes(S.target)||S.target===mn,v=[];for(let S of g.touches)x(S)||v.push(S);let w=v.length,_=0;if(w){let S=b(v[0].clientX,v[0].clientY),E=Ut;Ut=h(S),p?be=be.add(Ut.subtract(E)):Y[0][_]=3}else p&&(Y[0][_]=Y[0][_]&2|4);p=w}return jn&&g.cancelable&&document.hasFocus()&&g.preventDefault(),!0}}}function h(p){let d=j.getBoundingClientRect(),g=Ft(p.x,d.left,d.right),x=Ft(p.y,d.top,d.bottom);return b(g*j.width,x*j.height)}}function Pa(){if(N)return;!(bn&&ie)&&!document.hasFocus()&&Fs(),Le=ks(Ut),_r=uc(be),Dh(),t(),n();function n(){let e=us(0)||us(1)||us(2)||be.length()>Rr,s=!1;for(let o=pc();o--&&!s;)s=ms(o).lengthSquared()>.04;for(let o=17;o--&&!s;)s=Oe(o);let i=!1;for(let o in Y[0])if(isNaN(+o)&&Y[0][o]&1){i=!0;break}s?en="gamepad":e?en="mouse":i&&(en="keyboard"),Nn=en==="gamepad"}function t(){var r,a,c,l,u,h,p;let e=d=>{let v=w=>w>.3?Ft(w,.3,.8):w<-.3?-Ft(-w,.3,.8):0;return b(v(d.x),v(-d.y)).clampLength()};if(un&&ie){if(f(!Pn||!Kn,"set touchGamepadLeftStick or touchGamepadLeftButtonCount, not both"),f(!Qn||!$n,"set touchGamepadRightStick or touchGamepadButtonCount, not both"),!Wn.isSet())return;mt=0;let d=(r=xe[0])!=null?r:xe[0]=[],g=(a=gn[0])!=null?a:gn[0]=b();d.length=0,g.set();for(let v=0;v<2;v++){if(!Ue(v))continue;let w=kr(v);d[w]=b();let _=(c=_n[v])!=null?c:b();if(Ds)d[w]=e(_);else if(_.lengthSquared()>.3){let S=B(Qs(_.x),-1,1),E=B(Qs(_.y),-1,1);d[w]=b(S,-E).clampLength(),w||g.set(S,-E)}}let x=(l=Y[1])!=null?l:Y[1]=[];for(let v=12;v--;){let w=Oe(v,0);x[v]=oe[v]?w?1:3:w?4:0,ni&&x[v]===3&&(v===9||Mh(v))&&Dr(ni)}return}try{if(!Gi||!(navigator!=null&&navigator.getGamepads))return}catch{return}if(!Gt&&!document.hasFocus())return;let s=8,i=navigator.getGamepads(),o=Q(s,i.length);for(let d=0;d>1]=e(b(g.axes[S],g.axes[S+1]));let _=!1;for(let S=g.buttons.length;S--;){let E=g.buttons[S],A=Oe(S,d);x[S]=E.pressed?A?1:3:A?4:0,E.pressed&&(!E.value||E.value>.9)&&(_=!0)}_&&(ho[d]=!0,ho[mt]||(mt=d)),g.mapping==="standard"&&w.set((Oe(15,d)&&1)-(Oe(14,d)&&1),(Oe(12,d)&&1)-(Oe(13,d)&&1)),xr&&(w.x||w.y)&&(v[0]=w.clampLength())}un&&Nn&&Wn.unset()}}function La(){if(!N){for(let n of Y)for(let t in n)n[t]&=1;Er=0,_r=b(),be=b()}}function Oh(){Fh()}function Dh(){if(Qe||!un||!ie||N||!document.body)return;let n=Qe=document.createElement("div");n.style.cssText="position:fixed;inset:0;z-index:50;pointer-events:none;opacity:0;touch-action:none;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;transition:opacity .2s;box-sizing:border-box;padding:env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left)";let t=gc=document.createElement("div");t.style.cssText="position:relative;width:100%;height:100%;pointer-events:none",n.appendChild(t);let e=Mr=document.createElementNS(li,"svg");e.style.cssText="position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible;fill:none;stroke:#fff;stroke-width:3",t.appendChild(e);let s=()=>{let i=document.createElement("div");return i.style.cssText="position:absolute;pointer-events:auto;touch-action:none",i.addEventListener("pointerdown",o=>zh(o,i)),i.addEventListener("pointermove",o=>Jh(o)),i.addEventListener("pointerup",o=>Oa(o)),i.addEventListener("pointercancel",o=>Oa(o)),t.appendChild(i),i};bs[0]=s(),bs[1]=s(),mn=s(),addEventListener("resize",()=>qn=!0),document.body.appendChild(n),qn=!0}function Fi(){return gc.getBoundingClientRect()}function Ue(n){return n?Qn:Pn}function Dn(n){return n?$n:Kn}function Ir(n){return n?0:4}function kr(n){return n&&Pn?1:0}function Hn(n){return Ue(n)||Dn(n)>0}function Mh(n){for(let t=0;t<2;t++){let e=Ir(t);if(!Ue(t)&&n>=e&&no.style.cssText="position:absolute;pointer-events:auto;touch-action:none;"+r;if(Te){for(let o of bs)o.style.display="none";fe?(i(mn,"inset:0"),mn.style.display=""):mn.style.display="none"}else{for(let r=0;r<2;r++){let a=bs[r],c=r?"right":"left";if(a.style.display=Hn(r)?"":"none",dn){let l=Hn(r?0:1)?"50%":"100%";i(a,`${c}:0;bottom:0;width:${l};height:60%`)}else i(a,`${c}:0;bottom:0;width:${3*s}px;height:${3*s}px`)}mn.style.display=fe?"":"none";let o=fe;i(mn,`left:50%;top:50%;width:${2*o}px;height:${2*o}px;transform:translate(-50%,-50%)`)}kh(t,e),qn=!1}function kh(n,t){let e=Mr;for(;e.firstChild;)e.removeChild(e.firstChild);let s=mc={face:[],thumb:[]},i=Ht,o=(a,c,l,u)=>{let h=document.createElementNS(li,"circle");return h.setAttribute("cx",a),h.setAttribute("cy",c),h.setAttribute("r",l),u&&h.setAttribute("fill",u),e.appendChild(h),h},r=a=>{let c=i*.18,l=i*.5,u=a.x,h=a.y,p=document.createElementNS(li,"path");p.setAttribute("d",`M ${u-c} ${h-l} H ${u+c} V ${h-c} H ${u+l} V ${h+c} H ${u+c} V ${h+l} H ${u-c} V ${h+c} H ${u-l} V ${h-c} H ${u-c} Z`),e.appendChild(p)};for(let a=0;a<2;a++){let c=Dn(a),l=Ir(a),u=Be(a,n,t);if(Ue(a))Ds?o(u.x,u.y,i/2):r(u),s.thumb[a]=o(u.x,u.y,i/4,"#fff");else if(c===1)s.face[l]=o(u.x,u.y,i/2,"#000");else for(let h=0;h2?p:Q(p,c-1);d=d===3?2:d===2?3:d;let g=b().setDirection(p,i/2);c===2&&(g.x*=-1),a||(g.x*=-1);let x=u.add(g);s.face[l+d]=o(x.x,x.y,i/4,"#000")}}Gt&&wn&&Gh(n,t)}function Gh(n,t){let e=Ht,s=Mr,i=(r,a,c)=>{let l=document.createElementNS(li,r);for(let u in a)l.setAttribute(u,a[u]);l.setAttribute("stroke",c),l.setAttribute("stroke-width",2),l.setAttribute("fill","none"),s.appendChild(l)},o=(r,a,c)=>i("circle",{cx:r.x,cy:r.y,r:a},c);i("line",{x1:n/2,y1:0,x2:n/2,y2:t},"#0f0");for(let r=0;r<2;r++)if(Ue(r))if(dn){let a=t*.4,c=!Hn(r?0:1),l=c?0:r?n/2:0;i("rect",{x:l,y:a,width:c?n:n/2,height:t-a},"#0ff")}else o(Be(r,n,t),2*e,"#0ff");else Dn(r)>=1&&o(Be(r,n,t),e,"#0ff");if(fe){o(b(n/2,t/2),fe,"#ff0");for(let r=0;r<2;r++)Hn(r)&&o(Be(r,n,t),2*e,"#f0f")}}function Fh(){var l;if(!Qe||N)return;if(!un||!ie){Qe.style.display!=="none"&&(Qe.style.display="none",Fe.clear(),oe.length=0,_n.length=0,js.length=0);return}Qe.style.display="";let n=Gt&&wn,t=[$n,Kn,Pn,Qn,Ds,Ht,dn,fe,Te,n].join();t!==Ra&&(Ra=t,qn=!0),qn&&Ih();let e=ls?Ft(Wn.get(),ls+1,ls):1,s=n||Wn.isSet()&&e>0&&!Te;if(Qe.style.opacity=s?n?1:e*Sr:0,!s)return;let i=Fi(),o=i.width,r=i.height,a=Ht,c=mc;if(c){for(let u=0;u<2;u++)if(Ue(u)&&c.thumb[u]){let p=Be(u,o,r).add(((l=_n[u])!=null?l:b()).scale(a/2));c.thumb[u].setAttribute("cx",p.x),c.thumb[u].setAttribute("cy",p.y)}for(let u=0;u=Ht)return-1;if(i===1)return o;let a=r.subtract(t);n||(a.x*=-1);let c=i===2?a.xo:a&&Be(r,t,e).distance(n)<2*s)return{role:"stick",side:r}}else if(Dn(r)>=1){let c=Bh(r,n,t,e);if(c>=0)return{role:"face",btn:c}}}if(fe){for(let r=0;r<2;r++)if(Hn(r)&&Be(r,t,e).distance(n)<2*s)return;if(b(t/2,e/2).distance(n)h.getChannelData(v).set(x)),p.buffer=h,p.playbackRate.value=e,p.loop=i,r=r||ft.createGain(),r.gain.value=t,r.connect(Ne);let d=new StereoPannerNode(ft,{pan:B(s,-1,1)});p.connect(d).connect(r),p.addEventListener("ended",()=>{r.disconnect(),d.disconnect(),c&&c(p)});let g=a*e;return p.start(0,g),Gt&&Un&&vt("sound","vol",t.toFixed(2),"rate",e.toFixed(2),"pan",s.toFixed(2),i?"loop":""),p}function qh(...n){return Gr([ji(...n)])}function ji(n=1,t=.05,e=220,s=0,i=0,o=.1,r=0,a=1,c=0,l=0,u=0,h=0,p=0,d=0,g=0,x=0,v=0,w=1,_=0,S=0,E=0){let A=Zn,T=X*2,P=c*=500*T/A/A,k=e*=(1+dt(t,-t))*T/A,ct=0,st=0,it=0,gt=1,jt,Ve=[],Bt=0,ht=0,Dt=0,We,ye=2,M=T*tt(E)*2/A,F=at(M),xt=et(M)/2/ye,O=1+xt,U=-2*F/O,pt=(1-xt)/O,wt=(1+ne(E)*F)/2/O,ae=-(ne(E)+F)/O,qe=wt,fn=0,He=0,lt=0,ee=0;for(s=s*A||9,_*=A,i*=A,o*=A,v*=A,l*=500*T/A**3,g*=T/A,u*=T/A,h*=A,p=p*A|0,jt=s+_+i+o+v|0;ht1?r>2?r>3?r>4?Bt/T%14?Dt:ne(Dt)*tt(Dt)**a)*(htht?0:(hth&&(e+=u,k+=u,gt=0),p&&!(++st%p)&&(e=k,c=P,gt||(gt=1));return Ve}function hi(n,t=!0){for(let e of an)if((!t||e.isSolid)&&n.arrayCheck(e.size)){let s=e.getCollisionData(n);if(s)return s}return 0}function Ze(n,t=b(),e,s=!0){for(let i of an)if((!s||i.isSolid)&&i.collisionTest(n,t,e))return i}function vc(n,t,e,s,i=!0){let o,r,a,c=s&&b();for(let l of an)if(!i||l.isSolid){let u=l.collisionRaycast(n,t,e,c);if(u){let h=n.distanceSquared(u);(o===void 0||h{G=!1,Z.style.display="none",e.preventDefault(),vt("WebGL context lost! Switching to Canvas2d rendering.");for(let s of hs)s.glTexture=void 0;Zt=void 0,_t=0,En=!1,vn.forEach(s=>{var i;return(i=s.glContextLost)==null?void 0:i.call(s)})}),Z.addEventListener("webglcontextrestored",()=>{G=!0,Z.style.display="",vt("WebGL context restored, reinitializing..."),t();for(let e of hs)e.glTexture=Ni(e.image,e.wrap);vn.forEach(e=>{var s;return(s=e.glContextRestored)==null?void 0:s.call(e)})});function t(){pi=Yn(`#version 300 es
+`,o+=i.toString(),Ke(o,Nt,24,U(),.05,void 0,"center","monospace")}{e.save(),e.fillStyle="#fff",e.textAlign="left",e.textBaseline="top",e.font="20px monospace",e.shadowColor="#000",e.shadowBlur=9;let a=9,r=0,c=24;if(Re){e.fillText(`${Ji} v${Ui}`,a,r+=c/2),e.fillText("Time: "+ir($t),a,r+=c),e.fillText("FPS: "+Vi.toFixed(1)+(B?" WebGL":" Canvas2D"),a,r+=c),e.fillText("Objects: "+St.length,a,r+=c),e.fillText("Draw Calls: "+Te,a,r+=c),e.fillText("Primitives: "+Ae,a,r+=c),e.fillText("---------",a,r+=c),e.fillStyle="#f00",e.fillText("ESC: Debug Overlay",a,r+=c),e.fillStyle=ce?"#f00":"#fff",e.fillText("1: Debug Physics",a,r+=c),e.fillStyle=fn?"#f00":"#fff",e.fillText("2: Debug Particles",a,r+=c),e.fillStyle=pn?"#f00":"#fff",e.fillText("3: Debug Gamepads",a,r+=c),e.fillStyle=le?"#f00":"#fff",e.fillText("4: Debug Raycasts",a,r+=c),e.fillStyle="#fff",e.fillText("5: Save Screenshot",a,r+=c),e.fillText("6: Toggle Video Capture",a,r+=c),e.fillStyle=kn?"#f00":"#fff",e.fillText("7: Debug Sound",a,r+=c);let l="",u="";for(let h in $[0])Ot(h,0)&&(parseInt(h)<3?u+=h+" ":l+=h+" ");u&&e.fillText("Mouse: "+u,a,r+=c),l&&e.fillText("Keys: "+l,a,r+=c);for(let h=1;h<$.length;h++){let f="";if($[h])for(let d in $[h])Ot(d,h)&&(f+=d+" ");f&&e.fillText(`Gamepad ${h-1}: `+f,a,r+=c)}}else e.fillText(ce?"Debug Physics":"",a,r+=c),e.fillText(fn?"Debug Particles":"",a,r+=c),e.fillText(le?"Debug Raycasts":"",a,r+=c),e.fillText(pn?"Debug Gamepads":"",a,r+=c),e.fillText(kn?"Debug Sound":"",a,r+=c);e.restore()}if(Ts||Re){lt.textAlign="right",lt.textBaseline="top",lt.font="1em monospace",lt.fillStyle="#000";let s=Ji+" v"+Ui+" / "+n+" / "+t+" / "+St.length+" / "+Vi.toFixed(1)+(B?" GL":" 2D");lt.fillText(s,N.width-3,3),lt.fillStyle="#fff",lt.fillText(s,N.width-2,2)}}function jl(){if(ve()){Bl();return}}function ve(){return!!Pe}function ka(){p(!ve(),"Already capturing video!"),ae||(ae=document.createElement("div"),ae.style.position="absolute",ae.style.padding="9px",ae.style.color="#f00",ae.style.font="50px monospace",document.body.appendChild(ae)),ae.textContent="",ae.style.display="";let n=N.captureStream(0),t=n.getVideoTracks()[0],e=new we(0,!0),i=[];t.applyConstraints({frameRate:60});let s=new MediaRecorder(n,{mimeType:"video/webm;codecs=vp8"});s.ondataavailable=r=>i.push(r.data),s.onstop=()=>{let r=new Blob(i,{type:"video/webm"}),c=URL.createObjectURL(r);ri(c,"capture.webm",1e3)};let o,a;if(Wt){a=new ConstantSourceNode(dt,{offset:0}),a.connect(Ge),a.start(),o=dt.createMediaStreamDestination(),Ge.connect(o);for(let r of o.stream.getAudioTracks())n.addTrack(r)}try{s.start()}catch{vt("Video capture not supported in this browser!"),a==null||a.stop();return}vt("Video capture started."),Pe={mediaRecorder:s,captureTimer:e,videoTrack:t,silentAudioSource:a,audioStreamDestination:o}}function Ga(){var n,t,e;p(ve(),"Not capturing video!"),vt(`Video capture ended. ${Pe.captureTimer.get().toFixed(2)} seconds recorded.`),ae.style.display="none",(n=Pe.silentAudioSource)==null||n.stop(),(t=Pe.mediaRecorder)==null||t.stop(),(e=Pe.videoTrack)==null||e.stop(),Pe=void 0}function Bl(){p(ve(),"Not capturing video!"),br(),Pe.videoTrack.requestFrame(),ae.textContent="\u25CF REC "+ir(Pe.captureTimer)}function Qt(n){if(Ft){let t=Object.keys(n),e={};t.forEach(i=>e[i]=n[i]),t.forEach(i=>{Object.defineProperty(n,i,{get:()=>e[i],set:s=>{p(!1,`Cannot modify engine constant. Attempted to set constant (${n}) property '${i}' to '${s}'.`)},enumerable:!0})})}return Object.freeze(n)}function ee(n,t=1){return(n%t+t)%t}function z(n,t=0,e=1){return ne?e:n}function jt(n,t,e){return(e-=t)?z((n-t)/e):0}function Ut(n,t,e){return n+z(e)*(t-n)}function Nl(n,t,e,i,s){return Ut(i,s,jt(n,t,e))}function tr(n,t,e=1){p(e>0,"distanceWrap wrapSize must be > 0");let i=(n-t)%e;return i*2%e-i}function Na(n,t,e,i=1){return n+z(e)*tr(t,n,i)}function zl(n,t){return tr(n,t,2*Y)}function Jl(n,t,e){return Na(n,t,e,2*Y)}function qi(n){return n*n*(3-2*n)}function oi(n){return!(n&n-1)}function Ul(n){return 2**si(ja(n))}function Hi(n,t,e,i=b()){let s=(n.x-e.x)*2,o=(n.y-e.y)*2,a=t.x+i.x,r=t.y+i.y;return nt(s)f)return!1;h=K(y,h)}else{if(y0?r.x+1:r.x,x=h>0?r.y+1:r.y,v=c?(y-n.x)/c:1/0,w=l?(x-n.y)/l:1/0,C=0,S=v,_=w,A=fr.x&&(T.x=r.x+1-L),F.yr.y&&(T.y=r.y+1-L),i&&(A?i.set(-u,0):i.set(0,-h)),T}(A=S<_)?(r.x+=u,C=S,S+=f):(r.y+=h,C=_,_+=d)}}function ht(n=1,t=0){return t+Math.random()*(n-t)}function er(n,t=0){return wt(ht(n,t))}function Va(n=.5){return ht()URL.revokeObjectURL(n),e)}function $l(n,t,e){var i;p(W(n),"shareURL requires title string"),p(W(t),"shareURL requires url string"),(i=navigator.share)==null||i.call(navigator,{title:n,url:t}).then(()=>e==null?void 0:e())}function Kl(n,t){p(W(n),"loadData requires saveName string");let e={};try{let i=localStorage[n];if(i)try{e=JSON.parse(i)}catch{vt("readSaveData: corrupt JSON for",n,"\u2014 using defaults")}}catch{vt("readSaveData: localStorage unavailable \u2014 using defaults")}return{...t,...e}}function Ql(n,t){p(W(n),"saveData requires saveName string");try{localStorage[n]=JSON.stringify(t)}catch{vt("writeSaveData: failed to write",n)}}function ho(n){let t=(n|0)^2654435769;return t=Math.imul(t^t>>>16,2246822507),t=Math.imul(t^t>>>13,3266489909),t^=t>>>16,(t>>>0)/2**32}function Zl(n){let t=wt(n);return Ut(ho(t),ho(t+1),qi(n-t))}function tu(n,t){let e=wt(n),i=wt(t),s=qi(n-e),o=qi(t-i),a=(r,c)=>ho(r+c*374761393);return Ut(Ut(a(e,i),a(e+1,i),s),Ut(a(e,i+1),a(e+1,i+1),s),o)}function eu(n){Ct=n.copy()}function nu(n){Q=n}function iu(n){X=n}function su(n){sr=n}function ou(n){As=n}function ru(n){Ye=n.copy()}function au(n){Cn=n.copy()}function cu(n){Zn=n}function lu(n){Rn=n}function uu(n){Pn=n.copy()}function Za(n){or=n,N&&(N.style.imageRendering=n?"pixelated":""),et&&(et.style.imageRendering=n?"pixelated":"")}function hu(n){mn=n}function du(n){$e=n}function fu(n){wi=n}function pu(n){rr=n}function gu(n){J=n}function yu(n){if(n&&!vo){console.warn("Can not enable WebGL if it was disabled on start.");return}B=n,et&&(et.style.display=n?"":"none")}function mu(n){Ti=n}function bu(n){Es=n.copy()}function xu(n){_s=n}function vu(n){Cs=n}function Su(n){Rs=n}function wu(n){ar=n}function Tu(n){cr=n}function Au(n){lr=n}function Eu(n){ur=n}function _u(n){hr=n}function Cu(n){Oe=n}function Ru(n){Jt=n.copy()}function Pu(n){Xi=n}function Lu(n){Ps=n}function Ou(n){dr=n}function Du(n){ti=n}function Mu(n){un=n}function Iu(n){en=n}function ku(n){fr=n}function Gu(n){he=n}function Fu(n){Jn=n,n>0&&(Vn=!1)}function ju(n){Sn=n,n&&(Un=0)}function Bu(n){Un=n,n>0&&(Sn=!1)}function Nu(n){Vn=n,n&&(Jn=0)}function zu(n){Ai=n}function Ju(n){sn=n}function Uu(n){Vt=n}function Vu(n){pr=n}function Wu(n){ei=n}function qu(n){Yi=n}function Hu(n){Ei=n}function Xu(n){Wt=n}function Yu(n){gn=n,Wt&&!J&&Ge&&(Ge.gain.value=n)}function $u(n){gr=n}function Ku(n){yr=n}function Qu(n){Ts=n}function Zu(n){Ma=n}function $i(n){return n.r>=1&&n.g>=1&&n.b>=1}function mr(n){return n.r<=0&&n.g<=0&&n.b<=0&&n.a<=0}function _i(n=0,t=Es,e=0,i=_s,s=Cs){if(p(O(n)||typeof n=="number","index must be a vec2 or number"),p(O(t)||typeof t=="number","size must be a vec2 or number"),p(P(e)||e instanceof je,"texture must be a number or TextureInfo"),p(P(i),"padding must be a number"),J)return new Ee;typeof t=="number"&&(p(t>0),t=new rt(t,t));let o=typeof e=="number"?nn[e]:e;p(o instanceof je,"tile texture is not loaded"),p(o.size.x>0,"tile texture is not loaded");let a=t.x+i*2,r=t.y+i*2,c,l;if(typeof n=="number"){let h=o.size.x/a|0;c=n%h,l=n/h|0}else c=n.x,l=n.y;let u=new rt(c*a+i,l*r+i);return new Ee(u,t,o,i,s)}function Dt(n,t=b(1),e,i=q,s=0,o,a,r=B,c=!1,l){var f;p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(V(i),"color is invalid"),p(P(s),"angle must be a number"),p(!a||V(a),"additiveColor must be a color"),p(!l||!r,"context only supported in canvas 2D mode");let u=e==null?void 0:e.textureInfo,h=(f=e==null?void 0:e.bleed)!=null?f:0;if(r&&B)if(p(!!g,"WebGL is not enabled!"),c&&([n,t,s]=Ri(n,t,s)),u){let d=u.sizeInverse,y=e.pos.x*d.x,x=e.pos.y*d.y,v=e.size.x*d.x,w=e.size.y*d.y;if(Mr(u.glTexture),h){let C=d.x*h,S=d.y*h;mi(n.x,n.y,o?-t.x:t.x,t.y,s,y+C,x+S,y-C+v,x-S+w,i.rgbaInt(),a&&a.rgbaInt())}else mi(n.x,n.y,o?-t.x:t.x,t.y,s,y,x,y+v,x+w,i.rgbaInt(),a&&a.rgbaInt())}else{let d=a?i.add(a):i;vc(n.x,n.y,t.x,t.y,s,d.rgbaInt())}else++Te,++Ae,wn(n,t,s,o,d=>{if(u){d.scale(1,-1);let y=e.pos.x,x=e.pos.y,v=e.size.x,w=e.size.y;lh(d,u.image,y,x,v,w,-.5,-.5,1,1,i,a,h)}else{let y=a?i.add(a):i;d.fillStyle=y.toString(),d.fillRect(-.5,-.5,1,1)}},c,l)}function Ki(n,t,e,i,s,o,a){Dt(n,t,void 0,e,i,!1,void 0,s,o,a)}function th(n,t,e=q,i=tn,s=0,o=B,a=!1,r){if(p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(V(e)&&V(i),"color is invalid"),p(P(s),"angle must be a number"),p(!r||!o,"context only supported in canvas 2D mode"),o&&B){p(!!g,"WebGL is not enabled!"),a&&(n=Ci(n),t=t.scale(1/X),s+=Q);let c=[],l=[],u=t.x/2,h=t.y/2,f=e.rgbaInt(),d=i.rgbaInt(),y=at(-s),x=it(-s);for(let v=4;v--;){let w=v&1?u:-u,C=v&2?h:-h,S=w*y-C*x,_=w*x+C*y,A=v&2?f:d;c.push(b(n.x+S,n.y+_)),l.push(A)}jr(c,l)}else++Te,++Ae,wn(n,t,s,!1,c=>{let l=c.createLinearGradient(0,.5,0,-.5);l.addColorStop(0,e.toString()),l.addColorStop(1,i.toString()),c.fillStyle=l,c.fillRect(-.5,-.5,1,1)},a,r)}function eh(n,t,e,i=0,s=q,o=0,a,r=B,c=!1,l){if(p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(O(e),"wrapCount must be a vec2"),p(V(s),"color is invalid"),p(P(o),"angle must be a number"),p(!a||V(a),"additiveColor must be a color"),p(!l||!r,"context only supported in canvas 2D mode"),p(!(i instanceof Ee),"pass a TextureInfo or texture index, not a TileInfo \u2014 use tileInfo.textureInfo"),J)return;let u=typeof i=="number"?nn[i]:i;if(p(u instanceof je,"texture not loaded"),p(u.size.x>0,"texture not loaded"),p(u.wrap,"drawTextureWrapped requires a wrap-enabled texture; call textureInfo.setWrap(true) first"),r&&B){p(!!g,"WebGL is not enabled!"),c&&([n,t,o]=Ri(n,t,o)),Mr(u.glTexture),mi(n.x,n.y,t.x,t.y,o,0,0,e.x,e.y,s.rgbaInt(),a&&a.rgbaInt());return}++Te,++Ae,c||(n=Tn(n),t=t.scale(X),o-=Q);let h=!As||(a?$i(s.add(a))&&a.a<=0:$i(s)),f=!h&&a&&!mr(a),d=h?u.image:ch(u.image,s,a);l=l||Et,l.save(),l.translate(n.x+.5,n.y+.5),l.rotate(o),l.globalAlpha=f?1:s.a;let y=l.createPattern(d,"repeat"),x=new DOMMatrix().translate(-t.x/2,-t.y/2).scale(t.x/(e.x*d.width),t.y/(e.y*d.height));y.setTransform(x),l.fillStyle=y,l.fillRect(-t.x/2,-t.y/2,t.x,t.y),l.globalAlpha=1,l.restore()}function fo(n,t=.1,e=q,i=!1,s=b(),o=0,a=B,r=!1,c){if(p(ue(n),"points must be an array"),p(P(t),"width must be a number"),p(V(e),"color is invalid"),p(O(s),"pos must be a vec2"),p(P(o),"angle must be a number"),p(!c||!a,"context only supported in canvas 2D mode"),a&&B){p(!!g,"WebGL is not enabled!");let l=b(1);r&&([s,l,o]=Ri(s,l,o)),Fr(n,e.rgbaInt(),t,s.x,s.y,l.x,l.y,o,i)}else++Te,++Ae,wn(s,b(1),o,!1,l=>{l.strokeStyle=e.toString(),l.lineWidth=t,l.beginPath();for(let u=0;u0&&Fr(n,i.rgbaInt(),e,s.x,s.y,l.x,l.y,o)}else wn(s,b(1),o,!1,l=>{l.fillStyle=t.toString(),l.beginPath();for(let u of n)l.lineTo(u.x,u.y);l.closePath(),l.fill(),e&&(l.strokeStyle=i.toString(),l.lineWidth=e,l.stroke())},r,c)}function ec(n,t=b(1),e=q,i=0,s=0,o=st,a=B,r=!1,c){p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(V(e)&&V(o),"color is invalid"),p(P(i),"angle must be a number"),p(P(s),"lineWidth must be a number"),p(s>=0,"lineWidth must be a positive value or 0"),p(!c||!a,"context only supported in canvas 2D mode"),s=z(s,0,Z(t.x,t.y)),a&&B?tc(n,t,Ti,e,s,o,i,a,r,c):wn(n,b(1),i,!1,l=>{l.fillStyle=e.toString(),l.beginPath(),l.ellipse(0,0,t.x/2,t.y/2,0,0,9),l.fill(),s&&(l.strokeStyle=o.toString(),l.lineWidth=s,l.stroke())},r,c)}function Qi(n,t=1,e=q,i=0,s=st,o=B,a=!1,r){p(P(t),"size must be a number"),ec(n,b(t),e,0,i,s,o,a,r)}function nc(n,t=b(1),e=q,i=tn,s=0,o=B,a=!1,r){if(p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(V(e)&&V(i),"color is invalid"),p(P(s),"angle must be a number"),p(!r||!o,"context only supported in canvas 2D mode"),!J)if(o&&B){p(!!g,"WebGL is not enabled!"),a&&(n=Ci(n),t=t.scale(1/X),s+=Q);let c=Ti,l=t.x/2,u=t.y/2,h=e.rgbaInt(),f=i.rgbaInt(),d=nh++,y=at(-s),x=it(-s),v=_=>{let A=it(_)*l,T=at(_)*u;return b(n.x+A*y-T*x,n.y+A*x+T*y)},w=d%c/c*Y*2,C=[v(w)],S=[f];for(let _=c;_--;){let A=(_+d)%c/c*Y*2;C.push(n),S.push(h),C.push(v(A)),S.push(f)}jr(C,S)}else++Te,++Ae,wn(n,t,s,!1,c=>{let l=c.createRadialGradient(0,0,0,0,0,.5);l.addColorStop(0,e.toString()),l.addColorStop(1,i.toString()),c.fillStyle=l,c.beginPath(),c.ellipse(0,0,.5,.5,0,0,9),c.fill()},a,r)}function ih(n,t=1,e=q,i=tn,s=B,o=!1,a){p(P(t),"size must be a number"),nc(n,b(t),e,i,0,s,o,a)}function wn(n,t,e=0,i=!1,s,o=!1,a=Et){p(O(n),"pos must be a vec2"),p(O(t),"size must be a vec2"),p(P(e),"angle must be a number"),p(typeof s=="function","drawFunction must be a function"),o||(n=Tn(n),t=t.scale(X),e-=Q),a.save(),a.translate(n.x+.5,n.y+.5),a.rotate(e),a.scale(i?-t.x:t.x,-t.y),s(a),a.restore()}function sh(n,t,e=1,i=q,s=0,o=st,a="center",r=wi,c="",l,u=0,h=Et){t=Tn(t),e*=X,s*=X,u-=Q,u*=-1,Ke(n,t,e,i,s,o,a,r,c,l,u,h)}function Ke(n,t,e,i=q,s=0,o=st,a="center",r=wi,c="",l,u=0,h=Et){p(W(n),"text must be a string"),p(O(t),"pos must be a vec2"),p(P(e),"size must be a number"),p(V(i),"color must be a color"),p(P(s),"lineWidth must be a number"),p(V(o),"lineColor must be a color"),p(["left","center","right"].includes(a),"align must be left, center, or right"),p(W(r),"font must be a string"),p(W(c),"fontStyle must be a string"),p(P(u),"angle must be a number");let f=(n+"").split(`
+`),d=t.y-(f.length-1)*e/2;h.save(),h.fillStyle=i.toString(),h.strokeStyle=o.toString(),h.lineWidth=s,h.textAlign=a,h.font=c+" "+e+"px "+r,h.textBaseline="middle",h.translate(t.x,d),h.rotate(-u);let y=0;f.forEach(x=>{s&&h.strokeText(x,0,y,l),h.fillText(x,0,y,l),y+=e}),h.restore()}async function va(n,t){p(P(n),"textureIndex must be a number"),p(!nn[n],"textureIndex is already loaded!"),p(!t||W(t),"image src must be a string");let e=new Image;t&&await new Promise(i=>{e.onerror=e.onload=i,e.crossOrigin="anonymous",e.src=t}),nn[n]=new je(e)}function Ci(n){p(O(n),"screenPos must be a vec2");let t=(n.x-G.x/2+.5)/X,e=(n.y-G.y/2+.5)/-X;if(Q){let i=at(-Q),s=it(-Q),o=t*i-e*s,a=t*s+e*i;t=o,e=a}return new rt(t+Ct.x,e+Ct.y)}function Tn(n){p(O(n),"worldPos must be a vec2");let t=n.x-Ct.x,e=n.y-Ct.y;if(Q){let i=at(Q),s=it(Q),o=t*i-e*s,a=t*s+e*i;t=o,e=a}return new rt(t*X+G.x/2-.5,e*-X+G.y/2-.5)}function ic(n){p(O(n),"screenDelta must be a vec2");let t=n.x/X,e=n.y/-X;if(Q){let i=at(-Q),s=it(-Q),o=t*i-e*s,a=t*s+e*i;t=o,e=a}return new rt(t,e)}function oh(n){p(O(n),"worldDelta must be a vec2");let t=n.x,e=n.y;if(Q){let i=at(Q),s=it(Q),o=t*i-e*s,a=t*s+e*i;t=o,e=a}return new rt(t*X,e*-X)}function Ri(n,t,e=0){return p(O(n),"screenPos must be a vec2"),p(O(t),"screenSize must be a vec2"),p(P(e),"screenAngle must be a number"),[Ci(n),t.scale(1/X),e+Q]}function sc(){return G.scale(1/X)}function rh(n,t,e,i){p(O(n),"center must be a vec2"),p(O(t),"size must be a vec2");let s=f(e),o=f(i),a=t.x+s.left+s.right,r=t.y+s.top+s.bottom,c=G.x-o.left-o.right,l=G.y-o.top-o.bottom;if(!(a>0&&r>0&&c>0&&l>0))return X;X=Z(c/a,l/r);let u=b(s.right-s.left,s.top-s.bottom).scale(.5),h=b(o.right-o.left,o.top-o.bottom).scale(.5/X);return Ct=n.add(u).add(h),X;function f(d){return(d===void 0||P(d))&&(d=b(d)),O(d)?{top:d.y,right:d.x,bottom:d.y,left:d.x}:{top:d.top||0,right:d.right||0,bottom:d.bottom||0,left:d.left||0}}}function ah(n,t=0){if(p(O(n),"pos must be a vec2"),p(O(t)||P(t),"size must be a vec2 or number"),!X)return!1;let e=n.x-Ct.x,i=n.y-Ct.y;if(Q){let a=at(Q),r=it(Q),c=e*a-i*r,l=e*r+i*a;e=c,i=l}e*=X*2,i*=-X*2,t instanceof rt&&(t=t.length()),t*=X;let s=G.x,o=G.y;return e+t>-s&&e-t-o&&i-t{n.onerror=n.onload=r,n.crossOrigin="anonymous",n.src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUAAAAAeAQMAAABnrVXaAAAABlBMVEUAAAD///+l2Z/dAAAAAXRSTlMAQObYZgAAAjpJREFUOMu9kzFu2zAUhn+CAROgqrk+B2l0BWYxMjlXeYaAtFtbdA1sGgHqRQfI0CNkSG5AwYB0BQ8d5Bsomwah6CPVeGg6tEPzAxLwyI+P78cP4u9lNO9OoMKnLMOobG5020/yaj/MrRcCGh1gBbyiLTPJEYaIiom5KM9Jq7KgynMGtb6L4GL4MF2H4LQKCXTvDVw2I4MsgZT7QLExdiutH+D08VOP3INXRrWX1/mmpbkNgAPYRVANb4xpcegYvhiNbIXauQICEjBuYLfMakaakWQeXxiZ0VDtuJCKs3ztMV59QtsHJNcRxDzfdL21ty3PrfIcXTN+E+GFAv6T5nbT9jd50/WFxb5ksdAv49qS6ouymG66ji08UMT6moykYLAo+V0j23GN4m829ZySAD5K7QsBfQTvOG8eE+gTeGYRAmnNAubN3hf5Zv9tJWDHp/VTuaSm7SN4fyINQqaNO3RMVxvpSPXnOChnRNvFcGY0gnwiPswYwTKVPE0zVtX3mTEIOoFzaqLrGuJaV+Uqumb71fVk/VoOH3cdLNQP/FHi8hV0CQNoqBZsUPlLPMsdCJro9QAaQQ0woDy9BJm0eTxCFnO9srcYlhNVlfR2EyTrph1uUtbUtAJifwRgrKuYdXVHeb0YI3QpawohQHkloI3J5FuVwI5ORxC9k2Tuz9Ir1IjgeIPGMHYkAZe2RuYkmWFmt3gGbTPOmBUWVTmRmHtGrfpzG/yuQNOKa6gBB/WA9khitPgl6/GP+gl2Af6tCbvaygAAAABJRU5ErkJggg=="});let t=b(),e=b(8),i=1,s=0,o=new je(n),a=new Ee(t,e,o,i,s);rc=new Zi(a)}function fh(n=!0){Ln=n}function ph(n){Sr=n}function gh(){return He==="mouse"}function yh(){return He==="keyboard"}function mh(){return He==="gamepad"}function wr(n,t=0,e=!0,i=!0,s=!0){$[t]&&($[t][n]&=~((e?1:0)|(i?2:0)|(s?4:0)))}function Pi(){$.length=0,$[0]=[],ie.length=0,bn.length=0,Li.length=0,me.length=0,cn.length=0}function Ot(n,t=0){var e;return p(W(n),"key must be a number or string"),p(t>0||typeof n!="number"||n<3,"use code string for keyboard"),!!(((e=$[t])==null?void 0:e[n])&1)}function kt(n,t=0){var e;return p(W(n),"key must be a number or string"),p(t>0||typeof n!="number"||n<3,"use code string for keyboard"),!!(((e=$[t])==null?void 0:e[n])&2)}function Tr(n,t=0){var e;return p(W(n),"key must be a number or string"),p(t>0||typeof n!="number"||n<3,"use code string for keyboard"),!!(((e=$[t])==null?void 0:e[n])&4)}function bh(n="ArrowUp",t="ArrowDown",e="ArrowLeft",i="ArrowRight"){p(W(n),"up key must be a string"),p(W(t),"down key must be a string"),p(W(e),"left key must be a string"),p(W(i),"right key must be a string");let s=o=>Ot(o)?1:0;return b(s(i)-s(e),s(n)-s(t))}function ni(n){return p(P(n),"mouse button must be a number"),Ot(n)}function ci(n){return p(P(n),"mouse button must be a number"),kt(n)}function xh(n){return p(P(n),"mouse button must be a number"),Tr(n)}function Ce(n,t=mt){return p(P(n),"button must be a number"),p(P(t),"gamepad must be a number"),Ot(n,t+1)}function Ar(n,t=mt){return p(P(n),"button must be a number"),p(P(t),"gamepad must be a number"),kt(n,t+1)}function vh(n,t=mt){return p(P(n),"button must be a number"),p(P(t),"gamepad must be a number"),Tr(n,t+1)}function li(n,t=mt){var e,i;return p(P(n),"stick must be a number"),p(P(t),"gamepad must be a number"),(i=(e=me[t])==null?void 0:e[n])!=null?i:b()}function po(n=mt){var t;return p(P(n),"gamepad must be a number"),(t=cn[n])!=null?t:b()}function go(n=mt){return p(P(n),"gamepad must be a number"),!!$[n+1]}function ac(n=mt){var t,e;return p(P(n),"gamepad must be a number"),(e=(t=me[n])==null?void 0:t.length)!=null?e:0}function Sh(n=mt,t=200,e=1,i=1,s=0){var a,r,c;if(p(P(n),"gamepad must be a number"),!Ei||J)return;let o=(a=navigator==null?void 0:navigator.getGamepads)==null?void 0:a.call(navigator)[n];(c=(r=o==null?void 0:o.vibrationActuator)==null?void 0:r.playEffect)==null||c.call(r,"dual-rumble",{duration:t,strongMagnitude:e,weakMagnitude:i,startDelay:s})}function wh(n=mt){var e,i,s;if(p(P(n),"gamepad must be a number"),!Ei||J)return;let t=(e=navigator==null?void 0:navigator.getGamepads)==null?void 0:e.call(navigator)[n];(s=(i=t==null?void 0:t.vibrationActuator)==null?void 0:i.reset)==null||s.call(i)}function Er(n=100){var t;p(P(n)||ue(n),"pattern must be a number or array"),Ei&&!J&&((t=navigator==null?void 0:navigator.vibrate)==null||t.call(navigator,n))}function Th(){Er(0)}function Ah(){var n;!ne&&((n=N.requestPointerLock)==null||n.call(N))}function Eh(){var n;(n=document.exitPointerLock)==null||n.call(document)}function cc(){return document.pointerLockElement===N}function _h(){if(J)return;document.addEventListener("keydown",n),document.addEventListener("keyup",t),document.addEventListener("mousedown",i),document.addEventListener("mouseup",s),document.addEventListener("mousemove",o),document.addEventListener("mouseleave",a),document.addEventListener("wheel",r,{passive:!1}),document.addEventListener("contextmenu",c),document.addEventListener("blur",l),ne&&un&&u();function n(f){if(f.repeat||($[0][f.code]=3,ti&&($[0][e(f.code)]=3)),!Ln||!f.cancelable||!document.hasFocus()||f.ctrlKey||f.metaKey||f.altKey||x(f.target)||x(document.activeElement))return;let d=typeof f.key=="string"&&f.key.length===1;(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight","Space","Tab","Backspace"].includes(f.code)||d)&&f.preventDefault();function x(v){let w=v==null?void 0:v.tagName;return(v==null?void 0:v.isContentEditable)||["INPUT","TEXTAREA","SELECT"].includes(w)}}function t(f){$[0][f.code]=$[0][f.code]&2|4,ti&&($[0][e(f.code)]=4)}function e(f){return ti?f==="KeyW"?"ArrowUp":f==="KeyS"?"ArrowDown":f==="KeyA"?"ArrowLeft":f==="KeyD"?"ArrowRight":f:f}function i(f){if(ne&&un)return;Wt&&!J&&dt&&!hi()&&dt.resume(),$[0][f.button]=3;let d=Nt;Nt=h(b(f.x,f.y)),ye=ye.add(Nt.subtract(d)),Ln&&f.cancelable&&document.hasFocus()&&f.preventDefault()}function s(f){ne&&un||($[0][f.button]=$[0][f.button]&2|4)}function o(f){ts=!0;let d=Nt;Nt=h(b(f.x,f.y));let y=cc()?b(f.movementX,f.movementY):Nt.subtract(d);ye=ye.add(y)}function a(){ts=!1}function r(f){f.ctrlKey||(vr+=te(f.deltaY)),Ln&&f.cancelable&&document.hasFocus()&&f.preventDefault()}function c(f){f.preventDefault()}function l(){Pi(),Me.clear(),ie.length=0,bn.length=0,Li.length=0}function u(){document.addEventListener("touchstart",y=>d(y),{passive:!1}),document.addEventListener("touchmove",y=>d(y),{passive:!1}),document.addEventListener("touchend",y=>d(y),{passive:!1});let f;function d(y){if(un){if(Wt&&!J&&dt&&!hi()&&dt.resume(),!en||fr){let x=S=>ui.includes(S.target)||S.target===ln,v=[];for(let S of y.touches)x(S)||v.push(S);let w=v.length,C=0;if(w){let S=b(v[0].clientX,v[0].clientY),_=Nt;Nt=h(S),f?ye=ye.add(Nt.subtract(_)):$[0][C]=3}else f&&($[0][C]=$[0][C]&2|4);f=w}return Ln&&y.cancelable&&document.hasFocus()&&y.preventDefault(),!0}}}function h(f){let d=N.getBoundingClientRect(),y=jt(f.x,d.left,d.right),x=jt(f.y,d.top,d.bottom);return b(y*N.width,x*N.height)}}function wa(){if(J)return;!(un&&ne)&&!document.hasFocus()&&Pi(),_e=Ci(Nt),xr=ic(ye),Rh(),t(),n();function n(){let e=ni(0)||ni(1)||ni(2)||ye.length()>Sr,i=!1;for(let o=ac();o--&&!i;)i=li(o).lengthSquared()>.04;for(let o=17;o--&&!i;)i=Ce(o);let s=!1;for(let o in $[0])if(isNaN(+o)&&$[0][o]&1){s=!0;break}i?He="gamepad":e?He="mouse":s&&(He="keyboard"),Dn=He==="gamepad"}function t(){var a,r,c,l,u,h,f;let e=d=>{let v=w=>w>.3?jt(w,.3,.8):w<-.3?-jt(-w,.3,.8):0;return b(v(d.x),v(-d.y)).clampLength()};if(en&&ne){if(p(!Sn||!Un,"set touchGamepadLeftStick or touchGamepadLeftButtonCount, not both"),p(!Vn||!Jn,"set touchGamepadRightStick or touchGamepadButtonCount, not both"),!Fn.isSet())return;mt=0;let d=(a=me[0])!=null?a:me[0]=[],y=(r=cn[0])!=null?r:cn[0]=b();d.length=0,y.set();for(let v=0;v<2;v++){if(!Be(v))continue;let w=Rr(v);d[w]=b();let C=(c=bn[v])!=null?c:b();if(Ai)d[w]=e(C);else if(C.lengthSquared()>.3){let S=z(Wi(C.x),-1,1),_=z(Wi(C.y),-1,1);d[w]=b(S,-_).clampLength(),w||y.set(S,-_)}}let x=(l=$[1])!=null?l:$[1]=[];for(let v=12;v--;){let w=Ce(v,0);x[v]=ie[v]?w?1:3:w?4:0,Yi&&x[v]===3&&(v===9||Ph(v))&&Er(Yi)}return}try{if(!Ps||!(navigator!=null&&navigator.getGamepads))return}catch{return}if(!Ft&&!document.hasFocus())return;let i=8,s=navigator.getGamepads(),o=Z(i,s.length);for(let d=0;d>1]=e(b(y.axes[S],y.axes[S+1]));let C=!1;for(let S=y.buttons.length;S--;){let _=y.buttons[S],A=Ce(S,d);x[S]=_.pressed?A?1:3:A?4:0,_.pressed&&(!_.value||_.value>.9)&&(C=!0)}C&&(so[d]=!0,so[mt]||(mt=d)),y.mapping==="standard"&&w.set((Ce(15,d)&&1)-(Ce(14,d)&&1),(Ce(12,d)&&1)-(Ce(13,d)&&1)),dr&&(w.x||w.y)&&(v[0]=w.clampLength())}en&&Dn&&Fn.unset()}}function Ta(){if(!J){for(let n of $)for(let t in n)n[t]&=1;vr=0,xr=b(),ye=b()}}function Ch(){Mh()}function Rh(){if(Ve||!en||!ne||J||!document.body)return;let n=Ve=document.createElement("div");n.style.cssText="position:fixed;inset:0;z-index:50;pointer-events:none;opacity:0;touch-action:none;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;transition:opacity .2s;box-sizing:border-box;padding:env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left)";let t=lc=document.createElement("div");t.style.cssText="position:relative;width:100%;height:100%;pointer-events:none",n.appendChild(t);let e=_r=document.createElementNS(ns,"svg");e.style.cssText="position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible;fill:none;stroke:#fff;stroke-width:3",t.appendChild(e);let i=()=>{let s=document.createElement("div");return s.style.cssText="position:absolute;pointer-events:auto;touch-action:none",s.addEventListener("pointerdown",o=>Fh(o,s)),s.addEventListener("pointermove",o=>jh(o)),s.addEventListener("pointerup",o=>Aa(o)),s.addEventListener("pointercancel",o=>Aa(o)),t.appendChild(s),s};ui[0]=i(),ui[1]=i(),ln=i(),addEventListener("resize",()=>jn=!0),document.body.appendChild(n),jn=!0}function Ls(){return lc.getBoundingClientRect()}function Be(n){return n?Vn:Sn}function An(n){return n?Jn:Un}function Cr(n){return n?0:4}function Rr(n){return n&&Sn?1:0}function Bn(n){return Be(n)||An(n)>0}function Ph(n){for(let t=0;t<2;t++){let e=Cr(t);if(!Be(t)&&n>=e&&no.style.cssText="position:absolute;pointer-events:auto;touch-action:none;"+a;if(Se){for(let o of ui)o.style.display="none";he?(s(ln,"inset:0"),ln.style.display=""):ln.style.display="none"}else{for(let a=0;a<2;a++){let r=ui[a],c=a?"right":"left";if(r.style.display=Bn(a)?"":"none",sn){let l=Bn(a?0:1)?"50%":"100%";s(r,`${c}:0;bottom:0;width:${l};height:60%`)}else s(r,`${c}:0;bottom:0;width:${3*i}px;height:${3*i}px`)}ln.style.display=he?"":"none";let o=he;s(ln,`left:50%;top:50%;width:${2*o}px;height:${2*o}px;transform:translate(-50%,-50%)`)}Oh(t,e),jn=!1}function Oh(n,t){let e=_r;for(;e.firstChild;)e.removeChild(e.firstChild);let i=uc={face:[],thumb:[]},s=Vt,o=(r,c,l,u)=>{let h=document.createElementNS(ns,"circle");return h.setAttribute("cx",r),h.setAttribute("cy",c),h.setAttribute("r",l),u&&h.setAttribute("fill",u),e.appendChild(h),h},a=r=>{let c=s*.18,l=s*.5,u=r.x,h=r.y,f=document.createElementNS(ns,"path");f.setAttribute("d",`M ${u-c} ${h-l} H ${u+c} V ${h-c} H ${u+l} V ${h+c} H ${u+c} V ${h+l} H ${u-c} V ${h+c} H ${u-l} V ${h-c} H ${u-c} Z`),e.appendChild(f)};for(let r=0;r<2;r++){let c=An(r),l=Cr(r),u=ke(r,n,t);if(Be(r))Ai?o(u.x,u.y,s/2):a(u),i.thumb[r]=o(u.x,u.y,s/4,"#fff");else if(c===1)i.face[l]=o(u.x,u.y,s/2,"#000");else for(let h=0;h2?f:Z(f,c-1);d=d===3?2:d===2?3:d;let y=b().setDirection(f,s/2);c===2&&(y.x*=-1),r||(y.x*=-1);let x=u.add(y);i.face[l+d]=o(x.x,x.y,s/4,"#000")}}Ft&&pn&&Dh(n,t)}function Dh(n,t){let e=Vt,i=_r,s=(a,r,c)=>{let l=document.createElementNS(ns,a);for(let u in r)l.setAttribute(u,r[u]);l.setAttribute("stroke",c),l.setAttribute("stroke-width",2),l.setAttribute("fill","none"),i.appendChild(l)},o=(a,r,c)=>s("circle",{cx:a.x,cy:a.y,r},c);s("line",{x1:n/2,y1:0,x2:n/2,y2:t},"#0f0");for(let a=0;a<2;a++)if(Be(a))if(sn){let r=t*.4,c=!Bn(a?0:1),l=c?0:a?n/2:0;s("rect",{x:l,y:r,width:c?n:n/2,height:t-r},"#0ff")}else o(ke(a,n,t),2*e,"#0ff");else An(a)>=1&&o(ke(a,n,t),e,"#0ff");if(he){o(b(n/2,t/2),he,"#ff0");for(let a=0;a<2;a++)Bn(a)&&o(ke(a,n,t),2*e,"#f0f")}}function Mh(){var l;if(!Ve||J)return;if(!en||!ne){Ve.style.display!=="none"&&(Ve.style.display="none",Me.clear(),ie.length=0,bn.length=0,Li.length=0);return}Ve.style.display="";let n=Ft&&pn,t=[Jn,Un,Sn,Vn,Ai,Vt,sn,he,Se,n].join();t!==Sa&&(Sa=t,jn=!0),jn&&Lh();let e=ei?jt(Fn.get(),ei+1,ei):1,i=n||Fn.isSet()&&e>0&&!Se;if(Ve.style.opacity=i?n?1:e*pr:0,!i)return;let s=Ls(),o=s.width,a=s.height,r=Vt,c=uc;if(c){for(let u=0;u<2;u++)if(Be(u)&&c.thumb[u]){let f=ke(u,o,a).add(((l=bn[u])!=null?l:b()).scale(r/2));c.thumb[u].setAttribute("cx",f.x),c.thumb[u].setAttribute("cy",f.y)}for(let u=0;u=Vt)return-1;if(s===1)return o;let r=a.subtract(t);n||(r.x*=-1);let c=s===2?r.xo:r&&ke(a,t,e).distance(n)<2*i)return{role:"stick",side:a}}else if(An(a)>=1){let c=kh(a,n,t,e);if(c>=0)return{role:"face",btn:c}}}if(he){for(let a=0;a<2;a++)if(Bn(a)&&ke(a,t,e).distance(n)<2*i)return;if(b(t/2,e/2).distance(n)h.getChannelData(v).set(x)),f.buffer=h,f.playbackRate.value=e,f.loop=s,a=a||dt.createGain(),a.gain.value=t,a.connect(Ge);let d=new StereoPannerNode(dt,{pan:z(i,-1,1)});f.connect(d).connect(a),f.addEventListener("ended",()=>{a.disconnect(),d.disconnect(),c&&c(f)});let y=r*e;return f.start(0,y),Ft&&kn&&vt("sound","vol",t.toFixed(2),"rate",e.toFixed(2),"pan",i.toFixed(2),s?"loop":""),f}function Jh(...n){return Pr([Os(...n)])}function Os(n=1,t=.05,e=220,i=0,s=0,o=.1,a=0,r=1,c=0,l=0,u=0,h=0,f=0,d=0,y=0,x=0,v=0,w=1,C=0,S=0,_=0){let A=Wn,T=Y*2,L=c*=500*T/A/A,F=e*=(1+ht(t,-t))*T/A,ft=0,D=0,I=0,k=1,R,ct=[],j=0,tt=0,ut=0,xt,Ht=2,At=T*nt(_)*2/A,Pt=at(At),gt=it(At)/2/Ht,yt=1+gt,oe=-2*Pt/yt,on=(1-gt)/yt,rn=(1+te(_)*Pt)/2/yt,Mt=-(te(_)+Pt)/yt,Ne=rn,qn=0,Hn=0,Oi=0,Di=0;for(i=i*A||9,C*=A,s*=A,o*=A,v*=A,l*=500*T/A**3,y*=T/A,u*=T/A,h*=A,f=f*A|0,R=i+C+s+o+v|0;tt1?a>2?a>3?a>4?j/T%14?ut:te(ut)*nt(ut)**r)*(tttt?0:(tth&&(e+=u,F+=u,k=0),f&&!(++D%f)&&(e=F,c=L,k||(k=1));return ct}function ss(n,t=!0){for(let e of Qe)if((!t||e.isSolid)&&n.arrayCheck(e.size)){let i=e.getCollisionData(n);if(i)return i}return 0}function We(n,t=b(),e,i=!0){for(let s of Qe)if((!i||s.isSolid)&&s.collisionTest(n,t,e))return s}function fc(n,t,e,i,s=!0){let o,a,r,c=i&&b();for(let l of Qe)if(!s||l.isSolid){let u=l.collisionRaycast(n,t,e,c);if(u){let h=n.distanceSquared(u);(o===void 0||h{B=!1,et.style.display="none",e.preventDefault(),vt("WebGL context lost! Switching to Canvas2d rendering.");for(let i of ii)i.glTexture=void 0;Kt=void 0,_t=0,xn=!1,dn.forEach(i=>{var s;return(s=i.glContextLost)==null?void 0:s.call(i)})}),et.addEventListener("webglcontextrestored",()=>{B=!0,et.style.display="",vt("WebGL context restored, reinitializing..."),t();for(let e of ii)e.glTexture=Ms(e.image,e.wrap);dn.forEach(e=>{var i;return(i=e.glContextRestored)==null?void 0:i.call(e)})});function t(){as=zn(`#version 300 es
 precision highp float;uniform mat4 m;in vec2 g;in vec4 p,u,c,a;in float r;out vec2 v;out vec4 d,e;void main(){vec2 s=(g-.5)*p.zw;gl_Position=m*vec4(p.xy+s*cos(r)-vec2(-s.y,s)*sin(r),1,1);v=mix(u.xw,u.zy,g);d=c;e=a;}`,`#version 300 es
-precision highp float;uniform sampler2D s;in vec2 v;in vec4 d,e;out vec4 c;void main(){c=texture(s,v)*d+e;}`),yi=Yn(`#version 300 es
+precision highp float;uniform sampler2D s;in vec2 v;in vec4 d,e;out vec4 c;void main(){c=texture(s,v)*d+e;}`),cs=zn(`#version 300 es
 precision highp float;uniform mat4 m;in vec2 p;in vec4 c;out vec4 d;void main(){gl_Position=m*vec4(p,1,1);d=c;}`,`#version 300 es
-precision highp float;in vec4 d;out vec4 c;void main(){c=d;}`);let e=new ArrayBuffer(mi);kt=new Float32Array(e),Ts=new Uint32Array(e),Ao=y.createBuffer(),zn=y.createBuffer(),jr=y.createFramebuffer(),_t=0;let s=new Float32Array([0,0,1,0,0,1,1,1]);y.bindBuffer(y.ARRAY_BUFFER,zn),y.bufferData(y.ARRAY_BUFFER,s,y.STATIC_DRAW);let i,o,r,a=(c,l,u,h,p=0)=>{let d=y.getAttribLocation(o,c),g=u===1,x=u&&r;y.enableVertexAttribArray(d),y.vertexAttribPointer(d,h,l,g,x,i),y.vertexAttribDivisor(d,p),i+=h*u};Co=y.createVertexArray(),y.bindVertexArray(Co),i=0,o=pi,r=Sc,y.bindBuffer(y.ARRAY_BUFFER,zn),a("g",y.FLOAT,0,2),y.bindBuffer(y.ARRAY_BUFFER,Ao),y.bufferData(y.ARRAY_BUFFER,mi,y.DYNAMIC_DRAW),a("p",y.FLOAT,4,4,1),a("u",y.FLOAT,4,4,1),a("c",y.UNSIGNED_BYTE,1,4,1),a("a",y.UNSIGNED_BYTE,1,4,1),a("r",y.FLOAT,4,1,1),_o=y.createVertexArray(),y.bindVertexArray(_o),i=0,o=yi,r=wc,a("p",y.FLOAT,4,2),a("c",y.UNSIGNED_BYTE,1,4)}}function As(n=!1){!n&&!En||(Rt(),En=!1,y.useProgram(pi),y.bindVertexArray(Co))}function Tc(){En||(Rt(),En=!0,y.useProgram(yi),y.bindVertexArray(_o))}function Ro(n=!0){if(!G||!y)return;f(!_t,"glPreRender called with unflushed batch."),gi||(Z.width=I.x,Z.height=I.y),y.viewport(0,0,I.x,I.y),n&&Ac();let t=b(2*H).divide(I);gi&&(t.y=-t.y);let e=Et.rotate(-K),s=b(-1).subtract(e.multiply(t)),i=at(K),o=et(K),r=[t.x*i,t.y*o,0,0,-t.x*o,t.y*i,0,0,1,1,1,0,s.x,s.y,0,1],a=(c,l,u)=>{y.useProgram(c);let h=y.getUniformLocation(c,l);y.uniformMatrix4fv(h,!1,u)};a(yi,"m",r),a(pi,"m",r),y.activeTexture(y.TEXTURE0),hn[0]&&(Zt=hn[0].glTexture,y.bindTexture(y.TEXTURE_2D,Zt)),y.bindBuffer(y.ARRAY_BUFFER,Ao),Mn=Xn=!1,As(!0)}function Ac(){if(!y)return;let n=sn;y.clearColor(n.r,n.g,n.b,n.a),y.clear(y.COLOR_BUFFER_BIT)}function Nr(n){!y||n===Zt||(Rt(),Zt=n,y.bindTexture(y.TEXTURE_2D,Zt))}function Cc(n,t=!0){if(!y||!n)return;let e=n===Zt;e?Rt():y.bindTexture(y.TEXTURE_2D,n);let s=t?y.REPEAT:y.CLAMP_TO_EDGE;y.texParameteri(y.TEXTURE_2D,y.TEXTURE_WRAP_S,s),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_WRAP_T,s),!e&&Zt&&y.bindTexture(y.TEXTURE_2D,Zt)}function Po(n,t){if(!y)return;let e=y.createShader(t);if(y.shaderSource(e,n),y.compileShader(e),Gt&&!y.getShaderParameter(e,y.COMPILE_STATUS))throw y.getShaderInfoLog(e);return e}function Yn(n,t){if(!y)return;let e=y.createProgram();if(y.attachShader(e,Po(n,y.VERTEX_SHADER)),y.attachShader(e,Po(t,y.FRAGMENT_SHADER)),y.linkProgram(e),Gt&&!y.getProgramParameter(e,y.LINK_STATUS))throw y.getProgramInfoLog(e);return e}function Ni(n,t=!1){if(!y)return;let e=y.createTexture(),s=!1;if(n!=null&&n.width)zr(e,n),y.bindTexture(y.TEXTURE_2D,e),s=!Cn&&fs(n.width)&&fs(n.height);else{let a=new Uint8Array([255,255,255,255]);y.bindTexture(y.TEXTURE_2D,e),y.texImage2D(y.TEXTURE_2D,0,y.RGBA,1,1,0,y.RGBA,y.UNSIGNED_BYTE,a)}let i=Cn?y.NEAREST:y.LINEAR,o=s?y.LINEAR_MIPMAP_LINEAR:i;y.texParameteri(y.TEXTURE_2D,y.TEXTURE_MAG_FILTER,i),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_MIN_FILTER,o);let r=t?y.REPEAT:y.CLAMP_TO_EDGE;return y.texParameteri(y.TEXTURE_2D,y.TEXTURE_WRAP_S,r),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_WRAP_T,r),s&&y.generateMipmap(y.TEXTURE_2D),y.bindTexture(y.TEXTURE_2D,Zt),e}function _c(n){y&&y.deleteTexture(n)}function zr(n,t){y&&(f((t==null?void 0:t.width)>0,"Invalid image data."),y.bindTexture(y.TEXTURE_2D,n),y.texImage2D(y.TEXTURE_2D,0,y.RGBA,y.RGBA,y.UNSIGNED_BYTE,t),!Cn&&fs(t.width)&&fs(t.height)&&y.generateMipmap(y.TEXTURE_2D),y.bindTexture(y.TEXTURE_2D,Zt))}function Kh(n){N||(hs.add(n),y&&(n.glTexture?zr(n.glTexture,n.image):n.glTexture=Ni(n.image,n.wrap)))}function Qh(n){if(N)return;hs.delete(n);let t=n.glTexture;n.glTexture=void 0,_c(t)}function Rt(){if(G&&y&&_t){let n=Xn?y.ONE:y.ONE_MINUS_SRC_ALPHA;y.blendFuncSeparate(y.SRC_ALPHA,n,y.ONE,n),y.enable(y.BLEND);let t=_t*(En?Bi:Br);y.bufferSubData(y.ARRAY_BUFFER,0,kt,0,t),En?y.drawArrays(y.TRIANGLE_STRIP,0,_t):y.drawArraysInstanced(y.TRIANGLE_STRIP,0,4,_t),++Ce,_e+=_t,_t=0}Xn=Mn}function Jr(n){!G||!y||(Rt(),n.drawImage(Z,0,0))}function Zh(n=!0){f(!Z,"must be called before engineInit"),Fr=n}function Cs(n,t,e,s,i=0,o=0,r=0,a=1,c=1,l=-1,u=0){(_t>=Yh||Xn!==Mn)&&Rt(),As();let h=_t++*Br;kt[h++]=n,kt[h++]=t,kt[h++]=e,kt[h++]=s,kt[h++]=o,kt[h++]=r,kt[h++]=a,kt[h++]=c,Ts[h++]=l,Ts[h++]=u,kt[h++]=i}function Ec(n,t,e,s,i,o){Cs(n,t,e,s,i,0,0,0,0,0,o)}function Ur(n,t,e,s,i,o,r,a=!0){let c=[],l=et(-r),u=at(-r);for(let p of n){let d=p.x*i,g=p.y*o;c.push(b(e+u*d-l*g,s+l*d+u*g))}let h=a?ed(c):c;Rc(h,t)}function Vr(n,t,e,s,i,o,r,a,c=!0){let l=td(n,e,c);Ur(l,t,s,i,o,r,a,!1)}function Rc(n,t){if(!G||n.length<3)return;let e=n.length+2;if((_t+e>=Jn||Xn!==Mn)&&Rt(),f(e=Jn)return;Tc();let s=_t*Bi;for(let i=e;i--;){let o=B(i-1,0,e-3),r=n[o];kt[s++]=r.x,kt[s++]=r.y,Ts[s++]=t}_t+=e}function Wr(n,t){if(!G||n.length<3)return;let e=n.length+2;if((_t+e>=Jn||Xn!==Mn)&&Rt(),f(e=Jn)return;Tc();let s=_t*Bi;for(let i=e;i--;){let o=B(i-1,0,e-3),r=n[o],a=t[o];kt[s++]=r.x,kt[s++]=r.y,Ts[s++]=a}_t+=e}function rs(n,t=!1){n?(gi=n,y.bindFramebuffer(y.FRAMEBUFFER,jr),y.framebufferTexture2D(y.FRAMEBUFFER,y.COLOR_ATTACHMENT0,y.TEXTURE_2D,n,0),Ro(t)):(Rt(),gi=void 0,y.bindFramebuffer(y.FRAMEBUFFER,null),y.viewport(0,0,I.x,I.y))}function Pc(n,t,e,s){G&&(y.enable(y.SCISSOR_TEST),y.scissor(n,t,e,s),y.clearColor(0,0,0,0),y.clear(y.COLOR_BUFFER_BIT),y.disable(y.SCISSOR_TEST))}function td(n,t,e=!0){if(n.length<2)return[];let s=t/2,i=[],o=n.length,r=1e-6,a=10;for(let c=0;cr?-d/g:0,S=g>r?p/g:0,E=w>r?-v/w:0,A=w>r?x/w:0,T=_+E,P=S+A,k=(T*T+P*P)**.5;if(kr){let gt=Q(1/it,a);T*=gt,P*=gt}}let ct=b(u.x-T*s,u.y-P*s),st=b(u.x+T*s,u.y+P*s);i.push(ct),i.push(st)}return i.length>1&&e&&(i.push(i[0]),i.push(i[1])),i}function ed(n){if(n.length<3)return[];let t=(d,g,x)=>(g.x-d.x)*(x.y-d.y)-(g.y-d.y)*(x.x-d.x);(d=>{let g=0;for(let x=d.length;x--;){let v=(x+1)%d.length;g+=d[x].cross(d[v])}return g})(n)<0&&(n=n.slice().reverse());let s=1e-9,i=(d,g,x,v)=>{let w=t(g,x,d),_=t(x,v,d),S=t(v,g,d),E=(w<-s?1:0)+(_<-s?1:0)+(S<-s?1:0),A=(w>s?1:0)+(_>s?1:0)+(S>s?1:0);return!(E&&A)},o=[];for(let d=0;d3&&a++{if(E>=0){let T=s.fillStyle=s.createLinearGradient(v,w,_,S);T.addColorStop(0,h(E,2)),T.addColorStop(1,h(E,1))}else s.fillStyle="#000";E>=-1?(s.fill(),A&&s.stroke()):s.stroke()},c=(v,w,_,S=0,E=2*X,A,T)=>{s.beginPath(),s.arc(v,w,_,d*S,d*E),a(v,w-_,v,w+_,A,T)},l=(v,w,_,S,E)=>{s.beginPath(),s.rect(v,w,_,S*d),a(v,w+S,v+_,w,E)},u=(v,w,_,S)=>{s.beginPath();for(let E of v)s.lineTo(E.x,E.y);s.closePath(),a(0,_,0,_+S,w)},h=(v,w)=>w?`hsl(${[.95,.56,.13][v%3]*360} 99%${[0,50,75][w]}%)`:"#000",p=Ya(1,1,n),d=Ft(p,.1,.5),g=Q(6,Q(o,r)/99);s.translate(o/2,r/2),s.scale(g,g),s.translate(-40,-35),d<1&&s.setLineDash([99*d,99]),s.lineJoin=s.lineCap="round",s.lineWidth=.1+d*1.9;{let w="LittleJS";s.font="900 15.5px arial",s.lineWidth=.1+d*3.9,s.textAlign="center",s.textBaseline="top",l(11,55,59,8*d,-1),s.beginPath();let _=0;for(let S=0;S5?1:0),s[S?"strokeText":"fillText"](w[E],P,54+.5,17*d),A+=T}s.lineWidth=.1+d*1.9,l(3,54,73,0)}l(7,15,26,-7,0),l(25,15,8,25,-1),l(10,40,15,-25,1),l(14,21,7,9,2),l(38,20,6,-6,2),l(49,20,10,-6,0);let x=[b(44,8),b(64,8),b(59,8+6*d),b(49,8+6*d)];u(x,2,8,6*d),l(44,8,20,-7,0);for(let v=5;v--;)c(59-v*6*d,30,10,0,2*X,1,0);c(59,30,4,0,7,2),l(35,20,24,0),c(59,30,10),c(47,30,10,X/2,X*3/2),c(35,30,10,X/2,X*3/2),l(7,40,13,7,-1),l(17,40,43,14,-1);for(let v=3;v--;)for(let w=2;w--;)c(17+15*v,47,w?7:1,0,2*X,2);for(let v=2;v--;){let w=6,_=7,S=53+w*d*v,E=[b(S+_,54),b(S,40),b(S+w*d,40),b(S+_+w*d,54)];u(E,0,40,14)}s.restore()}function sd(n){if(vi=n,!yn){let e={};try{e=JSON.parse(localStorage[n]||"{}")}catch{e={}}zi(s=>{s.unlocked=!!(e[s.id]&&e[s.id].unlocked)}),Hr()}Rn(void 0,t);function t(){if(!Xs.length)return;let e=Xs[0],s=cn-Hs;if(!Hs)Hs=cn;else if(s>bi)Hs=0,Xs.shift();else{let i=bi-Bn,o=si?(s-i)/Bn:0;e.render(o)}}}function zi(n){Object.values(_s).forEach(t=>n(t))}function id(){zi(n=>n.unlocked=!1),Hr()}function Hr(){if(!vi)return;let n={};zi(t=>{let e={name:t.name,description:t.description,icon:t.icon,unlocked:t.unlocked};t.image&&(e.src=t.image.src),n[t.id]=e}),localStorage[vi]=JSON.stringify(n)}function od(n){bi=n}function rd(n){Bn=n}function ad(n){xi=n.copy()}function cd(n){qr=n}function Lc(n,t,e,s=125){let i,o,r,a,c,l,u,h,p,d,g,x,v,w=0,_,S=[],E=[],A=[],T=0,P=0,k=1,ct={},st=Zn/s*60>>2;for(;k;T++)S=[k=h=x=0],e.forEach((it,gt)=>{for(u=t[it][T]||[0,0,0],k|=t[it][T]&&1,_=x+(t[it][0].length-2-(h?0:1))*st,v=gt===e.length-1,i=2,r=x;ist-99&&p&&g<1?g+=1/99:0)l=(1-g)*S[w++]/2||0,E[r]=(E[r]||0)-l*P+l,A[r]=(A[r++]||0)+l*P+l;c&&(g=c%1,P=u[1]||0,(c|=0)&&(S=ct[[d=u[w=0]||0,c]]=ct[[d,c]]||(a=[...n[d]],a[2]=(a[2]||220)*2**(c/12-1),c>0?ji(...a):[])))}x=_});return[E,A]}function ld(n){Xr=typeof n=="boolean"?n?1:0:n}function ud(n){Yr=n}async function hd(){return new _i(await Box2D()),e(),Rn(n,t),m;function n(){if(!Te){m.step(),m.objects=m.objects.filter(s=>!s.destroyed);for(let s of m.objects)s.body&&(s.pos=m.vec2From(s.body.GetPosition()),s.angle=-s.body.GetAngle())}}function t(){(Yr||ue)&&m.world.DrawDebugData()}function e(){let i=new m.instance.JSDraw,o=l=>new At(l.get_r(),l.get_g(),l.get_b()),r=l=>o(m.instance.wrapPointer(l,m.instance.b2Color)),a=l=>r(l).scale(1,.8),c=(l,u)=>{let h=[];for(let p=u;p--;)h.push(m.vec2FromPointer(l+p*8));return h};i.DrawSegment=function(l,u,h){h=a(h),l=m.vec2FromPointer(l),u=m.vec2FromPointer(u),xn(l,u,.1,h,b(),0,!1)},i.DrawPolygon=function(l,u,h){h=a(h);let p=c(l,u);Vn(p,ln,.1,h,b(),0,!1)},i.DrawSolidPolygon=function(l,u,h){h=a(h);let p=c(l,u);Vn(p,h,0,h,b(),0,!1)},i.DrawCircle=function(l,u,h){h=a(h),l=m.vec2FromPointer(l),oi(l,u*2,ln,.1,h,!1)},i.DrawSolidCircle=function(l,u,h,p){p=a(p),l=m.vec2FromPointer(l),h=m.vec2FromPointer(h).scale(u),oi(l,u*2,p,.1,p,!1),xn(b(),h,.1,p,l,0,!1)},i.DrawTransform=function(l){l=m.instance.wrapPointer(l,m.instance.b2Transform);let u=m.vec2From(l.get_p()),h=-l.get_q().GetAngle(),p=b(1,0),d=z(.75,0,0,.8),g=b(0,1),x=z(0,.75,0,.8);xn(b(),p,.1,d,u,h,!1),xn(b(),g,.1,x,u,h,!1)},i.AppendFlags(m.instance.b2Draw.e_shapeBit),i.AppendFlags(m.instance.b2Draw.e_jointBit),m.world.SetDebugDraw(i)}}function dd(n,t,e,s=32,i=2,o=0){Oc(n,t,e,W,s,nt,i,o,!1,!0)}function Oc(n,t,e,s,i=1,o,r=.05,a=0,c=G,l,u){let h=e.offset(e.size),p=t.add(b(r-i*2)),d=b(i),g=t.scale(.5).subtract(d.scale(.5)),x=l?-1:1,v=l?-a:a;Ot(n,p,h,s,a,!1,o,c,l,u);for(let w=4;w--;){let _=w%2,S=g.multiply(b(_?w===1?1:-1:0,_?0:w?-1:1)),E=b(_?i:p.x,_?p.y:i),A=h.offset(e.size.multiply(b(w===1?1:w===3?-1:0,w===0?-x:w===2?x:0)));Ot(n.add(S.rotate(v)),E,A,s,a,!1,o,c,l,u)}for(let w=4;w--;){let _=w>1,S=w&&w<3,E=g.multiply(b(_?-1:1,S?-1:1)),A=h.offset(e.size.multiply(b(_?-1:1,S?x:-x)));Ot(n.add(E.rotate(v)),d,A,s,a,!1,o,c,l,u)}}function fd(n,t,e,s=32,i=2,o=0){Dc(n,t,e,W,s,nt,i,o,!1,!0)}function Dc(n,t,e,s,i=1,o,r=.05,a=0,c=G,l,u){let h=e.frame(0),p=e.frame(1),d=e.frame(2),g=t.add(b(r-i*2)),x=b(i),v=t.scale(.5).subtract(x.scale(.5)),w=l?-1:1,_=l?-a:a;Ot(n,g,d,s,a,!1,o,c,l,u);for(let S=4;S--;){let E=a+S*X/2,A=S%2,T=v.multiply(b(A?S===1?1:-1:0,A?0:S?-w:w)),P=b(A?g.y:g.x,i);Ot(n.add(T.rotate(_)),P,p,s,E,!1,o,c,l,u)}for(let S=4;S--;){let E=a+S*X/2,A=!S||S>2,T=S>1,P=v.multiply(b(A?-1:1,T?-w:w));Ot(n.add(P.rotate(_)),x,h,s,E,!1,o,c,l,u)}}function pd(n,t=1,e=0,s=W,i=0,o=!1,r=0,a=nt,c=G,l=!1,u){let h=Mc(b(),t,e,0,o);Vn(h,s,r,a,n,i,c,l,u)}function Mc(n,t=1,e=0,s=0,i=!1,o=Os){f(L(n),"pos must be a vec2"),f(R(t)&&R(e),"size and percent must be numbers");let r=se(e*4,4);r>=2&&(s+=X),r=r<=2?r-1:3-r,i&&(r=-r,s+=X);let a=[],c=$(3,o>>1),l=t/2;for(let u=0;u<=c;u++){let h=u/c*X;a.push(b(l*at(h),l*et(h)).rotate(s).add(n))}for(let u=c;u>=0;u--){let h=u/c*X;a.push(b(l*at(h),-l*r*et(h)).rotate(s).add(n))}return a}function Ia(n){return n&&typeof n.lerp=="function"}function yd(n,t,e,s,i=1,o={}){f(n!=null&&typeof n=="object","tweenProperty target must be an object"),f(V(t)&&t.length>0,"tweenProperty propertyPath must be a non-empty string");let r=t.split("."),a=r.pop(),c=l=>{let u=n;for(let h of r)u=u[h];u[a]=l};return new Ei(c,e,s,i,o)}function Ic(n){n.loopRemaining!==1/0&&n.loopRemaining<=1||(n.loopRemaining!==1/0&&(n.loopRemaining-=1),n.life=n.duration,n.thenCallback=()=>Ic(n),Kt.push(n),n.callback(n.interp(n.duration)))}function kc(n){if(n.loopRemaining!==1/0&&n.loopRemaining<=1)return;n.loopRemaining!==1/0&&(n.loopRemaining-=1);let t=n.start;n.start=n.end,n.end=t,n.life=n.duration,n.thenCallback=()=>kc(n),Kt.push(n),n.callback(n.interp(n.duration))}function Gc(n,t){n===void 0?(n=Qt-Da,t=cn-Ma,Da=Qt,Ma=cn):t===void 0&&(t=n);for(let e=Kt.length;e--;){let s=Kt[e];if(s.paused)continue;let i=s.useRealTime?t:n;if(!(i<=0))if(s.life-=i,s.life>0)s.callback(s.interp(s.life));else{s.callback(s.interp(0)),Kt.splice(e,1);let o=s.thenCallback;s.thenCallback=void 0,o&&o()}}}function gd(){for(let n of Kt)n.thenCallback=void 0;Kt.length=0}var Ys,$s,Ll,sr,St,ir,ka,Qt,cn,Te,uo,me,Ks,Ga,vn,po,Gt,Ba,Li,Na,De,nn,ue,he,Sn,wn,Un,yo,Me,le,X,tt,Tt,ds,Qs,Q,$,ne,Va,Wa,et,at,qa,rr,bo,rt,At,W,ln,nt,pe,Xl,lr,Yl,ec,nc,$l,sc,ic,Kl,Ae,Et,K,H,hr,Oi,sn,kn,as,Gn,Fn,dr,Cn,on,Ls,fr,N,G,Os,Di,Mi,Ii,ki,pr,yr,gr,mr,br,ke,Wt,ei,Gi,xr,cs,bn,un,vr,fe,$n,Pn,Kn,Qn,Ds,dn,Ht,Sr,ls,ni,Ms,Xt,Tn,wr,Tr,ze,j,ut,Ct,je,tn,ve,Ge,I,hn,Ce,_e,Ee,Je,rh,fc,ri,Le,Ut,_r,be,Er,ai,Nn,en,Rr,jn,mt,ie,Y,xe,gn,ho,Wn,oe,_n,ci,js,Fe,Qe,gc,Mr,mc,bs,mn,qn,Ra,li,ft,Ne,Zn,vs,ui,an,An,di,Ss,ws,To,Xh,fi,Z,y,Fr,pi,yi,En,Mn,Xn,Zt,Ao,zn,kt,Ts,_t,hs,Co,_o,jr,gi,Eo,mi,Br,Sc,Yh,Bi,wc,Jn,yn,bi,Bn,xi,qr,_s,Xs,vi,Hs,Si,Es,Lo,Oo,Mt,Do,q,Mo,Io,ko,C,Xr,Go,re,wi,Fo,jo,Rs,Bo,No,zo,Jo,m,Yr,Ps,Ti,Uo,Vo,Ai,Yt,Wo,Ci,qo,Ho,Xo,Yo,$o,Ko,Qo,Zo,tr,er,_i,Kt,Da,Ma,Ei,Ri,md,fo,Pi,nr,jc=Jc(()=>{"use strict";Ys="LittleJS",$s="1.18.19",Ll=60,sr=.016666666666666666,St=[],ir=[],ka=0,Qt=0,cn=0,Te=!1;uo=0,me=0,Ks=0,Ga=!0,vn=[],po=class{constructor(t,e,s,i){this.update=t,this.render=e,this.glContextLost=s,this.glContextRestored=i}};Gt=!0,Ba=.5,Li=!0,Na="Escape",De=!1,nn=[],ue=!1,he=!1,Sn=!1,wn=!1,Un=!1;X=Math.PI,tt=Math.abs,Tt=Math.floor,ds=Math.ceil,Qs=Math.round,Q=Math.min,$=Math.max,ne=n=>Math.sign(n),Va=(...n)=>Math.hypot(...n),Wa=n=>Math.log2(n),et=Math.sin,at=Math.cos,qa=Math.tan,rr=Math.atan2;bo=class{constructor(t=123456789){f(t!==0,"RandomGenerator seed must be non-zero (xorshift is fixed at 0)"),this.seed=t}float(t=1,e=0){return this.seed^=this.seed<<13,this.seed^=this.seed>>>17,this.seed^=this.seed<<5,e+(t-e)*((this.seed>>>0)/2**32)}int(t,e=0){return Tt(this.float(t,e))}bool(t=.5){return this.float().5?1:-1}floatSign(t=1,e=0){let s=Q(t,e),o=$(t,e)-s,r=this.float(o*2);return rt?this.scale(t/e):this.copy()}dot(t){return this.x*t.x+this.y*t.y}cross(t){return this.x*t.y-this.y*t.x}reflect(t,e=1){return this.subtract(t.scale((1+e)*this.dot(t)))}angle(){return rr(this.x,this.y)}setAngle(t=0,e=1){return $t(t),$t(e),this.x=e*et(t),this.y=e*at(t),this}rotate(t){$t(t);let e=at(-t),s=et(-t);return new n(this.x*e-this.y*s,this.x*s+this.y*e)}setDirection(t,e=1){return $t(t),$t(e),t=se(t,4),f(t===0||t===1||t===2||t===3,"Vector2.setDirection() direction must be an integer between 0 and 3."),this.x=t%2?t-1?-e:e:0,this.y=t%2?0:t?-e:e,this}direction(){return tt(this.x)>tt(this.y)?this.x<0?3:1:this.y<0?2:0}abs(){return new n(tt(this.x),tt(this.y))}floor(){return new n(Tt(this.x),Tt(this.y))}snap(t){return $t(t),new n(Tt(this.x*t)/t,Tt(this.y*t)/t)}mod(t=1){return new n(se(this.x,t),se(this.y,t))}area(){return tt(this.x*this.y)}lerp(t,e){_a(t),$t(e);let s=B(e);return new n(t.x*s+this.x*(1-s),t.y*s+this.y*(1-s))}arrayCheck(t){return this.x>=0&&this.y>=0&&this.x(u=se(u,1))*6<1?c+(l-c)*6*u:u*2<1?l:u*3<2?c+(l-c)*(4-u*6):c;return this.r=a(r,o,t+1/3),this.g=a(r,o,t),this.b=a(r,o,t-1/3),this.a=i,os(this),this}HSLA(){let t=B(this.r),e=B(this.g),s=B(this.b),i=B(this.a),o=$(t,e,s),r=Q(t,e,s),a=(o+r)/2,c=0,l=0;if(o!==r){let u=o-r;l=a>.5?u/(2-o-r):u/(o+r),t===o?c=(e-s)/u+(e((s=B(s)*255|0)<16?"0":"")+s.toString(16);return"#"+e(this.r)+e(this.g)+e(this.b)+(t?e(this.a):"")}setHex(t){if(f(V(t),"Color hex code must be a string"),f(t[0]==="#","Color hex code must start with #"),f([4,5,7,9].includes(t.length),"Invalid hex"),t.length<6){let e=s=>B(parseInt(t[s],16)/15);this.r=e(1),this.g=e(2),this.b=e(3),this.a=t.length===5?e(4):1}else{let e=s=>B(parseInt(t.slice(s,s+2),16)/255);this.r=e(1),this.g=e(3),this.b=e(5),this.a=t.length===9?e(7):1}return os(this),this}rgbaInt(){let t=B(this.r)*255|0,e=B(this.g)*255<<8,s=B(this.b)*255<<16,i=B(this.a)*255<<24;return t+e+s+i}isValid(){return R(this.r)&&R(this.g)&&R(this.b)&&R(this.a)}},W=te(z()),ln=te(z(1,1,1,0)),nt=te(z(0,0,0)),pe=te(z(0,0,0,0)),Xl=te(z(.5,.5,.5)),lr=te(z(1,0,0)),Yl=te(z(1,.5,0)),ec=te(z(1,1,0)),nc=te(z(0,1,0)),$l=te(z(0,1,1)),sc=te(z(0,0,1)),ic=te(z(.5,0,1)),Kl=te(z(1,0,1)),Ae=class{constructor(t,e=!1){f(t===void 0||R(t),"Constructed Timer is invalid.",t),this.useRealTime=e;let s=this.getGlobalTime();this.time=t===void 0?void 0:s+t,this.setTime=t}set(t=0){f(R(t),"Timer is invalid.",t);let e=this.getGlobalTime();this.time=e+t,this.setTime=t}setUseRealTime(t=!0){f(!this.isSet(),"Cannot change global time setting while timer is set."),this.useRealTime=t}unset(){this.time=void 0}isSet(){return this.time!==void 0}active(){return this.getGlobalTime()=this.time}get(){return this.isSet()?this.getGlobalTime()-this.time:0}getPercent(){return this.isSet()?this.setTime?1-Ft(this.time-this.getGlobalTime(),0,this.setTime):1:0}getSetTime(){return this.isSet()?this.setTime:0}getGlobalTime(){return this.useRealTime?cn:Qt}toString(){return this.isSet()?tt(this.get())+" seconds "+(this.get()<0?"before":"after"):"unset"}valueOf(){return this.get()}};Et=b(),K=0,H=32,hr=1,Oi=!0,sn=pe,kn=b(1920,1080),as=0,Gn=0,Fn=b(),dr=!1,Cn=!0,on=1,Ls="arial",fr=!1,N=!1,G=!0,Os=32,Di=b(16),Mi=0,Ii=0,ki=!0,pr=1,yr=1,gr=1,mr=0,br=.8,ke=1,Wt=b(),ei=1,Gi=!0,xr=!0,cs=!0,bn=!0,un=!1,vr=!1,fe=0,$n=4,Pn=!0,Kn=0,Qn=!1,Ds=!0,dn=!1,Ht=100,Sr=.3,ls=3,ni=0,Ms=!0,Xt=!0,Tn=.3,wr=40,Tr=.7;ze=class n{constructor(t=b(),e=b(1),s,i=0,o=W,r=0){f(L(t),"object pos must be a vec2"),f(L(e),"object size must be a vec2"),f(!s||s instanceof Ee,"object tileInfo should be a TileInfo or undefined"),f(typeof i=="number"&&isFinite(i),"object angle should be a number"),f(J(o),"object color should be a valid rgba color"),f(typeof r=="number","object renderOrder should be a number"),this.pos=t.copy(),this.size=e.copy(),this.drawSize=void 0,this.tileInfo=s,this.angle=i,this.color=o.copy(),this.additiveColor=void 0,this.mirror=!1,this.destroyed=!1,this.mass=pr,this.damping=yr,this.angleDamping=gr,this.restitution=mr,this.friction=br,this.gravityScale=1,this.renderOrder=r,this.velocity=b(),this.angleVelocity=0,this.spawnTime=Qt,this.children=[],this.clampSpeed=!0,this.groundObject=void 0,this.parent=void 0,this.localPos=b(),this.localAngle=0,this.collideTiles=!1,this.collideSolidObjects=!1,this.isSolid=!1,this.collideRaycast=!1,St.push(this)}updateTransforms(){let t=this.parent;if(t){let e=t.getMirrorSign(),s=this.localPos,i=t.pos,o=s.x*e,r=s.y,a=t.angle;if(a){let c=at(-a),l=et(-a);this.pos.set(o*c-r*l+i.x,o*l+r*c+i.y)}else this.pos.set(o+i.x,r+i.y);this.angle=e*this.localAngle+a}for(let e of this.children)e.updateTransforms()}updatePhysics(){if(f(!this.parent),this.destroyed)return;this.clampSpeed&&(this.velocity.x=B(this.velocity.x,-ke,ke),this.velocity.y=B(this.velocity.y,-ke,ke));let t=this.pos.copy();if(this.velocity.x*=this.damping,this.velocity.y*=this.damping,this.mass&&(this.velocity.x+=Wt.x*this.gravityScale,this.velocity.y+=Wt.y*this.gravityScale),this.pos.x+=this.velocity.x,this.pos.y+=this.velocity.y,this.angle+=this.angleVelocity*=this.angleDamping,f(this.angleDamping>=0&&this.angleDamping<=1),f(this.damping>=0&&this.damping<=1),!ki||!this.mass)return;let e=this.velocity.y<0&&Wt.y<0||this.velocity.y>0&&Wt.y>0;if(this.groundObject){let s=$(this.friction,this.groundObject.friction),i=this.groundObject.velocity.x;this.velocity.x=i+(this.velocity.x-i)*s,this.groundObject=void 0}if(this.collideSolidObjects)for(let i of ir){if(i.destroyed||i.parent||i===this||!this.isSolid&&!i.isSolid||!this.isOverlappingObject(i))continue;let o=this.collideWithObject(i),r=i.collideWithObject(this);if(!o||!r)continue;if(ti(t,this.size,i.pos,i.size)){let p=t.subtract(i.pos),d=p.length(),x=d<.001?b(0,1):p.scale(.001/d);this.velocity=this.velocity.add(x),i.mass&&(i.velocity=i.velocity.subtract(x)),ue&&go(this.pos,this.size,i.pos,i.size,"#f00");continue}let a=this.size.add(i.size),c=(t.y-i.pos.y)*2>a.y+Wt.y,l=tt(t.y-i.pos.y)*20?-1:1)>0?Tt(t.y-this.size.y/2+1)+this.size.y/2+.001:ds(t.y+this.size.y/2-1)-this.size.y/2-.001;if(tt(u-this.pos.y)<.1&&!Ze(b(this.pos.x,u),this.size,this)){this.pos.y=u,ue&&bt(this.pos,this.size,"#ff0");return}this.pos.x=t.x,this.velocity.x*=-r}if(o||!i){if(e){let c=this.size.y/2+1e-4;this.pos.y=Wt.y<0?Tt(t.y-this.size.y/2)+c:ds(t.y+this.size.y/2)-c,this.groundObject=s}else this.pos.y=t.y,this.groundObject=void 0;this.velocity.y*=-r}ue&&bt(this.pos,this.size,"#f00")}}}update(){}render(){Ot(this.pos,this.drawSize||this.size,this.tileInfo,this.color,this.angle,this.mirror,this.additiveColor)}renderLight(){}destroy(t=!1){var e;if(!this.destroyed){this.destroyed=!0,(e=this.parent)==null||e.removeChild(this);for(let s of this.children)s.parent=void 0,s.destroy(t)}}localToWorld(t){return this.pos.add(t.rotate(this.angle))}worldToLocal(t){return t.subtract(this.pos).rotate(-this.angle)}localToWorldVector(t){return t.rotate(this.angle)}worldToLocalVector(t){return t.rotate(-this.angle)}collideWithTile(t,e){return t>0}collideWithObject(t){return!0}getUp(t=1){return b().setAngle(this.angle,t)}getRight(t=1){return b().setAngle(this.angle+X/2,t)}getAliveTime(){return Qt-this.spawnTime}getSpeed(){return this.velocity.length()}applyAcceleration(t){this.mass&&(this.velocity=this.velocity.add(t))}applyAngularAcceleration(t){this.mass&&(this.angleVelocity+=t)}applyForce(t){this.mass&&this.applyAcceleration(t.scale(1/this.mass))}getMirrorSign(){return this.mirror?-1:1}addChild(t,e=b(),s=0){return f(!this.destroyed,"cannot add child to destroyed object"),this.destroyed||(f(!t.parent&&!this.children.includes(t)),f(t instanceof n,"child must be an EngineObject"),f(t!==this,"cannot add self as child"),this.children.push(t),t.parent=this,t.localPos=e.copy(),t.localAngle=s,t.updateTransforms()),t}removeChild(t){f(t.parent===this&&this.children.includes(t)),this.children.splice(this.children.indexOf(t),1),t.parent=void 0}isOverlappingObject(t){return this.isOverlapping(t.pos,t.size)}isOverlapping(t,e=b()){return ti(this.pos,this.size,t,e)}setCollision(t=!0,e=!0,s=!0,i=!0){f(t||!e,"solid objects must be set to collide"),this.collideSolidObjects=t,this.isSolid=e,this.collideTiles=s,this.collideRaycast=i}toString(){let t="type = "+this.constructor.name;return(this.pos.x||this.pos.y)&&(t+=`
+precision highp float;in vec4 d;out vec4 c;void main(){c=d;}`);let e=new ArrayBuffer(us);Gt=new Float32Array(e),gi=new Uint32Array(e),mo=g.createBuffer(),Mn=g.createBuffer(),Or=g.createFramebuffer(),_t=0;let i=new Float32Array([0,0,1,0,0,1,1,1]);g.bindBuffer(g.ARRAY_BUFFER,Mn),g.bufferData(g.ARRAY_BUFFER,i,g.STATIC_DRAW);let s,o,a,r=(c,l,u,h,f=0)=>{let d=g.getAttribLocation(o,c),y=u===1,x=u&&a;g.enableVertexAttribArray(d),g.vertexAttribPointer(d,h,l,y,x,s),g.vertexAttribDivisor(d,f),s+=h*u};bo=g.createVertexArray(),g.bindVertexArray(bo),s=0,o=as,a=pc,g.bindBuffer(g.ARRAY_BUFFER,Mn),r("g",g.FLOAT,0,2),g.bindBuffer(g.ARRAY_BUFFER,mo),g.bufferData(g.ARRAY_BUFFER,us,g.DYNAMIC_DRAW),r("p",g.FLOAT,4,4,1),r("u",g.FLOAT,4,4,1),r("c",g.UNSIGNED_BYTE,1,4,1),r("a",g.UNSIGNED_BYTE,1,4,1),r("r",g.FLOAT,4,1,1),xo=g.createVertexArray(),g.bindVertexArray(xo),s=0,o=cs,a=gc,r("p",g.FLOAT,4,2),r("c",g.UNSIGNED_BYTE,1,4)}}function yi(n=!1){!n&&!xn||(Rt(),xn=!1,g.useProgram(as),g.bindVertexArray(bo))}function yc(){xn||(Rt(),xn=!0,g.useProgram(cs),g.bindVertexArray(xo))}function So(n=!0){if(!B||!g)return;p(!_t,"glPreRender called with unflushed batch."),ls||(et.width=G.x,et.height=G.y),g.viewport(0,0,G.x,G.y),n&&mc();let t=b(2*X).divide(G);ls&&(t.y=-t.y);let e=Ct.rotate(-Q),i=b(-1).subtract(e.multiply(t)),s=at(Q),o=it(Q),a=[t.x*s,t.y*o,0,0,-t.x*o,t.y*s,0,0,1,1,1,0,i.x,i.y,0,1],r=(c,l,u)=>{g.useProgram(c);let h=g.getUniformLocation(c,l);g.uniformMatrix4fv(h,!1,u)};r(cs,"m",a),r(as,"m",a),g.activeTexture(g.TEXTURE0),nn[0]&&(Kt=nn[0].glTexture,g.bindTexture(g.TEXTURE_2D,Kt)),g.bindBuffer(g.ARRAY_BUFFER,mo),En=Nn=!1,yi(!0)}function mc(){if(!g)return;let n=Ye;g.clearColor(n.r,n.g,n.b,n.a),g.clear(g.COLOR_BUFFER_BIT)}function Mr(n){!g||n===Kt||(Rt(),Kt=n,g.bindTexture(g.TEXTURE_2D,Kt))}function bc(n,t=!0){if(!g||!n)return;let e=n===Kt;e?Rt():g.bindTexture(g.TEXTURE_2D,n);let i=t?g.REPEAT:g.CLAMP_TO_EDGE;g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_S,i),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_T,i),!e&&Kt&&g.bindTexture(g.TEXTURE_2D,Kt)}function wo(n,t){if(!g)return;let e=g.createShader(t);if(g.shaderSource(e,n),g.compileShader(e),Ft&&!g.getShaderParameter(e,g.COMPILE_STATUS))throw g.getShaderInfoLog(e);return e}function zn(n,t){if(!g)return;let e=g.createProgram();if(g.attachShader(e,wo(n,g.VERTEX_SHADER)),g.attachShader(e,wo(t,g.FRAGMENT_SHADER)),g.linkProgram(e),Ft&&!g.getProgramParameter(e,g.LINK_STATUS))throw g.getProgramInfoLog(e);return e}function Ms(n,t=!1){if(!g)return;let e=g.createTexture(),i=!1;if(n!=null&&n.width)Ir(e,n),g.bindTexture(g.TEXTURE_2D,e),i=!mn&&oi(n.width)&&oi(n.height);else{let r=new Uint8Array([255,255,255,255]);g.bindTexture(g.TEXTURE_2D,e),g.texImage2D(g.TEXTURE_2D,0,g.RGBA,1,1,0,g.RGBA,g.UNSIGNED_BYTE,r)}let s=mn?g.NEAREST:g.LINEAR,o=i?g.LINEAR_MIPMAP_LINEAR:s;g.texParameteri(g.TEXTURE_2D,g.TEXTURE_MAG_FILTER,s),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_MIN_FILTER,o);let a=t?g.REPEAT:g.CLAMP_TO_EDGE;return g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_S,a),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_T,a),i&&g.generateMipmap(g.TEXTURE_2D),g.bindTexture(g.TEXTURE_2D,Kt),e}function xc(n){g&&g.deleteTexture(n)}function Ir(n,t){g&&(p((t==null?void 0:t.width)>0,"Invalid image data."),g.bindTexture(g.TEXTURE_2D,n),g.texImage2D(g.TEXTURE_2D,0,g.RGBA,g.RGBA,g.UNSIGNED_BYTE,t),!mn&&oi(t.width)&&oi(t.height)&&g.generateMipmap(g.TEXTURE_2D),g.bindTexture(g.TEXTURE_2D,Kt))}function Hh(n){J||(ii.add(n),g&&(n.glTexture?Ir(n.glTexture,n.image):n.glTexture=Ms(n.image,n.wrap)))}function Xh(n){if(J)return;ii.delete(n);let t=n.glTexture;n.glTexture=void 0,xc(t)}function Rt(){if(B&&g&&_t){let n=Nn?g.ONE:g.ONE_MINUS_SRC_ALPHA;g.blendFuncSeparate(g.SRC_ALPHA,n,g.ONE,n),g.enable(g.BLEND);let t=_t*(xn?Ds:Dr);g.bufferSubData(g.ARRAY_BUFFER,0,Gt,0,t),xn?g.drawArrays(g.TRIANGLE_STRIP,0,_t):g.drawArraysInstanced(g.TRIANGLE_STRIP,0,4,_t),++Te,Ae+=_t,_t=0}Nn=En}function kr(n){!B||!g||(Rt(),n.drawImage(et,0,0))}function Yh(n=!0){p(!et,"must be called before engineInit"),Lr=n}function mi(n,t,e,i,s=0,o=0,a=0,r=1,c=1,l=-1,u=0){(_t>=Wh||Nn!==En)&&Rt(),yi();let h=_t++*Dr;Gt[h++]=n,Gt[h++]=t,Gt[h++]=e,Gt[h++]=i,Gt[h++]=o,Gt[h++]=a,Gt[h++]=r,Gt[h++]=c,gi[h++]=l,gi[h++]=u,Gt[h++]=s}function vc(n,t,e,i,s,o){mi(n,t,e,i,s,0,0,0,0,0,o)}function Gr(n,t,e,i,s,o,a,r=!0){let c=[],l=it(-a),u=at(-a);for(let f of n){let d=f.x*s,y=f.y*o;c.push(b(e+u*d-l*y,i+l*d+u*y))}let h=r?Kh(c):c;Sc(h,t)}function Fr(n,t,e,i,s,o,a,r,c=!0){let l=$h(n,e,c);Gr(l,t,i,s,o,a,r,!1)}function Sc(n,t){if(!B||n.length<3)return;let e=n.length+2;if((_t+e>=In||Nn!==En)&&Rt(),p(e=In)return;yc();let i=_t*Ds;for(let s=e;s--;){let o=z(s-1,0,e-3),a=n[o];Gt[i++]=a.x,Gt[i++]=a.y,gi[i++]=t}_t+=e}function jr(n,t){if(!B||n.length<3)return;let e=n.length+2;if((_t+e>=In||Nn!==En)&&Rt(),p(e=In)return;yc();let i=_t*Ds;for(let s=e;s--;){let o=z(s-1,0,e-3),a=n[o],r=t[o];Gt[i++]=a.x,Gt[i++]=a.y,gi[i++]=r}_t+=e}function Qn(n,t=!1){n?(ls=n,g.bindFramebuffer(g.FRAMEBUFFER,Or),g.framebufferTexture2D(g.FRAMEBUFFER,g.COLOR_ATTACHMENT0,g.TEXTURE_2D,n,0),So(t)):(Rt(),ls=void 0,g.bindFramebuffer(g.FRAMEBUFFER,null),g.viewport(0,0,G.x,G.y))}function wc(n,t,e,i){B&&(g.enable(g.SCISSOR_TEST),g.scissor(n,t,e,i),g.clearColor(0,0,0,0),g.clear(g.COLOR_BUFFER_BIT),g.disable(g.SCISSOR_TEST))}function $h(n,t,e=!0){if(n.length<2)return[];let i=t/2,s=[],o=n.length,a=1e-6,r=10;for(let c=0;ca?-d/y:0,S=y>a?f/y:0,_=w>a?-v/w:0,A=w>a?x/w:0,T=C+_,L=S+A,F=(T*T+L*L)**.5;if(Fa){let k=Z(1/I,r);T*=k,L*=k}}let ft=b(u.x-T*i,u.y-L*i),D=b(u.x+T*i,u.y+L*i);s.push(ft),s.push(D)}return s.length>1&&e&&(s.push(s[0]),s.push(s[1])),s}function Kh(n){if(n.length<3)return[];let t=(d,y,x)=>(y.x-d.x)*(x.y-d.y)-(y.y-d.y)*(x.x-d.x);(d=>{let y=0;for(let x=d.length;x--;){let v=(x+1)%d.length;y+=d[x].cross(d[v])}return y})(n)<0&&(n=n.slice().reverse());let i=1e-9,s=(d,y,x,v)=>{let w=t(y,x,d),C=t(x,v,d),S=t(v,y,d),_=(w<-i?1:0)+(C<-i?1:0)+(S<-i?1:0),A=(w>i?1:0)+(C>i?1:0)+(S>i?1:0);return!(_&&A)},o=[];for(let d=0;d3&&r++{if(_>=0){let T=i.fillStyle=i.createLinearGradient(v,w,C,S);T.addColorStop(0,h(_,2)),T.addColorStop(1,h(_,1))}else i.fillStyle="#000";_>=-1?(i.fill(),A&&i.stroke()):i.stroke()},c=(v,w,C,S=0,_=2*Y,A,T)=>{i.beginPath(),i.arc(v,w,C,d*S,d*_),r(v,w-C,v,w+C,A,T)},l=(v,w,C,S,_)=>{i.beginPath(),i.rect(v,w,C,S*d),r(v,w+S,v+C,w,_)},u=(v,w,C,S)=>{i.beginPath();for(let _ of v)i.lineTo(_.x,_.y);i.closePath(),r(0,C,0,C+S,w)},h=(v,w)=>w?`hsl(${[.95,.56,.13][v%3]*360} 99%${[0,50,75][w]}%)`:"#000",f=Ja(1,1,n),d=jt(f,.1,.5),y=Z(6,Z(o,a)/99);i.translate(o/2,a/2),i.scale(y,y),i.translate(-40,-35),d<1&&i.setLineDash([99*d,99]),i.lineJoin=i.lineCap="round",i.lineWidth=.1+d*1.9;{let w="LittleJS";i.font="900 15.5px arial",i.lineWidth=.1+d*3.9,i.textAlign="center",i.textBaseline="top",l(11,55,59,8*d,-1),i.beginPath();let C=0;for(let S=0;S5?1:0),i[S?"strokeText":"fillText"](w[_],L,54+.5,17*d),A+=T}i.lineWidth=.1+d*1.9,l(3,54,73,0)}l(7,15,26,-7,0),l(25,15,8,25,-1),l(10,40,15,-25,1),l(14,21,7,9,2),l(38,20,6,-6,2),l(49,20,10,-6,0);let x=[b(44,8),b(64,8),b(59,8+6*d),b(49,8+6*d)];u(x,2,8,6*d),l(44,8,20,-7,0);for(let v=5;v--;)c(59-v*6*d,30,10,0,2*Y,1,0);c(59,30,4,0,7,2),l(35,20,24,0),c(59,30,10),c(47,30,10,Y/2,Y*3/2),c(35,30,10,Y/2,Y*3/2),l(7,40,13,7,-1),l(17,40,43,14,-1);for(let v=3;v--;)for(let w=2;w--;)c(17+15*v,47,w?7:1,0,2*Y,2);for(let v=2;v--;){let w=6,C=7,S=53+w*d*v,_=[b(S+C,54),b(S,40),b(S+w*d,40),b(S+C+w*d,54)];u(_,0,40,14)}i.restore()}function Zh(n){if(fs=n,!an){let e={};try{e=JSON.parse(localStorage[n]||"{}")}catch{e={}}Is(i=>{i.unlocked=!!(e[i.id]&&e[i.id].unlocked)}),Nr()}vn(void 0,t);function t(){if(!zi.length)return;let e=zi[0],i=Ze-Ni;if(!Ni)Ni=Ze;else if(i>hs)Ni=0,zi.shift();else{let s=hs-On,o=is?(i-s)/On:0;e.render(o)}}}function Is(n){Object.values(bi).forEach(t=>n(t))}function td(){Is(n=>n.unlocked=!1),Nr()}function Nr(){if(!fs)return;let n={};Is(t=>{let e={name:t.name,description:t.description,icon:t.icon,unlocked:t.unlocked};t.image&&(e.src=t.image.src),n[t.id]=e}),localStorage[fs]=JSON.stringify(n)}function ed(n){hs=n}function nd(n){On=n}function id(n){ds=n.copy()}function sd(n){Br=n}function Tc(n,t,e,i=125){let s,o,a,r,c,l,u,h,f,d,y,x,v,w=0,C,S=[],_=[],A=[],T=0,L=0,F=1,ft={},D=Wn/i*60>>2;for(;F;T++)S=[F=h=x=0],e.forEach((I,k)=>{for(u=t[I][T]||[0,0,0],F|=t[I][T]&&1,C=x+(t[I][0].length-2-(h?0:1))*D,v=k===e.length-1,s=2,a=x;sD-99&&f&&y<1?y+=1/99:0)l=(1-y)*S[w++]/2||0,_[a]=(_[a]||0)-l*L+l,A[a]=(A[a++]||0)+l*L+l;c&&(y=c%1,L=u[1]||0,(c|=0)&&(S=ft[[d=u[w=0]||0,c]]=ft[[d,c]]||(r=[...n[d]],r[2]=(r[2]||220)*2**(c/12-1),c>0?Os(...r):[])))}x=C});return[_,A]}function od(n){zr=typeof n=="boolean"?n?1:0:n}function rd(n){Jr=n}async function ad(){return new xs(await Box2D()),e(),vn(n,t),m;function n(){if(!Se){m.step(),m.objects=m.objects.filter(i=>!i.destroyed);for(let i of m.objects)i.body&&(i.pos=m.vec2From(i.body.GetPosition()),i.angle=-i.body.GetAngle())}}function t(){(Jr||ce)&&m.world.DrawDebugData()}function e(){let s=new m.instance.JSDraw,o=l=>new Tt(l.get_r(),l.get_g(),l.get_b()),a=l=>o(m.instance.wrapPointer(l,m.instance.b2Color)),r=l=>a(l).scale(1,.8),c=(l,u)=>{let h=[];for(let f=u;f--;)h.push(m.vec2FromPointer(l+f*8));return h};s.DrawSegment=function(l,u,h){h=r(h),l=m.vec2FromPointer(l),u=m.vec2FromPointer(u),hn(l,u,.1,h,b(),0,!1)},s.DrawPolygon=function(l,u,h){h=r(h);let f=c(l,u);Gn(f,tn,.1,h,b(),0,!1)},s.DrawSolidPolygon=function(l,u,h){h=r(h);let f=c(l,u);Gn(f,h,0,h,b(),0,!1)},s.DrawCircle=function(l,u,h){h=r(h),l=m.vec2FromPointer(l),Qi(l,u*2,tn,.1,h,!1)},s.DrawSolidCircle=function(l,u,h,f){f=r(f),l=m.vec2FromPointer(l),h=m.vec2FromPointer(h).scale(u),Qi(l,u*2,f,.1,f,!1),hn(b(),h,.1,f,l,0,!1)},s.DrawTransform=function(l){l=m.instance.wrapPointer(l,m.instance.b2Transform);let u=m.vec2From(l.get_p()),h=-l.get_q().GetAngle(),f=b(1,0),d=U(.75,0,0,.8),y=b(0,1),x=U(0,.75,0,.8);hn(b(),f,.1,d,u,h,!1),hn(b(),y,.1,x,u,h,!1)},s.AppendFlags(m.instance.b2Draw.e_shapeBit),s.AppendFlags(m.instance.b2Draw.e_jointBit),m.world.SetDebugDraw(s)}}function cd(n,t,e,i=32,s=2,o=0){Ac(n,t,e,q,i,st,s,o,!1,!0)}function Ac(n,t,e,i,s=1,o,a=.05,r=0,c=B,l,u){let h=e.offset(e.size),f=t.add(b(a-s*2)),d=b(s),y=t.scale(.5).subtract(d.scale(.5)),x=l?-1:1,v=l?-r:r;Dt(n,f,h,i,r,!1,o,c,l,u);for(let w=4;w--;){let C=w%2,S=y.multiply(b(C?w===1?1:-1:0,C?0:w?-1:1)),_=b(C?s:f.x,C?f.y:s),A=h.offset(e.size.multiply(b(w===1?1:w===3?-1:0,w===0?-x:w===2?x:0)));Dt(n.add(S.rotate(v)),_,A,i,r,!1,o,c,l,u)}for(let w=4;w--;){let C=w>1,S=w&&w<3,_=y.multiply(b(C?-1:1,S?-1:1)),A=h.offset(e.size.multiply(b(C?-1:1,S?x:-x)));Dt(n.add(_.rotate(v)),d,A,i,r,!1,o,c,l,u)}}function ld(n,t,e,i=32,s=2,o=0){Ec(n,t,e,q,i,st,s,o,!1,!0)}function Ec(n,t,e,i,s=1,o,a=.05,r=0,c=B,l,u){let h=e.frame(0),f=e.frame(1),d=e.frame(2),y=t.add(b(a-s*2)),x=b(s),v=t.scale(.5).subtract(x.scale(.5)),w=l?-1:1,C=l?-r:r;Dt(n,y,d,i,r,!1,o,c,l,u);for(let S=4;S--;){let _=r+S*Y/2,A=S%2,T=v.multiply(b(A?S===1?1:-1:0,A?0:S?-w:w)),L=b(A?y.y:y.x,s);Dt(n.add(T.rotate(C)),L,f,i,_,!1,o,c,l,u)}for(let S=4;S--;){let _=r+S*Y/2,A=!S||S>2,T=S>1,L=v.multiply(b(A?-1:1,T?-w:w));Dt(n.add(L.rotate(C)),x,h,i,_,!1,o,c,l,u)}}function ud(n,t=1,e=0,i=q,s=0,o=!1,a=0,r=st,c=B,l=!1,u){let h=_c(b(),t,e,0,o);Gn(h,i,a,r,n,s,c,l,u)}function _c(n,t=1,e=0,i=0,s=!1,o=Ti){p(O(n),"pos must be a vec2"),p(P(t)&&P(e),"size and percent must be numbers");let a=ee(e*4,4);a>=2&&(i+=Y),a=a<=2?a-1:3-a,s&&(a=-a,i+=Y);let r=[],c=K(3,o>>1),l=t/2;for(let u=0;u<=c;u++){let h=u/c*Y;r.push(b(l*at(h),l*it(h)).rotate(i).add(n))}for(let u=c;u>=0;u--){let h=u/c*Y;r.push(b(l*at(h),-l*a*it(h)).rotate(i).add(n))}return r}function Ca(n){return n&&typeof n.lerp=="function"}function hd(n,t,e,i,s=1,o={}){p(n!=null&&typeof n=="object","tweenProperty target must be an object"),p(W(t)&&t.length>0,"tweenProperty propertyPath must be a non-empty string");let a=t.split("."),r=a.pop(),c=l=>{let u=n;for(let h of a)u=u[h];u[r]=l};return new vs(c,e,i,s,o)}function Cc(n){n.loopRemaining!==1/0&&n.loopRemaining<=1||(n.loopRemaining!==1/0&&(n.loopRemaining-=1),n.life=n.duration,n.thenCallback=()=>Cc(n),Yt.push(n),n.callback(n.interp(n.duration)))}function Rc(n){if(n.loopRemaining!==1/0&&n.loopRemaining<=1)return;n.loopRemaining!==1/0&&(n.loopRemaining-=1);let t=n.start;n.start=n.end,n.end=t,n.life=n.duration,n.thenCallback=()=>Rc(n),Yt.push(n),n.callback(n.interp(n.duration))}function Pc(n,t){n===void 0?(n=$t-Ea,t=Ze-_a,Ea=$t,_a=Ze):t===void 0&&(t=n);for(let e=Yt.length;e--;){let i=Yt[e];if(i.paused)continue;let s=i.useRealTime?t:n;if(!(s<=0))if(i.life-=s,i.life>0)i.callback(i.interp(i.life));else{i.callback(i.interp(0)),Yt.splice(e,1);let o=i.thenCallback;i.thenCallback=void 0,o&&o()}}}function dd(){for(let n of Yt)n.thenCallback=void 0;Yt.length=0}var Ji,Ui,_l,$o,St,Ko,Ra,$t,Ze,Se,io,ge,Vi,Pa,dn,ro,Ft,Da,Ts,Ma,Re,Xe,ce,le,fn,pn,kn,ao,Pe,ae,Y,nt,wt,si,Wi,Z,K,te,Fa,ja,it,at,Ba,Zo,uo,rt,Tt,q,tn,st,de,Vl,nr,Wl,Xa,Ya,ql,$a,Ka,Hl,we,Ct,Q,X,sr,As,Ye,Cn,Zn,Rn,Pn,or,mn,$e,wi,rr,J,B,Ti,Es,_s,Cs,Rs,ar,cr,lr,ur,hr,Oe,Jt,Xi,Ps,dr,ti,un,en,fr,he,Jn,Sn,Un,Vn,Ai,sn,Vt,pr,ei,Yi,Ei,Wt,gn,gr,yr,Fe,N,lt,Et,Ie,qe,be,De,G,nn,Te,Ae,Ee,je,nh,rc,Zi,_e,Nt,xr,ye,vr,ts,Dn,He,Sr,Ln,mt,ne,$,me,cn,so,Fn,ie,bn,es,Li,Me,Ve,lc,_r,uc,ui,ln,jn,Sa,ns,dt,Ge,Wn,di,is,Qe,yn,os,fi,pi,yo,Vh,rs,et,g,Lr,as,cs,xn,En,Nn,Kt,mo,Mn,Gt,gi,_t,ii,bo,xo,Or,ls,vo,us,Dr,pc,Wh,Ds,gc,In,an,hs,On,ds,Br,bi,zi,fs,Ni,ps,xi,To,Ao,It,Eo,H,_o,Co,Ro,E,zr,Po,se,gs,Lo,Oo,vi,Do,Mo,Io,ko,m,Jr,Si,ys,Go,Fo,ms,qt,jo,bs,Bo,No,zo,Jo,Uo,Vo,Wo,qo,Ho,Xo,xs,Yt,Ea,_a,vs,Ss,fd,oo,ws,Yo,Oc=jc(()=>{"use strict";Ji="LittleJS",Ui="1.18.19",_l=60,$o=.016666666666666666,St=[],Ko=[],Ra=0,$t=0,Ze=0,Se=!1;io=0,ge=0,Vi=0,Pa=!0,dn=[],ro=class{constructor(t,e,i,s){this.update=t,this.render=e,this.glContextLost=i,this.glContextRestored=s}};Ft=!0,Da=.5,Ts=!0,Ma="Escape",Re=!1,Xe=[],ce=!1,le=!1,fn=!1,pn=!1,kn=!1;Y=Math.PI,nt=Math.abs,wt=Math.floor,si=Math.ceil,Wi=Math.round,Z=Math.min,K=Math.max,te=n=>Math.sign(n),Fa=(...n)=>Math.hypot(...n),ja=n=>Math.log2(n),it=Math.sin,at=Math.cos,Ba=Math.tan,Zo=Math.atan2;uo=class{constructor(t=123456789){p(t!==0,"RandomGenerator seed must be non-zero (xorshift is fixed at 0)"),this.seed=t}float(t=1,e=0){return this.seed^=this.seed<<13,this.seed^=this.seed>>>17,this.seed^=this.seed<<5,e+(t-e)*((this.seed>>>0)/2**32)}int(t,e=0){return wt(this.float(t,e))}bool(t=.5){return this.float().5?1:-1}floatSign(t=1,e=0){let i=Z(t,e),o=K(t,e)-i,a=this.float(o*2);return at?this.scale(t/e):this.copy()}dot(t){return this.x*t.x+this.y*t.y}cross(t){return this.x*t.y-this.y*t.x}reflect(t,e=1){return this.subtract(t.scale((1+e)*this.dot(t)))}angle(){return Zo(this.x,this.y)}setAngle(t=0,e=1){return Xt(t),Xt(e),this.x=e*it(t),this.y=e*at(t),this}rotate(t){Xt(t);let e=at(-t),i=it(-t);return new n(this.x*e-this.y*i,this.x*i+this.y*e)}setDirection(t,e=1){return Xt(t),Xt(e),t=ee(t,4),p(t===0||t===1||t===2||t===3,"Vector2.setDirection() direction must be an integer between 0 and 3."),this.x=t%2?t-1?-e:e:0,this.y=t%2?0:t?-e:e,this}direction(){return nt(this.x)>nt(this.y)?this.x<0?3:1:this.y<0?2:0}abs(){return new n(nt(this.x),nt(this.y))}floor(){return new n(wt(this.x),wt(this.y))}snap(t){return Xt(t),new n(wt(this.x*t)/t,wt(this.y*t)/t)}mod(t=1){return new n(ee(this.x,t),ee(this.y,t))}area(){return nt(this.x*this.y)}lerp(t,e){xa(t),Xt(e);let i=z(e);return new n(t.x*i+this.x*(1-i),t.y*i+this.y*(1-i))}arrayCheck(t){return this.x>=0&&this.y>=0&&this.x(u=ee(u,1))*6<1?c+(l-c)*6*u:u*2<1?l:u*3<2?c+(l-c)*(4-u*6):c;return this.r=r(a,o,t+1/3),this.g=r(a,o,t),this.b=r(a,o,t-1/3),this.a=s,Kn(this),this}HSLA(){let t=z(this.r),e=z(this.g),i=z(this.b),s=z(this.a),o=K(t,e,i),a=Z(t,e,i),r=(o+a)/2,c=0,l=0;if(o!==a){let u=o-a;l=r>.5?u/(2-o-a):u/(o+a),t===o?c=(e-i)/u+(e((i=z(i)*255|0)<16?"0":"")+i.toString(16);return"#"+e(this.r)+e(this.g)+e(this.b)+(t?e(this.a):"")}setHex(t){if(p(W(t),"Color hex code must be a string"),p(t[0]==="#","Color hex code must start with #"),p([4,5,7,9].includes(t.length),"Invalid hex"),t.length<6){let e=i=>z(parseInt(t[i],16)/15);this.r=e(1),this.g=e(2),this.b=e(3),this.a=t.length===5?e(4):1}else{let e=i=>z(parseInt(t.slice(i,i+2),16)/255);this.r=e(1),this.g=e(3),this.b=e(5),this.a=t.length===9?e(7):1}return Kn(this),this}rgbaInt(){let t=z(this.r)*255|0,e=z(this.g)*255<<8,i=z(this.b)*255<<16,s=z(this.a)*255<<24;return t+e+i+s}isValid(){return P(this.r)&&P(this.g)&&P(this.b)&&P(this.a)}},q=Qt(U()),tn=Qt(U(1,1,1,0)),st=Qt(U(0,0,0)),de=Qt(U(0,0,0,0)),Vl=Qt(U(.5,.5,.5)),nr=Qt(U(1,0,0)),Wl=Qt(U(1,.5,0)),Xa=Qt(U(1,1,0)),Ya=Qt(U(0,1,0)),ql=Qt(U(0,1,1)),$a=Qt(U(0,0,1)),Ka=Qt(U(.5,0,1)),Hl=Qt(U(1,0,1)),we=class{constructor(t,e=!1){p(t===void 0||P(t),"Constructed Timer is invalid.",t),this.useRealTime=e;let i=this.getGlobalTime();this.time=t===void 0?void 0:i+t,this.setTime=t}set(t=0){p(P(t),"Timer is invalid.",t);let e=this.getGlobalTime();this.time=e+t,this.setTime=t}setUseRealTime(t=!0){p(!this.isSet(),"Cannot change global time setting while timer is set."),this.useRealTime=t}unset(){this.time=void 0}isSet(){return this.time!==void 0}active(){return this.getGlobalTime()=this.time}get(){return this.isSet()?this.getGlobalTime()-this.time:0}getPercent(){return this.isSet()?this.setTime?1-jt(this.time-this.getGlobalTime(),0,this.setTime):1:0}getSetTime(){return this.isSet()?this.setTime:0}getGlobalTime(){return this.useRealTime?Ze:$t}toString(){return this.isSet()?nt(this.get())+" seconds "+(this.get()<0?"before":"after"):"unset"}valueOf(){return this.get()}};Ct=b(),Q=0,X=32,sr=1,As=!0,Ye=de,Cn=b(1920,1080),Zn=0,Rn=0,Pn=b(),or=!1,mn=!0,$e=1,wi="arial",rr=!1,J=!1,B=!0,Ti=32,Es=b(16),_s=0,Cs=0,Rs=!0,ar=1,cr=1,lr=1,ur=0,hr=.8,Oe=1,Jt=b(),Xi=1,Ps=!0,dr=!0,ti=!0,un=!0,en=!1,fr=!1,he=0,Jn=4,Sn=!0,Un=0,Vn=!1,Ai=!0,sn=!1,Vt=100,pr=.3,ei=3,Yi=0,Ei=!0,Wt=!0,gn=.3,gr=40,yr=.7;Fe=class n{constructor(t=b(),e=b(1),i,s=0,o=q,a=0){p(O(t),"object pos must be a vec2"),p(O(e),"object size must be a vec2"),p(!i||i instanceof Ee,"object tileInfo should be a TileInfo or undefined"),p(typeof s=="number"&&isFinite(s),"object angle should be a number"),p(V(o),"object color should be a valid rgba color"),p(typeof a=="number","object renderOrder should be a number"),this.pos=t.copy(),this.size=e.copy(),this.drawSize=void 0,this.tileInfo=i,this.angle=s,this.color=o.copy(),this.additiveColor=void 0,this.mirror=!1,this.destroyed=!1,this.mass=ar,this.damping=cr,this.angleDamping=lr,this.restitution=ur,this.friction=hr,this.gravityScale=1,this.renderOrder=a,this.velocity=b(),this.angleVelocity=0,this.spawnTime=$t,this.children=[],this.clampSpeed=!0,this.groundObject=void 0,this.parent=void 0,this.localPos=b(),this.localAngle=0,this.collideTiles=!1,this.collideSolidObjects=!1,this.isSolid=!1,this.collideRaycast=!1,St.push(this)}updateTransforms(){let t=this.parent;if(t){let e=t.getMirrorSign(),i=this.localPos,s=t.pos,o=i.x*e,a=i.y,r=t.angle;if(r){let c=at(-r),l=it(-r);this.pos.set(o*c-a*l+s.x,o*l+a*c+s.y)}else this.pos.set(o+s.x,a+s.y);this.angle=e*this.localAngle+r}for(let e of this.children)e.updateTransforms()}updatePhysics(){if(p(!this.parent),this.destroyed)return;this.clampSpeed&&(this.velocity.x=z(this.velocity.x,-Oe,Oe),this.velocity.y=z(this.velocity.y,-Oe,Oe));let t=this.pos.copy();if(this.velocity.x*=this.damping,this.velocity.y*=this.damping,this.mass&&(this.velocity.x+=Jt.x*this.gravityScale,this.velocity.y+=Jt.y*this.gravityScale),this.pos.x+=this.velocity.x,this.pos.y+=this.velocity.y,this.angle+=this.angleVelocity*=this.angleDamping,p(this.angleDamping>=0&&this.angleDamping<=1),p(this.damping>=0&&this.damping<=1),!Rs||!this.mass)return;let e=this.velocity.y<0&&Jt.y<0||this.velocity.y>0&&Jt.y>0;if(this.groundObject){let i=K(this.friction,this.groundObject.friction),s=this.groundObject.velocity.x;this.velocity.x=s+(this.velocity.x-s)*i,this.groundObject=void 0}if(this.collideSolidObjects)for(let s of Ko){if(s.destroyed||s.parent||s===this||!this.isSolid&&!s.isSolid||!this.isOverlappingObject(s))continue;let o=this.collideWithObject(s),a=s.collideWithObject(this);if(!o||!a)continue;if(Hi(t,this.size,s.pos,s.size)){let f=t.subtract(s.pos),d=f.length(),x=d<.001?b(0,1):f.scale(.001/d);this.velocity=this.velocity.add(x),s.mass&&(s.velocity=s.velocity.subtract(x)),ce&&co(this.pos,this.size,s.pos,s.size,"#f00");continue}let r=this.size.add(s.size),c=(t.y-s.pos.y)*2>r.y+Jt.y,l=nt(t.y-s.pos.y)*20?-1:1)>0?wt(t.y-this.size.y/2+1)+this.size.y/2+.001:si(t.y+this.size.y/2-1)-this.size.y/2-.001;if(nt(u-this.pos.y)<.1&&!We(b(this.pos.x,u),this.size,this)){this.pos.y=u,ce&&bt(this.pos,this.size,"#ff0");return}this.pos.x=t.x,this.velocity.x*=-a}if(o||!s){if(e){let c=this.size.y/2+1e-4;this.pos.y=Jt.y<0?wt(t.y-this.size.y/2)+c:si(t.y+this.size.y/2)-c,this.groundObject=i}else this.pos.y=t.y,this.groundObject=void 0;this.velocity.y*=-a}ce&&bt(this.pos,this.size,"#f00")}}}update(){}render(){Dt(this.pos,this.drawSize||this.size,this.tileInfo,this.color,this.angle,this.mirror,this.additiveColor)}renderLight(){}destroy(t=!1){var e;if(!this.destroyed){this.destroyed=!0,(e=this.parent)==null||e.removeChild(this);for(let i of this.children)i.parent=void 0,i.destroy(t)}}localToWorld(t){return this.pos.add(t.rotate(this.angle))}worldToLocal(t){return t.subtract(this.pos).rotate(-this.angle)}localToWorldVector(t){return t.rotate(this.angle)}worldToLocalVector(t){return t.rotate(-this.angle)}collideWithTile(t,e){return t>0}collideWithObject(t){return!0}getUp(t=1){return b().setAngle(this.angle,t)}getRight(t=1){return b().setAngle(this.angle+Y/2,t)}getAliveTime(){return $t-this.spawnTime}getSpeed(){return this.velocity.length()}applyAcceleration(t){this.mass&&(this.velocity=this.velocity.add(t))}applyAngularAcceleration(t){this.mass&&(this.angleVelocity+=t)}applyForce(t){this.mass&&this.applyAcceleration(t.scale(1/this.mass))}getMirrorSign(){return this.mirror?-1:1}addChild(t,e=b(),i=0){return p(!this.destroyed,"cannot add child to destroyed object"),this.destroyed||(p(!t.parent&&!this.children.includes(t)),p(t instanceof n,"child must be an EngineObject"),p(t!==this,"cannot add self as child"),this.children.push(t),t.parent=this,t.localPos=e.copy(),t.localAngle=i,t.updateTransforms()),t}removeChild(t){p(t.parent===this&&this.children.includes(t)),this.children.splice(this.children.indexOf(t),1),t.parent=void 0}isOverlappingObject(t){return this.isOverlapping(t.pos,t.size)}isOverlapping(t,e=b()){return Hi(this.pos,this.size,t,e)}setCollision(t=!0,e=!0,i=!0,s=!0){p(t||!e,"solid objects must be set to collide"),this.collideSolidObjects=t,this.isSolid=e,this.collideTiles=i,this.collideRaycast=s}toString(){let t="type = "+this.constructor.name;return(this.pos.x||this.pos.y)&&(t+=`
 pos = `+this.pos),(this.velocity.x||this.velocity.y)&&(t+=`
 velocity = `+this.velocity),(this.size.x||this.size.y)&&(t+=`
 size = `+this.size),this.angle&&(t+=`
 angle = `+this.angle.toFixed(3)),this.color&&(t+=`
-color = `+this.color),t}renderDebugInfo(){if(!Gt)return;let t=this.collideTiles||this.collideSolidObjects||this.isSolid;if(!t&&!this.parent)return;let e=b($(this.size.x,.2),$(this.size.y,.2)),s=z(this.collideTiles?1:0,this.collideSolidObjects?1:0,this.isSolid?1:0,.5);bt(this.pos,e,s,0,this.angle,t),this.parent&&bt(this.pos,e.scale(.8),z(1,1,1,.5),0,this.angle),this.parent&&Se(this.pos,this.parent.pos,z(1,1,1,.5),.5)}},I=b(),hn=[];Ee=class n{constructor(t=b(),e=Di,s=hn[0],i=Mi,o=Ii){this.pos=t.copy(),this.size=e.copy(),this.padding=i,this.textureInfo=s,this.bleed=o}offset(t){return new n(this.pos.add(t),this.size,this.textureInfo,this.padding,this.bleed)}frame(t){f(typeof t=="number");let e=this.size.x+this.padding*2,s=t*e;return f(s+this.size.x<=this.textureInfo.size.x,"frame extends beyond texture width!"),this.offset(new rt(s))}setFullImage(t=this.textureInfo){return this.textureInfo=t,this.pos=new rt,this.size=t.size.copy(),this.bleed=this.padding=0,this}tile(t){return Is(t,this.size,this.textureInfo,this.padding,this.bleed)}},Je=class{constructor(t,e=!0,s=!1){this.image=t,this.size=t?b(t.width,t.height):b(),this.sizeInverse=t?b(1/t.width,1/t.height):b(),this.glTexture=void 0,this.wrap=s,e&&this.createWebGLTexture()}createWebGLTexture(){Kh(this)}destroyWebGLTexture(){Qh(this)}hasWebGL(){return!!this.glTexture}setWrap(t=!0){this.wrap=t,Cc(this.glTexture,t)}};rh=0;ri=class{constructor(t){f(!!t,"tileInfo is required for ImageFont"),this.tileInfo=t.frame(0)}drawText(t,e,s=1,i,o,r,a){f(L(s)||typeof s=="number","size must be a vec2 or number"),typeof s=="number"?(f(s>0),s*=H,s=new rt(s,s)):s=s.scale(H),this.drawTextScreen(t,On(e),s,i,o,r,a)}drawTextScreen(t,e,s,i=!0,o=W,r=G,a){f(V(t),"text must be a string"),f(L(e),"pos must be a vec2"),f(L(s)||typeof s=="number","size must be a vec2 or number"),f(J(o),"color must be a color"),s=typeof s=="number"?new rt(s,s):s;let c=new rt,l=this.tileInfo,u=l.padding,h=l.size.x+u*2,p=l.size.y+u*2,d=l.textureInfo.size.x/h|0;(t+"").split(`
-`).forEach((g,x)=>{let v=i?(g.length-1)*s.x/2:0;for(let w=g.length;w--;){let _=g.charCodeAt(w),S=_<32||_>127?95:_-32,E=S%d,A=S/d|0;l.pos.x=E*h+u,l.pos.y=A*p+u,c.x=e.x+w*s.x-v|0,c.y=e.y+x*s.y|0,Ot(c,s,l,o,0,!1,void 0,r,!0,a)}})}};Le=b(),Ut=b(),_r=b(),be=b(),Er=0,ai=!0,Nn=!1,en="mouse",Rr=6,jn=!0,mt=0,ie=!N&&window.ontouchstart!==void 0;Y=[[]],xe=[],gn=[],ho=[],Wn=new Ae,oe=[],_n=[],ci=[],js=[],Fe=new Map,bs=[],qn=!0;li="http://www.w3.org/2000/svg";ft=new AudioContext,Zn=44100;vs=class{constructor(t,e,s=wr,i=Tr,o){var r;if(!(!Xt||N)){if(f(!t||de(t)||V(t),"asset must be a file name or zzfx array"),f(e===void 0||R(e),"randomness must be a number"),f(e===void 0||e>=0&&e<=1,"randomness must be between 0 and 1"),f(R(s),"range must be a number"),f(R(i),"taper must be a number"),this.range=s,this.taper=i,this.randomness=e!=null?e:0,this.sampleRate=Zn,this.loadedPercent=0,this.onloadCallback=o,de(t)){let a=t.slice(),c=e!=null?e:.05,l=1;this.randomness=(r=a[l])!=null?r:c,a[l]=0,this.sampleChannels=[ji(...a)],this.loadedPercent=1,o==null||o(this)}else if(typeof t=="string"){let a=t;this.loadSound(a)}}}play(t,e=1,s=1,i=1,o=!1,r=!1){if(f(!t||L(t),"pos must be a vec2"),f(R(e),"volume must be a number"),f(R(s),"pitch must be a number"),f(R(i),"randomnessScale must be a number"),!Xt||N||!this.sampleChannels)return;let a;if(t){let u=this.range;if(u){let h=Et.distanceSquared(t);if(h>u*u)return;e*=Ft(h**.5,u,u*this.taper)}a=On(t).x*2/j.width-1}let c=s+s*this.randomness*i*dt(-1,1),l=new ui(this,e,c,a,o,r);return Gt&&Un&&t&&(Vt(t,.5,"#0ff",.5,!0),this.range&&(Vt(t,2*this.range,"#0ff",.5),Vt(t,2*this.range*this.taper,"#0ff",.5)),In("vol "+e.toFixed(2)+" pitch "+c.toFixed(2),t,.5,"#0ff",.5)),l}playMusic(t=1,e=!0,s=!1){return this.play(void 0,t,1,0,e,s)}playNote(t=0,e,s){f(R(t),"semitoneOffset must be a number");let i=xc(t,1);return this.play(e,s,i,0)}getDuration(){var t,e;return((e=(t=this.sampleChannels)==null?void 0:t[0])==null?void 0:e.length)/this.sampleRate||0}isLoaded(){return this.loadedPercent===1}async loadSound(t){var c;let e=await fetch(t);if(!e.ok)throw new Error(`Failed to load sound from ${t}: ${e.status} ${e.statusText}`);let s=await e.arrayBuffer(),i=await ft.decodeAudioData(s),o=i.numberOfChannels,r=1e5,a=[];for(let l=0;lsetTimeout(v,0));let d=Q(p+r,h);for(;p=0,"Sound volume must be positive or zero"),f(s>=0,"Sound rate must be positive or zero"),f(R(i),"Sound pan must be a number"),this.sound=t,this.volume=e,this.rate=s,this.pan=i,this.loop=o,this.pausedTime=0,this.startTime=void 0,this.gainNode=void 0,this.source=void 0,this.onendedCallback=a=>{a===this.source&&(this.source=void 0)},r||this.start()}start(t=0){f(t>=0,"Sound start offset must be positive or zero"),this.isPlaying()&&this.stop(),this.gainNode=ft.createGain(),this.source=Gr(this.sound.sampleChannels,this.volume,this.rate,this.pan,this.loop,this.sound.sampleRate,this.gainNode,t,this.onendedCallback),this.source?(this.startTime=ft.currentTime-t,this.pausedTime=void 0):(this.startTime=void 0,this.pausedTime=0)}setVolume(t){f(t>=0,"Sound volume must be positive or zero"),this.volume=t,this.gainNode&&(this.gainNode.gain.value=t)}stop(t=0){if(f(t>=0,"Sound fade time must be positive or zero"),this.isPlaying())if(t){let e=ft.currentTime,s=e+t;this.gainNode.gain.cancelScheduledValues(e),this.gainNode.gain.setValueAtTime(this.volume,e),this.gainNode.gain.linearRampToValueAtTime(0,s),this.source.stop(s)}else this.source.stop();this.pausedTime=0,this.source=void 0,this.startTime=void 0}pause(){this.isPaused()||(this.pausedTime=this.getCurrentTime(),this.source.stop(),this.source=void 0,this.startTime=void 0)}resume(){this.isPaused()&&this.start(this.pausedTime)}isPlaying(){return!!this.source}isPaused(){return!this.isPlaying()}getCurrentTime(){if(!this.isPlaying())return this.pausedTime;let t=this.getDuration();return t?se(ft.currentTime-this.startTime,t):0}getDuration(){return this.rate?this.sound.getDuration()/this.rate:0}getSource(){return this.source}};an=[];An=class{constructor(t,e=0,s=!1,i=new At){this.tile=t,this.direction=e,this.mirror=s,this.color=i.copy()}clear(){this.tile=this.direction=0,this.mirror=!1,this.color=new At}},di=class extends ze{constructor(t,e,s=0,i=0,o=b(512),r=!0){var a;f(L(o),"canvasSize must be a Vector2"),super(t,e,void 0,s,W,i),this.canvas=N?void 0:new OffscreenCanvas(o.x,o.y),this.context=(a=this.canvas)==null?void 0:a.getContext("2d"),this.textureInfo=new Je(this.canvas,r),this.mass=0}destroy(){this.destroyed||(this.textureInfo.destroyWebGLTexture(),super.destroy())}render(){this.draw(this.pos,this.size,this.color,this.angle,this.mirror,this.additiveColor)}draw(t,e,s=W,i=0,o=!1,r,a=!1,c){let l=new Ee().setFullImage(this.textureInfo),u=this.hasWebGL();Ot(t,e,l,s,i,o,r,u,a,c)}updateWebGL(){this.textureInfo.createWebGLTexture()}hasWebGL(){return G&&this.textureInfo.hasWebGL()}},Ss=class extends di{constructor(t,e,s=Is(),i=0,o=!0){let r=s?e.multiply(s.size):e;if(super(t,e,0,i,r,o),this.tileInfo=void 0,this.data=[],this.isUsingWebGL=!1,N){this.render=()=>{},this.redraw=()=>{},this.redrawStart=()=>{},this.redrawEnd=()=>{},this.drawTileData=()=>{},this.redrawTileData=()=>{},this.drawLayerTile=()=>{},this.drawLayerRect=()=>{},this.drawTile=()=>{},this.drawRect=()=>{},this.clearLayerRect=()=>{};return}s&&(this.tileInfo=s.frame(0),this.tileInfo.bleed=0);for(let a=this.size.area();a--;)this.data.push(new An)}setData(t,e,s=!1){if(t=t.floor(),f(L(t),"layerPos must be a Vector2"),f(e instanceof An,"data must be a TileLayerData"),!t.arrayCheck(this.size)||(this.data[(t.y|0)*this.size.x+(t.x|0)]=e,!s))return;Ct===this.context?this.drawTileData(t):this.redrawTileData(t)}clearData(t,e=!1){this.setData(t,new An,e)}getData(t){return f(L(t),"layerPos must be a Vector2"),t.arrayCheck(this.size)?this.data[(t.y|0)*this.size.x+(t.x|0)]:void 0}update(){!G&&this.isUsingWebGL&&(this.isUsingWebGL=!1,this.redraw())}render(){f(Ct!==this.context,"must call redrawEnd() after drawing tiles!");let t=this.drawSize||this.size,e=this.pos.add(t.scale(.5));this.draw(e,this.size,this.color,this.angle,this.mirror,this.additiveColor)}onRedraw(){}redraw(){this.redrawStart(!0);for(let t=this.size.x;t--;)for(let e=this.size.y;e--;)this.drawTileData(b(t,e),!1);this.isUsingWebGL&&Rt(),this.onRedraw(),this.redrawEnd()}redrawStart(t=!1){var s,i;if(!this.context)return;f(Ct!==this.context),this.savedRenderSettings=[Ct,I,Et,H,sn],Ct=this.context;let e=(i=(s=this.tileInfo)==null?void 0:s.size)!=null?i:b(1);I=this.size.multiply(e),sn=pe,Et=this.size.multiply(e).scale(.5),H=1,this.isUsingWebGL=this.hasWebGL(),this.isUsingWebGL?rs(this.textureInfo.glTexture,t):(this.context.imageSmoothingEnabled=!Cn,t&&(this.canvas.width=I.x,this.canvas.height=I.y))}redrawEnd(){this.context&&(f(Ct===this.context),this.isUsingWebGL&&rs(),[Ct,I,Et,H,sn]=this.savedRenderSettings)}drawTileData(t,e=!0){var a,c;if(!this.context)return;f(Ct===this.context,"must call redrawStart() before drawing tiles");let s=(c=(a=this.tileInfo)==null?void 0:a.size)!=null?c:b(1),i=t.multiply(s);e&&this.clearLayerRect(i,s);let o=this.getData(t);if(!o||!o.tile)return;let r=this.tileInfo&&this.tileInfo.tile(o.tile);this.drawLayerTile(i,s,r,o.color,o.direction*X/2,o.mirror)}redrawTileData(t,e=!0){this.context&&(f(Ct!==this.context,"redrawStart() should not be active when calling redrawTileData(), instead use drawTileData()"),this.redrawStart(),this.drawTileData(t,e),this.redrawEnd())}drawLayerTile(t,e=b(1),s,i=W,o=0,r,a){let c=t.add(e.scale(.5));Ot(c,e,s,i,o,r,a,this.isUsingWebGL)}drawLayerRect(t,e,s,i=0){this.drawLayerTile(t,e,void 0,s,i)}drawTile(t,e=b(1),s,i=new At,o=0,r=!1){t=t.subtract(this.pos).multiply(this.tileInfo.size),e=e.multiply(this.tileInfo.size),t.y=this.canvas.height-t.y;let a=I;I=b(this.canvas.width,this.canvas.height);let c=this.hasWebGL();c&&rs(this.textureInfo.glTexture);let l=c?void 0:this.context;Ot(t,e,s,i,o,r,void 0,c,!0,l),c&&rs(),I=a}drawRect(t,e,s,i){this.drawTile(t,e,void 0,s,i)}clearLayerRect(t,e){f(Ct===this.context,"must call redrawStart() before clearing tiles");let s=t.x,i=this.canvas.height-t.y-e.y;this.hasWebGL()?Pc(s,i,e.x,e.y):this.context.clearRect(s,i,e.x,e.y)}},ws=class extends Ss{constructor(t,e,s=Is(),i=0,o=!0){super(t,e.floor(),s,i,o),this.collisionData=[],this.initCollision(this.size),an.push(this),this.isSolid=!0}destroy(){if(this.destroyed)return;let t=an.indexOf(this);f(t>=0,"tile collision layer not found in array"),t>=0&&an.splice(t,1),super.destroy()}initCollision(t){f(L(t),"size must be a Vector2"),this.size=t.floor(),this.collisionData=[],this.collisionData.length=t.area(),this.collisionData.fill(0)}setCollisionData(t,e=1){f(L(t),"layerPos must be a Vector2");let s=(t.y|0)*this.size.x+(t.x|0);t.arrayCheck(this.size)&&(this.collisionData[s]=e)}clearCollisionData(t){this.setCollisionData(t,0)}getCollisionData(t){f(L(t),"layerPos must be a Vector2");let e=(t.y|0)*this.size.x+(t.x|0);return t.arrayCheck(this.size)?this.collisionData[e]:0}collisionTest(t,e=new rt,s){f(L(t)&&L(e),"pos and size must be Vector2s"),f(!s||typeof s=="function"||s instanceof ze,"callbackObject must be a function or EngineObject");let i=s?typeof s=="function"?(p,d)=>s(p,d):(p,d)=>s.collideWithTile(p,d):()=>!0,o=t.x-this.pos.x,r=t.y-this.pos.y;if(o+e.x/2<0||o-e.x/2>this.size.x||r+e.y/2<0||r-e.y/2>this.size.y)return!1;let a=$(o-e.x/2|0,0),c=$(r-e.y/2|0,0),l=Q($(o+e.x/2,a+1),this.size.x),u=Q($(r+e.y/2,c+1),this.size.y),h=new rt;for(let p=c;ps(l,u):(l,u)=>s.collideWithTile(l,u):l=>l>0,r=l=>{let u=this.getCollisionData(a.set(l.x-this.pos.x,l.y-this.pos.y));return u&&o(u,l)},a=new rt,c=$a(t,e,r,i);if(he&&c){let l=c.floor().add(b(.5));bt(l,b(1),"#f008"),Se(t,e,"#00f",.02),Se(t,c,"#f00",.02),or(c,"#0f0"),i&&Se(c,c.add(i),"#ff0",.02)}return c}},To=class extends ze{constructor(t,e,s=0,i=0,o=100,r=X,a,c=W,l=W,u=ln,h=ln,p=.5,d=.1,g=1,x=.1,v=.05,w=1,_=1,S=0,E=X,A=.1,T=.2,P=!1,k=!1,ct=!0,st=k?1e9:0,it=!1){super(t,b(),a,e,void 0,st),this.emitCircle=typeof s=="number",this.emitSize=typeof s=="number"?b(s):s.copy(),this.emitTime=i,this.emitRate=o,this.emitConeAngle=r,this.colorStartA=c.copy(),this.colorStartB=l.copy(),this.colorEndA=u.copy(),this.colorEndB=h.copy(),this.randomColorLinear=ct,this.particleTime=p,this.sizeStart=d,this.sizeEnd=g,this.speed=x,this.angleSpeed=v,this.damping=w,this.angleDamping=_,this.gravityScale=S,this.particleConeAngle=E,this.fadeRate=A,this.randomness=T,this.collideTiles=P,this.additive=k,this.localSpace=it,this.trailScale=0,this.particleCreateCallback=void 0,this.particleDestroyCallback=void 0,this.particleCollideCallback=void 0,this.velocityInheritance=0,this.emitTimeBuffer=0,this.particles=[],this.previousAngle=this.angle,this.previousPos=this.pos.copy()}update(){if(f(this.angleDamping>=0&&this.angleDamping<=1),f(this.damping>=0&&this.damping<=1),this.velocityInheritance){let s=this.velocityInheritance;this.velocity.x=s*(this.pos.x-this.previousPos.x),this.velocity.y=s*(this.pos.y-this.previousPos.y),this.angleVelocity=s*(this.angle-this.previousAngle),this.previousAngle=this.angle,this.previousPos.x=this.pos.x,this.previousPos.y=this.pos.y}if(this.isActive()){if(this.emitRate&&ei){let s=1/this.emitRate/ei;for(this.emitTimeBuffer+=sr;this.emitTimeBuffer>0;this.emitTimeBuffer-=s)this.emitParticle()}}else this.particles.length===0&&this.destroy(!0);let t=this.particles,e=0;for(let s=0;s_+_*dt(s,-s),o=i(this.particleTime),r=i(this.sizeStart),a=i(this.sizeEnd),c=i(this.speed),l=i(this.angleSpeed)*Qa(),u=dt(this.emitConeAngle,-this.emitConeAngle),h=mo(this.colorStartA,this.colorStartB,this.randomColorLinear),p=mo(this.colorEndA,this.colorEndB,this.randomColorLinear),d=this.localSpace?u:this.angle+u,g=b(c*et(d),c*at(d)),x=l;!this.localSpace&&this.velocityInheritance>0&&(g.x+=this.velocity.x,g.y+=this.velocity.y,x+=this.angleVelocity);let v=new fi(this,t,e,h,p,o,r,a,g,x);return this.particles.push(v),(w=this.particleCreateCallback)==null||w.call(this,v),v}updatePhysics(){}render(){for(let t of this.particles)t.render()}isActive(){return!this.emitTime||this.getAliveTime()0&&(this.destroyed=!1,this.emitTime=-1))}},Xh=new rt,fi=class{constructor(t,e,s,i,o,r,a,c,l=b(),u=0){this.emitter=t,this.pos=e,this.angle=s,this.size=b(a),this.color=i.copy(),this.colorStart=i,this.colorEnd=o,this.lifeTime=r,this.sizeStart=a,this.sizeEnd=c,this.velocity=l,this.angleVelocity=u,this.spawnTime=Qt,this.mirror=Ka(),this.groundObject=void 0,this.destroyed=!1,this.tileInfo=t.tileInfo}update(){let t=this.emitter,e=t.damping,s=t.angleDamping,i=t.restitution,o=t.friction,r=t.gravityScale,a=t.collideTiles,c=t.particleCollideCallback;if(this.lifeTime>0&&Qt-this.spawnTime>this.lifeTime){this.destroy();return}let l=this.pos.copy();if(this.velocity.x*=e,this.velocity.y*=e,this.pos.x+=this.velocity.x+=Wt.x*r,this.pos.y+=this.velocity.y+=Wt.y*r,this.angle+=this.angleVelocity*=s,!ki||!a)return;let u=this.velocity.lengthSquared();if(u>ke*ke){let p=ke/u**.5;this.velocity.x*=p,this.velocity.y*=p}this.groundObject=void 0;let h=c?p=>{let d=hi(p);return d&&c(this,d,p)}:p=>hi(p)>0;if(h(this.pos)){let p=Ze(this.pos);if(!h(l)){let d=h(b(this.pos.x,l.y)),g=h(b(l.x,this.pos.y)),x=$(i,p.restitution),v=$(o,p.friction);d&&(this.pos.x=l.x,this.velocity.x*=-x,this.velocity.y*=v),(g||!d)&&((this.velocity.y<0&&Wt.y<0||this.velocity.y>0&&Wt.y>0)&&(this.groundObject=p),this.pos.y=l.y,this.velocity.y*=-x,this.velocity.x*=v),ue&&bt(this.pos,this.size,"#f00")}}}destroy(){let t=this.emitter.particleDestroyCallback,e=this.colorEnd;this.color.set(e.r,e.g,e.b,e.a),this.size.set(this.sizeEnd,this.sizeEnd),this.destroyed=!0,t==null||t(this)}render(){let t=this.emitter,e=t.localSpace,s=t.additive,i=t.trailScale,o=t.fadeRate/2,r=this.lifeTime>0?Q((Qt-this.spawnTime)/this.lifeTime,1):1,a=1-r,c=a*this.sizeStart+r*this.sizeEnd,l=b(c),u=r1-o?(1-r)/o:1;this.color.r=a*this.colorStart.r+r*this.colorEnd.r,this.color.g=a*this.colorStart.g+r*this.colorEnd.g,this.color.b=a*this.colorStart.b+r*this.colorEnd.b,this.color.a=(a*this.colorStart.a+r*this.colorEnd.a)*u;let h=Xh.set(this.pos.x,this.pos.y),p=this.angle;if(e){let d=t.angle,g=at(-d),x=et(-d);h.set(t.pos.x+h.x*g-h.y*x,t.pos.y+h.x*x+h.y*g),p+=d}if(s&&ys(),i){let d=e?this.velocity.rotate(t.angle):this.velocity,g=d.length();if(g){let x=g*i;l.y=$(l.x,x),p=rr(d.x,d.y),Ot(h,l,this.tileInfo,this.color,p,this.mirror)}}else Ot(h,l,this.tileInfo,this.color,p,this.mirror);s&&ys(!1),Sn&&bt(h,l,"#f005",0,p)}},Fr=!0,Eo=!0,mi=5e5,Br=11,Sc=Br*4,Yh=mi/Sc|0,Bi=3,wc=Bi*4,Jn=mi/wc|0;yn=!1,bi=5,Bn=.5,xi=b(640,80),qr=!1,_s={},Xs=[];Si=class{constructor(t,e,s="",i="\u{1F3C6}",o){f(t>=0&&!_s[t]),this.id=t,this.name=e,this.description=s,this.icon=i,this.unlocked=!1,this.image=void 0,o&&((this.image=new Image).src=o),_s[t]=this}unlock(){qr||this.unlocked||(f(vi,"save name must be set"),this.unlocked=!0,Hr(),Xs.push(this))}render(t=0){let e=ut,s=Q(xi.x,j.width),i=xi.y,o=j.width-s,r=-i*t,a=Ie(0,0,.9);e.save(),e.beginPath(),e.fillStyle=a.toString(),e.strokeStyle=nt.toString(),e.lineWidth=3,e.rect(o,r,s,i),e.fill(),e.stroke(),e.clip();let c=b(.1,.05).scale(i),l=i-2*c.x;this.renderIcon(b(o+c.x+l/2,r+i/2),l);let u=i*.5,h=i*.3,p=b(o+l+2*c.x,r+c.y*2+u/2),d=s-l-3*c.x;rn(this.name,p,u,nt,0,void 0,"left",void 0,void 0,d),p.y=r+i-c.y*2-h/2,rn(this.description,p,h,nt,0,void 0,"left",void 0,void 0,d),e.restore()}renderIcon(t,e){this.image?ut.drawImage(this.image,t.x-e/2,t.y-e/2,e,e):rn(this.icon,t,e*.7,nt)}};Lo=class extends Si{constructor(t,e,s,i,o){super(t,e,s,i,o)}unlock(){super.unlock(),Es&&Es.unlockMedal(this.id)}},Oo=class{constructor(t,e,s){var c,l,u;f(!Es,"there can only be one newgrounds object"),f(!e||s,"must provide cryptojs if there is a cipher"),Es=this,this.app_id=t,this.cipher=e,this.cryptoJS=s,this.host=location?location.hostname:"";let i=new URL(location.href);if(this.session_id=i.searchParams.get("ngio_session_id"),!this.session_id)return;let o=this.call("Medal.getList");if(!o||!o.result||o.result.error){yn&&vt("Newgrounds session unavailable; skipping plugin init"),this.medals=[],this.scoreboards=[];return}this.medals=((c=o.result.data)==null?void 0:c.medals)||[],yn&&vt(this.medals);for(let h of this.medals){let p=_s[h.id];p&&(p.image=new Image,p.image.src=h.icon,p.name=h.name,p.description=h.description,p.unlocked=h.unlocked,p.difficulty=h.difficulty,p.value=h.value,p.value&&(p.description=p.description+` (${p.value})`))}let r=this.call("ScoreBoard.getBoards");this.scoreboards=((u=(l=r==null?void 0:r.result)==null?void 0:l.data)==null?void 0:u.scoreboards)||[],yn&&vt(this.scoreboards);let a=60*1e3;setInterval(()=>this.call("Gateway.ping",0,!0),a)}unlockMedal(t){return this.call("Medal.unlock",{id:t},!0)}postScore(t,e){return this.call("ScoreBoard.postScore",{id:t,value:e},!0)}getScores(t,e,s=0,i=0,o=10){return this.call("ScoreBoard.getScores",{id:t,user:e,social:s,skip:i,limit:o})}logView(){return this.call("App.logView",{host:this.host},!0)}call(t,e,s=!1){let i={component:t,parameters:e};if(this.cipher){let l=this.cryptoJS,u=l.enc.Base64.parse(this.cipher),h=l.lib.WordArray.random(16),p=l.AES.encrypt(JSON.stringify(i),u,{iv:h});i.secure=l.enc.Base64.stringify(h.concat(p.ciphertext)),i.parameters=0}let o={app_id:this.app_id,session_id:this.session_id,call:i},r=new FormData;r.append("input",JSON.stringify(o));let a=new XMLHttpRequest;a.open("POST","https://newgrounds.io/gateway_v3.php",!yn&&s);try{a.send(r)}catch(l){yn&&vt("newgrounds call failed",l);return}return yn&&vt(a.responseText),a.responseText&&JSON.parse(a.responseText)}},Do=class{constructor(t,e=!1,s=!1){f(!Mt,"Post process already initialized"),f(!(e&&s),"Post process cannot both include main canvas and use feedback texture"),Mt=this,t||(t="void mainImage(out vec4 c,vec2 p){c=texture(iChannel0,p/iResolution.xy);}"),this.shader=void 0,this.texture=void 0,this.vao=void 0,i(),Rn(void 0,a,o,r);function i(){if(N)return;if(!G){console.warn("PostProcessPlugin: WebGL not enabled!");return}Mt.texture=Ni(),Mt.shader=Yn(`#version 300 es
+color = `+this.color),t}renderDebugInfo(){if(!Ft)return;let t=this.collideTiles||this.collideSolidObjects||this.isSolid;if(!t&&!this.parent)return;let e=b(K(this.size.x,.2),K(this.size.y,.2)),i=U(this.collideTiles?1:0,this.collideSolidObjects?1:0,this.isSolid?1:0,.5);bt(this.pos,e,i,0,this.angle,t),this.parent&&bt(this.pos,e.scale(.8),U(1,1,1,.5),0,this.angle),this.parent&&xe(this.pos,this.parent.pos,U(1,1,1,.5),.5)}},G=b(),nn=[];Ee=class n{constructor(t=b(),e=Es,i=nn[0],s=_s,o=Cs){this.pos=t.copy(),this.size=e.copy(),this.padding=s,this.textureInfo=i,this.bleed=o}offset(t){return new n(this.pos.add(t),this.size,this.textureInfo,this.padding,this.bleed)}frame(t){p(typeof t=="number");let e=this.size.x+this.padding*2,i=t*e;return p(i+this.size.x<=this.textureInfo.size.x,"frame extends beyond texture width!"),this.offset(new rt(i))}setFullImage(t=this.textureInfo){return this.textureInfo=t,this.pos=new rt,this.size=t.size.copy(),this.bleed=this.padding=0,this}tile(t){return _i(t,this.size,this.textureInfo,this.padding,this.bleed)}},je=class{constructor(t,e=!0,i=!1){this.image=t,this.size=t?b(t.width,t.height):b(),this.sizeInverse=t?b(1/t.width,1/t.height):b(),this.glTexture=void 0,this.wrap=i,e&&this.createWebGLTexture()}createWebGLTexture(){Hh(this)}destroyWebGLTexture(){Xh(this)}hasWebGL(){return!!this.glTexture}setWrap(t=!0){this.wrap=t,bc(this.glTexture,t)}};nh=0;Zi=class{constructor(t){p(!!t,"tileInfo is required for ImageFont"),this.tileInfo=t.frame(0)}drawText(t,e,i=1,s,o,a,r){p(O(i)||typeof i=="number","size must be a vec2 or number"),typeof i=="number"?(p(i>0),i*=X,i=new rt(i,i)):i=i.scale(X),this.drawTextScreen(t,Tn(e),i,s,o,a,r)}drawTextScreen(t,e,i,s=!0,o=q,a=B,r){p(W(t),"text must be a string"),p(O(e),"pos must be a vec2"),p(O(i)||typeof i=="number","size must be a vec2 or number"),p(V(o),"color must be a color"),i=typeof i=="number"?new rt(i,i):i;let c=new rt,l=this.tileInfo,u=l.padding,h=l.size.x+u*2,f=l.size.y+u*2,d=l.textureInfo.size.x/h|0;(t+"").split(`
+`).forEach((y,x)=>{let v=s?(y.length-1)*i.x/2:0;for(let w=y.length;w--;){let C=y.charCodeAt(w),S=C<32||C>127?95:C-32,_=S%d,A=S/d|0;l.pos.x=_*h+u,l.pos.y=A*f+u,c.x=e.x+w*i.x-v|0,c.y=e.y+x*i.y|0,Dt(c,i,l,o,0,!1,void 0,a,!0,r)}})}};_e=b(),Nt=b(),xr=b(),ye=b(),vr=0,ts=!0,Dn=!1,He="mouse",Sr=6,Ln=!0,mt=0,ne=!J&&window.ontouchstart!==void 0;$=[[]],me=[],cn=[],so=[],Fn=new we,ie=[],bn=[],es=[],Li=[],Me=new Map,ui=[],jn=!0;ns="http://www.w3.org/2000/svg";dt=new AudioContext,Wn=44100;di=class{constructor(t,e,i=gr,s=yr,o){var a;if(!(!Wt||J)){if(p(!t||ue(t)||W(t),"asset must be a file name or zzfx array"),p(e===void 0||P(e),"randomness must be a number"),p(e===void 0||e>=0&&e<=1,"randomness must be between 0 and 1"),p(P(i),"range must be a number"),p(P(s),"taper must be a number"),this.range=i,this.taper=s,this.randomness=e!=null?e:0,this.sampleRate=Wn,this.loadedPercent=0,this.onloadCallback=o,ue(t)){let r=t.slice(),c=e!=null?e:.05,l=1;this.randomness=(a=r[l])!=null?a:c,r[l]=0,this.sampleChannels=[Os(...r)],this.loadedPercent=1,o==null||o(this)}else if(typeof t=="string"){let r=t;this.loadSound(r)}}}play(t,e=1,i=1,s=1,o=!1,a=!1){if(p(!t||O(t),"pos must be a vec2"),p(P(e),"volume must be a number"),p(P(i),"pitch must be a number"),p(P(s),"randomnessScale must be a number"),!Wt||J||!this.sampleChannels)return;let r;if(t){let u=this.range;if(u){let h=Ct.distanceSquared(t);if(h>u*u)return;e*=jt(h**.5,u,u*this.taper)}r=Tn(t).x*2/N.width-1}let c=i+i*this.randomness*s*ht(-1,1),l=new is(this,e,c,r,o,a);return Ft&&kn&&t&&(zt(t,.5,"#0ff",.5,!0),this.range&&(zt(t,2*this.range,"#0ff",.5),zt(t,2*this.range*this.taper,"#0ff",.5)),_n("vol "+e.toFixed(2)+" pitch "+c.toFixed(2),t,.5,"#0ff",.5)),l}playMusic(t=1,e=!0,i=!1){return this.play(void 0,t,1,0,e,i)}playNote(t=0,e,i){p(P(t),"semitoneOffset must be a number");let s=dc(t,1);return this.play(e,i,s,0)}getDuration(){var t,e;return((e=(t=this.sampleChannels)==null?void 0:t[0])==null?void 0:e.length)/this.sampleRate||0}isLoaded(){return this.loadedPercent===1}async loadSound(t){var c;let e=await fetch(t);if(!e.ok)throw new Error(`Failed to load sound from ${t}: ${e.status} ${e.statusText}`);let i=await e.arrayBuffer(),s=await dt.decodeAudioData(i),o=s.numberOfChannels,a=1e5,r=[];for(let l=0;lsetTimeout(v,0));let d=Z(f+a,h);for(;f=0,"Sound volume must be positive or zero"),p(i>=0,"Sound rate must be positive or zero"),p(P(s),"Sound pan must be a number"),this.sound=t,this.volume=e,this.rate=i,this.pan=s,this.loop=o,this.pausedTime=0,this.startTime=void 0,this.gainNode=void 0,this.source=void 0,this.onendedCallback=r=>{r===this.source&&(this.source=void 0)},a||this.start()}start(t=0){p(t>=0,"Sound start offset must be positive or zero"),this.isPlaying()&&this.stop(),this.gainNode=dt.createGain(),this.source=Pr(this.sound.sampleChannels,this.volume,this.rate,this.pan,this.loop,this.sound.sampleRate,this.gainNode,t,this.onendedCallback),this.source?(this.startTime=dt.currentTime-t,this.pausedTime=void 0):(this.startTime=void 0,this.pausedTime=0)}setVolume(t){p(t>=0,"Sound volume must be positive or zero"),this.volume=t,this.gainNode&&(this.gainNode.gain.value=t)}stop(t=0){if(p(t>=0,"Sound fade time must be positive or zero"),this.isPlaying())if(t){let e=dt.currentTime,i=e+t;this.gainNode.gain.cancelScheduledValues(e),this.gainNode.gain.setValueAtTime(this.volume,e),this.gainNode.gain.linearRampToValueAtTime(0,i),this.source.stop(i)}else this.source.stop();this.pausedTime=0,this.source=void 0,this.startTime=void 0}pause(){this.isPaused()||(this.pausedTime=this.getCurrentTime(),this.source.stop(),this.source=void 0,this.startTime=void 0)}resume(){this.isPaused()&&this.start(this.pausedTime)}isPlaying(){return!!this.source}isPaused(){return!this.isPlaying()}getCurrentTime(){if(!this.isPlaying())return this.pausedTime;let t=this.getDuration();return t?ee(dt.currentTime-this.startTime,t):0}getDuration(){return this.rate?this.sound.getDuration()/this.rate:0}getSource(){return this.source}};Qe=[];yn=class{constructor(t,e=0,i=!1,s=new Tt){this.tile=t,this.direction=e,this.mirror=i,this.color=s.copy()}clear(){this.tile=this.direction=0,this.mirror=!1,this.color=new Tt}},os=class extends Fe{constructor(t,e,i=0,s=0,o=b(512),a=!0){var r;p(O(o),"canvasSize must be a Vector2"),super(t,e,void 0,i,q,s),this.canvas=J?void 0:new OffscreenCanvas(o.x,o.y),this.context=(r=this.canvas)==null?void 0:r.getContext("2d"),this.textureInfo=new je(this.canvas,a),this.mass=0}destroy(){this.destroyed||(this.textureInfo.destroyWebGLTexture(),super.destroy())}render(){this.draw(this.pos,this.size,this.color,this.angle,this.mirror,this.additiveColor)}draw(t,e,i=q,s=0,o=!1,a,r=!1,c){let l=new Ee().setFullImage(this.textureInfo),u=this.hasWebGL();Dt(t,e,l,i,s,o,a,u,r,c)}updateWebGL(){this.textureInfo.createWebGLTexture()}hasWebGL(){return B&&this.textureInfo.hasWebGL()}},fi=class extends os{constructor(t,e,i=_i(),s=0,o=!0){let a=i?e.multiply(i.size):e;if(super(t,e,0,s,a,o),this.tileInfo=void 0,this.data=[],this.isUsingWebGL=!1,J){this.render=()=>{},this.redraw=()=>{},this.redrawStart=()=>{},this.redrawEnd=()=>{},this.drawTileData=()=>{},this.redrawTileData=()=>{},this.drawLayerTile=()=>{},this.drawLayerRect=()=>{},this.drawTile=()=>{},this.drawRect=()=>{},this.clearLayerRect=()=>{};return}i&&(this.tileInfo=i.frame(0),this.tileInfo.bleed=0);for(let r=this.size.area();r--;)this.data.push(new yn)}setData(t,e,i=!1){if(t=t.floor(),p(O(t),"layerPos must be a Vector2"),p(e instanceof yn,"data must be a TileLayerData"),!t.arrayCheck(this.size)||(this.data[(t.y|0)*this.size.x+(t.x|0)]=e,!i))return;Et===this.context?this.drawTileData(t):this.redrawTileData(t)}clearData(t,e=!1){this.setData(t,new yn,e)}getData(t){return p(O(t),"layerPos must be a Vector2"),t.arrayCheck(this.size)?this.data[(t.y|0)*this.size.x+(t.x|0)]:void 0}update(){!B&&this.isUsingWebGL&&(this.isUsingWebGL=!1,this.redraw())}render(){p(Et!==this.context,"must call redrawEnd() after drawing tiles!");let t=this.drawSize||this.size,e=this.pos.add(t.scale(.5));this.draw(e,this.size,this.color,this.angle,this.mirror,this.additiveColor)}onRedraw(){}redraw(){this.redrawStart(!0);for(let t=this.size.x;t--;)for(let e=this.size.y;e--;)this.drawTileData(b(t,e),!1);this.isUsingWebGL&&Rt(),this.onRedraw(),this.redrawEnd()}redrawStart(t=!1){var i,s;if(!this.context)return;p(Et!==this.context),this.savedRenderSettings=[Et,G,Ct,X,Ye],Et=this.context;let e=(s=(i=this.tileInfo)==null?void 0:i.size)!=null?s:b(1);G=this.size.multiply(e),Ye=de,Ct=this.size.multiply(e).scale(.5),X=1,this.isUsingWebGL=this.hasWebGL(),this.isUsingWebGL?Qn(this.textureInfo.glTexture,t):(this.context.imageSmoothingEnabled=!mn,t&&(this.canvas.width=G.x,this.canvas.height=G.y))}redrawEnd(){this.context&&(p(Et===this.context),this.isUsingWebGL&&Qn(),[Et,G,Ct,X,Ye]=this.savedRenderSettings)}drawTileData(t,e=!0){var r,c;if(!this.context)return;p(Et===this.context,"must call redrawStart() before drawing tiles");let i=(c=(r=this.tileInfo)==null?void 0:r.size)!=null?c:b(1),s=t.multiply(i);e&&this.clearLayerRect(s,i);let o=this.getData(t);if(!o||!o.tile)return;let a=this.tileInfo&&this.tileInfo.tile(o.tile);this.drawLayerTile(s,i,a,o.color,o.direction*Y/2,o.mirror)}redrawTileData(t,e=!0){this.context&&(p(Et!==this.context,"redrawStart() should not be active when calling redrawTileData(), instead use drawTileData()"),this.redrawStart(),this.drawTileData(t,e),this.redrawEnd())}drawLayerTile(t,e=b(1),i,s=q,o=0,a,r){let c=t.add(e.scale(.5));Dt(c,e,i,s,o,a,r,this.isUsingWebGL)}drawLayerRect(t,e,i,s=0){this.drawLayerTile(t,e,void 0,i,s)}drawTile(t,e=b(1),i,s=new Tt,o=0,a=!1){t=t.subtract(this.pos).multiply(this.tileInfo.size),e=e.multiply(this.tileInfo.size),t.y=this.canvas.height-t.y;let r=G;G=b(this.canvas.width,this.canvas.height);let c=this.hasWebGL();c&&Qn(this.textureInfo.glTexture);let l=c?void 0:this.context;Dt(t,e,i,s,o,a,void 0,c,!0,l),c&&Qn(),G=r}drawRect(t,e,i,s){this.drawTile(t,e,void 0,i,s)}clearLayerRect(t,e){p(Et===this.context,"must call redrawStart() before clearing tiles");let i=t.x,s=this.canvas.height-t.y-e.y;this.hasWebGL()?wc(i,s,e.x,e.y):this.context.clearRect(i,s,e.x,e.y)}},pi=class extends fi{constructor(t,e,i=_i(),s=0,o=!0){super(t,e.floor(),i,s,o),this.collisionData=[],this.initCollision(this.size),Qe.push(this),this.isSolid=!0}destroy(){if(this.destroyed)return;let t=Qe.indexOf(this);p(t>=0,"tile collision layer not found in array"),t>=0&&Qe.splice(t,1),super.destroy()}initCollision(t){p(O(t),"size must be a Vector2"),this.size=t.floor(),this.collisionData=[],this.collisionData.length=t.area(),this.collisionData.fill(0)}setCollisionData(t,e=1){p(O(t),"layerPos must be a Vector2");let i=(t.y|0)*this.size.x+(t.x|0);t.arrayCheck(this.size)&&(this.collisionData[i]=e)}clearCollisionData(t){this.setCollisionData(t,0)}getCollisionData(t){p(O(t),"layerPos must be a Vector2");let e=(t.y|0)*this.size.x+(t.x|0);return t.arrayCheck(this.size)?this.collisionData[e]:0}collisionTest(t,e=new rt,i){p(O(t)&&O(e),"pos and size must be Vector2s"),p(!i||typeof i=="function"||i instanceof Fe,"callbackObject must be a function or EngineObject");let s=i?typeof i=="function"?(f,d)=>i(f,d):(f,d)=>i.collideWithTile(f,d):()=>!0,o=t.x-this.pos.x,a=t.y-this.pos.y;if(o+e.x/2<0||o-e.x/2>this.size.x||a+e.y/2<0||a-e.y/2>this.size.y)return!1;let r=K(o-e.x/2|0,0),c=K(a-e.y/2|0,0),l=Z(K(o+e.x/2,r+1),this.size.x),u=Z(K(a+e.y/2,c+1),this.size.y),h=new rt;for(let f=c;fi(l,u):(l,u)=>i.collideWithTile(l,u):l=>l>0,a=l=>{let u=this.getCollisionData(r.set(l.x-this.pos.x,l.y-this.pos.y));return u&&o(u,l)},r=new rt,c=Ua(t,e,a,s);if(le&&c){let l=c.floor().add(b(.5));bt(l,b(1),"#f008"),xe(t,e,"#00f",.02),xe(t,c,"#f00",.02),Qo(c,"#0f0"),s&&xe(c,c.add(s),"#ff0",.02)}return c}},yo=class extends Fe{constructor(t,e,i=0,s=0,o=100,a=Y,r,c=q,l=q,u=tn,h=tn,f=.5,d=.1,y=1,x=.1,v=.05,w=1,C=1,S=0,_=Y,A=.1,T=.2,L=!1,F=!1,ft=!0,D=F?1e9:0,I=!1){super(t,b(),r,e,void 0,D),this.emitCircle=typeof i=="number",this.emitSize=typeof i=="number"?b(i):i.copy(),this.emitTime=s,this.emitRate=o,this.emitConeAngle=a,this.colorStartA=c.copy(),this.colorStartB=l.copy(),this.colorEndA=u.copy(),this.colorEndB=h.copy(),this.randomColorLinear=ft,this.particleTime=f,this.sizeStart=d,this.sizeEnd=y,this.speed=x,this.angleSpeed=v,this.damping=w,this.angleDamping=C,this.gravityScale=S,this.particleConeAngle=_,this.fadeRate=A,this.randomness=T,this.collideTiles=L,this.additive=F,this.localSpace=I,this.trailScale=0,this.particleCreateCallback=void 0,this.particleDestroyCallback=void 0,this.particleCollideCallback=void 0,this.velocityInheritance=0,this.emitTimeBuffer=0,this.particles=[],this.previousAngle=this.angle,this.previousPos=this.pos.copy()}update(){if(p(this.angleDamping>=0&&this.angleDamping<=1),p(this.damping>=0&&this.damping<=1),this.velocityInheritance){let i=this.velocityInheritance;this.velocity.x=i*(this.pos.x-this.previousPos.x),this.velocity.y=i*(this.pos.y-this.previousPos.y),this.angleVelocity=i*(this.angle-this.previousAngle),this.previousAngle=this.angle,this.previousPos.x=this.pos.x,this.previousPos.y=this.pos.y}if(this.isActive()){if(this.emitRate&&Xi){let i=1/this.emitRate/Xi;for(this.emitTimeBuffer+=$o;this.emitTimeBuffer>0;this.emitTimeBuffer-=i)this.emitParticle()}}else this.particles.length===0&&this.destroy(!0);let t=this.particles,e=0;for(let i=0;iC+C*ht(i,-i),o=s(this.particleTime),a=s(this.sizeStart),r=s(this.sizeEnd),c=s(this.speed),l=s(this.angleSpeed)*Wa(),u=ht(this.emitConeAngle,-this.emitConeAngle),h=lo(this.colorStartA,this.colorStartB,this.randomColorLinear),f=lo(this.colorEndA,this.colorEndB,this.randomColorLinear),d=this.localSpace?u:this.angle+u,y=b(c*it(d),c*at(d)),x=l;!this.localSpace&&this.velocityInheritance>0&&(y.x+=this.velocity.x,y.y+=this.velocity.y,x+=this.angleVelocity);let v=new rs(this,t,e,h,f,o,a,r,y,x);return this.particles.push(v),(w=this.particleCreateCallback)==null||w.call(this,v),v}updatePhysics(){}render(){for(let t of this.particles)t.render()}isActive(){return!this.emitTime||this.getAliveTime()0&&(this.destroyed=!1,this.emitTime=-1))}},Vh=new rt,rs=class{constructor(t,e,i,s,o,a,r,c,l=b(),u=0){this.emitter=t,this.pos=e,this.angle=i,this.size=b(r),this.color=s.copy(),this.colorStart=s,this.colorEnd=o,this.lifeTime=a,this.sizeStart=r,this.sizeEnd=c,this.velocity=l,this.angleVelocity=u,this.spawnTime=$t,this.mirror=Va(),this.groundObject=void 0,this.destroyed=!1,this.tileInfo=t.tileInfo}update(){let t=this.emitter,e=t.damping,i=t.angleDamping,s=t.restitution,o=t.friction,a=t.gravityScale,r=t.collideTiles,c=t.particleCollideCallback;if(this.lifeTime>0&&$t-this.spawnTime>this.lifeTime){this.destroy();return}let l=this.pos.copy();if(this.velocity.x*=e,this.velocity.y*=e,this.pos.x+=this.velocity.x+=Jt.x*a,this.pos.y+=this.velocity.y+=Jt.y*a,this.angle+=this.angleVelocity*=i,!Rs||!r)return;let u=this.velocity.lengthSquared();if(u>Oe*Oe){let f=Oe/u**.5;this.velocity.x*=f,this.velocity.y*=f}this.groundObject=void 0;let h=c?f=>{let d=ss(f);return d&&c(this,d,f)}:f=>ss(f)>0;if(h(this.pos)){let f=We(this.pos);if(!h(l)){let d=h(b(this.pos.x,l.y)),y=h(b(l.x,this.pos.y)),x=K(s,f.restitution),v=K(o,f.friction);d&&(this.pos.x=l.x,this.velocity.x*=-x,this.velocity.y*=v),(y||!d)&&((this.velocity.y<0&&Jt.y<0||this.velocity.y>0&&Jt.y>0)&&(this.groundObject=f),this.pos.y=l.y,this.velocity.y*=-x,this.velocity.x*=v),ce&&bt(this.pos,this.size,"#f00")}}}destroy(){let t=this.emitter.particleDestroyCallback,e=this.colorEnd;this.color.set(e.r,e.g,e.b,e.a),this.size.set(this.sizeEnd,this.sizeEnd),this.destroyed=!0,t==null||t(this)}render(){let t=this.emitter,e=t.localSpace,i=t.additive,s=t.trailScale,o=t.fadeRate/2,a=this.lifeTime>0?Z(($t-this.spawnTime)/this.lifeTime,1):1,r=1-a,c=r*this.sizeStart+a*this.sizeEnd,l=b(c),u=a1-o?(1-a)/o:1;this.color.r=r*this.colorStart.r+a*this.colorEnd.r,this.color.g=r*this.colorStart.g+a*this.colorEnd.g,this.color.b=r*this.colorStart.b+a*this.colorEnd.b,this.color.a=(r*this.colorStart.a+a*this.colorEnd.a)*u;let h=Vh.set(this.pos.x,this.pos.y),f=this.angle;if(e){let d=t.angle,y=at(-d),x=it(-d);h.set(t.pos.x+h.x*y-h.y*x,t.pos.y+h.x*x+h.y*y),f+=d}if(i&&ai(),s){let d=e?this.velocity.rotate(t.angle):this.velocity,y=d.length();if(y){let x=y*s;l.y=K(l.x,x),f=Zo(d.x,d.y),Dt(h,l,this.tileInfo,this.color,f,this.mirror)}}else Dt(h,l,this.tileInfo,this.color,f,this.mirror);i&&ai(!1),fn&&bt(h,l,"#f005",0,f)}},Lr=!0,vo=!0,us=5e5,Dr=11,pc=Dr*4,Wh=us/pc|0,Ds=3,gc=Ds*4,In=us/gc|0;an=!1,hs=5,On=.5,ds=b(640,80),Br=!1,bi={},zi=[];ps=class{constructor(t,e,i="",s="\u{1F3C6}",o){p(t>=0&&!bi[t]),this.id=t,this.name=e,this.description=i,this.icon=s,this.unlocked=!1,this.image=void 0,o&&((this.image=new Image).src=o),bi[t]=this}unlock(){Br||this.unlocked||(p(fs,"save name must be set"),this.unlocked=!0,Nr(),zi.push(this))}render(t=0){let e=lt,i=Z(ds.x,N.width),s=ds.y,o=N.width-i,a=-s*t,r=Le(0,0,.9);e.save(),e.beginPath(),e.fillStyle=r.toString(),e.strokeStyle=st.toString(),e.lineWidth=3,e.rect(o,a,i,s),e.fill(),e.stroke(),e.clip();let c=b(.1,.05).scale(s),l=s-2*c.x;this.renderIcon(b(o+c.x+l/2,a+s/2),l);let u=s*.5,h=s*.3,f=b(o+l+2*c.x,a+c.y*2+u/2),d=i-l-3*c.x;Ke(this.name,f,u,st,0,void 0,"left",void 0,void 0,d),f.y=a+s-c.y*2-h/2,Ke(this.description,f,h,st,0,void 0,"left",void 0,void 0,d),e.restore()}renderIcon(t,e){this.image?lt.drawImage(this.image,t.x-e/2,t.y-e/2,e,e):Ke(this.icon,t,e*.7,st)}};To=class extends ps{constructor(t,e,i,s,o){super(t,e,i,s,o)}unlock(){super.unlock(),xi&&xi.unlockMedal(this.id)}},Ao=class{constructor(t,e,i){var c,l,u;p(!xi,"there can only be one newgrounds object"),p(!e||i,"must provide cryptojs if there is a cipher"),xi=this,this.app_id=t,this.cipher=e,this.cryptoJS=i,this.host=location?location.hostname:"";let s=new URL(location.href);if(this.session_id=s.searchParams.get("ngio_session_id"),!this.session_id)return;let o=this.call("Medal.getList");if(!o||!o.result||o.result.error){an&&vt("Newgrounds session unavailable; skipping plugin init"),this.medals=[],this.scoreboards=[];return}this.medals=((c=o.result.data)==null?void 0:c.medals)||[],an&&vt(this.medals);for(let h of this.medals){let f=bi[h.id];f&&(f.image=new Image,f.image.src=h.icon,f.name=h.name,f.description=h.description,f.unlocked=h.unlocked,f.difficulty=h.difficulty,f.value=h.value,f.value&&(f.description=f.description+` (${f.value})`))}let a=this.call("ScoreBoard.getBoards");this.scoreboards=((u=(l=a==null?void 0:a.result)==null?void 0:l.data)==null?void 0:u.scoreboards)||[],an&&vt(this.scoreboards);let r=60*1e3;setInterval(()=>this.call("Gateway.ping",0,!0),r)}unlockMedal(t){return this.call("Medal.unlock",{id:t},!0)}postScore(t,e){return this.call("ScoreBoard.postScore",{id:t,value:e},!0)}getScores(t,e,i=0,s=0,o=10){return this.call("ScoreBoard.getScores",{id:t,user:e,social:i,skip:s,limit:o})}logView(){return this.call("App.logView",{host:this.host},!0)}call(t,e,i=!1){let s={component:t,parameters:e};if(this.cipher){let l=this.cryptoJS,u=l.enc.Base64.parse(this.cipher),h=l.lib.WordArray.random(16),f=l.AES.encrypt(JSON.stringify(s),u,{iv:h});s.secure=l.enc.Base64.stringify(h.concat(f.ciphertext)),s.parameters=0}let o={app_id:this.app_id,session_id:this.session_id,call:s},a=new FormData;a.append("input",JSON.stringify(o));let r=new XMLHttpRequest;r.open("POST","https://newgrounds.io/gateway_v3.php",!an&&i);try{r.send(a)}catch(l){an&&vt("newgrounds call failed",l);return}return an&&vt(r.responseText),r.responseText&&JSON.parse(r.responseText)}},Eo=class{constructor(t,e=!1,i=!1){p(!It,"Post process already initialized"),p(!(e&&i),"Post process cannot both include main canvas and use feedback texture"),It=this,t||(t="void mainImage(out vec4 c,vec2 p){c=texture(iChannel0,p/iResolution.xy);}"),this.shader=void 0,this.texture=void 0,this.vao=void 0,s(),vn(void 0,r,o,a);function s(){if(J)return;if(!B){console.warn("PostProcessPlugin: WebGL not enabled!");return}It.texture=Ms(),It.shader=zn(`#version 300 es
 precision highp float;in vec2 p;void main(){gl_Position=vec4(p+p-1.,1,1);}`,`#version 300 es
 precision highp float;uniform sampler2D iChannel0;uniform vec3 iResolution;uniform float iTime;out vec4 c;
 `+t+`
-void main(){mainImage(c,gl_FragCoord.xy);c.a=1.;}`),Mt.vao=y.createVertexArray(),y.bindVertexArray(Mt.vao),y.bindBuffer(y.ARRAY_BUFFER,zn);let c=8,l=y.getAttribLocation(Mt.shader,"p");y.enableVertexAttribArray(l),y.vertexAttribPointer(l,2,y.FLOAT,!1,c,0)}function o(){Mt.shader=void 0,Mt.texture=void 0,vt("PostProcessPlugin: WebGL context lost")}function r(){i(),vt("PostProcessPlugin: WebGL context restored")}function a(){if(N||!G)return;Rt(),y.bindFramebuffer(y.FRAMEBUFFER,null),y.useProgram(Mt.shader),y.bindVertexArray(Mt.vao),y.pixelStorei(y.UNPACK_FLIP_Y_WEBGL,!0),y.disable(y.BLEND),y.activeTexture(y.TEXTURE0),y.bindTexture(y.TEXTURE_2D,Mt.texture),e?(je.width=I.x,je.height=I.y,Jr(tn),tn.drawImage(j,0,0),j.width|=0,y.texImage2D(y.TEXTURE_2D,0,y.RGBA,y.RGBA,y.UNSIGNED_BYTE,je)):s||y.texImage2D(y.TEXTURE_2D,0,y.RGBA,y.RGBA,y.UNSIGNED_BYTE,Z);let c=l=>y.getUniformLocation(Mt.shader,l);y.uniform1i(c("iChannel0"),0),y.uniform1f(c("iTime"),Qt),y.uniform3f(c("iResolution"),j.width,j.height,1),y.drawArrays(y.TRIANGLE_STRIP,0,4),s&&y.texImage2D(y.TEXTURE_2D,0,y.RGBA,y.RGBA,y.UNSIGNED_BYTE,Z),y.pixelStorei(y.UNPACK_FLIP_Y_WEBGL,!1),As(!0)}}},Mo=class{constructor(t,e){f(!q,"LightSystemPlugin already initialized"),f(!Mt,"LightSystemPlugin must be created before PostProcessPlugin"),q=this,this.enabled=!0,this.ambientColor=(e||nt).copy(),this.textureSize=t?t.copy():void 0,this.texture=void 0,this.lightShader=void 0,this.compositeShader=void 0,this.lightVAO=void 0,this.compositeVAO=void 0,s(),Rn(void 0,i,o,r);function s(){if(N)return;if(!G){console.warn("LightSystemPlugin: WebGL not enabled!");return}q.textureSize||(q.textureSize=I.copy()),q.texture=y.createTexture(),y.bindTexture(y.TEXTURE_2D,q.texture),y.texImage2D(y.TEXTURE_2D,0,y.RGBA,q.textureSize.x,q.textureSize.y,0,y.RGBA,y.UNSIGNED_BYTE,null),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_MAG_FILTER,y.LINEAR),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_MIN_FILTER,y.LINEAR),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_WRAP_S,y.CLAMP_TO_EDGE),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_WRAP_T,y.CLAMP_TO_EDGE),q.lightShader=Yn(`#version 300 es
+void main(){mainImage(c,gl_FragCoord.xy);c.a=1.;}`),It.vao=g.createVertexArray(),g.bindVertexArray(It.vao),g.bindBuffer(g.ARRAY_BUFFER,Mn);let c=8,l=g.getAttribLocation(It.shader,"p");g.enableVertexAttribArray(l),g.vertexAttribPointer(l,2,g.FLOAT,!1,c,0)}function o(){It.shader=void 0,It.texture=void 0,vt("PostProcessPlugin: WebGL context lost")}function a(){s(),vt("PostProcessPlugin: WebGL context restored")}function r(){if(J||!B)return;Rt(),g.bindFramebuffer(g.FRAMEBUFFER,null),g.useProgram(It.shader),g.bindVertexArray(It.vao),g.pixelStorei(g.UNPACK_FLIP_Y_WEBGL,!0),g.disable(g.BLEND),g.activeTexture(g.TEXTURE0),g.bindTexture(g.TEXTURE_2D,It.texture),e?(Ie.width=G.x,Ie.height=G.y,kr(qe),qe.drawImage(N,0,0),N.width|=0,g.texImage2D(g.TEXTURE_2D,0,g.RGBA,g.RGBA,g.UNSIGNED_BYTE,Ie)):i||g.texImage2D(g.TEXTURE_2D,0,g.RGBA,g.RGBA,g.UNSIGNED_BYTE,et);let c=l=>g.getUniformLocation(It.shader,l);g.uniform1i(c("iChannel0"),0),g.uniform1f(c("iTime"),$t),g.uniform3f(c("iResolution"),N.width,N.height,1),g.drawArrays(g.TRIANGLE_STRIP,0,4),i&&g.texImage2D(g.TEXTURE_2D,0,g.RGBA,g.RGBA,g.UNSIGNED_BYTE,et),g.pixelStorei(g.UNPACK_FLIP_Y_WEBGL,!1),yi(!0)}}},_o=class{constructor(t,e){p(!H,"LightSystemPlugin already initialized"),p(!It,"LightSystemPlugin must be created before PostProcessPlugin"),H=this,this.enabled=!0,this.ambientColor=(e||st).copy(),this.textureSize=t?t.copy():void 0,this.texture=void 0,this.lightShader=void 0,this.compositeShader=void 0,this.lightVAO=void 0,this.compositeVAO=void 0,i(),vn(void 0,s,o,a);function i(){if(J)return;if(!B){console.warn("LightSystemPlugin: WebGL not enabled!");return}H.textureSize||(H.textureSize=G.copy()),H.texture=g.createTexture(),g.bindTexture(g.TEXTURE_2D,H.texture),g.texImage2D(g.TEXTURE_2D,0,g.RGBA,H.textureSize.x,H.textureSize.y,0,g.RGBA,g.UNSIGNED_BYTE,null),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_MAG_FILTER,g.LINEAR),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_MIN_FILTER,g.LINEAR),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_S,g.CLAMP_TO_EDGE),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_WRAP_T,g.CLAMP_TO_EDGE),H.lightShader=zn(`#version 300 es
 precision highp float;uniform mat4 m;uniform vec2 lightPos;uniform float radius;in vec2 g;out vec2 vWorldPos;void main(){vec2 worldP=lightPos+(g-.5)*2.*radius;gl_Position=m*vec4(worldP,1,1);vWorldPos=worldP;}`,`#version 300 es
-precision highp float;uniform vec2 lightPos;uniform float radius;uniform float fadeRange;uniform vec4 color;in vec2 vWorldPos;out vec4 c;void main(){float dist=distance(vWorldPos,lightPos);float t=clamp((radius-dist)/max(fadeRange,1e-6),0.,1.);c=vec4(color.rgb*t*color.a,1.);}`),q.compositeShader=Yn(`#version 300 es
+precision highp float;uniform vec2 lightPos;uniform float radius;uniform float fadeRange;uniform vec4 color;in vec2 vWorldPos;out vec4 c;void main(){float dist=distance(vWorldPos,lightPos);float t=clamp((radius-dist)/max(fadeRange,1e-6),0.,1.);c=vec4(color.rgb*t*color.a,1.);}`),H.compositeShader=zn(`#version 300 es
 precision highp float;in vec2 p;void main(){gl_Position=vec4(p+p-1.,1,1);}`,`#version 300 es
-precision highp float;uniform sampler2D s;uniform vec3 iResolution;out vec4 c;void main(){vec2 uv=gl_FragCoord.xy/iResolution.xy;c=vec4(texture(s,uv).rgb,1.);}`),q.lightVAO=y.createVertexArray(),y.bindVertexArray(q.lightVAO),y.bindBuffer(y.ARRAY_BUFFER,zn);let a=y.getAttribLocation(q.lightShader,"g");y.enableVertexAttribArray(a),y.vertexAttribPointer(a,2,y.FLOAT,!1,8,0),q.compositeVAO=y.createVertexArray(),y.bindVertexArray(q.compositeVAO),y.bindBuffer(y.ARRAY_BUFFER,zn);let c=y.getAttribLocation(q.compositeShader,"p");y.enableVertexAttribArray(c),y.vertexAttribPointer(c,2,y.FLOAT,!1,8,0)}function i(){if(N||!G||!q.enabled||!q.texture)return;Rt();let a=Mn,c=q.ambientColor;y.bindFramebuffer(y.FRAMEBUFFER,jr),y.framebufferTexture2D(y.FRAMEBUFFER,y.COLOR_ATTACHMENT0,y.TEXTURE_2D,q.texture,0),y.viewport(0,0,q.textureSize.x,q.textureSize.y),y.clearColor(c.r,c.g,c.b,c.a),y.clear(y.COLOR_BUFFER_BIT),ys(),y.enable(y.BLEND),y.blendFunc(y.ONE,y.ONE);for(let u of St)u.destroyed||u.renderLight();Rt(),y.bindFramebuffer(y.FRAMEBUFFER,null),y.viewport(0,0,I.x,I.y),y.useProgram(q.compositeShader),y.bindVertexArray(q.compositeVAO),y.activeTexture(y.TEXTURE0),y.bindTexture(y.TEXTURE_2D,q.texture);let l=q.compositeShader;y.uniform1i(y.getUniformLocation(l,"s"),0),y.uniform3f(y.getUniformLocation(l,"iResolution"),j.width,j.height,1),y.blendFunc(y.DST_COLOR,y.ZERO),y.drawArrays(y.TRIANGLE_STRIP,0,4),Zt&&y.bindTexture(y.TEXTURE_2D,Zt),ys(a),As(!0)}function o(){q.texture=void 0,q.lightShader=void 0,q.compositeShader=void 0,q.lightVAO=void 0,q.compositeVAO=void 0,vt("LightSystemPlugin: WebGL context lost")}function r(){s(),vt("LightSystemPlugin: WebGL context restored")}}drawLight(t){if(N||!G||!this.lightShader)return;Rt(),y.useProgram(this.lightShader),y.bindVertexArray(this.lightVAO);let e=b(2*H).divide(I),s=Et.rotate(-K),i=b(-1).subtract(s.multiply(e)),o=at(K),r=et(K),a=[e.x*o,e.y*r,0,0,-e.x*r,e.y*o,0,0,1,1,1,0,i.x,i.y,0,1],c=this.lightShader;y.uniformMatrix4fv(y.getUniformLocation(c,"m"),!1,a),y.uniform2f(y.getUniformLocation(c,"lightPos"),t.pos.x,t.pos.y),y.uniform1f(y.getUniformLocation(c,"radius"),t.radius),y.uniform1f(y.getUniformLocation(c,"fadeRange"),t.fadeRange);let l=t.color;y.uniform4f(y.getUniformLocation(c,"color"),l.r,l.g,l.b,l.a),y.drawArrays(y.TRIANGLE_STRIP,0,4),As(!0)}},Io=class extends ze{constructor(t,e,s,i){super(t,b(1),void 0,0,s),f(R(e)&&e>=0,"Light radius must be a non-negative number"),f(i===void 0||R(i)&&i>=0,"Light fadeRange must be a non-negative number when provided"),this.radius=e,this.fadeRange=i===void 0?e:i}render(){}renderLight(){q&&q.drawLight(this)}},ko=class extends vs{constructor(t){super(void 0),!(!Xt||N)&&(this.randomness=0,this.sampleChannels=Lc(...t),this.sampleRate=Zn)}playMusic(t=1,e=!0){return super.play(void 0,t,1,0,e)}};Xr=0;Go=class{constructor(t=ut){f(!C,"UI system already initialized"),C=this,this.activateOnPress=!1,this.defaultColor=W,this.defaultLineColor=nt,this.defaultTextColor=nt,this.defaultButtonColor=Ie(0,0,.7),this.defaultHoverColor=Ie(0,0,.9),this.defaultDisabledColor=Ie(0,0,.3),this.defaultGradientColor=void 0,this.defaultLineWidth=4,this.defaultCornerRadius=0,this.defaultTextFitScale=.8,this.defaultFont=Ls,this.defaultSoundPress=void 0,this.defaultSoundRelease=void 0,this.defaultSoundClick=void 0,this.defaultShadowColor=pe,this.defaultShadowBlur=5,this.defaultShadowOffset=b(5),this.nativeHeight=0,this.navigationObject=void 0,this.navigationTimer=new Ae(void 0,!0),this.navigationDelay=.2,this.navigationDirection=1,this.navigationMode=!1,this.uiObjects=[],this.uiContext=t,this.activeObject=void 0,this.hoverObject=void 0,this.lastHoverObject=void 0,this.confirmDialog=void 0,this._keyInputObject=void 0,this._onKeyDown=o=>{var r;return(r=this._keyInputObject)==null?void 0:r.onKeyDown(o)},Rn(s,i);function e(o){let r,a;o.parent?(r=o.parent.nativePos,a=o.parent.size):(r=C.screenToNative(I.scale(.5)),a=C.nativeHeight?b(I.x*C.nativeHeight/I.y,C.nativeHeight):I);let c=o.anchor;o.nativePos=r.add(a.multiply(c).scale(.5)).subtract(o.size.multiply(c).scale(.5)).add(o.localPos)}function s(){C.activeObject&&!C.activeObject.visible&&(C.activeObject=void 0),C.lastHoverObject=C.hoverObject,C.hoverObject=void 0,gs(0)&&(C.navigationMode=!1,C.navigationObject=void 0),C.keyInputObject&&(C.activeObject=C.keyInputObject,C.hoverObject=C.keyInputObject,C.navigationMode=!1,C.navigationObject=void 0);let o=C.getNavigableObjects();if(!o.length)C.navigationObject=void 0;else if(!C.keyInputObject){if(o.includes(C.navigationObject)||(C.navigationObject=void 0),ie||C.navigationMode&&!C.navigationObject&&(C.navigationObject=o.find(a=>a.navigationAutoSelect)),!C.navigationTimer.active()){let a=ne(C.getNavigationDirection());if(a){let c;if(C.navigationObject){let l=o.indexOf(C.navigationObject),u=se(l+a,o.length);c=o[u]}else if(c=o.find(l=>l.navigationAutoSelect),!c){let l=a>0?0:o.length-1;c=o[l]}C.navigationObject!==c&&(C.navigationMode=!0,C.hoverObject=void 0,C.navigationObject=c,C.navigationTimer.set(C.navigationDelay),c.soundPress&&c.soundPress.play())}}C.navigationObject&&C.getNavigationWasPressed()&&C.navigationObject.navigatePressed()}for(let a=C.uiObjects.length;a--;){let c=C.uiObjects[a];c.parent||r(c)}C.uiObjects=C.uiObjects.filter(a=>!a.destroyed);function r(a){if(!(a.destroyed||!a.visible)){e(a);for(let c=a.children.length;c--;){let l=a.children[c];l&&r(l)}a.destroyed||a.update()}}}function i(){let o=C.uiContext;if(o.save(),C.nativeHeight){let a=I.y/C.nativeHeight;o.translate(-a*I.x/2,0),o.scale(a,a),o.translate(I.x/2/a,0)}function r(a){if(a.visible){e(a),a.render();for(let c of a.children)r(c)}}if(C.uiObjects.forEach(a=>a.parent||r(a)),Xr>0){let a=function(c,l=!0){l&&(l=!!c.visible),e(c),c.renderDebug(l);for(let u of c.children)a(u,l)};C.uiObjects.forEach(c=>c.parent||a(c))}o.restore()}}drawRect(t,e,s=W,i=0,o=nt,r=0,a,c=nt,l=0,u=b()){f(L(t),"pos must be a vec2"),f(L(e),"size must be a vec2"),f(J(s),"color must be a color"),f(R(i),"lineWidth must be a number"),f(J(o),"lineColor must be a color"),f(R(r),"cornerRadius must be a number");let h=C.uiContext;if(a){let p=h.createLinearGradient(t.x,t.y-e.y/2,t.x,t.y+e.y/2),d=s.toString();p.addColorStop(0,d),p.addColorStop(.5,a.toString()),p.addColorStop(1,d),h.fillStyle=p}else h.fillStyle=s.toString();(l||u.x||u.y)&&c.a>0&&(h.shadowColor=c.toString(),h.shadowBlur=l,h.shadowOffsetX=u.x,h.shadowOffsetY=u.y),h.beginPath(),r&&h.roundRect?h.roundRect(t.x-e.x/2,t.y-e.y/2,e.x,e.y,r):h.rect(t.x-e.x/2,t.y-e.y/2,e.x,e.y),h.fill(),h.shadowColor="#0000",i&&o.a>0&&(h.strokeStyle=o.toString(),h.lineWidth=i,h.stroke())}drawLine(t,e,s=C.defaultLineWidth,i=C.defaultLineColor){f(L(t),"posA must be a vec2"),f(L(e),"posB must be a vec2"),f(R(s),"lineWidth must be a number"),f(J(i),"lineColor must be a color");let o=C.uiContext;o.strokeStyle=i.toString(),o.lineWidth=s,o.beginPath(),o.lineTo(t.x,t.y),o.lineTo(e.x,e.y),o.stroke()}drawTile(t,e,s,i=C.defaultColor,o=0,r=!1,a=nt,c=0,l=b()){let u=C.uiContext;(c||l.x||l.y)&&a.a>0&&(u.shadowColor=a.toString(),u.shadowBlur=c,u.shadowOffsetX=l.x,u.shadowOffsetY=l.y),Ot(t,e,s,i,o,r,pe,!1,!0,u),u.shadowColor="#0000"}drawText(t,e,s,i=C.defaultColor,o=C.defaultLineWidth,r=C.defaultLineColor,a="center",c=C.defaultFont,l="",u=!0,h=void 0,p=nt,d=0,g=b()){let x=C.uiContext;p.a>0&&(h&&rn(t,e.add(h),s.y,p,o,r,a,c,l,u?s.x:void 0,0,x),(d||g.x||g.y)&&(x.shadowColor=p.toString(),x.shadowBlur=d,x.shadowOffsetX=g.x,x.shadowOffsetY=g.y)),rn(t,e,s.y,i,o,r,a,c,l,u?s.x:void 0,0,x),x.shadowColor="#0000"}setupDragAndDrop(t,e,s,i){if(this._dragListeners)for(let[r,a]of this._dragListeners)document.removeEventListener(r,a);this._dragListeners=[];let o=(r,a)=>{let c=l=>{l.preventDefault(),r&&r(l)};document.addEventListener(a,c),this._dragListeners.push([a,c])};o(t,"drop"),o(e,"dragenter"),o(s,"dragleave"),o(i,"dragover")}screenToNative(t){if(!C.nativeHeight)return t;let e=I.y/C.nativeHeight,s=1/e,i=t.copy();return i.x+=e*I.x/2,i.x*=s,i.y*=s,i.x-=s*I.x/2,i}get keyInputObject(){return this._keyInputObject}set keyInputObject(t){let e=!!this._keyInputObject;this._keyInputObject=t,!e&&t?document.addEventListener("keydown",this._onKeyDown):e&&!t&&document.removeEventListener("keydown",this._onKeyDown)}destroyObjects(){for(let t of this.uiObjects)t.parent||t.destroy();this.uiObjects=this.uiObjects.filter(t=>!t.destroyed),this.activeObject=void 0,this.hoverObject=void 0,this.lastHoverObject=void 0,this.keyInputObject=void 0}getNavigableObjects(){function t(s){if(!(!s.visible||s.disabled)){s.isInteractive()&&s.navigationIndex!==void 0&&e.push(s);for(let i=s.children.length;i--;)t(s.children[i])}}let e=[];for(let s=C.uiObjects.length;s--;){let i=C.uiObjects[s];C.confirmDialog&&i!==C.confirmDialog||i.parent||t(i)}return e.sort((s,i)=>s.navigationIndex-i.navigationIndex),e}getNavigationDirection(){let t=C.navigationDirection===1,e=C.navigationDirection===2;if(Nn){let l=ms(0,mt),u=So(mt);return e?-(l.y||u.y)||l.x||u.x:t?-(l.y||u.y):l.x||u.x}let s="ArrowUp",i="ArrowDown",o="ArrowLeft",r="ArrowRight";if(e)return Lt(s)||Lt(o)?-1:Lt(i)||Lt(r)?1:0;let a=t?s:o,c=t?i:r;return Lt(a)?-1:Lt(c)?1:0}getNavigationOtherDirection(){if(C.navigationDirection===2)return 0;let t=C.navigationDirection===1;if(Nn){let i=ms(0,mt),o=So(mt);return t?i.x||o.x:i.y||o.y}let e=t?"ArrowLeft":"ArrowUp",s=t?"ArrowRight":"ArrowDown";return Lt(e)?-1:Lt(s)?1:0}getNavigationWasPressed(){return Nn?Or(0,mt):It("Space")||It("Enter")}showConfirmDialog(t="Are you sure?",e,s,i=b(500,250),o="Escape"){f(!C.confirmDialog);let r=C.navigationDirection;C.navigationDirection=2;let a=new re(b(),i);C.confirmDialog=a,a.onRender=()=>{let d=Ie(0,0,0,.7);C.drawRect(b(),b(1e9),d)},a.onUpdate=()=>{It(o)&&p()},a.isMouseOverlapping=()=>!0;let c=50,l=new wi(b(0,-50),b(i.x-c,70),t);a.addChild(l);let u=new Rs(b(-80,50),b(120,70),"Yes");u.textHeight=40,u.navigationIndex=1,u.hoverColor=Ie(0,1,.5),u.onClick=()=>{p(),e&&e()},a.addChild(u);let h=new Rs(b(80,50),b(120,70),"No");h.textHeight=40,h.navigationIndex=2,h.navigationAutoSelect=!0,h.onClick=()=>{p(),s&&s()},a.addChild(h);function p(){f(C.confirmDialog===a),a.destroy(),C.confirmDialog=void 0,C.navigationDirection=r,Fs()}}},re=class{constructor(t=b(),e=b()){var s,i;f(L(t),"ui object pos must be a vec2"),f(L(e),"ui object size must be a vec2"),this.localPos=t.copy(),this.nativePos=t.copy(),this.size=e.copy(),this.color=C.defaultColor.copy(),this.activeColor=void 0,this.text=void 0,this.disabledColor=C.defaultDisabledColor.copy(),this.disabled=!1,this.textColor=C.defaultTextColor.copy(),this.hoverColor=C.defaultHoverColor.copy(),this.lineColor=C.defaultLineColor.copy(),this.gradientColor=C.defaultGradientColor?C.defaultGradientColor.copy():void 0,this.lineWidth=C.defaultLineWidth,this.cornerRadius=C.defaultCornerRadius,this.font=C.defaultFont,this.fontStyle=void 0,this.textWidth=void 0,this.textHeight=void 0,this.textFitScale=C.defaultTextFitScale,this.textShadow=void 0,this.textLineColor=C.defaultLineColor.copy(),this.textLineWidth=0,this.visible=!0,this.children=[],this.parent=void 0,this.extraTouchSize=0,this.soundPress=C.defaultSoundPress,this.soundRelease=C.defaultSoundRelease,this.soundClick=C.defaultSoundClick,this.interactive=!1,this.dragActivate=!1,this.canBeHover=!0,this.shadowColor=(s=C.defaultShadowColor)==null?void 0:s.copy(),this.shadowBlur=C.defaultShadowBlur,this.shadowOffset=(i=C.defaultShadowOffset)==null?void 0:i.copy(),this.navigationIndex=void 0,this.navigationAutoSelect=!1,this.anchor=b(),C.uiObjects.push(this)}addChild(t){return f(!t.parent&&!this.children.includes(t)),this.children.push(t),t.parent=this,t}removeChild(t){f(t.parent===this&&this.children.includes(t)),this.children.splice(this.children.indexOf(t),1),t.parent=void 0}destroy(){var t;if(!this.destroyed){C.activeObject===this&&(C.activeObject=void 0),C.hoverObject===this&&(C.hoverObject=void 0),C.lastHoverObject===this&&(C.lastHoverObject=void 0),C.navigationObject===this&&(C.navigationObject=void 0),C.keyInputObject===this&&(C.keyInputObject=void 0),this.destroyed=1,(t=this.parent)==null||t.removeChild(this);for(let e of this.children)e.parent=void 0,e.destroy();this.children.length=0}}isMouseOverlapping(){if(!ai)return!1;let t=ie?this.size.add(b(this.extraTouchSize||0)):this.size,e=C.screenToNative(Ut);return ti(this.nativePos,t,e)}update(){if(this.onUpdate(),this.disabled&&(this===C.activeObject&&(C.activeObject=void 0),this===C.keyInputObject&&(C.keyInputObject=void 0)),C.keyInputObject)return;let t=C.lastHoverObject===this,e=this.isActiveObject(),s=us(0),i=this.dragActivate?s:gs(0);this.canBeHover&&(C.navigationMode||(i||e||!s&&!ie)&&!C.hoverObject&&this.isMouseOverlapping()&&(C.hoverObject=this)),this.isHoverObject()&&(this.disabled||(i&&this.interactive&&((!this.dragActivate||!t||gs(0))&&this.onPress(),this.soundPress&&this.soundPress.play(),C.activeObject&&!e&&C.activeObject.onRelease(),C.activeObject=this,C.activateOnPress&&this.click(!this.soundPress)),C.activateOnPress||!s&&this.isActiveObject()&&this.interactive&&this.click()),i&&Pr(0,0,0,1,0)),e&&(!s||this.dragActivate&&!this.isHoverObject())&&(this.onRelease(),this.soundRelease&&this.soundRelease.play(),C.activeObject=void 0),this.isHoverObject()!==t&&(this.isHoverObject()?this.onEnter():this.onLeave())}render(){if(this.onRender(),!this.size.x||!this.size.y)return;let t=this.isNavigationObject(),e=t?this.color:this.interactive&&this.isActiveObject()&&!this.disabled?this.color:this.lineColor,s=t?this.hoverColor:this.disabled?this.disabledColor:this.interactive?this.isActiveObject()?this.activeColor||this.hoverColor:this.isHoverObject()?this.hoverColor:this.color:this.color,i=this.lineWidth*(t?1.5:1);C.drawRect(this.nativePos,this.size,s,i,e,this.cornerRadius,this.gradientColor,this.shadowColor,this.shadowBlur,this.shadowOffset)}getTextSize(){return b(this.textWidth||this.textFitScale*this.size.x,this.textHeight||this.textFitScale*this.size.y)}navigatePressed(){this.click()}isHoverObject(){return C.hoverObject===this}isActiveObject(){return C.activeObject===this}isNavigationObject(){return C.navigationObject===this}isKeyInputObject(){return C.keyInputObject===this}isInteractive(){return this.interactive&&this.visible&&!this.disabled}toString(){let t="type = "+this.constructor.name;return this.text&&(t+=`
+precision highp float;uniform sampler2D s;uniform vec3 iResolution;out vec4 c;void main(){vec2 uv=gl_FragCoord.xy/iResolution.xy;c=vec4(texture(s,uv).rgb,1.);}`),H.lightVAO=g.createVertexArray(),g.bindVertexArray(H.lightVAO),g.bindBuffer(g.ARRAY_BUFFER,Mn);let r=g.getAttribLocation(H.lightShader,"g");g.enableVertexAttribArray(r),g.vertexAttribPointer(r,2,g.FLOAT,!1,8,0),H.compositeVAO=g.createVertexArray(),g.bindVertexArray(H.compositeVAO),g.bindBuffer(g.ARRAY_BUFFER,Mn);let c=g.getAttribLocation(H.compositeShader,"p");g.enableVertexAttribArray(c),g.vertexAttribPointer(c,2,g.FLOAT,!1,8,0)}function s(){if(J||!B||!H.enabled||!H.texture)return;Rt();let r=En,c=H.ambientColor;g.bindFramebuffer(g.FRAMEBUFFER,Or),g.framebufferTexture2D(g.FRAMEBUFFER,g.COLOR_ATTACHMENT0,g.TEXTURE_2D,H.texture,0),g.viewport(0,0,H.textureSize.x,H.textureSize.y),g.clearColor(c.r,c.g,c.b,c.a),g.clear(g.COLOR_BUFFER_BIT),ai(),g.enable(g.BLEND),g.blendFunc(g.ONE,g.ONE);for(let u of St)u.destroyed||u.renderLight();Rt(),g.bindFramebuffer(g.FRAMEBUFFER,null),g.viewport(0,0,G.x,G.y),g.useProgram(H.compositeShader),g.bindVertexArray(H.compositeVAO),g.activeTexture(g.TEXTURE0),g.bindTexture(g.TEXTURE_2D,H.texture);let l=H.compositeShader;g.uniform1i(g.getUniformLocation(l,"s"),0),g.uniform3f(g.getUniformLocation(l,"iResolution"),N.width,N.height,1),g.blendFunc(g.DST_COLOR,g.ZERO),g.drawArrays(g.TRIANGLE_STRIP,0,4),Kt&&g.bindTexture(g.TEXTURE_2D,Kt),ai(r),yi(!0)}function o(){H.texture=void 0,H.lightShader=void 0,H.compositeShader=void 0,H.lightVAO=void 0,H.compositeVAO=void 0,vt("LightSystemPlugin: WebGL context lost")}function a(){i(),vt("LightSystemPlugin: WebGL context restored")}}drawLight(t){if(J||!B||!this.lightShader)return;Rt(),g.useProgram(this.lightShader),g.bindVertexArray(this.lightVAO);let e=b(2*X).divide(G),i=Ct.rotate(-Q),s=b(-1).subtract(i.multiply(e)),o=at(Q),a=it(Q),r=[e.x*o,e.y*a,0,0,-e.x*a,e.y*o,0,0,1,1,1,0,s.x,s.y,0,1],c=this.lightShader;g.uniformMatrix4fv(g.getUniformLocation(c,"m"),!1,r),g.uniform2f(g.getUniformLocation(c,"lightPos"),t.pos.x,t.pos.y),g.uniform1f(g.getUniformLocation(c,"radius"),t.radius),g.uniform1f(g.getUniformLocation(c,"fadeRange"),t.fadeRange);let l=t.color;g.uniform4f(g.getUniformLocation(c,"color"),l.r,l.g,l.b,l.a),g.drawArrays(g.TRIANGLE_STRIP,0,4),yi(!0)}},Co=class extends Fe{constructor(t,e,i,s){super(t,b(1),void 0,0,i),p(P(e)&&e>=0,"Light radius must be a non-negative number"),p(s===void 0||P(s)&&s>=0,"Light fadeRange must be a non-negative number when provided"),this.radius=e,this.fadeRange=s===void 0?e:s}render(){}renderLight(){H&&H.drawLight(this)}},Ro=class extends di{constructor(t){super(void 0),!(!Wt||J)&&(this.randomness=0,this.sampleChannels=Tc(...t),this.sampleRate=Wn)}playMusic(t=1,e=!0){return super.play(void 0,t,1,0,e)}};zr=0;Po=class{constructor(t=lt){p(!E,"UI system already initialized"),E=this,this.activateOnPress=!1,this.defaultColor=q,this.defaultLineColor=st,this.defaultTextColor=st,this.defaultButtonColor=Le(0,0,.7),this.defaultHoverColor=Le(0,0,.9),this.defaultDisabledColor=Le(0,0,.3),this.defaultGradientColor=void 0,this.defaultLineWidth=4,this.defaultCornerRadius=0,this.defaultTextFitScale=.8,this.defaultFont=wi,this.defaultSoundPress=void 0,this.defaultSoundRelease=void 0,this.defaultSoundClick=void 0,this.defaultShadowColor=de,this.defaultShadowBlur=5,this.defaultShadowOffset=b(5),this.nativeHeight=0,this.navigationObject=void 0,this.navigationTimer=new we(void 0,!0),this.navigationDelay=.2,this.navigationDirection=1,this.navigationMode=!1,this.uiObjects=[],this.uiContext=t,this.activeObject=void 0,this.hoverObject=void 0,this.lastHoverObject=void 0,this.confirmDialog=void 0,this._keyInputObject=void 0,this._onKeyDown=o=>{var a;return(a=this._keyInputObject)==null?void 0:a.onKeyDown(o)},vn(i,s);function e(o){let a,r;o.parent?(a=o.parent.nativePos,r=o.parent.size):(a=E.screenToNative(G.scale(.5)),r=E.nativeHeight?b(G.x*E.nativeHeight/G.y,E.nativeHeight):G);let c=o.anchor;o.nativePos=a.add(r.multiply(c).scale(.5)).subtract(o.size.multiply(c).scale(.5)).add(o.localPos)}function i(){E.activeObject&&!E.activeObject.visible&&(E.activeObject=void 0),E.lastHoverObject=E.hoverObject,E.hoverObject=void 0,ci(0)&&(E.navigationMode=!1,E.navigationObject=void 0),E.keyInputObject&&(E.activeObject=E.keyInputObject,E.hoverObject=E.keyInputObject,E.navigationMode=!1,E.navigationObject=void 0);let o=E.getNavigableObjects();if(!o.length)E.navigationObject=void 0;else if(!E.keyInputObject){if(o.includes(E.navigationObject)||(E.navigationObject=void 0),ne||E.navigationMode&&!E.navigationObject&&(E.navigationObject=o.find(r=>r.navigationAutoSelect)),!E.navigationTimer.active()){let r=te(E.getNavigationDirection());if(r){let c;if(E.navigationObject){let l=o.indexOf(E.navigationObject),u=ee(l+r,o.length);c=o[u]}else if(c=o.find(l=>l.navigationAutoSelect),!c){let l=r>0?0:o.length-1;c=o[l]}E.navigationObject!==c&&(E.navigationMode=!0,E.hoverObject=void 0,E.navigationObject=c,E.navigationTimer.set(E.navigationDelay),c.soundPress&&c.soundPress.play())}}E.navigationObject&&E.getNavigationWasPressed()&&E.navigationObject.navigatePressed()}for(let r=E.uiObjects.length;r--;){let c=E.uiObjects[r];c.parent||a(c)}E.uiObjects=E.uiObjects.filter(r=>!r.destroyed);function a(r){if(!(r.destroyed||!r.visible)){e(r);for(let c=r.children.length;c--;){let l=r.children[c];l&&a(l)}r.destroyed||r.update()}}}function s(){let o=E.uiContext;if(o.save(),E.nativeHeight){let r=G.y/E.nativeHeight;o.translate(-r*G.x/2,0),o.scale(r,r),o.translate(G.x/2/r,0)}function a(r){if(r.visible){e(r),r.render();for(let c of r.children)a(c)}}if(E.uiObjects.forEach(r=>r.parent||a(r)),zr>0){let r=function(c,l=!0){l&&(l=!!c.visible),e(c),c.renderDebug(l);for(let u of c.children)r(u,l)};E.uiObjects.forEach(c=>c.parent||r(c))}o.restore()}}drawRect(t,e,i=q,s=0,o=st,a=0,r,c=st,l=0,u=b()){p(O(t),"pos must be a vec2"),p(O(e),"size must be a vec2"),p(V(i),"color must be a color"),p(P(s),"lineWidth must be a number"),p(V(o),"lineColor must be a color"),p(P(a),"cornerRadius must be a number");let h=E.uiContext;if(r){let f=h.createLinearGradient(t.x,t.y-e.y/2,t.x,t.y+e.y/2),d=i.toString();f.addColorStop(0,d),f.addColorStop(.5,r.toString()),f.addColorStop(1,d),h.fillStyle=f}else h.fillStyle=i.toString();(l||u.x||u.y)&&c.a>0&&(h.shadowColor=c.toString(),h.shadowBlur=l,h.shadowOffsetX=u.x,h.shadowOffsetY=u.y),h.beginPath(),a&&h.roundRect?h.roundRect(t.x-e.x/2,t.y-e.y/2,e.x,e.y,a):h.rect(t.x-e.x/2,t.y-e.y/2,e.x,e.y),h.fill(),h.shadowColor="#0000",s&&o.a>0&&(h.strokeStyle=o.toString(),h.lineWidth=s,h.stroke())}drawLine(t,e,i=E.defaultLineWidth,s=E.defaultLineColor){p(O(t),"posA must be a vec2"),p(O(e),"posB must be a vec2"),p(P(i),"lineWidth must be a number"),p(V(s),"lineColor must be a color");let o=E.uiContext;o.strokeStyle=s.toString(),o.lineWidth=i,o.beginPath(),o.lineTo(t.x,t.y),o.lineTo(e.x,e.y),o.stroke()}drawTile(t,e,i,s=E.defaultColor,o=0,a=!1,r=st,c=0,l=b()){let u=E.uiContext;(c||l.x||l.y)&&r.a>0&&(u.shadowColor=r.toString(),u.shadowBlur=c,u.shadowOffsetX=l.x,u.shadowOffsetY=l.y),Dt(t,e,i,s,o,a,de,!1,!0,u),u.shadowColor="#0000"}drawText(t,e,i,s=E.defaultColor,o=E.defaultLineWidth,a=E.defaultLineColor,r="center",c=E.defaultFont,l="",u=!0,h=void 0,f=st,d=0,y=b()){let x=E.uiContext;f.a>0&&(h&&Ke(t,e.add(h),i.y,f,o,a,r,c,l,u?i.x:void 0,0,x),(d||y.x||y.y)&&(x.shadowColor=f.toString(),x.shadowBlur=d,x.shadowOffsetX=y.x,x.shadowOffsetY=y.y)),Ke(t,e,i.y,s,o,a,r,c,l,u?i.x:void 0,0,x),x.shadowColor="#0000"}setupDragAndDrop(t,e,i,s){if(this._dragListeners)for(let[a,r]of this._dragListeners)document.removeEventListener(a,r);this._dragListeners=[];let o=(a,r)=>{let c=l=>{l.preventDefault(),a&&a(l)};document.addEventListener(r,c),this._dragListeners.push([r,c])};o(t,"drop"),o(e,"dragenter"),o(i,"dragleave"),o(s,"dragover")}screenToNative(t){if(!E.nativeHeight)return t;let e=G.y/E.nativeHeight,i=1/e,s=t.copy();return s.x+=e*G.x/2,s.x*=i,s.y*=i,s.x-=i*G.x/2,s}get keyInputObject(){return this._keyInputObject}set keyInputObject(t){let e=!!this._keyInputObject;this._keyInputObject=t,!e&&t?document.addEventListener("keydown",this._onKeyDown):e&&!t&&document.removeEventListener("keydown",this._onKeyDown)}destroyObjects(){for(let t of this.uiObjects)t.parent||t.destroy();this.uiObjects=this.uiObjects.filter(t=>!t.destroyed),this.activeObject=void 0,this.hoverObject=void 0,this.lastHoverObject=void 0,this.keyInputObject=void 0}getNavigableObjects(){function t(i){if(!(!i.visible||i.disabled)){i.isInteractive()&&i.navigationIndex!==void 0&&e.push(i);for(let s=i.children.length;s--;)t(i.children[s])}}let e=[];for(let i=E.uiObjects.length;i--;){let s=E.uiObjects[i];E.confirmDialog&&s!==E.confirmDialog||s.parent||t(s)}return e.sort((i,s)=>i.navigationIndex-s.navigationIndex),e}getNavigationDirection(){let t=E.navigationDirection===1,e=E.navigationDirection===2;if(Dn){let l=li(0,mt),u=po(mt);return e?-(l.y||u.y)||l.x||u.x:t?-(l.y||u.y):l.x||u.x}let i="ArrowUp",s="ArrowDown",o="ArrowLeft",a="ArrowRight";if(e)return Ot(i)||Ot(o)?-1:Ot(s)||Ot(a)?1:0;let r=t?i:o,c=t?s:a;return Ot(r)?-1:Ot(c)?1:0}getNavigationOtherDirection(){if(E.navigationDirection===2)return 0;let t=E.navigationDirection===1;if(Dn){let s=li(0,mt),o=po(mt);return t?s.x||o.x:s.y||o.y}let e=t?"ArrowLeft":"ArrowUp",i=t?"ArrowRight":"ArrowDown";return Ot(e)?-1:Ot(i)?1:0}getNavigationWasPressed(){return Dn?Ar(0,mt):kt("Space")||kt("Enter")}showConfirmDialog(t="Are you sure?",e,i,s=b(500,250),o="Escape"){p(!E.confirmDialog);let a=E.navigationDirection;E.navigationDirection=2;let r=new se(b(),s);E.confirmDialog=r,r.onRender=()=>{let d=Le(0,0,0,.7);E.drawRect(b(),b(1e9),d)},r.onUpdate=()=>{kt(o)&&f()},r.isMouseOverlapping=()=>!0;let c=50,l=new gs(b(0,-50),b(s.x-c,70),t);r.addChild(l);let u=new vi(b(-80,50),b(120,70),"Yes");u.textHeight=40,u.navigationIndex=1,u.hoverColor=Le(0,1,.5),u.onClick=()=>{f(),e&&e()},r.addChild(u);let h=new vi(b(80,50),b(120,70),"No");h.textHeight=40,h.navigationIndex=2,h.navigationAutoSelect=!0,h.onClick=()=>{f(),i&&i()},r.addChild(h);function f(){p(E.confirmDialog===r),r.destroy(),E.confirmDialog=void 0,E.navigationDirection=a,Pi()}}},se=class{constructor(t=b(),e=b()){var i,s;p(O(t),"ui object pos must be a vec2"),p(O(e),"ui object size must be a vec2"),this.localPos=t.copy(),this.nativePos=t.copy(),this.size=e.copy(),this.color=E.defaultColor.copy(),this.activeColor=void 0,this.text=void 0,this.disabledColor=E.defaultDisabledColor.copy(),this.disabled=!1,this.textColor=E.defaultTextColor.copy(),this.hoverColor=E.defaultHoverColor.copy(),this.lineColor=E.defaultLineColor.copy(),this.gradientColor=E.defaultGradientColor?E.defaultGradientColor.copy():void 0,this.lineWidth=E.defaultLineWidth,this.cornerRadius=E.defaultCornerRadius,this.font=E.defaultFont,this.fontStyle=void 0,this.textWidth=void 0,this.textHeight=void 0,this.textFitScale=E.defaultTextFitScale,this.textShadow=void 0,this.textLineColor=E.defaultLineColor.copy(),this.textLineWidth=0,this.visible=!0,this.children=[],this.parent=void 0,this.extraTouchSize=0,this.soundPress=E.defaultSoundPress,this.soundRelease=E.defaultSoundRelease,this.soundClick=E.defaultSoundClick,this.interactive=!1,this.dragActivate=!1,this.canBeHover=!0,this.shadowColor=(i=E.defaultShadowColor)==null?void 0:i.copy(),this.shadowBlur=E.defaultShadowBlur,this.shadowOffset=(s=E.defaultShadowOffset)==null?void 0:s.copy(),this.navigationIndex=void 0,this.navigationAutoSelect=!1,this.anchor=b(),E.uiObjects.push(this)}addChild(t){return p(!t.parent&&!this.children.includes(t)),this.children.push(t),t.parent=this,t}removeChild(t){p(t.parent===this&&this.children.includes(t)),this.children.splice(this.children.indexOf(t),1),t.parent=void 0}destroy(){var t;if(!this.destroyed){E.activeObject===this&&(E.activeObject=void 0),E.hoverObject===this&&(E.hoverObject=void 0),E.lastHoverObject===this&&(E.lastHoverObject=void 0),E.navigationObject===this&&(E.navigationObject=void 0),E.keyInputObject===this&&(E.keyInputObject=void 0),this.destroyed=1,(t=this.parent)==null||t.removeChild(this);for(let e of this.children)e.parent=void 0,e.destroy();this.children.length=0}}isMouseOverlapping(){if(!ts)return!1;let t=ne?this.size.add(b(this.extraTouchSize||0)):this.size,e=E.screenToNative(Nt);return Hi(this.nativePos,t,e)}update(){if(this.onUpdate(),this.disabled&&(this===E.activeObject&&(E.activeObject=void 0),this===E.keyInputObject&&(E.keyInputObject=void 0)),E.keyInputObject)return;let t=E.lastHoverObject===this,e=this.isActiveObject(),i=ni(0),s=this.dragActivate?i:ci(0);this.canBeHover&&(E.navigationMode||(s||e||!i&&!ne)&&!E.hoverObject&&this.isMouseOverlapping()&&(E.hoverObject=this)),this.isHoverObject()&&(this.disabled||(s&&this.interactive&&((!this.dragActivate||!t||ci(0))&&this.onPress(),this.soundPress&&this.soundPress.play(),E.activeObject&&!e&&E.activeObject.onRelease(),E.activeObject=this,E.activateOnPress&&this.click(!this.soundPress)),E.activateOnPress||!i&&this.isActiveObject()&&this.interactive&&this.click()),s&&wr(0,0,0,1,0)),e&&(!i||this.dragActivate&&!this.isHoverObject())&&(this.onRelease(),this.soundRelease&&this.soundRelease.play(),E.activeObject=void 0),this.isHoverObject()!==t&&(this.isHoverObject()?this.onEnter():this.onLeave())}render(){if(this.onRender(),!this.size.x||!this.size.y)return;let t=this.isNavigationObject(),e=t?this.color:this.interactive&&this.isActiveObject()&&!this.disabled?this.color:this.lineColor,i=t?this.hoverColor:this.disabled?this.disabledColor:this.interactive?this.isActiveObject()?this.activeColor||this.hoverColor:this.isHoverObject()?this.hoverColor:this.color:this.color,s=this.lineWidth*(t?1.5:1);E.drawRect(this.nativePos,this.size,i,s,e,this.cornerRadius,this.gradientColor,this.shadowColor,this.shadowBlur,this.shadowOffset)}getTextSize(){return b(this.textWidth||this.textFitScale*this.size.x,this.textHeight||this.textFitScale*this.size.y)}navigatePressed(){this.click()}isHoverObject(){return E.hoverObject===this}isActiveObject(){return E.activeObject===this}isNavigationObject(){return E.navigationObject===this}isKeyInputObject(){return E.keyInputObject===this}isInteractive(){return this.interactive&&this.visible&&!this.disabled}toString(){let t="type = "+this.constructor.name;return this.text&&(t+=`
 text = `+this.text),(this.nativePos.x||this.nativePos.y)&&(t+=`
 nativePos = `+this.nativePos),(this.localPos.x||this.localPos.y)&&(t+=`
 localPos = `+this.localPos),(this.size.x||this.size.y)&&(t+=`
 size = `+this.size),this.color&&(t+=`
-color = `+this.color),t}renderDebug(t=!0){let e=t?this.isHoverObject()?ec:this.disabled?ic:this.interactive?lr:sc:nc;C.drawRect(this.nativePos,this.size,pe,4,e)}click(t=!0){this.onClick(),t&&this.soundClick&&this.soundClick.play()}onUpdate(){}onRender(){}onEnter(){}onLeave(){}onPress(){}onRelease(){}onClick(){}onChange(){}},wi=class extends re{constructor(t,e,s="",i="center",o=C.defaultFont){super(t,e),f(V(s),"ui text must be a string"),f(["left","center","right"].includes(i),"ui text align must be left, center, or right"),f(V(o),"ui text font must be a string"),this.text=s,this.align=i,this.font=o,this.canBeHover=!1,this.color=pe,this.shadowColor=pe,this.gradientColor=void 0,this.lineWidth=0,this.textFitScale=1}render(){super.render();let t=this.getTextSize();C.drawText(this.text,this.nativePos,t,this.textColor,this.textLineWidth,this.textLineColor,this.align,this.font,this.fontStyle,!0,this.textShadow,this.shadowColor,this.shadowBlur,this.shadowOffset)}},Fo=class extends re{constructor(t,e,s=""){super(t,e),f(V(s),"ui text must be a string"),this.maxLength=0,this.text=s,this.interactive=!0,this.canBeHover=!0}click(){C.keyInputObject=this,this.onClick()}stopEditing(){this.isKeyInputObject()&&(this.soundRelease&&this.soundRelease.play(),C.activeObject=void 0,C.keyInputObject=void 0,this.onChange())}onKeyDown(t){let e=t.code,s=t.key;e==="Backspace"?this.text=this.text.slice(0,-1):e==="Enter"||e==="Escape"?this.stopEditing():s.length===1&&(!this.maxLength||this.text.lengththis.size.y,s=e?this.size.y:this.size.x,i=e?this.size.x:this.size.y,o=e?this.nativePos.x:this.nativePos.y,r=i-s,a=o-r/2,c=o+r/2,l=C.screenToNative(Ut);this.value=e?Ft(l.x,a,c):Ft(l.y,c,a)}else if(this.isNavigationObject()){let e=C.getNavigationOtherDirection();C.navigationTimer.active()||(this.value=B(this.value+e*.01))}this.value===t||this.onChange()}render(){super.render();let t=this.size.x>this.size.y,e=t?this.size.x:this.size.y,s=t?this.size.y:this.size.x;if(this.fillMode){let o=Q(s,this.cornerRadius*2),r=qt(o,e,this.value),a=(r-e)*(t?.5:-.5),c=this.nativePos.add(t?b(a,0):b(0,a)),l=this.disabled?this.disabledColor:this.handleColor,u=t?b(r,this.size.y):b(this.size.x,r);C.drawRect(c,u,l,this.lineWidth,this.lineColor,this.cornerRadius,this.gradientColor)}else{let o=B(t?this.value:1-this.value),r=(e-s)*(o-.5),a=this.nativePos.add(t?b(r,0):b(0,r)),c=this.disabled?this.disabledColor:this.handleColor,l=b(s);C.drawRect(a,l,c,this.lineWidth,this.lineColor,this.cornerRadius,this.gradientColor)}let i=this.getTextSize();C.drawText(this.text,this.nativePos,i,this.textColor,this.textLineWidth,this.textLineColor,this.align,this.font,this.fontStyle,!0,this.textShadow)}navigatePressed(){this.value=this.value?0:1,this.onChange(),this.onRelease(),super.navigatePressed()}},zo=class extends re{constructor(t,e,s,i=!1,o=!1,r=1){super(t,e||b()),f(V(s),"video src must be a string"),f(R(r),"video volume must be a number"),this.color=nt,this.cornerRadius=0,this.volume=r,this.video=document.createElement("video"),this.video.loop=o,this.video.volume=B(r*Tn),this.video.muted=!Xt,this.video.style.display="none",this.video.src=s,document.body.appendChild(this.video),i&&this.play()}async play(){try{await this.video.play()}catch{}}pause(){this.video.pause()}stop(){this.video.pause(),this.video.currentTime=0}isLoading(){return this.video.readyState=1,"ui layout columns must be a number >= 1"),f(R(s),"ui layout gap must be a number"),f(R(i),"ui layout padding must be a number"),this.columns=e,this.gap=s,this.padding=i,o&&(this.color=pe,this.gradientColor=void 0,this.lineWidth=0,this.shadowColor=pe),this.relayout()}addChild(t){return super.addChild(t),this.relayout(),t}removeChild(t){super.removeChild(t),this.relayout()}relayout(){let t=this.children.length;if(!t){this.size=b(this.padding*2);return}let e=this.columns,s=ds(t/e),i=new Array(e).fill(0),o=new Array(s).fill(0);for(let p=0;p=0&&m.objects.splice(t,1),super.destroy()}updatePhysics(){}render(){this.tileInfo?super.render():this.drawFixtures(this.color,this.lineColor,this.lineWidth)}renderDebugInfo(){let t=!this.getIsAwake(),e=this.getBodyType()===m.bodyTypeStatic,s=z(t?1:0,t?1:0,e?1:0,.5);this.drawFixtures(s)}drawFixtures(t=W,e=nt,s=.1,i,o){this.getFixtureList().forEach(r=>{m.castShapeObject(r.GetShape()).GetType()!==m.instance.b2Shape.e_edge&&m.drawFixture(r,this.pos,this.angle,t,e,s,i,o)}),this.edgeLists.forEach(r=>vo(r,s,e,!1,this.pos,this.angle)),this.edgeLoops.forEach(r=>vo(r,s,e,!0,this.pos,this.angle))}beginContact(t){}endContact(t){}addShape(t,e=1,s=.2,i=0,o=!1){f(R(e),"density must be a number"),f(R(s),"friction must be a number"),f(R(i),"restitution must be a number");let r=new m.instance.b2FixtureDef;return r.set_shape(t),r.set_density(e),r.set_friction(s),r.set_restitution(i),r.set_isSensor(o),this.body.CreateFixture(r)}addBox(t=b(1),e=b(),s=0,i,o,r,a){f(L(t),"size must be a Vector2"),f(t.x>0&&t.y>0,"size must be positive"),f(L(e),"offset must be a Vector2"),f(R(s),"angle must be a number");let c=new m.instance.b2PolygonShape;return c.SetAsBox(t.x/2,t.y/2,m.vec2dTo(e),-s),this.addShape(c,i,o,r,a)}addPoly(t,e,s,i,o){f(de(t),"points must be an array");function r(c){f(3<=c.length&&c.length<=8);let l=m.instance._malloc(c.length*8);for(let p=0,d=0;p>2]=c[p].x,d+=4,m.instance.HEAPF32[l+d>>2]=c[p].y,d+=4;let u=m.instance.wrapPointer(l,m.instance.b2Vec2),h=new m.instance.b2PolygonShape;return h.Set(u,c.length),m.instance._free(l),h}let a=r(t);return this.addShape(a,e,s,i,o)}addRegularPoly(t=1,e=8,s,i,o,r){f(R(t)&&t>0,"diameter must be a positive number"),f(R(e)&&e>2,"sides must be a positive number greater than 2");let a=[],c=t/2;for(let l=e;l--;)a.push(b(c,0).rotate((l+.5)/e*X*2));return this.addPoly(a,s,i,o,r)}addRandomPoly(t=1,e,s,i,o){f(R(t)&&t>0,"diameter must be a positive number");let r=cr(3,9),a=[],c=t/2;for(let l=r;l--;)a.push(b(dt(c/2,c*1.5),0).rotate(l/r*X*2));return this.addPoly(a,e,s,i,o)}addCircle(t=1,e=b(),s,i,o,r){f(R(t)&&t>0,"diameter must be a positive number"),f(L(e),"offset must be a Vector2");let a=new m.instance.b2CircleShape;return a.set_m_p(m.vec2dTo(e)),a.set_m_radius(t/2),this.addShape(a,s,i,o,r)}addEdge(t,e,s,i,o,r){f(L(t),"point1 must be a Vector2"),f(L(e),"point2 must be a Vector2");let a=new m.instance.b2EdgeShape;return a.Set(m.vec2dTo(t),m.vec2dTo(e)),this.addShape(a,s,i,o,r)}addEdgeList(t,e,s,i,o){f(de(t),"points must be an array");let r=[],a=[];for(let c=0;ct[se(l,t.length)];for(let l=0;lthis.destroyFixture(t))}getCenterOfMass(){return m.vec2From(this.body.GetWorldCenter())}getLinearVelocity(){return m.vec2From(this.body.GetLinearVelocity())}getAngularVelocity(){return this.body.GetAngularVelocity()}getMass(){return this.body.GetMass()}getInertia(){return this.body.GetInertia()}getIsAwake(){return this.body.IsAwake()}getBodyType(){return this.body.GetType()}getSpeed(){return this.getLinearVelocity().length()}setTransform(t,e){this.pos=t,this.angle=e,this.body.SetTransform(m.vec2dTo(t),-e)}setPosition(t){this.setTransform(t,this.body.GetAngle())}setAngle(t){this.setTransform(m.vec2From(this.body.GetPosition()),t)}setLinearVelocity(t){this.body.SetLinearVelocity(m.vec2dTo(t))}setAngularVelocity(t){this.body.SetAngularVelocity(t)}setLinearDamping(t){this.body.SetLinearDamping(t)}setAngularDamping(t){this.body.SetAngularDamping(t)}setGravityScale(t=1){this.body.SetGravityScale(this.gravityScale=t)}setBullet(t=!0){this.body.SetBullet(t)}setAwake(t=!0){this.body.SetAwake(t)}setBodyType(t){this.body.SetType(t)}setSleepingAllowed(t=!0){this.body.SetSleepingAllowed(t)}setFixedRotation(t=!0){this.body.SetFixedRotation(t)}setCenterOfMass(t){this.setMassData(t)}setMass(t){this.setMassData(void 0,t)}setMomentOfInertia(t){this.setMassData(void 0,void 0,t)}resetMassData(){this.body.ResetMassData()}setMassData(t,e,s){let i=new m.instance.b2MassData;this.body.GetMassData(i),t!==void 0&&i.set_center(m.vec2dTo(t)),e!==void 0&&i.set_mass(e),s!==void 0&&i.set_I(s),this.body.SetMassData(i)}setFilterData(t=0,e=0,s=0){this.getFixtureList().forEach(i=>{let o=i.GetFilterData();o.set_categoryBits(t),o.set_maskBits(65535&~e),o.set_groupIndex(s)})}setSensor(t=!0){this.getFixtureList().forEach(e=>e.SetSensor(t))}applyForce(t,e){e||(e=this.getCenterOfMass()),this.setAwake(),this.body.ApplyForce(m.vec2dTo(t),m.vec2dTo(e))}applyAcceleration(t,e){e||(e=this.getCenterOfMass()),this.setAwake();let s=t.scale(this.getMass());this.body.ApplyLinearImpulse(m.vec2dTo(s),m.vec2dTo(e))}applyImpulse(t,e){e||(e=this.getCenterOfMass()),this.setAwake(),this.body.ApplyLinearImpulse(m.vec2dTo(t),m.vec2dTo(e))}applyTorque(t){this.setAwake(),this.body.ApplyTorque(t)}applyAngularAcceleration(t){this.setAwake(),this.body.ApplyAngularImpulse(t*this.getInertia())}applyAngularImpulse(t){this.setAwake(),this.body.ApplyAngularImpulse(t)}hasFixtures(){return!m.isNull(this.body.GetFixtureList())}getFixtureList(){let t=[];for(let e=this.body.GetFixtureList();!m.isNull(e);)t.push(e),e=e.GetNext();return t}hasJoints(){return!m.isNull(this.body.GetJointList())}getJointList(){let t=[];for(let e=this.body.GetJointList();!m.isNull(e);)t.push(e),e=e.get_next();return t}},Ti=class extends Ps{constructor(t,e,s,i=0,o,r=0){let a=m.bodyTypeStatic;super(t,e,s,i,o,a,r)}},Uo=class extends Ps{constructor(t,e,s,i=0,o,r=0){let a=m.bodyTypeKinematic;super(t,e,s,i,o,a,r)}},Vo=class extends Ti{constructor(t){f(t instanceof ws,"tileLayer must be a TileCollisionLayer"),super(t.pos,t.size),this.tileLayer=t,this.addChild(t)}render(){}buildCollision(t=.2,e=0){this.destroyAllFixtures(),this.pos=this.tileLayer.pos.copy(),this.size=this.tileLayer.size.copy();let s=[],i=(r,a)=>r+a*this.size.x,o=(r,a)=>!s[i(r,a)]&&this.tileLayer.getCollisionData(b(r,a))>0;for(let r=0;ri.fractiono.pos.distanceSquared(t)0,"Tween duration must be > 0"),this.callback=t,this.start=e,this.end=s,this.duration=i,this.life=i,this.ease=o.ease||Ri.LINEAR,this.useRealTime=!!o.useRealTime,this.paused=!!o.paused,this.thenCallback=void 0,this.loopRemaining=0,Kt.push(this),t(this.interp(i))}setEase(t){return this.ease=t,this}then(t){return this.thenCallback=t,this.loopRemaining=0,this}loop(t=1/0){return this.loopRemaining=t,this.thenCallback=()=>Ic(this),this}pingPong(t=1/0){return this.loopRemaining=t,this.thenCallback=()=>kc(this),this}pause(){this.paused=!0}resume(){this.paused=!1}restart(){this.life=this.duration,this.paused=!1,Kt.indexOf(this)<0&&Kt.push(this),this.callback(this.interp(this.duration))}isActive(){return!this.paused&&Kt.indexOf(this)>=0}getPercent(){return Ft(this.duration-this.life,0,this.duration)}getValue(){return this.interp(this.life)}interp(t){let e=this.ease((this.duration-t)/this.duration);return Ia(this.start)?this.start.lerp(this.end,e):this.start+(this.end-this.start)*e}stop(){let t=Kt.indexOf(this);t>=0&&Kt.splice(t,1),this.thenCallback=void 0}},Ri={LINEAR:n=>n,POWER:n=>t=>t**n,SINE:n=>1-at(n*(X/2)),CIRC:n=>1-(1-n*n)**.5,EXPO:n=>n===0?0:2**(10*n-10),BACK:n=>n*n*(2.70158*n-1.70158),ELASTIC:n=>n===0?0:n===1?1:-(2**(10*n-10))*et((37-40*n)*X/6),SPRING:n=>1-(et(X*(1-n)*(.2+2.5*(1-n)**3))*n**2.2+(1-n))*(1+1.2*n),BOUNCE:n=>{let t=1-n,e;return t<4/11?e=7.5625*t*t:t<8/11?e=7.5625*(t-=6/11)*t+.75:t<10/11?e=7.5625*(t-=9/11)*t+.9375:e=7.5625*(t-=10.5/11)*t+.984375,1-e},IN:n=>n,OUT:n=>t=>1-n(1-t),IN_OUT:n=>Ri.PIECEWISE(n,Ri.OUT(n)),PIECEWISE:(...n)=>{let t=n.length;return e=>{let s=e*t-1e-9>>0;return(n[s]((e-s/t)*t)+s)/t}},BEZIER:(n,t,e,s)=>{let i=o=>{let r=1-o,a=3*r*r*o,c=3*r*o*o,l=o**3;return[a*n+c*e+l,a*t+c*s+l]};return o=>{let r=0,a=1;for(let c=0;c<128;c++){let l=(r+a)/2,[u,h]=i(l);if(tt(u-o)<1e-5)return h;u=this.size.x||e>=this.size.y?null:this.nodes[t+e*this.size.x]}worldToTile(t){let e=this.tileLayer?this.tileLayer.pos.x:0,s=this.tileLayer?this.tileLayer.pos.y:0;return b(Tt(t.x-e),Tt(t.y-s))}tileToWorld(t,e){let s=this.tileLayer?this.tileLayer.pos.x:0,i=this.tileLayer?this.tileLayer.pos.y:0;return b(t+.5+s,e+.5+i)}buildNodeData(){let t=this.size.x,e=this.size.y,s=this.tileLayer?this.tileLayer.pos.x:0,i=this.tileLayer?this.tileLayer.pos.y:0;for(let o=0;o0&&(c?l>0&&bt(a.posWorld,fo,z(1,0,0,Q(.2,l*.05)),this.debugTime):bt(a.posWorld,fo,z(1,0,0,.25),this.debugTime))}}aStarSearch(t,e){f(t&&e,"aStarSearch needs both endpoints"),f(t!==e,"aStarSearch: start and end must differ \u2014 caller should handle trivial case"),f(t.walkable&&e.walkable,"aStarSearch: endpoints must be walkable");let s=[t];t.isOpen=!0;let i=0;for(;s.length>0;){let o=0,r=s[0].f;for(let c=1;cthis.maxLoop)break;a.isOpen=!1,s.splice(o,1),a.isClosed=!0,this.debug&&this.debugTime>0&&bt(a.posWorld,fo,z(1,1,1,.05),this.debugTime);for(let c=-1;c<=1;++c)for(let l=-1;l<=1;++l){if(l===0&&c===0)continue;let u=this.getNode(a.pos.x+l,a.pos.y+c);if(!u||!u.walkable||u.isClosed)continue;let h=1;if(l!==0&&c!==0){let v=this.getNode(a.pos.x+l,a.pos.y);if(!v||!v.walkable)continue;let w=this.getNode(a.pos.x,a.pos.y+c);if(!w||!w.walkable)continue;h=md}let p=a.g+h+u.cost;if(!u.isOpen)u.isOpen=!0,s.push(u);else if(p>=u.g)continue;u.parent=a,u.g=p;let d=tt(e.pos.x-u.pos.x),g=tt(e.pos.y-u.pos.y),x=$(d,g)+(Math.SQRT2-1)*Q(d,g);u.f=u.g+x*this.heuristicWeight}}return e.parent!==null}getNearestClearNode(t,e=10,s=!0){f(L(t),"worldPos must be a Vector2"),s&&this.buildNodeData();let i=this.tileLayer?this.tileLayer.pos.x:0,o=this.tileLayer?this.tileLayer.pos.y:0,r=Tt(t.x-i),a=Tt(t.y-o);for(let c=0;c<=e;++c){let l=null,u=0;for(let h=-c;h<=c;++h)for(let p=-c;p<=c;++p){if(c>0&&tt(p)!==c&&tt(h)!==c)continue;let d=this.getNode(r+p,a+h);if(!d||!d.isClear())continue;let g=d.posWorld.x-t.x,x=d.posWorld.y-t.y,v=g*g+x*x;(!l||v0&&Vt(i.posWorld,.3,z(.5,0,.5,.5),this.debugTime),t.splice(e,1),e=$(1,e-1);continue}else if(c===2){this.debug&&this.debugTime>0&&Vt(i.posWorld,.3,z(1,0,0,.5),this.debugTime);let d,g;s.pos.y===i.pos.y&&o.pos.x===i.pos.x?(d=s.pos.x,g=o.pos.y):(d=o.pos.x,g=s.pos.y);let x=this.getNode(d,g);if(x&&x.isClear()){t.splice(e,1),e=$(1,e-1);continue}}else if(c===5){this.debug&&this.debugTime>0&&Vt(i.posWorld,.3,z(1,1,0,.5),this.debugTime);let d=e>=2?t[e-2]:s,g,x,v,w;l===0||h===0?(g=o.pos.x,x=i.pos.y,v=s.pos.x,w=i.pos.y):(g=i.pos.x,x=o.pos.y,v=i.pos.x,w=s.pos.y);let _=g-d.pos.x,S=x-d.pos.y,E=v-d.pos.x,A=w-d.pos.y,T=_*_+S*S,P=E*E+A*A,k=T0&&Vt(i.posWorld,.3,z(0,1,0,.5),this.debugTime),l===h&&u===p){++e;continue}else{let d,g;s.pos.y===o.pos.y?(d=i.pos.x,g=s.pos.y):(d=s.pos.x,g=i.pos.y);let x=this.getNode(d,g);if(x&&x.isClear()){t[e]=x,e=$(1,e-1);continue}}++e}}smoothPathStringPull(t){if(t.length<=2)return;for(let i of t)if(!i.isClear())return;let e=t.slice();t.length=0,t.push(e[0]);let s=0;for(let i=1;i0&&Se(o.posWorld,t[t.length-1].posWorld,z(0,0,1,.3),.02,this.debugTime);continue}for(;s=1;--e){let s=t[e-1],i=t[e],o=t[e+1];(i.pos.x-s.pos.x)*(o.pos.y-s.pos.y)===(i.pos.y-s.pos.y)*(o.pos.x-s.pos.x)&&t.splice(e,1)}}isNodeClear(t,e){let s=this.getNode(t,e);return s!==null&&s.isClear()}isLineClear(t,e){f(L(t)&&L(e),"isLineClear needs Vector2 endpoints"),f(this.isNodeClear(t.x,t.y)&&this.isNodeClear(e.x,e.y),"isLineClear endpoints must be in-bounds and clear");let s=e.x-t.x,i=e.y-t.y,o=tt(s),r=tt(i),a=ne(s),c=ne(i),l=t.x,u=t.y;if(r===o){for(;l!==e.x;){if(l!==t.x&&(!this.isNodeClear(l,u)||!this.isNodeClear(l,u-c))||!this.isNodeClear(l,u+c))return!1;l+=a,u+=c}if(!this.isNodeClear(e.x,e.y-c))return!1}else if(ra.posWorld.copy());if(this.debug&&this.debugTime>0&&r.length>0){for(let a=1;abd,bootGameHost:()=>vd,default:()=>xd});var Ns=class{constructor(t){this._state=(t==null?2654435769:t)>>>0}next(){this._state=this._state+1831565813>>>0;let t=this._state;return t=Math.imul(t^t>>>15,t|1),t^=t+Math.imul(t^t>>>7,t|61),((t^t>>>14)>>>0)/4294967296}range(t,e){return t+this.next()*(e-t)}reseed(t){this._state=(t==null?2654435769:t)>>>0}},Wi=class{constructor(t){this._clock=t||qc(),this._origin=this._clock()}nowMs(){return this._clock()}elapsedMs(){return this._clock()-this._origin}},qi=class{constructor(t){this._time=t,this._subs=new Map}sourceFor(t){let e=this,s=t==null?null:t;return{on(i,o){if(e._assertType(i),typeof o!="function")throw new Error("[HostDevInputBridge] on \u7684 handler \u5FC5\u987B\u662F\u51FD\u6570");let r=e._subs.get(i)||[],a={handler:o,scope:s};return r.push(a),e._subs.set(i,r),{cancel(){let c=e._subs.get(i);if(!c)return;let l=c.indexOf(a);l>=0&&c.splice(l,1)}}},off(i,o){e._assertType(i);let r=e._subs.get(i);if(!r)return;let a=r.findIndex(c=>c.handler===o&&c.scope===s);a>=0&&r.splice(a,1)}}}_emit(t,e){this._assertType(t);let s=e||{},i={type:t,x:typeof s.x=="number"?s.x:0,y:typeof s.y=="number"?s.y:0,key:typeof s.key=="string"?s.key:"",tMs:this._time.nowMs()},o=this._subs.get(t);if(!o||o.length===0)return;let r=o.slice();for(let a of r)try{a.handler(i)}catch(c){Ye("[host-dev input] \u8F93\u5165 handler \u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09type="+t,c)}}disposeScope(t){if(t==null)return 0;let e=0;for(let[s,i]of this._subs){let o=i.filter(r=>r.scope!==t);e+=i.length-o.length,o.length===0?this._subs.delete(s):this._subs.set(s,o)}return e}_subscriptionCount(){let t=0;for(let e of this._subs.values())t+=e.length;return t}_assertType(t){if(!Hi.has(t))throw new Error("[HostDevInputBridge] \u975E\u6CD5\u8F93\u5165\u4E8B\u4EF6\u7C7B\u578B\uFF1A"+String(t)+"\uFF08\u4EC5\u652F\u6301 "+Array.from(Hi).join("/")+"\uFF09")}},Hi=new Set(["pointerdown","pointermove","pointerup","keydown","keyup"]);function Qr(n){let t=n||{},e=new Wi(t.clock),s=new Ns(t.seed),i=t.seed==null?2654435769:t.seed>>>0,o=new qi(e),r=typeof t.audioFactory=="function"?t.audioFactory:null,a=null,c=!1,l=typeof t.engineFactory=="function"?t.engineFactory:null,u=null,h=!1,p=new Map,d=0,g=0;function x(){if(a)return a;if(!r)return c||(Yi("[host-dev audio] \u672A\u6CE8\u5165 audioFactory\uFF0CgetAudioContext \u8FD4\u56DE null\uFF08P6 \u987B\u5BB9\u9519\u964D\u7EA7\uFF1B\u96C6\u6210\u6BB5\u6CE8\u5165\u771F\u5B9E\u5DE5\u5382\uFF09"),c=!0),null;try{a=r()}catch(E){Ye("[host-dev audio] audioFactory \u629B\u9519\uFF0CgetAudioContext \u964D\u7EA7\u8FD4\u56DE null",E),a=null}return a}function v(){if(u)return u;if(!l)return h||(Yi("[host-dev engine] \u672A\u6CE8\u5165 engineFactory\uFF0CgetEngine \u8FD4\u56DE null\uFF08\u63D2\u4EF6\u987B\u5BB9\u9519\u964D\u7EA7\uFF1A\u7C92\u5B50\u9000\u53D7\u63A7\u9762\u81EA\u7BA1/\u5408\u6210\u6838\u9000 vendored/\u6570\u5B66\u9000\u5185\u7F6E\uFF1B\u96C6\u6210\u6BB5\u6CE8\u5165\u771F\u5B9E\u80CC\u4E66\uFF09"),h=!0),null;try{u=l()}catch(E){Ye("[host-dev engine] engineFactory \u629B\u9519\uFF0CgetEngine \u964D\u7EA7\u8FD4\u56DE null",E),u=null}return u}function w(E,A){return{getContext2d(){return t.context2d==null?null:t.context2d},onFrame(P){let k=d++;return p.set(k,P),{cancel(){p.delete(k)}}},getInput(){return o.sourceFor(E)},getAudioContext(){return x()},getEngine(){return v()},time:e,random:A}}let _=w(null,s),S={context:_,tick(E){g+=1;let A=Array.from(p.values());for(let T of A)try{T(E,g)}catch(P){Ye("[host-dev tick] \u5E27\u56DE\u8C03\u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09frame="+g,P)}},frameCount(){return g},inputBridge:o,deriveContextFor(E,A){let T=Wc(i,E),P=new Ns(T);return w(A==null?E:A,P)}};return Object.defineProperty(_,Xi,{value:S,enumerable:!1,writable:!1,configurable:!1}),S}var Xi=Symbol("zaomeng.coreProtocol.contextBundle"),zs=class{constructor(){this._plugins=new Map,this._initOrder=[],this._initErrors=[],this._phase="idle",this._disposed=!1,this._context=void 0,this._pluginContexts=new Map}register(t){if(!t||typeof t!="object")throw new Error("[PluginRegistry] register \u9700\u8981\u4E00\u4E2A\u63D2\u4EF6\u5BF9\u8C61");if(typeof t.name!="string"||t.name.length===0)throw new Error("[PluginRegistry] \u63D2\u4EF6\u7F3A\u5C11\u5408\u6CD5 name");if(typeof t.version!="string"||t.version.length===0)throw new Error("[PluginRegistry] \u63D2\u4EF6 "+t.name+" \u7F3A\u5C11\u5408\u6CD5 version");if(typeof t.init!="function")throw new Error("[PluginRegistry] \u63D2\u4EF6 "+t.name+" \u7F3A\u5C11 init \u51FD\u6570");if(t.dispose!=null&&typeof t.dispose!="function")throw new Error("[PluginRegistry] \u63D2\u4EF6 "+t.name+" \u7684 dispose \u5FC5\u987B\u662F\u51FD\u6570\u6216\u7701\u7565");if(this._plugins.has(t.name))throw new Error("[PluginRegistry] \u63D2\u4EF6\u91CD\u540D\u62D2\u7EDD\uFF1A"+t.name+" \u5DF2\u6CE8\u518C");return this._plugins.set(t.name,t),this}has(t){return this._plugins.has(t)}get(t){return this._plugins.get(t)}list(){return Array.from(this._plugins.keys())}initAll(){if(this._phase==="initialized")return Yi("[PluginRegistry] initAll \u91CD\u590D\u8C03\u7528\uFF0C\u5DF2\u5FFD\u7565\uFF08\u5DF2\u5904\u4E8E initialized\uFF09"),this._initResult();if(this._phase==="disposed")throw new Error("[PluginRegistry] \u5DF2 dispose \u7684\u6CE8\u518C\u5668\u4E0D\u53EF\u518D initAll");if(this._context==null)throw new Error("[PluginRegistry] \u672A\u6CE8\u5165\u53D7\u63A7\u4E0A\u4E0B\u6587\uFF1A\u8BF7\u5728 initAll() \u4E4B\u524D\u8C03\u7528 useContext(context)\u3002\uFF08host-dev \u7528\u6CD5\uFF1Aconst { context } = createHostDevContext(); reg.useContext(context); reg.initAll();\uFF09");for(let[t,e]of this._plugins){let s=this._missingDeps(e);if(s.length>0){let o=new Error("[PluginRegistry] \u63D2\u4EF6 "+t+" \u4F9D\u8D56\u7F3A\u5931\uFF1A"+s.join(", ")+"\uFF08\u672A\u6CE8\u518C\uFF09");this._initErrors.push({name:t,error:o}),Ye("[PluginRegistry] \u8DF3\u8FC7 init\uFF08\u4F9D\u8D56\u7F3A\u5931\uFF0C\u5DF2\u9694\u79BB\uFF09\uFF1A"+t,o);continue}let i=this._contextFor(t);try{e.init(i),this._initOrder.push(t)}catch(o){let r=o instanceof Error?o:new Error(String(o));this._initErrors.push({name:t,error:r}),Ye("[PluginRegistry] \u63D2\u4EF6 init \u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF0C\u4E0D\u8FDE\u5750\uFF09\uFF1A"+t,r)}}return this._phase="initialized",this._initResult()}_contextFor(t){let e=this._pluginContexts.get(t);if(e)return e;let s=this._context&&this._context[Xi],i;return s&&typeof s.deriveContextFor=="function"?i=s.deriveContextFor(t,t):i=this._context,this._pluginContexts.set(t,i),i}disposeAll(){if(this._disposed)return{disposed:[],errors:[]};let t=[],e=[],s=this._context&&this._context[Xi],i=s&&s.inputBridge;for(let o=this._initOrder.length-1;o>=0;o--){let r=this._initOrder[o],a=this._plugins.get(r);if(a&&typeof a.dispose=="function")try{a.dispose(),t.push(r)}catch(c){let l=c instanceof Error?c:new Error(String(c));e.push({name:r,error:l}),Ye("[PluginRegistry] \u63D2\u4EF6 dispose \u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09\uFF1A"+r,l)}if(i&&typeof i.disposeScope=="function")try{i.disposeScope(r)}catch(c){Ye("[PluginRegistry] \u56DE\u6536\u63D2\u4EF6\u8F93\u5165\u8BA2\u9605\u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09\uFF1A"+r,c)}}return this._disposed=!0,this._phase="disposed",{disposed:t,errors:e}}useContext(t){if(this._phase!=="idle")throw new Error("[PluginRegistry] useContext \u5FC5\u987B\u5728 initAll() \u4E4B\u524D\u8C03\u7528\uFF08\u5F53\u524D\u9636\u6BB5\uFF1A"+this._phase+"\uFF09\u3002\u8BF7\u5728\u4EFB\u4F55 initAll/disposeAll \u4E4B\u524D\u6CE8\u5165\u53D7\u63A7\u4E0A\u4E0B\u6587\u3002");if(t==null||typeof t!="object")throw new Error("[PluginRegistry] useContext \u9700\u8981\u4E00\u4E2A\u53D7\u63A7\u4E0A\u4E0B\u6587\u5BF9\u8C61\u3002\uFF08host-dev \u7528\u6CD5\uFF1Aconst { context } = createHostDevContext(); reg.useContext(context);\uFF09");return this._context=t,this}_missingDeps(t){return!Array.isArray(t.dependencies)||t.dependencies.length===0?[]:t.dependencies.filter(e=>!this._plugins.has(e))}_initResult(){return{ok:this._initErrors.length===0,initialized:this._initOrder.slice(),errors:this._initErrors.slice()}}};function Wc(n,t){let e=2166136261,s=16777619,i=n>>>0;for(let r=0;r<32;r+=8){let a=i>>>r&255;e^=a,e=Math.imul(e,s)>>>0}let o=String(t);for(let r=0;r>>0,e^=a>>>8&255,e=Math.imul(e,s)>>>0}return e>>>0}function qc(){if(typeof globalThis!="undefined"&&globalThis.performance&&typeof globalThis.performance.now=="function")return()=>globalThis.performance.now();if(typeof process!="undefined"&&process.hrtime&&typeof process.hrtime.bigint=="function"){let n=process.hrtime.bigint();return()=>Number(process.hrtime.bigint()-n)/1e6}return()=>Date.now()}function Ye(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function Yi(n){typeof console!="undefined"&&typeof console.warn=="function"&&console.warn(n)}var Td=Object.freeze(Array.from(Hi)),Zr="core-protocol-v0";var ta=Object.freeze(["t_boot","t_plugins_ready","t_game_init","t_first_paint","t_input_bound","t_game_start"]),$i=ta.reduce((n,t,e)=>(n[t]=e,n),Object.create(null)),Hc=new Set(ta);function Ki(n){let t=2166136261;for(let e=0;e>>0).toString(16).padStart(8,"0")}var ea=Ki("runtime-probe::seed::v1");function Js(n){return n===null||typeof n!="object"?JSON.stringify(n):Array.isArray(n)?"["+n.map(Js).join(",")+"]":"{"+Object.keys(n).sort().map(e=>JSON.stringify(e)+":"+Js(n[e])).join(",")+"}"}function na(n){let t=Js(n.extra==null?null:n.extra),e=Js(Array.isArray(n.pluginSet)?n.pluginSet:[]);return["seq="+n.seq,"anchor="+n.anchor,"tMono="+n.tMono,"buildSha="+(n.buildSha||""),"pluginSet="+e,"extra="+t].join("|")}function Xc(n){return Math.round(n*1e3)/1e3}function Yc(n){if(!Array.isArray(n))return{ok:!1,reason:"records_not_array"};let t=ea,e=-1;for(let s=0;stypeof E=="string").slice().sort():[],i=typeof t.sink=="function"?t.sink:null,o=t.autoBoot!==!1,r=typeof t.inputAnchorType=="string"?t.inputAnchorType:"pointerdown",a=()=>0,c=!1,l=0,u=ea,h=[],p=new Set,d=-1,g=null,x=!1,v=!1,w=!1;function _(E,A){let T=null;if(!Hc.has(E))T="unknown_anchor";else{p.has(E)&&(T=T?T+";duplicate_anchor":"duplicate_anchor");let k=$i[E];kE.time.nowMs(),c=!0,o&&!v&&_("t_boot",{auto:!0}),g=E.getInput().on(r,A=>{x||(x=!0,_("t_input_bound",{firstInput:!0,type:A.type}))}),_("t_input_bound",{stage:"registered",type:r})},dispose(){w||(g&&(g.cancel(),g=null),w=!0)},mark:_,getRecords(){return h.map(E=>({...E}))},toJSONL(){return h.map(E=>JSON.stringify(E)).join(`
-`)},verify(){return Yc(h)}}}function $c(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function ia(n){let t=n.LJS,e=n.engineMath,s=n.engineMode,i=n.recHook||(()=>{});if(s!=="real")return null;let o=e;return{math:{lerp:(a,c,l)=>(i("math.lerp"),o.lerp(a,c,l)),smoothStep:a=>(i("math.smoothStep"),o.smoothStep(a)),easing:Object.fromEntries(Object.keys(o.easing).map(a=>[a,c=>(i("math.easing."+a),o.easing[a](c))]))},particles:{spawnEmitter(a){i("particles.spawnEmitter");let c=t.screenToWorld(t.vec2(a.pos.x,a.pos.y)),l=t.cameraScale,u=a.emitTime!=null?a.emitTime:a.count!=null?1/60:0,h=a.emitRate!=null?a.emitRate:a.count!=null?a.count*60:100,p=(a.speed!=null?a.speed:0)/l/60,d=a.damping!=null?a.damping:1,g=a.colorStart||{r:1,g:1,b:1,a:1},x=a.colorEnd||{r:1,g:1,b:1,a:0},v=t.rgb(g.r,g.g,g.b,g.a),w=t.rgb(x.r,x.g,x.b,x.a),_=new t.ParticleEmitter(c,a.angle!=null?a.angle:0,(a.emitSize!=null?a.emitSize:0)/l,u,h,a.coneAngle!=null?a.coneAngle:Math.PI,void 0,v,v,w,w,a.particleTime!=null?a.particleTime:.5,(a.sizeStart!=null?a.sizeStart:6)/l,(a.sizeEnd!=null?a.sizeEnd:0)/l,p,0,d,1,a.gravityScale!=null?a.gravityScale:0,Math.PI,.1,0,!1,a.additive!=null?a.additive:!1,!0);return{isActive(){return _.isActive()},stop(){_.destroyed||_.destroy(!0)}}}},audio:{synth:{synthSfx:a=>{i("audio.synth.synthSfx");try{return t.zzfxG(...a)}catch(c){return console.error("[host][engine-audio] zzfxG \u5408\u6210\u5F02\u5E38\uFF0C\u8FD4 null\uFF1A"+(c&&c.message?c.message:c)),null}},synthSong:(a,c,l,u)=>{i("audio.synth.synthSong");try{return t.zzfxM(a,c,l,u)}catch(h){return console.error("[host][engine-audio] zzfxM \u5408\u6210\u5F02\u5E38\uFF0C\u8FD4 null\uFF1A"+(h&&h.message?h.message:h)),null}}}}}}function ce(n){return n<0?0:n>1?1:n}function oa(n){let t=n.Ease,e=t.POWER(2),s=t.POWER(3),i=t.OUT(e),o=t.IN_OUT(e),r=t.OUT(s),a=t.IN_OUT(s),c=t.OUT(t.BACK),l=t.OUT(t.ELASTIC);return{lerp:(u,h,p)=>n.lerp(u,h,p),smoothStep:u=>n.smoothStep(u),easing:{linear:u=>t.LINEAR(ce(u)),quadIn:u=>e(ce(u)),quadOut:u=>i(ce(u)),quadInOut:u=>o(ce(u)),cubicIn:u=>s(ce(u)),cubicOut:u=>r(ce(u)),cubicInOut:u=>a(ce(u)),backIn:u=>t.BACK(ce(u)),backOut:u=>c(ce(u)),elasticIn:u=>t.ELASTIC(ce(u)),elasticOut:u=>l(ce(u))}}}var $e=2,Us=1/60;async function ra(n){let t=n.canvas,e=n.statusEl||null,s=n.engine,i=n.seed>>>0,o=n.mode||"play",r=n.engineMode||"real",a=n.viewport.w,c=n.viewport.h,l=n.factory,u=n.buildFactoryOpts||(()=>{}),h=n.plugins||{},p=n.registerOrder||Object.values(h),d=n.onReady||(()=>{}),g=n.recHook||(()=>{});function x(D){e&&(e.textContent=D)}let v=[];window.addEventListener("error",D=>v.push({type:"error",message:String(D&&D.message||D)})),window.addEventListener("unhandledrejection",D=>v.push({type:"unhandledrejection",message:String(D&&D.reason&&D.reason.message||D&&D.reason||D)}));let w=null,_=!1;function S(){if(!_)return null;if(w)return w;let D=window.AudioContext||window.webkitAudioContext;return D?(w=new D,w):null}let E=0,A=null,T=null,P=null,k=null,ct=[],st={},it=null;function gt(D,ot){try{P&&P.mark(D,ot)}catch(Nt){v.push({type:"mark",message:String(Nt&&Nt.message||Nt)})}}function jt(){T&&typeof T._refreshChecklist=="function"&&T._refreshChecklist(st)}async function Ve(D,ot){A=Qr({context2d:D,seed:i,audioFactory:S,clock:()=>E,engineFactory:()=>ia({LJS:r==="real"?s:null,engineMath:r==="real"?oa(s):null,engineMode:r,recHook:g})});let Nt=new zs;for(let zt of p)Nt.register(zt);Nt.useContext(A.context),k=Nt.initAll(),ct=Nt.list().concat(["runtime-probe"]),P=sa({pluginSet:ct,inputAnchorType:"pointerdown",autoBoot:!0});let Pt=A.deriveContextFor("runtime-probe","runtime-probe");gt("t_boot",{by:"game-host",stage:"pre-init",engineMode:r}),gt("t_plugins_ready",{initialized:k.initialized.length,ok:k.ok});let pn=u(A.context,{bundle:A,plugins:h,getRealAudioCtx:()=>w});T=l(pn),await T.init({ctx:A.context,mainContext:D,canvas:ot(),seed:i}),it=T&&typeof T._forensicsView=="function"?T._forensicsView():null,gt("t_game_init",{hasForensics:!!it}),ht(),gt("t_first_paint",{frame:A.frameCount()});try{P.init(Pt)}catch(zt){v.push({type:"probe-init",message:String(zt&&zt.message||zt)})}gt("t_game_start",{mode:o,engineMode:r}),jt(),d(ye,{bundle:A,game:T,probe:P,checklist:st,uncaught:v,pluginSet:ct,initRes:k,getGameForensics:()=>it,mark:gt,stepOneFrame:ht})}let Bt=null;function ht(D){let ot=typeof D=="number"?D:Us;T&&(E+=ot*1e3,T.update(ot),r==="stub"&&Bt&&T.render(Bt),jt())}function Dt(D){for(let ot=0;ot{}),T&&typeof T._onAudioUnlock=="function"&&T._onAudioUnlock()}let ye={seed:i,mode:o,engineMode:r,protocol:Zr,frameCount:()=>A?A.frameCount():0,stepFrames:Dt,startRaf:()=>pt(),stopRaf:()=>wt(),tap(D,ot){We(),A&&(A.inputBridge._emit("pointerdown",{x:D,y:ot}),A.inputBridge._emit("pointerup",{x:D,y:ot}))},do(D){T&&typeof T._handleAction=="function"&&T._handleAction(D)},state:()=>it?it.state():{phase:"booting"}};function M(D){let ot=A.inputBridge;function Nt(Pt,pn){let zt=D.getBoundingClientRect();return{x:(Pt-zt.left)/zt.width*a,y:(pn-zt.top)/zt.height*c}}D.addEventListener("pointerdown",Pt=>{We(),ot._emit("pointerdown",Nt(Pt.clientX,Pt.clientY))}),D.addEventListener("pointermove",Pt=>{ot._emit("pointermove",Nt(Pt.clientX,Pt.clientY))}),D.addEventListener("pointerup",Pt=>{ot._emit("pointerup",Nt(Pt.clientX,Pt.clientY))})}let F=0,xt=!1,O=0;function U(D){if(!xt)return;O===0&&(O=D);let ot=(D-O)/1e3;O=D,ot>.05&&(ot=.05),ht(ot),F=window.requestAnimationFrame(U)}function pt(){r==="stub"&&(xt||(xt=!0,O=0,F=window.requestAnimationFrame(U)))}function wt(){xt=!1,F&&window.cancelAnimationFrame(F),F=0}function ae(D){D.width=a*$e,D.height=c*$e,D.style.width=a+"px",D.style.height=c+"px";let ot=D.getContext("2d",{willReadFrequently:!0});return ot.setTransform($e,0,0,$e,0,0),ot}async function qe(){let D=ae(t);return Bt=D,await Ve(D,()=>t),M(t),o==="evidence"?x(`evidence \u5C31\u7EEA seed=${i} \xB7 \u7528 host \u9A71\u52A8\uFF08stepFrames/tap\uFF09`):(x(`seed=${i} \xB7 \u70B9\u5F00\u59CB\uFF08\u9996\u6B21\u70B9\u51FB\u5F00\u58F0\uFF09`),pt()),ye}let fn=()=>{},He=()=>{};function lt(){window.__gameHostEngineInitFired=!0}function ee(){fn()}function Re(){}function Pe(){He()}function ts(){}async function Bs(D){await Ve(D,()=>s.mainCanvas),M(s.mainCanvas),fn=()=>{T&&(E+=Us*1e3,T.update(Us))},He=()=>{if(T){D.save(),D.setTransform($e,0,0,$e,0,0);try{D.imageSmoothingEnabled=!1}catch{}T.render(D),D.restore()}},s.mainCanvas&&(s.mainCanvas.id="game-engine"),window.__engine={frame(){return s.frame},time(){return s.time},timeReal(){return s.timeReal},paused(){return s.paused},timeScale(){return s.timeScale},snapshot(){return{frame:s.frame,time:s.time,timeReal:s.timeReal,paused:s.paused,timeScale:s.timeScale}}},x(`engine RAF running \xB7 seed=${i} engine=real`)}if(r!=="real")return await qe();if(!s){let D="real \u901A\u9053\u672A\u6CE8\u5165\u5F15\u64CE\uFF08opts.engine \u7F3A\u5931\uFF09\uFF1A\u8BF7\u7ECF entry \u5305\u88C5\u5C42\u542F\u52A8\uFF08host \u4E0D\u76F4\u63A5 import \u5F15\u64CE\uFF0CQ4/Option C\uFF09";throw x("ENGINE INJECT MISSING: "+D),new Error(D)}s.setGLEnable(!1),s.setShowSplashScreen(!1),s.setDebugWatermark(!1),s.setCanvasClearColor(s.BLACK),s.setCanvasFixedSize(s.vec2(a*$e,c*$e));let es=document.createElement("div");return es.id="engine-root",document.body.appendChild(es),await s.engineInit(lt,ee,Re,Pe,ts,[],es).then(()=>Bs(s.mainContext)).catch(D=>{throw window.__gameHostBootError=String(D&&D.message||D),x("ENGINE INIT FAILED: "+window.__gameHostBootError),D}),ye}var Qi=class{constructor(t){let e=t||{},s=typeof e.cellSize=="number"&&e.cellSize>0?e.cellSize:64;this._cellSize=s,this._cells=new Map,this._entries=new Map,this._seq=0}get size(){return this._entries.size}_cellRange(t){let e=this._cellSize,s=Math.floor((t.x-t.hw)/e),i=Math.floor((t.x+t.hw)/e),o=Math.floor((t.y-t.hh)/e),r=Math.floor((t.y+t.hh)/e);return{cx0:s,cy0:o,cx1:i,cy1:r}}insert(t,e){this._entries.has(t)&&this.remove(t);let{cx0:s,cy0:i,cx1:o,cy1:r}=this._cellRange(e),a=[];for(let l=i;l<=r;l++)for(let u=s;u<=o;u++){let h=u+","+l,p=this._cells.get(h);p||(p=new Set,this._cells.set(h,p)),p.add(t),a.push(h)}let c={x:e.x,y:e.y,hw:e.hw,hh:e.hh};this._entries.set(t,{id:t,box:c,seq:this._seq++,cells:a})}remove(t){let e=this._entries.get(t);if(!e)return!1;for(let s of e.cells){let i=this._cells.get(s);i&&(i.delete(t),i.size===0&&this._cells.delete(s))}return this._entries.delete(t),!0}query(t){let{cx0:e,cy0:s,cx1:i,cy1:o}=this._cellRange(t),r=new Set;for(let a=s;a<=o;a++)for(let c=e;c<=i;c++){let l=this._cells.get(c+","+a);if(l)for(let u of l)r.add(u)}return this._collect(r)}queryPoint(t,e){let s=this._cellSize,i=Math.floor(t/s),o=Math.floor(e/s),r=this._cells.get(i+","+o);return r?this._collect(new Set(r)):[]}clear(){this._cells.clear(),this._entries.clear(),this._seq=0}_collect(t){let e=[];for(let s of t){let i=this._entries.get(s);i&&e.push(i)}return e.sort((s,i)=>s.seq-i.seq),e.map(s=>({id:s.id,box:s.box}))}};function aa(n){let t=n||{},e=new Qi({cellSize:t.cellSize}),s=!1;return{name:"collision",version:"1.0.0",dependencies:[],spatial:e,init(o){},dispose(){s||(e.clear(),s=!0)}}}function ca(n){let t=!1;return{name:"physics-lite",version:"1.0.0",dependencies:[],init(s){},dispose(){t||(t=!0)}}}var Kc=["pointerdown","pointermove","pointerup","keydown","keyup"];function Jt(n){return n<0?0:n>1?1:n}var Qc=n=>(n=Jt(n),n*n),Zc=n=>(n=Jt(n),1-(1-n)*(1-n)),tl=n=>(n=Jt(n),n<.5?2*n*n:1-Math.pow(-2*n+2,2)/2),el=n=>(n=Jt(n),n*n*n),nl=n=>{n=Jt(n);let t=1-n;return 1-t*t*t},sl=n=>(n=Jt(n),n<.5?4*n*n*n:1-Math.pow(-2*n+2,3)/2),ha=2*Math.PI/3,la=2*Math.PI/4.5,il=n=>(n=Jt(n),n===0?0:n===1?1:-Math.pow(2,10*n-10)*Math.sin((n*10-10.75)*ha)),ol=n=>(n=Jt(n),n===0?0:n===1?1:Math.pow(2,-10*n)*Math.sin((n*10-.75)*ha)+1),rl=n=>(n=Jt(n),n===0?0:n===1?1:n<.5?-(Math.pow(2,20*n-10)*Math.sin((20*n-11.125)*la))/2:Math.pow(2,-20*n+10)*Math.sin((20*n-11.125)*la)/2+1),Ws=1.70158,Vs=Ws*1.525,da=Ws+1,al=n=>(n=Jt(n),da*n*n*n-Ws*n*n),cl=n=>{n=Jt(n);let t=n-1;return 1+da*t*t*t+Ws*t*t},ll=n=>(n=Jt(n),n<.5?Math.pow(2*n,2)*((Vs+1)*2*n-Vs)/2:(Math.pow(2*n-2,2)*((Vs+1)*(n*2-2)+Vs)+2)/2),ul=n=>Jt(n),ua=Object.freeze({linear:ul,quadIn:Qc,quadOut:Zc,quadInOut:tl,cubicIn:el,cubicOut:nl,cubicInOut:sl,elasticIn:il,elasticOut:ol,elasticInOut:rl,backIn:al,backOut:cl,backInOut:ll});var hl=["linear","quadIn","quadOut","quadInOut","cubicIn","cubicOut","cubicInOut","elasticIn","elasticOut","elasticInOut","backIn","backOut","backInOut"];function dl(n){let t=n&&n.easing;if(!t)return ua;let e=i=>typeof t[i]=="function"?o=>t[i](Jt(o)):ua[i],s={};for(let i of hl)s[i]=e(i);return Object.freeze(s)}var Zi=class{constructor(t,e,s){let i=s||{};this._time=e,this._windowMs=typeof i.windowMs=="number"&&i.windowMs>0?i.windowMs:120;let o=Array.isArray(i.types)&&i.types.length>0?i.types:Kc;this._records=new Map,this._subs=[],this._disposed=!1;for(let r of o){this._records.set(r,null);let a=t.on(r,c=>{this._records.set(r,c.tMs)});this._subs.push(a)}}consume(t,e){let s=typeof e=="number"?e:this._time.nowMs(),i=this._records.get(t);return i==null?!1:s-i<=this._windowMs?(this._records.set(t,null),!0):(this._records.set(t,null),!1)}peek(t,e){let s=typeof e=="number"?e:this._time.nowMs(),i=this._records.get(t);return i==null?!1:s-i<=this._windowMs}clear(){for(let t of this._records.keys())this._records.set(t,null)}dispose(){if(!this._disposed){for(let t of this._subs)try{t.cancel()}catch(e){}this._subs=[],this._disposed=!0}}};function fa(n){let t=n||{},e=null,s=null,i=!1;return{name:"gamefeel",version:"1.0.0",dependencies:[],get inputBuffer(){return e},get easing(){return dl(s)},init(r){let a=r.getInput();e=new Zi(a,r.time,{windowMs:t.inputBufferMs,types:t.inputTypes});let c=r.getEngine();s=c?c.math:null},dispose(){i||(e&&(e.dispose(),e=null),s=null,i=!0)}}}function qs(n,t){let e=t<0?0:t>1?1:t;switch(n&&n.kind){case"constant":return n.value;case"linear":return n.from+(n.to-n.from)*e;case"easeInOut":{let s=e*e*(3-2*e);return n.from+(n.to-n.from)*s}case"decay":{let s=n.power==null?2:n.power,i=Math.pow(1-e,s);return n.to+(n.from-n.to)*i}default:return 0}}var fl=Object.freeze({burst:Object.freeze({mode:"burst",count:24,angle:0,spread:Math.PI,speedMin:80,speedMax:160,lifeMin:.4,lifeMax:.8,gravity:0,drag:0,sizeCurve:{kind:"decay",from:6,to:0,power:1.5},alphaCurve:{kind:"linear",from:1,to:0}}),trail:Object.freeze({mode:"continuous",rate:60,angle:Math.PI,spread:.25,speedMin:20,speedMax:50,lifeMin:.2,lifeMax:.5,gravity:0,drag:1.5,sizeCurve:{kind:"easeInOut",from:4,to:0},alphaCurve:{kind:"decay",from:.8,to:0,power:2}}),drift:Object.freeze({mode:"continuous",rate:12,angle:Math.PI/2,spread:.6,speedMin:10,speedMax:30,lifeMin:1.5,lifeMax:3,gravity:8,drag:.5,sizeCurve:{kind:"constant",value:3},alphaCurve:{kind:"decay",from:.7,to:0,power:1}})});function pl(n){let t=fl[n];return t?to(t):null}function to(n){let t={};for(let e of Object.keys(n)){let s=n[e];t[e]=s&&typeof s=="object"?to(s):s}return t}function yl(n,t,e){let s=n.mode==="continuous";return{pos:{x:t,y:e},angle:n.angle,coneAngle:n.spread,emitSize:0,emitTime:s?0:1/60,emitRate:s?n.rate||0:void 0,count:s?void 0:n.count||0,particleTime:(n.lifeMin+n.lifeMax)/2,speed:(n.speedMin+n.speedMax)/2,gravityScale:n.gravity||0,damping:n.drag!=null?1-n.drag/60:1,sizeStart:qs(n.sizeCurve,0),sizeEnd:qs(n.sizeCurve,1),colorStart:{r:1,g:1,b:1,a:qs(n.alphaCurve,0)},colorEnd:{r:1,g:1,b:1,a:qs(n.alphaCurve,1)},additive:!1}}function pa(n){let t=n||{},e=null,s=null,i=null,o=new Map,r=0,a={isActive(){return!1},stop(){}},c=0,l=1,u=0,h=0,p=0,d={x:0,y:0,remain:0,dur:0,amplitude:0,frequency:0,_phase:0},g={alpha:0,remain:0,dur:0,peak:0},x={scale:1,remain:0,dur:0,amplitude:0,frequency:0},v=!1;function w(A){if(u>0)if(u-=A,u<=0)u=0,l=1;else{let T=h>0?1-u/h:1;l=p+(1-p)*T}if(d.remain>0)if(d.remain-=A,d.remain<=0)d.remain=0,d.x=0,d.y=0;else{let T=d.remain/d.dur,P=d.amplitude*T;d._phase+=d.frequency*A*Math.PI*2,d.x=Math.sin(d._phase)*P,d.y=Math.cos(d._phase*1.3)*P}if(g.remain>0&&(g.remain-=A,g.remain<=0?(g.remain=0,g.alpha=0):g.alpha=g.peak*(g.remain/g.dur)),x.remain>0)if(x.remain-=A,x.remain<=0)x.remain=0,x.scale=1;else{let T=x.remain/x.dur,P=(1-T)*x.frequency*Math.PI*2;x.scale=1+Math.sin(P)*x.amplitude*T}}function _(A){c+=1,w(A)}function S(A){let T=A!==void 0?A:e?e.getContext2d():null;if(T&&g.alpha>0){T.globalAlpha=g.alpha,T.fillStyle="#ffffff";let P=T.canvas?T.canvas.width:0,k=T.canvas?T.canvas.height:0;T.fillRect(0,0,P,k),T.globalAlpha=1}}return{name:"particles-juice",version:"1.0.0",dependencies:[],init(A){var T;e=A,i=((T=A.getEngine())==null?void 0:T.particles)||null,typeof t.seed=="number"&&A.random.reseed(t.seed),t.autoStep!==!1&&(s=A.onFrame(P=>{_(P)}))},dispose(){v||(s&&(s.cancel(),s=null),o.forEach(A=>{try{A.stop()}catch{}}),o.clear(),l=1,u=0,d.remain=0,d.x=0,d.y=0,g.remain=0,g.alpha=0,x.remain=0,x.scale=1,v=!0)},spawnEmitter(A,T,P,k){let ct=typeof A=="string"?pl(A):to(A);if(!ct)return-1;k&&(ct=Object.assign(ct,k));let st=r++;if(!i)return o.set(st,a),st;let it=i.spawnEmitter(yl(ct,T,P));return o.set(st,it),st},stopEmitter(A){let T=o.get(A);if(T)try{T.stop()}catch{}},step(A){_(A)},render(A){S(A)},particleCount(){return 0},emitterCount(){let A=0;for(let T of o.values())T.isActive()&&(A+=1);return A},hitStop(A,T){h=Math.max(0,A),u=h,p=T==null?0:Math.max(0,Math.min(1,T)),l=h>0?p:1},getTimeScale(){return l},shakeScreen(A,T,P){d.dur=Math.max(0,A),d.remain=d.dur,d.amplitude=Math.max(0,T),d.frequency=P==null?30:P,d._phase=0,d.x=0,d.y=0},getShakeOffset(){return{x:d.x,y:d.y}},flashScreen(A,T){g.dur=Math.max(0,A),g.remain=g.dur,g.peak=T==null?.8:Math.max(0,Math.min(1,T)),g.alpha=g.dur>0?g.peak:0},getFlashAlpha(){return g.alpha},pulseScale(A,T,P){x.dur=Math.max(0,A),x.remain=x.dur,x.amplitude=T==null?.2:T,x.frequency=P==null?4:P,x.scale=1},getPulseScale(){return x.scale},juiceSnapshot(){return{timeScale:l,shake:{x:d.x,y:d.y},flashAlpha:g.alpha,pulseScale:x.scale}},probe(){return{particles:0,emitters:o.size,dropped:0,steps:c,disposed:v}}}}function ya(n){let t=yt(n.r)/255,e=yt(n.g)/255,s=yt(n.b)/255,i=Math.max(t,e,s),o=Math.min(t,e,s),r=(i+o)/2,a=0,c=0,l=i-o;return l>1e-12&&(c=r>.5?l/(2-i-o):l/(i+o),i===t?a=(e-s)/l%6:i===e?a=(s-t)/l+2:a=(t-e)/l+4,a*=60,a<0&&(a+=360)),{h:a,s:c,l:r}}function ga(n){let t=(n.h%360+360)%360,e=Ke(n.s),s=Ke(n.l);if(e<1e-12){let a=Math.round(s*255);return{r:a,g:a,b:a}}let i=s<.5?s*(1+e):s+e-s*e,o=2*s-i,r=t/360;return{r:Math.round(eo(o,i,r+1/3)*255),g:Math.round(eo(o,i,r)*255),b:Math.round(eo(o,i,r-1/3)*255)}}function eo(n,t,e){let s=e;return s<0&&(s+=1),s>1&&(s-=1),s<1/6?n+(t-n)*6*s:s<1/2?t:s<2/3?n+(t-n)*(2/3-s)*6:n}function yt(n){return n<0?0:n>255?255:n}function Ke(n){return n<0?0:n>1?1:n}function gl(n,t){let e=bl(n.from,t);if(e>=0&&e({r:yt(a.r),g:yt(a.g),b:yt(a.b)})),to:o}}function no(n,t,e){return n+(t-n)*e}function Sl(n,t){let e=ya(n),s=e.h+(t.hue||0),i=Ke(e.s*(t.sat==null?1:t.sat)),o=Ke(e.l*(t.light==null?1:t.light));return ga({h:s,s:i,l:o})}var wl=Object.freeze([Object.freeze([0,8,2,10]),Object.freeze([12,4,14,6]),Object.freeze([3,11,1,9]),Object.freeze([15,7,13,5])]);function ma(n){let t=n||{},e=null,s=!1,i={vignette:{enabled:so(t.vignette&&t.vignette.enabled,!1),strength:io(t.vignette&&t.vignette.strength,.5)},dither:{enabled:so(t.dither&&t.dither.enabled,!1),strength:io(t.dither&&t.dither.strength,.5)},scanline:{enabled:so(t.scanline&&t.scanline.enabled,!1),strength:io(t.scanline&&t.scanline.strength,.5)}};function o(a){let c=a!==void 0?a:e?e.getContext2d():null;if(!c)return;let l=c.canvas?c.canvas.width:0,u=c.canvas?c.canvas.height:0;if(i.vignette.enabled&&i.vignette.strength>0&&l>0&&u>0){let h=c.createRadialGradient(l/2,u/2,Math.min(l,u)*.25,l/2,u/2,Math.max(l,u)*.75);h.addColorStop(0,"rgba(0,0,0,0)"),h.addColorStop(1,"rgba(0,0,0,"+i.vignette.strength.toFixed(3)+")"),c.fillStyle=h,c.fillRect(0,0,l,u)}if(i.scanline.enabled&&i.scanline.strength>0&&l>0&&u>0){c.fillStyle="rgba(0,0,0,"+(i.scanline.strength*.5).toFixed(3)+")";for(let h=0;h0&&l>0&&u>0&&typeof c.getImageData=="function"&&typeof c.putImageData=="function"){let h=c.getImageData(0,0,l,u);Tl(h,i.dither.strength),c.putImageData(h,0,0)}}return{name:"palette-post",version:"1.0.0",dependencies:[],init(a){e=a},dispose(){s||(e=null,s=!0)},applyPaletteMap(a,c){return gl(a,c)},applyPaletteMapToBuffer(a,c){return ml(a,c)},lerpPaletteMap(a,c,l){return vl(a,c,l)},shiftHsl(a,c){return Sl(a,c)},rgbToHsl(a){return ya(a)},hslToRgb(a){return ga(a)},setPost(a){if(a)for(let c of["vignette","dither","scanline"])a[c]&&(typeof a[c].enabled=="boolean"&&(i[c].enabled=a[c].enabled),typeof a[c].strength=="number"&&(i[c].strength=Ke(a[c].strength)))},getPost(){return{vignette:{enabled:i.vignette.enabled,strength:i.vignette.strength},dither:{enabled:i.dither.enabled,strength:i.dither.strength},scanline:{enabled:i.scanline.enabled,strength:i.scanline.strength}}},renderPost(a){o(a)},probe(){return{disposed:s,post:this.getPost()}}}}function Tl(n,t){let e=Ke(t);if(e<=0)return n;let{data:s,width:i}=n,r=255/(Math.max(2,Math.round(16-e*14))-1);for(let a=0;a+3>2)%i,l=Math.floor((a>>2)/i),u=(wl[l&3][c&3]/16-.5)*r;for(let h=0;h<3;h++){let p=s[a+h]+u,d=Math.round(p/r)*r;s[a+h]=d<0?0:d>255?255:d}}return n}function so(n,t){return typeof n=="boolean"?n:t}function io(n,t){return typeof n=="number"?Ke(n):t}var ro=Object.freeze({blip:Object.freeze({name:"blip",params:Object.freeze([.6,0,880,0,.03,.06,1,1.5])}),thud:Object.freeze({name:"thud",params:Object.freeze([.8,0,90,0,.04,.18,0,1,0,0,0,0,0,4])}),chime:Object.freeze({name:"chime",params:Object.freeze([.5,0,660,.02,.12,.3,1,2])})}),ba=Object.keys(ro);function Al(n){let t=[];return n==null||typeof n!="object"?{ok:!1,errors:["song \u5FC5\u987B\u662F\u5BF9\u8C61"]}:(!Array.isArray(n.instruments)||n.instruments.length===0?t.push("instruments \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4"):n.instruments.forEach((e,s)=>{(!Array.isArray(e)||e.some(i=>typeof i!="number"||!Number.isFinite(i)))&&t.push(`instruments[${s}] \u5FC5\u987B\u662F\u6709\u9650\u6570\u5B57\u6570\u7EC4\uFF08ZzFX \u53C2\u6570\u5305\uFF09`)}),!Array.isArray(n.patterns)||n.patterns.length===0?t.push("patterns \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4"):n.patterns.forEach((e,s)=>{if(!Array.isArray(e)||e.length===0){t.push(`patterns[${s}] \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4\uFF08\u81F3\u5C11\u4E00\u4E2A\u58F0\u90E8\u901A\u9053\uFF09`);return}e.forEach((i,o)=>{if(!Array.isArray(i)||i.length<2){t.push(`patterns[${s}][${o}] \u901A\u9053\u81F3\u5C11\u542B [\u4E50\u5668\u7D22\u5F15, \u58F0\u50CF]`);return}if(i.some(c=>typeof c!="number"||!Number.isFinite(c))){t.push(`patterns[${s}][${o}] \u901A\u9053\u5FC5\u987B\u5168\u4E3A\u6709\u9650\u6570\u5B57`);return}let r=i[0]|0;Array.isArray(n.instruments)&&(r<0||r>=n.instruments.length)&&t.push(`patterns[${s}][${o}] \u4E50\u5668\u7D22\u5F15 ${r} \u8D8A\u754C\uFF08instruments \u957F\u5EA6 ${n.instruments.length}\uFF09`);let a=i[1];(a<-1||a>1)&&t.push(`patterns[${s}][${o}] \u58F0\u50CF ${a} \u8D8A\u754C\uFF08\u5E94 -1..+1\uFF09`)})}),!Array.isArray(n.sequence)||n.sequence.length===0?t.push("sequence \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4"):n.sequence.forEach((e,s)=>{if(typeof e!="number"||!Number.isInteger(e)){t.push(`sequence[${s}] \u5FC5\u987B\u662F\u6574\u6570 pattern \u7D22\u5F15`);return}Array.isArray(n.patterns)&&(e<0||e>=n.patterns.length)&&t.push(`sequence[${s}] \u7D22\u5F15 ${e} \u8D8A\u754C\uFF08patterns \u957F\u5EA6 ${n.patterns.length}\uFF09`)}),n.bpm!=null&&(typeof n.bpm!="number"||!(n.bpm>0))&&t.push("bpm \u5FC5\u987B\u662F\u6B63\u6570"),{ok:t.length===0,errors:t})}function ge(n){return typeof n!="number"||Number.isNaN(n)||n<0?0:n>1?1:n}function Cl(n,t){switch(n){case"ease-in":return t*t;case"ease-out":return Math.sqrt(t);case"constant":return 1;default:return t}}function xa(n,t){let e=ge(t);return n==null||!Array.isArray(n.voices)?[]:n.voices.map(s=>{let i=String(s&&s.id!=null?s.id:""),o=Array.isArray(s&&s.channelIndices)?s.channelIndices.slice():[],r=typeof s.minIntensity=="number"?ge(s.minIntensity):0,a=typeof s.maxIntensity=="number"?ge(s.maxIntensity):1,c=typeof s.volumeCurve=="string"?s.volumeCurve:"linear",l=typeof s.baseVolume=="number"?ge(s.baseVolume):1;if(ea)return{id:i,on:!1,volume:0,channelIndices:o};let u=a-r,h=u<=0?1:(e-r)/u,p=ge(Cl(c,h)*l);return{id:i,on:!0,volume:p,channelIndices:o}})}function va(n,t,e,s){try{let i=t[0]||[],o=t[1]||i,r=Math.max(i.length,o.length);if(r===0)return null;let c=n.createBuffer(2,r,44100);c.getChannelData(0).set(i),c.getChannelData(1).set(o.length?o:i);let l=n.createBufferSource();l.buffer=c,l.loop=!!s;let u=n.createGain();return u.gain.value=ge(e*.3),l.connect(u),u.connect(n.destination),l.start(),{stop(){try{l.stop()}catch(h){}try{l.disconnect(),u.disconnect()}catch(h){}}}}catch(i){return ao("[audio-music] \u53D7\u63A7\u97F3\u9891\u64AD\u653E\u5F02\u5E38\uFF0C\u964D\u7EA7\u4E3A\u9759\u9ED8",i),null}}function Sa(n){let t=n||{},e=typeof t.masterVolume=="number"?ge(t.masterVolume):1,s=()=>null,i=null,o=null,r={voices:[]},a=1,c=null,l=!1,u=0,h=!1,p=!1;function d(){let S=s();return S==null?(u+=1,h||(oo("[audio-music] \u65E0\u53D7\u63A7\u97F3\u9891\u4E0A\u4E0B\u6587\uFF08getAudioContext \u8FD4\u56DE null\uFF09\uFF0C\u5168\u90E8\u53D1\u58F0\u9759\u9ED8 no-op\uFF08\u8BC4\u4F30\u73AF\u5883\u65E0\u58F0\u5361\u65F6\u7684\u5BB9\u9519\u964D\u7EA7\uFF09"),h=!0),null):S}function g(){if(!o||!i)return null;try{let S=typeof o.bpm=="number"&&o.bpm>0?o.bpm:125;return i.synthSong(o.instruments,o.patterns,o.sequence,S)}catch(S){return ao("[audio-music] \u66F2\u8C31\u6E32\u67D3\u5F02\u5E38\uFF0C\u964D\u7EA7\u4E3A\u9759\u9ED8",S),null}}function x(){let S=xa(r,a);if(S.length===0)return 1;let E=0;for(let A of S)A.on&&(E=Math.max(E,A.volume));return E}function v(S,E){typeof E=="number"&&(a=ge(E));let A=d();if(A==null||!o)return;w();let T=g();if(!T)return;let P=ge(e*x());c=va(A,T,P,S),l=!!S&&c!=null}function w(){c&&(c.stop(),c=null),l=!1}return{name:"audio-music",version:"1.0.0",dependencies:[],init(S){s=()=>S.getAudioContext();let E=S.getEngine&&S.getEngine();i=E?E.audio.synth:null},dispose(){p||(w(),p=!0)},loadSong(S){let E=Al(S);return E.ok?o={instruments:S.instruments,patterns:S.patterns,sequence:S.sequence,bpm:typeof S.bpm=="number"?S.bpm:125}:oo("[audio-music] \u66F2\u8C31\u6821\u9A8C\u5931\u8D25\uFF0C\u672A\u8F7D\u5165\uFF1A"+E.errors.join("\uFF1B")),E},play(S){v(!1,S)},stop(){w()},loop(S){v(!0,S)},setIntensityLayering(S){r=S&&Array.isArray(S.voices)?{voices:S.voices}:{voices:[]}},setIntensity(S){a=ge(S)},resolveVoices(S){return xa(r,S)},playSfx(S){let E=ro[S];if(!E){oo("[audio-music] \u672A\u77E5\u97F3\u6548\u9884\u8BBE\uFF1A"+String(S));return}let A=d();if(A!=null)try{let T=i?i.synthSfx(E.params):null;if(!T)return;va(A,[T,T],e,!1)}catch(T){ao("[audio-music] \u97F3\u6548\u64AD\u653E\u5F02\u5E38\uFF0C\u964D\u7EA7\u4E3A\u9759\u9ED8 name="+S,T)}},getPreset(S){return ro[S]},listPresets(){return ba.slice()},probe(){return{hasAudio:s()!=null,hasSong:o!=null,intensity:a,voiceCount:r.voices.length,looping:l,silentNoops:u,presetCount:ba.length}}}}function ao(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function oo(n){typeof console!="undefined"&&typeof console.warn=="function"&&console.warn(n)}var _l="zaomeng.save";function El(n){if(typeof TextEncoder!="undefined")return new TextEncoder().encode(n).length;if(typeof Buffer!="undefined"&&typeof Buffer.byteLength=="function")return Buffer.byteLength(n,"utf8");let t=0;for(let e=0;e=55296&&s<=56319?(t+=4,e++):t+=3}return t}function lo(){let n=new Map;return{getItem(t){return n.has(t)?n.get(t):null},setItem(t,e){n.set(t,e)},removeItem(t){n.delete(t)},keys(){return Array.from(n.keys())}}}function wa(){if(typeof localStorage=="undefined")throw new Error("[save-progress] createLocalStorageAdapter \u9700\u8981\u5168\u5C40 localStorage\uFF08\u4EC5\u6D4F\u89C8\u5668\u96C6\u6210\u6BB5\u53EF\u7528\uFF09\u3002node/host-dev \u8BF7\u7528\u7F3A\u7701\u5185\u5B58 adapter \u6216 createMemoryAdapter()\u3002");return{getItem(n){return localStorage.getItem(n)},setItem(n,t){localStorage.setItem(n,t)},removeItem(n){localStorage.removeItem(n)},keys(){let n=[];for(let t=0;t0?t.namespace:_l;if(e.indexOf(":")>=0)throw new Error('[save-progress] namespace \u4E0D\u5F97\u542B\u5206\u9694\u7B26 ":"\uFF08\u5F53\u524D="'+e+'"\uFF09');let s=typeof t.maxValueBytes=="number"&&t.maxValueBytes>0?Math.floor(t.maxValueBytes):32768,i=!Rl(t.adapter),o=i?lo():t.adapter,r=e+":",a=0,c=0,l=!1;function u(d){return typeof d!="string"||d.length===0?r+String(d):r+d}function h(){try{let d=o.keys();return Array.isArray(d)?d.filter(g=>typeof g=="string"&&g.indexOf(r)===0):[]}catch(d){return ns("[save-progress] adapter.keys() \u5F02\u5E38\uFF0C\u964D\u7EA7\u8FD4\u56DE\u7A7A\u96C6",d),[]}}return{name:"save-progress",version:"1.0.0",dependencies:[],init(d){h()},dispose(){},get(d,g){if(!co(d))return g;let x;try{x=o.getItem(u(d))}catch(v){return ns("[save-progress] adapter.getItem \u5F02\u5E38\uFF0C\u8FD4\u56DE\u9ED8\u8BA4\u503C key="+d,v),g}if(x==null)return g;try{return JSON.parse(x)}catch{return a+=1,l||(ss("[save-progress] \u68C0\u6D4B\u5230\u635F\u574F\u5B58\u6863\uFF08\u975E\u6CD5 JSON\uFF09\uFF0C\u5DF2\u5BB9\u9519\u56DE\u9000\u9ED8\u8BA4\u503C key="+d),l=!0),g}},set(d,g){if(!co(d))return ss("[save-progress] set \u6536\u5230\u975E\u6CD5 key\uFF0C\u62D2\u7EDD\u5199\u5165\uFF1A"+String(d)),!1;let x;try{x=JSON.stringify(g)}catch{return c+=1,ss("[save-progress] \u503C\u4E0D\u53EF JSON \u5E8F\u5217\u5316\uFF08\u5FAA\u73AF\u5F15\u7528?\uFF09\uFF0C\u62D2\u7EDD\u5199\u5165 key="+d),!1}if(x===void 0)return c+=1,ss("[save-progress] \u503C\u5E8F\u5217\u5316\u4E3A undefined\uFF08\u5982\u7EAF undefined/\u51FD\u6570\uFF09\uFF0C\u62D2\u7EDD\u5199\u5165 key="+d),!1;let v=El(x);if(v>s)return c+=1,ss("[save-progress] \u503C\u8D85\u5B57\u8282\u4E0A\u9650\u62D2\u7EDD\u5199\u5165 key="+d+"\uFF08"+v+" > "+s+" bytes\uFF09"),!1;try{return o.setItem(u(d),x),!0}catch(w){return c+=1,ns("[save-progress] adapter.setItem \u5F02\u5E38\uFF0C\u5199\u5165\u5931\u8D25 key="+d,w),!1}},remove(d){if(co(d))try{o.removeItem(u(d))}catch(g){ns("[save-progress] adapter.removeItem \u5F02\u5E38\uFF08\u5DF2\u5FFD\u7565\uFF09key="+d,g)}},clear(){let d=h(),g=0;for(let x of d)try{o.removeItem(x),g+=1}catch(v){ns("[save-progress] clear \u65F6 removeItem \u5F02\u5E38\uFF08\u5DF2\u8DF3\u8FC7\uFF09fullKey="+x,v)}return g},probe(){return{namespace:e,maxValueBytes:s,usingMemoryAdapter:i,size:h().length,corruptRecoveries:a,rejectedWrites:c}}}}function co(n){return typeof n=="string"&&n.length>0}function Rl(n){return!!n&&typeof n.getItem=="function"&&typeof n.setItem=="function"&&typeof n.removeItem=="function"&&typeof n.keys=="function"}function ns(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function ss(n){typeof console!="undefined"&&typeof console.warn=="function"&&console.warn(n)}var Pl={w:390,h:844};function Aa(n){let t=((n&&n.seed)!=null?n.seed:0)>>>0,e=aa({cellSize:96}),s=ca(),i=fa({inputBufferMs:260,inputTypes:["pointerdown"]}),o=pa({seed:t,maxParticles:600}),r=ma({vignette:{enabled:!0,strength:.22}}),a=Sa({masterVolume:.8}),c;try{c=wa()}catch(p){console.warn("[generic] localStorage \u4E0D\u53EF\u7528\uFF0C\u5B58\u6863\u9000\u5185\u5B58 adapter\uFF1A"+(p&&p.message)),c=lo()}let l=Ta({namespace:"zaomeng-generic",adapter:c});return{plugins:{collision:e,physics:s,gamefeel:i,juice:o,palettePost:r,audioMusic:a,save:l},registerOrder:[e,s,i,o,r,l,a],viewport:Pl,buildFactoryOpts:(p,d)=>({runtime:{plugins:d.plugins,bundle:d.bundle,getRealAudioCtx:d.getRealAudioCtx}})}}function is(n){let t=n||{},e=null,s="booting",i="",o=0,r=0,a=[],c=[],l=[],u={x:0,y:0,w:80,h:16},h=195,p=[],d=null,g=null,x=null,v=0,w=80,_=390,S=844,E=6,A=350,T=5,P=5,k=8,ct=44,st=18,it=2,gt=50,jt=(_-(k*(ct+it)-it))/2;function Ve(M){e=M.ctx,s="playing",i="",o=0,r=0,a=[],c=[],l=[],v=0,u.w=w,u.x=(_-w)/2,u.y=S-40;for(let U=0;U0&&c.push({x:u.x+u.w*(.2+.6*U/F),y:u.y-E-5,vx:ae,vy:qe,radius:E,alive:!0})}let xt=e.getEngine();xt&&(d=xt.particles||null,xt.audio&&xt.audio.synth&&(g=xt.audio.synth),x=xt.math||null);let O=e.getInput();if(O){let U=O.on("pointerdown",wt=>{h=wt.x}),pt=O.on("pointermove",wt=>{h=wt.x});p.push(U,pt)}h=_/2}function Bt(M){if(s!=="playing")return;let F=h-u.x;u.x+=F*.3,u.x=Math.max(0,Math.min(_-u.w,u.x)),v>0&&(v-=M,v<=0&&(u.w=w,u.x=Math.max(0,Math.min(_-u.w,u.x))));let xt=2;for(let O of c){if(!O.alive)continue;let U=O.vx*M,pt=O.vy*M,wt=Math.sqrt(U*U+pt*pt),ae=Math.max(1,Math.ceil(wt/xt)),qe=U/ae,fn=pt/ae;for(let He=0;He_&&(O.x=_-O.radius,O.vx=-O.vx),O.y-O.radius<0&&(O.y=O.radius,O.vy=-O.vy),O.y+O.radius>S){if(O.alive=!1,d)try{d.spawnEmitter({pos:{x:O.x,y:S},count:15,speed:80,particleTime:.3,colorStart:{r:1,g:.2,b:.2,a:1},colorEnd:{r:.8,g:0,b:0,a:0}})}catch{}break}if(O.vy>0&&O.y+O.radius>=u.y-1&&O.y-O.radius<=u.y+u.h+1&&O.x+O.radius>u.x&&O.x-O.radius.01){let Xe=Math.sqrt(zt),Ji=Pt/Xe,Ui=pn/Xe;O.x+=Ji*(Pe-Xe),O.y+=Ui*(Pe-Xe);let $r=O.vx*Ji+O.vy*Ui;O.vx-=2*$r*Ji,O.vy-=2*$r*Ui}else O.y=lt.y-Pe,O.vy=-O.vy;if(e.random.next()<.2){let Xe=e.random.next()<.5?"extra_ball":"widen";l.push({x:lt.x+lt.w/2,y:lt.y+lt.h/2,type:Xe,radius:6,speed:150})}break}}}}c=c.filter(O=>O.alive);for(let O=l.length-1;O>=0;O--){let U=l[O];if(U.y+=U.speed*M,U.y+U.radius>=u.y&&U.y-U.radius<=u.y+u.h&&U.x+U.radius>u.x&&U.x-U.radiusS+20&&l.splice(O,1)}r===0?(s="gameover",i="cleared_all"):c.length===0&&(s="gameover",i="ball_lost")}function ht(M){M.fillStyle="#0a0a1a",M.fillRect(0,0,_,S);for(let F of a)F.alive&&(M.fillStyle="#44aaff",M.fillRect(F.x,F.y,F.w,F.h),M.strokeStyle="#3399ee",M.lineWidth=1,M.strokeRect(F.x,F.y,F.w,F.h));for(let F of l)M.fillStyle=F.type==="extra_ball"?"#00ff88":"#ffaa00",M.beginPath(),M.arc(F.x,F.y,F.radius,0,Math.PI*2),M.fill();for(let F of c)F.alive&&(M.fillStyle="#ffffff",M.beginPath(),M.arc(F.x,F.y,F.radius,0,Math.PI*2),M.fill(),M.fillStyle="#cccccc",M.beginPath(),M.arc(F.x-2,F.y-2,F.radius*.5,0,Math.PI*2),M.fill());M.fillStyle="#ffaa44",M.fillRect(u.x,u.y,u.w,u.h),M.fillStyle="#ffcc88",M.fillRect(u.x,u.y,u.w,u.h/2),M.fillStyle="#ffffff",M.font="16px monospace",M.fillText("Score: "+o,10,28),M.fillText("Remaining: "+r,10,52),M.fillText("Balls: "+c.length,10,76),s==="gameover"&&(M.fillStyle="rgba(0,0,0,0.6)",M.fillRect(0,0,_,S),M.fillStyle="#ffcc00",M.font="bold 32px sans-serif",M.textAlign="center",i==="cleared_all"?M.fillText("YOU WIN!",_/2,S/2-20):M.fillText("GAME OVER",_/2,S/2-20),M.font="18px sans-serif",M.fillStyle="#ffffff",M.fillText("Tap to restart (not auto)",_/2,S/2+40),M.textAlign="left")}function Dt(){for(let M of p)try{M.cancel()}catch{}p=[],s="booting",c=[],a=[],l=[],v=0,u.w=w,h=_/2}function We(){let M=c.length>0?{x:c[0].x,y:c[0].y,vx:c[0].vx,vy:c[0].vy}:{x:0,y:0,vx:0,vy:0},F=c.map(xt=>({x:xt.x,y:xt.y}));return{seed:ye==null?void 0:ye.seed,state:()=>({phase:s,result:i==="cleared_all"?"win":i==="ball_lost"?"lose":null,score:o,remaining:r,progress:0,gameoverReason:i,ball:M,paddle:{x:u.x,y:u.y,w:u.w},balls:F})}}let ye;return{init:M=>(ye=M,Ve(M)),update:Bt,render:ht,destroy:Dt,_forensicsView:We}}var bd=is,xd=is;async function vd(n){let t=n||{},e=t.engine||await Promise.resolve().then(()=>(jc(),Fc)),s=(t.seed!=null?t.seed:305441741)>>>0,i=Aa({seed:s});return ra({canvas:t.canvas,statusEl:t.statusEl||null,engine:e,seed:s,mode:t.mode||"play",engineMode:"real",viewport:i.viewport,factory:is,plugins:i.plugins,registerOrder:i.registerOrder,buildFactoryOpts:i.buildFactoryOpts,recHook:t.recHook||null,onReady:t.onReady||null})}return Vc(Sd);})();
+color = `+this.color),t}renderDebug(t=!0){let e=t?this.isHoverObject()?Xa:this.disabled?Ka:this.interactive?nr:$a:Ya;E.drawRect(this.nativePos,this.size,de,4,e)}click(t=!0){this.onClick(),t&&this.soundClick&&this.soundClick.play()}onUpdate(){}onRender(){}onEnter(){}onLeave(){}onPress(){}onRelease(){}onClick(){}onChange(){}},gs=class extends se{constructor(t,e,i="",s="center",o=E.defaultFont){super(t,e),p(W(i),"ui text must be a string"),p(["left","center","right"].includes(s),"ui text align must be left, center, or right"),p(W(o),"ui text font must be a string"),this.text=i,this.align=s,this.font=o,this.canBeHover=!1,this.color=de,this.shadowColor=de,this.gradientColor=void 0,this.lineWidth=0,this.textFitScale=1}render(){super.render();let t=this.getTextSize();E.drawText(this.text,this.nativePos,t,this.textColor,this.textLineWidth,this.textLineColor,this.align,this.font,this.fontStyle,!0,this.textShadow,this.shadowColor,this.shadowBlur,this.shadowOffset)}},Lo=class extends se{constructor(t,e,i=""){super(t,e),p(W(i),"ui text must be a string"),this.maxLength=0,this.text=i,this.interactive=!0,this.canBeHover=!0}click(){E.keyInputObject=this,this.onClick()}stopEditing(){this.isKeyInputObject()&&(this.soundRelease&&this.soundRelease.play(),E.activeObject=void 0,E.keyInputObject=void 0,this.onChange())}onKeyDown(t){let e=t.code,i=t.key;e==="Backspace"?this.text=this.text.slice(0,-1):e==="Enter"||e==="Escape"?this.stopEditing():i.length===1&&(!this.maxLength||this.text.lengththis.size.y,i=e?this.size.y:this.size.x,s=e?this.size.x:this.size.y,o=e?this.nativePos.x:this.nativePos.y,a=s-i,r=o-a/2,c=o+a/2,l=E.screenToNative(Nt);this.value=e?jt(l.x,r,c):jt(l.y,c,r)}else if(this.isNavigationObject()){let e=E.getNavigationOtherDirection();E.navigationTimer.active()||(this.value=z(this.value+e*.01))}this.value===t||this.onChange()}render(){super.render();let t=this.size.x>this.size.y,e=t?this.size.x:this.size.y,i=t?this.size.y:this.size.x;if(this.fillMode){let o=Z(i,this.cornerRadius*2),a=Ut(o,e,this.value),r=(a-e)*(t?.5:-.5),c=this.nativePos.add(t?b(r,0):b(0,r)),l=this.disabled?this.disabledColor:this.handleColor,u=t?b(a,this.size.y):b(this.size.x,a);E.drawRect(c,u,l,this.lineWidth,this.lineColor,this.cornerRadius,this.gradientColor)}else{let o=z(t?this.value:1-this.value),a=(e-i)*(o-.5),r=this.nativePos.add(t?b(a,0):b(0,a)),c=this.disabled?this.disabledColor:this.handleColor,l=b(i);E.drawRect(r,l,c,this.lineWidth,this.lineColor,this.cornerRadius,this.gradientColor)}let s=this.getTextSize();E.drawText(this.text,this.nativePos,s,this.textColor,this.textLineWidth,this.textLineColor,this.align,this.font,this.fontStyle,!0,this.textShadow)}navigatePressed(){this.value=this.value?0:1,this.onChange(),this.onRelease(),super.navigatePressed()}},Io=class extends se{constructor(t,e,i,s=!1,o=!1,a=1){super(t,e||b()),p(W(i),"video src must be a string"),p(P(a),"video volume must be a number"),this.color=st,this.cornerRadius=0,this.volume=a,this.video=document.createElement("video"),this.video.loop=o,this.video.volume=z(a*gn),this.video.muted=!Wt,this.video.style.display="none",this.video.src=i,document.body.appendChild(this.video),s&&this.play()}async play(){try{await this.video.play()}catch{}}pause(){this.video.pause()}stop(){this.video.pause(),this.video.currentTime=0}isLoading(){return this.video.readyState=1,"ui layout columns must be a number >= 1"),p(P(i),"ui layout gap must be a number"),p(P(s),"ui layout padding must be a number"),this.columns=e,this.gap=i,this.padding=s,o&&(this.color=de,this.gradientColor=void 0,this.lineWidth=0,this.shadowColor=de),this.relayout()}addChild(t){return super.addChild(t),this.relayout(),t}removeChild(t){super.removeChild(t),this.relayout()}relayout(){let t=this.children.length;if(!t){this.size=b(this.padding*2);return}let e=this.columns,i=si(t/e),s=new Array(e).fill(0),o=new Array(i).fill(0);for(let f=0;f=0&&m.objects.splice(t,1),super.destroy()}updatePhysics(){}render(){this.tileInfo?super.render():this.drawFixtures(this.color,this.lineColor,this.lineWidth)}renderDebugInfo(){let t=!this.getIsAwake(),e=this.getBodyType()===m.bodyTypeStatic,i=U(t?1:0,t?1:0,e?1:0,.5);this.drawFixtures(i)}drawFixtures(t=q,e=st,i=.1,s,o){this.getFixtureList().forEach(a=>{m.castShapeObject(a.GetShape()).GetType()!==m.instance.b2Shape.e_edge&&m.drawFixture(a,this.pos,this.angle,t,e,i,s,o)}),this.edgeLists.forEach(a=>fo(a,i,e,!1,this.pos,this.angle)),this.edgeLoops.forEach(a=>fo(a,i,e,!0,this.pos,this.angle))}beginContact(t){}endContact(t){}addShape(t,e=1,i=.2,s=0,o=!1){p(P(e),"density must be a number"),p(P(i),"friction must be a number"),p(P(s),"restitution must be a number");let a=new m.instance.b2FixtureDef;return a.set_shape(t),a.set_density(e),a.set_friction(i),a.set_restitution(s),a.set_isSensor(o),this.body.CreateFixture(a)}addBox(t=b(1),e=b(),i=0,s,o,a,r){p(O(t),"size must be a Vector2"),p(t.x>0&&t.y>0,"size must be positive"),p(O(e),"offset must be a Vector2"),p(P(i),"angle must be a number");let c=new m.instance.b2PolygonShape;return c.SetAsBox(t.x/2,t.y/2,m.vec2dTo(e),-i),this.addShape(c,s,o,a,r)}addPoly(t,e,i,s,o){p(ue(t),"points must be an array");function a(c){p(3<=c.length&&c.length<=8);let l=m.instance._malloc(c.length*8);for(let f=0,d=0;f>2]=c[f].x,d+=4,m.instance.HEAPF32[l+d>>2]=c[f].y,d+=4;let u=m.instance.wrapPointer(l,m.instance.b2Vec2),h=new m.instance.b2PolygonShape;return h.Set(u,c.length),m.instance._free(l),h}let r=a(t);return this.addShape(r,e,i,s,o)}addRegularPoly(t=1,e=8,i,s,o,a){p(P(t)&&t>0,"diameter must be a positive number"),p(P(e)&&e>2,"sides must be a positive number greater than 2");let r=[],c=t/2;for(let l=e;l--;)r.push(b(c,0).rotate((l+.5)/e*Y*2));return this.addPoly(r,i,s,o,a)}addRandomPoly(t=1,e,i,s,o){p(P(t)&&t>0,"diameter must be a positive number");let a=er(3,9),r=[],c=t/2;for(let l=a;l--;)r.push(b(ht(c/2,c*1.5),0).rotate(l/a*Y*2));return this.addPoly(r,e,i,s,o)}addCircle(t=1,e=b(),i,s,o,a){p(P(t)&&t>0,"diameter must be a positive number"),p(O(e),"offset must be a Vector2");let r=new m.instance.b2CircleShape;return r.set_m_p(m.vec2dTo(e)),r.set_m_radius(t/2),this.addShape(r,i,s,o,a)}addEdge(t,e,i,s,o,a){p(O(t),"point1 must be a Vector2"),p(O(e),"point2 must be a Vector2");let r=new m.instance.b2EdgeShape;return r.Set(m.vec2dTo(t),m.vec2dTo(e)),this.addShape(r,i,s,o,a)}addEdgeList(t,e,i,s,o){p(ue(t),"points must be an array");let a=[],r=[];for(let c=0;ct[ee(l,t.length)];for(let l=0;lthis.destroyFixture(t))}getCenterOfMass(){return m.vec2From(this.body.GetWorldCenter())}getLinearVelocity(){return m.vec2From(this.body.GetLinearVelocity())}getAngularVelocity(){return this.body.GetAngularVelocity()}getMass(){return this.body.GetMass()}getInertia(){return this.body.GetInertia()}getIsAwake(){return this.body.IsAwake()}getBodyType(){return this.body.GetType()}getSpeed(){return this.getLinearVelocity().length()}setTransform(t,e){this.pos=t,this.angle=e,this.body.SetTransform(m.vec2dTo(t),-e)}setPosition(t){this.setTransform(t,this.body.GetAngle())}setAngle(t){this.setTransform(m.vec2From(this.body.GetPosition()),t)}setLinearVelocity(t){this.body.SetLinearVelocity(m.vec2dTo(t))}setAngularVelocity(t){this.body.SetAngularVelocity(t)}setLinearDamping(t){this.body.SetLinearDamping(t)}setAngularDamping(t){this.body.SetAngularDamping(t)}setGravityScale(t=1){this.body.SetGravityScale(this.gravityScale=t)}setBullet(t=!0){this.body.SetBullet(t)}setAwake(t=!0){this.body.SetAwake(t)}setBodyType(t){this.body.SetType(t)}setSleepingAllowed(t=!0){this.body.SetSleepingAllowed(t)}setFixedRotation(t=!0){this.body.SetFixedRotation(t)}setCenterOfMass(t){this.setMassData(t)}setMass(t){this.setMassData(void 0,t)}setMomentOfInertia(t){this.setMassData(void 0,void 0,t)}resetMassData(){this.body.ResetMassData()}setMassData(t,e,i){let s=new m.instance.b2MassData;this.body.GetMassData(s),t!==void 0&&s.set_center(m.vec2dTo(t)),e!==void 0&&s.set_mass(e),i!==void 0&&s.set_I(i),this.body.SetMassData(s)}setFilterData(t=0,e=0,i=0){this.getFixtureList().forEach(s=>{let o=s.GetFilterData();o.set_categoryBits(t),o.set_maskBits(65535&~e),o.set_groupIndex(i)})}setSensor(t=!0){this.getFixtureList().forEach(e=>e.SetSensor(t))}applyForce(t,e){e||(e=this.getCenterOfMass()),this.setAwake(),this.body.ApplyForce(m.vec2dTo(t),m.vec2dTo(e))}applyAcceleration(t,e){e||(e=this.getCenterOfMass()),this.setAwake();let i=t.scale(this.getMass());this.body.ApplyLinearImpulse(m.vec2dTo(i),m.vec2dTo(e))}applyImpulse(t,e){e||(e=this.getCenterOfMass()),this.setAwake(),this.body.ApplyLinearImpulse(m.vec2dTo(t),m.vec2dTo(e))}applyTorque(t){this.setAwake(),this.body.ApplyTorque(t)}applyAngularAcceleration(t){this.setAwake(),this.body.ApplyAngularImpulse(t*this.getInertia())}applyAngularImpulse(t){this.setAwake(),this.body.ApplyAngularImpulse(t)}hasFixtures(){return!m.isNull(this.body.GetFixtureList())}getFixtureList(){let t=[];for(let e=this.body.GetFixtureList();!m.isNull(e);)t.push(e),e=e.GetNext();return t}hasJoints(){return!m.isNull(this.body.GetJointList())}getJointList(){let t=[];for(let e=this.body.GetJointList();!m.isNull(e);)t.push(e),e=e.get_next();return t}},ys=class extends Si{constructor(t,e,i,s=0,o,a=0){let r=m.bodyTypeStatic;super(t,e,i,s,o,r,a)}},Go=class extends Si{constructor(t,e,i,s=0,o,a=0){let r=m.bodyTypeKinematic;super(t,e,i,s,o,r,a)}},Fo=class extends ys{constructor(t){p(t instanceof pi,"tileLayer must be a TileCollisionLayer"),super(t.pos,t.size),this.tileLayer=t,this.addChild(t)}render(){}buildCollision(t=.2,e=0){this.destroyAllFixtures(),this.pos=this.tileLayer.pos.copy(),this.size=this.tileLayer.size.copy();let i=[],s=(a,r)=>a+r*this.size.x,o=(a,r)=>!i[s(a,r)]&&this.tileLayer.getCollisionData(b(a,r))>0;for(let a=0;as.fractiono.pos.distanceSquared(t)0,"Tween duration must be > 0"),this.callback=t,this.start=e,this.end=i,this.duration=s,this.life=s,this.ease=o.ease||Ss.LINEAR,this.useRealTime=!!o.useRealTime,this.paused=!!o.paused,this.thenCallback=void 0,this.loopRemaining=0,Yt.push(this),t(this.interp(s))}setEase(t){return this.ease=t,this}then(t){return this.thenCallback=t,this.loopRemaining=0,this}loop(t=1/0){return this.loopRemaining=t,this.thenCallback=()=>Cc(this),this}pingPong(t=1/0){return this.loopRemaining=t,this.thenCallback=()=>Rc(this),this}pause(){this.paused=!0}resume(){this.paused=!1}restart(){this.life=this.duration,this.paused=!1,Yt.indexOf(this)<0&&Yt.push(this),this.callback(this.interp(this.duration))}isActive(){return!this.paused&&Yt.indexOf(this)>=0}getPercent(){return jt(this.duration-this.life,0,this.duration)}getValue(){return this.interp(this.life)}interp(t){let e=this.ease((this.duration-t)/this.duration);return Ca(this.start)?this.start.lerp(this.end,e):this.start+(this.end-this.start)*e}stop(){let t=Yt.indexOf(this);t>=0&&Yt.splice(t,1),this.thenCallback=void 0}},Ss={LINEAR:n=>n,POWER:n=>t=>t**n,SINE:n=>1-at(n*(Y/2)),CIRC:n=>1-(1-n*n)**.5,EXPO:n=>n===0?0:2**(10*n-10),BACK:n=>n*n*(2.70158*n-1.70158),ELASTIC:n=>n===0?0:n===1?1:-(2**(10*n-10))*it((37-40*n)*Y/6),SPRING:n=>1-(it(Y*(1-n)*(.2+2.5*(1-n)**3))*n**2.2+(1-n))*(1+1.2*n),BOUNCE:n=>{let t=1-n,e;return t<4/11?e=7.5625*t*t:t<8/11?e=7.5625*(t-=6/11)*t+.75:t<10/11?e=7.5625*(t-=9/11)*t+.9375:e=7.5625*(t-=10.5/11)*t+.984375,1-e},IN:n=>n,OUT:n=>t=>1-n(1-t),IN_OUT:n=>Ss.PIECEWISE(n,Ss.OUT(n)),PIECEWISE:(...n)=>{let t=n.length;return e=>{let i=e*t-1e-9>>0;return(n[i]((e-i/t)*t)+i)/t}},BEZIER:(n,t,e,i)=>{let s=o=>{let a=1-o,r=3*a*a*o,c=3*a*o*o,l=o**3;return[r*n+c*e+l,r*t+c*i+l]};return o=>{let a=0,r=1;for(let c=0;c<128;c++){let l=(a+r)/2,[u,h]=s(l);if(nt(u-o)<1e-5)return h;u=this.size.x||e>=this.size.y?null:this.nodes[t+e*this.size.x]}worldToTile(t){let e=this.tileLayer?this.tileLayer.pos.x:0,i=this.tileLayer?this.tileLayer.pos.y:0;return b(wt(t.x-e),wt(t.y-i))}tileToWorld(t,e){let i=this.tileLayer?this.tileLayer.pos.x:0,s=this.tileLayer?this.tileLayer.pos.y:0;return b(t+.5+i,e+.5+s)}buildNodeData(){let t=this.size.x,e=this.size.y,i=this.tileLayer?this.tileLayer.pos.x:0,s=this.tileLayer?this.tileLayer.pos.y:0;for(let o=0;o0&&(c?l>0&&bt(r.posWorld,oo,U(1,0,0,Z(.2,l*.05)),this.debugTime):bt(r.posWorld,oo,U(1,0,0,.25),this.debugTime))}}aStarSearch(t,e){p(t&&e,"aStarSearch needs both endpoints"),p(t!==e,"aStarSearch: start and end must differ \u2014 caller should handle trivial case"),p(t.walkable&&e.walkable,"aStarSearch: endpoints must be walkable");let i=[t];t.isOpen=!0;let s=0;for(;i.length>0;){let o=0,a=i[0].f;for(let c=1;cthis.maxLoop)break;r.isOpen=!1,i.splice(o,1),r.isClosed=!0,this.debug&&this.debugTime>0&&bt(r.posWorld,oo,U(1,1,1,.05),this.debugTime);for(let c=-1;c<=1;++c)for(let l=-1;l<=1;++l){if(l===0&&c===0)continue;let u=this.getNode(r.pos.x+l,r.pos.y+c);if(!u||!u.walkable||u.isClosed)continue;let h=1;if(l!==0&&c!==0){let v=this.getNode(r.pos.x+l,r.pos.y);if(!v||!v.walkable)continue;let w=this.getNode(r.pos.x,r.pos.y+c);if(!w||!w.walkable)continue;h=fd}let f=r.g+h+u.cost;if(!u.isOpen)u.isOpen=!0,i.push(u);else if(f>=u.g)continue;u.parent=r,u.g=f;let d=nt(e.pos.x-u.pos.x),y=nt(e.pos.y-u.pos.y),x=K(d,y)+(Math.SQRT2-1)*Z(d,y);u.f=u.g+x*this.heuristicWeight}}return e.parent!==null}getNearestClearNode(t,e=10,i=!0){p(O(t),"worldPos must be a Vector2"),i&&this.buildNodeData();let s=this.tileLayer?this.tileLayer.pos.x:0,o=this.tileLayer?this.tileLayer.pos.y:0,a=wt(t.x-s),r=wt(t.y-o);for(let c=0;c<=e;++c){let l=null,u=0;for(let h=-c;h<=c;++h)for(let f=-c;f<=c;++f){if(c>0&&nt(f)!==c&&nt(h)!==c)continue;let d=this.getNode(a+f,r+h);if(!d||!d.isClear())continue;let y=d.posWorld.x-t.x,x=d.posWorld.y-t.y,v=y*y+x*x;(!l||v0&&zt(s.posWorld,.3,U(.5,0,.5,.5),this.debugTime),t.splice(e,1),e=K(1,e-1);continue}else if(c===2){this.debug&&this.debugTime>0&&zt(s.posWorld,.3,U(1,0,0,.5),this.debugTime);let d,y;i.pos.y===s.pos.y&&o.pos.x===s.pos.x?(d=i.pos.x,y=o.pos.y):(d=o.pos.x,y=i.pos.y);let x=this.getNode(d,y);if(x&&x.isClear()){t.splice(e,1),e=K(1,e-1);continue}}else if(c===5){this.debug&&this.debugTime>0&&zt(s.posWorld,.3,U(1,1,0,.5),this.debugTime);let d=e>=2?t[e-2]:i,y,x,v,w;l===0||h===0?(y=o.pos.x,x=s.pos.y,v=i.pos.x,w=s.pos.y):(y=s.pos.x,x=o.pos.y,v=s.pos.x,w=i.pos.y);let C=y-d.pos.x,S=x-d.pos.y,_=v-d.pos.x,A=w-d.pos.y,T=C*C+S*S,L=_*_+A*A,F=T0&&zt(s.posWorld,.3,U(0,1,0,.5),this.debugTime),l===h&&u===f){++e;continue}else{let d,y;i.pos.y===o.pos.y?(d=s.pos.x,y=i.pos.y):(d=i.pos.x,y=s.pos.y);let x=this.getNode(d,y);if(x&&x.isClear()){t[e]=x,e=K(1,e-1);continue}}++e}}smoothPathStringPull(t){if(t.length<=2)return;for(let s of t)if(!s.isClear())return;let e=t.slice();t.length=0,t.push(e[0]);let i=0;for(let s=1;s0&&xe(o.posWorld,t[t.length-1].posWorld,U(0,0,1,.3),.02,this.debugTime);continue}for(;i=1;--e){let i=t[e-1],s=t[e],o=t[e+1];(s.pos.x-i.pos.x)*(o.pos.y-i.pos.y)===(s.pos.y-i.pos.y)*(o.pos.x-i.pos.x)&&t.splice(e,1)}}isNodeClear(t,e){let i=this.getNode(t,e);return i!==null&&i.isClear()}isLineClear(t,e){p(O(t)&&O(e),"isLineClear needs Vector2 endpoints"),p(this.isNodeClear(t.x,t.y)&&this.isNodeClear(e.x,e.y),"isLineClear endpoints must be in-bounds and clear");let i=e.x-t.x,s=e.y-t.y,o=nt(i),a=nt(s),r=te(i),c=te(s),l=t.x,u=t.y;if(a===o){for(;l!==e.x;){if(l!==t.x&&(!this.isNodeClear(l,u)||!this.isNodeClear(l,u-c))||!this.isNodeClear(l,u+c))return!1;l+=r,u+=c}if(!this.isNodeClear(e.x,e.y-c))return!1}else if(ar.posWorld.copy());if(this.debug&&this.debugTime>0&&a.length>0){for(let r=1;rpd,bootGameHost:()=>yd,default:()=>gd});var Mi=class{constructor(t){this._state=(t==null?2654435769:t)>>>0}next(){this._state=this._state+1831565813>>>0;let t=this._state;return t=Math.imul(t^t>>>15,t|1),t^=t+Math.imul(t^t>>>7,t|61),((t^t>>>14)>>>0)/4294967296}range(t,e){return t+this.next()*(e-t)}reseed(t){this._state=(t==null?2654435769:t)>>>0}},js=class{constructor(t){this._clock=t||Jc(),this._origin=this._clock()}nowMs(){return this._clock()}elapsedMs(){return this._clock()-this._origin}},Bs=class{constructor(t){this._time=t,this._subs=new Map}sourceFor(t){let e=this,i=t==null?null:t;return{on(s,o){if(e._assertType(s),typeof o!="function")throw new Error("[HostDevInputBridge] on \u7684 handler \u5FC5\u987B\u662F\u51FD\u6570");let a=e._subs.get(s)||[],r={handler:o,scope:i};return a.push(r),e._subs.set(s,a),{cancel(){let c=e._subs.get(s);if(!c)return;let l=c.indexOf(r);l>=0&&c.splice(l,1)}}},off(s,o){e._assertType(s);let a=e._subs.get(s);if(!a)return;let r=a.findIndex(c=>c.handler===o&&c.scope===i);r>=0&&a.splice(r,1)}}}_emit(t,e){this._assertType(t);let i=e||{},s={type:t,x:typeof i.x=="number"?i.x:0,y:typeof i.y=="number"?i.y:0,key:typeof i.key=="string"?i.key:"",tMs:this._time.nowMs()},o=this._subs.get(t);if(!o||o.length===0)return;let a=o.slice();for(let r of a)try{r.handler(s)}catch(c){ze("[host-dev input] \u8F93\u5165 handler \u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09type="+t,c)}}disposeScope(t){if(t==null)return 0;let e=0;for(let[i,s]of this._subs){let o=s.filter(a=>a.scope!==t);e+=s.length-o.length,o.length===0?this._subs.delete(i):this._subs.set(i,o)}return e}_subscriptionCount(){let t=0;for(let e of this._subs.values())t+=e.length;return t}_assertType(t){if(!Ns.has(t))throw new Error("[HostDevInputBridge] \u975E\u6CD5\u8F93\u5165\u4E8B\u4EF6\u7C7B\u578B\uFF1A"+String(t)+"\uFF08\u4EC5\u652F\u6301 "+Array.from(Ns).join("/")+"\uFF09")}},Ns=new Set(["pointerdown","pointermove","pointerup","keydown","keyup"]);function Wr(n){let t=n||{},e=new js(t.clock),i=new Mi(t.seed),s=t.seed==null?2654435769:t.seed>>>0,o=new Bs(e),a=typeof t.audioFactory=="function"?t.audioFactory:null,r=null,c=!1,l=typeof t.engineFactory=="function"?t.engineFactory:null,u=null,h=!1,f=new Map,d=0,y=0;function x(){if(r)return r;if(!a)return c||(Js("[host-dev audio] \u672A\u6CE8\u5165 audioFactory\uFF0CgetAudioContext \u8FD4\u56DE null\uFF08P6 \u987B\u5BB9\u9519\u964D\u7EA7\uFF1B\u96C6\u6210\u6BB5\u6CE8\u5165\u771F\u5B9E\u5DE5\u5382\uFF09"),c=!0),null;try{r=a()}catch(_){ze("[host-dev audio] audioFactory \u629B\u9519\uFF0CgetAudioContext \u964D\u7EA7\u8FD4\u56DE null",_),r=null}return r}function v(){if(u)return u;if(!l)return h||(Js("[host-dev engine] \u672A\u6CE8\u5165 engineFactory\uFF0CgetEngine \u8FD4\u56DE null\uFF08\u63D2\u4EF6\u987B\u5BB9\u9519\u964D\u7EA7\uFF1A\u7C92\u5B50\u9000\u53D7\u63A7\u9762\u81EA\u7BA1/\u5408\u6210\u6838\u9000 vendored/\u6570\u5B66\u9000\u5185\u7F6E\uFF1B\u96C6\u6210\u6BB5\u6CE8\u5165\u771F\u5B9E\u80CC\u4E66\uFF09"),h=!0),null;try{u=l()}catch(_){ze("[host-dev engine] engineFactory \u629B\u9519\uFF0CgetEngine \u964D\u7EA7\u8FD4\u56DE null",_),u=null}return u}function w(_,A){return{getContext2d(){return t.context2d==null?null:t.context2d},onFrame(L){let F=d++;return f.set(F,L),{cancel(){f.delete(F)}}},getInput(){return o.sourceFor(_)},getAudioContext(){return x()},getEngine(){return v()},time:e,random:A}}let C=w(null,i),S={context:C,tick(_){y+=1;let A=Array.from(f.values());for(let T of A)try{T(_,y)}catch(L){ze("[host-dev tick] \u5E27\u56DE\u8C03\u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09frame="+y,L)}},frameCount(){return y},inputBridge:o,deriveContextFor(_,A){let T=zc(s,_),L=new Mi(T);return w(A==null?_:A,L)}};return Object.defineProperty(C,zs,{value:S,enumerable:!1,writable:!1,configurable:!1}),S}var zs=Symbol("zaomeng.coreProtocol.contextBundle"),Ii=class{constructor(){this._plugins=new Map,this._initOrder=[],this._initErrors=[],this._phase="idle",this._disposed=!1,this._context=void 0,this._pluginContexts=new Map}register(t){if(!t||typeof t!="object")throw new Error("[PluginRegistry] register \u9700\u8981\u4E00\u4E2A\u63D2\u4EF6\u5BF9\u8C61");if(typeof t.name!="string"||t.name.length===0)throw new Error("[PluginRegistry] \u63D2\u4EF6\u7F3A\u5C11\u5408\u6CD5 name");if(typeof t.version!="string"||t.version.length===0)throw new Error("[PluginRegistry] \u63D2\u4EF6 "+t.name+" \u7F3A\u5C11\u5408\u6CD5 version");if(typeof t.init!="function")throw new Error("[PluginRegistry] \u63D2\u4EF6 "+t.name+" \u7F3A\u5C11 init \u51FD\u6570");if(t.dispose!=null&&typeof t.dispose!="function")throw new Error("[PluginRegistry] \u63D2\u4EF6 "+t.name+" \u7684 dispose \u5FC5\u987B\u662F\u51FD\u6570\u6216\u7701\u7565");if(this._plugins.has(t.name))throw new Error("[PluginRegistry] \u63D2\u4EF6\u91CD\u540D\u62D2\u7EDD\uFF1A"+t.name+" \u5DF2\u6CE8\u518C");return this._plugins.set(t.name,t),this}has(t){return this._plugins.has(t)}get(t){return this._plugins.get(t)}list(){return Array.from(this._plugins.keys())}initAll(){if(this._phase==="initialized")return Js("[PluginRegistry] initAll \u91CD\u590D\u8C03\u7528\uFF0C\u5DF2\u5FFD\u7565\uFF08\u5DF2\u5904\u4E8E initialized\uFF09"),this._initResult();if(this._phase==="disposed")throw new Error("[PluginRegistry] \u5DF2 dispose \u7684\u6CE8\u518C\u5668\u4E0D\u53EF\u518D initAll");if(this._context==null)throw new Error("[PluginRegistry] \u672A\u6CE8\u5165\u53D7\u63A7\u4E0A\u4E0B\u6587\uFF1A\u8BF7\u5728 initAll() \u4E4B\u524D\u8C03\u7528 useContext(context)\u3002\uFF08host-dev \u7528\u6CD5\uFF1Aconst { context } = createHostDevContext(); reg.useContext(context); reg.initAll();\uFF09");for(let[t,e]of this._plugins){let i=this._missingDeps(e);if(i.length>0){let o=new Error("[PluginRegistry] \u63D2\u4EF6 "+t+" \u4F9D\u8D56\u7F3A\u5931\uFF1A"+i.join(", ")+"\uFF08\u672A\u6CE8\u518C\uFF09");this._initErrors.push({name:t,error:o}),ze("[PluginRegistry] \u8DF3\u8FC7 init\uFF08\u4F9D\u8D56\u7F3A\u5931\uFF0C\u5DF2\u9694\u79BB\uFF09\uFF1A"+t,o);continue}let s=this._contextFor(t);try{e.init(s),this._initOrder.push(t)}catch(o){let a=o instanceof Error?o:new Error(String(o));this._initErrors.push({name:t,error:a}),ze("[PluginRegistry] \u63D2\u4EF6 init \u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF0C\u4E0D\u8FDE\u5750\uFF09\uFF1A"+t,a)}}return this._phase="initialized",this._initResult()}_contextFor(t){let e=this._pluginContexts.get(t);if(e)return e;let i=this._context&&this._context[zs],s;return i&&typeof i.deriveContextFor=="function"?s=i.deriveContextFor(t,t):s=this._context,this._pluginContexts.set(t,s),s}disposeAll(){if(this._disposed)return{disposed:[],errors:[]};let t=[],e=[],i=this._context&&this._context[zs],s=i&&i.inputBridge;for(let o=this._initOrder.length-1;o>=0;o--){let a=this._initOrder[o],r=this._plugins.get(a);if(r&&typeof r.dispose=="function")try{r.dispose(),t.push(a)}catch(c){let l=c instanceof Error?c:new Error(String(c));e.push({name:a,error:l}),ze("[PluginRegistry] \u63D2\u4EF6 dispose \u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09\uFF1A"+a,l)}if(s&&typeof s.disposeScope=="function")try{s.disposeScope(a)}catch(c){ze("[PluginRegistry] \u56DE\u6536\u63D2\u4EF6\u8F93\u5165\u8BA2\u9605\u629B\u9519\uFF08\u5DF2\u9694\u79BB\uFF09\uFF1A"+a,c)}}return this._disposed=!0,this._phase="disposed",{disposed:t,errors:e}}useContext(t){if(this._phase!=="idle")throw new Error("[PluginRegistry] useContext \u5FC5\u987B\u5728 initAll() \u4E4B\u524D\u8C03\u7528\uFF08\u5F53\u524D\u9636\u6BB5\uFF1A"+this._phase+"\uFF09\u3002\u8BF7\u5728\u4EFB\u4F55 initAll/disposeAll \u4E4B\u524D\u6CE8\u5165\u53D7\u63A7\u4E0A\u4E0B\u6587\u3002");if(t==null||typeof t!="object")throw new Error("[PluginRegistry] useContext \u9700\u8981\u4E00\u4E2A\u53D7\u63A7\u4E0A\u4E0B\u6587\u5BF9\u8C61\u3002\uFF08host-dev \u7528\u6CD5\uFF1Aconst { context } = createHostDevContext(); reg.useContext(context);\uFF09");return this._context=t,this}_missingDeps(t){return!Array.isArray(t.dependencies)||t.dependencies.length===0?[]:t.dependencies.filter(e=>!this._plugins.has(e))}_initResult(){return{ok:this._initErrors.length===0,initialized:this._initOrder.slice(),errors:this._initErrors.slice()}}};function zc(n,t){let e=2166136261,i=16777619,s=n>>>0;for(let a=0;a<32;a+=8){let r=s>>>a&255;e^=r,e=Math.imul(e,i)>>>0}let o=String(t);for(let a=0;a>>0,e^=r>>>8&255,e=Math.imul(e,i)>>>0}return e>>>0}function Jc(){if(typeof globalThis!="undefined"&&globalThis.performance&&typeof globalThis.performance.now=="function")return()=>globalThis.performance.now();if(typeof process!="undefined"&&process.hrtime&&typeof process.hrtime.bigint=="function"){let n=process.hrtime.bigint();return()=>Number(process.hrtime.bigint()-n)/1e6}return()=>Date.now()}function ze(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function Js(n){typeof console!="undefined"&&typeof console.warn=="function"&&console.warn(n)}var xd=Object.freeze(Array.from(Ns)),qr="core-protocol-v0";var Hr=Object.freeze(["t_boot","t_plugins_ready","t_game_init","t_first_paint","t_input_bound","t_game_start"]),Us=Hr.reduce((n,t,e)=>(n[t]=e,n),Object.create(null)),Uc=new Set(Hr);function Vs(n){let t=2166136261;for(let e=0;e>>0).toString(16).padStart(8,"0")}var Xr=Vs("runtime-probe::seed::v1");function ki(n){return n===null||typeof n!="object"?JSON.stringify(n):Array.isArray(n)?"["+n.map(ki).join(",")+"]":"{"+Object.keys(n).sort().map(e=>JSON.stringify(e)+":"+ki(n[e])).join(",")+"}"}function Yr(n){let t=ki(n.extra==null?null:n.extra),e=ki(Array.isArray(n.pluginSet)?n.pluginSet:[]);return["seq="+n.seq,"anchor="+n.anchor,"tMono="+n.tMono,"buildSha="+(n.buildSha||""),"pluginSet="+e,"extra="+t].join("|")}function Vc(n){return Math.round(n*1e3)/1e3}function Wc(n){if(!Array.isArray(n))return{ok:!1,reason:"records_not_array"};let t=Xr,e=-1;for(let i=0;itypeof _=="string").slice().sort():[],s=typeof t.sink=="function"?t.sink:null,o=t.autoBoot!==!1,a=typeof t.inputAnchorType=="string"?t.inputAnchorType:"pointerdown",r=()=>0,c=!1,l=0,u=Xr,h=[],f=new Set,d=-1,y=null,x=!1,v=!1,w=!1;function C(_,A){let T=null;if(!Uc.has(_))T="unknown_anchor";else{f.has(_)&&(T=T?T+";duplicate_anchor":"duplicate_anchor");let F=Us[_];F_.time.nowMs(),c=!0,o&&!v&&C("t_boot",{auto:!0}),y=_.getInput().on(a,A=>{x||(x=!0,C("t_input_bound",{firstInput:!0,type:A.type}))}),C("t_input_bound",{stage:"registered",type:a})},dispose(){w||(y&&(y.cancel(),y=null),w=!0)},mark:C,getRecords(){return h.map(_=>({..._}))},toJSONL(){return h.map(_=>JSON.stringify(_)).join(`
+`)},verify(){return Wc(h)}}}function qc(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function Kr(n){let t=n.LJS,e=n.engineMath,i=n.engineMode,s=n.recHook||(()=>{});if(i!=="real")return null;let o=e;return{math:{lerp:(r,c,l)=>(s("math.lerp"),o.lerp(r,c,l)),smoothStep:r=>(s("math.smoothStep"),o.smoothStep(r)),easing:Object.fromEntries(Object.keys(o.easing).map(r=>[r,c=>(s("math.easing."+r),o.easing[r](c))]))},particles:{spawnEmitter(r){s("particles.spawnEmitter");let c=t.screenToWorld(t.vec2(r.pos.x,r.pos.y)),l=t.cameraScale,u=r.emitTime!=null?r.emitTime:r.count!=null?1/60:0,h=r.emitRate!=null?r.emitRate:r.count!=null?r.count*60:100,f=(r.speed!=null?r.speed:0)/l/60,d=r.damping!=null?r.damping:1,y=r.colorStart||{r:1,g:1,b:1,a:1},x=r.colorEnd||{r:1,g:1,b:1,a:0},v=t.rgb(y.r,y.g,y.b,y.a),w=t.rgb(x.r,x.g,x.b,x.a),C=new t.ParticleEmitter(c,r.angle!=null?r.angle:0,(r.emitSize!=null?r.emitSize:0)/l,u,h,r.coneAngle!=null?r.coneAngle:Math.PI,void 0,v,v,w,w,r.particleTime!=null?r.particleTime:.5,(r.sizeStart!=null?r.sizeStart:6)/l,(r.sizeEnd!=null?r.sizeEnd:0)/l,f,0,d,1,r.gravityScale!=null?r.gravityScale:0,Math.PI,.1,0,!1,r.additive!=null?r.additive:!1,!0);return{isActive(){return C.isActive()},stop(){C.destroyed||C.destroy(!0)}}}},audio:{synth:{synthSfx:r=>{s("audio.synth.synthSfx");try{return t.zzfxG(...r)}catch(c){return console.error("[host][engine-audio] zzfxG \u5408\u6210\u5F02\u5E38\uFF0C\u8FD4 null\uFF1A"+(c&&c.message?c.message:c)),null}},synthSong:(r,c,l,u)=>{s("audio.synth.synthSong");try{return t.zzfxM(r,c,l,u)}catch(h){return console.error("[host][engine-audio] zzfxM \u5408\u6210\u5F02\u5E38\uFF0C\u8FD4 null\uFF1A"+(h&&h.message?h.message:h)),null}}}}}}function re(n){return n<0?0:n>1?1:n}function Qr(n){let t=n.Ease,e=t.POWER(2),i=t.POWER(3),s=t.OUT(e),o=t.IN_OUT(e),a=t.OUT(i),r=t.IN_OUT(i),c=t.OUT(t.BACK),l=t.OUT(t.ELASTIC);return{lerp:(u,h,f)=>n.lerp(u,h,f),smoothStep:u=>n.smoothStep(u),easing:{linear:u=>t.LINEAR(re(u)),quadIn:u=>e(re(u)),quadOut:u=>s(re(u)),quadInOut:u=>o(re(u)),cubicIn:u=>i(re(u)),cubicOut:u=>a(re(u)),cubicInOut:u=>r(re(u)),backIn:u=>t.BACK(re(u)),backOut:u=>c(re(u)),elasticIn:u=>t.ELASTIC(re(u)),elasticOut:u=>l(re(u))}}}var Je=2,Gi=1/60;async function Zr(n){let t=n.canvas,e=n.statusEl||null,i=n.engine,s=n.seed>>>0,o=n.mode||"play",a=n.engineMode||"real",r=n.viewport.w,c=n.viewport.h,l=n.factory,u=n.buildFactoryOpts||(()=>{}),h=n.plugins||{},f=n.registerOrder||Object.values(h),d=n.onReady||(()=>{}),y=n.recHook||(()=>{});function x(M){e&&(e.textContent=M)}let v=[];window.addEventListener("error",M=>v.push({type:"error",message:String(M&&M.message||M)})),window.addEventListener("unhandledrejection",M=>v.push({type:"unhandledrejection",message:String(M&&M.reason&&M.reason.message||M&&M.reason||M)}));let w=null,C=!1;function S(){if(!C)return null;if(w)return w;let M=window.AudioContext||window.webkitAudioContext;return M?(w=new M,w):null}let _=0,A=null,T=null,L=null,F=null,ft=[],D={},I=null;function k(M,ot){try{L&&L.mark(M,ot)}catch(Zt){v.push({type:"mark",message:String(Zt&&Zt.message||Zt)})}}function R(){T&&typeof T._refreshChecklist=="function"&&T._refreshChecklist(D)}async function ct(M,ot){A=Wr({context2d:M,seed:s,audioFactory:S,clock:()=>_,engineFactory:()=>Kr({LJS:a==="real"?i:null,engineMath:a==="real"?Qr(i):null,engineMode:a,recHook:y})});let Zt=new Ii;for(let fe of f)Zt.register(fe);Zt.useContext(A.context),F=Zt.initAll(),ft=Zt.list().concat(["runtime-probe"]),L=$r({pluginSet:ft,inputAnchorType:"pointerdown",autoBoot:!0});let Lt=A.deriveContextFor("runtime-probe","runtime-probe");k("t_boot",{by:"game-host",stage:"pre-init",engineMode:a}),k("t_plugins_ready",{initialized:F.initialized.length,ok:F.ok});let Gs=u(A.context,{bundle:A,plugins:h,getRealAudioCtx:()=>w});T=l(Gs),await T.init({ctx:A.context,mainContext:M,canvas:ot(),seed:s}),I=T&&typeof T._forensicsView=="function"?T._forensicsView():null,k("t_game_init",{hasForensics:!!I}),tt(),k("t_first_paint",{frame:A.frameCount()});try{L.init(Lt)}catch(fe){v.push({type:"probe-init",message:String(fe&&fe.message||fe)})}k("t_game_start",{mode:o,engineMode:a}),R(),d(Ht,{bundle:A,game:T,probe:L,checklist:D,uncaught:v,pluginSet:ft,initRes:F,getGameForensics:()=>I,mark:k,stepOneFrame:tt})}let j=null;function tt(M){let ot=typeof M=="number"?M:Gi;T&&(_+=ot*1e3,T.update(ot),a==="stub"&&j&&T.render(j),R())}function ut(M){for(let ot=0;ot{}),T&&typeof T._onAudioUnlock=="function"&&T._onAudioUnlock()}let Ht={seed:s,mode:o,engineMode:a,protocol:qr,frameCount:()=>A?A.frameCount():0,stepFrames:ut,startRaf:()=>on(),stopRaf:()=>rn(),tap(M,ot){xt(),A&&(A.inputBridge._emit("pointerdown",{x:M,y:ot}),A.inputBridge._emit("pointerup",{x:M,y:ot}))},do(M){T&&typeof T._handleAction=="function"&&T._handleAction(M)},state:()=>I?I.state():{phase:"booting"}};function At(M){let ot=A.inputBridge;function Zt(Lt,Gs){let fe=M.getBoundingClientRect();return{x:(Lt-fe.left)/fe.width*r,y:(Gs-fe.top)/fe.height*c}}M.addEventListener("pointerdown",Lt=>{xt(),ot._emit("pointerdown",Zt(Lt.clientX,Lt.clientY))}),M.addEventListener("pointermove",Lt=>{ot._emit("pointermove",Zt(Lt.clientX,Lt.clientY))}),M.addEventListener("pointerup",Lt=>{ot._emit("pointerup",Zt(Lt.clientX,Lt.clientY))}),window.addEventListener("keydown",Lt=>{xt(),ot._emit("keydown",{key:Lt.key})}),window.addEventListener("keyup",Lt=>ot._emit("keyup",{key:Lt.key}))}let Pt=0,gt=!1,yt=0;function oe(M){if(!gt)return;yt===0&&(yt=M);let ot=(M-yt)/1e3;yt=M,ot>.05&&(ot=.05),tt(ot),Pt=window.requestAnimationFrame(oe)}function on(){a==="stub"&&(gt||(gt=!0,yt=0,Pt=window.requestAnimationFrame(oe)))}function rn(){gt=!1,Pt&&window.cancelAnimationFrame(Pt),Pt=0}function Mt(M){M.width=r*Je,M.height=c*Je,M.style.width=r+"px",M.style.height=c+"px";let ot=M.getContext("2d",{willReadFrequently:!0});return ot.setTransform(Je,0,0,Je,0,0),ot}async function Ne(){let M=Mt(t);return j=M,await ct(M,()=>t),At(t),o==="evidence"?x(`evidence \u5C31\u7EEA seed=${s} \xB7 \u7528 host \u9A71\u52A8\uFF08stepFrames/tap\uFF09`):(x(`seed=${s} \xB7 \u70B9\u5F00\u59CB\uFF08\u9996\u6B21\u70B9\u51FB\u5F00\u58F0\uFF09`),on()),Ht}let qn=()=>{},Hn=()=>{};function Oi(){window.__gameHostEngineInitFired=!0}function Di(){qn()}function Ur(){}function Dc(){Hn()}function Mc(){}async function Ic(M){await ct(M,()=>i.mainCanvas),At(i.mainCanvas),qn=()=>{T&&(_+=Gi*1e3,T.update(Gi))},Hn=()=>{if(T){M.save(),M.setTransform(Je,0,0,Je,0,0);try{M.imageSmoothingEnabled=!1}catch{}T.render(M),M.restore()}},i.mainCanvas&&(i.mainCanvas.id="game-engine"),window.__engine={frame(){return i.frame},time(){return i.time},timeReal(){return i.timeReal},paused(){return i.paused},timeScale(){return i.timeScale},snapshot(){return{frame:i.frame,time:i.time,timeReal:i.timeReal,paused:i.paused,timeScale:i.timeScale}}},x(`engine RAF running \xB7 seed=${s} engine=real`)}if(a!=="real")return await Ne();if(!i){let M="real \u901A\u9053\u672A\u6CE8\u5165\u5F15\u64CE\uFF08opts.engine \u7F3A\u5931\uFF09\uFF1A\u8BF7\u7ECF entry \u5305\u88C5\u5C42\u542F\u52A8\uFF08host \u4E0D\u76F4\u63A5 import \u5F15\u64CE\uFF0CQ4/Option C\uFF09";throw x("ENGINE INJECT MISSING: "+M),new Error(M)}i.setGLEnable(!1),i.setShowSplashScreen(!1),i.setDebugWatermark(!1),i.setCanvasClearColor(i.BLACK),i.setCanvasFixedSize(i.vec2(r*Je,c*Je));let ks=document.createElement("div");return ks.id="engine-root",document.body.appendChild(ks),await i.engineInit(Oi,Di,Ur,Dc,Mc,[],ks).then(()=>Ic(i.mainContext)).catch(M=>{throw window.__gameHostBootError=String(M&&M.message||M),x("ENGINE INIT FAILED: "+window.__gameHostBootError),M}),Ht}var Ws=class{constructor(t){let e=t||{},i=typeof e.cellSize=="number"&&e.cellSize>0?e.cellSize:64;this._cellSize=i,this._cells=new Map,this._entries=new Map,this._seq=0}get size(){return this._entries.size}_cellRange(t){let e=this._cellSize,i=Math.floor((t.x-t.hw)/e),s=Math.floor((t.x+t.hw)/e),o=Math.floor((t.y-t.hh)/e),a=Math.floor((t.y+t.hh)/e);return{cx0:i,cy0:o,cx1:s,cy1:a}}insert(t,e){this._entries.has(t)&&this.remove(t);let{cx0:i,cy0:s,cx1:o,cy1:a}=this._cellRange(e),r=[];for(let l=s;l<=a;l++)for(let u=i;u<=o;u++){let h=u+","+l,f=this._cells.get(h);f||(f=new Set,this._cells.set(h,f)),f.add(t),r.push(h)}let c={x:e.x,y:e.y,hw:e.hw,hh:e.hh};this._entries.set(t,{id:t,box:c,seq:this._seq++,cells:r})}remove(t){let e=this._entries.get(t);if(!e)return!1;for(let i of e.cells){let s=this._cells.get(i);s&&(s.delete(t),s.size===0&&this._cells.delete(i))}return this._entries.delete(t),!0}query(t){let{cx0:e,cy0:i,cx1:s,cy1:o}=this._cellRange(t),a=new Set;for(let r=i;r<=o;r++)for(let c=e;c<=s;c++){let l=this._cells.get(c+","+r);if(l)for(let u of l)a.add(u)}return this._collect(a)}queryPoint(t,e){let i=this._cellSize,s=Math.floor(t/i),o=Math.floor(e/i),a=this._cells.get(s+","+o);return a?this._collect(new Set(a)):[]}clear(){this._cells.clear(),this._entries.clear(),this._seq=0}_collect(t){let e=[];for(let i of t){let s=this._entries.get(i);s&&e.push(s)}return e.sort((i,s)=>i.seq-s.seq),e.map(i=>({id:i.id,box:i.box}))}};function ta(n){let t=n||{},e=new Ws({cellSize:t.cellSize}),i=!1;return{name:"collision",version:"1.0.0",dependencies:[],spatial:e,init(o){},dispose(){i||(e.clear(),i=!0)}}}function ea(n){let t=!1;return{name:"physics-lite",version:"1.0.0",dependencies:[],init(i){},dispose(){t||(t=!0)}}}var Hc=["pointerdown","pointermove","pointerup","keydown","keyup"];function Bt(n){return n<0?0:n>1?1:n}var Xc=n=>(n=Bt(n),n*n),Yc=n=>(n=Bt(n),1-(1-n)*(1-n)),$c=n=>(n=Bt(n),n<.5?2*n*n:1-Math.pow(-2*n+2,2)/2),Kc=n=>(n=Bt(n),n*n*n),Qc=n=>{n=Bt(n);let t=1-n;return 1-t*t*t},Zc=n=>(n=Bt(n),n<.5?4*n*n*n:1-Math.pow(-2*n+2,3)/2),sa=2*Math.PI/3,na=2*Math.PI/4.5,tl=n=>(n=Bt(n),n===0?0:n===1?1:-Math.pow(2,10*n-10)*Math.sin((n*10-10.75)*sa)),el=n=>(n=Bt(n),n===0?0:n===1?1:Math.pow(2,-10*n)*Math.sin((n*10-.75)*sa)+1),nl=n=>(n=Bt(n),n===0?0:n===1?1:n<.5?-(Math.pow(2,20*n-10)*Math.sin((20*n-11.125)*na))/2:Math.pow(2,-20*n+10)*Math.sin((20*n-11.125)*na)/2+1),ji=1.70158,Fi=ji*1.525,oa=ji+1,il=n=>(n=Bt(n),oa*n*n*n-ji*n*n),sl=n=>{n=Bt(n);let t=n-1;return 1+oa*t*t*t+ji*t*t},ol=n=>(n=Bt(n),n<.5?Math.pow(2*n,2)*((Fi+1)*2*n-Fi)/2:(Math.pow(2*n-2,2)*((Fi+1)*(n*2-2)+Fi)+2)/2),rl=n=>Bt(n),ia=Object.freeze({linear:rl,quadIn:Xc,quadOut:Yc,quadInOut:$c,cubicIn:Kc,cubicOut:Qc,cubicInOut:Zc,elasticIn:tl,elasticOut:el,elasticInOut:nl,backIn:il,backOut:sl,backInOut:ol});var al=["linear","quadIn","quadOut","quadInOut","cubicIn","cubicOut","cubicInOut","elasticIn","elasticOut","elasticInOut","backIn","backOut","backInOut"];function cl(n){let t=n&&n.easing;if(!t)return ia;let e=s=>typeof t[s]=="function"?o=>t[s](Bt(o)):ia[s],i={};for(let s of al)i[s]=e(s);return Object.freeze(i)}var qs=class{constructor(t,e,i){let s=i||{};this._time=e,this._windowMs=typeof s.windowMs=="number"&&s.windowMs>0?s.windowMs:120;let o=Array.isArray(s.types)&&s.types.length>0?s.types:Hc;this._records=new Map,this._subs=[],this._disposed=!1;for(let a of o){this._records.set(a,null);let r=t.on(a,c=>{this._records.set(a,c.tMs)});this._subs.push(r)}}consume(t,e){let i=typeof e=="number"?e:this._time.nowMs(),s=this._records.get(t);return s==null?!1:i-s<=this._windowMs?(this._records.set(t,null),!0):(this._records.set(t,null),!1)}peek(t,e){let i=typeof e=="number"?e:this._time.nowMs(),s=this._records.get(t);return s==null?!1:i-s<=this._windowMs}clear(){for(let t of this._records.keys())this._records.set(t,null)}dispose(){if(!this._disposed){for(let t of this._subs)try{t.cancel()}catch(e){}this._subs=[],this._disposed=!0}}};function ra(n){let t=n||{},e=null,i=null,s=!1;return{name:"gamefeel",version:"1.0.0",dependencies:[],get inputBuffer(){return e},get easing(){return cl(i)},init(a){let r=a.getInput();e=new qs(r,a.time,{windowMs:t.inputBufferMs,types:t.inputTypes});let c=a.getEngine();i=c?c.math:null},dispose(){s||(e&&(e.dispose(),e=null),i=null,s=!0)}}}function Bi(n,t){let e=t<0?0:t>1?1:t;switch(n&&n.kind){case"constant":return n.value;case"linear":return n.from+(n.to-n.from)*e;case"easeInOut":{let i=e*e*(3-2*e);return n.from+(n.to-n.from)*i}case"decay":{let i=n.power==null?2:n.power,s=Math.pow(1-e,i);return n.to+(n.from-n.to)*s}default:return 0}}var ll=Object.freeze({burst:Object.freeze({mode:"burst",count:24,angle:0,spread:Math.PI,speedMin:80,speedMax:160,lifeMin:.4,lifeMax:.8,gravity:0,drag:0,sizeCurve:{kind:"decay",from:6,to:0,power:1.5},alphaCurve:{kind:"linear",from:1,to:0}}),trail:Object.freeze({mode:"continuous",rate:60,angle:Math.PI,spread:.25,speedMin:20,speedMax:50,lifeMin:.2,lifeMax:.5,gravity:0,drag:1.5,sizeCurve:{kind:"easeInOut",from:4,to:0},alphaCurve:{kind:"decay",from:.8,to:0,power:2}}),drift:Object.freeze({mode:"continuous",rate:12,angle:Math.PI/2,spread:.6,speedMin:10,speedMax:30,lifeMin:1.5,lifeMax:3,gravity:8,drag:.5,sizeCurve:{kind:"constant",value:3},alphaCurve:{kind:"decay",from:.7,to:0,power:1}})});function ul(n){let t=ll[n];return t?Hs(t):null}function Hs(n){let t={};for(let e of Object.keys(n)){let i=n[e];t[e]=i&&typeof i=="object"?Hs(i):i}return t}function hl(n,t,e){let i=n.mode==="continuous";return{pos:{x:t,y:e},angle:n.angle,coneAngle:n.spread,emitSize:0,emitTime:i?0:1/60,emitRate:i?n.rate||0:void 0,count:i?void 0:n.count||0,particleTime:(n.lifeMin+n.lifeMax)/2,speed:(n.speedMin+n.speedMax)/2,gravityScale:n.gravity||0,damping:n.drag!=null?1-n.drag/60:1,sizeStart:Bi(n.sizeCurve,0),sizeEnd:Bi(n.sizeCurve,1),colorStart:{r:1,g:1,b:1,a:Bi(n.alphaCurve,0)},colorEnd:{r:1,g:1,b:1,a:Bi(n.alphaCurve,1)},additive:!1}}function aa(n){let t=n||{},e=null,i=null,s=null,o=new Map,a=0,r={isActive(){return!1},stop(){}},c=0,l=1,u=0,h=0,f=0,d={x:0,y:0,remain:0,dur:0,amplitude:0,frequency:0,_phase:0},y={alpha:0,remain:0,dur:0,peak:0},x={scale:1,remain:0,dur:0,amplitude:0,frequency:0},v=!1;function w(A){if(u>0)if(u-=A,u<=0)u=0,l=1;else{let T=h>0?1-u/h:1;l=f+(1-f)*T}if(d.remain>0)if(d.remain-=A,d.remain<=0)d.remain=0,d.x=0,d.y=0;else{let T=d.remain/d.dur,L=d.amplitude*T;d._phase+=d.frequency*A*Math.PI*2,d.x=Math.sin(d._phase)*L,d.y=Math.cos(d._phase*1.3)*L}if(y.remain>0&&(y.remain-=A,y.remain<=0?(y.remain=0,y.alpha=0):y.alpha=y.peak*(y.remain/y.dur)),x.remain>0)if(x.remain-=A,x.remain<=0)x.remain=0,x.scale=1;else{let T=x.remain/x.dur,L=(1-T)*x.frequency*Math.PI*2;x.scale=1+Math.sin(L)*x.amplitude*T}}function C(A){c+=1,w(A)}function S(A){let T=A!==void 0?A:e?e.getContext2d():null;if(T&&y.alpha>0){T.globalAlpha=y.alpha,T.fillStyle="#ffffff";let L=T.canvas?T.canvas.width:0,F=T.canvas?T.canvas.height:0;T.fillRect(0,0,L,F),T.globalAlpha=1}}return{name:"particles-juice",version:"1.0.0",dependencies:[],init(A){var T;e=A,s=((T=A.getEngine())==null?void 0:T.particles)||null,typeof t.seed=="number"&&A.random.reseed(t.seed),t.autoStep!==!1&&(i=A.onFrame(L=>{C(L)}))},dispose(){v||(i&&(i.cancel(),i=null),o.forEach(A=>{try{A.stop()}catch{}}),o.clear(),l=1,u=0,d.remain=0,d.x=0,d.y=0,y.remain=0,y.alpha=0,x.remain=0,x.scale=1,v=!0)},spawnEmitter(A,T,L,F){let ft=typeof A=="string"?ul(A):Hs(A);if(!ft)return-1;F&&(ft=Object.assign(ft,F));let D=a++;if(!s)return o.set(D,r),D;let I=s.spawnEmitter(hl(ft,T,L));return o.set(D,I),D},stopEmitter(A){let T=o.get(A);if(T)try{T.stop()}catch{}},step(A){C(A)},render(A){S(A)},particleCount(){return 0},emitterCount(){let A=0;for(let T of o.values())T.isActive()&&(A+=1);return A},hitStop(A,T){h=Math.max(0,A),u=h,f=T==null?0:Math.max(0,Math.min(1,T)),l=h>0?f:1},getTimeScale(){return l},shakeScreen(A,T,L){d.dur=Math.max(0,A),d.remain=d.dur,d.amplitude=Math.max(0,T),d.frequency=L==null?30:L,d._phase=0,d.x=0,d.y=0},getShakeOffset(){return{x:d.x,y:d.y}},flashScreen(A,T){y.dur=Math.max(0,A),y.remain=y.dur,y.peak=T==null?.8:Math.max(0,Math.min(1,T)),y.alpha=y.dur>0?y.peak:0},getFlashAlpha(){return y.alpha},pulseScale(A,T,L){x.dur=Math.max(0,A),x.remain=x.dur,x.amplitude=T==null?.2:T,x.frequency=L==null?4:L,x.scale=1},getPulseScale(){return x.scale},juiceSnapshot(){return{timeScale:l,shake:{x:d.x,y:d.y},flashAlpha:y.alpha,pulseScale:x.scale}},probe(){return{particles:0,emitters:o.size,dropped:0,steps:c,disposed:v}}}}function ca(n){let t=pt(n.r)/255,e=pt(n.g)/255,i=pt(n.b)/255,s=Math.max(t,e,i),o=Math.min(t,e,i),a=(s+o)/2,r=0,c=0,l=s-o;return l>1e-12&&(c=a>.5?l/(2-s-o):l/(s+o),s===t?r=(e-i)/l%6:s===e?r=(i-t)/l+2:r=(t-e)/l+4,r*=60,r<0&&(r+=360)),{h:r,s:c,l:a}}function la(n){let t=(n.h%360+360)%360,e=Ue(n.s),i=Ue(n.l);if(e<1e-12){let r=Math.round(i*255);return{r,g:r,b:r}}let s=i<.5?i*(1+e):i+e-i*e,o=2*i-s,a=t/360;return{r:Math.round(Xs(o,s,a+1/3)*255),g:Math.round(Xs(o,s,a)*255),b:Math.round(Xs(o,s,a-1/3)*255)}}function Xs(n,t,e){let i=e;return i<0&&(i+=1),i>1&&(i-=1),i<1/6?n+(t-n)*6*i:i<1/2?t:i<2/3?n+(t-n)*(2/3-i)*6:n}function pt(n){return n<0?0:n>255?255:n}function Ue(n){return n<0?0:n>1?1:n}function dl(n,t){let e=pl(n.from,t);if(e>=0&&e({r:pt(r.r),g:pt(r.g),b:pt(r.b)})),to:o}}function Ys(n,t,e){return n+(t-n)*e}function ml(n,t){let e=ca(n),i=e.h+(t.hue||0),s=Ue(e.s*(t.sat==null?1:t.sat)),o=Ue(e.l*(t.light==null?1:t.light));return la({h:i,s,l:o})}var bl=Object.freeze([Object.freeze([0,8,2,10]),Object.freeze([12,4,14,6]),Object.freeze([3,11,1,9]),Object.freeze([15,7,13,5])]);function ua(n){let t=n||{},e=null,i=!1,s={vignette:{enabled:$s(t.vignette&&t.vignette.enabled,!1),strength:Ks(t.vignette&&t.vignette.strength,.5)},dither:{enabled:$s(t.dither&&t.dither.enabled,!1),strength:Ks(t.dither&&t.dither.strength,.5)},scanline:{enabled:$s(t.scanline&&t.scanline.enabled,!1),strength:Ks(t.scanline&&t.scanline.strength,.5)}};function o(r){let c=r!==void 0?r:e?e.getContext2d():null;if(!c)return;let l=c.canvas?c.canvas.width:0,u=c.canvas?c.canvas.height:0;if(s.vignette.enabled&&s.vignette.strength>0&&l>0&&u>0){let h=c.createRadialGradient(l/2,u/2,Math.min(l,u)*.25,l/2,u/2,Math.max(l,u)*.75);h.addColorStop(0,"rgba(0,0,0,0)"),h.addColorStop(1,"rgba(0,0,0,"+s.vignette.strength.toFixed(3)+")"),c.fillStyle=h,c.fillRect(0,0,l,u)}if(s.scanline.enabled&&s.scanline.strength>0&&l>0&&u>0){c.fillStyle="rgba(0,0,0,"+(s.scanline.strength*.5).toFixed(3)+")";for(let h=0;h0&&l>0&&u>0&&typeof c.getImageData=="function"&&typeof c.putImageData=="function"){let h=c.getImageData(0,0,l,u);xl(h,s.dither.strength),c.putImageData(h,0,0)}}return{name:"palette-post",version:"1.0.0",dependencies:[],init(r){e=r},dispose(){i||(e=null,i=!0)},applyPaletteMap(r,c){return dl(r,c)},applyPaletteMapToBuffer(r,c){return fl(r,c)},lerpPaletteMap(r,c,l){return yl(r,c,l)},shiftHsl(r,c){return ml(r,c)},rgbToHsl(r){return ca(r)},hslToRgb(r){return la(r)},setPost(r){if(r)for(let c of["vignette","dither","scanline"])r[c]&&(typeof r[c].enabled=="boolean"&&(s[c].enabled=r[c].enabled),typeof r[c].strength=="number"&&(s[c].strength=Ue(r[c].strength)))},getPost(){return{vignette:{enabled:s.vignette.enabled,strength:s.vignette.strength},dither:{enabled:s.dither.enabled,strength:s.dither.strength},scanline:{enabled:s.scanline.enabled,strength:s.scanline.strength}}},renderPost(r){o(r)},probe(){return{disposed:i,post:this.getPost()}}}}function xl(n,t){let e=Ue(t);if(e<=0)return n;let{data:i,width:s}=n,a=255/(Math.max(2,Math.round(16-e*14))-1);for(let r=0;r+3>2)%s,l=Math.floor((r>>2)/s),u=(bl[l&3][c&3]/16-.5)*a;for(let h=0;h<3;h++){let f=i[r+h]+u,d=Math.round(f/a)*a;i[r+h]=d<0?0:d>255?255:d}}return n}function $s(n,t){return typeof n=="boolean"?n:t}function Ks(n,t){return typeof n=="number"?Ue(n):t}var Zs=Object.freeze({blip:Object.freeze({name:"blip",params:Object.freeze([.6,0,880,0,.03,.06,1,1.5])}),thud:Object.freeze({name:"thud",params:Object.freeze([.8,0,90,0,.04,.18,0,1,0,0,0,0,0,4])}),chime:Object.freeze({name:"chime",params:Object.freeze([.5,0,660,.02,.12,.3,1,2])})}),ha=Object.keys(Zs);function vl(n){let t=[];return n==null||typeof n!="object"?{ok:!1,errors:["song \u5FC5\u987B\u662F\u5BF9\u8C61"]}:(!Array.isArray(n.instruments)||n.instruments.length===0?t.push("instruments \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4"):n.instruments.forEach((e,i)=>{(!Array.isArray(e)||e.some(s=>typeof s!="number"||!Number.isFinite(s)))&&t.push(`instruments[${i}] \u5FC5\u987B\u662F\u6709\u9650\u6570\u5B57\u6570\u7EC4\uFF08ZzFX \u53C2\u6570\u5305\uFF09`)}),!Array.isArray(n.patterns)||n.patterns.length===0?t.push("patterns \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4"):n.patterns.forEach((e,i)=>{if(!Array.isArray(e)||e.length===0){t.push(`patterns[${i}] \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4\uFF08\u81F3\u5C11\u4E00\u4E2A\u58F0\u90E8\u901A\u9053\uFF09`);return}e.forEach((s,o)=>{if(!Array.isArray(s)||s.length<2){t.push(`patterns[${i}][${o}] \u901A\u9053\u81F3\u5C11\u542B [\u4E50\u5668\u7D22\u5F15, \u58F0\u50CF]`);return}if(s.some(c=>typeof c!="number"||!Number.isFinite(c))){t.push(`patterns[${i}][${o}] \u901A\u9053\u5FC5\u987B\u5168\u4E3A\u6709\u9650\u6570\u5B57`);return}let a=s[0]|0;Array.isArray(n.instruments)&&(a<0||a>=n.instruments.length)&&t.push(`patterns[${i}][${o}] \u4E50\u5668\u7D22\u5F15 ${a} \u8D8A\u754C\uFF08instruments \u957F\u5EA6 ${n.instruments.length}\uFF09`);let r=s[1];(r<-1||r>1)&&t.push(`patterns[${i}][${o}] \u58F0\u50CF ${r} \u8D8A\u754C\uFF08\u5E94 -1..+1\uFF09`)})}),!Array.isArray(n.sequence)||n.sequence.length===0?t.push("sequence \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4"):n.sequence.forEach((e,i)=>{if(typeof e!="number"||!Number.isInteger(e)){t.push(`sequence[${i}] \u5FC5\u987B\u662F\u6574\u6570 pattern \u7D22\u5F15`);return}Array.isArray(n.patterns)&&(e<0||e>=n.patterns.length)&&t.push(`sequence[${i}] \u7D22\u5F15 ${e} \u8D8A\u754C\uFF08patterns \u957F\u5EA6 ${n.patterns.length}\uFF09`)}),n.bpm!=null&&(typeof n.bpm!="number"||!(n.bpm>0))&&t.push("bpm \u5FC5\u987B\u662F\u6B63\u6570"),{ok:t.length===0,errors:t})}function pe(n){return typeof n!="number"||Number.isNaN(n)||n<0?0:n>1?1:n}function Sl(n,t){switch(n){case"ease-in":return t*t;case"ease-out":return Math.sqrt(t);case"constant":return 1;default:return t}}function da(n,t){let e=pe(t);return n==null||!Array.isArray(n.voices)?[]:n.voices.map(i=>{let s=String(i&&i.id!=null?i.id:""),o=Array.isArray(i&&i.channelIndices)?i.channelIndices.slice():[],a=typeof i.minIntensity=="number"?pe(i.minIntensity):0,r=typeof i.maxIntensity=="number"?pe(i.maxIntensity):1,c=typeof i.volumeCurve=="string"?i.volumeCurve:"linear",l=typeof i.baseVolume=="number"?pe(i.baseVolume):1;if(er)return{id:s,on:!1,volume:0,channelIndices:o};let u=r-a,h=u<=0?1:(e-a)/u,f=pe(Sl(c,h)*l);return{id:s,on:!0,volume:f,channelIndices:o}})}function fa(n,t,e,i){try{let s=t[0]||[],o=t[1]||s,a=Math.max(s.length,o.length);if(a===0)return null;let c=n.createBuffer(2,a,44100);c.getChannelData(0).set(s),c.getChannelData(1).set(o.length?o:s);let l=n.createBufferSource();l.buffer=c,l.loop=!!i;let u=n.createGain();return u.gain.value=pe(e*.3),l.connect(u),u.connect(n.destination),l.start(),{stop(){try{l.stop()}catch(h){}try{l.disconnect(),u.disconnect()}catch(h){}}}}catch(s){return to("[audio-music] \u53D7\u63A7\u97F3\u9891\u64AD\u653E\u5F02\u5E38\uFF0C\u964D\u7EA7\u4E3A\u9759\u9ED8",s),null}}function pa(n){let t=n||{},e=typeof t.masterVolume=="number"?pe(t.masterVolume):1,i=()=>null,s=null,o=null,a={voices:[]},r=1,c=null,l=!1,u=0,h=!1,f=!1;function d(){let S=i();return S==null?(u+=1,h||(Qs("[audio-music] \u65E0\u53D7\u63A7\u97F3\u9891\u4E0A\u4E0B\u6587\uFF08getAudioContext \u8FD4\u56DE null\uFF09\uFF0C\u5168\u90E8\u53D1\u58F0\u9759\u9ED8 no-op\uFF08\u8BC4\u4F30\u73AF\u5883\u65E0\u58F0\u5361\u65F6\u7684\u5BB9\u9519\u964D\u7EA7\uFF09"),h=!0),null):S}function y(){if(!o||!s)return null;try{let S=typeof o.bpm=="number"&&o.bpm>0?o.bpm:125;return s.synthSong(o.instruments,o.patterns,o.sequence,S)}catch(S){return to("[audio-music] \u66F2\u8C31\u6E32\u67D3\u5F02\u5E38\uFF0C\u964D\u7EA7\u4E3A\u9759\u9ED8",S),null}}function x(){let S=da(a,r);if(S.length===0)return 1;let _=0;for(let A of S)A.on&&(_=Math.max(_,A.volume));return _}function v(S,_){typeof _=="number"&&(r=pe(_));let A=d();if(A==null||!o)return;w();let T=y();if(!T)return;let L=pe(e*x());c=fa(A,T,L,S),l=!!S&&c!=null}function w(){c&&(c.stop(),c=null),l=!1}return{name:"audio-music",version:"1.0.0",dependencies:[],init(S){i=()=>S.getAudioContext();let _=S.getEngine&&S.getEngine();s=_?_.audio.synth:null},dispose(){f||(w(),f=!0)},loadSong(S){let _=vl(S);return _.ok?o={instruments:S.instruments,patterns:S.patterns,sequence:S.sequence,bpm:typeof S.bpm=="number"?S.bpm:125}:Qs("[audio-music] \u66F2\u8C31\u6821\u9A8C\u5931\u8D25\uFF0C\u672A\u8F7D\u5165\uFF1A"+_.errors.join("\uFF1B")),_},play(S){v(!1,S)},stop(){w()},loop(S){v(!0,S)},setIntensityLayering(S){a=S&&Array.isArray(S.voices)?{voices:S.voices}:{voices:[]}},setIntensity(S){r=pe(S)},resolveVoices(S){return da(a,S)},playSfx(S){let _=Zs[S];if(!_){Qs("[audio-music] \u672A\u77E5\u97F3\u6548\u9884\u8BBE\uFF1A"+String(S));return}let A=d();if(A!=null)try{let T=s?s.synthSfx(_.params):null;if(!T)return;fa(A,[T,T],e,!1)}catch(T){to("[audio-music] \u97F3\u6548\u64AD\u653E\u5F02\u5E38\uFF0C\u964D\u7EA7\u4E3A\u9759\u9ED8 name="+S,T)}},getPreset(S){return Zs[S]},listPresets(){return ha.slice()},probe(){return{hasAudio:i()!=null,hasSong:o!=null,intensity:r,voiceCount:a.voices.length,looping:l,silentNoops:u,presetCount:ha.length}}}}function to(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function Qs(n){typeof console!="undefined"&&typeof console.warn=="function"&&console.warn(n)}var wl="zaomeng.save";function Tl(n){if(typeof TextEncoder!="undefined")return new TextEncoder().encode(n).length;if(typeof Buffer!="undefined"&&typeof Buffer.byteLength=="function")return Buffer.byteLength(n,"utf8");let t=0;for(let e=0;e=55296&&i<=56319?(t+=4,e++):t+=3}return t}function no(){let n=new Map;return{getItem(t){return n.has(t)?n.get(t):null},setItem(t,e){n.set(t,e)},removeItem(t){n.delete(t)},keys(){return Array.from(n.keys())}}}function ga(){if(typeof localStorage=="undefined")throw new Error("[save-progress] createLocalStorageAdapter \u9700\u8981\u5168\u5C40 localStorage\uFF08\u4EC5\u6D4F\u89C8\u5668\u96C6\u6210\u6BB5\u53EF\u7528\uFF09\u3002node/host-dev \u8BF7\u7528\u7F3A\u7701\u5185\u5B58 adapter \u6216 createMemoryAdapter()\u3002");return{getItem(n){return localStorage.getItem(n)},setItem(n,t){localStorage.setItem(n,t)},removeItem(n){localStorage.removeItem(n)},keys(){let n=[];for(let t=0;t0?t.namespace:wl;if(e.indexOf(":")>=0)throw new Error('[save-progress] namespace \u4E0D\u5F97\u542B\u5206\u9694\u7B26 ":"\uFF08\u5F53\u524D="'+e+'"\uFF09');let i=typeof t.maxValueBytes=="number"&&t.maxValueBytes>0?Math.floor(t.maxValueBytes):32768,s=!Al(t.adapter),o=s?no():t.adapter,a=e+":",r=0,c=0,l=!1;function u(d){return typeof d!="string"||d.length===0?a+String(d):a+d}function h(){try{let d=o.keys();return Array.isArray(d)?d.filter(y=>typeof y=="string"&&y.indexOf(a)===0):[]}catch(d){return Xn("[save-progress] adapter.keys() \u5F02\u5E38\uFF0C\u964D\u7EA7\u8FD4\u56DE\u7A7A\u96C6",d),[]}}return{name:"save-progress",version:"1.0.0",dependencies:[],init(d){h()},dispose(){},get(d,y){if(!eo(d))return y;let x;try{x=o.getItem(u(d))}catch(v){return Xn("[save-progress] adapter.getItem \u5F02\u5E38\uFF0C\u8FD4\u56DE\u9ED8\u8BA4\u503C key="+d,v),y}if(x==null)return y;try{return JSON.parse(x)}catch{return r+=1,l||(Yn("[save-progress] \u68C0\u6D4B\u5230\u635F\u574F\u5B58\u6863\uFF08\u975E\u6CD5 JSON\uFF09\uFF0C\u5DF2\u5BB9\u9519\u56DE\u9000\u9ED8\u8BA4\u503C key="+d),l=!0),y}},set(d,y){if(!eo(d))return Yn("[save-progress] set \u6536\u5230\u975E\u6CD5 key\uFF0C\u62D2\u7EDD\u5199\u5165\uFF1A"+String(d)),!1;let x;try{x=JSON.stringify(y)}catch{return c+=1,Yn("[save-progress] \u503C\u4E0D\u53EF JSON \u5E8F\u5217\u5316\uFF08\u5FAA\u73AF\u5F15\u7528?\uFF09\uFF0C\u62D2\u7EDD\u5199\u5165 key="+d),!1}if(x===void 0)return c+=1,Yn("[save-progress] \u503C\u5E8F\u5217\u5316\u4E3A undefined\uFF08\u5982\u7EAF undefined/\u51FD\u6570\uFF09\uFF0C\u62D2\u7EDD\u5199\u5165 key="+d),!1;let v=Tl(x);if(v>i)return c+=1,Yn("[save-progress] \u503C\u8D85\u5B57\u8282\u4E0A\u9650\u62D2\u7EDD\u5199\u5165 key="+d+"\uFF08"+v+" > "+i+" bytes\uFF09"),!1;try{return o.setItem(u(d),x),!0}catch(w){return c+=1,Xn("[save-progress] adapter.setItem \u5F02\u5E38\uFF0C\u5199\u5165\u5931\u8D25 key="+d,w),!1}},remove(d){if(eo(d))try{o.removeItem(u(d))}catch(y){Xn("[save-progress] adapter.removeItem \u5F02\u5E38\uFF08\u5DF2\u5FFD\u7565\uFF09key="+d,y)}},clear(){let d=h(),y=0;for(let x of d)try{o.removeItem(x),y+=1}catch(v){Xn("[save-progress] clear \u65F6 removeItem \u5F02\u5E38\uFF08\u5DF2\u8DF3\u8FC7\uFF09fullKey="+x,v)}return y},probe(){return{namespace:e,maxValueBytes:i,usingMemoryAdapter:s,size:h().length,corruptRecoveries:r,rejectedWrites:c}}}}function eo(n){return typeof n=="string"&&n.length>0}function Al(n){return!!n&&typeof n.getItem=="function"&&typeof n.setItem=="function"&&typeof n.removeItem=="function"&&typeof n.keys=="function"}function Xn(n,t){let e=t&&t.stack?t.stack:t&&t.message?t.message:t;typeof console!="undefined"&&typeof console.error=="function"&&console.error(n+(e?"\uFF1A"+e:""))}function Yn(n){typeof console!="undefined"&&typeof console.warn=="function"&&console.warn(n)}var El={w:390,h:844};function ma(n){let t=((n&&n.seed)!=null?n.seed:0)>>>0,e=ta({cellSize:96}),i=ea(),s=ra({inputBufferMs:260,inputTypes:["pointerdown"]}),o=aa({seed:t,maxParticles:600}),a=ua({vignette:{enabled:!0,strength:.22}}),r=pa({masterVolume:.8}),c;try{c=ga()}catch(f){console.warn("[generic] localStorage \u4E0D\u53EF\u7528\uFF0C\u5B58\u6863\u9000\u5185\u5B58 adapter\uFF1A"+(f&&f.message)),c=no()}let l=ya({namespace:"zaomeng-generic",adapter:c});return{plugins:{collision:e,physics:i,gamefeel:s,juice:o,palettePost:a,audioMusic:r,save:l},registerOrder:[e,i,s,o,a,l,r],viewport:El,buildFactoryOpts:(f,d)=>({runtime:{plugins:d.plugins,bundle:d.bundle,getRealAudioCtx:d.getRealAudioCtx}})}}function $n(n){let t=null,e=0,i=0,s="booting",o=0,a=[],r=[],c={x:195,y:810,w:80,h:14},l=[],u=null,h=[],f="",d=0,y=.1,x=8;function v(){a=[];for(let ut=0;ut<6;ut++)for(let xt=0;xt<13;xt++)a.push({x:1+xt*30,y:60+ut*17,w:28,h:15,alive:!0,color:`hsl(${(ut*30+xt*12)%360}, 80%, 60%)`,dropRate:.25})}function w(){c.x=195,c.y=810,c.w=80,c.h=14}function C(){r=[];let D=3;for(let I=0;I0&&(d-=D);return}if(d>0&&(d-=D),u!==null){let k=Math.max(c.w/2,Math.min(390-c.w/2,u));c.x+=(k-c.x)*.3}c.x=Math.max(c.w/2,Math.min(390-c.w/2,c.x));let I=5;for(let k=0;k390&&(R.x=390-R.radius,R.vx=-R.vx),R.y-R.radius<0&&(R.y=R.radius,R.vy=-R.vy),R.vy>0&&R.y+R.radius>=c.y-c.h/2&&R.y-R.radius<=c.y+c.h/2&&R.x>c.x-c.w/2&&R.x844){R.dead=!0,xt=!0;let At=t.getEngine();if(At&&At.particles)try{At.particles.spawnEmitter({pos:{x:R.x,y:844},count:12,speed:55,particleTime:.5,colorStart:{r:1,g:.2,b:.2,a:1},colorEnd:{r:.5,g:0,b:0,a:0}})}catch{}if(At&&At.audio&&At.audio.synth)try{At.audio.synth.synthSfx([1,.08,180,,,.15,,1.1])}catch{}break}}}r=r.filter(k=>!k.dead);for(let k=r.length-1;k>=0;k--){let R=r[k];for(let ct=a.length-1;ct>=0;ct--){let j=a[ct];if(!j.alive)continue;let tt=Math.max(j.x,Math.min(R.x,j.x+j.w)),ut=Math.max(j.y,Math.min(R.y,j.y+j.h)),xt=R.x-tt,Ht=R.y-ut;if(xt*xt+Ht*Htk.alive);for(let k=l.length-1;k>=0;k--){let R=l[k];if(R.y+=R.speed*D,R.y+R.h/2>=c.y-c.h/2&&R.y-R.h/2<=c.y+c.h/2&&R.x>c.x-c.w/2&&R.x844&&l.splice(k,1)}if(a.length===0&&s==="playing"){s="gameover",f="cleared_all";let k=t.getEngine();if(k&&k.particles)try{k.particles.spawnEmitter({pos:{x:195,y:422},count:50,speed:140,particleTime:1,colorStart:{r:1,g:1,b:.2,a:1},colorEnd:{r:1,g:.5,b:0,a:0}})}catch{}if(k&&k.audio&&k.audio.synth)try{k.audio.synth.synthSfx([1,.2,880,,,.3,,1.5])}catch{}}if(r.length===0&&s==="playing"){s="gameover",f="ball_lost";let k=t.getEngine();if(k&&k.particles)try{k.particles.spawnEmitter({pos:{x:195,y:422},count:30,speed:80,particleTime:.7,colorStart:{r:1,g:.2,b:.2,a:1},colorEnd:{r:.5,g:0,b:0,a:0}})}catch{}if(k&&k.audio&&k.audio.synth)try{k.audio.synth.synthSfx([1,.15,200,,,.2,,.8])}catch{}}}function L(D){D.fillStyle="#0a0a1a",D.fillRect(0,0,390,844);for(let I of a)D.fillStyle=I.color,D.fillRect(I.x,I.y,I.w,I.h),D.strokeStyle="#ffffff",D.strokeRect(I.x,I.y,I.w,I.h);D.fillStyle="#88ddff",D.fillRect(c.x-c.w/2,c.y-c.h/2,c.w,c.h),D.fillStyle="#ffffff";for(let I of r)D.beginPath(),D.arc(I.x,I.y,I.radius,0,Math.PI*2),D.fill();for(let I of l)D.fillStyle=I.type==="extraBall"?"#44ff88":"#4488ff",D.fillRect(I.x-I.w/2,I.y-I.h/2,I.w,I.h);if(d>0){let I=Math.min(.35,d/y*.35);D.fillStyle=`rgba(255,255,255,${I.toFixed(3)})`,D.fillRect(0,0,390,844)}D.fillStyle="#ffffff",D.font="18px monospace",D.fillText("Score: "+o,10,30),D.fillText("Rem: "+a.length,200,30),s==="gameover"&&(D.textAlign="center",D.font="32px bold monospace",D.fillStyle="#ffcc00",D.fillText(f==="cleared_all"?"YOU WIN!":"GAME OVER",195,400),D.font="16px monospace",D.fillStyle="#aaaaaa",D.fillText("Tap to restart",195,450),D.textAlign="left")}function F(){for(let D of h)try{D.cancel()}catch{}h=[],r=[],a=[],l=[],u=null}function ft(){let D={x:0,y:0,vx:0,vy:0};if(r.length>0){let I=r[0];D={x:I.x,y:I.y,vx:I.vx,vy:I.vy}}return{seed:i,state:()=>({phase:s,result:s==="gameover"?f==="cleared_all"?"win":"lose":null,score:o,remaining:a.length,ball:D,paddle:{x:c.x,y:c.y,w:c.w},balls:r.map(I=>({x:I.x,y:I.y}))})}}return{init:A,update:T,render:L,destroy:F,_forensicsView:ft}}var pd=$n,gd=$n;async function yd(n){let t=n||{},e=t.engine||await Promise.resolve().then(()=>(Oc(),Lc)),i=(t.seed!=null?t.seed:305441741)>>>0,s=ma({seed:i});return Zr({canvas:t.canvas,statusEl:t.statusEl||null,engine:e,seed:i,mode:t.mode||"play",engineMode:"real",viewport:s.viewport,factory:$n,plugins:s.plugins,registerOrder:s.registerOrder,buildFactoryOpts:s.buildFactoryOpts,recHook:t.recHook||null,onReady:t.onReady||null})}return Nc(md);})();
diff --git a/game-runtime/games/_wg1-gen/multiball/bundle.iife.js.meta.json b/game-runtime/games/_wg1-gen/multiball/bundle.iife.js.meta.json
index 6354113f..71692b38 100644
--- a/game-runtime/games/_wg1-gen/multiball/bundle.iife.js.meta.json
+++ b/game-runtime/games/_wg1-gen/multiball/bundle.iife.js.meta.json
@@ -1 +1 @@
-{"inputs":{"src/core/plugin.js":{"bytes":44317,"imports":[],"format":"esm"},"src/plugins/runtime-probe/impl.js":{"bytes":16639,"imports":[],"format":"esm"},"host-dev/engine-caps.js":{"bytes":13897,"imports":[],"format":"esm"},"host-dev/engine-math.js":{"bytes":6155,"imports":[],"format":"esm"},"src/host/boot-game-host.js":{"bytes":27676,"imports":[{"path":"src/core/plugin.js","kind":"import-statement","original":"../core/plugin.js"},{"path":"src/plugins/runtime-probe/impl.js","kind":"import-statement","original":"../plugins/runtime-probe/impl.js"},{"path":"host-dev/engine-caps.js","kind":"import-statement","original":"../../host-dev/engine-caps.js"},{"path":"host-dev/engine-math.js","kind":"import-statement","original":"../../host-dev/engine-math.js"}],"format":"esm"},"src/plugins/collision/impl.js":{"bytes":24812,"imports":[],"format":"esm"},"src/plugins/physics-lite/impl.js":{"bytes":14507,"imports":[],"format":"esm"},"src/plugins/gamefeel/impl.js":{"bytes":21715,"imports":[],"format":"esm"},"src/plugins/particles-juice/impl.js":{"bytes":31830,"imports":[],"format":"esm"},"src/plugins/palette-post/impl.js":{"bytes":20240,"imports":[],"format":"esm"},"src/plugins/audio-music/impl.js":{"bytes":24659,"imports":[],"format":"esm"},"src/plugins/save-progress/impl.js":{"bytes":14608,"imports":[],"format":"esm"},"src/host/generic-host-config.js":{"bytes":7803,"imports":[{"path":"src/plugins/collision/impl.js","kind":"import-statement","original":"../plugins/collision/impl.js"},{"path":"src/plugins/physics-lite/impl.js","kind":"import-statement","original":"../plugins/physics-lite/impl.js"},{"path":"src/plugins/gamefeel/impl.js","kind":"import-statement","original":"../plugins/gamefeel/impl.js"},{"path":"src/plugins/particles-juice/impl.js","kind":"import-statement","original":"../plugins/particles-juice/impl.js"},{"path":"src/plugins/palette-post/impl.js","kind":"import-statement","original":"../plugins/palette-post/impl.js"},{"path":"src/plugins/audio-music/impl.js","kind":"import-statement","original":"../plugins/audio-music/impl.js"},{"path":"src/plugins/save-progress/impl.js","kind":"import-statement","original":"../plugins/save-progress/impl.js"}],"format":"esm"},"games/_wg1-gen/multiball/generated-factory.js":{"bytes":12098,"imports":[],"format":"esm"},"node_modules/littlejsengine/dist/littlejs.esm.js":{"bytes":640153,"imports":[],"format":"esm"},"games/_wg1-gen/multiball/entry-bundle.js":{"bytes":6230,"imports":[{"path":"src/host/boot-game-host.js","kind":"import-statement","original":"../../../src/host/boot-game-host.js"},{"path":"src/host/generic-host-config.js","kind":"import-statement","original":"../../../src/host/generic-host-config.js"},{"path":"games/_wg1-gen/multiball/generated-factory.js","kind":"import-statement","original":"./generated-factory.js"},{"path":"node_modules/littlejsengine/dist/littlejs.esm.js","kind":"dynamic-import","original":"littlejsengine"}],"format":"esm"}},"outputs":{"games/_wg1-gen/multiball/bundle.iife.js":{"imports":[],"exports":[],"entryPoint":"games/_wg1-gen/multiball/entry-bundle.js","inputs":{"node_modules/littlejsengine/dist/littlejs.esm.js":{"bytesInOutput":164197},"games/_wg1-gen/multiball/entry-bundle.js":{"bytesInOutput":507},"src/core/plugin.js":{"bytesInOutput":8989},"src/plugins/runtime-probe/impl.js":{"bytesInOutput":2794},"host-dev/engine-caps.js":{"bytesInOutput":1597},"host-dev/engine-math.js":{"bytesInOutput":498},"src/host/boot-game-host.js":{"bytesInOutput":5355},"src/plugins/collision/impl.js":{"bytesInOutput":1605},"src/plugins/physics-lite/impl.js":{"bytesInOutput":115},"src/plugins/gamefeel/impl.js":{"bytesInOutput":2533},"src/plugins/particles-juice/impl.js":{"bytesInOutput":4166},"src/plugins/palette-post/impl.js":{"bytesInOutput":4218},"src/plugins/audio-music/impl.js":{"bytesInOutput":6001},"src/plugins/save-progress/impl.js":{"bytesInOutput":3933},"src/host/generic-host-config.js":{"bytesInOutput":697},"games/_wg1-gen/multiball/generated-factory.js":{"bytesInOutput":4945}},"bytes":212721}}}
\ No newline at end of file
+{"inputs":{"src/core/plugin.js":{"bytes":44317,"imports":[],"format":"esm"},"src/plugins/runtime-probe/impl.js":{"bytes":16639,"imports":[],"format":"esm"},"host-dev/engine-caps.js":{"bytes":13897,"imports":[],"format":"esm"},"host-dev/engine-math.js":{"bytes":6155,"imports":[],"format":"esm"},"src/host/boot-game-host.js":{"bytes":28239,"imports":[{"path":"src/core/plugin.js","kind":"import-statement","original":"../core/plugin.js"},{"path":"src/plugins/runtime-probe/impl.js","kind":"import-statement","original":"../plugins/runtime-probe/impl.js"},{"path":"host-dev/engine-caps.js","kind":"import-statement","original":"../../host-dev/engine-caps.js"},{"path":"host-dev/engine-math.js","kind":"import-statement","original":"../../host-dev/engine-math.js"}],"format":"esm"},"src/plugins/collision/impl.js":{"bytes":24812,"imports":[],"format":"esm"},"src/plugins/physics-lite/impl.js":{"bytes":14507,"imports":[],"format":"esm"},"src/plugins/gamefeel/impl.js":{"bytes":21715,"imports":[],"format":"esm"},"src/plugins/particles-juice/impl.js":{"bytes":31830,"imports":[],"format":"esm"},"src/plugins/palette-post/impl.js":{"bytes":20240,"imports":[],"format":"esm"},"src/plugins/audio-music/impl.js":{"bytes":24659,"imports":[],"format":"esm"},"src/plugins/save-progress/impl.js":{"bytes":14608,"imports":[],"format":"esm"},"src/host/generic-host-config.js":{"bytes":7803,"imports":[{"path":"src/plugins/collision/impl.js","kind":"import-statement","original":"../plugins/collision/impl.js"},{"path":"src/plugins/physics-lite/impl.js","kind":"import-statement","original":"../plugins/physics-lite/impl.js"},{"path":"src/plugins/gamefeel/impl.js","kind":"import-statement","original":"../plugins/gamefeel/impl.js"},{"path":"src/plugins/particles-juice/impl.js","kind":"import-statement","original":"../plugins/particles-juice/impl.js"},{"path":"src/plugins/palette-post/impl.js","kind":"import-statement","original":"../plugins/palette-post/impl.js"},{"path":"src/plugins/audio-music/impl.js","kind":"import-statement","original":"../plugins/audio-music/impl.js"},{"path":"src/plugins/save-progress/impl.js","kind":"import-statement","original":"../plugins/save-progress/impl.js"}],"format":"esm"},"games/_wg1-gen/multiball/generated-factory.js":{"bytes":13530,"imports":[],"format":"esm"},"node_modules/littlejsengine/dist/littlejs.esm.js":{"bytes":640153,"imports":[],"format":"esm"},"games/_wg1-gen/multiball/entry-bundle.js":{"bytes":6230,"imports":[{"path":"src/host/boot-game-host.js","kind":"import-statement","original":"../../../src/host/boot-game-host.js"},{"path":"src/host/generic-host-config.js","kind":"import-statement","original":"../../../src/host/generic-host-config.js"},{"path":"games/_wg1-gen/multiball/generated-factory.js","kind":"import-statement","original":"./generated-factory.js"},{"path":"node_modules/littlejsengine/dist/littlejs.esm.js","kind":"dynamic-import","original":"littlejsengine"}],"format":"esm"}},"outputs":{"games/_wg1-gen/multiball/bundle.iife.js":{"imports":[],"exports":[],"entryPoint":"games/_wg1-gen/multiball/entry-bundle.js","inputs":{"node_modules/littlejsengine/dist/littlejs.esm.js":{"bytesInOutput":164177},"games/_wg1-gen/multiball/entry-bundle.js":{"bytesInOutput":507},"src/core/plugin.js":{"bytesInOutput":8989},"src/plugins/runtime-probe/impl.js":{"bytesInOutput":2794},"host-dev/engine-caps.js":{"bytesInOutput":1597},"host-dev/engine-math.js":{"bytesInOutput":498},"src/host/boot-game-host.js":{"bytesInOutput":5497},"src/plugins/collision/impl.js":{"bytesInOutput":1605},"src/plugins/physics-lite/impl.js":{"bytesInOutput":115},"src/plugins/gamefeel/impl.js":{"bytesInOutput":2533},"src/plugins/particles-juice/impl.js":{"bytesInOutput":4159},"src/plugins/palette-post/impl.js":{"bytesInOutput":4214},"src/plugins/audio-music/impl.js":{"bytesInOutput":6001},"src/plugins/save-progress/impl.js":{"bytesInOutput":3933},"src/host/generic-host-config.js":{"bytesInOutput":697},"games/_wg1-gen/multiball/generated-factory.js":{"bytesInOutput":6312}},"bytes":214199}}}
\ No newline at end of file
diff --git a/game-runtime/games/_wg1-gen/multiball/evidence/after-play.png b/game-runtime/games/_wg1-gen/multiball/evidence/after-play.png
index b71e8454..6366044e 100644
Binary files a/game-runtime/games/_wg1-gen/multiball/evidence/after-play.png and b/game-runtime/games/_wg1-gen/multiball/evidence/after-play.png differ
diff --git a/game-runtime/games/_wg1-gen/multiball/evidence/first-paint.png b/game-runtime/games/_wg1-gen/multiball/evidence/first-paint.png
index c1448217..afb667cf 100644
Binary files a/game-runtime/games/_wg1-gen/multiball/evidence/first-paint.png and b/game-runtime/games/_wg1-gen/multiball/evidence/first-paint.png differ
diff --git a/game-runtime/games/_wg1-gen/multiball/evidence/verdict.json b/game-runtime/games/_wg1-gen/multiball/evidence/verdict.json
index 497963be..13c740f5 100644
--- a/game-runtime/games/_wg1-gen/multiball/evidence/verdict.json
+++ b/game-runtime/games/_wg1-gen/multiball/evidence/verdict.json
@@ -8,9 +8,9 @@
     },
     "C_frame": {
       "pass": true,
-      "f0": 46,
-      "f1": 75,
-      "delta": 29
+      "f0": 49,
+      "f1": 79,
+      "delta": 30
     },
     "I_control": {
       "pass": true,
@@ -18,31 +18,31 @@
       "results": [
         {
           "tapX": 50,
-          "before": 194.99999999990354,
-          "after": 50,
-          "moved": -144.99999999990354,
-          "distToTarget": 0,
+          "before": 195,
+          "after": 54.09589111049999,
+          "moved": -140.9041088895,
+          "distToTarget": 4.095891110499991,
           "pass": true
         },
         {
           "tapX": 340,
-          "before": 50,
-          "after": 310,
-          "moved": 260,
-          "distToTarget": 30,
+          "before": 54.09589111049999,
+          "after": 306.3636674932592,
+          "moved": 252.2677763827592,
+          "distToTarget": 33.636332506740814,
           "pass": true
         }
       ]
     },
     "D_render": {
       "pass": true,
-      "bright": 146201,
+      "bright": 154512,
       "maxCh": 255
     },
     "E_live": {
       "pass": true,
-      "distinctStates": 64,
-      "samples": 72
+      "distinctStates": 15,
+      "samples": 15
     },
     "B_uncaught": {
       "pass": true,
@@ -50,10 +50,10 @@
     },
     "F_wiring": {
       "pass": true,
-      "callCount": 15,
+      "callCount": 27,
       "sample": [
-        "audio.synth.synthSfx",
-        "audio.synth.synthSfx",
+        "particles.spawnEmitter",
+        "particles.spawnEmitter",
         "audio.synth.synthSfx",
         "particles.spawnEmitter",
         "audio.synth.synthSfx",
@@ -61,8 +61,8 @@
         "audio.synth.synthSfx",
         "particles.spawnEmitter",
         "audio.synth.synthSfx",
-        "audio.synth.synthSfx",
         "particles.spawnEmitter",
+        "audio.synth.synthSfx",
         "particles.spawnEmitter"
       ],
       "expected": [
@@ -72,96 +72,80 @@
     },
     "G_input": {
       "pass": true,
-      "inputHash": "9cd794ce",
-      "controlHash": "6afc48cc",
-      "atFrame": 1984,
-      "ctrlFrame": -1
+      "inputHash": "7a86cc2e",
+      "controlHash": "b60e0fa8",
+      "atFrame": 615,
+      "ctrlFrame": 620
     },
     "H_progress": {
-      "pass": false,
+      "pass": true,
       "checks": [
         {
           "path": "remaining",
           "op": "decreased",
-          "before": 40,
-          "after": 36,
+          "before": 78,
+          "after": 69,
           "pass": true,
           "why": "多球+挡板接球击碎砖→剩余下降;碰撞失效/高速穿透(CCD缺)则不降"
         }
       ],
       "latch": {
-        "pass": false,
-        "reason": "真玩未到达 gameover 终态(终态不可达/无失败态/play-spec 未驱动到结束)",
-        "phaseNow": "playing"
+        "pass": true,
+        "dwelledMs": 600,
+        "after": "gameover",
+        "reason": ""
       },
       "state0": {
         "phase": "playing",
         "result": null,
         "score": 0,
-        "remaining": 40,
-        "progress": 0,
-        "gameoverReason": "",
+        "remaining": 78,
         "ball": {
-          "x": 171,
-          "y": 793,
-          "vx": -103.2459330675854,
-          "vy": 317.75830848240577
+          "x": 178.39632164686918,
+          "y": 772.8069677809253,
+          "vx": -149.90107628982514,
+          "vy": -312.5555661244529
         },
         "paddle": {
-          "x": 194.99999700380667,
-          "y": 804,
+          "x": 195,
+          "y": 810,
           "w": 80
         },
         "balls": [
           {
-            "x": 171,
-            "y": 793
+            "x": 55.977109343511984,
+            "y": 517.5532554459528
           },
           {
-            "x": 187,
-            "y": 793
+            "x": 212.95210833312012,
+            "y": 465.970216069029
           },
           {
-            "x": 203,
-            "y": 793
+            "x": 199.6740988851525,
+            "y": 475.6221190751453
           }
         ]
       },
       "state1": {
-        "phase": "playing",
-        "result": null,
-        "score": 4,
-        "remaining": 36,
-        "progress": 0,
-        "gameoverReason": "",
+        "phase": "gameover",
+        "result": "lose",
+        "score": 9,
+        "remaining": 69,
         "ball": {
-          "x": 171,
-          "y": 793,
-          "vx": -103.2459330675854,
-          "vy": 317.75830848240577
+          "x": 178.39632164686918,
+          "y": 772.8069677809253,
+          "vx": -149.90107628982514,
+          "vy": -312.5555661244529
         },
         "paddle": {
-          "x": 171.00000000000003,
-          "y": 804,
+          "x": 179.63617952826013,
+          "y": 810,
           "w": 80
         },
-        "balls": [
-          {
-            "x": 171,
-            "y": 793
-          },
-          {
-            "x": 187,
-            "y": 793
-          },
-          {
-            "x": 203,
-            "y": 793
-          }
-        ]
+        "balls": []
       }
     }
   },
-  "pass": false,
+  "pass": true,
   "notes": []
 }
\ No newline at end of file
diff --git a/game-runtime/games/_wg1-gen/multiball/generated-factory.js b/game-runtime/games/_wg1-gen/multiball/generated-factory.js
index 8a081ff1..cd4c4aad 100644
--- a/game-runtime/games/_wg1-gen/multiball/generated-factory.js
+++ b/game-runtime/games/_wg1-gen/multiball/generated-factory.js
@@ -1,388 +1,432 @@
 'use strict';
-
-/**
- * 多球打砖块变体工厂模块
- * 竖屏390×844,底部挡板,2-3球,砖块网格,道具掉落,胜负终态驻留。
- */
 export default function createGame(opts) {
-  const o = opts || {};
   let ctx = null;
+  let nowMs = 0;
+  let seed = 0;
   let phase = 'booting';
-  let gameoverReason = '';
   let score = 0;
-  let remaining = 0;
   let bricks = [];
   let balls = [];
-  let items = [];
-  let paddle = { x: 0, y: 0, w: 80, h: 16 };
-  let pointerTargetX = 195;
-  let inputSubs = [];
-  let particles = null;
-  let audioSynth = null;
-  let math = null;
-  let paddleWidenTimer = 0;
-  const PADDLE_ORIG_W = 80;
-  const WIDTH = 390, HEIGHT = 844;
-  const BALL_RADIUS = 6;
-  const BALL_SPEED = 350;
-  const MAX_BALLS = 5;
-  const BRICK_ROWS = 5;
-  const BRICK_COLS = 8;
-  const BRICK_W = 44, BRICK_H = 18, BRICK_GAP = 2;
-  const BRICK_TOP_Y = 50;
-  const BRICK_LEFT_X = (WIDTH - (BRICK_COLS * (BRICK_W + BRICK_GAP) - BRICK_GAP)) / 2;
+  let paddle = { x: 195, y: 810, w: 80, h: 14 };
+  let powerups = [];
+  let touchX = null;
+  let subs = [];
+  let gameoverReason = '';
+  let flashTimer = 0;
+  const FLASH_DUR = 0.1;
+  const BALL_RADIUS = 8;
 
-  function init(boot) {
-    ctx = boot.ctx;
-    phase = 'playing';
-    gameoverReason = '';
-    score = 0;
-    remaining = 0;
+  function initBricks() {
+    const cols = 13;
+    const rows = 6;
+    const bw = 28;
+    const bh = 15;
+    const gap = 2;
+    const startX = (390 - (cols * (bw + gap) - gap)) / 2;
+    const startY = 60;
     bricks = [];
-    balls = [];
-    items = [];
-    paddleWidenTimer = 0;
-    paddle.w = PADDLE_ORIG_W;
-    paddle.x = (WIDTH - PADDLE_ORIG_W) / 2;
-    paddle.y = HEIGHT - 40;
-
-    // 砖块网格
-    for (let row = 0; row < BRICK_ROWS; row++) {
-      for (let col = 0; col < BRICK_COLS; col++) {
-        const x = BRICK_LEFT_X + col * (BRICK_W + BRICK_GAP);
-        const y = BRICK_TOP_Y + row * (BRICK_H + BRICK_GAP);
-        bricks.push({ x, y, w: BRICK_W, h: BRICK_H, alive: true });
-        remaining++;
-      }
-    }
-
-    // 初始球 (2~3)
-    const ballCount = 2 + (boot.seed ? (boot.seed % 2) : 0); // 2或3
-    for (let i = 0; i < ballCount; i++) {
-      const angle = Math.PI * (0.6 + 0.3 * i / ballCount);
-      const spd = BALL_SPEED + ctx.random.range(-20, 20);
-      const vx = Math.cos(angle) * spd;
-      const vy = Math.sin(angle) * spd;
-      if (vy > 0) {
-        balls.push({
-          x: paddle.x + paddle.w * (0.2 + 0.6 * i / ballCount),
-          y: paddle.y - BALL_RADIUS - 5,
-          vx, vy,
-          radius: BALL_RADIUS,
-          alive: true
+    for (let r = 0; r < rows; r++) {
+      for (let c = 0; c < cols; c++) {
+        bricks.push({
+          x: startX + c * (bw + gap),
+          y: startY + r * (bh + gap),
+          w: bw,
+          h: bh,
+          alive: true,
+          color: `hsl(${(r * 30 + c * 12) % 360}, 80%, 60%)`,
+          dropRate: 0.25
         });
       }
     }
+  }
 
-    // 引擎接口
+  function initPaddle() {
+    paddle.x = 195;
+    paddle.y = 810;
+    paddle.w = 80;
+    paddle.h = 14;
+  }
+
+  function initBalls() {
+    balls = [];
+    const count = 3;
+    for (let i = 0; i < count; i++) {
+      const baseSpeed = ctx.random.range(320, 420);
+      const vx = ctx.random.range(-150, 150);
+      const vy = -Math.sqrt(Math.max(0, baseSpeed * baseSpeed - vx * vx));
+      const x = paddle.x + ctx.random.range(-30, 30);
+      const y = paddle.y - 35 - ctx.random.range(0, 15);
+      balls.push({ x, y, vx, vy, radius: BALL_RADIUS, dead: false });
+    }
+  }
+
+  function resetGame() {
+    phase = 'playing';
+    score = 0;
+    gameoverReason = '';
+    flashTimer = 0;
+    initBricks();
+    initPaddle();
+    initBalls();
+    powerups = [];
+    touchX = null;
+  }
+
+  function handlePointer(e) {
+    if (e.type === 'pointerdown' && phase === 'gameover') {
+      resetGame();
+      return;
+    }
+    if (e.type === 'pointermove' || e.type === 'pointerdown') {
+      touchX = e.x;
+    }
+    if (e.type === 'pointerup') {
+      touchX = null;
+    }
+  }
+
+  function init(boot) {
+    ctx = boot.ctx;
+    seed = (opts && opts.seed) || 0;
+    ctx.random.reseed(seed);
+    phase = 'playing';
+    score = 0;
+    gameoverReason = '';
+    flashTimer = 0;
+    initBricks();
+    initPaddle();
+    initBalls();
+    powerups = [];
+    touchX = null;
+    subs.push(ctx.getInput().on('pointermove', handlePointer));
+    subs.push(ctx.getInput().on('pointerdown', handlePointer));
+    subs.push(ctx.getInput().on('pointerup', handlePointer));
     const eng = ctx.getEngine();
-    if (eng) {
-      particles = eng.particles || null;
-      if (eng.audio && eng.audio.synth) audioSynth = eng.audio.synth;
-      math = eng.math || null;
+    if (eng && eng.particles) {
+      try {
+        eng.particles.spawnEmitter({
+          pos: { x: 195, y: 300 },
+          emitRate: 5,
+          emitTime: 0,
+          particleTime: 0.6,
+          speed: 30,
+          colorStart: { r: 1, g: 0.8, b: 0.2, a: 1 },
+          colorEnd: { r: 1, g: 0.3, b: 0, a: 0 }
+        });
+      } catch (_) { /* ignore */ }
     }
-
-    // 输入订阅
-    const input = ctx.getInput();
-    if (input) {
-      const subDown = input.on('pointerdown', (e) => {
-        pointerTargetX = e.x;
-      });
-      const subMove = input.on('pointermove', (e) => {
-        pointerTargetX = e.x;
-      });
-      inputSubs.push(subDown, subMove);
-    }
-    pointerTargetX = WIDTH / 2;
   }
 
   function update(dt) {
-    if (phase !== 'playing') return;
-
-    // 挡板平滑跟随触摸点
-    const diff = pointerTargetX - paddle.x;
-    paddle.x += diff * 0.3;
-    paddle.x = Math.max(0, Math.min(WIDTH - paddle.w, paddle.x));
-
-    // 扩板计时
-    if (paddleWidenTimer > 0) {
-      paddleWidenTimer -= dt;
-      if (paddleWidenTimer <= 0) {
-        paddle.w = PADDLE_ORIG_W;
-        paddle.x = Math.max(0, Math.min(WIDTH - paddle.w, paddle.x));
-      }
+    nowMs = ctx.time.nowMs();
+    if (phase !== 'playing') {
+      if (flashTimer > 0) flashTimer -= dt;
+      return;
     }
+    if (flashTimer > 0) flashTimer -= dt;
 
-    // 球移动 + CCD
-    const SUB_STEP = 2;
-    for (let ball of balls) {
-      if (!ball.alive) continue;
-      const dx = ball.vx * dt;
-      const dy = ball.vy * dt;
-      const dist = Math.sqrt(dx * dx + dy * dy);
-      const steps = Math.max(1, Math.ceil(dist / SUB_STEP));
-      const stepDx = dx / steps;
-      const stepDy = dy / steps;
+    // 挡板跟踪
+    if (touchX !== null) {
+      const targetX = Math.max(paddle.w / 2, Math.min(390 - paddle.w / 2, touchX));
+      paddle.x += (targetX - paddle.x) * 0.3;
+    }
+    paddle.x = Math.max(paddle.w / 2, Math.min(390 - paddle.w / 2, paddle.x));
 
+    // 球移动・分段
+    const SUB_STEP = 5;
+    for (let bi = 0; bi < balls.length; bi++) {
+      const ball = balls[bi];
+      if (ball.dead) continue;
+      const speed = Math.hypot(ball.vx, ball.vy);
+      const steps = Math.max(1, Math.ceil(speed * dt / SUB_STEP));
+      const sx = ball.vx * dt / steps;
+      const sy = ball.vy * dt / steps;
+      let outOfBounds = false;
       for (let s = 0; s < steps; s++) {
-        ball.x += stepDx;
-        ball.y += stepDy;
-
-        // 墙壁边界
+        ball.x += sx;
+        ball.y += sy;
+        // 墙碰撞
         if (ball.x - ball.radius < 0) { ball.x = ball.radius; ball.vx = -ball.vx; }
-        else if (ball.x + ball.radius > WIDTH) { ball.x = WIDTH - ball.radius; ball.vx = -ball.vx; }
+        if (ball.x + ball.radius > 390) { ball.x = 390 - ball.radius; ball.vx = -ball.vx; }
         if (ball.y - ball.radius < 0) { ball.y = ball.radius; ball.vy = -ball.vy; }
-
-        // 球掉出底部
-        if (ball.y + ball.radius > HEIGHT) {
-          ball.alive = false;
-          if (particles) {
-            try {
-              particles.spawnEmitter({
-                pos: { x: ball.x, y: HEIGHT },
-                count: 15, speed: 80, particleTime: 0.3,
-                colorStart: { r: 1, g: 0.2, b: 0.2, a: 1 },
-                colorEnd: { r: 0.8, g: 0, b: 0, a: 0 }
-              });
-            } catch (_) {}
-          }
-          break;
-        }
-
         // 挡板碰撞
-        if (ball.vy > 0 &&
-            ball.y + ball.radius >= paddle.y - 1 &&
-            ball.y - ball.radius <= paddle.y + paddle.h + 1 &&
-            ball.x + ball.radius > paddle.x &&
-            ball.x - ball.radius < paddle.x + paddle.w) {
-          const hitPos = (ball.x - (paddle.x + paddle.w / 2)) / (paddle.w / 2);
-          const speed = Math.sqrt(ball.vx * ball.vx + ball.vy * ball.vy);
-          const newVx = Math.max(-speed, Math.min(speed, hitPos * 300));
-          const newVy = -Math.sqrt(speed * speed - newVx * newVx);
-          ball.vx = newVx;
-          ball.vy = newVy;
-          ball.y = paddle.y - ball.radius;
-          if (audioSynth) {
-            try { audioSynth.synthSfx([1, 0.02, 300, , , 0.1, , 0.8]); } catch (_) {}
-          }
-        }
-
-        // 砖块碰撞
-        for (let brick of bricks) {
-          if (!brick.alive) continue;
-          const cx = ball.x, cy = ball.y, r = ball.radius;
-          const rx = brick.x, ry = brick.y, rw = brick.w, rh = brick.h;
-          const nearestX = Math.max(rx, Math.min(cx, rx + rw));
-          const nearestY = Math.max(ry, Math.min(cy, ry + rh));
-          const dxb = cx - nearestX, dyb = cy - nearestY;
-          const distSq = dxb * dxb + dyb * dyb;
-          if (distSq <= r * r) {
-            brick.alive = false;
-            remaining--;
-            score++;
-            // 粒子爆发
-            if (particles) {
+        if (ball.vy > 0 && ball.y + ball.radius >= paddle.y - paddle.h / 2 && ball.y - ball.radius <= paddle.y + paddle.h / 2) {
+          if (ball.x > paddle.x - paddle.w / 2 && ball.x < paddle.x + paddle.w / 2) {
+            ball.vy = -Math.abs(ball.vy);
+            const offset = (ball.x - paddle.x) / (paddle.w / 2);
+            ball.vx += offset * 180;
+            const sp = Math.hypot(ball.vx, ball.vy);
+            if (sp < 300) { const f = 300 / sp; ball.vx *= f; ball.vy *= f; }
+            const eng = ctx.getEngine();
+            if (eng && eng.particles) {
               try {
-                particles.spawnEmitter({
-                  pos: { x: brick.x + brick.w / 2, y: brick.y + brick.h / 2 },
-                  count: 20, speed: 100, particleTime: 0.5,
-                  colorStart: { r: 1, g: 0.9, b: 0.4, a: 1 },
-                  colorEnd: { r: 1, g: 0.5, b: 0, a: 0 }
+                eng.particles.spawnEmitter({
+                  pos: { x: ball.x, y: ball.y + ball.radius },
+                  count: 8,
+                  speed: 70,
+                  particleTime: 0.4,
+                  colorStart: { r: 1, g: 1, b: 1, a: 1 },
+                  colorEnd: { r: 1, g: 0.6, b: 0.2, a: 0 }
                 });
               } catch (_) {}
             }
-            if (audioSynth) {
-              try { audioSynth.synthSfx([1, 0.05, 440, , , 0.1, , 1.2]); } catch (_) {}
+            if (eng && eng.audio && eng.audio.synth) {
+              try { eng.audio.synth.synthSfx([1, 0.02, 420, , , 0.1, , 0.7]); } catch (_) {}
             }
-            // 反弹
-            if (distSq > 0.01) {
-              const nl = Math.sqrt(distSq);
-              const nx = dxb / nl, ny = dyb / nl;
-              ball.x += nx * (r - nl);
-              ball.y += ny * (r - nl);
-              const dot = ball.vx * nx + ball.vy * ny;
-              ball.vx -= 2 * dot * nx;
-              ball.vy -= 2 * dot * ny;
-            } else {
-              ball.y = brick.y - r;
-              ball.vy = -ball.vy;
-            }
-            // 道具掉落 (20%)
-            if (ctx.random.next() < 0.2) {
-              const type = ctx.random.next() < 0.5 ? 'extra_ball' : 'widen';
-              items.push({
-                x: brick.x + brick.w / 2,
-                y: brick.y + brick.h / 2,
-                type,
-                radius: 6,
-                speed: 150
+          }
+        }
+        // 底部出界
+        if (ball.y - ball.radius > 844) {
+          ball.dead = true;
+          outOfBounds = true;
+          const eng = ctx.getEngine();
+          if (eng && eng.particles) {
+            try {
+              eng.particles.spawnEmitter({
+                pos: { x: ball.x, y: 844 },
+                count: 12,
+                speed: 55,
+                particleTime: 0.5,
+                colorStart: { r: 1, g: 0.2, b: 0.2, a: 1 },
+                colorEnd: { r: 0.5, g: 0, b: 0, a: 0 }
               });
-            }
-            break; // 每子步只处理一块砖
+            } catch (_) {}
           }
+          if (eng && eng.audio && eng.audio.synth) {
+            try { eng.audio.synth.synthSfx([1, 0.08, 180, , , 0.15, , 1.1]); } catch (_) {}
+          }
+          break;
         }
       }
     }
+    balls = balls.filter(b => !b.dead);
 
-    balls = balls.filter(b => b.alive);
+    // 球与砖块碰撞
+    for (let bi = balls.length - 1; bi >= 0; bi--) {
+      const ball = balls[bi];
+      for (let ri = bricks.length - 1; ri >= 0; ri--) {
+        const brick = bricks[ri];
+        if (!brick.alive) continue;
+        const cx = Math.max(brick.x, Math.min(ball.x, brick.x + brick.w));
+        const cy = Math.max(brick.y, Math.min(ball.y, brick.y + brick.h));
+        const dx = ball.x - cx;
+        const dy = ball.y - cy;
+        if (dx * dx + dy * dy < ball.radius * ball.radius) {
+          brick.alive = false;
+          score++;
+          const bCx = brick.x + brick.w / 2;
+          const bCy = brick.y + brick.h / 2;
+          const nx = ball.x - bCx;
+          const ny = ball.y - bCy;
+          const len = Math.hypot(nx, ny) || 1;
+          const push = ball.radius - Math.sqrt(dx * dx + dy * dy) + 1;
+          ball.x += (nx / len) * push;
+          ball.y += (ny / len) * push;
+          const dot = ball.vx * (nx / len) + ball.vy * (ny / len);
+          ball.vx -= 2 * dot * (nx / len);
+          ball.vy -= 2 * dot * (ny / len);
+          flashTimer = FLASH_DUR;
+          const eng = ctx.getEngine();
+          if (eng && eng.particles) {
+            try {
+              eng.particles.spawnEmitter({
+                pos: { x: brick.x + brick.w / 2, y: brick.y + brick.h / 2 },
+                count: 22,
+                speed: 90,
+                particleTime: 0.5,
+                colorStart: { r: 1, g: 1, b: 1, a: 1 },
+                colorEnd: { r: 0.2, g: 0.8, b: 1, a: 0 }
+              });
+            } catch (_) {}
+          }
+          if (eng && eng.audio && eng.audio.synth) {
+            try { eng.audio.synth.synthSfx([1, 0.03, 700, , , 0.12, , 0.6]); } catch (_) {}
+          }
+          if (eng && eng.particles && eng.particles.shakeScreen) {
+            try { eng.particles.shakeScreen(4, 90); } catch (_) {}
+          }
+          if (ctx.random.next() < brick.dropRate) {
+            const type = ctx.random.next() < 0.5 ? 'extraBall' : 'widePaddle';
+            powerups.push({ x: brick.x + brick.w / 2, y: brick.y + brick.h / 2, w: 20, h: 12, type, speed: 180 });
+          }
+          break;
+        }
+      }
+    }
+    bricks = bricks.filter(b => b.alive);
 
-    // 道具移动与收集
-    for (let i = items.length - 1; i >= 0; i--) {
-      const item = items[i];
-      item.y += item.speed * dt;
-      // 挡板收集
-      if (item.y + item.radius >= paddle.y &&
-          item.y - item.radius <= paddle.y + paddle.h &&
-          item.x + item.radius > paddle.x &&
-          item.x - item.radius < paddle.x + paddle.w) {
-        if (item.type === 'extra_ball') {
-          if (balls.length < MAX_BALLS) {
-            const angle = Math.PI * (0.6 + ctx.random.range(-0.15, 0.15));
-            const spd = BALL_SPEED + ctx.random.range(-20, 20);
-            balls.push({
-              x: paddle.x + paddle.w / 2,
-              y: paddle.y - BALL_RADIUS - 5,
-              vx: Math.cos(angle) * spd,
-              vy: Math.sin(angle) * spd,
+    // 道具更新
+    for (let pi = powerups.length - 1; pi >= 0; pi--) {
+      const pu = powerups[pi];
+      pu.y += pu.speed * dt;
+      if (pu.y + pu.h / 2 >= paddle.y - paddle.h / 2 && pu.y - pu.h / 2 <= paddle.y + paddle.h / 2) {
+        if (pu.x > paddle.x - paddle.w / 2 && pu.x < paddle.x + paddle.w / 2) {
+          if (pu.type === 'extraBall') {
+            const nb = {
+              x: paddle.x + ctx.random.range(-40, 40),
+              y: paddle.y - 35,
+              vx: ctx.random.range(-150, 150),
+              vy: -340,
               radius: BALL_RADIUS,
-              alive: true
-            });
+              dead: false
+            };
+            balls.push(nb);
+          } else if (pu.type === 'widePaddle') {
+            paddle.w = Math.min(150, paddle.w + 20);
           }
-        } else if (item.type === 'widen') {
-          paddle.w = PADDLE_ORIG_W * 1.5;
-          paddleWidenTimer = 7;
-          paddle.x = Math.max(0, Math.min(WIDTH - paddle.w, paddle.x));
+          const eng = ctx.getEngine();
+          if (eng && eng.particles) {
+            try {
+              eng.particles.spawnEmitter({
+                pos: { x: pu.x, y: pu.y },
+                count: 14,
+                speed: 60,
+                particleTime: 0.4,
+                colorStart: { r: 0, g: 1, b: 0.6, a: 1 },
+                colorEnd: { r: 0, g: 0.5, b: 0, a: 0 }
+              });
+            } catch (_) {}
+          }
+          if (eng && eng.audio && eng.audio.synth) {
+            try { eng.audio.synth.synthSfx([1, 0.04, 600, , , 0.12, , 0.8]); } catch (_) {}
+          }
+          powerups.splice(pi, 1);
+          continue;
         }
-        // 收集粒子
-        if (particles) {
-          try {
-            particles.spawnEmitter({
-              pos: { x: item.x, y: item.y },
-              count: 10, speed: 60, particleTime: 0.3,
-              colorStart: { r: 0.2, g: 1, b: 0.2, a: 1 },
-              colorEnd: { r: 0, g: 0.8, b: 0, a: 0 }
-            });
-          } catch (_) {}
-        }
-        items.splice(i, 1);
-        continue;
       }
-      if (item.y > HEIGHT + 20) items.splice(i, 1);
+      if (pu.y + pu.h / 2 > 844) {
+        powerups.splice(pi, 1);
+      }
     }
 
-    // 胜负判定
-    if (remaining === 0) {
+    // 终态判断
+    if (bricks.length === 0 && phase === 'playing') {
       phase = 'gameover';
       gameoverReason = 'cleared_all';
-    } else if (balls.length === 0) {
+      const eng = ctx.getEngine();
+      if (eng && eng.particles) {
+        try {
+          eng.particles.spawnEmitter({
+            pos: { x: 195, y: 422 },
+            count: 50,
+            speed: 140,
+            particleTime: 1.0,
+            colorStart: { r: 1, g: 1, b: 0.2, a: 1 },
+            colorEnd: { r: 1, g: 0.5, b: 0, a: 0 }
+          });
+        } catch (_) {}
+      }
+      if (eng && eng.audio && eng.audio.synth) {
+        try { eng.audio.synth.synthSfx([1, 0.2, 880, , , 0.3, , 1.5]); } catch (_) {}
+      }
+    }
+    if (balls.length === 0 && phase === 'playing') {
       phase = 'gameover';
       gameoverReason = 'ball_lost';
+      const eng = ctx.getEngine();
+      if (eng && eng.particles) {
+        try {
+          eng.particles.spawnEmitter({
+            pos: { x: 195, y: 422 },
+            count: 30,
+            speed: 80,
+            particleTime: 0.7,
+            colorStart: { r: 1, g: 0.2, b: 0.2, a: 1 },
+            colorEnd: { r: 0.5, g: 0, b: 0, a: 0 }
+          });
+        } catch (_) {}
+      }
+      if (eng && eng.audio && eng.audio.synth) {
+        try { eng.audio.synth.synthSfx([1, 0.15, 200, , , 0.2, , 0.8]); } catch (_) {}
+      }
     }
   }
 
   function render(g) {
-    // 背景
     g.fillStyle = '#0a0a1a';
-    g.fillRect(0, 0, WIDTH, HEIGHT);
+    g.fillRect(0, 0, 390, 844);
 
     // 砖块
-    for (let brick of bricks) {
-      if (!brick.alive) continue;
-      g.fillStyle = '#44aaff';
+    for (const brick of bricks) {
+      g.fillStyle = brick.color;
       g.fillRect(brick.x, brick.y, brick.w, brick.h);
-      g.strokeStyle = '#3399ee';
-      g.lineWidth = 1;
+      g.strokeStyle = '#ffffff';
       g.strokeRect(brick.x, brick.y, brick.w, brick.h);
     }
 
-    // 道具
-    for (let item of items) {
-      g.fillStyle = item.type === 'extra_ball' ? '#00ff88' : '#ffaa00';
-      g.beginPath();
-      g.arc(item.x, item.y, item.radius, 0, Math.PI * 2);
-      g.fill();
-    }
+    // 挡板
+    g.fillStyle = '#88ddff';
+    g.fillRect(paddle.x - paddle.w / 2, paddle.y - paddle.h / 2, paddle.w, paddle.h);
 
     // 球
-    for (let ball of balls) {
-      if (!ball.alive) continue;
-      g.fillStyle = '#ffffff';
+    g.fillStyle = '#ffffff';
+    for (const ball of balls) {
       g.beginPath();
       g.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
       g.fill();
-      g.fillStyle = '#cccccc';
-      g.beginPath();
-      g.arc(ball.x - 2, ball.y - 2, ball.radius * 0.5, 0, Math.PI * 2);
-      g.fill();
     }
 
-    // 挡板
-    g.fillStyle = '#ffaa44';
-    g.fillRect(paddle.x, paddle.y, paddle.w, paddle.h);
-    g.fillStyle = '#ffcc88';
-    g.fillRect(paddle.x, paddle.y, paddle.w, paddle.h / 2);
+    // 道具
+    for (const pu of powerups) {
+      g.fillStyle = pu.type === 'extraBall' ? '#44ff88' : '#4488ff';
+      g.fillRect(pu.x - pu.w / 2, pu.y - pu.h / 2, pu.w, pu.h);
+    }
+
+    // 闪白
+    if (flashTimer > 0) {
+      const alpha = Math.min(0.35, flashTimer / FLASH_DUR * 0.35);
+      g.fillStyle = `rgba(255,255,255,${alpha.toFixed(3)})`;
+      g.fillRect(0, 0, 390, 844);
+    }
 
     // HUD
     g.fillStyle = '#ffffff';
-    g.font = '16px monospace';
-    g.fillText('Score: ' + score, 10, 28);
-    g.fillText('Remaining: ' + remaining, 10, 52);
-    g.fillText('Balls: ' + balls.length, 10, 76);
+    g.font = '18px monospace';
+    g.fillText('Score: ' + score, 10, 30);
+    g.fillText('Rem: ' + bricks.length, 200, 30);
 
-    // 游戏结束画面
     if (phase === 'gameover') {
-      g.fillStyle = 'rgba(0,0,0,0.6)';
-      g.fillRect(0, 0, WIDTH, HEIGHT);
-      g.fillStyle = '#ffcc00';
-      g.font = 'bold 32px sans-serif';
       g.textAlign = 'center';
-      if (gameoverReason === 'cleared_all') {
-        g.fillText('YOU WIN!', WIDTH / 2, HEIGHT / 2 - 20);
-      } else {
-        g.fillText('GAME OVER', WIDTH / 2, HEIGHT / 2 - 20);
-      }
-      g.font = '18px sans-serif';
-      g.fillStyle = '#ffffff';
-      g.fillText('Tap to restart (not auto)', WIDTH / 2, HEIGHT / 2 + 40);
+      g.font = '32px bold monospace';
+      g.fillStyle = '#ffcc00';
+      g.fillText(gameoverReason === 'cleared_all' ? 'YOU WIN!' : 'GAME OVER', 195, 400);
+      g.font = '16px monospace';
+      g.fillStyle = '#aaaaaa';
+      g.fillText('Tap to restart', 195, 450);
       g.textAlign = 'left';
     }
   }
 
   function destroy() {
-    for (let sub of inputSubs) {
+    for (const sub of subs) {
       try { sub.cancel(); } catch (_) {}
     }
-    inputSubs = [];
-    phase = 'booting';
+    subs = [];
     balls = [];
     bricks = [];
-    items = [];
-    paddleWidenTimer = 0;
-    paddle.w = PADDLE_ORIG_W;
-    pointerTargetX = WIDTH / 2;
+    powerups = [];
+    touchX = null;
   }
 
   function _forensicsView() {
-    const mainBall = balls.length > 0
-      ? { x: balls[0].x, y: balls[0].y, vx: balls[0].vx, vy: balls[0].vy }
-      : { x: 0, y: 0, vx: 0, vy: 0 };
-    const ballPositions = balls.map(b => ({ x: b.x, y: b.y }));
+    let mainBall = { x: 0, y: 0, vx: 0, vy: 0 };
+    if (balls.length > 0) {
+      const b = balls[0];
+      mainBall = { x: b.x, y: b.y, vx: b.vx, vy: b.vy };
+    }
     return {
-      seed: boot?.seed,
+      seed,
       state: () => ({
         phase,
-        result: gameoverReason === 'cleared_all' ? 'win' : (gameoverReason === 'ball_lost' ? 'lose' : null),
+        result: phase === 'gameover' ? (gameoverReason === 'cleared_all' ? 'win' : 'lose') : null,
         score,
-        remaining,
-        progress: 0,
-        gameoverReason,
+        remaining: bricks.length,
         ball: mainBall,
         paddle: { x: paddle.x, y: paddle.y, w: paddle.w },
-        balls: ballPositions,
+        balls: balls.map(b => ({ x: b.x, y: b.y }))
       })
     };
   }
 
-  let boot;
-  return { init: (b) => { boot = b; return init(b); }, update, render, destroy, _forensicsView };
+  return { init, update, render, destroy, _forensicsView };
 }
\ No newline at end of file
diff --git a/game-runtime/games/_wg1-gen/multiball/play-spec.json b/game-runtime/games/_wg1-gen/multiball/play-spec.json
index 2d8676cb..1f202d53 100644
--- a/game-runtime/games/_wg1-gen/multiball/play-spec.json
+++ b/game-runtime/games/_wg1-gen/multiball/play-spec.json
@@ -14,8 +14,10 @@
     "type": "paddle-intercept",
     "ballPath": "ball.x",
     "paddleY": 800,
-    "steps": 70,
-    "stepMs": 130
+    "steps": 80,
+    "stepMs": 130,
+    "drainAfter": 48,
+    "drainX": 10
   },
   "expectedEngineCallPrefixes": [
     "particles.",
diff --git a/game-runtime/games/_wg1-gen/t2048/evidence/after-play.png b/game-runtime/games/_wg1-gen/t2048/evidence/after-play.png
index a35438be..f34ba53f 100644
Binary files a/game-runtime/games/_wg1-gen/t2048/evidence/after-play.png and b/game-runtime/games/_wg1-gen/t2048/evidence/after-play.png differ
diff --git a/game-runtime/games/_wg1-gen/t2048/evidence/first-paint.png b/game-runtime/games/_wg1-gen/t2048/evidence/first-paint.png
index 73dd069d..5468e664 100644
Binary files a/game-runtime/games/_wg1-gen/t2048/evidence/first-paint.png and b/game-runtime/games/_wg1-gen/t2048/evidence/first-paint.png differ
diff --git a/game-runtime/games/_wg1-gen/t2048/evidence/verdict.json b/game-runtime/games/_wg1-gen/t2048/evidence/verdict.json
index bc79f6b4..d2c53739 100644
--- a/game-runtime/games/_wg1-gen/t2048/evidence/verdict.json
+++ b/game-runtime/games/_wg1-gen/t2048/evidence/verdict.json
@@ -1,6 +1,6 @@
 {
   "gameId": "t2048",
-  "url": "http://localhost:4320/games/_wg1-gen/t2048/index.html",
+  "url": "http://localhost:4323/games/_wg1-gen/t2048/index.html",
   "ts": null,
   "guards": {
     "A_boot": {
@@ -8,8 +8,8 @@
     },
     "C_frame": {
       "pass": true,
-      "f0": 47,
-      "f1": 77,
+      "f0": 49,
+      "f1": 79,
       "delta": 30
     },
     "I_control": {
@@ -18,7 +18,7 @@
     },
     "D_render": {
       "pass": true,
-      "bright": 81964,
+      "bright": 81997,
       "maxCh": 249
     },
     "E_live": {
@@ -45,9 +45,9 @@
     },
     "G_input": {
       "pass": true,
-      "inputHash": "400f8c09",
-      "controlHash": "9c7f4289",
-      "atFrame": 2967,
+      "inputHash": "19cc6df1",
+      "controlHash": "45497b06",
+      "atFrame": 2766,
       "ctrlFrame": -1
     },
     "H_progress": {
diff --git a/game-runtime/games/_wg1-gen/t2048/play-spec.json b/game-runtime/games/_wg1-gen/t2048/play-spec.json
index 705f8efd..d0ef3292 100644
--- a/game-runtime/games/_wg1-gen/t2048/play-spec.json
+++ b/game-runtime/games/_wg1-gen/t2048/play-spec.json
@@ -2,13 +2,11 @@
   "driver": {
     "type": "key-cycle",
     "keys": [
-      "ArrowLeft",
       "ArrowUp",
-      "ArrowRight",
-      "ArrowDown"
+      "ArrowRight"
     ],
     "steps": 120,
-    "stepMs": 220
+    "stepMs": 200
   },
   "expectedEngineCallPrefixes": [
     "particles.",
diff --git a/wg1/gen-worker/briefs/angrybirds.json b/wg1/gen-worker/briefs/angrybirds.json
index a7859e95..08023df4 100644
--- a/wg1/gen-worker/briefs/angrybirds.json
+++ b/wg1/gen-worker/briefs/angrybirds.json
@@ -1,19 +1,11 @@
 {
   "title": "愤怒小鸟(简版)",
-  "brief": "做一款简版愤怒小鸟(抛射弹道)。竖屏逻辑视口 390×844。\n- 左下方一个弹弓发射点(约 x=80, y=600)。右侧摆放若干砖块结构与目标(猪)。\n- 操作:从发射点【拖拽】蓄力——按下并拖向反方向,松手时按【拖拽反向矢量】决定小鸟初速度(拖得越远力越大)发射;小鸟受重力走抛物线。\n- 小鸟击中砖块/猪 → 结构受冲量倒塌、击中猪得分 / 消除;一只鸟落地或飞出屏幕后换下一只。\n- 共 5 只鸟,用完(或击杀所有猪)= 结束。\n- 顶部文本 HUD:分数 / 剩余鸟数 / 状态。\n- 【终态契约·务必遵守】鸟用完/全清即把 phase 置 'gameover' 并【驻留】(结果 + 「点击重玩」);点击重玩前 phase 恒 'gameover',绝不自动重开 / 不下一帧复位。gameover 下输入忽略。\n- 【可测性·务必导出状态】_forensicsView().state() 纯只读实时真值:phase;result(null|'win'|'lose');score(整数,开局0);birdsLeft(剩余鸟数);targets(剩余猪/关键砖块中心,数组,每元素 {x,y})。harness 据 score/phase 验进展与终局。\n- 反馈(juice):发射 / 撞击 / 倒塌 / 击杀触发 getEngine().particles.spawnEmitter + getEngine().audio.synth.synthSfx。\n- 画面:深色背景铺满;弹弓 / 小鸟 / 砖块 / 猪 / 文字亮色实心。",
+  "brief": "做一款简版愤怒小鸟(抛射弹道)。竖屏逻辑视口 390×844。\n- 左下方一个弹弓发射点(固定 x=80, y=600)。右侧摆放若干砖块结构与目标(猪),猪的 x 落在约 [240, 350](弹道可达区间内,勿贴右边缘)。\n- 操作:从发射点【拖拽】蓄力——按下并拖向反方向,松手发射。**物理务必 pin 死且简单可解析**:初速度大小 = 拖拽距离(逻辑像素) × powerScale(**powerScale = 8**),方向 = 拖拽反方向;发射后小鸟只受重力 gravity(**gravity = 1200**,单位 px/s²,向下)做抛物线,**无空气阻力 / 无其他力 / 无速度上限 / 无额外缩放**。物理积分按真实时间(秒)推进(用受控 time 的 dt)。这两个常数就是游戏真实所用值。\n- 小鸟击中砖块/猪 → 结构受冲量倒塌、击中猪得分 / 消除;一只鸟落地或飞出屏幕后换下一只。\n- 共 5 只鸟,用完(或击杀所有猪)= 结束。\n- 顶部文本 HUD:分数 / 剩余鸟数 / 状态。\n- 【终态契约·务必遵守】鸟用完/全清即把 phase 置 'gameover' 并【驻留】(结果 + 「点击重玩」);点击重玩前 phase 恒 'gameover',绝不自动重开 / 不下一帧复位。gameover 下输入忽略。\n- 【可测性·务必导出状态】_forensicsView().state() 纯只读实时真值:phase;result(null|'win'|'lose');score(整数,开局0);birdsLeft(剩余鸟数);targets(剩余猪/关键砖块中心,数组,每元素 {x,y});**launch:{gravity, powerScale}(= 上面 pin 的两个常数,务必与实际物理完全一致,供 harness 解析反解拖拽瞄准)**。harness 据 launch+targets 解析 45° 抛瞄准、据 score/phase 验进展与终局。\n- 反馈(juice):发射 / 撞击 / 倒塌 / 击杀触发 getEngine().particles.spawnEmitter + getEngine().audio.synth.synthSfx。\n- 画面:深色背景铺满;弹弓 / 小鸟 / 砖块 / 猪 / 文字亮色实心。",
   "play_spec": {
-    "inputs": [
-      { "t": "wait", "ms": 700 },
-      { "t": "drag", "from": { "x": 80, "y": 600 }, "to": { "x": 44, "y": 668 }, "ms": 420 }, { "t": "wait", "ms": 1700 },
-      { "t": "drag", "from": { "x": 80, "y": 600 }, "to": { "x": 40, "y": 690 }, "ms": 420 }, { "t": "wait", "ms": 1700 },
-      { "t": "drag", "from": { "x": 80, "y": 600 }, "to": { "x": 50, "y": 655 }, "ms": 420 }, { "t": "wait", "ms": 1700 },
-      { "t": "drag", "from": { "x": 80, "y": 600 }, "to": { "x": 38, "y": 700 }, "ms": 420 }, { "t": "wait", "ms": 1700 },
-      { "t": "drag", "from": { "x": 80, "y": 600 }, "to": { "x": 54, "y": 648 }, "ms": 420 }, { "t": "wait", "ms": 1700 },
-      { "t": "drag", "from": { "x": 80, "y": 600 }, "to": { "x": 42, "y": 680 }, "ms": 420 }, { "t": "wait", "ms": 1700 }
-    ],
+    "driver": { "type": "drag-aiming", "origin": { "x": 80, "y": 600 }, "targetsPath": "targets", "launchPath": "launch", "steps": 6, "settleMs": 1700, "upLead": 95, "powers": [60, 80, 100, 70, 90, 110] },
     "expectedEngineCallPrefixes": ["particles.", "audio.synth"],
     "assertAfterPlay": [
-      { "path": "score", "op": "increased", "why": "盲态固定拖拽发射→偶中目标得分;若固定角度打不中(需读目标算拖拽矢量)则不升=暴露拖拽瞄准缺口" }
+      { "path": "score", "op": "increased", "why": "drag-aiming 读 launch 物理常数(gravity/powerScale)45° 抛解析反解拖拽矢量→命中猪得分上升;游戏暴露物理即可确定性瞄准(asteroids 式『暴露即可测』);若仍 0=物理未按 pin 实现" }
     ],
     "expectLatch": true
   }
diff --git a/wg1/gen-worker/briefs/asteroids.json b/wg1/gen-worker/briefs/asteroids.json
index cb8375ac..f9bae5e1 100644
--- a/wg1/gen-worker/briefs/asteroids.json
+++ b/wg1/gen-worker/briefs/asteroids.json
@@ -1,11 +1,11 @@
 {
   "title": "小行星 Asteroids",
-  "brief": "做一款经典小行星 Asteroids。竖屏逻辑视口 390×844。\n- 玩家飞船在屏幕中央,有惯性(推进后保持速度、缓慢摩擦)。按键 ArrowLeft/ArrowRight 旋转朝向;ArrowUp 朝当前朝向推进;Space 朝当前朝向发射子弹。\n- 屏幕四周漂浮大陨石(用受控 random 初始化方向);子弹击中大陨石→裂成两块小陨石、得分 +1;击中小陨石→击碎、得分 +1。所有元素屏幕环绕(飞出一边从另一边回来)。\n- 飞船被陨石撞到 = 失败;清光所有陨石 = 胜利。\n- 【CCD 注意】子弹与小陨石都可能高速移动,请用【连续碰撞/沿速度向量扫掠检测】判命中,避免高速穿透(漏判)。\n- 顶部文本 HUD:分数 / 剩余陨石数 / 状态。\n- 【终态契约·务必遵守】失败/胜利即把 phase 置 'gameover' 并【驻留】(显示结果 + 「点击重玩」);点击重玩前 phase 恒 'gameover',绝不自动重开 / 不下一帧复位(宿主每 500ms 轮询)。\n- 【可测性·务必导出状态】_forensicsView().state() 纯只读实时真值:phase;result(null|'win'|'lose');score(整数,开局0);asteroidsRemaining(剩余陨石数);ship:{x,y,angle}。harness 据 score/phase 验进展与终局。\n- 反馈(juice):开火 / 击碎 / 撞毁触发 getEngine().particles.spawnEmitter + getEngine().audio.synth.synthSfx。\n- 画面:深色背景铺满;飞船 / 陨石 / 子弹 / 文字亮色实心。",
+  "brief": "做一款经典小行星 Asteroids。竖屏逻辑视口 390×844。\n- 玩家飞船在屏幕中央,有惯性(推进后保持速度、缓慢摩擦)。按键 ArrowLeft/ArrowRight 旋转朝向;ArrowUp 朝当前朝向推进;Space 朝当前朝向发射子弹。\n- 屏幕四周漂浮大陨石(用受控 random 初始化方向);子弹击中大陨石→裂成两块小陨石、得分 +1;击中小陨石→击碎、得分 +1。所有元素屏幕环绕(飞出一边从另一边回来)。\n- 飞船被陨石撞到 = 失败;清光所有陨石 = 胜利。\n- 【CCD 注意】子弹与小陨石都可能高速移动,请用【连续碰撞/沿速度向量扫掠检测】判命中,避免高速穿透(漏判)。\n- 顶部文本 HUD:分数 / 剩余陨石数 / 状态。\n- 【终态契约·务必遵守】失败/胜利即把 phase 置 'gameover' 并【驻留】(显示结果 + 「点击重玩」);点击重玩前 phase 恒 'gameover',绝不自动重开 / 不下一帧复位(宿主每 500ms 轮询)。\n- 【可测性·务必导出状态】_forensicsView().state() 纯只读实时真值:phase;result(null|'win'|'lose');score(整数,开局0);asteroidsRemaining(剩余陨石数);ship:{x,y,angle}(angle=朝向弧度,与 atan2 同向:指上≈-π/2);asteroids:[{x,y}...](所有活跃陨石中心逻辑像素,供 harness 旋向瞄准开火)。harness 据 ship.angle/asteroids 旋转对齐开火、据 score/phase 验进展与终局。\n- 反馈(juice):开火 / 击碎 / 撞毁触发 getEngine().particles.spawnEmitter + getEngine().audio.synth.synthSfx。\n- 画面:深色背景铺满;飞船 / 陨石 / 子弹 / 文字亮色实心。",
   "play_spec": {
-    "driver": { "type": "key-cycle", "keys": ["ArrowLeft", "ArrowUp", "Space", "ArrowRight", "Space", "Space"], "steps": 50, "stepMs": 200 },
+    "driver": { "type": "aim-fire", "shipPath": "ship", "targetsPath": "asteroids", "fireKey": "Space", "steps": 90, "stepMs": 120, "downMs": 80 },
     "expectedEngineCallPrefixes": ["particles.", "audio.synth"],
     "assertAfterPlay": [
-      { "path": "score", "op": "increased", "why": "循环旋转+推进+开火→击碎陨石得分上升;若高速子弹穿透(CCD缺)或打不中则不升=暴露 CCD 缺口" }
+      { "path": "score", "op": "increased", "why": "aim-fire 读陨石坐标旋向对齐开火→击碎得分上升;若游戏不暴露陨石坐标致盲射则不升=可测性边界" }
     ],
     "expectLatch": true
   }
diff --git a/wg1/gen-worker/briefs/flappy.json b/wg1/gen-worker/briefs/flappy.json
index 1a4762d2..5f722b3b 100644
--- a/wg1/gen-worker/briefs/flappy.json
+++ b/wg1/gen-worker/briefs/flappy.json
@@ -1,8 +1,8 @@
 {
   "title": "Flappy Bird",
-  "brief": "做一款经典 Flappy Bird。竖屏逻辑视口 390×844(坐标 y 向下为正:y 越大越靠近屏幕底部)。\n- 小鸟固定在屏幕左侧 x≈110,受【适中】重力持续下落;点击任意位置 = 小鸟获得一个向上的瞬时速度(拍翅)。**拍翅力度与重力要平衡**:玩家能轻松让小鸟在屏内上下浮动,不会一拍就冲顶、也不会一松就坠底;开局小鸟稳定悬浮在屏幕中部附近等待操作。\n- 成对的上下管道从右向左匀速滚动;缝隙【宽松】——垂直缺口高度 ≥ 屏高的 24%;管道水平间距给足反应时间:开局到第一对管道 ≥ 1.5 秒,之后每对间距稳定。小鸟从缝隙穿过 = 得分 +1。\n- 撞到管道 / 触顶 / 触底 = 失败。\n- 顶部文本 HUD:得分 / 状态。\n- 【终态契约·务必遵守】失败即把 _forensicsView().state().phase 置 'gameover' 并【驻留】(显示结果 + 「点击重玩」提示);玩家点击重玩前 phase 必须恒为 'gameover',**绝不自动重开 / 不下一帧复位**(宿主每 500ms 轮询 phase 判结束)。gameover 下点击一律忽略;仅「重玩」按钮重开。\n- 【可测性·务必导出状态】_forensicsView().state() 返回纯只读实时真值:\n    · phase;result:null | 'lose'\n    · score:整数,已穿过管道数(开局必为 0)\n    · bird:{ x, y, vy }(小鸟中心逻辑像素坐标与竖直速度;y 向下为正,实时)\n    · nextGap:{ x, centerY }(小鸟前方最近一对管道【缝隙竖直中点】的 x 与 y 逻辑像素;缝隙中心 y 务必准确,harness 据此控制拍翅;无管道时为 null)。\n  harness 读 bird.y 与 nextGap.centerY 自动拍翅穿缝:鸟低于缝中心就拍、高于则任其下落。\n- 反馈(juice):拍翅 / 得分 / 撞击触发 getEngine().particles.spawnEmitter + getEngine().audio.synth.synthSfx。\n- 画面:深色背景铺满 390×844;小鸟 / 管道 / 文字亮色实心。",
+  "brief": "做一款经典 Flappy Bird。竖屏逻辑视口 390×844(坐标 y 向下为正:y 越大越靠近屏幕底部)。\n- 小鸟固定在屏幕左侧 x≈110,受【适中】重力持续下落;点击任意位置 = 小鸟获得一个向上的瞬时速度(拍翅)。**拍翅力度与重力要平衡**:玩家能轻松让小鸟在屏内上下浮动,不会一拍就冲顶、也不会一松就坠底;开局小鸟稳定悬浮在屏幕中部附近等待操作。\n- 成对的上下管道从右向左匀速滚动;缝隙【宽松】——垂直缺口高度 ≥ 屏高的 24%;管道水平间距给足反应时间:开局到第一对管道 ≥ 1.5 秒,之后每对间距稳定。小鸟从缝隙穿过 = 得分 +1。缝隙中心 y 随机落在中部可达区间(约 [300, 560]),勿贴顶/贴底致正常拍翅无法穿越。\n- 撞到管道 / 触顶 / 触底 = 失败。\n- 顶部文本 HUD:得分 / 状态。\n- 【终态契约·务必遵守】失败即把 _forensicsView().state().phase 置 'gameover' 并【驻留】(显示结果 + 「点击重玩」提示);玩家点击重玩前 phase 必须恒为 'gameover',**绝不自动重开 / 不下一帧复位**(宿主每 500ms 轮询 phase 判结束)。gameover 下点击一律忽略;仅「重玩」按钮重开。\n- 【可测性·务必导出状态】_forensicsView().state() 返回纯只读实时真值:\n    · phase;result:null | 'lose'\n    · score:整数,已穿过管道数(开局必为 0)\n    · bird:{ x, y, vy }(小鸟中心逻辑像素坐标与竖直速度;y 向下为正,实时)\n    · nextGap:{ x, centerY }(小鸟前方最近一对管道【缝隙竖直中点】的 x 与 y 逻辑像素;缝隙中心 y 务必准确,harness 据此控制拍翅;无管道时为 null)。\n  harness 读 bird.y 与 nextGap.centerY 自动拍翅穿缝:鸟低于缝中心就拍、高于则任其下落。\n- 反馈(juice):拍翅 / 得分 / 撞击触发 getEngine().particles.spawnEmitter + getEngine().audio.synth.synthSfx。\n- 画面:深色背景铺满 390×844;小鸟 / 管道 / 文字亮色实心。",
   "play_spec": {
-    "driver": { "type": "flap-to-gap", "steps": 70, "stepMs": 110, "margin": 14 },
+    "driver": { "type": "flap-to-gap", "steps": 100, "stepMs": 90, "margin": 14, "lookahead": 0.18, "aimBias": 24, "vyPath": "bird.vy" },
     "expectedEngineCallPrefixes": ["particles.", "audio.synth"],
     "assertAfterPlay": [
       { "path": "score", "op": "increased", "why": "适配性真玩(读 bird.y/nextGap.centerY 拍翅穿缝)→得分上升;物理太硬秒死或穿不过则 0" }
diff --git a/wg1/gen-worker/briefs/multiball.json b/wg1/gen-worker/briefs/multiball.json
index 5d29af9d..4b0ba046 100644
--- a/wg1/gen-worker/briefs/multiball.json
+++ b/wg1/gen-worker/briefs/multiball.json
@@ -1,9 +1,9 @@
 {
   "title": "多球弹球 Multiball",
-  "brief": "做一款多球打砖块变体。竖屏逻辑视口 390×844。\n- 底部一块玩家挡板(水平移动,厚度≥14)。开局有 2~3 个球同时斜向匀速运动,碰墙/挡板反弹(碰挡板按击中位置调水平速度)。\n- 顶部一片砖块网格;任一球击中砖块→该砖消除、得分 +1。部分砖被击碎后掉落道具(下落,挡板接到=增球或扩板)。\n- 所有球都掉到挡板下方 = 失败;清光所有砖 = 通关。\n- 命中砖块触发屏震 + 闪白(getEngine().particles.shakeScreen / flashScreen 或 spawnEmitter)。\n- 【CCD 注意】球速较快,碰撞请沿速度向量做连续检测,避免高速球穿砖/穿墙。\n- 球速:合速度约每秒 320~420 逻辑像素。\n- 【终态契约·务必遵守】失败/通关即把 phase 置 'gameover' 并【驻留】(结果 + 「点击重玩」);点击重玩前 phase 恒 'gameover',绝不自动重开 / 不下一帧复位。gameover 下点击忽略。\n- 【控制·务必跟手】挡板朝触摸点 x 平滑逼近(每帧插值 0.2~0.35),绝非一格一跳。\n- 【可测性·务必导出状态】_forensicsView().state() 纯只读实时真值:phase;result(null|'win'|'lose');score;remaining(剩余砖数);ball:{x,y,vx,vy}(任选一个【活跃主球】的位置,供 harness 挡板接球用,实时);paddle:{x,y,w};balls:[{x,y}...](所有活跃球,可选)。harness 读 ball.x 自动移挡板接球、据 remaining/phase 验进展与终局。\n- 反馈(juice):击砖/接道具/掉球触发 getEngine().particles.spawnEmitter + getEngine().audio.synth.synthSfx。\n- 画面:深色背景铺满;挡板/砖/球/道具/文字亮色实心。",
+  "brief": "做一款多球打砖块变体。竖屏逻辑视口 390×844。\n- 底部一块玩家挡板(水平移动,厚度≥14)。开局有 2~3 个球同时斜向匀速运动,碰墙/挡板反弹(碰挡板按击中位置调水平速度)。\n- 顶部一片砖块网格;任一球击中砖块→该砖消除、得分 +1。部分砖被击碎后掉落道具(下落,挡板接到=增球或扩板)。\n- 任一球 y 越过屏幕底沿即出局丢失(绝不在底部反弹回弹);所有球都掉到挡板下方出局 = 失败;清光所有砖 = 通关。\n- 命中砖块触发屏震 + 闪白(getEngine().particles.shakeScreen / flashScreen 或 spawnEmitter)。\n- 【CCD 注意】球速较快,碰撞请沿速度向量做连续检测,避免高速球穿砖/穿墙。\n- 球速:合速度约每秒 320~420 逻辑像素。\n- 【终态契约·务必遵守】失败/通关即把 phase 置 'gameover' 并【驻留】(结果 + 「点击重玩」);点击重玩前 phase 恒 'gameover',绝不自动重开 / 不下一帧复位。gameover 下点击忽略。\n- 【控制·务必跟手】挡板朝触摸点 x 平滑逼近(每帧插值 0.2~0.35),绝非一格一跳。\n- 【可测性·务必导出状态】_forensicsView().state() 纯只读实时真值:phase;result(null|'win'|'lose');score;remaining(剩余砖数);ball:{x,y,vx,vy}(任选一个【活跃主球】的位置,供 harness 挡板接球用,实时);paddle:{x,y,w};balls:[{x,y}...](所有活跃球,可选)。harness 读 ball.x 自动移挡板接球、据 remaining/phase 验进展与终局。\n- 反馈(juice):击砖/接道具/掉球触发 getEngine().particles.spawnEmitter + getEngine().audio.synth.synthSfx。\n- 画面:深色背景铺满;挡板/砖/球/道具/文字亮色实心。",
   "play_spec": {
     "controlCheck": { "paddlePath": "paddle.x", "paddleY": 800, "tapXs": [50, 340], "tapsPerTarget": 6, "moveMin": 25, "tolerance": 70 },
-    "driver": { "type": "paddle-intercept", "ballPath": "ball.x", "paddleY": 800, "steps": 70, "stepMs": 130 },
+    "driver": { "type": "paddle-intercept", "ballPath": "ball.x", "paddleY": 800, "steps": 80, "stepMs": 130, "drainAfter": 48, "drainX": 10 },
     "expectedEngineCallPrefixes": ["particles.", "audio.synth"],
     "assertAfterPlay": [
       { "path": "remaining", "op": "decreased", "why": "多球+挡板接球击碎砖→剩余下降;碰撞失效/高速穿透(CCD缺)则不降" }
diff --git a/wg1/gen-worker/results/angrybirds.json b/wg1/gen-worker/results/angrybirds.json
index 15e31a81..108de944 100644
--- a/wg1/gen-worker/results/angrybirds.json
+++ b/wg1/gen-worker/results/angrybirds.json
@@ -1,22 +1,22 @@
 {
   "game_id": "angrybirds",
   "model": "deepseek-v4-flash",
-  "pass": false,
-  "retries": 2,
+  "pass": true,
+  "retries": 0,
   "attempts": [
     {
       "attempt": 0,
       "stage": "play",
       "errors": [],
       "usage": {
-        "prompt_tokens": 3891,
-        "completion_tokens": 6038,
-        "total_tokens": 9929,
-        "wall_s": 46.865,
-        "id": "59e5581e-5e69-4962-83de-2b10baf138f3",
+        "prompt_tokens": 4056,
+        "completion_tokens": 7791,
+        "total_tokens": 11847,
+        "wall_s": 275.038,
+        "id": "1a79807c-f2f9-494e-b72c-83fe47163d6c",
         "finish_reason": "stop"
       },
-      "play_pass": false,
+      "play_pass": true,
       "verdict_guards": {
         "A_boot": true,
         "C_frame": true,
@@ -26,57 +26,7 @@
         "B_uncaught": true,
         "F_wiring": true,
         "G_input": true,
-        "H_progress": false
-      }
-    },
-    {
-      "attempt": 1,
-      "stage": "play",
-      "errors": [],
-      "usage": {
-        "prompt_tokens": 4028,
-        "completion_tokens": 8065,
-        "total_tokens": 12093,
-        "wall_s": 63.229,
-        "id": "ebb8533e-2126-4a5e-a3ab-bea50d034130",
-        "finish_reason": "stop"
-      },
-      "play_pass": false,
-      "verdict_guards": {
-        "A_boot": true,
-        "C_frame": true,
-        "I_control": true,
-        "D_render": true,
-        "E_live": true,
-        "B_uncaught": true,
-        "F_wiring": true,
-        "G_input": true,
-        "H_progress": false
-      }
-    },
-    {
-      "attempt": 2,
-      "stage": "play",
-      "errors": [],
-      "usage": {
-        "prompt_tokens": 4028,
-        "completion_tokens": 7180,
-        "total_tokens": 11208,
-        "wall_s": 51.572,
-        "id": "2e3428c1-1be1-4adc-bc19-a75407de7be9",
-        "finish_reason": "stop"
-      },
-      "play_pass": false,
-      "verdict_guards": {
-        "A_boot": true,
-        "C_frame": true,
-        "I_control": true,
-        "D_render": true,
-        "E_live": true,
-        "B_uncaught": true,
-        "F_wiring": true,
-        "G_input": true,
-        "H_progress": false
+        "H_progress": true
       }
     }
   ],
@@ -92,9 +42,9 @@
       },
       "C_frame": {
         "pass": true,
-        "f0": 48,
-        "f1": 78,
-        "delta": 30
+        "f0": 49,
+        "f1": 80,
+        "delta": 31
       },
       "I_control": {
         "pass": true,
@@ -102,13 +52,13 @@
       },
       "D_render": {
         "pass": true,
-        "bright": 34719,
+        "bright": 24407,
         "maxCh": 255
       },
       "E_live": {
         "pass": true,
-        "distinctStates": 10,
-        "samples": 15
+        "distinctStates": 3,
+        "samples": 3
       },
       "B_uncaught": {
         "pass": true,
@@ -116,12 +66,9 @@
       },
       "F_wiring": {
         "pass": true,
-        "callCount": 18,
+        "callCount": 9,
         "sample": [
           "particles.spawnEmitter",
-          "audio.synth.synthSfx",
-          "particles.spawnEmitter",
-          "audio.synth.synthSfx",
           "particles.spawnEmitter",
           "audio.synth.synthSfx",
           "particles.spawnEmitter",
@@ -138,18 +85,21 @@
       },
       "G_input": {
         "pass": true,
-        "skipped": "无 tap/key 输入"
+        "inputHash": "9aa44a5c",
+        "controlHash": "729b6a77",
+        "atFrame": 260,
+        "ctrlFrame": 265
       },
       "H_progress": {
-        "pass": false,
+        "pass": true,
         "checks": [
           {
             "path": "score",
             "op": "increased",
             "before": 0,
-            "after": 0,
-            "pass": false,
-            "why": "盲态固定拖拽发射→偶中目标得分;若固定角度打不中(需读目标算拖拽矢量)则不升=暴露拖拽瞄准缺口"
+            "after": 20,
+            "pass": true,
+            "why": "drag-aiming 读 launch 物理常数(gravity/powerScale)45° 抛解析反解拖拽矢量→命中猪得分上升;游戏暴露物理即可确定性瞄准(asteroids 式『暴露即可测』);若仍 0=物理未按 pin 实现"
           }
         ],
         "latch": {
@@ -162,54 +112,43 @@
           "phase": "playing",
           "result": null,
           "score": 0,
-          "birdsLeft": 4,
+          "birdsLeft": 5,
           "targets": [
             {
-              "x": 290,
-              "y": 560
+              "x": 320,
+              "y": 650
             },
             {
-              "x": 310,
-              "y": 520
-            },
-            {
-              "x": 280,
-              "y": 480
+              "x": 340,
+              "y": 700
             }
-          ]
+          ],
+          "launch": {
+            "gravity": 1200,
+            "powerScale": 8
+          }
         },
         "state1": {
           "phase": "gameover",
-          "result": "lose",
-          "score": 0,
-          "birdsLeft": 0,
-          "targets": [
-            {
-              "x": 290,
-              "y": 560
-            },
-            {
-              "x": 310,
-              "y": 520
-            },
-            {
-              "x": 280,
-              "y": 480
-            }
-          ]
+          "result": "win",
+          "score": 20,
+          "birdsLeft": 5,
+          "targets": [],
+          "launch": {
+            "gravity": 1200,
+            "powerScale": 8
+          }
         }
       }
     },
-    "pass": false,
+    "pass": true,
     "notes": []
   },
   "tokens": {
-    "prompt": 11947,
-    "completion": 21283
+    "prompt": 4056,
+    "completion": 7791
   },
   "request_ids": [
-    "59e5581e-5e69-4962-83de-2b10baf138f3",
-    "ebb8533e-2126-4a5e-a3ab-bea50d034130",
-    "2e3428c1-1be1-4adc-bc19-a75407de7be9"
+    "1a79807c-f2f9-494e-b72c-83fe47163d6c"
   ]
 }
\ No newline at end of file
diff --git a/wg1/gen-worker/results/asteroids.json b/wg1/gen-worker/results/asteroids.json
index b6f1889d..3e736ce9 100644
--- a/wg1/gen-worker/results/asteroids.json
+++ b/wg1/gen-worker/results/asteroids.json
@@ -1,47 +1,22 @@
 {
   "game_id": "asteroids",
   "model": "deepseek-v4-flash",
-  "pass": false,
-  "retries": 2,
+  "pass": true,
+  "retries": 0,
   "attempts": [
     {
       "attempt": 0,
       "stage": "play",
       "errors": [],
       "usage": {
-        "prompt_tokens": 3905,
-        "completion_tokens": 8225,
-        "total_tokens": 12130,
-        "wall_s": 98.632,
-        "id": "e0b13e0d-3a3c-49e3-9b8f-3fda547153dd",
+        "prompt_tokens": 3966,
+        "completion_tokens": 10009,
+        "total_tokens": 13975,
+        "wall_s": 118.648,
+        "id": "98a2a1a3-f11d-4bfc-8c4a-1bd0ba3d8370",
         "finish_reason": "stop"
       },
-      "play_pass": false,
-      "verdict_guards": {
-        "A_boot": true,
-        "C_frame": true,
-        "I_control": true,
-        "D_render": true,
-        "E_live": true,
-        "B_uncaught": true,
-        "F_wiring": false,
-        "G_input": true,
-        "H_progress": false
-      }
-    },
-    {
-      "attempt": 1,
-      "stage": "play",
-      "errors": [],
-      "usage": {
-        "prompt_tokens": 4078,
-        "completion_tokens": 8972,
-        "total_tokens": 13050,
-        "wall_s": 101.377,
-        "id": "c2b6f24b-41f7-45de-9d3a-0b3723e79aa3",
-        "finish_reason": "stop"
-      },
-      "play_pass": false,
+      "play_pass": true,
       "verdict_guards": {
         "A_boot": true,
         "C_frame": true,
@@ -51,32 +26,7 @@
         "B_uncaught": true,
         "F_wiring": true,
         "G_input": true,
-        "H_progress": false
-      }
-    },
-    {
-      "attempt": 2,
-      "stage": "play",
-      "errors": [],
-      "usage": {
-        "prompt_tokens": 4041,
-        "completion_tokens": 11024,
-        "total_tokens": 15065,
-        "wall_s": 91.997,
-        "id": "ea98e889-f96b-42d8-8c0e-691432017bc1",
-        "finish_reason": "stop"
-      },
-      "play_pass": false,
-      "verdict_guards": {
-        "A_boot": true,
-        "C_frame": true,
-        "I_control": true,
-        "D_render": true,
-        "E_live": true,
-        "B_uncaught": true,
-        "F_wiring": false,
-        "G_input": true,
-        "H_progress": false
+        "H_progress": true
       }
     }
   ],
@@ -93,8 +43,8 @@
       "C_frame": {
         "pass": true,
         "f0": 49,
-        "f1": 79,
-        "delta": 30
+        "f1": 80,
+        "delta": 31
       },
       "I_control": {
         "pass": true,
@@ -102,22 +52,35 @@
       },
       "D_render": {
         "pass": true,
-        "bright": 66529,
+        "bright": 73961,
         "maxCh": 255
       },
       "E_live": {
         "pass": true,
-        "distinctStates": 52,
-        "samples": 52
+        "distinctStates": 81,
+        "samples": 81
       },
       "B_uncaught": {
         "pass": true,
         "uncaught": []
       },
       "F_wiring": {
-        "pass": false,
-        "callCount": 0,
-        "sample": [],
+        "pass": true,
+        "callCount": 41,
+        "sample": [
+          "particles.spawnEmitter",
+          "particles.spawnEmitter",
+          "audio.synth.synthSfx",
+          "particles.spawnEmitter",
+          "audio.synth.synthSfx",
+          "particles.spawnEmitter",
+          "audio.synth.synthSfx",
+          "particles.spawnEmitter",
+          "audio.synth.synthSfx",
+          "particles.spawnEmitter",
+          "audio.synth.synthSfx",
+          "particles.spawnEmitter"
+        ],
         "expected": [
           "particles.",
           "audio.synth"
@@ -125,62 +88,113 @@
       },
       "G_input": {
         "pass": true,
-        "inputHash": "241aa975",
-        "controlHash": "7f223357",
-        "atFrame": 1241,
-        "ctrlFrame": 1244
+        "inputHash": "abb370ce",
+        "controlHash": "38e0cc7c",
+        "atFrame": 1581,
+        "ctrlFrame": -1
       },
       "H_progress": {
-        "pass": false,
+        "pass": true,
         "checks": [
           {
             "path": "score",
             "op": "increased",
             "before": 0,
-            "after": 0,
-            "pass": false,
-            "why": "循环旋转+推进+开火→击碎陨石得分上升;若高速子弹穿透(CCD缺)或打不中则不升=暴露 CCD 缺口"
+            "after": 6,
+            "pass": true,
+            "why": "aim-fire 读陨石坐标旋向对齐开火→击碎得分上升;若游戏不暴露陨石坐标致盲射则不升=可测性边界"
           }
         ],
         "latch": {
-          "pass": false,
-          "reason": "真玩未到达 gameover 终态(终态不可达/无失败态/play-spec 未驱动到结束)",
-          "phaseNow": "playing"
+          "pass": true,
+          "dwelledMs": 600,
+          "after": "gameover",
+          "reason": ""
         },
         "state0": {
           "phase": "playing",
           "result": null,
           "score": 0,
-          "asteroidsRemaining": 5,
+          "asteroidsRemaining": 6,
           "ship": {
             "x": 195,
             "y": 422,
             "angle": -1.5707963267948966
-          }
+          },
+          "asteroids": [
+            {
+              "x": 96.99717124909638,
+              "y": 519.2675040247642
+            },
+            {
+              "x": 319.4950147635825,
+              "y": 629.6736080402688
+            },
+            {
+              "x": 1.5485410220474345,
+              "y": 718.9562386134752
+            },
+            {
+              "x": 73.61813029544744,
+              "y": 761.5286812129356
+            },
+            {
+              "x": 337.5254555930884,
+              "y": 529.2215852456798
+            },
+            {
+              "x": 324.4826751629315,
+              "y": 697.42908304362
+            }
+          ]
         },
         "state1": {
-          "phase": "playing",
-          "result": null,
-          "score": 0,
-          "asteroidsRemaining": 5,
+          "phase": "gameover",
+          "result": "lose",
+          "score": 6,
+          "asteroidsRemaining": 6,
           "ship": {
             "x": 195,
             "y": 422,
-            "angle": -1.5707963267948966
-          }
+            "angle": -3.120796326794893
+          },
+          "asteroids": [
+            {
+              "x": -27.856391456713904,
+              "y": 735.1075081715107
+            },
+            {
+              "x": 116.74067642420584,
+              "y": 770.5545437859361
+            },
+            {
+              "x": 166.3536431747016,
+              "y": 455.6770210725548
+            },
+            {
+              "x": 272.7968611275529,
+              "y": 641.2863973557977
+            },
+            {
+              "x": 171.07105373838698,
+              "y": 848.8609648800336
+            },
+            {
+              "x": 213.6553002398836,
+              "y": 87.47766219533963
+            }
+          ]
         }
       }
     },
-    "pass": false,
+    "pass": true,
     "notes": []
   },
   "tokens": {
-    "prompt": 12024,
-    "completion": 28221
+    "prompt": 3966,
+    "completion": 10009
   },
   "request_ids": [
-    "e0b13e0d-3a3c-49e3-9b8f-3fda547153dd",
-    "c2b6f24b-41f7-45de-9d3a-0b3723e79aa3",
-    "ea98e889-f96b-42d8-8c0e-691432017bc1"
+    "98a2a1a3-f11d-4bfc-8c4a-1bd0ba3d8370"
   ]
 }
\ No newline at end of file
diff --git a/wg1/gen-worker/results/flappy.json b/wg1/gen-worker/results/flappy.json
index 6f7d89ab..c59fb735 100644
--- a/wg1/gen-worker/results/flappy.json
+++ b/wg1/gen-worker/results/flappy.json
@@ -1,7 +1,7 @@
 {
   "game_id": "flappy",
-  "model": "deepseek-v4-pro",
-  "pass": false,
+  "model": "deepseek-v4-flash",
+  "pass": true,
   "retries": 2,
   "attempts": [
     {
@@ -9,11 +9,11 @@
       "stage": "play",
       "errors": [],
       "usage": {
-        "prompt_tokens": 4029,
-        "completion_tokens": 8475,
-        "total_tokens": 12504,
-        "wall_s": 143.451,
-        "id": "6a71d430-00e3-4772-9b81-1228bc19bf59",
+        "prompt_tokens": 4060,
+        "completion_tokens": 8280,
+        "total_tokens": 12340,
+        "wall_s": 291.239,
+        "id": "ace28b05-5cab-405f-9a94-891cb9ebdb6f",
         "finish_reason": "stop"
       },
       "play_pass": false,
@@ -25,33 +25,23 @@
         "E_live": true,
         "B_uncaught": true,
         "F_wiring": true,
-        "G_input": true,
+        "G_input": false,
         "H_progress": false
       }
     },
     {
       "attempt": 1,
-      "stage": "play",
-      "errors": [],
+      "stage": "validate",
+      "errors": [
+        "违禁:禁 Date.now(用 ctx.time.nowMs)"
+      ],
       "usage": {
-        "prompt_tokens": 4163,
-        "completion_tokens": 7746,
-        "total_tokens": 11909,
-        "wall_s": 316.381,
-        "id": "5c3db979-5f22-4b7e-bde8-62d2c07e9071",
+        "prompt_tokens": 4242,
+        "completion_tokens": 5776,
+        "total_tokens": 10018,
+        "wall_s": 74.574,
+        "id": "e94fa6f0-1e0a-4163-a3f9-476480d82641",
         "finish_reason": "stop"
-      },
-      "play_pass": false,
-      "verdict_guards": {
-        "A_boot": true,
-        "C_frame": true,
-        "I_control": true,
-        "D_render": true,
-        "E_live": true,
-        "B_uncaught": true,
-        "F_wiring": true,
-        "G_input": true,
-        "H_progress": false
       }
     },
     {
@@ -59,14 +49,14 @@
       "stage": "play",
       "errors": [],
       "usage": {
-        "prompt_tokens": 4163,
-        "completion_tokens": 7230,
-        "total_tokens": 11393,
-        "wall_s": 125.343,
-        "id": "97b8fe12-616d-41bc-b60a-6c32efe20a6d",
+        "prompt_tokens": 4106,
+        "completion_tokens": 8529,
+        "total_tokens": 12635,
+        "wall_s": 95.039,
+        "id": "030f4ab8-f4e1-44ad-88ad-516ffe78d673",
         "finish_reason": "stop"
       },
-      "play_pass": false,
+      "play_pass": true,
       "verdict_guards": {
         "A_boot": true,
         "C_frame": true,
@@ -76,7 +66,7 @@
         "B_uncaught": true,
         "F_wiring": true,
         "G_input": true,
-        "H_progress": false
+        "H_progress": true
       }
     }
   ],
@@ -92,8 +82,8 @@
       },
       "C_frame": {
         "pass": true,
-        "f0": 48,
-        "f1": 78,
+        "f0": 51,
+        "f1": 81,
         "delta": 30
       },
       "I_control": {
@@ -102,13 +92,13 @@
       },
       "D_render": {
         "pass": true,
-        "bright": 178920,
+        "bright": 189671,
         "maxCh": 255
       },
       "E_live": {
         "pass": true,
-        "distinctStates": 6,
-        "samples": 6
+        "distinctStates": 40,
+        "samples": 41
       },
       "B_uncaught": {
         "pass": true,
@@ -116,7 +106,7 @@
       },
       "F_wiring": {
         "pass": true,
-        "callCount": 8,
+        "callCount": 44,
         "sample": [
           "particles.spawnEmitter",
           "audio.synth.synthSfx",
@@ -125,6 +115,10 @@
           "particles.spawnEmitter",
           "audio.synth.synthSfx",
           "particles.spawnEmitter",
+          "audio.synth.synthSfx",
+          "particles.spawnEmitter",
+          "audio.synth.synthSfx",
+          "particles.spawnEmitter",
           "audio.synth.synthSfx"
         ],
         "expected": [
@@ -134,20 +128,20 @@
       },
       "G_input": {
         "pass": true,
-        "inputHash": "0e133ce8",
-        "controlHash": "4fb72d48",
-        "atFrame": 214,
-        "ctrlFrame": 218
+        "inputHash": "4ae5c2e6",
+        "controlHash": "aad4cfb2",
+        "atFrame": 749,
+        "ctrlFrame": 750
       },
       "H_progress": {
-        "pass": false,
+        "pass": true,
         "checks": [
           {
             "path": "score",
             "op": "increased",
             "before": 0,
-            "after": 0,
-            "pass": false,
+            "after": 5,
+            "pass": true,
             "why": "适配性真玩(读 bird.y/nextGap.centerY 拍翅穿缝)→得分上升;物理太硬秒死或穿不过则 0"
           }
         ],
@@ -163,42 +157,43 @@
           "score": 0,
           "bird": {
             "x": 110,
-            "y": 559.1999999999999,
-            "vy": 336
-          },
-          "nextGap": {
-            "x": 600,
-            "centerY": 174.12938179075718
+            "y": 422,
+            "vy": 0
           },
+          "nextGap": null,
+          "remaining": 0,
+          "progress": null,
           "gameoverReason": ""
         },
         "state1": {
           "phase": "gameover",
           "result": "lose",
-          "score": 0,
+          "score": 5,
           "bird": {
             "x": 110,
-            "y": 523.0999999999999,
-            "vy": -169
+            "y": 405.6666666666665,
+            "vy": -116.66666666666673
           },
           "nextGap": {
-            "x": 600,
-            "centerY": 174.12938179075718
+            "x": 120,
+            "centerY": 302.81019813381135
           },
-          "gameoverReason": "pipe_collision"
+          "remaining": 1,
+          "progress": null,
+          "gameoverReason": "pipe"
         }
       }
     },
-    "pass": false,
+    "pass": true,
     "notes": []
   },
   "tokens": {
-    "prompt": 12355,
-    "completion": 23451
+    "prompt": 12408,
+    "completion": 22585
   },
   "request_ids": [
-    "6a71d430-00e3-4772-9b81-1228bc19bf59",
-    "5c3db979-5f22-4b7e-bde8-62d2c07e9071",
-    "97b8fe12-616d-41bc-b60a-6c32efe20a6d"
+    "ace28b05-5cab-405f-9a94-891cb9ebdb6f",
+    "e94fa6f0-1e0a-4163-a3f9-476480d82641",
+    "030f4ab8-f4e1-44ad-88ad-516ffe78d673"
   ]
 }
\ No newline at end of file
diff --git a/wg1/gen-worker/results/multiball.json b/wg1/gen-worker/results/multiball.json
index 0c0373a5..abaf0b1e 100644
--- a/wg1/gen-worker/results/multiball.json
+++ b/wg1/gen-worker/results/multiball.json
@@ -1,72 +1,22 @@
 {
   "game_id": "multiball",
   "model": "deepseek-v4-flash",
-  "pass": false,
-  "retries": 2,
+  "pass": true,
+  "retries": 0,
   "attempts": [
     {
       "attempt": 0,
       "stage": "play",
       "errors": [],
       "usage": {
-        "prompt_tokens": 3991,
-        "completion_tokens": 13015,
-        "total_tokens": 17006,
-        "wall_s": 114.807,
-        "id": "49098ea1-7ede-4e09-9e08-13f6dbdc486d",
+        "prompt_tokens": 4013,
+        "completion_tokens": 12724,
+        "total_tokens": 16737,
+        "wall_s": 129.522,
+        "id": "2e8c56b4-8545-4607-8206-a1d26d6fcfd4",
         "finish_reason": "stop"
       },
-      "play_pass": false,
-      "verdict_guards": {
-        "A_boot": true,
-        "C_frame": true,
-        "I_control": false,
-        "D_render": true,
-        "E_live": true,
-        "B_uncaught": true,
-        "F_wiring": true,
-        "G_input": true,
-        "H_progress": true
-      }
-    },
-    {
-      "attempt": 1,
-      "stage": "play",
-      "errors": [],
-      "usage": {
-        "prompt_tokens": 4118,
-        "completion_tokens": 7988,
-        "total_tokens": 12106,
-        "wall_s": 86.921,
-        "id": "afc6dad5-f0d3-4ded-b783-70ceffd60aca",
-        "finish_reason": "stop"
-      },
-      "play_pass": false,
-      "verdict_guards": {
-        "A_boot": true,
-        "C_frame": true,
-        "I_control": false,
-        "D_render": true,
-        "E_live": true,
-        "B_uncaught": true,
-        "F_wiring": true,
-        "G_input": true,
-        "H_progress": true
-      }
-    },
-    {
-      "attempt": 2,
-      "stage": "play",
-      "errors": [],
-      "usage": {
-        "prompt_tokens": 4116,
-        "completion_tokens": 14371,
-        "total_tokens": 18487,
-        "wall_s": 155.242,
-        "id": "abc8fb1c-3c77-478e-bdaa-ec0774104d96",
-        "finish_reason": "stop"
-      },
-      "play_pass": false,
+      "play_pass": true,
       "verdict_guards": {
         "A_boot": true,
         "C_frame": true,
@@ -76,7 +26,7 @@
         "B_uncaught": true,
         "F_wiring": true,
         "G_input": true,
-        "H_progress": false
+        "H_progress": true
       }
     }
   ],
@@ -92,9 +42,9 @@
       },
       "C_frame": {
         "pass": true,
-        "f0": 46,
-        "f1": 75,
-        "delta": 29
+        "f0": 49,
+        "f1": 79,
+        "delta": 30
       },
       "I_control": {
         "pass": true,
@@ -102,31 +52,31 @@
         "results": [
           {
             "tapX": 50,
-            "before": 194.99999999990354,
-            "after": 50,
-            "moved": -144.99999999990354,
-            "distToTarget": 0,
+            "before": 195,
+            "after": 54.09589111049999,
+            "moved": -140.9041088895,
+            "distToTarget": 4.095891110499991,
             "pass": true
           },
           {
             "tapX": 340,
-            "before": 50,
-            "after": 310,
-            "moved": 260,
-            "distToTarget": 30,
+            "before": 54.09589111049999,
+            "after": 306.3636674932592,
+            "moved": 252.2677763827592,
+            "distToTarget": 33.636332506740814,
             "pass": true
           }
         ]
       },
       "D_render": {
         "pass": true,
-        "bright": 146201,
+        "bright": 154512,
         "maxCh": 255
       },
       "E_live": {
         "pass": true,
-        "distinctStates": 64,
-        "samples": 72
+        "distinctStates": 15,
+        "samples": 15
       },
       "B_uncaught": {
         "pass": true,
@@ -134,10 +84,10 @@
       },
       "F_wiring": {
         "pass": true,
-        "callCount": 15,
+        "callCount": 27,
         "sample": [
-          "audio.synth.synthSfx",
-          "audio.synth.synthSfx",
+          "particles.spawnEmitter",
+          "particles.spawnEmitter",
           "audio.synth.synthSfx",
           "particles.spawnEmitter",
           "audio.synth.synthSfx",
@@ -145,8 +95,8 @@
           "audio.synth.synthSfx",
           "particles.spawnEmitter",
           "audio.synth.synthSfx",
-          "audio.synth.synthSfx",
           "particles.spawnEmitter",
+          "audio.synth.synthSfx",
           "particles.spawnEmitter"
         ],
         "expected": [
@@ -156,106 +106,88 @@
       },
       "G_input": {
         "pass": true,
-        "inputHash": "9cd794ce",
-        "controlHash": "6afc48cc",
-        "atFrame": 1984,
-        "ctrlFrame": -1
+        "inputHash": "7a86cc2e",
+        "controlHash": "b60e0fa8",
+        "atFrame": 615,
+        "ctrlFrame": 620
       },
       "H_progress": {
-        "pass": false,
+        "pass": true,
         "checks": [
           {
             "path": "remaining",
             "op": "decreased",
-            "before": 40,
-            "after": 36,
+            "before": 78,
+            "after": 69,
             "pass": true,
             "why": "多球+挡板接球击碎砖→剩余下降;碰撞失效/高速穿透(CCD缺)则不降"
           }
         ],
         "latch": {
-          "pass": false,
-          "reason": "真玩未到达 gameover 终态(终态不可达/无失败态/play-spec 未驱动到结束)",
-          "phaseNow": "playing"
+          "pass": true,
+          "dwelledMs": 600,
+          "after": "gameover",
+          "reason": ""
         },
         "state0": {
           "phase": "playing",
           "result": null,
           "score": 0,
-          "remaining": 40,
-          "progress": 0,
-          "gameoverReason": "",
+          "remaining": 78,
           "ball": {
-            "x": 171,
-            "y": 793,
-            "vx": -103.2459330675854,
-            "vy": 317.75830848240577
+            "x": 178.39632164686918,
+            "y": 772.8069677809253,
+            "vx": -149.90107628982514,
+            "vy": -312.5555661244529
           },
           "paddle": {
-            "x": 194.99999700380667,
-            "y": 804,
+            "x": 195,
+            "y": 810,
             "w": 80
           },
           "balls": [
             {
-              "x": 171,
-              "y": 793
+              "x": 55.977109343511984,
+              "y": 517.5532554459528
             },
             {
-              "x": 187,
-              "y": 793
+              "x": 212.95210833312012,
+              "y": 465.970216069029
             },
             {
-              "x": 203,
-              "y": 793
+              "x": 199.6740988851525,
+              "y": 475.6221190751453
             }
           ]
         },
         "state1": {
-          "phase": "playing",
-          "result": null,
-          "score": 4,
-          "remaining": 36,
-          "progress": 0,
-          "gameoverReason": "",
+          "phase": "gameover",
+          "result": "lose",
+          "score": 9,
+          "remaining": 69,
           "ball": {
-            "x": 171,
-            "y": 793,
-            "vx": -103.2459330675854,
-            "vy": 317.75830848240577
+            "x": 178.39632164686918,
+            "y": 772.8069677809253,
+            "vx": -149.90107628982514,
+            "vy": -312.5555661244529
           },
           "paddle": {
-            "x": 171.00000000000003,
-            "y": 804,
+            "x": 179.63617952826013,
+            "y": 810,
             "w": 80
           },
-          "balls": [
-            {
-              "x": 171,
-              "y": 793
-            },
-            {
-              "x": 187,
-              "y": 793
-            },
-            {
-              "x": 203,
-              "y": 793
-            }
-          ]
+          "balls": []
         }
       }
     },
-    "pass": false,
+    "pass": true,
     "notes": []
   },
   "tokens": {
-    "prompt": 12225,
-    "completion": 35374
+    "prompt": 4013,
+    "completion": 12724
   },
   "request_ids": [
-    "49098ea1-7ede-4e09-9e08-13f6dbdc486d",
-    "afc6dad5-f0d3-4ded-b783-70ceffd60aca",
-    "abc8fb1c-3c77-478e-bdaa-ec0774104d96"
+    "2e8c56b4-8545-4607-8206-a1d26d6fcfd4"
   ]
 }
\ No newline at end of file
diff --git a/wg1/gen-worker/worker/prompt.py b/wg1/gen-worker/worker/prompt.py
index a1ae88c0..e66d1d5c 100644
--- a/wg1/gen-worker/worker/prompt.py
+++ b/wg1/gen-worker/worker/prompt.py
@@ -1,7 +1,7 @@
 """prompt.py —— W-G1 生成上下文包:把装载契约/能力面/禁用项/硬规则蒸馏成 system prompt + few-shot。
 
 来源:理解阶段 7 份地图的综合(engine-caps/load-contract/ref-shape/plugin-surface)。
-原则:把便宜模型的活压到最小——只产出一个【纯工厂模块】,能力恒经 boot.ctx,质量由 harness 六门兜。
+原则:把便宜模型的活压到最小——只产出一个【纯工厂模块】,能力恒经 boot.ctx,质量由 harness 九门兜。
 """
 
 from pathlib import Path
diff --git a/wg1/gen-worker/worker/run.py b/wg1/gen-worker/worker/run.py
index 345dbca1..7987bf10 100644
--- a/wg1/gen-worker/worker/run.py
+++ b/wg1/gen-worker/worker/run.py
@@ -3,7 +3,7 @@
 job in :brief(题面 + play-spec)+ model + max_retries
 result:{ pass, retries, attempts[{usage,stage,errors}], bundle 路径, verdict 四件套, factory 路径 }
 
-闭环:generate → validate(静态+node --check) → scaffold+build(esbuild) → play(CDP 六门) →
+闭环:generate → validate(静态+node --check) → scaffold+build(esbuild) → play(CDP 九门) →
   任一阶段失败即把错因回喂模型重试,≤ max_retries 次。"能生成 ≠ 能玩"——必须过 play 才算 pass。
 """