@minicode-dev/chat 0.1.10 → 0.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -211,6 +211,22 @@ it is responsible for upload permissions, storage and preserving images used in
211
211
  The local demo includes a session-only image uploader (PNG/JPG/WebP/GIF, up to 256 KB
212
212
  and 2048 × 2048) and an example image. Open **Nuevas funciones** to try it.
213
213
 
214
+ ## Countdown messages
215
+
216
+ Open **✨ → Cuenta regresiva**, choose a quick duration button or a custom duration in seconds or minutes
217
+ (up to 24 hours), select the final effect (pig, confetti or nudge), and choose
218
+ whether to include its sound. **Probar efecto** previews the selection without sending.
219
+ Send it to display a live countdown in the conversation. The card hides the chosen
220
+ effect until zero; quotes and conversation previews also keep the surprise.
221
+ The last ten seconds animate; at zero, the visible conversation plays the selected
222
+ effect, respecting automatic playback, sound preferences and reduced motion.
223
+
224
+ Countdowns use ordinary text messages with a separate `[minicode-countdown:v1]`
225
+ payload containing an absolute deadline. No backend change is needed. Both clients
226
+ need this library version for the countdown UI; older clients show readable fallback
227
+ text. Device clocks should be accurate. Closed or hidden conversations do not play
228
+ the deadline effect; expired cards offer manual replay on return.
229
+
214
230
  ## Zumbidos and animated effects
215
231
 
216
232
  The chat includes a nudge, a dancing pig and confetti with approved audio recordings.
@@ -585,7 +585,7 @@ function Z({ gameKey: n, currentUserId: r, onMinimize: i, onDismiss: d, suspende
585
585
  }, r = () => {
586
586
  e || (t = q(T.current, n), D.current = t, F("2d"));
587
587
  };
588
- return j ? r() : import("./createLiveScene-GkalLsqm.js").then(({ createLiveScene: i }) => {
588
+ return j ? r() : import("./createLiveScene-CJQtq54t.js").then(({ createLiveScene: i }) => {
589
589
  if (!e) try {
590
590
  t = i(T.current, n), D.current = t, F("3d");
591
591
  } catch {
@@ -686,36 +686,51 @@ function Z({ gameKey: n, currentUserId: r, onMinimize: i, onDismiss: d, suspende
686
686
  }
687
687
  });
688
688
  return /* @__PURE__ */ v("section", {
689
- className: "chat-game-card tl-card",
689
+ className: `chat-game-card tl-card${I ? " tl-card--active" : ""}`,
690
690
  "aria-label": "Tanques LIVE 3D",
691
691
  children: [
692
692
  /* @__PURE__ */ v("header", {
693
693
  className: "tl-header",
694
+ children: [/* @__PURE__ */ _("strong", { children: "Tanques LIVE 3D" }), /* @__PURE__ */ v("div", {
695
+ className: "tl-header-actions",
696
+ children: [
697
+ /* @__PURE__ */ _(t, { manager: u() }),
698
+ i && /* @__PURE__ */ _("button", {
699
+ onClick: i,
700
+ "aria-label": "Minimizar",
701
+ children: "−"
702
+ }),
703
+ d && /* @__PURE__ */ _("button", {
704
+ onClick: d,
705
+ "aria-label": "Ocultar",
706
+ children: "×"
707
+ })
708
+ ]
709
+ })]
710
+ }),
711
+ C.status === "invited" && /* @__PURE__ */ v("div", {
712
+ className: "tl-invite",
694
713
  children: [
695
- /* @__PURE__ */ _("strong", { children: "Tanques LIVE 3D" }),
696
- /* @__PURE__ */ _(t, { manager: u() }),
697
- i && /* @__PURE__ */ _("button", {
698
- onClick: i,
699
- "aria-label": "Minimizar",
700
- children: "−"
714
+ /* @__PURE__ */ _("span", {
715
+ className: "tl-invite-icon",
716
+ "aria-hidden": "true",
717
+ children: "🪖"
701
718
  }),
702
- d && /* @__PURE__ */ _("button", {
703
- onClick: d,
704
- "aria-label": "Ocultar",
705
- children: "×"
719
+ /* @__PURE__ */ _("strong", { children: z ? "¿Listo para combatir?" : "Invitación enviada" }),
720
+ /* @__PURE__ */ _("p", { children: z ? "Te invitaron a un combate en tiempo real." : "Esperando que el rival acepte…" }),
721
+ z && /* @__PURE__ */ v("div", {
722
+ className: "tl-invite-actions",
723
+ children: [/* @__PURE__ */ _("button", {
724
+ className: "tl-button-primary",
725
+ onClick: () => Y(n, "game_accept"),
726
+ children: "Aceptar combate"
727
+ }), /* @__PURE__ */ _("button", {
728
+ onClick: () => Y(n, "game_decline"),
729
+ children: "Rechazar"
730
+ })]
706
731
  })
707
732
  ]
708
733
  }),
709
- C.status === "invited" && /* @__PURE__ */ v("div", {
710
- className: "tl-invite",
711
- children: [/* @__PURE__ */ _("p", { children: z ? "Te invitaron a un combate en tiempo real." : "Esperando que el rival acepte…" }), z && /* @__PURE__ */ v(g, { children: [/* @__PURE__ */ _("button", {
712
- onClick: () => Y(n, "game_accept"),
713
- children: "Aceptar"
714
- }), /* @__PURE__ */ _("button", {
715
- onClick: () => Y(n, "game_decline"),
716
- children: "Rechazar"
717
- })] })]
718
- }),
719
734
  (I || k) && /* @__PURE__ */ v(g, { children: [
720
735
  /* @__PURE__ */ v("div", {
721
736
  className: "tl-hud",
@@ -884,9 +899,12 @@ function Z({ gameKey: n, currentUserId: r, onMinimize: i, onDismiss: d, suspende
884
899
  role: "alert",
885
900
  children: C.error
886
901
  }),
887
- !["closed", "declined"].includes(C.status) && /* @__PURE__ */ _("button", {
888
- onClick: () => Y(n, "game_end"),
889
- children: "Cerrar partida"
902
+ !["closed", "declined"].includes(C.status) && /* @__PURE__ */ _("footer", {
903
+ className: "tl-footer",
904
+ children: /* @__PURE__ */ _("button", {
905
+ onClick: () => Y(n, "game_end"),
906
+ children: "Cerrar partida"
907
+ })
890
908
  })
891
909
  ]
892
910
  });
@@ -894,4 +912,4 @@ function Z({ gameKey: n, currentUserId: r, onMinimize: i, onDismiss: d, suspende
894
912
  var Q = d(Z);
895
913
  export { U as a, V as c, Q as default, R as i, W as l, P as n, z as o, I as r, B as s, J as t };
896
914
 
897
- //# sourceMappingURL=TanksLiveGameCard-BxQGR8P9.js.map
915
+ //# sourceMappingURL=TanksLiveGameCard-BNJqWt1z.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TanksLiveGameCard-BxQGR8P9.js","names":["_Fragment","useChatGames","GameSoundControls","decodeSignal","createPeerLink","encodeSignal","ChatContext","stopAllTanksLoops","startTanksSounds","handleSceneEvent","playOutcome","getTanksSoundManager","__defProp","__exportAll","target","name","all","no_symbols","connectionDiagnostics","net","connectionHint","RULES","clamp","lo","hi","n","angleDelta","b","a","createArena","x","z","r","i","createTank","id","index","validPosition","arena","radius","o","moveTank","tank","throttle","input","steer","dt","segmentCircle","dx","bx","ax","dz","bz","az","length","t","cx","cz","advanceShell","shell","first","tanks","interpolatePose","fraction","finite","idValid","createLiveMatch","selfId","game","ids","turnConfigured","iceServers","server","url","peerId","shells","events","time","sendAt","round","sequence","status","winner","destroyed","wasConnected","pendingResign","endReason","poses","lastPoseAt","lastPose","lastFire","seen","wantsRematch","me","other","notify","onChange","emit","send","link","e","remember","key","snapshot","reset","finish","force","fire","owner","shot","broadcast","receiveMove","data","yaw","turretYaw","speed","elapsed","previous","pose","receiveEvent","isHost","hp","validPlaying","validOver","maybeRematch","s","peerFactory","signaling","signal","text","scoped","frame","listener","previousPhase","state","resumed","next","dtMs","renderTime","remaining","hz","hit","out","RAD_TO_DEG","num","value","fallback","arenaBounds","withSize","w","d","box","arenaObstacles","eventKind","event","shooterOf","list","found","best","bestD","tankById","selfTank","damageLevel","alive","wrapAngle","v","createSelfTracker","last","moving","turning","moveIdle","turnIdle","hull","turret","isMoving","moveSpeed","turnSpeed","holdMs","isTurning","soundEventsFor","outcomeFor","render","createLiveScene2d","canvas","container","ctx","bounds","h","scale","ox","oz","resize","dpr","ro","nx","ny","obstacle","TanksLiveGameCard_exports","TanksLiveGameCard_default","act","type","stopInput","TanksLiveGameCard","rtcOptions","useContext","gameKey","suspendedRef","useRef","suspended","stage","match","renderer","view","setView","useState","error","setError","prefer2d","setPrefer2d","mode","setMode","active","setArena","useEffect","disposed","scene","options","createLiveScene","published","outcome","tracker","keys","session","currentUserId","clear","down","up","host","visibility","tick","now","paused","sound","nextOutcome","guest","over","aim","rect","ground","hold","field","onMinimize","onDismiss","Fragment","memo"],"sources":["../../src/games/tanks-live/net/connectionDiagnostics.js","../../src/games/tanks-live/logic/simulation.js","../../src/games/tanks-live/net/createLiveMatch.js","../../src/games/tanks-live/scene/liveView.js","../../src/games/tanks-live/scene/createLiveScene2d.js","../../src/games/tanks-live/TanksLiveGameCard.jsx"],"sourcesContent":["// Deliberately excludes SDP, ICE addresses, account IDs and TURN credentials.\nexport function connectionDiagnostics(net = {}) {\n return {\n phase: net.phase ?? 'idle', ice: net.ice ?? 'new',\n connection: net.connection ?? 'new', gathering: net.gathering ?? 'new',\n signaling: {\n sent: net.signals?.sent ?? 0, received: net.signals?.received ?? 0,\n sendFailures: net.signals?.sendFailures ?? 0,\n ignored: net.signals?.ignored ?? 0, invalid: net.signals?.invalid ?? 0,\n retransmits: net.signals?.retransmits ?? 0,\n },\n turnConfigured: Boolean(net.turnConfigured),\n route: net.route?.label ?? null,\n movesSent: net.move?.sent ?? 0, movesReceived: net.move?.received ?? 0,\n error: net.error ? (/^[a-z_]+$/.test(net.error) ? net.error : 'negotiation_error') : null,\n };\n}\n\nexport function connectionHint(net = {}) {\n if (net.phase === 'connected') return '';\n if (net.signals?.sendFailures) return 'No se pudieron enviar señales por el chat. Revisa la conexión WebSocket y reintenta.';\n if (net.ice === 'checking' || net.ice === 'failed') return net.turnConfigured\n ? 'WebRTC aún no encuentra una ruta entre los jugadores. Revisa el servicio TURN y la red.'\n : 'WebRTC aún no encuentra una ruta entre los jugadores. Algunas redes necesitan un servidor TURN; esta partida no tiene uno configurado.';\n if (net.phase === 'listening') return 'Esperando la conexión del rival. Ambos deben mantener abierta la partida y usar la misma versión del chat.';\n if (net.phase === 'failed') return 'No se pudo conectar. Revisa el diagnóstico de ambos jugadores y reintenta.';\n return 'Intercambiando señales de conexión por el chat. El combate empieza cuando conecta WebRTC.';\n}\n","// Deterministic arcade simulation. Angles are radians, forward is +x.\nexport const RULES = Object.freeze({ speed: 16, reverse: 9, turn: 1.8, acceleration: 28, radius: 2, reloadMs: 1500, shellSpeed: 60, damage: 25 });\nexport const clamp = (n, lo, hi) => Math.max(lo, Math.min(hi, n));\nexport const angleDelta = (a, b) => Math.atan2(Math.sin(b - a), Math.cos(b - a));\nexport function createArena() {\n return { size: 120, bounds: { minX: 0, maxX: 120, minZ: 0, maxZ: 120 }, obstacles: [\n [42, 35, 4], [78, 85, 4], [60, 30, 3], [60, 90, 3], [35, 65, 3], [85, 55, 3], [60, 60, 5],\n ].map(([x, z, r], i) => ({ x, z, r, kind: i % 2 ? 'tree' : 'rock' })) };\n}\nexport function createTank(id, index) { return { id: String(id), x: index ? 102 : 18, z: 60, yaw: index ? Math.PI : 0, turretYaw: index ? Math.PI : 0, speed: 0, hp: 100, alive: true, color: index ? '#d7463f' : '#54a34a' }; }\nexport function validPosition(x, z, arena, radius = RULES.radius) {\n const b = arena.bounds;\n return x >= b.minX + radius && x <= b.maxX - radius && z >= b.minZ + radius && z <= b.maxZ - radius\n && !arena.obstacles.some(o => Math.hypot(x - o.x, z - o.z) < o.r + radius);\n}\nexport function moveTank(tank, input, dt, arena) {\n if (!tank.alive) return;\n const throttle = clamp(Number(input.throttle) || 0, -1, 1), steer = clamp(Number(input.steer) || 0, -1, 1);\n const target = throttle * (throttle < 0 ? RULES.reverse : RULES.speed);\n tank.speed += clamp(target - tank.speed, -RULES.acceleration * dt, RULES.acceleration * dt);\n tank.yaw += steer * RULES.turn * dt;\n if (Number.isFinite(input.turretYaw)) tank.turretYaw = input.turretYaw;\n const x = tank.x + Math.cos(tank.yaw) * tank.speed * dt, z = tank.z + Math.sin(tank.yaw) * tank.speed * dt;\n if (validPosition(x, tank.z, arena)) tank.x = x; else tank.speed = 0;\n if (validPosition(tank.x, z, arena)) tank.z = z; else tank.speed = 0;\n}\nexport function segmentCircle(ax, az, bx, bz, cx, cz, radius) {\n const dx = bx - ax, dz = bz - az, length = dx * dx + dz * dz;\n const t = length ? clamp(((cx - ax) * dx + (cz - az) * dz) / length, 0, 1) : 0;\n return Math.hypot(ax + dx * t - cx, az + dz * t - cz) <= radius ? t : null;\n}\nexport function advanceShell(shell, dt, arena, tanks) {\n const x = shell.x + Math.cos(shell.yaw) * RULES.shellSpeed * dt, z = shell.z + Math.sin(shell.yaw) * RULES.shellSpeed * dt;\n let first = null;\n for (const o of arena.obstacles) { const t = segmentCircle(shell.x, shell.z, x, z, o.x, o.z, o.r); if (t !== null && (!first || t < first.t)) first = { t, kind: 'obstacle' }; }\n for (const tank of tanks) { if (!tank.alive || tank.id === shell.owner) continue; const t = segmentCircle(shell.x, shell.z, x, z, tank.x, tank.z, RULES.radius); if (t !== null && (!first || t < first.t)) first = { t, kind: 'tank', target: tank.id }; }\n if (first) { shell.x += (x - shell.x) * first.t; shell.z += (z - shell.z) * first.t; return first; }\n shell.x = x; shell.z = z; shell.age += dt;\n return !validPosition(x, z, { ...arena, obstacles: [] }, 0) || shell.age > 3 ? { kind: 'terrain' } : null;\n}\nexport function interpolatePose(a, b, fraction) {\n const t = clamp(fraction, 0, 1);\n return { ...b, x: a.x + (b.x - a.x) * t, z: a.z + (b.z - a.z) * t, yaw: a.yaw + angleDelta(a.yaw, b.yaw) * t, turretYaw: a.turretYaw + angleDelta(a.turretYaw, b.turretYaw) * t };\n}\n","import { decodeSignal, encodeSignal } from '../../../net/webrtc/protocol.js';\nimport { createPeerLink } from '../../../net/webrtc/createPeerLink.js';\nimport { RULES, createArena, createTank, moveTank, advanceShell, validPosition, interpolatePose } from '../logic/simulation.js';\n\nconst finite = n => typeof n === 'number' && Number.isFinite(n);\nconst idValid = id => typeof id === 'string' && id.length > 0 && id.length < 160;\nexport function createLiveMatch({ game, selfId, isHost = String(selfId) === String(game.hostId), signaling, onChange = () => {}, peerFactory = createPeerLink, iceServers, iceTransportPolicy, RTCPeerConnectionImpl } = {}) {\n selfId = String(selfId);\n const ids = [String(game.hostId), String(game.guestId)];\n if (!ids.includes(selfId) || ids[0] === ids[1]) throw new Error('Invalid live match players');\n const turnConfigured = (iceServers || []).some(server => [server.urls].flat().some(url => /^turns?:/i.test(String(url))));\n const peerId = ids.find(id => id !== selfId), arena = createArena();\n let tanks = ids.map(createTank), shells = [], events = [], input = {}, time = 0, sendAt = 0, round = 0, sequence = 0;\n let status = 'connecting', winner = null, destroyed = false, net = { phase: 'idle', rtt: null, route: null }, wasConnected = false, pendingResign = false, endReason = null;\n let poses = [], lastPoseAt = null, lastPose = null, lastFire = new Map(), seen = new Set(), wantsRematch = new Set();\n const me = () => tanks.find(t => t.id === selfId), other = () => tanks.find(t => t.id === peerId);\n const notify = () => { if (!destroyed) onChange({ status, winner, net }); };\n const emit = e => { events.push(e); if (events.length > 200) events.shift(); };\n const send = e => link.sendEvent({ ...e, g: game.gameId, r: round });\n const remember = key => { seen.add(key); if (seen.size > 2048) seen.delete(seen.values().next().value); };\n const snapshot = () => ({ k: 'snapshot', hp: tanks.map(t => t.hp), status, winner, reason: endReason });\n function reset() {\n tanks = ids.map(createTank); shells = []; poses = []; lastPoseAt = null; lastPose = null; lastFire.clear(); seen.clear(); wantsRematch.clear(); pendingResign = false; endReason = null; winner = null; status = net.phase === 'connected' ? 'playing' : 'connecting'; emit({ k: 'rematch' }); notify();\n }\n function finish(id, force = false) { if (status === 'over' && (!force || winner === id)) return; status = 'over'; winner = id; shells = []; emit({ k: 'over', winner }); notify(); }\n function fire(owner, e, broadcast) {\n if (status !== 'playing' || !idValid(e.id) || seen.has(e.id)) return false;\n const tank = tanks.find(t => t.id === owner);\n if (!tank?.alive || time - (lastFire.get(owner) ?? -Infinity) < RULES.reloadMs - 20) return false;\n if (![e.x, e.z, e.yaw].every(finite) || Math.hypot(e.x - (owner === peerId && lastPose ? lastPose.x : tank.x), e.z - (owner === peerId && lastPose ? lastPose.z : tank.z)) > 6) return false;\n remember(e.id);\n lastFire.set(owner, time);\n const shot = { ...e, k: 'fire', owner, x: e.x + Math.cos(e.yaw) * 2.8, z: e.z + Math.sin(e.yaw) * 2.8, y: 1.4, age: 0 };\n shells.push(shot); emit(shot); if (broadcast) send({ ...e, k: 'fire' }); return true;\n }\n function receiveMove(data) {\n if (destroyed || status !== 'playing' || data?.g !== game.gameId || data.r !== round || !Array.isArray(data.p) || data.p.length !== 5 || !data.p.every(finite)) return;\n const [x, z, yaw, turretYaw, speed] = data.p;\n if (!validPosition(x, z, arena) || Math.abs(speed) > RULES.speed + 0.1 || Math.abs(yaw) > 1e6 || Math.abs(turretYaw) > 1e6) return;\n const elapsed = lastPoseAt === null ? 0.1 : Math.max(0, (time - lastPoseAt) / 1000);\n const previous = lastPose || other();\n if (Math.hypot(x - previous.x, z - previous.z) > RULES.speed * elapsed + 3) return;\n const pose = { ...other(), x, z, yaw, turretYaw, speed };\n lastPose = pose; lastPoseAt = time; poses.push({ time, pose }); if (poses.length > 30) poses.shift();\n }\n function receiveEvent(e) {\n if (destroyed || !e || e.g !== game.gameId || !Number.isInteger(e.r)) return;\n if (e.k === 'round' && !isHost && status === 'over' && wantsRematch.has(selfId) && e.r === round + 1) { round = e.r; reset(); return; }\n if (e.r !== round) return;\n if (e.k === 'sync' && isHost) { send(snapshot()); return; }\n if (e.k === 'snapshot' && !isHost && Array.isArray(e.hp) && e.hp.length === 2 && e.hp.every(hp => Number.isInteger(hp) && hp >= 0 && hp <= 100)) {\n const validPlaying = e.status === 'playing' && e.winner === null && e.hp.every(hp => hp > 0);\n const validOver = e.status === 'over' && ids.includes(e.winner) && (e.hp[1 - ids.indexOf(e.winner)] === 0 || e.reason === 'resigned');\n if (!validPlaying && !validOver) return;\n tanks.forEach((t, i) => { t.hp = e.hp[i]; t.alive = t.hp > 0; });\n if (validOver) { pendingResign = false; endReason = e.reason; finish(e.winner, true); }\n return;\n }\n if (e.k === 'resign') { endReason = 'resigned'; finish(selfId, isHost); if (isHost) send(snapshot()); return; }\n if (e.k === 'rematch' && status === 'over') { wantsRematch.add(peerId); maybeRematch(); return; }\n if (status !== 'playing') return;\n if (e.k === 'fire') fire(peerId, e, false);\n if (!isHost && e.k === 'hit' && idValid(e.id) && !seen.has(`hit:${e.id}`) && ids.includes(e.target) && Array.isArray(e.hp) && e.hp.length === 2 && e.hp.every((hp, i) => Number.isInteger(hp) && hp >= 0 && hp <= tanks[i].hp) && [e.x, e.z].every(finite)) {\n remember(`hit:${e.id}`); tanks.forEach((tank, i) => { tank.hp = e.hp[i]; tank.alive = tank.hp > 0; }); shells = shells.filter(s => s.id !== e.id); emit(e);\n }\n if (!isHost && e.k === 'destroyed' && ids.includes(e.target) && !seen.has(`destroyed:${e.target}`) && tanks.find(t => t.id === e.target).hp === 0) { remember(`destroyed:${e.target}`); emit(e); }\n if (!isHost && e.k === 'over' && ids.includes(e.winner) && tanks.find(t => t.id !== e.winner).hp === 0) finish(e.winner);\n }\n // Scope negotiation itself: a finished card must never answer another game's hello.\n const scopedSignaling = signaling && {\n send(text) { const signal = decodeSignal(text); if (!signal) return Promise.reject(new Error('Invalid live signal')); const scoped = encodeSignal({ ...signal, liveGame: game.gameId }); return scoped ? signaling.send(scoped) : Promise.reject(new Error('Live signal too large')); },\n subscribe(listener) { return signaling.subscribe(frame => { const signal = decodeSignal(frame?.text); if (signal?.liveGame === game.gameId) listener(frame); }); },\n };\n const link = peerFactory({ signaling: scopedSignaling, selfId, peerId, roomId: game.roomId, iceServers, iceTransportPolicy, RTCPeerConnectionImpl, onMove: receiveMove, onEvent: receiveEvent, onChange(state) {\n const previousPhase = net.phase; net = state;\n if (state.phase === 'connected') { const resumed = wasConnected; wasConnected = true; if (status !== 'over') status = 'playing'; if (previousPhase !== 'connected') queueMicrotask(() => { if (!destroyed) { if (pendingResign) send({ k: 'resign' }); if (isHost && resumed) send(snapshot()); else if (!isHost) send({ k: 'sync' }); } }); }\n else if (status !== 'over') status = wasConnected ? 'disconnected' : 'connecting';\n notify();\n } });\n function maybeRematch() { if (isHost && wantsRematch.size === 2) { round++; send({ k: 'round' }); reset(); } }\n if (isHost) link.connect(); else link.setListening(true);\n return {\n setInput(next) { input = { ...next }; },\n step(dtMs) {\n if (destroyed) return;\n const elapsed = Math.max(0, Math.min(Number(dtMs) || 0, 100)); time += elapsed;\n if (status !== 'playing') return;\n const dt = elapsed / 1000;\n const renderTime = time - 100;\n while (poses.length > 1 && poses[1].time <= renderTime) poses.shift();\n if (poses.length) { const a = poses[0], b = poses[1] || a; const pose = interpolatePose(a.pose, b.pose, b.time === a.time ? 1 : (renderTime - a.time) / (b.time - a.time)); for (const key of ['x', 'z', 'yaw', 'turretYaw', 'speed']) other()[key] = pose[key]; }\n for (let remaining = dt; remaining > 0; remaining -= 0.016) moveTank(me(), input, Math.min(remaining, 0.016), arena);\n if (input.fire) fire(selfId, { id: `${selfId}:${round}:${++sequence}`, x: me().x, z: me().z, yaw: me().turretYaw, t: time }, true);\n const hz = net.rtt > 250 || net.move?.lossPct > 15 ? 10 : net.rtt > 100 ? 15 : 20;\n if (time >= sendAt) { sendAt = time + 1000 / hz; const t = me(); link.sendMove({ g: game.gameId, r: round, p: [t.x, t.z, t.yaw, t.turretYaw, t.speed], t: time }); }\n shells = shells.filter(shell => {\n const hit = advanceShell(shell, dt, arena, tanks);\n if (!hit) return true;\n if (isHost && hit.target && status === 'playing') {\n const tank = tanks.find(t => t.id === hit.target); tank.hp = Math.max(0, tank.hp - RULES.damage); tank.alive = tank.hp > 0;\n const e = { k: 'hit', id: shell.id, target: tank.id, dmg: RULES.damage, hp: tanks.map(t => t.hp), x: shell.x, z: shell.z }; send(e); emit(e);\n if (!tank.alive) { const e = { k: 'destroyed', target: tank.id }; send(e); emit(e); send({ k: 'over', winner: shell.owner }); finish(shell.owner); }\n } else emit({ k: 'impact', kind: hit.kind, x: shell.x, z: shell.z });\n return false;\n });\n },\n getRender() { const out = { arena, tanks: tanks.map(t => ({ ...t, self: t.id === selfId, reload: Math.min(1, (time - (lastFire.get(t.id) ?? -Infinity)) / RULES.reloadMs) })), shells: shells.map(s => ({ ...s })), events, status, winner, net: { ...net, turnConfigured } }; events = []; return out; },\n reconnect() { if (!destroyed && status !== 'over') link.connect(); },\n rematch() { if (!destroyed && status === 'over') { wantsRematch.add(selfId); send({ k: 'rematch' }); maybeRematch(); } },\n resign() { if (!destroyed && status !== 'over') { pendingResign = true; endReason = 'resigned'; send({ k: 'resign' }); finish(peerId); } },\n destroy() { if (destroyed) return; destroyed = true; link.destroy(); shells = []; poses = []; events = []; },\n };\n}\n","// Pure helpers shared by the live 3D/2D scenes and the card (no three, no DOM).\n// Render-state yaw is radians with forward = (cos yaw, sin yaw) on the x/z plane.\n\nexport const DEFAULT_ARENA_SIZE = 120;\nexport const RAD_TO_DEG = 180 / Math.PI;\n\nconst num = (value, fallback) => (Number.isFinite(value) ? value : fallback);\n\n/** Arena rectangle in world meters: explicit bounds, or `size` (corner origin unless `centered`). */\nexport function arenaBounds(arena) {\n const a = arena || {};\n const b = a.bounds || a;\n if (Number.isFinite(b.minX) && Number.isFinite(b.maxX) && Number.isFinite(b.minZ) && Number.isFinite(b.maxZ)) {\n return withSize({ minX: b.minX, minZ: b.minZ, maxX: b.maxX, maxZ: b.maxZ });\n }\n const w = num(a.width, num(a.size, DEFAULT_ARENA_SIZE));\n const d = num(a.depth, num(a.height, num(a.size, w)));\n const centered = a.centered === true || a.origin === 'center';\n return withSize(centered\n ? { minX: -w / 2, minZ: -d / 2, maxX: w / 2, maxZ: d / 2 }\n : { minX: 0, minZ: 0, maxX: w, maxZ: d });\n}\n\nfunction withSize(box) {\n return { ...box, width: box.maxX - box.minX, depth: box.maxZ - box.minZ, cx: (box.minX + box.maxX) / 2, cz: (box.minZ + box.maxZ) / 2 };\n}\n\n/** Circular obstacles [{ x, z, r, kind: 'tree'|'rock' }]. */\nexport function arenaObstacles(arena) {\n const list = arena?.obstacles || [];\n return list\n .filter((o) => Number.isFinite(o?.x) && Number.isFinite(o?.z))\n .map((o) => ({ x: o.x, z: o.z, r: num(o.r, num(o.radius, 1.5)), kind: o.kind === 'tree' ? 'tree' : 'rock' }));\n}\n\nexport const eventKind = (event) => (event ? event.k ?? event.type ?? null : null);\n\n/** Tank that fired: explicit owner field, else the tank nearest to the shot origin. */\nexport function shooterOf(event, tanks) {\n const list = tanks || [];\n const owner = event?.tank ?? event?.by ?? event?.owner ?? event?.from;\n if (owner != null) {\n const found = list.find((t) => String(t.id) === String(owner));\n if (found) return found;\n }\n if (!Number.isFinite(event?.x) || !Number.isFinite(event?.z)) return null;\n let best = null;\n let bestD = Infinity;\n for (const t of list) {\n const d = (t.x - event.x) ** 2 + (t.z - event.z) ** 2;\n if (d < bestD) { bestD = d; best = t; }\n }\n return best;\n}\n\nexport const tankById = (tanks, id) => (id == null ? null : (tanks || []).find((t) => String(t.id) === String(id)) || null);\nexport const selfTank = (tanks) => (tanks || []).find((t) => t.self) || null;\n\n/** 0 healthy, 1 smoking, 2 burning (also wrecks). */\nexport const damageLevel = (hp, alive = true) => (!alive || hp <= 25 ? 2 : hp <= 50 ? 1 : 0);\n\nexport const wrapAngle = (a) => {\n let v = a % (Math.PI * 2);\n if (v > Math.PI) v -= Math.PI * 2;\n if (v < -Math.PI) v += Math.PI * 2;\n return v;\n};\n\n/**\n * Tracks the own tank between frames to drive the engine/tracks/turret loops.\n * update(tank, dtMs) → scene-style sound events (move_start/move_end/turret_start/turret_end).\n */\nexport function createSelfTracker({ moveSpeed = 0.6, turnSpeed = 0.35, holdMs = 160 } = {}) {\n let last = null;\n let moving = false;\n let turning = false;\n let moveIdle = 0;\n let turnIdle = 0;\n return {\n update(tank, dtMs) {\n const out = [];\n if (!tank || tank.alive === false) {\n if (moving) out.push({ type: 'move_end' });\n if (turning) out.push({ type: 'turret_end' });\n moving = turning = false;\n last = null;\n return out;\n }\n const dt = Math.max(1, dtMs) / 1000;\n if (last) {\n const speed = Math.hypot(tank.x - last.x, tank.z - last.z) / dt;\n const hull = Math.abs(wrapAngle((tank.yaw ?? 0) - last.yaw)) / dt;\n const turret = Math.abs(wrapAngle((tank.turretYaw ?? 0) - (tank.yaw ?? 0) - last.rel)) / dt;\n const isMoving = speed > moveSpeed || hull > turnSpeed;\n moveIdle = isMoving ? 0 : moveIdle + dtMs;\n if (isMoving && !moving) { moving = true; out.push({ type: 'move_start' }); }\n else if (!isMoving && moving && moveIdle >= holdMs) { moving = false; out.push({ type: 'move_end' }); }\n const isTurning = turret > turnSpeed;\n turnIdle = isTurning ? 0 : turnIdle + dtMs;\n if (isTurning && !turning) { turning = true; out.push({ type: 'turret_start' }); }\n else if (!isTurning && turning && turnIdle >= holdMs) { turning = false; out.push({ type: 'turret_end' }); }\n }\n last = { x: tank.x, z: tank.z, yaw: tank.yaw ?? 0, rel: wrapAngle((tank.turretYaw ?? 0) - (tank.yaw ?? 0)) };\n return out;\n },\n reset() {\n last = null;\n moving = turning = false;\n moveIdle = turnIdle = 0;\n },\n get moving() { return moving; },\n get turning() { return turning; },\n };\n}\n\n/** Render events → scene-style sound events (sound/cues.js vocabulary). */\nexport function soundEventsFor(event) {\n switch (eventKind(event)) {\n case 'fire': return [{ type: 'fire' }, { type: 'projectile_start' }];\n case 'impact': return [{ type: 'impact', kind: event.kind === 'obstacle' ? 'obstacle' : 'terrain' }];\n case 'hit': return [{ type: 'tank_hit' }];\n case 'destroyed': return [{ type: 'destroyed' }];\n default: return [];\n }\n}\n\n/** 'victory' | 'defeat' | null for the own player once the match is over. */\nexport function outcomeFor(render) {\n if (!render || render.status !== 'over') return null;\n const me = selfTank(render.tanks);\n if (!me || render.winner == null) return null;\n return String(render.winner) === String(me.id) ? 'victory' : 'defeat';\n}\n\n/** Own reload progress 0..1 (1 = ready): the tank's own field when given, else from the last own fire. */\nexport function reloadProgress(tank, lastFireAt, now, reloadMs = 1500) {\n if (!tank) return 1;\n if (Number.isFinite(tank.reload)) return Math.max(0, Math.min(1, tank.reload));\n if (Number.isFinite(tank.reloadMs)) return Math.max(0, Math.min(1, 1 - tank.reloadMs / reloadMs));\n if (!Number.isFinite(lastFireAt)) return 1;\n return Math.max(0, Math.min(1, (now - lastFireAt) / reloadMs));\n}\n","import { arenaBounds, arenaObstacles } from './liveView.js';\n\n/** Lightweight top-down fallback, with the same render/picking lifecycle as WebGL. */\nexport function createLiveScene2d(container, { arena } = {}) {\n const canvas = document.createElement('canvas');\n canvas.style.cssText = 'width:100%;height:100%;display:block';\n container.appendChild(canvas);\n const ctx = canvas.getContext('2d');\n if (!ctx) { canvas.remove(); throw new Error('Canvas 2D unavailable'); }\n const bounds = arenaBounds(arena);\n let w = 1; let h = 1; let scale = 1; let ox = 0; let oz = 0;\n function resize() {\n w = Math.max(1, container.clientWidth); h = Math.max(1, container.clientHeight);\n const dpr = Math.min(window.devicePixelRatio || 1, 2);\n canvas.width = w * dpr; canvas.height = h * dpr;\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n scale = Math.min(w / bounds.width, h / bounds.depth);\n ox = (w - bounds.width * scale) / 2; oz = (h - bounds.depth * scale) / 2;\n }\n resize();\n const ro = typeof ResizeObserver === 'function' ? new ResizeObserver(resize) : null;\n ro?.observe(container);\n return {\n kind: '2d', resize,\n screenToGround(nx, ny) { return { x: ((nx + 1) * w / 2 - ox) / scale + bounds.minX, z: ((1 - ny) * h / 2 - oz) / scale + bounds.minZ }; },\n render(state) {\n ctx.fillStyle = '#152519'; ctx.fillRect(0, 0, w, h);\n ctx.save(); ctx.translate(ox, oz); ctx.scale(scale, scale); ctx.translate(-bounds.minX, -bounds.minZ);\n ctx.fillStyle = '#526348'; ctx.fillRect(bounds.minX, bounds.minZ, bounds.width, bounds.depth);\n for (const obstacle of arenaObstacles(arena)) { ctx.fillStyle = obstacle.kind === 'tree' ? '#24472d' : '#929285'; ctx.beginPath(); ctx.arc(obstacle.x, obstacle.z, obstacle.r, 0, Math.PI * 2); ctx.fill(); }\n for (const tank of state.tanks || []) {\n ctx.save(); ctx.translate(tank.x, tank.z); ctx.rotate(tank.yaw);\n ctx.fillStyle = tank.alive === false ? '#333' : tank.color || '#73ce68';\n ctx.fillRect(-3, -1.8, 6, 3.6); ctx.restore();\n ctx.save(); ctx.translate(tank.x, tank.z); ctx.rotate(tank.turretYaw); ctx.strokeStyle = '#dce8cf'; ctx.lineWidth = 0.8; ctx.beginPath(); ctx.moveTo(0, 0); ctx.lineTo(5, 0); ctx.stroke(); ctx.restore();\n if (tank.self) { ctx.strokeStyle = '#fff'; ctx.lineWidth = 0.3; ctx.beginPath(); ctx.arc(tank.x, tank.z, 4, 0, Math.PI * 2); ctx.stroke(); }\n }\n ctx.fillStyle = '#ffe097';\n for (const shell of state.shells || []) { ctx.beginPath(); ctx.arc(shell.x, shell.z, 0.7, 0, Math.PI * 2); ctx.fill(); }\n ctx.restore();\n },\n dispose() { ro?.disconnect(); canvas.remove(); },\n };\n}\n","/* eslint-disable react/prop-types */\nimport { memo, useContext, useEffect, useRef, useState } from 'react';\nimport { ChatContext } from '../../provider/ChatContext.js';\nimport useChatGames from '../shared/useChatGames.js';\nimport GameSoundControls from '../shared/GameSoundControls.jsx';\nimport { connectionDiagnostics, connectionHint } from './net/connectionDiagnostics.js';\nimport { createLiveMatch } from './net/createLiveMatch.js';\nimport { createLiveScene2d } from './scene/createLiveScene2d.js';\nimport { createSelfTracker, outcomeFor, selfTank, soundEventsFor } from './scene/liveView.js';\nimport { getTanksSoundManager, startTanksSounds, handleSceneEvent, playOutcome, stopAllTanksLoops } from '../tanks/sound/tanksSounds.js';\nimport '../connect4/games.css';\nimport './tanks-live.css';\n\nconst act = (key, type) => { void useChatGames.getState().act(key, type).catch(() => {}); };\nconst stopInput = (input) => { input.throttle = 0; input.steer = 0; input.fire = false; };\nfunction TanksLiveGameCard({ gameKey, currentUserId, onMinimize, onDismiss, suspended = false }) {\n const rtcOptions = useContext(ChatContext)?.config?.webrtc;\n const game = useChatGames((state) => state.games[gameKey]);\n const suspendedRef = useRef(suspended);\n suspendedRef.current = suspended;\n const stage = useRef(null); const match = useRef(null); const renderer = useRef(null);\n const input = useRef({ throttle: 0, steer: 0, fire: false });\n const [view, setView] = useState(null); const [error, setError] = useState(''); const [prefer2d, setPrefer2d] = useState(false);\n const [mode, setMode] = useState('loading');\n useEffect(() => {\n if (suspended) { stopInput(input.current); stopAllTanksLoops(); }\n else renderer.current?.resize();\n }, [suspended]);\n const active = ['active', 'won'].includes(game?.status);\n const [arena, setArena] = useState(null);\n useEffect(() => {\n if (!active || !arena || !stage.current) return undefined;\n let disposed = false; let scene = null;\n const options = { arena, lowPower: matchMedia('(pointer: coarse)').matches, reducedMotion: matchMedia('(prefers-reduced-motion: reduce)').matches, onEvent: (event) => { if (event.type === 'context_lost') setPrefer2d(true); } };\n const fallback = () => { if (!disposed) { scene = createLiveScene2d(stage.current, options); renderer.current = scene; setMode('2d'); } };\n if (prefer2d) fallback();\n else import('./scene/createLiveScene.js').then(({ createLiveScene }) => { if (!disposed) { try { scene = createLiveScene(stage.current, options); renderer.current = scene; setMode('3d'); } catch { fallback(); } } }).catch(fallback);\n return () => { disposed = true; scene?.dispose(); if (renderer.current === scene) renderer.current = null; };\n }, [active, arena, prefer2d]);\n useEffect(() => {\n if (!active || game.status !== 'active' || !stage.current) return undefined;\n let disposed = false; let frame = 0; let last = performance.now(); let published = 0; let outcome = null;\n const tracker = createSelfTracker(); const keys = new Set();\n startTanksSounds();\n let session;\n try {\n const signaling = useChatGames.getState().createLiveSignaling(gameKey);\n session = createLiveMatch({ iceServers: rtcOptions?.iceServers, iceTransportPolicy: rtcOptions?.iceTransportPolicy, game, selfId: String(currentUserId), isHost: String(game.hostId) === String(currentUserId), signaling });\n match.current = session;\n } catch (e) { setError(e.message || 'No se pudo iniciar WebRTC'); return undefined; }\n setArena(session.getRender().arena);\n function clear() { keys.clear(); stopInput(input.current); stopAllTanksLoops(); }\n function key(event, down) {\n if (/^(INPUT|TEXTAREA|SELECT)$/.test(event.target?.tagName)) return;\n if (!['KeyW', 'KeyA', 'KeyS', 'KeyD', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Space'].includes(event.code)) return;\n event.preventDefault(); if (down) keys.add(event.code); else keys.delete(event.code);\n input.current.throttle = Number(keys.has('KeyW') || keys.has('ArrowUp')) - Number(keys.has('KeyS') || keys.has('ArrowDown'));\n input.current.steer = Number(keys.has('KeyD') || keys.has('ArrowRight')) - Number(keys.has('KeyA') || keys.has('ArrowLeft'));\n input.current.fire = keys.has('Space');\n }\n const down = (e) => key(e, true); const up = (e) => key(e, false);\n const host = stage.current;\n host.addEventListener('keydown', down); host.addEventListener('keyup', up); host.addEventListener('blur', clear);\n const visibility = () => { if (document.hidden) clear(); };\n document.addEventListener('visibilitychange', visibility);\n handleSceneEvent({ type: 'engine_start' }, gameKey);\n function tick(now) {\n if (disposed) return;\n const dt = Math.min(80, now - last); last = now;\n const paused = suspendedRef.current || document.hidden;\n session.setInput(paused ? { throttle: 0, steer: 0, fire: false } : input.current);\n session.step(dt); const state = session.getRender();\n if (!paused) renderer.current?.render(state, dt);\n if (paused) { keys.clear(); tracker.reset(); stopAllTanksLoops(); }\n if (!paused) for (const event of state.events || []) for (const sound of soundEventsFor(event)) handleSceneEvent(sound, event.id);\n if (!paused) for (const event of tracker.update(selfTank(state.tanks), dt)) handleSceneEvent(event);\n const nextOutcome = outcomeFor(state);\n if (nextOutcome && !outcome) { setView(state); outcome = nextOutcome; if (!paused) playOutcome(outcome, gameKey); useChatGames.getState().liveFinish?.(gameKey, state.winner); }\n if (now - published > 100) { published = now; setView(state); }\n frame = requestAnimationFrame(tick);\n }\n frame = requestAnimationFrame(tick);\n return () => {\n disposed = true; cancelAnimationFrame(frame); clear(); session.destroy(); match.current = null;\n host.removeEventListener('keydown', down); host.removeEventListener('keyup', up); host.removeEventListener('blur', clear); document.removeEventListener('visibilitychange', visibility);\n };\n }, [active, gameKey, currentUserId]);\n if (!game) return null;\n const guest = String(currentUserId) === String(game.guestId);\n const over = view?.status === 'over' || game.status === 'won';\n function aim(event) {\n const rect = stage.current?.getBoundingClientRect(); const me = selfTank(view?.tanks);\n if (!rect || !me) return;\n const ground = renderer.current?.screenToGround((event.clientX - rect.left) / rect.width * 2 - 1, 1 - (event.clientY - rect.top) / rect.height * 2);\n if (ground) input.current.turretYaw = Math.atan2(ground.z - me.z, ground.x - me.x);\n }\n const hold = (field, value) => ({ onPointerDown: (e) => { e.preventDefault(); e.currentTarget.setPointerCapture(e.pointerId); input.current[field] = value; }, onPointerUp: () => { input.current[field] = field === 'fire' ? false : 0; }, onPointerCancel: () => { input.current[field] = field === 'fire' ? false : 0; }, onLostPointerCapture: () => { input.current[field] = field === 'fire' ? false : 0; } });\n return <section className=\"chat-game-card tl-card\" aria-label=\"Tanques LIVE 3D\">\n <header className=\"tl-header\"><strong>Tanques LIVE 3D</strong><GameSoundControls manager={getTanksSoundManager()} />{onMinimize && <button onClick={onMinimize} aria-label=\"Minimizar\">−</button>}{onDismiss && <button onClick={onDismiss} aria-label=\"Ocultar\">×</button>}</header>\n {game.status === 'invited' && <div className=\"tl-invite\"><p>{guest ? 'Te invitaron a un combate en tiempo real.' : 'Esperando que el rival acepte…'}</p>{guest && <><button onClick={() => act(gameKey, 'game_accept')}>Aceptar</button><button onClick={() => act(gameKey, 'game_decline')}>Rechazar</button></>}</div>}\n {(active || view) && <><div className=\"tl-hud\">{(view?.tanks || []).map((tank) => <span key={tank.id}>{tank.self ? 'Tú' : 'Rival'} <meter min=\"0\" max=\"100\" value={tank.hp} aria-label={tank.self ? 'Tu vida' : 'Vida del rival'} /> {tank.hp} HP</span>)}<span role=\"status\">{view?.net?.phase || 'Conectando WebRTC…'} {view?.net?.route?.label || (typeof view?.net?.route === 'string' ? view.net.route : '')} {Number.isFinite(view?.net?.rtt) ? `${Math.round(view.net.rtt)} ms` : ''}</span></div>\n <div className=\"tl-stage\" ref={stage} tabIndex={0} aria-label=\"Arena. WASD o flechas para conducir, ratón para apuntar, clic o espacio para disparar\" onPointerMove={aim} onPointerDown={(e) => { aim(e); if (e.pointerType === 'mouse') { e.currentTarget.focus(); e.currentTarget.setPointerCapture(e.pointerId); aim(e); input.current.fire = true; } }} onPointerUp={() => { input.current.fire = false; }} onPointerCancel={() => { stopInput(input.current); }} onLostPointerCapture={() => { input.current.fire = false; }} />\n <div className=\"tl-controls\"><div className=\"tl-joystick\" role=\"group\" aria-label=\"Joystick de conducción\" onPointerDown={(e) => { e.preventDefault(); e.currentTarget.setPointerCapture(e.pointerId); const r = e.currentTarget.getBoundingClientRect(); input.current.steer = Math.max(-1, Math.min(1, (e.clientX - r.left - r.width / 2) / (r.width / 2))); input.current.throttle = Math.max(-1, Math.min(1, -(e.clientY - r.top - r.height / 2) / (r.height / 2))); }} onPointerMove={(e) => { if (!e.currentTarget.hasPointerCapture(e.pointerId)) return; const r = e.currentTarget.getBoundingClientRect(); input.current.steer = Math.max(-1, Math.min(1, (e.clientX - r.left - r.width / 2) / (r.width / 2))); input.current.throttle = Math.max(-1, Math.min(1, -(e.clientY - r.top - r.height / 2) / (r.height / 2))); }} onPointerUp={() => stopInput(input.current)} onPointerCancel={() => stopInput(input.current)} onLostPointerCapture={() => stopInput(input.current)}>✥</div><div className=\"tl-drive\" aria-label=\"Controles de conducción\"><button aria-label=\"Avanzar\" {...hold('throttle', 1)}>▲</button><button aria-label=\"Girar izquierda\" {...hold('steer', -1)}>◀</button><button aria-label=\"Retroceder\" {...hold('throttle', -1)}>▼</button><button aria-label=\"Girar derecha\" {...hold('steer', 1)}>▶</button></div><button className=\"tl-fire\" {...hold('fire', true)}>Disparar</button></div>\n <div className=\"tl-reload\"><label>Recarga <progress max=\"1\" value={selfTank(view?.tanks)?.reload ?? 1} /> {(selfTank(view?.tanks)?.reload ?? 1) >= 1 ? 'Listo' : 'Recargando…'}</label></div>\n <small>WASD / flechas · ratón o toca la arena para apuntar · espacio / clic para disparar</small><button onClick={() => setPrefer2d((v) => !v)}>{mode === '2d' ? 'Probar 3D' : 'Vista 2D'}</button>\n </>}\n {over && <p role=\"status\">{String(view?.winner ?? game.winnerId) === String(currentUserId) ? '¡Victoria!' : 'Fin del combate'} <button onClick={() => { void Promise.resolve(useChatGames.getState().liveRematch?.(gameKey)).catch(() => {}); }}>Revancha</button></p>}\n {active && !over && view?.net?.phase !== 'connected' && <div className=\"tl-connection\">\n <p role=\"status\">{connectionHint(view?.net)}</p>\n <button type=\"button\" onClick={() => match.current?.reconnect()}>Reintentar conexión</button>\n </div>}\n {active && <details className=\"tl-diagnostics\"><summary>Diagnóstico de conexión</summary><pre>{JSON.stringify(connectionDiagnostics(view?.net), null, 2)}</pre></details>}\n {active && !over && <button onClick={() => match.current?.resign()}>Rendirse</button>}\n {game.pending && <p role=\"status\">Enviando…</p>}{game.pendingEvent && game.error && <button onClick={() => { void useChatGames.getState().retry(gameKey).catch(() => {}); }}>Reintentar envío</button>}\n {error && <p role=\"alert\">{error}</p>}{game.error && <p role=\"alert\">{game.error}</p>}\n {!['closed', 'declined'].includes(game.status) && <button onClick={() => act(gameKey, 'game_end')}>Cerrar partida</button>}\n </section>;\n}\nexport default memo(TanksLiveGameCard);\n"],"mappings":"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"}
1
+ {"version":3,"file":"TanksLiveGameCard-BNJqWt1z.js","names":["_Fragment","useChatGames","GameSoundControls","decodeSignal","createPeerLink","encodeSignal","ChatContext","stopAllTanksLoops","startTanksSounds","handleSceneEvent","playOutcome","getTanksSoundManager","__defProp","__exportAll","target","name","all","no_symbols","connectionDiagnostics","net","connectionHint","RULES","clamp","lo","hi","n","angleDelta","b","a","createArena","x","z","r","i","createTank","id","index","validPosition","arena","radius","o","moveTank","tank","throttle","input","steer","dt","segmentCircle","dx","bx","ax","dz","bz","az","length","t","cx","cz","advanceShell","shell","first","tanks","interpolatePose","fraction","finite","idValid","createLiveMatch","selfId","game","ids","turnConfigured","iceServers","server","url","peerId","shells","events","time","sendAt","round","sequence","status","winner","destroyed","wasConnected","pendingResign","endReason","poses","lastPoseAt","lastPose","lastFire","seen","wantsRematch","me","other","notify","onChange","emit","send","link","e","remember","key","snapshot","reset","finish","force","fire","owner","shot","broadcast","receiveMove","data","yaw","turretYaw","speed","elapsed","previous","pose","receiveEvent","isHost","hp","validPlaying","validOver","maybeRematch","s","peerFactory","signaling","signal","text","scoped","frame","listener","previousPhase","state","resumed","next","dtMs","renderTime","remaining","hz","hit","out","RAD_TO_DEG","num","value","fallback","arenaBounds","withSize","w","d","box","arenaObstacles","eventKind","event","shooterOf","list","found","best","bestD","tankById","selfTank","damageLevel","alive","wrapAngle","v","createSelfTracker","last","moving","turning","moveIdle","turnIdle","hull","turret","isMoving","moveSpeed","turnSpeed","holdMs","isTurning","soundEventsFor","outcomeFor","render","createLiveScene2d","canvas","container","ctx","bounds","h","scale","ox","oz","resize","dpr","ro","nx","ny","obstacle","TanksLiveGameCard_exports","TanksLiveGameCard_default","act","type","stopInput","TanksLiveGameCard","rtcOptions","useContext","gameKey","suspendedRef","useRef","suspended","stage","match","renderer","view","setView","useState","error","setError","prefer2d","setPrefer2d","mode","setMode","active","setArena","useEffect","disposed","scene","options","createLiveScene","published","outcome","tracker","keys","session","currentUserId","clear","down","up","host","visibility","tick","now","paused","sound","nextOutcome","guest","over","aim","rect","ground","hold","field","onMinimize","onDismiss","Fragment","memo"],"sources":["../../src/games/tanks-live/net/connectionDiagnostics.js","../../src/games/tanks-live/logic/simulation.js","../../src/games/tanks-live/net/createLiveMatch.js","../../src/games/tanks-live/scene/liveView.js","../../src/games/tanks-live/scene/createLiveScene2d.js","../../src/games/tanks-live/TanksLiveGameCard.jsx"],"sourcesContent":["// Deliberately excludes SDP, ICE addresses, account IDs and TURN credentials.\nexport function connectionDiagnostics(net = {}) {\n return {\n phase: net.phase ?? 'idle', ice: net.ice ?? 'new',\n connection: net.connection ?? 'new', gathering: net.gathering ?? 'new',\n signaling: {\n sent: net.signals?.sent ?? 0, received: net.signals?.received ?? 0,\n sendFailures: net.signals?.sendFailures ?? 0,\n ignored: net.signals?.ignored ?? 0, invalid: net.signals?.invalid ?? 0,\n retransmits: net.signals?.retransmits ?? 0,\n },\n turnConfigured: Boolean(net.turnConfigured),\n route: net.route?.label ?? null,\n movesSent: net.move?.sent ?? 0, movesReceived: net.move?.received ?? 0,\n error: net.error ? (/^[a-z_]+$/.test(net.error) ? net.error : 'negotiation_error') : null,\n };\n}\n\nexport function connectionHint(net = {}) {\n if (net.phase === 'connected') return '';\n if (net.signals?.sendFailures) return 'No se pudieron enviar señales por el chat. Revisa la conexión WebSocket y reintenta.';\n if (net.ice === 'checking' || net.ice === 'failed') return net.turnConfigured\n ? 'WebRTC aún no encuentra una ruta entre los jugadores. Revisa el servicio TURN y la red.'\n : 'WebRTC aún no encuentra una ruta entre los jugadores. Algunas redes necesitan un servidor TURN; esta partida no tiene uno configurado.';\n if (net.phase === 'listening') return 'Esperando la conexión del rival. Ambos deben mantener abierta la partida y usar la misma versión del chat.';\n if (net.phase === 'failed') return 'No se pudo conectar. Revisa el diagnóstico de ambos jugadores y reintenta.';\n return 'Intercambiando señales de conexión por el chat. El combate empieza cuando conecta WebRTC.';\n}\n","// Deterministic arcade simulation. Angles are radians, forward is +x.\nexport const RULES = Object.freeze({ speed: 16, reverse: 9, turn: 1.8, acceleration: 28, radius: 2, reloadMs: 1500, shellSpeed: 60, damage: 25 });\nexport const clamp = (n, lo, hi) => Math.max(lo, Math.min(hi, n));\nexport const angleDelta = (a, b) => Math.atan2(Math.sin(b - a), Math.cos(b - a));\nexport function createArena() {\n return { size: 120, bounds: { minX: 0, maxX: 120, minZ: 0, maxZ: 120 }, obstacles: [\n [42, 35, 4], [78, 85, 4], [60, 30, 3], [60, 90, 3], [35, 65, 3], [85, 55, 3], [60, 60, 5],\n ].map(([x, z, r], i) => ({ x, z, r, kind: i % 2 ? 'tree' : 'rock' })) };\n}\nexport function createTank(id, index) { return { id: String(id), x: index ? 102 : 18, z: 60, yaw: index ? Math.PI : 0, turretYaw: index ? Math.PI : 0, speed: 0, hp: 100, alive: true, color: index ? '#d7463f' : '#54a34a' }; }\nexport function validPosition(x, z, arena, radius = RULES.radius) {\n const b = arena.bounds;\n return x >= b.minX + radius && x <= b.maxX - radius && z >= b.minZ + radius && z <= b.maxZ - radius\n && !arena.obstacles.some(o => Math.hypot(x - o.x, z - o.z) < o.r + radius);\n}\nexport function moveTank(tank, input, dt, arena) {\n if (!tank.alive) return;\n const throttle = clamp(Number(input.throttle) || 0, -1, 1), steer = clamp(Number(input.steer) || 0, -1, 1);\n const target = throttle * (throttle < 0 ? RULES.reverse : RULES.speed);\n tank.speed += clamp(target - tank.speed, -RULES.acceleration * dt, RULES.acceleration * dt);\n tank.yaw += steer * RULES.turn * dt;\n if (Number.isFinite(input.turretYaw)) tank.turretYaw = input.turretYaw;\n const x = tank.x + Math.cos(tank.yaw) * tank.speed * dt, z = tank.z + Math.sin(tank.yaw) * tank.speed * dt;\n if (validPosition(x, tank.z, arena)) tank.x = x; else tank.speed = 0;\n if (validPosition(tank.x, z, arena)) tank.z = z; else tank.speed = 0;\n}\nexport function segmentCircle(ax, az, bx, bz, cx, cz, radius) {\n const dx = bx - ax, dz = bz - az, length = dx * dx + dz * dz;\n const t = length ? clamp(((cx - ax) * dx + (cz - az) * dz) / length, 0, 1) : 0;\n return Math.hypot(ax + dx * t - cx, az + dz * t - cz) <= radius ? t : null;\n}\nexport function advanceShell(shell, dt, arena, tanks) {\n const x = shell.x + Math.cos(shell.yaw) * RULES.shellSpeed * dt, z = shell.z + Math.sin(shell.yaw) * RULES.shellSpeed * dt;\n let first = null;\n for (const o of arena.obstacles) { const t = segmentCircle(shell.x, shell.z, x, z, o.x, o.z, o.r); if (t !== null && (!first || t < first.t)) first = { t, kind: 'obstacle' }; }\n for (const tank of tanks) { if (!tank.alive || tank.id === shell.owner) continue; const t = segmentCircle(shell.x, shell.z, x, z, tank.x, tank.z, RULES.radius); if (t !== null && (!first || t < first.t)) first = { t, kind: 'tank', target: tank.id }; }\n if (first) { shell.x += (x - shell.x) * first.t; shell.z += (z - shell.z) * first.t; return first; }\n shell.x = x; shell.z = z; shell.age += dt;\n return !validPosition(x, z, { ...arena, obstacles: [] }, 0) || shell.age > 3 ? { kind: 'terrain' } : null;\n}\nexport function interpolatePose(a, b, fraction) {\n const t = clamp(fraction, 0, 1);\n return { ...b, x: a.x + (b.x - a.x) * t, z: a.z + (b.z - a.z) * t, yaw: a.yaw + angleDelta(a.yaw, b.yaw) * t, turretYaw: a.turretYaw + angleDelta(a.turretYaw, b.turretYaw) * t };\n}\n","import { decodeSignal, encodeSignal } from '../../../net/webrtc/protocol.js';\nimport { createPeerLink } from '../../../net/webrtc/createPeerLink.js';\nimport { RULES, createArena, createTank, moveTank, advanceShell, validPosition, interpolatePose } from '../logic/simulation.js';\n\nconst finite = n => typeof n === 'number' && Number.isFinite(n);\nconst idValid = id => typeof id === 'string' && id.length > 0 && id.length < 160;\nexport function createLiveMatch({ game, selfId, isHost = String(selfId) === String(game.hostId), signaling, onChange = () => {}, peerFactory = createPeerLink, iceServers, iceTransportPolicy, RTCPeerConnectionImpl } = {}) {\n selfId = String(selfId);\n const ids = [String(game.hostId), String(game.guestId)];\n if (!ids.includes(selfId) || ids[0] === ids[1]) throw new Error('Invalid live match players');\n const turnConfigured = (iceServers || []).some(server => [server.urls].flat().some(url => /^turns?:/i.test(String(url))));\n const peerId = ids.find(id => id !== selfId), arena = createArena();\n let tanks = ids.map(createTank), shells = [], events = [], input = {}, time = 0, sendAt = 0, round = 0, sequence = 0;\n let status = 'connecting', winner = null, destroyed = false, net = { phase: 'idle', rtt: null, route: null }, wasConnected = false, pendingResign = false, endReason = null;\n let poses = [], lastPoseAt = null, lastPose = null, lastFire = new Map(), seen = new Set(), wantsRematch = new Set();\n const me = () => tanks.find(t => t.id === selfId), other = () => tanks.find(t => t.id === peerId);\n const notify = () => { if (!destroyed) onChange({ status, winner, net }); };\n const emit = e => { events.push(e); if (events.length > 200) events.shift(); };\n const send = e => link.sendEvent({ ...e, g: game.gameId, r: round });\n const remember = key => { seen.add(key); if (seen.size > 2048) seen.delete(seen.values().next().value); };\n const snapshot = () => ({ k: 'snapshot', hp: tanks.map(t => t.hp), status, winner, reason: endReason });\n function reset() {\n tanks = ids.map(createTank); shells = []; poses = []; lastPoseAt = null; lastPose = null; lastFire.clear(); seen.clear(); wantsRematch.clear(); pendingResign = false; endReason = null; winner = null; status = net.phase === 'connected' ? 'playing' : 'connecting'; emit({ k: 'rematch' }); notify();\n }\n function finish(id, force = false) { if (status === 'over' && (!force || winner === id)) return; status = 'over'; winner = id; shells = []; emit({ k: 'over', winner }); notify(); }\n function fire(owner, e, broadcast) {\n if (status !== 'playing' || !idValid(e.id) || seen.has(e.id)) return false;\n const tank = tanks.find(t => t.id === owner);\n if (!tank?.alive || time - (lastFire.get(owner) ?? -Infinity) < RULES.reloadMs - 20) return false;\n if (![e.x, e.z, e.yaw].every(finite) || Math.hypot(e.x - (owner === peerId && lastPose ? lastPose.x : tank.x), e.z - (owner === peerId && lastPose ? lastPose.z : tank.z)) > 6) return false;\n remember(e.id);\n lastFire.set(owner, time);\n const shot = { ...e, k: 'fire', owner, x: e.x + Math.cos(e.yaw) * 2.8, z: e.z + Math.sin(e.yaw) * 2.8, y: 1.4, age: 0 };\n shells.push(shot); emit(shot); if (broadcast) send({ ...e, k: 'fire' }); return true;\n }\n function receiveMove(data) {\n if (destroyed || status !== 'playing' || data?.g !== game.gameId || data.r !== round || !Array.isArray(data.p) || data.p.length !== 5 || !data.p.every(finite)) return;\n const [x, z, yaw, turretYaw, speed] = data.p;\n if (!validPosition(x, z, arena) || Math.abs(speed) > RULES.speed + 0.1 || Math.abs(yaw) > 1e6 || Math.abs(turretYaw) > 1e6) return;\n const elapsed = lastPoseAt === null ? 0.1 : Math.max(0, (time - lastPoseAt) / 1000);\n const previous = lastPose || other();\n if (Math.hypot(x - previous.x, z - previous.z) > RULES.speed * elapsed + 3) return;\n const pose = { ...other(), x, z, yaw, turretYaw, speed };\n lastPose = pose; lastPoseAt = time; poses.push({ time, pose }); if (poses.length > 30) poses.shift();\n }\n function receiveEvent(e) {\n if (destroyed || !e || e.g !== game.gameId || !Number.isInteger(e.r)) return;\n if (e.k === 'round' && !isHost && status === 'over' && wantsRematch.has(selfId) && e.r === round + 1) { round = e.r; reset(); return; }\n if (e.r !== round) return;\n if (e.k === 'sync' && isHost) { send(snapshot()); return; }\n if (e.k === 'snapshot' && !isHost && Array.isArray(e.hp) && e.hp.length === 2 && e.hp.every(hp => Number.isInteger(hp) && hp >= 0 && hp <= 100)) {\n const validPlaying = e.status === 'playing' && e.winner === null && e.hp.every(hp => hp > 0);\n const validOver = e.status === 'over' && ids.includes(e.winner) && (e.hp[1 - ids.indexOf(e.winner)] === 0 || e.reason === 'resigned');\n if (!validPlaying && !validOver) return;\n tanks.forEach((t, i) => { t.hp = e.hp[i]; t.alive = t.hp > 0; });\n if (validOver) { pendingResign = false; endReason = e.reason; finish(e.winner, true); }\n return;\n }\n if (e.k === 'resign') { endReason = 'resigned'; finish(selfId, isHost); if (isHost) send(snapshot()); return; }\n if (e.k === 'rematch' && status === 'over') { wantsRematch.add(peerId); maybeRematch(); return; }\n if (status !== 'playing') return;\n if (e.k === 'fire') fire(peerId, e, false);\n if (!isHost && e.k === 'hit' && idValid(e.id) && !seen.has(`hit:${e.id}`) && ids.includes(e.target) && Array.isArray(e.hp) && e.hp.length === 2 && e.hp.every((hp, i) => Number.isInteger(hp) && hp >= 0 && hp <= tanks[i].hp) && [e.x, e.z].every(finite)) {\n remember(`hit:${e.id}`); tanks.forEach((tank, i) => { tank.hp = e.hp[i]; tank.alive = tank.hp > 0; }); shells = shells.filter(s => s.id !== e.id); emit(e);\n }\n if (!isHost && e.k === 'destroyed' && ids.includes(e.target) && !seen.has(`destroyed:${e.target}`) && tanks.find(t => t.id === e.target).hp === 0) { remember(`destroyed:${e.target}`); emit(e); }\n if (!isHost && e.k === 'over' && ids.includes(e.winner) && tanks.find(t => t.id !== e.winner).hp === 0) finish(e.winner);\n }\n // Scope negotiation itself: a finished card must never answer another game's hello.\n const scopedSignaling = signaling && {\n send(text) { const signal = decodeSignal(text); if (!signal) return Promise.reject(new Error('Invalid live signal')); const scoped = encodeSignal({ ...signal, liveGame: game.gameId }); return scoped ? signaling.send(scoped) : Promise.reject(new Error('Live signal too large')); },\n subscribe(listener) { return signaling.subscribe(frame => { const signal = decodeSignal(frame?.text); if (signal?.liveGame === game.gameId) listener(frame); }); },\n };\n const link = peerFactory({ signaling: scopedSignaling, selfId, peerId, roomId: game.roomId, iceServers, iceTransportPolicy, RTCPeerConnectionImpl, onMove: receiveMove, onEvent: receiveEvent, onChange(state) {\n const previousPhase = net.phase; net = state;\n if (state.phase === 'connected') { const resumed = wasConnected; wasConnected = true; if (status !== 'over') status = 'playing'; if (previousPhase !== 'connected') queueMicrotask(() => { if (!destroyed) { if (pendingResign) send({ k: 'resign' }); if (isHost && resumed) send(snapshot()); else if (!isHost) send({ k: 'sync' }); } }); }\n else if (status !== 'over') status = wasConnected ? 'disconnected' : 'connecting';\n notify();\n } });\n function maybeRematch() { if (isHost && wantsRematch.size === 2) { round++; send({ k: 'round' }); reset(); } }\n if (isHost) link.connect(); else link.setListening(true);\n return {\n setInput(next) { input = { ...next }; },\n step(dtMs) {\n if (destroyed) return;\n const elapsed = Math.max(0, Math.min(Number(dtMs) || 0, 100)); time += elapsed;\n if (status !== 'playing') return;\n const dt = elapsed / 1000;\n const renderTime = time - 100;\n while (poses.length > 1 && poses[1].time <= renderTime) poses.shift();\n if (poses.length) { const a = poses[0], b = poses[1] || a; const pose = interpolatePose(a.pose, b.pose, b.time === a.time ? 1 : (renderTime - a.time) / (b.time - a.time)); for (const key of ['x', 'z', 'yaw', 'turretYaw', 'speed']) other()[key] = pose[key]; }\n for (let remaining = dt; remaining > 0; remaining -= 0.016) moveTank(me(), input, Math.min(remaining, 0.016), arena);\n if (input.fire) fire(selfId, { id: `${selfId}:${round}:${++sequence}`, x: me().x, z: me().z, yaw: me().turretYaw, t: time }, true);\n const hz = net.rtt > 250 || net.move?.lossPct > 15 ? 10 : net.rtt > 100 ? 15 : 20;\n if (time >= sendAt) { sendAt = time + 1000 / hz; const t = me(); link.sendMove({ g: game.gameId, r: round, p: [t.x, t.z, t.yaw, t.turretYaw, t.speed], t: time }); }\n shells = shells.filter(shell => {\n const hit = advanceShell(shell, dt, arena, tanks);\n if (!hit) return true;\n if (isHost && hit.target && status === 'playing') {\n const tank = tanks.find(t => t.id === hit.target); tank.hp = Math.max(0, tank.hp - RULES.damage); tank.alive = tank.hp > 0;\n const e = { k: 'hit', id: shell.id, target: tank.id, dmg: RULES.damage, hp: tanks.map(t => t.hp), x: shell.x, z: shell.z }; send(e); emit(e);\n if (!tank.alive) { const e = { k: 'destroyed', target: tank.id }; send(e); emit(e); send({ k: 'over', winner: shell.owner }); finish(shell.owner); }\n } else emit({ k: 'impact', kind: hit.kind, x: shell.x, z: shell.z });\n return false;\n });\n },\n getRender() { const out = { arena, tanks: tanks.map(t => ({ ...t, self: t.id === selfId, reload: Math.min(1, (time - (lastFire.get(t.id) ?? -Infinity)) / RULES.reloadMs) })), shells: shells.map(s => ({ ...s })), events, status, winner, net: { ...net, turnConfigured } }; events = []; return out; },\n reconnect() { if (!destroyed && status !== 'over') link.connect(); },\n rematch() { if (!destroyed && status === 'over') { wantsRematch.add(selfId); send({ k: 'rematch' }); maybeRematch(); } },\n resign() { if (!destroyed && status !== 'over') { pendingResign = true; endReason = 'resigned'; send({ k: 'resign' }); finish(peerId); } },\n destroy() { if (destroyed) return; destroyed = true; link.destroy(); shells = []; poses = []; events = []; },\n };\n}\n","// Pure helpers shared by the live 3D/2D scenes and the card (no three, no DOM).\n// Render-state yaw is radians with forward = (cos yaw, sin yaw) on the x/z plane.\n\nexport const DEFAULT_ARENA_SIZE = 120;\nexport const RAD_TO_DEG = 180 / Math.PI;\n\nconst num = (value, fallback) => (Number.isFinite(value) ? value : fallback);\n\n/** Arena rectangle in world meters: explicit bounds, or `size` (corner origin unless `centered`). */\nexport function arenaBounds(arena) {\n const a = arena || {};\n const b = a.bounds || a;\n if (Number.isFinite(b.minX) && Number.isFinite(b.maxX) && Number.isFinite(b.minZ) && Number.isFinite(b.maxZ)) {\n return withSize({ minX: b.minX, minZ: b.minZ, maxX: b.maxX, maxZ: b.maxZ });\n }\n const w = num(a.width, num(a.size, DEFAULT_ARENA_SIZE));\n const d = num(a.depth, num(a.height, num(a.size, w)));\n const centered = a.centered === true || a.origin === 'center';\n return withSize(centered\n ? { minX: -w / 2, minZ: -d / 2, maxX: w / 2, maxZ: d / 2 }\n : { minX: 0, minZ: 0, maxX: w, maxZ: d });\n}\n\nfunction withSize(box) {\n return { ...box, width: box.maxX - box.minX, depth: box.maxZ - box.minZ, cx: (box.minX + box.maxX) / 2, cz: (box.minZ + box.maxZ) / 2 };\n}\n\n/** Circular obstacles [{ x, z, r, kind: 'tree'|'rock' }]. */\nexport function arenaObstacles(arena) {\n const list = arena?.obstacles || [];\n return list\n .filter((o) => Number.isFinite(o?.x) && Number.isFinite(o?.z))\n .map((o) => ({ x: o.x, z: o.z, r: num(o.r, num(o.radius, 1.5)), kind: o.kind === 'tree' ? 'tree' : 'rock' }));\n}\n\nexport const eventKind = (event) => (event ? event.k ?? event.type ?? null : null);\n\n/** Tank that fired: explicit owner field, else the tank nearest to the shot origin. */\nexport function shooterOf(event, tanks) {\n const list = tanks || [];\n const owner = event?.tank ?? event?.by ?? event?.owner ?? event?.from;\n if (owner != null) {\n const found = list.find((t) => String(t.id) === String(owner));\n if (found) return found;\n }\n if (!Number.isFinite(event?.x) || !Number.isFinite(event?.z)) return null;\n let best = null;\n let bestD = Infinity;\n for (const t of list) {\n const d = (t.x - event.x) ** 2 + (t.z - event.z) ** 2;\n if (d < bestD) { bestD = d; best = t; }\n }\n return best;\n}\n\nexport const tankById = (tanks, id) => (id == null ? null : (tanks || []).find((t) => String(t.id) === String(id)) || null);\nexport const selfTank = (tanks) => (tanks || []).find((t) => t.self) || null;\n\n/** 0 healthy, 1 smoking, 2 burning (also wrecks). */\nexport const damageLevel = (hp, alive = true) => (!alive || hp <= 25 ? 2 : hp <= 50 ? 1 : 0);\n\nexport const wrapAngle = (a) => {\n let v = a % (Math.PI * 2);\n if (v > Math.PI) v -= Math.PI * 2;\n if (v < -Math.PI) v += Math.PI * 2;\n return v;\n};\n\n/**\n * Tracks the own tank between frames to drive the engine/tracks/turret loops.\n * update(tank, dtMs) → scene-style sound events (move_start/move_end/turret_start/turret_end).\n */\nexport function createSelfTracker({ moveSpeed = 0.6, turnSpeed = 0.35, holdMs = 160 } = {}) {\n let last = null;\n let moving = false;\n let turning = false;\n let moveIdle = 0;\n let turnIdle = 0;\n return {\n update(tank, dtMs) {\n const out = [];\n if (!tank || tank.alive === false) {\n if (moving) out.push({ type: 'move_end' });\n if (turning) out.push({ type: 'turret_end' });\n moving = turning = false;\n last = null;\n return out;\n }\n const dt = Math.max(1, dtMs) / 1000;\n if (last) {\n const speed = Math.hypot(tank.x - last.x, tank.z - last.z) / dt;\n const hull = Math.abs(wrapAngle((tank.yaw ?? 0) - last.yaw)) / dt;\n const turret = Math.abs(wrapAngle((tank.turretYaw ?? 0) - (tank.yaw ?? 0) - last.rel)) / dt;\n const isMoving = speed > moveSpeed || hull > turnSpeed;\n moveIdle = isMoving ? 0 : moveIdle + dtMs;\n if (isMoving && !moving) { moving = true; out.push({ type: 'move_start' }); }\n else if (!isMoving && moving && moveIdle >= holdMs) { moving = false; out.push({ type: 'move_end' }); }\n const isTurning = turret > turnSpeed;\n turnIdle = isTurning ? 0 : turnIdle + dtMs;\n if (isTurning && !turning) { turning = true; out.push({ type: 'turret_start' }); }\n else if (!isTurning && turning && turnIdle >= holdMs) { turning = false; out.push({ type: 'turret_end' }); }\n }\n last = { x: tank.x, z: tank.z, yaw: tank.yaw ?? 0, rel: wrapAngle((tank.turretYaw ?? 0) - (tank.yaw ?? 0)) };\n return out;\n },\n reset() {\n last = null;\n moving = turning = false;\n moveIdle = turnIdle = 0;\n },\n get moving() { return moving; },\n get turning() { return turning; },\n };\n}\n\n/** Render events → scene-style sound events (sound/cues.js vocabulary). */\nexport function soundEventsFor(event) {\n switch (eventKind(event)) {\n case 'fire': return [{ type: 'fire' }, { type: 'projectile_start' }];\n case 'impact': return [{ type: 'impact', kind: event.kind === 'obstacle' ? 'obstacle' : 'terrain' }];\n case 'hit': return [{ type: 'tank_hit' }];\n case 'destroyed': return [{ type: 'destroyed' }];\n default: return [];\n }\n}\n\n/** 'victory' | 'defeat' | null for the own player once the match is over. */\nexport function outcomeFor(render) {\n if (!render || render.status !== 'over') return null;\n const me = selfTank(render.tanks);\n if (!me || render.winner == null) return null;\n return String(render.winner) === String(me.id) ? 'victory' : 'defeat';\n}\n\n/** Own reload progress 0..1 (1 = ready): the tank's own field when given, else from the last own fire. */\nexport function reloadProgress(tank, lastFireAt, now, reloadMs = 1500) {\n if (!tank) return 1;\n if (Number.isFinite(tank.reload)) return Math.max(0, Math.min(1, tank.reload));\n if (Number.isFinite(tank.reloadMs)) return Math.max(0, Math.min(1, 1 - tank.reloadMs / reloadMs));\n if (!Number.isFinite(lastFireAt)) return 1;\n return Math.max(0, Math.min(1, (now - lastFireAt) / reloadMs));\n}\n","import { arenaBounds, arenaObstacles } from './liveView.js';\n\n/** Lightweight top-down fallback, with the same render/picking lifecycle as WebGL. */\nexport function createLiveScene2d(container, { arena } = {}) {\n const canvas = document.createElement('canvas');\n canvas.style.cssText = 'width:100%;height:100%;display:block';\n container.appendChild(canvas);\n const ctx = canvas.getContext('2d');\n if (!ctx) { canvas.remove(); throw new Error('Canvas 2D unavailable'); }\n const bounds = arenaBounds(arena);\n let w = 1; let h = 1; let scale = 1; let ox = 0; let oz = 0;\n function resize() {\n w = Math.max(1, container.clientWidth); h = Math.max(1, container.clientHeight);\n const dpr = Math.min(window.devicePixelRatio || 1, 2);\n canvas.width = w * dpr; canvas.height = h * dpr;\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n scale = Math.min(w / bounds.width, h / bounds.depth);\n ox = (w - bounds.width * scale) / 2; oz = (h - bounds.depth * scale) / 2;\n }\n resize();\n const ro = typeof ResizeObserver === 'function' ? new ResizeObserver(resize) : null;\n ro?.observe(container);\n return {\n kind: '2d', resize,\n screenToGround(nx, ny) { return { x: ((nx + 1) * w / 2 - ox) / scale + bounds.minX, z: ((1 - ny) * h / 2 - oz) / scale + bounds.minZ }; },\n render(state) {\n ctx.fillStyle = '#152519'; ctx.fillRect(0, 0, w, h);\n ctx.save(); ctx.translate(ox, oz); ctx.scale(scale, scale); ctx.translate(-bounds.minX, -bounds.minZ);\n ctx.fillStyle = '#526348'; ctx.fillRect(bounds.minX, bounds.minZ, bounds.width, bounds.depth);\n for (const obstacle of arenaObstacles(arena)) { ctx.fillStyle = obstacle.kind === 'tree' ? '#24472d' : '#929285'; ctx.beginPath(); ctx.arc(obstacle.x, obstacle.z, obstacle.r, 0, Math.PI * 2); ctx.fill(); }\n for (const tank of state.tanks || []) {\n ctx.save(); ctx.translate(tank.x, tank.z); ctx.rotate(tank.yaw);\n ctx.fillStyle = tank.alive === false ? '#333' : tank.color || '#73ce68';\n ctx.fillRect(-3, -1.8, 6, 3.6); ctx.restore();\n ctx.save(); ctx.translate(tank.x, tank.z); ctx.rotate(tank.turretYaw); ctx.strokeStyle = '#dce8cf'; ctx.lineWidth = 0.8; ctx.beginPath(); ctx.moveTo(0, 0); ctx.lineTo(5, 0); ctx.stroke(); ctx.restore();\n if (tank.self) { ctx.strokeStyle = '#fff'; ctx.lineWidth = 0.3; ctx.beginPath(); ctx.arc(tank.x, tank.z, 4, 0, Math.PI * 2); ctx.stroke(); }\n }\n ctx.fillStyle = '#ffe097';\n for (const shell of state.shells || []) { ctx.beginPath(); ctx.arc(shell.x, shell.z, 0.7, 0, Math.PI * 2); ctx.fill(); }\n ctx.restore();\n },\n dispose() { ro?.disconnect(); canvas.remove(); },\n };\n}\n","/* eslint-disable react/prop-types */\nimport { memo, useContext, useEffect, useRef, useState } from 'react';\nimport { ChatContext } from '../../provider/ChatContext.js';\nimport useChatGames from '../shared/useChatGames.js';\nimport GameSoundControls from '../shared/GameSoundControls.jsx';\nimport { connectionDiagnostics, connectionHint } from './net/connectionDiagnostics.js';\nimport { createLiveMatch } from './net/createLiveMatch.js';\nimport { createLiveScene2d } from './scene/createLiveScene2d.js';\nimport { createSelfTracker, outcomeFor, selfTank, soundEventsFor } from './scene/liveView.js';\nimport { getTanksSoundManager, startTanksSounds, handleSceneEvent, playOutcome, stopAllTanksLoops } from '../tanks/sound/tanksSounds.js';\nimport '../connect4/games.css';\nimport './tanks-live.css';\n\nconst act = (key, type) => { void useChatGames.getState().act(key, type).catch(() => {}); };\nconst stopInput = (input) => { input.throttle = 0; input.steer = 0; input.fire = false; };\nfunction TanksLiveGameCard({ gameKey, currentUserId, onMinimize, onDismiss, suspended = false }) {\n const rtcOptions = useContext(ChatContext)?.config?.webrtc;\n const game = useChatGames((state) => state.games[gameKey]);\n const suspendedRef = useRef(suspended);\n suspendedRef.current = suspended;\n const stage = useRef(null); const match = useRef(null); const renderer = useRef(null);\n const input = useRef({ throttle: 0, steer: 0, fire: false });\n const [view, setView] = useState(null); const [error, setError] = useState(''); const [prefer2d, setPrefer2d] = useState(false);\n const [mode, setMode] = useState('loading');\n useEffect(() => {\n if (suspended) { stopInput(input.current); stopAllTanksLoops(); }\n else renderer.current?.resize();\n }, [suspended]);\n const active = ['active', 'won'].includes(game?.status);\n const [arena, setArena] = useState(null);\n useEffect(() => {\n if (!active || !arena || !stage.current) return undefined;\n let disposed = false; let scene = null;\n const options = { arena, lowPower: matchMedia('(pointer: coarse)').matches, reducedMotion: matchMedia('(prefers-reduced-motion: reduce)').matches, onEvent: (event) => { if (event.type === 'context_lost') setPrefer2d(true); } };\n const fallback = () => { if (!disposed) { scene = createLiveScene2d(stage.current, options); renderer.current = scene; setMode('2d'); } };\n if (prefer2d) fallback();\n else import('./scene/createLiveScene.js').then(({ createLiveScene }) => { if (!disposed) { try { scene = createLiveScene(stage.current, options); renderer.current = scene; setMode('3d'); } catch { fallback(); } } }).catch(fallback);\n return () => { disposed = true; scene?.dispose(); if (renderer.current === scene) renderer.current = null; };\n }, [active, arena, prefer2d]);\n useEffect(() => {\n if (!active || game.status !== 'active' || !stage.current) return undefined;\n let disposed = false; let frame = 0; let last = performance.now(); let published = 0; let outcome = null;\n const tracker = createSelfTracker(); const keys = new Set();\n startTanksSounds();\n let session;\n try {\n const signaling = useChatGames.getState().createLiveSignaling(gameKey);\n session = createLiveMatch({ iceServers: rtcOptions?.iceServers, iceTransportPolicy: rtcOptions?.iceTransportPolicy, game, selfId: String(currentUserId), isHost: String(game.hostId) === String(currentUserId), signaling });\n match.current = session;\n } catch (e) { setError(e.message || 'No se pudo iniciar WebRTC'); return undefined; }\n setArena(session.getRender().arena);\n function clear() { keys.clear(); stopInput(input.current); stopAllTanksLoops(); }\n function key(event, down) {\n if (/^(INPUT|TEXTAREA|SELECT)$/.test(event.target?.tagName)) return;\n if (!['KeyW', 'KeyA', 'KeyS', 'KeyD', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Space'].includes(event.code)) return;\n event.preventDefault(); if (down) keys.add(event.code); else keys.delete(event.code);\n input.current.throttle = Number(keys.has('KeyW') || keys.has('ArrowUp')) - Number(keys.has('KeyS') || keys.has('ArrowDown'));\n input.current.steer = Number(keys.has('KeyD') || keys.has('ArrowRight')) - Number(keys.has('KeyA') || keys.has('ArrowLeft'));\n input.current.fire = keys.has('Space');\n }\n const down = (e) => key(e, true); const up = (e) => key(e, false);\n const host = stage.current;\n host.addEventListener('keydown', down); host.addEventListener('keyup', up); host.addEventListener('blur', clear);\n const visibility = () => { if (document.hidden) clear(); };\n document.addEventListener('visibilitychange', visibility);\n handleSceneEvent({ type: 'engine_start' }, gameKey);\n function tick(now) {\n if (disposed) return;\n const dt = Math.min(80, now - last); last = now;\n const paused = suspendedRef.current || document.hidden;\n session.setInput(paused ? { throttle: 0, steer: 0, fire: false } : input.current);\n session.step(dt); const state = session.getRender();\n if (!paused) renderer.current?.render(state, dt);\n if (paused) { keys.clear(); tracker.reset(); stopAllTanksLoops(); }\n if (!paused) for (const event of state.events || []) for (const sound of soundEventsFor(event)) handleSceneEvent(sound, event.id);\n if (!paused) for (const event of tracker.update(selfTank(state.tanks), dt)) handleSceneEvent(event);\n const nextOutcome = outcomeFor(state);\n if (nextOutcome && !outcome) { setView(state); outcome = nextOutcome; if (!paused) playOutcome(outcome, gameKey); useChatGames.getState().liveFinish?.(gameKey, state.winner); }\n if (now - published > 100) { published = now; setView(state); }\n frame = requestAnimationFrame(tick);\n }\n frame = requestAnimationFrame(tick);\n return () => {\n disposed = true; cancelAnimationFrame(frame); clear(); session.destroy(); match.current = null;\n host.removeEventListener('keydown', down); host.removeEventListener('keyup', up); host.removeEventListener('blur', clear); document.removeEventListener('visibilitychange', visibility);\n };\n }, [active, gameKey, currentUserId]);\n if (!game) return null;\n const guest = String(currentUserId) === String(game.guestId);\n const over = view?.status === 'over' || game.status === 'won';\n function aim(event) {\n const rect = stage.current?.getBoundingClientRect(); const me = selfTank(view?.tanks);\n if (!rect || !me) return;\n const ground = renderer.current?.screenToGround((event.clientX - rect.left) / rect.width * 2 - 1, 1 - (event.clientY - rect.top) / rect.height * 2);\n if (ground) input.current.turretYaw = Math.atan2(ground.z - me.z, ground.x - me.x);\n }\n const hold = (field, value) => ({ onPointerDown: (e) => { e.preventDefault(); e.currentTarget.setPointerCapture(e.pointerId); input.current[field] = value; }, onPointerUp: () => { input.current[field] = field === 'fire' ? false : 0; }, onPointerCancel: () => { input.current[field] = field === 'fire' ? false : 0; }, onLostPointerCapture: () => { input.current[field] = field === 'fire' ? false : 0; } });\n return <section className={`chat-game-card tl-card${active ? ' tl-card--active' : ''}`} aria-label=\"Tanques LIVE 3D\">\n <header className=\"tl-header\"><strong>Tanques LIVE 3D</strong><div className=\"tl-header-actions\"><GameSoundControls manager={getTanksSoundManager()} />{onMinimize && <button onClick={onMinimize} aria-label=\"Minimizar\">−</button>}{onDismiss && <button onClick={onDismiss} aria-label=\"Ocultar\">×</button>}</div></header>\n {game.status === 'invited' && <div className=\"tl-invite\"><span className=\"tl-invite-icon\" aria-hidden=\"true\">🪖</span><strong>{guest ? '¿Listo para combatir?' : 'Invitación enviada'}</strong><p>{guest ? 'Te invitaron a un combate en tiempo real.' : 'Esperando que el rival acepte…'}</p>{guest && <div className=\"tl-invite-actions\"><button className=\"tl-button-primary\" onClick={() => act(gameKey, 'game_accept')}>Aceptar combate</button><button onClick={() => act(gameKey, 'game_decline')}>Rechazar</button></div>}</div>}\n {(active || view) && <><div className=\"tl-hud\">{(view?.tanks || []).map((tank) => <span key={tank.id}>{tank.self ? 'Tú' : 'Rival'} <meter min=\"0\" max=\"100\" value={tank.hp} aria-label={tank.self ? 'Tu vida' : 'Vida del rival'} /> {tank.hp} HP</span>)}<span role=\"status\">{view?.net?.phase || 'Conectando WebRTC…'} {view?.net?.route?.label || (typeof view?.net?.route === 'string' ? view.net.route : '')} {Number.isFinite(view?.net?.rtt) ? `${Math.round(view.net.rtt)} ms` : ''}</span></div>\n <div className=\"tl-stage\" ref={stage} tabIndex={0} aria-label=\"Arena. WASD o flechas para conducir, ratón para apuntar, clic o espacio para disparar\" onPointerMove={aim} onPointerDown={(e) => { aim(e); if (e.pointerType === 'mouse') { e.currentTarget.focus(); e.currentTarget.setPointerCapture(e.pointerId); aim(e); input.current.fire = true; } }} onPointerUp={() => { input.current.fire = false; }} onPointerCancel={() => { stopInput(input.current); }} onLostPointerCapture={() => { input.current.fire = false; }} />\n <div className=\"tl-controls\"><div className=\"tl-joystick\" role=\"group\" aria-label=\"Joystick de conducción\" onPointerDown={(e) => { e.preventDefault(); e.currentTarget.setPointerCapture(e.pointerId); const r = e.currentTarget.getBoundingClientRect(); input.current.steer = Math.max(-1, Math.min(1, (e.clientX - r.left - r.width / 2) / (r.width / 2))); input.current.throttle = Math.max(-1, Math.min(1, -(e.clientY - r.top - r.height / 2) / (r.height / 2))); }} onPointerMove={(e) => { if (!e.currentTarget.hasPointerCapture(e.pointerId)) return; const r = e.currentTarget.getBoundingClientRect(); input.current.steer = Math.max(-1, Math.min(1, (e.clientX - r.left - r.width / 2) / (r.width / 2))); input.current.throttle = Math.max(-1, Math.min(1, -(e.clientY - r.top - r.height / 2) / (r.height / 2))); }} onPointerUp={() => stopInput(input.current)} onPointerCancel={() => stopInput(input.current)} onLostPointerCapture={() => stopInput(input.current)}>✥</div><div className=\"tl-drive\" aria-label=\"Controles de conducción\"><button aria-label=\"Avanzar\" {...hold('throttle', 1)}>▲</button><button aria-label=\"Girar izquierda\" {...hold('steer', -1)}>◀</button><button aria-label=\"Retroceder\" {...hold('throttle', -1)}>▼</button><button aria-label=\"Girar derecha\" {...hold('steer', 1)}>▶</button></div><button className=\"tl-fire\" {...hold('fire', true)}>Disparar</button></div>\n <div className=\"tl-reload\"><label>Recarga <progress max=\"1\" value={selfTank(view?.tanks)?.reload ?? 1} /> {(selfTank(view?.tanks)?.reload ?? 1) >= 1 ? 'Listo' : 'Recargando…'}</label></div>\n <small>WASD / flechas · ratón o toca la arena para apuntar · espacio / clic para disparar</small><button onClick={() => setPrefer2d((v) => !v)}>{mode === '2d' ? 'Probar 3D' : 'Vista 2D'}</button>\n </>}\n {over && <p role=\"status\">{String(view?.winner ?? game.winnerId) === String(currentUserId) ? '¡Victoria!' : 'Fin del combate'} <button onClick={() => { void Promise.resolve(useChatGames.getState().liveRematch?.(gameKey)).catch(() => {}); }}>Revancha</button></p>}\n {active && !over && view?.net?.phase !== 'connected' && <div className=\"tl-connection\">\n <p role=\"status\">{connectionHint(view?.net)}</p>\n <button type=\"button\" onClick={() => match.current?.reconnect()}>Reintentar conexión</button>\n </div>}\n {active && <details className=\"tl-diagnostics\"><summary>Diagnóstico de conexión</summary><pre>{JSON.stringify(connectionDiagnostics(view?.net), null, 2)}</pre></details>}\n {active && !over && <button onClick={() => match.current?.resign()}>Rendirse</button>}\n {game.pending && <p role=\"status\">Enviando…</p>}{game.pendingEvent && game.error && <button onClick={() => { void useChatGames.getState().retry(gameKey).catch(() => {}); }}>Reintentar envío</button>}\n {error && <p role=\"alert\">{error}</p>}{game.error && <p role=\"alert\">{game.error}</p>}\n {!['closed', 'declined'].includes(game.status) && <footer className=\"tl-footer\"><button onClick={() => act(gameKey, 'game_end')}>Cerrar partida</button></footer>}\n </section>;\n}\nexport default memo(TanksLiveGameCard);\n"],"mappings":";;;;;;;;;;;;;;;;AACA,SAAgBkB,EAAsB,IAAM,CAAC,GAAG;CAC9C,OAAO;EACL,OAAOC,EAAI,SAAS;EAAQ,KAAKA,EAAI,OAAO;EAC5C,YAAYA,EAAI,cAAc;EAAO,WAAWA,EAAI,aAAa;EACjE,WAAW;GACT,MAAMA,EAAI,SAAS,QAAQ;GAAG,UAAUA,EAAI,SAAS,YAAY;GACjE,cAAcA,EAAI,SAAS,gBAAgB;GAC3C,SAASA,EAAI,SAAS,WAAW;GAAG,SAASA,EAAI,SAAS,WAAW;GACrE,aAAaA,EAAI,SAAS,eAAe;EAC3C;EACA,gBAAgB,EAAQA,EAAI;EAC5B,OAAOA,EAAI,OAAO,SAAS;EAC3B,WAAWA,EAAI,MAAM,QAAQ;EAAG,eAAeA,EAAI,MAAM,YAAY;EACrE,OAAOA,EAAI,QAAS,YAAY,KAAKA,EAAI,KAAK,IAAIA,EAAI,QAAQ,sBAAuB;CACvF;AACF;AAEA,SAAgBC,EAAe,IAAM,CAAC,GAAG;CAQvC,OAPID,EAAI,UAAU,cAAoB,KAClCA,EAAI,SAAS,eAAqB,yFAClCA,EAAI,QAAQ,cAAcA,EAAI,QAAQ,WAAiBA,EAAI,iBAC3D,4FACA,2IACAA,EAAI,UAAU,cAAoB,+GAClCA,EAAI,UAAU,WAAiB,+EAC5B;AACT;;AC1BA,IAAaE,IAAQ,OAAO,OAAO;CAAE,OAAO;CAAI,SAAS;CAAG,MAAM;CAAK,cAAc;CAAI,QAAQ;CAAG,UAAU;CAAM,YAAY;CAAI,QAAQ;AAAG,CAAC,GACnIC,KAAS,GAAG,GAAI,MAAO,KAAK,IAAIC,GAAI,KAAK,IAAIC,GAAIC,CAAC,CAAC,GACnDC,KAAc,GAAG,MAAM,KAAK,MAAM,KAAK,IAAIC,IAAIC,CAAC,GAAG,KAAK,IAAID,IAAIC,CAAC,CAAC;AAC/E,SAAgBC,IAAc;CAC5B,OAAO;EAAE,MAAM;EAAK,QAAQ;GAAE,MAAM;GAAG,MAAM;GAAK,MAAM;GAAG,MAAM;EAAI;EAAG,WAAW;GACjF;IAAC;IAAI;IAAI;GAAC;GAAG;IAAC;IAAI;IAAI;GAAC;GAAG;IAAC;IAAI;IAAI;GAAC;GAAG;IAAC;IAAI;IAAI;GAAC;GAAG;IAAC;IAAI;IAAI;GAAC;GAAG;IAAC;IAAI;IAAI;GAAC;GAAG;IAAC;IAAI;IAAI;GAAC;EAC1F,CAAC,CAAC,KAAK,CAACC,GAAGC,GAAGC,IAAI,OAAO;GAAE;GAAG;GAAG;GAAG,MAAMC,IAAI,IAAI,SAAS;EAAO,EAAE;CAAE;AACxE;AACA,SAAgBC,EAAW,GAAI,GAAO;CAAE,OAAO;EAAE,IAAI,OAAOC,CAAE;EAAG,GAAGC,IAAQ,MAAM;EAAI,GAAG;EAAI,KAAKA,IAAQ,KAAK,KAAK;EAAG,WAAWA,IAAQ,KAAK,KAAK;EAAG,OAAO;EAAG,IAAI;EAAK,OAAO;EAAM,OAAOA,IAAQ,YAAY;CAAU;AAAG;AAC/N,SAAgBC,EAAc,GAAG,GAAG,GAAO,IAAShB,EAAM,QAAQ;CAChE,IAAMM,IAAIW,EAAM;CAChB,OAAOR,KAAKH,EAAE,OAAOY,KAAUT,KAAKH,EAAE,OAAOY,KAAUR,KAAKJ,EAAE,OAAOY,KAAUR,KAAKJ,EAAE,OAAOY,KACxF,CAACD,EAAM,UAAU,MAAK,MAAK,KAAK,MAAMR,IAAIU,EAAE,GAAGT,IAAIS,EAAE,CAAC,IAAIA,EAAE,IAAID,CAAM;AAC7E;AACA,SAAgBE,EAAS,GAAM,GAAO,GAAI,GAAO;CAC/C,IAAI,CAACC,EAAK,OAAO;CACjB,IAAMC,IAAWrB,EAAM,OAAOsB,EAAM,QAAQ,KAAK,GAAG,IAAI,CAAC,GAAGC,IAAQvB,EAAM,OAAOsB,EAAM,KAAK,KAAK,GAAG,IAAI,CAAC,GACnG9B,IAAS6B,KAAYA,IAAW,IAAItB,EAAM,UAAUA,EAAM;CAGhE,AAFA,EAAK,SAASC,EAAMR,IAAS4B,EAAK,OAAO,CAACrB,EAAM,eAAeyB,GAAIzB,EAAM,eAAeyB,CAAE,GAC1F,EAAK,OAAOD,IAAQxB,EAAM,OAAOyB,GAC7B,OAAO,SAASF,EAAM,SAAS,MAAG,EAAK,YAAYA,EAAM;CAC7D,IAAMd,IAAIY,EAAK,IAAI,KAAK,IAAIA,EAAK,GAAG,IAAIA,EAAK,QAAQI,GAAIf,IAAIW,EAAK,IAAI,KAAK,IAAIA,EAAK,GAAG,IAAIA,EAAK,QAAQI;CAExG,AADIT,EAAcP,GAAGY,EAAK,GAAGJ,CAAK,IAAG,EAAK,IAAIR,IAAQ,EAAK,QAAQ,GAC/DO,EAAcK,EAAK,GAAGX,GAAGO,CAAK,IAAG,EAAK,IAAIP,IAAQ,EAAK,QAAQ;AACrE;AACA,SAAgBgB,EAAc,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAQ;CAC5D,IAAMC,IAAKC,IAAKC,GAAIC,IAAKC,IAAKC,GAAIC,IAASN,IAAKA,IAAKG,IAAKA,GACpDI,IAAID,IAAShC,IAAQkC,IAAKN,KAAMF,KAAMS,IAAKJ,KAAMF,KAAMG,GAAQ,GAAG,CAAC,IAAI;CAC7E,OAAO,KAAK,MAAMJ,IAAKF,IAAKO,IAAIC,GAAIH,IAAKF,IAAKI,IAAIE,CAAE,KAAKlB,IAASgB,IAAI;AACxE;AACA,SAAgBG,GAAa,GAAO,GAAI,GAAO,GAAO;CACpD,IAAM5B,IAAI6B,EAAM,IAAI,KAAK,IAAIA,EAAM,GAAG,IAAItC,EAAM,aAAayB,GAAIf,IAAI4B,EAAM,IAAI,KAAK,IAAIA,EAAM,GAAG,IAAItC,EAAM,aAAayB,GACpHc,IAAQ;CACZ,KAAK,IAAMpB,KAAKF,EAAM,WAAW;EAAE,IAAMiB,IAAIR,EAAcY,EAAM,GAAGA,EAAM,GAAG7B,GAAGC,GAAGS,EAAE,GAAGA,EAAE,GAAGA,EAAE,CAAC;EAAG,AAAIe,MAAM,SAAS,CAACK,KAASL,IAAIK,EAAM,OAAI,IAAQ;GAAE;GAAG,MAAM;EAAW;CAAG;CAC/K,KAAK,IAAMlB,KAAQmB,GAAO;EAAE,IAAI,CAACnB,EAAK,SAASA,EAAK,OAAOiB,EAAM,OAAO;EAAU,IAAMJ,IAAIR,EAAcY,EAAM,GAAGA,EAAM,GAAG7B,GAAGC,GAAGW,EAAK,GAAGA,EAAK,GAAGrB,EAAM,MAAM;EAAG,AAAIkC,MAAM,SAAS,CAACK,KAASL,IAAIK,EAAM,OAAI,IAAQ;GAAE;GAAG,MAAM;GAAQ,QAAQlB,EAAK;EAAG;CAAG;CAG1P,OAFIkB,KAAS,EAAM,MAAM9B,IAAI6B,EAAM,KAAKC,EAAM,GAAG,EAAM,MAAM7B,IAAI4B,EAAM,KAAKC,EAAM,GAAUA,MAC5F,EAAM,IAAI9B,GAAG,EAAM,IAAIC,GAAG,EAAM,OAAOe,GAChC,CAACT,EAAcP,GAAGC,GAAG;EAAE,GAAGO;EAAO,WAAW,CAAC;CAAE,GAAG,CAAC,KAAKqB,EAAM,MAAM,IAAI,EAAE,MAAM,UAAU,IAAI;AACvG;AACA,SAAgBG,GAAgB,GAAG,GAAG,GAAU;CAC9C,IAAMP,IAAIjC,EAAMyC,GAAU,GAAG,CAAC;CAC9B,OAAO;EAAE,GAAGpC;EAAG,GAAGC,EAAE,KAAKD,EAAE,IAAIC,EAAE,KAAK2B;EAAG,GAAG3B,EAAE,KAAKD,EAAE,IAAIC,EAAE,KAAK2B;EAAG,KAAK3B,EAAE,MAAMF,EAAWE,EAAE,KAAKD,EAAE,GAAG,IAAI4B;EAAG,WAAW3B,EAAE,YAAYF,EAAWE,EAAE,WAAWD,EAAE,SAAS,IAAI4B;CAAE;AAClL;;ACvCA,IAAMS,KAAS,MAAK,OAAOvC,KAAM,YAAY,OAAO,SAASA,CAAC,GACxDwC,KAAU,MAAM,OAAO9B,KAAO,YAAYA,EAAG,SAAS,KAAKA,EAAG,SAAS;AAC7E,SAAgB+B,EAAgB,EAAE,SAAM,WAAQ,YAAS,OAAOC,CAAM,MAAM,OAAOC,EAAK,MAAM,GAAG,cAAW,oBAAiB,CAAC,GAAG,iBAAchE,GAAgB,eAAY,uBAAoB,6BAA0B,CAAC,GAAG;CAC3N,IAAS,OAAO+D,CAAM;CACtB,IAAME,IAAM,CAAC,OAAOD,EAAK,MAAM,GAAG,OAAOA,EAAK,OAAO,CAAC;CACtD,IAAI,CAACC,EAAI,SAASF,CAAM,KAAKE,EAAI,OAAOA,EAAI,IAAI,MAAU,MAAM,4BAA4B;CAC5F,IAAMC,KAAkBC,KAAc,CAAC,EAAA,CAAG,MAAK,MAAU,CAACC,EAAO,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,MAAK,MAAO,YAAY,KAAK,OAAOC,CAAG,CAAC,CAAC,CAAC,GAClHC,IAASL,EAAI,MAAK,MAAMlC,MAAOgC,CAAM,GAAG7B,IAAQT,EAAY,GAC9DgC,IAAQQ,EAAI,IAAInC,CAAU,GAAGyC,IAAS,CAAC,GAAGC,IAAS,CAAC,GAAGhC,IAAQ,CAAC,GAAGiC,IAAO,GAAGC,IAAS,GAAGC,IAAQ,GAAGC,IAAW,GAC/GC,IAAS,cAAcC,IAAS,MAAMC,IAAY,IAAOhE,IAAM;EAAE,OAAO;EAAQ,KAAK;EAAM,OAAO;CAAK,GAAGiE,IAAe,IAAOC,IAAgB,IAAOC,IAAY,MACnKC,IAAQ,CAAC,GAAGC,IAAa,MAAMC,IAAW,MAAMC,oBAAW,IAAI,IAAI,GAAGC,oBAAO,IAAI,IAAI,GAAGC,oBAAe,IAAI,IAAI,GAC7GC,UAAWhC,EAAM,MAAK,MAAKN,EAAE,OAAOY,CAAM,GAAG2B,WAAcjC,EAAM,MAAK,MAAKN,EAAE,OAAOmB,CAAM,GAC1FqB,UAAe;EAAE,AAAKZ,KAAWa,EAAS;GAAE;GAAQ;GAAQ;EAAI,CAAC;CAAG,GACpEC,KAAO,MAAK;EAAkB,AAAhBrB,EAAO,KAAK,CAAC,GAAOA,EAAO,SAAS,OAAKA,EAAO,MAAM;CAAG,GACvEsB,KAAO,MAAKC,EAAK,UAAU;EAAE,GAAGC;EAAG,GAAGhC,EAAK;EAAQ,GAAGW;CAAM,CAAC,GAC7DsB,KAAW,MAAO;EAAiB,AAAfV,EAAK,IAAIW,CAAG,GAAOX,EAAK,OAAO,QAAMA,EAAK,OAAOA,EAAK,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK;CAAG,GAClGY,WAAkB;EAAE,GAAG;EAAY,IAAI1C,EAAM,KAAI,MAAKN,EAAE,EAAE;EAAG;EAAQ;EAAQ,QAAQ+B;CAAU;CACrG,SAASkB,IAAQ;EACgR,AAA/R,IAAQnC,EAAI,IAAInC,CAAU,GAAG,IAAS,CAAC,GAAG,IAAQ,CAAC,GAAG,IAAa,MAAM,IAAW,MAAMwD,EAAS,MAAM,GAAGC,EAAK,MAAM,GAAGC,EAAa,MAAM,GAAG,IAAgB,IAAO,IAAY,MAAM,IAAS,MAAM,IAASzE,EAAI,UAAU,cAAc,YAAY,cAAc8E,EAAK,EAAE,GAAG,UAAU,CAAC,GAAGF,EAAO;CACxS;CACA,SAASU,EAAO,GAAI,IAAQ,IAAO;EAAE,CAAIxB,MAAW,UAAYyB,KAASxB,MAAW/C,OAAa,IAAS,QAAQ,IAASA,GAAI,IAAS,CAAC,GAAG8D,EAAK;GAAE,GAAG;GAAQ;EAAO,CAAC,GAAGF,EAAO;CAAG;CACnL,SAASY,EAAK,GAAO,GAAG,GAAW;EACjC,IAAI1B,MAAW,aAAa,CAAChB,EAAQmC,EAAE,EAAE,KAAKT,EAAK,IAAIS,EAAE,EAAE,GAAG,OAAO;EACrE,IAAM1D,IAAOmB,EAAM,MAAK,MAAK,EAAE,OAAO+C,CAAK;EAE3C,IADI,CAAClE,GAAM,SAASmC,KAAQa,EAAS,IAAIkB,CAAK,KAAK,aAAavF,EAAM,WAAW,MAC7E,CAAC;GAAC+E,EAAE;GAAGA,EAAE;GAAGA,EAAE;EAAG,CAAC,CAAC,MAAMpC,CAAM,KAAK,KAAK,MAAMoC,EAAE,KAAKQ,MAAUlC,KAAUe,IAAWA,EAAS,IAAI/C,EAAK,IAAI0D,EAAE,KAAKQ,MAAUlC,KAAUe,IAAWA,EAAS,IAAI/C,EAAK,EAAE,IAAI,GAAG,OAAO;EAEvL,AADA2D,EAASD,EAAE,EAAE,GACbV,EAAS,IAAIkB,GAAO/B,CAAI;EACxB,IAAMgC,IAAO;GAAE,GAAGT;GAAG,GAAG;GAAQ;GAAO,GAAGA,EAAE,IAAI,KAAK,IAAIA,EAAE,GAAG,IAAI;GAAK,GAAGA,EAAE,IAAI,KAAK,IAAIA,EAAE,GAAG,IAAI;GAAK,GAAG;GAAK,KAAK;EAAE;EAC7C,OAAzEzB,EAAO,KAAKkC,CAAI,GAAGZ,EAAKY,CAAI,GAAOC,KAAWZ,EAAK;GAAE,GAAGE;GAAG,GAAG;EAAO,CAAC,GAAU;CAClF;CACA,SAASW,GAAY,GAAM;EACzB,IAAI5B,KAAaF,MAAW,aAAa+B,GAAM,MAAM5C,EAAK,UAAU4C,EAAK,MAAMjC,KAAS,CAAC,MAAM,QAAQiC,EAAK,CAAC,KAAKA,EAAK,EAAE,WAAW,KAAK,CAACA,EAAK,EAAE,MAAMhD,CAAM,GAAG;EAChK,IAAM,CAAClC,GAAGC,GAAGkF,GAAKC,GAAWC,KAASH,EAAK;EAC3C,IAAI,CAAC3E,EAAcP,GAAGC,GAAGO,CAAK,KAAK,KAAK,IAAI6E,CAAK,IAAI9F,EAAM,QAAQ,MAAO,KAAK,IAAI4F,CAAG,IAAI,OAAO,KAAK,IAAIC,CAAS,IAAI,KAAK;EAC5H,IAAME,IAAU5B,MAAe,OAAO,KAAM,KAAK,IAAI,IAAIX,IAAOW,KAAc,GAAI,GAC5E6B,IAAW5B,KAAYK,GAAM;EACnC,IAAI,KAAK,MAAMhE,IAAIuF,EAAS,GAAGtF,IAAIsF,EAAS,CAAC,IAAIhG,EAAM,QAAQ+F,IAAU,GAAG;EAC5E,IAAME,IAAO;GAAE,GAAGxB,GAAM;GAAG;GAAG;GAAG;GAAK;GAAW;EAAM;EACS,AAAhE,IAAWwB,GAAM,IAAazC,GAAMU,EAAM,KAAK;GAAE;GAAM;EAAK,CAAC,GAAOA,EAAM,SAAS,MAAIA,EAAM,MAAM;CACrG;CACA,SAASgC,GAAa,GAAG;EACvB,IAAI,MAAcnB,KAAKA,EAAE,MAAMhC,EAAK,UAAW,OAAO,UAAUgC,EAAE,CAAC,GACnE;OAAIA,EAAE,MAAM,WAAW,CAACoB,KAAUvC,MAAW,UAAUW,EAAa,IAAIzB,CAAM,KAAKiC,EAAE,MAAMrB,IAAQ,GAAkB,AAAb,IAAQqB,EAAE,GAAGI,EAAM;QAC3H,IAAIJ,EAAE,MAAMrB,GACZ;QAAIqB,EAAE,MAAM,UAAUoB,GAAU,EAAKjB,EAAS,CAAC;SAC/C,IAAIH,EAAE,MAAM,cAAc,CAACoB,KAAU,MAAM,QAAQpB,EAAE,EAAE,KAAKA,EAAE,GAAG,WAAW,KAAKA,EAAE,GAAG,OAAM,MAAM,OAAO,UAAUqB,CAAE,KAAKA,KAAM,KAAKA,KAAM,GAAG,GAAG;KAC/I,IAAMC,IAAetB,EAAE,WAAW,aAAaA,EAAE,WAAW,QAAQA,EAAE,GAAG,OAAM,MAAMqB,IAAK,CAAC,GACrFE,IAAYvB,EAAE,WAAW,UAAU/B,EAAI,SAAS+B,EAAE,MAAM,MAAMA,EAAE,GAAG,IAAI/B,EAAI,QAAQ+B,EAAE,MAAM,OAAO,KAAKA,EAAE,WAAW;KAC1H,IAAI,CAACsB,KAAgB,CAACC,GAAW;KAEjC,AADA9D,EAAM,SAAS,GAAG,MAAM;MAAkB,AAAhB,EAAE,KAAKuC,EAAE,GAAGnE,IAAI,EAAE,QAAQsB,EAAE,KAAK;KAAG,CAAC,GAC3DoE,MAAa,IAAgB,IAAO,IAAYvB,EAAE,QAAQK,EAAOL,EAAE,QAAQ,EAAI;IAErF,OACA,AAAIA,EAAE,MAAM,YAAY,IAAY,YAAYK,EAAOtC,GAAQqD,CAAM,GAAOA,KAAQtB,EAAKK,EAAS,CAAC,KAC/FH,EAAE,MAAM,aAAanB,MAAW,UAAUW,EAAa,IAAIlB,CAAM,GAAGkD,GAAa,KACjF3C,MAAW,cACXmB,EAAE,MAAM,UAAQO,EAAKjC,GAAQ0B,GAAG,EAAK,GACrC,CAACoB,KAAUpB,EAAE,MAAM,SAASnC,EAAQmC,EAAE,EAAE,KAAK,CAACT,EAAK,IAAI,OAAOS,EAAE,IAAI,KAAK/B,EAAI,SAAS+B,EAAE,MAAM,KAAK,MAAM,QAAQA,EAAE,EAAE,KAAKA,EAAE,GAAG,WAAW,KAAKA,EAAE,GAAG,OAAO,GAAI,MAAM,OAAO,UAAUqB,CAAE,KAAKA,KAAM,KAAKA,KAAM5D,EAAM5B,EAAE,CAAC,EAAE,KAAK,CAACmE,EAAE,GAAGA,EAAE,CAAC,CAAC,CAAC,MAAMpC,CAAM,MACvPqC,EAAS,OAAOD,EAAE,IAAI,GAAGvC,EAAM,SAAS,GAAM,MAAM;KAAqB,AAAnB,EAAK,KAAKuC,EAAE,GAAGnE,IAAI,EAAK,QAAQS,EAAK,KAAK;IAAG,CAAC,GAAG,IAASiC,EAAO,QAAO,MAAKkD,EAAE,OAAOzB,EAAE,EAAE,GAAGH,EAAKG,CAAC,IAEvJ,CAACoB,KAAUpB,EAAE,MAAM,eAAe/B,EAAI,SAAS+B,EAAE,MAAM,KAAK,CAACT,EAAK,IAAI,aAAaS,EAAE,QAAQ,KAAKvC,EAAM,MAAK,MAAKN,EAAE,OAAO6C,EAAE,MAAM,CAAC,CAAC,OAAO,MAAKC,EAAS,aAAaD,EAAE,QAAQ,GAAGH,EAAKG,CAAC,IAC1L,CAACoB,KAAUpB,EAAE,MAAM,UAAU/B,EAAI,SAAS+B,EAAE,MAAM,KAAKvC,EAAM,MAAK,MAAKN,EAAE,OAAO6C,EAAE,MAAM,CAAC,CAAC,OAAO,KAAGK,EAAOL,EAAE,MAAM;GAjB7D;EAF4E;CAoBxI;CAMA,IAAMD,IAAO2B,EAAY;EAAE,WAJHC,KAAa;GACnC,KAAK,GAAM;IAAE,IAAMC,IAAS7H,EAAa8H,CAAI;IAAG,IAAI,CAACD,GAAQ,OAAO,QAAQ,OAAO,gBAAI,MAAM,qBAAqB,CAAC;IAAG,IAAME,IAAS7H,EAAa;KAAE,GAAG2H;KAAQ,UAAU5D,EAAK;IAAO,CAAC;IAAG,OAAO8D,IAASH,EAAU,KAAKG,CAAM,IAAI,QAAQ,OAAO,gBAAI,MAAM,uBAAuB,CAAC;GAAG;GACtR,UAAU,GAAU;IAAE,OAAOH,EAAU,WAAU,MAAS;KAA4C,AAA3B5H,EAAagI,GAAO,IAAgB,CAAC,EAAE,aAAa/D,EAAK,UAAQgE,EAASD,CAAK;IAAG,CAAC;GAAG;EACnK;EACuD;EAAQ;EAAQ,QAAQ/D,EAAK;EAAQ;EAAY;EAAoB;EAAuB,QAAQ2C;EAAa,SAASQ;EAAc,SAAS,GAAO;GAC7M,IAAMc,IAAgBlH,EAAI;GAC1B,IADiC,IAAMmH,GACnCA,EAAM,UAAU,aAAa;IAAE,IAAMC,IAAUnD;IAA8E,AAAhE,IAAe,IAAUH,MAAW,WAAQ,IAAS,YAAeoD,MAAkB,eAAa,qBAAqB;KAAE,AAAKlD,MAAiBE,KAAea,EAAK,EAAE,GAAG,SAAS,CAAC,GAAOsB,KAAUe,IAASrC,EAAKK,EAAS,CAAC,IAAaiB,KAAQtB,EAAK,EAAE,GAAG,OAAO,CAAC;IAAK,CAAC;GAAG,OACxU,AAAIjB,MAAW,WAAQ,IAASG,IAAe,iBAAiB;GACrE,EAAO;EACT;CAAE,CAAC;CACH,SAASwC,KAAe;EAAE,AAAIJ,KAAU5B,EAAa,SAAS,MAAK,KAASM,EAAK,EAAE,GAAG,QAAQ,CAAC,GAAGM,EAAM;CAAK;CAE7G,OADIgB,IAAQrB,EAAK,QAAQ,IAAQA,EAAK,aAAa,EAAI,GAChD;EACL,SAAS,GAAM;GAAE,IAAQ,EAAE,GAAGqC,EAAK;EAAG;EACtC,KAAK,GAAM;GACT,IAAIrD,GAAW;GACf,IAAMiC,IAAU,KAAK,IAAI,GAAG,KAAK,IAAI,OAAOqB,CAAI,KAAK,GAAG,GAAG,CAAC;GAC5D,IAD+D,KAAQrB,GACnEnC,MAAW,WAAW;GAC1B,IAAMnC,IAAKsE,IAAU,KACfsB,IAAa7D,IAAO;GAC1B,OAAOU,EAAM,SAAS,KAAKA,EAAM,EAAE,CAAC,QAAQmD,IAAY,EAAM,MAAM;GACpE,IAAInD,EAAM,QAAQ;IAAE,IAAM3D,IAAI2D,EAAM,IAAI5D,IAAI4D,EAAM,MAAM3D,GAAS0F,IAAOxD,GAAgBlC,EAAE,MAAMD,EAAE,MAAMA,EAAE,SAASC,EAAE,OAAO,KAAK8G,IAAa9G,EAAE,SAASD,EAAE,OAAOC,EAAE,KAAK;IAAG,KAAK,IAAM0E,KAAO;KAAC;KAAK;KAAK;KAAO;KAAa;IAAO,GAAG,GAAM,CAAC,CAACA,KAAOgB,EAAKhB;GAAM;GACjQ,KAAK,IAAIqC,IAAY7F,GAAI6F,IAAY,GAAG,KAAa,MAAO,EAAS9C,EAAG,GAAGjD,GAAO,KAAK,IAAI+F,GAAW,IAAK,GAAGrG,CAAK;GACnH,AAAIM,EAAM,QAAM+D,EAAKxC,GAAQ;IAAE,IAAI,GAAGA,EAAO,GAAGY,EAAM,GAAG,EAAEC;IAAY,GAAGa,EAAG,CAAC,CAAC;IAAG,GAAGA,EAAG,CAAC,CAAC;IAAG,KAAKA,EAAG,CAAC,CAAC;IAAW,GAAGhB;GAAK,GAAG,EAAI;GACjI,IAAM+D,IAAKzH,EAAI,MAAM,OAAOA,EAAI,MAAM,UAAU,KAAK,KAAKA,EAAI,MAAM,MAAM,KAAK;GAC/E,IAAI0D,KAAQC,GAAQ;IAAE,IAASD,IAAO,MAAO+D;IAAI,IAAM,IAAI/C,EAAG;IAAG,EAAK,SAAS;KAAE,GAAGzB,EAAK;KAAQ,GAAGW;KAAO,GAAG;MAAC,EAAE;MAAG,EAAE;MAAG,EAAE;MAAK,EAAE;MAAW,EAAE;KAAK;KAAG,GAAGF;IAAK,CAAC;GAAG;GACnK,IAASF,EAAO,QAAO,MAAS;IAC9B,IAAMkE,IAAMnF,GAAaC,GAAOb,GAAIR,GAAOuB,CAAK;IAChD,IAAI,CAACgF,GAAK,OAAO;IACjB,IAAIrB,KAAUqB,EAAI,UAAU5D,MAAW,WAAW;KAChD,IAAMvC,IAAOmB,EAAM,MAAK,MAAKN,EAAE,OAAOsF,EAAI,MAAM;KAAkD,AAA/C,EAAK,KAAK,KAAK,IAAI,GAAGnG,EAAK,KAAKrB,EAAM,MAAM,GAAG,EAAK,QAAQqB,EAAK,KAAK;KACzH,IAAM0D,IAAI;MAAE,GAAG;MAAO,IAAIzC,EAAM;MAAI,QAAQjB,EAAK;MAAI,KAAKrB,EAAM;MAAQ,IAAIwC,EAAM,KAAI,MAAKN,EAAE,EAAE;MAAG,GAAGI,EAAM;MAAG,GAAGA,EAAM;KAAE;KACzH,IAD4HuC,EAAKE,CAAC,GAAGH,EAAKG,CAAC,GACvI,CAAC1D,EAAK,OAAO;MAAE,IAAM0D,IAAI;OAAE,GAAG;OAAa,QAAQ1D,EAAK;MAAG;MAA+D,AAA5DwD,EAAKE,CAAC,GAAGH,EAAKG,CAAC,GAAGF,EAAK;OAAE,GAAG;OAAQ,QAAQvC,EAAM;MAAM,CAAC,GAAG8C,EAAO9C,EAAM,KAAK;KAAG;IACrJ,OAAO,EAAK;KAAE,GAAG;KAAU,MAAMkF,EAAI;KAAM,GAAGlF,EAAM;KAAG,GAAGA,EAAM;IAAE,CAAC;IACnE,OAAO;GACT,CAAC;EACH;EACA,YAAY;GAAE,IAAMmF,IAAM;IAAE;IAAO,OAAOjF,EAAM,KAAI,OAAM;KAAE,GAAGN;KAAG,MAAMA,EAAE,OAAOY;KAAQ,QAAQ,KAAK,IAAI,IAAIU,KAAQa,EAAS,IAAInC,EAAE,EAAE,KAAK,cAAclC,EAAM,QAAQ;IAAE,EAAE;IAAG,QAAQsD,EAAO,KAAI,OAAM,EAAE,GAAGkD,EAAE,EAAE;IAAG;IAAQ;IAAQ;IAAQ,KAAK;KAAE,GAAG1G;KAAK;IAAe;GAAE;GAAgB,OAAb,IAAS,CAAC,GAAU2H;EAAK;EACxS,YAAY;GAAE,AAAI,CAAC3D,KAAaF,MAAW,UAAQkB,EAAK,QAAQ;EAAG;EACnE,UAAU;GAAE,AAAI,CAAChB,KAAaF,MAAW,WAAUW,EAAa,IAAIzB,CAAM,GAAG+B,EAAK,EAAE,GAAG,UAAU,CAAC,GAAG0B,GAAa;EAAK;EACvH,SAAS;GAAE,AAAI,CAACzC,KAAaF,MAAW,WAAU,IAAgB,IAAM,IAAY,YAAYiB,EAAK,EAAE,GAAG,SAAS,CAAC,GAAGO,EAAO/B,CAAM;EAAK;EACzI,UAAU;GAAE,AAAIS,MAAmB,IAAY,IAAMgB,EAAK,QAAQ,GAAG,IAAS,CAAC,GAAG,IAAQ,CAAC,GAAG,IAAS,CAAC;EAAG;CAC7G;AACF;AC5GA,IAAa4C,IAAa,MAAM,KAAK,IAE/BC,KAAO,GAAO,MAAc,OAAO,SAASC,CAAK,IAAIA,IAAQC;AAGnE,SAAgBC,EAAY,GAAO;CACjC,IAAMvH,IAAIU,KAAS,CAAC,GACdX,IAAIC,EAAE,UAAUA;CACtB,IAAI,OAAO,SAASD,EAAE,IAAI,KAAK,OAAO,SAASA,EAAE,IAAI,KAAK,OAAO,SAASA,EAAE,IAAI,KAAK,OAAO,SAASA,EAAE,IAAI,GACzG,OAAOyH,EAAS;EAAE,MAAMzH,EAAE;EAAM,MAAMA,EAAE;EAAM,MAAMA,EAAE;EAAM,MAAMA,EAAE;CAAK,CAAC;CAE5E,IAAM0H,IAAIL,EAAIpH,EAAE,OAAOoH,EAAIpH,EAAE,MAAA,GAAwB,CAAC,GAChD0H,IAAIN,EAAIpH,EAAE,OAAOoH,EAAIpH,EAAE,QAAQoH,EAAIpH,EAAE,MAAMyH,CAAC,CAAC,CAAC;CAEpD,OAAOD,EADUxH,EAAE,aAAa,MAAQA,EAAE,WAAW,WAEjD;EAAE,MAAM,CAACyH,IAAI;EAAG,MAAM,CAACC,IAAI;EAAG,MAAMD,IAAI;EAAG,MAAMC,IAAI;CAAE,IACvD;EAAE,MAAM;EAAG,MAAM;EAAG,MAAMD;EAAG,MAAMC;CAAE,CAAC;AAC5C;AAEA,SAASF,EAAS,GAAK;CACrB,OAAO;EAAE,GAAGG;EAAK,OAAOA,EAAI,OAAOA,EAAI;EAAM,OAAOA,EAAI,OAAOA,EAAI;EAAM,KAAKA,EAAI,OAAOA,EAAI,QAAQ;EAAG,KAAKA,EAAI,OAAOA,EAAI,QAAQ;CAAE;AACxI;AAGA,SAAgBC,EAAe,GAAO;CAEpC,QADalH,GAAO,aAAa,CAAC,EAAA,CAE/B,QAAQ,MAAM,OAAO,SAASE,GAAG,CAAC,KAAK,OAAO,SAASA,GAAG,CAAC,CAAC,CAAC,CAC7D,KAAK,OAAO;EAAE,GAAGA,EAAE;EAAG,GAAGA,EAAE;EAAG,GAAGwG,EAAIxG,EAAE,GAAGwG,EAAIxG,EAAE,QAAQ,GAAG,CAAC;EAAG,MAAMA,EAAE,SAAS,SAAS,SAAS;CAAO,EAAE;AAChH;AAEA,IAAaiH,KAAa,MAAWC,IAAQA,EAAM,KAAKA,EAAM,QAAQ,OAAO;AAG7E,SAAgBC,EAAU,GAAO,GAAO;CACtC,IAAMC,IAAO/F,KAAS,CAAC,GACjB+C,IAAQ8C,GAAO,QAAQA,GAAO,MAAMA,GAAO,SAASA,GAAO;CACjE,IAAI9C,KAAS,MAAM;EACjB,IAAMiD,IAAQD,EAAK,MAAM,MAAM,OAAOrG,EAAE,EAAE,MAAM,OAAOqD,CAAK,CAAC;EAC7D,IAAIiD,GAAO,OAAOA;CACpB;CACA,IAAI,CAAC,OAAO,SAASH,GAAO,CAAC,KAAK,CAAC,OAAO,SAASA,GAAO,CAAC,GAAG,OAAO;CACrE,IAAII,IAAO,MACPC,IAAQ;CACZ,KAAK,IAAM,KAAKH,GAAM;EACpB,IAAMN,KAAK,EAAE,IAAII,EAAM,MAAM,KAAK,EAAE,IAAIA,EAAM,MAAM;EACpD,AAAIJ,IAAIS,MAAS,IAAQT,GAAG,IAAO;CACrC;CACA,OAAOQ;AACT;AAEA,IAAaE,KAAY,GAAO,MAAQ7H,KAAM,OAAO,QAAQ0B,KAAS,CAAC,EAAA,CAAG,MAAM,MAAM,OAAON,EAAE,EAAE,MAAM,OAAOpB,CAAE,CAAC,KAAK,MACzG8H,KAAY,OAAWpG,KAAS,CAAC,EAAA,CAAG,MAAM,MAAMN,EAAE,IAAI,KAAK,MAG3D2G,KAAe,GAAI,IAAQ,OAAU,CAACC,KAAS1C,KAAM,KAAK,IAAI,OAAM,KAEpE2C,KAAa,MAAM;CAC9B,IAAIC,IAAIzI,KAAK,KAAK,KAAK;CAGvB,OAFIyI,IAAI,KAAK,OAAI,KAAK,KAAK,KAAK,IAC5BA,IAAI,CAAC,KAAK,OAAI,KAAK,KAAK,KAAK,IAC1BA;AACT;AAMA,SAAgBC,GAAkB,EAAE,eAAY,IAAK,eAAY,KAAM,YAAS,QAAQ,CAAC,GAAG;CAC1F,IAAIC,IAAO,MACPC,IAAS,IACTC,IAAU,IACVC,IAAW,GACXC,IAAW;CACf,OAAO;EACL,OAAO,GAAM,GAAM;GACjB,IAAM7B,IAAM,CAAC;GACb,IAAI,CAACpG,KAAQA,EAAK,UAAU,IAK1B,OAJI8H,KAAQ1B,EAAI,KAAK,EAAE,MAAM,WAAW,CAAC,GACrC2B,KAAS3B,EAAI,KAAK,EAAE,MAAM,aAAa,CAAC,GAC5C,IAAS,IAAU,IACnB,IAAO,MACAA;GAET,IAAMhG,IAAK,KAAK,IAAI,GAAG2F,CAAI,IAAI;GAC/B,IAAI8B,GAAM;IACR,IAAMpD,IAAQ,KAAK,MAAMzE,EAAK,IAAI6H,EAAK,GAAG7H,EAAK,IAAI6H,EAAK,CAAC,IAAIzH,GACvD8H,IAAO,KAAK,IAAIR,GAAW1H,EAAK,OAAO,KAAK6H,EAAK,GAAG,CAAC,IAAIzH,GACzD+H,IAAS,KAAK,IAAIT,GAAW1H,EAAK,aAAa,MAAMA,EAAK,OAAO,KAAK6H,EAAK,GAAG,CAAC,IAAIzH,GACnFgI,IAAW3D,IAAQ4D,KAAaH,IAAOI;IAE7C,AADA,IAAWF,IAAW,IAAIJ,IAAWjC,GACjCqC,KAAY,CAACN,KAAU,IAAS,IAAM1B,EAAI,KAAK,EAAE,MAAM,aAAa,CAAC,KAChE,CAACgC,KAAYN,KAAUE,KAAYO,MAAU,IAAS,IAAOnC,EAAI,KAAK,EAAE,MAAM,WAAW,CAAC;IACnG,IAAMoC,IAAYL,IAASG;IAE3B,AADA,IAAWE,IAAY,IAAIP,IAAWlC,GAClCyC,KAAa,CAACT,KAAW,IAAU,IAAM3B,EAAI,KAAK,EAAE,MAAM,eAAe,CAAC,KACrE,CAACoC,KAAaT,KAAWE,KAAYM,MAAU,IAAU,IAAOnC,EAAI,KAAK,EAAE,MAAM,aAAa,CAAC;GAC1G;GAEA,OADA,IAAO;IAAE,GAAGpG,EAAK;IAAG,GAAGA,EAAK;IAAG,KAAKA,EAAK,OAAO;IAAG,KAAK0H,GAAW1H,EAAK,aAAa,MAAMA,EAAK,OAAO,EAAE;GAAE,GACpGoG;EACT;EACA,QAAQ;GAGN,AAFA,IAAO,MACP,IAAS,IAAU,IACnB,IAAW,IAAW;EACxB;EACA,IAAI,SAAS;GAAE,OAAO0B;EAAQ;EAC9B,IAAI,UAAU;GAAE,OAAOC;EAAS;CAClC;AACF;AAGA,SAAgBU,EAAe,GAAO;CACpC,QAAQ1B,EAAUC,CAAK,GAAvB;EACE,KAAK,QAAQ,OAAO,CAAC,EAAE,MAAM,OAAO,GAAG,EAAE,MAAM,mBAAmB,CAAC;EACnE,KAAK,UAAU,OAAO,CAAC;GAAE,MAAM;GAAU,MAAMA,EAAM,SAAS,aAAa,aAAa;EAAU,CAAC;EACnG,KAAK,OAAO,OAAO,CAAC,EAAE,MAAM,WAAW,CAAC;EACxC,KAAK,aAAa,OAAO,CAAC,EAAE,MAAM,YAAY,CAAC;EAC/C,SAAS,OAAO,CAAC;CACnB;AACF;AAGA,SAAgB0B,EAAW,GAAQ;CACjC,IAAI,CAACC,KAAUA,EAAO,WAAW,QAAQ,OAAO;CAChD,IAAMxF,IAAKoE,EAASoB,EAAO,KAAK;CAEhC,OADI,CAACxF,KAAMwF,EAAO,UAAU,OAAa,OAClC,OAAOA,EAAO,MAAM,MAAM,OAAOxF,EAAG,EAAE,IAAI,YAAY;AAC/D;;ACjIA,SAAgByF,EAAkB,GAAW,EAAE,aAAU,CAAC,GAAG;CAC3D,IAAMC,IAAS,SAAS,cAAc,QAAQ;CAE9C,AADA,EAAO,MAAM,UAAU,wCACvBC,EAAU,YAAYD,CAAM;CAC5B,IAAME,IAAMF,EAAO,WAAW,IAAI;CAClC,IAAI,CAACE,GAAwB,MAAjBF,EAAO,OAAO,GAAa,MAAM,uBAAuB;CACpE,IAAMG,IAASvC,EAAY7G,CAAK,GAC5B+G,IAAI,GAAOsC,IAAI,GAAOC,IAAQ,GAAOC,IAAK,GAAOC,IAAK;CAC1D,SAASC,IAAS;EACwB,AAAxC,IAAI,KAAK,IAAI,GAAGP,EAAU,WAAW,GAAG,IAAI,KAAK,IAAI,GAAGA,EAAU,YAAY;EAC9E,IAAMQ,IAAM,KAAK,IAAI,OAAO,oBAAoB,GAAG,CAAC;EAIf,AAHrC,EAAO,QAAQ3C,IAAI2C,GAAK,EAAO,SAASL,IAAIK,GAC5CP,EAAI,aAAaO,GAAK,GAAG,GAAGA,GAAK,GAAG,CAAC,GACrC,IAAQ,KAAK,IAAI3C,IAAIqC,EAAO,OAAOC,IAAID,EAAO,KAAK,GACnD,KAAMrC,IAAIqC,EAAO,QAAQE,KAAS,GAAG,KAAMD,IAAID,EAAO,QAAQE,KAAS;CACzE;CACA,EAAO;CACP,IAAMK,IAAK,OAAO,kBAAmB,aAAa,IAAI,eAAeF,CAAM,IAAI;CAE/E,OADAE,GAAI,QAAQT,CAAS,GACd;EACL,MAAM;EAAM;EACZ,eAAe,GAAI,GAAI;GAAE,OAAO;IAAE,KAAKU,IAAK,KAAK7C,IAAI,IAAIwC,KAAMD,IAAQF,EAAO;IAAM,KAAK,IAAIS,KAAMR,IAAI,IAAIG,KAAMF,IAAQF,EAAO;GAAK;EAAG;EACxI,OAAO,GAAO;GAGe,AAF3B,EAAI,YAAY,WAAWD,EAAI,SAAS,GAAG,GAAGpC,GAAGsC,CAAC,GAClDF,EAAI,KAAK,GAAGA,EAAI,UAAUI,GAAIC,CAAE,GAAGL,EAAI,MAAMG,GAAOA,CAAK,GAAGH,EAAI,UAAU,CAACC,EAAO,MAAM,CAACA,EAAO,IAAI,GACpG,EAAI,YAAY,WAAWD,EAAI,SAASC,EAAO,MAAMA,EAAO,MAAMA,EAAO,OAAOA,EAAO,KAAK;GAC5F,KAAK,IAAMU,KAAY5C,EAAelH,CAAK,GAAqJ,AAAhJ,EAAI,YAAY8J,EAAS,SAAS,SAAS,YAAY,WAAWX,EAAI,UAAU,GAAGA,EAAI,IAAIW,EAAS,GAAGA,EAAS,GAAGA,EAAS,GAAG,GAAG,KAAK,KAAK,CAAC,GAAGX,EAAI,KAAK;GACzM,KAAK,IAAM/I,KAAQ4F,EAAM,SAAS,CAAC,GAKjC,AAJAmD,EAAI,KAAK,GAAGA,EAAI,UAAU/I,EAAK,GAAGA,EAAK,CAAC,GAAG+I,EAAI,OAAO/I,EAAK,GAAG,GAC9D,EAAI,YAAYA,EAAK,UAAU,KAAQ,SAASA,EAAK,SAAS,WAC9D+I,EAAI,SAAS,IAAI,MAAM,GAAG,GAAG,GAAGA,EAAI,QAAQ,GAC5CA,EAAI,KAAK,GAAGA,EAAI,UAAU/I,EAAK,GAAGA,EAAK,CAAC,GAAG+I,EAAI,OAAO/I,EAAK,SAAS,GAAG,EAAI,cAAc,WAAW,EAAI,YAAY,IAAK+I,EAAI,UAAU,GAAGA,EAAI,OAAO,GAAG,CAAC,GAAGA,EAAI,OAAO,GAAG,CAAC,GAAGA,EAAI,OAAO,GAAGA,EAAI,QAAQ,GACpM/I,EAAK,SAAQ,EAAI,cAAc,QAAQ,EAAI,YAAY,IAAK+I,EAAI,UAAU,GAAGA,EAAI,IAAI/I,EAAK,GAAGA,EAAK,GAAG,GAAG,GAAG,KAAK,KAAK,CAAC,GAAG+I,EAAI,OAAO;GAE1I,EAAI,YAAY;GAChB,KAAK,IAAM9H,KAAS2E,EAAM,UAAU,CAAC,GAAsE,AAAjEmD,EAAI,UAAU,GAAGA,EAAI,IAAI9H,EAAM,GAAGA,EAAM,GAAG,IAAK,GAAG,KAAK,KAAK,CAAC,GAAG8H,EAAI,KAAK;GACpH,EAAI,QAAQ;EACd;EACA,UAAU;GAAoB,AAAlBQ,GAAI,WAAW,GAAGV,EAAO,OAAO;EAAG;CACjD;AACF;;A,iDC9BMgB,KAAO,GAAK,MAAS;CAAE,EAAkB,SAAS,CAAC,CAAC,IAAIjG,GAAKkG,CAAI,CAAC,CAAC,YAAY,CAAC,CAAC;AAAG,GACpFC,KAAa,MAAU;CAAuC,AAArC,EAAM,WAAW,GAAG,EAAM,QAAQ,GAAG,EAAM,OAAO;AAAO;AACxF,SAASC,EAAkB,EAAE,YAAS,kBAAe,eAAY,cAAW,eAAY,MAAS;CAC/F,IAAMC,IAAaC,EAAWtM,CAAW,CAAC,EAAE,QAAQ,QAC9C8D,IAAOnE,GAAc,MAAUqI,EAAM,MAAMuE,EAAQ,GACnDC,IAAeC,EAAOC,CAAS;CACrC,EAAa,UAAUA;CACvB,IAAMC,IAAQF,EAAO,IAAI,GAASG,IAAQH,EAAO,IAAI,GAASI,IAAWJ,EAAO,IAAI,GAC9EnK,IAAQmK,EAAO;EAAE,UAAU;EAAG,OAAO;EAAG,MAAM;CAAM,CAAC,GACrD,CAACK,GAAMC,KAAWC,EAAS,IAAI,GAAS,CAACC,IAAOC,MAAYF,EAAS,EAAE,GAAS,CAACG,GAAUC,KAAeJ,EAAS,EAAK,GACxH,CAACK,GAAMC,KAAWN,EAAS,SAAS;CAC1C,QAAgB;EACd,AAAIN,KAAaP,EAAU7J,EAAM,OAAO,GAAGrC,EAAkB,KACxD4M,EAAS,SAAS,OAAO;CAChC,GAAG,CAACH,CAAS,CAAC;CACd,IAAMa,IAAS,CAAC,UAAU,KAAK,CAAC,CAAC,SAASzJ,GAAM,MAAM,GAChD,CAAC9B,GAAOwL,KAAYR,EAAS,IAAI;CA0DvC,IAzDAS,QAAgB;EACd,IAAI,CAACF,KAAU,CAACvL,KAAS,CAAC2K,EAAM,SAAS;EACzC,IAAIe,IAAW,IAAWC,IAAQ,MAC5BC,IAAU;GAAE;GAAO,UAAU,WAAW,mBAAmB,CAAC,CAAC;GAAS,eAAe,WAAW,kCAAkC,CAAC,CAAC;GAAS,UAAU,MAAU;IAAE,AAAIxE,EAAM,SAAS,kBAAgBgE,EAAY,EAAI;GAAG;EAAE,GAC3NxE,UAAiB;GAAE,AAAK8E,MAAY,IAAQ1C,EAAkB2B,EAAM,SAASiB,CAAO,GAAG,EAAS,UAAUD,GAAOL,EAAQ,IAAI;EAAK;EAGxI,OAFIH,IAAUvE,EAAS,IAClB,OAAO,gCAA6B,CAAC,MAAM,EAAE,yBAAsB;GAAE,IAAI,CAAC8E,GAAY,IAAI;IAA6E,AAA3E,IAAQG,EAAgBlB,EAAM,SAASiB,CAAO,GAAG,EAAS,UAAUD,GAAOL,EAAQ,IAAI;GAAG,QAAQ;IAAE,EAAS;GAAG;EAAI,CAAC,CAAC,CAAC,MAAM1E,CAAQ,SACzN;GAAqC,AAAnC,IAAW,IAAM+E,GAAO,QAAQ,GAAOd,EAAS,YAAYc,MAAO,EAAS,UAAU;EAAM;CAC7G,GAAG;EAACJ;EAAQvL;EAAOmL;CAAQ,CAAC,GAC5BM,QAAgB;EACd,IAAI,CAACF,KAAUzJ,EAAK,WAAW,YAAY,CAAC6I,EAAM,SAAS;EAC3D,IAAIe,IAAW,IAAW7F,IAAQ,GAAOoC,IAAO,YAAY,IAAI,GAAO6D,IAAY,GAAOC,IAAU,MAC9FC,IAAUhE,GAAkB,GAASiE,oBAAO,IAAI,IAAI;EAC1D,EAAiB;EACjB,IAAIC;EACJ,IAAI;GACF,IAAMzG,IAAY9H,EAAa,SAAS,CAAC,CAAC,oBAAoB4M,CAAO;GAErE,AADA,IAAU3I,EAAgB;IAAE,YAAYyI,GAAY;IAAY,oBAAoBA,GAAY;IAAoB;IAAM,QAAQ,OAAO8B,CAAa;IAAG,QAAQ,OAAOrK,EAAK,MAAM,MAAM,OAAOqK,CAAa;IAAG;GAAU,CAAC,GAC3N,EAAM,UAAUD;EAClB,SAAS,GAAG;GAAE,GAAS,EAAE,WAAW,2BAA2B;GAAG;EAAkB;EACpF,EAASA,EAAQ,UAAU,CAAC,CAAC,KAAK;EAClC,SAASE,IAAQ;GAA0C,AAAxCH,EAAK,MAAM,GAAG9B,EAAU7J,EAAM,OAAO,GAAGrC,EAAkB;EAAG;EAChF,SAAS+F,EAAI,GAAO,GAAM;GACxB,AAAI,4BAA4B,KAAKoD,EAAM,QAAQ,OAAO,KACrD;IAAC;IAAQ;IAAQ;IAAQ;IAAQ;IAAW;IAAa;IAAa;IAAc;GAAO,CAAC,CAAC,SAASA,EAAM,IAAI,MACrHA,EAAM,eAAe,GAAOiF,IAAMJ,EAAK,IAAI7E,EAAM,IAAI,IAAQ6E,EAAK,OAAO7E,EAAM,IAAI,GACnF,EAAM,QAAQ,WAAW,OAAO6E,EAAK,IAAI,MAAM,KAAKA,EAAK,IAAI,SAAS,CAAC,IAAI,OAAOA,EAAK,IAAI,MAAM,KAAKA,EAAK,IAAI,WAAW,CAAC,GAC3H,EAAM,QAAQ,QAAQ,OAAOA,EAAK,IAAI,MAAM,KAAKA,EAAK,IAAI,YAAY,CAAC,IAAI,OAAOA,EAAK,IAAI,MAAM,KAAKA,EAAK,IAAI,WAAW,CAAC,GAC3H,EAAM,QAAQ,OAAOA,EAAK,IAAI,OAAO;EACvC;EACA,IAAMI,KAAQ,MAAMrI,EAAI,GAAG,EAAI,GAASsI,KAAM,MAAMtI,EAAI,GAAG,EAAK,GAC1DuI,IAAO5B,EAAM;EACyD,AAA5E4B,EAAK,iBAAiB,WAAWF,CAAI,GAAGE,EAAK,iBAAiB,SAASD,CAAE,GAAGC,EAAK,iBAAiB,QAAQH,CAAK;EAC/G,IAAMI,UAAmB;GAAE,AAAI,SAAS,UAAQJ,EAAM;EAAG;EAEzD,AADA,SAAS,iBAAiB,oBAAoBI,CAAU,GACxDrO,EAAiB,EAAE,MAAM,eAAe,GAAGoM,CAAO;EAClD,SAASkC,EAAK,GAAK;GACjB,IAAIf,GAAU;GACd,IAAMlL,IAAK,KAAK,IAAI,IAAIkM,IAAMzE,CAAI;GAAG,IAAOyE;GAC5C,IAAMC,IAASnC,EAAa,WAAW,SAAS;GAEhD,AADA0B,EAAQ,SAASS,IAAS;IAAE,UAAU;IAAG,OAAO;IAAG,MAAM;GAAM,IAAIrM,EAAM,OAAO,GAChF4L,EAAQ,KAAK1L,CAAE;GAAG,IAAMwF,IAAQkG,EAAQ,UAAU;GAGlD,IAFKS,KAAQ9B,EAAS,SAAS,OAAO7E,GAAOxF,CAAE,GAC3CmM,MAAUV,EAAK,MAAM,GAAGD,EAAQ,MAAM,GAAG/N,EAAkB,IAC3D,CAAC0O,GAAQ,KAAK,IAAMvF,KAASpB,EAAM,UAAU,CAAC,GAAG,KAAK,IAAM4G,KAAS/D,EAAezB,CAAK,GAAG,EAAiBwF,GAAOxF,EAAM,EAAE;GAChI,IAAI,CAACuF,GAAQ,KAAK,IAAMvF,KAAS4E,EAAQ,OAAOrE,EAAS3B,EAAM,KAAK,GAAGxF,CAAE,GAAG,EAAiB4G,CAAK;GAClG,IAAMyF,IAAc/D,EAAW9C,CAAK;GAGpC,AAFI6G,KAAe,CAACd,MAAWhB,EAAQ/E,CAAK,GAAG,IAAU6G,GAAkBF,KAAQvO,EAAY2N,GAASxB,CAAO,GAAG5M,EAAa,SAAS,CAAC,CAAC,aAAa4M,GAASvE,EAAM,MAAM,IACxK0G,IAAMZ,IAAY,QAAO,IAAYY,GAAK3B,EAAQ/E,CAAK,IAC3D,IAAQ,sBAAsByG,CAAI;EACpC;EAEA,OADA,IAAQ,sBAAsBA,CAAI,SACrB;GAEgH,AAD3H,IAAW,IAAM,qBAAqB5G,CAAK,GAAGuG,EAAM,GAAGF,EAAQ,QAAQ,GAAG,EAAM,UAAU,MAC1FK,EAAK,oBAAoB,WAAWF,CAAI,GAAGE,EAAK,oBAAoB,SAASD,CAAE,GAAGC,EAAK,oBAAoB,QAAQH,CAAK,GAAG,SAAS,oBAAoB,oBAAoBI,CAAU;EACxL;CACF,GAAG;EAACjB;EAAQhB;EAAS4B;CAAa,CAAC,GAC/B,CAACrK,GAAM,OAAO;CAClB,IAAMgL,IAAQ,OAAOX,CAAa,MAAM,OAAOrK,EAAK,OAAO,GACrDiL,IAAOjC,GAAM,WAAW,UAAUhJ,EAAK,WAAW;CACxD,SAASkL,EAAI,GAAO;EAClB,IAAMC,IAAOtC,EAAM,SAAS,sBAAsB,GAASpH,IAAKoE,EAASmD,GAAM,KAAK;EACpF,IAAI,CAACmC,KAAQ,CAAC1J,GAAI;EAClB,IAAM2J,IAASrC,EAAS,SAAS,gBAAgBzD,EAAM,UAAU6F,EAAK,QAAQA,EAAK,QAAQ,IAAI,GAAG,KAAK7F,EAAM,UAAU6F,EAAK,OAAOA,EAAK,SAAS,CAAC;EAClJ,AAAIC,MAAQ,EAAM,QAAQ,YAAY,KAAK,MAAMA,EAAO,IAAI3J,EAAG,GAAG2J,EAAO,IAAI3J,EAAG,CAAC;CACnF;CACA,IAAM4J,KAAQ,GAAO,OAAW;EAAE,gBAAgB,MAAM;GAAsE,AAApErJ,EAAE,eAAe,GAAGA,EAAE,cAAc,kBAAkBA,EAAE,SAAS,GAAG,EAAM,QAAQsJ,KAASzG;EAAO;EAAG,mBAAmB;GAAE,EAAM,QAAQyG,KAASA,MAAU,UAAiB;EAAG;EAAG,uBAAuB;GAAE,EAAM,QAAQA,KAASA,MAAU,UAAiB;EAAG;EAAG,4BAA4B;GAAE,EAAM,QAAQA,KAASA,MAAU,UAAiB;EAAG;CAAE;CAClZ,OAAO,kBAAC,WAAD;EAAS,WAAW,yBAAyB7B,IAAS,qBAAqB;EAAM,cAAW;EAA5F,UAAA;GACL,kBAAC,UAAD;IAAQ,WAAU;IAAlB,UAAA,CAA8B,kBAAC,UAAD,EAAA,UAAQ,kBAAuB,CAAA,GAAC,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA;MAAmC,kBAAC3N,GAAD,EAAmB,SAASS,EAAqB,EAAI,CAAA;MAAEgP,KAAc,kBAAC,UAAD;OAAQ,SAASA;OAAY,cAAW;OAAY,UAAA;MAAS,CAAA;MAAGC,KAAa,kBAAC,UAAD;OAAQ,SAASA;OAAW,cAAW;OAAU,UAAA;MAAS,CAAA;KAAO;IAAS,CAAA,CAAA;;GAC5TxL,EAAK,WAAW,aAAa,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA;KAA2B,kBAAC,QAAD;MAAM,WAAU;MAAiB,eAAY;MAAO,UAAA;KAAQ,CAAA;KAAC,kBAAC,UAAD,EAAA,UAASgL,IAAQ,0BAA0B,qBAA6B,CAAA;KAAC,kBAAC,KAAD,EAAA,UAAIA,IAAQ,8CAA8C,iCAAoC,CAAA;KAAEA,KAAS,kBAAC,OAAD;MAAK,WAAU;MAAf,UAAA,CAAmC,kBAAC,UAAD;OAAQ,WAAU;OAAoB,eAAe7C,EAAIM,GAAS,aAAa;OAAG,UAAA;MAAuB,CAAA,GAAC,kBAAC,UAAD;OAAQ,eAAeN,EAAIM,GAAS,cAAc;OAAG,UAAA;MAAgB,CAAA,CAAM;;IAAO;;IACrgBgB,KAAUT,MAAS,kBAAApN,GAAA,EAAA,UAAA;IAAE,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,EAA0BoN,GAAM,SAAS,CAAC,EAAA,CAAG,KAAK,MAAS,kBAAC,QAAD,EAAA,UAAA;MAAqB1K,EAAK,OAAO,OAAO;MAAQ;MAAC,kBAAC,SAAD;OAAO,KAAI;OAAI,KAAI;OAAM,OAAOA,EAAK;OAAI,cAAYA,EAAK,OAAO,YAAY;MAAmB,CAAA;MAAC;MAAEA,EAAK;MAAG;KAAS,EAAA,GAA1JA,EAAK,EAAqJ,CAAC,GAAE,kBAAC,QAAD;MAAM,MAAK;MAAX,UAAA;OAAqB0K,GAAM,KAAK,SAAS;OAAqB;OAAEA,GAAM,KAAK,OAAO,UAAU,OAAOA,GAAM,KAAK,SAAU,WAAWA,EAAK,IAAI,QAAQ;OAAI;OAAE,OAAO,SAASA,GAAM,KAAK,GAAG,IAAI,GAAG,KAAK,MAAMA,EAAK,IAAI,GAAG,EAAE,OAAO;MAAS;KAAM,CAAA,CAAA;;IACte,kBAAC,OAAD;KAAK,WAAU;KAAW,KAAKH;KAAO,UAAU;KAAG,cAAW;KAAwF,eAAeqC;KAAK,gBAAgB,MAAM;MAAU,AAARA,EAAI,CAAC,GAAO,EAAE,gBAAgB,YAAW,EAAE,cAAc,MAAM,GAAG,EAAE,cAAc,kBAAkB,EAAE,SAAS,GAAGA,EAAI,CAAC,GAAG,EAAM,QAAQ,OAAO;KAAQ;KAAG,mBAAmB;MAAE,EAAM,QAAQ,OAAO;KAAO;KAAG,uBAAuB;MAAE,EAAU1M,EAAM,OAAO;KAAG;KAAG,4BAA4B;MAAE,EAAM,QAAQ,OAAO;KAAO;IAAI,CAAA;IACpgB,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA;MAA6B,kBAAC,OAAD;OAAK,WAAU;OAAc,MAAK;OAAQ,cAAW;OAAyB,gBAAgB,MAAM;QAAsB,AAApB,EAAE,eAAe,GAAG,EAAE,cAAc,kBAAkB,EAAE,SAAS;QAAG,IAAMZ,IAAI,EAAE,cAAc,sBAAsB;QAAwG,AAArG,EAAM,QAAQ,QAAQ,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,EAAE,UAAUA,EAAE,OAAOA,EAAE,QAAQ,MAAMA,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAM,QAAQ,WAAW,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,EAAE,EAAE,UAAUA,EAAE,MAAMA,EAAE,SAAS,MAAMA,EAAE,SAAS,EAAE,CAAC;OAAG;OAAG,gBAAgB,MAAM;QAAE,IAAI,CAAC,EAAE,cAAc,kBAAkB,EAAE,SAAS,GAAG;QAAQ,IAAMA,IAAI,EAAE,cAAc,sBAAsB;QAAwG,AAArG,EAAM,QAAQ,QAAQ,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,EAAE,UAAUA,EAAE,OAAOA,EAAE,QAAQ,MAAMA,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAM,QAAQ,WAAW,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,EAAE,EAAE,UAAUA,EAAE,MAAMA,EAAE,SAAS,MAAMA,EAAE,SAAS,EAAE,CAAC;OAAG;OAAG,mBAAmByK,EAAU7J,EAAM,OAAO;OAAG,uBAAuB6J,EAAU7J,EAAM,OAAO;OAAG,4BAA4B6J,EAAU7J,EAAM,OAAO;OAAG,UAAA;MAAM,CAAA;MAAC,kBAAC,OAAD;OAAK,WAAU;OAAW,cAAW;OAArC,UAAA;QAA+D,kBAAC,UAAD;SAAQ,cAAW;SAAU,GAAI6M,EAAK,YAAY,CAAC;SAAG,UAAA;QAAS,CAAA;QAAC,kBAAC,UAAD;SAAQ,cAAW;SAAkB,GAAIA,EAAK,SAAS,EAAE;SAAG,UAAA;QAAS,CAAA;QAAC,kBAAC,UAAD;SAAQ,cAAW;SAAa,GAAIA,EAAK,YAAY,EAAE;SAAG,UAAA;QAAS,CAAA;QAAC,kBAAC,UAAD;SAAQ,cAAW;SAAgB,GAAIA,EAAK,SAAS,CAAC;SAAG,UAAA;QAAS,CAAA;OAAM;;MAAC,kBAAC,UAAD;OAAQ,WAAU;OAAU,GAAIA,EAAK,QAAQ,EAAI;OAAG,UAAA;MAAgB,CAAA;KAAM;;IAC71C,kBAAC,OAAD;KAAK,WAAU;KAAY,UAAA,kBAAC,SAAD,EAAA,UAAA;MAAO;MAAQ,kBAAC,YAAD;OAAU,KAAI;OAAI,OAAOxF,EAASmD,GAAM,KAAK,CAAC,EAAE,UAAU;MAAI,CAAA;MAAC;OAAGnD,EAASmD,GAAM,KAAK,CAAC,EAAE,UAAU,MAAM,IAAI,UAAU;KAAqB,EAAA,CAAA;IAAM,CAAA;IAC5L,kBAAC,SAAD,EAAA,UAAO,qFAAyF,CAAA;IAAC,kBAAC,UAAD;KAAQ,eAAeM,GAAa,MAAM,CAACrD,CAAC;KAAI,UAAAsD,MAAS,OAAO,cAAc;IAAmB,CAAA;GAClM,EAAA,CAAA;GACD0B,KAAQ,kBAAC,KAAD;IAAG,MAAK;IAAR,UAAA;KAAkB,OAAOjC,GAAM,UAAUhJ,EAAK,QAAQ,MAAM,OAAOqK,CAAa,IAAI,eAAe;KAAkB;KAAC,kBAAC,UAAD;MAAQ,eAAe;OAAE,QAAa,QAAQxO,EAAa,SAAS,CAAC,CAAC,cAAc4M,CAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;MAAG;MAAG,UAAA;KAAgB,CAAA;IAAI;;GACpQgB,KAAU,CAACwB,KAAQjC,GAAM,KAAK,UAAU,eAAe,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACtD,kBAAC,KAAD;KAAG,MAAK;KAAU,UAAAhM,EAAegM,GAAM,GAAG;IAAK,CAAA,GAC/C,kBAAC,UAAD;KAAQ,MAAK;KAAS,eAAeF,EAAM,SAAS,UAAU;KAAG,UAAA;IAA2B,CAAA,CACzF;;GACJW,KAAU,kBAAC,WAAD;IAAS,WAAU;IAAnB,UAAA,CAAoC,kBAAC,WAAD,EAAA,UAAS,0BAAgC,CAAA,GAAC,kBAAC,OAAD,EAAA,UAAM,KAAK,UAAU3M,EAAsBkM,GAAM,GAAG,GAAG,MAAM,CAAC,EAAO,CAAA,CAAU;;GACvKS,KAAU,CAACwB,KAAQ,kBAAC,UAAD;IAAQ,eAAenC,EAAM,SAAS,OAAO;IAAG,UAAA;GAAgB,CAAA;GACnF9I,EAAK,WAAW,kBAAC,KAAD;IAAG,MAAK;IAAS,UAAA;GAAY,CAAA;GAAGA,EAAK,gBAAgBA,EAAK,SAAS,kBAAC,UAAD;IAAQ,eAAe;KAAE,EAAkB,SAAS,CAAC,CAAC,MAAMyI,CAAO,CAAC,CAAC,YAAY,CAAC,CAAC;IAAG;IAAG,UAAA;GAAwB,CAAA;GACpMU,MAAS,kBAAC,KAAD;IAAG,MAAK;IAAS,UAAAA;GAAS,CAAA;GAAGnJ,EAAK,SAAS,kBAAC,KAAD;IAAG,MAAK;IAAS,UAAAA,EAAK;GAAS,CAAA;GACnF,CAAC,CAAC,UAAU,UAAU,CAAC,CAAC,SAASA,EAAK,MAAM,KAAK,kBAAC,UAAD;IAAQ,WAAU;IAAY,UAAA,kBAAC,UAAD;KAAQ,eAAemI,EAAIM,GAAS,UAAU;KAAG,UAAA;IAAsB,CAAA;GAAS,CAAA;EACzJ;;AACX;AACA,IAAAP,IAAewD,EAAKpD,CAAiB"}
@@ -1,4 +1,4 @@
1
- import { a as e, c as t, i as n, l as r, n as i, o as a, r as o, s } from "./TanksLiveGameCard-BxQGR8P9.js";
1
+ import { a as e, c as t, i as n, l as r, n as i, o as a, r as o, s } from "./TanksLiveGameCard-BNJqWt1z.js";
2
2
  import { _ as c, a as l, c as u, d, f, h as p, i as m, l as ee, m as te, n as h, o as ne, p as re, r as ie, s as ae, t as oe, u as se } from "./fx-BHsl4S_J.js";
3
3
  import { ACESFilmicToneMapping as ce, DirectionalLight as le, DynamicDrawUsage as ue, Fog as de, Group as fe, HemisphereLight as pe, InstancedMesh as me, Matrix4 as he, MeshBasicMaterial as ge, MeshLambertMaterial as _e, MeshStandardMaterial as ve, PCFSoftShadowMap as ye, PerspectiveCamera as be, Plane as xe, PlaneGeometry as Se, Raycaster as Ce, Scene as we, Vector2 as Te, Vector3 as g, WebGLRenderer as Ee, sRGBEncoding as De } from "three";
4
4
  // src/games/tanks-live/scene/createLiveScene.js
@@ -361,4 +361,4 @@ function y(y, { arena: Fe, lowPower: b = !1, reducedMotion: x = !1, onEvent: Ie
361
361
  }
362
362
  export { y as createLiveScene, y as default };
363
363
 
364
- //# sourceMappingURL=createLiveScene-GkalLsqm.js.map
364
+ //# sourceMappingURL=createLiveScene-CJQtq54t.js.map