@gamebob/axon-surge 0.8.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/axon-surge.js +1992 -598
  2. package/dist/config/GameConfig.d.ts +57 -0
  3. package/dist/config/GameConfig.d.ts.map +1 -0
  4. package/dist/core/GameEngine.d.ts +5 -0
  5. package/dist/core/GameEngine.d.ts.map +1 -1
  6. package/dist/director/WaveDirector.d.ts.map +1 -1
  7. package/dist/entities/CoreEntity.d.ts +14 -0
  8. package/dist/entities/CoreEntity.d.ts.map +1 -1
  9. package/dist/entities/EnemyEntity.d.ts +3 -0
  10. package/dist/entities/EnemyEntity.d.ts.map +1 -1
  11. package/dist/factory/EntityFactory.d.ts.map +1 -1
  12. package/dist/i18n/I18nService.d.ts +1 -1
  13. package/dist/i18n/I18nService.d.ts.map +1 -1
  14. package/dist/i18n/locales.d.ts +32 -0
  15. package/dist/i18n/locales.d.ts.map +1 -1
  16. package/dist/input/InputManager.d.ts +3 -0
  17. package/dist/input/InputManager.d.ts.map +1 -1
  18. package/dist/physics/PhysicsEngine.d.ts +1 -3
  19. package/dist/physics/PhysicsEngine.d.ts.map +1 -1
  20. package/dist/physics/handlers/ChainReactionHelper.d.ts +6 -0
  21. package/dist/physics/handlers/ChainReactionHelper.d.ts.map +1 -0
  22. package/dist/physics/handlers/CoreCollisionHandler.d.ts +11 -0
  23. package/dist/physics/handlers/CoreCollisionHandler.d.ts.map +1 -0
  24. package/dist/physics/handlers/ShieldCollisionHandler.d.ts +10 -0
  25. package/dist/physics/handlers/ShieldCollisionHandler.d.ts.map +1 -0
  26. package/dist/physics/handlers/ThrownCollisionHandler.d.ts +13 -0
  27. package/dist/physics/handlers/ThrownCollisionHandler.d.ts.map +1 -0
  28. package/dist/physics/handlers/ToxicPoolPhysicsHandler.d.ts +8 -0
  29. package/dist/physics/handlers/ToxicPoolPhysicsHandler.d.ts.map +1 -0
  30. package/dist/physics/handlers/VortexPhysicsHandler.d.ts +6 -0
  31. package/dist/physics/handlers/VortexPhysicsHandler.d.ts.map +1 -0
  32. package/dist/powerups/OrbitingModifierOrb.d.ts +16 -0
  33. package/dist/powerups/OrbitingModifierOrb.d.ts.map +1 -0
  34. package/dist/powerups/PowerUpRegistry.d.ts +7 -0
  35. package/dist/powerups/PowerUpRegistry.d.ts.map +1 -0
  36. package/dist/powerups/PowerUpTypes.d.ts +16 -0
  37. package/dist/powerups/PowerUpTypes.d.ts.map +1 -0
  38. package/dist/render/CanvasRenderer.d.ts +3 -0
  39. package/dist/render/CanvasRenderer.d.ts.map +1 -1
  40. package/dist/render/CosmosBackgroundRenderer.d.ts +1 -1
  41. package/dist/render/CosmosBackgroundRenderer.d.ts.map +1 -1
  42. package/dist/strategies/FragmentClusterStrategy.d.ts.map +1 -1
  43. package/dist/strategies/HeavyShieldStrategy.d.ts +5 -0
  44. package/dist/strategies/HeavyShieldStrategy.d.ts.map +1 -0
  45. package/dist/theme/ThemeManager.d.ts +1 -1
  46. package/dist/theme/ThemeManager.d.ts.map +1 -1
  47. package/dist/types/game.d.ts +1 -1
  48. package/dist/types/game.d.ts.map +1 -1
  49. package/dist/ui/ProgressBar.d.ts.map +1 -1
  50. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- class K {
1
+ class J {
2
2
  listeners = /* @__PURE__ */ new Map();
3
3
  on(t, e) {
4
4
  return this.listeners.has(t) || this.listeners.set(t, /* @__PURE__ */ new Set()), this.listeners.get(t).add(e), () => this.off(t, e);
@@ -15,7 +15,7 @@ class K {
15
15
  this.listeners.clear();
16
16
  }
17
17
  }
18
- class W {
18
+ class X {
19
19
  animationFrameId = null;
20
20
  lastTime = 0;
21
21
  isRunning = !1;
@@ -36,31 +36,126 @@ class W {
36
36
  this.lastTime = t, this.updateCallback(e), this.renderCallback(), this.animationFrameId = requestAnimationFrame(this.tick);
37
37
  }
38
38
  }
39
- class V {
39
+ const B = {
40
+ core: {
41
+ maxIntegrity: 3,
42
+ invulnerabilityDuration: 1.5,
43
+ radius: 32,
44
+ vampirismHealProgressRate: 0
45
+ },
46
+ toxicPool: {
47
+ baseRadius: 110,
48
+ synergyRadius: 210,
49
+ baseDuration: 4.5,
50
+ synergyDuration: 8,
51
+ damage: 50
52
+ },
53
+ gravityVortex: {
54
+ baseRadius: 220,
55
+ synergyRadius: 360,
56
+ baseDuration: 4,
57
+ synergyDuration: 6,
58
+ basePullForce: 2200,
59
+ synergyPullForce: 4e3,
60
+ hasImplosionLaunch: !1
61
+ },
62
+ shield: {
63
+ blastSpeed: 1600,
64
+ hitboxRange: 280,
65
+ isFanBlast: !1
66
+ },
67
+ cluster: {
68
+ fragmentCount: 6,
69
+ hasHoming: !1
70
+ },
71
+ piercer: {
72
+ terminalAoERadius: 0,
73
+ hasHoming: !1,
74
+ homingTargets: 1
75
+ }
76
+ };
77
+ class A {
78
+ static instance;
79
+ config;
80
+ constructor() {
81
+ this.config = JSON.parse(JSON.stringify(B));
82
+ }
83
+ static getInstance() {
84
+ return A.instance || (A.instance = new A()), A.instance;
85
+ }
86
+ getConfig() {
87
+ return this.config;
88
+ }
89
+ updateConfig(t) {
90
+ this.config = {
91
+ ...this.config,
92
+ ...t
93
+ };
94
+ }
95
+ setMaxCoreRings(t) {
96
+ this.config.core.maxIntegrity = Math.max(1, t);
97
+ }
98
+ addCoreRing(t = 1) {
99
+ this.config.core.maxIntegrity += t;
100
+ }
101
+ resetToDefault() {
102
+ this.config = JSON.parse(JSON.stringify(B));
103
+ }
104
+ }
105
+ class z {
40
106
  position;
41
- radius = 32;
42
- integrity = 3;
43
- maxIntegrity = 3;
107
+ radius;
108
+ integrity;
109
+ maxIntegrity;
44
110
  pulsePhase = 0;
45
111
  organicSeed;
112
+ invulnerabilityTimer = 0;
113
+ maxInvulnerabilityDuration;
114
+ customColor = { r: 0, g: 240, b: 255 };
115
+ powerUpCount = 0;
46
116
  constructor(t, e) {
47
- this.position = { x: t, y: e }, this.organicSeed = Math.random() * 100;
117
+ const i = A.getInstance().getConfig().core;
118
+ this.position = { x: t, y: e }, this.radius = i.radius, this.integrity = i.maxIntegrity, this.maxIntegrity = i.maxIntegrity, this.maxInvulnerabilityDuration = i.invulnerabilityDuration, this.organicSeed = Math.random() * 100;
119
+ }
120
+ absorbPowerUpColor(t, e = 0.35) {
121
+ this.powerUpCount++;
122
+ const i = t.replace("#", "");
123
+ if (i.length === 6) {
124
+ const s = parseInt(i.substring(0, 2), 16), a = parseInt(i.substring(2, 4), 16), l = parseInt(i.substring(4, 6), 16);
125
+ this.customColor.r = Math.round(this.customColor.r * (1 - e) + s * e), this.customColor.g = Math.round(this.customColor.g * (1 - e) + a * e), this.customColor.b = Math.round(this.customColor.b * (1 - e) + l * e);
126
+ }
127
+ }
128
+ getColorHex() {
129
+ const t = this.customColor.r.toString(16).padStart(2, "0"), e = this.customColor.g.toString(16).padStart(2, "0"), i = this.customColor.b.toString(16).padStart(2, "0");
130
+ return `#${t}${e}${i}`;
48
131
  }
49
132
  update(t) {
50
- this.pulsePhase += t * 2.8;
133
+ this.pulsePhase += t * 2.8, this.invulnerabilityTimer > 0 && (this.invulnerabilityTimer -= t);
51
134
  }
52
135
  getMembraneRadius(t) {
53
136
  const e = Math.sin(t * 5 + this.pulsePhase * 1.5 + this.organicSeed) * 4, i = Math.cos(t * 3 - this.pulsePhase * 2.2) * 2.5, s = Math.sin(t * 7 + this.pulsePhase * 3.1) * 1.5;
54
137
  return this.radius + e + i + s;
55
138
  }
139
+ repairProgress = 0;
140
+ addKillRepair() {
141
+ const t = A.getInstance().getConfig().core.vampirismHealProgressRate;
142
+ return t <= 0 ? !1 : (this.repairProgress += t, this.repairProgress >= 1 ? (this.integrity += 1, this.integrity > this.maxIntegrity && (this.maxIntegrity = this.integrity), this.repairProgress = 0, !0) : !1);
143
+ }
144
+ heal(t = 1) {
145
+ return this.integrity < this.maxIntegrity ? (this.integrity = Math.min(this.integrity + t, this.maxIntegrity), this.repairProgress = 0, !0) : !1;
146
+ }
147
+ addMaxRing(t = 1) {
148
+ this.maxIntegrity += t, this.integrity += t;
149
+ }
56
150
  takeDamage() {
57
- return this.integrity > 0 ? (this.integrity -= 1, !0) : !1;
151
+ return this.invulnerabilityTimer > 0 ? !1 : this.integrity > 0 ? (this.integrity -= 1, this.invulnerabilityTimer = this.maxInvulnerabilityDuration, !0) : !1;
58
152
  }
59
153
  reset(t, e) {
60
- this.position = { x: t, y: e }, this.integrity = this.maxIntegrity, this.pulsePhase = 0;
154
+ const i = A.getInstance().getConfig().core;
155
+ this.position = { x: t, y: e }, this.radius = i.radius, this.maxIntegrity = i.maxIntegrity, this.integrity = this.maxIntegrity, this.maxInvulnerabilityDuration = i.invulnerabilityDuration, this.pulsePhase = 0, this.invulnerabilityTimer = 0, this.repairProgress = 0, this.powerUpCount = 0, this.customColor = { r: 0, g: 240, b: 255 };
61
156
  }
62
157
  }
63
- class D {
158
+ class H {
64
159
  id;
65
160
  position = { x: 0, y: 0 };
66
161
  velocity = { x: 0, y: 0 };
@@ -75,6 +170,9 @@ class D {
75
170
  strategy = null;
76
171
  hitRadiusPadding = 1.2;
77
172
  maxSpeed = 200;
173
+ isStationaryShield = !1;
174
+ shieldAngle = 0;
175
+ remainingHomingKills = 0;
78
176
  isDying = !1;
79
177
  deathType = "none";
80
178
  deathTimer = 0;
@@ -98,7 +196,7 @@ class D {
98
196
  this.deathTimer += t, this.deathTimer >= this.maxDeathTimer && (this.active = !1, this.isDying = !1);
99
197
  return;
100
198
  }
101
- if (!this.isGrabbed) {
199
+ if (!(this.isGrabbed || this.isStationaryShield)) {
102
200
  if (!this.isThrown && this.maxSpeed > 0) {
103
201
  const e = Math.hypot(this.velocity.x, this.velocity.y);
104
202
  if (e > this.maxSpeed) {
@@ -106,18 +204,36 @@ class D {
106
204
  this.velocity.x *= i, this.velocity.y *= i;
107
205
  }
108
206
  }
109
- this.position.x += this.velocity.x * t, this.position.y += this.velocity.y * t, (this.velocity.x !== 0 || this.velocity.y !== 0) && (this.rotation = Math.atan2(this.velocity.y, this.velocity.x));
207
+ this.position.x += this.velocity.x * t, this.position.y += this.velocity.y * t, this.type !== "heavy" && (this.velocity.x !== 0 || this.velocity.y !== 0) && (this.rotation = Math.atan2(this.velocity.y, this.velocity.x));
110
208
  }
111
209
  }
112
210
  }
113
211
  reset() {
114
- this.active = !1, this.isGrabbed = !1, this.isThrown = !1, this.wasManipulated = !1, this.isDying = !1, this.deathType = "none", this.deathTimer = 0, this.sliceAngle = 0, this.position = { x: 0, y: 0 }, this.velocity = { x: 0, y: 0 }, this.rotation = 0, this.strategy = null, this.maxSpeed = 200;
212
+ this.active = !1, this.isGrabbed = !1, this.isThrown = !1, this.wasManipulated = !1, this.isDying = !1, this.deathType = "none", this.deathTimer = 0, this.sliceAngle = 0, this.isStationaryShield = !1, this.shieldAngle = 0, this.position = { x: 0, y: 0 }, this.velocity = { x: 0, y: 0 }, this.rotation = 0, this.strategy = null, this.maxSpeed = 200;
115
213
  }
116
214
  }
117
- class F {
215
+ class K {
216
+ id;
217
+ definition;
218
+ position = { x: 0, y: 0 };
219
+ orbitAngle = 0;
220
+ orbitDistance = 220;
221
+ radius = 26;
222
+ isGrabbed = !1;
223
+ active = !0;
224
+ isHovered = !1;
225
+ constructor(t, e, i) {
226
+ this.id = t, this.definition = e, this.orbitAngle = i;
227
+ }
228
+ update(t, e) {
229
+ this.active && !this.isGrabbed && !this.isHovered && (this.orbitAngle += t * 0.25, this.position.x = e.x + Math.cos(this.orbitAngle) * this.orbitDistance, this.position.y = e.y + Math.sin(this.orbitAngle) * this.orbitDistance);
230
+ }
231
+ }
232
+ class $ {
118
233
  pointerPosition = { x: 0, y: 0 };
119
234
  isPointerDown = !1;
120
235
  grabbedEnemy = null;
236
+ grabbedOrb = null;
121
237
  dragStart = null;
122
238
  pointerHistory = [];
123
239
  canvas;
@@ -134,8 +250,8 @@ class F {
134
250
  y: this.pointerPosition.y,
135
251
  time: l
136
252
  });
137
- const r = l - 0.08;
138
- this.pointerHistory = this.pointerHistory.filter((n) => n.time >= r), this.grabbedEnemy && (this.grabbedEnemy.position = { ...this.pointerPosition });
253
+ const n = l - 0.08;
254
+ this.pointerHistory = this.pointerHistory.filter((o) => o.time >= n), this.grabbedEnemy && (this.grabbedEnemy.position = { ...this.pointerPosition });
139
255
  }
140
256
  bindEvents() {
141
257
  this.canvas.addEventListener("mousemove", (t) => {
@@ -176,8 +292,18 @@ class F {
176
292
  for (const s of t) {
177
293
  if (!s.active || s.isGrabbed || s.isThrown || s.wasManipulated) continue;
178
294
  const a = this.pointerPosition.x - s.position.x, l = this.pointerPosition.y - s.position.y;
179
- if (Math.hypot(a, l) <= s.getHitRadius() + i)
180
- return s.isGrabbed = !0, this.grabbedEnemy = s, this.dragStart = { ...this.pointerPosition }, this.pointerHistory = [], s;
295
+ Math.hypot(a, l) <= s.getHitRadius() + i && (s.isGrabbed = !0, this.grabbedEnemy = s, this.dragStart = { ...this.pointerPosition }, this.pointerHistory = []);
296
+ }
297
+ return null;
298
+ }
299
+ tryGrabOrb(t, e = !1) {
300
+ if (this.grabbedOrb) return this.grabbedOrb;
301
+ const i = e ? 50 : 20;
302
+ for (const s of t) {
303
+ if (!s.active || s.isGrabbed) continue;
304
+ const a = this.pointerPosition.x - s.position.x, l = this.pointerPosition.y - s.position.y;
305
+ if (Math.hypot(a, l) <= s.radius * 1.5 + i)
306
+ return s.isGrabbed = !0, this.grabbedOrb = s, s;
181
307
  }
182
308
  return null;
183
309
  }
@@ -185,40 +311,46 @@ class F {
185
311
  if (!this.grabbedEnemy) return null;
186
312
  const t = this.grabbedEnemy;
187
313
  t.isGrabbed = !1, t.isThrown = !0, t.wasManipulated = !0;
188
- const i = performance.now() / 1e3 - 0.08, s = this.pointerHistory.filter((n) => n.time >= i);
314
+ const i = performance.now() / 1e3 - 0.08, s = this.pointerHistory.filter((o) => o.time >= i);
189
315
  let a = 0, l = 0;
190
316
  if (s.length >= 2) {
191
- const n = s[0], o = s[s.length - 1], h = Math.max(0.01, o.time - n.time);
192
- a = (o.x - n.x) / h, l = (o.y - n.y) / h;
317
+ const o = s[0], r = s[s.length - 1], c = Math.max(0.01, r.time - o.time);
318
+ a = (r.x - o.x) / c, l = (r.y - o.y) / c;
193
319
  }
194
- const r = Math.hypot(a, l);
195
- if (r > 30) {
196
- const o = Math.min(r * 1.15, 2500), h = Math.atan2(l, a);
320
+ const n = Math.hypot(a, l);
321
+ if (n > 30) {
322
+ const r = Math.min(n * 1.15, 2500), c = Math.atan2(l, a);
197
323
  t.velocity = {
198
- x: Math.cos(h) * o,
199
- y: Math.sin(h) * o
324
+ x: Math.cos(c) * r,
325
+ y: Math.sin(c) * r
200
326
  };
201
327
  } else if (this.dragStart) {
202
- const n = t.position.x - this.dragStart.x, o = t.position.y - this.dragStart.y, h = Math.hypot(n, o);
203
- if (h > 5) {
204
- const c = Math.atan2(o, n), u = Math.min(h * 4, 600);
328
+ const o = t.position.x - this.dragStart.x, r = t.position.y - this.dragStart.y, c = Math.hypot(o, r);
329
+ if (c > 5) {
330
+ const h = Math.atan2(r, o), u = Math.min(c * 4, 600);
205
331
  t.velocity = {
206
- x: Math.cos(c) * u,
207
- y: Math.sin(c) * u
332
+ x: Math.cos(h) * u,
333
+ y: Math.sin(h) * u
208
334
  };
209
335
  } else
210
336
  t.velocity = { x: 0, y: 0 }, t.isThrown = !1;
211
337
  }
338
+ if (t.type === "heavy")
339
+ t.shieldAngle = t.rotation, t.velocity = { x: 0, y: 0 }, t.isStationaryShield = !0, t.isThrown = !1;
340
+ else if (t.type === "piercer") {
341
+ const o = A.getInstance().getConfig().piercer;
342
+ o.hasHoming && (t.remainingHomingKills = o.homingTargets);
343
+ }
212
344
  return this.grabbedEnemy = null, this.dragStart = null, this.pointerHistory = [], t;
213
345
  }
214
346
  forceRelease() {
215
- this.grabbedEnemy && (this.grabbedEnemy.isGrabbed = !1, this.grabbedEnemy.isThrown = !1, this.grabbedEnemy.wasManipulated = !1, this.grabbedEnemy = null), this.dragStart = null, this.pointerHistory = [];
347
+ this.grabbedEnemy && (this.grabbedEnemy.isGrabbed = !1, this.grabbedEnemy.isThrown = !1, this.grabbedEnemy.wasManipulated = !1), this.grabbedOrb && (this.grabbedOrb.isGrabbed = !1), this.grabbedEnemy = null, this.grabbedOrb = null, this.dragStart = null, this.pointerHistory = [];
216
348
  }
217
349
  reset() {
218
- this.grabbedEnemy = null, this.dragStart = null, this.pointerHistory = [], this.isPointerDown = !1;
350
+ this.grabbedEnemy = null, this.grabbedOrb = null, this.dragStart = null, this.pointerHistory = [], this.isPointerDown = !1;
219
351
  }
220
352
  }
221
- class Y {
353
+ class j {
222
354
  cellSize;
223
355
  grid = /* @__PURE__ */ new Map();
224
356
  constructor(t = 100) {
@@ -230,22 +362,22 @@ class Y {
230
362
  insert(t) {
231
363
  const e = Math.floor((t.position.x - t.radius) / this.cellSize), i = Math.floor((t.position.x + t.radius) / this.cellSize), s = Math.floor((t.position.y - t.radius) / this.cellSize), a = Math.floor((t.position.y + t.radius) / this.cellSize);
232
364
  for (let l = e; l <= i; l++)
233
- for (let r = s; r <= a; r++) {
234
- const n = `${l}:${r}`;
235
- this.grid.has(n) || this.grid.set(n, /* @__PURE__ */ new Set()), this.grid.get(n).add(t);
365
+ for (let n = s; n <= a; n++) {
366
+ const o = `${l}:${n}`;
367
+ this.grid.has(o) || this.grid.set(o, /* @__PURE__ */ new Set()), this.grid.get(o).add(t);
236
368
  }
237
369
  }
238
370
  getNearby(t, e) {
239
- const i = /* @__PURE__ */ new Set(), s = Math.floor((t.x - e) / this.cellSize), a = Math.floor((t.x + e) / this.cellSize), l = Math.floor((t.y - e) / this.cellSize), r = Math.floor((t.y + e) / this.cellSize);
240
- for (let n = s; n <= a; n++)
241
- for (let o = l; o <= r; o++) {
242
- const h = `${n}:${o}`, c = this.grid.get(h);
243
- c && c.forEach((u) => i.add(u));
371
+ const i = /* @__PURE__ */ new Set(), s = Math.floor((t.x - e) / this.cellSize), a = Math.floor((t.x + e) / this.cellSize), l = Math.floor((t.y - e) / this.cellSize), n = Math.floor((t.y + e) / this.cellSize);
372
+ for (let o = s; o <= a; o++)
373
+ for (let r = l; r <= n; r++) {
374
+ const c = `${o}:${r}`, h = this.grid.get(c);
375
+ h && h.forEach((u) => i.add(u));
244
376
  }
245
377
  return i;
246
378
  }
247
379
  }
248
- class J {
380
+ class q {
249
381
  hitstopTime = 0;
250
382
  shakeTime = 0;
251
383
  shakeDuration = 0.14;
@@ -285,7 +417,7 @@ class J {
285
417
  };
286
418
  }
287
419
  }
288
- const R = {
420
+ const P = {
289
421
  es: {
290
422
  title: "AXON SURGE",
291
423
  startButton: "INICIAR ENLACE",
@@ -307,7 +439,39 @@ const R = {
307
439
  tutorialSettingLabel: "MOSTRAR TUTORIAL AL INICIAR",
308
440
  tutorialStep1Text: "PASO 1: MANTÉN PULSADO EL ENEMIGO SEÑALADO",
309
441
  tutorialStep2Text: "PASO 2: LÁNZALO CON IMPULSO HACIA EL OBJETIVO",
310
- tutorialDragWarning: "¡LA MEJOR ESTRATEGIA ES LANZARLOS! LÁNZALO CON IMPULSO"
442
+ tutorialDragWarning: "¡LA MEJOR ESTRATEGIA ES LANZARLOS! LÁNZALO CON IMPULSO",
443
+ levelUpChoose: "¡NIVEL {level}! ELIGE UN MODIFICADOR",
444
+ rerollButton: "🎲 REROLL (1 DISPONIBLE)",
445
+ pu_spore_radius_title: "EXPANSIÓN ÁCIDA",
446
+ pu_spore_radius_desc: "+30% Radio Ácido",
447
+ pu_spore_duration_title: "LONGEVIDAD ÁCIDA",
448
+ pu_spore_duration_desc: "+3.0s Duración Ácido",
449
+ pu_vortex_radius_title: "EXPANSIÓN DE SINGULARIDAD",
450
+ pu_vortex_radius_desc: "+25% Radio Vórtice",
451
+ pu_vortex_duration_title: "LONGEVIDAD GRAVITATORIA",
452
+ pu_vortex_duration_desc: "+2.5s Duración Vórtice",
453
+ pu_vortex_power_title: "SOBRECARGA GRAVITATORIA",
454
+ pu_vortex_power_desc: "+40% Fuerza Vórtice",
455
+ pu_vortex_pocket_title: "IMPLOSIÓN BOLSILLO",
456
+ pu_vortex_pocket_desc: "Lanza proyectiles al morir el vórtice",
457
+ pu_cluster_extra_title: "RÁFAGA DE METRALLA",
458
+ pu_cluster_extra_desc: "+2 Fragmentos Amarillos",
459
+ pu_cluster_homing_title: "METRALLA BUSCADORA",
460
+ pu_cluster_homing_desc: "Fragmentos orientados al enemigo más cercano",
461
+ pu_piercer_aoe_title: "DETONACIÓN ROJA",
462
+ pu_piercer_aoe_desc: "El corte explota al final del trayecto",
463
+ pu_piercer_homing_title: "CORTE BUSCADOR",
464
+ pu_piercer_homing_desc: "El corte busca al enemigo más cercano",
465
+ pu_piercer_homing_target_title: "CORTE ENCADENADO",
466
+ pu_piercer_homing_target_desc: "+1 Objetivo para el Corte Buscador",
467
+ pu_shield_fan_title: "TRIPLE RAGAZO ARC",
468
+ pu_shield_fan_desc: "Dispara 3 rayos en abanico",
469
+ pu_vampirism_unlock_title: "BIO-VAMPIRISMO",
470
+ pu_vampirism_unlock_desc: "Las bajas reparan vidas dañadas",
471
+ pu_vampirism_boost_title: "IMPULSO VAMPÍRICO",
472
+ pu_vampirism_boost_desc: "+0.3% Curación por baja",
473
+ pu_core_ring_title: "SOBRECARGA DE NÚCLEO",
474
+ pu_core_ring_desc: "+1 Anillo de Vida"
311
475
  },
312
476
  en: {
313
477
  title: "AXON SURGE",
@@ -330,7 +494,39 @@ const R = {
330
494
  tutorialSettingLabel: "SHOW TUTORIAL AT START",
331
495
  tutorialStep1Text: "STEP 1: PRESS AND HOLD THE INDICATED ENEMY",
332
496
  tutorialStep2Text: "STEP 2: FLICK TOWARD TARGET WITH SWIPE SPEED",
333
- tutorialDragWarning: "THE BEST STRATEGY IS TO FLICK THEM! THROW WITH SWIPE SPEED"
497
+ tutorialDragWarning: "THE BEST STRATEGY IS TO FLICK THEM! THROW WITH SWIPE SPEED",
498
+ levelUpChoose: "LEVEL {level}! CHOOSE MODIFIER",
499
+ rerollButton: "🎲 REROLL (1 AVAILABLE)",
500
+ pu_spore_radius_title: "ACID EXPANSION",
501
+ pu_spore_radius_desc: "+30% Acid Radius",
502
+ pu_spore_duration_title: "ACID LINGER",
503
+ pu_spore_duration_desc: "+3.0s Acid Duration",
504
+ pu_vortex_radius_title: "SINGULARITY EXPANSION",
505
+ pu_vortex_radius_desc: "+25% Vortex Radius",
506
+ pu_vortex_duration_title: "GRAVITY LINGER",
507
+ pu_vortex_duration_desc: "+2.5s Vortex Duration",
508
+ pu_vortex_power_title: "GRAVITY SURGE",
509
+ pu_vortex_power_desc: "+40% Vortex Pull Force",
510
+ pu_vortex_pocket_title: "POCKET IMPLOSION",
511
+ pu_vortex_pocket_desc: "Launches projectiles on vortex death",
512
+ pu_cluster_extra_title: "CLUSTER BURST",
513
+ pu_cluster_extra_desc: "+2 Yellow Shards",
514
+ pu_cluster_homing_title: "HOMING SHARDS",
515
+ pu_cluster_homing_desc: "Shards target nearest enemy",
516
+ pu_piercer_aoe_title: "PIERCER DETONATION",
517
+ pu_piercer_aoe_desc: "Slice detonates at end of path",
518
+ pu_piercer_homing_title: "SEEKER SLICE",
519
+ pu_piercer_homing_desc: "Slice seeks nearest enemy",
520
+ pu_piercer_homing_target_title: "CHAIN SEEKER",
521
+ pu_piercer_homing_target_desc: "+1 Target for Seeker Slice",
522
+ pu_shield_fan_title: "TRIPLE ARC BLAST",
523
+ pu_shield_fan_desc: "Fires 3 fan beams",
524
+ pu_vampirism_unlock_title: "BIO-VAMPIRISM",
525
+ pu_vampirism_unlock_desc: "Kills repair damaged core rings",
526
+ pu_vampirism_boost_title: "VAMPIRIC SURGE",
527
+ pu_vampirism_boost_desc: "+0.3% Heal per kill",
528
+ pu_core_ring_title: "NUCLEUS OVERCHARGE",
529
+ pu_core_ring_desc: "+1 Life Ring"
334
530
  },
335
531
  fr: {
336
532
  title: "AXON SURGE",
@@ -353,7 +549,39 @@ const R = {
353
549
  tutorialSettingLabel: "AFFICHER LE TUTORIEL AU DEMARRAGE",
354
550
  tutorialStep1Text: "ETAPE 1: MAINTENEZ L'ENNEMI INDIQUE",
355
551
  tutorialStep2Text: "ETAPE 2: LANCEZ AVEC VITESSE VERS LA CIBLE",
356
- tutorialDragWarning: "LA MEILLEURE STRATEGIE EST DE LES LANCER !"
552
+ tutorialDragWarning: "LA MEILLEURE STRATEGIE EST DE LES LANCER !",
553
+ levelUpChoose: "NIVEAU {level} ! CHOISISSEZ UN MODIFICATEUR",
554
+ rerollButton: "🎲 RELANCER (1 DISPONIBLE)",
555
+ pu_spore_radius_title: "EXPANSION ACIDE",
556
+ pu_spore_radius_desc: "+30% Rayon d'acide",
557
+ pu_spore_duration_title: "LONGEVITE ACIDE",
558
+ pu_spore_duration_desc: "+3.0s Durée d'acide",
559
+ pu_vortex_radius_title: "EXPANSION SINGULARITE",
560
+ pu_vortex_radius_desc: "+25% Rayon du vortex",
561
+ pu_vortex_duration_title: "LONGEVITE GRAVITATIONNELLE",
562
+ pu_vortex_duration_desc: "+2.5s Durée du vortex",
563
+ pu_vortex_power_title: "SURCHARGE GRAVITATIONNELLE",
564
+ pu_vortex_power_desc: "+40% Force d'attraction",
565
+ pu_vortex_pocket_title: "IMPLOSION DE POCHE",
566
+ pu_vortex_pocket_desc: "Ejecte les ennemis à la fin du vortex",
567
+ pu_cluster_extra_title: "RAFALE DE SHRAPNEL",
568
+ pu_cluster_extra_desc: "+2 Shrapnels jaunes",
569
+ pu_cluster_homing_title: "SHRAPNELS CHERCHEURS",
570
+ pu_cluster_homing_desc: "Shrapnels orientés vers l'ennemi proche",
571
+ pu_piercer_aoe_title: "DETONATION ROUGE",
572
+ pu_piercer_aoe_desc: "Explosion en fin de trajectoire",
573
+ pu_piercer_homing_title: "COUPE CHERCHEUSE",
574
+ pu_piercer_homing_desc: "Cherche l'ennemi le plus proche",
575
+ pu_piercer_homing_target_title: "CHASSE EN CHAINE",
576
+ pu_piercer_homing_target_desc: "+1 Cible supplémentaire pour la coupe",
577
+ pu_shield_fan_title: "TRIPLE ARC BLAST",
578
+ pu_shield_fan_desc: "Tire 3 rayons en éventail",
579
+ pu_vampirism_unlock_title: "BIO-VAMPIRISME",
580
+ pu_vampirism_unlock_desc: "Les éliminations réparent les anneaux",
581
+ pu_vampirism_boost_title: "POUSSEE VAMPIRIQUE",
582
+ pu_vampirism_boost_desc: "+0.3% Soin par élimination",
583
+ pu_core_ring_title: "SURCHARGE DU NOYAU",
584
+ pu_core_ring_desc: "+1 Anneau de vie"
357
585
  },
358
586
  de: {
359
587
  title: "AXON SURGE",
@@ -376,7 +604,39 @@ const R = {
376
604
  tutorialSettingLabel: "TUTORIAL BEIM START ANZEIGEN",
377
605
  tutorialStep1Text: "SCHRITT 1: HALTE DEN FEIND GEDRUECKT",
378
606
  tutorialStep2Text: "SCHRITT 2: SCHLEUDERE MIT SCHWUNG AUF DAS ZIEL",
379
- tutorialDragWarning: "DIE BESTE STRATEGIE IST ES SIE ZU SCHLEUDERN!"
607
+ tutorialDragWarning: "DIE BESTE STRATEGIE IST ES SIE ZU SCHLEUDERN!",
608
+ levelUpChoose: "LEVEL {level}! MODIFIKATOR WÄHLEN",
609
+ rerollButton: "🎲 NEU WÜRFELN (1 VERFÜGBAR)",
610
+ pu_spore_radius_title: "SÄURE-EXPANSION",
611
+ pu_spore_radius_desc: "+30% Säureradius",
612
+ pu_spore_duration_title: "SÄURE-DAUER",
613
+ pu_spore_duration_desc: "+3.0s Säuredauer",
614
+ pu_vortex_radius_title: "SINGULARITÄTS-EXPANSION",
615
+ pu_vortex_radius_desc: "+25% Wirbelradius",
616
+ pu_vortex_duration_title: "GRAVITATIONS-DAUER",
617
+ pu_vortex_duration_desc: "+2.5s Wirbeldauer",
618
+ pu_vortex_power_title: "GRAVITATIONS-SCHUB",
619
+ pu_vortex_power_desc: "+40% Anziehungskraft",
620
+ pu_vortex_pocket_title: "TASCHEN-IMPLOSION",
621
+ pu_vortex_pocket_desc: "Schleudert Feinde bei Wirbelende",
622
+ pu_cluster_extra_title: "SPLITTER-SALVE",
623
+ pu_cluster_extra_desc: "+2 Gelbe Splitter",
624
+ pu_cluster_homing_title: "SUCH-SPLITTER",
625
+ pu_cluster_homing_desc: "Splitter suchen nächsten Feind",
626
+ pu_piercer_aoe_title: "ROTE DETONATION",
627
+ pu_piercer_aoe_desc: "Explosion am Ende der Flugbahn",
628
+ pu_piercer_homing_title: "SUCH-SCHNITT",
629
+ pu_piercer_homing_desc: "Sucht nächsten Feind",
630
+ pu_piercer_homing_target_title: "KETTEN-SUCHER",
631
+ pu_piercer_homing_target_desc: "+1 Zusaetzliches Ziel",
632
+ pu_shield_fan_title: "TRIPLE ARC BLAST",
633
+ pu_shield_fan_desc: "Feuert 3 Strahlen im Fächer",
634
+ pu_vampirism_unlock_title: "BIO-VAMPIRISMUS",
635
+ pu_vampirism_unlock_desc: "Kills reparieren Ringe",
636
+ pu_vampirism_boost_title: "VAMPIR-SCHUB",
637
+ pu_vampirism_boost_desc: "+0.3% Heilung pro Kill",
638
+ pu_core_ring_title: "KERN-ÜBERLADUNG",
639
+ pu_core_ring_desc: "+1 Lebensring"
380
640
  },
381
641
  it: {
382
642
  title: "AXON SURGE",
@@ -399,7 +659,39 @@ const R = {
399
659
  tutorialSettingLabel: "MOSTRA TUTORIAL ALL'AVVIO",
400
660
  tutorialStep1Text: "PASSO 1: TIENI PREMUTO IL NEMICO INDICATO",
401
661
  tutorialStep2Text: "PASSO 2: LANCIA CON VELOCITA VERSO IL BERSAGLIO",
402
- tutorialDragWarning: "LA STRATEGIA MIGLIORE E LANCIARLI!"
662
+ tutorialDragWarning: "LA STRATEGIA MIGLIORE E LANCIARLI!",
663
+ levelUpChoose: "LIVELLO {level}! SCEGLI UN MODIFICATORE",
664
+ rerollButton: "🎲 RILANCIA (1 DISPONIBILE)",
665
+ pu_spore_radius_title: "ESPANSIONE ACIDA",
666
+ pu_spore_radius_desc: "+30% Raggio Acido",
667
+ pu_spore_duration_title: "DURATA ACIDA",
668
+ pu_spore_duration_desc: "+3.0s Durata Acida",
669
+ pu_vortex_radius_title: "ESPANSIONE SINGOLARITA",
670
+ pu_vortex_radius_desc: "+25% Raggio Vortice",
671
+ pu_vortex_duration_title: "DURATA GRAVITAZIONALE",
672
+ pu_vortex_duration_desc: "+2.5s Durata Vortice",
673
+ pu_vortex_power_title: "SOVRACCARICO GRAVITAZIONALE",
674
+ pu_vortex_power_desc: "+40% Forza di Attrazione",
675
+ pu_vortex_pocket_title: "IMPLOSIONE A TASCA",
676
+ pu_vortex_pocket_desc: "Lancia i nemici alla fine del vortice",
677
+ pu_cluster_extra_title: "RAFFICA DI SCHEGGE",
678
+ pu_cluster_extra_desc: "+2 Schegge Gialle",
679
+ pu_cluster_homing_title: "SCHEGGE GUIDATE",
680
+ pu_cluster_homing_desc: "Le schegge cercano il nemico vicino",
681
+ pu_piercer_aoe_title: "DETONAZIONE ROSSA",
682
+ pu_piercer_aoe_desc: "Esplosione a fine traiettoria",
683
+ pu_piercer_homing_title: "TAGLIO GUIDATO",
684
+ pu_piercer_homing_desc: "Cerca il nemico più vicino",
685
+ pu_piercer_homing_target_title: "INSEGUITORE A CATENA",
686
+ pu_piercer_homing_target_desc: "+1 Bersaglio aggiuntivo",
687
+ pu_shield_fan_title: "TRIPLE ARC BLAST",
688
+ pu_shield_fan_desc: "Spara 3 raggere a ventaglio",
689
+ pu_vampirism_unlock_title: "BIO-VAMPIRISMO",
690
+ pu_vampirism_unlock_desc: "Le uccisioni riparano gli anelli",
691
+ pu_vampirism_boost_title: "IMPULSO VAMPIRICO",
692
+ pu_vampirism_boost_desc: "+0.3% Cura per uccisione",
693
+ pu_core_ring_title: "SOVRACCARICO NUCLEO",
694
+ pu_core_ring_desc: "+1 Anello Vita"
403
695
  },
404
696
  pt: {
405
697
  title: "AXON SURGE",
@@ -422,7 +714,39 @@ const R = {
422
714
  tutorialSettingLabel: "MOSTRAR TUTORIAL AO INICIAR",
423
715
  tutorialStep1Text: "PASSO 1: SEGURE O INIMIGO INDICADO",
424
716
  tutorialStep2Text: "PASSO 2: LANCE COM IMPULSO EM DIRECAO AO ALVO",
425
- tutorialDragWarning: "A MELHOR ESTRATEGIA E LANCA-LOS!"
717
+ tutorialDragWarning: "A MELHOR ESTRATEGIA E LANCA-LOS!",
718
+ levelUpChoose: "NÍVEL {level}! ESCOLHA UM MODIFICADOR",
719
+ rerollButton: "🎲 REROLAR (1 DISPONÍVEL)",
720
+ pu_spore_radius_title: "EXPANSÃO ÁCIDA",
721
+ pu_spore_radius_desc: "+30% Raio Ácido",
722
+ pu_spore_duration_title: "LONGEVIDADE ÁCIDA",
723
+ pu_spore_duration_desc: "+3.0s Duração Ácida",
724
+ pu_vortex_radius_title: "EXPANSÃO SINGULARIDADE",
725
+ pu_vortex_radius_desc: "+25% Raio Vórtice",
726
+ pu_vortex_duration_title: "LONGEVIDADE GRAVITACIONAL",
727
+ pu_vortex_duration_desc: "+2.5s Duração Vórtice",
728
+ pu_vortex_power_title: "SOBRECARGA GRAVITACIONAL",
729
+ pu_vortex_power_desc: "+40% Força de Atração",
730
+ pu_vortex_pocket_title: "IMPLOSÃO DE BOLSO",
731
+ pu_vortex_pocket_desc: "Lança inimigos ao término do vórtice",
732
+ pu_cluster_extra_title: "EXPLOSÃO DE FRAGMENTOS",
733
+ pu_cluster_extra_desc: "+2 Fragmentos Amarelos",
734
+ pu_cluster_homing_title: "FRAGMENTOS GUIADOS",
735
+ pu_cluster_homing_desc: "Fragmentos buscam o inimigo próximo",
736
+ pu_piercer_aoe_title: "DETONAÇÃO VERMELHA",
737
+ pu_piercer_aoe_desc: "Explosão no final do trajeto",
738
+ pu_piercer_homing_title: "CORTE TELEGUIADO",
739
+ pu_piercer_homing_desc: "Busca o inimigo mais próximo",
740
+ pu_piercer_homing_target_title: "SEGUIDOR EM CADEIA",
741
+ pu_piercer_homing_target_desc: "+1 Alvo adicional para o corte",
742
+ pu_shield_fan_title: "TRIPLE ARC BLAST",
743
+ pu_shield_fan_desc: "Dispara 3 raios em leque",
744
+ pu_vampirism_unlock_title: "BIO-VAMPIRISMO",
745
+ pu_vampirism_unlock_desc: "Abates reparam anéis de vida",
746
+ pu_vampirism_boost_title: "IMPULSO VAMPÍRICO",
747
+ pu_vampirism_boost_desc: "+0.3% Cura por abate",
748
+ pu_core_ring_title: "SOBRECARGA DO NÚCLEO",
749
+ pu_core_ring_desc: "+1 Anel de Vida"
426
750
  },
427
751
  nl: {
428
752
  title: "AXON SURGE",
@@ -445,7 +769,39 @@ const R = {
445
769
  tutorialSettingLabel: "TUTORIAL TONEN BIJ START",
446
770
  tutorialStep1Text: "STAP 1: HOUD DE AANGEGEVEN VIJAND INGEDRUKT",
447
771
  tutorialStep2Text: "STAP 2: GOOI MET SNELHEID NAAR HET DOEL",
448
- tutorialDragWarning: "DE BESTE STRATEGIE IS OM ZE TE GOOIEN!"
772
+ tutorialDragWarning: "DE BESTE STRATEGIE IS OM ZE TE GOOIEN!",
773
+ levelUpChoose: "NIVEAU {level}! KIES EEN MODIFICATOR",
774
+ rerollButton: "🎲 HERROL (1 BESCHIKBAAR)",
775
+ pu_spore_radius_title: "ZURE EXPANSIE",
776
+ pu_spore_radius_desc: "+30% Zuurstraal",
777
+ pu_spore_duration_title: "ZURE DUUR",
778
+ pu_spore_duration_desc: "+3.0s Zuurduur",
779
+ pu_vortex_radius_title: "SINGULARITEIT EXPANSIE",
780
+ pu_vortex_radius_desc: "+25% Draaikolktraal",
781
+ pu_vortex_duration_title: "GRAVITATIEDUUR",
782
+ pu_vortex_duration_desc: "+2.5s Draaikolkduur",
783
+ pu_vortex_power_title: "GRAVITATIESURGE",
784
+ pu_vortex_power_desc: "+40% Trekkracht",
785
+ pu_vortex_pocket_title: "ZAK IMPLOSIE",
786
+ pu_vortex_pocket_desc: "Lanceert vijanden bij einde draaikolk",
787
+ pu_cluster_extra_title: "SCHERF SALVO",
788
+ pu_cluster_extra_desc: "+2 Gele Scherven",
789
+ pu_cluster_homing_title: "ZOEKENDE SCHERVEN",
790
+ pu_cluster_homing_desc: "Scherven zoeken dichtstbijzijnde vijand",
791
+ pu_piercer_aoe_title: "RODE DETONATIE",
792
+ pu_piercer_aoe_desc: "Explosie aan einde vliegpad",
793
+ pu_piercer_homing_title: "ZOEKENDE SNEDE",
794
+ pu_piercer_homing_desc: "Zoekt dichtstbijzijnde vijand",
795
+ pu_piercer_homing_target_title: "KETTING ZOEKER",
796
+ pu_piercer_homing_target_desc: "+1 Extra doelwit",
797
+ pu_shield_fan_title: "TRIPLE ARC BLAST",
798
+ pu_shield_fan_desc: "Vuurt 3 stralen in waaier",
799
+ pu_vampirism_unlock_title: "BIO-VAMPIRISME",
800
+ pu_vampirism_unlock_desc: "Kills herstellen levensringen",
801
+ pu_vampirism_boost_title: "VAMPIRISCHE BOOST",
802
+ pu_vampirism_boost_desc: "+0.3% Genezing per kill",
803
+ pu_core_ring_title: "KERN OVERBELASTING",
804
+ pu_core_ring_desc: "+1 Levensring"
449
805
  },
450
806
  sv: {
451
807
  title: "AXON SURGE",
@@ -468,7 +824,39 @@ const R = {
468
824
  tutorialSettingLabel: "VISA TUTORIAL VID START",
469
825
  tutorialStep1Text: "STEG 1: HÅLL INNE DEN ANGVIVNA FIENDEN",
470
826
  tutorialStep2Text: "STEG 2: KASTA MED HASTIGHET MOT MÅLET",
471
- tutorialDragWarning: "DEN BÄSTA STRATEGIN ÄR ATT KASTA DEM!"
827
+ tutorialDragWarning: "DEN BÄSTA STRATEGIN ÄR ATT KASTA DEM!",
828
+ levelUpChoose: "NIVÅ {level}! VÄLJ MODIFIERARE",
829
+ rerollButton: "🎲 SLÅ OM (1 TILLGÄNGLIG)",
830
+ pu_spore_radius_title: "SYRA-EXPANSION",
831
+ pu_spore_radius_desc: "+30% Syraradie",
832
+ pu_spore_duration_title: "SYRA-VARAKTIGHET",
833
+ pu_spore_duration_desc: "+3.0s Syrastund",
834
+ pu_vortex_radius_title: "SINGULARITETS-EXPANSION",
835
+ pu_vortex_radius_desc: "+25% Virvelradie",
836
+ pu_vortex_duration_title: "GRAVITATIONS-VARAKTIGHET",
837
+ pu_vortex_duration_desc: "+2.5s Virvelstund",
838
+ pu_vortex_power_title: "GRAVITATIONS-STÖT",
839
+ pu_vortex_power_desc: "+40% Dragningskraft",
840
+ pu_vortex_pocket_title: "FICK-IMPLOSION",
841
+ pu_vortex_pocket_desc: "Slungar fiender när virveln dör",
842
+ pu_cluster_extra_title: "SPLITTER-SALVA",
843
+ pu_cluster_extra_desc: "+2 Gula Splitter",
844
+ pu_cluster_homing_title: "SÖKANDE SPLITTER",
845
+ pu_cluster_homing_desc: "Splitter söker närmsta fiende",
846
+ pu_piercer_aoe_title: "RÖD DETONATION",
847
+ pu_piercer_aoe_desc: "Explosion i slutet av banan",
848
+ pu_piercer_homing_title: "SÖKANDE HUGG",
849
+ pu_piercer_homing_desc: "Söker närmsta fiende",
850
+ pu_piercer_homing_target_title: "KEDJE-SÖKARE",
851
+ pu_piercer_homing_target_desc: "+1 Extra mål för hugget",
852
+ pu_shield_fan_title: "TRIPLE ARC BLAST",
853
+ pu_shield_fan_desc: "Skjuter 3 strålar i fjäder",
854
+ pu_vampirism_unlock_title: "BIO-VAMPIRISM",
855
+ pu_vampirism_unlock_desc: "Kills reparerar livsringar",
856
+ pu_vampirism_boost_title: "VAMPYRISK STÖT",
857
+ pu_vampirism_boost_desc: "+0.3% Läkning per kill",
858
+ pu_core_ring_title: "KÄRN-ÖVERLADDNING",
859
+ pu_core_ring_desc: "+1 Livsring"
472
860
  },
473
861
  pl: {
474
862
  title: "AXON SURGE",
@@ -491,7 +879,39 @@ const R = {
491
879
  tutorialSettingLabel: "POKAZUJ SAMOUCZEK PRZY STARTOWIE",
492
880
  tutorialStep1Text: "KROK 1: PRZYTRZYMAJ WSKAZANEGO WROGA",
493
881
  tutorialStep2Text: "KROK 2: RZUĆ Z PRĘDKOŚCIĄ W STRONĘ CELU",
494
- tutorialDragWarning: "NAJLEPSZA STRATEGIA TO RZUCANIE NIMI!"
882
+ tutorialDragWarning: "NAJLEPSZA STRATEGIA TO RZUCANIE NIMI!",
883
+ levelUpChoose: "POZIOM {level}! WYBIERZ MODYFIKATOR",
884
+ rerollButton: "🎲 PRZEROSZADA (1 DOSTĘPNA)",
885
+ pu_spore_radius_title: "EKSPANSJA KWASOWA",
886
+ pu_spore_radius_desc: "+30% Promień kwasu",
887
+ pu_spore_duration_title: "TRWAŁOŚĆ KWASOWA",
888
+ pu_spore_duration_desc: "+3.0s Czas kwasu",
889
+ pu_vortex_radius_title: "EKSPANSJA OSOBLIWOŚCI",
890
+ pu_vortex_radius_desc: "+25% Promień wiru",
891
+ pu_vortex_duration_title: "TRWAŁOŚĆ GRAWITACYJNA",
892
+ pu_vortex_duration_desc: "+2.5s Czas wiru",
893
+ pu_vortex_power_title: "DOŁADOWANIE GRAWITACJI",
894
+ pu_vortex_power_desc: "+40% Siła przyciągania",
895
+ pu_vortex_pocket_title: "IMPLOZJA KIESZONKOWA",
896
+ pu_vortex_pocket_desc: "Wyrzuca wrogów po zakończeniu wiru",
897
+ pu_cluster_extra_title: "SALWA ODŁAMKÓW",
898
+ pu_cluster_extra_desc: "+2 Żółte odłamki",
899
+ pu_cluster_homing_title: "ODŁAMKI NAPROWADZANE",
900
+ pu_cluster_homing_desc: "Odłamki celują w najbliższego wroga",
901
+ pu_piercer_aoe_title: "CZERWONA DETONACJA",
902
+ pu_piercer_aoe_desc: "Eksplozja na końcu toru",
903
+ pu_piercer_homing_title: "CIĘCIE NAPROWADZANE",
904
+ pu_piercer_homing_desc: "Szuka najbliższego wroga",
905
+ pu_piercer_homing_target_title: "ŁAŃCUCH NAPROWADZANIA",
906
+ pu_piercer_homing_target_desc: "+1 Dodatkowy cel cięcia",
907
+ pu_shield_fan_title: "TRIPLE ARC BLAST",
908
+ pu_shield_fan_desc: "Wystrzeliwuje 3 promienie",
909
+ pu_vampirism_unlock_title: "BIO-WAMPIRYZM",
910
+ pu_vampirism_unlock_desc: "Zabójstwa naprawiają pierścienie",
911
+ pu_vampirism_boost_title: "ZRYW WAMPIRYCZNY",
912
+ pu_vampirism_boost_desc: "+0.3% Leczenia za zabójstwo",
913
+ pu_core_ring_title: "PRZEŁADOWANIE RDZENIA",
914
+ pu_core_ring_desc: "+1 Pierścień życia"
495
915
  },
496
916
  id: {
497
917
  title: "AXON SURGE",
@@ -514,7 +934,39 @@ const R = {
514
934
  tutorialSettingLabel: "TAMPILKAN TUTORIAL SAAT MULA",
515
935
  tutorialStep1Text: "LANGKAH 1: TAHAN MUSUH YANG DITUNJUK",
516
936
  tutorialStep2Text: "LANGKAH 2: LEMPAR DENGAN KECEPATAN KE TARGET",
517
- tutorialDragWarning: "STRATEGI TERBAIK ADALAH MELEMPAR MEREKA!"
937
+ tutorialDragWarning: "STRATEGI TERBAIK ADALAH MELEMPAR MEREKA!",
938
+ levelUpChoose: "TINGKAT {level}! PILIH MODIFIKASI",
939
+ rerollButton: "🎲 ACAK ULANG (1 TERSEDIA)",
940
+ pu_spore_radius_title: "EKSPANSI ASAM",
941
+ pu_spore_radius_desc: "+30% Radius Asam",
942
+ pu_spore_duration_title: "DURASI ASAM",
943
+ pu_spore_duration_desc: "+3.0s Durasi Asam",
944
+ pu_vortex_radius_title: "EKSPANSI SINGULARITAS",
945
+ pu_vortex_radius_desc: "+25% Radius Pusaran",
946
+ pu_vortex_duration_title: "DURASI GRAVITASI",
947
+ pu_vortex_duration_desc: "+2.5s Durasi Pusaran",
948
+ pu_vortex_power_title: "LONJAKAN GRAVITASI",
949
+ pu_vortex_power_desc: "+40% Daya Tarik",
950
+ pu_vortex_pocket_title: "IMPLOSI KANTONG",
951
+ pu_vortex_pocket_desc: "Lemparkan musuh saat pusaran berakhir",
952
+ pu_cluster_extra_title: "SERANGAN SERPIHAN",
953
+ pu_cluster_extra_desc: "+2 Serpihan Kuning",
954
+ pu_cluster_homing_title: "SERPIHAN PENCARI",
955
+ pu_cluster_homing_desc: "Serpihan mengincar musuh terdekat",
956
+ pu_piercer_aoe_title: "LEDAKAN MERAH",
957
+ pu_piercer_aoe_desc: "Ledakan di akhir lintasan",
958
+ pu_piercer_homing_title: "TEBASAN PENCARI",
959
+ pu_piercer_homing_desc: "Mencari musuh terdekat",
960
+ pu_piercer_homing_target_title: "PENCARI BERANTAI",
961
+ pu_piercer_homing_target_desc: "+1 Target tambahan",
962
+ pu_shield_fan_title: "TRIPLE ARC BLAST",
963
+ pu_shield_fan_desc: "Menembakkan 3 sinar kipas",
964
+ pu_vampirism_unlock_title: "BIO-VAMPIRISME",
965
+ pu_vampirism_unlock_desc: "Eliminasi memperbaiki cincin",
966
+ pu_vampirism_boost_title: "DORONGAN VAMPIR",
967
+ pu_vampirism_boost_desc: "+0.3% Pemulihan per eliminasi",
968
+ pu_core_ring_title: "OVERCHARGE INTI",
969
+ pu_core_ring_desc: "+1 Cincin Nyawa"
518
970
  },
519
971
  tr: {
520
972
  title: "AXON SURGE",
@@ -537,7 +989,39 @@ const R = {
537
989
  tutorialSettingLabel: "BAŞLANGIÇTA EĞİTİMİ GÖSTER",
538
990
  tutorialStep1Text: "ADIM 1: GÖSTERİLEN DÜŞMANI BASILI TUTUN",
539
991
  tutorialStep2Text: "ADIM 2: HEDEFE HIZLA FIRLATIN",
540
- tutorialDragWarning: "EN İYİ STRATEJİ ONLARI FIRLATMAKTIR!"
992
+ tutorialDragWarning: "EN İYİ STRATEJİ ONLARI FIRLATMAKTIR!",
993
+ levelUpChoose: "SEVİYE {level}! GÜÇLENDİRME SEÇ",
994
+ rerollButton: "🎲 YENİDEN ZAR AT (1 HAKK)",
995
+ pu_spore_radius_title: "ASİT GENİŞLEMESİ",
996
+ pu_spore_radius_desc: "+30% Asit Yarıçapı",
997
+ pu_spore_duration_title: "ASİT SÜRESİ",
998
+ pu_spore_duration_desc: "+3.0s Asit Süresi",
999
+ pu_vortex_radius_title: "TEKİLLİK GENİŞLEMESİ",
1000
+ pu_vortex_radius_desc: "+25% Girdap Yarıçapı",
1001
+ pu_vortex_duration_title: "YERÇEKİMİ SÜRESİ",
1002
+ pu_vortex_duration_desc: "+2.5s Girdap Süresi",
1003
+ pu_vortex_power_title: "YERÇEKİMİ ARTIŞI",
1004
+ pu_vortex_power_desc: "+40% Çekim Gücü",
1005
+ pu_vortex_pocket_title: "CEP İÇİ İÇE ÇÖKME",
1006
+ pu_vortex_pocket_desc: "Girdap biterken düşmanları fırlatır",
1007
+ pu_cluster_extra_title: "ŞARAPNEL PATLAMASI",
1008
+ pu_cluster_extra_desc: "+2 Sarı Şarapnel",
1009
+ pu_cluster_homing_title: "TAKİP EDEN ŞARAPNEL",
1010
+ pu_cluster_homing_desc: "Şarapneller en yakın düşmana yönelir",
1011
+ pu_piercer_aoe_title: "KIRMIZI PATLAMA",
1012
+ pu_piercer_aoe_desc: "Menzil sonunda alan patlaması",
1013
+ pu_piercer_homing_title: "TAKİP EDEN KESİŞ",
1014
+ pu_piercer_homing_desc: "En yakın düşmanı arar",
1015
+ pu_piercer_homing_target_title: "ZİNCİR TAKİPÇİSİ",
1016
+ pu_piercer_homing_target_desc: "+1 Ekstra hedef",
1017
+ pu_shield_fan_title: "TRIPLE ARC BLAST",
1018
+ pu_shield_fan_desc: "Yelpaze şeklinde 3 ışın atar",
1019
+ pu_vampirism_unlock_title: "BİYO-VAMPİRLİK",
1020
+ pu_vampirism_unlock_desc: "Skorlar halkaları onarır",
1021
+ pu_vampirism_boost_title: "VAMPİR ARTIŞI",
1022
+ pu_vampirism_boost_desc: "Skor başına +0.3% İyileşme",
1023
+ pu_core_ring_title: "ÇEKİRDEK AŞIRI YÜKLEME",
1024
+ pu_core_ring_desc: "+1 Can Halkası"
541
1025
  },
542
1026
  ru: {
543
1027
  title: "AXON SURGE",
@@ -560,7 +1044,39 @@ const R = {
560
1044
  tutorialSettingLabel: "ПОКАЗЫВАТЬ ОБУЧЕНИЕ ПРИ СТАРТЕ",
561
1045
  tutorialStep1Text: "ШАГ 1: УДЕРЖИВАЙТЕ УКАЗАННОГО ВРАГА",
562
1046
  tutorialStep2Text: "ШАГ 2: БРОСАЙТЕ С ИМПУЛЬСОМ В ЦЕЛЬ",
563
- tutorialDragWarning: "ЛУЧШАЯ СТРАТЕГИЯ - БРОСАТЬ ИХ С ИМПУЛЬСОМ!"
1047
+ tutorialDragWarning: "ЛУЧШАЯ СТРАТЕГИЯ - БРОСАТЬ ИХ С ИМПУЛЬСОМ!",
1048
+ levelUpChoose: "УРОВЕНЬ {level}! ВЫБЕРИТЕ МОДИФИКАТОР",
1049
+ rerollButton: "🎲 ПЕРЕБРОСИТЬ (1 ДОСТУПЕН)",
1050
+ pu_spore_radius_title: "КИСЛОТНОЕ РАСШИРЕНИЕ",
1051
+ pu_spore_radius_desc: "+30% Радиус кислоты",
1052
+ pu_spore_duration_title: "КИСЛОТНАЯ ДЛИТЕЛЬНОСТЬ",
1053
+ pu_spore_duration_desc: "+3.0с Длительность кислоты",
1054
+ pu_vortex_radius_title: "СИНГУЛЯРНОЕ РАСШИРЕНИЕ",
1055
+ pu_vortex_radius_desc: "+25% Радиус воронки",
1056
+ pu_vortex_duration_title: "ГРАВИТАЦИОННОЕ ВРЕМЯ",
1057
+ pu_vortex_duration_desc: "+2.5с Длительность воронки",
1058
+ pu_vortex_power_title: "ГРАВИТАЦИОННЫЙ ИМПУЛЬС",
1059
+ pu_vortex_power_desc: "+40% Сила притяжения",
1060
+ pu_vortex_pocket_title: "КАРМАННАЯ ИМПЛОЗИЯ",
1061
+ pu_vortex_pocket_desc: "Выбрасывает врагов в конце воронки",
1062
+ pu_cluster_extra_title: "ОСКОЛОЧНЫЙ ЗАЛП",
1063
+ pu_cluster_extra_desc: "+2 Желтых осколка",
1064
+ pu_cluster_homing_title: "НАВЕДЕННЫЕ ОСКОЛКИ",
1065
+ pu_cluster_homing_desc: "Осколки летят к ближнему врагу",
1066
+ pu_piercer_aoe_title: "КРАСНЫЙ ВЗРЫВ",
1067
+ pu_piercer_aoe_desc: "Взрыв в конце траектории",
1068
+ pu_piercer_homing_title: "САМОНАВОДЯЩИЙСЯ УДАР",
1069
+ pu_piercer_homing_desc: "Ищет ближайшего врага",
1070
+ pu_piercer_homing_target_title: "ЦЕПНОЙ НАВОДЧИК",
1071
+ pu_piercer_homing_target_desc: "+1 Дополнительная цель",
1072
+ pu_shield_fan_title: "TRIPLE ARC BLAST",
1073
+ pu_shield_fan_desc: "Залп из 3 лучей веером",
1074
+ pu_vampirism_unlock_title: "БИО-ВАМПИРИЗМ",
1075
+ pu_vampirism_unlock_desc: "Убийства чинят кольца",
1076
+ pu_vampirism_boost_title: "ВАМПИРИЧЕСКИЙ ИМПУЛЬС",
1077
+ pu_vampirism_boost_desc: "+0.3% Лечение за убийство",
1078
+ pu_core_ring_title: "ПЕРЕГРУЗКА ЯДРА",
1079
+ pu_core_ring_desc: "+1 Кольцо жизни"
564
1080
  },
565
1081
  ja: {
566
1082
  title: "AXON SURGE",
@@ -583,7 +1099,39 @@ const R = {
583
1099
  tutorialSettingLabel: "起動時にチュートリアルを表示",
584
1100
  tutorialStep1Text: "ステップ1: 指定された敵を長押し",
585
1101
  tutorialStep2Text: "ステップ2: ターゲットに向けて勢いよくフリック",
586
- tutorialDragWarning: "最高の戦略は勢いよく投げることです!"
1102
+ tutorialDragWarning: "最高の戦略は勢いよく投げることです!",
1103
+ levelUpChoose: "レベル {level}! 強化を選択",
1104
+ rerollButton: "🎲 リロール (残り1回)",
1105
+ pu_spore_radius_title: "アシッド拡大",
1106
+ pu_spore_radius_desc: "+30% アシッド範囲",
1107
+ pu_spore_duration_title: "アシッド持続",
1108
+ pu_spore_duration_desc: "+3.0秒 持続時間",
1109
+ pu_vortex_radius_title: "シンギュラリティ拡大",
1110
+ pu_vortex_radius_desc: "+25% ヴォルテックス範囲",
1111
+ pu_vortex_duration_title: "グラビティ持続",
1112
+ pu_vortex_duration_desc: "+2.5秒 ヴォルテックス持続",
1113
+ pu_vortex_power_title: "グラビティサージ",
1114
+ pu_vortex_power_desc: "+40% 吸引力",
1115
+ pu_vortex_pocket_title: "ポケットインプロージョン",
1116
+ pu_vortex_pocket_desc: "消滅時に敵を射出",
1117
+ pu_cluster_extra_title: "クラスターバースト",
1118
+ pu_cluster_extra_desc: "+2 黄色破片",
1119
+ pu_cluster_homing_title: "ホーミング破片",
1120
+ pu_cluster_homing_desc: "破片が近くの敵を追尾",
1121
+ pu_piercer_aoe_title: "レッドデトネーション",
1122
+ pu_piercer_aoe_desc: "軌道終端で範囲爆発",
1123
+ pu_piercer_homing_title: "シーカーバース",
1124
+ pu_piercer_homing_desc: "近くの敵を自動追尾",
1125
+ pu_piercer_homing_target_title: "チェインシーカー",
1126
+ pu_piercer_homing_target_desc: "+1 追加追尾ターゲット",
1127
+ pu_shield_fan_title: "TRIPLE ARC BLAST",
1128
+ pu_shield_fan_desc: "3方向扇状ビーム発射",
1129
+ pu_vampirism_unlock_title: "バイオヴァンパイリズム",
1130
+ pu_vampirism_unlock_desc: "撃破でライフリング修復",
1131
+ pu_vampirism_boost_title: "ヴァンパイアサージ",
1132
+ pu_vampirism_boost_desc: "撃破ごと +0.3% 回復",
1133
+ pu_core_ring_title: "コアオーバーチャージ",
1134
+ pu_core_ring_desc: "+1 ライフリング"
587
1135
  },
588
1136
  ko: {
589
1137
  title: "AXON SURGE",
@@ -606,7 +1154,39 @@ const R = {
606
1154
  tutorialSettingLabel: "시작 시 튜토리얼 표시",
607
1155
  tutorialStep1Text: "1단계: 표시된 적을 길게 누르세요",
608
1156
  tutorialStep2Text: "2단계: 표적을 향해 빠르게 튕기세요",
609
- tutorialDragWarning: "최선의 전략은 적을 튕겨 던지는 것입니다!"
1157
+ tutorialDragWarning: "최선의 전략은 적을 튕겨 던지는 것입니다!",
1158
+ levelUpChoose: "레벨 {level}! 강화 선택",
1159
+ rerollButton: "🎲 리롤 (1회 가능)",
1160
+ pu_spore_radius_title: "산성 확장",
1161
+ pu_spore_radius_desc: "+30% 산성 범주",
1162
+ pu_spore_duration_title: "산성 지속",
1163
+ pu_spore_duration_desc: "+3.0초 지속 시간",
1164
+ pu_vortex_radius_title: "특이점 확장",
1165
+ pu_vortex_radius_desc: "+25% 보텍스 범주",
1166
+ pu_vortex_duration_title: "중력 지속",
1167
+ pu_vortex_duration_desc: "+2.5초 보텍스 지속",
1168
+ pu_vortex_power_title: "중력 서지",
1169
+ pu_vortex_power_desc: "+40% 끌어당기는 힘",
1170
+ pu_vortex_pocket_title: "포켓 임플로전",
1171
+ pu_vortex_pocket_desc: "보텍스 종료 시 적 발사",
1172
+ pu_cluster_extra_title: "클러스터 버스트",
1173
+ pu_cluster_extra_desc: "+2 노란 파편",
1174
+ pu_cluster_homing_title: "유도 파편",
1175
+ pu_cluster_homing_desc: "파편이 가까운 적 추적",
1176
+ pu_piercer_aoe_title: "레드 폭발",
1177
+ pu_piercer_aoe_desc: "궤적 끝에서 범위 폭발",
1178
+ pu_piercer_homing_title: "시커 절단",
1179
+ pu_piercer_homing_desc: "가장 가까운 적 추적",
1180
+ pu_piercer_homing_target_title: "체인 시커",
1181
+ pu_piercer_homing_target_desc: "+1 추가 추적 타겟",
1182
+ pu_shield_fan_title: "TRIPLE ARC BLAST",
1183
+ pu_shield_fan_desc: "3방향 부채꼴 빔 발사",
1184
+ pu_vampirism_unlock_title: "바이오 뱀파이어리즘",
1185
+ pu_vampirism_unlock_desc: "처치 시 생명 고리 복구",
1186
+ pu_vampirism_boost_title: "뱀파이어 서지",
1187
+ pu_vampirism_boost_desc: "처치당 +0.3% 회복",
1188
+ pu_core_ring_title: "코어 오버차지",
1189
+ pu_core_ring_desc: "+1 생명 고리"
610
1190
  },
611
1191
  zh: {
612
1192
  title: "AXON SURGE",
@@ -629,9 +1209,41 @@ const R = {
629
1209
  tutorialSettingLabel: "启动时显示教程",
630
1210
  tutorialStep1Text: "步骤 1: 按住指定的敌人",
631
1211
  tutorialStep2Text: "步骤 2: 朝目标快速挥动抛投",
632
- tutorialDragWarning: "最佳策略是快速挥动抛投!"
633
- }
634
- }, H = [
1212
+ tutorialDragWarning: "最佳策略是快速挥动抛投!",
1213
+ levelUpChoose: "等级 {level}! 选择强化",
1214
+ rerollButton: "🎲 重刷 (剩余1次)",
1215
+ pu_spore_radius_title: "酸液扩张",
1216
+ pu_spore_radius_desc: "+30% 酸液范围",
1217
+ pu_spore_duration_title: "酸液持久",
1218
+ pu_spore_duration_desc: "+3.0秒 酸液持续",
1219
+ pu_vortex_radius_title: "奇点扩张",
1220
+ pu_vortex_radius_desc: "+25% 漩涡范围",
1221
+ pu_vortex_duration_title: "引力持久",
1222
+ pu_vortex_duration_desc: "+2.5秒 漩涡持续",
1223
+ pu_vortex_power_title: "引力涌动",
1224
+ pu_vortex_power_desc: "+40% 吸引力",
1225
+ pu_vortex_pocket_title: "袖珍内爆",
1226
+ pu_vortex_pocket_desc: "漩涡结束时发射敌人",
1227
+ pu_cluster_extra_title: "碎片爆发",
1228
+ pu_cluster_extra_desc: "+2 黄色碎片",
1229
+ pu_cluster_homing_title: "追踪碎片",
1230
+ pu_cluster_homing_desc: "碎片自动追踪最近敌人",
1231
+ pu_piercer_aoe_title: "红色引爆",
1232
+ pu_piercer_aoe_desc: "轨迹末端范围爆炸",
1233
+ pu_piercer_homing_title: "追踪斩击",
1234
+ pu_piercer_homing_desc: "自动寻找最近敌人",
1235
+ pu_piercer_homing_target_title: "连锁追踪",
1236
+ pu_piercer_homing_target_desc: "+1 额外追踪目标",
1237
+ pu_shield_fan_title: "TRIPLE ARC BLAST",
1238
+ pu_shield_fan_desc: "扇形发射 3 道光束",
1239
+ pu_vampirism_unlock_title: "生物吸血",
1240
+ pu_vampirism_unlock_desc: "击杀可修复生命环",
1241
+ pu_vampirism_boost_title: "吸血涌动",
1242
+ pu_vampirism_boost_desc: "每次击杀 +0.3% 治疗",
1243
+ pu_core_ring_title: "核心过载",
1244
+ pu_core_ring_desc: "+1 生命环"
1245
+ }
1246
+ }, Y = [
635
1247
  "es",
636
1248
  "en",
637
1249
  "fr",
@@ -648,29 +1260,29 @@ const R = {
648
1260
  "ko",
649
1261
  "zh"
650
1262
  ];
651
- function N(E) {
652
- return H.includes(E);
1263
+ function w(E) {
1264
+ return Y.includes(E);
653
1265
  }
654
- const k = "axon_surge_language", U = "axon_surge_language_explicit";
655
- class Z {
1266
+ const V = "axon_surge_language";
1267
+ class Q {
656
1268
  currentLanguage;
657
1269
  constructor(t) {
658
1270
  this.currentLanguage = this.detectLanguage(t);
659
1271
  }
660
1272
  detectLanguage(t) {
661
- if (t && N(t))
662
- return t;
663
1273
  try {
664
- const e = localStorage.getItem(U) === "true", i = localStorage.getItem(k);
665
- if (e && i && N(i))
666
- return i;
1274
+ const e = localStorage.getItem(V);
1275
+ if (e && w(e))
1276
+ return e;
667
1277
  } catch {
668
1278
  }
1279
+ if (t && w(t))
1280
+ return t;
669
1281
  try {
670
1282
  const e = (document.documentElement.lang || document.body?.getAttribute("lang") || document.documentElement.getAttribute("data-lang") || "").toLowerCase();
671
1283
  if (e) {
672
1284
  const i = e.split("-")[0];
673
- if (i && N(i))
1285
+ if (i && w(i))
674
1286
  return i;
675
1287
  }
676
1288
  } catch {
@@ -679,31 +1291,118 @@ class Z {
679
1291
  const e = (navigator.language || navigator.languages && navigator.languages[0] || "").toLowerCase();
680
1292
  if (e) {
681
1293
  const i = e.split("-")[0];
682
- if (i && N(i))
1294
+ if (i && w(i))
683
1295
  return i;
684
1296
  }
685
1297
  } catch {
686
1298
  }
687
1299
  return "en";
688
1300
  }
689
- setLanguage(t, e = !0) {
690
- if (R[t] && (this.currentLanguage = t, e))
1301
+ setLanguage(t) {
1302
+ if (P[t]) {
1303
+ this.currentLanguage = t;
691
1304
  try {
692
- localStorage.setItem(k, t), localStorage.setItem(U, "true");
1305
+ localStorage.setItem(V, t);
693
1306
  } catch {
694
1307
  }
1308
+ }
695
1309
  }
696
1310
  getLanguage() {
697
1311
  return this.currentLanguage;
698
1312
  }
699
1313
  translate(t, e) {
700
- let s = (R[this.currentLanguage] || R.en)[t] || R.en[t] || String(t);
1314
+ let s = (P[this.currentLanguage] || P.en)[t] || P.en[t] || String(t);
701
1315
  return e && Object.entries(e).forEach(([a, l]) => {
702
1316
  s = s.replace(`{${a}}`, String(l));
703
1317
  }), s;
704
1318
  }
705
1319
  }
706
- class X {
1320
+ class tt {
1321
+ static update(t, e, i) {
1322
+ const s = A.getInstance().getConfig();
1323
+ for (let a = t.length - 1; a >= 0; a--) {
1324
+ const l = t[a];
1325
+ if (l) {
1326
+ l.duration += i;
1327
+ for (const n of e) {
1328
+ if (!n.active || n.isGrabbed || n.isDying || n.isStationaryShield || n.isThrown && n.type === "piercer") continue;
1329
+ const o = l.position.x - n.position.x, r = l.position.y - n.position.y, c = Math.hypot(o, r);
1330
+ if (c > 2 && c <= l.radius) {
1331
+ const h = Math.pow(1 - c / l.radius, 0.7), u = l.pullForce * h, p = Math.atan2(r, o);
1332
+ n.velocity.x += Math.cos(p) * u * i, n.velocity.y += Math.sin(p) * u * i, n.position.x += Math.cos(p) * u * i * 0.8, n.position.y += Math.sin(p) * u * i * 0.8;
1333
+ }
1334
+ }
1335
+ if (l.duration >= l.maxDuration) {
1336
+ if (s.gravityVortex.hasImplosionLaunch)
1337
+ for (const n of e) {
1338
+ if (!n.active || n.isDying) continue;
1339
+ const o = n.position.x - l.position.x, r = n.position.y - l.position.y;
1340
+ if (Math.hypot(o, r) <= l.radius) {
1341
+ const h = Math.atan2(r, o), u = 1200;
1342
+ n.isThrown = !0, n.wasManipulated = !0, n.velocity = {
1343
+ x: Math.cos(h) * u,
1344
+ y: Math.sin(h) * u
1345
+ };
1346
+ }
1347
+ }
1348
+ t.splice(a, 1);
1349
+ }
1350
+ }
1351
+ }
1352
+ }
1353
+ }
1354
+ class et {
1355
+ static update(t, e, i, s, a, l, n, o, r, c) {
1356
+ for (const h of e) {
1357
+ if (!h.active || h.isGrabbed || h.isDying) continue;
1358
+ const u = t.position.x - h.position.x, p = t.position.y - h.position.y;
1359
+ if (Math.hypot(u, p) <= t.radius + h.radius) {
1360
+ if (h.active = !1, t.takeDamage()) {
1361
+ n.emit("onCoreDamaged", { currentIntegrity: t.integrity }), i.push({
1362
+ id: Math.random().toString(),
1363
+ position: { ...t.position },
1364
+ radius: 20,
1365
+ maxRadius: Math.max(r, c) * 1.3,
1366
+ color: "#00f0ff",
1367
+ alpha: 1,
1368
+ lifetime: 0,
1369
+ maxLifetime: 0.8
1370
+ }), l.triggerScreenShake({ x: u, y: p }, 25), l.triggerHitstop(0.15), l.triggerFlash(0.6);
1371
+ for (const g of e)
1372
+ if (g.active && !g.isGrabbed) {
1373
+ g.triggerDissolveDeath();
1374
+ for (let f = 0; f < 8; f++) {
1375
+ const x = Math.random() * Math.PI * 2, b = 100 + Math.random() * 200;
1376
+ s.push({
1377
+ id: Math.random().toString(),
1378
+ position: { ...g.position },
1379
+ velocity: { x: Math.cos(x) * b, y: Math.sin(x) * b },
1380
+ color: "#00f0ff",
1381
+ radius: 3 + Math.random() * 3,
1382
+ alpha: 1,
1383
+ lifetime: 0,
1384
+ maxLifetime: 0.5
1385
+ });
1386
+ }
1387
+ }
1388
+ a.push({
1389
+ id: Math.random().toString(),
1390
+ text: "CORE OVERLOAD PULSE!",
1391
+ position: { ...t.position },
1392
+ velocity: { x: 0, y: -90 },
1393
+ color: "#00f0ff",
1394
+ alpha: 1,
1395
+ lifetime: 0,
1396
+ maxLifetime: 1.5,
1397
+ size: 32
1398
+ }), t.integrity <= 0 && n.emit("onGameOver", { score: o.value, wave: 1 });
1399
+ }
1400
+ break;
1401
+ }
1402
+ }
1403
+ }
1404
+ }
1405
+ class it {
707
1406
  execute(t) {
708
1407
  const { thrownEnemy: e, targetEnemy: i, shockwaves: s, particles: a, floatingTexts: l } = t;
709
1408
  i.active = !1, s.push({
@@ -716,12 +1415,12 @@ class X {
716
1415
  lifetime: 0,
717
1416
  maxLifetime: 0.5
718
1417
  });
719
- for (let r = 0; r < 30; r++) {
720
- const n = Math.random() * Math.PI * 2, o = 180 + Math.random() * 320;
1418
+ for (let n = 0; n < 30; n++) {
1419
+ const o = Math.random() * Math.PI * 2, r = 180 + Math.random() * 320;
721
1420
  a.push({
722
1421
  id: Math.random().toString(),
723
1422
  position: { ...i.position },
724
- velocity: { x: Math.cos(n) * o, y: Math.sin(n) * o },
1423
+ velocity: { x: Math.cos(o) * r, y: Math.sin(o) * r },
725
1424
  color: "#ff2a5f",
726
1425
  radius: 3 + Math.random() * 4,
727
1426
  alpha: 1,
@@ -742,19 +1441,19 @@ class X {
742
1441
  });
743
1442
  }
744
1443
  }
745
- class _ {
1444
+ class st {
746
1445
  execute(t) {
747
- const { thrownEnemy: e, pools: i, shockwaves: s, particles: a, floatingTexts: l, eventBus: r } = t, n = e.position;
1446
+ const { thrownEnemy: e, pools: i, shockwaves: s, particles: a, floatingTexts: l, eventBus: n } = t, o = e.position;
748
1447
  i.push({
749
1448
  id: Math.random().toString(),
750
- position: { ...n },
1449
+ position: { ...o },
751
1450
  radius: 220,
752
1451
  duration: 0,
753
1452
  maxDuration: 7,
754
1453
  damage: 50
755
1454
  }), s.push({
756
1455
  id: Math.random().toString(),
757
- position: { ...n },
1456
+ position: { ...o },
758
1457
  radius: 10,
759
1458
  maxRadius: 240,
760
1459
  color: "#39ff14",
@@ -762,12 +1461,12 @@ class _ {
762
1461
  lifetime: 0,
763
1462
  maxLifetime: 0.6
764
1463
  });
765
- for (let o = 0; o < 45; o++) {
766
- const h = Math.random() * Math.PI * 2, c = 120 + Math.random() * 260;
1464
+ for (let r = 0; r < 45; r++) {
1465
+ const c = Math.random() * Math.PI * 2, h = 120 + Math.random() * 260;
767
1466
  a.push({
768
1467
  id: Math.random().toString(),
769
- position: { ...n },
770
- velocity: { x: Math.cos(h) * c, y: Math.sin(h) * c },
1468
+ position: { ...o },
1469
+ velocity: { x: Math.cos(c) * h, y: Math.sin(c) * h },
771
1470
  color: "#39ff14",
772
1471
  radius: 4 + Math.random() * 5,
773
1472
  alpha: 1,
@@ -778,22 +1477,22 @@ class _ {
778
1477
  l.push({
779
1478
  id: Math.random().toString(),
780
1479
  text: "MASSIVE SPORE NEBULA",
781
- position: { ...n },
1480
+ position: { ...o },
782
1481
  velocity: { x: 0, y: -60 },
783
1482
  color: "#39ff14",
784
1483
  alpha: 1,
785
1484
  lifetime: 0,
786
1485
  maxLifetime: 1.2,
787
1486
  size: 26
788
- }), e.active = !1, r.emit("onPoolCreated", { position: n });
1487
+ }), e.active = !1, n.emit("onPoolCreated", { position: o });
789
1488
  }
790
1489
  }
791
- class $ {
1490
+ class at {
792
1491
  execute(t) {
793
- const { thrownEnemy: e, targetEnemy: i, allEnemies: s, shockwaves: a, particles: l, floatingTexts: r } = t, n = i.position;
1492
+ const { thrownEnemy: e, targetEnemy: i, allEnemies: s, shockwaves: a, particles: l, floatingTexts: n } = t, o = i.position;
794
1493
  e.active = !1, i.active = !1, a.push({
795
1494
  id: Math.random().toString(),
796
- position: { ...n },
1495
+ position: { ...o },
797
1496
  radius: 15,
798
1497
  maxRadius: 280,
799
1498
  color: "#ffd700",
@@ -801,22 +1500,37 @@ class $ {
801
1500
  lifetime: 0,
802
1501
  maxLifetime: 0.6
803
1502
  });
804
- for (let o = 0; o < 6; o++) {
805
- const h = o * Math.PI * 2 / 6, c = {
806
- x: n.x + Math.cos(h) * 15,
807
- y: n.y + Math.sin(h) * 15
808
- }, u = S.createEnemy("micro", c, {
809
- x: c.x + Math.cos(h) * 200,
810
- y: c.y + Math.sin(h) * 200
1503
+ const r = A.getInstance().getConfig(), c = r.cluster.fragmentCount, h = r.cluster.hasHoming;
1504
+ for (let u = 0; u < c; u++) {
1505
+ const p = u * Math.PI * 2 / c, _ = 800 + Math.random() * 300, d = {
1506
+ x: o.x + Math.cos(p) * 45,
1507
+ y: o.y + Math.sin(p) * 45
1508
+ };
1509
+ let g = p;
1510
+ if (h) {
1511
+ let x = null, b = 1 / 0;
1512
+ for (const v of s) {
1513
+ if (v === e || v === i || !v.active || v.isGrabbed || v.isDying) continue;
1514
+ const I = Math.hypot(v.position.x - d.x, v.position.y - d.y);
1515
+ I < b && (b = I, x = v);
1516
+ }
1517
+ x && (g = Math.atan2(x.position.y - d.y, x.position.x - d.x));
1518
+ }
1519
+ const f = T.createEnemy("micro", d, {
1520
+ x: d.x + Math.cos(g) * 500,
1521
+ y: d.y + Math.sin(g) * 500
811
1522
  });
812
- u.isThrown = !0, s.push(u);
1523
+ f.isThrown = !0, f.wasManipulated = !0, f.velocity = {
1524
+ x: Math.cos(g) * _,
1525
+ y: Math.sin(g) * _
1526
+ }, s.push(f);
813
1527
  }
814
- for (let o = 0; o < 35; o++) {
815
- const h = Math.random() * Math.PI * 2, c = 200 + Math.random() * 300;
1528
+ for (let u = 0; u < 35; u++) {
1529
+ const p = Math.random() * Math.PI * 2, _ = 200 + Math.random() * 300;
816
1530
  l.push({
817
1531
  id: Math.random().toString(),
818
- position: { ...n },
819
- velocity: { x: Math.cos(h) * c, y: Math.sin(h) * c },
1532
+ position: { ...o },
1533
+ velocity: { x: Math.cos(p) * _, y: Math.sin(p) * _ },
820
1534
  color: "#ffd700",
821
1535
  radius: 4 + Math.random() * 4,
822
1536
  alpha: 1,
@@ -824,10 +1538,10 @@ class $ {
824
1538
  maxLifetime: 0.6
825
1539
  });
826
1540
  }
827
- r.push({
1541
+ n.push({
828
1542
  id: Math.random().toString(),
829
1543
  text: "CLUSTER DETONATION",
830
- position: { ...n },
1544
+ position: { ...o },
831
1545
  velocity: { x: 0, y: -60 },
832
1546
  color: "#ffd700",
833
1547
  alpha: 1,
@@ -837,7 +1551,7 @@ class $ {
837
1551
  });
838
1552
  }
839
1553
  }
840
- class z {
1554
+ class ot {
841
1555
  execute(t) {
842
1556
  const { thrownEnemy: e, targetEnemy: i, vortices: s, shockwaves: a } = t, l = {
843
1557
  x: (e.position.x + i.position.x) / 2,
@@ -862,120 +1576,213 @@ class z {
862
1576
  }), e.triggerDissolveDeath(), i.triggerDissolveDeath();
863
1577
  }
864
1578
  }
865
- class S {
1579
+ class nt {
1580
+ execute(t) {
1581
+ const { thrownEnemy: e, targetEnemy: i, allEnemies: s, shockwaves: a, particles: l, floatingTexts: n } = t, o = e.shieldAngle || e.rotation, r = A.getInstance().getConfig().shield, c = r.blastSpeed;
1582
+ if (e.isStationaryShield = !1, e.isThrown = !0, e.rotation = o, e.velocity = {
1583
+ x: Math.cos(o) * c,
1584
+ y: Math.sin(o) * c
1585
+ }, r.isFanBlast) {
1586
+ const h = [-Math.PI / 6, Math.PI / 6];
1587
+ for (const u of h) {
1588
+ const p = o + u, _ = T.createEnemy("heavy", { ...e.position }, { x: 0, y: 0 });
1589
+ _.isStationaryShield = !1, _.isThrown = !0, _.wasManipulated = !0, _.shieldAngle = p, _.rotation = p, _.velocity = {
1590
+ x: Math.cos(p) * c,
1591
+ y: Math.sin(p) * c
1592
+ }, s.push(_);
1593
+ }
1594
+ }
1595
+ i.active = !1, i.triggerDissolveDeath(), n.push({
1596
+ id: Math.random().toString(),
1597
+ text: "ARC BLAST!",
1598
+ position: { ...e.position },
1599
+ velocity: { x: 0, y: -50 },
1600
+ color: "#00f5ff",
1601
+ alpha: 1,
1602
+ lifetime: 0,
1603
+ maxLifetime: 0.9,
1604
+ size: 24
1605
+ });
1606
+ for (let h = 0; h < 50; h++) {
1607
+ const u = (Math.random() - 0.5) * 1.5, p = o + u, _ = 300 + Math.random() * 500;
1608
+ l.push({
1609
+ id: Math.random().toString(),
1610
+ position: { ...e.position },
1611
+ velocity: { x: Math.cos(p) * _, y: Math.sin(p) * _ },
1612
+ color: "#00f5ff",
1613
+ radius: 4 + Math.random() * 6,
1614
+ alpha: 1,
1615
+ lifetime: 0,
1616
+ maxLifetime: 0.7
1617
+ });
1618
+ }
1619
+ n.push({
1620
+ id: Math.random().toString(),
1621
+ text: "ARC BLAST!",
1622
+ position: { ...e.position },
1623
+ velocity: { x: 0, y: -50 },
1624
+ color: "#00f5ff",
1625
+ alpha: 1,
1626
+ lifetime: 0,
1627
+ maxLifetime: 0.9,
1628
+ size: 24
1629
+ });
1630
+ }
1631
+ }
1632
+ class T {
866
1633
  static createEnemy(t, e, i) {
867
- const s = `enemy_${Date.now()}_${Math.random()}`, a = new D(s);
1634
+ const s = `enemy_${Date.now()}_${Math.random()}`, a = new H(s);
868
1635
  return this.configureEnemy(a, t, e, i), a;
869
1636
  }
870
1637
  static configureEnemy(t, e, i, s) {
871
1638
  t.type = e, t.position = { ...i }, t.active = !0, t.isGrabbed = !1, t.isThrown = !1;
872
- const a = s.x - i.x, l = s.y - i.y, r = Math.atan2(l, a);
873
- let n = 70, o = 100, h = 20, c = "#ff2a5f", u = null;
874
- e === "piercer" ? (n = 95, o = 140, h = 18, c = "#ff2a5f", u = new X()) : e === "spore" ? (n = 65, o = 90, h = 24, c = "#39ff14", u = new _()) : e === "cluster" ? (n = 50, o = 75, h = 26, c = "#ffd700", u = new $()) : e === "parasite" ? (n = 80, o = 110, h = 22, c = "#9d4edd", u = new z()) : e === "micro" && (n = 130, o = 160, h = 12, c = "#ffd700"), t.radius = h, t.color = c, t.strategy = u, t.maxSpeed = o, t.velocity = {
875
- x: Math.cos(r) * n,
876
- y: Math.sin(r) * n
1639
+ const a = s.x - i.x, l = s.y - i.y, n = Math.atan2(l, a);
1640
+ let o = 70, r = 100, c = 20, h = "#ff2a5f", u = null;
1641
+ e === "piercer" ? (o = 95, r = 140, c = 18, h = "#ff2a5f", u = new it()) : e === "spore" ? (o = 65, r = 90, c = 24, h = "#39ff14", u = new st()) : e === "cluster" ? (o = 50, r = 75, c = 26, h = "#ffd700", u = new at()) : e === "parasite" ? (o = 80, r = 110, c = 22, h = "#9d4edd", u = new ot()) : e === "heavy" ? (o = 35, r = 50, c = 34, h = "#00f5ff", u = new nt(), t.rotation = Math.random() * Math.PI * 2) : e === "micro" && (o = 130, r = 160, c = 12, h = "#ffd700"), t.radius = c, t.color = h, t.strategy = u, t.maxSpeed = r, t.velocity = {
1642
+ x: Math.cos(n) * o,
1643
+ y: Math.sin(n) * o
877
1644
  };
878
1645
  }
879
1646
  }
880
- class q {
881
- spatialHash;
882
- eventBus;
883
- i18n;
884
- currentThrowKills = 0;
885
- currentThrowPos = null;
886
- constructor(t, e) {
887
- this.spatialHash = new Y(100), this.eventBus = t, this.i18n = e;
888
- }
889
- update(t, e, i, s, a, l, r, n, o, h, c, u, p, f) {
890
- this.spatialHash.clear();
891
- for (const d of i)
892
- d.active && !d.isDying ? (d.update(t), this.spatialHash.insert(d)) : d.active && d.isDying && d.update(t);
893
- for (let d = l.length - 1; d >= 0; d--) {
894
- const m = l[d];
895
- if (!m) continue;
896
- m.lifetime += t;
897
- const x = m.lifetime / m.maxLifetime;
898
- m.radius = m.maxRadius * x, m.alpha = Math.max(0, 1 - x), m.lifetime >= m.maxLifetime && l.splice(d, 1);
899
- }
900
- for (let d = a.length - 1; d >= 0; d--) {
901
- const m = a[d];
902
- if (m) {
903
- m.duration += t;
904
- for (const x of i) {
905
- if (!x.active || x.isGrabbed || x.isDying || x.isThrown && x.type === "piercer") continue;
906
- const L = m.position.x - x.position.x, A = m.position.y - x.position.y, b = Math.hypot(L, A);
907
- if (b > 2 && b <= m.radius) {
908
- const M = Math.pow(1 - b / m.radius, 0.7), T = m.pullForce * M, g = Math.atan2(A, L);
909
- x.velocity.x += Math.cos(g) * T * t, x.velocity.y += Math.sin(g) * T * t, x.position.x += Math.cos(g) * T * t * 0.8, x.position.y += Math.sin(g) * T * t * 0.8;
1647
+ class R {
1648
+ static killEnemy(t, e, i, s, a, l) {
1649
+ if (!t.active || t.isDying) return;
1650
+ const n = A.getInstance().getConfig();
1651
+ if (a.push({
1652
+ id: Math.random().toString(),
1653
+ position: { ...t.position },
1654
+ radius: 10,
1655
+ maxRadius: 180,
1656
+ color: t.color,
1657
+ alpha: 1,
1658
+ lifetime: 0,
1659
+ maxLifetime: 0.5
1660
+ }), t.type === "spore")
1661
+ t.triggerDissolveDeath(), i.push({
1662
+ id: Math.random().toString(),
1663
+ position: { ...t.position },
1664
+ radius: n.toxicPool.baseRadius,
1665
+ duration: 0,
1666
+ maxDuration: n.toxicPool.baseDuration,
1667
+ damage: n.toxicPool.damage
1668
+ });
1669
+ else if (t.type === "cluster") {
1670
+ t.triggerDissolveDeath();
1671
+ const o = n.cluster.fragmentCount, r = n.cluster.hasHoming;
1672
+ for (let c = 0; c < o; c++) {
1673
+ const h = c * Math.PI * 2 / o, u = 750 + Math.random() * 250, p = {
1674
+ x: t.position.x + Math.cos(h) * 40,
1675
+ y: t.position.y + Math.sin(h) * 40
1676
+ };
1677
+ let _ = h;
1678
+ if (r) {
1679
+ let g = null, f = 1 / 0;
1680
+ for (const x of l) {
1681
+ if (x === t || !x.active || x.isGrabbed || x.isDying) continue;
1682
+ const b = Math.hypot(x.position.x - p.x, x.position.y - p.y);
1683
+ b < f && (f = b, g = x);
910
1684
  }
1685
+ g && (_ = Math.atan2(g.position.y - p.y, g.position.x - p.x));
911
1686
  }
912
- m.duration >= m.maxDuration && a.splice(d, 1);
1687
+ const d = T.createEnemy("micro", p, {
1688
+ x: p.x + Math.cos(_) * 500,
1689
+ y: p.y + Math.sin(_) * 500
1690
+ });
1691
+ d.isThrown = !0, d.wasManipulated = !0, d.velocity = {
1692
+ x: Math.cos(_) * u,
1693
+ y: Math.sin(_) * u
1694
+ }, l.push(d);
913
1695
  }
914
- }
915
- for (const d of i) {
916
- if (!d.active || d.isGrabbed || d.isDying) continue;
917
- const m = e.position.x - d.position.x, x = e.position.y - d.position.y;
918
- if (Math.hypot(m, x) <= e.radius + d.radius) {
919
- d.active = !1;
920
- const A = e.takeDamage();
921
- this.eventBus.emit("onCoreDamaged", { currentIntegrity: e.integrity }), l.push({
922
- id: Math.random().toString(),
923
- position: { ...e.position },
924
- radius: 20,
925
- maxRadius: Math.max(u, p) * 1.3,
926
- color: "#00f0ff",
927
- alpha: 1,
928
- lifetime: 0,
929
- maxLifetime: 0.8
930
- }), o.triggerScreenShake({ x: m, y: x }, 25), o.triggerHitstop(0.15), o.triggerFlash(0.6);
931
- for (const b of i)
932
- if (b.active && !b.isGrabbed) {
933
- b.triggerDissolveDeath();
934
- for (let M = 0; M < 8; M++) {
935
- const T = Math.random() * Math.PI * 2, g = 100 + Math.random() * 200;
936
- r.push({
1696
+ } else t.type === "parasite" ? (t.triggerDissolveDeath(), s.push({
1697
+ id: Math.random().toString(),
1698
+ position: { ...t.position },
1699
+ radius: n.gravityVortex.baseRadius,
1700
+ duration: 0,
1701
+ maxDuration: n.gravityVortex.baseDuration,
1702
+ pullForce: n.gravityVortex.basePullForce
1703
+ })) : t.type === "piercer" ? t.triggerSliceDeath(e) : t.triggerDissolveDeath();
1704
+ }
1705
+ }
1706
+ class rt {
1707
+ static update(t, e, i, s, a, l, n, o, r, c, h, u, p) {
1708
+ let _ = !1;
1709
+ for (const d of t)
1710
+ if (!(!d.active || !d.isThrown || d.isDying)) {
1711
+ if (_ = !0, d.position.x < -120 || d.position.x > c + 120 || d.position.y < -120 || d.position.y > h + 120) {
1712
+ if (d.type === "heavy") {
1713
+ s.push({
1714
+ id: Math.random().toString(),
1715
+ position: { ...d.position },
1716
+ radius: 20,
1717
+ maxRadius: 350,
1718
+ color: "#00f5ff",
1719
+ alpha: 1,
1720
+ lifetime: 0,
1721
+ maxLifetime: 0.6
1722
+ });
1723
+ for (let g = 0; g < 40; g++) {
1724
+ const f = Math.random() * Math.PI * 2, x = 250 + Math.random() * 450;
1725
+ a.push({
1726
+ id: Math.random().toString(),
1727
+ position: { ...d.position },
1728
+ velocity: { x: Math.cos(f) * x, y: Math.sin(f) * x },
1729
+ color: "#00f5ff",
1730
+ radius: 4 + Math.random() * 5,
1731
+ alpha: 1,
1732
+ lifetime: 0,
1733
+ maxLifetime: 0.6
1734
+ });
1735
+ }
1736
+ } else if (d.type === "piercer") {
1737
+ const g = A.getInstance().getConfig().piercer;
1738
+ if (g.terminalAoERadius > 0) {
1739
+ const f = g.terminalAoERadius;
1740
+ s.push({
937
1741
  id: Math.random().toString(),
938
- position: { ...b.position },
939
- velocity: { x: Math.cos(T) * g, y: Math.sin(T) * g },
940
- color: "#00f0ff",
941
- radius: 3 + Math.random() * 3,
1742
+ position: { ...d.position },
1743
+ radius: 20,
1744
+ maxRadius: f,
1745
+ color: "#ff2a5f",
942
1746
  alpha: 1,
943
1747
  lifetime: 0,
944
- maxLifetime: 0.5
1748
+ maxLifetime: 0.6
945
1749
  });
1750
+ for (const x of t) {
1751
+ if (!x.active || x.isGrabbed || x.isDying) continue;
1752
+ const b = x.position.x - d.position.x, v = x.position.y - d.position.y;
1753
+ Math.hypot(b, v) <= f && R.killEnemy(x, Math.atan2(v, b), e, i, s, t);
1754
+ }
946
1755
  }
947
1756
  }
948
- n.push({
949
- id: Math.random().toString(),
950
- text: "CORE OVERLOAD PULSE!",
951
- position: { ...e.position },
952
- velocity: { x: 0, y: -90 },
953
- color: "#00f0ff",
954
- alpha: 1,
955
- lifetime: 0,
956
- maxLifetime: 1.5,
957
- size: 32
958
- }), (!A || e.integrity <= 0) && this.eventBus.emit("onGameOver", { score: c.value, wave: 1 });
959
- break;
960
- }
961
- }
962
- let y = !1;
963
- for (const d of i)
964
- if (!(!d.active || !d.isThrown || d.isDying)) {
965
- if (y = !0, d.position.x < -120 || d.position.x > u + 120 || d.position.y < -120 || d.position.y > p + 120) {
966
1757
  d.active = !1, d.isThrown = !1;
967
1758
  continue;
968
1759
  }
969
- for (const m of i) {
970
- if (m === d || !m.active || m.isGrabbed || m.isDying) continue;
971
- const x = m.position.x - d.position.x, L = m.position.y - d.position.y;
972
- if (Math.hypot(x, L) <= d.getHitRadius() + m.getHitRadius()) {
973
- this.currentThrowPos = { x: d.position.x, y: d.position.y };
974
- const b = Math.atan2(d.velocity.y, d.velocity.x);
975
- if (d.type === "piercer") {
976
- this.currentThrowKills++, this.killEnemyWithChainReaction(m, b, s, a, l, r, i), o.triggerHitstop(0.05), o.triggerScreenShake({ x, y: L }, 7), l.push({
1760
+ for (const g of t) {
1761
+ if (g === d || !g.active || g.isGrabbed || g.isDying) continue;
1762
+ const f = g.position.x - d.position.x, x = g.position.y - d.position.y;
1763
+ if (Math.hypot(f, x) <= d.getHitRadius() + g.getHitRadius()) {
1764
+ u.pos = { x: d.position.x, y: d.position.y };
1765
+ const v = Math.atan2(d.velocity.y, d.velocity.x);
1766
+ if (d.type === "heavy") {
1767
+ u.kills++, R.killEnemy(g, d.rotation, e, i, s, t), n.triggerHitstop(0.04), n.triggerScreenShake({ x: f, y: x }, 8);
1768
+ for (let I = 0; I < 8; I++) {
1769
+ const S = d.rotation + (Math.random() - 0.5), m = 200 + Math.random() * 350;
1770
+ a.push({
1771
+ id: Math.random().toString(),
1772
+ position: { ...g.position },
1773
+ velocity: { x: Math.cos(S) * m, y: Math.sin(S) * m },
1774
+ color: "#00f5ff",
1775
+ radius: 3 + Math.random() * 4,
1776
+ alpha: 1,
1777
+ lifetime: 0,
1778
+ maxLifetime: 0.4
1779
+ });
1780
+ }
1781
+ p && p();
1782
+ } else if (d.type === "piercer") {
1783
+ u.kills++, R.killEnemy(g, v, e, i, s, t), n.triggerHitstop(0.05), n.triggerScreenShake({ x: f, y: x }, 7), s.push({
977
1784
  id: Math.random().toString(),
978
- position: { ...m.position },
1785
+ position: { ...g.position },
979
1786
  radius: 10,
980
1787
  maxRadius: 180,
981
1788
  color: "#ff2a5f",
@@ -983,12 +1790,12 @@ class q {
983
1790
  lifetime: 0,
984
1791
  maxLifetime: 0.45
985
1792
  });
986
- for (let M = 0; M < 16; M++) {
987
- const T = Math.random() * Math.PI * 2, g = 150 + Math.random() * 300;
988
- r.push({
1793
+ for (let I = 0; I < 16; I++) {
1794
+ const S = Math.random() * Math.PI * 2, m = 150 + Math.random() * 300;
1795
+ a.push({
989
1796
  id: Math.random().toString(),
990
- position: { ...m.position },
991
- velocity: { x: Math.cos(T) * g, y: Math.sin(T) * g },
1797
+ position: { ...g.position },
1798
+ velocity: { x: Math.cos(S) * m, y: Math.sin(S) * m },
992
1799
  color: "#ff2a5f",
993
1800
  radius: 3 + Math.random() * 3,
994
1801
  alpha: 1,
@@ -996,25 +1803,41 @@ class q {
996
1803
  maxLifetime: 0.4
997
1804
  });
998
1805
  }
999
- f && f();
1806
+ if (d.remainingHomingKills > 0) {
1807
+ d.remainingHomingKills--;
1808
+ let I = null, S = 1 / 0;
1809
+ for (const m of t) {
1810
+ if (m === d || m === g || !m.active || m.isGrabbed || m.isDying) continue;
1811
+ const y = m.position.x - d.position.x, M = m.position.y - d.position.y, L = Math.hypot(y, M);
1812
+ L < S && (S = L, I = m);
1813
+ }
1814
+ if (I) {
1815
+ const m = Math.atan2(I.position.y - d.position.y, I.position.x - d.position.x), y = Math.hypot(d.velocity.x, d.velocity.y) || 1200;
1816
+ d.rotation = m, d.velocity = {
1817
+ x: Math.cos(m) * y,
1818
+ y: Math.sin(m) * y
1819
+ };
1820
+ }
1821
+ }
1822
+ p && p();
1000
1823
  } else {
1001
- const M = d.type === m.type, T = M ? 360 : 250;
1002
- l.push({
1824
+ const I = d.type === g.type, S = I ? 360 : 250;
1825
+ s.push({
1003
1826
  id: Math.random().toString(),
1004
- position: { ...this.currentThrowPos },
1827
+ position: { ...u.pos },
1005
1828
  radius: 15,
1006
- maxRadius: T,
1829
+ maxRadius: S,
1007
1830
  color: d.color,
1008
1831
  alpha: 1,
1009
1832
  lifetime: 0,
1010
1833
  maxLifetime: 0.55
1011
1834
  });
1012
- for (let g = 0; g < 45; g++) {
1013
- const I = Math.random() * Math.PI * 2, v = 200 + Math.random() * 450;
1014
- r.push({
1835
+ for (let m = 0; m < 45; m++) {
1836
+ const y = Math.random() * Math.PI * 2, M = 200 + Math.random() * 450;
1837
+ a.push({
1015
1838
  id: Math.random().toString(),
1016
- position: { ...this.currentThrowPos },
1017
- velocity: { x: Math.cos(I) * v, y: Math.sin(I) * v },
1839
+ position: { ...u.pos },
1840
+ velocity: { x: Math.cos(y) * M, y: Math.sin(y) * M },
1018
1841
  color: d.color,
1019
1842
  radius: 4 + Math.random() * 6,
1020
1843
  alpha: 1,
@@ -1022,131 +1845,213 @@ class q {
1022
1845
  maxLifetime: 0.7
1023
1846
  });
1024
1847
  }
1025
- if (M) {
1026
- if (this.currentThrowKills += 2, o.triggerHitstop(0.14), o.triggerFlash(0.5), o.triggerScreenShake({ x, y: L }, 16), n.push({
1848
+ if (I) {
1849
+ u.kills += 2, n.triggerHitstop(0.14), n.triggerFlash(0.5), n.triggerScreenShake({ x: f, y: x }, 16), l.push({
1027
1850
  id: Math.random().toString(),
1028
1851
  text: "COLOR SYNERGY!",
1029
- position: { ...this.currentThrowPos },
1852
+ position: { ...u.pos },
1030
1853
  velocity: { x: 0, y: -80 },
1031
1854
  color: d.color,
1032
1855
  alpha: 1,
1033
1856
  lifetime: 0,
1034
1857
  maxLifetime: 1.2,
1035
1858
  size: 26
1036
- }), d.type === "spore")
1037
- s.push({
1859
+ });
1860
+ const m = A.getInstance().getConfig();
1861
+ if (d.type === "spore")
1862
+ e.push({
1038
1863
  id: Math.random().toString(),
1039
- position: { ...this.currentThrowPos },
1040
- radius: 340,
1864
+ position: { ...u.pos },
1865
+ radius: m.toxicPool.synergyRadius,
1041
1866
  duration: 0,
1042
- maxDuration: 10,
1043
- damage: 100
1867
+ maxDuration: m.toxicPool.synergyDuration,
1868
+ damage: m.toxicPool.damage * 2
1044
1869
  });
1045
1870
  else if (d.type === "parasite")
1046
- a.push({
1871
+ i.push({
1047
1872
  id: Math.random().toString(),
1048
- position: { ...this.currentThrowPos },
1049
- radius: 600,
1873
+ position: { ...u.pos },
1874
+ radius: m.gravityVortex.synergyRadius,
1050
1875
  duration: 0,
1051
- maxDuration: 7,
1052
- pullForce: 5e3
1876
+ maxDuration: m.gravityVortex.synergyDuration,
1877
+ pullForce: m.gravityVortex.synergyPullForce
1053
1878
  });
1054
1879
  else if (d.type === "cluster")
1055
- for (let g = 0; g < 8; g++) {
1056
- const I = g * Math.PI * 2 / 8, v = {
1057
- x: this.currentThrowPos.x + Math.cos(I) * 15,
1058
- y: this.currentThrowPos.y + Math.sin(I) * 15
1059
- }, G = S.createEnemy("micro", v, {
1060
- x: v.x + Math.cos(I) * 220,
1061
- y: v.y + Math.sin(I) * 220
1880
+ for (let y = 0; y < 8; y++) {
1881
+ const M = y * Math.PI * 2 / 8, L = {
1882
+ x: u.pos.x + Math.cos(M) * 15,
1883
+ y: u.pos.y + Math.sin(M) * 15
1884
+ }, C = T.createEnemy("micro", L, {
1885
+ x: L.x + Math.cos(M) * 220,
1886
+ y: L.y + Math.sin(M) * 220
1062
1887
  });
1063
- G.isThrown = !0, i.push(G);
1888
+ C.isThrown = !0, t.push(C);
1064
1889
  }
1065
- this.killEnemyWithChainReaction(d, b, s, a, l, r, i), this.killEnemyWithChainReaction(m, b, s, a, l, r, i);
1890
+ R.killEnemy(d, v, e, i, s, t), R.killEnemy(g, v, e, i, s, t);
1066
1891
  } else
1067
- this.currentThrowKills += 2, o.triggerHitstop(0.08), o.triggerFlash(0.35), o.triggerScreenShake({ x, y: L }, 10), this.killEnemyWithChainReaction(d, b, s, a, l, r, i), this.killEnemyWithChainReaction(m, b, s, a, l, r, i);
1068
- for (const g of i) {
1069
- if (g === d || g === m || !g.active || g.isGrabbed || g.isDying) continue;
1070
- const I = g.position.x - this.currentThrowPos.x, v = g.position.y - this.currentThrowPos.y;
1071
- Math.hypot(I, v) <= T && (this.killEnemyWithChainReaction(g, b, s, a, l, r, i), this.currentThrowKills++);
1892
+ u.kills += 2, n.triggerHitstop(0.08), n.triggerFlash(0.35), n.triggerScreenShake({ x: f, y: x }, 10), R.killEnemy(d, v, e, i, s, t), R.killEnemy(g, v, e, i, s, t);
1893
+ for (const m of t) {
1894
+ if (m === d || m === g || !m.active || m.isGrabbed || m.isDying) continue;
1895
+ const y = m.position.x - u.pos.x, M = m.position.y - u.pos.y;
1896
+ Math.hypot(y, M) <= S && (R.killEnemy(m, v, e, i, s, t), u.kills++);
1072
1897
  }
1073
- f && f();
1898
+ p && p();
1074
1899
  break;
1075
1900
  }
1076
1901
  }
1077
1902
  }
1078
1903
  }
1079
- h.value = this.currentThrowKills, !y && this.currentThrowKills > 0 && (this.currentThrowKills >= 2 && this.currentThrowPos && n.push({
1904
+ r.value = u.kills, !_ && u.kills > 0 && (u.kills >= 2 && u.pos && l.push({
1080
1905
  id: Math.random().toString(),
1081
- text: `MULTIKILL x${this.currentThrowKills}!`,
1082
- position: { ...this.currentThrowPos },
1906
+ text: `MULTIKILL x${u.kills}!`,
1907
+ position: { ...u.pos },
1083
1908
  velocity: { x: 0, y: -90 },
1084
1909
  color: "#ff00dd",
1085
1910
  alpha: 1,
1086
1911
  lifetime: 0,
1087
1912
  maxLifetime: 1.4,
1088
1913
  size: 32
1089
- }), this.eventBus.emit("onComboUpdated", { combo: h.value }), this.currentThrowKills = 0, this.currentThrowPos = null);
1090
- for (let d = s.length - 1; d >= 0; d--) {
1091
- const m = s[d];
1092
- if (m) {
1093
- m.duration += t;
1094
- for (const x of i) {
1095
- if (!x.active || x.isGrabbed || x.isDying || x.isThrown && x.type === "piercer") continue;
1096
- const L = x.position.x - m.position.x, A = x.position.y - m.position.y;
1097
- Math.hypot(L, A) <= m.radius && (this.killEnemyWithChainReaction(x, 0, s, a, l, r, i), this.currentThrowKills++, f && f());
1914
+ }), o.emit("onComboUpdated", { combo: r.value }), u.kills = 0, u.pos = null);
1915
+ }
1916
+ }
1917
+ class lt {
1918
+ static update(t, e, i, s, a, l, n, o) {
1919
+ for (let r = t.length - 1; r >= 0; r--) {
1920
+ const c = t[r];
1921
+ if (c) {
1922
+ c.duration += l;
1923
+ for (const h of e) {
1924
+ if (!h.active || h.isGrabbed || h.isDying || h.isThrown && h.type === "piercer") continue;
1925
+ const u = h.position.x - c.position.x, p = h.position.y - c.position.y;
1926
+ Math.hypot(u, p) <= c.radius && (R.killEnemy(h, 0, t, i, s, e), n.kills++, o && o());
1098
1927
  }
1099
- m.duration >= m.maxDuration && s.splice(d, 1);
1928
+ c.duration >= c.maxDuration && t.splice(r, 1);
1100
1929
  }
1101
1930
  }
1102
1931
  }
1103
- killEnemyWithChainReaction(t, e, i, s, a, l, r) {
1104
- if (!(!t.active || t.isDying))
1105
- if (a.push({
1106
- id: Math.random().toString(),
1107
- position: { ...t.position },
1108
- radius: 10,
1109
- maxRadius: 180,
1110
- color: t.color,
1111
- alpha: 1,
1112
- lifetime: 0,
1113
- maxLifetime: 0.5
1114
- }), t.type === "spore")
1115
- t.triggerDissolveDeath(), i.push({
1116
- id: Math.random().toString(),
1117
- position: { ...t.position },
1118
- radius: 200,
1119
- duration: 0,
1120
- maxDuration: 6,
1121
- damage: 50
1122
- });
1123
- else if (t.type === "cluster") {
1124
- t.triggerDissolveDeath();
1125
- for (let n = 0; n < 6; n++) {
1126
- const o = n * Math.PI * 2 / 6, h = {
1127
- x: t.position.x + Math.cos(o) * 15,
1128
- y: t.position.y + Math.sin(o) * 15
1129
- }, c = S.createEnemy("micro", h, {
1130
- x: h.x + Math.cos(o) * 200,
1131
- y: h.y + Math.sin(o) * 200
1132
- });
1133
- c.isThrown = !0, r.push(c);
1932
+ }
1933
+ class ct {
1934
+ static update(t, e, i, s, a, l, n, o, r, c, h, u) {
1935
+ for (const p of t)
1936
+ if (!(!p.active || !p.isStationaryShield || p.isDying))
1937
+ for (const _ of t) {
1938
+ if (_ === p || !_.active || _.isGrabbed || _.isDying) continue;
1939
+ const d = _.position.x - p.position.x, g = _.position.y - p.position.y;
1940
+ if (Math.hypot(d, g) <= p.getHitRadius() + _.getHitRadius()) {
1941
+ p.isStationaryShield = !1, p.strategy && p.strategy.execute({
1942
+ thrownEnemy: p,
1943
+ targetEnemy: _,
1944
+ allEnemies: t,
1945
+ pools: e,
1946
+ vortices: i,
1947
+ shockwaves: s,
1948
+ particles: a,
1949
+ floatingTexts: l,
1950
+ eventBus: o,
1951
+ width: c,
1952
+ height: h
1953
+ }), r.kills += 2, n.triggerHitstop(0.12), n.triggerScreenShake({ x: d, y: g }, 18), u && u();
1954
+ break;
1955
+ }
1134
1956
  }
1135
- } else t.type === "parasite" ? (t.triggerDissolveDeath(), s.push({
1136
- id: Math.random().toString(),
1137
- position: { ...t.position },
1138
- radius: 450,
1139
- duration: 0,
1140
- maxDuration: 5,
1141
- pullForce: 3e3
1142
- })) : t.type === "piercer" ? t.triggerSliceDeath(e) : t.triggerDissolveDeath();
1143
1957
  }
1144
1958
  }
1145
- class j {
1959
+ class ht {
1960
+ spatialHash;
1961
+ eventBus;
1962
+ i18n;
1963
+ throwState = { kills: 0, pos: null };
1964
+ constructor(t, e) {
1965
+ this.spatialHash = new j(100), this.eventBus = t, this.i18n = e;
1966
+ }
1967
+ update(t, e, i, s, a, l, n, o, r, c, h, u, p, _) {
1968
+ this.spatialHash.clear();
1969
+ const d = A.getInstance().getConfig().piercer;
1970
+ for (const g of i)
1971
+ if (g.active && !g.isDying) {
1972
+ if (g.isThrown && g.type === "piercer" && d.hasHoming && g.remainingHomingKills > 0) {
1973
+ let f = null, x = 1 / 0;
1974
+ for (const b of i) {
1975
+ if (b === g || !b.active || b.isGrabbed || b.isDying) continue;
1976
+ const v = b.position.x - g.position.x, I = b.position.y - g.position.y, S = Math.hypot(v, I);
1977
+ S < x && (x = S, f = b);
1978
+ }
1979
+ if (f) {
1980
+ const b = Math.atan2(f.position.y - g.position.y, f.position.x - g.position.x), v = Math.max(Math.hypot(g.velocity.x, g.velocity.y), 1e3), I = 25 * t, S = Math.atan2(g.velocity.y, g.velocity.x);
1981
+ let m = b - S;
1982
+ for (; m < -Math.PI; ) m += Math.PI * 2;
1983
+ for (; m > Math.PI; ) m -= Math.PI * 2;
1984
+ const y = S + Math.sign(m) * Math.min(Math.abs(m), I);
1985
+ g.rotation = y, g.velocity = {
1986
+ x: Math.cos(y) * v,
1987
+ y: Math.sin(y) * v
1988
+ };
1989
+ }
1990
+ }
1991
+ g.update(t), this.spatialHash.insert(g);
1992
+ } else g.active && g.isDying && g.update(t);
1993
+ for (let g = l.length - 1; g >= 0; g--) {
1994
+ const f = l[g];
1995
+ if (!f) continue;
1996
+ f.lifetime += t;
1997
+ const x = f.lifetime / f.maxLifetime;
1998
+ f.radius = f.maxRadius * x, f.alpha = Math.max(0, 1 - x), f.lifetime >= f.maxLifetime && l.splice(g, 1);
1999
+ }
2000
+ tt.update(a, i, t), et.update(
2001
+ e,
2002
+ i,
2003
+ l,
2004
+ n,
2005
+ o,
2006
+ r,
2007
+ this.eventBus,
2008
+ h,
2009
+ u,
2010
+ p
2011
+ ), rt.update(
2012
+ i,
2013
+ s,
2014
+ a,
2015
+ l,
2016
+ n,
2017
+ o,
2018
+ r,
2019
+ this.eventBus,
2020
+ c,
2021
+ u,
2022
+ p,
2023
+ this.throwState,
2024
+ _
2025
+ ), lt.update(
2026
+ s,
2027
+ i,
2028
+ a,
2029
+ l,
2030
+ n,
2031
+ t,
2032
+ this.throwState,
2033
+ _
2034
+ ), ct.update(
2035
+ i,
2036
+ s,
2037
+ a,
2038
+ l,
2039
+ n,
2040
+ o,
2041
+ r,
2042
+ this.eventBus,
2043
+ this.throwState,
2044
+ u,
2045
+ p,
2046
+ _
2047
+ );
2048
+ }
2049
+ }
2050
+ class ut {
1146
2051
  pool = [];
1147
2052
  constructor(t = 500) {
1148
2053
  for (let e = 0; e < t; e++) {
1149
- const i = new D(`pool_enemy_${e}`);
2054
+ const i = new H(`pool_enemy_${e}`);
1150
2055
  this.pool.push(i);
1151
2056
  }
1152
2057
  }
@@ -1154,7 +2059,7 @@ class j {
1154
2059
  for (const e of this.pool)
1155
2060
  if (!e.active)
1156
2061
  return e.reset(), e;
1157
- const t = new D(`fallback_enemy_${Date.now()}_${Math.random()}`);
2062
+ const t = new H(`fallback_enemy_${Date.now()}_${Math.random()}`);
1158
2063
  return this.pool.push(t), t;
1159
2064
  }
1160
2065
  resetAll() {
@@ -1162,91 +2067,91 @@ class j {
1162
2067
  t.reset();
1163
2068
  }
1164
2069
  }
1165
- class C {
2070
+ class O {
1166
2071
  static getOffscreenPosition(t, e) {
1167
2072
  const i = Math.floor(Math.random() * 4), s = 70;
1168
2073
  return i === 0 ? { x: Math.random() * t, y: -s } : i === 1 ? { x: t + s, y: Math.random() * e } : i === 2 ? { x: Math.random() * t, y: e + s } : { x: -s, y: Math.random() * e };
1169
2074
  }
1170
2075
  static spawnCircleOfDeath(t, e, i, s) {
1171
- const a = [], r = Math.max(i, s) * 0.55 + 80;
1172
- for (let n = 0; n < 18; n++) {
1173
- const o = n * Math.PI * 2 / 18, h = {
1174
- x: e.x + Math.cos(o) * r,
1175
- y: e.y + Math.sin(o) * r
1176
- }, c = t.get(), u = ["piercer", "spore", "cluster", "parasite"], p = u[n % u.length];
1177
- S.configureEnemy(c, p, h, e), c.velocity = {
1178
- x: Math.cos(o + Math.PI) * 55,
1179
- y: Math.sin(o + Math.PI) * 55
1180
- }, a.push(c);
2076
+ const a = [], n = Math.max(i, s) * 0.55 + 80;
2077
+ for (let o = 0; o < 18; o++) {
2078
+ const r = o * Math.PI * 2 / 18, c = {
2079
+ x: e.x + Math.cos(r) * n,
2080
+ y: e.y + Math.sin(r) * n
2081
+ }, h = t.get(), u = ["piercer", "spore", "cluster", "parasite"], p = u[o % u.length];
2082
+ T.configureEnemy(h, p, c, e), h.velocity = {
2083
+ x: Math.cos(r + Math.PI) * 55,
2084
+ y: Math.sin(r + Math.PI) * 55
2085
+ }, a.push(h);
1181
2086
  }
1182
2087
  return a;
1183
2088
  }
1184
2089
  static spawnDenseCluster(t, e, i, s) {
1185
- const a = [], r = Math.floor(Math.random() * 4);
1186
- let n = { x: -60, y: -60 };
1187
- r === 0 ? n = { x: Math.random() * e, y: -80 } : r === 1 ? n = { x: e + 80, y: Math.random() * i } : r === 2 ? n = { x: Math.random() * e, y: i + 80 } : n = { x: -80, y: Math.random() * i };
1188
- for (let o = 0; o < 14; o++) {
1189
- const h = {
2090
+ const a = [], n = Math.floor(Math.random() * 4);
2091
+ let o = { x: -60, y: -60 };
2092
+ n === 0 ? o = { x: Math.random() * e, y: -80 } : n === 1 ? o = { x: e + 80, y: Math.random() * i } : n === 2 ? o = { x: Math.random() * e, y: i + 80 } : o = { x: -80, y: Math.random() * i };
2093
+ for (let r = 0; r < 14; r++) {
2094
+ const c = {
1190
2095
  x: (Math.random() - 0.5) * 60,
1191
2096
  y: (Math.random() - 0.5) * 60
1192
- }, c = { x: n.x + h.x, y: n.y + h.y }, u = t.get();
1193
- S.configureEnemy(u, "spore", c, s);
1194
- const p = s.x - c.x, f = s.y - c.y, y = Math.atan2(f, p);
2097
+ }, h = { x: o.x + c.x, y: o.y + c.y }, u = t.get();
2098
+ T.configureEnemy(u, "spore", h, s);
2099
+ const p = s.x - h.x, _ = s.y - h.y, d = Math.atan2(_, p);
1195
2100
  u.velocity = {
1196
- x: Math.cos(y) * (50 + Math.random() * 20),
1197
- y: Math.sin(y) * (50 + Math.random() * 20)
2101
+ x: Math.cos(d) * (50 + Math.random() * 20),
2102
+ y: Math.sin(d) * (50 + Math.random() * 20)
1198
2103
  }, a.push(u);
1199
2104
  }
1200
2105
  return a;
1201
2106
  }
1202
2107
  static spawnSineSnake(t, e, i, s) {
1203
- const a = [], r = i * 0.2 + Math.random() * i * 0.6;
1204
- for (let n = 0; n < 12; n++) {
1205
- const o = {
1206
- x: -60 - n * 40,
1207
- y: r + Math.sin(n * 0.45) * 70
1208
- }, h = t.get();
1209
- S.configureEnemy(h, "cluster", o, s), h.velocity = { x: 75, y: Math.cos(n * 0.45) * 30 }, a.push(h);
2108
+ const a = [], n = i * 0.2 + Math.random() * i * 0.6;
2109
+ for (let o = 0; o < 12; o++) {
2110
+ const r = {
2111
+ x: -60 - o * 40,
2112
+ y: n + Math.sin(o * 0.45) * 70
2113
+ }, c = t.get();
2114
+ T.configureEnemy(c, "cluster", r, s), c.velocity = { x: 75, y: Math.cos(o * 0.45) * 30 }, a.push(c);
1210
2115
  }
1211
2116
  return a;
1212
2117
  }
1213
2118
  static spawnDoubleSpiral(t, e, i, s) {
1214
2119
  const a = [];
1215
- for (let r = 0; r < 14; r++) {
1216
- const n = r / 14, o = n * Math.PI * 4, h = 120 + n * 450, c = {
1217
- x: e + Math.cos(o) * h,
1218
- y: -60 + Math.sin(o) * h
2120
+ for (let n = 0; n < 14; n++) {
2121
+ const o = n / 14, r = o * Math.PI * 4, c = 120 + o * 450, h = {
2122
+ x: e + Math.cos(r) * c,
2123
+ y: -60 + Math.sin(r) * c
1219
2124
  }, u = t.get();
1220
- S.configureEnemy(u, "parasite", c, s), a.push(u);
2125
+ T.configureEnemy(u, "parasite", h, s), a.push(u);
1221
2126
  }
1222
2127
  return a;
1223
2128
  }
1224
2129
  static spawnMarchingWall(t, e, i, s) {
1225
- const a = [], r = Math.random() > 0.5;
1226
- for (let n = 0; n < 12; n++) {
1227
- const o = n / 11 * i, h = {
1228
- x: r ? -60 : e + 60,
1229
- y: o
1230
- }, c = t.get();
1231
- S.configureEnemy(c, "piercer", h, s), c.velocity = {
1232
- x: r ? 70 : -70,
2130
+ const a = [], n = Math.random() > 0.5;
2131
+ for (let o = 0; o < 12; o++) {
2132
+ const r = o / 11 * i, c = {
2133
+ x: n ? -60 : e + 60,
2134
+ y: r
2135
+ }, h = t.get();
2136
+ T.configureEnemy(h, "piercer", c, s), h.velocity = {
2137
+ x: n ? 70 : -70,
1233
2138
  y: 0
1234
- }, a.push(c);
2139
+ }, a.push(h);
1235
2140
  }
1236
2141
  return a;
1237
2142
  }
1238
2143
  static spawnCrossfireStreams(t, e, i, s) {
1239
2144
  const a = [];
1240
- for (let r = 0; r < 10; r++) {
1241
- const n = { x: -50 - r * 35, y: -50 - r * 35 }, o = t.get();
1242
- S.configureEnemy(o, "spore", n, s), a.push(o);
1243
- const h = { x: e + 50 + r * 35, y: i + 50 + r * 35 }, c = t.get();
1244
- S.configureEnemy(c, "cluster", h, s), a.push(c);
2145
+ for (let n = 0; n < 10; n++) {
2146
+ const o = { x: -50 - n * 35, y: -50 - n * 35 }, r = t.get();
2147
+ T.configureEnemy(r, "spore", o, s), a.push(r);
2148
+ const c = { x: e + 50 + n * 35, y: i + 50 + n * 35 }, h = t.get();
2149
+ T.configureEnemy(h, "cluster", c, s), a.push(h);
1245
2150
  }
1246
2151
  return a;
1247
2152
  }
1248
2153
  }
1249
- class Q {
2154
+ class pt {
1250
2155
  wave = 1;
1251
2156
  pool;
1252
2157
  spawnTimer = 0;
@@ -1254,63 +2159,63 @@ class Q {
1254
2159
  patternCooldown = 0;
1255
2160
  initialGracePeriod = 6;
1256
2161
  constructor() {
1257
- this.pool = new j(500);
2162
+ this.pool = new ut(500);
1258
2163
  }
1259
2164
  reset() {
1260
2165
  this.wave = 1, this.spawnTimer = 0, this.waveTimer = 0, this.patternCooldown = 0;
1261
2166
  }
1262
2167
  update(t, e, i, s, a) {
1263
2168
  this.waveTimer += t, this.spawnTimer += t, this.patternCooldown += t, this.applyFlockingBehaviors(e, t, a);
1264
- const l = e.filter((o) => o.active).length, r = Math.max(0.9, 2.2 - (this.wave - 1) * 0.18);
2169
+ const l = e.filter((r) => r.active).length, n = Math.max(0.9, 2.2 - (this.wave - 1) * 0.18);
1265
2170
  if (this.waveTimer > this.initialGracePeriod && this.patternCooldown > Math.max(12 - this.wave, 6) && l < 35) {
1266
2171
  this.patternCooldown = 0;
1267
- const o = this.spawnPatternFormation(i, s, a);
1268
- for (const h of o)
1269
- e.push(h);
2172
+ const r = this.spawnPatternFormation(i, s, a);
2173
+ for (const c of r)
2174
+ e.push(c);
1270
2175
  }
1271
- const n = Math.min(18 + this.wave * 4, 80);
1272
- return this.spawnTimer >= r && l < n ? (this.spawnTimer = 0, this.spawnSingleEnemy(i, s, a)) : null;
2176
+ const o = Math.min(18 + this.wave * 4, 80);
2177
+ return this.spawnTimer >= n && l < o ? (this.spawnTimer = 0, this.spawnSingleEnemy(i, s, a)) : null;
1273
2178
  }
1274
2179
  spawnSingleEnemy(t, e, i) {
1275
- const s = C.getOffscreenPosition(t, e), a = Math.random();
2180
+ const s = O.getOffscreenPosition(t, e), a = Math.random();
1276
2181
  let l = "piercer";
1277
- a > 0.75 ? l = "parasite" : a > 0.5 ? l = "cluster" : a > 0.25 && (l = "spore");
1278
- const r = this.pool.get();
1279
- return S.configureEnemy(r, l, s, i), r;
2182
+ a > 0.75 ? l = "heavy" : a > 0.55 ? l = "parasite" : a > 0.35 ? l = "cluster" : a > 0.15 && (l = "spore");
2183
+ const n = this.pool.get();
2184
+ return T.configureEnemy(n, l, s, i), n;
1280
2185
  }
1281
2186
  spawnPatternFormation(t, e, i) {
1282
2187
  const s = Math.random();
1283
- return s < 0.25 ? C.spawnCircleOfDeath(this.pool, i, t, e) : s < 0.5 ? C.spawnDenseCluster(this.pool, t, e, i) : s < 0.75 ? C.spawnSineSnake(this.pool, t, e, i) : C.spawnMarchingWall(this.pool, t, e, i);
2188
+ return s < 0.25 ? O.spawnCircleOfDeath(this.pool, i, t, e) : s < 0.5 ? O.spawnDenseCluster(this.pool, t, e, i) : s < 0.75 ? O.spawnSineSnake(this.pool, t, e, i) : O.spawnMarchingWall(this.pool, t, e, i);
1284
2189
  }
1285
2190
  applyFlockingBehaviors(t, e, i) {
1286
2191
  for (let a = 0; a < t.length; a++) {
1287
2192
  const l = t[a];
1288
2193
  if (!l.active || l.isGrabbed || l.isThrown || l.isDying) continue;
1289
- let r = 0, n = 0, o = 0;
2194
+ let n = 0, o = 0, r = 0;
1290
2195
  for (let p = 0; p < t.length; p++) {
1291
2196
  if (a === p) continue;
1292
- const f = t[p];
1293
- if (!f.active || f.isGrabbed || f.isDying) continue;
1294
- const y = l.position.x - f.position.x, d = l.position.y - f.position.y, m = Math.hypot(y, d);
1295
- m > 0 && m < 70 && (r += y / m, n += d / m, o++);
2197
+ const _ = t[p];
2198
+ if (!_.active || _.isGrabbed || _.isDying) continue;
2199
+ const d = l.position.x - _.position.x, g = l.position.y - _.position.y, f = Math.hypot(d, g);
2200
+ f > 0 && f < 70 && (n += d / f, o += g / f, r++);
1296
2201
  }
1297
- o > 0 && (r /= o, n /= o, l.velocity.x += r * 60 * e, l.velocity.y += n * 60 * e);
1298
- const h = i.x - l.position.x, c = i.y - l.position.y, u = Math.hypot(h, c);
2202
+ r > 0 && (n /= r, o /= r, l.velocity.x += n * 60 * e, l.velocity.y += o * 60 * e);
2203
+ const c = i.x - l.position.x, h = i.y - l.position.y, u = Math.hypot(c, h);
1299
2204
  if (u > 0) {
1300
2205
  const p = 80 + Math.min(this.wave * 4, 40);
1301
- l.velocity.x += h / u * p * e, l.velocity.y += c / u * p * e;
2206
+ l.velocity.x += c / u * p * e, l.velocity.y += h / u * p * e;
1302
2207
  }
1303
2208
  if (l.maxSpeed > 0) {
1304
2209
  const p = Math.hypot(l.velocity.x, l.velocity.y);
1305
2210
  if (p > l.maxSpeed) {
1306
- const f = l.maxSpeed / p;
1307
- l.velocity.x *= f, l.velocity.y *= f;
2211
+ const _ = l.maxSpeed / p;
2212
+ l.velocity.x *= _, l.velocity.y *= _;
1308
2213
  }
1309
2214
  }
1310
2215
  }
1311
2216
  }
1312
2217
  }
1313
- const w = {
2218
+ const N = {
1314
2219
  bioluminescent: {
1315
2220
  bgInner: "#081220",
1316
2221
  bgMid: "#050b16",
@@ -1359,44 +2264,43 @@ const w = {
1359
2264
  tendrilMagenta: "#b5008c",
1360
2265
  tendrilCyan: "#0077b6"
1361
2266
  }
1362
- }, P = "axon_surge_theme", O = "axon_surge_theme_explicit";
1363
- class tt {
2267
+ }, U = "axon_surge_theme";
2268
+ class dt {
1364
2269
  currentTheme = "dark";
1365
2270
  isExplicit = !1;
1366
2271
  targetElement;
1367
2272
  constructor(t, e) {
1368
- if (e !== void 0 && (this.targetElement = e), t && w[t]) {
1369
- this.currentTheme = t, this.isExplicit = !0, this.applyThemeToDOM();
1370
- return;
1371
- }
2273
+ e !== void 0 && (this.targetElement = e);
1372
2274
  try {
1373
- const i = localStorage.getItem(O) === "true", s = localStorage.getItem(P);
1374
- if (i && s && w[s]) {
1375
- this.currentTheme = s, this.isExplicit = !0, this.applyThemeToDOM();
2275
+ const i = localStorage.getItem(U);
2276
+ if (i && N[i]) {
2277
+ this.currentTheme = i, this.isExplicit = !0, this.applyThemeToDOM();
1376
2278
  return;
1377
2279
  }
1378
2280
  } catch {
1379
2281
  }
2282
+ if (t && N[t]) {
2283
+ this.currentTheme = t, this.isExplicit = !0, this.applyThemeToDOM();
2284
+ return;
2285
+ }
1380
2286
  this.currentTheme = this.detectParentOrSystemTheme();
1381
2287
  }
1382
2288
  setTargetElement(t) {
1383
2289
  this.targetElement = t, this.isExplicit ? this.applyThemeToDOM() : this.currentTheme = this.detectParentOrSystemTheme();
1384
2290
  }
1385
- setTheme(t, e = !0) {
1386
- if (w[t])
1387
- if (this.currentTheme = t, this.isExplicit = e, e) {
1388
- this.applyThemeToDOM();
1389
- try {
1390
- localStorage.setItem(P, t), localStorage.setItem(O, "true");
1391
- } catch {
1392
- }
1393
- } else
1394
- this.removeThemeClasses();
2291
+ setTheme(t) {
2292
+ if (N[t]) {
2293
+ this.currentTheme = t, this.isExplicit = !0, this.applyThemeToDOM();
2294
+ try {
2295
+ localStorage.setItem(U, t);
2296
+ } catch {
2297
+ }
2298
+ }
1395
2299
  }
1396
2300
  clearExplicitTheme() {
1397
2301
  this.isExplicit = !1;
1398
2302
  try {
1399
- localStorage.removeItem(P), localStorage.removeItem(O);
2303
+ localStorage.removeItem(U);
1400
2304
  } catch {
1401
2305
  }
1402
2306
  this.removeThemeClasses(), this.currentTheme = this.detectParentOrSystemTheme();
@@ -1405,7 +2309,7 @@ class tt {
1405
2309
  return this.isExplicit || (this.currentTheme = this.detectParentOrSystemTheme()), this.currentTheme;
1406
2310
  }
1407
2311
  getPalette() {
1408
- return w[this.getTheme()] || w.dark;
2312
+ return N[this.getTheme()] || N.dark;
1409
2313
  }
1410
2314
  detectParentOrSystemTheme() {
1411
2315
  try {
@@ -1435,15 +2339,15 @@ class tt {
1435
2339
  }
1436
2340
  removeThemeClasses() {
1437
2341
  const t = ["theme-bioluminescent", "theme-dark", "theme-light"];
1438
- this.targetElement && this.targetElement.classList.remove(...t), document.documentElement.classList.remove(...t), document.documentElement.removeAttribute("data-theme");
2342
+ this.targetElement && this.targetElement.classList.remove(...t);
1439
2343
  }
1440
2344
  applyThemeToDOM() {
1441
- if (this.removeThemeClasses(), !this.isExplicit) return;
2345
+ if (this.removeThemeClasses(), !this.isExplicit || !this.targetElement) return;
1442
2346
  const t = `theme-${this.currentTheme}`;
1443
- this.targetElement && this.targetElement.classList.add(t), document.documentElement.classList.add(t);
2347
+ this.targetElement.classList.add(t);
1444
2348
  }
1445
2349
  }
1446
- class et {
2350
+ class gt {
1447
2351
  maxDistance = 450;
1448
2352
  maxThickness = 28;
1449
2353
  minThickness = 4;
@@ -1452,50 +2356,60 @@ class et {
1452
2356
  render(t, e, i, s) {
1453
2357
  for (const a of e) {
1454
2358
  if (!a.active || a.isGrabbed || a.isDying) continue;
1455
- const l = a.position.x, r = a.position.y;
1456
- if (l >= 0 && l <= i && r >= 0 && r <= s) continue;
1457
- const n = Math.min(i, Math.max(0, l)), o = Math.min(s, Math.max(0, r)), h = Math.hypot(l - n, r - o);
1458
- if (h <= 0 || h > this.maxDistance) continue;
1459
- const c = Math.min(1, Math.max(0, h / this.maxDistance)), u = this.minThickness + (this.maxThickness - this.minThickness) * c, p = this.minLength + (this.maxLength - this.minLength) * c, f = 0.35 + (1 - c) * 0.55;
1460
- if (t.save(), t.globalAlpha = f, t.shadowColor = a.color, t.shadowBlur = 12 + (1 - c) * 16, t.strokeStyle = a.color, t.lineWidth = u, t.lineCap = "round", t.beginPath(), n === 0 || n === i) {
1461
- const y = Math.max(0, o - p / 2), d = Math.min(s, o + p / 2);
1462
- t.moveTo(n, y), t.lineTo(n, d);
2359
+ const l = a.position.x, n = a.position.y;
2360
+ if (l >= 0 && l <= i && n >= 0 && n <= s) continue;
2361
+ const o = Math.min(i, Math.max(0, l)), r = Math.min(s, Math.max(0, n)), c = Math.hypot(l - o, n - r);
2362
+ if (c <= 0 || c > this.maxDistance) continue;
2363
+ const h = Math.min(1, Math.max(0, c / this.maxDistance)), u = this.minThickness + (this.maxThickness - this.minThickness) * h, p = this.minLength + (this.maxLength - this.minLength) * h, _ = 0.35 + (1 - h) * 0.55;
2364
+ if (t.save(), t.globalAlpha = _, t.shadowColor = a.color, t.shadowBlur = 12 + (1 - h) * 16, t.strokeStyle = a.color, t.lineWidth = u, t.lineCap = "round", t.beginPath(), o === 0 || o === i) {
2365
+ const d = Math.max(0, r - p / 2), g = Math.min(s, r + p / 2);
2366
+ t.moveTo(o, d), t.lineTo(o, g);
1463
2367
  } else {
1464
- const y = Math.max(0, n - p / 2), d = Math.min(i, n + p / 2);
1465
- t.moveTo(y, o), t.lineTo(d, o);
2368
+ const d = Math.max(0, o - p / 2), g = Math.min(i, o + p / 2);
2369
+ t.moveTo(d, r), t.lineTo(g, r);
1466
2370
  }
1467
- t.stroke(), t.strokeStyle = "#ffffff", t.lineWidth = Math.max(1.5, u * 0.25), t.globalAlpha = f * 0.8, t.stroke(), t.restore();
2371
+ t.stroke(), t.strokeStyle = "#ffffff", t.lineWidth = Math.max(1.5, u * 0.25), t.globalAlpha = _ * 0.8, t.stroke(), t.restore();
1468
2372
  }
1469
2373
  }
1470
2374
  }
1471
- class it {
1472
- render(t, e, i, s, a) {
1473
- const l = (210 + (a - 1) * 38 + Math.sin(s * 0.12) * 15) % 360, r = `hsl(${l}, 45%, 8%)`, n = `hsl(${(l + 30) % 360}, 40%, 4%)`, o = `hsl(${(l + 60) % 360}, 50%, 2%)`, h = t.createRadialGradient(e / 2, i / 2, 40, e / 2, i / 2, Math.max(e, i));
1474
- h.addColorStop(0, r), h.addColorStop(0.55, n), h.addColorStop(1, o), t.fillStyle = h, t.fillRect(0, 0, e, i);
1475
- const c = (l + 75) % 360, u = e * 0.35 + Math.sin(s * 0.25) * 70, p = i * 0.45 + Math.cos(s * 0.2) * 60, f = t.createRadialGradient(u, p, 20, u, p, 400);
1476
- f.addColorStop(0, `hsla(${c}, 65%, 12%, 0.35)`), f.addColorStop(1, "rgba(0, 0, 0, 0)"), t.fillStyle = f, t.beginPath(), t.arc(u, p, 400, 0, Math.PI * 2), t.fill();
1477
- const y = (l + 160) % 360, d = e * 0.68 + Math.cos(s * 0.28) * 60, m = i * 0.55 + Math.sin(s * 0.22) * 55, x = t.createRadialGradient(d, m, 20, d, m, 440);
1478
- x.addColorStop(0, `hsla(${y}, 60%, 10%, 0.3)`), x.addColorStop(1, "rgba(0, 0, 0, 0)"), t.fillStyle = x, t.beginPath(), t.arc(d, m, 440, 0, Math.PI * 2), t.fill();
2375
+ class _t {
2376
+ render(t, e, i, s, a, l = !1) {
2377
+ const n = (210 + (a - 1) * 38 + Math.sin(s * 0.12) * 15) % 360;
2378
+ if (l) {
2379
+ const v = `hsl(${n}, 50%, 94%)`, I = `hsl(${(n + 25) % 360}, 45%, 89%)`, S = `hsl(${(n + 50) % 360}, 40%, 82%)`, m = t.createRadialGradient(e / 2, i / 2, 40, e / 2, i / 2, Math.max(e, i));
2380
+ m.addColorStop(0, v), m.addColorStop(0.55, I), m.addColorStop(1, S), t.fillStyle = m, t.fillRect(0, 0, e, i);
2381
+ const y = (n + 75) % 360, M = e * 0.35 + Math.sin(s * 0.25) * 70, L = i * 0.45 + Math.cos(s * 0.2) * 60, C = t.createRadialGradient(M, L, 20, M, L, 400);
2382
+ C.addColorStop(0, `hsla(${y}, 65%, 78%, 0.35)`), C.addColorStop(1, "rgba(255, 255, 255, 0)"), t.fillStyle = C, t.beginPath(), t.arc(M, L, 400, 0, Math.PI * 2), t.fill();
2383
+ const Z = (n + 160) % 360, D = e * 0.68 + Math.cos(s * 0.28) * 60, k = i * 0.55 + Math.sin(s * 0.22) * 55, G = t.createRadialGradient(D, k, 20, D, k, 440);
2384
+ G.addColorStop(0, `hsla(${Z}, 60%, 75%, 0.3)`), G.addColorStop(1, "rgba(255, 255, 255, 0)"), t.fillStyle = G, t.beginPath(), t.arc(D, k, 440, 0, Math.PI * 2), t.fill();
2385
+ return;
2386
+ }
2387
+ const o = `hsl(${n}, 45%, 8%)`, r = `hsl(${(n + 30) % 360}, 40%, 4%)`, c = `hsl(${(n + 60) % 360}, 50%, 2%)`, h = t.createRadialGradient(e / 2, i / 2, 40, e / 2, i / 2, Math.max(e, i));
2388
+ h.addColorStop(0, o), h.addColorStop(0.55, r), h.addColorStop(1, c), t.fillStyle = h, t.fillRect(0, 0, e, i);
2389
+ const u = (n + 75) % 360, p = e * 0.35 + Math.sin(s * 0.25) * 70, _ = i * 0.45 + Math.cos(s * 0.2) * 60, d = t.createRadialGradient(p, _, 20, p, _, 400);
2390
+ d.addColorStop(0, `hsla(${u}, 65%, 12%, 0.35)`), d.addColorStop(1, "rgba(0, 0, 0, 0)"), t.fillStyle = d, t.beginPath(), t.arc(p, _, 400, 0, Math.PI * 2), t.fill();
2391
+ const g = (n + 160) % 360, f = e * 0.68 + Math.cos(s * 0.28) * 60, x = i * 0.55 + Math.sin(s * 0.22) * 55, b = t.createRadialGradient(f, x, 20, f, x, 440);
2392
+ b.addColorStop(0, `hsla(${g}, 60%, 10%, 0.3)`), b.addColorStop(1, "rgba(0, 0, 0, 0)"), t.fillStyle = b, t.beginPath(), t.arc(f, x, 440, 0, Math.PI * 2), t.fill();
1479
2393
  }
1480
2394
  }
1481
- class st {
2395
+ class mt {
1482
2396
  render(t, e, i) {
1483
2397
  if (!e.isActive) return;
1484
2398
  const s = e.getLauncher(), a = e.getTarget();
1485
2399
  if (!s || !a || !s.active || !a.active) return;
1486
2400
  const l = e.getStep();
1487
2401
  if (t.save(), l === 1) {
1488
- const r = Math.sin(i * 6) * 10, n = s.position.x, o = s.position.y - 65 + r;
1489
- t.shadowColor = "#00f0ff", t.shadowBlur = 20, t.fillStyle = "#00f0ff", t.beginPath(), t.moveTo(n, o + 20), t.lineTo(n - 16, o - 12), t.lineTo(n - 6, o - 12), t.lineTo(n - 6, o - 32), t.lineTo(n + 6, o - 32), t.lineTo(n + 6, o - 12), t.lineTo(n + 16, o - 12), t.closePath(), t.fill();
1490
- const h = s.radius * (1.6 + Math.sin(i * 8) * 0.3);
1491
- t.strokeStyle = "rgba(0, 240, 255, 0.8)", t.lineWidth = 3, t.beginPath(), t.arc(s.position.x, s.position.y, h, 0, Math.PI * 2), t.stroke();
2402
+ const n = Math.sin(i * 6) * 10, o = s.position.x, r = s.position.y - 65 + n;
2403
+ t.shadowColor = "#00f0ff", t.shadowBlur = 20, t.fillStyle = "#00f0ff", t.beginPath(), t.moveTo(o, r + 20), t.lineTo(o - 16, r - 12), t.lineTo(o - 6, r - 12), t.lineTo(o - 6, r - 32), t.lineTo(o + 6, r - 32), t.lineTo(o + 6, r - 12), t.lineTo(o + 16, r - 12), t.closePath(), t.fill();
2404
+ const c = s.radius * (1.6 + Math.sin(i * 8) * 0.3);
2405
+ t.strokeStyle = "rgba(0, 240, 255, 0.8)", t.lineWidth = 3, t.beginPath(), t.arc(s.position.x, s.position.y, c, 0, Math.PI * 2), t.stroke();
1492
2406
  } else if (l === 2) {
1493
- const r = a.position.x - s.position.x, n = a.position.y - s.position.y;
1494
- if (Math.hypot(r, n) > 10) {
1495
- const h = Math.atan2(n, r);
2407
+ const n = a.position.x - s.position.x, o = a.position.y - s.position.y;
2408
+ if (Math.hypot(n, o) > 10) {
2409
+ const c = Math.atan2(o, n);
1496
2410
  t.shadowColor = "#ff00dd", t.shadowBlur = 22, t.strokeStyle = "#ff00dd", t.lineWidth = 4, t.setLineDash([12, 8]), t.beginPath(), t.moveTo(s.position.x, s.position.y), t.lineTo(a.position.x, a.position.y), t.stroke(), t.setLineDash([]);
1497
- const c = a.position.x - Math.cos(h) * (a.radius + 10), u = a.position.y - Math.sin(h) * (a.radius + 10);
1498
- t.fillStyle = "#ff00dd", t.beginPath(), t.moveTo(c, u), t.lineTo(c - Math.cos(h - 0.4) * 24, u - Math.sin(h - 0.4) * 24), t.lineTo(c - Math.cos(h + 0.4) * 24, u - Math.sin(h + 0.4) * 24), t.closePath(), t.fill();
2411
+ const h = a.position.x - Math.cos(c) * (a.radius + 10), u = a.position.y - Math.sin(c) * (a.radius + 10);
2412
+ t.fillStyle = "#ff00dd", t.beginPath(), t.moveTo(h, u), t.lineTo(h - Math.cos(c - 0.4) * 24, u - Math.sin(c - 0.4) * 24), t.lineTo(h - Math.cos(c + 0.4) * 24, u - Math.sin(c + 0.4) * 24), t.closePath(), t.fill();
1499
2413
  const p = a.radius * (1.8 + Math.cos(i * 10) * 0.3);
1500
2414
  t.strokeStyle = "rgba(255, 0, 221, 0.9)", t.lineWidth = 3.5, t.beginPath(), t.arc(a.position.x, a.position.y, p, 0, Math.PI * 2), t.stroke();
1501
2415
  }
@@ -1503,7 +2417,7 @@ class st {
1503
2417
  t.restore();
1504
2418
  }
1505
2419
  }
1506
- class at {
2420
+ class ft {
1507
2421
  canvas;
1508
2422
  ctx;
1509
2423
  themeManager;
@@ -1511,34 +2425,34 @@ class at {
1511
2425
  bgRenderer;
1512
2426
  tutorialArrowRenderer;
1513
2427
  constructor(t, e) {
1514
- this.canvas = t, this.ctx = t.getContext("2d"), this.themeManager = e, this.indicatorRenderer = new et(), this.bgRenderer = new it(), this.tutorialArrowRenderer = new st();
2428
+ this.canvas = t, this.ctx = t.getContext("2d"), this.themeManager = e, this.indicatorRenderer = new gt(), this.bgRenderer = new _t(), this.tutorialArrowRenderer = new mt();
1515
2429
  }
1516
- render(t, e, i, s, a, l, r, n, o, h, c = 1, u) {
2430
+ render(t, e, i, s, a, l, n, o, r, c, h = 1, u) {
1517
2431
  if (!this.ctx) return;
1518
- const p = this.themeManager.getPalette(), { width: f, height: y } = this.canvas, d = n.getShakeOffset();
1519
- this.ctx.save(), this.ctx.translate(d.x, d.y), this.bgRenderer.render(this.ctx, f, y, t.pulsePhase, c), this.drawToxicPools(i, t.pulsePhase), this.drawGravityVortices(s, t.pulsePhase), this.drawShockwaves(a), this.drawCoreFilaments(t, p), this.drawParticles(l), this.indicatorRenderer.render(this.ctx, e, f, y), this.drawOrganicEnemies(e, t.pulsePhase, p), u && this.tutorialArrowRenderer.render(this.ctx, u, t.pulsePhase), o ? this.drawPsionicTendril(t.position, o.position, p) : t && this.drawHoverTendril(t.position, h, e, p), this.drawOrganicConsciousnessCore(t, p), this.drawFloatingTexts(r), n.flashAlpha > 0 && (this.ctx.fillStyle = `rgba(255, 255, 255, ${n.flashAlpha})`, this.ctx.fillRect(0, 0, f, y)), this.ctx.restore();
2432
+ const p = this.themeManager.getPalette(), { width: _, height: d } = this.canvas, g = o.getShakeOffset();
2433
+ this.ctx.save(), this.ctx.translate(g.x, g.y), this.bgRenderer.render(this.ctx, _, d, t.pulsePhase, h, this.themeManager.getTheme() === "light"), this.drawToxicPools(i, t.pulsePhase), this.drawGravityVortices(s, t.pulsePhase), this.drawShockwaves(a), this.drawCoreFilaments(t, p), this.drawParticles(l), this.indicatorRenderer.render(this.ctx, e, _, d), this.drawOrganicEnemies(e, t.pulsePhase, p), u && this.tutorialArrowRenderer.render(this.ctx, u, t.pulsePhase), r ? this.drawPsionicTendril(t.position, r.position, p) : t && this.drawHoverTendril(t.position, c, e, p), this.drawOrganicConsciousnessCore(t, p), this.drawFloatingTexts(n), o.flashAlpha > 0 && (this.ctx.fillStyle = `rgba(255, 255, 255, ${o.flashAlpha})`, this.ctx.fillRect(0, 0, _, d)), this.ctx.restore();
1520
2434
  }
1521
2435
  drawToxicPools(t, e) {
1522
2436
  if (this.ctx)
1523
2437
  for (const i of t) {
1524
- const s = i.duration / i.maxDuration, a = Math.min(0.7, (1 - s) * 0.7), { x: l, y: r } = i.position;
2438
+ const s = i.duration / i.maxDuration, a = Math.min(0.7, (1 - s) * 0.7), { x: l, y: n } = i.position;
1525
2439
  this.ctx.save();
1526
- const n = this.ctx.createRadialGradient(l, r, 10, l, r, i.radius * 1.2);
1527
- n.addColorStop(0, `rgba(57, 255, 20, ${a * 0.9})`), n.addColorStop(0.4, `rgba(16, 185, 129, ${a * 0.65})`), n.addColorStop(0.8, `rgba(5, 80, 45, ${a * 0.35})`), n.addColorStop(1, "rgba(2, 35, 15, 0)"), this.ctx.fillStyle = n, this.ctx.shadowColor = "#39ff14", this.ctx.shadowBlur = 30, this.ctx.beginPath();
1528
- const o = 70;
1529
- for (let h = 0; h <= o; h++) {
1530
- const c = h * Math.PI * 2 / o, u = Math.sin(c * 5 + e * 3) * 14, p = Math.cos(c * 3 - e * 2) * 9, f = i.radius + u + p, y = l + Math.cos(c) * f, d = r + Math.sin(c) * f;
1531
- h === 0 ? this.ctx.moveTo(y, d) : this.ctx.lineTo(y, d);
2440
+ const o = this.ctx.createRadialGradient(l, n, 10, l, n, i.radius * 1.2);
2441
+ o.addColorStop(0, `rgba(57, 255, 20, ${a * 0.9})`), o.addColorStop(0.4, `rgba(16, 185, 129, ${a * 0.65})`), o.addColorStop(0.8, `rgba(5, 80, 45, ${a * 0.35})`), o.addColorStop(1, "rgba(2, 35, 15, 0)"), this.ctx.fillStyle = o, this.ctx.shadowColor = "#39ff14", this.ctx.shadowBlur = 30, this.ctx.beginPath();
2442
+ const r = 70;
2443
+ for (let c = 0; c <= r; c++) {
2444
+ const h = c * Math.PI * 2 / r, u = Math.sin(h * 5 + e * 3) * 14, p = Math.cos(h * 3 - e * 2) * 9, _ = i.radius + u + p, d = l + Math.cos(h) * _, g = n + Math.sin(h) * _;
2445
+ c === 0 ? this.ctx.moveTo(d, g) : this.ctx.lineTo(d, g);
1532
2446
  }
1533
2447
  this.ctx.closePath(), this.ctx.fill(), this.ctx.strokeStyle = `rgba(57, 255, 20, ${a * 0.8})`, this.ctx.lineWidth = 2.5, this.ctx.beginPath();
1534
- for (let h = 0; h <= o; h++) {
1535
- const c = h * Math.PI * 2 / o, u = Math.sin(c * 6 + e * 4) * 8, p = i.radius * 0.75 + u, f = l + Math.cos(c) * p, y = r + Math.sin(c) * p;
1536
- h === 0 ? this.ctx.moveTo(f, y) : this.ctx.lineTo(f, y);
2448
+ for (let c = 0; c <= r; c++) {
2449
+ const h = c * Math.PI * 2 / r, u = Math.sin(h * 6 + e * 4) * 8, p = i.radius * 0.75 + u, _ = l + Math.cos(h) * p, d = n + Math.sin(h) * p;
2450
+ c === 0 ? this.ctx.moveTo(_, d) : this.ctx.lineTo(_, d);
1537
2451
  }
1538
2452
  this.ctx.closePath(), this.ctx.stroke();
1539
- for (let h = 0; h < 6; h++) {
1540
- const c = h * Math.PI * 0.33 + e * 1.5, u = i.radius * 0.5 * (0.3 + Math.sin(e * 2 + h) * 0.3), p = l + Math.cos(c) * u, f = r + Math.sin(c) * u, y = 3 + Math.sin(e * 3 + h) * 2;
1541
- this.ctx.fillStyle = `rgba(255, 255, 255, ${a * 0.8})`, this.ctx.beginPath(), this.ctx.arc(p, f, Math.max(1, y), 0, Math.PI * 2), this.ctx.fill();
2453
+ for (let c = 0; c < 6; c++) {
2454
+ const h = c * Math.PI * 0.33 + e * 1.5, u = i.radius * 0.5 * (0.3 + Math.sin(e * 2 + c) * 0.3), p = l + Math.cos(h) * u, _ = n + Math.sin(h) * u, d = 3 + Math.sin(e * 3 + c) * 2;
2455
+ this.ctx.fillStyle = `rgba(255, 255, 255, ${a * 0.8})`, this.ctx.beginPath(), this.ctx.arc(p, _, Math.max(1, d), 0, Math.PI * 2), this.ctx.fill();
1542
2456
  }
1543
2457
  this.ctx.restore();
1544
2458
  }
@@ -1561,13 +2475,13 @@ class at {
1561
2475
  drawGravityVortices(t, e) {
1562
2476
  if (this.ctx)
1563
2477
  for (const i of t) {
1564
- const s = Math.min(0.85, (1 - i.duration / i.maxDuration) * 0.85), a = i.radius * (1 - i.duration / i.maxDuration * 0.1), { x: l, y: r } = i.position;
2478
+ const s = Math.min(0.85, (1 - i.duration / i.maxDuration) * 0.85), a = i.radius * (1 - i.duration / i.maxDuration * 0.1), { x: l, y: n } = i.position;
1565
2479
  this.ctx.save();
1566
- const n = this.ctx.createRadialGradient(l, r, 0, l, r, 60);
1567
- n.addColorStop(0, `rgba(0, 0, 0, ${s})`), n.addColorStop(0.7, `rgba(20, 0, 40, ${s})`), n.addColorStop(1, `rgba(157, 78, 221, ${s * 0.5})`), this.ctx.fillStyle = n, this.ctx.beginPath(), this.ctx.arc(l, r, 60, 0, Math.PI * 2), this.ctx.fill(), this.ctx.strokeStyle = `rgba(157, 78, 221, ${s})`, this.ctx.lineWidth = 5, this.ctx.shadowColor = "#9d4edd", this.ctx.shadowBlur = 32;
1568
- for (let o = 1; o <= 5; o++) {
1569
- const h = a * o / 5, c = e * o * 2.2;
1570
- this.ctx.beginPath(), this.ctx.arc(l, r, h, c, c + Math.PI * 1.5), this.ctx.stroke();
2480
+ const o = this.ctx.createRadialGradient(l, n, 0, l, n, 60);
2481
+ o.addColorStop(0, `rgba(0, 0, 0, ${s})`), o.addColorStop(0.7, `rgba(20, 0, 40, ${s})`), o.addColorStop(1, `rgba(157, 78, 221, ${s * 0.5})`), this.ctx.fillStyle = o, this.ctx.beginPath(), this.ctx.arc(l, n, 60, 0, Math.PI * 2), this.ctx.fill(), this.ctx.strokeStyle = `rgba(157, 78, 221, ${s})`, this.ctx.lineWidth = 5, this.ctx.shadowColor = "#9d4edd", this.ctx.shadowBlur = 32;
2482
+ for (let r = 1; r <= 5; r++) {
2483
+ const c = a * r / 5, h = e * r * 2.2;
2484
+ this.ctx.beginPath(), this.ctx.arc(l, n, c, h, h + Math.PI * 1.5), this.ctx.stroke();
1571
2485
  }
1572
2486
  this.ctx.restore();
1573
2487
  }
@@ -1576,52 +2490,78 @@ class at {
1576
2490
  if (!this.ctx) return;
1577
2491
  const a = this.ctx.createRadialGradient(t / 2, e / 2, 40, t / 2, e / 2, Math.max(t, e));
1578
2492
  a.addColorStop(0, s.bgInner), a.addColorStop(0.5, s.bgMid), a.addColorStop(1, s.bgOuter), this.ctx.fillStyle = a, this.ctx.fillRect(0, 0, t, e);
1579
- const l = t * 0.35 + Math.sin(i * 0.3) * 60, r = e * 0.45 + Math.cos(i * 0.25) * 50, n = this.ctx.createRadialGradient(l, r, 20, l, r, 380);
1580
- n.addColorStop(0, s.nebulaCyan), n.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = n, this.ctx.beginPath(), this.ctx.arc(l, r, 380, 0, Math.PI * 2), this.ctx.fill();
1581
- const o = t * 0.68 + Math.cos(i * 0.35) * 50, h = e * 0.55 + Math.sin(i * 0.3) * 45, c = this.ctx.createRadialGradient(o, h, 20, o, h, 420);
1582
- c.addColorStop(0, s.nebulaMagenta), c.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = c, this.ctx.beginPath(), this.ctx.arc(o, h, 420, 0, Math.PI * 2), this.ctx.fill();
2493
+ const l = t * 0.35 + Math.sin(i * 0.3) * 60, n = e * 0.45 + Math.cos(i * 0.25) * 50, o = this.ctx.createRadialGradient(l, n, 20, l, n, 380);
2494
+ o.addColorStop(0, s.nebulaCyan), o.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = o, this.ctx.beginPath(), this.ctx.arc(l, n, 380, 0, Math.PI * 2), this.ctx.fill();
2495
+ const r = t * 0.68 + Math.cos(i * 0.35) * 50, c = e * 0.55 + Math.sin(i * 0.3) * 45, h = this.ctx.createRadialGradient(r, c, 20, r, c, 420);
2496
+ h.addColorStop(0, s.nebulaMagenta), h.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = h, this.ctx.beginPath(), this.ctx.arc(r, c, 420, 0, Math.PI * 2), this.ctx.fill();
1583
2497
  }
1584
2498
  drawCoreFilaments(t, e) {
1585
2499
  if (!this.ctx) return;
1586
2500
  const i = 12;
1587
2501
  this.ctx.lineWidth = 1.5, this.ctx.strokeStyle = e.nebulaCyan;
1588
2502
  for (let s = 0; s < i; s++) {
1589
- const a = s * Math.PI * 2 / i + t.pulsePhase * 0.12, l = 85 + Math.sin(t.pulsePhase * 1.5 + s) * 25, r = t.position.x + Math.cos(a) * l, n = t.position.y + Math.sin(a) * l, o = t.position.x + Math.cos(a + 0.4) * 48, h = t.position.y + Math.sin(a + 0.4) * 48;
1590
- this.ctx.beginPath(), this.ctx.moveTo(t.position.x, t.position.y), this.ctx.quadraticCurveTo(o, h, r, n), this.ctx.stroke(), this.ctx.fillStyle = e.sporeColor, this.ctx.beginPath(), this.ctx.arc(r, n, 3.5, 0, Math.PI * 2), this.ctx.fill();
2503
+ const a = s * Math.PI * 2 / i + t.pulsePhase * 0.12, l = 85 + Math.sin(t.pulsePhase * 1.5 + s) * 25, n = t.position.x + Math.cos(a) * l, o = t.position.y + Math.sin(a) * l, r = t.position.x + Math.cos(a + 0.4) * 48, c = t.position.y + Math.sin(a + 0.4) * 48;
2504
+ this.ctx.beginPath(), this.ctx.moveTo(t.position.x, t.position.y), this.ctx.quadraticCurveTo(r, c, n, o), this.ctx.stroke(), this.ctx.fillStyle = e.sporeColor, this.ctx.beginPath(), this.ctx.arc(n, o, 3.5, 0, Math.PI * 2), this.ctx.fill();
1591
2505
  }
1592
2506
  }
1593
2507
  drawOrganicConsciousnessCore(t, e) {
1594
2508
  if (!this.ctx) return;
1595
2509
  const { x: i, y: s } = t.position;
2510
+ if (this.ctx.save(), t.invulnerabilityTimer > 0) {
2511
+ const r = Math.floor(t.invulnerabilityTimer * 20) % 2 === 0;
2512
+ this.ctx.globalAlpha = r ? 0.3 : 0.9;
2513
+ }
2514
+ const a = t.getColorHex();
1596
2515
  for (let r = 0; r < t.integrity; r++) {
1597
- const n = t.radius + 16 + r * 12;
1598
- this.ctx.strokeStyle = e.corePrimary, this.ctx.lineWidth = 2.2, this.ctx.shadowColor = e.corePrimary, this.ctx.shadowBlur = 12, this.ctx.beginPath();
1599
- const o = 60;
1600
- for (let h = 0; h <= o; h++) {
1601
- const c = h * Math.PI * 2 / o, u = n + Math.sin(c * 4 + t.pulsePhase * 2 + r) * 3, p = i + Math.cos(c) * u, f = s + Math.sin(c) * u;
1602
- h === 0 ? this.ctx.moveTo(p, f) : this.ctx.lineTo(p, f);
2516
+ const c = t.radius + 16 + r * 12;
2517
+ this.ctx.strokeStyle = a, this.ctx.lineWidth = 2.2, this.ctx.shadowColor = a, this.ctx.shadowBlur = 12, this.ctx.beginPath();
2518
+ const h = 60;
2519
+ for (let u = 0; u <= h; u++) {
2520
+ const p = u * Math.PI * 2 / h, _ = c + Math.sin(p * 4 + t.pulsePhase * 2 + r) * 3, d = i + Math.cos(p) * _, g = s + Math.sin(p) * _;
2521
+ u === 0 ? this.ctx.moveTo(d, g) : this.ctx.lineTo(d, g);
1603
2522
  }
1604
2523
  this.ctx.closePath(), this.ctx.stroke();
1605
2524
  }
1606
- const a = this.ctx.createRadialGradient(i, s, 5, i, s, t.radius * 2.2);
1607
- a.addColorStop(0, e.coreGlow), a.addColorStop(0.5, e.nebulaMagenta), a.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = a, this.ctx.beginPath(), this.ctx.arc(i, s, t.radius * 2.2, 0, Math.PI * 2), this.ctx.fill(), this.ctx.save(), this.ctx.translate(i, s), this.ctx.strokeStyle = e.corePrimary, this.ctx.lineWidth = 3, this.ctx.fillStyle = e.nebulaCyan, this.ctx.shadowColor = e.corePrimary, this.ctx.shadowBlur = 20, this.ctx.beginPath();
1608
- const l = 80;
1609
- for (let r = 0; r <= l; r++) {
1610
- const n = r * Math.PI * 2 / l, o = t.getMembraneRadius(n), h = Math.cos(n) * o, c = Math.sin(n) * o;
1611
- r === 0 ? this.ctx.moveTo(h, c) : this.ctx.lineTo(h, c);
2525
+ if (t.repairProgress > 0) {
2526
+ const r = t.integrity, c = t.radius + 16 + r * 12;
2527
+ this.ctx.save(), this.ctx.globalAlpha = Math.max(0.15, t.repairProgress), this.ctx.strokeStyle = a, this.ctx.lineWidth = 2, this.ctx.shadowColor = a, this.ctx.shadowBlur = 8, this.ctx.setLineDash([6, 4]), this.ctx.beginPath();
2528
+ const h = 60;
2529
+ for (let u = 0; u <= h; u++) {
2530
+ const p = u * Math.PI * 2 / h, _ = c + Math.sin(p * 4 + t.pulsePhase * 2 + r) * 3, d = i + Math.cos(p) * _, g = s + Math.sin(p) * _;
2531
+ u === 0 ? this.ctx.moveTo(d, g) : this.ctx.lineTo(d, g);
2532
+ }
2533
+ this.ctx.closePath(), this.ctx.stroke(), this.ctx.restore();
2534
+ }
2535
+ const l = this.ctx.createRadialGradient(i, s, 5, i, s, t.radius * 2.2);
2536
+ l.addColorStop(0, a), l.addColorStop(0.5, e.nebulaMagenta), l.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = l, this.ctx.beginPath(), this.ctx.arc(i, s, t.radius * 2.2, 0, Math.PI * 2), this.ctx.fill(), this.ctx.save(), this.ctx.translate(i, s), this.ctx.strokeStyle = a, this.ctx.lineWidth = 3, this.ctx.fillStyle = a, this.ctx.shadowColor = a, this.ctx.shadowBlur = 20, this.ctx.beginPath();
2537
+ const n = 80;
2538
+ for (let r = 0; r <= n; r++) {
2539
+ const c = r * Math.PI * 2 / n, h = t.getMembraneRadius(c), u = Math.cos(c) * h, p = Math.sin(c) * h;
2540
+ r === 0 ? this.ctx.moveTo(u, p) : this.ctx.lineTo(u, p);
2541
+ }
2542
+ this.ctx.closePath(), this.ctx.fill(), this.ctx.stroke();
2543
+ const o = t.powerUpCount;
2544
+ if (o > 0) {
2545
+ this.ctx.strokeStyle = "#ffffff", this.ctx.lineWidth = 1.8, this.ctx.shadowColor = a, this.ctx.shadowBlur = 10;
2546
+ for (let r = 0; r < o; r++) {
2547
+ const c = r * Math.PI * 2 / o + t.pulsePhase * 0.4, h = t.radius * (0.45 + Math.sin(t.pulsePhase * 2 + r) * 0.15);
2548
+ this.ctx.beginPath(), this.ctx.moveTo(0, 0);
2549
+ const u = Math.cos(c + Math.sin(t.pulsePhase + r) * 0.4) * (h * 0.6), p = Math.sin(c + Math.cos(t.pulsePhase + r) * 0.4) * (h * 0.6), _ = Math.cos(c) * h, d = Math.sin(c) * h;
2550
+ this.ctx.quadraticCurveTo(u, p, _, d), this.ctx.stroke(), this.ctx.fillStyle = a, this.ctx.beginPath(), this.ctx.arc(_, d, 2.5, 0, Math.PI * 2), this.ctx.fill();
2551
+ }
1612
2552
  }
1613
- this.ctx.closePath(), this.ctx.fill(), this.ctx.stroke(), this.ctx.fillStyle = "#ffffff", this.ctx.beginPath(), this.ctx.arc(0, 0, t.radius * 0.3, 0, Math.PI * 2), this.ctx.fill(), this.ctx.restore();
2553
+ this.ctx.fillStyle = "#ffffff", this.ctx.beginPath(), this.ctx.arc(0, 0, t.radius * 0.3, 0, Math.PI * 2), this.ctx.fill(), this.ctx.restore(), this.ctx.restore();
1614
2554
  }
1615
2555
  drawPsionicTendril(t, e, i) {
1616
2556
  if (!this.ctx) return;
1617
2557
  this.ctx.save();
1618
2558
  const s = e.x - t.x, a = e.y - t.y;
1619
2559
  this.ctx.strokeStyle = i.tendrilMagenta, this.ctx.lineWidth = 9, this.ctx.shadowColor = i.tendrilMagenta, this.ctx.shadowBlur = 20, this.ctx.beginPath(), this.ctx.moveTo(t.x, t.y);
1620
- const l = (t.x + e.x) / 2 + Math.sin(Date.now() * 0.02) * 16, r = (t.y + e.y) / 2 + Math.cos(Date.now() * 0.02) * 16;
1621
- this.ctx.quadraticCurveTo(l, r, e.x, e.y), this.ctx.stroke(), this.ctx.strokeStyle = i.tendrilCyan, this.ctx.lineWidth = 3.5, this.ctx.shadowColor = i.tendrilCyan, this.ctx.shadowBlur = 12, this.ctx.beginPath(), this.ctx.moveTo(t.x, t.y), this.ctx.lineTo(e.x, e.y), this.ctx.stroke();
1622
- for (let n = 0; n < 6; n++) {
1623
- const o = Math.random(), h = t.x + s * o + (Math.random() - 0.5) * 24, c = t.y + a * o + (Math.random() - 0.5) * 24;
1624
- this.ctx.fillStyle = "#ffffff", this.ctx.beginPath(), this.ctx.arc(h, c, 2.5 + Math.random() * 2.5, 0, Math.PI * 2), this.ctx.fill();
2560
+ const l = (t.x + e.x) / 2 + Math.sin(Date.now() * 0.02) * 16, n = (t.y + e.y) / 2 + Math.cos(Date.now() * 0.02) * 16;
2561
+ this.ctx.quadraticCurveTo(l, n, e.x, e.y), this.ctx.stroke(), this.ctx.strokeStyle = i.tendrilCyan, this.ctx.lineWidth = 3.5, this.ctx.shadowColor = i.tendrilCyan, this.ctx.shadowBlur = 12, this.ctx.beginPath(), this.ctx.moveTo(t.x, t.y), this.ctx.lineTo(e.x, e.y), this.ctx.stroke();
2562
+ for (let o = 0; o < 6; o++) {
2563
+ const r = Math.random(), c = t.x + s * r + (Math.random() - 0.5) * 24, h = t.y + a * r + (Math.random() - 0.5) * 24;
2564
+ this.ctx.fillStyle = "#ffffff", this.ctx.beginPath(), this.ctx.arc(c, h, 2.5 + Math.random() * 2.5, 0, Math.PI * 2), this.ctx.fill();
1625
2565
  }
1626
2566
  this.ctx.restore();
1627
2567
  }
@@ -1629,8 +2569,8 @@ class at {
1629
2569
  if (this.ctx)
1630
2570
  for (const a of i) {
1631
2571
  if (!a.active || a.isGrabbed || a.isThrown || a.wasManipulated || a.isDying) continue;
1632
- const l = e.x - a.position.x, r = e.y - a.position.y;
1633
- if (Math.hypot(l, r) <= a.getHitRadius()) {
2572
+ const l = e.x - a.position.x, n = e.y - a.position.y;
2573
+ if (Math.hypot(l, n) <= a.getHitRadius()) {
1634
2574
  this.ctx.strokeStyle = s.tendrilMagenta, this.ctx.lineWidth = 2.5, this.ctx.beginPath(), this.ctx.moveTo(t.x, t.y), this.ctx.lineTo(a.position.x, a.position.y), this.ctx.stroke();
1635
2575
  break;
1636
2576
  }
@@ -1642,58 +2582,68 @@ class at {
1642
2582
  if (!s.active) continue;
1643
2583
  let a = s.color;
1644
2584
  s.type === "piercer" ? a = i.piercerColor : s.type === "spore" ? a = i.sporeColor : s.type === "cluster" ? a = i.clusterColor : s.type === "parasite" ? a = i.parasiteColor : s.type === "micro" && (a = i.microColor);
1645
- const { x: l, y: r } = s.position;
1646
- if (this.ctx.save(), this.ctx.translate(l, r), s.wasManipulated && !s.isDying) {
1647
- const n = s.radius * 1.5 + Math.sin(e * 6) * 4;
1648
- this.ctx.strokeStyle = i.tendrilMagenta, this.ctx.lineWidth = 2.5, this.ctx.shadowColor = i.tendrilMagenta, this.ctx.shadowBlur = 18, this.ctx.beginPath(), this.ctx.arc(0, 0, n, 0, Math.PI * 2), this.ctx.stroke();
1649
- const o = s.radius * 1.8 + Math.cos(e * 8) * 3;
1650
- this.ctx.strokeStyle = i.tendrilCyan, this.ctx.lineWidth = 1.5, this.ctx.beginPath(), this.ctx.arc(0, 0, o, 0, Math.PI * 2), this.ctx.stroke();
2585
+ const { x: l, y: n } = s.position;
2586
+ if (this.ctx.save(), this.ctx.translate(l, n), s.wasManipulated && !s.isDying) {
2587
+ const o = s.radius * 1.5 + Math.sin(e * 6) * 4;
2588
+ this.ctx.strokeStyle = i.tendrilMagenta, this.ctx.lineWidth = 2.5, this.ctx.shadowColor = i.tendrilMagenta, this.ctx.shadowBlur = 18, this.ctx.beginPath(), this.ctx.arc(0, 0, o, 0, Math.PI * 2), this.ctx.stroke();
2589
+ const r = s.radius * 1.8 + Math.cos(e * 8) * 3;
2590
+ this.ctx.strokeStyle = i.tendrilCyan, this.ctx.lineWidth = 1.5, this.ctx.beginPath(), this.ctx.arc(0, 0, r, 0, Math.PI * 2), this.ctx.stroke();
1651
2591
  }
1652
2592
  if (s.isDying) {
1653
- const n = s.deathTimer / s.maxDeathTimer, o = Math.max(0, 1 - n);
1654
- if (this.ctx.globalAlpha = o, s.deathType === "dissolve") {
1655
- const h = s.radius * (1 - n * 0.7);
1656
- this.ctx.fillStyle = i.sporeColor, this.ctx.shadowColor = i.sporeColor, this.ctx.shadowBlur = 20, this.ctx.beginPath(), this.ctx.arc(0, 0, h, 0, Math.PI * 2), this.ctx.fill();
1657
- for (let c = 0; c < 4; c++) {
1658
- const u = c * Math.PI * 0.5 + n * 4, p = h * 0.8 * n;
2593
+ const o = s.deathTimer / s.maxDeathTimer, r = Math.max(0, 1 - o);
2594
+ if (this.ctx.globalAlpha = r, s.deathType === "dissolve") {
2595
+ const c = s.radius * (1 - o * 0.7);
2596
+ this.ctx.fillStyle = i.sporeColor, this.ctx.shadowColor = i.sporeColor, this.ctx.shadowBlur = 20, this.ctx.beginPath(), this.ctx.arc(0, 0, c, 0, Math.PI * 2), this.ctx.fill();
2597
+ for (let h = 0; h < 4; h++) {
2598
+ const u = h * Math.PI * 0.5 + o * 4, p = c * 0.8 * o;
1659
2599
  this.ctx.fillStyle = "#ffffff", this.ctx.beginPath(), this.ctx.arc(Math.cos(u) * p, Math.sin(u) * p, 3, 0, Math.PI * 2), this.ctx.fill();
1660
2600
  }
1661
2601
  this.ctx.restore();
1662
2602
  continue;
1663
2603
  } else if (s.deathType === "sliced") {
1664
- const h = n * 24, c = s.sliceAngle + Math.PI / 2, u = Math.cos(c) * h, p = Math.sin(c) * h;
2604
+ const c = o * 24, h = s.sliceAngle + Math.PI / 2, u = Math.cos(h) * c, p = Math.sin(h) * c;
1665
2605
  this.ctx.shadowColor = "#ff2a5f", this.ctx.shadowBlur = 22, this.ctx.fillStyle = a, this.ctx.save(), this.ctx.translate(u, p), this.ctx.beginPath(), this.ctx.arc(0, 0, s.radius * 0.8, 0, Math.PI), this.ctx.fill(), this.ctx.restore(), this.ctx.save(), this.ctx.translate(-u, -p), this.ctx.beginPath(), this.ctx.arc(0, 0, s.radius * 0.8, Math.PI, Math.PI * 2), this.ctx.fill(), this.ctx.restore(), this.ctx.restore();
1666
2606
  continue;
1667
2607
  }
1668
2608
  }
1669
2609
  if (this.ctx.shadowColor = a, this.ctx.shadowBlur = 16, this.ctx.fillStyle = a, s.type === "piercer") {
1670
2610
  this.ctx.rotate(s.rotation), this.ctx.beginPath();
1671
- const n = 12;
1672
- for (let o = 0; o <= n; o++) {
1673
- const h = o * Math.PI * 2 / n, c = s.radius * 1.6 + Math.sin(h * 3 + e * 4) * 3, u = s.radius * 0.6 + Math.cos(h * 2 + e * 3) * 2, p = Math.cos(h) * c, f = Math.sin(h) * u;
1674
- o === 0 ? this.ctx.moveTo(p, f) : this.ctx.lineTo(p, f);
2611
+ const o = 12;
2612
+ for (let r = 0; r <= o; r++) {
2613
+ const c = r * Math.PI * 2 / o, h = s.radius * 1.6 + Math.sin(c * 3 + e * 4) * 3, u = s.radius * 0.6 + Math.cos(c * 2 + e * 3) * 2, p = Math.cos(c) * h, _ = Math.sin(c) * u;
2614
+ r === 0 ? this.ctx.moveTo(p, _) : this.ctx.lineTo(p, _);
1675
2615
  }
1676
2616
  this.ctx.closePath(), this.ctx.fill(), this.ctx.fillStyle = "#ffffff", this.ctx.beginPath(), this.ctx.arc(4, 0, 4, 0, Math.PI * 2), this.ctx.fill();
1677
2617
  } else if (s.type === "spore") {
1678
2618
  this.ctx.beginPath();
1679
- const n = 8;
1680
- for (let o = 0; o < n; o++) {
1681
- const h = o * Math.PI * 2 / n, c = s.radius + Math.sin(h * 4 + e * 3 + s.position.x) * 4, u = Math.cos(h) * c, p = Math.sin(h) * c;
1682
- o === 0 ? this.ctx.moveTo(u, p) : this.ctx.lineTo(u, p);
2619
+ const o = 8;
2620
+ for (let r = 0; r < o; r++) {
2621
+ const c = r * Math.PI * 2 / o, h = s.radius + Math.sin(c * 4 + e * 3 + s.position.x) * 4, u = Math.cos(c) * h, p = Math.sin(c) * h;
2622
+ r === 0 ? this.ctx.moveTo(u, p) : this.ctx.lineTo(u, p);
1683
2623
  }
1684
2624
  this.ctx.closePath(), this.ctx.fill(), this.ctx.fillStyle = "rgba(255, 255, 255, 0.7)", this.ctx.beginPath(), this.ctx.arc(-4, -4, 5, 0, Math.PI * 2), this.ctx.arc(5, 3, 4, 0, Math.PI * 2), this.ctx.fill();
1685
2625
  } else if (s.type === "cluster") {
1686
2626
  this.ctx.beginPath();
1687
- const n = Math.sin(e * 3) * 2;
1688
- this.ctx.arc(0, 0, s.radius * 0.55, 0, Math.PI * 2), this.ctx.arc(-9 + n, -7, s.radius * 0.42, 0, Math.PI * 2), this.ctx.arc(9 - n, -7, s.radius * 0.42, 0, Math.PI * 2), this.ctx.arc(0, 9 + n, s.radius * 0.45, 0, Math.PI * 2), this.ctx.fill();
2627
+ const o = Math.sin(e * 3) * 2;
2628
+ this.ctx.arc(0, 0, s.radius * 0.55, 0, Math.PI * 2), this.ctx.arc(-9 + o, -7, s.radius * 0.42, 0, Math.PI * 2), this.ctx.arc(9 - o, -7, s.radius * 0.42, 0, Math.PI * 2), this.ctx.arc(0, 9 + o, s.radius * 0.45, 0, Math.PI * 2), this.ctx.fill();
1689
2629
  } else if (s.type === "parasite") {
1690
2630
  this.ctx.beginPath();
1691
- const n = 14;
1692
- for (let o = 0; o <= n; o++) {
1693
- const h = o * Math.PI * 2 / n, c = s.radius + Math.sin(h * 5 - e * 5) * 3, u = Math.cos(h) * c, p = Math.sin(h) * c;
1694
- o === 0 ? this.ctx.moveTo(u, p) : this.ctx.lineTo(u, p);
2631
+ const o = 14;
2632
+ for (let r = 0; r <= o; r++) {
2633
+ const c = r * Math.PI * 2 / o, h = s.radius + Math.sin(c * 5 - e * 5) * 3, u = Math.cos(c) * h, p = Math.sin(c) * h;
2634
+ r === 0 ? this.ctx.moveTo(u, p) : this.ctx.lineTo(u, p);
1695
2635
  }
1696
2636
  this.ctx.closePath(), this.ctx.fill(), this.ctx.fillStyle = i.bgOuter, this.ctx.beginPath(), this.ctx.arc(0, 0, s.radius * 0.45, 0, Math.PI * 2), this.ctx.fill();
2637
+ } else if (s.type === "heavy") {
2638
+ this.ctx.rotate(s.rotation);
2639
+ const o = Math.PI * 0.75, r = s.radius * 1.35, c = s.radius * 0.75;
2640
+ this.ctx.beginPath(), this.ctx.arc(0, 0, r, -o / 2, o / 2, !1);
2641
+ const h = Math.cos(o / 2) * c, u = Math.sin(o / 2) * c;
2642
+ this.ctx.lineTo(h, u), this.ctx.arc(0, 0, c, o / 2, -o / 2, !0), this.ctx.closePath(), this.ctx.fillStyle = s.isStationaryShield ? "#00f5ff" : a, this.ctx.shadowColor = "#00f5ff", this.ctx.shadowBlur = s.isStationaryShield ? 28 : 16, this.ctx.fill(), this.ctx.strokeStyle = "#ffffff", this.ctx.lineWidth = 3, this.ctx.beginPath(), this.ctx.arc(0, 0, r + Math.sin(e * 4) * 2, -o / 2 + 0.1, o / 2 - 0.1), this.ctx.stroke();
2643
+ for (let p = -2; p <= 2; p++) {
2644
+ const _ = p * o / 6, d = Math.cos(_) * (c + 6), g = Math.sin(_) * (c + 6);
2645
+ this.ctx.fillStyle = "#ffffff", this.ctx.beginPath(), this.ctx.arc(d, g, 3, 0, Math.PI * 2), this.ctx.fill();
2646
+ }
1697
2647
  } else
1698
2648
  this.ctx.beginPath(), this.ctx.arc(0, 0, s.radius, 0, Math.PI * 2), this.ctx.fill();
1699
2649
  this.ctx.restore();
@@ -1709,8 +2659,30 @@ class at {
1709
2659
  for (const e of t)
1710
2660
  this.ctx.save(), this.ctx.globalAlpha = e.alpha, this.ctx.fillStyle = e.color, this.ctx.font = `900 ${e.size}px Orbitron, sans-serif`, this.ctx.textAlign = "center", this.ctx.shadowColor = e.color, this.ctx.shadowBlur = 12, this.ctx.fillText(e.text, e.position.x, e.position.y), this.ctx.restore();
1711
2661
  }
2662
+ drawOrbitingModifierOrbs(t, e, i, s = !0) {
2663
+ if (this.ctx) {
2664
+ for (const a of t) {
2665
+ if (!a.active) continue;
2666
+ const { x: l, y: n } = a.position, o = a.definition.color, r = a.definition.rarity, c = r === "legendary" ? "#ff00ff" : r === "epic" ? "#ffd700" : r === "rare" ? "#9d4edd" : "#00f5ff", h = a.radius + Math.sin(e * 6 + a.orbitAngle) * 3;
2667
+ if (this.ctx.save(), this.ctx.shadowColor = c, this.ctx.shadowBlur = a.isGrabbed ? 36 : r === "legendary" ? 28 : 16, r === "legendary" || r === "epic") {
2668
+ const _ = h + 12, d = this.ctx.createRadialGradient(l, n, h, l, n, _);
2669
+ d.addColorStop(0, c), d.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = d, this.ctx.beginPath(), this.ctx.arc(l, n, _, 0, Math.PI * 2), this.ctx.fill();
2670
+ }
2671
+ const u = this.ctx.createRadialGradient(l, n, 2, l, n, h * 1.4);
2672
+ u.addColorStop(0, "#ffffff"), u.addColorStop(0.4, o), u.addColorStop(1, "rgba(0, 0, 0, 0.5)"), this.ctx.fillStyle = u, this.ctx.beginPath(), this.ctx.arc(l, n, h, 0, Math.PI * 2), this.ctx.fill(), this.ctx.strokeStyle = c, this.ctx.lineWidth = r === "legendary" ? 3.5 : 2.5, this.ctx.beginPath(), this.ctx.arc(l, n, h + 4, e * 3, e * 3 + Math.PI * 1.2), this.ctx.stroke(), (r === "legendary" || r === "epic") && (this.ctx.strokeStyle = "#ffffff", this.ctx.lineWidth = 1.5, this.ctx.beginPath(), this.ctx.arc(l, n, h + 8, -e * 2, -e * 2 + Math.PI * 0.9), this.ctx.stroke()), this.ctx.font = "900 14px Orbitron, sans-serif", this.ctx.textAlign = "center", this.ctx.textBaseline = "middle", this.ctx.fillStyle = "#ffffff", this.ctx.shadowColor = "#000000", this.ctx.shadowBlur = 6, this.ctx.fillText(a.definition.badge, l, n);
2673
+ const p = i ? i.translate(a.definition.titleKey) : a.definition.badge;
2674
+ this.ctx.textBaseline = "alphabetic", this.ctx.font = "900 16px Orbitron, sans-serif", this.ctx.fillStyle = "#ffffff", this.ctx.shadowColor = c, this.ctx.shadowBlur = 14, this.ctx.fillText(p, l, n - h - 14), this.ctx.restore();
2675
+ }
2676
+ if (i && s) {
2677
+ const a = this.canvas.width / 2, l = this.canvas.height / 2 + 210, n = i.translate("rerollButton");
2678
+ this.ctx.save(), this.ctx.font = "900 14px Orbitron, sans-serif", this.ctx.textAlign = "center", this.ctx.textBaseline = "middle", this.ctx.fillStyle = "rgba(0, 0, 0, 0.65)", this.ctx.strokeStyle = "#00f0ff", this.ctx.lineWidth = 2, this.ctx.shadowColor = "#00f0ff", this.ctx.shadowBlur = 12;
2679
+ const c = this.ctx.measureText(n).width + 20 * 2, h = 38;
2680
+ this.ctx.beginPath(), this.ctx.roundRect(a - c / 2, l - h / 2, c, h, 8), this.ctx.fill(), this.ctx.stroke(), this.ctx.fillStyle = "#ffffff", this.ctx.shadowColor = "#000000", this.ctx.shadowBlur = 4, this.ctx.fillText(n, a, l), this.ctx.restore();
2681
+ }
2682
+ }
2683
+ }
1712
2684
  }
1713
- class nt {
2685
+ class xt {
1714
2686
  container;
1715
2687
  i18n;
1716
2688
  waveLabelElement;
@@ -1742,7 +2714,7 @@ class nt {
1742
2714
  this.container.style.display = "none";
1743
2715
  }
1744
2716
  }
1745
- class ot {
2717
+ class Et {
1746
2718
  container;
1747
2719
  i18n;
1748
2720
  onStartCallback;
@@ -1768,7 +2740,7 @@ class ot {
1768
2740
  this.container.style.display = "none";
1769
2741
  }
1770
2742
  }
1771
- class rt {
2743
+ class yt {
1772
2744
  modal;
1773
2745
  card;
1774
2746
  i18n;
@@ -1779,8 +2751,8 @@ class rt {
1779
2751
  hapticsEnabled = !0;
1780
2752
  constructor(t, e, i, s, a, l) {
1781
2753
  this.i18n = e, this.themeManager = i, this.platform = s, this.onLanguageChangedCallback = a, this.onCloseCallback = l;
1782
- const r = localStorage.getItem("axon_surge_haptics");
1783
- r !== null && (this.hapticsEnabled = r === "true"), this.modal = document.createElement("dialog"), this.modal.className = "axon-settings-modal", this.card = document.createElement("div"), this.card.className = "axon-settings-card", this.modal.appendChild(this.card), t.appendChild(this.modal), this.modal.addEventListener("close", () => {
2754
+ const n = localStorage.getItem("axon_surge_haptics");
2755
+ n !== null && (this.hapticsEnabled = n === "true"), this.modal = document.createElement("dialog"), this.modal.className = "axon-settings-modal", this.card = document.createElement("div"), this.card.className = "axon-settings-card", this.modal.appendChild(this.card), t.appendChild(this.modal), this.modal.addEventListener("close", () => {
1784
2756
  this.onCloseCallback && this.onCloseCallback();
1785
2757
  }), this.renderContent();
1786
2758
  }
@@ -1813,74 +2785,74 @@ class rt {
1813
2785
  ko: "한국어 (KO)",
1814
2786
  zh: "中文 (ZH)"
1815
2787
  };
1816
- for (const T of H) {
1817
- const g = document.createElement("option");
1818
- g.value = T, g.textContent = l[T], this.i18n.getLanguage() === T && (g.selected = !0), a.appendChild(g);
2788
+ for (const m of Y) {
2789
+ const y = document.createElement("option");
2790
+ y.value = m, y.textContent = l[m], this.i18n.getLanguage() === m && (y.selected = !0), a.appendChild(y);
1819
2791
  }
1820
2792
  a.addEventListener("change", () => {
1821
- const T = a.value;
1822
- this.i18n.setLanguage(T), this.onLanguageChangedCallback && this.onLanguageChangedCallback(T), this.renderContent();
2793
+ const m = a.value;
2794
+ this.i18n.setLanguage(m), this.onLanguageChangedCallback && this.onLanguageChangedCallback(m), this.renderContent();
1823
2795
  });
2796
+ const n = document.createElement("span");
2797
+ n.className = "axon-select-arrow", n.textContent = "▼", s.appendChild(a), s.appendChild(n), e.appendChild(i), e.appendChild(s);
2798
+ const o = document.createElement("div");
2799
+ o.className = "axon-setting-row";
1824
2800
  const r = document.createElement("span");
1825
- r.className = "axon-select-arrow", r.textContent = "▼", s.appendChild(a), s.appendChild(r), e.appendChild(i), e.appendChild(s);
1826
- const n = document.createElement("div");
1827
- n.className = "axon-setting-row";
1828
- const o = document.createElement("span");
1829
- o.textContent = this.i18n.translate("themeLabel");
1830
- const h = document.createElement("div");
1831
- h.className = "axon-toggle-group";
1832
- const c = [
2801
+ r.textContent = this.i18n.translate("themeLabel");
2802
+ const c = document.createElement("div");
2803
+ c.className = "axon-toggle-group";
2804
+ const h = [
1833
2805
  { id: "bioluminescent", label: "BIO" },
1834
2806
  { id: "dark", label: "DARK" },
1835
2807
  { id: "light", label: "LIGHT" }
1836
2808
  ];
1837
- for (const T of c) {
1838
- const g = document.createElement("button");
1839
- g.type = "button", g.className = `axon-toggle-btn ${this.themeManager.getTheme() === T.id ? "active" : ""}`, g.textContent = T.label, g.addEventListener("click", () => {
1840
- this.themeManager.setTheme(T.id), this.renderContent();
1841
- }), h.appendChild(g);
2809
+ for (const m of h) {
2810
+ const y = document.createElement("button");
2811
+ y.type = "button", y.className = `axon-toggle-btn ${this.themeManager.getTheme() === m.id ? "active" : ""}`, y.textContent = m.label, y.addEventListener("click", () => {
2812
+ this.themeManager.setTheme(m.id), this.renderContent();
2813
+ }), c.appendChild(y);
1842
2814
  }
1843
- n.appendChild(o), n.appendChild(h);
2815
+ o.appendChild(r), o.appendChild(c);
1844
2816
  const u = document.createElement("div");
1845
2817
  u.className = "axon-setting-row";
1846
2818
  const p = document.createElement("span");
1847
2819
  p.textContent = this.i18n.translate("hapticsLabel");
1848
- const f = document.createElement("div");
1849
- f.className = "axon-toggle-group";
1850
- const y = [
2820
+ const _ = document.createElement("div");
2821
+ _.className = "axon-toggle-group";
2822
+ const d = [
1851
2823
  { enabled: !0, label: this.i18n.translate("hapticsOn") },
1852
2824
  { enabled: !1, label: this.i18n.translate("hapticsOff") }
1853
2825
  ];
1854
- for (const T of y) {
1855
- const g = document.createElement("button");
1856
- g.type = "button", g.className = `axon-toggle-btn ${this.hapticsEnabled === T.enabled ? "active" : ""}`, g.textContent = T.label, g.addEventListener("click", () => {
1857
- this.hapticsEnabled = T.enabled, localStorage.setItem("axon_surge_haptics", String(T.enabled)), this.hapticsEnabled && this.platform.haptics.selectionChanged(), this.renderContent();
1858
- }), f.appendChild(g);
1859
- }
1860
- u.appendChild(p), u.appendChild(f);
1861
- const d = document.createElement("div");
1862
- d.className = "axon-setting-row";
1863
- const m = document.createElement("span");
1864
- m.textContent = this.i18n.translate("tutorialSettingLabel");
2826
+ for (const m of d) {
2827
+ const y = document.createElement("button");
2828
+ y.type = "button", y.className = `axon-toggle-btn ${this.hapticsEnabled === m.enabled ? "active" : ""}`, y.textContent = m.label, y.addEventListener("click", () => {
2829
+ this.hapticsEnabled = m.enabled, localStorage.setItem("axon_surge_haptics", String(m.enabled)), this.hapticsEnabled && this.platform.haptics.selectionChanged(), this.renderContent();
2830
+ }), _.appendChild(y);
2831
+ }
2832
+ u.appendChild(p), u.appendChild(_);
2833
+ const g = document.createElement("div");
2834
+ g.className = "axon-setting-row";
2835
+ const f = document.createElement("span");
2836
+ f.textContent = this.i18n.translate("tutorialSettingLabel");
1865
2837
  const x = document.createElement("div");
1866
2838
  x.className = "axon-toggle-group";
1867
- const L = localStorage.getItem("axon_surge_show_tutorial") !== "false", A = [
2839
+ const b = localStorage.getItem("axon_surge_show_tutorial") !== "false", v = [
1868
2840
  { enabled: !0, label: this.i18n.translate("hapticsOn") },
1869
2841
  { enabled: !1, label: this.i18n.translate("hapticsOff") }
1870
2842
  ];
1871
- for (const T of A) {
1872
- const g = document.createElement("button");
1873
- g.type = "button", g.className = `axon-toggle-btn ${L === T.enabled ? "active" : ""}`, g.textContent = T.label, g.addEventListener("click", () => {
1874
- localStorage.setItem("axon_surge_show_tutorial", String(T.enabled)), this.renderContent();
1875
- }), x.appendChild(g);
1876
- }
1877
- d.appendChild(m), d.appendChild(x);
1878
- const b = document.createElement("div");
1879
- b.className = "axon-settings-credits", b.textContent = this.i18n.translate("creditsJam");
1880
- const M = document.createElement("button");
1881
- M.type = "button", M.className = "axon-start-button", M.style.padding = "12px 36px", M.style.fontSize = "14px", M.textContent = this.i18n.translate("closeButton"), M.addEventListener("click", () => {
2843
+ for (const m of v) {
2844
+ const y = document.createElement("button");
2845
+ y.type = "button", y.className = `axon-toggle-btn ${b === m.enabled ? "active" : ""}`, y.textContent = m.label, y.addEventListener("click", () => {
2846
+ localStorage.setItem("axon_surge_show_tutorial", String(m.enabled)), this.renderContent();
2847
+ }), x.appendChild(y);
2848
+ }
2849
+ g.appendChild(f), g.appendChild(x);
2850
+ const I = document.createElement("div");
2851
+ I.className = "axon-settings-credits", I.textContent = this.i18n.translate("creditsJam");
2852
+ const S = document.createElement("button");
2853
+ S.type = "button", S.className = "axon-start-button", S.style.padding = "12px 36px", S.style.fontSize = "14px", S.textContent = this.i18n.translate("closeButton"), S.addEventListener("click", () => {
1882
2854
  this.modal.close();
1883
- }), this.card.appendChild(t), this.card.appendChild(e), this.card.appendChild(n), this.card.appendChild(u), this.card.appendChild(d), this.card.appendChild(b), this.card.appendChild(M);
2855
+ }), this.card.appendChild(t), this.card.appendChild(e), this.card.appendChild(o), this.card.appendChild(u), this.card.appendChild(g), this.card.appendChild(I), this.card.appendChild(S);
1884
2856
  }
1885
2857
  isHapticsEnabled() {
1886
2858
  return this.hapticsEnabled;
@@ -1892,8 +2864,8 @@ class rt {
1892
2864
  this.modal.close();
1893
2865
  }
1894
2866
  }
1895
- const B = "axon_surge_show_tutorial";
1896
- class ht {
2867
+ const W = "axon_surge_show_tutorial";
2868
+ class At {
1897
2869
  isActive = !1;
1898
2870
  showWarning = !1;
1899
2871
  dummyLauncher = null;
@@ -1902,14 +2874,14 @@ class ht {
1902
2874
  initialTargetPos = { x: 0, y: 0 };
1903
2875
  isTutorialEnabled() {
1904
2876
  try {
1905
- return localStorage.getItem(B) !== "false";
2877
+ return localStorage.getItem(W) !== "false";
1906
2878
  } catch {
1907
2879
  return !0;
1908
2880
  }
1909
2881
  }
1910
2882
  setTutorialEnabled(t) {
1911
2883
  try {
1912
- localStorage.setItem(B, String(t));
2884
+ localStorage.setItem(W, String(t));
1913
2885
  } catch {
1914
2886
  }
1915
2887
  }
@@ -1927,11 +2899,11 @@ class ht {
1927
2899
  this.isActive = !1;
1928
2900
  return;
1929
2901
  }
1930
- this.isActive = !0, this.showWarning = !1, i.length = 0, this.initialLauncherPos = { x: t * 0.28, y: e * 0.28 }, this.initialTargetPos = { x: t * 0.72, y: e * 0.28 }, this.dummyLauncher = S.createEnemy(
2902
+ this.isActive = !0, this.showWarning = !1, i.length = 0, this.initialLauncherPos = { x: t * 0.28, y: e * 0.28 }, this.initialTargetPos = { x: t * 0.72, y: e * 0.28 }, this.dummyLauncher = T.createEnemy(
1931
2903
  "piercer",
1932
2904
  this.initialLauncherPos,
1933
2905
  this.initialTargetPos
1934
- ), this.dummyLauncher.velocity = { x: 0, y: 0 }, this.dummyTarget = S.createEnemy(
2906
+ ), this.dummyLauncher.velocity = { x: 0, y: 0 }, this.dummyTarget = T.createEnemy(
1935
2907
  "spore",
1936
2908
  this.initialTargetPos,
1937
2909
  this.initialLauncherPos
@@ -1939,27 +2911,27 @@ class ht {
1939
2911
  }
1940
2912
  update(t, e, i, s, a, l) {
1941
2913
  if (!this.isActive || !this.dummyLauncher || !this.dummyTarget) return;
1942
- const r = this.dummyLauncher, n = this.dummyTarget;
1943
- e.includes(r) || e.push(r), e.includes(n) || e.push(n);
1944
- const o = n.position.x - r.position.x, h = n.position.y - r.position.y, c = Math.hypot(o, h);
1945
- if (r.isGrabbed) {
1946
- if (this.showWarning = !1, c <= r.radius + n.radius + 60) {
1947
- l && l(), r.isGrabbed = !1, this.showWarning = !0, this.resetDummies(r, n);
2914
+ const n = this.dummyLauncher, o = this.dummyTarget;
2915
+ e.includes(n) || e.push(n), e.includes(o) || e.push(o);
2916
+ const r = o.position.x - n.position.x, c = o.position.y - n.position.y, h = Math.hypot(r, c);
2917
+ if (n.isGrabbed) {
2918
+ if (this.showWarning = !1, h <= n.radius + o.radius + 60) {
2919
+ l && l(), n.isGrabbed = !1, this.showWarning = !0, this.resetDummies(n, o);
1948
2920
  return;
1949
2921
  }
1950
2922
  return;
1951
2923
  }
1952
- if (r.wasManipulated) {
1953
- const u = Math.hypot(r.velocity.x, r.velocity.y);
1954
- if (!r.isThrown || u < 70) {
1955
- l && l(), this.showWarning = !0, this.resetDummies(r, n);
2924
+ if (n.wasManipulated) {
2925
+ const u = Math.hypot(n.velocity.x, n.velocity.y);
2926
+ if (!n.isThrown || u < 70) {
2927
+ l && l(), this.showWarning = !0, this.resetDummies(n, o);
1956
2928
  return;
1957
2929
  }
1958
- if (c <= r.getHitRadius() + n.getHitRadius()) {
1959
- r.triggerDissolveDeath(), n.triggerDissolveDeath(), this.showWarning = !1, this.isActive = !1, a();
2930
+ if (h <= n.getHitRadius() + o.getHitRadius()) {
2931
+ n.triggerDissolveDeath(), o.triggerDissolveDeath(), this.showWarning = !1, this.isActive = !1, a();
1960
2932
  return;
1961
2933
  }
1962
- (r.position.x < -60 || r.position.x > i + 60 || r.position.y < -60 || r.position.y > s + 60 || u < 40) && (l && l(), this.showWarning = !0, this.resetDummies(r, n));
2934
+ (n.position.x < -60 || n.position.x > i + 60 || n.position.y < -60 || n.position.y > s + 60 || u < 40) && (l && l(), this.showWarning = !0, this.resetDummies(n, o));
1963
2935
  }
1964
2936
  }
1965
2937
  resetDummies(t, e) {
@@ -1969,7 +2941,7 @@ class ht {
1969
2941
  this.isActive = !1, this.showWarning = !1;
1970
2942
  }
1971
2943
  }
1972
- class lt {
2944
+ class bt {
1973
2945
  container;
1974
2946
  i18n;
1975
2947
  tutorialManager;
@@ -2005,7 +2977,7 @@ class lt {
2005
2977
  this.container.style.display = "none";
2006
2978
  }
2007
2979
  }
2008
- class ct {
2980
+ class vt {
2009
2981
  fillElement;
2010
2982
  killsCount = 0;
2011
2983
  currentLevel = 1;
@@ -2016,7 +2988,7 @@ class ct {
2016
2988
  i.className = "axon-hud-level-track", this.fillElement = document.createElement("div"), this.fillElement.className = "axon-hud-level-fill", i.appendChild(this.fillElement), t.appendChild(i);
2017
2989
  }
2018
2990
  getKillsRequiredForLevel(t) {
2019
- return 16 + (t - 1) * 6;
2991
+ return t === 1 ? 3 : t === 2 ? 6 : t === 3 ? 10 : 10 + (t - 3) * 6;
2020
2992
  }
2021
2993
  addKill() {
2022
2994
  this.killsCount++;
@@ -2036,7 +3008,313 @@ class ct {
2036
3008
  this.fillElement && this.fillElement.parentElement && (this.fillElement.parentElement.style.display = "none");
2037
3009
  }
2038
3010
  }
2039
- class dt {
3011
+ class F {
3012
+ static powerUps = [
3013
+ {
3014
+ id: "spore_radius",
3015
+ titleKey: "pu_spore_radius_title",
3016
+ descKey: "pu_spore_radius_desc",
3017
+ badge: "+30% RAD",
3018
+ category: "radius",
3019
+ rarity: "common",
3020
+ rarityWeight: 35,
3021
+ color: "#39ff14",
3022
+ apply: () => {
3023
+ const t = A.getInstance(), e = t.getConfig().toxicPool;
3024
+ t.updateConfig({
3025
+ toxicPool: {
3026
+ ...e,
3027
+ baseRadius: Math.round(e.baseRadius * 1.3),
3028
+ synergyRadius: Math.round(e.synergyRadius * 1.3)
3029
+ }
3030
+ });
3031
+ }
3032
+ },
3033
+ {
3034
+ id: "spore_duration",
3035
+ titleKey: "pu_spore_duration_title",
3036
+ descKey: "pu_spore_duration_desc",
3037
+ badge: "+3.0s DUR",
3038
+ category: "duration",
3039
+ rarity: "common",
3040
+ rarityWeight: 35,
3041
+ color: "#39ff14",
3042
+ apply: () => {
3043
+ const t = A.getInstance(), e = t.getConfig().toxicPool;
3044
+ t.updateConfig({
3045
+ toxicPool: {
3046
+ ...e,
3047
+ baseDuration: Number((e.baseDuration + 3).toFixed(1)),
3048
+ synergyDuration: Number((e.synergyDuration + 4).toFixed(1))
3049
+ }
3050
+ });
3051
+ }
3052
+ },
3053
+ {
3054
+ id: "vortex_radius",
3055
+ titleKey: "pu_vortex_radius_title",
3056
+ descKey: "pu_vortex_radius_desc",
3057
+ badge: "+25% RAD",
3058
+ category: "radius",
3059
+ rarity: "common",
3060
+ rarityWeight: 35,
3061
+ color: "#9d4edd",
3062
+ apply: () => {
3063
+ const t = A.getInstance(), e = t.getConfig().gravityVortex;
3064
+ t.updateConfig({
3065
+ gravityVortex: {
3066
+ ...e,
3067
+ baseRadius: Math.round(e.baseRadius * 1.25),
3068
+ synergyRadius: Math.round(e.synergyRadius * 1.25)
3069
+ }
3070
+ });
3071
+ }
3072
+ },
3073
+ {
3074
+ id: "vortex_duration",
3075
+ titleKey: "pu_vortex_duration_title",
3076
+ descKey: "pu_vortex_duration_desc",
3077
+ badge: "+2.5s DUR",
3078
+ category: "duration",
3079
+ rarity: "common",
3080
+ rarityWeight: 35,
3081
+ color: "#9d4edd",
3082
+ apply: () => {
3083
+ const t = A.getInstance(), e = t.getConfig().gravityVortex;
3084
+ t.updateConfig({
3085
+ gravityVortex: {
3086
+ ...e,
3087
+ baseDuration: Number((e.baseDuration + 2.5).toFixed(1)),
3088
+ synergyDuration: Number((e.synergyDuration + 3.5).toFixed(1))
3089
+ }
3090
+ });
3091
+ }
3092
+ },
3093
+ {
3094
+ id: "vortex_power",
3095
+ titleKey: "pu_vortex_power_title",
3096
+ descKey: "pu_vortex_power_desc",
3097
+ badge: "+40% PULL",
3098
+ category: "power",
3099
+ rarity: "rare",
3100
+ rarityWeight: 25,
3101
+ color: "#9d4edd",
3102
+ apply: () => {
3103
+ const t = A.getInstance(), e = t.getConfig().gravityVortex;
3104
+ t.updateConfig({
3105
+ gravityVortex: {
3106
+ ...e,
3107
+ basePullForce: Math.round(e.basePullForce * 1.4),
3108
+ synergyPullForce: Math.round(e.synergyPullForce * 1.4)
3109
+ }
3110
+ });
3111
+ }
3112
+ },
3113
+ {
3114
+ id: "vortex_pocket",
3115
+ titleKey: "pu_vortex_pocket_title",
3116
+ descKey: "pu_vortex_pocket_desc",
3117
+ badge: "IMPLODE LAUNCH",
3118
+ category: "power",
3119
+ rarity: "legendary",
3120
+ rarityWeight: 5,
3121
+ color: "#9d4edd",
3122
+ apply: () => {
3123
+ const t = A.getInstance(), e = t.getConfig().gravityVortex;
3124
+ t.updateConfig({
3125
+ gravityVortex: {
3126
+ ...e,
3127
+ hasImplosionLaunch: !0
3128
+ }
3129
+ });
3130
+ }
3131
+ },
3132
+ {
3133
+ id: "shield_fan",
3134
+ titleKey: "pu_shield_fan_title",
3135
+ descKey: "pu_shield_fan_desc",
3136
+ badge: "FAN BLAST",
3137
+ category: "power",
3138
+ rarity: "legendary",
3139
+ rarityWeight: 5,
3140
+ color: "#00f5ff",
3141
+ apply: () => {
3142
+ const t = A.getInstance(), e = t.getConfig().shield;
3143
+ t.updateConfig({
3144
+ shield: {
3145
+ ...e,
3146
+ isFanBlast: !0
3147
+ }
3148
+ });
3149
+ }
3150
+ },
3151
+ {
3152
+ id: "cluster_extra",
3153
+ titleKey: "pu_cluster_extra_title",
3154
+ descKey: "pu_cluster_extra_desc",
3155
+ badge: "+2 FRAGS",
3156
+ category: "power",
3157
+ rarity: "rare",
3158
+ rarityWeight: 25,
3159
+ color: "#ffcc00",
3160
+ apply: () => {
3161
+ const t = A.getInstance(), e = t.getConfig().cluster;
3162
+ t.updateConfig({
3163
+ cluster: {
3164
+ ...e,
3165
+ fragmentCount: e.fragmentCount + 2
3166
+ }
3167
+ });
3168
+ }
3169
+ },
3170
+ {
3171
+ id: "cluster_homing",
3172
+ titleKey: "pu_cluster_homing_title",
3173
+ descKey: "pu_cluster_homing_desc",
3174
+ badge: "SEEKER FRAGS",
3175
+ category: "power",
3176
+ rarity: "legendary",
3177
+ rarityWeight: 5,
3178
+ color: "#ffcc00",
3179
+ apply: () => {
3180
+ const t = A.getInstance(), e = t.getConfig().cluster;
3181
+ t.updateConfig({
3182
+ cluster: {
3183
+ ...e,
3184
+ hasHoming: !0
3185
+ }
3186
+ });
3187
+ }
3188
+ },
3189
+ {
3190
+ id: "piercer_aoe",
3191
+ titleKey: "pu_piercer_aoe_title",
3192
+ descKey: "pu_piercer_aoe_desc",
3193
+ badge: "AOE BURST",
3194
+ category: "power",
3195
+ rarity: "epic",
3196
+ rarityWeight: 15,
3197
+ color: "#ff3366",
3198
+ apply: () => {
3199
+ const t = A.getInstance(), e = t.getConfig().piercer;
3200
+ t.updateConfig({
3201
+ piercer: {
3202
+ ...e,
3203
+ terminalAoERadius: (e.terminalAoERadius || 0) + 160
3204
+ }
3205
+ });
3206
+ }
3207
+ },
3208
+ {
3209
+ id: "piercer_homing",
3210
+ titleKey: "pu_piercer_homing_title",
3211
+ descKey: "pu_piercer_homing_desc",
3212
+ badge: "SEEKER",
3213
+ category: "power",
3214
+ rarity: "legendary",
3215
+ rarityWeight: 5,
3216
+ color: "#ff2a5f",
3217
+ apply: () => {
3218
+ const t = A.getInstance(), e = t.getConfig().piercer;
3219
+ t.updateConfig({
3220
+ piercer: {
3221
+ ...e,
3222
+ hasHoming: !0
3223
+ }
3224
+ });
3225
+ }
3226
+ },
3227
+ {
3228
+ id: "piercer_homing_target",
3229
+ titleKey: "pu_piercer_homing_target_title",
3230
+ descKey: "pu_piercer_homing_target_desc",
3231
+ badge: "+1 TARGET",
3232
+ category: "power",
3233
+ rarity: "epic",
3234
+ rarityWeight: 15,
3235
+ color: "#ff2a5f",
3236
+ apply: () => {
3237
+ const t = A.getInstance(), e = t.getConfig().piercer;
3238
+ t.updateConfig({
3239
+ piercer: {
3240
+ ...e,
3241
+ homingTargets: e.homingTargets + 1
3242
+ }
3243
+ });
3244
+ }
3245
+ },
3246
+ {
3247
+ id: "vampirism_unlock",
3248
+ titleKey: "pu_vampirism_unlock_title",
3249
+ descKey: "pu_vampirism_unlock_desc",
3250
+ badge: "+0.5% REPAIR",
3251
+ category: "defense",
3252
+ rarity: "epic",
3253
+ rarityWeight: 15,
3254
+ color: "#00f5ff",
3255
+ apply: () => {
3256
+ const t = A.getInstance(), e = t.getConfig().core;
3257
+ t.updateConfig({
3258
+ core: {
3259
+ ...e,
3260
+ vampirismHealProgressRate: 5e-3
3261
+ }
3262
+ });
3263
+ }
3264
+ },
3265
+ {
3266
+ id: "vampirism_boost",
3267
+ titleKey: "pu_vampirism_boost_title",
3268
+ descKey: "pu_vampirism_boost_desc",
3269
+ badge: "+0.3% HEAL",
3270
+ category: "defense",
3271
+ rarity: "rare",
3272
+ rarityWeight: 25,
3273
+ color: "#00f5ff",
3274
+ apply: () => {
3275
+ const t = A.getInstance(), e = t.getConfig().core;
3276
+ t.updateConfig({
3277
+ core: {
3278
+ ...e,
3279
+ vampirismHealProgressRate: e.vampirismHealProgressRate + 3e-3
3280
+ }
3281
+ });
3282
+ }
3283
+ },
3284
+ {
3285
+ id: "core_ring",
3286
+ titleKey: "pu_core_ring_title",
3287
+ descKey: "pu_core_ring_desc",
3288
+ badge: "+1 RING",
3289
+ category: "defense",
3290
+ rarity: "rare",
3291
+ rarityWeight: 20,
3292
+ color: "#00f5ff",
3293
+ apply: (t) => {
3294
+ A.getInstance().addCoreRing(1), t && t.addMaxRing(1);
3295
+ }
3296
+ }
3297
+ ];
3298
+ static getRandomOptions(t = 3) {
3299
+ const e = A.getInstance().getConfig(), i = this.powerUps.filter((a) => !(a.id === "vampirism_unlock" && e.core.vampirismHealProgressRate > 0 || a.id === "vampirism_boost" && e.core.vampirismHealProgressRate <= 0 || a.id === "piercer_homing" && e.piercer.hasHoming || a.id === "piercer_homing_target" && !e.piercer.hasHoming || a.id === "vortex_pocket" && e.gravityVortex.hasImplosionLaunch || a.id === "shield_fan" && e.shield.isFanBlast || a.id === "cluster_homing" && e.cluster.hasHoming)), s = [];
3300
+ for (let a = 0; a < t && i.length > 0; a++) {
3301
+ const l = i.reduce((o, r) => o + r.rarityWeight, 0);
3302
+ let n = Math.random() * l;
3303
+ for (let o = 0; o < i.length; o++) {
3304
+ const r = i[o];
3305
+ if (n -= r.rarityWeight, n <= 0) {
3306
+ s.push(r), i.splice(o, 1);
3307
+ break;
3308
+ }
3309
+ }
3310
+ }
3311
+ return s;
3312
+ }
3313
+ static registerPowerUp(t) {
3314
+ this.powerUps.push(t);
3315
+ }
3316
+ }
3317
+ class St {
2040
3318
  haptics = {
2041
3319
  impact: async (t) => {
2042
3320
  if ("vibrate" in navigator) {
@@ -2076,7 +3354,7 @@ class dt {
2076
3354
  }
2077
3355
  };
2078
3356
  }
2079
- class ut {
3357
+ class It {
2080
3358
  container;
2081
3359
  canvas;
2082
3360
  i18n;
@@ -2103,12 +3381,15 @@ class ut {
2103
3381
  shockwaves = [];
2104
3382
  particles = [];
2105
3383
  floatingTexts = [];
3384
+ orbitingOrbs = [];
3385
+ isLevelUpActive = !1;
3386
+ hasRerolledThisLevel = !1;
2106
3387
  score = { value: 0 };
2107
3388
  combo = { value: 0 };
2108
3389
  isRunning = !1;
2109
3390
  isPaused = !1;
2110
3391
  constructor(t) {
2111
- this.container = t.root, this.container.classList.add("axon-game-root"), this.i18n = new Z(t.language), this.themeManager = new tt(t.theme, this.container), this.platform = t.platform || new dt(), this.canvas = document.createElement("canvas"), this.canvas.className = "axon-canvas", this.container.appendChild(this.canvas), this.resizeCanvas(), window.addEventListener("resize", () => this.resizeCanvas()), this.eventBus = new K(), this.core = new V(this.canvas.width / 2, this.canvas.height / 2), this.inputManager = new F(this.canvas), this.physicsEngine = new q(this.eventBus, this.i18n), this.waveDirector = new Q(), this.renderer = new at(this.canvas, this.themeManager), this.juice = new J(), this.settingsModal = new rt(
3392
+ this.container = t.root, this.container.classList.add("axon-game-root"), this.i18n = new Q(t.language), this.themeManager = new dt(t.theme, this.container), this.platform = t.platform || new St(), this.canvas = document.createElement("canvas"), this.canvas.className = "axon-canvas", this.container.appendChild(this.canvas), this.resizeCanvas(), window.addEventListener("resize", () => this.resizeCanvas()), this.eventBus = new J(), this.core = new z(this.canvas.width / 2, this.canvas.height / 2), this.inputManager = new $(this.canvas), this.physicsEngine = new ht(this.eventBus, this.i18n), this.waveDirector = new pt(), this.renderer = new ft(this.canvas, this.themeManager), this.juice = new q(), this.settingsModal = new yt(
2112
3393
  this.container,
2113
3394
  this.i18n,
2114
3395
  this.themeManager,
@@ -2117,20 +3398,20 @@ class ut {
2117
3398
  () => {
2118
3399
  this.isPaused = !1;
2119
3400
  }
2120
- ), this.interactiveTutorial = new ht(), this.tutorialOverlay = new lt(this.container, this.i18n, this.interactiveTutorial), this.hud = new nt(this.container, this.i18n, () => {
3401
+ ), this.interactiveTutorial = new At(), this.tutorialOverlay = new bt(this.container, this.i18n, this.interactiveTutorial), this.hud = new xt(this.container, this.i18n, () => {
2121
3402
  this.isPaused = !0, this.settingsModal.show();
2122
- }), this.hud.show(), this.progressBar = new ct(this.hud.progressSlot, (e) => {
2123
- this.waveDirector.wave = e;
2124
- }), this.startMenu = new ot(this.container, this.i18n, () => this.startGame()), this.initAmbientArena(), this.gameLoop = new W(
3403
+ }), this.hud.show(), this.progressBar = new vt(this.hud.progressSlot, (e) => {
3404
+ this.waveDirector.wave = e, this.triggerLevelUp(e);
3405
+ }), this.startMenu = new Et(this.container, this.i18n, () => this.startGame()), this.initAmbientArena(), this.gameLoop = new X(
2125
3406
  (e) => this.update(e),
2126
3407
  () => this.render()
2127
3408
  ), this.setupEvents(), this.gameLoop.start();
2128
3409
  }
2129
3410
  setLanguage(t) {
2130
- this.i18n.setLanguage(t, !1), this.onLanguageChanged(t);
3411
+ this.i18n.setLanguage(t), this.onLanguageChanged(t);
2131
3412
  }
2132
3413
  setTheme(t) {
2133
- this.themeManager.setTheme(t, !1);
3414
+ this.themeManager.setTheme(t);
2134
3415
  }
2135
3416
  getLanguage() {
2136
3417
  return this.i18n.getLanguage();
@@ -2148,11 +3429,11 @@ class ut {
2148
3429
  const i = t[e % t.length], s = e * Math.PI * 2 / 16, a = 180 + Math.random() * 220, l = {
2149
3430
  x: this.canvas.width / 2 + Math.cos(s) * a,
2150
3431
  y: this.canvas.height / 2 + Math.sin(s) * a
2151
- }, r = S.createEnemy(i, l, {
3432
+ }, n = T.createEnemy(i, l, {
2152
3433
  x: l.x + Math.sin(s) * 100,
2153
3434
  y: l.y - Math.cos(s) * 100
2154
3435
  });
2155
- this.ambientEnemies.push(r);
3436
+ this.ambientEnemies.push(n);
2156
3437
  }
2157
3438
  }
2158
3439
  resizeCanvas() {
@@ -2198,7 +3479,7 @@ class ut {
2198
3479
  },
2199
3480
  () => this.inputManager.forceRelease()
2200
3481
  ), this.tutorialOverlay.updateStep(this.interactiveTutorial.getStep());
2201
- else {
3482
+ else if (!this.isLevelUpActive) {
2202
3483
  const e = this.waveDirector.update(
2203
3484
  t,
2204
3485
  this.enemies,
@@ -2208,6 +3489,53 @@ class ut {
2208
3489
  );
2209
3490
  e && this.enemies.push(e);
2210
3491
  }
3492
+ if (this.isLevelUpActive) {
3493
+ this.inputManager.tryGrabOrb(this.orbitingOrbs);
3494
+ const e = this.inputManager.grabbedOrb;
3495
+ !this.inputManager.isPointerDown && e && (e.isGrabbed = !1, this.inputManager.grabbedOrb = null);
3496
+ const i = this.inputManager.pointerPosition;
3497
+ if (this.inputManager.isPointerDown && !this.inputManager.grabbedOrb && !this.hasRerolledThisLevel) {
3498
+ const s = this.canvas.width / 2, a = this.canvas.height / 2 + 210;
3499
+ Math.hypot(i.x - s, i.y - a) <= 80 && (this.triggerReroll(), this.inputManager.isPointerDown = !1);
3500
+ }
3501
+ for (const s of this.orbitingOrbs) {
3502
+ const a = i.x - s.position.x, l = i.y - s.position.y;
3503
+ if (s.isHovered = Math.hypot(a, l) <= s.radius * 1.5, s === e && this.inputManager.isPointerDown) {
3504
+ s.position = { ...this.inputManager.pointerPosition };
3505
+ const n = this.core.position.x - s.position.x, o = this.core.position.y - s.position.y;
3506
+ if (Math.hypot(n, o) <= this.core.radius + s.radius) {
3507
+ s.definition.apply(this.core), this.core.absorbPowerUpColor(s.definition.color, 0.4), this.juice.triggerFlash(0.8), this.juice.triggerScreenShake({ x: n, y: o }, 24);
3508
+ const c = this.i18n.translate(s.definition.titleKey);
3509
+ this.floatingTexts.push({
3510
+ id: Math.random().toString(),
3511
+ text: `+ ${c}`,
3512
+ position: { ...this.core.position },
3513
+ velocity: { x: 0, y: -80 },
3514
+ color: s.definition.color,
3515
+ alpha: 1,
3516
+ lifetime: 0,
3517
+ maxLifetime: 1.6,
3518
+ size: 26
3519
+ });
3520
+ for (let h = 0; h < 45; h++) {
3521
+ const u = Math.random() * Math.PI * 2, p = 200 + Math.random() * 400;
3522
+ this.particles.push({
3523
+ id: Math.random().toString(),
3524
+ position: { ...this.core.position },
3525
+ velocity: { x: Math.cos(u) * p, y: Math.sin(u) * p },
3526
+ color: s.definition.color,
3527
+ radius: 4 + Math.random() * 5,
3528
+ alpha: 1,
3529
+ lifetime: 0,
3530
+ maxLifetime: 0.7
3531
+ });
3532
+ }
3533
+ this.inputManager.forceRelease(), this.orbitingOrbs = [], this.isLevelUpActive = !1;
3534
+ }
3535
+ } else
3536
+ s.update(t, this.core.position);
3537
+ }
3538
+ }
2211
3539
  this.juice.hitstopTime <= 0 && this.physicsEngine.update(
2212
3540
  t,
2213
3541
  this.core,
@@ -2222,9 +3550,75 @@ class ut {
2222
3550
  this.score,
2223
3551
  this.canvas.width,
2224
3552
  this.canvas.height,
2225
- () => this.progressBar.addKill()
3553
+ () => {
3554
+ this.progressBar.addKill(), this.core.addKillRepair() && (this.juice.triggerFlash(0.4), this.floatingTexts.push({
3555
+ id: Math.random().toString(),
3556
+ text: "RING RESTORED!",
3557
+ position: { ...this.core.position },
3558
+ velocity: { x: 0, y: -60 },
3559
+ color: "#00f5ff",
3560
+ alpha: 1,
3561
+ lifetime: 0,
3562
+ maxLifetime: 1.2,
3563
+ size: 22
3564
+ }));
3565
+ }
2226
3566
  ), this.hud.update(this.progressBar.getLevel(), this.combo.value), this.juice.update(t, this.floatingTexts, this.particles), this.enemies = this.enemies.filter((e) => e.active);
2227
3567
  }
3568
+ triggerLevelUp(t) {
3569
+ this.isLevelUpActive = !0;
3570
+ for (const i of this.enemies)
3571
+ if (i.active) {
3572
+ i.triggerDissolveDeath();
3573
+ for (let s = 0; s < 6; s++) {
3574
+ const a = Math.random() * Math.PI * 2, l = 100 + Math.random() * 200;
3575
+ this.particles.push({
3576
+ id: Math.random().toString(),
3577
+ position: { ...i.position },
3578
+ velocity: { x: Math.cos(a) * l, y: Math.sin(a) * l },
3579
+ color: "#00f0ff",
3580
+ radius: 3 + Math.random() * 3,
3581
+ alpha: 1,
3582
+ lifetime: 0,
3583
+ maxLifetime: 0.5
3584
+ });
3585
+ }
3586
+ }
3587
+ this.shockwaves.push({
3588
+ id: Math.random().toString(),
3589
+ position: { ...this.core.position },
3590
+ radius: 20,
3591
+ maxRadius: Math.max(this.canvas.width, this.canvas.height) * 1.4,
3592
+ color: "#00f0ff",
3593
+ alpha: 1,
3594
+ lifetime: 0,
3595
+ maxLifetime: 0.8
3596
+ }), this.juice.triggerFlash(0.6), this.juice.triggerScreenShake({ x: 0, y: 1 }, 20), this.floatingTexts.push({
3597
+ id: Math.random().toString(),
3598
+ text: this.i18n.translate("levelUpChoose", { level: t }),
3599
+ position: { ...this.core.position },
3600
+ velocity: { x: 0, y: -100 },
3601
+ color: "#00f0ff",
3602
+ alpha: 1,
3603
+ lifetime: 0,
3604
+ maxLifetime: 2,
3605
+ size: 30
3606
+ });
3607
+ const e = F.getRandomOptions(3);
3608
+ this.orbitingOrbs = e.map((i, s) => {
3609
+ const a = s * Math.PI * 2 / e.length;
3610
+ return new K(`orb_${Date.now()}_${s}`, i, a);
3611
+ }), this.hasRerolledThisLevel = !1;
3612
+ }
3613
+ triggerReroll() {
3614
+ if (this.hasRerolledThisLevel) return;
3615
+ this.hasRerolledThisLevel = !0, this.juice.triggerFlash(0.4);
3616
+ const t = F.getRandomOptions(3);
3617
+ this.orbitingOrbs = t.map((e, i) => {
3618
+ const s = i * Math.PI * 2 / t.length;
3619
+ return new K(`orb_${Date.now()}_${i}`, e, s);
3620
+ });
3621
+ }
2228
3622
  render() {
2229
3623
  const t = this.isRunning ? this.enemies : this.ambientEnemies;
2230
3624
  this.renderer.render(
@@ -2240,20 +3634,20 @@ class ut {
2240
3634
  this.inputManager.pointerPosition,
2241
3635
  this.progressBar.getLevel(),
2242
3636
  this.interactiveTutorial.isActive ? this.interactiveTutorial : void 0
2243
- );
3637
+ ), this.isLevelUpActive && this.orbitingOrbs.length > 0 && this.renderer.drawOrbitingModifierOrbs(this.orbitingOrbs, this.core.pulsePhase, this.i18n, !this.hasRerolledThisLevel);
2244
3638
  }
2245
3639
  destroy() {
2246
3640
  this.gameLoop.stop(), this.canvas.remove();
2247
3641
  }
2248
3642
  }
2249
- function pt(E) {
2250
- return new ut(E);
3643
+ function Mt(E) {
3644
+ return new It(E);
2251
3645
  }
2252
3646
  export {
2253
- dt as BrowserPlatform,
2254
- ut as GameEngine,
2255
- H as LANGUAGES,
2256
- tt as ThemeManager,
2257
- pt as createAxonSurge,
2258
- N as isLanguage
3647
+ St as BrowserPlatform,
3648
+ It as GameEngine,
3649
+ Y as LANGUAGES,
3650
+ dt as ThemeManager,
3651
+ Mt as createAxonSurge,
3652
+ w as isLanguage
2259
3653
  };