@gamebob/axon-surge 0.9.0 → 0.11.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 (44) hide show
  1. package/dist/axon-surge.js +1953 -570
  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/locales.d.ts +32 -0
  13. package/dist/i18n/locales.d.ts.map +1 -1
  14. package/dist/input/InputManager.d.ts +3 -0
  15. package/dist/input/InputManager.d.ts.map +1 -1
  16. package/dist/physics/PhysicsEngine.d.ts +1 -3
  17. package/dist/physics/PhysicsEngine.d.ts.map +1 -1
  18. package/dist/physics/handlers/ChainReactionHelper.d.ts +6 -0
  19. package/dist/physics/handlers/ChainReactionHelper.d.ts.map +1 -0
  20. package/dist/physics/handlers/CoreCollisionHandler.d.ts +11 -0
  21. package/dist/physics/handlers/CoreCollisionHandler.d.ts.map +1 -0
  22. package/dist/physics/handlers/ShieldCollisionHandler.d.ts +10 -0
  23. package/dist/physics/handlers/ShieldCollisionHandler.d.ts.map +1 -0
  24. package/dist/physics/handlers/ThrownCollisionHandler.d.ts +13 -0
  25. package/dist/physics/handlers/ThrownCollisionHandler.d.ts.map +1 -0
  26. package/dist/physics/handlers/ToxicPoolPhysicsHandler.d.ts +8 -0
  27. package/dist/physics/handlers/ToxicPoolPhysicsHandler.d.ts.map +1 -0
  28. package/dist/physics/handlers/VortexPhysicsHandler.d.ts +6 -0
  29. package/dist/physics/handlers/VortexPhysicsHandler.d.ts.map +1 -0
  30. package/dist/powerups/OrbitingModifierOrb.d.ts +16 -0
  31. package/dist/powerups/OrbitingModifierOrb.d.ts.map +1 -0
  32. package/dist/powerups/PowerUpRegistry.d.ts +7 -0
  33. package/dist/powerups/PowerUpRegistry.d.ts.map +1 -0
  34. package/dist/powerups/PowerUpTypes.d.ts +16 -0
  35. package/dist/powerups/PowerUpTypes.d.ts.map +1 -0
  36. package/dist/render/CanvasRenderer.d.ts +3 -0
  37. package/dist/render/CanvasRenderer.d.ts.map +1 -1
  38. package/dist/strategies/FragmentClusterStrategy.d.ts.map +1 -1
  39. package/dist/strategies/HeavyShieldStrategy.d.ts +5 -0
  40. package/dist/strategies/HeavyShieldStrategy.d.ts.map +1 -0
  41. package/dist/types/game.d.ts +1 -1
  42. package/dist/types/game.d.ts.map +1 -1
  43. package/dist/ui/ProgressBar.d.ts.map +1 -1
  44. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- class V {
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 V {
15
15
  this.listeners.clear();
16
16
  }
17
17
  }
18
- class F {
18
+ class X {
19
19
  animationFrameId = null;
20
20
  lastTime = 0;
21
21
  isRunning = !1;
@@ -36,31 +36,126 @@ class F {
36
36
  this.lastTime = t, this.updateCallback(e), this.renderCallback(), this.animationFrameId = requestAnimationFrame(this.tick);
37
37
  }
38
38
  }
39
- class Y {
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 U {
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 U {
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 U {
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 U {
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 J {
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 J {
134
250
  y: this.pointerPosition.y,
135
251
  time: l
136
252
  });
137
- const o = l - 0.08;
138
- this.pointerHistory = this.pointerHistory.filter((n) => n.time >= o), 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 J {
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 J {
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], r = s[s.length - 1], h = Math.max(0.01, r.time - n.time);
192
- a = (r.x - n.x) / h, l = (r.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 o = Math.hypot(a, l);
195
- if (o > 30) {
196
- const r = Math.min(o * 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) * r,
199
- y: Math.sin(h) * r
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, r = t.position.y - this.dragStart.y, h = Math.hypot(n, r);
203
- if (h > 5) {
204
- const c = Math.atan2(r, 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 Z {
353
+ class j {
222
354
  cellSize;
223
355
  grid = /* @__PURE__ */ new Map();
224
356
  constructor(t = 100) {
@@ -230,22 +362,22 @@ class Z {
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 o = s; o <= a; o++) {
234
- const n = `${l}:${o}`;
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), o = Math.floor((t.y + e) / this.cellSize);
240
- for (let n = s; n <= a; n++)
241
- for (let r = l; r <= o; r++) {
242
- const h = `${n}:${r}`, 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 X {
380
+ class q {
249
381
  hitstopTime = 0;
250
382
  shakeTime = 0;
251
383
  shakeDuration = 0.14;
@@ -285,7 +417,7 @@ class X {
285
417
  };
286
418
  }
287
419
  }
288
- const N = {
420
+ const P = {
289
421
  es: {
290
422
  title: "AXON SURGE",
291
423
  startButton: "INICIAR ENLACE",
@@ -307,7 +439,39 @@ const N = {
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 N = {
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 N = {
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 N = {
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 N = {
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 N = {
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 N = {
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 N = {
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 N = {
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 N = {
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 N = {
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 N = {
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 N = {
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 N = {
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 N = {
629
1209
  tutorialSettingLabel: "启动时显示教程",
630
1210
  tutorialStep1Text: "步骤 1: 按住指定的敌人",
631
1211
  tutorialStep2Text: "步骤 2: 朝目标快速挥动抛投",
632
- tutorialDragWarning: "最佳策略是快速挥动抛投!"
633
- }
634
- }, K = [
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 N = {
648
1260
  "ko",
649
1261
  "zh"
650
1262
  ];
651
- function P(T) {
652
- return K.includes(T);
1263
+ function w(E) {
1264
+ return Y.includes(E);
653
1265
  }
654
- const H = "axon_surge_language";
655
- class $ {
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
1273
  try {
662
- const e = localStorage.getItem(H);
663
- if (e && P(e))
1274
+ const e = localStorage.getItem(V);
1275
+ if (e && w(e))
664
1276
  return e;
665
1277
  } catch {
666
1278
  }
667
- if (t && P(t))
1279
+ if (t && w(t))
668
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 && P(i))
1285
+ if (i && w(i))
674
1286
  return i;
675
1287
  }
676
1288
  } catch {
@@ -679,7 +1291,7 @@ class $ {
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 && P(i))
1294
+ if (i && w(i))
683
1295
  return i;
684
1296
  }
685
1297
  } catch {
@@ -687,10 +1299,10 @@ class $ {
687
1299
  return "en";
688
1300
  }
689
1301
  setLanguage(t) {
690
- if (N[t]) {
1302
+ if (P[t]) {
691
1303
  this.currentLanguage = t;
692
1304
  try {
693
- localStorage.setItem(H, t);
1305
+ localStorage.setItem(V, t);
694
1306
  } catch {
695
1307
  }
696
1308
  }
@@ -699,13 +1311,98 @@ class $ {
699
1311
  return this.currentLanguage;
700
1312
  }
701
1313
  translate(t, e) {
702
- let s = (N[this.currentLanguage] || N.en)[t] || N.en[t] || String(t);
1314
+ let s = (P[this.currentLanguage] || P.en)[t] || P.en[t] || String(t);
703
1315
  return e && Object.entries(e).forEach(([a, l]) => {
704
1316
  s = s.replace(`{${a}}`, String(l));
705
1317
  }), s;
706
1318
  }
707
1319
  }
708
- class z {
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 {
709
1406
  execute(t) {
710
1407
  const { thrownEnemy: e, targetEnemy: i, shockwaves: s, particles: a, floatingTexts: l } = t;
711
1408
  i.active = !1, s.push({
@@ -718,12 +1415,12 @@ class z {
718
1415
  lifetime: 0,
719
1416
  maxLifetime: 0.5
720
1417
  });
721
- for (let o = 0; o < 30; o++) {
722
- const n = Math.random() * Math.PI * 2, r = 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;
723
1420
  a.push({
724
1421
  id: Math.random().toString(),
725
1422
  position: { ...i.position },
726
- velocity: { x: Math.cos(n) * r, y: Math.sin(n) * r },
1423
+ velocity: { x: Math.cos(o) * r, y: Math.sin(o) * r },
727
1424
  color: "#ff2a5f",
728
1425
  radius: 3 + Math.random() * 4,
729
1426
  alpha: 1,
@@ -744,19 +1441,19 @@ class z {
744
1441
  });
745
1442
  }
746
1443
  }
747
- class _ {
1444
+ class st {
748
1445
  execute(t) {
749
- const { thrownEnemy: e, pools: i, shockwaves: s, particles: a, floatingTexts: l, eventBus: o } = t, n = e.position;
1446
+ const { thrownEnemy: e, pools: i, shockwaves: s, particles: a, floatingTexts: l, eventBus: n } = t, o = e.position;
750
1447
  i.push({
751
1448
  id: Math.random().toString(),
752
- position: { ...n },
1449
+ position: { ...o },
753
1450
  radius: 220,
754
1451
  duration: 0,
755
1452
  maxDuration: 7,
756
1453
  damage: 50
757
1454
  }), s.push({
758
1455
  id: Math.random().toString(),
759
- position: { ...n },
1456
+ position: { ...o },
760
1457
  radius: 10,
761
1458
  maxRadius: 240,
762
1459
  color: "#39ff14",
@@ -765,11 +1462,11 @@ class _ {
765
1462
  maxLifetime: 0.6
766
1463
  });
767
1464
  for (let r = 0; r < 45; r++) {
768
- const h = Math.random() * Math.PI * 2, c = 120 + Math.random() * 260;
1465
+ const c = Math.random() * Math.PI * 2, h = 120 + Math.random() * 260;
769
1466
  a.push({
770
1467
  id: Math.random().toString(),
771
- position: { ...n },
772
- 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 },
773
1470
  color: "#39ff14",
774
1471
  radius: 4 + Math.random() * 5,
775
1472
  alpha: 1,
@@ -780,22 +1477,22 @@ class _ {
780
1477
  l.push({
781
1478
  id: Math.random().toString(),
782
1479
  text: "MASSIVE SPORE NEBULA",
783
- position: { ...n },
1480
+ position: { ...o },
784
1481
  velocity: { x: 0, y: -60 },
785
1482
  color: "#39ff14",
786
1483
  alpha: 1,
787
1484
  lifetime: 0,
788
1485
  maxLifetime: 1.2,
789
1486
  size: 26
790
- }), e.active = !1, o.emit("onPoolCreated", { position: n });
1487
+ }), e.active = !1, n.emit("onPoolCreated", { position: o });
791
1488
  }
792
1489
  }
793
- class q {
1490
+ class at {
794
1491
  execute(t) {
795
- const { thrownEnemy: e, targetEnemy: i, allEnemies: s, shockwaves: a, particles: l, floatingTexts: o } = t, n = i.position;
1492
+ const { thrownEnemy: e, targetEnemy: i, allEnemies: s, shockwaves: a, particles: l, floatingTexts: n } = t, o = i.position;
796
1493
  e.active = !1, i.active = !1, a.push({
797
1494
  id: Math.random().toString(),
798
- position: { ...n },
1495
+ position: { ...o },
799
1496
  radius: 15,
800
1497
  maxRadius: 280,
801
1498
  color: "#ffd700",
@@ -803,22 +1500,37 @@ class q {
803
1500
  lifetime: 0,
804
1501
  maxLifetime: 0.6
805
1502
  });
806
- for (let r = 0; r < 6; r++) {
807
- const h = r * Math.PI * 2 / 6, c = {
808
- x: n.x + Math.cos(h) * 15,
809
- y: n.y + Math.sin(h) * 15
810
- }, u = L.createEnemy("micro", c, {
811
- x: c.x + Math.cos(h) * 200,
812
- 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
813
1522
  });
814
- 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);
815
1527
  }
816
- for (let r = 0; r < 35; r++) {
817
- 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;
818
1530
  l.push({
819
1531
  id: Math.random().toString(),
820
- position: { ...n },
821
- velocity: { x: Math.cos(h) * c, y: Math.sin(h) * c },
1532
+ position: { ...o },
1533
+ velocity: { x: Math.cos(p) * _, y: Math.sin(p) * _ },
822
1534
  color: "#ffd700",
823
1535
  radius: 4 + Math.random() * 4,
824
1536
  alpha: 1,
@@ -826,10 +1538,10 @@ class q {
826
1538
  maxLifetime: 0.6
827
1539
  });
828
1540
  }
829
- o.push({
1541
+ n.push({
830
1542
  id: Math.random().toString(),
831
1543
  text: "CLUSTER DETONATION",
832
- position: { ...n },
1544
+ position: { ...o },
833
1545
  velocity: { x: 0, y: -60 },
834
1546
  color: "#ffd700",
835
1547
  alpha: 1,
@@ -839,7 +1551,7 @@ class q {
839
1551
  });
840
1552
  }
841
1553
  }
842
- class j {
1554
+ class ot {
843
1555
  execute(t) {
844
1556
  const { thrownEnemy: e, targetEnemy: i, vortices: s, shockwaves: a } = t, l = {
845
1557
  x: (e.position.x + i.position.x) / 2,
@@ -864,120 +1576,213 @@ class j {
864
1576
  }), e.triggerDissolveDeath(), i.triggerDissolveDeath();
865
1577
  }
866
1578
  }
867
- class L {
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 {
868
1633
  static createEnemy(t, e, i) {
869
- const s = `enemy_${Date.now()}_${Math.random()}`, a = new U(s);
1634
+ const s = `enemy_${Date.now()}_${Math.random()}`, a = new H(s);
870
1635
  return this.configureEnemy(a, t, e, i), a;
871
1636
  }
872
1637
  static configureEnemy(t, e, i, s) {
873
1638
  t.type = e, t.position = { ...i }, t.active = !0, t.isGrabbed = !1, t.isThrown = !1;
874
- const a = s.x - i.x, l = s.y - i.y, o = Math.atan2(l, a);
875
- let n = 70, r = 100, h = 20, c = "#ff2a5f", u = null;
876
- e === "piercer" ? (n = 95, r = 140, h = 18, c = "#ff2a5f", u = new z()) : e === "spore" ? (n = 65, r = 90, h = 24, c = "#39ff14", u = new _()) : e === "cluster" ? (n = 50, r = 75, h = 26, c = "#ffd700", u = new q()) : e === "parasite" ? (n = 80, r = 110, h = 22, c = "#9d4edd", u = new j()) : e === "micro" && (n = 130, r = 160, h = 12, c = "#ffd700"), t.radius = h, t.color = c, t.strategy = u, t.maxSpeed = r, t.velocity = {
877
- x: Math.cos(o) * n,
878
- y: Math.sin(o) * 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
879
1644
  };
880
1645
  }
881
1646
  }
882
- class Q {
883
- spatialHash;
884
- eventBus;
885
- i18n;
886
- currentThrowKills = 0;
887
- currentThrowPos = null;
888
- constructor(t, e) {
889
- this.spatialHash = new Z(100), this.eventBus = t, this.i18n = e;
890
- }
891
- update(t, e, i, s, a, l, o, n, r, h, c, u, p, f) {
892
- this.spatialHash.clear();
893
- for (const d of i)
894
- d.active && !d.isDying ? (d.update(t), this.spatialHash.insert(d)) : d.active && d.isDying && d.update(t);
895
- for (let d = l.length - 1; d >= 0; d--) {
896
- const m = l[d];
897
- if (!m) continue;
898
- m.lifetime += t;
899
- const x = m.lifetime / m.maxLifetime;
900
- m.radius = m.maxRadius * x, m.alpha = Math.max(0, 1 - x), m.lifetime >= m.maxLifetime && l.splice(d, 1);
901
- }
902
- for (let d = a.length - 1; d >= 0; d--) {
903
- const m = a[d];
904
- if (m) {
905
- m.duration += t;
906
- for (const x of i) {
907
- if (!x.active || x.isGrabbed || x.isDying || x.isThrown && x.type === "piercer") continue;
908
- const S = m.position.x - x.position.x, v = m.position.y - x.position.y, b = Math.hypot(S, v);
909
- if (b > 2 && b <= m.radius) {
910
- const M = Math.pow(1 - b / m.radius, 0.7), E = m.pullForce * M, g = Math.atan2(v, S);
911
- x.velocity.x += Math.cos(g) * E * t, x.velocity.y += Math.sin(g) * E * t, x.position.x += Math.cos(g) * E * t * 0.8, x.position.y += Math.sin(g) * E * 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);
912
1684
  }
1685
+ g && (_ = Math.atan2(g.position.y - p.y, g.position.x - p.x));
913
1686
  }
914
- 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);
915
1695
  }
916
- }
917
- for (const d of i) {
918
- if (!d.active || d.isGrabbed || d.isDying) continue;
919
- const m = e.position.x - d.position.x, x = e.position.y - d.position.y;
920
- if (Math.hypot(m, x) <= e.radius + d.radius) {
921
- d.active = !1;
922
- const v = e.takeDamage();
923
- this.eventBus.emit("onCoreDamaged", { currentIntegrity: e.integrity }), l.push({
924
- id: Math.random().toString(),
925
- position: { ...e.position },
926
- radius: 20,
927
- maxRadius: Math.max(u, p) * 1.3,
928
- color: "#00f0ff",
929
- alpha: 1,
930
- lifetime: 0,
931
- maxLifetime: 0.8
932
- }), r.triggerScreenShake({ x: m, y: x }, 25), r.triggerHitstop(0.15), r.triggerFlash(0.6);
933
- for (const b of i)
934
- if (b.active && !b.isGrabbed) {
935
- b.triggerDissolveDeath();
936
- for (let M = 0; M < 8; M++) {
937
- const E = Math.random() * Math.PI * 2, g = 100 + Math.random() * 200;
938
- o.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({
939
1741
  id: Math.random().toString(),
940
- position: { ...b.position },
941
- velocity: { x: Math.cos(E) * g, y: Math.sin(E) * g },
942
- color: "#00f0ff",
943
- radius: 3 + Math.random() * 3,
1742
+ position: { ...d.position },
1743
+ radius: 20,
1744
+ maxRadius: f,
1745
+ color: "#ff2a5f",
944
1746
  alpha: 1,
945
1747
  lifetime: 0,
946
- maxLifetime: 0.5
1748
+ maxLifetime: 0.6
947
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
+ }
948
1755
  }
949
1756
  }
950
- n.push({
951
- id: Math.random().toString(),
952
- text: "CORE OVERLOAD PULSE!",
953
- position: { ...e.position },
954
- velocity: { x: 0, y: -90 },
955
- color: "#00f0ff",
956
- alpha: 1,
957
- lifetime: 0,
958
- maxLifetime: 1.5,
959
- size: 32
960
- }), (!v || e.integrity <= 0) && this.eventBus.emit("onGameOver", { score: c.value, wave: 1 });
961
- break;
962
- }
963
- }
964
- let y = !1;
965
- for (const d of i)
966
- if (!(!d.active || !d.isThrown || d.isDying)) {
967
- if (y = !0, d.position.x < -120 || d.position.x > u + 120 || d.position.y < -120 || d.position.y > p + 120) {
968
1757
  d.active = !1, d.isThrown = !1;
969
1758
  continue;
970
1759
  }
971
- for (const m of i) {
972
- if (m === d || !m.active || m.isGrabbed || m.isDying) continue;
973
- const x = m.position.x - d.position.x, S = m.position.y - d.position.y;
974
- if (Math.hypot(x, S) <= d.getHitRadius() + m.getHitRadius()) {
975
- this.currentThrowPos = { x: d.position.x, y: d.position.y };
976
- const b = Math.atan2(d.velocity.y, d.velocity.x);
977
- if (d.type === "piercer") {
978
- this.currentThrowKills++, this.killEnemyWithChainReaction(m, b, s, a, l, o, i), r.triggerHitstop(0.05), r.triggerScreenShake({ x, y: S }, 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({
979
1784
  id: Math.random().toString(),
980
- position: { ...m.position },
1785
+ position: { ...g.position },
981
1786
  radius: 10,
982
1787
  maxRadius: 180,
983
1788
  color: "#ff2a5f",
@@ -985,12 +1790,12 @@ class Q {
985
1790
  lifetime: 0,
986
1791
  maxLifetime: 0.45
987
1792
  });
988
- for (let M = 0; M < 16; M++) {
989
- const E = Math.random() * Math.PI * 2, g = 150 + Math.random() * 300;
990
- o.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({
991
1796
  id: Math.random().toString(),
992
- position: { ...m.position },
993
- velocity: { x: Math.cos(E) * g, y: Math.sin(E) * g },
1797
+ position: { ...g.position },
1798
+ velocity: { x: Math.cos(S) * m, y: Math.sin(S) * m },
994
1799
  color: "#ff2a5f",
995
1800
  radius: 3 + Math.random() * 3,
996
1801
  alpha: 1,
@@ -998,25 +1803,41 @@ class Q {
998
1803
  maxLifetime: 0.4
999
1804
  });
1000
1805
  }
1001
- 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();
1002
1823
  } else {
1003
- const M = d.type === m.type, E = M ? 360 : 250;
1004
- l.push({
1824
+ const I = d.type === g.type, S = I ? 360 : 250;
1825
+ s.push({
1005
1826
  id: Math.random().toString(),
1006
- position: { ...this.currentThrowPos },
1827
+ position: { ...u.pos },
1007
1828
  radius: 15,
1008
- maxRadius: E,
1829
+ maxRadius: S,
1009
1830
  color: d.color,
1010
1831
  alpha: 1,
1011
1832
  lifetime: 0,
1012
1833
  maxLifetime: 0.55
1013
1834
  });
1014
- for (let g = 0; g < 45; g++) {
1015
- const A = Math.random() * Math.PI * 2, I = 200 + Math.random() * 450;
1016
- o.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({
1017
1838
  id: Math.random().toString(),
1018
- position: { ...this.currentThrowPos },
1019
- velocity: { x: Math.cos(A) * I, y: Math.sin(A) * I },
1839
+ position: { ...u.pos },
1840
+ velocity: { x: Math.cos(y) * M, y: Math.sin(y) * M },
1020
1841
  color: d.color,
1021
1842
  radius: 4 + Math.random() * 6,
1022
1843
  alpha: 1,
@@ -1024,131 +1845,213 @@ class Q {
1024
1845
  maxLifetime: 0.7
1025
1846
  });
1026
1847
  }
1027
- if (M) {
1028
- if (this.currentThrowKills += 2, r.triggerHitstop(0.14), r.triggerFlash(0.5), r.triggerScreenShake({ x, y: S }, 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({
1029
1850
  id: Math.random().toString(),
1030
1851
  text: "COLOR SYNERGY!",
1031
- position: { ...this.currentThrowPos },
1852
+ position: { ...u.pos },
1032
1853
  velocity: { x: 0, y: -80 },
1033
1854
  color: d.color,
1034
1855
  alpha: 1,
1035
1856
  lifetime: 0,
1036
1857
  maxLifetime: 1.2,
1037
1858
  size: 26
1038
- }), d.type === "spore")
1039
- s.push({
1859
+ });
1860
+ const m = A.getInstance().getConfig();
1861
+ if (d.type === "spore")
1862
+ e.push({
1040
1863
  id: Math.random().toString(),
1041
- position: { ...this.currentThrowPos },
1042
- radius: 340,
1864
+ position: { ...u.pos },
1865
+ radius: m.toxicPool.synergyRadius,
1043
1866
  duration: 0,
1044
- maxDuration: 10,
1045
- damage: 100
1867
+ maxDuration: m.toxicPool.synergyDuration,
1868
+ damage: m.toxicPool.damage * 2
1046
1869
  });
1047
1870
  else if (d.type === "parasite")
1048
- a.push({
1871
+ i.push({
1049
1872
  id: Math.random().toString(),
1050
- position: { ...this.currentThrowPos },
1051
- radius: 600,
1873
+ position: { ...u.pos },
1874
+ radius: m.gravityVortex.synergyRadius,
1052
1875
  duration: 0,
1053
- maxDuration: 7,
1054
- pullForce: 5e3
1876
+ maxDuration: m.gravityVortex.synergyDuration,
1877
+ pullForce: m.gravityVortex.synergyPullForce
1055
1878
  });
1056
1879
  else if (d.type === "cluster")
1057
- for (let g = 0; g < 8; g++) {
1058
- const A = g * Math.PI * 2 / 8, I = {
1059
- x: this.currentThrowPos.x + Math.cos(A) * 15,
1060
- y: this.currentThrowPos.y + Math.sin(A) * 15
1061
- }, C = L.createEnemy("micro", I, {
1062
- x: I.x + Math.cos(A) * 220,
1063
- y: I.y + Math.sin(A) * 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
1064
1887
  });
1065
- C.isThrown = !0, i.push(C);
1888
+ C.isThrown = !0, t.push(C);
1066
1889
  }
1067
- this.killEnemyWithChainReaction(d, b, s, a, l, o, i), this.killEnemyWithChainReaction(m, b, s, a, l, o, i);
1890
+ R.killEnemy(d, v, e, i, s, t), R.killEnemy(g, v, e, i, s, t);
1068
1891
  } else
1069
- this.currentThrowKills += 2, r.triggerHitstop(0.08), r.triggerFlash(0.35), r.triggerScreenShake({ x, y: S }, 10), this.killEnemyWithChainReaction(d, b, s, a, l, o, i), this.killEnemyWithChainReaction(m, b, s, a, l, o, i);
1070
- for (const g of i) {
1071
- if (g === d || g === m || !g.active || g.isGrabbed || g.isDying) continue;
1072
- const A = g.position.x - this.currentThrowPos.x, I = g.position.y - this.currentThrowPos.y;
1073
- Math.hypot(A, I) <= E && (this.killEnemyWithChainReaction(g, b, s, a, l, o, 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++);
1074
1897
  }
1075
- f && f();
1898
+ p && p();
1076
1899
  break;
1077
1900
  }
1078
1901
  }
1079
1902
  }
1080
1903
  }
1081
- 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({
1082
1905
  id: Math.random().toString(),
1083
- text: `MULTIKILL x${this.currentThrowKills}!`,
1084
- position: { ...this.currentThrowPos },
1906
+ text: `MULTIKILL x${u.kills}!`,
1907
+ position: { ...u.pos },
1085
1908
  velocity: { x: 0, y: -90 },
1086
1909
  color: "#ff00dd",
1087
1910
  alpha: 1,
1088
1911
  lifetime: 0,
1089
1912
  maxLifetime: 1.4,
1090
1913
  size: 32
1091
- }), this.eventBus.emit("onComboUpdated", { combo: h.value }), this.currentThrowKills = 0, this.currentThrowPos = null);
1092
- for (let d = s.length - 1; d >= 0; d--) {
1093
- const m = s[d];
1094
- if (m) {
1095
- m.duration += t;
1096
- for (const x of i) {
1097
- if (!x.active || x.isGrabbed || x.isDying || x.isThrown && x.type === "piercer") continue;
1098
- const S = x.position.x - m.position.x, v = x.position.y - m.position.y;
1099
- Math.hypot(S, v) <= m.radius && (this.killEnemyWithChainReaction(x, 0, s, a, l, o, 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());
1100
1927
  }
1101
- m.duration >= m.maxDuration && s.splice(d, 1);
1928
+ c.duration >= c.maxDuration && t.splice(r, 1);
1102
1929
  }
1103
1930
  }
1104
1931
  }
1105
- killEnemyWithChainReaction(t, e, i, s, a, l, o) {
1106
- if (!(!t.active || t.isDying))
1107
- if (a.push({
1108
- id: Math.random().toString(),
1109
- position: { ...t.position },
1110
- radius: 10,
1111
- maxRadius: 180,
1112
- color: t.color,
1113
- alpha: 1,
1114
- lifetime: 0,
1115
- maxLifetime: 0.5
1116
- }), t.type === "spore")
1117
- t.triggerDissolveDeath(), i.push({
1118
- id: Math.random().toString(),
1119
- position: { ...t.position },
1120
- radius: 200,
1121
- duration: 0,
1122
- maxDuration: 6,
1123
- damage: 50
1124
- });
1125
- else if (t.type === "cluster") {
1126
- t.triggerDissolveDeath();
1127
- for (let n = 0; n < 6; n++) {
1128
- const r = n * Math.PI * 2 / 6, h = {
1129
- x: t.position.x + Math.cos(r) * 15,
1130
- y: t.position.y + Math.sin(r) * 15
1131
- }, c = L.createEnemy("micro", h, {
1132
- x: h.x + Math.cos(r) * 200,
1133
- y: h.y + Math.sin(r) * 200
1134
- });
1135
- c.isThrown = !0, o.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
+ }
1136
1956
  }
1137
- } else t.type === "parasite" ? (t.triggerDissolveDeath(), s.push({
1138
- id: Math.random().toString(),
1139
- position: { ...t.position },
1140
- radius: 450,
1141
- duration: 0,
1142
- maxDuration: 5,
1143
- pullForce: 3e3
1144
- })) : t.type === "piercer" ? t.triggerSliceDeath(e) : t.triggerDissolveDeath();
1145
1957
  }
1146
1958
  }
1147
- class tt {
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 {
1148
2051
  pool = [];
1149
2052
  constructor(t = 500) {
1150
2053
  for (let e = 0; e < t; e++) {
1151
- const i = new U(`pool_enemy_${e}`);
2054
+ const i = new H(`pool_enemy_${e}`);
1152
2055
  this.pool.push(i);
1153
2056
  }
1154
2057
  }
@@ -1156,7 +2059,7 @@ class tt {
1156
2059
  for (const e of this.pool)
1157
2060
  if (!e.active)
1158
2061
  return e.reset(), e;
1159
- const t = new U(`fallback_enemy_${Date.now()}_${Math.random()}`);
2062
+ const t = new H(`fallback_enemy_${Date.now()}_${Math.random()}`);
1160
2063
  return this.pool.push(t), t;
1161
2064
  }
1162
2065
  resetAll() {
@@ -1164,91 +2067,91 @@ class tt {
1164
2067
  t.reset();
1165
2068
  }
1166
2069
  }
1167
- class w {
2070
+ class O {
1168
2071
  static getOffscreenPosition(t, e) {
1169
2072
  const i = Math.floor(Math.random() * 4), s = 70;
1170
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 };
1171
2074
  }
1172
2075
  static spawnCircleOfDeath(t, e, i, s) {
1173
- const a = [], o = Math.max(i, s) * 0.55 + 80;
1174
- for (let n = 0; n < 18; n++) {
1175
- const r = n * Math.PI * 2 / 18, h = {
1176
- x: e.x + Math.cos(r) * o,
1177
- y: e.y + Math.sin(r) * o
1178
- }, c = t.get(), u = ["piercer", "spore", "cluster", "parasite"], p = u[n % u.length];
1179
- L.configureEnemy(c, p, h, e), c.velocity = {
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 = {
1180
2083
  x: Math.cos(r + Math.PI) * 55,
1181
2084
  y: Math.sin(r + Math.PI) * 55
1182
- }, a.push(c);
2085
+ }, a.push(h);
1183
2086
  }
1184
2087
  return a;
1185
2088
  }
1186
2089
  static spawnDenseCluster(t, e, i, s) {
1187
- const a = [], o = Math.floor(Math.random() * 4);
1188
- let n = { x: -60, y: -60 };
1189
- o === 0 ? n = { x: Math.random() * e, y: -80 } : o === 1 ? n = { x: e + 80, y: Math.random() * i } : o === 2 ? n = { x: Math.random() * e, y: i + 80 } : n = { x: -80, y: Math.random() * i };
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 };
1190
2093
  for (let r = 0; r < 14; r++) {
1191
- const h = {
2094
+ const c = {
1192
2095
  x: (Math.random() - 0.5) * 60,
1193
2096
  y: (Math.random() - 0.5) * 60
1194
- }, c = { x: n.x + h.x, y: n.y + h.y }, u = t.get();
1195
- L.configureEnemy(u, "spore", c, s);
1196
- 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);
1197
2100
  u.velocity = {
1198
- x: Math.cos(y) * (50 + Math.random() * 20),
1199
- 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)
1200
2103
  }, a.push(u);
1201
2104
  }
1202
2105
  return a;
1203
2106
  }
1204
2107
  static spawnSineSnake(t, e, i, s) {
1205
- const a = [], o = i * 0.2 + Math.random() * i * 0.6;
1206
- for (let n = 0; n < 12; n++) {
2108
+ const a = [], n = i * 0.2 + Math.random() * i * 0.6;
2109
+ for (let o = 0; o < 12; o++) {
1207
2110
  const r = {
1208
- x: -60 - n * 40,
1209
- y: o + Math.sin(n * 0.45) * 70
1210
- }, h = t.get();
1211
- L.configureEnemy(h, "cluster", r, s), h.velocity = { x: 75, y: Math.cos(n * 0.45) * 30 }, a.push(h);
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);
1212
2115
  }
1213
2116
  return a;
1214
2117
  }
1215
2118
  static spawnDoubleSpiral(t, e, i, s) {
1216
2119
  const a = [];
1217
- for (let o = 0; o < 14; o++) {
1218
- const n = o / 14, r = n * Math.PI * 4, h = 120 + n * 450, c = {
1219
- x: e + Math.cos(r) * h,
1220
- y: -60 + Math.sin(r) * 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
1221
2124
  }, u = t.get();
1222
- L.configureEnemy(u, "parasite", c, s), a.push(u);
2125
+ T.configureEnemy(u, "parasite", h, s), a.push(u);
1223
2126
  }
1224
2127
  return a;
1225
2128
  }
1226
2129
  static spawnMarchingWall(t, e, i, s) {
1227
- const a = [], o = Math.random() > 0.5;
1228
- for (let n = 0; n < 12; n++) {
1229
- const r = n / 11 * i, h = {
1230
- x: o ? -60 : e + 60,
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,
1231
2134
  y: r
1232
- }, c = t.get();
1233
- L.configureEnemy(c, "piercer", h, s), c.velocity = {
1234
- x: o ? 70 : -70,
2135
+ }, h = t.get();
2136
+ T.configureEnemy(h, "piercer", c, s), h.velocity = {
2137
+ x: n ? 70 : -70,
1235
2138
  y: 0
1236
- }, a.push(c);
2139
+ }, a.push(h);
1237
2140
  }
1238
2141
  return a;
1239
2142
  }
1240
2143
  static spawnCrossfireStreams(t, e, i, s) {
1241
2144
  const a = [];
1242
- for (let o = 0; o < 10; o++) {
1243
- const n = { x: -50 - o * 35, y: -50 - o * 35 }, r = t.get();
1244
- L.configureEnemy(r, "spore", n, s), a.push(r);
1245
- const h = { x: e + 50 + o * 35, y: i + 50 + o * 35 }, c = t.get();
1246
- L.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);
1247
2150
  }
1248
2151
  return a;
1249
2152
  }
1250
2153
  }
1251
- class et {
2154
+ class pt {
1252
2155
  wave = 1;
1253
2156
  pool;
1254
2157
  spawnTimer = 0;
@@ -1256,63 +2159,63 @@ class et {
1256
2159
  patternCooldown = 0;
1257
2160
  initialGracePeriod = 6;
1258
2161
  constructor() {
1259
- this.pool = new tt(500);
2162
+ this.pool = new ut(500);
1260
2163
  }
1261
2164
  reset() {
1262
2165
  this.wave = 1, this.spawnTimer = 0, this.waveTimer = 0, this.patternCooldown = 0;
1263
2166
  }
1264
2167
  update(t, e, i, s, a) {
1265
2168
  this.waveTimer += t, this.spawnTimer += t, this.patternCooldown += t, this.applyFlockingBehaviors(e, t, a);
1266
- const l = e.filter((r) => r.active).length, o = 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);
1267
2170
  if (this.waveTimer > this.initialGracePeriod && this.patternCooldown > Math.max(12 - this.wave, 6) && l < 35) {
1268
2171
  this.patternCooldown = 0;
1269
2172
  const r = this.spawnPatternFormation(i, s, a);
1270
- for (const h of r)
1271
- e.push(h);
2173
+ for (const c of r)
2174
+ e.push(c);
1272
2175
  }
1273
- const n = Math.min(18 + this.wave * 4, 80);
1274
- return this.spawnTimer >= o && 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;
1275
2178
  }
1276
2179
  spawnSingleEnemy(t, e, i) {
1277
- const s = w.getOffscreenPosition(t, e), a = Math.random();
2180
+ const s = O.getOffscreenPosition(t, e), a = Math.random();
1278
2181
  let l = "piercer";
1279
- a > 0.75 ? l = "parasite" : a > 0.5 ? l = "cluster" : a > 0.25 && (l = "spore");
1280
- const o = this.pool.get();
1281
- return L.configureEnemy(o, l, s, i), o;
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;
1282
2185
  }
1283
2186
  spawnPatternFormation(t, e, i) {
1284
2187
  const s = Math.random();
1285
- return s < 0.25 ? w.spawnCircleOfDeath(this.pool, i, t, e) : s < 0.5 ? w.spawnDenseCluster(this.pool, t, e, i) : s < 0.75 ? w.spawnSineSnake(this.pool, t, e, i) : w.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);
1286
2189
  }
1287
2190
  applyFlockingBehaviors(t, e, i) {
1288
2191
  for (let a = 0; a < t.length; a++) {
1289
2192
  const l = t[a];
1290
2193
  if (!l.active || l.isGrabbed || l.isThrown || l.isDying) continue;
1291
- let o = 0, n = 0, r = 0;
2194
+ let n = 0, o = 0, r = 0;
1292
2195
  for (let p = 0; p < t.length; p++) {
1293
2196
  if (a === p) continue;
1294
- const f = t[p];
1295
- if (!f.active || f.isGrabbed || f.isDying) continue;
1296
- const y = l.position.x - f.position.x, d = l.position.y - f.position.y, m = Math.hypot(y, d);
1297
- m > 0 && m < 70 && (o += y / m, n += d / m, r++);
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++);
1298
2201
  }
1299
- r > 0 && (o /= r, n /= r, l.velocity.x += o * 60 * e, l.velocity.y += n * 60 * e);
1300
- 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);
1301
2204
  if (u > 0) {
1302
2205
  const p = 80 + Math.min(this.wave * 4, 40);
1303
- 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;
1304
2207
  }
1305
2208
  if (l.maxSpeed > 0) {
1306
2209
  const p = Math.hypot(l.velocity.x, l.velocity.y);
1307
2210
  if (p > l.maxSpeed) {
1308
- const f = l.maxSpeed / p;
1309
- l.velocity.x *= f, l.velocity.y *= f;
2211
+ const _ = l.maxSpeed / p;
2212
+ l.velocity.x *= _, l.velocity.y *= _;
1310
2213
  }
1311
2214
  }
1312
2215
  }
1313
2216
  }
1314
2217
  }
1315
- const R = {
2218
+ const N = {
1316
2219
  bioluminescent: {
1317
2220
  bgInner: "#081220",
1318
2221
  bgMid: "#050b16",
@@ -1361,22 +2264,22 @@ const R = {
1361
2264
  tendrilMagenta: "#b5008c",
1362
2265
  tendrilCyan: "#0077b6"
1363
2266
  }
1364
- }, k = "axon_surge_theme";
1365
- class it {
2267
+ }, U = "axon_surge_theme";
2268
+ class dt {
1366
2269
  currentTheme = "dark";
1367
2270
  isExplicit = !1;
1368
2271
  targetElement;
1369
2272
  constructor(t, e) {
1370
2273
  e !== void 0 && (this.targetElement = e);
1371
2274
  try {
1372
- const i = localStorage.getItem(k);
1373
- if (i && R[i]) {
2275
+ const i = localStorage.getItem(U);
2276
+ if (i && N[i]) {
1374
2277
  this.currentTheme = i, this.isExplicit = !0, this.applyThemeToDOM();
1375
2278
  return;
1376
2279
  }
1377
2280
  } catch {
1378
2281
  }
1379
- if (t && R[t]) {
2282
+ if (t && N[t]) {
1380
2283
  this.currentTheme = t, this.isExplicit = !0, this.applyThemeToDOM();
1381
2284
  return;
1382
2285
  }
@@ -1386,10 +2289,10 @@ class it {
1386
2289
  this.targetElement = t, this.isExplicit ? this.applyThemeToDOM() : this.currentTheme = this.detectParentOrSystemTheme();
1387
2290
  }
1388
2291
  setTheme(t) {
1389
- if (R[t]) {
2292
+ if (N[t]) {
1390
2293
  this.currentTheme = t, this.isExplicit = !0, this.applyThemeToDOM();
1391
2294
  try {
1392
- localStorage.setItem(k, t);
2295
+ localStorage.setItem(U, t);
1393
2296
  } catch {
1394
2297
  }
1395
2298
  }
@@ -1397,7 +2300,7 @@ class it {
1397
2300
  clearExplicitTheme() {
1398
2301
  this.isExplicit = !1;
1399
2302
  try {
1400
- localStorage.removeItem(k);
2303
+ localStorage.removeItem(U);
1401
2304
  } catch {
1402
2305
  }
1403
2306
  this.removeThemeClasses(), this.currentTheme = this.detectParentOrSystemTheme();
@@ -1406,7 +2309,7 @@ class it {
1406
2309
  return this.isExplicit || (this.currentTheme = this.detectParentOrSystemTheme()), this.currentTheme;
1407
2310
  }
1408
2311
  getPalette() {
1409
- return R[this.getTheme()] || R.dark;
2312
+ return N[this.getTheme()] || N.dark;
1410
2313
  }
1411
2314
  detectParentOrSystemTheme() {
1412
2315
  try {
@@ -1444,7 +2347,7 @@ class it {
1444
2347
  this.targetElement.classList.add(t);
1445
2348
  }
1446
2349
  }
1447
- class st {
2350
+ class gt {
1448
2351
  maxDistance = 450;
1449
2352
  maxThickness = 28;
1450
2353
  minThickness = 4;
@@ -1453,60 +2356,60 @@ class st {
1453
2356
  render(t, e, i, s) {
1454
2357
  for (const a of e) {
1455
2358
  if (!a.active || a.isGrabbed || a.isDying) continue;
1456
- const l = a.position.x, o = a.position.y;
1457
- if (l >= 0 && l <= i && o >= 0 && o <= s) continue;
1458
- const n = Math.min(i, Math.max(0, l)), r = Math.min(s, Math.max(0, o)), h = Math.hypot(l - n, o - r);
1459
- if (h <= 0 || h > this.maxDistance) continue;
1460
- 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;
1461
- 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) {
1462
- const y = Math.max(0, r - p / 2), d = Math.min(s, r + p / 2);
1463
- 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);
1464
2367
  } else {
1465
- const y = Math.max(0, n - p / 2), d = Math.min(i, n + p / 2);
1466
- t.moveTo(y, r), t.lineTo(d, r);
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);
1467
2370
  }
1468
- 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();
1469
2372
  }
1470
2373
  }
1471
2374
  }
1472
- class at {
2375
+ class _t {
1473
2376
  render(t, e, i, s, a, l = !1) {
1474
- const o = (210 + (a - 1) * 38 + Math.sin(s * 0.12) * 15) % 360;
2377
+ const n = (210 + (a - 1) * 38 + Math.sin(s * 0.12) * 15) % 360;
1475
2378
  if (l) {
1476
- const v = `hsl(${o}, 50%, 94%)`, b = `hsl(${(o + 25) % 360}, 45%, 89%)`, M = `hsl(${(o + 50) % 360}, 40%, 82%)`, E = t.createRadialGradient(e / 2, i / 2, 40, e / 2, i / 2, Math.max(e, i));
1477
- E.addColorStop(0, v), E.addColorStop(0.55, b), E.addColorStop(1, M), t.fillStyle = E, t.fillRect(0, 0, e, i);
1478
- const g = (o + 75) % 360, A = e * 0.35 + Math.sin(s * 0.25) * 70, I = i * 0.45 + Math.cos(s * 0.2) * 60, C = t.createRadialGradient(A, I, 20, A, I, 400);
1479
- C.addColorStop(0, `hsla(${g}, 65%, 78%, 0.35)`), C.addColorStop(1, "rgba(255, 255, 255, 0)"), t.fillStyle = C, t.beginPath(), t.arc(A, I, 400, 0, Math.PI * 2), t.fill();
1480
- const W = (o + 160) % 360, O = e * 0.68 + Math.cos(s * 0.28) * 60, D = i * 0.55 + Math.sin(s * 0.22) * 55, G = t.createRadialGradient(O, D, 20, O, D, 440);
1481
- G.addColorStop(0, `hsla(${W}, 60%, 75%, 0.3)`), G.addColorStop(1, "rgba(255, 255, 255, 0)"), t.fillStyle = G, t.beginPath(), t.arc(O, D, 440, 0, Math.PI * 2), t.fill();
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();
1482
2385
  return;
1483
2386
  }
1484
- const n = `hsl(${o}, 45%, 8%)`, r = `hsl(${(o + 30) % 360}, 40%, 4%)`, h = `hsl(${(o + 60) % 360}, 50%, 2%)`, c = t.createRadialGradient(e / 2, i / 2, 40, e / 2, i / 2, Math.max(e, i));
1485
- c.addColorStop(0, n), c.addColorStop(0.55, r), c.addColorStop(1, h), t.fillStyle = c, t.fillRect(0, 0, e, i);
1486
- const u = (o + 75) % 360, p = e * 0.35 + Math.sin(s * 0.25) * 70, f = i * 0.45 + Math.cos(s * 0.2) * 60, y = t.createRadialGradient(p, f, 20, p, f, 400);
1487
- y.addColorStop(0, `hsla(${u}, 65%, 12%, 0.35)`), y.addColorStop(1, "rgba(0, 0, 0, 0)"), t.fillStyle = y, t.beginPath(), t.arc(p, f, 400, 0, Math.PI * 2), t.fill();
1488
- const d = (o + 160) % 360, m = e * 0.68 + Math.cos(s * 0.28) * 60, x = i * 0.55 + Math.sin(s * 0.22) * 55, S = t.createRadialGradient(m, x, 20, m, x, 440);
1489
- S.addColorStop(0, `hsla(${d}, 60%, 10%, 0.3)`), S.addColorStop(1, "rgba(0, 0, 0, 0)"), t.fillStyle = S, t.beginPath(), t.arc(m, x, 440, 0, Math.PI * 2), t.fill();
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();
1490
2393
  }
1491
2394
  }
1492
- class nt {
2395
+ class mt {
1493
2396
  render(t, e, i) {
1494
2397
  if (!e.isActive) return;
1495
2398
  const s = e.getLauncher(), a = e.getTarget();
1496
2399
  if (!s || !a || !s.active || !a.active) return;
1497
2400
  const l = e.getStep();
1498
2401
  if (t.save(), l === 1) {
1499
- const o = Math.sin(i * 6) * 10, n = s.position.x, r = s.position.y - 65 + o;
1500
- t.shadowColor = "#00f0ff", t.shadowBlur = 20, t.fillStyle = "#00f0ff", t.beginPath(), t.moveTo(n, r + 20), t.lineTo(n - 16, r - 12), t.lineTo(n - 6, r - 12), t.lineTo(n - 6, r - 32), t.lineTo(n + 6, r - 32), t.lineTo(n + 6, r - 12), t.lineTo(n + 16, r - 12), t.closePath(), t.fill();
1501
- const h = s.radius * (1.6 + Math.sin(i * 8) * 0.3);
1502
- 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();
1503
2406
  } else if (l === 2) {
1504
- const o = a.position.x - s.position.x, n = a.position.y - s.position.y;
1505
- if (Math.hypot(o, n) > 10) {
1506
- const h = Math.atan2(n, o);
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);
1507
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([]);
1508
- const c = a.position.x - Math.cos(h) * (a.radius + 10), u = a.position.y - Math.sin(h) * (a.radius + 10);
1509
- 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();
1510
2413
  const p = a.radius * (1.8 + Math.cos(i * 10) * 0.3);
1511
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();
1512
2415
  }
@@ -1514,7 +2417,7 @@ class nt {
1514
2417
  t.restore();
1515
2418
  }
1516
2419
  }
1517
- class ot {
2420
+ class ft {
1518
2421
  canvas;
1519
2422
  ctx;
1520
2423
  themeManager;
@@ -1522,34 +2425,34 @@ class ot {
1522
2425
  bgRenderer;
1523
2426
  tutorialArrowRenderer;
1524
2427
  constructor(t, e) {
1525
- this.canvas = t, this.ctx = t.getContext("2d"), this.themeManager = e, this.indicatorRenderer = new st(), this.bgRenderer = new at(), this.tutorialArrowRenderer = new nt();
2428
+ this.canvas = t, this.ctx = t.getContext("2d"), this.themeManager = e, this.indicatorRenderer = new gt(), this.bgRenderer = new _t(), this.tutorialArrowRenderer = new mt();
1526
2429
  }
1527
- render(t, e, i, s, a, l, o, n, r, h, c = 1, u) {
2430
+ render(t, e, i, s, a, l, n, o, r, c, h = 1, u) {
1528
2431
  if (!this.ctx) return;
1529
- const p = this.themeManager.getPalette(), { width: f, height: y } = this.canvas, d = n.getShakeOffset();
1530
- this.ctx.save(), this.ctx.translate(d.x, d.y), this.bgRenderer.render(this.ctx, f, y, t.pulsePhase, c, 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, f, y), 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, h, e, p), this.drawOrganicConsciousnessCore(t, p), this.drawFloatingTexts(o), 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();
1531
2434
  }
1532
2435
  drawToxicPools(t, e) {
1533
2436
  if (this.ctx)
1534
2437
  for (const i of t) {
1535
- const s = i.duration / i.maxDuration, a = Math.min(0.7, (1 - s) * 0.7), { x: l, y: o } = i.position;
2438
+ const s = i.duration / i.maxDuration, a = Math.min(0.7, (1 - s) * 0.7), { x: l, y: n } = i.position;
1536
2439
  this.ctx.save();
1537
- const n = this.ctx.createRadialGradient(l, o, 10, l, o, i.radius * 1.2);
1538
- 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();
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();
1539
2442
  const r = 70;
1540
- for (let h = 0; h <= r; h++) {
1541
- const c = h * Math.PI * 2 / r, 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 = o + Math.sin(c) * f;
1542
- h === 0 ? this.ctx.moveTo(y, d) : this.ctx.lineTo(y, d);
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);
1543
2446
  }
1544
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();
1545
- for (let h = 0; h <= r; h++) {
1546
- const c = h * Math.PI * 2 / r, u = Math.sin(c * 6 + e * 4) * 8, p = i.radius * 0.75 + u, f = l + Math.cos(c) * p, y = o + Math.sin(c) * p;
1547
- 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);
1548
2451
  }
1549
2452
  this.ctx.closePath(), this.ctx.stroke();
1550
- for (let h = 0; h < 6; h++) {
1551
- 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 = o + Math.sin(c) * u, y = 3 + Math.sin(e * 3 + h) * 2;
1552
- 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();
1553
2456
  }
1554
2457
  this.ctx.restore();
1555
2458
  }
@@ -1572,13 +2475,13 @@ class ot {
1572
2475
  drawGravityVortices(t, e) {
1573
2476
  if (this.ctx)
1574
2477
  for (const i of t) {
1575
- 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: o } = 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;
1576
2479
  this.ctx.save();
1577
- const n = this.ctx.createRadialGradient(l, o, 0, l, o, 60);
1578
- 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, o, 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;
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;
1579
2482
  for (let r = 1; r <= 5; r++) {
1580
- const h = a * r / 5, c = e * r * 2.2;
1581
- this.ctx.beginPath(), this.ctx.arc(l, o, h, c, c + Math.PI * 1.5), this.ctx.stroke();
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();
1582
2485
  }
1583
2486
  this.ctx.restore();
1584
2487
  }
@@ -1587,52 +2490,78 @@ class ot {
1587
2490
  if (!this.ctx) return;
1588
2491
  const a = this.ctx.createRadialGradient(t / 2, e / 2, 40, t / 2, e / 2, Math.max(t, e));
1589
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);
1590
- const l = t * 0.35 + Math.sin(i * 0.3) * 60, o = e * 0.45 + Math.cos(i * 0.25) * 50, n = this.ctx.createRadialGradient(l, o, 20, l, o, 380);
1591
- n.addColorStop(0, s.nebulaCyan), n.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = n, this.ctx.beginPath(), this.ctx.arc(l, o, 380, 0, Math.PI * 2), this.ctx.fill();
1592
- const r = t * 0.68 + Math.cos(i * 0.35) * 50, h = e * 0.55 + Math.sin(i * 0.3) * 45, c = this.ctx.createRadialGradient(r, h, 20, r, h, 420);
1593
- c.addColorStop(0, s.nebulaMagenta), c.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = c, this.ctx.beginPath(), this.ctx.arc(r, 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();
1594
2497
  }
1595
2498
  drawCoreFilaments(t, e) {
1596
2499
  if (!this.ctx) return;
1597
2500
  const i = 12;
1598
2501
  this.ctx.lineWidth = 1.5, this.ctx.strokeStyle = e.nebulaCyan;
1599
2502
  for (let s = 0; s < i; s++) {
1600
- const a = s * Math.PI * 2 / i + t.pulsePhase * 0.12, l = 85 + Math.sin(t.pulsePhase * 1.5 + s) * 25, o = t.position.x + Math.cos(a) * l, n = t.position.y + Math.sin(a) * l, r = t.position.x + Math.cos(a + 0.4) * 48, h = t.position.y + Math.sin(a + 0.4) * 48;
1601
- this.ctx.beginPath(), this.ctx.moveTo(t.position.x, t.position.y), this.ctx.quadraticCurveTo(r, h, o, n), this.ctx.stroke(), this.ctx.fillStyle = e.sporeColor, this.ctx.beginPath(), this.ctx.arc(o, 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();
1602
2505
  }
1603
2506
  }
1604
2507
  drawOrganicConsciousnessCore(t, e) {
1605
2508
  if (!this.ctx) return;
1606
2509
  const { x: i, y: s } = t.position;
1607
- for (let o = 0; o < t.integrity; o++) {
1608
- const n = t.radius + 16 + o * 12;
1609
- this.ctx.strokeStyle = e.corePrimary, this.ctx.lineWidth = 2.2, this.ctx.shadowColor = e.corePrimary, this.ctx.shadowBlur = 12, this.ctx.beginPath();
1610
- const r = 60;
1611
- for (let h = 0; h <= r; h++) {
1612
- const c = h * Math.PI * 2 / r, u = n + Math.sin(c * 4 + t.pulsePhase * 2 + o) * 3, p = i + Math.cos(c) * u, f = s + Math.sin(c) * u;
1613
- h === 0 ? this.ctx.moveTo(p, f) : this.ctx.lineTo(p, f);
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();
2515
+ for (let r = 0; r < t.integrity; r++) {
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);
1614
2522
  }
1615
2523
  this.ctx.closePath(), this.ctx.stroke();
1616
2524
  }
1617
- const a = this.ctx.createRadialGradient(i, s, 5, i, s, t.radius * 2.2);
1618
- 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();
1619
- const l = 80;
1620
- for (let o = 0; o <= l; o++) {
1621
- const n = o * Math.PI * 2 / l, r = t.getMembraneRadius(n), h = Math.cos(n) * r, c = Math.sin(n) * r;
1622
- o === 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
+ }
1623
2552
  }
1624
- 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();
1625
2554
  }
1626
2555
  drawPsionicTendril(t, e, i) {
1627
2556
  if (!this.ctx) return;
1628
2557
  this.ctx.save();
1629
2558
  const s = e.x - t.x, a = e.y - t.y;
1630
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);
1631
- const l = (t.x + e.x) / 2 + Math.sin(Date.now() * 0.02) * 16, o = (t.y + e.y) / 2 + Math.cos(Date.now() * 0.02) * 16;
1632
- this.ctx.quadraticCurveTo(l, o, 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();
1633
- for (let n = 0; n < 6; n++) {
1634
- const r = Math.random(), h = t.x + s * r + (Math.random() - 0.5) * 24, c = t.y + a * r + (Math.random() - 0.5) * 24;
1635
- 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();
1636
2565
  }
1637
2566
  this.ctx.restore();
1638
2567
  }
@@ -1640,8 +2569,8 @@ class ot {
1640
2569
  if (this.ctx)
1641
2570
  for (const a of i) {
1642
2571
  if (!a.active || a.isGrabbed || a.isThrown || a.wasManipulated || a.isDying) continue;
1643
- const l = e.x - a.position.x, o = e.y - a.position.y;
1644
- if (Math.hypot(l, o) <= a.getHitRadius()) {
2572
+ const l = e.x - a.position.x, n = e.y - a.position.y;
2573
+ if (Math.hypot(l, n) <= a.getHitRadius()) {
1645
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();
1646
2575
  break;
1647
2576
  }
@@ -1653,58 +2582,68 @@ class ot {
1653
2582
  if (!s.active) continue;
1654
2583
  let a = s.color;
1655
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);
1656
- const { x: l, y: o } = s.position;
1657
- if (this.ctx.save(), this.ctx.translate(l, o), s.wasManipulated && !s.isDying) {
1658
- const n = s.radius * 1.5 + Math.sin(e * 6) * 4;
1659
- 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();
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();
1660
2589
  const r = s.radius * 1.8 + Math.cos(e * 8) * 3;
1661
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();
1662
2591
  }
1663
2592
  if (s.isDying) {
1664
- const n = s.deathTimer / s.maxDeathTimer, r = Math.max(0, 1 - n);
2593
+ const o = s.deathTimer / s.maxDeathTimer, r = Math.max(0, 1 - o);
1665
2594
  if (this.ctx.globalAlpha = r, s.deathType === "dissolve") {
1666
- const h = s.radius * (1 - n * 0.7);
1667
- 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();
1668
- for (let c = 0; c < 4; c++) {
1669
- const u = c * Math.PI * 0.5 + n * 4, p = h * 0.8 * n;
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;
1670
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();
1671
2600
  }
1672
2601
  this.ctx.restore();
1673
2602
  continue;
1674
2603
  } else if (s.deathType === "sliced") {
1675
- 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;
1676
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();
1677
2606
  continue;
1678
2607
  }
1679
2608
  }
1680
2609
  if (this.ctx.shadowColor = a, this.ctx.shadowBlur = 16, this.ctx.fillStyle = a, s.type === "piercer") {
1681
2610
  this.ctx.rotate(s.rotation), this.ctx.beginPath();
1682
- const n = 12;
1683
- for (let r = 0; r <= n; r++) {
1684
- const h = r * 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;
1685
- r === 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, _);
1686
2615
  }
1687
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();
1688
2617
  } else if (s.type === "spore") {
1689
2618
  this.ctx.beginPath();
1690
- const n = 8;
1691
- for (let r = 0; r < n; r++) {
1692
- const h = r * 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;
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;
1693
2622
  r === 0 ? this.ctx.moveTo(u, p) : this.ctx.lineTo(u, p);
1694
2623
  }
1695
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();
1696
2625
  } else if (s.type === "cluster") {
1697
2626
  this.ctx.beginPath();
1698
- const n = Math.sin(e * 3) * 2;
1699
- 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();
1700
2629
  } else if (s.type === "parasite") {
1701
2630
  this.ctx.beginPath();
1702
- const n = 14;
1703
- for (let r = 0; r <= n; r++) {
1704
- const h = r * Math.PI * 2 / n, c = s.radius + Math.sin(h * 5 - e * 5) * 3, u = Math.cos(h) * c, p = Math.sin(h) * c;
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;
1705
2634
  r === 0 ? this.ctx.moveTo(u, p) : this.ctx.lineTo(u, p);
1706
2635
  }
1707
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
+ }
1708
2647
  } else
1709
2648
  this.ctx.beginPath(), this.ctx.arc(0, 0, s.radius, 0, Math.PI * 2), this.ctx.fill();
1710
2649
  this.ctx.restore();
@@ -1720,8 +2659,30 @@ class ot {
1720
2659
  for (const e of t)
1721
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();
1722
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
+ }
1723
2684
  }
1724
- class rt {
2685
+ class xt {
1725
2686
  container;
1726
2687
  i18n;
1727
2688
  waveLabelElement;
@@ -1753,7 +2714,7 @@ class rt {
1753
2714
  this.container.style.display = "none";
1754
2715
  }
1755
2716
  }
1756
- class ht {
2717
+ class Et {
1757
2718
  container;
1758
2719
  i18n;
1759
2720
  onStartCallback;
@@ -1779,7 +2740,7 @@ class ht {
1779
2740
  this.container.style.display = "none";
1780
2741
  }
1781
2742
  }
1782
- class lt {
2743
+ class yt {
1783
2744
  modal;
1784
2745
  card;
1785
2746
  i18n;
@@ -1790,8 +2751,8 @@ class lt {
1790
2751
  hapticsEnabled = !0;
1791
2752
  constructor(t, e, i, s, a, l) {
1792
2753
  this.i18n = e, this.themeManager = i, this.platform = s, this.onLanguageChangedCallback = a, this.onCloseCallback = l;
1793
- const o = localStorage.getItem("axon_surge_haptics");
1794
- o !== null && (this.hapticsEnabled = o === "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", () => {
1795
2756
  this.onCloseCallback && this.onCloseCallback();
1796
2757
  }), this.renderContent();
1797
2758
  }
@@ -1824,74 +2785,74 @@ class lt {
1824
2785
  ko: "한국어 (KO)",
1825
2786
  zh: "中文 (ZH)"
1826
2787
  };
1827
- for (const E of K) {
1828
- const g = document.createElement("option");
1829
- g.value = E, g.textContent = l[E], this.i18n.getLanguage() === E && (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);
1830
2791
  }
1831
2792
  a.addEventListener("change", () => {
1832
- const E = a.value;
1833
- this.i18n.setLanguage(E), this.onLanguageChangedCallback && this.onLanguageChangedCallback(E), this.renderContent();
2793
+ const m = a.value;
2794
+ this.i18n.setLanguage(m), this.onLanguageChangedCallback && this.onLanguageChangedCallback(m), this.renderContent();
1834
2795
  });
1835
- const o = document.createElement("span");
1836
- o.className = "axon-select-arrow", o.textContent = "▼", s.appendChild(a), s.appendChild(o), e.appendChild(i), e.appendChild(s);
1837
- const n = document.createElement("div");
1838
- n.className = "axon-setting-row";
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";
1839
2800
  const r = document.createElement("span");
1840
2801
  r.textContent = this.i18n.translate("themeLabel");
1841
- const h = document.createElement("div");
1842
- h.className = "axon-toggle-group";
1843
- const c = [
2802
+ const c = document.createElement("div");
2803
+ c.className = "axon-toggle-group";
2804
+ const h = [
1844
2805
  { id: "bioluminescent", label: "BIO" },
1845
2806
  { id: "dark", label: "DARK" },
1846
2807
  { id: "light", label: "LIGHT" }
1847
2808
  ];
1848
- for (const E of c) {
1849
- const g = document.createElement("button");
1850
- g.type = "button", g.className = `axon-toggle-btn ${this.themeManager.getTheme() === E.id ? "active" : ""}`, g.textContent = E.label, g.addEventListener("click", () => {
1851
- this.themeManager.setTheme(E.id), this.renderContent();
1852
- }), 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);
1853
2814
  }
1854
- n.appendChild(r), n.appendChild(h);
2815
+ o.appendChild(r), o.appendChild(c);
1855
2816
  const u = document.createElement("div");
1856
2817
  u.className = "axon-setting-row";
1857
2818
  const p = document.createElement("span");
1858
2819
  p.textContent = this.i18n.translate("hapticsLabel");
1859
- const f = document.createElement("div");
1860
- f.className = "axon-toggle-group";
1861
- const y = [
2820
+ const _ = document.createElement("div");
2821
+ _.className = "axon-toggle-group";
2822
+ const d = [
1862
2823
  { enabled: !0, label: this.i18n.translate("hapticsOn") },
1863
2824
  { enabled: !1, label: this.i18n.translate("hapticsOff") }
1864
2825
  ];
1865
- for (const E of y) {
1866
- const g = document.createElement("button");
1867
- g.type = "button", g.className = `axon-toggle-btn ${this.hapticsEnabled === E.enabled ? "active" : ""}`, g.textContent = E.label, g.addEventListener("click", () => {
1868
- this.hapticsEnabled = E.enabled, localStorage.setItem("axon_surge_haptics", String(E.enabled)), this.hapticsEnabled && this.platform.haptics.selectionChanged(), this.renderContent();
1869
- }), f.appendChild(g);
1870
- }
1871
- u.appendChild(p), u.appendChild(f);
1872
- const d = document.createElement("div");
1873
- d.className = "axon-setting-row";
1874
- const m = document.createElement("span");
1875
- 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");
1876
2837
  const x = document.createElement("div");
1877
2838
  x.className = "axon-toggle-group";
1878
- const S = localStorage.getItem("axon_surge_show_tutorial") !== "false", v = [
2839
+ const b = localStorage.getItem("axon_surge_show_tutorial") !== "false", v = [
1879
2840
  { enabled: !0, label: this.i18n.translate("hapticsOn") },
1880
2841
  { enabled: !1, label: this.i18n.translate("hapticsOff") }
1881
2842
  ];
1882
- for (const E of v) {
1883
- const g = document.createElement("button");
1884
- g.type = "button", g.className = `axon-toggle-btn ${S === E.enabled ? "active" : ""}`, g.textContent = E.label, g.addEventListener("click", () => {
1885
- localStorage.setItem("axon_surge_show_tutorial", String(E.enabled)), this.renderContent();
1886
- }), x.appendChild(g);
1887
- }
1888
- d.appendChild(m), d.appendChild(x);
1889
- const b = document.createElement("div");
1890
- b.className = "axon-settings-credits", b.textContent = this.i18n.translate("creditsJam");
1891
- const M = document.createElement("button");
1892
- 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", () => {
1893
2854
  this.modal.close();
1894
- }), 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);
1895
2856
  }
1896
2857
  isHapticsEnabled() {
1897
2858
  return this.hapticsEnabled;
@@ -1903,8 +2864,8 @@ class lt {
1903
2864
  this.modal.close();
1904
2865
  }
1905
2866
  }
1906
- const B = "axon_surge_show_tutorial";
1907
- class ct {
2867
+ const W = "axon_surge_show_tutorial";
2868
+ class At {
1908
2869
  isActive = !1;
1909
2870
  showWarning = !1;
1910
2871
  dummyLauncher = null;
@@ -1913,14 +2874,14 @@ class ct {
1913
2874
  initialTargetPos = { x: 0, y: 0 };
1914
2875
  isTutorialEnabled() {
1915
2876
  try {
1916
- return localStorage.getItem(B) !== "false";
2877
+ return localStorage.getItem(W) !== "false";
1917
2878
  } catch {
1918
2879
  return !0;
1919
2880
  }
1920
2881
  }
1921
2882
  setTutorialEnabled(t) {
1922
2883
  try {
1923
- localStorage.setItem(B, String(t));
2884
+ localStorage.setItem(W, String(t));
1924
2885
  } catch {
1925
2886
  }
1926
2887
  }
@@ -1938,11 +2899,11 @@ class ct {
1938
2899
  this.isActive = !1;
1939
2900
  return;
1940
2901
  }
1941
- 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 = L.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(
1942
2903
  "piercer",
1943
2904
  this.initialLauncherPos,
1944
2905
  this.initialTargetPos
1945
- ), this.dummyLauncher.velocity = { x: 0, y: 0 }, this.dummyTarget = L.createEnemy(
2906
+ ), this.dummyLauncher.velocity = { x: 0, y: 0 }, this.dummyTarget = T.createEnemy(
1946
2907
  "spore",
1947
2908
  this.initialTargetPos,
1948
2909
  this.initialLauncherPos
@@ -1950,27 +2911,27 @@ class ct {
1950
2911
  }
1951
2912
  update(t, e, i, s, a, l) {
1952
2913
  if (!this.isActive || !this.dummyLauncher || !this.dummyTarget) return;
1953
- const o = this.dummyLauncher, n = this.dummyTarget;
1954
- e.includes(o) || e.push(o), e.includes(n) || e.push(n);
1955
- const r = n.position.x - o.position.x, h = n.position.y - o.position.y, c = Math.hypot(r, h);
1956
- if (o.isGrabbed) {
1957
- if (this.showWarning = !1, c <= o.radius + n.radius + 60) {
1958
- l && l(), o.isGrabbed = !1, this.showWarning = !0, this.resetDummies(o, 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);
1959
2920
  return;
1960
2921
  }
1961
2922
  return;
1962
2923
  }
1963
- if (o.wasManipulated) {
1964
- const u = Math.hypot(o.velocity.x, o.velocity.y);
1965
- if (!o.isThrown || u < 70) {
1966
- l && l(), this.showWarning = !0, this.resetDummies(o, 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);
1967
2928
  return;
1968
2929
  }
1969
- if (c <= o.getHitRadius() + n.getHitRadius()) {
1970
- o.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();
1971
2932
  return;
1972
2933
  }
1973
- (o.position.x < -60 || o.position.x > i + 60 || o.position.y < -60 || o.position.y > s + 60 || u < 40) && (l && l(), this.showWarning = !0, this.resetDummies(o, 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));
1974
2935
  }
1975
2936
  }
1976
2937
  resetDummies(t, e) {
@@ -1980,7 +2941,7 @@ class ct {
1980
2941
  this.isActive = !1, this.showWarning = !1;
1981
2942
  }
1982
2943
  }
1983
- class dt {
2944
+ class bt {
1984
2945
  container;
1985
2946
  i18n;
1986
2947
  tutorialManager;
@@ -2016,7 +2977,7 @@ class dt {
2016
2977
  this.container.style.display = "none";
2017
2978
  }
2018
2979
  }
2019
- class ut {
2980
+ class vt {
2020
2981
  fillElement;
2021
2982
  killsCount = 0;
2022
2983
  currentLevel = 1;
@@ -2027,7 +2988,7 @@ class ut {
2027
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);
2028
2989
  }
2029
2990
  getKillsRequiredForLevel(t) {
2030
- return 16 + (t - 1) * 6;
2991
+ return t === 1 ? 3 : t === 2 ? 6 : t === 3 ? 10 : 10 + (t - 3) * 6;
2031
2992
  }
2032
2993
  addKill() {
2033
2994
  this.killsCount++;
@@ -2047,7 +3008,313 @@ class ut {
2047
3008
  this.fillElement && this.fillElement.parentElement && (this.fillElement.parentElement.style.display = "none");
2048
3009
  }
2049
3010
  }
2050
- class pt {
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 {
2051
3318
  haptics = {
2052
3319
  impact: async (t) => {
2053
3320
  if ("vibrate" in navigator) {
@@ -2087,7 +3354,7 @@ class pt {
2087
3354
  }
2088
3355
  };
2089
3356
  }
2090
- class mt {
3357
+ class It {
2091
3358
  container;
2092
3359
  canvas;
2093
3360
  i18n;
@@ -2114,12 +3381,15 @@ class mt {
2114
3381
  shockwaves = [];
2115
3382
  particles = [];
2116
3383
  floatingTexts = [];
3384
+ orbitingOrbs = [];
3385
+ isLevelUpActive = !1;
3386
+ hasRerolledThisLevel = !1;
2117
3387
  score = { value: 0 };
2118
3388
  combo = { value: 0 };
2119
3389
  isRunning = !1;
2120
3390
  isPaused = !1;
2121
3391
  constructor(t) {
2122
- this.container = t.root, this.container.classList.add("axon-game-root"), this.i18n = new $(t.language), this.themeManager = new it(t.theme, this.container), this.platform = t.platform || new pt(), 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 V(), this.core = new Y(this.canvas.width / 2, this.canvas.height / 2), this.inputManager = new J(this.canvas), this.physicsEngine = new Q(this.eventBus, this.i18n), this.waveDirector = new et(), this.renderer = new ot(this.canvas, this.themeManager), this.juice = new X(), this.settingsModal = new lt(
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(
2123
3393
  this.container,
2124
3394
  this.i18n,
2125
3395
  this.themeManager,
@@ -2128,11 +3398,11 @@ class mt {
2128
3398
  () => {
2129
3399
  this.isPaused = !1;
2130
3400
  }
2131
- ), this.interactiveTutorial = new ct(), this.tutorialOverlay = new dt(this.container, this.i18n, this.interactiveTutorial), this.hud = new rt(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, () => {
2132
3402
  this.isPaused = !0, this.settingsModal.show();
2133
- }), this.hud.show(), this.progressBar = new ut(this.hud.progressSlot, (e) => {
2134
- this.waveDirector.wave = e;
2135
- }), this.startMenu = new ht(this.container, this.i18n, () => this.startGame()), this.initAmbientArena(), this.gameLoop = new F(
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(
2136
3406
  (e) => this.update(e),
2137
3407
  () => this.render()
2138
3408
  ), this.setupEvents(), this.gameLoop.start();
@@ -2159,11 +3429,11 @@ class mt {
2159
3429
  const i = t[e % t.length], s = e * Math.PI * 2 / 16, a = 180 + Math.random() * 220, l = {
2160
3430
  x: this.canvas.width / 2 + Math.cos(s) * a,
2161
3431
  y: this.canvas.height / 2 + Math.sin(s) * a
2162
- }, o = L.createEnemy(i, l, {
3432
+ }, n = T.createEnemy(i, l, {
2163
3433
  x: l.x + Math.sin(s) * 100,
2164
3434
  y: l.y - Math.cos(s) * 100
2165
3435
  });
2166
- this.ambientEnemies.push(o);
3436
+ this.ambientEnemies.push(n);
2167
3437
  }
2168
3438
  }
2169
3439
  resizeCanvas() {
@@ -2209,7 +3479,7 @@ class mt {
2209
3479
  },
2210
3480
  () => this.inputManager.forceRelease()
2211
3481
  ), this.tutorialOverlay.updateStep(this.interactiveTutorial.getStep());
2212
- else {
3482
+ else if (!this.isLevelUpActive) {
2213
3483
  const e = this.waveDirector.update(
2214
3484
  t,
2215
3485
  this.enemies,
@@ -2219,6 +3489,53 @@ class mt {
2219
3489
  );
2220
3490
  e && this.enemies.push(e);
2221
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
+ }
2222
3539
  this.juice.hitstopTime <= 0 && this.physicsEngine.update(
2223
3540
  t,
2224
3541
  this.core,
@@ -2233,9 +3550,75 @@ class mt {
2233
3550
  this.score,
2234
3551
  this.canvas.width,
2235
3552
  this.canvas.height,
2236
- () => 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
+ }
2237
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);
2238
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
+ }
2239
3622
  render() {
2240
3623
  const t = this.isRunning ? this.enemies : this.ambientEnemies;
2241
3624
  this.renderer.render(
@@ -2251,20 +3634,20 @@ class mt {
2251
3634
  this.inputManager.pointerPosition,
2252
3635
  this.progressBar.getLevel(),
2253
3636
  this.interactiveTutorial.isActive ? this.interactiveTutorial : void 0
2254
- );
3637
+ ), this.isLevelUpActive && this.orbitingOrbs.length > 0 && this.renderer.drawOrbitingModifierOrbs(this.orbitingOrbs, this.core.pulsePhase, this.i18n, !this.hasRerolledThisLevel);
2255
3638
  }
2256
3639
  destroy() {
2257
3640
  this.gameLoop.stop(), this.canvas.remove();
2258
3641
  }
2259
3642
  }
2260
- function gt(T) {
2261
- return new mt(T);
3643
+ function Mt(E) {
3644
+ return new It(E);
2262
3645
  }
2263
3646
  export {
2264
- pt as BrowserPlatform,
2265
- mt as GameEngine,
2266
- K as LANGUAGES,
2267
- it as ThemeManager,
2268
- gt as createAxonSurge,
2269
- P 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
2270
3653
  };