@datamoc/mw_games 0.42.0 → 0.44.2
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/CHANGELOG.md +126 -0
- package/README.md +84 -1
- package/REFERENCE.md +134 -6
- package/api-surface.json +1814 -116
- package/data/microgm-essential.PROVENANCE.md +13 -0
- package/data/microgm-essential.sf2 +0 -0
- package/data/soundfont-catalog.json +8 -0
- package/dist/actors/Resource.d.ts.map +1 -1
- package/dist/actors/Resource.js +2 -3
- package/dist/actors/Resource.js.map +1 -1
- package/dist/audio/AdaptiveMusic.d.ts +85 -0
- package/dist/audio/AdaptiveMusic.d.ts.map +1 -0
- package/dist/audio/AdaptiveMusic.js +230 -0
- package/dist/audio/AdaptiveMusic.js.map +1 -0
- package/dist/audio/AudioLoader.d.ts +33 -0
- package/dist/audio/AudioLoader.d.ts.map +1 -0
- package/dist/audio/AudioLoader.js +58 -0
- package/dist/audio/AudioLoader.js.map +1 -0
- package/dist/audio/AudioViews.d.ts +70 -0
- package/dist/audio/AudioViews.d.ts.map +1 -0
- package/dist/audio/AudioViews.js +119 -0
- package/dist/audio/AudioViews.js.map +1 -0
- package/dist/audio/BusBudget.d.ts +89 -0
- package/dist/audio/BusBudget.d.ts.map +1 -0
- package/dist/audio/BusBudget.js +120 -0
- package/dist/audio/BusBudget.js.map +1 -0
- package/dist/audio/Channels.d.ts +66 -1
- package/dist/audio/Channels.d.ts.map +1 -1
- package/dist/audio/Channels.js +119 -31
- package/dist/audio/Channels.js.map +1 -1
- package/dist/audio/CoreHost.d.ts +114 -0
- package/dist/audio/CoreHost.d.ts.map +1 -0
- package/dist/audio/CoreHost.js +335 -0
- package/dist/audio/CoreHost.js.map +1 -0
- package/dist/audio/DecoderGuard.d.ts +139 -0
- package/dist/audio/DecoderGuard.d.ts.map +1 -0
- package/dist/audio/DecoderGuard.js +208 -0
- package/dist/audio/DecoderGuard.js.map +1 -0
- package/dist/audio/Fft.d.ts +3 -0
- package/dist/audio/Fft.d.ts.map +1 -0
- package/dist/audio/Fft.js +45 -0
- package/dist/audio/Fft.js.map +1 -0
- package/dist/audio/LoopTags.d.ts +18 -0
- package/dist/audio/LoopTags.d.ts.map +1 -1
- package/dist/audio/LoopTags.js +20 -0
- package/dist/audio/LoopTags.js.map +1 -1
- package/dist/audio/Midi.d.ts +35 -0
- package/dist/audio/Midi.d.ts.map +1 -1
- package/dist/audio/Midi.js +71 -1
- package/dist/audio/Midi.js.map +1 -1
- package/dist/audio/MidiRender.d.ts +47 -0
- package/dist/audio/MidiRender.d.ts.map +1 -1
- package/dist/audio/MidiRender.js +100 -2
- package/dist/audio/MidiRender.js.map +1 -1
- package/dist/audio/MidiSynth.d.ts +147 -0
- package/dist/audio/MidiSynth.d.ts.map +1 -0
- package/dist/audio/MidiSynth.js +205 -0
- package/dist/audio/MidiSynth.js.map +1 -0
- package/dist/audio/MusicPlayer.d.ts +80 -0
- package/dist/audio/MusicPlayer.d.ts.map +1 -0
- package/dist/audio/MusicPlayer.js +147 -0
- package/dist/audio/MusicPlayer.js.map +1 -0
- package/dist/audio/Playable.d.ts +7 -0
- package/dist/audio/Playable.d.ts.map +1 -1
- package/dist/audio/Playable.js.map +1 -1
- package/dist/audio/Positional.d.ts +12 -4
- package/dist/audio/Positional.d.ts.map +1 -1
- package/dist/audio/Positional.js +5 -2
- package/dist/audio/Positional.js.map +1 -1
- package/dist/audio/Resample.d.ts +61 -0
- package/dist/audio/Resample.d.ts.map +1 -0
- package/dist/audio/Resample.js +97 -0
- package/dist/audio/Resample.js.map +1 -0
- package/dist/audio/SampleDecoder.d.ts +16 -2
- package/dist/audio/SampleDecoder.d.ts.map +1 -1
- package/dist/audio/SampleDecoder.js +10 -6
- package/dist/audio/SampleDecoder.js.map +1 -1
- package/dist/audio/Settings.d.ts +99 -0
- package/dist/audio/Settings.d.ts.map +1 -0
- package/dist/audio/Settings.js +134 -0
- package/dist/audio/Settings.js.map +1 -0
- package/dist/audio/Sfx.d.ts +148 -0
- package/dist/audio/Sfx.d.ts.map +1 -0
- package/dist/audio/Sfx.js +213 -0
- package/dist/audio/Sfx.js.map +1 -0
- package/dist/audio/Sound.d.ts +2 -0
- package/dist/audio/Sound.d.ts.map +1 -1
- package/dist/audio/Sound.js +3 -0
- package/dist/audio/Sound.js.map +1 -1
- package/dist/audio/SoundFont.d.ts +5 -3
- package/dist/audio/SoundFont.d.ts.map +1 -1
- package/dist/audio/SoundFont.js +10 -8
- package/dist/audio/SoundFont.js.map +1 -1
- package/dist/audio/SpectralDistance.d.ts +34 -0
- package/dist/audio/SpectralDistance.d.ts.map +1 -0
- package/dist/audio/SpectralDistance.js +64 -0
- package/dist/audio/SpectralDistance.js.map +1 -0
- package/dist/audio/StreamChannel.d.ts +150 -0
- package/dist/audio/StreamChannel.d.ts.map +1 -0
- package/dist/audio/StreamChannel.js +390 -0
- package/dist/audio/StreamChannel.js.map +1 -0
- package/dist/audio/StreamPlayable.d.ts +73 -0
- package/dist/audio/StreamPlayable.d.ts.map +1 -0
- package/dist/audio/StreamPlayable.js +130 -0
- package/dist/audio/StreamPlayable.js.map +1 -0
- package/dist/audio/Synth.d.ts +1 -1
- package/dist/audio/Synth.d.ts.map +1 -1
- package/dist/audio/Synth.js +4 -0
- package/dist/audio/Synth.js.map +1 -1
- package/dist/audio/SyxBank.d.ts +73 -0
- package/dist/audio/SyxBank.d.ts.map +1 -0
- package/dist/audio/SyxBank.js +130 -0
- package/dist/audio/SyxBank.js.map +1 -0
- package/dist/audio/Underrun.d.ts +25 -0
- package/dist/audio/Underrun.d.ts.map +1 -0
- package/dist/audio/Underrun.js +18 -0
- package/dist/audio/Underrun.js.map +1 -0
- package/dist/audio/Wav.d.ts +56 -0
- package/dist/audio/Wav.d.ts.map +1 -0
- package/dist/audio/Wav.js +164 -0
- package/dist/audio/Wav.js.map +1 -0
- package/dist/audio/WebMidi.d.ts +58 -0
- package/dist/audio/WebMidi.d.ts.map +1 -0
- package/dist/audio/WebMidi.js +79 -0
- package/dist/audio/WebMidi.js.map +1 -0
- package/dist/audio/humanize/Onsets.d.ts.map +1 -1
- package/dist/audio/humanize/Onsets.js +1 -44
- package/dist/audio/humanize/Onsets.js.map +1 -1
- package/dist/audio/index.d.ts +43 -7
- package/dist/audio/index.d.ts.map +1 -1
- package/dist/audio/index.js +21 -3
- package/dist/audio/index.js.map +1 -1
- package/dist/battle/AttackPreview.d.ts.map +1 -1
- package/dist/battle/AttackPreview.js +8 -8
- package/dist/battle/AttackPreview.js.map +1 -1
- package/dist/battle/StatStages.d.ts.map +1 -1
- package/dist/battle/StatStages.js +2 -1
- package/dist/battle/StatStages.js.map +1 -1
- package/dist/board/Engine.d.ts +2 -0
- package/dist/board/Engine.d.ts.map +1 -1
- package/dist/board/Engine.js +1 -1
- package/dist/board/Engine.js.map +1 -1
- package/dist/board/HexSkirmish.d.ts.map +1 -1
- package/dist/board/HexSkirmish.js +11 -72
- package/dist/board/HexSkirmish.js.map +1 -1
- package/dist/board/Tactics.d.ts.map +1 -1
- package/dist/board/Tactics.js +3 -5
- package/dist/board/Tactics.js.map +1 -1
- package/dist/board/tourney.d.ts.map +1 -1
- package/dist/board/tourney.js +2 -19
- package/dist/board/tourney.js.map +1 -1
- package/dist/core/Handles.js +7 -7
- package/dist/core/Handles.js.map +1 -1
- package/dist/mw_games.global.js +25 -22
- package/dist/mwl/conditions.d.ts +12 -0
- package/dist/mwl/conditions.d.ts.map +1 -1
- package/dist/mwl/conditions.js +49 -8
- package/dist/mwl/conditions.js.map +1 -1
- package/dist/mwl/index.d.ts +13 -0
- package/dist/mwl/index.d.ts.map +1 -1
- package/dist/mwl/index.js +7 -0
- package/dist/mwl/index.js.map +1 -1
- package/dist/mwl/objects.d.ts +31 -0
- package/dist/mwl/objects.d.ts.map +1 -0
- package/dist/mwl/objects.js +83 -0
- package/dist/mwl/objects.js.map +1 -0
- package/dist/mwl/package-container.d.ts +185 -0
- package/dist/mwl/package-container.d.ts.map +1 -0
- package/dist/mwl/package-container.js +446 -0
- package/dist/mwl/package-container.js.map +1 -0
- package/dist/mwl/package-document.d.ts +217 -0
- package/dist/mwl/package-document.d.ts.map +1 -0
- package/dist/mwl/package-document.js +639 -0
- package/dist/mwl/package-document.js.map +1 -0
- package/dist/mwl/package-rom.d.ts +37 -0
- package/dist/mwl/package-rom.d.ts.map +1 -0
- package/dist/mwl/package-rom.js +96 -0
- package/dist/mwl/package-rom.js.map +1 -0
- package/dist/mwl/package-verify.d.ts +34 -0
- package/dist/mwl/package-verify.d.ts.map +1 -0
- package/dist/mwl/package-verify.js +111 -0
- package/dist/mwl/package-verify.js.map +1 -0
- package/dist/mwl/package.d.ts +184 -0
- package/dist/mwl/package.d.ts.map +1 -0
- package/dist/mwl/package.js +382 -0
- package/dist/mwl/package.js.map +1 -0
- package/dist/mwl/schema.d.ts +1 -1
- package/dist/mwl/schema.d.ts.map +1 -1
- package/dist/mwl/tables.d.ts +2 -0
- package/dist/mwl/tables.d.ts.map +1 -1
- package/dist/mwl/tables.js +13 -0
- package/dist/mwl/tables.js.map +1 -1
- package/dist/physics/PhysicsWorld.d.ts.map +1 -1
- package/dist/physics/PhysicsWorld.js +4 -3
- package/dist/physics/PhysicsWorld.js.map +1 -1
- package/dist/physics/XpbdWorld.d.ts +23 -5
- package/dist/physics/XpbdWorld.d.ts.map +1 -1
- package/dist/physics/XpbdWorld.js +91 -6
- package/dist/physics/XpbdWorld.js.map +1 -1
- package/dist/testing/FakeAudio.d.ts +149 -0
- package/dist/testing/FakeAudio.d.ts.map +1 -0
- package/dist/testing/FakeAudio.js +219 -0
- package/dist/testing/FakeAudio.js.map +1 -0
- package/dist/testing/index.d.ts +18 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +22 -0
- package/dist/testing/index.js.map +1 -1
- package/dist/threads/index.d.ts +2 -2
- package/dist/threads/index.d.ts.map +1 -1
- package/dist/threads/index.js +1 -1
- package/dist/threads/index.js.map +1 -1
- package/dist/threads/spawn.d.ts +32 -0
- package/dist/threads/spawn.d.ts.map +1 -1
- package/dist/threads/spawn.js +35 -11
- package/dist/threads/spawn.js.map +1 -1
- package/dist/three-d/Collision3D.d.ts +46 -2
- package/dist/three-d/Collision3D.d.ts.map +1 -1
- package/dist/three-d/Collision3D.js +46 -2
- package/dist/three-d/Collision3D.js.map +1 -1
- package/dist/three-d/Grid.d.ts +12 -1
- package/dist/three-d/Grid.d.ts.map +1 -1
- package/dist/three-d/Grid.js +12 -1
- package/dist/three-d/Grid.js.map +1 -1
- package/dist/three-d/Vox.d.ts +13 -1
- package/dist/three-d/Vox.d.ts.map +1 -1
- package/dist/three-d/Vox.js +13 -1
- package/dist/three-d/Vox.js.map +1 -1
- package/dist/two-d/Game.d.ts +32 -1
- package/dist/two-d/Game.d.ts.map +1 -1
- package/dist/two-d/Game.js +105 -14
- package/dist/two-d/Game.js.map +1 -1
- package/dist/two-d/Scene2D.d.ts +24 -0
- package/dist/two-d/Scene2D.d.ts.map +1 -1
- package/dist/two-d/Scene2D.js +30 -0
- package/dist/two-d/Scene2D.js.map +1 -1
- package/dist/two-d/render/HazeLayer.d.ts.map +1 -1
- package/dist/two-d/render/HazeLayer.js +2 -1
- package/dist/two-d/render/HazeLayer.js.map +1 -1
- package/dist/two-d/render/ImageModifiers.d.ts +4 -2
- package/dist/two-d/render/ImageModifiers.d.ts.map +1 -1
- package/dist/two-d/render/ImageModifiers.js +13 -8
- package/dist/two-d/render/ImageModifiers.js.map +1 -1
- package/dist/two-d/render/NeonGlow.d.ts.map +1 -1
- package/dist/two-d/render/NeonGlow.js +2 -1
- package/dist/two-d/render/NeonGlow.js.map +1 -1
- package/dist/two-d/render/Particles.d.ts.map +1 -1
- package/dist/two-d/render/Particles.js +2 -1
- package/dist/two-d/render/Particles.js.map +1 -1
- package/dist/two-d/render/SceneTransition.d.ts +301 -0
- package/dist/two-d/render/SceneTransition.d.ts.map +1 -0
- package/dist/two-d/render/SceneTransition.js +458 -0
- package/dist/two-d/render/SceneTransition.js.map +1 -0
- package/dist/two-d/render/ScreenEffects.d.ts.map +1 -1
- package/dist/two-d/render/ScreenEffects.js +2 -1
- package/dist/two-d/render/ScreenEffects.js.map +1 -1
- package/dist/two-d/render/SkeletalSprite.d.ts.map +1 -1
- package/dist/two-d/render/SkeletalSprite.js +2 -1
- package/dist/two-d/render/SkeletalSprite.js.map +1 -1
- package/dist/two-d/render/Types2D.d.ts +2 -2
- package/dist/two-d/render/Types2D.d.ts.map +1 -1
- package/dist/two-d/render/Types2D.js +2 -2
- package/dist/two-d/render/Types2D.js.map +1 -1
- package/dist/two-d/render/index.d.ts +2 -0
- package/dist/two-d/render/index.d.ts.map +1 -1
- package/dist/two-d/render/index.js +1 -0
- package/dist/two-d/render/index.js.map +1 -1
- package/dist/two-d/ui/Bar.d.ts.map +1 -1
- package/dist/two-d/ui/Bar.js +3 -5
- package/dist/two-d/ui/Bar.js.map +1 -1
- package/dist/two-d/ui/Button.d.ts +23 -0
- package/dist/two-d/ui/Button.d.ts.map +1 -1
- package/dist/two-d/ui/Button.js +37 -0
- package/dist/two-d/ui/Button.js.map +1 -1
- package/dist/two-d/ui/Dropdown.d.ts +5 -1
- package/dist/two-d/ui/Dropdown.d.ts.map +1 -1
- package/dist/two-d/ui/Dropdown.js +8 -1
- package/dist/two-d/ui/Dropdown.js.map +1 -1
- package/dist/two-d/ui/DropdownView.d.ts +63 -3
- package/dist/two-d/ui/DropdownView.d.ts.map +1 -1
- package/dist/two-d/ui/DropdownView.js +168 -9
- package/dist/two-d/ui/DropdownView.js.map +1 -1
- package/dist/two-d/ui/FloatingText.d.ts.map +1 -1
- package/dist/two-d/ui/FloatingText.js +2 -1
- package/dist/two-d/ui/FloatingText.js.map +1 -1
- package/dist/two-d/ui/IconGrid.d.ts.map +1 -1
- package/dist/two-d/ui/IconGrid.js +2 -1
- package/dist/two-d/ui/IconGrid.js.map +1 -1
- package/dist/two-d/ui/ListView.d.ts.map +1 -1
- package/dist/two-d/ui/ListView.js +2 -1
- package/dist/two-d/ui/ListView.js.map +1 -1
- package/dist/two-d/ui/ScrollBox.d.ts +96 -0
- package/dist/two-d/ui/ScrollBox.d.ts.map +1 -1
- package/dist/two-d/ui/ScrollBox.js +218 -5
- package/dist/two-d/ui/ScrollBox.js.map +1 -1
- package/dist/two-d/ui/ScrollText.d.ts +131 -0
- package/dist/two-d/ui/ScrollText.d.ts.map +1 -0
- package/dist/two-d/ui/ScrollText.js +218 -0
- package/dist/two-d/ui/ScrollText.js.map +1 -0
- package/dist/two-d/ui/Slider.d.ts.map +1 -1
- package/dist/two-d/ui/Slider.js +4 -4
- package/dist/two-d/ui/Slider.js.map +1 -1
- package/dist/two-d/ui/Tooltip.d.ts +70 -1
- package/dist/two-d/ui/Tooltip.d.ts.map +1 -1
- package/dist/two-d/ui/Tooltip.js +115 -3
- package/dist/two-d/ui/Tooltip.js.map +1 -1
- package/dist/two-d/ui/Window.d.ts +35 -2
- package/dist/two-d/ui/Window.d.ts.map +1 -1
- package/dist/two-d/ui/Window.js +58 -3
- package/dist/two-d/ui/Window.js.map +1 -1
- package/dist/two-d/ui/index.d.ts +7 -5
- package/dist/two-d/ui/index.d.ts.map +1 -1
- package/dist/two-d/ui/index.js +3 -2
- package/dist/two-d/ui/index.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +14 -3
- package/sbom.cdx.json +19 -260
- package/tools/audio.d.mts +75 -0
- package/tools/audio.mjs +437 -0
- package/tools/browser-driver.mjs +3 -3
- package/tools/browser-smoke.mjs +19 -2
- package/tools/build-tablebases.mjs +7 -3
- package/tools/compile-openings.mjs +7 -3
- package/tools/compile-resources.d.mts +2 -0
- package/tools/compile-resources.mjs +13 -1
- package/tools/emit-page.d.mts +6 -0
- package/tools/emit-page.mjs +43 -3
- package/tools/find-chrome.mjs +4 -2
- package/tools/init.mjs +11 -3
- package/tools/mwl.mjs +144 -2
- package/tools/play-uci.mjs +9 -5
- package/tools/vite.mjs +9 -1
- package/tools.md +2 -1
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
import { Signal } from '../core/Signal.js';
|
|
2
|
+
import { openWorker } from '../threads/spawn.js';
|
|
3
|
+
import { onAudioUnderrun } from './Underrun.js';
|
|
4
|
+
/**
|
|
5
|
+
* The part that touches the core: it holds the core, the events not yet due, and the frame it has
|
|
6
|
+
* rendered up to, and answers a render request with exactly that many frames, applying each event
|
|
7
|
+
* at its own frame inside the block. **Self-contained by construction**, like `workerMain`: the
|
|
8
|
+
* worker gets this function as text, so it may use nothing outside its own body. The inline
|
|
9
|
+
* fallback calls the very same function, which is why the two paths cannot disagree.
|
|
10
|
+
*/
|
|
11
|
+
function createCoreRunner(factorySource, sampleRate) {
|
|
12
|
+
const core = new Function(`return (${factorySource});`)()(sampleRate);
|
|
13
|
+
let position = 0;
|
|
14
|
+
let pending = [];
|
|
15
|
+
const now = () => (typeof performance === 'undefined' ? Date.now() : performance.now());
|
|
16
|
+
const apply = (event) => {
|
|
17
|
+
if (event.sysex)
|
|
18
|
+
core.sysex(event.sysex);
|
|
19
|
+
else
|
|
20
|
+
core.event(event.status, event.data1, event.data2);
|
|
21
|
+
};
|
|
22
|
+
return {
|
|
23
|
+
handle(message) {
|
|
24
|
+
if (message.type === 'events') {
|
|
25
|
+
pending = pending.concat(message.events).sort((a, b) => a.frame - b.frame);
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
if (message.type === 'reset') {
|
|
29
|
+
core.reset();
|
|
30
|
+
pending = [];
|
|
31
|
+
position = message.frame;
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
const frames = message.frames;
|
|
35
|
+
const left = new Float32Array(frames);
|
|
36
|
+
const right = new Float32Array(frames);
|
|
37
|
+
const began = now();
|
|
38
|
+
const start = position;
|
|
39
|
+
const end = start + frames;
|
|
40
|
+
let done = 0;
|
|
41
|
+
let used = 0;
|
|
42
|
+
//events already late are applied at the top of the block, in order
|
|
43
|
+
while (used < pending.length && pending[used].frame < end) {
|
|
44
|
+
const at = Math.max(0, pending[used].frame - start);
|
|
45
|
+
if (at > done) {
|
|
46
|
+
core.render(left, right, done, at - done);
|
|
47
|
+
done = at;
|
|
48
|
+
}
|
|
49
|
+
apply(pending[used++]);
|
|
50
|
+
}
|
|
51
|
+
pending = pending.slice(used);
|
|
52
|
+
if (done < frames)
|
|
53
|
+
core.render(left, right, done, frames - done);
|
|
54
|
+
position = end;
|
|
55
|
+
return { type: 'block', start, left, right, renderMs: now() - began };
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The worker half: builds the runner when told to, then answers each message. Self-contained for
|
|
61
|
+
* the same reason as `createCoreRunner`, which is passed in because a stringified function cannot
|
|
62
|
+
* reach its sibling. The same body runs under a browser worker and under Node's `worker_threads`.
|
|
63
|
+
*/
|
|
64
|
+
function coreWorkerMain(buildRunner) {
|
|
65
|
+
const nodePort = globalThis.process?.getBuiltinModule?.('node:worker_threads')?.parentPort ?? null;
|
|
66
|
+
const scope = globalThis;
|
|
67
|
+
const send = (message, transfer = []) => {
|
|
68
|
+
if (nodePort)
|
|
69
|
+
nodePort.postMessage(message, transfer);
|
|
70
|
+
else
|
|
71
|
+
scope.postMessage(message, transfer);
|
|
72
|
+
};
|
|
73
|
+
let runner = null;
|
|
74
|
+
const onMessage = (message) => {
|
|
75
|
+
try {
|
|
76
|
+
if (message.type === 'init') {
|
|
77
|
+
runner = buildRunner(message.factory, message.sampleRate);
|
|
78
|
+
send({ type: 'ready' });
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const block = runner?.handle(message);
|
|
82
|
+
if (block)
|
|
83
|
+
send(block, [block.left.buffer, block.right.buffer]);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
send({ type: 'error', message: String(error?.message ?? error) });
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
if (nodePort)
|
|
90
|
+
nodePort.on('message', (message) => onMessage(message));
|
|
91
|
+
else
|
|
92
|
+
scope.onmessage = (event) => onMessage(event.data);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Runs a synthesis core on a worker and presents it as an endless `BlockSource`, so a
|
|
96
|
+
* `StreamChannel` plays it like any stream while the render cost stays off the frame. Messages go
|
|
97
|
+
* to the core stamped with an output frame and are applied at that frame; blocks come back
|
|
98
|
+
* transferred, not copied, and wait in a short queue that `read` drains. When the queue runs dry
|
|
99
|
+
* the missing frames are silence, the playhead moves on, and the underrun is counted and reported
|
|
100
|
+
* (`onUnderrun`, `onAudioUnderrun`), so timing never drifts. Where no worker exists, or one dies,
|
|
101
|
+
* the same runner runs on the main thread instead: slower for the frame, identical in sound.
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```ts
|
|
105
|
+
* import { AudioCoreHost, StreamChannel, type AudioCore } from '@datamoc/mw_games/audio';
|
|
106
|
+
*
|
|
107
|
+
* declare const context: AudioContext;
|
|
108
|
+
*
|
|
109
|
+
* const host = new AudioCoreHost({
|
|
110
|
+
* sampleRate: 44100,
|
|
111
|
+
* factory: (rate): AudioCore => ({
|
|
112
|
+
* sampleRate: rate,
|
|
113
|
+
* event() {},
|
|
114
|
+
* sysex() {},
|
|
115
|
+
* render() {},
|
|
116
|
+
* reset() {},
|
|
117
|
+
* }),
|
|
118
|
+
* });
|
|
119
|
+
* new StreamChannel(context).play(host);
|
|
120
|
+
* host.event(0x90, 60, 100);
|
|
121
|
+
* console.log(host.stats().mode);
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
export class AudioCoreHost {
|
|
125
|
+
constructor(options) {
|
|
126
|
+
/** fires when a read found the queue short, with the seconds of silence it had to put in */
|
|
127
|
+
this.onUnderrun = new Signal();
|
|
128
|
+
this.link = null;
|
|
129
|
+
this.runner = null;
|
|
130
|
+
this.mode_ = 'inline';
|
|
131
|
+
//no underrun is reported before the first block has arrived: that wait is start-up latency, not a dropout
|
|
132
|
+
this.warm = false;
|
|
133
|
+
/** why the core could not be built on this thread, when it could not */
|
|
134
|
+
this.failure = null;
|
|
135
|
+
this.disposed = false;
|
|
136
|
+
this.readFrame = 0;
|
|
137
|
+
this.requestedUntil = 0;
|
|
138
|
+
this.blocks = [];
|
|
139
|
+
this.underruns = 0;
|
|
140
|
+
this.load = 0;
|
|
141
|
+
if (!(options.sampleRate > 0))
|
|
142
|
+
throw new Error('core host sample rate must be positive');
|
|
143
|
+
this.sampleRate = options.sampleRate;
|
|
144
|
+
this.factorySource = options.factory.toString();
|
|
145
|
+
this.blockFrames = Math.max(64, Math.floor(options.blockFrames ?? 1024));
|
|
146
|
+
this.queueFrames = Math.max(this.blockFrames, Math.floor((options.queueSeconds ?? 0.3) * options.sampleRate));
|
|
147
|
+
this.requested = options.mode ?? 'auto';
|
|
148
|
+
if (this.requested !== 'inline')
|
|
149
|
+
this.openWorker();
|
|
150
|
+
if (!this.link) {
|
|
151
|
+
if (this.requested === 'worker')
|
|
152
|
+
throw new Error(`the core host needs a worker: ${this.fallbackReason}`);
|
|
153
|
+
this.goInline(this.fallbackReason ?? 'inline mode was requested');
|
|
154
|
+
//the first failure of a core that cannot be built at all belongs to the caller
|
|
155
|
+
if (!this.runner && this.failure)
|
|
156
|
+
throw this.failure;
|
|
157
|
+
}
|
|
158
|
+
this.pump(0);
|
|
159
|
+
}
|
|
160
|
+
/** `'worker'` while the core runs off the main thread, `'inline'` otherwise */
|
|
161
|
+
get mode() {
|
|
162
|
+
return this.mode_;
|
|
163
|
+
}
|
|
164
|
+
stats() {
|
|
165
|
+
return {
|
|
166
|
+
mode: this.mode_,
|
|
167
|
+
...(this.fallbackReason ? { fallbackReason: this.fallbackReason } : {}),
|
|
168
|
+
underruns: this.underruns,
|
|
169
|
+
queuedFrames: this.blocks.reduce((total, block) => total + block.left.length, 0),
|
|
170
|
+
load: this.load,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
/** sends a channel message; applied at `atFrame`, or at the start of the next block to be rendered when omitted */
|
|
174
|
+
event(status, data1, data2, atFrame) {
|
|
175
|
+
this.send({ frame: atFrame ?? this.requestedUntil, status, data1, data2 });
|
|
176
|
+
}
|
|
177
|
+
sysex(bytes, atFrame) {
|
|
178
|
+
this.send({ frame: atFrame ?? this.requestedUntil, status: 0xf0, data1: 0, data2: 0, sysex: bytes });
|
|
179
|
+
}
|
|
180
|
+
/** silences the core and discards everything rendered ahead of the playhead */
|
|
181
|
+
reset() {
|
|
182
|
+
this.blocks = [];
|
|
183
|
+
this.requestedUntil = this.readFrame;
|
|
184
|
+
this.post({ type: 'reset', frame: this.readFrame });
|
|
185
|
+
this.pump(0);
|
|
186
|
+
}
|
|
187
|
+
/** moves the playhead; a different frame resets the core, the same frame leaves it playing */
|
|
188
|
+
seek(frame) {
|
|
189
|
+
const target = Math.max(0, Math.floor(frame));
|
|
190
|
+
if (target === this.readFrame)
|
|
191
|
+
return;
|
|
192
|
+
this.readFrame = target;
|
|
193
|
+
this.reset();
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Asks the runner for whatever the queue is missing; called by every read and safe to call
|
|
197
|
+
* from a timer. A worker keeps `queueSeconds` rendered ahead of the playhead, hiding its
|
|
198
|
+
* latency from the game; the inline fallback renders just in time instead, since a queue on the
|
|
199
|
+
* thread that pays for it only moves the cost, and a message then lands on exactly its frame.
|
|
200
|
+
*/
|
|
201
|
+
pump(needed = 0) {
|
|
202
|
+
if (this.disposed)
|
|
203
|
+
return;
|
|
204
|
+
const lead = this.mode_ === 'worker' ? Math.max(this.queueFrames, needed) : needed;
|
|
205
|
+
const queuedUntil = this.readFrame + lead;
|
|
206
|
+
while (this.requestedUntil < queuedUntil) {
|
|
207
|
+
this.requestedUntil += this.blockFrames;
|
|
208
|
+
this.post({ type: 'render', frames: this.blockFrames });
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/** an endless source: fills `count` frames, with silence where the core was late, and always returns `count` */
|
|
212
|
+
read(left, right, start, count) {
|
|
213
|
+
this.pump(count);
|
|
214
|
+
const wantedFrom = this.readFrame;
|
|
215
|
+
const wantedTo = wantedFrom + count;
|
|
216
|
+
let filled = 0;
|
|
217
|
+
this.blocks = this.blocks.filter((block) => block.start + block.left.length > wantedFrom);
|
|
218
|
+
for (const block of this.blocks) {
|
|
219
|
+
const from = Math.max(block.start, wantedFrom + filled);
|
|
220
|
+
if (from >= wantedTo)
|
|
221
|
+
break;
|
|
222
|
+
if (from > wantedFrom + filled)
|
|
223
|
+
break;
|
|
224
|
+
const offset = from - block.start;
|
|
225
|
+
const take = Math.min(block.left.length - offset, wantedTo - from);
|
|
226
|
+
left.set(block.left.subarray(offset, offset + take), start + filled);
|
|
227
|
+
right.set(block.right.subarray(offset, offset + take), start + filled);
|
|
228
|
+
filled += take;
|
|
229
|
+
}
|
|
230
|
+
if (filled < count) {
|
|
231
|
+
left.fill(0, start + filled, start + count);
|
|
232
|
+
right.fill(0, start + filled, start + count);
|
|
233
|
+
if (this.warm) {
|
|
234
|
+
this.underruns++;
|
|
235
|
+
const lateSeconds = (count - filled) / this.sampleRate;
|
|
236
|
+
this.onUnderrun.dispatch(lateSeconds);
|
|
237
|
+
onAudioUnderrun.dispatch({ source: 'core', lateSeconds });
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
this.readFrame = wantedTo;
|
|
241
|
+
this.pump(0);
|
|
242
|
+
return count;
|
|
243
|
+
}
|
|
244
|
+
/** stops the worker and drops what is queued; the host cannot be used afterwards */
|
|
245
|
+
dispose() {
|
|
246
|
+
this.disposed = true;
|
|
247
|
+
this.link?.terminate();
|
|
248
|
+
this.link = null;
|
|
249
|
+
this.blocks = [];
|
|
250
|
+
}
|
|
251
|
+
openWorker() {
|
|
252
|
+
const source = `const createCoreRunner = ${createCoreRunner.toString()};` +
|
|
253
|
+
`(${coreWorkerMain.toString()})(createCoreRunner);`;
|
|
254
|
+
try {
|
|
255
|
+
this.link = openWorker(source, {
|
|
256
|
+
message: (data) => this.onWorkerMessage(data),
|
|
257
|
+
fail: (error) => {
|
|
258
|
+
if (this.disposed)
|
|
259
|
+
return;
|
|
260
|
+
this.link?.terminate();
|
|
261
|
+
this.link = null;
|
|
262
|
+
this.goInline(error.message);
|
|
263
|
+
},
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
catch (error) {
|
|
267
|
+
this.link = null;
|
|
268
|
+
this.fallbackReason = error instanceof Error ? error.message : String(error);
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
if (!this.link) {
|
|
272
|
+
this.fallbackReason = 'no Web Worker or worker_threads here';
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
this.mode_ = 'worker';
|
|
276
|
+
this.link.post({ type: 'init', factory: this.factorySource, sampleRate: this.sampleRate });
|
|
277
|
+
}
|
|
278
|
+
goInline(reason) {
|
|
279
|
+
this.mode_ = 'inline';
|
|
280
|
+
this.fallbackReason = reason;
|
|
281
|
+
try {
|
|
282
|
+
this.runner = createCoreRunner(this.factorySource, this.sampleRate);
|
|
283
|
+
}
|
|
284
|
+
catch (error) {
|
|
285
|
+
//a core that fails to build anywhere leaves the host silent rather than throwing from a worker callback
|
|
286
|
+
this.runner = null;
|
|
287
|
+
this.failure = error instanceof Error ? error : new Error(String(error));
|
|
288
|
+
this.fallbackReason = `${reason}; the core also failed here: ${this.failure.message}`;
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
//whatever the dead worker had not delivered is rendered again, from the playhead
|
|
292
|
+
this.blocks = [];
|
|
293
|
+
this.runner.handle({ type: 'reset', frame: this.readFrame });
|
|
294
|
+
this.requestedUntil = this.readFrame;
|
|
295
|
+
}
|
|
296
|
+
onWorkerMessage(message) {
|
|
297
|
+
if (message.type === 'ready')
|
|
298
|
+
return;
|
|
299
|
+
if (message.type === 'error') {
|
|
300
|
+
this.link?.terminate();
|
|
301
|
+
this.link = null;
|
|
302
|
+
this.goInline(String(message.message));
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
if (message.type === 'block') {
|
|
306
|
+
const block = message;
|
|
307
|
+
this.noteLoad(block);
|
|
308
|
+
this.blocks.push(block);
|
|
309
|
+
this.warm = true;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
noteLoad(block) {
|
|
313
|
+
const audioMs = (block.left.length / this.sampleRate) * 1000;
|
|
314
|
+
const ratio = block.renderMs / audioMs;
|
|
315
|
+
this.load = this.load === 0 ? ratio : this.load * 0.9 + ratio * 0.1;
|
|
316
|
+
}
|
|
317
|
+
send(event) {
|
|
318
|
+
this.post({ type: 'events', events: [event] });
|
|
319
|
+
}
|
|
320
|
+
post(message) {
|
|
321
|
+
if (this.disposed)
|
|
322
|
+
return;
|
|
323
|
+
if (this.mode_ === 'worker' && this.link) {
|
|
324
|
+
this.link.post(message, []);
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
const block = this.runner?.handle(message);
|
|
328
|
+
if (block) {
|
|
329
|
+
this.noteLoad(block);
|
|
330
|
+
this.blocks.push(block);
|
|
331
|
+
this.warm = true;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
//# sourceMappingURL=CoreHost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CoreHost.js","sourceRoot":"","sources":["../../src/audio/CoreHost.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import type { BlockSource } from './StreamChannel.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Guards for decoders of formats that carry machine code or compressed payloads (NSF, SID, SPC,
|
|
4
|
+
* a tracker with a packed sample bank, an LHA or DEFLATE archive): all of them are untrusted
|
|
5
|
+
* input, and "it ran a long time" or "it grew enormous" is a failure the format itself cannot
|
|
6
|
+
* be asked to prevent. Every limit is named, defaulted and raised by the caller, and every
|
|
7
|
+
* breach is one `DecodeBudgetError` that says which limit and why, never a hang or a crash.
|
|
8
|
+
*/
|
|
9
|
+
export interface DecoderLimits {
|
|
10
|
+
/** refuse input larger than this many bytes; 16 MiB */
|
|
11
|
+
maxInputBytes: number;
|
|
12
|
+
/** refuse to inflate past this many bytes of output, the bound on a zip bomb; 64 MiB */
|
|
13
|
+
maxOutputBytes: number;
|
|
14
|
+
/** emulated instructions allowed per second of sound produced; 4 million */
|
|
15
|
+
maxInstructionsPerSecond: number;
|
|
16
|
+
/** stop a stream after this many seconds of output, whatever the file says; 3600 */
|
|
17
|
+
maxSeconds: number;
|
|
18
|
+
/** a read that takes longer than this multiple of the audio it produced counts as starved; 1 */
|
|
19
|
+
maxRealtimeRatio: number;
|
|
20
|
+
/** consecutive starved reads before the stream is cut; 8 */
|
|
21
|
+
maxStarvedReads: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The decoder limits every guard starts from, before a caller raises or lowers one.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* import { DEFAULT_DECODER_LIMITS } from '@datamoc/mw_games/audio';
|
|
29
|
+
*
|
|
30
|
+
* console.log(DEFAULT_DECODER_LIMITS.maxInputBytes); // 16777216
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare const DEFAULT_DECODER_LIMITS: Readonly<DecoderLimits>;
|
|
34
|
+
/** which limit a `DecodeBudgetError` is about */
|
|
35
|
+
export type DecoderLimitName = keyof DecoderLimits;
|
|
36
|
+
/**
|
|
37
|
+
* A decoder went past a limit; carries the limit's name so a game can say what to raise or
|
|
38
|
+
* what to refuse.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* import { DecodeBudgetError } from '@datamoc/mw_games/audio';
|
|
43
|
+
*
|
|
44
|
+
* const error = new DecodeBudgetError('maxInputBytes', 'tune.nsf is larger than the limit');
|
|
45
|
+
* console.log(error.limit); // 'maxInputBytes'
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export declare class DecodeBudgetError extends Error {
|
|
49
|
+
readonly limit: DecoderLimitName;
|
|
50
|
+
constructor(limit: DecoderLimitName, message: string);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Merges a partial override over the defaults and rejects values that cannot be limits.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* import { decoderLimits } from '@datamoc/mw_games/audio';
|
|
58
|
+
*
|
|
59
|
+
* console.log(decoderLimits({ maxSeconds: 600 }).maxSeconds); // 600
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export declare function decoderLimits(overrides?: Partial<DecoderLimits>): DecoderLimits;
|
|
63
|
+
/**
|
|
64
|
+
* Throws when input is bigger than `maxInputBytes`, before a decoder has touched it.
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```ts
|
|
68
|
+
* import { assertInputSize } from '@datamoc/mw_games/audio';
|
|
69
|
+
*
|
|
70
|
+
* declare const bytes: Uint8Array;
|
|
71
|
+
*
|
|
72
|
+
* assertInputSize(bytes, { maxInputBytes: 1_000_000 }, 'tune.nsf');
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
export declare function assertInputSize(input: {
|
|
76
|
+
byteLength: number;
|
|
77
|
+
}, limits?: Partial<DecoderLimits>, label?: string): void;
|
|
78
|
+
/**
|
|
79
|
+
* A count of emulated instructions an emulator spends as it runs. The emulator calls `spend`
|
|
80
|
+
* from its dispatch loop (once per instruction, or once per batch); past the allowance it
|
|
81
|
+
* throws, so a tune that loops forever without producing sound ends the render instead of
|
|
82
|
+
* hanging it.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* import { InstructionBudget } from '@datamoc/mw_games/audio';
|
|
87
|
+
*
|
|
88
|
+
* const budget = InstructionBudget.forSeconds(30);
|
|
89
|
+
* function runFrame(cycles: number): void {
|
|
90
|
+
* budget.spend(cycles);
|
|
91
|
+
* }
|
|
92
|
+
* runFrame(20000);
|
|
93
|
+
* console.log(budget.remaining);
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export declare class InstructionBudget {
|
|
97
|
+
private left;
|
|
98
|
+
constructor(allowance: number);
|
|
99
|
+
/** the allowance for rendering this many seconds of sound under the limits' per-second rate */
|
|
100
|
+
static forSeconds(seconds: number, limits?: Partial<DecoderLimits>): InstructionBudget;
|
|
101
|
+
get remaining(): number;
|
|
102
|
+
spend(count?: number): void;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Inflates a raw DEFLATE stream while counting the output, so a few kilobytes that expand into
|
|
106
|
+
* gigabytes are refused after `maxOutputBytes`, not after they have filled memory.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```ts
|
|
110
|
+
* import { inflateBounded } from '@datamoc/mw_games/audio';
|
|
111
|
+
*
|
|
112
|
+
* declare const packed: Uint8Array;
|
|
113
|
+
*
|
|
114
|
+
* const bytes = await inflateBounded(packed, { maxOutputBytes: 1_000_000 });
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
export declare function inflateBounded(packed: Uint8Array, limits?: Partial<DecoderLimits>, format?: 'deflate-raw' | 'deflate' | 'gzip'): Promise<Uint8Array>;
|
|
118
|
+
export interface GuardOptions {
|
|
119
|
+
/** replaces `performance.now` so a test controls the clock */
|
|
120
|
+
now?: () => number;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Wraps a `BlockSource` so a misbehaving decoder cannot hurt the game: a read that claims more
|
|
124
|
+
* frames than it was given room for is an error, non-finite or wildly loud samples are zeroed
|
|
125
|
+
* or clamped, the stream ends at `maxSeconds` whatever the file says, and a source that keeps
|
|
126
|
+
* taking longer to produce audio than the audio lasts is cut after `maxStarvedReads` in a row
|
|
127
|
+
* rather than being allowed to starve the page.
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```ts
|
|
131
|
+
* import { guardBlockSource, type BlockSource } from '@datamoc/mw_games/audio';
|
|
132
|
+
*
|
|
133
|
+
* declare const untrusted: BlockSource;
|
|
134
|
+
*
|
|
135
|
+
* const safe = guardBlockSource(untrusted, { maxSeconds: 600 });
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
export declare function guardBlockSource(source: BlockSource, overrides?: Partial<DecoderLimits>, options?: GuardOptions): BlockSource;
|
|
139
|
+
//# sourceMappingURL=DecoderGuard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DecoderGuard.d.ts","sourceRoot":"","sources":["../../src/audio/DecoderGuard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC7B,uDAAuD;IACvD,aAAa,EAAE,MAAM,CAAC;IACtB,wFAAwF;IACxF,cAAc,EAAE,MAAM,CAAC;IACvB,4EAA4E;IAC5E,wBAAwB,EAAE,MAAM,CAAC;IACjC,oFAAoF;IACpF,UAAU,EAAE,MAAM,CAAC;IACnB,gGAAgG;IAChG,gBAAgB,EAAE,MAAM,CAAC;IACzB,4DAA4D;IAC5D,eAAe,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAAC,aAAa,CAOzD,CAAC;AAEH,iDAAiD;AACjD,MAAM,MAAM,gBAAgB,GAAG,MAAM,aAAa,CAAC;AAEnD;;;;;;;;;;;GAWG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;IAEjC,YAAY,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,EAInD;CACD;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,SAAS,GAAE,OAAO,CAAC,aAAa,CAAM,GAAG,aAAa,CAMnF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC9B,KAAK,EAAE;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,EAC7B,MAAM,GAAE,OAAO,CAAC,aAAa,CAAM,EACnC,KAAK,SAAU,GACb,IAAI,CAQN;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,iBAAiB;IAC7B,OAAO,CAAC,IAAI,CAAS;IAErB,YAAY,SAAS,EAAE,MAAM,EAG5B;IAED,+FAA+F;IAC/F,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,CAAC,aAAa,CAAM,GAAG,iBAAiB,CAGzF;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,KAAK,CAAC,KAAK,SAAI,GAAG,IAAI,CAQrB;CACD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,cAAc,CACnC,MAAM,EAAE,UAAU,EAClB,MAAM,GAAE,OAAO,CAAC,aAAa,CAAM,EACnC,MAAM,GAAE,aAAa,GAAG,SAAS,GAAG,MAAsB,GACxD,OAAO,CAAC,UAAU,CAAC,CAuBrB;AAED,MAAM,WAAW,YAAY;IAC5B,8DAA8D;IAC9D,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAC/B,MAAM,EAAE,WAAW,EACnB,SAAS,GAAE,OAAO,CAAC,aAAa,CAAM,EACtC,OAAO,GAAE,YAAiB,GACxB,WAAW,CA6Cb"}
|