omnivad 0.2.9 → 0.2.10
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 +13 -3
- package/dist/index.cjs +64 -77
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -8
- package/dist/index.d.ts +18 -8
- package/dist/index.js +64 -77
- package/dist/index.js.map +1 -1
- package/dist/wasm/omnivad.cjs +1 -1
- package/dist/wasm/omnivad.js +1 -1
- package/dist/wasm/omnivad.wasm +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -44,21 +44,31 @@ const result = vad.detect(audioFloat32);
|
|
|
44
44
|
|
|
45
45
|
## Streaming VAD — real-time, frame-by-frame
|
|
46
46
|
|
|
47
|
-
`OmniStreamVAD` processes 10 ms frames (160
|
|
47
|
+
`OmniStreamVAD` processes 10 ms frames (160 samples @ 16 kHz) and emits
|
|
48
48
|
segment-boundary events on the same call that confirms the boundary —
|
|
49
49
|
bit-identical to upstream FireRedVAD's `FireRedStreamVad`.
|
|
50
50
|
|
|
51
|
+
`processFrame()` accepts `Float32Array` in `[-1, 1]` (Web Audio,
|
|
52
|
+
`AudioWorkletProcessor`, decoded WebRTC tracks) or `Int16Array` PCM
|
|
53
|
+
(WAV / microphone). Dispatch is by dtype — no scaling in JS.
|
|
54
|
+
|
|
51
55
|
```ts
|
|
52
56
|
import { OmniStreamVAD } from "omnivad";
|
|
53
57
|
|
|
54
58
|
const vad = await OmniStreamVAD.create();
|
|
55
59
|
|
|
56
|
-
|
|
57
|
-
|
|
60
|
+
// Float32Array [-1, 1] from Web Audio:
|
|
61
|
+
for (let i = 0; i + 160 <= floatPcm.length; i += 160) {
|
|
62
|
+
const r = vad.processFrame(floatPcm.subarray(i, i + 160));
|
|
58
63
|
if (!r) continue;
|
|
59
64
|
if (r.isSpeechStart) console.log(`START @ ${(r.speechStartFrame * 0.01).toFixed(2)}s`);
|
|
60
65
|
if (r.isSpeechEnd) console.log(`END @ ${(r.speechEndFrame * 0.01).toFixed(2)}s`);
|
|
61
66
|
}
|
|
67
|
+
|
|
68
|
+
// Or Int16Array PCM from a WAV file — same call, same result:
|
|
69
|
+
for (let i = 0; i + 160 <= int16Pcm.length; i += 160) {
|
|
70
|
+
vad.processFrame(int16Pcm.subarray(i, i + 160));
|
|
71
|
+
}
|
|
62
72
|
```
|
|
63
73
|
|
|
64
74
|
`processFrame()` returns `{ confidence, smoothedProb, isSpeech, isSpeechStart,
|
package/dist/index.cjs
CHANGED
|
@@ -38,7 +38,7 @@ var SIZEOF_AED_SEGMENT = 16;
|
|
|
38
38
|
var SIZEOF_CHUNK_CONFIG = 28;
|
|
39
39
|
var SIZEOF_CHUNK = 16;
|
|
40
40
|
var OMNI_ERR_NO_FRAMES = -7;
|
|
41
|
-
var VERSION = "0.2.
|
|
41
|
+
var VERSION = "0.2.10";
|
|
42
42
|
var DEFAULT_CDN_BASE = `https://cdn.jsdelivr.net/npm/omnivad@${VERSION}/models`;
|
|
43
43
|
var MODEL_FILES = {
|
|
44
44
|
vad: "vad.omnivad",
|
|
@@ -163,6 +163,23 @@ function copyAudioToHeap(M, audio) {
|
|
|
163
163
|
heap.set(audio);
|
|
164
164
|
return ptr;
|
|
165
165
|
}
|
|
166
|
+
function copyInt16ToHeap(M, audio) {
|
|
167
|
+
const ptr = M._malloc(audio.length * 2);
|
|
168
|
+
const heap = new Int16Array(M.HEAPU8.buffer, ptr, audio.length);
|
|
169
|
+
heap.set(audio);
|
|
170
|
+
return ptr;
|
|
171
|
+
}
|
|
172
|
+
function dispatchAudio(M, audio) {
|
|
173
|
+
if (audio instanceof Float32Array) {
|
|
174
|
+
return { ptr: copyAudioToHeap(M, audio), length: audio.length, format: "f32" };
|
|
175
|
+
}
|
|
176
|
+
if (audio instanceof Int16Array) {
|
|
177
|
+
return { ptr: copyInt16ToHeap(M, audio), length: audio.length, format: "int16" };
|
|
178
|
+
}
|
|
179
|
+
throw new TypeError(
|
|
180
|
+
`unsupported audio dtype; expected Float32Array in [-1, 1] or Int16Array`
|
|
181
|
+
);
|
|
182
|
+
}
|
|
166
183
|
function writePostConfig(M, ptr, cfg) {
|
|
167
184
|
M.setValue(ptr + 0, cfg.threshold, "float");
|
|
168
185
|
M.setValue(ptr + 4, cfg.smoothWindowSize, "i32");
|
|
@@ -402,14 +419,15 @@ function streamVadCreate(M, modelBuffer, config = {}) {
|
|
|
402
419
|
}
|
|
403
420
|
}
|
|
404
421
|
var SIZEOF_STREAM_VAD_RESULT = 24;
|
|
405
|
-
function streamVadProcess(M, handle,
|
|
422
|
+
function streamVadProcess(M, handle, audioPtr, numSamples, format = "f32") {
|
|
406
423
|
const resultPtr = M._malloc(SIZEOF_STREAM_VAD_RESULT);
|
|
424
|
+
const fn = format === "int16" ? "omni_stream_vad_process_int16" : "omni_stream_vad_process";
|
|
407
425
|
try {
|
|
408
426
|
const ret = M.ccall(
|
|
409
|
-
|
|
427
|
+
fn,
|
|
410
428
|
"number",
|
|
411
429
|
["number", "number", "number", "number"],
|
|
412
|
-
[handle,
|
|
430
|
+
[handle, audioPtr, numSamples, resultPtr]
|
|
413
431
|
);
|
|
414
432
|
if (ret === OMNI_ERR_NO_FRAMES) return null;
|
|
415
433
|
if (ret !== 0) throw new Error(`StreamVAD process failed: ${ret}`);
|
|
@@ -427,6 +445,28 @@ function streamVadProcess(M, handle, pcm16Ptr, numSamples) {
|
|
|
427
445
|
M._free(resultPtr);
|
|
428
446
|
}
|
|
429
447
|
}
|
|
448
|
+
function streamVadDetectFull(M, handle, audioPtr, numSamples, format = "f32") {
|
|
449
|
+
const probsPtrPtr = M._malloc(4);
|
|
450
|
+
const framesPtr = M._malloc(4);
|
|
451
|
+
const fn = format === "int16" ? "omni_stream_vad_detect_full_int16" : "omni_stream_vad_detect_full";
|
|
452
|
+
try {
|
|
453
|
+
const ret = M.ccall(
|
|
454
|
+
fn,
|
|
455
|
+
"number",
|
|
456
|
+
["number", "number", "number", "number", "number"],
|
|
457
|
+
[handle, audioPtr, numSamples, probsPtrPtr, framesPtr]
|
|
458
|
+
);
|
|
459
|
+
if (ret !== 0) throw new Error(`StreamVAD detectFull failed: ${ret}`);
|
|
460
|
+
const numFrames = M.getValue(framesPtr, "i32");
|
|
461
|
+
const probsPtr = M.getValue(probsPtrPtr, "i32");
|
|
462
|
+
const probabilities = probsPtr ? new Float32Array(new Float32Array(M.HEAPU8.buffer, probsPtr, numFrames)) : new Float32Array(0);
|
|
463
|
+
if (probsPtr) M._free(probsPtr);
|
|
464
|
+
return { probabilities, numFrames };
|
|
465
|
+
} finally {
|
|
466
|
+
M._free(probsPtrPtr);
|
|
467
|
+
M._free(framesPtr);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
430
470
|
function streamVadClone(M, handle) {
|
|
431
471
|
const errPtr = M._malloc(4);
|
|
432
472
|
try {
|
|
@@ -486,7 +526,7 @@ var OmniVAD = class _OmniVAD {
|
|
|
486
526
|
*/
|
|
487
527
|
detect(audio) {
|
|
488
528
|
const M = getModule();
|
|
489
|
-
const { ptr, length, format } =
|
|
529
|
+
const { ptr, length, format } = dispatchAudio(M, audio);
|
|
490
530
|
try {
|
|
491
531
|
const timestamps = vadDetect(M, this.handle, ptr, length, this.config, format);
|
|
492
532
|
return {
|
|
@@ -505,16 +545,6 @@ var OmniVAD = class _OmniVAD {
|
|
|
505
545
|
}
|
|
506
546
|
}
|
|
507
547
|
};
|
|
508
|
-
function prepareAudio(M, audio) {
|
|
509
|
-
const f32 = audio instanceof Int16Array ? int16ToNormalizedFloat32(audio) : audio;
|
|
510
|
-
const ptr = copyAudioToHeap(M, f32);
|
|
511
|
-
return { ptr, length: f32.length, format: "f32" };
|
|
512
|
-
}
|
|
513
|
-
function int16ToNormalizedFloat32(i16) {
|
|
514
|
-
const f32 = new Float32Array(i16.length);
|
|
515
|
-
for (let i = 0; i < i16.length; i++) f32[i] = i16[i] / 32768;
|
|
516
|
-
return f32;
|
|
517
|
-
}
|
|
518
548
|
|
|
519
549
|
// src/stream-vad.ts
|
|
520
550
|
var SAMPLE_RATE2 = 16e3;
|
|
@@ -553,20 +583,23 @@ var OmniStreamVAD = class _OmniStreamVAD {
|
|
|
553
583
|
return new _OmniStreamVAD(newHandle);
|
|
554
584
|
}
|
|
555
585
|
/**
|
|
556
|
-
* Process one frame of audio (160
|
|
586
|
+
* Process one frame of audio (160 samples = 10ms @ 16kHz).
|
|
587
|
+
*
|
|
588
|
+
* Accepts Float32Array in [-1, 1] (Web Audio, soundfile, torch) or
|
|
589
|
+
* Int16Array PCM (WAV, microphone). Dispatches by dtype to the matching
|
|
590
|
+
* C entry — no scaling in JS.
|
|
591
|
+
*
|
|
557
592
|
* Returns null until enough audio is accumulated.
|
|
558
593
|
*
|
|
559
594
|
* Segment-boundary events (isSpeechStart / isSpeechEnd and the matching
|
|
560
595
|
* speech_*_frame indices) come straight from the C-layer state machine
|
|
561
596
|
* (bit-identical to upstream FireRedVAD) — the wrapper is just a marshaller.
|
|
562
597
|
*/
|
|
563
|
-
processFrame(
|
|
598
|
+
processFrame(audio) {
|
|
564
599
|
const M = getModule();
|
|
565
|
-
const ptr = M
|
|
566
|
-
const heap16 = new Int16Array(M.HEAPU8.buffer, ptr, pcm160.length);
|
|
567
|
-
heap16.set(pcm160);
|
|
600
|
+
const { ptr, length, format } = dispatchAudio(M, audio);
|
|
568
601
|
try {
|
|
569
|
-
const result = streamVadProcess(M, this.handle, ptr,
|
|
602
|
+
const result = streamVadProcess(M, this.handle, ptr, length, format);
|
|
570
603
|
if (!result) return null;
|
|
571
604
|
return {
|
|
572
605
|
confidence: result.confidence,
|
|
@@ -588,31 +621,22 @@ var OmniStreamVAD = class _OmniStreamVAD {
|
|
|
588
621
|
*/
|
|
589
622
|
detectFull(audio) {
|
|
590
623
|
const M = getModule();
|
|
591
|
-
const
|
|
592
|
-
const audioPtr = copyAudioToHeap(M, f32);
|
|
593
|
-
const probsPtrPtr = M._malloc(4);
|
|
594
|
-
const framesPtr = M._malloc(4);
|
|
624
|
+
const { ptr, length, format } = dispatchAudio(M, audio);
|
|
595
625
|
try {
|
|
596
|
-
const
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
626
|
+
const { probabilities, numFrames } = streamVadDetectFull(
|
|
627
|
+
M,
|
|
628
|
+
this.handle,
|
|
629
|
+
ptr,
|
|
630
|
+
length,
|
|
631
|
+
format
|
|
601
632
|
);
|
|
602
|
-
if (ret !== 0) throw new Error(`StreamVAD detectFull failed: ${ret}`);
|
|
603
|
-
const numFrames = M.getValue(framesPtr, "i32");
|
|
604
|
-
const probsPtr = M.getValue(probsPtrPtr, "i32");
|
|
605
|
-
const probabilities = probsPtr ? new Float32Array(new Float32Array(M.HEAPU8.buffer, probsPtr, numFrames)) : new Float32Array(0);
|
|
606
|
-
if (probsPtr) M._free(probsPtr);
|
|
607
633
|
return {
|
|
608
634
|
probabilities,
|
|
609
635
|
numFrames,
|
|
610
|
-
duration: Math.round(
|
|
636
|
+
duration: Math.round(length / SAMPLE_RATE2 * 1e3) / 1e3
|
|
611
637
|
};
|
|
612
638
|
} finally {
|
|
613
|
-
M._free(
|
|
614
|
-
M._free(probsPtrPtr);
|
|
615
|
-
M._free(framesPtr);
|
|
639
|
+
M._free(ptr);
|
|
616
640
|
}
|
|
617
641
|
}
|
|
618
642
|
/** Reset all internal state (model cache, audio buffer, postprocessor). */
|
|
@@ -627,31 +651,6 @@ var OmniStreamVAD = class _OmniStreamVAD {
|
|
|
627
651
|
}
|
|
628
652
|
}
|
|
629
653
|
};
|
|
630
|
-
function int16ToFloat32(i16) {
|
|
631
|
-
const f32 = new Float32Array(i16.length);
|
|
632
|
-
for (let i = 0; i < i16.length; i++) f32[i] = i16[i];
|
|
633
|
-
return f32;
|
|
634
|
-
}
|
|
635
|
-
function prepareDetectFullAudio(audio) {
|
|
636
|
-
if (audio instanceof Int16Array) {
|
|
637
|
-
return int16ToFloat32(audio);
|
|
638
|
-
}
|
|
639
|
-
if (isNormalizedFloat(audio)) {
|
|
640
|
-
const scaled = new Float32Array(audio.length);
|
|
641
|
-
for (let i = 0; i < audio.length; i++) scaled[i] = audio[i] * 32768;
|
|
642
|
-
return scaled;
|
|
643
|
-
}
|
|
644
|
-
return audio;
|
|
645
|
-
}
|
|
646
|
-
function isNormalizedFloat(audio) {
|
|
647
|
-
const step = Math.max(1, Math.floor(audio.length / 1e3));
|
|
648
|
-
let maxAbs = 0;
|
|
649
|
-
for (let i = 0; i < audio.length; i += step) {
|
|
650
|
-
const v = Math.abs(audio[i]);
|
|
651
|
-
if (v > maxAbs) maxAbs = v;
|
|
652
|
-
}
|
|
653
|
-
return maxAbs <= 1;
|
|
654
|
-
}
|
|
655
654
|
|
|
656
655
|
// src/aed.ts
|
|
657
656
|
var SAMPLE_RATE3 = 16e3;
|
|
@@ -691,7 +690,7 @@ var OmniAED = class _OmniAED {
|
|
|
691
690
|
*/
|
|
692
691
|
detect(audio) {
|
|
693
692
|
const M = getModule();
|
|
694
|
-
const { ptr, length, format } =
|
|
693
|
+
const { ptr, length, format } = dispatchAudio(M, audio);
|
|
695
694
|
const duration = Math.round(length / SAMPLE_RATE3 * 1e3) / 1e3;
|
|
696
695
|
try {
|
|
697
696
|
const events = aedDetect(M, this.handle, ptr, length, this.config, format);
|
|
@@ -712,18 +711,6 @@ var OmniAED = class _OmniAED {
|
|
|
712
711
|
}
|
|
713
712
|
}
|
|
714
713
|
};
|
|
715
|
-
function prepareAudio2(M, audio) {
|
|
716
|
-
const f32 = audio instanceof Int16Array ? int16ToNormalizedFloat322(audio) : audio;
|
|
717
|
-
const ptr = M._malloc(f32.length * 4);
|
|
718
|
-
const heap = new Float32Array(M.HEAPU8.buffer, ptr, f32.length);
|
|
719
|
-
heap.set(f32);
|
|
720
|
-
return { ptr, length: f32.length, format: "f32" };
|
|
721
|
-
}
|
|
722
|
-
function int16ToNormalizedFloat322(i16) {
|
|
723
|
-
const f32 = new Float32Array(i16.length);
|
|
724
|
-
for (let i = 0; i < i16.length; i++) f32[i] = i16[i] / 32768;
|
|
725
|
-
return f32;
|
|
726
|
-
}
|
|
727
714
|
function computeCoverageRatios(events, duration) {
|
|
728
715
|
const ratios = {
|
|
729
716
|
speech: 0,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/wasm-binding.ts","../src/vad.ts","../src/stream-vad.ts","../src/aed.ts","../src/chunking.ts"],"names":["resp","SAMPLE_RATE","prepareAudio","int16ToNormalizedFloat32"],"mappings":";;;;AAQA,IAAI,OAAA,GAAmC,IAAA;AACvC,IAAI,QAAA,GAA6C,IAAA;AAWjD,SAAS,WAAW,GAAA,EAA4B;AAE9C,EAAA,IAAI,OAAO,UAAA,CAAW,QAAA,KAAa,WAAA,EAAa;AAC9C,IAAA,OAAO,IAAI,OAAA,CAAc,CAAC,OAAA,EAAS,MAAA,KAAW;AAC5C,MAAA,IAAI;AAEF,QAAA,MAAM,gBAAiB,UAAA,CAAmB,aAAA;AAG1C,QAAA,IAAI,OAAO,kBAAkB,UAAA,EAAY;AACvC,UAAA,MAAM,IAAI,KAAA;AAAA,YACR;AAAA,WACF;AAAA,QACF;AACA,QAAA,aAAA,CAAc,GAAG,CAAA;AACjB,QAAA,OAAA,EAAQ;AAAA,MACV,SAAS,GAAA,EAAK;AACZ,QAAA,MAAA,CAAO,GAAA,YAAe,QAAQ,GAAA,GAAM,IAAI,MAAM,MAAA,CAAO,GAAG,CAAC,CAAC,CAAA;AAAA,MAC5D;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,IAAI,OAAA,CAAc,CAAC,OAAA,EAAS,MAAA,KAAW;AAC5C,IAAA,MAAM,CAAA,GAAI,UAAA,CAAW,QAAA,CAAU,aAAA,CAAc,QAAQ,CAAA;AACrD,IAAA,CAAA,CAAE,GAAA,GAAM,GAAA;AACR,IAAA,CAAA,CAAE,KAAA,GAAQ,IAAA;AACV,IAAA,CAAA,CAAE,WAAA,GAAc,WAAA;AAChB,IAAA,CAAA,CAAE,MAAA,GAAS,MAAM,OAAA,EAAQ;AACzB,IAAA,CAAA,CAAE,OAAA,GAAU,MACV,MAAA,CAAO,IAAI,MAAM,CAAA,oCAAA,EAAuC,GAAG,EAAE,CAAC,CAAA;AAChE,IAAA,UAAA,CAAW,QAAA,CAAU,IAAA,CAAK,WAAA,CAAY,CAAC,CAAA;AAAA,EACzC,CAAC,CAAA;AACH;AAaA,IAAM,kBAAA,GAAqB,EAAA;AAC3B,IAAM,yBAAyB,CAAA,GAAI,kBAAA;AACnC,IAAM,cAAA,GAAiB,CAAA;AACvB,IAAM,kBAAA,GAAqB,EAAA;AAC3B,IAAM,mBAAA,GAAsB,EAAA;AAC5B,IAAM,YAAA,GAAe,EAAA;AAKrB,IAAM,kBAAA,GAAqB,EAAA;AAGpB,IAAM,OAAA,GAAU;AAGhB,IAAM,gBAAA,GAAmB,wCAAwC,OAAO,CAAA,OAAA;AAGxE,IAAM,WAAA,GAAc;AAAA,EACzB,GAAA,EAAK,aAAA;AAAA,EACL,YAAA,EAAc,oBAAA;AAAA,EACd,GAAA,EAAK;AACP;AAQA,eAAsB,SACpB,WAAA,EAC2B;AAC3B,EAAA,IAAI,SAAS,OAAO,OAAA;AACpB,EAAA,IAAI,UAAU,OAAO,QAAA;AAErB,EAAA,QAAA,GAAA,CAAY,YAAY;AAEtB,IAAA,IAAI,aAAA;AACJ,IAAA,IAAI,iBAAA;AAEJ,IAAA,IAAI,OAAO,UAAA,CAAW,OAAA,EAAS,QAAA,EAAU,SAAS,QAAA,EAAU;AAE1D,MAAA,MAAM,EAAE,aAAA,EAAc,GAAI,MAAM;AAAA;AAAA;AAAA,QAA6D;AAAA,OAAQ;AACrG,MAAA,MAAM,EAAE,OAAA,EAAS,IAAA,EAAK,GAAI,MAAM;AAAA;AAAA;AAAA,QAA6D;AAAA,OAAM;AACnG,MAAA,MAAM,GAAA,GAAM,aAAA,CAAc,2PAAe,CAAA;AACzC,MAAA,MAAM,QAAA,GAAW,GAAA,CAAI,OAAA,CAAQ,0BAA0B,CAAA;AACvD,MAAA,MAAM,OAAA,GAAU,QAAQ,QAAQ,CAAA;AAChC,MAAA,aAAA,GAAgB,IAAI,QAAQ,CAAA;AAC5B,MAAA,iBAAA,GAAoB,CAAC,QAAA,KAAqB,IAAA,CAAK,OAAA,EAAS,QAAQ,CAAA;AAAA,IAClE,CAAA,MAAO;AAWL,MAAA,IAAI,UAAA;AACJ,MAAA,IAAI,WAAA,EAAa;AACf,QAAA,UAAA,GAAa,YAAY,YAAY,CAAA;AAAA,MACvC,CAAA,MAAO;AAEL,QAAA,UAAA,GAAa,IAAI,GAAA,CAAI,yBAAA,EAA2B,2PAAe,CAAA,CAAE,IAAA;AAAA,MACnE;AAEA,MAAA,MAAM,CAAA,GAAI,UAAA;AACV,MAAA,IAAI,UACF,CAAA,CAAE,aAAA;AACJ,MAAA,IAAI,OAAO,YAAY,UAAA,EAAY;AACjC,QAAA,MAAM,WAAW,UAAU,CAAA;AAC3B,QAAA,OAAA,GAAU,CAAA,CAAE,aAAA;AAAA,MACd;AACA,MAAA,IAAI,OAAO,YAAY,UAAA,EAAY;AACjC,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,0BAA0B,UAAU,CAAA,wCAAA;AAAA,SACtC;AAAA,MACF;AACA,MAAA,aAAA,GAAgB,OAAA;AAIhB,MAAA,MAAM,WACJ,OAAO,UAAA,CAAW,aAAa,WAAA,GAC3B,UAAA,CAAW,SAAS,IAAA,GACpB,UAAA;AACN,MAAA,MAAM,OAAA,GAAU,IAAI,GAAA,CAAI,UAAA,EAAY,QAAQ,CAAA;AAC5C,MAAA,MAAM,WAAA,GAAc,IAAI,GAAA,CAAI,IAAA,EAAM,OAAO,CAAA;AACzC,MAAA,iBAAA,GAAoB,CAAC,QAAA,KAAqB,IAAI,IAAI,QAAA,EAAU,WAAW,EAAE,QAAA,EAAS;AAAA,IACpF;AAEA,IAAA,MAAM,OAAgC,EAAC;AACvC,IAAA,MAAM,aAAa,WAAA,IAAe,iBAAA;AAClC,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,IAAA,CAAK,UAAA,GAAa,CAAC,IAAA,KAAiB,UAAA,CAAW,IAAI,CAAA;AAAA,IACrD;AAEA,IAAA,OAAA,GAAU,MAAM,cAAc,IAAI,CAAA;AAClC,IAAA,OAAO,OAAA;AAAA,EACT,CAAA,GAAG;AAEH,EAAA,OAAO,QAAA;AACT;AAWA,eAAsB,SAAA,CACpB,SAAA,EACA,QAAA,EACA,SAAA,EACsB;AACtB,EAAA,IAAI,WAAW,OAAO,SAAA;AAEtB,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,MAAMA,KAAAA,GAAO,MAAM,KAAA,CAAM,QAAA,CAAS,UAAU,CAAA;AAC5C,IAAA,IAAI,CAACA,KAAAA,CAAK,EAAA,EAAI,MAAM,IAAI,KAAA,CAAM,CAAA,2BAAA,EAA8B,QAAQ,CAAA,EAAA,EAAKA,KAAAA,CAAK,MAAM,CAAA,CAAE,CAAA;AACtF,IAAA,OAAOA,MAAK,WAAA,EAAY;AAAA,EAC1B;AAEA,EAAA,MAAM,QAAA,GAAW,YAAY,SAAS,CAAA;AAEtC,EAAA,IAAI,OAAO,UAAA,CAAW,OAAA,EAAS,QAAA,EAAU,SAAS,QAAA,EAAU;AAE1D,IAAA,MAAM,EAAE,aAAA,EAAc,GAAI,MAAM;AAAA;AAAA;AAAA,MAA6D;AAAA,KAAQ;AACrG,IAAA,MAAM,EAAE,OAAA,EAAS,IAAA,EAAK,GAAI,MAAM;AAAA;AAAA;AAAA,MAA6D;AAAA,KAAM;AACnG,IAAA,MAAM,EAAE,QAAA,EAAS,GAAI,MAAM;AAAA;AAAA;AAAA,MAA6D;AAAA,KAAa;AACrG,IAAA,MAAM,GAAA,GAAM,aAAA,CAAc,2PAAe,CAAA;AACzC,IAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,GAAA,CAAI,OAAA,CAAQ,iBAAiB,CAAC,CAAA;AACrD,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,MAAA,EAAQ,QAAA,EAAU,QAAQ,CAAA;AACjD,IAAA,MAAM,GAAA,GAAM,MAAM,QAAA,CAAS,SAAS,CAAA;AACpC,IAAA,OAAO,GAAA,CAAI,OAAO,KAAA,CAAM,GAAA,CAAI,YAAY,GAAA,CAAI,UAAA,GAAa,IAAI,UAAU,CAAA;AAAA,EACzE;AAGA,EAAA,MAAM,GAAA,GAAM,CAAA,EAAG,gBAAgB,CAAA,CAAA,EAAI,QAAQ,CAAA,CAAA;AAC3C,EAAA,MAAM,IAAA,GAAO,MAAM,KAAA,CAAM,GAAG,CAAA;AAC5B,EAAA,IAAI,CAAC,IAAA,CAAK,EAAA,EAAI,MAAM,IAAI,KAAA,CAAM,CAAA,2BAAA,EAA8B,GAAG,CAAA,EAAA,EAAK,IAAA,CAAK,MAAM,CAAA,CAAE,CAAA;AACjF,EAAA,OAAO,KAAK,WAAA,EAAY;AAC1B;AAGO,SAAS,SAAA,GAA8B;AAC5C,EAAA,IAAI,CAAC,OAAA,EAAS,MAAM,IAAI,MAAM,8CAA8C,CAAA;AAC5E,EAAA,OAAO,OAAA;AACT;AAEA,SAAS,eAAA,CAAgB,GAAqB,IAAA,EAAsB;AAClE,EAAA,MAAM,GAAA,GAAM,CAAA,CAAE,KAAA,CAAM,mBAAA,EAAqB,QAAA,EAAU,CAAC,QAAQ,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AACrE,EAAA,OAAO,MAAM,CAAA,EAAG,GAAG,KAAK,IAAI,CAAA,CAAA,CAAA,GAAM,SAAS,IAAI,CAAA,CAAA;AACjD;AAGA,SAAS,WAAA,CACP,CAAA,EACA,MAAA,EACA,QAAA,EACA,MACA,KAAA,EACQ;AACR,EAAA,MAAM,MAAA,GAAS,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA;AAC1B,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,CAAA,CAAE,KAAA,CAAM,MAAA,EAAQ,UAAU,CAAC,GAAG,QAAA,EAAU,QAAQ,CAAA,EAAG,CAAC,GAAG,IAAA,EAAM,MAAM,CAAC,CAAA;AACnF,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,MAAM,GAAA,GAAM,CAAA,CAAE,QAAA,CAAS,MAAA,EAAQ,KAAK,CAAA;AACpC,MAAA,MAAM,IAAI,MAAM,CAAA,iBAAA,EAAoB,KAAK,WAAW,eAAA,CAAgB,CAAA,EAAG,GAAG,CAAC,CAAA,CAAE,CAAA;AAAA,IAC/E;AACA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA,SAAE;AACA,IAAA,CAAA,CAAE,MAAM,MAAM,CAAA;AAAA,EAChB;AACF;AAOO,SAAS,eAAA,CAAgB,GAAqB,KAAA,EAA6B;AAChF,EAAA,MAAM,GAAA,GAAM,CAAA,CAAE,OAAA,CAAQ,KAAA,CAAM,SAAS,CAAC,CAAA;AACtC,EAAA,MAAM,IAAA,GAAO,IAAI,YAAA,CAAa,CAAA,CAAE,OAAO,MAAA,EAAQ,GAAA,EAAK,MAAM,MAAM,CAAA;AAChE,EAAA,IAAA,CAAK,IAAI,KAAK,CAAA;AACd,EAAA,OAAO,GAAA;AACT;AAGO,SAAS,eAAA,CAAgB,CAAA,EAAqB,GAAA,EAAa,GAAA,EAAuB;AACvF,EAAA,CAAA,CAAE,QAAA,CAAS,GAAA,GAAM,CAAA,EAAG,GAAA,CAAI,WAAW,OAAO,CAAA;AAC1C,EAAA,CAAA,CAAE,QAAA,CAAS,GAAA,GAAM,CAAA,EAAG,GAAA,CAAI,kBAAkB,KAAK,CAAA;AAC/C,EAAA,CAAA,CAAE,QAAA,CAAS,GAAA,GAAM,CAAA,EAAG,GAAA,CAAI,iBAAiB,KAAK,CAAA;AAC9C,EAAA,CAAA,CAAE,QAAA,CAAS,GAAA,GAAM,EAAA,EAAI,GAAA,CAAI,kBAAkB,KAAK,CAAA;AAChD,EAAA,CAAA,CAAE,QAAA,CAAS,GAAA,GAAM,EAAA,EAAI,GAAA,CAAI,iBAAiB,KAAK,CAAA;AAC/C,EAAA,CAAA,CAAE,QAAA,CAAS,GAAA,GAAM,EAAA,EAAI,GAAA,CAAI,oBAAoB,KAAK,CAAA;AAClD,EAAA,CAAA,CAAE,QAAA,CAAS,GAAA,GAAM,EAAA,EAAI,GAAA,CAAI,oBAAoB,KAAK,CAAA;AACpD;AAEO,IAAM,kBAAA,GAAiC;AAAA,EAC5C,SAAA,EAAW,GAAA;AAAA,EACX,gBAAA,EAAkB,CAAA;AAAA,EAClB,eAAA,EAAiB,EAAA;AAAA,EACjB,gBAAA,EAAkB,EAAA;AAAA,EAClB,eAAA,EAAiB,GAAA;AAAA,EACjB,kBAAA,EAAoB,CAAA;AAAA,EACpB,kBAAA,EAAoB;AACtB,CAAA;AAOO,IAAM,iBAAA,GAAoB,CAAA;AAC1B,IAAM,sBAAA,GAAyB,CAAA;AA8B/B,IAAM,oBAAA,GAAoC;AAAA,EAC/C,YAAA,EAAc,EAAA;AAAA,EACd,UAAA,EAAY,QAAA;AAAA,EACZ,YAAA,EAAc,IAAA;AAAA,EACd,aAAA,EAAe,IAAA;AAAA,EACf,aAAA,EAAe,CAAA;AAAA,EACf,cAAA,EAAgB,GAAA;AAAA;AAAA,EAChB,IAAA,EAAM;AACR;AAEA,SAAS,UAAU,CAAA,EAAsB;AACvC,EAAA,QAAQ,CAAA;AAAG,IACT,KAAK,QAAA;AAAU,MAAA,OAAO,iBAAA;AAAA,IACtB,KAAK,aAAA;AAAe,MAAA,OAAO,sBAAA;AAAA,IAC3B;AAAS,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,uBAAA,EAA0B,MAAA,CAAO,CAAC,CAAC,CAAA,CAAE,CAAA;AAAA;AAElE;AAGO,SAAS,gBAAA,CAAiB,CAAA,EAAqB,GAAA,EAAa,GAAA,EAAwB;AACzF,EAAA,CAAA,CAAE,QAAA,CAAS,GAAA,GAAM,CAAA,EAAI,GAAA,CAAI,cAAoB,OAAO,CAAA;AACpD,EAAA,CAAA,CAAE,QAAA,CAAS,GAAA,GAAM,CAAA,EAAI,GAAA,CAAI,YAAqB,OAAO,CAAA;AACrD,EAAA,CAAA,CAAE,QAAA,CAAS,GAAA,GAAM,CAAA,EAAI,GAAA,CAAI,cAAqB,OAAO,CAAA;AACrD,EAAA,CAAA,CAAE,QAAA,CAAS,GAAA,GAAM,EAAA,EAAI,GAAA,CAAI,eAAqB,OAAO,CAAA;AACrD,EAAA,CAAA,CAAE,QAAA,CAAS,GAAA,GAAM,EAAA,EAAI,GAAA,CAAI,eAAiB,OAAO,CAAA;AACjD,EAAA,CAAA,CAAE,QAAA,CAAS,GAAA,GAAM,EAAA,EAAI,GAAA,CAAI,gBAAiB,OAAO,CAAA;AACjD,EAAA,CAAA,CAAE,SAAS,GAAA,GAAM,EAAA,EAAI,UAAU,GAAA,CAAI,IAAI,GAAG,KAAK,CAAA;AACjD;AAgBO,SAAS,UAAA,CACd,CAAA,EACA,QAAA,EACA,MAAA,EACe;AACf,EAAA,MAAM,cAAc,QAAA,CAAS,MAAA;AAE7B,EAAA,MAAM,SAAS,WAAA,GAAc,CAAA,GAAI,EAAE,OAAA,CAAQ,WAAA,GAAc,cAAc,CAAA,GAAI,CAAA;AAC3E,EAAA,MAAM,MAAA,GAAS,CAAA,CAAE,OAAA,CAAQ,mBAAmB,CAAA;AAC5C,EAAA,MAAM,SAAA,GAAY,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA;AAC7B,EAAA,MAAM,WAAA,GAAc,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA;AAE/B,EAAA,IAAI;AACF,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,WAAA,EAAa,CAAA,EAAA,EAAK;AACpC,MAAA,MAAM,IAAA,GAAO,SAAS,CAAA,GAAI,cAAA;AAC1B,MAAA,CAAA,CAAE,QAAA,CAAS,OAAO,CAAA,EAAG,QAAA,CAAS,CAAC,CAAA,CAAE,CAAC,GAAG,OAAO,CAAA;AAC5C,MAAA,CAAA,CAAE,QAAA,CAAS,OAAO,CAAA,EAAG,QAAA,CAAS,CAAC,CAAA,CAAE,CAAC,GAAG,OAAO,CAAA;AAAA,IAC9C;AACA,IAAA,gBAAA,CAAiB,CAAA,EAAG,QAAQ,MAAM,CAAA;AAClC,IAAA,CAAA,CAAE,QAAA,CAAS,SAAA,EAAW,CAAA,EAAG,KAAK,CAAA;AAC9B,IAAA,CAAA,CAAE,QAAA,CAAS,WAAA,EAAa,CAAA,EAAG,KAAK,CAAA;AAEhC,IAAA,MAAM,KAAK,CAAA,CAAE,KAAA;AAAA,MACX,mBAAA;AAAA,MACA,QAAA;AAAA,MACA,CAAC,QAAA,EAAU,QAAA,EAAU,QAAA,EAAU,UAAU,QAAQ,CAAA;AAAA,MACjD,CAAC,MAAA,EAAQ,WAAA,EAAa,MAAA,EAAQ,WAAW,WAAW;AAAA,KACtD;AACA,IAAA,IAAI,OAAO,CAAA,EAAG;AACZ,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,0BAAA,EAA6B,gBAAgB,CAAA,EAAG,EAAE,CAAC,CAAA,CAAE,CAAA;AAAA,IACvE;AAEA,IAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,QAAA,CAAS,WAAA,EAAa,KAAK,CAAA;AAC3C,IAAA,MAAM,QAAA,GAAW,CAAA,CAAE,QAAA,CAAS,SAAA,EAAW,KAAK,CAAA;AAC5C,IAAA,MAAM,SAAwB,EAAC;AAC/B,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,EAAO,CAAA,EAAA,EAAK;AAC9B,MAAA,MAAM,IAAA,GAAO,WAAW,CAAA,GAAI,YAAA;AAC5B,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,KAAA,EAAa,CAAA,CAAE,QAAA,CAAS,IAAA,GAAO,GAAG,OAAO,CAAA;AAAA,QACzC,GAAA,EAAa,CAAA,CAAE,QAAA,CAAS,IAAA,GAAO,GAAG,OAAO,CAAA;AAAA,QACzC,WAAA,EAAa,CAAA,CAAE,QAAA,CAAS,IAAA,GAAO,GAAG,KAAK,CAAA;AAAA,QACvC,QAAA,EAAa,CAAA,CAAE,QAAA,CAAS,IAAA,GAAO,IAAI,KAAK;AAAA,OACzC,CAAA;AAAA,IACH;AACA,IAAA,IAAI,QAAA,EAAU,CAAA,CAAE,KAAA,CAAM,QAAQ,CAAA;AAC9B,IAAA,OAAO,MAAA;AAAA,EACT,CAAA,SAAE;AACA,IAAA,IAAI,MAAA,EAAQ,CAAA,CAAE,KAAA,CAAM,MAAM,CAAA;AAC1B,IAAA,CAAA,CAAE,MAAM,MAAM,CAAA;AACd,IAAA,CAAA,CAAE,MAAM,SAAS,CAAA;AACjB,IAAA,CAAA,CAAE,MAAM,WAAW,CAAA;AAAA,EACrB;AACF;AAMO,SAAS,SAAA,CAAU,GAAqB,WAAA,EAAkC;AAC/E,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,WAAW,CAAA;AACxC,EAAA,MAAM,GAAA,GAAM,CAAA,CAAE,OAAA,CAAQ,KAAA,CAAM,MAAM,CAAA;AAClC,EAAA,CAAA,CAAE,MAAA,CAAO,GAAA,CAAI,KAAA,EAAO,GAAG,CAAA;AACvB,EAAA,IAAI;AACF,IAAA,OAAO,WAAA,CAAY,CAAA,EAAG,6BAAA,EAA+B,CAAC,QAAA,EAAU,QAAQ,CAAA,EAAG,CAAC,GAAA,EAAK,KAAA,CAAM,MAAM,CAAA,EAAG,KAAK,CAAA;AAAA,EACvG,CAAA,SAAE;AACA,IAAA,CAAA,CAAE,MAAM,GAAG,CAAA;AAAA,EACb;AACF;AASA,SAAS,YAAA,CAAa,CAAA,EAAqB,SAAA,EAAmB,QAAA,EAA2C;AACvG,EAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,QAAA,CAAS,QAAA,EAAU,KAAK,CAAA;AACxC,EAAA,MAAM,MAAA,GAAS,CAAA,CAAE,QAAA,CAAS,SAAA,EAAW,KAAK,CAAA;AAC1C,EAAA,MAAM,WAAoC,EAAC;AAC3C,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,EAAO,CAAA,EAAA,EAAK;AAC9B,IAAA,MAAM,IAAA,GAAO,SAAS,CAAA,GAAI,cAAA;AAC1B,IAAA,QAAA,CAAS,IAAA,CAAK;AAAA,MACZ,IAAA,CAAK,MAAM,CAAA,CAAE,QAAA,CAAS,MAAM,OAAO,CAAA,GAAI,GAAI,CAAA,GAAI,GAAA;AAAA,MAC/C,IAAA,CAAK,MAAM,CAAA,CAAE,QAAA,CAAS,OAAO,CAAA,EAAG,OAAO,CAAA,GAAI,GAAI,CAAA,GAAI;AAAA,KACpD,CAAA;AAAA,EACH;AACA,EAAA,IAAI,MAAA,EAAQ,CAAA,CAAE,KAAA,CAAM,MAAM,CAAA;AAC1B,EAAA,OAAO,QAAA;AACT;AAEO,SAAS,UACd,CAAA,EACA,MAAA,EACA,UACA,UAAA,EACA,GAAA,EACA,SAAsB,KAAA,EACG;AACzB,EAAA,MAAM,MAAA,GAAS,CAAA,CAAE,OAAA,CAAQ,kBAAkB,CAAA;AAC3C,EAAA,MAAM,SAAA,GAAY,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA;AAC7B,EAAA,MAAM,QAAA,GAAW,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA;AAC5B,EAAA,MAAM,EAAA,GAAK,MAAA,KAAW,OAAA,GAAU,uBAAA,GAA0B,iBAAA;AAE1D,EAAA,IAAI;AACF,IAAA,eAAA,CAAgB,CAAA,EAAG,QAAQ,GAAG,CAAA;AAC9B,IAAA,MAAM,MAAM,CAAA,CAAE,KAAA;AAAA,MACZ,EAAA;AAAA,MACA,QAAA;AAAA,MACA,CAAC,QAAA,EAAU,QAAA,EAAU,QAAA,EAAU,QAAA,EAAU,UAAU,QAAQ,CAAA;AAAA,MAC3D,CAAC,MAAA,EAAQ,QAAA,EAAU,UAAA,EAAY,MAAA,EAAQ,WAAW,QAAQ;AAAA,KAC5D;AACA,IAAA,IAAI,QAAQ,CAAA,EAAG,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,GAAG,CAAA,CAAE,CAAA;AAC1D,IAAA,OAAO,YAAA,CAAa,CAAA,EAAG,SAAA,EAAW,QAAQ,CAAA;AAAA,EAC5C,CAAA,SAAE;AACA,IAAA,CAAA,CAAE,MAAM,MAAM,CAAA;AACd,IAAA,CAAA,CAAE,MAAM,SAAS,CAAA;AACjB,IAAA,CAAA,CAAE,MAAM,QAAQ,CAAA;AAAA,EAClB;AACF;AAEO,SAAS,UAAA,CAAW,GAAqB,MAAA,EAAsB;AACpE,EAAA,CAAA,CAAE,KAAA,CAAM,oBAAoB,IAAA,EAAM,CAAC,QAAQ,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AACxD;AAMA,IAAM,cAAsC,EAAE,CAAA,EAAG,UAAU,CAAA,EAAG,SAAA,EAAW,GAAG,OAAA,EAAQ;AAE7E,SAAS,SAAA,CAAU,GAAqB,WAAA,EAAkC;AAC/E,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,WAAW,CAAA;AACxC,EAAA,MAAM,GAAA,GAAM,CAAA,CAAE,OAAA,CAAQ,KAAA,CAAM,MAAM,CAAA;AAClC,EAAA,CAAA,CAAE,MAAA,CAAO,GAAA,CAAI,KAAA,EAAO,GAAG,CAAA;AACvB,EAAA,IAAI;AACF,IAAA,OAAO,WAAA,CAAY,CAAA,EAAG,6BAAA,EAA+B,CAAC,QAAA,EAAU,QAAQ,CAAA,EAAG,CAAC,GAAA,EAAK,KAAA,CAAM,MAAM,CAAA,EAAG,KAAK,CAAA;AAAA,EACvG,CAAA,SAAE;AACA,IAAA,CAAA,CAAE,MAAM,GAAG,CAAA;AAAA,EACb;AACF;AAQO,SAAS,UACd,CAAA,EACA,MAAA,EACA,UACA,UAAA,EACA,GAAA,EACA,SAAsB,KAAA,EACmB;AACzC,EAAA,MAAM,MAAA,GAAS,CAAA,CAAE,OAAA,CAAQ,sBAAsB,CAAA;AAC/C,EAAA,MAAM,SAAA,GAAY,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA;AAC7B,EAAA,MAAM,QAAA,GAAW,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA;AAC5B,EAAA,MAAM,EAAA,GAAK,MAAA,KAAW,OAAA,GAAU,uBAAA,GAA0B,iBAAA;AAE1D,EAAA,IAAI;AACF,IAAA,eAAA,CAAgB,CAAA,EAAG,MAAA,EAAQ,GAAA,CAAI,MAAM,CAAA;AACrC,IAAA,eAAA,CAAgB,CAAA,EAAG,MAAA,GAAS,kBAAA,EAAoB,GAAA,CAAI,OAAO,CAAA;AAC3D,IAAA,eAAA,CAAgB,CAAA,EAAG,MAAA,GAAS,CAAA,GAAI,kBAAA,EAAoB,IAAI,KAAK,CAAA;AAE7D,IAAA,MAAM,MAAM,CAAA,CAAE,KAAA;AAAA,MACZ,EAAA;AAAA,MACA,QAAA;AAAA,MACA,CAAC,QAAA,EAAU,QAAA,EAAU,QAAA,EAAU,QAAA,EAAU,UAAU,QAAQ,CAAA;AAAA,MAC3D,CAAC,MAAA,EAAQ,QAAA,EAAU,UAAA,EAAY,MAAA,EAAQ,WAAW,QAAQ;AAAA,KAC5D;AACA,IAAA,IAAI,QAAQ,CAAA,EAAG,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,GAAG,CAAA,CAAE,CAAA;AAE1D,IAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,QAAA,CAAS,QAAA,EAAU,KAAK,CAAA;AACxC,IAAA,MAAM,MAAA,GAAS,CAAA,CAAE,QAAA,CAAS,SAAA,EAAW,KAAK,CAAA;AAC1C,IAAA,MAAM,MAAA,GAAkD;AAAA,MACtD,QAAQ,EAAC;AAAA,MACT,SAAS,EAAC;AAAA,MACV,OAAO;AAAC,KACV;AACA,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,EAAO,CAAA,EAAA,EAAK;AAC9B,MAAA,MAAM,IAAA,GAAO,SAAS,CAAA,GAAI,kBAAA;AAC1B,MAAA,MAAM,GAAA,GAAM,CAAA,CAAE,QAAA,CAAS,IAAA,GAAO,GAAG,KAAK,CAAA;AACtC,MAAA,MAAM,IAAA,GAAO,YAAY,GAAG,CAAA;AAC5B,MAAA,IAAI,IAAA,IAAQ,MAAA,CAAO,IAAI,CAAA,EAAG;AACxB,QAAA,MAAA,CAAO,IAAI,EAAE,IAAA,CAAK;AAAA,UAChB,IAAA,CAAK,MAAM,CAAA,CAAE,QAAA,CAAS,MAAM,OAAO,CAAA,GAAI,GAAI,CAAA,GAAI,GAAA;AAAA,UAC/C,IAAA,CAAK,MAAM,CAAA,CAAE,QAAA,CAAS,OAAO,CAAA,EAAG,OAAO,CAAA,GAAI,GAAI,CAAA,GAAI;AAAA,SACpD,CAAA;AAAA,MACH;AAAA,IACF;AACA,IAAA,IAAI,MAAA,EAAQ,CAAA,CAAE,KAAA,CAAM,MAAM,CAAA;AAC1B,IAAA,OAAO,MAAA;AAAA,EACT,CAAA,SAAE;AACA,IAAA,CAAA,CAAE,MAAM,MAAM,CAAA;AACd,IAAA,CAAA,CAAE,MAAM,SAAS,CAAA;AACjB,IAAA,CAAA,CAAE,MAAM,QAAQ,CAAA;AAAA,EAClB;AACF;AAEO,SAAS,UAAA,CAAW,GAAqB,MAAA,EAAsB;AACpE,EAAA,CAAA,CAAE,KAAA,CAAM,oBAAoB,IAAA,EAAM,CAAC,QAAQ,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AACxD;AAiBO,IAAM,yBAAA,GAA6C;AAAA,EACxD,SAAA,EAAW,GAAA;AAAA,EACX,gBAAA,EAAkB,CAAA;AAAA,EAClB,aAAA,EAAe,CAAA;AAAA,EACf,cAAA,EAAgB,CAAA;AAAA,EAChB,cAAA,EAAgB,GAAA;AAAA,EAChB,eAAA,EAAiB;AACnB,CAAA;AAEA,IAAM,wBAAA,GAA2B,EAAA;AAEjC,SAAS,oBAAA,CAAqB,CAAA,EAAqB,GAAA,EAAa,GAAA,EAA4B;AAC1F,EAAA,CAAA,CAAE,QAAA,CAAS,GAAA,GAAM,CAAA,EAAI,GAAA,CAAI,WAAkB,OAAO,CAAA;AAClD,EAAA,CAAA,CAAE,QAAA,CAAS,GAAA,GAAM,CAAA,EAAI,GAAA,CAAI,kBAAkB,KAAK,CAAA;AAChD,EAAA,CAAA,CAAE,QAAA,CAAS,GAAA,GAAM,CAAA,EAAI,GAAA,CAAI,eAAkB,KAAK,CAAA;AAChD,EAAA,CAAA,CAAE,QAAA,CAAS,GAAA,GAAM,EAAA,EAAI,GAAA,CAAI,gBAAkB,KAAK,CAAA;AAChD,EAAA,CAAA,CAAE,QAAA,CAAS,GAAA,GAAM,EAAA,EAAI,GAAA,CAAI,gBAAkB,KAAK,CAAA;AAChD,EAAA,CAAA,CAAE,QAAA,CAAS,GAAA,GAAM,EAAA,EAAI,GAAA,CAAI,iBAAkB,KAAK,CAAA;AAClD;AAEO,SAAS,eAAA,CACd,CAAA,EACA,WAAA,EACA,MAAA,GAAmC,EAAC,EAC5B;AAGR,EAAA,MAAM,YAAY,MAAA,CAAO,WAAA;AAAA,IACvB,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,CAAE,MAAA,CAAO,CAAC,GAAG,CAAC,CAAA,KAAM,CAAA,KAAM,MAAS;AAAA,GAC1D;AACA,EAAA,MAAM,GAAA,GAAuB,EAAE,GAAG,yBAAA,EAA2B,GAAG,SAAA,EAAU;AAC1E,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,WAAW,CAAA;AACxC,EAAA,MAAM,OAAA,GAAU,CAAA,CAAE,OAAA,CAAQ,KAAA,CAAM,MAAM,CAAA;AACtC,EAAA,CAAA,CAAE,MAAA,CAAO,GAAA,CAAI,KAAA,EAAO,OAAO,CAAA;AAC3B,EAAA,MAAM,MAAA,GAAS,CAAA,CAAE,OAAA,CAAQ,wBAAwB,CAAA;AACjD,EAAA,IAAI;AACF,IAAA,oBAAA,CAAqB,CAAA,EAAG,QAAQ,GAAG,CAAA;AACnC,IAAA,OAAO,WAAA;AAAA,MACL,CAAA;AAAA,MACA,oCAAA;AAAA,MACA,CAAC,QAAA,EAAU,QAAA,EAAU,QAAQ,CAAA;AAAA,MAC7B,CAAC,OAAA,EAAS,KAAA,CAAM,MAAA,EAAQ,MAAM,CAAA;AAAA,MAC9B;AAAA,KACF;AAAA,EACF,CAAA,SAAE;AACA,IAAA,CAAA,CAAE,MAAM,OAAO,CAAA;AACf,IAAA,CAAA,CAAE,MAAM,MAAM,CAAA;AAAA,EAChB;AACF;AAeA,IAAM,wBAAA,GAA2B,EAAA;AAG1B,SAAS,gBAAA,CACd,CAAA,EACA,MAAA,EACA,QAAA,EACA,UAAA,EACwB;AACxB,EAAA,MAAM,SAAA,GAAY,CAAA,CAAE,OAAA,CAAQ,wBAAwB,CAAA;AACpD,EAAA,IAAI;AACF,IAAA,MAAM,MAAM,CAAA,CAAE,KAAA;AAAA,MACZ,yBAAA;AAAA,MACA,QAAA;AAAA,MACA,CAAC,QAAA,EAAU,QAAA,EAAU,QAAA,EAAU,QAAQ,CAAA;AAAA,MACvC,CAAC,MAAA,EAAQ,QAAA,EAAU,UAAA,EAAY,SAAS;AAAA,KAC1C;AACA,IAAA,IAAI,GAAA,KAAQ,oBAAoB,OAAO,IAAA;AACvC,IAAA,IAAI,QAAQ,CAAA,EAAG,MAAM,IAAI,KAAA,CAAM,CAAA,0BAAA,EAA6B,GAAG,CAAA,CAAE,CAAA;AACjE,IAAA,OAAO;AAAA,MACL,UAAA,EAAkB,CAAA,CAAE,QAAA,CAAS,SAAA,GAAY,GAAI,OAAO,CAAA;AAAA,MACpD,YAAA,EAAkB,CAAA,CAAE,QAAA,CAAS,SAAA,GAAY,GAAI,OAAO,CAAA;AAAA,MACpD,UAAkB,CAAA,CAAE,QAAA,CAAS,SAAA,GAAY,CAAA,EAAI,IAAI,CAAA,KAAM,CAAA;AAAA,MACvD,eAAkB,CAAA,CAAE,QAAA,CAAS,SAAA,GAAY,CAAA,EAAI,IAAI,CAAA,KAAM,CAAA;AAAA,MACvD,aAAkB,CAAA,CAAE,QAAA,CAAS,SAAA,GAAY,EAAA,EAAI,IAAI,CAAA,KAAM,CAAA;AAAA,MACvD,QAAA,EAAkB,CAAA,CAAE,QAAA,CAAS,SAAA,GAAY,IAAI,KAAK,CAAA;AAAA,MAClD,gBAAA,EAAkB,CAAA,CAAE,QAAA,CAAS,SAAA,GAAY,IAAI,KAAK,CAAA;AAAA,MAClD,cAAA,EAAkB,CAAA,CAAE,QAAA,CAAS,SAAA,GAAY,IAAI,KAAK;AAAA,KACpD;AAAA,EACF,CAAA,SAAE;AACA,IAAA,CAAA,CAAE,MAAM,SAAS,CAAA;AAAA,EACnB;AACF;AAGO,SAAS,cAAA,CAAe,GAAqB,MAAA,EAAwB;AAC1E,EAAA,MAAM,MAAA,GAAS,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA;AAC1B,EAAA,IAAI;AACF,IAAA,MAAM,YAAY,CAAA,CAAE,KAAA;AAAA,MAClB,uBAAA;AAAA,MACA,QAAA;AAAA,MACA,CAAC,UAAU,QAAQ,CAAA;AAAA,MACnB,CAAC,QAAQ,MAAM;AAAA,KACjB;AACA,IAAA,IAAI,CAAC,SAAA,EAAW;AACd,MAAA,MAAM,GAAA,GAAM,CAAA,CAAE,QAAA,CAAS,MAAA,EAAQ,KAAK,CAAA;AACpC,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,wBAAA,EAA2B,gBAAgB,CAAA,EAAG,GAAG,CAAC,CAAA,CAAE,CAAA;AAAA,IACtE;AACA,IAAA,OAAO,SAAA;AAAA,EACT,CAAA,SAAE;AACA,IAAA,CAAA,CAAE,MAAM,MAAM,CAAA;AAAA,EAChB;AACF;AAEO,SAAS,cAAA,CAAe,GAAqB,MAAA,EAAsB;AACxE,EAAA,CAAA,CAAE,KAAA,CAAM,yBAAyB,IAAA,EAAM,CAAC,QAAQ,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAC7D;AAEO,SAAS,gBAAA,CAAiB,GAAqB,MAAA,EAAsB;AAC1E,EAAA,CAAA,CAAE,KAAA,CAAM,2BAA2B,IAAA,EAAM,CAAC,QAAQ,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAC/D;;;ACzqBA,IAAM,WAAA,GAAc,IAAA;AAEb,IAAM,OAAA,GAAN,MAAM,QAAA,CAAQ;AAAA,EAIX,WAAA,CAAY,QAAgB,MAAA,EAAoB;AACtD,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAa,MAAA,CAAO,OAAA,GAAqB,EAAC,EAAqB;AAC7D,IAAA,MAAM,QAAA,EAAS;AACf,IAAA,MAAM,IAAI,SAAA,EAAU;AACpB,IAAA,MAAM,cAAc,MAAM,SAAA,CAAU,OAAO,OAAA,CAAQ,QAAA,EAAU,QAAQ,SAAS,CAAA;AAC9E,IAAA,MAAM,MAAA,GAAS,SAAA,CAAU,CAAA,EAAG,WAAW,CAAA;AACvC,IAAA,MAAM,MAAA,GAAqB;AAAA,MACzB,SAAA,EAAW,OAAA,CAAQ,eAAA,IAAmB,kBAAA,CAAmB,SAAA;AAAA,MACzD,gBAAA,EAAkB,OAAA,CAAQ,gBAAA,IAAoB,kBAAA,CAAmB,gBAAA;AAAA,MACjE,eAAA,EAAiB,OAAA,CAAQ,eAAA,IAAmB,kBAAA,CAAmB,eAAA;AAAA,MAC/D,gBAAA,EAAkB,OAAA,CAAQ,gBAAA,IAAoB,kBAAA,CAAmB,gBAAA;AAAA,MACjE,eAAA,EAAiB,OAAA,CAAQ,eAAA,IAAmB,kBAAA,CAAmB,eAAA;AAAA,MAC/D,kBAAA,EAAoB,OAAA,CAAQ,kBAAA,IAAsB,kBAAA,CAAmB,kBAAA;AAAA,MACrE,kBAAA,EAAoB,OAAA,CAAQ,kBAAA,IAAsB,kBAAA,CAAmB;AAAA,KACvE;AACA,IAAA,OAAO,IAAI,QAAA,CAAQ,MAAA,EAAQ,MAAM,CAAA;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,KAAA,EAA6C;AAClD,IAAA,MAAM,IAAI,SAAA,EAAU;AACpB,IAAA,MAAM,EAAE,GAAA,EAAK,MAAA,EAAQ,QAAO,GAAI,YAAA,CAAa,GAAG,KAAK,CAAA;AAErD,IAAA,IAAI;AACF,MAAA,MAAM,UAAA,GAAa,UAAU,CAAA,EAAG,IAAA,CAAK,QAAQ,GAAA,EAAK,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAQ,MAAM,CAAA;AAC7E,MAAA,OAAO;AAAA,QACL,UAAU,IAAA,CAAK,KAAA,CAAO,MAAA,GAAS,WAAA,GAAe,GAAI,CAAA,GAAI,GAAA;AAAA,QACtD;AAAA,OACF;AAAA,IACF,CAAA,SAAE;AACA,MAAA,CAAA,CAAE,MAAM,GAAG,CAAA;AAAA,IACb;AAAA,EACF;AAAA;AAAA,EAGA,OAAA,GAAgB;AACd,IAAA,IAAI,KAAK,MAAA,EAAQ;AACf,MAAA,UAAA,CAAW,SAAA,EAAU,EAAG,IAAA,CAAK,MAAM,CAAA;AACnC,MAAA,IAAA,CAAK,MAAA,GAAS,CAAA;AAAA,IAChB;AAAA,EACF;AACF;AAIA,SAAS,YAAA,CAAa,GAAQ,KAAA,EAAwF;AACpH,EAAA,MAAM,GAAA,GAAM,KAAA,YAAiB,UAAA,GAAa,wBAAA,CAAyB,KAAK,CAAA,GAAI,KAAA;AAC5E,EAAA,MAAM,GAAA,GAAM,eAAA,CAAgB,CAAA,EAAG,GAAG,CAAA;AAClC,EAAA,OAAO,EAAE,GAAA,EAAK,MAAA,EAAQ,GAAA,CAAI,MAAA,EAAQ,QAAQ,KAAA,EAAM;AAClD;AAEA,SAAS,yBAAyB,GAAA,EAA+B;AAC/D,EAAA,MAAM,GAAA,GAAM,IAAI,YAAA,CAAa,GAAA,CAAI,MAAM,CAAA;AACvC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,CAAI,MAAA,EAAQ,CAAA,EAAA,EAAK,GAAA,CAAI,CAAC,CAAA,GAAI,GAAA,CAAI,CAAC,CAAA,GAAI,KAAA;AACvD,EAAA,OAAO,GAAA;AACT;;;AC7EA,IAAMC,YAAAA,GAAc,IAAA;AAEb,IAAM,aAAA,GAAN,MAAM,cAAA,CAAc;AAAA,EAGjB,YAAY,MAAA,EAAgB;AAClC,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAa,MAAA,CAAO,OAAA,GAA2B,EAAC,EAA2B;AACzE,IAAA,MAAM,QAAA,EAAS;AACf,IAAA,MAAM,IAAI,SAAA,EAAU;AACpB,IAAA,MAAM,cAAc,MAAM,SAAA,CAAU,cAAc,OAAA,CAAQ,QAAA,EAAU,QAAQ,SAAS,CAAA;AACrF,IAAA,MAAM,MAAA,GAAS,eAAA,CAAgB,CAAA,EAAG,WAAA,EAAa;AAAA,MAC7C,WAAkB,OAAA,CAAQ,SAAA;AAAA,MAC1B,kBAAkB,OAAA,CAAQ,gBAAA;AAAA,MAC1B,eAAkB,OAAA,CAAQ,aAAA;AAAA,MAC1B,gBAAkB,OAAA,CAAQ,cAAA;AAAA,MAC1B,gBAAkB,OAAA,CAAQ,cAAA;AAAA,MAC1B,iBAAkB,OAAA,CAAQ;AAAA,KAC3B,CAAA;AACD,IAAA,OAAO,IAAI,eAAc,MAAM,CAAA;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,KAAA,GAAuB;AACrB,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,EAAQ,MAAM,IAAI,MAAM,mCAAmC,CAAA;AACrE,IAAA,MAAM,IAAI,SAAA,EAAU;AACpB,IAAA,MAAM,SAAA,GAAY,cAAA,CAAe,CAAA,EAAG,IAAA,CAAK,MAAM,CAAA;AAC/C,IAAA,OAAO,IAAI,eAAc,SAAS,CAAA;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,aAAa,MAAA,EAAiD;AAC5D,IAAA,MAAM,IAAI,SAAA,EAAU;AACpB,IAAA,MAAM,GAAA,GAAM,CAAA,CAAE,OAAA,CAAQ,MAAA,CAAO,SAAS,CAAC,CAAA;AACvC,IAAA,MAAM,MAAA,GAAS,IAAI,UAAA,CAAW,CAAA,CAAE,OAAO,MAAA,EAAQ,GAAA,EAAK,OAAO,MAAM,CAAA;AACjE,IAAA,MAAA,CAAO,IAAI,MAAM,CAAA;AAEjB,IAAA,IAAI;AACF,MAAA,MAAM,SAAS,gBAAA,CAAiB,CAAA,EAAG,KAAK,MAAA,EAAQ,GAAA,EAAK,OAAO,MAAM,CAAA;AAClE,MAAA,IAAI,CAAC,QAAQ,OAAO,IAAA;AAEpB,MAAA,OAAO;AAAA,QACL,YAAkB,MAAA,CAAO,UAAA;AAAA,QACzB,cAAkB,MAAA,CAAO,YAAA;AAAA,QACzB,UAAkB,MAAA,CAAO,QAAA;AAAA,QACzB,YAAkB,MAAA,CAAO,QAAA;AAAA,QACzB,eAAkB,MAAA,CAAO,aAAA;AAAA,QACzB,aAAkB,MAAA,CAAO,WAAA;AAAA,QACzB,kBAAkB,MAAA,CAAO,gBAAA;AAAA,QACzB,gBAAkB,MAAA,CAAO;AAAA,OAC3B;AAAA,IACF,CAAA,SAAE;AACA,MAAA,CAAA,CAAE,MAAM,GAAG,CAAA;AAAA,IACb;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAW,KAAA,EAAuD;AAChE,IAAA,MAAM,IAAI,SAAA,EAAU;AACpB,IAAA,MAAM,GAAA,GAAM,uBAAuB,KAAK,CAAA;AACxC,IAAA,MAAM,QAAA,GAAW,eAAA,CAAgB,CAAA,EAAG,GAAG,CAAA;AACvC,IAAA,MAAM,WAAA,GAAc,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA;AAC/B,IAAA,MAAM,SAAA,GAAY,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA;AAE7B,IAAA,IAAI;AACF,MAAA,MAAM,MAAM,CAAA,CAAE,KAAA;AAAA,QACZ,6BAAA;AAAA,QACA,QAAA;AAAA,QACA,CAAC,QAAA,EAAU,QAAA,EAAU,QAAA,EAAU,UAAU,QAAQ,CAAA;AAAA,QACjD,CAAC,IAAA,CAAK,MAAA,EAAQ,UAAU,GAAA,CAAI,MAAA,EAAQ,aAAa,SAAS;AAAA,OAC5D;AACA,MAAA,IAAI,QAAQ,CAAA,EAAG,MAAM,IAAI,KAAA,CAAM,CAAA,6BAAA,EAAgC,GAAG,CAAA,CAAE,CAAA;AAEpE,MAAA,MAAM,SAAA,GAAY,CAAA,CAAE,QAAA,CAAS,SAAA,EAAW,KAAK,CAAA;AAC7C,MAAA,MAAM,QAAA,GAAW,CAAA,CAAE,QAAA,CAAS,WAAA,EAAa,KAAK,CAAA;AAC9C,MAAA,MAAM,aAAA,GAAgB,QAAA,GAClB,IAAI,YAAA,CAAa,IAAI,YAAA,CAAa,CAAA,CAAE,MAAA,CAAO,MAAA,EAAQ,UAAU,SAAS,CAAC,CAAA,GACvE,IAAI,aAAa,CAAC,CAAA;AACtB,MAAA,IAAI,QAAA,EAAU,CAAA,CAAE,KAAA,CAAM,QAAQ,CAAA;AAE9B,MAAA,OAAO;AAAA,QACL,aAAA;AAAA,QACA,SAAA;AAAA,QACA,UAAU,IAAA,CAAK,KAAA,CAAO,IAAI,MAAA,GAASA,YAAAA,GAAe,GAAI,CAAA,GAAI;AAAA,OAC5D;AAAA,IACF,CAAA,SAAE;AACA,MAAA,CAAA,CAAE,MAAM,QAAQ,CAAA;AAChB,MAAA,CAAA,CAAE,MAAM,WAAW,CAAA;AACnB,MAAA,CAAA,CAAE,MAAM,SAAS,CAAA;AAAA,IACnB;AAAA,EACF;AAAA;AAAA,EAGA,KAAA,GAAc;AACZ,IAAA,cAAA,CAAe,SAAA,EAAU,EAAG,IAAA,CAAK,MAAM,CAAA;AAAA,EACzC;AAAA;AAAA,EAGA,OAAA,GAAgB;AACd,IAAA,IAAI,KAAK,MAAA,EAAQ;AACf,MAAA,gBAAA,CAAiB,SAAA,EAAU,EAAG,IAAA,CAAK,MAAM,CAAA;AACzC,MAAA,IAAA,CAAK,MAAA,GAAS,CAAA;AAAA,IAChB;AAAA,EACF;AACF;AAEA,SAAS,eAAe,GAAA,EAA+B;AACrD,EAAA,MAAM,GAAA,GAAM,IAAI,YAAA,CAAa,GAAA,CAAI,MAAM,CAAA;AACvC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,CAAI,MAAA,EAAQ,KAAK,GAAA,CAAI,CAAC,CAAA,GAAI,GAAA,CAAI,CAAC,CAAA;AACnD,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,uBAAuB,KAAA,EAAgD;AAC9E,EAAA,IAAI,iBAAiB,UAAA,EAAY;AAC/B,IAAA,OAAO,eAAe,KAAK,CAAA;AAAA,EAC7B;AACA,EAAA,IAAI,iBAAA,CAAkB,KAAK,CAAA,EAAG;AAC5B,IAAA,MAAM,MAAA,GAAS,IAAI,YAAA,CAAa,KAAA,CAAM,MAAM,CAAA;AAC5C,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,MAAA,EAAQ,CAAA,EAAA,EAAK,MAAA,CAAO,CAAC,CAAA,GAAI,KAAA,CAAM,CAAC,CAAA,GAAI,KAAA;AAC9D,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,kBAAkB,KAAA,EAA8B;AACvD,EAAA,MAAM,IAAA,GAAO,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,GAAI,CAAC,CAAA;AACxD,EAAA,IAAI,MAAA,GAAS,CAAA;AACb,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,MAAA,EAAQ,KAAK,IAAA,EAAM;AAC3C,IAAA,MAAM,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,KAAA,CAAM,CAAC,CAAC,CAAA;AAC3B,IAAA,IAAI,CAAA,GAAI,QAAQ,MAAA,GAAS,CAAA;AAAA,EAC3B;AACA,EAAA,OAAO,MAAA,IAAU,CAAA;AACnB;;;ACxJA,IAAMA,YAAAA,GAAc,IAAA;AAEb,IAAM,OAAA,GAAN,MAAM,QAAA,CAAQ;AAAA,EAIX,WAAA,CAAY,QAAgB,MAAA,EAAuB;AACzD,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAa,MAAA,CAAO,OAAA,GAAqB,EAAC,EAAqB;AAC7D,IAAA,MAAM,QAAA,EAAS;AACf,IAAA,MAAM,IAAI,SAAA,EAAU;AACpB,IAAA,MAAM,cAAc,MAAM,SAAA,CAAU,OAAO,OAAA,CAAQ,QAAA,EAAU,QAAQ,SAAS,CAAA;AAC9E,IAAA,MAAM,MAAA,GAAS,SAAA,CAAU,CAAA,EAAG,WAAW,CAAA;AAEvC,IAAA,MAAM,IAAA,GAAO;AAAA,MACX,gBAAA,EAAkB,OAAA,CAAQ,gBAAA,IAAoB,kBAAA,CAAmB,gBAAA;AAAA,MACjE,eAAA,EAAiB,OAAA,CAAQ,eAAA,IAAmB,kBAAA,CAAmB,eAAA;AAAA,MAC/D,gBAAA,EAAkB,OAAA,CAAQ,gBAAA,IAAoB,kBAAA,CAAmB,gBAAA;AAAA,MACjE,eAAA,EAAiB,OAAA,CAAQ,eAAA,IAAmB,kBAAA,CAAmB,eAAA;AAAA,MAC/D,kBAAA,EAAoB,OAAA,CAAQ,kBAAA,IAAsB,kBAAA,CAAmB,kBAAA;AAAA,MACrE,kBAAA,EAAoB,OAAA,CAAQ,kBAAA,IAAsB,kBAAA,CAAmB;AAAA,KACvE;AAEA,IAAA,MAAM,MAAA,GAAwB;AAAA,MAC5B,QAAQ,EAAE,GAAG,MAAM,SAAA,EAAW,OAAA,CAAQ,mBAAmB,GAAA,EAAI;AAAA,MAC7D,SAAS,EAAE,GAAG,MAAM,SAAA,EAAW,OAAA,CAAQ,oBAAoB,GAAA,EAAI;AAAA,MAC/D,OAAO,EAAE,GAAG,MAAM,SAAA,EAAW,OAAA,CAAQ,kBAAkB,GAAA;AAAI,KAC7D;AACA,IAAA,OAAO,IAAI,QAAA,CAAQ,MAAA,EAAQ,MAAM,CAAA;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,KAAA,EAA6C;AAClD,IAAA,MAAM,IAAI,SAAA,EAAU;AACpB,IAAA,MAAM,EAAE,GAAA,EAAK,MAAA,EAAQ,QAAO,GAAIC,aAAAA,CAAa,GAAG,KAAK,CAAA;AACrD,IAAA,MAAM,WAAW,IAAA,CAAK,KAAA,CAAO,MAAA,GAASD,YAAAA,GAAe,GAAI,CAAA,GAAI,GAAA;AAE7D,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,UAAU,CAAA,EAAG,IAAA,CAAK,QAAQ,GAAA,EAAK,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAQ,MAAM,CAAA;AACzE,MAAA,OAAO;AAAA,QACL,QAAA;AAAA,QACA,MAAA;AAAA,QACA,MAAA,EAAQ,qBAAA,CAAsB,MAAA,EAAQ,QAAQ;AAAA,OAChD;AAAA,IACF,CAAA,SAAE;AACA,MAAA,CAAA,CAAE,MAAM,GAAG,CAAA;AAAA,IACb;AAAA,EACF;AAAA;AAAA,EAGA,OAAA,GAAgB;AACd,IAAA,IAAI,KAAK,MAAA,EAAQ;AACf,MAAA,UAAA,CAAW,SAAA,EAAU,EAAG,IAAA,CAAK,MAAM,CAAA;AACnC,MAAA,IAAA,CAAK,MAAA,GAAS,CAAA;AAAA,IAChB;AAAA,EACF;AACF;AAGA,SAASC,aAAAA,CAAa,GAAQ,KAAA,EAAwF;AACpH,EAAA,MAAM,GAAA,GAAM,KAAA,YAAiB,UAAA,GAAaC,yBAAAA,CAAyB,KAAK,CAAA,GAAI,KAAA;AAC5E,EAAA,MAAM,GAAA,GAAM,CAAA,CAAE,OAAA,CAAQ,GAAA,CAAI,SAAS,CAAC,CAAA;AACpC,EAAA,MAAM,IAAA,GAAO,IAAI,YAAA,CAAa,CAAA,CAAE,OAAO,MAAA,EAAQ,GAAA,EAAK,IAAI,MAAM,CAAA;AAC9D,EAAA,IAAA,CAAK,IAAI,GAAG,CAAA;AACZ,EAAA,OAAO,EAAE,GAAA,EAAK,MAAA,EAAQ,GAAA,CAAI,MAAA,EAAQ,QAAQ,KAAA,EAAM;AAClD;AAEA,SAASA,0BAAyB,GAAA,EAA+B;AAC/D,EAAA,MAAM,GAAA,GAAM,IAAI,YAAA,CAAa,GAAA,CAAI,MAAM,CAAA;AACvC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,CAAI,MAAA,EAAQ,CAAA,EAAA,EAAK,GAAA,CAAI,CAAC,CAAA,GAAI,GAAA,CAAI,CAAC,CAAA,GAAI,KAAA;AACvD,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,qBAAA,CACP,QACA,QAAA,EACwB;AACxB,EAAA,MAAM,MAAA,GAAiC;AAAA,IACrC,MAAA,EAAQ,CAAA;AAAA,IACR,OAAA,EAAS,CAAA;AAAA,IACT,KAAA,EAAO;AAAA,GACT;AAEA,EAAA,IAAI,QAAA,IAAY,GAAG,OAAO,MAAA;AAE1B,EAAA,KAAA,MAAW,GAAA,IAAO,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,EAAG;AACrC,IAAA,MAAM,OAAA,GAAA,CAAW,OAAO,GAAG,CAAA,IAAK,EAAC,EAAG,MAAA,CAAO,CAAC,GAAA,EAAK,CAAC,OAAO,GAAG,CAAA,KAAM,MAAM,IAAA,CAAK,GAAA,CAAI,GAAG,GAAA,GAAM,KAAK,GAAG,CAAC,CAAA;AACnG,IAAA,MAAA,CAAO,GAAG,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,OAAA,GAAU,QAAQ,CAAA,GAAI,GAAG,CAAA,GAAI,GAAA;AAAA,EACpE;AAEA,EAAA,OAAO,MAAA;AACT;;;ACnFA,eAAsB,WAAA,CACpB,QAAA,EACA,OAAA,GAAwB,EAAC,EACD;AACxB,EAAA,MAAM,QAAA,EAAS;AACf,EAAA,MAAM,IAAI,SAAA,EAAU;AAEpB,EAAA,MAAM,GAAA,GAAmB;AAAA,IACvB,YAAA,EAAiB,OAAA,CAAQ,YAAA,IAAmB,oBAAA,CAAqB,YAAA;AAAA,IACjE,UAAA,EAAiB,OAAA,CAAQ,UAAA,IAAmB,oBAAA,CAAqB,UAAA;AAAA,IACjE,YAAA,EAAiB,OAAA,CAAQ,YAAA,IAAmB,oBAAA,CAAqB,YAAA;AAAA,IACjE,aAAA,EAAiB,OAAA,CAAQ,aAAA,IAAmB,oBAAA,CAAqB,aAAA;AAAA,IACjE,aAAA,EAAiB,OAAA,CAAQ,aAAA,IAAmB,oBAAA,CAAqB,aAAA;AAAA,IACjE,cAAA,EAAiB,OAAA,CAAQ,cAAA,IAAmB,oBAAA,CAAqB,cAAA;AAAA,IACjE,IAAA,EAAiB,OAAA,CAAQ,IAAA,IAAmB,oBAAA,CAAqB;AAAA,GACnE;AAEA,EAAA,MAAM,OAAA,GAAU,UAAA,CAAW,CAAA,EAAG,QAAA,EAAU,GAAG,CAAA;AAC3C,EAAA,OAAO,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,IACzB,OAAO,CAAA,CAAE,KAAA;AAAA,IACT,KAAK,CAAA,CAAE,GAAA;AAAA,IACP,aAAa,CAAA,CAAE,WAAA;AAAA,IACf,UAAU,CAAA,CAAE;AAAA,GACd,CAAE,CAAA;AACJ","file":"index.cjs","sourcesContent":["/**\n * Low-level WASM binding for omnivad C API.\n * Loads the Emscripten module and provides typed wrappers.\n */\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype EmscriptenModule = any;\n\nlet _module: EmscriptenModule | null = null;\nlet _loading: Promise<EmscriptenModule> | null = null;\n\n/**\n * Browser-side classic-script loader. Used to pull in Emscripten's IIFE\n * glue (`var createOmniVAD = (() => {...})()`) without going through\n * `import()` — see initWasm()'s long comment.\n *\n * Works in both DOM contexts (main thread) and worker contexts: in a\n * Worker we fall back to `importScripts(url)` which is synchronous but\n * still wrapped in a Promise for API uniformity.\n */\nfunction loadScript(url: string): Promise<void> {\n // Worker path.\n if (typeof globalThis.document === \"undefined\") {\n return new Promise<void>((resolve, reject) => {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const importScripts = (globalThis as any).importScripts as\n | ((u: string) => void)\n | undefined;\n if (typeof importScripts !== \"function\") {\n throw new Error(\n \"omnivad: cannot load glue script — no document and no importScripts\",\n );\n }\n importScripts(url);\n resolve();\n } catch (err) {\n reject(err instanceof Error ? err : new Error(String(err)));\n }\n });\n }\n // Main thread path.\n return new Promise<void>((resolve, reject) => {\n const s = globalThis.document!.createElement(\"script\");\n s.src = url;\n s.async = true;\n s.crossOrigin = \"anonymous\";\n s.onload = () => resolve();\n s.onerror = () =>\n reject(new Error(`Failed to load omnivad glue script: ${url}`));\n globalThis.document!.head.appendChild(s);\n });\n}\n\n/** Post-processing config matching C struct OmniPostConfig (7 x i32/float, 28 bytes) */\nexport interface PostConfig {\n threshold: number;\n smoothWindowSize: number;\n minSpeechFrames: number;\n minSilenceFrames: number;\n maxSpeechFrames: number;\n mergeSilenceFrames: number;\n extendSpeechFrames: number;\n}\n\nconst SIZEOF_POST_CONFIG = 28; // 7 * 4 bytes\nconst SIZEOF_AED_POST_CONFIG = 3 * SIZEOF_POST_CONFIG; // 84 bytes\nconst SIZEOF_SEGMENT = 8; // start(f32) + end(f32)\nconst SIZEOF_AED_SEGMENT = 16; // start(f32) + end(f32) + cls(i32) + confidence(f32)\nconst SIZEOF_CHUNK_CONFIG = 28; // 6 floats + 1 i32 mode\nconst SIZEOF_CHUNK = 16; // start(f32) + end(f32) + seg_start_idx(i32) + seg_count(i32)\n\n/** Re-exported for ABI self-tests. */\nexport const _SIZEOF_CHUNK_CONFIG = SIZEOF_CHUNK_CONFIG;\nexport const _SIZEOF_CHUNK = SIZEOF_CHUNK;\nconst OMNI_ERR_NO_FRAMES = -7;\n\n/** Package version — used to construct default CDN URLs. */\nexport const VERSION = \"0.2.9\";\n\n/** Default CDN base for model files (jsDelivr serves npm package contents). */\nexport const DEFAULT_CDN_BASE = `https://cdn.jsdelivr.net/npm/omnivad@${VERSION}/models`;\n\n/** Model filenames keyed by type. */\nexport const MODEL_FILES = {\n vad: \"vad.omnivad\",\n \"stream-vad\": \"stream-vad.omnivad\",\n aed: \"aed.omnivad\",\n} as const;\n\nexport type ModelType = keyof typeof MODEL_FILES;\n\n/**\n * Initialize the WASM module. Call once before using any other functions.\n * Safe to call multiple times (returns cached module).\n */\nexport async function initWasm(\n wasmLocator?: (filename: string) => string,\n): Promise<EmscriptenModule> {\n if (_module) return _module;\n if (_loading) return _loading;\n\n _loading = (async () => {\n // Dynamic import of the Emscripten glue\n let createOmniVAD: (opts?: Record<string, unknown>) => Promise<EmscriptenModule>;\n let defaultLocateFile: ((filename: string) => string) | undefined;\n\n if (typeof globalThis.process?.versions?.node === \"string\") {\n // Node.js: use require for .cjs (avoids ESM detection issues)\n const { createRequire } = await import(/* webpackIgnore: true */ /* turbopackIgnore: true */ \"module\");\n const { dirname, join } = await import(/* webpackIgnore: true */ /* turbopackIgnore: true */ \"path\");\n const req = createRequire(import.meta.url);\n const gluePath = req.resolve(\"../dist/wasm/omnivad.cjs\");\n const wasmDir = dirname(gluePath);\n createOmniVAD = req(gluePath);\n defaultLocateFile = (filename: string) => join(wasmDir, filename);\n } else {\n // Browser. We can't `await import()` the glue: Emscripten with\n // MODULARIZE=1 (no EXPORT_ES6=1) emits an IIFE\n // var createOmniVAD = (() => { ... })();\n // which has zero ES exports, so dynamic import yields an empty\n // module record and `mod.default || mod` is the empty namespace\n // object → `createOmniVAD()` throws \"is not a function\".\n //\n // Solution: classic <script> injection, then read the global the\n // IIFE wrote to (`globalThis.createOmniVAD`). Caches via the global\n // so repeat callers don't re-fetch the script.\n let glueUrlStr: string;\n if (wasmLocator) {\n glueUrlStr = wasmLocator(\"omnivad.js\");\n } else {\n // Native ESM resolution path (when consumed without a bundler).\n glueUrlStr = new URL(\"../dist/wasm/omnivad.js\", import.meta.url).href;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const g = globalThis as any;\n let factory: ((opts?: Record<string, unknown>) => Promise<EmscriptenModule>) | undefined =\n g.createOmniVAD;\n if (typeof factory !== \"function\") {\n await loadScript(glueUrlStr);\n factory = g.createOmniVAD;\n }\n if (typeof factory !== \"function\") {\n throw new Error(\n `omnivad.js loaded from ${glueUrlStr} but globalThis.createOmniVAD is missing`,\n );\n }\n createOmniVAD = factory;\n // glueUrlStr may already be absolute (when wasmLocator returns a\n // full URL) or relative (native ESM mode). new URL(\"./\", abs) is\n // safe; new URL(\"./\", path-relative) throws — guard with a base.\n const baseHref =\n typeof globalThis.location !== \"undefined\"\n ? globalThis.location.href\n : \"file:///\";\n const absGlue = new URL(glueUrlStr, baseHref);\n const wasmBaseUrl = new URL(\"./\", absGlue);\n defaultLocateFile = (filename: string) => new URL(filename, wasmBaseUrl).toString();\n }\n\n const opts: Record<string, unknown> = {};\n const locateFile = wasmLocator ?? defaultLocateFile;\n if (locateFile) {\n opts.locateFile = (path: string) => locateFile(path);\n }\n\n _module = await createOmniVAD(opts);\n return _module!;\n })();\n\n return _loading;\n}\n\n/**\n * Load a model file as ArrayBuffer.\n *\n * Resolution order:\n * 1. modelData (ArrayBuffer) — use directly\n * 2. modelUrl (string/URL) — fetch from that URL\n * 3. Node.js — read from npm package's models/ directory\n * 4. Browser — fetch from jsDelivr CDN\n */\nexport async function loadModel(\n modelType: ModelType,\n modelUrl?: string | URL,\n modelData?: ArrayBuffer,\n): Promise<ArrayBuffer> {\n if (modelData) return modelData;\n\n if (modelUrl) {\n const resp = await fetch(modelUrl.toString());\n if (!resp.ok) throw new Error(`Failed to fetch model from ${modelUrl}: ${resp.status}`);\n return resp.arrayBuffer();\n }\n\n const filename = MODEL_FILES[modelType];\n\n if (typeof globalThis.process?.versions?.node === \"string\") {\n // Node.js: read from package's models/ directory\n const { createRequire } = await import(/* webpackIgnore: true */ /* turbopackIgnore: true */ \"module\");\n const { dirname, join } = await import(/* webpackIgnore: true */ /* turbopackIgnore: true */ \"path\");\n const { readFile } = await import(/* webpackIgnore: true */ /* turbopackIgnore: true */ \"fs/promises\");\n const req = createRequire(import.meta.url);\n const pkgDir = dirname(req.resolve(\"../package.json\"));\n const modelPath = join(pkgDir, \"models\", filename);\n const buf = await readFile(modelPath);\n return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);\n }\n\n // Browser: fetch from CDN\n const url = `${DEFAULT_CDN_BASE}/${filename}`;\n const resp = await fetch(url);\n if (!resp.ok) throw new Error(`Failed to fetch model from ${url}: ${resp.status}`);\n return resp.arrayBuffer();\n}\n\n/** Get the initialized WASM module (throws if not initialized) */\nexport function getModule(): EmscriptenModule {\n if (!_module) throw new Error(\"WASM not initialized. Call initWasm() first.\");\n return _module;\n}\n\nfunction readNativeError(M: EmscriptenModule, code: number): string {\n const msg = M.ccall(\"omni_error_string\", \"string\", [\"number\"], [code]);\n return msg ? `${msg} (${code})` : `error ${code}`;\n}\n\n/** Shared helper: call a C create function with out_error, throw on failure. */\nfunction createModel(\n M: EmscriptenModule,\n fnName: string,\n argTypes: string[],\n args: unknown[],\n label: string,\n): number {\n const errPtr = M._malloc(4);\n try {\n const handle = M.ccall(fnName, \"number\", [...argTypes, \"number\"], [...args, errPtr]);\n if (!handle) {\n const err = M.getValue(errPtr, \"i32\");\n throw new Error(`Failed to create ${label} model: ${readNativeError(M, err)}`);\n }\n return handle;\n } finally {\n M._free(errPtr);\n }\n}\n\n// -------------------------------------------------------------------------- //\n// Memory helpers //\n// -------------------------------------------------------------------------- //\n\n/** Copy Float32Array audio into WASM heap, returns pointer. Caller must free. */\nexport function copyAudioToHeap(M: EmscriptenModule, audio: Float32Array): number {\n const ptr = M._malloc(audio.length * 4);\n const heap = new Float32Array(M.HEAPU8.buffer, ptr, audio.length);\n heap.set(audio);\n return ptr;\n}\n\n/** Write PostConfig struct to WASM heap at ptr */\nexport function writePostConfig(M: EmscriptenModule, ptr: number, cfg: PostConfig): void {\n M.setValue(ptr + 0, cfg.threshold, \"float\");\n M.setValue(ptr + 4, cfg.smoothWindowSize, \"i32\");\n M.setValue(ptr + 8, cfg.minSpeechFrames, \"i32\");\n M.setValue(ptr + 12, cfg.minSilenceFrames, \"i32\");\n M.setValue(ptr + 16, cfg.maxSpeechFrames, \"i32\");\n M.setValue(ptr + 20, cfg.mergeSilenceFrames, \"i32\");\n M.setValue(ptr + 24, cfg.extendSpeechFrames, \"i32\");\n}\n\nexport const DEFAULT_VAD_CONFIG: PostConfig = {\n threshold: 0.4,\n smoothWindowSize: 5,\n minSpeechFrames: 20,\n minSilenceFrames: 20,\n maxSpeechFrames: 3000,\n mergeSilenceFrames: 0,\n extendSpeechFrames: 0,\n};\n\n// -------------------------------------------------------------------------- //\n// Chunking (pure-algorithm, mirrors omnivad.h's omni_merge_chunks) //\n// -------------------------------------------------------------------------- //\n\n/** OmniChunkMode enum values (must match native/include/omnivad.h). */\nexport const OMNI_CHUNK_GREEDY = 0;\nexport const OMNI_CHUNK_LONGEST_GAP = 1;\n\n/**\n * Chunking strategy:\n * - \"greedy\" — sequential append. Recommended for fixed-length-input ASR\n * (Whisper / whisperX, which pad to 30s anyway).\n * - \"longest_gap\" — recursive split at longest pause; falls back to hard-split\n * when a single segment exceeds maxChunkSecs. Recommended for\n * variable-length-input models (forced alignment, TTS,\n * encoder-style ASR); no fixed-length padding required.\n */\nexport type ChunkMode = \"greedy\" | \"longest_gap\";\n\n/** Configuration for omni_merge_chunks (matches C struct OmniChunkConfig, 28 bytes) */\nexport interface ChunkConfig {\n maxChunkSecs: number; // hard upper bound on chunk duration (seconds), > 0\n maxGapSecs: number; // split if gap > this. Infinity disables. Honored by both modes.\n padOnsetSecs: number; // extend chunk start backward (clamped >= 0)\n padOffsetSecs: number; // extend chunk end forward\n minSpeechSecs: number; // drop input segments shorter than this; pairs with VAD minSpeechFrames\n minSilenceSecs: number; // pre-merge gaps shorter than this; pairs with VAD minSilenceFrames\n mode: ChunkMode; // packing strategy (default \"greedy\")\n}\n\n/**\n * Default chunk config. Mirrors C-side omni_chunk_config_default(); kept in\n * TS so callers don't need a roundtrip into WASM just to read defaults.\n *\n * Defaults: max_chunk_secs matches Whisper's 30s input window.\n */\nexport const DEFAULT_CHUNK_CONFIG: ChunkConfig = {\n maxChunkSecs: 30.0,\n maxGapSecs: Infinity,\n padOnsetSecs: 0.04,\n padOffsetSecs: 0.04,\n minSpeechSecs: 0.0,\n minSilenceSecs: 0.20, // matches VAD minSilenceFrames=20 @ 10ms shift\n mode: \"greedy\",\n};\n\nfunction modeToInt(m: ChunkMode): number {\n switch (m) {\n case \"greedy\": return OMNI_CHUNK_GREEDY;\n case \"longest_gap\": return OMNI_CHUNK_LONGEST_GAP;\n default: throw new Error(`Unknown chunking mode: ${String(m)}`);\n }\n}\n\n/** Write ChunkConfig struct to WASM heap at ptr (must be SIZEOF_CHUNK_CONFIG bytes). */\nexport function writeChunkConfig(M: EmscriptenModule, ptr: number, cfg: ChunkConfig): void {\n M.setValue(ptr + 0, cfg.maxChunkSecs, \"float\");\n M.setValue(ptr + 4, cfg.maxGapSecs, \"float\");\n M.setValue(ptr + 8, cfg.padOnsetSecs, \"float\");\n M.setValue(ptr + 12, cfg.padOffsetSecs, \"float\");\n M.setValue(ptr + 16, cfg.minSpeechSecs, \"float\");\n M.setValue(ptr + 20, cfg.minSilenceSecs, \"float\");\n M.setValue(ptr + 24, modeToInt(cfg.mode), \"i32\");\n}\n\nexport interface ChunkRecord {\n start: number;\n end: number;\n segStartIdx: number;\n segCount: number;\n}\n\n/**\n * Call omni_merge_chunks via the WASM module.\n *\n * @param segments array of [start, end] pairs, sorted by start (caller's contract)\n * @param config chunking configuration\n * @returns array of ChunkRecord. On C error, throws.\n */\nexport function chunkMerge(\n M: EmscriptenModule,\n segments: Array<[number, number]>,\n config: ChunkConfig,\n): ChunkRecord[] {\n const numSegments = segments.length;\n\n const segPtr = numSegments > 0 ? M._malloc(numSegments * SIZEOF_SEGMENT) : 0;\n const cfgPtr = M._malloc(SIZEOF_CHUNK_CONFIG);\n const outPtrPtr = M._malloc(4); // pointer to OmniChunk*\n const outCountPtr = M._malloc(4);\n\n try {\n for (let i = 0; i < numSegments; i++) {\n const base = segPtr + i * SIZEOF_SEGMENT;\n M.setValue(base + 0, segments[i][0], \"float\");\n M.setValue(base + 4, segments[i][1], \"float\");\n }\n writeChunkConfig(M, cfgPtr, config);\n M.setValue(outPtrPtr, 0, \"i32\");\n M.setValue(outCountPtr, 0, \"i32\");\n\n const rc = M.ccall(\n \"omni_merge_chunks\",\n \"number\",\n [\"number\", \"number\", \"number\", \"number\", \"number\"],\n [segPtr, numSegments, cfgPtr, outPtrPtr, outCountPtr],\n );\n if (rc !== 0) {\n throw new Error(`omni_merge_chunks failed: ${readNativeError(M, rc)}`);\n }\n\n const count = M.getValue(outCountPtr, \"i32\");\n const chunkPtr = M.getValue(outPtrPtr, \"i32\");\n const chunks: ChunkRecord[] = [];\n for (let i = 0; i < count; i++) {\n const base = chunkPtr + i * SIZEOF_CHUNK;\n chunks.push({\n start: M.getValue(base + 0, \"float\"),\n end: M.getValue(base + 4, \"float\"),\n segStartIdx: M.getValue(base + 8, \"i32\"),\n segCount: M.getValue(base + 12, \"i32\"),\n });\n }\n if (chunkPtr) M._free(chunkPtr);\n return chunks;\n } finally {\n if (segPtr) M._free(segPtr);\n M._free(cfgPtr);\n M._free(outPtrPtr);\n M._free(outCountPtr);\n }\n}\n\n// -------------------------------------------------------------------------- //\n// Non-stream VAD //\n// -------------------------------------------------------------------------- //\n\nexport function vadCreate(M: EmscriptenModule, modelBuffer: ArrayBuffer): number {\n const bytes = new Uint8Array(modelBuffer);\n const ptr = M._malloc(bytes.length);\n M.HEAPU8.set(bytes, ptr);\n try {\n return createModel(M, \"omni_vad_create_from_buffer\", [\"number\", \"number\"], [ptr, bytes.length], \"VAD\");\n } finally {\n M._free(ptr);\n }\n}\n\n/**\n * Audio format: two types only.\n * \"f32\" — float* in [-1.0, 1.0] (Web Audio API, soundfile, torch)\n * \"int16\" — int16_t* PCM (WAV files, microphones)\n */\nexport type AudioFormat = \"f32\" | \"int16\";\n\nfunction readSegments(M: EmscriptenModule, segPtrPtr: number, countPtr: number): Array<[number, number]> {\n const count = M.getValue(countPtr, \"i32\");\n const segPtr = M.getValue(segPtrPtr, \"i32\");\n const segments: Array<[number, number]> = [];\n for (let i = 0; i < count; i++) {\n const base = segPtr + i * SIZEOF_SEGMENT;\n segments.push([\n Math.round(M.getValue(base, \"float\") * 1000) / 1000,\n Math.round(M.getValue(base + 4, \"float\") * 1000) / 1000,\n ]);\n }\n if (segPtr) M._free(segPtr);\n return segments;\n}\n\nexport function vadDetect(\n M: EmscriptenModule,\n handle: number,\n audioPtr: number,\n numSamples: number,\n cfg: PostConfig,\n format: AudioFormat = \"f32\",\n): Array<[number, number]> {\n const cfgPtr = M._malloc(SIZEOF_POST_CONFIG);\n const segPtrPtr = M._malloc(4);\n const countPtr = M._malloc(4);\n const fn = format === \"int16\" ? \"omni_vad_detect_int16\" : \"omni_vad_detect\";\n\n try {\n writePostConfig(M, cfgPtr, cfg);\n const ret = M.ccall(\n fn,\n \"number\",\n [\"number\", \"number\", \"number\", \"number\", \"number\", \"number\"],\n [handle, audioPtr, numSamples, cfgPtr, segPtrPtr, countPtr],\n );\n if (ret !== 0) throw new Error(`VAD detect failed: ${ret}`);\n return readSegments(M, segPtrPtr, countPtr);\n } finally {\n M._free(cfgPtr);\n M._free(segPtrPtr);\n M._free(countPtr);\n }\n}\n\nexport function vadDestroy(M: EmscriptenModule, handle: number): void {\n M.ccall(\"omni_vad_destroy\", null, [\"number\"], [handle]);\n}\n\n// -------------------------------------------------------------------------- //\n// Non-stream AED //\n// -------------------------------------------------------------------------- //\n\nconst AED_CLASSES: Record<number, string> = { 0: \"speech\", 1: \"singing\", 2: \"music\" };\n\nexport function aedCreate(M: EmscriptenModule, modelBuffer: ArrayBuffer): number {\n const bytes = new Uint8Array(modelBuffer);\n const ptr = M._malloc(bytes.length);\n M.HEAPU8.set(bytes, ptr);\n try {\n return createModel(M, \"omni_aed_create_from_buffer\", [\"number\", \"number\"], [ptr, bytes.length], \"AED\");\n } finally {\n M._free(ptr);\n }\n}\n\nexport interface AedPostConfig {\n speech: PostConfig;\n singing: PostConfig;\n music: PostConfig;\n}\n\nexport function aedDetect(\n M: EmscriptenModule,\n handle: number,\n audioPtr: number,\n numSamples: number,\n cfg: AedPostConfig,\n format: AudioFormat = \"f32\",\n): Record<string, Array<[number, number]>> {\n const cfgPtr = M._malloc(SIZEOF_AED_POST_CONFIG);\n const segPtrPtr = M._malloc(4);\n const countPtr = M._malloc(4);\n const fn = format === \"int16\" ? \"omni_aed_detect_int16\" : \"omni_aed_detect\";\n\n try {\n writePostConfig(M, cfgPtr, cfg.speech);\n writePostConfig(M, cfgPtr + SIZEOF_POST_CONFIG, cfg.singing);\n writePostConfig(M, cfgPtr + 2 * SIZEOF_POST_CONFIG, cfg.music);\n\n const ret = M.ccall(\n fn,\n \"number\",\n [\"number\", \"number\", \"number\", \"number\", \"number\", \"number\"],\n [handle, audioPtr, numSamples, cfgPtr, segPtrPtr, countPtr],\n );\n if (ret !== 0) throw new Error(`AED detect failed: ${ret}`);\n\n const count = M.getValue(countPtr, \"i32\");\n const segPtr = M.getValue(segPtrPtr, \"i32\");\n const events: Record<string, Array<[number, number]>> = {\n speech: [],\n singing: [],\n music: [],\n };\n for (let i = 0; i < count; i++) {\n const base = segPtr + i * SIZEOF_AED_SEGMENT;\n const cls = M.getValue(base + 8, \"i32\");\n const name = AED_CLASSES[cls];\n if (name && events[name]) {\n events[name].push([\n Math.round(M.getValue(base, \"float\") * 1000) / 1000,\n Math.round(M.getValue(base + 4, \"float\") * 1000) / 1000,\n ]);\n }\n }\n if (segPtr) M._free(segPtr);\n return events;\n } finally {\n M._free(cfgPtr);\n M._free(segPtrPtr);\n M._free(countPtr);\n }\n}\n\nexport function aedDestroy(M: EmscriptenModule, handle: number): void {\n M.ccall(\"omni_aed_destroy\", null, [\"number\"], [handle]);\n}\n\n// -------------------------------------------------------------------------- //\n// Stream VAD //\n// -------------------------------------------------------------------------- //\n\n/** OmniStreamVadConfig — bit-identical to upstream FireRedStreamVadConfig. */\nexport interface StreamVadConfig {\n threshold: number;\n smoothWindowSize: number;\n padStartFrame: number;\n minSpeechFrame: number;\n maxSpeechFrame: number;\n minSilenceFrame: number;\n}\n\n/** Defaults match upstream FireRedStreamVadConfig. */\nexport const DEFAULT_STREAM_VAD_CONFIG: StreamVadConfig = {\n threshold: 0.5,\n smoothWindowSize: 5,\n padStartFrame: 5,\n minSpeechFrame: 8,\n maxSpeechFrame: 2000,\n minSilenceFrame: 20,\n};\n\nconst SIZEOF_STREAM_VAD_CONFIG = 24; // float + 5 i32\n\nfunction writeStreamVadConfig(M: EmscriptenModule, ptr: number, cfg: StreamVadConfig): void {\n M.setValue(ptr + 0, cfg.threshold, \"float\");\n M.setValue(ptr + 4, cfg.smoothWindowSize, \"i32\");\n M.setValue(ptr + 8, cfg.padStartFrame, \"i32\");\n M.setValue(ptr + 12, cfg.minSpeechFrame, \"i32\");\n M.setValue(ptr + 16, cfg.maxSpeechFrame, \"i32\");\n M.setValue(ptr + 20, cfg.minSilenceFrame, \"i32\");\n}\n\nexport function streamVadCreate(\n M: EmscriptenModule,\n modelBuffer: ArrayBuffer,\n config: Partial<StreamVadConfig> = {},\n): number {\n // Skip undefined overrides — callers often relay optional kwargs that may\n // be `undefined`, and spreading those would clobber the upstream defaults.\n const overrides = Object.fromEntries(\n Object.entries(config).filter(([, v]) => v !== undefined),\n );\n const cfg: StreamVadConfig = { ...DEFAULT_STREAM_VAD_CONFIG, ...overrides };\n const bytes = new Uint8Array(modelBuffer);\n const dataPtr = M._malloc(bytes.length);\n M.HEAPU8.set(bytes, dataPtr);\n const cfgPtr = M._malloc(SIZEOF_STREAM_VAD_CONFIG);\n try {\n writeStreamVadConfig(M, cfgPtr, cfg);\n return createModel(\n M,\n \"omni_stream_vad_create_from_buffer\",\n [\"number\", \"number\", \"number\"],\n [dataPtr, bytes.length, cfgPtr],\n \"StreamVAD\",\n );\n } finally {\n M._free(dataPtr);\n M._free(cfgPtr);\n }\n}\n\n/** Per-frame result from streaming VAD. Bit-identical to upstream\n * StreamVadFrameResult: includes segment-boundary events. */\nexport interface StreamVadResult {\n confidence: number;\n smoothedProb: number;\n isSpeech: boolean;\n isSpeechStart: boolean;\n isSpeechEnd: boolean;\n frameIdx: number;\n speechStartFrame: number;\n speechEndFrame: number;\n}\n\nconst SIZEOF_STREAM_VAD_RESULT = 24; // 2*float + 3*bool + 1pad + 3*i32\n\n/** Process one chunk of int16 PCM (160 samples = 10ms). Returns null if buffering. */\nexport function streamVadProcess(\n M: EmscriptenModule,\n handle: number,\n pcm16Ptr: number,\n numSamples: number,\n): StreamVadResult | null {\n const resultPtr = M._malloc(SIZEOF_STREAM_VAD_RESULT);\n try {\n const ret = M.ccall(\n \"omni_stream_vad_process\",\n \"number\",\n [\"number\", \"number\", \"number\", \"number\"],\n [handle, pcm16Ptr, numSamples, resultPtr],\n );\n if (ret === OMNI_ERR_NO_FRAMES) return null;\n if (ret !== 0) throw new Error(`StreamVAD process failed: ${ret}`);\n return {\n confidence: M.getValue(resultPtr + 0, \"float\"),\n smoothedProb: M.getValue(resultPtr + 4, \"float\"),\n isSpeech: M.getValue(resultPtr + 8, \"i8\") !== 0,\n isSpeechStart: M.getValue(resultPtr + 9, \"i8\") !== 0,\n isSpeechEnd: M.getValue(resultPtr + 10, \"i8\") !== 0,\n frameIdx: M.getValue(resultPtr + 12, \"i32\"),\n speechStartFrame: M.getValue(resultPtr + 16, \"i32\"),\n speechEndFrame: M.getValue(resultPtr + 20, \"i32\"),\n };\n } finally {\n M._free(resultPtr);\n }\n}\n\n/** Clone a stream VAD handle (shares model weights, fresh per-instance state). */\nexport function streamVadClone(M: EmscriptenModule, handle: number): number {\n const errPtr = M._malloc(4);\n try {\n const newHandle = M.ccall(\n \"omni_stream_vad_clone\",\n \"number\",\n [\"number\", \"number\"],\n [handle, errPtr],\n );\n if (!newHandle) {\n const err = M.getValue(errPtr, \"i32\");\n throw new Error(`StreamVAD clone failed: ${readNativeError(M, err)}`);\n }\n return newHandle;\n } finally {\n M._free(errPtr);\n }\n}\n\nexport function streamVadReset(M: EmscriptenModule, handle: number): void {\n M.ccall(\"omni_stream_vad_reset\", null, [\"number\"], [handle]);\n}\n\nexport function streamVadDestroy(M: EmscriptenModule, handle: number): void {\n M.ccall(\"omni_stream_vad_destroy\", null, [\"number\"], [handle]);\n}\n","/**\n * Non-streaming Voice Activity Detection (WASM/ncnn backend).\n *\n * Audio format:\n * - Int16Array: raw 16-bit PCM, converted to normalized float internally\n * - Float32Array in [-1.0, 1.0]: normalized audio (Web Audio API format)\n */\n\nimport type { VADConfig, VADResult } from \"./types.js\";\nimport {\n initWasm,\n getModule,\n copyAudioToHeap,\n loadModel,\n vadCreate,\n vadDetect,\n vadDestroy,\n DEFAULT_VAD_CONFIG,\n type AudioFormat,\n type PostConfig,\n} from \"./wasm-binding.js\";\n\nconst SAMPLE_RATE = 16000;\n\nexport class OmniVAD {\n private handle: number;\n private config: PostConfig;\n\n private constructor(handle: number, config: PostConfig) {\n this.handle = handle;\n this.config = config;\n }\n\n /**\n * Create a new OmniVAD instance.\n * Loads model from CDN (browser), local package (Node.js), or custom source.\n */\n static async create(options: VADConfig = {}): Promise<OmniVAD> {\n await initWasm();\n const M = getModule();\n const modelBuffer = await loadModel(\"vad\", options.modelUrl, options.modelData);\n const handle = vadCreate(M, modelBuffer);\n const config: PostConfig = {\n threshold: options.speechThreshold ?? DEFAULT_VAD_CONFIG.threshold,\n smoothWindowSize: options.smoothWindowSize ?? DEFAULT_VAD_CONFIG.smoothWindowSize,\n minSpeechFrames: options.minSpeechFrames ?? DEFAULT_VAD_CONFIG.minSpeechFrames,\n minSilenceFrames: options.minSilenceFrames ?? DEFAULT_VAD_CONFIG.minSilenceFrames,\n maxSpeechFrames: options.maxSpeechFrames ?? DEFAULT_VAD_CONFIG.maxSpeechFrames,\n mergeSilenceFrames: options.mergeSilenceFrames ?? DEFAULT_VAD_CONFIG.mergeSilenceFrames,\n extendSpeechFrames: options.extendSpeechFrames ?? DEFAULT_VAD_CONFIG.extendSpeechFrames,\n };\n return new OmniVAD(handle, config);\n }\n\n /**\n * Detect speech segments in audio.\n *\n * Accepts Int16Array (PCM) or normalized Float32Array in [-1, 1].\n */\n detect(audio: Float32Array | Int16Array): VADResult {\n const M = getModule();\n const { ptr, length, format } = prepareAudio(M, audio);\n\n try {\n const timestamps = vadDetect(M, this.handle, ptr, length, this.config, format);\n return {\n duration: Math.round((length / SAMPLE_RATE) * 1000) / 1000,\n timestamps,\n };\n } finally {\n M._free(ptr);\n }\n }\n\n /** Release native resources. */\n dispose(): void {\n if (this.handle) {\n vadDestroy(getModule(), this.handle);\n this.handle = 0;\n }\n }\n}\n\n/** Copy audio to WASM heap as normalized float audio. */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction prepareAudio(M: any, audio: Float32Array | Int16Array): { ptr: number; length: number; format: AudioFormat } {\n const f32 = audio instanceof Int16Array ? int16ToNormalizedFloat32(audio) : audio;\n const ptr = copyAudioToHeap(M, f32);\n return { ptr, length: f32.length, format: \"f32\" };\n}\n\nfunction int16ToNormalizedFloat32(i16: Int16Array): Float32Array {\n const f32 = new Float32Array(i16.length);\n for (let i = 0; i < i16.length; i++) f32[i] = i16[i] / 32768;\n return f32;\n}\n","/**\n * Streaming Voice Activity Detection (WASM/ncnn backend).\n * Processes audio frame-by-frame (10ms chunks of 160 samples @ 16kHz).\n */\n\nimport type { StreamVADConfig, StreamVADFrameResult, StreamVADFullResult } from \"./types.js\";\nimport {\n initWasm,\n getModule,\n copyAudioToHeap,\n loadModel,\n streamVadCreate,\n streamVadClone,\n streamVadProcess,\n streamVadReset,\n streamVadDestroy,\n} from \"./wasm-binding.js\";\n\nconst SAMPLE_RATE = 16000;\n\nexport class OmniStreamVAD {\n private handle: number;\n\n private constructor(handle: number) {\n this.handle = handle;\n }\n\n /**\n * Create a new OmniStreamVAD instance.\n * Loads model from CDN (browser), local package (Node.js), or custom source.\n */\n static async create(options: StreamVADConfig = {}): Promise<OmniStreamVAD> {\n await initWasm();\n const M = getModule();\n const modelBuffer = await loadModel(\"stream-vad\", options.modelUrl, options.modelData);\n const handle = streamVadCreate(M, modelBuffer, {\n threshold: options.threshold,\n smoothWindowSize: options.smoothWindowSize,\n padStartFrame: options.padStartFrame,\n minSpeechFrame: options.minSpeechFrame,\n maxSpeechFrame: options.maxSpeechFrame,\n minSilenceFrame: options.minSilenceFrame,\n });\n return new OmniStreamVAD(handle);\n }\n\n /**\n * Create a lightweight clone sharing the same underlying model weights.\n * The clone has fresh per-instance state (empty audio buffer, zeroed cache).\n * This is synchronous and extremely fast — ideal for multi-stream scenarios\n * (e.g., handling multiple WebRTC tracks or concurrent audio sessions).\n */\n clone(): OmniStreamVAD {\n if (!this.handle) throw new Error(\"Cannot clone a disposed instance.\");\n const M = getModule();\n const newHandle = streamVadClone(M, this.handle);\n return new OmniStreamVAD(newHandle);\n }\n\n /**\n * Process one frame of audio (160 int16 samples = 10ms @ 16kHz).\n * Returns null until enough audio is accumulated.\n *\n * Segment-boundary events (isSpeechStart / isSpeechEnd and the matching\n * speech_*_frame indices) come straight from the C-layer state machine\n * (bit-identical to upstream FireRedVAD) — the wrapper is just a marshaller.\n */\n processFrame(pcm160: Int16Array): StreamVADFrameResult | null {\n const M = getModule();\n const ptr = M._malloc(pcm160.length * 2);\n const heap16 = new Int16Array(M.HEAPU8.buffer, ptr, pcm160.length);\n heap16.set(pcm160);\n\n try {\n const result = streamVadProcess(M, this.handle, ptr, pcm160.length);\n if (!result) return null;\n\n return {\n confidence: result.confidence,\n smoothedProb: result.smoothedProb,\n isSpeech: result.isSpeech,\n frameIndex: result.frameIdx,\n isSpeechStart: result.isSpeechStart,\n isSpeechEnd: result.isSpeechEnd,\n speechStartFrame: result.speechStartFrame,\n speechEndFrame: result.speechEndFrame,\n };\n } finally {\n M._free(ptr);\n }\n }\n\n /**\n * Process entire audio at once and return per-frame probabilities.\n * @param audio - Float32Array in [-1, 1] or Int16Array of 16kHz mono PCM\n */\n detectFull(audio: Float32Array | Int16Array): StreamVADFullResult {\n const M = getModule();\n const f32 = prepareDetectFullAudio(audio);\n const audioPtr = copyAudioToHeap(M, f32);\n const probsPtrPtr = M._malloc(4);\n const framesPtr = M._malloc(4);\n\n try {\n const ret = M.ccall(\n \"omni_stream_vad_detect_full\",\n \"number\",\n [\"number\", \"number\", \"number\", \"number\", \"number\"],\n [this.handle, audioPtr, f32.length, probsPtrPtr, framesPtr],\n );\n if (ret !== 0) throw new Error(`StreamVAD detectFull failed: ${ret}`);\n\n const numFrames = M.getValue(framesPtr, \"i32\");\n const probsPtr = M.getValue(probsPtrPtr, \"i32\");\n const probabilities = probsPtr\n ? new Float32Array(new Float32Array(M.HEAPU8.buffer, probsPtr, numFrames))\n : new Float32Array(0);\n if (probsPtr) M._free(probsPtr);\n\n return {\n probabilities,\n numFrames,\n duration: Math.round((f32.length / SAMPLE_RATE) * 1000) / 1000,\n };\n } finally {\n M._free(audioPtr);\n M._free(probsPtrPtr);\n M._free(framesPtr);\n }\n }\n\n /** Reset all internal state (model cache, audio buffer, postprocessor). */\n reset(): void {\n streamVadReset(getModule(), this.handle);\n }\n\n /** Release native resources. */\n dispose(): void {\n if (this.handle) {\n streamVadDestroy(getModule(), this.handle);\n this.handle = 0;\n }\n }\n}\n\nfunction int16ToFloat32(i16: Int16Array): Float32Array {\n const f32 = new Float32Array(i16.length);\n for (let i = 0; i < i16.length; i++) f32[i] = i16[i];\n return f32;\n}\n\nfunction prepareDetectFullAudio(audio: Float32Array | Int16Array): Float32Array {\n if (audio instanceof Int16Array) {\n return int16ToFloat32(audio);\n }\n if (isNormalizedFloat(audio)) {\n const scaled = new Float32Array(audio.length);\n for (let i = 0; i < audio.length; i++) scaled[i] = audio[i] * 32768;\n return scaled;\n }\n return audio;\n}\n\nfunction isNormalizedFloat(audio: Float32Array): boolean {\n const step = Math.max(1, Math.floor(audio.length / 1000));\n let maxAbs = 0;\n for (let i = 0; i < audio.length; i += step) {\n const v = Math.abs(audio[i]);\n if (v > maxAbs) maxAbs = v;\n }\n return maxAbs <= 1.0;\n}\n","/**\n * Audio Event Detection: speech, singing, music (WASM/ncnn backend).\n *\n * Audio format: same as OmniVAD — Int16Array or normalized Float32Array [-1, 1].\n */\n\nimport type { AEDConfig, AEDResult } from \"./types.js\";\nimport {\n initWasm,\n getModule,\n loadModel,\n aedCreate,\n aedDetect,\n aedDestroy,\n DEFAULT_VAD_CONFIG,\n type AudioFormat,\n type AedPostConfig,\n} from \"./wasm-binding.js\";\n\nconst SAMPLE_RATE = 16000;\n\nexport class OmniAED {\n private handle: number;\n private config: AedPostConfig;\n\n private constructor(handle: number, config: AedPostConfig) {\n this.handle = handle;\n this.config = config;\n }\n\n /**\n * Create a new OmniAED instance.\n * Loads model from CDN (browser), local package (Node.js), or custom source.\n */\n static async create(options: AEDConfig = {}): Promise<OmniAED> {\n await initWasm();\n const M = getModule();\n const modelBuffer = await loadModel(\"aed\", options.modelUrl, options.modelData);\n const handle = aedCreate(M, modelBuffer);\n\n const base = {\n smoothWindowSize: options.smoothWindowSize ?? DEFAULT_VAD_CONFIG.smoothWindowSize,\n minSpeechFrames: options.minSpeechFrames ?? DEFAULT_VAD_CONFIG.minSpeechFrames,\n minSilenceFrames: options.minSilenceFrames ?? DEFAULT_VAD_CONFIG.minSilenceFrames,\n maxSpeechFrames: options.maxSpeechFrames ?? DEFAULT_VAD_CONFIG.maxSpeechFrames,\n mergeSilenceFrames: options.mergeSilenceFrames ?? DEFAULT_VAD_CONFIG.mergeSilenceFrames,\n extendSpeechFrames: options.extendSpeechFrames ?? DEFAULT_VAD_CONFIG.extendSpeechFrames,\n };\n\n const config: AedPostConfig = {\n speech: { ...base, threshold: options.speechThreshold ?? 0.4 },\n singing: { ...base, threshold: options.singingThreshold ?? 0.5 },\n music: { ...base, threshold: options.musicThreshold ?? 0.5 },\n };\n return new OmniAED(handle, config);\n }\n\n /**\n * Detect audio events (speech, singing, music).\n *\n * Accepts Int16Array (PCM) or normalized Float32Array in [-1, 1].\n */\n detect(audio: Float32Array | Int16Array): AEDResult {\n const M = getModule();\n const { ptr, length, format } = prepareAudio(M, audio);\n const duration = Math.round((length / SAMPLE_RATE) * 1000) / 1000;\n\n try {\n const events = aedDetect(M, this.handle, ptr, length, this.config, format);\n return {\n duration,\n events,\n ratios: computeCoverageRatios(events, duration),\n };\n } finally {\n M._free(ptr);\n }\n }\n\n /** Release native resources. */\n dispose(): void {\n if (this.handle) {\n aedDestroy(getModule(), this.handle);\n this.handle = 0;\n }\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction prepareAudio(M: any, audio: Float32Array | Int16Array): { ptr: number; length: number; format: AudioFormat } {\n const f32 = audio instanceof Int16Array ? int16ToNormalizedFloat32(audio) : audio;\n const ptr = M._malloc(f32.length * 4);\n const heap = new Float32Array(M.HEAPU8.buffer, ptr, f32.length);\n heap.set(f32);\n return { ptr, length: f32.length, format: \"f32\" };\n}\n\nfunction int16ToNormalizedFloat32(i16: Int16Array): Float32Array {\n const f32 = new Float32Array(i16.length);\n for (let i = 0; i < i16.length; i++) f32[i] = i16[i] / 32768;\n return f32;\n}\n\nfunction computeCoverageRatios(\n events: Record<string, Array<[number, number]>>,\n duration: number,\n): Record<string, number> {\n const ratios: Record<string, number> = {\n speech: 0,\n singing: 0,\n music: 0,\n };\n\n if (duration <= 0) return ratios;\n\n for (const cls of Object.keys(ratios)) {\n const covered = (events[cls] ?? []).reduce((sum, [start, end]) => sum + Math.max(0, end - start), 0);\n ratios[cls] = Math.round(Math.min(1, covered / duration) * 1e6) / 1e6;\n }\n\n return ratios;\n}\n","/**\n * Pure-algorithm chunking utility — wraps the C function omni_merge_chunks\n * compiled into the WASM module.\n *\n * WhisperX-style binarize+merge, minus the binarize half because OmniVAD\n * already returns binarized timestamps.\n *\n * Usage:\n *\n * import { mergeChunks } from \"omnivad\";\n *\n * const chunks = await mergeChunks(\n * [[0.0, 5.0], [6.0, 10.0]],\n * { maxChunkSecs: 30.0, maxGapSecs: 2.0 }\n * );\n * // [{ start: 0, end: 10, segStartIdx: 0, segCount: 2 }]\n */\n\nimport type { ChunkOptions, ChunkResult } from \"./types.js\";\nimport {\n chunkMerge,\n DEFAULT_CHUNK_CONFIG,\n getModule,\n initWasm,\n type ChunkConfig,\n} from \"./wasm-binding.js\";\n\n/**\n * Merge a sorted array of [start, end] speech segments into duration-bounded\n * chunks.\n *\n * Lazily initializes the WASM module on first call (so the caller doesn't have\n * to await `initWasm()` separately). Subsequent calls reuse the cached module.\n *\n * @param segments array of [start, end] pairs in seconds, sorted by start\n * @param options chunking configuration; missing fields fall back to\n * {@link DEFAULT_CHUNK_CONFIG}\n */\nexport async function mergeChunks(\n segments: Array<[number, number]>,\n options: ChunkOptions = {},\n): Promise<ChunkResult[]> {\n await initWasm();\n const M = getModule();\n\n const cfg: ChunkConfig = {\n maxChunkSecs: options.maxChunkSecs ?? DEFAULT_CHUNK_CONFIG.maxChunkSecs,\n maxGapSecs: options.maxGapSecs ?? DEFAULT_CHUNK_CONFIG.maxGapSecs,\n padOnsetSecs: options.padOnsetSecs ?? DEFAULT_CHUNK_CONFIG.padOnsetSecs,\n padOffsetSecs: options.padOffsetSecs ?? DEFAULT_CHUNK_CONFIG.padOffsetSecs,\n minSpeechSecs: options.minSpeechSecs ?? DEFAULT_CHUNK_CONFIG.minSpeechSecs,\n minSilenceSecs: options.minSilenceSecs ?? DEFAULT_CHUNK_CONFIG.minSilenceSecs,\n mode: options.mode ?? DEFAULT_CHUNK_CONFIG.mode,\n };\n\n const records = chunkMerge(M, segments, cfg);\n return records.map((r) => ({\n start: r.start,\n end: r.end,\n segStartIdx: r.segStartIdx,\n segCount: r.segCount,\n }));\n}\n\nexport { DEFAULT_CHUNK_CONFIG } from \"./wasm-binding.js\";\nexport type { ChunkOptions, ChunkResult } from \"./types.js\";\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/wasm-binding.ts","../src/vad.ts","../src/stream-vad.ts","../src/aed.ts","../src/chunking.ts"],"names":["resp","SAMPLE_RATE"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Low-level WASM binding for omnivad C API.\n * Loads the Emscripten module and provides typed wrappers.\n */\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype EmscriptenModule = any;\n\nlet _module: EmscriptenModule | null = null;\nlet _loading: Promise<EmscriptenModule> | null = null;\n\n/**\n * Browser-side classic-script loader. Used to pull in Emscripten's IIFE\n * glue (`var createOmniVAD = (() => {...})()`) without going through\n * `import()` — see initWasm()'s long comment.\n *\n * Works in both DOM contexts (main thread) and worker contexts: in a\n * Worker we fall back to `importScripts(url)` which is synchronous but\n * still wrapped in a Promise for API uniformity.\n */\nfunction loadScript(url: string): Promise<void> {\n // Worker path.\n if (typeof globalThis.document === \"undefined\") {\n return new Promise<void>((resolve, reject) => {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const importScripts = (globalThis as any).importScripts as\n | ((u: string) => void)\n | undefined;\n if (typeof importScripts !== \"function\") {\n throw new Error(\n \"omnivad: cannot load glue script — no document and no importScripts\",\n );\n }\n importScripts(url);\n resolve();\n } catch (err) {\n reject(err instanceof Error ? err : new Error(String(err)));\n }\n });\n }\n // Main thread path.\n return new Promise<void>((resolve, reject) => {\n const s = globalThis.document!.createElement(\"script\");\n s.src = url;\n s.async = true;\n s.crossOrigin = \"anonymous\";\n s.onload = () => resolve();\n s.onerror = () =>\n reject(new Error(`Failed to load omnivad glue script: ${url}`));\n globalThis.document!.head.appendChild(s);\n });\n}\n\n/** Post-processing config matching C struct OmniPostConfig (7 x i32/float, 28 bytes) */\nexport interface PostConfig {\n threshold: number;\n smoothWindowSize: number;\n minSpeechFrames: number;\n minSilenceFrames: number;\n maxSpeechFrames: number;\n mergeSilenceFrames: number;\n extendSpeechFrames: number;\n}\n\nconst SIZEOF_POST_CONFIG = 28; // 7 * 4 bytes\nconst SIZEOF_AED_POST_CONFIG = 3 * SIZEOF_POST_CONFIG; // 84 bytes\nconst SIZEOF_SEGMENT = 8; // start(f32) + end(f32)\nconst SIZEOF_AED_SEGMENT = 16; // start(f32) + end(f32) + cls(i32) + confidence(f32)\nconst SIZEOF_CHUNK_CONFIG = 28; // 6 floats + 1 i32 mode\nconst SIZEOF_CHUNK = 16; // start(f32) + end(f32) + seg_start_idx(i32) + seg_count(i32)\n\n/** Re-exported for ABI self-tests. */\nexport const _SIZEOF_CHUNK_CONFIG = SIZEOF_CHUNK_CONFIG;\nexport const _SIZEOF_CHUNK = SIZEOF_CHUNK;\nconst OMNI_ERR_NO_FRAMES = -7;\n\n/** Package version — used to construct default CDN URLs. */\nexport const VERSION = \"0.2.10\";\n\n/** Default CDN base for model files (jsDelivr serves npm package contents). */\nexport const DEFAULT_CDN_BASE = `https://cdn.jsdelivr.net/npm/omnivad@${VERSION}/models`;\n\n/** Model filenames keyed by type. */\nexport const MODEL_FILES = {\n vad: \"vad.omnivad\",\n \"stream-vad\": \"stream-vad.omnivad\",\n aed: \"aed.omnivad\",\n} as const;\n\nexport type ModelType = keyof typeof MODEL_FILES;\n\n/**\n * Initialize the WASM module. Call once before using any other functions.\n * Safe to call multiple times (returns cached module).\n */\nexport async function initWasm(\n wasmLocator?: (filename: string) => string,\n): Promise<EmscriptenModule> {\n if (_module) return _module;\n if (_loading) return _loading;\n\n _loading = (async () => {\n // Dynamic import of the Emscripten glue\n let createOmniVAD: (opts?: Record<string, unknown>) => Promise<EmscriptenModule>;\n let defaultLocateFile: ((filename: string) => string) | undefined;\n\n if (typeof globalThis.process?.versions?.node === \"string\") {\n // Node.js: use require for .cjs (avoids ESM detection issues)\n const { createRequire } = await import(/* webpackIgnore: true */ /* turbopackIgnore: true */ \"module\");\n const { dirname, join } = await import(/* webpackIgnore: true */ /* turbopackIgnore: true */ \"path\");\n const req = createRequire(import.meta.url);\n const gluePath = req.resolve(\"../dist/wasm/omnivad.cjs\");\n const wasmDir = dirname(gluePath);\n createOmniVAD = req(gluePath);\n defaultLocateFile = (filename: string) => join(wasmDir, filename);\n } else {\n // Browser. We can't `await import()` the glue: Emscripten with\n // MODULARIZE=1 (no EXPORT_ES6=1) emits an IIFE\n // var createOmniVAD = (() => { ... })();\n // which has zero ES exports, so dynamic import yields an empty\n // module record and `mod.default || mod` is the empty namespace\n // object → `createOmniVAD()` throws \"is not a function\".\n //\n // Solution: classic <script> injection, then read the global the\n // IIFE wrote to (`globalThis.createOmniVAD`). Caches via the global\n // so repeat callers don't re-fetch the script.\n let glueUrlStr: string;\n if (wasmLocator) {\n glueUrlStr = wasmLocator(\"omnivad.js\");\n } else {\n // Native ESM resolution path (when consumed without a bundler).\n glueUrlStr = new URL(\"../dist/wasm/omnivad.js\", import.meta.url).href;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const g = globalThis as any;\n let factory: ((opts?: Record<string, unknown>) => Promise<EmscriptenModule>) | undefined =\n g.createOmniVAD;\n if (typeof factory !== \"function\") {\n await loadScript(glueUrlStr);\n factory = g.createOmniVAD;\n }\n if (typeof factory !== \"function\") {\n throw new Error(\n `omnivad.js loaded from ${glueUrlStr} but globalThis.createOmniVAD is missing`,\n );\n }\n createOmniVAD = factory;\n // glueUrlStr may already be absolute (when wasmLocator returns a\n // full URL) or relative (native ESM mode). new URL(\"./\", abs) is\n // safe; new URL(\"./\", path-relative) throws — guard with a base.\n const baseHref =\n typeof globalThis.location !== \"undefined\"\n ? globalThis.location.href\n : \"file:///\";\n const absGlue = new URL(glueUrlStr, baseHref);\n const wasmBaseUrl = new URL(\"./\", absGlue);\n defaultLocateFile = (filename: string) => new URL(filename, wasmBaseUrl).toString();\n }\n\n const opts: Record<string, unknown> = {};\n const locateFile = wasmLocator ?? defaultLocateFile;\n if (locateFile) {\n opts.locateFile = (path: string) => locateFile(path);\n }\n\n _module = await createOmniVAD(opts);\n return _module!;\n })();\n\n return _loading;\n}\n\n/**\n * Load a model file as ArrayBuffer.\n *\n * Resolution order:\n * 1. modelData (ArrayBuffer) — use directly\n * 2. modelUrl (string/URL) — fetch from that URL\n * 3. Node.js — read from npm package's models/ directory\n * 4. Browser — fetch from jsDelivr CDN\n */\nexport async function loadModel(\n modelType: ModelType,\n modelUrl?: string | URL,\n modelData?: ArrayBuffer,\n): Promise<ArrayBuffer> {\n if (modelData) return modelData;\n\n if (modelUrl) {\n const resp = await fetch(modelUrl.toString());\n if (!resp.ok) throw new Error(`Failed to fetch model from ${modelUrl}: ${resp.status}`);\n return resp.arrayBuffer();\n }\n\n const filename = MODEL_FILES[modelType];\n\n if (typeof globalThis.process?.versions?.node === \"string\") {\n // Node.js: read from package's models/ directory\n const { createRequire } = await import(/* webpackIgnore: true */ /* turbopackIgnore: true */ \"module\");\n const { dirname, join } = await import(/* webpackIgnore: true */ /* turbopackIgnore: true */ \"path\");\n const { readFile } = await import(/* webpackIgnore: true */ /* turbopackIgnore: true */ \"fs/promises\");\n const req = createRequire(import.meta.url);\n const pkgDir = dirname(req.resolve(\"../package.json\"));\n const modelPath = join(pkgDir, \"models\", filename);\n const buf = await readFile(modelPath);\n return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);\n }\n\n // Browser: fetch from CDN\n const url = `${DEFAULT_CDN_BASE}/${filename}`;\n const resp = await fetch(url);\n if (!resp.ok) throw new Error(`Failed to fetch model from ${url}: ${resp.status}`);\n return resp.arrayBuffer();\n}\n\n/** Get the initialized WASM module (throws if not initialized) */\nexport function getModule(): EmscriptenModule {\n if (!_module) throw new Error(\"WASM not initialized. Call initWasm() first.\");\n return _module;\n}\n\nfunction readNativeError(M: EmscriptenModule, code: number): string {\n const msg = M.ccall(\"omni_error_string\", \"string\", [\"number\"], [code]);\n return msg ? `${msg} (${code})` : `error ${code}`;\n}\n\n/** Shared helper: call a C create function with out_error, throw on failure. */\nfunction createModel(\n M: EmscriptenModule,\n fnName: string,\n argTypes: string[],\n args: unknown[],\n label: string,\n): number {\n const errPtr = M._malloc(4);\n try {\n const handle = M.ccall(fnName, \"number\", [...argTypes, \"number\"], [...args, errPtr]);\n if (!handle) {\n const err = M.getValue(errPtr, \"i32\");\n throw new Error(`Failed to create ${label} model: ${readNativeError(M, err)}`);\n }\n return handle;\n } finally {\n M._free(errPtr);\n }\n}\n\n// -------------------------------------------------------------------------- //\n// Memory helpers //\n// -------------------------------------------------------------------------- //\n\n/**\n * Audio format: two types only. Same convention across all 3 model types.\n * \"f32\" — float* in [-1.0, 1.0] (Web Audio, soundfile, torch)\n * \"int16\" — int16_t* PCM (WAV files, microphones)\n */\nexport type AudioFormat = \"f32\" | \"int16\";\n\n/** Copy Float32Array audio into WASM heap, returns pointer. Caller must free. */\nexport function copyAudioToHeap(M: EmscriptenModule, audio: Float32Array): number {\n const ptr = M._malloc(audio.length * 4);\n const heap = new Float32Array(M.HEAPU8.buffer, ptr, audio.length);\n heap.set(audio);\n return ptr;\n}\n\n/** Copy Int16Array audio into WASM heap, returns pointer. Caller must free. */\nexport function copyInt16ToHeap(M: EmscriptenModule, audio: Int16Array): number {\n const ptr = M._malloc(audio.length * 2);\n const heap = new Int16Array(M.HEAPU8.buffer, ptr, audio.length);\n heap.set(audio);\n return ptr;\n}\n\n/**\n * Audio format dispatch: copy `audio` to WASM heap using the correct\n * integer/float layout for its dtype, and return the matching format\n * tag for downstream C-entry routing.\n *\n * Wrappers MUST go through this helper — never scale or cast in JS.\n * All scaling lives in the C entries (the f32 entry multiplies by\n * 32768.0f, the int16 entry casts to float).\n */\nexport function dispatchAudio(\n M: EmscriptenModule,\n audio: Float32Array | Int16Array,\n): { ptr: number; length: number; format: AudioFormat } {\n if (audio instanceof Float32Array) {\n return { ptr: copyAudioToHeap(M, audio), length: audio.length, format: \"f32\" };\n }\n if (audio instanceof Int16Array) {\n return { ptr: copyInt16ToHeap(M, audio), length: audio.length, format: \"int16\" };\n }\n throw new TypeError(\n `unsupported audio dtype; expected Float32Array in [-1, 1] or Int16Array`,\n );\n}\n\n/** Write PostConfig struct to WASM heap at ptr */\nexport function writePostConfig(M: EmscriptenModule, ptr: number, cfg: PostConfig): void {\n M.setValue(ptr + 0, cfg.threshold, \"float\");\n M.setValue(ptr + 4, cfg.smoothWindowSize, \"i32\");\n M.setValue(ptr + 8, cfg.minSpeechFrames, \"i32\");\n M.setValue(ptr + 12, cfg.minSilenceFrames, \"i32\");\n M.setValue(ptr + 16, cfg.maxSpeechFrames, \"i32\");\n M.setValue(ptr + 20, cfg.mergeSilenceFrames, \"i32\");\n M.setValue(ptr + 24, cfg.extendSpeechFrames, \"i32\");\n}\n\nexport const DEFAULT_VAD_CONFIG: PostConfig = {\n threshold: 0.4,\n smoothWindowSize: 5,\n minSpeechFrames: 20,\n minSilenceFrames: 20,\n maxSpeechFrames: 3000,\n mergeSilenceFrames: 0,\n extendSpeechFrames: 0,\n};\n\n// -------------------------------------------------------------------------- //\n// Chunking (pure-algorithm, mirrors omnivad.h's omni_merge_chunks) //\n// -------------------------------------------------------------------------- //\n\n/** OmniChunkMode enum values (must match native/include/omnivad.h). */\nexport const OMNI_CHUNK_GREEDY = 0;\nexport const OMNI_CHUNK_LONGEST_GAP = 1;\n\n/**\n * Chunking strategy:\n * - \"greedy\" — sequential append. Recommended for fixed-length-input ASR\n * (Whisper / whisperX, which pad to 30s anyway).\n * - \"longest_gap\" — recursive split at longest pause; falls back to hard-split\n * when a single segment exceeds maxChunkSecs. Recommended for\n * variable-length-input models (forced alignment, TTS,\n * encoder-style ASR); no fixed-length padding required.\n */\nexport type ChunkMode = \"greedy\" | \"longest_gap\";\n\n/** Configuration for omni_merge_chunks (matches C struct OmniChunkConfig, 28 bytes) */\nexport interface ChunkConfig {\n maxChunkSecs: number; // hard upper bound on chunk duration (seconds), > 0\n maxGapSecs: number; // split if gap > this. Infinity disables. Honored by both modes.\n padOnsetSecs: number; // extend chunk start backward (clamped >= 0)\n padOffsetSecs: number; // extend chunk end forward\n minSpeechSecs: number; // drop input segments shorter than this; pairs with VAD minSpeechFrames\n minSilenceSecs: number; // pre-merge gaps shorter than this; pairs with VAD minSilenceFrames\n mode: ChunkMode; // packing strategy (default \"greedy\")\n}\n\n/**\n * Default chunk config. Mirrors C-side omni_chunk_config_default(); kept in\n * TS so callers don't need a roundtrip into WASM just to read defaults.\n *\n * Defaults: max_chunk_secs matches Whisper's 30s input window.\n */\nexport const DEFAULT_CHUNK_CONFIG: ChunkConfig = {\n maxChunkSecs: 30.0,\n maxGapSecs: Infinity,\n padOnsetSecs: 0.04,\n padOffsetSecs: 0.04,\n minSpeechSecs: 0.0,\n minSilenceSecs: 0.20, // matches VAD minSilenceFrames=20 @ 10ms shift\n mode: \"greedy\",\n};\n\nfunction modeToInt(m: ChunkMode): number {\n switch (m) {\n case \"greedy\": return OMNI_CHUNK_GREEDY;\n case \"longest_gap\": return OMNI_CHUNK_LONGEST_GAP;\n default: throw new Error(`Unknown chunking mode: ${String(m)}`);\n }\n}\n\n/** Write ChunkConfig struct to WASM heap at ptr (must be SIZEOF_CHUNK_CONFIG bytes). */\nexport function writeChunkConfig(M: EmscriptenModule, ptr: number, cfg: ChunkConfig): void {\n M.setValue(ptr + 0, cfg.maxChunkSecs, \"float\");\n M.setValue(ptr + 4, cfg.maxGapSecs, \"float\");\n M.setValue(ptr + 8, cfg.padOnsetSecs, \"float\");\n M.setValue(ptr + 12, cfg.padOffsetSecs, \"float\");\n M.setValue(ptr + 16, cfg.minSpeechSecs, \"float\");\n M.setValue(ptr + 20, cfg.minSilenceSecs, \"float\");\n M.setValue(ptr + 24, modeToInt(cfg.mode), \"i32\");\n}\n\nexport interface ChunkRecord {\n start: number;\n end: number;\n segStartIdx: number;\n segCount: number;\n}\n\n/**\n * Call omni_merge_chunks via the WASM module.\n *\n * @param segments array of [start, end] pairs, sorted by start (caller's contract)\n * @param config chunking configuration\n * @returns array of ChunkRecord. On C error, throws.\n */\nexport function chunkMerge(\n M: EmscriptenModule,\n segments: Array<[number, number]>,\n config: ChunkConfig,\n): ChunkRecord[] {\n const numSegments = segments.length;\n\n const segPtr = numSegments > 0 ? M._malloc(numSegments * SIZEOF_SEGMENT) : 0;\n const cfgPtr = M._malloc(SIZEOF_CHUNK_CONFIG);\n const outPtrPtr = M._malloc(4); // pointer to OmniChunk*\n const outCountPtr = M._malloc(4);\n\n try {\n for (let i = 0; i < numSegments; i++) {\n const base = segPtr + i * SIZEOF_SEGMENT;\n M.setValue(base + 0, segments[i][0], \"float\");\n M.setValue(base + 4, segments[i][1], \"float\");\n }\n writeChunkConfig(M, cfgPtr, config);\n M.setValue(outPtrPtr, 0, \"i32\");\n M.setValue(outCountPtr, 0, \"i32\");\n\n const rc = M.ccall(\n \"omni_merge_chunks\",\n \"number\",\n [\"number\", \"number\", \"number\", \"number\", \"number\"],\n [segPtr, numSegments, cfgPtr, outPtrPtr, outCountPtr],\n );\n if (rc !== 0) {\n throw new Error(`omni_merge_chunks failed: ${readNativeError(M, rc)}`);\n }\n\n const count = M.getValue(outCountPtr, \"i32\");\n const chunkPtr = M.getValue(outPtrPtr, \"i32\");\n const chunks: ChunkRecord[] = [];\n for (let i = 0; i < count; i++) {\n const base = chunkPtr + i * SIZEOF_CHUNK;\n chunks.push({\n start: M.getValue(base + 0, \"float\"),\n end: M.getValue(base + 4, \"float\"),\n segStartIdx: M.getValue(base + 8, \"i32\"),\n segCount: M.getValue(base + 12, \"i32\"),\n });\n }\n if (chunkPtr) M._free(chunkPtr);\n return chunks;\n } finally {\n if (segPtr) M._free(segPtr);\n M._free(cfgPtr);\n M._free(outPtrPtr);\n M._free(outCountPtr);\n }\n}\n\n// -------------------------------------------------------------------------- //\n// Non-stream VAD //\n// -------------------------------------------------------------------------- //\n\nexport function vadCreate(M: EmscriptenModule, modelBuffer: ArrayBuffer): number {\n const bytes = new Uint8Array(modelBuffer);\n const ptr = M._malloc(bytes.length);\n M.HEAPU8.set(bytes, ptr);\n try {\n return createModel(M, \"omni_vad_create_from_buffer\", [\"number\", \"number\"], [ptr, bytes.length], \"VAD\");\n } finally {\n M._free(ptr);\n }\n}\n\nfunction readSegments(M: EmscriptenModule, segPtrPtr: number, countPtr: number): Array<[number, number]> {\n const count = M.getValue(countPtr, \"i32\");\n const segPtr = M.getValue(segPtrPtr, \"i32\");\n const segments: Array<[number, number]> = [];\n for (let i = 0; i < count; i++) {\n const base = segPtr + i * SIZEOF_SEGMENT;\n segments.push([\n Math.round(M.getValue(base, \"float\") * 1000) / 1000,\n Math.round(M.getValue(base + 4, \"float\") * 1000) / 1000,\n ]);\n }\n if (segPtr) M._free(segPtr);\n return segments;\n}\n\nexport function vadDetect(\n M: EmscriptenModule,\n handle: number,\n audioPtr: number,\n numSamples: number,\n cfg: PostConfig,\n format: AudioFormat = \"f32\",\n): Array<[number, number]> {\n const cfgPtr = M._malloc(SIZEOF_POST_CONFIG);\n const segPtrPtr = M._malloc(4);\n const countPtr = M._malloc(4);\n const fn = format === \"int16\" ? \"omni_vad_detect_int16\" : \"omni_vad_detect\";\n\n try {\n writePostConfig(M, cfgPtr, cfg);\n const ret = M.ccall(\n fn,\n \"number\",\n [\"number\", \"number\", \"number\", \"number\", \"number\", \"number\"],\n [handle, audioPtr, numSamples, cfgPtr, segPtrPtr, countPtr],\n );\n if (ret !== 0) throw new Error(`VAD detect failed: ${ret}`);\n return readSegments(M, segPtrPtr, countPtr);\n } finally {\n M._free(cfgPtr);\n M._free(segPtrPtr);\n M._free(countPtr);\n }\n}\n\nexport function vadDestroy(M: EmscriptenModule, handle: number): void {\n M.ccall(\"omni_vad_destroy\", null, [\"number\"], [handle]);\n}\n\n// -------------------------------------------------------------------------- //\n// Non-stream AED //\n// -------------------------------------------------------------------------- //\n\nconst AED_CLASSES: Record<number, string> = { 0: \"speech\", 1: \"singing\", 2: \"music\" };\n\nexport function aedCreate(M: EmscriptenModule, modelBuffer: ArrayBuffer): number {\n const bytes = new Uint8Array(modelBuffer);\n const ptr = M._malloc(bytes.length);\n M.HEAPU8.set(bytes, ptr);\n try {\n return createModel(M, \"omni_aed_create_from_buffer\", [\"number\", \"number\"], [ptr, bytes.length], \"AED\");\n } finally {\n M._free(ptr);\n }\n}\n\nexport interface AedPostConfig {\n speech: PostConfig;\n singing: PostConfig;\n music: PostConfig;\n}\n\nexport function aedDetect(\n M: EmscriptenModule,\n handle: number,\n audioPtr: number,\n numSamples: number,\n cfg: AedPostConfig,\n format: AudioFormat = \"f32\",\n): Record<string, Array<[number, number]>> {\n const cfgPtr = M._malloc(SIZEOF_AED_POST_CONFIG);\n const segPtrPtr = M._malloc(4);\n const countPtr = M._malloc(4);\n const fn = format === \"int16\" ? \"omni_aed_detect_int16\" : \"omni_aed_detect\";\n\n try {\n writePostConfig(M, cfgPtr, cfg.speech);\n writePostConfig(M, cfgPtr + SIZEOF_POST_CONFIG, cfg.singing);\n writePostConfig(M, cfgPtr + 2 * SIZEOF_POST_CONFIG, cfg.music);\n\n const ret = M.ccall(\n fn,\n \"number\",\n [\"number\", \"number\", \"number\", \"number\", \"number\", \"number\"],\n [handle, audioPtr, numSamples, cfgPtr, segPtrPtr, countPtr],\n );\n if (ret !== 0) throw new Error(`AED detect failed: ${ret}`);\n\n const count = M.getValue(countPtr, \"i32\");\n const segPtr = M.getValue(segPtrPtr, \"i32\");\n const events: Record<string, Array<[number, number]>> = {\n speech: [],\n singing: [],\n music: [],\n };\n for (let i = 0; i < count; i++) {\n const base = segPtr + i * SIZEOF_AED_SEGMENT;\n const cls = M.getValue(base + 8, \"i32\");\n const name = AED_CLASSES[cls];\n if (name && events[name]) {\n events[name].push([\n Math.round(M.getValue(base, \"float\") * 1000) / 1000,\n Math.round(M.getValue(base + 4, \"float\") * 1000) / 1000,\n ]);\n }\n }\n if (segPtr) M._free(segPtr);\n return events;\n } finally {\n M._free(cfgPtr);\n M._free(segPtrPtr);\n M._free(countPtr);\n }\n}\n\nexport function aedDestroy(M: EmscriptenModule, handle: number): void {\n M.ccall(\"omni_aed_destroy\", null, [\"number\"], [handle]);\n}\n\n// -------------------------------------------------------------------------- //\n// Stream VAD //\n// -------------------------------------------------------------------------- //\n\n/** OmniStreamVadConfig — bit-identical to upstream FireRedStreamVadConfig. */\nexport interface StreamVadConfig {\n threshold: number;\n smoothWindowSize: number;\n padStartFrame: number;\n minSpeechFrame: number;\n maxSpeechFrame: number;\n minSilenceFrame: number;\n}\n\n/** Defaults match upstream FireRedStreamVadConfig. */\nexport const DEFAULT_STREAM_VAD_CONFIG: StreamVadConfig = {\n threshold: 0.5,\n smoothWindowSize: 5,\n padStartFrame: 5,\n minSpeechFrame: 8,\n maxSpeechFrame: 2000,\n minSilenceFrame: 20,\n};\n\nconst SIZEOF_STREAM_VAD_CONFIG = 24; // float + 5 i32\n\nfunction writeStreamVadConfig(M: EmscriptenModule, ptr: number, cfg: StreamVadConfig): void {\n M.setValue(ptr + 0, cfg.threshold, \"float\");\n M.setValue(ptr + 4, cfg.smoothWindowSize, \"i32\");\n M.setValue(ptr + 8, cfg.padStartFrame, \"i32\");\n M.setValue(ptr + 12, cfg.minSpeechFrame, \"i32\");\n M.setValue(ptr + 16, cfg.maxSpeechFrame, \"i32\");\n M.setValue(ptr + 20, cfg.minSilenceFrame, \"i32\");\n}\n\nexport function streamVadCreate(\n M: EmscriptenModule,\n modelBuffer: ArrayBuffer,\n config: Partial<StreamVadConfig> = {},\n): number {\n // Skip undefined overrides — callers often relay optional kwargs that may\n // be `undefined`, and spreading those would clobber the upstream defaults.\n const overrides = Object.fromEntries(\n Object.entries(config).filter(([, v]) => v !== undefined),\n );\n const cfg: StreamVadConfig = { ...DEFAULT_STREAM_VAD_CONFIG, ...overrides };\n const bytes = new Uint8Array(modelBuffer);\n const dataPtr = M._malloc(bytes.length);\n M.HEAPU8.set(bytes, dataPtr);\n const cfgPtr = M._malloc(SIZEOF_STREAM_VAD_CONFIG);\n try {\n writeStreamVadConfig(M, cfgPtr, cfg);\n return createModel(\n M,\n \"omni_stream_vad_create_from_buffer\",\n [\"number\", \"number\", \"number\"],\n [dataPtr, bytes.length, cfgPtr],\n \"StreamVAD\",\n );\n } finally {\n M._free(dataPtr);\n M._free(cfgPtr);\n }\n}\n\n/** Per-frame result from streaming VAD. Bit-identical to upstream\n * StreamVadFrameResult: includes segment-boundary events. */\nexport interface StreamVadResult {\n confidence: number;\n smoothedProb: number;\n isSpeech: boolean;\n isSpeechStart: boolean;\n isSpeechEnd: boolean;\n frameIdx: number;\n speechStartFrame: number;\n speechEndFrame: number;\n}\n\nconst SIZEOF_STREAM_VAD_RESULT = 24; // 2*float + 3*bool + 1pad + 3*i32\n\n/**\n * Process one chunk of audio (160 samples = 10ms). Returns null if buffering.\n *\n * Caller must have already copied audio to `audioPtr` via `dispatchAudio()`\n * (or `copyAudioToHeap` / `copyInt16ToHeap`); `format` selects the C entry.\n */\nexport function streamVadProcess(\n M: EmscriptenModule,\n handle: number,\n audioPtr: number,\n numSamples: number,\n format: AudioFormat = \"f32\",\n): StreamVadResult | null {\n const resultPtr = M._malloc(SIZEOF_STREAM_VAD_RESULT);\n const fn = format === \"int16\" ? \"omni_stream_vad_process_int16\" : \"omni_stream_vad_process\";\n try {\n const ret = M.ccall(\n fn,\n \"number\",\n [\"number\", \"number\", \"number\", \"number\"],\n [handle, audioPtr, numSamples, resultPtr],\n );\n if (ret === OMNI_ERR_NO_FRAMES) return null;\n if (ret !== 0) throw new Error(`StreamVAD process failed: ${ret}`);\n return {\n confidence: M.getValue(resultPtr + 0, \"float\"),\n smoothedProb: M.getValue(resultPtr + 4, \"float\"),\n isSpeech: M.getValue(resultPtr + 8, \"i8\") !== 0,\n isSpeechStart: M.getValue(resultPtr + 9, \"i8\") !== 0,\n isSpeechEnd: M.getValue(resultPtr + 10, \"i8\") !== 0,\n frameIdx: M.getValue(resultPtr + 12, \"i32\"),\n speechStartFrame: M.getValue(resultPtr + 16, \"i32\"),\n speechEndFrame: M.getValue(resultPtr + 20, \"i32\"),\n };\n } finally {\n M._free(resultPtr);\n }\n}\n\n/**\n * Batch mode: run the full audio through the streaming model at once and\n * return raw per-frame probabilities. `format` selects the C entry; the\n * caller must have copied `audioPtr` with the matching layout.\n */\nexport function streamVadDetectFull(\n M: EmscriptenModule,\n handle: number,\n audioPtr: number,\n numSamples: number,\n format: AudioFormat = \"f32\",\n): { probabilities: Float32Array; numFrames: number } {\n const probsPtrPtr = M._malloc(4);\n const framesPtr = M._malloc(4);\n const fn =\n format === \"int16\" ? \"omni_stream_vad_detect_full_int16\" : \"omni_stream_vad_detect_full\";\n try {\n const ret = M.ccall(\n fn,\n \"number\",\n [\"number\", \"number\", \"number\", \"number\", \"number\"],\n [handle, audioPtr, numSamples, probsPtrPtr, framesPtr],\n );\n if (ret !== 0) throw new Error(`StreamVAD detectFull failed: ${ret}`);\n\n const numFrames = M.getValue(framesPtr, \"i32\");\n const probsPtr = M.getValue(probsPtrPtr, \"i32\");\n const probabilities = probsPtr\n ? new Float32Array(new Float32Array(M.HEAPU8.buffer, probsPtr, numFrames))\n : new Float32Array(0);\n if (probsPtr) M._free(probsPtr);\n return { probabilities, numFrames };\n } finally {\n M._free(probsPtrPtr);\n M._free(framesPtr);\n }\n}\n\n/** Clone a stream VAD handle (shares model weights, fresh per-instance state). */\nexport function streamVadClone(M: EmscriptenModule, handle: number): number {\n const errPtr = M._malloc(4);\n try {\n const newHandle = M.ccall(\n \"omni_stream_vad_clone\",\n \"number\",\n [\"number\", \"number\"],\n [handle, errPtr],\n );\n if (!newHandle) {\n const err = M.getValue(errPtr, \"i32\");\n throw new Error(`StreamVAD clone failed: ${readNativeError(M, err)}`);\n }\n return newHandle;\n } finally {\n M._free(errPtr);\n }\n}\n\nexport function streamVadReset(M: EmscriptenModule, handle: number): void {\n M.ccall(\"omni_stream_vad_reset\", null, [\"number\"], [handle]);\n}\n\nexport function streamVadDestroy(M: EmscriptenModule, handle: number): void {\n M.ccall(\"omni_stream_vad_destroy\", null, [\"number\"], [handle]);\n}\n","/**\n * Non-streaming Voice Activity Detection (WASM/ncnn backend).\n *\n * Audio format: two types only. Wrappers dispatch by dtype to the matching\n * C entry — never scale or cast in JS.\n * - Float32Array in [-1.0, 1.0] (Web Audio, soundfile, torch)\n * - Int16Array (raw 16-bit PCM from WAV / microphone)\n */\n\nimport type { VADConfig, VADResult } from \"./types.js\";\nimport {\n initWasm,\n getModule,\n dispatchAudio,\n loadModel,\n vadCreate,\n vadDetect,\n vadDestroy,\n DEFAULT_VAD_CONFIG,\n type PostConfig,\n} from \"./wasm-binding.js\";\n\nconst SAMPLE_RATE = 16000;\n\nexport class OmniVAD {\n private handle: number;\n private config: PostConfig;\n\n private constructor(handle: number, config: PostConfig) {\n this.handle = handle;\n this.config = config;\n }\n\n /**\n * Create a new OmniVAD instance.\n * Loads model from CDN (browser), local package (Node.js), or custom source.\n */\n static async create(options: VADConfig = {}): Promise<OmniVAD> {\n await initWasm();\n const M = getModule();\n const modelBuffer = await loadModel(\"vad\", options.modelUrl, options.modelData);\n const handle = vadCreate(M, modelBuffer);\n const config: PostConfig = {\n threshold: options.speechThreshold ?? DEFAULT_VAD_CONFIG.threshold,\n smoothWindowSize: options.smoothWindowSize ?? DEFAULT_VAD_CONFIG.smoothWindowSize,\n minSpeechFrames: options.minSpeechFrames ?? DEFAULT_VAD_CONFIG.minSpeechFrames,\n minSilenceFrames: options.minSilenceFrames ?? DEFAULT_VAD_CONFIG.minSilenceFrames,\n maxSpeechFrames: options.maxSpeechFrames ?? DEFAULT_VAD_CONFIG.maxSpeechFrames,\n mergeSilenceFrames: options.mergeSilenceFrames ?? DEFAULT_VAD_CONFIG.mergeSilenceFrames,\n extendSpeechFrames: options.extendSpeechFrames ?? DEFAULT_VAD_CONFIG.extendSpeechFrames,\n };\n return new OmniVAD(handle, config);\n }\n\n /**\n * Detect speech segments in audio.\n *\n * Accepts Int16Array (PCM) or normalized Float32Array in [-1, 1].\n */\n detect(audio: Float32Array | Int16Array): VADResult {\n const M = getModule();\n const { ptr, length, format } = dispatchAudio(M, audio);\n\n try {\n const timestamps = vadDetect(M, this.handle, ptr, length, this.config, format);\n return {\n duration: Math.round((length / SAMPLE_RATE) * 1000) / 1000,\n timestamps,\n };\n } finally {\n M._free(ptr);\n }\n }\n\n /** Release native resources. */\n dispose(): void {\n if (this.handle) {\n vadDestroy(getModule(), this.handle);\n this.handle = 0;\n }\n }\n}\n","/**\n * Streaming Voice Activity Detection (WASM/ncnn backend).\n * Processes audio frame-by-frame (10ms chunks of 160 samples @ 16kHz).\n *\n * Audio format: Float32Array in [-1, 1] or Int16Array PCM. Wrappers\n * dispatch by dtype; all scaling lives in the C entries.\n */\n\nimport type { StreamVADConfig, StreamVADFrameResult, StreamVADFullResult } from \"./types.js\";\nimport {\n initWasm,\n getModule,\n dispatchAudio,\n loadModel,\n streamVadCreate,\n streamVadClone,\n streamVadProcess,\n streamVadDetectFull,\n streamVadReset,\n streamVadDestroy,\n} from \"./wasm-binding.js\";\n\nconst SAMPLE_RATE = 16000;\n\nexport class OmniStreamVAD {\n private handle: number;\n\n private constructor(handle: number) {\n this.handle = handle;\n }\n\n /**\n * Create a new OmniStreamVAD instance.\n * Loads model from CDN (browser), local package (Node.js), or custom source.\n */\n static async create(options: StreamVADConfig = {}): Promise<OmniStreamVAD> {\n await initWasm();\n const M = getModule();\n const modelBuffer = await loadModel(\"stream-vad\", options.modelUrl, options.modelData);\n const handle = streamVadCreate(M, modelBuffer, {\n threshold: options.threshold,\n smoothWindowSize: options.smoothWindowSize,\n padStartFrame: options.padStartFrame,\n minSpeechFrame: options.minSpeechFrame,\n maxSpeechFrame: options.maxSpeechFrame,\n minSilenceFrame: options.minSilenceFrame,\n });\n return new OmniStreamVAD(handle);\n }\n\n /**\n * Create a lightweight clone sharing the same underlying model weights.\n * The clone has fresh per-instance state (empty audio buffer, zeroed cache).\n * This is synchronous and extremely fast — ideal for multi-stream scenarios\n * (e.g., handling multiple WebRTC tracks or concurrent audio sessions).\n */\n clone(): OmniStreamVAD {\n if (!this.handle) throw new Error(\"Cannot clone a disposed instance.\");\n const M = getModule();\n const newHandle = streamVadClone(M, this.handle);\n return new OmniStreamVAD(newHandle);\n }\n\n /**\n * Process one frame of audio (160 samples = 10ms @ 16kHz).\n *\n * Accepts Float32Array in [-1, 1] (Web Audio, soundfile, torch) or\n * Int16Array PCM (WAV, microphone). Dispatches by dtype to the matching\n * C entry — no scaling in JS.\n *\n * Returns null until enough audio is accumulated.\n *\n * Segment-boundary events (isSpeechStart / isSpeechEnd and the matching\n * speech_*_frame indices) come straight from the C-layer state machine\n * (bit-identical to upstream FireRedVAD) — the wrapper is just a marshaller.\n */\n processFrame(audio: Float32Array | Int16Array): StreamVADFrameResult | null {\n const M = getModule();\n const { ptr, length, format } = dispatchAudio(M, audio);\n\n try {\n const result = streamVadProcess(M, this.handle, ptr, length, format);\n if (!result) return null;\n\n return {\n confidence: result.confidence,\n smoothedProb: result.smoothedProb,\n isSpeech: result.isSpeech,\n frameIndex: result.frameIdx,\n isSpeechStart: result.isSpeechStart,\n isSpeechEnd: result.isSpeechEnd,\n speechStartFrame: result.speechStartFrame,\n speechEndFrame: result.speechEndFrame,\n };\n } finally {\n M._free(ptr);\n }\n }\n\n /**\n * Process entire audio at once and return per-frame probabilities.\n * @param audio - Float32Array in [-1, 1] or Int16Array of 16kHz mono PCM\n */\n detectFull(audio: Float32Array | Int16Array): StreamVADFullResult {\n const M = getModule();\n const { ptr, length, format } = dispatchAudio(M, audio);\n\n try {\n const { probabilities, numFrames } = streamVadDetectFull(\n M,\n this.handle,\n ptr,\n length,\n format,\n );\n return {\n probabilities,\n numFrames,\n duration: Math.round((length / SAMPLE_RATE) * 1000) / 1000,\n };\n } finally {\n M._free(ptr);\n }\n }\n\n /** Reset all internal state (model cache, audio buffer, postprocessor). */\n reset(): void {\n streamVadReset(getModule(), this.handle);\n }\n\n /** Release native resources. */\n dispose(): void {\n if (this.handle) {\n streamVadDestroy(getModule(), this.handle);\n this.handle = 0;\n }\n }\n}\n\n","/**\n * Audio Event Detection: speech, singing, music (WASM/ncnn backend).\n *\n * Audio format: same as OmniVAD — Float32Array in [-1, 1] or Int16Array PCM.\n * Wrappers dispatch by dtype; all scaling lives in the C entries.\n */\n\nimport type { AEDConfig, AEDResult } from \"./types.js\";\nimport {\n initWasm,\n getModule,\n dispatchAudio,\n loadModel,\n aedCreate,\n aedDetect,\n aedDestroy,\n DEFAULT_VAD_CONFIG,\n type AedPostConfig,\n} from \"./wasm-binding.js\";\n\nconst SAMPLE_RATE = 16000;\n\nexport class OmniAED {\n private handle: number;\n private config: AedPostConfig;\n\n private constructor(handle: number, config: AedPostConfig) {\n this.handle = handle;\n this.config = config;\n }\n\n /**\n * Create a new OmniAED instance.\n * Loads model from CDN (browser), local package (Node.js), or custom source.\n */\n static async create(options: AEDConfig = {}): Promise<OmniAED> {\n await initWasm();\n const M = getModule();\n const modelBuffer = await loadModel(\"aed\", options.modelUrl, options.modelData);\n const handle = aedCreate(M, modelBuffer);\n\n const base = {\n smoothWindowSize: options.smoothWindowSize ?? DEFAULT_VAD_CONFIG.smoothWindowSize,\n minSpeechFrames: options.minSpeechFrames ?? DEFAULT_VAD_CONFIG.minSpeechFrames,\n minSilenceFrames: options.minSilenceFrames ?? DEFAULT_VAD_CONFIG.minSilenceFrames,\n maxSpeechFrames: options.maxSpeechFrames ?? DEFAULT_VAD_CONFIG.maxSpeechFrames,\n mergeSilenceFrames: options.mergeSilenceFrames ?? DEFAULT_VAD_CONFIG.mergeSilenceFrames,\n extendSpeechFrames: options.extendSpeechFrames ?? DEFAULT_VAD_CONFIG.extendSpeechFrames,\n };\n\n const config: AedPostConfig = {\n speech: { ...base, threshold: options.speechThreshold ?? 0.4 },\n singing: { ...base, threshold: options.singingThreshold ?? 0.5 },\n music: { ...base, threshold: options.musicThreshold ?? 0.5 },\n };\n return new OmniAED(handle, config);\n }\n\n /**\n * Detect audio events (speech, singing, music).\n *\n * Accepts Int16Array (PCM) or normalized Float32Array in [-1, 1].\n */\n detect(audio: Float32Array | Int16Array): AEDResult {\n const M = getModule();\n const { ptr, length, format } = dispatchAudio(M, audio);\n const duration = Math.round((length / SAMPLE_RATE) * 1000) / 1000;\n\n try {\n const events = aedDetect(M, this.handle, ptr, length, this.config, format);\n return {\n duration,\n events,\n ratios: computeCoverageRatios(events, duration),\n };\n } finally {\n M._free(ptr);\n }\n }\n\n /** Release native resources. */\n dispose(): void {\n if (this.handle) {\n aedDestroy(getModule(), this.handle);\n this.handle = 0;\n }\n }\n}\n\nfunction computeCoverageRatios(\n events: Record<string, Array<[number, number]>>,\n duration: number,\n): Record<string, number> {\n const ratios: Record<string, number> = {\n speech: 0,\n singing: 0,\n music: 0,\n };\n\n if (duration <= 0) return ratios;\n\n for (const cls of Object.keys(ratios)) {\n const covered = (events[cls] ?? []).reduce((sum, [start, end]) => sum + Math.max(0, end - start), 0);\n ratios[cls] = Math.round(Math.min(1, covered / duration) * 1e6) / 1e6;\n }\n\n return ratios;\n}\n","/**\n * Pure-algorithm chunking utility — wraps the C function omni_merge_chunks\n * compiled into the WASM module.\n *\n * WhisperX-style binarize+merge, minus the binarize half because OmniVAD\n * already returns binarized timestamps.\n *\n * Usage:\n *\n * import { mergeChunks } from \"omnivad\";\n *\n * const chunks = await mergeChunks(\n * [[0.0, 5.0], [6.0, 10.0]],\n * { maxChunkSecs: 30.0, maxGapSecs: 2.0 }\n * );\n * // [{ start: 0, end: 10, segStartIdx: 0, segCount: 2 }]\n */\n\nimport type { ChunkOptions, ChunkResult } from \"./types.js\";\nimport {\n chunkMerge,\n DEFAULT_CHUNK_CONFIG,\n getModule,\n initWasm,\n type ChunkConfig,\n} from \"./wasm-binding.js\";\n\n/**\n * Merge a sorted array of [start, end] speech segments into duration-bounded\n * chunks.\n *\n * Lazily initializes the WASM module on first call (so the caller doesn't have\n * to await `initWasm()` separately). Subsequent calls reuse the cached module.\n *\n * @param segments array of [start, end] pairs in seconds, sorted by start\n * @param options chunking configuration; missing fields fall back to\n * {@link DEFAULT_CHUNK_CONFIG}\n */\nexport async function mergeChunks(\n segments: Array<[number, number]>,\n options: ChunkOptions = {},\n): Promise<ChunkResult[]> {\n await initWasm();\n const M = getModule();\n\n const cfg: ChunkConfig = {\n maxChunkSecs: options.maxChunkSecs ?? DEFAULT_CHUNK_CONFIG.maxChunkSecs,\n maxGapSecs: options.maxGapSecs ?? DEFAULT_CHUNK_CONFIG.maxGapSecs,\n padOnsetSecs: options.padOnsetSecs ?? DEFAULT_CHUNK_CONFIG.padOnsetSecs,\n padOffsetSecs: options.padOffsetSecs ?? DEFAULT_CHUNK_CONFIG.padOffsetSecs,\n minSpeechSecs: options.minSpeechSecs ?? DEFAULT_CHUNK_CONFIG.minSpeechSecs,\n minSilenceSecs: options.minSilenceSecs ?? DEFAULT_CHUNK_CONFIG.minSilenceSecs,\n mode: options.mode ?? DEFAULT_CHUNK_CONFIG.mode,\n };\n\n const records = chunkMerge(M, segments, cfg);\n return records.map((r) => ({\n start: r.start,\n end: r.end,\n segStartIdx: r.segStartIdx,\n segCount: r.segCount,\n }));\n}\n\nexport { DEFAULT_CHUNK_CONFIG } from \"./wasm-binding.js\";\nexport type { ChunkOptions, ChunkResult } from \"./types.js\";\n"]}
|