@minicode-dev/chat 0.1.14 → 0.1.15
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/dist/chunks/{BattleshipGameCard-B-B4r7lK.js → BattleshipGameCard-8H-sBCsv.js} +3 -3
- package/dist/chunks/{BattleshipGameCard-B-B4r7lK.js.map → BattleshipGameCard-8H-sBCsv.js.map} +1 -1
- package/dist/chunks/{ChatContext-DQtKsR6Z.js → ChatContext-CVW58bzC.js} +2 -2
- package/dist/chunks/{ChatContext-DQtKsR6Z.js.map → ChatContext-CVW58bzC.js.map} +1 -1
- package/dist/chunks/{RacingLiveGameCard-c1G7uoDI.js → RacingLiveGameCard-8j9QLnxW.js} +4 -4
- package/dist/chunks/{RacingLiveGameCard-c1G7uoDI.js.map → RacingLiveGameCard-8j9QLnxW.js.map} +1 -1
- package/dist/chunks/{TanksGameCard-CvTaF7tu.js → TanksGameCard-DnCufSH6.js} +12 -12
- package/dist/chunks/{TanksGameCard-CvTaF7tu.js.map → TanksGameCard-DnCufSH6.js.map} +1 -1
- package/dist/chunks/TanksLiveGameCard-D_27Jomp.js +1274 -0
- package/dist/chunks/TanksLiveGameCard-D_27Jomp.js.map +1 -0
- package/dist/chunks/{avalancheScene3d-Z5QyZIid.js → avalancheScene3d-CIE2WKQn.js} +51 -50
- package/dist/chunks/{avalancheScene3d-Z5QyZIid.js.map → avalancheScene3d-CIE2WKQn.js.map} +1 -1
- package/dist/chunks/cars-D1PM7mVD.js +340 -0
- package/dist/chunks/cars-D1PM7mVD.js.map +1 -0
- package/dist/chunks/{connect4Sounds-DmD-E9kX.js → connect4Sounds-BqEHULjv.js} +2 -2
- package/dist/chunks/{connect4Sounds-DmD-E9kX.js.map → connect4Sounds-BqEHULjv.js.map} +1 -1
- package/dist/chunks/createLiveScene-MTGRv8rx.js +758 -0
- package/dist/chunks/createLiveScene-MTGRv8rx.js.map +1 -0
- package/dist/chunks/{createRaceScene-C7Rw89kj.js → createRaceScene-BiEtQsVs.js} +4 -3
- package/dist/chunks/{createRaceScene-C7Rw89kj.js.map → createRaceScene-BiEtQsVs.js.map} +1 -1
- package/dist/chunks/fx-DhXerGyt.js +248 -0
- package/dist/chunks/fx-DhXerGyt.js.map +1 -0
- package/dist/chunks/{games-BvYTWgaR.js → games-Bl_8raG6.js} +1147 -574
- package/dist/chunks/games-Bl_8raG6.js.map +1 -0
- package/dist/chunks/{tanksSounds-DwjfSp3W.js → tanksSounds-DTnidbiq.js} +5 -5
- package/dist/chunks/{tanksSounds-DwjfSp3W.js.map → tanksSounds-DTnidbiq.js.map} +1 -1
- package/dist/index.js +28 -28
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/dist/chunks/TanksLiveGameCard-COr9Oay5.js +0 -1011
- package/dist/chunks/TanksLiveGameCard-COr9Oay5.js.map +0 -1
- package/dist/chunks/createLiveScene-CWBunxPi.js +0 -367
- package/dist/chunks/createLiveScene-CWBunxPi.js.map +0 -1
- package/dist/chunks/fx-UZwhOmdl.js +0 -584
- package/dist/chunks/fx-UZwhOmdl.js.map +0 -1
- package/dist/chunks/games-BvYTWgaR.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { t as e } from "./games-
|
|
2
|
-
import { i as t, o as n } from "./ChatContext-
|
|
3
|
-
import { a as r, t as i } from "./connect4Sounds-
|
|
1
|
+
import { t as e } from "./games-Bl_8raG6.js";
|
|
2
|
+
import { i as t, o as n } from "./ChatContext-CVW58bzC.js";
|
|
3
|
+
import { a as r, t as i } from "./connect4Sounds-BqEHULjv.js";
|
|
4
4
|
// src/games/tanks/sound/cues.js
|
|
5
5
|
var a = [
|
|
6
6
|
"engine_loop",
|
|
@@ -204,6 +204,6 @@ function V(e, t) {
|
|
|
204
204
|
function H(e, t) {
|
|
205
205
|
B(d(e), t);
|
|
206
206
|
}
|
|
207
|
-
export {
|
|
207
|
+
export { L as a, R as c, I as i, F as l, V as n, M as o, H as r, z as s, E as t };
|
|
208
208
|
|
|
209
|
-
//# sourceMappingURL=tanksSounds-
|
|
209
|
+
//# sourceMappingURL=tanksSounds-DTnidbiq.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tanksSounds-DwjfSp3W.js","names":["chatSoundUrl","isSoundEnabled","subscribeSoundPreference","createSoundManager","connect4Sounds","TANKS_LOOPS","play","loopStart","loopStop","IMPACT_SOUNDS","sceneEventToCues","event","name","outcomeToCues","result","TANKS_SOUND_NAMES","LEVELS","DELIVERED_TANKS_SOUNDS","RETRIGGER_MS","LOOP_RAMPS","MP3_LOOP_TRIM","YIELDS_TO","supportsOgg","files","fileFor","extension","configured","format","configureTanksSounds","overrides","available","file","manager","getTanksSoundManager","hidden","canPlay","wantedLoops","syncLoops","allowed","started","startTanksSounds","lastPlayed","suppressedUntil","suppressTanksCue","ms","playTanksCue","key","now","played","startTanksLoop","stopTanksLoop","stopAllTanksLoops","names","runCues","cues","action","handleSceneEvent","suffix","playOutcome"],"sources":["../../src/games/tanks/sound/cues.js","../../src/games/tanks/sound/tanksSounds.js"],"sourcesContent":["// Pure sound choreography for Tanks (no audio, no DOM): maps scene events to\n// one-shot plays and loop start/stop actions.\n\nexport const TANKS_LOOPS = ['engine_loop', 'tracks_loop', 'turret_loop'];\n\nconst play = (name) => ({ name, action: 'play' });\nconst loopStart = (name) => ({ name, action: 'loop_start' });\nconst loopStop = (name) => ({ name, action: 'loop_stop' });\n\nconst IMPACT_SOUNDS = { terrain: 'terrain_impact', obstacle: 'terrain_impact', ground: 'terrain_impact' };\n\n/** Scene onEvent ({ type, ... } or a bare type string) → ordered cues. */\nexport function sceneEventToCues(event) {\n const type = typeof event === 'string' ? event : event?.type;\n switch (type) {\n case 'engine_start': return [play('engine_start')];\n case 'move_start': return [loopStart('engine_loop'), loopStart('tracks_loop')];\n case 'move_end': return [loopStop('tracks_loop'), loopStop('engine_loop')];\n case 'turret_start': return [loopStart('turret_loop')];\n case 'turret_end': return [loopStop('turret_loop')];\n case 'fire': return [play('cannon_fire')];\n case 'projectile_start': return [play('projectile_whistle')];\n case 'impact': {\n const name = IMPACT_SOUNDS[event?.kind];\n return name ? [play(name)] : [];\n }\n case 'tank_hit': return [play('tank_hit')];\n case 'big_explosion': return [play('big_explosion')];\n case 'destroyed': return [play('tank_destroyed')];\n default: return [];\n }\n}\n\n/** 'victory' | 'defeat' → cues; anything else (draw, unknown) stays silent. */\nexport function outcomeToCues(result) {\n if (result === 'victory' || result === 'defeat') return [...TANKS_LOOPS.map(loopStop), play(result)];\n return [];\n}\n","// Tanks (3D) sound layer.\n//\n// Expected files (host serves them from <assets>/sounds/tanks/, i.e. the\n// package's assets/sounds/tanks/), each as .ogg and .mp3: OGG Vorbis is used where\n// the browser supports it, MP3 otherwise. Only names listed in `available` are\n// fetched, so sounds not delivered (the optional UI cues) cost no requests and never error.\n// Format: 44.1 kHz, mono. True peak <= -1 dBTP; loops cut at zero crossings so\n// they repeat without clicks.\n//\n// name duration loudness\n// engine_start 1.5-2.5 s -20 LUFS\n// engine_loop 2-4 s (loop) -24 LUFS\n// tracks_loop 1-2 s (loop) -24 LUFS\n// turret_loop 1-2 s (loop) -26 LUFS\n// cannon_fire 1.5-2.5 s -16 LUFS\n// projectile_whistle 1.5-3 s -22 LUFS\n// terrain_impact 1-2 s -17 LUFS\n// tank_hit 1-2 s -16 LUFS\n// big_explosion 2.5-4 s -14 LUFS\n// tank_destroyed 3-5 s -18 LUFS\n// victory 3-4 s -18 LUFS\n// defeat 2.5-4 s -19 LUFS\n// Tanques LIVE (lives, shield, destructibles): life_lost, respawn, shield_loop (loop),\n// shield_end, health_pickup, crate_break, barrel_explode, wall_hit, last_life\n// optional: turn_start, your_turn, timer_warning (short UI cues, ~-22 LUFS)\n//\n// Gating: the games' shared mute/volume (connect4Sounds) applies through the\n// manager; the GLOBAL chat mute (isSoundEnabled) and a hidden page silence\n// every play and stop all loops.\n\nimport { createSoundManager } from '../../../audio/createSoundManager.js';\nimport { connect4Sounds } from '../../connect4/connect4Sounds.js';\nimport { chatSoundUrl } from '../../../assets/chatAssets.js';\nimport { isSoundEnabled, subscribeSoundPreference } from '../../../notifications/chatSounds.js';\nimport { outcomeToCues, sceneEventToCues, TANKS_LOOPS } from './cues.js';\n\nexport { outcomeToCues, sceneEventToCues } from './cues.js';\n\nexport const TANKS_SOUND_NAMES = [\n 'engine_start', 'engine_loop', 'tracks_loop', 'turret_loop', 'cannon_fire', 'projectile_whistle',\n 'terrain_impact', 'tank_hit', 'big_explosion', 'tank_destroyed', 'victory', 'defeat',\n 'turn_start', 'your_turn', 'timer_warning',\n 'life_lost', 'respawn', 'shield_loop', 'shield_end', 'health_pickup', 'crate_break', 'barrel_explode', 'wall_hit', 'last_life',\n];\n\n// Relative mix, set from the delivered files' measured loudness (blasts ~-16 LUFS,\n// impacts/stingers ~-20, loops -23..-25) so weapons lead and the engine sits under them.\nconst LEVELS = {\n engine_start: 0.6, engine_loop: 0.45, tracks_loop: 0.5, turret_loop: 0.5, cannon_fire: 0.8,\n projectile_whistle: 0.6, terrain_impact: 0.85, tank_hit: 0.85, big_explosion: 0.9, tank_destroyed: 1,\n victory: 0.8, defeat: 0.8, turn_start: 0.35, your_turn: 0.4, timer_warning: 0.35,\n life_lost: 0.8, respawn: 0.7, shield_loop: 0.4, shield_end: 0.55, health_pickup: 0.6, crate_break: 0.75,\n barrel_explode: 0.9, wall_hit: 0.6, last_life: 0.75,\n};\n\n// Sounds shipped in assets/sounds/tanks/ (the UI cues are optional and not delivered).\nexport const DELIVERED_TANKS_SOUNDS = [\n 'engine_start', 'engine_loop', 'tracks_loop', 'turret_loop', 'cannon_fire', 'projectile_whistle',\n 'terrain_impact', 'tank_hit', 'big_explosion', 'tank_destroyed', 'victory', 'defeat',\n 'life_lost', 'respawn', 'shield_loop', 'shield_end', 'health_pickup', 'crate_break', 'barrel_explode', 'wall_hit', 'last_life',\n];\n// The same sound within this window (cluster bomblets, impact + blast in one frame) plays once.\nconst RETRIGGER_MS = 120;\n// Short ramps so loops follow the animation without clicks (defaults are ambient-slow).\nconst LOOP_RAMPS = {\n engine_loop: { fadeIn: 0.5, fadeOut: 0.35 },\n tracks_loop: { fadeIn: 0.12, fadeOut: 0.2 },\n turret_loop: { fadeIn: 0.06, fadeOut: 0.12 },\n shield_loop: { fadeIn: 0.15, fadeOut: 0.25 },\n};\n// MP3 decoders pad both ends; trimming that keeps the Safari loops gapless.\nconst MP3_LOOP_TRIM = 0.03;\n// tank_destroyed is the cinematic destruction sound: big_explosion yields to it.\nconst YIELDS_TO = { tank_destroyed: { name: 'big_explosion', ms: 1500 } };\n\nconst supportsOgg = () => {\n try {\n return typeof Audio !== 'undefined' && new Audio().canPlayType('audio/ogg; codecs=\"vorbis\"') !== '';\n } catch {\n return false;\n }\n};\n\n// Shared by reference with the manager, so configure() still applies to files\n// not fetched yet.\nconst files = {};\nconst fileFor = (name, extension) => `${name}.${String(extension).replace(/^\\./, '')}`;\n\nlet configured = false;\nlet format = 'ogg';\n/**\n * Call before first use to change the format ('auto' | 'ogg' | 'mp3'), the delivered\n * names, or override files ({ name: 'file.ext' | null }).\n */\nexport function configureTanksSounds({ extension = 'auto', available = DELIVERED_TANKS_SOUNDS, files: overrides } = {}) {\n configured = true;\n format = extension === 'auto' ? (supportsOgg() ? 'ogg' : 'mp3') : extension;\n TANKS_SOUND_NAMES.forEach((name) => {\n if (available.includes(name)) files[name] = fileFor(name, format);\n else delete files[name];\n });\n Object.entries(overrides || {}).forEach(([name, file]) => {\n if (file) files[name] = String(file);\n else delete files[name];\n });\n}\n\nlet manager = null;\nexport function getTanksSoundManager() {\n if (!configured) configureTanksSounds();\n if (!manager) {\n manager = createSoundManager({\n id: 'tanks',\n baseUrl: () => chatSoundUrl('tanks'), // resolved lazily at fetch time\n settingsFrom: connect4Sounds, // one mute/volume preference for every chat game\n sounds: files,\n levels: LEVELS,\n });\n }\n return manager;\n}\n\nconst hidden = () => typeof document !== 'undefined' && document.hidden;\nconst canPlay = () => isSoundEnabled() && !hidden();\n\n// Loops the game currently wants; they only sound while canPlay().\nconst wantedLoops = new Set();\nconst syncLoops = () => {\n if (!manager) return;\n const allowed = canPlay();\n new Set([...TANKS_LOOPS, ...wantedLoops]).forEach((name) => {\n if (allowed && wantedLoops.has(name)) manager.startLoop(name, { ...LOOP_RAMPS[name], trim: format === 'mp3' ? MP3_LOOP_TRIM : 0 });\n else manager.stopLoop(name);\n });\n};\n\nlet started = false;\nlet unsubscribePreference = null;\n\n/** Idempotent: starts the manager, preloads files and links mute/visibility. */\nexport function startTanksSounds() {\n const sounds = getTanksSoundManager();\n sounds.preload();\n if (started) return;\n started = true;\n unsubscribePreference = subscribeSoundPreference(syncLoops);\n if (typeof document !== 'undefined') document.addEventListener('visibilitychange', syncLoops);\n}\n\n/** Stops loops and unlinks listeners (the manager restarts on next use). */\nexport function disposeTanksSounds() {\n wantedLoops.clear();\n syncLoops();\n if (unsubscribePreference) { unsubscribePreference(); unsubscribePreference = null; }\n if (typeof document !== 'undefined') document.removeEventListener('visibilitychange', syncLoops);\n started = false;\n manager?.dispose();\n}\n\nconst lastPlayed = new Map();\nconst suppressedUntil = new Map();\n\n/** Silences `name` for `ms` (e.g. a turn whose destruction already has its own sound). */\nexport function suppressTanksCue(name, ms) {\n suppressedUntil.set(name, Math.max(suppressedUntil.get(name) ?? 0, Date.now() + ms));\n}\n\n/** One-shot cue, deduplicated by key when given. Returns true when scheduled. */\nexport function playTanksCue(name, key) {\n if (!configured) configureTanksSounds();\n if (Date.now() < (suppressedUntil.get(name) ?? 0)) return false;\n if (!canPlay()) {\n // Keep keyed cues from replaying once the page/sound comes back.\n if (key != null) getTanksSoundManager().markPlayed(name, key);\n return false;\n }\n const now = Date.now();\n if (now - (lastPlayed.get(name) ?? 0) < RETRIGGER_MS) return false;\n const played = getTanksSoundManager().play(name, key != null ? { key } : undefined);\n if (played) {\n lastPlayed.set(name, now);\n if (YIELDS_TO[name]) suppressTanksCue(YIELDS_TO[name].name, YIELDS_TO[name].ms);\n }\n return played;\n}\n\nexport function startTanksLoop(name) {\n wantedLoops.add(name);\n getTanksSoundManager();\n syncLoops();\n}\n\nexport function stopTanksLoop(name) {\n wantedLoops.delete(name);\n manager?.stopLoop(name);\n}\n\nexport function stopAllTanksLoops() {\n const names = [...TANKS_LOOPS, ...wantedLoops];\n wantedLoops.clear();\n names.forEach((name) => manager?.stopLoop(name));\n}\n\nconst runCues = (cues, key) => cues.forEach(({ name, action }) => {\n if (action === 'loop_start') startTanksLoop(name);\n else if (action === 'loop_stop') stopTanksLoop(name);\n else playTanksCue(name, key != null ? `${key}:${name}` : undefined);\n});\n\n/** Maps a scene onEvent ({ type, kind?, tankId? }) to sounds. `key` dedupes one-shots (e.g. turn id). */\nexport function handleSceneEvent(event, key) {\n const suffix = event?.tankId != null ? `:${event.tankId}` : '';\n runCues(sceneEventToCues(event), key != null ? `${key}${suffix}` : undefined);\n}\n\n/** 'victory' | 'defeat': stops every loop and plays the outcome once per key. */\nexport function playOutcome(result, key) {\n runCues(outcomeToCues(result), key);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tanksSounds-DTnidbiq.js","names":["chatSoundUrl","isSoundEnabled","subscribeSoundPreference","createSoundManager","connect4Sounds","TANKS_LOOPS","play","loopStart","loopStop","IMPACT_SOUNDS","sceneEventToCues","event","name","outcomeToCues","result","TANKS_SOUND_NAMES","LEVELS","DELIVERED_TANKS_SOUNDS","RETRIGGER_MS","LOOP_RAMPS","MP3_LOOP_TRIM","YIELDS_TO","supportsOgg","files","fileFor","extension","configured","format","configureTanksSounds","overrides","available","file","manager","getTanksSoundManager","hidden","canPlay","wantedLoops","syncLoops","allowed","started","startTanksSounds","lastPlayed","suppressedUntil","suppressTanksCue","ms","playTanksCue","key","now","played","startTanksLoop","stopTanksLoop","stopAllTanksLoops","names","runCues","cues","action","handleSceneEvent","suffix","playOutcome"],"sources":["../../src/games/tanks/sound/cues.js","../../src/games/tanks/sound/tanksSounds.js"],"sourcesContent":["// Pure sound choreography for Tanks (no audio, no DOM): maps scene events to\n// one-shot plays and loop start/stop actions.\n\nexport const TANKS_LOOPS = ['engine_loop', 'tracks_loop', 'turret_loop'];\n\nconst play = (name) => ({ name, action: 'play' });\nconst loopStart = (name) => ({ name, action: 'loop_start' });\nconst loopStop = (name) => ({ name, action: 'loop_stop' });\n\nconst IMPACT_SOUNDS = { terrain: 'terrain_impact', obstacle: 'terrain_impact', ground: 'terrain_impact' };\n\n/** Scene onEvent ({ type, ... } or a bare type string) → ordered cues. */\nexport function sceneEventToCues(event) {\n const type = typeof event === 'string' ? event : event?.type;\n switch (type) {\n case 'engine_start': return [play('engine_start')];\n case 'move_start': return [loopStart('engine_loop'), loopStart('tracks_loop')];\n case 'move_end': return [loopStop('tracks_loop'), loopStop('engine_loop')];\n case 'turret_start': return [loopStart('turret_loop')];\n case 'turret_end': return [loopStop('turret_loop')];\n case 'fire': return [play('cannon_fire')];\n case 'projectile_start': return [play('projectile_whistle')];\n case 'impact': {\n const name = IMPACT_SOUNDS[event?.kind];\n return name ? [play(name)] : [];\n }\n case 'tank_hit': return [play('tank_hit')];\n case 'big_explosion': return [play('big_explosion')];\n case 'destroyed': return [play('tank_destroyed')];\n default: return [];\n }\n}\n\n/** 'victory' | 'defeat' → cues; anything else (draw, unknown) stays silent. */\nexport function outcomeToCues(result) {\n if (result === 'victory' || result === 'defeat') return [...TANKS_LOOPS.map(loopStop), play(result)];\n return [];\n}\n","// Tanks (3D) sound layer.\n//\n// Expected files (host serves them from <assets>/sounds/tanks/, i.e. the\n// package's assets/sounds/tanks/), each as .ogg and .mp3: OGG Vorbis is used where\n// the browser supports it, MP3 otherwise. Only names listed in `available` are\n// fetched, so sounds not delivered (the optional UI cues) cost no requests and never error.\n// Format: 44.1 kHz, mono. True peak <= -1 dBTP; loops cut at zero crossings so\n// they repeat without clicks.\n//\n// name duration loudness\n// engine_start 1.5-2.5 s -20 LUFS\n// engine_loop 2-4 s (loop) -24 LUFS\n// tracks_loop 1-2 s (loop) -24 LUFS\n// turret_loop 1-2 s (loop) -26 LUFS\n// cannon_fire 1.5-2.5 s -16 LUFS\n// projectile_whistle 1.5-3 s -22 LUFS\n// terrain_impact 1-2 s -17 LUFS\n// tank_hit 1-2 s -16 LUFS\n// big_explosion 2.5-4 s -14 LUFS\n// tank_destroyed 3-5 s -18 LUFS\n// victory 3-4 s -18 LUFS\n// defeat 2.5-4 s -19 LUFS\n// Tanques LIVE (lives, shield, destructibles): life_lost, respawn, shield_loop (loop),\n// shield_end, health_pickup, crate_break, barrel_explode, wall_hit, last_life\n// optional: turn_start, your_turn, timer_warning (short UI cues, ~-22 LUFS)\n//\n// Gating: the games' shared mute/volume (connect4Sounds) applies through the\n// manager; the GLOBAL chat mute (isSoundEnabled) and a hidden page silence\n// every play and stop all loops.\n\nimport { createSoundManager } from '../../../audio/createSoundManager.js';\nimport { connect4Sounds } from '../../connect4/connect4Sounds.js';\nimport { chatSoundUrl } from '../../../assets/chatAssets.js';\nimport { isSoundEnabled, subscribeSoundPreference } from '../../../notifications/chatSounds.js';\nimport { outcomeToCues, sceneEventToCues, TANKS_LOOPS } from './cues.js';\n\nexport { outcomeToCues, sceneEventToCues } from './cues.js';\n\nexport const TANKS_SOUND_NAMES = [\n 'engine_start', 'engine_loop', 'tracks_loop', 'turret_loop', 'cannon_fire', 'projectile_whistle',\n 'terrain_impact', 'tank_hit', 'big_explosion', 'tank_destroyed', 'victory', 'defeat',\n 'turn_start', 'your_turn', 'timer_warning',\n 'life_lost', 'respawn', 'shield_loop', 'shield_end', 'health_pickup', 'crate_break', 'barrel_explode', 'wall_hit', 'last_life',\n];\n\n// Relative mix, set from the delivered files' measured loudness (blasts ~-16 LUFS,\n// impacts/stingers ~-20, loops -23..-25) so weapons lead and the engine sits under them.\nconst LEVELS = {\n engine_start: 0.6, engine_loop: 0.45, tracks_loop: 0.5, turret_loop: 0.5, cannon_fire: 0.8,\n projectile_whistle: 0.6, terrain_impact: 0.85, tank_hit: 0.85, big_explosion: 0.9, tank_destroyed: 1,\n victory: 0.8, defeat: 0.8, turn_start: 0.35, your_turn: 0.4, timer_warning: 0.35,\n life_lost: 0.8, respawn: 0.7, shield_loop: 0.4, shield_end: 0.55, health_pickup: 0.6, crate_break: 0.75,\n barrel_explode: 0.9, wall_hit: 0.6, last_life: 0.75,\n};\n\n// Sounds shipped in assets/sounds/tanks/ (the UI cues are optional and not delivered).\nexport const DELIVERED_TANKS_SOUNDS = [\n 'engine_start', 'engine_loop', 'tracks_loop', 'turret_loop', 'cannon_fire', 'projectile_whistle',\n 'terrain_impact', 'tank_hit', 'big_explosion', 'tank_destroyed', 'victory', 'defeat',\n 'life_lost', 'respawn', 'shield_loop', 'shield_end', 'health_pickup', 'crate_break', 'barrel_explode', 'wall_hit', 'last_life',\n];\n// The same sound within this window (cluster bomblets, impact + blast in one frame) plays once.\nconst RETRIGGER_MS = 120;\n// Short ramps so loops follow the animation without clicks (defaults are ambient-slow).\nconst LOOP_RAMPS = {\n engine_loop: { fadeIn: 0.5, fadeOut: 0.35 },\n tracks_loop: { fadeIn: 0.12, fadeOut: 0.2 },\n turret_loop: { fadeIn: 0.06, fadeOut: 0.12 },\n shield_loop: { fadeIn: 0.15, fadeOut: 0.25 },\n};\n// MP3 decoders pad both ends; trimming that keeps the Safari loops gapless.\nconst MP3_LOOP_TRIM = 0.03;\n// tank_destroyed is the cinematic destruction sound: big_explosion yields to it.\nconst YIELDS_TO = { tank_destroyed: { name: 'big_explosion', ms: 1500 } };\n\nconst supportsOgg = () => {\n try {\n return typeof Audio !== 'undefined' && new Audio().canPlayType('audio/ogg; codecs=\"vorbis\"') !== '';\n } catch {\n return false;\n }\n};\n\n// Shared by reference with the manager, so configure() still applies to files\n// not fetched yet.\nconst files = {};\nconst fileFor = (name, extension) => `${name}.${String(extension).replace(/^\\./, '')}`;\n\nlet configured = false;\nlet format = 'ogg';\n/**\n * Call before first use to change the format ('auto' | 'ogg' | 'mp3'), the delivered\n * names, or override files ({ name: 'file.ext' | null }).\n */\nexport function configureTanksSounds({ extension = 'auto', available = DELIVERED_TANKS_SOUNDS, files: overrides } = {}) {\n configured = true;\n format = extension === 'auto' ? (supportsOgg() ? 'ogg' : 'mp3') : extension;\n TANKS_SOUND_NAMES.forEach((name) => {\n if (available.includes(name)) files[name] = fileFor(name, format);\n else delete files[name];\n });\n Object.entries(overrides || {}).forEach(([name, file]) => {\n if (file) files[name] = String(file);\n else delete files[name];\n });\n}\n\nlet manager = null;\nexport function getTanksSoundManager() {\n if (!configured) configureTanksSounds();\n if (!manager) {\n manager = createSoundManager({\n id: 'tanks',\n baseUrl: () => chatSoundUrl('tanks'), // resolved lazily at fetch time\n settingsFrom: connect4Sounds, // one mute/volume preference for every chat game\n sounds: files,\n levels: LEVELS,\n });\n }\n return manager;\n}\n\nconst hidden = () => typeof document !== 'undefined' && document.hidden;\nconst canPlay = () => isSoundEnabled() && !hidden();\n\n// Loops the game currently wants; they only sound while canPlay().\nconst wantedLoops = new Set();\nconst syncLoops = () => {\n if (!manager) return;\n const allowed = canPlay();\n new Set([...TANKS_LOOPS, ...wantedLoops]).forEach((name) => {\n if (allowed && wantedLoops.has(name)) manager.startLoop(name, { ...LOOP_RAMPS[name], trim: format === 'mp3' ? MP3_LOOP_TRIM : 0 });\n else manager.stopLoop(name);\n });\n};\n\nlet started = false;\nlet unsubscribePreference = null;\n\n/** Idempotent: starts the manager, preloads files and links mute/visibility. */\nexport function startTanksSounds() {\n const sounds = getTanksSoundManager();\n sounds.preload();\n if (started) return;\n started = true;\n unsubscribePreference = subscribeSoundPreference(syncLoops);\n if (typeof document !== 'undefined') document.addEventListener('visibilitychange', syncLoops);\n}\n\n/** Stops loops and unlinks listeners (the manager restarts on next use). */\nexport function disposeTanksSounds() {\n wantedLoops.clear();\n syncLoops();\n if (unsubscribePreference) { unsubscribePreference(); unsubscribePreference = null; }\n if (typeof document !== 'undefined') document.removeEventListener('visibilitychange', syncLoops);\n started = false;\n manager?.dispose();\n}\n\nconst lastPlayed = new Map();\nconst suppressedUntil = new Map();\n\n/** Silences `name` for `ms` (e.g. a turn whose destruction already has its own sound). */\nexport function suppressTanksCue(name, ms) {\n suppressedUntil.set(name, Math.max(suppressedUntil.get(name) ?? 0, Date.now() + ms));\n}\n\n/** One-shot cue, deduplicated by key when given. Returns true when scheduled. */\nexport function playTanksCue(name, key) {\n if (!configured) configureTanksSounds();\n if (Date.now() < (suppressedUntil.get(name) ?? 0)) return false;\n if (!canPlay()) {\n // Keep keyed cues from replaying once the page/sound comes back.\n if (key != null) getTanksSoundManager().markPlayed(name, key);\n return false;\n }\n const now = Date.now();\n if (now - (lastPlayed.get(name) ?? 0) < RETRIGGER_MS) return false;\n const played = getTanksSoundManager().play(name, key != null ? { key } : undefined);\n if (played) {\n lastPlayed.set(name, now);\n if (YIELDS_TO[name]) suppressTanksCue(YIELDS_TO[name].name, YIELDS_TO[name].ms);\n }\n return played;\n}\n\nexport function startTanksLoop(name) {\n wantedLoops.add(name);\n getTanksSoundManager();\n syncLoops();\n}\n\nexport function stopTanksLoop(name) {\n wantedLoops.delete(name);\n manager?.stopLoop(name);\n}\n\nexport function stopAllTanksLoops() {\n const names = [...TANKS_LOOPS, ...wantedLoops];\n wantedLoops.clear();\n names.forEach((name) => manager?.stopLoop(name));\n}\n\nconst runCues = (cues, key) => cues.forEach(({ name, action }) => {\n if (action === 'loop_start') startTanksLoop(name);\n else if (action === 'loop_stop') stopTanksLoop(name);\n else playTanksCue(name, key != null ? `${key}:${name}` : undefined);\n});\n\n/** Maps a scene onEvent ({ type, kind?, tankId? }) to sounds. `key` dedupes one-shots (e.g. turn id). */\nexport function handleSceneEvent(event, key) {\n const suffix = event?.tankId != null ? `:${event.tankId}` : '';\n runCues(sceneEventToCues(event), key != null ? `${key}${suffix}` : undefined);\n}\n\n/** 'victory' | 'defeat': stops every loop and plays the outcome once per key. */\nexport function playOutcome(result, key) {\n runCues(outcomeToCues(result), key);\n}\n"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { _ as e, a as t, g as n, h as r, i,
|
|
1
|
+
import { _ as e, a as t, g as n, h as r, i, k as a, n as o, r as s, t as c } from "./chunks/games-Bl_8raG6.js";
|
|
2
2
|
import { a as l, c as u, i as d, n as f, o as p, s as m, t as h } from "./chunks/createPeerLink-DBVs_yvQ.js";
|
|
3
|
-
import { a as g, i as _, n as v, o as y, r as b, s as x, t as S } from "./chunks/ChatContext-
|
|
3
|
+
import { a as g, i as _, n as v, o as y, r as b, s as x, t as S } from "./chunks/ChatContext-CVW58bzC.js";
|
|
4
4
|
import { i as C, n as w, r as T } from "./chunks/timeline-BLBedCYj.js";
|
|
5
5
|
import { n as E, r as D, t as O } from "./chunks/connectionStore-DwgIUl30.js";
|
|
6
6
|
import { a as k, c as A, l as j, n as M, o as ee, r as N, s as P, t as te } from "./chunks/gameStatus-BChd29yI.js";
|
|
7
|
-
import { i as ne, n as re, o as F, r as ie, t as ae } from "./chunks/connect4Sounds-
|
|
7
|
+
import { i as ne, n as re, o as F, r as ie, t as ae } from "./chunks/connect4Sounds-BqEHULjv.js";
|
|
8
8
|
import { t as I } from "./chunks/signalFaults-Dv2YjjKy.js";
|
|
9
9
|
import { Component as L, Suspense as R, createContext as oe, lazy as se, memo as z, useCallback as B, useContext as V, useEffect as H, useId as ce, useMemo as U, useRef as W, useState as G, useSyncExternalStore as K } from "react";
|
|
10
10
|
import { createStore as le } from "zustand/vanilla";
|
|
@@ -657,15 +657,15 @@ var Un = (e, t) => Ln?.scope === e && String(Ln.room) === String(t) && Ln.open &
|
|
|
657
657
|
function Kn() {
|
|
658
658
|
Fn.forEach((e) => e.close()), Fn.clear(), Ln = null;
|
|
659
659
|
}
|
|
660
|
-
async function qn(e, { scope: t, room: n, id: r, onClick: i, connectedAt:
|
|
661
|
-
let
|
|
662
|
-
if (!
|
|
660
|
+
async function qn(e, { scope: t, room: n, id: r, onClick: i, connectedAt: o, isCurrent: s }) {
|
|
661
|
+
let c = zn();
|
|
662
|
+
if (!c.supported || !c.enabled || c.permission !== "granted" || n == null || !r) return;
|
|
663
663
|
let l = Date.parse(e.timestamp);
|
|
664
|
-
if (!Number.isFinite(l) || l <
|
|
664
|
+
if (!Number.isFinite(l) || l < o || e.localOnly || e.optimistic || e.is_history || e.history) return;
|
|
665
665
|
let u = `${t}:${r}`;
|
|
666
666
|
if (Pn.has(u)) return;
|
|
667
667
|
Pn.add(u), Pn.size > 500 && Pn.delete(Pn.values().next().value);
|
|
668
|
-
let d = Un(t, n), f =
|
|
668
|
+
let d = Un(t, n), f = a();
|
|
669
669
|
if (In.set(f, () => {
|
|
670
670
|
d = !0;
|
|
671
671
|
}), Nn?.postMessage({
|
|
@@ -673,7 +673,7 @@ async function qn(e, { scope: t, room: n, id: r, onClick: i, connectedAt: a, isC
|
|
|
673
673
|
id: f,
|
|
674
674
|
scope: t,
|
|
675
675
|
room: n
|
|
676
|
-
}), await Gn(150), In.delete(f), d || Un(t, n) || !
|
|
676
|
+
}), await Gn(150), In.delete(f), d || Un(t, n) || !s()) return;
|
|
677
677
|
let p = async () => {
|
|
678
678
|
let r = `lira-chat-desktop-seen:${u}`;
|
|
679
679
|
try {
|
|
@@ -684,16 +684,16 @@ async function qn(e, { scope: t, room: n, id: r, onClick: i, connectedAt: a, isC
|
|
|
684
684
|
} catch {
|
|
685
685
|
return;
|
|
686
686
|
}
|
|
687
|
-
if (!
|
|
688
|
-
let a = Rn(Mn) && !String(n).startsWith("private") && !e.private && !e.sensitive,
|
|
687
|
+
if (!s() || !zn().enabled || Notification.permission !== "granted" || Un(t, n)) return;
|
|
688
|
+
let a = Rn(Mn) && !String(n).startsWith("private") && !e.private && !e.sensitive, o = String(e.username || "Nuevo mensaje").replace(/\s+/g, " ").slice(0, 70), c = a ? String(e.message || e.text || "Archivo adjunto").replace(/\s+/g, " ").slice(0, 140) : "Tienes un nuevo mensaje en LIRA Chat";
|
|
689
689
|
try {
|
|
690
|
-
let e = new Notification(a ?
|
|
690
|
+
let e = new Notification(a ? o : "LIRA Chat", {
|
|
691
691
|
body: c,
|
|
692
692
|
tag: u,
|
|
693
693
|
silent: !0
|
|
694
694
|
});
|
|
695
695
|
Fn.add(e), e.onclose = () => Fn.delete(e), e.onclick = () => {
|
|
696
|
-
e.close(),
|
|
696
|
+
e.close(), s() && (window.focus(), i());
|
|
697
697
|
}, Nn?.postMessage({
|
|
698
698
|
type: "shown",
|
|
699
699
|
id: u
|
|
@@ -1299,13 +1299,13 @@ var jr = /* @__PURE__ */ new Map([
|
|
|
1299
1299
|
function Mr(e, { volume: t = .4, onBlocked: n, onPlaying: r } = {}) {
|
|
1300
1300
|
let i = jr.get(e);
|
|
1301
1301
|
if (!i) return () => {};
|
|
1302
|
-
let a, o = !1,
|
|
1303
|
-
!o && !
|
|
1302
|
+
let a, o = !1, s = !1, l = () => {
|
|
1303
|
+
!o && !s && (s = !0, n?.());
|
|
1304
1304
|
}, u = () => {
|
|
1305
1305
|
o || r?.(a);
|
|
1306
1306
|
};
|
|
1307
1307
|
try {
|
|
1308
|
-
a = new Audio(
|
|
1308
|
+
a = new Audio(c(`effects/${i.file}`)), a.volume = Math.max(0, Math.min(1, (Number(t) || 0) * (i.level ?? 1))), a.preload = "auto", a.addEventListener("error", l), a.addEventListener("playing", u), a.play()?.catch(l);
|
|
1309
1309
|
} catch {
|
|
1310
1310
|
l();
|
|
1311
1311
|
}
|
|
@@ -1800,7 +1800,7 @@ function Zr({ clockRef: e, waitForAudio: t = !0 }) {
|
|
|
1800
1800
|
}, y = (e) => {
|
|
1801
1801
|
e && (c.add(e), e.onfinish = () => c.delete(e));
|
|
1802
1802
|
};
|
|
1803
|
-
import("./chunks/avalancheScene3d-
|
|
1803
|
+
import("./chunks/avalancheScene3d-CIE2WKQn.js").then(({ createAvalancheScene: e }) => {
|
|
1804
1804
|
d || (u = document.createElement("canvas"), u.className = "lira-avalanche-canvas", u.addEventListener("webglcontextlost", v), i.prepend(u), l = e(u), l.resize(i.clientWidth || 1, i.clientHeight || 1));
|
|
1805
1805
|
}).catch(_);
|
|
1806
1806
|
let b = (e) => {
|
|
@@ -5911,19 +5911,19 @@ function Is(e, t, n) {
|
|
|
5911
5911
|
var Ls = {
|
|
5912
5912
|
racing_live: {
|
|
5913
5913
|
title: "Carreras LIVE 🏎️",
|
|
5914
|
-
load: () => se(() => import("./chunks/RacingLiveGameCard-
|
|
5914
|
+
load: () => se(() => import("./chunks/RacingLiveGameCard-8j9QLnxW.js").then((e) => e.t))
|
|
5915
5915
|
},
|
|
5916
5916
|
battleship: {
|
|
5917
5917
|
title: "Batalla Naval",
|
|
5918
|
-
load: () => se(() => import("./chunks/BattleshipGameCard-
|
|
5918
|
+
load: () => se(() => import("./chunks/BattleshipGameCard-8H-sBCsv.js"))
|
|
5919
5919
|
},
|
|
5920
5920
|
tanks_live: {
|
|
5921
5921
|
title: "Tanques LIVE 3D",
|
|
5922
|
-
load: () => se(() => import("./chunks/TanksLiveGameCard-
|
|
5922
|
+
load: () => se(() => import("./chunks/TanksLiveGameCard-D_27Jomp.js").then((e) => e.t))
|
|
5923
5923
|
},
|
|
5924
5924
|
tanks: {
|
|
5925
5925
|
title: "Tanques de guerra",
|
|
5926
|
-
load: () => se(() => import("./chunks/TanksGameCard-
|
|
5926
|
+
load: () => se(() => import("./chunks/TanksGameCard-DnCufSH6.js"))
|
|
5927
5927
|
}
|
|
5928
5928
|
}, Rs = {}, zs = (e) => (Rs[e] ?? (Rs[e] = Ls[e].load()), Rs[e]);
|
|
5929
5929
|
function Bs({ title: e }) {
|
|
@@ -11362,7 +11362,7 @@ var Yu = 10485760, Xu = /* @__PURE__ */ new WeakMap(), Zu = (e) => (Xu.has(e) ||
|
|
|
11362
11362
|
}), Xu.get(e));
|
|
11363
11363
|
function Qu(e, t, n) {
|
|
11364
11364
|
if (e?.readyState !== WebSocket.OPEN) return Promise.reject(/* @__PURE__ */ Error("Sin conexión"));
|
|
11365
|
-
let r = Zu(e), i =
|
|
11365
|
+
let r = Zu(e), i = a();
|
|
11366
11366
|
return new Promise((a, o) => {
|
|
11367
11367
|
let s = setTimeout(() => {
|
|
11368
11368
|
r.pending.delete(i), o(/* @__PURE__ */ Error("El servidor no confirmó el envío. Conservamos el borrador."));
|
|
@@ -11443,20 +11443,20 @@ async function nd(e, t, n, r = []) {
|
|
|
11443
11443
|
}
|
|
11444
11444
|
let r = n.file;
|
|
11445
11445
|
if (!(r instanceof Blob) || !r.size || r.size > Yu) throw Error("El archivo debe pesar entre 1 byte y 10 MB.");
|
|
11446
|
-
let
|
|
11447
|
-
for (let i = 0,
|
|
11446
|
+
let o = a();
|
|
11447
|
+
for (let i = 0, a = 0; i < r.size; i += 32768, a++) {
|
|
11448
11448
|
let s = new Uint8Array(await r.slice(i, i + 32768).arrayBuffer()), c = btoa(String.fromCharCode(...s));
|
|
11449
11449
|
await Qu(e, "CHAT_FILE", {
|
|
11450
|
-
id:
|
|
11450
|
+
id: o,
|
|
11451
11451
|
room_id: t,
|
|
11452
11452
|
size: r.size,
|
|
11453
11453
|
type: r.type || "application/octet-stream",
|
|
11454
11454
|
name: n.name,
|
|
11455
|
-
index:
|
|
11455
|
+
index: a,
|
|
11456
11456
|
chunk: c
|
|
11457
11457
|
});
|
|
11458
11458
|
}
|
|
11459
|
-
i.push({ id:
|
|
11459
|
+
i.push({ id: o });
|
|
11460
11460
|
}
|
|
11461
11461
|
await Qu(e, "CHAT_MESSAGE", {
|
|
11462
11462
|
room_id: t,
|
|
@@ -11466,6 +11466,6 @@ async function nd(e, t, n, r = []) {
|
|
|
11466
11466
|
}
|
|
11467
11467
|
// src/net/webrtc/index.js
|
|
11468
11468
|
var rd = se(() => import("./chunks/WebRtcLab-ClRSYt4E.js")), id = "0.1.0", ad = () => import("./chunks/BattleshipPrototype-CmQd5AUO.js");
|
|
11469
|
-
export { Uu as ChatButton, S as ChatContext, Ju as ChatNotifications, Hu as ChatPage, ys as ChatPeopleContext, Vu as ChatWindow, bu as ChatWindowShell, Mt as DEFAULT_CONFIG, h as DEFAULT_ICE_SERVERS, pn as EDIT_PREFIX, kr as EFFECT_CATALOG, ri as EFFECT_PREFIX, gs as EmojiPicker, Pl as GifPicker, Mi as LiraChatProvider, Qn as MAX_CHAT_MESSAGES, d as MAX_SIGNAL_LENGTH, id as MINICODE_CHAT_VERSION, Es as MessageBubble, vu as MessageComposer, Ks as MessageList, mn as REACT_PREFIX, vn as STICKER_NAME_PREFIX, ru as StickerPicker, Ni as TRANSPORT_STATUSES, l as WEBRTC_PREFIX, rd as WebRtcLab, Fi as assertTransport, O as chatConnectionStore, i as chatGamesStore, Nu as chatUiStore, td as closeRelay, Vi as configureKlipy, $u as consumeRelayEvent, n as createChatSignaling, dr as createChatStore, f as createPeerLink, Gt as createStandaloneTransport, li as decodeEffect, p as decodeSignal, Cn as encodeEdit, ci as encodeEffect, wn as encodeReaction, m as encodeSignal,
|
|
11469
|
+
export { Uu as ChatButton, S as ChatContext, Ju as ChatNotifications, Hu as ChatPage, ys as ChatPeopleContext, Vu as ChatWindow, bu as ChatWindowShell, Mt as DEFAULT_CONFIG, h as DEFAULT_ICE_SERVERS, pn as EDIT_PREFIX, kr as EFFECT_CATALOG, ri as EFFECT_PREFIX, gs as EmojiPicker, Pl as GifPicker, Mi as LiraChatProvider, Qn as MAX_CHAT_MESSAGES, d as MAX_SIGNAL_LENGTH, id as MINICODE_CHAT_VERSION, Es as MessageBubble, vu as MessageComposer, Ks as MessageList, mn as REACT_PREFIX, vn as STICKER_NAME_PREFIX, ru as StickerPicker, Ni as TRANSPORT_STATUSES, l as WEBRTC_PREFIX, rd as WebRtcLab, Fi as assertTransport, O as chatConnectionStore, i as chatGamesStore, Nu as chatUiStore, td as closeRelay, Vi as configureKlipy, $u as consumeRelayEvent, n as createChatSignaling, dr as createChatStore, f as createPeerLink, Gt as createStandaloneTransport, li as decodeEffect, p as decodeSignal, Cn as encodeEdit, ci as encodeEffect, wn as encodeReaction, m as encodeSignal, o as getChatAssetsBaseUrl, Ar as getChatEffect, kn as groupReactions, ed as hydrateRelayMessage, xn as isMessageAction, yn as isStickerAttachment, u as isWebrtcMessage, ad as loadBattleshipPreview, Rt as normalizeConfig, Pt as normalizeUser, ku as openChatWindow, Tn as parseMessageAction, Au as registerChatWorker, e as rtcSignals, nd as sendRelayMessage, s as setChatAssetsBaseUrl, E as setChatConnectionStatus, qu as startAppBadge, Eu as startChatApp, ne as startConnect4Sounds, Zn as startDesktopNotifications, ss as startEmojiPreferencesSync, Hc as startGifLibrarySync, fn as startUnreadStorageSync, nn as totalUnread, Zt as unreadScope, mr as useChatConfig, xr as useChatConnection, D as useChatConnectionStatus, v as useChatContext, t as useChatGames, wr as useChatIdentity, Du as useChatInstall, _r as useChatStore, vr as useChatStoreApi, hr as useChatTransport, Fu as useChatUi, dn as useChatUnread, Cr as useChatUnreadTotal, I as withSignalFaults };
|
|
11470
11470
|
|
|
11471
11471
|
//# sourceMappingURL=index.js.map
|